diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 67358efab..d423c4b7e 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -33,7 +33,8 @@ KernelState* shared_kernel_state_ = nullptr; KernelState::KernelState(Emulator* emulator) : emulator_(emulator), memory_(emulator->memory()), - executable_module_(NULL) { + has_notified_startup_(false), + executable_module_(nullptr) { processor_ = emulator->processor(); file_system_ = emulator->file_system(); @@ -51,7 +52,7 @@ KernelState::KernelState(Emulator* emulator) } KernelState::~KernelState() { - SetExecutableModule(NULL); + SetExecutableModule(nullptr); // Delete all objects. delete object_table_; @@ -62,7 +63,7 @@ KernelState::~KernelState() { delete dispatcher_; assert_true(shared_kernel_state_ == this); - shared_kernel_state_ = NULL; + shared_kernel_state_ = nullptr; } KernelState* KernelState::shared() { return shared_kernel_state_; } @@ -86,17 +87,17 @@ XModule* KernelState::GetModule(const char* name) { return module; } else if (strcasecmp(name, "kernel32.dll") == 0) { // Some games request this, for some reason. wtf. - return NULL; + return nullptr; } else { // TODO(benvanik): support user modules/loading/etc. assert_always(); - return NULL; + return nullptr; } } XUserModule* KernelState::GetExecutableModule() { if (!executable_module_) { - return NULL; + return nullptr; } executable_module_->Retain(); @@ -132,7 +133,7 @@ void KernelState::UnregisterThread(XThread* thread) { XThread* KernelState::GetThreadByID(uint32_t thread_id) { std::lock_guard lock(object_mutex_); - XThread* thread = NULL; + XThread* thread = nullptr; auto it = threads_by_id_.find(thread_id); if (it != threads_by_id_.end()) { thread = it->second; @@ -145,6 +146,25 @@ XThread* KernelState::GetThreadByID(uint32_t thread_id) { void KernelState::RegisterNotifyListener(XNotifyListener* listener) { std::lock_guard lock(object_mutex_); notify_listeners_.push_back(listener); + + // Games seem to expect a few notifications on startup, only for the first + // listener. + // http://cs.rin.ru/forum/viewtopic.php?f=38&t=60668&hilit=resident+evil+5&start=375 + if (!has_notified_startup_ && listener->mask() & 0x00000001) { + has_notified_startup_ = true; + // XN_SYS_UI (on, off) + listener->EnqueueNotification(0x00000009, 1); + listener->EnqueueNotification(0x00000009, 0); + // XN_SYS_SIGNINCHANGED x2 + listener->EnqueueNotification(0x0000000A, 1); + listener->EnqueueNotification(0x0000000A, 1); + // XN_SYS_INPUTDEVICESCHANGED x2 + listener->EnqueueNotification(0x00000012, 0); + listener->EnqueueNotification(0x00000012, 0); + // XN_SYS_INPUTDEVICECONFIGCHANGED x2 + listener->EnqueueNotification(0x00000013, 0); + listener->EnqueueNotification(0x00000013, 0); + } } void KernelState::UnregisterNotifyListener(XNotifyListener* listener) { diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index 611c5cb27..72899d936 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -93,6 +93,7 @@ class KernelState { std::mutex object_mutex_; std::unordered_map threads_by_id_; std::vector notify_listeners_; + bool has_notified_startup_; XUserModule* executable_module_; diff --git a/src/xenia/kernel/objects/xnotify_listener.h b/src/xenia/kernel/objects/xnotify_listener.h index 7f92f6675..708230eea 100644 --- a/src/xenia/kernel/objects/xnotify_listener.h +++ b/src/xenia/kernel/objects/xnotify_listener.h @@ -23,6 +23,8 @@ class XNotifyListener : public XObject { XNotifyListener(KernelState* kernel_state); virtual ~XNotifyListener(); + uint64_t mask() const { return mask_; } + void Initialize(uint64_t mask); void EnqueueNotification(XNotificationID id, uint32_t data); diff --git a/src/xenia/kernel/xam_info.cc b/src/xenia/kernel/xam_info.cc index 40bf76b46..39eeb44a9 100644 --- a/src/xenia/kernel/xam_info.cc +++ b/src/xenia/kernel/xam_info.cc @@ -113,6 +113,7 @@ SHIM_CALL XamEnumerate_shim(PPCContext* ppc_state, KernelState* state) { return; } + // 0 items. if (item_count_ptr) { assert_zero(overlapped_ptr); SHIM_SET_MEM_32(item_count_ptr, 0); diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index 297391cee..027d16f63 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -48,9 +48,16 @@ SHIM_CALL XamUserGetSigninState_shim(PPCContext* ppc_state, // from initializing the network. if (user_index == 0 || (user_index & 0xFF) == 0xFF) { const auto& user_profile = state->user_profile(); - SHIM_SET_RETURN_64(user_profile->signin_state()); + auto signin_state = user_profile->signin_state(); + SHIM_SET_RETURN_64(signin_state); + + // Notify we exist, just for fun. + state->BroadcastNotification(0x0000000A, signin_state ? 1 : 0); } else { SHIM_SET_RETURN_64(0); + + // Notify no users. + state->BroadcastNotification(0x0000000A, 0); } }