Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --@name DigitalScreen
- --@author MechWipf
- --@shared
- local function clamp(x,min,max)
- if x < min then x = min
- elseif x > max then x = max end
- return x
- end
- ----------------------------------
- -- Net-Codes --
- -- 0 HWClr --
- -- 1 SetHeight --
- -- 2 SetWidth --
- -- 3 SetColor(X,Y,R,G,B) --
- -- 4 SetMode (Gray) --
- ----------------------------------
- local NetBuffer = {}
- local Screen_ID = 1
- local Data = {
- Height = 100,
- Width = 100,
- ColorMode = 0}
- -- Constants
- local NET_DATA_CLEAR = 0
- local NET_DATA_COLORMODE = 1
- local NET_DATA_DRAW = 2
- local function checkQ ( n )
- return quotaUsed() < quotaMax() * n
- end
- if SERVER then
- wire.adjustInputs( { "Refresh" }, { "normal" } )
- wire.adjustOutputs( {'Memory'}, {'normal'} )
- Data.Map = {}
- hook.add('readcell', 'DS_readcell_', function(address)
- return Data.Map[address+1] or 0
- end)
- local function sendDraw ( address, data )
- local x, y = address % Data.Width, math.floor( address / Data.Width )
- local w, h = math.floor( 1024 / Data.Width ), math.floor( 1024 / Data.Height )
- x, y = x * w, y * h
- local clr = {}
- if Data.ColorMode == 0 then
- clr[1] = data
- elseif Data.ColorMode == 1 then
- print "Not supported colormode"
- elseif Data.ColorMode == 2 then
- clr[1] = bit.rshift( clr, 16 ) % 256
- clr[2] = bit.rshift( clr, 8 ) % 256
- clr[3] = clr % 256
- elseif Data.ColorMode == 3 then
- local i = 1
- data = tostring(data)
- data = string.rep( "0", 9 - data:len() ) .. data
- data:gsub( "...", function( s ) clr[i] = tonumber(s); i = i + 1 end )
- end
- NetBuffer[#NetBuffer+1] = { NET_DATA_DRAW, x, y, w, h, unpack( clr ) }
- end
- hook.add('writecell', 'DS_writecell', function(address, data)
- -- print( ("write %s on %s"):format( data, address ) )
- if address >= 0 and (address <= 786431 and address <= Data.Height*Data.Width) then --RGB data
- Data.Map[address+1] = data
- sendDraw( address, data )
- elseif address == 1048569 then --Color mode
- -- 0 RGBXXX Grayscale
- -- 1 R G B seperated values
- -- 2 R*65536 + G*256 + B
- -- 3 RRRGGGBBB
- Data.ColorMode_ = clamp(data, 0, 3)
- elseif address == 1048570 then --Clear row
- elseif address == 1048571 then --Clear column
- elseif address == 1048572 then --Height
- Data.Height_ = clamp(data, 0, 512)
- elseif address == 1048573 then --Width
- Data.Width_ = clamp(data, 0, 512)
- elseif address == 1048574 then --Hardware Clear Screen
- if Data.Height_ then
- Data.Height = Data.Height_
- Data.Height_ = nil
- end
- if Data.Width_ then
- Data.Width = Data.Width_
- Data.Width_ = nil
- end
- if Data.ColorMode_ then
- Data.ColorMode = Data.ColorMode_
- Data.ColorMode_ = nil
- NetBuffer[#NetBuffer+1] = { NET_DATA_COLORMODE, Data.ColorMode}
- end
- Data.Map = {}
- NetBuffer[#NetBuffer+1] = { NET_DATA_CLEAR }
- end
- end)
- local function _resendAllData ()
- NetBuffer[#NetBuffer+1] = { NET_DATA_CLEAR }
- print "i am alive"
- for i = 1, Data.Width * Data.Height do
- sendDraw( i - 1, Data.Map[i] )
- if not checkQ( 0.95 ) then
- coroutine.yield()
- end
- end
- end
- local resendAllData = false
- local function DS_think ()
- if not checkQ( 0.1 ) then return end
- if resendAllData then
- coroutine.resume( resendAllData )
- local status = coroutine.status( resendAllData )
- if status == "running" then
- return
- else
- resendAllData = false
- end
- end
- if not Data.dat and #NetBuffer > 0 then
- local buffer = {}
- local c = math.min( #NetBuffer, 200 )
- while c > 0 do
- c = c - 1
- buffer[#buffer+1] = table.remove( NetBuffer, 1 )
- end
- Data.dat = fastlz.compress( von.serialize( buffer ) )
- end
- if Data.dat and net.getBytesLeft() > Data.dat:len() * 1.2 then
- -- print( Data.dat:len(), net.getBytesLeft() )
- net.start('DS_net_' .. Screen_ID)
- net.writeData( Data.dat, Data.dat:len() )
- net.send()
- Data.dat = nil
- end
- end
- local _Refresh = 0
- local function DS_input ( inputName, value )
- if not checkQ( 0.95 ) then return end
- if inputName == "Refresh" and _Refresh ~= value then
- _Refresh = value
- if value >= 1 and not resendAllData then
- resendAllData = coroutine.create( _resendAllData )
- end
- end
- end
- hook.add('think', 'DS_think', DS_think)
- hook.add( "input", "DS_input", DS_input)
- elseif CLIENT then
- local DrawBuffer = {}
- local A = true
- hook.add('net', 'DS_net', function(name, len, ply)
- if name == 'DS_net_' .. Screen_ID then
- local str = net.readData( len )
- local buffer = von.deserialize( fastlz.decompress( str ) )
- for _, v in pairs(buffer) do
- DrawBuffer[#DrawBuffer+1] = v
- end
- end
- end)
- local first = true
- hook.add('render', 'DS_render_', function(data)
- if first then
- first = false
- render.createRenderTarget( "ds_rt" )
- render.selectRenderTarget( "ds_rt" )
- render.clear()
- end
- render.selectRenderTarget( nil )
- render.setRenderTargetTexture( "ds_rt" )
- render.drawTexturedRect( 0, 0, 512, 512 )
- while #DrawBuffer > 0 do
- render.selectRenderTarget( "ds_rt" )
- local chunk = table.remove(DrawBuffer, 1)
- if chunk[1] == NET_DATA_CLEAR then
- render.clear( Color( 0,0,0,255 ) )
- elseif chunk[1] == NET_DATA_COLORMODE then
- Data.ColorMode = chunk[2]
- elseif chunk[1] == NET_DATA_DRAW then
- local x, y = chunk[2], chunk[3]
- local w, h = chunk[4], chunk[5]
- if Data.ColorMode == 0 then
- render.setRGBA(chunk[6],chunk[6],chunk[6],255)
- else
- render.setRGBA(chunk[6],chunk[7],chunk[8],255)
- end
- render.drawRect( x, y, w, h )
- end
- end
- end)
- end
Advertisement
Add Comment
Please, Sign In to add comment