|
--[[ |
|
multiMon v1.1 - An API which allows multiple monitor objects to act as a single virtual monitor. |
|
v1.0 Copyright (C) 2014 Shazz |
|
v1.1 Copyright (C) 2022 MineRobber___T |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
--]] |
|
|
|
if multiMon then |
|
for k,v in pairs(multiMon) do |
|
_ENV[k] = v |
|
end |
|
return |
|
end |
|
|
|
local multiMons={} |
|
-- peripheral.getNames() override. |
|
local oGetNames = peripheral.getNames |
|
function peripheral.getNames() |
|
local tbl = oGetNames() |
|
for k,v in pairs(multiMons) do table.insert(tbl,k) end |
|
return tbl |
|
end |
|
|
|
-- peripheral.isPresent() override. |
|
local oIsPresent = peripheral.isPresent |
|
function peripheral.isPresent(side) |
|
if multiMons[side] then |
|
return true |
|
else |
|
return oIsPresent(side) |
|
end |
|
end |
|
|
|
-- peripheral.getType() override. |
|
local oGetType = peripheral.getType |
|
function peripheral.getType(side) |
|
if multiMons[side] then |
|
return 'monitor' |
|
else |
|
return oGetType(side) |
|
end |
|
end |
|
|
|
local function startsWith(s,b) |
|
return s:sub(1,#b)==b |
|
end |
|
|
|
-- peripheral.getMethods() override. |
|
local oGetMethods = peripheral.getMethods |
|
function peripheral.getMethods(side) |
|
if multiMons[side] then |
|
local retTbl = {} |
|
for k, v in pairs(multiMons[side]) do |
|
if not startsWith(k,"__") then |
|
table.insert(retTbl, k) |
|
end |
|
end |
|
return retTbl |
|
else |
|
return oGetMethods(side) |
|
end |
|
end |
|
|
|
-- peripheral.call() override. |
|
local oCall = peripheral.call |
|
function peripheral.call(side, method, ...) |
|
if multiMons[side] and type(method) == 'string' then |
|
if type(multiMons[side][method]) ~= 'function' or startsWith(method,"__") then |
|
error('No such method ' .. method, 2) |
|
else |
|
return multiMons[side][method](...) |
|
end |
|
else |
|
return oCall(side, method, ...) |
|
end |
|
end |
|
|
|
|
|
-- os.pullEventRaw() override. |
|
local oPullEventRaw = os.pullEventRaw |
|
function os.pullEventRaw(...) |
|
local ev = {oPullEventRaw(...)} |
|
|
|
if ev[1] == 'monitor_touch' then |
|
for name, public in pairs(multiMons) do |
|
local tall, wide, monitors, getVirtual = public.__tall, public.__wide, public.__monitors, public.__getVirtual |
|
local toBreak = false |
|
for monY = 1, tall do |
|
for monX = 1, wide do |
|
if ev[2] == peripheral.getName(monitors[monY][monX]) then |
|
os.queueEvent('monitor_touch', name, getVirtual(monX, monY, ev[3], ev[4])) |
|
oPullEventRaw(...) -- load-bearing pullEventRaw call; without it the monitor touch event gets queued 4 times for some ungodly reason |
|
|
|
toBreak = true |
|
break |
|
end |
|
end |
|
if toBreak then |
|
break |
|
end |
|
end |
|
if toBreak then |
|
break |
|
end |
|
end |
|
end |
|
|
|
return unpack(ev) |
|
end |
|
|
|
function uninstall() |
|
peripheral.getNames=oGetNames |
|
peripheral.isPresent=oIsPresent |
|
peripheral.getType=oGetType |
|
peripheral.getMethods=oGetMethods |
|
peripheral.call=oCall |
|
os.pullEventRaw=oPullEventRaw |
|
_G.multiMon=nil |
|
return |
|
end |
|
|
|
--// Function: create - Creates a virtual monitor out of multiple monitor objects stitched together. |
|
---- Argument: name - Name of the virtual monitor. |
|
---- Argument: monitors - A table in format: { { object [, ...] } [, ...] } contaning the monitor objects to be stitched. |
|
---- Argument: wide - Optional (default: determined by 'monitors' argument). Amount of monitor objects stacked horizontally. |
|
---- Argument: tall - Optional (default: determined by 'monitors' argument). Amount of monitor objects stacked vertically. |
|
---- Argument: width - Optional (default: the width of the first object in 'monitors' argument). Width of each monitor object. |
|
---- Argument: height - Optional (default: the height of the first object in 'monitors' argument). Height of each monitor object. |
|
---- Return: handle - A handle to the virtual monitor created. Same as calling peripheral.wrap(name). |
|
function create(name, monitors, _wide, _tall, _width, _height) |
|
--// Parameters |
|
-- Make sure all parameters are of correct type. |
|
if |
|
type(name) ~= 'string' or |
|
type(monitors) ~= 'table' or |
|
(_wide ~= nil and type(_wide) ~= 'number') or |
|
(_tall ~= nil and type(_tall) ~= 'number') or |
|
(_width ~= nil and type(_width) ~= 'number') or |
|
(_height ~= nil and type(_height) ~= 'number') |
|
then |
|
error('Expected string, table [, table [, number [, number [, number [, number ]]]]]', 2) |
|
end |
|
|
|
-- Make sure 'name' doesn't already exist. |
|
if peripheral.isPresent(name) then |
|
error('name already exists', 2) |
|
end |
|
|
|
-- Make sure the 'monitors' object is in the correct format. |
|
if |
|
#monitors < 1 or |
|
type(monitors[1]) ~= 'table' or |
|
#monitors[1] < 1 |
|
then |
|
error('monitors expected in format: { { object [, ...] } [, ...] }', 2) |
|
end |
|
|
|
for y=1,#monitors do |
|
for x=1,#monitors[y] do |
|
if type(monitors[y][x])=="string" then |
|
if peripheral.isPresent(monitors[y][x]) then |
|
monitors[y][x]=peripheral.wrap(monitors[y][x]) |
|
else |
|
error(("bad peripheral %q (no such peripheral)"):format(monitors[y][x])) |
|
end |
|
end |
|
if type(monitors[y][x])~="table" or (getmetatable(monitors[y][x]) or {}).__name~="peripheral" then |
|
error(("item at monitors[%d][%d] is not a peripheral (is type %q)"):format(y,x,type(monitors[y][x]))) |
|
end |
|
if peripheral.getType(monitors[y][x])~="monitor" then error(("bad peripheral %q (expected monitor, got %s)"):format(peripheral.getName(monitors[y][x]),peripheral.getType(monitors[y][x]))) end |
|
end |
|
end |
|
|
|
-- Make sure that the 'monitors' object doesn't have an empty row and get the smallest width. |
|
local minWide |
|
for i = 1, #monitors do |
|
if not minWide then |
|
minWide = #monitors[i] |
|
elseif #monitors[i] < minWide then |
|
minWide = #monitors[i] |
|
end |
|
end |
|
if minWide < 1 then |
|
error('monitors has empty row(s)', 2) |
|
end |
|
|
|
|
|
--// Private |
|
local wide, tall = _wide or minWide, _tall or #monitors |
|
local monWidth, monHeight |
|
local width, height |
|
local isColour = (function() |
|
-- Only set 'isColour' to true if all monitors are advanced. |
|
local isColourCount = 0 |
|
for monY = 1, tall do |
|
for monX = 1, wide do |
|
if monitors[monY][monX].isColour and monitors[monY][monX].isColour() then |
|
isColourCount = isColourCount + 1 |
|
end |
|
end |
|
end |
|
if isColourCount < tall * wide then |
|
return false |
|
else |
|
return true |
|
end |
|
end)() |
|
|
|
|
|
local posX, posY = 1, 1 |
|
local textColour = colours.white |
|
local backColour = colours.black |
|
local cursorBlink = false |
|
local textScale = 1 |
|
|
|
local emptyLine |
|
local buffer |
|
|
|
local log2 = math.log(2) |
|
local tHex = {['0'] = 1, ['1'] = 2, ['2'] = 4, ['3'] = 8, ['4'] = 16, ['5'] = 32, ['6'] = 64, ['7'] = 128, ['8'] = 256, ['9'] = 512, ['A'] = 1024, ['B'] = 2048, ['C'] = 4096, ['D'] = 8192, ['E'] = 16384, ['F'] = 32768} |
|
|
|
-- Converts from a colour (int) to an uppercase hex character. |
|
local function colourToHex(colour) |
|
return string.format('%X', math.floor(math.log(colour) / log2)) |
|
end |
|
|
|
-- Converts an uppercase hex character into a colour (int). |
|
local function hexToColour(hex) |
|
return tHex[hex] |
|
end |
|
|
|
-- Mocks the Java .toString() invoked when calling mon.write with non-strings. |
|
local function javaToString(val) |
|
local valType = type(val) |
|
if valType == 'string' then |
|
return val |
|
elseif valType == 'number' then |
|
if val % 1 == 0 then |
|
return tostring(val) .. '.0' |
|
else |
|
return tostring(val) |
|
end |
|
elseif valType == 'boolean' then |
|
return tostring(val) |
|
elseif valType == 'table' then |
|
local function tbl(val, tables) |
|
tables = tables or {} |
|
if tables[val] then |
|
return '(this Map)' |
|
end |
|
tables[val] = true |
|
|
|
local str = '{' |
|
for k, v in pairs(val) do |
|
local key |
|
if type(k) == 'table' then |
|
key = tbl(k, tables) |
|
else |
|
key = javaToString(k) |
|
end |
|
|
|
if key then |
|
local value |
|
if type(v) == 'table' then |
|
value = tbl(v, tables) |
|
else |
|
value = javaToString(v) |
|
end |
|
|
|
if value then |
|
str = str .. key .. '=' .. value .. ', ' |
|
end |
|
end |
|
end |
|
|
|
tables[val] = nil |
|
|
|
if #str > 1 then |
|
return string.sub(str, 1, -3) .. '}' |
|
else |
|
return str .. '}' |
|
end |
|
end |
|
|
|
return tbl(val) |
|
else |
|
return nil |
|
end |
|
end |
|
|
|
-- Calculate width & height variables and clear the buffer. |
|
local function calculate() |
|
monWidth = _width or select(1, monitors[1][1].getSize()) |
|
monHeight = _height or select(2, monitors[1][1].getSize()) |
|
width, height = monWidth * wide, monHeight * tall |
|
|
|
emptyLine = string.rep(' ', width) |
|
buffer = {} |
|
for y = 1, height do |
|
buffer[y] = {text = emptyLine, textColour = string.rep(colourToHex(textColour), width), backColour = string.rep(colourToHex(backColour), width)} |
|
end |
|
end |
|
|
|
-- Gets the real x from the virtual x. |
|
local function getRealX(x) |
|
local monX = math.ceil(x / monWidth) |
|
|
|
if x > monWidth then |
|
if x % monWidth == 0 then |
|
x = monWidth |
|
else |
|
x = x % monWidth |
|
end |
|
end |
|
|
|
return monX, x |
|
end |
|
|
|
-- Gets the real y from the virtual y. |
|
local function getRealY(y) |
|
local monY = math.ceil(y / monHeight) |
|
|
|
if y > monHeight then |
|
if y % monHeight == 0 then |
|
y = monHeight |
|
else |
|
y = y % monHeight |
|
end |
|
end |
|
|
|
return monY, y |
|
end |
|
|
|
-- Gets the real x, y from the virtual x, y. |
|
local function getReal(x, y) |
|
local monX, x = getRealX(x) |
|
local monY, y = getRealY(y) |
|
|
|
return monitors[monY][monX], x, y |
|
end |
|
|
|
-- Gets the virtual x, y from the real x, y. |
|
local function getVirtual(monX, monY, x, y) |
|
x = x + (monWidth * (monX - 1)) |
|
y = y + (monHeight * (monY - 1)) |
|
return x, y |
|
end |
|
|
|
-- Updates cursor's colour (to make sure the cursor blinks in the right colour). |
|
local function updateCursorColour() |
|
for monY = 1, tall do |
|
for monX = 1, wide do |
|
monitors[monY][monX].setTextColour(textColour) |
|
end |
|
end |
|
end |
|
|
|
-- Updates cursor's position (to make sure the cursor blinks in the right position). |
|
local function updateCursorPos() |
|
for monY = 1, tall do |
|
for monX = 1, wide do |
|
monitors[monY][monX].setCursorPos(0, 0) |
|
end |
|
end |
|
|
|
if posX >= 1 and posX <= width and posY >= 1 and posY <= height then |
|
local mon, x, y = getReal(posX, posY) |
|
mon.setCursorPos(x, y) |
|
end |
|
end |
|
|
|
-- Updates cursor's blink state. |
|
local function updateCursorBlink() |
|
for monY = 1, tall do |
|
for monX = 1, wide do |
|
monitors[monY][monX].setCursorBlink(cursorBlink) |
|
end |
|
end |
|
end |
|
|
|
-- Updates the text scale. |
|
local function updateTextScale() |
|
for monY = 1, tall do |
|
for monX = 1, wide do |
|
-- Protected call in case object is not a monitor. |
|
pcall(function() |
|
monitors[monY][monX].setTextScale(textScale) |
|
end) |
|
end |
|
end |
|
end |
|
|
|
-- Writes to the display. |
|
local clock = os.clock() + 4.5 |
|
local function rawWrite(text) |
|
-- Hackish way to prevent 'too long without yielding' on huge displays. |
|
if os.clock() >= clock then |
|
clock = os.clock() + 4.5 |
|
os.queueEvent('') |
|
coroutine.yield() |
|
end |
|
|
|
local monY, y = getRealY(posY) |
|
local x_ = posX |
|
local spacesLeft = 0 |
|
repeat |
|
text = string.sub(text, spacesLeft + 1) |
|
local monX, x = getRealX(x_) |
|
spacesLeft = monWidth - x + 1 |
|
x_ = x_ + spacesLeft |
|
|
|
if not monitors[monY][monX] then |
|
break |
|
end |
|
|
|
monitors[monY][monX].setTextColour(textColour) |
|
monitors[monY][monX].setBackgroundColour(backColour) |
|
|
|
monitors[monY][monX].setCursorPos(x, y) |
|
monitors[monY][monX].write(text) |
|
until #text <= spacesLeft |
|
|
|
updateCursorColour() |
|
updateCursorPos() |
|
end |
|
|
|
local function rawBlit(text,fg,bg) |
|
-- Hackish way to prevent 'too long without yielding' on huge displays. |
|
if os.clock() >= clock then |
|
clock = os.clock() + 4.5 |
|
os.queueEvent('') |
|
coroutine.yield() |
|
end |
|
|
|
local monY, y = getRealY(posY) |
|
local x_ = posX |
|
local spacesLeft = 0 |
|
repeat |
|
text = string.sub(text, spacesLeft + 1) |
|
fg = string.sub(fg, spacesLeft + 1) |
|
bg = string.sub(bg, spacesLeft + 1) |
|
local monX, x = getRealX(x_) |
|
spacesLeft = monWidth - x + 1 |
|
x_ = x_ + spacesLeft |
|
|
|
if not monitors[monY][monX] then |
|
break |
|
end |
|
|
|
monitors[monY][monX].setTextColour(textColour) |
|
monitors[monY][monX].setBackgroundColour(backColour) |
|
|
|
monitors[monY][monX].setCursorPos(x, y) |
|
monitors[monY][monX].blit(text,fg,bg) |
|
until #text <= spacesLeft |
|
|
|
updateCursorColour() |
|
updateCursorPos() |
|
end |
|
|
|
-- Clears a line on the display. |
|
local function rawClearLine() |
|
local monY, y = getRealY(posY) |
|
for monX = 1, wide do |
|
monitors[monY][monX].setBackgroundColour(backColour) |
|
monitors[monY][monX].setCursorPos(0, y) |
|
monitors[monY][monX].clearLine() |
|
end |
|
|
|
updateCursorPos() |
|
end |
|
|
|
-- Clears the whole display. |
|
local function rawClear() |
|
for monY = 1, tall do |
|
for monX = 1, wide do |
|
monitors[monY][monX].setBackgroundColour(backColour) |
|
monitors[monY][monX].clear() |
|
end |
|
end |
|
end |
|
|
|
--// Public |
|
local public = {} |
|
public.__wide = wide |
|
public.__tall = tall |
|
public.__monitors = monitors |
|
public.__getVirtual = getVirtual |
|
|
|
-- Mocks mon.write(). |
|
function public.write(text) |
|
text = javaToString(text) |
|
if not text or #text < 1 then |
|
return |
|
end |
|
|
|
local endX = (posX + #text - 1) |
|
local textLength = #text |
|
if posY >= 1 and posY <= height and posX <= width and endX >= 1 then |
|
local textStart, textEnd = 1, #text |
|
if posX < 1 then |
|
textStart = math.abs(posX) + 2 |
|
end |
|
if endX > width then |
|
textEnd = width - endX - 1 |
|
end |
|
text = string.sub(text, textStart, textEnd) |
|
|
|
rawWrite(text) |
|
|
|
buffer[posY].text = string.sub(buffer[posY].text, 1, posX - 1) .. text .. string.sub(buffer[posY].text, endX + 1) |
|
buffer[posY].textColour = string.sub(buffer[posY].textColour, 1, posX - 1) .. string.rep(colourToHex(textColour), #text) .. string.sub(buffer[posY].textColour, endX + 1) |
|
buffer[posY].backColour = string.sub(buffer[posY].backColour, 1, posX - 1) .. string.rep(colourToHex(backColour), #text) .. string.sub(buffer[posY].backColour, endX + 1) |
|
end |
|
|
|
posX = posX + textLength |
|
end |
|
|
|
function public.blit(text,fg,bg) |
|
if type(text)~="string" then error("bad argument #1 (expected string, got "..type(text)..")") end |
|
if type(fg)~="string" then error("bad argument #1 (expected string, got "..type(fg)..")") end |
|
if type(bg)~="string" then error("bad argument #1 (expected string, got "..type(bg)..")") end |
|
if #text~=#fg or #text~=#bg or #fg~=#bg then error("Arguments must be the same length") end |
|
|
|
local endX = (posX + #text - 1) |
|
local textLength = #text |
|
if posY >= 1 and posY <= height and posX <= width and endX >= 1 then |
|
local textStart, textEnd = 1, #text |
|
if posX < 1 then |
|
textStart = math.abs(posX) + 2 |
|
end |
|
if endX > width then |
|
textEnd = width - endX - 1 |
|
end |
|
text = string.sub(text, textStart, textEnd) |
|
fg = string.sub(fg, textStart, textEnd) |
|
bg = string.sub(bg, textStart, textEnd) |
|
|
|
rawBlit(text,fg,bg) |
|
|
|
buffer[posY].text = string.sub(buffer[posY].text, 1, posX - 1) .. text .. string.sub(buffer[posY].text, endX + 1) |
|
buffer[posY].textColour = string.sub(buffer[posY].textColour, 1, posX - 1) .. fg:upper() .. string.sub(buffer[posY].textColour, endX + 1) |
|
buffer[posY].backColour = string.sub(buffer[posY].backColour, 1, posX - 1) .. bg:upper() .. string.sub(buffer[posY].backColour, endX + 1) |
|
end |
|
|
|
posX = posX + textLength |
|
end |
|
|
|
-- Mocks mon.clearLine(). |
|
function public.clearLine() |
|
if posY >= 1 and posY <= height then |
|
rawClearLine() |
|
|
|
buffer[posY].text = emptyLine |
|
buffer[posY].backColour = string.rep(colourToHex(backColour), width) |
|
end |
|
end |
|
|
|
-- Mocks mon.clear(). |
|
function public.clear() |
|
rawClear() |
|
|
|
for y = 1, height do |
|
buffer[y].text = emptyLine |
|
buffer[y].backColour = string.rep(colourToHex(backColour), width) |
|
end |
|
end |
|
|
|
-- Mocks mon.scroll(). |
|
function public.scroll(n) |
|
local function _write(y, text, sTextColour, sBackColour) |
|
local _posX, _posY = posX, posY |
|
local _textColour, _backColour = textColour, backColour |
|
posY = y |
|
|
|
local cPosX = 1 |
|
local cText = '' |
|
local cTextColour, cBackColour = string.sub(sTextColour, 1, 1), string.sub(sBackColour, 1, 1) |
|
|
|
for x = 1, width + 1 do |
|
local _cTextColour = string.sub(sTextColour, x, x) |
|
local _cBackColour = string.sub(sBackColour, x, x) |
|
local _cText = string.sub(text, x, x) |
|
if _cTextColour == cTextColour and _cBackColour == cBackColour then |
|
cText = cText .. _cText |
|
else |
|
posX = cPosX |
|
textColour = hexToColour(cTextColour) |
|
backColour = hexToColour(cBackColour) |
|
public.write(cText) |
|
|
|
cPosX = x |
|
cText = _cText |
|
cTextColour, cBackColour = _cTextColour, _cBackColour |
|
end |
|
end |
|
|
|
posX, posY = _posX, _posY |
|
textColour, backColour = _textColour, _backColour |
|
end |
|
|
|
local function _clearLine(y) |
|
local _posY = posY |
|
|
|
posY = y |
|
public.clearLine() |
|
|
|
posY = _posY |
|
end |
|
|
|
if n ~= 0 then |
|
local startY, endY, step |
|
if n < 0 then |
|
startY, endY, step = height, 1, -1 |
|
elseif n > 0 then |
|
startY, endY, step = 1, height, 1 |
|
end |
|
|
|
for y = startY, endY, step do |
|
if buffer[y + n] then |
|
_write(y, buffer[y + n].text, buffer[y + n].textColour, buffer[y + n].backColour) |
|
else |
|
_clearLine(y) |
|
end |
|
end |
|
end |
|
end |
|
|
|
-- Mocks mon.isColour(). |
|
function public.isColour() |
|
return isColour |
|
end |
|
|
|
public.isColor = public.isColour |
|
|
|
-- Always returns true, used to identify if monitor object is a virtual monitor. |
|
function public.isMulti() |
|
return true |
|
end |
|
|
|
-- Mocks mon.getSize(). |
|
function public.getSize() |
|
return width, height |
|
end |
|
|
|
-- Mocks mon.getCursorPos(). |
|
function public.getCursorPos() |
|
return posX, posY |
|
end |
|
|
|
-- Mocks mon.setTextScale(). |
|
function public.setTextScale(scale) |
|
if type(scale) ~= 'number' then |
|
error('Expected number', 2) |
|
end |
|
|
|
scale = math.floor(scale * 2) / 2 |
|
|
|
if scale < 0.5 or scale > 5 then |
|
error('Expected number in range 0.5-5', 2) |
|
end |
|
|
|
textScale = scale |
|
updateTextScale() |
|
|
|
public.clear() |
|
|
|
calculate() |
|
end |
|
|
|
function public.getTextScale() |
|
return textScale |
|
end |
|
|
|
-- Mocks mon.setCursorBlink(). |
|
function public.setCursorBlink(bool) |
|
if type(bool) ~= 'boolean' then |
|
error('Expected boolean', 2) |
|
end |
|
|
|
cursorBlink = bool |
|
updateCursorBlink() |
|
end |
|
|
|
function public.getCursorBlink() |
|
return cursorBlink |
|
end |
|
|
|
-- Mocks mon.setCursorPos(). |
|
function public.setCursorPos(x, y) |
|
if type(x) ~= 'number' or type(y) ~= 'number' then |
|
error('Expected number, number', 2) |
|
end |
|
|
|
x, y = math.floor(x), math.floor(y) |
|
|
|
posX, posY = x, y |
|
updateCursorPos() |
|
end |
|
|
|
-- Mocks mon.setTextColour(). |
|
function public.setTextColour(colour) |
|
if type(colour) ~= 'number' then |
|
error('Expected number', 2) |
|
end |
|
|
|
if colour <= 0 then |
|
error('Colour out of range', 2) |
|
end |
|
|
|
_colour = tonumber(colourToHex(colour), 16) |
|
|
|
if _colour < 0 or _colour > 15 then |
|
error('Colour out of range', 2) |
|
end |
|
|
|
textColour = colour |
|
updateCursorColour() |
|
end |
|
|
|
public.setTextColor = public.setTextColour |
|
|
|
function public.getTextColour() |
|
return textColour |
|
end |
|
|
|
public.getTextColor = public.getTextColour |
|
|
|
-- Mocks mon.setBackgroundColour(). |
|
function public.setBackgroundColour(colour) |
|
if type(colour) ~= 'number' then |
|
error('Expected number', 2) |
|
end |
|
|
|
if colour <= 0 then |
|
error('Colour out of range', 2) |
|
end |
|
|
|
_colour = tonumber(colourToHex(colour), 16) |
|
|
|
if _colour < 0 or _colour > 15 then |
|
error('Colour out of range', 2) |
|
end |
|
|
|
backColour = colour |
|
end |
|
|
|
public.setBackgroundColor = public.setBackgroundColour |
|
|
|
function public.getBackgroundColour() |
|
return backColour |
|
end |
|
|
|
public.getBackgroundColor = public.getBackgroundColour |
|
|
|
function public.setPaletteColour(colour,...) |
|
if type(colour) ~= 'number' then |
|
error('Expected number', 2) |
|
end |
|
|
|
if colour <= 0 then |
|
error('Colour out of range', 2) |
|
end |
|
|
|
_colour = tonumber(colourToHex(colour), 16) |
|
|
|
if _colour < 0 or _colour > 15 then |
|
error('Colour out of range', 2) |
|
end |
|
|
|
local tArgs = {...} |
|
if #tArgs==1 then tArgs=table.pack(colours.unpackRGB(tArgs[1])) end |
|
if #tArgs<3 then error("bad argument #4 (expected number, got nil)") end |
|
if #tArgs>3 then for i=#tArgs,4,-1 do tArgs[i]=nil end end |
|
|
|
if not isColour then |
|
local avg = (tArgs[1]+tArgs[2]+tArgs[3])/3 |
|
for i=1,3 do tArgs[i]=avg end |
|
end |
|
|
|
for monY = 1, tall do |
|
for monX = 1, wide do |
|
monitors[monY][monX].setPaletteColour(colour,table.unpack(tArgs)) |
|
end |
|
end |
|
end |
|
|
|
public.setPaletteColor = public.setPaletteColour |
|
|
|
function public.getPaletteColour(colour) |
|
if type(colour) ~= 'number' then |
|
error('Expected number', 2) |
|
end |
|
|
|
if colour <= 0 then |
|
error('Colour out of range', 2) |
|
end |
|
|
|
_colour = tonumber(colourToHex(colour), 16) |
|
|
|
if _colour < 0 or _colour > 15 then |
|
error('Colour out of range', 2) |
|
end |
|
|
|
return monitors[1][1].getPaletteColour(color) |
|
end |
|
|
|
public.getPaletteColor = public.getPaletteColour |
|
|
|
multiMons[name]=public |
|
updateTextScale() |
|
calculate() |
|
return peripheral.wrap(name) |
|
end |
|
|
|
function remove(name) |
|
multiMons[name]=nil |
|
end |