Patch: add floating point support

Also count applied entries
This commit is contained in:
Nekotekina 2017-07-17 16:34:04 +03:00
parent e39ee10105
commit f91f2e3e6d
4 changed files with 53 additions and 12 deletions

View File

@ -14,9 +14,13 @@ void fmt_class_string<patch_type>::format(std::string& out, u64 arg)
case patch_type::le16: return "le16"; case patch_type::le16: return "le16";
case patch_type::le32: return "le32"; case patch_type::le32: return "le32";
case patch_type::le64: return "le64"; case patch_type::le64: return "le64";
case patch_type::bef32: return "bef32";
case patch_type::bef64: return "bef64";
case patch_type::be16: return "be16"; case patch_type::be16: return "be16";
case patch_type::be32: return "be32"; case patch_type::be32: return "be32";
case patch_type::be64: return "be64"; case patch_type::be64: return "be64";
case patch_type::lef32: return "lef32";
case patch_type::lef64: return "lef64";
} }
return unknown; return unknown;
@ -39,23 +43,44 @@ void patch_engine::append(const std::string& patch)
u64 type64 = 0; u64 type64 = 0;
cfg::try_to_enum_value(&type64, &fmt_class_string<patch_type>::format, patch[0].Scalar()); cfg::try_to_enum_value(&type64, &fmt_class_string<patch_type>::format, patch[0].Scalar());
struct patch info; struct patch info{};
info.type = static_cast<patch_type>(type64); info.type = static_cast<patch_type>(type64);
info.offset = patch[1].as<u32>(); info.offset = patch[1].as<u32>();
switch (info.type)
{
case patch_type::bef32:
case patch_type::lef32:
{
info.value_as<f32>() = patch[2].as<f32>();
break;
}
case patch_type::bef64:
case patch_type::lef64:
{
info.value_as<f64>() = patch[2].as<f64>();
break;
}
default:
{
info.value = patch[2].as<u64>(); info.value = patch[2].as<u64>();
break;
}
}
data.emplace_back(info); data.emplace_back(info);
} }
} }
} }
} }
void patch_engine::apply(const std::string& name, u8* dst) const std::size_t patch_engine::apply(const std::string& name, u8* dst) const
{ {
const auto found = m_map.find(name); const auto found = m_map.find(name);
if (found == m_map.cend()) if (found == m_map.cend())
{ {
return; return 0;
} }
// Apply modifications sequentially // Apply modifications sequentially
@ -76,11 +101,13 @@ void patch_engine::apply(const std::string& name, u8* dst) const
break; break;
} }
case patch_type::le32: case patch_type::le32:
case patch_type::lef32:
{ {
*reinterpret_cast<le_t<u32, 1>*>(ptr) = static_cast<u32>(p.value); *reinterpret_cast<le_t<u32, 1>*>(ptr) = static_cast<u32>(p.value);
break; break;
} }
case patch_type::le64: case patch_type::le64:
case patch_type::lef64:
{ {
*reinterpret_cast<le_t<u64, 1>*>(ptr) = static_cast<u64>(p.value); *reinterpret_cast<le_t<u64, 1>*>(ptr) = static_cast<u64>(p.value);
break; break;
@ -91,15 +118,19 @@ void patch_engine::apply(const std::string& name, u8* dst) const
break; break;
} }
case patch_type::be32: case patch_type::be32:
case patch_type::bef32:
{ {
*reinterpret_cast<be_t<u32, 1>*>(ptr) = static_cast<u32>(p.value); *reinterpret_cast<be_t<u32, 1>*>(ptr) = static_cast<u32>(p.value);
break; break;
} }
case patch_type::be64: case patch_type::be64:
case patch_type::bef64:
{ {
*reinterpret_cast<be_t<u64, 1>*>(ptr) = static_cast<u64>(p.value); *reinterpret_cast<be_t<u64, 1>*>(ptr) = static_cast<u64>(p.value);
break; break;
} }
} }
} }
return found->second.size();
} }

View File

@ -11,9 +11,13 @@ enum class patch_type
le16, le16,
le32, le32,
le64, le64,
lef32,
lef64,
be16, be16,
be32, be32,
be64, be64,
bef32,
bef64,
}; };
class patch_engine class patch_engine
@ -23,6 +27,12 @@ class patch_engine
patch_type type; patch_type type;
u32 offset; u32 offset;
u64 value; u64 value;
template <typename T>
T& value_as()
{
return *reinterpret_cast<T*>(reinterpret_cast<char*>(&value));
}
}; };
// Database // Database
@ -32,6 +42,6 @@ public:
// Load from file // Load from file
void append(const std::string& path); void append(const std::string& path);
// Apply patch // Apply patch (returns the number of entries applied)
void apply(const std::string& name, u8* dst) const; std::size_t apply(const std::string& name, u8* dst) const;
}; };

View File

@ -1029,15 +1029,15 @@ void ppu_load_exec(const ppu_exec_object& elf)
} }
// Apply the patch // Apply the patch
fxm::check_unlocked<patch_engine>()->apply(hash, vm::g_base_addr); auto applied = fxm::check_unlocked<patch_engine>()->apply(hash, vm::g_base_addr);
if (!Emu.GetTitleID().empty()) if (!Emu.GetTitleID().empty())
{ {
// Alternative patch // Alternative patch
fxm::check_unlocked<patch_engine>()->apply(Emu.GetTitleID() + '-' + hash, vm::g_base_addr); applied += fxm::check_unlocked<patch_engine>()->apply(Emu.GetTitleID() + '-' + hash, vm::g_base_addr);
} }
LOG_NOTICE(LOADER, "PPU executable hash: %s", hash); LOG_NOTICE(LOADER, "PPU executable hash: %s (<- %u)", hash, applied);
// Initialize HLE modules // Initialize HLE modules
ppu_initialize_modules(link); ppu_initialize_modules(link);

View File

@ -135,15 +135,15 @@ void sys_spu_image::deploy(u32 loc)
} }
// Apply the patch // Apply the patch
fxm::check_unlocked<patch_engine>()->apply(hash, vm::g_base_addr + loc); auto applied = fxm::check_unlocked<patch_engine>()->apply(hash, vm::g_base_addr + loc);
if (!Emu.GetTitleID().empty()) if (!Emu.GetTitleID().empty())
{ {
// Alternative patch // Alternative patch
fxm::check_unlocked<patch_engine>()->apply(Emu.GetTitleID() + '-' + hash, vm::g_base_addr + loc); applied += fxm::check_unlocked<patch_engine>()->apply(Emu.GetTitleID() + '-' + hash, vm::g_base_addr + loc);
} }
LOG_NOTICE(LOADER, "Loaded SPU image: %s%s", hash, dump); LOG_NOTICE(LOADER, "Loaded SPU image: %s (<- %u)%s", hash, applied, dump);
} }
error_code sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu) error_code sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu)