summaryrefslogtreecommitdiff
path: root/data/item_fence.png
blob: 76a4618789c8b7f5bc9d50acd1fb3b14b6f17691 (plain)
ofshex dumpascii
0000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 10 00 00 00 10 08 02 00 00 00 90 91 68 .PNG........IHDR...............h
0020 36 00 00 03 00 50 4c 54 45 00 00 00 ff 00 00 00 ff 00 ff ff 00 00 00 ff ff 00 ff 00 ff ff ff ff 6....PLTE.......................
0040 ff db db db b6 b6 b6 92 92 92 6d 6d 6d 49 49 49 24 24 24 db 00 00 b6 00 00 92 00 00 6d 00 00 49 ..........mmmIII$$$.........m..I
0060 00 00 24 00 00 00 db 00 00 b6 00 00 92 00 00 6d 00 00 49 00 00 24 00 db db 00 b6 b6 00 92 92 00 ..$............m..I..$..........
0080 6d 6d 00 49 49 00 24 24 00 00 00 db 00 00 b6 00 00 92 00 00 6d 00 00 49 00 00 24 db 00 db b6 00 mm.II.$$............m..I..$.....
00a0 b6 92 00 92 6d 00 6d 49 00 49 24 00 24 00 db db 00 b6 b6 00 92 92 00 6d 6d 00 49 49 00 24 24 ff ....m.mI.I$.$..........mm.II.$$.
00c0 db db db b6 b6 b6 92 92 92 6d 6d 6d 49 49 49 24 24 ff b6 b6 db 92 92 b6 6d 6d 92 49 49 6d 24 24 .........mmmIII$$.......mm.IIm$$
00e0 ff 92 92 db 6d 6d b6 49 49 92 24 24 ff 6d 6d db 49 49 b6 24 24 ff 49 49 db 24 24 ff 24 24 db ff ....mm.II.$$.mm.II.$$.II.$$.$$..
0100 db b6 db b6 92 b6 92 6d 92 6d 49 6d 49 24 49 24 b6 ff b6 92 db 92 6d b6 6d 49 92 49 24 6d 24 92 .......m.mImI$I$......m.mI.I$m$.
0120 ff 92 6d db 6d 49 b6 49 24 92 24 6d ff 6d 49 db 49 24 b6 24 49 ff 49 24 db 24 24 ff 24 db db ff ..m.mI.I$.$m.mI.I$.$I.I$.$$.$...
0140 b6 b6 db 92 92 b6 6d 6d 92 49 49 6d 24 24 49 b6 b6 ff 92 92 db 6d 6d b6 49 49 92 24 24 6d 92 92 ......mm.IIm$$I......mm.II.$$m..
0160 ff 6d 6d db 49 49 b6 24 24 92 6d 6d ff 49 49 db 24 24 b6 49 49 ff 24 24 db 24 24 ff ff ff db db .mm.II.$$.mm.II.$$.II.$$.$$.....
0180 db b6 b6 b6 92 92 92 6d 6d 6d 49 49 49 24 ff ff b6 db db 92 b6 b6 6d 92 92 49 6d 6d 24 ff ff 92 .......mmmIII$........m..Imm$...
01a0 db db 6d b6 b6 49 92 92 24 ff ff 6d db db 49 b6 b6 24 ff ff 49 db db 24 ff ff 24 ff db ff db b6 ..m..I..$..m..I..$..I..$..$.....
01c0 db b6 92 b6 92 6d 92 6d 49 6d 49 24 49 ff b6 ff db 92 db b6 6d b6 92 49 92 6d 24 6d ff 92 ff db .....m.mImI$I.......m..I.m$m....
01e0 6d db b6 49 b6 92 24 92 ff 6d ff db 49 db b6 24 b6 ff 49 ff db 24 db ff 24 ff db ff ff b6 db db m..I..$..m..I..$..I..$..$.......
0200 92 b6 b6 6d 92 92 49 6d 6d 24 49 49 b6 ff ff 92 db db 6d b6 b6 49 92 92 24 6d 6d 92 ff ff 6d db ...m..Imm$II......m..I..$mm...m.
0220 db 49 b6 b6 24 92 92 6d ff ff 49 db db 24 b6 b6 49 ff ff 24 db db 24 ff ff ff db b6 db b6 92 b6 .I..$..m..I..$..I..$..$.........
0240 92 6d 92 6d 49 6d 49 24 49 24 00 ff b6 92 db 92 6d b6 6d 49 92 49 24 6d 24 00 ff b6 db db 92 b6 .m.mImI$I$......m.mI.I$m$.......
0260 b6 6d 92 92 49 6d 6d 24 49 49 00 24 ff 92 b6 db 6d 92 b6 49 6d 92 24 49 6d 00 24 db b6 ff b6 92 .m..Imm$II.$....m..Im.$Im.$.....
0280 db 92 6d b6 6d 49 92 49 24 6d 24 00 49 b6 92 ff 92 6d db 6d 49 b6 49 24 92 24 00 6d b6 db ff 92 ..m.mI.I$m$.I....m.mI.I$.$.m....
02a0 b6 db 6d 92 b6 49 6d 92 24 49 6d 00 24 49 92 b6 ff 6d 92 db 49 6d b6 24 49 92 00 24 6d b6 ff db ..m..Im.$Im.$I...m..Im.$I..$m...
02c0 92 db b6 6d b6 92 49 92 6d 24 6d 49 00 49 24 92 ff b6 6d db 92 49 b6 6d 24 92 49 00 6d 24 db ff ...m..I.m$mI.I$...m..I.m$.I.m$..
02e0 b6 b6 db 92 92 b6 6d 6d 92 49 49 6d 24 24 49 00 b6 ff 92 92 db 6d 6d b6 49 49 92 24 24 6d 00 ff ......mm.IIm$$I......mm.II.$$m..
0300 b6 00 db 92 00 b6 6d 00 92 49 00 ff 00 b6 db 00 92 b6 00 6d 92 00 49 00 b6 ff 00 92 db 00 6d b6 ......m..I.........m..I.......m.
0320 00 49 92 00 00 00 00 00 00 cf 2a 02 04 00 00 01 ab 49 44 41 54 28 cf b5 92 4b 8a 14 41 10 86 ff .I........*......IDAT(...K..A...
0340 cc 8c ac ac 47 56 f7 d4 14 d3 22 ee 04 97 e2 66 66 96 9e c0 8d e0 c6 85 27 90 d9 78 84 41 8f 20 ....GV...."....ff.......'..x.A..
0360 78 00 11 4f e0 03 75 dd e0 05 84 d9 88 82 88 34 4e 3f ea 95 55 99 95 e9 a6 96 dd 4b 63 1d df 1f x..O..u........4N?..U......Kc...
0380 f1 05 01 fc ef 62 00 2e 1e dc 52 44 5d 67 5e 7e fc b3 b7 e9 f9 93 db bd 1d 19 70 f9 f6 07 01 58 .....b....RD]g^~..........p....X
03a0 f7 dc ac 1b 8e f1 50 ea 28 f2 e0 6d 00 00 70 00 c2 b7 b3 38 70 6f 0f 01 e5 e2 e4 a8 2c 88 d9 69 ......P.(..m..p....8po......,..i
03c0 a5 7b 27 4c 46 a4 b8 ab 87 e0 1c 32 89 d1 22 61 50 09 00 14 5a 34 96 c7 84 1b 85 7a b5 ac 09 c0 .{'LF......2.."aP...Z4.....z....
03e0 e3 47 e7 ce 54 b5 27 c7 23 20 74 cd 36 78 cf 31 28 12 08 34 cb 75 24 09 a4 b4 4e b0 fc 42 00 94 .G..T.'.#.t.6x.1(..4.u$...N..B..
0400 9e 07 52 b9 4c 98 9a 99 be 57 b3 05 82 63 f0 3c 8c 9c 84 62 44 8a 88 58 3f 38 00 04 20 bf 79 27 ..R.L....W...c.<...bD..X?8....y'
0420 73 6d 5d f7 cf 2e df ec 75 78 71 71 5f 66 71 12 45 13 b0 fa 79 c5 24 05 db 1d 92 e6 49 16 54 96 sm].....uxqq_fq.E...y.$.....I.T.
0440 1e 2f 26 e0 c3 fb af 81 84 75 07 cf fa f9 dd 52 17 85 4e e3 09 b8 7b 7e 6a ad e5 c1 9d 9d 0a 92 ./&......u.....R..N...{~j.......
0460 22 99 17 82 03 ce fa d1 57 95 d9 5c 6f 83 0f 79 16 27 59 06 7c 23 00 cd ce b4 f5 ee 7a 53 b7 6d ".......W..\o..y.'Y.|#......zS.m
0480 9f 51 88 95 04 13 c6 8e b1 92 f0 3c 9f a7 d6 79 ef 42 18 d9 34 81 33 e8 23 cd 46 57 6a c9 49 34 .Q.........<...y.B..4.3.#.FWj.I4
04a0 66 20 8a 52 ce d2 38 1e 06 5b 96 c7 8c f3 58 45 8a 30 01 a3 a9 aa 7a 97 24 e9 eb 4f 57 7b 1d 9e f..R..8..[....XE.0....z.$..OW{..
04c0 3e 3c 53 42 cb 54 4f c0 df ad 69 3a fb fd f7 af 83 2f ea cc 6a d5 6d 36 6b 00 ff 00 d2 f9 af cb ><SB.TO...i:...../..j.m6k.......
04e0 9b ed ca 2f 00 00 00 00 49 45 4e 44 ae 42 60 82 .../....IEND.B`.
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "lua_api/l_noise.h"
#include "lua_api/l_internal.h"
#include "common/c_converter.h"
#include "common/c_content.h"
#include "log.h"
#include "porting.h"
#include "util/numeric.h"

///////////////////////////////////////
/*
  LuaPerlinNoise
*/

LuaPerlinNoise::LuaPerlinNoise(NoiseParams *params) :
	np(*params)
{
}


int LuaPerlinNoise::l_get_2d(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;
	LuaPerlinNoise *o = checkobject(L, 1);
	v2f p = readParam<v2f>(L, 2);
	lua_Number val = NoisePerlin2D(&o->np, p.X, p.Y, 0);
	lua_pushnumber(L, val);
	return 1;
}


int LuaPerlinNoise::l_get_3d(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;
	LuaPerlinNoise *o = checkobject(L, 1);
	v3f p = check_v3f(L, 2);
	lua_Number val = NoisePerlin3D(&o->np, p.X, p.Y, p.Z, 0);
	lua_pushnumber(L, val);
	return 1;
}


int LuaPerlinNoise::create_object(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	NoiseParams params;

	if (lua_istable(L, 1)) {
		read_noiseparams(L, 1, &params);
	} else {
		params.seed    = luaL_checkint(L, 1);
		params.octaves = luaL_checkint(L, 2);
		params.persist = readParam<float>(L, 3);
		params.spread  = v3f(1, 1, 1) * readParam<float>(L, 4);
	}

	LuaPerlinNoise *o = new LuaPerlinNoise(&params);

	*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
	luaL_getmetatable(L, className);
	lua_setmetatable(L, -2);
	return 1;
}


int LuaPerlinNoise::gc_object(lua_State *L)
{
	LuaPerlinNoise *o = *(LuaPerlinNoise **)(lua_touserdata(L, 1));
	delete o;
	return 0;
}


LuaPerlinNoise *LuaPerlinNoise::checkobject(lua_State *L, int narg)
{
	NO_MAP_LOCK_REQUIRED;
	luaL_checktype(L, narg, LUA_TUSERDATA);
	void *ud = luaL_checkudata(L, narg, className);
	if (!ud)
		luaL_typerror(L, narg, className);
	return *(LuaPerlinNoise **)ud;
}


void LuaPerlinNoise::Register(lua_State *L)
{
	lua_newtable(L);
	int methodtable = lua_gettop(L);
	luaL_newmetatable(L, className);
	int metatable = lua_gettop(L);

	lua_pushliteral(L, "__metatable");
	lua_pushvalue(L, methodtable);
	lua_settable(L, metatable);

	lua_pushliteral(L, "__index");
	lua_pushvalue(L, methodtable);
	lua_settable(L, metatable);

	lua_pushliteral(L, "__gc");
	lua_pushcfunction(L, gc_object);
	lua_settable(L, metatable);

	lua_pop(L, 1);

	markAliasDeprecated(methods);
	luaL_openlib(L, 0, methods, 0);
	lua_pop(L, 1);

	lua_register(L, className, create_object);
}


const char LuaPerlinNoise::className[] = "PerlinNoise";
luaL_Reg LuaPerlinNoise::methods[] = {
	luamethod_aliased(LuaPerlinNoise, get_2d, get2d),
	luamethod_aliased(LuaPerlinNoise, get_3d, get3d),
	{0,0}
};

///////////////////////////////////////
/*
  LuaPerlinNoiseMap
*/

LuaPerlinNoiseMap::LuaPerlinNoiseMap(NoiseParams *params, s32 seed, v3s16 size)
{
	m_is3d = size.Z > 1;
	np = *params;
	try {
		noise = new Noise(&np, seed, size.X, size.Y, size.Z);
	} catch (InvalidNoiseParamsException &e) {
		throw LuaError(e.what());
	}
}


LuaPerlinNoiseMap::~LuaPerlinNoiseMap()
{
	delete noise;
}


int LuaPerlinNoiseMap::l_get_2d_map(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;
	size_t i = 0;

	LuaPerlinNoiseMap *o = checkobject(L, 1);
	v2f p = readParam<v2f>(L, 2);

	Noise *n = o->noise;
	n->perlinMap2D(p.X, p.Y);

	lua_newtable(L);
	for (u32 y = 0; y != n->sy; y++) {
		lua_newtable(L);
		for (u32 x = 0; x != n->sx; x++) {
			lua_pushnumber(L, n->result[i++]);
			lua_rawseti(L, -2, x + 1);
		}
		lua_rawseti(L, -2, y + 1);
	}
	return 1;
}


int LuaPerlinNoiseMap::l_get_2d_map_flat(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaPerlinNoiseMap *o = checkobject(L, 1);
	v2f p = readParam<v2f>(L, 2);
	bool use_buffer = lua_istable(L, 3);

	Noise *n = o->noise;
	n->perlinMap2D(p.X, p.Y);

	size_t maplen = n->sx * n->sy;

	if (use_buffer)
		lua_pushvalue(L, 3);
	else
		lua_newtable(L);

	for (size_t i = 0; i != maplen; i++) {
		lua_pushnumber(L, n->result[i]);
		lua_rawseti(L, -2, i + 1);
	}
	return 1;
}


int LuaPerlinNoiseMap::l_get_3d_map(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;
	size_t i = 0;

	LuaPerlinNoiseMap *o = checkobject(L, 1);
	v3f p = check_v3f(L, 2);

	if (!o->m_is3d)
		return 0;

	Noise *n = o->noise;
	n->perlinMap3D(p.X, p.Y, p.Z);

	lua_newtable(L);
	for (u32 z = 0; z != n->sz; z++) {
		lua_newtable(L);
		for (u32 y = 0; y != n->sy; y++) {
			lua_newtable(L);
			for (u32 x = 0; x != n->sx; x++) {
				lua_pushnumber(L, n->result[i++]);
				lua_rawseti(L, -2, x + 1);
			}
			lua_rawseti(L, -2, y + 1);
		}
		lua_rawseti(L, -2, z + 1);
	}
	return 1;
}


int LuaPerlinNoiseMap::l_get_3d_map_flat(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaPerlinNoiseMap *o = checkobject(L, 1);
	v3f p                = check_v3f(L, 2);
	bool use_buffer      = lua_istable(L, 3);

	if (!o->m_is3d)
		return 0;

	Noise *n = o->noise;
	n->perlinMap3D(p.X, p.Y, p.Z);

	size_t maplen = n->sx * n->sy * n->sz;

	if (use_buffer)
		lua_pushvalue(L, 3);
	else
		lua_newtable(L);

	for (size_t i = 0; i != maplen; i++) {
		lua_pushnumber(L, n->result[i]);
		lua_rawseti(L, -2, i + 1);
	}
	return 1;
}


int LuaPerlinNoiseMap::l_calc_2d_map(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaPerlinNoiseMap *o = checkobject(L, 1);
	v2f p = readParam<v2f>(L, 2);

	Noise *n = o->noise;
	n->perlinMap2D(p.X, p.Y);

	return 0;
}

int LuaPerlinNoiseMap::l_calc_3d_map(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaPerlinNoiseMap *o = checkobject(L, 1);
	v3f p                = check_v3f(L, 2);

	if (!o->m_is3d)
		return 0;

	Noise *n = o->noise;
	n->perlinMap3D(p.X, p.Y, p.Z);

	return 0;
}


int LuaPerlinNoiseMap::l_get_map_slice(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaPerlinNoiseMap *o = checkobject(L, 1);
	v3s16 slice_offset   = read_v3s16(L, 2);
	v3s16 slice_size     = read_v3s16(L, 3);
	bool use_buffer      = lua_istable(L, 4);

	Noise *n = o->noise;

	if (use_buffer)
		lua_pushvalue(L, 4);
	else
		lua_newtable(L);

	write_array_slice_float(L, lua_gettop(L), n->result,
		v3u16(n->sx, n->sy, n->sz),
		v3u16(slice_offset.X, slice_offset.Y, slice_offset.Z),
		v3u16(slice_size.X, slice_size.Y, slice_size.Z));

	return 1;
}


int LuaPerlinNoiseMap::create_object(lua_State *L)
{
	NoiseParams np;
	if (!read_noiseparams(L, 1, &np))
		return 0;
	v3s16 size = read_v3s16(L, 2);

	LuaPerlinNoiseMap *o = new LuaPerlinNoiseMap(&np, 0, size);
	*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
	luaL_getmetatable(L, className);
	lua_setmetatable(L, -2);
	return 1;
}


int LuaPerlinNoiseMap::gc_object(lua_State *L)
{
	LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)(lua_touserdata(L, 1));
	delete o;
	return 0;
}


LuaPerlinNoiseMap *LuaPerlinNoiseMap::checkobject(lua_State *L, int narg)
{
	luaL_checktype(L, narg, LUA_TUSERDATA);

	void *ud = luaL_checkudata(L, narg, className);
	if (!ud)
		luaL_typerror(L, narg, className);

	return *(LuaPerlinNoiseMap **)ud;
}


void LuaPerlinNoiseMap::Register(lua_State *L)
{
	lua_newtable(L);
	int methodtable = lua_gettop(L);
	luaL_newmetatable(L, className);
	int metatable = lua_gettop(L);

	lua_pushliteral(L, "__metatable");
	lua_pushvalue(L, methodtable);
	lua_settable(L, metatable);

	lua_pushliteral(L, "__index");
	lua_pushvalue(L, methodtable);
	lua_settable(L, metatable);

	lua_pushliteral(L, "__gc");
	lua_pushcfunction(L, gc_object);
	lua_settable(L, metatable);

	lua_pop(L, 1);

	markAliasDeprecated(methods);
	luaL_openlib(L, 0, methods, 0);
	lua_pop(L, 1);

	lua_register(L, className, create_object);
}


const char LuaPerlinNoiseMap::className[] = "PerlinNoiseMap";
luaL_Reg LuaPerlinNoiseMap::methods[] = {
	luamethod_aliased(LuaPerlinNoiseMap, get_2d_map,      get2dMap),
	luamethod_aliased(LuaPerlinNoiseMap, get_2d_map_flat, get2dMap_flat),
	luamethod_aliased(LuaPerlinNoiseMap, calc_2d_map,     calc2dMap),
	luamethod_aliased(LuaPerlinNoiseMap, get_3d_map,      get3dMap),
	luamethod_aliased(LuaPerlinNoiseMap, get_3d_map_flat, get3dMap_flat),
	luamethod_aliased(LuaPerlinNoiseMap, calc_3d_map,     calc3dMap),
	luamethod_aliased(LuaPerlinNoiseMap, get_map_slice,   getMapSlice),
	{0,0}
};

///////////////////////////////////////
/*
	LuaPseudoRandom
*/

int LuaPseudoRandom::l_next(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaPseudoRandom *o = checkobject(L, 1);
	int min = 0;
	int max = 32767;
	lua_settop(L, 3);
	if (lua_isnumber(L, 2))
		min = luaL_checkinteger(L, 2);
	if (lua_isnumber(L, 3))
		max = luaL_checkinteger(L, 3);
	if (max < min) {
		errorstream<<"PseudoRandom.next(): max="<<max<<" min="<<min<<std::endl;
		throw LuaError("PseudoRandom.next(): max < min");
	}
	if(max - min != 32767 && max - min > 32767/5)
		throw LuaError("PseudoRandom.next() max-min is not 32767"
				" and is > 32768/5. This is disallowed due to"
				" the bad random distribution the"
				" implementation would otherwise make.");
	PseudoRandom &pseudo = o->m_pseudo;
	int val = pseudo.next();
	val = (val % (max-min+1)) + min;
	lua_pushinteger(L, val);
	return 1;
}


int LuaPseudoRandom::create_object(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	u64 seed = luaL_checknumber(L, 1);
	LuaPseudoRandom *o = new LuaPseudoRandom(seed);
	*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
	luaL_getmetatable(L, className);
	lua_setmetatable(L, -2);
	return 1;
}


int LuaPseudoRandom::gc_object(lua_State *L)
{
	LuaPseudoRandom *o = *(LuaPseudoRandom **)(lua_touserdata(L, 1));
	delete o;
	return 0;
}


LuaPseudoRandom *LuaPseudoRandom::checkobject(lua_State *L, int narg)
{
	luaL_checktype(L, narg, LUA_TUSERDATA);
	void *ud = luaL_checkudata(L, narg, className);
	if (!ud)
		luaL_typerror(L, narg, className);
	return *(LuaPseudoRandom **)ud;
}


void LuaPseudoRandom::Register(lua_State *L)
{
	lua_newtable(L);
	int methodtable = lua_gettop(L);
	luaL_newmetatable(L, className);
	int metatable = lua_gettop(L);

	lua_pushliteral(L, "__metatable");
	lua_pushvalue(L, methodtable);
	lua_settable(L, metatable);

	lua_pushliteral(L, "__index");
	lua_pushvalue(L, methodtable);
	lua_settable(L, metatable);

	lua_pushliteral(L, "__gc");
	lua_pushcfunction(L, gc_object);
	lua_settable(L, metatable);

	lua_pop(L, 1);

	luaL_openlib(L, 0, methods, 0);
	lua_pop(L, 1);

	lua_register(L, className, create_object);
}


const char LuaPseudoRandom::className[] = "PseudoRandom";
const luaL_Reg LuaPseudoRandom::methods[] = {
	luamethod(LuaPseudoRandom, next),
	{0,0}
};

///////////////////////////////////////
/*
	LuaPcgRandom
*/

int LuaPcgRandom::l_next(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaPcgRandom *o = checkobject(L, 1);
	u32 min = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : o->m_rnd.RANDOM_MIN;
	u32 max = lua_isnumber(L, 3) ? lua_tointeger(L, 3) : o->m_rnd.RANDOM_MAX;

	lua_pushinteger(L, o->m_rnd.range(min, max));
	return 1;
}


int LuaPcgRandom::l_rand_normal_dist(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaPcgRandom *o = checkobject(L, 1);
	u32 min = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : o->m_rnd.RANDOM_MIN;
	u32 max = lua_isnumber(L, 3) ? lua_tointeger(L, 3) : o->m_rnd.RANDOM_MAX;
	int num_trials = lua_isnumber(L, 4) ? lua_tointeger(L, 4) : 6;

	lua_pushinteger(L, o->m_rnd.randNormalDist(min, max, num_trials));
	return 1;
}


int LuaPcgRandom::create_object(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	u64 seed = luaL_checknumber(L, 1);
	LuaPcgRandom *o = lua_isnumber(L, 2) ?
		new LuaPcgRandom(seed, lua_tointeger(L, 2)) :
		new LuaPcgRandom(seed);
	*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
	luaL_getmetatable(L, className);
	lua_setmetatable(L, -2);
	return 1;
}


int LuaPcgRandom::gc_object(lua_State *L)
{
	LuaPcgRandom *o = *(LuaPcgRandom **)(lua_touserdata(L, 1));
	delete o;
	return 0;
}


LuaPcgRandom *LuaPcgRandom::checkobject(lua_State *L, int narg)
{
	luaL_checktype(L, narg, LUA_TUSERDATA);
	void *ud = luaL_checkudata(L, narg, className);
	if (!ud)
		luaL_typerror(L, narg, className);
	return *(LuaPcgRandom **)ud;
}


void LuaPcgRandom::Register(lua_State *L)
{
	lua_newtable(L);
	int methodtable = lua_gettop(L);
	luaL_newmetatable(L, className);
	int metatable = lua_gettop(L);

	lua_pushliteral(L, "__metatable");
	lua_pushvalue(L, methodtable);
	lua_settable(L, metatable);

	lua_pushliteral(L, "__index");
	lua_pushvalue(L, methodtable);
	lua_settable(L, metatable);

	lua_pushliteral(L, "__gc");
	lua_pushcfunction(L, gc_object);
	lua_settable(L, metatable);

	lua_pop(L, 1);

	luaL_openlib(L, 0, methods, 0);
	lua_pop(L, 1);

	lua_register(L, className, create_object);
}


const char LuaPcgRandom::className[] = "PcgRandom";
const luaL_Reg LuaPcgRandom::methods[] = {
	luamethod(LuaPcgRandom, next),
	luamethod(LuaPcgRandom, rand_normal_dist),
	{0,0}
};

///////////////////////////////////////
/*
	LuaSecureRandom
*/

bool LuaSecureRandom::fillRandBuf()
{
	return porting::secure_rand_fill_buf(m_rand_buf, RAND_BUF_SIZE);
}

int LuaSecureRandom::l_next_bytes(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaSecureRandom *o = checkobject(L, 1);
	u32 count = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : 1;

	// Limit count
	count = MYMIN(RAND_BUF_SIZE, count);

	// Find out whether we can pass directly from our array, or have to do some gluing
	size_t count_remaining = RAND_BUF_SIZE - o->m_rand_idx;
	if (count_remaining >= count) {
		lua_pushlstring(L, o->m_rand_buf + o->m_rand_idx, count);
		o->m_rand_idx += count;
	} else {