early-access version 3985
This commit is contained in:
		| @@ -1,7 +1,7 @@ | ||||
| yuzu emulator early access | ||||
| ============= | ||||
|  | ||||
| This is the source code for early-access 3984. | ||||
| This is the source code for early-access 3985. | ||||
|  | ||||
| ## Legal Notice | ||||
|  | ||||
|   | ||||
							
								
								
									
										5
									
								
								dist/languages/.tx/config
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								dist/languages/.tx/config
									
									
									
									
										vendored
									
									
								
							| @@ -6,3 +6,8 @@ file_filter = <lang>.ts | ||||
| source_file = en.ts | ||||
| source_lang = en | ||||
| type = QT | ||||
|  | ||||
| [o:yuzu-emulator:p:yuzu:r:yuzu-android] | ||||
| file_filter = ../../src/android/app/src/main/res/values-<lang>/strings.xml | ||||
| source_file = ../../src/android/app/src/main/res/values/strings.xml | ||||
| type = ANDROID | ||||
|   | ||||
| @@ -219,6 +219,13 @@ enum class NpadIdType : u32 { | ||||
|     Invalid = 0xFFFFFFFF, | ||||
| }; | ||||
|  | ||||
| enum class NpadInterfaceType : u8 { | ||||
|     Bluetooth = 1, | ||||
|     Rail = 2, | ||||
|     Usb = 3, | ||||
|     Embedded = 4, | ||||
| }; | ||||
|  | ||||
| // This is nn::hid::NpadStyleIndex | ||||
| enum class NpadStyleIndex : u8 { | ||||
|     None = 0, | ||||
|   | ||||
| @@ -13,6 +13,7 @@ | ||||
| #include "core/file_sys/patch_manager.h" | ||||
| #include "core/file_sys/registered_cache.h" | ||||
| #include "core/file_sys/savedata_factory.h" | ||||
| #include "core/hid/hid_types.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/kernel/k_transfer_memory.h" | ||||
| #include "core/hle/result.h" | ||||
| @@ -21,6 +22,7 @@ | ||||
| #include "core/hle/service/am/applet_ae.h" | ||||
| #include "core/hle/service/am/applet_oe.h" | ||||
| #include "core/hle/service/am/applets/applet_cabinet.h" | ||||
| #include "core/hle/service/am/applets/applet_controller.h" | ||||
| #include "core/hle/service/am/applets/applet_mii_edit_types.h" | ||||
| #include "core/hle/service/am/applets/applet_profile_select.h" | ||||
| #include "core/hle/service/am/applets/applet_software_keyboard_types.h" | ||||
| @@ -35,6 +37,7 @@ | ||||
| #include "core/hle/service/caps/caps_su.h" | ||||
| #include "core/hle/service/caps/caps_types.h" | ||||
| #include "core/hle/service/filesystem/filesystem.h" | ||||
| #include "core/hle/service/hid/controllers/npad.h" | ||||
| #include "core/hle/service/ipc_helpers.h" | ||||
| #include "core/hle/service/ns/ns.h" | ||||
| #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h" | ||||
| @@ -73,7 +76,7 @@ IWindowController::IWindowController(Core::System& system_) | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {0, nullptr, "CreateWindow"}, | ||||
|         {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"}, | ||||
|         {2, nullptr, "GetAppletResourceUserIdOfCallerApplet"}, | ||||
|         {2, &IWindowController::GetAppletResourceUserIdOfCallerApplet, "GetAppletResourceUserIdOfCallerApplet"}, | ||||
|         {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"}, | ||||
|         {11, nullptr, "ReleaseForegroundRights"}, | ||||
|         {12, nullptr, "RejectToChangeIntoBackground"}, | ||||
| @@ -97,6 +100,16 @@ void IWindowController::GetAppletResourceUserId(HLERequestContext& ctx) { | ||||
|     rb.Push<u64>(process_id); | ||||
| } | ||||
|  | ||||
| void IWindowController::GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx) { | ||||
|     const u64 process_id = 0; | ||||
|  | ||||
|     LOG_WARNING(Service_AM, "(STUBBED) called"); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 4}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push<u64>(process_id); | ||||
| } | ||||
|  | ||||
| void IWindowController::AcquireForegroundRights(HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_AM, "(STUBBED) called"); | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
| @@ -1565,7 +1578,7 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_) | ||||
|         {6, nullptr, "GetPopInteractiveInDataEvent"}, | ||||
|         {10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"}, | ||||
|         {11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"}, | ||||
|         {12, nullptr, "GetMainAppletIdentityInfo"}, | ||||
|         {12, &ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo, "GetMainAppletIdentityInfo"}, | ||||
|         {13, nullptr, "CanUseApplicationCore"}, | ||||
|         {14, &ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo, "GetCallerAppletIdentityInfo"}, | ||||
|         {15, nullptr, "GetMainAppletApplicationControlProperty"}, | ||||
| @@ -1609,6 +1622,9 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_) | ||||
|     case Applets::AppletId::SoftwareKeyboard: | ||||
|         PushInShowSoftwareKeyboard(); | ||||
|         break; | ||||
|     case Applets::AppletId::Controller: | ||||
|         PushInShowController(); | ||||
|         break; | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
| @@ -1666,13 +1682,33 @@ void ILibraryAppletSelfAccessor::GetLibraryAppletInfo(HLERequestContext& ctx) { | ||||
|     rb.PushRaw(applet_info); | ||||
| } | ||||
|  | ||||
| void ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(HLERequestContext& ctx) { | ||||
|     struct AppletIdentityInfo { | ||||
|         Applets::AppletId applet_id; | ||||
|         INSERT_PADDING_BYTES(0x4); | ||||
|         u64 application_id; | ||||
|     }; | ||||
|     static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size."); | ||||
|  | ||||
|     LOG_WARNING(Service_AM, "(STUBBED) called"); | ||||
|  | ||||
|     const AppletIdentityInfo applet_info{ | ||||
|         .applet_id = Applets::AppletId::QLaunch, | ||||
|         .application_id = 0x0100000000001000ull, | ||||
|     }; | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 6}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushRaw(applet_info); | ||||
| } | ||||
|  | ||||
| void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) { | ||||
|     struct AppletIdentityInfo { | ||||
|         Applets::AppletId applet_id; | ||||
|         INSERT_PADDING_BYTES(0x4); | ||||
|         u64 application_id; | ||||
|     }; | ||||
|  | ||||
|     static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size."); | ||||
|     LOG_WARNING(Service_AM, "(STUBBED) called"); | ||||
|  | ||||
|     const AppletIdentityInfo applet_info{ | ||||
| @@ -1737,6 +1773,55 @@ void ILibraryAppletSelfAccessor::PushInShowAlbum() { | ||||
|     queue_data.emplace_back(std::move(settings_data)); | ||||
| } | ||||
|  | ||||
| void ILibraryAppletSelfAccessor::PushInShowController() { | ||||
|     const Applets::CommonArguments common_args = { | ||||
|         .arguments_version = Applets::CommonArgumentVersion::Version3, | ||||
|         .size = Applets::CommonArgumentSize::Version3, | ||||
|         .library_version = static_cast<u32>(Applets::ControllerAppletVersion::Version8), | ||||
|         .theme_color = Applets::ThemeColor::BasicBlack, | ||||
|         .play_startup_sound = true, | ||||
|         .system_tick = system.CoreTiming().GetClockTicks(), | ||||
|     }; | ||||
|  | ||||
|     Applets::ControllerSupportArgNew user_args = { | ||||
|         .header = {.player_count_min = 1, | ||||
|                    .player_count_max = 4, | ||||
|                    .enable_take_over_connection = true, | ||||
|                    .enable_left_justify = false, | ||||
|                    .enable_permit_joy_dual = true, | ||||
|                    .enable_single_mode = false, | ||||
|                    .enable_identification_color = false}, | ||||
|         .identification_colors = {}, | ||||
|         .enable_explain_text = false, | ||||
|         .explain_text = {}, | ||||
|     }; | ||||
|  | ||||
|     Applets::ControllerSupportArgPrivate private_args = { | ||||
|         .arg_private_size = sizeof(Applets::ControllerSupportArgPrivate), | ||||
|         .arg_size = sizeof(Applets::ControllerSupportArgNew), | ||||
|         .is_home_menu = true, | ||||
|         .flag_1 = true, | ||||
|         .mode = Applets::ControllerSupportMode::ShowControllerSupport, | ||||
|         .caller = Applets::ControllerSupportCaller:: | ||||
|             Application, // switchbrew: Always zero except with | ||||
|                          // ShowControllerFirmwareUpdateForSystem/ShowControllerKeyRemappingForSystem, | ||||
|                          // which sets this to the input param | ||||
|         .style_set = Core::HID::NpadStyleSet::None, | ||||
|         .joy_hold_type = 0, | ||||
|     }; | ||||
|     std::vector<u8> common_args_data(sizeof(common_args)); | ||||
|     std::vector<u8> private_args_data(sizeof(private_args)); | ||||
|     std::vector<u8> user_args_data(sizeof(user_args)); | ||||
|  | ||||
|     std::memcpy(common_args_data.data(), &common_args, sizeof(common_args)); | ||||
|     std::memcpy(private_args_data.data(), &private_args, sizeof(private_args)); | ||||
|     std::memcpy(user_args_data.data(), &user_args, sizeof(user_args)); | ||||
|  | ||||
|     queue_data.emplace_back(std::move(common_args_data)); | ||||
|     queue_data.emplace_back(std::move(private_args_data)); | ||||
|     queue_data.emplace_back(std::move(user_args_data)); | ||||
| } | ||||
|  | ||||
| void ILibraryAppletSelfAccessor::PushInShowCabinetData() { | ||||
|     const Applets::CommonArguments arguments{ | ||||
|         .arguments_version = Applets::CommonArgumentVersion::Version3, | ||||
|   | ||||
| @@ -87,6 +87,7 @@ public: | ||||
|  | ||||
| private: | ||||
|     void GetAppletResourceUserId(HLERequestContext& ctx); | ||||
|     void GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx); | ||||
|     void AcquireForegroundRights(HLERequestContext& ctx); | ||||
| }; | ||||
|  | ||||
| @@ -345,6 +346,7 @@ private: | ||||
|     void PopInData(HLERequestContext& ctx); | ||||
|     void PushOutData(HLERequestContext& ctx); | ||||
|     void GetLibraryAppletInfo(HLERequestContext& ctx); | ||||
|     void GetMainAppletIdentityInfo(HLERequestContext& ctx); | ||||
|     void ExitProcessAndReturn(HLERequestContext& ctx); | ||||
|     void GetCallerAppletIdentityInfo(HLERequestContext& ctx); | ||||
|     void GetDesirableKeyboardLayout(HLERequestContext& ctx); | ||||
| @@ -355,6 +357,7 @@ private: | ||||
|     void PushInShowCabinetData(); | ||||
|     void PushInShowMiiEditData(); | ||||
|     void PushInShowSoftwareKeyboard(); | ||||
|     void PushInShowController(); | ||||
|  | ||||
|     std::deque<std::vector<u8>> queue_data; | ||||
| }; | ||||
|   | ||||
| @@ -56,7 +56,7 @@ enum class ControllerSupportResult : u32 { | ||||
| struct ControllerSupportArgPrivate { | ||||
|     u32 arg_private_size{}; | ||||
|     u32 arg_size{}; | ||||
|     bool flag_0{}; | ||||
|     bool is_home_menu{}; | ||||
|     bool flag_1{}; | ||||
|     ControllerSupportMode mode{}; | ||||
|     ControllerSupportCaller caller{}; | ||||
|   | ||||
| @@ -127,7 +127,7 @@ public: | ||||
|  | ||||
| private: | ||||
|     void GetCore(HLERequestContext& ctx) { | ||||
|         LOG_DEBUG(Service_BTM, "called"); | ||||
|         LOG_WARNING(Service_BTM, "called"); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
| @@ -263,13 +263,13 @@ public: | ||||
|     explicit IBtmSystemCore(Core::System& system_) : ServiceFramework{system_, "IBtmSystemCore"} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, nullptr, "StartGamepadPairing"}, | ||||
|             {1, nullptr, "CancelGamepadPairing"}, | ||||
|             {0, &IBtmSystemCore::StartGamepadPairing, "StartGamepadPairing"}, | ||||
|             {1, &IBtmSystemCore::CancelGamepadPairing, "CancelGamepadPairing"}, | ||||
|             {2, nullptr, "ClearGamepadPairingDatabase"}, | ||||
|             {3, nullptr, "GetPairedGamepadCount"}, | ||||
|             {4, nullptr, "EnableRadio"}, | ||||
|             {5, nullptr, "DisableRadio"}, | ||||
|             {6, nullptr, "GetRadioOnOff"}, | ||||
|             {6, &IBtmSystemCore::IsRadioEnabled, "IsRadioEnabled"}, | ||||
|             {7, nullptr, "AcquireRadioEvent"}, | ||||
|             {8, nullptr, "AcquireGamepadPairingEvent"}, | ||||
|             {9, nullptr, "IsGamepadPairingStarted"}, | ||||
| @@ -280,18 +280,58 @@ public: | ||||
|             {14, nullptr, "AcquireAudioDeviceConnectionEvent"}, | ||||
|             {15, nullptr, "ConnectAudioDevice"}, | ||||
|             {16, nullptr, "IsConnectingAudioDevice"}, | ||||
|             {17, nullptr, "GetConnectedAudioDevices"}, | ||||
|             {17, &IBtmSystemCore::GetConnectedAudioDevices, "GetConnectedAudioDevices"}, | ||||
|             {18, nullptr, "DisconnectAudioDevice"}, | ||||
|             {19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"}, | ||||
|             {20, nullptr, "GetPairedAudioDevices"}, | ||||
|             {21, nullptr, "RemoveAudioDevicePairing"}, | ||||
|             {22, nullptr, "RequestAudioDeviceConnectionRejection"}, | ||||
|             {23, nullptr, "CancelAudioDeviceConnectionRejection"} | ||||
|             {22, &IBtmSystemCore::RequestAudioDeviceConnectionRejection, "RequestAudioDeviceConnectionRejection"}, | ||||
|             {23, &IBtmSystemCore::CancelAudioDeviceConnectionRejection, "CancelAudioDeviceConnectionRejection"} | ||||
|         }; | ||||
|         // clang-format on | ||||
|  | ||||
|         RegisterHandlers(functions); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     void IsRadioEnabled(HLERequestContext& ctx) { | ||||
|         LOG_DEBUG(Service_BTM, "(STUBBED) called"); // Spams a lot when controller applet is running | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 3}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.Push(true); | ||||
|     } | ||||
|  | ||||
|     void StartGamepadPairing(HLERequestContext& ctx) { | ||||
|         LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ResultSuccess); | ||||
|     } | ||||
|  | ||||
|     void CancelGamepadPairing(HLERequestContext& ctx) { | ||||
|         LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ResultSuccess); | ||||
|     } | ||||
|  | ||||
|     void CancelAudioDeviceConnectionRejection(HLERequestContext& ctx) { | ||||
|         LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ResultSuccess); | ||||
|     } | ||||
|  | ||||
|     void GetConnectedAudioDevices(HLERequestContext& ctx) { | ||||
|         LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||||
|         IPC::ResponseBuilder rb{ctx, 3}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.Push<u32>(0); | ||||
|     } | ||||
|  | ||||
|     void RequestAudioDeviceConnectionRejection(HLERequestContext& ctx) { | ||||
|         LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ResultSuccess); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| class BTM_SYS final : public ServiceFramework<BTM_SYS> { | ||||
| @@ -308,7 +348,7 @@ public: | ||||
|  | ||||
| private: | ||||
|     void GetCore(HLERequestContext& ctx) { | ||||
|         LOG_DEBUG(Service_BTM, "called"); | ||||
|         LOG_WARNING(Service_BTM, "called"); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|   | ||||
| @@ -32,7 +32,7 @@ public: | ||||
|             {10200, nullptr, "SendFriendRequestForApplication"}, | ||||
|             {10211, nullptr, "AddFacedFriendRequestForApplication"}, | ||||
|             {10400, &IFriendService::GetBlockedUserListIds, "GetBlockedUserListIds"}, | ||||
|             {10420, nullptr, "IsBlockedUserListCacheAvailable"}, | ||||
|             {10420, &IFriendService::CheckBlockedUserListAvailability, "CheckBlockedUserListAvailability"}, | ||||
|             {10421, nullptr, "EnsureBlockedUserListAvailable"}, | ||||
|             {10500, nullptr, "GetProfileList"}, | ||||
|             {10600, nullptr, "DeclareOpenOnlinePlaySession"}, | ||||
| @@ -206,6 +206,17 @@ private: | ||||
|         rb.Push(true); | ||||
|     } | ||||
|  | ||||
|     void CheckBlockedUserListAvailability(HLERequestContext& ctx) { | ||||
|         IPC::RequestParser rp{ctx}; | ||||
|         const auto uuid{rp.PopRaw<Common::UUID>()}; | ||||
|  | ||||
|         LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString()); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 3}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.Push(true); | ||||
|     } | ||||
|  | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     Kernel::KEvent* completion_event; | ||||
|   | ||||
| @@ -292,6 +292,7 @@ void NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { | ||||
|         controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::AllDevices, | ||||
|                                           Common::Input::PollingMode::Active); | ||||
|     } | ||||
|  | ||||
|     SignalStyleSetChangedEvent(npad_id); | ||||
|     WriteEmptyEntry(controller.shared_memory); | ||||
|     hid_core.SetLastActiveController(npad_id); | ||||
| @@ -1342,4 +1343,13 @@ const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties( | ||||
|     } | ||||
| } | ||||
|  | ||||
| NPad::AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) { | ||||
|     const auto& shared_memory = GetControllerFromNpadIdType(npad_id).shared_memory; | ||||
|  | ||||
|     return { | ||||
|         .ui_variant = 0, | ||||
|         .footer = shared_memory->applet_footer_type, | ||||
|     }; | ||||
| } | ||||
|  | ||||
| } // namespace Service::HID | ||||
|   | ||||
| @@ -74,6 +74,46 @@ public: | ||||
|         MaxActivationMode = 3, | ||||
|     }; | ||||
|  | ||||
|     // This is nn::hid::system::AppletFooterUiAttributesSet | ||||
|     struct AppletFooterUiAttributes { | ||||
|         INSERT_PADDING_BYTES(0x4); | ||||
|     }; | ||||
|  | ||||
|     // This is nn::hid::system::AppletFooterUiType | ||||
|     enum class AppletFooterUiType : u8 { | ||||
|         None = 0, | ||||
|         HandheldNone = 1, | ||||
|         HandheldJoyConLeftOnly = 2, | ||||
|         HandheldJoyConRightOnly = 3, | ||||
|         HandheldJoyConLeftJoyConRight = 4, | ||||
|         JoyDual = 5, | ||||
|         JoyDualLeftOnly = 6, | ||||
|         JoyDualRightOnly = 7, | ||||
|         JoyLeftHorizontal = 8, | ||||
|         JoyLeftVertical = 9, | ||||
|         JoyRightHorizontal = 10, | ||||
|         JoyRightVertical = 11, | ||||
|         SwitchProController = 12, | ||||
|         CompatibleProController = 13, | ||||
|         CompatibleJoyCon = 14, | ||||
|         LarkHvc1 = 15, | ||||
|         LarkHvc2 = 16, | ||||
|         LarkNesLeft = 17, | ||||
|         LarkNesRight = 18, | ||||
|         Lucia = 19, | ||||
|         Verification = 20, | ||||
|         Lagon = 21, | ||||
|     }; | ||||
|  | ||||
|     using AppletFooterUiVariant = u8; | ||||
|  | ||||
|     // This is "nn::hid::system::AppletDetailedUiType". | ||||
|     struct AppletDetailedUiType { | ||||
|         AppletFooterUiVariant ui_variant; | ||||
|         INSERT_PADDING_BYTES(0x2); | ||||
|         AppletFooterUiType footer; | ||||
|     }; | ||||
|     static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size"); | ||||
|     // This is nn::hid::NpadCommunicationMode | ||||
|     enum class NpadCommunicationMode : u64 { | ||||
|         Mode_5ms = 0, | ||||
| @@ -178,6 +218,8 @@ public: | ||||
|  | ||||
|     void ApplyNpadSystemCommonPolicy(); | ||||
|  | ||||
|     AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id); | ||||
|  | ||||
| private: | ||||
|     static constexpr std::size_t NPAD_COUNT = 10; | ||||
|  | ||||
| @@ -311,37 +353,6 @@ private: | ||||
|     static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18, | ||||
|                   "NfcXcdDeviceHandleStateImpl is an invalid size"); | ||||
|  | ||||
|     // This is nn::hid::system::AppletFooterUiAttributesSet | ||||
|     struct AppletFooterUiAttributes { | ||||
|         INSERT_PADDING_BYTES(0x4); | ||||
|     }; | ||||
|  | ||||
|     // This is nn::hid::system::AppletFooterUiType | ||||
|     enum class AppletFooterUiType : u8 { | ||||
|         None = 0, | ||||
|         HandheldNone = 1, | ||||
|         HandheldJoyConLeftOnly = 2, | ||||
|         HandheldJoyConRightOnly = 3, | ||||
|         HandheldJoyConLeftJoyConRight = 4, | ||||
|         JoyDual = 5, | ||||
|         JoyDualLeftOnly = 6, | ||||
|         JoyDualRightOnly = 7, | ||||
|         JoyLeftHorizontal = 8, | ||||
|         JoyLeftVertical = 9, | ||||
|         JoyRightHorizontal = 10, | ||||
|         JoyRightVertical = 11, | ||||
|         SwitchProController = 12, | ||||
|         CompatibleProController = 13, | ||||
|         CompatibleJoyCon = 14, | ||||
|         LarkHvc1 = 15, | ||||
|         LarkHvc2 = 16, | ||||
|         LarkNesLeft = 17, | ||||
|         LarkNesRight = 18, | ||||
|         Lucia = 19, | ||||
|         Verification = 20, | ||||
|         Lagon = 21, | ||||
|     }; | ||||
|  | ||||
|     // This is nn::hid::NpadLarkType | ||||
|     enum class NpadLarkType : u32 { | ||||
|         Invalid, | ||||
|   | ||||
| @@ -1203,8 +1203,8 @@ void IHidServer::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) { | ||||
|     auto controller = GetResourceManager()->GetNpad(); | ||||
|     controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NPad::NpadJoyAssignmentMode::Dual); | ||||
|  | ||||
|     LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, | ||||
|              parameters.applet_resource_user_id); | ||||
|     LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, | ||||
|               parameters.applet_resource_user_id); // Spams a lot when controller applet is open | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
|   | ||||
| @@ -36,24 +36,24 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour | ||||
|         {233, nullptr, "GetXcdHandleForNpadWithIrSensor"}, | ||||
|         {301, nullptr, "ActivateNpadSystem"}, | ||||
|         {303, &IHidSystemServer::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"}, | ||||
|         {304, nullptr, "EnableAssigningSingleOnSlSrPress"}, | ||||
|         {305, nullptr, "DisableAssigningSingleOnSlSrPress"}, | ||||
|         {304, &IHidSystemServer::EnableAssigningSingleOnSlSrPress, "EnableAssigningSingleOnSlSrPress"}, | ||||
|         {305, &IHidSystemServer::DisableAssigningSingleOnSlSrPress, "DisableAssigningSingleOnSlSrPress"}, | ||||
|         {306, &IHidSystemServer::GetLastActiveNpad, "GetLastActiveNpad"}, | ||||
|         {307, nullptr, "GetNpadSystemExtStyle"}, | ||||
|         {308, nullptr, "ApplyNpadSystemCommonPolicyFull"}, | ||||
|         {309, nullptr, "GetNpadFullKeyGripColor"}, | ||||
|         {310, nullptr, "GetMaskedSupportedNpadStyleSet"}, | ||||
|         {308, &IHidSystemServer::ApplyNpadSystemCommonPolicyFull, "ApplyNpadSystemCommonPolicyFull"}, | ||||
|         {309, &IHidSystemServer::GetNpadFullKeyGripColor, "GetNpadFullKeyGripColor"}, | ||||
|         {310, &IHidSystemServer::GetMaskedSupportedNpadStyleSet, "GetMaskedSupportedNpadStyleSet"}, | ||||
|         {311, nullptr, "SetNpadPlayerLedBlinkingDevice"}, | ||||
|         {312, nullptr, "SetSupportedNpadStyleSetAll"}, | ||||
|         {312, &IHidSystemServer::SetSupportedNpadStyleSetAll, "SetSupportedNpadStyleSetAll"}, | ||||
|         {313, nullptr, "GetNpadCaptureButtonAssignment"}, | ||||
|         {314, nullptr, "GetAppletFooterUiType"}, | ||||
|         {315, nullptr, "GetAppletDetailedUiType"}, | ||||
|         {316, nullptr, "GetNpadInterfaceType"}, | ||||
|         {317, nullptr, "GetNpadLeftRightInterfaceType"}, | ||||
|         {318, nullptr, "HasBattery"}, | ||||
|         {319, nullptr, "HasLeftRightBattery"}, | ||||
|         {315, &IHidSystemServer::GetAppletDetailedUiType, "GetAppletDetailedUiType"}, | ||||
|         {316, &IHidSystemServer::GetNpadInterfaceType, "GetNpadInterfaceType"}, | ||||
|         {317, &IHidSystemServer::GetNpadLeftRightInterfaceType, "GetNpadLeftRightInterfaceType"}, | ||||
|         {318, &IHidSystemServer::HasBattery, "HasBattery"}, | ||||
|         {319, &IHidSystemServer::HasLeftRightBattery, "HasLeftRightBattery"}, | ||||
|         {321, &IHidSystemServer::GetUniquePadsFromNpad, "GetUniquePadsFromNpad"}, | ||||
|         {322, nullptr, "GetIrSensorState"}, | ||||
|         {322, &IHidSystemServer::GetIrSensorState, "GetIrSensorState"}, | ||||
|         {323, nullptr, "GetXcdHandleForNpadWithIrSensor"}, | ||||
|         {324, nullptr, "GetUniquePadButtonSet"}, | ||||
|         {325, nullptr, "GetUniquePadColor"}, | ||||
| @@ -85,15 +85,15 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour | ||||
|         {541, nullptr, "GetPlayReportControllerUsages"}, | ||||
|         {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"}, | ||||
|         {543, nullptr, "GetRegisteredDevicesOld"}, | ||||
|         {544, nullptr, "AcquireConnectionTriggerTimeoutEvent"}, | ||||
|         {544, &IHidSystemServer::AcquireConnectionTriggerTimeoutEvent, "AcquireConnectionTriggerTimeoutEvent"}, | ||||
|         {545, nullptr, "SendConnectionTrigger"}, | ||||
|         {546, nullptr, "AcquireDeviceRegisteredEventForControllerSupport"}, | ||||
|         {546, &IHidSystemServer::AcquireDeviceRegisteredEventForControllerSupport, "AcquireDeviceRegisteredEventForControllerSupport"}, | ||||
|         {547, nullptr, "GetAllowedBluetoothLinksCount"}, | ||||
|         {548, nullptr, "GetRegisteredDevices"}, | ||||
|         {548, &IHidSystemServer::GetRegisteredDevices, "GetRegisteredDevices"}, | ||||
|         {549, nullptr, "GetConnectableRegisteredDevices"}, | ||||
|         {700, nullptr, "ActivateUniquePad"}, | ||||
|         {702, nullptr, "AcquireUniquePadConnectionEventHandle"}, | ||||
|         {703, nullptr, "GetUniquePadIds"}, | ||||
|         {702, &IHidSystemServer::AcquireUniquePadConnectionEventHandle, "AcquireUniquePadConnectionEventHandle"}, | ||||
|         {703, &IHidSystemServer::GetUniquePadIds, "GetUniquePadIds"}, | ||||
|         {751, &IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle, "AcquireJoyDetachOnBluetoothOffEventHandle"}, | ||||
|         {800, nullptr, "ListSixAxisSensorHandles"}, | ||||
|         {801, nullptr, "IsSixAxisSensorUserCalibrationSupported"}, | ||||
| @@ -123,10 +123,10 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour | ||||
|         {850, &IHidSystemServer::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"}, | ||||
|         {851, nullptr, "EnableUsbFullKeyController"}, | ||||
|         {852, nullptr, "IsUsbConnected"}, | ||||
|         {870, nullptr, "IsHandheldButtonPressedOnConsoleMode"}, | ||||
|         {870, &IHidSystemServer::IsHandheldButtonPressedOnConsoleMode, "IsHandheldButtonPressedOnConsoleMode"}, | ||||
|         {900, nullptr, "ActivateInputDetector"}, | ||||
|         {901, nullptr, "NotifyInputDetector"}, | ||||
|         {1000, nullptr, "InitializeFirmwareUpdate"}, | ||||
|         {1000, &IHidSystemServer::InitializeFirmwareUpdate, "InitializeFirmwareUpdate"}, | ||||
|         {1001, nullptr, "GetFirmwareVersion"}, | ||||
|         {1002, nullptr, "GetAvailableFirmwareVersion"}, | ||||
|         {1003, nullptr, "IsFirmwareUpdateAvailable"}, | ||||
| @@ -149,6 +149,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour | ||||
|         {1132, nullptr, "CheckUsbFirmwareUpdateRequired"}, | ||||
|         {1133, nullptr, "StartUsbFirmwareUpdate"}, | ||||
|         {1134, nullptr, "GetUsbFirmwareUpdateState"}, | ||||
|         {1135, &IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory, "InitializeUsbFirmwareUpdateWithoutMemory"}, | ||||
|         {1150, nullptr, "SetTouchScreenMagnification"}, | ||||
|         {1151, nullptr, "GetTouchScreenFirmwareVersion"}, | ||||
|         {1152, nullptr, "SetTouchScreenDefaultConfiguration"}, | ||||
| @@ -220,11 +221,20 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour | ||||
|  | ||||
|     RegisterHandlers(functions); | ||||
|  | ||||
|     joy_detach_event = service_context.CreateEvent("HidSys::JoyDetachEvent"); | ||||
|     joy_detach_event = service_context.CreateEvent("IHidSystemServer::JoyDetachEvent"); | ||||
|     acquire_device_registered_event = | ||||
|         service_context.CreateEvent("IHidSystemServer::AcquireDeviceRegisteredEvent"); | ||||
|     acquire_connection_trigger_timeout_event = | ||||
|         service_context.CreateEvent("IHidSystemServer::AcquireConnectionTriggerTimeoutEvent"); | ||||
|     unique_pad_connection_event = | ||||
|         service_context.CreateEvent("IHidSystemServer::AcquireUniquePadConnectionEventHandle"); | ||||
| } | ||||
|  | ||||
| IHidSystemServer::~IHidSystemServer() { | ||||
|     service_context.CloseEvent(joy_detach_event); | ||||
|     service_context.CloseEvent(acquire_device_registered_event); | ||||
|     service_context.CloseEvent(acquire_connection_trigger_timeout_event); | ||||
|     service_context.CloseEvent(unique_pad_connection_event); | ||||
| }; | ||||
|  | ||||
| void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) { | ||||
| @@ -236,29 +246,231 @@ void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) { | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_HID, "(STUBBED) called"); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_HID, "(STUBBED) called"); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::GetLastActiveNpad(HLERequestContext& ctx) { | ||||
|     LOG_DEBUG(Service_HID, "(STUBBED) called"); | ||||
|     LOG_DEBUG(Service_HID, "(STUBBED) called"); // Spams a lot when controller applet is running | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushEnum(system.HIDCore().GetLastActiveController()); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_HID, "called"); | ||||
|  | ||||
|     GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy(); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::GetNpadFullKeyGripColor(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||||
|  | ||||
|     LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}", | ||||
|               npad_id_type); // Spams a lot when controller applet is running | ||||
|  | ||||
|     Core::HID::NpadColor left_color{}; | ||||
|     Core::HID::NpadColor right_color{}; | ||||
|     // TODO: Get colors from Npad | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 4}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushRaw(left_color); | ||||
|     rb.PushRaw(right_color); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|  | ||||
|     LOG_INFO(Service_HID, "(STUBBED) called"); | ||||
|  | ||||
|     Core::HID::NpadStyleSet supported_styleset = | ||||
|         GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw; | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushEnum(supported_styleset); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::SetSupportedNpadStyleSetAll(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|  | ||||
|     LOG_INFO(Service_HID, "(STUBBED) called"); | ||||
|  | ||||
|     Core::HID::NpadStyleSet supported_styleset = | ||||
|         GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw; | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushEnum(supported_styleset); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||||
|  | ||||
|     LOG_DEBUG(Service_HID, "called, npad_id_type={}", | ||||
|               npad_id_type); // Spams a lot when controller applet is running | ||||
|  | ||||
|     const NPad::AppletDetailedUiType detailed_ui_type = | ||||
|         GetResourceManager()->GetNpad()->GetAppletDetailedUiType(npad_id_type); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushRaw(detailed_ui_type); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::GetNpadInterfaceType(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||||
|  | ||||
|     LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}", | ||||
|               npad_id_type); // Spams a lot when controller applet is running | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::GetNpadLeftRightInterfaceType(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||||
|  | ||||
|     LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}", | ||||
|               npad_id_type); // Spams a lot when controller applet is running | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 4}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth); | ||||
|     rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::HasBattery(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||||
|  | ||||
|     LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}", | ||||
|               npad_id_type); // Spams a lot when controller applet is running | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push(false); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::HasLeftRightBattery(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||||
|  | ||||
|     LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}", | ||||
|               npad_id_type); // Spams a lot when controller applet is running | ||||
|  | ||||
|     struct LeftRightBattery { | ||||
|         bool left; | ||||
|         bool right; | ||||
|     }; | ||||
|  | ||||
|     LeftRightBattery left_right_battery{ | ||||
|         .left = false, | ||||
|         .right = false, | ||||
|     }; | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushRaw(left_right_battery); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::GetUniquePadsFromNpad(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||||
|  | ||||
|     LOG_WARNING(Service_HID, "(STUBBED) called, npad_id_type={}", npad_id_type); | ||||
|     LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}", | ||||
|               npad_id_type); // Spams a lot when controller applet is running | ||||
|  | ||||
|     const std::vector<Core::HID::UniquePadId> unique_pads{}; | ||||
|  | ||||
|     ctx.WriteBuffer(unique_pads); | ||||
|     if (!unique_pads.empty()) { | ||||
|         ctx.WriteBuffer(unique_pads); | ||||
|     } | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push(static_cast<u32>(unique_pads.size())); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::GetIrSensorState(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|  | ||||
|     LOG_WARNING(Service_HID, "(STUBBED) called"); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx) { | ||||
|     LOG_INFO(Service_AM, "(STUBBED) called"); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushCopyObjects(acquire_device_registered_event->GetReadableEvent()); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx) { | ||||
|     LOG_INFO(Service_HID, "(STUBBED) called"); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushCopyObjects(acquire_device_registered_event->GetReadableEvent()); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::GetRegisteredDevices(HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_HID, "(STUBBED) called"); | ||||
|  | ||||
|     struct RegisterData { | ||||
|         std::array<u8, 0x68> data; | ||||
|     }; | ||||
|     static_assert(sizeof(RegisterData) == 0x68, "RegisterData is an invalid size"); | ||||
|     std::vector<RegisterData> registered_devices{}; | ||||
|  | ||||
|     if (!registered_devices.empty()) { | ||||
|         ctx.WriteBuffer(registered_devices); | ||||
|     } | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 4}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push<u64>(registered_devices.size()); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::AcquireUniquePadConnectionEventHandle(HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_HID, "(STUBBED) called"); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.PushCopyObjects(unique_pad_connection_event->GetReadableEvent()); | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::GetUniquePadIds(HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_HID, "(STUBBED) called"); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 4}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push<u64>(0); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx) { | ||||
|     LOG_INFO(Service_AM, "called"); | ||||
|  | ||||
| @@ -277,6 +489,31 @@ void IHidSystemServer::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) { | ||||
|     rb.Push(is_enabled); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx) { | ||||
|     const bool button_pressed = false; | ||||
|  | ||||
|     LOG_DEBUG(Service_HID, "(STUBBED) called, is_enabled={}", | ||||
|               button_pressed); // Spams a lot when controller applet is open | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push(button_pressed); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::InitializeFirmwareUpdate(HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_HID, "(STUBBED) called"); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_HID, "(STUBBED) called"); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::GetTouchScreenDefaultConfiguration(HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_HID, "(STUBBED) called"); | ||||
|  | ||||
|   | ||||
| @@ -24,15 +24,38 @@ public: | ||||
|  | ||||
| private: | ||||
|     void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx); | ||||
|     void EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx); | ||||
|     void DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx); | ||||
|     void GetLastActiveNpad(HLERequestContext& ctx); | ||||
|     void ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx); | ||||
|     void GetNpadFullKeyGripColor(HLERequestContext& ctx); | ||||
|     void GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx); | ||||
|     void SetSupportedNpadStyleSetAll(HLERequestContext& ctx); | ||||
|     void GetAppletDetailedUiType(HLERequestContext& ctx); | ||||
|     void GetNpadInterfaceType(HLERequestContext& ctx); | ||||
|     void GetNpadLeftRightInterfaceType(HLERequestContext& ctx); | ||||
|     void HasBattery(HLERequestContext& ctx); | ||||
|     void HasLeftRightBattery(HLERequestContext& ctx); | ||||
|     void GetUniquePadsFromNpad(HLERequestContext& ctx); | ||||
|     void GetIrSensorState(HLERequestContext& ctx); | ||||
|     void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx); | ||||
|     void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx); | ||||
|     void GetRegisteredDevices(HLERequestContext& ctx); | ||||
|     void AcquireUniquePadConnectionEventHandle(HLERequestContext& ctx); | ||||
|     void GetUniquePadIds(HLERequestContext& ctx); | ||||
|     void AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx); | ||||
|     void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx); | ||||
|     void IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx); | ||||
|     void InitializeFirmwareUpdate(HLERequestContext& ctx); | ||||
|     void InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx); | ||||
|     void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx); | ||||
|  | ||||
|     std::shared_ptr<ResourceManager> GetResourceManager(); | ||||
|  | ||||
|     Kernel::KEvent* acquire_connection_trigger_timeout_event; | ||||
|     Kernel::KEvent* acquire_device_registered_event; | ||||
|     Kernel::KEvent* joy_detach_event; | ||||
|     Kernel::KEvent* unique_pad_connection_event; | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|     std::shared_ptr<ResourceManager> resource_manager; | ||||
| }; | ||||
|   | ||||
| @@ -115,12 +115,20 @@ public: | ||||
|             {400, nullptr, "InitializeSystem"}, | ||||
|             {401, nullptr, "FinalizeSystem"}, | ||||
|             {402, nullptr, "SetOperationMode"}, | ||||
|             {403, nullptr, "InitializeSystem2"}, | ||||
|             {403, &ISystemLocalCommunicationService::InitializeSystem2, "InitializeSystem2"}, | ||||
|         }; | ||||
|         // clang-format on | ||||
|  | ||||
|         RegisterHandlers(functions); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     void InitializeSystem2(HLERequestContext& ctx) { | ||||
|         LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ResultSuccess); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| class IUserLocalCommunicationService final | ||||
|   | ||||
| @@ -431,8 +431,7 @@ void SET_SYS::GetAutoUpdateEnableFlag(HLERequestContext& ctx) { | ||||
| void SET_SYS::GetBatteryPercentageFlag(HLERequestContext& ctx) { | ||||
|     u8 battery_percentage_flag{1}; | ||||
|  | ||||
|     LOG_WARNING(Service_SET, "(STUBBED) called, battery_percentage_flag={}", | ||||
|                 battery_percentage_flag); | ||||
|     LOG_DEBUG(Service_SET, "(STUBBED) called, battery_percentage_flag={}", battery_percentage_flag); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
| @@ -492,6 +491,29 @@ void SET_SYS::GetChineseTraditionalInputMethod(HLERequestContext& ctx) { | ||||
|     rb.PushEnum(ChineseTraditionalInputMethod::Unknown0); | ||||
| } | ||||
|  | ||||
| void SET_SYS::GetHomeMenuScheme(HLERequestContext& ctx) { | ||||
|     LOG_DEBUG(Service_SET, "(STUBBED) called"); | ||||
|  | ||||
|     const HomeMenuScheme default_color = { | ||||
|         .main = 0xFF323232, | ||||
|         .back = 0xFF323232, | ||||
|         .sub = 0xFFFFFFFF, | ||||
|         .bezel = 0xFFFFFFFF, | ||||
|         .extra = 0xFF000000, | ||||
|     }; | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 7}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushRaw(default_color); | ||||
| } | ||||
|  | ||||
| void SET_SYS::GetHomeMenuSchemeModel(HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_SET, "(STUBBED) called"); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push(0); | ||||
| } | ||||
| void SET_SYS::GetFieldTestingFlag(HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_SET, "(STUBBED) called"); | ||||
|  | ||||
| @@ -674,7 +696,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { | ||||
|         {171, nullptr, "SetChineseTraditionalInputMethod"}, | ||||
|         {172, nullptr, "GetPtmCycleCountReliability"}, | ||||
|         {173, nullptr, "SetPtmCycleCountReliability"}, | ||||
|         {174, nullptr, "GetHomeMenuScheme"}, | ||||
|         {174, &SET_SYS::GetHomeMenuScheme, "GetHomeMenuScheme"}, | ||||
|         {175, nullptr, "GetThemeSettings"}, | ||||
|         {176, nullptr, "SetThemeSettings"}, | ||||
|         {177, nullptr, "GetThemeKey"}, | ||||
| @@ -685,7 +707,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { | ||||
|         {182, nullptr, "SetT"}, | ||||
|         {183, nullptr, "GetPlatformRegion"}, | ||||
|         {184, nullptr, "SetPlatformRegion"}, | ||||
|         {185, nullptr, "GetHomeMenuSchemeModel"}, | ||||
|         {185, &SET_SYS::GetHomeMenuSchemeModel, "GetHomeMenuSchemeModel"}, | ||||
|         {186, nullptr, "GetMemoryUsageRateFlag"}, | ||||
|         {187, nullptr, "GetTouchScreenMode"}, | ||||
|         {188, nullptr, "SetTouchScreenMode"}, | ||||
|   | ||||
| @@ -269,6 +269,16 @@ private: | ||||
|     }; | ||||
|     static_assert(sizeof(EulaVersion) == 0x30, "EulaVersion is incorrect size"); | ||||
|  | ||||
|     /// This is nn::settings::system::HomeMenuScheme | ||||
|     struct HomeMenuScheme { | ||||
|         u32 main; | ||||
|         u32 back; | ||||
|         u32 sub; | ||||
|         u32 bezel; | ||||
|         u32 extra; | ||||
|     }; | ||||
|     static_assert(sizeof(HomeMenuScheme) == 0x14, "HomeMenuScheme is incorrect size"); | ||||
|  | ||||
|     void SetLanguageCode(HLERequestContext& ctx); | ||||
|     void GetFirmwareVersion(HLERequestContext& ctx); | ||||
|     void GetFirmwareVersion2(HLERequestContext& ctx); | ||||
| @@ -305,6 +315,8 @@ private: | ||||
|     void GetKeyboardLayout(HLERequestContext& ctx); | ||||
|     void GetChineseTraditionalInputMethod(HLERequestContext& ctx); | ||||
|     void GetFieldTestingFlag(HLERequestContext& ctx); | ||||
|     void GetHomeMenuScheme(HLERequestContext& ctx); | ||||
|     void GetHomeMenuSchemeModel(HLERequestContext& ctx); | ||||
|  | ||||
|     AccountSettings account_settings{ | ||||
|         .flags = {}, | ||||
|   | ||||
| @@ -1574,9 +1574,6 @@ std::optional<typename TextureCache<P>::BlitImages> TextureCache<P>::GetBlitImag | ||||
|                 if (!src_id && !dst_id) { | ||||
|                     return std::nullopt; | ||||
|                 } | ||||
|                 if (src_id && True(slot_images[src_id].flags & ImageFlagBits::GpuModified)) { | ||||
|                     break; | ||||
|                 } | ||||
|                 if (dst_id && True(slot_images[dst_id].flags & ImageFlagBits::GpuModified)) { | ||||
|                     break; | ||||
|                 } | ||||
|   | ||||
| @@ -252,6 +252,7 @@ file(GLOB_RECURSE THEMES ${PROJECT_SOURCE_DIR}/dist/qt_themes/*) | ||||
| if (ENABLE_QT_TRANSLATION) | ||||
|     set(YUZU_QT_LANGUAGES "${PROJECT_SOURCE_DIR}/dist/languages" CACHE PATH "Path to the translation bundle for the Qt frontend") | ||||
|     option(GENERATE_QT_TRANSLATION "Generate en.ts as the translation source file" OFF) | ||||
|     option(WORKAROUND_BROKEN_LUPDATE "Run lupdate directly through CMake if Qt's convenience wrappers don't work" OFF) | ||||
|  | ||||
|     # Update source TS file if enabled | ||||
|     if (GENERATE_QT_TRANSLATION) | ||||
| @@ -259,19 +260,51 @@ if (ENABLE_QT_TRANSLATION) | ||||
|         # these calls to qt_create_translation also creates a rule to generate en.qm which conflicts with providing english plurals | ||||
|         # so we have to set a OUTPUT_LOCATION so that we don't have multiple rules to generate en.qm | ||||
|         set_source_files_properties(${YUZU_QT_LANGUAGES}/en.ts PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/translations") | ||||
|         qt_create_translation(QM_FILES | ||||
|             ${SRCS} | ||||
|             ${UIS} | ||||
|             ${YUZU_QT_LANGUAGES}/en.ts | ||||
|         OPTIONS | ||||
|             -source-language en_US | ||||
|             -target-language en_US | ||||
|         ) | ||||
|         if (WORKAROUND_BROKEN_LUPDATE) | ||||
|             add_custom_command(OUTPUT ${YUZU_QT_LANGUAGES}/en.ts | ||||
|                 COMMAND lupdate | ||||
|                     -source-language en_US | ||||
|                     -target-language en_US | ||||
|                     ${SRCS} | ||||
|                     ${UIS} | ||||
|                     -ts ${YUZU_QT_LANGUAGES}/en.ts | ||||
|                 DEPENDS | ||||
|                     ${SRCS} | ||||
|                     ${UIS} | ||||
|                 WORKING_DIRECTORY | ||||
|                     ${CMAKE_CURRENT_SOURCE_DIR} | ||||
|             ) | ||||
|         else() | ||||
|             qt_create_translation(QM_FILES | ||||
|                 ${SRCS} | ||||
|                 ${UIS} | ||||
|                 ${YUZU_QT_LANGUAGES}/en.ts | ||||
|             OPTIONS | ||||
|                 -source-language en_US | ||||
|                 -target-language en_US | ||||
|             ) | ||||
|         endif() | ||||
|  | ||||
|         # Generate plurals into dist/english_plurals/generated_en.ts so it can be used to revise dist/english_plurals/en.ts | ||||
|         set(GENERATED_PLURALS_FILE ${PROJECT_SOURCE_DIR}/dist/english_plurals/generated_en.ts) | ||||
|         set_source_files_properties(${GENERATED_PLURALS_FILE} PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/plurals") | ||||
|         qt_create_translation(QM_FILES ${SRCS} ${UIS} ${GENERATED_PLURALS_FILE} OPTIONS -pluralonly -source-language en_US -target-language en_US) | ||||
|         if (WORKAROUND_BROKEN_LUPDATE) | ||||
|             add_custom_command(OUTPUT ${GENERATED_PLURALS_FILE} | ||||
|                 COMMAND lupdate | ||||
|                     -source-language en_US | ||||
|                     -target-language en_US | ||||
|                     ${SRCS} | ||||
|                     ${UIS} | ||||
|                     -ts ${GENERATED_PLURALS_FILE} | ||||
|                 DEPENDS | ||||
|                     ${SRCS} | ||||
|                     ${UIS} | ||||
|                 WORKING_DIRECTORY | ||||
|                     ${CMAKE_CURRENT_SOURCE_DIR} | ||||
|             ) | ||||
|         else() | ||||
|             qt_create_translation(QM_FILES ${SRCS} ${UIS} ${GENERATED_PLURALS_FILE} OPTIONS -pluralonly -source-language en_US -target-language en_US) | ||||
|         endif() | ||||
|  | ||||
|         add_custom_target(translation ALL DEPENDS ${YUZU_QT_LANGUAGES}/en.ts ${GENERATED_PLURALS_FILE}) | ||||
|     endif() | ||||
|   | ||||
| @@ -1,17 +1,18 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #include "common/time_zone.h" | ||||
| #include "yuzu/configuration/shared_translation.h" | ||||
|  | ||||
| #include <map> | ||||
| #include <memory> | ||||
| #include <tuple> | ||||
| #include <utility> | ||||
| #include <QCoreApplication> | ||||
| #include <QWidget> | ||||
| #include "common/settings.h" | ||||
| #include "common/settings_enums.h" | ||||
| #include "common/settings_setting.h" | ||||
| #include "common/time_zone.h" | ||||
| #include "yuzu/uisettings.h" | ||||
|  | ||||
| namespace ConfigurationShared { | ||||
| @@ -21,123 +22,135 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) { | ||||
|     const auto& tr = [parent](const char* text) -> QString { return parent->tr(text); }; | ||||
|  | ||||
| #define INSERT(SETTINGS, ID, NAME, TOOLTIP)                                                        \ | ||||
|     translations->insert(std::pair{SETTINGS::values.ID.Id(), std::pair{tr((NAME)), tr((TOOLTIP))}}) | ||||
|     translations->insert(std::pair{SETTINGS::values.ID.Id(), std::pair{(NAME), (TOOLTIP)}}) | ||||
|  | ||||
|     // A setting can be ignored by giving it a blank name | ||||
|  | ||||
|     // Audio | ||||
|     INSERT(Settings, sink_id, "Output Engine:", ""); | ||||
|     INSERT(Settings, audio_output_device_id, "Output Device:", ""); | ||||
|     INSERT(Settings, audio_input_device_id, "Input Device:", ""); | ||||
|     INSERT(Settings, audio_muted, "Mute audio", ""); | ||||
|     INSERT(Settings, volume, "Volume:", ""); | ||||
|     INSERT(Settings, dump_audio_commands, "", ""); | ||||
|     INSERT(UISettings, mute_when_in_background, "Mute audio when in background", ""); | ||||
|     INSERT(Settings, sink_id, tr("Output Engine:"), QStringLiteral()); | ||||
|     INSERT(Settings, audio_output_device_id, tr("Output Device:"), QStringLiteral()); | ||||
|     INSERT(Settings, audio_input_device_id, tr("Input Device:"), QStringLiteral()); | ||||
|     INSERT(Settings, audio_muted, tr("Mute audio"), QStringLiteral()); | ||||
|     INSERT(Settings, volume, tr("Volume:"), QStringLiteral()); | ||||
|     INSERT(Settings, dump_audio_commands, QStringLiteral(), QStringLiteral()); | ||||
|     INSERT(UISettings, mute_when_in_background, tr("Mute audio when in background"), | ||||
|            QStringLiteral()); | ||||
|  | ||||
|     // Core | ||||
|     INSERT(Settings, use_multi_core, "Multicore CPU Emulation", ""); | ||||
|     INSERT(Settings, memory_layout_mode, "Memory Layout", ""); | ||||
|     INSERT(Settings, use_speed_limit, "", ""); | ||||
|     INSERT(Settings, speed_limit, "Limit Speed Percent", ""); | ||||
|     INSERT(Settings, use_multi_core, tr("Multicore CPU Emulation"), QStringLiteral()); | ||||
|     INSERT(Settings, memory_layout_mode, tr("Memory Layout"), QStringLiteral()); | ||||
|     INSERT(Settings, use_speed_limit, QStringLiteral(), QStringLiteral()); | ||||
|     INSERT(Settings, speed_limit, tr("Limit Speed Percent"), QStringLiteral()); | ||||
|  | ||||
|     // Cpu | ||||
|     INSERT(Settings, cpu_accuracy, "Accuracy:", ""); | ||||
|     INSERT(Settings, cpu_accuracy, tr("Accuracy:"), QStringLiteral()); | ||||
|  | ||||
|     // Cpu Debug | ||||
|  | ||||
|     // Cpu Unsafe | ||||
|     INSERT(Settings, cpuopt_unsafe_unfuse_fma, | ||||
|            "Unfuse FMA (improve performance on CPUs without FMA)", | ||||
|            "This option improves speed by reducing accuracy of fused-multiply-add instructions on " | ||||
|            "CPUs without native FMA support."); | ||||
|     INSERT(Settings, cpuopt_unsafe_reduce_fp_error, "Faster FRSQRTE and FRECPE", | ||||
|            "This option improves the speed of some approximate floating-point functions by using " | ||||
|            "less accurate native approximations."); | ||||
|     INSERT(Settings, cpuopt_unsafe_ignore_standard_fpcr, "Faster ASIMD instructions (32 bits only)", | ||||
|            "This option improves the speed of 32 bits ASIMD floating-point functions by running " | ||||
|            "with incorrect rounding modes."); | ||||
|     INSERT(Settings, cpuopt_unsafe_inaccurate_nan, "Inaccurate NaN handling", | ||||
|            "This option improves speed by removing NaN checking. Please note this also reduces " | ||||
|            "accuracy of certain floating-point instructions."); | ||||
|     INSERT( | ||||
|         Settings, cpuopt_unsafe_fastmem_check, "Disable address space checks", | ||||
|         "This option improves speed by eliminating a safety check before every memory read/write " | ||||
|         "in guest. Disabling it may allow a game to read/write the emulator's memory."); | ||||
|     INSERT(Settings, cpuopt_unsafe_ignore_global_monitor, "Ignore global monitor", | ||||
|            "This option improves speed by relying only on the semantics of cmpxchg to ensure " | ||||
|         Settings, cpuopt_unsafe_unfuse_fma, | ||||
|         tr("Unfuse FMA (improve performance on CPUs without FMA)"), | ||||
|         tr("This option improves speed by reducing accuracy of fused-multiply-add instructions on " | ||||
|            "CPUs without native FMA support.")); | ||||
|     INSERT( | ||||
|         Settings, cpuopt_unsafe_reduce_fp_error, tr("Faster FRSQRTE and FRECPE"), | ||||
|         tr("This option improves the speed of some approximate floating-point functions by using " | ||||
|            "less accurate native approximations.")); | ||||
|     INSERT(Settings, cpuopt_unsafe_ignore_standard_fpcr, | ||||
|            tr("Faster ASIMD instructions (32 bits only)"), | ||||
|            tr("This option improves the speed of 32 bits ASIMD floating-point functions by running " | ||||
|               "with incorrect rounding modes.")); | ||||
|     INSERT(Settings, cpuopt_unsafe_inaccurate_nan, tr("Inaccurate NaN handling"), | ||||
|            tr("This option improves speed by removing NaN checking. Please note this also reduces " | ||||
|               "accuracy of certain floating-point instructions.")); | ||||
|     INSERT(Settings, cpuopt_unsafe_fastmem_check, tr("Disable address space checks"), | ||||
|            tr("This option improves speed by eliminating a safety check before every memory " | ||||
|               "read/write " | ||||
|               "in guest. Disabling it may allow a game to read/write the emulator's memory.")); | ||||
|     INSERT( | ||||
|         Settings, cpuopt_unsafe_ignore_global_monitor, tr("Ignore global monitor"), | ||||
|         tr("This option improves speed by relying only on the semantics of cmpxchg to ensure " | ||||
|            "safety of exclusive access instructions. Please note this may result in deadlocks and " | ||||
|            "other race conditions."); | ||||
|            "other race conditions.")); | ||||
|  | ||||
|     // Renderer | ||||
|     INSERT(Settings, renderer_backend, "API:", ""); | ||||
|     INSERT(Settings, vulkan_device, "Device:", ""); | ||||
|     INSERT(Settings, shader_backend, "Shader Backend:", ""); | ||||
|     INSERT(Settings, resolution_setup, "Resolution:", ""); | ||||
|     INSERT(Settings, scaling_filter, "Window Adapting Filter:", ""); | ||||
|     INSERT(Settings, fsr_sharpening_slider, "FSR Sharpness:", ""); | ||||
|     INSERT(Settings, anti_aliasing, "Anti-Aliasing Method:", ""); | ||||
|     INSERT(Settings, fullscreen_mode, "Fullscreen Mode:", ""); | ||||
|     INSERT(Settings, aspect_ratio, "Aspect Ratio:", ""); | ||||
|     INSERT(Settings, use_disk_shader_cache, "Use disk pipeline cache", ""); | ||||
|     INSERT(Settings, use_asynchronous_gpu_emulation, "Use asynchronous GPU emulation", ""); | ||||
|     INSERT(Settings, nvdec_emulation, "NVDEC emulation:", ""); | ||||
|     INSERT(Settings, accelerate_astc, "ASTC Decoding Method:", ""); | ||||
|     INSERT(Settings, astc_recompression, "ASTC Recompression Method:", ""); | ||||
|     INSERT(Settings, vsync_mode, "VSync Mode:", | ||||
|            "FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen " | ||||
|     INSERT(Settings, renderer_backend, tr("API:"), QStringLiteral()); | ||||
|     INSERT(Settings, vulkan_device, tr("Device:"), QStringLiteral()); | ||||
|     INSERT(Settings, shader_backend, tr("Shader Backend:"), QStringLiteral()); | ||||
|     INSERT(Settings, resolution_setup, tr("Resolution:"), QStringLiteral()); | ||||
|     INSERT(Settings, scaling_filter, tr("Window Adapting Filter:"), QStringLiteral()); | ||||
|     INSERT(Settings, fsr_sharpening_slider, tr("FSR Sharpness:"), QStringLiteral()); | ||||
|     INSERT(Settings, anti_aliasing, tr("Anti-Aliasing Method:"), QStringLiteral()); | ||||
|     INSERT(Settings, fullscreen_mode, tr("Fullscreen Mode:"), QStringLiteral()); | ||||
|     INSERT(Settings, aspect_ratio, tr("Aspect Ratio:"), QStringLiteral()); | ||||
|     INSERT(Settings, use_disk_shader_cache, tr("Use disk pipeline cache"), QStringLiteral()); | ||||
|     INSERT(Settings, use_asynchronous_gpu_emulation, tr("Use asynchronous GPU emulation"), | ||||
|            QStringLiteral()); | ||||
|     INSERT(Settings, nvdec_emulation, tr("NVDEC emulation:"), QStringLiteral()); | ||||
|     INSERT(Settings, accelerate_astc, tr("ASTC Decoding Method:"), QStringLiteral()); | ||||
|     INSERT(Settings, astc_recompression, tr("ASTC Recompression Method:"), QStringLiteral()); | ||||
|     INSERT( | ||||
|         Settings, vsync_mode, tr("VSync Mode:"), | ||||
|         tr("FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen " | ||||
|            "refresh rate.\nFIFO Relaxed is similar to FIFO but allows tearing as it recovers from " | ||||
|            "a slow down.\nMailbox can have lower latency than FIFO and does not tear but may drop " | ||||
|            "frames.\nImmediate (no synchronization) just presents whatever is available and can " | ||||
|            "exhibit tearing."); | ||||
|     INSERT(Settings, bg_red, "", ""); | ||||
|     INSERT(Settings, bg_green, "", ""); | ||||
|     INSERT(Settings, bg_blue, "", ""); | ||||
|            "exhibit tearing.")); | ||||
|     INSERT(Settings, bg_red, QStringLiteral(), QStringLiteral()); | ||||
|     INSERT(Settings, bg_green, QStringLiteral(), QStringLiteral()); | ||||
|     INSERT(Settings, bg_blue, QStringLiteral(), QStringLiteral()); | ||||
|  | ||||
|     // Renderer (Advanced Graphics) | ||||
|     INSERT(Settings, async_presentation, "Enable asynchronous presentation (Vulkan only)", ""); | ||||
|     INSERT(Settings, renderer_force_max_clock, "Force maximum clocks (Vulkan only)", | ||||
|            "Runs work in the background while waiting for graphics commands to keep the GPU from " | ||||
|            "lowering its clock speed."); | ||||
|     INSERT(Settings, max_anisotropy, "Anisotropic Filtering:", ""); | ||||
|     INSERT(Settings, gpu_accuracy, "Accuracy Level:", ""); | ||||
|     INSERT(Settings, use_asynchronous_shaders, "Use asynchronous shader building (Hack)", | ||||
|            "Enables asynchronous shader compilation, which may reduce shader stutter. This feature " | ||||
|            "is experimental."); | ||||
|     INSERT(Settings, use_fast_gpu_time, "Use Fast GPU Time (Hack)", | ||||
|            "Enables Fast GPU Time. This option will force most games to run at their highest " | ||||
|            "native resolution."); | ||||
|     INSERT(Settings, use_vulkan_driver_pipeline_cache, "Use Vulkan pipeline cache", | ||||
|            "Enables GPU vendor-specific pipeline cache. This option can improve shader loading " | ||||
|            "time significantly in cases where the Vulkan driver does not store pipeline cache " | ||||
|            "files internally."); | ||||
|     INSERT(Settings, enable_compute_pipelines, "Enable Compute Pipelines (Intel Vulkan Only)", | ||||
|            "Enable compute pipelines, required by some games.\nThis setting only exists for Intel " | ||||
|     INSERT(Settings, async_presentation, tr("Enable asynchronous presentation (Vulkan only)"), | ||||
|            QStringLiteral()); | ||||
|     INSERT( | ||||
|         Settings, renderer_force_max_clock, tr("Force maximum clocks (Vulkan only)"), | ||||
|         tr("Runs work in the background while waiting for graphics commands to keep the GPU from " | ||||
|            "lowering its clock speed.")); | ||||
|     INSERT(Settings, max_anisotropy, tr("Anisotropic Filtering:"), QStringLiteral()); | ||||
|     INSERT(Settings, gpu_accuracy, tr("Accuracy Level:"), QStringLiteral()); | ||||
|     INSERT( | ||||
|         Settings, use_asynchronous_shaders, tr("Use asynchronous shader building (Hack)"), | ||||
|         tr("Enables asynchronous shader compilation, which may reduce shader stutter. This feature " | ||||
|            "is experimental.")); | ||||
|     INSERT(Settings, use_fast_gpu_time, tr("Use Fast GPU Time (Hack)"), | ||||
|            tr("Enables Fast GPU Time. This option will force most games to run at their highest " | ||||
|               "native resolution.")); | ||||
|     INSERT(Settings, use_vulkan_driver_pipeline_cache, tr("Use Vulkan pipeline cache"), | ||||
|            tr("Enables GPU vendor-specific pipeline cache. This option can improve shader loading " | ||||
|               "time significantly in cases where the Vulkan driver does not store pipeline cache " | ||||
|               "files internally.")); | ||||
|     INSERT( | ||||
|         Settings, enable_compute_pipelines, tr("Enable Compute Pipelines (Intel Vulkan Only)"), | ||||
|         tr("Enable compute pipelines, required by some games.\nThis setting only exists for Intel " | ||||
|            "proprietary drivers, and may crash if enabled.\nCompute pipelines are always enabled " | ||||
|            "on all other drivers."); | ||||
|     INSERT(Settings, use_reactive_flushing, "Enable Reactive Flushing", | ||||
|            "Uses reactive flushing instead of predictive flushing, allowing more accurate memory " | ||||
|            "syncing."); | ||||
|     INSERT(Settings, use_video_framerate, "Sync to framerate of video playback", | ||||
|            "Run the game at normal speed during video playback, even when the framerate is " | ||||
|            "unlocked."); | ||||
|     INSERT(Settings, barrier_feedback_loops, "Barrier feedback loops", | ||||
|            "Improves rendering of transparency effects in specific games."); | ||||
|            "on all other drivers.")); | ||||
|     INSERT( | ||||
|         Settings, use_reactive_flushing, tr("Enable Reactive Flushing"), | ||||
|         tr("Uses reactive flushing instead of predictive flushing, allowing more accurate memory " | ||||
|            "syncing.")); | ||||
|     INSERT(Settings, use_video_framerate, tr("Sync to framerate of video playback"), | ||||
|            tr("Run the game at normal speed during video playback, even when the framerate is " | ||||
|               "unlocked.")); | ||||
|     INSERT(Settings, barrier_feedback_loops, tr("Barrier feedback loops"), | ||||
|            tr("Improves rendering of transparency effects in specific games.")); | ||||
|  | ||||
|     // Renderer (Debug) | ||||
|  | ||||
|     // System | ||||
|     INSERT(Settings, rng_seed, "RNG Seed", ""); | ||||
|     INSERT(Settings, rng_seed_enabled, "", ""); | ||||
|     INSERT(Settings, device_name, "Device Name", ""); | ||||
|     INSERT(Settings, custom_rtc, "Custom RTC", ""); | ||||
|     INSERT(Settings, custom_rtc_enabled, "", ""); | ||||
|     INSERT(Settings, language_index, | ||||
|            "Language:", "Note: this can be overridden when region setting is auto-select"); | ||||
|     INSERT(Settings, region_index, "Region:", ""); | ||||
|     INSERT(Settings, time_zone_index, "Time Zone:", ""); | ||||
|     INSERT(Settings, sound_index, "Sound Output Mode:", ""); | ||||
|     INSERT(Settings, use_docked_mode, "Console Mode:", ""); | ||||
|     INSERT(Settings, current_user, "", ""); | ||||
|     INSERT(Settings, rng_seed, tr("RNG Seed"), QStringLiteral()); | ||||
|     INSERT(Settings, rng_seed_enabled, QStringLiteral(), QStringLiteral()); | ||||
|     INSERT(Settings, device_name, tr("Device Name"), QStringLiteral()); | ||||
|     INSERT(Settings, custom_rtc, tr("Custom RTC"), QStringLiteral()); | ||||
|     INSERT(Settings, custom_rtc_enabled, QStringLiteral(), QStringLiteral()); | ||||
|     INSERT(Settings, language_index, tr("Language:"), | ||||
|            tr("Note: this can be overridden when region setting is auto-select")); | ||||
|     INSERT(Settings, region_index, tr("Region:"), QStringLiteral()); | ||||
|     INSERT(Settings, time_zone_index, tr("Time Zone:"), QStringLiteral()); | ||||
|     INSERT(Settings, sound_index, tr("Sound Output Mode:"), QStringLiteral()); | ||||
|     INSERT(Settings, use_docked_mode, tr("Console Mode:"), QStringLiteral()); | ||||
|     INSERT(Settings, current_user, QStringLiteral(), QStringLiteral()); | ||||
|  | ||||
|     // Controls | ||||
|  | ||||
| @@ -154,11 +167,14 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) { | ||||
|     // Ui | ||||
|  | ||||
|     // Ui General | ||||
|     INSERT(UISettings, select_user_on_boot, "Prompt for user on game boot", ""); | ||||
|     INSERT(UISettings, pause_when_in_background, "Pause emulation when in background", ""); | ||||
|     INSERT(UISettings, confirm_before_stopping, "Confirm before stopping emulation", ""); | ||||
|     INSERT(UISettings, hide_mouse, "Hide mouse on inactivity", ""); | ||||
|     INSERT(UISettings, controller_applet_disabled, "Disable controller applet", ""); | ||||
|     INSERT(UISettings, select_user_on_boot, tr("Prompt for user on game boot"), QStringLiteral()); | ||||
|     INSERT(UISettings, pause_when_in_background, tr("Pause emulation when in background"), | ||||
|            QStringLiteral()); | ||||
|     INSERT(UISettings, confirm_before_stopping, tr("Confirm before stopping emulation"), | ||||
|            QStringLiteral()); | ||||
|     INSERT(UISettings, hide_mouse, tr("Hide mouse on inactivity"), QStringLiteral()); | ||||
|     INSERT(UISettings, controller_applet_disabled, tr("Disable controller applet"), | ||||
|            QStringLiteral()); | ||||
|  | ||||
|     // Ui Debugging | ||||
|  | ||||
| @@ -178,140 +194,141 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) { | ||||
|         return parent->tr(text, context); | ||||
|     }; | ||||
|  | ||||
| #define PAIR(ENUM, VALUE, TRANSLATION)                                                             \ | ||||
|     { static_cast<u32>(Settings::ENUM::VALUE), tr(TRANSLATION) } | ||||
| #define CTX_PAIR(ENUM, VALUE, TRANSLATION, CONTEXT)                                                \ | ||||
|     { static_cast<u32>(Settings::ENUM::VALUE), tr(TRANSLATION, CONTEXT) } | ||||
| #define PAIR(ENUM, VALUE, TRANSLATION) {static_cast<u32>(Settings::ENUM::VALUE), (TRANSLATION)} | ||||
|  | ||||
|     // Intentionally skipping VSyncMode to let the UI fill that one out | ||||
|  | ||||
|     translations->insert({Settings::EnumMetadata<Settings::AstcDecodeMode>::Index(), | ||||
|                           { | ||||
|                               PAIR(AstcDecodeMode, Cpu, "CPU"), | ||||
|                               PAIR(AstcDecodeMode, Gpu, "GPU"), | ||||
|                               PAIR(AstcDecodeMode, CpuAsynchronous, "CPU Asynchronous"), | ||||
|                           }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::AstcRecompression>::Index(), | ||||
|                           { | ||||
|                               PAIR(AstcRecompression, Uncompressed, "Uncompressed (Best quality)"), | ||||
|                               PAIR(AstcRecompression, Bc1, "BC1 (Low quality)"), | ||||
|                               PAIR(AstcRecompression, Bc3, "BC3 (Medium quality)"), | ||||
|                               PAIR(AstcDecodeMode, Cpu, tr("CPU")), | ||||
|                               PAIR(AstcDecodeMode, Gpu, tr("GPU")), | ||||
|                               PAIR(AstcDecodeMode, CpuAsynchronous, tr("CPU Asynchronous")), | ||||
|                           }}); | ||||
|     translations->insert( | ||||
|         {Settings::EnumMetadata<Settings::AstcRecompression>::Index(), | ||||
|          { | ||||
|              PAIR(AstcRecompression, Uncompressed, tr("Uncompressed (Best quality)")), | ||||
|              PAIR(AstcRecompression, Bc1, tr("BC1 (Low quality)")), | ||||
|              PAIR(AstcRecompression, Bc3, tr("BC3 (Medium quality)")), | ||||
|          }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::RendererBackend>::Index(), | ||||
|                           { | ||||
| #ifdef HAS_OPENGL | ||||
|                               PAIR(RendererBackend, OpenGL, "OpenGL"), | ||||
|                               PAIR(RendererBackend, OpenGL, tr("OpenGL")), | ||||
| #endif | ||||
|                               PAIR(RendererBackend, Vulkan, "Vulkan"), | ||||
|                               PAIR(RendererBackend, Null, "Null"), | ||||
|                           }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::ShaderBackend>::Index(), | ||||
|                           { | ||||
|                               PAIR(ShaderBackend, Glsl, "GLSL"), | ||||
|                               PAIR(ShaderBackend, Glasm, "GLASM (Assembly Shaders, NVIDIA Only)"), | ||||
|                               PAIR(ShaderBackend, SpirV, "SPIR-V (Experimental, Mesa Only)"), | ||||
|                               PAIR(RendererBackend, Vulkan, tr("Vulkan")), | ||||
|                               PAIR(RendererBackend, Null, tr("Null")), | ||||
|                           }}); | ||||
|     translations->insert( | ||||
|         {Settings::EnumMetadata<Settings::ShaderBackend>::Index(), | ||||
|          { | ||||
|              PAIR(ShaderBackend, Glsl, tr("GLSL")), | ||||
|              PAIR(ShaderBackend, Glasm, tr("GLASM (Assembly Shaders, NVIDIA Only)")), | ||||
|              PAIR(ShaderBackend, SpirV, tr("SPIR-V (Experimental, Mesa Only)")), | ||||
|          }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::GpuAccuracy>::Index(), | ||||
|                           { | ||||
|                               PAIR(GpuAccuracy, Normal, "Normal"), | ||||
|                               PAIR(GpuAccuracy, High, "High"), | ||||
|                               PAIR(GpuAccuracy, Extreme, "Extreme"), | ||||
|                           }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::CpuAccuracy>::Index(), | ||||
|                           { | ||||
|                               PAIR(CpuAccuracy, Auto, "Auto"), | ||||
|                               PAIR(CpuAccuracy, Accurate, "Accurate"), | ||||
|                               PAIR(CpuAccuracy, Unsafe, "Unsafe"), | ||||
|                               PAIR(CpuAccuracy, Paranoid, "Paranoid (disables most optimizations)"), | ||||
|                               PAIR(GpuAccuracy, Normal, tr("Normal")), | ||||
|                               PAIR(GpuAccuracy, High, tr("High")), | ||||
|                               PAIR(GpuAccuracy, Extreme, tr("Extreme")), | ||||
|                           }}); | ||||
|     translations->insert( | ||||
|         {Settings::EnumMetadata<Settings::CpuAccuracy>::Index(), | ||||
|          { | ||||
|              PAIR(CpuAccuracy, Auto, tr("Auto")), | ||||
|              PAIR(CpuAccuracy, Accurate, tr("Accurate")), | ||||
|              PAIR(CpuAccuracy, Unsafe, tr("Unsafe")), | ||||
|              PAIR(CpuAccuracy, Paranoid, tr("Paranoid (disables most optimizations)")), | ||||
|          }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::FullscreenMode>::Index(), | ||||
|                           { | ||||
|                               PAIR(FullscreenMode, Borderless, "Borderless Windowed"), | ||||
|                               PAIR(FullscreenMode, Exclusive, "Exclusive Fullscreen"), | ||||
|                               PAIR(FullscreenMode, Borderless, tr("Borderless Windowed")), | ||||
|                               PAIR(FullscreenMode, Exclusive, tr("Exclusive Fullscreen")), | ||||
|                           }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::NvdecEmulation>::Index(), | ||||
|                           { | ||||
|                               PAIR(NvdecEmulation, Off, "No Video Output"), | ||||
|                               PAIR(NvdecEmulation, Cpu, "CPU Video Decoding"), | ||||
|                               PAIR(NvdecEmulation, Gpu, "GPU Video Decoding (Default)"), | ||||
|                           }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::ResolutionSetup>::Index(), | ||||
|                           { | ||||
|                               PAIR(ResolutionSetup, Res1_2X, "0.5X (360p/540p) [EXPERIMENTAL]"), | ||||
|                               PAIR(ResolutionSetup, Res3_4X, "0.75X (540p/810p) [EXPERIMENTAL]"), | ||||
|                               PAIR(ResolutionSetup, Res1X, "1X (720p/1080p)"), | ||||
|                               PAIR(ResolutionSetup, Res3_2X, "1.5X (1080p/1620p) [EXPERIMENTAL]"), | ||||
|                               PAIR(ResolutionSetup, Res2X, "2X (1440p/2160p)"), | ||||
|                               PAIR(ResolutionSetup, Res3X, "3X (2160p/3240p)"), | ||||
|                               PAIR(ResolutionSetup, Res4X, "4X (2880p/4320p)"), | ||||
|                               PAIR(ResolutionSetup, Res5X, "5X (3600p/5400p)"), | ||||
|                               PAIR(ResolutionSetup, Res6X, "6X (4320p/6480p)"), | ||||
|                               PAIR(ResolutionSetup, Res7X, "7X (5040p/7560p)"), | ||||
|                               PAIR(ResolutionSetup, Res8X, "8X (5760p/8640p)"), | ||||
|                               PAIR(NvdecEmulation, Off, tr("No Video Output")), | ||||
|                               PAIR(NvdecEmulation, Cpu, tr("CPU Video Decoding")), | ||||
|                               PAIR(NvdecEmulation, Gpu, tr("GPU Video Decoding (Default)")), | ||||
|                           }}); | ||||
|     translations->insert( | ||||
|         {Settings::EnumMetadata<Settings::ResolutionSetup>::Index(), | ||||
|          { | ||||
|              PAIR(ResolutionSetup, Res1_2X, tr("0.5X (360p/540p) [EXPERIMENTAL]")), | ||||
|              PAIR(ResolutionSetup, Res3_4X, tr("0.75X (540p/810p) [EXPERIMENTAL]")), | ||||
|              PAIR(ResolutionSetup, Res1X, tr("1X (720p/1080p)")), | ||||
|              PAIR(ResolutionSetup, Res3_2X, tr("1.5X (1080p/1620p) [EXPERIMENTAL]")), | ||||
|              PAIR(ResolutionSetup, Res2X, tr("2X (1440p/2160p)")), | ||||
|              PAIR(ResolutionSetup, Res3X, tr("3X (2160p/3240p)")), | ||||
|              PAIR(ResolutionSetup, Res4X, tr("4X (2880p/4320p)")), | ||||
|              PAIR(ResolutionSetup, Res5X, tr("5X (3600p/5400p)")), | ||||
|              PAIR(ResolutionSetup, Res6X, tr("6X (4320p/6480p)")), | ||||
|              PAIR(ResolutionSetup, Res7X, tr("7X (5040p/7560p)")), | ||||
|              PAIR(ResolutionSetup, Res8X, tr("8X (5760p/8640p)")), | ||||
|          }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::ScalingFilter>::Index(), | ||||
|                           { | ||||
|                               PAIR(ScalingFilter, NearestNeighbor, "Nearest Neighbor"), | ||||
|                               PAIR(ScalingFilter, Bilinear, "Bilinear"), | ||||
|                               PAIR(ScalingFilter, Bicubic, "Bicubic"), | ||||
|                               PAIR(ScalingFilter, Gaussian, "Gaussian"), | ||||
|                               PAIR(ScalingFilter, ScaleForce, "ScaleForce"), | ||||
|                               PAIR(ScalingFilter, Fsr, "AMD FidelityFX™️ Super Resolution"), | ||||
|                               PAIR(ScalingFilter, NearestNeighbor, tr("Nearest Neighbor")), | ||||
|                               PAIR(ScalingFilter, Bilinear, tr("Bilinear")), | ||||
|                               PAIR(ScalingFilter, Bicubic, tr("Bicubic")), | ||||
|                               PAIR(ScalingFilter, Gaussian, tr("Gaussian")), | ||||
|                               PAIR(ScalingFilter, ScaleForce, tr("ScaleForce")), | ||||
|                               PAIR(ScalingFilter, Fsr, tr("AMD FidelityFX™️ Super Resolution")), | ||||
|                           }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::AntiAliasing>::Index(), | ||||
|                           { | ||||
|                               PAIR(AntiAliasing, None, "None"), | ||||
|                               PAIR(AntiAliasing, Fxaa, "FXAA"), | ||||
|                               PAIR(AntiAliasing, Smaa, "SMAA"), | ||||
|                               PAIR(AntiAliasing, None, tr("None")), | ||||
|                               PAIR(AntiAliasing, Fxaa, tr("FXAA")), | ||||
|                               PAIR(AntiAliasing, Smaa, tr("SMAA")), | ||||
|                           }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::AspectRatio>::Index(), | ||||
|                           { | ||||
|                               PAIR(AspectRatio, R16_9, "Default (16:9)"), | ||||
|                               PAIR(AspectRatio, R4_3, "Force 4:3"), | ||||
|                               PAIR(AspectRatio, R21_9, "Force 21:9"), | ||||
|                               PAIR(AspectRatio, R16_10, "Force 16:10"), | ||||
|                               PAIR(AspectRatio, Stretch, "Stretch to Window"), | ||||
|                               PAIR(AspectRatio, R16_9, tr("Default (16:9)")), | ||||
|                               PAIR(AspectRatio, R4_3, tr("Force 4:3")), | ||||
|                               PAIR(AspectRatio, R21_9, tr("Force 21:9")), | ||||
|                               PAIR(AspectRatio, R16_10, tr("Force 16:10")), | ||||
|                               PAIR(AspectRatio, Stretch, tr("Stretch to Window")), | ||||
|                           }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::AnisotropyMode>::Index(), | ||||
|                           { | ||||
|                               PAIR(AnisotropyMode, Automatic, "Automatic"), | ||||
|                               PAIR(AnisotropyMode, Default, "Default"), | ||||
|                               PAIR(AnisotropyMode, X2, "2x"), | ||||
|                               PAIR(AnisotropyMode, X4, "4x"), | ||||
|                               PAIR(AnisotropyMode, X8, "8x"), | ||||
|                               PAIR(AnisotropyMode, X16, "16x"), | ||||
|                               PAIR(AnisotropyMode, Automatic, tr("Automatic")), | ||||
|                               PAIR(AnisotropyMode, Default, tr("Default")), | ||||
|                               PAIR(AnisotropyMode, X2, tr("2x")), | ||||
|                               PAIR(AnisotropyMode, X4, tr("4x")), | ||||
|                               PAIR(AnisotropyMode, X8, tr("8x")), | ||||
|                               PAIR(AnisotropyMode, X16, tr("16x")), | ||||
|                           }}); | ||||
|     translations->insert( | ||||
|         {Settings::EnumMetadata<Settings::Language>::Index(), | ||||
|          { | ||||
|              PAIR(Language, Japanese, "Japanese (日本語)"), | ||||
|              PAIR(Language, EnglishAmerican, "American English"), | ||||
|              PAIR(Language, French, "French (français)"), | ||||
|              PAIR(Language, German, "German (Deutsch)"), | ||||
|              PAIR(Language, Italian, "Italian (italiano)"), | ||||
|              PAIR(Language, Spanish, "Spanish (español)"), | ||||
|              PAIR(Language, Chinese, "Chinese"), | ||||
|              PAIR(Language, Korean, "Korean (한국어)"), | ||||
|              PAIR(Language, Dutch, "Dutch (Nederlands)"), | ||||
|              PAIR(Language, Portuguese, "Portuguese (português)"), | ||||
|              PAIR(Language, Russian, "Russian (Русский)"), | ||||
|              PAIR(Language, Taiwanese, "Taiwanese"), | ||||
|              PAIR(Language, EnglishBritish, "British English"), | ||||
|              PAIR(Language, FrenchCanadian, "Canadian French"), | ||||
|              PAIR(Language, SpanishLatin, "Latin American Spanish"), | ||||
|              PAIR(Language, ChineseSimplified, "Simplified Chinese"), | ||||
|              PAIR(Language, ChineseTraditional, "Traditional Chinese (正體中文)"), | ||||
|              PAIR(Language, PortugueseBrazilian, "Brazilian Portuguese (português do Brasil)"), | ||||
|              PAIR(Language, Japanese, tr("Japanese (日本語)")), | ||||
|              PAIR(Language, EnglishAmerican, tr("American English")), | ||||
|              PAIR(Language, French, tr("French (français)")), | ||||
|              PAIR(Language, German, tr("German (Deutsch)")), | ||||
|              PAIR(Language, Italian, tr("Italian (italiano)")), | ||||
|              PAIR(Language, Spanish, tr("Spanish (español)")), | ||||
|              PAIR(Language, Chinese, tr("Chinese")), | ||||
|              PAIR(Language, Korean, tr("Korean (한국어)")), | ||||
|              PAIR(Language, Dutch, tr("Dutch (Nederlands)")), | ||||
|              PAIR(Language, Portuguese, tr("Portuguese (português)")), | ||||
|              PAIR(Language, Russian, tr("Russian (Русский)")), | ||||
|              PAIR(Language, Taiwanese, tr("Taiwanese")), | ||||
|              PAIR(Language, EnglishBritish, tr("British English")), | ||||
|              PAIR(Language, FrenchCanadian, tr("Canadian French")), | ||||
|              PAIR(Language, SpanishLatin, tr("Latin American Spanish")), | ||||
|              PAIR(Language, ChineseSimplified, tr("Simplified Chinese")), | ||||
|              PAIR(Language, ChineseTraditional, tr("Traditional Chinese (正體中文)")), | ||||
|              PAIR(Language, PortugueseBrazilian, tr("Brazilian Portuguese (português do Brasil)")), | ||||
|          }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::Region>::Index(), | ||||
|                           { | ||||
|                               PAIR(Region, Japan, "Japan"), | ||||
|                               PAIR(Region, Usa, "USA"), | ||||
|                               PAIR(Region, Europe, "Europe"), | ||||
|                               PAIR(Region, Australia, "Australia"), | ||||
|                               PAIR(Region, China, "China"), | ||||
|                               PAIR(Region, Korea, "Korea"), | ||||
|                               PAIR(Region, Taiwan, "Taiwan"), | ||||
|                               PAIR(Region, Japan, tr("Japan")), | ||||
|                               PAIR(Region, Usa, tr("USA")), | ||||
|                               PAIR(Region, Europe, tr("Europe")), | ||||
|                               PAIR(Region, Australia, tr("Australia")), | ||||
|                               PAIR(Region, China, tr("China")), | ||||
|                               PAIR(Region, Korea, tr("Korea")), | ||||
|                               PAIR(Region, Taiwan, tr("Taiwan")), | ||||
|                           }}); | ||||
|     translations->insert( | ||||
|         {Settings::EnumMetadata<Settings::TimeZone>::Index(), | ||||
| @@ -323,72 +340,74 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) { | ||||
|              {static_cast<u32>(Settings::TimeZone::Default), | ||||
|               tr("Default (%1)", "Default time zone") | ||||
|                   .arg(QString::fromStdString(Common::TimeZone::GetDefaultTimeZone()))}, | ||||
|              PAIR(TimeZone, Cet, "CET"), | ||||
|              PAIR(TimeZone, Cst6Cdt, "CST6CDT"), | ||||
|              PAIR(TimeZone, Cuba, "Cuba"), | ||||
|              PAIR(TimeZone, Eet, "EET"), | ||||
|              PAIR(TimeZone, Egypt, "Egypt"), | ||||
|              PAIR(TimeZone, Eire, "Eire"), | ||||
|              PAIR(TimeZone, Est, "EST"), | ||||
|              PAIR(TimeZone, Est5Edt, "EST5EDT"), | ||||
|              PAIR(TimeZone, Gb, "GB"), | ||||
|              PAIR(TimeZone, GbEire, "GB-Eire"), | ||||
|              PAIR(TimeZone, Gmt, "GMT"), | ||||
|              PAIR(TimeZone, GmtPlusZero, "GMT+0"), | ||||
|              PAIR(TimeZone, GmtMinusZero, "GMT-0"), | ||||
|              PAIR(TimeZone, GmtZero, "GMT0"), | ||||
|              PAIR(TimeZone, Greenwich, "Greenwich"), | ||||
|              PAIR(TimeZone, Hongkong, "Hongkong"), | ||||
|              PAIR(TimeZone, Hst, "HST"), | ||||
|              PAIR(TimeZone, Iceland, "Iceland"), | ||||
|              PAIR(TimeZone, Iran, "Iran"), | ||||
|              PAIR(TimeZone, Israel, "Israel"), | ||||
|              PAIR(TimeZone, Jamaica, "Jamaica"), | ||||
|              PAIR(TimeZone, Japan, "Japan"), | ||||
|              PAIR(TimeZone, Kwajalein, "Kwajalein"), | ||||
|              PAIR(TimeZone, Libya, "Libya"), | ||||
|              PAIR(TimeZone, Met, "MET"), | ||||
|              PAIR(TimeZone, Mst, "MST"), | ||||
|              PAIR(TimeZone, Mst7Mdt, "MST7MDT"), | ||||
|              PAIR(TimeZone, Navajo, "Navajo"), | ||||
|              PAIR(TimeZone, Nz, "NZ"), | ||||
|              PAIR(TimeZone, NzChat, "NZ-CHAT"), | ||||
|              PAIR(TimeZone, Poland, "Poland"), | ||||
|              PAIR(TimeZone, Portugal, "Portugal"), | ||||
|              PAIR(TimeZone, Prc, "PRC"), | ||||
|              PAIR(TimeZone, Pst8Pdt, "PST8PDT"), | ||||
|              PAIR(TimeZone, Roc, "ROC"), | ||||
|              PAIR(TimeZone, Rok, "ROK"), | ||||
|              PAIR(TimeZone, Singapore, "Singapore"), | ||||
|              PAIR(TimeZone, Turkey, "Turkey"), | ||||
|              PAIR(TimeZone, Uct, "UCT"), | ||||
|              PAIR(TimeZone, Universal, "Universal"), | ||||
|              PAIR(TimeZone, Utc, "UTC"), | ||||
|              PAIR(TimeZone, WSu, "W-SU"), | ||||
|              PAIR(TimeZone, Wet, "WET"), | ||||
|              PAIR(TimeZone, Zulu, "Zulu"), | ||||
|              PAIR(TimeZone, Cet, tr("CET")), | ||||
|              PAIR(TimeZone, Cst6Cdt, tr("CST6CDT")), | ||||
|              PAIR(TimeZone, Cuba, tr("Cuba")), | ||||
|              PAIR(TimeZone, Eet, tr("EET")), | ||||
|              PAIR(TimeZone, Egypt, tr("Egypt")), | ||||
|              PAIR(TimeZone, Eire, tr("Eire")), | ||||
|              PAIR(TimeZone, Est, tr("EST")), | ||||
|              PAIR(TimeZone, Est5Edt, tr("EST5EDT")), | ||||
|              PAIR(TimeZone, Gb, tr("GB")), | ||||
|              PAIR(TimeZone, GbEire, tr("GB-Eire")), | ||||
|              PAIR(TimeZone, Gmt, tr("GMT")), | ||||
|              PAIR(TimeZone, GmtPlusZero, tr("GMT+0")), | ||||
|              PAIR(TimeZone, GmtMinusZero, tr("GMT-0")), | ||||
|              PAIR(TimeZone, GmtZero, tr("GMT0")), | ||||
|              PAIR(TimeZone, Greenwich, tr("Greenwich")), | ||||
|              PAIR(TimeZone, Hongkong, tr("Hongkong")), | ||||
|              PAIR(TimeZone, Hst, tr("HST")), | ||||
|              PAIR(TimeZone, Iceland, tr("Iceland")), | ||||
|              PAIR(TimeZone, Iran, tr("Iran")), | ||||
|              PAIR(TimeZone, Israel, tr("Israel")), | ||||
|              PAIR(TimeZone, Jamaica, tr("Jamaica")), | ||||
|              PAIR(TimeZone, Japan, tr("Japan")), | ||||
|              PAIR(TimeZone, Kwajalein, tr("Kwajalein")), | ||||
|              PAIR(TimeZone, Libya, tr("Libya")), | ||||
|              PAIR(TimeZone, Met, tr("MET")), | ||||
|              PAIR(TimeZone, Mst, tr("MST")), | ||||
|              PAIR(TimeZone, Mst7Mdt, tr("MST7MDT")), | ||||
|              PAIR(TimeZone, Navajo, tr("Navajo")), | ||||
|              PAIR(TimeZone, Nz, tr("NZ")), | ||||
|              PAIR(TimeZone, NzChat, tr("NZ-CHAT")), | ||||
|              PAIR(TimeZone, Poland, tr("Poland")), | ||||
|              PAIR(TimeZone, Portugal, tr("Portugal")), | ||||
|              PAIR(TimeZone, Prc, tr("PRC")), | ||||
|              PAIR(TimeZone, Pst8Pdt, tr("PST8PDT")), | ||||
|              PAIR(TimeZone, Roc, tr("ROC")), | ||||
|              PAIR(TimeZone, Rok, tr("ROK")), | ||||
|              PAIR(TimeZone, Singapore, tr("Singapore")), | ||||
|              PAIR(TimeZone, Turkey, tr("Turkey")), | ||||
|              PAIR(TimeZone, Uct, tr("UCT")), | ||||
|              PAIR(TimeZone, Universal, tr("Universal")), | ||||
|              PAIR(TimeZone, Utc, tr("UTC")), | ||||
|              PAIR(TimeZone, WSu, tr("W-SU")), | ||||
|              PAIR(TimeZone, Wet, tr("WET")), | ||||
|              PAIR(TimeZone, Zulu, tr("Zulu")), | ||||
|          }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::AudioMode>::Index(), | ||||
|                           { | ||||
|                               PAIR(AudioMode, Mono, "Mono"), | ||||
|                               PAIR(AudioMode, Stereo, "Stereo"), | ||||
|                               PAIR(AudioMode, Surround, "Surround"), | ||||
|                               PAIR(AudioMode, Mono, tr("Mono")), | ||||
|                               PAIR(AudioMode, Stereo, tr("Stereo")), | ||||
|                               PAIR(AudioMode, Surround, tr("Surround")), | ||||
|                           }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::MemoryLayout>::Index(), | ||||
|                           { | ||||
|                               PAIR(MemoryLayout, Memory_4Gb, "4GB DRAM (Default)"), | ||||
|                               PAIR(MemoryLayout, Memory_6Gb, "6GB DRAM (Unsafe)"), | ||||
|                               PAIR(MemoryLayout, Memory_8Gb, "8GB DRAM (Unsafe)"), | ||||
|                               PAIR(MemoryLayout, Memory_4Gb, tr("4GB DRAM (Default)")), | ||||
|                               PAIR(MemoryLayout, Memory_6Gb, tr("6GB DRAM (Unsafe)")), | ||||
|                               PAIR(MemoryLayout, Memory_8Gb, tr("8GB DRAM (Unsafe)")), | ||||
|                           }}); | ||||
|     translations->insert({Settings::EnumMetadata<Settings::ConsoleMode>::Index(), | ||||
|                           { | ||||
|                               PAIR(ConsoleMode, Docked, tr("Docked")), | ||||
|                               PAIR(ConsoleMode, Handheld, tr("Handheld")), | ||||
|                           }}); | ||||
|     translations->insert( | ||||
|         {Settings::EnumMetadata<Settings::ConsoleMode>::Index(), | ||||
|          {PAIR(ConsoleMode, Docked, "Docked"), PAIR(ConsoleMode, Handheld, "Handheld")}}); | ||||
|     translations->insert( | ||||
|         {Settings::EnumMetadata<Settings::ConfirmStop>::Index(), | ||||
|          { | ||||
|              PAIR(ConfirmStop, Ask_Always, "Always ask (Default)"), | ||||
|              PAIR(ConfirmStop, Ask_Based_On_Game, "Only if game specifies not to stop"), | ||||
|              PAIR(ConfirmStop, Ask_Never, "Never ask"), | ||||
|              PAIR(ConfirmStop, Ask_Always, tr("Always ask (Default)")), | ||||
|              PAIR(ConfirmStop, Ask_Based_On_Game, tr("Only if game specifies not to stop")), | ||||
|              PAIR(ConfirmStop, Ask_Never, tr("Never ask")), | ||||
|          }}); | ||||
|  | ||||
| #undef PAIR | ||||
|   | ||||
| @@ -1579,6 +1579,7 @@ void GMainWindow::ConnectMenuEvents() { | ||||
|     connect_menu(ui->action_Load_Cabinet_Formatter, | ||||
|                  [this]() { OnCabinet(Service::NFP::CabinetMode::StartFormatter); }); | ||||
|     connect_menu(ui->action_Load_Mii_Edit, &GMainWindow::OnMiiEdit); | ||||
|     connect_menu(ui->action_Open_Controller_Menu, &GMainWindow::OnOpenControllerMenu); | ||||
|     connect_menu(ui->action_Capture_Screenshot, &GMainWindow::OnCaptureScreenshot); | ||||
|  | ||||
|     // TAS | ||||
| @@ -1606,14 +1607,13 @@ void GMainWindow::UpdateMenuState() { | ||||
|         ui->action_Pause, | ||||
|     }; | ||||
|  | ||||
|     const std::array applet_actions{ | ||||
|         ui->action_Load_Album, | ||||
|         ui->action_Load_Cabinet_Nickname_Owner, | ||||
|         ui->action_Load_Cabinet_Eraser, | ||||
|         ui->action_Load_Cabinet_Restorer, | ||||
|         ui->action_Load_Cabinet_Formatter, | ||||
|         ui->action_Load_Mii_Edit, | ||||
|     }; | ||||
|     const std::array applet_actions{ui->action_Load_Album, | ||||
|                                     ui->action_Load_Cabinet_Nickname_Owner, | ||||
|                                     ui->action_Load_Cabinet_Eraser, | ||||
|                                     ui->action_Load_Cabinet_Restorer, | ||||
|                                     ui->action_Load_Cabinet_Formatter, | ||||
|                                     ui->action_Load_Mii_Edit, | ||||
|                                     ui->action_Open_Controller_Menu}; | ||||
|  | ||||
|     for (QAction* action : running_actions) { | ||||
|         action->setEnabled(emulation_running); | ||||
| @@ -4380,6 +4380,31 @@ void GMainWindow::OnMiiEdit() { | ||||
|     BootGame(filename, MiiEditId); | ||||
| } | ||||
|  | ||||
| void GMainWindow::OnOpenControllerMenu() { | ||||
|     constexpr u64 ControllerAppletId = | ||||
|         static_cast<u64>(Service::AM::Applets::AppletProgramId::Controller); | ||||
|     auto bis_system = system->GetFileSystemController().GetSystemNANDContents(); | ||||
|     if (!bis_system) { | ||||
|         QMessageBox::warning(this, tr("No firmware available"), | ||||
|                              tr("Please install the firmware to use the Controller Menu.")); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     auto controller_applet_nca = | ||||
|         bis_system->GetEntry(ControllerAppletId, FileSys::ContentRecordType::Program); | ||||
|     if (!controller_applet_nca) { | ||||
|         QMessageBox::warning(this, tr("Controller Applet"), | ||||
|                              tr("Controller Menu is not available. Please reinstall firmware.")); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::Controller); | ||||
|  | ||||
|     const auto filename = QString::fromStdString((controller_applet_nca->GetFullPath())); | ||||
|     UISettings::values.roms_path = QFileInfo(filename).path().toStdString(); | ||||
|     BootGame(filename, ControllerAppletId); | ||||
| } | ||||
|  | ||||
| void GMainWindow::OnCaptureScreenshot() { | ||||
|     if (emu_thread == nullptr || !emu_thread->IsRunning()) { | ||||
|         return; | ||||
|   | ||||
| @@ -411,6 +411,7 @@ private slots: | ||||
|     void OnAlbum(); | ||||
|     void OnCabinet(Service::NFP::CabinetMode mode); | ||||
|     void OnMiiEdit(); | ||||
|     void OnOpenControllerMenu(); | ||||
|     void OnCaptureScreenshot(); | ||||
|     void OnReinitializeKeys(ReinitializeKeyBehavior behavior); | ||||
|     void OnLanguageChanged(const QString& locale); | ||||
|   | ||||
| @@ -25,7 +25,7 @@ | ||||
|   </property> | ||||
|   <widget class="QWidget" name="centralwidget"> | ||||
|    <layout class="QHBoxLayout" name="horizontalLayout"> | ||||
|     <property name="margin"> | ||||
|     <property name="margin" stdset="0"> | ||||
|      <number>0</number> | ||||
|     </property> | ||||
|    </layout> | ||||
| @@ -36,7 +36,7 @@ | ||||
|      <x>0</x> | ||||
|      <y>0</y> | ||||
|      <width>1280</width> | ||||
|      <height>26</height> | ||||
|      <height>21</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|    <widget class="QMenu" name="menu_File"> | ||||
| @@ -162,6 +162,7 @@ | ||||
|     <addaction name="menu_cabinet_applet"/> | ||||
|     <addaction name="action_Load_Album"/> | ||||
|     <addaction name="action_Load_Mii_Edit"/> | ||||
|     <addaction name="action_Open_Controller_Menu"/> | ||||
|     <addaction name="separator"/> | ||||
|     <addaction name="action_Capture_Screenshot"/> | ||||
|     <addaction name="menuTAS"/> | ||||
| @@ -382,9 +383,9 @@ | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="action_Load_Album"> | ||||
|     <property name="text"> | ||||
|       <string>Open &Album</string> | ||||
|     </property> | ||||
|    <property name="text"> | ||||
|     <string>Open &Album</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="action_Load_Cabinet_Nickname_Owner"> | ||||
|    <property name="text"> | ||||
| @@ -407,9 +408,9 @@ | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="action_Load_Mii_Edit"> | ||||
|     <property name="text"> | ||||
|       <string>Open &Mii Editor</string> | ||||
|     </property> | ||||
|    <property name="text"> | ||||
|     <string>Open &Mii Editor</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="action_Configure_Tas"> | ||||
|    <property name="text"> | ||||
| @@ -454,6 +455,11 @@ | ||||
|     <string>R&ecord</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="action_Open_Controller_Menu"> | ||||
|    <property name="text"> | ||||
|     <string>Open &Controller Menu</string> | ||||
|    </property> | ||||
|   </action> | ||||
|  </widget> | ||||
|  <resources> | ||||
|   <include location="yuzu.qrc"/> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user