mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-16 17:32:13 +00:00
fdfcca557b
Also fix error handling path in our_require(), i.e. when loadstring fails. git-svn-id: https://svn.eduke32.com/eduke32@2857 1a8010ca-5511-0410-912e-c29ae57300e0
78 lines
1.9 KiB
Lua
78 lines
1.9 KiB
Lua
-- Pseudo random number generation module for Lunatic
|
|
|
|
local ffi = require("ffi")
|
|
local ffiC = ffi.C
|
|
|
|
local rawset = rawset
|
|
|
|
local type = type
|
|
local gv = gv_tmp -- temporarily set in defs.c
|
|
|
|
local print = print -- for commented out debug block in new() below
|
|
|
|
module(...)
|
|
|
|
|
|
-- NOTE: PRNG state struct and functions are declared in defs.ilua
|
|
|
|
ffi.cdef[[
|
|
typedef union { unsigned char u[16]; double d[2]; } uchar_double_u_t;
|
|
typedef union { unsigned char u[16]; uint32_t i[4]; } uchar_uint_u_t;
|
|
]]
|
|
|
|
local mt = {
|
|
__tostring = function(s)
|
|
return "rand.new("..s.x..","..s.y..","..s.z..","..s.c..")"
|
|
end,
|
|
|
|
__index = {
|
|
getu32 = ffiC.rand_jkiss_u32,
|
|
getdbl = ffiC.rand_jkiss_dbl,
|
|
|
|
-- Initialize the JKISS PRNG using the MD4 of the lower bits of the
|
|
-- profiling timer
|
|
init_time_md4 = function(s)
|
|
local tin = ffi.new("uchar_double_u_t")
|
|
local tout = ffi.new("uchar_uint_u_t")
|
|
|
|
repeat
|
|
tin.d[0] = gv.gethitickms() % 1
|
|
tin.d[1] = gv.gethitickms() % 1
|
|
|
|
ffiC.md4once(tin.u, 16, tout.u)
|
|
|
|
s.y = tout.u[1]
|
|
until (s.y ~= 0) -- y must not be zero!
|
|
|
|
s.x = tout.u[0]
|
|
s.z = tout.u[2]
|
|
s.c = tout.u[3] % 698769068 + 1 -- Should be less than 698769069
|
|
end,
|
|
},
|
|
}
|
|
local jkiss = ffi.metatype("rng_jkiss_t", mt)
|
|
|
|
function new(x,y,z,c)
|
|
local s
|
|
if (x == nil or type(x)=="boolean") then
|
|
s = jkiss(0,0,0,0) -- invalid state, must be initialized first
|
|
if (x) then
|
|
s:init_time_md4()
|
|
end
|
|
else
|
|
s = jkiss(x,y,z,c)
|
|
end
|
|
--[[
|
|
print("TEST")
|
|
local r=ffi.new("rng_jkiss_t")
|
|
r.x = 123456789; r.y = 987654321; r.z = 43219876; r.c = 6543217;
|
|
|
|
t=gv.gethitickms()
|
|
for i=1,4*2*1e6 do
|
|
ffiC.rand_jkiss_dbl(r)
|
|
end
|
|
print("TIME: "..gv.gethitickms()-t) -- x86_64: approx. 100 ms
|
|
--]]
|
|
|
|
return s
|
|
end
|