diff --git a/src/battle/BattleState.lua b/src/battle/BattleState.lua index a1af87ab..1722f05e 100644 --- a/src/battle/BattleState.lua +++ b/src/battle/BattleState.lua @@ -4006,9 +4006,10 @@ end -- recolor the grayscale BG canvas per zone; an active BGP fade permutes -- the zone palette (the SGB colors the remapped DMG shade). A window --- shake draws a second, offset copy over the base one: the color --- regions themselves never move on the SGB, and the vacated strip --- shows the unshifted BG map like the hardware. +-- shake draws only the offset copy: the baked canvas holds the HUDs and +-- text box (window-layer content), so compositing an unshifted copy +-- 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) local PaletteFX = require("src.render.PaletteFX") local shader = PaletteFX.shader() @@ -4016,13 +4017,17 @@ function BattleState:drawZonePass(src, sx, sy) local bgp = self:activeBgp() love.graphics.setColor(1, 1, 1, 1) love.graphics.setShader(shader) + local shaking = sx ~= 0 or sy ~= 0 for _, z in ipairs(BATTLE_ZONES) do PaletteFX.sendColors(shader, PaletteFX.permute(pals[z.pal], bgp)) - love.graphics.setScissor(z[1] * 8, z[2] * 8, - (z[3] - z[1] + 1) * 8, (z[4] - z[2] + 1) * 8) - love.graphics.draw(src, 0, 0) - if sx ~= 0 or sy ~= 0 then + local zx, zy = z[1] * 8, z[2] * 8 + local zw, zh = (z[3] - z[1] + 1) * 8, (z[4] - z[2] + 1) * 8 + love.graphics.setScissor(zx, zy, zw, zh) + if shaking then + love.graphics.rectangle("fill", zx, zy, zw, zh) love.graphics.draw(src, sx, sy) + else + love.graphics.draw(src, 0, 0) end end love.graphics.setScissor() diff --git a/tests/run_tests.lua b/tests/run_tests.lua index 396db06d..eec7849f 100644 --- a/tests/run_tests.lua +++ b/tests/run_tests.lua @@ -2886,6 +2886,47 @@ do Font.drawCode, Font.drawBox = origCode, origBox eq(drawn, 0, "no current message and no animation draws no text") 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 -- ================= BUGS.md batch: ledge-shadow =================