2017-05-01 13:32:39 +00:00
local function drawPixelInternal ( xPos , yPos )
term.setCursorPos ( xPos , yPos )
term.write ( " " )
end
local tColourLookup = { }
for n = 1 , 16 do
tColourLookup [ string.byte ( " 0123456789abcdef " , n , n ) ] = 2 ^ ( n - 1 )
end
2017-07-15 22:27:52 +00:00
local function parseLine ( tImageArg , sLine )
local tLine = { }
for x = 1 , sLine : len ( ) do
tLine [ x ] = tColourLookup [ string.byte ( sLine , x , x ) ] or 0
end
table.insert ( tImageArg , tLine )
return tImageArg
end
function parseImage ( sRawData )
if type ( sRawData ) ~= " string " then
error ( " bad argument #1 (expected string, got " .. type ( sRawData ) .. " ) " )
end
local function split ( str , delim ) -- modified split function from https://codea.io/talk/discussion/2118/split-a-string-by-return-newline
if string.find ( str , delim ) == nil then return { str } end
local result , pat , lastpos = { } , " (.-) " .. delim .. " () " , nil
for part , pos in string.gfind ( str , pat ) do table.insert ( result , part ) ; lastpos = pos ; end
table.insert ( result , string.sub ( str , lastpos ) )
return result
2017-05-01 13:32:39 +00:00
end
2017-07-15 22:27:52 +00:00
local tImage = { }
for _ , sLine in pairs ( split ( sPath , " \n " ) ) do -- read each line like original file handling did
tImage = parseLine ( tImage , sLine )
2017-07-15 21:50:05 +00:00
end
2017-07-15 22:27:52 +00:00
return tImage
end
2017-05-01 13:32:39 +00:00
2017-07-15 22:27:52 +00:00
function loadImage ( sPath )
if type ( sPath ) ~= " string " then
error ( " bad argument #1 (expected string, got " .. type ( sPath ) .. " ) " , 2 )
2017-07-15 21:50:05 +00:00
end
2017-07-15 22:27:52 +00:00
2017-07-15 22:31:42 +00:00
if fs.exists ( sPath ) then
2017-07-15 21:50:05 +00:00
local tImage = { }
local file = io.open ( sPath , " r " )
2017-05-01 13:32:39 +00:00
local sLine = file : read ( )
2017-07-15 22:27:52 +00:00
local sContent = " "
2017-05-01 13:32:39 +00:00
while sLine do
2017-07-15 22:31:42 +00:00
sContent = sContent .. " \n " .. sLine
2017-05-01 13:32:39 +00:00
sLine = file : read ( )
end
file : close ( )
2017-07-15 22:31:42 +00:00
return parseImage ( sContent : sub ( 2 ) ) -- remove first newline and delegate parsing of images to parseImage function as suggested by @SquidDev in discussion of PR #378
2017-05-01 13:32:39 +00:00
end
return nil
end
function drawPixel ( xPos , yPos , nColour )
2017-06-12 09:54:44 +00:00
if type ( xPos ) ~= " number " then error ( " bad argument #1 (expected number, got " .. type ( xPos ) .. " ) " , 2 ) end
if type ( yPos ) ~= " number " then error ( " bad argument #2 (expected number, got " .. type ( yPos ) .. " ) " , 2 ) end
if nColour ~= nil and type ( nColour ) ~= " number " then error ( " bad argument #3 (expected number, got " .. type ( nColour ) .. " ) " , 2 ) end
2017-05-01 13:32:39 +00:00
if nColour then
term.setBackgroundColor ( nColour )
end
drawPixelInternal ( xPos , yPos )
end
function drawLine ( startX , startY , endX , endY , nColour )
2017-06-12 09:54:44 +00:00
if type ( startX ) ~= " number " then error ( " bad argument #1 (expected number, got " .. type ( startX ) .. " ) " , 2 ) end
if type ( startY ) ~= " number " then error ( " bad argument #2 (expected number, got " .. type ( startY ) .. " ) " , 2 ) end
if type ( endX ) ~= " number " then error ( " bad argument #3 (expected number, got " .. type ( endX ) .. " ) " , 2 ) end
if type ( endY ) ~= " number " then error ( " bad argument #4 (expected number, got " .. type ( endY ) .. " ) " , 2 ) end
2017-06-19 03:46:13 +00:00
if nColour ~= nil and type ( nColour ) ~= " number " then error ( " bad argument #5 (expected number, got " .. type ( nColour ) .. " ) " , 2 ) end
2017-05-01 13:32:39 +00:00
startX = math.floor ( startX )
startY = math.floor ( startY )
endX = math.floor ( endX )
endY = math.floor ( endY )
if nColour then
term.setBackgroundColor ( nColour )
end
if startX == endX and startY == endY then
drawPixelInternal ( startX , startY )
return
end
local minX = math.min ( startX , endX )
if minX == startX then
minY = startY
maxX = endX
maxY = endY
else
minY = endY
maxX = startX
maxY = startY
end
-- TODO: clip to screen rectangle?
local xDiff = maxX - minX
local yDiff = maxY - minY
if xDiff > math.abs ( yDiff ) then
local y = minY
local dy = yDiff / xDiff
for x = minX , maxX do
drawPixelInternal ( x , math.floor ( y + 0.5 ) )
y = y + dy
end
else
local x = minX
local dx = xDiff / yDiff
if maxY >= minY then
for y = minY , maxY do
drawPixelInternal ( math.floor ( x + 0.5 ) , y )
x = x + dx
end
else
for y = minY , maxY , - 1 do
drawPixelInternal ( math.floor ( x + 0.5 ) , y )
x = x - dx
end
end
end
end
function drawBox ( startX , startY , endX , endY , nColour )
2017-06-12 09:54:44 +00:00
if type ( startX ) ~= " number " then error ( " bad argument #1 (expected number, got " .. type ( startX ) .. " ) " , 2 ) end
if type ( startY ) ~= " number " then error ( " bad argument #2 (expected number, got " .. type ( startY ) .. " ) " , 2 ) end
if type ( endX ) ~= " number " then error ( " bad argument #3 (expected number, got " .. type ( endX ) .. " ) " , 2 ) end
if type ( endY ) ~= " number " then error ( " bad argument #4 (expected number, got " .. type ( endY ) .. " ) " , 2 ) end
2017-06-19 03:46:13 +00:00
if nColour ~= nil and type ( nColour ) ~= " number " then error ( " bad argument #5 (expected number, got " .. type ( nColour ) .. " ) " , 2 ) end
2017-05-01 13:32:39 +00:00
startX = math.floor ( startX )
startY = math.floor ( startY )
endX = math.floor ( endX )
endY = math.floor ( endY )
if nColour then
term.setBackgroundColor ( nColour )
end
if startX == endX and startY == endY then
drawPixelInternal ( startX , startY )
return
end
local minX = math.min ( startX , endX )
if minX == startX then
minY = startY
maxX = endX
maxY = endY
else
minY = endY
maxX = startX
maxY = startY
end
for x = minX , maxX do
drawPixelInternal ( x , minY )
drawPixelInternal ( x , maxY )
end
if ( maxY - minY ) >= 2 then
for y = ( minY + 1 ) , ( maxY - 1 ) do
drawPixelInternal ( minX , y )
drawPixelInternal ( maxX , y )
end
end
end
function drawFilledBox ( startX , startY , endX , endY , nColour )
2017-06-12 09:54:44 +00:00
if type ( startX ) ~= " number " then error ( " bad argument #1 (expected number, got " .. type ( startX ) .. " ) " , 2 ) end
if type ( startY ) ~= " number " then error ( " bad argument #2 (expected number, got " .. type ( startY ) .. " ) " , 2 ) end
if type ( endX ) ~= " number " then error ( " bad argument #3 (expected number, got " .. type ( endX ) .. " ) " , 2 ) end
if type ( endY ) ~= " number " then error ( " bad argument #4 (expected number, got " .. type ( endY ) .. " ) " , 2 ) end
2017-06-19 03:46:13 +00:00
if nColour ~= nil and type ( nColour ) ~= " number " then error ( " bad argument #5 (expected number, got " .. type ( nColour ) .. " ) " , 2 ) end
2017-05-01 13:32:39 +00:00
startX = math.floor ( startX )
startY = math.floor ( startY )
endX = math.floor ( endX )
endY = math.floor ( endY )
if nColour then
term.setBackgroundColor ( nColour )
end
if startX == endX and startY == endY then
drawPixelInternal ( startX , startY )
return
end
local minX = math.min ( startX , endX )
if minX == startX then
minY = startY
maxX = endX
maxY = endY
else
minY = endY
maxX = startX
maxY = startY
end
for x = minX , maxX do
for y = minY , maxY do
drawPixelInternal ( x , y )
end
end
end
function drawImage ( tImage , xPos , yPos )
2017-06-19 03:46:13 +00:00
if type ( tImage ) ~= " table " then error ( " bad argument #1 (expected table, got " .. type ( tImage ) .. " ) " , 2 ) end
2017-06-12 09:54:44 +00:00
if type ( xPos ) ~= " number " then error ( " bad argument #2 (expected number, got " .. type ( xPos ) .. " ) " , 2 ) end
if type ( yPos ) ~= " number " then error ( " bad argument #3 (expected number, got " .. type ( yPos ) .. " ) " , 2 ) end
2017-05-01 13:32:39 +00:00
for y = 1 , # tImage do
local tLine = tImage [ y ]
for x = 1 , # tLine do
if tLine [ x ] > 0 then
term.setBackgroundColor ( tLine [ x ] )
drawPixelInternal ( x + xPos - 1 , y + yPos - 1 )
end
end
end
end