[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: {
sb.AppendFormat(" XEX_HEADER_SYSTEM_FLAGS: {:08X}\n",
static_cast<uint32_t>(opt_header.value));
uint32_t unused_flag = opt_header.value;
for (const auto& entry : xex2_system_flags_map) {
if (opt_header.value & entry.first) {
sb.AppendFormat(" {}\n", entry.second);
unused_flag &= ~entry.first;
}
}
if (unused_flag) {
sb.AppendFormat(" Unk flag: {:08X}\n", unused_flag);
}
} break;
case XEX_HEADER_SYSTEM_FLAGS_32: {
sb.AppendFormat(" XEX_HEADER_SYSTEM_FLAGS_32: {:08X}\n",
static_cast<uint32_t>(opt_header.value));
uint32_t unused_flag = opt_header.value;
for (const auto& entry : xex2_system_flags_32_map) {
if (opt_header.value & entry.first) {
sb.AppendFormat(" {}\n", entry.second);
unused_flag &= ~entry.first;
}
}
if (unused_flag) {
sb.AppendFormat(" Unk flag: {:08X}\n", unused_flag);
}
} break;
case XEX_HEADER_SYSTEM_FLAGS_64: {
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 = {
{XTileType::kGamerTile, "tile_64.png"},
{XTileType::kGamerTileSmall, "tile_32.png"},
{XTileType::kPersonalGamerTile, "tile_64.png"},
{XTileType::kPersonalGamerTileSmall, "tile_32.png"},
{XTileType::kLocalGamerTile, "tile_64.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::kAvatarGamerTileSmall, "avtr_32.png"},
};

View File

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

View File

@@ -22,8 +22,10 @@ enum class DeviceType : uint32_t {
Invalid = 0,
HDD = 1,
MU = 2, // support removed in 9199
System = 3,
ODD = 4,
TransferCable = 8,
Sapphire = 15,
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,
lpdword_t output_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);
if (!user) {
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,
dword_t unk1, dword_t unk2,
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,
buffer_size_ptr, 0);
buffer_size_ptr, overlapped_ptr);
}
DECLARE_XAM_EXPORT1(XamReadTileEx, kUserProfiles, kSketchy);

View File

@@ -88,6 +88,33 @@ object_ref<T> LookupNamedObject(KernelState* kernel_state,
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,
xe::be<uint32_t>* thread_id_ptr,
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,
// DWORD CreationFlags // 0x80?
auto kernel_state_var = kernel_state();
// xenia_assert((creation_flags & 2) == 0); // creating system thread?
if (creation_flags & 2) {
XELOGE("Guest is creating a system thread!");
}
std::string summary = "ExCreateThread Active:";
uint32_t unused_flag = creation_flags;
uint32_t thread_process = (creation_flags & 2)
? kernel_state_var->GetSystemProcess()
: kernel_state_var->GetTitleProcess();
for (const auto& entry : ex_thread_flag_map) {
if (creation_flags & entry.first) {
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 =
kernel_state_var->memory()->TranslateVirtual<X_KPROCESS*>(thread_process);
kernel_state()->memory()->TranslateVirtual<X_KPROCESS*>(thread_process);
// Inherit default 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 (handle_ptr) {
if (creation_flags & 0x80) {
if (creation_flags & ReturnKThreadPtr) {
*handle_ptr = thread->guest_object();
} else {
*handle_ptr = thread->handle();