diff --git a/src/xenia/gpu/d3d11/d3d11_shader_translator.cc b/src/xenia/gpu/d3d11/d3d11_shader_translator.cc index ef8b75650..549f0c72d 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_translator.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader_translator.cc @@ -163,8 +163,10 @@ int D3D11ShaderTranslator::TranslateVertexShader( " VS_OUTPUT o;\n"); // Always write position, as some shaders seem to only write certain values. - append( - " o.oPos = float4(0.0, 0.0, 0.0, 0.0);\n"); + if (alloc_counts.positions) { + append( + " o.oPos = float4(0.0, 0.0, 0.0, 0.0);\n"); + } if (alloc_counts.point_size) { append( " o.oPointSize = float4(1.0, 0.0, 0.0, 0.0);\n"); @@ -198,8 +200,11 @@ int D3D11ShaderTranslator::TranslateVertexShader( } // main footer. + if (alloc_counts.positions) { + append( + " o.oPos = applyViewport(o.oPos);\n"); + } append( - " o.oPos = applyViewport(o.oPos);\n" " return o;\n" "};\n"); diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 5cd6110b7..bc10751d7 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -135,3 +136,30 @@ XThread* KernelState::GetThreadByID(uint32_t thread_id) { xe_mutex_unlock(object_mutex_); return thread; } + +void KernelState::RegisterNotifyListener(XNotifyListener* listener) { + xe_mutex_lock(object_mutex_); + notify_listeners_.push_back(listener); + xe_mutex_unlock(object_mutex_); +} + +void KernelState::UnregisterNotifyListener(XNotifyListener* listener) { + xe_mutex_lock(object_mutex_); + for (auto it = notify_listeners_.begin(); it != notify_listeners_.end(); + ++it) { + if (*it == listener) { + notify_listeners_.erase(it); + break; + } + } + xe_mutex_unlock(object_mutex_); +} + +void KernelState::BroadcastNotification(XNotificationID id, uint32_t data) { + xe_mutex_lock(object_mutex_); + for (auto it = notify_listeners_.begin(); it != notify_listeners_.end(); + ++it) { + (*it)->EnqueueNotification(id, data); + } + xe_mutex_unlock(object_mutex_); +} diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index 944169918..f2fb3f47e 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -23,6 +23,7 @@ XEDECLARECLASS1(xe, Emulator); XEDECLARECLASS2(xe, cpu, Processor); XEDECLARECLASS2(xe, kernel, Dispatcher); XEDECLARECLASS2(xe, kernel, XModule); +XEDECLARECLASS2(xe, kernel, XNotifyListener); XEDECLARECLASS2(xe, kernel, XThread); XEDECLARECLASS2(xe, kernel, XUserModule); XEDECLARECLASS3(xe, kernel, fs, FileSystem); @@ -56,6 +57,10 @@ public: void UnregisterThread(XThread* thread); XThread* GetThreadByID(uint32_t thread_id); + void RegisterNotifyListener(XNotifyListener* listener); + void UnregisterNotifyListener(XNotifyListener* listener); + void BroadcastNotification(XNotificationID id, uint32_t data); + private: Emulator* emulator_; Memory* memory_; @@ -67,6 +72,7 @@ private: ObjectTable* object_table_; xe_mutex_t* object_mutex_; std::unordered_map threads_by_id_; + std::vector notify_listeners_; XUserModule* executable_module_; diff --git a/src/xenia/kernel/objects/xnotify_listener.cc b/src/xenia/kernel/objects/xnotify_listener.cc index b9d45dafb..7e9ffb704 100644 --- a/src/xenia/kernel/objects/xnotify_listener.cc +++ b/src/xenia/kernel/objects/xnotify_listener.cc @@ -20,6 +20,7 @@ XNotifyListener::XNotifyListener(KernelState* kernel_state) : } XNotifyListener::~XNotifyListener() { + kernel_state_->UnregisterNotifyListener(this); xe_mutex_free(lock_); if (wait_handle_) { CloseHandle(wait_handle_); @@ -32,9 +33,16 @@ void XNotifyListener::Initialize(uint64_t mask) { lock_ = xe_mutex_alloc(); wait_handle_ = CreateEvent(NULL, TRUE, FALSE, NULL); mask_ = mask; + + kernel_state_->RegisterNotifyListener(this); } void XNotifyListener::EnqueueNotification(XNotificationID id, uint32_t data) { + // Ignore if the notification doesn't match our mask. + if ((mask_ & uint64_t(1 << ((id >> 25) + 1))) == 0) { + return; + } + xe_mutex_lock(lock_); auto existing = notifications_.find(id); if (existing != notifications_.end()) { diff --git a/src/xenia/kernel/objects/xnotify_listener.h b/src/xenia/kernel/objects/xnotify_listener.h index a7aa16eee..436c4434a 100644 --- a/src/xenia/kernel/objects/xnotify_listener.h +++ b/src/xenia/kernel/objects/xnotify_listener.h @@ -21,9 +21,6 @@ namespace xe { namespace kernel { -// Values seem to be all over the place - GUIDs? -typedef uint32_t XNotificationID; - class XNotifyListener : public XObject { public: diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index af71eb182..1aca590e3 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -11,6 +11,7 @@ #include +#include #include #include #include @@ -20,6 +21,8 @@ using namespace alloy; +DEFINE_bool(xex_dev_key, false, "Use the devkit key."); + typedef struct xe_xex2 { xe_ref_t ref; @@ -434,7 +437,7 @@ int xe_xex2_decrypt_key(xe_xex2_header_t *header) { // Guess key based on file info. // TODO: better way to finding out which key to use? const uint8_t *xexkey; - if (header->execution_info.title_id) { + if (header->execution_info.title_id && !FLAGS_xex_dev_key) { xexkey = xe_xex2_retail_key; } else { xexkey = xe_xex2_devkit_key; diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index ebe48c2cb..005475812 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -174,6 +174,23 @@ SHIM_CALL XamUserReadProfileSettings_shim( } +SHIM_CALL XamShowSigninUI_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t unk_0 = SHIM_GET_ARG_32(0); + uint32_t unk_mask = SHIM_GET_ARG_32(1); + + XELOGD( + "XamShowSigninUI(%d, %.8X)", + unk_0, unk_mask); + + // Mask values vary. Probably matching user types? Local/remote? + // Games seem to sit and loop until we trigger this notification. + state->BroadcastNotification(0x00000009, 0); + + SHIM_SET_RETURN_32(X_ERROR_SUCCESS); +} + + } // namespace kernel } // namespace xe @@ -185,4 +202,5 @@ void xe::kernel::xam::RegisterUserExports( SHIM_SET_MAPPING("xam.xex", XamUserGetSigninInfo, state); SHIM_SET_MAPPING("xam.xex", XamUserGetName, state); SHIM_SET_MAPPING("xam.xex", XamUserReadProfileSettings, state); + SHIM_SET_MAPPING("xam.xex", XamShowSigninUI, state); } diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index c7f31aee0..0e119491b 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -1129,7 +1129,7 @@ SHIM_CALL NtWaitForSingleObjectEx_shim( uint64_t timeout = timeout_ptr ? SHIM_MEM_64(timeout_ptr) : 0; result = object->Wait( 3, wait_mode, alertable, - timeout_ptr ? &timeout : NULL); + timeout_ptr ? &timeout : NULL); object->Release(); } diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index aab667584..9f3a6b071 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -254,6 +254,10 @@ public: }; +// Values seem to be all over the place - GUIDs? +typedef uint32_t XNotificationID; + + typedef enum _X_INPUT_FLAG { X_INPUT_FLAG_GAMEPAD = 0x00000001, } X_INPUT_FLAG;