Ability to switch between docked and undocked mode in-game

Started implementation of the AM message queue mainly used in state getters. Added the ability to switch docked mode whilst in game without stopping emulation. Also removed some things which shouldn't be labelled as stubs as they're implemented correctly
This commit is contained in:
David Marcec 2018-11-07 18:01:33 +11:00
parent dd321dc85f
commit 41e99d8880
7 changed files with 163 additions and 36 deletions

View file

@ -338,7 +338,54 @@ void ISelfController::GetIdleTimeDetectionExtension(Kernel::HLERequestContext& c
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_WARNING(Service_AM, "(STUBBED) called");
} }
ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") { AppletMessageQueue::AppletMessageQueue() {
auto& kernel = Core::System::GetInstance().Kernel();
on_new_message = Kernel::Event::Create(kernel, Kernel::ResetType::Sticky,
"AMMessageQueue:OnMessageRecieved");
on_operation_mode_changed = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
"AMMessageQueue:OperationModeChanged");
}
AppletMessageQueue::~AppletMessageQueue() = default;
const Kernel::SharedPtr<Kernel::Event>& AppletMessageQueue::GetMesssageRecieveEvent() const {
return on_new_message;
}
const Kernel::SharedPtr<Kernel::Event>& AppletMessageQueue::GetOperationModeChangedEvent() const {
return on_operation_mode_changed;
}
void AppletMessageQueue::PushMessage(AppletMessage msg) {
messages.push(msg);
on_new_message->Signal();
}
AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() {
if (messages.empty()) {
on_new_message->Clear();
return AppletMessage::NoMessage;
}
auto msg = messages.front();
messages.pop();
if (messages.empty()) {
on_new_message->Clear();
}
return msg;
}
std::size_t AppletMessageQueue::GetMessageCount() const {
return messages.size();
}
void AppletMessageQueue::OperationModeChanged() {
PushMessage(AppletMessage::OperationModeChanged);
PushMessage(AppletMessage::PerformanceModeChanged);
on_operation_mode_changed->Signal();
}
ICommonStateGetter::ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_queue)
: ServiceFramework("ICommonStateGetter"), msg_queue(std::move(msg_queue)) {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"}, {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
@ -388,21 +435,19 @@ void ICommonStateGetter::GetBootMode(Kernel::HLERequestContext& ctx) {
} }
void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) { void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) {
event->Signal();
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(event); rb.PushCopyObjects(msg_queue->GetMesssageRecieveEvent());
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_DEBUG(Service_AM, "called");
} }
void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) { void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3}; IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.Push<u32>(15); rb.PushEnum<AppletMessageQueue::AppletMessage>(msg_queue->PopMessage());
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_DEBUG(Service_AM, "called");
} }
void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) { void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
@ -414,13 +459,11 @@ void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
} }
void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(Kernel::HLERequestContext& ctx) { void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(Kernel::HLERequestContext& ctx) {
event->Signal();
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(event); rb.PushCopyObjects(msg_queue->GetOperationModeChangedEvent());
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_DEBUG(Service_AM, "called");
} }
void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx) { void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx) {
@ -444,7 +487,7 @@ void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld)); rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld));
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_DEBUG(Service_AM, "called");
} }
void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) { void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
@ -454,7 +497,7 @@ void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked
: APM::PerformanceMode::Handheld)); : APM::PerformanceMode::Handheld));
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_DEBUG(Service_AM, "called");
} }
class IStorageAccessor final : public ServiceFramework<IStorageAccessor> { class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
@ -840,8 +883,12 @@ void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) {
void InstallInterfaces(SM::ServiceManager& service_manager, void InstallInterfaces(SM::ServiceManager& service_manager,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger) { std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager); auto message_queue = std::make_shared<AppletMessageQueue>();
std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager); message_queue->PushMessage(
AppletMessageQueue::AppletMessage::FocusStateChanged); // Needed on game boot
std::make_shared<AppletAE>(nvflinger, message_queue)->InstallAsService(service_manager);
std::make_shared<AppletOE>(nvflinger, message_queue)->InstallAsService(service_manager);
std::make_shared<IdleSys>()->InstallAsService(service_manager); std::make_shared<IdleSys>()->InstallAsService(service_manager);
std::make_shared<OMM>()->InstallAsService(service_manager); std::make_shared<OMM>()->InstallAsService(service_manager);
std::make_shared<SPSM>()->InstallAsService(service_manager); std::make_shared<SPSM>()->InstallAsService(service_manager);

View file

@ -5,6 +5,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <queue>
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Kernel { namespace Kernel {
@ -39,6 +40,31 @@ enum SystemLanguage {
TraditionalChinese = 16, TraditionalChinese = 16,
}; };
class AppletMessageQueue {
public:
enum class AppletMessage : u32 {
NoMessage = 0,
FocusStateChanged = 15,
OperationModeChanged = 30,
PerformanceModeChanged = 31,
};
AppletMessageQueue();
~AppletMessageQueue();
const Kernel::SharedPtr<Kernel::Event>& GetMesssageRecieveEvent() const;
const Kernel::SharedPtr<Kernel::Event>& GetOperationModeChangedEvent() const;
void PushMessage(AppletMessage msg);
AppletMessage PopMessage();
std::size_t GetMessageCount() const;
void OperationModeChanged();
private:
std::queue<AppletMessage> messages{};
Kernel::SharedPtr<Kernel::Event> on_new_message;
Kernel::SharedPtr<Kernel::Event> on_operation_mode_changed;
};
class IWindowController final : public ServiceFramework<IWindowController> { class IWindowController final : public ServiceFramework<IWindowController> {
public: public:
IWindowController(); IWindowController();
@ -102,7 +128,7 @@ private:
class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> { class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
public: public:
ICommonStateGetter(); explicit ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_queue);
~ICommonStateGetter() override; ~ICommonStateGetter() override;
private: private:
@ -126,6 +152,7 @@ private:
void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx); void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx);
Kernel::SharedPtr<Kernel::Event> event; Kernel::SharedPtr<Kernel::Event> event;
std::shared_ptr<AppletMessageQueue> msg_queue;
}; };
class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> { class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {

View file

@ -12,8 +12,10 @@ namespace Service::AM {
class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
public: public:
explicit ILibraryAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) explicit ILibraryAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
: ServiceFramework("ILibraryAppletProxy"), nvflinger(std::move(nvflinger)) { std::shared_ptr<AppletMessageQueue> msg_queue)
: ServiceFramework("ILibraryAppletProxy"), nvflinger(std::move(nvflinger)),
msg_queue(std::move(msg_queue)) {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
{1, &ILibraryAppletProxy::GetSelfController, "GetSelfController"}, {1, &ILibraryAppletProxy::GetSelfController, "GetSelfController"},
@ -32,7 +34,7 @@ private:
void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ICommonStateGetter>(); rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
} }
@ -93,12 +95,15 @@ private:
} }
std::shared_ptr<NVFlinger::NVFlinger> nvflinger; std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
std::shared_ptr<AppletMessageQueue> msg_queue;
}; };
class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
public: public:
explicit ISystemAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) explicit ISystemAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
: ServiceFramework("ISystemAppletProxy"), nvflinger(std::move(nvflinger)) { std::shared_ptr<AppletMessageQueue> msg_queue)
: ServiceFramework("ISystemAppletProxy"), nvflinger(std::move(nvflinger)),
msg_queue(std::move(msg_queue)) {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, {0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
{1, &ISystemAppletProxy::GetSelfController, "GetSelfController"}, {1, &ISystemAppletProxy::GetSelfController, "GetSelfController"},
@ -119,7 +124,7 @@ private:
void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ICommonStateGetter>(); rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
} }
@ -186,31 +191,34 @@ private:
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
} }
std::shared_ptr<NVFlinger::NVFlinger> nvflinger; std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
std::shared_ptr<AppletMessageQueue> msg_queue;
}; };
void AppletAE::OpenSystemAppletProxy(Kernel::HLERequestContext& ctx) { void AppletAE::OpenSystemAppletProxy(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISystemAppletProxy>(nvflinger); rb.PushIpcInterface<ISystemAppletProxy>(nvflinger, msg_queue);
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
} }
void AppletAE::OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx) { void AppletAE::OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger); rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger, msg_queue);
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
} }
void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) { void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger); rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger, msg_queue);
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
} }
AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
: ServiceFramework("appletAE"), nvflinger(std::move(nvflinger)) { std::shared_ptr<AppletMessageQueue> msg_queue)
: ServiceFramework("appletAE"), nvflinger(std::move(nvflinger)),
msg_queue(std::move(msg_queue)) {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"}, {100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"},
@ -228,4 +236,8 @@ AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
AppletAE::~AppletAE() = default; AppletAE::~AppletAE() = default;
const std::shared_ptr<AppletMessageQueue>& AppletAE::GetMessageQueue() const {
return msg_queue;
}
} // namespace Service::AM } // namespace Service::AM

