Add ioMode setting in arcadedefs.

Only relevant for Pac Man Battle Royale for now.
This commit is contained in:
Jean-Philip Desjardins 2024-06-08 09:42:46 -04:00
parent a226cafb05
commit 68ee945e5c
6 changed files with 133 additions and 71 deletions

View file

@ -78,6 +78,11 @@ std::string CSys147::GetFunctionName(unsigned int functionId) const
return "unknown";
}
void CSys147::SetIoMode(IO_MODE ioMode)
{
m_ioMode = ioMode;
}
void CSys147::SetButton(unsigned int switchIndex, unsigned int padNumber, PS2::CControllerInfo::BUTTON button)
{
m_switchBindings[{padNumber, button}] = switchIndex;
@ -90,59 +95,63 @@ void CSys147::SetButtonState(unsigned int padNumber, PS2::CControllerInfo::BUTTO
{
m_switchStates[binding->second] = pressed ? 0xFF : 0x00;
}
if(padNumber != 0) return;
//Player Switches
//4 nibbles, one for each player
//In one nibble:
//Bit 0 - Up
//Bit 1 - Down
//Bit 2 - Right
//Bit 3 - Left
if(m_ioMode == IO_MODE::AI)
{
if(padNumber != 0) return;
//System Switches
//Bit 0 - Select Down
//Bit 1 - Select Up
//Bit 2 - Enter
//Bit 3 - Test
//Bit 5 - Service
//Bit 8 - P1 Enter
//Bit 9 - P3 Enter
//Bit 10 - P2 Enter
//Bit 11 - P4 Enter
uint16 systemSwitchMask = 0;
uint16 playerSwitchMask = 0;
switch(button)
{
case PS2::CControllerInfo::L1:
systemSwitchMask = 0x0008; //Test Button
break;
case PS2::CControllerInfo::DPAD_UP:
systemSwitchMask = 0x0002; //Select Up
playerSwitchMask = 0x0010;
break;
case PS2::CControllerInfo::DPAD_DOWN:
systemSwitchMask = 0x0001; //Select Down
playerSwitchMask = 0x0020;
break;
case PS2::CControllerInfo::DPAD_LEFT:
playerSwitchMask = 0x0080;
break;
case PS2::CControllerInfo::DPAD_RIGHT:
playerSwitchMask = 0x0040;
break;
case PS2::CControllerInfo::CROSS:
systemSwitchMask = 0x0404; //Enter
break;
default:
break;
}
m_systemSwitchState &= ~systemSwitchMask;
m_playerSwitchState &= ~playerSwitchMask;
if(!pressed)
{
m_systemSwitchState |= systemSwitchMask;
m_playerSwitchState |= playerSwitchMask;
//Player Switches
//4 nibbles, one for each player
//In one nibble:
//Bit 0 - Up
//Bit 1 - Down
//Bit 2 - Right
//Bit 3 - Left
//System Switches
//Bit 0 - Select Down
//Bit 1 - Select Up
//Bit 2 - Enter
//Bit 3 - Test
//Bit 5 - Service
//Bit 8 - P1 Enter
//Bit 9 - P3 Enter
//Bit 10 - P2 Enter
//Bit 11 - P4 Enter
uint16 systemSwitchMask = 0;
uint16 playerSwitchMask = 0;
switch(button)
{
case PS2::CControllerInfo::L1:
systemSwitchMask = 0x0008; //Test Button
break;
case PS2::CControllerInfo::DPAD_UP:
systemSwitchMask = 0x0002; //Select Up
playerSwitchMask = 0x0010;
break;
case PS2::CControllerInfo::DPAD_DOWN:
systemSwitchMask = 0x0001; //Select Down
playerSwitchMask = 0x0020;
break;
case PS2::CControllerInfo::DPAD_LEFT:
playerSwitchMask = 0x0080;
break;
case PS2::CControllerInfo::DPAD_RIGHT:
playerSwitchMask = 0x0040;
break;
case PS2::CControllerInfo::CROSS:
systemSwitchMask = 0x0404; //Enter
break;
default:
break;
}
m_systemSwitchState &= ~systemSwitchMask;
m_playerSwitchState &= ~playerSwitchMask;
if(!pressed)
{
m_systemSwitchState |= systemSwitchMask;
m_playerSwitchState |= playerSwitchMask;
}
}
}
@ -468,23 +477,38 @@ bool CSys147::Invoke99(uint32 method, uint32* args, uint32 argsSize, uint32* ret
}
else if(packet->command == 0x10)
{
//Some kind of I/O device related response
//Animal Kaiser uses this for dispenser
//Pac Man Battle Royale uses this for switch state
if(m_ioMode == IO_MODE::AI)
{
{
MODULE_99_PACKET reply = {};
reply.type = 2;
reply.command = 0x10;
reply.data[0] = static_cast<uint8>(m_systemSwitchState);
reply.data[1] = static_cast<uint8>(m_systemSwitchState >> 8);
reply.checksum = ComputePacketChecksum(reply);
m_pendingReplies.emplace_back(reply);
}
{
MODULE_99_PACKET reply = {};
reply.type = 3;
reply.command = 0x10;
reply.data[0x32] = 0x20;
reply.data[0x36] = static_cast<uint8>(m_playerSwitchState);
reply.data[0x37] = static_cast<uint8>(m_playerSwitchState >> 8);
reply.checksum = ComputePacketChecksum(reply);
m_pendingReplies.emplace_back(reply);
}
}
else
{
MODULE_99_PACKET reply = {};
reply.type = 2;
reply.command = 0x10;
reply.data[0] = static_cast<uint8>(m_systemSwitchState);
reply.data[1] = static_cast<uint8>(m_systemSwitchState >> 8);
reply.checksum = ComputePacketChecksum(reply);
m_pendingReplies.emplace_back(reply);
}
{
MODULE_99_PACKET reply = {};
reply.type = 3;
reply.command = 0x10;
reply.data[0x32] = 0x20;
reply.data[0x36] = static_cast<uint8>(m_playerSwitchState);
reply.data[0x37] = static_cast<uint8>(m_playerSwitchState >> 8);
reply.data[0] = packet->data[0];
reply.checksum = ComputePacketChecksum(reply);
m_pendingReplies.emplace_back(reply);
}

View file

@ -13,6 +13,12 @@ namespace Iop
class CSys147 : public CModule, public CPadInterface
{
public:
enum class IO_MODE
{
DEFAULT,
AI,
};
CSys147(CSifMan&, const std::string&);
virtual ~CSys147() = default;
@ -20,6 +26,7 @@ namespace Iop
std::string GetFunctionName(unsigned int) const override;
void Invoke(CMIPS&, unsigned int) override;
void SetIoMode(IO_MODE);
void SetButton(unsigned int, unsigned int, PS2::CControllerInfo::BUTTON);
//CPadInterface
@ -79,15 +86,18 @@ namespace Iop
std::string m_gameId;
std::map<ButtonSelector, uint8> m_switchBindings;
IO_MODE m_ioMode = IO_MODE::DEFAULT;
std::vector<MODULE_99_PACKET> m_pendingReplies;
std::map<uint8, uint8> m_switchStates;
//AI board state
uint16 m_systemSwitchState = ~0U;
uint16 m_playerSwitchState = ~0U;
std::unique_ptr<Framework::CHttpServer> m_ioServer;
std::mutex m_barcodeMutex;
std::string m_currentBarcode;
uint16 m_systemSwitchState = ~0U;
uint16 m_playerSwitchState = ~0U;
};
}
}

View file

@ -8,6 +8,13 @@
struct ARCADE_MACHINE_DEF
{
enum DRIVER
{
UNKNOWN,
NAMCO_SYSTEM_246,
NAMCO_SYSTEM_147,
};
enum class INPUT_MODE
{
DEFAULT,
@ -17,13 +24,12 @@ struct ARCADE_MACHINE_DEF
TOUCH,
};
enum DRIVER
enum class IO_MODE
{
UNKNOWN,
NAMCO_SYSTEM_246,
NAMCO_SYSTEM_147,
DEFAULT,
SYS147_AI,
};
struct PATCH
{
uint32 address = 0;
@ -43,6 +49,7 @@ struct ARCADE_MACHINE_DEF
std::map<std::string, uint32> nandMounts;
std::map<unsigned int, ButtonSelector> buttons;
INPUT_MODE inputMode = INPUT_MODE::DEFAULT;
IO_MODE ioMode = IO_MODE::DEFAULT;
std::array<float, 4> screenPosXform = {65535, 0, 65535, 0};
uint32 eeFreqScaleNumerator = 1;
uint32 eeFreqScaleDenominator = 1;

View file

@ -48,6 +48,12 @@ static const std::pair<const char*, ARCADE_MACHINE_DEF::INPUT_MODE> g_inputModeV
{ "drive", ARCADE_MACHINE_DEF::INPUT_MODE::DRIVE },
{ "touch", ARCADE_MACHINE_DEF::INPUT_MODE::TOUCH },
};
static const std::pair<const char*, ARCADE_MACHINE_DEF::IO_MODE> g_ioModeValues[] =
{
{ "default", ARCADE_MACHINE_DEF::IO_MODE::DEFAULT },
{ "sys147_ai", ARCADE_MACHINE_DEF::IO_MODE::SYS147_AI },
};
// clang-format on
template <typename ValueType>
@ -183,6 +189,11 @@ ARCADE_MACHINE_DEF ReadArcadeMachineDefinition(const fs::path& arcadeDefPath)
std::string inputModeString = defJson["inputMode"];
def.inputMode = ParseEnumValue(inputModeString.c_str(), std::begin(g_inputModeValues), std::end(g_inputModeValues));
}
if(defJson.contains("ioMode"))
{
std::string ioModeString = defJson["ioMode"];
def.ioMode = ParseEnumValue(ioModeString.c_str(), std::begin(g_ioModeValues), std::end(g_ioModeValues));
}
if(defJson.contains("screenPosXform"))
{
auto screenPosXformArray = defJson["screenPosXform"];

View file

@ -27,6 +27,15 @@ void CNamcoSys147Driver::PrepareEnvironment(CPS2VM* virtualMachine, const ARCADE
{
auto sys147Module = std::make_shared<Iop::Namco::CSys147>(*iopBios->GetSifman(), def.id);
switch(def.ioMode)
{
case ARCADE_MACHINE_DEF::IO_MODE::SYS147_AI:
sys147Module->SetIoMode(Iop::Namco::CSys147::IO_MODE::AI);
break;
default:
assert(false);
break;
}
iopBios->RegisterModule(sys147Module);
iopBios->RegisterHleModuleReplacement("S147LINK", sys147Module);
virtualMachine->m_pad->InsertListener(sys147Module.get());

View file

@ -11,6 +11,7 @@
"atfile1": 131072
}
},
"ioMode": "sys147_ai",
"boot": "atfile0:pacmanBR.elf",
"patches":
[