summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar FearlessTobi2023-09-10 02:36:26 +0200
committerGravatar Liam2023-09-10 15:39:25 -0400
commit87c0ba129ce38dd3b001fbef8021590a127fb1a8 (patch)
tree28fa19ccd43fceeec31e433d32dae41e88d2b17e /src/core
parentam: Remove bcat from PopLaunchParameter (diff)
downloadyuzu-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.cpp6
-rw-r--r--src/core/core.h7
-rw-r--r--src/core/hle/service/am/am.cpp40
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
567System::System() : impl{std::make_unique<Impl>(*this)} {} 569System::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
1041std::deque<std::vector<u8>>& System::GetUserChannel() {
1042 return impl->user_channel;
1043}
1044
1039void System::RegisterExitCallback(ExitCallback&& callback) { 1045void 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
1554void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) { 1566void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) {
@@ -1840,14 +1852,22 @@ void IApplicationFunctions::ExecuteProgram(HLERequestContext& ctx) {
1840} 1852}
1841 1853
1842void IApplicationFunctions::ClearUserChannel(HLERequestContext& ctx) { 1854void 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
1849void IApplicationFunctions::UnpopToUserChannel(HLERequestContext& ctx) { 1863void 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);