summaryrefslogtreecommitdiff
path: root/init.lua
diff options
context:
space:
mode:
authorcheapie <no-email-for-you@example.com>2017-01-10 23:44:17 -0600
committercheapie <no-email-for-you@example.com>2017-01-10 23:44:17 -0600
commit3710261d8dc69d7e6df372c1643ff7ba13d396fa (patch)
tree683668c802033c67f0e1fc7be6438b50f1987ea4 /init.lua
downloadltc4000e-3710261d8dc69d7e6df372c1643ff7ba13d396fa.tar
ltc4000e-3710261d8dc69d7e6df372c1643ff7ba13d396fa.tar.gz
ltc4000e-3710261d8dc69d7e6df372c1643ff7ba13d396fa.tar.bz2
ltc4000e-3710261d8dc69d7e6df372c1643ff7ba13d396fa.tar.xz
ltc4000e-3710261d8dc69d7e6df372c1643ff7ba13d396fa.zip
Add existing content
Diffstat (limited to 'init.lua')
-rw-r--r--init.lua345
1 files changed, 345 insertions, 0 deletions
diff --git a/init.lua b/init.lua
new file mode 100644
index 0000000..21775bc
--- /dev/null
+++ b/init.lua
@@ -0,0 +1,345 @@
+--Just enough of the touchscreen to enable it to work here
+local function process_command(meta,data,msg)
+ if msg.command == "clear" then
+ data = {}
+ elseif msg.command == "addimage" then
+ for _,i in pairs({"X","Y","W","H"}) do
+ if not msg[i] or type(msg[i]) ~= "number" then
+ return
+ end
+ end
+ if not msg.texture_name or type(msg.texture_name) ~= "string" then
+ return
+ end
+ local field = {type="image",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,texture_name=minetest.formspec_escape(msg.texture_name)}
+ table.insert(data,field)
+ elseif msg.command == "addfield" then
+ for _,i in pairs({"X","Y","W","H"}) do
+ if not msg[i] or type(msg[i]) ~= "number" then
+ return
+ end
+ end
+ for _,i in pairs({"name","label","default"}) do
+ if not msg[i] or type(msg[i]) ~= "string" then
+ return
+ end
+ end
+ local field = {type="field",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label),default=minetest.formspec_escape(msg.default)}
+ table.insert(data,field)
+ elseif msg.command == "addpwdfield" then
+ for _,i in pairs({"X","Y","W","H"}) do
+ if not msg[i] or type(msg[i]) ~= "number" then
+ return
+ end
+ end
+ for _,i in pairs({"name","label"}) do
+ if not msg[i] or type(msg[i]) ~= "string" then
+ return
+ end
+ end
+ local field = {type="pwdfield",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)}
+ table.insert(data,field)
+ elseif msg.command == "addtextarea" then
+ for _,i in pairs({"X","Y","W","H"}) do
+ if not msg[i] or type(msg[i]) ~= "number" then
+ return
+ end
+ end
+ for _,i in pairs({"name","label","default"}) do
+ if not msg[i] or type(msg[i]) ~= "string" then
+ return
+ end
+ end
+ local field = {type="textarea",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label),default=minetest.formspec_escape(msg.default)}
+ table.insert(data,field)
+ elseif msg.command == "addlabel" then
+ for _,i in pairs({"X","Y"}) do
+ if not msg[i] or type(msg[i]) ~= "number" then
+ return
+ end
+ end
+ if not msg.label or type(msg.label) ~= "string" then
+ return
+ end
+ local field = {type="label",X=msg.X,Y=msg.Y,label=minetest.formspec_escape(msg.label)}
+ table.insert(data,field)
+ elseif msg.command == "addvertlabel" then
+ for _,i in pairs({"X","Y"}) do
+ if not msg[i] or type(msg[i]) ~= "number" then
+ return
+ end
+ end
+ if not msg.label or type(msg.label) ~= "string" then
+ return
+ end
+ local field = {type="vertlabel",X=msg.X,Y=msg.Y,label=minetest.formspec_escape(msg.label)}
+ table.insert(data,field)
+ elseif msg.command == "addbutton" then
+ for _,i in pairs({"X","Y","W","H"}) do
+ if not msg[i] or type(msg[i]) ~= "number" then
+ return
+ end
+ end
+ for _,i in pairs({"name","label"}) do
+ if not msg[i] or type(msg[i]) ~= "string" then
+ return
+ end
+ end
+ local field = {type="button",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)}
+ table.insert(data,field)
+ elseif msg.command == "addbutton_exit" then
+ for _,i in pairs({"X","Y","W","H"}) do
+ if not msg[i] or type(msg[i]) ~= "number" then
+ return
+ end
+ end
+ for _,i in pairs({"name","label"}) do
+ if not msg[i] or type(msg[i]) ~= "string" then
+ return
+ end
+ end
+ local field = {type="button_exit",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)}
+ table.insert(data,field)
+ elseif msg.command == "addimage_button" then
+ for _,i in pairs({"X","Y","W","H"}) do
+ if not msg[i] or type(msg[i]) ~= "number" then
+ return
+ end
+ end
+ for _,i in pairs({"image","name","label"}) do
+ if not msg[i] or type(msg[i]) ~= "string" then
+ return
+ end
+ end
+ local field = {type="image_button",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,image=minetest.formspec_escape(msg.image),name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)}
+ table.insert(data,field)
+ elseif msg.command == "addimage_button_exit" then
+ for _,i in pairs({"X","Y","W","H"}) do
+ if not msg[i] or type(msg[i]) ~= "number" then
+ return
+ end
+ end
+ for _,i in pairs({"image","name","label"}) do
+ if not msg[i] or type(msg[i]) ~= "string" then
+ return
+ end
+ end
+ local field = {type="image_button_exit",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,image=minetest.formspec_escape(msg.image),name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)}
+ table.insert(data,field)
+ elseif msg.command == "adddropdown" then
+ for _,i in pairs({"X","Y","W","H","selected_id"}) do
+ if not msg[i] or type(msg[i]) ~= "number" then
+ return
+ end
+ end
+ if not msg.name or type(msg.name) ~= "string" then
+ return
+ end
+ if not msg.choices or type(msg.choices) ~= "table" or #msg.choices < 1 then
+ return
+ end
+ local field = {type="dropdown",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=msg.name,selected_id=msg.selected_id,choices=msg.choices}
+ table.insert(data,field)
+ elseif msg.command == "lock" then
+ meta:set_int("locked",1)
+ elseif msg.command == "unlock" then
+ meta:set_int("locked",0)
+ end
+ return data
+end
+
+local function update_ts_formspec(pos,data)
+ local meta = minetest.get_meta(pos)
+ local fs = "size[10,8]"..
+ "background[0,0;0,0;ltc4000e_formspec_bg.png;true]"
+ for _,field in pairs(data) do
+ if field.type == "image" then
+ fs = fs..string.format("image[%s,%s;%s,%s;%s]",field.X,field.Y,field.W,field.H,field.texture_name)
+ elseif field.type == "field" then
+ fs = fs..string.format("field[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label,field.default)
+ elseif field.type == "pwdfield" then
+ fs = fs..string.format("pwdfield[%s,%s;%s,%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label)
+ elseif field.type == "textarea" then
+ fs = fs..string.format("textarea[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label,field.default)
+ elseif field.type == "label" then
+ fs = fs..string.format("label[%s,%s;%s]",field.X,field.Y,field.label)
+ elseif field.type == "vertlabel" then
+ fs = fs..string.format("vertlabel[%s,%s;%s]",field.X,field.Y,field.label)
+ elseif field.type == "button" then
+ fs = fs..string.format("button[%s,%s;%s,%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label)
+ elseif field.type == "button_exit" then
+ fs = fs..string.format("button_exit[%s,%s;%s,%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label)
+ elseif field.type == "image_button" then
+ fs = fs..string.format("image_button[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.image,field.name,field.label)
+ elseif field.type == "image_button_exit" then
+ fs = fs..string.format("image_button_exit[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.image,field.name,field.label)
+ elseif field.type == "dropdown" then
+ local choices = ""
+ for _,i in ipairs(field.choices) do
+ if type(i) == "string" then
+ choices = choices..minetest.formspec_escape(i)..","
+ end
+ end
+ choices = string.sub(choices,1,-2)
+ fs = fs..string.format("dropdown[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,choices,field.selected_id)
+ end
+ end
+ meta:set_string("formspec",fs)
+end
+
+local function ts_on_digiline_receive(pos,msg)
+ local meta = minetest.get_meta(pos)
+ if type(msg) ~= "table" then return end
+ local data = minetest.deserialize(meta:get_string("data")) or {}
+ if msg.command then
+ data = process_command(meta,data,msg)
+ else
+ for _,i in ipairs(msg) do
+ if i.command then
+ data = process_command(meta,data,i) or data
+ end
+ end
+ end
+ meta:set_string("data",minetest.serialize(data))
+ update_ts_formspec(pos,data)
+end
+
+--Load the (mostly unmodified) firmware
+local fw = loadfile(minetest.get_modpath("ltc4000e")..DIR_DELIM.."fw.lua")
+
+local function run(pos,event)
+ --Initialize environment
+ local context = {}
+ local meta = minetest.get_meta(pos)
+ context.mem = minetest.deserialize(meta:get_string("mem")) or {}
+ context.event = event
+ context.string = string
+ context.table = table
+ context.math = math
+ context.pairs = pairs
+ context.ipairs = ipairs
+ context.tostring = tostring
+ context.tonumber = tonumber
+ context.type = type
+ context.print = print
+ context.os = {}
+ for k,v in pairs(os) do
+ context.os[k] = v
+ end
+
+ function context.os.datetable()
+ return(os.date("*t",os.time()))
+ end
+
+ function context.digiline_send(channel,msg)
+ if channel == "touchscreen" then
+ --Touchscreen is integrated into the chip
+ ts_on_digiline_receive(pos,msg)
+ else
+ --Not an integrated peripheral, so send the message
+ digiline:receptor_send(pos,digiline.rules.default,channel,msg)
+ end
+ end
+
+ function context.interrupt(time,iid)
+ if iid == "gapout" then
+ --This one can have the time changed on-the-fly, so it has to be done with node timers
+ local timer = minetest.get_node_timer(pos)
+ if time then
+ timer:start(time)
+ else
+ timer:stop()
+ end
+ else
+ local event = {}
+ event.type = "interrupt"
+ event.iid = iid
+ minetest.after(time,run,pos,event)
+ end
+ end
+
+ --This is where the magic happens...
+ setfenv(fw,context)
+
+ --Run code
+ local success,err = pcall(fw)
+ if not success then
+ print("Error in LTC-4000E execution, aborting: "..err)
+ return
+ end
+
+ --Save memory after execution
+ meta:set_string("mem",minetest.serialize(context.mem))
+end
+
+local function ts_on_receive_fields(pos,formname,fields,sender)
+ local meta = minetest.get_meta(pos)
+ local playername = sender:get_player_name()
+ local locked = meta:get_int("locked") == 1
+ local can_bypass = minetest.check_player_privs(playername,{protection_bypass=true})
+ local is_protected = minetest.is_protected(pos,playername)
+ if (locked and is_protected) and not can_bypass then
+ minetest.record_protection_violation(pos,playername)
+ minetest.chat_send_player(playername,"You are not authorized to use this controller.")
+ return
+ end
+ local event = {}
+ event.type = "digiline"
+ event.channel = "touchscreen"
+ event.msg = fields
+ run(pos,event)
+end
+
+local nodebox = {
+ { -0.35, -0.45, 0.25, 0.35, 0.45, 0.75 }
+}
+
+
+minetest.register_node("ltc4000e:controller", {
+ tiles = {
+ "ltc4000e_cabinet_sides.png",
+ "ltc4000e_cabinet_sides.png",
+ "ltc4000e_cabinet_sides.png",
+ "ltc4000e_cabinet_sides.png",
+ "ltc4000e_cabinet_sides.png",
+ "ltc4000e_cabinet_front.png",
+ },
+ description = "LTC-4000E Traffic Signal Controller",
+ paramtype = "light",
+ paramtype2 = "facedir",
+ drawtype = "nodebox",
+ groups = {dig_immediate=2},
+ sounds = default.node_sound_stone_defaults(),
+ on_construct = function(pos)
+ local event = {type="program"}
+ run(pos,event)
+ end,
+ on_timer = function(pos)
+ local event = {}
+ event.type = "interrupt"
+ event.iid = "gapout"
+ run(pos,event)
+ end,
+ node_box = {
+ type = "fixed",
+ fixed = nodebox
+ },
+ selection_box = {
+ type = "fixed",
+ fixed = nodebox
+ },
+ on_receive_fields = ts_on_receive_fields,
+ digiline =
+ {
+ receptor = {},
+ effector = {
+ action = function(pos,_,channel,msg)
+ local event = {}
+ event.type = "digiline"
+ event.channel = channel
+ event.msg = msg
+ run(pos,event)
+ end
+ },
+ },
+})