-- 32vid-player-mini from sanjuuni -- Licensed under the MIT license local bit32_band, bit32_lshift, bit32_rshift, math_frexp = bit32.band, bit32.lshift, bit32.rshift, math.frexp local function log2(n) local _, r = math_frexp(n) return r-1 end local dfpwm = require "cc.audio.dfpwm" local speaker = peripheral.find "speaker" local file local path = ... if path:match "^https?://" then file = assert(http.get(path, nil, true)) else file = assert(fs.open(shell.resolve(path), "rb")) end if file.read(4) ~= "32VD" then file.close() error("Not a 32Vid file") end local width, height, fps, nstreams, flags = ("= 16 then local l = 2^(t.s - 15) for n = 0, l-1 do retval[i+n] = last end i = i + l else retval[i], last, i = t.s, t.s, i + 1 end X = t.X + readbits(t.n) end --print(X) return retval end else error("Unimplemented!") end local blitColors = {[0] = "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"} local start = os.epoch "utc" local lastyield = start local vframe = 0 local subs = {} term.clear() for _ = 1, nframes do local size, ftype = (" 3000 then sleep(0) lastyield = os.epoch "utc" end local dcstart = os.epoch "utc" --print("init screen", vframe, file.seek()) init(false) --print("read screen", vframe, file.seek()) local screen = read(width * height) --print("init colors", vframe, file.seek()) init(true) --print("read bg colors", vframe) local bg = read(width * height) --print("read fg colors", vframe) local fg = read(width * height) local dctime = os.epoch "utc" - dcstart while os.epoch "utc" < start + vframe * 1000 / fps do end local texta, fga, bga = {}, {}, {} for y = 0, height - 1 do local text, fgs, bgs = "", "", "" for x = 1, width do text = text .. string.char(128 + screen[y*width+x]) fgs = fgs .. blitColors[fg[y*width+x]] bgs = bgs .. blitColors[bg[y*width+x]] end texta[y+1], fga[y+1], bga[y+1] = text, fgs, bgs end for i = 0, 15 do term.setPaletteColor(2^i, file.read() / 255, file.read() / 255, file.read() / 255) end for y = 1, height do term.setCursorPos(1, y) term.blit(texta[y], fga[y], bga[y]) end local delete = {} for i, v in ipairs(subs) do if vframe <= v.frame + v.length then term.setCursorPos(v.x, v.y) term.setBackgroundColor(v.bgColor) term.setTextColor(v.fgColor) term.write(v.text) else delete[#delete+1] = i end end for i, v in ipairs(delete) do table.remove(subs, v - i + 1) end --term.setCursorPos(1, height + 1) --term.clearLine() --print("Frame decode time:", dctime, "ms") vframe = vframe + 1 elseif ftype == 1 then local audio = file.read(size) if speaker then if bit32_band(flags, 12) == 0 then local chunk = {audio:byte(1, -1)} for i = 1, #chunk do chunk[i] = chunk[i] - 128 end speaker.playAudio(chunk) else speaker.playAudio(dfpwm.decode(audio)) end end elseif ftype == 8 then local data = file.read(size) local sub = {} sub.frame, sub.length, sub.x, sub.y, sub.color, sub.flags, sub.text = ("= 0x40 and ftype < 0x80 then if ftype == 64 then vframe = vframe + 1 end local mx, my = bit32_band(bit32_rshift(ftype, 3), 7) + 1, bit32_band(ftype, 7) + 1 --print("(" .. mx .. ", " .. my .. ")") local term = monitors[my][mx] if os.epoch "utc" - lastyield > 3000 then sleep(0) lastyield = os.epoch "utc" end local width, height = ("