diff options
| -rw-r--r-- | src/android/app/src/main/jni/native.cpp | 1 | ||||
| -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 | 40 | ||||
| -rw-r--r-- | src/yuzu/game_list.cpp | 6 | ||||
| -rw-r--r-- | src/yuzu/game_list.h | 3 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 14 | ||||
| -rw-r--r-- | src/yuzu/main.h | 11 | ||||
| -rw-r--r-- | src/yuzu_cmd/yuzu.cpp | 1 |
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 | ||
| 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 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 | ||
| 1554 | void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) { | 1566 | void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) { |
| @@ -1840,14 +1852,22 @@ void IApplicationFunctions::ExecuteProgram(HLERequestContext& ctx) { | |||
| 1840 | } | 1852 | } |
| 1841 | 1853 | ||
| 1842 | void IApplicationFunctions::ClearUserChannel(HLERequestContext& ctx) { | 1854 | void 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 | ||
| 1849 | void IApplicationFunctions::UnpopToUserChannel(HLERequestContext& ctx) { | 1863 | void 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; | |||
| 28 | class GameListSearchField; | 28 | class GameListSearchField; |
| 29 | class GameListDir; | 29 | class GameListDir; |
| 30 | class GMainWindow; | 30 | class GMainWindow; |
| 31 | enum class AmLaunchType; | ||
| 31 | enum class StartGameType; | 32 | enum class StartGameType; |
| 32 | 33 | ||
| 33 | namespace FileSys { | 34 | namespace FileSys { |
| @@ -103,7 +104,7 @@ public: | |||
| 103 | 104 | ||
| 104 | signals: | 105 | signals: |
| 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 | ||
| 1701 | bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t program_index) { | 1701 | bool 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 | ||
| 1851 | void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index, | 1856 | void 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 | ||
| 3315 | void GMainWindow::OnExecuteProgram(std::size_t program_index) { | 3320 | void 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 | ||
| 3320 | void GMainWindow::OnExit() { | 3326 | void 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 | ||
| 61 | enum class AmLaunchType { | ||
| 62 | UserInitiated, | ||
| 63 | ApplicationInitiated, | ||
| 64 | }; | ||
| 65 | |||
| 61 | namespace Core { | 66 | namespace Core { |
| 62 | enum class SystemResultStatus : u32; | 67 | enum class SystemResultStatus : u32; |
| 63 | class System; | 68 | class 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 | ||