Compare commits

...

78 Commits

Author SHA1 Message Date
Luke aka SwissalpS 528d8b7a58
not ground content (#4) 2024-02-26 15:01:42 +01:00
Niklp 0f0f74a3e5
Fix settings file format (#3) 2023-08-13 18:04:51 +10:00
Niklp 0cc8f9e7a4
Maintenance + translation support (#2)
* maintenance + translation support

* fix too long line warning

* improvements through code review
2023-07-05 13:55:41 +02:00
Niklp 4732886317
maintenance (#1) 2022-07-24 10:28:24 -04:00
Vanessa Dannenberg 2bf2651cee Merge branch 'BuckarooBanzai-master-patch-93143' into 'master'
check proper `asc` range in digilines events too

See merge request VanessaE/led_marquee!7
2021-03-15 14:38:12 +00:00
Buckaroo Banzai aafa748f92 check proper `asc` range in digilines events too
fixes https://github.com/pandorabox-io/pandorabox.io/issues/629
2021-03-15 08:44:32 +00:00
Vanessa Dannenberg 39f571f788 Merge branch 'master' into 'master'
Fix deprecated use of use_texture_alpha

See merge request VanessaE/led_marquee!6
2021-02-27 05:14:01 +00:00
Sys Quatre 108f0dad1a Fix deprecated use of use_texture_alpha 2021-02-27 01:46:36 +01:00
Vanessa Dannenberg 63de1f5ab5 Don't allow engine to add the implicit "Proceed" button
(this change makes it possible to theme the formspec)
2021-02-25 02:08:22 -05:00
Vanessa Dannenberg 642aec419a Merge branch 'master' into 'master'
fix crash when "scroll_speed" is not a number

See merge request VanessaE/led_marquee!5
2020-09-09 10:29:17 +00:00
OgelGames caf6e24d04 fix crash when "scroll_speed" is not a number 2020-09-09 19:22:14 +10:00
VanessaE 31a938693a add minimum minetest version key for contentdb 2020-06-03 13:00:22 -04:00
Vanessa Dannenberg 45c89704f0 Add lag mitigation
All messages sent to the displays are firstr enqueued, then "played
back" on globalstep, similar to biome_lib's deferred-generation method.

By default, no more than 10 messages will be added to the queue.  If the
queue should exceed that, old messages will be deleted to make room for
new messages.

Messages will be pulled from the queue, one item per server tick, in the
order received, and relayed to their displays, if dtime <= 0.2s.  If
dtime is greater, messages will be withheld until it decreases.

Autoscroll now limits the speed to 0.5s per step.
2019-08-21 19:34:07 -04:00
Vanessa Dannenberg 8d3a0e92de Merge branch 'bad_unicode' into 'master'
add check to prevent bad unicode from crashing the server

See merge request VanessaE/led_marquee!4
2019-07-06 02:17:06 +00:00
flux db78e3dcdb add check to prevent bad unicode from crashing the server 2019-07-06 02:17:06 +00:00
Vanessa Dannenberg da1deecb4c use masking:
glyph images are now used as masks over the "leds_on" image
instead of the glyphs themselves looking like they're made of LEDs.

Makes font files much simpler, easier to draw, makes LEDs easier
to re-texture.

White for "on" LEDs, black for "off"

Also optimized all images (optipng, pngcrush)
2019-05-25 03:52:00 -04:00
Vanessa Dannenberg df30ce9477 Use hardware overlay instead of an extra face
to display the LEDs, gets rid of Z fighting due
to Irrlicht rounding errors
2019-05-25 03:00:14 -04:00
Vanessa Dannenberg b2defa0eec Merge branch 'master' into 'master'
Added protection to marquee channel setup formspec

See merge request VanessaE/led_marquee!3
2019-03-24 19:44:27 +00:00
Emiel van Rooijen 4880b5c0c3 Added protection to marquee channel setup formspec 2019-03-24 19:58:23 +01:00
Vanessa Dannenberg 114856e529 license fixups: use LGPL3.0 for code, CC-by-SA 4.0 for media 2018-11-08 18:30:35 -05:00
Vanessa Dannenberg 589ab5f19a don't reset scroll position if re-printing the same message 2018-08-22 18:40:58 -04:00
Vanessa Dannenberg bbb2b57328 fix shifted block shades (char 143, 144) 2018-08-21 21:14:27 -04:00
Vanessa Dannenberg 1b2e898615 remove debug prints 2018-08-21 05:48:41 -04:00
Vanessa Dannenberg 2d74ccf8e6 fix the fix ;) 2018-08-21 04:59:58 -04:00
Vanessa Dannenberg 3f98601875 fix glitch where first byte of msg gets skipped on scroll
(causes color code to be displayed raw)
2018-08-21 04:47:00 -04:00
Vanessa Dannenberg cf94878a46 consolidate timer sanity checking into led_marquee.set_timer 2018-08-21 04:22:22 -04:00
Vanessa Dannenberg 0bc150e64a reduce allowed minimum timeout to 0.2s 2018-08-21 04:15:37 -04:00
Vanessa Dannenberg f9f68d13ab better centering for k 2018-08-21 01:35:45 -04:00
Vanessa Dannenberg ddfed65b2a better centering for y ÿ ý 2018-08-21 01:30:48 -04:00
Vanessa Dannenberg 85fd214907 better shape for "Ý" 2018-08-21 01:26:34 -04:00
Vanessa Dannenberg 4658f9eeff better ring on "Å" 2018-08-21 01:03:10 -04:00
Vanessa Dannenberg 57cdabac78 better circumflexes
characters Â Ê Î Ô Û â ê î ô û
2018-08-21 00:59:48 -04:00
Vanessa Dannenberg 07f41b13d8 fix height of "Ø"
(capital O with stroke, char #216)
2018-08-21 00:39:18 -04:00
Vanessa Dannenberg 9ca24f1f10 fix width of "L" 2018-08-21 00:37:51 -04:00
Vanessa Dannenberg 45ec33e78c fix string length limits in README 2018-08-21 00:29:27 -04:00
Vanessa Dannenberg f5512c4837 wield image 2018-08-21 00:27:07 -04:00
Vanessa Dannenberg f7155b385e don't forget to increment the string index for unrecognized chars 2018-08-20 21:33:04 -04:00
Vanessa Dannenberg 4c804e1851 forgot to lowercase chars in color codes table 2018-08-20 20:58:10 -04:00
Vanessa Dannenberg 87ebd877b8 update README accordingly 2018-08-20 20:34:36 -04:00
Vanessa Dannenberg 3ba2dbd1bd use string.char(10) for newline, like it should be
(since colors are now strings)
2018-08-20 20:25:44 -04:00
Vanessa Dannenberg 452102cc7c use printable strings for color codes
instead of string.char(0-27), use "/" as an escape followed by
"[0-9][A-R][a-r]", all inside the string.

e.g. digiline_send("chan", "/0this /1is /2some /3colorful /4text")

"/" followed by any other character than the above will be treated as an
invalid color code and will be taken literally.

"//" will print a single slash.

Note: on receipt, all instances of "//" in a message are actually
translated to string.char(30) -- one for each pair.  This makes the
scrolling code easier.  Keep this in mind if you use the "getstr" and
"getindex" commands.

Also, this expands the max string length to 6 kB, to allow a full 80x25
display with one color code er character.  "clear" and "allon" remain at
2kB since that's still enough.
2018-08-20 20:24:31 -04:00
Vanessa Dannenberg bee8d5c32d increase string limit to 4 kB
(also pad "clear" and "allon" strings to 2 kB)
2018-08-19 02:06:00 -04:00
Vanessa Dannenberg 5cf5e0318a documentation fixes 2018-08-17 18:20:41 -04:00
Vanessa Dannenberg 65a22e1c8e drop support for "off_multi" (just use "clear")
renamed "allon_multi" to "allon"
2018-08-17 17:14:55 -04:00
Vanessa Dannenberg c703dbfa74 add optional stepping value to "scroll_step" 2018-08-17 17:12:49 -04:00
Vanessa Dannenberg 0cacd9af9c fix fencepost error 2018-08-17 15:43:41 -04:00
Vanessa Dannenberg 06b419a905 track colors properly in scrolling text
(also fixes timing glitches)
2018-08-17 15:24:21 -04:00
Vanessa Dannenberg 010dab660b don't reset index to 1 on timer-start
(that's handled elsewhere)

also, pre-increment the index so that it matches what's displayed
2018-08-17 11:42:16 -04:00
Vanessa Dannenberg 5826209f16 always reset the scroll index to 1 on any new displayed message 2018-08-17 11:20:49 -04:00
Vanessa Dannenberg b25b3ef995 use proper form of digilines.receptor_send() 2018-08-17 11:17:27 -04:00
Vanessa Dannenberg b8a0f1cbb7 fix getindex 2018-08-17 11:03:07 -04:00
Vanessa Dannenberg 3d5380ef25 only reset the scroll index when starting the timer
(not when stopping it)
2018-08-17 10:48:33 -04:00
Vanessa Dannenberg 3df1e6454b add "getindex" command to read the stored message's scroll index position
that is, the string index position of the first displayed character thereof.
2018-08-17 10:46:49 -04:00
Vanessa Dannenberg e8c0fa93ca more clarifications 2018-08-17 10:44:13 -04:00
Vanessa Dannenberg ab0582ff97 update README accordingly 2018-08-17 10:39:20 -04:00
Vanessa Dannenberg 4af469f1aa check for "get" and "get_string" in the right place :-P 2018-08-17 10:36:20 -04:00
Vanessa Dannenberg d9499481cf clarify "get" command 2018-08-17 10:34:40 -04:00
Vanessa Dannenberg 1823b6f0e5 get_str will now get the last displayed string from the master's meta
(instead of only the first char)
2018-08-17 10:33:48 -04:00
Vanessa Dannenberg 02216ee611 store single-byte messages in the meta also 2018-08-17 10:29:10 -04:00
Vanessa Dannenberg 10dcad8e06 store numeric message as a string in the master's meta 2018-08-17 10:27:27 -04:00
Vanessa Dannenberg 898a027a77 numeric messages are now printed in full
instead of just the first char.
2018-08-17 10:25:12 -04:00
Vanessa Dannenberg 922efe9210 clarify README regarding scrolling
also make sure to `return false` from the scroll_text function if the
scroll timer was last set to a value below the allowed minimum (which
would mean the user/program intended to shut it off by setting it to 0,
or the stepper was called manually, implying no timer)
2018-08-17 10:12:35 -04:00
Vanessa Dannenberg 81a06dc054 add a command to immediately scroll the displayed message by one step
to be used in lieu of the three existing auto-scroll commands in case
you want the LuaC to handle the stepping.
2018-08-17 09:49:26 -04:00
Vanessa Dannenberg d47f2746d7 Merge branch '138-fix' into 'master'
Rotate char 138 correctly

See merge request VanessaE/led_marquee!2
2018-08-17 12:45:33 +00:00
Thomas--S 68b748a741 Rotate char 138 correctly 2018-08-17 09:09:08 +02:00
Vanessa Dannenberg 3cee6172ae brain-o 2018-08-17 00:49:18 -04:00
Vanessa Dannenberg 0db84edb1e more documentation tweaks 2018-08-17 00:05:08 -04:00
Vanessa Dannenberg 81a52b2e0f update README to follow those commits 2018-08-17 00:00:24 -04:00
Vanessa Dannenberg 053ee765c0 drop support for "off", "colon", "period", "del", "all_on" and "cursor" keywords
(use the actuall ascii chars instead, they do the same thing anyways, but can be part of a string)
2018-08-16 23:50:26 -04:00
Vanessa Dannenberg 57d4c99eb8 add "clear" as more readable an alternate to "off_multi" 2018-08-16 23:41:40 -04:00
Vanessa Dannenberg 244b5011a1 move "allon_multi" and "off_multi" checks to main eval section 2018-08-16 23:40:35 -04:00
Vanessa Dannenberg 3141aa5ba7 basic automatic horizontal scrolling support 2018-08-16 23:35:51 -04:00
Vanessa Dannenberg c647effff2 make µC and lamps optional depends
(they're only needed for crafting anyways)
2018-08-16 16:50:41 -04:00
Vanessa Dannenberg ce9666cc48 local-ize functions 2018-08-16 13:22:02 -04:00
Vanessa Dannenberg 4d1d90cccc local-ize iso_chars 2018-08-16 13:21:28 -04:00
Vanessa Dannenberg 5ed4d1ef27 update README to follow 2018-08-16 13:20:26 -04:00
Vanessa Dannenberg ee77614b97 treat strings prefixed with 0xff as Lua's weird UTF-8 encoding
translate them to bare ISO-8859-1 at print time

Only alters chars with codes > 0x9f, so graphics/symbols in the
0x7f-0x9f range and color and control codes < 0x20 are preserved

The routine assumes that any char code > 0x9f is the first byte of a
two-byte UTF-8 symbol.

Note that due to Minetest's busted formspecs, it's not possible to
actually type-in or copy-paste proper UTF strings to take advantage of
this mode, so it's only useful if the strings are generated by or
imported in from something else (e.g. a URL or something, or a LuaC
program that generates strings)
2018-08-16 13:14:27 -04:00
Vanessa Dannenberg d0d127e837 rewrite README a bit, synchronize with forum post 2018-08-16 02:43:11 -04:00
245 changed files with 820 additions and 134 deletions

10
.github/workflows/luacheck.yml vendored Normal file
View File

@ -0,0 +1,10 @@
name: luacheck
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: Roang-zero1/factorio-mod-luacheck@master
with:
luacheckrc_url: ""

11
.luacheckrc Normal file
View File

@ -0,0 +1,11 @@
unused_args = false
read_globals = {
table = {fields = {"copy"}},
"minetest",
"digilines"
}
globals = {
"led_marquee"
}

445
LICENSE
View File

@ -1,15 +1,12 @@
(This file copied from Digilines mod)
License for code: LGPL 3.0
License for media and all other assets: CC-by-SA 4.0
The LGPLv3 applies to all code in this project.
The WTFPL applies to textures and any other content in this project which is
not source code.
###############################################################################
=============================================================
GNU LESSER GENERAL PUBLIC LICENSE
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@ -172,20 +169,432 @@ apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
###############################################################################
=============================================================
Attribution-ShareAlike 4.0 International
=======================================================================
Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are
intended for use by those authorized to give the public
permission to use material in ways otherwise restricted by
copyright and certain other rights. Our licenses are
irrevocable. Licensors should read and understand the terms
and conditions of the license they choose before applying it.
Licensors should also secure all rights necessary before
applying our licenses so that the public can reuse the
material as expected. Licensors should clearly mark any
material not subject to the license. This includes other CC-
licensed material, or material used under an exception or
limitation to copyright. More considerations for licensors:
wiki.creativecommons.org/Considerations_for_licensors
Considerations for the public: By using one of our public
licenses, a licensor grants the public permission to use the
licensed material under specified terms and conditions. If
the licensor's permission is not necessary for any reason--for
example, because of any applicable exception or limitation to
copyright--then that use is not regulated by the license. Our
licenses grant only permissions under copyright and certain
other rights that a licensor has authority to grant. Use of
the licensed material may still be restricted for other
reasons, including because others have copyright or other
rights in the material. A licensor may make special requests,
such as asking that all changes be marked or described.
Although not required by our licenses, you are encouraged to
respect those requests where reasonable. More considerations
for the public:
wiki.creativecommons.org/Considerations_for_licensees
=======================================================================
Creative Commons Attribution-ShareAlike 4.0 International Public
License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution-ShareAlike 4.0 International Public License ("Public
License"). To the extent this Public License may be interpreted as a
contract, You are granted the Licensed Rights in consideration of Your
acceptance of these terms and conditions, and the Licensor grants You
such rights in consideration of benefits the Licensor receives from
making the Licensed Material available under these terms and
conditions.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Section 1 -- Definitions.
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
b. Adapter's License means the license You apply to Your Copyright
and Similar Rights in Your contributions to Adapted Material in
accordance with the terms and conditions of this Public License.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
c. BY-SA Compatible License means a license listed at
creativecommons.org/compatiblelicenses, approved by Creative
Commons as essentially the equivalent of this Public License.
0. You just DO WHAT THE FUCK YOU WANT TO.
d. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
e. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
f. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
g. License Elements means the license attributes listed in the name
of a Creative Commons Public License. The License Elements of this
Public License are Attribution and ShareAlike.
h. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
i. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
j. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
k. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
l. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
m. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part; and
b. produce, reproduce, and Share Adapted Material.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. Additional offer from the Licensor -- Adapted Material.
Every recipient of Adapted Material from You
automatically receives an offer from the Licensor to
exercise the Licensed Rights in the Adapted Material
under the conditions of the Adapter's License You apply.
c. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified
form), You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
b. ShareAlike.
In addition to the conditions in Section 3(a), if You Share
Adapted Material You produce, the following conditions also apply.
1. The Adapter's License You apply must be a Creative Commons
license with the same License Elements, this version or
later, or a BY-SA Compatible License.
2. You must include the text of, or the URI or hyperlink to, the
Adapter's License You apply. You may satisfy this condition
in any reasonable manner based on the medium, means, and
context in which You Share Adapted Material.
3. You may not offer or impose any additional or different terms
or conditions on, or apply any Effective Technological
Measures to, Adapted Material that restrict exercise of the
rights granted under the Adapter's License You apply.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material,
including for purposes of Section 3(b); and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
=======================================================================
Creative Commons is not a party to its public
licenses. Notwithstanding, Creative Commons may elect to apply one of
its public licenses to material it publishes and in those instances
will be considered the “Licensor.” The text of the Creative Commons
public licenses is dedicated to the public domain under the CC0 Public
Domain Dedication. Except for the limited purpose of indicating that
material is shared under a Creative Commons public license or as
otherwise permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including,
without limitation, in connection with any unauthorized modifications
to any of its public licenses or any other arrangements,
understandings, or agreements concerning use of licensed material. For
the avoidance of doubt, this paragraph does not form part of the
public licenses.
Creative Commons may be contacted at creativecommons.org.

View File

@ -1,39 +1,37 @@
# LED marquee mod
*by Vanessa Dannenberg*
This mod provides set of alphanumeric LED marquee panels, controlled by Mesecons' Digilines mod.
Simply place a panel, right-click it, and set a channel.
Simply place one or more panels, and set a channel on just the left-most or upper-left one.
Then send a character, a string, or one of several control words to that channel from a Mesecons Lua Controller and the mod will try to display it. The panels use the standard 7-bit ASCII character set (with a few alterations).
Then send a character, a string, or one of several control words or codes to that channel from a Mesecons Lua Controller and the mod will try to display it.
A single character will be displayed on the connected panel. A numeric message (i.e. not a string) will display the first digit on the connected panel.
A single character will be displayed on the connected panel.
Strings will be displayed using all panels in a lineup, so long as they all face the same way, starting from the panel the Lua Controller is connected to, going left to right. The other panels in the line do not need to be connected to anything - think of them as being connected together internally. Only the panel at the far left need be connected to the Lua Controller.
A numeric message (i.e. not a string) will be converted into a string.
Strings of all types (other than the keywords below) will be displayed using all panels in a lineup, so long as they all face the same way, starting from the panel the Lua Controller is connected to, going left to right. The other panels in the line do not need to be connected to anything - think of them as being connected together internally. Only the panel at the far left need be connected to the Lua Controller.
The string will spread down the line until either a panel is found that faces the wrong way, or has a channel that's not empty/nil and is set to something other than what the first is set to, or if a node is encountered that is not an alpha-numeric panel at all.
Panels to the left of the connected one are ignored (unless they, too, have their own connections).
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.
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).
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.
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 there.
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.
Strings are trimmed to 6 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.
This mod uses the full ISO-8859-1 character set (see https://en.wikipedia.org/wiki/ISO/IEC_8859-1 for details), plus a bunch of symbols stuffed into the empty 128-159 range that should be useful on a marquee:
This mod uses the full ISO-8859-1 character set (see https://en.wikipedia.org/wiki/ISO/IEC_8859-1 for details), plus a bunch of symbols stuffed into the normally-empty 128-159 range that should be useful on this sort of display:
* 128,129: musical notes
* 130-140: box drawing glyphs
* 141-144: block shades
@ -41,31 +39,46 @@ This mod uses the full ISO-8859-1 character set (see https://en.wikipedia.org/wi
* 153-156: explosion/splat
* 157-159: smileys
If a string is prefixed with character code 255, it is treated as UTF-8 and passed through a simple translation function. Only characters with codes greater than 159 are altered; normal ASCII text, color codes, control codes, and the above symbols are passed through unchanged. Note that in this mode, a character code over 159 is treated as the first byte of a two-byte symbol.
The panels also respond to these control messages:
* the keywords "off", "colon" and "period" translate to a blank space, ":", and ".", respectively (they're leftover from the nixie tubes fork, but might be useful anyway)
* "del" is mapped to character #127, a square with an X in it.
* "allon" is mapped to character #144, the full/all-on block graphic.
* "cursor" or character code 31 will display a short, thick, flashing line at the bottom of the panel.
* "off_multi" turns all panels in a lineup off
* "allon_multi" turns on all LEDs of all panels in a lineup.
* "clear" turns all panels in a lineup or wall off, or up to 2048 of them, anyway - essentially a "clear screen" command.
* "allon" fills all panels in a lineup/wall, up to a max of 2048 of them, with char(144), i.e. the reverse of "clear".
* "start_scroll" starts the automatic scrolling function, repeatedly moving the last displayed message to the left one character space each time the scroll timer runs out (and automatically restarting it, natch). The scroll action will spread across the line, and down a multi-line wall (just set a new, different channel on the first row you want to exclude), and will continue until "stop_scroll" or any displayable message is received.
A byte value of 0 to 27 will change colors (i.e. string.char(0 to 27) ). Color values 0 to 11 are:
As it advances through the message, the scroll code will search through the message for a printable character, on each scroll step, basically stripping-out color code, and using just the last one before the new start position. This is done in order to keep a constant visible speed (the text will still be colored properly though).
* "stop_scroll" does just what it says - it stops the auto-scroll timer.
* "scroll_speed" followed by a decimal number (in the string, not a byte value) sets the time between scroll steps. Minimum 0.2s, maximum 5s.
* "scroll_step" will immediately advance the last-displayed message by one character. Omit the above automatic scrolling keywords, and use ONLY this keyword instead if you want to let your LuaController control the scrolling speed. Optionally, you can follow this with a number and the scroll code will skip forward that many bytes into the message, starting from the current position, before starting the above-mentioned color-vs-character search. Essentially, this value will roughly translate to the number of printable characters to skip.
* "get" will read the one character (as a numerical character value) currently displayed by the master panel (by reading its node name)
* "getstr" will read the last-stored message for the entire lineup/wall (from the master panel's meta). Note that even if the message has been or is being scrolled, you'll get the original stored message.
* "getindex" will read the scroll index position in that message, which will always point at a printable character, per the above color-versus-character search.
During a scroll event, the printed string is padded with spaces (one in auto mode, or as many as the skip value when manually stepping).
If you need vertical scrolling, you will have to handle that yourself (since the size of a screen/wall is not hard-coded).
To change colors, put a "/" followed by a digit or a letter from "A" to "R" (or "a" to "r") into your printed string. Digits 0 to 9 trigger colors 0 to 9 (obviously :-) ), while A/a through R/r set colors 10 to 27. Any other sequence is invalid and will just be printed literally. Two slashes "//" will translated to a single char(30) internally, and displayed as a single slash (doing it that way makes the code easier).
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 24 - 27 are white, light grey, medium grey, and dim grey.
Colors 24 - 27 are white, light grey, medium grey, and dim grey (or think of them as full bright white, a bit less bright, medium brightness, and dim white).
The left-most/"master" panel will remember the last color used, and defaults to red.
The last color that was used is stored in the left-most/upper-left "master" panel's metadata, and defaults to red. It should persist across reboots.
A byte value of 28 will act as a line feed (I would have used 10, but that's a color code :-P )
char(10) will do its job as linefeed/newline.
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.
char(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 onward with normal line wrapping, colors and so forth. Note that any string that does NOT contain cursor positioning commands will automatically start printing at the upper-left.
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.
Any number of color, line feed, and cursor position commands may be present in a string, making it possible to "frame-buffer" a screen full of text into a string before printing it.
All panels emit a small amount of light when displaying something.
The panels only mount on a wall.
The "master"/connected panel stores the last-displayed message and some other details in its metadata, so you may occasionally need to dig and re-place the panel if things go wonky (this won't happen during normal use, but it may happen if you're making lots of changes to the panels' layout, channel names, etc).

View File

@ -1,5 +0,0 @@
default
digilines
mesecons_luacontroller
mesecons_microcontroller
mesecons_lamp

View File

@ -1 +0,0 @@
This mod provides a simple LED marquee that accepts single characters, strings, and special control words via digilines.

380
init.lua
View File

@ -1,27 +1,194 @@
-- simple LED marquee mod
-- by Vanessa Dannenberg
local S
if minetest.get_modpath("intllib") then
S = intllib.make_gettext_pair()
else
S = function(s) return s end
end
led_marquee = {}
led_marquee.scheduled_messages = {}
-- settings
led_marquee.message_minimum_time = tonumber(minetest.settings:get("led_marquee_message_minimum_time")) or 0.5
led_marquee.message_schedule_dtime = tonumber(minetest.settings:get("led_marquee_message_schedule_dtime")) or 0.2
led_marquee.message_schedule_size = tonumber(minetest.settings:get("led_marquee_message_schedule_size")) or 10
led_marquee.relay_timer = 0
local S = minetest.get_translator(minetest.get_current_modname())
local FS = function(...) return minetest.formspec_escape(S(...)) end
local color_to_char = {
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R"
}
local char_to_color = {
["0"] = 0,
["1"] = 1,
["2"] = 2,
["3"] = 3,
["4"] = 4,
["5"] = 5,
["6"] = 6,
["7"] = 7,
["8"] = 8,
["9"] = 9,
["A"] = 10,
["B"] = 11,
["C"] = 12,
["D"] = 13,
["E"] = 14,
["F"] = 15,
["G"] = 16,
["H"] = 17,
["I"] = 18,
["J"] = 19,
["K"] = 20,
["L"] = 21,
["M"] = 22,
["N"] = 23,
["O"] = 24,
["P"] = 25,
["Q"] = 26,
["R"] = 27,
["a"] = 10,
["b"] = 11,
["c"] = 12,
["d"] = 13,
["e"] = 14,
["f"] = 15,
["g"] = 16,
["h"] = 17,
["i"] = 18,
["j"] = 19,
["k"] = 20,
["l"] = 21,
["m"] = 22,
["n"] = 23,
["o"] = 24,
["p"] = 25,
["q"] = 26,
["r"] = 27
}
-- the following functions based on the so-named ones in Jeija's digilines mod
local reset_meta = function(pos)
minetest.get_meta(pos):set_string("formspec", "field[channel;Channel;${channel}]")
minetest.get_meta(pos):set_string("formspec",
"formspec_version[4]"..
"size[8,4]"..
"button_exit[3,2.5;2,0.5;proceed;"..FS("Proceed").."]"..
"field[1.75,1.5;4.5,0.5;channel;"..FS("Channel")..";${channel}]"
)
end
local on_digiline_receive_std = function(pos, node, channel, msg)
local meta = minetest.get_meta(pos)
local setchan = meta:get_string("channel")
if setchan ~= channel then return end
local num = tonumber(msg)
if msg == "colon" or msg == "period" or msg == "off" or (num and (num >= 0 and num <= 9)) then
minetest.swap_node(pos, { name = "led_marquee:marquee_"..msg, param2 = node.param2})
-- convert Lua's idea of a UTF-8 char to ISO-8859-1
local get_iso = function(c)
local hb = string.byte(c,1) or 0
local lb = string.byte(c,2) or 0
local dec = lb+hb*256
local char = dec - 49664
if dec > 49855 then char = dec - 49856 end
return char
end
local make_iso = function(s)
local i = 1
local s2 = ""
while i <= string.len(s) do
if string.byte(s,i) > 159 then
local ciso = get_iso(string.sub(s, i, i+1))
if ciso >= 0 and ciso < 256 then
s2 = s2..string.char(ciso)
else
s2 = s2..string.char(127)
end
i = i + 2
else
s2 = s2..string.sub(s, i, i)
i = i + 1
end
end
return s2
end
-- scrolling
led_marquee.set_timer = function(pos, timeout)
local timer = minetest.get_node_timer(pos)
timer:stop()
if not timeout or timeout < led_marquee.message_minimum_time or timeout > 5 then return false end
if timeout > 0 then
local meta = minetest.get_meta(pos)
meta:set_int("timeout", timeout)
timer:start(timeout)
end
end
led_marquee.scroll_text = function(pos, elapsed, skip)
skip = skip or 1
local meta = minetest.get_meta(pos)
local msg = meta:get_string("last_msg")
local channel = meta:get_string("channel")
local index = meta:get_int("index")
local color = meta:get_int("last_color")
local colorchar = color_to_char[color+1]
if not index or index < 1 then index = 1 end
local len = string.len(msg)
index = index + skip
if index > len then index = 1 end
-- search backward to find the most recent color code in the string
local r = index
while r > 0 and not string.match(string.sub(msg, r, r+1), "/[0-9A-Ra-r]") do
r = r - 1
end
if r == 0 then r = 1 end
if string.match(string.sub(msg, r, r+1), "/[0-9A-Ra-r]") then
colorchar = string.sub(msg, r+1, r+1)
end
-- search forward to find the next printable symbol after the current index
local f = index
while f < len do
if string.match(string.sub(msg, f-1, f), "/[0-9A-Ra-r]") then
f = f + 2
else
break
end
end
led_marquee.schedule_msg(pos, channel, "/"..colorchar..string.sub(msg, f)..string.rep(" ", skip + 1))
meta:set_int("index", f)
if not elapsed or elapsed < 0.2 then return false end
return true
end
-- the nodes:
@ -42,13 +209,37 @@ local cbox = {
wall_side = { -8/16, -8/16, -8/16, -7/16, 8/16, 8/16 }
}
local display_string = function(pos, channel, string)
if string == "off_multi" then
string = string.rep(" ", 1024)
elseif string == "allon_multi" then
string = string.rep(string.char(144), 1024)
led_marquee.decode_color = function(msg)
end
minetest.register_globalstep(function(dtime)
if dtime <= led_marquee.message_schedule_dtime
and (#led_marquee.scheduled_messages) > 0 then
led_marquee.display_msg(
led_marquee.scheduled_messages[1].pos,
led_marquee.scheduled_messages[1].channel,
led_marquee.scheduled_messages[1].msg
)
end
string = string.sub(string, 1, 1024)
table.remove(led_marquee.scheduled_messages, 1)
end)
led_marquee.schedule_msg = function(pos, channel, msg)
local idx = #led_marquee.scheduled_messages
led_marquee.scheduled_messages[idx+1] = { pos=pos, channel=channel, msg=msg }
if idx >= led_marquee.message_schedule_size then
table.remove(led_marquee.scheduled_messages, 1)
end
end
led_marquee.display_msg = function(pos, channel, msg)
msg = string.sub(msg, 1, 6144).." "
if string.sub(msg,1,1) == string.char(255) then -- treat it as incoming UTF-8
msg = make_iso(string.sub(msg, 2, 6144))
end
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")
@ -58,7 +249,7 @@ local display_string = function(pos, channel, string)
master_meta:set_int("last_color", 0)
end
local i = 1
local len = string.len(string)
local len = string.len(msg)
local wrapped = nil
while i <= len do
local node = minetest.get_node(pos2)
@ -66,7 +257,7 @@ local display_string = function(pos, channel, string)
local meta = minetest.get_meta(pos2)
local setchan = nil
if meta then setchan = meta:get_string("channel") end
local asc = string.byte(string, i, i)
local asc = string.byte(msg, i, i)
if not string.match(node.name, "led_marquee:char_") then
if not wrapped then
pos2.x = pos.x
@ -79,31 +270,48 @@ local display_string = function(pos, channel, string)
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
elseif asc == 10 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
local c = string.byte(msg, i+1, i+1) or 0
local r = string.byte(msg, 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 then -- translate to slash for printing
minetest.swap_node(pos2, { name = "led_marquee:char_47", 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
elseif asc == 47 then -- slash
local ccode = string.sub(msg, i+1, i+1)
if ccode then
if char_to_color[ccode] then
last_color = char_to_color[ccode]
i = i + 2
else
minetest.swap_node(pos2, { name = "led_marquee:char_47", 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
end
end
master_meta:set_int("last_color", last_color)
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)
else
i = i + 1
wrapped = nil
end
end
end
@ -121,77 +329,100 @@ local on_digiline_receive_string = function(pos, node, channel, msg)
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 = fdir + (last_color*8)})
elseif msg == "colon" then
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 = fdir + (last_color*8)})
elseif msg == "del" then
minetest.swap_node(pos, { name = "led_marquee:char_127", param2 = fdir + (last_color*8)})
if msg == "clear" then
led_marquee.set_timer(pos, 0)
msg = string.rep(" ", 2048)
meta:set_string("last_msg", msg)
led_marquee.schedule_msg(pos, channel, msg)
meta:set_int("index", 1)
elseif msg == "allon" then
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 = fdir + (last_color*8)})
led_marquee.set_timer(pos, 0)
msg = string.rep(string.char(144), 2048)
meta:set_string("last_msg", msg)
led_marquee.schedule_msg(pos, channel, msg)
meta:set_int("index", 1)
elseif msg == "start_scroll" then
local timeout = meta:get_int("timeout")
led_marquee.set_timer(pos, timeout)
elseif msg == "stop_scroll" then
led_marquee.set_timer(pos, 0)
return
elseif string.sub(msg, 1, 12) == "scroll_speed" then
local timeout = tonumber(string.sub(msg, 13)) or 0
led_marquee.set_timer(pos, math.max(timeout, led_marquee.message_minimum_time))
elseif string.sub(msg, 1, 11) == "scroll_step" then
local skip = tonumber(string.sub(msg, 12))
led_marquee.scroll_text(pos, nil, skip)
elseif msg == "get" then -- get the master panel's displayed char as ASCII numerical value
digilines.receptor_send(pos, digilines.rules.default, channel,
tonumber(string.match(minetest.get_node(pos).name,"led_marquee:char_(.+)")))
elseif msg == "getstr" then -- get the last stored message
digilines.receptor_send(pos, digilines.rules.default, channel, meta:get_string("last_msg"))
elseif msg == "getindex" then -- get the scroll index
digilines.receptor_send(pos, digilines.rules.default, channel, meta:get_int("index"))
else
display_string(pos, channel, msg)
msg = string.gsub(msg, "//", string.char(30))
led_marquee.set_timer(pos, 0)
local last_msg = meta:get_string("last_msg")
meta:set_string("last_msg", msg)
led_marquee.schedule_msg(pos, channel, msg)
if last_msg ~= msg then
meta:set_int("index", 1)
end
end
else
local asc = string.byte(msg)
if asc > 30 and asc < 256 then
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
digiline:receptor_send(pos, digiline.rules.default, channel, string.char(tonumber(string.match(minetest.get_node(pos).name,"led_marquee:char_(.+)"))))
meta:set_string("last_msg", tostring(msg))
meta:set_int("index", 1)
end
end
elseif msg and type(msg) == "number" then
if msg == 0 then
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 = fdir + (last_color*8)})
end
meta:set_string("last_msg", tostring(msg))
led_marquee.schedule_msg(pos, channel, tostring(msg))
meta:set_int("index", 1)
end
end
-- the nodes!
for i = 31, 255 do
local groups = { cracky = 2, not_in_creative_inventory = 1}
local light = LIGHT_MAX-2
local description = S("Alphanumeric LED marquee panel ("..i..")")
local tiles = {
{ name="led_marquee_base.png", color="white"},
{ name="led_marquee_leds_off.png", color="white"},
"led_marquee_char_"..i..".png",
}
local light = minetest.LIGHT_MAX-2
local description = S("LED marquee panel (@1)", i)
local leds = "led_marquee_char_"..i..".png^[mask:led_marquee_leds_on.png"
if i == 31 then
tiles = {
{ name="led_marquee_base.png", color="white"},
{ name="led_marquee_leds_off.png", color="white"},
{
name = "led_marquee_char_31.png",
animation = {type = "vertical_frames", aspect_w = 32, aspect_h = 32, length = 0.75}
}
leds ={
name = "led_marquee_char_31.png^[mask:led_marquee_leds_on_cursor.png",
animation = {type = "vertical_frames", aspect_w = 32, aspect_h = 32, length = 0.75}
}
end
local wimage
if i == 32 then
groups = {cracky = 2}
light = nil
description = S("Alphanumeric LED marquee panel")
description = S("LED marquee panel")
wimage = "led_marquee_leds_off.png^(led_marquee_char_155.png^[multiply:red)"
end
minetest.register_node("led_marquee:char_"..i, {
description = description,
drawtype = "mesh",
mesh = "led_marquee.obj",
tiles = tiles,
tiles = {
{ name = "led_marquee_base.png", color = "white" },
{ name = "led_marquee_leds_off.png", color = "white" }
},
overlay_tiles = { "", leds },
inventory_image = wimage,
is_ground_content = false,
wield_image = wimage,
palette="led_marquee_palette.png",
use_texture_alpha = true,
use_texture_alpha = "blend",
groups = groups,
paramtype = "light",
paramtype2 = "colorwallmounted",
@ -202,6 +433,11 @@ for i = 31, 255 do
reset_meta(pos)
end,
on_receive_fields = function(pos, formname, fields, sender)
local name = sender:get_player_name()
if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
minetest.record_protection_violation(pos, name)
return
end
if (fields.channel) then
minetest.get_meta(pos):set_string("channel", fields.channel)
end
@ -212,13 +448,13 @@ for i = 31, 255 do
action = on_digiline_receive_string,
},
},
drop = "led_marquee:char_32"
drop = "led_marquee:char_32",
on_timer = led_marquee.scroll_text
})
end
-- crafts
minetest.register_craft({
output = "led_marquee:char_32 6",
recipe = {

5
locale/led_marquee.de.tr Normal file
View File

@ -0,0 +1,5 @@
# textdomain: led_marquee
LED marquee panel (@1)=LED-Anzeigetafel (@1)
LED marquee panel=LED-Anzeigetafel
Proceed=Fortsetzen
Channel=Kanal

5
locale/template.txt Normal file
View File

@ -0,0 +1,5 @@
# textdomain: led_marquee
LED marquee panel (@1)=
LED marquee panel=
Proceed=
Channel=

View File

@ -1 +1,6 @@
name = led_marquee
title = LED marquee
description = This mod provides a simple LED marquee that accepts single characters, strings, and special control words via digilines.
depends = default, digilines
optional_depends = mesecons_luacontroller, mesecons_microcontroller, mesecons_lamp
min_minetest_version = 5.2.0

View File

@ -21,10 +21,6 @@ v -0.500000 -0.453125 0.468750
v -0.500000 -0.453125 -0.468750
v -0.500000 -0.437500 -0.484375
v -0.500000 -0.437500 -0.500000
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.681855 0.961799
vt 0.723891 0.992824
vt 0.723891 0.000000
@ -69,10 +65,6 @@ vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
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
@ -106,7 +98,5 @@ 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
g Cube_Cube_LEDs_Cube_Cube_LEDs_base_led_marquee_leds_off.png
f 1/41/6 2/42/6 3/43/6 4/44/6
g Cube_Cube_LEDs_Cube_Cube_LEDs_leds_on
f 21/45/6 22/46/6 23/47/6 24/48/6

BIN
screenshot_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 649 KiB

8
settingtypes.txt Normal file
View File

@ -0,0 +1,8 @@
# Minimal marquee interval
led_marquee_message_minimum_time (Minimal marquee interval) float 0.5
# Marquee globalstep update interval
led_marquee_message_schedule_dtime (Marquee globalstep update interval) float 0.2
# Global message queue size
led_marquee_message_schedule_size (Global message queue size) int 10

Binary file not shown.

Before

Width:  |  Height:  |  Size: 419 B

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 B

After

Width:  |  Height:  |  Size: 89 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 495 B

After

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 485 B

After

Width:  |  Height:  |  Size: 98 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 493 B

After

Width:  |  Height:  |  Size: 92 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 437 B

After

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 449 B

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 451 B

After

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 444 B

After

Width:  |  Height:  |  Size: 89 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 594 B

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 424 B

After

Width:  |  Height:  |  Size: 82 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 B

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 472 B

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 492 B

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 441 B

After

Width:  |  Height:  |  Size: 84 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 89 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 454 B

After

Width:  |  Height:  |  Size: 89 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 416 B

After

Width:  |  Height:  |  Size: 81 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 B

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 486 B

After

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 473 B

After

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 501 B

After

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 B

After

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 445 B

After

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 B

After

Width:  |  Height:  |  Size: 79 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 447 B

After

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 B

After

Width:  |  Height:  |  Size: 81 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 568 B

After

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 B

After

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 338 B

After

Width:  |  Height:  |  Size: 89 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 B

After

Width:  |  Height:  |  Size: 76 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 B

After

Width:  |  Height:  |  Size: 79 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

After

Width:  |  Height:  |  Size: 78 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 B

After

Width:  |  Height:  |  Size: 78 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 B

After

Width:  |  Height:  |  Size: 83 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 B

After

Width:  |  Height:  |  Size: 84 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 B

After

Width:  |  Height:  |  Size: 83 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 B

After

Width:  |  Height:  |  Size: 81 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 272 B

After

Width:  |  Height:  |  Size: 84 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 272 B

After

Width:  |  Height:  |  Size: 83 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 B

After

Width:  |  Height:  |  Size: 84 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 B

After

Width:  |  Height:  |  Size: 84 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 B

After

Width:  |  Height:  |  Size: 81 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 352 B

After

Width:  |  Height:  |  Size: 84 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 B

After

Width:  |  Height:  |  Size: 75 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 B

After

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 92 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 B

After

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 309 B

After

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 323 B

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 B

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 352 B

After

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 B

After

Width:  |  Height:  |  Size: 83 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 B

After

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 B

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 379 B

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 494 B

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 518 B

After

Width:  |  Height:  |  Size: 105 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 B

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 B

After

Width:  |  Height:  |  Size: 71 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 B

After

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 367 B

After

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 332 B

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 B

After

Width:  |  Height:  |  Size: 82 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 B

After

Width:  |  Height:  |  Size: 97 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 77 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 438 B

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 B

After

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 293 B

After

Width:  |  Height:  |  Size: 83 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 B

After

Width:  |  Height:  |  Size: 81 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 77 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 461 B

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 79 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 B

After

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 B

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 B

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 291 B

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 B

After

Width:  |  Height:  |  Size: 82 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 B

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 B

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 B

After

Width:  |  Height:  |  Size: 76 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

After

Width:  |  Height:  |  Size: 78 B

Some files were not shown because too many files have changed in this diff Show More