From 478dc675dc483380f111d7eb3db4f61f4f8c00cb Mon Sep 17 00:00:00 2001 From: UltiNaruto Date: Wed, 23 Dec 2020 01:11:52 +0100 Subject: [PATCH] Implemented Restore Dashing mod --- Source/Core/Core/ConfigManager.h | 1 + Source/Core/Core/Core.vcxproj | 1 + Source/Core/Core/Core.vcxproj.filters | 3 + Source/Core/Core/HotkeyManager.cpp | 5 +- Source/Core/Core/HotkeyManager.h | 1 + Source/Core/Core/PrimeHack/HackConfig.cpp | 6 + Source/Core/Core/PrimeHack/HackConfig.h | 1 + Source/Core/Core/PrimeHack/HackManager.cpp | 1 + .../Core/Core/PrimeHack/Mods/RestoreDashing.h | 137 ++++++++++++++++++ Source/Core/Core/PrimeHack/PrimeUtils.cpp | 8 +- Source/Core/Core/PrimeHack/PrimeUtils.h | 2 +- Source/Core/DolphinQt/HotkeyScheduler.cpp | 9 ++ 12 files changed, 170 insertions(+), 5 deletions(-) create mode 100644 Source/Core/Core/PrimeHack/Mods/RestoreDashing.h diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h index 78ef69282126..7d83e617f081 100644 --- a/Source/Core/Core/ConfigManager.h +++ b/Source/Core/Core/ConfigManager.h @@ -151,6 +151,7 @@ struct SConfig bool bPrimeNoclip = false; bool bPrimeInvulnerability = false; bool bPrimeSkipCutscene = false; + bool bPrimeRestoreDashing = false; // Interface settings bool bConfirmStop = false; diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index 144736de4da3..54c6fb4840bd 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -694,6 +694,7 @@ + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index 4b4e29206b1d..9e4998461748 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -1837,6 +1837,9 @@ PrimeHack + + PrimeHack\Mods + diff --git a/Source/Core/Core/HotkeyManager.cpp b/Source/Core/Core/HotkeyManager.cpp index a3cbade1faea..fbc0e4a7caef 100644 --- a/Source/Core/Core/HotkeyManager.cpp +++ b/Source/Core/Core/HotkeyManager.cpp @@ -24,7 +24,7 @@ #include "InputCommon/GCPadStatus.h" // clang-format off -constexpr std::array s_hotkey_labels{{ +constexpr std::array s_hotkey_labels{{ _trans("Open"), _trans("Change Disc"), _trans("Eject Disc"), @@ -196,6 +196,7 @@ constexpr std::array s_hotkey_labels{{ _trans("Toggle Noclip"), _trans("Toggle Invulnerability"), _trans("Toggle Skippable Cutscenes"), + _trans("Toggle Dashing Restoration"), _trans("Toggle Lock Camera In Motion Puzzles") }}; // clang-format on @@ -354,7 +355,7 @@ constexpr std::array s_groups_info = { {_trans("Select State"), HK_SELECT_STATE_SLOT_1, HK_SELECT_STATE_SLOT_10}, {_trans("Load Last State"), HK_LOAD_LAST_STATE_1, HK_LOAD_LAST_STATE_10}, {_trans("Other State Hotkeys"), HK_SAVE_FIRST_STATE, HK_LOAD_STATE_FILE}, - {_trans("PrimeHack Cheats"), HK_NOCLIP_TOGGLE, HK_SKIP_CUTSCENE}, + {_trans("PrimeHack Cheats"), HK_NOCLIP_TOGGLE, HK_RESTORE_DASHING}, {_trans("PrimeHack Graphics"), HK_MOTION_LOCK, HK_MOTION_LOCK}}}; HotkeyManager::HotkeyManager() diff --git a/Source/Core/Core/HotkeyManager.h b/Source/Core/Core/HotkeyManager.h index 3b77e5d7aafe..27b68b1a492c 100644 --- a/Source/Core/Core/HotkeyManager.h +++ b/Source/Core/Core/HotkeyManager.h @@ -181,6 +181,7 @@ enum Hotkey HK_NOCLIP_TOGGLE, HK_INVULNERABILITY_TOGGLE, HK_SKIP_CUTSCENE, + HK_RESTORE_DASHING, HK_MOTION_LOCK, NUM_HOTKEYS, diff --git a/Source/Core/Core/PrimeHack/HackConfig.cpp b/Source/Core/Core/PrimeHack/HackConfig.cpp index ddb218ee8d43..f2ebd0a1fc8d 100644 --- a/Source/Core/Core/PrimeHack/HackConfig.cpp +++ b/Source/Core/Core/PrimeHack/HackConfig.cpp @@ -10,6 +10,7 @@ #include "Core/PrimeHack/Mods/CutBeamFxMP1.h" #include "Core/PrimeHack/Mods/DisableBloom.h" #include "Core/PrimeHack/Mods/FpsControls.h" +#include "Core/PrimeHack/Mods/RestoreDashing.h" #include "Core/PrimeHack/Mods/Invulnerability.h" #include "Core/PrimeHack/Mods/Noclip.h" #include "Core/PrimeHack/Mods/SkipCutscene.h" @@ -51,6 +52,7 @@ void InitializeHack() { hack_mgr.add_mod("invulnerability", std::make_unique()); hack_mgr.add_mod("noclip", std::make_unique()); hack_mgr.add_mod("skip_cutscene", std::make_unique()); + hack_mgr.add_mod("restore_dashing", std::make_unique()); hack_mgr.add_mod("springball_button", std::make_unique()); hack_mgr.add_mod("fov_modifier", std::make_unique()); hack_mgr.add_mod("context_sensitive_controls", std::make_unique()); @@ -137,6 +139,10 @@ bool GetSkipCutscene() { return SConfig::GetInstance().bPrimeSkipCutscene; } +bool GetRestoreDashing() { + return SConfig::GetInstance().bPrimeRestoreDashing; +} + bool GetEFBTexture() { return Config::Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM); } diff --git a/Source/Core/Core/PrimeHack/HackConfig.h b/Source/Core/Core/PrimeHack/HackConfig.h index 2d95958e9b5e..8146f0c16395 100644 --- a/Source/Core/Core/PrimeHack/HackConfig.h +++ b/Source/Core/Core/PrimeHack/HackConfig.h @@ -31,6 +31,7 @@ bool GetBloom(); bool GetNoclip(); bool GetInvulnerability(); bool GetSkipCutscene(); +bool GetRestoreDashing(); bool GetEnableSecondaryGunFX(); diff --git a/Source/Core/Core/PrimeHack/HackManager.cpp b/Source/Core/Core/PrimeHack/HackManager.cpp index a066d5758231..985578a7eaac 100644 --- a/Source/Core/Core/PrimeHack/HackManager.cpp +++ b/Source/Core/Core/PrimeHack/HackManager.cpp @@ -160,6 +160,7 @@ void HackManager::update_mod_states() set_mod_enabled("noclip", GetNoclip()); set_mod_enabled("invulnerability", GetInvulnerability()); set_mod_enabled("skip_cutscene", GetSkipCutscene()); + set_mod_enabled("restore_dashing", GetRestoreDashing()); // Disallow any PrimeHack control mods if (!SConfig::GetInstance().bEnablePrimeHack) { diff --git a/Source/Core/Core/PrimeHack/Mods/RestoreDashing.h b/Source/Core/Core/PrimeHack/Mods/RestoreDashing.h new file mode 100644 index 000000000000..c7a0c1ef616c --- /dev/null +++ b/Source/Core/Core/PrimeHack/Mods/RestoreDashing.h @@ -0,0 +1,137 @@ +#pragma once + +#include "Core/PrimeHack/PrimeMod.h" +#include + +namespace prime { + class RestoreDashing : public PrimeMod { + public: + void run_mod(Game game, Region region) override {} + void init_mod(Game game, Region region) override { + // d0210014 d0010010 4b -> pattern to search for CPlayer::FinishSidewaysDash() for Prime 2 GC + // d0210024 d0010020 4b -> pattern to search for CPlayer::FinishSidewaysDash() for Prime 2 and 3 Wii + + u8 version = PowerPC::HostRead_U8(0x80000007); + + switch (game) { + case Game::PRIME_1: + if (region == Region::NTSC_U) { + // remove scan visor check + code_changes.emplace_back(0x80193334, 0x48000018); + // restore dashing speed + code_changes.emplace_back(0x80194b60, 0x4800001c); + // stop dash when done dashing + code_changes.emplace_back(0x80192cc0, 0x801f037c); // CPlayer + 0x37c + } + else if (region == Region::PAL) { + // remove scan visor check + code_changes.emplace_back(0x801935cc, 0x48000018); + // restore dashing speed + code_changes.emplace_back(0x80194df8, 0x4800001c); + // stop dash when done dashing + code_changes.emplace_back(0x80192f58, 0x801f037c); // CPlayer + 0x37c + } + else { // region == Region::NTSC-J + // remove scan visor check + code_changes.emplace_back(0x80193eb4, 0x48000018); + // restore dashing speed + code_changes.emplace_back(0x801956e0, 0x4800001c); + // stop dash when done dashing + code_changes.emplace_back(0x80193840, 0x801f037c); // CPlayer + 0x37c + } + break; + case Game::PRIME_1_GCN: + if (region == Region::NTSC_U) { + if (version == 2) { + // remove scan visor check + code_changes.emplace_back(0x802888d0, 0x48000018); + } + } + else if (region == Region::NTSC_J) { + // remove scan visor check + code_changes.emplace_back(0x802770e4, 0x48000018); + } + else if (region == Region::PAL) { + // remove scan visor check + code_changes.emplace_back(0x80275328, 0x48000018); + } + break; + case Game::PRIME_2: + if (region == Region::NTSC_U) { + // don't slow down when finishing the dash + code_changes.emplace_back(0x8015d690, 0x60000000); + // stop dash when done dashing + code_changes.emplace_back(0x8015cd1c, 0x881e0574); // CPlayer + 0x574 as u8 + } + else if (region == Region::NTSC_J) { + // don't slow down when finishing the dash + code_changes.emplace_back(0x8015cc58, 0x60000000); + // stop dash when done dashing + code_changes.emplace_back(0x8015c2e4, 0x881e0574); // CPlayer + 0x574 as u8 + } + else if (region == Region::PAL) { + // don't slow down when finishing the dash + code_changes.emplace_back(0x8015ee08, 0x60000000); + // stop dash when done dashing + code_changes.emplace_back(0x8015e494, 0x881e0574); // CPlayer + 0x574 as u8 + } + break; + case Game::PRIME_2_GCN: + if (region == Region::NTSC_U) { + // don't slow down when finishing the dash + code_changes.emplace_back(0x8018961c, 0x60000000); + // stop dash when done dashing + code_changes.emplace_back(0x80189d6c, 0x881e0588); // CPlayer + 0x588 as u8 + } + else if (region == Region::NTSC_J) { + // don't slow down when finishing the dash + code_changes.emplace_back(0x8018b130, 0x60000000); + // stop dash when done dashing + code_changes.emplace_back(0x8018b884, 0x881e0588); // CPlayer + 0x588 as u8 + } + else if (region == Region::PAL) { + // don't slow down when finishing the dash + code_changes.emplace_back(0x80189914, 0x60000000); + // stop dash when done dashing + code_changes.emplace_back(0x8018a068, 0x881e0588); // CPlayer + 0x588 as u8 + } + break; + case Game::PRIME_3: + if (region == Region::NTSC_U) { + // don't slow down when finishing the dash + code_changes.emplace_back(0x80174c60, 0x60000000); + // stop dash when done dashing + code_changes.emplace_back(0x8017432c, 0x881e06cc); // CPlayer + 0x6cc as u8 + } + else if (region == Region::PAL) { + // don't slow down when finishing the dash + code_changes.emplace_back(0x801745ac, 0x60000000); + // stop dash when done dashing + code_changes.emplace_back(0x80173c78, 0x881e06cc); // CPlayer + 0x6cc as u8 + } + break; + case Game::PRIME_3_STANDALONE: + if (region == Region::NTSC_U) { + // don't slow down when finishing the dash + code_changes.emplace_back(0x80178d90, 0x60000000); + // stop dash when done dashing + code_changes.emplace_back(0x8017845c, 0x881e06cc); // CPlayer + 0x6cc as u8 + } + else if (region == Region::NTSC_J) { + // don't slow down when finishing the dash + code_changes.emplace_back(0x8017aa90, 0x60000000); + // stop dash when done dashing + code_changes.emplace_back(0x8017a15c, 0x881e06cc); // CPlayer + 0x6cc as u8 + } + else if (region == Region::PAL) { + // don't slow down when finishing the dash + code_changes.emplace_back(0x80179884, 0x60000000); + // stop dash when done dashing + code_changes.emplace_back(0x80178F50, 0x881e06cc); // CPlayer + 0x6cc as u8 + } + break; + } + initialized = true; + } + }; +} diff --git a/Source/Core/Core/PrimeHack/PrimeUtils.cpp b/Source/Core/Core/PrimeHack/PrimeUtils.cpp index 6f24059bd597..57cb28080666 100644 --- a/Source/Core/Core/PrimeHack/PrimeUtils.cpp +++ b/Source/Core/Core/PrimeHack/PrimeUtils.cpp @@ -33,6 +33,7 @@ std::array(Game::MAX_VAL) + 1>, static u32 noclip_msg_time; static u32 invulnerability_msg_time; static u32 cutscene_msg_time; +static u32 restore_dashing_msg_time; u8 read8(u32 addr) { return PowerPC::HostRead_U8(addr); @@ -247,9 +248,9 @@ std::string GetDevInfo() } // Common::Timer::GetTimeMs() -std::tuple GetCheatsTime() +std::tuple GetCheatsTime() { - return std::make_tuple(noclip_msg_time, invulnerability_msg_time, cutscene_msg_time); + return std::make_tuple(noclip_msg_time, invulnerability_msg_time, cutscene_msg_time, restore_dashing_msg_time); } void AddCheatsTime(int index, u32 time) @@ -264,6 +265,9 @@ void AddCheatsTime(int index, u32 time) break; case 2: cutscene_msg_time = Common::Timer::GetTimeMs() + 3000; + break; + case 3: + restore_dashing_msg_time = Common::Timer::GetTimeMs() + 3000; } } diff --git a/Source/Core/Core/PrimeHack/PrimeUtils.h b/Source/Core/Core/PrimeHack/PrimeUtils.h index 2551fc50139c..92436a401556 100644 --- a/Source/Core/Core/PrimeHack/PrimeUtils.h +++ b/Source/Core/Core/PrimeHack/PrimeUtils.h @@ -44,7 +44,7 @@ void set_cursor_pos(float x, float y); void DevInfo(const char* name, const char* format, ...); void DevInfoMatrix(const char* name, const Transform& t); -std::tuple GetCheatsTime(); +std::tuple GetCheatsTime(); void AddCheatsTime(int index, u32 time); std::string GetDevInfo(); diff --git a/Source/Core/DolphinQt/HotkeyScheduler.cpp b/Source/Core/DolphinQt/HotkeyScheduler.cpp index 73687d912a80..6d5a29a0a7c6 100644 --- a/Source/Core/DolphinQt/HotkeyScheduler.cpp +++ b/Source/Core/DolphinQt/HotkeyScheduler.cpp @@ -613,8 +613,17 @@ void HotkeyScheduler::Run() OSD::AddMessage(StringFromFormat("Skippable Cutscenes: %s", new_value ? "Enabled" : "Disabled")); } + + if (IsHotkey(HK_RESTORE_DASHING)) + { + const bool new_value = !SConfig::GetInstance().bPrimeRestoreDashing; + SConfig::GetInstance().bPrimeRestoreDashing = new_value; + + OSD::AddMessage(StringFromFormat("Restore Dashing: %s", new_value ? "Enabled" : "Disabled")); + } } else { + SConfig::GetInstance().bPrimeRestoreDashing = false; SConfig::GetInstance().bPrimeSkipCutscene = false; SConfig::GetInstance().bPrimeInvulnerability = false; SConfig::GetInstance().bPrimeNoclip = false;