Disable event buffer SDL2 when holding down a key - c++

I'm currently developing a server-client game and I'm having trouble with SDL2 event queue. The following code is used to move the character:
void handleEvent( SDL_Event& e) {
if( e.type == SDL_KEYDOWN ) {
switch( e.key.keysym.sym ) {
case SDLK_LEFT:
// Do something and send key to server
break;
case SDLK_RIGHT:
// Do something and send key to server
break;
case SDLK_UP:
// Do something and send key to server
break;
}
}
else if( e.type == SDL_KEYUP ) {
switch( e.key.keysym.sym ) {
case SDLK_LEFT:
// Do something and send key to server
break;
case SDLK_RIGHT:
// Do something and send key to server
break;
case SDLK_UP:
// Do something and send key to server
break;
}
}
}
There seems to be some kind of event buffer when a key is being hold down. Basically if I rapidly tap the arrow keys, the keys are instantly sent to the server. But when I hold down the arrow I instantly get only one key message (the initial tap one) and after 200ms I start getting the stream of keys. The behaviour I am aiming for is to always get the stream of the key being pressed at that time asap.
I am purposely avoiding the use of (e.key.repeat == 0) because I need to send every key press to the server to update the server's character logic object position correctly.

Related

SDL cannot read input from keyboard

I am having trouble dealing with input from the keyboard. Somehow all the letter ones are extremely slow(always a big delay), most of the time it just doesn't load at all. But the up down left right and number keys all work really well. Does anyone know why?
This is my program:
while (!quit)
{
while (SDL_PollEvent(&e) != 0 )
{
SDL_StartTextInput();
//User requests quit
switch (e.type) {
case SDL_QUIT:
quit = true;
break;
case SDL_TEXTINPUT:
if (e.key.keysym.sym == SDLK_w)
std::cout << "w ";
break;
case SDL_KEYDOWN:
if (e.key.keysym.sym == SDLK_1)
std::cout << "1 ";
break;
}
As already mentioned in your comments, you never check the event type.
event.type can be SDL_TEXTINPUT or SDL_KEYDOWN for example.
Here I have a typical event loop copied from one of my projects:
while (SDL_PollEvent(&event)) {
SDL_StartTextInput();
switch (event.type) {
case SDL_QUIT:
appRunning = false;
break;
case SDL_TEXTINPUT:
// here you can use event.text.text; to
break;
case SDL_KEYDOWN:
char keyDown = event.key.keysym.scancode;
break;
}
}
Here is the official list of SDL_Events: https://wiki.libsdl.org/SDL2/SDL_Event
SDL provides event handlers for keyboard input.
SDL_Event e;
.
.
/* Poll for events. SDL_PollEvent() returns 0 when there are no */
/* more events on the event queue, our while loop will exit when */
/* that occurs. */
while(SDL_PollEvent(&e)){
/* We are only worried about SDL_KEYDOWN and SDL_KEYUP events */
switch(event.type){
case SDL_KEYDOWN:
//Keypress
break;
case SDL_KEYUP:
//Key Release
break;
default:
break;
}
Then, you can get the value of key->keysym.sym for the keyboard input.

Open GL SDL Keypresses and behaviours mismatched on program start

I'm developing a simple game in OpenGL and using the SDL library to handle my input.
The game uses several keyboard buttons for input. Two arrow keys, the space bar, the 'r' button to reset the game and escape to close it.
What's currently happening is that the output or the methods being called when these buttons are pressed when I first launch the game are mismatched. (i.e left arrow performs the right arrow's method). This random behaviour ends once I press each of the buttons the game uses apart from the escape button once.
I'm wondering if there is something I'm missing as it feels like I have to 'assign' each button on each launch of the game. I've provided my input handling code below.
if (e.type == SDL_KEYDOWN) {
switch (e.key.keysym.sym) {
case SDLK_ESCAPE:
m_isClosed = true;
break;
case SDLK_SPACE:
m_selection = true;
break;
case SDLK_LEFT:
m_leftPressed = true;
break;
case SDLK_RIGHT:
m_rightPressed = true;
break;
case SDLK_r:
m_reset = true;
break;
}
}
if(e.type == SDL_KEYUP)
switch (e.key.keysym.sym)
{
case SDLK_LEFT:
m_leftPressed = false;
m_keydown = false;
break;
case SDLK_RIGHT:
m_rightPressed = false;
m_keydown = false;
break;
case SDLK_SPACE:
m_selection = false;
m_keydown = false;
break;
case SDLK_r:
m_reset = false;
m_keydown = false;
break;
}
}
Each event handler simply sets a boolean used for the game logic in another class. If you think you need to see anymore code in order to help me let me know.
It turns out that I had not initialised the booleans corresponding to the button listeners to false. A silly mistake but I thought I should provide the solution nonetheless.

How do I switch two keyboard key actions?

I have a dialog-based MFC project. I have the ON_WM_KEYDOWN() function working and when I press the down key it does what it should.
Now I want to change the down key to the 'w' key, and the left key to 'a', etc. I have very basic MFC knowledge, I am not sure what function I should add and what part of the program to change.
My ON_WM_KEYDOWN() function looks as follows:
if(pMsg->message == WM_KEYDOWN)
{
switch(pMsg->wParam)
{
// Disable OK & Cancel function
case VK_ESCAPE:
case VK_RETURN:
return TRUE;
}
}
The variable pMsg->wParam contains the key that has been pressed. You can look up the key codes here. As a result, you need some code similar to the following in your ON_WM_KEYDOWN handler:
if(pMsg->message == WM_KEYDOWN)
{
switch(pMsg->wParam)
{
case 0x57:
// W key. Put code for "up" here...
break;
case 0x41:
// A key. Put code for "left" here...
break;
case 0x53:
// S key. Put code for "down" here...
break;
case 0x44:
// D key. Put code for "right" here...
break;
// Disable OK & Cancel function
case VK_ESCAPE:
case VK_RETURN:
return TRUE;
}
}
If you want the A key to perform the same action of the cursor-left key, for example, then you could do that by sending a VK_LEFT via a WM_KEYDOWN message with the PostMessage function:
PostMessage(WM_KEYDOWN, VK_LEFT, 0);
However, I didn't try this and I don't know if it's a good style to do so.

SDL event loop quitting?

I am making an RTS in C++ using SDL for graphics.
Every time I run the game, it crashes without errors or anything in the compiler debug window. It doesn't crash immediately or consistently, sometimes taking 10 seconds to crash and other times taking 2 minutes to crash.
When I played around with return values (at the end of the main function) it turned out it wasn't crashing, but rather quitting as the return values were consistent with what I changed it to.
The only theory that I have is that my poll event loop is glitching and telling the program to quit when it isn't supposed to.
Here is my event loop, contained within my game loop:
if( SDL_PollEvent( &event ) )
{
if( event.type == SDL_MOUSEMOTION )
{
mx = event.motion.x;
my = event.motion.y;
}
if( event.type == SDL_MOUSEBUTTONDOWN )
{
if( hut.getselected() && hut.getplacable() )
{
hut.place( map );
}
}
if( event.type == SDL_QUIT )
{
quit = true;
}
switch( event.key.keysym.sym )
{
case SDLK_ESCAPE: quit = true; break;
}
}
Is it possible that when the mouse moves or clicks, that it is confusing it for exiting? I don't think the ram is overloading either because it only displays what it needs to tile-wise.
Is it also possible that my compiler, VisualC++, is screwing up?
How about changing the switch at end of your snippet to:
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE) {
quit = true;
}
Because in your code you check keysym for all events, so usually event is of wrong type when you test if it is escape, and you get "garbage" value for keysym, and sometimes it matches with ESC.
Actually might be good idea to test the event.type with switch:
switch(event.type) {
case SDL_MOUSEMOTION:
//....
break;
case SDK_KEYDOWN:
switch(event.key.keysym.sym) {
case SDLK_ESCAPE:
quit = true;
break;
// cases for other keypresses
}
break;
// cases for other events
}

