commit 983de1cc760068218c76dbd8049e432d6bc6bc9e Author: number Zero Date: Fri Mar 3 00:37:44 2017 +0300 Working version diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b25c15b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..d621529 --- /dev/null +++ b/depends.txt @@ -0,0 +1,3 @@ +default? +digilines +mesecons_materials? diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..2037577 --- /dev/null +++ b/init.lua @@ -0,0 +1,12 @@ +-- © 2017 numberZero +-- Input format: {cmd=, addr=, value=} +-- Output format: {ok=, value=} +-- Commands: get, set, clear +-- Addresses are zero-based integers + +local MODPATH = minetest.get_modpath("digiline_memory") + +digiline_memory = {} + +dofile(MODPATH.."/memory.lua") +dofile(MODPATH.."/ram.lua") diff --git a/memory.lua b/memory.lua new file mode 100644 index 0000000..3a79ac7 --- /dev/null +++ b/memory.lua @@ -0,0 +1,61 @@ +-- © 2017 numberZero + +local ROW_SIZE_LIMIT = 4 * 1024 +local MSG_INVALID_ADDRESS = "Invalid address" +local MSG_DATA_TOO_LONG = "Data too long" + +local function get_meta_field_name(addr, desc) + if type(addr) ~= "number" then + return false + end + local int, frac = math.modf(addr) + if frac ~= 0 or int < 0 or int >= desc.size then + return false + end + return true, "data_"..int +end + +function digiline_memory.on_digiline_receive(pos, node, channel, msg) + if type(msg) ~= "table" or not msg.cmd then + return + end + local meta = minetest.get_meta(pos) + if channel ~= meta:get_string("channel") then + return + end + local ok = false + local addr + local value + local desc = minetest.registered_nodes[minetest.get_node(pos).name].digiline_memory + if msg.cmd == "get" then + ok, addr = get_meta_field_name(msg.addr, desc) + if ok then + value = minetest.deserialize(meta:get_string(addr)) + else + value = MSG_INVALID_ADDRESS + end + elseif msg.cmd == "set" then + ok, addr = get_meta_field_name(msg.addr, desc) + if ok then + if msg.value == nil then + value = "" + else + value = minetest.serialize(msg.value) + end + if #value > ROW_SIZE_LIMIT then + ok = false + value = MSG_DATA_TOO_LONG + else + meta:set_string(addr, value) + value = nil -- don't send it back + end + else + value = MSG_INVALID_ADDRESS + end + elseif msg.cmd == "clear" then + if desc.reset then + ok = desc:reset(pos) ~= false + end + end + digiline:receptor_send(pos, digiline.rules.default, channel, {ok=ok, value=value}) +end diff --git a/ram.lua b/ram.lua new file mode 100644 index 0000000..4e4e4e6 --- /dev/null +++ b/ram.lua @@ -0,0 +1,186 @@ +-- © 2017 numberZero + +local chip_size = 16 +local ram_layouts = { + [1] = { + {x=6, y=7, w=4, h=2}, + }, + [2] = { + {x=4, y=6, w=2, h=4}, + {x=10, y=6, w=2, h=4}, + }, + [4] = { + {x=3, y=4, w=4, h=2}, + {x=3, y=4, w=4, h=2}, + {x=9, y=10, w=4, h=2}, + {x=9, y=10, w=4, h=2}, + }, + [8] = { + {x=2, y=3, w=2, h=4}, + {x=5, y=3, w=2, h=4}, + {x=9, y=3, w=2, h=4}, + {x=12, y=3, w=2, h=4}, + {x=2, y=9, w=2, h=4}, + {x=5, y=9, w=2, h=4}, + {x=9, y=9, w=2, h=4}, + {x=12, y=9, w=2, h=4}, + }, +} + +local function chip_reset(desc, pos) + local meta = minetest.get_meta(pos) + meta:from_table({ + inventory = {}, + fields = { + formspec = "field[channel;Channel;${channel}]", + infotext = desc.label, + channel = "", + } + }) +end + +local function chip_receive_fields(pos, formname, fields, sender) + if fields.channel then + local meta = minetest.get_meta(pos) + meta:set_string("channel", fields.channel) + end +end + +for chip_count, layout in pairs(ram_layouts) do + local row_count = chip_size * chip_count + local nodename = "digiline_memory:ram_module_"..chip_count + local desc = { + label = string.format("RAM module (%d rows)", row_count), + size = row_count, + reset = chip_reset, + } + local nodeboxes = { + { -8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }, + { -7/16, -7/16, -7/16, 7/16, -6/16, 7/16 }, + + { -8/16, -7/16, -1/16, -7/16, -6/16, 1/16 }, + { 8/16, -7/16, -1/16, 7/16, -6/16, 1/16 }, + { -1/16, -7/16, -8/16, 1/16, -6/16, -7/16 }, + { -1/16, -7/16, 8/16, 1/16, -6/16, 7/16 }, + } + for _, chip in ipairs(layout) do + nodeboxes[#nodeboxes + 1] = { + (chip.x - 8) / 16, + -6 / 16, + (chip.y - 8) / 16, + (chip.x + chip.w - 8) / 16, + -5 / 16, + (chip.y + chip.h - 8) / 16, + } + end + minetest.register_node(nodename, { + description = string.format("Digiline %d-chip RAM module (%d rows)", chip_count, row_count), + drawtype = "nodebox", + tiles = { + string.format("digiline_memory_ram_%d.png", chip_count), + "digiline_memory_flat.png", + "digiline_memory_ram_side.png", + }, + paramtype = "light", + groups = { dig_immediate = 2 }, + selection_box = { + type = "fixed", + fixed = {{ -8/16, -8/16, -8/16, 8/16, -4/16, 8/16 }} + }, + node_box = { + type = "fixed", + fixed = nodeboxes, + }, + digiline = { + receptor = {}, + effector = { action = digiline_memory.on_digiline_receive }, + }, + digiline_memory = desc, + on_construct = function(pos) chip_reset(desc, pos) end, + on_receive_fields = chip_receive_fields, + }) +end + +-- Craftitems + +minetest.register_craftitem("digiline_memory:ram_chip", { + description = "Digiline RAM chip", + inventory_image = "digiline_memory_ram_chip.png", +}) + +minetest.register_craftitem("digiline_memory:ram_module_base", { + description = "Digiline RAM module base", + inventory_image = "digiline_memory_ram_base.png", +}) + +-- Item crafting + +minetest.register_craft({ + output = "digiline_memory:ram_module_base 4", + recipe = { + { "default:copper_ingot", "digilines:wire_std_00000000", "default:steel_ingot" }, + { "digilines:wire_std_00000000", "default:glass", "digilines:wire_std_00000000" }, + { "default:steel_ingot", "digilines:wire_std_00000000", "default:copper_ingot" }, + }, +}) + +minetest.register_craft({ + output = "digiline_memory:ram_module_base 4", + recipe = { + { "default:steel_ingot", "digilines:wire_std_00000000", "default:copper_ingot" }, + { "digilines:wire_std_00000000", "default:glass", "digilines:wire_std_00000000" }, + { "default:copper_ingot", "digilines:wire_std_00000000", "default:steel_ingot" }, + }, +}) + +minetest.register_craft({ + output = "digiline_memory:ram_chip 2", + recipe = { + { "mesecons_materials:silicon", "default:mese_crystal_fragment", "mesecons_materials:silicon" }, + { "mesecons_materials:silicon", "default:gold_ingot", "mesecons_materials:silicon" }, + }, +}) + +-- Module crafting + +minetest.register_craft({ + output = "digiline_memory:ram_module_1", + recipe = { + { "digiline_memory:ram_chip" }, + { "digiline_memory:ram_module_base" }, + }, +}) + +minetest.register_craft({ + output = "digiline_memory:ram_module_2", + recipe = { + { "digiline_memory:ram_chip" }, + { "digiline_memory:ram_module_base" }, + { "digiline_memory:ram_chip" }, + }, +}) + +minetest.register_craft({ + output = "digiline_memory:ram_module_4", + recipe = { + { "digiline_memory:ram_chip", "", "digiline_memory:ram_chip" }, + { "", "digiline_memory:ram_module_base", "" }, + { "digiline_memory:ram_chip", "", "digiline_memory:ram_chip" }, + }, +}) + +minetest.register_craft({ + output = "digiline_memory:ram_module_8", + recipe = { + { "digiline_memory:ram_chip", "digiline_memory:ram_chip", "digiline_memory:ram_chip" }, + { "digiline_memory:ram_chip", "digiline_memory:ram_module_base", "digiline_memory:ram_chip" }, + { "digiline_memory:ram_chip", "digiline_memory:ram_chip", "digiline_memory:ram_chip" }, + }, +}) + +-- Aliases + +minetest.register_alias("digiline_memory:memory_16", "digiline_memory:ram_module_1") +minetest.register_alias("digiline_memory:memory_32", "digiline_memory:ram_module_2") +minetest.register_alias("digiline_memory:memory_64", "digiline_memory:ram_module_4") +minetest.register_alias("digiline_memory:memory_128", "digiline_memory:ram_module_8") diff --git a/textures/digiline_memory_flat.png b/textures/digiline_memory_flat.png new file mode 100644 index 0000000..3585686 Binary files /dev/null and b/textures/digiline_memory_flat.png differ diff --git a/textures/digiline_memory_ram_1.png b/textures/digiline_memory_ram_1.png new file mode 100644 index 0000000..9613cc1 Binary files /dev/null and b/textures/digiline_memory_ram_1.png differ diff --git a/textures/digiline_memory_ram_2.png b/textures/digiline_memory_ram_2.png new file mode 100644 index 0000000..5fae1b8 Binary files /dev/null and b/textures/digiline_memory_ram_2.png differ diff --git a/textures/digiline_memory_ram_4.png b/textures/digiline_memory_ram_4.png new file mode 100644 index 0000000..f2ee011 Binary files /dev/null and b/textures/digiline_memory_ram_4.png differ diff --git a/textures/digiline_memory_ram_8.png b/textures/digiline_memory_ram_8.png new file mode 100644 index 0000000..9aceb95 Binary files /dev/null and b/textures/digiline_memory_ram_8.png differ diff --git a/textures/digiline_memory_ram_base.png b/textures/digiline_memory_ram_base.png new file mode 100644 index 0000000..cecae8a Binary files /dev/null and b/textures/digiline_memory_ram_base.png differ diff --git a/textures/digiline_memory_ram_chip.png b/textures/digiline_memory_ram_chip.png new file mode 100644 index 0000000..4a52167 Binary files /dev/null and b/textures/digiline_memory_ram_chip.png differ diff --git a/textures/digiline_memory_ram_side.png b/textures/digiline_memory_ram_side.png new file mode 100644 index 0000000..4a31ba0 Binary files /dev/null and b/textures/digiline_memory_ram_side.png differ