mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-19 23:14:05 +09:00
BEEPs are now played limitness, without killing AL
Former-commit-id: 627561820d469f0b563832f01ee37a8b04bd6935 Former-commit-id: 16f01413bc1c6809f3402d87ebffac8731338562
This commit is contained in:
@@ -47,7 +47,7 @@ _G.bell = function(patn) term.bell(patn or ".") end
|
||||
_G.beep = _G.bell
|
||||
|
||||
if totalMemory() == 0 then
|
||||
bell "="
|
||||
bell "==="
|
||||
print("no RAM installed")
|
||||
__haltsystemexplicit__()
|
||||
return
|
||||
@@ -457,9 +457,9 @@ do
|
||||
::brk::
|
||||
end
|
||||
return s
|
||||
end
|
||||
end
|
||||
|
||||
local function push_onecapture(ms, i, s, e)
|
||||
local function push_onecapture(ms, i, s, e)
|
||||
if i >= ms.level then
|
||||
if i == 0 then -- ms->level == 0, too
|
||||
return s:head(e - s) -- add whole match
|
||||
@@ -475,19 +475,19 @@ local function push_onecapture(ms, i, s, e)
|
||||
return ms.capture[i].init:head(l)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function push_captures(ms, s, e)
|
||||
local function push_captures(ms, s, e)
|
||||
local nlevels = (ms.level == 0 and s) and 1 or ms.level
|
||||
local captures = {}
|
||||
for i = 0, nlevels - 1 do
|
||||
table.insert(captures, push_onecapture(ms, i, s, e))
|
||||
end
|
||||
return table.unpack(captures)
|
||||
end
|
||||
end
|
||||
|
||||
-- check whether pattern has no special characters
|
||||
local function nospecials(p)
|
||||
-- check whether pattern has no special characters
|
||||
local function nospecials(p)
|
||||
for i = 1, #p do
|
||||
for j = 1, #SPECIALS do
|
||||
if p:sub(i, i) == SPECIALS:sub(j, j) then
|
||||
@@ -496,9 +496,9 @@ local function nospecials(p)
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function str_find_aux(str, pattern, init, plain, find)
|
||||
local function str_find_aux(str, pattern, init, plain, find)
|
||||
checkArg(1, str, "string")
|
||||
checkArg(2, pattern, "string")
|
||||
checkArg(3, init, "number", "nil")
|
||||
@@ -544,17 +544,17 @@ local function str_find_aux(str, pattern, init, plain, find)
|
||||
until s1:step() > ms.src_end or anchor
|
||||
end
|
||||
return nil -- not found
|
||||
end
|
||||
end
|
||||
|
||||
local function str_find(s, pattern, init, plain)
|
||||
local function str_find(s, pattern, init, plain)
|
||||
return str_find_aux(s, pattern, init, plain, true)
|
||||
end
|
||||
end
|
||||
|
||||
local function str_match(s, pattern, init)
|
||||
local function str_match(s, pattern, init)
|
||||
return str_find_aux(s, pattern, init, false, false)
|
||||
end
|
||||
end
|
||||
|
||||
local function str_gmatch(s, pattern)
|
||||
local function str_gmatch(s, pattern)
|
||||
checkArg(1, s, "string")
|
||||
checkArg(2, pattern, "string")
|
||||
|
||||
@@ -585,9 +585,9 @@ local function str_gmatch(s, pattern)
|
||||
end
|
||||
return nil -- not found
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function add_s(ms, b, s, e, r)
|
||||
local function add_s(ms, b, s, e, r)
|
||||
local news = tostring(r)
|
||||
local i = 1
|
||||
while i <= #news do
|
||||
@@ -606,9 +606,9 @@ local function add_s(ms, b, s, e, r)
|
||||
i = i + 1
|
||||
end
|
||||
return b
|
||||
end
|
||||
end
|
||||
|
||||
local function add_value(ms, b, s, e, r, tr)
|
||||
local function add_value(ms, b, s, e, r, tr)
|
||||
local res
|
||||
if tr == "function" then
|
||||
res = r(push_captures(ms, s, e))
|
||||
@@ -623,9 +623,9 @@ local function add_value(ms, b, s, e, r, tr)
|
||||
error("invalid replacement value (a "..type(res)..")")
|
||||
end
|
||||
return b .. res -- add result to accumulator
|
||||
end
|
||||
end
|
||||
|
||||
local function str_gsub(s, pattern, repl, n)
|
||||
local function str_gsub(s, pattern, repl, n)
|
||||
checkArg(1, s, "string")
|
||||
checkArg(2, pattern, "string")
|
||||
checkArg(3, repl, "number", "string", "function", "table")
|
||||
@@ -669,55 +669,55 @@ local function str_gsub(s, pattern, repl, n)
|
||||
end
|
||||
b = b .. src:head()
|
||||
return b, n -- number of substitutions
|
||||
end
|
||||
end
|
||||
|
||||
string.find = str_find
|
||||
string.match = str_match
|
||||
string.gmatch = str_gmatch
|
||||
string.gsub = str_gsub
|
||||
string.find = str_find
|
||||
string.match = str_match
|
||||
string.gmatch = str_gmatch
|
||||
string.gsub = str_gsub
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local function spcall(...)
|
||||
local result = table.pack(pcall(...))
|
||||
if not result[1] then
|
||||
error(tostring(result[2]), 0)
|
||||
else
|
||||
return table.unpack(result, 2, result.n)
|
||||
end
|
||||
local result = table.pack(pcall(...))
|
||||
if not result[1] then
|
||||
error(tostring(result[2]), 0)
|
||||
else
|
||||
return table.unpack(result, 2, result.n)
|
||||
end
|
||||
end
|
||||
|
||||
local sgcco
|
||||
|
||||
local function sgcf(self, gc)
|
||||
while true do
|
||||
self, gc = coroutine.yield(pcall(gc, self))
|
||||
end
|
||||
while true do
|
||||
self, gc = coroutine.yield(pcall(gc, self))
|
||||
end
|
||||
end
|
||||
|
||||
local function sgc(self)
|
||||
local oldDeadline, oldHitDeadline = deadline, hitDeadline
|
||||
local mt = debug.getmetatable(self)
|
||||
mt = rawget(mt, "mt")
|
||||
local gc = rawget(mt, "__gc")
|
||||
if type(gc) ~= "function" then
|
||||
return
|
||||
end
|
||||
if not sgcco then
|
||||
sgcco = coroutine.create(sgcf)
|
||||
end
|
||||
debug.sethook(sgcco, checkDeadline, "", hookInterval)
|
||||
deadline, hitDeadline = math.min(oldDeadline, computer.realTime() + 0.5), true
|
||||
local _, result, reason = coroutine.resume(sgcco, self, gc)
|
||||
debug.sethook(sgcco)
|
||||
if coroutine.status(sgcco) == "dead" then
|
||||
sgcco = nil
|
||||
end
|
||||
deadline, hitDeadline = oldDeadline, oldHitDeadline
|
||||
if not result then
|
||||
error(reason, 0)
|
||||
end
|
||||
local oldDeadline, oldHitDeadline = deadline, hitDeadline
|
||||
local mt = debug.getmetatable(self)
|
||||
mt = rawget(mt, "mt")
|
||||
local gc = rawget(mt, "__gc")
|
||||
if type(gc) ~= "function" then
|
||||
return
|
||||
end
|
||||
if not sgcco then
|
||||
sgcco = coroutine.create(sgcf)
|
||||
end
|
||||
debug.sethook(sgcco, checkDeadline, "", hookInterval)
|
||||
deadline, hitDeadline = math.min(oldDeadline, computer.realTime() + 0.5), true
|
||||
local _, result, reason = coroutine.resume(sgcco, self, gc)
|
||||
debug.sethook(sgcco)
|
||||
if coroutine.status(sgcco) == "dead" then
|
||||
sgcco = nil
|
||||
end
|
||||
deadline, hitDeadline = oldDeadline, oldHitDeadline
|
||||
if not result then
|
||||
error(reason, 0)
|
||||
end
|
||||
end
|
||||
|
||||
--[[ This is the global environment we make available to userland programs. ]]
|
||||
@@ -727,262 +727,262 @@ end
|
||||
-- persisted.
|
||||
local sandbox, libprocess
|
||||
sandbox = {
|
||||
assert = assert,
|
||||
dofile = nil, -- in boot/*_base.lua
|
||||
error = error,
|
||||
_G = nil, -- see below
|
||||
getmetatable = function(t)
|
||||
if type(t) == "string" then -- don't allow messing with the string mt
|
||||
return nil
|
||||
end
|
||||
local result = getmetatable(t)
|
||||
-- check if we have a wrapped __gc using mt
|
||||
if type(result) == "table" and system.allowGC() and rawget(result, "__gc") == sgc then
|
||||
result = rawget(result, "mt")
|
||||
end
|
||||
return result
|
||||
end,
|
||||
ipairs = ipairs,
|
||||
load = function(ld, source, mode, env)
|
||||
if not system.allowBytecode() then
|
||||
mode = "t"
|
||||
end
|
||||
return load(ld, source, mode, env or sandbox)
|
||||
end,
|
||||
loadfile = nil, -- in boot/*_base.lua
|
||||
next = next,
|
||||
pairs = pairs,
|
||||
pcall = function(...)
|
||||
local result = table.pack(pcall(...))
|
||||
checkDeadline()
|
||||
return table.unpack(result, 1, result.n)
|
||||
end,
|
||||
print = nil, -- in boot/*_base.lua
|
||||
rawequal = rawequal,
|
||||
rawget = rawget,
|
||||
rawlen = rawlen,
|
||||
rawset = rawset,
|
||||
select = select,
|
||||
setmetatable = function(t, mt)
|
||||
if type(mt) ~= "table" then
|
||||
return setmetatable(t, mt)
|
||||
end
|
||||
if rawget(mt, "__gc") ~= nil then -- If __gc is set to ANYTHING not `nil`, we're gonna have issues
|
||||
-- Garbage collector callbacks apparently can't be sandboxed after
|
||||
-- all, because hooks are disabled while they're running. So we just
|
||||
-- disable them altogether by default.
|
||||
if system.allowGC() then
|
||||
-- For all user __gc functions we enforce a much tighter deadline.
|
||||
-- This is because these functions may be called from the main
|
||||
-- thread under certain circumstanced (such as when saving the world),
|
||||
-- which can lead to noticeable lag if the __gc function behaves badly.
|
||||
local sbmt = {} -- sandboxed metatable. only for __gc stuff, so it's
|
||||
-- kinda ok to have a shallow copy instead... meh.
|
||||
for k, v in next, mt do
|
||||
sbmt[k] = v
|
||||
end
|
||||
sbmt.__gc = sgc
|
||||
sbmt.mt = mt
|
||||
mt = sbmt
|
||||
else
|
||||
-- Don't allow marking for finalization, but use the raw metatable.
|
||||
local gc = rawget(mt, "__gc")
|
||||
rawset(mt, "__gc", nil) -- remove __gc
|
||||
local ret = table.pack(pcall(setmetatable, t, mt))
|
||||
rawset(mt, "__gc", gc) -- restore __gc
|
||||
if not ret[1] then error(ret[2], 0) end
|
||||
return table.unpack(ret, 2, ret.n)
|
||||
end
|
||||
end
|
||||
return setmetatable(t, mt)
|
||||
end,
|
||||
tonumber = tonumber,
|
||||
tostring = tostring,
|
||||
type = type,
|
||||
_VERSION = _VERSION:match("5.3") and "Lua 5.3" or "Lua 5.2",
|
||||
xpcall = function(f, msgh, ...)
|
||||
local handled = false
|
||||
local result = table.pack(xpcall(f, function(...)
|
||||
if handled then
|
||||
return ...
|
||||
else
|
||||
handled = true
|
||||
return msgh(...)
|
||||
end
|
||||
end, ...))
|
||||
checkDeadline()
|
||||
return table.unpack(result, 1, result.n)
|
||||
end,
|
||||
assert = assert,
|
||||
dofile = nil, -- in boot/*_base.lua
|
||||
error = error,
|
||||
_G = nil, -- see below
|
||||
getmetatable = function(t)
|
||||
if type(t) == "string" then -- don't allow messing with the string mt
|
||||
return nil
|
||||
end
|
||||
local result = getmetatable(t)
|
||||
-- check if we have a wrapped __gc using mt
|
||||
if type(result) == "table" and system.allowGC() and rawget(result, "__gc") == sgc then
|
||||
result = rawget(result, "mt")
|
||||
end
|
||||
return result
|
||||
end,
|
||||
ipairs = ipairs,
|
||||
load = function(ld, source, mode, env)
|
||||
if not system.allowBytecode() then
|
||||
mode = "t"
|
||||
end
|
||||
return load(ld, source, mode, env or sandbox)
|
||||
end,
|
||||
loadfile = nil, -- in boot/*_base.lua
|
||||
next = next,
|
||||
pairs = pairs,
|
||||
pcall = function(...)
|
||||
local result = table.pack(pcall(...))
|
||||
checkDeadline()
|
||||
return table.unpack(result, 1, result.n)
|
||||
end,
|
||||
print = nil, -- in boot/*_base.lua
|
||||
rawequal = rawequal,
|
||||
rawget = rawget,
|
||||
rawlen = rawlen,
|
||||
rawset = rawset,
|
||||
select = select,
|
||||
setmetatable = function(t, mt)
|
||||
if type(mt) ~= "table" then
|
||||
return setmetatable(t, mt)
|
||||
end
|
||||
if rawget(mt, "__gc") ~= nil then -- If __gc is set to ANYTHING not `nil`, we're gonna have issues
|
||||
-- Garbage collector callbacks apparently can't be sandboxed after
|
||||
-- all, because hooks are disabled while they're running. So we just
|
||||
-- disable them altogether by default.
|
||||
if system.allowGC() then
|
||||
-- For all user __gc functions we enforce a much tighter deadline.
|
||||
-- This is because these functions may be called from the main
|
||||
-- thread under certain circumstanced (such as when saving the world),
|
||||
-- which can lead to noticeable lag if the __gc function behaves badly.
|
||||
local sbmt = {} -- sandboxed metatable. only for __gc stuff, so it's
|
||||
-- kinda ok to have a shallow copy instead... meh.
|
||||
for k, v in next, mt do
|
||||
sbmt[k] = v
|
||||
end
|
||||
sbmt.__gc = sgc
|
||||
sbmt.mt = mt
|
||||
mt = sbmt
|
||||
else
|
||||
-- Don't allow marking for finalization, but use the raw metatable.
|
||||
local gc = rawget(mt, "__gc")
|
||||
rawset(mt, "__gc", nil) -- remove __gc
|
||||
local ret = table.pack(pcall(setmetatable, t, mt))
|
||||
rawset(mt, "__gc", gc) -- restore __gc
|
||||
if not ret[1] then error(ret[2], 0) end
|
||||
return table.unpack(ret, 2, ret.n)
|
||||
end
|
||||
end
|
||||
return setmetatable(t, mt)
|
||||
end,
|
||||
tonumber = tonumber,
|
||||
tostring = tostring,
|
||||
type = type,
|
||||
_VERSION = _VERSION:match("5.3") and "Lua 5.3" or "Lua 5.2",
|
||||
xpcall = function(f, msgh, ...)
|
||||
local handled = false
|
||||
local result = table.pack(xpcall(f, function(...)
|
||||
if handled then
|
||||
return ...
|
||||
else
|
||||
handled = true
|
||||
return msgh(...)
|
||||
end
|
||||
end, ...))
|
||||
checkDeadline()
|
||||
return table.unpack(result, 1, result.n)
|
||||
end,
|
||||
|
||||
coroutine = {
|
||||
create = coroutine.create,
|
||||
resume = function(co, ...) -- custom resume part for bubbling sysyields
|
||||
checkArg(1, co, "thread")
|
||||
local args = table.pack(...)
|
||||
while true do -- for consecutive sysyields
|
||||
debug.sethook(co, checkDeadline, "", hookInterval)
|
||||
local result = table.pack(
|
||||
coroutine.resume(co, table.unpack(args, 1, args.n)))
|
||||
debug.sethook(co) -- avoid gc issues
|
||||
checkDeadline()
|
||||
if result[1] then -- success: (true, sysval?, ...?)
|
||||
if coroutine.status(co) == "dead" then -- return: (true, ...)
|
||||
return true, table.unpack(result, 2, result.n)
|
||||
elseif result[2] ~= nil then -- yield: (true, sysval)
|
||||
args = table.pack(coroutine.yield(result[2]))
|
||||
else -- yield: (true, nil, ...)
|
||||
return true, table.unpack(result, 3, result.n)
|
||||
end
|
||||
else -- error: result = (false, string)
|
||||
return false, result[2]
|
||||
end
|
||||
end
|
||||
end,
|
||||
running = coroutine.running,
|
||||
status = coroutine.status,
|
||||
wrap = function(f) -- for bubbling coroutine.resume
|
||||
local co = coroutine.create(f)
|
||||
return function(...)
|
||||
local result = table.pack(sandbox.coroutine.resume(co, ...))
|
||||
if result[1] then
|
||||
return table.unpack(result, 2, result.n)
|
||||
else
|
||||
error(result[2], 0)
|
||||
end
|
||||
end
|
||||
end,
|
||||
yield = function(...) -- custom yield part for bubbling sysyields
|
||||
return coroutine.yield(nil, ...)
|
||||
end
|
||||
},
|
||||
coroutine = {
|
||||
create = coroutine.create,
|
||||
resume = function(co, ...) -- custom resume part for bubbling sysyields
|
||||
checkArg(1, co, "thread")
|
||||
local args = table.pack(...)
|
||||
while true do -- for consecutive sysyields
|
||||
debug.sethook(co, checkDeadline, "", hookInterval)
|
||||
local result = table.pack(
|
||||
coroutine.resume(co, table.unpack(args, 1, args.n)))
|
||||
debug.sethook(co) -- avoid gc issues
|
||||
checkDeadline()
|
||||
if result[1] then -- success: (true, sysval?, ...?)
|
||||
if coroutine.status(co) == "dead" then -- return: (true, ...)
|
||||
return true, table.unpack(result, 2, result.n)
|
||||
elseif result[2] ~= nil then -- yield: (true, sysval)
|
||||
args = table.pack(coroutine.yield(result[2]))
|
||||
else -- yield: (true, nil, ...)
|
||||
return true, table.unpack(result, 3, result.n)
|
||||
end
|
||||
else -- error: result = (false, string)
|
||||
return false, result[2]
|
||||
end
|
||||
end
|
||||
end,
|
||||
running = coroutine.running,
|
||||
status = coroutine.status,
|
||||
wrap = function(f) -- for bubbling coroutine.resume
|
||||
local co = coroutine.create(f)
|
||||
return function(...)
|
||||
local result = table.pack(sandbox.coroutine.resume(co, ...))
|
||||
if result[1] then
|
||||
return table.unpack(result, 2, result.n)
|
||||
else
|
||||
error(result[2], 0)
|
||||
end
|
||||
end
|
||||
end,
|
||||
yield = function(...) -- custom yield part for bubbling sysyields
|
||||
return coroutine.yield(nil, ...)
|
||||
end
|
||||
},
|
||||
|
||||
string = {
|
||||
byte = string.byte,
|
||||
char = string.char,
|
||||
dump = string.dump,
|
||||
find = string.find,
|
||||
format = string.format,
|
||||
gmatch = string.gmatch,
|
||||
gsub = string.gsub,
|
||||
len = string.len,
|
||||
lower = string.lower,
|
||||
match = string.match,
|
||||
rep = string.rep,
|
||||
reverse = string.reverse,
|
||||
sub = string.sub,
|
||||
upper = string.upper
|
||||
},
|
||||
string = {
|
||||
byte = string.byte,
|
||||
char = string.char,
|
||||
dump = string.dump,
|
||||
find = string.find,
|
||||
format = string.format,
|
||||
gmatch = string.gmatch,
|
||||
gsub = string.gsub,
|
||||
len = string.len,
|
||||
lower = string.lower,
|
||||
match = string.match,
|
||||
rep = string.rep,
|
||||
reverse = string.reverse,
|
||||
sub = string.sub,
|
||||
upper = string.upper
|
||||
},
|
||||
|
||||
table = {
|
||||
concat = table.concat,
|
||||
insert = table.insert,
|
||||
pack = table.pack,
|
||||
remove = table.remove,
|
||||
sort = table.sort,
|
||||
unpack = table.unpack
|
||||
},
|
||||
table = {
|
||||
concat = table.concat,
|
||||
insert = table.insert,
|
||||
pack = table.pack,
|
||||
remove = table.remove,
|
||||
sort = table.sort,
|
||||
unpack = table.unpack
|
||||
},
|
||||
|
||||
math = {
|
||||
abs = math.abs,
|
||||
acos = math.acos,
|
||||
asin = math.asin,
|
||||
atan = math.atan,
|
||||
atan2 = math.atan2,
|
||||
ceil = math.ceil,
|
||||
cos = math.cos,
|
||||
cosh = math.cosh,
|
||||
deg = math.deg,
|
||||
exp = math.exp,
|
||||
floor = math.floor,
|
||||
fmod = math.fmod,
|
||||
frexp = math.frexp,
|
||||
huge = math.huge,
|
||||
ldexp = math.ldexp,
|
||||
log = math.log,
|
||||
max = math.max,
|
||||
min = math.min,
|
||||
modf = math.modf,
|
||||
pi = math.pi,
|
||||
pow = math.pow or function(a, b) -- Deprecated in Lua 5.3
|
||||
return a^b
|
||||
end,
|
||||
rad = math.rad,
|
||||
random = function(...)
|
||||
return spcall(math.random, ...)
|
||||
end,
|
||||
randomseed = function(seed)
|
||||
spcall(math.randomseed, seed)
|
||||
end,
|
||||
sin = math.sin,
|
||||
sinh = math.sinh,
|
||||
sqrt = math.sqrt,
|
||||
tan = math.tan,
|
||||
tanh = math.tanh
|
||||
},
|
||||
math = {
|
||||
abs = math.abs,
|
||||
acos = math.acos,
|
||||
asin = math.asin,
|
||||
atan = math.atan,
|
||||
atan2 = math.atan2,
|
||||
ceil = math.ceil,
|
||||
cos = math.cos,
|
||||
cosh = math.cosh,
|
||||
deg = math.deg,
|
||||
exp = math.exp,
|
||||
floor = math.floor,
|
||||
fmod = math.fmod,
|
||||
frexp = math.frexp,
|
||||
huge = math.huge,
|
||||
ldexp = math.ldexp,
|
||||
log = math.log,
|
||||
max = math.max,
|
||||
min = math.min,
|
||||
modf = math.modf,
|
||||
pi = math.pi,
|
||||
pow = math.pow or function(a, b) -- Deprecated in Lua 5.3
|
||||
return a^b
|
||||
end,
|
||||
rad = math.rad,
|
||||
random = function(...)
|
||||
return spcall(math.random, ...)
|
||||
end,
|
||||
randomseed = function(seed)
|
||||
spcall(math.randomseed, seed)
|
||||
end,
|
||||
sin = math.sin,
|
||||
sinh = math.sinh,
|
||||
sqrt = math.sqrt,
|
||||
tan = math.tan,
|
||||
tanh = math.tanh
|
||||
},
|
||||
|
||||
-- Deprecated in Lua 5.3.
|
||||
bit32 = bit32 and {
|
||||
arshift = bit32.arshift,
|
||||
band = bit32.band,
|
||||
bnot = bit32.bnot,
|
||||
bor = bit32.bor,
|
||||
btest = bit32.btest,
|
||||
bxor = bit32.bxor,
|
||||
extract = bit32.extract,
|
||||
replace = bit32.replace,
|
||||
lrotate = bit32.lrotate,
|
||||
lshift = bit32.lshift,
|
||||
rrotate = bit32.rrotate,
|
||||
rshift = bit32.rshift
|
||||
},
|
||||
-- Deprecated in Lua 5.3.
|
||||
bit32 = bit32 and {
|
||||
arshift = bit32.arshift,
|
||||
band = bit32.band,
|
||||
bnot = bit32.bnot,
|
||||
bor = bit32.bor,
|
||||
btest = bit32.btest,
|
||||
bxor = bit32.bxor,
|
||||
extract = bit32.extract,
|
||||
replace = bit32.replace,
|
||||
lrotate = bit32.lrotate,
|
||||
lshift = bit32.lshift,
|
||||
rrotate = bit32.rrotate,
|
||||
rshift = bit32.rshift
|
||||
},
|
||||
|
||||
io = nil, -- in lib/io.lua
|
||||
io = nil, -- in lib/io.lua
|
||||
|
||||
os = {
|
||||
clock = os.clock,
|
||||
date = function(format, time)
|
||||
return spcall(os.date, format, time)
|
||||
end,
|
||||
difftime = function(t2, t1)
|
||||
return t2 - t1
|
||||
end,
|
||||
execute = nil, -- in boot/*_os.lua
|
||||
exit = nil, -- in boot/*_os.lua
|
||||
remove = nil, -- in boot/*_os.lua
|
||||
rename = nil, -- in boot/*_os.lua
|
||||
time = function(table)
|
||||
checkArg(1, table, "table", "nil")
|
||||
return os.time(table)
|
||||
end,
|
||||
tmpname = nil, -- in boot/*_os.lua
|
||||
},
|
||||
os = {
|
||||
clock = os.clock,
|
||||
date = function(format, time)
|
||||
return spcall(os.date, format, time)
|
||||
end,
|
||||
difftime = function(t2, t1)
|
||||
return t2 - t1
|
||||
end,
|
||||
execute = nil, -- in boot/*_os.lua
|
||||
exit = nil, -- in boot/*_os.lua
|
||||
remove = nil, -- in boot/*_os.lua
|
||||
rename = nil, -- in boot/*_os.lua
|
||||
time = function(table)
|
||||
checkArg(1, table, "table", "nil")
|
||||
return os.time(table)
|
||||
end,
|
||||
tmpname = nil, -- in boot/*_os.lua
|
||||
},
|
||||
|
||||
debug = {
|
||||
getinfo = function(...)
|
||||
local result = debug.getinfo(...)
|
||||
if result then
|
||||
-- Only make primitive information available in the sandbox.
|
||||
return {
|
||||
source = result.source,
|
||||
short_src = result.short_src,
|
||||
linedefined = result.linedefined,
|
||||
lastlinedefined = result.lastlinedefined,
|
||||
what = result.what,
|
||||
currentline = result.currentline,
|
||||
nups = result.nups,
|
||||
nparams = result.nparams,
|
||||
isvararg = result.isvararg,
|
||||
name = result.name,
|
||||
namewhat = result.namewhat,
|
||||
istailcall = result.istailcall
|
||||
}
|
||||
end
|
||||
end,
|
||||
traceback = debug.traceback
|
||||
},
|
||||
debug = {
|
||||
getinfo = function(...)
|
||||
local result = debug.getinfo(...)
|
||||
if result then
|
||||
-- Only make primitive information available in the sandbox.
|
||||
return {
|
||||
source = result.source,
|
||||
short_src = result.short_src,
|
||||
linedefined = result.linedefined,
|
||||
lastlinedefined = result.lastlinedefined,
|
||||
what = result.what,
|
||||
currentline = result.currentline,
|
||||
nups = result.nups,
|
||||
nparams = result.nparams,
|
||||
isvararg = result.isvararg,
|
||||
name = result.name,
|
||||
namewhat = result.namewhat,
|
||||
istailcall = result.istailcall
|
||||
}
|
||||
end
|
||||
end,
|
||||
traceback = debug.traceback
|
||||
},
|
||||
|
||||
|
||||
checkArg = checkArg
|
||||
checkArg = checkArg
|
||||
}
|
||||
sandbox._G = sandbox
|
||||
|
||||
|
||||
@@ -311,7 +311,7 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
||||
beepCursor = 0
|
||||
}
|
||||
|
||||
// continue emitTone queue
|
||||
// advance emitTone queue
|
||||
if (beepCursor >= 0 && beepQueueLineExecTimer >= beepQueueGetLenOfPtn(beepCursor)) {
|
||||
beepQueueLineExecTimer -= beepQueueGetLenOfPtn(beepCursor)
|
||||
beepCursor += 1
|
||||
@@ -321,7 +321,6 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
||||
// complete emitTone queue
|
||||
if (beepCursor >= beepQueue.size) {
|
||||
clearBeepQueue()
|
||||
AL.destroy()
|
||||
if (DEBUG) println("[BaseTerrarumComputer] !! Beep queue clear")
|
||||
}
|
||||
|
||||
@@ -329,6 +328,12 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
||||
if (beepCursor >= 0 && beepQueue.size > 0 && !beepQueueFired) {
|
||||
playTone(beepQueue[beepCursor].first, beepQueue[beepCursor].second)
|
||||
beepQueueFired = true
|
||||
|
||||
// delete sources that is finished. AL is limited to 256 sources. If you exceed it,
|
||||
// we won't get any more sounds played.
|
||||
AL10.alSourcei(oldBeepSource, AL10.AL_BUFFER, 0)
|
||||
AL10.alDeleteSources(oldBeepSource)
|
||||
AL10.alDeleteBuffers(oldBeepBuffer)
|
||||
}
|
||||
|
||||
if (beepQueueFired) beepQueueLineExecTimer += delta
|
||||
@@ -338,6 +343,8 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
||||
beepQueue.clear()
|
||||
beepCursor = -1
|
||||
beepQueueLineExecTimer = 0
|
||||
|
||||
//AL.destroy()
|
||||
}
|
||||
|
||||
fun enqueueBeep(duration: Int, freq: Double) {
|
||||
@@ -352,8 +359,10 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
||||
////////////////////
|
||||
|
||||
private val sampleRate = 44100
|
||||
private var beepSource: Int? = null
|
||||
private var beepBuffer: Int? = null
|
||||
private var beepSource: Int = -1
|
||||
private var beepBuffer: Int = -1
|
||||
private var oldBeepSource: Int = -1
|
||||
private var oldBeepBuffer: Int = -1
|
||||
var audioData: ByteBuffer? = null
|
||||
|
||||
/**
|
||||
@@ -424,36 +433,37 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
||||
// Clear error stack.
|
||||
AL10.alGetError()
|
||||
|
||||
oldBeepBuffer = beepBuffer
|
||||
beepBuffer = AL10.alGenBuffers()
|
||||
checkALError()
|
||||
|
||||
try {
|
||||
AL10.alBufferData(beepBuffer!!, AL10.AL_FORMAT_MONO8, audioData, sampleRate)
|
||||
AL10.alBufferData(beepBuffer, AL10.AL_FORMAT_MONO8, audioData, sampleRate)
|
||||
checkALError()
|
||||
|
||||
oldBeepSource = beepSource
|
||||
beepSource = AL10.alGenSources()
|
||||
checkALError()
|
||||
|
||||
try {
|
||||
AL10.alSourceQueueBuffers(beepSource!!, beepBuffer!!)
|
||||
AL10.alSourceQueueBuffers(beepSource, beepBuffer)
|
||||
checkALError()
|
||||
|
||||
AL10.alSource3f(beepSource!!, AL10.AL_POSITION, 0f, 0f, 1f)
|
||||
AL10.alSourcef(beepSource!!, AL10.AL_REFERENCE_DISTANCE, 1f)
|
||||
AL10.alSourcef(beepSource!!, AL10.AL_MAX_DISTANCE, 1f)
|
||||
AL10.alSourcef(beepSource!!, AL10.AL_GAIN, 0.3f)
|
||||
AL10.alSource3f(beepSource, AL10.AL_POSITION, 0f, 0f, 1f)
|
||||
AL10.alSourcef(beepSource, AL10.AL_REFERENCE_DISTANCE, 1f)
|
||||
AL10.alSourcef(beepSource, AL10.AL_MAX_DISTANCE, 1f)
|
||||
AL10.alSourcef(beepSource, AL10.AL_GAIN, 0.3f)
|
||||
checkALError()
|
||||
|
||||
AL10.alSourcePlay(beepSource!!)
|
||||
AL10.alSourcePlay(beepSource)
|
||||
checkALError()
|
||||
|
||||
}
|
||||
catch (e: ALException) {
|
||||
AL10.alDeleteSources(beepSource!!)
|
||||
AL10.alDeleteSources(beepSource)
|
||||
}
|
||||
}
|
||||
catch (e: ALException) {
|
||||
if (beepSource != null) AL10.alDeleteSources(beepSource!!)
|
||||
AL10.alDeleteSources(beepSource)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user