Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local stitch = shell and {} or getfenv()
- local string_sub, string_rep, unpack = string.sub, string.rep, unpack or table.unpack
- local internalX, internalY, internalCurrentTextColor, internalCurrentBackgroundColor, internalUpdatedLines, internalText, internalTextColor, internalBackgroundColor, tMonitors, tMonitorSizes = 1, 1, colors.white, colors.black, {}, {}, {}, {}, {}, {{}}, {{}}
- local isPatch, bVisible = {}, true
- local string_space = " "
- --[[taken from window API]]
- local tHex = {
- [ colors.white ] = "0",
- [ colors.orange ] = "1",
- [ colors.magenta ] = "2",
- [ colors.lightBlue ] = "3",
- [ colors.yellow ] = "4",
- [ colors.lime ] = "5",
- [ colors.pink ] = "6",
- [ colors.gray ] = "7",
- [ colors.lightGray ] = "8",
- [ colors.cyan ] = "9",
- [ colors.purple ] = "a",
- [ colors.blue ] = "b",
- [ colors.brown ] = "c",
- [ colors.green ] = "d",
- [ colors.red ] = "e",
- [ colors.black ] = "f",
- }
- --[[]]
- local function update()
- if not bVisible then
- return
- end
- local currentY = 1 --how far down are we in the buffer?
- for y = 1, #tMonitors do --iterate through the rows of monitors
- local currentX, height = 1, tMonitorSizes[ y ][ 1 ][ 2 ] --how far right are we in the buffer, how high is the current monitor row?
- for x = 1, #tMonitors[ y ] do --iterate through the columns of monitors
- local mon = tMonitors[ y ][ x ] --the current monitor object
- local width = tMonitorSizes[ y ][ x ][ 1 ] --width of the current column
- for y = currentY, currentY + height do --iterate through the buffer, starting at the last pixel of the last monitor plus one, ending at the last pixel of this monitor
- if internalUpdatedLines[ y ] then --if the line was updated, we'll blit the entire line (CC updates this way, so no performance loss)
- mon.setCursorPos( 1, y - currentY + 1 )
- mon.blit( string_sub( internalText[ y ], currentX, currentX + width ), string_sub( internalTextColor[ y ], currentX, currentX + width ), string_sub( internalBackgroundColor[ y ], currentX, currentX + width ) )
- end
- end
- currentX = currentX + width --add the width of the current monitor column to the currentX value
- end
- currentY = currentY + height --add the height of the current monitor row to the currentY value
- end
- internalUpdatedLines = {} --reset the lines which need to be drawn
- end
- stitch.write = function( text ) --I'm lazy, just turn it into a problem for blit
- sText = tostring( text )
- local len = #sText
- stitch.blit( sText, string_rep( tHex[ internalCurrentTextColor ], len ), string_rep( tHex[ internalCurrentBackgroundColor ], len ) )
- end
- stitch.blit = function( text, textColors, backgroundColors )
- local text_len = #text
- if not internalText[ internalY ] or internalX + text_len < 1 then --if we're off screen; do nothing
- return
- end
- local maxx, maxy = stitch.getSize()
- local beforeMaxLen, afterMinLen = internalX - 1, internalX + text_len
- local minLen, maxLen = 2 - internalX, maxx -internalX + 1
- if internalX < 1 and maxx < internalX + text_len then
- --ooh we have a really long string
- internalText[ internalY ] = string_sub( text, minLen, maxLen )
- internalTextColor[ internalY] = string_sub( textColors, minLen, maxLen )
- internalBackgroundColor[ internalY ] = string_sub( backgroundColors, minLen, maxLen )
- elseif internalX < 1 then
- internalText[ internalY ] = string_sub( text, minLen ) .. string_sub( internalText[ internalY ], afterMinLen )
- internalTextColor[ internalY ] = string_sub( textColors, minLen ) .. string_sub( internalTextColor[ internalY ], afterMinLen )
- internalBackgroundColor[ internalY ] = string_sub( backgroundColors, minLen ) .. string_sub( internalBackgroundColor[ internalY ], afterMinLen )
- elseif maxx < internalX + text_len then
- internalText[ internalY ] = string_sub( internalText[ internalY ], 1, beforeMaxLen ) .. string_sub( text, 1, maxLen )
- internalTextColor[ internalY ] = string_sub( internalTextColor[ internalY ], 1, beforeMaxLen ) .. string_sub( textColors, 1, maxLen )
- internalBackgroundColor[ internalY ] = string_sub( internalBackgroundColor[ internalY ], 1, beforeMaxLen ) .. string_sub( backgroundColors, 1, maxLen )
- else
- internalText[ internalY ] = string_sub( internalText[ internalY ], 1, beforeMaxLen ) .. text .. string_sub( internalText[ internalY ], afterMinLen )
- internalTextColor[ internalY ] = string_sub( internalTextColor[ internalY ], 1, beforeMaxLen ) .. textColors.. string_sub( internalTextColor[ internalY ], afterMinLen )
- internalBackgroundColor[ internalY ] = string_sub( internalBackgroundColor[ internalY ], 1, beforeMaxLen ) .. backgroundColors .. string_sub( internalBackgroundColor[ internalY ], afterMinLen )
- end
- internalUpdatedLines[ internalY ] = true
- end
- stitch.clear = function()
- --clears the screen with the current background color/text color
- local maxx, maxy = stitch.getSize()
- local newLineText, newLineTextColor, newLineBackgroundColor = string_rep( string_space, maxx ), string_rep( tHex[ internalCurrentTextColor ], maxx ), string_rep( tHex[ internalCurrentBackgroundColor ], maxx )
- for y = 1, maxy do
- internalText[ y ] = newLineText
- internalTextColor[ y ] = newLineTextColor
- internalBackgroundColor[ y ] = newLineBackgroundColor
- internalUpdatedLines[ y ] = true
- end
- end
- stitch.clearLine = function()
- --clears the current line
- local maxx, maxy = stitch.getSize()
- internalText[ internalY ] = string_rep( string_space, maxx )
- internalTextColor[ internalY ] = string_rep( tHex[ internalCurrentTextColor ], maxx )
- internalBackgroundColor[ internalY ] = string_rep( tHex[ internalCurrentBackgroundColor ], maxx )
- internalUpdatedLines[ internalY ] = true
- end
- stitch.getCursorPos = function()
- --return the current cursor position
- return internalX, internalY
- end
- stitch.setCursorPos = function( x, y )
- internalX, internalY = x, y
- --todo: which friggin monitor do I set this to???
- end
- stitch.setCursorBlink = function( bool )
- for y, t in ipairs( tMonitors ) do
- for x, mon in ipairs( t ) do
- mon.setCursorBlink( bool )
- end
- end
- end
- stitch.isColor = function()
- --return boolean isColor
- --if all monitors support color, mine does. Otherwise, it does not. (or rather, it does in certain places, but I'll tell you it doesn't)
- for y, t in ipairs( tMonitors ) do
- for x, mon in ipairs( t ) do
- if not mon.isColor() then
- return false
- end
- end
- end
- return true
- end
- stitch.setPaletteColor = function( ... )
- for y, t in ipairs( tMonitors) do
- for x, mo in ipairs( t ) do
- mon.setPaletteColor( ... )
- end
- end
- end
- stitch.setPaletteColour = stitch.setPaletteColor
- stitch.isColour = stitch.isColor
- stitch.getSize = function()
- --return number x, number y
- local maxx, maxy = 0, 0
- for y, t in ipairs( tMonitorSizes ) do
- maxy = maxy + t[ 1 ][ 2 ]
- end
- for x, mon in ipairs( tMonitorSizes[ 1 ] ) do
- maxx = maxx + mon[ 1 ]
- end
- return maxx, maxy
- end
- stitch.scroll = function( n )
- local _internalText, _internalTextColor, _internalBackgroundColor = {}, {}, {}
- local maxx, maxy = stitch.getSize()
- for i = 1, maxy do
- _internalText[ i ] = internalText[ i - n ] or string_rep( string_space, maxx )
- _internalTextColor[ i ] = internalText[ i - n ] or tHex[ internalCurrentTextColor ]:rep( maxx )
- _internalBackgroundColor[ i ] = internalText[ i - n ] or tHex[ internalCurrentBackgroundColor ]:rep( maxx )
- internalUpdatedLines[ i ] = true
- end
- internalText, internalTextColor, internalBackgroundColor = _internalText, _internalTextColor, _internalBackgroundColor
- end
- stitch.setTextColor = function( color )
- internalCurrentTextColor = color
- end
- stitch.setTextColour = stitch.setTextColor
- stitch.getTextColor = function()
- return internalCurrentTextColor
- end
- stitch.getTextColour = stitch.getTextColor
- stitch.setBackgroundColor = function( color )
- internalCurrentBackgroundColor = color
- end
- stitch.setBackgroundColour = stitch.setBackgroundColor
- stitch.getBackgroundColor = function()
- return internalCurrentBackgroundColor
- end
- stitch.getBackgroundColour = stitch.getBackgroundColor
- stitch.setTextScale = function( scale )
- for y, t in ipairs( tMonitors ) do
- tMonitorSizes[ y ] = tMonitorSizes[ y ] or {}
- for x, mon in ipairs( t ) do
- mon.setTextScale( scale )
- tMonitorSizes[ y ][ x ] = {mon.getSize()}
- end
- end
- end
- stitch.setMonitors = function( mons )
- tMonitors = {}
- for y, t in ipairs( mons ) do
- tMonitors[ y ] = tMonitors[ y ] or {}
- for x, sName in ipairs( t ) do
- tMonitors[ y ][ x ] = peripheral.wrap( sName )
- tMonitors[ y ][ x ].name = sName
- isPatch[ sName ] = true
- end
- end
- stitch.setTextScale( 1 )
- stitch.clear()
- end
- local function project( name, posx, posy )
- local offsetY = 0
- for y, t in ipairs( tMonitors ) do
- local offsetX = 0
- for x, mon in ipairs( t ) do
- if mon.name == name then
- return posx + offsetX, posy + offsetY
- end
- offsetX = offsetX + tMonitorSizes[ y ][ x ][ 1 ]
- end
- offsetY = offsetY + tMonitorSizes[ y ][ 1 ][ 2 ]
- end
- end
- --hacking into the event system to make stuff work
- local _yield, id, doAutoBuffer = coroutine.yield, os.startTimer( 0.5 ), true
- _G.coroutine.yield = function( ... )
- local tEventData = {_yield( ... )}
- if doAutoBuffer and tEventData[ 1 ] == "timer" and tEventData[ 2 ] == id then
- id = os.startTimer( 0.05 )
- update()
- elseif tEventData[ 1 ] == "monitor_touch" and isPatch[ tEventData[ 2 ] ] then
- return "monitor_touch", "stitch", project( tEventData[ 2 ], tEventData[ 3 ], tEventData[ 4 ] )
- end
- return unpack( tEventData )
- end
- stitch.disableAutoBuffer = function()
- doAutoBuffer = false
- end
- stitch.buffer = function()
- update()
- end
- stitch.setVisible = function( visible )
- if visible and not bVisible then
- stitch.redraw()
- end
- bVisible = visible
- end
- stitch.redraw = function()
- if not bVisible then
- return
- end
- local maxx, maxy = stitch.getSize()
- for y = 1, maxy do
- internalUpdatedLines[ y ] = true
- end
- update()
- end
- --fancy peripheral stuff
- local isPresent, getType, getMethods, call, wrap, find, getNames, methods = peripheral.isPresent, peripheral.getType, peripheral.getMethods, peripheral.call, peripheral.wrap, peripheral.find, peripheral.getNames, {}
- for k, v in pairs( stitch ) do
- methods[ #methods + 1 ] = k
- end
- peripheral.isPresent = function( side )
- --if it's a real peripheral or my virtual peripheral return true
- return isPresent( side ) or side == "stitch"
- end
- peripheral.getType = function( side )
- --if it's my virtual peripheral return monitor
- return getType( side ) or (side == "stitch" and "monitor")
- end
- peripheral.getMethods = function( side )
- --if it's my virtual peripheral return my list of methods
- return getMethods( side ) or (side == "stitch" and methods)
- end
- peripheral.call = function( side, method, ... )
- --if it's my peripheral, call the relevent function with the relevent arguments
- if side == "stitch" then
- return stitch[ method ]( ... )
- end
- return call( side, method, ... )
- end
- peripheral.wrap = function( side )
- --if it's my virtual peripheral, return it
- return wrap( side ) or (stitch and side == "stitch")
- end
- peripheral.find = function( type, fnFilter )
- --if we're looking for monitors, add mine in
- if type == "monitor" then
- local result = find( type, fnFilter )
- result[ #result + 1 ] = fnFilter and fnFilter( "stitch", stitch ) or stitch
- return unpack( result )
- end
- return find( type, fnFilter )
- end
- peripheral.getNames = function()
- --add my virtual peripheral to the list
- local result = getNames()
- result[ #result + 1 ] = "stitch"
- return result
- end
- return stitch
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement