/* * Updates the input queue state. Called every * frame by the client and does nearly all the * input magic. */ void IN_Update(void) { qboolean want_grab; SDL_Event event; unsigned int key; /* Get and process an event */ while (SDL_PollEvent(&event)) { switch (event.type) { #if SDL_VERSION_ATLEAST(2, 0, 0) case SDL_MOUSEWHEEL: Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), true, true); Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), false, true); break; #endif case SDL_MOUSEBUTTONDOWN: #if !SDL_VERSION_ATLEAST(2, 0, 0) if (event.button.button == 4) { Key_Event(K_MWHEELUP, true, true); Key_Event(K_MWHEELUP, false, true); break; } else if (event.button.button == 5) { Key_Event(K_MWHEELDOWN, true, true); Key_Event(K_MWHEELDOWN, false, true); break; } #endif /* fall-through */ case SDL_MOUSEBUTTONUP: switch (event.button.button) { case SDL_BUTTON_LEFT: key = K_MOUSE1; break; case SDL_BUTTON_MIDDLE: key = K_MOUSE3; break; case SDL_BUTTON_RIGHT: key = K_MOUSE2; break; case SDL_BUTTON_X1: key = K_MOUSE4; break; case SDL_BUTTON_X2: key = K_MOUSE5; break; default: return; } Key_Event(key, (event.type == SDL_MOUSEBUTTONDOWN), true); break; case SDL_MOUSEMOTION: if (cls.key_dest == key_game && (int) cl_paused->value == 0) { mouse_x += event.motion.xrel; mouse_y += event.motion.yrel; } break; #if SDL_VERSION_ATLEAST(2, 0, 0) case SDL_TEXTINPUT: if ((event.text.text[0] >= ' ') && (event.text.text[0] <= '~')) { Char_Event(event.text.text[0]); } break; #endif case SDL_KEYDOWN: #if !SDL_VERSION_ATLEAST(2, 0, 0) if ((event.key.keysym.unicode >= SDLK_SPACE) && (event.key.keysym.unicode < SDLK_DELETE)) { Char_Event(event.key.keysym.unicode); } #endif /* fall-through */ case SDL_KEYUP: { qboolean down = (event.type == SDL_KEYDOWN); #if SDL_VERSION_ATLEAST(2, 0, 0) /* workaround for AZERTY-keyboards, which don't have 1, 2, ..., 9, 0 in first row: * always map those physical keys (scancodes) to those keycodes anyway * see also https://bugzilla.libsdl.org/show_bug.cgi?id=3188 */ SDL_Scancode sc = event.key.keysym.scancode; if (sc >= SDL_SCANCODE_1 && sc <= SDL_SCANCODE_0) { /* Note that the SDL_SCANCODEs are SDL_SCANCODE_1, _2, ..., _9, SDL_SCANCODE_0 * while in ASCII it's '0', '1', ..., '9' => handle 0 and 1-9 separately * (quake2 uses the ASCII values for those keys) */ int key = '0'; /* implicitly handles SDL_SCANCODE_0 */ if (sc <= SDL_SCANCODE_9) { key = '1' + (sc - SDL_SCANCODE_1); } Key_Event(key, down, false); } else #endif /* SDL2; (SDL1.2 doesn't have scancodes so nothing we can do there) */ if ((event.key.keysym.sym >= SDLK_SPACE) && (event.key.keysym.sym < SDLK_DELETE)) { Key_Event(event.key.keysym.sym, down, false); } else { Key_Event(IN_TranslateSDLtoQ2Key(event.key.keysym.sym), down, true); } } break; #if SDL_VERSION_ATLEAST(2, 0, 0) case SDL_WINDOWEVENT: if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST || event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) { Key_MarkAllUp(); } else if (event.window.event == SDL_WINDOWEVENT_MOVED) { // make sure GLimp_GetRefreshRate() will query from SDL again - the window might // be on another display now! glimp_refreshRate = -1; } #else /* SDL1.2 */ case SDL_ACTIVEEVENT: if(event.active.gain == 0 && (event.active.state & SDL_APPINPUTFOCUS)) { Key_MarkAllUp(); } #endif break; #if SDL_VERSION_ATLEAST(2, 0, 0) case SDL_CONTROLLERBUTTONUP: case SDL_CONTROLLERBUTTONDOWN: /* Handle Controller Back button */ { qboolean down = (event.type == SDL_CONTROLLERBUTTONDOWN); if (event.cbutton.button == SDL_CONTROLLER_BUTTON_BACK) { Key_Event(K_JOY_BACK, down, true); } } break; case SDL_CONTROLLERAXISMOTION: /* Handle Controller Motion */ { char *direction_type; float threshold = 0; float fix_value = 0; int axis_value = event.caxis.value; switch (event.caxis.axis) { /* left/right */ case SDL_CONTROLLER_AXIS_LEFTX: direction_type = joy_axis_leftx->string; threshold = joy_axis_leftx_threshold->value; break; /* top/bottom */ case SDL_CONTROLLER_AXIS_LEFTY: direction_type = joy_axis_lefty->string; threshold = joy_axis_lefty_threshold->value; break; /* second left/right */ case SDL_CONTROLLER_AXIS_RIGHTX: direction_type = joy_axis_rightx->string; threshold = joy_axis_rightx_threshold->value; break; /* second top/bottom */ case SDL_CONTROLLER_AXIS_RIGHTY: direction_type = joy_axis_righty->string; threshold = joy_axis_righty_threshold->value; break; case SDL_CONTROLLER_AXIS_TRIGGERLEFT: direction_type = joy_axis_triggerleft->string; threshold = joy_axis_triggerleft_threshold->value; break; case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: direction_type = joy_axis_triggerright->string; threshold = joy_axis_triggerright_threshold->value; break; default: direction_type = "none"; } if (threshold > 0.9) threshold = 0.9; if (axis_value < 0 && (axis_value > (32768 * threshold))) axis_value = 0; else if (axis_value > 0 && (axis_value < (32768 * threshold))) axis_value = 0; // Smoothly ramp from dead zone to maximum value (from ioquake) // https://github.com/ioquake/ioq3/blob/master/code/sdl/sdl_input.c fix_value = ((float) abs(axis_value) / 32767.0f - threshold) / (1.0f - threshold); if (fix_value < 0.0f) fix_value = 0.0f; axis_value = (int) (32767 * ((axis_value < 0) ? -fix_value : fix_value)); if (cls.key_dest == key_game && (int) cl_paused->value == 0) { if (strcmp(direction_type, "sidemove") == 0) { joystick_sidemove = axis_value * joy_sidesensitivity->value; // We need to be twice faster because with joystic we run... joystick_sidemove *= cl_sidespeed->value * 2.0f; } else if (strcmp(direction_type, "forwardmove") == 0) { joystick_forwardmove = axis_value * joy_forwardsensitivity->value; // We need to be twice faster because with joystic we run... joystick_forwardmove *= cl_forwardspeed->value * 2.0f; } else if (strcmp(direction_type, "yaw") == 0) { joystick_yaw = axis_value * joy_yawsensitivity->value; joystick_yaw *= cl_yawspeed->value; } else if (strcmp(direction_type, "pitch") == 0) { joystick_pitch = axis_value * joy_pitchsensitivity->value; joystick_pitch *= cl_pitchspeed->value; } else if (strcmp(direction_type, "updown") == 0) { joystick_up = axis_value * joy_upsensitivity->value; joystick_up *= cl_upspeed->value; } } if (strcmp(direction_type, "triggerleft") == 0) { qboolean new_left_trigger = abs(axis_value) > (32767 / 4); if (new_left_trigger != left_trigger) { left_trigger = new_left_trigger; Key_Event(K_TRIG_LEFT, left_trigger, true); } } else if (strcmp(direction_type, "triggerright") == 0) { qboolean new_right_trigger = abs(axis_value) > (32767 / 4); if (new_right_trigger != right_trigger) { right_trigger = new_right_trigger; Key_Event(K_TRIG_RIGHT, right_trigger, true); } } } break; /* Joystick can have more buttons than on general game controller * so try to map not free buttons */ case SDL_JOYBUTTONUP: case SDL_JOYBUTTONDOWN: { qboolean down = (event.type == SDL_JOYBUTTONDOWN); /* Ignore back button, we dont need event for such button */ if (back_button_id == event.jbutton.button) return; if (event.jbutton.button <= (K_JOY32 - K_JOY1)) { Key_Event(event.jbutton.button + K_JOY1, down, true); } } break; case SDL_JOYHATMOTION: { if (last_hat != event.jhat.value) { char diff = last_hat ^event.jhat.value; int i; for (i = 0; i < 4; i++) { if (diff & (1 << i)) { /* check that we have button up for some bit */ if (last_hat & (1 << i)) Key_Event(i + K_HAT_UP, false, true); /* check that we have button down for some bit */ if (event.jhat.value & (1 << i)) Key_Event(i + K_HAT_UP, true, true); } } last_hat = event.jhat.value; } } break; #endif case SDL_QUIT: Com_Quit(); break; } } /* Grab and ungrab the mouse if the console or the menu is opened */ if (in_grab->value == 3) { want_grab = windowed_mouse->value; } else { want_grab = (vid_fullscreen->value || in_grab->value == 1 || (in_grab->value == 2 && windowed_mouse->value)); } /* calling GLimp_GrabInput() each is a bit ugly but simple and should work. * + the called SDL functions return after a cheap check, if there's * nothing to do, anyway. */ GLimp_GrabInput(want_grab); /* We need to save the frame time so other subsystems know the * exact time of the last input events. */ sys_frame_time = Sys_Milliseconds(); }
/* * Updates the state of the input queue */ void IN_Update(void) { SDL_Event event; static int IN_Update_Flag; int bstate; /* Protection against multiple calls */ if (IN_Update_Flag == 1) { return; } IN_Update_Flag = 1; #if defined(WIZ) || defined(CAANOO) uint32_t key; uint8_t update; uint8_t button; uint8_t state; SDLKey keymap; GPH_Input(); for (button=0; button<GPH_MAX_BUTTONS; button++) { keymap = gph_map[button]; state = GPH_GetButttonState( GPH_BUTTON(button) ) ; if (state == GPH_RELEASED_TO_PRESSED) { KeyStates[keymap] = 1; update = 1; printf( "GPH press %d\n", button ); } else if (state == GPH_PRESSED_TO_RELEASED) { if (KeyStates[keymap]) { KeyStates[keymap] = 0; update = 1; printf( "GPH release %d\n", button ); } } else { update = 0; } if (update) { /* Get the pressed key and add it to the key list */ key = IN_TranslateSDLtoQ2Key(keymap); if (key) { keyq[keyq_head].key = key; keyq[keyq_head].down = KeyStates[keymap] ? true : false; keyq_head = (keyq_head + 1) & 127; } } } #else while (SDL_PollEvent(&event)) { IN_GetEvent(&event); } #endif /* Mouse button processing. Button 4 and 5 are the mousewheel and thus not processed here. */ if (!mx && !my) { SDL_GetRelativeMouseState(&mx, &my); } mouse_buttonstate = 0; bstate = SDL_GetMouseState(NULL, NULL); if (SDL_BUTTON(1) & bstate) { mouse_buttonstate |= (1 << 0); } if (SDL_BUTTON(3) & bstate) { mouse_buttonstate |= (1 << 1); } if (SDL_BUTTON(2) & bstate) { mouse_buttonstate |= (1 << 2); } if (SDL_BUTTON(6) & bstate) { mouse_buttonstate |= (1 << 3); } if (SDL_BUTTON(7) & bstate) { mouse_buttonstate |= (1 << 4); } /* Grab and ungrab the mouse if the console is opened */ if (in_grab->value == 2) { if (old_windowed_mouse != windowed_mouse->value) { old_windowed_mouse = windowed_mouse->value; if (!windowed_mouse->value) { SDL_WM_GrabInput(SDL_GRAB_OFF); } else { SDL_WM_GrabInput(SDL_GRAB_ON); } } } else if (in_grab->value == 1) { SDL_WM_GrabInput(SDL_GRAB_ON); } else { SDL_WM_GrabInput(SDL_GRAB_OFF); } /* Process the key events */ while (keyq_head != keyq_tail) { in_state->Key_Event_fp(keyq[keyq_tail].key, keyq[keyq_tail].down); keyq_tail = (keyq_tail + 1) & 127; } IN_Update_Flag = 0; }
/* * Input event processing */ void IN_GetEvent(SDL_Event *event) { unsigned int key; switch(event->type) { /* The mouse wheel */ case SDL_MOUSEBUTTONDOWN: if (event->button.button == 4) { keyq[keyq_head].key = K_MWHEELUP; keyq[keyq_head].down = true; keyq_head = (keyq_head + 1) & 127; keyq[keyq_head].key = K_MWHEELUP; keyq[keyq_head].down = false; keyq_head = (keyq_head + 1) & 127; } else if (event->button.button == 5) { keyq[keyq_head].key = K_MWHEELDOWN; keyq[keyq_head].down = true; keyq_head = (keyq_head + 1) & 127; keyq[keyq_head].key = K_MWHEELDOWN; keyq[keyq_head].down = false; keyq_head = (keyq_head + 1) & 127; } break; case SDL_MOUSEBUTTONUP: break; /* The user pressed a button */ case SDL_KEYDOWN: /* Fullscreen switch via Alt-Return */ if ( (KeyStates[SDLK_LALT] || KeyStates[SDLK_RALT]) && (event->key.keysym.sym == SDLK_RETURN) ) { cvar_t *fullscreen; #if !defined(USE_EGL_RAW) SDL_WM_ToggleFullScreen(surface); if (surface->flags & SDL_FULLSCREEN) { ri.Cvar_SetValue( "vid_fullscreen", 1 ); } else { ri.Cvar_SetValue( "vid_fullscreen", 0 ); } fullscreen = ri.Cvar_Get( "vid_fullscreen", "0", 0 ); fullscreen->modified = false; #endif break; } KeyStates[event->key.keysym.sym] = 1; /* Get the pressed key and add it to the key list */ key = IN_TranslateSDLtoQ2Key(event->key.keysym.sym); if (key) { keyq[keyq_head].key = key; keyq[keyq_head].down = true; keyq_head = (keyq_head + 1) & 127; } break; /* The user released a key */ case SDL_KEYUP: if (KeyStates[event->key.keysym.sym]) { KeyStates[event->key.keysym.sym] = 0; /* Get the pressed key and remove it from the key list */ key = IN_TranslateSDLtoQ2Key(event->key.keysym.sym); if (key) { keyq[keyq_head].key = key; keyq[keyq_head].down = false; keyq_head = (keyq_head + 1) & 127; } } break; } }
/* * Updates the input queue state. Called every * frame by the client and does nearly all the * input magic. */ void IN_Update(void) { qboolean want_grab; SDL_Event event; unsigned int key; /* Get and process an event */ while (SDL_PollEvent(&event)) { switch (event.type) { #if SDL_VERSION_ATLEAST(2, 0, 0) case SDL_MOUSEWHEEL: Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), true, true); Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), false, true); break; #endif case SDL_MOUSEBUTTONDOWN: #if !SDL_VERSION_ATLEAST(2, 0, 0) if (event.button.button == 4) { Key_Event(K_MWHEELUP, true, true); Key_Event(K_MWHEELUP, false, true); break; } else if (event.button.button == 5) { Key_Event(K_MWHEELDOWN, true, true); Key_Event(K_MWHEELDOWN, false, true); break; } #endif case SDL_MOUSEBUTTONUP: switch( event.button.button ) { case SDL_BUTTON_LEFT: key = K_MOUSE1; break; case SDL_BUTTON_MIDDLE: key = K_MOUSE3; break; case SDL_BUTTON_RIGHT: key = K_MOUSE2; break; case SDL_BUTTON_X1: key = K_MOUSE4; break; case SDL_BUTTON_X2: key = K_MOUSE5; break; default: return; } Key_Event(key, (event.type == SDL_MOUSEBUTTONDOWN), true); break; case SDL_MOUSEMOTION: if (cls.key_dest == key_game && (int)cl_paused->value == 0) { mouse_x += event.motion.xrel; mouse_y += event.motion.yrel; } break; #if SDL_VERSION_ATLEAST(2, 0, 0) case SDL_TEXTINPUT: if ((event.text.text[0] >= SDLK_SPACE) && (event.text.text[0] < SDLK_DELETE)) { Char_Event(event.text.text[0]); } break; #endif case SDL_KEYDOWN: #if !SDL_VERSION_ATLEAST(2, 0, 0) if ((event.key.keysym.unicode >= SDLK_SPACE) && (event.key.keysym.unicode < SDLK_DELETE)) { Char_Event(event.key.keysym.unicode); } #endif if ((event.key.keysym.sym >= SDLK_SPACE) && (event.key.keysym.sym < SDLK_DELETE)) { Key_Event(event.key.keysym.sym, true, false); } else { Key_Event(IN_TranslateSDLtoQ2Key(event.key.keysym.sym), true, true); } break; case SDL_KEYUP: if ((event.key.keysym.sym >= SDLK_SPACE) && (event.key.keysym.sym < SDLK_DELETE)) { Key_Event(event.key.keysym.sym, false, false); } else { Key_Event(IN_TranslateSDLtoQ2Key(event.key.keysym.sym), false, true); } break; #if SDL_VERSION_ATLEAST(2, 0, 0) case SDL_WINDOWEVENT: if(event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) { Key_MarkAllUp(); } #else // SDL1.2 case SDL_ACTIVEEVENT: if(event.active.gain == 0 && (event.active.state & SDL_APPINPUTFOCUS)) { Key_MarkAllUp(); } #endif break; } } /* Grab and ungrab the mouse if the* console or the menu is opened */ want_grab = (vid_fullscreen->value || in_grab->value == 1 || (in_grab->value == 2 && windowed_mouse->value)); /* calling GLimp_GrabInput() each is a but ugly but simple and should work. * + the called SDL functions return after a cheap check, if there's * nothing to do, anyway */ GLimp_GrabInput(want_grab); }
/* * Updates the input queue state. Called every * frame by the client and does nearly all the * input magic. */ void IN_Update(void) { qboolean want_grab; SDL_Event event; unsigned int key; /* Get and process an event */ while (SDL_PollEvent(&event)) { switch (event.type) { #if SDL_VERSION_ATLEAST(2, 0, 0) case SDL_MOUSEWHEEL: Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), true, true); Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), false, true); break; #endif case SDL_MOUSEBUTTONDOWN: #if !SDL_VERSION_ATLEAST(2, 0, 0) if (event.button.button == 4) { Key_Event(K_MWHEELUP, true, true); Key_Event(K_MWHEELUP, false, true); break; } else if (event.button.button == 5) { Key_Event(K_MWHEELDOWN, true, true); Key_Event(K_MWHEELDOWN, false, true); break; } #endif /* fall-through */ case SDL_MOUSEBUTTONUP: switch( event.button.button ) { case SDL_BUTTON_LEFT: key = K_MOUSE1; break; case SDL_BUTTON_MIDDLE: key = K_MOUSE3; break; case SDL_BUTTON_RIGHT: key = K_MOUSE2; break; case SDL_BUTTON_X1: key = K_MOUSE4; break; case SDL_BUTTON_X2: key = K_MOUSE5; break; default: return; } Key_Event(key, (event.type == SDL_MOUSEBUTTONDOWN), true); break; case SDL_MOUSEMOTION: if (cls.key_dest == key_game && (int)cl_paused->value == 0) { mouse_x += event.motion.xrel; mouse_y += event.motion.yrel; } break; #if SDL_VERSION_ATLEAST(2, 0, 0) case SDL_TEXTINPUT: if((event.text.text[0] >= ' ') && (event.text.text[0] <= '~')) { Char_Event(event.text.text[0]); } break; #endif case SDL_KEYDOWN: #if !SDL_VERSION_ATLEAST(2, 0, 0) if ((event.key.keysym.unicode >= SDLK_SPACE) && (event.key.keysym.unicode < SDLK_DELETE)) { Char_Event(event.key.keysym.unicode); } #endif /* fall-through */ case SDL_KEYUP: { qboolean down = (event.type == SDL_KEYDOWN); #if SDL_VERSION_ATLEAST(2, 0, 0) /* workaround for AZERTY-keyboards, which don't have 1, 2, ..., 9, 0 in first row: * always map those physical keys (scancodes) to those keycodes anyway * see also https://bugzilla.libsdl.org/show_bug.cgi?id=3188 */ SDL_Scancode sc = event.key.keysym.scancode; if(sc >= SDL_SCANCODE_1 && sc <= SDL_SCANCODE_0) { /* Note that the SDL_SCANCODEs are SDL_SCANCODE_1, _2, ..., _9, SDL_SCANCODE_0 * while in ASCII it's '0', '1', ..., '9' => handle 0 and 1-9 separately * (quake2 uses the ASCII values for those keys) */ int key = '0'; /* implicitly handles SDL_SCANCODE_0 */ if(sc <= SDL_SCANCODE_9) { key = '1' + (sc - SDL_SCANCODE_1); } Key_Event(key, down, false); } else #endif /* SDL2; (SDL1.2 doesn't have scancodes so nothing we can do there) */ if((event.key.keysym.sym >= SDLK_SPACE) && (event.key.keysym.sym < SDLK_DELETE)) { Key_Event(event.key.keysym.sym, down, false); } else { Key_Event(IN_TranslateSDLtoQ2Key(event.key.keysym.sym), down, true); } } break; #if SDL_VERSION_ATLEAST(2, 0, 0) case SDL_WINDOWEVENT: if(event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) { Key_MarkAllUp(); } #else /* SDL1.2 */ case SDL_ACTIVEEVENT: if(event.active.gain == 0 && (event.active.state & SDL_APPINPUTFOCUS)) { Key_MarkAllUp(); } #endif break; } } /* Grab and ungrab the mouse if the* console or the menu is opened */ want_grab = (vid_fullscreen->value || in_grab->value == 1 || (in_grab->value == 2 && windowed_mouse->value)); /* calling GLimp_GrabInput() each is a but ugly but simple and should work. * + the called SDL functions return after a cheap check, if there's * nothing to do, anyway */ GLimp_GrabInput(want_grab); }
/* * Input event processing */ void IN_GetEvent(SDL_Event *event) { unsigned int key; switch (event->type) { /* The mouse wheel */ case SDL_MOUSEBUTTONDOWN: if (event->button.button == 4) { keyq[keyq_head].key = K_MWHEELUP; keyq[keyq_head].down = true; keyq_head = (keyq_head + 1) & 127; keyq[keyq_head].key = K_MWHEELUP; keyq[keyq_head].down = false; keyq_head = (keyq_head + 1) & 127; } else if (event->button.button == 5) { keyq[keyq_head].key = K_MWHEELDOWN; keyq[keyq_head].down = true; keyq_head = (keyq_head + 1) & 127; keyq[keyq_head].key = K_MWHEELDOWN; keyq[keyq_head].down = false; keyq_head = (keyq_head + 1) & 127; } break; case SDL_MOUSEBUTTONUP: break; /* The user pressed a button */ case SDL_KEYDOWN: /* Fullscreen switch via Alt-Return */ if ((KeyStates[SDLK_LALT] || KeyStates[SDLK_RALT]) && (event->key.keysym.sym == SDLK_RETURN)) { SDL_WM_ToggleFullScreen(surface); if (surface->flags & SDL_FULLSCREEN) { Cvar_SetValue("vid_fullscreen", 1); } else { Cvar_SetValue("vid_fullscreen", 0); } vid_fullscreen->modified = false; break; } /* Make Shift+Escape toggle the console. This really belongs in Key_Event(), but since Key_ClearStates() can mess up the internal K_SHIFT state let's do it here instead. */ if ((KeyStates[SDLK_LSHIFT] || KeyStates[SDLK_RSHIFT]) && (event->key.keysym.sym == SDLK_ESCAPE)) { Cbuf_ExecuteText(EXEC_NOW, "toggleconsole"); break; } KeyStates[event->key.keysym.sym] = 1; /* Get the pressed key and add it to the key list */ key = IN_TranslateSDLtoQ2Key(event->key.keysym.sym); if (key) { keyq[keyq_head].key = key; keyq[keyq_head].down = true; keyq_head = (keyq_head + 1) & 127; } break; /* The user released a key */ case SDL_KEYUP: if (KeyStates[event->key.keysym.sym]) { KeyStates[event->key.keysym.sym] = 0; /* Get the pressed key and remove it from the key list */ key = IN_TranslateSDLtoQ2Key(event->key.keysym.sym); if (key) { keyq[keyq_head].key = key; keyq[keyq_head].down = false; keyq_head = (keyq_head + 1) & 127; } } break; } }