Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local luaPrint = print
- function isScreen(side, id)
- if wrap(side, id) then
- return true
- end
- return false
- end
- -- "Class" for handler for remote devices (via a wired modem)
- local RemoteHandler = {}
- RemoteHandler.new = function(side, id)
- local handler = {}
- handler.modem = peripheral.wrap(side)
- if handler.modem == nil then return end
- handler.side = side
- handler.id = id
- handler.name = "monitor_" .. id
- handler.isHandler = true
- handler.isRemoteHandler = true
- handler.clear = function() handler.modem.callRemote(handler.name, "clear") end
- handler.write = function(txt) return handler.modem.callRemote(handler.name, "write", txt) end
- handler.clearLine = function() handler.modem.callRemote(handler.name, "clearLine") end
- handler.getCursorPos = function() local a, b = handler.modem.callRemote(handler.name, "getCursorPos") return a, b end
- handler.getCursor = handler.getCursorPos
- handler.getCursorXPos = function() local a, b = handler.modem.callRemote(handler.name, "getCursorPos") return a end
- handler.getCursorX = handler.getCursorXPos
- handler.getX = handler.getCursorXPos
- handler.getCursorYPos = function() local a, b = handler.modem.callRemote(handler.name, "getCursorPos") return b end
- handler.getCursorY = handler.getCursorYPos
- handler.getY = handler.getCursorYPos
- handler.setCursorPos = function(a, b) handler.modem.callRemote(handler.name, "setCursorPos", a, b) end
- handler.setCursor = handler.setCursorPos
- handler.setCursorXPos = function(x) local a, b = handler.modem.callRemote(handler.name, "getCursorPos")
- handler.modem.callRemote(handler.name, "setCursorPos", x, b) end
- handler.setCursorX = handler.setCursorXPos
- handler.setX = handler.setCursorXPos
- handler.setCursorYPos = function(y) local a, b = handler.modem.callRemote(handler.name, "getCursorPos")
- handler.modem.callRemote(handler.name, "setCursorPos", a, y) end
- handler.setCursorY = handler.setCursorYPos
- handler.setY = handler.setCursorYPos
- handler.setCursorBlink = function(b) handler.modem.callRemote(handler.name, "setCursorBlink", b) end
- handler.setBlink = handler.setCursorBlink
- handler.isColor = function() return handler.modem.callRemote(handler.name, "isColor") end
- handler.getSize = function() local a, b = handler.modem.callRemote(handler.name, "getSize") return a, b end
- handler.getXSize = function() local a, b = handler.modem.callRemote(handler.name, "getSize") return a end
- handler.getYSize = function() local a, b = handler.modem.callRemote(handler.name, "getSize") return b end
- handler.scroll = function(n) handler.modem.callRemote(handler.name, "scroll", n) end
- handler.setTextScale = function(s) handler.modem.callRemote(handler.name, "setTextScale", s) end
- if handler.isColor() then
- handler.setTextColor = function(color) handler.modem.callRemote(handler.name, "setTextColor", color) end
- handler.setBackgroundColor = function(color) handler.modem.callRemote(handler.name, "setBackgroundColor", color) end
- handler.setBackColor = handler.setBackgroundColor
- handler.setColors = function(col1, col2) if col1 ~= nil then
- handler.modem.callRemote(handler.name, "setTextColor", col1)
- else
- handler.modem.callRemote(handler.name, "setTextColor", colours.white)
- end
- if col2 ~= nil then
- handler.modem.callRemote(handler.name, "setBackgroundColor", col2)
- else
- handler.modem.callRemote(handler.name, "setBackgroundColor", colours.black)
- end end
- end
- -- adding the additional API functions
- handler.reset = function() handler.modem.callRemote(handler.name, "clear") handler.modem.callRemote(handler.name, "setCursorPos", 1, 1) end
- handler.nextLine = function(scrolling) nextLine(handler.side, handler.id, scrolling) end
- handler.nextLines = function(n, scrolling) nextLines(n, handler.side, handler.id, scrolling) end
- handler.print = function(text, scrolling) return print(text, handler.side, handler.id, scrolling) end
- handler.println = function(text, scrolling) handler.print(text, handler.side, handler.id, scrolling) handler.nextLine(scrolling) return text end
- handler.left = function(text, scrolling) return left(text, handler.side, handler.id, scrolling) end
- return handler
- end
- -- "Class" for a normal handler (using this add methods that implements the function added by this API)
- local Handler = {}
- Handler.new = function(side)
- local handler = peripheral.wrap(side)
- if handler == nil then return end
- handler.side = side
- handler.isHandler = true
- handler.isRemoteHandler = false
- handler.getCursor = handler.getCursorPos
- handler.getCursorXPos = function() local a, b = handler.getCursorPos() return a end
- handler.getCursorX = handler.getCursorXPos
- handler.getX = handler.getCursorXPos
- handler.getCursorYPos = function() local a, b = handler.getCursorPos() return b end
- handler.getCursorY = handler.getCursorYPos
- handler.getY = handler.getCursorYPos
- handler.setCursor = handler.setCursorPos
- handler.setCursorXPos = function(x) local a, b = handler.getCursorPos() handler.setCursorPos(x, b) end
- handler.setCursorX = handler.setCursorXPos
- handler.setX = handler.setCursorXPos
- handler.setCursorYPos = function(y) local a, b = handler.getCursorPos() handler.setCursorPos(a, y) end
- handler.setCursorY = handler.setCursorYPos
- handler.setY = handler.setCursorYPos
- handler.getXSize = function() local a, b = handler.getSize() return a end
- handler.getYSize = function() local a, b = handler.getSize() return b end
- handler.setBlink = handler.setCursorBlink
- if handler.isColor() then
- handler.setBackColor = handler.setBackgroundColor
- handler.setColors = function(col1, col2) if col1 ~= nil then
- handler.setTextColor(col1)
- else
- handler.setTextColor(colours.white)
- end
- if col2 ~= nil then
- handler.setBackgroundColor(col2)
- else
- handler.setBackgroundColor(colours.black)
- end end
- end
- -- adding the additional API functions
- handler.reset = function() handler.clear() handler.setCursorPos(1, 1) end
- handler.nextLine = function(scrolling) nextLine(handler.side, nil, scrolling) end
- handler.nextLines = function(n, scrolling) nextLines(n, handler.side, nil, scrolling) end
- handler.print = function(text, scrolling) return print(text, handler.side, nil, scrolling) end
- handler.println = function(text, scrolling) handler.print(text, handler.side, nil, scrolling) handler.nextLine(scrolling) return text end
- handler.left = function(text, scrolling) return left(text, handler.side, nil, scrolling) end
- return handler
- end
- -- wrap around 'side', if 'side' is a modem, 'id' designate the number id of the monitor targetted (name structure is "monitor_id")
- function wrap(side, id)
- if side == nil then
- return term
- elseif peripheral.isPresent(side) then
- if peripheral.getType(side) == "monitor" then
- return Handler.new(side)
- elseif peripheral.getType(side) == "modem" and id ~= nil then
- local modem = peripheral.wrap(side)
- if modem.isPresentRemote and modem.isPresentRemote("monitor_" .. id) then
- return RemoteHandler.new(side, id)
- end
- end
- end
- luaPrint("wrap: invalid input").crash()
- end
- --------------------------------------------------------------------------------------------------------------------------
- -------------------------------------------REDEFINITION-OF-STANDARD-FUNCTIONS---------------------------------------------
- --------------------------------------------------------------------------------------------------------------------------
- -- Clear the screen
- function clear(side, id)
- wrap(side, id).clear()
- end
- -- Clear the line at the cursor's position
- function clearLine(side, id)
- wrap(side, id).clearLine()
- end
- -- Write a text at the cursor's position
- function write (text, side, id)
- return wrap(side, id).write(text)
- end
- -- Get the cursor's position
- -- getCursorPos, getCursor
- -- getCursorXPos, getCursorX, getX
- -- getCursorYPos, getCursorY, getY
- function getCursorPos(side, id)
- local a, b = wrap(side, id).getCursorPos()
- return a, b
- end
- getCursor = getCursorPos
- function getCursorXPos(side, id)
- local a, b = getCursorPos(side, id)
- return a
- end
- getCursorX = getCursorXPos
- getX = getCursorXPos
- function getCursorYPos(side, id)
- local a, b = getCursorPos(side, id)
- return b
- end
- getCursorY = getCursorYPos
- getY = getCursorYPos
- -- Set the cursor's position
- -- setCursorPos, setCursor
- -- setCursorXPos, setCursorX
- -- setCursorYPos, setCursorY
- function setCursorPos(x, y, side, id)
- wrap(side, id).setCursorPos(x, y)
- end
- setCursor = setCursorPos
- function setCursorXPos(x, side, id)
- local handler = wrap(side, id)
- local a, b = handler.getCursorPos()
- handler.setCursorPos(x, b)
- end
- setCursorX = setCursorXPos
- setX = setCursorXPos
- function setCursorYPos(y, side, id)
- local handler = wrap(side, id)
- local a, b = handler.getCursorPos()
- handler.setCursorPos(a, y)
- end
- setCursorY = setCursorYPos
- setY = setCursorYPos
- -- Set weither or not the cursor is blinking
- -- setCursorBlink, setBlink
- function setCursorBlink(b, side, id)
- wrap(side, id).setCursorBlink(b)
- end
- setBlink = setCursorBlink
- -- true if advanced, false if not
- function isColor(side, id)
- return wrap(side, id).isColor()
- end
- -- Get the screen's side
- -- getSize
- -- getXSize
- -- getYSize
- function getSize(side, id)
- local a, b = wrap(side, id).getSize()
- return a, b
- end
- function getXSize(side, id)
- local a, b = wrap(side, id).getCursorPos()
- return a
- end
- function getYSize(side, id)
- local a, b = wrap(side, id).getCursorPos()
- return b
- end
- -- Scroll the screen upward
- function scroll(n, side, id)
- wrap(side, id).scroll(n)
- end
- -- Set the scale of the monitor (has no effect on a terminal)
- function setTextScale(x, side, id)
- if side ~= nil then
- wrap(side, id).setTextScale(x)
- return true
- end
- return false
- end
- -- Set the text color (has no effect on a non-advanced screen
- function setTextColor(color, side, id)
- local handler = wrap(side, id)
- if handler.isColor() then
- handler.setTextColor(color)
- return true
- end
- return false
- end
- -- Set the background color (has no effect on a non-advanced screen
- function setBackgroundColor(color, side, id)
- local handler = wrap(side, id)
- if handler.isColor() then
- handler.setBackgroundColor(color)
- return true
- end
- return false
- end
- setBackColor = setBackgroundColor
- --------------------------------------------------------------------------------------------------------------------------
- --------------------------------------------ADDITIONAL-SIMPLE-FUNCTIONS---------------------------------------------------
- --------------------------------------------------------------------------------------------------------------------------
- -- clear the screen, then set the cursor back to (1,1)
- function reset(side, id)
- clear(side, id)
- setCursorPos(1, 1, side, id)
- end
- -- set the colors of both the background and the text
- function setColors(col1, col2, side, id)
- if handler.isColor() then
- if col1 ~= nil then
- handler.setTextColor(col1)
- else
- handler.setTextColor(colours.white)
- end
- if col2 ~= nil then
- handler.setBackgroundColor(col2)
- else
- handler.setBackgroundColor(colours.black)
- end
- return true
- end
- return false
- end
- -- go to the next line, return the number of lines scrolled
- -- if scrolling is true, will scroll the screen if on the last line
- function nextLine(side, id, scrolling)
- local x, y = getCursor(side, id)
- local a, b = getSize(side, id)
- if y < b then
- setCursor(1, y+1, side, id)
- return 0
- elseif y == b and scrolling then
- scroll(1, side, id)
- setCursor(1, y, side, id)
- return 1
- end
- setCursor(1, y, side, id)
- return 0
- end
- -- multilines version
- function nextLines(n, side, id, scrolling)
- local x, y = getCursor(side, id)
- local a, b = getSize(side, id)
- if y+n <= b then
- if y+n > 0 then
- setCursor(1, y+n, side, id)
- else
- setCursor(1, 1, side, id)
- end
- return 0
- end
- if scrolling then
- scroll(y+n-b, side, id)
- setCursor(1, b, side, id)
- return y+n-b
- end
- setCursor(1, b, side, id)
- return 0
- end
- -- print the text given to screen
- -- this function recognize the "\n" character and interprete them accordingly (with a new line)
- -- see nextLine function for the usage of "scrolling" argument"
- function print(text, side, id, scrolling)
- local handler = wrap(side, id)
- for i=1, text:len() do
- if text:sub(i, i) == "\n" then
- handler.nextLine(scrolling)
- else
- handler.write(text:sub(i, i))
- end
- end
- return text
- end
- -- print the given text and go to the next line
- -- this function recognize the "\n" character and interprete them accordingly (with a new line)
- -- see nextLine function for the usage of "scrolling" argument"
- function println(text, side, id, scrolling)
- local handler = wrap(side, id)
- handler.print(text, scrolling)
- handler.nextLine(scrolling)
- return text
- end
- --------------------------------------------------------------------------------------------------------------------------
- --------------------------------------------ALIGNMENT-AND-SPACE-PARSING-FUNCTIONS-----------------------------------------
- --------------------------------------------------------------------------------------------------------------------------
- -- return a structured table separating the lines and words
- -- the table is an integer array, going from 1 to n, where the line #n is the nth line of the text
- -- each line has a table containing an alternance of integers representing an amonth of blank spaces, and of string representing the words
- -- so an odd index for a line means the number of spaces, while an even number for a word
- local function parseWords(str)
- local words = {}
- words[1] = {}
- words[1][1] = 0
- local line = 1
- local element = 1
- for i=1, str:len() do
- local char = str:sub(i, i)
- if char == "\n" then
- line = line+1
- words[line] = {}
- element = 1
- words[line][1] = 0
- elseif char == " " then
- if element/2 == math.floor(element/2) then
- element = element+1
- words[line][element] = 1
- else
- words[line][element] = words[line][element]+1
- end
- else
- if element/2 == math.floor(element/2) then
- words[line][element] = words[line][element] .. char
- else
- element = element+1
- words[line][element] = char
- end
- end
- end
- return words
- end
- -- insert into an integer array table, value at key, if the value already exists, all the next elements are shifted the the next key
- local function table_insert(t, key, value)
- if type(key) ~= "number" then
- return false
- end
- if key > #t then
- t[#t+1] = value
- elseif key < 1 then
- table_append(t, 1, value)
- else
- for i=#t, key-1, -1 do
- t[i+1] = t[i]
- end
- t[key] = value
- end
- return t
- end
- -- remove elements from the integer array table t, from and including index start, till and including index ending
- local function table_remove(t, start, ending)
- if not ending then
- ending = start
- start = 1
- end
- if not start then
- start = 1
- ending = #t
- end
- for i=start, #t do
- if i > ending then
- t[i-ending-1+start] = t[i]
- end
- t[i] = nil
- end
- return t
- end
- -- return a strict duplicate of the table, reccursively dupplicating tables included as elements
- local function table_dupplicate(t)
- local newTable = {}
- for k, e in pairs(t) do
- if type(e) == "table" then
- newTable[k] = table_dupplicate(e)
- else
- newTable[k] = e
- end
- end
- return newTable
- end
- -- concatenate words from and including index a, till and including index b, at the given line
- -- this is to be applied on a table resulting from the above function "parseWords"
- local function concat_words(t, line, a, b)
- if not t or type(t) ~= "table" then return "" end
- local lineT = t[line]
- if not a then a = 1 b = #lineT end
- if not b then b = a a = 1 end
- if b-a <= 0 then return "" end
- local str = ""
- for i=a, b do
- if i/2 == math.floor(i/2) then
- str = str .. lineT[i]
- elseif lineT[i] > 0 then
- str = str .. string.rep(" ", lineT[i])
- end
- end
- return str
- end
- -- create a structured table showings lines to print in a screen of a given width
- -- ignore_trailing to true indicate that starting and trailing spaces are removed from the result
- -- the table is an integer array like the parseWords result
- -- each line is made up of 3 elements of indexes {1,2,3}
- -- [1] contains the starting spaces
- -- [2] contains the line body text
- -- [3] contains the trailing spaces
- local function parseLines(words, width, ignore_trailing)
- words = table_dupplicate(words)
- local lines = {}
- local i=1
- while i <= #words do
- lines[i] = {}
- local wordsLine = words[i]
- if ignore_trailing then
- wordsLine[1] = 0
- if (#wordsLine)/2 ~= math.floor((#wordsLine)/2) then
- wordsLine[#wordsLine] = 0
- end
- end
- local saveJ = nil
- for j=1, #wordsLine do
- saveJ = j
- --wrap("back", 0).print("Concatenation of line " .. i .. "\n until words #" .. j .. ':\n "' .. concat_words(words, i, j) .. '"\n', true)
- if concat_words(words, i, j):len() > width then
- saveJ = -1
- if j == 1 then
- -- wrap("back", 0).print("j == 1\n", true)
- lines[i][1] = 0
- lines[i][2] = ""
- lines[i][3] = width
- wordsLine[1] = wordsLine[1] - width
- if ignore_trailing then
- lines[i][3] = 0
- wordsLine[1] = 0
- end
- table_insert(words, i+1, wordsLine)
- break
- elseif j == 2 then
- -- wrap("back", 0).print("j == 2\n", true)
- lines[i][1] = 0
- if wordsLine[1] == 0 then
- lines[i][2] = string.sub(wordsLine[2], 1, width)
- lines[i][3] = 0
- wordsLine[2] = string.sub(wordsLine[2], width+1)
- table_insert(words, i+1, wordsLine)
- else
- lines[i][2] = ""
- lines[i][3] = wordsLine[1]
- if ignore_trailing then
- lines[i][3] = 0
- end
- wordsLine[1] = 0
- end
- table_insert(words, i+1, wordsLine)
- break
- elseif j == 3 then
- -- wrap("back", 0).print("j == 3\n", true)
- lines[i][1] = wordsLine[1]
- lines[i][2] = string.rep(" ", wordsLine[1]) .. wordsLine[2]
- lines[i][3] = 0
- table_remove(wordsLine, 2)
- if ignore_trailing then
- lines[i][1] = 0
- wordsLine[1] = 0
- end
- table_insert(words, i+1, wordsLine)
- break
- elseif j/2 == math.floor(j/2) then
- -- wrap("back", 0).print("j > 3 and last is odd\n", true)
- lines[i][1] = wordsLine[1]
- lines[i][2] = concat_words(words, i, j-2)
- lines[i][3] = wordsLine[j-1]
- table_remove(wordsLine, j-1)
- table_insert(wordsLine, 1, 0)
- if ignore_trailing then
- lines[i][1] = 0
- lines[i][3] = 0
- end
- table_insert(words, i+1, wordsLine)
- break
- else
- -- wrap("back", 0).print("j > 3 and last is even\n", true)
- lines[i][1] = wordsLine[1]
- lines[i][2] = concat_words(words, i, j-1)
- lines[i][3] = 0
- table_remove(wordsLine, j-1) -- in that case, the issue is with a set of spaces, so it's removed from the list so that the next word is sent away
- wordsLine[1] = 0
- if ignore_trailing then
- lines[i][1] = 0
- wordsLine[1] = 0
- end
- table_insert(words, i+1, wordsLine)
- break
- end
- end
- end
- if not saveJ then
- lines[i][1] = 0
- lines[i][2] = ""
- lines[i][3] = 0
- elseif saveJ > 0 then
- lines[i][1] = wordsLine[1]
- if (#wordsLine)/2 == math.floor((#wordsLine)/2) then
- lines[i][2] = concat_words(words, i, #wordsLine)
- lines[i][3] = 0
- else
- lines[i][2] = concat_words(words, i, (#wordsLine)-1)
- lines[i][3] = wordsLine[#wordsLine]
- end
- if ignore_trailing then
- lines[i][1] = 0
- lines[i][3] = 0
- end
- end
- --wrap("back", 0).print("(" .. lines[i][1] .. ', "' .. lines[i][2] .. '", ' .. lines[i][3] .. ")\n", true)
- i = i+1
- end
- return lines
- end
- -- print a left-aligned version of the text, parsed with the above functions to send to the next line any overflowing words
- -- this function recognize the "\n" character and interprete them accordingly (with a new line)
- -- see nextLine function for the usage of "scrolling" argument"
- -- if scrolling in disabled, it will only print the lines of text that fits the given space
- function left(text, side, id, scrolling)
- local handler = wrap(side, id)
- local width, height = handler.getSize()
- local x, y = handler.getCursor()
- term.clear()
- term.setCursorPos(1, 1)
- local words = parseWords(text)
- local lines = parseLines(words, width)
- if x > 1 then
- handler.nextLine(scrolling)
- end
- local str = ""
- if scrolling then
- for i=1, #lines do
- local tmp = string.rep(" ", lines[i][1]) .. lines[i][2]
- handler.write(tmp)
- str = str .. tmp
- if i < #lines then
- handler.nextLine(true)
- str = str .. "\n"
- end
- end
- else
- for i=y, height do
- if not lines[i-y+1] then
- break
- end
- local tmp = string.rep(" ", lines[i-y+1][1]) .. lines[i-y+1][2]
- handler.write(tmp)
- str = str .. tmp
- if i < height then
- handler.nextLine(false)
- str = str .. "\n"
- end
- end
- end
- return text
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement