singe/testScripts/scene60.singe
2026-09-14 14:20:17 -05:00

148 lines
4.7 KiB
Text

-- The timeline (FORGE.md milestone 1): hitbox tracks keyed to disc frames, edited in Forge. The
-- cursor is stepped, keys are made at it, one is picked up off the canvas and dragged, one is
-- deleted, and the compiled game carries what was drawn. The description names its video, so the
-- editor has a frame to show under the cursor.
FORGE_LIBRARY = true
dofile("Forge/Forge.singe")
local font = fontLoad("Singe/FreeSansBold.ttf", 15)
local out = singeGetDataPath()
local work = out .. "timeline.game"
fontSelect(font)
fontQuality(FONT_QUALITY_BLENDED)
overlaySetResolution(720, 480)
local source = assert(io.open("testScripts/author/gunvideo.game", "r"))
local copy = assert(io.open(work, "w"))
copy:write(source:read("a"))
source:close()
copy:close()
if not forgeBegin(work) then
debugPrint("TIMELINE FAIL could not open " .. work)
singeQuit()
end
local frames = 0
local stage = 0
local function key(code, character)
forgeKey(character or 0, code.value)
end
local function step()
local track = forgeRoom().tracks[1]
if stage == 1 then
debugPrint("TIMELINE video loaded: " .. tostring(FORGE.video ~= nil) .. "; track '" .. track.name .. "' has " .. #track.boxes .. " keys")
key(SCANCODE.TAB)
key(SCANCODE.TAB)
key(SCANCODE.TAB)
if FORGE.mode ~= "tracks" then
debugPrint("TIMELINE FAIL three tabs did not reach the tracks: " .. FORGE.mode)
end
elseif stage == 2 then
-- Step and leap the cursor to frame 170, halfway between the bandit's two keys.
for _ = 1, 17 do
key(SCANCODE.RIGHTBRACKET)
end
local box = forgeCursorBox()
debugPrint(string.format("TIMELINE cursor at %d, the bandit box is at x=%.0f (halfway from 100 to 400)", FORGE.cursor, box.x))
if math.abs(box.x - 250) > 1 then
debugPrint("TIMELINE FAIL interpolation at the cursor")
end
elseif stage == 3 then
-- A key at the cursor takes the interpolated box, and the list stays sorted.
key(SCANCODE.K)
if #track.boxes == 3 and track.boxes[2].at == 170 and track.boxes[2].x == 250 then
debugPrint("TIMELINE a key at 170 went in between the two, at x=250")
else
debugPrint("TIMELINE FAIL after K the track has " .. #track.boxes .. " keys; second at " .. tostring(track.boxes[2] and track.boxes[2].at))
end
elseif stage == 4 then
-- Pick the box up off the canvas and drag it, the way a pointer would.
local box = forgeCursorBox()
forgePress(box.x + 5, box.y + 5)
forgeDrag(box.x + 65, box.y + 25)
forgeRelease()
if track.boxes[2].x == 310 and track.boxes[2].y == 220 then
debugPrint("TIMELINE dragged the key to " .. track.boxes[2].x .. "," .. track.boxes[2].y)
else
debugPrint("TIMELINE FAIL the drag left the key at " .. tostring(track.boxes[2].x) .. "," .. tostring(track.boxes[2].y))
end
elseif stage == 5 then
-- Type the key's height, then step back a frame: the box between keys follows the new one.
key(SCANCODE.RETURN) -- at
key(SCANCODE.RETURN) -- x
key(SCANCODE.RETURN) -- y
key(SCANCODE.RETURN) -- w
key(SCANCODE.RETURN) -- h
for c in string.gmatch("40", ".") do
key(SCANCODE.A, string.byte(c))
end
key(SCANCODE.RETURN)
key(SCANCODE.ESCAPE)
key(SCANCODE.COMMA)
local box = forgeCursorBox()
debugPrint(string.format("TIMELINE key height typed to %d; at frame %d the box is %.0f tall", track.boxes[2].h, FORGE.cursor, box.h))
elseif stage == 6 then
-- Undo the typing and the drag, then delete the key. Undo puts a copy of the description
-- in place, so the track is looked up again afterwards.
key(SCANCODE.U)
key(SCANCODE.U)
track = forgeRoom().tracks[1]
if track.boxes[2].x ~= 250 then
debugPrint("TIMELINE FAIL undo did not bring the key back to x=250: " .. tostring(track.boxes[2].x))
end
FORGE.key = 2
key(SCANCODE.DELETE)
debugPrint("TIMELINE after two undos and a delete the track has " .. #track.boxes .. " keys")
elseif stage == 7 then
-- And a new key in a new track reaches the compiled game.
key(SCANCODE.N)
key(SCANCODE.K)
key(SCANCODE.S)
local built = forgeBuild(out .. "timeline.singe")
local text = assert(io.open(built, "r")):read("a")
if text:find('name = "track3"') and text:find("at = " .. FORGE.cursor) then
debugPrint("TIMELINE the compiled game carries the new track and its key")
else
debugPrint("TIMELINE FAIL the new track is missing from the compiled game")
end
debugPrint("TIMELINE RESULT done")
end
end
function onOverlayUpdate()
frames = frames + 1
if frames % 14 == 0 and stage < 8 then
stage = stage + 1
step()
end
forgeDraw(nil, nil)
colorForeground(255, 255, 255, 255)
fontPrint(210, 8, "timeline, stage " .. stage)
if frames == 44 or frames == 72 or frames == 100 then
singeScreenshot()
end
if frames > 130 then
singeQuit()
end
return OVERLAY_UPDATED
end