Advertisement
LDDestroier

CC forwards compatible test

Sep 14th, 2017
285
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 33.46 KB | None | 0 0
  1. -- CC forwards compatibility mode "fcomp"
  2. -- working title
  3. -- goal: to get as many new programs to work with older versions of CC by recreating functions
  4. -- pastebin get ZXCbDnTY fcomp
  5.  
  6. local fileToRun = nil --string, run this if no argument is given. if nil, then, like, do fuck all after.
  7.  
  8. -- 'skipCheck' skips checking whether or not you have certain functions, solely for testing.
  9. local skipCheck = true
  10.  
  11. -- 'lddterm' stores metadata used by new term functions.
  12. local lddterm = {
  13.     cursor = {
  14.         x = 1,
  15.         y = 1,
  16.         blink = true,
  17.     },
  18.     textcol = colors.white,
  19.     bgcol = colors.black,
  20.     turtleslot = 1,
  21.     native = term.native,
  22. }
  23.  
  24. -- DEFINE TERM FUNCTIONS --
  25.  
  26. if type(term.native) ~= "function" then
  27.     term.native = function()
  28.         return lddterm.native
  29.     end
  30. end
  31.  
  32. if skipCheck or not term.current then
  33.     local native = (term.native and term.native()) or term
  34.     local redirectTarget = native
  35.    
  36.     local function wrap( _sFunction )
  37.         return function( ... )
  38.             return redirectTarget[ _sFunction ]( ... )
  39.         end
  40.     end
  41.    
  42.     local term = {}
  43.    
  44.     term.redirect = function( target )
  45.         if target == nil or type( target ) ~= "table" then
  46.             error( "Invalid redirect target", 2 )
  47.         end
  48.         if target == term then
  49.             error( "term is not a recommended redirect target, try term.current() instead", 2 )
  50.         end
  51.         for k,v in pairs( native ) do
  52.             if type( k ) == "string" and type( v ) == "function" then
  53.                 if type( target[k] ) ~= "function" then
  54.                     target[k] = function()
  55.                         error( "Redirect object is missing method "..k..".", 2 )
  56.                     end
  57.                 end
  58.             end
  59.         end
  60.         local oldRedirectTarget = redirectTarget
  61.         redirectTarget = target
  62.         return oldRedirectTarget
  63.     end
  64.  
  65.     term.current = function()
  66.         return redirectTarget
  67.     end
  68.    
  69.     term.native = function()
  70.         -- NOTE: please don't use this function unless you have to.
  71.         -- If you're running in a redirected or multitasked enviorment, term.native() will NOT be
  72.         -- the current terminal when your program starts up. It is far better to use term.current()
  73.         return native
  74.     end
  75.    
  76.     for k,v in pairs( native ) do
  77.         if type( k ) == "string" and type( v ) == "function" then
  78.             if term[k] == nil then
  79.                 term[k] = wrap( k )
  80.             end
  81.         end
  82.     end
  83. end
  84.  
  85. -- 'origterm' used for accessing original term functions in new functions
  86. local origterm = {}
  87. for k,v in pairs(term) do
  88.     origterm[k] = v
  89. end
  90.  
  91. -- 'explode' function for separating strings
  92. local explode = function(div,str)
  93.     if (div=='') then return false end
  94.     local pos,arr = 0,{}
  95.     for st,sp in function() return string.find(str,div,pos,false) end do
  96.         table.insert(arr,string.sub(str,pos,st-1))
  97.         pos = sp + 1
  98.     end
  99.     table.insert(arr,string.sub(str,pos))
  100.     return arr
  101. end
  102.  
  103. local getFileTreeSize = function(path)
  104.     return #explode("/",fs.combine("",path))
  105. end
  106.  
  107. if skipCheck or not term.getCursorPos then
  108.     term.getCursorPos = function()
  109.         return lddterm.cursor.x, lddterm.cursor.y
  110.     end
  111.    
  112.     term.setCursorPos = function(x,y)
  113.         origterm.setCursorPos(x,y)
  114.         lddterm.cursor.x = x
  115.         lddterm.cursor.y = y
  116.     end
  117.    
  118.     term.write = function(text)
  119.         origterm.write(text)
  120.         lddterm.cursor.x = lddterm.cursor.x + #tostring(text)
  121.     end
  122.     term.blit = function(tx,bg,text)
  123.         origterm.blit(tx,bg,text)
  124.         lddterm.cursor.x = lddterm.cursor.x + #tostring(text)
  125.     end
  126. end
  127.  
  128. if skipCheck or not term.getTextColor then
  129.     term.getTextColor = function()
  130.         return lddterm.textcol
  131.     end
  132.     term.getTextColour = term.getTextColor
  133.    
  134.     term.getBackgroundColor = function()
  135.         return lddterm.bgcol
  136.     end
  137.     term.getBackgroundColour = term.getBackgroundColor
  138.    
  139.     term.setTextColor = function(col)
  140.         origterm.setTextColor(col)
  141.         lddterm.textcol = col
  142.     end
  143.     term.setTextColour = term.setTextColor
  144.  
  145.     term.setBackgroundColor = function(col)
  146.         origterm.setBackgroundColor(col)
  147.         lddterm.bgcol = col
  148.     end
  149.     term.setBackgroundColour = term.setBackgroundColor
  150. end
  151.  
  152. if skipCheck or not fs.getDir then
  153.     fs.getDir = function(dir)
  154.         local tree = explode("/", dir or "")
  155.         for a = 1, #tree do
  156.             tree[a] = fs.combine("",tree[a])
  157.         end
  158.         if #tree == 0 then
  159.             return ".."
  160.         elseif #tree == 1 then
  161.             return ""
  162.         else
  163.             return tree[#tree-1]
  164.         end
  165.     end
  166. end
  167.  
  168. write = function( sText ) --can't go wrong with this
  169.     local w,h = term.getSize()        
  170.     local x,y = term.getCursorPos()
  171.     local nLinesPrinted = 0
  172.     local function newLine()
  173.         if y + 1 <= h then
  174.             term.setCursorPos(1, y + 1)
  175.         else
  176.             term.setCursorPos(1, h)
  177.             term.scroll(1)
  178.         end
  179.         x, y = term.getCursorPos()
  180.         nLinesPrinted = nLinesPrinted + 1
  181.     end
  182.     while string.len(sText) > 0 do
  183.         local whitespace = string.match( sText, "^[ \t]+" )
  184.         if whitespace then
  185.             -- Print whitespace
  186.             term.write( whitespace )
  187.             x,y = term.getCursorPos()
  188.             sText = string.sub( sText, string.len(whitespace) + 1 )
  189.         end
  190.         local newline = string.match( sText, "^\n" )
  191.         if newline then
  192.             newLine()
  193.             sText = string.sub( sText, 2 )
  194.         end
  195.         local text = string.match( sText, "^[^ \t\n]+" )
  196.         if text then
  197.             sText = string.sub( sText, string.len(text) + 1 )
  198.             if string.len(text) > w then
  199.                 -- Print a multiline word                
  200.                 while string.len( text ) > 0 do
  201.                     if x > w then
  202.                         newLine()
  203.                     end
  204.                     term.write( text )
  205.                     text = string.sub( text, (w-x) + 2 )
  206.                     x,y = term.getCursorPos()
  207.                 end
  208.             else
  209.                 -- Print a word normally
  210.                 if x + string.len(text) - 1 > w then
  211.                     newLine()
  212.                 end
  213.                 term.write( text )
  214.                 x,y = term.getCursorPos()
  215.             end
  216.         end
  217.     end
  218.    
  219.     return nLinesPrinted
  220. end
  221. local env = _ENV
  222. for k,v in pairs( term ) do
  223.     env[k] = v
  224. end
  225.  
  226. if skipCheck or not fs.find then --thank you bomb bloke
  227.     fs.find = function(path)
  228.         if type(path) ~= "string" then error("bad argument #1 (expected string, got " .. type(path) .. ")", 2 ) end
  229.         local pathParts, results, curfolder = {}, {}, "/"
  230.         for part in path:gmatch("[^/]+") do pathParts[#pathParts + 1] = part:gsub("*", "[^/]*") end
  231.         if #pathParts == 0 then return {} end
  232.             local prospects = fs.list(curfolder)
  233.         for i = 1, #prospects do prospects[i] = {["parent"] = curfolder, ["depth"] = 1, ["name"] = prospects[i]} end
  234.             while #prospects > 0 do
  235.             local thisProspect = table.remove(prospects, 1)
  236.             local fullPath = fs.combine(thisProspect.parent, thisProspect.name)
  237.                 if thisProspect.name == thisProspect.name:match(pathParts[thisProspect.depth]) then
  238.                 if thisProspect.depth == #pathParts then
  239.                     results[#results + 1] = fullPath
  240.                 elseif fs.isDir(fullPath) and thisProspect.depth < #pathParts then
  241.                     local newList = fs.list(fullPath)
  242.                     for i = 1, #newList do prospects[#prospects + 1] = {["parent"] = fullPath, ["depth"] = thisProspect.depth + 1, ["name"] = newList[i]} end
  243.                 end
  244.             end
  245.         end
  246.         return results
  247.     end
  248. end
  249.  
  250. if skipCheck or not fs.complete then
  251.     fscomplete = function(pstr,path,_inclfile,_inclslash)
  252.         if type(_inclfile) == "boolean" then
  253.             inclfile = _inclfile
  254.         else
  255.             inclfile = true
  256.         end
  257.         if type(_inclslash) == "boolean" then
  258.             inclslash = _inclslash
  259.         else
  260.             inclslash = true
  261.         end
  262.        
  263.         output,f1,f2,file = {}
  264.         list = fs.list(path)
  265.         for a = 1, #list do
  266.             file = fs.combine(path,list[a])
  267.             if fs.isDir(file) or inclfile then
  268.                 f1,f2 = list[a]:find("^"..pstr)
  269.                 if f2 then
  270.                     if (inclslash == true) and fs.isDir(file) then
  271.                         output[#output+1] = list[a]:sub(f2+1).."/"
  272.                     end
  273.                     output[#output+1] = list[a]:sub(f2+1)
  274.                 end
  275.             end
  276.         end
  277.         return output
  278.     end
  279. end
  280.  
  281. if skipCheck or not rednet.host then --all ripped straight from /rom/apis/rednet
  282.     rednet.lookup = function( sProtocol, sHostname )
  283.         if type( sProtocol ) ~= "string" then
  284.             error( "expected string", 2 )
  285.         end
  286.         -- Build list of host IDs
  287.         local tResults = nil
  288.         if sHostname == nil then
  289.             tResults = {}
  290.         end
  291.    
  292.         -- Check localhost first
  293.         if tHostnames[ sProtocol ] then
  294.             if sHostname == nil then
  295.                 table.insert( tResults, os.getComputerID() )
  296.             elseif sHostname == "localhost" or sHostname == tHostnames[ sProtocol ] then
  297.                 return os.getComputerID()
  298.             end
  299.         end
  300.         if not isOpen() then
  301.             if tResults then
  302.                 return table.unpack( tResults )
  303.             end
  304.             return nil
  305.         end
  306.         -- Broadcast a lookup packet
  307.         rednet.broadcast( {
  308.             sType = "lookup",
  309.             sProtocol = sProtocol,
  310.             sHostname = sHostname,
  311.         }, "dns" )
  312.    
  313.         -- Start a timer
  314.         local timer = os.startTimer( 2 )
  315.         -- Wait for events
  316.         while true do
  317.             local event, p1, p2, p3 = os.pullEvent()
  318.             if event == "rednet_message" then
  319.                 -- Got a rednet message, check if it's the response to our request
  320.                 local nSenderID, tMessage, sMessageProtocol = p1, p2, p3
  321.                 if sMessageProtocol == "dns" and type(tMessage) == "table" and tMessage.sType == "lookup response" then
  322.                     if tMessage.sProtocol == sProtocol then
  323.                         if sHostname == nil then
  324.                             table.insert( tResults, nSenderID )
  325.                         elseif tMessage.sHostname == sHostname then
  326.                             return nSenderID
  327.                         end
  328.                     end
  329.                 end
  330.             else
  331.                 -- Got a timer event, check it's the end of our timeout
  332.                 if p1 == timer then
  333.                     break
  334.                 end
  335.             end
  336.         end
  337.         if tResults then
  338.             return table.unpack( tResults )
  339.         end
  340.         return nil
  341.     end
  342.     rednet.host = function( sProtocol, sHostname )
  343.         if type( sProtocol ) ~= "string" or type( sHostname ) ~= "string" then
  344.             error( "expected string, string", 2 )
  345.         end
  346.         if sHostname == "localhost" then
  347.             error( "Reserved hostname", 2 )
  348.         end
  349.         if tHostnames[ sProtocol ] ~= sHostname then
  350.             if rednet.lookup( sProtocol, sHostname ) ~= nil then
  351.                 error( "Hostname in use", 2 )
  352.             end
  353.             tHostnames[ sProtocol ] = sHostname
  354.         end
  355.     end
  356.    
  357.     rednet.unhost = function( sProtocol )
  358.         if type( sProtocol ) ~= "string" then
  359.             error( "expected string", 2 )
  360.         end
  361.         tHostnames[ sProtocol ] = nil
  362.     end
  363. end
  364.  
  365. if skipCheck or not settings then
  366.     local tSettings = {}
  367.     settings.set = function( sName, value )
  368.         if type(sName) ~= "string" or
  369.            (type(value) ~= "string" and type(value) ~= "number" and type(value) ~= "boolean" and type(value) ~= "table") then
  370.             error( "Expected string, value", 2 )
  371.         end
  372.         if type(value) == "table" then
  373.             -- Ensure value is serializeable
  374.             value = textutils.unserialize( textutils.serialize(value) )
  375.         end
  376.         tSettings[ sName ] = value
  377.     end
  378.     local copy
  379.     copy = function( value )
  380.         if type(value) == "table" then
  381.             local result = {}
  382.             for k,v in pairs(value) do
  383.                 result[k] = copy(v)
  384.             end
  385.             return result
  386.         else
  387.             return value
  388.         end
  389.     end
  390.    
  391.     settings.get = function( sName, default )
  392.         if type(sName) ~= "string" then
  393.             error( "Expected string", 2 )
  394.         end
  395.         local result = tSettings[ sName ]
  396.         if result ~= nil then
  397.             return copy(result)
  398.         else
  399.             return default
  400.         end
  401.     end
  402.    
  403.     settings.unset = function( sName )
  404.         if type(sName) ~= "string" then
  405.             error( "Expected string", 2 )
  406.         end
  407.         tSettings[ sName ] = nil
  408.     end
  409.    
  410.     settings.clear = function()
  411.         tSettings = {}
  412.     end
  413.    
  414.     settings.getNames = function()
  415.         local result = {}
  416.         for k,v in pairs( tSettings ) do
  417.             result[ #result + 1 ] = k
  418.         end
  419.         return result
  420.     end
  421.    
  422.     settings.load = function( sPath )
  423.         if type(sPath) ~= "string" then
  424.             error( "Expected string", 2 )
  425.         end
  426.         local file = fs.open( sPath, "r" )
  427.         if not file then
  428.             return false
  429.         end
  430.    
  431.         local sText = file.readAll()
  432.         file.close()
  433.    
  434.         local tFile = textutils.unserialize( sText )
  435.         if type(tFile) ~= "table" then
  436.             return false
  437.         end
  438.    
  439.         for k,v in pairs(tFile) do
  440.             if type(k) == "string" and
  441.                (type(v) == "string" or type(v) == "number" or type(v) == "boolean" or type(v) == "table") then
  442.                 settings.set( k, v )
  443.             end
  444.         end
  445.    
  446.         return true
  447.     end
  448.    
  449.     settings.save = function( sPath )
  450.         if type(sPath) ~= "string" then
  451.             error( "Expected string", 2 )
  452.         end
  453.         local file = fs.open( sPath, "w" )
  454.         if not file then
  455.             return false
  456.         end
  457.    
  458.         file.write( textutils.serialize( tSettings ) )
  459.         file.close()
  460.    
  461.         return true
  462.     end
  463. end
  464.  
  465. if skipCheck or not textutils.serializeJSON then
  466.     local empty_json_array = {}
  467.     local serializeJSONImpl
  468.     function serializeJSONImpl( t, tTracking, bNBTStyle )
  469.         local sType = type(t)
  470.         if t == empty_json_array then
  471.             return "[]"
  472.    
  473.         elseif sType == "table" then
  474.             if tTracking[t] ~= nil then
  475.                 error( "Cannot serialize table with recursive entries", 0 )
  476.             end
  477.             tTracking[t] = true
  478.    
  479.             if next(t) == nil then
  480.                 -- Empty tables are simple
  481.                 return "{}"
  482.             else
  483.                 -- Other tables take more work
  484.                 local sObjectResult = "{"
  485.                 local sArrayResult = "["
  486.                 local nObjectSize = 0
  487.                 local nArraySize = 0
  488.                 for k,v in pairs(t) do
  489.                     if type(k) == "string" then
  490.                         local sEntry
  491.                         if bNBTStyle then
  492.                             sEntry = tostring(k) .. ":" .. serializeJSONImpl( v, tTracking, bNBTStyle )
  493.                         else
  494.                             sEntry = string.format( "%q", k ) .. ":" .. serializeJSONImpl( v, tTracking, bNBTStyle )
  495.                         end
  496.                         if nObjectSize == 0 then
  497.                             sObjectResult = sObjectResult .. sEntry
  498.                         else
  499.                             sObjectResult = sObjectResult .. "," .. sEntry
  500.                         end
  501.                         nObjectSize = nObjectSize + 1
  502.                     end
  503.                 end
  504.                 for n,v in ipairs(t) do
  505.                     local sEntry = serializeJSONImpl( v, tTracking, bNBTStyle )
  506.                     if nArraySize == 0 then
  507.                         sArrayResult = sArrayResult .. sEntry
  508.                     else
  509.                         sArrayResult = sArrayResult .. "," .. sEntry
  510.                     end
  511.                     nArraySize = nArraySize + 1
  512.                 end
  513.                 sObjectResult = sObjectResult .. "}"
  514.                 sArrayResult = sArrayResult .. "]"
  515.                 if nObjectSize > 0 or nArraySize == 0 then
  516.                     return sObjectResult
  517.                 else
  518.                     return sArrayResult
  519.                 end
  520.             end
  521.    
  522.         elseif sType == "string" then
  523.             return string.format( "%q", t )
  524.    
  525.         elseif sType == "number" or sType == "boolean" then
  526.             return tostring(t)
  527.         else
  528.             error( "Cannot serialize type "..sType, 0 )
  529.         end
  530.     end
  531.  
  532.     function urlEncode( str )
  533.         if str then
  534.             str = string.gsub(str, "\n", "\r\n")
  535.             str = string.gsub(str, "([^A-Za-z0-9 %-%_%.])", function(c)
  536.                 local n = string.byte(c)
  537.                 if n < 128 then
  538.                     -- ASCII
  539.                     return string.format("%%%02X", n)
  540.                 else
  541.                     -- Non-ASCII (encode as UTF-8)
  542.                     return
  543.                         string.format("%%%02X", 192 + bit32.band( bit32.arshift(n,6), 31 ) ) ..
  544.                         string.format("%%%02X", 128 + bit32.band( n, 63 ) )
  545.                 end
  546.             end )
  547.             str = string.gsub(str, " ", "+")
  548.         end
  549.         return str    
  550.     end
  551.  
  552.     local tEmpty = {}
  553.     function complete( sSearchText, tSearchTable )
  554.         local nStart = 1
  555.         local nDot = string.find( sSearchText, ".", nStart, true )
  556.         local tTable = tSearchTable or _ENV
  557.         while nDot do
  558.             local sPart = string.sub( sSearchText, nStart, nDot - 1 )
  559.             local value = tTable[ sPart ]
  560.             if type( value ) == "table" then
  561.                 tTable = value
  562.                 nStart = nDot + 1
  563.                 nDot = string.find( sSearchText, ".", nStart, true )
  564.             else
  565.                 return tEmpty
  566.             end
  567.         end
  568.    
  569.         local sPart = string.sub( sSearchText, nStart, nDot )
  570.         local nPartLength = string.len( sPart )
  571.    
  572.         local tResults = {}
  573.         local tSeen = {}
  574.         while tTable do
  575.             for k,v in pairs( tTable ) do
  576.                 if not tSeen[k] and type(k) == "string" then
  577.                     if string.find( k, sPart, 1, true ) == 1 then
  578.                         if not g_tLuaKeywords[k] and string.match( k, "^[%a_][%a%d_]*$" ) then
  579.                             local sResult = string.sub( k, nPartLength + 1 )
  580.                             if type(v) == "function" then
  581.                                 sResult = sResult .. "("
  582.                             elseif type(v) == "table" and next(v) ~= nil then
  583.                                 sResult = sResult .. "."
  584.                             end
  585.                             table.insert( tResults, sResult )
  586.                         end
  587.                     end
  588.                 end
  589.                 tSeen[k] = true
  590.             end
  591.             local tMetatable = getmetatable( tTable )
  592.             if tMetatable and type( tMetatable.__index ) == "table" then
  593.                 tTable = tMetatable.__index
  594.             else
  595.                 tTable = nil
  596.             end
  597.         end
  598.    
  599.         table.sort( tResults )
  600.         return tResults
  601.     end
  602. end
  603. -- GB versions of serialise
  604. serialise = serialize
  605. unserialise = unserialize
  606. serialiseJSON = serializeJSON
  607.  
  608. if turtle then
  609.     if skipCheck or not turtle.getSelectedSlot then
  610.         local tselect = turtle.select
  611.         turtle.select = function(slot)
  612.             local success = tselect(slot)
  613.             if success then
  614.                 lddterm.turtleslot = slot
  615.             end
  616.             return success
  617.         end
  618.        
  619.         turtle.getSelectedSlot = function()
  620.             return lddterm.turtleslot
  621.         end
  622.     end
  623. end
  624.  
  625. local tablCopy = function(tabl)
  626.     local output = {}
  627.     for k,v in pairs(tabl) do
  628.         output[k] = v
  629.     end
  630.     return output
  631. end
  632.  
  633. if skipCheck or not window then
  634.    
  635.     local tHex = {
  636.         [ colors.white ] = "0",
  637.         [ colors.orange ] = "1",
  638.         [ colors.magenta ] = "2",
  639.         [ colors.lightBlue ] = "3",
  640.         [ colors.yellow ] = "4",
  641.         [ colors.lime ] = "5",
  642.         [ colors.pink ] = "6",
  643.         [ colors.gray ] = "7",
  644.         [ colors.lightGray ] = "8",
  645.         [ colors.cyan ] = "9",
  646.         [ colors.purple ] = "a",
  647.         [ colors.blue ] = "b",
  648.         [ colors.brown ] = "c",
  649.         [ colors.green ] = "d",
  650.         [ colors.red ] = "e",
  651.         [ colors.black ] = "f",
  652.     }
  653.    
  654.     local string_rep = string.rep
  655.     local string_sub = string.sub
  656.    
  657.     function window.create( parent, nX, nY, nWidth, nHeight, bStartVisible )
  658.    
  659.         if type( parent ) ~= "table" or
  660.            type( nX ) ~= "number" or
  661.            type( nY ) ~= "number" or
  662.            type( nWidth ) ~= "number" or
  663.            type( nHeight ) ~= "number" or
  664.            (bStartVisible ~= nil and type( bStartVisible ) ~= "boolean") then
  665.             error( "Expected object, number, number, number, number, [boolean]", 2 )
  666.         end
  667.         --[[
  668.         if parent == term then
  669.             error( "term is not a recommended window parent, try term.current() instead", 2 )
  670.         end
  671.         --]]
  672.         local sEmptySpaceLine
  673.         local tEmptyColorLines = {}
  674.         local function createEmptyLines( nWidth )
  675.             sEmptySpaceLine = string_rep( " ", nWidth )
  676.             for n=0,15 do
  677.                 local nColor = 2^n
  678.                 local sHex = tHex[nColor]
  679.                 tEmptyColorLines[nColor] = string_rep( sHex, nWidth )
  680.             end
  681.         end
  682.    
  683.         createEmptyLines( nWidth )
  684.    
  685.         -- Setup
  686.         local bVisible = (bStartVisible ~= false)
  687.         local nCursorX = 1
  688.         local nCursorY = 1
  689.         local bCursorBlink = false
  690.         local nTextColor = colors.white
  691.         local nBackgroundColor = colors.black
  692.         local tLines = {}
  693.         do
  694.             local sEmptyText = sEmptySpaceLine
  695.             local sEmptyTextColor = tEmptyColorLines[ nTextColor ]
  696.             local sEmptyBackgroundColor = tEmptyColorLines[ nBackgroundColor ]
  697.             for y=1,nHeight do
  698.                 tLines[y] = {
  699.                     text = sEmptyText,
  700.                     textColor = sEmptyTextColor,
  701.                     backgroundColor = sEmptyBackgroundColor,
  702.                 }
  703.             end
  704.         end
  705.    
  706.         -- Helper functions
  707.         local function updateCursorPos()
  708.             if nCursorX >= 1 and nCursorY >= 1 and
  709.                nCursorX <= nWidth and nCursorY <= nHeight then
  710.                 parent.setCursorPos( nX + nCursorX - 1, nY + nCursorY - 1 )
  711.             else
  712.                 parent.setCursorPos( 0, 0 )
  713.             end
  714.         end
  715.        
  716.         local function updateCursorBlink()
  717.             parent.setCursorBlink( bCursorBlink )
  718.         end
  719.        
  720.         local function updateCursorColor()
  721.             parent.setTextColor( nTextColor )
  722.         end
  723.        
  724.         local function redrawLine( n )
  725.             local tLine = tLines[ n ]
  726.             parent.setCursorPos( nX, nY + n - 1 )
  727.             parent.blit( tLine.text, tLine.textColor, tLine.backgroundColor )
  728.         end
  729.    
  730.         local function redraw()
  731.             for n=1,nHeight do
  732.                 redrawLine( n )
  733.             end
  734.         end
  735.    
  736.         local function internalBlit( sText, sTextColor, sBackgroundColor )
  737.             local nStart = nCursorX
  738.             local nEnd = nStart + #sText - 1
  739.             if nCursorY >= 1 and nCursorY <= nHeight then
  740.                 if nStart <= nWidth and nEnd >= 1 then
  741.                     -- Modify line
  742.                     local tLine = tLines[ nCursorY ]
  743.                     if nStart == 1 and nEnd == nWidth then
  744.                         tLine.text = sText
  745.                         tLine.textColor = sTextColor
  746.                         tLine.backgroundColor = sBackgroundColor
  747.                     else
  748.                         local sClippedText, sClippedTextColor, sClippedBackgroundColor
  749.                         if nStart < 1 then
  750.                             local nClipStart = 1 - nStart + 1
  751.                             local nClipEnd = nWidth - nStart + 1
  752.                             sClippedText = string_sub( sText, nClipStart, nClipEnd )
  753.                             sClippedTextColor = string_sub( sTextColor, nClipStart, nClipEnd )
  754.                             sClippedBackgroundColor = string_sub( sBackgroundColor, nClipStart, nClipEnd )
  755.                         elseif nEnd > nWidth then
  756.                             local nClipEnd = nWidth - nStart + 1
  757.                             sClippedText = string_sub( sText, 1, nClipEnd )
  758.                             sClippedTextColor = string_sub( sTextColor, 1, nClipEnd )
  759.                             sClippedBackgroundColor = string_sub( sBackgroundColor, 1, nClipEnd )
  760.                         else
  761.                             sClippedText = sText
  762.                             sClippedTextColor = sTextColor
  763.                             sClippedBackgroundColor = sBackgroundColor
  764.                         end
  765.    
  766.                         local sOldText = tLine.text
  767.                         local sOldTextColor = tLine.textColor
  768.                         local sOldBackgroundColor = tLine.backgroundColor
  769.                         local sNewText, sNewTextColor, sNewBackgroundColor
  770.                         if nStart > 1 then
  771.                             local nOldEnd = nStart - 1
  772.                             sNewText = string_sub( sOldText, 1, nOldEnd ) .. sClippedText
  773.                             sNewTextColor = string_sub( sOldTextColor, 1, nOldEnd ) .. sClippedTextColor
  774.                             sNewBackgroundColor = string_sub( sOldBackgroundColor, 1, nOldEnd ) .. sClippedBackgroundColor
  775.                         else
  776.                             sNewText = sClippedText
  777.                             sNewTextColor = sClippedTextColor
  778.                             sNewBackgroundColor = sClippedBackgroundColor
  779.                         end
  780.                         if nEnd < nWidth then
  781.                             local nOldStart = nEnd + 1
  782.                             sNewText = sNewText .. string_sub( sOldText, nOldStart, nWidth )
  783.                             sNewTextColor = sNewTextColor .. string_sub( sOldTextColor, nOldStart, nWidth )
  784.                             sNewBackgroundColor = sNewBackgroundColor .. string_sub( sOldBackgroundColor, nOldStart, nWidth )
  785.                         end
  786.    
  787.                         tLine.text = sNewText
  788.                         tLine.textColor = sNewTextColor
  789.                         tLine.backgroundColor = sNewBackgroundColor
  790.                     end
  791.    
  792.                     -- Redraw line
  793.                     if bVisible then
  794.                         redrawLine( nCursorY )
  795.                     end
  796.                 end
  797.             end
  798.    
  799.             -- Move and redraw cursor
  800.             nCursorX = nEnd + 1
  801.             if bVisible then
  802.                 updateCursorColor()
  803.                 updateCursorPos()
  804.             end
  805.         end
  806.    
  807.         -- Terminal implementation
  808.         local window = {}
  809.    
  810.         function window.write( sText )
  811.             sText = tostring( sText )
  812.             internalBlit( sText, string_rep( tHex[ nTextColor ], #sText ), string_rep( tHex[ nBackgroundColor ], #sText ) )
  813.         end
  814.    
  815.         function window.blit( sText, sTextColor, sBackgroundColor )
  816.             if type(sText) ~= "string" or type(sTextColor) ~= "string" or type(sBackgroundColor) ~= "string" then
  817.                 error( "Expected string, string, string", 2 )
  818.             end
  819.             if #sTextColor ~= #sText or #sBackgroundColor ~= #sText then
  820.                 error( "Arguments must be the same length", 2 )
  821.             end
  822.             internalBlit( sText, sTextColor, sBackgroundColor )
  823.         end
  824.    
  825.         function window.clear()
  826.             local sEmptyText = sEmptySpaceLine
  827.             local sEmptyTextColor = tEmptyColorLines[ nTextColor ]
  828.             local sEmptyBackgroundColor = tEmptyColorLines[ nBackgroundColor ]
  829.             for y=1,nHeight do
  830.                 tLines[y] = {
  831.                     text = sEmptyText,
  832.                     textColor = sEmptyTextColor,
  833.                     backgroundColor = sEmptyBackgroundColor,
  834.                 }
  835.             end
  836.             if bVisible then
  837.                 redraw()
  838.                 updateCursorColor()
  839.                 updateCursorPos()
  840.             end
  841.         end
  842.    
  843.         function window.clearLine()
  844.             if nCursorY >= 1 and nCursorY <= nHeight then
  845.                 local sEmptyText = sEmptySpaceLine
  846.                 local sEmptyTextColor = tEmptyColorLines[ nTextColor ]
  847.                 local sEmptyBackgroundColor = tEmptyColorLines[ nBackgroundColor ]
  848.                 tLines[ nCursorY ] = {
  849.                     text = sEmptyText,
  850.                     textColor = sEmptyTextColor,
  851.                     backgroundColor = sEmptyBackgroundColor,
  852.                 }
  853.                 if bVisible then
  854.                     redrawLine( nCursorY )
  855.                     updateCursorColor()
  856.                     updateCursorPos()
  857.                 end
  858.             end
  859.         end
  860.    
  861.         function window.getCursorPos()
  862.             return nCursorX, nCursorY
  863.         end
  864.    
  865.         function window.setCursorPos( x, y )
  866.             nCursorX = math.floor( x )
  867.             nCursorY = math.floor( y )
  868.             if bVisible then
  869.                 updateCursorPos()
  870.             end
  871.         end
  872.    
  873.         function window.setCursorBlink( blink )
  874.             bCursorBlink = blink
  875.             if bVisible then
  876.                 updateCursorBlink()
  877.             end
  878.         end
  879.    
  880.         local function isColor()
  881.             return parent.isColor()
  882.         end
  883.    
  884.         function window.isColor()
  885.             return isColor()
  886.         end
  887.    
  888.         function window.isColour()
  889.             return isColor()
  890.         end
  891.    
  892.         local function setTextColor( color )
  893.             if not parent.isColor() then
  894.                 if color ~= colors.white and color ~= colors.black and color ~= colors.gray and color ~= colors.lightGray then
  895.                     error( "Color not supported", 3 )
  896.                 end
  897.             end
  898.             nTextColor = color
  899.             if bVisible then
  900.                 updateCursorColor()
  901.             end
  902.         end
  903.    
  904.         function window.setTextColor( color )
  905.             setTextColor( color )
  906.         end
  907.    
  908.         function window.setTextColour( color )
  909.             setTextColor( color )
  910.         end
  911.    
  912.         local function setBackgroundColor( color )
  913.             if not parent.isColor() then
  914.                 if color ~= colors.white and color ~= colors.black and color ~= colors.gray and color ~= colors.lightGray then
  915.                     error( "Color not supported", 3 )
  916.                 end
  917.             end
  918.             nBackgroundColor = color
  919.         end
  920.    
  921.         function window.setBackgroundColor( color )
  922.             setBackgroundColor( color )
  923.         end
  924.    
  925.         function window.setBackgroundColour( color )
  926.             setBackgroundColor( color )
  927.         end
  928.    
  929.         function window.getSize()
  930.             return nWidth, nHeight
  931.         end
  932.    
  933.         function window.scroll( n )
  934.             if n ~= 0 then
  935.                 local tNewLines = {}
  936.                 local sEmptyText = sEmptySpaceLine
  937.                 local sEmptyTextColor = tEmptyColorLines[ nTextColor ]
  938.                 local sEmptyBackgroundColor = tEmptyColorLines[ nBackgroundColor ]
  939.                 for newY=1,nHeight do
  940.                     local y = newY + n
  941.                     if y >= 1 and y <= nHeight then
  942.                         tNewLines[newY] = tLines[y]
  943.                     else
  944.                         tNewLines[newY] = {
  945.                             text = sEmptyText,
  946.                             textColor = sEmptyTextColor,
  947.                             backgroundColor = sEmptyBackgroundColor,
  948.                         }
  949.                     end
  950.                 end
  951.                 tLines = tNewLines
  952.                 if bVisible then
  953.                     redraw()
  954.                     updateCursorColor()
  955.                     updateCursorPos()
  956.                 end
  957.             end
  958.         end
  959.    
  960.         function window.getTextColor()
  961.             return nTextColor
  962.         end
  963.    
  964.         function window.getTextColour()
  965.             return nTextColor
  966.         end
  967.    
  968.         function window.getBackgroundColor()
  969.             return nBackgroundColor
  970.         end
  971.    
  972.         function window.getBackgroundColour()
  973.             return nBackgroundColor
  974.         end
  975.    
  976.         -- Other functions
  977.         function window.setVisible( bVis )
  978.             if bVisible ~= bVis then
  979.                 bVisible = bVis
  980.                 if bVisible then
  981.                     window.redraw()
  982.                 end
  983.             end
  984.         end
  985.    
  986.         function window.redraw()
  987.             if bVisible then
  988.                 redraw()
  989.                 updateCursorBlink()
  990.                 updateCursorColor()
  991.                 updateCursorPos()
  992.             end
  993.         end
  994.    
  995.         function window.restoreCursor()
  996.             if bVisible then
  997.                 updateCursorBlink()
  998.                 updateCursorColor()
  999.                 updateCursorPos()
  1000.             end
  1001.         end
  1002.    
  1003.         function window.getPosition()
  1004.             return nX, nY
  1005.         end
  1006.    
  1007.         function window.reposition( nNewX, nNewY, nNewWidth, nNewHeight )
  1008.             nX = nNewX
  1009.             nY = nNewY
  1010.             if nNewWidth and nNewHeight then
  1011.                 local tNewLines = {}
  1012.                 createEmptyLines( nNewWidth )
  1013.                 local sEmptyText = sEmptySpaceLine
  1014.                 local sEmptyTextColor = tEmptyColorLines[ nTextColor ]
  1015.                 local sEmptyBackgroundColor = tEmptyColorLines[ nBackgroundColor ]
  1016.                 for y=1,nNewHeight do
  1017.                     if y > nHeight then
  1018.                         tNewLines[y] = {
  1019.                             text = sEmptyText,
  1020.                             textColor = sEmptyTextColor,
  1021.                             backgroundColor = sEmptyBackgroundColor
  1022.                         }
  1023.                     else
  1024.                         local tOldLine = tLines[y]
  1025.                         if nNewWidth == nWidth then
  1026.                             tNewLines[y] = tOldLine
  1027.                         elseif nNewWidth < nWidth then
  1028.                             tNewLines[y] = {
  1029.                                 text = string_sub( tOldLine.text, 1, nNewWidth ),
  1030.                                 textColor = string_sub( tOldLine.textColor, 1, nNewWidth ),
  1031.                                 backgroundColor = string_sub( tOldLine.backgroundColor, 1, nNewWidth ),
  1032.                             }
  1033.                         else
  1034.                             tNewLines[y] = {
  1035.                                 text = tOldLine.text .. string_sub( sEmptyText, nWidth + 1, nNewWidth ),
  1036.                                 textColor = tOldLine.textColor .. string_sub( sEmptyTextColor, nWidth + 1, nNewWidth ),
  1037.                                 backgroundColor = tOldLine.backgroundColor .. string_sub( sEmptyBackgroundColor, nWidth + 1, nNewWidth ),
  1038.                             }
  1039.                         end
  1040.                     end
  1041.                 end
  1042.                 nWidth = nNewWidth
  1043.                 nHeight = nNewHeight
  1044.                 tLines = tNewLines
  1045.             end
  1046.             if bVisible then
  1047.                 window.redraw()
  1048.             end
  1049.         end
  1050.    
  1051.         if bVisible then
  1052.             window.redraw()
  1053.         end
  1054.         return window
  1055.     end
  1056. end
  1057.  
  1058. if skipCheck or not redstone.setAnalogOutput then
  1059.     redstone.setAnalogOutput = function(side,amnt)
  1060.         if amnt > 0 then
  1061.             redstone.setOutput(side,true)
  1062.         else
  1063.             redstone.setOutput(side,false)
  1064.         end
  1065.     end
  1066.     redstone.getAnalogInput = function(side)
  1067.         return redstone.getInput(side) and 16 or 0
  1068.     end
  1069.     redstone.getAnalogOutput = function(side)
  1070.         return redstone.getOutput(side) and 16 or 0
  1071.     end
  1072. end
  1073.  
  1074.  
  1075. local tArg = {...}
  1076. fileToRun = fileToRun or tArg
  1077. if (fileToRun) and (fileToRun ~= {}) then
  1078.     if shell then
  1079.         shell.run(fileToRun)
  1080.     else
  1081.         dofile(fileToRun)
  1082.     end
  1083. else
  1084.     term.setCursorPos(1,1)
  1085.     term.clear()
  1086.     print("FCOMP ACTIVE!")
  1087. end
  1088. --[[
  1089. TODO:
  1090.  + test test test!
  1091. --]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement