summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-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.cpp57
-rw-r--r--src/core/hle/service/am/am.h1
-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
10 files changed, 71 insertions, 36 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 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;
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index 6842ced3e..f254c1e1c 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -589,10 +589,12 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
589 emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData, path); 589 emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData, path);
590 }); 590 });
591 connect(start_game, &QAction::triggered, [this, path]() { 591 connect(start_game, &QAction::triggered, [this, path]() {
592 emit BootGame(QString::fromStdString(path), 0, 0, StartGameType::Normal); 592 emit BootGame(QString::fromStdString(path), 0, 0, StartGameType::Normal,
593 AmLaunchType::UserInitiated);
593 }); 594 });
594 connect(start_game_global, &QAction::triggered, [this, path]() { 595 connect(start_game_global, &QAction::triggered, [this, path]() {
595 emit BootGame(QString::fromStdString(path), 0, 0, StartGameType::Global); 596 emit BootGame(QString::fromStdString(path), 0, 0, StartGameType::Global,
597 AmLaunchType::UserInitiated);
596 }); 598 });
597 connect(open_mod_location, &QAction::triggered, [this, program_id, path]() { 599 connect(open_mod_location, &QAction::triggered, [this, program_id, path]() {
598 emit OpenFolderRequested(program_id, GameListOpenTarget::ModData, path); 600 emit OpenFolderRequested(program_id, GameListOpenTarget::ModData, path);
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h
index 8aea646b2..1fcbbf0ba 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 9cea60c32..1540fe1c1 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1705,7 +1705,8 @@ void GMainWindow::AllowOSSleep() {
1705#endif 1705#endif
1706} 1706}
1707 1707
1708bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t program_index) { 1708bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t program_index,
1709 AmLaunchType launch_type) {
1709 // Shutdown previous session if the emu thread is still active... 1710 // Shutdown previous session if the emu thread is still active...
1710 if (emu_thread != nullptr) { 1711 if (emu_thread != nullptr) {
1711 ShutdownGame(); 1712 ShutdownGame();
@@ -1717,6 +1718,10 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p
1717 1718
1718 system->SetFilesystem(vfs); 1719 system->SetFilesystem(vfs);
1719 1720
1721 if (launch_type == AmLaunchType::UserInitiated) {
1722 system->GetUserChannel().clear();
1723 }
1724
1720 system->SetAppletFrontendSet({ 1725 system->SetAppletFrontendSet({
1721 std::make_unique<QtAmiiboSettings>(*this), // Amiibo Settings 1726 std::make_unique<QtAmiiboSettings>(*this), // Amiibo Settings
1722 (UISettings::values.controller_applet_disabled.GetValue() == true) 1727 (UISettings::values.controller_applet_disabled.GetValue() == true)
@@ -1856,7 +1861,7 @@ void GMainWindow::ConfigureFilesystemProvider(const std::string& filepath) {
1856} 1861}
1857 1862
1858void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index, 1863void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index,
1859 StartGameType type) { 1864 StartGameType type, AmLaunchType launch_type) {
1860 LOG_INFO(Frontend, "yuzu starting..."); 1865 LOG_INFO(Frontend, "yuzu starting...");
1861 StoreRecentFile(filename); // Put the filename on top of the list 1866 StoreRecentFile(filename); // Put the filename on top of the list
1862 1867
@@ -1900,7 +1905,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
1900 } 1905 }
1901 } 1906 }
1902 1907
1903 if (!LoadROM(filename, program_id, program_index)) { 1908 if (!LoadROM(filename, program_id, program_index, launch_type)) {
1904 return; 1909 return;
1905 } 1910 }
1906 1911
@@ -3369,7 +3374,8 @@ void GMainWindow::OnLoadComplete() {
3369 3374
3370void GMainWindow::OnExecuteProgram(std::size_t program_index) { 3375void GMainWindow::OnExecuteProgram(std::size_t program_index) {
3371 ShutdownGame(); 3376 ShutdownGame();
3372 BootGame(last_filename_booted, 0, program_index); 3377 BootGame(last_filename_booted, 0, program_index, StartGameType::Normal,
3378 AmLaunchType::ApplicationInitiated);
3373} 3379}
3374 3380
3375void GMainWindow::OnExit() { 3381void GMainWindow::OnExit() {
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 1e4f6e477..3b0e7f2fe 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