Merge branch 'master' of https://github.com/warmist/dfhack
commit
77a301db27
@ -0,0 +1,35 @@
|
|||||||
|
PROJECT (rendermax)
|
||||||
|
|
||||||
|
# A list of source files
|
||||||
|
SET(PROJECT_SRCS
|
||||||
|
rendermax.cpp
|
||||||
|
)
|
||||||
|
# A list of headers
|
||||||
|
SET(PROJECT_HDRS
|
||||||
|
renderer_opengl.hpp
|
||||||
|
)
|
||||||
|
SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
|
|
||||||
|
# mash them together (headers are marked as headers and nothing will try to compile them)
|
||||||
|
LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS})
|
||||||
|
|
||||||
|
|
||||||
|
#linux
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
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})
|
@ -0,0 +1,336 @@
|
|||||||
|
//original file from https://github.com/Baughn/Dwarf-Fortress--libgraphics-
|
||||||
|
#include "tinythread.h"
|
||||||
|
#include "fast_mutex.h"
|
||||||
|
|
||||||
|
#include "Core.h"
|
||||||
|
#include <VTableInterpose.h>
|
||||||
|
#include "df/renderer.h"
|
||||||
|
#include "df/init.h"
|
||||||
|
#include "df/enabler.h"
|
||||||
|
#include "df/zoom_commands.h"
|
||||||
|
#include "df/texture_handler.h"
|
||||||
|
#include "df/graphic.h"
|
||||||
|
|
||||||
|
using df::renderer;
|
||||||
|
using df::init;
|
||||||
|
using df::enabler;
|
||||||
|
|
||||||
|
struct old_opengl:public renderer
|
||||||
|
{
|
||||||
|
void* sdlSurface;
|
||||||
|
int32_t dispx,dispy;
|
||||||
|
float *vertexes, *fg, *bg, *tex;
|
||||||
|
int32_t zoom_steps,forced_steps,natural_w,natural_h;
|
||||||
|
int32_t off_x,off_y,size_x,size_y;
|
||||||
|
};
|
||||||
|
struct renderer_wrap : public renderer {
|
||||||
|
private:
|
||||||
|
void set_to_null() {
|
||||||
|
screen = NULL;
|
||||||
|
screentexpos = NULL;
|
||||||
|
screentexpos_addcolor = NULL;
|
||||||
|
screentexpos_grayscale = NULL;
|
||||||
|
screentexpos_cf = NULL;
|
||||||
|
screentexpos_cbr = NULL;
|
||||||
|
screen_old = NULL;
|
||||||
|
screentexpos_old = NULL;
|
||||||
|
screentexpos_addcolor_old = NULL;
|
||||||
|
screentexpos_grayscale_old = NULL;
|
||||||
|
screentexpos_cf_old = NULL;
|
||||||
|
screentexpos_cbr_old = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_from_inner() {
|
||||||
|
screen = parent->screen;
|
||||||
|
screentexpos = parent->screentexpos;
|
||||||
|
screentexpos_addcolor = parent->screentexpos_addcolor;
|
||||||
|
screentexpos_grayscale = parent->screentexpos_grayscale;
|
||||||
|
screentexpos_cf = parent->screentexpos_cf;
|
||||||
|
screentexpos_cbr = parent->screentexpos_cbr;
|
||||||
|
screen_old = parent->screen_old;
|
||||||
|
screentexpos_old = parent->screentexpos_old;
|
||||||
|
screentexpos_addcolor_old = parent->screentexpos_addcolor_old;
|
||||||
|
screentexpos_grayscale_old = parent->screentexpos_grayscale_old;
|
||||||
|
screentexpos_cf_old = parent->screentexpos_cf_old;
|
||||||
|
screentexpos_cbr_old = parent->screentexpos_cbr_old;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_to_inner() {
|
||||||
|
parent->screen = screen;
|
||||||
|
parent->screentexpos = screentexpos;
|
||||||
|
parent->screentexpos_addcolor = screentexpos_addcolor;
|
||||||
|
parent->screentexpos_grayscale = screentexpos_grayscale;
|
||||||
|
parent->screentexpos_cf = screentexpos_cf;
|
||||||
|
parent->screentexpos_cbr = screentexpos_cbr;
|
||||||
|
parent->screen_old = screen_old;
|
||||||
|
parent->screentexpos_old = screentexpos_old;
|
||||||
|
parent->screentexpos_addcolor_old = screentexpos_addcolor_old;
|
||||||
|
parent->screentexpos_grayscale_old = screentexpos_grayscale_old;
|
||||||
|
parent->screentexpos_cf_old = screentexpos_cf_old;
|
||||||
|
parent->screentexpos_cbr_old = screentexpos_cbr_old;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
renderer_wrap(renderer* parent):parent(parent)
|
||||||
|
{
|
||||||
|
copy_from_inner();
|
||||||
|
}
|
||||||
|
virtual void update_tile(int32_t x, int32_t y) {
|
||||||
|
|
||||||
|
copy_to_inner();
|
||||||
|
parent->update_tile(x,y);
|
||||||
|
};
|
||||||
|
virtual void update_all() {
|
||||||
|
copy_to_inner();
|
||||||
|
parent->update_all();
|
||||||
|
};
|
||||||
|
virtual void render() {
|
||||||
|
copy_to_inner();
|
||||||
|
parent->render();
|
||||||
|
};
|
||||||
|
virtual void set_fullscreen() {
|
||||||
|
copy_to_inner();
|
||||||
|
parent->set_fullscreen();
|
||||||
|
};
|
||||||
|
virtual void zoom(df::zoom_commands z) {
|
||||||
|
copy_to_inner();
|
||||||
|
parent->zoom(z);
|
||||||
|
};
|
||||||
|
virtual void resize(int32_t w, int32_t h) {
|
||||||
|
copy_to_inner();
|
||||||
|
parent->resize(w,h);
|
||||||
|
copy_from_inner();
|
||||||
|
};
|
||||||
|
virtual void grid_resize(int32_t w, int32_t h) {
|
||||||
|
copy_to_inner();
|
||||||
|
parent->grid_resize(w,h);
|
||||||
|
copy_from_inner();
|
||||||
|
};
|
||||||
|
virtual ~renderer_wrap() {
|
||||||
|
df::global::enabler->renderer=parent;
|
||||||
|
};
|
||||||
|
virtual bool get_mouse_coords(int32_t* x, int32_t* y) {
|
||||||
|
return parent->get_mouse_coords(x,y);
|
||||||
|
};
|
||||||
|
virtual bool uses_opengl() {
|
||||||
|
return parent->uses_opengl();
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
renderer* parent;
|
||||||
|
};
|
||||||
|
struct renderer_trippy : public renderer_wrap {
|
||||||
|
private:
|
||||||
|
float rFloat()
|
||||||
|
{
|
||||||
|
return rand()/(float)RAND_MAX;
|
||||||
|
}
|
||||||
|
void colorizeTile(int x,int y)
|
||||||
|
{
|
||||||
|
const int tile = x*(df::global::gps->dimy) + y;
|
||||||
|
old_opengl* p=reinterpret_cast<old_opengl*>(parent);
|
||||||
|
float *fg = p->fg + tile * 4 * 6;
|
||||||
|
float *bg = p->bg + tile * 4 * 6;
|
||||||
|
float *tex = p->tex + tile * 2 * 6;
|
||||||
|
const float val=1/2.0;
|
||||||
|
|
||||||
|
float r=rFloat()*val - val/2;
|
||||||
|
float g=rFloat()*val - val/2;
|
||||||
|
float b=rFloat()*val - val/2;
|
||||||
|
|
||||||
|
float backr=rFloat()*val - val/2;
|
||||||
|
float backg=rFloat()*val - val/2;
|
||||||
|
float backb=rFloat()*val - val/2;
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
*(fg++) += r;
|
||||||
|
*(fg++) += g;
|
||||||
|
*(fg++) += b;
|
||||||
|
*(fg++) = 1;
|
||||||
|
|
||||||
|
*(bg++) += backr;
|
||||||
|
*(bg++) += backg;
|
||||||
|
*(bg++) += backb;
|
||||||
|
*(bg++) = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
renderer_trippy(renderer* parent):renderer_wrap(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual void update_tile(int32_t x, int32_t y) {
|
||||||
|
renderer_wrap::update_tile(x,y);
|
||||||
|
colorizeTile(x,y);
|
||||||
|
};
|
||||||
|
virtual void update_all() {
|
||||||
|
renderer_wrap::update_all();
|
||||||
|
for (int x = 0; x < df::global::gps->dimx; x++)
|
||||||
|
for (int y = 0; y < df::global::gps->dimy; y++)
|
||||||
|
colorizeTile(x,y);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lightCell
|
||||||
|
{
|
||||||
|
float r,g,b;
|
||||||
|
lightCell():r(0),g(0),b(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
lightCell(float r,float g,float b):r(r),g(g),b(b)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
lightCell operator*(float val)
|
||||||
|
{
|
||||||
|
return lightCell(r*val,g*val,b*val);
|
||||||
|
}
|
||||||
|
lightCell operator+(const lightCell& other)
|
||||||
|
{
|
||||||
|
return lightCell(r+other.r,g+other.g,b+other.b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct renderer_test : public renderer_wrap {
|
||||||
|
private:
|
||||||
|
void colorizeTile(int x,int y)
|
||||||
|
{
|
||||||
|
const int tile = x*(df::global::gps->dimy) + y;
|
||||||
|
old_opengl* p=reinterpret_cast<old_opengl*>(parent);
|
||||||
|
float *fg = p->fg + tile * 4 * 6;
|
||||||
|
float *bg = p->bg + tile * 4 * 6;
|
||||||
|
float *tex = p->tex + tile * 2 * 6;
|
||||||
|
lightCell light=lightGrid[tile];
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
*(fg++) *= light.r;
|
||||||
|
*(fg++) *= light.g;
|
||||||
|
*(fg++) *= light.b;
|
||||||
|
*(fg++) = 1;
|
||||||
|
|
||||||
|
*(bg++) *= light.r;
|
||||||
|
*(bg++) *= light.g;
|
||||||
|
*(bg++) *= light.b;
|
||||||
|
*(bg++) = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void reinitLightGrid(int w,int h)
|
||||||
|
{
|
||||||
|
tthread::lock_guard<tthread::fast_mutex> guard(dataMutex);
|
||||||
|
lightGrid.resize(w*h);
|
||||||
|
}
|
||||||
|
void reinitLightGrid()
|
||||||
|
{
|
||||||
|
reinitLightGrid(df::global::gps->dimy,df::global::gps->dimx);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
tthread::fast_mutex dataMutex;
|
||||||
|
std::vector<lightCell> lightGrid;
|
||||||
|
renderer_test(renderer* parent):renderer_wrap(parent)
|
||||||
|
{
|
||||||
|
reinitLightGrid();
|
||||||
|
}
|
||||||
|
virtual void update_tile(int32_t x, int32_t y) {
|
||||||
|
renderer_wrap::update_tile(x,y);
|
||||||
|
tthread::lock_guard<tthread::fast_mutex> guard(dataMutex);
|
||||||
|
colorizeTile(x,y);
|
||||||
|
//some sort of mutex or sth?
|
||||||
|
//and then map read
|
||||||
|
};
|
||||||
|
virtual void update_all() {
|
||||||
|
renderer_wrap::update_all();
|
||||||
|
tthread::lock_guard<tthread::fast_mutex> guard(dataMutex);
|
||||||
|
for (int x = 0; x < df::global::gps->dimx; x++)
|
||||||
|
for (int y = 0; y < df::global::gps->dimy; y++)
|
||||||
|
colorizeTile(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);
|
||||||
|
reinitLightGrid(w,h);
|
||||||
|
};
|
||||||
|
virtual void resize(int32_t w, int32_t h) {
|
||||||
|
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<old_opengl*>(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<rgba*>(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<rgba*>(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<tthread::fast_mutex> 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<lightCell> foreOffset,foreMult;
|
||||||
|
std::vector<lightCell> 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<tthread::fast_mutex> 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<tthread::fast_mutex> 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);
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,280 @@
|
|||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <LuaTools.h>
|
||||||
|
|
||||||
|
#include "Core.h"
|
||||||
|
#include "Console.h"
|
||||||
|
#include "Export.h"
|
||||||
|
#include "PluginManager.h"
|
||||||
|
|
||||||
|
#include <VTableInterpose.h>
|
||||||
|
#include "df/renderer.h"
|
||||||
|
#include "df/enabler.h"
|
||||||
|
|
||||||
|
#include "renderer_opengl.hpp"
|
||||||
|
|
||||||
|
using namespace DFHack;
|
||||||
|
using std::vector;
|
||||||
|
using std::string;
|
||||||
|
enum RENDERER_MODE
|
||||||
|
{
|
||||||
|
MODE_DEFAULT,MODE_TRIPPY,MODE_TRUECOLOR,MODE_LUA
|
||||||
|
};
|
||||||
|
RENDERER_MODE current_mode=MODE_DEFAULT;
|
||||||
|
static command_result rendermax(color_ostream &out, vector <string> & parameters);
|
||||||
|
|
||||||
|
DFHACK_PLUGIN("rendermax");
|
||||||
|
|
||||||
|
|
||||||
|
DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
|
||||||
|
{
|
||||||
|
commands.push_back(PluginCommand(
|
||||||
|
"rendermax", "switch rendering engine.", rendermax, false,
|
||||||
|
" rendermax trippy\n"
|
||||||
|
" rendermax truecolor red|green|blue|white\n"
|
||||||
|
" rendermax disable\n"
|
||||||
|
));
|
||||||
|
return CR_OK;
|
||||||
|
}
|
||||||
|
void removeOld()
|
||||||
|
{
|
||||||
|
if(current_mode!=MODE_DEFAULT)
|
||||||
|
delete df::global::enabler->renderer;
|
||||||
|
current_mode=MODE_DEFAULT;
|
||||||
|
}
|
||||||
|
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<renderer_lua*>(df::global::enabler->renderer);
|
||||||
|
r->dataMutex.lock();
|
||||||
|
}
|
||||||
|
static void unlockGrids()
|
||||||
|
{
|
||||||
|
if(current_mode!=MODE_LUA)
|
||||||
|
return ;
|
||||||
|
renderer_lua* r=reinterpret_cast<renderer_lua*>(df::global::enabler->renderer);
|
||||||
|
r->dataMutex.unlock();
|
||||||
|
}
|
||||||
|
static void resetGrids()
|
||||||
|
{
|
||||||
|
if(current_mode!=MODE_LUA)
|
||||||
|
return ;
|
||||||
|
renderer_lua* r=reinterpret_cast<renderer_lua*>(df::global::enabler->renderer);
|
||||||
|
for(size_t i=0;i<r->foreMult.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<renderer_lua*>(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<renderer_lua*>(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<renderer_lua*>(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 <string> & parameters)
|
||||||
|
{
|
||||||
|
if(parameters.size()==0)
|
||||||
|
return CR_WRONG_USAGE;
|
||||||
|
string cmd=parameters[0];
|
||||||
|
if(cmd=="trippy")
|
||||||
|
{
|
||||||
|
removeOld();
|
||||||
|
installNew(new renderer_trippy(df::global::enabler->renderer),MODE_TRIPPY);
|
||||||
|
return CR_OK;
|
||||||
|
}
|
||||||
|
else if(cmd=="truecolor")
|
||||||
|
{
|
||||||
|
if(current_mode!=MODE_TRUECOLOR)
|
||||||
|
{
|
||||||
|
removeOld();
|
||||||
|
installNew(new renderer_test(df::global::enabler->renderer),MODE_TRUECOLOR);
|
||||||
|
}
|
||||||
|
if(current_mode==MODE_TRUECOLOR && parameters.size()==2)
|
||||||
|
{
|
||||||
|
lightCell red(1,0,0),green(0,1,0),blue(0,0,1),white(1,1,1);
|
||||||
|
lightCell cur=white;
|
||||||
|
lightCell dim(0.2,0.2,0.2);
|
||||||
|
string col=parameters[1];
|
||||||
|
if(col=="red")
|
||||||
|
cur=red;
|
||||||
|
else if(col=="green")
|
||||||
|
cur=green;
|
||||||
|
else if(col=="blue")
|
||||||
|
cur=blue;
|
||||||
|
|
||||||
|
renderer_test* r=reinterpret_cast<renderer_test*>(df::global::enabler->renderer);
|
||||||
|
tthread::lock_guard<tthread::fast_mutex> guard(r->dataMutex);
|
||||||
|
int h=df::global::gps->dimy;
|
||||||
|
int w=df::global::gps->dimx;
|
||||||
|
int cx=w/2;
|
||||||
|
int cy=h/2;
|
||||||
|
int rad=cx;
|
||||||
|
if(rad>cy)rad=cy;
|
||||||
|
rad/=2;
|
||||||
|
int radsq=rad*rad;
|
||||||
|
for(size_t i=0;i<r->lightGrid.size();i++)
|
||||||
|
{
|
||||||
|
r->lightGrid[i]=dim;
|
||||||
|
}
|
||||||
|
for(int i=-rad;i<rad;i++)
|
||||||
|
for(int j=-rad;j<rad;j++)
|
||||||
|
{
|
||||||
|
if((i*i+j*j)<radsq)
|
||||||
|
{
|
||||||
|
float val=(radsq-i*i-j*j)/(float)radsq;
|
||||||
|
r->lightGrid[(cx+i)*h+(cy+j)]=dim+cur*val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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")
|
||||||
|
{
|
||||||
|
if(current_mode==MODE_DEFAULT)
|
||||||
|
out.print("%s\n","Not installed, doing nothing.");
|
||||||
|
else
|
||||||
|
removeOld();
|
||||||
|
|
||||||
|
return CR_OK;
|
||||||
|
}
|
||||||
|
return CR_WRONG_USAGE;
|
||||||
|
}
|
@ -0,0 +1,238 @@
|
|||||||
|
-- an experimental lighting engine for df
|
||||||
|
local gui = require 'gui'
|
||||||
|
local guidm = require 'gui.dwarfmode'
|
||||||
|
local render = require 'plugins.rendermax'
|
||||||
|
|
||||||
|
local levelDim=0.05
|
||||||
|
local tile_attrs = df.tiletype.attrs
|
||||||
|
|
||||||
|
local args={...}
|
||||||
|
|
||||||
|
function setCell(x,y,cell)
|
||||||
|
cell=cell or {}
|
||||||
|
cell.fm=cell.fm or {r=1,g=1,b=1}
|
||||||
|
cell.bm=cell.bm or {r=1,g=1,b=1}
|
||||||
|
cell.fo=cell.fo or {r=0,g=0,b=0}
|
||||||
|
cell.bo=cell.bo or {r=0,g=0,b=0}
|
||||||
|
render.setCell(x,y,cell)
|
||||||
|
end
|
||||||
|
function getCursorPos()
|
||||||
|
local g_cursor=df.global.cursor
|
||||||
|
if g_cursor.x ~= -30000 then
|
||||||
|
return copyall(g_cursor)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function falloff(color,sqDist,maxdist)
|
||||||
|
local v1=1/(sqDist/maxdist+1)
|
||||||
|
local v2=v1-1/(1+maxdist*maxdist)
|
||||||
|
local v=v2/(1-1/(1+maxdist*maxdist))
|
||||||
|
return {r=v*color.r,g=v*color.g,b=v*color.b}
|
||||||
|
end
|
||||||
|
function blend(c1,c2)
|
||||||
|
return {r=math.max(c1.r,c2.r),
|
||||||
|
g=math.max(c1.g,c2.g),
|
||||||
|
b=math.max(c1.b,c2.b)}
|
||||||
|
end
|
||||||
|
LightOverlay=defclass(LightOverlay,guidm.DwarfOverlay)
|
||||||
|
LightOverlay.ATTRS {
|
||||||
|
lightMap={},
|
||||||
|
dynamic=true
|
||||||
|
}
|
||||||
|
function LightOverlay.init(args)
|
||||||
|
end
|
||||||
|
|
||||||
|
function lightPassable(shape)
|
||||||
|
if shape==df.tiletype_shape.WALL or
|
||||||
|
shape==df.tiletype_shape.BROOK_BED or
|
||||||
|
shape==df.tiletype_shape.TREE then
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function LightOverlay:placeLightFov(pos,radius,color,f,rays)
|
||||||
|
f=f or falloff
|
||||||
|
local raycount=rays or 25
|
||||||
|
local vp=self:getViewport()
|
||||||
|
local map = self.df_layout.map
|
||||||
|
local off=math.random(0,math.pi)
|
||||||
|
local done={}
|
||||||
|
for d=0,math.pi*2,math.pi*2/raycount do
|
||||||
|
local dx,dy
|
||||||
|
dx=math.cos(d+off)
|
||||||
|
dy=math.sin(d+off)
|
||||||
|
local cx=0
|
||||||
|
local cy=0
|
||||||
|
|
||||||
|
for dt=0,radius,0.01 do
|
||||||
|
if math.abs(math.floor(dt*dx)-cx)>0 or math.abs(math.floor(dt*dy)-cy)> 0then
|
||||||
|
local x=cx+pos.x
|
||||||
|
local y=cy+pos.y
|
||||||
|
|
||||||
|
if x>0 and y>0 and x<=map.width and y<=map.height and not done[tile] then
|
||||||
|
local tile=x+y*map.width
|
||||||
|
done[tile]=true
|
||||||
|
local ncol=f(color,dt*dt,radius)
|
||||||
|
local ocol=self.lightMap[tile] or {r=0,g=0,b=0}
|
||||||
|
ncol=blend(ncol,ocol)
|
||||||
|
self.lightMap[tile]=ncol
|
||||||
|
|
||||||
|
|
||||||
|
if --(ncol.r==ocol.r and ncol.g==ocol.g and ncol.b==ocol.b) or
|
||||||
|
not self.ocupancy[tile] then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
cx=math.floor(dt*dx)
|
||||||
|
cy=math.floor(dt*dy)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function LightOverlay:placeLight(pos,radius,color,f)
|
||||||
|
f=f or falloff
|
||||||
|
local vp=self:getViewport()
|
||||||
|
local map = self.df_layout.map
|
||||||
|
|
||||||
|
for i=-radius,radius do
|
||||||
|
for j=-radius,radius do
|
||||||
|
local x=pos.x+i+1
|
||||||
|
local y=pos.y+j+1
|
||||||
|
if x>0 and y>0 and x<=map.width and y<=map.height then
|
||||||
|
local tile=x+y*map.width
|
||||||
|
local ncol=f(color,(i*i+j*j),radius)
|
||||||
|
local ocol=self.lightMap[tile] or {r=0,g=0,b=0}
|
||||||
|
self.lightMap[tile]=blend(ncol,ocol)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function LightOverlay:calculateLightLava()
|
||||||
|
local vp=self:getViewport()
|
||||||
|
local map = self.df_layout.map
|
||||||
|
for i=map.x1,map.x2 do
|
||||||
|
for j=map.y1,map.y2 do
|
||||||
|
local pos={x=i+vp.x1-1,y=j+vp.y1-1,z=vp.z}
|
||||||
|
local pos2={x=i+vp.x1-1,y=j+vp.y1-1,z=vp.z-1}
|
||||||
|
local t1=dfhack.maps.getTileFlags(pos)
|
||||||
|
local shape=tile_attrs[dfhack.maps.getTileType(pos)].shape
|
||||||
|
local t2=dfhack.maps.getTileFlags(pos2)
|
||||||
|
if (t1 and t1.liquid_type and t1.flow_size>0) or
|
||||||
|
(shape==df.tiletype_shape.EMPTY and t2 and t2.liquid_type and t2.flow_size>0) then
|
||||||
|
--self:placeLight({x=i,y=j},5,{r=0.8,g=0.2,b=0.2})
|
||||||
|
self:placeLightFov({x=i,y=j},5,{r=0.8,g=0.2,b=0.2},nil,5)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function LightOverlay:calculateLightSun()
|
||||||
|
local vp=self:getViewport()
|
||||||
|
local map = self.df_layout.map
|
||||||
|
for i=map.x1,map.x2+1 do
|
||||||
|
for j=map.y1,map.y2+1 do
|
||||||
|
local pos={x=i+vp.x1-1,y=j+vp.y1-1,z=vp.z}
|
||||||
|
|
||||||
|
local t1=dfhack.maps.getTileFlags(pos)
|
||||||
|
|
||||||
|
if (t1 and t1.outside ) then
|
||||||
|
|
||||||
|
self:placeLightFov({x=i,y=j},7,{r=1,g=1,b=1},nil,3)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function LightOverlay:calculateLightCursor()
|
||||||
|
local c=getCursorPos()
|
||||||
|
|
||||||
|
if c then
|
||||||
|
|
||||||
|
local vp=self:getViewport()
|
||||||
|
local pos=vp:tileToScreen(c)
|
||||||
|
--self:placeLight(pos,11,{r=0.96,g=0.84,b=0.03})
|
||||||
|
self:placeLightFov({x=pos.x+1,y=pos.y+1},11,{r=0.96,g=0.84,b=0.03})
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function LightOverlay:buildOcupancy()
|
||||||
|
self.ocupancy={}
|
||||||
|
local vp=self:getViewport()
|
||||||
|
local map = self.df_layout.map
|
||||||
|
for i=map.x1,map.x2+1 do
|
||||||
|
for j=map.y1,map.y2+1 do
|
||||||
|
local pos={x=i+vp.x1-1,y=j+vp.y1-1,z=vp.z}
|
||||||
|
local tile=i+j*map.width
|
||||||
|
local tt=dfhack.maps.getTileType(pos)
|
||||||
|
|
||||||
|
if tt then
|
||||||
|
local shape=tile_attrs[tt].shape
|
||||||
|
self.ocupancy[tile]=lightPassable(shape)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
function LightOverlay:makeLightMap()
|
||||||
|
self.lightMap={}
|
||||||
|
self:buildOcupancy()
|
||||||
|
self:calculateLightCursor()
|
||||||
|
self:calculateLightLava()
|
||||||
|
self:calculateLightSun()
|
||||||
|
end
|
||||||
|
function LightOverlay:onIdle()
|
||||||
|
self._native.parent:logic()
|
||||||
|
if self.dynamic then
|
||||||
|
self:makeLightMap()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function LightOverlay:render(dc)
|
||||||
|
|
||||||
|
|
||||||
|
self:renderParent()
|
||||||
|
local vp=self:getViewport()
|
||||||
|
local map = self.df_layout.map
|
||||||
|
|
||||||
|
self.lightMap=self.lightMap or {}
|
||||||
|
render.lockGrids()
|
||||||
|
df.global.gps.force_full_display_count=df.global.gps.force_full_display_count+1
|
||||||
|
render.resetGrids()
|
||||||
|
for i=map.x1,map.x2 do
|
||||||
|
for j=map.y1,map.y2 do
|
||||||
|
local v=self.lightMap[i+j*map.width]
|
||||||
|
if v then
|
||||||
|
setCell(i,j,{fm=v,bm=v})
|
||||||
|
else
|
||||||
|
local dimRgb={r=levelDim,g=levelDim,b=levelDim}
|
||||||
|
setCell(i,j,{fm=dimRgb,bm=dimRgb})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
render.unlockGrids()
|
||||||
|
|
||||||
|
end
|
||||||
|
function LightOverlay:onDismiss()
|
||||||
|
render.lockGrids()
|
||||||
|
render.resetGrids()
|
||||||
|
render.unlockGrids()
|
||||||
|
df.global.gps.force_full_display_count=df.global.gps.force_full_display_count+1
|
||||||
|
end
|
||||||
|
function LightOverlay:onInput(keys)
|
||||||
|
if keys.LEAVESCREEN then
|
||||||
|
self:dismiss()
|
||||||
|
else
|
||||||
|
self:sendInputToParent(keys)
|
||||||
|
|
||||||
|
if keys.CHANGETAB then
|
||||||
|
self:updateLayout()
|
||||||
|
end
|
||||||
|
if keys.STRING_A126 and not self.dynamic then
|
||||||
|
self:makeLightMap()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not render.isEnabled() then
|
||||||
|
qerror("Lua rendermode not enabled!")
|
||||||
|
end
|
||||||
|
local dyn=true
|
||||||
|
if #args>0 and args[1]=="static" then dyn=false end
|
||||||
|
local lview = LightOverlay{ dynamic=dyn}
|
||||||
|
lview:show()
|
Loading…
Reference in New Issue