forked from izaya/LuPPC
Compare commits
No commits in common. "master" and "master" have entirely different histories.
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,4 +8,3 @@
|
|||||||
/usereeprom.lua
|
/usereeprom.lua
|
||||||
/run
|
/run
|
||||||
/root*
|
/root*
|
||||||
/musl-cross-make
|
|
||||||
|
@ -13,7 +13,6 @@ extern char lua_init[];
|
|||||||
extern char lua_internet[];
|
extern char lua_internet[];
|
||||||
extern char lua_sandbox[];
|
extern char lua_sandbox[];
|
||||||
extern char lua_textgpu[];
|
extern char lua_textgpu[];
|
||||||
extern char lua_textgpu_old[];
|
|
||||||
extern char lua_util_buffer[];
|
extern char lua_util_buffer[];
|
||||||
extern char lua_util_color[];
|
extern char lua_util_color[];
|
||||||
extern char lua_util_random[];
|
extern char lua_util_random[];
|
||||||
|
@ -42,10 +42,6 @@ case "$1" in
|
|||||||
TOOL=powerpc-linux-musl
|
TOOL=powerpc-linux-musl
|
||||||
OUT=$TOOL
|
OUT=$TOOL
|
||||||
;;
|
;;
|
||||||
i686 )
|
|
||||||
TOOL=i686-linux-musl
|
|
||||||
OUT=i686-linux-musl
|
|
||||||
;;
|
|
||||||
*) echo "Invalid target!" ; exit 1
|
*) echo "Invalid target!" ; exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -64,7 +60,7 @@ cd dependencies
|
|||||||
|
|
||||||
if [ $2 = "libressl" ] || [ $# -lt 2 ]; then
|
if [ $2 = "libressl" ] || [ $# -lt 2 ]; then
|
||||||
|
|
||||||
git clone --depth 1 https://github.com/libressl-portable/portable.git libressl
|
git clone https://github.com/libressl-portable/portable.git libressl
|
||||||
cd libressl
|
cd libressl
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
CFLAGS="-fdata-sections -ffunction-sections" ./configure --host=$TOOL
|
CFLAGS="-fdata-sections -ffunction-sections" ./configure --host=$TOOL
|
||||||
|
@ -31,7 +31,7 @@ function boot.boot()
|
|||||||
gpu.setBackground(0x000000)
|
gpu.setBackground(0x000000)
|
||||||
|
|
||||||
native.sleep(4000000)
|
native.sleep(4000000)
|
||||||
while true do --[[NOTHING]] end
|
os.exit(1)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -62,30 +62,30 @@ local keymap = {
|
|||||||
|
|
||||||
[0x60 + 0x01] = 0x1E,
|
[0x60 + 0x01] = 0x1E,
|
||||||
[0x60 + 0x02] = 0x30,
|
[0x60 + 0x02] = 0x30,
|
||||||
[0x60 + 0x03] = 0x2E,
|
[0x60 + 0x04] = 0x2E,
|
||||||
[0x60 + 0x04] = 0x20,
|
[0x60 + 0x05] = 0x20,
|
||||||
[0x60 + 0x05] = 0x12,
|
[0x60 + 0x06] = 0x12,
|
||||||
[0x60 + 0x06] = 0x21,
|
[0x60 + 0x07] = 0x21,
|
||||||
[0x60 + 0x07] = 0x22,
|
[0x60 + 0x08] = 0x22,
|
||||||
[0x60 + 0x08] = 0x23,
|
[0x60 + 0x09] = 0x23,
|
||||||
[0x60 + 0x09] = 0x17,
|
[0x60 + 0x0A] = 0x17,
|
||||||
[0x60 + 0x0A] = 0x24,
|
[0x60 + 0x0B] = 0x24,
|
||||||
[0x60 + 0x0B] = 0x25,
|
[0x60 + 0x0C] = 0x25,
|
||||||
[0x60 + 0x0C] = 0x26,
|
[0x60 + 0x0D] = 0x26,
|
||||||
[0x60 + 0x0D] = 0x32,
|
[0x60 + 0x0E] = 0x32,
|
||||||
[0x60 + 0x0E] = 0x31,
|
[0x60 + 0x0F] = 0x31,
|
||||||
[0x60 + 0x0F] = 0x18,
|
[0x60 + 0x11] = 0x18,
|
||||||
[0x60 + 0x10] = 0x19,
|
[0x60 + 0x12] = 0x19,
|
||||||
[0x60 + 0x11] = 0x10,
|
[0x60 + 0x13] = 0x10,
|
||||||
[0x60 + 0x12] = 0x13,
|
[0x60 + 0x14] = 0x13,
|
||||||
[0x60 + 0x13] = 0x1F,
|
[0x60 + 0x15] = 0x1F,
|
||||||
[0x60 + 0x13] = 0x14,
|
[0x60 + 0x16] = 0x14,
|
||||||
[0x60 + 0x14] = 0x16,
|
[0x60 + 0x17] = 0x16,
|
||||||
[0x60 + 0x16] = 0x2F,
|
[0x60 + 0x18] = 0x2F,
|
||||||
[0x60 + 0x17] = 0x11,
|
[0x60 + 0x19] = 0x11,
|
||||||
[0x60 + 0x18] = 0x2D,
|
[0x60 + 0x1A] = 0x2D,
|
||||||
[0x60 + 0x19] = 0x15,
|
[0x60 + 0x1B] = 0x15,
|
||||||
[0x60 + 0x1A] = 0x2C,
|
[0x60 + 0x1C] = 0x2C,
|
||||||
|
|
||||||
[13] = 28, --Return key
|
[13] = 28, --Return key
|
||||||
[127] = 14, --backspace
|
[127] = 14, --backspace
|
||||||
@ -97,88 +97,24 @@ local asciitr = {
|
|||||||
[127] = 8,
|
[127] = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
local escmap = {
|
|
||||||
[65] = 200, -- up
|
|
||||||
[66] = 208, -- down
|
|
||||||
[67] = 205, -- right
|
|
||||||
[68] = 203, -- left
|
|
||||||
}
|
|
||||||
|
|
||||||
local inesc_down = false
|
|
||||||
local esc_down_ctrl = false
|
|
||||||
function computer.signalTransformers.key_down(s, a, ascii, key, user)
|
function computer.signalTransformers.key_down(s, a, ascii, key, user)
|
||||||
if key ~= -1 then
|
if key ~= -1 then
|
||||||
return s, a, ascii, key, user
|
return s, a, ascii, key, user
|
||||||
end
|
end
|
||||||
if ascii == 27 then
|
|
||||||
inesc_down = native.uptime()
|
|
||||||
return nil
|
|
||||||
elseif ascii < 27 and ascii ~= 8 and ascii ~= 13 and ascii ~= 9 then
|
|
||||||
signalQueue[#signalQueue + 1] = {s, a, 0, 29, user}
|
|
||||||
key = keymap[ascii + 96] or -1
|
|
||||||
elseif inesc_down then
|
|
||||||
if (ascii < 48 or ascii > 57) and ascii ~= 59 and ascii ~= 91 then
|
|
||||||
inesc_down = false
|
|
||||||
key = escmap[ascii] or 0
|
|
||||||
if not esc_down_ctrl then
|
|
||||||
--ascii = math.max(0, ascii - 96)
|
|
||||||
else
|
|
||||||
ascii = 0
|
|
||||||
end
|
|
||||||
esc_down_ctrl = false
|
|
||||||
elseif ascii == 91 then
|
|
||||||
esc_down_ctrl = true
|
|
||||||
elseif native.uptime() - inesc_down > 100 then -- 100ms timeout after {ESC}
|
|
||||||
return nil
|
|
||||||
else
|
|
||||||
esc_down_ctrl = false
|
|
||||||
inesc_down = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return s, a, math.floor(asciitr[ascii] or ascii), keymap[ascii] or key, user
|
return s, a, math.floor(asciitr[ascii] or ascii), keymap[ascii] or key, user
|
||||||
end
|
end
|
||||||
|
|
||||||
local inesc_up = false
|
|
||||||
local esc_up_ctrl = false
|
|
||||||
function computer.signalTransformers.key_up(s, a, ascii, key, user)
|
function computer.signalTransformers.key_up(s, a, ascii, key, user)
|
||||||
if key ~= -1 then
|
if key ~= -1 then
|
||||||
return s, a, ascii, key, user
|
return s, a, ascii, key, user
|
||||||
end
|
end
|
||||||
if ascii == 27 then
|
|
||||||
inesc_up = native.uptime()
|
|
||||||
return nil
|
|
||||||
elseif ascii < 27 and ascii ~= 8 and ascii ~= 13 and ascii ~= 9 then
|
|
||||||
signalQueue[#signalQueue+1] = {s, a, 0, 29, user}
|
|
||||||
key = keymap[ascii + 96] or 0
|
|
||||||
elseif inesc_up then
|
|
||||||
if (ascii < 48 or ascii > 57) and ascii ~= 59 and ascii ~= 91 then
|
|
||||||
inesc_up = false
|
|
||||||
key = escmap[ascii] or 0
|
|
||||||
if not esc_up_ctrl then
|
|
||||||
--ascii = math.max(0, ascii - 96)
|
|
||||||
else
|
|
||||||
ascii = 0
|
|
||||||
end
|
|
||||||
esc_up_ctrl = false
|
|
||||||
elseif ascii == 91 then
|
|
||||||
esc_up_ctrl = true
|
|
||||||
elseif native.uptime() - inesc_up > 100 then -- 100ms timeout after {ESC}
|
|
||||||
return nil
|
|
||||||
else
|
|
||||||
esc_up_ctrl = false
|
|
||||||
inesc_up = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return s, a, math.floor(asciitr[ascii] or ascii), keymap[ascii] or key, user
|
return s, a, math.floor(asciitr[ascii] or ascii), keymap[ascii] or key, user
|
||||||
end
|
end
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
||||||
function api.pushSignal(s, ...)
|
function api.pushSignal(s, ...)
|
||||||
local result = table.pack(computer.signalTransformers[s](s, ...))
|
signalQueue[#signalQueue + 1] = {computer.signalTransformers[s](s, ...)}
|
||||||
if result.n == 0 or not result[1] then return end
|
|
||||||
result.n = nil
|
|
||||||
signalQueue[#signalQueue + 1] = result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function api.pullSignal(timeout)
|
function api.pullSignal(timeout)
|
||||||
|
@ -1,324 +1,257 @@
|
|||||||
local textgpu = {}
|
local textgpu = {}
|
||||||
|
|
||||||
local mapping = {}
|
local mapping = {
|
||||||
local palette = {}
|
["0"] = 0x000000,
|
||||||
|
["1"] = 0xFF0000,
|
||||||
|
["2"] = 0x00FF00,
|
||||||
|
["3"] = 0xFFFF00,
|
||||||
|
["4"] = 0x0000FF,
|
||||||
|
["5"] = 0xFF00FF,
|
||||||
|
["6"] = 0x00FFFF,
|
||||||
|
["7"] = 0xFFFFFF,
|
||||||
|
}
|
||||||
|
|
||||||
-- generate color mapping
|
--[[local nw = io.write
|
||||||
|
io.write = function(...)
|
||||||
for g=0, 255, 0x24 do
|
nw(...)
|
||||||
for b=0, 256, 0x40 do
|
io.flush()
|
||||||
for r=0, 255, 0x33 do
|
native.sleep(20000)
|
||||||
mapping[#mapping+1] = (math.min(r, 255) * 0x10000)
|
end]]--
|
||||||
+ (math.min(g, 255) * 0x100) + math.min(b, 255)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for i=0, 15, 1 do
|
|
||||||
mapping[#mapping+1] = (i+1) * 0x0f0f0f
|
|
||||||
palette[i] = (i+1) * 0x0f0f0f
|
|
||||||
end
|
|
||||||
|
|
||||||
local write = io.write
|
local write = io.write
|
||||||
local flush = io.flush
|
local flush = io.flush
|
||||||
|
|
||||||
local background = 1
|
local background = "0"
|
||||||
local foreground = 256
|
local foreground = "0"
|
||||||
|
|
||||||
local tbuffer = {}
|
local tbuffer = {}
|
||||||
local bbuffer = {}
|
local bbuffer = {}
|
||||||
local fbuffer = {}
|
local fbuffer = {}
|
||||||
|
|
||||||
local function prep(w, h)
|
local function prepareBuffers(w, h)
|
||||||
local tl = string.rep(" ", w)
|
local tbline = (" "):rep(w)
|
||||||
local bb = string.rep("\0", w)
|
local bbline = ("0"):rep(w)
|
||||||
local fb = string.rep("\255", w)
|
local fbline = ("7"):rep(w)
|
||||||
|
for i=1, h do
|
||||||
for i=1, h, 1 do
|
tbuffer[i] = tbline
|
||||||
tbuffer[i] = tl
|
bbuffer[i] = bbline
|
||||||
bbuffer[i] = bb
|
fbuffer[i] = fbline
|
||||||
fbuffer[i] = fb
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local fg = 256
|
local usub
|
||||||
local bg = 1
|
local function insertString(main, sub, at)
|
||||||
local w, h = 1, 1
|
checkArg(1, main, "string")
|
||||||
|
checkArg(2, sub, "string")
|
||||||
|
checkArg(3, at, "number")
|
||||||
|
|
||||||
local function rgb(i)
|
return usub(main, 1, at - 1)
|
||||||
return i>>16&0xFF, i>>8&0xFF, i&0xFF
|
.. sub .. usub(main, at + (utf8.len(sub) or 0))
|
||||||
end
|
|
||||||
|
|
||||||
local unsub, fullRefresh
|
|
||||||
local function set(x, y, text, f, b, safe, noref)
|
|
||||||
if x > w or x < 1 or y > h or y < 1 or not tbuffer[y] then
|
|
||||||
if safe then
|
|
||||||
return
|
|
||||||
else
|
|
||||||
error("index out of bounds: " .. y, 3)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not text then return end
|
|
||||||
f = f or fg
|
|
||||||
b = b or bg
|
|
||||||
local len = utf8.len(text)
|
|
||||||
if x + len > w then
|
|
||||||
--len = (x + len) - w
|
|
||||||
--text = unsub(text, 1, len)
|
|
||||||
end
|
|
||||||
tbuffer[y] = unsub(tbuffer[y], 1, x - 1) ..
|
|
||||||
text .. unsub(tbuffer[y], x + len)
|
|
||||||
if type(f) == "string" then
|
|
||||||
fbuffer[y] = fbuffer[y]:sub(1, x - 1) ..
|
|
||||||
f .. fbuffer[y]:sub(x + len)
|
|
||||||
else
|
|
||||||
if not noref then
|
|
||||||
local F = mapping[f]
|
|
||||||
local r, g, _b = rgb(F)
|
|
||||||
write("\27[38;2;", r, ";", g, ";", _b, "m")
|
|
||||||
end
|
|
||||||
fbuffer[y] = fbuffer[y]:sub(1, x - 1) ..
|
|
||||||
string.rep(string.char(f - 1), len) .. fbuffer[y]:sub(x + len)
|
|
||||||
end
|
|
||||||
if type(b) == "string" then
|
|
||||||
bbuffer[y] = bbuffer[y]:sub(1, x - 1) ..
|
|
||||||
b .. bbuffer[y]:sub(x + len)
|
|
||||||
else
|
|
||||||
if not noref then
|
|
||||||
local B = mapping[b]
|
|
||||||
local r, g, _b = rgb(B)
|
|
||||||
write("\27[48;2;", r, ";", g, ";", _b, "m")
|
|
||||||
end
|
|
||||||
bbuffer[y] = bbuffer[y]:sub(1, x - 1) ..
|
|
||||||
string.rep(string.char(b - 1), len) .. bbuffer[y]:sub(x + len)
|
|
||||||
end
|
|
||||||
-- clamp buffers
|
|
||||||
tbuffer[y] = unsub(tbuffer[y], 1, w)
|
|
||||||
fbuffer[y] = fbuffer[y]:sub(1, w)
|
|
||||||
bbuffer[y] = bbuffer[y]:sub(1, w)
|
|
||||||
if not noref then
|
|
||||||
write("\27[", y, ";", x, "H", text)
|
|
||||||
flush()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
fullRefresh = function()
|
|
||||||
for i=1, h, 1 do
|
|
||||||
local text = tbuffer[i]
|
|
||||||
local fgt = fbuffer[i]
|
|
||||||
local bgt = bbuffer[i]
|
|
||||||
--native.log("UPDATE " .. i .. ": \"" .. text .. "\"")
|
|
||||||
local pb, pf
|
|
||||||
fgt = fgt:gsub("()(.)", function(n, fc)
|
|
||||||
local bc, tc = bgt:sub(n,n), text:sub(n,n)
|
|
||||||
local str = ""
|
|
||||||
if bc ~= pb then
|
|
||||||
pb = bc
|
|
||||||
local B = mapping[bc:byte() + 1]
|
|
||||||
str = str .. string.format("\27[48;2;%d;%d;%dm",
|
|
||||||
rgb(B))
|
|
||||||
end
|
|
||||||
if fc ~= pf then
|
|
||||||
pf = fc
|
|
||||||
local F = mapping[fc:byte() + 1]
|
|
||||||
str = str .. string.format("\27[38;2;%d;%d;%dm",
|
|
||||||
rgb(F))
|
|
||||||
end
|
|
||||||
str = str .. tc
|
|
||||||
return str
|
|
||||||
end)
|
|
||||||
write("\27[", i, ";1H", fgt)
|
|
||||||
end
|
|
||||||
flush()
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get(x, y, len, safe)
|
|
||||||
if x < 1 or x > w or y < 1 or y > h then
|
|
||||||
if safe then
|
|
||||||
return
|
|
||||||
else
|
|
||||||
error("index out of bounds: " .. y, 3)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
len = (len or 1) - 1
|
|
||||||
if x + len > w then
|
|
||||||
len = (x + len) - w
|
|
||||||
end
|
|
||||||
local text = unsub(tbuffer[y], x, x + len)
|
|
||||||
if len == 0 then
|
|
||||||
return text,
|
|
||||||
mapping[fbuffer[y]:sub(x, x):byte() + 1],
|
|
||||||
mapping[bbuffer[y]:sub(x, x):byte() + 1]
|
|
||||||
else
|
|
||||||
return text, fbuffer[y]:sub(x, x + len), bbuffer[y]:sub(x, x + len)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function textgpu.start()
|
function textgpu.start()
|
||||||
unsub = modules.sandbox.unicode.sub
|
usub = modules.sandbox.unicode.sub
|
||||||
|
local _height = 0
|
||||||
local gpu = {}
|
local gpu = {}
|
||||||
|
function gpu.bind() return false, "This is static bound gpu" end
|
||||||
function gpu.setForeground(color, ispalette)
|
function gpu.setBackground(color, isPaletteIndex)
|
||||||
checkArg(1, color, "number")
|
checkArg(1, color, "number")
|
||||||
checkArg(2, ispalette, "boolean", "nil")
|
checkArg(2, isPaletteIndex, "boolean", "nil")
|
||||||
local ret = color
|
if isPaletteIndex then
|
||||||
if ispalette then
|
return --TODO: Maybe?
|
||||||
if not palette[color] then
|
|
||||||
error("invalid palette index", 2)
|
|
||||||
end
|
end
|
||||||
color = palette[color]
|
local old = background
|
||||||
|
background = tostring(math.floor(modules.color.nearest(color, mapping)))
|
||||||
|
write("\x1b[4" .. background .. "m")
|
||||||
|
flush()
|
||||||
|
return mapping[old]
|
||||||
end
|
end
|
||||||
local index = math.floor(modules.color.nearest(color, mapping))
|
function gpu.setForeground(color, isPaletteIndex)
|
||||||
fg = index or fg
|
|
||||||
return ret, ispalette
|
|
||||||
end
|
|
||||||
|
|
||||||
function gpu.setBackground(color, ispalette)
|
|
||||||
checkArg(1, color, "number")
|
checkArg(1, color, "number")
|
||||||
checkArg(2, ispalette, "boolean", "nil")
|
checkArg(2, isPaletteIndex, "boolean", "nil")
|
||||||
local ret = color
|
if isPaletteIndex then
|
||||||
if ispalette then
|
return --TODO: Maybe?
|
||||||
if not palette[color] then
|
|
||||||
error("invalid palette index", 2)
|
|
||||||
end
|
end
|
||||||
color = palette[color]
|
local old = foreground
|
||||||
|
foreground = tostring(math.floor(modules.color.nearest(color, mapping)))
|
||||||
|
write("\x1b[3" .. foreground .. "m")
|
||||||
|
flush()
|
||||||
|
return mapping[old]
|
||||||
end
|
end
|
||||||
local index = math.floor(modules.color.nearest(color, mapping))
|
|
||||||
bg = index or bg
|
|
||||||
return ret, ispalette
|
|
||||||
end
|
|
||||||
|
|
||||||
function gpu.setPaletteColor(c, v)
|
|
||||||
checkArg(1, c, "number")
|
|
||||||
checkArg(2, v, "number")
|
|
||||||
if not palette[c] then
|
|
||||||
error("invalid palette index", 2)
|
|
||||||
end
|
|
||||||
palette[c] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
function gpu.getPaletteColor(c)
|
|
||||||
checkArg(1, c, "number")
|
|
||||||
if not palette[c] then
|
|
||||||
error("invalid palette index", 2)
|
|
||||||
end
|
|
||||||
return palette[c]
|
|
||||||
end
|
|
||||||
|
|
||||||
function gpu.getForeground()
|
|
||||||
return mapping[fg]
|
|
||||||
end
|
|
||||||
|
|
||||||
function gpu.getBackground()
|
function gpu.getBackground()
|
||||||
return mapping[bg]
|
return mapping[background], false
|
||||||
end
|
end
|
||||||
|
function gpu.getForeground()
|
||||||
function gpu.getDepth()
|
return mapping[foreground], false
|
||||||
return 4
|
end
|
||||||
|
function gpu.getPaletteColor()
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
function gpu.setPaletteColor()
|
||||||
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function gpu.maxDepth()
|
function gpu.maxDepth()
|
||||||
return 4
|
return 3
|
||||||
end
|
end
|
||||||
|
|
||||||
function gpu.setDepth()
|
function gpu.setDepth()
|
||||||
return true
|
return false
|
||||||
|
end
|
||||||
|
function gpu.getDepth()
|
||||||
|
return 3
|
||||||
|
end
|
||||||
|
function gpu.maxResolution()
|
||||||
|
return termutils.getSize()
|
||||||
end
|
end
|
||||||
|
|
||||||
function gpu.getResolution()
|
function gpu.getResolution()
|
||||||
return termutils.getSize()
|
return termutils.getSize()
|
||||||
end
|
end
|
||||||
|
function gpu.getViewport()
|
||||||
function gpu.setResolution()
|
return termutils.getSize()
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
function gpu.setViewport(w, h)
|
||||||
gpu.maxResolution = gpu.getResolution
|
checkArg(1, w, "number")
|
||||||
gpu.getViewport = gpu.getResolution
|
checkArg(2, h, "number")
|
||||||
gpu.setViewport = gpu.setResolution
|
return false, "Viewport not supported for this gpu"
|
||||||
|
|
||||||
function gpu.set(x, y, text, vert)
|
|
||||||
checkArg(1, x, "number")
|
|
||||||
checkArg(2, y, "number")
|
|
||||||
checkArg(3, text, "string")
|
|
||||||
checkArg(4, vert, "boolean", "nil")
|
|
||||||
vert = false
|
|
||||||
if vert then
|
|
||||||
local i = 1
|
|
||||||
local len = utf8.len(text)
|
|
||||||
while i <= len do
|
|
||||||
set(x, y + i - 1, unsub(text, i, i))
|
|
||||||
i = i + 1
|
|
||||||
end
|
end
|
||||||
return true
|
function gpu.setResolution(w, h)
|
||||||
else
|
checkArg(1, w, "number")
|
||||||
set(x, y, text)
|
checkArg(2, h, "number")
|
||||||
return true
|
return false, "Non resizeable gpu"
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
function gpu.get(x, y)
|
function gpu.get(x, y)
|
||||||
checkArg(1, x, "number")
|
checkArg(1, x, "number")
|
||||||
checkArg(2, y, "number")
|
checkArg(2, y, "number")
|
||||||
return get(x, y)
|
|
||||||
end
|
|
||||||
|
|
||||||
function gpu.fill(x, y, W, H, c)
|
return tbuffer[y]:sub(x,x), mapping[fbuffer[y]:sub(x,x)], mapping[bbuffer[y]:sub(x,x)]
|
||||||
checkArg(1, x, "number")
|
|
||||||
checkArg(1, y, "number")
|
|
||||||
checkArg(1, W, "number")
|
|
||||||
checkArg(1, H, "number")
|
|
||||||
checkArg(1, c, "string")
|
|
||||||
c = unsub(c, 1, 1)
|
|
||||||
if #c == 0 then return true end
|
|
||||||
local str = c:rep(W)
|
|
||||||
for i=1, H, 1 do
|
|
||||||
set(x, y + i - 1, str, nil, nil, true)
|
|
||||||
end
|
end
|
||||||
return true
|
function gpu.set(x, y, value, vertical)
|
||||||
end
|
|
||||||
|
|
||||||
function gpu.copy(x, y, W, H, xd, yd)
|
|
||||||
checkArg(1, x, "number")
|
checkArg(1, x, "number")
|
||||||
checkArg(2, y, "number")
|
checkArg(2, y, "number")
|
||||||
checkArg(3, W, "number")
|
checkArg(3, value, "string")
|
||||||
checkArg(4, H, "number")
|
checkArg(4, vertical, "boolean", "nil")
|
||||||
checkArg(5, xd, "number")
|
x = math.floor(x)
|
||||||
checkArg(6, yd, "number")
|
y = math.floor(y)
|
||||||
if xd == 0 and yd == 0 then return true end -- hah
|
if not vertical then
|
||||||
local start, stop, step
|
if not tbuffer[y] then
|
||||||
if yd < 0 then -- moving up - copy from the top down
|
native.log("GPU Set failed: under buffer")
|
||||||
start, stop, step = y, y + H, 1
|
return false
|
||||||
else -- moving down - copy from the bottom up
|
|
||||||
start, stop, step = y + H, y, -1
|
|
||||||
end
|
end
|
||||||
for i=start, stop, step do
|
tbuffer[y] = insertString(tbuffer[y], value, x)
|
||||||
local str, fstr, bstr = get(x, i, W, true)
|
bbuffer[y] = insertString(bbuffer[y], background:rep(utf8.len(value)), x)
|
||||||
--native.log("COPY " .. i .. " (" .. (str or "") .. ") to " .. (i + yd))
|
fbuffer[y] = insertString(fbuffer[y], foreground:rep(utf8.len(value)), x)
|
||||||
if str then-- and fstr and bstr then
|
write("\x1b[" .. y .. ";" .. x .. "H" .. value)
|
||||||
set(x + xd, i + yd, str, fstr, bstr, true, true)
|
else
|
||||||
|
--TODO: Buffers!
|
||||||
|
write("\x1b[" .. y .. ";" .. x .. "H")
|
||||||
|
value:gsub("([%z\1-\127\194-\244][\128-\191]*)", function(c)
|
||||||
|
write(c .. "\x1b[D\x1b[B")
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
flush()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
function gpu.copy(x, y, w, h, tx, ty) --TODO: Check(check X multiple times)
|
||||||
|
checkArg(1, x, "number")
|
||||||
|
checkArg(2, y, "number")
|
||||||
|
checkArg(3, w, "number")
|
||||||
|
checkArg(4, h, "number")
|
||||||
|
checkArg(5, tx, "number")
|
||||||
|
checkArg(6, ty, "number")
|
||||||
|
local ttbuf = {}
|
||||||
|
local btbuf = {}
|
||||||
|
local ftbuf = {}
|
||||||
|
for i=1, h do
|
||||||
|
if i + y - 2 <= _height and i + y > 1 then
|
||||||
|
ttbuf[i] = tbuffer[y + i - 1] and usub(tbuffer[y + i - 1], x, x + w - 1) or (" "):rep(w)
|
||||||
|
btbuf[i] = bbuffer[y + i - 1] and bbuffer[y + i - 1]:sub(x, x + w - 1) or background:rep(w)
|
||||||
|
ftbuf[i] = fbuffer[y + i - 1] and fbuffer[y + i - 1]:sub(x, x + w - 1) or foreground:rep(w)
|
||||||
|
else
|
||||||
|
ttbuf[i] = (" "):rep(w)
|
||||||
|
btbuf[i] = background:rep(w)
|
||||||
|
ftbuf[i] = foreground:rep(w)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local bg = background
|
||||||
|
local fg = foreground
|
||||||
|
|
||||||
|
for i=1, h do
|
||||||
|
local line, linex
|
||||||
|
local lwrite = false
|
||||||
|
for j=1, w do
|
||||||
|
if btbuf[i]:sub(j,j) ~= bg then
|
||||||
|
lwrite = true
|
||||||
|
end
|
||||||
|
if ftbuf[i]:sub(j,j) ~= fg then
|
||||||
|
lwrite = true
|
||||||
|
end
|
||||||
|
if not line then linex = j end
|
||||||
|
line = (line or "")
|
||||||
|
if lwrite then
|
||||||
|
local wx = (tx + x + linex - 1)|0
|
||||||
|
local wy = (ty + y + i - 1)|0
|
||||||
|
if tbuffer[wy] then
|
||||||
|
write("\x1b[4" .. bg .. "m\x1b[3" .. fg .. "m\x1b[" .. wy .. ";" .. wx .. "H" .. line)
|
||||||
|
tbuffer[wy] = insertString(tbuffer[wy], line, wx)
|
||||||
|
bbuffer[wy] = insertString(bbuffer[wy], bg:rep(utf8.len(line)), wx)
|
||||||
|
fbuffer[wy] = insertString(fbuffer[wy], fg:rep(utf8.len(line)), wx)
|
||||||
|
end
|
||||||
|
|
||||||
|
bg = btbuf[i]:sub(j,j)
|
||||||
|
fg = ftbuf[i]:sub(j,j)
|
||||||
|
line = nil
|
||||||
|
linex = nil
|
||||||
|
lwrite = false
|
||||||
|
end
|
||||||
|
if not line then linex = j end
|
||||||
|
line = (line or "") .. usub(ttbuf[i], j,j)
|
||||||
|
end
|
||||||
|
if line then
|
||||||
|
local wx = (tx + x + linex - 1)|0
|
||||||
|
local wy = (ty + y + i - 1)|0
|
||||||
|
if tbuffer[wy] then
|
||||||
|
write("\x1b[4" .. bg .. "m\x1b[3" .. fg .. "m\x1b[" .. wy .. ";" .. wx .. "H" .. line)
|
||||||
|
tbuffer[wy] = insertString(tbuffer[wy], line, wx)
|
||||||
|
bbuffer[wy] = insertString(bbuffer[wy], bg:rep(utf8.len(line)), wx)
|
||||||
|
fbuffer[wy] = insertString(fbuffer[wy], fg:rep(utf8.len(line)), wx)
|
||||||
|
end
|
||||||
|
line = nil
|
||||||
|
linex = nil
|
||||||
|
lwrite = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
write("\x1b[4" .. background .. "m")
|
||||||
|
write("\x1b[3" .. foreground .. "m")
|
||||||
|
flush()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
function gpu.fill(x, y, w, h, ch)
|
||||||
|
checkArg(1, x, "number")
|
||||||
|
checkArg(2, y, "number")
|
||||||
|
checkArg(3, w, "number")
|
||||||
|
checkArg(4, h, "number")
|
||||||
|
checkArg(5, ch, "string")
|
||||||
|
ch = usub(ch, 1, 1):rep(math.floor(w))
|
||||||
|
for i=1, h do
|
||||||
|
if i + y - 1 <= _height and i + y > 1 then
|
||||||
|
gpu.set(x, y + i - 1, ch)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
fullRefresh()
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local screenAddr
|
local screenAddr
|
||||||
|
|
||||||
function gpu.getScreen()
|
function gpu.getScreen()
|
||||||
return screenAddr
|
return screenAddr
|
||||||
end
|
end
|
||||||
|
|
||||||
function gpu.bind() --[[STUB]] end
|
|
||||||
|
|
||||||
if not termutils.init() then
|
if not termutils.init() then
|
||||||
return nil, "Cannot initialize terminal based gpu"
|
return nil, "Cannot initialize terminal based gpu"
|
||||||
end
|
end
|
||||||
write("\x1b[?25l") --Disable cursor
|
write("\x1b[?25l") --Disable cursor
|
||||||
|
local w, h = gpu.getResolution()
|
||||||
w, h = gpu.getResolution()
|
_height = h
|
||||||
prep(w, h)
|
prepareBuffers(w, h)
|
||||||
fullRefresh()
|
|
||||||
|
|
||||||
gpu.setForeground(0xFFFFFF)
|
gpu.setForeground(0xFFFFFF)
|
||||||
gpu.setBackground(0x000000)
|
gpu.setBackground(0x000000)
|
||||||
|
|
||||||
|
@ -1,271 +0,0 @@
|
|||||||
local textgpu = {}
|
|
||||||
|
|
||||||
local mapping = {
|
|
||||||
["0"] = 0x000000,
|
|
||||||
["1"] = 0xFF0000,
|
|
||||||
["2"] = 0x00FF00,
|
|
||||||
["3"] = 0xFFFF00,
|
|
||||||
["4"] = 0x0000FF,
|
|
||||||
["5"] = 0xFF00FF,
|
|
||||||
["6"] = 0x00FFFF,
|
|
||||||
["7"] = 0xFFFFFF,
|
|
||||||
}
|
|
||||||
|
|
||||||
--[[local nw = io.write
|
|
||||||
io.write = function(...)
|
|
||||||
nw(...)
|
|
||||||
io.flush()
|
|
||||||
native.sleep(20000)
|
|
||||||
end]]--
|
|
||||||
|
|
||||||
local write = io.write
|
|
||||||
local flush = io.flush
|
|
||||||
|
|
||||||
local background = "0"
|
|
||||||
local foreground = "0"
|
|
||||||
|
|
||||||
local tbuffer = {}
|
|
||||||
local bbuffer = {}
|
|
||||||
local fbuffer = {}
|
|
||||||
|
|
||||||
local function prepareBuffers(w, h)
|
|
||||||
local tbline = (" "):rep(w)
|
|
||||||
local bbline = ("0"):rep(w)
|
|
||||||
local fbline = ("7"):rep(w)
|
|
||||||
for i=1, h do
|
|
||||||
tbuffer[i] = tbline
|
|
||||||
bbuffer[i] = bbline
|
|
||||||
fbuffer[i] = fbline
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local usub
|
|
||||||
local function insertString(main, sub, at)
|
|
||||||
checkArg(1, main, "string")
|
|
||||||
checkArg(2, sub, "string")
|
|
||||||
checkArg(3, at, "number")
|
|
||||||
|
|
||||||
return usub(main, 1, at - 1)
|
|
||||||
.. sub .. usub(main, at + (utf8.len(sub) or 0))
|
|
||||||
end
|
|
||||||
|
|
||||||
function textgpu.start()
|
|
||||||
usub = modules.sandbox.unicode.sub
|
|
||||||
local _height = 0
|
|
||||||
local gpu = {}
|
|
||||||
function gpu.bind() return false, "This is static bound gpu" end
|
|
||||||
function gpu.setBackground(color, isPaletteIndex)
|
|
||||||
checkArg(1, color, "number")
|
|
||||||
checkArg(2, isPaletteIndex, "boolean", "nil")
|
|
||||||
if isPaletteIndex then
|
|
||||||
return --TODO: Maybe?
|
|
||||||
end
|
|
||||||
local old = background
|
|
||||||
background = tostring(math.floor(modules.color.nearest(color, mapping)))
|
|
||||||
write("\x1b[4" .. background .. "m")
|
|
||||||
flush()
|
|
||||||
return mapping[old]
|
|
||||||
end
|
|
||||||
function gpu.setForeground(color, isPaletteIndex)
|
|
||||||
checkArg(1, color, "number")
|
|
||||||
checkArg(2, isPaletteIndex, "boolean", "nil")
|
|
||||||
if isPaletteIndex then
|
|
||||||
return --TODO: Maybe?
|
|
||||||
end
|
|
||||||
local old = foreground
|
|
||||||
foreground = tostring(math.floor(modules.color.nearest(color, mapping)))
|
|
||||||
write("\x1b[3" .. foreground .. "m")
|
|
||||||
flush()
|
|
||||||
return mapping[old]
|
|
||||||
end
|
|
||||||
function gpu.getBackground()
|
|
||||||
return mapping[background], false
|
|
||||||
end
|
|
||||||
function gpu.getForeground()
|
|
||||||
return mapping[foreground], false
|
|
||||||
end
|
|
||||||
function gpu.getPaletteColor()
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
function gpu.setPaletteColor()
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
function gpu.maxDepth()
|
|
||||||
return 3
|
|
||||||
end
|
|
||||||
function gpu.setDepth()
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
function gpu.getDepth()
|
|
||||||
return 3
|
|
||||||
end
|
|
||||||
function gpu.maxResolution()
|
|
||||||
return termutils.getSize()
|
|
||||||
end
|
|
||||||
function gpu.getResolution()
|
|
||||||
return termutils.getSize()
|
|
||||||
end
|
|
||||||
function gpu.getViewport()
|
|
||||||
return termutils.getSize()
|
|
||||||
end
|
|
||||||
function gpu.setViewport(w, h)
|
|
||||||
checkArg(1, w, "number")
|
|
||||||
checkArg(2, h, "number")
|
|
||||||
return false, "Viewport not supported for this gpu"
|
|
||||||
end
|
|
||||||
function gpu.setResolution(w, h)
|
|
||||||
checkArg(1, w, "number")
|
|
||||||
checkArg(2, h, "number")
|
|
||||||
return false, "Non resizeable gpu"
|
|
||||||
end
|
|
||||||
function gpu.get(x, y)
|
|
||||||
checkArg(1, x, "number")
|
|
||||||
checkArg(2, y, "number")
|
|
||||||
|
|
||||||
return tbuffer[y]:sub(x,x), mapping[fbuffer[y]:sub(x,x)], mapping[bbuffer[y]:sub(x,x)]
|
|
||||||
end
|
|
||||||
function gpu.set(x, y, value, vertical)
|
|
||||||
checkArg(1, x, "number")
|
|
||||||
checkArg(2, y, "number")
|
|
||||||
checkArg(3, value, "string")
|
|
||||||
checkArg(4, vertical, "boolean", "nil")
|
|
||||||
x = math.floor(x)
|
|
||||||
y = math.floor(y)
|
|
||||||
if not vertical then
|
|
||||||
if not tbuffer[y] then
|
|
||||||
native.log("GPU Set failed: under buffer")
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
tbuffer[y] = insertString(tbuffer[y], value, x)
|
|
||||||
bbuffer[y] = insertString(bbuffer[y], background:rep(utf8.len(value)), x)
|
|
||||||
fbuffer[y] = insertString(fbuffer[y], foreground:rep(utf8.len(value)), x)
|
|
||||||
write("\x1b[" .. y .. ";" .. x .. "H" .. value)
|
|
||||||
else
|
|
||||||
--TODO: Buffers!
|
|
||||||
write("\x1b[" .. y .. ";" .. x .. "H")
|
|
||||||
value:gsub("([%z\1-\127\194-\244][\128-\191]*)", function(c)
|
|
||||||
write(c .. "\x1b[D\x1b[B")
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
flush()
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
function gpu.copy(x, y, w, h, tx, ty) --TODO: Check(check X multiple times)
|
|
||||||
checkArg(1, x, "number")
|
|
||||||
checkArg(2, y, "number")
|
|
||||||
checkArg(3, w, "number")
|
|
||||||
checkArg(4, h, "number")
|
|
||||||
checkArg(5, tx, "number")
|
|
||||||
checkArg(6, ty, "number")
|
|
||||||
local ttbuf = {}
|
|
||||||
local btbuf = {}
|
|
||||||
local ftbuf = {}
|
|
||||||
for i=1, h do
|
|
||||||
if i + y - 2 <= _height and i + y > 1 then
|
|
||||||
ttbuf[i] = tbuffer[y + i - 1] and usub(tbuffer[y + i - 1], x, x + w - 1) or (" "):rep(w)
|
|
||||||
btbuf[i] = bbuffer[y + i - 1] and bbuffer[y + i - 1]:sub(x, x + w - 1) or background:rep(w)
|
|
||||||
ftbuf[i] = fbuffer[y + i - 1] and fbuffer[y + i - 1]:sub(x, x + w - 1) or foreground:rep(w)
|
|
||||||
else
|
|
||||||
ttbuf[i] = (" "):rep(w)
|
|
||||||
btbuf[i] = background:rep(w)
|
|
||||||
ftbuf[i] = foreground:rep(w)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local bg = background
|
|
||||||
local fg = foreground
|
|
||||||
|
|
||||||
for i=1, h do
|
|
||||||
local line, linex
|
|
||||||
local lwrite = false
|
|
||||||
for j=1, w do
|
|
||||||
if btbuf[i]:sub(j,j) ~= bg then
|
|
||||||
lwrite = true
|
|
||||||
end
|
|
||||||
if ftbuf[i]:sub(j,j) ~= fg then
|
|
||||||
lwrite = true
|
|
||||||
end
|
|
||||||
if not line then linex = j end
|
|
||||||
line = (line or "")
|
|
||||||
if lwrite then
|
|
||||||
local wx = (tx + x + linex - 1)|0
|
|
||||||
local wy = (ty + y + i - 1)|0
|
|
||||||
if tbuffer[wy] then
|
|
||||||
write("\x1b[4" .. bg .. "m\x1b[3" .. fg .. "m\x1b[" .. wy .. ";" .. wx .. "H" .. line)
|
|
||||||
tbuffer[wy] = insertString(tbuffer[wy], line, wx)
|
|
||||||
bbuffer[wy] = insertString(bbuffer[wy], bg:rep(utf8.len(line)), wx)
|
|
||||||
fbuffer[wy] = insertString(fbuffer[wy], fg:rep(utf8.len(line)), wx)
|
|
||||||
end
|
|
||||||
|
|
||||||
bg = btbuf[i]:sub(j,j)
|
|
||||||
fg = ftbuf[i]:sub(j,j)
|
|
||||||
line = nil
|
|
||||||
linex = nil
|
|
||||||
lwrite = false
|
|
||||||
end
|
|
||||||
if not line then linex = j end
|
|
||||||
line = (line or "") .. usub(ttbuf[i], j,j)
|
|
||||||
end
|
|
||||||
if line then
|
|
||||||
local wx = (tx + x + linex - 1)|0
|
|
||||||
local wy = (ty + y + i - 1)|0
|
|
||||||
if tbuffer[wy] then
|
|
||||||
write("\x1b[4" .. bg .. "m\x1b[3" .. fg .. "m\x1b[" .. wy .. ";" .. wx .. "H" .. line)
|
|
||||||
tbuffer[wy] = insertString(tbuffer[wy], line, wx)
|
|
||||||
bbuffer[wy] = insertString(bbuffer[wy], bg:rep(utf8.len(line)), wx)
|
|
||||||
fbuffer[wy] = insertString(fbuffer[wy], fg:rep(utf8.len(line)), wx)
|
|
||||||
end
|
|
||||||
line = nil
|
|
||||||
linex = nil
|
|
||||||
lwrite = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
write("\x1b[4" .. background .. "m")
|
|
||||||
write("\x1b[3" .. foreground .. "m")
|
|
||||||
flush()
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
function gpu.fill(x, y, w, h, ch)
|
|
||||||
checkArg(1, x, "number")
|
|
||||||
checkArg(2, y, "number")
|
|
||||||
checkArg(3, w, "number")
|
|
||||||
checkArg(4, h, "number")
|
|
||||||
checkArg(5, ch, "string")
|
|
||||||
ch = usub(ch, 1, 1):rep(math.floor(w))
|
|
||||||
for i=1, h do
|
|
||||||
if i + y - 1 <= _height and i + y > 1 then
|
|
||||||
gpu.set(x, y + i - 1, ch)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
local screenAddr
|
|
||||||
|
|
||||||
function gpu.getScreen()
|
|
||||||
return screenAddr
|
|
||||||
end
|
|
||||||
|
|
||||||
if not termutils.init() then
|
|
||||||
return nil, "Cannot initialize terminal based gpu"
|
|
||||||
end
|
|
||||||
write("\x1b[?25l") --Disable cursor
|
|
||||||
local w, h = gpu.getResolution()
|
|
||||||
_height = h
|
|
||||||
prepareBuffers(w, h)
|
|
||||||
gpu.setForeground(0xFFFFFF)
|
|
||||||
gpu.setBackground(0x000000)
|
|
||||||
|
|
||||||
local gpuaddr = modules.component.api.register(nil, "gpu", gpu)
|
|
||||||
screenAddr = modules.component.api.register(nil, "screen", {getKeyboards = function() return {"TODO:SetThisUuid"} end}) --verry dummy screen, TODO: make it better, kbd uuid also in epoll.c
|
|
||||||
modules.component.api.register("TODO:SetThisUuid", "keyboard", {})
|
|
||||||
|
|
||||||
deadhooks[#deadhooks + 1] = function()
|
|
||||||
write("\x1b[?25h\x1b[" .. ((h-1)|0) .. ";1H") --Enable cursor on quit
|
|
||||||
io.flush()
|
|
||||||
termutils.restore()
|
|
||||||
end
|
|
||||||
|
|
||||||
return gpuaddr
|
|
||||||
end
|
|
||||||
|
|
||||||
return textgpu
|
|
Loading…
Reference in New Issue
Block a user