From 1ac267b0f22e34ea56c41278cca02a2593f9b681 Mon Sep 17 00:00:00 2001 From: florianessl Date: Wed, 19 Feb 2025 18:45:29 +0100 Subject: [PATCH] Removed function Player::IsPatchItalian() & added a new heuristic check to automatically apply the known patch config for WhiteDragon patch --- src/exe_constants.h | 38 ++++++++++++++++++++++++++++++++++++++ src/exe_reader.cpp | 33 ++++++++++++++++++++++++++++++--- src/player.cpp | 31 ------------------------------- src/player.h | 8 -------- 4 files changed, 68 insertions(+), 42 deletions(-) diff --git a/src/exe_constants.h b/src/exe_constants.h index 4d3ebf7e3e..5b11ca74e0 100644 --- a/src/exe_constants.h +++ b/src/exe_constants.h @@ -24,6 +24,22 @@ namespace ExeConstants { + enum class KnownPatchConfigurations { + //Rm2k_Italian_40, // Italian "RPG Maker 4.0" patch + Rm2k3_Italian_108, // Italian "WhiteDragon" patch + //QP_StatDelimiter, + LAST + }; + static constexpr auto kKnownPatchConfigurations = lcf::makeEnumTags( + //"Rm2k Italian 4.0", + "Rm2k3 Italian 1.08" + //"QuickPatch StatDelimiter" + ); + + static_assert(kKnownPatchConfigurations.size() == static_cast(KnownPatchConfigurations::LAST)); + + using patch_config = std::map; + constexpr size_t MAX_SIZE_CHK_PRE = 4; struct CodeAddressInfoU32 { @@ -288,4 +304,26 @@ namespace ExeConstants::RT_2K3 { not_def() }}; } + +namespace ExeConstants { + using T = Player::GameConstantType; + + std::map known_patch_configurations = { + { + KnownPatchConfigurations::Rm2k3_Italian_108, { + { T::MinVarLimit, -999999999 }, + { T::MaxVarLimit, 999999999 }, + { T::MaxEnemyHP, 999999999 }, + { T::MaxEnemySP, 999999999 }, + { T::MaxActorHP, 99999 }, + { T::MaxActorSP, 9999 }, + { T::MaxAtkBaseValue, 9999 }, + { T::MaxDefBaseValue, 9999 }, + { T::MaxSpiBaseValue, 9999 }, + { T::MaxAgiBaseValue, 9999 }, + { T::MaxDamageValue, 99999 }, + { T::MaxGoldValue, 9999999 } + }} + }; +} #endif diff --git a/src/exe_reader.cpp b/src/exe_reader.cpp index af3146b6c2..dc4c177576 100644 --- a/src/exe_reader.cpp +++ b/src/exe_reader.cpp @@ -540,11 +540,15 @@ std::map EXEReader::GetOverridenGameConstants if (extract_constant) { int32_t value = GetU32(const_ofs); - if (value != addr_info.default_val) { + auto it = game_constants.find(const_type); + if (it != game_constants.end() && it->second == value) { + // Constant override has already been applied through some other means + continue; + } + + if (value != addr_info.default_val || it != game_constants.end()) { game_constants[const_type] = value; Output::Debug("Read constant '{}': {} (default: {})", Player::kGameConstantType.tag(const_type), value, addr_info.default_val); - } else { - Output::Debug("Read constant '{}': {}", Player::kGameConstantType.tag(const_type), value); } extract_success = true; } else { @@ -562,6 +566,24 @@ std::map EXEReader::GetOverridenGameConstants Output::Debug("Assuming RPG2003 build '{}' for constant extraction", str); }; + auto apply_known_config = [&](ExeConstants::KnownPatchConfigurations conf) { + Output::Debug("Assuming known patch config '{}'", ExeConstants::kKnownPatchConfigurations.tag(static_cast(conf))); + auto it_conf = ExeConstants::known_patch_configurations.find(conf); + assert(it_conf != ExeConstants::known_patch_configurations.end()); + + for (auto it = it_conf->second.begin(); it != it_conf->second.end(); ++it) { + game_constants[it->first] = it->second; + } + }; + + auto check_for_string = [&](uint32_t offset, const char* p) { + while (*p) { + if (GetU8(offset++) != *p++) + return false; + } + return true; + }; + switch (file_info.code_size) { case 0x96600: if (file_info.entrypoint == 0x0972C4) { @@ -593,6 +615,11 @@ std::map EXEReader::GetOverridenGameConstants break; case 0xC8E00: log_version_rm2k3("1.0.8.0_1.0.8.0"); + + if (check_for_string(file_info.code_ofs + 0x08EBE0, "NoTitolo")) { + apply_known_config(ExeConstants::KnownPatchConfigurations::Rm2k3_Italian_108); + } + check_address_map(ExeConstants::RT_2K3::const_addresses_108); break; } diff --git a/src/player.cpp b/src/player.cpp index a31216e0ee..39c9970791 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -1610,16 +1610,11 @@ namespace Player::Constants { void Player::Constants::GetVariableLimits(Var_t& min_var, Var_t& max_var) { - static constexpr Var_t min_2k3_patch_italiano = -999'999'999; - static constexpr Var_t max_2k3_patch_italiano = 999'999'999; - min_var = lcf::Data::system.easyrpg_variable_min_value; TryGetOverriddenConstant(GameConstantType::MinVarLimit, min_var); if (min_var == 0) { if (Player::IsPatchManiac()) { min_var = std::numeric_limits::min(); - } else if (Player::IsPatchItalian()) { - min_var = min_2k3_patch_italiano; } else { min_var = Player::IsRPG2k3() ? Game_Variables::min_2k3 : Game_Variables::min_2k; } @@ -1629,8 +1624,6 @@ void Player::Constants::GetVariableLimits(Var_t& min_var, Var_t& max_var) { if (max_var == 0) { if (Player::IsPatchManiac()) { max_var = std::numeric_limits::max(); - } else if (Player::IsPatchItalian()) { - max_var = max_2k3_patch_italiano; } else { max_var = Player::IsRPG2k3() ? Game_Variables::max_2k3 : Game_Variables::max_2k; } @@ -1659,9 +1652,6 @@ int32_t Player::Constants::MaxEnemyHpValue() { auto& val = lcf::Data::system.easyrpg_max_enemy_hp; TryGetOverriddenConstant(GameConstantType::MaxEnemyHP, val); if (val == -1) { - if (Player::IsPatchItalian()) { - return 999'999'999; - } return Player::IsRPG2k() ? 9'999 : 99'999; } return val; @@ -1671,9 +1661,6 @@ int32_t Player::Constants::MaxEnemySpValue() { auto& val = lcf::Data::system.easyrpg_max_enemy_sp; TryGetOverriddenConstant(GameConstantType::MaxEnemySP, val); if (val == -1) { - if (Player::IsPatchItalian()) { - return 999'999'999; - } return 9'999; } return val; @@ -1683,9 +1670,6 @@ int32_t Player::Constants::MaxAtkBaseValue() { auto& val = lcf::Data::system.easyrpg_max_stat_base_value; TryGetOverriddenConstant(GameConstantType::MaxAtkBaseValue, val); if (val == -1) { - if (Player::IsPatchItalian()) { - return 9'999; - } return max_stat_base_value; } return val; @@ -1695,9 +1679,6 @@ int32_t Player::Constants::MaxDefBaseValue() { auto& val = lcf::Data::system.easyrpg_max_stat_base_value; TryGetOverriddenConstant(GameConstantType::MaxDefBaseValue, val); if (val == -1) { - if (Player::IsPatchItalian()) { - return 9'999; - } return max_stat_base_value; } return val; @@ -1707,9 +1688,6 @@ int32_t Player::Constants::MaxSpiBaseValue() { auto& val = lcf::Data::system.easyrpg_max_stat_base_value; TryGetOverriddenConstant(GameConstantType::MaxSpiBaseValue, val); if (val == -1) { - if (Player::IsPatchItalian()) { - return 9'999; - } return max_stat_base_value; } return val; @@ -1719,9 +1697,6 @@ int32_t Player::Constants::MaxAgiBaseValue() { auto& val = lcf::Data::system.easyrpg_max_stat_base_value; TryGetOverriddenConstant(GameConstantType::MaxAgiBaseValue, val); if (val == -1) { - if (Player::IsPatchItalian()) { - return 9'999; - } return max_stat_base_value; } return val; @@ -1767,9 +1742,6 @@ int32_t Player::Constants::MaxDamageValue() { auto& val = lcf::Data::system.easyrpg_max_damage; TryGetOverriddenConstant(GameConstantType::MaxDamageValue, val); if (val == -1) { - if (Player::IsPatchItalian()) { - return 99'999; - } return (Player::IsRPG2k() ? 999 : 9'999); } return val; @@ -1800,9 +1772,6 @@ int32_t Player::Constants::MaxGoldValue() { if (TryGetOverriddenConstant(GameConstantType::MaxGoldValue, max_gold)) { return max_gold; } - if (Player::IsPatchItalian()) { - return 9'999'999; - } return max_gold; } diff --git a/src/player.h b/src/player.h index 57f25ae70c..498da9f9cb 100644 --- a/src/player.h +++ b/src/player.h @@ -367,8 +367,6 @@ namespace Player { */ bool IsPatchDestiny(); - bool IsPatchItalian(); - /** * @return True when EasyRpg extensions are on */ @@ -615,12 +613,6 @@ inline bool Player::IsPatchDestiny() { return game_config.patch_destiny.Get(); } - -inline bool Player::IsPatchItalian() { - return false; - //return game_config.patch_italian.Get(); -} - inline bool Player::HasEasyRpgExtensions() { return game_config.patch_easyrpg.Get(); }