diff options
Diffstat (limited to '')
| -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 | 57 | ||||
| -rw-r--r-- | src/core/hle/service/am/am.h | 1 | ||||
| -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 |
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 | ||
| 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; |
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; | |||
| 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 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 | ||
| 1708 | bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t program_index) { | 1708 | bool 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 | ||
| 1858 | void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index, | 1863 | void 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 | ||
| 3370 | void GMainWindow::OnExecuteProgram(std::size_t program_index) { | 3375 | void 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 | ||
| 3375 | void GMainWindow::OnExit() { | 3381 | void 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 | ||
| 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 | ||