Add RAM, EEPROM, and GPU

master
cheapie 2021-01-26 15:44:07 -06:00
parent c4b40bcfd5
commit 91b95b03cf
9 changed files with 2071 additions and 0 deletions

11
README
View File

@ -90,3 +90,14 @@ In addition to right-clicking the controller in use to stop using it, the follow
* The player leaves the game
* The player is teleported away from the controller
* The controller receives the string "release" on its digilines channel
How to use the RAM and EEPROM chips:
First, set a channel.
Messages should consist of a table, with "command" set to either "read" or "write". "address" should be set to the number (0-31) of the 512-character block to read or write, and if writing then "data" should contain the data to write.
Example (to write - reading is similar, but with no data):
{command = "write",address = 7,data = "9a91a9e451b94dc262972557ab0d406f"}
The RAM and EEPROM chips behave identically, except that the RAM chip loses its contents when dug whereas the EEPROM does not.
How to use the 2D graphics processor:
Please see gpu.txt for information on this part.

1333
gpu-font.lua Normal file

File diff suppressed because it is too large Load Diff

431
gpu.lua Normal file
View File

@ -0,0 +1,431 @@
local font = dofile(minetest.get_modpath("digistuff")..DIR_DELIM.."gpu-font.lua")
local function explodebits(input)
local output = {}
for i=0,7,1 do
output[i] = input%(2^(i+1)) >= 2^i
end
return output
end
local function implodebits(input)
local output = 0
for i=0,7,1 do
output = output + (input[i] and 2^i or 0)
end
return output
end
local function tohsv(r,g,b)
r = r/255
g = g/255
b = b/255
max = math.max(r,g,b)
min = math.min(r,g,b)
delta = max-min
local hue = 0
if delta > 0 then
if max == r then
hue = (g-b)/delta
hue = (hue%6)*60
elseif max == g then
hue = (b-r)/delta
hue = 60*(hue+2)
elseif max == b then
hue = (r-g)/delta
hue = 60*(hue+4)
end
hue = hue/360
end
local sat = 0
if max > 0 then
sat = delta/max
end
return math.floor(hue*255),math.floor(sat*255),math.floor(max*255)
end
local function torgb(h,s,v)
h = h/255*360
s = s/255
v = v/255
local c = s*v
local x = (h/60)%2
x = 1-math.abs(x-1)
x = x*c
local m = v-c
local r = 0
local g = 0
local b = 0
if h < 60 then
r = c
g = x
elseif h < 120 then
r = x
g = c
elseif h < 180 then
g = c
b = x
elseif h < 240 then
g = x
b = c
elseif h < 300 then
r = x
b = c
else
r = c
b = x
end
r = r+m
g = g+m
b = b+m
return math.floor(r*255),math.floor(g*255),math.floor(b*255)
end
local function bitwiseblend(srcr,dstr,srcg,dstg,srcb,dstb,mode)
local srbits = explodebits(srcr)
local sgbits = explodebits(srcg)
local sbbits = explodebits(srcb)
local drbits = explodebits(dstr)
local dgbits = explodebits(dstg)
local dbbits = explodebits(dstb)
for i=0,7,1 do
if mode == "and" then
drbits[i] = srbits[i] and drbits[i]
dgbits[i] = sgbits[i] and dgbits[i]
dbbits[i] = sbbits[i] and dbbits[i]
elseif mode == "or" then
drbits[i] = srbits[i] or drbits[i]
dgbits[i] = sgbits[i] or dgbits[i]
dbbits[i] = sbbits[i] or dbbits[i]
elseif mode == "xor" then
drbits[i] = srbits[i] ~= drbits[i]
dgbits[i] = sgbits[i] ~= dgbits[i]
dbbits[i] = sbbits[i] ~= dbbits[i]
elseif mode == "xnor" then
drbits[i] = srbits[i] == drbits[i]
dgbits[i] = sgbits[i] == dgbits[i]
dbbits[i] = sbbits[i] == dbbits[i]
elseif mode == "not" then
drbits[i] = not srbits[i]
dgbits[i] = not sgbits[i]
dbbits[i] = not sbbits[i]
elseif mode == "nand" then
drbits[i] = not (srbits[i] and drbits[i])
dgbits[i] = not (sgbits[i] and dgbits[i])
dbbits[i] = not (sbbits[i] and dbbits[i])
elseif mode == "nor" then
drbits[i] = not (srbits[i] or drbits[i])
dgbits[i] = not (sgbits[i] or dgbits[i])
dbbits[i] = not (sbbits[i] or dbbits[i])
end
end
return string.format("%02X%02X%02X",implodebits(drbits),implodebits(dgbits),implodebits(dbbits))
end
local function blend(src,dst,mode,transparent)
local srcr = tonumber(string.sub(src,1,2),16)
local srcg = tonumber(string.sub(src,3,4),16)
local srcb = tonumber(string.sub(src,5,6),16)
local dstr = tonumber(string.sub(dst,1,2),16)
local dstg = tonumber(string.sub(dst,3,4),16)
local dstb = tonumber(string.sub(dst,5,6),16)
local op = "normal"
if type(mode) == "string" then op = string.lower(mode) end
if op == "normal" then
return src
elseif op == "nop" then
return dst
elseif op == "overlay" then
return (string.upper(src) == string.upper(transparent)) and dst or src
elseif op == "add" then
local r = math.min(255,srcr+dstr)
local g = math.min(255,srcg+dstg)
local b = math.min(255,srcb+dstb)
return string.format("%02X%02X%02X",r,g,b)
elseif op == "sub" then
local r = math.max(0,dstr-srcr)
local g = math.max(0,dstg-srcg)
local b = math.max(0,dstb-srcb)
return string.format("%02X%02X%02X",r,g,b)
elseif op == "isub" then
local r = math.max(0,srcr-dstr)
local g = math.max(0,srcg-dstg)
local b = math.max(0,srcb-dstb)
return string.format("%02X%02X%02X",r,g,b)
elseif op == "average" then
local r = math.min(255,(srcr+dstr)/2)
local g = math.min(255,(srcg+dstg)/2)
local b = math.min(255,(srcb+dstb)/2)
return string.format("%02X%02X%02X",r,g,b)
elseif op == "and" or op == "or" or op == "xor" or op == "xnor" or op == "not" or op == "nand" or op == "nor" then
return bitwiseblend(srcr,dstr,srcg,dstg,srcb,dstb,op)
elseif op == "tohsv" then
return string.format("%02X%02X%02X",tohsv(srcr,srcg,srcb))
elseif op == "torgb" then
return string.format("%02X%02X%02X",torgb(srcr,srcg,srcb))
else
return src
end
end
local function runcommand(pos,meta,command)
if type(command) ~= "table" then return end
if command.command == "createbuffer" then
if type(command.buffer) ~= "number" or type(command.xsize) ~= "number" or type(command.ysize) ~= "number" then return end
local bufnum = math.floor(command.buffer)
if bufnum < 0 or bufnum > 7 then return end
local xsize = math.min(64,math.floor(command.xsize))
local ysize = math.min(64,math.floor(command.ysize))
if xsize < 1 or ysize < 1 then return end
local fillcolor = command.fill
if type(fillcolor) ~= "string" or string.len(fillcolor) > 7 or string.len(fillcolor) < 6 then fillcolor = "000000" end
if string.sub(fillcolor,1,1) == "#" then fillcolor = string.sub(fillcolor,2,7) end
if not tonumber(fillcolor,16) then fillcolor = "000000" end
local buffer = {}
buffer.xsize = xsize
buffer.ysize = ysize
for y=1,ysize,1 do
buffer[y] = {}
for x=1,xsize,1 do
buffer[y][x] = fillcolor
end
end
meta:set_string("buffer"..bufnum,minetest.serialize(buffer))
elseif command.command == "send" then
if type(command.buffer) ~= "number" or type(command.channel) ~= "string" then return end
local bufnum = math.floor(command.buffer)
if bufnum < 0 or bufnum > 7 then return end
local buffer = meta:get_string("buffer"..bufnum)
if string.len(buffer) == 0 then return end
buffer = minetest.deserialize(buffer)
if type(buffer) == "table" then
digiline:receptor_send(pos,digiline.rules.default,command.channel,buffer)
end
elseif command.command == "drawrect" then
if type(command.buffer) ~= "number" or type(command.x1) ~= "number" or type(command.y1) ~= "number" or type(command.x2) ~= "number" or type(command.y2) ~= "number" then return end
local bufnum = math.floor(command.buffer)
if bufnum < 0 or bufnum > 7 then return end
local x1 = math.min(64,math.floor(command.x1))
local y1 = math.min(64,math.floor(command.y1))
local x2 = math.min(64,math.floor(command.x2))
local y2 = math.min(64,math.floor(command.y2))
if x1 < 1 or y1 < 1 or x2 < 1 or y2 < 1 then return end
local buffer = meta:get_string("buffer"..bufnum)
if string.len(buffer) == 0 then return end
buffer = minetest.deserialize(buffer)
if type(buffer) ~= "table" then return end
x2 = math.min(x2,buffer.xsize)
y2 = math.min(y2,buffer.ysize)
if x1 > x2 or y1 > y2 then return end
local fillcolor = command.fill
if type(fillcolor) ~= "string" or string.len(fillcolor) > 7 or string.len(fillcolor) < 6 then fillcolor = "000000" end
if string.sub(fillcolor,1,1) == "#" then fillcolor = string.sub(fillcolor,2,7) end
if not tonumber(fillcolor,16) then fillcolor = "000000" end
local edgecolor = command.edge
if type(edgecolor) ~= "string" or string.len(edgecolor) > 7 or string.len(edgecolor) < 6 then edgecolor = fillcolor end
if string.sub(edgecolor,1,1) == "#" then edgecolor = string.sub(edgecolor,2,7) end
if not tonumber(edgecolor,16) then edgecolor = fillcolor end
for y=y1,y2,1 do
for x=x1,x2,1 do
buffer[y][x] = fillcolor
end
end
if fillcolor ~= edgecolor then
for x=x1,x2,1 do
buffer[y1][x] = edgecolor
buffer[y2][x] = edgecolor
end
for y=y1,y2,1 do
buffer[y][x1] = edgecolor
buffer[y][x2] = edgecolor
end
end
meta:set_string("buffer"..bufnum,minetest.serialize(buffer))
elseif command.command == "drawpoint" then
if type(command.buffer) ~= "number" or type(command.x) ~= "number" or type(command.y) ~= "number" then return end
local bufnum = math.floor(command.buffer)
if bufnum < 0 or bufnum > 7 then return end
local x = math.floor(command.x)
local y = math.floor(command.y)
if x < 1 or y < 1 then return end
local buffer = meta:get_string("buffer"..bufnum)
if string.len(buffer) == 0 then return end
buffer = minetest.deserialize(buffer)
if type(buffer) ~= "table" then return end
if x > buffer.xsize or y > buffer.ysize then return end
local color = command.color
if type(color) ~= "string" or string.len(color) > 7 or string.len(color) < 6 then color = "000000" end
if string.sub(color,1,1) == "#" then color = string.sub(color,2,7) end
if not tonumber(color,16) then color = "000000" end
buffer[y][x] = color
meta:set_string("buffer"..bufnum,minetest.serialize(buffer))
elseif command.command == "copy" then
if type(command.src) ~= "number" or type(command.dst) ~= "number" or type(command.srcx) ~= "number" or type(command.srcy) ~= "number" or type(command.dstx) ~= "number" or type(command.dsty) ~= "number" or type(command.xsize) ~= "number" or type(command.ysize) ~= "number" then return end
local src = math.floor(command.src)
if src < 0 or src > 7 then return end
local dst = math.floor(command.dst)
if dst < 0 or dst > 7 then return end
local srcx = math.floor(command.srcx)
local srcy = math.floor(command.srcy)
local dstx = math.floor(command.dstx)
local dsty = math.floor(command.dsty)
local xsize = math.floor(command.xsize)
local ysize = math.floor(command.ysize)
if srcx < 1 or srcy < 1 or dstx < 1 or dsty < 1 or xsize < 1 or ysize < 1 then return end
local sourcebuffer = meta:get_string("buffer"..src)
local destbuffer = meta:get_string("buffer"..dst)
if string.len(sourcebuffer) == 0 then return end
sourcebuffer = minetest.deserialize(sourcebuffer)
if type(sourcebuffer) ~= "table" then return end
if string.len(destbuffer) == 0 then return end
destbuffer = minetest.deserialize(destbuffer)
if type(destbuffer) ~= "table" then return end
if srcx + xsize-1 > sourcebuffer.xsize or srcy + ysize-1 > sourcebuffer.ysize then return end
if dstx + xsize-1 > destbuffer.xsize or dsty + ysize-1 > destbuffer.ysize then return end
local transparent = command.transparent
if type(transparent) ~= "string" or string.len(transparent) > 7 or string.len(transparent) < 6 then transparent = "000000" end
if string.sub(transparent,1,1) == "#" then transparent = string.sub(transparent,2,7) end
if not tonumber(transparent,16) then transparent = "000000" end
for y=0,xsize-1,1 do
for x=0,xsize-1,1 do
local srcpx = sourcebuffer[srcy+y][srcx+x]
local destpx = destbuffer[dsty+y][dstx+x]
destbuffer[dsty+y][dstx+x] = blend(srcpx,destpx,command.mode,transparent)
end
end
meta:set_string("buffer"..dst,minetest.serialize(destbuffer))
elseif command.command == "load" then
if type(command.buffer) ~= "number" or type(command.x) ~= "number" or type(command.y) ~= "number" or type(command.data) ~= "table" then return end
local bufnum = math.floor(command.buffer)
if bufnum < 0 or bufnum > 7 then return end
local xstart = math.floor(command.x)
local ystart = math.floor(command.y)
if xstart < 1 or ystart < 1 then return end
local buffer = meta:get_string("buffer"..bufnum)
if string.len(buffer) == 0 then return end
buffer = minetest.deserialize(buffer)
if type(buffer) ~= "table" then return end
if type(command.data[1]) ~= "table" then return end
if #command.data[1] < 1 then return end
local ysize = #command.data
local xsize = #command.data[1]
if xstart+xsize > buffer.xsize or ystart+ysize > buffer.ysize then return end
for y=1,ysize,1 do
if type(command.data[y]) == "table" then
for x=1,xsize,1 do
local color = command.data[y][x]
if type(color) == "string" then
if string.len(color) == 7 then color = string.sub(color,2,7) end
if tonumber(color,16) then
buffer[ystart+y-1][xstart+x-1] = color
end
end
end
end
end
meta:set_string("buffer"..bufnum,minetest.serialize(buffer))
elseif command.command == "text" then
if type(command.buffer) ~= "number" or type(command.x) ~= "number" or type(command.y) ~= "number" or type(command.text) ~= "string" or string.len(command.text) < 1 then return end
command.text = string.sub(command.text,1,16)
local bufnum = math.floor(command.buffer)
if bufnum < 0 or bufnum > 7 then return end
local x = math.floor(command.x)
local y = math.floor(command.y)
if x < 1 or y < 1 then return end
local buffer = meta:get_string("buffer"..bufnum)
if string.len(buffer) == 0 then return end
buffer = minetest.deserialize(buffer)
if type(buffer) ~= "table" then return end
if x > buffer.xsize or y > buffer.ysize then return end
local color = command.color
if type(color) ~= "string" or string.len(color) > 7 or string.len(color) < 6 then color = "ff6600" end
if string.sub(color,1,1) == "#" then color = string.sub(color,2,7) end
if not tonumber(color,16) then color = "ff6600" end
for i=1,string.len(command.text),1 do
local char = font[string.byte(string.sub(command.text,i,i))]
for chary=1,12,1 do
for charx=1,5,1 do
local startx = x + (i*6-6)
if char[chary][charx] and y+chary-1 <= buffer.ysize and startx+charx-1 <= buffer.xsize then
local dstpx = buffer[y+chary-1][startx+charx-1]
buffer[y+chary-1][startx+charx-1] = blend(color,dstpx,command.mode,"")
end
end
end
end
meta:set_string("buffer"..bufnum,minetest.serialize(buffer))
end
end
minetest.register_node("digistuff:gpu", {
description = "Digilines 2D Graphics Processor",
groups = {cracky=3},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec","field[channel;Channel;${channel}")
end,
tiles = {
"digistuff_gpu_top.png",
"jeija_microcontroller_bottom.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png"
},
inventory_image = "digistuff_gpu_top.png",
drawtype = "nodebox",
selection_box = {
--From luacontroller
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -5/16, 8/16 },
},
_digistuff_channelcopier_fieldname = "channel",
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,
digiline =
{
receptor = {},
effector = {
action = function(pos,node,channel,msg)
local meta = minetest.get_meta(pos)
if meta:get_string("channel") ~= channel or type(msg) ~= "table" then return end
if type(msg[1]) == "table" then
for i=1,32,1 do
if type(msg[i]) == "table" then
runcommand(pos,meta,msg[i])
end
end
else
runcommand(pos,meta,msg)
end
end
},
},
})
minetest.register_craft({
output = "digistuff:gpu",
recipe = {
{"","default:steel_ingot",""},
{"digilines:wire_std_00000000","mesecons_luacontroller:luacontroller0000","digilines:wire_std_00000000"},
{"dye:red","dye:green","dye:blue"},
}
})

