diff options
Diffstat (limited to 'src')
26 files changed, 764 insertions, 115 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c59107102..2ace866ee 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -88,6 +88,10 @@ add_library(core STATIC | |||
| 88 | file_sys/vfs_vector.h | 88 | file_sys/vfs_vector.h |
| 89 | file_sys/xts_archive.cpp | 89 | file_sys/xts_archive.cpp |
| 90 | file_sys/xts_archive.h | 90 | file_sys/xts_archive.h |
| 91 | frontend/applets/error.cpp | ||
| 92 | frontend/applets/error.h | ||
| 93 | frontend/applets/general_frontend.cpp | ||
| 94 | frontend/applets/general_frontend.h | ||
| 91 | frontend/applets/profile_select.cpp | 95 | frontend/applets/profile_select.cpp |
| 92 | frontend/applets/profile_select.h | 96 | frontend/applets/profile_select.h |
| 93 | frontend/applets/software_keyboard.cpp | 97 | frontend/applets/software_keyboard.cpp |
| @@ -177,12 +181,14 @@ add_library(core STATIC | |||
| 177 | hle/service/am/applet_oe.h | 181 | hle/service/am/applet_oe.h |
| 178 | hle/service/am/applets/applets.cpp | 182 | hle/service/am/applets/applets.cpp |
| 179 | hle/service/am/applets/applets.h | 183 | hle/service/am/applets/applets.h |
| 184 | hle/service/am/applets/error.cpp | ||
| 185 | hle/service/am/applets/error.h | ||
| 186 | hle/service/am/applets/general_backend.cpp | ||
| 187 | hle/service/am/applets/general_backend.h | ||
| 180 | hle/service/am/applets/profile_select.cpp | 188 | hle/service/am/applets/profile_select.cpp |
| 181 | hle/service/am/applets/profile_select.h | 189 | hle/service/am/applets/profile_select.h |
| 182 | hle/service/am/applets/software_keyboard.cpp | 190 | hle/service/am/applets/software_keyboard.cpp |
| 183 | hle/service/am/applets/software_keyboard.h | 191 | hle/service/am/applets/software_keyboard.h |
| 184 | hle/service/am/applets/stub_applet.cpp | ||
| 185 | hle/service/am/applets/stub_applet.h | ||
| 186 | hle/service/am/applets/web_browser.cpp | 192 | hle/service/am/applets/web_browser.cpp |
| 187 | hle/service/am/applets/web_browser.h | 193 | hle/service/am/applets/web_browser.h |
| 188 | hle/service/am/idle.cpp | 194 | hle/service/am/idle.cpp |
diff --git a/src/core/core.cpp b/src/core/core.cpp index 175a5f2ea..7106151bd 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -18,13 +18,18 @@ | |||
| 18 | #include "core/file_sys/registered_cache.h" | 18 | #include "core/file_sys/registered_cache.h" |
| 19 | #include "core/file_sys/vfs_concat.h" | 19 | #include "core/file_sys/vfs_concat.h" |
| 20 | #include "core/file_sys/vfs_real.h" | 20 | #include "core/file_sys/vfs_real.h" |
| 21 | #include "core/frontend/applets/error.h" | ||
| 22 | #include "core/frontend/applets/general_frontend.h" | ||
| 23 | #include "core/frontend/applets/profile_select.h" | ||
| 24 | #include "core/frontend/applets/software_keyboard.h" | ||
| 25 | #include "core/frontend/applets/web_browser.h" | ||
| 21 | #include "core/gdbstub/gdbstub.h" | 26 | #include "core/gdbstub/gdbstub.h" |
| 22 | #include "core/hle/kernel/client_port.h" | 27 | #include "core/hle/kernel/client_port.h" |
| 23 | #include "core/hle/kernel/kernel.h" | 28 | #include "core/hle/kernel/kernel.h" |
| 24 | #include "core/hle/kernel/process.h" | 29 | #include "core/hle/kernel/process.h" |
| 25 | #include "core/hle/kernel/scheduler.h" | 30 | #include "core/hle/kernel/scheduler.h" |
| 26 | #include "core/hle/kernel/thread.h" | 31 | #include "core/hle/kernel/thread.h" |
| 27 | #include "core/hle/service/am/applets/software_keyboard.h" | 32 | #include "core/hle/service/am/applets/applets.h" |
| 28 | #include "core/hle/service/service.h" | 33 | #include "core/hle/service/service.h" |
| 29 | #include "core/hle/service/sm/sm.h" | 34 | #include "core/hle/service/sm/sm.h" |
| 30 | #include "core/loader/loader.h" | 35 | #include "core/loader/loader.h" |
| @@ -110,12 +115,7 @@ struct System::Impl { | |||
| 110 | content_provider = std::make_unique<FileSys::ContentProviderUnion>(); | 115 | content_provider = std::make_unique<FileSys::ContentProviderUnion>(); |
| 111 | 116 | ||
| 112 | /// Create default implementations of applets if one is not provided. | 117 | /// Create default implementations of applets if one is not provided. |
| 113 | if (profile_selector == nullptr) | 118 | applet_manager.SetDefaultAppletsIfMissing(); |
| 114 | profile_selector = std::make_unique<Core::Frontend::DefaultProfileSelectApplet>(); | ||
| 115 | if (software_keyboard == nullptr) | ||
| 116 | software_keyboard = std::make_unique<Core::Frontend::DefaultSoftwareKeyboardApplet>(); | ||
| 117 | if (web_browser == nullptr) | ||
| 118 | web_browser = std::make_unique<Core::Frontend::DefaultWebBrowserApplet>(); | ||
| 119 | 119 | ||
| 120 | telemetry_session = std::make_unique<Core::TelemetrySession>(); | 120 | telemetry_session = std::make_unique<Core::TelemetrySession>(); |
| 121 | service_manager = std::make_shared<Service::SM::ServiceManager>(); | 121 | service_manager = std::make_shared<Service::SM::ServiceManager>(); |
| @@ -223,9 +223,7 @@ struct System::Impl { | |||
| 223 | app_loader.reset(); | 223 | app_loader.reset(); |
| 224 | 224 | ||
| 225 | // Clear all applets | 225 | // Clear all applets |
| 226 | profile_selector.reset(); | 226 | applet_manager.ClearAll(); |
| 227 | software_keyboard.reset(); | ||
| 228 | web_browser.reset(); | ||
| 229 | 227 | ||
| 230 | LOG_DEBUG(Core, "Shutdown OK"); | 228 | LOG_DEBUG(Core, "Shutdown OK"); |
| 231 | } | 229 | } |
| @@ -264,9 +262,7 @@ struct System::Impl { | |||
| 264 | std::unique_ptr<FileSys::CheatEngine> cheat_engine; | 262 | std::unique_ptr<FileSys::CheatEngine> cheat_engine; |
| 265 | 263 | ||
| 266 | /// Frontend applets | 264 | /// Frontend applets |
| 267 | std::unique_ptr<Core::Frontend::ProfileSelectApplet> profile_selector; | 265 | Service::AM::Applets::AppletManager applet_manager; |
| 268 | std::unique_ptr<Core::Frontend::SoftwareKeyboardApplet> software_keyboard; | ||
| 269 | std::unique_ptr<Core::Frontend::WebBrowserApplet> web_browser; | ||
| 270 | 266 | ||
| 271 | /// Service manager | 267 | /// Service manager |
| 272 | std::shared_ptr<Service::SM::ServiceManager> service_manager; | 268 | std::shared_ptr<Service::SM::ServiceManager> service_manager; |
| @@ -476,20 +472,20 @@ std::shared_ptr<FileSys::VfsFilesystem> System::GetFilesystem() const { | |||
| 476 | return impl->virtual_filesystem; | 472 | return impl->virtual_filesystem; |
| 477 | } | 473 | } |
| 478 | 474 | ||
| 479 | void System::SetProfileSelector(std::unique_ptr<Frontend::ProfileSelectApplet> applet) { | 475 | void System::SetAppletFrontendSet(Service::AM::Applets::AppletFrontendSet&& set) { |
| 480 | impl->profile_selector = std::move(applet); | 476 | impl->applet_manager.SetAppletFrontendSet(std::move(set)); |
| 481 | } | 477 | } |
| 482 | 478 | ||
| 483 | const Frontend::ProfileSelectApplet& System::GetProfileSelector() const { | 479 | void System::SetDefaultAppletFrontendSet() { |
| 484 | return *impl->profile_selector; | 480 | impl->applet_manager.SetDefaultAppletFrontendSet(); |
| 485 | } | 481 | } |
| 486 | 482 | ||
| 487 | void System::SetSoftwareKeyboard(std::unique_ptr<Frontend::SoftwareKeyboardApplet> applet) { | 483 | Service::AM::Applets::AppletManager& System::GetAppletManager() { |
| 488 | impl->software_keyboard = std::move(applet); | 484 | return impl->applet_manager; |
| 489 | } | 485 | } |
| 490 | 486 | ||
| 491 | const Frontend::SoftwareKeyboardApplet& System::GetSoftwareKeyboard() const { | 487 | const Service::AM::Applets::AppletManager& System::GetAppletManager() const { |
| 492 | return *impl->software_keyboard; | 488 | return impl->applet_manager; |
| 493 | } | 489 | } |
| 494 | 490 | ||
| 495 | void System::SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider) { | 491 | void System::SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider) { |
| @@ -513,18 +509,6 @@ void System::ClearContentProvider(FileSys::ContentProviderUnionSlot slot) { | |||
| 513 | impl->content_provider->ClearSlot(slot); | 509 | impl->content_provider->ClearSlot(slot); |
| 514 | } | 510 | } |
| 515 | 511 | ||
| 516 | void System::SetWebBrowser(std::unique_ptr<Frontend::WebBrowserApplet> applet) { | ||
| 517 | impl->web_browser = std::move(applet); | ||
| 518 | } | ||
| 519 | |||
| 520 | Frontend::WebBrowserApplet& System::GetWebBrowser() { | ||
| 521 | return *impl->web_browser; | ||
| 522 | } | ||
| 523 | |||
| 524 | const Frontend::WebBrowserApplet& System::GetWebBrowser() const { | ||
| 525 | return *impl->web_browser; | ||
| 526 | } | ||
| 527 | |||
| 528 | System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) { | 512 | System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) { |
| 529 | return impl->Init(*this, emu_window); | 513 | return impl->Init(*this, emu_window); |
| 530 | } | 514 | } |
diff --git a/src/core/core.h b/src/core/core.h index 82b2e087e..a9a756a4c 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -14,9 +14,6 @@ | |||
| 14 | 14 | ||
| 15 | namespace Core::Frontend { | 15 | namespace Core::Frontend { |
| 16 | class EmuWindow; | 16 | class EmuWindow; |
| 17 | class ProfileSelectApplet; | ||
| 18 | class SoftwareKeyboardApplet; | ||
| 19 | class WebBrowserApplet; | ||
| 20 | } // namespace Core::Frontend | 17 | } // namespace Core::Frontend |
| 21 | 18 | ||
| 22 | namespace FileSys { | 19 | namespace FileSys { |
| @@ -38,9 +35,18 @@ class AppLoader; | |||
| 38 | enum class ResultStatus : u16; | 35 | enum class ResultStatus : u16; |
| 39 | } // namespace Loader | 36 | } // namespace Loader |
| 40 | 37 | ||
| 41 | namespace Service::SM { | 38 | namespace Service { |
| 39 | |||
| 40 | namespace AM::Applets { | ||
| 41 | struct AppletFrontendSet; | ||
| 42 | class AppletManager; | ||
| 43 | } // namespace AM::Applets | ||
| 44 | |||
| 45 | namespace SM { | ||
| 42 | class ServiceManager; | 46 | class ServiceManager; |
| 43 | } // namespace Service::SM | 47 | } // namespace SM |
| 48 | |||
| 49 | } // namespace Service | ||
| 44 | 50 | ||
| 45 | namespace Tegra { | 51 | namespace Tegra { |
| 46 | class DebugContext; | 52 | class DebugContext; |
| @@ -260,18 +266,13 @@ public: | |||
| 260 | void RegisterCheatList(const std::vector<FileSys::CheatList>& list, const std::string& build_id, | 266 | void RegisterCheatList(const std::vector<FileSys::CheatList>& list, const std::string& build_id, |
| 261 | VAddr code_region_start, VAddr code_region_end); | 267 | VAddr code_region_start, VAddr code_region_end); |
| 262 | 268 | ||
| 263 | void SetProfileSelector(std::unique_ptr<Frontend::ProfileSelectApplet> applet); | 269 | void SetAppletFrontendSet(Service::AM::Applets::AppletFrontendSet&& set); |
| 264 | |||
| 265 | const Frontend::ProfileSelectApplet& GetProfileSelector() const; | ||
| 266 | |||
| 267 | void SetSoftwareKeyboard(std::unique_ptr<Frontend::SoftwareKeyboardApplet> applet); | ||
| 268 | 270 | ||
| 269 | const Frontend::SoftwareKeyboardApplet& GetSoftwareKeyboard() const; | 271 | void SetDefaultAppletFrontendSet(); |
| 270 | 272 | ||
| 271 | void SetWebBrowser(std::unique_ptr<Frontend::WebBrowserApplet> applet); | 273 | Service::AM::Applets::AppletManager& GetAppletManager(); |
| 272 | 274 | ||
| 273 | Frontend::WebBrowserApplet& GetWebBrowser(); | 275 | const Service::AM::Applets::AppletManager& GetAppletManager() const; |
| 274 | const Frontend::WebBrowserApplet& GetWebBrowser() const; | ||
| 275 | 276 | ||
| 276 | void SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider); | 277 | void SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider); |
| 277 | 278 | ||
diff --git a/src/core/frontend/applets/error.cpp b/src/core/frontend/applets/error.cpp new file mode 100644 index 000000000..4002a9211 --- /dev/null +++ b/src/core/frontend/applets/error.cpp | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/frontend/applets/error.h" | ||
| 6 | |||
| 7 | namespace Core::Frontend { | ||
| 8 | |||
| 9 | ErrorApplet::~ErrorApplet() = default; | ||
| 10 | |||
| 11 | void DefaultErrorApplet::ShowError(ResultCode error, std::function<void()> finished) const { | ||
| 12 | LOG_CRITICAL(Service_Fatal, "Application requested error display: {:04}-{:04} (raw={:08X})", | ||
| 13 | static_cast<u32>(error.module.Value()), error.description.Value(), error.raw); | ||
| 14 | } | ||
| 15 | |||
| 16 | void DefaultErrorApplet::ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, | ||
| 17 | std::function<void()> finished) const { | ||
| 18 | LOG_CRITICAL( | ||
| 19 | Service_Fatal, | ||
| 20 | "Application requested error display: {:04X}-{:04X} (raw={:08X}) with timestamp={:016X}", | ||
| 21 | static_cast<u32>(error.module.Value()), error.description.Value(), error.raw, time.count()); | ||
| 22 | } | ||
| 23 | |||
| 24 | void DefaultErrorApplet::ShowCustomErrorText(ResultCode error, std::string main_text, | ||
| 25 | std::string detail_text, | ||
| 26 | std::function<void()> finished) const { | ||
| 27 | LOG_CRITICAL(Service_Fatal, | ||
| 28 | "Application requested custom error with error_code={:04X}-{:04X} (raw={:08X})", | ||
| 29 | static_cast<u32>(error.module.Value()), error.description.Value(), error.raw); | ||
| 30 | LOG_CRITICAL(Service_Fatal, " Main Text: {}", main_text); | ||
| 31 | LOG_CRITICAL(Service_Fatal, " Detail Text: {}", detail_text); | ||
| 32 | } | ||
| 33 | |||
| 34 | } // namespace Core::Frontend | ||
diff --git a/src/core/frontend/applets/error.h b/src/core/frontend/applets/error.h new file mode 100644 index 000000000..699df940d --- /dev/null +++ b/src/core/frontend/applets/error.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <chrono> | ||
| 8 | #include <functional> | ||
| 9 | |||
| 10 | #include "core/hle/result.h" | ||
| 11 | |||
| 12 | namespace Core::Frontend { | ||
| 13 | |||
| 14 | class ErrorApplet { | ||
| 15 | public: | ||
| 16 | virtual ~ErrorApplet(); | ||
| 17 | |||
| 18 | virtual void ShowError(ResultCode error, std::function<void()> finished) const = 0; | ||
| 19 | |||
| 20 | virtual void ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, | ||
| 21 | std::function<void()> finished) const = 0; | ||
| 22 | |||
| 23 | virtual void ShowCustomErrorText(ResultCode error, std::string dialog_text, | ||
| 24 | std::string fullscreen_text, | ||
| 25 | std::function<void()> finished) const = 0; | ||
| 26 | }; | ||
| 27 | |||
| 28 | class DefaultErrorApplet final : public ErrorApplet { | ||
| 29 | public: | ||
| 30 | void ShowError(ResultCode error, std::function<void()> finished) const override; | ||
| 31 | void ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, | ||
| 32 | std::function<void()> finished) const override; | ||
| 33 | void ShowCustomErrorText(ResultCode error, std::string main_text, std::string detail_text, | ||
| 34 | std::function<void()> finished) const override; | ||
| 35 | }; | ||
| 36 | |||
| 37 | } // namespace Core::Frontend | ||
diff --git a/src/core/frontend/applets/general_frontend.cpp b/src/core/frontend/applets/general_frontend.cpp new file mode 100644 index 000000000..b974f2289 --- /dev/null +++ b/src/core/frontend/applets/general_frontend.cpp | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/logging/log.h" | ||
| 6 | #include "core/frontend/applets/general_frontend.h" | ||
| 7 | |||
| 8 | namespace Core::Frontend { | ||
| 9 | |||
| 10 | PhotoViewerApplet::~PhotoViewerApplet() = default; | ||
| 11 | |||
| 12 | DefaultPhotoViewerApplet::~DefaultPhotoViewerApplet() {} | ||
| 13 | |||
| 14 | void DefaultPhotoViewerApplet::ShowPhotosForApplication(u64 title_id, | ||
| 15 | std::function<void()> finished) const { | ||
| 16 | LOG_INFO(Service_AM, | ||
| 17 | "Application requested frontend to display stored photos for title_id={:016X}", | ||
| 18 | title_id); | ||
| 19 | finished(); | ||
| 20 | } | ||
| 21 | |||
| 22 | void DefaultPhotoViewerApplet::ShowAllPhotos(std::function<void()> finished) const { | ||
| 23 | LOG_INFO(Service_AM, "Application requested frontend to display all stored photos."); | ||
| 24 | finished(); | ||
| 25 | } | ||
| 26 | |||
| 27 | } // namespace Core::Frontend | ||
diff --git a/src/core/frontend/applets/general_frontend.h b/src/core/frontend/applets/general_frontend.h new file mode 100644 index 000000000..d4506c999 --- /dev/null +++ b/src/core/frontend/applets/general_frontend.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <functional> | ||
| 8 | #include "common/common_types.h" | ||
| 9 | |||
| 10 | namespace Core::Frontend { | ||
| 11 | |||
| 12 | class PhotoViewerApplet { | ||
| 13 | public: | ||
| 14 | virtual ~PhotoViewerApplet(); | ||
| 15 | |||
| 16 | virtual void ShowPhotosForApplication(u64 title_id, std::function<void()> finished) const = 0; | ||
| 17 | virtual void ShowAllPhotos(std::function<void()> finished) const = 0; | ||
| 18 | }; | ||
| 19 | |||
| 20 | class DefaultPhotoViewerApplet final : public PhotoViewerApplet { | ||
| 21 | public: | ||
| 22 | ~DefaultPhotoViewerApplet() override; | ||
| 23 | |||
| 24 | void ShowPhotosForApplication(u64 title_id, std::function<void()> finished) const override; | ||
| 25 | void ShowAllPhotos(std::function<void()> finished) const override; | ||
| 26 | }; | ||
| 27 | |||
| 28 | } // namespace Core::Frontend | ||
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 1aa4ce1ac..26a665bfd 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | #include "core/hle/service/am/applets/applets.h" | 22 | #include "core/hle/service/am/applets/applets.h" |
| 23 | #include "core/hle/service/am/applets/profile_select.h" | 23 | #include "core/hle/service/am/applets/profile_select.h" |
| 24 | #include "core/hle/service/am/applets/software_keyboard.h" | 24 | #include "core/hle/service/am/applets/software_keyboard.h" |
| 25 | #include "core/hle/service/am/applets/stub_applet.h" | ||
| 26 | #include "core/hle/service/am/applets/web_browser.h" | 25 | #include "core/hle/service/am/applets/web_browser.h" |
| 27 | #include "core/hle/service/am/idle.h" | 26 | #include "core/hle/service/am/idle.h" |
| 28 | #include "core/hle/service/am/omm.h" | 27 | #include "core/hle/service/am/omm.h" |
| @@ -42,12 +41,6 @@ constexpr ResultCode ERR_NO_DATA_IN_CHANNEL{ErrorModule::AM, 0x2}; | |||
| 42 | constexpr ResultCode ERR_NO_MESSAGES{ErrorModule::AM, 0x3}; | 41 | constexpr ResultCode ERR_NO_MESSAGES{ErrorModule::AM, 0x3}; |
| 43 | constexpr ResultCode ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 0x1F7}; | 42 | constexpr ResultCode ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 0x1F7}; |
| 44 | 43 | ||
| 45 | enum class AppletId : u32 { | ||
| 46 | ProfileSelect = 0x10, | ||
| 47 | SoftwareKeyboard = 0x11, | ||
| 48 | LibAppletOff = 0x17, | ||
| 49 | }; | ||
| 50 | |||
| 51 | constexpr u32 POP_LAUNCH_PARAMETER_MAGIC = 0xC79497CA; | 44 | constexpr u32 POP_LAUNCH_PARAMETER_MAGIC = 0xC79497CA; |
| 52 | 45 | ||
| 53 | struct LaunchParameters { | 46 | struct LaunchParameters { |
| @@ -886,30 +879,16 @@ ILibraryAppletCreator::ILibraryAppletCreator() : ServiceFramework("ILibraryApple | |||
| 886 | 879 | ||
| 887 | ILibraryAppletCreator::~ILibraryAppletCreator() = default; | 880 | ILibraryAppletCreator::~ILibraryAppletCreator() = default; |
| 888 | 881 | ||
| 889 | static std::shared_ptr<Applets::Applet> GetAppletFromId(AppletId id) { | ||
| 890 | switch (id) { | ||
| 891 | case AppletId::ProfileSelect: | ||
| 892 | return std::make_shared<Applets::ProfileSelect>(); | ||
| 893 | case AppletId::SoftwareKeyboard: | ||
| 894 | return std::make_shared<Applets::SoftwareKeyboard>(); | ||
| 895 | case AppletId::LibAppletOff: | ||
| 896 | return std::make_shared<Applets::WebBrowser>(); | ||
| 897 | default: | ||
| 898 | LOG_ERROR(Service_AM, "Unimplemented AppletId [{:08X}]! -- Falling back to stub!", | ||
| 899 | static_cast<u32>(id)); | ||
| 900 | return std::make_shared<Applets::StubApplet>(); | ||
| 901 | } | ||
| 902 | } | ||
| 903 | |||
| 904 | void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) { | 882 | void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) { |
| 905 | IPC::RequestParser rp{ctx}; | 883 | IPC::RequestParser rp{ctx}; |
| 906 | const auto applet_id = rp.PopRaw<AppletId>(); | 884 | const auto applet_id = rp.PopRaw<Applets::AppletId>(); |
| 907 | const auto applet_mode = rp.PopRaw<u32>(); | 885 | const auto applet_mode = rp.PopRaw<u32>(); |
| 908 | 886 | ||
| 909 | LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", | 887 | LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", |
| 910 | static_cast<u32>(applet_id), applet_mode); | 888 | static_cast<u32>(applet_id), applet_mode); |
| 911 | 889 | ||
| 912 | const auto applet = GetAppletFromId(applet_id); | 890 | const auto& applet_manager{Core::System::GetInstance().GetAppletManager()}; |
| 891 | const auto applet = applet_manager.GetApplet(applet_id); | ||
| 913 | 892 | ||
| 914 | if (applet == nullptr) { | 893 | if (applet == nullptr) { |
| 915 | LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", static_cast<u32>(applet_id)); | 894 | LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", static_cast<u32>(applet_id)); |
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index a6064c63f..7f70b10df 100644 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp | |||
| @@ -5,11 +5,21 @@ | |||
| 5 | #include <cstring> | 5 | #include <cstring> |
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/frontend/applets/error.h" | ||
| 9 | #include "core/frontend/applets/general_frontend.h" | ||
| 10 | #include "core/frontend/applets/profile_select.h" | ||
| 11 | #include "core/frontend/applets/software_keyboard.h" | ||
| 12 | #include "core/frontend/applets/web_browser.h" | ||
| 8 | #include "core/hle/kernel/readable_event.h" | 13 | #include "core/hle/kernel/readable_event.h" |
| 9 | #include "core/hle/kernel/server_session.h" | 14 | #include "core/hle/kernel/server_session.h" |
| 10 | #include "core/hle/kernel/writable_event.h" | 15 | #include "core/hle/kernel/writable_event.h" |
| 11 | #include "core/hle/service/am/am.h" | 16 | #include "core/hle/service/am/am.h" |
| 12 | #include "core/hle/service/am/applets/applets.h" | 17 | #include "core/hle/service/am/applets/applets.h" |
| 18 | #include "core/hle/service/am/applets/error.h" | ||
| 19 | #include "core/hle/service/am/applets/general_backend.h" | ||
| 20 | #include "core/hle/service/am/applets/profile_select.h" | ||
| 21 | #include "core/hle/service/am/applets/software_keyboard.h" | ||
| 22 | #include "core/hle/service/am/applets/web_browser.h" | ||
| 13 | 23 | ||
| 14 | namespace Service::AM::Applets { | 24 | namespace Service::AM::Applets { |
| 15 | 25 | ||
| @@ -111,4 +121,76 @@ void Applet::Initialize() { | |||
| 111 | initialized = true; | 121 | initialized = true; |
| 112 | } | 122 | } |
| 113 | 123 | ||
| 124 | AppletManager::AppletManager() = default; | ||
| 125 | |||
| 126 | AppletManager::~AppletManager() = default; | ||
| 127 | |||
| 128 | void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) { | ||
| 129 | if (set.error != nullptr) | ||
| 130 | frontend.error = std::move(set.error); | ||
| 131 | if (set.photo_viewer != nullptr) | ||
| 132 | frontend.photo_viewer = std::move(set.photo_viewer); | ||
| 133 | if (set.profile_select != nullptr) | ||
| 134 | frontend.profile_select = std::move(set.profile_select); | ||
| 135 | if (set.software_keyboard != nullptr) | ||
| 136 | frontend.software_keyboard = std::move(set.software_keyboard); | ||
| 137 | if (set.web_browser != nullptr) | ||
| 138 | frontend.web_browser = std::move(set.web_browser); | ||
| 139 | } | ||
| 140 | |||
| 141 | void AppletManager::SetDefaultAppletFrontendSet() { | ||
| 142 | frontend.error = std::make_unique<Core::Frontend::DefaultErrorApplet>(); | ||
| 143 | frontend.photo_viewer = std::make_unique<Core::Frontend::DefaultPhotoViewerApplet>(); | ||
| 144 | frontend.profile_select = std::make_unique<Core::Frontend::DefaultProfileSelectApplet>(); | ||
| 145 | frontend.software_keyboard = std::make_unique<Core::Frontend::DefaultSoftwareKeyboardApplet>(); | ||
| 146 | frontend.web_browser = std::make_unique<Core::Frontend::DefaultWebBrowserApplet>(); | ||
| 147 | } | ||
| 148 | |||
| 149 | void AppletManager::SetDefaultAppletsIfMissing() { | ||
| 150 | if (frontend.error == nullptr) { | ||
| 151 | frontend.error = std::make_unique<Core::Frontend::DefaultErrorApplet>(); | ||
| 152 | } | ||
| 153 | |||
| 154 | if (frontend.photo_viewer == nullptr) { | ||
| 155 | frontend.photo_viewer = std::make_unique<Core::Frontend::DefaultPhotoViewerApplet>(); | ||
| 156 | } | ||
| 157 | |||
| 158 | if (frontend.profile_select == nullptr) { | ||
| 159 | frontend.profile_select = std::make_unique<Core::Frontend::DefaultProfileSelectApplet>(); | ||
| 160 | } | ||
| 161 | |||
| 162 | if (frontend.software_keyboard == nullptr) { | ||
| 163 | frontend.software_keyboard = | ||
| 164 | std::make_unique<Core::Frontend::DefaultSoftwareKeyboardApplet>(); | ||
| 165 | } | ||
| 166 | |||
| 167 | if (frontend.web_browser == nullptr) { | ||
| 168 | frontend.web_browser = std::make_unique<Core::Frontend::DefaultWebBrowserApplet>(); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | void AppletManager::ClearAll() { | ||
| 173 | frontend = {}; | ||
| 174 | } | ||
| 175 | |||
| 176 | std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id) const { | ||
| 177 | switch (id) { | ||
| 178 | case AppletId::Error: | ||
| 179 | return std::make_shared<Error>(*frontend.error); | ||
| 180 | case AppletId::ProfileSelect: | ||
| 181 | return std::make_shared<ProfileSelect>(*frontend.profile_select); | ||
| 182 | case AppletId::SoftwareKeyboard: | ||
| 183 | return std::make_shared<SoftwareKeyboard>(*frontend.software_keyboard); | ||
| 184 | case AppletId::PhotoViewer: | ||
| 185 | return std::make_shared<PhotoViewer>(*frontend.photo_viewer); | ||
| 186 | case AppletId::LibAppletOff: | ||
| 187 | return std::make_shared<WebBrowser>(*frontend.web_browser); | ||
| 188 | default: | ||
| 189 | UNIMPLEMENTED_MSG( | ||
| 190 | "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.", | ||
| 191 | static_cast<u8>(id)); | ||
| 192 | return std::make_shared<StubApplet>(); | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 114 | } // namespace Service::AM::Applets | 196 | } // namespace Service::AM::Applets |
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index 37424c379..7f932672c 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h | |||
| @@ -12,12 +12,43 @@ | |||
| 12 | 12 | ||
| 13 | union ResultCode; | 13 | union ResultCode; |
| 14 | 14 | ||
| 15 | namespace Core::Frontend { | ||
| 16 | class ErrorApplet; | ||
| 17 | class PhotoViewerApplet; | ||
| 18 | class ProfileSelectApplet; | ||
| 19 | class SoftwareKeyboardApplet; | ||
| 20 | class WebBrowserApplet; | ||
| 21 | } // namespace Core::Frontend | ||
| 22 | |||
| 15 | namespace Service::AM { | 23 | namespace Service::AM { |
| 16 | 24 | ||
| 17 | class IStorage; | 25 | class IStorage; |
| 18 | 26 | ||
| 19 | namespace Applets { | 27 | namespace Applets { |
| 20 | 28 | ||
| 29 | enum class AppletId : u32 { | ||
| 30 | OverlayDisplay = 0x02, | ||
| 31 | QLaunch = 0x03, | ||
| 32 | Starter = 0x04, | ||
| 33 | Auth = 0x0A, | ||
| 34 | Cabinet = 0x0B, | ||
| 35 | Controller = 0x0C, | ||
| 36 | DataErase = 0x0D, | ||
| 37 | Error = 0x0E, | ||
| 38 | NetConnect = 0x0F, | ||
| 39 | ProfileSelect = 0x10, | ||
| 40 | SoftwareKeyboard = 0x11, | ||
| 41 | MiiEdit = 0x12, | ||
| 42 | LibAppletWeb = 0x13, | ||
| 43 | LibAppletShop = 0x14, | ||
| 44 | PhotoViewer = 0x15, | ||
| 45 | Settings = 0x16, | ||
| 46 | LibAppletOff = 0x17, | ||
| 47 | LibAppletWhitelisted = 0x18, | ||
| 48 | LibAppletAuth = 0x19, | ||
| 49 | MyPage = 0x1A, | ||
| 50 | }; | ||
| 51 | |||
| 21 | class AppletDataBroker final { | 52 | class AppletDataBroker final { |
| 22 | public: | 53 | public: |
| 23 | AppletDataBroker(); | 54 | AppletDataBroker(); |
| @@ -105,5 +136,29 @@ protected: | |||
| 105 | bool initialized = false; | 136 | bool initialized = false; |
| 106 | }; | 137 | }; |
| 107 | 138 | ||
| 139 | struct AppletFrontendSet { | ||
| 140 | std::unique_ptr<Core::Frontend::ErrorApplet> error; | ||
| 141 | std::unique_ptr<Core::Frontend::PhotoViewerApplet> photo_viewer; | ||
| 142 | std::unique_ptr<Core::Frontend::ProfileSelectApplet> profile_select; | ||
| 143 | std::unique_ptr<Core::Frontend::SoftwareKeyboardApplet> software_keyboard; | ||
| 144 | std::unique_ptr<Core::Frontend::WebBrowserApplet> web_browser; | ||
| 145 | }; | ||
| 146 | |||
| 147 | class AppletManager { | ||
| 148 | public: | ||
| 149 | AppletManager(); | ||
| 150 | ~AppletManager(); | ||
| 151 | |||
| 152 | void SetAppletFrontendSet(AppletFrontendSet set); | ||
| 153 | void SetDefaultAppletFrontendSet(); | ||
| 154 | void SetDefaultAppletsIfMissing(); | ||
| 155 | void ClearAll(); | ||
| 156 | |||
| 157 | std::shared_ptr<Applet> GetApplet(AppletId id) const; | ||
| 158 | |||
| 159 | private: | ||
| 160 | AppletFrontendSet frontend; | ||
| 161 | }; | ||
| 162 | |||
| 108 | } // namespace Applets | 163 | } // namespace Applets |
| 109 | } // namespace Service::AM | 164 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp new file mode 100644 index 000000000..04774bedc --- /dev/null +++ b/src/core/hle/service/am/applets/error.cpp | |||
| @@ -0,0 +1,182 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <array> | ||
| 6 | #include <cstring> | ||
| 7 | #include "common/assert.h" | ||
| 8 | #include "common/logging/log.h" | ||
| 9 | #include "common/string_util.h" | ||
| 10 | #include "core/core.h" | ||
| 11 | #include "core/frontend/applets/error.h" | ||
| 12 | #include "core/hle/service/am/am.h" | ||
| 13 | #include "core/hle/service/am/applets/error.h" | ||
| 14 | |||
| 15 | namespace Service::AM::Applets { | ||
| 16 | |||
| 17 | #pragma pack(push, 4) | ||
| 18 | struct ShowError { | ||
| 19 | u8 mode; | ||
| 20 | bool jump; | ||
| 21 | INSERT_PADDING_BYTES(4); | ||
| 22 | bool use_64bit_error_code; | ||
| 23 | INSERT_PADDING_BYTES(1); | ||
| 24 | u64 error_code_64; | ||
| 25 | u32 error_code_32; | ||
| 26 | }; | ||
| 27 | static_assert(sizeof(ShowError) == 0x14, "ShowError has incorrect size."); | ||
| 28 | #pragma pack(pop) | ||
| 29 | |||
| 30 | struct ShowErrorRecord { | ||
| 31 | u8 mode; | ||
| 32 | bool jump; | ||
| 33 | INSERT_PADDING_BYTES(6); | ||
| 34 | u64 error_code_64; | ||
| 35 | u64 posix_time; | ||
| 36 | }; | ||
| 37 | static_assert(sizeof(ShowErrorRecord) == 0x18, "ShowErrorRecord has incorrect size."); | ||
| 38 | |||
| 39 | struct SystemErrorArg { | ||
| 40 | u8 mode; | ||
| 41 | bool jump; | ||
| 42 | INSERT_PADDING_BYTES(6); | ||
| 43 | u64 error_code_64; | ||
| 44 | std::array<char, 8> language_code; | ||
| 45 | std::array<char, 0x800> main_text; | ||
| 46 | std::array<char, 0x800> detail_text; | ||
| 47 | }; | ||
| 48 | static_assert(sizeof(SystemErrorArg) == 0x1018, "SystemErrorArg has incorrect size."); | ||
| 49 | |||
| 50 | struct ApplicationErrorArg { | ||
| 51 | u8 mode; | ||
| 52 | bool jump; | ||
| 53 | INSERT_PADDING_BYTES(6); | ||
| 54 | u32 error_code; | ||
| 55 | std::array<char, 8> language_code; | ||
| 56 | std::array<char, 0x800> main_text; | ||
| 57 | std::array<char, 0x800> detail_text; | ||
| 58 | }; | ||
| 59 | static_assert(sizeof(ApplicationErrorArg) == 0x1014, "ApplicationErrorArg has incorrect size."); | ||
| 60 | |||
| 61 | union Error::ErrorArguments { | ||
| 62 | ShowError error; | ||
| 63 | ShowErrorRecord error_record; | ||
| 64 | SystemErrorArg system_error; | ||
| 65 | ApplicationErrorArg application_error; | ||
| 66 | }; | ||
| 67 | |||
| 68 | namespace { | ||
| 69 | template <typename T> | ||
| 70 | void CopyArgumentData(const std::vector<u8>& data, T& variable) { | ||
| 71 | ASSERT(data.size() >= sizeof(T)); | ||
| 72 | std::memcpy(&variable, data.data(), sizeof(T)); | ||
| 73 | } | ||
| 74 | |||
| 75 | ResultCode Decode64BitError(u64 error) { | ||
| 76 | const auto description = (error >> 32) & 0x1FFF; | ||
| 77 | auto module = error & 0x3FF; | ||
| 78 | if (module >= 2000) | ||
| 79 | module -= 2000; | ||
| 80 | module &= 0x1FF; | ||
| 81 | return {static_cast<ErrorModule>(module), static_cast<u32>(description)}; | ||
| 82 | } | ||
| 83 | |||
| 84 | } // Anonymous namespace | ||
| 85 | |||
| 86 | Error::Error(const Core::Frontend::ErrorApplet& frontend) : frontend(frontend) {} | ||
| 87 | |||
| 88 | Error::~Error() = default; | ||
| 89 | |||
| 90 | void Error::Initialize() { | ||
| 91 | Applet::Initialize(); | ||
| 92 | args = std::make_unique<ErrorArguments>(); | ||
| 93 | complete = false; | ||
| 94 | |||
| 95 | const auto storage = broker.PopNormalDataToApplet(); | ||
| 96 | ASSERT(storage != nullptr); | ||
| 97 | const auto data = storage->GetData(); | ||
| 98 | |||
| 99 | ASSERT(!data.empty()); | ||
| 100 | std::memcpy(&mode, data.data(), sizeof(ErrorAppletMode)); | ||
| 101 | |||
| 102 | switch (mode) { | ||
| 103 | case ErrorAppletMode::ShowError: | ||
| 104 | CopyArgumentData(data, args->error); | ||
| 105 | if (args->error.use_64bit_error_code) { | ||
| 106 | error_code = Decode64BitError(args->error.error_code_64); | ||
| 107 | } else { | ||
| 108 | error_code = ResultCode(args->error.error_code_32); | ||
| 109 | } | ||
| 110 | break; | ||
| 111 | case ErrorAppletMode::ShowSystemError: | ||
| 112 | CopyArgumentData(data, args->system_error); | ||
| 113 | error_code = ResultCode(Decode64BitError(args->system_error.error_code_64)); | ||
| 114 | break; | ||
| 115 | case ErrorAppletMode::ShowApplicationError: | ||
| 116 | CopyArgumentData(data, args->application_error); | ||
| 117 | error_code = ResultCode(args->application_error.error_code); | ||
| 118 | break; | ||
| 119 | case ErrorAppletMode::ShowErrorRecord: | ||
| 120 | CopyArgumentData(data, args->error_record); | ||
| 121 | error_code = Decode64BitError(args->error_record.error_code_64); | ||
| 122 | break; | ||
| 123 | default: | ||
| 124 | UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", static_cast<u8>(mode)); | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | bool Error::TransactionComplete() const { | ||
| 129 | return complete; | ||
| 130 | } | ||
| 131 | |||
| 132 | ResultCode Error::GetStatus() const { | ||
| 133 | return RESULT_SUCCESS; | ||
| 134 | } | ||
| 135 | |||
| 136 | void Error::ExecuteInteractive() { | ||
| 137 | UNREACHABLE_MSG("Unexpected interactive applet data!"); | ||
| 138 | } | ||
| 139 | |||
| 140 | void Error::Execute() { | ||
| 141 | if (complete) { | ||
| 142 | return; | ||
| 143 | } | ||
| 144 | |||
| 145 | const auto callback = [this] { DisplayCompleted(); }; | ||
| 146 | |||
| 147 | switch (mode) { | ||
| 148 | case ErrorAppletMode::ShowError: | ||
| 149 | frontend.ShowError(error_code, callback); | ||
| 150 | break; | ||
| 151 | case ErrorAppletMode::ShowSystemError: | ||
| 152 | case ErrorAppletMode::ShowApplicationError: { | ||
| 153 | const auto system = mode == ErrorAppletMode::ShowSystemError; | ||
| 154 | const auto& main_text = | ||
| 155 | system ? args->system_error.main_text : args->application_error.main_text; | ||
| 156 | const auto& detail_text = | ||
| 157 | system ? args->system_error.detail_text : args->application_error.detail_text; | ||
| 158 | |||
| 159 | frontend.ShowCustomErrorText( | ||
| 160 | error_code, | ||
| 161 | Common::StringFromFixedZeroTerminatedBuffer(main_text.data(), main_text.size()), | ||
| 162 | Common::StringFromFixedZeroTerminatedBuffer(detail_text.data(), detail_text.size()), | ||
| 163 | callback); | ||
| 164 | break; | ||
| 165 | } | ||
| 166 | case ErrorAppletMode::ShowErrorRecord: | ||
| 167 | frontend.ShowErrorWithTimestamp( | ||
| 168 | error_code, std::chrono::seconds{args->error_record.posix_time}, callback); | ||
| 169 | break; | ||
| 170 | default: | ||
| 171 | UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", static_cast<u8>(mode)); | ||
| 172 | DisplayCompleted(); | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | void Error::DisplayCompleted() { | ||
| 177 | complete = true; | ||
| 178 | broker.PushNormalDataFromApplet(IStorage{{}}); | ||
| 179 | broker.SignalStateChanged(); | ||
| 180 | } | ||
| 181 | |||
| 182 | } // namespace Service::AM::Applets | ||
diff --git a/src/core/hle/service/am/applets/error.h b/src/core/hle/service/am/applets/error.h new file mode 100644 index 000000000..a3590d181 --- /dev/null +++ b/src/core/hle/service/am/applets/error.h | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/result.h" | ||
| 8 | #include "core/hle/service/am/applets/applets.h" | ||
| 9 | |||
| 10 | namespace Service::AM::Applets { | ||
| 11 | |||
| 12 | enum class ErrorAppletMode : u8 { | ||
| 13 | ShowError = 0, | ||
| 14 | ShowSystemError = 1, | ||
| 15 | ShowApplicationError = 2, | ||
| 16 | ShowEula = 3, | ||
| 17 | ShowErrorPctl = 4, | ||
| 18 | ShowErrorRecord = 5, | ||
| 19 | ShowUpdateEula = 8, | ||
| 20 | }; | ||
| 21 | |||
| 22 | class Error final : public Applet { | ||
| 23 | public: | ||
| 24 | explicit Error(const Core::Frontend::ErrorApplet& frontend); | ||
| 25 | ~Error() override; | ||
| 26 | |||
| 27 | void Initialize() override; | ||
| 28 | |||
| 29 | bool TransactionComplete() const override; | ||
| 30 | ResultCode GetStatus() const override; | ||
| 31 | void ExecuteInteractive() override; | ||
| 32 | void Execute() override; | ||
| 33 | |||
| 34 | void DisplayCompleted(); | ||
| 35 | |||
| 36 | private: | ||
| 37 | union ErrorArguments; | ||
| 38 | |||
| 39 | const Core::Frontend::ErrorApplet& frontend; | ||
| 40 | ResultCode error_code = RESULT_SUCCESS; | ||
| 41 | ErrorAppletMode mode = ErrorAppletMode::ShowError; | ||
| 42 | std::unique_ptr<ErrorArguments> args; | ||
| 43 | |||
| 44 | bool complete = false; | ||
| 45 | }; | ||
| 46 | |||
| 47 | } // namespace Service::AM::Applets | ||
diff --git a/src/core/hle/service/am/applets/stub_applet.cpp b/src/core/hle/service/am/applets/general_backend.cpp index ed166b87d..c591b9ac2 100644 --- a/src/core/hle/service/am/applets/stub_applet.cpp +++ b/src/core/hle/service/am/applets/general_backend.cpp | |||
| @@ -4,11 +4,15 @@ | |||
| 4 | 4 | ||
| 5 | #include <string> | 5 | #include <string> |
| 6 | 6 | ||
| 7 | #include "common/assert.h" | ||
| 7 | #include "common/hex_util.h" | 8 | #include "common/hex_util.h" |
| 8 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 10 | #include "core/core.h" | ||
| 11 | #include "core/frontend/applets/general_frontend.h" | ||
| 12 | #include "core/hle/kernel/process.h" | ||
| 9 | #include "core/hle/result.h" | 13 | #include "core/hle/result.h" |
| 10 | #include "core/hle/service/am/am.h" | 14 | #include "core/hle/service/am/am.h" |
| 11 | #include "core/hle/service/am/applets/stub_applet.h" | 15 | #include "core/hle/service/am/applets/general_backend.h" |
| 12 | 16 | ||
| 13 | namespace Service::AM::Applets { | 17 | namespace Service::AM::Applets { |
| 14 | 18 | ||
| @@ -30,6 +34,55 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string prefix) { | |||
| 30 | } | 34 | } |
| 31 | } | 35 | } |
| 32 | 36 | ||
| 37 | PhotoViewer::PhotoViewer(const Core::Frontend::PhotoViewerApplet& frontend) : frontend(frontend) {} | ||
| 38 | |||
| 39 | PhotoViewer::~PhotoViewer() = default; | ||
| 40 | |||
| 41 | void PhotoViewer::Initialize() { | ||
| 42 | Applet::Initialize(); | ||
| 43 | complete = false; | ||
| 44 | |||
| 45 | const auto storage = broker.PopNormalDataToApplet(); | ||
| 46 | ASSERT(storage != nullptr); | ||
| 47 | const auto data = storage->GetData(); | ||
| 48 | ASSERT(!data.empty()); | ||
| 49 | mode = static_cast<PhotoViewerAppletMode>(data[0]); | ||
| 50 | } | ||
| 51 | |||
| 52 | bool PhotoViewer::TransactionComplete() const { | ||
| 53 | return complete; | ||
| 54 | } | ||
| 55 | |||
| 56 | ResultCode PhotoViewer::GetStatus() const { | ||
| 57 | return RESULT_SUCCESS; | ||
| 58 | } | ||
| 59 | |||
| 60 | void PhotoViewer::ExecuteInteractive() { | ||
| 61 | UNREACHABLE_MSG("Unexpected interactive applet data."); | ||
| 62 | } | ||
| 63 | |||
| 64 | void PhotoViewer::Execute() { | ||
| 65 | if (complete) | ||
| 66 | return; | ||
| 67 | |||
| 68 | const auto callback = [this] { ViewFinished(); }; | ||
| 69 | switch (mode) { | ||
| 70 | case PhotoViewerAppletMode::CurrentApp: | ||
| 71 | frontend.ShowPhotosForApplication(Core::CurrentProcess()->GetTitleID(), callback); | ||
| 72 | break; | ||
| 73 | case PhotoViewerAppletMode::AllApps: | ||
| 74 | frontend.ShowAllPhotos(callback); | ||
| 75 | break; | ||
| 76 | default: | ||
| 77 | UNIMPLEMENTED_MSG("Unimplemented PhotoViewer applet mode={:02X}!", static_cast<u8>(mode)); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | void PhotoViewer::ViewFinished() { | ||
| 82 | broker.PushNormalDataFromApplet(IStorage{{}}); | ||
| 83 | broker.SignalStateChanged(); | ||
| 84 | } | ||
| 85 | |||
| 33 | StubApplet::StubApplet() = default; | 86 | StubApplet::StubApplet() = default; |
| 34 | 87 | ||
| 35 | StubApplet::~StubApplet() = default; | 88 | StubApplet::~StubApplet() = default; |
| @@ -67,4 +120,5 @@ void StubApplet::Execute() { | |||
| 67 | broker.PushInteractiveDataFromApplet(IStorage{std::vector<u8>(0x1000)}); | 120 | broker.PushInteractiveDataFromApplet(IStorage{std::vector<u8>(0x1000)}); |
| 68 | broker.SignalStateChanged(); | 121 | broker.SignalStateChanged(); |
| 69 | } | 122 | } |
| 123 | |||
| 70 | } // namespace Service::AM::Applets | 124 | } // namespace Service::AM::Applets |
diff --git a/src/core/hle/service/am/applets/general_backend.h b/src/core/hle/service/am/applets/general_backend.h new file mode 100644 index 000000000..2dd255d7c --- /dev/null +++ b/src/core/hle/service/am/applets/general_backend.h | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/am/applets/applets.h" | ||
| 8 | |||
| 9 | namespace Service::AM::Applets { | ||
| 10 | |||
| 11 | enum class PhotoViewerAppletMode : u8 { | ||
| 12 | CurrentApp = 0, | ||
| 13 | AllApps = 1, | ||
| 14 | }; | ||
| 15 | |||
| 16 | class PhotoViewer final : public Applet { | ||
| 17 | public: | ||
| 18 | explicit PhotoViewer(const Core::Frontend::PhotoViewerApplet& frontend); | ||
| 19 | ~PhotoViewer() override; | ||
| 20 | |||
| 21 | void Initialize() override; | ||
| 22 | bool TransactionComplete() const override; | ||
| 23 | ResultCode GetStatus() const override; | ||
| 24 | void ExecuteInteractive() override; | ||
| 25 | void Execute() override; | ||
| 26 | |||
| 27 | void ViewFinished(); | ||
| 28 | |||
| 29 | private: | ||
| 30 | const Core::Frontend::PhotoViewerApplet& frontend; | ||
| 31 | bool complete = false; | ||
| 32 | PhotoViewerAppletMode mode = PhotoViewerAppletMode::CurrentApp; | ||
| 33 | }; | ||
| 34 | |||
| 35 | class StubApplet final : public Applet { | ||
| 36 | public: | ||
| 37 | StubApplet(); | ||
| 38 | ~StubApplet() override; | ||
| 39 | |||
| 40 | void Initialize() override; | ||
| 41 | |||
| 42 | bool TransactionComplete() const override; | ||
| 43 | ResultCode GetStatus() const override; | ||
| 44 | void ExecuteInteractive() override; | ||
| 45 | void Execute() override; | ||
| 46 | }; | ||
| 47 | |||
| 48 | } // namespace Service::AM::Applets | ||
diff --git a/src/core/hle/service/am/applets/profile_select.cpp b/src/core/hle/service/am/applets/profile_select.cpp index 14e2a1fee..d113bd2eb 100644 --- a/src/core/hle/service/am/applets/profile_select.cpp +++ b/src/core/hle/service/am/applets/profile_select.cpp | |||
| @@ -15,7 +15,9 @@ namespace Service::AM::Applets { | |||
| 15 | 15 | ||
| 16 | constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1}; | 16 | constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1}; |
| 17 | 17 | ||
| 18 | ProfileSelect::ProfileSelect() = default; | 18 | ProfileSelect::ProfileSelect(const Core::Frontend::ProfileSelectApplet& frontend) |
| 19 | : frontend(frontend) {} | ||
| 20 | |||
| 19 | ProfileSelect::~ProfileSelect() = default; | 21 | ProfileSelect::~ProfileSelect() = default; |
| 20 | 22 | ||
| 21 | void ProfileSelect::Initialize() { | 23 | void ProfileSelect::Initialize() { |
| @@ -51,8 +53,6 @@ void ProfileSelect::Execute() { | |||
| 51 | return; | 53 | return; |
| 52 | } | 54 | } |
| 53 | 55 | ||
| 54 | const auto& frontend{Core::System::GetInstance().GetProfileSelector()}; | ||
| 55 | |||
| 56 | frontend.SelectProfile([this](std::optional<Account::UUID> uuid) { SelectionComplete(uuid); }); | 56 | frontend.SelectProfile([this](std::optional<Account::UUID> uuid) { SelectionComplete(uuid); }); |
| 57 | } | 57 | } |
| 58 | 58 | ||
diff --git a/src/core/hle/service/am/applets/profile_select.h b/src/core/hle/service/am/applets/profile_select.h index 787485f22..a2ac6cf50 100644 --- a/src/core/hle/service/am/applets/profile_select.h +++ b/src/core/hle/service/am/applets/profile_select.h | |||
| @@ -28,7 +28,7 @@ static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has inco | |||
| 28 | 28 | ||
| 29 | class ProfileSelect final : public Applet { | 29 | class ProfileSelect final : public Applet { |
| 30 | public: | 30 | public: |
| 31 | ProfileSelect(); | 31 | explicit ProfileSelect(const Core::Frontend::ProfileSelectApplet& frontend); |
| 32 | ~ProfileSelect() override; | 32 | ~ProfileSelect() override; |
| 33 | 33 | ||
| 34 | void Initialize() override; | 34 | void Initialize() override; |
| @@ -41,6 +41,8 @@ public: | |||
| 41 | void SelectionComplete(std::optional<Account::UUID> uuid); | 41 | void SelectionComplete(std::optional<Account::UUID> uuid); |
| 42 | 42 | ||
| 43 | private: | 43 | private: |
| 44 | const Core::Frontend::ProfileSelectApplet& frontend; | ||
| 45 | |||
| 44 | UserSelectionConfig config; | 46 | UserSelectionConfig config; |
| 45 | bool complete = false; | 47 | bool complete = false; |
| 46 | ResultCode status = RESULT_SUCCESS; | 48 | ResultCode status = RESULT_SUCCESS; |
diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp index 8c5bd6059..e197990f7 100644 --- a/src/core/hle/service/am/applets/software_keyboard.cpp +++ b/src/core/hle/service/am/applets/software_keyboard.cpp | |||
| @@ -39,7 +39,8 @@ static Core::Frontend::SoftwareKeyboardParameters ConvertToFrontendParameters( | |||
| 39 | return params; | 39 | return params; |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | SoftwareKeyboard::SoftwareKeyboard() = default; | 42 | SoftwareKeyboard::SoftwareKeyboard(const Core::Frontend::SoftwareKeyboardApplet& frontend) |
| 43 | : frontend(frontend) {} | ||
| 43 | 44 | ||
| 44 | SoftwareKeyboard::~SoftwareKeyboard() = default; | 45 | SoftwareKeyboard::~SoftwareKeyboard() = default; |
| 45 | 46 | ||
| @@ -90,8 +91,6 @@ void SoftwareKeyboard::ExecuteInteractive() { | |||
| 90 | if (status == INTERACTIVE_STATUS_OK) { | 91 | if (status == INTERACTIVE_STATUS_OK) { |
| 91 | complete = true; | 92 | complete = true; |
| 92 | } else { | 93 | } else { |
| 93 | const auto& frontend{Core::System::GetInstance().GetSoftwareKeyboard()}; | ||
| 94 | |||
| 95 | std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string; | 94 | std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string; |
| 96 | std::memcpy(string.data(), data.data() + 4, string.size() * 2); | 95 | std::memcpy(string.data(), data.data() + 4, string.size() * 2); |
| 97 | frontend.SendTextCheckDialog( | 96 | frontend.SendTextCheckDialog( |
| @@ -106,8 +105,6 @@ void SoftwareKeyboard::Execute() { | |||
| 106 | return; | 105 | return; |
| 107 | } | 106 | } |
| 108 | 107 | ||
| 109 | const auto& frontend{Core::System::GetInstance().GetSoftwareKeyboard()}; | ||
| 110 | |||
| 111 | const auto parameters = ConvertToFrontendParameters(config, initial_text); | 108 | const auto parameters = ConvertToFrontendParameters(config, initial_text); |
| 112 | 109 | ||
| 113 | frontend.RequestText([this](std::optional<std::u16string> text) { WriteText(text); }, | 110 | frontend.RequestText([this](std::optional<std::u16string> text) { WriteText(text); }, |
diff --git a/src/core/hle/service/am/applets/software_keyboard.h b/src/core/hle/service/am/applets/software_keyboard.h index b93a30d28..0fbc43e51 100644 --- a/src/core/hle/service/am/applets/software_keyboard.h +++ b/src/core/hle/service/am/applets/software_keyboard.h | |||
| @@ -55,7 +55,7 @@ static_assert(sizeof(KeyboardConfig) == 0x3E0, "KeyboardConfig has incorrect siz | |||
| 55 | 55 | ||
| 56 | class SoftwareKeyboard final : public Applet { | 56 | class SoftwareKeyboard final : public Applet { |
| 57 | public: | 57 | public: |
| 58 | SoftwareKeyboard(); | 58 | explicit SoftwareKeyboard(const Core::Frontend::SoftwareKeyboardApplet& frontend); |
| 59 | ~SoftwareKeyboard() override; | 59 | ~SoftwareKeyboard() override; |
| 60 | 60 | ||
| 61 | void Initialize() override; | 61 | void Initialize() override; |
| @@ -68,6 +68,8 @@ public: | |||
| 68 | void WriteText(std::optional<std::u16string> text); | 68 | void WriteText(std::optional<std::u16string> text); |
| 69 | 69 | ||
| 70 | private: | 70 | private: |
| 71 | const Core::Frontend::SoftwareKeyboardApplet& frontend; | ||
| 72 | |||
| 71 | KeyboardConfig config; | 73 | KeyboardConfig config; |
| 72 | std::u16string initial_text; | 74 | std::u16string initial_text; |
| 73 | bool complete = false; | 75 | bool complete = false; |
diff --git a/src/core/hle/service/am/applets/stub_applet.h b/src/core/hle/service/am/applets/stub_applet.h deleted file mode 100644 index 7d8dc968d..000000000 --- a/src/core/hle/service/am/applets/stub_applet.h +++ /dev/null | |||
| @@ -1,24 +0,0 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/am/applets/applets.h" | ||
| 8 | |||
| 9 | namespace Service::AM::Applets { | ||
| 10 | |||
| 11 | class StubApplet final : public Applet { | ||
| 12 | public: | ||
| 13 | StubApplet(); | ||
| 14 | ~StubApplet() override; | ||
| 15 | |||
| 16 | void Initialize() override; | ||
| 17 | |||
| 18 | bool TransactionComplete() const override; | ||
| 19 | ResultCode GetStatus() const override; | ||
| 20 | void ExecuteInteractive() override; | ||
| 21 | void Execute() override; | ||
| 22 | }; | ||
| 23 | |||
| 24 | } // namespace Service::AM::Applets | ||
diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp index 7e17df98a..7878f5136 100644 --- a/src/core/hle/service/am/applets/web_browser.cpp +++ b/src/core/hle/service/am/applets/web_browser.cpp | |||
| @@ -95,7 +95,7 @@ static FileSys::VirtualFile GetManualRomFS() { | |||
| 95 | return nullptr; | 95 | return nullptr; |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | WebBrowser::WebBrowser() = default; | 98 | WebBrowser::WebBrowser(Core::Frontend::WebBrowserApplet& frontend) : frontend(frontend) {} |
| 99 | 99 | ||
| 100 | WebBrowser::~WebBrowser() = default; | 100 | WebBrowser::~WebBrowser() = default; |
| 101 | 101 | ||
| @@ -152,8 +152,6 @@ void WebBrowser::Execute() { | |||
| 152 | return; | 152 | return; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | auto& frontend{Core::System::GetInstance().GetWebBrowser()}; | ||
| 156 | |||
| 157 | frontend.OpenPage(filename, [this] { UnpackRomFS(); }, [this] { Finalize(); }); | 155 | frontend.OpenPage(filename, [this] { UnpackRomFS(); }, [this] { Finalize(); }); |
| 158 | } | 156 | } |
| 159 | 157 | ||
diff --git a/src/core/hle/service/am/applets/web_browser.h b/src/core/hle/service/am/applets/web_browser.h index b9e228fac..7e0f34c7d 100644 --- a/src/core/hle/service/am/applets/web_browser.h +++ b/src/core/hle/service/am/applets/web_browser.h | |||
| @@ -12,7 +12,7 @@ namespace Service::AM::Applets { | |||
| 12 | 12 | ||
| 13 | class WebBrowser final : public Applet { | 13 | class WebBrowser final : public Applet { |
| 14 | public: | 14 | public: |
| 15 | WebBrowser(); | 15 | WebBrowser(Core::Frontend::WebBrowserApplet& frontend); |
| 16 | ~WebBrowser() override; | 16 | ~WebBrowser() override; |
| 17 | 17 | ||
| 18 | void Initialize() override; | 18 | void Initialize() override; |
| @@ -32,6 +32,8 @@ public: | |||
| 32 | void Finalize(); | 32 | void Finalize(); |
| 33 | 33 | ||
| 34 | private: | 34 | private: |
| 35 | Core::Frontend::WebBrowserApplet& frontend; | ||
| 36 | |||
| 35 | bool complete = false; | 37 | bool complete = false; |
| 36 | bool unpacked = false; | 38 | bool unpacked = false; |
| 37 | ResultCode status = RESULT_SUCCESS; | 39 | ResultCode status = RESULT_SUCCESS; |
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 31b65c04c..5138bd9a3 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt | |||
| @@ -7,6 +7,8 @@ add_executable(yuzu | |||
| 7 | Info.plist | 7 | Info.plist |
| 8 | about_dialog.cpp | 8 | about_dialog.cpp |
| 9 | about_dialog.h | 9 | about_dialog.h |
| 10 | applets/error.cpp | ||
| 11 | applets/error.h | ||
| 10 | applets/profile_select.cpp | 12 | applets/profile_select.cpp |
| 11 | applets/profile_select.h | 13 | applets/profile_select.h |
| 12 | applets/software_keyboard.cpp | 14 | applets/software_keyboard.cpp |
diff --git a/src/yuzu/applets/error.cpp b/src/yuzu/applets/error.cpp new file mode 100644 index 000000000..1fb2fe277 --- /dev/null +++ b/src/yuzu/applets/error.cpp | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | // Copyright 2019 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <QDateTime> | ||
| 6 | #include "core/hle/lock.h" | ||
| 7 | #include "yuzu/applets/error.h" | ||
| 8 | #include "yuzu/main.h" | ||
| 9 | |||
| 10 | QtErrorDisplay::QtErrorDisplay(GMainWindow& parent) { | ||
| 11 | connect(this, &QtErrorDisplay::MainWindowDisplayError, &parent, | ||
| 12 | &GMainWindow::ErrorDisplayDisplayError, Qt::QueuedConnection); | ||
| 13 | connect(&parent, &GMainWindow::ErrorDisplayFinished, this, | ||
| 14 | &QtErrorDisplay::MainWindowFinishedError, Qt::DirectConnection); | ||
| 15 | } | ||
| 16 | |||
| 17 | QtErrorDisplay::~QtErrorDisplay() = default; | ||
| 18 | |||
| 19 | void QtErrorDisplay::ShowError(ResultCode error, std::function<void()> finished) const { | ||
| 20 | this->callback = std::move(finished); | ||
| 21 | emit MainWindowDisplayError( | ||
| 22 | tr("An error has occured.\nPlease try again or contact the developer of the " | ||
| 23 | "software.\n\nError Code: %1-%2 (0x%3)") | ||
| 24 | .arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0')) | ||
| 25 | .arg(error.description, 4, 10, QChar::fromLatin1('0')) | ||
| 26 | .arg(error.raw, 8, 16, QChar::fromLatin1('0'))); | ||
| 27 | } | ||
| 28 | |||
| 29 | void QtErrorDisplay::ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, | ||
| 30 | std::function<void()> finished) const { | ||
| 31 | this->callback = std::move(finished); | ||
| 32 | emit MainWindowDisplayError( | ||
| 33 | tr("An error occured on %1 at %2.\nPlease try again or contact the " | ||
| 34 | "developer of the software.\n\nError Code: %3-%4 (0x%5)") | ||
| 35 | .arg(QDateTime::fromSecsSinceEpoch(time.count()).toString("dddd, MMMM d, yyyy")) | ||
| 36 | .arg(QDateTime::fromSecsSinceEpoch(time.count()).toString("h:mm:ss A")) | ||
| 37 | .arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0')) | ||
| 38 | .arg(error.description, 4, 10, QChar::fromLatin1('0')) | ||
| 39 | .arg(error.raw, 8, 16, QChar::fromLatin1('0'))); | ||
| 40 | } | ||
| 41 | |||
| 42 | void QtErrorDisplay::ShowCustomErrorText(ResultCode error, std::string dialog_text, | ||
| 43 | std::string fullscreen_text, | ||
| 44 | std::function<void()> finished) const { | ||
| 45 | this->callback = std::move(finished); | ||
| 46 | emit MainWindowDisplayError( | ||
| 47 | tr("An error has occured.\nError Code: %1-%2 (0x%3)\n\n%4\n\n%5") | ||
| 48 | .arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0')) | ||
| 49 | .arg(error.description, 4, 10, QChar::fromLatin1('0')) | ||
| 50 | .arg(error.raw, 8, 16, QChar::fromLatin1('0')) | ||
| 51 | .arg(QString::fromStdString(dialog_text)) | ||
| 52 | .arg(QString::fromStdString(fullscreen_text))); | ||
| 53 | } | ||
| 54 | |||
| 55 | void QtErrorDisplay::MainWindowFinishedError() { | ||
| 56 | // Acquire the HLE mutex | ||
| 57 | std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock); | ||
| 58 | callback(); | ||
| 59 | } | ||
diff --git a/src/yuzu/applets/error.h b/src/yuzu/applets/error.h new file mode 100644 index 000000000..b0932d895 --- /dev/null +++ b/src/yuzu/applets/error.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | // Copyright 2019 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <QObject> | ||
| 8 | |||
| 9 | #include "core/frontend/applets/error.h" | ||
| 10 | |||
| 11 | class GMainWindow; | ||
| 12 | |||
| 13 | class QtErrorDisplay final : public QObject, public Core::Frontend::ErrorApplet { | ||
| 14 | Q_OBJECT | ||
| 15 | |||
| 16 | public: | ||
| 17 | explicit QtErrorDisplay(GMainWindow& parent); | ||
| 18 | ~QtErrorDisplay() override; | ||
| 19 | |||
| 20 | void ShowError(ResultCode error, std::function<void()> finished) const override; | ||
| 21 | void ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, | ||
| 22 | std::function<void()> finished) const override; | ||
| 23 | void ShowCustomErrorText(ResultCode error, std::string dialog_text, std::string fullscreen_text, | ||
| 24 | std::function<void()> finished) const override; | ||
| 25 | |||
| 26 | signals: | ||
| 27 | void MainWindowDisplayError(QString error) const; | ||
| 28 | |||
| 29 | private: | ||
| 30 | void MainWindowFinishedError(); | ||
| 31 | |||
| 32 | mutable std::function<void()> callback; | ||
| 33 | }; | ||
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index bdee44b04..e33e3aaaf 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <thread> | 8 | #include <thread> |
| 9 | 9 | ||
| 10 | // VFS includes must be before glad as they will conflict with Windows file api, which uses defines. | 10 | // VFS includes must be before glad as they will conflict with Windows file api, which uses defines. |
| 11 | #include "applets/error.h" | ||
| 11 | #include "applets/profile_select.h" | 12 | #include "applets/profile_select.h" |
| 12 | #include "applets/software_keyboard.h" | 13 | #include "applets/software_keyboard.h" |
| 13 | #include "applets/web_browser.h" | 14 | #include "applets/web_browser.h" |
| @@ -15,6 +16,7 @@ | |||
| 15 | #include "configuration/configure_per_general.h" | 16 | #include "configuration/configure_per_general.h" |
| 16 | #include "core/file_sys/vfs.h" | 17 | #include "core/file_sys/vfs.h" |
| 17 | #include "core/file_sys/vfs_real.h" | 18 | #include "core/file_sys/vfs_real.h" |
| 19 | #include "core/frontend/applets/general_frontend.h" | ||
| 18 | #include "core/frontend/scope_acquire_window_context.h" | 20 | #include "core/frontend/scope_acquire_window_context.h" |
| 19 | #include "core/hle/service/acc/profile_manager.h" | 21 | #include "core/hle/service/acc/profile_manager.h" |
| 20 | #include "core/hle/service/am/applets/applets.h" | 22 | #include "core/hle/service/am/applets/applets.h" |
| @@ -795,9 +797,13 @@ bool GMainWindow::LoadROM(const QString& filename) { | |||
| 795 | 797 | ||
| 796 | system.SetGPUDebugContext(debug_context); | 798 | system.SetGPUDebugContext(debug_context); |
| 797 | 799 | ||
| 798 | system.SetProfileSelector(std::make_unique<QtProfileSelector>(*this)); | 800 | system.SetAppletFrontendSet({ |
| 799 | system.SetSoftwareKeyboard(std::make_unique<QtSoftwareKeyboard>(*this)); | 801 | std::make_unique<QtErrorDisplay>(*this), |
| 800 | system.SetWebBrowser(std::make_unique<QtWebBrowser>(*this)); | 802 | nullptr, |
| 803 | std::make_unique<QtProfileSelector>(*this), | ||
| 804 | std::make_unique<QtSoftwareKeyboard>(*this), | ||
| 805 | std::make_unique<QtWebBrowser>(*this), | ||
| 806 | }); | ||
| 801 | 807 | ||
| 802 | const Core::System::ResultStatus result{system.Load(*render_window, filename.toStdString())}; | 808 | const Core::System::ResultStatus result{system.Load(*render_window, filename.toStdString())}; |
| 803 | 809 | ||
| @@ -1583,6 +1589,11 @@ void GMainWindow::OnLoadComplete() { | |||
| 1583 | loading_screen->OnLoadComplete(); | 1589 | loading_screen->OnLoadComplete(); |
| 1584 | } | 1590 | } |
| 1585 | 1591 | ||
| 1592 | void GMainWindow::ErrorDisplayDisplayError(QString body) { | ||
| 1593 | QMessageBox::critical(this, tr("Error Display"), body); | ||
| 1594 | emit ErrorDisplayFinished(); | ||
| 1595 | } | ||
| 1596 | |||
| 1586 | void GMainWindow::OnMenuReportCompatibility() { | 1597 | void GMainWindow::OnMenuReportCompatibility() { |
| 1587 | if (!Settings::values.yuzu_token.empty() && !Settings::values.yuzu_username.empty()) { | 1598 | if (!Settings::values.yuzu_token.empty() && !Settings::values.yuzu_username.empty()) { |
| 1588 | CompatDB compatdb{this}; | 1599 | CompatDB compatdb{this}; |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index ce5045819..fb2a193cb 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -102,6 +102,8 @@ signals: | |||
| 102 | // Signal that tells widgets to update icons to use the current theme | 102 | // Signal that tells widgets to update icons to use the current theme |
| 103 | void UpdateThemedIcons(); | 103 | void UpdateThemedIcons(); |
| 104 | 104 | ||
| 105 | void ErrorDisplayFinished(); | ||
| 106 | |||
| 105 | void ProfileSelectorFinishedSelection(std::optional<Service::Account::UUID> uuid); | 107 | void ProfileSelectorFinishedSelection(std::optional<Service::Account::UUID> uuid); |
| 106 | void SoftwareKeyboardFinishedText(std::optional<std::u16string> text); | 108 | void SoftwareKeyboardFinishedText(std::optional<std::u16string> text); |
| 107 | void SoftwareKeyboardFinishedCheckDialog(); | 109 | void SoftwareKeyboardFinishedCheckDialog(); |
| @@ -111,6 +113,7 @@ signals: | |||
| 111 | 113 | ||
| 112 | public slots: | 114 | public slots: |
| 113 | void OnLoadComplete(); | 115 | void OnLoadComplete(); |
| 116 | void ErrorDisplayDisplayError(QString body); | ||
| 114 | void ProfileSelectorSelectProfile(); | 117 | void ProfileSelectorSelectProfile(); |
| 115 | void SoftwareKeyboardGetText(const Core::Frontend::SoftwareKeyboardParameters& parameters); | 118 | void SoftwareKeyboardGetText(const Core::Frontend::SoftwareKeyboardParameters& parameters); |
| 116 | void SoftwareKeyboardInvokeCheckDialog(std::u16string error_message); | 119 | void SoftwareKeyboardInvokeCheckDialog(std::u16string error_message); |