diff --git a/Client/mods/deathmatch/logic/lua/CLuaMain.cpp b/Client/mods/deathmatch/logic/lua/CLuaMain.cpp index 4dbe913aa0b..abb0190cd5d 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaMain.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaMain.cpp @@ -142,7 +142,7 @@ void CLuaMain::InitVM() // Set the instruction count hook lua_sethook(m_luaVM, InstructionCountHook, LUA_MASKCOUNT, HOOK_INSTRUCTION_COUNT); - // Load LUA libraries + // Load Lua libraries luaopen_base(m_luaVM); luaopen_math(m_luaVM); luaopen_string(m_luaVM); @@ -150,6 +150,7 @@ void CLuaMain::InitVM() luaopen_debug(m_luaVM); luaopen_utf8(m_luaVM); luaopen_os(m_luaVM); + luaopen_vec(m_luaVM); // Initialize security restrictions. Very important to prevent lua trojans and viruses! InitSecurity(); diff --git a/Server/mods/deathmatch/logic/lua/CLuaMain.cpp b/Server/mods/deathmatch/logic/lua/CLuaMain.cpp index dd7df7f0405..a0717c4854b 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaMain.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaMain.cpp @@ -205,7 +205,7 @@ void CLuaMain::Initialize() // Set the instruction count hook lua_sethook(m_luaVM, InstructionCountHook, LUA_MASKCOUNT, HOOK_INSTRUCTION_COUNT); - // Load LUA libraries + // Load Lua libraries luaopen_base(m_luaVM); luaopen_math(m_luaVM); luaopen_string(m_luaVM); @@ -213,6 +213,7 @@ void CLuaMain::Initialize() luaopen_debug(m_luaVM); luaopen_utf8(m_luaVM); luaopen_os(m_luaVM); + luaopen_vec(m_luaVM); // Initialize security restrictions. Very important to prevent lua trojans and viruses! InitSecurity(); diff --git a/vendor/lua/src/Makefile.std b/vendor/lua/src/Makefile.std index 071211c3333..6ff328bd8a3 100644 --- a/vendor/lua/src/Makefile.std +++ b/vendor/lua/src/Makefile.std @@ -29,7 +29,7 @@ CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \ lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \ lundump.o lvm.o lzio.o LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ - lstrlib.o loadlib.o linit.o + lstrlib.o loadlib.o linit.o lvector.o LUA_T= lua$(SFX) LUA_O= lua.o diff --git a/vendor/lua/src/lapi.c b/vendor/lua/src/lapi.c index 82880f9b505..c9b5633ad5c 100644 --- a/vendor/lua/src/lapi.c +++ b/vendor/lua/src/lapi.c @@ -28,7 +28,7 @@ #include "ltm.h" #include "lundump.h" #include "lvm.h" - +#include "lvector.h" /*LUA-VEC*/ const char lua_ident[] = @@ -110,7 +110,7 @@ LUA_API int lua_checkstack (lua_State *L, int size) { LUA_API int lua_getstackgap (lua_State *L) { int res, gap1, gap2; lua_lock(L); - gap1 = ( (char *)L->stack_last - (char *)L->top ) / (int)sizeof(TValue); + gap1 = ( (char *)L->stack_last - (char *)L->top ) / sizeof(TValue); gap2 = L->ci->top - L->top; res = gap1 < gap2 ? gap1 : gap2; lua_unlock(L); @@ -437,7 +437,11 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) { } } - +/* LUA-VEC */ +LUA_API const float* lua_tovec(lua_State* L, int idx) { + StkId o = index2adr(L, idx); + return (!ttisvec(o)) ? NULL : vvalue(o)->vec; +} /* ** push functions (C -> stack) @@ -550,6 +554,14 @@ LUA_API int lua_pushthread (lua_State *L) { return (G(L)->mainthread == L); } +/* LUA-VEC */ +LUA_API void lua_pushvec(lua_State* L, float x, float y, float z, float w) { + lua_lock(L); + luaC_checkGC(L); + setvvalue(L, L->top, luaVec_new(L, x, y, z, w)); + api_incr_top(L); + lua_unlock(L); +} /* ** get functions (Lua -> stack) @@ -796,7 +808,7 @@ LUA_API int lua_setfenv (lua_State *L, int idx) { #define checkresults(L,na,nr) \ api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) - + LUA_API void lua_call (lua_State *L, int nargs, int nresults) { StkId func; diff --git a/vendor/lua/src/lauxlib.c b/vendor/lua/src/lauxlib.c index faff5823386..79843654954 100644 --- a/vendor/lua/src/lauxlib.c +++ b/vendor/lua/src/lauxlib.c @@ -185,6 +185,18 @@ LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { return luaL_opt(L, luaL_checknumber, narg, def); } +/* LUA-VEC */ +LUALIB_API const float* luaL_checkvec(lua_State* L, int narg) { + const float* v = lua_tovec(L, narg); + if (v == 0 && !lua_isvec(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TVEC); + return v; +} + +/* LUA-VEC */ +LUALIB_API const float* luaL_optvec(lua_State* L, int narg, const float* def) { + return luaL_opt(L, luaL_checkvec, narg, def); +} LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { lua_Integer d = lua_tointeger(L, narg); diff --git a/vendor/lua/src/lauxlib.h b/vendor/lua/src/lauxlib.h index 8af41db52ab..d5a520b6134 100644 --- a/vendor/lua/src/lauxlib.h +++ b/vendor/lua/src/lauxlib.h @@ -54,10 +54,12 @@ LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); -LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); -LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, - lua_Integer def); +LUALIB_API const float *(luaL_checkvec)(lua_State* L, int numArg); /* LUA-VEC */ +LUALIB_API const float *(luaL_optvec)(lua_State* L, int nArg, const float* def); /* LUA-VEC */ +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, 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 narg, int t); LUALIB_API void (luaL_checkany) (lua_State *L, int narg); diff --git a/vendor/lua/src/lbaselib.c b/vendor/lua/src/lbaselib.c index 2ab550bd48d..cec2e1bff48 100644 --- a/vendor/lua/src/lbaselib.c +++ b/vendor/lua/src/lbaselib.c @@ -410,6 +410,12 @@ static int luaB_tostring (lua_State *L) { case LUA_TNIL: lua_pushliteral(L, "nil"); break; + case LUA_TVEC: /* LUA-VEC */ + { + const float* v = lua_tovec(L, 1); + lua_pushfstring(L, "vec(%f, %f, %f, %f)", v[0], v[1], v[2], v[3]); + } + break; default: lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1)); break; diff --git a/vendor/lua/src/lgc.c b/vendor/lua/src/lgc.c index e909c79a969..55933878d18 100644 --- a/vendor/lua/src/lgc.c +++ b/vendor/lua/src/lgc.c @@ -21,6 +21,7 @@ #include "lstring.h" #include "ltable.h" #include "ltm.h" +#include "lvector.h" /*LUA-VEC*/ #define GCSTEPSIZE 1024u @@ -107,6 +108,10 @@ static void reallymarkobject (global_State *g, GCObject *o) { g->gray = o; break; } + case LUA_TVEC: { /* LUA-VEC */ + gray2black(o); + break; + } default: lua_assert(0); } } @@ -395,6 +400,10 @@ static void freeobj (lua_State *L, GCObject *o) { luaM_freemem(L, o, sizeudata(gco2u(o))); break; } + case LUA_TVEC: { /* LUA-VEC */ + luaVec_free(L, o); + break; + } default: lua_assert(0); } } diff --git a/vendor/lua/src/linit.c b/vendor/lua/src/linit.c index c1f90dfab71..f6ffc8b494c 100644 --- a/vendor/lua/src/linit.c +++ b/vendor/lua/src/linit.c @@ -22,11 +22,11 @@ static const luaL_Reg lualibs[] = { {LUA_OSLIBNAME, luaopen_os}, {LUA_STRLIBNAME, luaopen_string}, {LUA_MATHLIBNAME, luaopen_math}, + {LUA_VECLIBNAME, luaopen_vec}, /* LUA-VEC */ {LUA_DBLIBNAME, luaopen_debug}, {NULL, NULL} }; - LUALIB_API void luaL_openlibs (lua_State *L) { const luaL_Reg *lib = lualibs; for (; lib->func; lib++) { @@ -35,4 +35,3 @@ LUALIB_API void luaL_openlibs (lua_State *L) { lua_call(L, 1, 0); } } - diff --git a/vendor/lua/src/lobject.h b/vendor/lua/src/lobject.h index f1e447ef3ba..d80cca35df7 100644 --- a/vendor/lua/src/lobject.h +++ b/vendor/lua/src/lobject.h @@ -17,7 +17,7 @@ /* tags for values visible from Lua */ -#define LAST_TAG LUA_TTHREAD +#define LAST_TAG LUA_TVEC /* LUA_TTHREAD -- LUA-VEC */ #define NUM_TAGS (LAST_TAG+1) @@ -85,6 +85,7 @@ typedef struct lua_TValue { #define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) #define ttisthread(o) (ttype(o) == LUA_TTHREAD) #define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) +#define ttisvec(o) (ttype(o) == LUA_TVEC) /* LUA-VEC */ /* Macros to access values */ #define ttype(o) ((o)->tt) @@ -99,6 +100,7 @@ typedef struct lua_TValue { #define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) #define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) #define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) +#define vvalue(o) check_exp(ttisvec(o), &(o)->value.gc->v) /* LUA-VEC */ #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) @@ -155,8 +157,11 @@ typedef struct lua_TValue { i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ checkliveness(G(L),i_o); } - - +/* LUA-VEC */ +#define setvvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TVEC; \ + checkliveness(G(L),i_o); } #define setobj(L,obj1,obj2) \ { const TValue *o2=(obj2); TValue *o1=(obj1); \ @@ -347,7 +352,14 @@ typedef struct Table { int sizearray; /* size of `array' array */ } Table; +/* +** Vector (LUA-VEC) +*/ +typedef struct Vector { + CommonHeader; + float vec[LUA_VEC_SIZE]; +} Vector; /* ** `module' operation for hashing (size is always a power of 2) diff --git a/vendor/lua/src/lstate.h b/vendor/lua/src/lstate.h index 24bbae85731..6c6bca04227 100644 --- a/vendor/lua/src/lstate.h +++ b/vendor/lua/src/lstate.h @@ -147,9 +147,9 @@ union GCObject { struct Proto p; struct UpVal uv; struct lua_State th; /* thread */ + struct Vector v; /* LUA-VEC */ }; - /* macros to convert a GCObject into a specific value */ #define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) #define gco2ts(o) (&rawgco2ts(o)->tsv) @@ -162,6 +162,7 @@ union GCObject { #define ngcotouv(o) \ check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) #define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) +#define gco2v(o) check_exp((o)->gch.tt == LUA_TVEC, &((o)->v)) /* LUA-VEC */ /* macro to convert any Lua object into a GCObject */ #define obj2gco(v) (cast(GCObject *, (v))) diff --git a/vendor/lua/src/ltm.c b/vendor/lua/src/ltm.c index c27f0f6fab8..b491d42f93b 100644 --- a/vendor/lua/src/ltm.c +++ b/vendor/lua/src/ltm.c @@ -20,9 +20,10 @@ -const char *const luaT_typenames[] = { +const char* const luaT_typenames[] = { "nil", "boolean", "userdata", "number", "string", "table", "function", "userdata", "thread", + "vec", /* LUA-VEC */ "proto", "upval" }; diff --git a/vendor/lua/src/lua.h b/vendor/lua/src/lua.h index 9eb284eee22..845b200c996 100644 --- a/vendor/lua/src/lua.h +++ b/vendor/lua/src/lua.h @@ -83,17 +83,19 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); */ #define LUA_TNONE (-1) -#define LUA_TNIL 0 +#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_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 #define LUA_TFUNCTION 6 #define LUA_TUSERDATA 7 -#define LUA_TTHREAD 8 - +#define LUA_TTHREAD 8 +#define LUA_TVEC 9 /* LUA-VEC */ +/* LUA_VEC - Number of components in a vec */ +#define LUA_VEC_SIZE 4 /* minimum Lua stack available to a C function */ #define LUA_MINSTACK 50 // MTA change. Was 20 @@ -170,6 +172,7 @@ 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); +LUA_API const float *(lua_tovec)(lua_State* L, int idx); /* LUA-VEC */ /* @@ -187,6 +190,7 @@ 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); +LUA_API void (lua_pushvec)(lua_State* L, float x, float y, float z, float w); /* LUA-VEC */ /* ** get functions (Lua -> stack) @@ -293,6 +297,7 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); #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_isvec(L, n) (lua_type(L, (n)) == LUA_TVEC) /* LUA-VEC */ #define lua_pushliteral(L, s) \ lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) @@ -388,6 +393,7 @@ struct lua_Debug { /****************************************************************************** * Copyright (C) 1994-2012 Lua.org, PUC-Rio. All rights reserved. +* Lua-vec Extension Copyright (C) 2010 Petri Häkkinen and Henri Häkkinen. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the diff --git a/vendor/lua/src/lualib.h b/vendor/lua/src/lualib.h index 5872ef5db53..e541f86a7fd 100644 --- a/vendor/lua/src/lualib.h +++ b/vendor/lua/src/lualib.h @@ -39,6 +39,9 @@ LUALIB_API int (luaopen_debug) (lua_State *L); #define LUA_LOADLIBNAME "package" LUALIB_API int (luaopen_package) (lua_State *L); +/* LUA-VEC */ +#define LUA_VECLIBNAME "vec" +LUALIB_API int (luaopen_vec)(lua_State* L); /* open all previous libraries */ LUALIB_API void (luaL_openlibs) (lua_State *L); diff --git a/vendor/lua/src/lveclib.c b/vendor/lua/src/lveclib.c new file mode 100644 index 00000000000..0fc5714d5fe --- /dev/null +++ b/vendor/lua/src/lveclib.c @@ -0,0 +1,85 @@ +/* +** Vector math library +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#define lveclib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + +static int vec_new (lua_State *L) { + float x = (float)lua_tonumber(L, 1); + float y = (float)lua_tonumber(L, 2); + float z = (float)lua_tonumber(L, 3); + float w = (float)lua_tonumber(L, 4); + lua_pushvec(L, x, y, z, w); + return 1; +} + +static int vec_dot (lua_State *L) { + const float* v1 = luaL_checkvec(L, 1); + const float* v2 = luaL_checkvec(L, 2); +#pragma warning(disable:26451) /*we dont want to cast to double here*/ + lua_pushnumber(L, v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] + v1[3]*v2[3]); +#pragma warning(default:26451) + return 1; +} + +static int vec_cross (lua_State *L) { + const float* v1 = luaL_checkvec(L, 1); + const float* v2 = luaL_checkvec(L, 2); + lua_pushvec(L, + v1[1] *v2[2] - v1[2] * v2[1], + v1[2] *v2[0] - v1[0] * v2[2], + v1[0] *v2[1] - v1[1] * v2[0], + 0.0f + ); + return 1; +} + +static int vec_length (lua_State *L) { + const float* v = luaL_checkvec(L, 1); + lua_pushnumber(L, sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + v[3]*v[3])); + return 1; +} + +static int vec_normalize (lua_State *L) { + const float* v = luaL_checkvec(L, 1); + float s = 1.0f / sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + v[3]*v[3]); + lua_pushvec(L, v[0]*s, v[1]*s, v[2]*s, v[3]*s); + return 1; +} + + +static const luaL_Reg veclib[] = { + {"new", vec_new}, + {"dot", vec_dot}, + {"cross", vec_cross}, + {"length", vec_length}, + {"normalize", vec_normalize}, + {NULL, NULL} +}; + + +/* +** Open veclib +*/ +LUALIB_API int luaopen_vec (lua_State *L) { + luaL_register(L, LUA_VECLIBNAME, veclib); + + // numeric constants + lua_pushvec(L, 0, 0, 0, 0); + lua_setfield(L, -2, "zero"); + lua_pushvec(L, 1, 1, 1, 1); + lua_setfield(L, -2, "one"); + return 1; +} + diff --git a/vendor/lua/src/lvector.c b/vendor/lua/src/lvector.c new file mode 100644 index 00000000000..bed9dbb4417 --- /dev/null +++ b/vendor/lua/src/lvector.c @@ -0,0 +1,38 @@ +/* +** LUA-VEC +** Lua Vectors +** See Copyright Notice in lua.h +*/ + +#define lvector_c +#define LUA_CORE + +#include "lua.h" + +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lvector.h" + +static GCObject *head = NULL; + +Vector *luaVec_new (lua_State *L, float x, float y, float z, float w) { + Vector *v; + if (head) { + v = gco2v(head); + head = head->gch.next; + } else { + v = luaM_new(L, Vector); + } + luaC_link(L, obj2gco(v), LUA_TVEC); + v->vec[0] = x; + v->vec[1] = y; + v->vec[2] = z; + v->vec[3] = w; + return v; +} + +void luaVec_free (lua_State *L, GCObject *o) { + o->gch.next = head; + head = o; +} diff --git a/vendor/lua/src/lvector.h b/vendor/lua/src/lvector.h new file mode 100644 index 00000000000..63f49381695 --- /dev/null +++ b/vendor/lua/src/lvector.h @@ -0,0 +1,20 @@ +/* +** LUA-VEC +** Lua Vectors +** See Copyright Notice in lua.h +*/ + +#ifndef lvector_h +#define lvector_h + + +#include "lgc.h" +#include "lobject.h" +#include "lstate.h" + + +LUAI_FUNC Vector *luaVec_new (lua_State *L, float x, float y, float z, float w); +LUAI_FUNC void luaVec_free (lua_State *L, GCObject *o); + + +#endif diff --git a/vendor/lua/src/lvm.c b/vendor/lua/src/lvm.c index e0a0cd85219..d76bfa9f5c4 100644 --- a/vendor/lua/src/lvm.c +++ b/vendor/lua/src/lvm.c @@ -25,6 +25,7 @@ #include "ltable.h" #include "ltm.h" #include "lvm.h" +#include "lvector.h" /*LUA-VEC*/ @@ -119,6 +120,51 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { } /* else will try the tag method */ } + /* LUA-VEC TODO - if LUA_VEC_SIZE gets changed this code will break */ + else if (ttisvec(t)) { /* LUA-VEC -- vec[idx] operator */ + /* issue: "index" may not be the correct arg for luaG_typeerror in here */ + if (ttisnumber(key) && /* acessing vec by a number? */ + (nvalue(key) >= 1 && nvalue(key) <= LUA_VEC_SIZE)) { /* index is between 1-LUA_VEC_SIZE? */ + TValue res; + setnvalue(&res, vvalue(t)->vec[cast_int(nvalue(key))-1]); + setobj2s(L, val, &res); + return; + } + else if (ttisstring(key)) { /* acessing vec by a string? */ + if (tsvalue(key)->len == 1) { + /* accessing by a single component, such as vec.x */ + TValue res; + switch (*getstr(tsvalue(key))) { + case 'x': setnvalue(&res, vvalue(t)->vec[0]); break; + case 'y': setnvalue(&res, vvalue(t)->vec[1]); break; + case 'z': setnvalue(&res, vvalue(t)->vec[2]); break; + case 'w': setnvalue(&res, vvalue(t)->vec[3]); break; + default: luaG_typeerror(L, t, "index"); + } + setobj2s(L, val, &res); + return; + } + else if (tsvalue(key)->len <= LUA_VEC_SIZE) { + /* accessing by swizzling, such as vec.xy, vec.xxyz etc. */ + TValue res; + float v[LUA_VEC_SIZE] = {0}; + unsigned int i; + for (i = 0; i < tsvalue(key)->len; ++i) { + switch (getstr(tsvalue(key))[i]) { + case 'x': v[i] = vvalue(t)->vec[0]; break; + case 'y': v[i] = vvalue(t)->vec[1]; break; + case 'z': v[i] = vvalue(t)->vec[2]; break; + case 'w': v[i] = vvalue(t)->vec[3]; break; + default: luaG_typeerror(L, t, "index"); + } + } + setvvalue(L, &res, luaVec_new(L, v[0], v[1], v[2], v[3])); + setobj2s(L, val, &res); + return; + } + } + luaG_typeerror(L, t, "index"); + } else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) luaG_typeerror(L, t, "index"); if (ttisfunction(tm)) { @@ -367,13 +413,29 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb, if (ttisnumber(rb) && ttisnumber(rc)) { \ lua_Number nb = nvalue(rb), nc = nvalue(rc); \ setnvalue(ra, op(nb, nc)); \ - } \ - else \ + /* LUA-VEC add vector arithmetic operators */ \ + } else if (ttisvec(rb) && ttisvec(rc) && (tm==TM_ADD || tm==TM_SUB || tm==TM_MUL || tm==TM_DIV || tm==TM_POW)) { \ + /* vector (add/sub/mul/div/pow) vector */ \ + const float* nb = vvalue(rb)->vec; \ + const float* nc = vvalue(rc)->vec; \ + setvvalue(L, ra, luaVec_new(L, (float)op(nb[0], nc[0]), (float)op(nb[1], nc[1]), (float)op(nb[2], nc[2]), (float)op(nb[3], nc[3]))); \ + } else if (ttisvec(rb) && ttisnumber(rc) && (tm==TM_MUL || tm==TM_DIV || tm==TM_POW)) { \ + /* vector (mul/div/pow) scalar */ \ + const float* nb = vvalue(rb)->vec; \ + lua_Number nc = nvalue(rc); \ + setvvalue(L, ra, luaVec_new(L, (float)op(nb[0], nc), (float)op(nb[1], nc), (float)op(nb[2], nc), (float)op(nb[3], nc))); \ + } else if (ttisnumber(rb) && ttisvec(rc) && tm==TM_MUL) { \ + /* scalar (mul) vector */ \ + lua_Number nb = nvalue(rb); \ + const float* nc = vvalue(rc)->vec; \ + setvvalue(L, ra, luaVec_new(L, (float)op(nb, nc[0]), (float)op(nb, nc[1]), (float)op(nb, nc[2]), (float)op(nb, nc[3]))); \ + } else \ Protect(Arith(L, ra, rb, rc, tm)); \ } + void luaV_execute (lua_State *L, int nexeccalls) { LClosure *cl; StkId base; @@ -500,8 +562,10 @@ void luaV_execute (lua_State *L, int nexeccalls) { if (ttisnumber(rb)) { lua_Number nb = nvalue(rb); setnvalue(ra, luai_numunm(nb)); - } - else { + } else if (ttisvec(rb)) { /* LUA-VEC - added unary negate */ + const float *vb = vvalue(rb)->vec; + setvvalue(L, ra, luaVec_new(L, -vb[0], -vb[1], -vb[2], -vb[3])); + } else { Protect(Arith(L, ra, rb, rb, TM_UNM)); } continue; @@ -522,6 +586,11 @@ void luaV_execute (lua_State *L, int nexeccalls) { setnvalue(ra, cast_num(tsvalue(rb)->len)); break; } + /* LUA-VEC -- #vec operator */ + case LUA_TVEC: { + setnvalue(ra, 4); + break; + } default: { /* try metamethod */ Protect( if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))