diff --git a/plugins/rendermax/CMakeLists.txt b/plugins/rendermax/CMakeLists.txt index c781bde48..a7422a2cd 100644 --- a/plugins/rendermax/CMakeLists.txt +++ b/plugins/rendermax/CMakeLists.txt @@ -19,12 +19,14 @@ IF(UNIX) add_definitions(-DLINUX_BUILD) SET(PROJECT_LIBS # add any extra linux libs here + lua ${PROJECT_LIBS} ) # windows ELSE(UNIX) SET(PROJECT_LIBS # add any extra windows libs here + lua ${PROJECT_LIBS} $(NOINHERIT) ) diff --git a/plugins/rendermax/renderer_opengl.hpp b/plugins/rendermax/renderer_opengl.hpp index 525460b71..1cd9d1bac 100644 --- a/plugins/rendermax/renderer_opengl.hpp +++ b/plugins/rendermax/renderer_opengl.hpp @@ -250,4 +250,87 @@ public: renderer_wrap::resize(w,h); reinitLightGrid(w,h); } +}; + +struct rgba +{ + float r,g,b,a; +}; +struct renderer_lua : public renderer_wrap { +private: + void overwriteTile(int x,int y) + { + const int tile = xyToTile(x,y); + old_opengl* p=reinterpret_cast(parent); + float *fg = p->fg + tile * 4 * 6; + float *bg = p->bg + tile * 4 * 6; + float *tex = p->tex + tile * 2 * 6; + lightCell fm=foreMult[tile]; + lightCell fo=foreOffset[tile]; + + lightCell bm=backMult[tile]; + lightCell bo=backOffset[tile]; + for (int i = 0; i < 6; i++) { + rgba* fore=reinterpret_cast(fg); + fore->r=fore->r*fm.r+fo.r; + fore->g=fore->g*fm.g+fo.g; + fore->b=fore->b*fm.b+fo.b; + + fg+=4; + rgba* back=reinterpret_cast(bg); + back->r=back->r*bm.r+bo.r; + back->g=back->g*bm.g+bo.g; + back->b=back->b*bm.b+bo.b; + bg+=4; + } + } + void reinitGrids(int w,int h) + { + tthread::lock_guard guard(dataMutex); + foreOffset.resize(w*h); + foreMult.resize(w*h); + backOffset.resize(w*h); + backMult.resize(w*h); + } + void reinitGrids() + { + reinitGrids(df::global::gps->dimy,df::global::gps->dimx); + } +public: + tthread::fast_mutex dataMutex; + std::vector foreOffset,foreMult; + std::vector backOffset,backMult; + inline int xyToTile(int x, int y) + { + return x*(df::global::gps->dimy) + y; + } + renderer_lua(renderer* parent):renderer_wrap(parent) + { + reinitGrids(); + } + virtual void update_tile(int32_t x, int32_t y) { + renderer_wrap::update_tile(x,y); + tthread::lock_guard guard(dataMutex); + overwriteTile(x,y); + //some sort of mutex or sth? + //and then map read + }; + virtual void update_all() { + renderer_wrap::update_all(); + tthread::lock_guard guard(dataMutex); + for (int x = 0; x < df::global::gps->dimx; x++) + for (int y = 0; y < df::global::gps->dimy; y++) + overwriteTile(x,y); + //some sort of mutex or sth? + //and then map read + //same stuff for all of them i guess... + }; + virtual void grid_resize(int32_t w, int32_t h) { + renderer_wrap::grid_resize(w,h); + reinitGrids(w,h); + }; + virtual void resize(int32_t w, int32_t h) { + renderer_wrap::resize(w,h); + reinitGrids(w,h); + } }; \ No newline at end of file diff --git a/plugins/rendermax/rendermax.cpp b/plugins/rendermax/rendermax.cpp index 85232cde9..cc4b77301 100644 --- a/plugins/rendermax/rendermax.cpp +++ b/plugins/rendermax/rendermax.cpp @@ -1,6 +1,8 @@ #include #include +#include + #include "Core.h" #include "Console.h" #include "Export.h" @@ -17,7 +19,7 @@ using std::vector; using std::string; enum RENDERER_MODE { - MODE_DEFAULT,MODE_TRIPPY,MODE_TRUECOLOR + MODE_DEFAULT,MODE_TRIPPY,MODE_TRUECOLOR,MODE_LUA }; RENDERER_MODE current_mode=MODE_DEFAULT; static command_result rendermax(color_ostream &out, vector & parameters); @@ -46,6 +48,159 @@ void installNew(df::renderer* r,RENDERER_MODE newMode) df::global::enabler->renderer=r; current_mode=newMode; } +static void lockGrids() +{ + if(current_mode!=MODE_LUA) + return ; + renderer_lua* r=reinterpret_cast(df::global::enabler->renderer); + r->dataMutex.lock(); +} +static void unlockGrids() +{ + if(current_mode!=MODE_LUA) + return ; + renderer_lua* r=reinterpret_cast(df::global::enabler->renderer); + r->dataMutex.unlock(); +} +static void resetGrids() +{ + if(current_mode!=MODE_LUA) + return ; + renderer_lua* r=reinterpret_cast(df::global::enabler->renderer); + for(size_t i=0;iforeMult.size();i++) + { + r->foreMult[i]=lightCell(1,1,1); + r->foreOffset[i]=lightCell(0,0,0); + r->backMult[i]=lightCell(1,1,1); + r->backOffset[i]=lightCell(0,0,0); + } +} +static int getGridsSize() +{ + if(current_mode!=MODE_LUA) + return -1; + renderer_lua* r=reinterpret_cast(df::global::enabler->renderer); + lua_pushnumber(L,df::global::gps->dimx); + lua_pushnumber(L,df::global::gps->dimy); + return 2; +} +static int getCell(lua_State* L) +{ + if(current_mode!=MODE_LUA) + return 0; + renderer_lua* r=reinterpret_cast(df::global::enabler->renderer); + int x=luaL_checknumber(L,1); + int y=luaL_checknumber(L,2); + int id=r->xyToTile(x,y); + lightCell fo=r->foreOffset[id]; + lightCell fm=r->foreMult[id]; + lightCell bo=r->backOffset[id]; + lightCell bm=r->backMult[id]; + lua_newtable(L); + + lua_newtable(L); + lua_pushnumber(L,fo.r); + lua_setfield(L,-2,"r"); + lua_pushnumber(L,fo.g); + lua_setfield(L,-2,"g"); + lua_pushnumber(L,fo.b); + lua_setfield(L,-2,"b"); + lua_setfield(L,-2,"fo"); + + lua_newtable(L); + lua_pushnumber(L,fm.r); + lua_setfield(L,-2,"r"); + lua_pushnumber(L,fm.g); + lua_setfield(L,-2,"g"); + lua_pushnumber(L,fm.b); + lua_setfield(L,-2,"b"); + lua_setfield(L,-2,"fm"); + + lua_newtable(L); + lua_pushnumber(L,bo.r); + lua_setfield(L,-2,"r"); + lua_pushnumber(L,bo.g); + lua_setfield(L,-2,"g"); + lua_pushnumber(L,bo.b); + lua_setfield(L,-2,"b"); + lua_setfield(L,-2,"bo"); + + lua_newtable(L); + lua_pushnumber(L,bm.r); + lua_setfield(L,-2,"r"); + lua_pushnumber(L,bm.g); + lua_setfield(L,-2,"g"); + lua_pushnumber(L,bm.b); + lua_setfield(L,-2,"b"); + lua_setfield(L,-2,"bm"); + return 1; +} +static int setCell(lua_State* L) +{ + if(current_mode!=MODE_LUA) + return 0; + renderer_lua* r=reinterpret_cast(df::global::enabler->renderer); + int x=luaL_checknumber(L,1); + int y=luaL_checknumber(L,2); + + lightCell fo; + lua_getfield(L,3,"fo"); + lua_getfield(L,-1,"r"); + fo.r=lua_tonumber(L,-1);lua_pop(L,1); + lua_getfield(L,-1,"g"); + fo.g=lua_tonumber(L,-1);lua_pop(L,1); + lua_getfield(L,-1,"b"); + fo.b=lua_tonumber(L,-1);lua_pop(L,1); + lightCell fm; + lua_getfield(L,3,"fm"); + lua_getfield(L,-1,"r"); + fm.r=lua_tonumber(L,-1);lua_pop(L,1); + lua_getfield(L,-1,"g"); + fm.g=lua_tonumber(L,-1);lua_pop(L,1); + lua_getfield(L,-1,"b"); + fm.b=lua_tonumber(L,-1);lua_pop(L,1); + + lightCell bo; + lua_getfield(L,3,"bo"); + lua_getfield(L,-1,"r"); + bo.r=lua_tonumber(L,-1);lua_pop(L,1); + lua_getfield(L,-1,"g"); + bo.g=lua_tonumber(L,-1);lua_pop(L,1); + lua_getfield(L,-1,"b"); + bo.b=lua_tonumber(L,-1);lua_pop(L,1); + + lightCell bm; + lua_getfield(L,3,"bm"); + lua_getfield(L,-1,"r"); + bm.r=lua_tonumber(L,-1);lua_pop(L,1); + lua_getfield(L,-1,"g"); + bm.g=lua_tonumber(L,-1);lua_pop(L,1); + lua_getfield(L,-1,"b"); + bm.b=lua_tonumber(L,-1);lua_pop(L,1); + int id=r->xyToTile(x,y); + r->foreMult[id]=fm; + r->foreOffset[id]=fo; + r->backMult[id]=bm; + r->backOffset[id]=bo; + return 0; +} +bool isEnabled() +{ + return current_mode==MODE_LUA; +} +DFHACK_PLUGIN_LUA_FUNCTIONS { + DFHACK_LUA_FUNCTION(isEnabled), + DFHACK_LUA_FUNCTION(lockGrids), + DFHACK_LUA_FUNCTION(unlockGrids), + DFHACK_LUA_FUNCTION(getGridsSize), + DFHACK_LUA_FUNCTION(resetGrids), + DFHACK_LUA_END +}; +DFHACK_PLUGIN_LUA_COMMANDS { + DFHACK_LUA_COMMAND(getCell), + DFHACK_LUA_COMMAND(setCell), + DFHACK_LUA_END +}; static command_result rendermax(color_ostream &out, vector & parameters) { if(parameters.size()==0) @@ -102,8 +257,15 @@ static command_result rendermax(color_ostream &out, vector & parameters } return CR_OK; } - - + } + else if(cmd=="lua") + { + removeOld(); + installNew(new renderer_lua(df::global::enabler->renderer),MODE_LUA); + lockGrids(); + resetGrids(); + unlockGrids(); + return CR_OK; } else if(cmd=="disable") {