Step 1: Go back to a single control map.

Break save/load for now, it will be redone.
This commit is contained in:
Henrik Rydgard 2013-08-16 19:34:44 +02:00
parent 33beb57a31
commit f1bc751eb9
7 changed files with 195 additions and 173 deletions

View File

@ -29,58 +29,60 @@ struct DefaultKeyMap {
static KeyMapping defaultKeyboardMap()
{
KeyMapping m;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_A)] = CTRL_SQUARE;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_S)] = CTRL_TRIANGLE;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_X)] = CTRL_CIRCLE;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_Z)] = CTRL_CROSS;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_Q)] = CTRL_LTRIGGER;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_W)] = CTRL_RTRIGGER;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_SPACE)] = CTRL_START;
m[CTRL_SQUARE] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_A);
m[CTRL_TRIANGLE] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_S);
m[CTRL_CIRCLE] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_X);
m[CTRL_CROSS] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_Z);
m[CTRL_LTRIGGER] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_Q);
m[CTRL_RTRIGGER] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_W);
m[CTRL_START] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_SPACE);
#ifdef _WIN32
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_V)] = CTRL_SELECT;
m[CTRL_SELECT] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_V);
#else
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_ENTER)] = CTRL_SELECT;
m[CTRL_SELECT]; = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_ENTER);
#endif
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_UP)] = CTRL_UP;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_DOWN)] = CTRL_DOWN;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_LEFT)] = CTRL_LEFT;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_RIGHT)] = CTRL_RIGHT;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_I)] = VIRTKEY_AXIS_Y_MAX;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_K)] = VIRTKEY_AXIS_Y_MIN;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_J)] = VIRTKEY_AXIS_X_MIN;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_L)] = VIRTKEY_AXIS_X_MAX;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_SHIFT_LEFT)] = VIRTKEY_RAPID_FIRE;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_TAB)] = VIRTKEY_UNTHROTTLE;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_GRAVE)] = VIRTKEY_SPEED_TOGGLE;
m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_ESCAPE)] = VIRTKEY_PAUSE;
m[CTRL_UP ] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_UP) ;
m[CTRL_DOWN ] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_DOWN) ;
m[CTRL_LEFT ] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_LEFT) ;
m[CTRL_RIGHT] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_RIGHT);
m[VIRTKEY_AXIS_Y_MAX] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_I);
m[VIRTKEY_AXIS_Y_MIN] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_K);
m[VIRTKEY_AXIS_X_MIN] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_J);
m[VIRTKEY_AXIS_X_MAX] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_L);
m[VIRTKEY_RAPID_FIRE ] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_SHIFT_LEFT);
m[VIRTKEY_UNTHROTTLE ] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_TAB) ;
m[VIRTKEY_SPEED_TOGGLE] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_GRAVE) ;
m[VIRTKEY_PAUSE ] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_ESCAPE) ;
return m;
}
static KeyMapping default360Map()
{
KeyMapping m;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_A)] = CTRL_CROSS;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_B)] = CTRL_CIRCLE;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_X)] = CTRL_SQUARE;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_Y)] = CTRL_TRIANGLE;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_UP)] = CTRL_UP;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_RIGHT)] = CTRL_RIGHT;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_DOWN)] = CTRL_DOWN;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_LEFT)] = CTRL_LEFT;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_START)] = CTRL_START;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_SELECT)] = CTRL_SELECT;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_L1)] = CTRL_LTRIGGER;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_R1)] = CTRL_RTRIGGER;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_R2)] = VIRTKEY_UNTHROTTLE;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_THUMBR)] = VIRTKEY_PAUSE;
m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_L2)] = VIRTKEY_SPEED_TOGGLE;
m[AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_X, -1)] = VIRTKEY_AXIS_X_MIN;
m[AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_X, +1)] = VIRTKEY_AXIS_X_MAX;
m[AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_Y, -1)] = VIRTKEY_AXIS_Y_MIN;
m[AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_Y, +1)] = VIRTKEY_AXIS_Y_MAX;
m[CTRL_CROSS ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_A) ;
m[CTRL_CIRCLE ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_B) ;
m[CTRL_SQUARE ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_X) ;
m[CTRL_TRIANGLE ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_Y) ;
m[CTRL_UP ] = KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_UP) ;
m[CTRL_RIGHT ] = KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_RIGHT) ;
m[CTRL_DOWN ] = KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_DOWN) ;
m[CTRL_LEFT ] = KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_LEFT) ;
m[CTRL_START ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_START) ;
m[CTRL_SELECT ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_SELECT);
m[CTRL_LTRIGGER ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_L1) ;
m[CTRL_RTRIGGER ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_R1) ;
m[VIRTKEY_UNTHROTTLE ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_R2) ;
m[VIRTKEY_PAUSE ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_THUMBR);
m[VIRTKEY_SPEED_TOGGLE] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_L2) ;
m[VIRTKEY_AXIS_X_MIN ] = AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_X, -1);
m[VIRTKEY_AXIS_X_MAX ] = AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_X, +1);
m[VIRTKEY_AXIS_Y_MIN ] = AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_Y, -1);
m[VIRTKEY_AXIS_Y_MAX ] = AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_Y, +1);
return m;
}
/*
// Not used yet, will autodetect later
static KeyMapping defaultShieldMap()
{
@ -172,11 +174,15 @@ struct DefaultKeyMap {
m[AxisDef(DEVICE_ID_DEFAULT, JOYSTICK_AXIS_Y, +1)] = VIRTKEY_AXIS_Y_MAX;
return m;
}
*/
static std::vector<ControllerMap> init()
static ControllerMap init()
{
std::vector<ControllerMap> m;
ControllerMap m;
m.keys = defaultKeyboardMap();
/*
#if defined(USING_GLES2)
// Mobile! Only a pad map required, some can use a keyboard map though.
// Currently no way to distinguish between external keyboard and qwerty keyboard ('pad'?)
@ -217,13 +223,17 @@ struct DefaultKeyMap {
pad.active = false;
m.push_back(pad);
#endif
*/
return m;
}
static std::vector<ControllerMap> KeyMap;
static ControllerMap KeyMap;
};
std::vector<ControllerMap> DefaultKeyMap::KeyMap = DefaultKeyMap::init();
ControllerMap DefaultKeyMap::KeyMap = DefaultKeyMap::init();
ControllerMap g_controllerMap;
// Key & Button names
@ -231,6 +241,7 @@ struct KeyMap_IntStrPair {
int key;
std::string name;
};
const KeyMap_IntStrPair key_names[] = {
{NKCODE_A, "A"},
{NKCODE_B, "B"},
@ -433,6 +444,7 @@ const KeyMap_IntStrPair axis_names[] = {
};
static std::string unknown_key_name = "??";
const KeyMap_IntStrPair psp_button_names[] = {
{CTRL_CIRCLE, "O"},
{CTRL_CROSS, "X"},
@ -465,8 +477,7 @@ const KeyMap_IntStrPair psp_button_names[] = {
const int AXIS_BIND_NKCODE_START = 4000;
static std::string FindName(int key, const KeyMap_IntStrPair list[], size_t size)
{
static std::string FindName(int key, const KeyMap_IntStrPair list[], size_t size) {
for (size_t i = 0; i < size; i++)
if (list[i].key == key)
return list[i].name;
@ -474,18 +485,23 @@ static std::string FindName(int key, const KeyMap_IntStrPair list[], size_t size
return unknown_key_name;
}
std::string GetKeyName(int keyCode)
{
std::string GetKeyName(int keyCode) {
return FindName(keyCode, key_names, ARRAY_SIZE(key_names));
}
std::string GetPspButtonName(int btn)
{
std::string GetPspButtonName(int btn) {
return FindName(btn, psp_button_names, ARRAY_SIZE(psp_button_names));
}
int TranslateKeyCodeToAxis(int keyCode, int &direction)
{
std::vector<KeyMap_IntStrPair> GetMappableKeys() {
std::vector<KeyMap_IntStrPair> temp;
for (size_t i = 0; i < ARRAY_SIZE(psp_button_names); i++) {
temp.push_back(psp_button_names[i]);
}
return temp;
}
int TranslateKeyCodeToAxis(int keyCode, int &direction) {
if (keyCode < AXIS_BIND_NKCODE_START)
return 0;
int v = keyCode - AXIS_BIND_NKCODE_START;
@ -495,8 +511,7 @@ int TranslateKeyCodeToAxis(int keyCode, int &direction)
return v / 2;
}
int TranslateKeyCodeFromAxis(int axisId, int direction)
{
int TranslateKeyCodeFromAxis(int axisId, int direction) {
direction = direction < 0 ? 1 : 0;
return AXIS_BIND_NKCODE_START + axisId * 2 + direction;
}
@ -505,16 +520,11 @@ KeyDef AxisDef(int deviceId, int axisId, int direction) {
return KeyDef(deviceId, TranslateKeyCodeFromAxis(axisId, direction));
}
static bool FindKeyMapping(int deviceId, int key, int *psp_button)
{
for (size_t i = 0; i < controllerMaps.size(); i++) {
if (!controllerMaps[i].active)
continue;
auto iter = controllerMaps[i].keys.find(KeyDef(deviceId, key));
if (iter != controllerMaps[i].keys.end()) {
*psp_button = iter->second;
static bool FindKeyMapping(int deviceId, int key, int *psp_button) {
// Brute force, let's optimize later
for (auto iter = g_controllerMap.keys.begin(); iter != g_controllerMap.keys.end(); ++iter) {
if (iter->second == KeyDef(deviceId, key)) {
*psp_button = iter->first;
return true;
}
}
@ -532,130 +542,126 @@ int KeyToPspButton(int deviceId, int key)
return KEYMAP_ERROR_UNKNOWN_KEY;
}
bool KeyFromPspButton(int controllerMap, int btn, int *deviceId, int *keyCode)
// TODO: vector output
bool KeyFromPspButton(int btn, int *deviceId, int *keyCode)
{
int search_start_layer = 0;
for (auto iter = controllerMaps[controllerMap].keys.begin(); iter != controllerMaps[controllerMap].keys.end(); ++iter) {
if (iter->second == btn) {
*deviceId = iter->first.deviceId;
*keyCode = iter->first.keyCode;
for (auto iter = g_controllerMap.keys.begin(); iter != g_controllerMap.keys.end(); ++iter) {
if (iter->first == btn) {
*deviceId = iter->second.deviceId;
*keyCode = iter->second.keyCode;
return true;
}
}
return false;
}
int AxisToPspButton(int deviceId, int axisId, int direction)
{
int AxisToPspButton(int deviceId, int axisId, int direction) {
int key = TranslateKeyCodeFromAxis(axisId, direction);
return KeyToPspButton(deviceId, key);
}
bool AxisFromPspButton(int controllerMap, int btn, int *deviceId, int *axisId, int *direction)
{
bool AxisFromPspButton(int btn, int *deviceId, int *axisId, int *direction) {
int search_start_layer = 0;
for (auto iter = controllerMaps[controllerMap].keys.begin(); iter != controllerMaps[controllerMap].keys.end(); ++iter) {
if (iter->second == btn && iter->first.keyCode >= AXIS_BIND_NKCODE_START) {
*deviceId = iter->first.deviceId;
*axisId = TranslateKeyCodeToAxis(iter->first.keyCode, *direction);
for (auto iter = g_controllerMap.keys.begin(); iter != g_controllerMap.keys.end(); ++iter) {
if (iter->first == btn && iter->second.keyCode >= AXIS_BIND_NKCODE_START) {
*deviceId = iter->second.deviceId;
*axisId = TranslateKeyCodeToAxis(iter->second.keyCode, *direction);
return true;
}
}
return false;
}
std::string NameKeyFromPspButton(int controllerMap, int btn) {
std::string NameKeyFromPspButton(int btn) {
int deviceId;
int axisId;
int direction;
int keyCode;
if (AxisFromPspButton(controllerMap, btn, &deviceId, &axisId, &direction)) {
if (AxisFromPspButton(btn, &deviceId, &axisId, &direction)) {
return GetAxisName(axisId) + (direction < 0 ? "-" : "+");
}
if (KeyFromPspButton(controllerMap, btn, &deviceId, &keyCode)) {
if (KeyFromPspButton(btn, &deviceId, &keyCode)) {
return GetKeyName(keyCode);
}
return "unknown";
}
std::string NameDeviceFromPspButton(int controllerMap, int btn) {
std::string NameDeviceFromPspButton(int btn) {
int deviceId;
int axisId;
int direction;
int keyCode;
if (AxisFromPspButton(controllerMap, btn, &deviceId, &axisId, &direction)) {
if (AxisFromPspButton(btn, &deviceId, &axisId, &direction)) {
return GetDeviceName(deviceId);
}
if (KeyFromPspButton(controllerMap, btn, &deviceId, &keyCode)) {
if (KeyFromPspButton(btn, &deviceId, &keyCode)) {
return GetDeviceName(deviceId);
}
return "unknown";
}
bool IsMappedKey(int deviceId, int key)
{
bool IsMappedKey(int deviceId, int key) {
return KeyToPspButton(deviceId, key) != KEYMAP_ERROR_UNKNOWN_KEY;
}
std::string NamePspButtonFromKey(int deviceId, int key)
{
std::string NamePspButtonFromKey(int deviceId, int key) {
return GetPspButtonName(KeyToPspButton(deviceId, key));
}
void RemoveButtonMapping(int map, int btn) {
for (auto iter = controllerMaps[map].keys.begin(); iter != controllerMaps[map].keys.end(); ++iter) {
if (iter->second == btn) {
controllerMaps[map].keys.erase(iter);
void RemoveButtonMapping(int btn) {
for (auto iter = g_controllerMap.keys.begin(); iter != g_controllerMap.keys.end(); ++iter) {
if (iter->first == btn) {
g_controllerMap.keys.erase(iter);
return;
}
}
}
void SetKeyMapping(int map, int deviceId, int key, int btn)
{
RemoveButtonMapping(map, btn);
controllerMaps[map].keys[KeyDef(deviceId, key)] = btn;
void SetKeyMapping(int deviceId, int key, int btn) {
RemoveButtonMapping(btn);
g_controllerMap.keys[btn] = KeyDef(deviceId, key);
}
std::string GetAxisName(int axisId)
{
std::string GetAxisName(int axisId) {
return FindName(axisId, axis_names, ARRAY_SIZE(axis_names));
}
bool IsMappedAxis(int deviceId, int axisId, int direction)
{
bool IsMappedAxis(int deviceId, int axisId, int direction) {
int key = TranslateKeyCodeFromAxis(axisId, direction);
return KeyToPspButton(deviceId, key) != KEYMAP_ERROR_UNKNOWN_KEY;
}
std::string NamePspButtonFromAxis(int deviceId, int axisId, int direction)
{
std::string NamePspButtonFromAxis(int deviceId, int axisId, int direction) {
int key = TranslateKeyCodeFromAxis(axisId, direction);
return GetPspButtonName(KeyToPspButton(deviceId, key));
}
void SetAxisMapping(int map, int deviceId, int axisId, int direction, int btn)
{
void SetAxisMapping(int deviceId, int axisId, int direction, int btn) {
int key = TranslateKeyCodeFromAxis(axisId, direction);
SetKeyMapping(map, deviceId, key, btn);
SetKeyMapping(deviceId, key, btn);
}
void RestoreDefault() {
controllerMaps = DefaultKeyMap::KeyMap;
g_controllerMap = DefaultKeyMap::KeyMap;
}
// TODO: Make the ini format nicer.
void LoadFromIni(IniFile &file) {
if (!file.HasSection("ControlMapping")) {
controllerMaps = DefaultKeyMap::KeyMap;
g_controllerMap = DefaultKeyMap::KeyMap;
return;
}
controllerMaps.clear();
g_controllerMap.keys.clear();
IniFile::Section *controls = file.GetOrCreateSection("ControlMapping");
/*
std::vector<std::string> maps;
controls->Get("ControllerMaps", maps);
if (!maps.size()) {
@ -680,11 +686,13 @@ void LoadFromIni(IniFile &file) {
newMap.keys[KeyDef(deviceId, keyCode)] = atoi(x->second.c_str());
}
controllerMaps.push_back(newMap);
}
}*/
}
void SaveToIni(IniFile &file) {
IniFile::Section *controls = file.GetOrCreateSection("ControlMapping");
/*
std::vector<std::string> maps;
for (auto x = controllerMaps.begin(); x != controllerMaps.end(); ++x) {
maps.push_back(x->name);
@ -702,9 +710,7 @@ void SaveToIni(IniFile &file) {
sprintf(value, "%i", iter->second);
map->Set(key, value);
}
}
}*/
}
} // KeyMap
std::vector<ControllerMap> controllerMaps = KeyMap::DefaultKeyMap::KeyMap;

View File

@ -48,6 +48,7 @@ const float AXIS_BIND_THRESHOLD = 0.75f;
class KeyDef {
public:
KeyDef() : deviceId(0), keyCode(0) {}
KeyDef(int devId, int k) : deviceId(devId), keyCode(k) {}
int deviceId;
int keyCode;
@ -58,29 +59,40 @@ public:
if (keyCode < other.keyCode) return true;
return false;
}
bool operator == (const KeyDef &other) const {
if (deviceId != other.deviceId) return false;
if (keyCode != other.keyCode) return false;
return true;
}
};
struct AxisPos {
int axis;
float position;
bool operator < (const AxisPos &other) const {
if (axis < other.axis) return true;
if (axis > other.axis) return false;
return position < other.position;
}
bool operator == (const AxisPos &other) const {
return axis == other.axis && position == other.position;
}
};
typedef std::map<KeyDef, int> KeyMapping;
typedef std::map<KeyDef, AxisPos> AxisMapping;
typedef std::map<int, KeyDef> KeyMapping;
// These are for speed only, built from the regular ones. For the future.
// typedef std::map<int, KeyDef> KeyMapping;
// Multiple maps can be active at the same time.
class ControllerMap {
public:
ControllerMap() : active(true) {}
bool active;
struct ControllerMap {
KeyMapping keys;
AxisMapping axis; // TODO
std::string name;
};
extern std::vector<ControllerMap> controllerMaps;
extern ControllerMap g_controllerMap;
// KeyMap
// A translation layer for key assignment. Provides
@ -113,26 +125,28 @@ namespace KeyMap {
// about mapping conflicts
std::string NamePspButtonFromKey(int deviceId, int key);
bool KeyFromPspButton(int controllerMap, int btn, int *deviceId, int *keyCode);
std::string NameKeyFromPspButton(int controllerMap, int btn);
std::string NameDeviceFromPspButton(int controllerMap, int btn);
bool KeyFromPspButton(int btn, int *deviceId, int *keyCode);
std::string NameKeyFromPspButton(int btn);
std::string NameDeviceFromPspButton(int btn);
// Configure the key mapping.
// Any configuration will be saved to the Core config.
void SetKeyMapping(int map, int deviceId, int keyCode, int psp_key);
void SetKeyMapping(int deviceId, int keyCode, int psp_key);
std::string GetAxisName(int axisId);
int AxisToPspButton(int deviceId, int axisId, int direction);
bool AxisFromPspButton(int controllerMap, int btn, int *deviceId, int *axisId, int *direction);
bool AxisFromPspButton(int btn, int *deviceId, int *axisId, int *direction);
bool IsMappedAxis(int deviceId, int axisId, int direction);
std::string NamePspButtonFromAxis(int deviceId, int axisId, int direction);
// Configure an axis mapping, saves the configuration.
// Direction is negative or positive.
void SetAxisMapping(int map, int deviceId, int axisId, int direction, int btn);
void SetAxisMapping(int deviceId, int axisId, int direction, int btn);
void LoadFromIni(IniFile &iniFile);
void SaveToIni(IniFile &iniFile);
void RestoreDefault();
void QuickMap(int device);
}

View File

@ -33,9 +33,10 @@ extern bool isJailed;
Config::Config() { }
Config::~Config() { }
void Config::Load(const char *iniFileName)
void Config::Load(const char *iniFileName, const char *controllerIniFilename)
{
iniFilename_ = iniFileName;
controllerIniFilename_ = controllerIniFilename;
INFO_LOG(LOADER, "Loading config: %s", iniFileName);
bSaveSettings = true;
@ -188,7 +189,16 @@ void Config::Load(const char *iniFileName)
IniFile::Section *gleshacks = iniFile.GetOrCreateSection("GLESHacks");
gleshacks->Get("PrescaleUV", &bPrescaleUV, false);
KeyMap::LoadFromIni(iniFile);
INFO_LOG(LOADER, "Loading controller config: %s", controllerIniFilename);
bSaveSettings = true;
IniFile controllerIniFile;
if (!controllerIniFile.Load(controllerIniFilename)) {
ERROR_LOG(LOADER, "Failed to read %s. Setting controller config to default.", controllerIniFilename);
}
// Continue anyway to initialize the config. It will just restore the defaults.
KeyMap::LoadFromIni(controllerIniFile);
CleanRecent();
}
@ -305,14 +315,26 @@ void Config::Save()
debugConfig->Set("FontWidth", iFontWidth);
debugConfig->Set("FontHeight", iFontHeight);
debugConfig->Set("DisplayStatusBar", bDisplayStatusBar);
KeyMap::SaveToIni(iniFile);
if (!iniFile.Save(iniFilename_.c_str())) {
ERROR_LOG(LOADER, "Error saving config - can't write ini %s", iniFilename_.c_str());
return;
}
INFO_LOG(LOADER, "Config saved: %s", iniFilename_.c_str());
IniFile controllerIniFile;
if (!controllerIniFile.Load(controllerIniFilename_.c_str())) {
ERROR_LOG(LOADER, "Error saving config - can't read ini %s", controllerIniFilename_.c_str());
} else {
KeyMap::SaveToIni(controllerIniFile);
}
if (!controllerIniFile.Save(controllerIniFilename_.c_str())) {
ERROR_LOG(LOADER, "Error saving config - can't write ini %s", controllerIniFilename_.c_str());
return;
}
INFO_LOG(LOADER, "Controller config saved: %s", controllerIniFilename_.c_str());
} else {
INFO_LOG(LOADER, "Not saving config");
}

View File

@ -162,7 +162,7 @@ public:
std::string flashDirectory;
std::string internalDataDirectory;
void Load(const char *iniFileName = "ppsspp.ini");
void Load(const char *iniFileName = "ppsspp.ini", const char *controllerIniFilename = "controls.ini");
void Save();
// Utility functions for "recent" management
@ -171,6 +171,7 @@ public:
private:
std::string iniFilename_;
std::string controllerIniFilename_;
};
extern Config g_Config;

View File

@ -51,18 +51,14 @@ void KeyMappingScreen::render() {
#define KeyBtn(x, y, symbol) \
if (UIButton(GEN_ID, Pos(x, y), 90, 0, KeyMap::NameKeyFromPspButton(currentMap_, symbol).c_str(), \
if (UIButton(GEN_ID, Pos(x, y), 90, 0, KeyMap::NameKeyFromPspButton(symbol).c_str(), \
ALIGN_TOPLEFT)) {\
screenManager()->push(new KeyMappingNewKeyDialog(symbol, currentMap_), 0); \
screenManager()->push(new KeyMappingNewKeyDialog(symbol), 0); \
UIReset(); \
} \
UIText(0, Pos(x+30, y+50), KeyMap::NameDeviceFromPspButton(currentMap_, symbol).c_str(), 0xFFFFFFFF, 0.7f, ALIGN_HCENTER); \
UIText(0, Pos(x+30, y+50), KeyMap::NameDeviceFromPspButton(symbol).c_str(), 0xFFFFFFFF, 0.7f, ALIGN_HCENTER); \
UIText(0, Pos(x+30, y+80), KeyMap::GetPspButtonName(symbol).c_str(), 0xFFFFFFFF, 0.5f, ALIGN_HCENTER); \
// \
// UIText(0, Pos(x, y+50), controllerMaps[currentMap_].name.c_str(), 0xFFFFFFFF, 0.5f, ALIGN_HCENTER);
int pad = 130;
int hlfpad = pad / 2;
@ -114,20 +110,6 @@ void KeyMappingScreen::render() {
screenManager()->finishDialog(this, DR_OK);
}
if (UIButton(GEN_ID, Pos(10, dp_yres-10), LARGE_BUTTON_WIDTH, 0, generalI18N->T("Prev"), ALIGN_BOTTOMLEFT)) {
currentMap_--;
if (currentMap_ < 0)
currentMap_ = (int)controllerMaps.size() - 1;
}
if (UIButton(GEN_ID, Pos(10 + 10 + LARGE_BUTTON_WIDTH, dp_yres-10), LARGE_BUTTON_WIDTH, 0, generalI18N->T("Next"), ALIGN_BOTTOMLEFT)) {
currentMap_++;
if (currentMap_ >= (int)controllerMaps.size())
currentMap_ = 0;
}
char temp[256];
sprintf(temp, "%s (%i/%i)", controllerMaps[currentMap_].name.c_str(), currentMap_ + 1, (int)controllerMaps.size());
UIText(0, Pos(10, dp_yres-170), temp, 0xFFFFFFFF, 1.0f, ALIGN_BOTTOMLEFT);
UICheckBox(GEN_ID,10, dp_yres - 80, keyI18N->T("Mapping Active"), ALIGN_BOTTOMLEFT, &controllerMaps[currentMap_].active);
UIEnd();
}
@ -141,8 +123,8 @@ void KeyMappingNewKeyDialog::CreatePopupContents(UI::ViewGroup *parent) {
parent->Add(new TextView(std::string(keyI18N->T("Map a new key for ")) + pspButtonName));
std::string buttonKey = KeyMap::NameKeyFromPspButton(currentMap_, this->pspBtn_);
std::string buttonDevice = KeyMap::NameDeviceFromPspButton(currentMap_, this->pspBtn_);
std::string buttonKey = KeyMap::NameKeyFromPspButton(this->pspBtn_);
std::string buttonDevice = KeyMap::NameDeviceFromPspButton(this->pspBtn_);
parent->Add(new TextView(std::string(keyI18N->T("Previous:")) + " " + buttonKey + " - " + buttonDevice));
}
@ -156,7 +138,7 @@ void KeyMappingNewKeyDialog::key(const KeyInput &key) {
last_kb_key_ = key.keyCode;
last_axis_id_ = -1;
KeyMap::SetKeyMapping(currentMap_, last_kb_deviceid_, last_kb_key_, pspBtn_);
KeyMap::SetKeyMapping(last_kb_deviceid_, last_kb_key_, pspBtn_);
screenManager()->finishDialog(this, DR_OK);
}
}
@ -167,7 +149,7 @@ void KeyMappingNewKeyDialog::axis(const AxisInput &axis) {
last_axis_id_ = axis.axisId;
last_axis_direction_ = 1;
last_kb_key_ = 0;
KeyMap::SetAxisMapping(currentMap_, last_axis_deviceid_, last_axis_id_, last_axis_direction_, pspBtn_);
KeyMap::SetAxisMapping(last_axis_deviceid_, last_axis_id_, last_axis_direction_, pspBtn_);
screenManager()->finishDialog(this, DR_OK);
}
@ -176,7 +158,7 @@ void KeyMappingNewKeyDialog::axis(const AxisInput &axis) {
last_axis_id_ = axis.axisId;
last_axis_direction_ = -1;
last_kb_key_ = 0;
KeyMap::SetAxisMapping(currentMap_, last_axis_deviceid_, last_axis_id_, last_axis_direction_, pspBtn_);
KeyMap::SetAxisMapping(last_axis_deviceid_, last_axis_id_, last_axis_direction_, pspBtn_);
screenManager()->finishDialog(this, DR_OK);
}
}

View File

@ -20,23 +20,20 @@
class KeyMappingScreen : public Screen {
public:
KeyMappingScreen() : currentMap_(0) {}
KeyMappingScreen() : Screen() {}
void update(InputState &input);
void render();
private:
int currentMap_;
};
// Dialog box, meant to be pushed
class KeyMappingNewKeyDialog : public PopupScreen {
public:
KeyMappingNewKeyDialog(int btn, int currentMap) : PopupScreen("Map Key") {
explicit KeyMappingNewKeyDialog(int btn) : PopupScreen("Map Key") {
pspBtn_ = btn;
last_kb_deviceid_ = 0;
last_kb_key_ = 0;
last_axis_deviceid_ = 0;
last_axis_id_ = -1;
currentMap_ = currentMap;
}
void key(const KeyInput &key);
@ -56,5 +53,4 @@ private:
int last_axis_deviceid_;
int last_axis_id_;
int last_axis_direction_;
int currentMap_;
};

View File

@ -260,22 +260,23 @@ void GameSettingsScreen::CreateViews() {
atracString.assign(Atrac3plus_Decoder::IsInstalled() ? "Redownload Atrac3+ plugin" : "Download Atrac3+ plugin");
audioSettings->Add(new Choice(a->T(atracString.c_str())))->OnClick.Handle(this, &GameSettingsScreen::OnDownloadPlugin);
audioSettings->Add(new CheckBox(&g_Config.bEnableSound, a->T("Enable Sound")));
audioSettings->Add(new CheckBox(&g_Config.bEnableAtrac3plus, a->T("Enable Atrac3+")));
audioSettings->Add(new PopupSliderChoice(&g_Config.iSFXVolume, 0, 8, a->T("SFX volume"), screenManager()));
audioSettings->Add(new PopupSliderChoice(&g_Config.iBGMVolume, 0, 8, a->T("BGM volume"), screenManager()));
audioSettings->Add(new CheckBox(&g_Config.bEnableSound, a->T("Enable Sound")));
audioSettings->Add(new CheckBox(&g_Config.bEnableAtrac3plus, a->T("Enable Atrac3+")));
// Control
ViewGroup *controlsSettingsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
ViewGroup *controlsSettings = new LinearLayout(ORIENT_VERTICAL);
controlsSettingsScroll->Add(controlsSettings);
tabHolder->AddTab(ms->T("Controls"), controlsSettingsScroll);
controlsSettings->Add(new CheckBox(&g_Config.bShowTouchControls, c->T("OnScreen", "On-Screen Touch Controls")));
controlsSettings->Add(new CheckBox(&g_Config.bShowAnalogStick, c->T("Show Left Analog Stick")));
controlsSettings->Add(new CheckBox(&g_Config.bAccelerometerToAnalogHoriz, c->T("Tilt", "Tilt to Analog (horizontal)")));
controlsSettings->Add(new Choice(gs->T("Control Mapping")))->OnClick.Handle(this, &GameSettingsScreen::OnControlMapping);
controlsSettings->Add(new CheckBox(&g_Config.bShowTouchControls, c->T("OnScreen", "On-Screen Touch Controls")));
controlsSettings->Add(new PopupSliderChoice(&g_Config.iTouchButtonOpacity, 0, 85, c->T("Button Opacity"), screenManager()));
controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fButtonScale, 1.15, 2.05, c->T("Button Scaling"), screenManager()));
controlsSettings->Add(new CheckBox(&g_Config.bShowAnalogStick, c->T("Show Left Analog Stick")));
controlsSettings->Add(new CheckBox(&g_Config.bAccelerometerToAnalogHoriz, c->T("Tilt", "Tilt to Analog (horizontal)")));
// System
ViewGroup *systemSettingsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
@ -283,16 +284,16 @@ void GameSettingsScreen::CreateViews() {
systemSettingsScroll->Add(systemSettings);
tabHolder->AddTab(ms->T("System"), systemSettingsScroll);
systemSettings->Add(new CheckBox(&g_Config.bJit, s->T("Dynarec", "Dynarec (JIT)")));
systemSettings->Add(new CheckBox(&g_Config.bSeparateCPUThread, s->T("Multithreaded (experimental)")));
systemSettings->Add(new CheckBox(&g_Config.bFastMemory, s->T("Fast Memory", "Fast Memory (Unstable)")));
systemSettings->Add(new PopupSliderChoice(&g_Config.iLockedCPUSpeed, 0, 1000, gs->T("Unlock CPU Clock"), screenManager()));
systemSettings->Add(new CheckBox(&g_Config.bSeparateCPUThread, s->T("Multithreaded (experimental)")));
systemSettings->Add(new PopupSliderChoice(&g_Config.iLockedCPUSpeed, 0, 1000, gs->T("Change CPU Clock", "Change CPU Clock (0 = default)"), screenManager()));
systemSettings->Add(new CheckBox(&g_Config.bDayLightSavings, s->T("Day Light Saving")));
static const char *dateFormat[] = { "YYYYMMDD", "MMDDYYYY", "DDMMYYYY"};
systemSettings->Add(new PopupMultiChoice(&g_Config.iDateFormat, gs->T("Date Format"), dateFormat, 1, 3, s, screenManager()));
static const char *timeFormat[] = { "12HR", "24HR"};
systemSettings->Add(new PopupMultiChoice(&g_Config.iTimeFormat, gs->T("Time Format"), timeFormat, 1, 2, s, screenManager()));
static const char *buttonPref[] = { "Use X to confirm", "Use O to confirm"};
systemSettings->Add(new PopupMultiChoice(&g_Config.iButtonPreference, gs->T("Button Preference"), buttonPref, 1, 2, s, screenManager()));
systemSettings->Add(new PopupMultiChoice(&g_Config.iButtonPreference, gs->T("Confirmation Button"), buttonPref, 1, 2, s, screenManager()));
}
void DrawBackground(float alpha);