View file

@ -17,15 +17,19 @@ namespace AM {
class AppletAE final : public ServiceFramework<AppletAE> { class AppletAE final : public ServiceFramework<AppletAE> {
public: public:
explicit AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger); explicit AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
std::shared_ptr<AppletMessageQueue> msg_queue);
~AppletAE() override; ~AppletAE() override;
const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const;
private: private:
void OpenSystemAppletProxy(Kernel::HLERequestContext& ctx); void OpenSystemAppletProxy(Kernel::HLERequestContext& ctx);
void OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx); void OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx);
void OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx); void OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx);
std::shared_ptr<NVFlinger::NVFlinger> nvflinger; std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
std::shared_ptr<AppletMessageQueue> msg_queue;
}; };
} // namespace AM } // namespace AM

View file

@ -12,8 +12,10 @@ namespace Service::AM {
class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
public: public:
explicit IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) explicit IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
: ServiceFramework("IApplicationProxy"), nvflinger(std::move(nvflinger)) { std::shared_ptr<AppletMessageQueue> msg_queue)
: ServiceFramework("IApplicationProxy"), nvflinger(std::move(nvflinger)),
msg_queue(std::move(msg_queue)) {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"}, {0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"},
@ -70,7 +72,7 @@ private:
void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ICommonStateGetter>(); rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
} }
@ -89,17 +91,20 @@ private:
} }
std::shared_ptr<NVFlinger::NVFlinger> nvflinger; std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
std::shared_ptr<AppletMessageQueue> msg_queue;
}; };
void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) { void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IApplicationProxy>(nvflinger); rb.PushIpcInterface<IApplicationProxy>(nvflinger, msg_queue);
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
} }
AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
: ServiceFramework("appletOE"), nvflinger(std::move(nvflinger)) { std::shared_ptr<AppletMessageQueue> msg_queue)
: ServiceFramework("appletOE"), nvflinger(std::move(nvflinger)),
msg_queue(std::move(msg_queue)) {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"}, {0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"},
}; };
@ -108,4 +113,8 @@ AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
AppletOE::~AppletOE() = default; AppletOE::~AppletOE() = default;
const std::shared_ptr<AppletMessageQueue>& AppletOE::GetMessageQueue() const {
return msg_queue;
}
} // namespace Service::AM } // namespace Service::AM

