From 68ee945e5cd6fba0fbada7ab8253eadea77df697 Mon Sep 17 00:00:00 2001 From: Jean-Philip Desjardins Date: Sat, 8 Jun 2024 09:42:46 -0400 Subject: [PATCH] Add ioMode setting in arcadedefs. Only relevant for Pac Man Battle Royale for now. --- Source/iop/namco_sys147/Iop_NamcoSys147.cpp | 152 ++++++++++-------- Source/iop/namco_sys147/Iop_NamcoSys147.h | 14 +- Source/ui_shared/ArcadeDefinition.h | 17 +- Source/ui_shared/ArcadeUtils.cpp | 11 ++ .../arcadedrivers/NamcoSys147Driver.cpp | 9 ++ arcadedefs/pacmanbr.arcadedef | 1 + 6 files changed, 133 insertions(+), 71 deletions(-) diff --git a/Source/iop/namco_sys147/Iop_NamcoSys147.cpp b/Source/iop/namco_sys147/Iop_NamcoSys147.cpp index 231b7febe..95d3a7a64 100644 --- a/Source/iop/namco_sys147/Iop_NamcoSys147.cpp +++ b/Source/iop/namco_sys147/Iop_NamcoSys147.cpp @@ -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(m_systemSwitchState); + reply.data[1] = static_cast(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(m_playerSwitchState); + reply.data[0x37] = static_cast(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(m_systemSwitchState); - reply.data[1] = static_cast(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(m_playerSwitchState); - reply.data[0x37] = static_cast(m_playerSwitchState >> 8); + reply.data[0] = packet->data[0]; reply.checksum = ComputePacketChecksum(reply); m_pendingReplies.emplace_back(reply); } diff --git a/Source/iop/namco_sys147/Iop_NamcoSys147.h b/Source/iop/namco_sys147/Iop_NamcoSys147.h index 0bd832dc4..65173429d 100644 --- a/Source/iop/namco_sys147/Iop_NamcoSys147.h +++ b/Source/iop/namco_sys147/Iop_NamcoSys147.h @@ -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 m_switchBindings; + IO_MODE m_ioMode = IO_MODE::DEFAULT; std::vector m_pendingReplies; std::map m_switchStates; + //AI board state + uint16 m_systemSwitchState = ~0U; + uint16 m_playerSwitchState = ~0U; + std::unique_ptr m_ioServer; std::mutex m_barcodeMutex; std::string m_currentBarcode; - uint16 m_systemSwitchState = ~0U; - uint16 m_playerSwitchState = ~0U; }; } } diff --git a/Source/ui_shared/ArcadeDefinition.h b/Source/ui_shared/ArcadeDefinition.h index 622137209..58a914091 100644 --- a/Source/ui_shared/ArcadeDefinition.h +++ b/Source/ui_shared/ArcadeDefinition.h @@ -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 nandMounts; std::map buttons; INPUT_MODE inputMode = INPUT_MODE::DEFAULT; + IO_MODE ioMode = IO_MODE::DEFAULT; std::array screenPosXform = {65535, 0, 65535, 0}; uint32 eeFreqScaleNumerator = 1; uint32 eeFreqScaleDenominator = 1; diff --git a/Source/ui_shared/ArcadeUtils.cpp b/Source/ui_shared/ArcadeUtils.cpp index a2087423c..b31a42808 100644 --- a/Source/ui_shared/ArcadeUtils.cpp +++ b/Source/ui_shared/ArcadeUtils.cpp @@ -48,6 +48,12 @@ static const std::pair g_inputModeV { "drive", ARCADE_MACHINE_DEF::INPUT_MODE::DRIVE }, { "touch", ARCADE_MACHINE_DEF::INPUT_MODE::TOUCH }, }; + +static const std::pair g_ioModeValues[] = +{ + { "default", ARCADE_MACHINE_DEF::IO_MODE::DEFAULT }, + { "sys147_ai", ARCADE_MACHINE_DEF::IO_MODE::SYS147_AI }, +}; // clang-format on template @@ -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"]; diff --git a/Source/ui_shared/arcadedrivers/NamcoSys147Driver.cpp b/Source/ui_shared/arcadedrivers/NamcoSys147Driver.cpp index 3c3042426..51a84bdae 100644 --- a/Source/ui_shared/arcadedrivers/NamcoSys147Driver.cpp +++ b/Source/ui_shared/arcadedrivers/NamcoSys147Driver.cpp @@ -27,6 +27,15 @@ void CNamcoSys147Driver::PrepareEnvironment(CPS2VM* virtualMachine, const ARCADE { auto sys147Module = std::make_shared(*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()); diff --git a/arcadedefs/pacmanbr.arcadedef b/arcadedefs/pacmanbr.arcadedef index 7651477e7..942f3f16e 100644 --- a/arcadedefs/pacmanbr.arcadedef +++ b/arcadedefs/pacmanbr.arcadedef @@ -11,6 +11,7 @@ "atfile1": 131072 } }, + "ioMode": "sys147_ai", "boot": "atfile0:pacmanBR.elf", "patches": [