Spamming some notifications on startup to unhang games.
This commit is contained in:
parent
1566b4c890
commit
6053f1d35c
|
@ -33,7 +33,8 @@ KernelState* shared_kernel_state_ = nullptr;
|
||||||
KernelState::KernelState(Emulator* emulator)
|
KernelState::KernelState(Emulator* emulator)
|
||||||
: emulator_(emulator),
|
: emulator_(emulator),
|
||||||
memory_(emulator->memory()),
|
memory_(emulator->memory()),
|
||||||
executable_module_(NULL) {
|
has_notified_startup_(false),
|
||||||
|
executable_module_(nullptr) {
|
||||||
processor_ = emulator->processor();
|
processor_ = emulator->processor();
|
||||||
file_system_ = emulator->file_system();
|
file_system_ = emulator->file_system();
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ KernelState::KernelState(Emulator* emulator)
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelState::~KernelState() {
|
KernelState::~KernelState() {
|
||||||
SetExecutableModule(NULL);
|
SetExecutableModule(nullptr);
|
||||||
|
|
||||||
// Delete all objects.
|
// Delete all objects.
|
||||||
delete object_table_;
|
delete object_table_;
|
||||||
|
@ -62,7 +63,7 @@ KernelState::~KernelState() {
|
||||||
delete dispatcher_;
|
delete dispatcher_;
|
||||||
|
|
||||||
assert_true(shared_kernel_state_ == this);
|
assert_true(shared_kernel_state_ == this);
|
||||||
shared_kernel_state_ = NULL;
|
shared_kernel_state_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelState* KernelState::shared() { return shared_kernel_state_; }
|
KernelState* KernelState::shared() { return shared_kernel_state_; }
|
||||||
|
@ -86,17 +87,17 @@ XModule* KernelState::GetModule(const char* name) {
|
||||||
return module;
|
return module;
|
||||||
} else if (strcasecmp(name, "kernel32.dll") == 0) {
|
} else if (strcasecmp(name, "kernel32.dll") == 0) {
|
||||||
// Some games request this, for some reason. wtf.
|
// Some games request this, for some reason. wtf.
|
||||||
return NULL;
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
// TODO(benvanik): support user modules/loading/etc.
|
// TODO(benvanik): support user modules/loading/etc.
|
||||||
assert_always();
|
assert_always();
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XUserModule* KernelState::GetExecutableModule() {
|
XUserModule* KernelState::GetExecutableModule() {
|
||||||
if (!executable_module_) {
|
if (!executable_module_) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
executable_module_->Retain();
|
executable_module_->Retain();
|
||||||
|
@ -132,7 +133,7 @@ void KernelState::UnregisterThread(XThread* thread) {
|
||||||
|
|
||||||
XThread* KernelState::GetThreadByID(uint32_t thread_id) {
|
XThread* KernelState::GetThreadByID(uint32_t thread_id) {
|
||||||
std::lock_guard<std::mutex> lock(object_mutex_);
|
std::lock_guard<std::mutex> lock(object_mutex_);
|
||||||
XThread* thread = NULL;
|
XThread* thread = nullptr;
|
||||||
auto it = threads_by_id_.find(thread_id);
|
auto it = threads_by_id_.find(thread_id);
|
||||||
if (it != threads_by_id_.end()) {
|
if (it != threads_by_id_.end()) {
|
||||||
thread = it->second;
|
thread = it->second;
|
||||||
|
@ -145,6 +146,25 @@ XThread* KernelState::GetThreadByID(uint32_t thread_id) {
|
||||||
void KernelState::RegisterNotifyListener(XNotifyListener* listener) {
|
void KernelState::RegisterNotifyListener(XNotifyListener* listener) {
|
||||||
std::lock_guard<std::mutex> lock(object_mutex_);
|
std::lock_guard<std::mutex> lock(object_mutex_);
|
||||||
notify_listeners_.push_back(listener);
|
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) {
|
void KernelState::UnregisterNotifyListener(XNotifyListener* listener) {
|
||||||
|
|
|
@ -93,6 +93,7 @@ class KernelState {
|
||||||
std::mutex object_mutex_;
|
std::mutex object_mutex_;
|
||||||
std::unordered_map<uint32_t, XThread*> threads_by_id_;
|
std::unordered_map<uint32_t, XThread*> threads_by_id_;
|
||||||
std::vector<XNotifyListener*> notify_listeners_;
|
std::vector<XNotifyListener*> notify_listeners_;
|
||||||
|
bool has_notified_startup_;
|
||||||
|
|
||||||
XUserModule* executable_module_;
|
XUserModule* executable_module_;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ class XNotifyListener : public XObject {
|
||||||
XNotifyListener(KernelState* kernel_state);
|
XNotifyListener(KernelState* kernel_state);
|
||||||
virtual ~XNotifyListener();
|
virtual ~XNotifyListener();
|
||||||
|
|
||||||
|
uint64_t mask() const { return mask_; }
|
||||||
|
|
||||||
void Initialize(uint64_t mask);
|
void Initialize(uint64_t mask);
|
||||||
|
|
||||||
void EnqueueNotification(XNotificationID id, uint32_t data);
|
void EnqueueNotification(XNotificationID id, uint32_t data);
|
||||||
|
|
|
@ -113,6 +113,7 @@ SHIM_CALL XamEnumerate_shim(PPCContext* ppc_state, KernelState* state) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 0 items.
|
||||||
if (item_count_ptr) {
|
if (item_count_ptr) {
|
||||||
assert_zero(overlapped_ptr);
|
assert_zero(overlapped_ptr);
|
||||||
SHIM_SET_MEM_32(item_count_ptr, 0);
|
SHIM_SET_MEM_32(item_count_ptr, 0);
|
||||||
|
|
|
@ -48,9 +48,16 @@ SHIM_CALL XamUserGetSigninState_shim(PPCContext* ppc_state,
|
||||||
// from initializing the network.
|
// from initializing the network.
|
||||||
if (user_index == 0 || (user_index & 0xFF) == 0xFF) {
|
if (user_index == 0 || (user_index & 0xFF) == 0xFF) {
|
||||||
const auto& user_profile = state->user_profile();
|
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 {
|
} else {
|
||||||
SHIM_SET_RETURN_64(0);
|
SHIM_SET_RETURN_64(0);
|
||||||
|
|
||||||
|
// Notify no users.
|
||||||
|
state->BroadcastNotification(0x0000000A, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue