/* ================ Sys_GetEvent ================ */ sysEvent_t Sys_GetEvent() { SDL_Event ev; sysEvent_t res = { }; byte key; static const sysEvent_t res_none = { SE_NONE, 0, 0, 0, NULL }; #if SDL_VERSION_ATLEAST(2, 0, 0) static char s[SDL_TEXTINPUTEVENT_TEXT_SIZE] = {0}; static size_t s_pos = 0; if (s[0] != '\0') { res.evType = SE_CHAR; res.evValue = s[s_pos]; ++s_pos; if (!s[s_pos] || s_pos == SDL_TEXTINPUTEVENT_TEXT_SIZE) { memset(s, 0, sizeof(s)); s_pos = 0; } return res; } #endif static byte c = 0; if (c) { res.evType = SE_CHAR; res.evValue = c; c = 0; return res; } // loop until there is an event we care about (will return then) or no more events while(SDL_PollEvent(&ev)) { switch (ev.type) { #if SDL_VERSION_ATLEAST(2, 0, 0) case SDL_WINDOWEVENT: switch (ev.window.event) { case SDL_WINDOWEVENT_FOCUS_GAINED: { // unset modifier, in case alt-tab was used to leave window and ALT is still set // as that can cause fullscreen-toggling when pressing enter... SDL_Keymod currentmod = SDL_GetModState(); int newmod = KMOD_NONE; if (currentmod & KMOD_CAPS) // preserve capslock newmod |= KMOD_CAPS; SDL_SetModState((SDL_Keymod)newmod); } // new context because visual studio complains about newmod and currentmod not initialized because of the case SDL_WINDOWEVENT_FOCUS_LOST GLimp_GrabInput(GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR); break; case SDL_WINDOWEVENT_FOCUS_LOST: GLimp_GrabInput(0); break; } continue; // handle next event #else case SDL_ACTIVEEVENT: { int flags = 0; if (ev.active.gain) { flags = GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR; // unset modifier, in case alt-tab was used to leave window and ALT is still set // as that can cause fullscreen-toggling when pressing enter... SDLMod currentmod = SDL_GetModState(); int newmod = KMOD_NONE; if (currentmod & KMOD_CAPS) // preserve capslock newmod |= KMOD_CAPS; SDL_SetModState((SDLMod)newmod); } GLimp_GrabInput(flags); } continue; // handle next event case SDL_VIDEOEXPOSE: continue; // handle next event #endif case SDL_KEYDOWN: if (ev.key.keysym.sym == SDLK_RETURN && (ev.key.keysym.mod & KMOD_ALT) > 0) { cvarSystem->SetCVarBool("r_fullscreen", !renderSystem->IsFullScreen()); PushConsoleEvent("vid_restart"); return res_none; } // fall through case SDL_KEYUP: key = mapkey(ev.key.keysym.sym); #if !SDL_VERSION_ATLEAST(2, 0, 0) if (!key) { unsigned char c; // check if its an unmapped console key if (ev.key.keysym.unicode == (c = Sys_GetConsoleKey(false))) { key = c; } else if (ev.key.keysym.unicode == (c = Sys_GetConsoleKey(true))) { key = c; } else { if (ev.type == SDL_KEYDOWN) common->Warning("unmapped SDL key %d (0x%x)", ev.key.keysym.sym, ev.key.keysym.unicode); continue; // handle next event } } #else if(!key) { if (ev.key.keysym.scancode == SDL_SCANCODE_GRAVE) { // TODO: always do this check? key = Sys_GetConsoleKey(true); } else { if (ev.type == SDL_KEYDOWN) { common->Warning("unmapped SDL key %d", ev.key.keysym.sym); } continue; // handle next event } } #endif res.evType = SE_KEY; res.evValue = key; res.evValue2 = ev.key.state == SDL_PRESSED ? 1 : 0; kbd_polls.Append(kbd_poll_t(key, ev.key.state == SDL_PRESSED)); #if SDL_VERSION_ATLEAST(2, 0, 0) if (key == K_BACKSPACE && ev.key.state == SDL_PRESSED) c = key; #else if (ev.key.state == SDL_PRESSED && (ev.key.keysym.unicode & 0xff00) == 0) c = ev.key.keysym.unicode & 0xff; #endif return res; #if SDL_VERSION_ATLEAST(2, 0, 0) case SDL_TEXTINPUT: if (ev.text.text[0]) { res.evType = SE_CHAR; res.evValue = ev.text.text[0]; if (ev.text.text[1] != '\0') { memcpy(s, ev.text.text, SDL_TEXTINPUTEVENT_TEXT_SIZE); s_pos = 1; // pos 0 is returned } return res; } continue; // handle next event #endif case SDL_MOUSEMOTION: res.evType = SE_MOUSE; res.evValue = ev.motion.xrel; res.evValue2 = ev.motion.yrel; mouse_polls.Append(mouse_poll_t(M_DELTAX, ev.motion.xrel)); mouse_polls.Append(mouse_poll_t(M_DELTAY, ev.motion.yrel)); return res; #if SDL_VERSION_ATLEAST(2, 0, 0) case SDL_MOUSEWHEEL: res.evType = SE_KEY; if (ev.wheel.y > 0) { res.evValue = K_MWHEELUP; mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1)); } else { res.evValue = K_MWHEELDOWN; mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1)); } res.evValue2 = 1; return res; #endif case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: res.evType = SE_KEY; switch (ev.button.button) { case SDL_BUTTON_LEFT: res.evValue = K_MOUSE1; mouse_polls.Append(mouse_poll_t(M_ACTION1, ev.button.state == SDL_PRESSED ? 1 : 0)); break; case SDL_BUTTON_MIDDLE: res.evValue = K_MOUSE3; mouse_polls.Append(mouse_poll_t(M_ACTION3, ev.button.state == SDL_PRESSED ? 1 : 0)); break; case SDL_BUTTON_RIGHT: res.evValue = K_MOUSE2; mouse_polls.Append(mouse_poll_t(M_ACTION2, ev.button.state == SDL_PRESSED ? 1 : 0)); break; #if !SDL_VERSION_ATLEAST(2, 0, 0) case SDL_BUTTON_WHEELUP: res.evValue = K_MWHEELUP; if (ev.button.state == SDL_PRESSED) mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1)); break; case SDL_BUTTON_WHEELDOWN: res.evValue = K_MWHEELDOWN; if (ev.button.state == SDL_PRESSED) mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1)); break; #endif } res.evValue2 = ev.button.state == SDL_PRESSED ? 1 : 0; return res; case SDL_QUIT: PushConsoleEvent("quit"); return res_none; case SDL_USEREVENT: switch (ev.user.code) { case SE_CONSOLE: res.evType = SE_CONSOLE; res.evPtrLength = (intptr_t)ev.user.data1; res.evPtr = ev.user.data2; return res; default: common->Warning("unknown user event %u", ev.user.code); continue; // handle next event } default: common->Warning("unknown event %u", ev.type); continue; // handle next event } } return res_none; }
/* ================ Sys_GetEvent ================ */ sysEvent_t Sys_GetEvent() { SDL_Event ev; sysEvent_t res = { }; byte key; static const sysEvent_t res_none = { SE_NONE, 0, 0, 0, NULL }; static byte c = 0; if (c) { res.evType = SE_CHAR; res.evValue = c; c = 0; return res; } if (SDL_PollEvent(&ev)) { switch (ev.type) { case SDL_ACTIVEEVENT: GrabInput(grabbed && ev.active.gain == 1, ev.active.gain == 1, false); return res_none; case SDL_VIDEOEXPOSE: return res_none; case SDL_KEYDOWN: if (ev.key.keysym.sym == SDLK_RETURN && (ev.key.keysym.mod & KMOD_ALT) > 0) { cvarSystem->SetCVarBool("r_fullscreen", !renderSystem->IsFullScreen()); PushConsoleEvent("vid_restart"); return res_none; } // fall through case SDL_KEYUP: key = mapkey(ev.key.keysym.sym); if (!key) { unsigned char c; // check if its an unmapped console key if (ev.key.keysym.unicode == (c = Sys_GetConsoleKey(false))) { key = c; } else if (ev.key.keysym.unicode == (c = Sys_GetConsoleKey(true))) { key = c; } else { if (ev.type == SDL_KEYDOWN) common->Warning("unmapped SDL key %d (0x%x)", ev.key.keysym.sym, ev.key.keysym.unicode); return res_none; } } res.evType = SE_KEY; res.evValue = key; res.evValue2 = ev.key.state == SDL_PRESSED ? 1 : 0; kbd_polls.Append(kbd_poll_t(key, ev.key.state == SDL_PRESSED)); if (ev.key.state == SDL_PRESSED && (ev.key.keysym.unicode & 0xff00) == 0) c = ev.key.keysym.unicode & 0xff; return res; case SDL_MOUSEMOTION: res.evType = SE_MOUSE; res.evValue = ev.motion.xrel; res.evValue2 = ev.motion.yrel; mouse_polls.Append(mouse_poll_t(M_DELTAX, ev.motion.xrel)); mouse_polls.Append(mouse_poll_t(M_DELTAY, ev.motion.yrel)); return res; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: res.evType = SE_KEY; switch (ev.button.button) { case SDL_BUTTON_LEFT: res.evValue = K_MOUSE1; mouse_polls.Append(mouse_poll_t(M_ACTION1, ev.button.state == SDL_PRESSED ? 1 : 0)); break; case SDL_BUTTON_MIDDLE: res.evValue = K_MOUSE3; mouse_polls.Append(mouse_poll_t(M_ACTION3, ev.button.state == SDL_PRESSED ? 1 : 0)); break; case SDL_BUTTON_RIGHT: res.evValue = K_MOUSE2; mouse_polls.Append(mouse_poll_t(M_ACTION2, ev.button.state == SDL_PRESSED ? 1 : 0)); break; case SDL_BUTTON_WHEELUP: res.evValue = K_MWHEELUP; if (ev.button.state == SDL_PRESSED) mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1)); break; case SDL_BUTTON_WHEELDOWN: res.evValue = K_MWHEELDOWN; if (ev.button.state == SDL_PRESSED) mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1)); break; } res.evValue2 = ev.button.state == SDL_PRESSED ? 1 : 0; return res; case SDL_QUIT: PushConsoleEvent("quit"); return res_none; case SDL_USEREVENT: switch (ev.user.code) { case SE_CONSOLE: res.evType = SE_CONSOLE; res.evPtrLength = (intptr_t)ev.user.data1; res.evPtr = ev.user.data2; return res; default: common->Warning("unknown user event %u", ev.user.code); return res_none; } default: common->Warning("unknown event %u", ev.type); return res_none; } } return res_none; }
/* ================ Sys_GetEvent ================ */ sysEvent_t Sys_GetEvent() { SDL_Event ev; sysEvent_t res = { }; byte key; static const sysEvent_t res_none = { SE_NONE, 0, 0, 0, NULL }; // process any overflow. if (event_overflow.Num() > 0) { res = event_overflow[0]; event_overflow.RemoveIndex(0); return res; } // overflow text input. static char *s = NULL; static size_t s_pos = 0; if (s) { res.evType = SE_CHAR; res.evValue = s[s_pos]; s_pos++; if (!s[s_pos]) { free(s); s = NULL; s_pos = 0; } return res; } static byte c = 0; if (c) { res.evType = SE_CHAR; res.evValue = c; c = 0; return res; } bool getNext = true; while (SDL_PollEvent(&ev) && getNext) { getNext = false; switch (ev.type) { #ifdef __WINDOWS__ // on windows we need to grab the hwnd. case SDL_SYSWMEVENT: if (win32.hWnd == NULL) { win32.hWnd = ev.syswm.msg->msg.win.hwnd; } getNext = true; // try to get a decent event. break; #endif case SDL_WINDOWEVENT: switch (ev.window.event) { case SDL_WINDOWEVENT_FOCUS_GAINED: { // unset modifier, in case alt-tab was used to leave window and ALT is still set // as that can cause fullscreen-toggling when pressing enter... SDL_Keymod currentmod = SDL_GetModState(); int newmod = KMOD_NONE; if (currentmod & KMOD_CAPS) // preserve capslock newmod |= KMOD_CAPS; SDL_SetModState((SDL_Keymod)newmod); } // new context because visual studio complains about newmod and currentmod not initialized because of the case SDL_WINDOWEVENT_FOCUS_LOST GLimp_GrabInput(GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR); break; case SDL_WINDOWEVENT_FOCUS_LOST: GLimp_GrabInput(0); break; } return res_none; case SDL_KEYDOWN: if (ev.key.keysym.sym == SDLK_RETURN && (ev.key.keysym.mod & KMOD_ALT) > 0) { cvarSystem->SetCVarBool("r_fullscreen", !renderSystem->IsFullScreen()); PushConsoleEvent("vid_restart"); return res_none; } // fall through case SDL_KEYUP: key = mapkey(ev.key.keysym.sym); if(!key) { if (ev.key.keysym.scancode == SDL_SCANCODE_GRAVE) { key = Sys_GetConsoleKey(true); } else { if (ev.type == SDL_KEYDOWN) { common->Warning("unmapped SDL key %d", ev.key.keysym.sym); getNext = true; // try to get a decent event. break; } } } res.evType = SE_KEY; res.evValue = key; res.evValue2 = ev.key.state == SDL_PRESSED ? 1 : 0; kbd_polls.Append(kbd_poll_t(key, ev.key.state == SDL_PRESSED)); if ( (key == K_BACKSPACE && ev.key.state == SDL_PRESSED) || SDL_GetEventState(SDL_TEXTINPUT) == SDL_DISABLE) c = key; return res; case SDL_TEXTINPUT: if (ev.text.text && *ev.text.text) { res.evType = SE_CHAR; res.evValue = *ev.text.text; // if there are more characters hold onto them for later events. if (ev.text.text[1] != 0) s = strdup(ev.text.text+1); return res; } getNext = true; // try to get a decent event. break; case SDL_MOUSEMOTION: if (g_inputGrabbed) { res.evType = SE_MOUSE; res.evValue = ev.motion.xrel; res.evValue2 = ev.motion.yrel; mouse_polls.Append(mouse_poll_t(M_DELTAX, ev.motion.xrel)); mouse_polls.Append(mouse_poll_t(M_DELTAY, ev.motion.yrel)); return res; } getNext = true; break; case SDL_MOUSEWHEEL: if (g_inputGrabbed) { res.evType = SE_KEY; if (ev.wheel.y > 0) { res.evValue = K_MWHEELUP; mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1)); } else { res.evValue = K_MWHEELDOWN; mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1)); } res.evValue2 = 1; return res; } getNext = true; break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: if (g_inputGrabbed) { res.evType = SE_KEY; switch (ev.button.button) { case SDL_BUTTON_LEFT: res.evValue = K_MOUSE1; mouse_polls.Append(mouse_poll_t(M_ACTION1, ev.button.state == SDL_PRESSED ? 1 : 0)); break; case SDL_BUTTON_MIDDLE: res.evValue = K_MOUSE3; mouse_polls.Append(mouse_poll_t(M_ACTION3, ev.button.state == SDL_PRESSED ? 1 : 0)); break; case SDL_BUTTON_RIGHT: res.evValue = K_MOUSE2; mouse_polls.Append(mouse_poll_t(M_ACTION2, ev.button.state == SDL_PRESSED ? 1 : 0)); break; } res.evValue2 = ev.button.state == SDL_PRESSED ? 1 : 0; return res; } getNext = true; break; case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONUP: { sys_jEvents jEvent = mapjoybutton( (SDL_GameControllerButton)ev.cbutton.button); joystick_polls.Append(joystick_poll_t( jEvent, ev.cbutton.state == SDL_PRESSED ? 1 : 0) ); res.evType = SE_KEY; res.evValue2 = ev.cbutton.state == SDL_PRESSED ? 1 : 0; if ( ( jEvent >= J_ACTION1 ) && ( jEvent <= J_ACTION_MAX ) ) { res.evValue = K_JOY1 + ( jEvent - J_ACTION1 ); return res; } else if ( ( jEvent >= J_DPAD_UP ) && ( jEvent <= J_DPAD_RIGHT ) ) { res.evValue = K_JOY_DPAD_UP + ( jEvent - J_DPAD_UP ); return res; } getNext = true; // try to get a decent event. } break; case SDL_CONTROLLERAXISMOTION: { const int range = 16384; sys_jEvents jEvent = mapjoyaxis( (SDL_GameControllerAxis)ev.caxis.axis); joystick_polls.Append(joystick_poll_t( jEvent, ev.caxis.value) ); if ( jEvent == J_AXIS_LEFT_X ) { PushButton( K_JOY_STICK1_LEFT, ( ev.caxis.value < -range ) ); PushButton( K_JOY_STICK1_RIGHT, ( ev.caxis.value > range ) ); } else if ( jEvent == J_AXIS_LEFT_Y ) { PushButton( K_JOY_STICK1_UP, ( ev.caxis.value < -range ) ); PushButton( K_JOY_STICK1_DOWN, ( ev.caxis.value > range ) ); } else if ( jEvent == J_AXIS_RIGHT_X ) { PushButton( K_JOY_STICK2_LEFT, ( ev.caxis.value < -range ) ); PushButton( K_JOY_STICK2_RIGHT, ( ev.caxis.value > range ) ); } else if ( jEvent == J_AXIS_RIGHT_Y ) { PushButton( K_JOY_STICK2_UP, ( ev.caxis.value < -range ) ); PushButton( K_JOY_STICK2_DOWN, ( ev.caxis.value > range ) ); } else if ( jEvent == J_AXIS_LEFT_TRIG ) { PushButton( K_JOY_TRIGGER1, ( ev.caxis.value > range ) ); } else if ( jEvent == J_AXIS_RIGHT_TRIG ) { PushButton( K_JOY_TRIGGER2, ( ev.caxis.value > range ) ); } if ( jEvent >= J_AXIS_MIN && jEvent <= J_AXIS_MAX ) { int axis = jEvent - J_AXIS_MIN; int percent = ( ev.caxis.value * 16 ) / range; if ( joyAxis[axis] != percent ) { joyAxis[axis] = percent; res.evType = SE_JOYSTICK; res.evValue = axis; res.evValue2 = percent; return res; } } getNext = true; // try to get a decent event. } break; case SDL_JOYDEVICEADDED: SDL_GameControllerOpen( ev.jdevice.which ); // TODO: hot swapping maybe. //lbOnControllerPlugIn(event.jdevice.which); break; case SDL_JOYDEVICEREMOVED: // TODO: hot swapping maybe. //lbOnControllerUnPlug(event.jdevice.which); break; case SDL_QUIT: PushConsoleEvent("quit"); return res_none; case SDL_USEREVENT: switch (ev.user.code) { case SE_CONSOLE: res.evType = SE_CONSOLE; res.evPtrLength = (intptr_t)ev.user.data1; res.evPtr = ev.user.data2; return res; default: common->Warning("unknown user event %u", ev.user.code); getNext = true; // try to get a decent event. break; } default: getNext = true; // try to get a decent event. break; } } return res_none; }
/* ================ Sys_GetEvent ================ */ sysEvent_t Sys_GetEvent() { SDL_Event ev; sysEvent_t res = { }; byte key; static const sysEvent_t res_none = { SE_NONE, 0, 0, 0, NULL }; static char *s = NULL; static size_t s_pos = 0; if (s) { res.evType = SE_CHAR; res.evValue = s[s_pos]; s_pos++; if (!s[s_pos]) { free(s); s = NULL; s_pos = 0; } return res; } static byte c = 0; if (c) { res.evType = SE_CHAR; res.evValue = c; c = 0; return res; } if (SDL_PollEvent(&ev)) { switch (ev.type) { case SDL_WINDOWEVENT: switch (ev.window.event) { case SDL_WINDOWEVENT_SHOWN: SDL_Log("Window %d shown", ev.window.windowID); break; case SDL_WINDOWEVENT_HIDDEN: SDL_Log("Window %d hidden", ev.window.windowID); break; case SDL_WINDOWEVENT_EXPOSED: SDL_Log("Window %d exposed", ev.window.windowID); break; case SDL_WINDOWEVENT_MOVED: SDL_Log("Window %d moved to %d,%d", ev.window.windowID, ev.window.data1, ev.window.data2); break; case SDL_WINDOWEVENT_RESIZED: SDL_Log("Window %d resized to %dx%d", ev.window.windowID, ev.window.data1, ev.window.data2); break; case SDL_WINDOWEVENT_MINIMIZED: SDL_Log("Window %d minimized", ev.window.windowID); break; case SDL_WINDOWEVENT_MAXIMIZED: SDL_Log("Window %d maximized", ev.window.windowID); break; case SDL_WINDOWEVENT_RESTORED: SDL_Log("Window %d restored", ev.window.windowID); break; case SDL_WINDOWEVENT_ENTER: SDL_Log("Mouse entered window %d", ev.window.windowID); break; case SDL_WINDOWEVENT_LEAVE: SDL_Log("Mouse left window %d", ev.window.windowID); break; case SDL_WINDOWEVENT_FOCUS_GAINED: SDL_Log("Window %d gained keyboard focus", ev.window.windowID); cvarSystem->SetCVarBool( "com_pause", false ); GLimp_GrabInput(GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR); break; case SDL_WINDOWEVENT_FOCUS_LOST: SDL_Log("Window %d lost keyboard focus", ev.window.windowID); cvarSystem->SetCVarBool( "com_pause", true ); GLimp_GrabInput(0); break; case SDL_WINDOWEVENT_CLOSE: SDL_Log("Window %d closed", ev.window.windowID); break; default: SDL_Log("Window %d got unknown event %d", ev.window.windowID, ev.window.event); break; } return res_none; case SDL_KEYDOWN: if (ev.key.keysym.sym == SDLK_RETURN && (ev.key.keysym.mod & KMOD_ALT) > 0) { cvarSystem->SetCVarBool("r_fullscreen", !renderSystem->IsFullScreen()); PushConsoleEvent("vid_restart"); /* * FIXME vid_restart */ return res_none; } // fall through case SDL_KEYUP: key = mapkey(ev.key.keysym.sym); if(!key) { if (ev.key.keysym.scancode == SDL_SCANCODE_GRAVE) { key = Sys_GetConsoleKey(true); } else { if (ev.type == SDL_KEYDOWN) { common->Warning("unmapped SDL key %d", ev.key.keysym.sym); return res_none; } } } res.evType = SE_KEY; res.evValue = key; res.evValue2 = ev.key.state == SDL_PRESSED ? 1 : 0; kbd_polls.Append(kbd_poll_t(key, ev.key.state == SDL_PRESSED)); if (key == K_BACKSPACE && ev.key.state == SDL_PRESSED) c = key; return res; case SDL_TEXTINPUT: if (ev.text.text && *ev.text.text) { if (!ev.text.text[1]) c = *ev.text.text; else s = strdup(ev.text.text); } return res_none; case SDL_TEXTEDITING: SDL_StartTextInput(); SDL_Log("SDL_TextEditingEvent"); //SDL_StopTextInput(); break; case SDL_SYSWMEVENT: SDL_Log("SDL_SYSWMEVENT"); break; case SDL_CLIPBOARDUPDATE: SDL_Log("SDL_CLIPBOARDUPDATE"); break; case SDL_MOUSEMOTION: res.evType = SE_MOUSE; res.evValue = ev.motion.xrel; res.evValue2 = ev.motion.yrel; mouse_polls.Append(mouse_poll_t(M_DELTAX, ev.motion.xrel)); mouse_polls.Append(mouse_poll_t(M_DELTAY, ev.motion.yrel)); return res; case SDL_MOUSEWHEEL: res.evType = SE_KEY; if (ev.wheel.y > 0) { res.evValue = K_MWHEELUP; mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1)); } else { res.evValue = K_MWHEELDOWN; mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1)); } res.evValue2 = 1; return res; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: res.evType = SE_KEY; switch (ev.button.button) { case SDL_BUTTON_LEFT: res.evValue = K_MOUSE1; mouse_polls.Append(mouse_poll_t(M_ACTION1, ev.button.state == SDL_PRESSED ? 1 : 0)); break; case SDL_BUTTON_MIDDLE: res.evValue = K_MOUSE3; mouse_polls.Append(mouse_poll_t(M_ACTION3, ev.button.state == SDL_PRESSED ? 1 : 0)); break; case SDL_BUTTON_RIGHT: res.evValue = K_MOUSE2; mouse_polls.Append(mouse_poll_t(M_ACTION2, ev.button.state == SDL_PRESSED ? 1 : 0)); break; } res.evValue2 = ev.button.state == SDL_PRESSED ? 1 : 0; return res; case SDL_QUIT: PushConsoleEvent("quit"); SDL_Quit(); return res_none; case SDL_USEREVENT: switch (ev.user.code) { case SE_CONSOLE: res.evType = SE_CONSOLE; res.evPtrLength = (intptr_t)ev.user.data1; res.evPtr = ev.user.data2; return res; default: common->Warning("unknown user event %u", ev.user.code); return res_none; } default: common->Warning("unknown event %u", ev.type); return res_none; } } return res_none; }
/* ================ Sys_GetEvent ================ */ sysEvent_t Sys_GetEvent() { SDL_Event ev; sysEvent_t res = { }; byte key; static const sysEvent_t res_none = { SE_NONE, 0, 0, 0, NULL }; static char *s = NULL; static size_t s_pos = 0; if (s) { res.evType = SE_CHAR; res.evValue = s[s_pos]; s_pos++; if (!s[s_pos]) { free(s); s = NULL; s_pos = 0; } return res; } static byte c = 0; if (c) { res.evType = SE_CHAR; res.evValue = c; c = 0; return res; } if (SDL_PollEvent(&ev)) { switch (ev.type) { case SDL_WINDOWEVENT: switch (ev.window.event) { case SDL_WINDOWEVENT_FOCUS_GAINED: { // unset modifier, in case alt-tab was used to leave window and ALT is still set // as that can cause fullscreen-toggling when pressing enter... SDL_Keymod currentmod = SDL_GetModState(); int newmod = KMOD_NONE; if (currentmod & KMOD_CAPS) // preserve capslock newmod |= KMOD_CAPS; SDL_SetModState((SDL_Keymod)newmod); GLimp_GrabInput(GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR); break; } case SDL_WINDOWEVENT_FOCUS_LOST: GLimp_GrabInput(0); break; } return res_none; case SDL_KEYDOWN: if (ev.key.keysym.sym == SDLK_RETURN && (ev.key.keysym.mod & KMOD_ALT) > 0) { cvarSystem->SetCVarBool("r_fullscreen", !renderSystem->IsFullScreen()); PushConsoleEvent("vid_restart"); return res_none; } // fall through case SDL_KEYUP: key = mapkey(ev.key.keysym.sym); if (!key) { unsigned char c; // check if its an unmapped console key if (ev.key.keysym.unicode == (c = Sys_GetConsoleKey(false))) { key = c; } else if (ev.key.keysym.unicode == (c = Sys_GetConsoleKey(true))) { key = c; } else { if (ev.type == SDL_KEYDOWN) common->Warning("unmapped SDL key %d (0x%x)", ev.key.keysym.sym, ev.key.keysym.unicode); return res_none; } } res.evType = SE_KEY; res.evValue = key; res.evValue2 = ev.key.state == SDL_PRESSED ? 1 : 0; kbd_polls.Append(kbd_poll_t(key, ev.key.state == SDL_PRESSED)); if (key == K_BACKSPACE && ev.key.state == SDL_PRESSED) c = key; return res; case SDL_TEXTINPUT: if (ev.text.text && *ev.text.text) { if (!ev.text.text[1]) c = *ev.text.text; else s = strdup(ev.text.text); } return res_none; case SDL_MOUSEMOTION: res.evType = SE_MOUSE; res.evValue = ev.motion.xrel; res.evValue2 = ev.motion.yrel; mouse_polls.Append(mouse_poll_t(M_DELTAX, ev.motion.xrel)); mouse_polls.Append(mouse_poll_t(M_DELTAY, ev.motion.yrel)); return res; case SDL_MOUSEWHEEL: res.evType = SE_KEY; if (ev.wheel.y > 0) { res.evValue = K_MWHEELUP; mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1)); } else { res.evValue = K_MWHEELDOWN; mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1)); } res.evValue2 = 1; return res; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: res.evType = SE_KEY; switch (ev.button.button) { case SDL_BUTTON_LEFT: res.evValue = K_MOUSE1; mouse_polls.Append(mouse_poll_t(M_ACTION1, ev.button.state == SDL_PRESSED ? 1 : 0)); break; case SDL_BUTTON_MIDDLE: res.evValue = K_MOUSE3; mouse_polls.Append(mouse_poll_t(M_ACTION3, ev.button.state == SDL_PRESSED ? 1 : 0)); break; case SDL_BUTTON_RIGHT: res.evValue = K_MOUSE2; mouse_polls.Append(mouse_poll_t(M_ACTION2, ev.button.state == SDL_PRESSED ? 1 : 0)); break; } res.evValue2 = ev.button.state == SDL_PRESSED ? 1 : 0; return res; case SDL_QUIT: PushConsoleEvent("quit"); return res_none; case SDL_USEREVENT: switch (ev.user.code) { case SE_CONSOLE: res.evType = SE_CONSOLE; res.evPtrLength = (intptr_t)ev.user.data1; res.evPtr = ev.user.data2; return res; default: common->Warning("unknown user event %u", ev.user.code); return res_none; } default: common->Warning("unknown event %u", ev.type); return res_none; } } return res_none; }