From d3b5f5eb988bc217bb92e4ede8186ab81647ec85 Mon Sep 17 00:00:00 2001 From: Kyzentun Date: Sun, 30 Nov 2014 14:45:52 -0700 Subject: [PATCH 1/2] Added debug menu option for resetting key mappings to default. Added sanity checking requirement to ScreenMapControllers. --- .../ScreenMapControllers sanitymessage.lua | 20 ++++++ Themes/_fallback/Languages/en.ini | 6 ++ Themes/_fallback/metrics.ini | 2 + src/InputMapper.cpp | 61 +++++++++++++++++ src/InputMapper.h | 2 + src/ScreenDebugOverlay.cpp | 15 +++++ src/ScreenMapControllers.cpp | 65 +++++++++++++++++-- src/ScreenMapControllers.h | 4 ++ 8 files changed, 171 insertions(+), 4 deletions(-) create mode 100644 Themes/_fallback/Graphics/ScreenMapControllers sanitymessage.lua diff --git a/Themes/_fallback/Graphics/ScreenMapControllers sanitymessage.lua b/Themes/_fallback/Graphics/ScreenMapControllers sanitymessage.lua new file mode 100644 index 0000000000..5fd085b230 --- /dev/null +++ b/Themes/_fallback/Graphics/ScreenMapControllers sanitymessage.lua @@ -0,0 +1,20 @@ +return Def.ActorFrame{ + InitCommand=cmd(x,SCREEN_CENTER_X;y,SCREEN_CENTER_Y), + Def.Quad{ + InitCommand=cmd(zoomto,SCREEN_WIDTH,SCREEN_HEIGHT;diffuse,Color.Black;diffusealpha,0), + SetTextCommand=cmd(stoptweening;diffusealpha,1;linear,0.5;diffusealpha,0.8), + TweenOffCommand=cmd(stoptweening;linear,0.5;diffusealpha,0), + }, + Def.ActorFrame{ + Def.BitmapText{ + Font="Common Normal", + InitCommand=cmd(y,10;wrapwidthpixels,SCREEN_WIDTH-48;diffusealpha,0), + SetTextCommand= function(self, param) + self:settext(param.Text) + self:playcommand("TweenOn") + end, + TweenOnCommand=cmd(stoptweening;diffusealpha,0;sleep,0.5125;linear,0.125;diffusealpha,1), + TweenOffCommand=cmd(stoptweening;linear,0.5;diffusealpha,0), + }, + }, +} diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index c36778babb..fcdae3f725 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1340,6 +1340,7 @@ Reload=Reload Reload Overlay Screens=Reload Overlay Screens Reload Theme and Textures=Reload Theme and Textures Rendering Stats=Rendering Stats +Reset key mapping to default=Reset key mapping to default Screen Test Mode=Screen Test Mode Send Off To Screen=Send Off To Screen Send On To Screen=Send On To Screen @@ -1540,11 +1541,16 @@ Default=Default HeaderText=Map Controllers InvalidButton=That key can not be mapped. KeyName=Key Name +MenuLeftMissing=Nothing is mapped to MenuLeft +MenuRightMissing=Nothing is mapped to MenuRight NoSetListPrompt=No entries in the list to set. Add entries to the list by hitting 'm' when the cursor is on them. %s slots=%s slots +OperatorMissing=Nothing is mapped to Operator Primary=Primary SavePrompt=Save settings before exiting? Secondary=Secondary +StartMissing=Nothing is mapped to Start +VitalButtons=Buttons vital for navigating menus are not mapped: WarningHeader=WARNING! WarningText=Please ensure that you do not overwrite any important keymappings, such as:\n&MENULEFT; LEFT &MENURIGHT; RIGHT &MENUUP; UP &MENUDOWN; DOWN &START; START &BACK; BACK or &SELECT; SELECT. Do not apply keymappings that you do not know the function of or unmap important keys! diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index 8f5acd8502..6d3ba44a9f 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -2870,6 +2870,8 @@ AutoDismissWarningSecs=2.5 LinesVisible=16 # This sets how long the NoSetListPrompt will show before being sent TweenOff. AutoDismissNoSetListPromptSecs=5 +# The time to auto dismiss the sanity warning if the current mapping is not sane. +AutoDismissSanitySecs=5 # # The position of the Devices list and its On/Off commands. DevicesX=SCREEN_CENTER_X diff --git a/src/InputMapper.cpp b/src/InputMapper.cpp index b6a4e90cc9..70da57665a 100644 --- a/src/InputMapper.cpp +++ b/src/InputMapper.cpp @@ -661,6 +661,67 @@ void InputMapper::ResetMappingsToDefault() AddDefaultMappingsForCurrentGameIfUnmapped(); } +void InputMapper::CheckButtonAndAddToReason(GameButton menu, vector& full_reason, RString const& sub_reason) +{ + vector inputs; + bool exists= false; + // Only player 1 is checked because the player 2 buttons are rarely + // unmapped and do not exist on some keyboard models. -Kyz + GetInputScheme()->MenuButtonToGameInputs(menu, PLAYER_1, inputs); + if(!inputs.empty()) + { + vector device_inputs; + FOREACH(GameInput, inputs, inp) + { + for(int slot= 0; slot < NUM_GAME_TO_DEVICE_SLOTS; ++slot) + { + device_inputs.push_back(m_mappings.m_GItoDI[inp->controller][inp->button][slot]); + } + } + FOREACH(DeviceInput, device_inputs, inp) + { + if(!inp->IsValid()) + { + continue; + } + int use_count= 0; + FOREACH_ENUM(GameController, cont) + { + FOREACH_GameButtonInScheme(GetInputScheme(), gb) + { + for(int slot= 0; slot < NUM_GAME_TO_DEVICE_SLOTS; ++slot) + { + use_count+= ((*inp) == m_mappings.m_GItoDI[cont][gb][slot]); + } + } + } + // If the device input is used more than once, it's a case where a + // default mapped key was remapped to some other game button. -Kyz + if(use_count == 1) + { + exists= true; + } + } + } + if(!exists) + { + full_reason.push_back(sub_reason); + } +} + +void InputMapper::SanityCheckMappings(vector& reason) +{ + // This is just to check whether the current mapping has the minimum + // necessary to navigate the menus so the user can reach the config screen. + // For this purpose, only the following keys are needed: + // MenuLeft, MenuRight, Start, Operator + // The InputScheme handles OnlyDedicatedMenuButtons logic. -Kyz + CheckButtonAndAddToReason(GAME_BUTTON_MENULEFT, reason, "MenuLeftMissing"); + CheckButtonAndAddToReason(GAME_BUTTON_MENURIGHT, reason, "MenuRightMissing"); + CheckButtonAndAddToReason(GAME_BUTTON_START, reason, "StartMissing"); + CheckButtonAndAddToReason(GAME_BUTTON_OPERATOR, reason, "OperatorMissing"); +} + static LocalizedString CONNECTED ( "InputMapper", "Connected" ); static LocalizedString DISCONNECTED ( "InputMapper", "Disconnected" ); static LocalizedString AUTOMAPPING_ALL_JOYSTICKS ( "InputMapper", "Auto-mapping all joysticks." ); diff --git a/src/InputMapper.h b/src/InputMapper.h index 64c5c8bf34..4e35b421a0 100644 --- a/src/InputMapper.h +++ b/src/InputMapper.h @@ -152,6 +152,8 @@ public: void ReadMappingsFromDisk(); void SaveMappingsToDisk(); void ResetMappingsToDefault(); + void CheckButtonAndAddToReason(GameButton menu, vector& full_reason, RString const& sub_reason); + void SanityCheckMappings(vector& reason); void ClearAllMappings(); diff --git a/src/ScreenDebugOverlay.cpp b/src/ScreenDebugOverlay.cpp index 049448f7bf..54fc0e74c1 100644 --- a/src/ScreenDebugOverlay.cpp +++ b/src/ScreenDebugOverlay.cpp @@ -12,6 +12,7 @@ #include "ScreenGameplay.h" #include "RageSoundManager.h" #include "GameSoundManager.h" +#include "InputMapper.h" #include "RageTextureManager.h" #include "MemoryCardManager.h" #include "NoteSkinManager.h" @@ -544,6 +545,7 @@ static LocalizedString PROFILE ( "ScreenDebugOverlay", "Profile" ); static LocalizedString CLEAR_PROFILE_STATS ( "ScreenDebugOverlay", "Clear Profile Stats" ); static LocalizedString FILL_PROFILE_STATS ( "ScreenDebugOverlay", "Fill Profile Stats" ); static LocalizedString SEND_NOTES_ENDED ( "ScreenDebugOverlay", "Send Notes Ended" ); +static LocalizedString RESET_KEY_MAP ("ScreenDebugOverlay", "Reset key mapping to default"); static LocalizedString RELOAD ( "ScreenDebugOverlay", "Reload" ); static LocalizedString RESTART ( "ScreenDebugOverlay", "Restart" ); static LocalizedString SCREEN_ON ( "ScreenDebugOverlay", "Send On To Screen" ); @@ -952,6 +954,18 @@ class DebugLineSendNotesEnded : public IDebugLine } }; +class DebugLineResetKeyMapping : public IDebugLine +{ + virtual RString GetDisplayTitle() { return RESET_KEY_MAP.GetValue(); } + virtual RString GetDisplayValue() { return RString(); } + virtual bool IsEnabled() { return true; } + virtual void DoAndLog( RString &sMessageOut ) + { + INPUTMAPPER->ResetMappingsToDefault(); + IDebugLine::DoAndLog( sMessageOut ); + } +}; + class DebugLineReloadCurrentScreen : public IDebugLine { virtual RString GetDisplayTitle() { return RELOAD.GetValue(); } @@ -1272,6 +1286,7 @@ DECLARE_ONE( DebugLineVisualDelayDown ); DECLARE_ONE( DebugLineVisualDelayUp ); DECLARE_ONE( DebugLineForceCrash ); DECLARE_ONE( DebugLineUptime ); +DECLARE_ONE( DebugLineResetKeyMapping ); /* diff --git a/src/ScreenMapControllers.cpp b/src/ScreenMapControllers.cpp index 3f58579e0a..a3d0689a45 100644 --- a/src/ScreenMapControllers.cpp +++ b/src/ScreenMapControllers.cpp @@ -200,6 +200,10 @@ void ScreenMapControllers::Init() m_NoSetListPrompt->SetName("NoSetListPrompt"); this->AddChild(m_NoSetListPrompt); + m_SanityMessage.Load(THEME->GetPathG(m_sName, "sanitymessage")); + m_SanityMessage->SetName("SanityMessage"); + this->AddChild(m_SanityMessage); + m_Warning.Load(THEME->GetPathG(m_sName, "warning")); m_Warning->SetName("Warning"); m_Warning->SetDrawOrder(DRAW_ORDER_TRANSITIONS); @@ -222,6 +226,7 @@ void ScreenMapControllers::BeginScreen() m_fLockInputSecs= THEME->GetMetricF(m_sName, "LockInputSecs"); m_AutoDismissWarningSecs= THEME->GetMetricF(m_sName, "AutoDismissWarningSecs"); m_AutoDismissNoSetListPromptSecs= 0.0f; + m_AutoDismissSanitySecs= 0.0f; m_Warning->PlayCommand("TweenOn"); } @@ -247,6 +252,14 @@ void ScreenMapControllers::Update( float fDeltaTime ) m_NoSetListPrompt->PlayCommand("TweenOff"); } } + if(m_AutoDismissSanitySecs > 0.0f) + { + m_AutoDismissSanitySecs-= fDeltaTime; + if(m_AutoDismissSanitySecs <= 0.0f) + { + m_SanityMessage->PlayCommand("TweenOff"); + } + } // // Update devices text @@ -349,6 +362,18 @@ bool ScreenMapControllers::Input( const InputEventPlus &input ) } return false; } + + if(m_AutoDismissSanitySecs > 0.0f) + { + if(input.type == IET_FIRST_PRESS && + input.DeviceI.device == DEVICE_KEYBOARD && + input.DeviceI.button == KEY_ENTER) + { + m_AutoDismissSanitySecs = 0.0f; + m_SanityMessage->PlayCommand("TweenOff"); + } + return false; + } if( input.type != IET_FIRST_PRESS && input.type != IET_REPEAT ) { @@ -706,8 +731,11 @@ void ScreenMapControllers::ReloadFromDisk() void ScreenMapControllers::SaveToDisk() { - INPUTMAPPER->SaveMappingsToDisk(); - m_ChangeOccurred= false; + if(SanityCheckWrapper()) + { + INPUTMAPPER->SaveMappingsToDisk(); + m_ChangeOccurred= false; + } } void ScreenMapControllers::SetListMode() @@ -732,8 +760,13 @@ void ScreenMapControllers::ExitAction() { if(m_ChangeOccurred) { - ScreenPrompt::Prompt(SM_DoSaveAndExit, SAVE_PROMPT, PROMPT_YES_NO_CANCEL, - ANSWER_YES); + // If the current mapping doesn't pass the sanity check, then the user + // can't navigate the prompt screen to pick a choice. -Kyz + if(SanityCheckWrapper()) + { + ScreenPrompt::Prompt(SM_DoSaveAndExit, SAVE_PROMPT, + PROMPT_YES_NO_CANCEL, ANSWER_YES); + } } else { @@ -742,6 +775,30 @@ void ScreenMapControllers::ExitAction() } } +bool ScreenMapControllers::SanityCheckWrapper() +{ + vector reasons_not_sane; + INPUTMAPPER->SanityCheckMappings(reasons_not_sane); + if(reasons_not_sane.empty()) + { + return true; + } + else + { + FOREACH(RString, reasons_not_sane, reason) + { + *reason= THEME->GetString("ScreenMapControllers", *reason); + } + RString joined_reasons= join("\n", reasons_not_sane); + joined_reasons= THEME->GetString("ScreenMapControllers", "VitalButtons") + "\n" + joined_reasons; + Message msg("SetText"); + msg.SetParam("Text", joined_reasons); + m_SanityMessage->HandleMessage(msg); + m_AutoDismissSanitySecs= THEME->GetMetricF(m_sName, "AutoDismissSanitySecs"); + return false; + } +} + void ScreenMapControllers::ActionRow::Load(RString const& scr_name, RString const& name, ScreenMapControllers::action_fun_t action, ActorFrame* line, ActorScroller* scroller) diff --git a/src/ScreenMapControllers.h b/src/ScreenMapControllers.h index 92ca5bff71..7f6600bbaf 100644 --- a/src/ScreenMapControllers.h +++ b/src/ScreenMapControllers.h @@ -72,6 +72,9 @@ private: float m_AutoDismissNoSetListPromptSecs; AutoActor m_NoSetListPrompt; + float m_AutoDismissSanitySecs; + AutoActor m_SanityMessage; + struct SetListEntry { int m_button; @@ -111,6 +114,7 @@ private: void SaveToDisk(); void SetListMode(); void ExitAction(); + bool SanityCheckWrapper(); vector m_Actions; From c3d2b5e1b186c9e435a545eab3e17d3c176fb7b1 Mon Sep 17 00:00:00 2001 From: Kyzentun Date: Sun, 30 Nov 2014 14:58:03 -0700 Subject: [PATCH 2/2] Reset keys debug option changed to save defaults to disk and reset. --- src/ScreenDebugOverlay.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ScreenDebugOverlay.cpp b/src/ScreenDebugOverlay.cpp index 54fc0e74c1..0dd61a09a3 100644 --- a/src/ScreenDebugOverlay.cpp +++ b/src/ScreenDebugOverlay.cpp @@ -962,6 +962,7 @@ class DebugLineResetKeyMapping : public IDebugLine virtual void DoAndLog( RString &sMessageOut ) { INPUTMAPPER->ResetMappingsToDefault(); + INPUTMAPPER->SaveMappingsToDisk(); IDebugLine::DoAndLog( sMessageOut ); } };