summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
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.cpp57
-rw-r--r--src/core/hle/service/am/am.h1
4 files changed, 44 insertions, 27 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 e92f400de..f9c4f9678 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -46,7 +46,7 @@ constexpr Result ResultNoMessages{ErrorModule::AM, 3};
46constexpr Result ResultInvalidOffset{ErrorModule::AM, 503}; 46constexpr Result ResultInvalidOffset{ErrorModule::AM, 503};
47 47
48enum class LaunchParameterKind : u32 { 48enum class LaunchParameterKind : u32 {
49 ApplicationSpecific = 1, 49 UserChannel = 1,
50 AccountPreselectedUser = 2, 50 AccountPreselectedUser = 2,
51}; 51};
52 52
@@ -1518,27 +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_DEBUG(Service_AM, "called, kind={:08X}", kind); 1521 LOG_INFO(Service_AM, "called, kind={:08X}", kind);
1522 1522
1523 if (kind == LaunchParameterKind::ApplicationSpecific && !launch_popped_application_specific) { 1523 if (kind == LaunchParameterKind::UserChannel) {
1524 const auto backend = BCAT::CreateBackendFromSettings(system, [this](u64 tid) { 1524 auto channel = system.GetUserChannel();
1525 return system.GetFileSystemController().GetBCATDirectory(tid); 1525 if (channel.empty()) {
1526 }); 1526 LOG_ERROR(Service_AM, "Attempted to load launch parameter but none was found!");
1527 const auto build_id_full = system.GetApplicationProcessBuildID(); 1527 IPC::ResponseBuilder rb{ctx, 2};
1528 u64 build_id{}; 1528 rb.Push(AM::ResultNoDataInChannel);
1529 std::memcpy(&build_id, build_id_full.data(), sizeof(u64));
1530
1531 auto data =
1532 backend->GetLaunchParameter({system.GetApplicationProcessProgramID(), build_id});
1533 if (data.has_value()) {
1534 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1535 rb.Push(ResultSuccess);
1536 rb.PushIpcInterface<IStorage>(system, std::move(*data));
1537 launch_popped_application_specific = true;
1538 return; 1529 return;
1539 } 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));
1540 } else if (kind == LaunchParameterKind::AccountPreselectedUser && 1538 } else if (kind == LaunchParameterKind::AccountPreselectedUser &&
1541 !launch_popped_account_preselect) { 1539 !launch_popped_account_preselect) {
1540 // TODO: Verify this is hw-accurate
1542 LaunchParameterAccountPreselectedUser params{}; 1541 LaunchParameterAccountPreselectedUser params{};
1543 1542
1544 params.magic = LAUNCH_PARAMETER_ACCOUNT_PRESELECTED_USER_MAGIC; 1543 params.magic = LAUNCH_PARAMETER_ACCOUNT_PRESELECTED_USER_MAGIC;
@@ -1550,7 +1549,6 @@ void IApplicationFunctions::PopLaunchParameter(HLERequestContext& ctx) {
1550 params.current_user = *uuid; 1549 params.current_user = *uuid;
1551 1550
1552 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1551 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1553
1554 rb.Push(ResultSuccess); 1552 rb.Push(ResultSuccess);
1555 1553
1556 std::vector<u8> buffer(sizeof(LaunchParameterAccountPreselectedUser)); 1554 std::vector<u8> buffer(sizeof(LaunchParameterAccountPreselectedUser));
@@ -1558,12 +1556,11 @@ void IApplicationFunctions::PopLaunchParameter(HLERequestContext& ctx) {
1558 1556
1559 rb.PushIpcInterface<IStorage>(system, std::move(buffer)); 1557 rb.PushIpcInterface<IStorage>(system, std::move(buffer));
1560 launch_popped_account_preselect = true; 1558 launch_popped_account_preselect = true;
1561 return; 1559 } else {
1560 LOG_ERROR(Service_AM, "Unknown launch parameter kind.");
1561 IPC::ResponseBuilder rb{ctx, 2};
1562 rb.Push(AM::ResultNoDataInChannel);
1562 } 1563 }
1563
1564 LOG_ERROR(Service_AM, "Attempted to load launch parameter but none was found!");
1565 IPC::ResponseBuilder rb{ctx, 2};
1566 rb.Push(AM::ResultNoDataInChannel);
1567} 1564}
1568 1565
1569void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) { 1566void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) {
@@ -1855,14 +1852,22 @@ void IApplicationFunctions::ExecuteProgram(HLERequestContext& ctx) {
1855} 1852}
1856 1853
1857void IApplicationFunctions::ClearUserChannel(HLERequestContext& ctx) { 1854void IApplicationFunctions::ClearUserChannel(HLERequestContext& ctx) {
1858 LOG_WARNING(Service_AM, "(STUBBED) called"); 1855 LOG_DEBUG(Service_AM, "called");
1856
1857 system.GetUserChannel().clear();
1859 1858
1860 IPC::ResponseBuilder rb{ctx, 2}; 1859 IPC::ResponseBuilder rb{ctx, 2};
1861 rb.Push(ResultSuccess); 1860 rb.Push(ResultSuccess);
1862} 1861}
1863 1862
1864void IApplicationFunctions::UnpopToUserChannel(HLERequestContext& ctx) { 1863void IApplicationFunctions::UnpopToUserChannel(HLERequestContext& ctx) {
1865 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 }
1866 1871
1867 IPC::ResponseBuilder rb{ctx, 2}; 1872 IPC::ResponseBuilder rb{ctx, 2};
1868 rb.Push(ResultSuccess); 1873 rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index d68998f04..f75a665b2 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -339,7 +339,6 @@ private:
339 339
340 KernelHelpers::ServiceContext service_context; 340 KernelHelpers::ServiceContext service_context;
341 341
342 bool launch_popped_application_specific = false;
343 bool launch_popped_account_preselect = false; 342 bool launch_popped_account_preselect = false;
344 s32 previous_program_index{-1}; 343 s32 previous_program_index{-1};
345 Kernel::KEvent* gpu_error_detected_event; 344 Kernel::KEvent* gpu_error_detected_event;