Modifiers: how to?

Hi everyone

I’ve got short question about using modifiers (shift, ctrl etc.) and GetKeyState. Every game loop I take snapshot of all keyboard keys (of course using SDL_GetKeyState) and now I’m in this situation: when user types some text into edit control holding shift, he should get proper uppercase text (a-z) or other modifications (ie. 1 changes to !, 2 changes to @ etc.).
First part is accomplished by simply checking if KMOD_SHIFT is pressed and if yes, then toupper’ing it. It works for normal letters a-z, but for others not! they don’t change. It looks like that’s how toupper should work.
Looking into SDL_KeySym.h found that simply subtracting any arbitrary number won’t do the trick, because characters are not in linear order. Also, I don’t want to play manually constructing huge switch for simple conversions :-/

Any ideas, advices, existing functions, links? Thanks from advance!–
Koshmaar
<Of all the things I’'ve lost, I miss my mind the most>
GG: 3928072
http://jnr.sourceforge.net/
www.pongowar.prv.pl
www.liero-turbo.prv.pl

Quoth Koshmaar , on 2004-11-28 21:13:06 +0100:

Hi everyone

I’ve got short question about using modifiers (shift, ctrl etc.) and
GetKeyState. Every game loop I take snapshot of all keyboard keys (of
course using SDL_GetKeyState) and now I’m in this situation: when user
types some text into edit control holding shift, he should get proper
uppercase text (a-z) or other modifications (ie. 1 changes to !, 2
changes to @ etc.).

SDL provides Unicode translation for key-down events. Look at the
’unicode’ field of the keysym structure. In order for it to be valid,
though, you must first enable Unicode translation with an
SDL_EnableUNICODE(1) call. The release events don’t get translated,
either. Look at the documentation for SDL_keysym and
SDL_EnableUNICODE.

—> Drake Wilson
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20041128/14b2e8c5/attachment.pgp

This is a common question:

http://www.libsdl.org/cgi/docwiki.cgi/FAQ_20Unicode

Gerald> ----- Original Message -----

From: sdl-bounces+gerald.kaszuba=apnoutdoor.com.au@libsdl.org [mailto:sdl-bounces+gerald.kaszuba=apnoutdoor.com.au at libsdl.org]On Behalf Of Koshmaar
Sent: Monday, 29 November 2004 7:13 AM
To: A list for developers using the SDL library. (includes SDL-announce)
Subject: [SDL] Modifiers: how to?

Hi everyone

I’ve got short question about using modifiers (shift, ctrl etc.) and GetKeyState. Every game loop I take snapshot of all keyboard keys (of course using SDL_GetKeyState) and now I’m in this situation: when user types some text into edit control holding shift, he should get proper uppercase text (a-z) or other modifications (ie. 1 changes to !, 2 changes to @ etc.).
First part is accomplished by simply checking if KMOD_SHIFT is pressed and if yes, then toupper’ing it. It works for normal letters a-z, but for others not! they don’t change. It looks like that’s how toupper should work.
Looking into SDL_KeySym.h found that simply subtracting any arbitrary number won’t do the trick, because characters are not in linear order. Also, I don’t want to play manually constructing huge switch for simple conversions :-/

Any ideas, advices, existing functions, links? Thanks from advance!


Koshmaar
<Of all the things I’'ve lost, I miss my mind the most>
GG: 3928072
http://jnr.sourceforge.net/
www.pongowar.prv.pl
www.liero-turbo.prv.pl


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

This is a common question:

http://www.libsdl.org/cgi/docwiki.cgi/FAQ_20Unicode

Gerald

Unfortunately not, you would use SDL_EnableUNICODE() when dealing with normal message-based SDL loop. Yes, I’m using it (well, sort of, one SDL_PollEvent per frame; checking for SDL_QUIT, anything else is ignored) but for input system I use SDL_GetKeyState(), so enabling unicode won’t do the trick. I wonder if there is any SDL/standard lib specific function for converting between normal characters and they quasi uppercase version…? :-/

Anyway, thanks for replays

Koshmaar

This is a common question:

http://www.libsdl.org/cgi/docwiki.cgi/FAQ_20Unicode

Gerald

Unfortunately not, you would use SDL_EnableUNICODE() when dealing with normal message-based SDL loop. Yes, I’m using it (well, sort of, one SDL_PollEvent per frame; checking for SDL_QUIT, anything else is ignored) but for input system I use SDL_GetKeyState(), so enabling unicode won’t do the trick. I wonder if there is any SDL/standard lib specific function for converting between normal characters and they quasi uppercase version…? :-/

