diff --git a/src/xenia/kernel/xam/apps/xgi_app.cc b/src/xenia/kernel/xam/apps/xgi_app.cc index bb8eccd07..26006619c 100644 --- a/src/xenia/kernel/xam/apps/xgi_app.cc +++ b/src/xenia/kernel/xam/apps/xgi_app.cc @@ -24,11 +24,17 @@ namespace apps { * https://github.com/NicolasDe/AlienSwarm/blob/master/src/common/xbox/xboxstubs.h */ -struct XGI_XUSER_ACHIEVEMENT { +struct X_USER_ACHIEVEMENT { xe::be user_index; xe::be achievement_id; }; -static_assert_size(XGI_XUSER_ACHIEVEMENT, 0x8); +static_assert_size(X_USER_ACHIEVEMENT, 0x8); + +struct XGI_WRITEACHIEVEMENT { + xe::be num_achievements; + xe::be achievements_ptr; // X_USER_ACHIEVEMENT* +}; +static_assert_size(XGI_WRITEACHIEVEMENT, 0x8); struct XGI_XUSER_GET_PROPERTY { xe::be user_index; @@ -151,19 +157,27 @@ X_HRESULT XgiApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, } case 0x000B0008: { assert_true(!buffer_length || - buffer_length == sizeof(XGI_XUSER_ACHIEVEMENT)); - uint32_t achievement_count = xe::load_and_swap(buffer + 0); - uint32_t achievements_ptr = xe::load_and_swap(buffer + 4); - XELOGD("XGIUserWriteAchievements({:08X}, {:08X})", achievement_count, - achievements_ptr); + buffer_length == sizeof(X_USER_ACHIEVEMENT)); + + const XGI_WRITEACHIEVEMENT* write_achievements = + reinterpret_cast(buffer); + + const X_USER_ACHIEVEMENT* achievements = + memory_->TranslateVirtual( + write_achievements->achievements_ptr); + + XELOGD("XGIUserWriteAchievements({:08X}, {:08X})", + write_achievements->num_achievements.get(), + write_achievements->achievements_ptr.get()); + + for (uint32_t i = 0; i < write_achievements->num_achievements; i++) { + const X_USER_ACHIEVEMENT& achievement = achievements[i]; - auto* achievement = - memory_->TranslateVirtual(achievements_ptr); - for (uint32_t i = 0; i < achievement_count; i++, achievement++) { kernel_state_->achievement_manager()->EarnAchievement( - achievement->user_index, kernel_state_->title_id(), - achievement->achievement_id); + achievement.user_index, kernel_state_->title_id(), + achievement.achievement_id); } + return X_E_SUCCESS; } case 0x000B0010: {