From c6111a32590980877127c6e4e94e406e952acf12 Mon Sep 17 00:00:00 2001
From: Toad King <toadking@toadking.com>
Date: Wed, 28 Nov 2012 19:54:49 -0500
Subject: [PATCH] [CONSOLE] Make separate timers for holding scroll and
 menu/exit button delay.

Fixes issues with exit/menu button combo not working on GC controllers occasionally
---
 360/frontend-xdk/menu.cpp     | 6 +++---
 console/rarch_console_video.h | 6 +++---
 console/rmenu/rmenu.c         | 8 ++++----
 general.h                     | 7 +------
 gfx/gl.c                      | 2 +-
 gx/frontend/main.c            | 8 ++++----
 gx/gx_input.c                 | 6 +++---
 ps3/ps3_input.c               | 6 +++---
 xdk/xdk_xinput_input.c        | 6 +++---
 9 files changed, 25 insertions(+), 30 deletions(-)

diff --git a/360/frontend-xdk/menu.cpp b/360/frontend-xdk/menu.cpp
index 2368947c62..5ebf49bb66 100644
--- a/360/frontend-xdk/menu.cpp
+++ b/360/frontend-xdk/menu.cpp
@@ -1169,7 +1169,7 @@ void menu_loop(void)
 
       g_extern.console.rmenu.state.rmenu.enable = !((state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) 
             && (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) && (g_extern.console.emulator_initialized)
-            && IS_TIMER_EXPIRED(device_ptr));
+            && IS_TIMER_EXPIRED(device_ptr, 0));
 
       g_extern.console.rmenu.mode = g_extern.console.rmenu.state.rmenu.enable ? MODE_MENU : MODE_EMULATION;
 
@@ -1181,7 +1181,7 @@ void menu_loop(void)
                {
                uint64_t action = (1 << RMENU_DEVICE_NAV_A);
                browser_update(browser, action, rarch_console_get_rom_ext());
-               SET_TIMER_EXPIRATION(d3d, 15);
+               SET_TIMER_EXPIRATION(d3d, 0, 15);
                }
                */
          case INPUT_LOOP_MENU:
@@ -1201,7 +1201,7 @@ void menu_loop(void)
 
       if(g_extern.console.rmenu.mode == MODE_EMULATION && !g_extern.console.screen.state.frame_advance.enable)
       {
-         SET_TIMER_EXPIRATION(device_ptr, 30);
+         SET_TIMER_EXPIRATION(device_ptr, 0, 30);
       }
 
       const char *message = msg_queue_pull(g_extern.msg_queue);
diff --git a/console/rarch_console_video.h b/console/rarch_console_video.h
index 946fa5baa3..e65efdbd52 100644
--- a/console/rarch_console_video.h
+++ b/console/rarch_console_video.h
@@ -17,9 +17,9 @@
 #ifndef RARCH_CONSOLE_VIDEO_H__
 #define RARCH_CONSOLE_VIDEO_H__
 
-#define IS_TIMER_NOT_EXPIRED(handle) ((handle)->frame_count < g_extern.console.timers.general_timer.expire_frame)
-#define IS_TIMER_EXPIRED(handle) 	(!(IS_TIMER_NOT_EXPIRED((handle))))
-#define SET_TIMER_EXPIRATION(handle, value) (g_extern.console.timers.general_timer.expire_frame = (handle)->frame_count + (value))
+#define IS_TIMER_NOT_EXPIRED(handle, index)        ((handle)->frame_count < g_extern.console.general_timers[(index)].expire_frame)
+#define IS_TIMER_EXPIRED(handle, index)            (!(IS_TIMER_NOT_EXPIRED((handle), (index))))
+#define SET_TIMER_EXPIRATION(handle, index, value) (g_extern.console.general_timers[(index)].expire_frame = (handle)->frame_count + (value))
 
 #define MIN_SCALING_FACTOR (1.0f)
 
diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c
index e611a48d1f..fa6dffe24d 100644
--- a/console/rmenu/rmenu.c
+++ b/console/rmenu/rmenu.c
@@ -2260,10 +2260,10 @@ void menu_loop(void)
          if(!first_held)
          {
             first_held = true;
-            SET_TIMER_EXPIRATION(device_ptr, 7);
+            SET_TIMER_EXPIRATION(device_ptr, 1, 7);
          }
 
