Advertisement
Guest User

stitch

a guest
Jul 26th, 2022
2,961
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.71 KB | None | 0 0
  1. local stitch = shell and {} or getfenv()
  2.  
  3. local string_sub, string_rep, unpack = string.sub, string.rep, unpack or table.unpack
  4.  
  5. local internalX, internalY, internalCurrentTextColor, internalCurrentBackgroundColor, internalUpdatedLines, internalText, internalTextColor, internalBackgroundColor, tMonitors, tMonitorSizes = 1, 1, colors.white, colors.black, {}, {}, {}, {}, {}, {{}}, {{}}
  6. local isPatch, bVisible = {}, true
  7.  
  8. local string_space = " "
  9.  
  10. --[[taken from window API]]
  11. local tHex = {
  12.     [ colors.white ] = "0",
  13.     [ colors.orange ] = "1",
  14.     [ colors.magenta ] = "2",
  15.     [ colors.lightBlue ] = "3",
  16.     [ colors.yellow ] = "4",
  17.     [ colors.lime ] = "5",
  18.     [ colors.pink ] = "6",
  19.     [ colors.gray ] = "7",
  20.     [ colors.lightGray ] = "8",
  21.     [ colors.cyan ] = "9",
  22.     [ colors.purple ] = "a",
  23.     [ colors.blue ] = "b",
  24.     [ colors.brown ] = "c",
  25.     [ colors.green ] = "d",
  26.     [ colors.red ] = "e",
  27.     [ colors.black ] = "f",
  28. }
  29. --[[]]
  30.  
  31. local function update()
  32.     if not bVisible then
  33.         return
  34.     end
  35.     local currentY = 1 --how far down are we in the buffer?
  36.     for y = 1, #tMonitors do --iterate through the rows of monitors
  37.         local currentX, height = 1, tMonitorSizes[ y ][ 1 ][ 2 ] --how far right are we in the buffer, how high is the current monitor row?
  38.         for x = 1, #tMonitors[ y ] do --iterate through the columns of monitors
  39.             local mon = tMonitors[ y ][ x ] --the current monitor object
  40.             local width = tMonitorSizes[ y ][ x ][ 1 ] --width of the current column
  41.             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
  42.                 if internalUpdatedLines[ y ] then --if the line was updated, we'll blit the entire line (CC updates this way, so no performance loss)
  43.                     mon.setCursorPos( 1, y - currentY + 1 )
  44.                     mon.blit( string_sub( internalText[ y ], currentX, currentX + width ), string_sub( internalTextColor[ y ], currentX, currentX + width ), string_sub( internalBackgroundColor[ y ], currentX, currentX + width ) )
  45.                 end
  46.             end
  47.             currentX = currentX + width --add the width of the current monitor column to the currentX value
  48.         end
  49.         currentY = currentY + height --add the height of the current monitor row to the currentY value
  50.     end
  51.     internalUpdatedLines = {} --reset the lines which need to be drawn
  52. end
  53.  
  54. stitch.write = function( text ) --I'm lazy, just turn it into a problem for blit
  55.     sText = tostring( text )
  56.     local len = #sText
  57.     stitch.blit( sText, string_rep( tHex[ internalCurrentTextColor ], len ), string_rep( tHex[ internalCurrentBackgroundColor ], len ) )
  58. end
  59.  
  60. stitch.blit = function( text, textColors, backgroundColors )
  61.     local text_len = #text
  62.     if not internalText[ internalY ] or internalX + text_len < 1 then --if we're off screen; do nothing
  63.         return
  64.     end
  65.     local maxx, maxy = stitch.getSize()
  66.     local beforeMaxLen, afterMinLen = internalX - 1, internalX + text_len
  67.  
  68.     local minLen, maxLen = 2 - internalX, maxx -internalX + 1
  69.  
  70.     if internalX < 1 and maxx < internalX + text_len then
  71.         --ooh we have a really long string
  72.         internalText[ internalY ] = string_sub( text, minLen, maxLen )
  73.         internalTextColor[ internalY] = string_sub( textColors, minLen, maxLen )
  74.         internalBackgroundColor[ internalY ] = string_sub( backgroundColors, minLen, maxLen )
  75.     elseif internalX < 1 then
  76.         internalText[ internalY ] = string_sub( text, minLen ) .. string_sub( internalText[ internalY ], afterMinLen )
  77.         internalTextColor[ internalY ] = string_sub( textColors, minLen ) .. string_sub( internalTextColor[ internalY ], afterMinLen )
  78.         internalBackgroundColor[ internalY ] = string_sub( backgroundColors, minLen ) .. string_sub( internalBackgroundColor[ internalY ], afterMinLen )
  79.     elseif maxx < internalX + text_len then
  80.         internalText[ internalY ] = string_sub( internalText[ internalY ], 1, beforeMaxLen ) .. string_sub( text, 1, maxLen )
  81.         internalTextColor[ internalY ] = string_sub( internalTextColor[ internalY ], 1, beforeMaxLen ) .. string_sub( textColors, 1, maxLen )
  82.         internalBackgroundColor[ internalY ] = string_sub( internalBackgroundColor[ internalY ], 1, beforeMaxLen ) .. string_sub( backgroundColors, 1, maxLen )
  83.     else
  84.         internalText[ internalY ] = string_sub( internalText[ internalY ], 1, beforeMaxLen ) .. text .. string_sub( internalText[ internalY ], afterMinLen )
  85.         internalTextColor[ internalY ] = string_sub( internalTextColor[ internalY ], 1, beforeMaxLen ) .. textColors.. string_sub( internalTextColor[ internalY ], afterMinLen )
  86.         internalBackgroundColor[ internalY ] = string_sub( internalBackgroundColor[ internalY ], 1, beforeMaxLen ) .. backgroundColors .. string_sub( internalBackgroundColor[ internalY ], afterMinLen )
  87.     end
  88.     internalUpdatedLines[ internalY ] = true
  89. end
  90.  
  91. stitch.clear = function()
  92.     --clears the screen with the current background color/text color
  93.     local maxx, maxy = stitch.getSize()
  94.     local newLineText, newLineTextColor, newLineBackgroundColor = string_rep( string_space, maxx ), string_rep( tHex[ internalCurrentTextColor ], maxx ), string_rep( tHex[ internalCurrentBackgroundColor ], maxx )
  95.     for y = 1, maxy do
  96.         internalText[ y ] = newLineText
  97.         internalTextColor[ y ] = newLineTextColor
  98.         internalBackgroundColor[ y ] = newLineBackgroundColor
  99.         internalUpdatedLines[ y ] = true
  100.     end
  101. end
  102.  
  103. stitch.clearLine = function()
  104.     --clears the current line
  105.     local maxx, maxy = stitch.getSize()
  106.     internalText[ internalY ] = string_rep( string_space, maxx )
  107.     internalTextColor[ internalY ] = string_rep( tHex[ internalCurrentTextColor ], maxx )
  108.     internalBackgroundColor[ internalY ] = string_rep( tHex[ internalCurrentBackgroundColor ], maxx )
  109.     internalUpdatedLines[ internalY ] = true
  110. end
  111.  
  112. stitch.getCursorPos = function()
  113.     --return the current cursor position
  114.     return internalX, internalY
  115. end
  116.  
  117. stitch.setCursorPos = function( x, y )
  118.     internalX, internalY = x, y
  119.     --todo: which friggin monitor do I set this to???
  120. end
  121.  
  122. stitch.setCursorBlink = function( bool )
  123.     for y, t in ipairs( tMonitors ) do
  124.         for x, mon in ipairs( t ) do
  125.             mon.setCursorBlink( bool )
  126.         end
  127.     end
  128. end
  129.  
  130. stitch.isColor = function()
  131.     --return boolean isColor
  132.     --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)
  133.     for y, t in ipairs( tMonitors ) do
  134.         for x, mon in ipairs( t ) do
  135.             if not mon.isColor() then
  136.                 return false
  137.             end
  138.         end
  139.     end
  140.     return true
  141. end
  142.  
  143. stitch.setPaletteColor = function( ... )
  144.     for y, t in ipairs( tMonitors) do
  145.         for x, mon in ipairs( t ) do
  146.             mon.setPaletteColor( ... )
  147.         end
  148.     end
  149. end
  150.  
  151. stitch.getPaletteColour = function(...)
  152.     return term.getPaletteColor(...)
  153. end
  154. stitch.getPaletteColor = stitch.getPaletteColour
  155.  
  156. stitch.setPaletteColour = stitch.setPaletteColor
  157.  
  158. stitch.isColour = stitch.isColor
  159.  
  160. stitch.getSize = function()
  161.     --return number x, number y
  162.     local maxx, maxy = 0, 0
  163.     for y, t in ipairs( tMonitorSizes ) do
  164.         maxy = maxy + t[ 1 ][ 2 ]
  165.     end
  166.     for x, mon in ipairs( tMonitorSizes[ 1 ] ) do
  167.         maxx = maxx + mon[ 1 ]
  168.     end
  169.     return maxx, maxy
  170. end
  171.  
  172. stitch.scroll = function( n )
  173.     local _internalText, _internalTextColor, _internalBackgroundColor = {}, {}, {}
  174.     local maxx, maxy = stitch.getSize()
  175.     for i = 1, maxy do
  176.         _internalText[ i ] = internalText[ i - n ] or string_rep( string_space, maxx )
  177.         _internalTextColor[ i ] = internalText[ i - n ] or tHex[ internalCurrentTextColor ]:rep( maxx )
  178.         _internalBackgroundColor[ i ] = internalText[ i - n ] or tHex[ internalCurrentBackgroundColor ]:rep( maxx )
  179.         internalUpdatedLines[ i ] = true
  180.     end
  181.     internalText, internalTextColor, internalBackgroundColor = _internalText, _internalTextColor, _internalBackgroundColor
  182. end
  183.  
  184. stitch.setTextColor = function( color )
  185.     internalCurrentTextColor = color
  186. end
  187.  
  188. stitch.setTextColour = stitch.setTextColor
  189.  
  190. stitch.getTextColor = function()
  191.     return internalCurrentTextColor
  192. end
  193.  
  194. stitch.getTextColour = stitch.getTextColor
  195.  
  196. stitch.setBackgroundColor = function( color )
  197.     internalCurrentBackgroundColor = color
  198. end
  199.  
  200. stitch.setBackgroundColour = stitch.setBackgroundColor
  201.  
  202. stitch.getBackgroundColor = function()
  203.     return internalCurrentBackgroundColor
  204. end
  205.  
  206. stitch.getBackgroundColour = stitch.getBackgroundColor
  207.  
  208. stitch.setTextScale = function( scale )
  209.     for y, t in ipairs( tMonitors ) do
  210.         tMonitorSizes[ y ] = tMonitorSizes[ y ] or {}
  211.         for x, mon in ipairs( t ) do
  212.             mon.setTextScale( scale )
  213.             tMonitorSizes[ y ][ x ] = {mon.getSize()}
  214.         end
  215.     end
  216. end
  217.  
  218. stitch.setMonitors = function( mons )
  219.     tMonitors = {}
  220.     for y, t in ipairs( mons ) do
  221.         tMonitors[ y ] = tMonitors[ y ] or {}
  222.         for x, sName in ipairs( t ) do
  223.             tMonitors[ y ][ x ] = peripheral.wrap( sName )
  224.             tMonitors[ y ][ x ].name = sName
  225.             isPatch[ sName ] = true
  226.         end
  227.     end
  228.  
  229.     stitch.setTextScale( 1 )
  230.     stitch.clear()
  231. end
  232.  
  233. local function project( name, posx, posy )
  234.     local offsetY = 0
  235.     for y, t in ipairs( tMonitors ) do
  236.         local offsetX = 0
  237.         for x, mon in ipairs( t ) do
  238.             if mon.name == name then
  239.                 return posx + offsetX, posy + offsetY
  240.             end
  241.             offsetX = offsetX + tMonitorSizes[ y ][ x ][ 1 ]
  242.         end
  243.         offsetY = offsetY + tMonitorSizes[ y ][ 1 ][ 2 ]
  244.     end
  245. end
  246.  
  247. --hacking into the event system to make stuff work
  248. local _yield, id, doAutoBuffer = coroutine.yield, os.startTimer( 0.5 ), true
  249.  
  250. _G.coroutine.yield = function( ... )
  251.     local tEventData = {_yield( ... )}
  252.     if doAutoBuffer and tEventData[ 1 ] == "timer" and tEventData[ 2 ] == id then
  253.         id = os.startTimer( 0.05 )
  254.         update()
  255.     elseif tEventData[ 1 ] == "monitor_touch" and isPatch[ tEventData[ 2 ] ] then
  256.         return "monitor_touch", "stitch", project( tEventData[ 2 ], tEventData[ 3 ], tEventData[ 4 ] )
  257.     end
  258.     return unpack( tEventData )
  259. end
  260.  
  261. stitch.disableAutoBuffer = function()
  262.     doAutoBuffer = false
  263. end
  264.  
  265. stitch.buffer = function()
  266.     update()
  267. end
  268.  
  269. stitch.setVisible = function( visible )
  270.     if visible and not bVisible then
  271.         stitch.redraw()
  272.     end
  273.     bVisible = visible
  274. end
  275.  
  276. stitch.redraw = function()
  277.     if not bVisible then
  278.         return
  279.     end
  280.     local maxx, maxy = stitch.getSize()
  281.     for y = 1, maxy do
  282.         internalUpdatedLines[ y ] = true
  283.     end
  284.     update()
  285. end
  286.  
  287. --fancy peripheral stuff
  288. local isPresent, getType, getMethods, call, wrap, find, getNames, methods = peripheral.isPresent, peripheral.getType, peripheral.getMethods, peripheral.call, peripheral.wrap, peripheral.find, peripheral.getNames, {}
  289.  
  290. for k, v in pairs( stitch ) do
  291.     methods[ #methods + 1 ] = k
  292. end
  293.  
  294. peripheral.isPresent = function( side )
  295.     --if it's a real peripheral or my virtual peripheral return true
  296.     return isPresent( side ) or side == "stitch"
  297. end
  298.  
  299. peripheral.getType = function( side )
  300.     --if it's my virtual peripheral return monitor
  301.     return getType( side ) or (side == "stitch" and "monitor")
  302. end
  303.  
  304. peripheral.getMethods = function( side )
  305.     --if it's my virtual peripheral return my list of methods
  306.     return getMethods( side ) or (side == "stitch" and methods)
  307. end
  308.  
  309. peripheral.call = function( side, method, ... )
  310.     --if it's my peripheral, call the relevent function with the relevent arguments
  311.     if side == "stitch" then
  312.         return stitch[ method ]( ... )
  313.     end
  314.     return call( side, method, ... )
  315. end
  316.  
  317. peripheral.wrap = function( side )
  318.     --if it's my virtual peripheral, return it
  319.     return wrap( side ) or (stitch and side == "stitch")
  320. end
  321.  
  322. peripheral.find = function( type, fnFilter )
  323.     --if we're looking for monitors, add mine in
  324.     if type == "monitor" then
  325.         local result = find( type, fnFilter )
  326.         result[ #result + 1 ] = fnFilter and fnFilter( "stitch", stitch ) or stitch
  327.         return unpack( result )
  328.     end
  329.     return find( type, fnFilter )
  330. end
  331.  
  332. peripheral.getNames = function()
  333.     --add my virtual peripheral to the list
  334.     local result = getNames()
  335.     result[ #result + 1 ] = "stitch"
  336.     return result
  337. end
  338.  
  339. return stitch
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement