Browse Source

[rlua] new module: raylib Lua binding

raysan5 9 years ago
parent
commit
735968e685

+ 41 - 0
examples/core_basic_window.lua

@@ -0,0 +1,41 @@
+-- Initialization
+----------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [rlua] example - basic window")
+
+InitAudioDevice()
+
+--local pause = false
+--local texture = LoadTexture("resources/texture.png")
+
+SetTargetFPS(60)       -- Set target frames-per-second
+----------------------------------------------------------------------------------------
+
+while not WindowShouldClose() do
+    -- Update
+    ------------------------------------------------------------------------------------
+    --if (IsKeyPressed(KEY.SPACE)) then
+    --  pause = not pause
+    --end
+    ------------------------------------------------------------------------------------
+
+    -- Draw
+    ------------------------------------------------------------------------------------
+    BeginDrawing()
+
+        ClearBackground(RAYWHITE)
+
+        DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY)
+
+    EndDrawing()
+    ------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+------------------------------------------------------------------------------------
+CloseAudioDevice()      -- Close audio device
+
+CloseWindow()           -- Close window and OpenGL context
+------------------------------------------------------------------------------------

+ 39 - 0
examples/rlua_execute_file.c

@@ -0,0 +1,39 @@
+/*******************************************************************************************
+*
+*   raylib [rlua] example - Lua file execution
+*
+*   NOTE: This example requires Lua library (http://luabinaries.sourceforge.net/download.html)
+*
+*   Compile example using:
+*   gcc -o $(NAME_PART).exe $(FILE_NAME) $(RAYLIB_DIR)\raylib_icon          /
+*       -I../src -I../src/external/lua/include -L../src/external/lua/lib    /
+*       -lraylib -lglfw3 -lopengl32 -lopenal32 -llua53 -lgdi32 -std=c99
+*
+*   This example has been created using raylib 1.6 (www.raylib.com)
+*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+*   Copyright (c) 2013-2016 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#define RLUA_IMPLEMENTATION
+#include "rlua.h"
+
+int main()
+{
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    InitLuaDevice();
+    //--------------------------------------------------------------------------------------
+
+    ExecuteLuaFile("core_basic_window.lua");
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+    CloseLuaDevice();        // Close Lua device and free resources
+    //--------------------------------------------------------------------------------------
+
+	return 0;
+}

+ 256 - 0
src/external/lua/include/lauxlib.h

@@ -0,0 +1,256 @@
+/*
+** $Id: lauxlib.h,v 1.129 2015/11/23 11:29:43 roberto Exp $
+** Auxiliary functions for building Lua libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lauxlib_h
+#define lauxlib_h
+
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include "lua.h"
+
+
+
+/* extra error code for 'luaL_load' */
+#define LUA_ERRFILE     (LUA_ERRERR+1)
+
+
+typedef struct luaL_Reg {
+  const char *name;
+  lua_CFunction func;
+} luaL_Reg;
+
+
+#define LUAL_NUMSIZES	(sizeof(lua_Integer)*16 + sizeof(lua_Number))
+
+LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz);
+#define luaL_checkversion(L)  \
+	  luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES)
+
+LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
+LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
+LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
+LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg);
+LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg,
+                                                          size_t *l);
+LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg,
+                                          const char *def, size_t *l);
+LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg);
+LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def);
+
+LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg);
+LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg,
+                                          lua_Integer def);
+
+LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
+LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t);
+LUALIB_API void (luaL_checkany) (lua_State *L, int arg);
+
+LUALIB_API int   (luaL_newmetatable) (lua_State *L, const char *tname);
+LUALIB_API void  (luaL_setmetatable) (lua_State *L, const char *tname);
+LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
+LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
+
+LUALIB_API void (luaL_where) (lua_State *L, int lvl);
+LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
+
+LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def,
+                                   const char *const lst[]);
+
+LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
+LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
+
+/* predefined references */
+#define LUA_NOREF       (-2)
+#define LUA_REFNIL      (-1)
+
+LUALIB_API int (luaL_ref) (lua_State *L, int t);
+LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
+
+LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
+                                               const char *mode);
+
+#define luaL_loadfile(L,f)	luaL_loadfilex(L,f,NULL)
+
+LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
+                                   const char *name, const char *mode);
+LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
+
+LUALIB_API lua_State *(luaL_newstate) (void);
+
+LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
+
+LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
+                                                  const char *r);
+
+LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
+
+LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname);
+
+LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1,
+                                  const char *msg, int level);
+
+LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
+                                 lua_CFunction openf, int glb);
+
+/*
+** ===============================================================
+** some useful macros
+** ===============================================================
+*/
+
+
+#define luaL_newlibtable(L,l)	\
+  lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
+
+#define luaL_newlib(L,l)  \
+  (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
+
+#define luaL_argcheck(L, cond,arg,extramsg)	\
+		((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
+#define luaL_checkstring(L,n)	(luaL_checklstring(L, (n), NULL))
+#define luaL_optstring(L,n,d)	(luaL_optlstring(L, (n), (d), NULL))
+
+#define luaL_typename(L,i)	lua_typename(L, lua_type(L,(i)))
+
+#define luaL_dofile(L, fn) \
+	(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
+
+#define luaL_dostring(L, s) \
+	(luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
+
+#define luaL_getmetatable(L,n)	(lua_getfield(L, LUA_REGISTRYINDEX, (n)))
+
+#define luaL_opt(L,f,n,d)	(lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
+
+#define luaL_loadbuffer(L,s,sz,n)	luaL_loadbufferx(L,s,sz,n,NULL)
+
+
+/*
+** {======================================================
+** Generic Buffer manipulation
+** =======================================================
+*/
+
+typedef struct luaL_Buffer {
+  char *b;  /* buffer address */
+  size_t size;  /* buffer size */
+  size_t n;  /* number of characters in buffer */
+  lua_State *L;
+  char initb[LUAL_BUFFERSIZE];  /* initial buffer */
+} luaL_Buffer;
+
+
+#define luaL_addchar(B,c) \
+  ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \
+   ((B)->b[(B)->n++] = (c)))
+
+#define luaL_addsize(B,s)	((B)->n += (s))
+
+LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
+LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
+LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
+LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
+LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
+LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
+LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz);
+LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
+
+#define luaL_prepbuffer(B)	luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** File handles for IO library
+** =======================================================
+*/
+
+/*
+** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and
+** initial structure 'luaL_Stream' (it may contain other fields
+** after that initial structure).
+*/
+
+#define LUA_FILEHANDLE          "FILE*"
+
+
+typedef struct luaL_Stream {
+  FILE *f;  /* stream (NULL for incompletely created streams) */
+  lua_CFunction closef;  /* to close stream (NULL for closed streams) */
+} luaL_Stream;
+
+/* }====================================================== */
+
+
+
+/* compatibility with old module system */
+#if defined(LUA_COMPAT_MODULE)
+
+LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
+                                   int sizehint);
+LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
+                                const luaL_Reg *l, int nup);
+
+#define luaL_register(L,n,l)	(luaL_openlib(L,(n),(l),0))
+
+#endif
+
+
+/*
+** {==================================================================
+** "Abstraction Layer" for basic report of messages and errors
+** ===================================================================
+*/
+
+/* print a string */
+#if !defined(lua_writestring)
+#define lua_writestring(s,l)   fwrite((s), sizeof(char), (l), stdout)
+#endif
+
+/* print a newline and flush the output */
+#if !defined(lua_writeline)
+#define lua_writeline()        (lua_writestring("\n", 1), fflush(stdout))
+#endif
+
+/* print an error message */
+#if !defined(lua_writestringerror)
+#define lua_writestringerror(s,p) \
+        (fprintf(stderr, (s), (p)), fflush(stderr))
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {============================================================
+** Compatibility with deprecated conversions
+** =============================================================
+*/
+#if defined(LUA_COMPAT_APIINTCASTS)
+
+#define luaL_checkunsigned(L,a)	((lua_Unsigned)luaL_checkinteger(L,a))
+#define luaL_optunsigned(L,a,d)	\
+	((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d)))
+
+#define luaL_checkint(L,n)	((int)luaL_checkinteger(L, (n)))
+#define luaL_optint(L,n,d)	((int)luaL_optinteger(L, (n), (d)))
+
+#define luaL_checklong(L,n)	((long)luaL_checkinteger(L, (n)))
+#define luaL_optlong(L,n,d)	((long)luaL_optinteger(L, (n), (d)))
+
+#endif
+/* }============================================================ */
+
+
+
+#endif
+
+

+ 486 - 0
src/external/lua/include/lua.h

@@ -0,0 +1,486 @@
+/*
+** $Id: lua.h,v 1.331 2016/05/30 15:53:28 roberto Exp $
+** Lua - A Scripting Language
+** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
+** See Copyright Notice at the end of this file
+*/
+
+
+#ifndef lua_h
+#define lua_h
+
+#include <stdarg.h>
+#include <stddef.h>
+
+
+#include "luaconf.h"
+
+
+#define LUA_VERSION_MAJOR	"5"
+#define LUA_VERSION_MINOR	"3"
+#define LUA_VERSION_NUM		503
+#define LUA_VERSION_RELEASE	"3"
+
+#define LUA_VERSION	"Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
+#define LUA_RELEASE	LUA_VERSION "." LUA_VERSION_RELEASE
+#define LUA_COPYRIGHT	LUA_RELEASE "  Copyright (C) 1994-2016 Lua.org, PUC-Rio"
+#define LUA_AUTHORS	"R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
+
+
+/* mark for precompiled code ('<esc>Lua') */
+#define LUA_SIGNATURE	"\x1bLua"
+
+/* option for multiple returns in 'lua_pcall' and 'lua_call' */
+#define LUA_MULTRET	(-1)
+
+
+/*
+** Pseudo-indices
+** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
+** space after that to help overflow detection)
+*/
+#define LUA_REGISTRYINDEX	(-LUAI_MAXSTACK - 1000)
+#define lua_upvalueindex(i)	(LUA_REGISTRYINDEX - (i))
+
+
+/* thread status */
+#define LUA_OK		0
+#define LUA_YIELD	1
+#define LUA_ERRRUN	2
+#define LUA_ERRSYNTAX	3
+#define LUA_ERRMEM	4
+#define LUA_ERRGCMM	5
+#define LUA_ERRERR	6
+
+
+typedef struct lua_State lua_State;
+
+
+/*
+** basic types
+*/
+#define LUA_TNONE		(-1)
+
+#define LUA_TNIL		0
+#define LUA_TBOOLEAN		1
+#define LUA_TLIGHTUSERDATA	2
+#define LUA_TNUMBER		3
+#define LUA_TSTRING		4
+#define LUA_TTABLE		5
+#define LUA_TFUNCTION		6
+#define LUA_TUSERDATA		7
+#define LUA_TTHREAD		8
+
+#define LUA_NUMTAGS		9
+
+
+
+/* minimum Lua stack available to a C function */
+#define LUA_MINSTACK	20
+
+
+/* predefined values in the registry */
+#define LUA_RIDX_MAINTHREAD	1
+#define LUA_RIDX_GLOBALS	2
+#define LUA_RIDX_LAST		LUA_RIDX_GLOBALS
+
+
+/* type of numbers in Lua */
+typedef LUA_NUMBER lua_Number;
+
+
+/* type for integer functions */
+typedef LUA_INTEGER lua_Integer;
+
+/* unsigned integer type */
+typedef LUA_UNSIGNED lua_Unsigned;
+
+/* type for continuation-function contexts */
+typedef LUA_KCONTEXT lua_KContext;
+
+
+/*
+** Type for C functions registered with Lua
+*/
+typedef int (*lua_CFunction) (lua_State *L);
+
+/*
+** Type for continuation functions
+*/
+typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);
+
+
+/*
+** Type for functions that read/write blocks when loading/dumping Lua chunks
+*/
+typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
+
+typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud);
+
+
+/*
+** Type for memory-allocation functions
+*/
+typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
+
+
+
+/*
+** generic extra include file
+*/
+#if defined(LUA_USER_H)
+#include LUA_USER_H
+#endif
+
+
+/*
+** RCS ident string
+*/
+extern const char lua_ident[];
+
+
+/*
+** state manipulation
+*/
+LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
+LUA_API void       (lua_close) (lua_State *L);
+LUA_API lua_State *(lua_newthread) (lua_State *L);
+
+LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
+
+
+LUA_API const lua_Number *(lua_version) (lua_State *L);
+
+
+/*
+** basic stack manipulation
+*/
+LUA_API int   (lua_absindex) (lua_State *L, int idx);
+LUA_API int   (lua_gettop) (lua_State *L);
+LUA_API void  (lua_settop) (lua_State *L, int idx);
+LUA_API void  (lua_pushvalue) (lua_State *L, int idx);
+LUA_API void  (lua_rotate) (lua_State *L, int idx, int n);
+LUA_API void  (lua_copy) (lua_State *L, int fromidx, int toidx);
+LUA_API int   (lua_checkstack) (lua_State *L, int n);
+
+LUA_API void  (lua_xmove) (lua_State *from, lua_State *to, int n);
+
+
+/*
+** access functions (stack -> C)
+*/
+
+LUA_API int             (lua_isnumber) (lua_State *L, int idx);
+LUA_API int             (lua_isstring) (lua_State *L, int idx);
+LUA_API int             (lua_iscfunction) (lua_State *L, int idx);
+LUA_API int             (lua_isinteger) (lua_State *L, int idx);
+LUA_API int             (lua_isuserdata) (lua_State *L, int idx);
+LUA_API int             (lua_type) (lua_State *L, int idx);
+LUA_API const char     *(lua_typename) (lua_State *L, int tp);
+
+LUA_API lua_Number      (lua_tonumberx) (lua_State *L, int idx, int *isnum);
+LUA_API lua_Integer     (lua_tointegerx) (lua_State *L, int idx, int *isnum);
+LUA_API int             (lua_toboolean) (lua_State *L, int idx);
+LUA_API const char     *(lua_tolstring) (lua_State *L, int idx, size_t *len);
+LUA_API size_t          (lua_rawlen) (lua_State *L, int idx);
+LUA_API lua_CFunction   (lua_tocfunction) (lua_State *L, int idx);
+LUA_API void	       *(lua_touserdata) (lua_State *L, int idx);
+LUA_API lua_State      *(lua_tothread) (lua_State *L, int idx);
+LUA_API const void     *(lua_topointer) (lua_State *L, int idx);
+
+
+/*
+** Comparison and arithmetic functions
+*/
+
+#define LUA_OPADD	0	/* ORDER TM, ORDER OP */
+#define LUA_OPSUB	1
+#define LUA_OPMUL	2
+#define LUA_OPMOD	3
+#define LUA_OPPOW	4
+#define LUA_OPDIV	5
+#define LUA_OPIDIV	6
+#define LUA_OPBAND	7
+#define LUA_OPBOR	8
+#define LUA_OPBXOR	9
+#define LUA_OPSHL	10
+#define LUA_OPSHR	11
+#define LUA_OPUNM	12
+#define LUA_OPBNOT	13
+
+LUA_API void  (lua_arith) (lua_State *L, int op);
+
+#define LUA_OPEQ	0
+#define LUA_OPLT	1
+#define LUA_OPLE	2
+
+LUA_API int   (lua_rawequal) (lua_State *L, int idx1, int idx2);
+LUA_API int   (lua_compare) (lua_State *L, int idx1, int idx2, int op);
+
+
+/*
+** push functions (C -> stack)
+*/
+LUA_API void        (lua_pushnil) (lua_State *L);
+LUA_API void        (lua_pushnumber) (lua_State *L, lua_Number n);
+LUA_API void        (lua_pushinteger) (lua_State *L, lua_Integer n);
+LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t len);
+LUA_API const char *(lua_pushstring) (lua_State *L, const char *s);
+LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
+                                                      va_list argp);
+LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
+LUA_API void  (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
+LUA_API void  (lua_pushboolean) (lua_State *L, int b);
+LUA_API void  (lua_pushlightuserdata) (lua_State *L, void *p);
+LUA_API int   (lua_pushthread) (lua_State *L);
+
+
+/*
+** get functions (Lua -> stack)
+*/
+LUA_API int (lua_getglobal) (lua_State *L, const char *name);
+LUA_API int (lua_gettable) (lua_State *L, int idx);
+LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k);
+LUA_API int (lua_geti) (lua_State *L, int idx, lua_Integer n);
+LUA_API int (lua_rawget) (lua_State *L, int idx);
+LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n);
+LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p);
+
+LUA_API void  (lua_createtable) (lua_State *L, int narr, int nrec);
+LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
+LUA_API int   (lua_getmetatable) (lua_State *L, int objindex);
+LUA_API int  (lua_getuservalue) (lua_State *L, int idx);
+
+
+/*
+** set functions (stack -> Lua)
+*/
+LUA_API void  (lua_setglobal) (lua_State *L, const char *name);
+LUA_API void  (lua_settable) (lua_State *L, int idx);
+LUA_API void  (lua_setfield) (lua_State *L, int idx, const char *k);
+LUA_API void  (lua_seti) (lua_State *L, int idx, lua_Integer n);
+LUA_API void  (lua_rawset) (lua_State *L, int idx);
+LUA_API void  (lua_rawseti) (lua_State *L, int idx, lua_Integer n);
+LUA_API void  (lua_rawsetp) (lua_State *L, int idx, const void *p);
+LUA_API int   (lua_setmetatable) (lua_State *L, int objindex);
+LUA_API void  (lua_setuservalue) (lua_State *L, int idx);
+
+
+/*
+** 'load' and 'call' functions (load and run Lua code)
+*/
+LUA_API void  (lua_callk) (lua_State *L, int nargs, int nresults,
+                           lua_KContext ctx, lua_KFunction k);
+#define lua_call(L,n,r)		lua_callk(L, (n), (r), 0, NULL)
+
+LUA_API int   (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
+                            lua_KContext ctx, lua_KFunction k);
+#define lua_pcall(L,n,r,f)	lua_pcallk(L, (n), (r), (f), 0, NULL)
+
+LUA_API int   (lua_load) (lua_State *L, lua_Reader reader, void *dt,
+                          const char *chunkname, const char *mode);
+
+LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
+
+
+/*
+** coroutine functions
+*/
+LUA_API int  (lua_yieldk)     (lua_State *L, int nresults, lua_KContext ctx,
+                               lua_KFunction k);
+LUA_API int  (lua_resume)     (lua_State *L, lua_State *from, int narg);
+LUA_API int  (lua_status)     (lua_State *L);
+LUA_API int (lua_isyieldable) (lua_State *L);
+
+#define lua_yield(L,n)		lua_yieldk(L, (n), 0, NULL)
+
+
+/*
+** garbage-collection function and options
+*/
+
+#define LUA_GCSTOP		0
+#define LUA_GCRESTART		1
+#define LUA_GCCOLLECT		2
+#define LUA_GCCOUNT		3
+#define LUA_GCCOUNTB		4
+#define LUA_GCSTEP		5
+#define LUA_GCSETPAUSE		6
+#define LUA_GCSETSTEPMUL	7
+#define LUA_GCISRUNNING		9
+
+LUA_API int (lua_gc) (lua_State *L, int what, int data);
+
+
+/*
+** miscellaneous functions
+*/
+
+LUA_API int   (lua_error) (lua_State *L);
+
+LUA_API int   (lua_next) (lua_State *L, int idx);
+
+LUA_API void  (lua_concat) (lua_State *L, int n);
+LUA_API void  (lua_len)    (lua_State *L, int idx);
+
+LUA_API size_t   (lua_stringtonumber) (lua_State *L, const char *s);
+
+LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
+LUA_API void      (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
+
+
+
+/*
+** {==============================================================
+** some useful macros
+** ===============================================================
+*/
+
+#define lua_getextraspace(L)	((void *)((char *)(L) - LUA_EXTRASPACE))
+
+#define lua_tonumber(L,i)	lua_tonumberx(L,(i),NULL)
+#define lua_tointeger(L,i)	lua_tointegerx(L,(i),NULL)
+
+#define lua_pop(L,n)		lua_settop(L, -(n)-1)
+
+#define lua_newtable(L)		lua_createtable(L, 0, 0)
+
+#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
+
+#define lua_pushcfunction(L,f)	lua_pushcclosure(L, (f), 0)
+
+#define lua_isfunction(L,n)	(lua_type(L, (n)) == LUA_TFUNCTION)
+#define lua_istable(L,n)	(lua_type(L, (n)) == LUA_TTABLE)
+#define lua_islightuserdata(L,n)	(lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
+#define lua_isnil(L,n)		(lua_type(L, (n)) == LUA_TNIL)
+#define lua_isboolean(L,n)	(lua_type(L, (n)) == LUA_TBOOLEAN)
+#define lua_isthread(L,n)	(lua_type(L, (n)) == LUA_TTHREAD)
+#define lua_isnone(L,n)		(lua_type(L, (n)) == LUA_TNONE)
+#define lua_isnoneornil(L, n)	(lua_type(L, (n)) <= 0)
+
+#define lua_pushliteral(L, s)	lua_pushstring(L, "" s)
+
+#define lua_pushglobaltable(L)  \
+	((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
+
+#define lua_tostring(L,i)	lua_tolstring(L, (i), NULL)
+
+
+#define lua_insert(L,idx)	lua_rotate(L, (idx), 1)
+
+#define lua_remove(L,idx)	(lua_rotate(L, (idx), -1), lua_pop(L, 1))
+
+#define lua_replace(L,idx)	(lua_copy(L, -1, (idx)), lua_pop(L, 1))
+
+/* }============================================================== */
+
+
+/*
+** {==============================================================
+** compatibility macros for unsigned conversions
+** ===============================================================
+*/
+#if defined(LUA_COMPAT_APIINTCASTS)
+
+#define lua_pushunsigned(L,n)	lua_pushinteger(L, (lua_Integer)(n))
+#define lua_tounsignedx(L,i,is)	((lua_Unsigned)lua_tointegerx(L,i,is))
+#define lua_tounsigned(L,i)	lua_tounsignedx(L,(i),NULL)
+
+#endif
+/* }============================================================== */
+
+/*
+** {======================================================================
+** Debug API
+** =======================================================================
+*/
+
+
+/*
+** Event codes
+*/
+#define LUA_HOOKCALL	0
+#define LUA_HOOKRET	1
+#define LUA_HOOKLINE	2
+#define LUA_HOOKCOUNT	3
+#define LUA_HOOKTAILCALL 4
+
+
+/*
+** Event masks
+*/
+#define LUA_MASKCALL	(1 << LUA_HOOKCALL)
+#define LUA_MASKRET	(1 << LUA_HOOKRET)
+#define LUA_MASKLINE	(1 << LUA_HOOKLINE)
+#define LUA_MASKCOUNT	(1 << LUA_HOOKCOUNT)
+
+typedef struct lua_Debug lua_Debug;  /* activation record */
+
+
+/* Functions to be called by the debugger in specific events */
+typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
+
+
+LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar);
+LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
+LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n);
+LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n);
+LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n);
+LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n);
+
+LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n);
+LUA_API void  (lua_upvaluejoin) (lua_State *L, int fidx1, int n1,
+                                               int fidx2, int n2);
+
+LUA_API void (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);
+LUA_API lua_Hook (lua_gethook) (lua_State *L);
+LUA_API int (lua_gethookmask) (lua_State *L);
+LUA_API int (lua_gethookcount) (lua_State *L);
+
+
+struct lua_Debug {
+  int event;
+  const char *name;	/* (n) */
+  const char *namewhat;	/* (n) 'global', 'local', 'field', 'method' */
+  const char *what;	/* (S) 'Lua', 'C', 'main', 'tail' */
+  const char *source;	/* (S) */
+  int currentline;	/* (l) */
+  int linedefined;	/* (S) */
+  int lastlinedefined;	/* (S) */
+  unsigned char nups;	/* (u) number of upvalues */
+  unsigned char nparams;/* (u) number of parameters */
+  char isvararg;        /* (u) */
+  char istailcall;	/* (t) */
+  char short_src[LUA_IDSIZE]; /* (S) */
+  /* private part */
+  struct CallInfo *i_ci;  /* active function */
+};
+
+/* }====================================================================== */
+
+
+/******************************************************************************
+* Copyright (C) 1994-2016 Lua.org, PUC-Rio.
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
+
+#endif

+ 9 - 0
src/external/lua/include/lua.hpp

@@ -0,0 +1,9 @@
+// lua.hpp
+// Lua header files for C++
+// <<extern "C">> not supplied automatically because Lua also compiles as C++
+
+extern "C" {
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+}

+ 769 - 0
src/external/lua/include/luaconf.h

@@ -0,0 +1,769 @@
+/*
+** $Id: luaconf.h,v 1.255 2016/05/01 20:06:09 roberto Exp $
+** Configuration file for Lua
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef luaconf_h
+#define luaconf_h
+
+#include <limits.h>
+#include <stddef.h>
+
+
+/*
+** ===================================================================
+** Search for "@@" to find all configurable definitions.
+** ===================================================================
+*/
+
+
+/*
+** {====================================================================
+** System Configuration: macros to adapt (if needed) Lua to some
+** particular platform, for instance compiling it with 32-bit numbers or
+** restricting it to C89.
+** =====================================================================
+*/
+
+/*
+@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. You
+** can also define LUA_32BITS in the make file, but changing here you
+** ensure that all software connected to Lua will be compiled with the
+** same configuration.
+*/
+/* #define LUA_32BITS */
+
+
+/*
+@@ LUA_USE_C89 controls the use of non-ISO-C89 features.
+** Define it if you want Lua to avoid the use of a few C99 features
+** or Windows-specific features on Windows.
+*/
+/* #define LUA_USE_C89 */
+
+
+/*
+** By default, Lua on Windows use (some) specific Windows features
+*/
+#if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE)
+#define LUA_USE_WINDOWS  /* enable goodies for regular Windows */
+#endif
+
+
+#if defined(LUA_USE_WINDOWS)
+#define LUA_DL_DLL	/* enable support for DLL */
+#define LUA_USE_C89	/* broadly, Windows is C89 */
+#endif
+
+
+#if defined(LUA_USE_LINUX)
+#define LUA_USE_POSIX
+#define LUA_USE_DLOPEN		/* needs an extra library: -ldl */
+#define LUA_USE_READLINE	/* needs some extra libraries */
+#endif
+
+
+#if defined(LUA_USE_MACOSX)
+#define LUA_USE_POSIX
+#define LUA_USE_DLOPEN		/* MacOS does not need -ldl */
+#define LUA_USE_READLINE	/* needs an extra library: -lreadline */
+#endif
+
+
+/*
+@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for
+** C89 ('long' and 'double'); Windows always has '__int64', so it does
+** not need to use this case.
+*/
+#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS)
+#define LUA_C89_NUMBERS
+#endif
+
+
+
+/*
+@@ LUAI_BITSINT defines the (minimum) number of bits in an 'int'.
+*/
+/* avoid undefined shifts */
+#if ((INT_MAX >> 15) >> 15) >= 1
+#define LUAI_BITSINT	32
+#else
+/* 'int' always must have at least 16 bits */
+#define LUAI_BITSINT	16
+#endif
+
+
+/*
+@@ LUA_INT_TYPE defines the type for Lua integers.
+@@ LUA_FLOAT_TYPE defines the type for Lua floats.
+** Lua should work fine with any mix of these options (if supported
+** by your C compiler). The usual configurations are 64-bit integers
+** and 'double' (the default), 32-bit integers and 'float' (for
+** restricted platforms), and 'long'/'double' (for C compilers not
+** compliant with C99, which may not have support for 'long long').
+*/
+
+/* predefined options for LUA_INT_TYPE */
+#define LUA_INT_INT		1
+#define LUA_INT_LONG		2
+#define LUA_INT_LONGLONG	3
+
+/* predefined options for LUA_FLOAT_TYPE */
+#define LUA_FLOAT_FLOAT		1
+#define LUA_FLOAT_DOUBLE	2
+#define LUA_FLOAT_LONGDOUBLE	3
+
+#if defined(LUA_32BITS)		/* { */
+/*
+** 32-bit integers and 'float'
+*/
+#if LUAI_BITSINT >= 32  /* use 'int' if big enough */
+#define LUA_INT_TYPE	LUA_INT_INT
+#else  /* otherwise use 'long' */
+#define LUA_INT_TYPE	LUA_INT_LONG
+#endif
+#define LUA_FLOAT_TYPE	LUA_FLOAT_FLOAT
+
+#elif defined(LUA_C89_NUMBERS)	/* }{ */
+/*
+** largest types available for C89 ('long' and 'double')
+*/
+#define LUA_INT_TYPE	LUA_INT_LONG
+#define LUA_FLOAT_TYPE	LUA_FLOAT_DOUBLE
+
+#endif				/* } */
+
+
+/*
+** default configuration for 64-bit Lua ('long long' and 'double')
+*/
+#if !defined(LUA_INT_TYPE)
+#define LUA_INT_TYPE	LUA_INT_LONGLONG
+#endif
+
+#if !defined(LUA_FLOAT_TYPE)
+#define LUA_FLOAT_TYPE	LUA_FLOAT_DOUBLE
+#endif
+
+/* }================================================================== */
+
+
+
+
+/*
+** {==================================================================
+** Configuration for Paths.
+** ===================================================================
+*/
+
+/*
+@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
+** Lua libraries.
+@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
+** C libraries.
+** CHANGE them if your machine has a non-conventional directory
+** hierarchy or if you want to install your libraries in
+** non-conventional directories.
+*/
+#define LUA_VDIR	LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
+#if defined(_WIN32)	/* { */
+/*
+** In Windows, any exclamation mark ('!') in the path is replaced by the
+** path of the directory of the executable file of the current process.
+*/
+#define LUA_LDIR	"!\\lua\\"
+#define LUA_CDIR	"!\\"
+#define LUA_SHRDIR	"!\\..\\share\\lua\\" LUA_VDIR "\\"
+#define LUA_PATH_DEFAULT  \
+		LUA_LDIR"?.lua;"  LUA_LDIR"?\\init.lua;" \
+		LUA_CDIR"?.lua;"  LUA_CDIR"?\\init.lua;" \
+		LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \
+		".\\?.lua;" ".\\?\\init.lua"
+#define LUA_CPATH_DEFAULT \
+		LUA_CDIR"?.dll;" \
+		LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \
+		LUA_CDIR"loadall.dll;" ".\\?.dll;" \
+    LUA_CDIR"?53.dll;" ".\\?53.dll"
+
+#else			/* }{ */
+
+#define LUA_ROOT	"/usr/local/"
+#define LUA_LDIR	LUA_ROOT "share/lua/" LUA_VDIR "/"
+#define LUA_CDIR	LUA_ROOT "lib/lua/" LUA_VDIR "/"
+#define LUA_PATH_DEFAULT  \
+		LUA_LDIR"?.lua;"  LUA_LDIR"?/init.lua;" \
+		LUA_CDIR"?.lua;"  LUA_CDIR"?/init.lua;" \
+		"./?.lua;" "./?/init.lua"
+#define LUA_CPATH_DEFAULT \
+		LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so;" \
+    LUA_CDIR"lib?53.so;" "./lib?53.so"
+#endif			/* } */
+
+
+/*
+@@ LUA_DIRSEP is the directory separator (for submodules).
+** CHANGE it if your machine does not use "/" as the directory separator
+** and is not Windows. (On Windows Lua automatically uses "\".)
+*/
+#if defined(_WIN32)
+#define LUA_DIRSEP	"\\"
+#else
+#define LUA_DIRSEP	"/"
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Marks for exported symbols in the C code
+** ===================================================================
+*/
+
+/*
+@@ LUA_API is a mark for all core API functions.
+@@ LUALIB_API is a mark for all auxiliary library functions.
+@@ LUAMOD_API is a mark for all standard library opening functions.
+** CHANGE them if you need to define those functions in some special way.
+** For instance, if you want to create one Windows DLL with the core and
+** the libraries, you may want to use the following definition (define
+** LUA_BUILD_AS_DLL to get it).
+*/
+#if defined(LUA_BUILD_AS_DLL)	/* { */
+
+#if defined(LUA_CORE) || defined(LUA_LIB)	/* { */
+#define LUA_API __declspec(dllexport)
+#else						/* }{ */
+#define LUA_API __declspec(dllimport)
+#endif						/* } */
+
+#else				/* }{ */
+
+#define LUA_API		extern
+
+#endif				/* } */
+
+
+/* more often than not the libs go together with the core */
+#define LUALIB_API	LUA_API
+#define LUAMOD_API	LUALIB_API
+
+
+/*
+@@ LUAI_FUNC is a mark for all extern functions that are not to be
+** exported to outside modules.
+@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables
+** that are not to be exported to outside modules (LUAI_DDEF for
+** definitions and LUAI_DDEC for declarations).
+** CHANGE them if you need to mark them in some special way. Elf/gcc
+** (versions 3.2 and later) mark them as "hidden" to optimize access
+** when Lua is compiled as a shared library. Not all elf targets support
+** this attribute. Unfortunately, gcc does not offer a way to check
+** whether the target offers that support, and those without support
+** give a warning about it. To avoid these warnings, change to the
+** default definition.
+*/
+#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
+    defined(__ELF__)		/* { */
+#define LUAI_FUNC	__attribute__((visibility("hidden"))) extern
+#else				/* }{ */
+#define LUAI_FUNC	extern
+#endif				/* } */
+
+#define LUAI_DDEC	LUAI_FUNC
+#define LUAI_DDEF	/* empty */
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Compatibility with previous versions
+** ===================================================================
+*/
+
+/*
+@@ LUA_COMPAT_5_2 controls other macros for compatibility with Lua 5.2.
+@@ LUA_COMPAT_5_1 controls other macros for compatibility with Lua 5.1.
+** You can define it to get all options, or change specific options
+** to fit your specific needs.
+*/
+#if defined(LUA_COMPAT_5_2)	/* { */
+
+/*
+@@ LUA_COMPAT_MATHLIB controls the presence of several deprecated
+** functions in the mathematical library.
+*/
+#define LUA_COMPAT_MATHLIB
+
+/*
+@@ LUA_COMPAT_BITLIB controls the presence of library 'bit32'.
+*/
+#define LUA_COMPAT_BITLIB
+
+/*
+@@ LUA_COMPAT_IPAIRS controls the effectiveness of the __ipairs metamethod.
+*/
+#define LUA_COMPAT_IPAIRS
+
+/*
+@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for
+** manipulating other integer types (lua_pushunsigned, lua_tounsigned,
+** luaL_checkint, luaL_checklong, etc.)
+*/
+#define LUA_COMPAT_APIINTCASTS
+
+#endif				/* } */
+
+
+#if defined(LUA_COMPAT_5_1)	/* { */
+
+/* Incompatibilities from 5.2 -> 5.3 */
+#define LUA_COMPAT_MATHLIB
+#define LUA_COMPAT_APIINTCASTS
+
+/*
+@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
+** You can replace it with 'table.unpack'.
+*/
+#define LUA_COMPAT_UNPACK
+
+/*
+@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'.
+** You can replace it with 'package.searchers'.
+*/
+#define LUA_COMPAT_LOADERS
+
+/*
+@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall.
+** You can call your C function directly (with light C functions).
+*/
+#define lua_cpcall(L,f,u)  \
+	(lua_pushcfunction(L, (f)), \
+	 lua_pushlightuserdata(L,(u)), \
+	 lua_pcall(L,1,0,0))
+
+
+/*
+@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library.
+** You can rewrite 'log10(x)' as 'log(x, 10)'.
+*/
+#define LUA_COMPAT_LOG10
+
+/*
+@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base
+** library. You can rewrite 'loadstring(s)' as 'load(s)'.
+*/
+#define LUA_COMPAT_LOADSTRING
+
+/*
+@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library.
+*/
+#define LUA_COMPAT_MAXN
+
+/*
+@@ The following macros supply trivial compatibility for some
+** changes in the API. The macros themselves document how to
+** change your code to avoid using them.
+*/
+#define lua_strlen(L,i)		lua_rawlen(L, (i))
+
+#define lua_objlen(L,i)		lua_rawlen(L, (i))
+
+#define lua_equal(L,idx1,idx2)		lua_compare(L,(idx1),(idx2),LUA_OPEQ)
+#define lua_lessthan(L,idx1,idx2)	lua_compare(L,(idx1),(idx2),LUA_OPLT)
+
+/*
+@@ LUA_COMPAT_MODULE controls compatibility with previous
+** module functions 'module' (Lua) and 'luaL_register' (C).
+*/
+#define LUA_COMPAT_MODULE
+
+#endif				/* } */
+
+
+/*
+@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
+@@ a float mark ('.0').
+** This macro is not on by default even in compatibility mode,
+** because this is not really an incompatibility.
+*/
+/* #define LUA_COMPAT_FLOATSTRING */
+
+/* }================================================================== */
+
+
+
+/*
+** {==================================================================
+** Configuration for Numbers.
+** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_*
+** satisfy your needs.
+** ===================================================================
+*/
+
+/*
+@@ LUA_NUMBER is the floating-point type used by Lua.
+@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
+@@ over a floating number.
+@@ l_mathlim(x) corrects limit name 'x' to the proper float type
+** by prefixing it with one of FLT/DBL/LDBL.
+@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
+@@ LUA_NUMBER_FMT is the format for writing floats.
+@@ lua_number2str converts a float to a string.
+@@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
+@@ l_floor takes the floor of a float.
+@@ lua_str2number converts a decimal numeric string to a number.
+*/
+
+
+/* The following definitions are good for most cases here */
+
+#define l_floor(x)		(l_mathop(floor)(x))
+
+#define lua_number2str(s,sz,n)	l_sprintf((s), sz, LUA_NUMBER_FMT, (n))
+
+/*
+@@ lua_numbertointeger converts a float number to an integer, or
+** returns 0 if float is not within the range of a lua_Integer.
+** (The range comparisons are tricky because of rounding. The tests
+** here assume a two-complement representation, where MININTEGER always
+** has an exact representation as a float; MAXINTEGER may not have one,
+** and therefore its conversion to float may have an ill-defined value.)
+*/
+#define lua_numbertointeger(n,p) \
+  ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \
+   (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \
+      (*(p) = (LUA_INTEGER)(n), 1))
+
+
+/* now the variable definitions */
+
+#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT		/* { single float */
+
+#define LUA_NUMBER	float
+
+#define l_mathlim(n)		(FLT_##n)
+
+#define LUAI_UACNUMBER	double
+
+#define LUA_NUMBER_FRMLEN	""
+#define LUA_NUMBER_FMT		"%.7g"
+
+#define l_mathop(op)		op##f
+
+#define lua_str2number(s,p)	strtof((s), (p))
+
+
+#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE	/* }{ long double */
+
+#define LUA_NUMBER	long double
+
+#define l_mathlim(n)		(LDBL_##n)
+
+#define LUAI_UACNUMBER	long double
+
+#define LUA_NUMBER_FRMLEN	"L"
+#define LUA_NUMBER_FMT		"%.19Lg"
+
+#define l_mathop(op)		op##l
+
+#define lua_str2number(s,p)	strtold((s), (p))
+
+#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE	/* }{ double */
+
+#define LUA_NUMBER	double
+
+#define l_mathlim(n)		(DBL_##n)
+
+#define LUAI_UACNUMBER	double
+
+#define LUA_NUMBER_FRMLEN	""
+#define LUA_NUMBER_FMT		"%.14g"
+
+#define l_mathop(op)		op
+
+#define lua_str2number(s,p)	strtod((s), (p))
+
+#else						/* }{ */
+
+#error "numeric float type not defined"
+
+#endif					/* } */
+
+
+
+/*
+@@ LUA_INTEGER is the integer type used by Lua.
+**
+@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
+**
+@@ LUAI_UACINT is the result of an 'usual argument conversion'
+@@ over a lUA_INTEGER.
+@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
+@@ LUA_INTEGER_FMT is the format for writing integers.
+@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
+@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
+@@ lua_integer2str converts an integer to a string.
+*/
+
+
+/* The following definitions are good for most cases here */
+
+#define LUA_INTEGER_FMT		"%" LUA_INTEGER_FRMLEN "d"
+#define lua_integer2str(s,sz,n)	l_sprintf((s), sz, LUA_INTEGER_FMT, (n))
+
+#define LUAI_UACINT		LUA_INTEGER
+
+/*
+** use LUAI_UACINT here to avoid problems with promotions (which
+** can turn a comparison between unsigneds into a signed comparison)
+*/
+#define LUA_UNSIGNED		unsigned LUAI_UACINT
+
+
+/* now the variable definitions */
+
+#if LUA_INT_TYPE == LUA_INT_INT		/* { int */
+
+#define LUA_INTEGER		int
+#define LUA_INTEGER_FRMLEN	""
+
+#define LUA_MAXINTEGER		INT_MAX
+#define LUA_MININTEGER		INT_MIN
+
+#elif LUA_INT_TYPE == LUA_INT_LONG	/* }{ long */
+
+#define LUA_INTEGER		long
+#define LUA_INTEGER_FRMLEN	"l"
+
+#define LUA_MAXINTEGER		LONG_MAX
+#define LUA_MININTEGER		LONG_MIN
+
+#elif LUA_INT_TYPE == LUA_INT_LONGLONG	/* }{ long long */
+
+/* use presence of macro LLONG_MAX as proxy for C99 compliance */
+#if defined(LLONG_MAX)		/* { */
+/* use ISO C99 stuff */
+
+#define LUA_INTEGER		long long
+#define LUA_INTEGER_FRMLEN	"ll"
+
+#define LUA_MAXINTEGER		LLONG_MAX
+#define LUA_MININTEGER		LLONG_MIN
+
+#elif defined(LUA_USE_WINDOWS) /* }{ */
+/* in Windows, can use specific Windows types */
+
+#define LUA_INTEGER		__int64
+#define LUA_INTEGER_FRMLEN	"I64"
+
+#define LUA_MAXINTEGER		_I64_MAX
+#define LUA_MININTEGER		_I64_MIN
+
+#else				/* }{ */
+
+#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \
+  or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)"
+
+#endif				/* } */
+
+#else				/* }{ */
+
+#error "numeric integer type not defined"
+
+#endif				/* } */
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Dependencies with C99 and other C details
+** ===================================================================
+*/
+
+/*
+@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89.
+** (All uses in Lua have only one format item.)
+*/
+#if !defined(LUA_USE_C89)
+#define l_sprintf(s,sz,f,i)	snprintf(s,sz,f,i)
+#else
+#define l_sprintf(s,sz,f,i)	((void)(sz), sprintf(s,f,i))
+#endif
+
+
+/*
+@@ lua_strx2number converts an hexadecimal numeric string to a number.
+** In C99, 'strtod' does that conversion. Otherwise, you can
+** leave 'lua_strx2number' undefined and Lua will provide its own
+** implementation.
+*/
+#if !defined(LUA_USE_C89)
+#define lua_strx2number(s,p)		lua_str2number(s,p)
+#endif
+
+
+/*
+@@ lua_number2strx converts a float to an hexadecimal numeric string. 
+** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
+** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
+** provide its own implementation.
+*/
+#if !defined(LUA_USE_C89)
+#define lua_number2strx(L,b,sz,f,n)	((void)L, l_sprintf(b,sz,f,n))
+#endif
+
+
+/*
+** 'strtof' and 'opf' variants for math functions are not valid in
+** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the
+** availability of these variants. ('math.h' is already included in
+** all files that use these macros.)
+*/
+#if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF))
+#undef l_mathop  /* variants not available */
+#undef lua_str2number
+#define l_mathop(op)		(lua_Number)op  /* no variant */
+#define lua_str2number(s,p)	((lua_Number)strtod((s), (p)))
+#endif
+
+
+/*
+@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation
+** functions.  It must be a numerical type; Lua will use 'intptr_t' if
+** available, otherwise it will use 'ptrdiff_t' (the nearest thing to
+** 'intptr_t' in C89)
+*/
+#define LUA_KCONTEXT	ptrdiff_t
+
+#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
+    __STDC_VERSION__ >= 199901L
+#include <stdint.h>
+#if defined(INTPTR_MAX)  /* even in C99 this type is optional */
+#undef LUA_KCONTEXT
+#define LUA_KCONTEXT	intptr_t
+#endif
+#endif
+
+
+/*
+@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point).
+** Change that if you do not want to use C locales. (Code using this
+** macro must include header 'locale.h'.)
+*/
+#if !defined(lua_getlocaledecpoint)
+#define lua_getlocaledecpoint()		(localeconv()->decimal_point[0])
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Language Variations
+** =====================================================================
+*/
+
+/*
+@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some
+** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from
+** numbers to strings. Define LUA_NOCVTS2N to turn off automatic
+** coercion from strings to numbers.
+*/
+/* #define LUA_NOCVTN2S */
+/* #define LUA_NOCVTS2N */
+
+
+/*
+@@ LUA_USE_APICHECK turns on several consistency checks on the C API.
+** Define it as a help when debugging C code.
+*/
+#if defined(LUA_USE_APICHECK)
+#include <assert.h>
+#define luai_apicheck(l,e)	assert(e)
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Macros that affect the API and must be stable (that is, must be the
+** same when you compile Lua and when you compile code that links to
+** Lua). You probably do not want/need to change them.
+** =====================================================================
+*/
+
+/*
+@@ LUAI_MAXSTACK limits the size of the Lua stack.
+** CHANGE it if you need a different limit. This limit is arbitrary;
+** its only purpose is to stop Lua from consuming unlimited stack
+** space (and to reserve some numbers for pseudo-indices).
+*/
+#if LUAI_BITSINT >= 32
+#define LUAI_MAXSTACK		1000000
+#else
+#define LUAI_MAXSTACK		15000
+#endif
+
+
+/*
+@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
+** a Lua state with very fast access.
+** CHANGE it if you need a different size.
+*/
+#define LUA_EXTRASPACE		(sizeof(void *))
+
+
+/*
+@@ LUA_IDSIZE gives the maximum size for the description of the source
+@@ of a function in debug information.
+** CHANGE it if you want a different size.
+*/
+#define LUA_IDSIZE	60
+
+
+/*
+@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
+** CHANGE it if it uses too much C-stack space. (For long double,
+** 'string.format("%.99f", 1e4932)' needs ~5030 bytes, so a
+** smaller buffer would force a memory allocation for each call to
+** 'string.format'.)
+*/
+#if defined(LUA_FLOAT_LONGDOUBLE)
+#define LUAL_BUFFERSIZE		8192
+#else
+#define LUAL_BUFFERSIZE   ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
+#endif
+
+/* }================================================================== */
+
+
+/*
+@@ LUA_QL describes how error messages quote program elements.
+** Lua does not use these macros anymore; they are here for
+** compatibility only.
+*/
+#define LUA_QL(x)	"'" x "'"
+#define LUA_QS		LUA_QL("%s")
+
+
+
+
+/* =================================================================== */
+
+/*
+** Local configuration. You can use this space to add your redefinitions
+** without modifying the main part of the file.
+*/
+
+
+
+
+
+#endif
+

+ 58 - 0
src/external/lua/include/lualib.h

@@ -0,0 +1,58 @@
+/*
+** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp $
+** Lua standard libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lualib_h
+#define lualib_h
+
+#include "lua.h"
+
+
+
+LUAMOD_API int (luaopen_base) (lua_State *L);
+
+#define LUA_COLIBNAME	"coroutine"
+LUAMOD_API int (luaopen_coroutine) (lua_State *L);
+
+#define LUA_TABLIBNAME	"table"
+LUAMOD_API int (luaopen_table) (lua_State *L);
+
+#define LUA_IOLIBNAME	"io"
+LUAMOD_API int (luaopen_io) (lua_State *L);
+
+#define LUA_OSLIBNAME	"os"
+LUAMOD_API int (luaopen_os) (lua_State *L);
+
+#define LUA_STRLIBNAME	"string"
+LUAMOD_API int (luaopen_string) (lua_State *L);
+
+#define LUA_UTF8LIBNAME	"utf8"
+LUAMOD_API int (luaopen_utf8) (lua_State *L);
+
+#define LUA_BITLIBNAME	"bit32"
+LUAMOD_API int (luaopen_bit32) (lua_State *L);
+
+#define LUA_MATHLIBNAME	"math"
+LUAMOD_API int (luaopen_math) (lua_State *L);
+
+#define LUA_DBLIBNAME	"debug"
+LUAMOD_API int (luaopen_debug) (lua_State *L);
+
+#define LUA_LOADLIBNAME	"package"
+LUAMOD_API int (luaopen_package) (lua_State *L);
+
+
+/* open all previous libraries */
+LUALIB_API void (luaL_openlibs) (lua_State *L);
+
+
+
+#if !defined(lua_assert)
+#define lua_assert(x)	((void)0)
+#endif
+
+
+#endif

BIN
src/external/lua/lib/liblua53.a


BIN
src/external/lua/lib/liblua53dll.a


+ 3631 - 0
src/rlua.h

@@ -0,0 +1,3631 @@
+/**********************************************************************************************
+*
+*   rlua - raylib Lua bindings
+*
+*   NOTE 01:
+*   The following types:
+*       Color, Vector2, Vector3, Rectangle, Ray, Camera
+*   are treated as objects with named fields, same as in C.
+*   
+*   Lua defines utility functions for creating those objects.
+*   Usage:
+*       local cl = Color(255,255,255,255)
+*       local rec = Rectangle(10, 10, 100, 100)
+*       local ray = Ray(Vector3(20, 20, 20), Vector3(50, 50, 50))
+*       local x2 = rec.x + rec.width
+*
+*   The following types:
+*       Image, Texture2D, SpriteFont
+*   are immutable, and you can only read their non-pointer arguments (e.g. sprfnt.size).
+*
+*   All other object types are opaque, that is, you cannot access or
+*   change their fields directly.
+*
+*   Remember that ALL raylib types have REFERENCE SEMANTICS in Lua.
+*   There is currently no way to create a copy of an opaque object.
+*
+*   NOTE 02:
+*   Some raylib functions take a pointer to an array, and the size of that array.
+*   The equivalent Lua functions take only an array table of the specified type UNLESS
+*   it's a pointer to a large char array (e.g. for images), then it takes (and potentially returns) 
+*   a Lua string (without the size argument, as Lua strings are sized by default).
+*
+*   NOTE 03:
+*   Some raylib functions take pointers to objects to modify (e.g. ImageToPOT, etc.)
+*   In Lua, these functions take values and return a new changed value, instead.
+*   So, in C:
+*       ImageToPOT(&img, BLACK);
+*   In Lua becomes:
+*       img = ImageToPOT(img, BLACK)
+*
+*   Remember that functions can return multiple values, so:
+*       UpdateCameraPlayer(&cam, &playerPos);
+*       Vector3 vec = ResolveCollisionCubicmap(img, mapPos, &playerPos, 5.0);
+*   becomes:
+*       cam, playerPos = UpdateCameraPlayer(cam, playerPos)
+*       vec, playerPos = ResolveCollisionCubicmap(img, mapPos, playerPos, 5)
+*
+*   This is to preserve value semantics of raylib objects.
+*
+*
+*   This Lua binding for raylib was originally created by Ghassan Al-Mashareqa ([email protected])
+*   for raylib 1.3 and later on reviewed and updated to raylib 1.6 by Ramon Santamaria.
+*
+*   Copyright (c) 2015-2016 Ghassan Al-Mashareqa and Ramon Santamaria (@raysan5)
+*
+*   This software is provided "as-is", without any express or implied warranty. In no event
+*   will the authors be held liable for any damages arising from the use of this software.
+*
+*   Permission is granted to anyone to use this software for any purpose, including commercial
+*   applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+*     1. The origin of this software must not be misrepresented; you must not claim that you
+*     wrote the original software. If you use this software in a product, an acknowledgment
+*     in the product documentation would be appreciated but is not required.
+*
+*     2. Altered source versions must be plainly marked as such, and must not be misrepresented
+*     as being the original software.
+*
+*     3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#pragma once
+
+#include "raylib.h"
+
+#define RLUA_STATIC
+#ifdef RLUA_STATIC
+    #define RLUADEF static            // Functions just visible to module including this file
+#else
+    #ifdef __cplusplus
+        #define RLUADEF extern "C"    // Functions visible from other files (no name mangling of functions in C++)
+    #else
+        #define RLUADEF extern        // Functions visible from other files
+    #endif
+#endif
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+// ...
+
+//----------------------------------------------------------------------------------
+// Module Functions Declaration
+//----------------------------------------------------------------------------------
+RLUADEF void InitLuaDevice(void);                   // Initialize Lua system
+RLUADEF void ExecuteLuaCode(const char *code);      // Execute raylib Lua code
+RLUADEF void ExecuteLuaFile(const char *filename);  // Execute raylib Lua script
+RLUADEF void CloseLuaDevice(void);                  // De-initialize Lua system
+
+/***********************************************************************************
+*
+*   RLUA IMPLEMENTATION
+*
+************************************************************************************/
+
+#if defined(RLUA_IMPLEMENTATION)
+
+#include "raylib.h"
+#include "utils.h"
+#include "raymath.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+//----------------------------------------------------------------------------------
+// Defines and Macros
+//----------------------------------------------------------------------------------
+#define LuaPush_Image(L, img) LuaPushOpaqueTypeWithMetatable(L, img, Image)
+#define LuaPush_Texture2D(L, tex) LuaPushOpaqueTypeWithMetatable(L, tex, Texture2D)
+#define LuaPush_RenderTexture2D(L, tex) LuaPushOpaqueTypeWithMetatable(L, tex, RenderTexture2D)
+#define LuaPush_SpriteFont(L, sf) LuaPushOpaqueTypeWithMetatable(L, sf, SpriteFont)
+#define LuaPush_Mesh(L, vd) LuaPushOpaqueType(L, vd)
+#define LuaPush_Shader(L, s) LuaPushOpaqueType(L, s)
+#define LuaPush_Sound(L, snd) LuaPushOpaqueType(L, snd)
+#define LuaPush_Wave(L, wav) LuaPushOpaqueType(L, wav)
+#define LuaPush_Music(L, mus) LuaPushOpaqueType(L, mus)
+
+#define LuaGetArgument_string luaL_checkstring
+#define LuaGetArgument_int (int)luaL_checkinteger
+#define LuaGetArgument_unsigned (unsigned)luaL_checkinteger
+#define LuaGetArgument_char (char)luaL_checkinteger
+#define LuaGetArgument_float (float)luaL_checknumber
+#define LuaGetArgument_double luaL_checknumber
+#define LuaGetArgument_Image(L, img) *(Image*)LuaGetArgumentOpaqueTypeWithMetatable(L, img, "Image")
+#define LuaGetArgument_Texture2D(L, tex) *(Texture2D*)LuaGetArgumentOpaqueTypeWithMetatable(L, tex, "Texture2D")
+#define LuaGetArgument_RenderTexture2D(L, rtex) *(RenderTexture2D*)LuaGetArgumentOpaqueTypeWithMetatable(L, rtex, "RenderTexture2D")
+#define LuaGetArgument_SpriteFont(L, sf) *(SpriteFont*)LuaGetArgumentOpaqueTypeWithMetatable(L, sf, "SpriteFont")
+#define LuaGetArgument_Mesh(L, vd) *(Mesh*)LuaGetArgumentOpaqueType(L, vd)
+#define LuaGetArgument_Shader(L, s) *(Shader*)LuaGetArgumentOpaqueType(L, s)
+#define LuaGetArgument_Sound(L, snd) *(Sound*)LuaGetArgumentOpaqueType(L, snd)
+#define LuaGetArgument_Wave(L, wav) *(Wave*)LuaGetArgumentOpaqueType(L, wav)
+#define LuaGetArgument_Music(L, mus) *(Music*)LuaGetArgumentOpaqueType(L, mus)
+
+#define LuaPushOpaqueType(L, str) LuaPushOpaque(L, &str, sizeof(str))
+#define LuaPushOpaqueTypeWithMetatable(L, str, meta) LuaPushOpaqueWithMetatable(L, &str, sizeof(str), #meta)
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+static lua_State* mainLuaState = 0;
+static lua_State* L = 0;
+
+//----------------------------------------------------------------------------------
+// Module specific Functions Declaration
+//----------------------------------------------------------------------------------
+static void LuaPush_Color(lua_State* L, Color color);
+static void LuaPush_Vector2(lua_State* L, Vector2 vec);
+static void LuaPush_Vector3(lua_State* L, Vector3 vec);
+static void LuaPush_Quaternion(lua_State* L, Quaternion vec);
+static void LuaPush_Matrix(lua_State* L, Matrix *matrix);
+static void LuaPush_Rectangle(lua_State* L, Rectangle rect);
+static void LuaPush_Model(lua_State* L, Model mdl);
+static void LuaPush_Ray(lua_State* L, Ray ray);
+static void LuaPush_Camera(lua_State* L, Camera cam);
+
+static Vector2 LuaGetArgument_Vector2(lua_State* L, int index);
+static Vector3 LuaGetArgument_Vector3(lua_State* L, int index);
+static Quaternion LuaGetArgument_Quaternion(lua_State* L, int index);
+static Color LuaGetArgument_Color(lua_State* L, int index);
+static Rectangle LuaGetArgument_Rectangle(lua_State* L, int index);
+static Camera LuaGetArgument_Camera(lua_State* L, int index);
+static Ray LuaGetArgument_Ray(lua_State* L, int index);
+static Matrix LuaGetArgument_Matrix(lua_State* L, int index);
+static Model LuaGetArgument_Model(lua_State* L, int index);
+
+//----------------------------------------------------------------------------------
+// rlua Helper Functions
+//----------------------------------------------------------------------------------
+static void LuaStartEnum(void)
+{
+	lua_newtable(L);
+}
+
+static void LuaSetEnum(const char *name, int value)
+{
+	lua_pushinteger(L, value);
+	lua_setfield(L, -2, name);
+}
+
+static void LuaSetEnumColor(const char *name, Color color)
+{
+	LuaPush_Color(L, color);
+	lua_setfield(L, -2, name);
+}
+
+static void LuaEndEnum(const char *name)
+{
+	lua_setglobal(L, name);
+}
+
+static void LuaPushOpaque(lua_State* L, void *ptr, size_t size)
+{
+	void *ud = lua_newuserdata(L, size);
+	memcpy(ud, ptr, size);
+}
+
+static void LuaPushOpaqueWithMetatable(lua_State* L, void *ptr, size_t size, const char *metatable_name)
+{
+	void *ud = lua_newuserdata(L, size);
+	memcpy(ud, ptr, size);
+	luaL_setmetatable(L, metatable_name);
+}
+
+static void* LuaGetArgumentOpaqueType(lua_State* L, int index)
+{
+	return lua_touserdata(L, index);
+}
+
+static void* LuaGetArgumentOpaqueTypeWithMetatable(lua_State* L, int index, const char *metatable_name)
+{
+	return luaL_checkudata(L, index, metatable_name);
+}
+
+//----------------------------------------------------------------------------------
+// LuaIndex* functions
+//----------------------------------------------------------------------------------
+static int LuaIndexImage(lua_State* L)
+{
+	Image img = LuaGetArgument_Image(L, 1);
+	const char *key = luaL_checkstring(L, 2);
+	if (!strcmp(key, "width"))
+		lua_pushinteger(L, img.width);
+	else if (!strcmp(key, "height"))
+		lua_pushinteger(L, img.height);
+	else if (!strcmp(key, "mipmaps"))
+		lua_pushinteger(L, img.mipmaps);
+	else if (!strcmp(key, "format"))
+		lua_pushinteger(L, img.format);
+	else
+		return 0;
+	return 1;
+}
+
+static int LuaIndexTexture2D(lua_State* L)
+{
+	Texture2D img = LuaGetArgument_Texture2D(L, 1);
+	const char *key = luaL_checkstring(L, 2);
+	if (!strcmp(key, "width"))
+		lua_pushinteger(L, img.width);
+	else if (!strcmp(key, "height"))
+		lua_pushinteger(L, img.height);
+	else if (!strcmp(key, "mipmaps"))
+		lua_pushinteger(L, img.mipmaps);
+	else if (!strcmp(key, "format"))
+		lua_pushinteger(L, img.format);
+	else
+		return 0;
+	return 1;
+}
+
+// TODO: RenderTexture2D?
+
+static int LuaIndexSpriteFont(lua_State* L)
+{
+	SpriteFont img = LuaGetArgument_SpriteFont(L, 1);
+	const char *key = luaL_checkstring(L, 2);
+	if (!strcmp(key, "size"))
+		lua_pushinteger(L, img.size);
+	else if (!strcmp(key, "texture"))
+		LuaPush_Texture2D(L, img.texture);
+	else if (!strcmp(key, "numChars"))
+		lua_pushinteger(L, img.numChars);
+	else
+		return 0;
+	return 1;
+}
+
+static void LuaBuildOpaqueMetatables(void)
+{
+	luaL_newmetatable(L, "Image");
+	lua_pushcfunction(L, &LuaIndexImage);
+	lua_setfield(L, -2, "__index");
+	lua_pop(L, 1);
+
+	luaL_newmetatable(L, "Texture2D");
+	lua_pushcfunction(L, &LuaIndexTexture2D);
+	lua_setfield(L, -2, "__index");
+	lua_pop(L, 1);
+    
+    // TODO?
+    /*
+    luaL_newmetatable(L, "RenderTexture2D");
+	lua_pushcfunction(L, &LuaIndexRenderTexture2D);
+	lua_setfield(L, -2, "__index");
+	lua_pop(L, 1);
+    */
+	luaL_newmetatable(L, "SpriteFont");
+	lua_pushcfunction(L, &LuaIndexSpriteFont);
+	lua_setfield(L, -2, "__index");
+	lua_pop(L, 1);
+}
+
+//----------------------------------------------------------------------------------
+// LuaGetArgument functions
+//----------------------------------------------------------------------------------
+
+static Vector2 LuaGetArgument_Vector2(lua_State* L, int index)
+{
+	luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Vector2");
+	float x = (float)lua_tonumber(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Vector2");
+	float y = (float)lua_tonumber(L, -1);
+	lua_pop(L, 2);
+	return (Vector2) { x, y };
+}
+
+static Vector3 LuaGetArgument_Vector3(lua_State* L, int index)
+{
+	luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Vector3");
+	float x = (float)lua_tonumber(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Vector3");
+	float y = (float)lua_tonumber(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "z") == LUA_TNUMBER, index, "Expected Vector3");
+	float z = (float)lua_tonumber(L, -1);
+	lua_pop(L, 3);
+	return (Vector3) { x, y, z };
+}
+
+static Quaternion LuaGetArgument_Quaternion(lua_State* L, int index)
+{
+	luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Quaternion");
+	float x = (float)lua_tonumber(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Quaternion");
+	float y = (float)lua_tonumber(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "z") == LUA_TNUMBER, index, "Expected Quaternion");
+	float z = (float)lua_tonumber(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "w") == LUA_TNUMBER, index, "Expected Quaternion");
+	float w = (float)lua_tonumber(L, -1);
+	lua_pop(L, 4);
+	return (Quaternion) { x, y, z, w };
+}
+
+static Color LuaGetArgument_Color(lua_State* L, int index)
+{
+	luaL_argcheck(L, lua_getfield(L, index, "r") == LUA_TNUMBER, index, "Expected Color");
+	unsigned char r = (unsigned char)lua_tointeger(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "g") == LUA_TNUMBER, index, "Expected Color");
+	unsigned char g = (unsigned char)lua_tointeger(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "b") == LUA_TNUMBER, index, "Expected Color");
+	unsigned char b = (unsigned char)lua_tointeger(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "a") == LUA_TNUMBER, index, "Expected Color");
+	unsigned char a = (unsigned char)lua_tointeger(L, -1);
+	lua_pop(L, 4);
+	return (Color) { r, g, b, a };
+}
+
+static Rectangle LuaGetArgument_Rectangle(lua_State* L, int index)
+{
+	luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Rectangle");
+	int x = (int)lua_tointeger(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Rectangle");
+	int y = (int)lua_tointeger(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "width") == LUA_TNUMBER, index, "Expected Rectangle");
+	int w = (int)lua_tointeger(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "height") == LUA_TNUMBER, index, "Expected Rectangle");
+	int h = (int)lua_tointeger(L, -1);
+	lua_pop(L, 4);
+	return (Rectangle) { x, y, w, h };
+}
+
+static Camera LuaGetArgument_Camera(lua_State* L, int index)
+{
+	Camera result;
+	luaL_argcheck(L, lua_getfield(L, index, "position") == LUA_TTABLE, index, "Expected Camera");
+	result.position = LuaGetArgument_Vector3(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "target") == LUA_TTABLE, index, "Expected Camera");
+	result.target = LuaGetArgument_Vector3(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "up") == LUA_TTABLE, index, "Expected Camera");
+	result.up = LuaGetArgument_Vector3(L, -1);
+    luaL_argcheck(L, lua_getfield(L, index, "fovy") == LUA_TTABLE, index, "Expected Camera");
+	result.fovy = LuaGetArgument_float(L, -1);
+	lua_pop(L, 4);
+	return result;
+}
+
+static Camera2D LuaGetArgument_Camera2D(lua_State* L, int index)
+{
+	Camera2D result;
+	luaL_argcheck(L, lua_getfield(L, index, "offset") == LUA_TTABLE, index, "Expected Camera2D");
+	result.offset = LuaGetArgument_Vector2(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "target") == LUA_TTABLE, index, "Expected Camera2D");
+	result.target = LuaGetArgument_Vector2(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "rotation") == LUA_TTABLE, index, "Expected Camera2D");
+	result.rotation = LuaGetArgument_float(L, -1);
+    luaL_argcheck(L, lua_getfield(L, index, "zoom") == LUA_TTABLE, index, "Expected Camera2D");
+	result.zoom = LuaGetArgument_float(L, -1);
+	lua_pop(L, 4);
+	return result;
+}
+
+// TODO:
+//BoundingBox
+//LightData, *Light
+//MusicData *Music;
+//AudioStream
+
+// TODO: Review Mesh, Shader
+
+static BoundingBox LuaGetArgument_BoundingBox(lua_State* L, int index)
+{
+	BoundingBox result;
+	luaL_argcheck(L, lua_getfield(L, index, "min") == LUA_TTABLE, index, "Expected BoundingBox");
+	result.min = LuaGetArgument_Vector3(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "max") == LUA_TTABLE, index, "Expected BoundingBox");
+	result.max = LuaGetArgument_Vector3(L, -1);
+	lua_pop(L, 2);
+	return result;
+}
+
+static Ray LuaGetArgument_Ray(lua_State* L, int index)
+{
+	Ray result;
+	luaL_argcheck(L, lua_getfield(L, index, "position") == LUA_TTABLE, index, "Expected Ray");
+	result.position = LuaGetArgument_Vector3(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "direction") == LUA_TTABLE, index, "Expected Ray");
+	result.direction = LuaGetArgument_Vector3(L, -1);
+	lua_pop(L, 2);
+	return result;
+}
+
+static Matrix LuaGetArgument_Matrix(lua_State* L, int index)
+{
+	Matrix result = { 0 };
+	float* ptr = &result.m0;
+	for (int i = 0; i < 16; i++)
+	{
+		lua_geti(L, -1, i+1);
+		ptr[i] = luaL_checkinteger(L, -1);
+	}
+	lua_pop(L, 16);
+	return result;
+}
+
+static Material LuaGetArgument_Material(lua_State* L, int index)
+{
+    Material result;
+    luaL_argcheck(L, lua_getfield(L, index, "shader") == LUA_TUSERDATA, index, "Expected Material");
+	result.shader = LuaGetArgument_Shader(L, -1);
+    luaL_argcheck(L, lua_getfield(L, index, "texDiffuse") == LUA_TUSERDATA, index, "Expected Material");
+	result.texDiffuse = LuaGetArgument_Texture2D(L, -1);
+    luaL_argcheck(L, lua_getfield(L, index, "texNormal") == LUA_TUSERDATA, index, "Expected Material");
+	result.texNormal = LuaGetArgument_Texture2D(L, -1);
+    luaL_argcheck(L, lua_getfield(L, index, "texSpecular") == LUA_TUSERDATA, index, "Expected Material");
+	result.texSpecular = LuaGetArgument_Texture2D(L, -1);
+    luaL_argcheck(L, lua_getfield(L, index, "colDiffuse") == LUA_TUSERDATA, index, "Expected Material");
+	result.colDiffuse = LuaGetArgument_Color(L, -1);
+    luaL_argcheck(L, lua_getfield(L, index, "colAmbient") == LUA_TUSERDATA, index, "Expected Material");
+	result.colAmbient = LuaGetArgument_Color(L, -1);
+    luaL_argcheck(L, lua_getfield(L, index, "colSpecular") == LUA_TUSERDATA, index, "Expected Material");
+	result.colSpecular = LuaGetArgument_Color(L, -1);
+    luaL_argcheck(L, lua_getfield(L, index, "glossiness") == LUA_TUSERDATA, index, "Expected Material");
+	result.glossiness = LuaGetArgument_float(L, -1);
+    lua_pop(L, 8);
+    return result;
+}
+
+static Model LuaGetArgument_Model(lua_State* L, int index)
+{
+	Model result;
+	luaL_argcheck(L, lua_getfield(L, index, "mesh") == LUA_TUSERDATA, index, "Expected Model");
+	result.mesh = LuaGetArgument_Mesh(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "transform") == LUA_TTABLE, index, "Expected Model");
+	result.transform = LuaGetArgument_Matrix(L, -1);
+	luaL_argcheck(L, lua_getfield(L, index, "material") == LUA_TTABLE, index, "Expected Model");
+	result.material = LuaGetArgument_Material(L, -1);
+	lua_pop(L, 3);
+	return result;
+}
+
+//----------------------------------------------------------------------------------
+// LuaPush functions
+//----------------------------------------------------------------------------------
+static void LuaPush_Color(lua_State* L, Color color)
+{
+	lua_createtable(L, 0, 4);
+	lua_pushinteger(L, color.r);
+	lua_setfield(L, -2, "r");
+	lua_pushinteger(L, color.g);
+	lua_setfield(L, -2, "g");
+	lua_pushinteger(L, color.b);
+	lua_setfield(L, -2, "b");
+	lua_pushinteger(L, color.a);
+	lua_setfield(L, -2, "a");
+}
+
+static void LuaPush_Vector2(lua_State* L, Vector2 vec)
+{
+	lua_createtable(L, 0, 2);
+	lua_pushnumber(L, vec.x);
+	lua_setfield(L, -2, "x");
+	lua_pushnumber(L, vec.y);
+	lua_setfield(L, -2, "y");
+}
+
+static void LuaPush_Vector3(lua_State* L, Vector3 vec)
+{
+	lua_createtable(L, 0, 3);
+	lua_pushnumber(L, vec.x);
+	lua_setfield(L, -2, "x");
+	lua_pushnumber(L, vec.y);
+	lua_setfield(L, -2, "y");
+	lua_pushnumber(L, vec.z);
+	lua_setfield(L, -2, "z");
+}
+
+static void LuaPush_Quaternion(lua_State* L, Quaternion vec)
+{
+	lua_createtable(L, 0, 4);
+	lua_pushnumber(L, vec.x);
+	lua_setfield(L, -2, "x");
+	lua_pushnumber(L, vec.y);
+	lua_setfield(L, -2, "y");
+	lua_pushnumber(L, vec.z);
+	lua_setfield(L, -2, "z");
+	lua_pushnumber(L, vec.w);
+	lua_setfield(L, -2, "w");
+}
+
+static void LuaPush_Matrix(lua_State* L, Matrix *matrix)
+{
+	int i;
+	lua_createtable(L, 16, 0);
+	float* num = (&matrix->m0);
+	for (i = 0; i < 16; i++)
+	{
+		lua_pushnumber(L, num[i]);
+		lua_rawseti(L, -2, i + 1);
+	}
+}
+
+static void LuaPush_Rectangle(lua_State* L, Rectangle rect)
+{
+	lua_createtable(L, 0, 4);
+	lua_pushinteger(L, rect.x);
+	lua_setfield(L, -2, "x");
+	lua_pushinteger(L, rect.y);
+	lua_setfield(L, -2, "y");
+	lua_pushinteger(L, rect.width);
+	lua_setfield(L, -2, "width");
+	lua_pushinteger(L, rect.height);
+	lua_setfield(L, -2, "height");
+}
+
+static void LuaPush_Ray(lua_State* L, Ray ray)
+{
+	lua_createtable(L, 0, 2);
+	LuaPush_Vector3(L, ray.position);
+	lua_setfield(L, -2, "position");
+	LuaPush_Vector3(L, ray.direction);
+	lua_setfield(L, -2, "direction");
+}
+
+static void LuaPush_BoundingBox(lua_State* L, BoundingBox bb)
+{
+	lua_createtable(L, 0, 2);
+	LuaPush_Vector3(L, bb.min);
+	lua_setfield(L, -2, "min");
+	LuaPush_Vector3(L, bb.max);
+	lua_setfield(L, -2, "max");
+}
+
+static void LuaPush_Camera(lua_State* L, Camera cam)
+{
+	lua_createtable(L, 0, 4);
+	LuaPush_Vector3(L, cam.position);
+	lua_setfield(L, -2, "position");
+	LuaPush_Vector3(L, cam.target);
+	lua_setfield(L, -2, "target");
+	LuaPush_Vector3(L, cam.up);
+	lua_setfield(L, -2, "up");
+    lua_pushnumber(L, cam.fovy);
+	lua_setfield(L, -2, "fovy");
+}
+
+static void LuaPush_Camera2D(lua_State* L, Camera2D cam)
+{
+	lua_createtable(L, 0, 3);
+	LuaPush_Vector2(L, cam.offset);
+	lua_setfield(L, -2, "offset");
+	LuaPush_Vector2(L, cam.target);
+	lua_setfield(L, -2, "target");
+	lua_pushnumber(L, cam.rotation);
+	lua_setfield(L, -2, "rotation");
+    lua_pushnumber(L, cam.zoom);
+	lua_setfield(L, -2, "zoom");
+}
+
+static void LuaPush_Material(lua_State* L, Material mat)
+{
+	lua_createtable(L, 0, 8);
+	LuaPush_Shader(L, mat.shader);
+	lua_setfield(L, -2, "shader");
+	LuaPush_Texture2D(L, mat.texDiffuse);
+	lua_setfield(L, -2, "texDiffuse");
+	LuaPush_Texture2D(L, mat.texNormal);
+	lua_setfield(L, -2, "texNormal");
+    LuaPush_Texture2D(L, mat.texSpecular);
+	lua_setfield(L, -2, "texSpecular");
+    LuaPush_Color(L, mat.colDiffuse);
+	lua_setfield(L, -2, "colDiffuse");
+    LuaPush_Color(L, mat.colAmbient);
+	lua_setfield(L, -2, "colAmbient");
+    LuaPush_Color(L, mat.colSpecular);
+	lua_setfield(L, -2, "colSpecular");
+    lua_pushnumber(L, mat.glossiness);
+	lua_setfield(L, -2, "glossiness");
+}
+
+static void LuaPush_Model(lua_State* L, Model mdl)
+{
+	lua_createtable(L, 0, 4);
+	LuaPush_Mesh(L, mdl.mesh);
+	lua_setfield(L, -2, "mesh");
+	LuaPush_Matrix(L, &mdl.transform);
+	lua_setfield(L, -2, "transform");
+	LuaPush_Material(L, mdl.material);
+	lua_setfield(L, -2, "material");
+}
+
+//----------------------------------------------------------------------------------
+// raylib Lua Structure constructors
+//----------------------------------------------------------------------------------
+static int lua_Color(lua_State* L)
+{
+	LuaPush_Color(L, (Color) { (unsigned char)luaL_checkinteger(L, 1), (unsigned char)luaL_checkinteger(L, 2), (unsigned char)luaL_checkinteger(L, 3), (unsigned char)luaL_checkinteger(L, 4) });
+	return 1;
+}
+
+static int lua_Vector2(lua_State* L)
+{
+	LuaPush_Vector2(L, (Vector2) { (float)luaL_checknumber(L, 1), (float)luaL_checknumber(L, 2) });
+	return 1;
+}
+
+static int lua_Vector3(lua_State* L)
+{
+	LuaPush_Vector3(L, (Vector3) { (float)luaL_checknumber(L, 1), (float)luaL_checknumber(L, 2), (float)luaL_checknumber(L, 3) });
+	return 1;
+}
+
+static int lua_Rectangle(lua_State* L)
+{
+	LuaPush_Rectangle(L, (Rectangle) { (int)luaL_checkinteger(L, 1), (int)luaL_checkinteger(L, 2), (int)luaL_checkinteger(L, 3), (int)luaL_checkinteger(L, 4) });
+	return 1;
+}
+
+static int lua_Ray(lua_State* L)
+{
+	Vector2 pos = LuaGetArgument_Vector2(L, 1);
+	Vector2 dir = LuaGetArgument_Vector2(L, 2);
+	LuaPush_Ray(L, (Ray) { { pos.x, pos.y }, { dir.x, dir.y } });
+	return 1;
+}
+
+static int lua_Camera(lua_State* L)
+{
+	Vector3 pos = LuaGetArgument_Vector3(L, 1);
+	Vector3 tar = LuaGetArgument_Vector3(L, 2);
+	Vector3 up = LuaGetArgument_Vector3(L, 3);
+    float fovy = LuaGetArgument_float(L, 4);
+	LuaPush_Camera(L, (Camera) { { pos.x, pos.y, pos.z }, { tar.x, tar.y, tar.z }, { up.x, up.y, up.z }, fovy });
+	return 1;
+}
+
+static int lua_Camera2D(lua_State* L)
+{
+	Vector2 off = LuaGetArgument_Vector2(L, 1);
+	Vector2 tar = LuaGetArgument_Vector2(L, 2);
+	float rot = LuaGetArgument_float(L, 3);
+    float zoom = LuaGetArgument_float(L, 4);
+	LuaPush_Camera2D(L, (Camera2D) { { off.x, off.y }, { tar.x, tar.y }, rot, zoom });
+	return 1;
+}
+
+
+/*************************************************************************************
+*  raylib Lua Functions Bindings
+**************************************************************************************/
+
+//------------------------------------------------------------------------------------
+// raylib [core] module functions - Window and Graphics Device
+//------------------------------------------------------------------------------------
+int lua_InitWindow(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	const char* arg3 = LuaGetArgument_string(L, 3);
+	InitWindow(arg1, arg2, arg3);
+	return 0;
+}
+
+int lua_CloseWindow(lua_State* L)
+{
+	CloseWindow();
+	return 0;
+}
+
+int lua_WindowShouldClose(lua_State* L)
+{
+	bool result = WindowShouldClose();
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_IsWindowMinimized(lua_State* L)
+{
+	bool result = IsWindowMinimized();
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_ToggleFullscreen(lua_State* L)
+{
+	ToggleFullscreen();
+	return 0;
+}
+
+int lua_GetScreenWidth(lua_State* L)
+{
+	int result = GetScreenWidth();
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+int lua_GetScreenHeight(lua_State* L)
+{
+	int result = GetScreenHeight();
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+int lua_ShowCursor(lua_State* L)
+{
+	ShowCursor();
+	return 0;
+}
+
+int lua_HideCursor(lua_State* L)
+{
+	HideCursor();
+	return 0;
+}
+
+int lua_IsCursorHidden(lua_State* L)
+{
+	bool result = IsCursorHidden();
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+// TODO:
+/*
+void EnableCursor(void);                                    // Enables cursor
+void DisableCursor(void);                                   // Disables cursor
+*/
+
+int lua_ClearBackground(lua_State* L)
+{
+	Color arg1 = LuaGetArgument_Color(L, 1);
+	ClearBackground(arg1);
+	return 0;
+}
+
+int lua_BeginDrawing(lua_State* L)
+{
+	BeginDrawing();
+	return 0;
+}
+
+int lua_EndDrawing(lua_State* L)
+{
+	EndDrawing();
+	return 0;
+}
+
+// TODO:
+//void Begin2dMode(Camera2D camera);                          // Initialize 2D mode with custom camera
+//void End2dMode(void);                                       // Ends 2D mode custom camera usage
+
+int lua_Begin3dMode(lua_State* L)
+{
+	Camera arg1 = LuaGetArgument_Camera(L, 1);
+	Begin3dMode(arg1);
+	return 0;
+}
+
+int lua_End3dMode(lua_State* L)
+{
+	End3dMode();
+	return 0;
+}
+
+// TODO:
+//void BeginTextureMode(RenderTexture2D target);              // Initializes render texture for drawing
+//void EndTextureMode(void);                                  // Ends drawing to render texture
+
+int lua_GetMouseRay(lua_State* L)
+{
+	Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+	Camera arg2 = LuaGetArgument_Camera(L, 2);
+	Ray result = GetMouseRay(arg1, arg2);
+	LuaPush_Ray(L, result);
+	return 1;
+}
+
+// TODO: 
+//Vector2 GetWorldToScreen(Vector3 position, Camera camera);  // Returns the screen space position from a 3d world space position
+//Matrix GetCameraMatrix(Camera camera);                      // Returns camera transform matrix (view matrix)
+
+#if defined(PLATFORM_WEB)
+
+static int LuaDrawLoopFunc;
+
+static void LuaDrawLoop()
+{
+	lua_rawgeti(L, LUA_REGISTRYINDEX, LuaDrawLoopFunc);
+	lua_call(L, 0, 0);
+}
+
+int lua_SetDrawingLoop(lua_State* L)
+{
+	luaL_argcheck(L, lua_isfunction(L, 1), 1, "Loop function expected");
+	lua_pushvalue(L, 1);
+	LuaDrawLoopFunc = luaL_ref(L, LUA_REGISTRYINDEX);
+	SetDrawingLoop(&LuaDrawLoop);
+	return 0;
+}
+
+#else
+
+int lua_SetTargetFPS(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	SetTargetFPS(arg1);
+	return 0;
+}
+#endif
+
+int lua_GetFPS(lua_State* L)
+{
+	float result = GetFPS();
+	lua_pushnumber(L, result);
+	return 1;
+}
+
+int lua_GetFrameTime(lua_State* L)
+{
+	float result = GetFrameTime();
+	lua_pushnumber(L, result);
+	return 1;
+}
+
+int lua_GetColor(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	Color result = GetColor(arg1);
+	LuaPush_Color(L, result);
+	return 1;
+}
+
+int lua_GetHexValue(lua_State* L)
+{
+	Color arg1 = LuaGetArgument_Color(L, 1);
+	int result = GetHexValue(arg1);
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+// TODO:
+/*
+float *ColorToFloat(Color color);                           // Converts Color to float array and normalizes
+float *VectorToFloat(Vector3 vec);                          // Converts Vector3 to float array
+float *MatrixToFloat(Matrix mat);                           // Converts Matrix to float array
+*/
+
+int lua_GetRandomValue(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	int result = GetRandomValue(arg1, arg2);
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+int lua_Fade(lua_State* L)
+{
+	Color arg1 = LuaGetArgument_Color(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	Color result = Fade(arg1, arg2);
+	LuaPush_Color(L, result);
+	return 1;
+}
+
+int lua_SetConfigFlags(lua_State* L)
+{
+	char arg1 = LuaGetArgument_char(L, 1);
+	SetConfigFlags(arg1);
+	return 0;
+}
+
+int lua_ShowLogo(lua_State* L)
+{
+	ShowLogo();
+	return 0;
+}
+
+int lua_IsFileDropped(lua_State* L)
+{
+	bool result = IsFileDropped();
+	lua_pushboolean(L, result);
+	return 1;
+}
+/*
+int lua_*GetDroppedFiles(lua_State* L)
+{
+	int * arg1 = LuaGetArgument_int *(L, 1);
+	//char * result = *GetDroppedFiles(arg1);
+	LuaPush_//char *(L, result);
+		return 1;
+}
+*/
+int lua_ClearDroppedFiles(lua_State* L)
+{
+	ClearDroppedFiles();
+	return 0;
+}
+
+int lua_StorageSaveValue(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	StorageSaveValue(arg1, arg2);
+	return 0;
+}
+
+int lua_StorageLoadValue(lua_State* L)
+{
+    int arg1 = LuaGetArgument_int(L, 1);
+	int result = StorageLoadValue(arg1);
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+//------------------------------------------------------------------------------------
+// raylib [core] module functions - Input Handling
+//------------------------------------------------------------------------------------
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
+int lua_IsKeyPressed(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	bool result = IsKeyPressed(arg1);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_IsKeyDown(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	bool result = IsKeyDown(arg1);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_IsKeyReleased(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	bool result = IsKeyReleased(arg1);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_IsKeyUp(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	bool result = IsKeyUp(arg1);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_GetKeyPressed(lua_State* L)
+{
+	int result = GetKeyPressed();
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+int lua_SetExitKey(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	SetExitKey(arg1);
+	return 0;
+}
+
+int lua_IsGamepadAvailable(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	bool result = IsGamepadAvailable(arg1);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+// TODO: Review
+// float GetGamepadAxisMovement(int gamepad, int axis);    // Return axis movement value for a gamepad axis
+/*
+int lua_GetGamepadMovement(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	Vector2 result = GetGamepadMovement(arg1);
+	LuaPush_Vector2(L, result);
+	return 1;
+}
+*/
+
+int lua_IsGamepadButtonPressed(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	bool result = IsGamepadButtonPressed(arg1, arg2);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_IsGamepadButtonDown(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	bool result = IsGamepadButtonDown(arg1, arg2);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_IsGamepadButtonReleased(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	bool result = IsGamepadButtonReleased(arg1, arg2);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_IsGamepadButtonUp(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	bool result = IsGamepadButtonUp(arg1, arg2);
+	lua_pushboolean(L, result);
+	return 1;
+}
+#endif
+
+int lua_IsMouseButtonPressed(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	bool result = IsMouseButtonPressed(arg1);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_IsMouseButtonDown(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	bool result = IsMouseButtonDown(arg1);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_IsMouseButtonReleased(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	bool result = IsMouseButtonReleased(arg1);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_IsMouseButtonUp(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	bool result = IsMouseButtonUp(arg1);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_GetMouseX(lua_State* L)
+{
+	int result = GetMouseX();
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+int lua_GetMouseY(lua_State* L)
+{
+	int result = GetMouseY();
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+int lua_GetMousePosition(lua_State* L)
+{
+	Vector2 result = GetMousePosition();
+	LuaPush_Vector2(L, result);
+	return 1;
+}
+
+int lua_SetMousePosition(lua_State* L)
+{
+	Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+	SetMousePosition(arg1);
+	return 0;
+}
+
+int lua_GetMouseWheelMove(lua_State* L)
+{
+	int result = GetMouseWheelMove();
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+int lua_GetTouchX(lua_State* L)
+{
+	int result = GetTouchX();
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+int lua_GetTouchY(lua_State* L)
+{
+	int result = GetTouchY();
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+int lua_GetTouchPosition(lua_State* L)
+{
+    int arg1 = LuaGetArgument_int(L, 1);
+	Vector2 result = GetTouchPosition(arg1);
+	LuaPush_Vector2(L, result);
+	return 1;
+}
+
+// TODO:
+/*
+#if defined(PLATFORM_ANDROID)
+bool IsButtonPressed(int button);                       // Detect if an android physic button has been pressed
+bool IsButtonDown(int button);                          // Detect if an android physic button is being pressed
+bool IsButtonReleased(int button);                      // Detect if an android physic button has been released
+#endif
+*/
+
+//------------------------------------------------------------------------------------
+// raylib [gestures] module functions - Gestures and Touch Handling
+//------------------------------------------------------------------------------------
+int lua_SetGesturesEnabled(lua_State* L)
+{
+	unsigned arg1 = LuaGetArgument_unsigned(L, 1);
+	SetGesturesEnabled(arg1);
+	return 0;
+}
+
+int lua_IsGestureDetected(lua_State* L)
+{
+    int arg1 = LuaGetArgument_int(L, 1);
+	bool result = IsGestureDetected(arg1);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+// TODO:
+///void ProcessGestureEvent(GestureEvent event);           // Process gesture event and translate it into gestures
+
+int lua_UpdateGestures(lua_State* L)
+{
+	UpdateGestures();
+	return 0;
+}
+
+int lua_GetTouchPointsCount(lua_State* L)
+{
+	int result = GetTouchPointsCount();
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+int lua_GetGestureDetected(lua_State* L)
+{
+	int result = GetGestureDetected();
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+int lua_GetGestureHoldDuration(lua_State* L)
+{
+	int result = GetGestureHoldDuration();
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+int lua_GetGestureDragVector(lua_State* L)
+{
+	Vector2 result = GetGestureDragVector();
+	LuaPush_Vector2(L, result);
+	return 1;
+}
+
+int lua_GetGestureDragAngle(lua_State* L)
+{
+	float result = GetGestureDragAngle();
+	lua_pushnumber(L, result);
+	return 1;
+}
+
+int lua_GetGesturePinchVector(lua_State* L)
+{
+	Vector2 result = GetGesturePinchVector();
+	LuaPush_Vector2(L, result);
+	return 1;
+}
+
+int lua_GetGesturePinchAngle(lua_State* L)
+{
+	float result = GetGesturePinchAngle();
+	lua_pushnumber(L, result);
+	return 1;
+}
+
+//------------------------------------------------------------------------------------
+// raylib [camera] module functions - Camera System
+//------------------------------------------------------------------------------------
+int lua_SetCameraMode(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	SetCameraMode(arg1);
+	return 0;
+}
+
+int lua_UpdateCamera(lua_State* L)
+{
+	Camera arg1 = LuaGetArgument_Camera(L, 1);
+	UpdateCamera(&arg1);
+	LuaPush_Camera(L, arg1);
+	return 1;
+}
+
+int lua_UpdateCameraPlayer(lua_State* L)
+{
+	Camera arg1 = LuaGetArgument_Camera(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	UpdateCameraPlayer(&arg1, &arg2);
+	LuaPush_Camera(L, arg1);
+	LuaPush_Vector3(L, arg2);
+	return 2;
+}
+
+int lua_SetCameraPosition(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	SetCameraPosition(arg1);
+	return 0;
+}
+
+int lua_SetCameraTarget(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	SetCameraTarget(arg1);
+	return 0;
+}
+
+int lua_SetCameraFovy(lua_State* L)
+{
+	float arg1 = LuaGetArgument_float(L, 1);
+	SetCameraFovy(arg1);
+	return 0;
+}
+
+int lua_SetCameraPanControl(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	SetCameraPanControl(arg1);
+	return 0;
+}
+
+int lua_SetCameraAltControl(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	SetCameraAltControl(arg1);
+	return 0;
+}
+
+int lua_SetCameraSmoothZoomControl(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	SetCameraSmoothZoomControl(arg1);
+	return 0;
+}
+
+int lua_SetCameraMoveControls(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	int arg4 = LuaGetArgument_int(L, 4);
+	int arg5 = LuaGetArgument_int(L, 5);
+	int arg6 = LuaGetArgument_int(L, 6);
+	SetCameraMoveControls(arg1, arg2, arg3, arg4, arg5, arg6);
+	return 0;
+}
+
+int lua_SetCameraMouseSensitivity(lua_State* L)
+{
+	float arg1 = LuaGetArgument_float(L, 1);
+	SetCameraMouseSensitivity(arg1);
+	return 0;
+}
+
+//------------------------------------------------------------------------------------
+// raylib [shapes] module functions - Basic Shapes Drawing
+//------------------------------------------------------------------------------------
+int lua_DrawPixel(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	Color arg3 = LuaGetArgument_Color(L, 3);
+	DrawPixel(arg1, arg2, arg3);
+	return 0;
+}
+
+int lua_DrawPixelV(lua_State* L)
+{
+	Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+	Color arg2 = LuaGetArgument_Color(L, 2);
+	DrawPixelV(arg1, arg2);
+	return 0;
+}
+
+int lua_DrawLine(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	int arg4 = LuaGetArgument_int(L, 4);
+	Color arg5 = LuaGetArgument_Color(L, 5);
+	DrawLine(arg1, arg2, arg3, arg4, arg5);
+	return 0;
+}
+
+int lua_DrawLineV(lua_State* L)
+{
+	Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+	Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+	Color arg3 = LuaGetArgument_Color(L, 3);
+	DrawLineV(arg1, arg2, arg3);
+	return 0;
+}
+
+int lua_DrawCircle(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	Color arg4 = LuaGetArgument_Color(L, 4);
+	DrawCircle(arg1, arg2, arg3, arg4);
+	return 0;
+}
+
+int lua_DrawCircleGradient(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	Color arg4 = LuaGetArgument_Color(L, 4);
+	Color arg5 = LuaGetArgument_Color(L, 5);
+	DrawCircleGradient(arg1, arg2, arg3, arg4, arg5);
+	return 0;
+}
+
+int lua_DrawCircleV(lua_State* L)
+{
+	Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	Color arg3 = LuaGetArgument_Color(L, 3);
+	DrawCircleV(arg1, arg2, arg3);
+	return 0;
+}
+
+int lua_DrawCircleLines(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	Color arg4 = LuaGetArgument_Color(L, 4);
+	DrawCircleLines(arg1, arg2, arg3, arg4);
+	return 0;
+}
+
+int lua_DrawRectangle(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	int arg4 = LuaGetArgument_int(L, 4);
+	Color arg5 = LuaGetArgument_Color(L, 5);
+	DrawRectangle(arg1, arg2, arg3, arg4, arg5);
+	return 0;
+}
+
+int lua_DrawRectangleRec(lua_State* L)
+{
+	Rectangle arg1 = LuaGetArgument_Rectangle(L, 1);
+	Color arg2 = LuaGetArgument_Color(L, 2);
+	DrawRectangleRec(arg1, arg2);
+	return 0;
+}
+
+int lua_DrawRectangleGradient(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	int arg4 = LuaGetArgument_int(L, 4);
+	Color arg5 = LuaGetArgument_Color(L, 5);
+	Color arg6 = LuaGetArgument_Color(L, 6);
+	DrawRectangleGradient(arg1, arg2, arg3, arg4, arg5, arg6);
+	return 0;
+}
+
+int lua_DrawRectangleV(lua_State* L)
+{
+	Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+	Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+	Color arg3 = LuaGetArgument_Color(L, 3);
+	DrawRectangleV(arg1, arg2, arg3);
+	return 0;
+}
+
+int lua_DrawRectangleLines(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	int arg4 = LuaGetArgument_int(L, 4);
+	Color arg5 = LuaGetArgument_Color(L, 5);
+	DrawRectangleLines(arg1, arg2, arg3, arg4, arg5);
+	return 0;
+}
+
+int lua_DrawTriangle(lua_State* L)
+{
+	Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+	Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+	Vector2 arg3 = LuaGetArgument_Vector2(L, 3);
+	Color arg4 = LuaGetArgument_Color(L, 4);
+	DrawTriangle(arg1, arg2, arg3, arg4);
+	return 0;
+}
+
+int lua_DrawTriangleLines(lua_State* L)
+{
+	Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+	Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+	Vector2 arg3 = LuaGetArgument_Vector2(L, 3);
+	Color arg4 = LuaGetArgument_Color(L, 4);
+	DrawTriangleLines(arg1, arg2, arg3, arg4);
+	return 0;
+}
+
+int lua_DrawPoly(lua_State* L)
+{
+	Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	float arg4 = LuaGetArgument_float(L, 4);
+	Color arg5 = LuaGetArgument_Color(L, 5);
+	DrawPoly(arg1, arg2, arg3, arg4, arg5);
+	return 0;
+}
+
+#define GET_TABLE(type, name, index) \
+	type* name = 0; \
+	size_t name##_size = 0; \
+	{ \
+		size_t sz = 0; \
+		luaL_checktype(L, index, LUA_TTABLE); \
+		lua_pushnil(L); \
+		while (lua_next(L, index)) { \
+			LuaGetArgument_##type(L, -1); \
+			sz++; \
+			lua_pop(L, 1); \
+		} \
+		lua_pop(L, 1); \
+		name = calloc(sz, sizeof(type)); \
+		sz = 0; \
+		lua_pushnil(L); \
+		while (lua_next(L, index)) { \
+			name[sz] = LuaGetArgument_##type(L, -1); \
+			sz++; \
+			lua_pop(L, 1); \
+		} \
+		lua_pop(L, 1); \
+		name##_size = sz; \
+	}
+
+
+int lua_DrawPolyEx(lua_State* L)
+{
+	GET_TABLE(Vector2, arg1, 1);
+	Color arg2 = LuaGetArgument_Color(L, 2);
+	DrawPolyEx(arg1, arg1_size, arg2);
+	free(arg1);
+	return 0;
+}
+
+int lua_DrawPolyExLines(lua_State* L)
+{
+	GET_TABLE(Vector2, arg1, 1);
+	Color arg2 = LuaGetArgument_Color(L, 2);
+	DrawPolyExLines(arg1, arg1_size, arg2);
+	free(arg1);
+	return 0;
+}
+
+int lua_CheckCollisionRecs(lua_State* L)
+{
+	Rectangle arg1 = LuaGetArgument_Rectangle(L, 1);
+	Rectangle arg2 = LuaGetArgument_Rectangle(L, 2);
+	bool result = CheckCollisionRecs(arg1, arg2);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_CheckCollisionCircles(lua_State* L)
+{
+	Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	Vector2 arg3 = LuaGetArgument_Vector2(L, 3);
+	float arg4 = LuaGetArgument_float(L, 4);
+	bool result = CheckCollisionCircles(arg1, arg2, arg3, arg4);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_CheckCollisionCircleRec(lua_State* L)
+{
+	Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	Rectangle arg3 = LuaGetArgument_Rectangle(L, 3);
+	bool result = CheckCollisionCircleRec(arg1, arg2, arg3);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_GetCollisionRec(lua_State* L)
+{
+	Rectangle arg1 = LuaGetArgument_Rectangle(L, 1);
+	Rectangle arg2 = LuaGetArgument_Rectangle(L, 2);
+	Rectangle result = GetCollisionRec(arg1, arg2);
+	LuaPush_Rectangle(L, result);
+	return 1;
+}
+
+int lua_CheckCollisionPointRec(lua_State* L)
+{
+	Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+	Rectangle arg2 = LuaGetArgument_Rectangle(L, 2);
+	bool result = CheckCollisionPointRec(arg1, arg2);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_CheckCollisionPointCircle(lua_State* L)
+{
+	Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+	Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	bool result = CheckCollisionPointCircle(arg1, arg2, arg3);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_CheckCollisionPointTriangle(lua_State* L)
+{
+	Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+	Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+	Vector2 arg3 = LuaGetArgument_Vector2(L, 3);
+	Vector2 arg4 = LuaGetArgument_Vector2(L, 4);
+	bool result = CheckCollisionPointTriangle(arg1, arg2, arg3, arg4);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+//------------------------------------------------------------------------------------
+// raylib [textures] module functions - Texture Loading and Drawing
+//------------------------------------------------------------------------------------
+int lua_LoadImage(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	Image result = LoadImage(arg1);
+	LuaPush_Image(L, result);
+	return 1;
+}
+
+int lua_LoadImageEx(lua_State* L)
+{
+	//Color * arg1 = LuaGetArgument_Color *(L, 1);
+	GET_TABLE(Color, arg1, 1);
+
+	int arg2 = LuaGetArgument_int(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	Image result = LoadImageEx(arg1, arg2, arg3);
+	LuaPush_Image(L, result);
+
+	free(arg1);
+	return 1;
+}
+
+int lua_LoadImageRaw(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	int arg4 = LuaGetArgument_int(L, 4);
+	int arg5 = LuaGetArgument_int(L, 5);
+	Image result = LoadImageRaw(arg1, arg2, arg3, arg4, arg5);
+	LuaPush_Image(L, result);
+	return 1;
+}
+
+int lua_LoadImageFromRES(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	Image result = LoadImageFromRES(arg1, arg2);
+	LuaPush_Image(L, result);
+	return 1;
+}
+
+int lua_LoadTexture(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	Texture2D result = LoadTexture(arg1);
+	LuaPush_Texture2D(L, result);
+	return 1;
+}
+
+// TODO: Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat);
+int lua_LoadTextureEx(lua_State* L)
+{
+	void * arg1 = LuaGetArgument_string(L, 1);  // TODO: How to get a void * ?
+    int arg2 = LuaGetArgument_int(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	int arg4 = LuaGetArgument_int(L, 4);
+	Texture2D result = LoadTextureEx(arg1, arg2, arg3, arg4);
+	LuaPush_Texture2D(L, result);
+	return 1;
+}
+
+int lua_LoadTextureFromRES(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	Texture2D result = LoadTextureFromRES(arg1, arg2);
+	LuaPush_Texture2D(L, result);
+	return 1;
+}
+
+int lua_LoadTextureFromImage(lua_State* L)
+{
+	Image arg1 = LuaGetArgument_Image(L, 1);
+	Texture2D result = LoadTextureFromImage(arg1);
+	LuaPush_Texture2D(L, result);
+	return 1;
+}
+
+int lua_LoadRenderTexture(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	RenderTexture2D result = LoadRenderTexture(arg1, arg2);
+	LuaPush_RenderTexture2D(L, result);
+	return 1;
+}
+
+int lua_UnloadImage(lua_State* L)
+{
+	Image arg1 = LuaGetArgument_Image(L, 1);
+	UnloadImage(arg1);
+	return 0;
+}
+
+int lua_UnloadTexture(lua_State* L)
+{
+	Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+	UnloadTexture(arg1);
+	return 0;
+}
+
+int lua_UnloadRenderTexture(lua_State* L)
+{
+	RenderTexture2D arg1 = LuaGetArgument_RenderTexture2D(L, 1);
+	UnloadRenderTexture(arg1);
+	return 0;
+}
+
+int lua_GetImageData(lua_State* L)
+{
+	Image arg1 = LuaGetArgument_Image(L, 1);
+	Color * result = GetImageData(arg1);
+	lua_createtable(L, arg1.width*arg1.height, 0);
+	for (int i = 0; i < arg1.width*arg1.height; i++)
+	{
+		LuaPush_Color(L, result[i]);
+		lua_rawseti(L, -2, i + 1);
+	}
+	free(result);
+	return 1;
+}
+
+int lua_GetTextureData(lua_State* L)
+{
+	Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+	Image result = GetTextureData(arg1);
+	LuaPush_Image(L, result);
+	return 1;
+}
+
+int lua_ImageToPOT(lua_State* L)
+{
+	Image arg1 = LuaGetArgument_Image(L, 1);
+	Color arg2 = LuaGetArgument_Color(L, 2);
+	ImageToPOT(&arg1, arg2);
+	LuaPush_Image(L, arg1);
+	return 1;
+}
+
+int lua_ImageFormat(lua_State* L)
+{
+	Image arg1 = LuaGetArgument_Image(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	ImageFormat(&arg1, arg2);
+	LuaPush_Image(L, arg1);
+	return 1;
+}
+
+// TODO:
+/*
+void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp);                            // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
+Image ImageCopy(Image image);                                                                      // Create an image duplicate (useful for transformations)
+void ImageCrop(Image *image, Rectangle crop);                                                      // Crop an image to a defined rectangle
+void ImageResize(Image *image, int newWidth, int newHeight);                                       // Resize and image (bilinear filtering)
+void ImageResizeNN(Image *image,int newWidth,int newHeight);                                       // Resize and image (Nearest-Neighbor scaling algorithm)
+Image ImageText(const char *text, int fontSize, Color color);                                      // Create an image from text (default font)
+Image ImageTextEx(SpriteFont font, const char *text, int fontSize, int spacing, Color tint);       // Create an image from text (custom sprite font)
+void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec);                         // Draw a source image within a destination image
+void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color);     // Draw text (default font) within an image (destination)
+void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, int fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination)
+void ImageFlipVertical(Image *image);                                                              // Flip image vertically
+void ImageFlipHorizontal(Image *image);                                                            // Flip image horizontally
+void ImageColorTint(Image *image, Color color);                                                    // Modify image color: tint
+void ImageColorInvert(Image *image);                                                               // Modify image color: invert
+void ImageColorGrayscale(Image *image);                                                            // Modify image color: grayscale
+void ImageColorContrast(Image *image, float contrast);                                             // Modify image color: contrast (-100 to 100)
+void ImageColorBrightness(Image *image, int brightness);                                           // Modify image color: brightness (-255 to 255)
+*/
+
+int lua_GenTextureMipmaps(lua_State* L)
+{
+	Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+	GenTextureMipmaps(arg1);
+	return 0;
+}
+
+// TODO: void UpdateTexture(Texture2D texture, void *pixels);                                               // Update GPU texture with new data
+
+int lua_DrawTexture(lua_State* L)
+{
+	Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	Color arg4 = LuaGetArgument_Color(L, 4);
+	DrawTexture(arg1, arg2, arg3, arg4);
+	return 0;
+}
+
+int lua_DrawTextureV(lua_State* L)
+{
+	Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+	Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+	Color arg3 = LuaGetArgument_Color(L, 3);
+	DrawTextureV(arg1, arg2, arg3);
+	return 0;
+}
+
+int lua_DrawTextureEx(lua_State* L)
+{
+	Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+	Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	float arg4 = LuaGetArgument_float(L, 4);
+	Color arg5 = LuaGetArgument_Color(L, 5);
+	DrawTextureEx(arg1, arg2, arg3, arg4, arg5);
+	return 0;
+}
+
+int lua_DrawTextureRec(lua_State* L)
+{
+	Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+	Rectangle arg2 = LuaGetArgument_Rectangle(L, 2);
+	Vector2 arg3 = LuaGetArgument_Vector2(L, 3);
+	Color arg4 = LuaGetArgument_Color(L, 4);
+	DrawTextureRec(arg1, arg2, arg3, arg4);
+	return 0;
+}
+
+int lua_DrawTexturePro(lua_State* L)
+{
+	Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+	Rectangle arg2 = LuaGetArgument_Rectangle(L, 2);
+	Rectangle arg3 = LuaGetArgument_Rectangle(L, 3);
+	Vector2 arg4 = LuaGetArgument_Vector2(L, 4);
+	float arg5 = LuaGetArgument_float(L, 5);
+	Color arg6 = LuaGetArgument_Color(L, 6);
+	DrawTexturePro(arg1, arg2, arg3, arg4, arg5, arg6);
+	return 0;
+}
+
+//------------------------------------------------------------------------------------
+// raylib [text] module functions - Font Loading and Text Drawing
+//------------------------------------------------------------------------------------
+int lua_GetDefaultFont(lua_State* L)
+{
+	SpriteFont result = GetDefaultFont();
+	LuaPush_SpriteFont(L, result);
+	return 1;
+}
+
+int lua_LoadSpriteFont(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	SpriteFont result = LoadSpriteFont(arg1);
+	LuaPush_SpriteFont(L, result);
+	return 1;
+}
+
+int lua_UnloadSpriteFont(lua_State* L)
+{
+	SpriteFont arg1 = LuaGetArgument_SpriteFont(L, 1);
+	UnloadSpriteFont(arg1);
+	return 0;
+}
+
+int lua_DrawText(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	int arg4 = LuaGetArgument_int(L, 4);
+	Color arg5 = LuaGetArgument_Color(L, 5);
+	DrawText(arg1, arg2, arg3, arg4, arg5);
+	return 0;
+}
+
+int lua_DrawTextEx(lua_State* L)
+{
+	SpriteFont arg1 = LuaGetArgument_SpriteFont(L, 1);
+	const char* arg2 = LuaGetArgument_string(L, 2);
+	Vector2 arg3 = LuaGetArgument_Vector2(L, 3);
+	int arg4 = LuaGetArgument_int(L, 4);
+	int arg5 = LuaGetArgument_int(L, 5);
+	Color arg6 = LuaGetArgument_Color(L, 6);
+	DrawTextEx(arg1, arg2, arg3, arg4, arg5, arg6);
+	return 0;
+}
+
+int lua_MeasureText(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	int result = MeasureText(arg1, arg2);
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+int lua_MeasureTextEx(lua_State* L)
+{
+	SpriteFont arg1 = LuaGetArgument_SpriteFont(L, 1);
+	const char * arg2 = LuaGetArgument_string(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	int arg4 = LuaGetArgument_int(L, 4);
+	Vector2 result = MeasureTextEx(arg1, arg2, arg3, arg4);
+	LuaPush_Vector2(L, result);
+	return 1;
+}
+
+int lua_DrawFPS(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	DrawFPS(arg1, arg2);
+	return 0;
+}
+
+// TODO:
+/*
+const char *FormatText(const char *text, ...);                                                     // Formatting of text with variables to 'embed'
+const char *SubText(const char *text, int position, int length);                                   // Get a piece of a text string
+*/
+
+int lua_DrawCube(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	float arg4 = LuaGetArgument_float(L, 4);
+	Color arg5 = LuaGetArgument_Color(L, 5);
+	DrawCube(arg1, arg2, arg3, arg4, arg5);
+	return 0;
+}
+
+int lua_DrawCubeV(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	Color arg3 = LuaGetArgument_Color(L, 3);
+	DrawCubeV(arg1, arg2, arg3);
+	return 0;
+}
+
+int lua_DrawCubeWires(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	float arg4 = LuaGetArgument_float(L, 4);
+	Color arg5 = LuaGetArgument_Color(L, 5);
+	DrawCubeWires(arg1, arg2, arg3, arg4, arg5);
+	return 0;
+}
+
+int lua_DrawCubeTexture(lua_State* L)
+{
+	Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	float arg4 = LuaGetArgument_float(L, 4);
+	float arg5 = LuaGetArgument_float(L, 5);
+	Color arg6 = LuaGetArgument_Color(L, 6);
+	DrawCubeTexture(arg1, arg2, arg3, arg4, arg5, arg6);
+	return 0;
+}
+
+int lua_DrawSphere(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	Color arg3 = LuaGetArgument_Color(L, 3);
+	DrawSphere(arg1, arg2, arg3);
+	return 0;
+}
+
+int lua_DrawSphereEx(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	int arg4 = LuaGetArgument_int(L, 4);
+	Color arg5 = LuaGetArgument_Color(L, 5);
+	DrawSphereEx(arg1, arg2, arg3, arg4, arg5);
+	return 0;
+}
+
+int lua_DrawSphereWires(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	int arg4 = LuaGetArgument_int(L, 4);
+	Color arg5 = LuaGetArgument_Color(L, 5);
+	DrawSphereWires(arg1, arg2, arg3, arg4, arg5);
+	return 0;
+}
+
+int lua_DrawCylinder(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	float arg4 = LuaGetArgument_float(L, 4);
+	int arg5 = LuaGetArgument_int(L, 5);
+	Color arg6 = LuaGetArgument_Color(L, 6);
+	DrawCylinder(arg1, arg2, arg3, arg4, arg5, arg6);
+	return 0;
+}
+
+int lua_DrawCylinderWires(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	float arg4 = LuaGetArgument_float(L, 4);
+	int arg5 = LuaGetArgument_int(L, 5);
+	Color arg6 = LuaGetArgument_Color(L, 6);
+	DrawCylinderWires(arg1, arg2, arg3, arg4, arg5, arg6);
+	return 0;
+}
+
+int lua_DrawPlane(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+	Color arg3 = LuaGetArgument_Color(L, 3);
+	DrawPlane(arg1, arg2, arg3);
+	return 0;
+}
+
+int lua_DrawRay(lua_State* L)
+{
+	Ray arg1 = LuaGetArgument_Ray(L, 1);
+	Color arg2 = LuaGetArgument_Color(L, 2);
+	DrawRay(arg1, arg2);
+	return 0;
+}
+
+int lua_DrawGrid(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	DrawGrid(arg1, arg2);
+	return 0;
+}
+
+int lua_DrawGizmo(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	DrawGizmo(arg1);
+	return 0;
+}
+
+// TODO:
+/*
+void DrawLight(Light light);                                                                       // Draw light in 3D world
+void Draw3DLine(Vector3 startPos, Vector3 endPos, Color color);                                    // Draw a line in 3D world space
+void Draw3DCircle(Vector3 center, float radius, float rotationAngle, Vector3 rotation, Color color);    // Draw a circle in 3D world space
+*/
+
+//------------------------------------------------------------------------------------
+// raylib [models] module functions
+//------------------------------------------------------------------------------------
+int lua_LoadModel(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	Model result = LoadModel(arg1);
+	LuaPush_Model(L, result);
+	return 1;
+}
+
+int lua_LoadModelEx(lua_State* L)
+{
+	Mesh arg1 = LuaGetArgument_Mesh(L, 1);
+	bool arg2 = LuaGetArgument_int(L, 2);
+	Model result = LoadModelEx(arg1, arg2);
+	LuaPush_Model(L, result);
+	return 1;
+}
+
+int lua_LoadModelFromRES(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	Model result = LoadModelFromRES(arg1, arg2);
+	LuaPush_Model(L, result);
+	return 1;
+}
+
+int lua_LoadHeightmap(lua_State* L)
+{
+	Image arg1 = LuaGetArgument_Image(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	Model result = LoadHeightmap(arg1, arg2);
+	LuaPush_Model(L, result);
+	return 1;
+}
+
+int lua_LoadCubicmap(lua_State* L)
+{
+	Image arg1 = LuaGetArgument_Image(L, 1);
+	Model result = LoadCubicmap(arg1);
+	LuaPush_Model(L, result);
+	return 1;
+}
+
+int lua_UnloadModel(lua_State* L)
+{
+	Model arg1 = LuaGetArgument_Model(L, 1);
+	UnloadModel(arg1);
+	return 0;
+}
+
+// TODO: GenMesh*()
+
+int lua_LoadMaterial(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	Material result = LoadMaterial(arg1);
+	LuaPush_Material(L, result);
+	return 1;
+}
+
+int lua_LoadDefaultMaterial(lua_State* L)
+{
+	Material result = LoadDefaultMaterial();
+	LuaPush_Material(L, result);
+	return 1;
+}
+
+int lua_LoadStandardMaterial(lua_State* L)
+{
+	Material result = LoadStandardMaterial();
+	LuaPush_Material(L, result);
+	return 1;
+}
+
+int lua_UnloadMaterial(lua_State* L)
+{
+	Material arg1 = LuaGetArgument_Material(L, 1);
+	UnloadMaterial(arg1);
+	return 0;
+}
+
+int lua_DrawModel(lua_State* L)
+{
+	Model arg1 = LuaGetArgument_Model(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	Color arg4 = LuaGetArgument_Color(L, 4);
+	DrawModel(arg1, arg2, arg3, arg4);
+	return 0;
+}
+
+int lua_DrawModelEx(lua_State* L)
+{
+	Model arg1 = LuaGetArgument_Model(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+    Vector3 arg3 = LuaGetArgument_Vector3(L, 3);
+	float arg4 = LuaGetArgument_float(L, 4);
+	Vector3 arg5 = LuaGetArgument_Vector3(L, 5);
+	Color arg6 = LuaGetArgument_Color(L, 6);
+	DrawModelEx(arg1, arg2, arg3, arg4, arg5, arg6);
+	return 0;
+}
+
+int lua_DrawModelWires(lua_State* L)
+{
+	Model arg1 = LuaGetArgument_Model(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	Color arg4 = LuaGetArgument_Color(L, 4);
+	DrawModelWires(arg1, arg2, arg3, arg4);
+	return 0;
+}
+
+int lua_DrawModelWiresEx(lua_State* L)
+{
+	Model arg1 = LuaGetArgument_Model(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+    Vector3 arg3 = LuaGetArgument_Vector3(L, 3);
+	float arg4 = LuaGetArgument_float(L, 4);
+	Vector3 arg5 = LuaGetArgument_Vector3(L, 5);
+	Color arg6 = LuaGetArgument_Color(L, 6);
+	DrawModelWiresEx(arg1, arg2, arg3, arg4, arg5, arg6);
+	return 0;
+}
+
+int lua_DrawBillboard(lua_State* L)
+{
+	Camera arg1 = LuaGetArgument_Camera(L, 1);
+	Texture2D arg2 = LuaGetArgument_Texture2D(L, 2);
+	Vector3 arg3 = LuaGetArgument_Vector3(L, 3);
+	float arg4 = LuaGetArgument_float(L, 4);
+	Color arg5 = LuaGetArgument_Color(L, 5);
+	DrawBillboard(arg1, arg2, arg3, arg4, arg5);
+	return 0;
+}
+
+int lua_DrawBillboardRec(lua_State* L)
+{
+	Camera arg1 = LuaGetArgument_Camera(L, 1);
+	Texture2D arg2 = LuaGetArgument_Texture2D(L, 2);
+	Rectangle arg3 = LuaGetArgument_Rectangle(L, 3);
+	Vector3 arg4 = LuaGetArgument_Vector3(L, 4);
+	float arg5 = LuaGetArgument_float(L, 5);
+	Color arg6 = LuaGetArgument_Color(L, 6);
+	DrawBillboardRec(arg1, arg2, arg3, arg4, arg5, arg6);
+	return 0;
+}
+
+int lua_CalculateBoundingBox(lua_State* L)
+{
+	Mesh arg1 = LuaGetArgument_Mesh(L, 1);
+    BoundingBox result = CalculateBoundingBox(arg1);
+	LuaPush_BoundingBox(L, result);
+	return 0;
+}
+
+int lua_CheckCollisionSpheres(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	Vector3 arg3 = LuaGetArgument_Vector3(L, 3);
+	float arg4 = LuaGetArgument_float(L, 4);
+	bool result = CheckCollisionSpheres(arg1, arg2, arg3, arg4);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_CheckCollisionBoxes(lua_State* L)
+{
+	BoundingBox arg1 = LuaGetArgument_BoundingBox(L, 1);
+	BoundingBox arg2 = LuaGetArgument_BoundingBox(L, 2);
+	bool result = CheckCollisionBoxes(arg1, arg2);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_CheckCollisionBoxSphere(lua_State* L)
+{
+	BoundingBox arg1 = LuaGetArgument_BoundingBox(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	float arg3 = LuaGetArgument_float(L, 4);
+	bool result = CheckCollisionBoxSphere(arg1, arg2, arg3);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+// TODO:
+/*
+bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius);                              // Detect collision between ray and sphere
+bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint);   // Detect collision between ray and sphere with extended parameters and collision point detection
+bool CheckCollisionRayBox(Ray ray, BoundingBox box);                                                            // Detect collision between ray and box
+Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius);   // Detect collision of player radius with cubicmap
+*/
+
+int lua_ResolveCollisionCubicmap(lua_State* L)
+{
+	Image arg1 = LuaGetArgument_Image(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	Vector3 arg3 = LuaGetArgument_Vector3(L, 3);
+	float arg4 = LuaGetArgument_float(L, 4);
+	Vector3 result = ResolveCollisionCubicmap(arg1, arg2, &arg3, arg4);
+	LuaPush_Vector3(L, result);
+	LuaPush_Vector3(L, arg3);
+	return 2;
+}
+
+//------------------------------------------------------------------------------------
+// raylib [raymath] module functions - Shaders
+//------------------------------------------------------------------------------------
+int lua_LoadShader(lua_State* L)
+{
+	char * arg1 = (char*)LuaGetArgument_string(L, 1);
+	char * arg2 = (char*)LuaGetArgument_string(L, 2);
+	Shader result = LoadShader(arg1, arg2);
+	LuaPush_Shader(L, result);
+	return 1;
+}
+
+int lua_UnloadShader(lua_State* L)
+{
+	Shader arg1 = LuaGetArgument_Shader(L, 1);
+	UnloadShader(arg1);
+	return 0;
+}
+
+int lua_GetDefaultShader(lua_State* L)
+{
+	Shader result = GetDefaultShader();
+	LuaPush_Shader(L, result);
+	return 1;
+}
+
+int lua_GetStandardShader(lua_State* L)
+{
+	Shader result = GetStandardShader();
+	LuaPush_Shader(L, result);
+	return 1;
+}
+
+int lua_GetDefaultTexture(lua_State* L)
+{
+	Texture2D result = GetDefaultTexture();
+	LuaPush_Texture2D(L, result);
+	return 1;
+}
+
+int lua_GetShaderLocation(lua_State* L)
+{
+	Shader arg1 = LuaGetArgument_Shader(L, 1);
+	const char * arg2 = LuaGetArgument_string(L, 2);
+	int result = GetShaderLocation(arg1, arg2);
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+int lua_SetShaderValue(lua_State* L)
+{
+	Shader arg1 = LuaGetArgument_Shader(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	GET_TABLE(float, arg3, 3);
+	SetShaderValue(arg1, arg2, arg3, arg3_size);
+	free(arg3);
+	return 0;
+}
+
+int lua_SetShaderValuei(lua_State* L)
+{
+	Shader arg1 = LuaGetArgument_Shader(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	GET_TABLE(int, arg3, 3);
+	SetShaderValuei(arg1, arg2, arg3, arg3_size);
+	free(arg3);
+	return 0;
+}
+
+int lua_SetShaderValueMatrix(lua_State* L)
+{
+	Shader arg1 = LuaGetArgument_Shader(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	Matrix arg3 = LuaGetArgument_Matrix(L, 3);
+	SetShaderValueMatrix(arg1, arg2, arg3);
+	return 0;
+}
+
+int lua_SetMatrixProjection(lua_State* L)
+{
+	Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+	SetMatrixProjection(arg1);
+	return 0;
+}
+
+int lua_SetMatrixModelview(lua_State* L)
+{
+	Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+	SetMatrixModelview(arg1);
+	return 0;
+}
+
+int lua_BeginShaderMode(lua_State* L)
+{
+	Shader arg1 = LuaGetArgument_Shader(L, 1);
+	BeginShaderMode(arg1);
+	return 0;
+}
+
+int lua_EndShaderMode(lua_State* L)
+{
+	EndShaderMode();
+	return 0;
+}
+
+int lua_BeginBlendMode(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	BeginBlendMode(arg1);
+	return 0;
+}
+
+int lua_EndBlendMode(lua_State* L)
+{
+	EndBlendMode();
+	return 0;
+}
+
+// TODO:
+//Light CreateLight(int type, Vector3 position, Color diffuse);       // Create a new light, initialize it and add to pool
+//void DestroyLight(Light light);                                     // Destroy a light and take it out of the list
+
+// TODO:
+/*
+//------------------------------------------------------------------------------------
+// raylib [rlgl] module functions - VR experience
+//------------------------------------------------------------------------------------
+void InitVrDevice(int vdDevice);            // Init VR device
+void CloseVrDevice(void);                   // Close VR device
+void UpdateVrTracking(void);                // Update VR tracking (position and orientation)
+void BeginVrDrawing(void);                  // Begin VR drawing configuration
+void EndVrDrawing(void);                    // End VR drawing process (and desktop mirror)
+bool IsVrDeviceReady(void);                 // Detect if VR device (or simulator) is ready
+void ToggleVrMode(void);                    // Enable/Disable VR experience (device or simulator)
+*/
+
+//------------------------------------------------------------------------------------
+// raylib [audio] module functions
+//------------------------------------------------------------------------------------
+int lua_InitAudioDevice(lua_State* L)
+{
+	InitAudioDevice();
+	return 0;
+}
+
+int lua_CloseAudioDevice(lua_State* L)
+{
+	CloseAudioDevice();
+	return 0;
+}
+
+int lua_IsAudioDeviceReady(lua_State* L)
+{
+	bool result = IsAudioDeviceReady();
+    lua_pushboolean(L, result);
+	return 0;
+}
+
+int lua_LoadSound(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	Sound result = LoadSound((char*)arg1);
+	LuaPush_Sound(L, result);
+	return 1;
+}
+
+int lua_LoadSoundFromWave(lua_State* L)
+{
+	Wave arg1 = LuaGetArgument_Wave(L, 1);
+	Sound result = LoadSoundFromWave(arg1);
+	LuaPush_Sound(L, result);
+	return 1;
+}
+
+int lua_LoadSoundFromRES(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	int arg2 = LuaGetArgument_int(L, 2);
+	Sound result = LoadSoundFromRES(arg1, arg2);
+	LuaPush_Sound(L, result);
+	return 1;
+}
+
+int lua_UnloadSound(lua_State* L)
+{
+	Sound arg1 = LuaGetArgument_Sound(L, 1);
+	UnloadSound(arg1);
+	return 0;
+}
+
+int lua_PlaySound(lua_State* L)
+{
+	Sound arg1 = LuaGetArgument_Sound(L, 1);
+	PlaySound(arg1);
+	return 0;
+}
+
+int lua_PauseSound(lua_State* L)
+{
+	Sound arg1 = LuaGetArgument_Sound(L, 1);
+	PauseSound(arg1);
+	return 0;
+}
+
+int lua_ResumeSound(lua_State* L)
+{
+	Sound arg1 = LuaGetArgument_Sound(L, 1);
+	ResumeSound(arg1);
+	return 0;
+}
+
+int lua_StopSound(lua_State* L)
+{
+	Sound arg1 = LuaGetArgument_Sound(L, 1);
+	StopSound(arg1);
+	return 0;
+}
+
+int lua_IsSoundPlaying(lua_State* L)
+{
+	Sound arg1 = LuaGetArgument_Sound(L, 1);
+	bool result = IsSoundPlaying(arg1);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_SetSoundVolume(lua_State* L)
+{
+	Sound arg1 = LuaGetArgument_Sound(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	SetSoundVolume(arg1, arg2);
+	return 0;
+}
+
+int lua_SetSoundPitch(lua_State* L)
+{
+	Sound arg1 = LuaGetArgument_Sound(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	SetSoundPitch(arg1, arg2);
+	return 0;
+}
+
+int lua_LoadMusicStream(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+    Music result = LoadMusicStream((char *)arg1);
+	LuaPush_Music(L, result);
+	return 0;
+}
+
+int lua_UnloadMusicStream(lua_State* L)
+{
+	Music arg1 = LuaGetArgument_Music(L, 1);
+	UnloadMusicStream(arg1);
+	return 0;
+}
+
+int lua_PlayMusicStream(lua_State* L)
+{
+	Music arg1 = LuaGetArgument_Music(L, 1);
+	PlayMusicStream(arg1);
+	return 0;
+}
+
+int lua_UpdateMusicStream(lua_State* L)
+{
+    Music arg1 = LuaGetArgument_Music(L, 1);
+	UpdateMusicStream(arg1);
+	return 0;
+}
+
+int lua_StopMusicStream(lua_State* L)
+{
+    Music arg1 = LuaGetArgument_Music(L, 1);
+	StopMusicStream(arg1);
+	return 0;
+}
+
+int lua_PauseMusicStream(lua_State* L)
+{
+    Music arg1 = LuaGetArgument_Music(L, 1);
+	PauseMusicStream(arg1);
+	return 0;
+}
+
+int lua_ResumeMusicStream(lua_State* L)
+{
+    Music arg1 = LuaGetArgument_Music(L, 1);
+	ResumeMusicStream(arg1);
+	return 0;
+}
+
+int lua_IsMusicPlaying(lua_State* L)
+{
+    Music arg1 = LuaGetArgument_Music(L, 1);
+	bool result = IsMusicPlaying(arg1);
+	lua_pushboolean(L, result);
+	return 1;
+}
+
+int lua_SetMusicVolume(lua_State* L)
+{
+    Music arg1 = LuaGetArgument_Music(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	SetMusicVolume(arg1, arg2);
+	return 0;
+}
+
+int lua_GetMusicTimeLength(lua_State* L)
+{
+    Music arg1 = LuaGetArgument_Music(L, 1);
+	float result = GetMusicTimeLength(arg1);
+	lua_pushnumber(L, result);
+	return 1;
+}
+
+int lua_GetMusicTimePlayed(lua_State* L)
+{
+    Music arg1 = LuaGetArgument_Music(L, 1);
+	float result = GetMusicTimePlayed(arg1);
+	lua_pushnumber(L, result);
+	return 1;
+}
+
+// TODO:
+/*
+AudioStream InitAudioStream(unsigned int sampleRate, 
+                            unsigned int sampleSize, 
+                            unsigned int channels);             // Init audio stream (to stream audio pcm data)
+void UpdateAudioStream(AudioStream stream, void *data, int numSamples); // Update audio stream buffers with data
+void CloseAudioStream(AudioStream stream);                      // Close audio stream and free memory
+bool IsAudioBufferProcessed(AudioStream stream);                // Check if any audio stream buffers requires refill
+void PlayAudioStream(AudioStream stream);                       // Play audio stream
+void PauseAudioStream(AudioStream stream);                      // Pause audio stream
+void ResumeAudioStream(AudioStream stream);                     // Resume audio stream
+void StopAudioStream(AudioStream stream);                       // Stop audio stream
+*/
+
+//----------------------------------------------------------------------------------
+// raylib [utils] module functions
+//----------------------------------------------------------------------------------
+int lua_DecompressData(lua_State* L)
+{
+	unsigned char *arg1 = (unsigned char *)LuaGetArgument_string(L, 1);
+	unsigned arg2 = (unsigned)LuaGetArgument_int(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	unsigned char *result = DecompressData(arg1, arg2, arg3);
+	lua_pushlstring(L, (const char *)result, arg3);
+	return 1;
+}
+
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
+int lua_WriteBitmap(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	unsigned char* arg2 = (unsigned char*)LuaGetArgument_string(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	int arg4 = LuaGetArgument_int(L, 4);
+	WriteBitmap(arg1, arg2, arg3, arg4);
+	return 0;
+}
+
+int lua_WritePNG(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	unsigned char* arg2 = (unsigned char*)LuaGetArgument_string(L, 2);
+	int arg3 = LuaGetArgument_int(L, 3);
+	int arg4 = LuaGetArgument_int(L, 4);
+	int arg5 = LuaGetArgument_int(L, 5);
+	WritePNG(arg1, arg2, arg3, arg4, arg5);
+	return 0;
+}
+#endif
+
+int lua_TraceLog(lua_State* L)
+{
+	int num_args = lua_gettop(L) - 1;
+	int arg1 = LuaGetArgument_int(L, 1);
+
+	/// type, fmt, args...
+
+	lua_rotate(L, 1, -1); /// fmt, args..., type
+	lua_pop(L, 1); /// fmt, args...
+
+	lua_getglobal(L, "string"); /// fmt, args..., [string]
+	lua_getfield(L, 1, "format"); /// fmt, args..., [string], format()
+	lua_rotate(L, 1, 2); /// [string], format(), fmt, args...
+	lua_call(L, num_args, 1); /// [string], formatted_string
+	
+	TraceLog(arg1, "%s", luaL_checkstring(L,-1));
+	return 0;
+}
+
+int lua_GetExtension(lua_State* L)
+{
+	const char * arg1 = LuaGetArgument_string(L, 1);
+	const char* result = GetExtension(arg1);
+	lua_pushstring(L, result);
+	return 1;
+}
+
+int lua_GetNextPOT(lua_State* L)
+{
+	int arg1 = LuaGetArgument_int(L, 1);
+	int result = GetNextPOT(arg1);
+	lua_pushinteger(L, result);
+	return 1;
+}
+
+//----------------------------------------------------------------------------------
+// raylib [raymath] module functions - Vector3 math
+//----------------------------------------------------------------------------------
+int lua_VectorAdd(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	Vector3 result = VectorAdd(arg1, arg2);
+	LuaPush_Vector3(L, result);
+	return 1;
+}
+
+int lua_VectorSubtract(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	Vector3 result = VectorSubtract(arg1, arg2);
+	LuaPush_Vector3(L, result);
+	return 1;
+}
+
+int lua_VectorCrossProduct(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	Vector3 result = VectorCrossProduct(arg1, arg2);
+	LuaPush_Vector3(L, result);
+	return 1;
+}
+
+int lua_VectorPerpendicular(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	Vector3 result = VectorPerpendicular(arg1);
+	LuaPush_Vector3(L, result);
+	return 1;
+}
+
+int lua_VectorDotProduct(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	float result = VectorDotProduct(arg1, arg2);
+	lua_pushnumber(L, result);
+	return 1;
+}
+
+int lua_VectorLength(lua_State* L)
+{
+	const Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	float result = VectorLength(arg1);
+	lua_pushnumber(L, result);
+	return 1;
+}
+
+int lua_VectorScale(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	VectorScale(&arg1, arg2);
+	LuaPush_Vector3(L, arg1);
+	return 1;
+}
+
+int lua_VectorNegate(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	VectorNegate(&arg1);
+	LuaPush_Vector3(L, arg1);
+	return 1;
+}
+
+int lua_VectorNormalize(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	VectorNormalize(&arg1);
+	LuaPush_Vector3(L, arg1);
+	return 1;
+}
+
+int lua_VectorDistance(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	float result = VectorDistance(arg1, arg2);
+	lua_pushnumber(L, result);
+	return 1;
+}
+
+int lua_VectorLerp(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	Vector3 result = VectorLerp(arg1, arg2, arg3);
+	LuaPush_Vector3(L, result);
+	return 1;
+}
+
+int lua_VectorReflect(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	Vector3 result = VectorReflect(arg1, arg2);
+	LuaPush_Vector3(L, result);
+	return 1;
+}
+
+int lua_VectorTransform(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	Matrix arg2 = LuaGetArgument_Matrix(L, 2);
+	VectorTransform(&arg1, arg2);
+	LuaPush_Vector3(L, arg1);
+	return 1;
+}
+
+int lua_VectorZero(lua_State* L)
+{
+	Vector3 result = VectorZero();
+	LuaPush_Vector3(L, result);
+	return 1;
+}
+
+//----------------------------------------------------------------------------------
+// raylib [raymath] module functions - Matrix math
+//----------------------------------------------------------------------------------
+int lua_MatrixDeterminant(lua_State* L)
+{
+	Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+	float result = MatrixDeterminant(arg1);
+	lua_pushnumber(L, result);
+	return 1;
+}
+
+int lua_MatrixTrace(lua_State* L)
+{
+	Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+	float result = MatrixTrace(arg1);
+	lua_pushnumber(L, result);
+	return 1;
+}
+
+int lua_MatrixTranspose(lua_State* L)
+{
+	Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+	MatrixTranspose(&arg1);
+	LuaPush_Matrix(L, &arg1);
+	return 1;
+}
+
+int lua_MatrixInvert(lua_State* L)
+{
+	Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+	MatrixInvert(&arg1);
+	LuaPush_Matrix(L, &arg1);
+	return 1;
+}
+
+int lua_MatrixNormalize(lua_State* L)
+{
+	Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+	MatrixNormalize(&arg1);
+	LuaPush_Matrix(L, &arg1);
+	return 1;
+}
+
+int lua_MatrixIdentity(lua_State* L)
+{
+	Matrix result = MatrixIdentity();
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+int lua_MatrixAdd(lua_State* L)
+{
+	Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+	Matrix arg2 = LuaGetArgument_Matrix(L, 2);
+	Matrix result = MatrixAdd(arg1, arg2);
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+int lua_MatrixSubstract(lua_State* L)
+{
+	Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+	Matrix arg2 = LuaGetArgument_Matrix(L, 2);
+	Matrix result = MatrixSubstract(arg1, arg2);
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+int lua_MatrixTranslate(lua_State* L)
+{
+	float arg1 = LuaGetArgument_float(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	Matrix result = MatrixTranslate(arg1, arg2, arg3);
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+int lua_MatrixRotate(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	Matrix result = MatrixRotate(arg1, arg2);
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+int lua_MatrixRotateX(lua_State* L)
+{
+	float arg1 = LuaGetArgument_float(L, 1);
+	Matrix result = MatrixRotateX(arg1);
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+int lua_MatrixRotateY(lua_State* L)
+{
+	float arg1 = LuaGetArgument_float(L, 1);
+	Matrix result = MatrixRotateY(arg1);
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+int lua_MatrixRotateZ(lua_State* L)
+{
+	float arg1 = LuaGetArgument_float(L, 1);
+	Matrix result = MatrixRotateZ(arg1);
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+int lua_MatrixScale(lua_State* L)
+{
+	float arg1 = LuaGetArgument_float(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	Matrix result = MatrixScale(arg1, arg2, arg3);
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+int lua_MatrixMultiply(lua_State* L)
+{
+	Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+	Matrix arg2 = LuaGetArgument_Matrix(L, 2);
+	Matrix result = MatrixMultiply(arg1, arg2);
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+int lua_MatrixFrustum(lua_State* L)
+{
+	double arg1 = LuaGetArgument_double(L, 1);
+	double arg2 = LuaGetArgument_double(L, 2);
+	double arg3 = LuaGetArgument_double(L, 3);
+	double arg4 = LuaGetArgument_double(L, 4);
+	double arg5 = LuaGetArgument_double(L, 5);
+	double arg6 = LuaGetArgument_double(L, 6);
+	Matrix result = MatrixFrustum(arg1, arg2, arg3, arg4, arg5, arg6);
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+int lua_MatrixPerspective(lua_State* L)
+{
+	double arg1 = LuaGetArgument_double(L, 1);
+	double arg2 = LuaGetArgument_double(L, 2);
+	double arg3 = LuaGetArgument_double(L, 3);
+	double arg4 = LuaGetArgument_double(L, 4);
+	Matrix result = MatrixPerspective(arg1, arg2, arg3, arg4);
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+int lua_MatrixOrtho(lua_State* L)
+{
+	double arg1 = LuaGetArgument_double(L, 1);
+	double arg2 = LuaGetArgument_double(L, 2);
+	double arg3 = LuaGetArgument_double(L, 3);
+	double arg4 = LuaGetArgument_double(L, 4);
+	double arg5 = LuaGetArgument_double(L, 5);
+	double arg6 = LuaGetArgument_double(L, 6);
+	Matrix result = MatrixOrtho(arg1, arg2, arg3, arg4, arg5, arg6);
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+int lua_MatrixLookAt(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+	Vector3 arg3 = LuaGetArgument_Vector3(L, 3);
+	Matrix result = MatrixLookAt(arg1, arg2, arg3);
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+//----------------------------------------------------------------------------------
+// raylib [raymath] module functions - Quaternion math
+//----------------------------------------------------------------------------------
+int lua_QuaternionLength(lua_State* L)
+{
+	Quaternion arg1 = LuaGetArgument_Quaternion(L, 1);
+	float result = QuaternionLength(arg1);
+	lua_pushnumber(L, result);
+	return 1;
+}
+
+int lua_QuaternionNormalize(lua_State* L)
+{
+	Quaternion arg1 = LuaGetArgument_Quaternion(L, 1);
+	QuaternionNormalize(&arg1);
+	LuaPush_Quaternion(L, arg1);
+	return 1;
+}
+
+int lua_QuaternionMultiply(lua_State* L)
+{
+	Quaternion arg1 = LuaGetArgument_Quaternion(L, 1);
+	Quaternion arg2 = LuaGetArgument_Quaternion(L, 2);
+	Quaternion result = QuaternionMultiply(arg1, arg2);
+	LuaPush_Quaternion(L, result);
+	return 1;
+}
+
+int lua_QuaternionSlerp(lua_State* L)
+{
+	Quaternion arg1 = LuaGetArgument_Quaternion(L, 1);
+	Quaternion arg2 = LuaGetArgument_Quaternion(L, 2);
+	float arg3 = LuaGetArgument_float(L, 3);
+	Quaternion result = QuaternionSlerp(arg1, arg2, arg3);
+	LuaPush_Quaternion(L, result);
+	return 1;
+}
+
+int lua_QuaternionFromMatrix(lua_State* L)
+{
+	Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+	Quaternion result = QuaternionFromMatrix(arg1);
+	LuaPush_Quaternion(L, result);
+	return 1;
+}
+
+int lua_QuaternionToMatrix(lua_State* L)
+{
+	Quaternion arg1 = LuaGetArgument_Quaternion(L, 1);
+	Matrix result = QuaternionToMatrix(arg1);
+	LuaPush_Matrix(L, &result);
+	return 1;
+}
+
+int lua_QuaternionFromAxisAngle(lua_State* L)
+{
+	Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+	float arg2 = LuaGetArgument_float(L, 2);
+	Quaternion result = QuaternionFromAxisAngle(arg1, arg2);
+	LuaPush_Quaternion(L, result);
+	return 1;
+}
+
+int lua_QuaternionToAxisAngle(lua_State* L)
+{
+	Quaternion arg1 = LuaGetArgument_Quaternion(L, 1);
+    Vector3 arg2;
+	float arg3 = 0;
+	QuaternionToAxisAngle(arg1, &arg2, &arg3);
+	LuaPush_Vector3(L, arg2);
+	lua_pushnumber(L, arg3);
+	return 2;
+}
+
+int lua_QuaternionTransform(lua_State* L)
+{
+	Quaternion arg1 = LuaGetArgument_Quaternion(L, 1);
+	Matrix arg2 = LuaGetArgument_Matrix(L, 2);
+	QuaternionTransform(&arg1, arg2);
+	LuaPush_Quaternion(L, arg1);
+	return 1;
+}
+
+
+//----------------------------------------------------------------------------------
+// Functions Registering
+//----------------------------------------------------------------------------------
+#define REG(name) { #name, lua_##name },
+
+// raylib Functions (and data types) list
+static luaL_Reg raylib_functions[] = {
+	REG(Color)
+	REG(Vector2)
+	REG(Vector3)
+	REG(Rectangle)
+	REG(Ray)
+	REG(Camera)
+    // TODO: Additional structs
+
+    // TODO: Review registered functions
+	REG(InitWindow)
+	REG(CloseWindow)
+	REG(WindowShouldClose)
+	REG(IsWindowMinimized)
+	REG(ToggleFullscreen)
+
+	REG(GetScreenWidth)
+	REG(GetScreenHeight)
+	REG(ClearBackground)
+	REG(BeginDrawing)
+	REG(EndDrawing)
+	REG(Begin3dMode)
+	REG(End3dMode)
+	REG(GetMouseRay)
+#if defined(PLATFORM_WEB)
+	REG(SetDrawingLoop)
+#else
+	REG(SetTargetFPS)
+#endif
+	REG(GetFPS)
+	REG(GetFrameTime)
+	REG(GetColor)
+	REG(GetHexValue)
+	REG(GetRandomValue)
+	REG(Fade)
+	REG(SetConfigFlags)
+	REG(ShowLogo)
+	REG(IsFileDropped)
+	//REG(*GetDroppedFiles)
+	REG(ClearDroppedFiles)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
+	REG(IsKeyPressed)
+	REG(IsKeyDown)
+	REG(IsKeyReleased)
+	REG(IsKeyUp)
+	REG(GetKeyPressed)
+	REG(IsMouseButtonPressed)
+	REG(IsMouseButtonDown)
+	REG(IsMouseButtonReleased)
+	REG(IsMouseButtonUp)
+	REG(GetMouseX)
+	REG(GetMouseY)
+	REG(GetMousePosition)
+	REG(SetMousePosition)
+	REG(GetMouseWheelMove)
+	REG(ShowCursor)
+	REG(HideCursor)
+	REG(IsCursorHidden)
+#endif
+
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
+	REG(IsGamepadAvailable)
+    
+	REG(IsGamepadButtonPressed)
+	REG(IsGamepadButtonDown)
+	REG(IsGamepadButtonReleased)
+	REG(IsGamepadButtonUp)
+#endif
+
+#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
+	REG(GetTouchX)
+	REG(GetTouchY)
+	REG(GetTouchPosition)
+#if defined(PLATFORM_WEB)
+	REG(InitGesturesSystem)
+#elif defined(PLATFORM_ANDROID)
+	//REG(InitGesturesSystem)
+#endif
+	REG(UpdateGestures)
+	REG(IsGestureDetected)
+	REG(GetGestureType)
+	REG(SetGesturesEnabled)
+	REG(GetGestureDragIntensity)
+	REG(GetGestureDragAngle)
+	REG(GetGestureDragVector)
+	REG(GetGestureHoldDuration)
+	REG(GetGesturePinchDelta)
+	REG(GetGesturePinchAngle)
+#endif
+	REG(SetCameraMode)
+	REG(UpdateCamera)
+	REG(UpdateCameraPlayer)
+	REG(SetCameraPosition)
+	REG(SetCameraTarget)
+	REG(SetCameraPanControl)
+	REG(SetCameraAltControl)
+	REG(SetCameraSmoothZoomControl)
+	REG(SetCameraMoveControls)
+	REG(SetCameraMouseSensitivity)
+	REG(DrawPixel)
+	REG(DrawPixelV)
+	REG(DrawLine)
+	REG(DrawLineV)
+	REG(DrawCircle)
+	REG(DrawCircleGradient)
+	REG(DrawCircleV)
+	REG(DrawCircleLines)
+	REG(DrawRectangle)
+	REG(DrawRectangleRec)
+	REG(DrawRectangleGradient)
+	REG(DrawRectangleV)
+	REG(DrawRectangleLines)
+	REG(DrawTriangle)
+	REG(DrawTriangleLines)
+	REG(DrawPoly)
+	REG(DrawPolyEx)
+	REG(DrawPolyExLines)
+	REG(CheckCollisionRecs)
+	REG(CheckCollisionCircles)
+	REG(CheckCollisionCircleRec)
+	REG(GetCollisionRec)
+	REG(CheckCollisionPointRec)
+	REG(CheckCollisionPointCircle)
+	REG(CheckCollisionPointTriangle)
+	REG(LoadImage)
+	REG(LoadImageEx)
+	REG(LoadImageRaw)
+	REG(LoadImageFromRES)
+	REG(LoadTexture)
+	REG(LoadTextureFromRES)
+	REG(LoadTextureFromImage)
+	REG(UnloadImage)
+	REG(UnloadTexture)
+	REG(GetImageData)
+	REG(GetTextureData)
+	REG(ImageToPOT)
+	REG(ImageFormat)
+	REG(GenTextureMipmaps)
+	REG(DrawTexture)
+	REG(DrawTextureV)
+	REG(DrawTextureEx)
+	REG(DrawTextureRec)
+	REG(DrawTexturePro)
+	REG(GetDefaultFont)
+	REG(LoadSpriteFont)
+	REG(UnloadSpriteFont)
+	REG(DrawText)
+	REG(DrawTextEx)
+	REG(MeasureText)
+	REG(MeasureTextEx)
+	REG(DrawFPS)
+	REG(DrawCube)
+	REG(DrawCubeV)
+	REG(DrawCubeWires)
+	REG(DrawCubeTexture)
+	REG(DrawSphere)
+	REG(DrawSphereEx)
+	REG(DrawSphereWires)
+	REG(DrawCylinder)
+	REG(DrawCylinderWires)
+	REG(DrawPlane)
+	REG(DrawRay)
+	REG(DrawGrid)
+	REG(DrawGizmo)
+	REG(LoadModel)
+	REG(LoadModelEx)
+	REG(LoadHeightmap)
+	REG(LoadCubicmap)
+	REG(UnloadModel)
+	REG(DrawModel)
+	REG(DrawModelEx)
+	REG(DrawModelWires)
+	REG(DrawBillboard)
+	REG(DrawBillboardRec)
+	REG(CheckCollisionSpheres)
+	REG(CheckCollisionBoxes)
+	REG(CheckCollisionBoxSphere)
+	REG(ResolveCollisionCubicmap)
+	REG(LoadShader)
+	REG(UnloadShader)
+	REG(GetShaderLocation)
+	REG(SetShaderValue)
+	REG(SetShaderValuei)
+
+	REG(BeginBlendMode)
+	REG(EndBlendMode)
+	REG(InitAudioDevice)
+	REG(CloseAudioDevice)
+	REG(LoadSound)
+	REG(LoadSoundFromWave)
+	REG(LoadSoundFromRES)
+	REG(UnloadSound)
+	REG(PlaySound)
+	REG(PauseSound)
+	REG(StopSound)
+	REG(IsSoundPlaying)
+	REG(SetSoundVolume)
+	REG(SetSoundPitch)
+	REG(PlayMusicStream)
+	REG(UpdateMusicStream)
+	REG(StopMusicStream)
+	REG(PauseMusicStream)
+	REG(ResumeMusicStream)
+	REG(IsMusicPlaying)
+	REG(SetMusicVolume)
+	REG(GetMusicTimeLength)
+	REG(GetMusicTimePlayed)
+
+	/// Math and util
+	REG(DecompressData)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
+	REG(WriteBitmap)
+	REG(WritePNG)
+#endif
+	REG(TraceLog)
+	REG(GetExtension)
+	REG(GetNextPOT)
+	REG(VectorAdd)
+	REG(VectorSubtract)
+	REG(VectorCrossProduct)
+	REG(VectorPerpendicular)
+	REG(VectorDotProduct)
+	REG(VectorLength)
+	REG(VectorScale)
+	REG(VectorNegate)
+	REG(VectorNormalize)
+	REG(VectorDistance)
+	REG(VectorLerp)
+	REG(VectorReflect)
+	REG(VectorTransform)
+	REG(VectorZero)
+	REG(MatrixDeterminant)
+	REG(MatrixTrace)
+	REG(MatrixTranspose)
+	REG(MatrixInvert)
+	REG(MatrixNormalize)
+	REG(MatrixIdentity)
+	REG(MatrixAdd)
+	REG(MatrixSubstract)
+	REG(MatrixTranslate)
+	REG(MatrixRotate)
+	REG(MatrixRotateX)
+	REG(MatrixRotateY)
+	REG(MatrixRotateZ)
+	REG(MatrixScale)
+	REG(MatrixMultiply)
+	REG(MatrixFrustum)
+	REG(MatrixPerspective)
+	REG(MatrixOrtho)
+	REG(MatrixLookAt)
+	REG(QuaternionLength)
+	REG(QuaternionNormalize)
+	REG(QuaternionMultiply)
+	REG(QuaternionSlerp)
+	REG(QuaternionFromMatrix)
+	REG(QuaternionToMatrix)
+	REG(QuaternionFromAxisAngle)
+	REG(QuaternionToAxisAngle)
+	REG(QuaternionTransform)
+
+	{0,0}
+};
+
+// Register raylib functionality
+static void LuaRegisterRayLib(const char *opt_table)
+{
+	if (opt_table) lua_createtable(L, 0, sizeof(raylib_functions)/sizeof(raylib_functions[0]));
+	else lua_pushglobaltable(L);
+
+	luaL_setfuncs(L, raylib_functions, 0);
+}
+
+//----------------------------------------------------------------------------------
+// raylib Lua API
+//----------------------------------------------------------------------------------
+
+// Initialize Lua system
+RLUADEF void InitLuaDevice(void)
+{
+	mainLuaState = luaL_newstate();
+	L = mainLuaState;
+    
+	LuaStartEnum();
+	LuaSetEnum("FULLSCREEN_MODE", 1);
+	LuaSetEnum("SHOW_LOGO", 2);
+	LuaSetEnum("SHOW_MOUSE_CURSOR", 4);
+	LuaSetEnum("CENTERED_MODE", 8);
+	LuaSetEnum("MSAA_4X_HINT", 16);
+	LuaSetEnum("VSYNC_HINT", 32);
+	LuaEndEnum("FLAG");
+
+	LuaStartEnum();
+	LuaSetEnum("SPACE", 32);
+	LuaSetEnum("ESCAPE", 256);
+	LuaSetEnum("ENTER", 257);
+	LuaSetEnum("BACKSPACE", 259);
+	LuaSetEnum("RIGHT", 262);
+	LuaSetEnum("LEFT", 263);
+	LuaSetEnum("DOWN", 264);
+	LuaSetEnum("UP", 265);
+	LuaSetEnum("F1", 290);
+	LuaSetEnum("F2", 291);
+	LuaSetEnum("F3", 292);
+	LuaSetEnum("F4", 293);
+	LuaSetEnum("F5", 294);
+	LuaSetEnum("F6", 295);
+	LuaSetEnum("F7", 296);
+	LuaSetEnum("F8", 297);
+	LuaSetEnum("F9", 298);
+	LuaSetEnum("F10", 299);
+	LuaSetEnum("LEFT_SHIFT", 340);
+	LuaSetEnum("LEFT_CONTROL", 341);
+	LuaSetEnum("LEFT_ALT", 342);
+	LuaSetEnum("RIGHT_SHIFT", 344);
+	LuaSetEnum("RIGHT_CONTROL", 345);
+	LuaSetEnum("RIGHT_ALT", 346);
+	LuaSetEnum("ZERO", 48);
+	LuaSetEnum("ONE", 49);
+	LuaSetEnum("TWO", 50);
+	LuaSetEnum("THREE", 51);
+	LuaSetEnum("FOUR", 52);
+	LuaSetEnum("FIVE", 53);
+	LuaSetEnum("SIX", 54);
+	LuaSetEnum("SEVEN", 55);
+	LuaSetEnum("EIGHT", 56);
+	LuaSetEnum("NINE", 57);
+	LuaSetEnum("A", 65);
+	LuaSetEnum("B", 66);
+	LuaSetEnum("C", 67);
+	LuaSetEnum("D", 68);
+	LuaSetEnum("E", 69);
+	LuaSetEnum("F", 70);
+	LuaSetEnum("G", 71);
+	LuaSetEnum("H", 72);
+	LuaSetEnum("I", 73);
+	LuaSetEnum("J", 74);
+	LuaSetEnum("K", 75);
+	LuaSetEnum("L", 76);
+	LuaSetEnum("M", 77);
+	LuaSetEnum("N", 78);
+	LuaSetEnum("O", 79);
+	LuaSetEnum("P", 80);
+	LuaSetEnum("Q", 81);
+	LuaSetEnum("R", 82);
+	LuaSetEnum("S", 83);
+	LuaSetEnum("T", 84);
+	LuaSetEnum("U", 85);
+	LuaSetEnum("V", 86);
+	LuaSetEnum("W", 87);
+	LuaSetEnum("X", 88);
+	LuaSetEnum("Y", 89);
+	LuaSetEnum("Z", 90);
+	LuaEndEnum("KEY");
+
+	LuaStartEnum();
+	LuaSetEnum("LEFT_BUTTON", 0);
+	LuaSetEnum("RIGHT_BUTTON", 1);
+	LuaSetEnum("MIDDLE_BUTTON", 2);
+	LuaEndEnum("MOUSE");
+
+	LuaStartEnum();
+	LuaSetEnum("PLAYER1", 0);
+	LuaSetEnum("PLAYER2", 1);
+	LuaSetEnum("PLAYER3", 2);
+	LuaSetEnum("PLAYER4", 3);
+
+	LuaSetEnum("BUTTON_A", 2);
+	LuaSetEnum("BUTTON_B", 1);
+	LuaSetEnum("BUTTON_X", 3);
+	LuaSetEnum("BUTTON_Y", 4);
+	LuaSetEnum("BUTTON_R1", 7);
+	LuaSetEnum("BUTTON_R2", 5);
+	LuaSetEnum("BUTTON_L1", 6);
+	LuaSetEnum("BUTTON_L2", 8);
+	LuaSetEnum("BUTTON_SELECT", 9);
+	LuaSetEnum("BUTTON_START", 10);
+	LuaEndEnum("GAMEPAD");
+    
+	LuaStartEnum();
+	LuaSetEnum("PLAYER1", 0);
+	LuaSetEnum("PLAYER2", 1);
+	LuaSetEnum("PLAYER3", 2);
+	LuaSetEnum("PLAYER4", 3);
+
+	LuaSetEnum("BUTTON_A", 2);
+	LuaSetEnum("BUTTON_B", 1);
+	LuaSetEnum("BUTTON_X", 3);
+	LuaSetEnum("BUTTON_Y", 4);
+	LuaSetEnum("BUTTON_R1", 7);
+	LuaSetEnum("BUTTON_R2", 5);
+	LuaSetEnum("BUTTON_L1", 6);
+	LuaSetEnum("BUTTON_L2", 8);
+	LuaSetEnum("BUTTON_SELECT", 9);
+	LuaSetEnum("BUTTON_START", 10);
+	LuaEndEnum("GAMEPAD");
+    
+    // TODO: XBOX controller buttons enum
+
+	lua_pushglobaltable(L);
+	LuaSetEnumColor("LIGHTGRAY", LIGHTGRAY);
+	LuaSetEnumColor("GRAY", GRAY);
+	LuaSetEnumColor("DARKGRAY", DARKGRAY);
+	LuaSetEnumColor("YELLOW", YELLOW);
+	LuaSetEnumColor("GOLD", GOLD);
+	LuaSetEnumColor("ORANGE", ORANGE);
+	LuaSetEnumColor("PINK", PINK);
+	LuaSetEnumColor("RED", RED);
+	LuaSetEnumColor("MAROON", MAROON);
+	LuaSetEnumColor("GREEN", GREEN);
+	LuaSetEnumColor("LIME", LIME);
+	LuaSetEnumColor("DARKGREEN", DARKGREEN);
+	LuaSetEnumColor("SKYBLUE", SKYBLUE);
+	LuaSetEnumColor("BLUE", BLUE);
+	LuaSetEnumColor("DARKBLUE", DARKBLUE);
+	LuaSetEnumColor("PURPLE", PURPLE);
+	LuaSetEnumColor("VIOLET", VIOLET);
+	LuaSetEnumColor("DARKPURPLE", DARKPURPLE);
+	LuaSetEnumColor("BEIGE", BEIGE);
+	LuaSetEnumColor("BROWN", BROWN);
+	LuaSetEnumColor("DARKBROWN", DARKBROWN);
+	LuaSetEnumColor("WHITE", WHITE);
+	LuaSetEnumColor("BLACK", BLACK);
+	LuaSetEnumColor("BLANK", BLANK);
+	LuaSetEnumColor("MAGENTA", MAGENTA);
+	LuaSetEnumColor("RAYWHITE", RAYWHITE);
+	lua_pop(L, 1);
+
+	LuaStartEnum();
+	LuaSetEnum("UNCOMPRESSED_GRAYSCALE", UNCOMPRESSED_GRAYSCALE);
+	LuaSetEnum("UNCOMPRESSED_GRAY_ALPHA", UNCOMPRESSED_GRAY_ALPHA);
+	LuaSetEnum("UNCOMPRESSED_R5G6B5", UNCOMPRESSED_R5G6B5);
+	LuaSetEnum("UNCOMPRESSED_R8G8B8", UNCOMPRESSED_R8G8B8);
+	LuaSetEnum("UNCOMPRESSED_R5G5B5A1", UNCOMPRESSED_R5G5B5A1);
+	LuaSetEnum("UNCOMPRESSED_R4G4B4A4", UNCOMPRESSED_R4G4B4A4);
+	LuaSetEnum("UNCOMPRESSED_R8G8B8A8", UNCOMPRESSED_R8G8B8A8);
+	LuaSetEnum("COMPRESSED_DXT1_RGB", COMPRESSED_DXT1_RGB);
+	LuaSetEnum("COMPRESSED_DXT1_RGBA", COMPRESSED_DXT1_RGBA);
+	LuaSetEnum("COMPRESSED_DXT3_RGBA", COMPRESSED_DXT3_RGBA);
+	LuaSetEnum("COMPRESSED_DXT5_RGBA", COMPRESSED_DXT5_RGBA);
+	LuaSetEnum("COMPRESSED_ETC1_RGB", COMPRESSED_ETC1_RGB);
+	LuaSetEnum("COMPRESSED_ETC2_RGB", COMPRESSED_ETC2_RGB);
+	LuaSetEnum("COMPRESSED_ETC2_EAC_RGBA", COMPRESSED_ETC2_EAC_RGBA);
+	LuaSetEnum("COMPRESSED_PVRT_RGB", COMPRESSED_PVRT_RGB);
+	LuaSetEnum("COMPRESSED_PVRT_RGBA", COMPRESSED_PVRT_RGBA);
+	LuaSetEnum("COMPRESSED_ASTC_4x4_RGBA", COMPRESSED_ASTC_4x4_RGBA);
+	LuaSetEnum("COMPRESSED_ASTC_8x8_RGBA", COMPRESSED_ASTC_8x8_RGBA);
+	LuaEndEnum("TextureFormat");
+
+	LuaStartEnum();
+	LuaSetEnum("ALPHA", BLEND_ALPHA);
+	LuaSetEnum("ADDITIVE", BLEND_ADDITIVE);
+	LuaSetEnum("MULTIPLIED", BLEND_MULTIPLIED);
+	LuaEndEnum("BlendMode");
+
+	LuaStartEnum();
+	LuaSetEnum("NONE", GESTURE_NONE);
+	LuaSetEnum("TAP", GESTURE_TAP);
+	LuaSetEnum("DOUBLETAP", GESTURE_DOUBLETAP);
+	LuaSetEnum("HOLD", GESTURE_HOLD);
+	LuaSetEnum("DRAG", GESTURE_DRAG);
+	LuaSetEnum("SWIPE_RIGHT", GESTURE_SWIPE_RIGHT);
+	LuaSetEnum("SWIPE_LEFT", GESTURE_SWIPE_LEFT);
+	LuaSetEnum("SWIPE_UP", GESTURE_SWIPE_UP);
+	LuaSetEnum("SWIPE_DOWN", GESTURE_SWIPE_DOWN);
+	LuaSetEnum("PINCH_IN", GESTURE_PINCH_IN);
+	LuaSetEnum("PINCH_OUT", GESTURE_PINCH_OUT);
+	LuaEndEnum("Gestures");
+
+	LuaStartEnum();
+	LuaSetEnum("CUSTOM", CAMERA_CUSTOM);
+	LuaSetEnum("FREE", CAMERA_FREE);
+	LuaSetEnum("ORBITAL", CAMERA_ORBITAL);
+	LuaSetEnum("FIRST_PERSON", CAMERA_FIRST_PERSON);
+	LuaSetEnum("THIRD_PERSON", CAMERA_THIRD_PERSON);
+	LuaEndEnum("CameraMode");
+    
+    LuaStartEnum();
+    LuaSetEnum("HMD_DEFAULT_DEVICE", HMD_DEFAULT_DEVICE);
+    LuaSetEnum("HMD_OCULUS_RIFT_DK2", HMD_OCULUS_RIFT_DK2);
+    LuaSetEnum("HMD_OCULUS_RIFT_CV1", HMD_OCULUS_RIFT_CV1);
+    LuaSetEnum("HMD_VALVE_HTC_VIVE", HMD_VALVE_HTC_VIVE);
+    LuaSetEnum("HMD_SAMSUNG_GEAR_VR", HMD_SAMSUNG_GEAR_VR);
+    LuaSetEnum("HMD_GOOGLE_CARDBOARD", HMD_GOOGLE_CARDBOARD);
+    LuaSetEnum("HMD_SONY_PLAYSTATION_VR", HMD_SONY_PLAYSTATION_VR);
+    LuaSetEnum("HMD_RAZER_OSVR", HMD_RAZER_OSVR);
+    LuaSetEnum("HMD_FOVE_VR", HMD_FOVE_VR);
+	LuaEndEnum("VrDevice");
+
+	lua_pushglobaltable(L);
+	LuaSetEnum("INFO", INFO);
+	LuaSetEnum("ERROR", ERROR);
+	LuaSetEnum("WARNING", WARNING);
+	LuaSetEnum("DEBUG", DEBUG);
+	LuaSetEnum("OTHER", OTHER);
+	lua_pop(L, 1);
+
+	lua_pushboolean(L, true);
+#if defined(PLATFORM_DESKTOP)
+	lua_setglobal(L, "PLATFORM_DESKTOP");
+#elif defined(PLATFORM_ANDROID) 
+	lua_setglobal(L, "PLATFORM_ANDROID");
+#elif defined(PLATFORM_RPI) 
+	lua_setglobal(L, "PLATFORM_RPI");
+#elif defined(PLATFORM_WEB)
+	lua_setglobal(L, "PLATFORM_WEB");
+#endif
+
+	luaL_openlibs(L);
+	LuaBuildOpaqueMetatables();
+    
+	LuaRegisterRayLib(0);
+}
+
+// De-initialize Lua system
+RLUADEF void CloseLuaDevice(void)
+{
+	if (mainLuaState)
+	{
+		lua_close(mainLuaState);
+		mainLuaState = 0;
+		L = 0;
+	}
+}
+
+// Execute raylib Lua code
+RLUADEF void ExecuteLuaCode(const char *code)
+{
+	if (!mainLuaState)
+	{
+		TraceLog(WARNING, "Lua device not initialized");
+		return;
+	}
+
+	int result = luaL_dostring(L, code);
+    
+	switch (result)
+	{
+        case LUA_OK: break;
+        case LUA_ERRRUN: TraceLog(ERROR, "Lua Runtime Error: %s", lua_tostring(L, -1)); break;
+        case LUA_ERRMEM: TraceLog(ERROR, "Lua Memory Error: %s", lua_tostring(L, -1)); break;
+        default: TraceLog(ERROR, "Lua Error: %s", lua_tostring(L, -1)); break;
+	}
+}
+
+// Execute raylib Lua script
+RLUADEF void ExecuteLuaFile(const char *filename)
+{
+	if (!mainLuaState)
+	{
+		TraceLog(WARNING, "Lua device not initialized");
+		return;
+	}
+
+	int result = luaL_dofile(L, filename);
+    
+	switch (result)
+	{
+        case LUA_OK: break;
+        case LUA_ERRRUN: TraceLog(ERROR, "Lua Runtime Error: %s", lua_tostring(L, -1));
+        case LUA_ERRMEM: TraceLog(ERROR, "Lua Memory Error: %s", lua_tostring(L, -1));
+        default: TraceLog(ERROR, "Lua Error: %s", lua_tostring(L, -1));
+	}
+}
+
+#endif // RLUA_IMPLEMENTATION