nonogamer9

Timeless by Tran OpenComputers Port

Oct 6th, 2026
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 121.64 KB | Source Code | 0 0
  1. local component = component or require("component")
  2. local computer  = computer  or require("computer")
  3. local args = {...}
  4.  
  5. local byte, char, rep, sub = string.byte, string.char, string.rep, string.sub
  6. local floor = math.floor
  7. local unpack = table.unpack
  8.  
  9.  
  10.  
  11.  
  12. local OPT = {loops = 0, skipend = false, nobuf = false, nojerk = false, maxsteps = 8}
  13. do
  14.   local i = 1
  15.   while i <= #args do
  16.     local a = args[i]
  17.     if a == "-l" then i = i + 1; OPT.loops = tonumber(args[i]) or 0
  18.     elseif a == "-e" then OPT.skipend = true
  19.     elseif a == "-d" then OPT.nobuf = true
  20.     elseif a == "-j" then OPT.nojerk = true
  21.     elseif a == "-s" then i = i + 1; OPT.maxsteps = tonumber(args[i]) or 8
  22.     elseif a == "-h" or a == "--help" or a == "/?" then
  23.       print("Timeless (OpenComputers port of the 1994 demo by Tran)")
  24.       print("usage: timeless [-l N] [-e] [-d] [-j] [-s N]")
  25.       print("  -l N loops, -e skip end picture, -d no GPU buffers,")
  26.       print("  -j no jerky, -s N max logic steps per frame; ESC/Q quits""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  27.   local map = {}
  28.   for i = 1, 64 do map[byte(al, i)] = i - 1 end
  29.   s = s:gsub("[^%w%+/]", "") .. "AAA"
  30.   return (s:gsub("(.)(.)(.)(.)", function(a, b, c, d)
  31.     local v = (map[byte(a)] << 18) | (map[byte(b)] << 12) | (map[byte(c)] << 6) | map[byte(d)]
  32.     return char(v >> 16, (v >> 8) & 255, v & 255)
  33.   end))
  34. end
  35.  
  36. local function unlzss(c, n)
  37.   local parts, np = {}, 0
  38.   local o, k, total, i = {}, 0, 0, 1
  39.   while total < n do
  40.     local f = byte(c, i); i = i + 1
  41.     for b = 0, 7 do
  42.       if total >= n then break end
  43.       if f & (1 << b) ~= 0 then
  44.         k = k + 1; o[k] = byte(c, i); i = i + 1; total = total + 1
  45.       else
  46.         local lo, hi = byte(c, i, i + 1); i = i + 2
  47.         local off = lo | ((hi >> 4) << 8)
  48.         local len = (hi & 15) + 3
  49.         for _ = 1, len do k = k + 1; o[k] = o[k - off] end
  50.         total = total + len
  51.       end
  52.     end
  53.     if k >= 8192 then
  54.       np = np + 1; parts[np] = char(unpack(o, 1, 4096))
  55.       table.move(o, 4097, k, 1); k = k - 4096
  56.     end
  57.   end
  58.   np = np + 1; parts[np] = char(unpack(o, 1, k))
  59.   return sub(table.concat(parts), 1, n)
  60. end
  61.  
  62. local BLOB = unlzss(b64decode(PACK), PACKLEN)
  63. PACK = nil
  64. local function sec(name) local s = SEC[name]; return sub(BLOB, s[1] + 1, s[1] + s[2]) end
  65.  
  66. local TILES = sec("tiles")
  67. local SCT   = sec("sctbl")
  68. local SPRS  = sec("sprites")
  69. local LS    = sec("lensshape")
  70. local LSRC  = sec("lenssrc")
  71. local PALS  = sec("pals")
  72. local PAL0A = sec("pal0a")
  73. local ENDP  = sec("endpic")
  74. local RAYSTR = sec("rays")
  75.  
  76. local SIN0, SIN0S, L2TBL = {}, {}, {}
  77. do
  78.   local s = sec("sincos")
  79.   for i = 0, 255 do
  80.     SIN0[i] = byte(s, i + 1)
  81.     local v = byte(s, 257 + i); if v > 127 then v = v - 256 end
  82.     SIN0S[i] = v
  83.   end
  84.   local t = sec("l2tbl")
  85.   for i = 0, 255 do L2TBL[i] = byte(t, i + 1) end
  86. end
  87.  
  88.  
  89. local SPRO = {}
  90. do
  91.   local ls = sec("sprlens")
  92.   local p = 1
  93.   for id = 0, 34 do
  94.     SPRO[id] = p
  95.     p = p + byte(ls, id * 2 + 1) + (byte(ls, id * 2 + 2) << 8)
  96.   end
  97. end
  98.  
  99.  
  100.  
  101.  
  102. local cpal = {}
  103. for i = 0, 767 do cpal[i] = 0 end
  104. local ZERO = {}
  105. for i = 0, 767 do ZERO[i] = 0 end
  106. local slide = nil
  107. local pal_dirty = true
  108.  
  109.  
  110. local function getpal(h, first, count)
  111.   local pos = (h < 10) and h or (h - 1)
  112.   local base = pos * 381 + first * 3
  113.   local t = {}
  114.   for i = 0, count * 3 - 1 do
  115.     local idx = first * 3 + i
  116.     t[i] = (idx < 381) and byte(PALS, pos * 381 + idx + 1) or 0
  117.   end
  118.   return t
  119. end
  120. local function getpal0a(set)
  121.   local t = {}
  122.   for i = 0, 191 do t[i] = byte(PAL0A, set * 192 + i + 1) end
  123.   return t
  124. end
  125.  
  126. local function pal_set(idx, len, tgt)
  127.   for i = 0, len * 3 - 1 do cpal[idx * 3 + i] = tgt[i] end
  128.   pal_dirty = true
  129. end
  130. local function pal_slide(idx, len, tgt)
  131.   slide = {idx = idx, len = len, t = tgt}
  132. end
  133. local function slide_tick()
  134.   local s = slide
  135.   if not s then return end
  136.   local fast = (s.len - 1) >= 128
  137.   local changed = false
  138.   local base, t = s.idx * 3, s.t
  139.   for i = 0, s.len * 3 - 1 do
  140.     local cur = cpal[base + i]
  141.     local d = (cur - t[i]) & 255
  142.     if d ~= 0 then
  143.       changed = true
  144.       local dl
  145.       if fast then
  146.         if d == 1 then dl = -1 elseif d < 128 then dl = -2
  147.         elseif d == 255 then dl = 1 else dl = 2 end
  148.       else
  149.         dl = (d < 128) and -1 or 1
  150.       end
  151.       cpal[base + i] = (cur + dl) & 255
  152.     end
  153.   end
  154.   if changed then pal_dirty = true else slide = nil end
  155. end
  156.  
  157.  
  158.  
  159.  
  160. local gpu
  161. do
  162.   local addr = component.list("gpu")()
  163.   if not addr then error("no graphics card") end
  164.   gpu = component.proxy(addr)
  165.   if not gpu.getScreen() then
  166.     local s = component.list("screen")()
  167.     if s then gpu.bind(s) end
  168.   end
  169. end
  170.  
  171. local old_w, old_h = gpu.getResolution()
  172. local old_depth = gpu.getDepth and gpu.getDepth() or 8
  173. local old_fg, old_bg = gpu.getForeground(), gpu.getBackground()
  174. local max_w, max_h = gpu.maxResolution()
  175. local WC, HC = math.min(160, max_w), math.min(50, max_h)
  176. gpu.setResolution(WC, HC)
  177. WC, HC = gpu.getResolution()
  178. if gpu.maxDepth and gpu.maxDepth() >= 8 then gpu.setDepth(8) end
  179.  
  180. local W, H = WC, HC * 2          
  181. local HS = H // 2                
  182. local scr = {}                  
  183. for i = 1, W * H do scr[i] = 0 end
  184.  
  185. local vram = nil                
  186. if gpu.allocateBuffer and not OPT.nobuf then
  187.   local ok, id = pcall(gpu.allocateBuffer, WC, HC)
  188.   if ok and id then vram = id end
  189. end
  190.  
  191. local HALF = "\u{2580}"
  192. local SP, HB = {}, {}
  193. local function spaces(n) local s = SP[n]; if not s then s = rep(" ", n); SP[n] = s end; return s end
  194. local function halves(n) local s = HB[n]; if not s then s = rep(HALF, n); HB[n] = s end; return s end
  195.  
  196.  
  197. local RL = {[0] = 0, 51, 102, 153, 204, 255}
  198. local GL = {[0] = 0, 36, 73, 109, 146, 182, 219, 255}
  199. local BL = {[0] = 0, 63, 127, 191, 255}
  200. local function nearest(levels, n, v)
  201.   local best, bd = 0, 1e9
  202.   for i = 0, n do
  203.     local d = (levels[i] - v); d = d * d
  204.     if d < bd then bd = d; best = i end
  205.   end
  206.   return levels[best]
  207. end
  208. local function quant(r, g, b)
  209.   local qr, qg, qb = nearest(RL, 5, r), nearest(GL, 7, g), nearest(BL, 4, b)
  210.   local e1 = (qr - r) ^ 2 + (qg - g) ^ 2 + (qb - b) ^ 2
  211.   local gv = (r + g + b) // 3
  212.   local gi = floor(gv * 17 / 255 + 0.5) - 1
  213.   if gi < 0 then gi = 0 elseif gi > 15 then gi = 15 end
  214.   local gq = (gi + 1) * 255 // 17
  215.   local e2 = (gq - r) ^ 2 + (gq - g) ^ 2 + (gq - b) ^ 2
  216.   if e2 < e1 then return (gq << 16) | (gq << 8) | gq end
  217.   return (qr << 16) | (qg << 8) | qb
  218. end
  219.  
  220. local rgb = {}
  221. for i = 0, 255 do rgb[i] = 0 end
  222. local fade = 1.0
  223. local function update_rgb()
  224.   if not pal_dirty then return end
  225.   pal_dirty = false
  226.   for i = 0, 255 do
  227.     local r, g, b = cpal[i * 3], cpal[i * 3 + 1], cpal[i * 3 + 2]
  228.     rgb[i] = quant(r * 255 // 63, g * 255 // 63, b * 255 // 63)
  229.   end
  230. end
  231.  
  232. local direct_prev_t, direct_prev_b = nil, nil
  233. local function target_begin()
  234.   if vram then gpu.setActiveBuffer(vram) end
  235. end
  236. local function target_end()
  237.   if vram then
  238.     gpu.setActiveBuffer(0)
  239.     gpu.bitblt(0, 1, 1, WC, HC, vram, 1, 1)
  240.   end
  241. end
  242.  
  243.  
  244. local function present()
  245.   update_rgb()
  246.   local setfg, setbg, set = gpu.setForeground, gpu.setBackground, gpu.set
  247.   local fgc, bgc = -1, -1
  248.   local direct = not vram
  249.   if direct and not direct_prev_t then
  250.     direct_prev_t, direct_prev_b = {}, {}
  251.     for i = 1, W * HC do direct_prev_t[i] = -1; direct_prev_b[i] = -1 end
  252.   end
  253.   target_begin()
  254.   for cy = 0, HC - 1 do
  255.     local r0 = cy * 2 * W
  256.     local r1 = r0 + W
  257.     local cx = 1
  258.     while cx <= W do
  259.       local t, b = rgb[scr[r0 + cx]], rgb[scr[r1 + cx]]
  260.       local e = cx
  261.       while e < W and rgb[scr[r0 + e + 1]] == t and rgb[scr[r1 + e + 1]] == b do e = e + 1 end
  262.       local draw = true
  263.       if direct then
  264.         draw = false
  265.         local pb = cy * W
  266.         for q = cx, e do
  267.           if direct_prev_t[pb + q] ~= t or direct_prev_b[pb + q] ~= b then draw = true end
  268.           direct_prev_t[pb + q] = t; direct_prev_b[pb + q] = b
  269.         end
  270.       end
  271.       if draw then
  272.         local n = e - cx + 1
  273.         if t == b then
  274.           if bgc ~= t then setbg(t); bgc = t end
  275.           set(cx, cy + 1, spaces(n))
  276.         else
  277.           if fgc ~= t then setfg(t); fgc = t end
  278.           if bgc ~= b then setbg(b); bgc = b end
  279.           set(cx, cy + 1, halves(n))
  280.         end
  281.       end
  282.       cx = e + 1
  283.     end
  284.   end
  285.   target_end()
  286. end
  287.  
  288. local function gpu_restore()
  289.   if vram then
  290.     pcall(gpu.setActiveBuffer, 0)
  291.     pcall(gpu.freeBuffer, vram)
  292.     vram = nil
  293.   end
  294.   pcall(gpu.setResolution, old_w, old_h)
  295.   pcall(gpu.setForeground, old_fg)
  296.   pcall(gpu.setBackground, old_bg)
  297.   pcall(gpu.fill, 1, 1, old_w, old_h, " ")
  298. end
  299.  
  300.  
  301.  
  302.  
  303. local buf = {}
  304. for i = 1, 8192 do buf[i] = 0 end
  305. local function bput(a, v)
  306.   a = a & 0xFFFF
  307.   local i, s = (a >> 3) + 1, (a & 7) << 3
  308.   buf[i] = (buf[i] & ~(0xFF << s)) | (v << s)
  309. end
  310. local function bget(a)
  311.   a = a & 0xFFFF
  312.   return (buf[(a >> 3) + 1] >> ((a & 7) << 3)) & 0xFF
  313. end
  314. local function bfill(a, n, v)
  315.   a = a & 0xFFFF
  316.   while n > 0 do
  317.     if a & 7 == 0 and n >= 8 then
  318.       local w = v * 0x0101010101010101
  319.       local cnt = n >> 3
  320.       local maxc = (0x10000 - a) >> 3
  321.       if cnt > maxc then cnt = maxc end
  322.       local i = (a >> 3) + 1
  323.       for q = i, i + cnt - 1 do buf[q] = w end
  324.       a = (a + cnt * 8) & 0xFFFF; n = n - cnt * 8
  325.     else
  326.       bput(a, v); a = (a + 1) & 0xFFFF; n = n - 1
  327.     end
  328.   end
  329. end
  330.  
  331. local function rol16(x, n) x = x & 0xFFFF; return ((x << n) | (x >> (16 - n))) & 0xFFFF end
  332. local function rol32(x, n) x = x & 0xFFFFFFFF; return ((x << n) | (x >> (32 - n))) & 0xFFFFFFFF end
  333. local function ror32(x, n) x = x & 0xFFFFFFFF; return ((x >> n) | (x << (32 - n))) & 0xFFFFFFFF end
  334.  
  335.  
  336. local DRAWING = true      
  337. local ending = false
  338. local l1on, l2on = false, false
  339. local loopcount = OPT.loops
  340. local finish_req = false
  341.  
  342.  
  343.  
  344.  
  345. local XT = {}
  346. local function sc_tobuf(tile, bl, bh, loc)
  347.   local tb = tile * 1024
  348.   local no = bl * (bl + 1) // 2
  349.   local nx = bl + 1
  350.   local c = 0
  351.   for k = 1, nx do c = c + byte(SCT, no + k); XT[k] = c + 1 end
  352.   local yo = bh * (bh + 1) // 2
  353.   local r = 0
  354.   local lx, ly = loc & 255, (loc >> 8) & 255
  355.   for i = 1, bh + 1 do
  356.     r = r + byte(SCT, yo + i)
  357.     local rb = tb + r * 32
  358.     local dst = (((ly + i - 1) & 255) << 8) + lx
  359.     for k = 1, nx do
  360.       local v = byte(TILES, rb + XT[k])
  361.       if v ~= 0 then
  362.         local a = (dst + k - 1) & 0xFFFF
  363.         local q, s = (a >> 3) + 1, (a & 7) << 3
  364.         buf[q] = (buf[q] & ~(0xFF << s)) | (v << s)
  365.       end
  366.     end
  367.   end
  368. end
  369.  
  370. local l0rout
  371. do
  372.  
  373.  
  374.  
  375. local routtbl, ROUTTBLLEN, ROUTTBLSTART
  376. local routtblindex = 0
  377. local delaycntr = 0
  378. local palindex = 0
  379. local pal0aptr = 0
  380. local palptrtbl = {0x02, 0x00, 0x01, 0x06, 0x09, 0x01, 0x07, 0x04, 0x03,
  381.                    0x05, 0x0e, 0x0d, 0x0c, 0x0b, 0x03,
  382.                    0x01, 0x0f, 0x10, 0x04, 0x08, 0x0b}  
  383. local PALTBLLEN = 21
  384.  
  385. local function setnext0()
  386.   local i = routtblindex + 1
  387.   if i >= ROUTTBLLEN then
  388.     if loopcount > 0 then
  389.       loopcount = loopcount - 1
  390.       if loopcount == 0 then finish_req = true end
  391.     end
  392.     pal0aptr = (pal0aptr + 1) % 6
  393.     i = ROUTTBLSTART
  394.   end
  395.   l0rout = routtbl[i + 1]
  396.   routtblindex = i
  397. end
  398.  
  399.  
  400. local function nextpal_idx()
  401.   palindex = palindex + 1
  402.   if palindex >= PALTBLLEN then palindex = 0 end
  403.   return palptrtbl[palindex + 1]
  404. end
  405. local function palnext(bank)
  406.   if ending then return true end
  407.   pal_set(bank * 64, 64, getpal(nextpal_idx(), 0, 64))
  408.   return false
  409. end
  410. local function palnexts(bank)
  411.   if ending then return true end
  412.   pal_slide(bank * 64, 64, getpal(nextpal_idx(), 0, 64))
  413.   return false
  414. end
  415. local function set_palso(idx, len, tgt)
  416.   if ending then return true end
  417.   pal_slide(idx, len, tgt); return false
  418. end
  419. local function set_palo(idx, len, tgt)
  420.   if ending then return true end
  421.   pal_set(idx, len, tgt); return false
  422. end
  423.  
  424.  
  425. local d0loc, d0locd, d0color, d0counter = 0x357c, 0x137e, 0, 0
  426. local function p00()
  427.   local dx, bx = d0loc, (d0locd + 0x1395) & 0xFFFF
  428.   local al = d0color
  429.   for _ = 1, 32 do
  430.     bput(dx, al)
  431.     local cf = bx >> 15
  432.     bx = rol16(bx, 1)
  433.     dx = (dx + bx + cf) & 0xFFFF
  434.     al = ((al + 13) & 255) & 0x3f
  435.   end
  436.   d0loc, d0locd, d0color = dx, bx, al
  437.   d0counter = (d0counter - 2) & 255
  438.   if d0counter == 0 then setnext0() end
  439. end
  440.  
  441.  
  442. local d1counter = 0
  443. local function p10()
  444.   local dl = d1counter
  445.   local function run(bx, v, dbx)
  446.     for _ = 1, 16 do
  447.       bput(bx, v); bput(bx + 1, v); bput(bx + 256, v); bput(bx + 257, v)
  448.       v = (v + 4) & 255
  449.       bx = (bx + dbx) & 0xFFFF
  450.     end
  451.   end
  452.   run(dl, 0x40, 97 * 256 + 97)
  453.   run((0x33 << 8) | ((-dl) & 255), 0x42, 17 * 256 + 223)
  454.   run((dl << 8) | 0x57, 0x41, 111 * 256 + 17)
  455.   run((((-dl) & 255) << 8) | 0xa9, 0x43, 203 * 256 + 117)
  456.   d1counter = (d1counter - 1) & 255
  457.   if d1counter == 0 then setnext0() end
  458. end
  459.  
  460.  
  461. local d2counter = 0
  462. local function p20()
  463.   local dl = d2counter
  464.   local t = (dl < 64) and dl or (127 - dl)  
  465.   local col = 0x80 + t
  466.   local function vline(a)
  467.     for _ = 1, 256 do bput(a, col); a = a + 256 end
  468.   end
  469.   vline(dl * 2)
  470.   bfill(dl * 512, 256, col)
  471.   bfill((dl ~ 0x7f) * 512 + 256, 256, col)
  472.   vline((dl ~ 0x7f) * 2 + 1)
  473.   dl = (dl + 1) & 0x7f
  474.   d2counter = dl
  475.   if dl == 0 then setnext0() end
  476. end
  477.  
  478.  
  479. local d3tile = {0, 1, 2, 3}
  480. local d3sizeseed
  481. d3sizeseed = 0x974ADEC2
  482. local d3loc, d3locd = 0x53c7, 0x137e
  483. local d3size, d3counter, d3counter2 = 0, 0, 4
  484. local d3sizetbl = {4, 4, 4, 4, 5, 5, 6, 7}
  485. if OPT.nojerk then d3sizetbl[7] = 5; d3sizetbl[8] = 5 end
  486. local function p30()
  487.   local di = d3loc
  488.   local cl = d3size
  489.   local bl = (1 << cl) & 255
  490.   local ax = bl
  491.   bl = (bl - 1) & 255
  492.   d3size = cl + 1
  493.   local cx = ax << 8
  494.   sc_tobuf(d3tile[4], bl, bl, di)
  495.   di = (di - ax) & 0xFFFF
  496.   sc_tobuf(d3tile[3], bl, bl, di)
  497.   di = (di - cx) & 0xFFFF
  498.   sc_tobuf(d3tile[1], bl, bl, di)
  499.   di = (di + ax) & 0xFFFF
  500.   sc_tobuf(d3tile[2], bl, bl, di)
  501.  
  502.   d3counter2 = d3counter2 - 1
  503.   if d3counter2 ~= 0 then return end
  504.   local ax2 = (d3locd + 0x4377) & 0xFFFF
  505.   ax2 = rol16(ax2, 5)
  506.   local cf = ax2 & 1
  507.   local t = d3loc + ax2 + cf
  508.   local cf2 = t >> 16
  509.   d3loc = t & 0xFFFF
  510.   d3locd = ax2
  511.   local e = (ax2 + d3sizeseed + cf2) & 0xFFFFFFFF
  512.   e = rol32(e, 9)
  513.   d3sizeseed = e
  514.   d3counter2 = d3sizetbl[(e & 7) + 1]
  515.   d3size = 0
  516.   d3counter = (d3counter - 1) & 0xFFFF
  517.   if d3counter == 0 then setnext0() end
  518. end
  519.  
  520.  
  521. local d4loc, d4locd, d4len, d4lend = 0x7e7e, 0xFFFE, 1, 1
  522. local function p40()
  523.   local bp = d4loc
  524.   local di, si = bp, bp
  525.   local dl = d4len
  526.   local al = (0x41 - dl) & 255
  527.   local cf = (al < 0x40) and 1 or 0
  528.   al = (al + 0x3f + cf) & 255
  529.   local function put4()
  530.     bput(di, al); bput(di + 1, al); bput(si, al); bput(si + 1, al)
  531.     bput(di + 256, al); bput(di + 257, al); bput(si + 256, al); bput(si + 257, al)
  532.   end
  533.   for _ = 1, dl do
  534.     put4()
  535.     di = (di + 0x202) & 0xFFFF; si = (si - 0x1fe) & 0xFFFF
  536.   end
  537.   if dl - 1 > 0 then
  538.     di = (di - 0x400) & 0xFFFF; si = (si + 0x400) & 0xFFFF
  539.     for _ = 1, dl - 1 do
  540.       put4()
  541.       di = (di - 0x1fe) & 0xFFFF; si = (si + 0x202) & 0xFFFF
  542.     end
  543.   end
  544.   bp = (bp + d4locd) & 0xFFFF
  545.   dl = (dl + d4lend) & 255
  546.   local callnext = false
  547.   if dl == 0 then
  548.     bp = 0x7e7e; dl = 1; d4locd = 0xFFFE; d4lend = 1
  549.     callnext = true
  550.   elseif dl >= 0x42 then
  551.     bp = 0xfe7e; dl = 0x41; d4locd = 2; d4lend = 255
  552.   end
  553.   d4loc, d4len = bp, dl
  554.   if callnext then setnext0() end
  555. end
  556.  
  557.  
  558. local d5cntr = 255
  559. local function p50()
  560.   local cn = d5cntr
  561.   local di = cn << 8
  562.   local al = cn & 0x7f
  563.   if al >= 0x40 then al = al ~ 0x7f end
  564.   local ebp = al - 0x20
  565.   local dl = 0
  566.   for _ = 1, 64 do
  567.     for _ = 1, 4 do
  568.       local bx = (SIN0S[dl] * ebp) & ~0xFF
  569.       dl = (dl + 8) & 255
  570.       local ah = ((bx + 0xA000) >> 8) & 255
  571.       local a = (di + bx) & 0xFFFF
  572.       bput(a, ah); bput(a + 256, ah)
  573.       di = di + 1
  574.     end
  575.   end
  576.   d5cntr = d5cntr - 1
  577.   if d5cntr < 0 then d5cntr = 255; setnext0() end
  578. end
  579.  
  580.  
  581. local d6loc = 0
  582. local function p60()
  583.   bfill(d6loc << 8, 0x2000, 0)
  584.   d6loc = d6loc + 0x20
  585.   if d6loc >= 0x100 then d6loc = 0; setnext0() end
  586. end
  587.  
  588.  
  589. local d7loc0, d7loc1, d7sinloc = 0, 0, 0
  590. local function add4(a)
  591.   local v = bget(a) | (bget(a + 1) << 8) | (bget(a + 2) << 16) | (bget(a + 3) << 24)
  592.   v = (v + 0x04040404) & 0xFFFFFFFF
  593.   bput(a, v & 255); bput(a + 1, (v >> 8) & 255); bput(a + 2, (v >> 16) & 255); bput(a + 3, v >> 24)
  594. end
  595. local function p70r0(bl, dh, dl, ch)
  596.   for _ = 1, 4 do
  597.     local cl = SIN0[bl] >> 3
  598.     bl = (bl + 4) & 255
  599.     local di = ((dh << 8) | dl) + cl
  600.     for _ = 1, 15 do
  601.       add4(di); add4(di + 4); add4(di + 8); add4(di + 12)
  602.       di = di + 256
  603.     end
  604.     dh = (dh + ch) & 255
  605.   end
  606.   return bl, dh
  607. end
  608. local function p70()
  609.   local bl, dh = p70r0(d7sinloc, d7loc0, 0, 1)
  610.   d7loc0 = dh
  611.   bl = (bl - 16) & 255
  612.   bl, dh = p70r0(bl, d7loc1, 0x80, 255)
  613.   d7loc1 = dh
  614.   d7sinloc = bl
  615.   if dh == 0 then setnext0() end
  616. end
  617.  
  618.  
  619. local d8tile = 16
  620. local d8loc, d8locd = 0xe000, 0x2000
  621. local d8locdtbl = {0x2000, 0x0020, 0xe000, 0xffe0, 0x2000, 0x0020, 0xe000,
  622.                    0xffe0, 0x2000, 0x0020, 0xe000, 0xffe0, 0x2000, 0x0020, 0xe000, 0}
  623. local d8cntrtbl = {8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 1}
  624. local d8cntr, d8index = 8, 0
  625. local function p80()
  626.   local di = (d8loc + d8locd) & 0xFFFF
  627.   d8loc = di
  628.   local callnext = false
  629.   d8cntr = d8cntr - 1
  630.   if d8cntr == 0 then
  631.     local ix = (d8index + 1) & 15
  632.     d8index = ix
  633.     d8cntr = d8cntrtbl[ix + 1]
  634.     d8locd = d8locdtbl[ix + 1]
  635.     if ix == 0 then d8loc = 0; callnext = true end
  636.   end
  637.   local tb = d8tile * 1024
  638.   for r = 0, 31 do
  639.     local dst = di + r * 256
  640.     local sp = tb + r * 32 + 1
  641.     for k = 0, 31 do
  642.       bput(dst + k, byte(TILES, sp + k))
  643.     end
  644.   end
  645.   if callnext then setnext0() end
  646. end
  647.  
  648.  
  649. local d9cntr = 0
  650. local function p90()
  651.   local dl = d9cntr
  652.   local di = dl << 8
  653.   local al = dl & 0x7f
  654.   local ebx = 0x01010101
  655.   if al & 0x40 ~= 0 then ebx = 0xFEFEFEFF; al = al ~ 0x7f end
  656.   local eax = al * 0x01010101
  657.   dl = (dl + 4) & 255
  658.   d9cntr = dl
  659.   local callnext = (dl == 0)
  660.   for row = 0, 3 do
  661.     local b0, b1, b2, b3 = eax & 255, (eax >> 8) & 255, (eax >> 16) & 255, (eax >> 24) & 255
  662.     if b0 == b1 and b1 == b2 and b2 == b3 then
  663.       bfill(di + row * 256, 256, b0)
  664.     else
  665.       local a = di + row * 256
  666.       for q = 0, 63 do
  667.         bput(a, b0); bput(a + 1, b1); bput(a + 2, b2); bput(a + 3, b3); a = a + 4
  668.       end
  669.     end
  670.     eax = (eax + ebx) & 0xFFFFFFFF
  671.   end
  672.   if callnext then setnext0() end
  673. end
  674.  
  675. local function delay0()
  676.   delaycntr = (delaycntr - 1) & 0xFFFF
  677.   if delaycntr == 0 then setnext0() end
  678. end
  679. local function waitpals() if slide == nil then setnext0() end end
  680.  
  681. local function tiles4(a, b, c, d) d3tile = {a, b, c, d} end
  682.  
  683. local function m00() if palnexts(0) then return end setnext0() end
  684. local function m01() if palnexts(1) then return end setnext0() end
  685. local function m02() if set_palso(0, 64, ZERO) then return end setnext0() end
  686. local function m03() if palnexts(2) then return end setnext0() end
  687. local function m04()
  688.   if set_palso(192, 64, getpal0a(pal0aptr)) then return end
  689.   if palnext(1) then return end
  690.   setnext0()
  691. end
  692. local function m05()
  693.   if palnexts(2) then return end
  694.   tiles4(0, 1, 2, 3); d3counter = 0x10; delaycntr = 2
  695.   setnext0()
  696. end
  697. local function m06()
  698.   l1on = true
  699.   if set_palso(128, 64, ZERO) then return end
  700.   d3counter = 0x20
  701.   setnext0()
  702. end
  703. local function m07() tiles4(4, 5, 6, 7); d3counter = 0x40; setnext0() end
  704. local function m08() if palnexts(1) then return end delaycntr = 0x80; setnext0() end
  705. local function m09()
  706.   l2on = true
  707.   if palnext(2) then return end
  708.   if palnexts(1) then return end
  709.   setnext0()
  710. end
  711. local function m0a() tiles4(8, 9, 10, 11); d3counter = 0x10; delaycntr = 0x40; setnext0() end
  712. local function m0b() delaycntr = 0x40; setnext0() end
  713. local function m0c() if set_palso(0, 192, ZERO) then return end setnext0() end
  714. local function m0d() if palnext(0) then return end delaycntr = 0x40; setnext0() end
  715. local function m0e()
  716.   if palnext(1) then return end
  717.   tiles4(12, 13, 14, 15); d3counter = 0x10; delaycntr = 0x40
  718.   setnext0()
  719. end
  720. local function m0f() if palnext(2) then return end d8tile = 16; delaycntr = 0x40; setnext0() end
  721. local function m10() tiles4(17, 18, 19, 20); d3counter = 0x10; setnext0() end
  722. local function m11()
  723.   if palnext(0) then return end
  724.   if set_palso(128, 64, ZERO) then return end
  725.   d3counter = 0x40; delaycntr = 0x40
  726.   setnext0()
  727. end
  728. local function m12()
  729.   if set_palso(64, 64, getpal(palptrtbl[palindex + 1], 63, 64)) then return end
  730.   setnext0()
  731. end
  732. local function m13() if palnext(2) then return end setnext0() end
  733. local function m14()
  734.   if set_palo(0, 64, ZERO) then return end
  735.   if set_palso(128, 64, ZERO) then return end
  736.   setnext0()
  737. end
  738. local function m15()
  739.   if palnexts(0) then return end
  740.   tiles4(21, 22, 23, 24); d3counter = 0x20; delaycntr = 0x80
  741.   setnext0()
  742. end
  743. local function m16() tiles4(25, 26, 27, 28); d3counter = 0x10; delaycntr = 0x40; setnext0() end
  744.  
  745. routtbl = {m00, p00, m01, p10, m02, waitpals,
  746.   m03, p20, m04, waitpals, m05,
  747.   delay0, p30, m06, p30, m07, p30, m08, waitpals, p40, delay0, m09,
  748.   m0a, p30, delay0, p50, m0b, delay0, m0c, waitpals, p60, m0d, p70,
  749.   delay0, m0e, p30, delay0, m0f, p80, delay0, m10, p30, m11, p30, p90,
  750.   delay0, m12, p70, m13, p20, m14, waitpals, p60, m15, p30, delay0,
  751.   m16, p30, delay0}
  752. ROUTTBLLEN = #routtbl
  753. ROUTTBLSTART = 6
  754. l0rout = m00
  755.  
  756. end
  757.  
  758.  
  759.  
  760.  
  761. local gnbg_update, gnbg_render
  762. do
  763. local RAYS = {}
  764. do
  765.   local rowmap = {}
  766.   for j = 0, HS - 1 do rowmap[j] = (j * 50) // HS end
  767.   local cano = {}
  768.   for k = 0, 319 do
  769.     local x, y = 0, 0
  770.     for j = 0, 49 do
  771.       local dx = byte(RAYSTR, k * 100 + j + 1)
  772.       local dy = byte(RAYSTR, k * 100 + 50 + j + 1)
  773.       if dx > 127 then dx = dx - 256 end
  774.       if dy > 127 then dy = dy - 256 end
  775.       x = x + dx; y = y + dy
  776.       cano[j] = (y * 256 + x) & 0xFFFF
  777.     end
  778.     for j = 0, HS - 1 do RAYS[k * HS + j + 1] = cano[rowmap[j]] end
  779.   end
  780.   RAYSTR = nil
  781.   local r = {}
  782.   for j = 0, HS - 1 do r[j] = rowmap[j] * 2 end
  783.   RAYS.rowr = r        
  784. end
  785.  
  786. local vpdir, vploc = 0, 0x8080
  787. local skewD = {}
  788. for i = 0, 99 do skewD[i] = 0 end
  789. local skewSK = {}
  790. for j = 1, HS do skewSK[j] = 0 end
  791. local skewptr, skewcounter, skewmode, skewindex = 0, 0x10f, 0, 3
  792. local skewtbl = {1, -3, 5, -3}
  793. local mtblvpdir = {5, 0, 0xe7, 0xf0, 0, 5, -7, 6, -5, 9, -6, 7, -9}
  794. local mtblvpy   = {3, 0, 0xc0, 0xc0, 0, 3, -1, 5, -3, 1, -5, 1, -3}
  795. local mtblvpx   = {1, 0, 0x60, 0xc0, 0, 1, -5, 1, -3, 3, -1, 5, -3}
  796.  
  797.  
  798. local function drawr0(t)
  799.   local al = t[1]
  800.   if t[2] == 0 then
  801.     local bl = (t[3] - 1) & 255
  802.     if bl ~= 0 then t[3] = bl; return al end
  803.     t[5] = (t[5] + 1) & 7
  804.     t[2] = 1
  805.     t[3] = t[4]
  806.     return al
  807.   else
  808.     local tg = t[6 + t[5]]
  809.     if al == tg then t[2] = 0; return al end
  810.     if al < tg then al = al + 1 else al = al - 1 end
  811.     t[1] = al
  812.     return al
  813.   end
  814. end
  815.  
  816. gnbg_update = function()
  817.   if skewmode == 0 then
  818.     skewcounter = (skewcounter - 1) & 0xFFFF
  819.     if skewcounter == 0 then
  820.       skewcounter = 0x175; skewmode = 1; skewindex = (skewindex + 1) & 3
  821.     end
  822.   else
  823.     skewD[skewptr] = skewD[skewptr] + skewtbl[skewindex + 1]
  824.     skewptr = skewptr + 1
  825.     if skewptr >= 100 then skewptr = 0; skewmode = 0 end
  826.   end
  827.   local dh, dl = (vploc >> 8) & 255, vploc & 255
  828.   dh = (dh + drawr0(mtblvpy)) & 255
  829.   dl = (dl + drawr0(mtblvpx)) & 255
  830.   vploc = (dh << 8) | dl
  831.   local d = drawr0(mtblvpdir)
  832.   local ax = d + vpdir
  833.   if ax >= 320 then ax = ax - 320 elseif ax < 0 then ax = ax + 320 end
  834.   vpdir = ax
  835. end
  836.  
  837. gnbg_render = function()
  838.  
  839.   do
  840.     local ps, acc = {}, 0
  841.     for r = 0, 99 do acc = acc + skewD[r]; ps[r] = acc end
  842.     local rr = RAYS.rowr
  843.     for j = 1, HS do skewSK[j] = ps[rr[j - 1]] end
  844.   end
  845.   local loc, dir = vploc, vpdir
  846.   local SK = skewSK
  847.   local last = (H - 1) * W
  848.   for cx = 0, W - 1 do
  849.     local c = (cx * 320) // W
  850.     local rb = ((dir + c) % 320) * HS
  851.     local top, bot = cx + 1, last + cx + 1
  852.     for j = 1, HS do
  853.       local off = (loc + RAYS[rb + j] + SK[j]) & 0xFFFF
  854.       local v = (buf[(off >> 3) + 1] >> ((off & 7) << 3)) & 255
  855.       scr[top] = v; scr[bot] = v
  856.       top = top + W; bot = bot - W
  857.     end
  858.   end
  859. end
  860.  
  861. end
  862.  
  863.  
  864.  
  865. local function spr(id, L)
  866.   if not DRAWING then return end
  867.   local p = SPRO[id]
  868.   local n = byte(SPRS, p) | (byte(SPRS, p + 1) << 8)
  869.   p = p + 2
  870.   for _ = 1, n do
  871.     local dy, x0, len = byte(SPRS, p, p + 2)
  872.     p = p + 3
  873.     local a = L + dy * 400 + x0
  874.     local y = a // 400
  875.     if y >= 0 and y < 200 then
  876.       local x = a - y * 400
  877.       local gy = (y * H) // 200
  878.       local rowb = gy * W + 1
  879.       for k = 0, len - 1 do
  880.         local xx = x + k
  881.         if xx < 320 then
  882.           if xx >= 0 then scr[rowb + (xx * W) // 320] = byte(SPRS, p + k) end
  883.         end
  884.       end
  885.     else
  886.  
  887.       for k = 0, len - 1 do
  888.         local aa = a + k
  889.         local yy = aa // 400
  890.         if yy >= 0 and yy < 200 then
  891.           local xx = aa - yy * 400
  892.           if xx < 320 then scr[((yy * H) // 200) * W + (xx * W) // 320 + 1] = byte(SPRS, p + k) end
  893.         end
  894.       end
  895.     end
  896.     p = p + len
  897.   end
  898. end
  899.  
  900.  
  901. local function dotput(o, mask, color)
  902.   if not DRAWING then return end
  903.   local y = o // 100
  904.   if y < 0 or y >= 200 then return end
  905.   local xb = o - y * 100
  906.   local rowb = ((y * H) // 200) * W + 1
  907.   for p = 0, 3 do
  908.     if mask & (1 << p) ~= 0 then
  909.       local x = xb * 4 + p
  910.       if x < 320 then scr[rowb + (x * W) // 320] = color end
  911.     end
  912.   end
  913. end
  914.  
  915. local l1rout
  916. do
  917.  
  918.  
  919.  
  920. local l1routtbl, l1index = nil, 0
  921. local l1fn = {}
  922. local L1SEQ = {0, 1, 2, 3, 4, 6, 7, 8, 5, 9, 0, 2, 3, 4, 6, 5, 1, 8, 7, 9,
  923.                3, 4, 5, 6, 0, 8, 1, 2, 9, 7}
  924. local function setnext1()
  925.   local i = l1index + 1
  926.   if i >= #L1SEQ then i = 0 end
  927.   l1rout = l1fn[L1SEQ[i + 1]]
  928.   l1index = i
  929. end
  930.  
  931.  
  932. local d0spr = {2, 1, 0}
  933. local d0csprloctbl = {400 * 168 + 320, 400 * 200, -32, 400 * -32 + 288}
  934. local d0csprdtbl = {-4, -1600, 4, 1600}
  935. local d0csprcntrtbl = {88, 58, 88, 58}
  936. local d0l, d0d, d0i, d0c, d0n = 400 * 168 + 320, -4, 0, 88, 0
  937. l1fn[0] = function()
  938.   d0l = d0l + d0d
  939.   local bl = d0i - 1
  940.   if bl < 0 then bl = 2 end
  941.   d0i = bl
  942.   spr(d0spr[bl + 1], d0l)
  943.   d0c = (d0c - 1) & 255
  944.   if d0c ~= 0 then return end
  945.   d0n = (d0n + 1) & 3
  946.   d0l = d0csprloctbl[d0n + 1]; d0d = d0csprdtbl[d0n + 1]; d0c = d0csprcntrtbl[d0n + 1]
  947.   setnext1()
  948. end
  949.  
  950.  
  951. local d1seed = 0x974ADEC2
  952. local fx, fy, ff = {}, {}, {}
  953. for i = 0, 9 do fx[i] = 0; fy[i] = 0; ff[i] = 0 end
  954. local yadd = {-100, 0, 0, 100}
  955. local fendcntr, finitcntr, finitcntr2 = 10, 10, 1
  956. l1fn[1] = function()
  957.   local ecx = d1seed
  958.   local esi = 9
  959.   while esi >= 0 do
  960.     local edi = fx[esi] - 3
  961.     local skip = false
  962.     if edi < 0 then
  963.       skip = true
  964.     else
  965.       fx[esi] = edi
  966.       if edi == 0 then
  967.         fendcntr = fendcntr - 1
  968.         if fendcntr ~= 0 then
  969.           skip = true
  970.         else
  971.           fendcntr = 10; finitcntr = 10
  972.           setnext1(); return
  973.         end
  974.       end
  975.     end
  976.     if not skip then
  977.       local ebx = yadd[(ecx & 3) + 1] + fy[esi]
  978.       local edx = fy[esi]
  979.       if not (ebx > 100 * 183 or ebx < 0) then edx = ebx end
  980.       fy[esi] = edx & 0xFFFF
  981.       ecx = ror32(ecx, 11)
  982.       ecx = (ecx + 0x12345671 + ((ecx >> 31) & 1)) & 0xFFFFFFFF
  983.       ff[esi] = ff[esi] ~ 1
  984.       spr(3 + ff[esi], edx * 4 + edi - 20)
  985.     end
  986.     ecx = (ecx + esi) & 0xFFFFFFFF
  987.     esi = esi - 1
  988.   end
  989.   local edx = finitcntr - 1
  990.   if edx >= 0 then
  991.     finitcntr2 = (finitcntr2 - 1) & 255
  992.     if finitcntr2 == 0 then
  993.       finitcntr = edx
  994.       finitcntr2 = (ecx & 15) + 4
  995.       fx[edx] = 342
  996.       fy[edx] = ((((ecx >> 8) & 0x7f) + 27) * 100) & 0xFFFF
  997.       ecx = ror32(ecx, 5)
  998.       ecx = (ecx + 0x59f4132f + ((ecx >> 31) & 1)) & 0xFFFFFFFF
  999.     end
  1000.   end
  1001.   d1seed = ecx
  1002. end
  1003.  
  1004.  
  1005. local sluggytbl = {8, 9, 10, 9, 8, 7}      
  1006. sluggytbl = {6, 7, 8, 7, 6, 5}
  1007. local sluggyofs = {9, 5, 0, 0, 0, 0}
  1008. local s2f, s2y, s2x = 5, 233, 0x71
  1009. l1fn[2] = function()
  1010.   local bl = s2f
  1011.   local y = s2y - sluggyofs[bl + 1]
  1012.   local L = (y - 29) * 400 + s2x + 24
  1013.   spr(sluggytbl[bl + 1], L)
  1014.   bl = bl - 1
  1015.   if bl < 0 then
  1016.     bl = 5
  1017.     local ny = s2y - 13
  1018.     s2y = ny & 255
  1019.     if not (ny > 0) then
  1020.       s2y = 233
  1021.       s2x = (s2x + 0x6f) & 255
  1022.       s2f = bl
  1023.       setnext1()
  1024.       return
  1025.     end
  1026.   end
  1027.   s2f = bl
  1028. end
  1029.  
  1030.  
  1031. local d3hseed = 0x9693972E
  1032. local hL = {}
  1033. for i = 0, 15 do hL[i] = 0 end
  1034. local hidx, hmloc = 0, -80
  1035. l1fn[3] = function()
  1036.   for esi = 15, 0, -1 do spr(9, hL[esi]) end
  1037.   local ebp = d3hseed
  1038.   local edx = (hidx + 1) & 15
  1039.   hidx = edx
  1040.   local ebx = hmloc
  1041.   local eax = (ebp & 0x3f) + ebx
  1042.   if eax >= 320 then eax = 320 end
  1043.   local ecx = (ebp >> 6) & 255
  1044.   if ecx >= 188 then ecx = ecx - 156 end
  1045.   ecx = ecx * 400 + eax + 400
  1046.   hL[edx] = ecx
  1047.   ebp = ror32(ebp, 9)
  1048.   ebp = (ebp + edx + 0x123457) & 0xFFFFFFFF
  1049.   ebx = ebx + 7
  1050.   local callnext = false
  1051.   if ebx >= 320 + 7 * 16 then callnext = true; ebx = -80 end
  1052.   d3hseed = ebp; hmloc = ebx
  1053.   if callnext then setnext1() end
  1054. end
  1055.  
  1056.  
  1057. local w4loc = 0
  1058. local function r0a()
  1059.   w4loc = (w4loc + 2) & 0xFFFF
  1060.   local edx = w4loc - 50
  1061.   if edx < 0 then return 0, 0, 0 end
  1062.   return edx, (SIN0[edx & 255] >> 1) + 131, 0
  1063. end
  1064. local function r0b()
  1065.   local dx = w4loc
  1066.   if dx == 276 then return 0, 0, 1 end
  1067.   if dx >= 226 then return 0, 0, 0 end
  1068.   return dx, (SIN0[(dx - 178) & 255] >> 1) + 131, 0
  1069. end
  1070. local function r1a()
  1071.   w4loc = (w4loc + 3) & 0xFFFF
  1072.   local ebx = w4loc - 80
  1073.   if ebx < 0 then return 0, 0, 0 end
  1074.   return (SIN0[ebx & 255] >> 1) + 49, ebx, 0
  1075. end
  1076. local function r1b()
  1077.   local ebx = w4loc
  1078.   if ebx >= 472 then return 0, 0, 1 end
  1079.   if ebx >= 392 then return 0, 0, 0 end
  1080.   return (SIN0[(ebx - 208) & 255] >> 1) + 49, ebx, 0
  1081. end
  1082. local function r2a()
  1083.   w4loc = (w4loc + 2) & 0xFFFF
  1084.   local dx = w4loc - 50
  1085.   if dx < 0 then return 0, 0, 0 end
  1086.   local x = (SIN0[dx & 255] >> 1) + 131
  1087.   local y = (dx & ~255) | ((226 - (dx & 255)) & 255)
  1088.   return y, x, 0
  1089. end
  1090. local function r2b()
  1091.   local dx = w4loc
  1092.   if dx == 276 then return 0, 0, 1 end
  1093.   if dx >= 226 then return 0, 0, 0 end
  1094.   local x = (SIN0[(dx - 178) & 255] >> 1) + 131
  1095.   local y = (dx & ~255) | ((224 - (dx & 255)) & 255)
  1096.   return y, x, 0
  1097. end
  1098. local function r3a()
  1099.   w4loc = (w4loc + 3) & 0xFFFF
  1100.   local ebx = w4loc - 78
  1101.   if ebx < 0 then return 0, 0, 0 end
  1102.   return (SIN0[ebx & 255] >> 1) + 49, 396 - ebx, 0
  1103. end
  1104. local function r3b()
  1105.   local ebx = w4loc
  1106.   if ebx >= 474 then return 0, 0, 1 end
  1107.   if ebx >= 396 then return 0, 0, 0 end
  1108.   return (SIN0[(ebx - 206) & 255] >> 1) + 49, 393 - ebx, 0
  1109. end
  1110. local pos4tbl0 = {r0a, r1a, r2a, r3a, r0a, r1a, r2a, r3a}
  1111. local pos4tbl1 = {r0b, r1b, r2b, r3b, r2b, r3b, r0b, r1b}
  1112. local pos4 = {r0a, r0b}
  1113. local d4frame = {0, 2}
  1114. local d4wing = {11, 12, 13, 12}
  1115. local d4centertbl = {10, 23, 17, 16, 34}
  1116. local d4center, d4posi, d4centeri = 10, 0, 0
  1117. local function wing(esi)
  1118.   local y, x, cf = pos4[esi + 1]()
  1119.   local Lw = (y - 26) * 400 + x - 72
  1120.   local f = (d4frame[esi + 1] + 1) & 3
  1121.   d4frame[esi + 1] = f
  1122.   spr(d4wing[f + 1], Lw)
  1123.   spr(d4center, Lw + 3625)
  1124.   return cf
  1125. end
  1126. l1fn[4] = function()
  1127.   wing(0)
  1128.   local cf = wing(1)
  1129.   if cf == 0 then return end
  1130.   d4posi = (d4posi + 1) & 7
  1131.   pos4[1] = pos4tbl0[d4posi + 1]; pos4[2] = pos4tbl1[d4posi + 1]
  1132.   w4loc = 0
  1133.   d4centeri = d4centeri + 1
  1134.   if d4centeri >= 5 then d4centeri = 0 end
  1135.   d4center = d4centertbl[d4centeri + 1]
  1136.   setnext1()
  1137. end
  1138.  
  1139.  
  1140. local H5 = {[0]=37,36,36,35,34,33,33,32,31,30,30,29,28,28,27,26,26,25,24,24,23,23,22,21,21,20,20,19,18,18,17,17,16,16,15,15,14,14,13,13,12,12,11,11,10,10,10,9,9,8,8,8,7,7,6,6,6,5,5,5,5,4,4,4,3,3,3,3,2,2,2,2,2,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,4,4,4,5,5,5,5,6,6,6,7,7,8,8,8,9,9,10,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,20,20,21,21,22,23,23,24,24,25,26,26,27,28,28,29,30,30,31,32,33,33,34,35,36,36,37}
  1141. local d5loc, d5i, d5cur = 372, 0, 14
  1142. local d5tbl = {14, 15, 18, 19, 20, 21}
  1143. local d5callnext
  1144. l1fn[5] = function()
  1145.   local ebx = d5loc - 2
  1146.   local callnext = false
  1147.   if ebx == 0 then
  1148.     d5i = d5i + 1; if d5i >= 6 then d5i = 0 end
  1149.     d5cur = d5tbl[d5i + 1]
  1150.     ebx = 372; callnext = true
  1151.   end
  1152.   d5loc = ebx
  1153.   local h = H5[ebx >> 1]
  1154.   spr(d5cur, (h + 15) * 400 + ebx - 52)
  1155.   if callnext then setnext1() end
  1156. end
  1157.  
  1158.  
  1159. local function mkdots(n, t0, t1, t2, t3, dec1, mod2, dec3, wmul, mask0, maskfn)
  1160.   local o, m, c = {}, {}, {}
  1161.   local t4 = mask0
  1162.   for i = 1, n do
  1163.     o[i] = (t0 * 100 + t2 * wmul) & 0xFFFF
  1164.     m[i] = t4 or 0
  1165.     c[i] = (t2 + 1) & 255
  1166.     t0 = t0 + t1
  1167.     if t0 > 199 then t0 = t0 - 200; t1 = t1 - dec1 end
  1168.     t2 = t2 + t3
  1169.     if t2 > mod2 then t2 = t2 - (mod2 + 1); t3 = t3 - dec3 end
  1170.     if maskfn then t4 = maskfn(t4) end
  1171.   end
  1172.   return {o = o, m = m, c = c, n = n}
  1173. end
  1174. local function cyc(v) if v == 0x11 then return 0x22 elseif v == 0x22 then return 0x44 elseif v == 0x44 then return 0x88 else return 0x11 end end
  1175. local D6 = {
  1176.   mkdots(64, 0, 79, 0, 67, 3, 79, 4, 1, 0x11, cyc),
  1177.   mkdots(32, 56, 95, 49, 59, 6, 79, 5, 1, 0x33, function(v) return v ~ 0xFF end),
  1178.   mkdots(16, 132, 96, 13, 73, 8, 79, 7, 1, 0, nil)}
  1179. local D8 = {
  1180.   mkdots(64, 192, 188, 53, 37, 8, 79, 7, 1, 0, nil),
  1181.   mkdots(32, 64, 96, 25, 31, 8, 39, 3, 2, 0, nil),
  1182.   mkdots(16, 132, 96, 13, 13, 8, 19, 2, 4, 0, nil)}
  1183.  
  1184. local function nums(state)
  1185.  
  1186.   local al = (state.cntr - 1) & 255
  1187.   if al == 0 then
  1188.     state.cntr = 0xF0; state.num = 0; state.numd = 1
  1189.     return nil
  1190.   end
  1191.   state.cntr = al
  1192.   local ch, cl = state.num, state.numd
  1193.   if al == 0x10 then cl = -1; state.numd = cl end
  1194.   ch = (ch + cl) & 255
  1195.   if ch == 0 or ch >= 0x10 then state.numd = 0 end
  1196.   state.num = ch
  1197.   return ch
  1198. end
  1199. local S6 = {cntr = 0xF0, num = 0, numd = 1}
  1200. l1fn[6] = function()
  1201.   local ch = nums(S6)
  1202.   if not ch then setnext1(); return end
  1203.   local COL = 0xC7
  1204.  
  1205.   do
  1206.     local g = D6[3]
  1207.     for k = 0, 15 do
  1208.       local cl = 16 - k
  1209.       local bx = (g.o[k + 1] + 400) & 0xFFFF
  1210.       if bx >= 20000 then bx = (bx - 20000) & 0xFFFF end
  1211.       local ebx = bx - 1
  1212.       local cnt = (g.c[k + 1] - 1) & 255
  1213.       if cnt == 0 then cnt = 80; ebx = ebx + 80 end
  1214.       g.c[k + 1] = cnt
  1215.       g.o[k + 1] = ebx & 0xFFFF
  1216.       if cl <= ch then
  1217.         dotput(ebx, 6, COL); dotput(ebx + 300, 6, COL)
  1218.         dotput(ebx + 100, 15, COL); dotput(ebx + 200, 15, COL)
  1219.       end
  1220.     end
  1221.   end
  1222.   ch = (ch * 2) & 255
  1223.   do
  1224.     local g = D6[2]
  1225.     for k = 0, 31 do
  1226.       local cl = 32 - k
  1227.       local bx = (g.o[k + 1] + 200) & 0xFFFF
  1228.       if bx >= 20000 then bx = (bx - 20000) & 0xFFFF end
  1229.       local ebx = bx
  1230.       local al = g.m[k + 1] ~ 0xFF
  1231.       if al >= 0x80 then
  1232.         ebx = ebx - 1
  1233.         local cnt = (g.c[k + 1] - 1) & 255
  1234.         if cnt == 0 then cnt = 80; ebx = ebx + 80 end
  1235.         g.c[k + 1] = cnt
  1236.       end
  1237.       g.o[k + 1] = ebx & 0xFFFF
  1238.       g.m[k + 1] = al
  1239.       if cl <= ch then
  1240.         dotput(ebx, al & 15, COL); dotput(ebx + 100, al & 15, COL)
  1241.       end
  1242.     end
  1243.   end
  1244.   ch = (ch * 2) & 255
  1245.   do
  1246.     local g = D6[1]
  1247.     for k = 0, 63 do
  1248.       local cl = 64 - k
  1249.       local bx = (g.o[k + 1] + 100) & 0xFFFF
  1250.       if bx >= 20000 then bx = (bx - 20000) & 0xFFFF end
  1251.       local ebx = bx
  1252.       local al = g.m[k + 1]
  1253.       local cf = al & 1
  1254.       al = (al >> 1) | (cf << 7)
  1255.       if cf == 1 then
  1256.         ebx = ebx - 1
  1257.         local cnt = (g.c[k + 1] - 1) & 255
  1258.         if cnt == 0 then cnt = 80; ebx = ebx + 80 end
  1259.         g.c[k + 1] = cnt
  1260.       end
  1261.       g.o[k + 1] = ebx & 0xFFFF
  1262.       g.m[k + 1] = al
  1263.       if cl <= ch then dotput(ebx, al & 15, COL) end
  1264.     end
  1265.   end
  1266. end
  1267.  
  1268.  
  1269. local d7x, d7xd = 0, 2
  1270. local d7cl, d7ch, d7bl, d7bh = 0x40, 0x40, -1, -1
  1271. local d7i, d7cnt, d7phase = 0, 3, 0
  1272. local d7tbl = {22, 10, 23}
  1273. local d7cur = 22
  1274. l1fn[7] = function()
  1275.   local eax = d7x + d7xd
  1276.   d7x = eax
  1277.   if eax == 0 or eax >= 470 or eax < 0 then
  1278.     d7xd = -d7xd
  1279.     d7i = d7i + 1; if d7i >= 3 then d7i = 0 end
  1280.     d7cur = d7tbl[d7i + 1]
  1281.     setnext1(); return
  1282.   end
  1283.   local cl, ch, bl, bh = d7cl, d7ch, d7bl, d7bh
  1284.   cl = (cl + bl) & 255
  1285.   if cl == 0x10 or cl == 0x40 then bl = -bl end
  1286.   d7cnt = d7cnt - 1
  1287.   if d7cnt == 0 then
  1288.     d7cnt = 3
  1289.     ch = (ch + bh) & 255
  1290.     if ch == 0x10 or ch == 0x40 then bh = -bh end
  1291.   end
  1292.   d7cl, d7ch, d7bl, d7bh = cl, ch, bl, bh
  1293.   local ybase = 0x40 - cl
  1294.   d7phase = (d7phase + 5) & 255
  1295.   local b = d7phase
  1296.   for _ = 0, 7 do
  1297.     local rows = (SIN0[b] * cl) >> 7
  1298.     b = (b + 0x40) & 255
  1299.     local x = ((SIN0[b] * ch) >> 7) + d7x - 128
  1300.     if x >= 0 and x < 340 then
  1301.       spr(d7cur, (rows + ybase + 26) * 400 + x - 20)
  1302.     end
  1303.     b = (b - 32) & 255
  1304.   end
  1305. end
  1306.  
  1307.  
  1308. local S8 = {cntr = 0xF0, num = 0, numd = 1}
  1309. local function plot16(ebx, step, n)
  1310.  
  1311. end
  1312. l1fn[8] = function()
  1313.   local ch = nums(S8)
  1314.   if not ch then setnext1(); return end
  1315.   local COL = 0xD9
  1316.   do
  1317.     local g = D8[3]
  1318.     for k = 0, 15 do
  1319.       local cl = 16 - k
  1320.       local bx = (g.o[k + 1] + 1600) & 0xFFFF
  1321.       if bx >= 100 * 208 then bx = (bx - 20000) & 0xFFFF end
  1322.       local ebx = bx - 4
  1323.       local cnt = (g.c[k + 1] - 1) & 255
  1324.       if cnt == 0 then cnt = 20; ebx = ebx + 80 end
  1325.       g.c[k + 1] = cnt
  1326.       g.o[k + 1] = ebx & 0xFFFF
  1327.       if cl <= ch then
  1328.         for p = 0, 3 do
  1329.           local m = 1 << p
  1330.           local base = ebx - 100 * p
  1331.           dotput(base, m, COL); dotput(base - 400 + 1, m, COL)
  1332.           dotput(base - 800 + 2, m, COL); dotput(base - 1200 + 3, m, COL)
  1333.         end
  1334.       end
  1335.     end
  1336.   end
  1337.   ch = (ch * 2) & 255
  1338.   do
  1339.     local g = D8[2]
  1340.     for k = 0, 31 do
  1341.       local cl = 32 - k
  1342.       local bx = (g.o[k + 1] + 800) & 0xFFFF
  1343.       if bx >= 20000 then bx = (bx - 20000) & 0xFFFF end
  1344.       local ebx = bx - 2
  1345.       local cnt = (g.c[k + 1] - 1) & 255
  1346.       if cnt == 0 then cnt = 40; ebx = ebx + 80 end
  1347.       g.c[k + 1] = cnt
  1348.       g.o[k + 1] = ebx & 0xFFFF
  1349.       if cl <= ch then
  1350.         for p = 0, 3 do
  1351.           local m = 1 << p
  1352.           local base = ebx - 100 * p
  1353.           dotput(base, m, COL); dotput(base - 400 + 1, m, COL)
  1354.         end
  1355.       end
  1356.     end
  1357.   end
  1358.   ch = (ch * 2) & 255
  1359.   do
  1360.     local g = D8[1]
  1361.     for k = 0, 63 do
  1362.       local cl = 64 - k
  1363.       local bx = (g.o[k + 1] + 400) & 0xFFFF
  1364.       if bx >= 20000 then bx = (bx - 20000) & 0xFFFF end
  1365.       local ebx = bx - 1
  1366.       local cnt = (g.c[k + 1] - 1) & 255
  1367.       if cnt == 0 then cnt = 80; ebx = ebx + 80 end
  1368.       g.c[k + 1] = cnt
  1369.       g.o[k + 1] = ebx & 0xFFFF
  1370.       if cl <= ch then
  1371.         for p = 0, 3 do dotput(ebx - 100 * p, 1 << p, COL) end
  1372.       end
  1373.     end
  1374.   end
  1375. end
  1376.  
  1377.  
  1378. local d9frame = {24, 25, 25, 26, 26, 27, 27, 28, 29, 30, 30, 31, 31, 32, 32, 33}
  1379. local leafx, leafy = {}, {}
  1380. do
  1381.   local t0, t1 = 152, 187
  1382.   for i = 0, 23 do
  1383.     leafx[i] = t0
  1384.     t0 = t0 + t1
  1385.     if t0 > 333 then t0 = t0 - 334; t1 = t1 - 17 end
  1386.   end
  1387.   t0, t1 = 137, 167
  1388.   for i = 0, 23 do
  1389.     leafy[i] = t0 & 255
  1390.     t0 = t0 + t1
  1391.     if t0 > 209 then t0 = t0 - 210; t1 = t1 - 11 end
  1392.   end
  1393. end
  1394. local d9ph0, d9ph1 = 0, 0
  1395. local d9cntr, d9num, d9numd = 0xF0, 0, 1
  1396. l1fn[9] = function()
  1397.   local al = (d9cntr - 1) & 255
  1398.   if al == 0 then
  1399.     d9cntr = 0xF0; d9num = 0; d9numd = 1
  1400.     for i = 1, 8 do d9frame[i], d9frame[i + 8] = d9frame[i + 8], d9frame[i] end
  1401.     setnext1(); return
  1402.   end
  1403.   d9cntr = al
  1404.   local bh, bl = d9num, d9numd
  1405.   if al == 23 then bl = -1; d9numd = bl end
  1406.   bh = (bh + bl) & 255
  1407.   if bh == 0 or bh >= 23 then d9numd = 0 end
  1408.   d9num = bh
  1409.   local cl = (d9ph0 + 7) & 255
  1410.   local ch = (d9ph1 + 13) & 255
  1411.   d9ph0, d9ph1 = cl, ch
  1412.   for esi = bh, 0, -1 do
  1413.     local y = leafy[esi]
  1414.     local a = (SIN0[(cl + y) & 255] >> 6) + 1
  1415.     y = y + a
  1416.     if y >= 210 then y = y - 210 end
  1417.     leafy[esi] = y
  1418.     local x = leafx[esi]
  1419.     local v = SIN0[(ch + (x & 255)) & 255]
  1420.     local edx = v >> 5
  1421.     local mv = (edx >> 1) + 1
  1422.     x = x - mv
  1423.     if x < 0 then x = x + 334 end
  1424.     leafx[esi] = x
  1425.     spr(d9frame[edx + 1], (y - 9) * 400 + x - 13)
  1426.     local t = ((ch << 8) | cl) + 0x11b
  1427.     cl = t & 255; ch = (t >> 8) & 255
  1428.   end
  1429. end
  1430.  
  1431. l1rout = function() if l1on then l1rout = l1fn[0] end end
  1432.  
  1433. end
  1434.  
  1435.  
  1436.  
  1437.  
  1438. local l2rout
  1439. do
  1440. local l2fn = {}
  1441. local L2SEQ = {0, 2, 1, 3}
  1442. local l2index = 0
  1443. local function setnext2()
  1444.   local i = l2index + 1
  1445.   if i >= #L2SEQ then i = 0 end
  1446.   l2rout = l2fn[L2SEQ[i + 1]]
  1447.   l2index = i
  1448. end
  1449.  
  1450. local p0y, p0yd, p0xi = 251, -1, 0
  1451. local p1x, p1xd, p1y, p1yd = 0, 2, 80, 0
  1452. local p2x, p2xd, p2i = 0, 2, 0
  1453. local lasty = 93
  1454. local posroutindex = 0
  1455. local pos0, pos1, pos2
  1456. local posrout
  1457. local function posd()
  1458.   posroutindex = (posroutindex + 1) % 3
  1459.   posrout = (posroutindex == 0 and pos0) or (posroutindex == 1 and pos1) or pos2
  1460. end
  1461. pos0 = function()
  1462.   local bl = (p0xi + 3) & 255
  1463.   p0xi = bl
  1464.   local x = (SIN0[bl] >> 1) + 127
  1465.   local y = p0y + p0yd
  1466.   p0y = y
  1467.   lasty = y
  1468.   if y == 0 or y == 251 then p0yd = -p0yd; posd(); return x, y, 1 end
  1469.   return x, y, 0
  1470. end
  1471. pos1 = function()
  1472.   local edx = p1y + p1yd
  1473.   local eax = p1yd + 1
  1474.   if (edx & 255) >= 200 then eax = -(eax - 1) end
  1475.   p1y = edx & 255
  1476.   p1yd = ((eax + 128) & 255) - 128
  1477.   local ebx = p1x + p1xd
  1478.   p1x = ebx & 0xFFFF
  1479.   lasty = edx
  1480.   if ebx == 0 or ebx == 384 then p1xd = -p1xd; posd(); return ebx, edx, 1 end
  1481.   return ebx, edx, 0
  1482. end
  1483. pos2 = function()
  1484.   local ebx = p2x + p2xd
  1485.   p2x = ebx & 0xFFFF
  1486.   if ebx == 0 or ebx >= 448 then p2xd = -p2xd; posd(); return ebx, lasty, 1 end
  1487.   local cl = (p2i + 7) & 255
  1488.   p2i = cl
  1489.   ebx = ebx + (SIN0[cl] >> 2) - 64
  1490.   if ebx > 384 or ebx < 0 then ebx = 0 end
  1491.   cl = (cl + 0x40) & 255
  1492.   local edx = (SIN0[cl] >> 2) + 93
  1493.   lasty = edx
  1494.   return ebx, edx, 0
  1495. end
  1496. posrout = pos0
  1497.  
  1498. local TI, TV = {}, {}
  1499. local NSHAPE = #LS // 2
  1500.  
  1501. local function lens_draw(kind, lx, ly, src)
  1502.   if not DRAWING then return end
  1503.   local OX, OY = lx - 63, ly - 51
  1504.   local n, ci = 0, 0
  1505.   for i = 1, NSHAPE do
  1506.     local X, Y = byte(LS, 2 * i - 1, 2 * i)
  1507.     local z = X >= 128
  1508.     if z then X = X - 128 else ci = ci + 1 end
  1509.     local px, py = OX + X, OY + Y
  1510.     if px >= 0 and px < 320 and py >= 0 and py < 200 then
  1511.       local gx, gy = (px * W) // 320, (py * H) // 200
  1512.       local di = gy * W + gx + 1
  1513.       local v
  1514.       if z then v = 0
  1515.       elseif kind == 0 then v = bget(src + Y * 256 + X)
  1516.       elseif kind == 1 then v = L2TBL[scr[di]]
  1517.       elseif kind == 2 then v = scr[(((199 - py) * H) // 200) * W + gx + 1]
  1518.       else
  1519.         local col, row = byte(LSRC, 2 * ci - 1, 2 * ci)
  1520.         v = scr[((row * H) // 200) * W + ((col * 4 + 1) * W) // 320 + 1]
  1521.       end
  1522.       n = n + 1; TI[n] = di; TV[n] = v
  1523.     end
  1524.   end
  1525.   for q = 1, n do scr[TI[q]] = TV[q] end
  1526. end
  1527.  
  1528. local d2off = 0
  1529. l2fn[0] = function()
  1530.   local x, y, cf = posrout()
  1531.   local si = d2off
  1532.   if cf == 1 then d2off = (si + 0x5f31) & 0xFFFF end
  1533.   local src = si + (((y & 255) << 8) | (x & 255))
  1534.   lens_draw(0, x, y, src)
  1535.   if cf == 1 then setnext2() end
  1536. end
  1537. local function mklens(kind)
  1538.   return function()
  1539.     local x, y, cf = posrout()
  1540.     if cf == 1 then setnext2(); return end
  1541.     lens_draw(kind, x, y, 0)
  1542.   end
  1543. end
  1544. l2fn[1] = mklens(1)
  1545. l2fn[2] = mklens(2)
  1546. l2fn[3] = mklens(3)
  1547. l2rout = function() if l2on then l2rout = l2fn[0] end end
  1548.  
  1549. end
  1550.  
  1551.  
  1552.  
  1553. local BRAILLE = {{0x01, 0x08}, {0x02, 0x10}, {0x04, 0x20}, {0x40, 0x80}}
  1554. local function draw_end(f)
  1555.   local QG = {}
  1556.   for v = 0, 255 do
  1557.     local g = floor(v * f + 0.5)
  1558.     QG[v] = quant(g, g, g)
  1559.   end
  1560.   local setfg, setbg, set = gpu.setForeground, gpu.setBackground, gpu.set
  1561.   local fgc, bgc = -1, -1
  1562.   target_begin()
  1563.   local utf8char = utf8.char
  1564.   local sample = {}
  1565.   for cy = 0, HC - 1 do
  1566.     local cx = 0
  1567.     local pk, pc, pf, pb, pstart = nil, nil, nil, nil, 0
  1568.     local line = {}
  1569.     local function flush(endx)
  1570.       if pc then
  1571.         local n = endx - pstart
  1572.         if pc == " " then
  1573.           if bgc ~= pb then setbg(pb); bgc = pb end
  1574.         else
  1575.           if fgc ~= pf then setfg(pf); fgc = pf end
  1576.           if bgc ~= pb then setbg(pb); bgc = pb end
  1577.         end
  1578.         set(pstart + 1, cy + 1, rep(pc, n))
  1579.       end
  1580.     end
  1581.     for x = 0, WC - 1 do
  1582.       local mn, mx = 99, -1
  1583.       for j = 0, 3 do
  1584.         local sy = ((cy * 4 + j) * 200) // (HC * 4)
  1585.         for i = 0, 1 do
  1586.           local sx = ((x * 2 + i) * 320) // (WC * 2)
  1587.           local nidx = sy * 320 + sx
  1588.           local v = byte(ENDP, (nidx >> 1) + 1)
  1589.           if nidx & 1 == 0 then v = v >> 4 else v = v & 15 end
  1590.           sample[j * 2 + i + 1] = v
  1591.           if v < mn then mn = v end
  1592.           if v > mx then mx = v end
  1593.         end
  1594.       end
  1595.       local ch, fg, bg
  1596.       if mn == mx then
  1597.         ch = " "; bg = QG[floor(mn * 16.2 + 0.5)]; fg = bg
  1598.       else
  1599.         local thr = (mn + mx) / 2
  1600.         local bits, sl, nl, su, nu = 0, 0, 0, 0, 0
  1601.         for j = 0, 3 do
  1602.           for i = 0, 1 do
  1603.             local v = sample[j * 2 + i + 1]
  1604.             if v > thr then bits = bits | BRAILLE[j + 1][i + 1]; sl = sl + v; nl = nl + 1
  1605.             else su = su + v; nu = nu + 1 end
  1606.           end
  1607.         end
  1608.         ch = utf8char(0x2800 + bits)
  1609.         fg = QG[floor(sl / nl * 16.2 + 0.5)]
  1610.         bg = QG[floor(su / nu * 16.2 + 0.5)]
  1611.       end
  1612.       local key = ch
  1613.       if pc == ch and pb == bg and (ch == " " or pf == fg) then
  1614.  
  1615.       else
  1616.         flush(x)
  1617.         pc, pf, pb, pstart = ch, fg, bg, x
  1618.       end
  1619.     end
  1620.     flush(WC)
  1621.   end
  1622.   target_end()
  1623. end
  1624.  
  1625.  
  1626.  
  1627.  
  1628. local STEP_HZ = 70 / 3
  1629. local quit_req = false
  1630.  
  1631. local function handle_event(ev, a, b, c)
  1632.   if ev == "key_down" then
  1633.     if c == 1 or b == 113 or b == 81 or b == 3 then quit_req = true end
  1634.   elseif ev == "interrupted" then
  1635.     quit_req = true
  1636.   end
  1637. end
  1638.  
  1639. local function logic_step(drawing)
  1640.   DRAWING = drawing
  1641.   l0rout()
  1642.   gnbg_update()
  1643.   if drawing then gnbg_render() end
  1644.   l1rout()
  1645.   l2rout()
  1646.   slide_tick(); slide_tick(); slide_tick()
  1647. end
  1648.  
  1649. local function frame_loop(stop)
  1650.   local last = computer.uptime()
  1651.   local acc = 1
  1652.   while true do
  1653.     local now = computer.uptime()
  1654.     acc = acc + (now - last) * STEP_HZ
  1655.     last = now
  1656.     local n = floor(acc)
  1657.     if n < 1 then n = 1 end
  1658.     acc = acc - n
  1659.     if acc < 0 then acc = 0 end
  1660.     if n > OPT.maxsteps then n = OPT.maxsteps end
  1661.     for i = 1, n do logic_step(i == n) end
  1662.     present()
  1663.     local wait = (1 - acc) / STEP_HZ
  1664.     handle_event(computer.pullSignal(wait > 0 and wait or 0))
  1665.     if stop() then return end
  1666.   end
  1667. end
  1668.  
  1669. local function pause(sec)
  1670.   local t = computer.uptime() + sec
  1671.   while computer.uptime() < t and not quit_req do
  1672.     handle_event(computer.pullSignal(0.05))
  1673.   end
  1674. end
  1675.  
  1676. local function main()
  1677.   frame_loop(function() return quit_req or finish_req end)
  1678.  
  1679.   quit_req = false
  1680.   ending = true
  1681.   pal_slide(0, 256, ZERO)
  1682.   frame_loop(function() return slide == nil end)
  1683.   if not OPT.skipend then
  1684.     quit_req = false
  1685.     local steps = vram and 8 or 3
  1686.     pcall(gpu.setBackground, 0)
  1687.     pcall(gpu.fill, 1, 1, WC, HC, " ")
  1688.     for k = 1, steps do draw_end(k / steps) end
  1689.  
  1690.     local t = computer.uptime() + 768 / 70
  1691.     while computer.uptime() < t and not quit_req do
  1692.       handle_event(computer.pullSignal(0.1))
  1693.     end
  1694.     for k = steps - 1, 0, -1 do draw_end(k / steps) end
  1695.   end
  1696. end
  1697.  
  1698. local ok, err = pcall(main)
  1699. gpu_restore()
  1700. if not ok then error(err, 0) end
  1701. if print then
  1702.   print("Timeless: Copywrong (c) 1994, Tran (a.k.a. Thomas Pytel).")
  1703.   print("OpenComputers port.  Cogito ergo sum... NOT!")
  1704. end
Add Comment
Please, Sign In to add comment