Skip to content

Commit 446b4b9

Browse files
committed
New line algo for lights
1 parent eb999cd commit 446b4b9

3 files changed

Lines changed: 126 additions & 9 deletions

File tree

plugins/rendermax/renderer_opengl.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,19 @@ struct renderer_wrap : public renderer {
114114
virtual bool uses_opengl() {
115115
return parent->uses_opengl();
116116
};
117+
void invalidateRect(int32_t x,int32_t y,int32_t w,int32_t h)
118+
{
119+
for(int i=x;i<x+w;i++)
120+
for(int j=y;j<y+h;j++)
121+
{
122+
int index=i*df::global::gps->dimy + j;
123+
screen_old[index*4]=screen[index*4]+1;
124+
}
125+
};
126+
void invalidate()
127+
{
128+
invalidateRect(0,0,df::global::gps->dimx,df::global::gps->dimy);
129+
};
117130
protected:
118131
renderer* parent;
119132
};

plugins/rendermax/rendermax.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,30 @@ static int setCell(lua_State* L)
185185
r->backOffset[id]=bo;
186186
return 0;
187187
}
188+
static int invalidate(lua_State* L)
189+
{
190+
if(current_mode!=MODE_LUA)
191+
return 0;
192+
renderer_lua* r=reinterpret_cast<renderer_lua*>(df::global::enabler->renderer);
193+
if(lua_gettop(L)==0)
194+
{
195+
r->invalidate();
196+
}
197+
else
198+
{
199+
int x,y,w,h;
200+
lua_getfield(L,1,"x");
201+
x=lua_tonumber(L,-1);lua_pop(L,1);
202+
lua_getfield(L,1,"y");
203+
y=lua_tonumber(L,-1);lua_pop(L,1);
204+
lua_getfield(L,1,"w");
205+
w=lua_tonumber(L,-1);lua_pop(L,1);
206+
lua_getfield(L,1,"h");
207+
h=lua_tonumber(L,-1);lua_pop(L,1);
208+
r->invalidateRect(x,y,w,h);
209+
}
210+
return 0;
211+
}
188212
bool isEnabled()
189213
{
190214
return current_mode==MODE_LUA;
@@ -200,6 +224,7 @@ DFHACK_PLUGIN_LUA_COMMANDS {
200224
DFHACK_LUA_COMMAND(getCell),
201225
DFHACK_LUA_COMMAND(setCell),
202226
DFHACK_LUA_COMMAND(getGridsSize),
227+
DFHACK_LUA_COMMAND(invalidate),
203228
DFHACK_LUA_END
204229
};
205230
static command_result rendermax(color_ostream &out, vector <string> & parameters)

scripts/devel/light.lua

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,82 @@ function lightPassable(shape)
5050
return true
5151
end
5252
end
53-
function LightOverlay:placeLightFov(pos,radius,color,f,rays)
53+
function circle(xm, ym,r,plot)
54+
local x = -r
55+
local y = 0
56+
local err = 2-2*r -- /* II. Quadrant */
57+
repeat
58+
plot(xm-x, ym+y);--/* I. Quadrant */
59+
plot(xm-y, ym-x);--/* II. Quadrant */
60+
plot(xm+x, ym-y);--/* III. Quadrant */
61+
plot(xm+y, ym+x);--/* IV. Quadrant */
62+
r = err;
63+
if (r <= y) then
64+
y=y+1
65+
err =err+y*2+1; --/* e_xy+e_y < 0 */
66+
end
67+
if (r > x or err > y) then
68+
x=x+1
69+
err =err+x*2+1; --/* e_xy+e_x > 0 or no 2nd y-step */
70+
end
71+
until (x >= 0);
72+
end
73+
function line(x0, y0, x1, y1,plot)
74+
local dx = math.abs(x1-x0)
75+
local dy = math.abs(y1-y0)
76+
local sx,sy
77+
if x0 < x1 then sx = 1 else sx = -1 end
78+
if y0 < y1 then sy = 1 else sy = -1 end
79+
local err = dx-dy
80+
81+
while true do
82+
if not plot(x0,y0) then
83+
return
84+
end
85+
if x0 == x1 and y0 == y1 then
86+
break
87+
end
88+
local e2 = 2*err
89+
if e2 > -dy then
90+
err = err - dy
91+
x0 = x0 + sx
92+
end
93+
if x0 == x1 and y0 == y1 then
94+
if not plot(x0,y0) then
95+
return
96+
end
97+
break
98+
end
99+
if e2 < dx then
100+
err = err + dx
101+
y0 = y0 + sy
102+
end
103+
end
104+
end
105+
function LightOverlay:placeLightFov(pos,radius,color,f)
106+
f=f or falloff
107+
local vp=self:getViewport()
108+
local map = self.df_layout.map
109+
local ray=function(tx,ty)
110+
111+
local setTile=function(x,y)
112+
if x>0 and y>0 and x<=map.width and y<=map.height then
113+
local dtsq=(pos.x-x)*(pos.x-x)+(pos.y-y)*(pos.y-y)
114+
local tile=x+y*map.width
115+
local ncol=f(color,dtsq,radius)
116+
local ocol=self.lightMap[tile] or {r=0,g=0,b=0}
117+
ncol=blend(ncol,ocol)
118+
self.lightMap[tile]=ncol
119+
120+
return self.ocupancy[tile]
121+
end
122+
return false
123+
end
124+
line(pos.x,pos.y,tx,ty,setTile)
125+
end
126+
circle(pos.x,pos.y,radius,ray)
127+
end
128+
function LightOverlay:placeLightFov2(pos,radius,color,f,rays)
54129
f=f or falloff
55130
local raycount=rays or 25
56131
local vp=self:getViewport()
@@ -115,12 +190,15 @@ function LightOverlay:calculateLightLava()
115190
local pos={x=i+vp.x1-1,y=j+vp.y1-1,z=vp.z}
116191
local pos2={x=i+vp.x1-1,y=j+vp.y1-1,z=vp.z-1}
117192
local t1=dfhack.maps.getTileFlags(pos)
118-
local shape=tile_attrs[dfhack.maps.getTileType(pos)].shape
119-
local t2=dfhack.maps.getTileFlags(pos2)
120-
if (t1 and t1.liquid_type and t1.flow_size>0) or
121-
(shape==df.tiletype_shape.EMPTY and t2 and t2.liquid_type and t2.flow_size>0) then
122-
--self:placeLight({x=i,y=j},5,{r=0.8,g=0.2,b=0.2})
123-
self:placeLightFov({x=i,y=j},5,{r=0.8,g=0.2,b=0.2},nil,5)
193+
local tt=dfhack.maps.getTileType(pos)
194+
if tt then
195+
local shape=tile_attrs[tt].shape
196+
local t2=dfhack.maps.getTileFlags(pos2)
197+
if (t1 and t1.liquid_type and t1.flow_size>0) or
198+
(shape==df.tiletype_shape.EMPTY and t2 and t2.liquid_type and t2.flow_size>0) then
199+
--self:placeLight({x=i,y=j},5,{r=0.8,g=0.2,b=0.2})
200+
self:placeLightFov({x=i,y=j},5,{r=0.8,g=0.2,b=0.2},nil,5)
201+
end
124202
end
125203
end
126204
end
@@ -193,7 +271,7 @@ function LightOverlay:render(dc)
193271

194272
self.lightMap=self.lightMap or {}
195273
render.lockGrids()
196-
df.global.gps.force_full_display_count=df.global.gps.force_full_display_count+1
274+
render.invalidate({x=map.x1,y=map.y1,w=map.width,h=map.height})
197275
render.resetGrids()
198276
for i=map.x1,map.x2 do
199277
for j=map.y1,map.y2 do
@@ -212,8 +290,9 @@ end
212290
function LightOverlay:onDismiss()
213291
render.lockGrids()
214292
render.resetGrids()
293+
render.invalidate()
215294
render.unlockGrids()
216-
df.global.gps.force_full_display_count=df.global.gps.force_full_display_count+1
295+
217296
end
218297
function LightOverlay:onInput(keys)
219298
if keys.LEAVESCREEN then

0 commit comments

Comments
 (0)