cleanup of game mode handling
[rocksndiamonds.git] / src / events.c
index 14e7df862d68b129d81effc376322c081cf9aad4..e82d3667b42958144a01fdce30e24a70a3b8cec9 100644 (file)
 
 #define        DEBUG_EVENTS            0
 
+#define DEBUG_EVENTS_BUTTON    (DEBUG_EVENTS   * 0)
+#define DEBUG_EVENTS_MOTION    (DEBUG_EVENTS   * 0)
+#define DEBUG_EVENTS_WINDOW    (DEBUG_EVENTS   * 0)
+#define DEBUG_EVENTS_FINGER    (DEBUG_EVENTS   * 0)
+#define DEBUG_EVENTS_TEXT      (DEBUG_EVENTS   * 1)
+#define DEBUG_EVENTS_KEY       (DEBUG_EVENTS   * 1)
 
-static boolean cursor_inside_playfield = FALSE;
-static boolean playfield_cursor_set = FALSE;
-static unsigned int playfield_cursor_delay = 0;
 
+static boolean cursor_inside_playfield = FALSE;
+static int cursor_mode_last = CURSOR_DEFAULT;
+static unsigned int special_cursor_delay = 0;
+static unsigned int special_cursor_delay_value = 1000;
 
 /* event filter especially needed for SDL event filtering due to
    delay problems with lots of mouse motion events when mouse button
@@ -57,11 +64,18 @@ static int FilterEventsExt(const Event *event)
   cursor_inside_playfield = (motion->x >= SX && motion->x < SX + SXSIZE &&
                             motion->y >= SY && motion->y < SY + SYSIZE);
 
-  if (game_status == GAME_MODE_PLAYING && playfield_cursor_set)
+  /* 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);
-    playfield_cursor_set = FALSE;
-    DelayReached(&playfield_cursor_delay, 0);
+
+    DelayReached(&special_cursor_delay, 0);
+
+    cursor_mode_last = CURSOR_DEFAULT;
   }
 
   /* skip mouse motion events without pressed button outside level editor */
@@ -94,9 +108,8 @@ boolean SkipPressedMouseMotionEvent(const Event *event)
   if (event->type != EVENT_MOTIONNOTIFY)
     return FALSE;
 
-  /* only skip motion events with pressed button outside level editor */
-  if (button_status == MB_RELEASED ||
-      game_status == GAME_MODE_EDITOR || game_status == GAME_MODE_PLAYING)
+  /* only skip motion events with pressed button outside the game */
+  if (button_status == MB_RELEASED || game_status == GAME_MODE_PLAYING)
     return FALSE;
 
   if (PendingEvent())
@@ -117,7 +130,7 @@ boolean SkipPressedMouseMotionEvent(const Event *event)
    when using SDL with properly installed event filter, this function can be
    replaced with a simple "NextEvent()" call, but it doesn't hurt either */
 
-static boolean NextValidEvent(Event *event)
+boolean NextValidEvent(Event *event)
 {
   while (PendingEvent())
   {
@@ -195,21 +208,35 @@ void EventLoop(void)
     }
     else
     {
-      /* when playing, display a special mouse pointer inside the playfield */
-      if (game_status == GAME_MODE_PLAYING && !tape.pausing)
+      if (game_status == GAME_MODE_TITLE)
+      {
+       /* when showing title screens, hide mouse pointer (if not moved) */
+
+       if (gfx.cursor_mode != CURSOR_NONE &&
+           DelayReached(&special_cursor_delay, special_cursor_delay_value))
+       {
+         SetMouseCursor(CURSOR_NONE);
+       }
+      }
+      else if (game_status == GAME_MODE_PLAYING && (!tape.pausing ||
+                                                   tape.single_step))
       {
-       if (!playfield_cursor_set && cursor_inside_playfield &&
-           DelayReached(&playfield_cursor_delay, 1000))
+       /* when playing, display a special mouse pointer inside the playfield */
+
+       if (gfx.cursor_mode != CURSOR_PLAYFIELD &&
+           cursor_inside_playfield &&
+           DelayReached(&special_cursor_delay, special_cursor_delay_value))
        {
          SetMouseCursor(CURSOR_PLAYFIELD);
-         playfield_cursor_set = TRUE;
        }
       }
-      else if (playfield_cursor_set)
+      else if (gfx.cursor_mode != CURSOR_DEFAULT)
       {
        SetMouseCursor(CURSOR_DEFAULT);
-       playfield_cursor_set = FALSE;
       }
+
+      /* this is set after all pending events have been processed */
+      cursor_mode_last = gfx.cursor_mode;
     }
 
     /* also execute after pending events have been processed before */
@@ -224,8 +251,6 @@ void EventLoop(void)
     }
     else
     {
-      SyncDisplay();
-
       if (!PendingEvent())     /* delay only if no pending events */
        Delay(10);
     }
