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\$
2
  • \$\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, 2015 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, 2015 at 22:43

1 Answer 1

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\$
1
  • \$\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, 2015 at 8:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .