Merge branch 'keymapping_sanity' of https://github.com/kyzentun/stepmania

This commit is contained in:
Kyzentun
2014-12-08 16:01:47 -07:00
8 changed files with 172 additions and 4 deletions
@@ -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),
},
},
}
+6
View File
@@ -1362,6 +1362,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
@@ -1562,11 +1563,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!
+2
View File
@@ -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
+61
View File
@@ -661,6 +661,67 @@ void InputMapper::ResetMappingsToDefault()
AddDefaultMappingsForCurrentGameIfUnmapped();
}
void InputMapper::CheckButtonAndAddToReason(GameButton menu, vector<RString>& full_reason, RString const& sub_reason)
{
vector<GameInput> 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<DeviceInput> 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<RString>& 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." );
+2
View File
@@ -152,6 +152,8 @@ public:
void ReadMappingsFromDisk();
void SaveMappingsToDisk();
void ResetMappingsToDefault();
void CheckButtonAndAddToReason(GameButton menu, vector<RString>& full_reason, RString const& sub_reason);
void SanityCheckMappings(vector<RString>& reason);
void ClearAllMappings();
+16
View File
@@ -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,19 @@ 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();
INPUTMAPPER->SaveMappingsToDisk();
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineReloadCurrentScreen : public IDebugLine
{
virtual RString GetDisplayTitle() { return RELOAD.GetValue(); }
@@ -1272,6 +1287,7 @@ DECLARE_ONE( DebugLineVisualDelayDown );
DECLARE_ONE( DebugLineVisualDelayUp );
DECLARE_ONE( DebugLineForceCrash );
DECLARE_ONE( DebugLineUptime );
DECLARE_ONE( DebugLineResetKeyMapping );
/*
+61 -4
View File
@@ -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<RString> 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)
+4
View File
@@ -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<ActionRow> m_Actions;