Long story but I'm trying to allow for arrows to be used in my program so I have to use key codes or scancode (or what ever they are called) but I don't want any if statements to have to look for upper and lower case letters separately.

You can put anything you want in a CPP macro (#define), but it's just static text. It will not magically be expanded by the preprocessor into multiple checks. Show us your code and will have a better idea what you're trying to do. In general, if case is all that matters, you can lower-case both sides and compare them (or upper-case both). Show us code and we might be able to be more helpful.

Chris, I didn't think it would work but was hoping there was another trick I could use.

Unfortunately I'm using Allegro 4. I will include the code.

The issue in short is, during my game Menu, Credits, & Instructions screens, I have a set of Atari Adventure looking Dragons that go back and forth along the bottom of the screen while waiting on the user entry. At the time I wrote this I just dealt with letter choices so I have a CHAR called RESP being returned to main. In this case I used toupper after readkey so any IFs involved in the Menu functions only had to look for the upper case of a letter (C, I, P, Quit). Later I got the idea to scroll the Instructions, within a widowed screen. Now I have to have arrow keys to scroll. Arrow keys will not work with CHAR variables. I have to use INT and scancodes. I can make it work, but with out the "toupper" option I've just doubled my checks for Q = 4433 and q = 4465. I was hoping a tricky define might allow for a single macro call Q for both numbers.

In any case, it doesn't sound like it will. I was just looking for simplicity and compact code.

Not it will tell the entire tale but here is the CHAR DRAGONS function that simply moves the dragons while waiting on a key hit. The calling functions actually determine what to do with the return value.

Just curious: why are you using Allegro 4? I've seen a handful of posts related to Allegro 4 recently, but I keep asking myself "why?". I understand that Allegro 4 was out for a long while before 5, and that it's near and dear to a lot of folks. But unless you're trying to make something for DOS, why not use Allegro 5 instead?

And I normally put all keyboard routines into a input() function which merely sets flags, and all EFFECTS of those flags are in a logic() function that gets called next.

So in my games it's normally:

#SelectExpand

1void main()//this is ALL that I put in main. 2{ 3initialize();//allegro setup routines, loading files, etc. 4execute(); 5shutdown(); 6} 7 8void execute() 9{ 10while(true)//Runs this full loop ONCE per game frame 11{ 12if( input ())break;//either return 1 to indicate quit, or I set a global "is_finished" variable 13 logic(); 14 draw(); 15} 16} 17 18bool player1_wants_to_move_upward;// global for simplicity (no time to explain dependency injection) 19 20int input() 21{ 22if(key[KEY_ESC])return1;//if time to quit game 23 24//other keys 25// NOTE, input SETS FLAGS (that are reset per frame). It doesn't directly call physics or logic updates. 26player1_wants_to_move_upward =false; 27if(key[KEY_W])player1_wants_to_move_upward =true; 28} 29 30void logic() 31{ 32if(player1_wants_to_move_upward) 33{ 34//attempt to move him upward. 35} 36// NOTE HERE. NO matter HOW MANY times W is pressed within ONE FRAME, the FLAG 37// is only set to TRUE. So this guy won't move upward MORE TIMES if a player 38// can press UP more times during a slow frame rate. This is IMPORTANT for most 39// games, like jumping, where you don't want someone to rapidly press SPACE to 40// jump higher than they should be able to 41}

-----sig:“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

AceBlkwell's use of keypressed() and readkey() looks fine, because it will make use of keyboard repetition : Press and hold the key, it will trigger once, wait a fraction of a second, then start repeating 10 times per second.

As for testing individual keys, readkey() returns an integer already. Just make resp and dragons() integer instead of char, and have the calling code test for :

int val = dragons();if((val >>8)== KEY_LEFT)// for cursor, ESC,...
...
if((val &0xff)=='a')// Letter A on keyboard, no matter where it is (works on every keyboard layout)
...

Thanks for the info. Couple of questions. I'm not familiar with the shifts or offsets (or whatever they are). How do you know which to use or what the offset should be?

val >> 8 or val & 0xff ?? not really for sure what these are. If it's too much to explain, just tell me where to look.

Eric,

I'm using Allegro 4 because it's more console friendly from my perspective. I do want to graduate Allegro 5 but for the sake of my current program, I didn't want to learn event type programming on top getting refamiliar with programming. I haven't even written a program that uses a mouse yet. but I agree it is time to move on. Maybe after this one is done.

Chris,

I appreciate the info on the KEY_(letter) will cover both upper and lower case. That's what I'm looking for

It's all in the fabulous manual. Your distribution hopefully came with a copy, perhaps you have to build it, but one version can be found on liballeg.org[1] (or indeed, also there should be one still on allegro.cc).

TFM said:

The low byte of the return value contains the ASCII code of the key, and the high byte the scancode. The scancode remains the same whatever the state of the shift, ctrl and alt keys, while the ASCII code is affected by shift and ctrl in the normal way (shift changes case, ctrl+letter gives the position of that letter in the alphabet, eg. ctrl+A = 1, ctrl+B = 2, etc). Pressing alt+key returns only the scancode, with a zero ASCII code in the low byte.

This paragraph is followed by example code that demonstrates, but I'll blabber one with my own explanation inline.

The >> operator shifts the bits in the left operand (value) to the right by the right operand. In this case, x >>8 means to move all of the bits in x to the right 8 places, effectively erasing the bottom 8 bits, and moving the 8-32 bits to positions 1-24, respectively (for a 32-bit integer) (using a 1-based index, which is somewhat weird probably).

0001000101010101 >> 8
|
+-------+
|
= 0000000000010001

The & operator is a bitwise-AND. This compares the bits in the left-hand operand with the corresponding bits in the right-hand operand. If they're both 1 then the result is 1. If either is 0 then the result is 0. Just like a standard AND logic gate.

00010001
& 01010101
= 00010001

0xff AKA 255 represented in binary in a 32-bit signed integer is 00000000000000000000000011111111 (all 8 lowest bits set to 1). This is just another trick to discard the parts you don't care about (the upper bits) and keep the ones you do care about (the bottom 8). Any bits in the other operand that are set in the lowest 8 positions are kept, and the rest are thrown away. This leaves you with only the part that you care about.

The bitwise operations are required to extract the information you care about from the readkey function. It returns an integer. Within this one integer are two fields. The ASCII code corresponding to the character is stored in the "low-byte". The scancode is stored in the "high-byte". Where A=ASCII character and S=scancode:

32-bit int: 00000000 00000000 SSSSSSSS AAAAAAAA
32 24 16 87654321

If you bitwise-AND with 0xFF you get AAAAAAAA. If you shift everything the right 8 bits (1 byte) you get SSSSSSSS. The scancode in the high-byte gets you the "key", whereas the ASCII character is obviously the "letter".

So I guess yes, it is dependent on what information you care about. The scancode should tell you everything (except for maybe Alt?), but you may prefer the ASCII code if you're manipulating text.