[XAM/INFO] - Implement multiple functions

- Implement XamIsSystemExperienceTitleId, XamIsSystemTitleId, XamIsXbox1TitleId
- Replaced is_title_system_type
- Changed XamIsCurrentTitleDash
- Reduced magic numbers
This commit is contained in:
The-Little-Wolf 2025-04-19 23:07:28 -07:00 committed by Radosław Gliński
parent afe74e3d72
commit be44b9ba33
7 changed files with 127 additions and 19 deletions

View File

@ -40,6 +40,7 @@
#include "xenia/hid/input_driver.h"
#include "xenia/hid/input_system.h"
#include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/title_id_utils.h"
#include "xenia/kernel/user_module.h"
#include "xenia/kernel/xam/achievement_manager.h"
#include "xenia/kernel/xam/xam_module.h"
@ -574,7 +575,8 @@ X_STATUS Emulator::LaunchXexFile(const std::filesystem::path& path) {
if (XSUCCEEDED(result)) {
kernel_state_->deployment_type_ = XDeploymentType::kHardDrive;
if (!kernel_state_->is_title_system_type(title_id())) {
auto title_id = kernel_state_->title_id();
if (!kernel::IsSystemTitle(title_id)) {
// Assumption that any loaded game is loaded as a disc.
kernel_state_->deployment_type_ = XDeploymentType::kOpticalDisc;
}
@ -622,7 +624,8 @@ X_STATUS Emulator::LaunchDefaultModule(const std::filesystem::path& path) {
if (XSUCCEEDED(result)) {
kernel_state_->deployment_type_ = XDeploymentType::kHardDrive;
if (!kernel_state_->is_title_system_type(title_id())) {
auto title_id = kernel_state_->title_id();
if (!kernel::IsSystemTitle(title_id)) {
// Assumption that any loaded game is loaded as a disc.
kernel_state_->deployment_type_ = XDeploymentType::kOpticalDisc;
}

View File

@ -127,18 +127,6 @@ uint32_t KernelState::title_id() const {
return 0;
}
bool KernelState::is_title_system_type(uint32_t title_id) {
if (!title_id) {
return true;
}
if ((title_id & 0xFF000000) == 0x58000000u) {
return (title_id & 0xFF0000) != 0x410000; // if 'X' but not 'XA' (XBLA)
}
return (title_id >> 16) == 0xFFFE;
}
const std::unique_ptr<xam::SpaInfo> KernelState::title_xdbf() const {
return module_xdbf(executable_module_);
}

View File

@ -185,7 +185,6 @@ class KernelState {
vfs::VirtualFileSystem* file_system() const { return file_system_; }
uint32_t title_id() const;
static bool is_title_system_type(uint32_t title_id);
const std::unique_ptr<xam::SpaInfo> title_xdbf() const;
const std::unique_ptr<xam::SpaInfo> module_xdbf(
object_ref<UserModule> exec_module) const;

View File

@ -0,0 +1,101 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2025 Xenia Canary. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_KERNEL_UTIL_TITLE_ID_UTILS_H_
#define XENIA_KERNEL_UTIL_TITLE_ID_UTILS_H_
#include <cstdint>
#include <utility>
namespace xe {
namespace kernel {
static constexpr uint32_t kXN_2001 = 0x584E07D1;
static constexpr uint32_t kXN_2002 = 0x584E07D2;
static constexpr uint32_t kDashboardID = 0xFFFE07D1;
static constexpr uint16_t GetGameId(const uint32_t title_id) {
return title_id >> 16;
}
static constexpr bool IsValidGameId(const uint32_t title_id) {
return (title_id >> 16) != 0xFFFE;
}
static constexpr std::pair<char, char> GetTitlePublisher(
const uint32_t title_id) {
const char first_char = title_id >> 24;
const char second_char = (title_id >> 16) & 0xFF;
return {first_char, second_char};
}
static constexpr bool IsXboxTitle(const uint32_t title_id) {
const auto publisher = GetTitlePublisher(title_id);
return publisher.first == 'X';
}
static constexpr bool IsXblaTitle(const uint32_t title_id) {
const auto publisher = GetTitlePublisher(title_id);
return publisher.first == 'X' && publisher.second == 'A';
}
static constexpr bool IsAppTitle(const uint32_t title_id) {
const auto publisher = GetTitlePublisher(title_id);
return publisher.first == 'X' && publisher.second == 'H' ||
publisher.first == 'X' && publisher.second == 'H';
}
static constexpr bool IsXNTitle(const uint32_t title_id) {
return title_id == kXN_2001 || title_id == kXN_2002;
}
static constexpr bool IsSystemExperienceTitle(const uint32_t title_id) {
if (IsAppTitle(title_id)) {
return true;
}
return IsXNTitle(title_id);
};
static constexpr bool IsSystemTitle(const uint32_t title_id) {
if (!title_id) {
return true;
}
if (!IsXboxTitle(title_id)) {
return IsValidGameId(title_id);
}
if (IsXblaTitle(title_id)) {
return IsValidGameId(title_id);
}
return true;
};
static constexpr bool IsOriginalXboxTitle(const uint32_t title_id) {
if (!IsValidGameId(title_id)) {
return true;
}
if (!title_id || (title_id >> 24) == 0xFF) {
return false;
}
return (title_id >> 17) < 0x7D0;
};
} // namespace kernel
} // namespace xe
#endif

View File

@ -17,6 +17,7 @@
#include "third_party/fmt/include/fmt/format.h"
#include "xenia/base/string.h"
#include "xenia/kernel/title_id_utils.h"
#include "xenia/kernel/xam/user_profile.h"
#include "xenia/xbox.h"
@ -38,7 +39,6 @@ namespace xe {
namespace kernel {
namespace xam {
constexpr uint32_t kDashboardID = 0xFFFE07D1;
const static std::string kDashboardStringID =
fmt::format("{:08X}", kDashboardID);

View File

@ -13,6 +13,7 @@
#include "xenia/base/logging.h"
#include "xenia/base/string_util.h"
#include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/title_id_utils.h"
#include "xenia/kernel/user_module.h"
#include "xenia/kernel/util/shim_utils.h"
#include "xenia/kernel/xam/xam_module.h"
@ -281,7 +282,7 @@ dword_result_t XamGetCurrentTitleId_entry() {
DECLARE_XAM_EXPORT1(XamGetCurrentTitleId, kNone, kImplemented);
dword_result_t XamIsCurrentTitleDash_entry(const ppc_context_t& ctx) {
return ctx->kernel_state->title_id() == 0xFFFE07D1;
return ctx->kernel_state->title_id() == kDashboardID;
}
DECLARE_XAM_EXPORT1(XamIsCurrentTitleDash, kNone, kImplemented);
@ -712,6 +713,21 @@ DECLARE_XAM_EXPORT1(RtlRandom, kNone, kImplemented);
dword_result_t Refresh_entry() { return X_ERROR_SUCCESS; }
DECLARE_XAM_EXPORT1(Refresh, kNone, kStub);
dword_result_t XamIsSystemExperienceTitleId_entry(dword_t title_id) {
return IsSystemExperienceTitle(title_id);
}
DECLARE_XAM_EXPORT1(XamIsSystemExperienceTitleId, kNone, kImplemented);
dword_result_t XamIsSystemTitleId_entry(dword_t title_id) {
return IsSystemTitle(title_id);
}
DECLARE_XAM_EXPORT1(XamIsSystemTitleId, kNone, kImplemented);
dword_result_t XamIsXbox1TitleId_entry(dword_t title_id) {
return IsOriginalXboxTitle(title_id);
}
DECLARE_XAM_EXPORT1(XamIsXbox1TitleId, kNone, kImplemented);
} // namespace xam
} // namespace kernel
} // namespace xe

View File

@ -10,6 +10,7 @@
#ifndef XENIA_KERNEL_XAM_XDBF_GPD_INFO_PROFILE_H_
#define XENIA_KERNEL_XAM_XDBF_GPD_INFO_PROFILE_H_
#include "xenia/kernel/title_id_utils.h"
#include "xenia/kernel/xam/xdbf/gpd_info.h"
#include "xenia/kernel/xam/xdbf/spa_info.h"
@ -24,9 +25,9 @@ namespace xam {
class GpdInfoProfile : public GpdInfo {
public:
GpdInfoProfile() : GpdInfo(0xFFFE07D1) {};
GpdInfoProfile() : GpdInfo(kDashboardID) {};
GpdInfoProfile(const std::vector<uint8_t> buffer)
: GpdInfo(0xFFFE07D1, buffer) {};
: GpdInfo(kDashboardID, buffer) {};
~GpdInfoProfile() {};