diff --git a/OpenParrot/src/Functions/Games/Nesica/NesicaGeneric.cpp b/OpenParrot/src/Functions/Games/Nesica/NesicaGeneric.cpp index b6d8c72..b1af3cc 100644 --- a/OpenParrot/src/Functions/Games/Nesica/NesicaGeneric.cpp +++ b/OpenParrot/src/Functions/Games/Nesica/NesicaGeneric.cpp @@ -6,6 +6,7 @@ #include "Functions/Nesica_Libs/RfidEmu.h" #include "Functions/Nesica_Libs/NesysEmu.h" #include "Functions/Nesica_Libs/RegHooks.h" +#include "Utility/Hooking.Patterns.h" static InitFunction initFunction([]() { @@ -42,6 +43,39 @@ static InitFunction initFunction_GC2([]() #endif }, GameID::GrooveCoaster2); +static InitFunction initFunction_DariusBurst([]() +{ + init_FastIoEmu(); + init_RegHooks(); + init_NesysEmu(true); + + uintptr_t imageBase = (uintptr_t)GetModuleHandleA(0); + + // Ignore cryptopipe check. + // NOTE: This could be cause for the non-working TEST MODE. No time to analyze since dump was released and we want to give instant support. + injector::WriteMemory(imageBase + 0x2CC753, 0xEB, true); + + // D: + injector::WriteMemoryRaw(imageBase + 0x482F38, "\x2E\x5C\x44", 3, true); // D:\%s%04d%02d%02d_%02d%02d%02d_ + injector::WriteMemoryRaw(imageBase + 0x4830A0, "\x2E\x5C\x44", 3, true); // D:\%s/%s/* + injector::WriteMemoryRaw(imageBase + 0x4830AC, "\x2E\x5C\x44", 3, true); // D:\%s/%s + injector::WriteMemoryRaw(imageBase + 0x4830B3, "\x2E\x5C\x44", 3, true); // D:\%s/* + injector::WriteMemoryRaw(imageBase + 0x49FC90, "\x2E\x5C\x44", 3, true); // D:\%s + injector::WriteMemoryRaw(imageBase + 0x4A269C, "\x2E\x5C\x44", 3, true); // EDData + injector::WriteMemoryRaw(imageBase + 0x4AA168, "\x2E\x5C\x44", 3, true); + injector::WriteMemoryRaw(imageBase + 0x4D460C, "\x2E\x5C\x44", 3, true); + injector::WriteMemoryRaw(imageBase + 0x4D46A8, "\x2E\x5C\x44", 3, true); // Proclog + + // D:/ + injector::WriteMemoryRaw(imageBase + 0x4D44B4, "\x2E\x5C\x44", 3, true); + + // Disable invertion of 2nd screen area + // NOTE: Nezarn is pro + injector::WriteMemoryRaw(imageBase + 0x4D4E34, "\x30\x2E\x30\x66\x20\x20\x20\x20", 8, true); // 0.0f + injector::WriteMemoryRaw(imageBase + 0x4D4E4C, "\x2A\x20\x30\x2E\x30\x66\x20\x20\x20\x20\x20\x2D", 12, true); // * 0.0f - + +}, GameID::DariusBurst); + static InitFunction initFunction_PB([]() { uintptr_t imageBase = (uintptr_t)GetModuleHandleA(0); diff --git a/OpenParrot/src/Functions/Nesica_Libs/FastIoEmu.cpp b/OpenParrot/src/Functions/Nesica_Libs/FastIoEmu.cpp index 4539bce..601a998 100644 --- a/OpenParrot/src/Functions/Nesica_Libs/FastIoEmu.cpp +++ b/OpenParrot/src/Functions/Nesica_Libs/FastIoEmu.cpp @@ -1,6 +1,7 @@ #include #include "Utility/InitFunction.h" #include +#include "Utility/GameDetect.h" static uint8_t g_fastIOValues[64]; @@ -42,6 +43,7 @@ int __cdecl iDmacDrvRegisterRead(int DeviceId, DWORD CommandCode, LPVOID OutBuff switch (CommandCode) { + // TODO: COMMAND CODES SHOULD BE DEFINED PROPERLY! case 0x400: { result = 0x00010201; @@ -51,9 +53,17 @@ int __cdecl iDmacDrvRegisterRead(int DeviceId, DWORD CommandCode, LPVOID OutBuff result = 0x00FF00FF; break; case 0x4004: - result = 0x00FF0000; + if(GameDetect::currentGame == GameID::DariusBurst) + { + // I/O error without this switch + result = 0x00FF00FF; + } + else + { + result = 0x00FF0000; + } break; - case 0x4120: + case 0x4120: // Player 1 and 2 controls result = g_fastIOValues[0] + ((DWORD)g_fastIOValues[1] * 0x100) + ((DWORD)g_fastIOValues[2] * 0x10000) + ((DWORD)g_fastIOValues[3] * 0x1000000); break; case 0x412C: @@ -97,8 +107,8 @@ int __cdecl iDmacDrvRegisterRead(int DeviceId, DWORD CommandCode, LPVOID OutBuff //if (result != 0) // CoinPackageSecond = 0; break; - case 0x41A0: - result = 0; + case 0x41A0: // Player 3 and 4 controls + result = g_fastIOValues[10] + ((DWORD)g_fastIOValues[11] * 0x100) + ((DWORD)g_fastIOValues[12] * 0x10000) + ((DWORD)g_fastIOValues[13] * 0x1000000); break; case 0x41A8: result = 0; @@ -116,7 +126,27 @@ int __cdecl iDmacDrvRegisterRead(int DeviceId, DWORD CommandCode, LPVOID OutBuff case 0x4108: result = 0; break; - + case 0x4150u: + result = 0x1823C; + break; + // Packages that are ok to return 0 for now to prevent spam... + case 0x4158: + case 0x415C: + case 0x41D0: + case 0x41D4: + case 0x41D8: + case 0x41DC: + case 0x4148: + case 0x414C: + case 0x41C8: + case 0x41CC: + result = 0; + break; + default: +#ifdef _DEBUG + info(true, "Unknown Fast I/O Request: %08X", CommandCode); +#endif + break; } *(DWORD*)OutBuffer = result; *(DWORD*)DeviceResult = 0; diff --git a/OpenParrot/src/Functions/Nesica_Libs/NesysEmu.cpp b/OpenParrot/src/Functions/Nesica_Libs/NesysEmu.cpp index 3ca3d20..2e3c340 100644 --- a/OpenParrot/src/Functions/Nesica_Libs/NesysEmu.cpp +++ b/OpenParrot/src/Functions/Nesica_Libs/NesysEmu.cpp @@ -473,13 +473,17 @@ void NesysEmu::SendResponse(nesys_command command, const void* data, size_t data free(buffer); } -void NesysEmu::Initialize() +void NesysEmu::Initialize(bool isDarius) { std::thread([=]() { while (true) { - auto pipe = CreateNamedPipeW(L"\\\\.\\pipe\\nesys_games", PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 8192, 8192, 0, nullptr); + HANDLE pipe; + if(!isDarius) + pipe = CreateNamedPipeW(L"\\\\.\\pipe\\nesys_games", PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 8192, 8192, 0, nullptr); + else + pipe = CreateNamedPipeW(L"\\\\.\\pipe\\nesystest", PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 8192, 8192, 0, nullptr); if (pipe == INVALID_HANDLE_VALUE) { @@ -537,7 +541,7 @@ void WriteNewsFile() } } -void init_NesysEmu() +void init_NesysEmu(bool IsDarius) { CreateDirectoryA("OpenParrot", nullptr); WriteNewsFile(); @@ -545,6 +549,6 @@ void init_NesysEmu() MH_CreateHookApi(L"iphlpapi.dll", "GetIfEntry", GetIfEntryFunc, (void**)&g_origGetIfEntry); MH_EnableHook(MH_ALL_HOOKS); - g_nesysEmu.Initialize(); + g_nesysEmu.Initialize(IsDarius); } #pragma optimize("", on) \ No newline at end of file diff --git a/OpenParrot/src/Functions/Nesica_Libs/NesysEmu.h b/OpenParrot/src/Functions/Nesica_Libs/NesysEmu.h index 007c5a8..dfdf052 100644 --- a/OpenParrot/src/Functions/Nesica_Libs/NesysEmu.h +++ b/OpenParrot/src/Functions/Nesica_Libs/NesysEmu.h @@ -110,7 +110,7 @@ public: ~NesysEmu(); - void Initialize(); + void Initialize(bool isDarius); void Shutdown(); @@ -141,4 +141,4 @@ private: std::map> m_commandHandlers; }; -void init_NesysEmu(); \ No newline at end of file +void init_NesysEmu(bool IsDarius = false); \ No newline at end of file diff --git a/OpenParrot/src/Functions/Nesica_Libs/RegHooks.cpp b/OpenParrot/src/Functions/Nesica_Libs/RegHooks.cpp index 0612758..3c53238 100644 --- a/OpenParrot/src/Functions/Nesica_Libs/RegHooks.cpp +++ b/OpenParrot/src/Functions/Nesica_Libs/RegHooks.cpp @@ -7,6 +7,7 @@ DWORD GameResult = 0; DWORD IOErrorCoin = 0; DWORD IOErrorCredit = 0; DWORD EventModeEnable = 0; +DWORD SystemType = 0; DWORD FillDwordInformation(const char *setting, const char *subkey, DWORD defaultValue) { @@ -230,6 +231,11 @@ LSTATUS __stdcall RegQueryValueExWWrap( *lpData = FillDwordInformation("NESiCA", "IOErrorCredit", IOErrorCredit); // UNK *lpcbData = 4; } + else if (wcscmp(lpValueName, L"SystemType") == 0) // REG_DWORD + { + *lpData = FillDwordInformation("NESiCA", "SystemType", SystemType);; // UNK + *lpcbData = 4; + } else { MessageBoxA(0, "UNKNOWN REG QUERY FROM SOFTWWARE\\TAITO\\NESiCAxLive, contact devs!", "Error", 0); diff --git a/OpenParrot/src/Utility/GameDetect.cpp b/OpenParrot/src/Utility/GameDetect.cpp index 466e15f..b674f46 100644 --- a/OpenParrot/src/Utility/GameDetect.cpp +++ b/OpenParrot/src/Utility/GameDetect.cpp @@ -385,6 +385,11 @@ void GameDetect::DetectCurrentGame() currentGame = GameID::Daytona3; break; } + if(*(uint32_t*)(moduleBase + 0x2CC751) == 0x6B75C084) + { + currentGame = GameID::DariusBurst; + break; + } #else // X64 // School of Ragnarok diff --git a/OpenParrot/src/Utility/GameID.h b/OpenParrot/src/Utility/GameID.h index a9b1c23..36382e9 100644 --- a/OpenParrot/src/Utility/GameID.h +++ b/OpenParrot/src/Utility/GameID.h @@ -47,6 +47,7 @@ enum class GameID CrimzonClover, Daytona3, MB4, + DariusBurst, GTIClub3, GRID }; \ No newline at end of file