It actually works :D
This commit is contained in:
parent
e96e5793dd
commit
1ae4504eb7
193
t400/init.lua
193
t400/init.lua
@ -1,193 +0,0 @@
|
|||||||
if not digiline then
|
|
||||||
print("Digilines not found.")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local oldprint=print
|
|
||||||
local function print(...)
|
|
||||||
for k,v in ipairs({...}) do
|
|
||||||
oldprint("[Test3D:T400] "..tostring(v))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
print("Test3D loading.")
|
|
||||||
|
|
||||||
local tInstructions = {
|
|
||||||
"NOP",
|
|
||||||
"ADD",
|
|
||||||
"SUB",
|
|
||||||
"PEEK",
|
|
||||||
"POKE",
|
|
||||||
}
|
|
||||||
local function push(pos,val)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local sstack = ""
|
|
||||||
local stack = string.split(meta:get_string("stack"),"\n")
|
|
||||||
if #stack > 15 then
|
|
||||||
print("Stack overflow at "..pos.x..","..pos.y..","..pos.z)
|
|
||||||
table.remove(stack,1)
|
|
||||||
end
|
|
||||||
stack[#sstack+1] = tostring(val)
|
|
||||||
for k,v in ipairs(stack) do
|
|
||||||
sstack = sstack .. v .. "\n"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local function pop(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local sstack = ""
|
|
||||||
local stack = string.split(meta:get_string("stack"),"\n")
|
|
||||||
local n = table.remove(stack,#stack) or 0
|
|
||||||
stack[#sstack+1] = tostring(val)
|
|
||||||
for k,v in ipairs(stack) do
|
|
||||||
sstack = sstack .. v .. "\n"
|
|
||||||
end
|
|
||||||
return tonumber(n)
|
|
||||||
end
|
|
||||||
local function t400_digiline_receive(pos, node, channel, msg)
|
|
||||||
print(pos,node,channel,msg)
|
|
||||||
meta = minetest.get_meta(pos)
|
|
||||||
if meta:get_string("waitingfor") == channel then
|
|
||||||
if meta:get_string("state") == "waitingstack" then
|
|
||||||
push(pos,msg)
|
|
||||||
if meta:get_string("state") == "waitingins" then
|
|
||||||
meta:set_int("ci",tonumber(msg))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
print("Created T400 digiline function")
|
|
||||||
|
|
||||||
local function t400_set_infotext(pos)
|
|
||||||
local meta=minetest.get_meta(pos)
|
|
||||||
local running="false"
|
|
||||||
if meta:get_int("test3d_running") == 1 then running="true" end
|
|
||||||
meta:set_string("infotext","Running: "..running.."\nState: "..meta:get_string("state").."\nPC: "..tostring(meta:get_int("pc")).."\nACC: "..tostring(meta:get_int("acc")).."\nBAK: "..tostring(meta:get_int("bak")))
|
|
||||||
end
|
|
||||||
|
|
||||||
local function t400_set_meta(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local fspec = "size[8,9]\nlabel[0,0;T400 execution node]\nfield[0.25,1;8,1;channel;Channel prefix;${channel}]\n"
|
|
||||||
fspec = fspec .. "textarea[0.25,2;8,7.5;program;Program;${program}]\n"
|
|
||||||
fspec = fspec .. "button_exit[0,8.5;7.9,1;;Done]\n"
|
|
||||||
meta:set_string("formspec",fspec)
|
|
||||||
meta:set_string("channel","")
|
|
||||||
meta:set_string("state","running") -- can be "running", "waitingstack" or "waitingins"
|
|
||||||
meta:set_string("waitingfor","") -- address waiting for
|
|
||||||
meta:set_string("stack","") -- internal stack
|
|
||||||
meta:set_int("ci",0) -- current instruction
|
|
||||||
meta:set_int("pc",0) -- program counter
|
|
||||||
t400_set_infotext(pos)
|
|
||||||
print("Initialized T400 at "..tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z))
|
|
||||||
end
|
|
||||||
minetest.register_node("test3d:t400", {
|
|
||||||
description = "T400 Execution Node",
|
|
||||||
tiles = {
|
|
||||||
{
|
|
||||||
image="t400.png",
|
|
||||||
animation={
|
|
||||||
type = "vertical_frames",
|
|
||||||
aspect_w=16,
|
|
||||||
aspect_h=16,
|
|
||||||
length=18,
|
|
||||||
length=1.8,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
on_construct = t400_set_meta,
|
|
||||||
on_punch = function(pos, _, _, _)
|
|
||||||
local meta=minetest.get_meta(pos)
|
|
||||||
local cstate = meta:get_int("test3d_running")
|
|
||||||
local nstate=1
|
|
||||||
if cstate==1 then
|
|
||||||
nstate=0
|
|
||||||
else
|
|
||||||
nstate=1
|
|
||||||
end
|
|
||||||
print("State: "..tostring(cstate).." -> "..tostring(nstate))
|
|
||||||
meta:set_int("test3d_running",nstate)
|
|
||||||
end,
|
|
||||||
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3},
|
|
||||||
digiline = {
|
|
||||||
receptor = {},
|
|
||||||
effector = {
|
|
||||||
action = t400_digiline_receive
|
|
||||||
}
|
|
||||||
},
|
|
||||||
on_receive_fields = function(pos,_,fields,sender)
|
|
||||||
if fields.channel == nil or fields.program == nil then return end
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
fields.channel = fields.channel or ""
|
|
||||||
meta:set_string("channel",fields.channel)
|
|
||||||
print("Channel: "..fields.channel)
|
|
||||||
local tProgram = {}
|
|
||||||
local lcounter = 0
|
|
||||||
for _,line in ipairs(string.split(fields.program,"\n")) do
|
|
||||||
if lcounter > 14 then break end -- only 15 real lines will be stored
|
|
||||||
local ltab = string.split(line," ")
|
|
||||||
local valid=false
|
|
||||||
if line:sub(1,1) == "#" then valid=true end
|
|
||||||
if line:sub(#line,#line) == ":" then valid=true end
|
|
||||||
for _,ins in ipairs(tInstructions) do
|
|
||||||
if string.upper(ltab[1]) == ins then
|
|
||||||
valid = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if valid then
|
|
||||||
lcounter = lcounter + 1
|
|
||||||
tProgram[#tProgram+1] = line
|
|
||||||
print("Valid: "..line)
|
|
||||||
else
|
|
||||||
print("Invalid: "..line)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local sProgram = ""
|
|
||||||
for _,l in ipairs(tProgram) do
|
|
||||||
sProgram = sProgram .. l .. "\n"
|
|
||||||
end
|
|
||||||
sProgram = sProgram:sub(1,-1)
|
|
||||||
meta:set_string("program",sProgram)
|
|
||||||
print("Program:\n"..sProgram)
|
|
||||||
meta:set_int("pc",0)
|
|
||||||
end
|
|
||||||
})
|
|
||||||
print("T400 node registered")
|
|
||||||
|
|
||||||
minetest.register_abm({
|
|
||||||
nodenames={"test3d:t400"},
|
|
||||||
interval=1,
|
|
||||||
chance=1,
|
|
||||||
action = function(pos)
|
|
||||||
function getDigiline(addr)
|
|
||||||
digiline:receptor_send(pos,digilines.rules.default,addr,"get")
|
|
||||||
minetest.get_meta(pos):set_string("state","waiting")
|
|
||||||
minetest.get_meta(pos):set_string("waitingfor",addr)
|
|
||||||
end
|
|
||||||
local node = minetest.get_node_or_nil(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
if meta:get_string("state") == "running" then
|
|
||||||
local state = meta:get_int("test3d_running")
|
|
||||||
if state == nil then state=1 end
|
|
||||||
if state == 1 then
|
|
||||||
local pc = meta:get_int("pc")
|
|
||||||
local acc = meta:get_int("acc")
|
|
||||||
local bak = meta:get_int("bak")
|
|
||||||
print("Running T400 node with instance at position "..tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z).." (PC: "..tostring(pc)..", ACC: "..tostring(acc)..", BAK: "..tostring(bak)..")")
|
|
||||||
local tProgram = string.split(meta:get_string("program"),"\n")
|
|
||||||
local tLine = string.split(tProgram[pc]:upper())
|
|
||||||
if pc == #tProgram then pc = 0 end
|
|
||||||
meta:set_int("pc",pc+1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
t400_set_infotext(pos)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
print("T400 ABMs registered")
|
|
||||||
|
|
||||||
--[[
|
|
||||||
minetest.register_chatcommand("lua", { -- I'm a terrible person
|
|
||||||
params = "<text>",
|
|
||||||
description = "Execute some Lua code",
|
|
||||||
privs = {talk = true},
|
|
||||||
func = function( _ , text)
|
|
||||||
e,lstr = pcall(loadstring(text))
|
|
||||||
minetest.chat_send_all(tostring(lstr))
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
]]--
|
|
181
test3d_t400/init.lua
Normal file
181
test3d_t400/init.lua
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
local MEMSIZE=16
|
||||||
|
if not digiline then
|
||||||
|
print("Digilines not found.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local oldprint=print
|
||||||
|
local function print(...)
|
||||||
|
for k,v in ipairs({...}) do
|
||||||
|
oldprint("[Test3D:T400] "..tostring(v))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
print("Loading.")
|
||||||
|
|
||||||
|
local function pos2string(pos)
|
||||||
|
return tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function push(pos,val)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local sstring = ""
|
||||||
|
local sstab = string.split(meta:get_string("stack"),"\n")
|
||||||
|
sstab[#sstab+1] = tostring(tonumber(val))
|
||||||
|
if #sstab > 16 then
|
||||||
|
table.remove(sstab,1)
|
||||||
|
end
|
||||||
|
for k,v in ipairs(sstab) do
|
||||||
|
sstring = sstring .. v .. "\n"
|
||||||
|
end
|
||||||
|
meta:set_string("stack",sstring)
|
||||||
|
end
|
||||||
|
local function pop(pos)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local sstring = ""
|
||||||
|
local sstab = string.split(meta:get_string("stack"),"\n")
|
||||||
|
local sval = table.remove(sstab,#sstab)
|
||||||
|
for k,v in ipairs(sstab) do
|
||||||
|
sstring = sstring .. v .. "\n"
|
||||||
|
end
|
||||||
|
meta:set_string("stack",sstring)
|
||||||
|
if not sval then sval = 0 end
|
||||||
|
return sval
|
||||||
|
end
|
||||||
|
|
||||||
|
local function t400_digiline_receive(pos, node, channel, msg)
|
||||||
|
print("Digiline: "..tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z).."; Channel: "..tostring(channel).."; Message: "..tostring(msg))
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if meta:get_string("state") == "waitingdat" and meta:get_string("waitingfor") == channel then
|
||||||
|
push(pos,tonumber(msg))
|
||||||
|
meta:set_int("pc",meta:get_int("pc")+1)
|
||||||
|
meta:set_string("state","running")
|
||||||
|
elseif meta:get_string("state") == "waitingins" and meta:get_string("waitingfor") == channel then
|
||||||
|
meta:set_int("ci",tonumber(msg))
|
||||||
|
meta:set_string("state","running")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
print("Created T400 digiline function")
|
||||||
|
|
||||||
|
local function t400_set_meta(pos)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local ms = ""
|
||||||
|
for i = 1, MEMSIZE do
|
||||||
|
ms = ms .. "0\n"
|
||||||
|
end
|
||||||
|
meta:set_string("stack",ms)
|
||||||
|
meta:set_string("channel","Default")
|
||||||
|
meta:set_string("state","running")
|
||||||
|
meta:set_string("waitingfor","")
|
||||||
|
meta:set_int("pc",0)
|
||||||
|
meta:set_int("ci",0)
|
||||||
|
meta:set_string("formspec","size[5,5]\nlabel[0.4,0.5;T400 Execution Node]\nfield[0.5,2;4,1;channel;Channel prefix;${channel}]\nfield[0.5,3;4,1;pc;Program Counter;${pc}]field[0.5,4;4,1;state;State;${state}]")
|
||||||
|
end
|
||||||
|
minetest.register_node("test3d_t400:t400", {
|
||||||
|
description = "T400 Execution Node",
|
||||||
|
tiles = {
|
||||||
|
{
|
||||||
|
image="t400.png",
|
||||||
|
animation={
|
||||||
|
type = "vertical_frames",
|
||||||
|
aspect_w=16,
|
||||||
|
aspect_h=16,
|
||||||
|
length=18,
|
||||||
|
length=1.8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
on_construct = t400_set_meta,
|
||||||
|
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3},
|
||||||
|
digiline = {
|
||||||
|
receptor = {},
|
||||||
|
effector = {
|
||||||
|
action = t400_digiline_receive
|
||||||
|
}
|
||||||
|
},
|
||||||
|
on_receive_fields = 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)
|
||||||
|
meta:set_string("pc",fields.pc)
|
||||||
|
meta:set_string("state",fields.state)
|
||||||
|
end
|
||||||
|
})
|
||||||
|
print("T400 node registered")
|
||||||
|
|
||||||
|
minetest.register_abm({
|
||||||
|
nodenames={"test3d_t400:t400"},
|
||||||
|
interval=0.1,
|
||||||
|
chance=1,
|
||||||
|
action = function(pos)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if meta:get_string("state") == "running" then
|
||||||
|
local skipnext = false
|
||||||
|
print("Attempting to run T400 node at "..pos2string(pos))
|
||||||
|
local ci = meta:get_int("ci")
|
||||||
|
--[[
|
||||||
|
4095 = drop
|
||||||
|
4094 = dup
|
||||||
|
4093 = swap
|
||||||
|
4092 = read
|
||||||
|
4091 = write
|
||||||
|
4090 = add
|
||||||
|
4089 = sup
|
||||||
|
4088 = multiply
|
||||||
|
4087 = jmp
|
||||||
|
4086 = skip if zero
|
||||||
|
]]--
|
||||||
|
if ci == 4095 then
|
||||||
|
print("Dropped "..tostring(pop(pos)).." from "..tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z))
|
||||||
|
elseif ci == 4094 then
|
||||||
|
local dat = pop(pos)
|
||||||
|
push(pos,dat)
|
||||||
|
push(pos,dat)
|
||||||
|
print("Duplicated "..tostring(dat).." at "..tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z))
|
||||||
|
elseif ci == 4093 then
|
||||||
|
local a = pop(pos)
|
||||||
|
local b = pop(pos)
|
||||||
|
push(pos,b)
|
||||||
|
push(pos,a)
|
||||||
|
--[[ I'll write the stuff for reading and writing memory eventually(TM)
|
||||||
|
]]--
|
||||||
|
elseif ci == 4092 then
|
||||||
|
skipnext = true
|
||||||
|
meta:set_string("state","waitingdat")
|
||||||
|
meta:set_string("waitingfor",meta:get_string("channel")..string.format("%X",addr))
|
||||||
|
local addr = pop(pos)
|
||||||
|
digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",addr),"get")
|
||||||
|
elseif ci == 4091 then
|
||||||
|
local addr = pop(pos)
|
||||||
|
local dat = pop(pos)
|
||||||
|
print("Writing "..tostring(dat).." to address "..addr)
|
||||||
|
digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",addr),dat)
|
||||||
|
elseif ci == 4090 then
|
||||||
|
print("Adding stuff")
|
||||||
|
push(pos,pop(pos)+pop(pos))
|
||||||
|
elseif ci == 4089 then
|
||||||
|
push(pos,pop(pos)-pop(pos))
|
||||||
|
elseif ci == 4088 then
|
||||||
|
push(pos,pop(pos)*pop(pos))
|
||||||
|
elseif ci == 4087 then
|
||||||
|
local npc = pop(pos)
|
||||||
|
print("Jumping to "..tostring(npc))
|
||||||
|
meta:set_int("pc",npc)
|
||||||
|
elseif ci == 4086 then
|
||||||
|
if pop(pos) == 0 then
|
||||||
|
meta:set_int("pc",meta:get_int("pc")+1)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print("Pushing "..ci.." to "..pos2string(pos))
|
||||||
|
push(pos,ci)
|
||||||
|
end
|
||||||
|
if not skipnext then
|
||||||
|
meta:set_int("pc",meta:get_int("pc")+1)
|
||||||
|
meta:set_string("state","waitingins")
|
||||||
|
meta:set_string("waitingfor",meta:get_string("channel")..string.format("%X",meta:get_int("pc")))
|
||||||
|
digiline:receptor_send(pos, digiline.rules.default, meta:get_string("channel")..string.format("%X",meta:get_int("pc")), "get")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
print("T400 ABM registered")
|
||||||
|
print("T400 init finished")
|
Before Width: | Height: | Size: 778 B After Width: | Height: | Size: 778 B |
BIN
test3d_t416/.init.lua.swp
Normal file
BIN
test3d_t416/.init.lua.swp
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user