添加全彩

This commit is contained in:
nnwang
2025-12-21 18:42:45 +08:00
parent fe4d7917a7
commit 12fc9a8d94
54 changed files with 379 additions and 770 deletions

BIN
HB-IMG/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

BIN
HB-IMG/10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

BIN
HB-IMG/11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

BIN
HB-IMG/12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

BIN
HB-IMG/13.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

BIN
HB-IMG/14.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

BIN
HB-IMG/15.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 B

BIN
HB-IMG/16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

BIN
HB-IMG/17.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

BIN
HB-IMG/18.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 B

BIN
HB-IMG/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 B

BIN
HB-IMG/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

BIN
HB-IMG/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

BIN
HB-IMG/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

BIN
HB-IMG/6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

BIN
HB-IMG/7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

BIN
HB-IMG/8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 391 B

BIN
HB-IMG/9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

BIN
HB-IMG/out.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
QC-IMG/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

BIN
QC-IMG/10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

BIN
QC-IMG/11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

BIN
QC-IMG/12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

BIN
QC-IMG/13.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

BIN
QC-IMG/14.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 B

BIN
QC-IMG/15.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

BIN
QC-IMG/16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

BIN
QC-IMG/17.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

BIN
QC-IMG/18.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

BIN
QC-IMG/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

BIN
QC-IMG/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

BIN
QC-IMG/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

BIN
QC-IMG/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

BIN
QC-IMG/6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

BIN
QC-IMG/7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

BIN
QC-IMG/8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

BIN
QC-IMG/9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

BIN
QC-IMG/out.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

313
lib/1.lua
View File

@@ -1,313 +0,0 @@
local f1 = {
{
"\159\143\159\143\139\143",
"ffffff",
"000000",
},
{
"\128\149\159\137\143\155",
"00ffff",
"ff0000",
},
{
"\130\151\128\148\148\148",
"000000",
"ffffff",
},
{
"\136\135\159\133\149\138",
"00f00f",
"ff0ff0",
},
}
local f2 = {
{
"\159\143\159\143\139\143",
"ffffff",
"000000",
},
{
"\128\149\151\157\153\151",
"00ffff",
"ff0000",
},
{
"\130\151\157\140\136\140",
"00ffff",
"ff0000",
},
{
"\136\135\149\142\134\145",
"00f00f",
"ff0ff0",
},
}
local f3 = {
{
"\159\143\132\159\128\148",
"ff0f00",
"00f0ff",
},
{
"\159\133\144\144\129\149",
"ff0000",
"00ffff",
},
{
"\128\129\144\130\143\157",
"0f00f0",
"f0ff0f",
},
{
"\130\149\128\131\128\149",
"0f0000",
"f0ffff",
},
}
local f4 = {
{
"\128\148\128\128\148\128",
"000000",
"ffffff",
},
{
"\130\151\130\131\151\131",
"000000",
"ffffff",
},
{
"\136\151\149\131\131\149",
"00f000",
"ff0fff",
},
{
"\159\149\143\153\153\143",
"f0f0ff",
"0f0f00",
},
}
local n = {" ","ffffff","ffffff"}
-- 创建 img 表结构
local img = {}
for i1 = 1, 8 do
img[i1] = {}
for i2 = 1, 4 do
img[i1][i2] = {}
end
end
-- ✅ 关键修复:将 logon 改为函数,每次返回新表
local function logon()
return {
" ",
"fffffffffffffffffffffffff",
"fffffffffffffffffffffffff"
}
end
-- 定义 logo 为普通表(不是函数)
local logo = {
{
" \139 ",
"fffffff0000000f000fffffff",
"ffffffffffffff0ffffffffff"
},
{
" \143\129\149 \132 ",
"fffffff0000ff00000fffffff",
"fffffffffff00f00fffffffff"
},
{
" \159\135 \149\143\158\135\149 ",
"fffffff0ff00000ff0fffffff",
"ffffffff00000ff00ffffffff"
},
{
" \149 \143\150\144 \131\133 ",
"ffffffff00000f0000fffffff",
"fffffff00000f0fffffffffff"
},
{
" \149 \136 \149 \131\144 ",
"ffffffff00f00f0f00fffffff",
"fffffff0000ff000fffffffff"
},
{
" \138 \131\133 \149 ",
"fffffff00000ff0000fffffff",
"ffffffff00000000fffffffff"
},
{
" \130\139\144 \149 ",
"fffffff000f0000000fffffff",
"ffffffffff000000fffffffff"
},
{
" \143\131 \135 ",
"fffffff00ff0000000fffffff",
"fffffffff000000ffffffffff"
},
{
" \143\131 ",
"fffffff00000000000fffffff",
"fffffffff000fffffffffffff"
},
{
" \143\135\129 ",
"fffffff00000000000fffffff",
"fffffffffffffffffffffffff"
},
}
local logo1 = {{},{},{},{}}
-- 第一组
for i = 1, 3 do
table.insert(logo1[1], logon())
end
-- 插入 logo 的每一帧
for _, frame in ipairs(logo) do
table.insert(logo1[1], frame)
end
for i = 1, 2 do
table.insert(logo1[1], logon())
end
logo1[1].duration = 1
-- 第二组
for i = 1, 2 do
table.insert(logo1[2], logon())
end
for _, frame in ipairs(logo) do
table.insert(logo1[2], frame)
end
for i = 1, 3 do
table.insert(logo1[2], logon())
end
-- 第三组
table.insert(logo1[3], logon())
for _, frame in ipairs(logo) do
table.insert(logo1[3], frame)
end
for i = 1, 4 do
table.insert(logo1[3], logon())
end
-- 第四组
for _, frame in ipairs(logo) do
table.insert(logo1[4], frame)
end
for i = 1, 5 do
table.insert(logo1[4], logon())
end
-- 填充 img 前 4 行
for i = 1, 4 do
img[i] = logo1[i]
end
-- 清理临时变量
logo1 = nil
logo = nil
-- 构建 img[5] 到 img[8]
for i=1,3 do
img[5][1][i] = n[i] .. f2[4][i] .. n[i] .. f4[4][i]
end
for i=1,3 do
img[5][2][i] = n[i] .. n[i] .. n[i] .. n[i]
end
for i=1,3 do
img[5][3][i] = n[i] .. n[i] .. n[i] .. n[i]
end
for i=1,3 do
img[5][4][i] = f1[1][i] .. n[i] .. f3[1][i] .. n[i]
end
for i=1,3 do
img[6][1][i] = n[i] .. f2[3][i] .. n[i] .. f4[3][i]
end
for i=1,3 do
img[6][2][i] = n[i] .. f2[4][i] .. n[i] .. f4[4][i]
end
for i=1,3 do
img[6][3][i] = f1[1][i] .. n[i] .. f3[1][i] .. n[i]
end
for i=1,3 do
img[6][4][i] = f1[2][i] .. n[i] .. f3[2][i] .. n[i]
end
for i=1,3 do
img[7][1][i] = n[i] .. f2[2][i] .. n[i] .. f4[2][i]
end
for i=1,3 do
img[7][2][i] = f1[1][i] .. f2[3][i] .. f3[1][i] .. f4[3][i]
end
for i=1,3 do
img[7][3][i] = f1[2][i] .. f2[4][i] .. f3[2][i] .. f4[4][i]
end
for i=1,3 do
img[7][4][i] = f1[3][i] .. n[i] .. f3[3][i] .. n[i]
end
for i=1,3 do
img[8][1][i] = f1[1][i] .. f2[1][i] .. f3[1][i] .. f4[1][i]
end
for i=1,3 do
img[8][2][i] = f1[2][i] .. f2[2][i] .. f3[2][i] .. f4[2][i]
end
for i=1,3 do
img[8][3][i] = f1[3][i] .. f2[3][i] .. f3[3][i] .. f4[3][i]
end
for i=1,3 do
img[8][4][i] = f1[4][i] .. f2[4][i] .. f3[4][i] .. f4[4][i]
end
-- 清理
f1 = nil
f2 = nil
f3 = nil
f4 = nil
n = nil
img.animation = true
img.secondsPerFrame = 0.1
-- ✅ 现在可以安全序列化
print(textutils.serialize(img[1]))
local function drawFrame(frame, term)
for y, row in ipairs(frame) do
term.setCursorPos(1, y)
term.blit(table.unpack(row))
end
if frame.palette then for i = 0, #frame.palette do
local c = frame.palette[i]
if type(c) == "table" then term.setPaletteColor(2^i, table.unpack(c))
else term.setPaletteColor(2^i, c) end
end end
if img.multiMonitor then term.setTextScale(img.multiMonitor.scale or 0.5) end
end
term.clear()
for i, frame in ipairs(img) do
drawFrame(frame, term)
if img.animation then sleep(frame.duration or img.secondsPerFrame or 0.05)
else read() break end
end
read()
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1, 1)
for i = 0, 15 do term.setPaletteColor(2^i, term.nativePaletteColor(2^i)) end