121
gpu.txt Normal file
View File

@ -0,0 +1,121 @@
Digilines 2D Graphics Processor
===============================
Commands for this part are in the form of a table, consisting of a field called "command" with the command to be executed, and other fields supplying parameters to the command.
Example:
{command="send",buffer=0,channel="example"}
Up to 32 commands may be sent at once by placing all of the tables into one.
Example:
{
{command="createbuffer",buffer=0,xsize=16,ysize=16,color="aaaaaa"},
{command="send",buffer=0,channel="example"}
}
Command: createbuffer
---------------------
Creates a new buffer. Up to 8 buffers may exist at one time, and each can be up to 64x64 pixels in size.
Parameters:
buffer [integer 0-7]: The slot number to create the new buffer in. If the slot is already occupied, the existing contents will be erased.
xsize [integer 1-64]: The width of the new buffer in pixels.
ysize [integer 1-64]: The height of the new buffer in pixels.
color [hex color, default "000000"]: A color to fill the new buffer with.
Command: send
-------------
Sends the contents of a buffer to a digiscreen, rgblightstone panel, or other digilines device.
Parameters:
buffer [integer 0-7]: The buffer to send the contents of.
channel [string]: The digilines channel to send the message on.
Command: drawrect
-----------------
Draws a rectangle with optional border on a buffer.
Parameters:
buffer [integer 0-7]: The buffer to draw the rectangle on.
x1 [integer 1-64]: The X position of the left side of the rectangle.
x2 [integer 1-64]: The X position of the right side of the rectangle.
y1 [integer 1-64]: The Y position of the top side of the rectangle.
y2 [integer 1-64]: The Y position of the bottom side of the rectangle.
fill [hex color, default "000000"]: The color of the rectangle.
edge [hex color, default same as fill]: The color of the outside edge of the rectangle.
Command: drawpoint
------------------
Draws a point on a buffer.
This command is intended for use when writing a single pixel at a time.
For writing large blocks at one time, it is recommended to use the "load" command instead.
Parameters:
buffer [integer 0-7]: The buffer to draw the point on.
x [integer 1-64]: The X position of the point.
y [integer 1-64]: The Y position of the point.
color [hex color, default "000000"]: The color of the point.
Command: copy
-------------
Perform a BitBLT operation (such as copying one buffer to another).
Parameters:
src [integer 0-7]: The buffer to copy from.
dst [integer 0-7]: The buffer to copy to. May be the same or different from "src".
srcx [integer 1-64]: The X position of the left side of the region to copy from.
srcy [integer 1-64]: The Y position of the top side of the region to copy from.
dstx [integer 1-64]: The X position of the left side of the region to copy to.
dsty [integer 1-64]: The Y position of the top side of the region to copy to.
xsize [integer 1-64]: The width of the region to copy.
ysize [integer 1-64]: The height of the region to copy.
mode [string from list below, default "normal"]: The blend mode to use for the copy operation.
transparent [hex color, default "000000"]: The color to treat as transparency when using the "overlay" blend mode. No effect in other modes.
Blend modes:
normal: Copy the source to the destination, overwriting the destination.
nop: Do nothing.
overlay: Same as normal, but skip pixels in the source matching the "transparent" color.
add: For each subpixel (red, green, blue) add the source values to the destination and write the sum to the destination.
sub: For each subpixel (red, green, blue) subtract the source values from the destination and write the difference to the destination.
isub: For each subpixel (red, green, blue) subtract the destination values from the source and write the difference to the destination.
average: For each subpixel (red, green, blue) calculate the average of the source and destination and write the average to the destination.
and: Perform a bitwise AND of the source and destination and write the result to the destination.
or: Perform a bitwise OR of the source and destination and write the result to the destination.
nand: Perform a bitwise NAND of the source and destination and write the result to the destination.
nor: Perform a bitwise NOR of the source and destination and write the result to the destination.
xor: Perform a bitwise XOR of the source and destination and write the result to the destination.
xnor: Perform a bitwise XNOR of the source and destination and write the result to the destination.
not: Perform a bitwise NOT of the source and write the result to the destination.
tohsv: Convert the source from the RGB color system to the HSV color system and write the result to the destination, storing hue as "red", saturation as "green", and value as "blue".
torgb: Convert the source from the HSV color system to the RGB color system, reading hue from the red channel, saturation from the green channel, and value from the blue channel, and write the result to the destination.
Command: load
-------------
Transfer a bitmap image into a buffer.
The width and height of the image will be automatically determined from the data given.
Parameters:
buffer [integer 0-7]: The buffer to write the image into.
x [integer 1-64]: The X position of the left side of the image.
y [integer 1-64]: The Y position of the top side of the image.
data [2D array of hex color values, default for each is transparency]: The bitmap image to write.
Command: text
-------------
Draw one or more text characters on a buffer.
The font being used is 5*12 pixels in size, with one pixel spacing between characters.
Parameters:
buffer [integer 0-7]: The buffer to draw the text on.
x [integer 1-64]: The X position of the left side of the text.
y [integer 1-64]: The Y position of the right side of the text.
color [hex color, default "ff6600"]: The color of the text.
text: The text string to draw.

