From 304391bd00a305597daa556f6dec5bab56579c08 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Mon, 27 Apr 2020 12:51:17 +1000 Subject: [PATCH] GPU: Truncate sprite/rectangle positions to 12 bits before rendering Fixes disappearing objects in Skullmonkeys. --- src/core/gpu.h | 6 ++++-- src/core/gpu_hw.cpp | 4 ++-- src/core/gpu_sw.cpp | 20 ++++++++++---------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/core/gpu.h b/src/core/gpu.h index 8d819b9ec..fdc7b123e 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -166,7 +166,7 @@ public: bool ConvertScreenCoordinatesToBeamTicksAndLines(s32 window_x, s32 window_y, u32* out_tick, u32* out_line) const; protected: - static TickCount GPUTicksToSystemTicks(TickCount gpu_ticks) + static constexpr TickCount GPUTicksToSystemTicks(TickCount gpu_ticks) { // convert to master clock, rounding up as we want to overshoot not undershoot return static_cast((static_cast(gpu_ticks) * 7u + 10u) / 11u); @@ -254,7 +254,6 @@ protected: } }; - // TODO: Use BitField to do sign extending instead union VertexPosition { u32 bits; @@ -263,6 +262,9 @@ protected: BitField y; }; + // Sprites/rectangles should be clipped to 12 bits before drawing. + static constexpr s32 TruncateVertexPosition(s32 x) { return SignExtendN<11, s32>(x); } + union VRAMPixel { u16 bits; diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index af468f07c..997b87244 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -270,8 +270,8 @@ void GPU_HW::LoadVertices() { const u32 color = rc.color_for_first_vertex; const VertexPosition vp{m_fifo.Pop()}; - const s32 pos_x = m_drawing_offset.x + vp.x; - const s32 pos_y = m_drawing_offset.y + vp.y; + const s32 pos_x = TruncateVertexPosition(m_drawing_offset.x + vp.x); + const s32 pos_y = TruncateVertexPosition(m_drawing_offset.y + vp.y); const auto [texcoord_x, texcoord_y] = UnpackTexcoord(rc.texture_enable ? Truncate16(m_fifo.Pop()) : 0); u16 orig_tex_left = ZeroExtend16(texcoord_x); diff --git a/src/core/gpu_sw.cpp b/src/core/gpu_sw.cpp index dc39639ff..9bda22730 100644 --- a/src/core/gpu_sw.cpp +++ b/src/core/gpu_sw.cpp @@ -514,24 +514,24 @@ template void GPU_SW::DrawRectangle(s32 origin_x, s32 origin_y, u32 width, u32 height, u8 r, u8 g, u8 b, u8 origin_texcoord_x, u8 origin_texcoord_y) { - origin_x += m_drawing_offset.x; - origin_y += m_drawing_offset.y; + const s32 start_x = TruncateVertexPosition(m_drawing_offset.x + origin_x); + const s32 start_y = TruncateVertexPosition(m_drawing_offset.y + origin_y); { - const u32 clip_left = static_cast(std::clamp(origin_x, m_drawing_area.left, m_drawing_area.right)); + const u32 clip_left = static_cast(std::clamp(start_x, m_drawing_area.left, m_drawing_area.right)); const u32 clip_right = - static_cast(std::clamp(origin_x + static_cast(width), m_drawing_area.left, m_drawing_area.right)) + + static_cast(std::clamp(start_x + static_cast(width), m_drawing_area.left, m_drawing_area.right)) + + 1u; + const u32 clip_top = static_cast(std::clamp(start_y, m_drawing_area.top, m_drawing_area.bottom)); + const u32 clip_bottom = + static_cast(std::clamp(start_y + static_cast(height), m_drawing_area.top, m_drawing_area.bottom)) + 1u; - const u32 clip_top = static_cast(std::clamp(origin_y, m_drawing_area.top, m_drawing_area.bottom)); - const u32 clip_bottom = static_cast(std::clamp(origin_y + static_cast(height), m_drawing_area.top, - m_drawing_area.bottom)) + - 1u; AddDrawRectangleTicks(clip_right - clip_left, clip_bottom - clip_top, texture_enable); } for (u32 offset_y = 0; offset_y < height; offset_y++) { - const s32 y = origin_y + static_cast(offset_y); + const s32 y = start_y + static_cast(offset_y); if (y < static_cast(m_drawing_area.top) || y > static_cast(m_drawing_area.bottom)) continue; @@ -539,7 +539,7 @@ void GPU_SW::DrawRectangle(s32 origin_x, s32 origin_y, u32 width, u32 height, u8 for (u32 offset_x = 0; offset_x < width; offset_x++) { - const s32 x = origin_x + static_cast(offset_x); + const s32 x = start_x + static_cast(offset_x); if (x < static_cast(m_drawing_area.left) || x > static_cast(m_drawing_area.right)) continue;