I assume you firmly believe you are getting something of great value by
doing it your way, or you wouldn’t do it that way. Can you please tell
us what that is?

	Bob PendletonOn Mon, 2004-11-29 at 11:17, Koshmaar wrote:

Anyway, thanks for replays

Koshmaar


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

±-------------------------------------+

I assume you firmly believe you are getting something of great value by
doing it your way, or you wouldn’t do it that way. Can you please tell
us what that is?

Well, it’s not that I’ve designed it particularly this way to achieve some specific goals. There were two main reasons for it:

  1. I really don’t like this whole concept of event loop and obligation to listen for messages; it’s one of (many ;-)) reasons I keep myself far from strict Windows programming. If there are other ways to achieve the same results, I generally try them out before going to events.

  2. Some performance reasons - I believe that it’s faster and more reliable to copy all keys state once per frame than to do redundant checks multiple times (I’m coding game for max. 4 players on one comptuer playing simultaneously, each using 4-5 keys so check count may be high). It’s the same argument why in some cases vectors can be faster than maps though maps are generally O(log n) while vectors have linear complexity (source of information: Game Programming Gems #2).

Ok, it looks that there is no standard way to deal with this problem. I’m going to code huge function with nasty switch statement :-/ if someone is interested in it, I can share this code.

Koshmaar

Koshmaar wrote:

Ok, it looks that there is no standard way to deal with this problem. I’m going to code huge function with nasty switch statement :-/ if someone is interested in it, I can share this code.

An easier way would be to write your own KeyState class or structure and
have it save the unicode values.
Plus, the unicode field might even take into account the user’s keyboard
layout (I don’t know if it actually does), which your switch statement
is unable to do, not to speak of inputting non-english characters.

By the way, I don’t know whether this has been discussed before, but
what is the rationale behind the unicode field of SDL_keysym only having
16 bits?

-Sebastian

An easier way would be to write your own KeyState class or structure and
have it save the unicode values.

Too late, it’s already written :slight_smile:

Plus, the unicode field might even take into account the user’s keyboard
layout (I don’t know if it actually does), which your switch statement
is unable to do, not to speak of inputting non-english characters.

Though my native language is polish, which uses characters like ?, ?, ?, ?, ? etc. (probably they won’t be displayed correctly in your OS) so in theory I should be fairly accustumed with such things, in my current project I’m totally ignoring internationalization stuff because:

  1. I don’t need it, normal plain english ASCII will suffice
  2. I’m already quite past my deadline, and there’s still much to do
  3. Lazyness :wink:

By the way, I don’t know whether this has been discussed before, but
what is the rationale behind the unicode field of SDL_keysym only having
16 bits?

IMHO it’s how standard unicode text is keeped in memory: 2 bytes per character.

OK, I’ve also got BTW: why there’s not defined SDLK_(percent symbol you get when pressing shift + 5) and SDLK_(fancy brackets you get pressing shift + [ or shift + ])? Others from group 1-9 are defined, but those aren’t, though I see no reason why. In that converting function I had to workaround it using:

case SDLK_5: return (SDLKey) 37;
case SDLK_RIGHTBRACKET: return (SDLKey) 125;
case SDLK_LEFTBRACKET: return (SDLKey) 123;

It’s working but it looks ugly :-/

Koshmaar

I believe this would be because %, [ and ] are not valid characters
for C variable names. Specifically, % is the modulus operator, and [
and ] are array index operators. Allowing those characters in variable
names would just confuse the compiler.

-JustinOn Mon, 29 Nov 2004 23:37:22 +0100, Koshmaar wrote:

OK, I’ve also got BTW: why there’s not defined SDLK_(percent symbol you get when pressing shift + 5) and SDLK_(fancy brackets you get pressing shift + [ or shift + ])? Others from group 1-9 are defined, but those aren’t, though I see no reason why. In that converting function I had to workaround it using:

case SDLK_5: return (SDLKey) 37;
case SDLK_RIGHTBRACKET: return (SDLKey) 125;
case SDLK_LEFTBRACKET: return (SDLKey) 123;

I believe this would be because %, [ and ] are not valid characters
for C variable names. Specifically, % is the modulus operator, and [
and ] are array index operators. Allowing those characters in variable
names would just confuse the compiler.

If so, please tell me why I didn’t write similiar case statement ie. for comma “.” or exclamation “!”? :wink: This % could be defined as SDLK_PERCENT…

BTW: ok, I stop spamming

Koshmaar

I don’t have SDL headers in front of me, but I THINK they’re complaining
that there’s not:

SDLK_PERCENT
SDLK_RIGHTBRACE
SDLK_LEFTBRACE

or some-such.

I can’t confirm, though. Like I said, no headers in front of me :wink:

-bill!On Mon, Nov 29, 2004 at 06:21:37PM -0500, Justin Coleman wrote:

On Mon, 29 Nov 2004 23:37:22 +0100, Koshmaar wrote:

OK, I’ve also got BTW: why there’s not defined SDLK_(percent symbol you get when pressing shift + 5) and SDLK_(fancy brackets you get pressing shift + [ or shift + ])? Others from group 1-9 are defined, but those aren’t, though I see no reason why. In that converting function I had to workaround it using:

case SDLK_5: return (SDLKey) 37;
case SDLK_RIGHTBRACKET: return (SDLKey) 125;
case SDLK_LEFTBRACKET: return (SDLKey) 123;

I believe this would be because %, [ and ] are not valid characters
for C variable names. Specifically, % is the modulus operator, and [
and ] are array index operators. Allowing those characters in variable
names would just confuse the compiler.

I assume you firmly believe you are getting something of great value by
doing it your way, or you wouldn’t do it that way. Can you please tell
us what that is?

Well, it’s not that I’ve designed it particularly this way to achieve some specific goals. There were two main reasons for it:

  1. I really don’t like this whole concept of event loop and obligation to listen for messages; it’s one of (many ;-)) reasons I keep myself far from strict Windows programming. If there are other ways to achieve the same results, I generally try them out before going to events.

