From f58097e814ebb000f23acbe26f096c8c4368da73 Mon Sep 17 00:00:00 2001 From: Maufeat Date: Thu, 27 Nov 2025 19:46:41 +0100 Subject: [hle,display,overlay,starter,hid] add overlay functions, starter applet (initially), HID handheld for system applets and fw21 stubs (#3080) Adds fully functional overlay display. - Enable Overlay Applet via "View" -> "Enable Overlay Display Applet" - Open the overlay by pressing the home button for over 1s - Can adjust volume - Can toggle airplane mode (if on WiFi, maybe if overlay is enabled pretend to be on WiFi?) - Future TODO(?): Adjust Brightness implementation for host system - Inputs are properly registered. e.g. if overlay open, application does not register inputs. You can control volume and airplane mode outside of the emulator window Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3080 Reviewed-by: CamilleLaVey Reviewed-by: crueter Co-authored-by: Maufeat Co-committed-by: Maufeat --- src/core/core.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'src/core/core.cpp') diff --git a/src/core/core.cpp b/src/core/core.cpp index 6c321afdbb..edc2df4851 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -580,6 +580,21 @@ struct System::Impl { gpu_dirty_memory_managers; std::deque> user_channel; + + std::mutex general_channel_mutex; + std::deque> general_channel; + std::unique_ptr general_channel_context; // lazy + std::unique_ptr general_channel_event; // lazy + bool general_channel_initialized{false}; + + void EnsureGeneralChannelInitialized(System& system) { + if (general_channel_initialized) { + return; + } + general_channel_context = std::make_unique(system, "GeneralChannel"); + general_channel_event = std::make_unique(*general_channel_context); + general_channel_initialized = true; + } }; System::System() : impl{std::make_unique(*this)} {} @@ -993,6 +1008,39 @@ std::deque>& System::GetUserChannel() { return impl->user_channel; } +std::deque>& System::GetGeneralChannel() { + return impl->general_channel; +} + +void System::PushGeneralChannelData(std::vector&& data) { + std::scoped_lock lk{impl->general_channel_mutex}; + impl->EnsureGeneralChannelInitialized(*this); + const bool was_empty = impl->general_channel.empty(); + impl->general_channel.push_back(std::move(data)); + if (was_empty) { + impl->general_channel_event->Signal(); + } +} + +bool System::TryPopGeneralChannel(std::vector& out_data) { + std::scoped_lock lk{impl->general_channel_mutex}; + if (!impl->general_channel_initialized || impl->general_channel.empty()) { + return false; + } + out_data = std::move(impl->general_channel.back()); + impl->general_channel.pop_back(); + if (impl->general_channel.empty()) { + impl->general_channel_event->Clear(); + } + return true; +} + +Service::Event& System::GetGeneralChannelEvent() { + std::scoped_lock lk{impl->general_channel_mutex}; + impl->EnsureGeneralChannelInitialized(*this); + return *impl->general_channel_event; +} + void System::RegisterExitCallback(ExitCallback&& callback) { impl->exit_callback = std::move(callback); } -- cgit v1.2.3