From d711baaa31b3409333a8baf55383faf247767c0b Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 25 Jul 2020 02:37:00 +1000 Subject: [PATCH] GPU/HW: Fix lines being one pixel too short Fixes lines in screen wipe effect in Vagrant Story. --- src/core/gpu_hw.cpp | 38 ++++++++++++++++++++++++++++++++++---- src/core/gpu_hw.h | 1 + 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index 66a762e4b..c4a365992 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -186,6 +186,27 @@ void GPU_HW::HandleFlippedQuadTextureCoordinates(BatchVertex* vertices) } } +// The PlayStation GPU draws lines from start to end, inclusive. Or, more specifically, inclusive of the greatest delta +// in the x or y direction. +void GPU_HW::FixLineVertexCoordinates(BatchVertex& start, BatchVertex& end, s32 dx, s32 dy) +{ + // deliberately not else if to catch the equal case + if (dx >= dy) + { + if (start.x > end.x) + start.x++; + else + end.x++; + } + if (dx <= dy) + { + if (start.y > end.y) + start.y++; + else + end.y++; + } +} + void GPU_HW::LoadVertices() { const RenderCommand rc{m_render_command.bits}; @@ -414,13 +435,17 @@ void GPU_HW::LoadVertices() const s32 max_x = std::max(start.x, end.x); const s32 min_y = std::min(start.y, end.y); const s32 max_y = std::max(start.y, end.y); + const s32 dx = max_x - min_x; + const s32 dy = max_y - min_y; - if ((max_x - min_x) >= MAX_PRIMITIVE_WIDTH || (max_y - min_y) >= MAX_PRIMITIVE_HEIGHT) + if (dx >= MAX_PRIMITIVE_WIDTH || dy >= MAX_PRIMITIVE_HEIGHT) { Log_DebugPrintf("Culling too-large line: %d,%d - %d,%d", start.x, start.y, end.x, end.y); return; } + FixLineVertexCoordinates(start, end, dx, dy); + AddVertex(start); AddVertex(end); @@ -461,16 +486,21 @@ void GPU_HW::LoadVertices() const s32 max_x = std::max(last_vertex.x, vertex.x); const s32 min_y = std::min(last_vertex.y, vertex.y); const s32 max_y = std::max(last_vertex.y, vertex.y); + const s32 dx = max_x - min_x; + const s32 dy = max_y - min_y; - if ((max_x - min_x) >= MAX_PRIMITIVE_WIDTH || (max_y - min_y) >= MAX_PRIMITIVE_HEIGHT) + if (dx >= MAX_PRIMITIVE_WIDTH || dy >= MAX_PRIMITIVE_HEIGHT) { Log_DebugPrintf("Culling too-large line: %d,%d - %d,%d", last_vertex.x, last_vertex.y, vertex.x, vertex.y); } else { - AddVertex(last_vertex); - AddVertex(vertex); + BatchVertex start(last_vertex); + BatchVertex end(vertex); + FixLineVertexCoordinates(start, end, dx, dy); + AddVertex(start); + AddVertex(end); const u32 clip_left = static_cast(std::clamp(min_x, m_drawing_area.left, m_drawing_area.left)); const u32 clip_right = diff --git a/src/core/gpu_hw.h b/src/core/gpu_hw.h index d57e3aeec..90ec7620a 100644 --- a/src/core/gpu_hw.h +++ b/src/core/gpu_hw.h @@ -235,6 +235,7 @@ protected: /// Handles quads with flipped texture coordinate directions. static void HandleFlippedQuadTextureCoordinates(BatchVertex* vertices); + static void FixLineVertexCoordinates(BatchVertex& start, BatchVertex& end, s32 dx, s32 dy); HeapArray m_vram_shadow;