View File

@@ -1,284 +1,284 @@
import json import json
import struct import struct
import sys import sys
from pathlib import Path from pathlib import Path
# Base64 字母表CC:Tweaked 使用的自定义顺序) # Base64 字母表CC:Tweaked 使用的自定义顺序)
B64STR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" B64STR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
B64MAP = {ch: i for i, ch in enumerate(B64STR)} B64MAP = {ch: i for i, ch in enumerate(B64STR)}
def custom_b64decode(s): def custom_b64decode(s):
"""使用自定义字母表解码 base64 字符串(忽略 '='""" """使用自定义字母表解码 base64 字符串(忽略 '='"""
val = 0 val = 0
bits = 0 bits = 0
out = bytearray() out = bytearray()
for ch in s: for ch in s:
if ch == '=': if ch == '=':
continue continue
val = (val << 6) | B64MAP[ch] val = (val << 6) | B64MAP[ch]
bits += 6 bits += 6
if bits >= 8: if bits >= 8:
bits -= 8 bits -= 8
out.append((val >> bits) & 0xFF) out.append((val >> bits) & 0xFF)
return bytes(out) return bytes(out)
def decode_frame(data): def decode_frame(data):
# 验证头部 # 验证头部
assert data[:4] == b'\x00\x00\x00\x00', "Invalid frame header (first 4 bytes)" assert data[:4] == b'\x00\x00\x00\x00', "Invalid frame header (first 4 bytes)"
assert data[8:16] == b'\x00\x00\x00\x00\x00\x00\x00\x00', "Invalid frame header (bytes 8-15)" assert data[8:16] == b'\x00\x00\x00\x00\x00\x00\x00\x00', "Invalid frame header (bytes 8-15)"
width, height = struct.unpack('<HH', data[4:8]) width, height = struct.unpack('<HH', data[4:8])
total_chars = width * height total_chars = width * height
# === 解码字符 RLE 流 === # === 解码字符 RLE 流 ===
text_bytes = [] text_bytes = []
pos = 16 pos = 16
remaining = total_chars remaining = total_chars
while remaining > 0: while remaining > 0:
char_byte = data[pos] char_byte = data[pos]
count = data[pos + 1] count = data[pos + 1]
pos += 2 pos += 2
text_bytes.extend([char_byte] * count) text_bytes.extend([char_byte] * count)
remaining -= count remaining -= count
assert len(text_bytes) == total_chars, "Character RLE length mismatch" assert len(text_bytes) == total_chars, "Character RLE length mismatch"
# === 解码颜色 RLE 流 === # === 解码颜色 RLE 流 ===
color_bytes = [] color_bytes = []
remaining = total_chars remaining = total_chars
while remaining > 0: while remaining > 0:
color_byte = data[pos] color_byte = data[pos]
count = data[pos + 1] count = data[pos + 1]
pos += 2 pos += 2
color_bytes.extend([color_byte] * count) color_bytes.extend([color_byte] * count)
remaining -= count remaining -= count
assert len(color_bytes) == total_chars, "Color RLE length mismatch" assert len(color_bytes) == total_chars, "Color RLE length mismatch"
# === 读取调色板16 色 × RGB=== # === 读取调色板16 色 × RGB===
palette_raw = data[pos:pos + 48] palette_raw = data[pos:pos + 48]
assert len(palette_raw) == 48, "Palette must be 48 bytes" assert len(palette_raw) == 48, "Palette must be 48 bytes"
palette = [] palette = []
for i in range(16): for i in range(16):
r = palette_raw[i * 3] r = palette_raw[i * 3]
g = palette_raw[i * 3 + 1] g = palette_raw[i * 3 + 1]
b = palette_raw[i * 3 + 2] b = palette_raw[i * 3 + 2]
palette.append([r, g, b]) palette.append([r, g, b])
# === 构建行数据 === # === 构建行数据 ===
text_rows = [] text_rows = []
fg_rows = [] fg_rows = []
bg_rows = [] bg_rows = []
idx = 0 idx = 0
for y in range(height): for y in range(height):
row_text_parts = [] row_text_parts = []
row_fg = '' row_fg = ''
row_bg = '' row_bg = ''
for x in range(width): for x in range(width):
b = text_bytes[idx] b = text_bytes[idx]
row_text_parts.append(f"\\{b:03d}") # 如 \130 row_text_parts.append(f"\\{b:03d}") # 如 \130
c = color_bytes[idx] c = color_bytes[idx]
fg = c & 0x0F fg = c & 0x0F
bg = (c >> 4) & 0x0F bg = (c >> 4) & 0x0F
row_fg += f"{fg:x}" row_fg += f"{fg:x}"
row_bg += f"{bg:x}" row_bg += f"{bg:x}"
idx += 1 idx += 1
text_rows.append(''.join(row_text_parts)) text_rows.append(''.join(row_text_parts))
fg_rows.append(row_fg) fg_rows.append(row_fg)
bg_rows.append(row_bg) bg_rows.append(row_bg)
return { return {
"width": width, "width": width,
"height": height, "height": height,
"text": text_rows, "text": text_rows,
"foreground": fg_rows, "foreground": fg_rows,
"background": bg_rows, "background": bg_rows,
"palette": palette "palette": palette
} }
def encode_frame(frame): def encode_frame(frame):
width = frame["width"] width = frame["width"]
height = frame["height"] height = frame["height"]
total = width * height total = width * height
# === 从 \ddd 序列还原字节 === # === 从 \ddd 序列还原字节 ===
full_text = ''.join(frame["text"]) full_text = ''.join(frame["text"])
text_bytes = [] text_bytes = []
i = 0 i = 0
while i < len(full_text): while i < len(full_text):
if full_text[i] == '\\' and i + 4 <= len(full_text): if full_text[i] == '\\' and i + 4 <= len(full_text):
try: try:
num_str = full_text[i+1:i+4] num_str = full_text[i+1:i+4]
num = int(num_str) num = int(num_str)
if 0 <= num <= 255: if 0 <= num <= 255:
text_bytes.append(num) text_bytes.append(num)
i += 4 i += 4
continue continue
except ValueError: except ValueError:
pass pass
raise ValueError(f"Invalid escape sequence at position {i}: expected \\ddd, got {full_text[i:i+5]}") raise ValueError(f"Invalid escape sequence at position {i}: expected \\ddd, got {full_text[i:i+5]}")
assert len(text_bytes) == total, "Text byte count mismatch" assert len(text_bytes) == total, "Text byte count mismatch"
# === 编码字符 RLE === # === 编码字符 RLE ===
char_rle = [] char_rle = []
i = 0 i = 0
while i < total: while i < total:
b = text_bytes[i] b = text_bytes[i]
j = i j = i
while j < total and text_bytes[j] == b and (j - i + 1) <= 255: while j < total and text_bytes[j] == b and (j - i + 1) <= 255:
j += 1 j += 1
count = j - i count = j - i
char_rle.extend([b, count]) char_rle.extend([b, count])
i = j i = j
# === 构建颜色流 === # === 构建颜色流 ===
color_stream = [] color_stream = []
for y in range(height): for y in range(height):
fg_row = frame["foreground"][y] fg_row = frame["foreground"][y]
bg_row = frame["background"][y] bg_row = frame["background"][y]
assert len(fg_row) == len(bg_row) == width, f"Row {y} length mismatch" assert len(fg_row) == len(bg_row) == width, f"Row {y} length mismatch"
for x in range(width): for x in range(width):
fg = int(fg_row[x], 16) & 0x0F fg = int(fg_row[x], 16) & 0x0F
bg = int(bg_row[x], 16) & 0x0F bg = int(bg_row[x], 16) & 0x0F
color_stream.append((bg << 4) | fg) color_stream.append((bg << 4) | fg)
assert len(color_stream) == total assert len(color_stream) == total
# === 编码颜色 RLE === # === 编码颜色 RLE ===
color_rle = [] color_rle = []
i = 0 i = 0
while i < total: while i < total:
c = color_stream[i] c = color_stream[i]
j = i j = i
while j < total and color_stream[j] == c and (j - i + 1) <= 255: while j < total and color_stream[j] == c and (j - i + 1) <= 255:
j += 1 j += 1
count = j - i count = j - i
color_rle.extend([c, count]) color_rle.extend([c, count])
i = j i = j
# === 调色板 === # === 调色板 ===
palette_bytes = [] palette_bytes = []
for rgb in frame["palette"]: for rgb in frame["palette"]:
assert len(rgb) == 3 assert len(rgb) == 3
r, g, b = rgb r, g, b = rgb
assert 0 <= r <= 255 and 0 <= g <= 255 and 0 <= b <= 255 assert 0 <= r <= 255 and 0 <= g <= 255 and 0 <= b <= 255
palette_bytes.extend([r, g, b]) palette_bytes.extend([r, g, b])
assert len(palette_bytes) == 48 assert len(palette_bytes) == 48
# === 拼接二进制数据 === # === 拼接二进制数据 ===
header = b'\x00\x00\x00\x00' + struct.pack('<HH', width, height) + b'\x00' * 8 header = b'\x00\x00\x00\x00' + struct.pack('<HH', width, height) + b'\x00' * 8
body = bytes(char_rle) + bytes(color_rle) + bytes(palette_bytes) body = bytes(char_rle) + bytes(color_rle) + bytes(palette_bytes)
full_data = header + body full_data = header + body
# === 自定义 Base64 编码 === # === 自定义 Base64 编码 ===
b64 = "" b64 = ""
val = 0 val = 0
bits = 0 bits = 0
for byte in full_data: for byte in full_data:
val = (val << 8) | byte val = (val << 8) | byte
bits += 8 bits += 8
while bits >= 6: while bits >= 6:
bits -= 6 bits -= 6
b64 += B64STR[(val >> bits) & 0x3F] b64 += B64STR[(val >> bits) & 0x3F]
if bits: if bits:
b64 += B64STR[(val << (6 - bits)) & 0x3F] b64 += B64STR[(val << (6 - bits)) & 0x3F]
# 补齐到 4 的倍数(虽然 CC 可能不检查,但保持兼容) # 补齐到 4 的倍数(虽然 CC 可能不检查,但保持兼容)
while len(b64) % 4: while len(b64) % 4:
b64 += '=' b64 += '='
# 使用 !CPD 格式12 位十六进制长度) # 使用 !CPD 格式12 位十六进制长度)
hex_len = f"{len(b64):012x}" hex_len = f"{len(b64):012x}"
return f"!CPD{hex_len}{b64}" return f"!CPD{hex_len}{b64}"
def vid_to_json(vid_path, json_path): def vid_to_json(vid_path, json_path):
with open(vid_path, 'r', encoding='latin1') as f: with open(vid_path, 'r', encoding='latin1') as f:
lines = [line.rstrip('\n\r') for line in f] lines = [line.rstrip('\n\r') for line in f]
if not lines or lines[0] != "32Vid 1.1": if not lines or lines[0] != "32Vid 1.1":
raise ValueError("Not a valid .32vid file: missing header") raise ValueError("Not a valid .32vid file: missing header")
fps_str = lines[1] if len(lines) > 1 else "0" fps_str = lines[1] if len(lines) > 1 else "0"
try: try:
fps = float(fps_str) fps = float(fps_str)
except ValueError: except ValueError:
fps = 0.0 fps = 0.0
frame_lines = [] frame_lines = []
for line in lines[2:]: for line in lines[2:]:
if line.strip() == "": if line.strip() == "":
continue continue
if line.startswith("!CP"): if line.startswith("!CP"):
frame_lines.append(line) frame_lines.append(line)
frames = [] frames = []
for line in frame_lines: for line in frame_lines:
mode = line[3] mode = line[3]
if mode == 'C': if mode == 'C':
length = int(line[4:8], 16) length = int(line[4:8], 16)
b64data = line[8:8 + length] b64data = line[8:8 + length]
elif mode == 'D': elif mode == 'D':
length = int(line[4:16], 16) length = int(line[4:16], 16)
b64data = line[16:16 + length] b64data = line[16:16 + length]
else: else:
raise ValueError(f"Unknown frame mode: {mode}") raise ValueError(f"Unknown frame mode: {mode}")
binary_data = custom_b64decode(b64data) binary_data = custom_b64decode(b64data)
frame = decode_frame(binary_data) frame = decode_frame(binary_data)
frames.append(frame) frames.append(frame)
result = { result = {
"header": { "header": {
"magic": "32Vid 1.1", "magic": "32Vid 1.1",
"fps": fps "fps": fps
}, },
"frames": frames "frames": frames
} }
with open(json_path, 'w', encoding='utf-8') as f: with open(json_path, 'w', encoding='utf-8') as f:
json.dump(result, f, indent=2, ensure_ascii=False) json.dump(result, f, indent=2, ensure_ascii=False)
def json_to_vid(json_path, vid_path): def json_to_vid(json_path, vid_path):
with open(json_path, 'r', encoding='utf-8') as f: with open(json_path, 'r', encoding='utf-8') as f:
data = json.load(f) data = json.load(f)
fps = data["header"]["fps"] fps = data["header"]["fps"]
frames = data["frames"] frames = data["frames"]
with open(vid_path, 'w', encoding='latin1') as f: with open(vid_path, 'w', encoding='latin1') as f:
f.write("32Vid 1.1\n") f.write("32Vid 1.1\n")
f.write(f"{fps}\n") f.write(f"{fps}\n")
for frame in frames: for frame in frames:
line = encode_frame(frame) line = encode_frame(frame)
f.write(line + "\n") f.write(line + "\n")
# ====================== # ======================
# CLI 入口 # CLI 入口
# ====================== # ======================
def main(): def main():
if len(sys.argv) != 4: if len(sys.argv) != 4:
print("Usage:") print("Usage:")
print(" python 32vid_converter.py to-json input.32vid output.json") print(" python 32vid_converter.py to-json input.32vid output.json")
print(" python 32vid_converter.py to-vid input.json output.32vid") print(" python 32vid_converter.py to-vid input.json output.32vid")
sys.exit(1) sys.exit(1)
command = sys.argv[1] command = sys.argv[1]
input_path = sys.argv[2] input_path = sys.argv[2]
output_path = sys.argv[3] output_path = sys.argv[3]
if command == "to-json": if command == "to-json":
vid_to_json(input_path, output_path) vid_to_json(input_path, output_path)
print(f"✅ Converted: {input_path}{output_path}") print(f"✅ Converted: {input_path}{output_path}")
elif command == "to-vid": elif command == "to-vid":
json_to_vid(input_path, output_path) json_to_vid(input_path, output_path)
print(f"✅ Converted: {input_path}{output_path}") print(f"✅ Converted: {input_path}{output_path}")
else: else:
print(f"❌ Unknown command: {command}") print(f"❌ Unknown command: {command}")
sys.exit(1) sys.exit(1)
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@@ -1,53 +0,0 @@
-- 压缩函数
function rleCompress(str)
local result = {}
local i = 1
while i <= #str do
local char = str:sub(i, i)
local count = 1
while i + count <= #str and str:sub(i + count, i + count) == char do
count = count + 1
end
if count > 2 then
table.insert(result, ("[%d]%s"):format(count, char))
else
table.insert(result, char:rep(count))
end
i = i + count
end
return table.concat(result)
end
-- 解压函数
function rleDecompress(str)
local result = {}
local i = 1
while i <= #str do
if str:sub(i, i) == "[" then
local j = str:find("]", i)
local num = tonumber(str:sub(i+1, j-1))
local char = str:sub(j+1, j+1)
table.insert(result, char:rep(num))
i = j + 2
else
table.insert(result, str:sub(i, i))
i = i + 1
end
end
return table.concat(result)
end
-- 测试
file = fs.open("1.bimg","r")
original = file.readAll()
file.close()
local compressed = rleCompress(original)
print("原始:", original)
print("压缩:", compressed)
print("解压:", rleDecompress(compressed))
file = fs.open("12.bimg","w")
file.write(compressed)
file.close()

