The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
keyboard input question
knd


Joined: 29 Jan 2014
Posts: 5
Hi every1.
Here's my task:
I need to know exactly what key was pushed down/released up during the exact current frame. So that on the next frame keys that being held won't generate duplicate events/messages.
Still, I want to get repeated key events.

My current solution is:
Code:

   const Uint8* curKeys = SDL_GetKeyboardState( 0 );
      const Uint8* newKeys = curKeys;
      Uint8 downKeys[ 512 ];
      Uint8 upKeys[ 512 ];
   // main loop start
   while( running ) {
      // ...
      // TODO: update input
         SDL_PumpEvents();
         newKeys = SDL_GetKeyboardState( 0 );
         for ( int i = 0; i < 512; i++ ) {
            downKeys[ i ] = 0;
            upKeys[ i ] = 0;
            if ( !curKeys[ i ] && newKeys[ i ] )
               downKeys[ i ] = 1;
            if ( curKeys[ i ] && !newKeys[ i ] )
               upKeys[ i ] = 1;
         }
         curKeys = newKeys;

         if ( curKeys [ SDL_SCANCODE_F ] )
            std::cerr << "'f' is pressed\n";
         if ( downKeys [ SDL_SCANCODE_F ] )
            std::cerr << "'f' is down\n";
         if ( upKeys [ SDL_SCANCODE_F ] )
            std::cerr << "'f' is up\n";
      //...
   }


The problem is that downKeys and upKeys are not functional - I'm getting response only from curKeys.
What am I doing wrong ? Somebody? Smile
knd


Joined: 29 Jan 2014
Posts: 5
So yeah...
The solution is pretty simple.
So there is how to implement basic SDL2 'buffered/unbuffered' keyboard input class.

Code:
#define INPUT_NUM_SCANCODES 512

// -- basic input-handling class
class Input {
   public:
            Input      ();
            ~Input      ();
      void    Update      ();
      bool   GetKey      ( const int );
      bool   GetKeyDown   ( const int );
      bool   GetKeyUp   ( const int );
   public:
      bool    textMode;

   private:

      bool       currentKeys[ INPUT_NUM_SCANCODES ];
      bool       downKeys[ INPUT_NUM_SCANCODES ];
      bool       upKeys[ INPUT_NUM_SCANCODES ];
      SDL_Event    event;
};

// -- implementation


Input::Input() {
   textMode = false;
}

Input::~Input() {
}

void Input::Update(){
   for ( int i = 0; i < INPUT_NUM_SCANCODES; i++ ) {
      downKeys[ i ] = false;
      upKeys[ i ] = false;
   }
   while( SDL_PollEvent( &event ) ) {
      if ( SDL_KEYDOWN == event.type ) {
         int value = event.key.keysym.scancode;
         if ( !currentKeys[ value ] && !textMode )
            downKeys[ value ] = true;
         else if ( textMode )
            downKeys[ value ] = true;
         currentKeys[ value ] = true;
      }
      if ( SDL_KEYUP == event.type ) {
         int value = event.key.keysym.scancode;
         upKeys[ value ] = true;
         currentKeys[ value ] = false;
      }
   }

}

bool Input::GetKey( const int key ) {
   return currentKeys[ key ];
}

bool Input::GetKeyDown( const int key ) {
   return downKeys[ key ];
}

bool Input::GetKeyUp( const int key ) {
   return upKeys[ key ];
}


Maybe it's a bit of SDL internals reimplementation, but it's a bit more intuitive, I think. And it works Smile

Thanks to everyone, again.