Event handling questions

I’m writing a game in c++ using SDL.

I’m curious as to the best way to handle events from SDL.

I have separate objects for the various players, and each player needs to
detect if the appropriate keys have been pressed or not.

The best way, I assume, is to poll through the events at the point I need
the keypresses.
The problem is that if I poll through the events in one player’s object,
then the key press may be removed and not detected again when the second
player’s controls come around.

The other way, I guess, is to pump_events at the beginning of my loop and
check the status of the various keys at the end.

I’ve been trying the second way, but sometimes my game goes crazy with
events that seem to hang around in the queue.

When I call pump_events does this clear the current event queue?

I was wondering if other people had any ideas as to how best to manage game
input when requiring input detection in various locations.

Thanks.

With my emulator programms I had the exact same problem
and some more strange things (like that the key was stuck
in the events while the key wasn’t pressed).

I use the following function which resolved this issue.

I hope this is understanding code :wink:

Regards,

Niels Wagenaar

inline void BoycaMain::ProcessSDLKeys()
{
#define GET_KEY(x, b, v)
if (keystate[GetKeyVal(x)]) b |= v;

#define GET_JOY(x, b, v) \
if(SDL_JoystickGetButton(joystick, GetVal(x)) == SDL_PRESSED) b |= 

v;

Sint16 x_move = 0, y_move = 0;

unsigned int eventstate = 0;
char	fpName[256];
char    BAMfile[256];

keystate = SDL_GetKeyState(NULL); // First to initialize the 

keystates
int mod = SDL_GetModState();

strcpy( fpName, romfile );
strcpy( BAMfile, romfile );
SelectFileExtension(BAMfile,".bam");


if(joy) {
	x_move = SDL_JoystickGetAxis(joystick, 0);
	y_move = SDL_JoystickGetAxis(joystick, 1);
}

#if defined(BEOS) || defined(TARGET_WIN32)
if((keystate[SDLK_RETURN]) && (mod & KMOD_LALT)) {
SDL_WM_ToggleFullScreen(gbascreen);
}
#endif

GET_KEY(2, eventstate, HID_EVENT_LEFT);
GET_KEY(3, eventstate, HID_EVENT_RIGHT);
GET_KEY(0, eventstate, HID_EVENT_UP);
GET_KEY(1, eventstate, HID_EVENT_DOWN);
GET_KEY(5, eventstate, HID_EVENT_SELECT);
GET_KEY(4, eventstate, HID_EVENT_START);
GET_KEY(6, eventstate, HID_EVENT_A);
GET_KEY(7, eventstate, HID_EVENT_B);
GET_KEY(8, eventstate, HID_EVENT_L);
GET_KEY(9, eventstate, HID_EVENT_R);

if ( keystate[SDLK_F1] ) { // Pause on

  if (mod & KMOD_LALT)
  { 
	savebank = 1;
	printf("Savebank %d selected\n", savebank);
  }
  else
  {
	printf("Emulator is now in pause mode!\n");
	SDL_PauseAudio(1);
	emulation = -1;
  }

}

if ( keystate[SDLK_F2] ) { // Pause off

  if (mod & KMOD_LALT)
  { 
	savebank = 2;
	printf("Savebank %d selected\n", savebank);
  }
  else
  {
	emulation = 0;
	SDL_PauseAudio(0);
	printf("Emulation continued!\n");
  }

}

if ( keystate[SDLK_F3] ) { // Framecounter on

  if (mod & KMOD_LALT)
  { 
	savebank = 3;
	printf("Savebank %d selected\n", savebank);
  }
  else
  {
	printf("Framecounter enabled.\n");
	framecounter = TRUE;
  }

}

if ( keystate[SDLK_F4] ) { // Framecounter off

  if (mod & KMOD_LALT)
  { 
	savebank = 4;
	printf("Savebank %d selected\n", savebank);
  }
  else
  {
	printf("Framecounter disabled.\n");
	SDL_WM_SetCaption( VERSIONINTERNAL , "BOYCOTTADVANCE" );
	framecounter = FALSE;
  }

}

if ( keystate[SDLK_F5] ) { // Frameskip increase

  if (mod & KMOD_LALT)
  { 
	savebank = 5;
	printf("Savebank %d selected\n", savebank);
  }

}

if ( keystate[SDLK_F6] ) { // Frameskip decrease

  if (mod & KMOD_LALT)
  { 
	savebank = 6;
	printf("Savebank %d selected\n", savebank);
  }

}

if ( keystate[SDLK_F7] ) { // Save state save (not yet working in
0.21b)

  if (mod & KMOD_LALT)
  { 
	savebank = 7;
	printf("Savebank %d selected\n", savebank);
  }
  else
  {
   
	Save_STATE( NULL, savebank );
	printf("Savestate saved to savebank %d.\n", savebank);
  }

}