48
player-hb.lua Normal file
View File

@@ -0,0 +1,48 @@
local b64str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
local logostr = [[
32Vid 1.1
12
!CPC009CAAAAAA8ADQAAAAAAAAAAACApnwEgG5ABIAKfASALiwKQASANggGDASBdAClAAQAbAgEAAhABAAsCASABAgEADQICAF0AAAAHBwf///8LCwsODg4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=b7cd0256
!CPC009CAAAAAA8ADQAAAAAAAAAAACApnwEgG5ABIAKfASAMiwGQASAMnwGHAYMBIF0AKUABABsCAQACEAEACyACAgEADAIDAF0AAAAHBwf///8LCwsODg4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=2b710733
!CPC00E8AAAAAA8ADQAAAAAAAAAAACApnwEgG5ABIAKfASAMiwGQASAMnwGHAYMBIAqIAYcBmAEgAZ8BIAmfAYEBIAKfAYEBIAqDAYsBhwEgMgApoAEAGwgBAAJwAQALgAIIAQAMaAMACgUBYAFkAWABBgEACWABYQFgAgYCAAoGAwAyAAAAEhIS4+Tl5ubn5eXmBAQE5OTlBwcH/v7+CwsLDQ0NAAAAAAAAAAAAAAAAAAAA08f91bff
!CPC00FCAAAAAA8ADQAAAAAAAAAAACApnwEgG5ABIAKfASAMiwGQASAMnwGHAYMBIAuHASACnwEgCZ8BgQEgAp8BgQEgCIcBIAOHASAJlQEgAp8BgQEgCoIBgwIgFwApUAEAGwMBAAIgAQALMAIDAQAMEwMACxADAQEACRAEAQIACBAEAQEACRADAQIACgEDABcAAADk5OQHBwf+/v4LCwsODg4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=0a11a2a8
!CPC0150AAAAAA8ADQAAAAAAAAAAACAjgQEgBZ8BIAaIAYQBIA2PASAFkAEgAp8BIAaCAYsBIASLAZABIAmCAYsBkAGfAYcBgwEgBoIBjwEgA4cBIAKfASAJnAGBASACnwGBASAIhwEgA4cBIAmVASACnwGBASAKggGDAiAXACMHAQAFYAEABgcCAA1AAQAFAwEAAiABAAVAAwADMAIDAQAGQAUEARMDAAYEAkADFAEQAgEBAAlAARQBEAIBAgAIEAQBAQAJEAMBAgAKAQMAFwAAAOTk5AcHB/7+/ru5uQsLCw4ODgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==3d1b8cf9
!CPC0160AAAAAA8ADQAAAAAAAAAAACAlnwGDASACnwEgCIcBgQGaAYUBIAmDASAEnwGQASACnwEgCIcBgQEgAosBkAEgCYIBiwGQAZ8BhwGDASAGggGPASADhwEgAp8BIAmcAYEBIAKfAYEBIAiHASADhwEgCZUBIAKfAYEBIAqCAYMCIBfwJR8B7wHwAj8B8AjvApYBdQHwCe8B4AT+AfIB8AIfAfAF4AP+AvABIAEvAfIB8AbgA+8C/gECA/AG/gLgAw4BAALwCu8BDgEAAvAKDwEAA/AKDwEAAvAm5OTkBQUF/v7+DAwMw8LDy8vMu7m6wcDBtbOzy8rLxsXGxsXHycjKycnKu7m5AAAAb1c34e98
!CPC0170AAAAAA8ADQAAAAAAAAAAACAYnwEgDJ8BgwGVAYIBiwEgCIcBgQEgApUBnwGBASAGgwEgBJ8BkAEgAp8BIAiHAYEBIAKLAZABIAmCAYsBkAGfAYcBgwEgBoIBjwEgA4cBIAKfASAJnAGBASACnwGBASAIhwEgA4cBIAmVASACnwGBASAKggGDAiAXABhQAQAMQAJQAwAIQARQAQUCAAZABQQBBQEAAiABAAVAAwQCAAFQAgUBAAZABQQBFQMABgQCQAMUARACAQEACUABFAEQAgECAAgQBAEBAAkQAwECAAoBAwAXAAAA5OTkBQUFEBARu7m5/v7+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAd32547aa
!CPC017CAAAAAA8ADQAAAAAAAAAAACAYnwEgDJ8BgwGVAYIBiwEgCIcBgQEgApUBnwGBAYcBIAWDASAEnwGQASABiwGQASAIhwGBASACiwGQASAJggGLAZABnwGHAYMBIAaCAY8BIAOHASACnwEgCZwBgQEgAp8BgQEgCIcBIAOHASAJlQEgAp8BgQEgCoIBgwIgFwAYQAEADDACQAMACDAEQAEEAkABAAUwBQMBBAEAAQQBQAEABTADAwIAAUACBAEABjAFAwEUAwAGAwIwAxMBEAIBAQAJMAETARACAQIACBAEAQEACRADAQIACgEDABcAAADk5OQTExO7ubn+/v4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=3b77f20a
!CPC0174AAAAAA8ADQAAAAAAAAAAACAXjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAlABcwAUACBAEACDAEQAIEAUABAAUwBgQCQAIABTADAwNAAQQBAAEEAQAFMAQDAQABQAEUARABAAYDATAFFAEQAgAIAwITARADAQEACBAEAQIACBAEAQEACgEEACUAAADk5OQUFBS7ubn+/v4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=e8f01cff
!CPC0168AAAAAA8ADQAAAAAAAAAAACAJlwGQASAKnwGHASABlQEgAZ0BIAePAYEBIAOKAYcBjwGBASAJnwGHAYsBIAGCAYsBIAiRASADggGLASAGkAEgA4IBiwGHAYEBIAiDAY8BIAGfAYEBIAKXASAJhwEgA4cBIAifAYEBIAKfAYEBIAmVASAChwEgNAAJQAEEAQAKMANAAgQBAAcwBQQCQAIABTAEAwJAAQABBAIABTADAwEAAkADAAYwBhQCEAEABwMCMAETAhACAQEACRAEAQEACBAEAQIACRADAQEANAAAAOTk5BISE7u5uf7+/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==71309b9a
!CPC0180AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAIiAGQASAqAAgwAUACBAEACDAEQAIEAUABAAUwBgQCQAIABTADAwNAAQQBAAEEAQAFMAQDAQABQAEUARABAAYDATAFFAEQAgAIAwITARADAQEACBAEAQIACBAEAQEACgEEAAgEAgAqAAAA5OTkEhITu7m5/v7+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA09bec4a6
!CPC01ACAAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABiAEgB58BIAGIAZsBIBeXASAGAAgwAUACBAEACDAEQAIEAUABAAUwBgQCQAIABTADAwNAAQQBAAEEAQAFMAQDAQABQAEUARABAAYDATAFFAEQAgAIAwITARADAQEACBAEAQIACBAEAQEACgEEAAcEBAAHQAEAAQQBQAEAF0ABAAYAAADk5OQSEhO7ubn+/v4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=d150c220
!CPC01D8AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABiAEgBZ8BjAGbAZ8BjAGbAZUBIAefASADggEgCJcBIAGVASAGAAgwAUACBAEACDAEQAIEAUABAAUwBgQCQAIABTADAwNAAQQBAAEEAQAFMAQDAQABQAEUARABAAYDATAFFAEQAgAIAwITARADAQEACBAEAQIACBAEAQEACgEEAAcEBAAFQAEEAUACBAFAAQQBAAdAAQADBAEACEABAAFAAQAGAAAA5OTkExMTu7m5////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0659c669
!CPC0208AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgBZ8BjAGbAZ8BjAGbAZUBIAWfASABnwGCAYQBIAGCAYQBIAGFASACnwEgApUBIAGVASAGAAgwAUACBAEACDAEQAIEAUABAAUwBgQCQAIABTADAwNAAQQBAAEEAQAFMAQDAQABQAEUARABAAYDATAFFAEQAgAIAwITARADAQEACBAEAQIACBAEAQEACgEEAAcEA0ABAAVAAQQBQAIEAUABBAEABUABAAFAAQQCAAEEAgABBAEAAkABAAJAAQABQAEABgAAAOTk5BMTE7u5uf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==96fa278a
!CPC0214AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgBZ8BjAGbAZ8BjAGbAZUBIAKCASAClQEgAZUBggGMAZABggGMAZABmgGQASABnwGQASABlQEgAZUBIAYACDABQAIEAQAIMARAAgQBQAEABTAGBAJAAgAFMAMDA0ABBAEAAQQBAAUwBAMBAAFAARQBEAEABgMBMAUUARACAAgDAhMBEAMBAQAIEAQBAgAIEAQBAQAKAQQABwQDQAEABUABBAFAAgQBQAEEAQACBAEAAkABAAFAAQQGQAEEAQABQAEEAQABQAEAAUABAAYAAADk5OQTExO7ubn///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=4bc7ae74
!CPC0228AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgAp8BhAGfAowBmwGfAYwBmwGVASACigEgApUBIAGVAYIBjAGQAYIBjAGQAZoBjwGEAZ8BjwEgAZUBIAGVASACigEgAooBAAgwAUACBAEACDAEQAIEAUABAAUwBgQCQAIABTADAwNAAQQBAAEEAQAFMAQDAQABQAEUARABAAYDATAFFAEQAgAIAwITARADAQEACBAEAQIACBAEAQEACgEEAAcEA0ABAAJAAQQBQAIEAUACBAFAAQQBAAIEAQACQAEAAUABBAZAAgQBQAIAAUABAAFAAQACBAEAAgQBAAAA5OTkExMTu7m5////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4c7a3588
!CPC023CAAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgAp8BjAGbAZ8BjAGbAZ8BjAGbAZUBIAGQAZUBIAKVASABlQGCAYwBkAGCAYwBkAGaAY8BhQGfAY8BkAGVASABlQEgAZ8BmgEgAZ8BmgEACDABQAIEAQAIMARAAgQBQAEABTAGBAJAAgAFMAMDA0ABBAEAAQQBAAUwBAMBAAFAARQBEAEABgMBMAUUARACAAgDAhMBEAMBAQAIEAQBAgAIEAQBAQAKAQQABwQDQAEAAkABBAFAAgQBQAIEAUABBAEAAQQBQAEAAkABAAFAAQQGQAIEAUACBAFAAQABQAEAAUABBAEAAUABBAEAAADk5OQTExO7ubn///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=c37eac4a
!CPC023CAAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgAp8BjAGbAZ8BjAGbAZ8BjAGbAZUBnwGQAZUBIAKVASABlQGCAYwBkAGCAYwBkAGaAY8BhQGdAY8BkAGVAYMBlAEgAY8BmgEgAY8BmgEACDABQAIEAQAIMARAAgQBQAEABTAGBAJAAgAFMAMDA0ABBAEAAQQBAAUwBAMBAAFAARQBEAEABgMBMAUUARACAAgDAhMBEAMBAQAIEAQBAgAIEAQBAQAKAQQABwQDQAEAAkABBAFAAgQBQAIEAUABBAFAAQQBQAEAAkABAAFAAQQGQAIEAUACBAFAAQQBQAEAAUABBAEAAUABBAEAAADk5OQTExO7ubn///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=dbdd3396
]]
local lines, lineIndex = {}, 1; for line in logostr:gmatch("[^\r\n]+") do table.insert(lines, line) end; local readLine = function() local line = lines[lineIndex]; lineIndex = lineIndex + 1; return line end; if readLine() ~= "32Vid 1.1" then error("Unsupported file") end; local fps = tonumber(readLine()); local first, second = readLine(), readLine(); if second == "" or second == nil then fps = 0 end
term.clear()
local fi = 1
while true do
local f;if first then f,first=first,nil elseif second then f,second=second,nil else f=readLine()end;if f==""or f==nil then break end;local m=f:match("^!CP([CD])");if not m then error("Invalid file")end;local d;if m=="C"then local l=tonumber(f:sub(5,8),16);d=f:sub(9,l+8)else local l=tonumber(f:sub(5,16),16);d=f:sub(17,l+16)end;local function b64dec(s)local r="";for c in s:gmatch"...."do if c:sub(3,4)=="=="then r=r..string.char(bit32.bor(bit32.lshift(b64str:find(c:sub(1,1))-1,2),bit32.rshift(b64str:find(c:sub(2,2))-1,4)))elseif c:sub(4,4)=="="then local n=(b64str:find(c:sub(1,1))-1)*4096+(b64str:find(c:sub(2,2))-1)*64+(b64str:find(c:sub(3,3))-1);r=r..string.char(bit32.extract(n,10,8))..string.char(bit32.extract(n,2,8))else local n=(b64str:find(c:sub(1,1))-1)*262144+(b64str:find(c:sub(2,2))-1)*4096+(b64str:find(c:sub(3,3))-1)*64+(b64str:find(c:sub(4,4))-1);r=r..string.char(bit32.extract(n,16,8))..string.char(bit32.extract(n,8,8))..string.char(bit32.extract(n,0,8))end end;return r end;local dt=b64dec(d);assert(dt:sub(1,4)=="\0\0\0\0"and dt:sub(9,16)=="\0\0\0\0\0\0\0\0","Invalid file");local w,h=("HH"):unpack(dt,5);if w<=0 or h<=0 then break end;local c,n,p=string.unpack("c1B",dt,17);local tl={};local ch=c:byte();for y=1,h do local l="";for x=1,w do l=l..string.char(ch);n=n-1;if n==0 then c,n,p=string.unpack("c1B",dt,p);ch=c:byte()end end;tl[y]=l end;local fl,bl={},{};
for y=1,h do local fg,bg="","";for x=1,w do fg=fg..("%x"):format(bit32.band(ch,0x0F));bg=bg..("%x"):format(bit32.rshift(ch,4));n=n-1;if n==0 then ch,n,p=string.unpack("BB",dt,p)end end;fl[y]=fg;bl[y]=bg end;local tw,th=term.getSize();local sx=math.max(1,math.floor((tw-w)/2)+1);local sy=math.max(1,math.floor((th-h)/2)+1);local dh=math.min(h,th-sy+1);local dw=math.min(w,tw-sx+1);if dh>0 and dw>0 then for y=1,dh do local tx=string.sub(tl[y],1,dw);local fg=string.sub(fl[y],1,dw);local bg=string.sub(bl[y],1,dw);term.setCursorPos(sx,sy+y-1);term.blit(tx,fg,bg)end end;p=p-2;for i=0,15 do local r,g,b;r,g,b,p=string.unpack("BBB",dt,p);term.setPaletteColor(2^i,r/255,g/255,b/255)end;if fps==0 then read();break else sleep(1/fps)end
if fi == 8 then sleep(0.5) end
fi = fi+1
end
sleep(1.5)
-- Restore default palette
for i = 0, 15 do term.setPaletteColor(2^i, term.nativePaletteColor(2^i)) end
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1, 1)
shell.run("shell")

