diff --git a/plugins/rendermax/CMakeLists.txt b/plugins/rendermax/CMakeLists.txt index a05294a09..5fcf4d6a9 100644 --- a/plugins/rendermax/CMakeLists.txt +++ b/plugins/rendermax/CMakeLists.txt @@ -36,4 +36,4 @@ ENDIF(UNIX) # this makes sure all the stuff is put in proper places and linked to dfhack DFHACK_PLUGIN(rendermax ${PROJECT_SRCS} LINK_LIBRARIES ${PROJECT_LIBS}) install(FILES rendermax.lua - DESTINATION ${DFHACK_DATA_DESTINATION}) \ No newline at end of file + DESTINATION ${DFHACK_BINARY_DESTINATION}) \ No newline at end of file diff --git a/plugins/rendermax/renderer_light.cpp b/plugins/rendermax/renderer_light.cpp index 6448532ec..980d1250c 100644 --- a/plugins/rendermax/renderer_light.cpp +++ b/plugins/rendermax/renderer_light.cpp @@ -27,7 +27,7 @@ using df::global::gps; using namespace DFHack; using df::coord2d; -const float levelDim=0.2f; + const float RootTwo = 1.4142135623730950488016887242097f; lightSource::lightSource(lightCell power,int radius):power(power),flicker(false) @@ -36,6 +36,7 @@ lightSource::lightSource(lightCell power,int radius):power(power),flicker(false) this->radius = radius; else { + float levelDim = 0.2f; float totalPower = power.r; if(totalPower < power.g)totalPower = power.g; if(totalPower < power.b)totalPower = power.b; @@ -239,6 +240,16 @@ void lightingEngineViewscreen::doFovs() } } } +void lightingEngineViewscreen::clear() +{ + lightMap.assign(lightMap.size(),lightCell(1,1,1)); + tthread::lock_guard guard(myRenderer->dataMutex); + if(lightMap.size()==myRenderer->lightGrid.size()) + { + std::swap(myRenderer->lightGrid,lightMap); + myRenderer->invalidate(); + } +} void lightingEngineViewscreen::calculate() { rect2d vp=getMapViewport(); @@ -270,8 +281,8 @@ void lightingEngineViewscreen::updateWindow() std::swap(lightMap,myRenderer->lightGrid); rect2d vp=getMapViewport(); - //myRenderer->invalidateRect(vp.first.x,vp.first.y,vp.second.x-vp.first.x,vp.second.y-vp.first.y); - myRenderer->invalidate(); + myRenderer->invalidateRect(vp.first.x,vp.first.y,vp.second.x-vp.first.x,vp.second.y-vp.first.y); + //myRenderer->invalidate(); //std::copy(lightMap.begin(),lightMap.end(),myRenderer->lightGrid.begin()); } void lightSource::combine(const lightSource& other) @@ -462,7 +473,7 @@ void lightingEngineViewscreen::doSun(const lightSource& sky,MapExtras::MapCache& void lightingEngineViewscreen::doOcupancyAndLights() { // TODO better curve (+red dawn ?) - float daycol = 0;//abs((*df::global::cur_year_tick % 1200) - 600.0) / 400.0; + float daycol = 1;//abs((*df::global::cur_year_tick % 1200) - 600.0) / 400.0; lightCell sky_col(daycol, daycol, daycol); lightSource sky(sky_col, 15); @@ -602,21 +613,20 @@ void lightingEngineViewscreen::doOcupancyAndLights() } if(df::global::cursor->x>-30000) { - //lightSource cursor(lightCell(9.6f,8.4f,0.3f),-1); - //cursor.flicker=false; int wx=df::global::cursor->x-window_x+vp.first.x; int wy=df::global::cursor->y-window_y+vp.first.y; int tile=getIndex(wx,wy); applyMaterial(tile,matCursor); } - lightSource citizen(lightCell(0.80f,0.80f,0.90f),6); + //citizen only emit light, if defined + if(matCitizen.isEmiting) for (int i=0;iunits.active.size();++i) { df::unit *u = df::global::world->units.active[i]; coord2d pos=worldToViewportCoord(coord2d(u->pos.x,u->pos.y),vp,window2d); if(u->pos.z==window_z && isInViewport(pos,vp)) if (DFHack::Units::isCitizen(u) && !u->counters.unconscious) - addLight(getIndex(pos.x,pos.y),citizen); + addLight(getIndex(pos.x,pos.y),matCitizen.makeSource()); } //buildings for(size_t i = 0; i < df::global::world->buildings.all.size(); i++) @@ -754,6 +764,10 @@ int lightingEngineViewscreen::parseSpecial(lua_State* L) LOAD_SPECIAL(FROZEN_LIQUID,matIce); LOAD_SPECIAL(AMBIENT,matAmbience); LOAD_SPECIAL(CURSOR,matCursor); + LOAD_SPECIAL(CITIZEN,matCitizen); + lua_getfield(L,-1,"LevelDim"); + if(!lua_isnil(L,-1) && lua_isnumber(L,-1))engine->levelDim=lua_tonumber(L,-1); + lua_pop(L,1); return 0; } #undef LOAD_SPECIAL @@ -766,6 +780,8 @@ void lightingEngineViewscreen::defaultSettings() matCursor=matLightDef(lightCell(0.96f,0.84f,0.03f),11); matCursor.flicker=true; matWall=matLightDef(lightCell(0,0,0)); + matCitizen=matLightDef(lightCell(0.8f,0.8f,0.9f),6); + levelDim=0.2f; } void lightingEngineViewscreen::loadSettings() { @@ -782,6 +798,7 @@ void lightingEngineViewscreen::loadSettings() if(ret==LUA_ERRFILE) { out.printerr("File not found:%s\n",settingsfile.c_str()); + lua_pop(s,1); } else if(ret==LUA_ERRSYNTAX) { @@ -805,6 +822,7 @@ void lightingEngineViewscreen::loadSettings() Lua::SafeCall(out,s,2,0); } + } } catch(std::exception& e) diff --git a/plugins/rendermax/renderer_light.hpp b/plugins/rendermax/renderer_light.hpp index 668a729a5..e3122a8ca 100644 --- a/plugins/rendermax/renderer_light.hpp +++ b/plugins/rendermax/renderer_light.hpp @@ -75,6 +75,7 @@ public: virtual void updateWindow()=0; virtual void loadSettings()=0; + virtual void clear()=0; protected: renderer_light* myRenderer; @@ -108,7 +109,7 @@ struct matLightDef bool flicker; lightCell emitColor; int radius; - matLightDef(){} + matLightDef():isTransparent(false),isEmiting(false),transparency(0,0,0),emitColor(0,0,0),radius(0){} matLightDef(lightCell transparency,lightCell emit,int rad):isTransparent(true),isEmiting(true), transparency(transparency),emitColor(emit),radius(rad){} matLightDef(lightCell emit,int rad):isTransparent(false),isEmiting(true),emitColor(emit),radius(rad),transparency(0,0,0){} @@ -130,6 +131,7 @@ public: void updateWindow(); void loadSettings(); + void clear(); private: df::coord2d worldToViewportCoord(const df::coord2d& in,const DFHack::rect2d& r,const df::coord2d& window2d) ; @@ -170,6 +172,8 @@ private: matLightDef matCursor; matLightDef matWall; matLightDef matWater; + matLightDef matCitizen; + float levelDim; //materials std::map,matLightDef> matDefs; diff --git a/plugins/rendermax/renderer_opengl.hpp b/plugins/rendermax/renderer_opengl.hpp index 6beba522f..57e81295b 100644 --- a/plugins/rendermax/renderer_opengl.hpp +++ b/plugins/rendermax/renderer_opengl.hpp @@ -124,13 +124,13 @@ public: for(int j=y;jdimy + j; - screen_old[index*4]=0; + screen_old[index*4]=screen[index*4]+1;//ensure tile is different } }; void invalidate() { - //invalidateRect(0,0,df::global::gps->dimx,df::global::gps->dimy); - df::global::gps->force_full_display_count++; + invalidateRect(0,0,df::global::gps->dimx,df::global::gps->dimy); + //df::global::gps->force_full_display_count++; }; protected: renderer* parent; diff --git a/plugins/rendermax/rendermax.cpp b/plugins/rendermax/rendermax.cpp index dda0d5d2c..482dfa6cb 100644 --- a/plugins/rendermax/rendermax.cpp +++ b/plugins/rendermax/rendermax.cpp @@ -3,6 +3,8 @@ #include +#include + #include "Core.h" #include "Console.h" #include "Export.h" @@ -15,12 +17,18 @@ #include "renderer_opengl.hpp" #include "renderer_light.hpp" +#include "df/viewscreen_dwarfmodest.h" +#include "df/viewscreen_dungeonmodest.h" + +using df::viewscreen_dungeonmodest; +using df::viewscreen_dwarfmodest; + using namespace DFHack; using std::vector; using std::string; enum RENDERER_MODE { - MODE_DEFAULT,MODE_TRIPPY,MODE_TRUECOLOR,MODE_LUA,MODE_LIGHT,MODE_LIGHT_OFF + MODE_DEFAULT,MODE_TRIPPY,MODE_TRUECOLOR,MODE_LUA,MODE_LIGHT }; RENDERER_MODE current_mode=MODE_DEFAULT; lightingEngine *engine=NULL; @@ -42,10 +50,44 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector calculate(); + engine->updateWindow(); + } +}; +IMPLEMENT_VMETHOD_INTERPOSE(dwarmode_render_hook, render); + +struct dungeon_render_hook : viewscreen_dungeonmodest{ + typedef df::viewscreen_dungeonmodest interpose_base; + DEFINE_VMETHOD_INTERPOSE(void,render,()) + { + CoreSuspendClaimer suspend; + INTERPOSE_NEXT(render)(); + engine->calculate(); + engine->updateWindow(); + } +}; +IMPLEMENT_VMETHOD_INTERPOSE(dungeon_render_hook, render); + void removeOld() { + if(engine) + { + CoreSuspender lock; + INTERPOSE_HOOK(dwarmode_render_hook,render).apply(false); + INTERPOSE_HOOK(dungeon_render_hook,render).apply(false); + delete engine; + + } if(current_mode!=MODE_DEFAULT) delete df::global::enabler->renderer; + current_mode=MODE_DEFAULT; } void installNew(df::renderer* r,RENDERER_MODE newMode) @@ -231,6 +273,10 @@ DFHACK_PLUGIN_LUA_COMMANDS { DFHACK_LUA_COMMAND(invalidate), DFHACK_LUA_END }; + + + + static command_result rendermax(color_ostream &out, vector & parameters) { if(parameters.size()==0) @@ -304,19 +350,22 @@ static command_result rendermax(color_ostream &out, vector & parameters } else if(cmd=="light") { - if(current_mode!=MODE_LIGHT || current_mode!=MODE_LIGHT_OFF) + if(current_mode!=MODE_LIGHT) { removeOld(); renderer_light *myRender=new renderer_light(df::global::enabler->renderer); installNew(myRender,MODE_LIGHT); engine=new lightingEngineViewscreen(myRender); - engine->calculate(); - engine->updateWindow(); + INTERPOSE_HOOK(dwarmode_render_hook,render).apply(true); + INTERPOSE_HOOK(dungeon_render_hook,render).apply(true); } else if(current_mode==MODE_LIGHT && parameters.size()>1) { if(parameters[1]=="reload") + { + CoreSuspender suspend; engine->loadSettings(); + } } else out.printerr("Light mode already enabled"); @@ -327,8 +376,6 @@ static command_result rendermax(color_ostream &out, vector & parameters { if(current_mode==MODE_DEFAULT) out.print("%s\n","Not installed, doing nothing."); - else if(current_mode==MODE_LIGHT) - current_mode=MODE_LIGHT_OFF; else removeOld(); @@ -336,27 +383,21 @@ static command_result rendermax(color_ostream &out, vector & parameters } return CR_WRONG_USAGE; } -DFhackCExport command_result plugin_onupdate (color_ostream &out) + +DFhackCExport command_result plugin_shutdown(color_ostream &) +{ + removeOld(); + return CR_OK; +} +DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event) { - if(engine) + if(event==SC_VIEWSCREEN_CHANGED) { - if(current_mode==MODE_LIGHT_OFF) + CoreSuspendClaimer suspender; + if(current_mode==MODE_LIGHT) { - delete engine; - engine=0; - removeOld(); - } - else - { - engine->calculate(); - engine->updateWindow(); + engine->clear(); } } - - return CR_OK; -} -DFhackCExport command_result plugin_shutdown(color_ostream &) -{ - removeOld(); return CR_OK; } \ No newline at end of file diff --git a/plugins/rendermax/rendermax.lua b/plugins/rendermax/rendermax.lua index 762116c0b..4b19e2485 100644 --- a/plugins/rendermax/rendermax.lua +++ b/plugins/rendermax/rendermax.lua @@ -49,6 +49,8 @@ special.WATER=makeMaterialDef({0.5,0.5,0.8}) special.FROZEN_LIQUID=makeMaterialDef({0.2,0.7,0.9}) -- ice special.AMBIENT=makeMaterialDef({0.85,0.85,0.85}) --ambient fog special.CURSOR=makeMaterialDef({1,1,1},{0.96,0.84,0.03},11, {"flicker"}) +special.CITIZEN=makeMaterialDef(nil,{0.80,0.80,0.90},6) +special.LevelDim=0.2 -- darkness. Do not set to 0 --TODO dragonfire --TODO daylight --materials