[Xam/User_profile] - Add missing filenames & device types

- Add missing XTileType filenames
- Add missing device types
- Add XamLoaderLaunchTitle/Ex Flags
- Add ExThreadCreate flags and logging (from nukernel)
- Add more logging to user_module
- Add missing XamReadTileEx param
This commit is contained in:
The-Little-Wolf
2026-01-10 16:06:04 -08:00
committed by Radosław Gliński
parent 49c700b9c5
commit 2027f50b6e
6 changed files with 73 additions and 16 deletions

View File

@@ -764,21 +764,30 @@ void UserModule::Dump() {
case XEX_HEADER_SYSTEM_FLAGS: { case XEX_HEADER_SYSTEM_FLAGS: {
sb.AppendFormat(" XEX_HEADER_SYSTEM_FLAGS: {:08X}\n", sb.AppendFormat(" XEX_HEADER_SYSTEM_FLAGS: {:08X}\n",
static_cast<uint32_t>(opt_header.value)); static_cast<uint32_t>(opt_header.value));
uint32_t unused_flag = opt_header.value;
for (const auto& entry : xex2_system_flags_map) { for (const auto& entry : xex2_system_flags_map) {
if (opt_header.value & entry.first) { if (opt_header.value & entry.first) {
sb.AppendFormat(" {}\n", entry.second); sb.AppendFormat(" {}\n", entry.second);
unused_flag &= ~entry.first;
} }
} }
if (unused_flag) {
sb.AppendFormat(" Unk flag: {:08X}\n", unused_flag);
}
} break; } break;
case XEX_HEADER_SYSTEM_FLAGS_32: { case XEX_HEADER_SYSTEM_FLAGS_32: {
sb.AppendFormat(" XEX_HEADER_SYSTEM_FLAGS_32: {:08X}\n", sb.AppendFormat(" XEX_HEADER_SYSTEM_FLAGS_32: {:08X}\n",
static_cast<uint32_t>(opt_header.value)); static_cast<uint32_t>(opt_header.value));
uint32_t unused_flag = opt_header.value;
for (const auto& entry : xex2_system_flags_32_map) { for (const auto& entry : xex2_system_flags_32_map) {
if (opt_header.value & entry.first) { if (opt_header.value & entry.first) {
sb.AppendFormat(" {}\n", entry.second); sb.AppendFormat(" {}\n", entry.second);
unused_flag &= ~entry.first;
} }
} }
if (unused_flag) {
sb.AppendFormat(" Unk flag: {:08X}\n", unused_flag);
}
} break; } break;
case XEX_HEADER_SYSTEM_FLAGS_64: { case XEX_HEADER_SYSTEM_FLAGS_64: {
sb.Append(" XEX_HEADER_SYSTEM_FLAGS_64 (TODO):\n"); sb.Append(" XEX_HEADER_SYSTEM_FLAGS_64 (TODO):\n");

View File

@@ -77,8 +77,13 @@ enum class XTileType {
inline const std::map<XTileType, std::string> kTileFileNames = { inline const std::map<XTileType, std::string> kTileFileNames = {
{XTileType::kGamerTile, "tile_64.png"}, {XTileType::kGamerTile, "tile_64.png"},
{XTileType::kGamerTileSmall, "tile_32.png"}, {XTileType::kGamerTileSmall, "tile_32.png"},
{XTileType::kPersonalGamerTile, "tile_64.png"}, {XTileType::kLocalGamerTile, "tile_64.png"},
{XTileType::kPersonalGamerTileSmall, "tile_32.png"}, {XTileType::kLocalGamerTileSmall, "tile_32.png"},
{XTileType::kAwardedGamerTile, "64_{:08x}{:08x}{:08x}.png"},
{XTileType::kAwardedGamerTileSmall, "32_{:08x}{:08x}{:08x}.png"},
{XTileType::kGamerTileByImageId, "{:d}_{:08x}{:08x}{:08x}.png"},
{XTileType::kPersonalGamerTile, "pp_64.png"},
{XTileType::kPersonalGamerTileSmall, "pp_32.png"},
{XTileType::kAvatarGamerTile, "avtr_64.png"}, {XTileType::kAvatarGamerTile, "avtr_64.png"},
{XTileType::kAvatarGamerTileSmall, "avtr_32.png"}, {XTileType::kAvatarGamerTileSmall, "avtr_32.png"},
}; };

View File

@@ -373,6 +373,11 @@ struct X_STATS_DETAILS {
}; };
static_assert_size(X_STATS_DETAILS, 8 + kStatsMaxAmount * 2); static_assert_size(X_STATS_DETAILS, 8 + kStatsMaxAmount * 2);
enum LoaderLaunchFlags : uint32_t {
GetSystemVersion = 0x00000040, // XamUpdateGetCurrentSystemVersion
GetVersionFromExecutionId = 0x00010000,
};
} // namespace xam } // namespace xam
} // namespace kernel } // namespace kernel
} // namespace xe } // namespace xe

View File

@@ -22,8 +22,10 @@ enum class DeviceType : uint32_t {
Invalid = 0, Invalid = 0,
HDD = 1, HDD = 1,
MU = 2, // support removed in 9199 MU = 2, // support removed in 9199
System = 3,
ODD = 4, ODD = 4,
TransferCable = 8, TransferCable = 8,
Sapphire = 15,
USBMASS = 16, // Added in 8955 USBMASS = 16, // Added in 8955
}; };

View File