if ( keystate[SDLK_F8] ) { // Save state load (net yet working in
0.21b)

  if (mod & KMOD_LALT)
  { 
	savebank = 8;
	printf("Savebank %d selected\n", savebank);
  }
  else
  {

	Load_STATE( NULL, savebank );
	printf("Savebank %d loaded into emulator\n", savebank);
  }

}

if ( keystate[SDLK_F9] ) { // Make screenshot

  if (mod & KMOD_LALT)
  { 
	savebank = 9;
	printf("Savebank %d selected\n", savebank);
  }
  else
  {

  strcpy(scrsht, screenshot);
  switch(scrno)
  {
	case 1:
        strcat(scrsht, "1"); break;
    case 2:
        strcat(scrsht, "2"); break;
    case 3:
		strcat(scrsht, "3"); break;
    case 4:
		strcat(scrsht, "4"); break;
    case 5:
		strcat(scrsht, "5"); break;
    case 6:
		strcat(scrsht, "6"); break;
    case 7:
		strcat(scrsht, "7"); break;
    case 8:
		strcat(scrsht, "8"); break;
    case 9:
		strcat(scrsht, "9"); break;
    case 10:
		strcat(scrsht, "10"); break;
   }
   strcat(scrsht, ".bmp");
  if (!OpenGL) {
   SDL_SaveBMP(gbascreen, scrsht);
  }
  else

// BoycaGL->OpenGLScreenshot(scrsht);
printf(“Screenshot taking not supported under OpenGL
rendering.\n”);
}
if ( scrno < 10 )
printf(“Saving screenshot as %s\n”, scrsht);
scrno++;

}

if ( keystate[SDLK_F10] ) { // GBA Reset

  if (mod & KMOD_LALT)
  { 
	savebank = 10;
	printf("Savebank %d selected\n", savebank);
  }
  else
  {
	printf("GBA Reset\n");		
	ResetGBA();
  }

}

if ( keystate[SDLK_ESCAPE] ) { // ON/OFF key (well, definately more 

off :slight_smile:
static char buffer[256];
sprintf (buffer, “%0.f FPS”, FrameTimer_lastFrameFPS());

	printf("Last know FPS : %s\n", buffer );
    FreeGeneric();
    exit(1);				
}

if ( keystate[SDLK_INSERT] ) // BAM MOVIE Recording
{
	printf("BAM movie-recording started to %s.\n",  BAMfile);
	GBAStartMovie(BAMfile,1);
}


if ( keystate[SDLK_HOME] ) // BAM MOVIE recording stop!
{

	printf("BAM movie-recording/playing stopped.\n");
	GBAStopMovie();
}

if ( keystate[SDLK_PAGEUP] ) // BAM MOVIE recording play!
{

	printf("Playing BAM movie-recording %s.\n", BAMfile);
	GBAStartMovie(BAMfile,0);
}


if ( keystate[SDLK_KP_PLUS] ) // SpeedUp increase
{
	EmuOptions.SpeedUp+=50;
	if (EmuOptions.SpeedUp>=900) {
		EmuOptions.SpeedUp=900;
	} else {
		printf ("- Current Speed Increase: %d%%\n", 

(EmuOptions.SpeedUp*100)/900);
}
}