48
player-qc.lua Normal file
View File

@@ -0,0 +1,48 @@
local b64str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
local logostr = [[
32Vid 1.1
12
!CPC0088AAAAAA8ADQAAAAAAAAAAACBFkAEgDosCkAEgDYIBgwEgXQBFAgEADgEBIAECAQANAgIAXQAAACDUrAvUpwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==aee8912c
!CPC0090AAAAAA8ADQAAAAAAAAAAACBFkAEgDoIBiwGQASALnwKHAYMBIF0ARQMBAA4yATABAwEACxABAwMAXQAAAAgICSLUrQnUpwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==54cba36e
!CPC00C8AAAAAA8ADQAAAAAAAAAAACBFkAEgDoIBiwGQASAMnwGHAYMBIAuHASACnwEgCZ8BgQEgAp8BgQEgCoMBiwGHASAyAEUDAQAOMgEwAQMBAAwTAwALEAMBAQAJEAQBAgAKAQMAMgAAAAqlnyHTrAnTpwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==66c61a81
!CPC00ECAAAAAA8ADQAAAAAAAAAAACBFkAEgDoIBiwGQASAMnwGHAYMBIAuHASACnwEgCZ8BgQEgAp8BgQEgCIcBIAOHASAJlQEgAp8BgQEgCoIBgwIgFwBFAwEADjIBMAEDAQAMEwMACxADAQEACRAEAQIACBAEAQEACRADAQIACgEDABcAAAAKpZ8f06wJ06cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=237cdd0f
!CPC0124AAAAAA8ADQAAAAAAAAAAACA/jwEgBZABIAmCAYsBIAOCAYsBkAEgCYIBiwGPAZ8BhwGDASAGggGPASADhwEgAp8BIAmfAYEBIAKfAYEBIAiHASADhwEgCZUBIAKfAYEBIAqCAYMCIBcAP0ABAAUDAQAIQAMAAzIBMAEDAQAGQAYTAwAGBAJAAxQBEAIBAQAJQAEUARACAQIACBAEAQEACRADAQIACgEDABcAAAAKpZ8f06wJ06ckAIMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=1281e843
!CPC0144AAAAAA8ADQAAAAAAAAAAACAlnwGDASALhwGBASALgwEgBJ8BkAEgC4cBgQEgAYIBiwGQASAJggGLAY8BnwGHAYMBIAaCAY8BIAOHASACnwEgCZ8BgQEgAp8BgQEgCIcBIAOHASAJlQEgAp8BgQEgCoIBgwIgFwAlQAIAC0AEAAlABQQBAwEACEADBAIAATIBMAEDAQAGQAYTAwAGBAJAAxQBEAIBAQAJQAEUARACAQIACBAEAQEACRADAQIACgEDABcAAAAKpZ8f06wJ06ckAIMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=1ca3632d
!CPC0168AAAAAA8ADQAAAAAAAAAAACAYnwEgDJ8BgwGVAYIBiwEgCIcBgQEgApUBnwGBASAGgwEgBJ8BkAEgC4cBgQEgAYIBiwGQASAJggGLAY8BnwGHAYMBIAaCAY8BIAOHASACnwEgCZ8BgQEgAp8BgQEgCIcBIAOHASAJlQEgAp8BgQEgCoIBgwIgFwAYYAEADFACYAMACFAEYAEGAgAGUAUFAQMBAAhQAwUCAAEyATABAwEABlAGEwMABgUCUAMVARACAQEACVABFQEQAgECAAgQBAEBAAkQAwECAAoBAwAXAAAACaWfDNioCdSnBwITJACDCv6vAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7f1066b0
!CPC0180AAAAAA8ADQAAAAAAAAAAACAYnwEgDJ8BgwGVAYIBiwEgCIcBgQEgApUBnwGBAYcBIAWDASAEnwGQASABiwGQASAIhwGBASABggGLAZABIAmCAYsBjwGfAYcBgwEgBoIBjwEgA4cBIAKfASAJnwGBASACnwGBASAIhwEgA4cBIAmVASACnwGBASAKggGDAiAXABhgAQAMUAJgAwAIUARgAQYCYAEABVAFBQEDAQABBgFgAQAFUAMFAgABMgEwAQMBAAZQBhMDAAYFAlADFQEQAgEBAAlQARUBEAIBAgAIEAQBAQAJEAMBAgAKAQMAFwAAAAmlnw3XqAnUpwcCFCQAgwr+rwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==85fb6a05
!CPC0178AAAAAA8ADQAAAAAAAAAAACAXjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASfAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAlABdQAWACBgEACFAEYAIGAWABAAVQBgYCYAIABVADBQMwAQMBAAEGAQAFUAQFAQABMAETARABAAYFAVAEFQETARACAAgFAhUBEAMBAQAIEAQBAgAIEAQBAQAKAQQAJQAAAAqlnw/WqQnUpwUBDyQAhAr+rwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==886211b1
!CPC0168AAAAAA8ADQAAAAAAAAAAACAJlwGQASAKnwGHASABlQEgAZ0BIAePAYEBIAOKAYcBjwGBASAJnwGHAYsBIAGCAYsBIAiRASADggGLASAGkAEgA4IBgwGHAYEBIAiDAY8BIAGfAYEBIAKXASAJhwEgA4cBIAifAYEBIAKfAYEBIAmVASAChwEgNAAJYAEGAQAKUANgAgYBAAdQBQYCYAIABVAEBQIwAQABBgIABVADBQEAAjADAAZQBhMCEAEABwUCUAEVAhACAQEACRAEAQEACBAEAQIACRADAQEANAAAAAqlnwvYqAnUpwIACiQAhAr+rwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==e5413615
!CPC0180AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASfASALgwGPAYcBIAOFASAInwGBASACnwGBASAIlwEgA4cBIAqKAY8CgQEgCIgBkAEgKgAIYAFwAgcBAAhgBHACBwFwAQAFYAYHAnACAAVgAwYDQAEEAQABBwEABWAEBgEAAUABJAEgAQAGBgFgBCYBIAMACAYCJgEgAwIBAAggBAICAAggBAIBAAoCBAAIAQIAKgAAAP///wmlnwrXqAnUpw8KHiQAhAr+rgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==15b0c7c0
!CPC01B0AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASfAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABiAEgB58BIAGIAZsBIBeXASAGAAhgAXACBwEACGAEcAIHAXABAAVgBgcCcAIABWADBgNAAQQBAAEHAQAFYAQGAQABQAEkASABAAYGAWAEJgEkASACAAgGAiYBIAMCAQAIIAQCAgAIIAQCAQAKAgQABwEEAAcQAQABAQEQAQAXEAEABgAAAP///wmlnwrXqAnUpw8KHiQAhAr+rgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==207a1880
!CPC01DCAAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASfAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABiAEgBZ8BjAGbAZ8BjAGbAZUBIAefASADggEgCJcBIAGVASAGAAhgAXACBwEACGAEcAIHAXABAAVgBgcCcAIABWADBgNAAQQBAAEHAQAFYAQGAQABQAEkASABAAYGAWAEJgEkASACAAgGAiYBIAMCAQAIIAQCAgAIIAQCAQAKAgQABwEEAAUQAQEBEAIBARABAQEABxABAAMBAQAIEAEAARABAAYAAAD///8JpZ8K16gJ1KcPCh8kAIQK/q4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=15b84ecc
!CPC0208AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASfAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgBZ8BjAGbAZ8BjAGbAZUBIAWfASABnwGCAYQBIAGCAYQBIAGFASACnwEgApUBIAGVASAGAAhgAXACBwEACGAEcAIHAXABAAVgBgcCcAIABWADBgNAAQQBAAEHAQAFYAQGAQABQAEkASABAAYGAWAEJgEkASACAAgGAiYBIAMCAQAIIAQCAgAIIAQCAQAKAgQABwEDEAEABRABAQEQAgEBEAEBAQAFEAEAARABAQIAAQECAAEBAQACEAEAAhABAAEQAQAGAAAA////CaWfCteoCdSnDwofJACECv6uAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA48b5ed0d
!CPC0218AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASfAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgBZ8BjAGbAZ8BjAGbAZUBIAKCASAClQEgAZUBggGMAZABggGMAZABmgGQASABnwGQASABlQEgAZUBIAYACGABcAIHAQAIYARwAgcBcAEABWAGBwJwAgAFYAMGA0ABBAEAAQcBAAVgBAYBAAFAASQBIAEABgYBYAQmASQBIAIACAYCJgEgAwIBAAggBAICAAggBAIBAAoCBAAHAQMQAQAFEAEBARACAQEQAQEBAAIBAQACEAEAARABAQYQAQEBAAEQAQEBAAEQAQABEAEABgAAAP///wmlnwrXqAnUpwoIDyQAhAr+rgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==548cda66
!CPC022CAAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASfAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgAp8BhAGfAowBmwGfAYwBmwGVASACigEgApUBIAGVAYIBjAGQAYIBjAGQAZoBjwGEAZ8BjwEgAZUBIAGVASACigEgAooBAAhgAXACBwEACGAEcAIHAXABAAVgBgcCcAIABWADBgNAAQQBAAEHAQAFYAQGAQABQAEkASABAAYGAWAEJgEkASACAAgGAiYBIAMCAQAIIAQCAgAIIAQCAQAKAgQABwEDEAEAAhABAQEQAgEBEAIBARABAQEAAgEBAAIQAQABEAEBBhACAQEQAgABEAEAARABAAIBAQACAQEAAAD///8JpZ8K16gJ1KcKCA8kAIQK/q4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=f0226c54
!CPC0240AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASfAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgAp8BjAGbAZ8BjAGbAZ8BjAGbAZUBIAGQAZUBIAKVASABlQGCAYwBkAGCAYwBkAGaAY8BhQGfAY8BkAGVASABlQEgAZ8BmgEgAZ8BmgEACGABcAIHAQAIYARwAgcBcAEABWAGBwJwAgAFYAMGA0ABBAEAAQcBAAVgBAYBAAFAASQBIAEABgYBYAQmASQBIAIACAYCJgEgAwIBAAggBAICAAggBAIBAAoCBAAHAQMQAQACEAEBARACAQEQAgEBEAEBAQABAQEQAQACEAEAARABAQYQAgEBEAIBARABAAEQAQABEAEBAQABEAEBAQAAAP///wmlnwrXqAnUpwoIDyQAhAr+rgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==9585a281
!CPC0240AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASfAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgAp8BjAGbAZ8BjAGbAZ8BjAGbAZUBnwGQAZUBIAKVASABlQGCAYwBkAGCAYwBkAGaAY8BhQGdAY8BkAGVAYMBlAEgAY8BmgEgAY8BmgEACGABcAIHAQAIYARwAgcBcAEABWAGBwJwAgAFYAMGA0ABBAEAAQcBAAVgBAYBAAFAASQBIAEABgYBYAQmASQBIAIACAYCJgEgAwIBAAggBAICAAggBAIBAAoCBAAHAQMQAQACEAEBARACAQEQAgEBEAEBARABAQEQAQACEAEAARABAQYQAgEBEAIBARABAQEQAQABEAEBAQABEAEBAQAAAP///wmlnwrXqAnUpwoIDyQAhAr+rgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==9d0fbd72
]]
local lines, lineIndex = {}, 1; for line in logostr:gmatch("[^\r\n]+") do table.insert(lines, line) end; local readLine = function() local line = lines[lineIndex]; lineIndex = lineIndex + 1; return line end; if readLine() ~= "32Vid 1.1" then error("Unsupported file") end; local fps = tonumber(readLine()); local first, second = readLine(), readLine(); if second == "" or second == nil then fps = 0 end
term.clear()
local fi = 1
while true do
local f;if first then f,first=first,nil elseif second then f,second=second,nil else f=readLine()end;if f==""or f==nil then break end;local m=f:match("^!CP([CD])");if not m then error("Invalid file")end;local d;if m=="C"then local l=tonumber(f:sub(5,8),16);d=f:sub(9,l+8)else local l=tonumber(f:sub(5,16),16);d=f:sub(17,l+16)end;local function b64dec(s)local r="";for c in s:gmatch"...."do if c:sub(3,4)=="=="then r=r..string.char(bit32.bor(bit32.lshift(b64str:find(c:sub(1,1))-1,2),bit32.rshift(b64str:find(c:sub(2,2))-1,4)))elseif c:sub(4,4)=="="then local n=(b64str:find(c:sub(1,1))-1)*4096+(b64str:find(c:sub(2,2))-1)*64+(b64str:find(c:sub(3,3))-1);r=r..string.char(bit32.extract(n,10,8))..string.char(bit32.extract(n,2,8))else local n=(b64str:find(c:sub(1,1))-1)*262144+(b64str:find(c:sub(2,2))-1)*4096+(b64str:find(c:sub(3,3))-1)*64+(b64str:find(c:sub(4,4))-1);r=r..string.char(bit32.extract(n,16,8))..string.char(bit32.extract(n,8,8))..string.char(bit32.extract(n,0,8))end end;return r end;local dt=b64dec(d);assert(dt:sub(1,4)=="\0\0\0\0"and dt:sub(9,16)=="\0\0\0\0\0\0\0\0","Invalid file");local w,h=("HH"):unpack(dt,5);if w<=0 or h<=0 then break end;local c,n,p=string.unpack("c1B",dt,17);local tl={};local ch=c:byte();for y=1,h do local l="";for x=1,w do l=l..string.char(ch);n=n-1;if n==0 then c,n,p=string.unpack("c1B",dt,p);ch=c:byte()end end;tl[y]=l end;local fl,bl={},{};
for y=1,h do local fg,bg="","";for x=1,w do fg=fg..("%x"):format(bit32.band(ch,0x0F));bg=bg..("%x"):format(bit32.rshift(ch,4));n=n-1;if n==0 then ch,n,p=string.unpack("BB",dt,p)end end;fl[y]=fg;bl[y]=bg end;local tw,th=term.getSize();local sx=math.max(1,math.floor((tw-w)/2)+1);local sy=math.max(1,math.floor((th-h)/2)+1);local dh=math.min(h,th-sy+1);local dw=math.min(w,tw-sx+1);if dh>0 and dw>0 then for y=1,dh do local tx=string.sub(tl[y],1,dw);local fg=string.sub(fl[y],1,dw);local bg=string.sub(bl[y],1,dw);term.setCursorPos(sx,sy+y-1);term.blit(tx,fg,bg)end end;p=p-2;for i=0,15 do local r,g,b;r,g,b,p=string.unpack("BBB",dt,p);term.setPaletteColor(2^i,r/255,g/255,b/255)end;if fps==0 then read();break else sleep(1/fps)end
if fi == 8 then sleep(0.5) end
fi = fi+1
end
sleep(1.5)
-- Restore default palette
for i = 0, 15 do term.setPaletteColor(2^i, term.nativePaletteColor(2^i)) end
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1, 1)
shell.run("shell")

