static int l_get_key_modifiers(lua_State *L) { l_push_modifiers_table(L, SDL_GetModState()); return 1; }
/** * \brief Returns whether the caps lock key is currently active. * \return \c true if the caps lock key is currently active. */ bool InputEvent::is_caps_lock_on() { SDL_Keymod mod = SDL_GetModState(); return mod & KMOD_CAPS; }
static void sdl_refresh(DisplayState *ds) { SDL_Event ev1, *ev = &ev1; int mod_state; int buttonstate = SDL_GetMouseState(NULL, NULL); if (last_vm_running != vm_running) { last_vm_running = vm_running; sdl_update_caption(); } vga_hw_update(); SDL_EnableUNICODE(!is_graphic_console()); while (SDL_PollEvent(ev)) { switch (ev->type) { case SDL_VIDEOEXPOSE: sdl_update(ds, 0, 0, real_screen->w, real_screen->h); break; case SDL_KEYDOWN: case SDL_KEYUP: if (ev->type == SDL_KEYDOWN) { if (!alt_grab) { mod_state = (SDL_GetModState() & gui_grab_code) == gui_grab_code; } else { mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) == (gui_grab_code | KMOD_LSHIFT); } gui_key_modifier_pressed = mod_state; if (gui_key_modifier_pressed) { int keycode; keycode = sdl_keyevent_to_keycode(&ev->key); switch(keycode) { case 0x21: /* 'f' key on US keyboard */ toggle_full_screen(ds); gui_keysym = 1; break; case 0x02 ... 0x0a: /* '1' to '9' keys */ /* Reset the modifiers sent to the current console */ reset_keys(); console_select(keycode - 0x02); if (!is_graphic_console()) { /* display grab if going to a text console */ if (gui_grab) sdl_grab_end(); } gui_keysym = 1; break; default: break; } } else if (!is_graphic_console()) { int keysym; keysym = 0; if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) { switch(ev->key.keysym.sym) { case SDLK_UP: keysym = QEMU_KEY_CTRL_UP; break; case SDLK_DOWN: keysym = QEMU_KEY_CTRL_DOWN; break; case SDLK_LEFT: keysym = QEMU_KEY_CTRL_LEFT; break; case SDLK_RIGHT: keysym = QEMU_KEY_CTRL_RIGHT; break; case SDLK_HOME: keysym = QEMU_KEY_CTRL_HOME; break; case SDLK_END: keysym = QEMU_KEY_CTRL_END; break; case SDLK_PAGEUP: keysym = QEMU_KEY_CTRL_PAGEUP; break; case SDLK_PAGEDOWN: keysym = QEMU_KEY_CTRL_PAGEDOWN; break; default: break; } } else { switch(ev->key.keysym.sym) { case SDLK_UP: keysym = QEMU_KEY_UP; break; case SDLK_DOWN: keysym = QEMU_KEY_DOWN; break; case SDLK_LEFT: keysym = QEMU_KEY_LEFT; break; case SDLK_RIGHT: keysym = QEMU_KEY_RIGHT; break; case SDLK_HOME: keysym = QEMU_KEY_HOME; break; case SDLK_END: keysym = QEMU_KEY_END; break; case SDLK_PAGEUP: keysym = QEMU_KEY_PAGEUP; break; case SDLK_PAGEDOWN: keysym = QEMU_KEY_PAGEDOWN; break; case SDLK_BACKSPACE: keysym = QEMU_KEY_BACKSPACE; break; case SDLK_DELETE: keysym = QEMU_KEY_DELETE; break; default: break; } } if (keysym) { kbd_put_keysym(keysym); } else if (ev->key.keysym.unicode != 0) { kbd_put_keysym(ev->key.keysym.unicode); } } } else if (ev->type == SDL_KEYUP) { if (!alt_grab) { mod_state = (ev->key.keysym.mod & gui_grab_code); } else { mod_state = (ev->key.keysym.mod & (gui_grab_code | KMOD_LSHIFT)); } if (!mod_state) { if (gui_key_modifier_pressed) { gui_key_modifier_pressed = 0; if (gui_keysym == 0) { /* exit/enter grab if pressing Ctrl-Alt */ if (!gui_grab) { /* if the application is not active, do not try to enter grab state. It prevents 'SDL_WM_GrabInput(SDL_GRAB_ON)' from blocking all the application (SDL bug). */ if (SDL_GetAppState() & SDL_APPACTIVE) sdl_grab_start(); } else { sdl_grab_end(); } /* SDL does not send back all the modifiers key, so we must correct it */ reset_keys(); break; } gui_keysym = 0; } } } if (is_graphic_console() && !gui_keysym) sdl_process_key(&ev->key); break; case SDL_QUIT: if (!no_quit) qemu_system_shutdown_request(); break; case SDL_MOUSEMOTION: if (gui_grab || kbd_mouse_is_absolute() || absolute_enabled) { sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel, 0, ev->motion.x, ev->motion.y, ev->motion.state); } break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: { SDL_MouseButtonEvent *bev = &ev->button; if (!gui_grab && !kbd_mouse_is_absolute()) { if (ev->type == SDL_MOUSEBUTTONDOWN && (bev->button == SDL_BUTTON_LEFT)) { /* start grabbing all events */ sdl_grab_start(); } } else { int dz; dz = 0; if (ev->type == SDL_MOUSEBUTTONDOWN) { buttonstate |= SDL_BUTTON(bev->button); } else { buttonstate &= ~SDL_BUTTON(bev->button); } #ifdef SDL_BUTTON_WHEELUP if (bev->button == SDL_BUTTON_WHEELUP && ev->type == SDL_MOUSEBUTTONDOWN) { dz = -1; } else if (bev->button == SDL_BUTTON_WHEELDOWN && ev->type == SDL_MOUSEBUTTONDOWN) { dz = 1; } #endif sdl_send_mouse_event(0, 0, dz, bev->x, bev->y, buttonstate); } } break; case SDL_ACTIVEEVENT: if (gui_grab && ev->active.state == SDL_APPINPUTFOCUS && !ev->active.gain && !gui_fullscreen_initial_grab) { sdl_grab_end(); } if (ev->active.state & SDL_APPACTIVE) { if (ev->active.gain) { /* Back to default interval */ dcl->gui_timer_interval = 0; dcl->idle = 0; } else { /* Sleeping interval */ dcl->gui_timer_interval = 500; dcl->idle = 1; } } break; default: break; }
bool select_difficulty( void ) { JE_loadPic(VGAScreen, 2, false); JE_dString(VGAScreen, JE_fontCenter(difficulty_name[0], FONT_SHAPES), 20, difficulty_name[0], FONT_SHAPES); difficultyLevel = 2; int difficulty_max = 3; bool fade_in = true; for (; ; ) { for (int i = 1; i <= difficulty_max; i++) { JE_outTextAdjust(VGAScreen, JE_fontCenter(difficulty_name[i], SMALL_FONT_SHAPES), i * 24 + 30, difficulty_name[i], 15, -4 + (i == difficultyLevel ? 2 : 0), SMALL_FONT_SHAPES, true); } JE_showVGA(); if (fade_in) { fade_palette(colors, 10, 0, 255); fade_in = false; } JE_word temp = 0; JE_textMenuWait(&temp, false); if (SDL_GetModState() & KMOD_SHIFT) { if ((difficulty_max < 4 && keysactive[SDLK_g]) || (difficulty_max == 4 && keysactive[SDLK_RIGHTBRACKET])) { difficulty_max++; } } else if (difficulty_max == 5 && keysactive[SDLK_l] && keysactive[SDLK_o] && keysactive[SDLK_r] && keysactive[SDLK_d]) { difficulty_max++; } if (newkey) { switch (lastkey_sym) { case SDLK_UP: difficultyLevel--; if (difficultyLevel < 1) { difficultyLevel = difficulty_max; } JE_playSampleNum(S_CURSOR); break; case SDLK_DOWN: difficultyLevel++; if (difficultyLevel > difficulty_max) { difficultyLevel = 1; } JE_playSampleNum(S_CURSOR); break; case SDLK_RETURN: JE_playSampleNum(S_SELECT); /* fading handled elsewhere fade_black(10); */ if (difficultyLevel == 6) { difficultyLevel = 8; } else if (difficultyLevel == 5) { difficultyLevel = 6; } return true; case SDLK_ESCAPE: JE_playSampleNum(S_SPRING); /* fading handled elsewhere fade_black(10); */ return false; default: break; } } } }
/** * \brief Returns whether the CTRL key is currently down. * * There is no distinction between the right and left CTRL keys in this function. * * \return true if the CTRL key is currently down */ bool InputEvent::is_control_down() { SDL_Keymod mod = SDL_GetModState(); return mod & KMOD_CTRL; }
void Runtime::pollEvents(bool blocking) { if (isActive() && !isRestart()) { SDL_Event ev; SDL_Keymod mod; if (blocking ? SDL_WaitEvent(&ev) : SDL_PollEvent(&ev)) { MAEvent *maEvent = NULL; switch (ev.type) { case SDL_TEXTINPUT: // pre-transformed/composted text mod = SDL_GetModState(); if (!mod || (mod & (KMOD_SHIFT|KMOD_CAPS))) { // ALT + CTRL keys handled in SDL_KEYDOWN for (int i = 0; ev.text.text[i] != 0; i++) { MAEvent *keyEvent = new MAEvent(); keyEvent->type = EVENT_TYPE_KEY_PRESSED; keyEvent->key = ev.text.text[i]; keyEvent->nativeKey = 0; pushEvent(keyEvent); } } break; case SDL_QUIT: setExit(true); break; case SDL_KEYDOWN: if (!isEditing() && ev.key.keysym.sym == SDLK_c && (ev.key.keysym.mod & KMOD_CTRL)) { setExit(true); } else if (ev.key.keysym.sym == SDLK_m && (ev.key.keysym.mod & KMOD_CTRL)) { showMenu(); } else if (ev.key.keysym.sym == SDLK_b && (ev.key.keysym.mod & KMOD_CTRL)) { setBack(); } else if (ev.key.keysym.sym == SDLK_BACKSPACE && get_focus_edit() == NULL && ((ev.key.keysym.mod & KMOD_CTRL) || !isRunning())) { setBack(); } else if (!isEditing() && ev.key.keysym.sym == SDLK_PAGEUP && (ev.key.keysym.mod & KMOD_CTRL)) { _output->scroll(true, true); } else if (!isEditing() && ev.key.keysym.sym == SDLK_PAGEDOWN && (ev.key.keysym.mod & KMOD_CTRL)) { _output->scroll(false, true); } else if (!isEditing() && ev.key.keysym.sym == SDLK_UP && (ev.key.keysym.mod & KMOD_CTRL)) { _output->scroll(true, false); } else if (!isEditing() && ev.key.keysym.sym == SDLK_DOWN && (ev.key.keysym.mod & KMOD_CTRL)) { _output->scroll(false, false); } else if (ev.key.keysym.sym == SDLK_p && (ev.key.keysym.mod & KMOD_CTRL)) { ::screen_dump(); } else { int lenMap = sizeof(keymap) / sizeof(keymap[0]); for (int i = 0; i < lenMap; i++) { if (ev.key.keysym.sym == keymap[i][0]) { maEvent = new MAEvent(); maEvent->type = EVENT_TYPE_KEY_PRESSED; maEvent->key = keymap[i][1]; maEvent->nativeKey = ev.key.keysym.mod; break; } } if (maEvent == NULL && ((ev.key.keysym.sym >= SDLK_KP_1 && ev.key.keysym.sym <= SDLK_KP_9) || ((ev.key.keysym.mod & KMOD_CTRL) && ev.key.keysym.sym != SDLK_LSHIFT && ev.key.keysym.sym != SDLK_RSHIFT && ev.key.keysym.sym != SDLK_LCTRL && ev.key.keysym.sym != SDLK_RCTRL) || (ev.key.keysym.mod & KMOD_ALT))) { maEvent = new MAEvent(); maEvent->type = EVENT_TYPE_KEY_PRESSED; maEvent->key = ev.key.keysym.sym; maEvent->nativeKey = ev.key.keysym.mod; } } break; case SDL_MOUSEBUTTONDOWN: if (ev.button.button == SDL_BUTTON_RIGHT) { _menuX = ev.motion.x; _menuY = ev.motion.y; showMenu(); } else if (ev.motion.x != 0 && ev.motion.y != 0) { // avoid phantom down message when launching in windows maEvent = getMotionEvent(EVENT_TYPE_POINTER_PRESSED, &ev); } break; case SDL_MOUSEMOTION: maEvent = getMotionEvent(EVENT_TYPE_POINTER_DRAGGED, &ev); break; case SDL_MOUSEBUTTONUP: SDL_SetCursor(_cursorArrow); maEvent = getMotionEvent(EVENT_TYPE_POINTER_RELEASED, &ev); break; case SDL_WINDOWEVENT: switch (ev.window.event) { case SDL_WINDOWEVENT_FOCUS_GAINED: SDL_SetModState(KMOD_NONE); break; case SDL_WINDOWEVENT_RESIZED: onResize(ev.window.data1, ev.window.data2); break; case SDL_WINDOWEVENT_EXPOSED: _graphics->redraw(); break; case SDL_WINDOWEVENT_LEAVE: _output->removeHover(); break; } break; case SDL_DROPFILE: setLoadPath(ev.drop.file); setExit(false); SDL_free(ev.drop.file); break; case SDL_MOUSEWHEEL: if (!_output->scroll(ev.wheel.y == 1, false)) { maEvent = new MAEvent(); maEvent->type = EVENT_TYPE_KEY_PRESSED; maEvent->key = ev.wheel.y == 1 ? SB_KEY_UP : SB_KEY_DN; maEvent->nativeKey = KMOD_CTRL; } break; } if (maEvent != NULL) { pushEvent(maEvent); } } } }
// Get the equivalent ASCII (Unicode?) character for a keypress. static int GetTypedChar(SDL_Keysym *sym) { // We only return typed characters when entering text, after // I_StartTextInput() has been called. Otherwise we return nothing. if (!text_input_enabled) { return 0; } // If we're strictly emulating Vanilla, we should always act like // we're using a US layout keyboard (in ev_keydown, data1=data2). // Otherwise we should use the native key mapping. if (vanilla_keyboard_mapping) { int result = TranslateKey(sym); // If shift is held down, apply the original uppercase // translation table used under DOS. if ((SDL_GetModState() & KMOD_SHIFT) != 0 && result >= 0 && result < arrlen(shiftxform)) { result = shiftxform[result]; } return result; } else { SDL_Event next_event; // Special cases, where we always return a fixed value. switch (sym->sym) { case SDLK_BACKSPACE: return KEY_BACKSPACE; case SDLK_RETURN: return KEY_ENTER; default: break; } // The following is a gross hack, but I don't see an easier way // of doing this within the SDL2 API (in SDL1 it was easier). // We want to get the fully transformed input character associated // with this keypress - correct keyboard layout, appropriately // transformed by any modifier keys, etc. So peek ahead in the SDL // event queue and see if the key press is immediately followed by // an SDL_TEXTINPUT event. If it is, it's reasonable to assume the // key press and the text input are connected. Technically the SDL // API does not guarantee anything of the sort, but in practice this // is what happens and I've verified it through manual inspect of // the SDL source code. // // In an ideal world we'd split out ev_keydown into a separate // ev_textinput event, as SDL2 has done. But this doesn't work // (I experimented with the idea), because lots of Doom's code is // based around different responders "eating" events to stop them // being passed on to another responder. If code is listening for // a text input, it cannot block the corresponding keydown events // which can affect other responders. // // So we're stuck with this as a rather fragile alternative. if (SDL_PeepEvents(&next_event, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) == 1 && next_event.type == SDL_TEXTINPUT) { // If an SDL_TEXTINPUT event is found, we always assume it // matches the key press. The input text must be a single // ASCII character - if it isn't, it's possible the input // char is a Unicode value instead; better to send a null // character than the unshifted key. if (strlen(next_event.text.text) == 1 && (next_event.text.text[0] & 0x80) == 0) { return next_event.text.text[0]; } } // Failed to find anything :/ return 0; } }
Sdl2Application::InputEvent::Modifiers Sdl2Application::MouseMoveEvent::modifiers() { if(modifiersLoaded) return _modifiers; modifiersLoaded = true; return _modifiers = fixedModifiers(Uint16(SDL_GetModState())); }
int main(int argc, char *argv[]) { SDL_Init(SDL_INIT_VIDEO); SDL_WM_SetCaption("La grue !", NULL); SDL_SetVideoMode(LARGEUR_ECRAN, HAUTEUR_ECRAN, 32, SDL_OPENGL); SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, LARGEUR_ECRAN, 0, HAUTEUR_ECRAN); bool continuer = true; SDL_Event event; SDLMod mod = KMOD_NONE; int angle_grand_bras = 45; int angle_petit_bras = -10; int longueur_fils = 50; while (continuer) { SDL_WaitEvent(&event); mod = SDL_GetModState(); switch(event.type) { case SDL_QUIT: continuer = false; break; case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_ESCAPE: /* Appui sur la touche Echap, on arrête le programme */ continuer = false; break; case SDLK_UP: if (longueur_fils > LONGUEUR_FILS_MIN) longueur_fils -= 1; break; case SDLK_DOWN: if (longueur_fils < LONGUEUR_FILS_MAX) longueur_fils += 1; break; case SDLK_LEFT: if (mod & KMOD_SHIFT) { if (angle_grand_bras < ANGLE_GD_BRAS_MAX) angle_grand_bras += 5; } else { if (angle_petit_bras < ANGLE_PT_BRAS_MAX) angle_petit_bras += 5; } break; case SDLK_RIGHT: if (mod & KMOD_SHIFT) { if (angle_grand_bras > ANGLE_GD_BRAS_MIN) angle_grand_bras -= 5; } else { if (angle_petit_bras > ANGLE_PT_BRAS_MIN) angle_petit_bras -= 5; } break; case SDLK_h: /* dessinerRepere(50); */ break; default: break; } break; default: break; } /* efface le tampon d'affichage */ glClear(GL_COLOR_BUFFER_BIT); /* dessine */ /* base */ glPushMatrix(); glTranslated(20, 20, 0); glBegin(GL_QUADS); glColor3ub(255, 150, 0); glVertex2d(0, 0); glVertex2d(0, 40); glVertex2d(100, 40); glVertex2d(100, 0); glEnd(); glPopMatrix(); /* grand bras */ glPushMatrix(); glTranslated(70, 60, 0); glRotated(angle_grand_bras, 0, 0, 1); glBegin(GL_QUADS); glColor3ub(255, 250, 0); glVertex2d(0, -15); glVertex2d(0, 15); glVertex2d(LONGUEUR_GD_BRAS, 15); glVertex2d(LONGUEUR_GD_BRAS, -15); glEnd(); /* petit bras */ glTranslated(LONGUEUR_GD_BRAS, 0, 0); glRotated(angle_petit_bras, 0, 0, 1); glBegin(GL_QUADS); glColor3ub(50, 250, 50); glVertex2d(0, -10); glVertex2d(0, 10); glVertex2d(LONGUEUR_PT_BRAS, 10); glVertex2d(LONGUEUR_PT_BRAS, -10); glEnd(); /* fils */ glTranslated(LONGUEUR_PT_BRAS, 0, 0); glRotated(-90 + (angle_petit_bras * -1) + (angle_grand_bras * -1), 0, 0, 1); glBegin(GL_LINES); glColor3ub(255, 255, 255); glVertex2d(0, 0); glVertex2d(longueur_fils, 0); glEnd(); /* caisse */ glTranslated(longueur_fils, 0, 0); glBegin(GL_QUADS); glColor3ub(255, 0, 0); glVertex2d(0, (TAILLE_CAISSE / 2)); glVertex2d(TAILLE_CAISSE, (TAILLE_CAISSE / 2)); glVertex2d(TAILLE_CAISSE, -(TAILLE_CAISSE / 2)); glVertex2d(0, -(TAILLE_CAISSE / 2)); glEnd(); /* Restore la matrice de base pour que les modifications qui viennent d'être effectuées ne s'ajoutent pas à chaque fois que les éléments se redessine */ glPopMatrix(); /* s'assure que toutes les cmd opengl ont été exécutées */ glFlush(); /* échange des buffers back et front */ SDL_GL_SwapBuffers(); } SDL_Quit(); return 0; }
static void handle_keydown(DisplayState *ds, SDL_Event *ev) { int mod_state; int keycode; if (alt_grab) { // LOGV("Found alt grab\n"); mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) == (gui_grab_code | KMOD_LSHIFT); } else if (ctrl_grab) { // LOGV("Found ctrl grab\n"); mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL; } else { // LOGV("Default grab\n"); mod_state = (SDL_GetModState() & gui_grab_code) == gui_grab_code; } gui_key_modifier_pressed = mod_state; if (gui_key_modifier_pressed) { keycode = sdl_keyevent_to_keycode(&ev->key); // LOGV("Found modifier pressed for key/keycode = %d/%d\n", ev->key.keysym.sym, keycode); switch (keycode) { case 1: /* 'f' key on US keyboard */ LOGV("Keycode Pressed 'f' Fullscreen\n"); toggle_full_screen(ds); gui_keysym = 1; break; case 16: /* 'u' key on US keyboard */ LOGV("Keycode Pressed 'u' unset Scale\n"); if (scaling_active) { LOGV("Found scaling active Unsetting...\n"); scaling_active = 0; sdl_resize(ds); vga_hw_invalidate(); vga_hw_update(); reset_keys(); } gui_keysym = 1; break; case 22 ... 23: /* '1' to '9' keys */ //MK hack /* Reset the modifiers sent to the current console */ LOGV("Keycode Pressed '1-9' console\n"); reset_keys(); console_select(keycode - 22); gui_keysym = 1; // if (gui_fullscreen) { // LOGV("Found fullscreen breaking...\n"); // break; // } if (!is_graphic_console()) { /* release grab if going to a text console */ LOGV("Found text console releasing grab...\n"); if (gui_grab) { LOGV("Found grab, grab ending...\n"); sdl_grab_end(); } else if (absolute_enabled) { LOGV("Found absolute_enabled, show cursor...\n"); sdl_show_cursor(); } } else if (absolute_enabled) { LOGV("Found absolute_enabled, hiding cursor and grabing mouse...\n"); sdl_hide_cursor(); absolute_mouse_grab(); } break; case 24: /* '4' Zoom In */ case 25: /* '3' Zoom Out*/ LOGV("Keycode Pressed '3/4' Zoom\n"); // if (!gui_fullscreen) { { int width = MAX(real_screen->w + (keycode == 25 ? 50 : -50), 160); int height = (ds_get_height(ds) * width) / ds_get_width(ds); LOGV("Found no fullscreen, scaling to: %dx%d \n", width, height); sdl_scale(ds, width, height); vga_hw_invalidate(); vga_hw_update(); reset_keys(); gui_keysym = 1; } // } break; case 26: /* Fit to Screen */ LOGV("Keycode Pressed '5' Fit to Screen\n"); // if (!gui_fullscreen) { { int width; int height; AndroidGetWindowSize(&width, &height); LOGV("Got Android window size=%dx%d", width, height); LOGV("Got VM resolution=%dx%d", ds_get_width(ds), ds_get_height(ds)); float aspectRatio = (float) ds_get_height(ds) / (float) ds_get_width(ds); LOGV("Got aspectRatio=%f", aspectRatio); int new_width = (int) (height / aspectRatio); if(new_width > width){ LOGV("Width is overrun, modifying height"); new_width = width; height = width * aspectRatio; } LOGV("Found no fullscreen, Fit To Screen: %dx%d \n", new_width, height); sdl_scale(ds, new_width, height); vga_hw_invalidate(); vga_hw_update(); reset_keys(); gui_keysym = 1; } // } break; case 27: /* Stretch to Screen */ LOGV("Keycode Pressed '6' Fit to Screen\n"); // if (!gui_fullscreen) { { int width; int height; AndroidGetWindowSize(&width, &height); LOGV("Found no fullscreen, Fit To Screen: %dx%d \n", width, height); sdl_scale(ds, width, height); vga_hw_invalidate(); vga_hw_update(); reset_keys(); gui_keysym = 1; } // } break; default: LOGV("Default\n"); break; } } else if (!is_graphic_console()) {
/* ================ 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 = 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; } #endif static byte c = 0; if (c) { res.evType = SE_CHAR; res.evValue = c; c = 0; return res; } if (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; } return res_none; #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); } return res_none; case SDL_VIDEOEXPOSE: return res_none; #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); return res_none; } } #else 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; } } } #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 && *ev.text.text) { if (!ev.text.text[1]) c = *ev.text.text; else s = strdup(ev.text.text); } return res_none; #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); return res_none; } default: common->Warning("unknown event %u", ev.type); return res_none; } } return res_none; }
static int _process_mouse_event(void) { SDLMod keymods; short shift_flags = 0; memset(&pdc_mouse_status, 0, sizeof(MOUSE_STATUS)); keymods = SDL_GetModState(); if (keymods & KMOD_SHIFT) shift_flags |= BUTTON_SHIFT; if (keymods & KMOD_CTRL) shift_flags |= BUTTON_CONTROL; if (keymods & KMOD_ALT) shift_flags |= BUTTON_ALT; if (event.type == SDL_MOUSEMOTION) { int i; pdc_mouse_status.x = event.motion.x / pdc_fwidth; pdc_mouse_status.y = event.motion.y / pdc_fheight; if (!event.motion.state || (pdc_mouse_status.x == old_mouse_status.x && pdc_mouse_status.y == old_mouse_status.y)) return -1; pdc_mouse_status.changes = PDC_MOUSE_MOVED; for (i = 0; i < 3; i++) { if (event.motion.state & SDL_BUTTON(i + 1)) { pdc_mouse_status.button[i] = BUTTON_MOVED | shift_flags; pdc_mouse_status.changes |= (1 << i); } } } else { short action = (event.button.state == SDL_PRESSED) ? BUTTON_PRESSED : BUTTON_RELEASED; Uint8 btn = event.button.button; /* handle scroll wheel */ if ((btn == 4 || btn == 5) && action == BUTTON_RELEASED) { pdc_mouse_status.x = pdc_mouse_status.y = -1; pdc_mouse_status.changes = (btn == 5) ? PDC_MOUSE_WHEEL_DOWN : PDC_MOUSE_WHEEL_UP; return KEY_MOUSE; } if (btn < 1 || btn > 3) return -1; /* check for a click -- a press followed immediately by a release */ if (action == BUTTON_PRESSED && SP->mouse_wait) { SDL_Event rel; napms(SP->mouse_wait); if (SDL_PollEvent(&rel)) { if (rel.type == SDL_MOUSEBUTTONUP && rel.button.button == btn) action = BUTTON_CLICKED; else SDL_PushEvent(&rel); } } pdc_mouse_status.x = event.button.x / pdc_fwidth; pdc_mouse_status.y = event.button.y / pdc_fheight; btn--; pdc_mouse_status.button[btn] = action | shift_flags; pdc_mouse_status.changes = (1 << btn); } old_mouse_status = pdc_mouse_status; return KEY_MOUSE; }
/** * Handles screen key shortcuts. * @param action Pointer to an action. */ void Screen::handle(Action *action) { if (Options::debug) { if (action->getDetails()->type == SDL_KEYDOWN && action->getDetails()->key.keysym.sym == SDLK_F8) { switch(Timer::gameSlowSpeed) { case 1: Timer::gameSlowSpeed = 5; break; case 5: Timer::gameSlowSpeed = 15; break; default: Timer::gameSlowSpeed = 1; break; } } } if (action->getDetails()->type == SDL_KEYDOWN && action->getDetails()->key.keysym.sym == SDLK_RETURN && (SDL_GetModState() & KMOD_ALT) != 0) { Options::fullscreen = !Options::fullscreen; resetDisplay(); } else if (action->getDetails()->type == SDL_KEYDOWN && action->getDetails()->key.keysym.sym == Options::keyScreenshot) { std::ostringstream ss; int i = 0; do { ss.str(""); ss << Options::getMasterUserFolder() << "screen" << std::setfill('0') << std::setw(3) << i << ".png"; i++; } while (CrossPlatform::fileExists(ss.str())); screenshot(ss.str()); return; } }
void textbox::handle_event(const SDL_Event& event, bool was_forwarded) { if(!enabled()) return; scrollarea::handle_event(event); if(hidden()) return; bool changed = false; const int old_selstart = selstart_; const int old_selend = selend_; //Sanity check: verify that selection start and end are within text //boundaries if(is_selection() && !(size_t(selstart_) <= text_.size() && size_t(selend_) <= text_.size())) { WRN_DP << "out-of-boundary selection\n"; selstart_ = selend_ = -1; } int mousex, mousey; const Uint8 mousebuttons = SDL_GetMouseState(&mousex,&mousey); if(!(mousebuttons & SDL_BUTTON(1))) { grabmouse_ = false; } SDL_Rect const &loc = inner_location(); bool clicked_inside = !mouse_locked() && (event.type == SDL_MOUSEBUTTONDOWN && (mousebuttons & SDL_BUTTON(1)) && point_in_rect(mousex, mousey, loc)); if(clicked_inside) { set_focus(true); } if ((grabmouse_ && (!mouse_locked() && event.type == SDL_MOUSEMOTION)) || clicked_inside) { const int x = mousex - loc.x + text_pos_; const int y = mousey - loc.y; int pos = 0; int distance = x; for(unsigned int i = 1; i < char_x_.size(); ++i) { if(static_cast<int>(yscroll_) + y < char_y_[i]) { break; } // Check individually each distance (if, one day, we support // RTL languages, char_x_[c] may not be monotonous.) if(abs(x - char_x_[i]) < distance && yscroll_ + y < char_y_[i] + line_height_) { pos = i; distance = abs(x - char_x_[i]); } } cursor_ = pos; if(grabmouse_) selend_ = cursor_; update_text_cache(false); if(!grabmouse_ && mousebuttons & SDL_BUTTON(1)) { grabmouse_ = true; selstart_ = selend_ = cursor_; } else if (! (mousebuttons & SDL_BUTTON(1))) { grabmouse_ = false; } set_dirty(); } //if we don't have the focus, then see if we gain the focus, //otherwise return if(!was_forwarded && focus(&event) == false) { if (!mouse_locked() && event.type == SDL_MOUSEMOTION && point_in_rect(mousex, mousey, loc)) events::focus_handler(this); return; } if(event.type != SDL_KEYDOWN || (!was_forwarded && focus(&event) != true)) { draw(); return; } const SDL_keysym& key = reinterpret_cast<const SDL_KeyboardEvent&>(event).keysym; const SDLMod modifiers = SDL_GetModState(); const int c = key.sym; const int old_cursor = cursor_; if(editable_) { if(c == SDLK_LEFT && cursor_ > 0) --cursor_; if(c == SDLK_RIGHT && cursor_ < static_cast<int>(text_.size())) ++cursor_; // ctrl-a, ctrl-e and ctrl-u are readline style shortcuts, even on Macs if(c == SDLK_END || (c == SDLK_e && (modifiers & KMOD_CTRL))) cursor_ = text_.size(); if(c == SDLK_HOME || (c == SDLK_a && (modifiers & KMOD_CTRL))) cursor_ = 0; if((old_cursor != cursor_) && (modifiers & KMOD_SHIFT)) { if(selstart_ == -1) selstart_ = old_cursor; selend_ = cursor_; } } else if(c == SDLK_LEFT || c == SDLK_RIGHT || c == SDLK_END || c == SDLK_HOME) { pass_event_to_target(event); } if(editable_) { if(c == SDLK_BACKSPACE) { changed = true; if(is_selection()) { erase_selection(); } else if(cursor_ > 0) { --cursor_; text_.erase(text_.begin()+cursor_); } } if(c == SDLK_u && (modifiers & KMOD_CTRL)) { // clear line changed = true; cursor_ = 0; text_.resize(0); } if(c == SDLK_DELETE && !text_.empty()) { changed = true; if(is_selection()) { erase_selection(); } else { if(cursor_ < static_cast<int>(text_.size())) { text_.erase(text_.begin()+cursor_); } } } } else if(c == SDLK_BACKSPACE || c == SDLK_DELETE || (c == SDLK_u && (modifiers & KMOD_CTRL))) { pass_event_to_target(event); } #if SDL_VERSION_ATLEAST(2, 0, 0) ucs4::char_t character = key.scancode; #else ucs4::char_t character = key.unicode; #endif //movement characters may have a "Unicode" field on some platforms, so ignore it. if(!(c == SDLK_UP || c == SDLK_DOWN || c == SDLK_LEFT || c == SDLK_RIGHT || c == SDLK_DELETE || c == SDLK_BACKSPACE || c == SDLK_END || c == SDLK_HOME || c == SDLK_PAGEUP || c == SDLK_PAGEDOWN)) { if(character != 0) { DBG_G << "Char: " << character << ", c = " << c << "\n"; } if((event.key.keysym.mod & copypaste_modifier) //on windows SDL fires for AltGr lctrl+ralt (needed to access @ etc on certain keyboards) #ifdef _WIN32 && !(event.key.keysym.mod & KMOD_ALT) #endif ) { switch(c) { case SDLK_v: // paste { if(!editable()) { pass_event_to_target(event); break; } changed = true; if(is_selection()) erase_selection(); std::string str = copy_from_clipboard(false); //cut off anything after the first newline str.erase(std::find_if(str.begin(),str.end(),utils::isnewline),str.end()); ucs4::string s = utils::string_to_ucs4string(str); if(text_.size() < max_size_) { if(s.size() + text_.size() > max_size_) { s.resize(max_size_ - text_.size()); } text_.insert(text_.begin()+cursor_, s.begin(), s.end()); cursor_ += s.size(); } } break; case SDLK_c: // copy { if(is_selection()) { const size_t beg = std::min<size_t>(size_t(selstart_),size_t(selend_)); const size_t end = std::max<size_t>(size_t(selstart_),size_t(selend_)); ucs4::string ws(text_.begin() + beg, text_.begin() + end); std::string s = utils::ucs4string_to_string(ws); copy_to_clipboard(s, false); } } break; } } else if(editable_) { if(character >= 32 && character != 127) { changed = true; if(is_selection()) erase_selection(); if(text_.size() + 1 <= max_size_) { text_.insert(text_.begin()+cursor_,character); ++cursor_; } } } else { pass_event_to_target(event); } } if(is_selection() && (selend_ != cursor_)) selstart_ = selend_ = -1; //since there has been cursor activity, make the cursor appear for //at least the next 500ms. show_cursor_ = true; show_cursor_at_ = SDL_GetTicks(); if(changed || old_cursor != cursor_ || old_selstart != selstart_ || old_selend != selend_) { text_image_ = NULL; handle_text_changed(text_); } set_dirty(true); }
void SDLViewer::execute() { bool redisplay = true; MouseButton button = NoButton; unsigned char key; int x, y; SDL_Event event; int modifiers = 0; static unsigned int stimer; //Ensure window visible for interaction show(); // Enter event loop processing while ( !quitProgram ) { // Check for events // Delay redisplay & resize until event queue empty if (SDL_PollEvent(&event) == 0) { // Resize window if (resized) { if (stimer < SDL_GetTicks()) { // Create in new dimensions resized = false; open(width, height); redisplay = true; } else continue; //Cycle until timer runs out } if (redisplay) { // Redraw Viewer (Call virtual to display) display(); redisplay = false; } // Wait for next event SDL_WaitEvent( &event ); } //Save shift states modifiers = SDL_GetModState(); keyState.shift = (modifiers & KMOD_SHIFT); keyState.ctrl = (modifiers & KMOD_CTRL); keyState.alt = (modifiers & KMOD_ALT); // Process event switch (event.type) { case SDL_QUIT: quitProgram = true; break; case SDL_VIDEORESIZE: //Adjust viewport metrics etc... resize(event.resize.w, event.resize.h); resized = true; //Start timer to wait for sizing events to cease before calling actual context resize stimer = SDL_GetTicks() + 200; break; case SDL_KEYDOWN: //Pass keystrokes on KEYDOWN only, char info not provided by SDL on KEYUP key = event.key.keysym.unicode; if (!key) { int code = (int)event.key.keysym.sym; if (code == SDLK_KP8 || code == SDLK_UP) key = KEY_UP; if (code == SDLK_KP2 || code == SDLK_DOWN) key = KEY_DOWN; if (code == SDLK_KP4 || code == SDLK_LEFT) key = KEY_LEFT; if (code == SDLK_KP6 || code == SDLK_RIGHT) key = KEY_RIGHT; if (code == SDLK_KP9 || code == SDLK_PAGEUP) key = KEY_PAGEUP; if (code == SDLK_KP3 || code == SDLK_PAGEDOWN) key = KEY_PAGEDOWN; if (code == SDLK_KP7 || code == SDLK_HOME) key = KEY_HOME; if (code == SDLK_KP1 || code == SDLK_END) key = KEY_END; //key = (unsigned char)code; if (!key) continue; } SDL_GetMouseState(&x, &y); if (keyPress(key, x, y)) redisplay = true; break; case SDL_MOUSEMOTION: if (mouseState) { mouseMove(event.motion.x, event.motion.y); redisplay = true; } break; case SDL_MOUSEBUTTONDOWN: button = (MouseButton)event.button.button; // XOR state of three mouse buttons to the mouseState variable if (button <= RightButton) mouseState ^= (int)pow(2.0,button); mousePress( button, true, event.button.x, event.button.y); break; case SDL_MOUSEBUTTONUP: mouseState = 0; button = (MouseButton)event.button.button; mousePress( button, false, event.button.x, event.button.y); redisplay = true; break; case SDL_USEREVENT: // Timer event redisplay = true; break; case SDL_ACTIVEEVENT: if (event.active.state == SDL_APPACTIVE && event.active.gain == 1) // Restored from icon redisplay = true; break; case SDL_VIDEOEXPOSE: redisplay = true; // Repaint break; } } }
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { #else int main(int argc, char** argv) { #endif SDL_Surface *screen_sfc; F1SpiritApp *game; KEYBOARDSTATE *k; int time, act_time; SDL_Event event; bool quit = false; bool need_to_redraw = true; #ifdef F1SPIRIT_DEBUG_MESSAGES output_debug_message("Application started\n"); #endif #ifdef HAVE_GLES fullscreen = true; #endif screen_sfc = initialization((fullscreen ? SDL_FULLSCREEN : 0)); if (screen_sfc == 0) return 0; k = new KEYBOARDSTATE(); game = new F1SpiritApp(); #if 0//ndef HAVE_GLES // why recreating the context ??? if (fullscreen) { #ifdef HAVE_GLES EGL_Close(); screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, (fullscreen ? SDL_FULLSCREEN : 0)); EGL_Open((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y); #else screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0)); #endif SDL_WM_SetCaption(application_name, 0); SDL_ShowCursor(SDL_DISABLE); reload_textures++; #ifndef HAVE_GLES SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); #endif } #endif time = init_time = SDL_GetTicks(); IMG_Init(IMG_INIT_JPG|IMG_INIT_PNG); while (!quit) { while ( SDL_PollEvent( &event ) ) { switch ( event.type ) { /* Keyboard event */ case SDL_KEYDOWN: #ifdef __APPLE__ if (event.key.keysym.sym == SDLK_q) { SDLMod modifiers; modifiers = SDL_GetModState(); if ((modifiers &KMOD_META) != 0) { quit = true; } } #else if (event.key.keysym.sym == SDLK_F12) { quit = true; } #endif if (event.key.keysym.sym == SDLK_F10) { game->save_configuration("f1spirit.cfg"); game->load_configuration("f1spirit.cfg"); } #ifdef _WIN32 if (event.key.keysym.sym == SDLK_F4) { SDLMod modifiers; modifiers = SDL_GetModState(); if ((modifiers&KMOD_ALT) != 0) quit = true; } #endif #ifdef __APPLE__ if (event.key.keysym.sym == SDLK_f) { SDLMod modifiers; modifiers = SDL_GetModState(); if ((modifiers&KMOD_META) != 0) { /* Toggle FULLSCREEN mode: */ if (fullscreen) fullscreen = false; else fullscreen = true; screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0)); calcMinMax((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y); SDL_WM_SetCaption(application_name, 0); SDL_ShowCursor(SDL_DISABLE); reload_textures++; SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); } } #else if (event.key.keysym.sym == SDLK_RETURN) { SDLMod modifiers; modifiers = SDL_GetModState(); if ((modifiers&KMOD_ALT) != 0) { /* Toggle FULLSCREEN mode: */ if (fullscreen) fullscreen = false; else fullscreen = true; #ifndef HAVE_GLES #ifdef HAVE_GLES EGL_Close(); screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0)); EGL_Open((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y); #else screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0)); #endif calcMinMax((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y); SDL_WM_SetCaption(application_name, 0); SDL_ShowCursor(SDL_DISABLE); reload_textures++; #ifndef HAVE_GLES SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); #endif #endif } } #endif if (event.key.keysym.sym == SDLK_f) { SDLMod modifiers; modifiers = SDL_GetModState(); if ((modifiers&KMOD_ALT) != 0) { /* toggle FPS mode: */ if (show_fps) show_fps = false; else show_fps = true; } } /* Keyboard event */ SDL_keysym *ks; ks = new SDL_keysym(); *ks = event.key.keysym; k->keyevents.Add(ks); break; /* SDL_QUIT event (window close) */ case SDL_QUIT: quit = true; break; } } act_time = SDL_GetTicks(); if (act_time - time >= REDRAWING_PERIOD) { int max_frame_step = 10; /* frames_per_sec_tmp+=1; if ((act_time-init_time)>=1000) { frames_per_sec=frames_per_sec_tmp; frames_per_sec_tmp=0; init_time=act_time; } // if */ // On PANDORA, let's target 25 fps... int min_frame=1; #ifdef PANDORA min_frame=2; #endif do { time += REDRAWING_PERIOD; if ((act_time - time) > 10*REDRAWING_PERIOD) time = act_time; /* cycle */ k->cycle(); if (!game->cycle(k)) quit = true; need_to_redraw = true; k->keyevents.Delete(); act_time = SDL_GetTicks(); max_frame_step--; min_frame--; } while (((act_time - time >= REDRAWING_PERIOD) && (max_frame_step > 0)) || (min_frame > 0)); } /* Redraw */ if (need_to_redraw) { game->draw(); need_to_redraw = false; frames_per_sec_tmp += 1; } if ((act_time - init_time) >= 1000) { frames_per_sec = frames_per_sec_tmp; frames_per_sec_tmp = 0; init_time = act_time; } #ifndef PANDORA SDL_Delay(1); #endif } delete k; k = 0; delete game; game = 0; Stop_playback(); finalization(); #ifdef F1SPIRIT_DEBUG_MESSAGES output_debug_message("Application finished\n"); close_debug_messages(); #endif return 0; } /* main */
bool IN_IsNumLockDown() { return SDL_GetModState() & KMOD_NUM; }
void Engine::CheckMessages() { CDEBUG("checkmessages"); SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: { the<Input>()->KeyDown(event.key.keysym.sym); // bottom line screenshot if F11 is pressed //if (event.key.keysym.sym == SDLK_F11 && event.key.state == SDL_PRESSED) // ScreenShot(); // Alt-F4: Quit. Now. if (event.key.keysym.sym == SDLK_F4 && (SDL_GetModState() & (KMOD_LALT | KMOD_RALT))) { Shutdown(); exit(0); } break; } case SDL_KEYUP: { the<Input>()->KeyUp(event.key.keysym.sym); break; } case SDL_JOYAXISMOTION: { the<Input>()->JoyAxisMove(event.jaxis.which, event.jaxis.axis, event.jaxis.value); break; } case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: { the<Input>()->JoyButtonChange(event.jbutton.which, event.jbutton.button, event.jbutton.state == SDL_PRESSED); break; } case SDL_MOUSEBUTTONDOWN: { the<Input>()->MouseButtonChange(event.button.button, true); break; } case SDL_MOUSEBUTTONUP: { the<Input>()->MouseButtonChange(event.button.button, false); break; } case SDL_MOUSEMOTION: { the<Input>()->MouseMoved(event.motion.x, event.motion.y); break; } case SDL_QUIT: { Shutdown(); exit(0); break; } default: { break; } } } }
// // I_GetEvent // void I_GetEvent (void) { event_t event; event_t mouseevent = {ev_mouse, 0, 0, 0}; static int mbuttons = 0; int sendmouseevent = 0; SDL_Event ev; if (!(SDL_GetAppState()&SDL_APPINPUTFOCUS) && havefocus) { havefocus = false; UngrabMouse(); SetCursorState(true); } else if((SDL_GetAppState()&SDL_APPINPUTFOCUS) && !havefocus) { havefocus = true; if(!mousepaused) I_ResumeMouse(); } while(SDL_PollEvent(&ev)) { event.data1 = event.data2 = event.data3 = 0; switch(ev.type) { case SDL_QUIT: AddCommandString("quit"); break; case SDL_KEYDOWN: event.type = ev_keydown; event.data1 = ev.key.keysym.sym; if(event.data1 >= SDLK_KP0 && event.data1 <= SDLK_KP9) event.data2 = event.data3 = '0' + (event.data1 - SDLK_KP0); else if(event.data1 == SDLK_KP_PERIOD) event.data2 = event.data3 = '.'; else if(event.data1 == SDLK_KP_DIVIDE) event.data2 = event.data3 = '/'; else if(event.data1 == SDLK_KP_ENTER) event.data2 = event.data3 = '\r'; else if ( (ev.key.keysym.unicode & 0xFF80) == 0 ) event.data2 = event.data3 = ev.key.keysym.unicode; else event.data2 = event.data3 = 0; #ifdef WIN32 // SoM: Ignore the tab portion of alt-tab presses if(event.data1 == SDLK_TAB && SDL_GetModState() & (KMOD_LALT | KMOD_RALT)) event.data1 = event.data2 = event.data3 = 0; else #endif D_PostEvent(&event); break; case SDL_KEYUP: event.type = ev_keyup; event.data1 = ev.key.keysym.sym; if ( (ev.key.keysym.unicode & 0xFF80) == 0 ) event.data2 = event.data3 = ev.key.keysym.unicode; else event.data2 = event.data3 = 0; D_PostEvent(&event); break; case SDL_MOUSEMOTION: if(flushmouse) { flushmouse = false; break; } // denis - ignore artificially inserted events (see SDL_WarpMouse below) if(ev.motion.x == screen->width/2 && ev.motion.y == screen->height/2) { break; } mouseevent.data2 += AccelerateMouse(ev.motion.xrel); mouseevent.data3 -= AccelerateMouse(ev.motion.yrel); sendmouseevent = 1; break; case SDL_MOUSEBUTTONDOWN: if(nomouse) break; event.type = ev_keydown; if(ev.button.button == SDL_BUTTON_LEFT) { event.data1 = KEY_MOUSE1; mbuttons |= 1; } else if(ev.button.button == SDL_BUTTON_RIGHT) { event.data1 = KEY_MOUSE2; mbuttons |= 2; } else if(ev.button.button == SDL_BUTTON_MIDDLE) { event.data1 = KEY_MOUSE3; mbuttons |= 4; } else if(ev.button.button == SDL_BUTTON_WHEELUP) event.data1 = KEY_MWHEELUP; else if(ev.button.button == SDL_BUTTON_WHEELDOWN) event.data1 = KEY_MWHEELDOWN; D_PostEvent(&event); break; case SDL_MOUSEBUTTONUP: if(nomouse) break; event.type = ev_keyup; if(ev.button.button == SDL_BUTTON_LEFT) { event.data1 = KEY_MOUSE1; mbuttons &= ~1; } else if(ev.button.button == SDL_BUTTON_RIGHT) { event.data1 = KEY_MOUSE2; mbuttons &= ~2; } else if(ev.button.button == SDL_BUTTON_MIDDLE) { event.data1 = KEY_MOUSE3; mbuttons &= ~4; } else if(ev.button.button == SDL_BUTTON_WHEELUP) event.data1 = KEY_MWHEELUP; else if(ev.button.button == SDL_BUTTON_WHEELDOWN) event.data1 = KEY_MWHEELDOWN; D_PostEvent(&event); break; }; } if(!nomouse) { if(sendmouseevent) { mouseevent.data1 = mbuttons; D_PostEvent(&mouseevent); } if(mousegrabbed && screen) { SDL_WarpMouse(screen->width/ 2, screen->height / 2); } } }
bool InputWrapper::isModifierHeld(SDL_Keymod mod) { return SDL_GetModState() & mod; }
// Handle a released key void ManMachineInterface::HandleKeyReleased(const Key_t &key) { PressedKeys[key] = false; // Here we manage only actions which are activated on KEY_RELEASED event. { // Managing keys related to interface (no game interaction) // Always available switch(key){ // Managing interface case KEY_HELP: Game::GetInstance()->UserAsksForHelpMenu(); return; case KEY_QUIT: case KEY_PAUSE: Game::GetInstance()->UserAsksForMenu(); return; case KEY_FULLSCREEN: AppWarmux::GetInstance()->video->ToggleFullscreen(); return; case KEY_CHAT: if(Network::IsConnected()) Game::GetInstance()->chatsession.ShowInput(); return; case KEY_CENTER: Camera::GetInstance()->CenterOnActiveCharacter(); return; case KEY_TOGGLE_INTERFACE: Interface::GetInstance()->EnableDisplay(!Interface::GetInstance()->IsDisplayed()); return; case KEY_MINIMAP_FROM_GAME: Interface::GetInstance()->ToggleMinimap(); return; case KEY_MENU_OPTIONS_FROM_GAME: { OptionMenu options_menu; options_menu.Run(); return; } case KEY_MOVE_CAMERA_RIGHT: Camera::GetInstance()->RemoveLRMoveIntention(INTENTION_MOVE_RIGHT); return; case KEY_MOVE_CAMERA_LEFT: Camera::GetInstance()->RemoveLRMoveIntention(INTENTION_MOVE_LEFT); return; case KEY_MOVE_CAMERA_UP: Camera::GetInstance()->RemoveUDMoveIntention(INTENTION_MOVE_UP); return; case KEY_MOVE_CAMERA_DOWN: Camera::GetInstance()->RemoveUDMoveIntention(INTENTION_MOVE_DOWN); return; case KEY_DECREASE_MINIMAP: Interface::GetInstance()->MinimapSizeDelta(1); return; case KEY_INCREASE_MINIMAP: Interface::GetInstance()->MinimapSizeDelta(-1); return; case KEY_DECREASE_VOLUME: { Config *cfg = Config::GetInstance(); int volume = cfg->GetVolumeMusic() - 5; if (volume > 0) { cfg->SetVolumeMusic(volume); } else { cfg->SetVolumeMusic(0); JukeBox::GetInstance()->ActiveMusic(false); } volume = cfg->GetVolumeEffects() - 5; if (volume > 0) { cfg->SetVolumeEffects(volume); } else { cfg->SetVolumeEffects(0); JukeBox::GetInstance()->ActiveEffects(false); } return; } case KEY_INCREASE_VOLUME: { Config *cfg = Config::GetInstance(); int max_volume = cfg->GetMaxVolume(); int volume = cfg->GetVolumeMusic() + 5; if (volume < max_volume) { cfg->SetVolumeMusic(volume); } else { cfg->SetVolumeMusic(max_volume); } JukeBox::GetInstance()->ActiveMusic(true); volume = cfg->GetVolumeEffects() + 5; if (volume < max_volume) { cfg->SetVolumeEffects(volume); } else { cfg->SetVolumeEffects(max_volume); } JukeBox::GetInstance()->ActiveEffects(true); return; } default: break; } } // Managing shoot key // Drop bonus box or medkit when outside a turn // Shoot when in turn if (key == KEY_SHOOT) { if (Game::GetInstance()->ReadState() == Game::END_TURN) { Game::GetInstance()->RequestBonusBoxDrop(); } else if (Game::GetInstance()->ReadState() == Game::PLAYING && ActiveTeam().IsLocalHuman() && !ActiveCharacter().IsDead()) { ActiveTeam().AccessWeapon().HandleKeyReleased_Shoot(); } return; } { // Managing keys related to character moves // Available only when local if (!ActiveTeam().IsLocalHuman()) return; if (ActiveCharacter().IsDead()) return; if (Game::GetInstance()->ReadState() == Game::END_TURN) return; switch (key) { case KEY_MOVE_RIGHT: ActiveCharacter().HandleKeyReleased_MoveRight(false); break; case KEY_MOVE_RIGHT_SLOWLY: ActiveCharacter().HandleKeyReleased_MoveRight(true); break; case KEY_MOVE_LEFT: ActiveCharacter().HandleKeyReleased_MoveLeft(false); break; case KEY_MOVE_LEFT_SLOWLY: ActiveCharacter().HandleKeyReleased_MoveLeft(true); break; case KEY_UP: ActiveCharacter().HandleKeyReleased_Up(false); break; case KEY_UP_SLOWLY: ActiveCharacter().HandleKeyReleased_Up(true); break; case KEY_DOWN: ActiveCharacter().HandleKeyReleased_Down(false); break; case KEY_DOWN_SLOWLY: ActiveCharacter().HandleKeyReleased_Down(true); break; case KEY_JUMP: ActiveCharacter().HandleKeyReleased_Jump(); break; case KEY_HIGH_JUMP: ActiveCharacter().HandleKeyReleased_HighJump(); break; case KEY_BACK_JUMP: ActiveCharacter().HandleKeyReleased_BackJump(); break; default: if (Game::GetInstance()->ReadState() == Game::HAS_PLAYED) return; break; } if (Game::GetInstance()->ReadState() == Game::PLAYING) { switch (key) { case KEY_MOVE_RIGHT: ActiveTeam().AccessWeapon().HandleKeyReleased_MoveRight(false); return; case KEY_MOVE_RIGHT_SLOWLY: ActiveTeam().AccessWeapon().HandleKeyReleased_MoveRight(true); return; case KEY_MOVE_LEFT: ActiveTeam().AccessWeapon().HandleKeyReleased_MoveLeft(false); return; case KEY_MOVE_LEFT_SLOWLY: ActiveTeam().AccessWeapon().HandleKeyReleased_MoveLeft(true); return; case KEY_UP: ActiveTeam().AccessWeapon().HandleKeyReleased_Up(false); return; case KEY_UP_SLOWLY: ActiveTeam().AccessWeapon().HandleKeyReleased_Up(true); return; case KEY_DOWN: ActiveTeam().AccessWeapon().HandleKeyReleased_Down(false); return; case KEY_DOWN_SLOWLY: ActiveTeam().AccessWeapon().HandleKeyReleased_Down(true); return; case KEY_JUMP: ActiveTeam().AccessWeapon().HandleKeyReleased_Jump(); return; case KEY_HIGH_JUMP: ActiveTeam().AccessWeapon().HandleKeyReleased_HighJump(); return; case KEY_BACK_JUMP: ActiveTeam().AccessWeapon().HandleKeyReleased_BackJump(); return; // Shoot key case KEY_SHOOT: ActiveTeam().AccessWeapon().HandleKeyReleased_Shoot(); return; // Other keys usefull for weapons case KEY_WEAPON_1: ActiveTeam().AccessWeapon().HandleKeyReleased_Num1(); return; case KEY_WEAPON_2: ActiveTeam().AccessWeapon().HandleKeyReleased_Num2(); return; case KEY_WEAPON_3: ActiveTeam().AccessWeapon().HandleKeyReleased_Num3(); return; case KEY_WEAPON_4: ActiveTeam().AccessWeapon().HandleKeyReleased_Num4(); return; case KEY_WEAPON_5: ActiveTeam().AccessWeapon().HandleKeyReleased_Num5(); return; case KEY_WEAPON_6: ActiveTeam().AccessWeapon().HandleKeyReleased_Num6(); return; case KEY_WEAPON_7: ActiveTeam().AccessWeapon().HandleKeyReleased_Num7(); return; case KEY_WEAPON_8: ActiveTeam().AccessWeapon().HandleKeyReleased_Num8(); return; case KEY_WEAPON_9: ActiveTeam().AccessWeapon().HandleKeyReleased_Num9(); return; case KEY_WEAPON_LESS: ActiveTeam().AccessWeapon().HandleKeyReleased_Less(); return; case KEY_WEAPON_MORE: ActiveTeam().AccessWeapon().HandleKeyReleased_More(); return; default: break; } } } { // Managing keys related to change of character or weapon if (Game::GetInstance()->ReadState() != Game::PLAYING || !ActiveTeam().GetWeapon().CanChangeWeapon() || !ActiveTeam().IsLocalHuman()) return; Weapon::category_t weapon_sort = Weapon::INVALID; switch(key) { case KEY_NEXT_CHARACTER: if (GameMode::GetInstance()->AllowCharacterSelection()) { SDLMod mod = SDL_GetModState(); if (mod & KMOD_CTRL) { ActiveTeam().PreviousCharacter(); } else { ActiveTeam().NextCharacter(); } ActionHandler::GetInstance()->NewActionActiveCharacter(); } return; case KEY_WEAPONS1: weapon_sort = Weapon::HEAVY; break; case KEY_WEAPONS2: weapon_sort = Weapon::RIFLE; break; case KEY_WEAPONS3: weapon_sort = Weapon::THROW; break; case KEY_WEAPONS4: weapon_sort = Weapon::SPECIAL; break; case KEY_WEAPONS5: weapon_sort = Weapon::DUEL; break; case KEY_WEAPONS6: weapon_sort = Weapon::MOVE; break; case KEY_WEAPONS7: weapon_sort = Weapon::TOOL; break; default: // Key not supported return; } if (weapon_sort != Weapon::INVALID && ActiveTeam().GetWeapon().CanChangeWeapon()) { Weapon::Weapon_type weapon; WeaponsList * weapons_list = Game::GetInstance()->GetWeaponsList(); if (weapons_list->GetWeaponBySort(weapon_sort, weapon)) { ASSERT (weapon >= Weapon::FIRST && weapon <= Weapon::LAST); ActionHandler::GetInstance()->NewAction(new Action(Action::ACTION_PLAYER_CHANGE_WEAPON, weapon)); } } } }
int VideoDriver_SDL::PollEvent() { SDL_Event ev; if (!SDL_CALL SDL_PollEvent(&ev)) return -2; switch (ev.type) { case SDL_MOUSEMOTION: if (_cursor.UpdateCursorPosition(ev.motion.x, ev.motion.y, true)) { SDL_CALL SDL_WarpMouse(_cursor.pos.x, _cursor.pos.y); } HandleMouseEvents(); break; case SDL_MOUSEBUTTONDOWN: if (_rightclick_emulate && SDL_CALL SDL_GetModState() & KMOD_CTRL) { ev.button.button = SDL_BUTTON_RIGHT; } switch (ev.button.button) { case SDL_BUTTON_LEFT: _left_button_down = true; break; case SDL_BUTTON_RIGHT: _right_button_down = true; _right_button_clicked = true; break; case SDL_BUTTON_WHEELUP: _cursor.wheel--; break; case SDL_BUTTON_WHEELDOWN: _cursor.wheel++; break; default: break; } HandleMouseEvents(); break; case SDL_MOUSEBUTTONUP: if (_rightclick_emulate) { _right_button_down = false; _left_button_down = false; _left_button_clicked = false; } else if (ev.button.button == SDL_BUTTON_LEFT) { _left_button_down = false; _left_button_clicked = false; } else if (ev.button.button == SDL_BUTTON_RIGHT) { _right_button_down = false; } HandleMouseEvents(); break; case SDL_ACTIVEEVENT: if (!(ev.active.state & SDL_APPMOUSEFOCUS)) break; if (ev.active.gain) { // mouse entered the window, enable cursor _cursor.in_window = true; } else { UndrawMouseCursor(); // mouse left the window, undraw cursor _cursor.in_window = false; } break; case SDL_QUIT: HandleExitGameRequest(); break; case SDL_KEYDOWN: // Toggle full-screen on ALT + ENTER/F if ((ev.key.keysym.mod & (KMOD_ALT | KMOD_META)) && (ev.key.keysym.sym == SDLK_RETURN || ev.key.keysym.sym == SDLK_f)) { ToggleFullScreen(!_fullscreen); } else { WChar character; uint keycode = ConvertSdlKeyIntoMy(&ev.key.keysym, &character); HandleKeypress(keycode, character); } break; case SDL_VIDEORESIZE: { int w = max(ev.resize.w, 64); int h = max(ev.resize.h, 64); CreateMainSurface(w, h); break; } case SDL_VIDEOEXPOSE: { /* Force a redraw of the entire screen. Note * that SDL 1.2 seems to do this automatically * in most cases, but 1.3 / 2.0 does not. */ _num_dirty_rects = MAX_DIRTY_RECTS + 1; break; } } return -1; }
/** * \brief Returns whether the SHIFT key is currently down. * * There is no distinction between the right and left SHIFT keys in this function. * * \return true if the SHIFT key is currently down */ bool InputEvent::is_shift_down() { SDL_Keymod mod = SDL_GetModState(); return mod & KMOD_SHIFT; }
void VideoDriver_SDL::MainLoop() { uint32 cur_ticks = SDL_CALL SDL_GetTicks(); uint32 last_cur_ticks = cur_ticks; uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK; uint32 mod; int numkeys; Uint8 *keys; CheckPaletteAnim(); if (_draw_threaded) { /* Initialise the mutex first, because that's the thing we *need* * directly in the newly created thread. */ _draw_mutex = ThreadMutex::New(); if (_draw_mutex == NULL) { _draw_threaded = false; } else { _draw_mutex->BeginCritical(); _draw_continue = true; _draw_threaded = ThreadObject::New(&DrawSurfaceToScreenThread, NULL, &_draw_thread, "ottd:draw-sdl"); /* Free the mutex if we won't be able to use it. */ if (!_draw_threaded) { _draw_mutex->EndCritical(); delete _draw_mutex; _draw_mutex = NULL; } else { /* Wait till the draw mutex has started itself. */ _draw_mutex->WaitForSignal(); } } } DEBUG(driver, 1, "SDL: using %sthreads", _draw_threaded ? "" : "no "); for (;;) { uint32 prev_cur_ticks = cur_ticks; // to check for wrapping InteractiveRandom(); // randomness while (PollEvent() == -1) {} if (_exit_game) break; mod = SDL_CALL SDL_GetModState(); #if SDL_VERSION_ATLEAST(1, 3, 0) keys = SDL_CALL SDL_GetKeyboardState(&numkeys); #else keys = SDL_CALL SDL_GetKeyState(&numkeys); #endif #if defined(_DEBUG) if (_shift_pressed) #else /* Speedup when pressing tab, except when using ALT+TAB * to switch to another application */ #if SDL_VERSION_ATLEAST(1, 3, 0) if (keys[SDL_SCANCODE_TAB] && (mod & KMOD_ALT) == 0) #else if (keys[SDLK_TAB] && (mod & KMOD_ALT) == 0) #endif /* SDL_VERSION_ATLEAST(1, 3, 0) */ #endif /* defined(_DEBUG) */ { if (!_networking && _game_mode != GM_MENU) _fast_forward |= 2; } else if (_fast_forward & 2) { _fast_forward = 0; } cur_ticks = SDL_CALL SDL_GetTicks(); if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode) || cur_ticks < prev_cur_ticks) { _realtime_tick += cur_ticks - last_cur_ticks; last_cur_ticks = cur_ticks; next_tick = cur_ticks + MILLISECONDS_PER_TICK; bool old_ctrl_pressed = _ctrl_pressed; _ctrl_pressed = !!(mod & KMOD_CTRL); _shift_pressed = !!(mod & KMOD_SHIFT); /* determine which directional keys are down */ _dirkeys = #if SDL_VERSION_ATLEAST(1, 3, 0) (keys[SDL_SCANCODE_LEFT] ? 1 : 0) | (keys[SDL_SCANCODE_UP] ? 2 : 0) | (keys[SDL_SCANCODE_RIGHT] ? 4 : 0) | (keys[SDL_SCANCODE_DOWN] ? 8 : 0); #else (keys[SDLK_LEFT] ? 1 : 0) | (keys[SDLK_UP] ? 2 : 0) | (keys[SDLK_RIGHT] ? 4 : 0) | (keys[SDLK_DOWN] ? 8 : 0); #endif if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged(); /* The gameloop is the part that can run asynchronously. The rest * except sleeping can't. */ if (_draw_mutex != NULL) _draw_mutex->EndCritical(); GameLoop(); if (_draw_mutex != NULL) _draw_mutex->BeginCritical(); UpdateWindows(); _local_palette = _cur_palette; } else { /* Release the thread while sleeping */ if (_draw_mutex != NULL) _draw_mutex->EndCritical(); CSleep(1); if (_draw_mutex != NULL) _draw_mutex->BeginCritical(); NetworkDrawChatMessage(); DrawMouseCursor(); } /* End of the critical part. */ if (_draw_mutex != NULL && !HasModalProgress()) { _draw_mutex->SendSignal(); } else { /* Oh, we didn't have threads, then just draw unthreaded */ CheckPaletteAnim(); DrawSurfaceToScreen(); } } if (_draw_mutex != NULL) { _draw_continue = false; /* Sending signal if there is no thread blocked * is very valid and results in noop */ _draw_mutex->SendSignal(); _draw_mutex->EndCritical(); _draw_thread->Join(); delete _draw_mutex; delete _draw_thread; _draw_mutex = NULL; _draw_thread = NULL; } }
/** * \brief Returns whether the ALT key is currently down. * * There is no distinction between the right and left ALT keys in this function. * * \return true if the ALT key is currently down */ bool InputEvent::is_alt_down() { SDL_Keymod mod = SDL_GetModState(); return mod & KMOD_ALT; }
u16 LocalEvent::KeyMod(void) const { return SDL_GetModState(); }
/** * \brief Returns whether the num lock key is currently active. * \return \c true if the num lock key is currently active. */ bool InputEvent::is_num_lock_on() { SDL_Keymod mod = SDL_GetModState(); return mod & KMOD_NUM; }
int Projectile::calculateTrajectory(double accuracy, Position originVoxel) { Tile *targetTile = _save->getTile(_action.target); BattleUnit *bu = _action.actor; int test = _save->getTileEngine()->calculateLine(originVoxel, _targetVoxel, false, &_trajectory, bu); if (test != V_EMPTY && !_trajectory.empty() && _action.actor->getFaction() == FACTION_PLAYER && _action.autoShotCounter == 1 && ((SDL_GetModState() & KMOD_CTRL) == 0 || !Options::forceFire) && _save->getBattleGame()->getPanicHandled() && _action.type != BA_LAUNCH) { Position hitPos = Position(_trajectory.at(0).x/16, _trajectory.at(0).y/16, _trajectory.at(0).z/24); if (test == V_UNIT && _save->getTile(hitPos) && _save->getTile(hitPos)->getUnit() == 0) //no unit? must be lower { hitPos = Position(hitPos.x, hitPos.y, hitPos.z-1); } if (hitPos != _action.target && _action.result == "") { if (test == V_NORTHWALL) { if (hitPos.y - 1 != _action.target.y) { _trajectory.clear(); return V_EMPTY; } } else if (test == V_WESTWALL) { if (hitPos.x - 1 != _action.target.x) { _trajectory.clear(); return V_EMPTY; } } else if (test == V_UNIT) { BattleUnit *hitUnit = _save->getTile(hitPos)->getUnit(); BattleUnit *targetUnit = targetTile->getUnit(); if (hitUnit != targetUnit) { _trajectory.clear(); return V_EMPTY; } } else { _trajectory.clear(); return V_EMPTY; } } } _trajectory.clear(); bool extendLine = true; // even guided missiles drift, but how much is based on // the shooter's faction, rather than accuracy. if (_action.type == BA_LAUNCH) { if (_action.actor->getFaction() == FACTION_PLAYER) { accuracy = 0.60; } else { accuracy = 0.55; } extendLine = _action.waypoints.size() <= 1; } // apply some accuracy modifiers. // This will results in a new target voxel applyAccuracy(originVoxel, &_targetVoxel, accuracy, false, targetTile, extendLine); // finally do a line calculation and store this trajectory. return _save->getTileEngine()->calculateLine(originVoxel, _targetVoxel, true, &_trajectory, bu); }
// // I_GetEvent // void I_GetEvent (void) { event_t event; event_t mouseevent = {ev_mouse, 0, 0, 0}; static int mbuttons = 0; int sendmouseevent = 0; SDL_Event ev; if (!havefocus) I_PauseMouse(); else { I_ResumeMouse(); } while(SDL_PollEvent(&ev)) { event.data1 = event.data2 = event.data3 = 0; switch(ev.type) { case SDL_QUIT: AddCommandString("menu_quit"); break; // Resizable window mode resolutions case SDL_VIDEORESIZE: { if (!mousegrabbed && !vid_fullscreen) { char Command[64]; snprintf(Command, sizeof(Command), "vid_setmode %d %d", ev.resize.w, ev.resize.h); AddCommandString(Command); vid_defwidth.Set((float)ev.resize.w); vid_defheight.Set((float)ev.resize.h); } } break; case SDL_ACTIVEEVENT: // need to update our focus state UpdateFocus(); break; case SDL_KEYDOWN: event.type = ev_keydown; event.data1 = ev.key.keysym.sym; if(event.data1 >= SDLK_KP0 && event.data1 <= SDLK_KP9) event.data2 = event.data3 = '0' + (event.data1 - SDLK_KP0); else if(event.data1 == SDLK_KP_PERIOD) event.data2 = event.data3 = '.'; else if(event.data1 == SDLK_KP_DIVIDE) event.data2 = event.data3 = '/'; else if(event.data1 == SDLK_KP_ENTER) event.data2 = event.data3 = '\r'; else if ( (ev.key.keysym.unicode & 0xFF80) == 0 ) event.data2 = event.data3 = ev.key.keysym.unicode; else event.data2 = event.data3 = 0; #ifdef _XBOX // Fix for ENTER key on Xbox if(event.data1 == SDLK_RETURN) event.data2 = event.data3 = '\r'; #endif #ifdef WIN32 //HeX9109: Alt+F4 for cheats! Thanks Spleen if(event.data1 == SDLK_F4 && SDL_GetModState() & (KMOD_LALT | KMOD_RALT)) AddCommandString("menu_quit"); // SoM: Ignore the tab portion of alt-tab presses if(event.data1 == SDLK_TAB && SDL_GetModState() & (KMOD_LALT | KMOD_RALT)) event.data1 = event.data2 = event.data3 = 0; else #endif D_PostEvent(&event); break; case SDL_KEYUP: event.type = ev_keyup; event.data1 = ev.key.keysym.sym; if ( (ev.key.keysym.unicode & 0xFF80) == 0 ) event.data2 = event.data3 = ev.key.keysym.unicode; else event.data2 = event.data3 = 0; D_PostEvent(&event); break; case SDL_MOUSEMOTION: if(flushmouse) { flushmouse = false; break; } if (!havefocus) break; // denis - ignore artificially inserted events (see SDL_WarpMouse below) if(ev.motion.x == screen->width/2 && ev.motion.y == screen->height/2) { break; } mouseevent.data2 += AccelerateMouse(ev.motion.xrel); mouseevent.data3 -= AccelerateMouse(ev.motion.yrel); sendmouseevent = 1; break; case SDL_MOUSEBUTTONDOWN: if(nomouse || !havefocus) break; event.type = ev_keydown; if(ev.button.button == SDL_BUTTON_LEFT) { event.data1 = KEY_MOUSE1; mbuttons |= 1; } else if(ev.button.button == SDL_BUTTON_RIGHT) { event.data1 = KEY_MOUSE2; mbuttons |= 2; } else if(ev.button.button == SDL_BUTTON_MIDDLE) { event.data1 = KEY_MOUSE3; mbuttons |= 4; } else if(ev.button.button == SDL_BUTTON_WHEELUP) event.data1 = KEY_MWHEELUP; else if(ev.button.button == SDL_BUTTON_WHEELDOWN) event.data1 = KEY_MWHEELDOWN; D_PostEvent(&event); break; case SDL_MOUSEBUTTONUP: if(nomouse || !havefocus) break; event.type = ev_keyup; if(ev.button.button == SDL_BUTTON_LEFT) { event.data1 = KEY_MOUSE1; mbuttons &= ~1; } else if(ev.button.button == SDL_BUTTON_RIGHT) { event.data1 = KEY_MOUSE2; mbuttons &= ~2; } else if(ev.button.button == SDL_BUTTON_MIDDLE) { event.data1 = KEY_MOUSE3; mbuttons &= ~4; } else if(ev.button.button == SDL_BUTTON_WHEELUP) event.data1 = KEY_MWHEELUP; else if(ev.button.button == SDL_BUTTON_WHEELDOWN) event.data1 = KEY_MWHEELDOWN; D_PostEvent(&event); break; case SDL_JOYBUTTONDOWN: if(ev.jbutton.which == joy_active) { event.type = ev_keydown; event.data1 = ev.jbutton.button + KEY_JOY1; event.data2 = event.data1; D_PostEvent(&event); break; } case SDL_JOYBUTTONUP: if(ev.jbutton.which == joy_active) { event.type = ev_keyup; event.data1 = ev.jbutton.button + KEY_JOY1; event.data2 = event.data1; D_PostEvent(&event); break; } case SDL_JOYAXISMOTION: if(ev.jaxis.which == joy_active) { event.type = ev_joystick; event.data1 = 0; event.data2 = ev.jaxis.axis; if( (ev.jaxis.value < JOY_DEADZONE) && (ev.jaxis.value > -JOY_DEADZONE) ) event.data3 = 0; else event.data3 = ev.jaxis.value; D_PostEvent(&event); break; } case SDL_JOYHATMOTION: if(ev.jhat.which == joy_active) { // Each of these need to be tested because more than one can be pressed and a // unique event is needed for each if(ev.jhat.value & SDL_HAT_UP) RegisterJoystickEvent(&ev, SDL_HAT_UP); if(ev.jhat.value & SDL_HAT_RIGHT) RegisterJoystickEvent(&ev, SDL_HAT_RIGHT); if(ev.jhat.value & SDL_HAT_DOWN) RegisterJoystickEvent(&ev, SDL_HAT_DOWN); if(ev.jhat.value & SDL_HAT_LEFT) RegisterJoystickEvent(&ev, SDL_HAT_LEFT); break; } }; } if(!nomouse) { if(sendmouseevent) { mouseevent.data1 = mbuttons; D_PostEvent(&mouseevent); } if(mousegrabbed && screen) { SDL_WarpMouse(screen->width/ 2, screen->height / 2); } } if(use_joystick) UpdateJoystickEvents(); }
int Application::exec() { bool done = false; while (!done) { SDL_Event e; if (SDL_WaitEvent(&e)) { switch (e.type) { case SDL_WINDOWEVENT: { Widget *w = widgetByWindowId(e.window.windowID); switch (e.window.event) { case SDL_WINDOWEVENT_SHOWN: std::cout << "Window " << e.window.windowID << " shown" << std::endl; break; case SDL_WINDOWEVENT_HIDDEN: std::cout << "Window " << e.window.windowID << " hidden" << std::endl; break; case SDL_WINDOWEVENT_EXPOSED: { needUpdateWithoutRedraw_ = w; break; } case SDL_WINDOWEVENT_MOVED: break; case SDL_WINDOWEVENT_RESIZED: { w->resize(e.window.data1, e.window.data2); #if __APPLE__==1 SDL_RenderPresent(w->renderer_); // hack for MacOS X #endif break; } case SDL_WINDOWEVENT_MINIMIZED: std::cout << "Window " << e.window.windowID << " minimized" << std::endl; break; case SDL_WINDOWEVENT_MAXIMIZED: std::cout << "Window " << e.window.windowID << " maximized" << std::endl; break; case SDL_WINDOWEVENT_RESTORED: std::cout << "Window " << e.window.windowID << " restored" << std::endl; break; case SDL_WINDOWEVENT_ENTER: std::cout << "Mouse entered window " << e.window.windowID << std::endl; break; case SDL_WINDOWEVENT_LEAVE: std::cout << "Mouse left window " << e.window.windowID << std::endl; break; case SDL_WINDOWEVENT_FOCUS_GAINED: std::cout << "Window " << e.window.windowID << " gained keyboard focus" << std::endl; break; case SDL_WINDOWEVENT_FOCUS_LOST: std::cout << "Window " << e.window.windowID << " lost keyboard focus" << std::endl; break; case SDL_WINDOWEVENT_CLOSE: std::cout << "Window " << e.window.windowID << " closed" << std::endl; break; default: std::cout << "Window " << e.window.windowID << " got unknown event " << static_cast<int>(e.window.event) << std::endl; break; } break; } case SDL_KEYDOWN: { KeyEvent ke { static_cast<KeyEvent::Key>(e.key.keysym.sym), SDL_GetModState(), static_cast<bool>(e.key.repeat) }; auto w = focusWidget(); if (!w) w = widgetByWindowId(e.key.windowID); else if (w->ancestor() != widgetByWindowId(e.key.windowID)) { std::cerr << "Unknown windowID " << e.key.windowID << std::endl; break; } while (w) { if (w->keyPressEvent(ke)) break; w = w->parent(); } break; } case SDL_KEYUP: { KeyEvent ke { static_cast<KeyEvent::Key>(e.key.keysym.sym), SDL_GetModState(), static_cast<bool>(e.key.repeat) }; auto w = focusWidget(); if (!w) w = widgetByWindowId(e.key.windowID); else if (w->ancestor() != widgetByWindowId(e.key.windowID)) { std::cerr << "Unknown windowID " << e.key.windowID << std::endl; break; } while (w) { if (w->keyReleaseEvent(ke)) break; w = w->parent(); } break; } case SDL_TEXTINPUT: { TextInputEvent tie { toUtf16(e.text.text) }; auto w = focusWidget(); if (!w) w = widgetByWindowId(e.key.windowID); else if (w->ancestor() != widgetByWindowId(e.key.windowID)) { std::cerr << "Unknown windowID " << e.key.windowID << std::endl; break; } while (w) { if (w->textInputEvent(tie)) break; w = w->parent(); } break; } case SDL_QUIT: done = true; break; } } const auto isEmpty = (SDL_PeepEvents(&e, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) == 0); if (isEmpty || SDL_GetTicks() > lastUpdate_ + 1000 / 60) { auto x = SDL_GetTicks(); for (auto w: widgetList_) if (w->needRepaint()) { PaintEvent e; w->internalPaint(e); } if (needUpdateWithoutRedraw_) { needUpdateWithoutRedraw_->updateWithoutRedraw(); needUpdateWithoutRedraw_ = nullptr; } lastUpdate_ = SDL_GetTicks(); std::cout << "Update time: " << lastUpdate_ - x << " " << (lastUpdate_ - x > 0 ? 1000 / (lastUpdate_ - x) : 999)<< "fps" << std::endl; } for (auto obj: deletingObjects_) delete obj; deletingObjects_.clear(); } return 0; }