summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/android/app/src/main/jni/native.cpp1
-rw-r--r--src/core/core.cpp6
-rw-r--r--src/core/core.h7
-rw-r--r--src/core/hle/service/am/am.cpp40
-rw-r--r--src/yuzu/game_list.cpp6
-rw-r--r--src/yuzu/game_list.h3
-rw-r--r--src/yuzu/main.cpp14
-rw-r--r--src/yuzu/main.h11
-rw-r--r--src/yuzu_cmd/yuzu.cpp1
9 files changed, 70 insertions, 19 deletions
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index 0f2a6d9e4..b9ecefa74 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -270,6 +270,7 @@ public:
270 m_vulkan_library); 270 m_vulkan_library);
271 271
272 m_system.SetFilesystem(m_vfs); 272 m_system.SetFilesystem(m_vfs);
273 m_system.GetUserChannel().clear();
273 274
274 // Initialize system. 275 // Initialize system.
275 jauto android_keyboard = std::make_unique<SoftwareKeyboard::AndroidKeyboard>(); 276 jauto android_keyboard = std::make_unique<SoftwareKeyboard::AndroidKeyboard>();
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);
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index b5a02700d..c29d762c2 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -588,10 +588,12 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
588 emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData, path); 588 emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData, path);
589 }); 589 });
590 connect(start_game, &QAction::triggered, [this, path]() { 590 connect(start_game, &QAction::triggered, [this, path]() {
591 emit BootGame(QString::fromStdString(path), 0, 0, StartGameType::Normal); 591 emit BootGame(QString::fromStdString(path), 0, 0, StartGameType::Normal,
592 AmLaunchType::UserInitiated);
592 }); 593 });
593 connect(start_game_global, &QAction::triggered, [this, path]() { 594 connect(start_game_global, &QAction::triggered, [this, path]() {
594 emit BootGame(QString::fromStdString(path), 0, 0, StartGameType::Global); 595 emit BootGame(QString::fromStdString(path), 0, 0, StartGameType::Global,
596 AmLaunchType::UserInitiated);
595 }); 597 });
596 connect(open_mod_location, &QAction::triggered, [this, program_id, path]() { 598 connect(open_mod_location, &QAction::triggered, [this, program_id, path]() {
597 emit OpenFolderRequested(program_id, GameListOpenTarget::ModData, path); 599 emit OpenFolderRequested(program_id, GameListOpenTarget::ModData, path);
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h
index 6c2f75e53..45d6dee88 100644
--- a/src/yuzu/game_list.h
+++ b/src/yuzu/game_list.h
@@ -28,6 +28,7 @@ class GameListWorker;
28class GameListSearchField; 28class GameListSearchField;
29class GameListDir; 29class GameListDir;
30class GMainWindow; 30class GMainWindow;
31enum class AmLaunchType;
31enum class StartGameType; 32enum class StartGameType;
32 33
33namespace FileSys { 34namespace FileSys {
@@ -103,7 +104,7 @@ public:
103 104
104signals: 105signals:
105 void BootGame(const QString& game_path, u64 program_id, std::size_t program_index, 106 void BootGame(const QString& game_path, u64 program_id, std::size_t program_index,
106 StartGameType type); 107 StartGameType type, AmLaunchType launch_type);
107 void GameChosen(const QString& game_path, const u64 title_id = 0); 108 void GameChosen(const QString& game_path, const u64 title_id = 0);
108 void ShouldCancelWorker(); 109 void ShouldCancelWorker();
109 void OpenFolderRequested(u64 program_id, GameListOpenTarget target, 110 void OpenFolderRequested(u64 program_id, GameListOpenTarget target,
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 4e435c7e2..538174462 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1698,7 +1698,8 @@ void GMainWindow::AllowOSSleep() {
1698#endif 1698#endif
1699} 1699}
1700 1700
1701bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t program_index) { 1701bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t program_index,
1702 AmLaunchType launch_type) {
1702 // Shutdown previous session if the emu thread is still active... 1703 // Shutdown previous session if the emu thread is still active...
1703 if (emu_thread != nullptr) { 1704 if (emu_thread != nullptr) {
1704 ShutdownGame(); 1705 ShutdownGame();
@@ -1710,6 +1711,10 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p
1710 1711
1711 system->SetFilesystem(vfs); 1712 system->SetFilesystem(vfs);
1712 1713
1714 if (launch_type == AmLaunchType::UserInitiated) {
1715 system->GetUserChannel().clear();
1716 }
1717
1713 system->SetAppletFrontendSet({ 1718 system->SetAppletFrontendSet({
1714 std::make_unique<QtAmiiboSettings>(*this), // Amiibo Settings 1719 std::make_unique<QtAmiiboSettings>(*this), // Amiibo Settings
1715 (UISettings::values.controller_applet_disabled.GetValue() == true) 1720 (UISettings::values.controller_applet_disabled.GetValue() == true)
@@ -1849,7 +1854,7 @@ void GMainWindow::ConfigureFilesystemProvider(const std::string& filepath) {
1849} 1854}
1850 1855
1851void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index, 1856void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index,
1852 StartGameType type) { 1857 StartGameType type, AmLaunchType launch_type) {
1853 LOG_INFO(Frontend, "yuzu starting..."); 1858 LOG_INFO(Frontend, "yuzu starting...");
1854 StoreRecentFile(filename); // Put the filename on top of the list 1859 StoreRecentFile(filename); // Put the filename on top of the list
1855 1860
@@ -1893,7 +1898,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
1893 } 1898 }
1894 } 1899 }
1895 1900
1896 if (!LoadROM(filename, program_id, program_index)) { 1901 if (!LoadROM(filename, program_id, program_index, launch_type)) {
1897 return; 1902 return;
1898 } 1903 }
1899 1904
@@ -3314,7 +3319,8 @@ void GMainWindow::OnLoadComplete() {
3314 3319
3315void GMainWindow::OnExecuteProgram(std::size_t program_index) { 3320void GMainWindow::OnExecuteProgram(std::size_t program_index) {
3316 ShutdownGame(); 3321 ShutdownGame();
3317 BootGame(last_filename_booted, 0, program_index); 3322 BootGame(last_filename_booted, 0, program_index, StartGameType::Normal,
3323 AmLaunchType::ApplicationInitiated);
3318} 3324}
3319 3325
3320void GMainWindow::OnExit() { 3326void GMainWindow::OnExit() {
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 668dbc3b1..fd8b196c3 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -58,6 +58,11 @@ enum class StartGameType {
58 Global, // Only uses global configuration 58 Global, // Only uses global configuration
59}; 59};
60 60
61enum class AmLaunchType {
62 UserInitiated,
63 ApplicationInitiated,
64};
65
61namespace Core { 66namespace Core {
62enum class SystemResultStatus : u32; 67enum class SystemResultStatus : u32;
63class System; 68class System;
@@ -239,9 +244,11 @@ private:
239 void PreventOSSleep(); 244 void PreventOSSleep();
240 void AllowOSSleep(); 245 void AllowOSSleep();
241 246
242 bool LoadROM(const QString& filename, u64 program_id, std::size_t program_index); 247 bool LoadROM(const QString& filename, u64 program_id, std::size_t program_index,
248 AmLaunchType launch_type);
243 void BootGame(const QString& filename, u64 program_id = 0, std::size_t program_index = 0, 249 void BootGame(const QString& filename, u64 program_id = 0, std::size_t program_index = 0,
244 StartGameType with_config = StartGameType::Normal); 250 StartGameType with_config = StartGameType::Normal,
251 AmLaunchType launch_type = AmLaunchType::UserInitiated);
245 void ShutdownGame(); 252 void ShutdownGame();
246 253
247 void ShowTelemetryCallout(); 254 void ShowTelemetryCallout();
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index c1695cc6e..55d0938f7 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -358,6 +358,7 @@ int main(int argc, char** argv) {
358 system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>()); 358 system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
359 system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>()); 359 system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>());
360 system.GetFileSystemController().CreateFactories(*system.GetFilesystem()); 360 system.GetFileSystemController().CreateFactories(*system.GetFilesystem());
361 system.GetUserChannel().clear();
361 362
362 const Core::SystemResultStatus load_result{system.Load(*emu_window, filepath)}; 363 const Core::SystemResultStatus load_result{system.Load(*emu_window, filepath)};
363 364