mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
23617f43b4
CLOSES #2290, CLOSES #2338, CLOSES #2186, CLOSES #2305, CLOSES #2332, CLOSES #2320, CLOSES #2344, CLOSES #2291, CLOSES #2335, CLOSES #2340, CLOSES #2385, CLOSES #2352, CLOSES #2378, CLOSES #2403, CLOSES #2404, CLOSES #2405, CLOSES #2367, CLOSES #2037, CLOSES #2177, CLOSES #2368, CLOSES #2382, CLOSES #1951
209 lines
7.7 KiB
Lua
209 lines
7.7 KiB
Lua
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
local T = require("tests.harness")
|
|
local check, eq = T.check, T.eq
|
|
love = love or require("tests.love_stub")
|
|
|
|
local GameVersion = require("src.core.GameVersion")
|
|
local PaletteFX = require("src.render.PaletteFX")
|
|
local SpriteRenderer = require("src.render.SpriteRenderer")
|
|
local IntroMovie = require("src.ui.IntroMovie")
|
|
|
|
local prevVersion, prevMode = GameVersion.get(), PaletteFX.mode
|
|
|
|
local STAR_START, FLASH_START = 64, 104
|
|
local WAVES_START, SPLASH_FRAMES = 134, 318
|
|
|
|
local LOGO = "tests/fixtures/missing_gflogo_2385.png"
|
|
local TEXT = "tests/fixtures/missing_gftext_2385.png"
|
|
local STAR = "tests/fixtures/missing_bigstar_2385.png"
|
|
|
|
local function pal(n)
|
|
return { { 255, 239, 255 }, { n, 200, 100 }, { n, 90, 40 }, { 16, 16, 16 } }
|
|
end
|
|
local PALS = { palettes = {
|
|
GAMEFREAK = pal(1), REDMON = pal(2), VIRIDIAN = pal(3), BLUEMON = pal(4),
|
|
} }
|
|
|
|
local function newGame(studio)
|
|
return {
|
|
data = { palettes = PALS, field = { intro = {
|
|
gamefreakLogo = { path = LOGO },
|
|
gamefreakText = { path = TEXT },
|
|
bigStar = { path = STAR },
|
|
studio = studio,
|
|
} } },
|
|
stack = { pop = function() end },
|
|
}
|
|
end
|
|
|
|
local bakes = {}
|
|
local realObp = SpriteRenderer.obpImage
|
|
SpriteRenderer.obpImage = function(path, colors, group)
|
|
bakes[#bakes + 1] = { path = path, colors = colors, group = group }
|
|
return realObp(path, colors, group)
|
|
end
|
|
|
|
local function sameRamp(a, b)
|
|
if not (a and b) then return false end
|
|
for i = 1, 4 do
|
|
if a[i] ~= b[i] then return false end
|
|
end
|
|
return true
|
|
end
|
|
|
|
local function ramp(base, i1, i2, i3)
|
|
return { base[1], base[i1 + 1], base[i2 + 1], base[i3 + 1] }
|
|
end
|
|
|
|
local function bakeFor(list, path, group)
|
|
for _, b in ipairs(list) do
|
|
if b.path == path and b.group == group then return b end
|
|
end
|
|
end
|
|
|
|
local function drawSplash(mode, version, timer)
|
|
GameVersion.set(version)
|
|
PaletteFX.setMode(mode)
|
|
local movie = IntroMovie.new(newGame())
|
|
movie.phase = 2
|
|
movie.timer = timer
|
|
local before = #bakes
|
|
PaletteFX.clearSpriteRedraws()
|
|
PaletteFX.setPass("ui")
|
|
local ok, err = pcall(movie.draw, movie)
|
|
PaletteFX.setPass(nil)
|
|
check(ok, mode .. "/" .. version .. " splash draw runs headless" .. (ok and "" or (": " .. tostring(err))))
|
|
local out, newBakes = {}, {}
|
|
for i, r in ipairs(PaletteFX.uiSpriteRedraws()) do out[i] = r end
|
|
for i = before + 1, #bakes do newBakes[#newBakes + 1] = bakes[i] end
|
|
PaletteFX.clearSpriteRedraws()
|
|
return out, newBakes, movie
|
|
end
|
|
|
|
do
|
|
local game = newGame()
|
|
for _, v in ipairs({ "red", "blue" }) do
|
|
GameVersion.set(v)
|
|
PaletteFX.setMode("ogred")
|
|
local movie = IntroMovie.new(game)
|
|
local z = movie:sgbPalettes(game)
|
|
check(z and z[1], "ogred/" .. v .. ": the copyright card has palette zones")
|
|
check(z and z[1] and sameRamp(z[1].colors, PaletteFX.ogBg()),
|
|
"ogred/" .. v .. ": the copyright card wears the boot-ROM BG ramp")
|
|
PaletteFX.setMode("gbc")
|
|
z = movie:sgbPalettes(game)
|
|
eq(z and #z, 4, "gbc/" .. v .. ": the copyright card gets PalPacket_GameFreakIntro's four zones")
|
|
movie.phase = 2
|
|
local z2 = movie:sgbPalettes(game)
|
|
check(z and z2 and sameRamp(z[1].colors, z2[1].colors),
|
|
"gbc/" .. v .. ": the card and the splash share PAL_GAMEFREAK")
|
|
end
|
|
GameVersion.set("red")
|
|
PaletteFX.setMode("ogred")
|
|
local mod = newGame()
|
|
mod.data.field.intro.studio = { card = "A MOD" }
|
|
local movie = IntroMovie.new(mod)
|
|
eq(movie:sgbPalettes(mod), nil, "a studio text card stays untinted")
|
|
end
|
|
|
|
do
|
|
local movie = IntroMovie.new(newGame())
|
|
local function at(t)
|
|
movie.timer = t
|
|
return movie.logoObp0 and movie:logoObp0()
|
|
end
|
|
eq(at(STAR_START), 0xF9, "rOBP0 starts at $F9")
|
|
eq(at(FLASH_START - 1), 0xF9, "rOBP0 holds $F9 until the flash loop")
|
|
eq(at(FLASH_START), 0x7E, "first rrc rrc gives $7E")
|
|
eq(at(FLASH_START + 9), 0x7E, "$7E holds 10 frames")
|
|
eq(at(FLASH_START + 10), 0x9F, "second rotation gives $9F")
|
|
eq(at(FLASH_START + 20), 0xE7, "third rotation gives $E7")
|
|
eq(at(WAVES_START + 10), 0xE7, "$E7 stays through the small-star waves")
|
|
eq(at(SPLASH_FRAMES - 1), 0xE7, "$E7 stays through the 40-frame tail")
|
|
end
|
|
|
|
do
|
|
local G = PaletteFX.GRAYS
|
|
local _, b = drawSplash("gbc", "red", STAR_START + 5)
|
|
local logo = bakeFor(b, LOGO, "gfobp" .. 0xF9)
|
|
check(logo and sameRamp(logo.colors, ramp(G, 2, 3, 3)),
|
|
"$F9 draws the logo's colour 2 as black on the canvas")
|
|
local text = bakeFor(b, TEXT, "gfobp" .. 0xF9)
|
|
check(text and sameRamp(text.colors, ramp(G, 2, 3, 3)),
|
|
"$F9 draws the text's colour 3 as black on the canvas")
|
|
local star = bakeFor(b, STAR, "gfobp" .. 0xA4)
|
|
check(star and sameRamp(star.colors, ramp(G, 1, 2, 2)),
|
|
"rOBP1 $A4 draws the big star's colour 3 as shade 2")
|
|
_, b = drawSplash("gbc", "red", FLASH_START + 5)
|
|
logo = bakeFor(b, LOGO, "gfobp" .. 0x7E)
|
|
check(logo and sameRamp(logo.colors, ramp(G, 3, 3, 1)),
|
|
"$7E: logo black, text light")
|
|
_, b = drawSplash("gbc", "red", FLASH_START + 15)
|
|
logo = bakeFor(b, LOGO, "gfobp" .. 0x9F)
|
|
check(logo and sameRamp(logo.colors, ramp(G, 3, 1, 2)),
|
|
"$9F: logo light, text dark")
|
|
_, b = drawSplash("og", "red", WAVES_START + 10)
|
|
logo = bakeFor(b, LOGO, "gfobp" .. 0xE7)
|
|
check(logo and sameRamp(logo.colors, ramp(G, 1, 2, 3)),
|
|
"$E7 settles the logo on shade 2 and the text on black")
|
|
end
|
|
|
|
do
|
|
local O = PaletteFX.GBC_OBJ
|
|
local r, b = drawSplash("ogred", "red", STAR_START + 5)
|
|
eq(#r, 3, "ogred red: logo, text and big star are replayed over the zone pass")
|
|
local logo, text, star = r[1] or {}, r[2] or {}, r[3] or {}
|
|
eq(logo.x, 72, "logo replays at x 72")
|
|
eq(logo.y, 56, "logo replays at y 56")
|
|
eq(text.x, 40, "text replays at x 40")
|
|
eq(text.y, 80, "text replays at y 80")
|
|
local lb = bakeFor(b, LOGO, "gfobj" .. 0xF9)
|
|
check(lb and sameRamp(lb.colors, { O[1], O[3], O[4], O[4] }),
|
|
"ogred red: the logo starts black through OBJ0")
|
|
eq(logo.image, SpriteRenderer.obpImage(LOGO, lb and lb.colors or O, "gfobj" .. 0xF9),
|
|
"the replayed logo is the OBJ0 bake")
|
|
local sb = bakeFor(b, STAR, "gfobj1" .. 0xA4)
|
|
check(sb and sameRamp(sb.colors, ramp(PaletteFX.GBC_BG, 1, 2, 2)),
|
|
"ogred red: the big star replays through OBJ1 = the BG ramp")
|
|
eq(star.image, SpriteRenderer.obpImage(STAR, sb and sb.colors or O, "gfobj1" .. 0xA4),
|
|
"the big star replays last so it stays over the logo")
|
|
|
|
r, b = drawSplash("ogred", "red", WAVES_START + 10)
|
|
eq(#r, 2, "ogred red: after the star, only logo and text replay")
|
|
lb = bakeFor(b, LOGO, "gfobj" .. 0xE7)
|
|
check(lb and sameRamp(lb.colors, { O[1], O[2], O[3], O[4] }),
|
|
"ogred red: $E7 leaves the logo dark green and the text black")
|
|
_, b = drawSplash("ogred", "red", FLASH_START + 5)
|
|
lb = bakeFor(b, TEXT, "gfobj" .. 0x7E)
|
|
check(lb and sameRamp(lb.colors, { O[1], O[4], O[4], O[2] }),
|
|
"ogred red: the first flash turns the text light green")
|
|
end
|
|
|
|
do
|
|
local OB = PaletteFX.GBC_OBJ_BLUE
|
|
local r, b = drawSplash("ogred", "blue", WAVES_START + 10)
|
|
eq(#r, 2, "ogred blue: logo and text replay")
|
|
local lb = bakeFor(b, LOGO, "gfobj_blue" .. 0xE7)
|
|
check(lb and sameRamp(lb.colors, { OB[1], OB[2], OB[3], OB[4] }),
|
|
"ogred blue: the logo bakes Blue's pink OBJ0 under its own group")
|
|
check(not bakeFor(b, LOGO, "gfobj" .. 0xE7), "ogred blue never bakes into the red group")
|
|
end
|
|
|
|
do
|
|
for _, mode in ipairs({ "gbc", "og", "classic", "redpp" }) do
|
|
local r = drawSplash(mode, "red", WAVES_START + 10)
|
|
eq(#r, 0, mode .. " records no splash OBJ replay")
|
|
end
|
|
local r = drawSplash("ogred", "yellow", WAVES_START + 10)
|
|
eq(#r, 0, "OG YELLOW keeps the CGB zone path")
|
|
r = drawSplash("ogred", "red", 0)
|
|
eq(#r, 0, "nothing replays before the star")
|
|
end
|
|
|
|
SpriteRenderer.obpImage = realObp
|
|
GameVersion.set(prevVersion)
|
|
PaletteFX.setMode(prevMode)
|
|
|
|
T.finish()
|