mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-23 16:19:44 +00:00
Get basic axis mapping working.
This commit is contained in:
parent
613b9ec994
commit
8e5d115c8e
@ -329,7 +329,35 @@ const KeyMap_IntStrPair key_names[] = {
|
||||
{KEYCODE_NUMPAD_9, "Num9"},
|
||||
};
|
||||
|
||||
static int key_names_count = sizeof(key_names) / sizeof(key_names[0]);
|
||||
const KeyMap_IntStrPair axis_names[] = {
|
||||
{JOYSTICK_AXIS_X, "X Axis"},
|
||||
{JOYSTICK_AXIS_Y, "Y Axis"},
|
||||
{JOYSTICK_AXIS_PRESSURE, "Pressure"},
|
||||
{JOYSTICK_AXIS_SIZE, "Size"},
|
||||
{JOYSTICK_AXIS_TOUCH_MAJOR, "Touch Major"},
|
||||
{JOYSTICK_AXIS_TOUCH_MINOR, "Touch Minor"},
|
||||
{JOYSTICK_AXIS_TOOL_MAJOR, "Tool Major"},
|
||||
{JOYSTICK_AXIS_TOOL_MINOR, "Tool Minor"},
|
||||
{JOYSTICK_AXIS_ORIENTATION, "Orient"},
|
||||
{JOYSTICK_AXIS_VSCROLL, "Vert Scroll"},
|
||||
{JOYSTICK_AXIS_HSCROLL, "Horiz Scroll"},
|
||||
{JOYSTICK_AXIS_Z, "Z Axis"},
|
||||
{JOYSTICK_AXIS_RX, "X Rotation"},
|
||||
{JOYSTICK_AXIS_RY, "Y Rotation"},
|
||||
{JOYSTICK_AXIS_RZ, "Z Rotation"},
|
||||
{JOYSTICK_AXIS_HAT_X, "X HAT"},
|
||||
{JOYSTICK_AXIS_HAT_Y, "Y HAT"},
|
||||
{JOYSTICK_AXIS_LTRIGGER, "TriggerL"},
|
||||
{JOYSTICK_AXIS_RTRIGGER, "TriggerR"},
|
||||
{JOYSTICK_AXIS_THROTTLE, "Throttle"},
|
||||
{JOYSTICK_AXIS_RUDDER, "Rudder"},
|
||||
{JOYSTICK_AXIS_WHEEL, "Wheel"},
|
||||
{JOYSTICK_AXIS_GAS, "Gas"},
|
||||
{JOYSTICK_AXIS_BRAKE, "Brake"},
|
||||
{JOYSTICK_AXIS_DISTANCE, "Distance"},
|
||||
{JOYSTICK_AXIS_TILT, "Tilt"}
|
||||
};
|
||||
|
||||
static std::string unknown_key_name = "??";
|
||||
const KeyMap_IntStrPair psp_button_names[] = {
|
||||
{CTRL_CIRCLE, "O"},
|
||||
@ -356,11 +384,11 @@ const KeyMap_IntStrPair psp_button_names[] = {
|
||||
{VIRTKEY_PAUSE, "Pause"},
|
||||
};
|
||||
|
||||
static int psp_button_names_count = sizeof(psp_button_names) / sizeof(psp_button_names[0]);
|
||||
const int AXIS_BIND_KEYCODE_START = 4000;
|
||||
|
||||
static std::string FindName(int key, const KeyMap_IntStrPair list[], int size)
|
||||
static std::string FindName(int key, const KeyMap_IntStrPair list[], size_t size)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
for (size_t i = 0; i < size; i++)
|
||||
if (list[i].key == key)
|
||||
return list[i].name;
|
||||
|
||||
@ -369,12 +397,29 @@ static std::string FindName(int key, const KeyMap_IntStrPair list[], int size)
|
||||
|
||||
std::string GetKeyName(int keyCode)
|
||||
{
|
||||
return FindName(keyCode, key_names, key_names_count);
|
||||
return FindName(keyCode, key_names, ARRAY_SIZE(key_names));
|
||||
}
|
||||
|
||||
std::string GetPspButtonName(int btn)
|
||||
{
|
||||
return FindName(btn, psp_button_names, psp_button_names_count);
|
||||
return FindName(btn, psp_button_names, ARRAY_SIZE(psp_button_names));
|
||||
}
|
||||
|
||||
int TranslateKeyCodeToAxis(int keyCode, int &direction)
|
||||
{
|
||||
if (keyCode < AXIS_BIND_KEYCODE_START)
|
||||
return 0;
|
||||
int v = keyCode - AXIS_BIND_KEYCODE_START;
|
||||
|
||||
// Even/odd for direction.
|
||||
direction = v & 1 ? -1 : 1;
|
||||
return v / 2;
|
||||
}
|
||||
|
||||
int TranslateKeyCodeFromAxis(int axisId, int direction)
|
||||
{
|
||||
direction = direction < 0 ? 1 : 0;
|
||||
return AXIS_BIND_KEYCODE_START + axisId * 2 + direction;
|
||||
}
|
||||
|
||||
static bool FindKeyMapping(int deviceId, int key, int *psp_button)
|
||||
@ -417,9 +462,34 @@ bool KeyFromPspButton(int controllerMap, int btn, int *deviceId, int *keyCode)
|
||||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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_KEYCODE_START) {
|
||||
*deviceId = iter->first.deviceId;
|
||||
*axisId = TranslateKeyCodeToAxis(iter->first.keyCode, *direction);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string NameKeyFromPspButton(int controllerMap, int btn) {
|
||||
int deviceId;
|
||||
int axisId;
|
||||
int direction;
|
||||
int keyCode;
|
||||
if (AxisFromPspButton(controllerMap, btn, &deviceId, &axisId, &direction)) {
|
||||
return GetAxisName(axisId) + (direction < 0 ? "-" : "+");
|
||||
}
|
||||
if (KeyFromPspButton(controllerMap, btn, &deviceId, &keyCode)) {
|
||||
return GetKeyName(keyCode);
|
||||
}
|
||||
@ -428,7 +498,12 @@ std::string NameKeyFromPspButton(int controllerMap, int btn) {
|
||||
|
||||
std::string NameDeviceFromPspButton(int controllerMap, int btn) {
|
||||
int deviceId;
|
||||
int axisId;
|
||||
int direction;
|
||||
int keyCode;
|
||||
if (AxisFromPspButton(controllerMap, btn, &deviceId, &axisId, &direction)) {
|
||||
return GetDeviceName(deviceId);
|
||||
}
|
||||
if (KeyFromPspButton(controllerMap, btn, &deviceId, &keyCode)) {
|
||||
return GetDeviceName(deviceId);
|
||||
}
|
||||
@ -446,7 +521,7 @@ std::string NamePspButtonFromKey(int deviceId, int key)
|
||||
}
|
||||
|
||||
void RemoveButtonMapping(int map, int btn) {
|
||||
for (auto iter = controllerMaps[map].keys.begin(); iter != controllerMaps[map].keys.end(); ++iter) {
|
||||
for (auto iter = controllerMaps[map].keys.begin(); iter != controllerMaps[map].keys.end(); ++iter) {
|
||||
if (iter->second == btn) {
|
||||
controllerMaps[map].keys.erase(iter);
|
||||
return;
|
||||
@ -460,6 +535,29 @@ void SetKeyMapping(int map, int deviceId, int key, int btn)
|
||||
controllerMaps[map].keys[KeyDef(deviceId, key)] = btn;
|
||||
}
|
||||
|
||||
std::string GetAxisName(int axisId)
|
||||
{
|
||||
return FindName(axisId, axis_names, ARRAY_SIZE(axis_names));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int key = TranslateKeyCodeFromAxis(axisId, direction);
|
||||
return GetPspButtonName(KeyToPspButton(deviceId, key));
|
||||
}
|
||||
|
||||
void SetAxisMapping(int map, int deviceId, int axisId, int direction, int btn)
|
||||
{
|
||||
int key = TranslateKeyCodeFromAxis(axisId, direction);
|
||||
SetKeyMapping(map, deviceId, key, btn);
|
||||
}
|
||||
|
||||
void RestoreDefault() {
|
||||
controllerMaps = DefaultKeyMap::KeyMap;
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ enum {
|
||||
VIRTKEY_COUNT = VIRTKEY_LAST - VIRTKEY_FIRST
|
||||
};
|
||||
|
||||
const float AXIS_BIND_THRESHOLD = 0.75f;
|
||||
|
||||
class KeyDef {
|
||||
public:
|
||||
KeyDef(int devId, int k) : deviceId(devId), keyCode(k) {}
|
||||
@ -115,6 +117,16 @@ namespace KeyMap {
|
||||
// Any configuration will be saved to the Core config.
|
||||
void SetKeyMapping(int map, 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 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 LoadFromIni(IniFile &iniFile);
|
||||
void SaveToIni(IniFile &iniFile);
|
||||
void RestoreDefault();
|
||||
|
@ -219,31 +219,52 @@ void EmuScreen::key(const KeyInput &key) {
|
||||
if (result == KEYMAP_ERROR_UNKNOWN_KEY)
|
||||
return;
|
||||
|
||||
if (result >= VIRTKEY_FIRST) {
|
||||
int vk = result - VIRTKEY_FIRST;
|
||||
if (key.flags & KEY_DOWN) {
|
||||
pspKey(result, key.flags);
|
||||
}
|
||||
|
||||
void EmuScreen::pspKey(int pspKeyCode, int flags) {
|
||||
if (pspKeyCode >= VIRTKEY_FIRST) {
|
||||
int vk = pspKeyCode - VIRTKEY_FIRST;
|
||||
if (flags & KEY_DOWN) {
|
||||
virtKeys[vk] = true;
|
||||
onVKeyDown(result);
|
||||
onVKeyDown(pspKeyCode);
|
||||
}
|
||||
if (key.flags & KEY_UP) {
|
||||
if (flags & KEY_UP) {
|
||||
virtKeys[vk] = false;
|
||||
onVKeyUp(result);
|
||||
onVKeyUp(pspKeyCode);
|
||||
}
|
||||
} else {
|
||||
if (key.flags & KEY_DOWN)
|
||||
__CtrlButtonDown(result);
|
||||
if (key.flags & KEY_UP)
|
||||
__CtrlButtonUp(result);
|
||||
if (flags & KEY_DOWN)
|
||||
__CtrlButtonDown(pspKeyCode);
|
||||
if (flags & KEY_UP)
|
||||
__CtrlButtonUp(pspKeyCode);
|
||||
}
|
||||
}
|
||||
|
||||
void EmuScreen::axis(const AxisInput &axis) {
|
||||
// TODO: Apply some form of axis mapping
|
||||
switch (axis.axisId) {
|
||||
case JOYSTICK_AXIS_X: analog_[0].x = axis.value; break;
|
||||
case JOYSTICK_AXIS_Y: analog_[0].y = axis.value; break;
|
||||
case JOYSTICK_AXIS_Z: analog_[1].x = axis.value; break;
|
||||
case JOYSTICK_AXIS_RZ: analog_[1].y = axis.value; break;
|
||||
int result = KeyMap::AxisToPspButton(axis.deviceId, axis.axisId, axis.value >= 0 ? 1 : -1);
|
||||
if (result == KEYMAP_ERROR_UNKNOWN_KEY)
|
||||
return;
|
||||
|
||||
switch (result) {
|
||||
case VIRTKEY_AXIS_X_MIN:
|
||||
case VIRTKEY_AXIS_X_MAX:
|
||||
analog_[0].x = axis.value;
|
||||
break;
|
||||
|
||||
case VIRTKEY_AXIS_Y_MIN:
|
||||
case VIRTKEY_AXIS_Y_MAX:
|
||||
analog_[0].y = axis.value;
|
||||
break;
|
||||
|
||||
// TODO: right stick.
|
||||
|
||||
default:
|
||||
if (axis.value >= AXIS_BIND_THRESHOLD || axis.value <= -AXIS_BIND_THRESHOLD) {
|
||||
pspKey(result, KEY_DOWN);
|
||||
} else {
|
||||
pspKey(result, KEY_UP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
virtual void axis(const AxisInput &axis);
|
||||
|
||||
private:
|
||||
void pspKey(int pspKeyCode, int flags);
|
||||
void onVKeyDown(int virtualKeyCode);
|
||||
void onVKeyUp(int virtualKeyCode);
|
||||
|
||||
|
@ -690,6 +690,22 @@ void KeyMappingNewKeyDialog::key(const KeyInput &key) {
|
||||
if (key.flags & KEY_DOWN) {
|
||||
last_kb_deviceid = key.deviceId;
|
||||
last_kb_key = key.keyCode;
|
||||
last_axis_id = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void KeyMappingNewKeyDialog::axis(const AxisInput &axis) {
|
||||
if (axis.value > AXIS_BIND_THRESHOLD) {
|
||||
last_axis_deviceid = axis.deviceId;
|
||||
last_axis_id = axis.axisId;
|
||||
last_axis_direction = 1;
|
||||
last_kb_key = 0;
|
||||
}
|
||||
if (axis.value < -AXIS_BIND_THRESHOLD) {
|
||||
last_axis_deviceid = axis.deviceId;
|
||||
last_axis_id = axis.axisId;
|
||||
last_axis_direction = -1;
|
||||
last_kb_key = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1682,16 +1698,29 @@ void KeyMappingNewKeyDialog::render() {
|
||||
KeyScale(1.4f);
|
||||
KeyText(right, top, keyI18N->T("New Key"));
|
||||
KeyScale(2.0f);
|
||||
if (last_kb_key != 0) {
|
||||
if (last_axis_id != -1) {
|
||||
const std::string axis_direction_name = KeyMap::GetAxisName(last_axis_id) + (last_axis_direction < 0 ? "-" : "+");
|
||||
KeyText(right, top += stride, axis_direction_name.c_str());
|
||||
KeyScale(1.4f);
|
||||
KeyText(right, top + stride, GetDeviceName(last_axis_deviceid));
|
||||
bool key_used = KeyMap::IsMappedAxis(last_axis_deviceid, last_axis_id, last_axis_direction);
|
||||
if (key_used) {
|
||||
KeyScale(1.0f);
|
||||
KeyText(left + stride, top + 2*stride,
|
||||
keyI18N->T("Warning: Key is already used by"));
|
||||
KeyText(left + stride, top + 3*stride,
|
||||
(KeyMap::NamePspButtonFromAxis(last_axis_deviceid, last_axis_id, last_axis_direction)).c_str());
|
||||
}
|
||||
} else if (last_kb_key != 0) {
|
||||
KeyText(right, top += stride, KeyMap::GetKeyName(last_kb_key).c_str());
|
||||
KeyScale(1.4f);
|
||||
KeyText(right, top + stride, GetDeviceName(last_kb_deviceid));
|
||||
bool key_used = KeyMap::IsMappedKey(last_kb_deviceid, last_kb_key);
|
||||
if (key_used) {
|
||||
KeyScale(1.0f);
|
||||
KeyText(left + stride, top + 2*stride,
|
||||
keyI18N->T("Warning: Key is already used by"));
|
||||
KeyText(left + stride, top + 3*stride,
|
||||
KeyText(left + stride, top + 2*stride,
|
||||
keyI18N->T("Warning: Key is already used by"));
|
||||
KeyText(left + stride, top + 3*stride,
|
||||
(KeyMap::NamePspButtonFromKey(last_kb_deviceid, last_kb_key)).c_str());
|
||||
}
|
||||
}
|
||||
@ -1702,7 +1731,10 @@ void KeyMappingNewKeyDialog::render() {
|
||||
|
||||
// Save & cancel buttons
|
||||
if (UIButton(GEN_ID, Pos(10, dp_yres - 10), LARGE_BUTTON_WIDTH, 0, keyI18N->T("Save Mapping"), ALIGN_LEFT | ALIGN_BOTTOM)) {
|
||||
KeyMap::SetKeyMapping(currentMap_, last_kb_deviceid, last_kb_key, pspBtn);
|
||||
if (last_axis_id != -1)
|
||||
KeyMap::SetAxisMapping(currentMap_, last_axis_deviceid, last_axis_id, last_axis_direction, pspBtn);
|
||||
else
|
||||
KeyMap::SetKeyMapping(currentMap_, last_kb_deviceid, last_kb_key, pspBtn);
|
||||
g_Config.Save();
|
||||
screenManager()->finishDialog(this, DR_OK);
|
||||
}
|
||||
|
@ -150,16 +150,22 @@ public:
|
||||
pspBtn = btn;
|
||||
last_kb_deviceid = 0;
|
||||
last_kb_key = 0;
|
||||
last_axis_deviceid = 0;
|
||||
last_axis_id = -1;
|
||||
currentMap_ = currentMap;
|
||||
}
|
||||
void update(InputState &input);
|
||||
void render();
|
||||
void key(const KeyInput &key);
|
||||
void axis(const AxisInput &axis);
|
||||
|
||||
private:
|
||||
int pspBtn;
|
||||
int last_kb_deviceid;
|
||||
int last_kb_key;
|
||||
int last_axis_deviceid;
|
||||
int last_axis_id;
|
||||
int last_axis_direction;
|
||||
int currentMap_;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user