aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDjihads <76681596+Djihads80@users.noreply.github.com>2026-10-30 09:02:43 +0100
committerGitHub <noreply@github.com>2026-10-30 09:02:43 +0100
commitc4b0289c33db9049ddd9a8b43e0089ea70e851c1 (patch)
treea1770524ff7c5177a5664989d173acbb3d2d1297 /src
parent467ec722581e7ad573491c5662bcd9544eadd2ed (diff)
parentf4b0c80401605ad66b255f91d8fb9cdcd31932d8 (diff)
Merge branch 'nx2' into fix/vfs-open-file-limit
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/renderer/system.cpp5
-rw-r--r--src/core/hle/service/audio/audio_renderer.cpp6
-rw-r--r--src/core/hle/service/audio/audio_renderer.h5
-rw-r--r--src/core/hle/service/audio/audio_renderer_manager.cpp4
-rw-r--r--src/core/hle/service/audio/audio_renderer_manager.h2
-rw-r--r--src/core/hle/service/nx2_gsv.h25
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp14
-rw-r--r--src/yuzu/bootmanager.cpp7
-rw-r--r--src/yuzu/main.cpp4
-rw-r--r--src/yuzu/main_window.cpp46
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);
}
}