From 5f371baab2c581caf4abac35ee69f687c032b2e2 Mon Sep 17 00:00:00 2001 From: HKXluo Date: Sun, 4 May 2025 23:10:57 +0800 Subject: [PATCH] add 32vid --- 32vid/32vid-player-mini.lua | 261 ++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 32vid/32vid-player-mini.lua diff --git a/32vid/32vid-player-mini.lua b/32vid/32vid-player-mini.lua new file mode 100644 index 0000000..ef6e9c7 --- /dev/null +++ b/32vid/32vid-player-mini.lua @@ -0,0 +1,261 @@ +-- 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 = ("