Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL/GLUT keyboard managed with bool*: all values appear to be set to ints at second initialisation. Any ideas?

Tags:

c++

opengl

glut

Making a game with OpenGL/GLUT and C++.

I've heard the easiest way to manage keyboard stuff in GLUT is to use an array of bools.

So basically, here's what I have:

bool* keys = new bool[256];

...

void keyDown(unsigned char ch, int x, int y)
{
    keys[ch] = true;    
}

void keyUp(unsigned char ch, int x, int y)
{
    keys[ch] = false;
}

Then if I want to know the state of a key, I just return keys[key].

I have a similar setup for the special keys. Now, in my game when you die, it resets all the values that need to be reset and starts the game again. Until just now, that included

keys = new bool[256];

and a similar declaration for the special keys array. What makes no sense to me is that occasionally, this supposed resetting of the arrays would cause some or all of the values in keys to become two- or three-digit integers (therefore always evaluating true and making the player character move uncontrollably until one or more of the keys that were apparently down were depressed). I have a suspicion that this happened because at time of endgame one of the keys was pressed down, thereby confusing C++ when it tried to make the whole array false and found that one thing was stuck true.

Man, that's confusing. The problem has been solved by eliminating all the extra initialisations of keys, as far as I can see. But I don't get it. Anyone got any ideas on how I managed to turn some bools into ints?

like image 295
PROGRAM_IX Avatar asked Jan 20 '26 19:01

PROGRAM_IX


2 Answers

This statement

keys = new bool[256];

Allocates memory. It does not initialize that memory to any particular value. To do that, you could do a memset(keys, 0, sizeof(bool) * 256) to zero.

However, you shouldn't allocate memory (which is what new does) to reinitialize an array. You should actually reinitialize it, using memset or whatever feature you used to initialize it with "false" values.

Lastly, why are you allocating this array with new to begin with? Just make it a global array: bool keys[256]. Initialize it (with memset) before you use it, and everything will be fine.

I would have suggested a std::vector<bool>, but sadly, those are not usable. You could use a std::vector<char> though, with 0 meaning false. Or a std::bitset with 256 bits. All of these contain their allocations internally (thus being safe), and have ways to clear their memory to some value.

making a game with OpenGL/GLUT and C++.

As an aside, I wouldn't advise that. GLUT isn't a tool designed for the kinds of timings that most games need. GLFW allows you to control the main loop, rather than using callbacks, so it is a more appropriate tool for a game.

like image 185
Nicol Bolas Avatar answered Jan 23 '26 08:01

Nicol Bolas


Because of CPU granularity you can only access things as a byte therefore bools always resolve to some kind of unsigned char type which are 1 byte in size. This way you can get from 0-255 range in values. What happens is that any non zero value is true and 0 is false. We can't implement bool as a single bit (except in C++ STL vector etc... where they are converted to bitfields) because of that granularity unless you decide to make an array and index bits in particular entries.

like image 37
Jesus Ramos Avatar answered Jan 23 '26 09:01

Jesus Ramos