diff options
| author | Djihads <76681596+Djihads80@users.noreply.github.com> | 2026-10-30 09:02:43 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-10-30 09:02:43 +0100 |
| commit | c4b0289c33db9049ddd9a8b43e0089ea70e851c1 (patch) | |
| tree | a1770524ff7c5177a5664989d173acbb3d2d1297 /src | |
| parent | 467ec722581e7ad573491c5662bcd9544eadd2ed (diff) | |
| parent | f4b0c80401605ad66b255f91d8fb9cdcd31932d8 (diff) | |
Merge branch 'nx2' into fix/vfs-open-file-limit
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio_core/renderer/system.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audio_renderer.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audio_renderer.h | 5 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audio_renderer_manager.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audio_renderer_manager.h | 2 | ||||
| -rw-r--r-- | src/core/hle/service/nx2_gsv.h | 25 | ||||
| -rw-r--r-- | src/core/loader/deconstructed_rom_directory.cpp | 14 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.cpp | 7 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 4 | ||||
| -rw-r--r-- | src/yuzu/main_window.cpp | 46 |
10 files changed, 98 insertions, 20 deletions
diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp index b7675ff5de..2e3e741d3e 100644 --- a/src/audio_core/renderer/system.cpp +++ b/src/audio_core/renderer/system.cpp @@ -444,7 +444,10 @@ void System::Stop() { } if (execution_mode == ExecutionMode::Auto) { - terminate_event.Wait(); + // The system manager thread signals this; it may already be gone during shutdown. + if (!terminate_event.WaitFor(std::chrono::seconds(1))) { + LOG_WARNING(Service_Audio, "Timed out waiting for the renderer to terminate"); + } } } diff --git a/src/core/hle/service/audio/audio_renderer.cpp b/src/core/hle/service/audio/audio_renderer.cpp index dd76544094..49ca3c434b 100644 --- a/src/core/hle/service/audio/audio_renderer.cpp +++ b/src/core/hle/service/audio/audio_renderer.cpp @@ -10,14 +10,14 @@ namespace Service::Audio { using namespace AudioCore::Renderer; -IAudioRenderer::IAudioRenderer(Core::System& system_, Manager& manager_, +IAudioRenderer::IAudioRenderer(Core::System& system_, std::shared_ptr<Manager> manager_, AudioCore::AudioRendererParameterInternal& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, Kernel::KProcess* process_handle_, u64 applet_resource_user_id, s32 session_id) : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"}, - rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_}, - impl{std::make_unique<Renderer>(system_, manager, rendered_event)}, process_handle{ + rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{std::move(manager_)}, + impl{std::make_unique<Renderer>(system_, *manager, rendered_event)}, process_handle{ process_handle_} { // clang-format off static const FunctionInfo functions[] = { diff --git a/src/core/hle/service/audio/audio_renderer.h b/src/core/hle/service/audio/audio_renderer.h index 7f4ea9a662..d7fb1daf99 100644 --- a/src/core/hle/service/audio/audio_renderer.h +++ b/src/core/hle/service/audio/audio_renderer.h @@ -19,7 +19,7 @@ namespace Service::Audio { class IAudioRenderer final : public ServiceFramework<IAudioRenderer> { public: - explicit IAudioRenderer(Core::System& system_, AudioCore::Renderer::Manager& manager_, + explicit IAudioRenderer(Core::System& system_, std::shared_ptr<AudioCore::Renderer::Manager> manager_, AudioCore::AudioRendererParameterInternal& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, Kernel::KProcess* process_handle_, u64 applet_resource_user_id, @@ -47,7 +47,8 @@ private: KernelHelpers::ServiceContext service_context; Kernel::KEvent* rendered_event; - AudioCore::Renderer::Manager& manager; + // Keeps the manager alive for as long as this renderer session exists. + std::shared_ptr<AudioCore::Renderer::Manager> manager; std::unique_ptr<AudioCore::Renderer::Renderer> impl; Kernel::KProcess* process_handle; Common::ScratchBuffer<u8> output_buffer; diff --git a/src/core/hle/service/audio/audio_renderer_manager.cpp b/src/core/hle/service/audio/audio_renderer_manager.cpp index 4756802eeb..97d9f44ddd 100644 --- a/src/core/hle/service/audio/audio_renderer_manager.cpp +++ b/src/core/hle/service/audio/audio_renderer_manager.cpp @@ -20,7 +20,7 @@ using namespace AudioCore::Renderer; IAudioRendererManager::IAudioRendererManager(Core::System& system_) : ServiceFramework{system_, "audren:u"} - , impl(system_) + , impl(std::make_shared<AudioCore::Renderer::Manager>(system_)) { // clang-format off static const FunctionInfo functions[] = { @@ -64,7 +64,7 @@ Result IAudioRendererManager::OpenAudioRenderer( impl->GetSessionCount()); *out_audio_renderer = - std::make_shared<IAudioRenderer>(system, *impl, parameter, tmem_handle.Get(), tmem_size, + std::make_shared<IAudioRenderer>(system, impl, parameter, tmem_handle.Get(), tmem_size, process_handle.Get(), aruid.pid, session_id); R_SUCCEED(); } diff --git a/src/core/hle/service/audio/audio_renderer_manager.h b/src/core/hle/service/audio/audio_renderer_manager.h index fdce8b6ffa..f23691dbc8 100644 --- a/src/core/hle/service/audio/audio_renderer_manager.h +++ b/src/core/hle/service/audio/audio_renderer_manager.h @@ -33,7 +33,7 @@ private: Result GetAudioDeviceServiceWithRevisionInfo(Out<SharedPointer<IAudioDevice>> out_audio_device, u32 revision, ClientAppletResourceUserId aruid); - std::optional<AudioCore::Renderer::Manager> impl; + std::shared_ptr<AudioCore::Renderer::Manager> impl; u32 num_audio_devices{0}; }; diff --git a/src/core/hle/service/nx2_gsv.h b/src/core/hle/service/nx2_gsv.h index fb1436bd5e..caf4a452c4 100644 --- a/src/core/hle/service/nx2_gsv.h +++ b/src/core/hle/service/nx2_gsv.h @@ -929,6 +929,29 @@ private: image_id, address); return; } + u32 crop_width = layout.width; + u32 crop_height = layout.height; + if (system.GetApplicationProcessProgramID() == 0x0400C3F00006E000ULL && + layout.width == 3840 && layout.height == 2160) { + crop_width = 2560; + crop_height = 1440; + } + static const u32 env_crop_w = [] { + const char* v = std::getenv("EDEN_NX2_CROP_WIDTH"); + return v ? static_cast<u32>(std::strtoul(v, nullptr, 10)) : 0U; + }(); + static const u32 env_crop_h = [] { + const char* v = std::getenv("EDEN_NX2_CROP_HEIGHT"); + return v ? static_cast<u32>(std::strtoul(v, nullptr, 10)) : 0U; + }(); + if (env_crop_w != 0 && env_crop_h != 0) { + crop_width = env_crop_w; + crop_height = env_crop_h; + } + if (m_presents <= 4) { + LOG_INFO(Service, "nx2:vi2 composite image {} layout {}x{}, crop {}x{}", + image_id, layout.width, layout.height, crop_width, crop_height); + } std::vector<Tegra::FramebufferConfig> layers{Tegra::FramebufferConfig{ .address = *device, .offset = 0, @@ -937,7 +960,7 @@ private: .stride = static_cast<u32>(layout.pitch / 4), .pixel_format = android::PixelFormat::Rgba8888, .transform_flags = android::BufferTransformFlags::Unset, - .crop_rect = {0, 0, static_cast<int>(layout.width), static_cast<int>(layout.height)}, + .crop_rect = {0, 0, static_cast<int>(crop_width), static_cast<int>(crop_height)}, .blending = Tegra::BlendMode::Opaque, .native_tiling = true, }}; diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 458e0210a0..62ea7ebe1d 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -214,6 +214,20 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect } metadata.Print(); + // Loose-ExeFS loads bypass the NCA/NSP loaders, which are the ones that normally apply + // LayeredFS to the RomFS; apply it here so mods in user/load/<titleid>/ work too. + if (romfs != nullptr) { + const FileSys::PatchManager patch_manager(metadata.GetTitleID(), + system.GetFileSystemController(), + system.GetContentProvider()); + auto patched = patch_manager.PatchRomFS(nullptr, romfs); + if (patched != nullptr) { + romfs = std::move(patched); + LOG_INFO(Loader, "Applied RomFS patches (LayeredFS) for title {:016X}", + metadata.GetTitleID()); + } + } + // Enable NCE only for applications with 39-bit address space. const bool is_39bit = metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is39Bit; diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 57cc395ae8..7b68e0761b 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -764,12 +764,15 @@ bool GRenderWindow::InitRenderTarget() { // Update the Window System information with the new render target window_info = QtCommon::GetWindowSystemInfo(child_widget->windowHandle()); - child_widget->resize(Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height); + const auto target_width = Settings::IsDockedMode() ? Layout::ScreenDocked::Width : Layout::ScreenUndocked::Width; + const auto target_height = Settings::IsDockedMode() ? Layout::ScreenDocked::Height : Layout::ScreenUndocked::Height; + + child_widget->resize(target_width, target_height); layout()->addWidget(child_widget); // Reset minimum required size to avoid resizing issues on the main window after restarting. setMinimumSize(1, 1); - resize(Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height); + resize(target_width, target_height); OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); OnFramebufferSizeChanged(); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index c7616e0151..32292afa5f 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -125,8 +125,8 @@ int main(int argc, char* argv[]) { // Raise the open file limit to at least 8192, or the hard limit. // Most sane systems should not hit the hard limit here. struct rlimit rl; - if (getrlimit(RLIMIT_NOFILE, &rl) == 0 && rl.rlim_cur < 8192) { - rl.rlim_cur = std::min<rlim_t>(8192, rl.rlim_max); + if (getrlimit(RLIMIT_NOFILE, &rl) == 0) { + rl.rlim_cur = std::min<rlim_t>(1048576, rl.rlim_max); setrlimit(RLIMIT_NOFILE, &rl); } #endif // _WIN32 diff --git a/src/yuzu/main_window.cpp b/src/yuzu/main_window.cpp index f19b827a32..13359620dd 100644 --- a/src/yuzu/main_window.cpp +++ b/src/yuzu/main_window.cpp @@ -2049,6 +2049,12 @@ void MainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletPa emulation_running = true; if (ui->action_Fullscreen->isChecked()) { ShowFullscreen(); + } else { + if (Settings::IsDockedMode()) { + ResetWindowSize1080(); + } else { + ResetWindowSize720(); + } } OnStartGame(); } @@ -2129,7 +2135,11 @@ void MainWindow::OnEmulationStopped() { shutdown_timer.stop(); if (QtCommon::emu_thread) { QtCommon::emu_thread->disconnect(); - QtCommon::emu_thread->wait(); + if (!QtCommon::emu_thread->wait(QDeadlineTimer(10'000))) { + LOG_ERROR(Frontend, "Emulation thread failed to stop, terminating it"); + QtCommon::emu_thread->terminate(); + QtCommon::emu_thread->wait(); + } QtCommon::emu_thread.reset(); } @@ -3311,12 +3321,36 @@ void MainWindow::ToggleWindowMode() { void MainWindow::ResetWindowSize(u32 width, u32 height) { const auto aspect_ratio = Layout::EmulationAspectRatio(Settings::values.aspect_ratio.GetValue(), float(height) / width); - if (!ui->action_Single_Window_Mode->isChecked()) { - render_window->resize(height / aspect_ratio, height); + const bool single_window = ui->action_Single_Window_Mode->isChecked(); + const bool show_status_bar = ui->action_Show_Status_Bar->isChecked(); + const auto status_bar_height = (single_window && show_status_bar) ? statusBar()->height() : 0; + const auto menu_bar_height = single_window ? menuBar()->height() : 0; + const auto extra_height = menu_bar_height + status_bar_height; + + auto* current_screen = this->screen(); + if (!current_screen) { + current_screen = QGuiApplication::primaryScreen(); + } + const auto available = current_screen ? current_screen->availableGeometry() : QRect(); + + u32 target_h = height; + u32 target_w = static_cast<u32>(std::round(height / aspect_ratio)); + + if (!available.isEmpty()) { + const int max_w = available.width(); + const int max_h = available.height() - extra_height; + if (max_w > 0 && max_h > 0 && + (target_w > static_cast<u32>(max_w) || target_h > static_cast<u32>(max_h))) { + const float scale = (std::min)(float(max_w) / target_w, float(max_h) / target_h); + target_w = (std::max)(1U, static_cast<u32>(std::round(target_w * scale))); + target_h = (std::max)(1U, static_cast<u32>(std::round(target_h * scale))); + } + } + + if (!single_window) { + render_window->resize(target_w, target_h); } else { - const bool show_status_bar = ui->action_Show_Status_Bar->isChecked(); - const auto status_bar_height = show_status_bar ? statusBar()->height() : 0; - resize(height / aspect_ratio, height + menuBar()->height() + status_bar_height); + resize(target_w, target_h + extra_height); } } |
