X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fevents.c;h=3a303fa5e5fc20155b1e179401e3e79b9ed881e6;hb=3107a4558d89655d39413a1fa3da127d4e8b2c1e;hp=e4f3329e32ab740df7fd18246735a97d19b7c4f2;hpb=7373d54bd6896193f7f20ed0ff148dacee9d084e;p=rocksndiamonds.git diff --git a/src/events.c b/src/events.c index e4f3329e..3a303fa5 100644 --- a/src/events.c +++ b/src/events.c @@ -4,7 +4,7 @@ // (c) 1995-2014 by Artsoft Entertainment // Holger Schemel // info@artsoft.org -// http://www.artsoft.org/ +// https://www.artsoft.org/ // ---------------------------------------------------------------------------- // events.c // ============================================================================ @@ -39,7 +39,7 @@ static int cursor_mode_last = CURSOR_DEFAULT; static unsigned int special_cursor_delay = 0; static unsigned int special_cursor_delay_value = 1000; -static boolean virtual_button_pressed = FALSE; +static boolean stop_processing_events = FALSE; // forward declarations for internal use @@ -47,6 +47,24 @@ static void HandleNoEvent(void); static void HandleEventActions(void); +// event filter to set mouse x/y position (for pointer class global animations) +// (this is especially required to ensure smooth global animation mouse pointer +// movement when the screen is updated without handling events; this can happen +// when drawing door/envelope request animations, for example) + +int FilterMouseMotionEvents(void *userdata, Event *event) +{ + if (event->type == EVENT_MOTIONNOTIFY) + { + int mouse_x = ((MotionEvent *)event)->x; + int mouse_y = ((MotionEvent *)event)->y; + + UpdateRawMousePosition(mouse_x, mouse_y); + } + + return 1; +} + // event filter especially needed for SDL event filtering due to // delay problems with lots of mouse motion events when mouse button // not pressed (X11 can handle this with 'PointerMotionHintMask') @@ -74,9 +92,25 @@ static int FilterEvents(const Event *event) { ((MotionEvent *)event)->x -= video.screen_xoffset; ((MotionEvent *)event)->y -= video.screen_yoffset; + } + + if (event->type == EVENT_BUTTONPRESS || + event->type == EVENT_BUTTONRELEASE || + event->type == EVENT_MOTIONNOTIFY) + { + // do not reset mouse cursor before all pending events have been processed + if (gfx.cursor_mode == cursor_mode_last && + ((game_status == GAME_MODE_TITLE && + gfx.cursor_mode == CURSOR_NONE) || + (game_status == GAME_MODE_PLAYING && + gfx.cursor_mode == CURSOR_PLAYFIELD))) + { + SetMouseCursor(CURSOR_DEFAULT); + + DelayReached(&special_cursor_delay, 0); - gfx.mouse_x = ((MotionEvent *)event)->x; - gfx.mouse_y = ((MotionEvent *)event)->y; + cursor_mode_last = CURSOR_DEFAULT; + } } // non-motion events are directly passed to event handler functions @@ -87,19 +121,14 @@ static int FilterEvents(const Event *event) cursor_inside_playfield = (motion->x >= SX && motion->x < SX + SXSIZE && motion->y >= SY && motion->y < SY + SYSIZE); - // do no reset mouse cursor before all pending events have been processed - if (gfx.cursor_mode == cursor_mode_last && - ((game_status == GAME_MODE_TITLE && - gfx.cursor_mode == CURSOR_NONE) || - (game_status == GAME_MODE_PLAYING && - gfx.cursor_mode == CURSOR_PLAYFIELD))) - { - SetMouseCursor(CURSOR_DEFAULT); - - DelayReached(&special_cursor_delay, 0); - - cursor_mode_last = CURSOR_DEFAULT; - } + // set correct mouse x/y position (for pointer class global animations) + // (this is required in rare cases where the mouse x/y position calculated + // from raw values (to apply logical screen size scaling corrections) does + // not match the final mouse event x/y position -- this may happen because + // the SDL renderer's viewport position is internally represented as float, + // but only accessible as integer, which may lead to rounding errors) + gfx.mouse_x = motion->x; + gfx.mouse_y = motion->y; // skip mouse motion events without pressed button outside level editor if (button_status == MB_RELEASED && @@ -167,6 +196,11 @@ boolean NextValidEvent(Event *event) return FALSE; } +void StopProcessingEvents(void) +{ + stop_processing_events = TRUE; +} + static void HandleEvents(void) { Event event; @@ -175,6 +209,8 @@ static void HandleEvents(void) ResetDelayCounter(&event_frame_delay); + stop_processing_events = FALSE; + while (NextValidEvent(&event)) { switch (event.type) @@ -218,6 +254,10 @@ static void HandleEvents(void) HandleKeyEvent((KeyEvent *) &event); break; + case EVENT_USER: + HandleUserEvent((UserEvent *) &event); + break; + default: HandleOtherEvents(&event); break; @@ -226,6 +266,10 @@ static void HandleEvents(void) // do not handle events for longer than standard frame delay period if (DelayReached(&event_frame_delay, event_frame_delay_value)) break; + + // do not handle any further events if triggered by a special flag + if (stop_processing_events) + break; } } @@ -233,10 +277,6 @@ void HandleOtherEvents(Event *event) { switch (event->type) { - case EVENT_CLIENTMESSAGE: - HandleClientMessageEvent((ClientMessageEvent *) event); - break; - case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONUP: // for any game controller button event, disable overlay buttons @@ -261,6 +301,10 @@ void HandleOtherEvents(Event *event) HandleDropEvent(event); break; + case EVENT_QUIT: + CloseAllAndExit(0); + break; + default: break; } @@ -283,6 +327,10 @@ static void HandleMouseCursor(void) { // when playing, display a special mouse pointer inside the playfield + // display normal pointer if mouse pressed + if (button_status != MB_RELEASED) + DelayReached(&special_cursor_delay, 0); + if (gfx.cursor_mode != CURSOR_PLAYFIELD && cursor_inside_playfield && DelayReached(&special_cursor_delay, special_cursor_delay_value)) @@ -416,7 +464,7 @@ static void SetPlayerMouseAction(int mx, int my, int button) local_player->mouse_action.ly = ly; local_player->mouse_action.button = button; - if (tape.recording && tape.pausing && tape.use_mouse) + if (tape.recording && tape.pausing && tape.use_mouse_actions) { // un-pause a paused game only if mouse button was newly pressed down if (new_button) @@ -426,6 +474,32 @@ static void SetPlayerMouseAction(int mx, int my, int button) SetTileCursorXY(lx, ly); } +static Key GetKeyFromGridButton(int grid_button) +{ + return (grid_button == CHAR_GRID_BUTTON_LEFT ? setup.input[0].key.left : + grid_button == CHAR_GRID_BUTTON_RIGHT ? setup.input[0].key.right : + grid_button == CHAR_GRID_BUTTON_UP ? setup.input[0].key.up : + grid_button == CHAR_GRID_BUTTON_DOWN ? setup.input[0].key.down : + grid_button == CHAR_GRID_BUTTON_SNAP ? setup.input[0].key.snap : + grid_button == CHAR_GRID_BUTTON_DROP ? setup.input[0].key.drop : + KSYM_UNDEFINED); +} + +#if defined(PLATFORM_ANDROID) +static boolean CheckVirtualButtonPressed(int mx, int my, int button) +{ + float touch_x = (float)(mx + video.screen_xoffset) / video.screen_width; + float touch_y = (float)(my + video.screen_yoffset) / video.screen_height; + int x = touch_x * overlay.grid_xsize; + int y = touch_y * overlay.grid_ysize; + int grid_button = overlay.grid_button[x][y]; + Key key = GetKeyFromGridButton(grid_button); + int key_status = (button == MB_RELEASED ? KEY_RELEASED : KEY_PRESSED); + + return (key_status == KEY_PRESSED && key != KSYM_UNDEFINED); +} +#endif + void HandleButtonEvent(ButtonEvent *event) { #if DEBUG_EVENTS_BUTTON @@ -567,6 +641,8 @@ void HandleWindowEvent(WindowEvent *event) if (game_status == GAME_MODE_SETUP) RedrawSetupScreenAfterFullscreenToggle(); + UpdateMousePosition(); + SetWindowTitle(); } } @@ -586,6 +662,7 @@ void HandleWindowEvent(WindowEvent *event) video.display_height = new_display_height; SDLSetScreenProperties(); + SetGadgetsPosition_OverlayTouchButtons(); // check if screen orientation has changed (should always be true here) if (nr != GRID_ACTIVE_NR()) @@ -623,50 +700,17 @@ static struct static void HandleFingerEvent_VirtualButtons(FingerEvent *event) { -#if 1 int x = event->x * overlay.grid_xsize; int y = event->y * overlay.grid_ysize; int grid_button = overlay.grid_button[x][y]; int grid_button_action = GET_ACTION_FROM_GRID_BUTTON(grid_button); - Key key = (grid_button == CHAR_GRID_BUTTON_LEFT ? setup.input[0].key.left : - grid_button == CHAR_GRID_BUTTON_RIGHT ? setup.input[0].key.right : - grid_button == CHAR_GRID_BUTTON_UP ? setup.input[0].key.up : - grid_button == CHAR_GRID_BUTTON_DOWN ? setup.input[0].key.down : - grid_button == CHAR_GRID_BUTTON_SNAP ? setup.input[0].key.snap : - grid_button == CHAR_GRID_BUTTON_DROP ? setup.input[0].key.drop : - KSYM_UNDEFINED); -#else - float ypos = 1.0 - 1.0 / 3.0 * video.display_width / video.display_height; - float event_x = (event->x); - float event_y = (event->y - ypos) / (1 - ypos); - Key key = (event_x > 0 && event_x < 1.0 / 6.0 && - event_y > 2.0 / 3.0 && event_y < 1 ? - setup.input[0].key.snap : - event_x > 1.0 / 6.0 && event_x < 1.0 / 3.0 && - event_y > 2.0 / 3.0 && event_y < 1 ? - setup.input[0].key.drop : - event_x > 7.0 / 9.0 && event_x < 8.0 / 9.0 && - event_y > 0 && event_y < 1.0 / 3.0 ? - setup.input[0].key.up : - event_x > 6.0 / 9.0 && event_x < 7.0 / 9.0 && - event_y > 1.0 / 3.0 && event_y < 2.0 / 3.0 ? - setup.input[0].key.left : - event_x > 8.0 / 9.0 && event_x < 1 && - event_y > 1.0 / 3.0 && event_y < 2.0 / 3.0 ? - setup.input[0].key.right : - event_x > 7.0 / 9.0 && event_x < 8.0 / 9.0 && - event_y > 2.0 / 3.0 && event_y < 1 ? - setup.input[0].key.down : - KSYM_UNDEFINED); -#endif + Key key = GetKeyFromGridButton(grid_button); int key_status = (event->type == EVENT_FINGERRELEASE ? KEY_RELEASED : KEY_PRESSED); char *key_status_name = (key_status == KEY_RELEASED ? "KEY_RELEASED" : "KEY_PRESSED"); int i; - virtual_button_pressed = (key_status == KEY_PRESSED && key != KSYM_UNDEFINED); - // for any touch input event, enable overlay buttons (if activated) SetOverlayEnabled(TRUE); @@ -1240,7 +1284,7 @@ static void HandleButtonOrFinger_FollowFinger(int mx, int my, int button) int last_move_dir = (ABS(dx) > ABS(dy) ? MV_VERTICAL : MV_HORIZONTAL); if (level.game_engine_type == GAME_ENGINE_TYPE_EM) - level.native_em_level->ply[0]->last_move_dir = last_move_dir; + game_em.ply[0]->last_move_dir = last_move_dir; else local_player->last_move_dir = last_move_dir; @@ -1313,6 +1357,8 @@ static void HandleButtonOrFinger_FollowFinger(int mx, int my, int button) static void HandleButtonOrFinger(int mx, int my, int button) { + boolean valid_mouse_event = (mx != -1 && my != -1 && button != -1); + if (game_status != GAME_MODE_PLAYING) return; @@ -1329,16 +1375,23 @@ static void HandleButtonOrFinger(int mx, int my, int button) { if (strEqual(setup.touch.control_type, TOUCH_CONTROL_FOLLOW_FINGER)) HandleButtonOrFinger_FollowFinger(mx, my, button); + else if (game.use_mouse_actions && valid_mouse_event) + SetPlayerMouseAction(mx, my, button); } } -static boolean checkTextInputKeyModState(void) +static boolean checkTextInputKey(Key key) { // when playing, only handle raw key events and ignore text input if (game_status == GAME_MODE_PLAYING) return FALSE; - return ((GetKeyModState() & KMOD_TextInput) != KMOD_None); + // ignore raw keys as text input when not in text input mode + if (KSYM_RAW(key) && !textinput_status) + return FALSE; + + // else handle all printable keys as text input + return KSYM_PRINTABLE(key); } void HandleTextEvent(TextEvent *event) @@ -1356,16 +1409,12 @@ void HandleTextEvent(TextEvent *event) GetKeyModState()); #endif -#if !defined(HAS_SCREEN_KEYBOARD) - // non-mobile devices: only handle key input with modifier keys pressed here - // (every other key input is handled directly as physical key input event) - if (!checkTextInputKeyModState()) - return; -#endif - - // process text input as "classic" (with uppercase etc.) key input event - HandleKey(key, KEY_PRESSED); - HandleKey(key, KEY_RELEASED); + if (checkTextInputKey(key)) + { + // process printable keys (with uppercase etc.) in text input mode + HandleKey(key, KEY_PRESSED); + HandleKey(key, KEY_RELEASED); + } } void HandlePauseResumeEvent(PauseResumeEvent *event) @@ -1414,22 +1463,19 @@ void HandleKeyEvent(KeyEvent *event) { // for any other "real" key event, disable virtual buttons SetOverlayEnabled(FALSE); + + // for any other "real" key event, disable overlay touch buttons + runtime.uses_touch_device = FALSE; } #endif HandleKeyModState(keymod, key_status); - // only handle raw key input without text modifier keys pressed - if (!checkTextInputKeyModState()) + // process all keys if not in text input mode or if non-printable keys + if (!checkTextInputKey(key)) HandleKey(key, key_status); } -void HandleClientMessageEvent(ClientMessageEvent *event) -{ - if (CheckCloseWindowEvent(event)) - CloseAllAndExit(0); -} - static int HandleDropFileEvent(char *filename) { Error(ERR_DEBUG, "DROP FILE EVENT: '%s'", filename); @@ -1605,6 +1651,24 @@ void HandleDropEvent(Event *event) SDL_free(event->drop.file); } +void HandleUserEvent(UserEvent *event) +{ + switch (event->code) + { + case USEREVENT_ANIM_DELAY_ACTION: + case USEREVENT_ANIM_EVENT_ACTION: + // execute action functions until matching action was found + if (DoKeysymAction(event->value1) || + DoGadgetAction(event->value1) || + DoScreenAction(event->value1)) + return; + break; + + default: + break; + } +} + void HandleButton(int mx, int my, int button, int button_nr) { static int old_mx = 0, old_my = 0; @@ -1633,7 +1697,15 @@ void HandleButton(int mx, int my, int button, int button_nr) level.game_engine_type == GAME_ENGINE_TYPE_MM || strEqual(setup.touch.control_type, TOUCH_CONTROL_FOLLOW_FINGER) || (strEqual(setup.touch.control_type, TOUCH_CONTROL_VIRTUAL_BUTTONS) && - !virtual_button_pressed)); + !CheckVirtualButtonPressed(mx, my, button))); + + // always recognize potentially releasing already pressed gadgets + if (button == MB_RELEASED) + handle_gadgets = TRUE; + + // always recognize pressing or releasing overlay touch buttons + if (CheckPosition_OverlayTouchButtons(mx, my, button) && !motion_status) + handle_gadgets = TRUE; #endif if (HandleGlobalAnimClicks(mx, my, button, FALSE)) @@ -1712,17 +1784,6 @@ void HandleButton(int mx, int my, int button, int button_nr) } } -static boolean is_string_suffix(char *string, char *suffix) -{ - int string_len = strlen(string); - int suffix_len = strlen(suffix); - - if (suffix_len > string_len) - return FALSE; - - return (strEqual(&string[string_len - suffix_len], suffix)); -} - #define MAX_CHEAT_INPUT_LEN 32 static void HandleKeysSpecial(Key key) @@ -1752,73 +1813,69 @@ static void HandleKeysSpecial(Key key) if (game_status == GAME_MODE_MAIN) { - if (is_string_suffix(cheat_input, ":insert-solution-tape") || - is_string_suffix(cheat_input, ":ist")) + if (strSuffix(cheat_input, ":insert-solution-tape") || + strSuffix(cheat_input, ":ist")) { InsertSolutionTape(); } - else if (is_string_suffix(cheat_input, ":play-solution-tape") || - is_string_suffix(cheat_input, ":pst")) + else if (strSuffix(cheat_input, ":play-solution-tape") || + strSuffix(cheat_input, ":pst")) { PlaySolutionTape(); } - else if (is_string_suffix(cheat_input, ":reload-graphics") || - is_string_suffix(cheat_input, ":rg")) + else if (strSuffix(cheat_input, ":reload-graphics") || + strSuffix(cheat_input, ":rg")) { ReloadCustomArtwork(1 << ARTWORK_TYPE_GRAPHICS); DrawMainMenu(); } - else if (is_string_suffix(cheat_input, ":reload-sounds") || - is_string_suffix(cheat_input, ":rs")) + else if (strSuffix(cheat_input, ":reload-sounds") || + strSuffix(cheat_input, ":rs")) { ReloadCustomArtwork(1 << ARTWORK_TYPE_SOUNDS); DrawMainMenu(); } - else if (is_string_suffix(cheat_input, ":reload-music") || - is_string_suffix(cheat_input, ":rm")) + else if (strSuffix(cheat_input, ":reload-music") || + strSuffix(cheat_input, ":rm")) { ReloadCustomArtwork(1 << ARTWORK_TYPE_MUSIC); DrawMainMenu(); } - else if (is_string_suffix(cheat_input, ":reload-artwork") || - is_string_suffix(cheat_input, ":ra")) + else if (strSuffix(cheat_input, ":reload-artwork") || + strSuffix(cheat_input, ":ra")) { ReloadCustomArtwork(1 << ARTWORK_TYPE_GRAPHICS | 1 << ARTWORK_TYPE_SOUNDS | 1 << ARTWORK_TYPE_MUSIC); DrawMainMenu(); } - else if (is_string_suffix(cheat_input, ":dump-level") || - is_string_suffix(cheat_input, ":dl")) + else if (strSuffix(cheat_input, ":dump-level") || + strSuffix(cheat_input, ":dl")) { DumpLevel(&level); } - else if (is_string_suffix(cheat_input, ":dump-tape") || - is_string_suffix(cheat_input, ":dt")) + else if (strSuffix(cheat_input, ":dump-tape") || + strSuffix(cheat_input, ":dt")) { DumpTape(&tape); } - else if (is_string_suffix(cheat_input, ":fix-tape") || - is_string_suffix(cheat_input, ":ft")) + else if (strSuffix(cheat_input, ":undo-tape") || + strSuffix(cheat_input, ":ut")) { - /* fix single-player tapes that contain player input for more than one - player (due to a bug in 3.3.1.2 and earlier versions), which results - in playing levels with more than one player in multi-player mode, - even though the tape was originally recorded in single-player mode */ - - // remove player input actions for all players but the first one - for (i = 1; i < MAX_PLAYERS; i++) - tape.player_participates[i] = FALSE; - - tape.changed = TRUE; + UndoTape(); } - else if (is_string_suffix(cheat_input, ":save-native-level") || - is_string_suffix(cheat_input, ":snl")) + else if (strSuffix(cheat_input, ":fix-tape") || + strSuffix(cheat_input, ":ft")) + { + FixTape_ForceSinglePlayer(); + } + else if (strSuffix(cheat_input, ":save-native-level") || + strSuffix(cheat_input, ":snl")) { SaveNativeLevel(&level); } - else if (is_string_suffix(cheat_input, ":frames-per-second") || - is_string_suffix(cheat_input, ":fps")) + else if (strSuffix(cheat_input, ":frames-per-second") || + strSuffix(cheat_input, ":fps")) { global.show_frames_per_second = !global.show_frames_per_second; } @@ -1826,18 +1883,18 @@ static void HandleKeysSpecial(Key key) else if (game_status == GAME_MODE_PLAYING) { #ifdef DEBUG - if (is_string_suffix(cheat_input, ".q")) + if (strSuffix(cheat_input, ".q")) DEBUG_SetMaximumDynamite(); #endif } else if (game_status == GAME_MODE_EDITOR) { - if (is_string_suffix(cheat_input, ":dump-brush") || - is_string_suffix(cheat_input, ":DB")) + if (strSuffix(cheat_input, ":dump-brush") || + strSuffix(cheat_input, ":DB")) { DumpBrush(); } - else if (is_string_suffix(cheat_input, ":DDB")) + else if (strSuffix(cheat_input, ":DDB")) { DumpBrush_Small(); } @@ -1856,13 +1913,20 @@ static void HandleKeysSpecial(Key key) { CopyClipboardToBrush(); } + else if (letter == 'z') // undo or redo last operation + { + if (GetKeyModState() & KMOD_Shift) + RedoLevelEditorOperation(); + else + UndoLevelEditorOperation(); + } } } // special key shortcuts for all game modes - if (is_string_suffix(cheat_input, ":dump-event-actions") || - is_string_suffix(cheat_input, ":dea") || - is_string_suffix(cheat_input, ":DEA")) + if (strSuffix(cheat_input, ":dump-event-actions") || + strSuffix(cheat_input, ":dea") || + strSuffix(cheat_input, ":DEA")) { DumpGadgetIdentifiers(); DumpScreenIdentifiers(); @@ -2020,43 +2084,46 @@ void HandleKey(Key key, int key_status) if (stored_player[pnr].snap_action) stored_player[pnr].action |= JOY_BUTTON_SNAP; - if (tape.single_step && tape.recording && tape.pausing && !tape.use_mouse) + if (tape.recording && tape.pausing && tape.use_key_actions) { - if (key_status == KEY_PRESSED && key_action & KEY_MOTION) + if (tape.single_step) { - TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); + if (key_status == KEY_PRESSED && key_action & KEY_MOTION) + { + TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); - // if snap key already pressed, keep pause mode when releasing - if (stored_player[pnr].action & KEY_BUTTON_SNAP) - has_snapped[pnr] = TRUE; - } - else if (key_status == KEY_PRESSED && key_action & KEY_BUTTON_DROP) - { - TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); + // if snap key already pressed, keep pause mode when releasing + if (stored_player[pnr].action & KEY_BUTTON_SNAP) + has_snapped[pnr] = TRUE; + } + else if (key_status == KEY_PRESSED && key_action & KEY_BUTTON_DROP) + { + TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); - if (level.game_engine_type == GAME_ENGINE_TYPE_SP && - getRedDiskReleaseFlag_SP() == 0) + if (level.game_engine_type == GAME_ENGINE_TYPE_SP && + getRedDiskReleaseFlag_SP() == 0) + { + // add a single inactive frame before dropping starts + stored_player[pnr].action &= ~KEY_BUTTON_DROP; + stored_player[pnr].force_dropping = TRUE; + } + } + else if (key_status == KEY_RELEASED && key_action & KEY_BUTTON_SNAP) { - // add a single inactive frame before dropping starts - stored_player[pnr].action &= ~KEY_BUTTON_DROP; - stored_player[pnr].force_dropping = TRUE; + // if snap key was pressed without direction, leave pause mode + if (!has_snapped[pnr]) + TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); + + has_snapped[pnr] = FALSE; } } - else if (key_status == KEY_RELEASED && key_action & KEY_BUTTON_SNAP) + else { - // if snap key was pressed without direction, leave pause mode - if (!has_snapped[pnr]) - TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); - - has_snapped[pnr] = FALSE; + // prevent key release events from un-pausing a paused game + if (key_status == KEY_PRESSED && key_action & KEY_ACTION) + TapeTogglePause(TAPE_TOGGLE_MANUAL); } } - else if (tape.recording && tape.pausing && !tape.use_mouse) - { - // prevent key release events from un-pausing a paused game - if (key_status == KEY_PRESSED && key_action & KEY_ACTION) - TapeTogglePause(TAPE_TOGGLE_MANUAL); - } // for MM style levels, handle in-game keyboard input in HandleJoystick() if (level.game_engine_type == GAME_ENGINE_TYPE_MM) @@ -2099,11 +2166,13 @@ void HandleKey(Key key, int key_status) { setup.fullscreen = !setup.fullscreen; - ToggleFullscreenOrChangeWindowScalingIfNeeded(); + ToggleFullscreenIfNeeded(); if (game_status == GAME_MODE_SETUP) RedrawSetupScreenAfterFullscreenToggle(); + UpdateMousePosition(); + // set flag to ignore repeated "key pressed" events ignore_repeated_key = TRUE; @@ -2130,17 +2199,22 @@ void HandleKey(Key key, int key_status) else if (setup.window_scaling_percent > MAX_WINDOW_SCALING_PERCENT) setup.window_scaling_percent = MAX_WINDOW_SCALING_PERCENT; - ToggleFullscreenOrChangeWindowScalingIfNeeded(); + ChangeWindowScalingIfNeeded(); if (game_status == GAME_MODE_SETUP) RedrawSetupScreenAfterFullscreenToggle(); + UpdateMousePosition(); + return; } - if (HandleGlobalAnimClicks(-1, -1, (key == KSYM_space || - key == KSYM_Return || - key == KSYM_Escape), TRUE)) + // some key events are handled like clicks for global animations + boolean click = (key == KSYM_space || + key == KSYM_Return || + key == KSYM_Escape); + + if (click && HandleGlobalAnimClicks(-1, -1, MB_LEFTBUTTON, TRUE)) { // do not handle this key event anymore if (key != KSYM_Escape) // always allow ESC key to be handled @@ -2545,15 +2619,18 @@ void HandleJoystick(void) return; } - if (tape.single_step && tape.recording && tape.pausing && !tape.use_mouse) - { - if (joystick & JOY_ACTION) - TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); - } - else if (tape.recording && tape.pausing && !tape.use_mouse) + if (tape.recording && tape.pausing && tape.use_key_actions) { - if (joystick & JOY_ACTION) - TapeTogglePause(TAPE_TOGGLE_MANUAL); + if (tape.single_step) + { + if (joystick & JOY_ACTION) + TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); + } + else + { + if (joystick & JOY_ACTION) + TapeTogglePause(TAPE_TOGGLE_MANUAL); + } } if (level.game_engine_type == GAME_ENGINE_TYPE_MM)