diff --git a/README.md b/README.md index a4e6d6c26..ba1123aee 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2635. +This is the source code for early-access 2636. ## Legal Notice diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 90e0662cf..b547a3463 100755 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -25,9 +25,9 @@ namespace Kernel { SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_, - bool create_service_thread_) + ServiceThreadType thread_type) : kernel{kernel_} { - if (create_service_thread_) { + if (thread_type == ServiceThreadType::CreateNew) { service_thread = kernel.CreateServiceThread(service_name_); } else { service_thread = kernel.GetDefaultServiceThread(); diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 07ce83ab4..640146137 100755 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -33,6 +33,11 @@ namespace Service { class ServiceFrameworkBase; } +enum class ServiceThreadType { + Default, + CreateNew, +}; + namespace Kernel { class Domain; @@ -58,7 +63,7 @@ enum class ThreadWakeupReason; class SessionRequestHandler : public std::enable_shared_from_this { public: SessionRequestHandler(KernelCore& kernel_, const char* service_name_, - bool create_service_thread_); + ServiceThreadType thread_type); virtual ~SessionRequestHandler(); /** diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 763e83187..75c35f319 100755 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -1091,7 +1091,7 @@ std::weak_ptr KernelCore::CreateServiceThread(const std:: return impl->CreateServiceThread(*this, name); } -std::weak_ptr KernelCore::GetDefaultServiceThread() { +std::weak_ptr KernelCore::GetDefaultServiceThread() const { return impl->default_service_thread; } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 77901e5a9..f4437a06f 100755 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -294,7 +294,7 @@ public: * creating a new service thread. * @returns The a weak pointer for the default service thread. */ - std::weak_ptr GetDefaultServiceThread(); + std::weak_ptr GetDefaultServiceThread() const; /** * Releases a HLE service thread, instructing KernelCore to free it. This should be called when diff --git a/src/core/hle/service/am/applets/applet_web_browser.cpp b/src/core/hle/service/am/applets/applet_web_browser.cpp index bb5cb61be..a4b3fb187 100755 --- a/src/core/hle/service/am/applets/applet_web_browser.cpp +++ b/src/core/hle/service/am/applets/applet_web_browser.cpp @@ -446,6 +446,14 @@ void WebBrowser::ExecuteLogin() { } void WebBrowser::ExecuteOffline() { + // TODO (Morph): This is a hack for WebSession foreground web applets such as those used by + // Super Mario 3D All-Stars. + // TODO (Morph): Implement WebSession. + if (applet_mode == LibraryAppletMode::AllForegroundInitiallyHidden) { + LOG_WARNING(Service_AM, "WebSession is not implemented"); + return; + } + const auto main_url = GetMainURL(Common::FS::PathToUTF8String(offline_document)); if (!Common::FS::Exists(main_url)) { diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 834ac14ca..a72956a28 100755 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -41,7 +41,7 @@ public: explicit IAudioOut(Core::System& system_, AudoutParams audio_params_, AudioCore::AudioOut& audio_core_, std::string&& device_name_, std::string&& unique_name) - : ServiceFramework{system_, "IAudioOut", true /*create_service_thread*/}, + : ServiceFramework{system_, "IAudioOut", ServiceThreadType::CreateNew}, audio_core{audio_core_}, device_name{std::move(device_name_)}, audio_params{audio_params_}, main_memory{system.Memory()}, service_context{system_, "IAudioOut"} { diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 8df874fcf..d4ffeb21d 100755 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -24,7 +24,7 @@ public: explicit IAudioRenderer(Core::System& system_, const AudioCommon::AudioRendererParameter& audren_params, const std::size_t instance_number) - : ServiceFramework{system_, "IAudioRenderer", true /*create_service_thread*/}, + : ServiceFramework{system_, "IAudioRenderer", ServiceThreadType::CreateNew}, service_context{system_, "IAudioRenderer"} { // clang-format off static const FunctionInfo functions[] = { diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 9feccfbb8..c07929ab8 100755 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -58,7 +58,7 @@ enum class FileSystemType : u8 { class IStorage final : public ServiceFramework { public: explicit IStorage(Core::System& system_, FileSys::VirtualFile backend_) - : ServiceFramework{system_, "IStorage", true /*create_service_thread*/}, + : ServiceFramework{system_, "IStorage", ServiceThreadType::CreateNew}, backend(std::move(backend_)) { static const FunctionInfo functions[] = { {0, &IStorage::Read, "Read"}, @@ -117,7 +117,7 @@ private: class IFile final : public ServiceFramework { public: explicit IFile(Core::System& system_, FileSys::VirtualFile backend_) - : ServiceFramework{system_, "IFile", true /*create_service_thread*/}, + : ServiceFramework{system_, "IFile", ServiceThreadType::CreateNew}, backend(std::move(backend_)) { static const FunctionInfo functions[] = { {0, &IFile::Read, "Read"}, @@ -254,7 +254,7 @@ static void BuildEntryIndex(std::vector& entries, const std::vec class IDirectory final : public ServiceFramework { public: explicit IDirectory(Core::System& system_, FileSys::VirtualDir backend_) - : ServiceFramework{system_, "IDirectory", true /*create_service_thread*/}, + : ServiceFramework{system_, "IDirectory", ServiceThreadType::CreateNew}, backend(std::move(backend_)) { static const FunctionInfo functions[] = { {0, &IDirectory::Read, "Read"}, @@ -311,7 +311,7 @@ private: class IFileSystem final : public ServiceFramework { public: explicit IFileSystem(Core::System& system_, FileSys::VirtualDir backend_, SizeGetter size_) - : ServiceFramework{system_, "IFileSystem", true /*create_service_thread*/}, + : ServiceFramework{system_, "IFileSystem", ServiceThreadType::CreateNew}, backend{std::move(backend_)}, size{std::move(size_)} { static const FunctionInfo functions[] = { {0, &IFileSystem::CreateFile, "CreateFile"}, diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index e5c951e06..aa6cb34b7 100755 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -262,11 +262,6 @@ void Controller_NPad::OnInit() { service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i)); } - if (hid_core.GetSupportedStyleTag().raw == Core::HID::NpadStyleSet::None) { - // We want to support all controllers - hid_core.SetSupportedStyleTag({Core::HID::NpadStyleSet::All}); - } - supported_npad_id_types.resize(npad_id_list.size()); std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), npad_id_list.size() * sizeof(Core::HID::NpadIdType)); @@ -288,14 +283,6 @@ void Controller_NPad::OnInit() { WriteEmptyEntry(npad); } } - - // Connect controllers - for (auto& controller : controller_data) { - const auto& device = controller.device; - if (device->IsConnected()) { - AddNewControllerAt(device->GetNpadStyleIndex(), device->GetNpadIdType()); - } - } } void Controller_NPad::WriteEmptyEntry(NpadInternalState& npad) { @@ -320,6 +307,7 @@ void Controller_NPad::WriteEmptyEntry(NpadInternalState& npad) { } void Controller_NPad::OnRelease() { + is_controller_initialized = false; for (std::size_t i = 0; i < controller_data.size(); ++i) { auto& controller = controller_data[i]; service_context.CloseEvent(controller.styleset_changed_event); @@ -651,9 +639,27 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing void Controller_NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) { hid_core.SetSupportedStyleTag(style_set); + + if (is_controller_initialized) { + return; + } + + // Once SetSupportedStyleSet is called controllers are fully initialized + is_controller_initialized = true; + + // Connect all active controllers + for (auto& controller : controller_data) { + const auto& device = controller.device; + if (device->IsConnected()) { + AddNewControllerAt(device->GetNpadStyleIndex(), device->GetNpadIdType()); + } + } } Core::HID::NpadStyleTag Controller_NPad::GetSupportedStyleSet() const { + if (!is_controller_initialized) { + return {Core::HID::NpadStyleSet::None}; + } return hid_core.GetSupportedStyleTag(); } diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 3287cf435..c417a36bb 100755 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -511,7 +511,8 @@ private: NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; NpadCommunicationMode communication_mode{NpadCommunicationMode::Default}; bool permit_vibration_session_enabled{false}; - bool analog_stick_use_center_clamp{}; + bool analog_stick_use_center_clamp{false}; bool is_in_lr_assignment_mode{false}; + bool is_controller_initialized{false}; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 9d3e0a658..fb99cf7a0 100755 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -64,10 +64,6 @@ IAppletResource::IAppletResource(Core::System& system_, MakeController(HidController::Gesture); MakeController(HidController::ConsoleSixAxisSensor); - // Homebrew doesn't try to activate some controllers, so we activate them by default - GetController(HidController::NPad).ActivateController(); - GetController(HidController::Touchscreen).ActivateController(); - GetController(HidController::HomeButton).SetCommonHeaderOffset(0x4C00); GetController(HidController::SleepButton).SetCommonHeaderOffset(0x4E00); GetController(HidController::CaptureButton).SetCommonHeaderOffset(0x5000); diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp index c16babe14..b3b8576a9 100755 --- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp +++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp @@ -230,7 +230,7 @@ void NVDRV::DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx) { } NVDRV::NVDRV(Core::System& system_, std::shared_ptr nvdrv_, const char* name) - : ServiceFramework{system_, name}, nvdrv{std::move(nvdrv_)} { + : ServiceFramework{system_, name, ServiceThreadType::CreateNew}, nvdrv{std::move(nvdrv_)} { static const FunctionInfo functions[] = { {0, &NVDRV::Open, "Open"}, {1, &NVDRV::Ioctl1, "Ioctl"}, diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 04eb0d6ea..8d902beb9 100755 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -91,11 +91,10 @@ namespace Service { } ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* service_name_, - bool create_service_thread_, u32 max_sessions_, + ServiceThreadType thread_type, u32 max_sessions_, InvokerFn* handler_invoker_) - : SessionRequestHandler(system_.Kernel(), service_name_, create_service_thread_), - system{system_}, service_name{service_name_}, max_sessions{max_sessions_}, - handler_invoker{handler_invoker_} {} + : SessionRequestHandler(system_.Kernel(), service_name_, thread_type), system{system_}, + service_name{service_name_}, max_sessions{max_sessions_}, handler_invoker{handler_invoker_} {} ServiceFrameworkBase::~ServiceFrameworkBase() { // Wait for other threads to release access before destroying diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 778b6da4e..c78b2baeb 100755 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -114,7 +114,7 @@ private: Kernel::HLERequestContext& ctx); explicit ServiceFrameworkBase(Core::System& system_, const char* service_name_, - bool create_service_thread_, u32 max_sessions_, + ServiceThreadType thread_type, u32 max_sessions_, InvokerFn* handler_invoker_); ~ServiceFrameworkBase() override; @@ -179,16 +179,15 @@ protected: * * @param system_ The system context to construct this service under. * @param service_name_ Name of the service. - * @param create_service_thread_ Creates a service thread for this if true, otherwise use the - * default service thread. + * @param thread_type Specifies the thread type for this service. If this is set to CreateNew, + * it creates a new thread for it, otherwise this uses the default thread. * @param max_sessions_ Maximum number of sessions that can be connected to this service at the * same time. */ explicit ServiceFramework(Core::System& system_, const char* service_name_, - bool create_service_thread_ = false, + ServiceThreadType thread_type = ServiceThreadType::Default, u32 max_sessions_ = ServerSessionCountMax) - : ServiceFrameworkBase(system_, service_name_, create_service_thread_, max_sessions_, - Invoker) {} + : ServiceFrameworkBase(system_, service_name_, thread_type, max_sessions_, Invoker) {} /// Registers handlers in the service. template diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 5233e5b33..97f895852 100755 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -206,7 +206,7 @@ void SM::UnregisterService(Kernel::HLERequestContext& ctx) { } SM::SM(ServiceManager& service_manager_, Core::System& system_) - : ServiceFramework{system_, "sm:", false /*create_service_thread*/, 4}, + : ServiceFramework{system_, "sm:", ServiceThreadType::Default, 4}, service_manager{service_manager_}, kernel{system_.Kernel()} { RegisterHandlers({ {0, &SM::Initialize, "Initialize"}, diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index 3970879c8..d6702e4e1 100755 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -838,7 +838,7 @@ void BSD::BuildErrnoResponse(Kernel::HLERequestContext& ctx, Errno bsd_errno) co } BSD::BSD(Core::System& system_, const char* name) - : ServiceFramework{system_, name, true /*create_service_thread*/} { + : ServiceFramework{system_, name, ServiceThreadType::CreateNew} { // clang-format off static const FunctionInfo functions[] = { {0, &BSD::RegisterClient, "RegisterClient"}, diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 3284de519..a3436c8ea 100755 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -77,7 +77,7 @@ static_assert(sizeof(NativeWindow) == 0x28, "NativeWindow has wrong size"); class IHOSBinderDriver final : public ServiceFramework { public: explicit IHOSBinderDriver(Core::System& system_, NVFlinger::HosBinderDriverServer& server_) - : ServiceFramework{system_, "IHOSBinderDriver", true /*create_service_thread*/}, + : ServiceFramework{system_, "IHOSBinderDriver", ServiceThreadType::CreateNew}, server(server_) { static const FunctionInfo functions[] = { {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"},