diff --git a/src/xenia/kernel/xam/xam_user.cc b/src/xenia/kernel/xam/xam_user.cc index 82a621668..45d821cfc 100644 --- a/src/xenia/kernel/xam/xam_user.cc +++ b/src/xenia/kernel/xam/xam_user.cc @@ -610,19 +610,6 @@ dword_result_t XamUserCreateAchievementEnumerator(dword_t title_id, return X_ERROR_SUCCESS; } - static uint32_t placeholder = 0; - - if (!placeholder) { - const wchar_t* placeholder_val = L""; - - placeholder = kernel_memory()->SystemHeapAlloc( - ((uint32_t)wcslen(placeholder_val) + 1) * 2); - auto* place_addr = kernel_memory()->TranslateVirtual(placeholder); - - memset(place_addr, 0, (wcslen(placeholder_val) + 1) * 2); - xe::copy_and_swap(place_addr, placeholder_val, wcslen(placeholder_val)); - } - std::vector achievements; game_gpd->GetAchievements(&achievements); @@ -638,9 +625,14 @@ dword_result_t XamUserCreateAchievementEnumerator(dword_t title_id, // very bad... // maybe we could alloc these in guest when the title GPD is first loaded? - details->label_ptr = placeholder; - details->description_ptr = placeholder; - details->unachieved_ptr = placeholder; + // Only the 1888 dashboard reallocates them every time + // Newer dashes allocates this only once + details->label_ptr = + kernel_memory()->AllocSpaceForWStringInSystemHeap(ach.label); + details->description_ptr = + kernel_memory()->AllocSpaceForWStringInSystemHeap(ach.description); + details->unachieved_ptr = + kernel_memory()->AllocSpaceForWStringInSystemHeap(ach.unachieved_desc); } XELOGD("XamUserCreateAchievementEnumerator: added %d items to enumerator", diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index c42a6095d..7ac5cea26 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -1801,4 +1801,14 @@ uint32_t PhysicalHeap::GetPhysicalAddress(uint32_t address) const { return address; } +uint32_t Memory::AllocSpaceForWStringInSystemHeap(std::wstring phrase) { + uint32_t address = SystemHeapAlloc((uint32_t)phrase.size()); + + auto* place_addr = TranslateVirtual(address); + + memset(place_addr, 0, (uint32_t)phrase.size()); + xe::copy_and_swap(place_addr, phrase.c_str(), (uint32_t)phrase.size()); + return address; +} + } // namespace xe diff --git a/src/xenia/memory.h b/src/xenia/memory.h index 9d01af167..3c7d0c93b 100644 --- a/src/xenia/memory.h +++ b/src/xenia/memory.h @@ -458,6 +458,9 @@ class Memory { // Gets the physical base heap. VirtualHeap* GetPhysicalHeap(); + // Allocate space for wstring in memory and returns its address + uint32_t AllocSpaceForWStringInSystemHeap(std::wstring phrase); + // Dumps a map of all allocated memory to the log. void DumpMap();