@@ -364,7 +389,7 @@ void HandleExposeEvent(ExposeEvent *event)
 
 void HandleButtonEvent(ButtonEvent *event)
 {
-#if DEBUG_EVENTS
+#if DEBUG_EVENTS_BUTTON
   Error(ERR_DEBUG, "BUTTON EVENT: button %d %s, x/y %d/%d\n",
        event->button,
        event->type == EVENT_BUTTONPRESS ? "pressed" : "released",
@@ -383,15 +408,12 @@ void HandleButtonEvent(ButtonEvent *event)
 
 void HandleMotionEvent(MotionEvent *event)
 {
-  if (!PointerInWindow(window))
-    return;    /* window and pointer are on different screens */
-
   if (button_status == MB_RELEASED && game_status != GAME_MODE_EDITOR)
     return;
 
   motion_status = TRUE;
 
-#if DEBUG_EVENTS
+#if DEBUG_EVENTS_MOTION
   Error(ERR_DEBUG, "MOTION EVENT: button %d moved, x/y %d/%d\n",
        button_status, event->x, event->y);
 #endif
@@ -403,7 +425,7 @@ void HandleMotionEvent(MotionEvent *event)
 
 void HandleWindowEvent(WindowEvent *event)
 {
-#if DEBUG_EVENTS
+#if DEBUG_EVENTS_WINDOW
   int subtype = event->event;
 
   char *event_name =
@@ -485,7 +507,7 @@ void HandleFingerEvent(FingerEvent *event)
   float event_x = event->x;
   float event_y = event->y;
 
-#if DEBUG_EVENTS
+#if DEBUG_EVENTS_FINGER
   Error(ERR_DEBUG, "FINGER EVENT: finger was %s, touch ID %lld, finger ID %lld, x/y %f/%f, dx/dy %f/%f, pressure %f",
        event->type == EVENT_FINGERPRESS ? "pressed" :
        event->type == EVENT_FINGERRELEASE ? "released" : "moved",
@@ -775,7 +797,7 @@ void HandleTextEvent(TextEvent *event)
   char *text = event->text;
   Key key = getKeyFromKeyName(text);
 
-#if DEBUG_EVENTS
+#if DEBUG_EVENTS_TEXT
   Error(ERR_DEBUG, "TEXT EVENT: text == '%s' [%d byte(s), '%c'/%d], resulting key == %d (%s) [%04x]",
        text,
        strlen(text),
@@ -785,11 +807,16 @@ void HandleTextEvent(TextEvent *event)
        GetKeyModState());
 #endif
 
-  // if (game_status != GAME_MODE_PLAYING && GetKeyModState() != KMOD_None)
-  /*
-  if (game_status != GAME_MODE_PLAYING &&
-      (GetKeyModState() & KMOD_TextInput) != KMOD_None)
-  */
+#if defined(PLATFORM_ANDROID)
+  if (game_status == GAME_MODE_PSEUDO_TYPENAME)
+  {
+    HandleTypeName(0, key);
+
+    return;
+  }
+#endif
+
+  // only handle key input with text modifier keys pressed
   if (checkTextInputKeyModState())
   {
     HandleKey(key, KEY_PRESSED);
@@ -818,7 +845,7 @@ void HandleKeyEvent(KeyEvent *event)
   Key key = GetEventKey(event, with_modifiers);
   Key keymod = (with_modifiers ? GetEventKey(event, FALSE) : key);
 
-#if DEBUG_EVENTS
+#if DEBUG_EVENTS_KEY
   Error(ERR_DEBUG, "KEY EVENT: key was %s, keysym.scancode == %d, keysym.sym == %d, keymod = %d, GetKeyModState() = 0x%04x, resulting key == %d (%s)",
        event->type == EVENT_KEYPRESS ? "pressed" : "released",
        event->keysym.scancode,
@@ -838,6 +865,7 @@ void HandleKeyEvent(KeyEvent *event)
   HandleKeyModState(keymod, key_status);
 
 #if defined(TARGET_SDL2)
+  // only handle raw key input without text modifier keys pressed
   if (!checkTextInputKeyModState())
     HandleKey(key, key_status);
 #else
@@ -902,12 +930,14 @@ void HandleWindowManagerEvent(Event *event)
 void HandleButton(int mx, int my, int button, int button_nr)
 {
   static int old_mx = 0, old_my = 0;
+  boolean button_hold = FALSE;
 
   if (button < 0)
   {
     mx = old_mx;
     my = old_my;
     button = -button;
+    button_hold = TRUE;
   }
   else
   {
@@ -916,6 +946,7 @@ void HandleButton(int mx, int my, int button, int button_nr)
   }
 
 #if defined(PLATFORM_ANDROID)
+  // !!! for now, do not handle gadgets when playing -- maybe fix this !!!
   if (game_status != GAME_MODE_PLAYING &&
       HandleGadgets(mx, my, button))
   {
@@ -930,6 +961,9 @@ void HandleButton(int mx, int my, int button, int button_nr)
   }
 #endif
 
+  if (button_hold && game_status == GAME_MODE_PLAYING && tape.pausing)
+    return;
+
   /* do not use scroll wheel button events for anything other than gadgets */
   if (IS_WHEEL_BUTTON(button_nr))
     return;
@@ -1020,7 +1054,7 @@ static void HandleKeysSpecial(Key key)
   cheat_input[cheat_input_len++] = letter;
   cheat_input[cheat_input_len] = '\0';
 
-#if DEBUG_EVENTS
+#if DEBUG_EVENTS_KEY
   Error(ERR_DEBUG, "SPECIAL KEY '%s' [%d]\n", cheat_input, cheat_input_len);
 #endif
 
@@ -1518,28 +1552,6 @@ void HandleKey(Key key, int key_status)
          }
          break;
 
-#if 0
-       case KSYM_s:
-         if (!global.fps_slowdown)
-         {
-           global.fps_slowdown = TRUE;
-           global.fps_slowdown_factor = 2;
-           printf("fps slowdown enabled -- display only every 2nd frame\n");
-         }
-         else if (global.fps_slowdown_factor == 2)
-         {
-           global.fps_slowdown_factor = 4;
-           printf("fps slowdown enabled -- display only every 4th frame\n");
-         }
-         else
-         {
-           global.fps_slowdown = FALSE;
-           global.fps_slowdown_factor = 1;
-           printf("fps slowdown disabled\n");
-         }
-         break;
-#endif
-
        case KSYM_v:
          printf("::: currently using game engine version %d\n",
                 game.engine_version);
@@ -1565,7 +1577,8 @@ void HandleKey(Key key, int key_status)
 
 void HandleNoEvent()
 {
-  if (button_status && game_status != GAME_MODE_PLAYING)
+  // if (button_status && game_status != GAME_MODE_PLAYING)
+  if (button_status && (game_status != GAME_MODE_PLAYING || tape.pausing))
   {
     HandleButton(0, 0, -button_status, button_status);
   }