- merged 3dfloors2 branch into trunk.

SVN r3124 (trunk)
This commit is contained in:
Christoph Oelckers 2011-01-29 11:09:38 +00:00
commit fae8ed444c
41 changed files with 12358 additions and 445 deletions

View file

@ -56,6 +56,7 @@
#include "r_bsp.h"
#include "r_plane.h"
#include "r_segs.h"
#include "r_3dfloors.h"
#include "v_palette.h"
#include "r_translate.h"
@ -1683,7 +1684,7 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop
// R_ProjectSprite
// Generates a vissprite for a thing if it might be visible.
//
void R_ProjectSprite (AActor *thing, int fakeside)
void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling)
{
fixed_t fx, fy, fz;
fixed_t tr_x;
@ -1978,11 +1979,14 @@ void R_ProjectSprite (AActor *thing, int fakeside)
vis->gzb = gzb; // [RH] use gzb, not thing->z
vis->gzt = gzt; // killough 3/27/98
vis->renderflags = thing->renderflags;
if(thing->flags5 & MF5_BRIGHT) vis->renderflags |= RF_FULLBRIGHT; // kg3D
vis->RenderStyle = thing->RenderStyle;
vis->FillColor = thing->fillcolor;
vis->Translation = thing->Translation; // [RH] thing translation table
vis->FakeFlatStat = fakeside;
vis->alpha = thing->alpha;
vis->fakefloor = fakefloor;
vis->fakeceiling = fakeceiling;
if (voxel != NULL)
{
@ -2063,6 +2067,9 @@ void R_ProjectSprite (AActor *thing, int fakeside)
void R_AddSprites (sector_t *sec, int lightlevel, int fakeside)
{
AActor *thing;
F3DFloor *rover;
F3DFloor *fakeceiling = NULL;
F3DFloor *fakefloor = NULL;
// BSP is traversed by subsector.
// A sector might have been split into several
@ -2079,7 +2086,26 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside)
// Handle all things in sector.
for (thing = sec->thinglist; thing; thing = thing->snext)
{
R_ProjectSprite (thing, fakeside);
// find fake level
for(int i = 0; i < (int)frontsector->e->XFloor.ffloors.Size(); i++) {
rover = frontsector->e->XFloor.ffloors[i];
if(!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) continue;
if(!(rover->flags & FF_SOLID) || rover->alpha != 255) continue;
if(!fakefloor)
{
if(!(rover->top.plane->a) && !(rover->top.plane->b))
{
if(rover->top.plane->Zat0() <= thing->z) fakefloor = rover;
}
}
if(!(rover->bottom.plane->a) && !(rover->bottom.plane->b))
{
if(rover->bottom.plane->Zat0() >= thing->z + thing->height) fakeceiling = rover;
}
}
R_ProjectSprite (thing, fakeside, fakefloor, fakeceiling);
fakeceiling = NULL;
fakefloor = NULL;
}
}
@ -2307,32 +2333,55 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_
//
//==========================================================================
void R_DrawPlayerSprites (void)
void R_DrawPlayerSprites ()
{
int i;
int lightnum;
pspdef_t* psp;
sector_t* sec;
sector_t* sec = NULL;
static sector_t tempsec;
int floorlight, ceilinglight;
F3DFloor *rover;
if (!r_drawplayersprites ||
!camera->player ||
(players[consoleplayer].cheats & CF_CHASECAM))
return;
// This used to use camera->Sector but due to interpolation that can be incorrect
// when the interpolated viewpoint is in a different sector than the camera.
sec = R_FakeFlat (viewsector, &tempsec, &floorlight,
&ceilinglight, false);
if(fixedlightlev < 0 && viewsector->e && viewsector->e->XFloor.lightlist.Size()) {
for(i = viewsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
if(viewz <= viewsector->e->XFloor.lightlist[i].plane.Zat0()) {
rover = viewsector->e->XFloor.lightlist[i].caster;
if(rover) {
if(rover->flags & FF_DOUBLESHADOW && viewz <= rover->bottom.plane->Zat0())
break;
sec = rover->model;
if(rover->flags & FF_FADEWALLS)
basecolormap = sec->ColorMap;
else
basecolormap = viewsector->e->XFloor.lightlist[i].extra_colormap;
}
break;
}
if(!sec) {
sec = viewsector;
basecolormap = sec->ColorMap;
}
floorlight = ceilinglight = sec->lightlevel;
} else {
// This used to use camera->Sector but due to interpolation that can be incorrect
// when the interpolated viewpoint is in a different sector than the camera.
sec = R_FakeFlat (viewsector, &tempsec, &floorlight,
&ceilinglight, false);
// [RH] set basecolormap
basecolormap = sec->ColorMap;
}
// [RH] set foggy flag
foggy = (level.fadeto || sec->ColorMap->Fade || (level.flags & LEVEL_HASFADETABLE));
foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE));
r_actualextralight = foggy ? 0 : extralight << 4;
// [RH] set basecolormap
basecolormap = sec->ColorMap;
// get light level
lightnum = ((floorlight + ceilinglight) >> 1) + r_actualextralight;
spriteshade = LIGHT2SHADE(lightnum) - 24*FRACUNIT;
@ -2656,10 +2705,16 @@ void R_DrawSprite (vissprite_t *spr)
int r1, r2;
short topclip, botclip;
short *clip1, *clip2;
lighttable_t *colormap = spr->colormap;
F3DFloor *rover;
FDynamicColormap *mybasecolormap;
// [RH] Check for particles
if (!spr->bIsVoxel && spr->pic == NULL)
{
// kg3D - reject invisible parts
if ((fake3D & FAKE3D_CLIPBOTTOM) && spr->gz <= sclipBottom) return;
if ((fake3D & FAKE3D_CLIPTOP) && spr->gz >= sclipTop) return;
R_DrawParticle (spr);
return;
}
@ -2675,6 +2730,93 @@ void R_DrawSprite (vissprite_t *spr)
if (spr->sector == NULL)
return;
// kg3D - reject invisible parts
if ((fake3D & FAKE3D_CLIPBOTTOM) && spr->gzt <= sclipBottom) return;
if ((fake3D & FAKE3D_CLIPTOP) && spr->gzb >= sclipTop) return;
// kg3D - correct colors now
if (!fixedcolormap && fixedlightlev < 0 && spr->sector->e && spr->sector->e->XFloor.lightlist.Size())
{
if (!(fake3D & FAKE3D_CLIPTOP))
{
sclipTop = spr->sector->ceilingplane.ZatPoint(viewx, viewy);
}
sector_t *sec = NULL;
for (i = spr->sector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
{
if (sclipTop <= spr->sector->e->XFloor.lightlist[i].plane.Zat0())
{
rover = spr->sector->e->XFloor.lightlist[i].caster;
if (rover)
{
if (rover->flags & FF_DOUBLESHADOW && sclipTop <= rover->bottom.plane->Zat0())
{
break;
}
sec = rover->model;
if (rover->flags & FF_FADEWALLS)
{
mybasecolormap = sec->ColorMap;
}
else
{
mybasecolormap = spr->sector->e->XFloor.lightlist[i].extra_colormap;
}
}
break;
}
}
// found new values, recalculate
if (sec)
{
INTBOOL invertcolormap = (spr->RenderStyle.Flags & STYLEF_InvertOverlay);
if (spr->RenderStyle.Flags & STYLEF_InvertSource)
{
invertcolormap = !invertcolormap;
}
// Sprites that are added to the scene must fade to black.
if (spr->RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0)
{
mybasecolormap = GetSpecialLights(mybasecolormap->Color, 0, mybasecolormap->Desaturate);
}
if (spr->RenderStyle.Flags & STYLEF_FadeToBlack)
{
if (invertcolormap)
{ // Fade to white
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(255,255,255), mybasecolormap->Desaturate);
invertcolormap = false;
}
else
{ // Fade to black
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(0,0,0), mybasecolormap->Desaturate);
}
}
// get light level
if (invertcolormap)
{
mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate);
}
if (fixedlightlev >= 0)
{
spr->colormap = mybasecolormap->Maps + fixedlightlev;
}
else if (!foggy && (spr->renderflags & RF_FULLBRIGHT))
{ // full bright
spr->colormap = mybasecolormap->Maps;
}
else
{ // diminished light
spriteshade = LIGHT2SHADE(sec->lightlevel + r_actualextralight);
spr->colormap = mybasecolormap->Maps + (GETPALOOKUP (
(fixed_t)DivScale12 (r_SpriteVisibility, spr->depth), spriteshade) << COLORMAPSHIFT);
}
}
}
// [RH] Initialize the clipping arrays to their largest possible range
// instead of using a special "not clipped" value. This eliminates
// visual anomalies when looking down and should be faster, too.
@ -2752,6 +2894,50 @@ void R_DrawSprite (vissprite_t *spr)
}
}
if (fake3D & FAKE3D_CLIPBOTTOM)
{
if (!spr->bIsVoxel)
{
fixed_t h = sclipBottom;
if (spr->fakefloor)
{
fixed_t floorz = spr->fakefloor->top.plane->Zat0();
if (viewz > floorz && floorz == sclipBottom )
{
h = spr->fakefloor->bottom.plane->Zat0();
}
}
h = (centeryfrac - FixedMul(h-viewz, scale)) >> FRACBITS;
if (h < botclip)
{
botclip = MAX<short>(0, h);
}
}
hzb = MAX(hzb, sclipBottom);
}
if (fake3D & FAKE3D_CLIPTOP)
{
if (!spr->bIsVoxel)
{
fixed_t h = sclipTop;
if (spr->fakeceiling != NULL)
{
fixed_t ceilingz = spr->fakeceiling->bottom.plane->Zat0();
if (viewz < ceilingz && ceilingz == sclipTop)
{
h = spr->fakeceiling->top.plane->Zat0();
}
}
h = (centeryfrac - FixedMul (h-viewz, scale)) >> FRACBITS;
if (h > topclip)
{
topclip = MIN<short>(h, viewheight);
}
}
hzt = MIN(hzt, sclipTop);
}
#if 0
// [RH] Sprites that were split by a drawseg should also be clipped
// by the sector's floor and ceiling. (Not sure how/if to handle this
@ -2776,6 +2962,7 @@ void R_DrawSprite (vissprite_t *spr)
if (topclip >= botclip)
{
spr->colormap = colormap;
return;
}
@ -2799,6 +2986,8 @@ void R_DrawSprite (vissprite_t *spr)
for (ds = ds_p; ds-- > firstdrawseg; ) // new -- killough
{
// kg3D - no clipping on fake segs
if(ds->fake) continue;
// determine if the drawseg obscures the sprite
if (ds->x1 > x2 || ds->x2 < x1 ||
(!(ds->silhouette & SIL_BOTH) && ds->maskedtexturecol == -1 &&
@ -2887,6 +3076,7 @@ void R_DrawSprite (vissprite_t *spr)
}
if (i == x2)
{
spr->colormap = colormap;
return;
}
}
@ -2894,12 +3084,14 @@ void R_DrawSprite (vissprite_t *spr)
int maxvoxely = spr->gzb > hzb ? INT_MAX : (spr->gzt - hzb) / spr->yscale;
R_DrawVisVoxel(spr, minvoxely, maxvoxely, cliptop, clipbot);
}
spr->colormap = colormap;
}
//
// R_DrawMasked
//
void R_DrawMasked (void)
// kg3D:
// R_DrawMasked contains sorting
// original renamed to R_DrawMaskedSingle
void R_DrawMaskedSingle (bool renew)
{
drawseg_t *ds;
int i;
@ -2907,7 +3099,6 @@ void R_DrawMasked (void)
#if 0
R_SplitVisSprites ();
#endif
R_SortVisSprites (sv_compare, firstvissprite - vissprites);
for (i = vsprcount; i > 0; i--)
{
@ -2922,14 +3113,75 @@ void R_DrawMasked (void)
// for (ds=ds_p-1 ; ds >= drawsegs ; ds--) old buggy code
if (renew)
{
fake3D |= FAKE3D_REFRESHCLIP;
}
for (ds = ds_p; ds-- > firstdrawseg; ) // new -- killough
{
// kg3D - no fake segs
if (ds->fake) continue;
if (ds->maskedtexturecol != -1 || ds->bFogBoundary)
{
R_RenderMaskedSegRange (ds, ds->x1, ds->x2);
}
}
}
void R_DrawHeightPlanes(fixed_t height); // kg3D - fake planes
void R_DrawMasked (void)
{
R_SortVisSprites (sv_compare, firstvissprite - vissprites);
if (height_top == NULL)
{ // kg3D - no visible 3D floors, normal rendering
R_DrawMaskedSingle(false);
}
else
{ // kg3D - correct sorting
HeightLevel *hl;
// ceilings
for (hl = height_cur; hl != NULL && hl->height >= viewz; hl = hl->prev)
{
if (hl->next)
{
fake3D = FAKE3D_CLIPBOTTOM | FAKE3D_CLIPTOP;
sclipTop = hl->next->height;
}
else
{
fake3D = FAKE3D_CLIPBOTTOM;
}
sclipBottom = hl->height;
R_DrawMaskedSingle(true);
R_DrawHeightPlanes(hl->height);
}
// floors
fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPTOP;
sclipTop = height_top->height;
R_DrawMaskedSingle(true);
hl = height_top;
for (hl = height_top; hl != NULL && hl->height < viewz; hl = hl->next)
{
R_DrawHeightPlanes(hl->height);
if (hl->next)
{
fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPTOP | FAKE3D_CLIPBOTTOM;
sclipTop = hl->next->height;
}
else
{
fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPBOTTOM;
}
sclipBottom = hl->height;
R_DrawMaskedSingle(true);
}
R_3D_DeleteHeights();
fake3D = 0;
}
// draw the psprites on top of everything but does not draw on side views
if (!viewangleoffset)
{
@ -3150,6 +3402,7 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade,
vis->cx = tx;
vis->gx = particle->x;
vis->gy = particle->y;
vis->texturemid = particle->z; // kg3D
vis->gzb = y1;
vis->gzt = y2;
vis->x1 = x1;
@ -3161,7 +3414,6 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade,
vis->renderflags = particle->trans;
vis->FakeFlatStat = fakeside;
vis->floorclip = 0;
vis->heightsec = heightsec;
if (fixedlightlev >= 0)
{
@ -3190,6 +3442,8 @@ static void R_DrawMaskedSegsBehindParticle (const vissprite_t *vis)
for (unsigned int p = InterestingDrawsegs.Size(); p-- > FirstInterestingDrawseg; )
{
drawseg_t *ds = &drawsegs[InterestingDrawsegs[p]];
// kg3D - no fake segs
if(ds->fake) continue;
if (ds->x1 >= x2 || ds->x2 < x1)
{
continue;