[XAM] Fix Halo 3 aborting save load after XamShowDeviceSelectorUI call
Should let Halo 3 savegames work now (Resume Solo Game...) This changes XamShowDeviceSelectorUI code to pretty much the same code as xenia-master, with some param checks added from XAM. Looks like it was 0xB notification which made Halo 3 abort (looks like thats for when storage devices are added/removed) I guess Halo doesn't like to see that notify just after it was told the device it could make use of? I reverted the function to master since I don't really think the threading stuff is needed any more. AFAIK the threads just turned out to be a band-aid fix for the issue in https://github.com/xenia-project/xenia/pull/1417, where games could only ever see a single notification for a given ID. (Since we'd send the first notify in one thread, then wait a little while before sending in another thread, that'd gave it enough time to see both notifys - but now with the fix from that PR this band-aid isn't needed) If there's actually any regressions from removing the threading code we can easily put it back in (I'd be really interested in any games that might require this kind of thing too) The way these functions are handled (and really everything that uses XOVERLAPPED) isn't really correct tho, since they'll cause blocking in the caller thread while it does the work which the actual XAM impls don't do AFAIK. There probably should be a seperate thread that handles all that, completing the overlapped etc, but I really don't think the way I did it with this band-aid fix was the best way for it...
This commit is contained in:
parent
0a037ee453
commit
f119f5b206
|
@ -376,58 +376,27 @@ dword_result_t XamShowDeviceSelectorUI(dword_t user_index, dword_t content_type,
|
|||
qword_t total_requested,
|
||||
lpdword_t device_id_ptr,
|
||||
pointer_t<XAM_OVERLAPPED> overlapped) {
|
||||
|
||||
// Set overlapped to X_ERROR_IO_PENDING
|
||||
if (overlapped) {
|
||||
XOverlappedSetResult((void*)overlapped.host_address(), X_ERROR_IO_PENDING);
|
||||
}
|
||||
|
||||
// broadcast begin
|
||||
kernel_state()->BroadcastNotification(0x1, 1);
|
||||
// Broadcast XN_SYS_UI = true
|
||||
kernel_state()->BroadcastNotification(0x9, true);
|
||||
|
||||
auto ui_fn = [content_type, device_id_ptr, overlapped]() {
|
||||
XELOGW("XamShowDeviceSelectorUI Content_type:(%X) device_id_ptr: %.8X overlapped:(%X)",
|
||||
content_type, device_id_ptr, (bool)overlapped);
|
||||
|
||||
// NOTE: 0x00000001 is our dummy device ID from xam_content.cc
|
||||
*device_id_ptr = 0x00000001;
|
||||
|
||||
xe::threading::Sleep(std::chrono::milliseconds(500));
|
||||
|
||||
// user_index must be 0-3 or 0xFF, device_id_ptr can't be null and
|
||||
// overlapped is required
|
||||
// XAM also checks something to do with content_flags here, but we don't
|
||||
// handle that atm so who cares
|
||||
if ((user_index > 3 && user_index != 0xFF) || !device_id_ptr || !overlapped) {
|
||||
if (overlapped) {
|
||||
kernel_state()->CompleteOverlappedImmediate(overlapped, X_ERROR_SUCCESS);
|
||||
kernel_state()->CompleteOverlappedImmediate(overlapped,
|
||||
X_ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
xe::threading::Sleep(std::chrono::milliseconds(100));
|
||||
|
||||
// Broadcast XN_SYS_UI = true followed by XN_SYS_UI = false
|
||||
kernel_state()->BroadcastNotification(0x9, true);
|
||||
kernel_state()->BroadcastNotification(0x9, false);
|
||||
|
||||
// return 0;
|
||||
return X_ERROR_SUCCESS;
|
||||
};
|
||||
|
||||
if (overlapped) {
|
||||
// Create a host thread to run the function above
|
||||
auto ui_thread = kernel::object_ref<kernel::XHostThread>(
|
||||
new kernel::XHostThread(kernel_state(), 128 * 1024, 0, ui_fn));
|
||||
ui_thread->set_name("XamShowDeviceSelectorUI Thread");
|
||||
ui_thread->Create();
|
||||
while (ui_thread->last_error() != X_ERROR_SUCCESS) {
|
||||
xe::threading::Sleep(std::chrono::milliseconds(110));
|
||||
}
|
||||
// broadcast end
|
||||
kernel_state()->BroadcastNotification(0x26, 1);
|
||||
return X_ERROR_IO_PENDING;
|
||||
} else {
|
||||
ui_fn();
|
||||
// broadcast end
|
||||
kernel_state()->BroadcastNotification(0x26, 1);
|
||||
return X_ERROR_SUCCESS;
|
||||
return X_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// NOTE: 0x00000001 is our dummy device ID from xam_content.cc
|
||||
*device_id_ptr = 0x00000001;
|
||||
|
||||
// Broadcast XN_SYS_UI = true followed by XN_SYS_UI = false
|
||||
kernel_state()->BroadcastNotification(0x9, true);
|
||||
kernel_state()->BroadcastNotification(0x9, false);
|
||||
|
||||
kernel_state()->CompleteOverlappedImmediate(overlapped, X_ERROR_SUCCESS);
|
||||
return X_ERROR_IO_PENDING;
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XamShowDeviceSelectorUI, kUI, kImplemented);
|
||||
|
||||
|
|
Loading…
Reference in New Issue