Skip to content

Commit abdbc54

Browse files
committed
HelpComponent: Display different help icons depending on controller
Before this commit, all buttons shown in the help component would use the SNES layout, which wouldn't match when having plugged in an Xbox or Sony Playstation controller. If there are different kinds of controllers plugged in, the input mapping shown will be of the last used or inserted. The intention here is to help solving #442, or at least most of it.
1 parent 0c4b42d commit abdbc54

4 files changed

Lines changed: 77 additions & 15 deletions

File tree

es-core/src/InputManager.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ int SDL_USER_CECBUTTONUP = -1;
3131

3232
InputManager* InputManager::mInstance = NULL;
3333

34-
InputManager::InputManager() : mKeyboardInputConfig(NULL)
34+
InputManager::InputManager() : mKeyboardInputConfig(NULL), mLastUsedKeyboardOrController(DEVICE_KEYBOARD)
3535
{
3636
}
3737

@@ -111,6 +111,8 @@ void InputManager::addJoystickByDeviceIndex(int id)
111111
int numAxes = SDL_JoystickNumAxes(joy);
112112
mPrevAxisValues[joyId] = new int[numAxes];
113113
std::fill(mPrevAxisValues[joyId], mPrevAxisValues[joyId] + numAxes, 0); //initialize array to 0
114+
115+
mLastUsedKeyboardOrController = joyId;
114116
}
115117

116118
void InputManager::removeJoystickByJoystickID(SDL_JoystickID joyId)
@@ -198,6 +200,9 @@ int InputManager::getButtonCountByDevice(SDL_JoystickID id)
198200

199201
InputConfig* InputManager::getInputConfigByDevice(int device)
200202
{
203+
if(device != DEVICE_CEC)
204+
mLastUsedKeyboardOrController = device;
205+
201206
if(device == DEVICE_KEYBOARD)
202207
return mKeyboardInputConfig;
203208
else if(device == DEVICE_CEC)
@@ -206,6 +211,18 @@ InputConfig* InputManager::getInputConfigByDevice(int device)
206211
return mInputConfigs[device];
207212
}
208213

214+
InputConfig* InputManager::getInputConfigForLastUsedDevice() const
215+
{
216+
if(mLastUsedKeyboardOrController == DEVICE_KEYBOARD)
217+
return mKeyboardInputConfig;
218+
219+
const auto it = mInputConfigs.find(mLastUsedKeyboardOrController);
220+
if(it != mInputConfigs.end())
221+
return it->second;
222+
223+
return nullptr; // Could happen if last used controller was unplugged
224+
}
225+
209226
bool InputManager::parseEvent(const SDL_Event& ev, Window* window)
210227
{
211228
bool causedEvent = false;

es-core/src/InputManager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class InputManager
2626
std::map<SDL_JoystickID, InputConfig*> mInputConfigs;
2727
InputConfig* mKeyboardInputConfig;
2828
InputConfig* mCECInputConfig;
29+
int mLastUsedKeyboardOrController;
2930

3031
std::map<SDL_JoystickID, int*> mPrevAxisValues;
3132

@@ -56,6 +57,7 @@ class InputManager
5657
std::string getDeviceGUIDString(int deviceId);
5758

5859
InputConfig* getInputConfigByDevice(int deviceId);
60+
InputConfig* getInputConfigForLastUsedDevice() const;
5961

6062
bool parseEvent(const SDL_Event& ev, Window* window);
6163
};

es-core/src/components/HelpComponent.cpp

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
#include "components/ComponentGrid.h"
44
#include "components/ImageComponent.h"
55
#include "components/TextComponent.h"
6-
#include "resources/TextureResource.h"
76
#include "utils/StringUtil.h"
87
#include "Log.h"
98
#include "Settings.h"
9+
#include "InputManager.h"
1010

1111
#define OFFSET_X 12 // move the entire thing right by this amount (px)
1212
#define OFFSET_Y 12 // move the entire thing up by this amount (px)
1313

1414
#define ICON_TEXT_SPACING 8 // space between [icon] and [text] (px)
1515
#define ENTRY_SPACING 16 // space between [text] and next [icon] (px)
1616

