Add "sendregion" command to GPU

This allows part of a buffer to be sent instead of the whole thing, meaning that driving digiscreen arrays can now be done with fewer commands and no temporary buffers.
This also greatly improves the speed of doing so, and I suppose also allows hardware-accelerated scrolling if your display is smaller than 64x64...
This commit is contained in:
cheapie 2021-02-21 14:45:08 -06:00
parent f62c9932b4
commit a5ca8f19b7
2 changed files with 41 additions and 0 deletions

@ -12,6 +12,7 @@ Example:
{command="send",buffer=0,channel="example"} {command="send",buffer=0,channel="example"}
} }
Invalid commands or commands with missing/invalid parameters will be ignored.
Command: createbuffer Command: createbuffer
--------------------- ---------------------
@ -33,6 +34,19 @@ Parameters:
buffer [integer 0-7]: The buffer to send the contents of. buffer [integer 0-7]: The buffer to send the contents of.
channel [string]: The digilines channel to send the message on. channel [string]: The digilines channel to send the message on.
Command: sendregion
-------------------
Sends part of the contents of a buffer to a digiscreen, rgblightstone panel, or other digilines device.
Parameters:
buffer [integer 0-7]: The buffer to send part of the contents of.
channel [string]: The digilines channel to send the message on.
x1 [integer 1-64]: The X position of the left side of the region to send.
x2 [integer 1-64]: The X position of the right side of the region to send.
y1 [integer 1-64]: The Y position of the top side of the region to send.
y2 [integer 1-64]: The Y position of the bottom side of the region to send.
Command: drawrect Command: drawrect
----------------- -----------------

27
gpu.lua

@ -201,6 +201,33 @@ local function runcommand(pos,meta,command)
if type(buffer) == "table" then if type(buffer) == "table" then
digiline:receptor_send(pos,digiline.rules.default,command.channel,buffer) digiline:receptor_send(pos,digiline.rules.default,command.channel,buffer)
end end
elseif command.command == "sendregion" then
if type(command.buffer) ~= "number" or type(command.channel) ~= "string" then return end
local bufnum = math.floor(command.buffer)
if bufnum < 0 or bufnum > 7 then return end
local buffer = meta:get_string("buffer"..bufnum)
if string.len(buffer) == 0 then return end
buffer = minetest.deserialize(buffer)
if type(buffer) ~= "table" then return end
if type(command.x1) ~= "number" or type(command.x2) ~= "number" or type(command.y1) ~= "number" or type(command.x2) ~= "number" then return end
local x1 = math.min(64,math.floor(command.x1))
local y1 = math.min(64,math.floor(command.y1))
local x2 = math.min(64,math.floor(command.x2))
local y2 = math.min(64,math.floor(command.y2))
if x1 < 1 or y1 < 1 or x2 < 1 or y2 < 1 then return end
x2 = math.min(x2,buffer.xsize)
y2 = math.min(y2,buffer.ysize)
if x1 > x2 or y1 > y2 then return end
local tempbuf = {}
for y=y1,y2,1 do
local dsty = y-y1+1
tempbuf[dsty] = {}
for x=x1,x2,1 do
local dstx = x-x1+1
tempbuf[dsty][dstx] = buffer[y][x]
end
end
digiline:receptor_send(pos,digiline.rules.default,command.channel,tempbuf)
elseif command.command == "drawrect" then elseif command.command == "drawrect" then
if type(command.buffer) ~= "number" or type(command.x1) ~= "number" or type(command.y1) ~= "number" or type(command.x2) ~= "number" or type(command.y2) ~= "number" then return end if type(command.buffer) ~= "number" or type(command.x1) ~= "number" or type(command.y1) ~= "number" or type(command.x2) ~= "number" or type(command.y2) ~= "number" then return end
local bufnum = math.floor(command.buffer) local bufnum = math.floor(command.buffer)