mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-29 01:25:38 +00:00
Improved input device configuration.
Default keyboard mappings are now applied if the user has not configured the keyboard.
This commit is contained in:
parent
57d6dab2cc
commit
1b65eaac2e
|
@ -38,6 +38,7 @@ https://google.github.io/styleguide/cppguide.html
|
||||||
* Comments should be proper sentences, starting with a capital letter and ending with a dot
|
* Comments should be proper sentences, starting with a capital letter and ending with a dot
|
||||||
* Use K&R placements of braces, read the Linux Kernel coding style document for clarifications
|
* Use K&R placements of braces, read the Linux Kernel coding style document for clarifications
|
||||||
* Always use spaces between keywords and opening brackets, i.e. `if ()`, `for ()`, `while ()` etc.
|
* Always use spaces between keywords and opening brackets, i.e. `if ()`, `for ()`, `while ()` etc.
|
||||||
|
* Indentation of switch/case statements is optional, but it's usually easier to read the code with indentations in place
|
||||||
* Use `std::string` instead of `char *` or `char []` unless there is a specific reason requiring the latter
|
* Use `std::string` instead of `char *` or `char []` unless there is a specific reason requiring the latter
|
||||||
* If the arguments (and initializer list) for a function or class exceeds 4 items, arrange them vertically to make the code easier to read
|
* If the arguments (and initializer list) for a function or class exceeds 4 items, arrange them vertically to make the code easier to read
|
||||||
* Always declare one variable per line, never combine multiple declarations of the same type
|
* Always declare one variable per line, never combine multiple declarations of the same type
|
||||||
|
|
1
NEWS.md
1
NEWS.md
|
@ -18,6 +18,7 @@ v1.0.0
|
||||||
* Per-game launch command override, so that different cores or emulators can be used on a per-game basis (saved to gamelist.xml)
|
* Per-game launch command override, so that different cores or emulators can be used on a per-game basis (saved to gamelist.xml)
|
||||||
* Core location can be defined relative to the emulator binary using the %EMUPATH% varible in es_systems.cfg (mostly useful for Windows)
|
* Core location can be defined relative to the emulator binary using the %EMUPATH% varible in es_systems.cfg (mostly useful for Windows)
|
||||||
* Help system updated and expanded to the complete application (previously it was only partially implemented)
|
* Help system updated and expanded to the complete application (previously it was only partially implemented)
|
||||||
|
* Improved input device configuration, and default keyboard mappings are now applied if the keyboard has not been configured by the user
|
||||||
* GUI-configurable option to sort favorite games on the top of the game lists (favorites marked with stars)
|
* GUI-configurable option to sort favorite games on the top of the game lists (favorites marked with stars)
|
||||||
* Added new component GuiComplexTextEditPopup to handle changes to configuration file entries and similar
|
* Added new component GuiComplexTextEditPopup to handle changes to configuration file entries and similar
|
||||||
* Speed improvements and optimizations, the application now starts faster and feels more responsive
|
* Speed improvements and optimizations, the application now starts faster and feels more responsive
|
||||||
|
|
|
@ -495,6 +495,11 @@ int main(int argc, char* argv[])
|
||||||
ViewController::get()->goToStart();
|
ViewController::get()->goToStart();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// Always reset ShowDefaultKeyboardWarning to true if the es_input.cfg
|
||||||
|
// file is missing.
|
||||||
|
Settings::getInstance()->setBool("ShowDefaultKeyboardWarning", true);
|
||||||
|
Settings::getInstance()->saveFile();
|
||||||
|
|
||||||
window.pushGui(new GuiDetectDevice(&window, true, [] {
|
window.pushGui(new GuiDetectDevice(&window, true, [] {
|
||||||
ViewController::get()->goToStart(); }));
|
ViewController::get()->goToStart(); }));
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
|
||||||
UIModeController * UIModeController::sInstance = nullptr;
|
UIModeController* UIModeController::sInstance = nullptr;
|
||||||
|
|
||||||
UIModeController * UIModeController::getInstance()
|
UIModeController* UIModeController::getInstance()
|
||||||
{
|
{
|
||||||
if (sInstance == nullptr)
|
if (sInstance == nullptr)
|
||||||
sInstance = new UIModeController();
|
sInstance = new UIModeController();
|
||||||
|
@ -39,7 +39,7 @@ void UIModeController::monitorUIMode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UIModeController::listen(InputConfig * config, Input input)
|
bool UIModeController::listen(InputConfig* config, Input input)
|
||||||
{
|
{
|
||||||
// Reads the current input to listen for the passkey sequence to unlock
|
// Reads the current input to listen for the passkey sequence to unlock
|
||||||
// the UI mode. The progress is saved in mPassKeyCounter.
|
// the UI mode. The progress is saved in mPassKeyCounter.
|
||||||
|
@ -59,7 +59,7 @@ bool UIModeController::listen(InputConfig * config, Input input)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UIModeController::inputIsMatch(InputConfig * config, Input input)
|
bool UIModeController::inputIsMatch(InputConfig* config, Input input)
|
||||||
{
|
{
|
||||||
for (auto valstring : mInputVals) {
|
for (auto valstring : mInputVals) {
|
||||||
if (config->isMappedLike(valstring, input) &&
|
if (config->isMappedLike(valstring, input) &&
|
||||||
|
@ -107,36 +107,36 @@ std::string UIModeController::getFormattedPassKeyStr()
|
||||||
out += (out == "") ? "" : ", "; // Add a comma after the first entry.
|
out += (out == "") ? "" : ", "; // Add a comma after the first entry.
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'u':
|
case 'u':
|
||||||
out += Utils::String::unicode2Chars(0x2191); // Arrow pointing up.
|
out += Utils::String::unicode2Chars(0x2191); // Arrow pointing up.
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
out += Utils::String::unicode2Chars(0x2193); // Arrow pointing down.
|
out += Utils::String::unicode2Chars(0x2193); // Arrow pointing down.
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
out += Utils::String::unicode2Chars(0x2190); // Arrow pointing left.
|
out += Utils::String::unicode2Chars(0x2190); // Arrow pointing left.
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
out += Utils::String::unicode2Chars(0x2192); // Arrow pointing right.
|
out += Utils::String::unicode2Chars(0x2192); // Arrow pointing right.
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
out += "A";
|
out += "A";
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
out += "B";
|
out += "B";
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
out += "X";
|
out += "X";
|
||||||
break;
|
break;
|
||||||
case 'y':
|
case 'y':
|
||||||
out += "Y";
|
out += "Y";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIModeController::logInput(InputConfig * config, Input input)
|
void UIModeController::logInput(InputConfig* config, Input input)
|
||||||
{
|
{
|
||||||
std::string mapname = "";
|
std::string mapname = "";
|
||||||
std::vector<std::string> maps = config->getMappedTo(input);
|
std::vector<std::string> maps = config->getMappedTo(input);
|
||||||
|
@ -146,11 +146,11 @@ void UIModeController::logInput(InputConfig * config, Input input)
|
||||||
mapname += ", ";
|
mapname += ", ";
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(LogDebug) << "UIModeController::logInput(" << config->getDeviceName() <<
|
LOG(LogDebug) << "UIModeController::logInput(" << config->getDeviceName() << "): " <<
|
||||||
"): " << input.string() << ", isMappedTo=" << mapname << ", value=" << input.value;
|
input.string() << ", isMappedTo=" << mapname << ", value=" << input.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UIModeController::isValidInput(InputConfig * config, Input input)
|
bool UIModeController::isValidInput(InputConfig* config, Input input)
|
||||||
{
|
{
|
||||||
if ((config->getMappedTo(input).size() == 0) || // Not a mapped input, so ignore..
|
if ((config->getMappedTo(input).size() == 0) || // Not a mapped input, so ignore..
|
||||||
(input.type == TYPE_HAT) || // Ignore all hat inputs.
|
(input.type == TYPE_HAT) || // Ignore all hat inputs.
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "animations/LaunchAnimation.h"
|
#include "animations/LaunchAnimation.h"
|
||||||
#include "animations/MoveCameraAnimation.h"
|
#include "animations/MoveCameraAnimation.h"
|
||||||
#include "guis/GuiMenu.h"
|
#include "guis/GuiMenu.h"
|
||||||
|
#include "guis/GuiMsgBox.h"
|
||||||
#include "views/gamelist/DetailedGameListView.h"
|
#include "views/gamelist/DetailedGameListView.h"
|
||||||
#include "views/gamelist/IGameListView.h"
|
#include "views/gamelist/IGameListView.h"
|
||||||
#include "views/gamelist/GridGameListView.h"
|
#include "views/gamelist/GridGameListView.h"
|
||||||
|
@ -21,11 +22,12 @@
|
||||||
#include "views/SystemView.h"
|
#include "views/SystemView.h"
|
||||||
#include "views/UIModeController.h"
|
#include "views/UIModeController.h"
|
||||||
#include "FileFilterIndex.h"
|
#include "FileFilterIndex.h"
|
||||||
|
#include "InputManager.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
#include "Sound.h"
|
||||||
#include "SystemData.h"
|
#include "SystemData.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
#include "Sound.h"
|
|
||||||
|
|
||||||
ViewController* ViewController::sInstance = nullptr;
|
ViewController* ViewController::sInstance = nullptr;
|
||||||
|
|
||||||
|
@ -60,6 +62,26 @@ ViewController::~ViewController()
|
||||||
|
|
||||||
void ViewController::goToStart()
|
void ViewController::goToStart()
|
||||||
{
|
{
|
||||||
|
// Check if the keyboard config is set as application default, meaning no user
|
||||||
|
// configuration has been performed.
|
||||||
|
if (InputManager::getInstance()->
|
||||||
|
getInputConfigByDevice(DEVICE_KEYBOARD)->getDefaultConfigFlag()) {
|
||||||
|
if (Settings::getInstance()->getBool("ShowDefaultKeyboardWarning")) {
|
||||||
|
std::string message = "NO KEYBOARD CONFIGURATION COULD BE\n"
|
||||||
|
"FOUND IN ES_INPUT.CFG, SO APPLYING THE\n"
|
||||||
|
"DEFAULT KEYBOARD MAPPINGS. IT'S HOWEVER\n"
|
||||||
|
"RECOMMENDED TO SETUP YOUR OWN KEYBOARD\n"
|
||||||
|
"CONFIGURATION. TO DO SO, CHOOSE THE ENTRY\n"
|
||||||
|
"\"CONFIGURE INPUT\" ON THE MAIN MENU.";
|
||||||
|
|
||||||
|
mWindow->pushGui(new GuiMsgBox(mWindow, HelpStyle(), message.c_str(),
|
||||||
|
"OK", nullptr, "DON'T SHOW AGAIN", [] {
|
||||||
|
Settings::getInstance()->setBool("ShowDefaultKeyboardWarning", false);
|
||||||
|
Settings::getInstance()->saveFile();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If a specific system is requested, go directly to its game list.
|
// If a specific system is requested, go directly to its game list.
|
||||||
auto requestedSystem = Settings::getInstance()->getString("StartupSystem");
|
auto requestedSystem = Settings::getInstance()->getString("StartupSystem");
|
||||||
if ("" != requestedSystem && "retropie" != requestedSystem) {
|
if ("" != requestedSystem && "retropie" != requestedSystem) {
|
||||||
|
|
|
@ -59,7 +59,8 @@ InputConfig::InputConfig(
|
||||||
const std::string& deviceGUID)
|
const std::string& deviceGUID)
|
||||||
: mDeviceId(deviceId),
|
: mDeviceId(deviceId),
|
||||||
mDeviceName(deviceName),
|
mDeviceName(deviceName),
|
||||||
mDeviceGUID(deviceGUID)
|
mDeviceGUID(deviceGUID),
|
||||||
|
mDefaultConfigFlag(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +187,7 @@ void InputConfig::loadFromXML(pugi::xml_node& node)
|
||||||
InputType typeEnum = stringToInputType(type);
|
InputType typeEnum = stringToInputType(type);
|
||||||
|
|
||||||
if (typeEnum == TYPE_COUNT) {
|
if (typeEnum == TYPE_COUNT) {
|
||||||
LOG(LogError) << "InputConfig load error - input of type \"" << type <<
|
LOG(LogError) << "Error - InputConfig load error - input of type \"" << type <<
|
||||||
"\" is invalid! Skipping input \"" << name << "\".\n";
|
"\" is invalid! Skipping input \"" << name << "\".\n";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +196,7 @@ void InputConfig::loadFromXML(pugi::xml_node& node)
|
||||||
int value = input.attribute("value").as_int();
|
int value = input.attribute("value").as_int();
|
||||||
|
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
LOG(LogWarning) << "WARNING: InputConfig value is 0 for " <<
|
LOG(LogWarning) << "Warning - InputConfig value is 0 for " <<
|
||||||
type << " " << id << "!\n";
|
type << " " << id << "!\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,10 @@ public:
|
||||||
inline const std::string& getDeviceName() { return mDeviceName; }
|
inline const std::string& getDeviceName() { return mDeviceName; }
|
||||||
inline const std::string& getDeviceGUIDString() { return mDeviceGUID; }
|
inline const std::string& getDeviceGUIDString() { return mDeviceGUID; }
|
||||||
|
|
||||||
|
void setDefaultConfigFlag() { mDefaultConfigFlag = true; };
|
||||||
|
void unsetDefaultConfigFlag() { mDefaultConfigFlag = false; };
|
||||||
|
bool getDefaultConfigFlag() { return mDefaultConfigFlag; };
|
||||||
|
|
||||||
// Returns true if Input is mapped to this name, false otherwise.
|
// Returns true if Input is mapped to this name, false otherwise.
|
||||||
bool isMappedTo(const std::string& name, Input input);
|
bool isMappedTo(const std::string& name, Input input);
|
||||||
bool isMappedLike(const std::string& name, Input input);
|
bool isMappedLike(const std::string& name, Input input);
|
||||||
|
@ -149,6 +153,7 @@ private:
|
||||||
const int mDeviceId;
|
const int mDeviceId;
|
||||||
const std::string mDeviceName;
|
const std::string mDeviceName;
|
||||||
const std::string mDeviceGUID;
|
const std::string mDeviceGUID;
|
||||||
|
bool mDefaultConfigFlag;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ES_CORE_INPUT_CONFIG_H
|
#endif // ES_CORE_INPUT_CONFIG_H
|
||||||
|
|
|
@ -299,8 +299,15 @@ bool InputManager::parseEvent(const SDL_Event& ev, Window* window)
|
||||||
bool InputManager::loadInputConfig(InputConfig* config)
|
bool InputManager::loadInputConfig(InputConfig* config)
|
||||||
{
|
{
|
||||||
std::string path = getConfigPath();
|
std::string path = getConfigPath();
|
||||||
if (!Utils::FileSystem::exists(path))
|
if (!Utils::FileSystem::exists(path)) {
|
||||||
|
if (config->getDeviceName() == "Keyboard") {
|
||||||
|
LOG(LogDebug) << "InputManager::loadInputConfig(): Assigning default keyboard "
|
||||||
|
"mappings as there is no es_input.cfg configuration file.";
|
||||||
|
loadDefaultKBConfig();
|
||||||
|
config->setDefaultConfigFlag();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
pugi::xml_document doc;
|
pugi::xml_document doc;
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
@ -323,17 +330,25 @@ bool InputManager::loadInputConfig(InputConfig* config)
|
||||||
if (!configNode)
|
if (!configNode)
|
||||||
configNode = root.find_child_by_attribute("inputConfig",
|
configNode = root.find_child_by_attribute("inputConfig",
|
||||||
"deviceName", config->getDeviceName().c_str());
|
"deviceName", config->getDeviceName().c_str());
|
||||||
if (!configNode)
|
if (!configNode) {
|
||||||
return false;
|
if (config->getDeviceName() == "Keyboard") {
|
||||||
|
LOG(LogDebug) << "InputManager::loadInputConfig(): Assigning default keyboard "
|
||||||
|
"mappings as there is no keyboard configuration in es_input.cfg.";
|
||||||
|
loadDefaultKBConfig();
|
||||||
|
config->setDefaultConfigFlag();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
config->loadFromXML(configNode);
|
config->loadFromXML(configNode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used in an "emergency" where no keyboard config could be loaded from the inputmanager
|
// If there is no es_input.cfg file or if the user has not yet configured the keyboard
|
||||||
// config file. Allows the user to select to reconfigure in menus if this happens without
|
// mappings, then load these defaults.
|
||||||
// having to delete es_input.cfg manually.
|
|
||||||
// Note: Not currently used.
|
|
||||||
void InputManager::loadDefaultKBConfig()
|
void InputManager::loadDefaultKBConfig()
|
||||||
{
|
{
|
||||||
InputConfig* cfg = getInputConfigByDevice(DEVICE_KEYBOARD);
|
InputConfig* cfg = getInputConfigByDevice(DEVICE_KEYBOARD);
|
||||||
|
@ -363,6 +378,9 @@ void InputManager::writeDeviceConfig(InputConfig* config)
|
||||||
|
|
||||||
std::string path = getConfigPath();
|
std::string path = getConfigPath();
|
||||||
|
|
||||||
|
LOG(LogDebug) << "InputManager::writeDeviceConfig(): "
|
||||||
|
"Saving input configuration file to " << path;
|
||||||
|
|
||||||
pugi::xml_document doc;
|
pugi::xml_document doc;
|
||||||
|
|
||||||
if (Utils::FileSystem::exists(path)) {
|
if (Utils::FileSystem::exists(path)) {
|
||||||
|
@ -420,7 +438,7 @@ void InputManager::writeDeviceConfig(InputConfig* config)
|
||||||
Scripting::fireEvent("config-changed");
|
Scripting::fireEvent("config-changed");
|
||||||
Scripting::fireEvent("controls-changed");
|
Scripting::fireEvent("controls-changed");
|
||||||
|
|
||||||
// Execute any doOnFinish commands and re-load the config for changes.
|
// Execute any doOnFinish commands and reload the config for changes.
|
||||||
doOnFinish();
|
doOnFinish();
|
||||||
loadInputConfig(config);
|
loadInputConfig(config);
|
||||||
}
|
}
|
||||||
|
@ -440,7 +458,7 @@ void InputManager::doOnFinish()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
LOG(LogError) << "Error parsing input config: " << result.description();
|
LOG(LogError) << "Error - Couldn't parse input config: " << result.description();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pugi::xml_node root = doc.child("inputList");
|
pugi::xml_node root = doc.child("inputList");
|
||||||
|
@ -514,7 +532,7 @@ std::string InputManager::getDeviceGUIDString(int deviceId)
|
||||||
|
|
||||||
auto it = mJoysticks.find(deviceId);
|
auto it = mJoysticks.find(deviceId);
|
||||||
if (it == mJoysticks.cend()) {
|
if (it == mJoysticks.cend()) {
|
||||||
LOG(LogError) << "getDeviceGUIDString - deviceId " << deviceId << " not found!";
|
LOG(LogError) << "Error - getDeviceGUIDString - deviceId " << deviceId << " not found!";
|
||||||
return "something went horribly wrong";
|
return "something went horribly wrong";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,29 +25,6 @@ union SDL_Event;
|
||||||
// You should only ever instantiate one of these, by the way.
|
// You should only ever instantiate one of these, by the way.
|
||||||
class InputManager
|
class InputManager
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
InputManager();
|
|
||||||
|
|
||||||
static InputManager* mInstance;
|
|
||||||
|
|
||||||
static const int DEADZONE = 23000;
|
|
||||||
|
|
||||||
void loadDefaultKBConfig();
|
|
||||||
|
|
||||||
std::map<SDL_JoystickID, SDL_Joystick*> mJoysticks;
|
|
||||||
std::map<SDL_JoystickID, InputConfig*> mInputConfigs;
|
|
||||||
InputConfig* mKeyboardInputConfig;
|
|
||||||
InputConfig* mCECInputConfig;
|
|
||||||
|
|
||||||
std::map<SDL_JoystickID, int*> mPrevAxisValues;
|
|
||||||
|
|
||||||
bool initialized() const;
|
|
||||||
|
|
||||||
void addJoystickByDeviceIndex(int id);
|
|
||||||
void removeJoystickByJoystickID(SDL_JoystickID id);
|
|
||||||
// Returns true if successfully loaded, false if not (or if it didn't exist).
|
|
||||||
bool loadInputConfig(InputConfig* config);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~InputManager();
|
virtual ~InputManager();
|
||||||
|
|
||||||
|
@ -71,6 +48,29 @@ public:
|
||||||
InputConfig* getInputConfigByDevice(int deviceId);
|
InputConfig* getInputConfigByDevice(int deviceId);
|
||||||
|
|
||||||
bool parseEvent(const SDL_Event& ev, Window* window);
|
bool parseEvent(const SDL_Event& ev, Window* window);
|
||||||
|
|
||||||
|
private:
|
||||||
|
InputManager();
|
||||||
|
|
||||||
|
static InputManager* mInstance;
|
||||||
|
|
||||||
|
static const int DEADZONE = 23000;
|
||||||
|
|
||||||
|
void loadDefaultKBConfig();
|
||||||
|
|
||||||
|
std::map<SDL_JoystickID, SDL_Joystick*> mJoysticks;
|
||||||
|
std::map<SDL_JoystickID, InputConfig*> mInputConfigs;
|
||||||
|
InputConfig* mKeyboardInputConfig;
|
||||||
|
InputConfig* mCECInputConfig;
|
||||||
|
|
||||||
|
std::map<SDL_JoystickID, int*> mPrevAxisValues;
|
||||||
|
|
||||||
|
bool initialized() const;
|
||||||
|
|
||||||
|
void addJoystickByDeviceIndex(int id);
|
||||||
|
void removeJoystickByJoystickID(SDL_JoystickID id);
|
||||||
|
// Returns true if successfully loaded, false if not (or if it didn't exist).
|
||||||
|
bool loadInputConfig(InputConfig* config);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ES_CORE_INPUT_MANAGER_H
|
#endif // ES_CORE_INPUT_MANAGER_H
|
||||||
|
|
|
@ -214,9 +214,10 @@ void Settings::setDefaults()
|
||||||
|
|
||||||
//
|
//
|
||||||
// Settings that can be changed in es_settings.cfg
|
// Settings that can be changed in es_settings.cfg
|
||||||
// but that are not configurable via the GUI (yet).
|
// but that are not configurable via the GUI.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
mBoolMap["ShowDefaultKeyboardWarning"] = true;
|
||||||
mStringMap["DefaultSortOrder"] = "filename, ascending";
|
mStringMap["DefaultSortOrder"] = "filename, ascending";
|
||||||
mStringMap["MediaDirectory"] = "";
|
mStringMap["MediaDirectory"] = "";
|
||||||
mStringMap["ROMDirectory"] = "";
|
mStringMap["ROMDirectory"] = "";
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "InputManager.h"
|
#include "InputManager.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Scripting.h"
|
#include "Scripting.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
|
@ -130,7 +131,8 @@ void Window::input(InputConfig* config, Input input)
|
||||||
if (mScreenSaver->isScreenSaverActive() &&
|
if (mScreenSaver->isScreenSaverActive() &&
|
||||||
Settings::getInstance()->getBool("ScreenSaverControls") &&
|
Settings::getInstance()->getBool("ScreenSaverControls") &&
|
||||||
(Settings::getInstance()->getString("ScreenSaverBehavior") == "random video")) {
|
(Settings::getInstance()->getString("ScreenSaverBehavior") == "random video")) {
|
||||||
if (mScreenSaver->getCurrentGame() != nullptr && (config->isMappedLike("right", input) ||
|
if (mScreenSaver->getCurrentGame() != nullptr &&
|
||||||
|
(config->isMappedLike("right", input) ||
|
||||||
config->isMappedTo("start", input) || config->isMappedTo("select", input))) {
|
config->isMappedTo("start", input) || config->isMappedTo("select", input))) {
|
||||||
if (config->isMappedLike("right", input) || config->isMappedTo("select", input)) {
|
if (config->isMappedLike("right", input) || config->isMappedTo("select", input)) {
|
||||||
if (input.value != 0) {
|
if (input.value != 0) {
|
||||||
|
@ -140,7 +142,7 @@ void Window::input(InputConfig* config, Input input)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (config->isMappedTo("start", input) && input.value != 0) {
|
else if (config->isMappedTo("start", input) && input.value != 0) {
|
||||||
// Launch game!
|
// Launch game.
|
||||||
cancelScreenSaver();
|
cancelScreenSaver();
|
||||||
mScreenSaver->launchGame();
|
mScreenSaver->launchGame();
|
||||||
// To force handling the wake up process.
|
// To force handling the wake up process.
|
||||||
|
@ -217,7 +219,7 @@ void Window::update(int deltaTime)
|
||||||
float fontVramUsageMb = Font::getTotalMemUsage() / 1000.0f / 1000.0f;
|
float fontVramUsageMb = Font::getTotalMemUsage() / 1000.0f / 1000.0f;
|
||||||
|
|
||||||
ss << "\nFont VRAM: " << fontVramUsageMb << " Tex VRAM: " << textureVramUsageMb <<
|
ss << "\nFont VRAM: " << fontVramUsageMb << " Tex VRAM: " << textureVramUsageMb <<
|
||||||
" Tex Max: " << textureTotalUsageMb;
|
" Tex Max: " << textureTotalUsageMb;
|
||||||
mFrameDataText = std::unique_ptr<TextCache>
|
mFrameDataText = std::unique_ptr<TextCache>
|
||||||
(mDefaultFonts.at(1)->buildTextCache(ss.str(), 50.f, 50.f, 0xFF00FFFF));
|
(mDefaultFonts.at(1)->buildTextCache(ss.str(), 50.f, 50.f, 0xFF00FFFF));
|
||||||
}
|
}
|
||||||
|
@ -388,8 +390,7 @@ void Window::setHelpPrompts(const std::vector<HelpPrompt>& prompts, const HelpSt
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int aVal = 0;
|
int aVal = 0;
|
||||||
int bVal = 0;
|
int bVal = 0;
|
||||||
while (map[i] != nullptr)
|
while (map[i] != nullptr) {
|
||||||
{
|
|
||||||
if (a.first == map[i])
|
if (a.first == map[i])
|
||||||
aVal = i;
|
aVal = i;
|
||||||
if (b.first == map[i])
|
if (b.first == map[i])
|
||||||
|
|
|
@ -27,7 +27,8 @@ struct HelpStyle;
|
||||||
class Window
|
class Window
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class ScreenSaver {
|
class ScreenSaver
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
virtual void startScreenSaver() = 0;
|
virtual void startScreenSaver() = 0;
|
||||||
virtual void stopScreenSaver() = 0;
|
virtual void stopScreenSaver() = 0;
|
||||||
|
@ -41,7 +42,8 @@ public:
|
||||||
virtual void resetCounts() = 0;
|
virtual void resetCounts() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class InfoPopup {
|
class InfoPopup
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
virtual void render(const Transform4x4f& parentTrans) = 0;
|
virtual void render(const Transform4x4f& parentTrans) = 0;
|
||||||
virtual void stop() = 0;
|
virtual void stop() = 0;
|
||||||
|
|
|
@ -51,7 +51,7 @@ GuiDetectDevice::GuiDetectDevice(
|
||||||
|
|
||||||
// Message.
|
// Message.
|
||||||
mMsg1 = std::make_shared<TextComponent>(mWindow,
|
mMsg1 = std::make_shared<TextComponent>(mWindow,
|
||||||
"HOLD A BUTTON ON YOUR DEVICE TO CONFIGURE IT.",
|
"HOLD A BUTTON ON YOUR DEVICE OR KEYBOARD TO CONFIGURE IT.",
|
||||||
Font::get(FONT_SIZE_SMALL), 0x777777FF, ALIGN_CENTER);
|
Font::get(FONT_SIZE_SMALL), 0x777777FF, ALIGN_CENTER);
|
||||||
mGrid.setEntry(mMsg1, Vector2i(0, 2), false, true);
|
mGrid.setEntry(mMsg1, Vector2i(0, 2), false, true);
|
||||||
|
|
||||||
|
|
|
@ -200,41 +200,51 @@ GuiInputConfig::GuiInputConfig(
|
||||||
// Buttons.
|
// Buttons.
|
||||||
std::vector< std::shared_ptr<ButtonComponent> > buttons;
|
std::vector< std::shared_ptr<ButtonComponent> > buttons;
|
||||||
std::function<void()> okFunction = [this, okCallback] {
|
std::function<void()> okFunction = [this, okCallback] {
|
||||||
InputManager::getInstance()->writeDeviceConfig(mTargetConfig); // save
|
// If we have just configured the keyboard, then unset the flag to indicate that
|
||||||
|
// we are using the default keyboard mappings.
|
||||||
|
if (mTargetConfig->getDeviceId() == DEVICE_KEYBOARD) {
|
||||||
|
InputManager::getInstance()->
|
||||||
|
getInputConfigByDevice(DEVICE_KEYBOARD)->unsetDefaultConfigFlag();
|
||||||
|
}
|
||||||
|
InputManager::getInstance()->writeDeviceConfig(mTargetConfig); // Save.
|
||||||
if (okCallback)
|
if (okCallback)
|
||||||
okCallback();
|
okCallback();
|
||||||
delete this;
|
delete this;
|
||||||
};
|
};
|
||||||
buttons.push_back(std::make_shared<ButtonComponent>(mWindow, "OK", "ok", [this, okFunction] {
|
|
||||||
// Check if the hotkey enable button is set. if not prompt the
|
buttons.push_back(std::make_shared<ButtonComponent>
|
||||||
// user to use select or nothing.
|
(mWindow, "OK", "ok", [this, okFunction] { okFunction(); }));
|
||||||
Input input;
|
|
||||||
okFunction();
|
// This code is disabled as there is no intention to provide emulator configuration or
|
||||||
// Temporarily commented out, needs to be properly cleaned up later.
|
// control via ES Desktop Edition. Let's keep the code for reference though.
|
||||||
// if (!mTargetConfig->getInputByName("HotKeyEnable", &input)) {
|
// buttons.push_back(std::make_shared<ButtonComponent>(mWindow, "OK", "ok", [this, okFunction] {
|
||||||
// mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(),
|
// // Check if the hotkey enable button is set. if not prompt the
|
||||||
// "YOU DIDN'T CHOOSE A HOTKEY ENABLE BUTTON. THIS IS REQUIRED FOR EXITING GAMES "
|
// // user to use select or nothing.
|
||||||
// "WITH A CONTROLLER. DO YOU WANT TO USE THE SELECT BUTTON DEFAULT ? PLEASE ANSWER "
|
// Input input;
|
||||||
// "YES TO USE SELECT OR NO TO NOT SET A HOTKEY ENABLE BUTTON.",
|
// okFunction();
|
||||||
// "YES", [this, okFunction] {
|
// if (!mTargetConfig->getInputByName("HotKeyEnable", &input)) {
|
||||||
// Input input;
|
// mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(),
|
||||||
// mTargetConfig->getInputByName("Select", &input);
|
// "YOU DIDN'T CHOOSE A HOTKEY ENABLE BUTTON. THIS IS REQUIRED FOR EXITING "
|
||||||
// mTargetConfig->mapInput("HotKeyEnable", input);
|
// "GAMES WITH A CONTROLLER. DO YOU WANT TO USE THE SELECT BUTTON DEFAULT ? "
|
||||||
// okFunction();
|
// "PLEASE ANSWER YES TO USE SELECT OR NO TO NOT SET A HOTKEY ENABLE BUTTON.",
|
||||||
// },
|
// "YES", [this, okFunction] {
|
||||||
// "NO", [this, okFunction] {
|
// Input input;
|
||||||
// // for a disabled hotkey enable button, set to a key with id 0,
|
// mTargetConfig->getInputByName("Select", &input);
|
||||||
// // so the input configuration script can be backwards compatible.
|
// mTargetConfig->mapInput("HotKeyEnable", input);
|
||||||
// mTargetConfig->mapInput("HotKeyEnable", Input(DEVICE_KEYBOARD,
|
// okFunction();
|
||||||
// TYPE_KEY, 0, 1, true));
|
// },
|
||||||
// okFunction();
|
// "NO", [this, okFunction] {
|
||||||
// }
|
// // For a disabled hotkey enable button, set to a key with id 0,
|
||||||
// ));
|
// // so the input configuration script can be backwards compatible.
|
||||||
// }
|
// mTargetConfig->mapInput("HotKeyEnable", Input(DEVICE_KEYBOARD,
|
||||||
// else {
|
// TYPE_KEY, 0, 1, true));
|
||||||
// okFunction();
|
// okFunction();
|
||||||
// }
|
// }));
|
||||||
}));
|
// }
|
||||||
|
// else {
|
||||||
|
// okFunction();
|
||||||
|
// }
|
||||||
|
// }));
|
||||||
|
|
||||||
mButtonGrid = makeButtonGrid(mWindow, buttons);
|
mButtonGrid = makeButtonGrid(mWindow, buttons);
|
||||||
mGrid.setEntry(mButtonGrid, Vector2i(0, 6), true, false);
|
mGrid.setEntry(mButtonGrid, Vector2i(0, 6), true, false);
|
||||||
|
@ -354,8 +364,8 @@ bool GuiInputConfig::assign(Input input, int inputId)
|
||||||
input.configured = true;
|
input.configured = true;
|
||||||
mTargetConfig->mapInput(GUI_INPUT_CONFIG_LIST[inputId].name, input);
|
mTargetConfig->mapInput(GUI_INPUT_CONFIG_LIST[inputId].name, input);
|
||||||
|
|
||||||
LOG(LogInfo) << " Mapping [" << input.string() << "] -> " <<
|
LOG(LogInfo) << "Mapping [" << input.string() << "] to [" <<
|
||||||
GUI_INPUT_CONFIG_LIST[inputId].name;
|
GUI_INPUT_CONFIG_LIST[inputId].name << "]";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue