From 8e5d115c8ecc83bcc91feb4640613f8e0e261ed6 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Jul 2013 15:21:40 -0700 Subject: [PATCH 01/13] Get basic axis mapping working. --- Common/KeyMap.cpp | 112 ++++++++++++++++++++++++++++++++++++++++++--- Common/KeyMap.h | 12 +++++ UI/EmuScreen.cpp | 53 ++++++++++++++------- UI/EmuScreen.h | 1 + UI/MenuScreens.cpp | 42 +++++++++++++++-- UI/MenuScreens.h | 6 +++ 6 files changed, 198 insertions(+), 28 deletions(-) diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index 0ad3bdcd12..907f058823 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -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; } diff --git a/Common/KeyMap.h b/Common/KeyMap.h index 9c2e2a6448..1f12a5bf2c 100644 --- a/Common/KeyMap.h +++ b/Common/KeyMap.h @@ -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(); diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 9ea5a07588..7ff2abbb8c 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -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); + } } } diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index 5ba91af12e..2c3a09910d 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -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); diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index aa1d0c9d76..1186dda7b0 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -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); } diff --git a/UI/MenuScreens.h b/UI/MenuScreens.h index fa80e040a1..4276cf7570 100644 --- a/UI/MenuScreens.h +++ b/UI/MenuScreens.h @@ -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_; }; From fb2ca2bb825c0c1ad8af7ff68f0cebd31cb4dea1 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Jul 2013 15:26:38 -0700 Subject: [PATCH 02/13] Add default mappings for left analog sticks. --- Common/KeyMap.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index 907f058823..3ff6f91eb2 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -22,6 +22,8 @@ namespace KeyMap { +KeyDef AxisDef(int deviceId, int axisId, int direction); + // TODO: Make use const_map.h from native struct DefaultKeyMap { static KeyMapping defaultKeyboardMap() @@ -72,6 +74,10 @@ struct DefaultKeyMap { m[KeyDef(DEVICE_ID_X360_0, KEYCODE_BUTTON_R2)] = VIRTKEY_UNTHROTTLE; m[KeyDef(DEVICE_ID_X360_0, KEYCODE_BUTTON_THUMBR)] = VIRTKEY_PAUSE; m[KeyDef(DEVICE_ID_X360_0, KEYCODE_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; return m; } @@ -90,6 +96,10 @@ struct DefaultKeyMap { m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BACK)] = CTRL_SELECT; m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_L1)] = CTRL_LTRIGGER; m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_R1)] = CTRL_RTRIGGER; + m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_X, -1)] = VIRTKEY_AXIS_X_MIN; + m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_X, +1)] = VIRTKEY_AXIS_X_MAX; + m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_Y, -1)] = VIRTKEY_AXIS_Y_MIN; + m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_Y, +1)] = VIRTKEY_AXIS_Y_MAX; return m; } @@ -108,6 +118,10 @@ struct DefaultKeyMap { m[KeyDef(DEVICE_ID_DEFAULT, KEYCODE_BACK)] = CTRL_SELECT; m[KeyDef(DEVICE_ID_DEFAULT, KEYCODE_BUTTON_L1)] = CTRL_LTRIGGER; m[KeyDef(DEVICE_ID_DEFAULT, KEYCODE_BUTTON_R1)] = CTRL_RTRIGGER; + m[AxisDef(DEVICE_ID_DEFAULT, JOYSTICK_AXIS_X, -1)] = VIRTKEY_AXIS_X_MIN; + m[AxisDef(DEVICE_ID_DEFAULT, JOYSTICK_AXIS_X, +1)] = VIRTKEY_AXIS_X_MAX; + m[AxisDef(DEVICE_ID_DEFAULT, JOYSTICK_AXIS_Y, -1)] = VIRTKEY_AXIS_Y_MIN; + m[AxisDef(DEVICE_ID_DEFAULT, JOYSTICK_AXIS_Y, +1)] = VIRTKEY_AXIS_Y_MAX; return m; } @@ -422,6 +436,11 @@ int TranslateKeyCodeFromAxis(int axisId, int direction) return AXIS_BIND_KEYCODE_START + axisId * 2 + direction; } +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++) { From 4541a79d549247e17b30dae0f9eb8791704d8992 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Jul 2013 16:09:06 -0700 Subject: [PATCH 03/13] Send only changed analog sticks in dinput. --- Windows/DinputDevice.cpp | 265 ++++----------------------------------- Windows/DinputDevice.h | 4 + 2 files changed, 31 insertions(+), 238 deletions(-) diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp index b2940155df..a680a9dc8f 100644 --- a/Windows/DinputDevice.cpp +++ b/Windows/DinputDevice.cpp @@ -51,12 +51,7 @@ static const int dinput_buttons[] = { KEYCODE_BUTTON_Z, }; -struct Stick { - float x; - float y; -}; - -static Stick NormalizedDeadzoneFilter(short x, short y); +static float NormalizedDeadzoneFilter(short value); #define DIFF (JOY_POVRIGHT - JOY_POVFORWARD) / 2 #define JOY_POVFORWARD_RIGHT JOY_POVFORWARD + DIFF @@ -87,6 +82,10 @@ DinputDevice::DinputDevice() { pDI = NULL; memset(lastButtons_, 0, sizeof(lastButtons_)); memset(lastPOV_, 0, sizeof(lastPOV_)); + last_lX_ = 0; + last_lY_ = 0; + last_lZ_ = 0; + last_lRz_ = 0; if(FAILED(DirectInput8Create(GetModuleHandle(NULL),DIRECTINPUT_VERSION,IID_IDirectInput8,(void**)&pDI,NULL))) return; @@ -148,6 +147,19 @@ DinputDevice::~DinputDevice() { } } +void SendNativeAxis(int deviceId, short value, short &lastValue, int axisId) { + if (value == lastValue) + return; + + AxisInput axis; + axis.deviceId = deviceId; + axis.axisId = axisId; + axis.value = NormalizedDeadzoneFilter(value); + NativeAxis(axis); + + lastValue = value; +} + int DinputDevice::UpdateState(InputState &input_state) { if (!pJoystick) return -1; @@ -164,47 +176,25 @@ int DinputDevice::UpdateState(InputState &input_state) { ApplyButtons(js, input_state); if (analog) { - Stick left = NormalizedDeadzoneFilter(js.lX, js.lY); - Stick right = NormalizedDeadzoneFilter(js.lZ, js.lRz); - - input_state.pad_lstick_x += left.x; - input_state.pad_lstick_y += left.y; - input_state.pad_rstick_x += right.x; - input_state.pad_rstick_y += right.y; - AxisInput axis; axis.deviceId = DEVICE_ID_PAD_0; - axis.axisId = JOYSTICK_AXIS_X; - axis.value = left.x; - NativeAxis(axis); - - axis.axisId = JOYSTICK_AXIS_Y; - axis.value = left.y; - NativeAxis(axis); - - axis.axisId = JOYSTICK_AXIS_Z; - axis.value = right.x; - NativeAxis(axis); - - axis.axisId = JOYSTICK_AXIS_RZ; - axis.value = right.y; - NativeAxis(axis); + SendNativeAxis(DEVICE_ID_PAD_0, js.lX, last_lX_, JOYSTICK_AXIS_X); + SendNativeAxis(DEVICE_ID_PAD_0, js.lY, last_lY_, JOYSTICK_AXIS_Y); + SendNativeAxis(DEVICE_ID_PAD_0, js.lZ, last_lZ_, JOYSTICK_AXIS_Z); + SendNativeAxis(DEVICE_ID_PAD_0, js.lRz, last_lRz_, JOYSTICK_AXIS_RZ); } return UPDATESTATE_SKIP_PAD; } -static Stick NormalizedDeadzoneFilter(short x, short y) { - Stick s; - s.x = (float)x / 10000.f; - s.y = -((float)y / 10000.f); +static float NormalizedDeadzoneFilter(short value) { + float result = (float)value / 10000.0f; - // Expand and clamp. Hack to let us reach the corners on most pads. - s.x = std::min(1.0f, std::max(-1.0f, s.x * 1.2f)); - s.y = std::min(1.0f, std::max(-1.0f, s.y * 1.2f)); + // Expand and clamp. Hack to let us reach the corners on most pads. + result = std::min(1.0f, std::max(result * 1.2f, -1.0f)); - return s; + return result; } void DinputDevice::ApplyButtons(DIJOYSTATE2 &state, InputState &input_state) { @@ -261,206 +251,5 @@ void DinputDevice::ApplyButtons(DIJOYSTATE2 &state, InputState &input_state) { lastPOV_[0] = LOWORD(state.rgdwPOV[0]); } - - // TODO: Remove this once proper analog stick - // binding is implemented. - const LONG rthreshold = 8000; - - KeyInput RAS; - RAS.deviceId = DEVICE_ID_PAD_0; - switch (g_Config.iRightStickBind) { - case 0: - break; - case 1: - if(!g_Config.iSwapRightAxes) { - if (state.lRz > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_DPAD_RIGHT; - NativeKey(RAS); - } - else if (state.lRz < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_DPAD_LEFT; - NativeKey(RAS); - } - if (state.lZ > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_DPAD_DOWN; - NativeKey(RAS); - } - else if (state.lZ < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_DPAD_UP; - NativeKey(RAS); - } - } - else { - if (state.lX > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_DPAD_RIGHT; - NativeKey(RAS); - } - else if (state.lZ < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_DPAD_LEFT; - NativeKey(RAS); - } - if (state.lRz > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_DPAD_UP; - NativeKey(RAS); - } - else if (state.lRz < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_DPAD_DOWN; - NativeKey(RAS); - } - } - break; - case 2: - if(!g_Config.iSwapRightAxes) { - if (state.lRz > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_B; - NativeKey(RAS); - } - else if (state.lRz < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_X; - NativeKey(RAS); - } - if (state.lZ > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_Y; - NativeKey(RAS); - } - else if (state.lZ < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_A; - NativeKey(RAS); - } - } - else { - if (state.lZ > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_B; - NativeKey(RAS); - } - else if (state.lZ < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_X; - NativeKey(RAS); - } - if (state.lRz > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_Y; - NativeKey(RAS); - } - else if (state.lRz < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = RAS.keyCode = KEYCODE_BUTTON_A; - NativeKey(RAS); - } - } - break; - case 3: - if(!g_Config.iSwapRightAxes) { - if (state.lRz > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_R1; - NativeKey(RAS); - } - else if (state.lRz < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_L1; - NativeKey(RAS); - } - } - else { - if (state.lZ > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_R1; - NativeKey(RAS); - } - else if (state.lZ < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_L1; - NativeKey(RAS); - } - } - break; - case 4: - if(!g_Config.iSwapRightAxes) { - if (state.lRz > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_R1; - NativeKey(RAS); - } - else if (state.lRz < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_L1; - NativeKey(RAS); - } - if (state.lZ > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_Y; - NativeKey(RAS); - } - else if (state.lZ < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_A; - NativeKey(RAS); - } - } - else { - if (state.lZ > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_R1; - NativeKey(RAS); - } - else if (state.lZ < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_L1; - NativeKey(RAS); - } - if (state.lRz > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_BUTTON_Y; - NativeKey(RAS); - } - else if (state.lRz < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = RAS.keyCode = KEYCODE_BUTTON_A; - NativeKey(RAS); - } - } - break; - case 5: - if(!g_Config.iSwapRightAxes) { - if (state.lRz > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_DPAD_RIGHT; - NativeKey(RAS); - } - else if (state.lRz < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_DPAD_LEFT; - NativeKey(RAS); - } - } - else { - if (state.lZ > rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_DPAD_LEFT; - NativeKey(RAS); - } - else if (state.lZ < -rthreshold) { - RAS.flags = KEY_DOWN; - RAS.keyCode = KEYCODE_DPAD_RIGHT; - NativeKey(RAS); - } - } - break; - } } diff --git a/Windows/DinputDevice.h b/Windows/DinputDevice.h index a2d9c14e0e..978aff62e6 100644 --- a/Windows/DinputDevice.h +++ b/Windows/DinputDevice.h @@ -37,4 +37,8 @@ private: bool analog; BYTE lastButtons_[128]; WORD lastPOV_[4]; + short last_lX_; + short last_lY_; + short last_lZ_; + short last_lRz_; }; From 5f382c5ab04fbcfbbae57f5f41eb271e0f5ffb1b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Jul 2013 16:09:20 -0700 Subject: [PATCH 04/13] Unpress the reverse direction, avoids sticking. --- UI/EmuScreen.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 7ff2abbb8c..0760861bec 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -262,6 +262,11 @@ void EmuScreen::axis(const AxisInput &axis) { default: if (axis.value >= AXIS_BIND_THRESHOLD || axis.value <= -AXIS_BIND_THRESHOLD) { pspKey(result, KEY_DOWN); + + // Also unpress the other direction. + result = KeyMap::AxisToPspButton(axis.deviceId, axis.axisId, axis.value >= 0 ? -1 : 1); + if (result != KEYMAP_ERROR_UNKNOWN_KEY) + pspKey(result, KEY_UP); } else { pspKey(result, KEY_UP); } From e45863cb87e65d2edbd2f7a6d04d5c198869685a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Jul 2013 16:14:28 -0700 Subject: [PATCH 05/13] Support binding analog backwards. --- UI/EmuScreen.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 0760861bec..803c1439e2 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -248,13 +248,19 @@ void EmuScreen::axis(const AxisInput &axis) { switch (result) { case VIRTKEY_AXIS_X_MIN: + analog_[0].x = -fabs(axis.value); + break; + case VIRTKEY_AXIS_X_MAX: - analog_[0].x = axis.value; + analog_[0].x = fabs(axis.value); break; case VIRTKEY_AXIS_Y_MIN: + analog_[0].y = -fabs(axis.value); + break; + case VIRTKEY_AXIS_Y_MAX: - analog_[0].y = axis.value; + analog_[0].y = fabs(axis.value); break; // TODO: right stick. From fc5009472591f4038a4c97c0575f7b8c52956491 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Jul 2013 16:16:51 -0700 Subject: [PATCH 06/13] Add back the right stick, but no UI. Not sure where to fit it... --- Common/KeyMap.cpp | 5 +++++ Common/KeyMap.h | 4 ++++ UI/EmuScreen.cpp | 16 +++++++++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index 3ff6f91eb2..c34b4e7266 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -392,6 +392,11 @@ const KeyMap_IntStrPair psp_button_names[] = { {VIRTKEY_AXIS_Y_MIN, "An.Down"}, {VIRTKEY_AXIS_Y_MAX, "An.Up"}, + {VIRTKEY_AXIS_RIGHT_X_MIN, "RightAn.Left"}, + {VIRTKEY_AXIS_RIGHT_X_MAX, "RightAn.Right"}, + {VIRTKEY_AXIS_RIGHT_Y_MIN, "RightAn.Down"}, + {VIRTKEY_AXIS_RIGHT_Y_MAX, "RightAn.Up"}, + {VIRTKEY_RAPID_FIRE, "RapidFire"}, {VIRTKEY_UNTHROTTLE, "Unthrottle"}, {VIRTKEY_SPEED_TOGGLE, "SpeedToggle"}, diff --git a/Common/KeyMap.h b/Common/KeyMap.h index 1f12a5bf2c..ae6a47e796 100644 --- a/Common/KeyMap.h +++ b/Common/KeyMap.h @@ -36,6 +36,10 @@ enum { VIRTKEY_UNTHROTTLE = 0x10005, VIRTKEY_PAUSE = 0x10006, VIRTKEY_SPEED_TOGGLE = 0x10007, + VIRTKEY_AXIS_RIGHT_X_MIN = 0x10008, + VIRTKEY_AXIS_RIGHT_Y_MIN = 0x10009, + VIRTKEY_AXIS_RIGHT_X_MAX = 0x1000a, + VIRTKEY_AXIS_RIGHT_Y_MAX = 0x1000b, VIRTKEY_LAST, VIRTKEY_COUNT = VIRTKEY_LAST - VIRTKEY_FIRST }; diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 803c1439e2..7e7d6fd907 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -263,7 +263,21 @@ void EmuScreen::axis(const AxisInput &axis) { analog_[0].y = fabs(axis.value); break; - // TODO: right stick. + case VIRTKEY_AXIS_RIGHT_X_MIN: + analog_[1].x = -fabs(axis.value); + break; + + case VIRTKEY_AXIS_RIGHT_X_MAX: + analog_[1].x = fabs(axis.value); + break; + + case VIRTKEY_AXIS_RIGHT_Y_MIN: + analog_[1].y = -fabs(axis.value); + break; + + case VIRTKEY_AXIS_RIGHT_Y_MAX: + analog_[1].y = fabs(axis.value); + break; default: if (axis.value >= AXIS_BIND_THRESHOLD || axis.value <= -AXIS_BIND_THRESHOLD) { From 82442fa68a5b5f71d65dea7c203b47f65f250188 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Jul 2013 16:25:15 -0700 Subject: [PATCH 07/13] Cut down on analog stick latency. --- UI/EmuScreen.cpp | 96 +++++++++++++++++++++++++++++++----------------- UI/EmuScreen.h | 3 -- 2 files changed, 63 insertions(+), 36 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 7e7d6fd907..903cbb102b 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -107,7 +107,6 @@ EmuScreen::EmuScreen(const std::string &filename) : invalid_(true) { osm.Show(s->T("PressESC", "Press ESC to open the pause menu"), 3.0f); } #endif - memset(analog_, 0, sizeof(analog_)); memset(&fakeInputState, 0, sizeof(fakeInputState)); memset(virtKeys, 0, sizeof(virtKeys)); } @@ -204,11 +203,54 @@ void EmuScreen::onVKeyDown(int virtualKeyCode) { fbo_unbind(); screenManager()->push(new PauseScreen()); break; + + case VIRTKEY_AXIS_X_MIN: + __CtrlSetAnalogX(-1.0f, CTRL_STICK_LEFT); + break; + case VIRTKEY_AXIS_X_MAX: + __CtrlSetAnalogX(1.0f, CTRL_STICK_LEFT); + break; + case VIRTKEY_AXIS_Y_MIN: + __CtrlSetAnalogY(-1.0f, CTRL_STICK_LEFT); + break; + case VIRTKEY_AXIS_Y_MAX: + __CtrlSetAnalogY(1.0f, CTRL_STICK_LEFT); + break; + + case VIRTKEY_AXIS_RIGHT_X_MIN: + __CtrlSetAnalogX(-1.0f, CTRL_STICK_RIGHT); + break; + case VIRTKEY_AXIS_RIGHT_X_MAX: + __CtrlSetAnalogX(1.0f, CTRL_STICK_RIGHT); + break; + case VIRTKEY_AXIS_RIGHT_Y_MIN: + __CtrlSetAnalogY(-1.0f, CTRL_STICK_RIGHT); + break; + case VIRTKEY_AXIS_RIGHT_Y_MAX: + __CtrlSetAnalogY(1.0f, CTRL_STICK_RIGHT); + break; } } void EmuScreen::onVKeyUp(int virtualKeyCode) { switch (virtualKeyCode) { + case VIRTKEY_AXIS_X_MIN: + case VIRTKEY_AXIS_X_MAX: + __CtrlSetAnalogX(0.0f, CTRL_STICK_LEFT); + break; + case VIRTKEY_AXIS_Y_MIN: + case VIRTKEY_AXIS_Y_MAX: + __CtrlSetAnalogY(0.0f, CTRL_STICK_LEFT); + break; + + case VIRTKEY_AXIS_RIGHT_X_MIN: + case VIRTKEY_AXIS_RIGHT_X_MAX: + __CtrlSetAnalogX(0.0f, CTRL_STICK_RIGHT); + break; + case VIRTKEY_AXIS_RIGHT_Y_MIN: + case VIRTKEY_AXIS_RIGHT_Y_MAX: + __CtrlSetAnalogY(0.0f, CTRL_STICK_RIGHT); + break; default: break; } @@ -248,35 +290,29 @@ void EmuScreen::axis(const AxisInput &axis) { switch (result) { case VIRTKEY_AXIS_X_MIN: - analog_[0].x = -fabs(axis.value); + __CtrlSetAnalogX(-fabs(axis.value), CTRL_STICK_LEFT); break; - case VIRTKEY_AXIS_X_MAX: - analog_[0].x = fabs(axis.value); + __CtrlSetAnalogX(fabs(axis.value), CTRL_STICK_LEFT); break; - case VIRTKEY_AXIS_Y_MIN: - analog_[0].y = -fabs(axis.value); + __CtrlSetAnalogY(-fabs(axis.value), CTRL_STICK_LEFT); break; - case VIRTKEY_AXIS_Y_MAX: - analog_[0].y = fabs(axis.value); + __CtrlSetAnalogY(fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_RIGHT_X_MIN: - analog_[1].x = -fabs(axis.value); + __CtrlSetAnalogX(-fabs(axis.value), CTRL_STICK_RIGHT); break; - case VIRTKEY_AXIS_RIGHT_X_MAX: - analog_[1].x = fabs(axis.value); + __CtrlSetAnalogX(fabs(axis.value), CTRL_STICK_RIGHT); break; - case VIRTKEY_AXIS_RIGHT_Y_MIN: - analog_[1].y = -fabs(axis.value); + __CtrlSetAnalogY(-fabs(axis.value), CTRL_STICK_RIGHT); break; - case VIRTKEY_AXIS_RIGHT_Y_MAX: - analog_[1].y = fabs(axis.value); + __CtrlSetAnalogY(fabs(axis.value), CTRL_STICK_RIGHT); break; default: @@ -323,20 +359,12 @@ void EmuScreen::update(InputState &input) { if (invalid_) return; - float leftstick_x = analog_[0].x; - float leftstick_y = analog_[0].y; - float rightstick_x = analog_[1].x; - float rightstick_y = analog_[1].y; + float leftstick_x = 0.0f; + float leftstick_y = 0.0f; + float rightstick_x = 0.0f; + float rightstick_y = 0.0f; // Virtual keys. - if (virtKeys[VIRTKEY_AXIS_X_MIN - VIRTKEY_FIRST]) - leftstick_x -= 1.0f; - if (virtKeys[VIRTKEY_AXIS_X_MAX - VIRTKEY_FIRST]) - leftstick_x += 1.0f; - if (virtKeys[VIRTKEY_AXIS_Y_MIN - VIRTKEY_FIRST]) - leftstick_y -= 1.0f; - if (virtKeys[VIRTKEY_AXIS_Y_MAX - VIRTKEY_FIRST]) - leftstick_y += 1.0f; __CtrlSetRapidFire(virtKeys[VIRTKEY_RAPID_FIRE - VIRTKEY_FIRST]); // First translate touches into native pad input. @@ -374,6 +402,13 @@ void EmuScreen::update(InputState &input) { rightstick_x += fakeInputState.pad_rstick_x; rightstick_y += fakeInputState.pad_rstick_y; + if (g_Config.bShowAnalogStick) { + __CtrlSetAnalogX(clamp1(leftstick_x), CTRL_STICK_LEFT); + __CtrlSetAnalogY(clamp1(leftstick_y), CTRL_STICK_LEFT); + } + __CtrlSetAnalogX(clamp1(rightstick_x), CTRL_STICK_RIGHT); + __CtrlSetAnalogY(clamp1(rightstick_y), CTRL_STICK_RIGHT); + // Also send the special buttons to input, since that's where they're handled. input.pad_buttons_down |= fakeInputState.pad_buttons_down & (PAD_BUTTON_MENU | PAD_BUTTON_BACK | PAD_BUTTON_RIGHT_THUMB | PAD_BUTTON_LEFT_THUMB); input.pad_buttons_up |= fakeInputState.pad_buttons_up & (PAD_BUTTON_MENU | PAD_BUTTON_BACK | PAD_BUTTON_RIGHT_THUMB | PAD_BUTTON_LEFT_THUMB); @@ -390,14 +425,9 @@ void EmuScreen::update(InputState &input) { if (g_Config.bAccelerometerToAnalogHoriz) { // TODO: Deadzone, etc. leftstick_x += clamp1(curve1(input.acc.y) * 2.0f); - leftstick_x = clamp1(leftstick_x); + __CtrlSetAnalogX(clamp1(leftstick_x), CTRL_STICK_LEFT); } - __CtrlSetAnalogX(clamp1(leftstick_x), CTRL_STICK_LEFT); - __CtrlSetAnalogY(clamp1(leftstick_y), CTRL_STICK_LEFT); - __CtrlSetAnalogX(clamp1(rightstick_x), CTRL_STICK_RIGHT); - __CtrlSetAnalogY(clamp1(rightstick_y), CTRL_STICK_RIGHT); - // Make sure fpsLimit starts at 0 if (PSP_CoreParameter().fpsLimit != 0 && PSP_CoreParameter().fpsLimit != 1 && PSP_CoreParameter().fpsLimit != 2) { PSP_CoreParameter().fpsLimit = 0; diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index 2c3a09910d..422468d05a 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -51,9 +51,6 @@ private: // For the virtual touch buttons, that currently can't send key events. InputState fakeInputState; - // Analog is still buffered. - struct {float x, y;} analog_[2]; - // To track mappable virtual keys. We can have as many as we want. bool virtKeys[VIRTKEY_COUNT]; }; From 4f93d57186e54c6978cea341f9ff087c6677ba34 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Jul 2013 16:28:36 -0700 Subject: [PATCH 08/13] Add a few more dinput axises since it's easy. --- Windows/DinputDevice.cpp | 4 ++++ Windows/DinputDevice.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp index a680a9dc8f..4a95ca375f 100644 --- a/Windows/DinputDevice.cpp +++ b/Windows/DinputDevice.cpp @@ -85,6 +85,8 @@ DinputDevice::DinputDevice() { last_lX_ = 0; last_lY_ = 0; last_lZ_ = 0; + last_lRx_ = 0; + last_lRy_ = 0; last_lRz_ = 0; if(FAILED(DirectInput8Create(GetModuleHandle(NULL),DIRECTINPUT_VERSION,IID_IDirectInput8,(void**)&pDI,NULL))) @@ -182,6 +184,8 @@ int DinputDevice::UpdateState(InputState &input_state) { SendNativeAxis(DEVICE_ID_PAD_0, js.lX, last_lX_, JOYSTICK_AXIS_X); SendNativeAxis(DEVICE_ID_PAD_0, js.lY, last_lY_, JOYSTICK_AXIS_Y); SendNativeAxis(DEVICE_ID_PAD_0, js.lZ, last_lZ_, JOYSTICK_AXIS_Z); + SendNativeAxis(DEVICE_ID_PAD_0, js.lRx, last_lRx_, JOYSTICK_AXIS_RX); + SendNativeAxis(DEVICE_ID_PAD_0, js.lRy, last_lRy_, JOYSTICK_AXIS_RY); SendNativeAxis(DEVICE_ID_PAD_0, js.lRz, last_lRz_, JOYSTICK_AXIS_RZ); } diff --git a/Windows/DinputDevice.h b/Windows/DinputDevice.h index 978aff62e6..fe2d5d9aee 100644 --- a/Windows/DinputDevice.h +++ b/Windows/DinputDevice.h @@ -40,5 +40,7 @@ private: short last_lX_; short last_lY_; short last_lZ_; + short last_lRx_; + short last_lRy_; short last_lRz_; }; From d9bfcce0de9d89f9c181234ae448b24f13ddb50e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Jul 2013 17:02:12 -0700 Subject: [PATCH 09/13] Switch to buttons instead of A/B/X/Y for dinput. This way people don't say "but my X button shows up as L1." --- Common/KeyMap.cpp | 16 ++++++++-------- Windows/DinputDevice.cpp | 29 ++++++++++++++++------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index c34b4e7266..d350842775 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -84,18 +84,18 @@ struct DefaultKeyMap { static KeyMapping defaultPadMap() { KeyMapping m; - m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_A)] = CTRL_CROSS; - m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_B)] = CTRL_CIRCLE; - m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_X)] = CTRL_SQUARE; - m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_Y)] = CTRL_TRIANGLE; + m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_2)] = CTRL_CROSS; + m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_3)] = CTRL_CIRCLE; + m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_4)] = CTRL_SQUARE; + m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_1)] = CTRL_TRIANGLE; m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_DPAD_UP)] = CTRL_UP; m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_DPAD_RIGHT)] = CTRL_RIGHT; m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_DPAD_DOWN)] = CTRL_DOWN; m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_DPAD_LEFT)] = CTRL_LEFT; - m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_START)] = CTRL_START; - m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BACK)] = CTRL_SELECT; - m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_L1)] = CTRL_LTRIGGER; - m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_R1)] = CTRL_RTRIGGER; + m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_10)] = CTRL_START; + m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_9)] = CTRL_SELECT; + m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_7)] = CTRL_LTRIGGER; + m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_8)] = CTRL_RTRIGGER; m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_X, -1)] = VIRTKEY_AXIS_X_MIN; m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_X, +1)] = VIRTKEY_AXIS_X_MAX; m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_Y, -1)] = VIRTKEY_AXIS_Y_MIN; diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp index 4a95ca375f..7f6fd0f378 100644 --- a/Windows/DinputDevice.cpp +++ b/Windows/DinputDevice.cpp @@ -36,19 +36,22 @@ // In order from 0. There can be 128, but most controllers do not have that many. static const int dinput_buttons[] = { - KEYCODE_BUTTON_Y, - KEYCODE_BUTTON_A, - KEYCODE_BUTTON_B, - KEYCODE_BUTTON_X, - KEYCODE_BUTTON_L2, - KEYCODE_BUTTON_R2, - KEYCODE_BUTTON_L1, - KEYCODE_BUTTON_R1, - KEYCODE_BUTTON_SELECT, - KEYCODE_BUTTON_START, - KEYCODE_BUTTON_THUMBL, - KEYCODE_BUTTON_THUMBR, - KEYCODE_BUTTON_Z, + KEYCODE_BUTTON_1, + KEYCODE_BUTTON_2, + KEYCODE_BUTTON_3, + KEYCODE_BUTTON_4, + KEYCODE_BUTTON_5, + KEYCODE_BUTTON_6, + KEYCODE_BUTTON_7, + KEYCODE_BUTTON_8, + KEYCODE_BUTTON_9, + KEYCODE_BUTTON_10, + KEYCODE_BUTTON_11, + KEYCODE_BUTTON_12, + KEYCODE_BUTTON_13, + KEYCODE_BUTTON_14, + KEYCODE_BUTTON_15, + KEYCODE_BUTTON_16, }; static float NormalizedDeadzoneFilter(short value); From cb1b1164d1dd4868e0590cca7ad3788c70aaf0a4 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Jul 2013 17:18:02 -0700 Subject: [PATCH 10/13] Only send XInput analog on change. --- Windows/XinputDevice.cpp | 84 ++++++++++++---------------------------- 1 file changed, 25 insertions(+), 59 deletions(-) diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index 47d2435217..c65e6846e1 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -66,35 +66,36 @@ int XinputDevice::UpdateState(InputState &input_state) { if ( dwResult == ERROR_SUCCESS ) { ApplyButtons(state, input_state); - Stick left = NormalizedDeadzoneFilter(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY); - Stick right = NormalizedDeadzoneFilter(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY); - input_state.pad_lstick_x += left.x; - input_state.pad_lstick_y += left.y; - input_state.pad_rstick_x += right.x; - input_state.pad_rstick_y += right.y; - // Also convert the analog triggers. - input_state.pad_ltrigger = state.Gamepad.bLeftTrigger / 255.0f; - input_state.pad_rtrigger = state.Gamepad.bRightTrigger / 255.0f; + if (prevState.Gamepad.sThumbLX != state.Gamepad.sThumbLX || prevState.Gamepad.sThumbLY != state.Gamepad.sThumbLY) { + Stick left = NormalizedDeadzoneFilter(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY); + + AxisInput axis; + axis.deviceId = DEVICE_ID_X360_0; + axis.axisId = JOYSTICK_AXIS_X; + axis.value = left.x; + NativeAxis(axis); + axis.axisId = JOYSTICK_AXIS_Y; + axis.value = left.y; + NativeAxis(axis); + } + + if (prevState.Gamepad.sThumbRX != state.Gamepad.sThumbRX || prevState.Gamepad.sThumbRY != state.Gamepad.sThumbRY) { + Stick right = NormalizedDeadzoneFilter(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY); + + AxisInput axis; + axis.deviceId = DEVICE_ID_X360_0; + axis.axisId = JOYSTICK_AXIS_Z; + axis.value = right.x; + NativeAxis(axis); + axis.axisId = JOYSTICK_AXIS_RZ; + axis.value = right.y; + NativeAxis(axis); + } this->prevState = state; this->check_delay = 0; - AxisInput axis; - axis.deviceId = DEVICE_ID_KEYBOARD; - axis.axisId = JOYSTICK_AXIS_X; - axis.value = left.x; - NativeAxis(axis); - axis.axisId = JOYSTICK_AXIS_Y; - axis.value = left.y; - NativeAxis(axis); - axis.axisId = JOYSTICK_AXIS_Z; - axis.value = right.x; - NativeAxis(axis); - axis.axisId = JOYSTICK_AXIS_RZ; - axis.value = right.y; - NativeAxis(axis); - // If there's an XInput pad, skip following pads. This prevents DInput and XInput // from colliding. return UPDATESTATE_SKIP_PAD; @@ -112,7 +113,6 @@ inline float Clampf(float val, float min, float max) { return val; } -// We only filter the left stick since PSP has no analog triggers or right stick static Stick NormalizedDeadzoneFilter(short x, short y) { static const float DEADZONE = (float)XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE / 32767.0f; Stick s; @@ -139,46 +139,12 @@ static Stick NormalizedDeadzoneFilter(short x, short y) { void XinputDevice::ApplyButtons(XINPUT_STATE &state, InputState &input_state) { u32 buttons = state.Gamepad.wButtons; - // Simulate some extra buttons from axes. This should be done elsewhere really. if (state.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD) buttons |= XBOX_CODE_LEFTTRIGGER; if (state.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD) buttons |= XBOX_CODE_RIGHTTRIGGER; - const SHORT rthreshold = 22000; - - switch (g_Config.iRightStickBind) { - case 0: - break; - case 1: - if (state.Gamepad.sThumbRX > rthreshold) buttons |= XINPUT_GAMEPAD_DPAD_RIGHT; - else if (state.Gamepad.sThumbRX < -rthreshold) buttons |= XINPUT_GAMEPAD_DPAD_LEFT; - if (state.Gamepad.sThumbRY > rthreshold) buttons |= XINPUT_GAMEPAD_DPAD_UP; - else if (state.Gamepad.sThumbRY < -rthreshold) buttons |= XINPUT_GAMEPAD_DPAD_DOWN; - break; - case 2: - if (state.Gamepad.sThumbRX > rthreshold) buttons |= XINPUT_GAMEPAD_B; - else if (state.Gamepad.sThumbRX < -rthreshold) buttons |= XINPUT_GAMEPAD_X; - if (state.Gamepad.sThumbRY > rthreshold) buttons |= XINPUT_GAMEPAD_Y; - else if (state.Gamepad.sThumbRY < -rthreshold) buttons |= XINPUT_GAMEPAD_A; - break; - case 3: - if (state.Gamepad.sThumbRX > rthreshold) buttons |= XINPUT_GAMEPAD_RIGHT_SHOULDER; - else if (state.Gamepad.sThumbRX < -rthreshold) buttons |= XINPUT_GAMEPAD_LEFT_SHOULDER; - break; - case 4: - if (state.Gamepad.sThumbRX > rthreshold) buttons |= XINPUT_GAMEPAD_RIGHT_SHOULDER; - else if (state.Gamepad.sThumbRX < -rthreshold) buttons |= XINPUT_GAMEPAD_LEFT_SHOULDER; - if (state.Gamepad.sThumbRY > rthreshold) buttons |= XINPUT_GAMEPAD_Y; - else if (state.Gamepad.sThumbRY < -rthreshold) buttons |= XINPUT_GAMEPAD_A; - break; - case 5: - if (state.Gamepad.sThumbRX > rthreshold) buttons |= XINPUT_GAMEPAD_DPAD_RIGHT; - else if (state.Gamepad.sThumbRX < -rthreshold) buttons |= XINPUT_GAMEPAD_DPAD_LEFT; - break; - } - u32 downMask = buttons & (~prevButtons); u32 upMask = (~buttons) & prevButtons; prevButtons = buttons; From facad022ee97e0a43a91fa74428f183424b90bea Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Jul 2013 17:18:24 -0700 Subject: [PATCH 11/13] Reverse default DirectInput Y mapping. As it was before. --- Common/KeyMap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index d350842775..967d863e0e 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -98,8 +98,8 @@ struct DefaultKeyMap { m[KeyDef(DEVICE_ID_PAD_0, KEYCODE_BUTTON_8)] = CTRL_RTRIGGER; m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_X, -1)] = VIRTKEY_AXIS_X_MIN; m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_X, +1)] = VIRTKEY_AXIS_X_MAX; - m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_Y, -1)] = VIRTKEY_AXIS_Y_MIN; - m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_Y, +1)] = VIRTKEY_AXIS_Y_MAX; + m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_Y, +1)] = VIRTKEY_AXIS_Y_MIN; + m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_Y, -1)] = VIRTKEY_AXIS_Y_MAX; return m; } From 00aaf2bb118b35412656a3c48dee76c878d95797 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Jul 2013 17:21:22 -0700 Subject: [PATCH 12/13] Remove right stick bind option entirely. --- Core/Config.cpp | 2 -- Core/Config.h | 7 ------- UI/MenuScreens.cpp | 28 ---------------------------- 3 files changed, 37 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 2e46aa9ac2..070d3ddb8d 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -145,7 +145,6 @@ void Config::Load(const char *iniFileName) control->Get("LargeControls", &bLargeControls, false); // control->Get("KeyMapping",iMappingMap); control->Get("AccelerometerToAnalogHoriz", &bAccelerometerToAnalogHoriz, false); - control->Get("RightStickBind", &iRightStickBind, 0); control->Get("SwapDInputRightAxes", &iSwapRightAxes, 0); control->Get("TouchButtonOpacity", &iTouchButtonOpacity, 65); control->Get("ButtonScale", &fButtonScale, 1.15); @@ -259,7 +258,6 @@ void Config::Save() control->Set("LargeControls", bLargeControls); // control->Set("KeyMapping",iMappingMap); control->Set("AccelerometerToAnalogHoriz", bAccelerometerToAnalogHoriz); - control->Set("RightStickBind", iRightStickBind); control->Set("SwapDInputRightAxes", iSwapRightAxes); control->Set("TouchButtonOpacity", iTouchButtonOpacity); control->Set("ButtonScale", fButtonScale); diff --git a/Core/Config.h b/Core/Config.h index 2ca9499203..40db11ade1 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -108,13 +108,6 @@ public: bool bShowDebugStats; bool bLargeControls; bool bAccelerometerToAnalogHoriz; - // Temporary until control mapping rewrite - // 0 = none - // 1 = arrow buttons - // 2 = face buttons - // 3 = L/R - // 4 = L/R + triangle/cross - int iRightStickBind; int iSwapRightAxes; // Control diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 1186dda7b0..2ff00e5dd1 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -1491,34 +1491,6 @@ void ControlsScreen::render() { UICheckBox(GEN_ID, x, y += stride, c->T("Tilt", "Tilt to Analog (horizontal)"), ALIGN_TOPLEFT, &g_Config.bAccelerometerToAnalogHoriz); if (g_Config.bShowTouchControls) { UICheckBox(GEN_ID, x, y += stride, c->T("Show Left Analog Stick"), ALIGN_TOPLEFT, &g_Config.bShowAnalogStick); - bool rightstick = g_Config.iRightStickBind > 0; - UICheckBox(GEN_ID, x, y += stride, c->T("Bind Right Analog Stick"), ALIGN_TOPLEFT, &rightstick); - if (rightstick) { - if (g_Config.iRightStickBind <= 0 ) - g_Config.iRightStickBind = 1; - - char showType[256]; - std::string type; - switch (g_Config.iRightStickBind) { - case 1: type = "Arrow Buttons";break; - case 2: type = "Face Buttons";break; - case 3: type = "L/R";break; - case 4: type = "L/R + Triangle/Cross";break; - } - sprintf(showType, "%s %s", c->T("Target :"), type.c_str()); - ui_draw2d.DrawText(UBUNTU24, showType, x + 60, (y += stride) , 0xFFFFFFFF, ALIGN_LEFT); - HLinear hlinear1(x + 60 , y+= stride + 5, 10); - if (UIButton(GEN_ID, hlinear1, 200, 0, c->T("Arrow Buttons"), ALIGN_LEFT)) - g_Config.iRightStickBind = 1; - if (UIButton(GEN_ID, hlinear1, 200, 0, c->T("Face Buttons"), ALIGN_LEFT)) - g_Config.iRightStickBind = 2; - if (UIButton(GEN_ID, hlinear1, 60, 0, c->T("L/R"), ALIGN_LEFT)) - g_Config.iRightStickBind = 3; - if (UIButton(GEN_ID, hlinear1, 280, 0, c->T("L/R + Triangle/Cross"), ALIGN_LEFT)) - g_Config.iRightStickBind = 4; - y += 20; - } else - g_Config.iRightStickBind = 0; UICheckBox(GEN_ID, x, y += stride, c->T("Buttons Scaling"), ALIGN_TOPLEFT, &g_Config.bLargeControls); if (g_Config.bLargeControls) { From 1edbda62d0b2d4a806189c6de366a0fb60ecc69c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Jul 2013 17:22:07 -0700 Subject: [PATCH 13/13] Remove right stick swap option, not needed. --- Core/Config.cpp | 2 -- Core/Config.h | 1 - 2 files changed, 3 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 070d3ddb8d..f0fc674b2b 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -145,7 +145,6 @@ void Config::Load(const char *iniFileName) control->Get("LargeControls", &bLargeControls, false); // control->Get("KeyMapping",iMappingMap); control->Get("AccelerometerToAnalogHoriz", &bAccelerometerToAnalogHoriz, false); - control->Get("SwapDInputRightAxes", &iSwapRightAxes, 0); control->Get("TouchButtonOpacity", &iTouchButtonOpacity, 65); control->Get("ButtonScale", &fButtonScale, 1.15); @@ -258,7 +257,6 @@ void Config::Save() control->Set("LargeControls", bLargeControls); // control->Set("KeyMapping",iMappingMap); control->Set("AccelerometerToAnalogHoriz", bAccelerometerToAnalogHoriz); - control->Set("SwapDInputRightAxes", iSwapRightAxes); control->Set("TouchButtonOpacity", iTouchButtonOpacity); control->Set("ButtonScale", fButtonScale); diff --git a/Core/Config.h b/Core/Config.h index 40db11ade1..d75caddbdf 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -108,7 +108,6 @@ public: bool bShowDebugStats; bool bLargeControls; bool bAccelerometerToAnalogHoriz; - int iSwapRightAxes; // Control int iTouchButtonOpacity;