psx: multitap support. tested for 20 seconds, but worth someone else testing.
This commit is contained in:
parent
27e419bba5
commit
d3a1ec64dd
|
@ -409,9 +409,26 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
SetControllerButtons();
|
||||
|
||||
var fioCfg = _SyncSettings.FIOConfig;
|
||||
if(fioCfg.Devices8[0] != OctoshockDll.ePeripheralType.None)
|
||||
if (fioCfg.Multitaps[0])
|
||||
{
|
||||
OctoshockDll.shock_Peripheral_Connect(psx, 0x01, OctoshockDll.ePeripheralType.Multitap);
|
||||
OctoshockDll.shock_Peripheral_Connect(psx, 0x11, fioCfg.Devices8[0]);
|
||||
OctoshockDll.shock_Peripheral_Connect(psx, 0x21, fioCfg.Devices8[1]);
|
||||
OctoshockDll.shock_Peripheral_Connect(psx, 0x31, fioCfg.Devices8[2]);
|
||||
OctoshockDll.shock_Peripheral_Connect(psx, 0x41, fioCfg.Devices8[3]);
|
||||
}
|
||||
else
|
||||
OctoshockDll.shock_Peripheral_Connect(psx, 0x01, fioCfg.Devices8[0]);
|
||||
if (fioCfg.Devices8[4] != OctoshockDll.ePeripheralType.None)
|
||||
|
||||
if (fioCfg.Multitaps[1])
|
||||
{
|
||||
OctoshockDll.shock_Peripheral_Connect(psx, 0x02, OctoshockDll.ePeripheralType.Multitap);
|
||||
OctoshockDll.shock_Peripheral_Connect(psx, 0x12, fioCfg.Devices8[4]);
|
||||
OctoshockDll.shock_Peripheral_Connect(psx, 0x22, fioCfg.Devices8[5]);
|
||||
OctoshockDll.shock_Peripheral_Connect(psx, 0x32, fioCfg.Devices8[6]);
|
||||
OctoshockDll.shock_Peripheral_Connect(psx, 0x42, fioCfg.Devices8[7]);
|
||||
}
|
||||
else
|
||||
OctoshockDll.shock_Peripheral_Connect(psx, 0x02, fioCfg.Devices8[4]);
|
||||
|
||||
var memcardTransaction = new OctoshockDll.ShockMemcardTransaction()
|
||||
|
@ -456,9 +473,11 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
{
|
||||
var fioCfg = _SyncSettings.FIOConfig.ToLogical();
|
||||
|
||||
int portNum = 0x01;
|
||||
foreach (int slot in new[] { 0, 4 })
|
||||
for(int port=0;port<2;port++)
|
||||
for(int multiport=0;multiport<4;multiport++)
|
||||
{
|
||||
int portNum = (port+1) + ((multiport+1) << 4);
|
||||
int slot = port * 4 + multiport;
|
||||
//no input to set
|
||||
if (fioCfg.Devices8[slot] == OctoshockDll.ePeripheralType.None)
|
||||
continue;
|
||||
|
@ -518,8 +537,6 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
|
||||
OctoshockDll.shock_Peripheral_SetPadInput(psx, portNum, buttons, left_x, left_y, right_x, right_y);
|
||||
}
|
||||
|
||||
portNum <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
|
@ -135,6 +135,8 @@ FrontIO::FrontIO()
|
|||
Ports[i] = new InputDevice();
|
||||
PortData[i] = NULL;
|
||||
MCPorts[i] = new InputDevice();
|
||||
emulate_multitap[i] = false;
|
||||
DevicesTap[i] = new InputDevice_Multitap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,6 +147,7 @@ FrontIO::~FrontIO()
|
|||
{
|
||||
delete Ports[i];
|
||||
delete MCPorts[i];
|
||||
delete DevicesTap[i];
|
||||
}
|
||||
delete DummyDevice;
|
||||
}
|
||||
|
@ -573,16 +576,8 @@ void FrontIO::Reset(bool powering_up)
|
|||
istatus = false;
|
||||
}
|
||||
|
||||
void FrontIO::UpdateInput(void)
|
||||
{
|
||||
for(int i=0;i<2;i++)
|
||||
{
|
||||
if(Ports[i] != NULL) Ports[i]->UpdateInput(PortData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Take care to call ->Power() only if the device actually changed.
|
||||
void FrontIO::SetInput(unsigned int port, const char *type, void *ptr)
|
||||
void FrontIO::SetInput(unsigned int port, unsigned int multiport, const char *type, void *ptr)
|
||||
{
|
||||
//clean up the old device
|
||||
delete Ports[port];
|
||||
|
@ -604,6 +599,8 @@ void FrontIO::SetInput(unsigned int port, const char *type, void *ptr)
|
|||
Ports[port] = Device_GunCon_Create();
|
||||
else if(!strcmp(type, "justifier"))
|
||||
Ports[port] = Device_Justifier_Create();
|
||||
else if (!strcmp(type, "multitap"))
|
||||
Ports[port] = new InputDevice_Multitap();
|
||||
else
|
||||
Ports[port] = new InputDevice();
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ class FrontIO
|
|||
void GPULineHook(const pscpu_timestamp_t timestamp, const pscpu_timestamp_t line_timestamp, bool vsync, uint32 *pixels, const MDFN_PixelFormat* const format, const unsigned width, const unsigned pix_clock_offset, const unsigned pix_clock, const unsigned pix_clock_divider);
|
||||
|
||||
void UpdateInput(void);
|
||||
void SetInput(unsigned int port, const char *type, void *ptr);
|
||||
void SetInput(unsigned int port, unsigned int multiport, const char *type, void *ptr);
|
||||
void SetCrosshairsColor(unsigned port, uint32 color);
|
||||
|
||||
uint64 GetMemcardDirtyCount(unsigned int which);
|
||||
|
@ -88,7 +88,7 @@ class FrontIO
|
|||
InputDevice *MCPorts[2];
|
||||
InputDevice *DummyDevice;
|
||||
|
||||
private:
|
||||
//private:
|
||||
|
||||
void DoDSRIRQ(void);
|
||||
void CheckStartStopPending(pscpu_timestamp_t timestamp, bool skip_event_set = false);
|
||||
|
@ -99,8 +99,8 @@ class FrontIO
|
|||
//OLD
|
||||
//bool emulate_memcards[8];
|
||||
//void MapDevicesToPorts(void);
|
||||
//bool emulate_multitap[2];
|
||||
//InputDevice_Multitap *DevicesTap[2];
|
||||
bool emulate_multitap[2];
|
||||
InputDevice_Multitap *DevicesTap[2];
|
||||
//InputDevice *Devices[8];
|
||||
//void *DeviceData[8];
|
||||
//InputDevice *DevicesMC[8];
|
||||
|
|
|
@ -97,14 +97,22 @@ InputDevice_Multitap::InputDevice_Multitap()
|
|||
{
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
pad_devices[i] = NULL;
|
||||
mc_devices[i] = NULL;
|
||||
//dummies
|
||||
pad_devices[i] = new InputDevice();
|
||||
mc_devices[i] = new InputDevice();
|
||||
}
|
||||
Power();
|
||||
}
|
||||
|
||||
InputDevice_Multitap::~InputDevice_Multitap()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
delete pad_devices[i];
|
||||
delete mc_devices[i];
|
||||
pad_devices[i] = NULL;
|
||||
mc_devices[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void InputDevice_Multitap::SetSubDevice(unsigned int sub_index, InputDevice *device, InputDevice *mc_device)
|
||||
|
@ -113,6 +121,9 @@ void InputDevice_Multitap::SetSubDevice(unsigned int sub_index, InputDevice *dev
|
|||
|
||||
//printf("%d\n", sub_index);
|
||||
|
||||
delete pad_devices[sub_index];
|
||||
delete mc_devices[sub_index];
|
||||
|
||||
pad_devices[sub_index] = device;
|
||||
mc_devices[sub_index] = mc_device;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "input/negcon.h"
|
||||
#include "input/gamepad.h"
|
||||
#include "input/memcard.h"
|
||||
#include "input/multitap.h"
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
|
@ -1050,13 +1051,34 @@ struct ShockPeripheral
|
|||
{
|
||||
ePeripheralType type;
|
||||
u8 buffer[32]; //must be larger than 16+3+1 or thereabouts because the dualshock writes some rumble data into it. bleck, ill fix it later
|
||||
//TODO: test for multitap. does it need to be as large as 4 of whatever the single largest port would be?
|
||||
//well, it must manage its own stuff.. its not like we feed in external data, right?
|
||||
InputDevice* device;
|
||||
};
|
||||
|
||||
static int addressToPortNum(int address)
|
||||
{
|
||||
int portnum = SHOCK_INVALID_ADDRESS;
|
||||
//WHY did I choose 1 indexed? I dunno, let's roll with it
|
||||
if (address == 0x01) portnum = 0;
|
||||
else if (address == 0x02) portnum = 1;
|
||||
else if (address == 0x11) portnum = 2;
|
||||
else if (address == 0x21) portnum = 3;
|
||||
else if (address == 0x31) portnum = 4;
|
||||
else if (address == 0x41) portnum = 5;
|
||||
else if (address == 0x12) portnum = 6;
|
||||
else if (address == 0x22) portnum = 7;
|
||||
else if (address == 0x32) portnum = 8;
|
||||
else if (address == 0x42) portnum = 9;
|
||||
return portnum;
|
||||
}
|
||||
|
||||
struct {
|
||||
|
||||
//This is kind of redundant with the frontIO code, and should be merged with it eventually, when the configurability gets more advanced
|
||||
//"This is kind of redundant with the frontIO code, and should be merged with it eventually, when the configurability gets more advanced"
|
||||
//I dunno.
|
||||
|
||||
ShockPeripheral ports[2];
|
||||
ShockPeripheral ports[10];
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
|
@ -1067,13 +1089,12 @@ struct {
|
|||
}
|
||||
}
|
||||
|
||||
//TODO: "Take care to call ->Power() only if the device actually changed."
|
||||
//(like, is this about savestates? seems silly"
|
||||
s32 Connect(s32 address, s32 type)
|
||||
{
|
||||
//check the port address
|
||||
int portnum = address&0x0F;
|
||||
if(portnum != 1 && portnum != 2)
|
||||
return SHOCK_INVALID_ADDRESS;
|
||||
portnum--;
|
||||
int portnum = addressToPortNum(address);
|
||||
if(portnum == SHOCK_INVALID_ADDRESS) return SHOCK_INVALID_ADDRESS;
|
||||
|
||||
//check whats already there
|
||||
if(ports[portnum].type == ePeripheralType_None && type == ePeripheralType_None) return SHOCK_OK; //NOP
|
||||
|
@ -1083,35 +1104,50 @@ struct {
|
|||
if(type == ePeripheralType_None) {
|
||||
ports[portnum].type = ePeripheralType_None;
|
||||
memset(ports[portnum].buffer,0,sizeof(ports[portnum].buffer));
|
||||
FIO->SetInput(portnum, "none", ports[portnum].buffer);
|
||||
return SHOCK_OK;
|
||||
|
||||
//fall through to setup a nonexistent `next` for disconnecting, instead of returning now
|
||||
}
|
||||
|
||||
//connecting:
|
||||
const char* name = NULL;
|
||||
InputDevice* next = nullptr;
|
||||
switch(type)
|
||||
{
|
||||
case ePeripheralType_Pad: name = "gamepad"; break;
|
||||
case ePeripheralType_DualShock: name = "dualshock"; break;
|
||||
case ePeripheralType_DualAnalog: name = "dualanalog"; break;
|
||||
case ePeripheralType_NegCon: name = "negcon"; break;
|
||||
case ePeripheralType_Pad: next = Device_Gamepad_Create(); break;
|
||||
case ePeripheralType_DualShock: next = Device_DualShock_Create(); break;
|
||||
case ePeripheralType_DualAnalog: next = Device_DualAnalog_Create(false); break;
|
||||
case ePeripheralType_Multitap: next = new InputDevice_Multitap(); break;
|
||||
case ePeripheralType_NegCon: next = Device_neGcon_Create(); break;
|
||||
case ePeripheralType_None: next = new InputDevice(); break; //dummy
|
||||
break;
|
||||
default:
|
||||
return SHOCK_ERROR;
|
||||
}
|
||||
ports[portnum].type = (ePeripheralType)type;
|
||||
ports[portnum].device = next;
|
||||
memset(ports[portnum].buffer,0,sizeof(ports[portnum].buffer));
|
||||
FIO->SetInput(portnum, name, ports[portnum].buffer);
|
||||
|
||||
if (portnum == 0 || portnum == 1)
|
||||
{
|
||||
FIO->Ports[portnum] = next;
|
||||
FIO->PortData[portnum] = ports[portnum].buffer;
|
||||
}
|
||||
else {
|
||||
//must be multitap child device
|
||||
int portidx = (address & 0xF) - 1;
|
||||
int subidx = (address >> 4) - 1;
|
||||
auto tap = (InputDevice_Multitap*)FIO->Ports[portidx];
|
||||
auto mcdummy = new InputDevice();
|
||||
//next->
|
||||
tap->SetSubDevice(subidx, next, mcdummy);
|
||||
}
|
||||
|
||||
return SHOCK_OK;
|
||||
}
|
||||
|
||||
s32 PollActive(s32 address, bool clear)
|
||||
{
|
||||
//check the port address
|
||||
int portnum = address&0x0F;
|
||||
if(portnum != 1 && portnum != 2)
|
||||
return SHOCK_INVALID_ADDRESS;
|
||||
portnum--;
|
||||
int portnum = addressToPortNum(address);
|
||||
if (portnum == SHOCK_INVALID_ADDRESS) return SHOCK_INVALID_ADDRESS;
|
||||
|
||||
s32 ret = SHOCK_FALSE;
|
||||
|
||||
|
@ -1161,11 +1197,8 @@ struct {
|
|||
|
||||
s32 SetPadInput(s32 address, u32 buttons, u8 left_x, u8 left_y, u8 right_x, u8 right_y)
|
||||
{
|
||||
//check the port address
|
||||
int portnum = address&0x0F;
|
||||
if(portnum != 1 && portnum != 2)
|
||||
return SHOCK_INVALID_ADDRESS;
|
||||
portnum--;
|
||||
int portnum = addressToPortNum(address);
|
||||
if (portnum == SHOCK_INVALID_ADDRESS) return SHOCK_INVALID_ADDRESS;
|
||||
|
||||
u8* buf = ports[portnum].buffer;
|
||||
switch(ports[portnum].type)
|
||||
|
@ -1219,11 +1252,8 @@ struct {
|
|||
|
||||
s32 MemcardTransact(s32 address, ShockMemcardTransaction* transaction)
|
||||
{
|
||||
//check the port address
|
||||
int portnum = address&1;
|
||||
if(portnum != 1 && portnum != 2)
|
||||
return SHOCK_INVALID_ADDRESS;
|
||||
portnum--;
|
||||
int portnum = addressToPortNum(address);
|
||||
if (portnum == SHOCK_INVALID_ADDRESS) return SHOCK_INVALID_ADDRESS;
|
||||
|
||||
//TODO - once we get flexible here, do some extra condition checks.. whether memcards exist, etc. much like devices.
|
||||
switch(transaction->transaction)
|
||||
|
@ -1261,6 +1291,18 @@ struct {
|
|||
}
|
||||
}
|
||||
|
||||
void UpdateInput()
|
||||
{
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
for(int i=0;i<ARRAY_SIZE(ports);i++)
|
||||
{
|
||||
if(ports[i].device)
|
||||
ports[i].device->UpdateInput(ports[i].buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} s_ShockPeripheralState;
|
||||
|
||||
EW_EXPORT s32 shock_Peripheral_Connect(void* psx, s32 address, s32 type)
|
||||
|
@ -1367,7 +1409,7 @@ EW_EXPORT s32 shock_PowerOn(void* psx)
|
|||
{
|
||||
if(s_ShockState.power) return SHOCK_NOCANDO;
|
||||
|
||||
s_ShockState.power = true;
|
||||
s_ShockState.power = true;
|
||||
PSX_Power(true);
|
||||
|
||||
return SHOCK_OK;
|
||||
|
@ -1427,7 +1469,7 @@ EW_EXPORT s32 shock_Step(void* psx, eShockStep step)
|
|||
|
||||
//-------------------------
|
||||
|
||||
FIO->UpdateInput();
|
||||
s_ShockPeripheralState.UpdateInput();
|
||||
|
||||
//GPU->StartFrame(psf_loader ? NULL : espec); //a reminder that when we do psf, we will be telling the gpu not to draw
|
||||
GPU->StartFrame(&espec);
|
||||
|
|
Loading…
Reference in New Issue