[App] Improve title tracking.

[App] Improve title tracking.
[App] Show title version in emulator window title, when available.
This commit is contained in:
gibbed
2021-05-01 17:18:38 -05:00
committed by Rick Gibbed
parent 0419a9f13d
commit ea1f2b114a
3 changed files with 71 additions and 22 deletions

View File

@@ -68,7 +68,8 @@ Emulator::Emulator(const std::filesystem::path& command_line,
storage_root_(storage_root),
content_root_(content_root),
cache_root_(cache_root),
game_title_(),
title_name_(),
title_version_(),
display_window_(nullptr),
memory_(),
audio_system_(),
@@ -78,7 +79,7 @@ Emulator::Emulator(const std::filesystem::path& command_line,
file_system_(),
kernel_state_(),
main_thread_(),
title_id_(0),
title_id_({}),
paused_(false),
restoring_(false),
restore_fence_() {}
@@ -246,8 +247,9 @@ X_STATUS Emulator::TerminateTitle() {
}
kernel_state_->TerminateTitle();
title_id_ = 0;
game_title_ = "";
title_id_ = {};
title_name_ = "";
title_version_ = "";
on_terminate();
return X_STATUS_SUCCESS;
}
@@ -419,7 +421,10 @@ bool Emulator::SaveToFile(const std::filesystem::path& path) {
// Save the emulator state to a file
ByteStream stream(map->data(), map->size());
stream.Write('XSAV');
stream.Write(title_id_);
stream.Write(title_id_.has_value());
if (title_id_.has_value()) {
stream.Write(title_id_.value());
}
// It's important we don't hold the global lock here! XThreads need to step
// forward (possibly through guarded regions) without worry!
@@ -453,8 +458,15 @@ bool Emulator::RestoreFromFile(const std::filesystem::path& path) {
return false;
}
auto title_id = stream.Read<uint32_t>();
if (title_id != title_id_) {
auto has_title_id = stream.Read<bool>();
std::optional<uint32_t> title_id;
if (!has_title_id) {
title_id = {};
} else {
title_id = stream.Read<uint32_t>();
}
if (title_id_.has_value() != title_id.has_value() ||
title_id_.value() != title_id.value()) {
// Swapping between titles is unsupported at the moment.
assert_always();
return false;
@@ -642,11 +654,28 @@ std::string Emulator::FindLaunchModule() {
return path + default_module;
}
static std::string format_version(xex2_version version) {
// fmt::format doesn't like bit fields
uint32_t major, minor, build, qfe;
major = version.major;
minor = version.minor;
build = version.build;
qfe = version.qfe;
if (qfe) {
return fmt::format("{}.{}.{}.{}", major, minor, build, qfe);
}
if (build) {
return fmt::format("{}.{}.{}", major, minor, build);
}
return fmt::format("{}.{}", major, minor);
}
X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path,
const std::string_view module_path) {
// Reset state.
title_id_ = 0;
game_title_ = "";
title_id_ = {};
title_name_ = "";
title_version_ = "";
display_window_->SetIcon(nullptr, 0);
// Allow xam to request module loads.
@@ -662,8 +691,15 @@ X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path,
// Grab the current title ID.
xex2_opt_execution_info* info = nullptr;
module->GetOptHeader(XEX_HEADER_EXECUTION_INFO, &info);
if (info) {
if (!info) {
title_id_ = 0;
} else {
title_id_ = info->title_id;
auto title_version = info->version();
if (title_version.value != 0) {
title_version_ = format_version(title_version);
}
}
// Try and load the resource database (xex only).
@@ -678,10 +714,10 @@ X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path,
module->memory()->TranslateVirtual(resource_data), resource_size);
if (db.is_valid()) {
// TODO(gibbed): get title respective to user locale.
game_title_ = db.title(kernel::util::XdbfLocale::kEnglish);
if (game_title_.empty()) {
title_name_ = db.title(kernel::util::XdbfLocale::kEnglish);
if (title_name_.empty()) {
// If English title is unavailable, get the title in default locale.
game_title_ = db.title();
title_name_ = db.title();
}
auto icon_block = db.icon();
if (icon_block) {
@@ -696,7 +732,7 @@ X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path,
// playing before the video can be seen if doing this in parallel with the
// main thread.
on_shader_storage_initialization(true);
graphics_system_->InitializeShaderStorage(cache_root_, title_id_, true);
graphics_system_->InitializeShaderStorage(cache_root_, title_id_.value(), true);
on_shader_storage_initialization(false);
auto main_thread = kernel_state_->LaunchModule(module);
@@ -704,7 +740,7 @@ X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path,
return X_STATUS_UNSUCCESSFUL;
}
main_thread_ = main_thread;
on_launch(title_id_, game_title_);
on_launch(title_id_.value(), title_name_);
return X_STATUS_SUCCESS;
}