summaryrefslogtreecommitdiff
path: root/ioexpander.lua
diff options
context:
space:
mode:
authorcheapie <no-email-for-you@example.com>2019-09-13 14:09:25 -0500
committercheapie <no-email-for-you@example.com>2019-09-13 14:09:25 -0500
commitc92659a11ad77093b8a66a43a8fe362590774d48 (patch)
tree2de1579ccb36394e9fd9ba14d313df025cf25eb2 /ioexpander.lua
parent6062d9b08e2b66b6b3ab4b5059bc992e1edc4150 (diff)
downloaddigistuff-c92659a11ad77093b8a66a43a8fe362590774d48.tar
digistuff-c92659a11ad77093b8a66a43a8fe362590774d48.tar.gz
digistuff-c92659a11ad77093b8a66a43a8fe362590774d48.tar.bz2
digistuff-c92659a11ad77093b8a66a43a8fe362590774d48.tar.xz
digistuff-c92659a11ad77093b8a66a43a8fe362590774d48.zip
Add I/O expander
Diffstat (limited to 'ioexpander.lua')
-rw-r--r--ioexpander.lua176
1 files changed, 176 insertions, 0 deletions
diff --git a/ioexpander.lua b/ioexpander.lua
new file mode 100644
index 0000000..7e25772
--- /dev/null
+++ b/ioexpander.lua
@@ -0,0 +1,176 @@
+local explode_port_states = function(state)
+ local port = {}
+ port.a = state%2 == 1
+ port.b = state%4 >= 2
+ port.c = state%8 >= 4
+ port.d = state%16 >= 8
+ return port
+end
+
+local implode_port_states = function(port)
+ local state = 0
+ if port.a then state = state + 1 end
+ if port.b then state = state + 2 end
+ if port.c then state = state + 4 end
+ if port.d then state = state + 8 end
+ return state
+end
+
+local gettiles = function(state)
+ tiles = {
+ "digistuff_ioexp_top.png",
+ "jeija_microcontroller_bottom.png",
+ "jeija_microcontroller_sides.png",
+ "jeija_microcontroller_sides.png",
+ "jeija_microcontroller_sides.png",
+ "jeija_microcontroller_sides.png"
+ }
+ local port = explode_port_states(state)
+ for p,v in pairs(port) do
+ if v then
+ tiles[1] = tiles[1].."^jeija_luacontroller_LED_"..string.upper(p)..".png"
+ end
+ end
+ return tiles
+end
+
+local ioexp_get_on_rules = function(state)
+ local port = explode_port_states(state)
+ local rules = {}
+ if port.a then table.insert(rules,vector.new(-1,0,0)) end
+ if port.b then table.insert(rules,vector.new(0,0,1)) end
+ if port.c then table.insert(rules,vector.new(1,0,0)) end
+ if port.d then table.insert(rules,vector.new(0,0,-1)) end
+ return rules
+end
+
+local ioexp_get_off_rules = function(state)
+ local port = explode_port_states(state)
+ local rules = {}
+ if not port.a then table.insert(rules,vector.new(-1,0,0)) end
+ if not port.b then table.insert(rules,vector.new(0,0,1)) end
+ if not port.c then table.insert(rules,vector.new(1,0,0)) end
+ if not port.d then table.insert(rules,vector.new(0,0,-1)) end
+ return rules
+end
+
+local ioexp_digiline_send = function(pos)
+ local meta = minetest.get_meta(pos)
+ local channel = meta:get_string("channel")
+ local port = {
+ a = meta:get_int("aon") == 1,
+ b = meta:get_int("bon") == 1,
+ c = meta:get_int("con") == 1,
+ d = meta:get_int("don") == 1,
+ }
+ local outstate = explode_port_states(meta:get_int("outstate"))
+ for k,v in pairs(outstate) do port[k] = port[k] or v end
+ digiline:receptor_send(pos,digiline.rules.default,channel,port)
+end
+
+local ioexp_handle_digilines = function(pos,node,channel,msg)
+ local meta = minetest.get_meta(pos)
+ if channel ~= meta:get_string("channel") then return end
+ if msg == "GET" then
+ ioexp_digiline_send(pos)
+ return
+ end
+ if type(msg) ~= "table" then return end
+ local state = implode_port_states(msg)
+ node.name = "digistuff:ioexpander_"..state
+ meta:set_int("outstate",state)
+ minetest.swap_node(pos,node)
+ for _,i in ipairs(ioexp_get_on_rules(state)) do
+ mesecon.receptor_on(pos,{i})
+ end
+ for _,i in ipairs(ioexp_get_off_rules(state)) do
+ mesecon.receptor_off(pos,{i})
+ end
+end
+
+local ioexp_rule_to_port = function(rule)
+ if rule.x < 0 then return "a"
+ elseif rule.z > 0 then return "b"
+ elseif rule.x > 0 then return "c"
+ elseif rule.z < 0 then return "d" end
+end
+
+local ioexp_handle_mesecons = function(pos,_,rule,state)
+ local meta = minetest.get_meta(pos)
+ local port = ioexp_rule_to_port(rule)
+ if not port then return end
+ local meta = minetest.get_meta(pos)
+ meta:set_int(port.."on",state == "on" and 1 or 0)
+ ioexp_digiline_send(pos)
+end
+
+for i=0,15,1 do
+ local offstate = i == 0
+ minetest.register_node("digistuff:ioexpander_"..i, {
+ description = offstate and "Digilines I/O Expander" or string.format("Digilines I/O Expander (on state %X - you hacker you!)",i),
+ groups = offstate and {cracky = 3,} or {cracky = 3,not_in_creative_inventory = 1,},
+ on_construct = function(pos)
+ local meta = minetest.get_meta(pos)
+ meta:set_string("formspec","field[channel;Channel;${channel}")
+ meta:set_int("aon",0)
+ meta:set_int("bon",0)
+ meta:set_int("con",0)
+ meta:set_int("don",0)
+ meta:set_int("outstate",i)
+ end,
+ tiles = gettiles(i),
+ inventory_image = "digistuff_ioexp_top.png",
+ drawtype = "nodebox",
+ drop = "digistuff:ioexpander_0",
+ selection_box = {
+ --From luacontroller
+ type = "fixed",
+ fixed = { -8/16, -8/16, -8/16, 8/16, -5/16, 8/16 },
+ },
+ node_box = {
+ --From Luacontroller
+ type = "fixed",
+ fixed = {
+ {-8/16, -8/16, -8/16, 8/16, -7/16, 8/16}, -- Bottom slab
+ {-5/16, -7/16, -5/16, 5/16, -6/16, 5/16}, -- Circuit board
+ {-3/16, -6/16, -3/16, 3/16, -5/16, 3/16}, -- IC
+ }
+ },
+ paramtype = "light",
+ sunlight_propagates = true,
+ 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
+ local meta = minetest.get_meta(pos)
+ if fields.channel then meta:set_string("channel",fields.channel) end
+ end,
+ mesecons = {
+ effector = {
+ rules = ioexp_get_off_rules(i),
+ action_change = ioexp_handle_mesecons,
+ },
+ receptor = {
+ state = mesecon.state.on,
+ rules = ioexp_get_on_rules(i),
+ },
+ },
+ digiline = {
+ receptor = {},
+ effector = {
+ action = ioexp_handle_digilines,
+ },
+ },
+ })
+end
+
+minetest.register_craft({
+ output = "digistuff:ioexpander_0",
+ recipe = {
+ {"","mesecons:wire_00000000_off","",},
+ {"digilines:wire_std_00000000","basic_materials:silicon","mesecons:wire_00000000_off",},
+ {"","mesecons:wire_00000000_off","",},
+ }
+})