2
\$\begingroup\$

I'm teaching myself 3D graphics with OpenGL and SDL in C++. I'm at a point where I need to be able to query states of individual keys, like so:

if (InputManager::justPressed(SDLK_UP)) {}
if (InputManager::pressed(SDLK_UP)) {}
if (InputManager::justReleased(SDLK_UP) {}

I'm not sure if I should be using SDL_GetKeyboardState or bool arrays for SDL_Keycode/SDL_Scancode, using states seems to me to be the more correct way. I've implemented this previously using states in C# with XNA (see that here). But I've been unsuccessful trying to replicate that with SDL.

Method 1 - Using SDL_GetKeyboardState

// InputManager stores
Uint8* _curKeys, _oldKeys;

void InputManager::init() {
    _curKeys = SDL_GetKeyboardState(NULL);
    _oldKeys = new Uint8[sizeof(_curKeys)/sizeof(Uint8)];
}

void InputManager::update() {
    memcpy(_oldKeys, _curKeys, sizeof(_curKeys)/sizeof(Uint8)); // this seems to work
    std::copy(std::begin(_curKeys), std::end(_oldKeys), std::begin(_curKeys));
}

bool InputManager::pressed(SDL_Keycode code) {
    return _curKeys[code];
}

bool InputManager::justPressed(SDL_Keycode code) {
    return _curKeys[code] && !_oldKeys[code];
}

bool InputManager::justReleased(SDL_Keycode code) {
    return !_curKeys[code] && _oldKeys[code];
}

In the main loop I update the InputManager instance by copying the current keyboard state and updating the current state. Since I'm relatively new to C++ I'm unsure of exactly the best way to copy the values from _curKeys to _oldKeys without using a for-loop. I can't just set _oldKeys=_curKeys because that just makes _oldKeys point to _curKeys. But memcpy seemed to work.

With this implementation justReleased is constantly true, no matter what key is pressed, and justPressed and pressed are always false.

Method 2 -Array of bools

// SDL_PollEvent() loop
case SDL_KEYDOWN: InputManager::keyDown(//event keycode);
case SDL_KEYUP: InputManager::keyUp(//event keycode);

The keyDown and keyUp functions just set keyArray[keycode] to true and false. In the InputManager update function I once again duplicate of the array, simulating "states". But with this implementation all three functions are always false.

Anyway

I hope that this question wasn't too incoherent, I tried to explain it as best as I could. I've found some forums where people had similar problems, the criticism always was that this kind of functionality isn't needed. I would disagree, a good use case for this would be, for example, a charge-up weapon in a game. At justPressed you start the charge, increment a charge counter while pressed is true, and at justReleased you fire the weapon.

If anyone has any pointers for me (no pun intended :P) that would be awesome.

\$\endgroup\$
  • \$\begingroup\$ A follow up to the answer, for anyone else who may still be stuck. What msell is saying is that I can't calculate the size of the _curKeys array because it is a dynamic array, aka it was allocated with the "new" keyword and is just a pointer to memory. There is a great answer here describing dynamic and static arrays: stackoverflow.com/questions/2672085/… \$\endgroup\$ – bpercevic Jan 7 '15 at 17:58
  • \$\begingroup\$ std::copy(std::begin(_curKeys), std::end(_oldKeys), std::begin(_curKeys)); has wrong arguments. On top of that, only one of memcpy or std::copy is needed - after fixing, they should do exactly the same in this case. \$\endgroup\$ – Sjoerd Sep 30 '15 at 22:43
2
\$\begingroup\$

sizeof(_curKeys)/sizeof(Uint8) does not give you the size of the array, because it's just a pointer from compiler's point of view.

Instead of passing NULL as an argument to SDL_GetKeyboardState();, pass a pointer to an integer and the function will write the length of the array to that integer. See documentation. Use that value for both allocating _oldKeys and memcpying the data.

\$\endgroup\$
  • \$\begingroup\$ Ok thank you for the answer, I need more c++ experience and I need to read the docs more carefully. Thanks again! \$\endgroup\$ – bpercevic Jan 5 '15 at 8:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.