diff options
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 | 57 | ||||
| -rw-r--r-- | src/core/hle/service/am/am.h | 1 |
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 | ||
| 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 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}; | |||
| 46 | constexpr Result ResultInvalidOffset{ErrorModule::AM, 503}; | 46 | constexpr Result ResultInvalidOffset{ErrorModule::AM, 503}; |
| 47 | 47 | ||
| 48 | enum class LaunchParameterKind : u32 { | 48 | enum 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 | ||
| 1569 | void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) { | 1566 | void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) { |
| @@ -1855,14 +1852,22 @@ void IApplicationFunctions::ExecuteProgram(HLERequestContext& ctx) { | |||
| 1855 | } | 1852 | } |
| 1856 | 1853 | ||
| 1857 | void IApplicationFunctions::ClearUserChannel(HLERequestContext& ctx) { | 1854 | void 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 | ||
| 1864 | void IApplicationFunctions::UnpopToUserChannel(HLERequestContext& ctx) { | 1863 | void 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; |