if ( keystate[SDLK_KP_MINUS] ) // SpeedUp increase
{
	EmuOptions.SpeedUp-=50;
	if (EmuOptions.SpeedUp<=0) {
		EmuOptions.SpeedUp=0;
	} else {
		printf ("- Current Speed Decrease: %d%%\n", 

(EmuOptions.SpeedUp*100)/900);
}
}

if(joy) {
if(x_move > 32768/2)
	eventstate |= ( HID_EVENT_RIGHT ); // seems to work fine
			
if(x_move < -32768/2)
	eventstate |= ( HID_EVENT_LEFT );

if(y_move > 32768/2)
	eventstate |= ( HID_EVENT_DOWN );
			
if(y_move < -32768/2)
	eventstate |= ( HID_EVENT_UP );

GET_JOY(0, eventstate, HID_EVENT_A);
GET_JOY(1, eventstate, HID_EVENT_B);
GET_JOY(2, eventstate, HID_EVENT_L);
GET_JOY(3, eventstate, HID_EVENT_R);
GET_JOY(4, eventstate, HID_EVENT_START);
GET_JOY(5, eventstate, HID_EVENT_SELECT);
}

SetHID_Events( eventstate ); // Setting GBA events
SDL_PumpEvents();            // We need this to pump the event queue 

otherwise it won’t work.
}> -----Oorspronkelijk bericht-----

Van: serenity [mailto:serenity at nosubstancesoftware.com]
Verzonden: donderdag 25 juli 2002 12:00
Aan: sdl
Onderwerp: [SDL] Event handling questions

I’m writing a game in c++ using SDL.

I’m curious as to the best way to handle events from SDL.

I have separate objects for the various players, and each
player needs to
detect if the appropriate keys have been pressed or not.

The best way, I assume, is to poll through the events at the
point I need
the keypresses.
The problem is that if I poll through the events in one
player’s object,
then the key press may be removed and not detected again when
the second
player’s controls come around.

The other way, I guess, is to pump_events at the beginning of
my loop and
check the status of the various keys at the end.

I’ve been trying the second way, but sometimes my game goes crazy with
events that seem to hang around in the queue.

When I call pump_events does this clear the current event queue?

I was wondering if other people had any ideas as to how best
to manage game
input when requiring input detection in various locations.

Thanks.


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

Thanks very much, shall look at and see what I’m doing differently.> ----- Original Message -----

From: nwagenaar@digitaldynamics.nl (Niels Wagenaar)
To:
Sent: Thursday, July 25, 2002 8:17 PM
Subject: RE: [SDL] Event handling questions

With my emulator programms I had the exact same problem
and some more strange things (like that the key was stuck
in the events while the key wasn’t pressed).

I use the following function which resolved this issue.

I hope this is understanding code :wink:

Regards,

Niels Wagenaar

