BigTerm smoke test 1: enough to show CCPI

This commit is contained in:
Casey 2024-01-18 12:18:05 +03:00
parent 637827c6af
commit 2f889add9b
Signed by: hkc
GPG Key ID: F0F6CFE11CDB0960
5 changed files with 316 additions and 0 deletions

99
bigterm-hello.lua Normal file
View File

@ -0,0 +1,99 @@
local bigterm = require("bigterm")({
{ p = peripheral.wrap("monitor_1"), x = 1, y = 1 },
{ p = peripheral.wrap("monitor_2"), x = 2, y = 1 },
{ p = peripheral.wrap("monitor_3"), x = 1, y = 2 },
{ p = peripheral.wrap("monitor_4"), x = 2, y = 2 },
{ p = peripheral.wrap("monitor_5"), x = 1, y = 3 },
{ p = peripheral.wrap("monitor_6"), x = 2, y = 3 },
}, {
palette = {
[colors.white] = 0xEFEFEF,
[colors.orange] = 0xEF712A,
[colors.magenta] = 0xCF43EA,
[colors.lightBlue] = 0x5643EF,
[colors.yellow] = 0xEFCF42,
[colors.lime] = 0x43FA99,
[colors.pink] = 0xEF7192,
[colors.gray] = 0x676767,
[colors.lightGray] = 0xAAAAAA,
[colors.cyan] = 0x42DFFA,
[colors.blue] = 0x7853FF,
[colors.brown] = 0xb18624,
[colors.green] = 0x00FF00,
[colors.red] = 0xFF0000,
[colors.black] = 0x000000
},
scale = 0.5
})
bigterm._forEachMonitor(function(mon, i)
print(mon.x, mon.y, mon.p.getSize())
end)
--bigterm._blitpixel(1, 21, "A")
local w, h = bigterm.getSize()
print(w, h)
--for y = 1, h do
-- for x = 1, w do
-- bigterm._blitpixel(
-- x,
-- y,
-- string.char((x + y * 16 - 16) % 256),
-- string.format("%x", (x - y) % 16),
-- string.format("%x", (x + y) % 16)
-- )
-- end
--end
bigterm.setTextColor(colors.white)
bigterm.setBackgroundColor(colors.black)
bigterm.clear()
if false then
local lines = require("cc.strings").wrap(io.lines("cc-stuff/beemovie.txt")(), w)
for i, line in ipairs(lines) do
bigterm.setCursorPos(1, i)
bigterm.setTextColor(2 ^ (i % 2))
bigterm.write(line)
if i == h then break end
end
end
for t = 0, 31 do
for y = 1, h do
local res = {}
for x = 0, w do
table.insert(res, string.format("%x", bit.bxor(x, y * t + 1) % 16))
end
res = table.concat(res)
bigterm.setCursorPos(1, y)
bigterm.blit(res, res, string.rep("f", #res))
end
os.sleep(0.05)
end
local ccpi = require("ccpi")
local img = ccpi.load("cc-stuff/cute.cpi")
local ys = {}
for y = 1, img.h do table.insert(ys, y) end
for i = 1, #ys do
local a, b = math.random(1, #ys), math.random(1, #ys)
ys[a], ys[b] = ys[b], ys[a]
end
for i, y in ipairs(ys) do
bigterm.setCursorPos(1, y)
bigterm.blit(img.lines[y].s, img.lines[y].fg, img.lines[y].bg)
os.sleep(0.05)
end
for i = 1, 16 do
bigterm.setPaletteColor(bit.blshift(1, i - 1), img.palette[i])
os.sleep(0.10)
end

217
bigterm.lua Normal file
View File

@ -0,0 +1,217 @@
local expect = require("cc.expect").expect
local function todo() error("todo!") end
local pretty = require "cc.pretty"
local BigTerm = {
write = function(self, text)
local w = self.getSize()
for i = 1, #text do
if self._pos.x <= w then
self._blitpixel(
self._pos.x,
self._pos.y,
text:sub(i, i),
self._colorChar(self._colorForeground),
self._colorChar(self._colorBackground)
)
self._pos.x = self._pos.x + 1
end
end
end,
blit = function(self, text, foreground, background)
local x, y = self._pos.x, self._pos.y
local w = #text
local LIMIT = 0
local ox = 1
while w > 0 and LIMIT < 20 do
local mon, i, lx, ly = self._getMonitorForScreenPos(x, y)
if not mon then break end
local remaining = mon._w - lx
mon.p.setCursorPos(lx + 1, ly + 1)
mon.p.blit(
text:sub(ox, ox + w),
foreground:sub(ox, ox + w - 1),
background:sub(ox, ox + w - 1)
)
w = w - remaining
x = x + remaining
ox = ox + remaining
end
end,
clear = function(self)
self._forEachMonitor(function(mon)
mon.p.clear()
end)
end,
clearLine = function(self) todo() end,
scroll = function(self, n)
-- TODO: NOPE! store framebuffer and write lines onto other screens
self._forEachMonitor(function(mon)
mon.p.scroll(n)
end)
end,
getCursorPos = function(self) return self._pos.x, self._pos.y end,
setCursorPos = function(self, x, y)
self._pos.x = x
self._pos.y = y
-- TODO: move cursor to the correct monitor and hide it from others
end,
setCursorBlink = function(self, state) todo() end,
getCursorBlink = function(self) todo() end,
isColor = function(self) return true end,
getSize = function(self)
local w, h = 0, 0
for ix = 1, self._w do
local mon = self._findMonitor(ix, 1)
w = w + mon._w
end
for iy = 1, self._h do
local mon = self._findMonitor(1, iy)
h = h + mon._h
end
return w, h
end,
setTextColor = function(self, fg)
self._forEachMonitor(function(mon)
mon.p.setTextColor(fg)
end)
self._colorForeground = fg
end,
getTextColor = function(self) todo() end,
setBackgroundColor = function(self, bg)
self._forEachMonitor(function(mon)
mon.p.setBackgroundColor(bg)
end)
self._colorBackground = bg
end,
getBackgroundColor = function(self) todo() end,
setTextScale = function(self, scale)
self._scale = scale
self._reset()
end,
getTextScale = function(self)
return self._scale
end,
setPaletteColor = function(self, index, color, g, b)
expect(1, index, "number")
expect(2, color, "number")
expect(3, g, "number", "nil")
expect(4, b, "number", "nil")
if index < 0 or index > 32768 or math.log(index, 2) % 1 ~= 0 then
error("index out of range")
end
local r = color
if g == nil or b == nil then
if color < 0 or color > 0xFFFFFF then
error("color out of range")
end
r = bit.band(0xFF, bit.brshift(color, 16)) / 255
g = bit.band(0xFF, bit.brshift(color, 8)) / 255
b = bit.band(0xFF, bit.brshift(color, 0)) / 255
else
if r < 0 or r > 1.0 then error("red channel out of range") end
if g < 0 or g > 1.0 then error("green channel out of range") end
if b < 0 or b > 1.0 then error("blue channel out of range") end
end
self._palette[index] = bit.bor(
bit.blshift(math.floor(r * 255), 16),
bit.blshift(math.floor(g * 255), 8),
bit.blshift(math.floor(b * 255), 0)
)
self._forEachMonitor(function(mon)
mon.p.setPaletteColor(index, r, g, b)
end)
end,
getPaletteColor = function(self, index) todo() end,
-- internals
_colorChar = function(self, v)
return string.format("%x", math.floor(math.log(v, 2)))
end,
_reset = function(self)
self._w = 1
self._h = 1
self._forEachMonitor(function(mon, i)
mon.p.setTextScale(self._scale)
local w, h = mon.p.getSize()
self._monitors[i]._w = w
self._monitors[i]._h = h
if mon.x > self._w then self._w = mon.x end
if mon.y > self._h then self._h = mon.y end
for id, color in pairs(self._palette) do
mon.p.setPaletteColor(id, color)
end
end)
end,
_blitpixel = function(self, x, y, c, bg, fg)
bg = bg or "0"
fg = fg or "f"
local mon = self._getMonitorForScreenPos(x, y)
mon.p.setCursorPos(((x - 1) % mon._w) + 1, ((y - 1) % mon._h) + 1)
mon.p.blit(c, bg, fg)
end,
_findMonitor = function(self, x, y)
for i = 1, #self._monitors do
local mon = self._monitors[i]
if mon.x == x and mon.y == y then
return mon, i
end
end
end,
_getMonitorForScreenPos = function(self, x, y)
local oy = 1
for iy = 1, self._h do
local ox = 1
for ix = 1, self._w do
local mon, i = self._findMonitor(ix, iy)
if x >= ox and x < (ox + mon._w) and y >= oy and y < (oy + mon._h) then
return mon, i, x - ox, y - oy
end
ox = ox + mon._w
end
local mon, i = self._findMonitor(1, iy)
oy = oy + mon._h
end
end,
_forEachMonitor = function(self, fun)
for i = 1, #self._monitors do
fun(self._monitors[i], i)
end
end,
}
return function(monitors, args)
args = args or {}
local mon = setmetatable({
_monitors = monitors,
_pos = { x = 1, y = 1 },
_blink = false,
_colorForeground = colors.white,
_colorBackground = colors.black,
_scale = args.scale or 1.0,
_palette = args.palette or {},
}, { __index = BigTerm })
for name, method in pairs(BigTerm) do
if type(method) == "function" then
mon[name] = function(...) return method(mon, ...) end
end
end
mon._reset()
return mon
end

BIN
casey.cpi Normal file

Binary file not shown.

BIN
cute.cpi Normal file

Binary file not shown.

BIN
rando.cpi Normal file

Binary file not shown.