mirror of
https://cheapiesystems.com/git/digistuff
synced 2024-11-24 08:03:50 +01:00
Add RAM, EEPROM, and GPU
This commit is contained in:
parent
c4b40bcfd5
commit
91b95b03cf
11
README
11
README
@ -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
1333
gpu-font.lua
Normal file
File diff suppressed because it is too large
Load Diff
431
gpu.lua
Normal file
431
gpu.lua
Normal 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
121
gpu.txt
Normal 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.
|
2
init.lua
2
init.lua
@ -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
173
memory.lua
Normal 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"},
|
||||
}
|
||||
})
|
BIN
textures/digistuff_eeprom_top.png
Normal file
BIN
textures/digistuff_eeprom_top.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
textures/digistuff_gpu_top.png
Normal file
BIN
textures/digistuff_gpu_top.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
textures/digistuff_ram_top.png
Normal file
BIN
textures/digistuff_ram_top.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
Loading…
Reference in New Issue
Block a user