diff options
| author | 2023-09-10 02:36:26 +0200 | |
|---|---|---|
| committer | 2023-09-10 15:39:25 -0400 | |
| commit | 87c0ba129ce38dd3b001fbef8021590a127fb1a8 (patch) | |
| tree | 28fa19ccd43fceeec31e433d32dae41e88d2b17e /src/core | |
| parent | am: Remove bcat from PopLaunchParameter (diff) | |
| download | yuzu-87c0ba129ce38dd3b001fbef8021590a127fb1a8.tar.gz yuzu-87c0ba129ce38dd3b001fbef8021590a127fb1a8.tar.xz yuzu-87c0ba129ce38dd3b001fbef8021590a127fb1a8.zip | |
am: Implement UserChannel parameters
Used by the Super Mairo 3D All-Stars collection.
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/core.cpp | 6 | ||||
| -rw-r--r-- | src/core/core.h | 7 | ||||
| -rw-r--r-- | src/core/hle/service/am/am.cpp | 40 |
3 files changed, 43 insertions, 10 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index e95ae80da..f075ae7fa 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -562,6 +562,8 @@ struct System::Impl { | |||
| 562 | 562 | ||
| 563 | std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES> | 563 | std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES> |
| 564 | gpu_dirty_memory_write_manager{}; | 564 | gpu_dirty_memory_write_manager{}; |
| 565 | |||
| 566 | std::deque<std::vector<u8>> user_channel; | ||
| 565 | }; | 567 | }; |
| 566 | 568 | ||
| 567 | System::System() : impl{std::make_unique<Impl>(*this)} {} | 569 | System::System() : impl{std::make_unique<Impl>(*this)} {} |
| @@ -1036,6 +1038,10 @@ void System::ExecuteProgram(std::size_t program_index) { | |||
| 1036 | } | 1038 | } |
| 1037 | } | 1039 | } |
| 1038 | 1040 | ||
| 1041 | std::deque<std::vector<u8>>& System::GetUserChannel() { | ||
| 1042 | return impl->user_channel; | ||
| 1043 | } | ||
| 1044 | |||
| 1039 | void System::RegisterExitCallback(ExitCallback&& callback) { | 1045 | void System::RegisterExitCallback(ExitCallback&& callback) { |
| 1040 | impl->exit_callback = std::move(callback); | 1046 | impl->exit_callback = std::move(callback); |
| 1041 | } | 1047 | } |
diff --git a/src/core/core.h b/src/core/core.h index a9ff9315e..fba312125 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <cstddef> | 6 | #include <cstddef> |
| 7 | #include <deque> | ||
| 7 | #include <functional> | 8 | #include <functional> |
| 8 | #include <memory> | 9 | #include <memory> |
| 9 | #include <mutex> | 10 | #include <mutex> |
| @@ -459,6 +460,12 @@ public: | |||
| 459 | */ | 460 | */ |
| 460 | void ExecuteProgram(std::size_t program_index); | 461 | void ExecuteProgram(std::size_t program_index); |
| 461 | 462 | ||
| 463 | /** | ||
| 464 | * Gets a reference to the user channel stack. | ||
| 465 | * It is used to transfer data between programs. | ||
| 466 | */ | ||
| 467 | [[nodiscard]] std::deque<std::vector<u8>>& GetUserChannel(); | ||
| 468 | |||
| 462 | /// Type used for the frontend to designate a callback for System to exit the application. | 469 | /// Type used for the frontend to designate a callback for System to exit the application. |
| 463 | using ExitCallback = std::function<void()>; | 470 | using ExitCallback = std::function<void()>; |
| 464 | 471 | ||
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 42e00c30a..f9c4f9678 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -1518,12 +1518,26 @@ void IApplicationFunctions::PopLaunchParameter(HLERequestContext& ctx) { | |||
| 1518 | IPC::RequestParser rp{ctx}; | 1518 | IPC::RequestParser rp{ctx}; |
| 1519 | const auto kind = rp.PopEnum<LaunchParameterKind>(); | 1519 | const auto kind = rp.PopEnum<LaunchParameterKind>(); |
| 1520 | 1520 | ||
| 1521 | LOG_WARNING(Service_AM, "(STUBBED) called, kind={:08X}", kind); | 1521 | LOG_INFO(Service_AM, "called, kind={:08X}", kind); |
| 1522 | 1522 | ||
| 1523 | if (kind == LaunchParameterKind::UserChannel) { | 1523 | if (kind == LaunchParameterKind::UserChannel) { |
| 1524 | LOG_ERROR(Service_AM, "Popping from UserChannel is not supported!"); | 1524 | auto channel = system.GetUserChannel(); |
| 1525 | if (channel.empty()) { | ||
| 1526 | LOG_ERROR(Service_AM, "Attempted to load launch parameter but none was found!"); | ||
| 1527 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1528 | rb.Push(AM::ResultNoDataInChannel); | ||
| 1529 | return; | ||
| 1530 | } | ||
| 1531 | |||
| 1532 | auto data = channel.back(); | ||
| 1533 | channel.pop_back(); | ||
| 1534 | |||
| 1535 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 1536 | rb.Push(ResultSuccess); | ||
| 1537 | rb.PushIpcInterface<IStorage>(system, std::move(data)); | ||
| 1525 | } else if (kind == LaunchParameterKind::AccountPreselectedUser && | 1538 | } else if (kind == LaunchParameterKind::AccountPreselectedUser && |
| 1526 | !launch_popped_account_preselect) { | 1539 | !launch_popped_account_preselect) { |
| 1540 | // TODO: Verify this is hw-accurate | ||
| 1527 | LaunchParameterAccountPreselectedUser params{}; | 1541 | LaunchParameterAccountPreselectedUser params{}; |
| 1528 | 1542 | ||
| 1529 | params.magic = LAUNCH_PARAMETER_ACCOUNT_PRESELECTED_USER_MAGIC; | 1543 | params.magic = LAUNCH_PARAMETER_ACCOUNT_PRESELECTED_USER_MAGIC; |
| @@ -1535,7 +1549,6 @@ void IApplicationFunctions::PopLaunchParameter(HLERequestContext& ctx) { | |||
| 1535 | params.current_user = *uuid; | 1549 | params.current_user = *uuid; |
| 1536 | 1550 | ||
| 1537 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 1551 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 1538 | |||
| 1539 | rb.Push(ResultSuccess); | 1552 | rb.Push(ResultSuccess); |
| 1540 | 1553 | ||
| 1541 | std::vector<u8> buffer(sizeof(LaunchParameterAccountPreselectedUser)); | 1554 | std::vector<u8> buffer(sizeof(LaunchParameterAccountPreselectedUser)); |
| @@ -1543,12 +1556,11 @@ void IApplicationFunctions::PopLaunchParameter(HLERequestContext& ctx) { | |||
| 1543 | 1556 | ||
| 1544 | rb.PushIpcInterface<IStorage>(system, std::move(buffer)); | 1557 | rb.PushIpcInterface<IStorage>(system, std::move(buffer)); |
| 1545 | launch_popped_account_preselect = true; | 1558 | launch_popped_account_preselect = true; |
| 1546 | return; | 1559 | } else { |
| 1560 | LOG_ERROR(Service_AM, "Unknown launch parameter kind."); | ||
| 1561 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1562 | rb.Push(AM::ResultNoDataInChannel); | ||
| 1547 | } | 1563 | } |
| 1548 | |||
| 1549 | LOG_ERROR(Service_AM, "Attempted to load launch parameter but none was found!"); | ||
| 1550 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1551 | rb.Push(AM::ResultNoDataInChannel); | ||
| 1552 | } | 1564 | } |
| 1553 | 1565 | ||
| 1554 | void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) { | 1566 | void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) { |
| @@ -1840,14 +1852,22 @@ void IApplicationFunctions::ExecuteProgram(HLERequestContext& ctx) { | |||
| 1840 | } | 1852 | } |
| 1841 | 1853 | ||
| 1842 | void IApplicationFunctions::ClearUserChannel(HLERequestContext& ctx) { | 1854 | void IApplicationFunctions::ClearUserChannel(HLERequestContext& ctx) { |
| 1843 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 1855 | LOG_DEBUG(Service_AM, "called"); |
| 1856 | |||
| 1857 | system.GetUserChannel().clear(); | ||
| 1844 | 1858 | ||
| 1845 | IPC::ResponseBuilder rb{ctx, 2}; | 1859 | IPC::ResponseBuilder rb{ctx, 2}; |
| 1846 | rb.Push(ResultSuccess); | 1860 | rb.Push(ResultSuccess); |
| 1847 | } | 1861 | } |
| 1848 | 1862 | ||
| 1849 | void IApplicationFunctions::UnpopToUserChannel(HLERequestContext& ctx) { | 1863 | void IApplicationFunctions::UnpopToUserChannel(HLERequestContext& ctx) { |
| 1850 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 1864 | LOG_DEBUG(Service_AM, "called"); |
| 1865 | |||
| 1866 | IPC::RequestParser rp{ctx}; | ||
| 1867 | const auto storage = rp.PopIpcInterface<IStorage>().lock(); | ||
| 1868 | if (storage) { | ||
| 1869 | system.GetUserChannel().push_back(storage->GetData()); | ||
| 1870 | } | ||
| 1851 | 1871 | ||
| 1852 | IPC::ResponseBuilder rb{ctx, 2}; | 1872 | IPC::ResponseBuilder rb{ctx, 2}; |
| 1853 | rb.Push(ResultSuccess); | 1873 | rb.Push(ResultSuccess); |