diff --git a/windont/windont.lua b/windont/windont.lua index e44f0a0..468ab99 100644 --- a/windont/windont.lua +++ b/windont/windont.lua @@ -24,18 +24,27 @@ local lval = { end, -- check if space on screenBuffer is transparent - check = function(buff, x, y, blitLayer) - if buff[blitLayer or 1][y] then - return (blitLayer or buff[1][y][x]) and ( - (not buff[blitLayer or 2][y][x] or buff[blitLayer or 2][y][x] ~= "-") or - (not buff[blitLayer or 3][y][x] or buff[blitLayer or 3][y][x] ~= "-") - ) and ( - not (buff[1][y][x] == " " and buff[3][y][x] == "-") - ) + + check = 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 buffer[1][y][x] == " " then + return false + else + return true + end + end end end } +local table_insert = table.insert +local math_floor = math.floor + for i = 1, 16 do lval.to_blit[2 ^ (i - 1)] = ("0123456789abcdef"):sub(i, i) lval.to_colors[("0123456789abcdef"):sub(i, i)] = 2 ^ (i - 1) @@ -67,23 +76,24 @@ windont.render = function(onlyX1, onlyX2, onlyY, ...) local windows = {...} local bT local check = lval.check + local screenBuffer = {{}, {}, {}} local scr_x, scr_y local blitList = {} -- list of blit commands per line local c = 1 -- current blitList entry if type(onlyY) == "table" then - table.insert(windows, 1, onlyY) + table_insert(windows, 1, onlyY) onlyY = nil end if type(onlyX2) == "table" then - table.insert(windows, 1, onlyX2) + table_insert(windows, 1, onlyX2) onlyX2 = nil end if type(onlyX1) == "table" then - table.insert(windows, 1, onlyX1) + table_insert(windows, 1, onlyX1) onlyX1 = nil end @@ -91,11 +101,12 @@ windont.render = function(onlyX1, onlyX2, onlyY, ...) local AMNT_OF_BLITS = 0 -- how many blit calls are there? - 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 newChar, newText, newBack -- if the transformation function declares a new dot, this is it - local tBlit, tSetCursorPos -- each baseTerm's blit and setCursorPos functions + 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 baseTerms = {} for i = 1, #windows do @@ -108,8 +119,15 @@ windont.render = function(onlyX1, onlyX2, onlyY, ...) bT = output.meta.baseTerm end scr_x, scr_y = bT.getSize() - tBlit = bT.blit - tSetCursorPos = bT.setCursorPos + -- 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 = onlyY or 1, onlyY or scr_y do screenBuffer[1][y] = {} screenBuffer[2][y] = {} @@ -119,40 +137,41 @@ windont.render = function(onlyX1, onlyX2, onlyY, ...) for x = onlyX1 or 1, math.min(scr_x, onlyX2 or scr_x) do for i = #windows, 1, -1 do if bT_list[i] then + newChar, newText, newBack = nil if windows[i].meta.visible then buffer = windows[i].meta.buffer - newChar = (buffer[1][y] or {})[x] - newText = (buffer[2][y] or {})[x] - newBack = (buffer[3][y] or {})[x] - cx = 1 + x + -windows[i].meta.x cy = 1 + y + -windows[i].meta.y char_cx, text_cx, back_cx = cx, cx, cx char_cy, text_cy, back_cy = cy, cy, cy + oriChar = (buffer[1][cy] or {})[cx] + oriText = (buffer[2][cy] or {})[cx] + oriBack = (buffer[3][cy] or {})[cx] + -- try char transformation if windows[i].meta.charTransformation then - char_cx, char_cy, newChar = windows[i].meta.charTransformation(cx, cy, newChar, windows[i].meta) - char_cx = math.floor(char_cx or cx) - char_cy = math.floor(char_cy or cy) - if char_cx ~= math.floor(char_cx) or char_cy ~= math.floor(char_cy) then + char_cx, char_cy, newChar = windows[i].meta.charTransformation(cx, cy, {oriChar, oriText, oriBack}, windows[i].meta) + if char_cx ~= math_floor(char_cx) or char_cy ~= math_floor(char_cy) then newChar = " " end + char_cx = math_floor(char_cx or cx) + char_cy = math_floor(char_cy or cy) end -- try text transformation if windows[i].meta.textTransformation then - text_cx, text_cy, newText = windows[i].meta.textTransformation(cx, cy, newText, windows[i].meta) - text_cx = math.floor(text_cx or cx) - text_cy = math.floor(text_cy or cy) + text_cx, text_cy, newText = windows[i].meta.textTransformation(cx, cy, {oriChar, oriText, oriBack}, windows[i].meta) + text_cx = math_floor(text_cx or cx) + text_cy = math_floor(text_cy or cy) end -- try back transformation if windows[i].meta.backTransformation then - back_cx, back_cy, newBack = windows[i].meta.backTransformation(cx, cy, newBack, windows[i].meta) - back_cx = math.floor(back_cx or cx) - back_cy = math.floor(back_cy or cy) + back_cx, back_cy, newBack = windows[i].meta.backTransformation(cx, cy, {oriChar, oriText, oriBack}, windows[i].meta) + back_cx = math_floor(back_cx or cx) + back_cy = math_floor(back_cy or cy) end if check(buffer, char_cx, char_cy) or check(buffer, text_cx, text_cy) or check(buffer, back_cx, back_cy) then @@ -171,7 +190,7 @@ windont.render = function(onlyX1, onlyX2, onlyY, ...) screenBuffer[3][y][x] = screenBuffer[3][y][x] or windont.default.backColor if check(screenBuffer, x, y) then - if check(screenBuffer, x - 1, y) then + if check(screenBuffer, -1 + x, y) then 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] @@ -186,9 +205,9 @@ windont.render = function(onlyX1, onlyX2, onlyY, ...) end end for k,v in pairs(blitList) do - tSetCursorPos(k, y) - tBlit(v[1], v[2], v[3]) - AMNT_OF_BLITS = AMNT_OF_BLITS + 1 + bT.setCursorPos(k, y) + bT.blit(v[1], v[2], v[3]) + AMNT_OF_BLITS = 1 + AMNT_OF_BLITS end end end @@ -197,7 +216,7 @@ windont.render = function(onlyX1, onlyX2, onlyY, ...) windont.info.BLIT_CALLS = AMNT_OF_BLITS windont.info.LAST_RENDER_WINDOWS = windows windont.info.LAST_RENDER_TIME = cTime - windont.info.LAST_RENDER_DURATION = lval.getTime() - cTime + windont.info.LAST_RENDER_DURATION = lval.getTime() + -cTime end @@ -220,10 +239,10 @@ windont.newWindow = function( x, y, width, height, misc ) local output = {} misc = misc or {} local meta = { - x = lval.expect(x, 1), -- x position of the window - y = lval.expect(y, 1), -- y position of the window - width = width, -- width of the buffer - height = height, -- height of the buffer + x = lval.expect(x, 1), -- x position of the window + y = lval.expect(y, 1), -- y position of the window + width = width, -- width of the buffer + height = height, -- height of the buffer buffer = lval.expect(misc.buffer, {}, "table"), -- stores contents of terminal in buffer[1][y][x] format renderBuddies = lval.expect(misc.renderBuddies, {}, "table"), -- renders any other window objects stored here after rendering here baseTerm = lval.expect(misc.baseTerm, windont.default.baseTerm, "table"), -- base terminal for which this window draws on @@ -232,12 +251,13 @@ windont.newWindow = function( x, y, width, height, misc ) charTransformation = lval.expect(misc.charTransformation, nil, "function"), -- function that transforms the characters of the window textTransformation = lval.expect(misc.textTransformation, nil, "function"), -- function that transforms the text colors of the window backTransformation = lval.expect(misc.backTransformation, nil, "function"), -- function that transforms the BG colors of the window + metaTransformation = lval.expect(misc.miscTransformation, nil, "function"), -- function that transforms the whole output.meta function cursorX = lval.expect(misc.cursorX, 1), cursorY = lval.expect(misc.cursorY, 1), - textColor = lval.expect(misc.textColor, windont.default.textColor, "string"), -- current text color - backColor = lval.expect(misc.backColor, windont.default.backColor, "string"), -- current background color + textColor = lval.expect(misc.textColor, windont.default.textColor, "string"), -- current text color + backColor = lval.expect(misc.backColor, windont.default.backColor, "string"), -- current background color blink = lval.expect(misc.blink, windont.default.blink, "boolean"), -- cursor blink alwaysRender = lval.expect(misc.alwaysRender, windont.default.alwaysRender, "boolean"), -- render after every terminal operation @@ -282,7 +302,11 @@ windont.newWindow = function( x, y, width, height, misc ) meta.cursorX = meta.cursorX + 1 end if meta.alwaysRender then - output.redraw(meta.x + initX - 1, meta.x + meta.cursorX - 1, meta.y + meta.cursorY - 1) + output.redraw( + -1 + meta.x + initX, + -1 + meta.x + meta.cursorX, + -1 + meta.y + meta.cursorY + ) end end @@ -299,7 +323,11 @@ windont.newWindow = function( x, y, width, height, misc ) end end if meta.alwaysRender then - output.redraw(meta.x + initX - 1, meta.x + meta.cursorX - 1, meta.y + meta.cursorY - 1) + output.redraw( + -1 + meta.x + initX, + -1 + meta.x + meta.cursorX, + -1 + meta.y + meta.cursorY + ) end end @@ -311,7 +339,10 @@ windont.newWindow = function( x, y, width, height, misc ) if bT == output then bT = output.meta.baseTerm end - bT.setCursorPos(meta.x + meta.cursorX - 1, meta.y + meta.cursorY - 1) + bT.setCursorPos( + -1 + meta.x + meta.cursorX, + -1 + meta.y + meta.cursorY + ) end end @@ -365,7 +396,12 @@ windont.newWindow = function( x, y, width, height, misc ) meta.buffer[3][meta.cursorY] = nil meta.buffer = meta.newBuffer(meta.width, meta.height, " ", meta.textColor, meta.backColor, meta.buffer) if meta.alwaysRender then - output.redraw(meta.x, meta.x + meta.width - 1, meta.y + meta.cursorY - 1) + bT.setCursorPos(meta.x, -1 + meta.y + meta.cursorY) + bT.blit( + (" "):rep(meta.width), + (meta.textColor):rep(meta.width), + (meta.backColor):rep(meta.width) + ) end end @@ -392,7 +428,7 @@ windont.newWindow = function( x, y, width, height, misc ) meta.buffer = meta.newBuffer(meta.width, meta.height, " ", meta.textColor, meta.backColor) end if meta.alwaysRender then - if math.floor(amplitude) ~= 0 then + if math_floor(amplitude) ~= 0 then output.redraw() end end @@ -410,8 +446,8 @@ windont.newWindow = function( x, y, width, height, misc ) 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) .. ")") - meta.x = math.floor(x) - meta.y = math.floor(y) + meta.x = math_floor(x) + meta.y = math_floor(y) 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) .. ")") @@ -426,8 +462,8 @@ windont.newWindow = function( x, y, width, height, misc ) output.restoreCursor = function() bT.setCursorPos( - math.max(0, meta.x + meta.cursorX - 1), - math.max(0, meta.y + meta.cursorY - 1) + math.max(0, -1 + meta.x + meta.cursorX), + math.max(0, -1 + meta.y + meta.cursorY) ) bT.setCursorBlink(meta.blink) end