-- A KarisFramework game as it ships, driven by karisDrive.singe and traced. PORT_GAME names -- the game's directory in the library and PORT_SCRIPT its main script; run with -v the video -- its games.dat names. local here = ((debug.getinfo(1, "S").source:gsub("^@", "")):match("^(.*[/\\])") or "") local library = os.getenv("SINGE_LIBRARY") or (os.getenv("HOME") .. "/claude/singetest/ported") local game = os.getenv("PORT_GAME") or "TimeGal" local script = library .. "/" .. game .. "/" .. (os.getenv("PORT_SCRIPT") or "Timegal.singe") dofile(here .. "karisDrive.singe") -- What its launcher entry and the engine would have given it, and a seed both runs share. SINGE_LEGACY_SPRITE_ARGS = true local realTime = os.time os.time = function(...) return KARIS_SEED end local realScriptPath = singeGetScriptPath singeGetScriptPath = function() return script end local realSkip = discSkipToFrame discSkipToFrame = function(frame) karisTraceSeek(frame) return realSkip(frame) end dofile(script) singeGetScriptPath = realScriptPath local realUpdate = onOverlayUpdate local frames = 0 function karisPress(switch, down) if down then onInputPressed(switch) else onInputReleased(switch) end end function karisMouse(x, y) if onMouseMoved then onMouseMoved(x, y, 0, 0, 0) end end local function view() local m = move and move[currentMove or 0] or nil local window = nil local chosen = nil -- A Kimmy game (acombo is its own) hands over the sequences and branches of the move too; -- a map-mode game (segment is its own) says so, for its own numbering of the kinds. local kimmy = (acombo ~= nil) local timegal = (STAGEMAX ~= nil) local rdg = ((segment ~= nil) or timegal) and (acombo == nil) if timegal then -- Time Gal's row: clip start, window start, window end, clip end, death clip, kind. if (currentLevel == levelNormal) and m and (m[2] ~= nil) then window = { from = m[2], to = m[3], kind = m[7], death = 0, alt = 0, alt2 = 0 } end elseif (currentLevel == levelNormal) and m and (m[1] ~= nil) then window = { from = m[1], to = m[2], kind = m[3], death = m[4], alt = m[5], alt2 = m[6] } end -- A map-mode shot: a down action whose row carries a zone, and the game's pointer ratios. local zone = (m and (m[3] == ACTDOWN) and (m[7] ~= nil)) and { m[7], m[8], m[9], m[10] } or nil local mouse = ratiox and { ratiox, ratioy, ratioxOffset, ratioyOffset } or nil -- The pair kinds by the game's own numbers (Super Don Quixote numbers them as Karis does). local pairs = nil if rdg and ACTUP then pairs = { [ACTUP] = { 5, 1 }, [ACTDOWN] = { 5, 2 }, [ACTLEFT] = { 5, 3 }, [ACTRIGHT] = { 5, 4 }, [UPLEFT] = { 1, 3 }, [UPRIGHT] = { 1, 4 }, [DOWNLEFT] = { 2, 3 }, [DOWNRIGHT] = { 2, 4 } } end -- A choice: the framework's at branch10, the later map-mode copies' at branch02. if ((lvlState == branch10) or (rdg and (lvlState == branch02))) and choice then chosen = {} for index, c in ipairs(choice) do chosen[index] = { right = c[2] } end end if timegal and (lvlState == branch03) and opt then chosen = {} for index, c in ipairs(opt) do chosen[index] = { right = c[2] } end end return { screen = currentLevel, step = lvlState, level = iLevel or iCurPos or iStageIndex, scene = iScene or iSegPointer, move = currentMove, frame = discGetFrame(), frames = frames, score = iScore, lives = iLives, window = window, choices = chosen, order = optorder, choice = iChoice, kimmy = kimmy, rdg = rdg, timegal = timegal, multi = kimmy and multi and multi[currentMove] or nil, path = kimmy and path and path[currentMove] or nil, timed = kimmy and timed or nil, freeplay = (dip_CoinsPerCredit == DOPT_FREEPLAY), credits = iCredits, zone = zone, mouse = mouse, pairs = pairs, mashKind = rdg and MASH or nil } end function onOverlayUpdate() frames = frames + 1 if gameflow == flow_GameRunning then karisDrive(view()) end local r = realUpdate() if (frames > 100) and karisDone(view()) or (frames > KARIS_FRAMES) then debugPrint("TRACE end after " .. frames .. " frames") singeQuit() end return r end