4

I have a generic problem I suppose.

I`m currently learning C++ and SDL 2.0. SDL provides a function which returns a pointer to a const uint * containing all the keystates.

These are the variables I would like to use:

const Uint8* oldKeyState;
const Uint8* currentKeyState;

In the construction of my input.cpp:

currentKeyState = SDL_GetKeyboardState(&this->length);
    oldKeyState =  currentKeyState;

And in the Update() method I use:

oldKeyState = currentKeyState;
currentKeyState = SDL_GetKeyboardState(NULL);

However, instead of copying over the last values, all I do is giving a pointer to the oldKeyState, which in turn points to the current keystates..

So how do I go about copying the actual values from the variable's pointer to the current and old keystate? I don't want the pointer in my old keystate since I will not be able to check whether the previous state was UP and the new state is DOWN.

user57368
  • 5,675
  • 28
  • 39
Symphlion
  • 63
  • 1
  • 5
  • Do you know how large the key state array is? (I haven't programmed SDL 2.0, only 1.2.) If you do know how large it is, then you can `new` that amount of memory and use `std::memcpy` to copy the state out from the pointer provided by `SDL_GetKeyboardState()`. In my own programs, I actually watch for keydown/keyup SDL events instead of scanning a state table like this. – Joe Z Dec 02 '13 at 06:56
  • If i`m correct, if you pass an integer value within the SDL_GetKeyboardState( myVar ), myVar will be updated with the length of the array. – Symphlion Dec 02 '13 at 16:44
  • @Symphlion no, it takes pointer to integer, not integer. If function takes int, it cannot update its value. But yes, it is sets this int to size of array. Anyway, maximum value is 512 - probably too low to bear with overhead of separate `new`. – keltar Dec 02 '13 at 17:54

4 Answers4

3
Uint8 oldKeyState[SDL_NUM_SCANCODES];

// ...

memcpy(oldkeystate, currentKeyState, length);
keltar
  • 17,711
  • 2
  • 37
  • 42
  • I tried doing this, but apparently, i`m getting all kinds of errors with pointers.. – Symphlion Dec 02 '13 at 17:42
  • I don't think anyone could help with 'all kinds of errors'. I surely can't. Please be specific. In truth, you should [re]learn pointers, as your comments shows poor understanding - but i could still answer a question or two if it wouldn't require some telepathic abilities. Edit your question to add more information, like modified code and error messages. – keltar Dec 02 '13 at 17:51
2

The signature of the function you're calling is

const Uint8* SDL_GetKeyboardState(int* numkeys)

This function has return type const Uint8*, which means it returns a pointer to byte(s). (It does not return a pointer to a pointer.) According to the documentation, this returned pointer actually points to an array of Uint8 (one Uint8 is not big enough to encode the states of all the keys on the keyboard), and the value pointed to by numkeys is overwritten with the length of that array (ie. the number of keys). So to preserve the values in the array, you need to allocate a region of memory the same length as gets stored in this->length, and then copy that memory from SDL's array to your own. Then you'll want to keep a pointer to your own array around for you to continue to use. Because SDL says that the returned pointer to the array is valid for the entire lifetime of the application, you may assume that the length is unchanging, so you don't need to worry about resizing your array, but you should worry about deallocating that memory when you're done with it.

user57368
  • 5,675
  • 28
  • 39
2

So, I think SDL is mostly a C library.

The const Uint8* returned by SDL_GetKeyboardState is a pointer to the first element in an array in values. If you want to copy a given state for later reference, you would generally need an array to copy them to, and a for loop to do the copying. eg:

currentKeyState = SDL_GetKeyboardState(&this->length);
savedKeyState = malloc(this->length*sizeof(Uint8));
for(int i=0; i<&this-length, i++) savedKeyState [i] = currentKeyState[i];

Of course that pretty poor code, using a vector might be a better way to go, something like:

currentKeyState = SDL_GetKeyboardState(&this->length);
vector savedKeyState(currentKeyState, currentKeyState+length);
RichardPlunkett
  • 2,998
  • 14
  • 14
1

The problem you have here is that you are trying to copy the pointer to a const array, which never changes. As a result, you will see that both pointers go to the same memory address, and you never have two copies of the input state which allows you to check for pressed keys.

Instead, you should use memcpy to copy one array to the other. But in order to do so, you should change the type of oldKeyState to just Uint8*, or else you will get an error for copying into a const array.

So, the code should end up like this:

const Uint8 * currentKeyState;
Uint8 * oldKeyState;

...

//Constructor
currentKeyState = SDL_GetKeyboardState(&this->length);
oldKeyState = new Uint8[this->length];

...

//Input update
memcpy(oldKeyState, currentKeyState, this->length);
SDL_PumpEvents(); //Copy the array before calling PumpEvents()!
currentKeyState = SDL_GetKeyboardState(NULL);
Osguima3
  • 151
  • 10