From 60bff23281a9c422243c522f0cfa2ecf189b0e7b Mon Sep 17 00:00:00 2001 From: cheapie Date: Mon, 27 Apr 2020 23:31:01 -0500 Subject: Add initial content --- COPYING | 30 ++++++++ README | 16 +++++ init.lua | 157 ++++++++++++++++++++++++++++++++++++++++++ mod.conf | 4 ++ textures/digiscreen_bg.png | Bin 0 -> 1355 bytes textures/digiscreen_pixel.png | Bin 0 -> 546 bytes 6 files changed, 207 insertions(+) create mode 100644 COPYING create mode 100644 README create mode 100644 init.lua create mode 100644 mod.conf create mode 100644 textures/digiscreen_bg.png create mode 100644 textures/digiscreen_pixel.png diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..41b41b5 --- /dev/null +++ b/COPYING @@ -0,0 +1,30 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to + +------------------- + +The font was originally by, to the best of my knowledge, gbl08ma. +The font was originally licensed under the WTFPL, and I believe that +this allows me to relicense it under the terms of the above license. diff --git a/README b/README new file mode 100644 index 0000000..b34604a --- /dev/null +++ b/README @@ -0,0 +1,16 @@ +Digilines Graphical Screen for Minetest +======================================= + +How to use: +1. Place one and set the channel +2. Send an image (see below for the format) +3. Image will be displayed on the screen + + + +Image format: +(this is the same as rgblightstone in group mode) +Images consist of tables, containing one table for each row with keys numbered from 1 to 16. +Within each row are 16 strings, one for each pixel in the row, with keys numbered from 1 to 16. +Each string contains the color for that pixel as a 6-digit hex color, with optional "#" prefix. +Invalid or omitted pixels or rows will appear as black, and excess pixels or rows will be discarded. diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..1c6ea88 --- /dev/null +++ b/init.lua @@ -0,0 +1,157 @@ +local function removeEntity(pos) + local entitiesNearby = minetest.get_objects_inside_radius(pos,0.5) + for _,i in pairs(entitiesNearby) do + if i:get_luaentity() and i:get_luaentity().name == "digiscreen:image" then + i:remove() + end + end +end + +local function generateTexture(pos,serdata) + --The data *should* always be valid, but it pays to double-check anyway due to how easily this could crash if something did go wrong + if type(serdata) ~= "string" then + minetest.log("error","[digiscreen] Serialized display data appears to be missing at "..minetest.pos_to_string(pos,0)) + return + end + local data = minetest.deserialize(serdata) + if type(data) ~= "table" then + minetest.log("error","[digiscreen] Failed to deserialize display data at "..minetest.pos_to_string(pos,0)) + return + end + for y=1,16,1 do + if type(data[y]) ~= "table" then + minetest.log("error","[digiscreen] Invalid row "..y.." at "..minetest.pos_to_string(pos,0)) + return + end + for x=1,16,1 do + if type(data[y][x]) ~= "string" or string.len(data[y][x]) ~= 6 then + minetest.log("error","[digiscreen] Missing/wrong length display data for X="..x.." Y="..y.." at "..minetest.pos_to_string(pos,0)) + return + end + for i=1,6,1 do + if not tonumber(string.sub(data[y][x],i,i),16) then + minetest.log("error","[digiscreen] Invalid digit in display data for X="..x.." Y="..y.." at "..minetest.pos_to_string(pos,0)) + return + end + end + end + end + + local ret = "[combine:16x16" + for y=1,16,1 do + for x=1,16,1 do + ret = ret..string.format(":%d,%d=(digiscreen_pixel.png\\^[colorize\\:#%s\\:255)",x-1,y-1,data[y][x]) + end + end + return ret +end + +local function updateDisplay(pos) + removeEntity(pos) + local meta = minetest.get_meta(pos) + local data = meta:get_string("data") + local entity = minetest.add_entity(pos,"digiscreen:image") + local fdir = minetest.facedir_to_dir(minetest.get_node(pos).param2) + local etex = "digiscreen_pixel.png" + etex = generateTexture(pos,data) or etex + entity:set_properties({textures={etex}}) + entity:set_yaw((fdir.x ~= 0) and math.pi/2 or 0) + entity:set_pos(vector.add(pos,vector.multiply(fdir,0.39))) +end + +minetest.register_entity("digiscreen:image",{ + initial_properties = { + visual = "upright_sprite", + physical = false, + collisionbox = {0,0,0,0,0,0,}, + textures = {"digiscreen_pixel.png",}, + }, +}) + +minetest.register_node("digiscreen:digiscreen",{ + description = "Digilines Graphical Display", + tiles = {"digiscreen_pixel.png",}, + groups = {cracky = 3,}, + paramtype = "light", + paramtype2 = "facedir", + on_rotate = minetest.global_exists("screwdriver") and screwdriver.rotate_simple, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {-0.5,-0.5,0.4,0.5,0.5,0.5}, + }, + light_source = 10, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec","field[channel;Channel;${channel}]") + local disp = {} + for y=1,16,1 do + disp[y] = {} + for x=1,16,1 do + disp[y][x] = "000000" + end + end + meta:set_string("data",minetest.serialize(disp)) + updateDisplay(pos) + end, + on_destruct = removeEntity, + on_receive_fields = function(pos,_,fields,sender) + local name = sender:get_player_name() + if not fields.channel then return end + if minetest.is_protected(pos,name) and not minetest.check_player_privs(name,"protection_bypass") then + minetest.record_protection_violation(pos,name) + return + end + local meta = minetest.get_meta(pos) + meta:set_string("channel",fields.channel) + end, + digiline = { + wire = { + rules = digiline.rules.default, + }, + effector = { + action = function(pos,_,channel,msg) + local meta = minetest.get_meta(pos) + local setchan = meta:get_string("channel") + if type(msg) ~= "table" or setchan ~= channel then return end + local data = {} + for y=1,16,1 do + data[y] = {} + if type(msg[y]) ~= "table" then msg[y] = {} end + for x=1,16,1 do + if type(msg[y][x]) == "string" and string.len(msg[y][x]) == 7 and string.sub(msg[y][x],1,1) == "#" then + msg[y][x] = string.sub(msg[y][x],2,-1) + end + if type(msg[y][x]) ~= "string" or string.len(msg[y][x]) ~= 6 then msg[y][x] = "000000" end + msg[y][x] = string.upper(msg[y][x]) + for i=1,6,1 do + if not tonumber(string.sub(msg[y][x],i,i),16) then + msg[y][x] = "000000" + end + end + data[y][x] = msg[y][x] + end + end + meta:set_string("data",minetest.serialize(data)) + updateDisplay(pos) + end, + }, + }, +}) + +minetest.register_lbm({ + name = "digiscreen:respawn", + label = "Respawn digiscreen entities", + nodenames = {"digiscreen:digiscreen"}, + run_at_every_load = true, + action = updateDisplay, +}) + +minetest.register_craft({ + output = "digiscreen:digiscreen", + recipe = { + {"mesecons_luacontroller:luacontroller0000","rgblightstone:rgblightstone_truecolor_0","rgblightstone:rgblightstone_truecolor_0",}, + {"rgblightstone:rgblightstone_truecolor_0","rgblightstone:rgblightstone_truecolor_0","rgblightstone:rgblightstone_truecolor_0",}, + {"rgblightstone:rgblightstone_truecolor_0","rgblightstone:rgblightstone_truecolor_0","rgblightstone:rgblightstone_truecolor_0",}, + }, +}) diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..663b3d0 --- /dev/null +++ b/mod.conf @@ -0,0 +1,4 @@ +name = digiscreen +description = Digilines Graphical Screen +depends = digilines +optional_depends = screwdriver diff --git a/textures/digiscreen_bg.png b/textures/digiscreen_bg.png new file mode 100644 index 0000000..91009da Binary files /dev/null and b/textures/digiscreen_bg.png differ diff --git a/textures/digiscreen_pixel.png b/textures/digiscreen_pixel.png new file mode 100644 index 0000000..7b51e15 Binary files /dev/null and b/textures/digiscreen_pixel.png differ -- cgit v1.2.3