diff options
Diffstat (limited to 'src')
31 files changed, 716 insertions, 144 deletions
diff --git a/src/common/logging/log.h b/src/common/logging/log.h index abbd056ee..c9161155a 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h | |||
| @@ -91,6 +91,7 @@ enum class Class : ClassType { | |||
| 91 | Service_PM, ///< The PM service | 91 | Service_PM, ///< The PM service |
| 92 | Service_PREPO, ///< The PREPO (Play report) service | 92 | Service_PREPO, ///< The PREPO (Play report) service |
| 93 | Service_PSC, ///< The PSC service | 93 | Service_PSC, ///< The PSC service |
| 94 | Service_PSM, ///< The PSM service | ||
| 94 | Service_SET, ///< The SET (Settings) service | 95 | Service_SET, ///< The SET (Settings) service |
| 95 | Service_SM, ///< The SM (Service manager) service | 96 | Service_SM, ///< The SM (Service manager) service |
| 96 | Service_SPL, ///< The SPL service | 97 | Service_SPL, ///< The SPL service |
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 4755ec822..64fdf38cd 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -156,6 +156,8 @@ add_library(core STATIC | |||
| 156 | hle/service/am/omm.h | 156 | hle/service/am/omm.h |
| 157 | hle/service/am/spsm.cpp | 157 | hle/service/am/spsm.cpp |
| 158 | hle/service/am/spsm.h | 158 | hle/service/am/spsm.h |
| 159 | hle/service/am/tcap.cpp | ||
| 160 | hle/service/am/tcap.h | ||
| 159 | hle/service/aoc/aoc_u.cpp | 161 | hle/service/aoc/aoc_u.cpp |
| 160 | hle/service/aoc/aoc_u.h | 162 | hle/service/aoc/aoc_u.h |
| 161 | hle/service/apm/apm.cpp | 163 | hle/service/apm/apm.cpp |
| @@ -280,6 +282,8 @@ add_library(core STATIC | |||
| 280 | hle/service/nifm/nifm.h | 282 | hle/service/nifm/nifm.h |
| 281 | hle/service/nim/nim.cpp | 283 | hle/service/nim/nim.cpp |
| 282 | hle/service/nim/nim.h | 284 | hle/service/nim/nim.h |
| 285 | hle/service/npns/npns.cpp | ||
| 286 | hle/service/npns/npns.h | ||
| 283 | hle/service/ns/ns.cpp | 287 | hle/service/ns/ns.cpp |
| 284 | hle/service/ns/ns.h | 288 | hle/service/ns/ns.h |
| 285 | hle/service/ns/pl_u.cpp | 289 | hle/service/ns/pl_u.cpp |
| @@ -327,6 +331,8 @@ add_library(core STATIC | |||
| 327 | hle/service/prepo/prepo.h | 331 | hle/service/prepo/prepo.h |
| 328 | hle/service/psc/psc.cpp | 332 | hle/service/psc/psc.cpp |
| 329 | hle/service/psc/psc.h | 333 | hle/service/psc/psc.h |
| 334 | hle/service/ptm/psm.cpp | ||
| 335 | hle/service/ptm/psm.h | ||
| 330 | hle/service/service.cpp | 336 | hle/service/service.cpp |
| 331 | hle/service/service.h | 337 | hle/service/service.h |
| 332 | hle/service/set/set.cpp | 338 | hle/service/set/set.cpp |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 3b8a2e230..690b84930 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -654,7 +654,7 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i | |||
| 654 | } | 654 | } |
| 655 | auto vma = process->VMManager().FindVMA(addr); | 655 | auto vma = process->VMManager().FindVMA(addr); |
| 656 | memory_info->attributes = 0; | 656 | memory_info->attributes = 0; |
| 657 | if (vma == Core::CurrentProcess()->VMManager().vma_map.end()) { | 657 | if (vma == process->VMManager().vma_map.end()) { |
| 658 | memory_info->base_address = 0; | 658 | memory_info->base_address = 0; |
| 659 | memory_info->permission = static_cast<u32>(VMAPermission::None); | 659 | memory_info->permission = static_cast<u32>(VMAPermission::None); |
| 660 | memory_info->size = 0; | 660 | memory_info->size = 0; |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 4d1f83170..ecf72ae24 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "core/hle/service/am/idle.h" | 15 | #include "core/hle/service/am/idle.h" |
| 16 | #include "core/hle/service/am/omm.h" | 16 | #include "core/hle/service/am/omm.h" |
| 17 | #include "core/hle/service/am/spsm.h" | 17 | #include "core/hle/service/am/spsm.h" |
| 18 | #include "core/hle/service/am/tcap.h" | ||
| 18 | #include "core/hle/service/apm/apm.h" | 19 | #include "core/hle/service/apm/apm.h" |
| 19 | #include "core/hle/service/filesystem/filesystem.h" | 20 | #include "core/hle/service/filesystem/filesystem.h" |
| 20 | #include "core/hle/service/nvflinger/nvflinger.h" | 21 | #include "core/hle/service/nvflinger/nvflinger.h" |
| @@ -26,13 +27,18 @@ | |||
| 26 | namespace Service::AM { | 27 | namespace Service::AM { |
| 27 | 28 | ||
| 28 | IWindowController::IWindowController() : ServiceFramework("IWindowController") { | 29 | IWindowController::IWindowController() : ServiceFramework("IWindowController") { |
| 30 | // clang-format off | ||
| 29 | static const FunctionInfo functions[] = { | 31 | static const FunctionInfo functions[] = { |
| 30 | {0, nullptr, "CreateWindow"}, | 32 | {0, nullptr, "CreateWindow"}, |
| 31 | {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"}, | 33 | {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"}, |
| 32 | {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"}, | 34 | {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"}, |
| 33 | {11, nullptr, "ReleaseForegroundRights"}, | 35 | {11, nullptr, "ReleaseForegroundRights"}, |
| 34 | {12, nullptr, "RejectToChangeIntoBackground"}, | 36 | {12, nullptr, "RejectToChangeIntoBackground"}, |
| 37 | {20, nullptr, "SetAppletWindowVisibility"}, | ||
| 38 | {21, nullptr, "SetAppletGpuTimeSlice"}, | ||
| 35 | }; | 39 | }; |
| 40 | // clang-format on | ||
| 41 | |||
| 36 | RegisterHandlers(functions); | 42 | RegisterHandlers(functions); |
| 37 | } | 43 | } |
| 38 | 44 | ||
| @@ -87,6 +93,7 @@ void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestCo | |||
| 87 | } | 93 | } |
| 88 | 94 | ||
| 89 | IDisplayController::IDisplayController() : ServiceFramework("IDisplayController") { | 95 | IDisplayController::IDisplayController() : ServiceFramework("IDisplayController") { |
| 96 | // clang-format off | ||
| 90 | static const FunctionInfo functions[] = { | 97 | static const FunctionInfo functions[] = { |
| 91 | {0, nullptr, "GetLastForegroundCaptureImage"}, | 98 | {0, nullptr, "GetLastForegroundCaptureImage"}, |
| 92 | {1, nullptr, "UpdateLastForegroundCaptureImage"}, | 99 | {1, nullptr, "UpdateLastForegroundCaptureImage"}, |
| @@ -117,7 +124,11 @@ IDisplayController::IDisplayController() : ServiceFramework("IDisplayController" | |||
| 117 | {25, nullptr, "ReleaseLastForegroundCaptureSharedBuffer"}, | 124 | {25, nullptr, "ReleaseLastForegroundCaptureSharedBuffer"}, |
| 118 | {26, nullptr, "AcquireCallerAppletCaptureSharedBuffer"}, | 125 | {26, nullptr, "AcquireCallerAppletCaptureSharedBuffer"}, |
| 119 | {27, nullptr, "ReleaseCallerAppletCaptureSharedBuffer"}, | 126 | {27, nullptr, "ReleaseCallerAppletCaptureSharedBuffer"}, |
| 127 | // 6.0.0+ | ||
| 128 | {28, nullptr, "TakeScreenShotOfOwnLayerEx"}, | ||
| 120 | }; | 129 | }; |
| 130 | // clang-format on | ||
| 131 | |||
| 121 | RegisterHandlers(functions); | 132 | RegisterHandlers(functions); |
| 122 | } | 133 | } |
| 123 | 134 | ||
| @@ -128,6 +139,7 @@ IDebugFunctions::~IDebugFunctions() = default; | |||
| 128 | 139 | ||
| 129 | ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) | 140 | ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) |
| 130 | : ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) { | 141 | : ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) { |
| 142 | // clang-format off | ||
| 131 | static const FunctionInfo functions[] = { | 143 | static const FunctionInfo functions[] = { |
| 132 | {0, nullptr, "Exit"}, | 144 | {0, nullptr, "Exit"}, |
| 133 | {1, &ISelfController::LockExit, "LockExit"}, | 145 | {1, &ISelfController::LockExit, "LockExit"}, |
| @@ -136,10 +148,8 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger | |||
| 136 | {4, nullptr, "LeaveFatalSection"}, | 148 | {4, nullptr, "LeaveFatalSection"}, |
| 137 | {9, &ISelfController::GetLibraryAppletLaunchableEvent, "GetLibraryAppletLaunchableEvent"}, | 149 | {9, &ISelfController::GetLibraryAppletLaunchableEvent, "GetLibraryAppletLaunchableEvent"}, |
| 138 | {10, &ISelfController::SetScreenShotPermission, "SetScreenShotPermission"}, | 150 | {10, &ISelfController::SetScreenShotPermission, "SetScreenShotPermission"}, |
| 139 | {11, &ISelfController::SetOperationModeChangedNotification, | 151 | {11, &ISelfController::SetOperationModeChangedNotification, "SetOperationModeChangedNotification"}, |
| 140 | "SetOperationModeChangedNotification"}, | 152 | {12, &ISelfController::SetPerformanceModeChangedNotification, "SetPerformanceModeChangedNotification"}, |
| 141 | {12, &ISelfController::SetPerformanceModeChangedNotification, | ||
| 142 | "SetPerformanceModeChangedNotification"}, | ||
| 143 | {13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"}, | 153 | {13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"}, |
| 144 | {14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"}, | 154 | {14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"}, |
| 145 | {15, nullptr, "SetScreenShotAppletIdentityInfo"}, | 155 | {15, nullptr, "SetScreenShotAppletIdentityInfo"}, |
| @@ -165,7 +175,12 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger | |||
| 165 | {69, nullptr, "IsAutoSleepDisabled"}, | 175 | {69, nullptr, "IsAutoSleepDisabled"}, |
| 166 | {70, nullptr, "ReportMultimediaError"}, | 176 | {70, nullptr, "ReportMultimediaError"}, |
| 167 | {80, nullptr, "SetWirelessPriorityMode"}, | 177 | {80, nullptr, "SetWirelessPriorityMode"}, |
| 178 | {90, nullptr, "GetAccumulatedSuspendedTickValue"}, | ||
| 179 | {91, nullptr, "GetAccumulatedSuspendedTickChangedEvent"}, | ||
| 180 | {1000, nullptr, "GetDebugStorageChannel"}, | ||
| 168 | }; | 181 | }; |
| 182 | // clang-format on | ||
| 183 | |||
| 169 | RegisterHandlers(functions); | 184 | RegisterHandlers(functions); |
| 170 | 185 | ||
| 171 | auto& kernel = Core::System::GetInstance().Kernel(); | 186 | auto& kernel = Core::System::GetInstance().Kernel(); |
| @@ -312,6 +327,7 @@ void ISelfController::GetIdleTimeDetectionExtension(Kernel::HLERequestContext& c | |||
| 312 | } | 327 | } |
| 313 | 328 | ||
| 314 | ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") { | 329 | ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") { |
| 330 | // clang-format off | ||
| 315 | static const FunctionInfo functions[] = { | 331 | static const FunctionInfo functions[] = { |
| 316 | {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"}, | 332 | {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"}, |
| 317 | {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"}, | 333 | {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"}, |
| @@ -336,11 +352,12 @@ ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter" | |||
| 336 | {52, nullptr, "SwitchLcdBacklight"}, | 352 | {52, nullptr, "SwitchLcdBacklight"}, |
| 337 | {55, nullptr, "IsInControllerFirmwareUpdateSection"}, | 353 | {55, nullptr, "IsInControllerFirmwareUpdateSection"}, |
| 338 | {60, &ICommonStateGetter::GetDefaultDisplayResolution, "GetDefaultDisplayResolution"}, | 354 | {60, &ICommonStateGetter::GetDefaultDisplayResolution, "GetDefaultDisplayResolution"}, |
| 339 | {61, &ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent, | 355 | {61, &ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent, "GetDefaultDisplayResolutionChangeEvent"}, |
| 340 | "GetDefaultDisplayResolutionChangeEvent"}, | ||
| 341 | {62, nullptr, "GetHdcpAuthenticationState"}, | 356 | {62, nullptr, "GetHdcpAuthenticationState"}, |
| 342 | {63, nullptr, "GetHdcpAuthenticationStateChangeEvent"}, | 357 | {63, nullptr, "GetHdcpAuthenticationStateChangeEvent"}, |
| 343 | }; | 358 | }; |
| 359 | // clang-format on | ||
| 360 | |||
| 344 | RegisterHandlers(functions); | 361 | RegisterHandlers(functions); |
| 345 | 362 | ||
| 346 | auto& kernel = Core::System::GetInstance().Kernel(); | 363 | auto& kernel = Core::System::GetInstance().Kernel(); |
| @@ -432,11 +449,14 @@ class IStorageAccessor final : public ServiceFramework<IStorageAccessor> { | |||
| 432 | public: | 449 | public: |
| 433 | explicit IStorageAccessor(std::vector<u8> buffer) | 450 | explicit IStorageAccessor(std::vector<u8> buffer) |
| 434 | : ServiceFramework("IStorageAccessor"), buffer(std::move(buffer)) { | 451 | : ServiceFramework("IStorageAccessor"), buffer(std::move(buffer)) { |
| 452 | // clang-format off | ||
| 435 | static const FunctionInfo functions[] = { | 453 | static const FunctionInfo functions[] = { |
| 436 | {0, &IStorageAccessor::GetSize, "GetSize"}, | 454 | {0, &IStorageAccessor::GetSize, "GetSize"}, |
| 437 | {10, &IStorageAccessor::Write, "Write"}, | 455 | {10, &IStorageAccessor::Write, "Write"}, |
| 438 | {11, &IStorageAccessor::Read, "Read"}, | 456 | {11, &IStorageAccessor::Read, "Read"}, |
| 439 | }; | 457 | }; |
| 458 | // clang-format on | ||
| 459 | |||
| 440 | RegisterHandlers(functions); | 460 | RegisterHandlers(functions); |
| 441 | } | 461 | } |
| 442 | 462 | ||
| @@ -489,10 +509,13 @@ class IStorage final : public ServiceFramework<IStorage> { | |||
| 489 | public: | 509 | public: |
| 490 | explicit IStorage(std::vector<u8> buffer) | 510 | explicit IStorage(std::vector<u8> buffer) |
| 491 | : ServiceFramework("IStorage"), buffer(std::move(buffer)) { | 511 | : ServiceFramework("IStorage"), buffer(std::move(buffer)) { |
| 512 | // clang-format off | ||
| 492 | static const FunctionInfo functions[] = { | 513 | static const FunctionInfo functions[] = { |
| 493 | {0, &IStorage::Open, "Open"}, | 514 | {0, &IStorage::Open, "Open"}, |
| 494 | {1, nullptr, "OpenTransferStorage"}, | 515 | {1, nullptr, "OpenTransferStorage"}, |
| 495 | }; | 516 | }; |
| 517 | // clang-format on | ||
| 518 | |||
| 496 | RegisterHandlers(functions); | 519 | RegisterHandlers(functions); |
| 497 | } | 520 | } |
| 498 | 521 | ||
| @@ -512,6 +535,7 @@ private: | |||
| 512 | class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { | 535 | class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { |
| 513 | public: | 536 | public: |
| 514 | explicit ILibraryAppletAccessor() : ServiceFramework("ILibraryAppletAccessor") { | 537 | explicit ILibraryAppletAccessor() : ServiceFramework("ILibraryAppletAccessor") { |
| 538 | // clang-format off | ||
| 515 | static const FunctionInfo functions[] = { | 539 | static const FunctionInfo functions[] = { |
| 516 | {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"}, | 540 | {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"}, |
| 517 | {1, nullptr, "IsCompleted"}, | 541 | {1, nullptr, "IsCompleted"}, |
| @@ -532,6 +556,8 @@ public: | |||
| 532 | {150, nullptr, "RequestForAppletToGetForeground"}, | 556 | {150, nullptr, "RequestForAppletToGetForeground"}, |
| 533 | {160, nullptr, "GetIndirectLayerConsumerHandle"}, | 557 | {160, nullptr, "GetIndirectLayerConsumerHandle"}, |
| 534 | }; | 558 | }; |
| 559 | // clang-format on | ||
| 560 | |||
| 535 | RegisterHandlers(functions); | 561 | RegisterHandlers(functions); |
| 536 | 562 | ||
| 537 | auto& kernel = Core::System::GetInstance().Kernel(); | 563 | auto& kernel = Core::System::GetInstance().Kernel(); |
| @@ -624,13 +650,13 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) { | |||
| 624 | } | 650 | } |
| 625 | 651 | ||
| 626 | IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationFunctions") { | 652 | IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationFunctions") { |
| 653 | // clang-format off | ||
| 627 | static const FunctionInfo functions[] = { | 654 | static const FunctionInfo functions[] = { |
| 628 | {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"}, | 655 | {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"}, |
| 629 | {10, nullptr, "CreateApplicationAndPushAndRequestToStart"}, | 656 | {10, nullptr, "CreateApplicationAndPushAndRequestToStart"}, |
| 630 | {11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"}, | 657 | {11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"}, |
| 631 | {12, nullptr, "CreateApplicationAndRequestToStart"}, | 658 | {12, nullptr, "CreateApplicationAndRequestToStart"}, |
| 632 | {13, &IApplicationFunctions::CreateApplicationAndRequestToStartForQuest, | 659 | {13, &IApplicationFunctions::CreateApplicationAndRequestToStartForQuest, "CreateApplicationAndRequestToStartForQuest"}, |
| 633 | "CreateApplicationAndRequestToStartForQuest"}, | ||
| 634 | {20, &IApplicationFunctions::EnsureSaveData, "EnsureSaveData"}, | 660 | {20, &IApplicationFunctions::EnsureSaveData, "EnsureSaveData"}, |
| 635 | {21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"}, | 661 | {21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"}, |
| 636 | {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"}, | 662 | {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"}, |
| @@ -638,10 +664,8 @@ IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationF | |||
| 638 | {24, nullptr, "GetLaunchStorageInfoForDebug"}, | 664 | {24, nullptr, "GetLaunchStorageInfoForDebug"}, |
| 639 | {25, nullptr, "ExtendSaveData"}, | 665 | {25, nullptr, "ExtendSaveData"}, |
| 640 | {26, nullptr, "GetSaveDataSize"}, | 666 | {26, nullptr, "GetSaveDataSize"}, |
| 641 | {30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, | 667 | {30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"}, |
| 642 | "BeginBlockingHomeButtonShortAndLongPressed"}, | 668 | {31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"}, |
| 643 | {31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, | ||
| 644 | "EndBlockingHomeButtonShortAndLongPressed"}, | ||
| 645 | {32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"}, | 669 | {32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"}, |
| 646 | {33, &IApplicationFunctions::EndBlockingHomeButton, "EndBlockingHomeButton"}, | 670 | {33, &IApplicationFunctions::EndBlockingHomeButton, "EndBlockingHomeButton"}, |
| 647 | {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"}, | 671 | {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"}, |
| @@ -666,6 +690,8 @@ IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationF | |||
| 666 | {1000, nullptr, "CreateMovieMaker"}, | 690 | {1000, nullptr, "CreateMovieMaker"}, |
| 667 | {1001, nullptr, "PrepareForJit"}, | 691 | {1001, nullptr, "PrepareForJit"}, |
| 668 | }; | 692 | }; |
| 693 | // clang-format on | ||
| 694 | |||
| 669 | RegisterHandlers(functions); | 695 | RegisterHandlers(functions); |
| 670 | } | 696 | } |
| 671 | 697 | ||
| @@ -804,9 +830,11 @@ void InstallInterfaces(SM::ServiceManager& service_manager, | |||
| 804 | std::make_shared<IdleSys>()->InstallAsService(service_manager); | 830 | std::make_shared<IdleSys>()->InstallAsService(service_manager); |
| 805 | std::make_shared<OMM>()->InstallAsService(service_manager); | 831 | std::make_shared<OMM>()->InstallAsService(service_manager); |
| 806 | std::make_shared<SPSM>()->InstallAsService(service_manager); | 832 | std::make_shared<SPSM>()->InstallAsService(service_manager); |
| 833 | std::make_shared<TCAP>()->InstallAsService(service_manager); | ||
| 807 | } | 834 | } |
| 808 | 835 | ||
| 809 | IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") { | 836 | IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") { |
| 837 | // clang-format off | ||
| 810 | static const FunctionInfo functions[] = { | 838 | static const FunctionInfo functions[] = { |
| 811 | {10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"}, | 839 | {10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"}, |
| 812 | {11, nullptr, "LockForeground"}, | 840 | {11, nullptr, "LockForeground"}, |
| @@ -815,7 +843,10 @@ IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions" | |||
| 815 | {21, nullptr, "GetPopFromGeneralChannelEvent"}, | 843 | {21, nullptr, "GetPopFromGeneralChannelEvent"}, |
| 816 | {30, nullptr, "GetHomeButtonWriterLockAccessor"}, | 844 | {30, nullptr, "GetHomeButtonWriterLockAccessor"}, |
| 817 | {31, nullptr, "GetWriterLockAccessorEx"}, | 845 | {31, nullptr, "GetWriterLockAccessorEx"}, |
| 846 | {100, nullptr, "PopRequestLaunchApplicationForDebug"}, | ||
| 818 | }; | 847 | }; |
| 848 | // clang-format on | ||
| 849 | |||
| 819 | RegisterHandlers(functions); | 850 | RegisterHandlers(functions); |
| 820 | } | 851 | } |
| 821 | 852 | ||
| @@ -828,6 +859,7 @@ void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx) | |||
| 828 | } | 859 | } |
| 829 | 860 | ||
| 830 | IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStateController") { | 861 | IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStateController") { |
| 862 | // clang-format off | ||
| 831 | static const FunctionInfo functions[] = { | 863 | static const FunctionInfo functions[] = { |
| 832 | {0, nullptr, "RequestToEnterSleep"}, | 864 | {0, nullptr, "RequestToEnterSleep"}, |
| 833 | {1, nullptr, "EnterSleep"}, | 865 | {1, nullptr, "EnterSleep"}, |
| @@ -841,18 +873,23 @@ IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStat | |||
| 841 | {14, nullptr, "ShouldSleepOnBoot"}, | 873 | {14, nullptr, "ShouldSleepOnBoot"}, |
| 842 | {15, nullptr, "GetHdcpAuthenticationFailedEvent"}, | 874 | {15, nullptr, "GetHdcpAuthenticationFailedEvent"}, |
| 843 | }; | 875 | }; |
| 876 | // clang-format on | ||
| 877 | |||
| 844 | RegisterHandlers(functions); | 878 | RegisterHandlers(functions); |
| 845 | } | 879 | } |
| 846 | 880 | ||
| 847 | IGlobalStateController::~IGlobalStateController() = default; | 881 | IGlobalStateController::~IGlobalStateController() = default; |
| 848 | 882 | ||
| 849 | IApplicationCreator::IApplicationCreator() : ServiceFramework("IApplicationCreator") { | 883 | IApplicationCreator::IApplicationCreator() : ServiceFramework("IApplicationCreator") { |
| 884 | // clang-format off | ||
| 850 | static const FunctionInfo functions[] = { | 885 | static const FunctionInfo functions[] = { |
| 851 | {0, nullptr, "CreateApplication"}, | 886 | {0, nullptr, "CreateApplication"}, |
| 852 | {1, nullptr, "PopLaunchRequestedApplication"}, | 887 | {1, nullptr, "PopLaunchRequestedApplication"}, |
| 853 | {10, nullptr, "CreateSystemApplication"}, | 888 | {10, nullptr, "CreateSystemApplication"}, |
| 854 | {100, nullptr, "PopFloatingApplicationForDevelopment"}, | 889 | {100, nullptr, "PopFloatingApplicationForDevelopment"}, |
| 855 | }; | 890 | }; |
| 891 | // clang-format on | ||
| 892 | |||
| 856 | RegisterHandlers(functions); | 893 | RegisterHandlers(functions); |
| 857 | } | 894 | } |
| 858 | 895 | ||
| @@ -860,6 +897,7 @@ IApplicationCreator::~IApplicationCreator() = default; | |||
| 860 | 897 | ||
| 861 | IProcessWindingController::IProcessWindingController() | 898 | IProcessWindingController::IProcessWindingController() |
| 862 | : ServiceFramework("IProcessWindingController") { | 899 | : ServiceFramework("IProcessWindingController") { |
| 900 | // clang-format off | ||
| 863 | static const FunctionInfo functions[] = { | 901 | static const FunctionInfo functions[] = { |
| 864 | {0, nullptr, "GetLaunchReason"}, | 902 | {0, nullptr, "GetLaunchReason"}, |
| 865 | {11, nullptr, "OpenCallingLibraryApplet"}, | 903 | {11, nullptr, "OpenCallingLibraryApplet"}, |
| @@ -870,6 +908,8 @@ IProcessWindingController::IProcessWindingController() | |||
| 870 | {40, nullptr, "ReserveToStartAndWaitAndUnwindThis"}, | 908 | {40, nullptr, "ReserveToStartAndWaitAndUnwindThis"}, |
| 871 | {41, nullptr, "ReserveToStartAndWait"}, | 909 | {41, nullptr, "ReserveToStartAndWait"}, |
| 872 | }; | 910 | }; |
| 911 | // clang-format on | ||
| 912 | |||
| 873 | RegisterHandlers(functions); | 913 | RegisterHandlers(functions); |
| 874 | } | 914 | } |
| 875 | 915 | ||
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp index 4296c255e..68ea778e8 100644 --- a/src/core/hle/service/am/applet_ae.cpp +++ b/src/core/hle/service/am/applet_ae.cpp | |||
| @@ -211,6 +211,7 @@ void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) { | |||
| 211 | 211 | ||
| 212 | AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) | 212 | AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) |
| 213 | : ServiceFramework("appletAE"), nvflinger(std::move(nvflinger)) { | 213 | : ServiceFramework("appletAE"), nvflinger(std::move(nvflinger)) { |
| 214 | // clang-format off | ||
| 214 | static const FunctionInfo functions[] = { | 215 | static const FunctionInfo functions[] = { |
| 215 | {100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"}, | 216 | {100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"}, |
| 216 | {200, &AppletAE::OpenLibraryAppletProxyOld, "OpenLibraryAppletProxyOld"}, | 217 | {200, &AppletAE::OpenLibraryAppletProxyOld, "OpenLibraryAppletProxyOld"}, |
| @@ -218,7 +219,10 @@ AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) | |||
| 218 | {300, nullptr, "OpenOverlayAppletProxy"}, | 219 | {300, nullptr, "OpenOverlayAppletProxy"}, |
| 219 | {350, nullptr, "OpenSystemApplicationProxy"}, | 220 | {350, nullptr, "OpenSystemApplicationProxy"}, |
| 220 | {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"}, | 221 | {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"}, |
| 222 | {401, nullptr, "GetSystemAppletControllerForDebug"}, | ||
| 221 | }; | 223 | }; |
| 224 | // clang-format on | ||
| 225 | |||
| 222 | RegisterHandlers(functions); | 226 | RegisterHandlers(functions); |
| 223 | } | 227 | } |
| 224 | 228 | ||
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp index e45cf6e20..60717afd9 100644 --- a/src/core/hle/service/am/applet_oe.cpp +++ b/src/core/hle/service/am/applet_oe.cpp | |||
| @@ -14,6 +14,7 @@ class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { | |||
| 14 | public: | 14 | public: |
| 15 | explicit IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) | 15 | explicit IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) |
| 16 | : ServiceFramework("IApplicationProxy"), nvflinger(std::move(nvflinger)) { | 16 | : ServiceFramework("IApplicationProxy"), nvflinger(std::move(nvflinger)) { |
| 17 | // clang-format off | ||
| 17 | static const FunctionInfo functions[] = { | 18 | static const FunctionInfo functions[] = { |
| 18 | {0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"}, | 19 | {0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"}, |
| 19 | {1, &IApplicationProxy::GetSelfController, "GetSelfController"}, | 20 | {1, &IApplicationProxy::GetSelfController, "GetSelfController"}, |
| @@ -25,6 +26,8 @@ public: | |||
| 25 | {20, &IApplicationProxy::GetApplicationFunctions, "GetApplicationFunctions"}, | 26 | {20, &IApplicationProxy::GetApplicationFunctions, "GetApplicationFunctions"}, |
| 26 | {1000, &IApplicationProxy::GetDebugFunctions, "GetDebugFunctions"}, | 27 | {1000, &IApplicationProxy::GetDebugFunctions, "GetDebugFunctions"}, |
| 27 | }; | 28 | }; |
| 29 | // clang-format on | ||
| 30 | |||
| 28 | RegisterHandlers(functions); | 31 | RegisterHandlers(functions); |
| 29 | } | 32 | } |
| 30 | 33 | ||
diff --git a/src/core/hle/service/am/idle.cpp b/src/core/hle/service/am/idle.cpp index 0e3088bc8..f814fe2c0 100644 --- a/src/core/hle/service/am/idle.cpp +++ b/src/core/hle/service/am/idle.cpp | |||
| @@ -12,9 +12,9 @@ IdleSys::IdleSys() : ServiceFramework{"idle:sys"} { | |||
| 12 | {0, nullptr, "GetAutoPowerDownEvent"}, | 12 | {0, nullptr, "GetAutoPowerDownEvent"}, |
| 13 | {1, nullptr, "Unknown1"}, | 13 | {1, nullptr, "Unknown1"}, |
| 14 | {2, nullptr, "Unknown2"}, | 14 | {2, nullptr, "Unknown2"}, |
| 15 | {3, nullptr, "Unknown3"}, | 15 | {3, nullptr, "SetHandlingContext"}, |
| 16 | {4, nullptr, "Unknown4"}, | 16 | {4, nullptr, "LoadAndApplySettings"}, |
| 17 | {5, nullptr, "Unknown5"}, | 17 | {5, nullptr, "ReportUserIsActive"}, |
| 18 | }; | 18 | }; |
| 19 | // clang-format on | 19 | // clang-format on |
| 20 | 20 | ||
diff --git a/src/core/hle/service/am/tcap.cpp b/src/core/hle/service/am/tcap.cpp new file mode 100644 index 000000000..a75cbdda8 --- /dev/null +++ b/src/core/hle/service/am/tcap.cpp | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/service/am/tcap.h" | ||
| 6 | |||
| 7 | namespace Service::AM { | ||
| 8 | |||
| 9 | TCAP::TCAP() : ServiceFramework{"tcap"} { | ||
| 10 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, nullptr, "GetContinuousHighSkinTemperatureEvent"}, | ||
| 13 | {1, nullptr, "SetOperationMode"}, | ||
| 14 | {2, nullptr, "LoadAndApplySettings"}, | ||
| 15 | }; | ||
| 16 | // clang-format on | ||
| 17 | |||
| 18 | RegisterHandlers(functions); | ||
| 19 | } | ||
| 20 | |||
| 21 | TCAP::~TCAP() = default; | ||
| 22 | |||
| 23 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/tcap.h b/src/core/hle/service/am/tcap.h new file mode 100644 index 000000000..2021b55d1 --- /dev/null +++ b/src/core/hle/service/am/tcap.h | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | class TCAP final : public ServiceFramework<TCAP> { | ||
| 12 | public: | ||
| 13 | explicit TCAP(); | ||
| 14 | ~TCAP() override; | ||
| 15 | }; | ||
| 16 | |||
| 17 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index b26593b4f..b06e65a77 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -26,7 +26,11 @@ constexpr s32 HID_JOYSTICK_MAX = 0x7fff; | |||
| 26 | constexpr s32 HID_JOYSTICK_MIN = -0x7fff; | 26 | constexpr s32 HID_JOYSTICK_MIN = -0x7fff; |
| 27 | constexpr std::size_t NPAD_OFFSET = 0x9A00; | 27 | constexpr std::size_t NPAD_OFFSET = 0x9A00; |
| 28 | constexpr u32 BATTERY_FULL = 2; | 28 | constexpr u32 BATTERY_FULL = 2; |
| 29 | 29 | constexpr u32 NPAD_HANDHELD = 32; | |
| 30 | constexpr u32 NPAD_UNKNOWN = 16; // TODO(ogniK): What is this? | ||
| 31 | constexpr u32 MAX_NPAD_ID = 7; | ||
| 32 | constexpr Controller_NPad::NPadControllerType PREFERRED_CONTROLLER = | ||
| 33 | Controller_NPad::NPadControllerType::JoyDual; | ||
| 30 | constexpr std::array<u32, 10> npad_id_list{ | 34 | constexpr std::array<u32, 10> npad_id_list{ |
| 31 | 0, 1, 2, 3, 4, 5, 6, 7, 32, 16, | 35 | 0, 1, 2, 3, 4, 5, 6, 7, 32, 16, |
| 32 | }; | 36 | }; |
| @@ -121,7 +125,7 @@ void Controller_NPad::OnInit() { | |||
| 121 | supported_npad_id_types.resize(npad_id_list.size()); | 125 | supported_npad_id_types.resize(npad_id_list.size()); |
| 122 | std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), | 126 | std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), |
| 123 | npad_id_list.size() * sizeof(u32)); | 127 | npad_id_list.size() * sizeof(u32)); |
| 124 | AddNewController(NPadControllerType::JoyDual); | 128 | AddNewController(PREFERRED_CONTROLLER); |
| 125 | } | 129 | } |
| 126 | } | 130 | } |
| 127 | 131 | ||
| @@ -218,6 +222,51 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { | |||
| 218 | rstick_entry.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX); | 222 | rstick_entry.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX); |
| 219 | rstick_entry.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX); | 223 | rstick_entry.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX); |
| 220 | 224 | ||
| 225 | if (controller_type == NPadControllerType::JoyLeft || | ||
| 226 | controller_type == NPadControllerType::JoyRight) { | ||
| 227 | if (npad.properties.is_horizontal) { | ||
| 228 | ControllerPadState state{}; | ||
| 229 | AnalogPosition temp_lstick_entry{}; | ||
| 230 | AnalogPosition temp_rstick_entry{}; | ||
| 231 | if (controller_type == NPadControllerType::JoyLeft) { | ||
| 232 | state.d_down.Assign(pad_state.d_left.Value()); | ||
| 233 | state.d_left.Assign(pad_state.d_up.Value()); | ||
| 234 | state.d_right.Assign(pad_state.d_down.Value()); | ||
| 235 | state.d_up.Assign(pad_state.d_right.Value()); | ||
| 236 | state.l.Assign(pad_state.l.Value() | pad_state.sl.Value()); | ||
| 237 | state.r.Assign(pad_state.r.Value() | pad_state.sr.Value()); | ||
| 238 | |||
| 239 | state.zl.Assign(pad_state.zl.Value()); | ||
| 240 | state.plus.Assign(pad_state.minus.Value()); | ||
| 241 | |||
| 242 | temp_lstick_entry = lstick_entry; | ||
| 243 | temp_rstick_entry = rstick_entry; | ||
| 244 | std::swap(temp_lstick_entry.x, temp_lstick_entry.y); | ||
| 245 | std::swap(temp_rstick_entry.x, temp_rstick_entry.y); | ||
| 246 | temp_lstick_entry.y *= -1; | ||
| 247 | } else if (controller_type == NPadControllerType::JoyRight) { | ||
| 248 | state.x.Assign(pad_state.a.Value()); | ||
| 249 | state.a.Assign(pad_state.b.Value()); | ||
| 250 | state.b.Assign(pad_state.y.Value()); | ||
| 251 | state.y.Assign(pad_state.b.Value()); | ||
| 252 | |||
| 253 | state.l.Assign(pad_state.l.Value() | pad_state.sl.Value()); | ||
| 254 | state.r.Assign(pad_state.r.Value() | pad_state.sr.Value()); | ||
| 255 | state.zr.Assign(pad_state.zr.Value()); | ||
| 256 | state.plus.Assign(pad_state.plus.Value()); | ||
| 257 | |||
| 258 | temp_lstick_entry = lstick_entry; | ||
| 259 | temp_rstick_entry = rstick_entry; | ||
| 260 | std::swap(temp_lstick_entry.x, temp_lstick_entry.y); | ||
| 261 | std::swap(temp_rstick_entry.x, temp_rstick_entry.y); | ||
| 262 | temp_rstick_entry.x *= -1; | ||
| 263 | } | ||
| 264 | pad_state.raw = state.raw; | ||
| 265 | lstick_entry = temp_lstick_entry; | ||
| 266 | rstick_entry = temp_rstick_entry; | ||
| 267 | } | ||
| 268 | } | ||
| 269 | |||
| 221 | auto& main_controller = | 270 | auto& main_controller = |
| 222 | npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; | 271 | npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; |
| 223 | auto& handheld_entry = | 272 | auto& handheld_entry = |
| @@ -320,6 +369,16 @@ void Controller_NPad::SetSupportedNPadIdTypes(u8* data, std::size_t length) { | |||
| 320 | supported_npad_id_types.clear(); | 369 | supported_npad_id_types.clear(); |
| 321 | supported_npad_id_types.resize(length / sizeof(u32)); | 370 | supported_npad_id_types.resize(length / sizeof(u32)); |
| 322 | std::memcpy(supported_npad_id_types.data(), data, length); | 371 | std::memcpy(supported_npad_id_types.data(), data, length); |
| 372 | for (std::size_t i = 0; i < connected_controllers.size(); i++) { | ||
| 373 | auto& controller = connected_controllers[i]; | ||
| 374 | if (!controller.is_connected) { | ||
| 375 | continue; | ||
| 376 | } | ||
| 377 | if (!IsControllerSupported(PREFERRED_CONTROLLER)) { | ||
| 378 | controller.type = DecideBestController(PREFERRED_CONTROLLER); | ||
| 379 | InitNewlyAddedControler(i); | ||
| 380 | } | ||
| 381 | } | ||
| 323 | } | 382 | } |
| 324 | 383 | ||
| 325 | void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) { | 384 | void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) { |
| @@ -351,11 +410,11 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids, | |||
| 351 | for (std::size_t i = 0; i < controller_ids.size(); i++) { | 410 | for (std::size_t i = 0; i < controller_ids.size(); i++) { |
| 352 | std::size_t controller_pos = i; | 411 | std::size_t controller_pos = i; |
| 353 | // Handheld controller conversion | 412 | // Handheld controller conversion |
| 354 | if (controller_pos == 32) { | 413 | if (controller_pos == NPAD_HANDHELD) { |
| 355 | controller_pos = 8; | 414 | controller_pos = 8; |
| 356 | } | 415 | } |
| 357 | // Unknown controller conversion | 416 | // Unknown controller conversion |
| 358 | if (controller_pos == 16) { | 417 | if (controller_pos == NPAD_UNKNOWN) { |
| 359 | controller_pos = 9; | 418 | controller_pos = 9; |
| 360 | } | 419 | } |
| 361 | if (connected_controllers[controller_pos].is_connected) { | 420 | if (connected_controllers[controller_pos].is_connected) { |
| @@ -433,4 +492,128 @@ Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { | |||
| 433 | void Controller_NPad::SetVibrationEnabled(bool can_vibrate) { | 492 | void Controller_NPad::SetVibrationEnabled(bool can_vibrate) { |
| 434 | can_controllers_vibrate = can_vibrate; | 493 | can_controllers_vibrate = can_vibrate; |
| 435 | } | 494 | } |
| 495 | |||
| 496 | bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const { | ||
| 497 | const bool support_handheld = | ||
| 498 | std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), NPAD_HANDHELD) != | ||
| 499 | supported_npad_id_types.end(); | ||
| 500 | if (controller == NPadControllerType::Handheld) { | ||
| 501 | // Handheld is not even a supported type, lets stop here | ||
| 502 | if (!support_handheld) { | ||
| 503 | return false; | ||
| 504 | } | ||
| 505 | // Handheld should not be supported in docked mode | ||
| 506 | if (Settings::values.use_docked_mode) { | ||
| 507 | return false; | ||
| 508 | } | ||
| 509 | |||
| 510 | return true; | ||
| 511 | } | ||
| 512 | if (std::any_of(supported_npad_id_types.begin(), supported_npad_id_types.end(), | ||
| 513 | [](u32 npad_id) { return npad_id <= MAX_NPAD_ID; })) { | ||
| 514 | switch (controller) { | ||
| 515 | case NPadControllerType::ProController: | ||
| 516 | return style.pro_controller; | ||
| 517 | case NPadControllerType::JoyDual: | ||
| 518 | return style.joycon_dual; | ||
| 519 | case NPadControllerType::JoyLeft: | ||
| 520 | return style.joycon_left; | ||
| 521 | case NPadControllerType::JoyRight: | ||
| 522 | return style.joycon_right; | ||
| 523 | case NPadControllerType::Pokeball: | ||
| 524 | return style.pokeball; | ||
| 525 | default: | ||
| 526 | return false; | ||
| 527 | } | ||
| 528 | } | ||
| 529 | return false; | ||
| 530 | } | ||
| 531 | |||
| 532 | Controller_NPad::NPadControllerType Controller_NPad::DecideBestController( | ||
| 533 | NPadControllerType priority) const { | ||
| 534 | if (IsControllerSupported(priority)) { | ||
| 535 | return priority; | ||
| 536 | } | ||
| 537 | const auto is_docked = Settings::values.use_docked_mode; | ||
| 538 | if (is_docked && priority == NPadControllerType::Handheld) { | ||
| 539 | priority = NPadControllerType::JoyDual; | ||
| 540 | if (IsControllerSupported(priority)) { | ||
| 541 | return priority; | ||
| 542 | } | ||
| 543 | } | ||
| 544 | std::vector<NPadControllerType> priority_list; | ||
| 545 | switch (priority) { | ||
| 546 | case NPadControllerType::ProController: | ||
| 547 | priority_list.push_back(NPadControllerType::JoyDual); | ||
| 548 | if (!is_docked) { | ||
| 549 | priority_list.push_back(NPadControllerType::Handheld); | ||
| 550 | } | ||
| 551 | priority_list.push_back(NPadControllerType::JoyLeft); | ||
| 552 | priority_list.push_back(NPadControllerType::JoyRight); | ||
| 553 | priority_list.push_back(NPadControllerType::Pokeball); | ||
| 554 | break; | ||
| 555 | case NPadControllerType::Handheld: | ||
| 556 | priority_list.push_back(NPadControllerType::JoyDual); | ||
| 557 | priority_list.push_back(NPadControllerType::ProController); | ||
| 558 | priority_list.push_back(NPadControllerType::JoyLeft); | ||
| 559 | priority_list.push_back(NPadControllerType::JoyRight); | ||
| 560 | priority_list.push_back(NPadControllerType::Pokeball); | ||
| 561 | break; | ||
| 562 | case NPadControllerType::JoyDual: | ||
| 563 | if (!is_docked) { | ||
| 564 | priority_list.push_back(NPadControllerType::Handheld); | ||
| 565 | } | ||
| 566 | priority_list.push_back(NPadControllerType::ProController); | ||
| 567 | priority_list.push_back(NPadControllerType::JoyLeft); | ||
| 568 | priority_list.push_back(NPadControllerType::JoyRight); | ||
| 569 | priority_list.push_back(NPadControllerType::Pokeball); | ||
| 570 | break; | ||
| 571 | case NPadControllerType::JoyLeft: | ||
| 572 | priority_list.push_back(NPadControllerType::JoyRight); | ||
| 573 | priority_list.push_back(NPadControllerType::JoyDual); | ||
| 574 | if (!is_docked) { | ||
| 575 | priority_list.push_back(NPadControllerType::Handheld); | ||
| 576 | } | ||
| 577 | priority_list.push_back(NPadControllerType::ProController); | ||
| 578 | priority_list.push_back(NPadControllerType::Pokeball); | ||
| 579 | break; | ||
| 580 | case NPadControllerType::JoyRight: | ||
| 581 | priority_list.push_back(NPadControllerType::JoyLeft); | ||
| 582 | priority_list.push_back(NPadControllerType::JoyDual); | ||
| 583 | if (!is_docked) { | ||
| 584 | priority_list.push_back(NPadControllerType::Handheld); | ||
| 585 | } | ||
| 586 | priority_list.push_back(NPadControllerType::ProController); | ||
| 587 | priority_list.push_back(NPadControllerType::Pokeball); | ||
| 588 | break; | ||
| 589 | case NPadControllerType::Pokeball: | ||
| 590 | priority_list.push_back(NPadControllerType::JoyLeft); | ||
| 591 | priority_list.push_back(NPadControllerType::JoyRight); | ||
| 592 | priority_list.push_back(NPadControllerType::JoyDual); | ||
| 593 | if (!is_docked) { | ||
| 594 | priority_list.push_back(NPadControllerType::Handheld); | ||
| 595 | } | ||
| 596 | priority_list.push_back(NPadControllerType::ProController); | ||
| 597 | break; | ||
| 598 | default: | ||
| 599 | priority_list.push_back(NPadControllerType::JoyDual); | ||
| 600 | if (!is_docked) { | ||
| 601 | priority_list.push_back(NPadControllerType::Handheld); | ||
| 602 | } | ||
| 603 | priority_list.push_back(NPadControllerType::ProController); | ||
| 604 | priority_list.push_back(NPadControllerType::JoyLeft); | ||
| 605 | priority_list.push_back(NPadControllerType::JoyRight); | ||
| 606 | priority_list.push_back(NPadControllerType::JoyDual); | ||
| 607 | } | ||
| 608 | |||
| 609 | const auto iter = std::find_if(priority_list.begin(), priority_list.end(), | ||
| 610 | [this](auto type) { return IsControllerSupported(type); }); | ||
| 611 | if (iter == priority_list.end()) { | ||
| 612 | UNIMPLEMENTED_MSG("Could not find supported controller!"); | ||
| 613 | return priority; | ||
| 614 | } | ||
| 615 | |||
| 616 | return *iter; | ||
| 617 | } | ||
| 618 | |||
| 436 | } // namespace Service::HID | 619 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 7c0f93acf..ac86985ff 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -283,5 +283,7 @@ private: | |||
| 283 | bool can_controllers_vibrate{true}; | 283 | bool can_controllers_vibrate{true}; |
| 284 | 284 | ||
| 285 | void InitNewlyAddedControler(std::size_t controller_idx); | 285 | void InitNewlyAddedControler(std::size_t controller_idx); |
| 286 | bool IsControllerSupported(NPadControllerType controller) const; | ||
| 287 | NPadControllerType DecideBestController(NPadControllerType priority) const; | ||
| 286 | }; | 288 | }; |
| 287 | } // namespace Service::HID | 289 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index beb89218a..a9aa9ec78 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -827,6 +827,7 @@ public: | |||
| 827 | {11, nullptr, "EnableJoyPollingReceiveMode"}, | 827 | {11, nullptr, "EnableJoyPollingReceiveMode"}, |
| 828 | {12, nullptr, "DisableJoyPollingReceiveMode"}, | 828 | {12, nullptr, "DisableJoyPollingReceiveMode"}, |
| 829 | {13, nullptr, "GetPollingData"}, | 829 | {13, nullptr, "GetPollingData"}, |
| 830 | {14, nullptr, "SetStatusManagerType"}, | ||
| 830 | }; | 831 | }; |
| 831 | // clang-format on | 832 | // clang-format on |
| 832 | 833 | ||
diff --git a/src/core/hle/service/lbl/lbl.cpp b/src/core/hle/service/lbl/lbl.cpp index 7321584e1..164c57e18 100644 --- a/src/core/hle/service/lbl/lbl.cpp +++ b/src/core/hle/service/lbl/lbl.cpp | |||
| @@ -18,35 +18,35 @@ public: | |||
| 18 | explicit LBL() : ServiceFramework{"lbl"} { | 18 | explicit LBL() : ServiceFramework{"lbl"} { |
| 19 | // clang-format off | 19 | // clang-format off |
| 20 | static const FunctionInfo functions[] = { | 20 | static const FunctionInfo functions[] = { |
| 21 | {0, nullptr, "Unknown1"}, | 21 | {0, nullptr, "SaveCurrentSetting"}, |
| 22 | {1, nullptr, "Unknown2"}, | 22 | {1, nullptr, "LoadCurrentSetting"}, |
| 23 | {2, nullptr, "Unknown3"}, | 23 | {2, nullptr, "SetCurrentBrightnessSetting"}, |
| 24 | {3, nullptr, "GetCurrentBacklightLevel"}, | 24 | {3, nullptr, "GetCurrentBrightnessSetting"}, |
| 25 | {4, nullptr, "Unknown4"}, | 25 | {4, nullptr, "ApplyCurrentBrightnessSettingToBacklight"}, |
| 26 | {5, nullptr, "GetAlsComputedBacklightLevel"}, | 26 | {5, nullptr, "GetBrightnessSettingAppliedToBacklight"}, |
| 27 | {6, nullptr, "TurnOffBacklight"}, | 27 | {6, nullptr, "SwitchBacklightOn"}, |
| 28 | {7, nullptr, "TurnOnBacklight"}, | 28 | {7, nullptr, "SwitchBacklightOff"}, |
| 29 | {8, nullptr, "GetBacklightStatus"}, | 29 | {8, nullptr, "GetBacklightSwitchStatus"}, |
| 30 | {9, nullptr, "Unknown5"}, | 30 | {9, nullptr, "EnableDimming"}, |
| 31 | {10, nullptr, "Unknown6"}, | 31 | {10, nullptr, "DisableDimming"}, |
| 32 | {11, nullptr, "Unknown7"}, | 32 | {11, nullptr, "IsDimmingEnabled"}, |
| 33 | {12, nullptr, "Unknown8"}, | 33 | {12, nullptr, "EnableAutoBrightnessControl"}, |
| 34 | {13, nullptr, "Unknown9"}, | 34 | {13, nullptr, "DisableAutoBrightnessControl"}, |
| 35 | {14, nullptr, "Unknown10"}, | 35 | {14, nullptr, "IsAutoBrightnessControlEnabled"}, |
| 36 | {15, nullptr, "GetAutoBrightnessSetting"}, | 36 | {15, nullptr, "SetAmbientLightSensorValue"}, |
| 37 | {16, nullptr, "ReadRawLightSensor"}, | 37 | {16, nullptr, "GetAmbientLightSensorValue"}, |
| 38 | {17, nullptr, "Unknown11"}, | 38 | {17, nullptr, "SetBrightnessReflectionDelayLevel"}, |
| 39 | {18, nullptr, "Unknown12"}, | 39 | {18, nullptr, "GetBrightnessReflectionDelayLevel"}, |
| 40 | {19, nullptr, "Unknown13"}, | 40 | {19, nullptr, "SetCurrentBrightnessMapping"}, |
| 41 | {20, nullptr, "Unknown14"}, | 41 | {20, nullptr, "GetCurrentBrightnessMapping"}, |
| 42 | {21, nullptr, "Unknown15"}, | 42 | {21, nullptr, "SetCurrentAmbientLightSensorMapping"}, |
| 43 | {22, nullptr, "Unknown16"}, | 43 | {22, nullptr, "GetCurrentAmbientLightSensorMapping"}, |
| 44 | {23, nullptr, "Unknown17"}, | 44 | {23, nullptr, "IsAmbientLightSensorAvailable"}, |
| 45 | {24, nullptr, "Unknown18"}, | 45 | {24, nullptr, "SetCurrentBrightnessSettingForVrMode"}, |
| 46 | {25, nullptr, "Unknown19"}, | 46 | {25, nullptr, "GetCurrentBrightnessSettingForVrMode"}, |
| 47 | {26, &LBL::EnableVrMode, "EnableVrMode"}, | 47 | {26, &LBL::EnableVrMode, "EnableVrMode"}, |
| 48 | {27, &LBL::DisableVrMode, "DisableVrMode"}, | 48 | {27, &LBL::DisableVrMode, "DisableVrMode"}, |
| 49 | {28, &LBL::GetVrMode, "GetVrMode"}, | 49 | {28, &LBL::IsVrModeEnabled, "IsVrModeEnabled"}, |
| 50 | }; | 50 | }; |
| 51 | // clang-format on | 51 | // clang-format on |
| 52 | 52 | ||
| @@ -72,7 +72,7 @@ private: | |||
| 72 | LOG_DEBUG(Service_LBL, "called"); | 72 | LOG_DEBUG(Service_LBL, "called"); |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | void GetVrMode(Kernel::HLERequestContext& ctx) { | 75 | void IsVrModeEnabled(Kernel::HLERequestContext& ctx) { |
| 76 | IPC::ResponseBuilder rb{ctx, 3}; | 76 | IPC::ResponseBuilder rb{ctx, 3}; |
| 77 | rb.Push(RESULT_SUCCESS); | 77 | rb.Push(RESULT_SUCCESS); |
| 78 | rb.Push(vr_mode_enabled); | 78 | rb.Push(vr_mode_enabled); |
diff --git a/src/core/hle/service/npns/npns.cpp b/src/core/hle/service/npns/npns.cpp new file mode 100644 index 000000000..ccb6f9da9 --- /dev/null +++ b/src/core/hle/service/npns/npns.cpp | |||
| @@ -0,0 +1,88 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "core/hle/service/npns/npns.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | #include "core/hle/service/sm/sm.h" | ||
| 10 | |||
| 11 | namespace Service::NPNS { | ||
| 12 | |||
| 13 | class NPNS_S final : public ServiceFramework<NPNS_S> { | ||
| 14 | public: | ||
| 15 | explicit NPNS_S() : ServiceFramework{"npns:s"} { | ||
| 16 | // clang-format off | ||
| 17 | static const FunctionInfo functions[] = { | ||
| 18 | {1, nullptr, "ListenAll"}, | ||
| 19 | {2, nullptr, "ListenTo"}, | ||
| 20 | {3, nullptr, "Receive"}, | ||
| 21 | {4, nullptr, "ReceiveRaw"}, | ||
| 22 | {5, nullptr, "GetReceiveEvent"}, | ||
| 23 | {6, nullptr, "ListenUndelivered"}, | ||
| 24 | {7, nullptr, "GetStateChangeEVent"}, | ||
| 25 | {11, nullptr, "SubscribeTopic"}, | ||
| 26 | {12, nullptr, "UnsubscribeTopic"}, | ||
| 27 | {13, nullptr, "QueryIsTopicExist"}, | ||
| 28 | {21, nullptr, "CreateToken"}, | ||
| 29 | {22, nullptr, "CreateTokenWithApplicationId"}, | ||
| 30 | {23, nullptr, "DestroyToken"}, | ||
| 31 | {24, nullptr, "DestroyTokenWithApplicationId"}, | ||
| 32 | {25, nullptr, "QueryIsTokenValid"}, | ||
| 33 | {31, nullptr, "UploadTokenToBaaS"}, | ||
| 34 | {32, nullptr, "DestroyTokenForBaaS"}, | ||
| 35 | {33, nullptr, "CreateTokenForBaaS"}, | ||
| 36 | {34, nullptr, "SetBaaSDeviceAccountIdList"}, | ||
| 37 | {101, nullptr, "Suspend"}, | ||
| 38 | {102, nullptr, "Resume"}, | ||
| 39 | {103, nullptr, "GetState"}, | ||
| 40 | {104, nullptr, "GetStatistics"}, | ||
| 41 | {105, nullptr, "GetPlayReportRequestEvent"}, | ||
| 42 | {111, nullptr, "GetJid"}, | ||
| 43 | {112, nullptr, "CreateJid"}, | ||
| 44 | {113, nullptr, "DestroyJid"}, | ||
| 45 | {114, nullptr, "AttachJid"}, | ||
| 46 | {115, nullptr, "DetachJid"}, | ||
| 47 | {201, nullptr, "RequestChangeStateForceTimed"}, | ||
| 48 | {102, nullptr, "RequestChangeStateForceAsync"}, | ||
| 49 | }; | ||
| 50 | // clang-format on | ||
| 51 | |||
| 52 | RegisterHandlers(functions); | ||
| 53 | } | ||
| 54 | }; | ||
| 55 | |||
| 56 | class NPNS_U final : public ServiceFramework<NPNS_U> { | ||
| 57 | public: | ||
| 58 | explicit NPNS_U() : ServiceFramework{"npns:u"} { | ||
| 59 | // clang-format off | ||
| 60 | static const FunctionInfo functions[] = { | ||
| 61 | {1, nullptr, "ListenAll"}, | ||
| 62 | {2, nullptr, "ListenTo"}, | ||
| 63 | {3, nullptr, "Receive"}, | ||
| 64 | {4, nullptr, "ReceiveRaw"}, | ||
| 65 | {5, nullptr, "GetReceiveEvent"}, | ||
| 66 | {7, nullptr, "GetStateChangeEVent"}, | ||
| 67 | {21, nullptr, "CreateToken"}, | ||
| 68 | {23, nullptr, "DestroyToken"}, | ||
| 69 | {25, nullptr, "QueryIsTokenValid"}, | ||
| 70 | {26, nullptr, "ListenToMyApplicationId"}, | ||
| 71 | {101, nullptr, "Suspend"}, | ||
| 72 | {102, nullptr, "Resume"}, | ||
| 73 | {103, nullptr, "GetState"}, | ||
| 74 | {104, nullptr, "GetStatistics"}, | ||
| 75 | {111, nullptr, "GetJid"}, | ||
| 76 | }; | ||
| 77 | // clang-format on | ||
| 78 | |||
| 79 | RegisterHandlers(functions); | ||
| 80 | } | ||
| 81 | }; | ||
| 82 | |||
| 83 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 84 | std::make_shared<NPNS_S>()->InstallAsService(sm); | ||
| 85 | std::make_shared<NPNS_U>()->InstallAsService(sm); | ||
| 86 | } | ||
| 87 | |||
| 88 | } // namespace Service::NPNS | ||
diff --git a/src/core/hle/service/npns/npns.h b/src/core/hle/service/npns/npns.h new file mode 100644 index 000000000..861cd3e48 --- /dev/null +++ b/src/core/hle/service/npns/npns.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::NPNS { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::NPNS | ||
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp index 6a9eccfb5..e4fcee9f8 100644 --- a/src/core/hle/service/prepo/prepo.cpp +++ b/src/core/hle/service/prepo/prepo.cpp | |||
| @@ -14,20 +14,24 @@ public: | |||
| 14 | explicit PlayReport(const char* name) : ServiceFramework{name} { | 14 | explicit PlayReport(const char* name) : ServiceFramework{name} { |
| 15 | // clang-format off | 15 | // clang-format off |
| 16 | static const FunctionInfo functions[] = { | 16 | static const FunctionInfo functions[] = { |
| 17 | {10100, nullptr, "SaveReport"}, | 17 | {10100, nullptr, "SaveReportOld"}, |
| 18 | {10101, &PlayReport::SaveReportWithUser, "SaveReportWithUser"}, | 18 | {10101, &PlayReport::SaveReportWithUserOld, "SaveReportWithUserOld"}, |
| 19 | {10102, nullptr, "SaveReport"}, | ||
| 20 | {10103, nullptr, "SaveReportWithUser"}, | ||
| 19 | {10200, nullptr, "RequestImmediateTransmission"}, | 21 | {10200, nullptr, "RequestImmediateTransmission"}, |
| 20 | {10300, nullptr, "GetTransmissionStatus"}, | 22 | {10300, nullptr, "GetTransmissionStatus"}, |
| 21 | {20100, nullptr, "SaveSystemReport"}, | 23 | {20100, nullptr, "SaveSystemReport"}, |
| 22 | {20200, nullptr, "SetOperationMode"}, | ||
| 23 | {20101, nullptr, "SaveSystemReportWithUser"}, | 24 | {20101, nullptr, "SaveSystemReportWithUser"}, |
| 25 | {20200, nullptr, "SetOperationMode"}, | ||
| 24 | {30100, nullptr, "ClearStorage"}, | 26 | {30100, nullptr, "ClearStorage"}, |
| 27 | {30200, nullptr, "ClearStatistics"}, | ||
| 28 | {30300, nullptr, "GetStorageUsage"}, | ||
| 29 | {30400, nullptr, "GetStatistics"}, | ||
| 30 | {30401, nullptr, "GetThroughputHistory"}, | ||
| 31 | {30500, nullptr, "GetLastUploadError"}, | ||
| 25 | {40100, nullptr, "IsUserAgreementCheckEnabled"}, | 32 | {40100, nullptr, "IsUserAgreementCheckEnabled"}, |
| 26 | {40101, nullptr, "SetUserAgreementCheckEnabled"}, | 33 | {40101, nullptr, "SetUserAgreementCheckEnabled"}, |
| 27 | {90100, nullptr, "GetStorageUsage"}, | 34 | {90100, nullptr, "ReadAllReportFiles"}, |
| 28 | {90200, nullptr, "GetStatistics"}, | ||
| 29 | {90201, nullptr, "GetThroughputHistory"}, | ||
| 30 | {90300, nullptr, "GetLastUploadError"}, | ||
| 31 | }; | 35 | }; |
| 32 | // clang-format on | 36 | // clang-format on |
| 33 | 37 | ||
| @@ -35,7 +39,7 @@ public: | |||
| 35 | } | 39 | } |
| 36 | 40 | ||
| 37 | private: | 41 | private: |
| 38 | void SaveReportWithUser(Kernel::HLERequestContext& ctx) { | 42 | void SaveReportWithUserOld(Kernel::HLERequestContext& ctx) { |
| 39 | // TODO(ogniK): Do we want to add play report? | 43 | // TODO(ogniK): Do we want to add play report? |
| 40 | LOG_WARNING(Service_PREPO, "(STUBBED) called"); | 44 | LOG_WARNING(Service_PREPO, "(STUBBED) called"); |
| 41 | 45 | ||
| @@ -46,6 +50,7 @@ private: | |||
| 46 | 50 | ||
| 47 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 51 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
| 48 | std::make_shared<PlayReport>("prepo:a")->InstallAsService(service_manager); | 52 | std::make_shared<PlayReport>("prepo:a")->InstallAsService(service_manager); |
| 53 | std::make_shared<PlayReport>("prepo:a2")->InstallAsService(service_manager); | ||
| 49 | std::make_shared<PlayReport>("prepo:m")->InstallAsService(service_manager); | 54 | std::make_shared<PlayReport>("prepo:m")->InstallAsService(service_manager); |
| 50 | std::make_shared<PlayReport>("prepo:s")->InstallAsService(service_manager); | 55 | std::make_shared<PlayReport>("prepo:s")->InstallAsService(service_manager); |
| 51 | std::make_shared<PlayReport>("prepo:u")->InstallAsService(service_manager); | 56 | std::make_shared<PlayReport>("prepo:u")->InstallAsService(service_manager); |
diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp new file mode 100644 index 000000000..c2d5fda94 --- /dev/null +++ b/src/core/hle/service/ptm/psm.cpp | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/hle/ipc_helpers.h" | ||
| 9 | #include "core/hle/service/ptm/psm.h" | ||
| 10 | #include "core/hle/service/service.h" | ||
| 11 | #include "core/hle/service/sm/sm.h" | ||
| 12 | |||
| 13 | namespace Service::PSM { | ||
| 14 | |||
| 15 | constexpr u32 BATTERY_FULLY_CHARGED = 100; // 100% Full | ||
| 16 | constexpr u32 BATTERY_CURRENTLY_CHARGING = 1; // Plugged into an official dock | ||
| 17 | |||
| 18 | class PSM final : public ServiceFramework<PSM> { | ||
| 19 | public: | ||
| 20 | explicit PSM() : ServiceFramework{"psm"} { | ||
| 21 | // clang-format off | ||
| 22 | static const FunctionInfo functions[] = { | ||
| 23 | {0, &PSM::GetBatteryChargePercentage, "GetBatteryChargePercentage"}, | ||
| 24 | {1, &PSM::GetChargerType, "GetChargerType"}, | ||
| 25 | {2, nullptr, "EnableBatteryCharging"}, | ||
| 26 | {3, nullptr, "DisableBatteryCharging"}, | ||
| 27 | {4, nullptr, "IsBatteryChargingEnabled"}, | ||
| 28 | {5, nullptr, "AcquireControllerPowerSupply"}, | ||
| 29 | {6, nullptr, "ReleaseControllerPowerSupply"}, | ||
| 30 | {7, nullptr, "OpenSession"}, | ||
| 31 | {8, nullptr, "EnableEnoughPowerChargeEmulation"}, | ||
| 32 | {9, nullptr, "DisableEnoughPowerChargeEmulation"}, | ||
| 33 | {10, nullptr, "EnableFastBatteryCharging"}, | ||
| 34 | {11, nullptr, "DisableFastBatteryCharging"}, | ||
| 35 | {12, nullptr, "GetBatteryVoltageState"}, | ||
| 36 | {13, nullptr, "GetRawBatteryChargePercentage"}, | ||
| 37 | {14, nullptr, "IsEnoughPowerSupplied"}, | ||
| 38 | {15, nullptr, "GetBatteryAgePercentage"}, | ||
| 39 | {16, nullptr, "GetBatteryChargeInfoEvent"}, | ||
| 40 | {17, nullptr, "GetBatteryChargeInfoFields"}, | ||
| 41 | }; | ||
| 42 | // clang-format on | ||
| 43 | |||
| 44 | RegisterHandlers(functions); | ||
| 45 | } | ||
| 46 | |||
| 47 | ~PSM() override = default; | ||
| 48 | |||
| 49 | private: | ||
| 50 | void GetBatteryChargePercentage(Kernel::HLERequestContext& ctx) { | ||
| 51 | LOG_WARNING(Service_PSM, "(STUBBED) called"); | ||
| 52 | |||
| 53 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 54 | rb.Push(RESULT_SUCCESS); | ||
| 55 | rb.Push<u32>(BATTERY_FULLY_CHARGED); | ||
| 56 | } | ||
| 57 | |||
| 58 | void GetChargerType(Kernel::HLERequestContext& ctx) { | ||
| 59 | LOG_WARNING(Service_PSM, "(STUBBED) called"); | ||
| 60 | |||
| 61 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 62 | rb.Push(RESULT_SUCCESS); | ||
| 63 | rb.Push<u32>(BATTERY_CURRENTLY_CHARGING); | ||
| 64 | } | ||
| 65 | }; | ||
| 66 | |||
| 67 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 68 | std::make_shared<PSM>()->InstallAsService(sm); | ||
| 69 | } | ||
| 70 | |||
| 71 | } // namespace Service::PSM | ||
diff --git a/src/core/hle/service/ptm/psm.h b/src/core/hle/service/ptm/psm.h new file mode 100644 index 000000000..a286793ae --- /dev/null +++ b/src/core/hle/service/ptm/psm.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::PSM { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::PSM | ||
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index a225cb4cb..a4cf45267 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | #include "core/hle/service/apm/apm.h" | 22 | #include "core/hle/service/apm/apm.h" |
| 23 | #include "core/hle/service/arp/arp.h" | 23 | #include "core/hle/service/arp/arp.h" |
| 24 | #include "core/hle/service/audio/audio.h" | 24 | #include "core/hle/service/audio/audio.h" |
| 25 | #include "core/hle/service/bcat/bcat.h" | 25 | #include "core/hle/service/bcat/module.h" |
| 26 | #include "core/hle/service/bpc/bpc.h" | 26 | #include "core/hle/service/bpc/bpc.h" |
| 27 | #include "core/hle/service/btdrv/btdrv.h" | 27 | #include "core/hle/service/btdrv/btdrv.h" |
| 28 | #include "core/hle/service/btm/btm.h" | 28 | #include "core/hle/service/btm/btm.h" |
| @@ -48,15 +48,17 @@ | |||
| 48 | #include "core/hle/service/nfp/nfp.h" | 48 | #include "core/hle/service/nfp/nfp.h" |
| 49 | #include "core/hle/service/nifm/nifm.h" | 49 | #include "core/hle/service/nifm/nifm.h" |
| 50 | #include "core/hle/service/nim/nim.h" | 50 | #include "core/hle/service/nim/nim.h" |
| 51 | #include "core/hle/service/npns/npns.h" | ||
| 51 | #include "core/hle/service/ns/ns.h" | 52 | #include "core/hle/service/ns/ns.h" |
| 52 | #include "core/hle/service/nvdrv/nvdrv.h" | 53 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 53 | #include "core/hle/service/nvflinger/nvflinger.h" | 54 | #include "core/hle/service/nvflinger/nvflinger.h" |
| 54 | #include "core/hle/service/pcie/pcie.h" | 55 | #include "core/hle/service/pcie/pcie.h" |
| 55 | #include "core/hle/service/pctl/pctl.h" | 56 | #include "core/hle/service/pctl/module.h" |
| 56 | #include "core/hle/service/pcv/pcv.h" | 57 | #include "core/hle/service/pcv/pcv.h" |
| 57 | #include "core/hle/service/pm/pm.h" | 58 | #include "core/hle/service/pm/pm.h" |
| 58 | #include "core/hle/service/prepo/prepo.h" | 59 | #include "core/hle/service/prepo/prepo.h" |
| 59 | #include "core/hle/service/psc/psc.h" | 60 | #include "core/hle/service/psc/psc.h" |
| 61 | #include "core/hle/service/ptm/psm.h" | ||
| 60 | #include "core/hle/service/service.h" | 62 | #include "core/hle/service/service.h" |
| 61 | #include "core/hle/service/set/settings.h" | 63 | #include "core/hle/service/set/settings.h" |
| 62 | #include "core/hle/service/sm/sm.h" | 64 | #include "core/hle/service/sm/sm.h" |
| @@ -236,6 +238,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, FileSys::VfsFilesystem& vfs) | |||
| 236 | NFP::InstallInterfaces(*sm); | 238 | NFP::InstallInterfaces(*sm); |
| 237 | NIFM::InstallInterfaces(*sm); | 239 | NIFM::InstallInterfaces(*sm); |
| 238 | NIM::InstallInterfaces(*sm); | 240 | NIM::InstallInterfaces(*sm); |
| 241 | NPNS::InstallInterfaces(*sm); | ||
| 239 | NS::InstallInterfaces(*sm); | 242 | NS::InstallInterfaces(*sm); |
| 240 | Nvidia::InstallInterfaces(*sm, *nv_flinger); | 243 | Nvidia::InstallInterfaces(*sm, *nv_flinger); |
| 241 | PCIe::InstallInterfaces(*sm); | 244 | PCIe::InstallInterfaces(*sm); |
| @@ -244,6 +247,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, FileSys::VfsFilesystem& vfs) | |||
| 244 | PlayReport::InstallInterfaces(*sm); | 247 | PlayReport::InstallInterfaces(*sm); |
| 245 | PM::InstallInterfaces(*sm); | 248 | PM::InstallInterfaces(*sm); |
| 246 | PSC::InstallInterfaces(*sm); | 249 | PSC::InstallInterfaces(*sm); |
| 250 | PSM::InstallInterfaces(*sm); | ||
| 247 | Set::InstallInterfaces(*sm); | 251 | Set::InstallInterfaces(*sm); |
| 248 | Sockets::InstallInterfaces(*sm); | 252 | Sockets::InstallInterfaces(*sm); |
| 249 | SPL::InstallInterfaces(*sm); | 253 | SPL::InstallInterfaces(*sm); |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index c8af1c6b6..0e09a7ee5 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -643,8 +643,10 @@ public: | |||
| 643 | u32 d3d_cull_mode; | 643 | u32 d3d_cull_mode; |
| 644 | 644 | ||
| 645 | ComparisonOp depth_test_func; | 645 | ComparisonOp depth_test_func; |
| 646 | float alpha_test_ref; | ||
| 647 | ComparisonOp alpha_test_func; | ||
| 646 | 648 | ||
| 647 | INSERT_PADDING_WORDS(0xB); | 649 | INSERT_PADDING_WORDS(0x9); |
| 648 | 650 | ||
| 649 | struct { | 651 | struct { |
| 650 | u32 separate_alpha; | 652 | u32 separate_alpha; |
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index e3d67ff87..ac50bb622 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -564,6 +564,10 @@ union Instruction { | |||
| 564 | } fmul; | 564 | } fmul; |
| 565 | 565 | ||
| 566 | union { | 566 | union { |
| 567 | BitField<55, 1, u64> saturate; | ||
| 568 | } fmul32; | ||
| 569 | |||
| 570 | union { | ||
| 567 | BitField<48, 1, u64> is_signed; | 571 | BitField<48, 1, u64> is_signed; |
| 568 | } shift; | 572 | } shift; |
| 569 | 573 | ||
| @@ -753,7 +757,6 @@ union Instruction { | |||
| 753 | BitField<45, 2, PredOperation> op; | 757 | BitField<45, 2, PredOperation> op; |
| 754 | BitField<47, 1, u64> ftz; | 758 | BitField<47, 1, u64> ftz; |
| 755 | BitField<48, 4, PredCondition> cond; | 759 | BitField<48, 4, PredCondition> cond; |
| 756 | BitField<56, 1, u64> neg_b; | ||
| 757 | } fsetp; | 760 | } fsetp; |
| 758 | 761 | ||
| 759 | union { | 762 | union { |
| @@ -828,7 +831,6 @@ union Instruction { | |||
| 828 | BitField<53, 1, u64> neg_b; | 831 | BitField<53, 1, u64> neg_b; |
| 829 | BitField<54, 1, u64> abs_a; | 832 | BitField<54, 1, u64> abs_a; |
| 830 | BitField<55, 1, u64> ftz; | 833 | BitField<55, 1, u64> ftz; |
| 831 | BitField<56, 1, u64> neg_imm; | ||
| 832 | } fset; | 834 | } fset; |
| 833 | 835 | ||
| 834 | union { | 836 | union { |
| @@ -1211,11 +1213,13 @@ public: | |||
| 1211 | KIL, | 1213 | KIL, |
| 1212 | SSY, | 1214 | SSY, |
| 1213 | SYNC, | 1215 | SYNC, |
| 1216 | BRK, | ||
| 1214 | DEPBAR, | 1217 | DEPBAR, |
| 1215 | BFE_C, | 1218 | BFE_C, |
| 1216 | BFE_R, | 1219 | BFE_R, |
| 1217 | BFE_IMM, | 1220 | BFE_IMM, |
| 1218 | BRA, | 1221 | BRA, |
| 1222 | PBK, | ||
| 1219 | LD_A, | 1223 | LD_A, |
| 1220 | LD_C, | 1224 | LD_C, |
| 1221 | ST_A, | 1225 | ST_A, |
| @@ -1372,7 +1376,7 @@ public: | |||
| 1372 | /// conditionally executed). | 1376 | /// conditionally executed). |
| 1373 | static bool IsPredicatedInstruction(Id opcode) { | 1377 | static bool IsPredicatedInstruction(Id opcode) { |
| 1374 | // TODO(Subv): Add the rest of unpredicated instructions. | 1378 | // TODO(Subv): Add the rest of unpredicated instructions. |
| 1375 | return opcode != Id::SSY; | 1379 | return opcode != Id::SSY && opcode != Id::PBK; |
| 1376 | } | 1380 | } |
| 1377 | 1381 | ||
| 1378 | class Matcher { | 1382 | class Matcher { |
| @@ -1468,9 +1472,11 @@ private: | |||
| 1468 | #define INST(bitstring, op, type, name) Detail::GetMatcher(bitstring, op, type, name) | 1472 | #define INST(bitstring, op, type, name) Detail::GetMatcher(bitstring, op, type, name) |
| 1469 | INST("111000110011----", Id::KIL, Type::Flow, "KIL"), | 1473 | INST("111000110011----", Id::KIL, Type::Flow, "KIL"), |
| 1470 | INST("111000101001----", Id::SSY, Type::Flow, "SSY"), | 1474 | INST("111000101001----", Id::SSY, Type::Flow, "SSY"), |
| 1475 | INST("111000101010----", Id::PBK, Type::Flow, "PBK"), | ||
| 1471 | INST("111000100100----", Id::BRA, Type::Flow, "BRA"), | 1476 | INST("111000100100----", Id::BRA, Type::Flow, "BRA"), |
| 1477 | INST("1111000011111---", Id::SYNC, Type::Flow, "SYNC"), | ||
| 1478 | INST("111000110100---", Id::BRK, Type::Flow, "BRK"), | ||
| 1472 | INST("1111000011110---", Id::DEPBAR, Type::Synch, "DEPBAR"), | 1479 | INST("1111000011110---", Id::DEPBAR, Type::Synch, "DEPBAR"), |
| 1473 | INST("1111000011111---", Id::SYNC, Type::Synch, "SYNC"), | ||
| 1474 | INST("1110111111011---", Id::LD_A, Type::Memory, "LD_A"), | 1480 | INST("1110111111011---", Id::LD_A, Type::Memory, "LD_A"), |
| 1475 | INST("1110111110010---", Id::LD_C, Type::Memory, "LD_C"), | 1481 | INST("1110111110010---", Id::LD_C, Type::Memory, "LD_C"), |
| 1476 | INST("1110111111110---", Id::ST_A, Type::Memory, "ST_A"), | 1482 | INST("1110111111110---", Id::ST_A, Type::Memory, "ST_A"), |
| @@ -1608,4 +1614,4 @@ private: | |||
| 1608 | } | 1614 | } |
| 1609 | }; | 1615 | }; |
| 1610 | 1616 | ||
| 1611 | } // namespace Tegra::Shader | 1617 | } // namespace Tegra::Shader \ No newline at end of file |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 3daccf82f..be51c5215 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -570,10 +570,11 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 570 | SyncBlendState(); | 570 | SyncBlendState(); |
| 571 | SyncLogicOpState(); | 571 | SyncLogicOpState(); |
| 572 | SyncCullMode(); | 572 | SyncCullMode(); |
| 573 | SyncAlphaTest(); | ||
| 574 | SyncScissorTest(); | 573 | SyncScissorTest(); |
| 574 | // Alpha Testing is synced on shaders. | ||
| 575 | SyncTransformFeedback(); | 575 | SyncTransformFeedback(); |
| 576 | SyncPointState(); | 576 | SyncPointState(); |
| 577 | CheckAlphaTests(); | ||
| 577 | 578 | ||
| 578 | // TODO(bunnei): Sync framebuffer_scale uniform here | 579 | // TODO(bunnei): Sync framebuffer_scale uniform here |
| 579 | // TODO(bunnei): Sync scissorbox uniform(s) here | 580 | // TODO(bunnei): Sync scissorbox uniform(s) here |
| @@ -1007,17 +1008,6 @@ void RasterizerOpenGL::SyncLogicOpState() { | |||
| 1007 | state.logic_op.operation = MaxwellToGL::LogicOp(regs.logic_op.operation); | 1008 | state.logic_op.operation = MaxwellToGL::LogicOp(regs.logic_op.operation); |
| 1008 | } | 1009 | } |
| 1009 | 1010 | ||
| 1010 | void RasterizerOpenGL::SyncAlphaTest() { | ||
| 1011 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | ||
| 1012 | |||
| 1013 | // TODO(Rodrigo): Alpha testing is a legacy OpenGL feature, but it can be | ||
| 1014 | // implemented with a test+discard in fragment shaders. | ||
| 1015 | if (regs.alpha_test_enabled != 0) { | ||
| 1016 | LOG_CRITICAL(Render_OpenGL, "Alpha testing is not implemented"); | ||
| 1017 | UNREACHABLE(); | ||
| 1018 | } | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | void RasterizerOpenGL::SyncScissorTest() { | 1011 | void RasterizerOpenGL::SyncScissorTest() { |
| 1022 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | 1012 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; |
| 1023 | 1013 | ||
| @@ -1052,4 +1042,15 @@ void RasterizerOpenGL::SyncPointState() { | |||
| 1052 | state.point.size = regs.point_size == 0 ? 1 : regs.point_size; | 1042 | state.point.size = regs.point_size == 0 ? 1 : regs.point_size; |
| 1053 | } | 1043 | } |
| 1054 | 1044 | ||
| 1045 | void RasterizerOpenGL::CheckAlphaTests() { | ||
| 1046 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | ||
| 1047 | |||
| 1048 | if (regs.alpha_test_enabled != 0 && regs.rt_control.count > 1) { | ||
| 1049 | LOG_CRITICAL( | ||
| 1050 | Render_OpenGL, | ||
| 1051 | "Alpha Testing is enabled with Multiple Render Targets, this behavior is undefined."); | ||
| 1052 | UNREACHABLE(); | ||
| 1053 | } | ||
| 1054 | } | ||
| 1055 | |||
| 1055 | } // namespace OpenGL | 1056 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index b1f7ccc7e..0e90a31f5 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -162,9 +162,6 @@ private: | |||
| 162 | /// Syncs the LogicOp state to match the guest state | 162 | /// Syncs the LogicOp state to match the guest state |
| 163 | void SyncLogicOpState(); | 163 | void SyncLogicOpState(); |
| 164 | 164 | ||
| 165 | /// Syncs the alpha test state to match the guest state | ||
| 166 | void SyncAlphaTest(); | ||
| 167 | |||
| 168 | /// Syncs the scissor test state to match the guest state | 165 | /// Syncs the scissor test state to match the guest state |
| 169 | void SyncScissorTest(); | 166 | void SyncScissorTest(); |
| 170 | 167 | ||
| @@ -174,6 +171,9 @@ private: | |||
| 174 | /// Syncs the point state to match the guest state | 171 | /// Syncs the point state to match the guest state |
| 175 | void SyncPointState(); | 172 | void SyncPointState(); |
| 176 | 173 | ||
| 174 | /// Check asserts for alpha testing. | ||
| 175 | void CheckAlphaTests(); | ||
| 176 | |||
| 177 | bool has_ARB_direct_state_access = false; | 177 | bool has_ARB_direct_state_access = false; |
| 178 | bool has_ARB_multi_bind = false; | 178 | bool has_ARB_multi_bind = false; |
| 179 | bool has_ARB_separate_shader_objects = false; | 179 | bool has_ARB_separate_shader_objects = false; |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index a427353e9..7a019fc86 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -163,10 +163,11 @@ private: | |||
| 163 | const ExitMethod jmp = Scan(target, end, labels); | 163 | const ExitMethod jmp = Scan(target, end, labels); |
| 164 | return exit_method = ParallelExit(no_jmp, jmp); | 164 | return exit_method = ParallelExit(no_jmp, jmp); |
| 165 | } | 165 | } |
| 166 | case OpCode::Id::SSY: { | 166 | case OpCode::Id::SSY: |
| 167 | // The SSY instruction uses a similar encoding as the BRA instruction. | 167 | case OpCode::Id::PBK: { |
| 168 | // The SSY and PBK use a similar encoding as the BRA instruction. | ||
| 168 | ASSERT_MSG(instr.bra.constant_buffer == 0, | 169 | ASSERT_MSG(instr.bra.constant_buffer == 0, |
| 169 | "Constant buffer SSY is not supported"); | 170 | "Constant buffer branching is not supported"); |
| 170 | const u32 target = offset + instr.bra.GetBranchTarget(); | 171 | const u32 target = offset + instr.bra.GetBranchTarget(); |
| 171 | labels.insert(target); | 172 | labels.insert(target); |
| 172 | // Continue scanning for an exit method. | 173 | // Continue scanning for an exit method. |
| @@ -378,8 +379,8 @@ public: | |||
| 378 | * @param reg The destination register to use. | 379 | * @param reg The destination register to use. |
| 379 | * @param elem The element to use for the operation. | 380 | * @param elem The element to use for the operation. |
| 380 | * @param value The code representing the value to assign. Type has to be half float. | 381 | * @param value The code representing the value to assign. Type has to be half float. |
| 381 | * @param type Half float kind of assignment. | 382 | * @param merge Half float kind of assignment. |
| 382 | * @param dest_num_components Number of components in the destionation. | 383 | * @param dest_num_components Number of components in the destination. |
| 383 | * @param value_num_components Number of components in the value. | 384 | * @param value_num_components Number of components in the value. |
| 384 | * @param is_saturated Optional, when True, saturates the provided value. | 385 | * @param is_saturated Optional, when True, saturates the provided value. |
| 385 | * @param dest_elem Optional, the destination element to use for the operation. | 386 | * @param dest_elem Optional, the destination element to use for the operation. |
| @@ -422,6 +423,7 @@ public: | |||
| 422 | * @param reg The destination register to use. | 423 | * @param reg The destination register to use. |
| 423 | * @param elem The element to use for the operation. | 424 | * @param elem The element to use for the operation. |
| 424 | * @param attribute The input attribute to use as the source value. | 425 | * @param attribute The input attribute to use as the source value. |
| 426 | * @param input_mode The input mode. | ||
| 425 | * @param vertex The register that decides which vertex to read from (used in GS). | 427 | * @param vertex The register that decides which vertex to read from (used in GS). |
| 426 | */ | 428 | */ |
| 427 | void SetRegisterToInputAttibute(const Register& reg, u64 elem, Attribute::Index attribute, | 429 | void SetRegisterToInputAttibute(const Register& reg, u64 elem, Attribute::Index attribute, |
| @@ -951,7 +953,7 @@ private: | |||
| 951 | // Can't assign to the constant predicate. | 953 | // Can't assign to the constant predicate. |
| 952 | ASSERT(pred != static_cast<u64>(Pred::UnusedIndex)); | 954 | ASSERT(pred != static_cast<u64>(Pred::UnusedIndex)); |
| 953 | 955 | ||
| 954 | const std::string variable = 'p' + std::to_string(pred) + '_' + suffix; | 956 | std::string variable = 'p' + std::to_string(pred) + '_' + suffix; |
| 955 | shader.AddLine(variable + " = " + value + ';'); | 957 | shader.AddLine(variable + " = " + value + ';'); |
| 956 | declr_predicates.insert(std::move(variable)); | 958 | declr_predicates.insert(std::move(variable)); |
| 957 | } | 959 | } |
| @@ -1058,7 +1060,7 @@ private: | |||
| 1058 | /* | 1060 | /* |
| 1059 | * Transforms the input string GLSL operand into an unpacked half float pair. | 1061 | * Transforms the input string GLSL operand into an unpacked half float pair. |
| 1060 | * @note This function returns a float type pair instead of a half float pair. This is because | 1062 | * @note This function returns a float type pair instead of a half float pair. This is because |
| 1061 | * real half floats are not standarized in GLSL but unpackHalf2x16 (which returns a vec2) is. | 1063 | * real half floats are not standardized in GLSL but unpackHalf2x16 (which returns a vec2) is. |
| 1062 | * @param operand Input operand. It has to be an unsigned integer. | 1064 | * @param operand Input operand. It has to be an unsigned integer. |
| 1063 | * @param type How to unpack the unsigned integer to a half float pair. | 1065 | * @param type How to unpack the unsigned integer to a half float pair. |
| 1064 | * @param abs Get the absolute value of unpacked half floats. | 1066 | * @param abs Get the absolute value of unpacked half floats. |
| @@ -1232,27 +1234,27 @@ private: | |||
| 1232 | } | 1234 | } |
| 1233 | 1235 | ||
| 1234 | /* | 1236 | /* |
| 1235 | * Emits code to push the input target address to the SSY address stack, incrementing the stack | 1237 | * Emits code to push the input target address to the flow address stack, incrementing the stack |
| 1236 | * top. | 1238 | * top. |
| 1237 | */ | 1239 | */ |
| 1238 | void EmitPushToSSYStack(u32 target) { | 1240 | void EmitPushToFlowStack(u32 target) { |
| 1239 | shader.AddLine('{'); | 1241 | shader.AddLine('{'); |
| 1240 | ++shader.scope; | 1242 | ++shader.scope; |
| 1241 | shader.AddLine("ssy_stack[ssy_stack_top] = " + std::to_string(target) + "u;"); | 1243 | shader.AddLine("flow_stack[flow_stack_top] = " + std::to_string(target) + "u;"); |
| 1242 | shader.AddLine("ssy_stack_top++;"); | 1244 | shader.AddLine("flow_stack_top++;"); |
| 1243 | --shader.scope; | 1245 | --shader.scope; |
| 1244 | shader.AddLine('}'); | 1246 | shader.AddLine('}'); |
| 1245 | } | 1247 | } |
| 1246 | 1248 | ||
| 1247 | /* | 1249 | /* |
| 1248 | * Emits code to pop an address from the SSY address stack, setting the jump address to the | 1250 | * Emits code to pop an address from the flow address stack, setting the jump address to the |
| 1249 | * popped address and decrementing the stack top. | 1251 | * popped address and decrementing the stack top. |
| 1250 | */ | 1252 | */ |
| 1251 | void EmitPopFromSSYStack() { | 1253 | void EmitPopFromFlowStack() { |
| 1252 | shader.AddLine('{'); | 1254 | shader.AddLine('{'); |
| 1253 | ++shader.scope; | 1255 | ++shader.scope; |
| 1254 | shader.AddLine("ssy_stack_top--;"); | 1256 | shader.AddLine("flow_stack_top--;"); |
| 1255 | shader.AddLine("jmp_to = ssy_stack[ssy_stack_top];"); | 1257 | shader.AddLine("jmp_to = flow_stack[flow_stack_top];"); |
| 1256 | shader.AddLine("break;"); | 1258 | shader.AddLine("break;"); |
| 1257 | --shader.scope; | 1259 | --shader.scope; |
| 1258 | shader.AddLine('}'); | 1260 | shader.AddLine('}'); |
| @@ -1264,9 +1266,29 @@ private: | |||
| 1264 | 1266 | ||
| 1265 | ASSERT_MSG(header.ps.omap.sample_mask == 0, "Samplemask write is unimplemented"); | 1267 | ASSERT_MSG(header.ps.omap.sample_mask == 0, "Samplemask write is unimplemented"); |
| 1266 | 1268 | ||
| 1269 | shader.AddLine("if (alpha_test[0] != 0) {"); | ||
| 1270 | ++shader.scope; | ||
| 1271 | // We start on the register containing the alpha value in the first RT. | ||
| 1272 | u32 current_reg = 3; | ||
| 1273 | for (u32 render_target = 0; render_target < Maxwell3D::Regs::NumRenderTargets; | ||
| 1274 | ++render_target) { | ||
| 1275 | // TODO(Blinkhawk): verify the behavior of alpha testing on hardware when | ||
| 1276 | // multiple render targets are used. | ||
| 1277 | if (header.ps.IsColorComponentOutputEnabled(render_target, 0) || | ||
| 1278 | header.ps.IsColorComponentOutputEnabled(render_target, 1) || | ||
| 1279 | header.ps.IsColorComponentOutputEnabled(render_target, 2) || | ||
| 1280 | header.ps.IsColorComponentOutputEnabled(render_target, 3)) { | ||
| 1281 | shader.AddLine(fmt::format("if (!AlphaFunc({})) discard;", | ||
| 1282 | regs.GetRegisterAsFloat(current_reg))); | ||
| 1283 | current_reg += 4; | ||
| 1284 | } | ||
| 1285 | } | ||
| 1286 | --shader.scope; | ||
| 1287 | shader.AddLine('}'); | ||
| 1288 | |||
| 1267 | // Write the color outputs using the data in the shader registers, disabled | 1289 | // Write the color outputs using the data in the shader registers, disabled |
| 1268 | // rendertargets/components are skipped in the register assignment. | 1290 | // rendertargets/components are skipped in the register assignment. |
| 1269 | u32 current_reg = 0; | 1291 | current_reg = 0; |
| 1270 | for (u32 render_target = 0; render_target < Maxwell3D::Regs::NumRenderTargets; | 1292 | for (u32 render_target = 0; render_target < Maxwell3D::Regs::NumRenderTargets; |
| 1271 | ++render_target) { | 1293 | ++render_target) { |
| 1272 | // TODO(Subv): Figure out how dual-source blending is configured in the Switch. | 1294 | // TODO(Subv): Figure out how dual-source blending is configured in the Switch. |
| @@ -1459,9 +1481,10 @@ private: | |||
| 1459 | break; | 1481 | break; |
| 1460 | } | 1482 | } |
| 1461 | case OpCode::Id::FMUL32_IMM: { | 1483 | case OpCode::Id::FMUL32_IMM: { |
| 1462 | regs.SetRegisterToFloat( | 1484 | regs.SetRegisterToFloat(instr.gpr0, 0, |
| 1463 | instr.gpr0, 0, | 1485 | regs.GetRegisterAsFloat(instr.gpr8) + " * " + |
| 1464 | regs.GetRegisterAsFloat(instr.gpr8) + " * " + GetImmediate32(instr), 1, 1); | 1486 | GetImmediate32(instr), |
| 1487 | 1, 1, instr.fmul32.saturate); | ||
| 1465 | break; | 1488 | break; |
| 1466 | } | 1489 | } |
| 1467 | case OpCode::Id::FADD32I: { | 1490 | case OpCode::Id::FADD32I: { |
| @@ -2736,20 +2759,13 @@ private: | |||
| 2736 | break; | 2759 | break; |
| 2737 | } | 2760 | } |
| 2738 | case OpCode::Type::FloatSetPredicate: { | 2761 | case OpCode::Type::FloatSetPredicate: { |
| 2739 | std::string op_a = instr.fsetp.neg_a ? "-" : ""; | 2762 | const std::string op_a = |
| 2740 | op_a += regs.GetRegisterAsFloat(instr.gpr8); | 2763 | GetOperandAbsNeg(regs.GetRegisterAsFloat(instr.gpr8), instr.fsetp.abs_a != 0, |
| 2741 | 2764 | instr.fsetp.neg_a != 0); | |
| 2742 | if (instr.fsetp.abs_a) { | ||
| 2743 | op_a = "abs(" + op_a + ')'; | ||
| 2744 | } | ||
| 2745 | 2765 | ||
| 2746 | std::string op_b{}; | 2766 | std::string op_b; |
| 2747 | 2767 | ||
| 2748 | if (instr.is_b_imm) { | 2768 | if (instr.is_b_imm) { |
| 2749 | if (instr.fsetp.neg_b) { | ||
| 2750 | // Only the immediate version of fsetp has a neg_b bit. | ||
| 2751 | op_b += '-'; | ||
| 2752 | } | ||
| 2753 | op_b += '(' + GetImmediate19(instr) + ')'; | 2769 | op_b += '(' + GetImmediate19(instr) + ')'; |
| 2754 | } else { | 2770 | } else { |
| 2755 | if (instr.is_b_gpr) { | 2771 | if (instr.is_b_gpr) { |
| @@ -2945,33 +2961,24 @@ private: | |||
| 2945 | break; | 2961 | break; |
| 2946 | } | 2962 | } |
| 2947 | case OpCode::Type::FloatSet: { | 2963 | case OpCode::Type::FloatSet: { |
| 2948 | std::string op_a = instr.fset.neg_a ? "-" : ""; | 2964 | const std::string op_a = GetOperandAbsNeg(regs.GetRegisterAsFloat(instr.gpr8), |
| 2949 | op_a += regs.GetRegisterAsFloat(instr.gpr8); | 2965 | instr.fset.abs_a != 0, instr.fset.neg_a != 0); |
| 2950 | |||
| 2951 | if (instr.fset.abs_a) { | ||
| 2952 | op_a = "abs(" + op_a + ')'; | ||
| 2953 | } | ||
| 2954 | 2966 | ||
| 2955 | std::string op_b = instr.fset.neg_b ? "-" : ""; | 2967 | std::string op_b; |
| 2956 | 2968 | ||
| 2957 | if (instr.is_b_imm) { | 2969 | if (instr.is_b_imm) { |
| 2958 | const std::string imm = GetImmediate19(instr); | 2970 | const std::string imm = GetImmediate19(instr); |
| 2959 | if (instr.fset.neg_imm) | 2971 | op_b = imm; |
| 2960 | op_b += "(-" + imm + ')'; | ||
| 2961 | else | ||
| 2962 | op_b += imm; | ||
| 2963 | } else { | 2972 | } else { |
| 2964 | if (instr.is_b_gpr) { | 2973 | if (instr.is_b_gpr) { |
| 2965 | op_b += regs.GetRegisterAsFloat(instr.gpr20); | 2974 | op_b = regs.GetRegisterAsFloat(instr.gpr20); |
| 2966 | } else { | 2975 | } else { |
| 2967 | op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, | 2976 | op_b = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, |
| 2968 | GLSLRegister::Type::Float); | 2977 | GLSLRegister::Type::Float); |
| 2969 | } | 2978 | } |
| 2970 | } | 2979 | } |
| 2971 | 2980 | ||
| 2972 | if (instr.fset.abs_b) { | 2981 | op_b = GetOperandAbsNeg(op_b, instr.fset.abs_b != 0, instr.fset.neg_b != 0); |
| 2973 | op_b = "abs(" + op_b + ')'; | ||
| 2974 | } | ||
| 2975 | 2982 | ||
| 2976 | // The fset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the | 2983 | // The fset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the |
| 2977 | // condition is true, and to 0 otherwise. | 2984 | // condition is true, and to 0 otherwise. |
| @@ -3279,16 +3286,32 @@ private: | |||
| 3279 | // The SSY opcode tells the GPU where to re-converge divergent execution paths, it | 3286 | // The SSY opcode tells the GPU where to re-converge divergent execution paths, it |
| 3280 | // sets the target of the jump that the SYNC instruction will make. The SSY opcode | 3287 | // sets the target of the jump that the SYNC instruction will make. The SSY opcode |
| 3281 | // has a similar structure to the BRA opcode. | 3288 | // has a similar structure to the BRA opcode. |
| 3282 | ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported"); | 3289 | ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer flow is not supported"); |
| 3290 | |||
| 3291 | const u32 target = offset + instr.bra.GetBranchTarget(); | ||
| 3292 | EmitPushToFlowStack(target); | ||
| 3293 | break; | ||
| 3294 | } | ||
| 3295 | case OpCode::Id::PBK: { | ||
| 3296 | // PBK pushes to a stack the address where BRK will jump to. This shares stack with | ||
| 3297 | // SSY but using SYNC on a PBK address will kill the shader execution. We don't | ||
| 3298 | // emulate this because it's very unlikely a driver will emit such invalid shader. | ||
| 3299 | ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer PBK is not supported"); | ||
| 3283 | 3300 | ||
| 3284 | const u32 target = offset + instr.bra.GetBranchTarget(); | 3301 | const u32 target = offset + instr.bra.GetBranchTarget(); |
| 3285 | EmitPushToSSYStack(target); | 3302 | EmitPushToFlowStack(target); |
| 3286 | break; | 3303 | break; |
| 3287 | } | 3304 | } |
| 3288 | case OpCode::Id::SYNC: { | 3305 | case OpCode::Id::SYNC: { |
| 3289 | // The SYNC opcode jumps to the address previously set by the SSY opcode | 3306 | // The SYNC opcode jumps to the address previously set by the SSY opcode |
| 3290 | ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); | 3307 | ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); |
| 3291 | EmitPopFromSSYStack(); | 3308 | EmitPopFromFlowStack(); |
| 3309 | break; | ||
| 3310 | } | ||
| 3311 | case OpCode::Id::BRK: { | ||
| 3312 | // The BRK opcode jumps to the address previously set by the PBK opcode | ||
| 3313 | ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); | ||
| 3314 | EmitPopFromFlowStack(); | ||
| 3292 | break; | 3315 | break; |
| 3293 | } | 3316 | } |
| 3294 | case OpCode::Id::DEPBAR: { | 3317 | case OpCode::Id::DEPBAR: { |
| @@ -3307,8 +3330,8 @@ private: | |||
| 3307 | Tegra::Shader::VmadType type, u64 byte_height) { | 3330 | Tegra::Shader::VmadType type, u64 byte_height) { |
| 3308 | const std::string value = [&]() { | 3331 | const std::string value = [&]() { |
| 3309 | if (!is_chunk) { | 3332 | if (!is_chunk) { |
| 3310 | const auto offset = static_cast<u32>(byte_height * 8); | 3333 | const auto shift = static_cast<u32>(byte_height * 8); |
| 3311 | return "((" + op + " >> " + std::to_string(offset) + ") & 0xff)"; | 3334 | return "((" + op + " >> " + std::to_string(shift) + ") & 0xff)"; |
| 3312 | } | 3335 | } |
| 3313 | const std::string zero = "0"; | 3336 | const std::string zero = "0"; |
| 3314 | 3337 | ||
| @@ -3442,11 +3465,11 @@ private: | |||
| 3442 | labels.insert(subroutine.begin); | 3465 | labels.insert(subroutine.begin); |
| 3443 | shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;"); | 3466 | shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;"); |
| 3444 | 3467 | ||
| 3445 | // TODO(Subv): Figure out the actual depth of the SSY stack, for now it seems | 3468 | // TODO(Subv): Figure out the actual depth of the flow stack, for now it seems |
| 3446 | // unlikely that shaders will use 20 nested SSYs. | 3469 | // unlikely that shaders will use 20 nested SSYs and PBKs. |
| 3447 | constexpr u32 SSY_STACK_SIZE = 20; | 3470 | constexpr u32 FLOW_STACK_SIZE = 20; |
| 3448 | shader.AddLine("uint ssy_stack[" + std::to_string(SSY_STACK_SIZE) + "];"); | 3471 | shader.AddLine("uint flow_stack[" + std::to_string(FLOW_STACK_SIZE) + "];"); |
| 3449 | shader.AddLine("uint ssy_stack_top = 0u;"); | 3472 | shader.AddLine("uint flow_stack_top = 0u;"); |
| 3450 | 3473 | ||
| 3451 | shader.AddLine("while (true) {"); | 3474 | shader.AddLine("while (true) {"); |
| 3452 | ++shader.scope; | 3475 | ++shader.scope; |
| @@ -3513,7 +3536,7 @@ private: | |||
| 3513 | 3536 | ||
| 3514 | // Declarations | 3537 | // Declarations |
| 3515 | std::set<std::string> declr_predicates; | 3538 | std::set<std::string> declr_predicates; |
| 3516 | }; // namespace Decompiler | 3539 | }; // namespace OpenGL::GLShader::Decompiler |
| 3517 | 3540 | ||
| 3518 | std::string GetCommonDeclarations() { | 3541 | std::string GetCommonDeclarations() { |
| 3519 | return fmt::format("#define MAX_CONSTBUFFER_ELEMENTS {}\n", | 3542 | return fmt::format("#define MAX_CONSTBUFFER_ELEMENTS {}\n", |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index ecbc9d8ed..e883ffb1d 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp | |||
| @@ -29,6 +29,7 @@ layout(std140) uniform vs_config { | |||
| 29 | vec4 viewport_flip; | 29 | vec4 viewport_flip; |
| 30 | uvec4 instance_id; | 30 | uvec4 instance_id; |
| 31 | uvec4 flip_stage; | 31 | uvec4 flip_stage; |
| 32 | uvec4 alpha_test; | ||
| 32 | }; | 33 | }; |
| 33 | )"; | 34 | )"; |
| 34 | 35 | ||
| @@ -105,6 +106,7 @@ layout (std140) uniform gs_config { | |||
| 105 | vec4 viewport_flip; | 106 | vec4 viewport_flip; |
| 106 | uvec4 instance_id; | 107 | uvec4 instance_id; |
| 107 | uvec4 flip_stage; | 108 | uvec4 flip_stage; |
| 109 | uvec4 alpha_test; | ||
| 108 | }; | 110 | }; |
| 109 | 111 | ||
| 110 | void main() { | 112 | void main() { |
| @@ -142,8 +144,33 @@ layout (std140) uniform fs_config { | |||
| 142 | vec4 viewport_flip; | 144 | vec4 viewport_flip; |
| 143 | uvec4 instance_id; | 145 | uvec4 instance_id; |
| 144 | uvec4 flip_stage; | 146 | uvec4 flip_stage; |
| 147 | uvec4 alpha_test; | ||
| 145 | }; | 148 | }; |
| 146 | 149 | ||
| 150 | bool AlphaFunc(in float value) { | ||
| 151 | float ref = uintBitsToFloat(alpha_test[2]); | ||
| 152 | switch (alpha_test[1]) { | ||
| 153 | case 1: | ||
| 154 | return false; | ||
| 155 | case 2: | ||
| 156 | return value < ref; | ||
| 157 | case 3: | ||
| 158 | return value == ref; | ||
| 159 | case 4: | ||
| 160 | return value <= ref; | ||
| 161 | case 5: | ||
| 162 | return value > ref; | ||
| 163 | case 6: | ||
| 164 | return value != ref; | ||
| 165 | case 7: | ||
| 166 | return value >= ref; | ||
| 167 | case 8: | ||
| 168 | return true; | ||
| 169 | default: | ||
| 170 | return false; | ||
| 171 | } | ||
| 172 | } | ||
| 173 | |||
| 147 | void main() { | 174 | void main() { |
| 148 | exec_fragment(); | 175 | exec_fragment(); |
| 149 | } | 176 | } |
| @@ -152,4 +179,4 @@ void main() { | |||
| 152 | out += program.first; | 179 | out += program.first; |
| 153 | return {out, program.second}; | 180 | return {out, program.second}; |
| 154 | } | 181 | } |
| 155 | } // namespace OpenGL::GLShader \ No newline at end of file | 182 | } // namespace OpenGL::GLShader |
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index 010857ec6..8b8869ecb 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp | |||
| @@ -16,6 +16,17 @@ void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& sh | |||
| 16 | viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f; | 16 | viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f; |
| 17 | viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f; | 17 | viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f; |
| 18 | 18 | ||
| 19 | u32 func = static_cast<u32>(regs.alpha_test_func); | ||
| 20 | // Normalize the gl variants of opCompare to be the same as the normal variants | ||
| 21 | u32 op_gl_variant_base = static_cast<u32>(Tegra::Engines::Maxwell3D::Regs::ComparisonOp::Never); | ||
| 22 | if (func >= op_gl_variant_base) { | ||
| 23 | func = func - op_gl_variant_base + 1U; | ||
| 24 | } | ||
| 25 | |||
| 26 | alpha_test.enabled = regs.alpha_test_enabled; | ||
| 27 | alpha_test.func = func; | ||
| 28 | alpha_test.ref = regs.alpha_test_ref; | ||
| 29 | |||
| 19 | // We only assign the instance to the first component of the vector, the rest is just padding. | 30 | // We only assign the instance to the first component of the vector, the rest is just padding. |
| 20 | instance_id[0] = state.current_instance; | 31 | instance_id[0] = state.current_instance; |
| 21 | 32 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index b3a191cf2..36fe1f04c 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h | |||
| @@ -22,8 +22,14 @@ struct MaxwellUniformData { | |||
| 22 | alignas(16) GLvec4 viewport_flip; | 22 | alignas(16) GLvec4 viewport_flip; |
| 23 | alignas(16) GLuvec4 instance_id; | 23 | alignas(16) GLuvec4 instance_id; |
| 24 | alignas(16) GLuvec4 flip_stage; | 24 | alignas(16) GLuvec4 flip_stage; |
| 25 | struct alignas(16) { | ||
| 26 | GLuint enabled; | ||
| 27 | GLuint func; | ||
| 28 | GLfloat ref; | ||
| 29 | GLuint padding; | ||
| 30 | } alpha_test; | ||
| 25 | }; | 31 | }; |
| 26 | static_assert(sizeof(MaxwellUniformData) == 48, "MaxwellUniformData structure size is incorrect"); | 32 | static_assert(sizeof(MaxwellUniformData) == 64, "MaxwellUniformData structure size is incorrect"); |
| 27 | static_assert(sizeof(MaxwellUniformData) < 16384, | 33 | static_assert(sizeof(MaxwellUniformData) < 16384, |
| 28 | "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); | 34 | "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); |
| 29 | 35 | ||
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index 3c3bcaae4..0f6dcab2b 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h | |||
| @@ -82,8 +82,20 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) { | |||
| 82 | return {}; | 82 | return {}; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | case Maxwell::VertexAttribute::Type::Float: | 85 | case Maxwell::VertexAttribute::Type::Float: { |
| 86 | return GL_FLOAT; | 86 | switch (attrib.size) { |
| 87 | case Maxwell::VertexAttribute::Size::Size_16: | ||
| 88 | case Maxwell::VertexAttribute::Size::Size_16_16: | ||
| 89 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | ||
| 90 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | ||
| 91 | return GL_HALF_FLOAT; | ||
| 92 | case Maxwell::VertexAttribute::Size::Size_32: | ||
| 93 | case Maxwell::VertexAttribute::Size::Size_32_32: | ||
| 94 | case Maxwell::VertexAttribute::Size::Size_32_32_32: | ||
| 95 | case Maxwell::VertexAttribute::Size::Size_32_32_32_32: | ||
| 96 | return GL_FLOAT; | ||
| 97 | } | ||
| 98 | } | ||
| 87 | } | 99 | } |
| 88 | 100 | ||
| 89 | LOG_CRITICAL(Render_OpenGL, "Unimplemented vertex type={}", attrib.TypeString()); | 101 | LOG_CRITICAL(Render_OpenGL, "Unimplemented vertex type={}", attrib.TypeString()); |
diff --git a/src/web_service/CMakeLists.txt b/src/web_service/CMakeLists.txt index 1c83e9c34..9ad75e74a 100644 --- a/src/web_service/CMakeLists.txt +++ b/src/web_service/CMakeLists.txt | |||
| @@ -12,5 +12,5 @@ create_target_directory_groups(web_service) | |||
| 12 | get_directory_property(OPENSSL_LIBS | 12 | get_directory_property(OPENSSL_LIBS |
| 13 | DIRECTORY ${CMAKE_SOURCE_DIR}/externals/libressl | 13 | DIRECTORY ${CMAKE_SOURCE_DIR}/externals/libressl |
| 14 | DEFINITION OPENSSL_LIBS) | 14 | DEFINITION OPENSSL_LIBS) |
| 15 | target_compile_definitions(web_service PUBLIC -DCPPHTTPLIB_OPENSSL_SUPPORT) | 15 | target_compile_definitions(web_service PRIVATE -DCPPHTTPLIB_OPENSSL_SUPPORT) |
| 16 | target_link_libraries(web_service PRIVATE common json-headers ${OPENSSL_LIBS} httplib lurlparser) | 16 | target_link_libraries(web_service PRIVATE common json-headers ${OPENSSL_LIBS} httplib lurlparser) |
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 04464ad5e..b901c29d2 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt | |||
| @@ -121,7 +121,7 @@ target_link_libraries(yuzu PRIVATE Boost::boost glad Qt5::OpenGL Qt5::Widgets) | |||
| 121 | target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) | 121 | target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) |
| 122 | 122 | ||
| 123 | if (YUZU_ENABLE_COMPATIBILITY_REPORTING) | 123 | if (YUZU_ENABLE_COMPATIBILITY_REPORTING) |
| 124 | add_definitions(-DYUZU_ENABLE_COMPATIBILITY_REPORTING) | 124 | target_compile_definitions(yuzu PRIVATE -DYUZU_ENABLE_COMPATIBILITY_REPORTING) |
| 125 | endif() | 125 | endif() |
| 126 | 126 | ||
| 127 | if (USE_DISCORD_PRESENCE) | 127 | if (USE_DISCORD_PRESENCE) |
diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index 9851f507d..dffd9c788 100644 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui | |||
| @@ -97,18 +97,24 @@ | |||
| 97 | <addaction name="action_Show_Status_Bar"/> | 97 | <addaction name="action_Show_Status_Bar"/> |
| 98 | <addaction name="menu_View_Debugging"/> | 98 | <addaction name="menu_View_Debugging"/> |
| 99 | </widget> | 99 | </widget> |
| 100 | <widget class ="QMenu" name="menu_Tools"> | ||
| 101 | <property name="title"> | ||
| 102 | <string>Tools</string> | ||
| 103 | </property> | ||
| 104 | <addaction name="action_Rederive" /> | ||
| 105 | </widget> | ||
| 100 | <widget class="QMenu" name="menu_Help"> | 106 | <widget class="QMenu" name="menu_Help"> |
| 101 | <property name="title"> | 107 | <property name="title"> |
| 102 | <string>&Help</string> | 108 | <string>&Help</string> |
| 103 | </property> | 109 | </property> |
| 104 | <addaction name="action_Report_Compatibility"/> | 110 | <addaction name="action_Report_Compatibility"/> |
| 105 | <addaction name="separator"/> | 111 | <addaction name="separator"/> |
| 106 | <addaction name="action_Rederive"/> | ||
| 107 | <addaction name="action_About"/> | 112 | <addaction name="action_About"/> |
| 108 | </widget> | 113 | </widget> |
| 109 | <addaction name="menu_File"/> | 114 | <addaction name="menu_File"/> |
| 110 | <addaction name="menu_Emulation"/> | 115 | <addaction name="menu_Emulation"/> |
| 111 | <addaction name="menu_View"/> | 116 | <addaction name="menu_View"/> |
| 117 | <addaction name="menu_Tools" /> | ||
| 112 | <addaction name="menu_Help"/> | 118 | <addaction name="menu_Help"/> |
| 113 | </widget> | 119 | </widget> |
| 114 | <action name="action_Install_File_NAND"> | 120 | <action name="action_Install_File_NAND"> |