So, it is a matter of personal taste. Can’t argue with that! :slight_smile:

  1. Some performance reasons - I believe that it’s faster and more reliable to copy all keys state once per frame than to do redundant checks multiple times (I’m coding game for max. 4 players on one comptuer playing simultaneously, each using 4-5 keys so check count may be high). It’s the same argument why in some cases vectors can be faster than maps though maps are generally O(log n) while vectors have linear complexity (source of information: Game Programming Gems #2).

Not really, the code is pretty deeply intertwined. You might want to
look at the source before you decide it is faster. Generally SDL has to
read an event queue to get the information it puts in the key vector.

Anyway, the cost is so small it doesn’t really affect game play even
with 4 players on one machine. OTOH, if you are only using one keyboard
then you will have problems with keys presses not being detected at all.

Ok, it looks that there is no standard way to deal with this problem. I’m going to code huge function with nasty switch statement :-/ if someone is interested in it, I can share this code.

Since the key vector shows you the state at the time you check it, it is
pretty easy to miss key presses and shift presses. People don’t press
them at the same time so you might get wrong results at times. The only
way around that problem is to use a form of input that doesn’t let you
miss key presses/releases.

	Bob PendletonOn Mon, 2004-11-29 at 14:44, Koshmaar wrote:

Koshmaar


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

±-------------------------------------+

And this is really more of an architecture/hardware problem, anyway.

(Are USB keyboards better at reading Up/Left/Space simultaneously, OOC?)

-bill!On Mon, Nov 29, 2004 at 06:04:33PM -0600, Bob Pendleton wrote:

Anyway, the cost is so small it doesn’t really affect game play even
with 4 players on one machine. OTOH, if you are only using one keyboard
then you will have problems with keys presses not being detected at all.

Koshmaar wrote:

Ok, it looks that there is no standard way to deal with this problem. I’m going to code huge function with nasty switch statement :-/ if someone is interested in it, I can share this code.

An easier way would be to write your own KeyState class or structure and
have it save the unicode values.
Plus, the unicode field might even take into account the user’s keyboard
layout (I don’t know if it actually does), which your switch statement
is unable to do, not to speak of inputting non-english characters.

By the way, I don’t know whether this has been discussed before, but
what is the rationale behind the unicode field of SDL_keysym only having
16 bits?

Probably the same reason that rectangle sizes are only 16 bits. It was
enough when that code was written and if it had been more people would
have been upset about how horrible SDL is for wasting those unneeded 16
bits.

The oldest entries in the SDL mailing list archives are from 1994. SDL
must be at least 10 years old. A lot has changed since then. A big
computer back then had speedy 66MHz 486, maybe 16 megs of RAM, and an
SVGA card.

10 years is really really old for game development software.

Looks like a lot of things need to be reworked.

	Bob PendletonOn Mon, 2004-11-29 at 16:09, Sebastian Beschke wrote:

-Sebastian


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

±-------------------------------------+

Hello Bill,

Tuesday, November 30, 2004, 1:07:46 AM, you wrote:

BK> On Mon, Nov 29, 2004 at 06:04:33PM -0600, Bob Pendleton wrote:

Anyway, the cost is so small it doesn’t really affect game play even
with 4 players on one machine. OTOH, if you are only using one keyboard
then you will have problems with keys presses not being detected at all.

BK> And this is really more of an architecture/hardware problem, anyway.

BK> (Are USB keyboards better at reading Up/Left/Space simultaneously, OOC?)

You can find a normal PS2 keyboard that passes well multiple keypress events. I.e. I
bought old, used DELL keyboard ( model AT102W heavy, indestructible) which do it
well, but my new, multimedia Logitech (Y-SQ33) can’t do, same as many other I
tried.–
Best regards,
Milan mailto:milan_g at eunet.yu

Bob Pendleton wrote:> On Mon, 2004-11-29 at 16:09, Sebastian Beschke wrote:

By the way, I don’t know whether this has been discussed before, but
what is the rationale behind the unicode field of SDL_keysym only having
16 bits?

Probably the same reason that rectangle sizes are only 16 bits. It was
enough when that code was written and if it had been more people would
have been upset about how horrible SDL is for wasting those unneeded 16
bits.

Well, I kinda suspected that. Anyway, I don’t know if there even are
any keyboards that can input characters beyond FFFF… there probably
aren’t.

-Sebastian

This is a really interesting thread, so I’ll address several issues brought up.

  1. I really don’t like this whole concept of event loop and obligation to listen for messages; it’s one of (many ;-)) reasons I keep myself far from strict Windows programming. If there are other ways to achieve the same results, I generally try them out before going to events.

