UltimateZoneBuilder/Source/Native/VPO/r_plane.cpp
Magnus Norddahl 8eb522c873 Move vpo native code into BuilderNative as it is easier to manage. The plugins folder doesn't support including native dlls properly anyway.
Fix visplane explorer busy looping when waiting for data and reduce the used core count to 75% of the total available
Made vpo native code thread safe, removing the need for ungodly DLL patching hacks
2020-04-19 15:56:24 +02:00

306 lines
6 KiB
C++

// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright(C) 1993-1996 Id Software, Inc.
// Copyright(C) 2005 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
// DESCRIPTION:
// Here is a core component: drawing the floors and ceilings,
// while maintaining a per column clipping list only.
// Moreover, the sky areas have to be determined.
//
//-----------------------------------------------------------------------------
#include "Precomp.h"
#include "vpo_local.h"
namespace vpo
{
#if 0
//
// R_MapPlane
//
// Uses global vars:
// planeheight
// ds_source
// basexscale
// baseyscale
// viewx
// viewy
//
// BASIC PRIMITIVE
//
void R_MapPlane ( int y, int x1, int x2 )
{
angle_t angle;
fixed_t distance;
fixed_t length;
unsigned index;
#ifdef RANGECHECK
if (x2 < x1
|| x1 < 0
|| x2 >= viewwidth
|| y > viewheight)
{
I_Error ("R_MapPlane: %i, %i at %i",x1,x2,y);
}
#endif
if (planeheight != cachedheight[y])
{
cachedheight[y] = planeheight;
distance = cacheddistance[y] = FixedMul (planeheight, yslope[y]);
ds_xstep = cachedxstep[y] = FixedMul (distance,basexscale);
ds_ystep = cachedystep[y] = FixedMul (distance,baseyscale);
}
else
{
distance = cacheddistance[y];
ds_xstep = cachedxstep[y];
ds_ystep = cachedystep[y];
}
length = FixedMul (distance,distscale[x1]);
angle = (viewangle + xtoviewangle[x1])>>ANGLETOFINESHIFT;
ds_xfrac = viewx + FixedMul(finecosine[angle], length);
ds_yfrac = -viewy - FixedMul(finesine[angle], length);
if (fixedcolormap)
ds_colormap = fixedcolormap;
else
{
index = distance >> LIGHTZSHIFT;
if (index >= MAXLIGHTZ )
index = MAXLIGHTZ-1;
ds_colormap = planezlight[index];
}
ds_y = y;
ds_x1 = x1;
ds_x2 = x2;
// high or low detail
spanfunc ();
}
#endif
//
// R_ClearPlanes
// At begining of frame.
//
void Context::R_ClearPlanes (void)
{
int i;
angle_t angle;
// opening / clipping determination
for (i=0 ; i<viewwidth ; i++)
{
floorclip[i] = viewheight;
ceilingclip[i] = -1;
}
total_visplanes = 0;
total_openings = 0;
lastvisplane = visplanes;
lastopening = openings;
// texture calculation
memset (cachedheight, 0, sizeof(cachedheight));
// left to right mapping
angle = (viewangle-ANG90)>>ANGLETOFINESHIFT;
// scale will be unit scale at SCREENWIDTH/2 distance
basexscale = FixedDiv (finecosine[angle],centerxfrac);
baseyscale = -FixedDiv (finesine[angle],centerxfrac);
}
//
// R_FindPlane
//
visplane_t* Context::R_FindPlane ( fixed_t height, int picnum, int lightlevel )
{
visplane_t* check;
if (picnum == skyflatnum)
{
height = 0; // all skys map together
lightlevel = 0;
}
for (check=visplanes; check<lastvisplane; check++)
{
if (height == check->height
&& picnum == check->picnum
&& lightlevel == check->lightlevel)
{
break;
}
}
if (check < lastvisplane)
return check;
if (total_visplanes >= MAXVISPLANES)
throw overflow_exception(); // I_Error ("R_FindPlane: no more visplanes");
total_visplanes++;
lastvisplane++;
check->height = height;
check->picnum = picnum;
check->lightlevel = lightlevel;
check->minx = SCREENWIDTH;
check->maxx = -1;
memset (check->top,0xff,sizeof(check->top));
return check;
}
//
// R_CheckPlane
//
visplane_t* Context::R_CheckPlane ( visplane_t* pl, int start, int stop )
{
int intrl;
int intrh;
int unionl;
int unionh;
int x;
if (start < pl->minx)
{
intrl = pl->minx;
unionl = start;
}
else
{
unionl = pl->minx;
intrl = start;
}
if (stop > pl->maxx)
{
intrh = pl->maxx;
unionh = stop;
}
else
{
unionh = pl->maxx;
intrh = stop;
}
for (x=intrl ; x<= intrh ; x++)
if (pl->top[x] != 0xff)
break;
if (x > intrh)
{
pl->minx = unionl;
pl->maxx = unionh;
// use the same one
return pl;
}
// make a new visplane
lastvisplane->height = pl->height;
lastvisplane->picnum = pl->picnum;
lastvisplane->lightlevel = pl->lightlevel;
if (total_visplanes >= MAXVISPLANES)
throw overflow_exception(); // I_Error ("R_FindPlane: no more visplanes");
total_visplanes++;
pl = lastvisplane++;
pl->minx = start;
pl->maxx = stop;
memset (pl->top,0xff,sizeof(pl->top));
return pl;
}
#if 0
//
// R_MakeSpans
//
void R_MakeSpans ( int x, int t1, int b1, int t2, int b2 )
{
while (t1 < t2 && t1<=b1)
{
R_MapPlane (t1,spanstart[t1],x-1);
t1++;
}
while (b1 > b2 && b1>=t1)
{
R_MapPlane (b1,spanstart[b1],x-1);
b1--;
}
while (t2 < t1 && t2<=b2)
{
spanstart[t2] = x;
t2++;
}
while (b2 > b1 && b2>=t2)
{
spanstart[b2] = x;
b2--;
}
}
#endif
#if 0
was: R_DrawPlanes()
if (ds_p - drawsegs > MAXDRAWSEGS)
I_Error ("R_DrawPlanes: drawsegs overflow (%i)",
ds_p - drawsegs);
if (lastvisplane - visplanes > MAXVISPLANES)
I_Error ("R_DrawPlanes: visplane overflow (%i)",
lastvisplane - visplanes);
if (lastopening - openings > MAXOPENINGS)
I_Error ("R_DrawPlanes: opening overflow (%i)",
lastopening - openings);
#endif
} // namespace vpo