X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fevents.c;h=6054f74097006ca8d9b0140424f867b71b173da2;hp=9966905b6286a496ee0a97868b2990105d6dc98a;hb=f93b88d332d24f32bbd5030cf8dec20fdb8d5ea9;hpb=c38790fcee093efb156366bb4a02dbde55085ca4 diff --git a/src/events.c b/src/events.c index 9966905b..6054f740 100644 --- a/src/events.c +++ b/src/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,6 @@ static int FilterEvents(const Event *event) { ((MotionEvent *)event)->x -= video.screen_xoffset; ((MotionEvent *)event)->y -= video.screen_yoffset; - - gfx.mouse_x = ((MotionEvent *)event)->x; - gfx.mouse_y = ((MotionEvent *)event)->y; } // non-motion events are directly passed to event handler functions @@ -87,6 +102,15 @@ static int FilterEvents(const Event *event) cursor_inside_playfield = (motion->x >= SX && motion->x < SX + SXSIZE && motion->y >= SY && motion->y < SY + SYSIZE); + // 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; + // do no reset mouse cursor before all pending events have been processed if (gfx.cursor_mode == cursor_mode_last && ((game_status == GAME_MODE_TITLE && @@ -167,6 +191,11 @@ boolean NextValidEvent(Event *event) return FALSE; } +void StopProcessingEvents(void) +{ + stop_processing_events = TRUE; +} + static void HandleEvents(void) { Event event; @@ -175,6 +204,8 @@ static void HandleEvents(void) ResetDelayCounter(&event_frame_delay); + stop_processing_events = FALSE; + while (NextValidEvent(&event)) { switch (event.type) @@ -230,6 +261,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; } } @@ -430,6 +465,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 @@ -571,6 +632,8 @@ void HandleWindowEvent(WindowEvent *event) if (game_status == GAME_MODE_SETUP) RedrawSetupScreenAfterFullscreenToggle(); + UpdateMousePosition(); + SetWindowTitle(); } } @@ -627,50 +690,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); @@ -1607,6 +1637,15 @@ 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; } @@ -1640,7 +1679,11 @@ 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; #endif if (HandleGlobalAnimClicks(mx, my, button, FALSE)) @@ -1863,6 +1906,13 @@ static void HandleKeysSpecial(Key key) { CopyClipboardToBrush(); } + else if (letter == 'z') // undo or redo last operation + { + if (GetKeyModState() & KMOD_Shift) + RedoLevelEditorOperation(); + else + UndoLevelEditorOperation(); + } } } @@ -2111,6 +2161,8 @@ void HandleKey(Key key, int key_status) if (game_status == GAME_MODE_SETUP) RedrawSetupScreenAfterFullscreenToggle(); + UpdateMousePosition(); + // set flag to ignore repeated "key pressed" events ignore_repeated_key = TRUE; @@ -2142,12 +2194,17 @@ void HandleKey(Key key, int key_status) 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