diff --git a/src/patches/audio.cpp b/src/patches/audio.cpp index 394faf0..89b9df0 100644 --- a/src/patches/audio.cpp +++ b/src/patches/audio.cpp @@ -41,9 +41,10 @@ FAST_HOOK_DYNAMIC (bool, LoadASIODriver, void *a1, const char *a2) { } return result; } +TestMode::Value *speakerLevel = TestMode::CreateValue(L"OutputLevelSpeakerItem"); FAST_HOOK_DYNAMIC (u64, NuscBusVolume, u64 a1, u64 a2, float a3) { if (volumeRate == 0.0f) { - int value = patches::TestMode::ReadTestModeValue (L"OutputLevelSpeakerItem"); + int value = speakerLevel->Read (); if (value == -1) return originalNuscBusVolume.fastcall (a1, a2, a3); volumeRate = value <= 100 ? 1.0f : value / 100.0f; } diff --git a/src/patches/language.cpp b/src/patches/language.cpp index 52544a3..8b787a6 100644 --- a/src/patches/language.cpp +++ b/src/patches/language.cpp @@ -546,9 +546,10 @@ FixToneName (const std::string &bankName, std::string toneName, int voiceLang) { } size_t commonSize = 0; +TestMode::Value *voiceLanguage = TestMode::CreateValue (L"VoiceLanguageItem"); FAST_HOOK_DYNAMIC (i64, PlaySoundMain, i64 a1) { LogMessage (LogLevel::HOOKS, "PlaySoundMain was called"); - int lang = TestMode::ReadTestModeValue (L"VoiceLanguageItem"); + int lang = voiceLanguage->Read (); if (lang > 0) { const std::string bankName (lua_tolstring (a1, -3, &commonSize)); if (bankName[0] == 'v') { @@ -561,7 +562,7 @@ FAST_HOOK_DYNAMIC (i64, PlaySoundMain, i64 a1) { FAST_HOOK_DYNAMIC (i64, PlaySoundMulti, i64 a1) { LogMessage (LogLevel::HOOKS, "PlaySoundMulti was called"); - int lang = TestMode::ReadTestModeValue (L"VoiceLanguageItem"); + int lang = voiceLanguage->Read (); if (lang > 0) { const std::string bankName (const_cast (lua_tolstring (a1, -3, &commonSize))); if (bankName[0] == 'v') { @@ -582,7 +583,7 @@ FixToneNameEnso (u64 *Src, const std::string &bankName, int voiceLang) { FAST_HOOK_DYNAMIC (bool, PlaySoundEnso, u64 *a1, u64 *a2, i64 a3) { LogMessage (LogLevel::HOOKS, "PlaySoundEnso was called"); - int lang = TestMode::ReadTestModeValue (L"VoiceLanguageItem"); + int lang = voiceLanguage->Read (); if (lang > 0) { const std::string bankName = a1[3] > 0x10 ? std::string (*reinterpret_cast (a1)) : std::string (reinterpret_cast (a1)); if (bankName[0] == 'v') a2 = FixToneNameEnso (a2, bankName, lang); @@ -592,7 +593,7 @@ FAST_HOOK_DYNAMIC (bool, PlaySoundEnso, u64 *a1, u64 *a2, i64 a3) { FAST_HOOK_DYNAMIC (bool, PlaySoundSpecial, u64 *a1, u64 *a2) { LogMessage (LogLevel::HOOKS, "PlaySoundSpecial was called"); - int lang = TestMode::ReadTestModeValue (L"VoiceLanguageItem"); + int lang = voiceLanguage->Read (); if (lang > 0) { const std::string bankName = a1[3] > 0x10 ? std::string (*reinterpret_cast (a1)) : std::string (reinterpret_cast (a1)); if (bankName[0] == 'v') a2 = FixToneNameEnso (a2, bankName, lang); diff --git a/src/patches/patches.h b/src/patches/patches.h index 650855a..7410622 100644 --- a/src/patches/patches.h +++ b/src/patches/patches.h @@ -50,6 +50,12 @@ class Menu : public Applicable { public: virtual void RegisterItem (Applicable *item) = 0; }; +class Value { +public: + virtual int Read() = 0; + virtual void Write(int value) = 0; + virtual void Reset() = 0; +}; typedef u64 (*RefTestModeMain) (u64); void Init (); void Append (const pugi::xml_node &node, const wchar_t *attr, const std::wstring &append); @@ -57,6 +63,7 @@ void SetupAccessor (u64 appAccessor, RefTestModeMain refTestMode); int ReadTestModeValue (const wchar_t *itemId); void SetTestModeValue (const wchar_t *itemId, int value); Menu *CreateMenu (const std::wstring &menuName, const std::wstring &menuId); +Value *CreateValue (const std::wstring &key); void RegisterItem (const std::wstring &item, const std::function &initMethod, Menu *menu); void RegisterItem (const std::wstring &item, const std::function &initMethod); void RegisterItem (const std::wstring &item, Menu *menu); diff --git a/src/patches/testmode.cpp b/src/patches/testmode.cpp index b002d64..215e675 100644 --- a/src/patches/testmode.cpp +++ b/src/patches/testmode.cpp @@ -17,6 +17,7 @@ std::thread *hookInstall; std::mutex hooksMutex; std::condition_variable hooksCV; std::vector patches = {}; +std::vector values = {}; std::wstring mergeCondition (std::wstring original, std::wstring addition, std::wstring value) { @@ -202,9 +203,38 @@ public: return nullptr; } }; - +class TestModeValue : Value { +public: + std::wstring key; + int value; + boolean reset; + TestModeValue (std::wstring key) { + this->key = key; + this->value = -1; + this->reset = true; + } + int + Read () override { + if (reset) { + this->value = ReadTestModeValue (key.c_str ()); + if (this->value != -1) { + LogMessage (LogLevel::DEBUG, L"TestMode Value({}) got val: {}", this->key, this->value); + reset = false; + } + } + return this->value; + } + void + Write (int value) override { + SetTestModeValue (this->key.c_str (), value); + this->reset = true; + } + void + Reset () override { + this->reset = true; + } +}; Menu *modManager = new RegisteredMenu (L"MOD MANAGER", L"ModManagerMenu"); -// std::vector registeredItems = {}; std::vector registeredSingleItems = {}; std::vector registeredModifies = {}; std::wstring moddedInitial = L""; @@ -227,6 +257,7 @@ FAST_HOOK_DYNAMIC (char, SceneTestModeLoading, u64 a1, u64 a2, u64 a3) { FAST_HOOK_DYNAMIC (char, SceneTestModeFinalize, u64 a1, u64 a2, u64 a3) { char result = originalSceneTestModeFinalize.fastcall (a1, a2, a3); + for (auto value : values) { value->Reset (); value->Read (); } return result; } @@ -482,8 +513,11 @@ Init () { void SetupAccessor (const u64 appAccessor, const RefTestModeMain refTestMode) { - TestMode::appAccessor = appAccessor; - TestMode::refTestMode = refTestMode; + if (TestMode::appAccessor != appAccessor) { + LogMessage (LogLevel::DEBUG, "TestMode setup!"); + TestMode::appAccessor = appAccessor; + TestMode::refTestMode = refTestMode; + } } int @@ -515,6 +549,14 @@ CreateMenu (const std::wstring &menuName, const std::wstring &menuId) { return new RegisteredMenu (menuName, menuId); } +Value * +CreateValue (const std::wstring &key) { + LogMessage (LogLevel::DEBUG, L"Create TestMode Value key: {}", key); + Value *value = (Value *)(new TestModeValue (key)); + values.push_back ((Value *)value); + return value; +} + void RegisterItem (const std::wstring &item, const std::function &initMethod, Menu *menu) { LogMessage (LogLevel::DEBUG, L"Register \nItem: {}", item); diff --git a/src/patches/versions/JPN39.cpp b/src/patches/versions/JPN39.cpp index 9db41f5..d3ab4e3 100644 --- a/src/patches/versions/JPN39.cpp +++ b/src/patches/versions/JPN39.cpp @@ -66,55 +66,62 @@ GetUserStatus () { return -1; } +TestMode::Value *unlockSongs = TestMode::CreateValue (L"ModUnlockSongs"); FAST_HOOK (bool, IsSongRelease, ASLR (0x1403F4510), i64 a1, i64 a2, int a3) { - if (TestMode::ReadTestModeValue (L"ModUnlockSongs") == 1) return true; + if (unlockSongs->Read () == 1) return true; return originalIsSongRelease.fastcall (a1, a2, a3); } FAST_HOOK (bool, IsSongReleasePlayer, ASLR (0x1403F45F0), i64 a1, u64 a2, i32 a3) { - if (TestMode::ReadTestModeValue (L"ModUnlockSongs") == 2) return true; + if (unlockSongs->Read () == 2) return true; return originalIsSongReleasePlayer.fastcall (a1, a2, a3); } MID_HOOK (DifficultyPanelCrown, ASLR (0x1403F2A25), SafetyHookContext &ctx) { - if (TestMode::ReadTestModeValue (L"ModUnlockSongs") != 1) return; + if (unlockSongs->Read () != 1) return; ctx.r15 |= 1; } +TestMode::Value *tournmentMode = TestMode::CreateValue (L"TournamentMode"); +TestMode::Value *mode024 = TestMode::CreateValue (L"ModModeCollabo024"); +TestMode::Value *mode025 = TestMode::CreateValue (L"ModModeCollabo025"); +TestMode::Value *mode026 = TestMode::CreateValue (L"ModModeCollabo026"); +TestMode::Value *modeApril001 = TestMode::CreateValue (L"ModModeAprilFool001"); FAST_HOOK (i64, AvailableMode_Collabo024, ASLR (0x1402DE710), i64 a1) { LogMessage (LogLevel::HOOKS, "AvailableMode_Collabo024 was called"); - const int tournamentMode = TestMode::ReadTestModeValue (L"TournamentMode"); + const int tournamentMode = tournmentMode->Read (); if (tournamentMode == 1) return originalAvailableMode_Collabo024.fastcall (a1); - const int status = TestMode::ReadTestModeValue (L"ModModeCollabo024"); + const int status = mode024->Read (); if (status == 1 && GetUserStatus () == 1) return lua_pushbool (a1, true); return originalAvailableMode_Collabo024.fastcall (a1); } FAST_HOOK (i64, AvailableMode_Collabo025, ASLR (0x1402DE6B0), i64 a1) { LogMessage (LogLevel::HOOKS, "AvailableMode_Collabo025 was called"); - const int tournamentMode = TestMode::ReadTestModeValue (L"TournamentMode"); + const int tournamentMode = tournmentMode->Read (); if (tournamentMode == 1) return originalAvailableMode_Collabo025.fastcall (a1); - const int status = TestMode::ReadTestModeValue (L"ModModeCollabo025"); + const int status = mode025->Read (); if (status == 1 && GetUserStatus () == 1) return lua_pushbool (a1, true); return originalAvailableMode_Collabo025.fastcall (a1); } FAST_HOOK (i64, AvailableMode_Collabo026, ASLR (0x1402DE670), i64 a1) { LogMessage (LogLevel::HOOKS, "AvailableMode_Collabo026 was called"); - const int tournamentMode = TestMode::ReadTestModeValue (L"TournamentMode"); + const int tournamentMode = tournmentMode->Read (); if (tournamentMode == 1) return originalAvailableMode_Collabo026.fastcall (a1); - const int status = TestMode::ReadTestModeValue (L"ModModeCollabo026"); + const int status = mode026->Read (); if (status == 1 && GetUserStatus () == 1) return lua_pushbool (a1, true); return originalAvailableMode_Collabo026.fastcall (a1); } FAST_HOOK (i64, AvailableMode_AprilFool001, ASLR (0x1402DE5B0), i64 a1) { LogMessage (LogLevel::HOOKS, "AvailableMode_AprilFool001 was called"); - const int tournamentMode = TestMode::ReadTestModeValue (L"TournamentMode"); + const int tournamentMode = tournmentMode->Read (); if (tournamentMode == 1) return originalAvailableMode_AprilFool001.fastcall (a1); - const int status = TestMode::ReadTestModeValue (L"ModModeAprilFool001"); + const int status = modeApril001->Read (); if (status == 1) return lua_pushbool (a1, true); return originalAvailableMode_AprilFool001.fastcall (a1); } +TestMode::Value *freezeTimer = TestMode::CreateValue (L"ModFreezeTimer"); i64 __fastcall lua_freeze_timer (const i64 a1) { LogMessage (LogLevel::HOOKS, "lua_freeze_timer was called"); - const int tournamentMode = TestMode::ReadTestModeValue (L"TournamentMode"); + const int tournamentMode = tournmentMode->Read (); if (tournamentMode == 1) return lua_pushbool (a1, true); - const int status = TestMode::ReadTestModeValue (L"ModFreezeTimer"); + const int status = freezeTimer-> Read (); if (status == 1) return lua_pushbool (a1, true); return lua_pushbool (a1, false); } @@ -221,8 +228,9 @@ FAST_HOOK (i32, SetMasterVolumeSpeaker, ASLR (0x140160330), i32 a1) { return originalSetMasterVolumeSpeaker.fastcall (a1 > 100 ? 100 : a1); } +TestMode::Value *attractDemo = TestMode::CreateValue (L"AttractDemoItem"); MID_HOOK (AttractDemo, ASLR (0x14045A720), SafetyHookContext &ctx) { - if (TestMode::ReadTestModeValue (L"AttractDemoItem") == 1) ctx.r14 = 0; + if (attractDemo->Read () == 1) ctx.r14 = 0; } // HOOK (DWORD*, AcquireMostCompatibleDisplayMode, ASLR (0x14064C870), i64 a1, DWORD *a2, DWORD *a3) {