As was mentioned elsewhere, if you rely on the current state of the keyboard,
you’ll miss keys that were pressed and then released before you polled the
keyboard state.

Since most operating systems handle keyboard and mouse input in an input queue,
and you only have a snapshot of the keyboard state at any given time, the only
way that I know of to catch keyboard state changes as they occur is to process
events and handle them appropriately.

FYI, the way SDL handles it’s key state is when you pump the event loop, as
it queues each key event, it will update it’s internal keyboard state array.

  1. Some performance reasons - I believe that it’s faster and more reliable to copy all keys state once per frame than to do redundant checks multiple times (I’m coding game for max. 4 players on one comptuer playing simultaneously, each using 4-5 keys so check count may be high). It’s the same argument why in some cases vectors can be faster than maps though maps are generally O(log n) while vectors have linear complexity (source of information: Game Programming Gems #2).

Usually what programs do is poll for any queued events at the beginning of the
logic for the frame, update any internal state and then proceed with the logic.
The framerate is usually high enough that all the input for the frame can be
considered to be simultaneous. This breaks down when your framerate slows and
it’s important to know the duration a key was held down that was pressed and
released before you got there, but many operating systems don’t provide time
information on input events, and those that do usually provide it in a
different time base than the values that SDL_GetTicks() returns. However,
as I mentioned framerates are usually high enough that this doesn’t matter.

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment

Plus, the unicode field might even take into account the user’s keyboard
layout (I don’t know if it actually does)

Yes, it does.

By the way, I don’t know whether this has been discussed before, but
what is the rationale behind the unicode field of SDL_keysym only having
16 bits?

When it was written Unicode was UTF-16. The UTF-32 standard hadn’t been
defined yet.

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment

OK, I’ve also got BTW: why there’s not defined SDLK_(percent symbol you get when pressing shift + 5) and SDLK_(fancy brackets you get pressing shift + [ or shift + ])? Others from group 1-9 are defined, but those aren’t, though I see no reason why.

They were overlooked. When I wrote the list of keysyms I didn’t have a polish
keyboard handy. :slight_smile:

I recently wrote the international keyboard handling for World of Warcraft,
and I finally figured out how to do it right, so SDL 1.3 is going to have a
completely revamped set of keysyms, which will include the lower ASCII set
unchanged, as keys on the keyboard.

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment

Anyway, the cost is so small it doesn’t really affect game play even
with 4 players on one machine. OTOH, if you are only using one keyboard
then you will have problems with keys presses not being detected at all.

Yes, many keyboards cannot handle even 3 keys pressed simultaneously,
depending on where they are on the keyboard. This is a hardware limitation,
due to the circuitry on the keyboard.

To fully support 4 people playing on the same system, you’ll probably have
to support joystick input.

Bob, as an FYI, I’d like to support multiple keyboards in SDL 1.3. :slight_smile:

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment