early-access version 2121
This commit is contained in:
		| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -170,7 +170,8 @@ public: | ||||
|     float GetAxis(int axis, float range, float offset) const { | ||||
|         std::lock_guard lock{mutex}; | ||||
|         const float value = static_cast<float>(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 | ||||
|   | ||||
| @@ -20,6 +20,8 @@ | ||||
|  | ||||
| #include <array> | ||||
| #include <bit> | ||||
|  | ||||
| #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<u8>& 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); | ||||
|   | ||||
| @@ -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<u64>(frame->width) != surface_width || | ||||
|         static_cast<u64>(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<u32>(frame->width); | ||||
|     const u32 height = static_cast<u32>(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<u8*>(av_malloc(linear_size)), av_free}; | ||||
|         const size_t frame_size = frame->width * frame->height * 4; | ||||
|         converted_frame_buffer = AVMallocPtr{static_cast<u8*>(av_malloc(frame_size)), av_free}; | ||||
|     } | ||||
|     const std::array<int, 4> 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<u32>(config.surface_width_minus1) + 1; | ||||
|     const u32 surface_height = static_cast<u32>(config.surface_height_minus1) + 1; | ||||
|     const u32 width = std::min(surface_width, static_cast<u32>(frame->width)); | ||||
|     const u32 height = std::min(surface_height, static_cast<u32>(frame->height)); | ||||
|     const u32 blk_kind = static_cast<u32>(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<size_t>(frame->width)); | ||||
|     const auto frame_height = std::min(surface_height, static_cast<size_t>(frame->height)); | ||||
|     const std::size_t aligned_width = (surface_width + 0xff) & ~0xffUL; | ||||
|  | ||||
|     const auto stride = static_cast<size_t>(frame->linesize[0]); | ||||
|  | ||||
|   | ||||
| @@ -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<Layout::AspectRatio>(Settings::values.aspect_ratio.GetValue()), | ||||
|         static_cast<float>(Layout::ScreenUndocked::Height) / Layout::ScreenUndocked::Width); | ||||
|         static_cast<float>(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<Layout::AspectRatio>(Settings::values.aspect_ratio.GetValue()), | ||||
|         static_cast<float>(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() { | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -78,6 +78,35 @@ | ||||
|     <property name="title"> | ||||
|      <string>&View</string> | ||||
|     </property> | ||||
|     <widget class="QMenu" name="menu_Reset_Window_Size"> | ||||
|       <property name="title"> | ||||
|         <string>&Reset Window Size</string> | ||||
|       </property> | ||||
|     </widget> | ||||
|     <action name="action_Reset_Window_Size_720"> | ||||
|       <property name="text"> | ||||
|         <string>Reset Window Size to &720p</string> | ||||
|       </property> | ||||
|       <property name="iconText"> | ||||
|         <string>Reset Window Size to 720p</string> | ||||
|       </property> | ||||
|     </action> | ||||
|     <action name="action_Reset_Window_Size_900"> | ||||
|       <property name="text"> | ||||
|         <string>Reset Window Size to &900p</string> | ||||
|       </property> | ||||
|       <property name="iconText"> | ||||
|         <string>Reset Window Size to 900p</string> | ||||
|       </property> | ||||
|     </action> | ||||
|     <action name="action_Reset_Window_Size_1080"> | ||||
|       <property name="text"> | ||||
|         <string>Reset Window Size to &1080p</string> | ||||
|       </property> | ||||
|       <property name="iconText"> | ||||
|         <string>Reset Window Size to 1080p</string> | ||||
|       </property> | ||||
|     </action> | ||||
|     <widget class="QMenu" name="menu_View_Debugging"> | ||||
|      <property name="title"> | ||||
|       <string>&Debugging</string> | ||||
| @@ -88,9 +117,8 @@ | ||||
|     <addaction name="action_Display_Dock_Widget_Headers"/> | ||||
|     <addaction name="action_Show_Filter_Bar"/> | ||||
|     <addaction name="action_Show_Status_Bar"/> | ||||
|     <addaction name="action_Reset_Window_Size_720"/> | ||||
|     <addaction name="action_Reset_Window_Size_1080"/> | ||||
|     <addaction name="separator"/> | ||||
|     <addaction name="menu_Reset_Window_Size"/> | ||||
|     <addaction name="menu_View_Debugging"/> | ||||
|    </widget> | ||||
|    <widget class="QMenu" name="menu_Tools"> | ||||
| @@ -216,22 +244,6 @@ | ||||
|     <string>Show Status Bar</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="action_Reset_Window_Size_720"> | ||||
|    <property name="text"> | ||||
|     <string>Reset Window Size to &720p</string> | ||||
|    </property> | ||||
|    <property name="iconText"> | ||||
|     <string>Reset Window Size to 720p</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="action_Reset_Window_Size_1080"> | ||||
|    <property name="text"> | ||||
|     <string>Reset Window Size to &1080p</string> | ||||
|    </property> | ||||
|    <property name="iconText"> | ||||
|     <string>Reset Window Size to 1080p</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="action_Fullscreen"> | ||||
|    <property name="checkable"> | ||||
|     <bool>true</bool> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user