mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-22 13:36:14 +02:00
skins
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
-- Screen-rect check for a touch skin, both generations.
|
||||
--
|
||||
-- POKEPORT_DRIVER=tests/drivers/skin_screen_shot.lua love .
|
||||
-- POKEPORT_GAME=gold POKEPORT_SKIN=my_skin POKEPORT_DRIVER=... love .
|
||||
--
|
||||
-- Gold's cache lives under the DEFAULT save identity, so a POKEPORT_IDENTITY
|
||||
-- sandbox has to be seeded with it first or the boot hangs in the importer:
|
||||
-- cp -R ~/Library/Application\ Support/LOVE/pokemon-love2d/{gold,skins} \
|
||||
-- ~/Library/Application\ Support/LOVE/<identity>/
|
||||
local U = require("tests.drivers.util")
|
||||
local GameVersion = require("src.core.GameVersion")
|
||||
|
||||
local function env(name, fallback)
|
||||
local v = os.getenv(name)
|
||||
if v == nil or v == "" then return fallback end
|
||||
return v
|
||||
end
|
||||
|
||||
local function tap(game, button)
|
||||
game.input.pressQueue[#game.input.pressQueue + 1] = button
|
||||
game.input.state[button] = true
|
||||
U.wait(2)
|
||||
game.input.state[button] = false
|
||||
end
|
||||
|
||||
return function(game)
|
||||
local TouchControls = require("src.core.TouchControls")
|
||||
local out = env("POKEPORT_SHOT_DIR", ".")
|
||||
local gen2 = GameVersion.generation() == 2
|
||||
|
||||
love.window.setMode(tonumber(env("POKEPORT_SHOT_W", 460)),
|
||||
tonumber(env("POKEPORT_SHOT_H", 950)))
|
||||
local skin = env("POKEPORT_SKIN", "gb_anim")
|
||||
local ok, err = TouchControls:selectSkin(skin)
|
||||
assert(ok, "skin " .. skin .. ": " .. tostring(err))
|
||||
|
||||
U.wait(60)
|
||||
if gen2 then
|
||||
local A = require("tests.drivers.gold.adapter")
|
||||
assert(game.world and game.world.map, "gold world did not boot")
|
||||
A.teleport(game, env("POKEPORT_SHOT_MAP", "NEW_BARK_TOWN"), 6, 6)
|
||||
U.wait(120)
|
||||
else
|
||||
local Pokemon = require("src.pokemon.Pokemon")
|
||||
game.save.party = { Pokemon.new(game.data, "CHARIZARD", 50) }
|
||||
U.teleport(game, env("POKEPORT_SHOT_MAP", "PALLET_TOWN"), 10, 8, "down")
|
||||
U.wait(40)
|
||||
end
|
||||
U.shot(game, out .. "/skin_world.png")
|
||||
|
||||
tap(game, "start")
|
||||
U.wait(60)
|
||||
U.shot(game, out .. "/skin_menu.png")
|
||||
|
||||
love.event.quit()
|
||||
while true do coroutine.yield() end
|
||||
end
|
||||
@@ -316,6 +316,8 @@ check(view:find('"tab-sync"', 1, true) ~= nil,
|
||||
local header = view:match("local HEADER_TABS = %{(.-)%}\n")
|
||||
check(header and header:find('id = "skins"', 1, true) ~= nil,
|
||||
"and it sits beside the skins tab")
|
||||
check(header and header:find("beta = true", 1, true) ~= nil,
|
||||
"the skins tab carries a BETA badge too")
|
||||
check(view:find('"BETA"', 1, true) ~= nil,
|
||||
"the button and the modal are labelled BETA")
|
||||
check(view:find("buildSyncModal", 1, true) ~= nil,
|
||||
|
||||
@@ -111,6 +111,25 @@ check(Studio.page().viewport ~= nil, "the SGB cutout cannot be toggled off")
|
||||
Studio.setCanvas(#Studio.CANVASES + 1)
|
||||
eq(Studio.canvasIndex, 1, "canvas selection wraps")
|
||||
|
||||
-- the preview must lay the page out the way the game will, so a preset never
|
||||
-- overwrites the aspect the bezel art (or a cfg) already fixed
|
||||
session()
|
||||
local art = Studio.page()
|
||||
art.aspect, art.aspectFromImage = 0.5625, true
|
||||
Studio.setCanvas(1)
|
||||
near(art.aspect, 0.5625, 1e-9, "bezel art keeps its own aspect on a preset switch")
|
||||
local deckW, deckH = 900, 1700
|
||||
local _, dby, _, dbh = TouchSkin.pageBox(art, deckW, deckH)
|
||||
check(dby > 0 and math.abs(dby + dbh - deckH) < 1e-6,
|
||||
"so a preset taller than the art pins the deck low, as gameplay does")
|
||||
|
||||
session()
|
||||
local plain = Studio.page()
|
||||
plain.aspect, plain.aspectFromImage, plain.aspectFromCfg = nil, nil, nil
|
||||
Studio.setCanvas(1)
|
||||
near(plain.aspect, Studio.canvas().w / Studio.canvas().h, 1e-9,
|
||||
"a page with no art of its own still takes the preset's aspect")
|
||||
|
||||
Studio.setCanvas(1)
|
||||
Studio.viewZoom = 1
|
||||
local cx, cy, cw, ch = Studio.canvasRect(0, 0, 800, 600)
|
||||
|
||||
@@ -136,11 +136,16 @@ for off = lo, hi do
|
||||
end
|
||||
Zoom.offset = 0
|
||||
|
||||
local capped = select(1, Renderer:worldViewSize())
|
||||
useSkin("0.25,0.1,0.5,0.6", "overlay0_viewport_expand = true")
|
||||
local expanded = select(1, Renderer:worldViewSize())
|
||||
check(expanded > capped,
|
||||
"viewport_expand lets the survey world fill the cutout instead of the GB box")
|
||||
useSkin("0.25,0.1,0.3,0.8")
|
||||
local tallR = Renderer:frameRects()
|
||||
local tallVw, tallVh = Renderer:worldViewSize()
|
||||
local tallSp = Zoom.scale(tallR.Sp)
|
||||
check(tallVw * tallSp >= tallR.vuw and tallVh * tallSp >= tallR.vuh,
|
||||
"the world pass covers the whole cutout, not just the GB box inside it")
|
||||
check(tallVh * tallSp > tallR.uvph,
|
||||
"so a cutout taller than 160x144 shows map where the UI letterbox ends")
|
||||
check(tallR.uvph < tallR.vuh and tallR.uvpw <= tallR.vuw,
|
||||
"while the UI keeps its whole-pixel letterbox inside that cutout")
|
||||
useSkin("0.25,0.1,0.5,0.6")
|
||||
|
||||
setWindow(480, 800)
|
||||
@@ -159,22 +164,14 @@ setWindow(1280, 720)
|
||||
useSkin("0.25,0.1,0.5,0.6")
|
||||
local px, py, pw, ph, active = Playfield.rect(1280, 720)
|
||||
eq(active, true, "Gold sees the cutout too")
|
||||
eq(pw, 480, "the playfield is a whole multiple of 160")
|
||||
eq(ph, 432, "and of 144")
|
||||
check(inside(px, py, pw, ph, 320, 72, 640, 432),
|
||||
"centred inside the cutout")
|
||||
eq(Chrome.fitScale(1280, 720), 3, "Chrome fits the playfield")
|
||||
eq(px, 320, "the playfield is the cutout, at its origin")
|
||||
eq(py, 72, "on both axes")
|
||||
eq(pw, 640, "with its full width")
|
||||
eq(ph, 432, "and its full height")
|
||||
eq(Chrome.fitScale(1280, 720), 3, "Chrome fits whole GB pixels in it")
|
||||
local cox, coy = Chrome.fitOrigin(1280, 720)
|
||||
eq(cox, px, "and centres the panel on it")
|
||||
eq(coy, py, "on both axes")
|
||||
|
||||
useSkin("0.25,0.1,0.5,0.6", "overlay0_viewport_expand = true")
|
||||
local ex, ey, ew, eh = Playfield.rect(1280, 720)
|
||||
eq(ew, 640, "expand hands the picture the full cutout width")
|
||||
eq(eh, 432, "and its full height")
|
||||
eq(ex, 320, "at the cutout origin")
|
||||
eq(ey, 72, "on both axes")
|
||||
useSkin("0.25,0.1,0.5,0.6")
|
||||
eq(cox, 320 + 80, "and centres the panel on the cutout")
|
||||
eq(coy, 72, "on both axes")
|
||||
|
||||
local ew2, eh2, ex2, ey2, act2 = Playfield.push(1280, 720)
|
||||
eq(act2, true, "push reports the frame is contained")
|
||||
@@ -184,12 +181,29 @@ eq(ew2, pw, "and hands the scene the playfield size")
|
||||
eq(Playfield.cutout(ew2, eh2), nil, "inside the frame there is no cutout left")
|
||||
eq(select(3, Playfield.rect(ew2, eh2)), pw, "so the playfield is the surface")
|
||||
eq(Chrome.fitScale(ew2, eh2), 3, "and Chrome fits it without re-applying")
|
||||
eq(select(1, Chrome.fitOrigin(ew2, eh2)), 0, "at a local origin")
|
||||
eq(select(1, Chrome.fitOrigin(ew2, eh2)), 80, "centred on that surface alone")
|
||||
eq(select(1, Playfield.dimensions()), pw, "screens read the playfield as the display")
|
||||
Playfield.pop()
|
||||
eq(Playfield.entered, false, "pop leaves the frame")
|
||||
eq(select(1, Playfield.cutout(1280, 720)), 320, "and the cutout is visible again")
|
||||
|
||||
setWindow(960, 1901)
|
||||
useSkin("0,0,1,0.5", "overlay0_aspect_ratio = 0.5625")
|
||||
local deck = TouchSkin.page()
|
||||
local _, dy, _, dh = TouchSkin.pageBox(deck, 960, 1901)
|
||||
check(dy > 0 and math.abs(dy + dh - 1901) < 1,
|
||||
"a portrait deck taller than the display pins to the lower edge")
|
||||
local hx, hy, hw, hh = Playfield.cutout(960, 1901)
|
||||
eq(hy, 0, "and the screen rect it left flush takes the room above it")
|
||||
eq(hx, 0, "without moving sideways")
|
||||
eq(hw, 960, "or changing width")
|
||||
eq(hh, math.floor(dy + dh * 0.5), "growing by exactly the headroom")
|
||||
|
||||
useSkin("0,0.1,1,0.5", "overlay0_aspect_ratio = 0.5625")
|
||||
check(select(2, Playfield.cutout(960, 1901)) > dy,
|
||||
"a screen rect the author inset from the top keeps that bezel margin")
|
||||
|
||||
setWindow(1280, 720)
|
||||
useSkin("0.4,0.4,0.1,0.1")
|
||||
local sx, sy, sw, sh = Playfield.rect(1280, 720)
|
||||
check(inside(sx, sy, sw, sh, 512, 288, 128, 72),
|
||||
|
||||
Reference in New Issue
Block a user