Merge remote-tracking branch 'GliniakRepo/TU_APPLY' into canary_experimental

This commit is contained in:
Gliniak
2022-05-19 11:00:34 +02:00
8 changed files with 132 additions and 62 deletions

View File

@@ -21,8 +21,6 @@
#include "xenia/kernel/xfile.h"
#include "xenia/kernel/xthread.h"
DEFINE_bool(xex_apply_patches, true, "Apply XEX patches.", "Kernel");
namespace xe {
namespace kernel {
@@ -35,20 +33,38 @@ uint32_t UserModule::title_id() const {
if (module_format_ != kModuleFormatXex) {
return 0;
}
auto header = xex_header();
for (uint32_t i = 0; i < header->header_count; i++) {
auto& opt_header = header->headers[i];
if (opt_header.key == XEX_HEADER_EXECUTION_INFO) {
auto opt_header_ptr =
reinterpret_cast<const uint8_t*>(header) + opt_header.offset;
auto opt_exec_info =
reinterpret_cast<const xex2_opt_execution_info*>(opt_header_ptr);
return static_cast<uint32_t>(opt_exec_info->title_id);
}
xex2_opt_execution_info* opt_exec_info = nullptr;
if (xex_module()->GetOptHeader(XEX_HEADER_EXECUTION_INFO, &opt_exec_info)) {
return static_cast<uint32_t>(opt_exec_info->title_id);
}
return 0;
}
uint32_t UserModule::disc_number() const {
if (module_format_ != kModuleFormatXex) {
return 1;
}
xex2_opt_execution_info* opt_exec_info = nullptr;
if (xex_module()->GetOptHeader(XEX_HEADER_EXECUTION_INFO, &opt_exec_info)) {
return static_cast<uint32_t>(opt_exec_info->disc_number);
}
return 1;
}
bool UserModule::is_multi_disc_title() const {
if (module_format_ != kModuleFormatXex) {
return false;
}
xex2_opt_execution_info* opt_exec_info = nullptr;
if (xex_module()->GetOptHeader(XEX_HEADER_EXECUTION_INFO, &opt_exec_info)) {
return opt_exec_info->disc_count > 1;
}
return false;
}
X_STATUS UserModule::LoadFromFile(const std::string_view path) {
X_STATUS result = X_STATUS_UNSUCCESSFUL;
@@ -97,42 +113,7 @@ X_STATUS UserModule::LoadFromFile(const std::string_view path) {
// Close the file.
file->Destroy();
}
// Only XEX returns X_STATUS_PENDING
if (result != X_STATUS_PENDING) {
return result;
}
if (cvars::xex_apply_patches) {
// Search for xexp patch file
auto patch_entry = kernel_state()->file_system()->ResolvePath(path_ + "p");
if (patch_entry) {
auto patch_path = patch_entry->absolute_path();
XELOGI("Loading XEX patch from {}", patch_path);
auto patch_module = object_ref<UserModule>(new UserModule(kernel_state_));
result = patch_module->LoadFromFile(patch_path);
if (!result) {
result = patch_module->xex_module()->ApplyPatch(xex_module());
if (result) {
XELOGE("Failed to apply XEX patch, code: {}", result);
}
} else {
XELOGE("Failed to load XEX patch, code: {}", result);
}
if (result) {
return X_STATUS_UNSUCCESSFUL;
}
}
}
CalculateHash();
XELOGI("Module hash: {:016X} for {}", hash_, name_);
return LoadXexContinue();
return result;
}
X_STATUS UserModule::LoadFromMemory(const void* addr, const size_t length) {
@@ -198,7 +179,7 @@ X_STATUS UserModule::LoadFromMemory(const void* addr, const size_t length) {
return X_STATUS_SUCCESS;
}
X_STATUS UserModule::LoadXexContinue() {
X_STATUS UserModule::LoadContinue() {
// LoadXexContinue: finishes loading XEX after a patch has been applied (or
// patch wasn't found)