MechWipf

SF Digiscreen

Mar 20th, 2017
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.11 KB | None | 0 0
  1. --@name DigitalScreen
  2. --@author MechWipf
  3. --@shared
  4.  
  5. local function clamp(x,min,max)
  6.   if x < min then x = min
  7.   elseif x > max then x = max end
  8.   return x
  9. end
  10.  
  11. ----------------------------------
  12. --     Net-Codes        --
  13. --      0 HWClr             --
  14. --    1 SetHeight           --
  15. --    2 SetWidth            --
  16. --      3 SetColor(X,Y,R,G,B)   --
  17. --    4 SetMode (Gray)    --
  18. ----------------------------------
  19. local NetBuffer = {}
  20.  
  21. local Screen_ID = 1
  22. local Data = {
  23.   Height = 100,
  24.   Width  = 100,
  25.   ColorMode = 0}
  26.  
  27. -- Constants
  28. local NET_DATA_CLEAR   = 0
  29. local NET_DATA_COLORMODE = 1
  30. local NET_DATA_DRAW    = 2
  31.  
  32. local function checkQ ( n )
  33.   return quotaUsed() < quotaMax() * n
  34. end
  35.  
  36. if SERVER then
  37.   wire.adjustInputs( { "Refresh" }, { "normal" } )
  38.   wire.adjustOutputs( {'Memory'}, {'normal'} )
  39.  
  40.   Data.Map = {}
  41.  
  42.   hook.add('readcell', 'DS_readcell_', function(address)
  43.     return Data.Map[address+1] or 0
  44.   end)
  45.  
  46.   local function sendDraw ( address, data )
  47.       local x, y = address % Data.Width, math.floor( address / Data.Width )
  48.       local w, h = math.floor( 1024 / Data.Width ), math.floor( 1024 / Data.Height )
  49.      
  50.       x, y = x * w, y * h
  51.  
  52.       local clr = {}
  53.       if Data.ColorMode == 0 then
  54.         clr[1] = data
  55.       elseif Data.ColorMode == 1 then
  56.         print "Not supported colormode"
  57.       elseif Data.ColorMode == 2 then
  58.         clr[1] = bit.rshift( clr, 16 ) % 256
  59.         clr[2] = bit.rshift( clr,  8 ) % 256
  60.         clr[3] = clr % 256
  61.       elseif Data.ColorMode == 3 then
  62.         local i = 1
  63.         data = tostring(data)
  64.         data = string.rep( "0", 9 - data:len() ) .. data
  65.         data:gsub( "...", function( s ) clr[i] = tonumber(s); i = i + 1 end )
  66.       end
  67.      
  68.       NetBuffer[#NetBuffer+1] = { NET_DATA_DRAW, x, y, w, h, unpack( clr ) }
  69.   end
  70.  
  71.   hook.add('writecell', 'DS_writecell', function(address, data)
  72.     -- print( ("write %s on %s"):format( data, address ) )
  73.     if address >= 0 and (address <= 786431 and address <= Data.Height*Data.Width) then --RGB data
  74.       Data.Map[address+1] = data
  75.       sendDraw( address, data )
  76.     elseif address == 1048569 then --Color mode
  77.       -- 0 RGBXXX Grayscale
  78.       -- 1 R G B seperated values
  79.       -- 2 R*65536 + G*256 + B
  80.       -- 3 RRRGGGBBB
  81.       Data.ColorMode_ = clamp(data, 0, 3)
  82.     elseif address == 1048570 then --Clear row
  83.     elseif address == 1048571 then --Clear column
  84.     elseif address == 1048572 then --Height
  85.       Data.Height_ = clamp(data, 0, 512)
  86.     elseif address == 1048573 then --Width
  87.       Data.Width_ = clamp(data, 0, 512)
  88.     elseif address == 1048574 then --Hardware Clear Screen
  89.       if Data.Height_ then
  90.         Data.Height = Data.Height_
  91.         Data.Height_ = nil
  92.       end
  93.  
  94.       if Data.Width_ then
  95.         Data.Width = Data.Width_
  96.         Data.Width_ = nil
  97.       end
  98.  
  99.       if Data.ColorMode_ then
  100.         Data.ColorMode = Data.ColorMode_
  101.         Data.ColorMode_ = nil
  102.         NetBuffer[#NetBuffer+1] = { NET_DATA_COLORMODE, Data.ColorMode}
  103.       end
  104.  
  105.       Data.Map = {}
  106.       NetBuffer[#NetBuffer+1] = { NET_DATA_CLEAR }
  107.     end
  108.   end)
  109.  
  110.   local function _resendAllData ()
  111.     NetBuffer[#NetBuffer+1] = { NET_DATA_CLEAR }
  112.  
  113.     print "i am alive"
  114.  
  115.     for i = 1, Data.Width * Data.Height do
  116.       sendDraw( i - 1, Data.Map[i] )
  117.      
  118.       if not checkQ( 0.95 ) then
  119.         coroutine.yield()
  120.       end
  121.     end
  122.   end
  123.  
  124.   local resendAllData = false
  125.   local function DS_think ()
  126.     if not checkQ( 0.1 ) then return end
  127.    
  128.     if resendAllData then
  129.       coroutine.resume( resendAllData )
  130.      
  131.       local status = coroutine.status( resendAllData )
  132.       if status == "running" then
  133.         return
  134.       else
  135.         resendAllData = false
  136.       end
  137.     end
  138.    
  139.     if not Data.dat and #NetBuffer > 0 then
  140.       local buffer = {}
  141.       local c = math.min( #NetBuffer, 200 )
  142.  
  143.       while c > 0 do
  144.         c = c - 1
  145.         buffer[#buffer+1] = table.remove( NetBuffer, 1 )
  146.       end
  147.      
  148.       Data.dat = fastlz.compress( von.serialize( buffer ) )
  149.     end
  150.  
  151.     if Data.dat and net.getBytesLeft() > Data.dat:len() * 1.2 then
  152.       -- print( Data.dat:len(), net.getBytesLeft() )
  153.  
  154.       net.start('DS_net_' .. Screen_ID)
  155.       net.writeData( Data.dat, Data.dat:len() )
  156.       net.send()
  157.  
  158.       Data.dat = nil
  159.     end
  160.   end
  161.  
  162.   local _Refresh = 0
  163.   local function DS_input ( inputName, value )
  164.     if not checkQ( 0.95 ) then return end
  165.    
  166.     if inputName == "Refresh" and _Refresh ~= value then
  167.       _Refresh = value
  168.      
  169.       if value >= 1 and not resendAllData then
  170.         resendAllData = coroutine.create( _resendAllData )
  171.       end
  172.     end
  173.   end
  174.  
  175.   hook.add('think', 'DS_think', DS_think)
  176.   hook.add( "input", "DS_input", DS_input)
  177.  
  178. elseif CLIENT then
  179.   local DrawBuffer = {}
  180.   local A = true
  181.  
  182.   hook.add('net', 'DS_net', function(name, len, ply)
  183.     if name == 'DS_net_' .. Screen_ID then
  184.       local str = net.readData( len )
  185.       local buffer = von.deserialize( fastlz.decompress( str ) )
  186.       for _, v in pairs(buffer) do
  187.         DrawBuffer[#DrawBuffer+1] = v
  188.       end
  189.     end
  190.   end)
  191.  
  192.   local first = true
  193.   hook.add('render', 'DS_render_', function(data)
  194.     if first then
  195.       first = false
  196.       render.createRenderTarget( "ds_rt" )
  197.       render.selectRenderTarget( "ds_rt" )
  198.       render.clear()
  199.     end
  200.  
  201.     render.selectRenderTarget( nil )
  202.     render.setRenderTargetTexture( "ds_rt" )
  203.     render.drawTexturedRect( 0, 0, 512, 512 )
  204.  
  205.     while #DrawBuffer > 0 do
  206.       render.selectRenderTarget( "ds_rt" )
  207.       local chunk = table.remove(DrawBuffer, 1)
  208.  
  209.       if        chunk[1] == NET_DATA_CLEAR then
  210.         render.clear( Color( 0,0,0,255 ) )
  211.       elseif  chunk[1] == NET_DATA_COLORMODE then
  212.         Data.ColorMode = chunk[2]
  213.       elseif    chunk[1] == NET_DATA_DRAW then
  214.         local x, y = chunk[2], chunk[3]
  215.         local w, h = chunk[4], chunk[5]
  216.        
  217.         if Data.ColorMode == 0 then
  218.           render.setRGBA(chunk[6],chunk[6],chunk[6],255)
  219.         else
  220.           render.setRGBA(chunk[6],chunk[7],chunk[8],255)
  221.         end
  222.  
  223.         render.drawRect( x, y, w, h )
  224.       end
  225.     end
  226.   end)
  227. end
Advertisement
Add Comment
Please, Sign In to add comment