diff --git a/bigterm-hello.lua b/bigterm-hello.lua new file mode 100644 index 0000000..5adb156 --- /dev/null +++ b/bigterm-hello.lua @@ -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 + diff --git a/bigterm.lua b/bigterm.lua new file mode 100644 index 0000000..6ec0fb1 --- /dev/null +++ b/bigterm.lua @@ -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 diff --git a/casey.cpi b/casey.cpi new file mode 100644 index 0000000..04ec1ad Binary files /dev/null and b/casey.cpi differ diff --git a/cute.cpi b/cute.cpi new file mode 100644 index 0000000..64a1c18 Binary files /dev/null and b/cute.cpi differ diff --git a/rando.cpi b/rando.cpi new file mode 100644 index 0000000..698c508 Binary files /dev/null and b/rando.cpi differ