diff --git a/Themes/_fallback/Scripts/04 pause_menu_helper.lua b/Themes/_fallback/Scripts/04 pause_menu_helper.lua new file mode 100644 index 0000000000..b8f4c25e25 --- /dev/null +++ b/Themes/_fallback/Scripts/04 pause_menu_helper.lua @@ -0,0 +1,92 @@ +local config_data= { + pause_buttons= {Start= false, Select= true, Back= true}, + pause_tap_time= 1, pause_debounce_time= .1, +} +local pause_press_times= {} +local last_press_buttons= {} +local down_status= {} +local enabled_players= {} +local screen_gameplay= false +local pause_actor= false + +local function other_button_down(pn, button) + for other_pn, status in pairs(down_status) do + for other_button, down in pairs(status) do + if down and (other_button ~= button or other_pn ~= pn) then + return true + end + end + end + return false +end + +local function detect_lr_press(pn) + return down_status[pn].MenuLeft and down_status[pn].MenuRight +end + +local function input(event) + local pn= event.PlayerNumber + if not enabled_players[pn] then return end + local button= event.button + local game_button= event.GameButton + if not game_button then return end + if event.type == "InputEventType_Release" then + down_status[pn][button]= false + return + end + down_status[pn][button]= true + if button ~= last_press_buttons[pn] then + last_press_buttons[pn]= nil + end + if screen_gameplay:IsPaused() then return end + if event.type ~= "InputEventType_FirstPress" then return end + if detect_lr_press(pn) then + MESSAGEMAN:Broadcast("PlayerHitPause", {pn= pn, button= button}) + return + end + if not config_data.pause_buttons[button] then + MESSAGEMAN:Broadcast("HidePausePrompt") + return + end + if last_press_buttons[pn] == button and pause_press_times[pn] + and not other_button_down(pn, button) then + local time_diff= GetTimeSinceStart() - pause_press_times[pn] + if time_diff > config_data.pause_debounce_time then + if time_diff < config_data.pause_tap_time then + if GAMESTATE:GetCurMusicSeconds() > GAMESTATE:GetCurrentSong():GetFirstSecond() then + gameplay_pause_count= gameplay_pause_count + 1 + end + last_press_buttons[pn]= nil + pause_press_times[pn]= nil + MESSAGEMAN:Broadcast("PlayerHitPause", {pn= pn, button= button}) + return true + else + pause_press_times[pn]= GetTimeSinceStart() + last_press_buttons[pn]= button + MESSAGEMAN:Broadcast("ShowPausePrompt", {pn= pn, button= button}) + end + end + else + pause_press_times[pn]= GetTimeSinceStart() + last_press_buttons[pn]= button + MESSAGEMAN:Broadcast("ShowPausePrompt", {pn= pn, button= button}) + end +end + +function pause_controller_actor() + gameplay_pause_count= 0 + return Def.Actor{ + OnCommand= function(self) + screen_gameplay= SCREENMAN:GetTopScreen() + if screen_gameplay:GetName() == "ScreenGameplaySyncMachine" then + return + end + screen_gameplay:AddInputCallback(input) + enabled_players= GAMESTATE:GetEnabledPlayers() + for i, pn in ipairs(enabled_players) do + enabled_players[pn]= true + down_status[pn]= {} + end + end, + } +end diff --git a/Themes/default/Graphics/pause_menu.lua b/Themes/default/Graphics/pause_menu.lua index b641ff258f..6da3f7b44f 100644 --- a/Themes/default/Graphics/pause_menu.lua +++ b/Themes/default/Graphics/pause_menu.lua @@ -1,4 +1,3 @@ -gameplay_pause_count= 0 course_stopped_by_pause_menu= false local prompt_text= { @@ -8,10 +7,6 @@ local prompt_text= { } local prompt_actor= false -local pause_buttons= {Start= false, Select= true, Back= true} -local pause_double_tap_time= 1 -local tap_debounce_time= .1 -local pause_press_times= {} local screen_gameplay= false local menu_items= {[PLAYER_1]= {}, [PLAYER_2]= {}} local menu_frames= {} @@ -162,21 +157,6 @@ menu_actions.MenuRight= menu_actions.Right menu_actions.MenuUp= menu_actions.Up menu_actions.MenuDown= menu_actions.Down -local down_status= {} - -local function other_button_down(button) - for other_button, down in pairs(down_status) do - if down and other_button ~= button then - return true - end - end - return false -end - -local function detect_lr_press() - return down_status.MenuLeft and down_status.MenuRight -end - local function pause_and_show(pn) gameplay_pause_count= gameplay_pause_count + 1 screen_gameplay:PauseGame(true) @@ -202,12 +182,7 @@ local function input(event) if not enabled_players[pn] then return end local button= event.GameButton if not button then return end - if event.type == "InputEventType_Release" then - down_status[event.button]= false - return - end - down_status[event.button]= true - if screen_gameplay:GetName() == "ScreenGameplaySyncMachine" then return end + if event.type == "InputEventType_Release" then return end local is_paused= screen_gameplay:IsPaused() if is_paused then if menu_is_showing[pn] then @@ -216,44 +191,30 @@ local function input(event) return end else - if pause_buttons[button] or detect_lr_press() then + if button == "Start" then show_menu(pn) return end end - else - button= event.button - if event.type ~= "InputEventType_FirstPress" then return end - if detect_lr_press() then - pause_and_show(pn) - elseif pause_buttons[button] then - if GAMESTATE:GetCoinMode() == "CoinMode_Pay" then return end - if pause_press_times[pn] and not other_button_down(button) then - local time_since_press= GetTimeSinceStart() - pause_press_times[pn] - if time_since_press > tap_debounce_time then - if time_since_press <= pause_double_tap_time then - pause_and_show(pn) - else - show_prompt(button) - pause_press_times[pn]= GetTimeSinceStart() - end - end - else - show_prompt(button) - pause_press_times[pn]= GetTimeSinceStart() - end - else - hide_prompt() - pause_press_times[pn]= nil - end end end local frame= Def.ActorFrame{ OnCommand= function(self) screen_gameplay= SCREENMAN:GetTopScreen() + if screen_gameplay:GetName() == "ScreenGameplaySyncMachine" then return end screen_gameplay:AddInputCallback(input) end, + PlayerHitPauseMessageCommand= function(self, params) + pause_and_show(params.pn) + end, + ShowPausePromptMessageCommand= function(self, params) + show_prompt(params.button) + end, + HidePausePromptMessageCommand= function(self) + hide_prompt() + end, + pause_controller_actor(), Def.BitmapText{ Font= "Common Normal", InitCommand= function(self) prompt_actor= self @@ -261,6 +222,7 @@ local frame= Def.ActorFrame{ end, ShowCommand= function(self, param) self:stoptweening():settext(param.text):accelerate(.25):diffusealpha(1) + :sleep(1):queuecommand("Hide") end, HideCommand= function(self) self:stoptweening():decelerate(.25):diffusealpha(0) diff --git a/Themes/default/metrics.ini b/Themes/default/metrics.ini index 9a38121582..0a93b9cc94 100644 --- a/Themes/default/metrics.ini +++ b/Themes/default/metrics.ini @@ -1424,7 +1424,6 @@ HelpOnCommand=visible,false # 05 # C [ScreenGameplay] -UsePauseMenuInsteadOfGiveUp=true # SongMeterDisplayX=SCREEN_CENTER_X SongMeterDisplayY=SCREEN_TOP+50 @@ -1611,6 +1610,7 @@ ActiveAttackListP2OffCommand= # # Disable the normal start and select button actions to enable a custom pause # menu +UsePauseMenuInsteadOfGiveUp=true UnpauseWithStart=false StopCourseEarly=check_stop_course_early()