inline void BoycaMain::ProcessSDLKeys()
{
#define GET_KEY(x, b, v)
if (keystate[GetKeyVal(x)]) b |= v;

#define GET_JOY(x, b, v)
if(SDL_JoystickGetButton(joystick, GetVal(x)) == SDL_PRESSED) b |=
v;

Sint16 x_move = 0, y_move = 0;

unsigned int eventstate = 0;
char fpName[256];
char BAMfile[256];

keystate = SDL_GetKeyState(NULL); // First to initialize the

keystates
int mod = SDL_GetModState();

strcpy( fpName, romfile );

strcpy( BAMfile, romfile );
SelectFileExtension(BAMfile,".bam");

if(joy) {
x_move = SDL_JoystickGetAxis(joystick, 0);

y_move = SDL_JoystickGetAxis(joystick, 1);
}

#if defined(BEOS) || defined(TARGET_WIN32)
if((keystate[SDLK_RETURN]) && (mod & KMOD_LALT)) {
SDL_WM_ToggleFullScreen(gbascreen);
}
#endif

GET_KEY(2, eventstate, HID_EVENT_LEFT);
GET_KEY(3, eventstate, HID_EVENT_RIGHT);
GET_KEY(0, eventstate, HID_EVENT_UP);
GET_KEY(1, eventstate, HID_EVENT_DOWN);
GET_KEY(5, eventstate, HID_EVENT_SELECT);
GET_KEY(4, eventstate, HID_EVENT_START);
GET_KEY(6, eventstate, HID_EVENT_A);
GET_KEY(7, eventstate, HID_EVENT_B);
GET_KEY(8, eventstate, HID_EVENT_L);
GET_KEY(9, eventstate, HID_EVENT_R);

if ( keystate[SDLK_F1] ) { // Pause on

if (mod & KMOD_LALT)
{
savebank = 1;
printf(“Savebank %d selected\n”, savebank);
}
else
{
printf(“Emulator is now in pause mode!\n”);
SDL_PauseAudio(1);
emulation = -1;
}
}

if ( keystate[SDLK_F2] ) { // Pause off

if (mod & KMOD_LALT)
{
savebank = 2;
printf(“Savebank %d selected\n”, savebank);
}
else
{
emulation = 0;
SDL_PauseAudio(0);
printf(“Emulation continued!\n”);
}
}

if ( keystate[SDLK_F3] ) { // Framecounter on

if (mod & KMOD_LALT)
{
savebank = 3;
printf(“Savebank %d selected\n”, savebank);
}
else
{
printf(“Framecounter enabled.\n”);
framecounter = TRUE;
}
}

if ( keystate[SDLK_F4] ) { // Framecounter off

if (mod & KMOD_LALT)
{
savebank = 4;
printf(“Savebank %d selected\n”, savebank);
}
else
{
printf(“Framecounter disabled.\n”);
SDL_WM_SetCaption( VERSIONINTERNAL , “BOYCOTTADVANCE” );
framecounter = FALSE;
}
}

if ( keystate[SDLK_F5] ) { // Frameskip increase

if (mod & KMOD_LALT)
{
savebank = 5;
printf(“Savebank %d selected\n”, savebank);
}

}

if ( keystate[SDLK_F6] ) { // Frameskip decrease

if (mod & KMOD_LALT)
{
savebank = 6;
printf(“Savebank %d selected\n”, savebank);
}

}

if ( keystate[SDLK_F7] ) { // Save state save (not yet working in
0.21b)

if (mod & KMOD_LALT)
{
savebank = 7;
printf(“Savebank %d selected\n”, savebank);
}
else
{

Save_STATE( NULL, savebank );
printf(“Savestate saved to savebank %d.\n”, savebank);
}

}

if ( keystate[SDLK_F8] ) { // Save state load (net yet working in
0.21b)

 if (mod & KMOD_LALT)

{
savebank = 8;
printf(“Savebank %d selected\n”, savebank);
}
else
{

Load_STATE( NULL, savebank );
printf(“Savebank %d loaded into emulator\n”, savebank);
}
}

if ( keystate[SDLK_F9] ) { // Make screenshot

if (mod & KMOD_LALT)
{
savebank = 9;
printf(“Savebank %d selected\n”, savebank);
}
else
{

  strcpy(scrsht, screenshot);
  switch(scrno)
  {

case 1:
strcat(scrsht, “1”); break;
case 2:
strcat(scrsht, “2”); break;
case 3:
strcat(scrsht, “3”); break;
case 4:
strcat(scrsht, “4”); break;
case 5:
strcat(scrsht, “5”); break;
case 6:
strcat(scrsht, “6”); break;
case 7:
strcat(scrsht, “7”); break;
case 8:
strcat(scrsht, “8”); break;
case 9:
strcat(scrsht, “9”); break;
case 10:
strcat(scrsht, “10”); break;
}
strcat(scrsht, “.bmp”);
if (!OpenGL) {
SDL_SaveBMP(gbascreen, scrsht);
}
else
// BoycaGL->OpenGLScreenshot(scrsht);
printf(“Screenshot taking not supported under OpenGL
rendering.\n”);
}
if ( scrno < 10 )
printf(“Saving screenshot as %s\n”, scrsht);
scrno++;

}

