1
0
mirror of https://github.com/mt-mods/led_marquee.git synced 2025-06-28 22:36:41 +02:00

2 Commits

Author SHA1 Message Date
b9a0656407 Added a "cursor position" command byte
updated README
2018-08-16 02:25:31 -04:00
4bb68ec009 basic multi-line support
Stack up a wall of LED panels, any horizontal and vertical amount

Set a channel on the upper left panel, leave the others un-set, and
connect a LuaC to it via digilines.

Long strings sent to that channel will be displayed using all panels,
starting at the upper-left and working from left to right, top to
bottom, wrapping from line to line as appropriate (similar to printing
to a shell terminal).

string.char(28) can be inserted anywhere to force a linefeed.

As usual, printing continues from node to node until the program either
finds a panel with a different non-empty channel than the first one, or
it finds a panel that's facing the wrong way.

If the program finds something other than a panel, it wraps to the next
line.  If it finds something other than a panel twice in a row, that
signals that text has wrapped off of the last row, and printing is cut
off.

Lines of panels don't need to be the same length, the program will wrap
as needed.

This commit also gets rid of the end-of-line padding, uses proper
string.rep() to create the all-off and all-on fills (each of which is
1kB), and fixes one or two other minor issues.

Strings are trimmed to 1 kB.

Panels are not erased between prints.
2018-08-16 01:46:03 -04:00
2 changed files with 58 additions and 19 deletions

View File

@ -16,9 +16,19 @@ The string will spread down the line until either a panel is found that faces th
Panels to the left of the connected one are ignored (unless they, too, have their own connections).
You can put multiple lines of panels end to end to form independent displays, so long as the panels that start each of the lines have unique channel names set.
You can also stack up a wall of LED panels, of any horizontal and vertical amount. If you then set a channel on the upper left panel, leave the others un-set, and connect a LuaController to it via digilines, the whole wall of panels will be treated as a multi-line display.
Long strings sent to that channel will be displayed starting at the upper-left and working from left to right, top to bottom, wrapping from line to line as appropriate (similar to printing to a shell terminal).
The string is padded with spaces and then trimmed to 64 characters.
As with a single line, printing continues from node to node until the program either finds a panel with a different non-empty channel than the first one, or if it finds a panel that's facing the wrong way.
If the program finds something other than a panel, it wraps to the next line. If it finds something other than a panel twice in a row, that signals that text has wrapped off of the last row, and printing is cut off.
Lines of panels don't need to be all the same length, the program will wrap as needed, with the left margin always being aligned with the panel the LuaController is connected to.
Strings are trimmed to 1 kB.
Panels are not erased between prints.
Any unrecognized symbol or character, whether part of a string or singularly is ignored, except as noted below.
@ -50,6 +60,10 @@ Colors 24 - 27 are white, light grey, medium grey, and dim grey.
The left-most/"master" panel will remember the last color used, and defaults to red.
A byte value of 28 will act as a line feed (I would have used 10, but that's a color code :-P )
A byte value of 29 signals a cursor position command. The next two byte values select a column and row, respectively. The next character after the row byte will be printed there, and the rest of the string then continues printing from that spot onwards.
You can use "get" and "getstr" to read the one character from the connected panel. These messages will not read the other panels in the lineup.
All panels emit a small amount of light when displaying something.

View File

@ -42,43 +42,68 @@ local cbox = {
wall_side = { -8/16, -8/16, -8/16, -7/16, 8/16, 8/16 }
}
local padding = " "
local allon = string.char(128)
for i = 1, 64 do
padding = padding.." "
allon = allon..string.char(144)
end
local display_string = function(pos, channel, string)
if string == "off_multi" then
string = ""
string = string.rep(" ", 1024)
elseif string == "allon_multi" then
string = allon
string = string.rep(string.char(144), 1024)
end
local padded_string = string.sub(string..padding, 1, 64)
string = string.sub(string, 1, 1024)
local master_fdir = minetest.get_node(pos).param2 % 8
local master_meta = minetest.get_meta(pos)
local last_color = master_meta:get_int("last_color")
local pos2 = pos
local pos2 = table.copy(pos)
if not last_color or last_color < 0 or last_color > 27 then
last_color = 0
master_meta:set_int("last_color", 0)
end
for i = 1, 64 do
local i = 1
local len = string.len(string)
local wrapped = nil
while i <= len do
local node = minetest.get_node(pos2)
local fdir = node.param2 % 8
local meta = minetest.get_meta(pos2)
local setchan = meta:get_string("channel")
if not string.match(node.name, "led_marquee:char_") or (setchan ~= nil and setchan ~= "" and setchan ~= channel) then break end
local asc = string.byte(padded_string, i, i)
if master_fdir == fdir and asc > 30 and asc < 256 then
local setchan = nil
if meta then setchan = meta:get_string("channel") end
local asc = string.byte(string, i, i)
if not string.match(node.name, "led_marquee:char_") then
if not wrapped then
pos2.x = pos.x
pos2.y = pos2.y-1
pos2.z = pos.z
wrapped = true
else
break
end
elseif string.match(node.name, "led_marquee:char_")
and fdir ~= master_fdir or (setchan ~= nil and setchan ~= "" and setchan ~= channel) then
break
elseif asc == 28 then
pos2.x = pos.x
pos2.y = pos2.y-1
pos2.z = pos.z
i = i + 1
wrapped = nil
elseif asc == 29 then
local c = string.byte(string, i+1, i+1) or 0
local r = string.byte(string, i+2, i+2) or 0
pos2.x = pos.x + (fdir_to_right[fdir+1][1])*c
pos2.y = pos.y - r
pos2.z = pos.z + (fdir_to_right[fdir+1][2])*c
i = i + 3
wrapped = nil
elseif asc > 30 and asc < 256 then
minetest.swap_node(pos2, { name = "led_marquee:char_"..asc, param2 = master_fdir + (last_color*8)})
pos2.x = pos2.x + fdir_to_right[fdir+1][1]
pos2.z = pos2.z + fdir_to_right[fdir+1][2]
i = i + 1
wrapped = nil
elseif asc < 28 then
last_color = asc
master_meta:set_int("last_color", asc)
i = i + 1
wrapped = nil
end
end
end