mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 00:10:56 +02:00
135 lines
5.6 KiB
Lua
135 lines
5.6 KiB
Lua
-- Driver: SET_PAL_BATTLE_BLACK darkens the whole battle screen while the
|
|
-- blackout text is up (#292). pokered engine/battle/core.asm:1147-1159
|
|
-- runs the palette command before the text, and returns early on OAKS_LAB.
|
|
-- No POKEPORT_SPEED here: audio runs on its own real-time clock.
|
|
-- POKEPORT_DRIVER=tests/drivers/blackout_palette_bug292_test.lua \
|
|
-- POKEPORT_IDENTITY=bug292 POKEPORT_TOUCH=0 SHOT_DIR=/tmp/shots love .
|
|
return function(game)
|
|
local U = dofile("tests/drivers/util.lua")
|
|
local DIR = os.getenv("SHOT_DIR") or "/tmp/shots"
|
|
local Pokemon = require("src.pokemon.Pokemon")
|
|
local BattleState = require("src.battle.BattleState")
|
|
local PaletteFX = require("src.render.PaletteFX")
|
|
|
|
-- Route 1: no scripted battle, not the Oak's Lab exception, and (5,5) is
|
|
-- open floor there (data/generated/maps.lua).
|
|
local MAP = "ROUTE_1"
|
|
local STAND = { x = 5, y = 5, facing = "down" }
|
|
|
|
local function check(label, ok)
|
|
U.log(ok and "PASS" or "FAIL", label)
|
|
return ok
|
|
end
|
|
|
|
-- ---- preconditions the eye cannot check --------------------------------
|
|
-- A missing PAL_BLACK looks exactly like the bug on screen.
|
|
local pack = PaletteFX.pack(game.data)
|
|
local BLACK = pack and pack.palettes and pack.palettes.BLACK
|
|
check("the active COLORS pack carries PAL_BLACK", BLACK ~= nil)
|
|
if BLACK then
|
|
U.log(" PAL_BLACK shades:",
|
|
("0 = %d,%d,%d"):format(BLACK[1][1], BLACK[1][2], BLACK[1][3]),
|
|
("1 = %d,%d,%d"):format(BLACK[2][1], BLACK[2][2], BLACK[2][3]),
|
|
("3 = %d,%d,%d"):format(BLACK[4][1], BLACK[4][2], BLACK[4][3]))
|
|
check("shade 0 is the near-white paper", BLACK[1][1] > 200)
|
|
check("shades 1-3 are near-black ink",
|
|
BLACK[2][1] < 90 and BLACK[3][1] < 90 and BLACK[4][1] < 90)
|
|
end
|
|
|
|
-- A DMG never had SGB darkening, so the fix deliberately does nothing in
|
|
-- the forced-mono modes and a run in one of them proves nothing.
|
|
local mode = PaletteFX.mode
|
|
local mono = mode == "og" or mode == "og_inv" or mode == "classic"
|
|
U.log("COLORS mode:", tostring(mode), "(" .. PaletteFX.modeLabel(mode) .. ")")
|
|
if mono then
|
|
U.log("WARNING: " .. PaletteFX.modeLabel(mode) .. " is a forced-mono mode.")
|
|
U.log("WARNING: PAL_BLACK is an SGB packet and a DMG never darkened, so")
|
|
U.log("WARNING: nothing below will look dark and that is CORRECT. Press 2")
|
|
U.log("WARNING: (or set COLORS in OPTION) to SGB / GBC first, then re-run.")
|
|
end
|
|
check("the COLORS mode is one that can show the darkening", not mono)
|
|
|
|
-- ---- a losing battle ---------------------------------------------------
|
|
-- One mon on 1 HP against something that outspeeds it.
|
|
game.save.party = { Pokemon.new(game.data, "RATTATA", 3) }
|
|
game.save.party[1].hp = 1
|
|
U.teleport(game, MAP, STAND.x, STAND.y, STAND.facing)
|
|
U.wait(10)
|
|
local ow = game.overworld
|
|
check("the overworld is up on " .. MAP, ow ~= nil)
|
|
check("this is not the Oak's Lab starter-rival exception",
|
|
(ow and ow.map and ow.map.id) ~= "OAKS_LAB")
|
|
|
|
local battle = BattleState.newWild(game, "RATICATE", 50)
|
|
battle.onFinish = function() end
|
|
if ow then ow:pushBattle(battle) end
|
|
for _ = 1, 400 do
|
|
if game.stack:top() == battle and (battle.introSlide or 0) == 0 then break end
|
|
U.wait(1)
|
|
end
|
|
check("the battle reached the screen", game.stack:top() == battle)
|
|
|
|
-- photograph the full-color screen so the "after" shot has a reference
|
|
for _ = 1, 60 do
|
|
if battle.phase == "menu" then break end
|
|
U.tap(game, "a")
|
|
U.wait(4)
|
|
end
|
|
check("the battle reached its action menu", battle.phase == "menu")
|
|
check("nothing is darkened yet", battle.blackedOut == nil)
|
|
if not U.shot(game, DIR .. "/bug292_1_full_color.png") then
|
|
U.log("FAIL could not capture the full-color battle")
|
|
end
|
|
|
|
-- ---- lose it -----------------------------------------------------------
|
|
-- Stop the instant the wipe registers, so the blackout text is still ahead
|
|
-- of the player.
|
|
for _ = 1, 700 do
|
|
if battle.blackedOut then break end
|
|
if battle.result then break end
|
|
U.tap(game, "a")
|
|
U.wait(4)
|
|
end
|
|
if not battle.blackedOut and not battle.result then
|
|
-- the foe kept rolling status moves: take the engine's own faint path
|
|
U.log("the foe never landed a hit; forcing the KO through onFaint")
|
|
battle.player.mon.hp = 0
|
|
battle.nextInsert = 0
|
|
battle:onFaint(battle.player)
|
|
for _ = 1, 400 do
|
|
if battle.blackedOut then break end
|
|
U.tap(game, "a")
|
|
U.wait(4)
|
|
end
|
|
end
|
|
check("the party was wiped out and the screen blacked", battle.blackedOut == true)
|
|
|
|
-- Two code paths darken the screen (the zone pass for HUD and bars, a
|
|
-- re-baked pic for the sprites) and both have to fire.
|
|
if BLACK then
|
|
local pals = battle:sgbBattlePals()
|
|
check("all four battle zones are PAL_BLACK",
|
|
pals ~= nil and pals[0] == BLACK and pals[1] == BLACK
|
|
and pals[2] == BLACK and pals[3] == BLACK)
|
|
end
|
|
|
|
U.wait(20)
|
|
if not U.shot(game, DIR .. "/bug292_2_blacked_out.png") then
|
|
U.log("FAIL could not capture the blacked-out battle")
|
|
end
|
|
local cur = battle.current
|
|
U.log("box on screen:", cur and cur.text and (cur.text:gsub("\n", " / "))
|
|
or "(between rows)")
|
|
|
|
-- ---- hand off ----------------------------------------------------------
|
|
U.log("Your last POKeMON has fainted; press A through the blackout text.")
|
|
U.log("Behind the box the enemy sprite, the HP bar and the HUD should all")
|
|
U.log("be near-black on near-white for both lines (#292). Compare")
|
|
U.log(DIR .. "/bug292_1_full_color.png with bug292_2_blacked_out.png.")
|
|
U.log("OG / OG INV / CLASSIC and the Oak's lab rival fight never darken.")
|
|
|
|
while true do
|
|
coroutine.yield()
|
|
end
|
|
end
|