View File

@@ -1,47 +0,0 @@
local b64str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
local logostr = [[
32Vid 1.1
12
!CPC0078AAAAAA8ADQAAAAAAAAAAACBFkAEgDosCkAEgDYIBgwEgXfBVDwHwbf///////////////////////////////////////////////////////////wAAAA==d0775422
!CPC00C4AAAAAA8ADQAAAAAAAAAAACBFkAEgD4sBkAEgDJ8BhwGDASALhwEgAp8BIAmfAYEBIAKfAYEBIAqDAYsBhwEgMvBUIAEvAfIB8AwSA/ALHwEQAvEB8AkfAhAC8QLwCvED8DL////k5OX+/v7///////////////////////////////////////////////8AAAA=ff87384c
!CPC00F0AAAAAA8ADQAAAAAAAAAAACBFkAEgD4sBkAEgDJ8BhwGDASALhwEgAp8BIAmfAYEBIAKfAYEBIAiHASADhwEgCZUBIAKfAYEBIAqCAYMCIBfwVCABLwHyAfAMEgPwCx8BEALxAfAJHwIQAvEC8AgfARAD8QHwCR8BEALxAvAK8QPwF////+Tk5P7+/v///////////////////////////////////////////////wAAAA==e0e51196
!CPC0128AAAAAA8ADQAAAAAAAAAAACA/jwEgBZABIAmCAYsBIASLAZABIAmCAYsBkAGfAYcBgwEgBoIBjwEgA4cBIAKfASAJnAGBASACnwGBASAIhwEgA4cBIAmVASACnwGBASAKggGDAiAX8D/fAfAO0AHfAvADIAEvAfIB8AbQA98C/QESA/AG/QLQAx0BEALxAfAJ3wEdARAC8QLwCB8BEAPxAfAJHwEQAvEC8ArxA/AX////5OTk/v7+////////////////////////////////////////u7m5////AAAA761d642a
!CPC015CAAAAAA8ADQAAAAAAAAAAACAlnwGDASALhwGBAZoBnwEgCYMBIASfAZABIAuHAYEBIAGBAYsBkAEgCYIBiwGQAZ8BhwGDASAGggGPASADhwEgAp8BIAmcAYEBIAKfAYEBIAiHASADhwEgCZUBIAKfAYEBIAqCAYMCIBfwJd8BzwHwC88C3AHNAfAJzwHABPwB8AnAA/wC8AEgAS8B8gHwBsADzwL8ARID8Ab8AsADHAEQAvEB8AnPARwBEALxAvAIHwEQA/EB8AkfARAC8QLwCvED8Bf////k5OT+/v7///////////////////////////////////+6uLjGxcb///8AAAA=65ab8982
!CPC0178AAAAAA8ADQAAAAAAAAAAACAYnwEgDJ8BgwGVAYIBiwEgCIcBgQEgApUBnwGBASAGgwEgBJ8BkAEgC4cBgQEgAYIBiwGQASAJggGLAZABnwGHAYMBIAaCAY8BIAOHASACnwEgCZwBgQEgAp8BgQEgCIcBIAOHASAJlQEgAp8BgQEgCoIBgwIgF/AYHwHwDM8CHwPwCM8CwAIfAfEC8AbPAcAE/AHwCcAD/ALwARABHwHxAfAGwAPPAvwB0QPwBvwCwAPcAdAC/QHwCc8B3AHQAv0C8AjfAdAD/QHwCd8B0AL9AvAK/QPwF/////7+/v///////////////////////////////////////7u5ueTk5P///wAAAA==f6f3bb26
!CPC0188AAAAAA8ADQAAAAAAAAAAACAYnwEgDJ8BgwGVAYIBiwEgCIcBgQEgApUBnwGBAYcBIAWDASAEnwGQASABiwGQASAIhwGBASABggGLAZABIAmCAYsBkAGfAYcBgwEgBoIBjwEgA4cBIAKfASAJnAGBASACnwGBASAIhwEgA4cBIAmVASACnwGBASAKggGDAiAX8BgfAfAMzwIfA/AIzwLAAh8B8QIfAfAFzwHABPwB8AMfAfAFwAP8AvABEAEfAfEB8AbAA88C/AHRA/AG/ALAA9wB0AL9AfAJzwHcAdAC/QLwCN8B0AP9AfAJ3wHQAv0C8Ar9A/AX/////v7+////////////////////////////////////////u7m55OTk////AAAA7d67fd3d
!CPC0188AAAAAA8ADQAAAAAAAAAAACAXjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAl8BfPAR8C8QHwCM8DwAEfARAB8QEfAfAFzwLABPECHwEQAfAFwAP8Ax8B8QHwAfEB8AXAA88B/AHwARAB0QHfAfAG/AHABM8B0QHQAvAI/ALcAdAD/QHwCN8C0AL9AvAI3wHQA/0B8Ar9BPAl/////v7+////////////////////////////////////////u7m55OTk////AAAA2a65ee17
!CPC0180AAAAAA8ADQAAAAAAAAAAACAJlwGQASAKnwGHASABlQEgAZ0BIAePAYEBIAOKAYcBjwGBASAJnwGHAYsBIAGCAYsBIAiRASADggGLASAGkAEgA4IBiwGHAYEBIAiDAY8BIAGfAYEBIAKXASAJhwEgA4cBIAifAYEBIAKfAYEBIAmVASAChwEgNPAJHwHxAfAKzwLAAR8BEAHxAfAHzwLAA/ECHwLwBcAE/AIfAfAB8QLwBcAD/AHwAhABHwLwBs8BwAPPAtEC0AHwB/wCwAHcAtAC/QHwCd8B0AP9AfAI3wLQAv0C8AnfAdAC/QHwNP////7+/v///////////////////////////////////////7u5ueTk5P///wAAAA==a2eea819
!CPC0198AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAIiAGQASAq8AjPAR8C8QHwCM8DwAEfARAB8QEfAfAFzwLABPECHwEQAfAFwAP8Ax8B8QHwAfEB8AXAA88B/AHwARAB0QHfAfAG/AHABM8B0QHQAvAI/ALcAdAD/QHwCN8C0AL9AvAI3wHQA/0B8Ar9BPAI8QLwKv////7+/v///////////////////////////////////////7u5ueTk5P///wAAAA==eb475fdf
!CPC01C0AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABiAEgB58BIAGIAZsBIBeXASAG8AjPAR8C8QHwCM8DwAEfARAB8QEfAfAFzwLABPECHwEQAfAFwAP8Ax8B8QHwAfEB8AXAA88B/AHwARAB0QHfAfAG/AHABM8B0QHQAvAI/ALcAdAD/QHwCN8C0AL9AvAI3wHQA/0B8Ar9BPAH8QTwBx8B8AHxAR8B8BcfAfAG/////v7+////////////////////////////////////////u7m55OTk////AAAA301e73b4
!CPC01D4AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABiAEgBZ8BjAGbAZ8BjAGbAZUBIAefASADggEgCJcBIAGVASAG8AjPAQ8C8AnPA8ABDwEAAfABDwHwBc8CwATwAg8BAAHwBcAD/AMPAfAIwAPPAfwB8AEAAdAB3wHwBvwBwATPAdAD8Aj8AtwB0AP9AfAI3wLQAv0C8AjfAdAD/QHwCv0E8BAPAfABDwLwAQ8B8AgPAfAMDwHwAQ8B8Ab///////////////////////////////////////////////+7ubnk5OT///8AAAA=4b7462bb
!CPC01FCAAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgBZ8BjAGbAZ8BjAGbAZUBIAWfASABnwGCAYQBIAGCAYQBIAGFASACnwEgApUBIAGVASAG8Ai/AQ8C8Am/A7ABDwEAAfABDwHwBb8CsATwAg8BAAHwBbAD+wMPAfAIsAO/AfsB8AEAAdAB3wHwBvsBsAS/AdAD8Aj7AtsB0AP9AfAI3wLQAv0C8AjfAdAD/QHwCv0E8AoPAfAFDwHwAQ8C8AEPAfAGDwHwAQ8B8AkPAfACDwHwAQ8B8Ab///////////////////////////////////////8TExO7ubn////k5OT///8AAAA=2c287f1b
!CPC020CAAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgBZ8BjAGbAZ8BjAGbAZUBIAKCASAClQEgAZUBggGMAZABggGMAZABmgGQASABnwGQASABlQEgAZUBIAbwCL8BDwLwCb8DsAEPAQAB8AEPAfAFvwKwBPACDwEAAfAFsAP7Aw8B8AiwA78B+wHwAQAB0AHfAfAG+wGwBL8B0APwCPsC2wHQA/0B8AjfAtAC/QLwCN8B0AP9AfAK/QTwCg8B8AUPAfABDwLwAQ8B8AYPAfABDwHwBg8B8AIPAfACDwHwAQ8B8Ab///////////////////////////////////////8TExO7ubn////k5OT///8AAAA=5671f063
!CPC0220AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgAp8BhAGfAowBmwGfAYwBmwGVASACigEgApUBIAGVAYIBjAGQAYIBjAGQAZoBjwGEAZ8BjwEgAZUBIAGVASACigEgAooB8Ai/AQ8C8Am/A7ABDwEAAfABDwHwBb8CsATwAg8BAAHwBbAD+wMPAfAIsAO/AfsB8AEAAdAB3wHwBvsBsAS/AdAD8Aj7AtsB0AP9AfAI3wLQAv0C8AjfAdAD/QHwCv0E8AoPAfACDwHwAQ8C8AEPAvABDwHwBg8B8AEPAfAGDwLwAQ8C8AEPAfABDwHwBv///////////////////////////////////////////7u5uf///+Tk5P///wAAAA==de165a07
!CPC0238AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgAp8BjAGbAZ8BjAGbAZ8BjAGbAZUBIAGQAZUBIAKVASABlQGCAYwBkAGCAYwBkAGaAY8BhQGfAY8BkAGVASABlQEgAZ8BmgEgAZ8BmgHwCL8BDwLwCb8DsAEPAQAB8AEPAfAFvwKwBPACDwEAAfAFsAP7Aw8B8AiwA78B+wHwAQABwAHPAfAG+wGwBL8BwAPwCPsCywHAA/wB8AjPAsAC/ALwCM8BwAP8AfAK/ATwCg8B8AIPAfABDwLwAQ8C8AEPAfADDwHwAg8B8AEPAfAGDwLwAQ8C8AEPAfABDwHwAQ8B8AIPAfAB////////////////////////////////////////////u7m55OTk////////AAAAd4c99577
!CPC0240AAAAAA8ADQAAAAAAAAAAACAIjwGVAYsBkAEgCJ8BhwGBASABlQEgAYcBnwEgBY8BgwEgBIIBgQGTASAJnwGHAYEBggGQASABggEgCIsBkAEgAp8BggEgBosBIASCAYEBIAqDAY8BhwEgA4UBIAifAYEBIAKfAYEBIAiXASADhwEgCooBjwKBASAHmAGMAZABlwEgAp8BjAGbAZ8BjAGbAZ8BjAGbAZUBnwGQAZUBIAKVASABlQGCAYwBkAGCAYwBkAGaAY8BhQGdAY8BkAGVAYMBlAEgAY8BmgEgAY8BmgHwCL8BDwLwCb8DsAEPAQAB8AEPAfAFvwKwBPACDwEAAfAFsAP7Aw8B8AiwA78B+wHwAQABwAHPAfAG+wGwBL8BwAPwCPsCywHAA/wB8AjPAsAC/ALwCM8BwAP8AfAK/ATwCg8B8AIPAfABDwLwAQ8C8AEPAfABDwHwAQ8B8AIPAfABDwHwBg8C8AEPAvABDwHwAQ8B8AEPAfACDwHwAf///////////////////////////////////////////7u5ueTk5P///////wAAAA==66b4d14d
]]
local lines, lineIndex = {}, 1; for line in logostr:gmatch("[^\r\n]+") do table.insert(lines, line) end; local readLine = function() local line = lines[lineIndex]; lineIndex = lineIndex + 1; return line end; if readLine() ~= "32Vid 1.1" then error("Unsupported file") end; local fps = tonumber(readLine()); local first, second = readLine(), readLine(); if second == "" or second == nil then fps = 0 end
term.clear()
local fi = 1
while true do
local f;if first then f,first=first,nil elseif second then f,second=second,nil else f=readLine()end;if f==""or f==nil then break end;local m=f:match("^!CP([CD])");if not m then error("Invalid file")end;local d;if m=="C"then local l=tonumber(f:sub(5,8),16);d=f:sub(9,l+8)else local l=tonumber(f:sub(5,16),16);d=f:sub(17,l+16)end;local function b64dec(s)local r="";for c in s:gmatch"...."do if c:sub(3,4)=="=="then r=r..string.char(bit32.bor(bit32.lshift(b64str:find(c:sub(1,1))-1,2),bit32.rshift(b64str:find(c:sub(2,2))-1,4)))elseif c:sub(4,4)=="="then local n=(b64str:find(c:sub(1,1))-1)*4096+(b64str:find(c:sub(2,2))-1)*64+(b64str:find(c:sub(3,3))-1);r=r..string.char(bit32.extract(n,10,8))..string.char(bit32.extract(n,2,8))else local n=(b64str:find(c:sub(1,1))-1)*262144+(b64str:find(c:sub(2,2))-1)*4096+(b64str:find(c:sub(3,3))-1)*64+(b64str:find(c:sub(4,4))-1);r=r..string.char(bit32.extract(n,16,8))..string.char(bit32.extract(n,8,8))..string.char(bit32.extract(n,0,8))end end;return r end;local dt=b64dec(d);assert(dt:sub(1,4)=="\0\0\0\0"and dt:sub(9,16)=="\0\0\0\0\0\0\0\0","Invalid file");local w,h=("HH"):unpack(dt,5);if w<=0 or h<=0 then break end;local c,n,p=string.unpack("c1B",dt,17);local tl={};local ch=c:byte();for y=1,h do local l="";for x=1,w do l=l..string.char(ch);n=n-1;if n==0 then c,n,p=string.unpack("c1B",dt,p);ch=c:byte()end end;tl[y]=l end;local fl,bl={},{};
for y=1,h do local fg,bg="","";for x=1,w do fg=fg..("%x"):format(bit32.band(ch,0x0F));bg=bg..("%x"):format(bit32.rshift(ch,4));n=n-1;if n==0 then ch,n,p=string.unpack("BB",dt,p)end end;fl[y]=fg;bl[y]=bg end;local tw,th=term.getSize();local sx=math.max(1,math.floor((tw-w)/2)+1);local sy=math.max(1,math.floor((th-h)/2)+1);local dh=math.min(h,th-sy+1);local dw=math.min(w,tw-sx+1);if dh>0 and dw>0 then for y=1,dh do local tx=string.sub(tl[y],1,dw);local fg=string.sub(fl[y],1,dw);local bg=string.sub(bl[y],1,dw);term.setCursorPos(sx,sy+y-1);term.blit(tx,fg,bg)end end;p=p-2;for i=0,15 do local r,g,b;r,g,b,p=string.unpack("BBB",dt,p);term.setPaletteColor(2^i,r/255,g/255,b/255)end;if fps==0 then read();break else sleep(1/fps)end
if fi == 7 then sleep(0.5) end
fi = fi+1
end
sleep(1)
-- Restore default palette
for i = 0, 15 do term.setPaletteColor(2^i, term.nativePaletteColor(2^i)) end
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1, 1)
shell.run("shell")

File diff suppressed because one or more lines are too long