WinMM first & second joysticks are not always 0 & 1

This commit is contained in:
Fabrice CARUSO 2023-01-06 20:37:56 +01:00
parent d01a9ccb40
commit 6303401f54
3 changed files with 139 additions and 102 deletions

View File

@ -52,6 +52,9 @@
#include "Memory.h" #include "Memory.h"
#include "YamlHelper.h" #include "YamlHelper.h"
extern int JOYSTICK_1; // declared in joystick.cpp
extern int JOYSTICK_2;
BYTE __stdcall FourPlayCard::IORead(WORD pc, WORD addr, BYTE bWrite, BYTE value, ULONG nExecutedCycles) BYTE __stdcall FourPlayCard::IORead(WORD pc, WORD addr, BYTE bWrite, BYTE value, ULONG nExecutedCycles)
{ {
BYTE nOutput = MemReadFloatingBus(nExecutedCycles); BYTE nOutput = MemReadFloatingBus(nExecutedCycles);
@ -67,15 +70,13 @@ BYTE __stdcall FourPlayCard::IORead(WORD pc, WORD addr, BYTE bWrite, BYTE value,
UINT yAxis = 0; UINT yAxis = 0;
JOYINFOEX infoEx; JOYINFOEX infoEx;
MMRESULT result = 0;
infoEx.dwSize = sizeof(infoEx); infoEx.dwSize = sizeof(infoEx);
infoEx.dwFlags = JOY_RETURNPOV | JOY_RETURNBUTTONS; infoEx.dwFlags = JOY_RETURNPOV | JOY_RETURNBUTTONS;
switch (addr & 0xF) switch (addr & 0xF)
{ {
case 0: // Joystick 1 case 0: // Joystick 1
result = joyGetPosEx(JOYSTICKID1, &infoEx); if (JOYSTICK_1 >= 0 && joyGetPosEx(JOYSTICK_1, &infoEx) == JOYERR_NOERROR)
if (result == JOYERR_NOERROR)
{ {
xAxis = (infoEx.dwXpos >> 8) & 0xFF; xAxis = (infoEx.dwXpos >> 8) & 0xFF;
yAxis = (infoEx.dwYpos >> 8) & 0xFF; yAxis = (infoEx.dwYpos >> 8) & 0xFF;
@ -89,8 +90,7 @@ BYTE __stdcall FourPlayCard::IORead(WORD pc, WORD addr, BYTE bWrite, BYTE value,
nOutput = up | (down << 1) | (left << 2) | (right << 3) | (alwaysHigh << 5) | (trigger2 << 6) | (trigger1 << 7); nOutput = up | (down << 1) | (left << 2) | (right << 3) | (alwaysHigh << 5) | (trigger2 << 6) | (trigger1 << 7);
break; break;
case 1: // Joystick 2 case 1: // Joystick 2
result = joyGetPosEx(JOYSTICKID2, &infoEx); if (JOYSTICK_2 >= 0 && joyGetPosEx(JOYSTICK_2, &infoEx) == JOYERR_NOERROR)
if (result == JOYERR_NOERROR)
{ {
xAxis = (infoEx.dwXpos >> 8) & 0xFF; xAxis = (infoEx.dwXpos >> 8) & 0xFF;
yAxis = (infoEx.dwYpos >> 8) & 0xFF; yAxis = (infoEx.dwYpos >> 8) & 0xFF;

View File

@ -51,6 +51,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
enum {DEVICE_NONE=0, DEVICE_JOYSTICK, DEVICE_KEYBOARD, DEVICE_MOUSE, DEVICE_JOYSTICK_THUMBSTICK2}; enum {DEVICE_NONE=0, DEVICE_JOYSTICK, DEVICE_KEYBOARD, DEVICE_MOUSE, DEVICE_JOYSTICK_THUMBSTICK2};
int JOYSTICK_1 = -1;
int JOYSTICK_2 = -1;
// Indexed by joytype[n] // Indexed by joytype[n]
static const DWORD joyinfo[6] = { DEVICE_NONE, static const DWORD joyinfo[6] = { DEVICE_NONE,
DEVICE_JOYSTICK, DEVICE_JOYSTICK,
@ -123,13 +126,16 @@ void JoySetHookAltKeys(bool hook)
//=========================================================================== //===========================================================================
void CheckJoystick0() void CheckJoystick0()
{ {
if (JOYSTICK_1 < 0)
return;
static DWORD lastcheck = 0; static DWORD lastcheck = 0;
DWORD currtime = GetTickCount(); DWORD currtime = GetTickCount();
if ((currtime-lastcheck >= 10) || joybutton[0] || joybutton[1]) if ((currtime-lastcheck >= 10) || joybutton[0] || joybutton[1])
{ {
lastcheck = currtime; lastcheck = currtime;
JOYINFO info; JOYINFO info;
if (joyGetPos(JOYSTICKID1,&info) == JOYERR_NOERROR) if (joyGetPos(JOYSTICK_1,&info) == JOYERR_NOERROR)
{ {
joybutton[0] = ((info.wButtons & JOY_BUTTON1) != 0); joybutton[0] = ((info.wButtons & JOY_BUTTON1) != 0);
if (joyinfo[joytype[1]] == DEVICE_NONE) // Only consider 2nd button if NOT emulating a 2nd Apple joystick if (joyinfo[joytype[1]] == DEVICE_NONE) // Only consider 2nd button if NOT emulating a 2nd Apple joystick
@ -160,7 +166,7 @@ void CheckJoystick1()
JOYINFOEX infoEx; JOYINFOEX infoEx;
infoEx.dwSize = sizeof(infoEx); infoEx.dwSize = sizeof(infoEx);
infoEx.dwFlags = JOY_RETURNBUTTONS | JOY_RETURNZ | JOY_RETURNR; infoEx.dwFlags = JOY_RETURNBUTTONS | JOY_RETURNZ | JOY_RETURNR;
result = joyGetPosEx(JOYSTICKID1, &infoEx); result = joyGetPosEx(JOYSTICK_1, &infoEx);
if (result == JOYERR_NOERROR) if (result == JOYERR_NOERROR)
{ {
info.wButtons = (infoEx.dwButtons & JOY_BUTTON2) ? JOY_BUTTON1 : 0; info.wButtons = (infoEx.dwButtons & JOY_BUTTON2) ? JOY_BUTTON1 : 0;
@ -169,7 +175,7 @@ void CheckJoystick1()
} }
} }
else else
result = joyGetPos(JOYSTICKID2, &info); result = joyGetPos(JOYSTICK_2, &info);
if (result == JOYERR_NOERROR) if (result == JOYERR_NOERROR)
{ {
joybutton[2] = ((info.wButtons & JOY_BUTTON1) != 0); joybutton[2] = ((info.wButtons & JOY_BUTTON1) != 0);
@ -193,99 +199,128 @@ void CheckJoystick1()
//=========================================================================== //===========================================================================
void JoyInitialize() void JoyInitialize()
{ {
// Emulated joystick #0 can only use JOYSTICKID1 (if no joystick, then use keyboard) //
// Emulated joystick #1 can only use JOYSTICKID2 (if no joystick, then disable) // Detect First and Second connected JOYSTICK in WinMM apis. JOYSTICKID1 is 0 and is not always anymore the first connected joystick
//
// JOYSTICK_1 = -1;
// Init for emulated joystick #0: JOYSTICK_2 = -1;
//
if (joyinfo[joytype[0]] == DEVICE_JOYSTICK) bool firstFound = false;
{
JOYCAPS caps; UINT joys = joyGetNumDevs();
if (joyGetDevCaps(JOYSTICKID1,&caps,sizeof(JOYCAPS)) == JOYERR_NOERROR) for (int i = 0; i < joys; i++)
{ {
joyshrx[0] = 0; JOYCAPS caps;
joyshry[0] = 0; int ret = joyGetDevCaps(i, &caps, sizeof(JOYCAPS));
joysubx[0] = (int)caps.wXmin; if (ret != JOYERR_NOERROR)
joysuby[0] = (int)caps.wYmin; continue;
UINT xrange = caps.wXmax-caps.wXmin;
UINT yrange = caps.wYmax-caps.wYmin; JOYINFO info;
while (xrange > 256) ret = joyGetPos(i, &info);
{ if (ret != JOYERR_NOERROR)
xrange >>= 1; continue;
++joyshrx[0];
} if (firstFound)
while (yrange > 256) {
{ JOYSTICK_2 = i;
yrange >>= 1; break;
++joyshry[0]; }
}
} JOYSTICK_1 = i;
else firstFound = true;
{
joytype[0] = J0C_KEYBD_NUMPAD;
} }
}
// //
// Init for emulated joystick #1: // Init for emulated joystick #0:
// //
if (joyinfo[joytype[1]] == DEVICE_JOYSTICK) if (joyinfo[joytype[0]] == DEVICE_JOYSTICK)
{
JOYCAPS caps;
if (joyGetDevCaps(JOYSTICKID2,&caps,sizeof(JOYCAPS)) == JOYERR_NOERROR)
{ {
joyshrx[1] = 0; JOYCAPS caps;
joyshry[1] = 0; if (JOYSTICK_1 >= 0 && joyGetDevCaps(JOYSTICK_1, &caps, sizeof(JOYCAPS)) == JOYERR_NOERROR)
joysubx[1] = (int)caps.wXmin; {
joysuby[1] = (int)caps.wYmin; joyshrx[0] = 0;
UINT xrange = caps.wXmax-caps.wXmin; joyshry[0] = 0;
UINT yrange = caps.wYmax-caps.wYmin; joysubx[0] = (int)caps.wXmin;
while (xrange > 256) joysuby[0] = (int)caps.wYmin;
{ UINT xrange = caps.wXmax - caps.wXmin;
xrange >>= 1; UINT yrange = caps.wYmax - caps.wYmin;
++joyshrx[1]; while (xrange > 256)
} {
while (yrange > 256) xrange >>= 1;
{ ++joyshrx[0];
yrange >>= 1; }
++joyshry[1]; while (yrange > 256)
} {
} yrange >>= 1;
else ++joyshry[0];
{ }
joytype[1] = J1C_DISABLED; }
else
{
joytype[0] = J0C_KEYBD_NUMPAD;
}
}
//
// Init for emulated joystick #1:
//
if (JOYSTICK_2 >= 0 && joyinfo[joytype[1]] == DEVICE_JOYSTICK)
{
JOYCAPS caps;
if (joyGetDevCaps(JOYSTICK_2, &caps, sizeof(JOYCAPS)) == JOYERR_NOERROR)
{
joyshrx[1] = 0;
joyshry[1] = 0;
joysubx[1] = (int)caps.wXmin;
joysuby[1] = (int)caps.wYmin;
UINT xrange = caps.wXmax - caps.wXmin;
UINT yrange = caps.wYmax - caps.wYmin;
while (xrange > 256)
{
xrange >>= 1;
++joyshrx[1];
}
while (yrange > 256)
{
yrange >>= 1;
++joyshry[1];
}
}
else
{
joytype[1] = J1C_DISABLED;
}
}
else if (JOYSTICK_1 >= 0 && joyinfo[joytype[1]] == DEVICE_JOYSTICK_THUMBSTICK2)
{
JOYCAPS caps;
if (joyGetDevCaps(JOYSTICK_1, &caps, sizeof(JOYCAPS)) == JOYERR_NOERROR)
{
joyshrx[1] = 0;
joyshry[1] = 0;
joysubx[1] = (int)caps.wZmin;
joysuby[1] = (int)caps.wRmin;
UINT xrange = caps.wZmax - caps.wZmin;
UINT yrange = caps.wRmax - caps.wRmin;
while (xrange > 256)
{
xrange >>= 1;
++joyshrx[1];
}
while (yrange > 256)
{
yrange >>= 1;
++joyshry[1];
}
}
else
{
joytype[1] = J1C_DISABLED;
}
} }
}
else if (joyinfo[joytype[1]] == DEVICE_JOYSTICK_THUMBSTICK2)
{
JOYCAPS caps;
if (joyGetDevCaps(JOYSTICKID1, &caps, sizeof(JOYCAPS)) == JOYERR_NOERROR)
{
joyshrx[1] = 0;
joyshry[1] = 0;
joysubx[1] = (int)caps.wZmin;
joysuby[1] = (int)caps.wRmin;
UINT xrange = caps.wZmax - caps.wZmin;
UINT yrange = caps.wRmax - caps.wRmin;
while (xrange > 256)
{
xrange >>= 1;
++joyshrx[1];
}
while (yrange > 256)
{
yrange >>= 1;
++joyshry[1];
}
}
else
{
joytype[1] = J1C_DISABLED;
}
}
} }
//=========================================================================== //===========================================================================
@ -710,9 +745,9 @@ BOOL JoySetEmulationType(HWND window, DWORD newtype, int nJoystickNumber, const
if (joyinfo[newtype] == DEVICE_JOYSTICK || joyinfo[newtype] == DEVICE_JOYSTICK_THUMBSTICK2) if (joyinfo[newtype] == DEVICE_JOYSTICK || joyinfo[newtype] == DEVICE_JOYSTICK_THUMBSTICK2)
{ {
JOYCAPS caps; JOYCAPS caps;
unsigned int nJoy2ID = joyinfo[newtype] == DEVICE_JOYSTICK_THUMBSTICK2 ? JOYSTICKID1 : JOYSTICKID2; unsigned int nJoy2ID = joyinfo[newtype] == DEVICE_JOYSTICK_THUMBSTICK2 ? JOYSTICK_1 : JOYSTICK_2;
unsigned int nJoyID = nJoystickNumber == JN_JOYSTICK0 ? JOYSTICKID1 : nJoy2ID; unsigned int nJoyID = nJoystickNumber == JN_JOYSTICK0 ? JOYSTICK_1 : nJoy2ID;
if (joyGetDevCaps(nJoyID, &caps, sizeof(JOYCAPS)) != JOYERR_NOERROR) if (nJoyID < 0 || joyGetDevCaps(nJoyID, &caps, sizeof(JOYCAPS)) != JOYERR_NOERROR)
{ {
MessageBox(window, MessageBox(window,
TEXT("The emulator is unable to read your PC joystick. ") TEXT("The emulator is unable to read your PC joystick. ")

View File

@ -57,6 +57,9 @@
#include "Memory.h" #include "Memory.h"
#include "YamlHelper.h" #include "YamlHelper.h"
extern int JOYSTICK_1; // declared in joystick.cpp
extern int JOYSTICK_2;
// Default to Sony DS4 / DualSense: // Default to Sony DS4 / DualSense:
// b11,..,b0: St,Sl / -,-,R,L,X,A,B,Y // b11,..,b0: St,Sl / -,-,R,L,X,A,B,Y
// //
@ -102,8 +105,7 @@ BYTE __stdcall SNESMAXCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE value,
UINT xAxis = 0; UINT xAxis = 0;
UINT yAxis = 0; UINT yAxis = 0;
JOYINFOEX infoEx; JOYINFOEX infoEx;
MMRESULT result = 0;
infoEx.dwSize = sizeof(infoEx); infoEx.dwSize = sizeof(infoEx);
infoEx.dwFlags = JOY_RETURNPOV | JOY_RETURNBUTTONS; infoEx.dwFlags = JOY_RETURNPOV | JOY_RETURNBUTTONS;
@ -117,14 +119,14 @@ BYTE __stdcall SNESMAXCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE value,
controller1Buttons = 0; controller1Buttons = 0;
controller2Buttons = 0; controller2Buttons = 0;
result = joyGetPosEx(JOYSTICKID1, &infoEx); if (JOYSTICK_1 >= 0 && joyGetPosEx(JOYSTICK_1, &infoEx) == JOYERR_NOERROR)
if (result == JOYERR_NOERROR)
controller1Buttons = pCard->GetControllerButtons(JOYSTICKID1, infoEx, pCard->m_altControllerType[0]); controller1Buttons = pCard->GetControllerButtons(JOYSTICKID1, infoEx, pCard->m_altControllerType[0]);
controller1Buttons = ~controller1Buttons; controller1Buttons = ~controller1Buttons;
result = joyGetPosEx(JOYSTICKID2, &infoEx); if (JOYSTICK_2 >= 0 && joyGetPosEx(JOYSTICK_2, &infoEx) == JOYERR_NOERROR)
if (result == JOYERR_NOERROR)
controller2Buttons = pCard->GetControllerButtons(JOYSTICKID2, infoEx, pCard->m_altControllerType[1]); controller2Buttons = pCard->GetControllerButtons(JOYSTICKID2, infoEx, pCard->m_altControllerType[1]);
controller2Buttons = ~controller2Buttons; controller2Buttons = ~controller2Buttons;
break; break;