diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 7ca6ca4e0d..2bc1b93e9c 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -341,6 +341,8 @@ set(COMMON_SRC_FILES iop/namco_arcade/Iop_NamcoAcCdvd.h iop/namco_arcade/Iop_NamcoAcRam.cpp iop/namco_arcade/Iop_NamcoAcRam.h + iop/namco_arcade/Iop_NamcoPadMan.cpp + iop/namco_arcade/Iop_NamcoPadMan.h iop/Iop_NamcoArcade.cpp iop/Iop_NamcoArcade.h iop/Iop_PadMan.cpp diff --git a/Source/iop/namco_arcade/Iop_NamcoPadMan.cpp b/Source/iop/namco_arcade/Iop_NamcoPadMan.cpp new file mode 100644 index 0000000000..21be13a58a --- /dev/null +++ b/Source/iop/namco_arcade/Iop_NamcoPadMan.cpp @@ -0,0 +1,67 @@ +#include "Iop_NamcoPadMan.h" +#include "Log.h" + +using namespace Iop; +using namespace Iop::Namco; + +#define LOG_NAME ("iop_namco_padman") + +std::string CPadMan::GetId() const +{ + return "padman"; +} + +std::string CPadMan::GetFunctionName(unsigned int) const +{ + return "unknown"; +} + +void CPadMan::RegisterSifModules(CSifMan& sif) +{ + sif.RegisterModule(MODULE_ID_1, this); + sif.RegisterModule(MODULE_ID_2, this); + sif.RegisterModule(MODULE_ID_3, this); + sif.RegisterModule(MODULE_ID_4, this); +} + +void CPadMan::Invoke(CMIPS& context, unsigned int functionId) +{ + throw std::runtime_error("Not implemented."); +} + +bool CPadMan::Invoke(uint32 method, uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram) +{ + assert(method == 1); + method = args[0]; + switch(method) + { + case 0x00000010: + Init(args, argsSize, ret, retSize, ram); + break; + case 0x00000012: + GetModuleVersion(args, argsSize, ret, retSize, ram); + break; + default: + CLog::GetInstance().Print(LOG_NAME, "Unknown method invoked (0x%08X).\r\n", method); + break; + } + return true; +} + +void CPadMan::Init(uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram) +{ + assert(retSize >= 0x10); + + CLog::GetInstance().Print(LOG_NAME, "Init();\r\n"); + + ret[3] = 1; +} + +void CPadMan::GetModuleVersion(uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram) +{ + assert(retSize >= 0x10); + + CLog::GetInstance().Print(LOG_NAME, "GetModuleVersion();\r\n"); + + ret[3] = 0x00000400; +} diff --git a/Source/iop/namco_arcade/Iop_NamcoPadMan.h b/Source/iop/namco_arcade/Iop_NamcoPadMan.h new file mode 100644 index 0000000000..b33a354c8a --- /dev/null +++ b/Source/iop/namco_arcade/Iop_NamcoPadMan.h @@ -0,0 +1,37 @@ +#pragma once + +#include "../Iop_Module.h" +#include "../Iop_SifMan.h" +#include "../Iop_SifModuleProvider.h" + +namespace Iop +{ + namespace Namco + { + class CPadMan : public CModule, public CSifModule, public CSifModuleProvider + { + public: + CPadMan() = default; + + std::string GetId() const override; + std::string GetFunctionName(unsigned int) const override; + + void RegisterSifModules(CSifMan&) override; + + void Invoke(CMIPS&, unsigned int) override; + bool Invoke(uint32, uint32*, uint32, uint32*, uint32, uint8*) override; + + enum MODULE_ID + { + MODULE_ID_1 = 0x80000100, + MODULE_ID_2 = 0x80000101, + MODULE_ID_3 = 0x8000010F, + MODULE_ID_4 = 0x8000011F, + }; + + private: + void Init(uint32*, uint32, uint32*, uint32, uint8*); + void GetModuleVersion(uint32*, uint32, uint32*, uint32, uint8*); + }; + } +} diff --git a/Source/ui_shared/ArcadeUtils.cpp b/Source/ui_shared/ArcadeUtils.cpp index 4e24edd29c..d310c1ea49 100644 --- a/Source/ui_shared/ArcadeUtils.cpp +++ b/Source/ui_shared/ArcadeUtils.cpp @@ -16,6 +16,7 @@ #include "iop/Iop_NamcoArcade.h" #include "iop/namco_arcade/Iop_NamcoAcCdvd.h" #include "iop/namco_arcade/Iop_NamcoAcRam.h" +#include "iop/namco_arcade/Iop_NamcoPadMan.h" struct ARCADE_MACHINE_DEF { @@ -276,17 +277,20 @@ void PrepareArcadeEnvironment(CPS2VM* virtualMachine, const ARCADE_MACHINE_DEF& iopBios->RegisterHleModuleReplacement("ATA/ATAPI_driver", acCdvdModule); iopBios->RegisterHleModuleReplacement("CD/DVD_Compatible", acCdvdModule); + //Taiko no Tatsujin loads and use these, but we don't have a proper HLE + //for PADMAN at the version that's provided by the SYS2x6 BIOS. + //Using our current HLE PADMAN causes the game to crash due to differences in structure layouts. + //Bloody Roar 3 also loads PADMAN and expects some response from it. + //Just provide a dummy module instead to make sure loading succeeds. + //Games rely on JVS for input anyways, so, it shouldn't be a problem if they can't use PADMAN. + auto padManModule = std::make_shared(); + iopBios->RegisterHleModuleReplacement("rom0:PADMAN", padManModule); + iopBios->RegisterHleModuleReplacement("rom0:SIO2MAN", padManModule); + { auto namcoArcadeModule = std::make_shared(*iopBios->GetSifman(), *iopBios->GetSifcmd(), *acRam, def.id); iopBios->RegisterModule(namcoArcadeModule); iopBios->RegisterHleModuleReplacement("rom0:DAEMON", namcoArcadeModule); - //Taiko no Tatsujin loads and use these, but we don't have a proper HLE - //for PADMAN at the version that's provided by the SYS2x6 BIOS. - //Using our current HLE PADMAN causes the game to crash due to differences in structure layouts. - //Just provide a dummy module instead to make sure loading succeeds. - //Games rely on JVS for input anyways, so, it shouldn't be a problem if they can't use PADMAN. - iopBios->RegisterHleModuleReplacement("rom0:PADMAN", namcoArcadeModule); - iopBios->RegisterHleModuleReplacement("rom0:SIO2MAN", namcoArcadeModule); virtualMachine->m_pad->InsertListener(namcoArcadeModule.get()); for(const auto& buttonPair : def.buttons) {