Separate screens and computers

This commit is contained in:
Novatux 2013-07-07 10:17:58 +02:00
parent 6d13c01eb1
commit d1cc800302
3 changed files with 4939 additions and 4890 deletions

File diff suppressed because it is too large Load Diff

View File

@ -66,7 +66,7 @@ ASSEMBLER
: O+ 0x32 0x31 0x0c 0x22 0x21 0x29 ;
: UDM/MOD 0x33 0x31 0x32 0x1e 0x23 0x22 0x21 0x29 ;
\ : RAWKEY 0x50 0x21 0x29 ;
: EMIT 0x31 0x51 0x29 ;
\ : EMIT 0x31 0x51 0x29 ;
: < 0x32 0x3f 0x41 0x32 0x22 0x2e 0x45 0x3f 0x2f 0x39 0x04 0x00 0x32 0x3f 0x21 0x29 0x31 0x43 0x0d 0x21 0x29 ;
: > 0x31 0x32 0x21 0x3f 0x41 0x32 0x22 0x2e 0x45 0x3f 0x2f 0x39 0x04 0x00 0x32 0x3f 0x21 0x29 0x31 0x43 0x0d 0x21 0x29 ;
: NEGATE 0x32 0x4d 0x00 0x00 0x0d 0x22 0x29 ;
@ -110,6 +110,7 @@ FORTH
: CELL- 2 - ;
: CHAR+ 1+ ;
: CELLS 2* ;
: EMIT S" screen" SET-CHANNEL 2 ! 2 1 SEND ;
: RECEIVE 0x80 RECEIVE-AT ;
: 2! SWAP OVER ! CELL+ ! ;
: 2@ DUP CELL+ @ SWAP @ ;
@ -223,7 +224,8 @@ FORTH
: ?DO ['] (?do) , HERE 0 , HERE ; IMMEDIATE
: LOOP ['] (loop) , , HERE SWAP ! ; IMMEDIATE
: +LOOP ['] (+loop) , , HERE SWAP ! ; IMMEDIATE
: ACCEPT WAIT-INPUT 0 @ MIN TUCK 16 -ROT MOVE ;
\ : ACCEPT WAIT-INPUT 0 @ MIN TUCK 16 -ROT MOVE ;
: ACCEPT S" screen" DELETE-MSG BEGIN S" screen" 16 RECEIVE-AT DUP 0< WHILE DROP WAIT REPEAT MIN TUCK 16 -ROT MOVE ;
: EXPECT ACCEPT SPAN ! ;
: QUERY 0 >IN ! 0 SOURCE-ID ! TIB DUP 80 ACCEPT SPACE (source) 2! ;
: REFILL SOURCE-ID @ IF FALSE ELSE 0 >IN ! TIB DUP 80 ACCEPT SPACE (source) 2! TRUE THEN ;

View File

@ -62,12 +62,31 @@ local function dehashpos(str)
return {x = tonumber(l[1]), y = tonumber(l[2]), z = tonumber(l[3])}
end
function newline(text, toadd)
local function newline(text, toadd)
local f = lines(text)
table.insert(f, toadd)
return table.concat(f, "\n", 2)
end
local function add_char(text, char)
local ls = lines(text)
local ll = ls[#ls]
if char=="\n" or char=="\r" then
return newline(text,"")
elseif string.len(ll)>=MAX_LINE_LENGHT then
return newline(text, char)
else
return text..char
end
end
local function add_text(text, toadd)
for i=1, string.len(toadd) do
text = add_char(text, string.sub(toadd, i, i))
end
return text
end
local function readC(cptr, addr)
return cptr[addr]
end
@ -145,7 +164,7 @@ local function receive(cptr, caddr, clen, raddr)
end
cptr.X = string.len(event)
else
cptr.X = 0
cptr.X = u16(-1)
end
end
@ -290,8 +309,8 @@ ITABLE_RAW = {
[0x4e] = "cptr.Y = read(cptr, cptr.PC); cptr.PC = u16(cptr.PC+2)",
[0x4f] = "cptr.Z = read(cptr, cptr.PC); cptr.PC = u16(cptr.PC+2)",
[0x50] = "if cptr.has_input then\ncptr.has_input = false\nelse\ncptr.paused = true\ncptr.PC = u16(cptr.PC-1)\nend",
[0x51] = "emit(pos, cptr.X, cptr)",
-- [0x50] = "if cptr.has_input then\ncptr.has_input = false\nelse\ncptr.paused = true\ncptr.PC = u16(cptr.PC-1)\nend",
-- [0x51] = "emit(pos, cptr.X, cptr)",
[0x52] = "receive(cptr, cptr.X, cptr.Y, cptr.Z)", -- Digiline receive
[0x53] = "delete_message(cptr, cptr.X, cptr.Y)",
[0x54] = "send_message(pos, cptr, cptr.X, cptr.Y)", -- Digiline send
@ -354,8 +373,9 @@ local function write_file(fn, tbl)
end
local cptrs = read_file(wpath.."/forth_computers")
local screens = read_file(wpath.."/screens")
local on_digiline_receive = function (pos, node, channel, msg)
local on_computer_digiline_receive = function (pos, node, channel, msg)
local cptr = cptrs[hashpos(pos)].cptr
if cptr == nil then return end
cptr.digiline_events[channel] = msg
@ -369,50 +389,81 @@ minetest.register_node("forth_computer:computer",{
digiline =
{
receptor = {},
effector = {action = on_digiline_receive},
effector = {action = on_computer_digiline_receive},
},
on_construct = function(pos)
local meta=minetest.get_meta(pos)
meta:set_string("text","\n\n\n\n\n\n\n\n\n\n")
cptrs[hashpos(pos)] = {pos=pos, cptr=create_cptr(), fmodif=false}
cptrs[hashpos(pos)] = {pos=pos, cptr=create_cptr()}
end,
on_destruct = function(pos)
cptrs[hashpos(pos)] = nil
end,
})
local on_screen_digiline_receive = function (pos, node, channel, msg)
if channel == "screen" then
local meta = minetest.get_meta(pos)
local ntext = add_text(meta:get_string("text"), msg)
meta:set_string("text",ntext)
screens[hashpos(pos)].fmodif = true
end
end
minetest.register_node("forth_computer:screen",{
description = "Screen",
tiles = {"screen.png"},
groups = {cracky=3},
sounds = default.node_sound_stone_defaults(),
digiline =
{
receptor = {},
effector = {action = on_screen_digiline_receive},
},
on_construct = function(pos)
local meta=minetest.get_meta(pos)
meta:set_string("text","\n\n\n\n\n\n\n\n\n\n")
screens[hashpos(pos)] = {pos=pos, fmodif=false}
end,
on_destruct = function(pos)
screens[hashpos(pos)] = nil
end,
on_rightclick = function(pos, node, clicker)
local meta = minetest.get_meta(pos)
local name = clicker:get_player_name()
if cptrs[hashpos(pos)] == nil then
cptrs[hashpos(pos)] = {pos=pos, cptr=create_cptr(), fmodif=false}
if screens[hashpos(pos)] == nil then
screens[hashpos(pos)] = {pos=pos, fmodif=false}
end
cptrs[hashpos(pos)].cptr.pname = name
screens[hashpos(pos)].pname = name
on_formspec_close(name, function()
local c = cptrs[hashpos(pos)]
if c~= nil then c.cptr.pname = nil end
local s = screens[hashpos(pos)]
if s~= nil then s.pname = nil end
end)
minetest.show_formspec(name,"computer"..hashpos(pos),create_formspec(meta:get_string("text")))
minetest.show_formspec(name,"screen"..hashpos(pos),create_formspec(meta:get_string("text")))
end,
})
minetest.register_globalstep(function(dtime)
for _,i in pairs(cptrs) do
run_computer(i.pos, i.cptr)
if i.cptr.fmodif then
i.cptr.fmodif=false
if i.cptr.pname~=nil then
end
for _,i in pairs(screens) do
if i.fmodif then
i.fmodif=false
if i.pname~=nil then
local meta = minetest.get_meta(i.pos)
minetest.show_formspec(i.cptr.pname,"computer"..hashpos(i.pos),create_formspec(meta:get_string("text")))
minetest.show_formspec(i.pname,"screen"..hashpos(i.pos),create_formspec(meta:get_string("text")))
end
end
end
end)
minetest.register_on_shutdown(function()
for _,i in pairs(cptrs) do
i.cptr.fmodif = false
i.cptr.panme = nil
for _,i in pairs(screens) do
i.fmodif = false
i.pname = nil
end
write_file(wpath.."/forth_computers",cptrs)
write_file(wpath.."/screens",screens)
end)
function escape(x)
@ -432,23 +483,19 @@ function create_formspec(text)
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname:sub(1,8)~="computer" then return end
if formname:sub(1,6)~="screen" then return end
if fields["f"]==nil or fields["f"]=="" then return end
local pos = dehashpos(formname:sub(9,-1))
local c = cptrs[hashpos(pos)]
if c==nil then return end
local cptr=c.cptr
cptr.has_input = true
local pos = dehashpos(formname:sub(7,-1))
local s = screens[hashpos(pos)]
if s==nil then return end
if string.len(fields["f"])>MAX_LINE_LENGHT then
fields["f"] = string.sub(fields["f"],1,MAX_LINE_LENGHT)
end
for i=1,string.len(fields["f"]) do
cptr[15+i] = string.byte(fields["f"],i)
end
write(cptr, 0, string.len(fields["f"]))
digiline:receptor_send(pos, digiline.rules.default, "screen", fields["f"])
local meta = minetest.get_meta(pos)
--local ntext = newline(meta:get_string("text"),fields["f"])
local ntext = meta:get_string("text")..fields["f"]
--local ntext = meta:get_string("text")..fields["f"]
local ntext = add_text(meta:get_string("text"), fields["f"])
meta:set_string("text",ntext)
minetest.show_formspec(player:get_player_name(),formname,create_formspec(ntext))
end)