@@ -695,7 +695,7 @@ dword_result_t XamReadTile_entry(dword_t tile_type, dword_t title_id,
qword_t item_id, dword_t user_index, qword_t item_id, dword_t user_index,
lpdword_t output_ptr, lpdword_t output_ptr,
lpdword_t buffer_size_ptr, lpdword_t buffer_size_ptr,
lpvoid_t overlapped_ptr) { pointer_t<XAM_OVERLAPPED> overlapped_ptr) {
auto user = kernel_state()->xam_state()->GetUserProfile(user_index); auto user = kernel_state()->xam_state()->GetUserProfile(user_index);
if (!user) { if (!user) {
user = kernel_state()->xam_state()->GetUserProfile(item_id); user = kernel_state()->xam_state()->GetUserProfile(item_id);
@@ -747,9 +747,10 @@ dword_result_t XamReadTileEx_entry(dword_t tile_type, dword_t game_id,
qword_t item_id, dword_t offset, qword_t item_id, dword_t offset,
dword_t unk1, dword_t unk2, dword_t unk1, dword_t unk2,
lpdword_t output_ptr, lpdword_t output_ptr,
lpdword_t buffer_size_ptr) { lpdword_t buffer_size_ptr,
pointer_t<XAM_OVERLAPPED> overlapped_ptr) {
return XamReadTile_entry(tile_type, game_id, item_id, offset, output_ptr, return XamReadTile_entry(tile_type, game_id, item_id, offset, output_ptr,
buffer_size_ptr, 0); buffer_size_ptr, overlapped_ptr);
} }
DECLARE_XAM_EXPORT1(XamReadTileEx, kUserProfiles, kSketchy); DECLARE_XAM_EXPORT1(XamReadTileEx, kUserProfiles, kSketchy);

View File

@@ -88,6 +88,33 @@ object_ref<T> LookupNamedObject(KernelState* kernel_state,
return nullptr; return nullptr;
} }
enum CreateThreadFlags : uint32_t {
ThreadInitiallySuspended = 0x00000001,
SystemThread = 0x00000002,
PriorityClass1 = 0x00000020,
PriorityClass2 = 0x00000040,
ReturnKThreadPtr = 0x00000080,
AffinityCpu0 = 0x01000000,
AffinityCpu1 = 0x02000000,
AffinityCpu2 = 0x04000000,
AffinityCpu3 = 0x08000000,
AffinityCpu4 = 0x10000000,
AffinityCpu5 = 0x20000000,
};
inline const std::map<uint32_t, std::string> ex_thread_flag_map = {
{ThreadInitiallySuspended, "Thread Initially Suspended"},
{SystemThread, "Guest Created System Thread"},
{PriorityClass1, "Thread Priority Class 1"},
{PriorityClass2, "Thread Priority Class 2"},
{ReturnKThreadPtr, "Return Kthread Ptr"},
{AffinityCpu0, "Thread Starts At Cpu 1"},
{AffinityCpu1, "Thread Starts At Cpu 2"},
{AffinityCpu2, "Thread Starts At Cpu 3"},
{AffinityCpu3, "Thread Starts At Cpu 4"},
{AffinityCpu4, "Thread Starts At Cpu 5"},
{AffinityCpu5, "Thread Starts At Cpu 6"}};
uint32_t ExCreateThread(xe::be<uint32_t>* handle_ptr, uint32_t stack_size, uint32_t ExCreateThread(xe::be<uint32_t>* handle_ptr, uint32_t stack_size,
xe::be<uint32_t>* thread_id_ptr, xe::be<uint32_t>* thread_id_ptr,
uint32_t xapi_thread_startup, uint32_t start_address, uint32_t xapi_thread_startup, uint32_t start_address,
@@ -103,17 +130,25 @@ uint32_t ExCreateThread(xe::be<uint32_t>* handle_ptr, uint32_t stack_size,
// LPVOID StartContext, // LPVOID StartContext,
// DWORD CreationFlags // 0x80? // DWORD CreationFlags // 0x80?
auto kernel_state_var = kernel_state(); std::string summary = "ExCreateThread Active:";
// xenia_assert((creation_flags & 2) == 0); // creating system thread? uint32_t unused_flag = creation_flags;
if (creation_flags & 2) {
XELOGE("Guest is creating a system thread!");
}
uint32_t thread_process = (creation_flags & 2) for (const auto& entry : ex_thread_flag_map) {
? kernel_state_var->GetSystemProcess() if (creation_flags & entry.first) {
: kernel_state_var->GetTitleProcess(); summary += fmt::format(" {},", entry.second);
unused_flag &= ~entry.first;
}
}
if (unused_flag) {
summary += fmt::format(" Unk flag: {:08X}", unused_flag);
}
XELOGD("{}", summary);
uint32_t thread_process = (creation_flags & SystemThread)
? kernel_state()->GetSystemProcess()
: kernel_state()->GetTitleProcess();
X_KPROCESS* target_process = X_KPROCESS* target_process =
kernel_state_var->memory()->TranslateVirtual<X_KPROCESS*>(thread_process); kernel_state()->memory()->TranslateVirtual<X_KPROCESS*>(thread_process);
// Inherit default stack size // Inherit default stack size
uint32_t actual_stack_size = stack_size; uint32_t actual_stack_size = stack_size;
@@ -138,7 +173,7 @@ uint32_t ExCreateThread(xe::be<uint32_t>* handle_ptr, uint32_t stack_size,
if (XSUCCEEDED(result)) { if (XSUCCEEDED(result)) {
if (handle_ptr) { if (handle_ptr) {
if (creation_flags & 0x80) { if (creation_flags & ReturnKThreadPtr) {
*handle_ptr = thread->guest_object(); *handle_ptr = thread->guest_object();
} else { } else {
*handle_ptr = thread->handle(); *handle_ptr = thread->handle();