Detect joystick menu for XInput

This commit is contained in:
erorcun 2021-02-05 17:51:57 +03:00
parent c002dd6cba
commit c7ba01b034
10 changed files with 112 additions and 14 deletions

View File

@ -354,6 +354,11 @@ uint32 CControllerConfigManager::ms_padButtonsInited = 0;
void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons)
{
#ifdef XINPUT
// No manual bindings for you, honey.
return;
#endif
m_bFirstCapture = true;
uint32 btn = buttons;

View File

@ -243,7 +243,7 @@ enum eMenuScreen
#ifdef GRAPHICS_MENU_OPTIONS
MENUPAGE_GRAPHICS_SETTINGS,
#endif
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
#ifdef DETECT_JOYSTICK_MENU
MENUPAGE_DETECT_JOYSTICK,
#endif

View File

@ -1,4 +1,13 @@
#include "common.h"
#if defined DETECT_JOYSTICK_MENU && defined XINPUT
#include <windows.h>
#include <xinput.h>
#if !defined(PSAPI_VERSION) || (PSAPI_VERSION > 1)
#pragma comment( lib, "Xinput9_1_0.lib" )
#else
#pragma comment( lib, "Xinput.lib" )
#endif
#endif
#include "platform.h"
#include "crossplatform.h"
#include "Renderer.h"
@ -297,11 +306,13 @@ void ScreenModeAfterChange(int8 before, int8 after)
#endif
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
#ifdef DETECT_JOYSTICK_MENU
wchar selectedJoystickUnicode[128];
int cachedButtonNum = -1;
wchar* DetectJoystickDraw(bool* disabled, bool userHovering) {
#if defined RW_GL3 && !defined LIBRW_SDL2
int numButtons;
int found = -1;
const char *joyname;
@ -332,6 +343,40 @@ wchar* DetectJoystickDraw(bool* disabled, bool userHovering) {
}
}
if (PSGLOBAL(joy1id) == -1)
#elif defined XINPUT
int found = -1;
XINPUT_STATE xstate;
memset(&xstate, 0, sizeof(XINPUT_STATE));
if (userHovering) {
for (int i = 0; i <= 3; i++) {
if (XInputGetState(i, &xstate) == ERROR_SUCCESS) {
if (xstate.Gamepad.bLeftTrigger || xstate.Gamepad.bRightTrigger) {
found = i;
break;
}
for (int j = XINPUT_GAMEPAD_DPAD_UP; j != XINPUT_GAMEPAD_Y << 1; j = (j << 1)) {
if (xstate.Gamepad.wButtons & j) {
found = i;
break;
}
}
if (found != -1)
break;
}
}
if (found != -1 && CPad::XInputJoy1 != found) {
if (CPad::XInputJoy1 != -1 && CPad::XInputJoy1 != found)
CPad::XInputJoy2 = CPad::XInputJoy1;
else
CPad::XInputJoy2 = -1;
CPad::XInputJoy1 = found;
cachedButtonNum = 0; // fake too, because xinput bypass CControllerConfig
}
}
sprintf(gSelectedJoystickName, "%d", CPad::XInputJoy1); // fake, on xinput we only store gamepad ids(thanks MS) so this is a temp variable to be used below
if (CPad::XInputJoy1 == -1)
#endif
AsciiToUnicode("Not found", selectedJoystickUnicode);
else
AsciiToUnicode(gSelectedJoystickName, selectedJoystickUnicode);
@ -666,7 +711,7 @@ CMenuScreenCustom aScreens[MENUPAGES] = {
#ifdef GAMEPAD_MENU
MENUACTION_CHANGEMENU, "FET_AGS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
#endif
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
#ifdef DETECT_JOYSTICK_MENU
MENUACTION_CHANGEMENU, "FEC_JOD", { nil, SAVESLOT_NONE, MENUPAGE_DETECT_JOYSTICK },
#endif
MENUACTION_CHANGEMENU, "FET_AMS", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS },
@ -873,7 +918,7 @@ CMenuScreenCustom aScreens[MENUPAGES] = {
},
#endif
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
#ifdef DETECT_JOYSTICK_MENU
// MENUPAGE_DETECT_JOYSTICK
{ "FEC_JOD", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC,
new CCustomScreenLayout({MENUSPRITE_MAINMENU, 40, 60, 20, FONT_BANK, FESCREEN_LEFT_ALIGN, false, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), DetectJoystickGoBack,

View File

@ -1028,8 +1028,14 @@ void CPad::AddToPCCheatString(char c)
}
#ifdef XINPUT
int CPad::XInputJoy1 = 0;
int CPad::XInputJoy2 = 1;
void CPad::AffectFromXinput(uint32 pad)
{
pad = pad == 0 ? XInputJoy1 : XInputJoy2;
if (pad == -1) // LoadINIControllerSettings can set it to -1
return;
XINPUT_STATE xstate;
memset(&xstate, 0, sizeof(XINPUT_STATE));
if (XInputGetState(pad, &xstate) == ERROR_SUCCESS)

View File

@ -263,6 +263,8 @@ public:
static int32 *EditCodesForControls(int32 *pRsKeys, int32 nSize);
#ifdef XINPUT
static int XInputJoy1;
static int XInputJoy2;
void AffectFromXinput(uint32 pad);
#endif

View File

@ -287,8 +287,8 @@ enum Config {
#if !defined(RW_GL3) && defined(_WIN32)
#define XINPUT
#endif
#if !defined(_WIN32) && !defined(__SWITCH__)
#define DONT_TRUST_RECOGNIZED_JOYSTICKS // Then we'll only rely on GLFW gamepad DB, and expect user to enter Controller->Detect joysticks if his joystick isn't on that list.
#if defined XINPUT || (defined RW_GL3 && !defined LIBRW_SDL2 && !defined __SWITCH__)
#define DETECT_JOYSTICK_MENU // Then we'll expect user to enter Controller->Detect joysticks if his joystick isn't detected at the start.
#endif
#define DETECT_PAD_INPUT_SWITCH // Adds automatic switch of pad related stuff between controller and kb/m
#define KANGAROO_CHEAT

View File

@ -1,6 +1,14 @@
#include <csignal>
#define WITHWINDOWS
#include "common.h"
#if defined DETECT_JOYSTICK_MENU && defined XINPUT
#include <xinput.h>
#if !defined(PSAPI_VERSION) || (PSAPI_VERSION > 1)
#pragma comment( lib, "Xinput9_1_0.lib" )
#else
#pragma comment( lib, "Xinput.lib" )
#endif
#endif
#include "Renderer.h"
#include "Credits.h"
#include "Camera.h"
@ -34,7 +42,7 @@
#include "MBlur.h"
#include "ControllerConfig.h"
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
#ifdef DETECT_JOYSTICK_MENU
#include "crossplatform.h"
#endif
@ -244,8 +252,32 @@ const char *iniKeyboardButtons[] = {"ESC","F1","F2","F3","F4","F5","F6","F7","F8
void LoadINIControllerSettings()
{
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
#ifdef DETECT_JOYSTICK_MENU
#ifdef XINPUT
int storedJoy1 = -1;
if (ReadIniIfExists("Controller", "JoystickName", &storedJoy1)) {
CPad::XInputJoy1 = -1;
CPad::XInputJoy2 = -1;
XINPUT_STATE xstate;
memset(&xstate, 0, sizeof(XINPUT_STATE));
// Firstly confirm & set joy 1
if (XInputGetState(storedJoy1, &xstate) == ERROR_SUCCESS) {
CPad::XInputJoy1 = storedJoy1;
}
for (int i = 0; i <= 3; i++) {
if (XInputGetState(i, &xstate) == ERROR_SUCCESS) {
if (CPad::XInputJoy1 == -1)
CPad::XInputJoy1 = i;
else if (CPad::XInputJoy2 == -1 && i != CPad::XInputJoy1)
CPad::XInputJoy2 = i;
}
}
}
#else
ReadIniIfExists("Controller", "JoystickName", gSelectedJoystickName, 128);
#endif
#endif
// force to default GTA behaviour (never overwrite bindings on joy change/initialization) if user init'ed/set bindings before we introduced that
if (!ReadIniIfExists("Controller", "PadButtonsInited", &ControlsManager.ms_padButtonsInited)) {
@ -343,8 +375,12 @@ void SaveINIControllerSettings()
StoreIni("Bindings", iniControllerActions[i], value, 128);
}
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
#ifdef DETECT_JOYSTICK_MENU
#ifdef XINPUT
StoreIni("Controller", "JoystickName", CPad::XInputJoy1);
#else
StoreIni("Controller", "JoystickName", gSelectedJoystickName, 128);
#endif
#endif
StoreIni("Controller", "PadButtonsInited", ControlsManager.ms_padButtonsInited);
cfg.write_file("re3.ini");

View File

@ -71,7 +71,7 @@ void CapturePad(RwInt32 padID);
void joysChangeCB(int jid, int event);
#endif
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
#ifdef DETECT_JOYSTICK_MENU
extern char gSelectedJoystickName[128];
#endif

View File

@ -81,7 +81,7 @@ static psGlobalType PsGlobal;
size_t _dwMemAvailPhys;
RwUInt32 gGameState;
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
#ifdef DETECT_JOYSTICK_MENU
char gSelectedJoystickName[128] = "";
#endif
@ -841,7 +841,7 @@ void joysChangeCB(int jid, int event);
bool IsThisJoystickBlacklisted(int i)
{
#ifndef DONT_TRUST_RECOGNIZED_JOYSTICKS
#ifndef DETECT_JOYSTICK_MENU
return false;
#else
if (glfwJoystickIsGamepad(i))
@ -906,7 +906,7 @@ void _InputInitialiseJoys()
if (PSGLOBAL(joy1id) != -1) {
int count;
glfwGetJoystickButtons(PSGLOBAL(joy1id), &count);
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
#ifdef DETECT_JOYSTICK_MENU
strcpy(gSelectedJoystickName, glfwGetJoystickName(PSGLOBAL(joy1id)));
#endif
ControlsManager.InitDefaultControlConfigJoyPad(count);
@ -2150,7 +2150,7 @@ void joysChangeCB(int jid, int event)
if (event == GLFW_CONNECTED && !IsThisJoystickBlacklisted(jid)) {
if (PSGLOBAL(joy1id) == -1) {
PSGLOBAL(joy1id) = jid;
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
#ifdef DETECT_JOYSTICK_MENU
strcpy(gSelectedJoystickName, glfwGetJoystickName(jid));
#endif
// This is behind LOAD_INI_SETTINGS, because otherwise the Init call below will destroy/overwrite your bindings.

View File

@ -121,6 +121,10 @@ DWORD _dwOperatingSystemVersion;
RwUInt32 gGameState;
CJoySticks AllValidWinJoys;
#ifdef DETECT_JOYSTICK_MENU
char gSelectedJoystickName[128] = "";
#endif
// What is that for anyway?
#ifndef IMPROVED_VIDEOMODE
static RwBool defaultFullscreenRes = TRUE;