View file

@ -17,13 +17,17 @@ namespace AM {
class AppletOE final : public ServiceFramework<AppletOE> { class AppletOE final : public ServiceFramework<AppletOE> {
public: public:
explicit AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger); explicit AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
std::shared_ptr<AppletMessageQueue> msg_queue);
~AppletOE() override; ~AppletOE() override;
const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const;
private: private:
void OpenApplicationProxy(Kernel::HLERequestContext& ctx); void OpenApplicationProxy(Kernel::HLERequestContext& ctx);
std::shared_ptr<NVFlinger::NVFlinger> nvflinger; std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
std::shared_ptr<AppletMessageQueue> msg_queue;
}; };
} // namespace AM } // namespace AM

View file

@ -3,6 +3,10 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "core/core.h" #include "core/core.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applet_ae.h"
#include "core/hle/service/am/applet_oe.h"
#include "core/hle/service/sm/sm.h"
#include "core/settings.h" #include "core/settings.h"
#include "ui_configure_general.h" #include "ui_configure_general.h"
#include "yuzu/configuration/configure_general.h" #include "yuzu/configuration/configure_general.h"
@ -20,7 +24,6 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
this->setConfiguration(); this->setConfiguration();
ui->use_cpu_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn()); ui->use_cpu_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn());
ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn());
} }
ConfigureGeneral::~ConfigureGeneral() = default; ConfigureGeneral::~ConfigureGeneral() = default;
@ -45,6 +48,27 @@ void ConfigureGeneral::applyConfiguration() {
ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString(); ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString();
Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked(); Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked();
const bool pre_docked_mode = Settings::values.use_docked_mode;
Settings::values.use_docked_mode = ui->use_docked_mode->isChecked(); Settings::values.use_docked_mode = ui->use_docked_mode->isChecked();
if (pre_docked_mode != Settings::values.use_docked_mode) {
Core::System& system{Core::System::GetInstance()};
Service::SM::ServiceManager& sm = system.ServiceManager();
// Message queue is shared between these services, we just need to signal an operation
// change to one and it will handle both automatically
auto applet_oe = sm.GetService<Service::AM::AppletOE>("appletOE");
auto applet_ae = sm.GetService<Service::AM::AppletAE>("appletAE");
bool has_signalled = false;
if (applet_oe != nullptr) {
applet_oe->GetMessageQueue()->OperationModeChanged();
has_signalled = true;
}
if (applet_ae != nullptr && !has_signalled) {
applet_ae->GetMessageQueue()->OperationModeChanged();
}
}
Settings::values.enable_nfc = ui->enable_nfc->isChecked(); Settings::values.enable_nfc = ui->enable_nfc->isChecked();
} }