-         if(IS_TIMER_EXPIRED(device_ptr))
+         if(IS_TIMER_EXPIRED(device_ptr, 1))
          {
             first_held = false;
             trig_state = input_state; //second input frame set as current frame
@@ -2344,7 +2344,7 @@ void menu_loop(void)
 
       old_state = input_state_first_frame;
 
-      if(IS_TIMER_EXPIRED(device_ptr))
+      if(IS_TIMER_EXPIRED(device_ptr, 0))
       {
          // if we want to force goto the emulation loop, skip this
          if(g_extern.console.rmenu.mode != MODE_EMULATION)
@@ -2372,7 +2372,7 @@ void menu_loop(void)
       // press and holding L3 + R3 in the emulation loop (lasts for 30 frame ticks)
       if(g_extern.console.rmenu.mode == MODE_EMULATION && !g_extern.console.screen.state.frame_advance.enable)
       {
-         SET_TIMER_EXPIRATION(device_ptr, 30);
+         SET_TIMER_EXPIRATION(device_ptr, 0, 30);
       }
 
       const char * message = msg_queue_pull(g_extern.msg_queue);
diff --git a/general.h b/general.h
index 86e0cffb1e..b0ac1f168b 100644
--- a/general.h
+++ b/general.h
@@ -474,6 +474,7 @@ struct global
       bool block_config_read;
       bool initialize_rarch_enable;
       unsigned emulator_initialized;
+      rarch_frame_count_t general_timers[2];
 
       struct
       {
@@ -498,12 +499,6 @@ struct global
          } state;
       } rmenu;
 
-      struct
-      {
-         rarch_frame_count_t control_timer;
-         rarch_frame_count_t general_timer;
-      } timers;
-
       struct
       {
          bool enable;
diff --git a/gfx/gl.c b/gfx/gl.c
index 1d5abce597..3ddc44358c 100644
--- a/gfx/gl.c
+++ b/gfx/gl.c
@@ -1749,7 +1749,7 @@ static void gl_restart(void)
 
 #ifdef RARCH_CONSOLE
    gl->block_swap = should_block_swap;
-   SET_TIMER_EXPIRATION(gl, 30);
+   SET_TIMER_EXPIRATION(gl, 0, 30);
 #endif
 }
 
diff --git a/gx/frontend/main.c b/gx/frontend/main.c
index fe80aad746..5f47fb99a2 100644
--- a/gx/frontend/main.c
+++ b/gx/frontend/main.c
@@ -304,10 +304,10 @@ static void menu_loop(void)
          if(!first_held)
          {
             first_held = true;
-            SET_TIMER_EXPIRATION(gx, (initial_held) ? 15 : 7);
+            SET_TIMER_EXPIRATION(gx, 1, (initial_held) ? 15 : 7);
          }
 
-         if(IS_TIMER_EXPIRED(gx))
+         if(IS_TIMER_EXPIRED(gx, 1))
          {
             first_held = false;
             trigger_state = input_state; //second input frame set as current frame
@@ -357,7 +357,7 @@ static void menu_loop(void)
       bool goto_menu_key_pressed = (trigger_state & (1 << GX_DEVICE_NAV_MENU));
       bool quit_key_pressed = (trigger_state & (1 << GX_DEVICE_NAV_QUIT));
 
-      if(IS_TIMER_EXPIRED(gx))
+      if(IS_TIMER_EXPIRED(gx, 0))
       {
          // if we want to force goto the emulation loop, skip this
          if(g_extern.console.rmenu.mode != MODE_EMULATION)
@@ -380,7 +380,7 @@ static void menu_loop(void)
       // press and holding QUIT in the emulation loop (lasts for 30 frame ticks)
       if(g_extern.console.rmenu.mode == MODE_EMULATION)
       {
-         SET_TIMER_EXPIRATION(gx, 30);
+         SET_TIMER_EXPIRATION(gx, 0, 30);
       }
 
    }while(g_extern.console.rmenu.state.rmenu.enable);
diff --git a/gx/gx_input.c b/gx/gx_input.c
index 107e68bb32..e96c9c2732 100644
--- a/gx/gx_input.c
+++ b/gx/gx_input.c
@@ -465,7 +465,7 @@ static bool gx_input_key_pressed(void *data, int key)
    switch (key)
    {
       case RARCH_QUIT_KEY:
-      if(IS_TIMER_EXPIRED(gx))
+      if(IS_TIMER_EXPIRED(gx, 0))
       {
          uint64_t goto_menu_pressed = pad_state[0] & (GX_WIIMOTE_HOME
 #ifdef HW_RVL
@@ -474,13 +474,13 @@ static bool gx_input_key_pressed(void *data, int key)
  );
          uint64_t quit_rarch = pad_state[0] & GX_QUIT_KEY;
          bool retval = false;
-         g_extern.console.rmenu.state.rmenu.enable = ((quit_rarch || goto_menu_pressed) && IS_TIMER_EXPIRED(gx));
+         g_extern.console.rmenu.state.rmenu.enable = ((quit_rarch || goto_menu_pressed) && IS_TIMER_EXPIRED(gx, 0));
 
          if(g_extern.console.rmenu.state.rmenu.enable)
          {
             g_extern.console.rmenu.mode = MODE_MENU;
             g_extern.console.rmenu.state.ingame_menu.enable = true;
-            SET_TIMER_EXPIRATION(gx, 30);
+            SET_TIMER_EXPIRATION(gx, 0, 30);
          }
 
          if(quit_rarch)
diff --git a/ps3/ps3_input.c b/ps3/ps3_input.c
index 89064ea76d..a0f2ac645b 100644
--- a/ps3/ps3_input.c
+++ b/ps3/ps3_input.c
@@ -454,18 +454,18 @@ static bool ps3_input_key_pressed(void *data, int key)
          return (state[0] & PS3_GAMEPAD_RSTICK_UP_MASK) && !(state[0] & PS3_GAMEPAD_R2);
       case RARCH_QUIT_KEY:
 #ifdef HAVE_OPENGL
-         if(IS_TIMER_EXPIRED(gl))
+         if(IS_TIMER_EXPIRED(gl, 0))
          {
             uint32_t r3_pressed = state[0] & PS3_GAMEPAD_R3;
             uint32_t l3_pressed = state[0] & PS3_GAMEPAD_L3;
             bool retval = false;
-            g_extern.console.rmenu.state.rmenu.enable = (r3_pressed && l3_pressed && IS_TIMER_EXPIRED(gl));
+            g_extern.console.rmenu.state.rmenu.enable = (r3_pressed && l3_pressed && IS_TIMER_EXPIRED(gl, 0));
             g_extern.console.rmenu.state.ingame_menu.enable = r3_pressed && !l3_pressed;
 
             if(g_extern.console.rmenu.state.rmenu.enable || (g_extern.console.rmenu.state.ingame_menu.enable && !g_extern.console.rmenu.state.rmenu.enable))
             {
                g_extern.console.rmenu.mode = MODE_MENU;
-               SET_TIMER_EXPIRATION(gl, 30);
+               SET_TIMER_EXPIRATION(gl, 0, 30);
                retval = g_extern.console.rmenu.state.rmenu.enable;
             }
 
diff --git a/xdk/xdk_xinput_input.c b/xdk/xdk_xinput_input.c
index 478bf2bcc0..e267d78baa 100644
--- a/xdk/xdk_xinput_input.c
+++ b/xdk/xdk_xinput_input.c
@@ -338,18 +338,18 @@ static bool xinput_input_key_pressed(void *data, int key)
       case RARCH_REWIND:
          return ((state[0] & XINPUT1_GAMEPAD_RSTICK_UP_MASK) && !(state[0] & XINPUT1_GAMEPAD_RIGHT_TRIGGER));
       case RARCH_QUIT_KEY:
-         if(IS_TIMER_EXPIRED(d3d))
+         if(IS_TIMER_EXPIRED(d3d, 0))
          {
             uint32_t left_thumb_pressed = (state[0] & (1 << RETRO_DEVICE_ID_JOYPAD_L3));
             uint32_t right_thumb_pressed = (state[0] & (1 << RETRO_DEVICE_ID_JOYPAD_R3));
 
-            g_extern.console.rmenu.state.rmenu.enable = right_thumb_pressed && left_thumb_pressed && IS_TIMER_EXPIRED(d3d);
+            g_extern.console.rmenu.state.rmenu.enable = right_thumb_pressed && left_thumb_pressed && IS_TIMER_EXPIRED(d3d, 0);
             g_extern.console.rmenu.state.ingame_menu.enable = right_thumb_pressed && !left_thumb_pressed;
             
             if(g_extern.console.rmenu.state.rmenu.enable || (g_extern.console.rmenu.state.ingame_menu.enable && !g_extern.console.rmenu.state.rmenu.enable))
             {
                g_extern.console.rmenu.mode = MODE_MENU;
-               SET_TIMER_EXPIRATION(d3d, 30);
+               SET_TIMER_EXPIRATION(d3d, 0, 30);
                retval = g_extern.console.rmenu.state.rmenu.enable;
             }
             retval = g_extern.console.rmenu.state.ingame_menu.enable ? g_extern.console.rmenu.state.ingame_menu.enable : g_extern.console.rmenu.state.rmenu.enable;