17-
static const std::map<std::string, const char*> ICON_PATH_MAP {
17+
static const HelpComponent::IconPathMap DEFAULT_ICON_PATH_MAP {
1818
{ "up/down", ":/help/dpad_updown.svg" },
1919
{ "left/right", ":/help/dpad_leftright.svg" },
2020
{ "up/down/left/right", ":/help/dpad_all.svg" },
@@ -29,6 +29,20 @@ static const std::map<std::string, const char*> ICON_PATH_MAP {
2929
{ "select", ":/help/button_select.svg" }
3030
};
3131

32+
static const HelpComponent::IconPathMap NO_ICON_OVERRIDES {};
33+
static const HelpComponent::IconPathMap XBOX_ICON_OVERRIDES {
34+
{ "a", ":/help/button_b.svg" },
35+
{ "b", ":/help/button_a.svg" },
36+
{ "x", ":/help/button_y.svg" },
37+
{ "y", ":/help/button_x.svg" },
38+
};
39+
static const HelpComponent::IconPathMap PLAYSTATION_ICON_OVERRIDES {
40+
{ "a", ":/help/button_circle.svg" },
41+
{ "b", ":/help/button_x.svg" },
42+
{ "x", ":/help/button_triangle.svg" },
43+
{ "y", ":/help/button_square.svg" },
44+
};
45+
3246
HelpComponent::HelpComponent(Window* window) : GuiComponent(window)
3347
{
3448
}
@@ -67,12 +81,15 @@ void HelpComponent::updateGrid()
6781
std::vector< std::shared_ptr<ImageComponent> > icons;
6882
std::vector< std::shared_ptr<TextComponent> > labels;
6983

84+
const auto& iconOverrides =
85+
getIconOverridesForInput(InputManager::getInstance()->getInputConfigForLastUsedDevice());
86+
7087
float width = 0;
7188
const float height = Math::round(font->getLetterHeight() * 1.25f);
7289
for(auto it = mPrompts.cbegin(); it != mPrompts.cend(); it++)
7390
{
7491
auto icon = std::make_shared<ImageComponent>(mWindow);
75-
icon->setImage(getIconTexture(it->first.c_str()));
92+
icon->setImage(getIconTexture(it->first, iconOverrides));
7693
icon->setColorShift(mStyle.iconColor);
7794
icon->setResize(0, height);
7895
icons.push_back(icon);
@@ -100,26 +117,46 @@ void HelpComponent::updateGrid()
100117
mGrid->setOrigin(mStyle.origin);
101118
}
102119

103-
std::shared_ptr<TextureResource> HelpComponent::getIconTexture(const char* name)
120+
const HelpComponent::IconPathMap& HelpComponent::getIconOverridesForInput(InputConfig* inputConfig)
104121
{
105-
auto it = mIconCache.find(name);
106-
if(it != mIconCache.cend())
107-
return it->second;
122+
if(!inputConfig)
123+
return NO_ICON_OVERRIDES;
124+
125+
const auto& deviceName = inputConfig->getDeviceName();
126+
if(strcasestr(deviceName.c_str(), "xbox"))
127+
return XBOX_ICON_OVERRIDES;
128+
129+
if(strcasestr(deviceName.c_str(), "sony") || strcasestr(deviceName.c_str(), "playstation"))
130+
return PLAYSTATION_ICON_OVERRIDES;
108131

109-
auto pathLookup = ICON_PATH_MAP.find(name);
110-
if(pathLookup == ICON_PATH_MAP.cend())
132+
return NO_ICON_OVERRIDES;
133+
}
134+
135+
std::shared_ptr<TextureResource> HelpComponent::getIconTexture(const std::string& name, const IconPathMap& iconOverrides)
136+
{
137+
auto pathLookup = iconOverrides.find(name);
138+
if(pathLookup == iconOverrides.cend())
111139
{
112-
LOG(LogError) << "Unknown help icon \"" << name << "\"!";
113-
return nullptr;
140+
pathLookup = DEFAULT_ICON_PATH_MAP.find(name);
141+
if(pathLookup == DEFAULT_ICON_PATH_MAP.cend())
142+
{
143+
LOG(LogError) << "Unknown help icon \"" << name << "\"!";
144+
return nullptr;
145+
}
114146
}
147+
148+
auto it = mIconCache.find(pathLookup->second);
149+
if(it != mIconCache.cend())
150+
return it->second;
151+
115152
if(!ResourceManager::getInstance()->fileExists(pathLookup->second))
116153
{
117-
LOG(LogError) << "Help icon \"" << name << "\" - corresponding image file \"" << pathLookup->second << "\" misisng!";
154+
LOG(LogError) << "Help icon \"" << name << "\" - corresponding image file \"" << pathLookup->second << "\" missing!";
118155
return nullptr;
119156
}
120157

121158
std::shared_ptr<TextureResource> tex = TextureResource::get(pathLookup->second);
122-
mIconCache[std::string(name)] = tex;
159+
mIconCache[pathLookup->second] = tex;
123160
return tex;
124161
}
125162

es-core/src/components/HelpComponent.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
#include "GuiComponent.h"
66
#include "HelpStyle.h"
7+
#include "resources/TextureResource.h"
8+
9+
#include <string>
710

811
class ComponentGrid;
912
class ImageComponent;
@@ -22,8 +25,11 @@ class HelpComponent : public GuiComponent
2225

2326
void setStyle(const HelpStyle& style);
2427

28+
using IconPathMap = std::map<std::string /*name*/, std::string /*path*/>;
29+
2530
private:
26-
std::shared_ptr<TextureResource> getIconTexture(const char* name);
31+
const IconPathMap& getIconOverridesForInput(InputConfig* inputConfig);
32+
std::shared_ptr<TextureResource> getIconTexture(const std::string& name, const IconPathMap& iconOverrides);
2733
std::map< std::string, std::shared_ptr<TextureResource> > mIconCache;
2834

2935
std::shared_ptr<ComponentGrid> mGrid;

0 commit comments

Comments
 (0)