mirror of
https://github.com/mt-mods/led_marquee.git
synced 2025-06-28 22:36:41 +02:00
Compare commits
11 Commits
20180815-4
...
2018-08-16
Author | SHA1 | Date | |
---|---|---|---|
b9a0656407 | |||
4bb68ec009 | |||
161623e869 | |||
d182766236 | |||
09e5607d7a | |||
b9dd38c0de | |||
4fa6d54a4b | |||
157e517663 | |||
e622f94dfc | |||
be7f72dfeb | |||
b33de7a530 |
22
README.md
22
README.md
@ -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.
|
||||
|
||||
The string is padded with spaces and then trimmed to 64 characters.
|
||||
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).
|
||||
|
||||
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.
|
||||
|
||||
@ -40,16 +50,20 @@ The panels also respond to these control messages:
|
||||
* "off_multi" turns all panels in a lineup off
|
||||
* "allon_multi" turns on all LEDs of all panels in a lineup.
|
||||
|
||||
A byte value of 0 to 30 will change colors (i.e. string.char(0 to 30) ). Color values 0 to 11 are:
|
||||
A byte value of 0 to 27 will change colors (i.e. string.char(0 to 27) ). Color values 0 to 11 are:
|
||||
|
||||
Red (0), orange, yellow, lime, green, aqua, cyan, sky blue, blue, violet, magenta, or red-violet (11)
|
||||
|
||||
Colors 12 to 23 are the same as 0 to 11, but lower brightness.
|
||||
|
||||
Colors 23 - 30 are white, light grey, medium grey, dim grey, light blue, brown, and pink.
|
||||
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.
|
||||
|
118
init.lua
118
init.lua
@ -1,11 +1,9 @@
|
||||
-- simple LED marquee mod
|
||||
-- by Vanessa Dannenberg
|
||||
|
||||
led_marquee = {}
|
||||
|
||||
local S
|
||||
if minetest.get_modpath("intllib") then
|
||||
S = intllib.Getter()
|
||||
S = intllib.make_gettext_pair()
|
||||
else
|
||||
S = function(s) return s end
|
||||
end
|
||||
@ -44,41 +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)
|
||||
local fdir = minetest.get_node(pos).param2 % 8
|
||||
local pos2 = pos
|
||||
local mastermeta = minetest.get_meta(pos)
|
||||
local lastcolor = mastermeta:get_int("lastcolor")
|
||||
if not lastcolor or lastcolor < 0 or lastcolor > 30 then
|
||||
lastcolor = 0
|
||||
mastermeta:set_int("lastcolor", 0)
|
||||
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 = 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 (node.param2 % 8) == fdir and asc > 30 and asc < 256 then
|
||||
minetest.swap_node(pos2, { name = "led_marquee:char_"..asc, param2 = (node.param2 % 8) + (lastcolor*8)})
|
||||
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]
|
||||
elseif asc < 31 then
|
||||
lastcolor = asc
|
||||
mastermeta:set_int("lastcolor", asc)
|
||||
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
|
||||
@ -86,37 +111,38 @@ end
|
||||
local on_digiline_receive_string = function(pos, node, channel, msg)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local setchan = meta:get_string("channel")
|
||||
local lastcolor = meta:get_int("lastcolor")
|
||||
if not lastcolor or lastcolor < 0 or lastcolor > 30 then
|
||||
lastcolor = 0
|
||||
meta:set_int("lastcolor", 0)
|
||||
local last_color = meta:get_int("last_color")
|
||||
if not last_color or last_color < 0 or last_color > 27 then
|
||||
last_color = 0
|
||||
meta:set_int("last_color", 0)
|
||||
end
|
||||
local fdir = node.param2 % 8
|
||||
|
||||
if setchan ~= channel then return end
|
||||
if msg and msg ~= "" and type(msg) == "string" then
|
||||
if string.len(msg) > 1 then
|
||||
if msg == "off" then
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_32", param2 = (node.param2 % 8) + (lastcolor*8)})
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_32", param2 = fdir + (last_color*8)})
|
||||
elseif msg == "colon" then
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_58", param2 = (node.param2 % 8) + (lastcolor*8)})
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_58", param2 = fdir + (last_color*8)})
|
||||
elseif msg == "period" then
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_46", param2 = (node.param2 % 8) + (lastcolor*8)})
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_46", param2 = fdir + (last_color*8)})
|
||||
elseif msg == "del" then
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_127", param2 = (node.param2 % 8) + (lastcolor*8)})
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_127", param2 = fdir + (last_color*8)})
|
||||
elseif msg == "allon" then
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_144", param2 = (node.param2 % 8) + (lastcolor*8)})
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_144", param2 = fdir + (last_color*8)})
|
||||
elseif msg == "cursor" then
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_31", param2 = (node.param2 % 8) + (lastcolor*8)})
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_31", param2 = fdir + (last_color*8)})
|
||||
else
|
||||
display_string(pos, channel, msg)
|
||||
end
|
||||
else
|
||||
local asc = string.byte(msg)
|
||||
if asc > 30 and asc < 256 then
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_"..asc, param2 = (node.param2 % 8) + (lastcolor*8)})
|
||||
elseif asc < 31 then
|
||||
lastcolor = asc
|
||||
meta:set_int("lastcolor", asc)
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_"..asc, param2 = fdir + (last_color*8)})
|
||||
elseif asc < 28 then
|
||||
last_color = asc
|
||||
meta:set_int("last_color", asc)
|
||||
elseif msg == "get" then -- get value as ASCII numerical value
|
||||
digiline:receptor_send(pos, digiline.rules.default, channel, tonumber(string.match(minetest.get_node(pos).name,"led_marquee:char_(.+)"))) -- wonderfully horrible string manipulaiton
|
||||
elseif msg == "getstr" then -- get actual char
|
||||
@ -125,9 +151,9 @@ local on_digiline_receive_string = function(pos, node, channel, msg)
|
||||
end
|
||||
elseif msg and type(msg) == "number" then
|
||||
if msg == 0 then
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_32", param2 = (node.param2 % 8) + (lastcolor*8)})
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_32", param2 = fdir + (last_color*8)})
|
||||
elseif msg > 30 then
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_"..tostring(msg), param2 = (node.param2 % 8) + (lastcolor*8)})
|
||||
minetest.swap_node(pos, { name = "led_marquee:char_"..tostring(msg), param2 = fdir + (last_color*8)})
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -164,7 +190,7 @@ for i = 31, 255 do
|
||||
drawtype = "mesh",
|
||||
mesh = "led_marquee.obj",
|
||||
tiles = tiles,
|
||||
palette="palette.png",
|
||||
palette="led_marquee_palette.png",
|
||||
use_texture_alpha = true,
|
||||
groups = groups,
|
||||
paramtype = "light",
|
||||
|
Binary file not shown.
Binary file not shown.
@ -25,12 +25,7 @@ v 0.500000 -0.449125 -0.468750
|
||||
v -0.500000 -0.449125 -0.468750
|
||||
v -0.500000 -0.449125 0.468750
|
||||
v 0.500000 -0.449125 0.468750
|
||||
vt 0.667843 0.000000
|
||||
vt 0.667843 0.015513
|
||||
vt 0.681855 0.031026
|
||||
vt 0.681855 0.961799
|
||||
vt 0.667843 0.977312
|
||||
vt 0.667843 0.992824
|
||||
vt 0.723891 0.992824
|
||||
vt 0.723891 0.000000
|
||||
vt 1.000000 0.007175
|
||||
@ -39,32 +34,37 @@ vt 0.103234 1.000000
|
||||
vt 0.103234 0.007175
|
||||
vt 0.723891 0.000000
|
||||
vt 0.723891 0.992824
|
||||
vt 0.667843 0.992824
|
||||
vt 0.667843 0.977312
|
||||
vt 0.681855 0.961799
|
||||
vt 0.681855 0.031026
|
||||
vt 0.003280 0.226388
|
||||
vt 0.900045 0.226388
|
||||
vt 0.900045 0.164337
|
||||
vt 0.003280 0.164337
|
||||
vt 0.900045 0.226388
|
||||
vt 0.003280 0.226388
|
||||
vt 0.003280 0.164337
|
||||
vt 0.900045 0.164337
|
||||
vt 1.000000 0.017400
|
||||
vt 0.000000 -0.000000
|
||||
vt 1.000000 -0.000000
|
||||
vt 1.000000 1.000000
|
||||
vt 0.000000 0.982506
|
||||
vt 1.000000 0.982506
|
||||
vt 0.000000 0.965011
|
||||
vt 0.000000 0.034801
|
||||
vt 1.000000 0.034801
|
||||
vt 0.667843 0.992824
|
||||
vt 0.681855 0.961799
|
||||
vt 0.667843 0.977312
|
||||
vt 0.667843 0.015513
|
||||
vt 0.667843 0.000000
|
||||
vt 0.003280 0.226388
|
||||
vt 0.900045 0.226388
|
||||
vt 0.900045 0.164337
|
||||
vt 0.003280 0.164337
|
||||
vt 0.900045 0.226388
|
||||
vt 0.003280 0.226388
|
||||
vt 0.003280 0.164337
|
||||
vt 0.900045 0.164337
|
||||
vt 1.000000 -0.000000
|
||||
vt 1.000000 0.017400
|
||||
vt 0.667843 0.000000
|
||||
vt 0.681855 0.031026
|
||||
vt 0.667843 0.015513
|
||||
vt 0.667843 0.977312
|
||||
vt 0.667843 0.992824
|
||||
vt 0.000000 0.017400
|
||||
vt 0.000000 -0.000000
|
||||
vt 1.000000 0.982506
|
||||
vt 1.000000 1.000000
|
||||
vt 0.000000 1.000000
|
||||
vt 0.000000 0.982506
|
||||
vt 0.000000 0.965011
|
||||
vt 1.000000 0.965011
|
||||
vt 1.000000 0.034801
|
||||
vt 0.000000 0.034801
|
||||
vt 0.000000 0.000000
|
||||
vt 1.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
@ -73,25 +73,39 @@ vt 0.000000 0.000000
|
||||
vt 1.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
vt 0.000000 1.000000
|
||||
vn 1.0000 0.0000 -0.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn -0.0000 -0.0000 -1.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn -0.0000 0.0000 1.0000
|
||||
vn -0.0000 1.0000 0.0000
|
||||
vn -0.0000 0.7071 -0.7071
|
||||
vn -0.0000 0.7071 0.7071
|
||||
g Cube_Cube_LEDs_Cube_Cube_LEDs_base
|
||||
s off
|
||||
f 5/1/1 6/2/1 7/3/1 8/4/1 9/5/1 10/6/1 11/7/1 12/8/1
|
||||
f 12/9/2 11/10/2 13/11/2 14/12/2
|
||||
f 14/13/3 13/14/3 15/15/3 16/16/3 17/17/3 18/18/3 19/19/3 20/20/3
|
||||
f 12/21/4 14/22/4 20/23/4 5/24/4
|
||||
f 13/25/5 11/26/5 10/27/5 15/28/5
|
||||
f 20/29/6 19/30/6 6/31/6 5/32/6
|
||||
f 16/33/6 15/34/6 10/35/6 9/36/6
|
||||
f 9/36/7 8/37/7 17/38/7 16/33/7
|
||||
f 18/39/8 7/40/8 6/31/8 19/30/8
|
||||
f 8/1/1 11/2/1 12/3/1
|
||||
f 12/4/2 11/5/2 13/6/2 14/7/2
|
||||
f 14/8/3 13/9/3 18/10/3
|
||||
f 12/11/4 14/12/4 20/13/4 5/14/4
|
||||
f 13/15/5 11/16/5 10/17/5 15/18/5
|
||||
f 19/19/6 5/20/6 20/21/6
|
||||
f 15/22/6 9/23/6 16/24/6
|
||||
f 8/25/7 16/24/7 9/23/7
|
||||
f 7/26/8 19/19/8 18/27/8
|
||||
f 13/9/3 15/28/3 17/29/3
|
||||
f 15/28/3 16/30/3 17/29/3
|
||||
f 19/31/3 20/32/3 18/10/3
|
||||
f 20/32/3 14/8/3 18/10/3
|
||||
f 13/9/3 17/29/3 18/10/3
|
||||
f 12/3/1 5/33/1 7/34/1
|
||||
f 5/33/1 6/35/1 7/34/1
|
||||
f 9/36/1 10/37/1 8/1/1
|
||||
f 10/37/1 11/2/1 8/1/1
|
||||
f 12/3/1 7/34/1 8/1/1
|
||||
f 7/26/8 6/38/8 19/19/8
|
||||
f 19/19/6 6/38/6 5/20/6
|
||||
f 15/22/6 10/39/6 9/23/6
|
||||
f 8/25/7 17/40/7 16/24/7
|
||||
g Cube_Cube_LEDs_Cube_Cube_LEDs_leds_off
|
||||
f 1/41/6 2/42/6 3/43/6 4/44/6
|
||||
g Cube_Cube_LEDs_Cube_Cube_LEDs_leds_on
|
||||
|
BIN
textures/led_marquee_palette.png
Normal file
BIN
textures/led_marquee_palette.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 120 B |
Binary file not shown.
Before Width: | Height: | Size: 131 B |
Reference in New Issue
Block a user