diff --git a/README.md b/README.md index 8513759f6..3d306778c 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2118. +This is the source code for early-access 2121. ## Legal Notice diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index ab6211b29..ecb00d428 100755 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp @@ -170,7 +170,8 @@ public: float GetAxis(int axis, float range, float offset) const { std::lock_guard lock{mutex}; const float value = static_cast(state.axes.at(axis)) / 32767.0f; - return (value + offset) / range; + const float offset_scale = (value + offset) > 0.0f ? 1.0f + offset : 1.0f - offset; + return (value + offset) / range / offset_scale; } bool RumblePlay(u16 amp_low, u16 amp_high) { @@ -789,8 +790,8 @@ public: const std::string invert_y_value = params.Get("invert_y", "+"); const bool invert_x = invert_x_value == "-"; const bool invert_y = invert_y_value == "-"; - const float offset_x = params.Get("offset_x", 0.0f); - const float offset_y = params.Get("offset_y", 0.0f); + const float offset_x = std::clamp(params.Get("offset_x", 0.0f), -0.99f, 0.99f); + const float offset_y = std::clamp(params.Get("offset_y", 0.0f), -0.99f, 0.99f); auto joystick = state.GetSDLJoystickByGUID(guid, port); // This is necessary so accessing GetAxis with axis_x and axis_y won't crash diff --git a/src/video_core/command_classes/codecs/h264.cpp b/src/video_core/command_classes/codecs/h264.cpp index 51ee14c13..5519c4705 100755 --- a/src/video_core/command_classes/codecs/h264.cpp +++ b/src/video_core/command_classes/codecs/h264.cpp @@ -20,6 +20,8 @@ #include #include + +#include "common/settings.h" #include "video_core/command_classes/codecs/h264.h" #include "video_core/gpu.h" #include "video_core/memory_manager.h" @@ -96,7 +98,10 @@ const std::vector& H264::ComposeFrameHeader(const NvdecCommon::NvdecRegister (context.h264_parameter_set.frame_mbs_only_flag ? 1 : 2); // TODO (ameerj): Where do we get this number, it seems to be particular for each stream - writer.WriteUe(6); // Max number of reference frames + const auto nvdec_decoding = Settings::values.nvdec_emulation.GetValue(); + const bool uses_gpu_decoding = nvdec_decoding == Settings::NvdecEmulation::GPU; + const u32 max_num_ref_frames = uses_gpu_decoding ? 6u : 16u; + writer.WriteUe(max_num_ref_frames); writer.WriteBit(false); writer.WriteUe(context.h264_parameter_set.pic_width_in_mbs - 1); writer.WriteUe(pic_height - 1); diff --git a/src/video_core/command_classes/vic.cpp b/src/video_core/command_classes/vic.cpp index 51f739801..051616124 100755 --- a/src/video_core/command_classes/vic.cpp +++ b/src/video_core/command_classes/vic.cpp @@ -32,7 +32,7 @@ enum class VideoPixelFormat : u64_le { RGBA8 = 0x1f, BGRA8 = 0x20, RGBX8 = 0x23, - Yuv420 = 0x44, + YUV420 = 0x44, }; } // Anonymous namespace @@ -90,9 +90,8 @@ void Vic::Execute() { if (static_cast(frame->width) != surface_width || static_cast(frame->height) != surface_height) { // TODO: Properly support multiple video streams with differing frame dimensions - LOG_WARNING(Debug, "Frame dimensions {}x{} do not match expected surface dimensions {}x{}", + LOG_WARNING(Service_NVDRV, "Frame dimensions {}x{} don't match surface dimensions {}x{}", frame->width, frame->height, surface_width, surface_height); - return; } switch (config.pixel_format) { case VideoPixelFormat::RGBA8: @@ -100,7 +99,7 @@ void Vic::Execute() { case VideoPixelFormat::RGBX8: WriteRGBFrame(frame, config); break; - case VideoPixelFormat::Yuv420: + case VideoPixelFormat::YUV420: WriteYUVFrame(frame, config); break; default: @@ -135,21 +134,20 @@ void Vic::WriteRGBFrame(const AVFrame* frame, const VicConfig& config) { scaler_height = frame->height; converted_frame_buffer.reset(); } - // Get Converted frame - const u32 width = static_cast(frame->width); - const u32 height = static_cast(frame->height); - const std::size_t linear_size = width * height * 4; - - // Only allocate frame_buffer once per stream, as the size is not expected to change if (!converted_frame_buffer) { - converted_frame_buffer = AVMallocPtr{static_cast(av_malloc(linear_size)), av_free}; + const size_t frame_size = frame->width * frame->height * 4; + converted_frame_buffer = AVMallocPtr{static_cast(av_malloc(frame_size)), av_free}; } const std::array converted_stride{frame->width * 4, frame->height * 4, 0, 0}; u8* const converted_frame_buf_addr{converted_frame_buffer.get()}; - sws_scale(scaler_ctx, frame->data, frame->linesize, 0, frame->height, &converted_frame_buf_addr, converted_stride.data()); + // Use the minimum of surface/frame dimensions to avoid buffer overflow. + const u32 surface_width = static_cast(config.surface_width_minus1) + 1; + const u32 surface_height = static_cast(config.surface_height_minus1) + 1; + const u32 width = std::min(surface_width, static_cast(frame->width)); + const u32 height = std::min(surface_height, static_cast(frame->height)); const u32 blk_kind = static_cast(config.block_linear_kind); if (blk_kind != 0) { // swizzle pitch linear to block linear @@ -157,11 +155,12 @@ void Vic::WriteRGBFrame(const AVFrame* frame, const VicConfig& config) { const auto size = Texture::CalculateSize(true, 4, width, height, 1, block_height, 0); luma_buffer.resize(size); Texture::SwizzleSubrect(width, height, width * 4, width, 4, luma_buffer.data(), - converted_frame_buffer.get(), block_height, 0, 0); + converted_frame_buf_addr, block_height, 0, 0); gpu.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(), size); } else { // send pitch linear frame + const size_t linear_size = width * height * 4; gpu.MemoryManager().WriteBlock(output_surface_luma_address, converted_frame_buf_addr, linear_size); } @@ -172,9 +171,10 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) { const std::size_t surface_width = config.surface_width_minus1 + 1; const std::size_t surface_height = config.surface_height_minus1 + 1; + const std::size_t aligned_width = (surface_width + 0xff) & ~0xffUL; + // Use the minimum of surface/frame dimensions to avoid buffer overflow. const auto frame_width = std::min(surface_width, static_cast(frame->width)); const auto frame_height = std::min(surface_height, static_cast(frame->height)); - const std::size_t aligned_width = (surface_width + 0xff) & ~0xffUL; const auto stride = static_cast(frame->linesize[0]); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 8140e659b..9f80a245c 100755 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1172,10 +1172,16 @@ void GMainWindow::ConnectMenuEvents() { &GMainWindow::OnDisplayTitleBars); connect(ui.action_Show_Filter_Bar, &QAction::triggered, this, &GMainWindow::OnToggleFilterBar); connect(ui.action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible); + connect(ui.action_Reset_Window_Size_720, &QAction::triggered, this, &GMainWindow::ResetWindowSize720); + connect(ui.action_Reset_Window_Size_900, &QAction::triggered, this, + &GMainWindow::ResetWindowSize900); connect(ui.action_Reset_Window_Size_1080, &QAction::triggered, this, &GMainWindow::ResetWindowSize1080); + ui.menu_Reset_Window_Size->addAction(ui.action_Reset_Window_Size_720); + ui.menu_Reset_Window_Size->addAction(ui.action_Reset_Window_Size_900); + ui.menu_Reset_Window_Size->addAction(ui.action_Reset_Window_Size_1080); // Fullscreen connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen); @@ -2611,32 +2617,29 @@ void GMainWindow::ToggleWindowMode() { } } -void GMainWindow::ResetWindowSize720() { +void GMainWindow::ResetWindowSize(u32 width, u32 height) { const auto aspect_ratio = Layout::EmulationAspectRatio( static_cast(Settings::values.aspect_ratio.GetValue()), - static_cast(Layout::ScreenUndocked::Height) / Layout::ScreenUndocked::Width); + static_cast(height) / width); if (!ui.action_Single_Window_Mode->isChecked()) { - render_window->resize(Layout::ScreenUndocked::Height / aspect_ratio, - Layout::ScreenUndocked::Height); + render_window->resize(height / aspect_ratio, height); } else { - resize(Layout::ScreenUndocked::Height / aspect_ratio, - Layout::ScreenUndocked::Height + menuBar()->height() + - (ui.action_Show_Status_Bar->isChecked() ? statusBar()->height() : 0)); + 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); } } +void GMainWindow::ResetWindowSize720() { + ResetWindowSize(Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height); +} + +void GMainWindow::ResetWindowSize900() { + ResetWindowSize(1600U, 900U); +} + void GMainWindow::ResetWindowSize1080() { - const auto aspect_ratio = Layout::EmulationAspectRatio( - static_cast(Settings::values.aspect_ratio.GetValue()), - static_cast(Layout::ScreenDocked::Height) / Layout::ScreenDocked::Width); - if (!ui.action_Single_Window_Mode->isChecked()) { - render_window->resize(Layout::ScreenDocked::Height / aspect_ratio, - Layout::ScreenDocked::Height); - } else { - resize(Layout::ScreenDocked::Height / aspect_ratio, - Layout::ScreenDocked::Height + menuBar()->height() + - (ui.action_Show_Status_Bar->isChecked() ? statusBar()->height() : 0)); - } + ResetWindowSize(Layout::ScreenDocked::Width, Layout::ScreenDocked::Height); } void GMainWindow::OnConfigure() { diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 6ef4e4d4e..e31b3d06b 100755 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -272,7 +272,9 @@ private slots: void ShowFullscreen(); void HideFullscreen(); void ToggleWindowMode(); + void ResetWindowSize(u32 width, u32 height); void ResetWindowSize720(); + void ResetWindowSize900(); void ResetWindowSize1080(); void OnCaptureScreenshot(); void OnCoreError(Core::System::ResultStatus, std::string); diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index 653c010d8..a62e39a06 100755 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui @@ -78,6 +78,35 @@ &View + + + &Reset Window Size + + + + + Reset Window Size to &720p + + + Reset Window Size to 720p + + + + + Reset Window Size to &900p + + + Reset Window Size to 900p + + + + + Reset Window Size to &1080p + + + Reset Window Size to 1080p + + &Debugging @@ -88,9 +117,8 @@ - - + @@ -216,22 +244,6 @@ Show Status Bar - - - Reset Window Size to &720p - - - Reset Window Size to 720p - - - - - Reset Window Size to &1080p - - - Reset Window Size to 1080p - - true