moved flag for mouse click events from level to game structure
[rocksndiamonds.git] / src / events.c
index 085dd9ff4c3c3fccf9a875a2e878de96ced3e0b5..2f5589fee711f23ae7cc8014138db14759f1e28b 100644 (file)
@@ -39,7 +39,6 @@ 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;
 
 
@@ -95,6 +94,25 @@ static int FilterEvents(const Event *event)
     ((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);
+
+      cursor_mode_last = CURSOR_DEFAULT;
+    }
+  }
+
   // non-motion events are directly passed to event handler functions
   if (event->type != EVENT_MOTIONNOTIFY)
     return 1;
@@ -112,20 +130,6 @@ static int FilterEvents(const Event *event)
   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 &&
-       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;
-  }
-
   // skip mouse motion events without pressed button outside level editor
   if (button_status == MB_RELEASED &&
       game_status != GAME_MODE_EDITOR && game_status != GAME_MODE_PLAYING)
@@ -323,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))
@@ -466,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
@@ -628,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())
@@ -665,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);
 
@@ -1282,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;
 
@@ -1355,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;
 
@@ -1371,6 +1375,8 @@ 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_events && valid_mouse_event)
+      SetPlayerMouseAction(mx, my, button);
   }
 }
 
@@ -1456,6 +1462,9 @@ 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
 
@@ -1687,7 +1696,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))
@@ -1910,6 +1927,13 @@ static void HandleKeysSpecial(Key key)
       {
        CopyClipboardToBrush();
       }
+      else if (letter == 'z')  // undo or redo last operation
+      {
+       if (GetKeyModState() & KMOD_Shift)
+         RedoLevelEditorOperation();
+       else
+         UndoLevelEditorOperation();
+      }
     }
   }