1
0
mirror of https://github.com/LDDestroier/CC/ synced 2024-11-15 06:14:55 +00:00
ldd-CC/windont/windont.lua

659 lines
21 KiB
Lua
Raw Normal View History

-- Windon't
-- enhanced window API by LDDestroier
2019-12-09 07:30:33 +00:00
-- intended for general use within all me new programs
--
-- Unique features:
-- + Transparency within windows
-- + Built-in window layering
-- stores each base terminal's framebuffers to optimize rendering
local oldScreenBuffer = {}
local table_insert = table.insert
local table_concat = table.concat
local math_floor = math.floor
local to_blit = {}
local to_colors = {}
2019-12-14 01:12:53 +00:00
2020-02-04 05:53:49 +00:00
local table_compare = function(tbl1, tbl2)
if type(tbl1) ~= "table" or type(tbl2) ~= "table" then
return tbl1 == tbl2
else
for k,v in pairs(tbl1) do
if tbl1[k] ~= tbl2[k] then
return false
end
end
for k,v in pairs(tbl2) do
if tbl1[k] ~= tbl2[k] then
return false
end
end
return true
end
end
local getTime = function()
return 24 * os.day() + os.time()
end
2020-01-06 07:54:05 +00:00
for i = 1, 16 do
to_blit[2 ^ (i - 1)] = ("0123456789abcdef"):sub(i, i)
to_colors[("0123456789abcdef"):sub(i, i)] = 2 ^ (i - 1)
end
to_blit[0], to_colors["-"] = "-", 0
local nativePalette = { -- native palette colors, since some terminals are naughty and don't contain term.nativePaletteColor()
[ 1 ] = {
0.94117647409439,
0.94117647409439,
0.94117647409439,
},
[ 2 ] = {
0.94901961088181,
0.69803923368454,
0.20000000298023,
},
[ 4 ] = {
0.89803922176361,
0.49803921580315,
0.84705883264542,
},
[ 8 ] = {
0.60000002384186,
0.69803923368454,
0.94901961088181,
},
[ 16 ] = {
0.87058824300766,
0.87058824300766,
0.42352941632271,
},
[ 32 ] = {
0.49803921580315,
0.80000001192093,
0.098039217293262,
},
[ 64 ] = {
0.94901961088181,
0.69803923368454,
0.80000001192093,
},
[ 128 ] = {
0.29803922772408,
0.29803922772408,
0.29803922772408,
},
[ 256 ] = {
0.60000002384186,
0.60000002384186,
0.60000002384186,
},
[ 512 ] = {
0.29803922772408,
0.60000002384186,
0.69803923368454,
},
[ 1024 ] = {
0.69803923368454,
0.40000000596046,
0.89803922176361,
},
[ 2048 ] = {
0.20000000298023,
0.40000000596046,
0.80000001192093,
},
[ 4096 ] = {
0.49803921580315,
0.40000000596046,
0.29803922772408,
},
[ 8192 ] = {
0.34117648005486,
0.65098041296005,
0.30588236451149,
},
[ 16384 ] = {
0.80000001192093,
0.29803922772408,
0.29803922772408,
},
[ 32768 ] = {
0.066666670143604,
0.066666670143604,
0.066666670143604,
}
}
-- check if space on screenBuffer is transparent
local checkTransparent = function(buffer, x, y, blitLayer)
if buffer[blitLayer or 1][y] then
if blitLayer then
return (buffer[blitLayer][y][x] and buffer[blitLayer][y][x] ~= "-")
else
if (not buffer[2][y][x] or buffer[2][y][x] == "-") and (not buffer[3][y][x] or buffer[3][y][x] == "-") then
return false
elseif (not buffer[3][y][x] or buffer[3][y][x] == "-") and (not buffer[1][y][x] or buffer[1][y][x] == " ") then
return false
2020-01-06 07:54:05 +00:00
else
return buffer[1][y][x] and buffer[2][y][x] and buffer[3][y][x]
2020-01-06 07:54:05 +00:00
end
end
2019-12-14 01:12:53 +00:00
end
end
2020-01-06 07:54:05 +00:00
local expect = function(value, default, valueType)
if value == nil or (valueType and type(value) ~= valueType) then
return default
else
return value
end
end
2019-12-09 07:30:33 +00:00
local windont = {
doClearScreen = false, -- if true, will clear the screen during render
2020-01-30 06:50:15 +00:00
ignoreUnchangedLines = true, -- if true, the render function will check each line it renders against the last framebuffer and ignore it if they are the same
2020-01-12 07:30:28 +00:00
useSetVisible = false, -- if true, sets the base terminal's visibility to false before rendering
sameCharWillStencil = false, -- if true, if one window is layered atop another and both windows have a spot where the character is the same, and the top window's text color is transparent, it will use the TEXT color of the lower window instead of the BACKGROUND color
default = {
baseTerm = term.current(), -- default base terminal for all windows
textColor = "0", -- default text color (what " " corresponds to in term.blit's second argument)
backColor = "f", -- default background color (what " " corresponds to in term.blit's third argument)
blink = true,
visible = true,
alwaysRender = true, -- if true, new windows will always render if they are written to
},
info = {
BLIT_CALLS = 0, -- amount of term.blit calls during the last render
LAST_RENDER_TIME = 0, -- last time in which render was called
LAST_RENDER_AMOUNT = 0, -- amount of windows drawn during last render
LAST_RENDER_WINDOWS = {}, -- table of the last window objects that were rendered
}
}
-- draws one or more windon't objects
-- should not draw over any terminal space that isn't occupied by a window
windont.render = function(options, ...)
2020-01-30 06:50:15 +00:00
-- potential options:
-- number: onlyX1
-- number: onlyX2
-- number: onlyY
-- boolean: force (forces render / ignores optimiztaion that compares current framebuffer to old one)
-- terminal: baseTerm (forces to render onto this terminal instead of the window's base terminal)
2019-12-09 07:30:33 +00:00
local windows = {...}
options = options or {}
local bT, scr_x, scr_y
-- checks if "options" is actually the first window, just in case
if type(options.meta) == "table" then
if (
type(options.meta.buffer) == "table" and
type(options.meta.x) == "number" and
type(options.meta.y) == "number" and
type(options.meta.newBuffer) == "function"
) then
table_insert(windows, 1, options)
end
end
2019-12-09 07:30:33 +00:00
local screenBuffer = {{}, {}, {}}
local blitList = {} -- list of blit commands per line
local c = 1 -- current blitList entry
local cTime = getTime()
local AMNT_OF_BLITS = 0 -- how many blit calls are there?
2020-01-06 07:54:05 +00:00
local cx, cy -- each window's absolute X and Y
local char_cx, text_cx, back_cx -- each window's transformed absolute X's in table form
local char_cy, text_cy, back_cy -- each window's transformed absolute X's in table form
local buffer -- each window's buffer
local newChar, newText, newBack -- if the transformation function declares a new dot, this is it
local oriChar, oriText, oriBack
local char_out, text_out, back_out -- three tables, directly returned from the transformation functions
2019-12-09 07:30:33 +00:00
2019-12-11 09:26:37 +00:00
local baseTerms = {}
2020-01-30 06:50:15 +00:00
if type(options.baseTerm) == "table" then
for i = 1, #windows do
baseTerms[options.baseTerm] = baseTerms[options.baseTerm] or {}
baseTerms[options.baseTerm][i] = true
end
else
for i = 1, #windows do
baseTerms[windows[i].meta.baseTerm] = baseTerms[windows[i].meta.baseTerm] or {}
baseTerms[windows[i].meta.baseTerm][i] = true
end
2019-12-11 09:26:37 +00:00
end
2019-12-11 09:26:37 +00:00
for bT, bT_list in pairs(baseTerms) do
if bT == output then
bT = options.baseTerm or output.meta.baseTerm
end
2020-01-12 07:30:28 +00:00
if windont.useSetVisible and bT.setVisible then
bT.setVisible(false)
end
2019-12-11 09:26:37 +00:00
scr_x, scr_y = bT.getSize()
2020-01-06 07:54:05 +00:00
-- try entire buffer transformations
for i = #windows, 1, -1 do
if bT_list[i] then
if windows[i].meta.metaTransformation then
-- metaTransformation functions needn't return a value
windows[i].meta.metaTransformation(windows[i].meta)
end
end
end
for y = options.onlyY or 1, options.onlyY or scr_y do
2019-12-11 09:26:37 +00:00
screenBuffer[1][y] = {}
screenBuffer[2][y] = {}
screenBuffer[3][y] = {}
blitList = {}
c = 1
for x = options.onlyX1 or 1, math.min(scr_x, options.onlyX2 or scr_x) do
2019-12-11 09:26:37 +00:00
for i = #windows, 1, -1 do
if bT_list[i] then
2020-01-06 07:54:05 +00:00
newChar, newText, newBack = nil
2019-12-11 09:26:37 +00:00
if windows[i].meta.visible then
buffer = windows[i].meta.buffer
cx = 1 + x + -windows[i].meta.x
cy = 1 + y + -windows[i].meta.y
2019-12-11 09:26:37 +00:00
char_cx, text_cx, back_cx = cx, cx, cx
char_cy, text_cy, back_cy = cy, cy, cy
2020-01-06 07:54:05 +00:00
oriChar = (buffer[1][cy] or {})[cx]
oriText = (buffer[2][cy] or {})[cx]
oriBack = (buffer[3][cy] or {})[cx]
-- try transformation
if windows[i].meta.transformation then
char_out, text_out, back_out = windows[i].meta.transformation(cx, cy, oriChar, oriText, oriBack, windows[i].meta)
if char_out then
char_cx = math_floor(char_out[1] or cx)
char_cy = math_floor(char_out[2] or cy)
if (char_out[1] % 1 ~= 0) or (char_out[2] % 1 ~= 0) then
newChar = " "
else
newChar = char_out[3]
end
2019-12-11 09:26:37 +00:00
end
if text_out then
text_cx = math_floor(text_out[1] or cx)
text_cy = math_floor(text_out[2] or cy)
newText = text_out[3]
end
2019-12-11 09:26:37 +00:00
if back_out then
back_cx = math_floor(back_out[1] or cx)
back_cy = math_floor(back_out[2] or cy)
newBack = back_out[3]
end
2019-12-11 09:26:37 +00:00
end
if checkTransparent(buffer, char_cx, char_cy) or checkTransparent(buffer, text_cx, text_cy) or checkTransparent(buffer, back_cx, back_cy) then
screenBuffer[2][y][x] = newText or checkTransparent(buffer, text_cx, text_cy, 2) and (buffer[2][text_cy][text_cx]) or (
(buffer[1][text_cy][text_cx] == screenBuffer[1][y][x]) and (windont.sameCharWillStencil) and
screenBuffer[2][y][x]
or
screenBuffer[3][y][x]
)
screenBuffer[1][y][x] = newChar or checkTransparent(buffer, char_cx, char_cy ) and (buffer[1][char_cy][char_cx]) or screenBuffer[1][y][x]
screenBuffer[3][y][x] = newBack or checkTransparent(buffer, back_cx, back_cy, 3) and (buffer[3][back_cy][back_cx]) or screenBuffer[3][y][x]
2019-12-11 09:26:37 +00:00
end
end
end
2019-12-11 09:26:37 +00:00
end
if windont.doClearScreen then
2019-12-11 09:26:37 +00:00
screenBuffer[1][y][x] = screenBuffer[1][y][x] or " "
end
screenBuffer[2][y][x] = screenBuffer[2][y][x] or windont.default.backColor -- intentionally not the default text color
screenBuffer[3][y][x] = screenBuffer[3][y][x] or windont.default.backColor
2019-12-11 09:26:37 +00:00
if checkTransparent(screenBuffer, x, y) then
if checkTransparent(screenBuffer, -1 + x, y) then
2019-12-11 09:26:37 +00:00
blitList[c][1] = blitList[c][1] .. screenBuffer[1][y][x]
blitList[c][2] = blitList[c][2] .. screenBuffer[2][y][x]
blitList[c][3] = blitList[c][3] .. screenBuffer[3][y][x]
else
c = x
blitList[c] = {
screenBuffer[1][y][x],
screenBuffer[2][y][x],
screenBuffer[3][y][x]
}
end
2019-12-09 07:30:33 +00:00
end
end
if (not oldScreenBuffer[bT]) or (not windont.ignoreUnchangedLines) or (options.force) or (
2020-02-04 05:53:49 +00:00
(not table_compare(screenBuffer[1][y], oldScreenBuffer[bT][1][y])) or
(not table_compare(screenBuffer[2][y], oldScreenBuffer[bT][2][y])) or
(not table_compare(screenBuffer[3][y], oldScreenBuffer[bT][3][y]))
) then
for k,v in pairs(blitList) do
bT.setCursorPos(k, y)
bT.blit(v[1], v[2], v[3])
AMNT_OF_BLITS = 1 + AMNT_OF_BLITS
end
2019-12-09 07:30:33 +00:00
end
end
oldScreenBuffer[bT] = screenBuffer
2020-01-12 07:30:28 +00:00
if windont.useSetVisible and bT.setVisible then
if not multishell then
bT.setVisible(true)
elseif multishell.getFocus() == multishell.getCurrent() then
bT.setVisible(true)
end
2020-01-12 07:30:28 +00:00
end
2019-12-09 07:30:33 +00:00
end
windont.info.LAST_RENDER_AMOUNT = #windows
windont.info.BLIT_CALLS = AMNT_OF_BLITS
windont.info.LAST_RENDER_WINDOWS = windows
windont.info.LAST_RENDER_TIME = cTime
windont.info.LAST_RENDER_DURATION = getTime() + -cTime
2019-12-09 07:30:33 +00:00
end
-- creates a new windon't object that can be manipulated the same as a regular window
2019-12-09 07:30:33 +00:00
windont.newWindow = function( x, y, width, height, misc )
-- check argument types
assert(type(x) == "number", "argument #1 must be number, got " .. type(x))
assert(type(y) == "number", "argument #2 must be number, got " .. type(y))
assert(type(width) == "number", "argument #3 must be number, got " .. type(width))
assert(type(height) == "number", "argument #4 must be number, got " .. type(height))
-- check argument validity
assert(x > 0, "x position must be above zero")
assert(y > 0, "y position must be above zero")
assert(width > 0, "width must be above zero")
assert(height > 0, "height must be above zero")
local output = {}
misc = misc or {}
local meta = {
x = expect(x, 1), -- x position of the window
y = expect(y, 1), -- y position of the window
2020-01-06 07:54:05 +00:00
width = width, -- width of the buffer
height = height, -- height of the buffer
buffer = expect(misc.buffer, {}, "table"), -- stores contents of terminal in buffer[1][y][x] format
renderBuddies = expect(misc.renderBuddies, {}, "table"), -- renders any other window objects stored here after rendering here
baseTerm = expect(misc.baseTerm, windont.default.baseTerm, "table"), -- base terminal for which this window draws on
isColor = expect(misc.isColor, term.isColor(), "boolean"), -- if true, then it's an advanced computer
transformation = expect(misc.transformation, nil, "function"), -- function that transforms the char/text/back dots of the window
metaTransformation = expect(misc.miscTransformation, nil, "function"), -- function that transforms the whole output.meta function
cursorX = expect(misc.cursorX, 1),
cursorY = expect(misc.cursorY, 1),
textColor = expect(misc.textColor, windont.default.textColor, "string"), -- current text color
backColor = expect(misc.backColor, windont.default.backColor, "string"), -- current background color
blink = expect(misc.blink, windont.default.blink, "boolean"), -- cursor blink
alwaysRender = expect(misc.alwaysRender, windont.default.alwaysRender, "boolean"), -- render after every terminal operation
visible = expect(misc.visible, windont.default.visible, "boolean"), -- if false, don't render ever
-- make a new buffer (optionally uses an existing buffer as a reference)
2019-12-09 07:30:33 +00:00
newBuffer = function(width, height, char, text, back, drawAtop)
local output = {{}, {}, {}}
drawAtop = drawAtop or {{}, {}, {}}
2019-12-09 07:30:33 +00:00
for y = 1, height do
output[1][y] = output[1][y] or {}
output[2][y] = output[2][y] or {}
output[3][y] = output[3][y] or {}
for x = 1, width do
output[1][y][x] = (drawAtop[1][y] or {})[x] or (output[1][y][x] or (char or " "))
output[2][y][x] = (drawAtop[2][y] or {})[x] or (output[2][y][x] or (text or "0"))
output[3][y][x] = (drawAtop[3][y] or {})[x] or (output[3][y][x] or (back or "f"))
2019-12-09 07:30:33 +00:00
end
end
return output
end
}
2019-12-11 09:26:37 +00:00
bT = meta.baseTerm
-- initialize the buffer
2019-12-09 07:30:33 +00:00
meta.buffer = meta.newBuffer(meta.width, meta.height, " ", meta.textColor, meta.backColor)
output.meta = meta
2019-12-09 07:30:33 +00:00
output.write = function(text)
assert(type(text) == "string" or type(text) == "number", "expected string, got " .. type(text))
local initX = meta.cursorX
for i = 1, #tostring(text) do
2019-12-09 07:30:33 +00:00
if meta.cursorX >= 1 and meta.cursorX <= meta.width and meta.cursorY >= 1 and meta.cursorY <= meta.height then
if not meta.buffer[1] then
error("what the fuck happened")
end
meta.buffer[1][meta.cursorY][meta.cursorX] = tostring(text):sub(i,i)
2019-12-09 07:30:33 +00:00
meta.buffer[2][meta.cursorY][meta.cursorX] = meta.textColor
meta.buffer[3][meta.cursorY][meta.cursorX] = meta.backColor
end
meta.cursorX = meta.cursorX + 1
2019-12-09 07:30:33 +00:00
end
if meta.alwaysRender then
2020-01-06 07:54:05 +00:00
output.redraw(
-1 + meta.x + initX,
-1 + meta.x + meta.cursorX,
-1 + meta.y + meta.cursorY
)
end
2019-12-09 07:30:33 +00:00
end
output.blit = function(char, text, back)
assert(type(char) == "string" and type(text) == "string" and type(back) == "string", "all arguments must be strings")
assert(#char == #text and #text == #back, "arguments must be same length")
local initX = meta.cursorX
2019-12-09 07:30:33 +00:00
for i = 1, #char do
if meta.cursorX >= 1 and meta.cursorX <= meta.width and meta.cursorY >= 1 and meta.cursorY <= meta.height then
meta.buffer[1][meta.cursorY][meta.cursorX] = char:sub(i,i)
meta.buffer[2][meta.cursorY][meta.cursorX] = text:sub(i,i) == " " and windont.default.textColor or text:sub(i,i)
meta.buffer[3][meta.cursorY][meta.cursorX] = back:sub(i,i) == " " and windont.default.backColor or back:sub(i,i)
2019-12-09 07:30:33 +00:00
meta.cursorX = meta.cursorX + 1
end
end
if meta.alwaysRender then
2020-01-06 07:54:05 +00:00
output.redraw(
-1 + meta.x + initX,
-1 + meta.x + meta.cursorX,
-1 + meta.y + meta.cursorY
)
end
2019-12-09 07:30:33 +00:00
end
output.setCursorPos = function(x, y)
assert(type(x) == "number", "argument #1 must be number, got " .. type(x))
assert(type(y) == "number", "argument #2 must be number, got " .. type(y))
meta.cursorX, meta.cursorY = math.floor(x), math.floor(y)
2019-12-09 07:30:33 +00:00
if meta.alwaysRender then
if bT == output then
bT = output.meta.baseTerm
end
2020-01-06 07:54:05 +00:00
bT.setCursorPos(
-1 + meta.x + meta.cursorX,
-1 + meta.y + meta.cursorY
)
2019-12-09 07:30:33 +00:00
end
end
output.getCursorPos = function()
return meta.cursorX, meta.cursorY
end
output.setTextColor = function(color)
if to_blit[color] then
meta.textColor = to_blit[color]
2019-12-09 07:30:33 +00:00
else
error("Invalid color (got " .. color .. ")")
end
end
output.setTextColour = output.setTextColor
output.setBackgroundColor = function(color)
if to_blit[color] then
meta.backColor = to_blit[color]
2019-12-09 07:30:33 +00:00
else
error("Invalid color (got " .. color .. ")")
end
end
output.setBackgroundColour = output.setBackgroundColor
output.getTextColor = function()
return to_colors[meta.textColor]
2019-12-09 07:30:33 +00:00
end
output.getTextColour = output.getTextColor
output.getBackgroundColor = function()
return to_colors[meta.backColor]
2019-12-09 07:30:33 +00:00
end
output.getBackgroundColour = output.getBackgroundColor
output.setVisible = function(visible)
2020-01-12 08:31:16 +00:00
assert(type(visible) == "boolean", "bad argument #1 (expected boolean, got " .. type(visible) .. ")")
2019-12-09 07:30:33 +00:00
meta.visible = visible and true or false
end
output.clear = function()
meta.buffer = meta.newBuffer(meta.width, meta.height, " ", meta.textColor, meta.backColor)
if meta.alwaysRender then
output.redraw()
end
2019-12-09 07:30:33 +00:00
end
output.clearLine = function()
meta.buffer[1][meta.cursorY] = nil
meta.buffer[2][meta.cursorY] = nil
meta.buffer[3][meta.cursorY] = nil
2019-12-09 07:30:33 +00:00
meta.buffer = meta.newBuffer(meta.width, meta.height, " ", meta.textColor, meta.backColor, meta.buffer)
if meta.alwaysRender then
2020-01-06 07:54:05 +00:00
bT.setCursorPos(meta.x, -1 + meta.y + meta.cursorY)
bT.blit(
(" "):rep(meta.width),
(meta.textColor):rep(meta.width),
(meta.backColor):rep(meta.width)
)
2019-12-09 07:30:33 +00:00
end
end
output.getLine = function(y)
assert(type(y) == "number", "bad argument #1 (expected number, got " .. type(y) .. ")")
assert(meta.buffer[1][y], "Line is out of range.")
return table_concat(meta.buffer[1][y]), table_concat(meta.buffer[2][y]), table_concat(meta.buffer[3][y])
2019-12-09 07:30:33 +00:00
end
output.scroll = function(amplitude)
2019-12-14 01:12:53 +00:00
if math.abs(amplitude) < meta.height then -- minor optimization
local blank = {{}, {}, {}}
for x = 1, meta.width do
blank[1][x] = " "
blank[2][x] = meta.textColor
blank[3][x] = meta.backColor
end
for y = 1, meta.height do
meta.buffer[1][y] = meta.buffer[1][y + amplitude] or blank[1]
meta.buffer[2][y] = meta.buffer[2][y + amplitude] or blank[2]
meta.buffer[3][y] = meta.buffer[3][y + amplitude] or blank[3]
2019-12-09 07:30:33 +00:00
end
else
2019-12-14 01:12:53 +00:00
meta.buffer = meta.newBuffer(meta.width, meta.height, " ", meta.textColor, meta.backColor)
2019-12-09 07:30:33 +00:00
end
if meta.alwaysRender then
2020-01-06 07:54:05 +00:00
if math_floor(amplitude) ~= 0 then
2019-12-14 01:12:53 +00:00
output.redraw()
end
2019-12-09 07:30:33 +00:00
end
end
output.getSize = function()
2020-02-23 23:54:44 +00:00
return meta.width, meta.height
2019-12-09 07:30:33 +00:00
end
output.isColor = function()
return meta.isColor
end
output.isColour = output.isColor
output.reposition = function(x, y, width, height)
assert(type(x) == "number", "bad argument #1 (expected number, got " .. type(x) .. ")")
assert(type(y) == "number", "bad argument #2 (expected number, got " .. type(y) .. ")")
2020-01-06 07:54:05 +00:00
meta.x = math_floor(x)
meta.y = math_floor(y)
2019-12-09 07:30:33 +00:00
if width then
assert(type(width) == "number", "bad argument #3 (expected number, got " .. type(width) .. ")")
assert(type(height) == "number", "bad argument #4 (expected number, got " .. type(height) .. ")")
meta.width = width
meta.height = height
meta.buffer = meta.newBuffer(meta.width, meta.height, " ", meta.textColor, meta.backColor, meta.buffer)
end
if meta.alwaysRender then
output.redraw()
end
end
output.restoreCursor = function()
bT.setCursorPos(
2020-01-06 07:54:05 +00:00
math.max(0, -1 + meta.x + meta.cursorX),
math.max(0, -1 + meta.y + meta.cursorY)
)
2019-12-09 07:30:33 +00:00
bT.setCursorBlink(meta.blink)
end
output.getPosition = function()
return meta.x, meta.y
end
output.setCursorBlink = function(blink)
meta.blink = blink and true or false
end
output.getCursorBlink = function(blink)
return meta.blink
end
output.setPaletteColor = bT.setPaletteColor
output.setPaletteColour = bT.setPaletteColour
output.getPaletteColor = bT.getPaletteColor
output.getPaletteColour = bT.getPaletteColour
if bT.getPaletteColor then
output.nativePaletteColor = bT.nativePaletteColor or function(col)
if nativePalette[col] then
return table.unpack(nativePalette[col])
else
return table.unpack(nativePalette[1]) -- I don't get how this function takes in non-base2 numbers...
end
end
end
output.redraw = function(x1, x2, y, options)
options = options or {}
options.onlyX1 = x1
options.onlyX2 = x2
options.onlyY = y
if #meta.renderBuddies > 0 then
windont.render(options, output, table.unpack(meta.renderBuddies))
else
windont.render(options, output)
end
output.restoreCursor()
2019-12-09 07:30:33 +00:00
end
if meta.alwaysRender then
output.redraw()
end
2019-12-09 07:30:33 +00:00
return output
end
return windont