View File

@ -16,6 +16,8 @@ local components = {
"cardreader",
"channelcopier",
"controller",
"memory",
"gpu",
}
if minetest.get_modpath("mesecons_luacontroller") then table.insert(components,"ioexpander") end

173
memory.lua Normal file
View File

@ -0,0 +1,173 @@
minetest.register_node("digistuff:ram", {
description = "Digilines 128Kbit SRAM",
groups = {cracky=3},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec","field[channel;Channel;${channel}")
for i=0,31,1 do
meta:set_string(string.format("data%02d",i),"")
end
end,
tiles = {
"digistuff_ram_top.png",
"jeija_microcontroller_bottom.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png"
},
inventory_image = "digistuff_ram_top.png",
drawtype = "nodebox",
selection_box = {
--From luacontroller
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -5/16, 8/16 },
},
_digistuff_channelcopier_fieldname = "channel",
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,
digiline =
{
receptor = {},
effector = {
action = function(pos,node,channel,msg)
local meta = minetest.get_meta(pos)
if meta:get_string("channel") ~= channel or type(msg) ~= "table" then return end
if msg.command == "read" then
if type(msg.address) == "number" and msg.address >= 0 and msg.address <= 31 then
digiline:receptor_send(pos,digiline.rules.default,channel,meta:get_string(string.format("data%02i",math.floor(msg.address))))
end
elseif msg.command == "write" then
if type(msg.address) == "number" and msg.address >= 0 and msg.address <= 31 and type(msg.data) == "string" then
meta:set_string(string.format("data%02i",math.floor(msg.address)),string.sub(msg.data,1,512))
end
end
end
},
},
})
minetest.register_node("digistuff:eeprom", {
description = "Digilines 128Kbit EEPROM",
groups = {cracky=3},
stack_max = 1,
after_place_node = function(pos,_,istack)
local meta = minetest.get_meta(pos)
local smeta = istack:get_meta()
for i=0,31,1 do
meta:set_string(string.format("data%02d",i),smeta:get_string(string.format("data%02d",i)))
end
meta:set_string("channel",smeta:get_string("channel"))
meta:set_string("formspec","field[channel;Channel;${channel}")
end,
on_dig = function(pos,node,player)
local name = player: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)
local istack = ItemStack("digistuff:eeprom")
local smeta = istack:get_meta()
for i=0,31,1 do
smeta:set_string(string.format("data%02d",i),meta:get_string(string.format("data%02d",i)))
end
smeta:set_string("channel",meta:get_string("channel"))
minetest.remove_node(pos)
smeta:set_string("description","Digilines 128KBit EEPROM (with data)")
local inv = minetest.get_inventory({type = "player",name = name,})
inv:add_item("main",istack)
digilines.update_autoconnect(pos)
end,
tiles = {
"digistuff_eeprom_top.png",
"jeija_microcontroller_bottom.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png"
},
inventory_image = "digistuff_eeprom_top.png",
drawtype = "nodebox",
selection_box = {
--From luacontroller
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -5/16, 8/16 },
},
_digistuff_channelcopier_fieldname = "channel",
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,
digiline =
{
receptor = {},
effector = {
action = function(pos,node,channel,msg)
local meta = minetest.get_meta(pos)
if meta:get_string("channel") ~= channel or type(msg) ~= "table" then return end
if msg.command == "read" then
if type(msg.address) == "number" and msg.address >= 0 and msg.address <= 31 then
digiline:receptor_send(pos,digiline.rules.default,channel,meta:get_string(string.format("data%02i",math.floor(msg.address))))
end
elseif msg.command == "write" then
if type(msg.address) == "number" and msg.address >= 0 and msg.address <= 31 and type(msg.data) == "string" then
meta:set_string(string.format("data%02i",math.floor(msg.address)),string.sub(msg.data,1,512))
end
end
end
},
},
})
minetest.register_craft({
output = "digistuff:ram",
recipe = {
{"basic_materials:plastic_sheet","basic_materials:plastic_sheet","basic_materials:plastic_sheet"},
{"mesecons_gates:nand_off","basic_materials:plastic_sheet","mesecons_gates:nand_off"},
{"mesecons:wire_00000000_off","basic_materials:silicon","mesecons:wire_00000000_off"},
}
})
minetest.register_craft({
output = "digistuff:eeprom",
recipe = {
{"basic_materials:plastic_sheet","mesecons:wire_00000000_off","basic_materials:plastic_sheet"},
{"digilines:wire_std_00000000","basic_materials:plastic_sheet","digilines:wire_std_00000000"},
{"mesecons:wire_00000000_off","basic_materials:silicon","mesecons:wire_00000000_off"},
}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB