diff --git a/OpenParrot/src/Functions/Games/APM3/APM3.cpp b/OpenParrot/src/Functions/Games/APM3/APM3.cpp index 149d708..8b5b929 100644 --- a/OpenParrot/src/Functions/Games/APM3/APM3.cpp +++ b/OpenParrot/src/Functions/Games/APM3/APM3.cpp @@ -1019,6 +1019,7 @@ static InitFunction initVF5TestFunc([]() static InitFunction initGoonyaFunc([]() { HookAPM3(L"SDGX"); + Aime_hasConfirmValue = true; __int64 mainModuleBase = (__int64)GetModuleHandle(0); auto mod = LoadLibraryA(".\\Goonya Fighter_Data\\Plugins\\abaasgs.dll"); if (mod == nullptr) @@ -1231,7 +1232,7 @@ static InitFunction initFuncGGXrdAPM3([]() if (ToBool(config["General"]["Windowed"])) { MH_Initialize(); - MH_CreateHookApi(L"user32.dll", "LoadLibraryW", ClipCursorHook, NULL); + MH_CreateHookApi(L"user32.dll", "ClipCursor", ClipCursorHook, NULL); MH_EnableHook(MH_ALL_HOOKS); // force windowed diff --git a/OpenParrot/src/Functions/Games/APM3/Aime.cpp b/OpenParrot/src/Functions/Games/APM3/Aime.cpp index d4350f1..80be4e6 100644 --- a/OpenParrot/src/Functions/Games/APM3/Aime.cpp +++ b/OpenParrot/src/Functions/Games/APM3/Aime.cpp @@ -5,6 +5,7 @@ #include "Aime.h" bool Aime_isDBAliveReturnValue = true; +bool Aime_hasConfirmValue = false; bool CALLPLEB Aime_acceptConfirm() { @@ -67,7 +68,7 @@ bool CALLPLEB Aime_hasConfirm() #ifdef _LOGAPM3AIME info(true, "Aime_hasConfirm"); #endif - return false; + return Aime_hasConfirmValue; } bool CALLPLEB Aime_hasError() diff --git a/OpenParrot/src/Functions/Games/APM3/Aime.h b/OpenParrot/src/Functions/Games/APM3/Aime.h index 8e35cc2..71be3ac 100644 --- a/OpenParrot/src/Functions/Games/APM3/Aime.h +++ b/OpenParrot/src/Functions/Games/APM3/Aime.h @@ -55,4 +55,5 @@ bool CALLPLEB Aime_setLedError(); bool CALLPLEB Aime_setLedSuccess(); bool CALLPLEB Aime_start(); -extern bool Aime_isDBAliveReturnValue; \ No newline at end of file +extern bool Aime_isDBAliveReturnValue; +extern bool Aime_hasConfirmValue; \ No newline at end of file diff --git a/OpenParrot/src/Functions/Games/BNA1/Taiko.cpp b/OpenParrot/src/Functions/Games/BNA1/Taiko.cpp index 2cb3a0c..bd1121b 100644 --- a/OpenParrot/src/Functions/Games/BNA1/Taiko.cpp +++ b/OpenParrot/src/Functions/Games/BNA1/Taiko.cpp @@ -486,7 +486,7 @@ static DWORD XInputGetCapabilitiesHook(DWORD dwUserIndex, DWORD dwFlags, XINPUT_ return ERROR_DEVICE_NOT_CONNECTED; } -static InitFunction TaikoFunc([]() +static InitFunction TaikoV0Func([]() { uintptr_t imageBase = (uintptr_t)GetModuleHandleA(0); uintptr_t amBase = (uintptr_t)GetModuleHandleA("AMFrameWork.dll"); @@ -602,5 +602,123 @@ static InitFunction TaikoFunc([]() MH_CreateHookApi(L"xinput9_1_0.dll", "XInputGetCapabilities", XInputGetCapabilitiesHook, NULL); MH_EnableHook(MH_ALL_HOOKS); -}, GameID::Taiko); +}, GameID::TaikoV0); + +static InitFunction TaikoV8Func([]() +{ + uintptr_t imageBase = (uintptr_t)GetModuleHandleA(0); + uintptr_t amBase = (uintptr_t)GetModuleHandleA("AMFrameWork.dll"); + + // Skip ExitWindowsEx (reboots pc when debugging) + injector::MakeNOP(amBase + 0x35AB1, 10); + + // Path fixes + injector::WriteMemoryRaw(imageBase + 0xB5C538, ".\\Setting2.bin", 15, true); // g:\\Setting2.bin + injector::WriteMemoryRaw(imageBase + 0xB5C528, ".\\Setting1.bin", 15, true); // f:\\Setting1.bin + + injector::WriteMemory(amBase + 0x33EF7, 0xEB, true); // ErrorLogPathA + injector::WriteMemory(amBase + 0x3404A, 0xEB, true); // ErrorLogPathB + injector::WriteMemory(amBase + 0x34429, 0xEB, true); // CommonLogPathA + injector::WriteMemory(amBase + 0x3457C, 0xEB, true); // CommonLogPathB + injector::WriteMemory(amBase + 0x3497A, 0xEB, true); // BackupDataPathA + injector::WriteMemory(amBase + 0x34ACD, 0xEB, true); // BackupDataPathB + injector::WriteMemory(amBase + 0x148AF, 0xEB, true); // CreditLogPathA + injector::WriteMemory(amBase + 0x14A1A, 0xEB, true); // CreditLogPathB + + // Skip errors + injector::WriteMemory(imageBase + 0x239C0, 0xC3, true); + + // Respatch (currently doesn't change render resolution) + if (ToBool(config["General"]["Custom Resolution (Stretches)"])) + { + DWORD resWidth = FetchDwordInformation("General", "Resolution Width", 1920); + DWORD resHeight = FetchDwordInformation("General", "Resolution Height", 1080); + + injector::WriteMemory(imageBase + 0x35FC5B, resWidth, true); + injector::WriteMemory(imageBase + 0x35FC62, resHeight, true); + } + + // Fixes by the Taiko community (thanks Swigz, Samyuu and Mon!) + if (ToBool(config["General"]["FixAnimationsEnable"])) + { + DWORD aniFps = FetchDwordInformation("General", "FixAnimationsFps", 120); + + injector::WriteMemory(imageBase + 0xB1A2D4, 1.0f / (float)aniFps * 1000.0f, true); // Enso Game Frame Time + injector::WriteMemory(imageBase + 0xB7755C, 0.0166800003498793f / 120.0f * (float)aniFps, true); // Model Animation 60 FPS Frame Time Factor + injector::WriteMemory(imageBase + 0xB77730, (double)aniFps, true); // Lua Common.FPS + injector::WriteMemory(imageBase + 0xB77814, (float)aniFps, true); // Compressed Animation Frame Rate + } + + if (ToBool(config["General"]["UnlockAllSongs"])) + { + injector::WriteMemoryRaw(imageBase + 0x314E8D, "\xB0\x01", 2, true); // 32 C0 (XOR AL, AL) -> B0 01 (MOV AL, 1) + } + + if (ToBool(config["General"]["SharedAudioMode"])) + { + injector::WriteMemory(imageBase + 0x692E17, 0xEB, true); // 74 (JZ) -> EB (JMP) + } + + // Hooks + MH_Initialize(); + + MH_CreateHookApi(L"user32.dll", "CreateWindowExW", CreateWindowExWHook, (void**)&CreateWindowExWOri); + MH_CreateHookApi(L"user32.dll", "ShowCursor", ShowCursorHook, (void**)&ShowCursorOri); + + MH_CreateHookApi(L"bnusio.dll", "bnusio_ClearSram", bnusio_ClearSram, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_Close", bnusio_Close, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_Communication", bnusio_Communication, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_DecCoin", bnusio_DecCoin, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_DecService", bnusio_DecService, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetAnalogIn", bnusio_GetAnalogIn, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetBuffer", bnusio_GetBuffer, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetCDOut", bnusio_GetCDOut, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetCoin", bnusio_GetCoin, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetCoinError", bnusio_GetCoinError, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetCoinLock", bnusio_GetCoinLock, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetEncoder", bnusio_GetEncoder, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetExpansionMode", bnusio_GetExpansionMode, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetFirmwareVersion", bnusio_GetFirmwareVersion, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetGout", bnusio_GetGout, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetHopOut", bnusio_GetHopOut, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetIoBoardName", bnusio_GetIoBoardName, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetRegisterU16", bnusio_GetRegisterU16, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetRegisterU8", bnusio_GetRegisterU8, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetService", bnusio_GetService, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetServiceError", bnusio_GetServiceError, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetStatusU16", bnusio_GetStatusU16, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetStatusU8", bnusio_GetStatusU8, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetSwIn", bnusio_GetSwIn, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetSwIn64", bnusio_GetSwIn64, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_GetSystemError", bnusio_GetSystemError, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_IsConnected", bnusio_IsConnected, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_IsWideUsio", bnusio_IsWideUsio, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_Open", bnusio_Open, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_ResetCoin", bnusio_ResetCoin, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_ResetIoBoard", bnusio_ResetIoBoard, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_SetBuffer", bnusio_SetBuffer, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_SetCDOut", bnusio_SetCDOut, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_SetCoinLock", bnusio_SetCoinLock, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_SetExpansionMode", bnusio_SetExpansionMode, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_SetGout", bnusio_SetGout, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_SetHopOut", bnusio_SetHopOut, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_SetHopperLimit", bnusio_SetHopperLimit, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_SetHopperRequest", bnusio_SetHopperRequest, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_SetPLCounter", bnusio_SetPLCounter, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_SetRegisterU16", bnusio_SetRegisterU16, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_SetRegisterU8", bnusio_SetRegisterU8, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_SetSystemError", bnusio_SetSystemError, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_SramRead", bnusio_SramRead, NULL); + MH_CreateHookApi(L"bnusio.dll", "bnusio_SramWrite", bnusio_SramWrite, NULL); + + MH_CreateHookApi(L"nbamUsbFinder.dll", "nbamUsbFinderInitialize", nbamUsbFinderInitialize, NULL); + MH_CreateHookApi(L"nbamUsbFinder.dll", "nbamUsbFinderRelease", nbamUsbFinderRelease, NULL); + MH_CreateHookApi(L"nbamUsbFinder.dll", "nbamUsbFinderGetSerialNumber", nbamUsbFinderGetSerialNumber, NULL); + + MH_CreateHookApi(L"xinput9_1_0.dll", "XInputGetState", XInputGetStateHook, NULL); + MH_CreateHookApi(L"xinput9_1_0.dll", "XInputSetState", XInputSetStateHook, NULL); + MH_CreateHookApi(L"xinput9_1_0.dll", "XInputGetCapabilities", XInputGetCapabilitiesHook, NULL); + + MH_EnableHook(MH_ALL_HOOKS); +}, GameID::TaikoV8); #endif \ No newline at end of file diff --git a/OpenParrot/src/Functions/Games/TypeX2/TypeX2Generic.cpp b/OpenParrot/src/Functions/Games/TypeX2/TypeX2Generic.cpp index d10a418..0b16d96 100644 --- a/OpenParrot/src/Functions/Games/TypeX2/TypeX2Generic.cpp +++ b/OpenParrot/src/Functions/Games/TypeX2/TypeX2Generic.cpp @@ -182,7 +182,7 @@ static HANDLE __stdcall CreateFileAWrap(LPCSTR lpFileName, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { - if (GameDetect::X2Type == X2Type::BG4 || GameDetect::X2Type == X2Type::BG4_Eng || GameDetect::X2Type == X2Type::VRL) + if (GameDetect::X2Type == X2Type::BG4 || GameDetect::X2Type == X2Type::BG4_Eng || GameDetect::X2Type == X2Type::VRL || GameDetect::X2Type == X2Type::ElevatorActionDeathParade) { if (strncmp(lpFileName, "COM1", 4) == 0) { @@ -1108,6 +1108,24 @@ static InitFunction initFunction([]() injector::WriteMemory(imageBase + 0x1CD8, 0x01, true); } } + + if (GameDetect::currentGame == GameID::ElevatorActionDeathParade) + { + DWORD oldPageProtection = 0; + + if (ToBool(config["General"]["Windowed"])) + { + VirtualProtect((LPVOID)(imageBase + 0X18F270), 4, PAGE_EXECUTE_READWRITE, &oldPageProtection); + windowHooks hooks = { 0 }; + hooks.createWindowExA = imageBase + 0X18F270; + init_windowHooks(&hooks); + VirtualProtect((LPVOID)(imageBase + 0X18F270), 4, oldPageProtection, &oldPageProtection); + + // change window title + static const char* title = "OpenParrot - Elevator Action: Death Parade"; + injector::WriteMemory(imageBase + 0x22EC, (DWORD)title, true); + } + } }); #endif #pragma optimize("", on) diff --git a/OpenParrot/src/Functions/Types.h b/OpenParrot/src/Functions/Types.h index 218e4ea..493f1c4 100644 --- a/OpenParrot/src/Functions/Types.h +++ b/OpenParrot/src/Functions/Types.h @@ -13,5 +13,6 @@ enum class X2Type { MB4, Wontertainment, BG4_Eng, - BlazBlue + BlazBlue, + ElevatorActionDeathParade }; \ No newline at end of file diff --git a/OpenParrot/src/Utility/GameDetect.cpp b/OpenParrot/src/Utility/GameDetect.cpp index 82adba9..3b44116 100644 --- a/OpenParrot/src/Utility/GameDetect.cpp +++ b/OpenParrot/src/Utility/GameDetect.cpp @@ -671,6 +671,12 @@ void GameDetect::DetectCurrentGame() case 0x24df738f: // Under Night Proto SetGameId(GameID::UnderNightAPM3Test, "Under Night In Birth APM3 Test Menu"); break; +#ifdef _DEBUG + case 0x148CC191: // Elevator Action Death Parade + currentGame = GameID::ElevatorActionDeathParade; + X2Type = X2Type::ElevatorActionDeathParade; + break; +#endif #endif #ifdef _AMD64_ case 0xf322d053: @@ -748,7 +754,8 @@ void GameDetect::DetectCurrentGame() case 0x666f192f: // Patched GX12 SetGameId(GameID::GoonyaFighterTest, "GoonyaFighter Test Menu"); break; - case 0x8c30fa5a: + case 0x206214E6: // v1.00 + case 0x8c30fa5a: // v1.01 SetGameId(GameID::PuyoPuyoEsports, "PuyoPuyoEsports"); break; case 0xe000b287: // Ver 10 @@ -781,8 +788,11 @@ void GameDetect::DetectCurrentGame() case 0x4fade723: // GGS 1.2 SetGameId(GameID::GGS, "Guilty Gear Strive"); break; - case 0x72F9B475: - SetGameId(GameID::Taiko, "Taiko no Tatsujin Nijiiro"); + case 0x72F9B475: // 00.18 + SetGameId(GameID::TaikoV0, "Taiko no Tatsujin Nijiiro (Version 00.18)"); + break; + case 0xA12445B9: + SetGameId(GameID::TaikoV8, "Taiko no Tatsujin Nijiiro (Version 08.18)"); break; case 0xd9557fd6: // Base and 1.2 case 0x8fdfa4dd: // Patched Base and 1.2 @@ -882,6 +892,7 @@ bool GameDetect::IsTypeX() case GameID::VirtuaRLimit: case GameID::MB4: case GameID::BG4_Eng: + case GameID::ElevatorActionDeathParade: return true; default: return false; diff --git a/OpenParrot/src/Utility/GameID.h b/OpenParrot/src/Utility/GameID.h index a5a70ab..7b24b94 100644 --- a/OpenParrot/src/Utility/GameID.h +++ b/OpenParrot/src/Utility/GameID.h @@ -116,7 +116,8 @@ enum class GameID UmifreshTest, RollingGunner, Aleste, - Taiko, + TaikoV0, + TaikoV8, WMMT5DX, Aleste11, CottonRocknRollA, @@ -132,5 +133,6 @@ enum class GameID KoihimeEnbuAPM3, UnderNightAPM3, UnderNightAPM3Test, - OtoshuDX + OtoshuDX, + ElevatorActionDeathParade }; \ No newline at end of file