if ( keystate[SDLK_F10] ) { // GBA Reset

if (mod & KMOD_LALT)
{
savebank = 10;
printf(“Savebank %d selected\n”, savebank);
}
else
{
printf(“GBA Reset\n”);
ResetGBA();
}
}

if ( keystate[SDLK_ESCAPE] ) { // ON/OFF key (well, definately more

off :slight_smile:
static char buffer[256];
sprintf (buffer, “%0.f FPS”, FrameTimer_lastFrameFPS());

printf(“Last know FPS : %s\n”, buffer );
FreeGeneric();
exit(1);
}

if ( keystate[SDLK_INSERT] ) // BAM MOVIE Recording

{
printf(“BAM movie-recording started to %s.\n”, BAMfile);
GBAStartMovie(BAMfile,1);
}

if ( keystate[SDLK_HOME] ) // BAM MOVIE recording stop!

{

printf(“BAM movie-recording/playing stopped.\n”);
GBAStopMovie();
}

if ( keystate[SDLK_PAGEUP] ) // BAM MOVIE recording play!

{

printf(“Playing BAM movie-recording %s.\n”, BAMfile);
GBAStartMovie(BAMfile,0);
}

if ( keystate[SDLK_KP_PLUS] ) // SpeedUp increase

{
EmuOptions.SpeedUp+=50;
if (EmuOptions.SpeedUp>=900) {
EmuOptions.SpeedUp=900;
} else {
printf ("- Current Speed Increase: %d%%\n",
(EmuOptions.SpeedUp*100)/900);
}
}

if ( keystate[SDLK_KP_MINUS] ) // SpeedUp increase

{
EmuOptions.SpeedUp-=50;
if (EmuOptions.SpeedUp<=0) {
EmuOptions.SpeedUp=0;
} else {
printf ("- Current Speed Decrease: %d%%\n",
(EmuOptions.SpeedUp*100)/900);
}
}

if(joy) {
if(x_move > 32768/2)
eventstate |= ( HID_EVENT_RIGHT ); // seems to work fine

if(x_move < -32768/2)
eventstate |= ( HID_EVENT_LEFT );

if(y_move > 32768/2)
eventstate |= ( HID_EVENT_DOWN );

if(y_move < -32768/2)
eventstate |= ( HID_EVENT_UP );

GET_JOY(0, eventstate, HID_EVENT_A);
GET_JOY(1, eventstate, HID_EVENT_B);
GET_JOY(2, eventstate, HID_EVENT_L);
GET_JOY(3, eventstate, HID_EVENT_R);
GET_JOY(4, eventstate, HID_EVENT_START);
GET_JOY(5, eventstate, HID_EVENT_SELECT);
}

SetHID_Events( eventstate ); // Setting GBA events
SDL_PumpEvents(); // We need this to pump the event queue
otherwise it won’t work.
}

-----Oorspronkelijk bericht-----
Van: serenity [mailto:@Robert_Sadedin]
Verzonden: donderdag 25 juli 2002 12:00
Aan: sdl
Onderwerp: [SDL] Event handling questions

I’m writing a game in c++ using SDL.

I’m curious as to the best way to handle events from SDL.

I have separate objects for the various players, and each
player needs to
detect if the appropriate keys have been pressed or not.

The best way, I assume, is to poll through the events at the
point I need
the keypresses.
The problem is that if I poll through the events in one
player’s object,
then the key press may be removed and not detected again when
the second
player’s controls come around.

The other way, I guess, is to pump_events at the beginning of
my loop and
check the status of the various keys at the end.

I’ve been trying the second way, but sometimes my game goes crazy with
events that seem to hang around in the queue.

When I call pump_events does this clear the current event queue?

I was wondering if other people had any ideas as to how best
to manage game
input when requiring input detection in various locations.

Thanks.


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


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