[Kernel] Added XLast Decompression

This commit is contained in:
Gliniak 2024-03-22 11:45:33 +01:00
parent 42e7f99021
commit 81dfbc2b28
5 changed files with 131 additions and 0 deletions

View File

@ -118,6 +118,7 @@ Emulator::Emulator(const std::filesystem::path& command_line,
kernel_state_(), kernel_state_(),
main_thread_(), main_thread_(),
title_id_(std::nullopt), title_id_(std::nullopt),
title_xlast_(),
paused_(false), paused_(false),
restoring_(false), restoring_(false),
restore_fence_() { restore_fence_() {
@ -1180,6 +1181,13 @@ X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path,
XELOGI("-------------------- CONTEXTS --------------------\n{}", XELOGI("-------------------- CONTEXTS --------------------\n{}",
table.str()); table.str());
uint32_t compressed_size, decompressed_size = 0;
const uint8_t* xlast_ptr =
db.ReadXLast(compressed_size, decompressed_size);
title_xlast_ =
kernel::util::XLast(xlast_ptr, compressed_size, decompressed_size);
auto icon_block = db.icon(); auto icon_block = db.icon();
if (icon_block) { if (icon_block) {
display_window_->SetIcon(icon_block.buffer, icon_block.size); display_window_->SetIcon(icon_block.buffer, icon_block.size);

View File

@ -20,6 +20,7 @@
#include "xenia/base/delegate.h" #include "xenia/base/delegate.h"
#include "xenia/base/exception_handler.h" #include "xenia/base/exception_handler.h"
#include "xenia/kernel/kernel_state.h" #include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/util/xlast.h"
#include "xenia/memory.h" #include "xenia/memory.h"
#include "xenia/patcher/patcher.h" #include "xenia/patcher/patcher.h"
#include "xenia/patcher/plugin_loader.h" #include "xenia/patcher/plugin_loader.h"
@ -298,6 +299,7 @@ class Emulator {
kernel::object_ref<kernel::XThread> main_thread_; kernel::object_ref<kernel::XThread> main_thread_;
kernel::object_ref<kernel::XHostThread> plugin_loader_thread_; kernel::object_ref<kernel::XHostThread> plugin_loader_thread_;
std::optional<uint32_t> title_id_; // Currently running title ID std::optional<uint32_t> title_id_; // Currently running title ID
kernel::util::XLast title_xlast_;
bool paused_; bool paused_;
bool restoring_; bool restoring_;

View File

@ -9,6 +9,7 @@ project("xenia-kernel")
links({ links({
"aes_128", "aes_128",
"fmt", "fmt",
"zlib",
"xenia-apu", "xenia-apu",
"xenia-base", "xenia-base",
"xenia-cpu", "xenia-cpu",

View File

@ -0,0 +1,84 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2024 Xenia Canary. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/kernel/util/xlast.h"
#include "third_party/zlib/zlib.h"
#include "xenia/base/filesystem.h"
#include "xenia/base/logging.h"
namespace xe {
namespace kernel {
namespace util {
XLast::XLast() {}
XLast::XLast(const uint8_t* compressed_xml_data,
const uint32_t compressed_data_size,
const uint32_t decompressed_data_size) {
if (!compressed_data_size || !decompressed_data_size) {
XELOGW("XLast: Current title don't have any XLast XML data!");
return;
}
xlast_decompressed_xml_.resize(decompressed_data_size);
z_stream stream;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
stream.avail_in = 0;
stream.next_in = Z_NULL;
int ret = inflateInit2(
&stream, 16 + MAX_WBITS); // 16 + MAX_WBITS enables gzip decoding
if (ret != Z_OK) {
XELOGE("XLast: Error during Zlib stream init");
return;
}
stream.avail_in = compressed_data_size;
stream.next_in =
reinterpret_cast<Bytef*>(const_cast<uint8_t*>(compressed_xml_data));
stream.avail_out = decompressed_data_size;
stream.next_out = reinterpret_cast<Bytef*>(xlast_decompressed_xml_.data());
ret = inflate(&stream, Z_NO_FLUSH);
if (ret == Z_STREAM_ERROR) {
XELOGE("XLast: Error during XLast decompression");
inflateEnd(&stream);
return;
}
inflateEnd(&stream);
}
XLast::~XLast() {}
void XLast::Dump(std::string file_name) {
if (xlast_decompressed_xml_.empty()) {
return;
}
if (file_name.empty()) {
// TODO: Read default xlast name from it and use that one.
}
FILE* outfile =
xe::filesystem::OpenFile(fmt::format("{}.xml", file_name).c_str(), "ab");
if (!outfile) {
return;
}
fwrite(xlast_decompressed_xml_.data(), 1, xlast_decompressed_xml_.size(),
outfile);
fclose(outfile);
}
} // namespace util
} // namespace kernel
} // namespace xe

View File

@ -0,0 +1,36 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2024 Xenia Canary. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_KERNEL_UTIL_XLAST_H_
#define XENIA_KERNEL_UTIL_XLAST_H_
#include <string>
#include <vector>
namespace xe {
namespace kernel {
namespace util {
class XLast {
public:
XLast();
XLast(const uint8_t* compressed_xml_data, const uint32_t compressed_data_size,
const uint32_t decompressed_data_size);
~XLast();
void Dump(std::string file_name);
private:
std::vector<uint8_t> xlast_decompressed_xml_;
};
} // namespace util
} // namespace kernel
} // namespace xe
#endif