mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 13:55:38 +00:00
Reworked the "Force NTSC Timings" feature to support both NTSC and PAL frame timings (#3287)
This commit is contained in:
parent
7d40228765
commit
f511877910
|
@ -4270,6 +4270,12 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
||||||
"Display", "Scaling", Settings::DEFAULT_DISPLAY_SCALING, &Settings::ParseDisplayScaling,
|
"Display", "Scaling", Settings::DEFAULT_DISPLAY_SCALING, &Settings::ParseDisplayScaling,
|
||||||
&Settings::GetDisplayScalingName, &Settings::GetDisplayScalingDisplayName, DisplayScalingMode::Count);
|
&Settings::GetDisplayScalingName, &Settings::GetDisplayScalingDisplayName, DisplayScalingMode::Count);
|
||||||
|
|
||||||
|
DrawEnumSetting(
|
||||||
|
bsi, FSUI_CSTR("Force Frame Timings"),
|
||||||
|
FSUI_CSTR("Utilizes the chosen frame timing regardless of the active region."),
|
||||||
|
"GPU", "ForceFrameTimings", Settings::DEFAULT_FORCE_FRAME_TIMINGS_MODE, &Settings::ParseForceFrameTimings,
|
||||||
|
&Settings::GetForceFrameTimingsName, &Settings::GetForceFrameTimingsDisplayName, ForceFrameTimingsMode::Count);
|
||||||
|
|
||||||
if (is_hardware)
|
if (is_hardware)
|
||||||
{
|
{
|
||||||
DrawToggleSetting(bsi, FSUI_CSTR("True Color Rendering"),
|
DrawToggleSetting(bsi, FSUI_CSTR("True Color Rendering"),
|
||||||
|
@ -4309,12 +4315,6 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
||||||
"but others will break."),
|
"but others will break."),
|
||||||
"GPU", "DisableInterlacing", true);
|
"GPU", "DisableInterlacing", true);
|
||||||
|
|
||||||
DrawToggleSetting(
|
|
||||||
bsi, FSUI_CSTR("Force NTSC Timings"),
|
|
||||||
FSUI_CSTR("Forces PAL games to run at NTSC timings, i.e. 60hz. Some PAL games will run at their \"normal\" "
|
|
||||||
"speeds, while others will break."),
|
|
||||||
"GPU", "ForceNTSCTimings", false);
|
|
||||||
|
|
||||||
MenuHeading(FSUI_CSTR("Advanced"));
|
MenuHeading(FSUI_CSTR("Advanced"));
|
||||||
|
|
||||||
std::optional<SmallString> strvalue = bsi->GetOptionalSmallStringValue(
|
std::optional<SmallString> strvalue = bsi->GetOptionalSmallStringValue(
|
||||||
|
|
|
@ -75,7 +75,7 @@ static constexpr const std::array<const char*, static_cast<u32>(GameDatabase::Tr
|
||||||
"DisableTextureFiltering",
|
"DisableTextureFiltering",
|
||||||
"DisableSpriteTextureFiltering",
|
"DisableSpriteTextureFiltering",
|
||||||
"DisableScaledDithering",
|
"DisableScaledDithering",
|
||||||
"DisableForceNTSCTimings",
|
"DisableForceFrameTimings",
|
||||||
"DisableWidescreen",
|
"DisableWidescreen",
|
||||||
"DisablePGXP",
|
"DisablePGXP",
|
||||||
"DisablePGXPCulling",
|
"DisablePGXPCulling",
|
||||||
|
@ -105,7 +105,7 @@ static constexpr const std::array<const char*, static_cast<u32>(GameDatabase::Tr
|
||||||
TRANSLATE_NOOP("GameDatabase", "Disable Texture Filtering"),
|
TRANSLATE_NOOP("GameDatabase", "Disable Texture Filtering"),
|
||||||
TRANSLATE_NOOP("GameDatabase", "Disable Sprite Texture Filtering"),
|
TRANSLATE_NOOP("GameDatabase", "Disable Sprite Texture Filtering"),
|
||||||
TRANSLATE_NOOP("GameDatabase", "Disable Scaled Dithering"),
|
TRANSLATE_NOOP("GameDatabase", "Disable Scaled Dithering"),
|
||||||
TRANSLATE_NOOP("GameDatabase", "Disable Force NTSC Timings"),
|
TRANSLATE_NOOP("GameDatabase", "Disable Force Frame Timings"),
|
||||||
TRANSLATE_NOOP("GameDatabase", "Disable Widescreen"),
|
TRANSLATE_NOOP("GameDatabase", "Disable Widescreen"),
|
||||||
TRANSLATE_NOOP("GameDatabase", "Disable PGXP"),
|
TRANSLATE_NOOP("GameDatabase", "Disable PGXP"),
|
||||||
TRANSLATE_NOOP("GameDatabase", "Disable PGXP Culling"),
|
TRANSLATE_NOOP("GameDatabase", "Disable PGXP Culling"),
|
||||||
|
@ -590,12 +590,12 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
|
||||||
settings.gpu_widescreen_hack = false;
|
settings.gpu_widescreen_hack = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasTrait(Trait::DisableForceNTSCTimings))
|
if (HasTrait(Trait::DisableForceFrameTimings))
|
||||||
{
|
{
|
||||||
if (display_osd_messages && settings.gpu_force_ntsc_timings)
|
if (display_osd_messages && settings.gpu_force_frame_timings != ForceFrameTimingsMode::Disabled)
|
||||||
APPEND_MESSAGE(TRANSLATE_SV("GameDatabase", "Force NTSC timings disabled."));
|
APPEND_MESSAGE(TRANSLATE_SV("GameDatabase", "Force frame timings disabled."));
|
||||||
|
|
||||||
settings.gpu_force_ntsc_timings = false;
|
settings.gpu_force_frame_timings = ForceFrameTimingsMode::Disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasTrait(Trait::DisablePGXP))
|
if (HasTrait(Trait::DisablePGXP))
|
||||||
|
|
|
@ -40,7 +40,7 @@ enum class Trait : u32
|
||||||
DisableTextureFiltering,
|
DisableTextureFiltering,
|
||||||
DisableSpriteTextureFiltering,
|
DisableSpriteTextureFiltering,
|
||||||
DisableScaledDithering,
|
DisableScaledDithering,
|
||||||
DisableForceNTSCTimings,
|
DisableForceFrameTimings,
|
||||||
DisableWidescreen,
|
DisableWidescreen,
|
||||||
DisablePGXP,
|
DisablePGXP,
|
||||||
DisablePGXPCulling,
|
DisablePGXPCulling,
|
||||||
|
|
|
@ -88,7 +88,7 @@ GPU::~GPU()
|
||||||
bool GPU::Initialize()
|
bool GPU::Initialize()
|
||||||
{
|
{
|
||||||
m_force_progressive_scan = g_settings.gpu_disable_interlacing;
|
m_force_progressive_scan = g_settings.gpu_disable_interlacing;
|
||||||
m_force_ntsc_timings = g_settings.gpu_force_ntsc_timings;
|
m_force_frame_timings = g_settings.gpu_force_frame_timings;
|
||||||
s_crtc_tick_event.Activate();
|
s_crtc_tick_event.Activate();
|
||||||
m_fifo_size = g_settings.gpu_fifo_size;
|
m_fifo_size = g_settings.gpu_fifo_size;
|
||||||
m_max_run_ahead = g_settings.gpu_max_run_ahead;
|
m_max_run_ahead = g_settings.gpu_max_run_ahead;
|
||||||
|
@ -119,9 +119,9 @@ void GPU::UpdateSettings(const Settings& old_settings)
|
||||||
m_fifo_size = g_settings.gpu_fifo_size;
|
m_fifo_size = g_settings.gpu_fifo_size;
|
||||||
m_max_run_ahead = g_settings.gpu_max_run_ahead;
|
m_max_run_ahead = g_settings.gpu_max_run_ahead;
|
||||||
|
|
||||||
if (m_force_ntsc_timings != g_settings.gpu_force_ntsc_timings || m_console_is_pal != System::IsPALRegion())
|
if (m_force_frame_timings != g_settings.gpu_force_frame_timings)
|
||||||
{
|
{
|
||||||
m_force_ntsc_timings = g_settings.gpu_force_ntsc_timings;
|
m_force_frame_timings = g_settings.gpu_force_frame_timings;
|
||||||
m_console_is_pal = System::IsPALRegion();
|
m_console_is_pal = System::IsPALRegion();
|
||||||
UpdateCRTCConfig();
|
UpdateCRTCConfig();
|
||||||
}
|
}
|
||||||
|
@ -637,7 +637,7 @@ void GPU::UpdateCRTCConfig()
|
||||||
cs.vertical_display_start = std::min<u16>(cs.regs.Y1, cs.vertical_total);
|
cs.vertical_display_start = std::min<u16>(cs.regs.Y1, cs.vertical_total);
|
||||||
cs.vertical_display_end = std::min<u16>(cs.regs.Y2, cs.vertical_total);
|
cs.vertical_display_end = std::min<u16>(cs.regs.Y2, cs.vertical_total);
|
||||||
|
|
||||||
if (m_GPUSTAT.pal_mode && m_force_ntsc_timings)
|
if (m_GPUSTAT.pal_mode && m_force_frame_timings == ForceFrameTimingsMode::NTSC)
|
||||||
{
|
{
|
||||||
// scale to NTSC parameters
|
// scale to NTSC parameters
|
||||||
cs.horizontal_display_start =
|
cs.horizontal_display_start =
|
||||||
|
@ -655,6 +655,24 @@ void GPU::UpdateCRTCConfig()
|
||||||
cs.horizontal_total = NTSC_TICKS_PER_LINE;
|
cs.horizontal_total = NTSC_TICKS_PER_LINE;
|
||||||
cs.current_tick_in_scanline %= NTSC_TICKS_PER_LINE;
|
cs.current_tick_in_scanline %= NTSC_TICKS_PER_LINE;
|
||||||
}
|
}
|
||||||
|
else if (!m_GPUSTAT.pal_mode && m_force_frame_timings == ForceFrameTimingsMode::PAL)
|
||||||
|
{
|
||||||
|
// scale to PAL parameters
|
||||||
|
cs.horizontal_display_start =
|
||||||
|
static_cast<u16>((static_cast<u32>(cs.horizontal_display_start) * PAL_TICKS_PER_LINE) / NTSC_TICKS_PER_LINE);
|
||||||
|
cs.horizontal_display_end = static_cast<u16>(
|
||||||
|
((static_cast<u32>(cs.horizontal_display_end) * PAL_TICKS_PER_LINE) + (NTSC_TICKS_PER_LINE - 1)) /
|
||||||
|
NTSC_TICKS_PER_LINE);
|
||||||
|
cs.vertical_display_start =
|
||||||
|
static_cast<u16>((static_cast<u32>(cs.vertical_display_start) * PAL_TOTAL_LINES) / NTSC_TOTAL_LINES);
|
||||||
|
cs.vertical_display_end = static_cast<u16>(
|
||||||
|
((static_cast<u32>(cs.vertical_display_end) * PAL_TOTAL_LINES) + (NTSC_TOTAL_LINES - 1)) / NTSC_TOTAL_LINES);
|
||||||
|
|
||||||
|
cs.vertical_total = PAL_TOTAL_LINES;
|
||||||
|
cs.current_scanline %= PAL_TOTAL_LINES;
|
||||||
|
cs.horizontal_total = PAL_TICKS_PER_LINE;
|
||||||
|
cs.current_tick_in_scanline %= PAL_TICKS_PER_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
cs.horizontal_display_start =
|
cs.horizontal_display_start =
|
||||||
static_cast<u16>(System::ScaleTicksToOverclock(static_cast<TickCount>(cs.horizontal_display_start)));
|
static_cast<u16>(System::ScaleTicksToOverclock(static_cast<TickCount>(cs.horizontal_display_start)));
|
||||||
|
|
|
@ -505,7 +505,7 @@ protected:
|
||||||
bool m_set_texture_disable_mask = false;
|
bool m_set_texture_disable_mask = false;
|
||||||
bool m_drawing_area_changed = false;
|
bool m_drawing_area_changed = false;
|
||||||
bool m_force_progressive_scan = false;
|
bool m_force_progressive_scan = false;
|
||||||
bool m_force_ntsc_timings = false;
|
ForceFrameTimingsMode m_force_frame_timings = ForceFrameTimingsMode::Disabled;
|
||||||
|
|
||||||
struct CRTCState
|
struct CRTCState
|
||||||
{
|
{
|
||||||
|
|
|
@ -444,8 +444,10 @@ void ImGuiManager::DrawEnhancementsOverlay()
|
||||||
}
|
}
|
||||||
if (g_settings.gpu_disable_interlacing)
|
if (g_settings.gpu_disable_interlacing)
|
||||||
text.append(" ForceProg");
|
text.append(" ForceProg");
|
||||||
if (g_settings.gpu_force_ntsc_timings && System::GetRegion() == ConsoleRegion::PAL)
|
if (g_settings.gpu_force_frame_timings == ForceFrameTimingsMode::NTSC && System::GetRegion() == ConsoleRegion::PAL)
|
||||||
text.append(" PAL60");
|
text.append(" PAL60");
|
||||||
|
if (g_settings.gpu_force_frame_timings == ForceFrameTimingsMode::PAL && System::GetRegion() != ConsoleRegion::PAL)
|
||||||
|
text.append(" NTSC50");
|
||||||
if (g_settings.gpu_texture_filter != GPUTextureFilter::Nearest)
|
if (g_settings.gpu_texture_filter != GPUTextureFilter::Nearest)
|
||||||
{
|
{
|
||||||
if (g_settings.gpu_sprite_texture_filter != g_settings.gpu_texture_filter)
|
if (g_settings.gpu_sprite_texture_filter != g_settings.gpu_texture_filter)
|
||||||
|
|
|
@ -229,7 +229,10 @@ void Settings::Load(SettingsInterface& si, SettingsInterface& controller_si)
|
||||||
si.GetStringValue("GPU", "WireframeMode", GetGPUWireframeModeName(DEFAULT_GPU_WIREFRAME_MODE)).c_str())
|
si.GetStringValue("GPU", "WireframeMode", GetGPUWireframeModeName(DEFAULT_GPU_WIREFRAME_MODE)).c_str())
|
||||||
.value_or(DEFAULT_GPU_WIREFRAME_MODE);
|
.value_or(DEFAULT_GPU_WIREFRAME_MODE);
|
||||||
gpu_disable_interlacing = si.GetBoolValue("GPU", "DisableInterlacing", true);
|
gpu_disable_interlacing = si.GetBoolValue("GPU", "DisableInterlacing", true);
|
||||||
gpu_force_ntsc_timings = si.GetBoolValue("GPU", "ForceNTSCTimings", false);
|
gpu_force_frame_timings =
|
||||||
|
ParseForceFrameTimings(
|
||||||
|
si.GetStringValue("GPU", "ForceFrameTimings", GetForceFrameTimingsName(DEFAULT_FORCE_FRAME_TIMINGS_MODE)).c_str())
|
||||||
|
.value_or(DEFAULT_FORCE_FRAME_TIMINGS_MODE);
|
||||||
gpu_widescreen_hack = si.GetBoolValue("GPU", "WidescreenHack", false);
|
gpu_widescreen_hack = si.GetBoolValue("GPU", "WidescreenHack", false);
|
||||||
display_24bit_chroma_smoothing = si.GetBoolValue("GPU", "ChromaSmoothing24Bit", false);
|
display_24bit_chroma_smoothing = si.GetBoolValue("GPU", "ChromaSmoothing24Bit", false);
|
||||||
gpu_pgxp_enable = si.GetBoolValue("GPU", "PGXPEnable", false);
|
gpu_pgxp_enable = si.GetBoolValue("GPU", "PGXPEnable", false);
|
||||||
|
@ -535,7 +538,7 @@ void Settings::Save(SettingsInterface& si, bool ignore_base) const
|
||||||
si.SetUIntValue("GPU", "DownsampleScale", gpu_downsample_scale);
|
si.SetUIntValue("GPU", "DownsampleScale", gpu_downsample_scale);
|
||||||
si.SetStringValue("GPU", "WireframeMode", GetGPUWireframeModeName(gpu_wireframe_mode));
|
si.SetStringValue("GPU", "WireframeMode", GetGPUWireframeModeName(gpu_wireframe_mode));
|
||||||
si.SetBoolValue("GPU", "DisableInterlacing", gpu_disable_interlacing);
|
si.SetBoolValue("GPU", "DisableInterlacing", gpu_disable_interlacing);
|
||||||
si.SetBoolValue("GPU", "ForceNTSCTimings", gpu_force_ntsc_timings);
|
si.SetStringValue("GPU", "ForceFrameTimings", GetForceFrameTimingsName(gpu_force_frame_timings));
|
||||||
si.SetBoolValue("GPU", "WidescreenHack", gpu_widescreen_hack);
|
si.SetBoolValue("GPU", "WidescreenHack", gpu_widescreen_hack);
|
||||||
si.SetBoolValue("GPU", "ChromaSmoothing24Bit", display_24bit_chroma_smoothing);
|
si.SetBoolValue("GPU", "ChromaSmoothing24Bit", display_24bit_chroma_smoothing);
|
||||||
si.SetBoolValue("GPU", "PGXPEnable", gpu_pgxp_enable);
|
si.SetBoolValue("GPU", "PGXPEnable", gpu_pgxp_enable);
|
||||||
|
@ -744,7 +747,7 @@ void Settings::FixIncompatibleSettings(bool display_osd_messages)
|
||||||
g_settings.gpu_sprite_texture_filter = GPUTextureFilter::Nearest;
|
g_settings.gpu_sprite_texture_filter = GPUTextureFilter::Nearest;
|
||||||
g_settings.gpu_line_detect_mode = GPULineDetectMode::Disabled;
|
g_settings.gpu_line_detect_mode = GPULineDetectMode::Disabled;
|
||||||
g_settings.gpu_disable_interlacing = false;
|
g_settings.gpu_disable_interlacing = false;
|
||||||
g_settings.gpu_force_ntsc_timings = false;
|
g_settings.gpu_force_frame_timings = ForceFrameTimingsMode::Disabled;
|
||||||
g_settings.gpu_widescreen_hack = false;
|
g_settings.gpu_widescreen_hack = false;
|
||||||
g_settings.gpu_pgxp_enable = false;
|
g_settings.gpu_pgxp_enable = false;
|
||||||
g_settings.display_24bit_chroma_smoothing = false;
|
g_settings.display_24bit_chroma_smoothing = false;
|
||||||
|
@ -1507,7 +1510,22 @@ const char* Settings::GetDisplayRotationDisplayName(DisplayRotation rotation)
|
||||||
{
|
{
|
||||||
return Host::TranslateToCString("Settings", s_display_rotation_display_names[static_cast<size_t>(rotation)]);
|
return Host::TranslateToCString("Settings", s_display_rotation_display_names[static_cast<size_t>(rotation)]);
|
||||||
}
|
}
|
||||||
|
static constexpr const std::array s_display_force_frame_timings_names = {
|
||||||
|
"Disabled", "NTSC", "PAL"
|
||||||
|
};
|
||||||
|
std::optional<ForceFrameTimingsMode> Settings::ParseForceFrameTimings(const char* str)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
for (const char* name : s_display_force_frame_timings_names)
|
||||||
|
{
|
||||||
|
if (StringUtil::Strcasecmp(name, str) == 0)
|
||||||
|
return static_cast<ForceFrameTimingsMode>(index);
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
static constexpr const std::array s_display_scaling_names = {
|
static constexpr const std::array s_display_scaling_names = {
|
||||||
"Nearest", "NearestInteger", "BilinearSmooth", "BilinearSharp", "BilinearInteger",
|
"Nearest", "NearestInteger", "BilinearSmooth", "BilinearSharp", "BilinearInteger",
|
||||||
};
|
};
|
||||||
|
@ -1543,6 +1561,16 @@ const char* Settings::GetDisplayScalingDisplayName(DisplayScalingMode mode)
|
||||||
return Host::TranslateToCString("DisplayScalingMode", s_display_scaling_display_names[static_cast<int>(mode)]);
|
return Host::TranslateToCString("DisplayScalingMode", s_display_scaling_display_names[static_cast<int>(mode)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* Settings::GetForceFrameTimingsName(ForceFrameTimingsMode mode)
|
||||||
|
{
|
||||||
|
return s_display_force_frame_timings_names[static_cast<int>(mode)];
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Settings::GetForceFrameTimingsDisplayName(ForceFrameTimingsMode mode)
|
||||||
|
{
|
||||||
|
return Host::TranslateToCString("ForceFrameTimingsMode", s_display_force_frame_timings_names[static_cast<int>(mode)]);
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr const std::array s_display_exclusive_fullscreen_mode_names = {
|
static constexpr const std::array s_display_exclusive_fullscreen_mode_names = {
|
||||||
"Automatic",
|
"Automatic",
|
||||||
"Disallowed",
|
"Disallowed",
|
||||||
|
|
|
@ -122,7 +122,6 @@ struct Settings
|
||||||
bool gpu_force_round_texcoords : 1 = false;
|
bool gpu_force_round_texcoords : 1 = false;
|
||||||
bool gpu_accurate_blending : 1 = false;
|
bool gpu_accurate_blending : 1 = false;
|
||||||
bool gpu_disable_interlacing : 1 = true;
|
bool gpu_disable_interlacing : 1 = true;
|
||||||
bool gpu_force_ntsc_timings : 1 = false;
|
|
||||||
bool gpu_widescreen_hack : 1 = false;
|
bool gpu_widescreen_hack : 1 = false;
|
||||||
bool gpu_pgxp_enable : 1 = false;
|
bool gpu_pgxp_enable : 1 = false;
|
||||||
bool gpu_pgxp_culling : 1 = true;
|
bool gpu_pgxp_culling : 1 = true;
|
||||||
|
@ -133,6 +132,7 @@ struct Settings
|
||||||
bool gpu_pgxp_preserve_proj_fp : 1 = false;
|
bool gpu_pgxp_preserve_proj_fp : 1 = false;
|
||||||
bool gpu_pgxp_depth_buffer : 1 = false;
|
bool gpu_pgxp_depth_buffer : 1 = false;
|
||||||
bool gpu_pgxp_disable_2d : 1 = false;
|
bool gpu_pgxp_disable_2d : 1 = false;
|
||||||
|
ForceFrameTimingsMode gpu_force_frame_timings = DEFAULT_FORCE_FRAME_TIMINGS_MODE;
|
||||||
GPUTextureFilter gpu_texture_filter = DEFAULT_GPU_TEXTURE_FILTER;
|
GPUTextureFilter gpu_texture_filter = DEFAULT_GPU_TEXTURE_FILTER;
|
||||||
GPUTextureFilter gpu_sprite_texture_filter = DEFAULT_GPU_TEXTURE_FILTER;
|
GPUTextureFilter gpu_sprite_texture_filter = DEFAULT_GPU_TEXTURE_FILTER;
|
||||||
GPULineDetectMode gpu_line_detect_mode = DEFAULT_GPU_LINE_DETECT_MODE;
|
GPULineDetectMode gpu_line_detect_mode = DEFAULT_GPU_LINE_DETECT_MODE;
|
||||||
|
@ -434,6 +434,10 @@ struct Settings
|
||||||
static const char* GetDisplayScalingName(DisplayScalingMode mode);
|
static const char* GetDisplayScalingName(DisplayScalingMode mode);
|
||||||
static const char* GetDisplayScalingDisplayName(DisplayScalingMode mode);
|
static const char* GetDisplayScalingDisplayName(DisplayScalingMode mode);
|
||||||
|
|
||||||
|
static std::optional<ForceFrameTimingsMode> ParseForceFrameTimings(const char* str);
|
||||||
|
static const char* GetForceFrameTimingsName(ForceFrameTimingsMode mode);
|
||||||
|
static const char* GetForceFrameTimingsDisplayName(ForceFrameTimingsMode mode);
|
||||||
|
|
||||||
static std::optional<DisplayExclusiveFullscreenControl> ParseDisplayExclusiveFullscreenControl(const char* str);
|
static std::optional<DisplayExclusiveFullscreenControl> ParseDisplayExclusiveFullscreenControl(const char* str);
|
||||||
static const char* GetDisplayExclusiveFullscreenControlName(DisplayExclusiveFullscreenControl mode);
|
static const char* GetDisplayExclusiveFullscreenControlName(DisplayExclusiveFullscreenControl mode);
|
||||||
static const char* GetDisplayExclusiveFullscreenControlDisplayName(DisplayExclusiveFullscreenControl mode);
|
static const char* GetDisplayExclusiveFullscreenControlDisplayName(DisplayExclusiveFullscreenControl mode);
|
||||||
|
@ -492,6 +496,7 @@ struct Settings
|
||||||
static constexpr DisplayAlignment DEFAULT_DISPLAY_ALIGNMENT = DisplayAlignment::Center;
|
static constexpr DisplayAlignment DEFAULT_DISPLAY_ALIGNMENT = DisplayAlignment::Center;
|
||||||
static constexpr DisplayRotation DEFAULT_DISPLAY_ROTATION = DisplayRotation::Normal;
|
static constexpr DisplayRotation DEFAULT_DISPLAY_ROTATION = DisplayRotation::Normal;
|
||||||
static constexpr DisplayScalingMode DEFAULT_DISPLAY_SCALING = DisplayScalingMode::BilinearSmooth;
|
static constexpr DisplayScalingMode DEFAULT_DISPLAY_SCALING = DisplayScalingMode::BilinearSmooth;
|
||||||
|
static constexpr ForceFrameTimingsMode DEFAULT_FORCE_FRAME_TIMINGS_MODE = ForceFrameTimingsMode::Disabled;
|
||||||
static constexpr DisplayExclusiveFullscreenControl DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL =
|
static constexpr DisplayExclusiveFullscreenControl DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL =
|
||||||
DisplayExclusiveFullscreenControl::Automatic;
|
DisplayExclusiveFullscreenControl::Automatic;
|
||||||
static constexpr DisplayScreenshotMode DEFAULT_DISPLAY_SCREENSHOT_MODE = DisplayScreenshotMode::ScreenResolution;
|
static constexpr DisplayScreenshotMode DEFAULT_DISPLAY_SCREENSHOT_MODE = DisplayScreenshotMode::ScreenResolution;
|
||||||
|
|
|
@ -4304,7 +4304,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
||||||
g_settings.gpu_sprite_texture_filter != old_settings.gpu_sprite_texture_filter ||
|
g_settings.gpu_sprite_texture_filter != old_settings.gpu_sprite_texture_filter ||
|
||||||
g_settings.gpu_line_detect_mode != old_settings.gpu_line_detect_mode ||
|
g_settings.gpu_line_detect_mode != old_settings.gpu_line_detect_mode ||
|
||||||
g_settings.gpu_disable_interlacing != old_settings.gpu_disable_interlacing ||
|
g_settings.gpu_disable_interlacing != old_settings.gpu_disable_interlacing ||
|
||||||
g_settings.gpu_force_ntsc_timings != old_settings.gpu_force_ntsc_timings ||
|
g_settings.gpu_force_frame_timings != old_settings.gpu_force_frame_timings ||
|
||||||
g_settings.gpu_downsample_mode != old_settings.gpu_downsample_mode ||
|
g_settings.gpu_downsample_mode != old_settings.gpu_downsample_mode ||
|
||||||
g_settings.gpu_downsample_scale != old_settings.gpu_downsample_scale ||
|
g_settings.gpu_downsample_scale != old_settings.gpu_downsample_scale ||
|
||||||
g_settings.gpu_wireframe_mode != old_settings.gpu_wireframe_mode ||
|
g_settings.gpu_wireframe_mode != old_settings.gpu_wireframe_mode ||
|
||||||
|
@ -4531,9 +4531,9 @@ void System::WarnAboutUnsafeSettings()
|
||||||
TinyString(TRANSLATE_SV("System", "Instant")) :
|
TinyString(TRANSLATE_SV("System", "Instant")) :
|
||||||
TinyString::from_format("{}x", g_settings.cdrom_seek_speedup)));
|
TinyString::from_format("{}x", g_settings.cdrom_seek_speedup)));
|
||||||
}
|
}
|
||||||
if (g_settings.gpu_force_ntsc_timings)
|
if (g_settings.gpu_force_frame_timings != ForceFrameTimingsMode::Disabled)
|
||||||
{
|
{
|
||||||
append(ICON_FA_TV, TRANSLATE_SV("System", "Force NTSC timings is enabled. Games may run at incorrect speeds."));
|
append(ICON_FA_TV, TRANSLATE_SV("System", "Force frame timings is enabled. Games may run at incorrect speeds."));
|
||||||
}
|
}
|
||||||
if (!g_settings.IsUsingSoftwareRenderer())
|
if (!g_settings.IsUsingSoftwareRenderer())
|
||||||
{
|
{
|
||||||
|
|
|
@ -275,3 +275,12 @@ enum class SaveStateCompressionMode : u8
|
||||||
|
|
||||||
Count,
|
Count,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ForceFrameTimingsMode : u8
|
||||||
|
{
|
||||||
|
Disabled,
|
||||||
|
NTSC,
|
||||||
|
PAL,
|
||||||
|
|
||||||
|
Count,
|
||||||
|
};
|
||||||
|
|
|
@ -74,6 +74,9 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
||||||
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayScaling, "Display", "Scaling",
|
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayScaling, "Display", "Scaling",
|
||||||
&Settings::ParseDisplayScaling, &Settings::GetDisplayScalingName,
|
&Settings::ParseDisplayScaling, &Settings::GetDisplayScalingName,
|
||||||
Settings::DEFAULT_DISPLAY_SCALING);
|
Settings::DEFAULT_DISPLAY_SCALING);
|
||||||
|
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.forceFrameTimings, "GPU", "ForceFrameTimings",
|
||||||
|
&Settings::ParseForceFrameTimings, &Settings::GetForceFrameTimingsName,
|
||||||
|
Settings::DEFAULT_FORCE_FRAME_TIMINGS_MODE);
|
||||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.gpuDownsampleScale, "GPU", "DownsampleScale", 1);
|
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.gpuDownsampleScale, "GPU", "DownsampleScale", 1);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.trueColor, "GPU", "TrueColor", false);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.trueColor, "GPU", "TrueColor", false);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableInterlacing, "GPU", "DisableInterlacing", true);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableInterlacing, "GPU", "DisableInterlacing", true);
|
||||||
|
@ -81,7 +84,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpDepthBuffer, "GPU", "PGXPDepthBuffer", false);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpDepthBuffer, "GPU", "PGXPDepthBuffer", false);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.force43For24Bit, "Display", "Force4_3For24Bit", false);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.force43For24Bit, "Display", "Force4_3For24Bit", false);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chromaSmoothingFor24Bit, "GPU", "ChromaSmoothing24Bit", false);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chromaSmoothingFor24Bit, "GPU", "ChromaSmoothing24Bit", false);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.forceNTSCTimings, "GPU", "ForceNTSCTimings", false);
|
|
||||||
|
|
||||||
connect(m_ui.renderer, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
connect(m_ui.renderer, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||||
&GraphicsSettingsWidget::updateRendererDependentOptions);
|
&GraphicsSettingsWidget::updateRendererDependentOptions);
|
||||||
|
@ -106,8 +108,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
||||||
!m_dialog->hasGameTrait(GameDatabase::Trait::ForceInterlacing));
|
!m_dialog->hasGameTrait(GameDatabase::Trait::ForceInterlacing));
|
||||||
SettingWidgetBinder::SetAvailability(m_ui.widescreenHack,
|
SettingWidgetBinder::SetAvailability(m_ui.widescreenHack,
|
||||||
!m_dialog->hasGameTrait(GameDatabase::Trait::DisableWidescreen));
|
!m_dialog->hasGameTrait(GameDatabase::Trait::DisableWidescreen));
|
||||||
SettingWidgetBinder::SetAvailability(m_ui.forceNTSCTimings,
|
SettingWidgetBinder::SetAvailability(m_ui.forceFrameTimings,
|
||||||
!m_dialog->hasGameTrait(GameDatabase::Trait::DisableForceNTSCTimings));
|
!m_dialog->hasGameTrait(GameDatabase::Trait::DisableForceFrameTimings));
|
||||||
|
|
||||||
// Advanced Tab
|
// Advanced Tab
|
||||||
|
|
||||||
|
@ -336,6 +338,12 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
||||||
dialog->registerWidgetHelp(
|
dialog->registerWidgetHelp(
|
||||||
m_ui.displayScaling, tr("Scaling"), tr("Bilinear (Smooth)"),
|
m_ui.displayScaling, tr("Scaling"), tr("Bilinear (Smooth)"),
|
||||||
tr("Determines how the emulated console's output is upscaled or downscaled to your monitor's resolution."));
|
tr("Determines how the emulated console's output is upscaled or downscaled to your monitor's resolution."));
|
||||||
|
dialog->registerWidgetHelp(
|
||||||
|
m_ui.forceFrameTimings, tr("Force Frame Timings"), tr("Disabled"),
|
||||||
|
tr("Utilizes the chosen frame timing regardless of the active region. "
|
||||||
|
"This feature can be used to force PAL games to run at 60Hz and NTSC games to run at 50Hz. "
|
||||||
|
"For most games which have a speed tied to the framerate, this will result in the game running approximately 17% faster or slower. "
|
||||||
|
"For variable frame rate games, it may not affect the speed."));
|
||||||
dialog->registerWidgetHelp(
|
dialog->registerWidgetHelp(
|
||||||
m_ui.trueColor, tr("True Color Rendering"), tr("Checked"),
|
m_ui.trueColor, tr("True Color Rendering"), tr("Checked"),
|
||||||
tr("Forces the precision of colours output to the console's framebuffer to use the full 8 bits of precision per "
|
tr("Forces the precision of colours output to the console's framebuffer to use the full 8 bits of precision per "
|
||||||
|
@ -366,11 +374,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
||||||
"Forces the rendering and display of frames to progressive mode. <br>This removes the \"combing\" effect seen in "
|
"Forces the rendering and display of frames to progressive mode. <br>This removes the \"combing\" effect seen in "
|
||||||
"480i games by rendering them in 480p. Usually safe to enable.<br><b><u>May not be compatible with all "
|
"480i games by rendering them in 480p. Usually safe to enable.<br><b><u>May not be compatible with all "
|
||||||
"games.</u></b>"));
|
"games.</u></b>"));
|
||||||
dialog->registerWidgetHelp(
|
|
||||||
m_ui.forceNTSCTimings, tr("Force NTSC Timings"), tr("Unchecked"),
|
|
||||||
tr("Uses NTSC frame timings when the console is in PAL mode, forcing PAL games to run at 60hz. <br>For most games "
|
|
||||||
"which have a speed tied to the framerate, this will result in the game running approximately 17% faster. "
|
|
||||||
"<br>For variable frame rate games, it may not affect the speed."));
|
|
||||||
|
|
||||||
// Advanced Tab
|
// Advanced Tab
|
||||||
|
|
||||||
|
@ -655,6 +658,13 @@ void GraphicsSettingsWidget::setupAdditionalUi()
|
||||||
QString::fromUtf8(Settings::GetDisplayScalingDisplayName(static_cast<DisplayScalingMode>(i))));
|
QString::fromUtf8(Settings::GetDisplayScalingDisplayName(static_cast<DisplayScalingMode>(i))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i < static_cast<u32>(ForceFrameTimingsMode::Count); i++)
|
||||||
|
{
|
||||||
|
m_ui.forceFrameTimings->addItem(
|
||||||
|
QString::fromUtf8(Settings::GetForceFrameTimingsName(static_cast<ForceFrameTimingsMode>(i))));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Advanced Tab
|
// Advanced Tab
|
||||||
|
|
||||||
for (u32 i = 0; i < static_cast<u32>(DisplayExclusiveFullscreenControl::Count); i++)
|
for (u32 i = 0; i < static_cast<u32>(DisplayExclusiveFullscreenControl::Count); i++)
|
||||||
|
|
|
@ -201,7 +201,7 @@
|
||||||
<item row="7" column="1">
|
<item row="7" column="1">
|
||||||
<widget class="QComboBox" name="displayScaling"/>
|
<widget class="QComboBox" name="displayScaling"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="0" colspan="2">
|
<item row="9" column="0" colspan="2">
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QCheckBox" name="pgxpDepthBuffer">
|
<widget class="QCheckBox" name="pgxpDepthBuffer">
|
||||||
|
@ -217,13 +217,6 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QCheckBox" name="forceNTSCTimings">
|
|
||||||
<property name="text">
|
|
||||||
<string>Force NTSC Timings</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QCheckBox" name="force43For24Bit">
|
<widget class="QCheckBox" name="force43For24Bit">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -274,6 +267,16 @@
|
||||||
<item row="3" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QComboBox" name="spriteTextureFiltering"/>
|
<widget class="QComboBox" name="spriteTextureFiltering"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="8" column="0">
|
||||||
|
<widget class="QLabel" name="forceFrameTimingsLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Force Frame Timings:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="1">
|
||||||
|
<widget class="QComboBox" name="forceFrameTimings"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
Loading…
Reference in a new issue