Stop HUD names ghosting during the battle window shake (#295)

The zone pass composited two copies of the baked canvas on shake
frames: a base copy and the offset copy. The canvas holds window-layer
content (HUD names, the text box), so the vacated strip showed a full
second copy of the enemy name. Draw only the shifted copy and fill the
strip blank, like the hardware revealing empty BG.
This commit is contained in:
johnjohto
2026-07-27 20:44:09 -04:00
parent 10acfe0710
commit 5b3c5f5da8
2 changed files with 53 additions and 7 deletions
+12 -7
View File
@@ -4006,9 +4006,10 @@ end
-- recolor the grayscale BG canvas per zone; an active BGP fade permutes -- recolor the grayscale BG canvas per zone; an active BGP fade permutes
-- the zone palette (the SGB colors the remapped DMG shade). A window -- the zone palette (the SGB colors the remapped DMG shade). A window
-- shake draws a second, offset copy over the base one: the color -- shake draws only the offset copy: the baked canvas holds the HUDs and
-- regions themselves never move on the SGB, and the vacated strip -- text box (window-layer content), so compositing an unshifted copy
-- shows the unshifted BG map like the hardware. -- underneath ghosted every name in the vacated strip (#295). The strip
-- shows blank color 0 instead, like the hardware revealing empty BG.
function BattleState:drawZonePass(src, sx, sy) function BattleState:drawZonePass(src, sx, sy)
local PaletteFX = require("src.render.PaletteFX") local PaletteFX = require("src.render.PaletteFX")
local shader = PaletteFX.shader() local shader = PaletteFX.shader()
@@ -4016,13 +4017,17 @@ function BattleState:drawZonePass(src, sx, sy)
local bgp = self:activeBgp() local bgp = self:activeBgp()
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
love.graphics.setShader(shader) love.graphics.setShader(shader)
local shaking = sx ~= 0 or sy ~= 0
for _, z in ipairs(BATTLE_ZONES) do for _, z in ipairs(BATTLE_ZONES) do
PaletteFX.sendColors(shader, PaletteFX.permute(pals[z.pal], bgp)) PaletteFX.sendColors(shader, PaletteFX.permute(pals[z.pal], bgp))
love.graphics.setScissor(z[1] * 8, z[2] * 8, local zx, zy = z[1] * 8, z[2] * 8
(z[3] - z[1] + 1) * 8, (z[4] - z[2] + 1) * 8) local zw, zh = (z[3] - z[1] + 1) * 8, (z[4] - z[2] + 1) * 8
love.graphics.draw(src, 0, 0) love.graphics.setScissor(zx, zy, zw, zh)
if sx ~= 0 or sy ~= 0 then if shaking then
love.graphics.rectangle("fill", zx, zy, zw, zh)
love.graphics.draw(src, sx, sy) love.graphics.draw(src, sx, sy)
else
love.graphics.draw(src, 0, 0)
end end
end end
love.graphics.setScissor() love.graphics.setScissor()
+41
View File
@@ -2886,6 +2886,47 @@ do
Font.drawCode, Font.drawBox = origCode, origBox Font.drawCode, Font.drawBox = origCode, origBox
eq(drawn, 0, "no current message and no animation draws no text") eq(drawn, 0, "no current message and no animation draws no text")
end end
-- issue #295: during a window shake the zone pass draws only the shifted
-- copy; a base copy underneath ghosted the HUD names in the vacated strip
do
local PaletteFX = require("src.render.PaletteFX")
local origShaderFn, origSend = PaletteFX.shader, PaletteFX.sendColors
local origPermute = PaletteFX.permute
local origDraw, origRect = love.graphics.draw, love.graphics.rectangle
PaletteFX.shader = function() return nil end
PaletteFX.sendColors = function() end
PaletteFX.permute = function(p) return p end
local draws, fills = {}, 0
love.graphics.draw = function(_, x, y) draws[#draws + 1] = { x, y } end
love.graphics.rectangle = function(mode) if mode == "fill" then fills = fills + 1 end end
local battle = setmetatable({ fx = {} }, BattleState)
function battle:sgbBattlePals() return setmetatable({}, { __index = function() return {} end }) end
function battle:activeBgp() return nil end
battle:drawZonePass("canvas", 0, 8)
check(#draws > 0, "the zone pass still draws during a shake")
local shiftedOnly = true
for _, d in ipairs(draws) do
if d[1] == 0 and d[2] == 0 then shiftedOnly = false end
if d[2] ~= 8 then shiftedOnly = false end
end
check(shiftedOnly, "a shake draws only the shifted copy, no base copy")
check(fills == #draws, "the vacated strip is filled blank per zone")
draws, fills = {}, 0
battle:drawZonePass("canvas", 0, 0)
local baseOnly = #draws > 0
for _, d in ipairs(draws) do
if d[1] ~= 0 or d[2] ~= 0 then baseOnly = false end
end
check(baseOnly, "no shake draws the single base copy as before")
check(fills == 0, "no strip fill without a shake")
love.graphics.draw, love.graphics.rectangle = origDraw, origRect
PaletteFX.shader, PaletteFX.sendColors = origShaderFn, origSend
PaletteFX.permute = origPermute
end
end end
-- ================= BUGS.md batch: ledge-shadow ================= -- ================= BUGS.md batch: ledge-shadow =================