Hook Keyboard to change the key code

I have buy this keyboard http://www.mobilitylab.eu/mini-design-touch-silver.html of 107 touch,
and I want a keypad to put it on my left hand.
but when we activate the numlock of the keypad, it activates the numlock on the keyboard.
So we have 456- instead of uiop.
I have found this program but it don't work on a 64 bits OS. http://www.bellamyjc.org/fr/systeme.html#knumlock.
So i want to do my own program with C++, but it don't work fine, the hook is allright (WH_GETMESSAGE) but i don't understand how we can change the keycode and how we can find if it's a key of the keypad or the keybord ?
Here this is my code where i try to change the message :
//-----------------Keyboard Hook Callback---------------//
Hookmsg_API LRESULT CALLBACK Hookmsg(int ncode,WPARAM wparam,LPARAM lparam){
//if(ncode>=0) //
if(ncode<0)
return CallNextHookEx(hook,ncode,wparam,lparam);
MSG *msg;
msg=(MSG *)lparam;
WORD newVK,oldVK;
WORD newSC,oldSC;
if(ncode==HC_ACTION)
{
if((msg->message == WM_KEYUP))//Check whether key was pressed(not released).)
{
oldVK=msg->wParam;
oldSC=SCANCODE(msg->lParam);
bool extendkey=false;
if(((HIWORD(msg->wParam) & 0x0100) == 0x0100))
{
extendkey=true;
}
if(!extendkey)
{
bool modif=true;
switch(oldVK)//wparam
{
case VK_INSERT: newVK=VK_NUMPAD0; break;
case VK_END: newVK=VK_NUMPAD1; break;
case VK_DOWN: newVK=VK_NUMPAD2; break;
case VK_NEXT: newVK=VK_NUMPAD3; break;
case VK_LEFT: newVK=VK_NUMPAD4; break;
case VK_CLEAR: newVK=VK_NUMPAD5; break;
case VK_RIGHT: newVK=VK_NUMPAD6; break;
case VK_HOME: newVK=VK_NUMPAD7; break;
case VK_UP: newVK=VK_NUMPAD8; break;
case VK_PRIOR: newVK=VK_NUMPAD9; break;
case VK_DELETE: newVK=VK_DECIMAL; break;
default: modif=false;
}
if(modif==true)
{
msg->wParam = VK_NUMPAD0;
UINT newSC=MapVirtualKey(VK_NUMPAD0,MAPVK_VK_TO_VSC);
msg->lParam &= 0xFF00;
msg->lParam += (newSC << 16 );
//MessageBox( NULL, TEXT("OK"), TEXT("Error!"), MB_OK);
}
}
}
}
return ( CallNextHookEx(hook,ncode,wparam,lparam) );//pass control to next hook in the hook chain.
}
cant understand u...
u have 2 keyboards? if yes, try to use Raw Input (raw data from USB HID device)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms645543(v=vs.85).aspx
Lparam and wparam are not visible for other applications.
Keyboard input is much more than just windows messages. Modifying the messages will work in some cases, but is a vastly incomplete solution. You also need to consider driver state, GetKeyboardState, and others.
If you want to remap keys on your keyboard, you can create a new keyboard layout and assign it to a locale.
If keyboard layouts don't satisfy your needs, you will need to write a keyboard device driver.
If you only need this functionality in a specific application (not system globally), then you might be able to get lucky and only modify windows messages.