From 866cbdca4b907a1a8588ef4749e63d4d6761050b Mon Sep 17 00:00:00 2001 From: Albert Liu <45282415+ggrtk@users.noreply.github.com> Date: Sat, 12 Dec 2020 00:02:24 -0800 Subject: [PATCH] GPU: Prevent potential overflow in CRTC visible area calculation --- src/core/gpu.cpp | 16 ++++++++++++++++ src/core/gpu.h | 1 + 2 files changed, 17 insertions(+) diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index 0a1f3c99a..00f5e8e52 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -568,6 +568,14 @@ void GPU::UpdateCRTCDisplayParameters() cs.vertical_visible_end = vertical_display_end; break; } + cs.horizontal_visible_start = + std::clamp(cs.horizontal_visible_start, PAL_HORIZONTAL_ACTIVE_START, PAL_HORIZONTAL_ACTIVE_END); + cs.horizontal_visible_end = + std::clamp(cs.horizontal_visible_end, cs.horizontal_visible_start, PAL_HORIZONTAL_ACTIVE_END); + cs.vertical_visible_start = + std::clamp(cs.vertical_visible_start, PAL_VERTICAL_ACTIVE_START, PAL_VERTICAL_ACTIVE_END); + cs.vertical_visible_end = + std::clamp(cs.vertical_visible_end, cs.vertical_visible_start, PAL_VERTICAL_ACTIVE_END); } else { @@ -597,6 +605,14 @@ void GPU::UpdateCRTCDisplayParameters() cs.vertical_visible_end = vertical_display_end; break; } + cs.horizontal_visible_start = + std::clamp(cs.horizontal_visible_start, NTSC_HORIZONTAL_ACTIVE_START, NTSC_HORIZONTAL_ACTIVE_END); + cs.horizontal_visible_end = + std::clamp(cs.horizontal_visible_end, cs.horizontal_visible_start, NTSC_HORIZONTAL_ACTIVE_END); + cs.vertical_visible_start = + std::clamp(cs.vertical_visible_start, NTSC_VERTICAL_ACTIVE_START, NTSC_VERTICAL_ACTIVE_END); + cs.vertical_visible_end = + std::clamp(cs.vertical_visible_end, cs.vertical_visible_start, NTSC_VERTICAL_ACTIVE_END); } // If force-progressive is enabled, we only double the height in 480i mode. This way non-interleaved 480i framebuffers diff --git a/src/core/gpu.h b/src/core/gpu.h index 1b6ba782b..47242a74f 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -497,6 +497,7 @@ protected: u16 display_vram_width; u16 display_vram_height; + // Visible range of the screen, in GPU ticks/lines. Clamped to lie within the active video region. u16 horizontal_visible_start; u16 horizontal_visible_end; u16 vertical_visible_start;