Add buildsys
FossilOrigin-Name: e5461ff8527693d6fead8581236f625852d55c2a3d7577e4eac219c7031e774f
This commit is contained in:
parent
acb5cb42f3
commit
cbf07a9ef5
48 changed files with 6326 additions and 14 deletions
214
src/worldlight.cxx
Normal file
214
src/worldlight.cxx
Normal file
|
@ -0,0 +1,214 @@
|
|||
// worldlight.cpp
|
||||
|
||||
#include "cube.h"
|
||||
|
||||
extern bool hasoverbright;
|
||||
|
||||
VAR(lightscale,1,4,100);
|
||||
|
||||
void lightray(float bx, float by, persistent_entity &light) // done in realtime, needs to be fast
|
||||
{
|
||||
float lx = light.x+(rnd(21)-10)*0.1f;
|
||||
float ly = light.y+(rnd(21)-10)*0.1f;
|
||||
float dx = bx-lx;
|
||||
float dy = by-ly;
|
||||
float dist = (float)sqrt(dx*dx+dy*dy);
|
||||
if(dist<1.0f) return;
|
||||
int reach = light.attr1;
|
||||
int steps = (int)(reach*reach*1.6f/dist); // can change this for speedup/quality?
|
||||
const int PRECBITS = 12;
|
||||
const float PRECF = 4096.0f;
|
||||
int x = (int)(lx*PRECF);
|
||||
int y = (int)(ly*PRECF);
|
||||
int l = light.attr2<<PRECBITS;
|
||||
int stepx = (int)(dx/(float)steps*PRECF);
|
||||
int stepy = (int)(dy/(float)steps*PRECF);
|
||||
int stepl = fast_f2nat(l/(float)steps); // incorrect: light will fade quicker if near edge of the world
|
||||
|
||||
if(hasoverbright)
|
||||
{
|
||||
l /= lightscale;
|
||||
stepl /= lightscale;
|
||||
|
||||
if(light.attr3 || light.attr4) // coloured light version, special case because most lights are white
|
||||
{
|
||||
int dimness = rnd((255-(light.attr2+light.attr3+light.attr4)/3)/16+1);
|
||||
x += stepx*dimness;
|
||||
y += stepy*dimness;
|
||||
|
||||
if(OUTBORD(x>>PRECBITS, y>>PRECBITS)) return;
|
||||
|
||||
int g = light.attr3<<PRECBITS;
|
||||
int stepg = fast_f2nat(g/(float)steps);
|
||||
int b = light.attr4<<PRECBITS;
|
||||
int stepb = fast_f2nat(b/(float)steps);
|
||||
g /= lightscale;
|
||||
stepg /= lightscale;
|
||||
b /= lightscale;
|
||||
stepb /= lightscale;
|
||||
loopi(steps)
|
||||
{
|
||||
sqr *s = S(x>>PRECBITS, y>>PRECBITS);
|
||||
int tl = (l>>PRECBITS)+s->r;
|
||||
s->r = tl>255 ? 255 : tl;
|
||||
tl = (g>>PRECBITS)+s->g;
|
||||
s->g = tl>255 ? 255 : tl;
|
||||
tl = (b>>PRECBITS)+s->b;
|
||||
s->b = tl>255 ? 255 : tl;
|
||||
if(SOLID(s)) return;
|
||||
x += stepx;
|
||||
y += stepy;
|
||||
l -= stepl;
|
||||
g -= stepg;
|
||||
b -= stepb;
|
||||
stepl -= 25;
|
||||
stepg -= 25;
|
||||
stepb -= 25;
|
||||
};
|
||||
}
|
||||
else // white light, special optimized version
|
||||
{
|
||||
int dimness = rnd((255-light.attr2)/16+1);
|
||||
x += stepx*dimness;
|
||||
y += stepy*dimness;
|
||||
|
||||
if(OUTBORD(x>>PRECBITS, y>>PRECBITS)) return;
|
||||
|
||||
loopi(steps)
|
||||
{
|
||||
sqr *s = S(x>>PRECBITS, y>>PRECBITS);
|
||||
int tl = (l>>PRECBITS)+s->r;
|
||||
s->r = s->g = s->b = tl>255 ? 255 : tl;
|
||||
if(SOLID(s)) return;
|
||||
x += stepx;
|
||||
y += stepy;
|
||||
l -= stepl;
|
||||
stepl -= 25;
|
||||
};
|
||||
};
|
||||
}
|
||||
else // the old (white) light code, here for the few people with old video cards that don't support overbright
|
||||
{
|
||||
loopi(steps)
|
||||
{
|
||||
sqr *s = S(x>>PRECBITS, y>>PRECBITS);
|
||||
int light = l>>PRECBITS;
|
||||
if(light>s->r) s->r = s->g = s->b = (uchar)light;
|
||||
if(SOLID(s)) return;
|
||||
x += stepx;
|
||||
y += stepy;
|
||||
l -= stepl;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void calclightsource(persistent_entity &l)
|
||||
{
|
||||
int reach = l.attr1;
|
||||
int sx = l.x-reach;
|
||||
int ex = l.x+reach;
|
||||
int sy = l.y-reach;
|
||||
int ey = l.y+reach;
|
||||
|
||||
rndreset();
|
||||
|
||||
const float s = 0.8f;
|
||||
|
||||
for(float sx2 = (float)sx; sx2<=ex; sx2+=s*2) { lightray(sx2, (float)sy, l); lightray(sx2, (float)ey, l); };
|
||||
for(float sy2 = sy+s; sy2<=ey-s; sy2+=s*2) { lightray((float)sx, sy2, l); lightray((float)ex, sy2, l); };
|
||||
|
||||
rndtime();
|
||||
};
|
||||
|
||||
void postlightarea(block &a) // median filter, smooths out random noise in light and makes it more mipable
|
||||
{
|
||||
loop(x,a.xs) loop(y,a.ys) // assumes area not on edge of world
|
||||
{
|
||||
sqr *s = S(x+a.x,y+a.y);
|
||||
#define median(m) s->m = (s->m*2 + SW(s,1,0)->m*2 + SW(s,0,1)->m*2 \
|
||||
+ SW(s,-1,0)->m*2 + SW(s,0,-1)->m*2 \
|
||||
+ SW(s,1,1)->m + SW(s,1,-1)->m \
|
||||
+ SW(s,-1,1)->m + SW(s,-1,-1)->m)/14; // median is 4/2/1 instead
|
||||
median(r);
|
||||
median(g);
|
||||
median(b);
|
||||
};
|
||||
|
||||
remip(a);
|
||||
};
|
||||
|
||||
void calclight()
|
||||
{
|
||||
loop(x,ssize) loop(y,ssize)
|
||||
{
|
||||
sqr *s = S(x,y);
|
||||
s->r = s->g = s->b = 10;
|
||||
};
|
||||
|
||||
loopv(ents)
|
||||
{
|
||||
entity &e = ents[i];
|
||||
if(e.type==LIGHT) calclightsource(e);
|
||||
};
|
||||
|
||||
block b = { 1, 1, ssize-2, ssize-2 };
|
||||
postlightarea(b);
|
||||
setvar("fullbright", 0);
|
||||
};
|
||||
|
||||
VARP(dynlight, 0, 16, 32);
|
||||
|
||||
vector<block *> dlights;
|
||||
|
||||
void cleardlights()
|
||||
{
|
||||
while(!dlights.empty())
|
||||
{
|
||||
block *backup = dlights.pop();
|
||||
blockpaste(*backup);
|
||||
free(backup);
|
||||
};
|
||||
};
|
||||
|
||||
void dodynlight(vec &vold, vec &v, int reach, int strength, dynent *owner)
|
||||
{
|
||||
if(!reach) reach = dynlight;
|
||||
if(owner->monsterstate) reach = reach/2;
|
||||
if(!reach) return;
|
||||
if(v.x<0 || v.y<0 || v.x>ssize || v.y>ssize) return;
|
||||
|
||||
int creach = reach+16; // dependant on lightray random offsets!
|
||||
block b = { (int)v.x-creach, (int)v.y-creach, creach*2+1, creach*2+1 };
|
||||
|
||||
if(b.x<1) b.x = 1;
|
||||
if(b.y<1) b.y = 1;
|
||||
if(b.xs+b.x>ssize-2) b.xs = ssize-2-b.x;
|
||||
if(b.ys+b.y>ssize-2) b.ys = ssize-2-b.y;
|
||||
|
||||
dlights.add(blockcopy(b)); // backup area before rendering in dynlight
|
||||
|
||||
persistent_entity l = { (int)v.x, (int)v.y, (int)v.z, reach, LIGHT, strength, 0, 0 };
|
||||
calclightsource(l);
|
||||
postlightarea(b);
|
||||
};
|
||||
|
||||
// utility functions also used by editing code
|
||||
|
||||
block *blockcopy(block &s)
|
||||
{
|
||||
block *b = (block *)alloc(sizeof(block)+s.xs*s.ys*sizeof(sqr));
|
||||
*b = s;
|
||||
sqr *q = (sqr *)(b+1);
|
||||
for(int x = s.x; x<s.xs+s.x; x++) for(int y = s.y; y<s.ys+s.y; y++) *q++ = *S(x,y);
|
||||
return b;
|
||||
};
|
||||
|
||||
void blockpaste(block &b)
|
||||
{
|
||||
sqr *q = (sqr *)((&b)+1);
|
||||
for(int x = b.x; x<b.xs+b.x; x++) for(int y = b.y; y<b.ys+b.y; y++) *S(x,y) = *q++;
|
||||
remipmore(b);
|
||||
};
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue