mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-27 08:51:27 +02:00
276 lines
10 KiB
Lua
276 lines
10 KiB
Lua
-- Gen 2's answer to tests/engine/palette_test.lua: the same COLORS picker,
|
|
-- wired onto Gold's COLOR row and its own substitution seam
|
|
-- (src/render/GbcPalette.lua) instead of Gen 1's PaletteFX.
|
|
-- luajit tests/engine/gen2_palette_picker_test.lua
|
|
--
|
|
-- Covers GbcPalette.customRamp/setCustomRamp (the seam every Gen 2 draw call
|
|
-- shares), that a stored palette beats CLASSIC's present pass the same way
|
|
-- it beats OG/OG INV/CLASSIC on Gen 1, and that the COLOR row opens the
|
|
-- picker while GBC/DMG/CLASSIC stay reachable inside it.
|
|
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
if not _G.love then _G.love = require("tests.love_stub") end
|
|
|
|
local T = require("tests.harness")
|
|
local check, eq = T.check, T.eq
|
|
|
|
local function hex(c)
|
|
return type(c) == "table" and ("%02x%02x%02x"):format(c[1], c[2], c[3]) or "?"
|
|
end
|
|
|
|
local Palette = require("src.render.Palette")
|
|
local GbcPalette = require("src.render.GbcPalette")
|
|
|
|
-- ------- GbcPalette seam: a custom ramp wins outright
|
|
|
|
do
|
|
GbcPalette.setCustomRamp(nil)
|
|
GbcPalette.setMode("gbc")
|
|
|
|
local cartColors = { { 9, 9, 9 }, { 8, 8, 8 }, { 7, 7, 7 }, { 6, 6, 6 } }
|
|
eq(GbcPalette.resolve(cartColors), cartColors,
|
|
"no custom ramp: GBC mode passes the cart's own colours through")
|
|
|
|
local id = Palette.packId("GalleryWebApp Palettes", "Original GB")
|
|
local ramp = Palette.ramp(id)
|
|
GbcPalette.setCustomRamp(ramp)
|
|
|
|
local out = GbcPalette.resolve(cartColors)
|
|
for i = 1, 4 do
|
|
eq(hex(out[i]), hex(ramp[i]),
|
|
"resolve[" .. i .. "] is the custom ramp, not the cart's own colours")
|
|
end
|
|
|
|
-- it should win even over DMG, since DMG's whole effect lives at this seam
|
|
GbcPalette.setMode("dmg")
|
|
local out2 = GbcPalette.resolve(cartColors)
|
|
eq(hex(out2[1]), hex(ramp[1]), "a custom ramp beats DMG too")
|
|
|
|
GbcPalette.setMode("gbc")
|
|
GbcPalette.setCustomRamp(nil)
|
|
eq(GbcPalette.resolve(cartColors), cartColors,
|
|
"clearing the ramp restores the cart's own colours")
|
|
end
|
|
|
|
-- ------- CLASSIC is a present pass, same as Gen 1: it has to be dropped
|
|
|
|
do
|
|
GbcPalette.setCustomRamp(nil)
|
|
GbcPalette.setMode("classic")
|
|
check(GbcPalette.presentColors() ~= nil,
|
|
"CLASSIC has a present pass before any palette is picked")
|
|
|
|
local id = Palette.packId("BGB", "Red")
|
|
local ramp = Palette.ramp(id)
|
|
GbcPalette.setCustomRamp(ramp)
|
|
-- resolve() alone can't save CLASSIC: presentColors bypasses resolve
|
|
-- entirely, so the picker's opts have to drop the mode itself. Covered
|
|
-- below via the real row wiring.
|
|
GbcPalette.setMode("gbc")
|
|
GbcPalette.setCustomRamp(nil)
|
|
end
|
|
|
|
-- ------- applyOptions: a saved palette re-applies on load, like Gen 1's
|
|
|
|
do
|
|
GbcPalette.setCustomRamp(nil)
|
|
local id = Palette.packId("BGB", "Blue")
|
|
GbcPalette.applyOptions({ color = "dmg", palette = id })
|
|
eq(GbcPalette.mode, "dmg", "applyOptions still sets the mode")
|
|
check(GbcPalette.customRamp ~= nil, "applyOptions applied the saved palette")
|
|
eq(hex(GbcPalette.customRamp[1]), hex(Palette.ramp(id)[1]),
|
|
"and it's the right ramp")
|
|
|
|
GbcPalette.applyOptions({ color = "gbc", palette = "" })
|
|
check(GbcPalette.customRamp == nil,
|
|
"applyOptions with no palette clears the custom ramp")
|
|
end
|
|
|
|
-- ------- the COLOR row's real wiring: activate opens the picker
|
|
|
|
local OptionsMenu = require("src.ui.gen2.OptionsMenu")
|
|
|
|
local function rowNamed(rows, label)
|
|
for _, row in ipairs(rows) do
|
|
if row.label == label then return row end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
do
|
|
local colorRow = rowNamed(OptionsMenu.ROWS, "COLOR")
|
|
check(colorRow ~= nil, "COLOR is still a row")
|
|
check(colorRow.cycle == nil, "COLOR no longer cycles in place")
|
|
check(type(colorRow.activate) == "function",
|
|
"COLOR opens the picker instead")
|
|
|
|
GbcPalette.setCustomRamp(nil)
|
|
GbcPalette.setMode("classic")
|
|
|
|
local pushed
|
|
local game = {
|
|
options = { color = "classic", palette = "" },
|
|
stack = { states = {},
|
|
push = function(self, inst) pushed = inst end },
|
|
persistOptions = function() end,
|
|
}
|
|
|
|
colorRow.activate(game)
|
|
check(pushed ~= nil, "activate pushed a screen")
|
|
check(pushed.view == "root", "the pushed screen is a real PaletteScreen")
|
|
eq(game.options.color, "gbc",
|
|
"opening the picker while CLASSIC was active dropped it to GBC")
|
|
eq(GbcPalette.mode, "gbc", "and the live mode followed")
|
|
|
|
-- the root offers the engine's own GBC/DMG/CLASSIC ladder alongside the
|
|
-- 699-pack folders and MONOCHROME: "the original options" still work
|
|
local sawModes = {}
|
|
for _, row in ipairs(pushed.rows) do
|
|
if row.mode then sawModes[row.mode] = true end
|
|
end
|
|
check(sawModes.gbc and sawModes.dmg and sawModes.classic,
|
|
"GBC, DMG and CLASSIC are all still reachable from the picker")
|
|
|
|
local id = Palette.packId("BGB", "Blue")
|
|
pushed.set(id)
|
|
eq(game.options.palette, id, "storing a palette writes options.palette")
|
|
check(GbcPalette.customRamp ~= nil, "and GbcPalette.setCustomRamp actually ran")
|
|
eq(hex(GbcPalette.customRamp[1]), hex(Palette.ramp(id)[1]), "with the right ramp")
|
|
|
|
pushed.set("")
|
|
check(GbcPalette.customRamp == nil, "storing empty clears the custom ramp")
|
|
eq(game.options.color, "gbc",
|
|
"clearing a palette lands back on GEN 2, not whatever mode was active")
|
|
eq(GbcPalette.mode, "gbc", "and the live mode followed")
|
|
|
|
-- picking an engine mode through the picker still works and clears the
|
|
-- stored palette, exactly like Gen 1's picker
|
|
pushed.set(id)
|
|
pushed.setMode("dmg")
|
|
eq(game.options.color, "dmg", "setMode still writes options.color")
|
|
eq(GbcPalette.mode, "dmg", "and drives the live module")
|
|
|
|
GbcPalette.setCustomRamp(nil)
|
|
GbcPalette.setMode("gbc")
|
|
end
|
|
|
|
-- ------- GBC/GEN 2 relabel: GbcPalette.MODES keeps its id "gbc", but the
|
|
-- label the player sees for it moved to "GEN 2", freeing "GBC" up as
|
|
-- CUSTOM_MODE's own label, the state a stored palette actually lands on.
|
|
|
|
do
|
|
eq(GbcPalette.MODE_LABELS.gbc, "GEN 2",
|
|
"GEN 2 is the engine's own unique-colour mode's display name now")
|
|
eq(GbcPalette.MODE_LABELS[GbcPalette.CUSTOM_MODE], "GBC",
|
|
"GBC is the label for a stored custom palette's state")
|
|
check(not (function()
|
|
for _, id in ipairs(GbcPalette.MODES) do
|
|
if id == GbcPalette.CUSTOM_MODE then return true end
|
|
end
|
|
return false
|
|
end)(), "CUSTOM_MODE is deliberately not one of the root ladder's own modes")
|
|
end
|
|
|
|
-- ------- the bug this session's relabel fixes: picking a palette from a
|
|
-- non-GEN-2 mode used to strand the player there once the palette cleared,
|
|
-- because only CLASSIC ever got dropped back. Now ANY mode lands on
|
|
-- CUSTOM_MODE the moment a palette is picked, so clearing it always finds
|
|
-- its way back to GEN 2's own unique colours.
|
|
|
|
do
|
|
local OptionsMenu = require("src.ui.gen2.OptionsMenu")
|
|
local colorRow = nil
|
|
for _, r in ipairs(OptionsMenu.ROWS) do
|
|
if r.key == "color" then colorRow = r end
|
|
end
|
|
check(colorRow ~= nil, "found the COLOR row")
|
|
|
|
GbcPalette.setCustomRamp(nil)
|
|
GbcPalette.setMode("dmg")
|
|
|
|
local pushed
|
|
local game = {
|
|
options = { color = "dmg", palette = "" },
|
|
stack = { states = {}, push = function(self, inst) pushed = inst end },
|
|
persistOptions = function() end,
|
|
}
|
|
colorRow.activate(game)
|
|
|
|
-- opening the picker from DMG (not CLASSIC) doesn't touch the mode yet:
|
|
-- dropClassic only fires for CLASSIC, exactly as before.
|
|
eq(game.options.color, "dmg", "opening the picker from DMG leaves it alone")
|
|
|
|
local id = Palette.packId("BGB", "Blue")
|
|
pushed.set(id)
|
|
eq(game.options.color, GbcPalette.CUSTOM_MODE,
|
|
"picking a palette from DMG now lands on CUSTOM_MODE, not DMG")
|
|
eq(GbcPalette.mode, GbcPalette.CUSTOM_MODE, "and the live mode followed")
|
|
|
|
pushed.set("")
|
|
eq(game.options.color, "gbc",
|
|
"clearing it lands on GEN 2 (the bug: this used to stay on DMG, " ..
|
|
"with no selectable row left to get back to GEN 2's unique colours)")
|
|
eq(GbcPalette.mode, "gbc", "and the live mode followed")
|
|
|
|
GbcPalette.setCustomRamp(nil)
|
|
GbcPalette.setMode("gbc")
|
|
end
|
|
|
|
-- ------- TitleState's two baked art sets: GEN 2 and a picked custom
|
|
-- palette both want the colour set (there's no live recolour of this
|
|
-- screen's art either way); only DMG/CLASSIC want the grey set.
|
|
|
|
do
|
|
local TitleState = require("src.ui.gen2.TitleState")
|
|
GbcPalette.setMode("gbc")
|
|
check(not TitleState.gray(), "GEN 2 shows the colour art")
|
|
GbcPalette.setMode(GbcPalette.CUSTOM_MODE)
|
|
check(not TitleState.gray(), "a picked custom palette also shows the colour art")
|
|
GbcPalette.setMode("dmg")
|
|
check(TitleState.gray(), "DMG shows the grey art")
|
|
GbcPalette.setMode("classic")
|
|
check(TitleState.gray(), "CLASSIC shows the grey art (then the green present pass)")
|
|
GbcPalette.setMode("gbc")
|
|
end
|
|
|
|
-- ------- the "2" hotkey ladder (Game2:hotkey) and GbcPalette.cycle(): the
|
|
-- bug this session fixes. Unlike the picker's own row.mode branch (tested
|
|
-- above), this ladder used to change GbcPalette.mode/options.color without
|
|
-- touching customRamp or options.palette, so resolve() stayed locked onto
|
|
-- the old pack's colours no matter how many times "2" landed back on "gbc".
|
|
|
|
do
|
|
local Game2 = require("src.core.Game2")
|
|
local cartColors = { { 9, 9, 9 }, { 8, 8, 8 }, { 7, 7, 7 }, { 6, 6, 6 } }
|
|
|
|
GbcPalette.setCustomRamp(nil)
|
|
GbcPalette.setMode("gbc")
|
|
|
|
local id = Palette.packId("BGB", "Blue")
|
|
local ramp = Palette.ramp(id)
|
|
local game = {
|
|
options = { color = GbcPalette.CUSTOM_MODE, palette = id },
|
|
persistOptions = function() end,
|
|
}
|
|
GbcPalette.setMode(GbcPalette.CUSTOM_MODE)
|
|
GbcPalette.setCustomRamp(ramp)
|
|
|
|
-- cycle() isn't in GbcPalette.MODES so a custom-mode start is treated as
|
|
-- index 1: three "2" presses walk dmg -> classic -> gbc.
|
|
for _ = 1, 3 do Game2.hotkey(game, "2") end
|
|
|
|
eq(game.options.color, "gbc", "three presses land back on GEN 2's label")
|
|
eq(game.options.palette, "",
|
|
"BUG FIX: the hotkey ladder clears options.palette too, not just color")
|
|
check(GbcPalette.customRamp == nil,
|
|
"BUG FIX: GbcPalette.cycle() drops the live custom ramp")
|
|
eq(GbcPalette.resolve(cartColors), cartColors,
|
|
"BUG FIX: resolve() answers with the cart's own colours again, not " ..
|
|
"the stale custom ramp")
|
|
|
|
GbcPalette.setCustomRamp(nil)
|
|
GbcPalette.setMode("gbc")
|
|
end
|
|
|
|
T.finish("gen2 palette picker")
|