MT-test3d/test3d_t408/init.lua

199 lines
6.3 KiB
Lua

local MEMSIZE=16
local path = minetest.get_modpath(minetest.get_current_modname())
local t408_mem, t408_stab = {},{}
print("Looking for memory file at "..path.."/mem.dat")
local f=io.open(path.."/mem.dat","rb")
if f ~= nil then
local c = f:read("*a")
print("Found T408 memory file.")
-- rawset(_G,"t408_mem",minetest.deserialize(c))
t408_mem = minetest.deserialize(c)
print("Contents: "..c)
f:close()
end
print("Looking for metadata file at "..path.."/stab.dat")
local f=io.open(path.."/stab.dat","rb")
if f ~= nil then
print("Found T408 metadata file.")
local c = f:read("*a")
t408_stab = minetest.deserialize(c)
print("Contents: "..c)
f:close()
end
local t408 = dofile(path.."/t408.lua")
t408.debug = true
print(type(_G.t408_mem))
if not digiline then
print("Digilines not found.")
return
end
local oldprint=print
local function print(...)
for k,v in ipairs({...}) do
oldprint("[Test3D:T408] "..tostring(v))
end
end
print("Loading.")
local function t408_digiline_receive(pos, node, channel, msg)
local meta = minetest.get_meta(pos)
local nid = minetest.pos_to_string(pos)
local prea,preb = string.find(channel,meta:get_string("channel"))
print("Start channel: "..prea,"End channel: "..preb)
print("Recieved (pre)"..tostring(msg).." from "..tostring(channel).." (device channel: "..tostring(meta:get_string("channel"))..")")
if prea == 1 then
--if string.sub(channel,1,meta:get_string("channel"):len()) == meta:get_string("channel") then
-- local addr = tonumber(msg:sub(meta:get_string("channel"):len()+1))
-- local addr = tonumber(channel)
print("Correct channel.")
local addr = tonumber(string.sub(channel,preb+1))
print(addr)
if addr > -1 and addr < 16 then
print("Recieved "..tostring(msg).." from "..tostring(channel).." for "..tostring(addr).." (device channel: "..tostring(meta:get_string("channel"))..")")
t408_mem[nid][addr+224] = tonumber(msg)
end
end
--end
end
print("Created T408 digiline function")
local function t408_read(pos,addr)
if t408_mem[pos] == nil then return false end
print("Read: "..tostring(pos).." "..tostring(addr)..": "..tostring(t408_mem[pos][addr]))
return t408_mem[pos][addr] or 0
end
local function t408_write(pos,addr,val)
print(tostring(pos).." "..tostring(addr).." "..tostring(val))
if t408_mem[pos] == nil then return false end
t408_mem[pos][tonumber(addr)] = (tonumber(val)%256)
print("Write: "..tostring(pos).." "..tostring(addr)..": "..tostring(t408_mem[pos][addr]).." = "..tostring(val))
return true
end
local function t408_set_meta(pos)
local meta = minetest.get_meta(pos)
meta:set_string("channel","")
meta:set_string("state","running")
t408_mem[minetest.pos_to_string(pos)] = {}
t408_stab[minetest.pos_to_string(pos)] = {["ci"]=1,["pc"]=1,["stack"]={},["rstack"]={}}
print("Created T408 memory table with ID "..minetest.pos_to_string(pos))
end
minetest.register_node("test3d_t408:t408", {
description = "T408 Memory Node",
tiles = {{image="t408.png",animation={type="vertical_frames",aspect_w=16,aspect_h=16,length=1.8}}},
on_construct = t408_set_meta,
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3},
digiline = {
receptor = {},
effector = {
action = function (a,b,c,d) pcall(t408_digiline_receive,a,b,c,d) end
}
},
on_punch = function(pos,_,fields,sender)
-- if fields.channel == nil then return end
local meta = minetest.get_meta(pos)
-- fields.channel = fields.channel or ""
-- meta:set_string("channel",fields.channel)
if meta:get_string("state") == "running" then
meta:set_string("state","halted")
else
meta:set_string("state","running")
end
print(meta:get_string("state"))
end
})
minetest.register_chatcommand("test3d-t408-read", {
params = "<node ID> <address>",
description = "Read the memory in a T408 node",
func = function(name,str)
local tArg = {}
for s in str:gmatch("%S+") do
tArg[#tArg+1] = s
end
local nid,addr = tArg[1],tArg[2]
print(nid,addr)
minetest.chat_send_player(name,tostring(t408_read(nid,tonumber(addr))))
end
})
minetest.register_chatcommand("test3d-t408-write", {
params = "<node ID> <address> <new value>",
description = "Read the memory in a T408 node",
func = function(name,str)
local tArg = {}
for s in str:gmatch("%S+") do
tArg[#tArg+1] = s
end
local nid,addr,val = tArg[1],tArg[2],tArg[3]
print(nid,addr,val)
minetest.chat_send_player(name,tostring(t408_write(nid,tonumber(addr),tostring(val))))
end
})
minetest.register_chatcommand("test3d-t408-set", {
params = "<node ID> <variable> <new value>",
description = "Set T408 variables.",
func = function(name,str)
local tArg = {}
for s in str:gmatch("%S+") do
tArg[#tArg+1] = s
end
local nid,addr,val = tArg[1],tArg[2],tArg[3]
local meta = minetest.get_meta(minetest.string_to_pos(nid))
meta:set_string(addr,tArg[3] or "")
print("Set "..nid.."'s "..addr.." to "..(tArg[3] or ""))
end
})
minetest.register_chatcommand("test3d-t408-dump", {
params = "<node ID> <address> <new value>",
description = "Read the memory in a T408 node",
func = function(name,nid,addr,val)
for k,v in ipairs(t408_mem) do
print(k,v)
end
end
})
print("T408 node registered")
minetest.register_abm({
nodenames={"test3d_t408:t408"},
interval=1,
chance=1,
action = function(pos)
local meta = minetest.get_meta(pos)
if meta:get_string("state") == "running" then
local nid = minetest.pos_to_string(pos)
local stab,rw,addr,val = t408_stab[nid],nil,0,0
stab.cins = t408_mem[nid][stab.pc]
stab,rw,addr,val = t408.run(stab)
if rw == "read" then
stab.stack[#stab.stack+1] = t408_mem[nid][addr]
elseif rw == "preread" then
if addr > 223 and addr < 240 then
digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",tonumber(addr)-224),"get")
end
elseif rw == "write" then
t408_mem[nid][addr] = tonumber(val)
print("Writing "..tostring(val).." to "..tostring(addr))
if addr > 223 and addr < 240 then
digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",tonumber(addr)-224),tonumber(val))
print(string.char(val))
end
end
t408_stab[nid] = stab
end
end
})
minetest.register_on_shutdown(function()
local f=io.open(path.."/mem.dat","wb")
if f then
f:write(minetest.serialize(t408_mem))
f:close()
end
local f=io.open(path.."/stab.dat","wb")
if f then
f:write(minetest.serialize(t408_stab))
f:close()
end
end)