mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-14 16:41:07 +00:00
Added DrawerContext class
This commit is contained in:
parent
77c4786b9d
commit
312776621e
19 changed files with 1922 additions and 1291 deletions
|
@ -892,6 +892,7 @@ set( FASTMATH_PCH_SOURCES
|
||||||
r_swrenderer.cpp
|
r_swrenderer.cpp
|
||||||
r_3dfloors.cpp
|
r_3dfloors.cpp
|
||||||
r_bsp.cpp
|
r_bsp.cpp
|
||||||
|
r_drawer_context.cpp
|
||||||
r_draw.cpp
|
r_draw.cpp
|
||||||
r_draw_rgba.cpp
|
r_draw_rgba.cpp
|
||||||
r_drawt.cpp
|
r_drawt.cpp
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#include "r_local.h"
|
#include "r_local.h"
|
||||||
#include "r_main.h"
|
#include "r_main.h"
|
||||||
#include "r_plane.h"
|
#include "r_plane.h"
|
||||||
#include "r_draw.h"
|
#include "r_drawer_context.h"
|
||||||
#include "r_things.h"
|
#include "r_things.h"
|
||||||
#include "r_3dfloors.h"
|
#include "r_3dfloors.h"
|
||||||
#include "a_sharedglobal.h"
|
#include "a_sharedglobal.h"
|
||||||
|
@ -545,7 +545,7 @@ void R_AddLine (seg_t *line)
|
||||||
curline = line;
|
curline = line;
|
||||||
|
|
||||||
// [RH] Color if not texturing line
|
// [RH] Color if not texturing line
|
||||||
dc_color = (((int)(line - segs) * 8) + 4) & 255;
|
DrawerContext::SetFlatColor((((int)(line - segs) * 8) + 4) & 255);
|
||||||
|
|
||||||
pt1 = line->v1->fPos() - ViewPos;
|
pt1 = line->v1->fPos() - ViewPos;
|
||||||
pt2 = line->v2->fPos() - ViewPos;
|
pt2 = line->v2->fPos() - ViewPos;
|
||||||
|
|
798
src/r_draw.cpp
798
src/r_draw.cpp
|
@ -23,6 +23,8 @@
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define DRAWER_INTERNALS
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
|
@ -40,6 +42,8 @@
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
#include "r_plane.h"
|
#include "r_plane.h"
|
||||||
#include "r_draw_rgba.h"
|
#include "r_draw_rgba.h"
|
||||||
|
#include "r_drawer_context.h"
|
||||||
|
#include "d_net.h"
|
||||||
|
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
|
@ -66,6 +70,7 @@ int ylookup[MAXHEIGHT];
|
||||||
BYTE *dc_destorg;
|
BYTE *dc_destorg;
|
||||||
}
|
}
|
||||||
int scaledviewwidth;
|
int scaledviewwidth;
|
||||||
|
DCanvas *dc_canvas;
|
||||||
|
|
||||||
// [RH] Pointers to the different column drawers.
|
// [RH] Pointers to the different column drawers.
|
||||||
// These get changed depending on the current
|
// These get changed depending on the current
|
||||||
|
@ -97,9 +102,9 @@ void (*R_DrawSpanMaskedAddClamp)(void);
|
||||||
void (*R_FillSpan)(void);
|
void (*R_FillSpan)(void);
|
||||||
void (*R_FillColumnHoriz)(void);
|
void (*R_FillColumnHoriz)(void);
|
||||||
void (*R_DrawFogBoundary)(int x1, int x2, short *uclip, short *dclip);
|
void (*R_DrawFogBoundary)(int x1, int x2, short *uclip, short *dclip);
|
||||||
void (*R_MapTiltedPlane)(int y, int x1);
|
void (*R_DrawTiltedSpan)(int y, int x1, int x2);
|
||||||
void (*R_MapColoredPlane)(int y, int x1);
|
void (*R_DrawColoredSpan)(int y, int x1, int x2);
|
||||||
void (*R_DrawParticle)(vissprite_t *);
|
void (*R_FillTransColumn)(int x, int y1, int y2, int color, int alpha);
|
||||||
fixed_t (*tmvline1_add)();
|
fixed_t (*tmvline1_add)();
|
||||||
void (*tmvline4_add)();
|
void (*tmvline4_add)();
|
||||||
fixed_t (*tmvline1_addclamp)();
|
fixed_t (*tmvline1_addclamp)();
|
||||||
|
@ -134,6 +139,24 @@ void (*rt_tlatesubclamp4cols)(int sx, int yl, int yh);
|
||||||
void (*rt_tlaterevsubclamp4cols)(int sx, int yl, int yh);
|
void (*rt_tlaterevsubclamp4cols)(int sx, int yl, int yh);
|
||||||
void (*rt_initcols)(BYTE *buffer);
|
void (*rt_initcols)(BYTE *buffer);
|
||||||
void (*rt_span_coverage)(int x, int start, int stop);
|
void (*rt_span_coverage)(int x, int start, int stop);
|
||||||
|
void (*colfunc) (void);
|
||||||
|
void (*basecolfunc) (void);
|
||||||
|
void (*fuzzcolfunc) (void);
|
||||||
|
void (*transcolfunc) (void);
|
||||||
|
void (*spanfunc) (void);
|
||||||
|
void (*hcolfunc_pre) (void);
|
||||||
|
void (*hcolfunc_post1) (int hx, int sx, int yl, int yh);
|
||||||
|
void (*hcolfunc_post2) (int hx, int sx, int yl, int yh);
|
||||||
|
void (*hcolfunc_post4) (int sx, int yl, int yh);
|
||||||
|
|
||||||
|
extern "C" void R_DrawTiltedPlane_ASM(int y, int x1);
|
||||||
|
#ifdef X86_ASM
|
||||||
|
extern "C" void R_SetSpanSource_ASM(const BYTE *flat);
|
||||||
|
extern "C" void R_SetSpanSize_ASM(int xbits, int ybits);
|
||||||
|
extern "C" void R_SetSpanColormap_ASM(BYTE *colormap);
|
||||||
|
extern "C" void R_SetTiltedSpanSource_ASM(const BYTE *flat);
|
||||||
|
extern "C" BYTE *ds_curcolormap, *ds_cursource, *ds_curtiltedsource;
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_DrawColumn
|
// R_DrawColumn
|
||||||
|
@ -1040,13 +1063,6 @@ const BYTE* ds_source;
|
||||||
|
|
||||||
// just for profiling
|
// just for profiling
|
||||||
int dscount;
|
int dscount;
|
||||||
|
|
||||||
#ifdef X86_ASM
|
|
||||||
extern "C" void R_SetSpanSource_ASM (const BYTE *flat);
|
|
||||||
extern "C" void R_SetSpanSize_ASM (int xbits, int ybits);
|
|
||||||
extern "C" void R_SetSpanColormap_ASM (BYTE *colormap);
|
|
||||||
extern "C" BYTE *ds_curcolormap, *ds_cursource, *ds_curtiltedsource;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1076,9 +1092,8 @@ void R_SetSpanSource(const BYTE *pixels)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void R_SetSpanColormap(FDynamicColormap *colormap, int shade)
|
void R_SetSpanColormap()
|
||||||
{
|
{
|
||||||
R_SetDSColorMapLight(colormap, 0, shade);
|
|
||||||
#ifdef X86_ASM
|
#ifdef X86_ASM
|
||||||
if (!r_swtruecolor && ds_colormap != ds_curcolormap)
|
if (!r_swtruecolor && ds_colormap != ds_curcolormap)
|
||||||
{
|
{
|
||||||
|
@ -2297,9 +2312,9 @@ void R_InitColumnDrawers ()
|
||||||
R_FillColumnHoriz = R_FillColumnHoriz_rgba;
|
R_FillColumnHoriz = R_FillColumnHoriz_rgba;
|
||||||
|
|
||||||
R_DrawFogBoundary = R_DrawFogBoundary_rgba;
|
R_DrawFogBoundary = R_DrawFogBoundary_rgba;
|
||||||
R_MapTiltedPlane = R_MapTiltedPlane_rgba;
|
R_DrawTiltedSpan = R_DrawTiltedSpan_rgba;
|
||||||
R_MapColoredPlane = R_MapColoredPlane_rgba;
|
R_DrawColoredSpan = R_DrawColoredSpan_rgba;
|
||||||
R_DrawParticle = R_DrawParticle_rgba;
|
R_FillTransColumn = R_FillTransColumn_rgba;
|
||||||
|
|
||||||
tmvline1_add = tmvline1_add_rgba;
|
tmvline1_add = tmvline1_add_rgba;
|
||||||
tmvline4_add = tmvline4_add_rgba;
|
tmvline4_add = tmvline4_add_rgba;
|
||||||
|
@ -2394,9 +2409,15 @@ void R_InitColumnDrawers ()
|
||||||
R_FillColumnHoriz = R_FillColumnHorizP_C;
|
R_FillColumnHoriz = R_FillColumnHorizP_C;
|
||||||
|
|
||||||
R_DrawFogBoundary = R_DrawFogBoundary_C;
|
R_DrawFogBoundary = R_DrawFogBoundary_C;
|
||||||
R_MapTiltedPlane = R_MapTiltedPlane_C;
|
R_DrawColoredSpan = R_DrawColoredSpan_C;
|
||||||
R_MapColoredPlane = R_MapColoredPlane_C;
|
R_FillTransColumn = R_FillTransColumn_C;
|
||||||
R_DrawParticle = R_DrawParticle_C;
|
|
||||||
|
#ifdef X86_ASM
|
||||||
|
// To do: update R_DrawTiltedPlane_ASM to use x2 rather than spanend[y]
|
||||||
|
R_DrawTiltedSpan = [](int y, int x1, int x2) { R_DrawTiltedPlane_ASM(y, x1); };
|
||||||
|
#else
|
||||||
|
R_DrawTiltedSpan = R_DrawTiltedSpan_C;
|
||||||
|
#endif
|
||||||
|
|
||||||
tmvline1_add = tmvline1_add_C;
|
tmvline1_add = tmvline1_add_C;
|
||||||
tmvline4_add = tmvline4_add_C;
|
tmvline4_add = tmvline4_add_C;
|
||||||
|
@ -2829,3 +2850,744 @@ void R_SetDSColorMapLight(FColormap *base_colormap, float light, int shade)
|
||||||
ds_colormap = base_colormap->Maps + (GETPALOOKUP(light, shade) << COLORMAPSHIFT);
|
ds_colormap = base_colormap->Maps + (GETPALOOKUP(light, shade) << COLORMAPSHIFT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
FVector3 ds_plane_sz, ds_plane_su, ds_plane_sv;
|
||||||
|
bool ds_plane_shade;
|
||||||
|
float ds_planelightfloat;
|
||||||
|
fixed_t ds_pviewx, ds_pviewy;
|
||||||
|
int ds_planeshade;
|
||||||
|
extern "C" BYTE *tiltlighting[MAXWIDTH];
|
||||||
|
|
||||||
|
extern "C" { void R_CalcTiltedLighting(double lval, double lend, int width); }
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(disable:4244) // warning C4244: conversion from 'SQWORD' to 'DWORD', possible loss of data
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// R_CalcTiltedLighting
|
||||||
|
//
|
||||||
|
// Calculates the lighting for one row of a tilted plane. If the definition
|
||||||
|
// of GETPALOOKUP changes, this needs to change, too.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void R_CalcTiltedLighting (double lval, double lend, int width)
|
||||||
|
{
|
||||||
|
double lstep;
|
||||||
|
BYTE *lightfiller;
|
||||||
|
BYTE *basecolormapdata = ds_fcolormap->Maps;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (width == 0 || lval == lend)
|
||||||
|
{ // Constant lighting
|
||||||
|
lightfiller = basecolormapdata + (GETPALOOKUP(lval, ds_planeshade) << COLORMAPSHIFT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lstep = (lend - lval) / width;
|
||||||
|
if (lval >= MAXLIGHTVIS)
|
||||||
|
{ // lval starts "too bright".
|
||||||
|
lightfiller = basecolormapdata + (GETPALOOKUP(lval, ds_planeshade) << COLORMAPSHIFT);
|
||||||
|
for (; i <= width && lval >= MAXLIGHTVIS; ++i)
|
||||||
|
{
|
||||||
|
tiltlighting[i] = lightfiller;
|
||||||
|
lval += lstep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lend >= MAXLIGHTVIS)
|
||||||
|
{ // lend ends "too bright".
|
||||||
|
lightfiller = basecolormapdata + (GETPALOOKUP(lend, ds_planeshade) << COLORMAPSHIFT);
|
||||||
|
for (; width > i && lend >= MAXLIGHTVIS; --width)
|
||||||
|
{
|
||||||
|
tiltlighting[width] = lightfiller;
|
||||||
|
lend -= lstep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (width > 0)
|
||||||
|
{
|
||||||
|
lval = FIXED2DBL(ds_planeshade) - lval;
|
||||||
|
lend = FIXED2DBL(ds_planeshade) - lend;
|
||||||
|
lstep = (lend - lval) / width;
|
||||||
|
if (lstep < 0)
|
||||||
|
{ // Going from dark to light
|
||||||
|
if (lval < 1.)
|
||||||
|
{ // All bright
|
||||||
|
lightfiller = basecolormapdata;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (lval >= NUMCOLORMAPS)
|
||||||
|
{ // Starts beyond the dark end
|
||||||
|
BYTE *clight = basecolormapdata + ((NUMCOLORMAPS-1) << COLORMAPSHIFT);
|
||||||
|
while (lval >= NUMCOLORMAPS && i <= width)
|
||||||
|
{
|
||||||
|
tiltlighting[i++] = clight;
|
||||||
|
lval += lstep;
|
||||||
|
}
|
||||||
|
if (i > width)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (i <= width && lval >= 0)
|
||||||
|
{
|
||||||
|
tiltlighting[i++] = basecolormapdata + (xs_ToInt(lval) << COLORMAPSHIFT);
|
||||||
|
lval += lstep;
|
||||||
|
}
|
||||||
|
lightfiller = basecolormapdata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Going from light to dark
|
||||||
|
if (lval >= (NUMCOLORMAPS-1))
|
||||||
|
{ // All dark
|
||||||
|
lightfiller = basecolormapdata + ((NUMCOLORMAPS-1) << COLORMAPSHIFT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (lval < 0 && i <= width)
|
||||||
|
{
|
||||||
|
tiltlighting[i++] = basecolormapdata;
|
||||||
|
lval += lstep;
|
||||||
|
}
|
||||||
|
if (i > width)
|
||||||
|
return;
|
||||||
|
while (i <= width && lval < (NUMCOLORMAPS-1))
|
||||||
|
{
|
||||||
|
tiltlighting[i++] = basecolormapdata + (xs_ToInt(lval) << COLORMAPSHIFT);
|
||||||
|
lval += lstep;
|
||||||
|
}
|
||||||
|
lightfiller = basecolormapdata + ((NUMCOLORMAPS-1) << COLORMAPSHIFT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (; i <= width; i++)
|
||||||
|
{
|
||||||
|
tiltlighting[i] = lightfiller;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
void R_DrawTiltedSpan_C (int y, int x1, int x2)
|
||||||
|
{
|
||||||
|
int width = x2 - x1;
|
||||||
|
double iz, uz, vz;
|
||||||
|
BYTE *fb;
|
||||||
|
DWORD u, v;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
iz = ds_plane_sz[2] + ds_plane_sz[1]*(centery-y) + ds_plane_sz[0]*(x1-centerx);
|
||||||
|
|
||||||
|
// Lighting is simple. It's just linear interpolation from start to end
|
||||||
|
if (ds_plane_shade)
|
||||||
|
{
|
||||||
|
uz = (iz + ds_plane_sz[0]*width) * ds_planelightfloat;
|
||||||
|
vz = iz * ds_planelightfloat;
|
||||||
|
R_CalcTiltedLighting (vz, uz, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
uz = ds_plane_su[2] + ds_plane_su[1]*(centery-y) + ds_plane_su[0]*(x1-centerx);
|
||||||
|
vz = ds_plane_sv[2] + ds_plane_sv[1]*(centery-y) + ds_plane_sv[0]*(x1-centerx);
|
||||||
|
|
||||||
|
fb = ylookup[y] + x1 + dc_destorg;
|
||||||
|
|
||||||
|
BYTE vshift = 32 - ds_ybits;
|
||||||
|
BYTE ushift = vshift - ds_xbits;
|
||||||
|
int umask = ((1 << ds_xbits) - 1) << ds_ybits;
|
||||||
|
|
||||||
|
#if 0 // The "perfect" reference version of this routine. Pretty slow.
|
||||||
|
// Use it only to see how things are supposed to look.
|
||||||
|
i = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
double z = 1.f/iz;
|
||||||
|
|
||||||
|
u = SQWORD(uz*z) + ds_pviewx;
|
||||||
|
v = SQWORD(vz*z) + ds_pviewy;
|
||||||
|
R_SetDSColorMapLight(tiltlighting[i], 0, 0);
|
||||||
|
fb[i++] = ds_colormap[ds_source[(v >> vshift) | ((u >> ushift) & umask)]];
|
||||||
|
iz += ds_plane_sz[0];
|
||||||
|
uz += ds_plane_su[0];
|
||||||
|
vz += ds_plane_sv[0];
|
||||||
|
} while (--width >= 0);
|
||||||
|
#else
|
||||||
|
//#define SPANSIZE 32
|
||||||
|
//#define INVSPAN 0.03125f
|
||||||
|
//#define SPANSIZE 8
|
||||||
|
//#define INVSPAN 0.125f
|
||||||
|
#define SPANSIZE 16
|
||||||
|
#define INVSPAN 0.0625f
|
||||||
|
|
||||||
|
double startz = 1.f/iz;
|
||||||
|
double startu = uz*startz;
|
||||||
|
double startv = vz*startz;
|
||||||
|
double izstep, uzstep, vzstep;
|
||||||
|
|
||||||
|
izstep = ds_plane_sz[0] * SPANSIZE;
|
||||||
|
uzstep = ds_plane_su[0] * SPANSIZE;
|
||||||
|
vzstep = ds_plane_sv[0] * SPANSIZE;
|
||||||
|
x1 = 0;
|
||||||
|
width++;
|
||||||
|
|
||||||
|
while (width >= SPANSIZE)
|
||||||
|
{
|
||||||
|
iz += izstep;
|
||||||
|
uz += uzstep;
|
||||||
|
vz += vzstep;
|
||||||
|
|
||||||
|
double endz = 1.f/iz;
|
||||||
|
double endu = uz*endz;
|
||||||
|
double endv = vz*endz;
|
||||||
|
DWORD stepu = SQWORD((endu - startu) * INVSPAN);
|
||||||
|
DWORD stepv = SQWORD((endv - startv) * INVSPAN);
|
||||||
|
u = SQWORD(startu) + ds_pviewx;
|
||||||
|
v = SQWORD(startv) + ds_pviewy;
|
||||||
|
|
||||||
|
for (i = SPANSIZE-1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
fb[x1] = *(tiltlighting[x1] + ds_source[(v >> vshift) | ((u >> ushift) & umask)]);
|
||||||
|
x1++;
|
||||||
|
u += stepu;
|
||||||
|
v += stepv;
|
||||||
|
}
|
||||||
|
startu = endu;
|
||||||
|
startv = endv;
|
||||||
|
width -= SPANSIZE;
|
||||||
|
}
|
||||||
|
if (width > 0)
|
||||||
|
{
|
||||||
|
if (width == 1)
|
||||||
|
{
|
||||||
|
u = SQWORD(startu);
|
||||||
|
v = SQWORD(startv);
|
||||||
|
fb[x1] = *(tiltlighting[x1] + ds_source[(v >> vshift) | ((u >> ushift) & umask)]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double left = width;
|
||||||
|
iz += ds_plane_sz[0] * left;
|
||||||
|
uz += ds_plane_su[0] * left;
|
||||||
|
vz += ds_plane_sv[0] * left;
|
||||||
|
|
||||||
|
double endz = 1.f/iz;
|
||||||
|
double endu = uz*endz;
|
||||||
|
double endv = vz*endz;
|
||||||
|
left = 1.f/left;
|
||||||
|
DWORD stepu = SQWORD((endu - startu) * left);
|
||||||
|
DWORD stepv = SQWORD((endv - startv) * left);
|
||||||
|
u = SQWORD(startu) + ds_pviewx;
|
||||||
|
v = SQWORD(startv) + ds_pviewy;
|
||||||
|
|
||||||
|
for (; width != 0; width--)
|
||||||
|
{
|
||||||
|
fb[x1] = *(tiltlighting[x1] + ds_source[(v >> vshift) | ((u >> ushift) & umask)]);
|
||||||
|
x1++;
|
||||||
|
u += stepu;
|
||||||
|
v += stepv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_DrawColoredSpan_C (int y, int x1, int x2)
|
||||||
|
{
|
||||||
|
memset (ylookup[y] + x1 + dc_destorg, ds_color, x2 - x1 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Draw a column with support for non-power-of-two ranges
|
||||||
|
uint32_t wallscan_drawcol1(int x, int y1, int y2, uint32_t uv_start, uint32_t uv_step, uint32_t uv_max, const BYTE *source, DWORD(*draw1column)())
|
||||||
|
{
|
||||||
|
int pixelsize = r_swtruecolor ? 4 : 1;
|
||||||
|
if (uv_max == 0) // power of two
|
||||||
|
{
|
||||||
|
int count = y2 - y1;
|
||||||
|
|
||||||
|
dc_source = source;
|
||||||
|
dc_dest = (ylookup[y1] + x) * pixelsize + dc_destorg;
|
||||||
|
dc_count = count;
|
||||||
|
dc_iscale = uv_step;
|
||||||
|
dc_texturefrac = uv_start;
|
||||||
|
draw1column();
|
||||||
|
|
||||||
|
uint64_t step64 = uv_step;
|
||||||
|
uint64_t pos64 = uv_start;
|
||||||
|
return (uint32_t)(pos64 + step64 * count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32_t uv_pos = uv_start;
|
||||||
|
|
||||||
|
uint32_t left = y2 - y1;
|
||||||
|
while (left > 0)
|
||||||
|
{
|
||||||
|
uint32_t available = uv_max - uv_pos;
|
||||||
|
uint32_t next_uv_wrap = available / uv_step;
|
||||||
|
if (available % uv_step != 0)
|
||||||
|
next_uv_wrap++;
|
||||||
|
uint32_t count = MIN(left, next_uv_wrap);
|
||||||
|
|
||||||
|
dc_source = source;
|
||||||
|
dc_dest = (ylookup[y1] + x) * pixelsize + dc_destorg;
|
||||||
|
dc_count = count;
|
||||||
|
dc_iscale = uv_step;
|
||||||
|
dc_texturefrac = uv_pos;
|
||||||
|
draw1column();
|
||||||
|
|
||||||
|
left -= count;
|
||||||
|
uv_pos += uv_step * count;
|
||||||
|
if (uv_pos >= uv_max)
|
||||||
|
uv_pos -= uv_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uv_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw four columns with support for non-power-of-two ranges
|
||||||
|
void wallscan_drawcol4(int x, int y1, int y2, uint32_t *uv_pos, uint32_t *uv_step, uint32_t uv_max, const BYTE **source, void(*draw4columns)())
|
||||||
|
{
|
||||||
|
int pixelsize = r_swtruecolor ? 4 : 1;
|
||||||
|
if (uv_max == 0) // power of two, no wrap handling needed
|
||||||
|
{
|
||||||
|
int count = y2 - y1;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
bufplce[i] = source[i];
|
||||||
|
vplce[i] = uv_pos[i];
|
||||||
|
vince[i] = uv_step[i];
|
||||||
|
|
||||||
|
uint64_t step64 = uv_step[i];
|
||||||
|
uint64_t pos64 = uv_pos[i];
|
||||||
|
uv_pos[i] = (uint32_t)(pos64 + step64 * count);
|
||||||
|
}
|
||||||
|
dc_dest = (ylookup[y1] + x) * pixelsize + dc_destorg;
|
||||||
|
dc_count = count;
|
||||||
|
draw4columns();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dc_dest = (ylookup[y1] + x) * pixelsize + dc_destorg;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
bufplce[i] = source[i];
|
||||||
|
|
||||||
|
uint32_t left = y2 - y1;
|
||||||
|
while (left > 0)
|
||||||
|
{
|
||||||
|
// Find which column wraps first
|
||||||
|
uint32_t count = left;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
uint32_t available = uv_max - uv_pos[i];
|
||||||
|
uint32_t next_uv_wrap = available / uv_step[i];
|
||||||
|
if (available % uv_step[i] != 0)
|
||||||
|
next_uv_wrap++;
|
||||||
|
count = MIN(next_uv_wrap, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw until that column wraps
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
vplce[i] = uv_pos[i];
|
||||||
|
vince[i] = uv_step[i];
|
||||||
|
}
|
||||||
|
dc_count = count;
|
||||||
|
draw4columns();
|
||||||
|
|
||||||
|
// Wrap the uv position
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
uv_pos[i] += uv_step[i] * count;
|
||||||
|
if (uv_pos[i] >= uv_max)
|
||||||
|
uv_pos[i] -= uv_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
left -= count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculates a wrapped uv start position value for a column
|
||||||
|
void calc_uv_start_and_step(int y1, float swal, double yrepeat, uint32_t uv_height, int fracbits, uint32_t &uv_start_out, uint32_t &uv_step_out)
|
||||||
|
{
|
||||||
|
double uv_stepd = swal * yrepeat;
|
||||||
|
|
||||||
|
// Find start uv in [0-uv_height[ range.
|
||||||
|
// Not using xs_ToFixed because it rounds the result and we need something that always rounds down to stay within the range.
|
||||||
|
double v = (dc_texturemid + uv_stepd * (y1 - CenterY + 0.5)) / uv_height;
|
||||||
|
v = v - floor(v);
|
||||||
|
v *= uv_height;
|
||||||
|
v *= (1 << fracbits);
|
||||||
|
|
||||||
|
uv_start_out = (uint32_t)v;
|
||||||
|
uv_step_out = xs_ToFixed(fracbits, uv_stepd);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef DWORD(*Draw1ColumnFuncPtr)();
|
||||||
|
typedef void(*Draw4ColumnsFuncPtr)();
|
||||||
|
|
||||||
|
void wallscan_any(
|
||||||
|
int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat,
|
||||||
|
FTexture *rw_pic, fixed_t rw_offset, const BYTE *(*getcol)(FTexture *tex, int x),
|
||||||
|
void(setupwallscan(int bits, Draw1ColumnFuncPtr &draw1, Draw4ColumnsFuncPtr &draw2)))
|
||||||
|
{
|
||||||
|
if (rw_pic->UseType == FTexture::TEX_Null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32_t uv_height = rw_pic->GetHeight();
|
||||||
|
uint32_t fracbits = 32 - rw_pic->HeightBits;
|
||||||
|
uint32_t uv_max = uv_height << fracbits;
|
||||||
|
|
||||||
|
DWORD(*draw1column)();
|
||||||
|
void(*draw4columns)();
|
||||||
|
setupwallscan(fracbits, draw1column, draw4columns);
|
||||||
|
|
||||||
|
fixed_t xoffset = rw_offset;
|
||||||
|
|
||||||
|
bool fixed = (fixedcolormap != NULL || fixedlightlev >= 0);
|
||||||
|
if (fixed)
|
||||||
|
{
|
||||||
|
palookupoffse[0] = dc_colormap;
|
||||||
|
palookupoffse[1] = dc_colormap;
|
||||||
|
palookupoffse[2] = dc_colormap;
|
||||||
|
palookupoffse[3] = dc_colormap;
|
||||||
|
palookuplight[0] = 0;
|
||||||
|
palookuplight[1] = 0;
|
||||||
|
palookuplight[2] = 0;
|
||||||
|
palookuplight[3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fixedcolormap)
|
||||||
|
R_SetColorMapLight(fixedcolormap, 0, 0);
|
||||||
|
else
|
||||||
|
R_SetColorMapLight(basecolormap, 0, 0);
|
||||||
|
|
||||||
|
float light = rw_light;
|
||||||
|
|
||||||
|
// Calculate where 4 column alignment begins and ends:
|
||||||
|
int aligned_x1 = clamp((x1 + 3) / 4 * 4, x1, x2);
|
||||||
|
int aligned_x2 = clamp(x2 / 4 * 4, x1, x2);
|
||||||
|
|
||||||
|
// First unaligned columns:
|
||||||
|
for (int x = x1; x < aligned_x1; x++, light += rw_lightstep)
|
||||||
|
{
|
||||||
|
int y1 = uwal[x];
|
||||||
|
int y2 = dwal[x];
|
||||||
|
if (y2 <= y1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!fixed)
|
||||||
|
R_SetColorMapLight(basecolormap, light, wallshade);
|
||||||
|
|
||||||
|
const BYTE *source = getcol(rw_pic, (lwal[x] + xoffset) >> FRACBITS);
|
||||||
|
|
||||||
|
uint32_t uv_start, uv_step;
|
||||||
|
calc_uv_start_and_step(y1, swal[x], yrepeat, uv_height, fracbits, uv_start, uv_step);
|
||||||
|
|
||||||
|
wallscan_drawcol1(x, y1, y2, uv_start, uv_step, uv_max, source, draw1column);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The aligned columns
|
||||||
|
for (int x = aligned_x1; x < aligned_x2; x += 4)
|
||||||
|
{
|
||||||
|
// Find y1, y2, light and uv values for four columns:
|
||||||
|
int y1[4] = { uwal[x], uwal[x + 1], uwal[x + 2], uwal[x + 3] };
|
||||||
|
int y2[4] = { dwal[x], dwal[x + 1], dwal[x + 2], dwal[x + 3] };
|
||||||
|
|
||||||
|
const BYTE *source[4];
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
source[i] = getcol(rw_pic, (lwal[x + i] + xoffset) >> FRACBITS);
|
||||||
|
|
||||||
|
float lights[4];
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
lights[i] = light;
|
||||||
|
light += rw_lightstep;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t uv_pos[4], uv_step[4];
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
calc_uv_start_and_step(y1[i], swal[x + i], yrepeat, uv_height, fracbits, uv_pos[i], uv_step[i]);
|
||||||
|
|
||||||
|
// Figure out where we vertically can start and stop drawing 4 columns in one go
|
||||||
|
int middle_y1 = y1[0];
|
||||||
|
int middle_y2 = y2[0];
|
||||||
|
for (int i = 1; i < 4; i++)
|
||||||
|
{
|
||||||
|
middle_y1 = MAX(y1[i], middle_y1);
|
||||||
|
middle_y2 = MIN(y2[i], middle_y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got an empty column in our set we cannot draw 4 columns in one go:
|
||||||
|
bool empty_column_in_set = false;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (y2[i] <= y1[i])
|
||||||
|
empty_column_in_set = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty_column_in_set || middle_y2 <= middle_y1)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (y2[i] <= y1[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!fixed)
|
||||||
|
R_SetColorMapLight(basecolormap, lights[i], wallshade);
|
||||||
|
wallscan_drawcol1(x + i, y1[i], y2[i], uv_pos[i], uv_step[i], uv_max, source[i], draw1column);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the first rows where not all 4 columns are active
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (!fixed)
|
||||||
|
R_SetColorMapLight(basecolormap, lights[i], wallshade);
|
||||||
|
|
||||||
|
if (y1[i] < middle_y1)
|
||||||
|
uv_pos[i] = wallscan_drawcol1(x + i, y1[i], middle_y1, uv_pos[i], uv_step[i], uv_max, source[i], draw1column);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the area where all 4 columns are active
|
||||||
|
if (!fixed)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (r_swtruecolor)
|
||||||
|
{
|
||||||
|
palookupoffse[i] = basecolormap->Maps;
|
||||||
|
palookuplight[i] = LIGHTSCALE(lights[i], wallshade);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
palookupoffse[i] = basecolormap->Maps + (GETPALOOKUP(lights[i], wallshade) << COLORMAPSHIFT);
|
||||||
|
palookuplight[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wallscan_drawcol4(x, middle_y1, middle_y2, uv_pos, uv_step, uv_max, source, draw4columns);
|
||||||
|
|
||||||
|
// Draw the last rows where not all 4 columns are active
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (!fixed)
|
||||||
|
R_SetColorMapLight(basecolormap, lights[i], wallshade);
|
||||||
|
|
||||||
|
if (middle_y2 < y2[i])
|
||||||
|
uv_pos[i] = wallscan_drawcol1(x + i, middle_y2, y2[i], uv_pos[i], uv_step[i], uv_max, source[i], draw1column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The last unaligned columns:
|
||||||
|
for (int x = aligned_x2; x < x2; x++, light += rw_lightstep)
|
||||||
|
{
|
||||||
|
int y1 = uwal[x];
|
||||||
|
int y2 = dwal[x];
|
||||||
|
if (y2 <= y1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!fixed)
|
||||||
|
R_SetColorMapLight(basecolormap, light, wallshade);
|
||||||
|
|
||||||
|
const BYTE *source = getcol(rw_pic, (lwal[x] + xoffset) >> FRACBITS);
|
||||||
|
|
||||||
|
uint32_t uv_start, uv_step;
|
||||||
|
calc_uv_start_and_step(y1, swal[x], yrepeat, uv_height, fracbits, uv_start, uv_step);
|
||||||
|
|
||||||
|
wallscan_drawcol1(x, y1, y2, uv_start, uv_step, uv_max, source, draw1column);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, FTexture *rw_pic, fixed_t rw_offset, const BYTE *(*getcol)(FTexture *tex, int x))
|
||||||
|
{
|
||||||
|
wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, rw_pic, rw_offset, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4)
|
||||||
|
{
|
||||||
|
setupvline(bits);
|
||||||
|
line1 = dovline1;
|
||||||
|
line4 = dovline4;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void maskwallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, FTexture *rw_pic, fixed_t rw_offset, const BYTE *(*getcol)(FTexture *tex, int x))
|
||||||
|
{
|
||||||
|
if (!rw_pic->bMasked) // Textures that aren't masked can use the faster wallscan.
|
||||||
|
{
|
||||||
|
wallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, rw_pic, rw_offset, getcol);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, rw_pic, rw_offset, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4)
|
||||||
|
{
|
||||||
|
setupmvline(bits);
|
||||||
|
line1 = domvline1;
|
||||||
|
line4 = domvline4;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void transmaskwallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, FTexture *rw_pic, fixed_t rw_offset, const BYTE *(*getcol)(FTexture *tex, int x))
|
||||||
|
{
|
||||||
|
static fixed_t(*tmvline1)();
|
||||||
|
static void(*tmvline4)();
|
||||||
|
if (!R_GetTransMaskDrawers(&tmvline1, &tmvline4))
|
||||||
|
{
|
||||||
|
// The current translucency is unsupported, so draw with regular maskwallscan instead.
|
||||||
|
maskwallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, rw_pic, rw_offset, getcol);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, rw_pic, rw_offset, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4)
|
||||||
|
{
|
||||||
|
setuptmvline(bits);
|
||||||
|
line1 = reinterpret_cast<DWORD(*)()>(tmvline1);
|
||||||
|
line4 = tmvline4;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void R_FillTransColumn_C(int x, int y1, int y2, int color, int alpha)
|
||||||
|
{
|
||||||
|
fixed_t fglevel, bglevel;
|
||||||
|
DWORD *fg2rgb;
|
||||||
|
DWORD *bg2rgb;
|
||||||
|
int spacing;
|
||||||
|
BYTE *dest;
|
||||||
|
DWORD fg;
|
||||||
|
|
||||||
|
fglevel = ((alpha + 1) << 8) & ~0x3ff;
|
||||||
|
bglevel = FRACUNIT - fglevel;
|
||||||
|
fg2rgb = Col2RGB8[fglevel >> 10];
|
||||||
|
bg2rgb = Col2RGB8[bglevel >> 10];
|
||||||
|
fg = fg2rgb[color];
|
||||||
|
|
||||||
|
spacing = dc_pitch;
|
||||||
|
|
||||||
|
int ycount = y2 - y1 + 1;
|
||||||
|
dest = ylookup[y1] + x + dc_destorg;
|
||||||
|
for (int y = 0; y < ycount; y++)
|
||||||
|
{
|
||||||
|
DWORD bg = bg2rgb[*dest];
|
||||||
|
bg = (fg + bg) | 0x1f07c1f;
|
||||||
|
*dest = RGB32k.All[bg & (bg >> 15)];
|
||||||
|
dest += spacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//
|
||||||
|
// R_DrawMaskedColumn
|
||||||
|
// Used for sprites and masked mid textures.
|
||||||
|
// Masked means: partly transparent, i.e. stored
|
||||||
|
// in posts/runs of opaque pixels.
|
||||||
|
//
|
||||||
|
short* dc_mfloorclip;
|
||||||
|
short* dc_mceilingclip;
|
||||||
|
|
||||||
|
double dc_spryscale;
|
||||||
|
double dc_sprtopscreen;
|
||||||
|
|
||||||
|
bool dc_sprflipvert;
|
||||||
|
|
||||||
|
void R_DrawMaskedColumn(int x, const BYTE *column, const FTexture::Span *span)
|
||||||
|
{
|
||||||
|
int pixelsize = r_swtruecolor ? 4 : 1;
|
||||||
|
const fixed_t centeryfrac = FLOAT2FIXED(CenterY);
|
||||||
|
const fixed_t texturemid = FLOAT2FIXED(dc_texturemid);
|
||||||
|
while (span->Length != 0)
|
||||||
|
{
|
||||||
|
const int length = span->Length;
|
||||||
|
const int top = span->TopOffset;
|
||||||
|
|
||||||
|
fixed_t texturefrac = dc_texturefrac;
|
||||||
|
fixed_t iscale = dc_iscale;
|
||||||
|
|
||||||
|
// calculate unclipped screen coordinates for post
|
||||||
|
int yl = xs_RoundToInt(dc_sprtopscreen + dc_spryscale * top);
|
||||||
|
int yh = xs_RoundToInt(dc_sprtopscreen + dc_spryscale * (top + length)) - 1;
|
||||||
|
|
||||||
|
if (dc_sprflipvert)
|
||||||
|
{
|
||||||
|
swapvalues(yl, yh);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yh >= dc_mfloorclip[x])
|
||||||
|
{
|
||||||
|
yh = dc_mfloorclip[x] - 1;
|
||||||
|
}
|
||||||
|
if (yl < dc_mceilingclip[x])
|
||||||
|
{
|
||||||
|
yl = dc_mceilingclip[x];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yl <= yh)
|
||||||
|
{
|
||||||
|
if (dc_sprflipvert)
|
||||||
|
{
|
||||||
|
texturefrac = (yl*iscale) - (top << FRACBITS)
|
||||||
|
- FixedMul(centeryfrac, iscale) - texturemid;
|
||||||
|
const fixed_t maxfrac = length << FRACBITS;
|
||||||
|
while (texturefrac >= maxfrac)
|
||||||
|
{
|
||||||
|
if (++yl > yh)
|
||||||
|
goto nextpost;
|
||||||
|
texturefrac += iscale;
|
||||||
|
}
|
||||||
|
fixed_t endfrac = texturefrac + (yh - yl)*iscale;
|
||||||
|
while (endfrac < 0)
|
||||||
|
{
|
||||||
|
if (--yh < yl)
|
||||||
|
goto nextpost;
|
||||||
|
endfrac -= iscale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
texturefrac = texturemid - (top << FRACBITS)
|
||||||
|
+ (yl*iscale) - FixedMul(centeryfrac - FRACUNIT, iscale);
|
||||||
|
while (texturefrac < 0)
|
||||||
|
{
|
||||||
|
if (++yl > yh)
|
||||||
|
goto nextpost;
|
||||||
|
texturefrac += iscale;
|
||||||
|
}
|
||||||
|
fixed_t endfrac = texturefrac + (yh - yl)*iscale;
|
||||||
|
const fixed_t maxfrac = length << FRACBITS;
|
||||||
|
if (yh < dc_mfloorclip[x] - 1 && endfrac < maxfrac - iscale)
|
||||||
|
{
|
||||||
|
yh++;
|
||||||
|
}
|
||||||
|
else while (endfrac >= maxfrac)
|
||||||
|
{
|
||||||
|
if (--yh < yl)
|
||||||
|
goto nextpost;
|
||||||
|
endfrac -= iscale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dc_yl = yl;
|
||||||
|
dc_yh = yh;
|
||||||
|
dc_x = x;
|
||||||
|
dc_texturefrac = texturefrac;
|
||||||
|
dc_iscale = iscale;
|
||||||
|
dc_source = column + top;
|
||||||
|
dc_count = yh - yl + 1;
|
||||||
|
dc_dest = (ylookup[yl] + x) * pixelsize + dc_destorg;
|
||||||
|
colfunc();
|
||||||
|
}
|
||||||
|
nextpost:
|
||||||
|
span++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
89
src/r_draw.h
89
src/r_draw.h
|
@ -25,6 +25,11 @@
|
||||||
|
|
||||||
#include "r_defs.h"
|
#include "r_defs.h"
|
||||||
|
|
||||||
|
// Prevents files outside the DrawerContext class getting good ideas about
|
||||||
|
// accessing the private globals. Any drawer actions should be facilitated
|
||||||
|
// via the DrawerContext class!
|
||||||
|
#ifdef DRAWER_INTERNALS
|
||||||
|
|
||||||
// Spectre/Invisibility.
|
// Spectre/Invisibility.
|
||||||
#define FUZZTABLE 50
|
#define FUZZTABLE 50
|
||||||
extern "C" int fuzzoffset[FUZZTABLE + 1]; // [RH] +1 for the assembly routine
|
extern "C" int fuzzoffset[FUZZTABLE + 1]; // [RH] +1 for the assembly routine
|
||||||
|
@ -71,6 +76,7 @@ extern "C" fixed_t dc_destalpha;
|
||||||
// first pixel in a column
|
// first pixel in a column
|
||||||
extern "C" const BYTE* dc_source;
|
extern "C" const BYTE* dc_source;
|
||||||
|
|
||||||
|
extern DCanvas *dc_canvas;
|
||||||
extern "C" BYTE *dc_dest, *dc_destorg;
|
extern "C" BYTE *dc_dest, *dc_destorg;
|
||||||
extern "C" int dc_count;
|
extern "C" int dc_count;
|
||||||
|
|
||||||
|
@ -86,6 +92,23 @@ extern "C" unsigned int dc_tspans[4][MAXHEIGHT];
|
||||||
extern "C" unsigned int *dc_ctspan[4];
|
extern "C" unsigned int *dc_ctspan[4];
|
||||||
extern "C" unsigned int horizspans[4];
|
extern "C" unsigned int horizspans[4];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Function pointers to switch refresh/drawing functions.
|
||||||
|
// Used to select shadow mode etc.
|
||||||
|
//
|
||||||
|
extern void (*colfunc) (void);
|
||||||
|
extern void (*basecolfunc) (void);
|
||||||
|
extern void (*fuzzcolfunc) (void);
|
||||||
|
extern void (*transcolfunc) (void);
|
||||||
|
// No shadow effects on floors.
|
||||||
|
extern void (*spanfunc) (void);
|
||||||
|
|
||||||
|
// [RH] Function pointers for the horizontal column drawers.
|
||||||
|
extern void (*hcolfunc_pre) (void);
|
||||||
|
extern void (*hcolfunc_post1) (int hx, int sx, int yl, int yh);
|
||||||
|
extern void (*hcolfunc_post2) (int hx, int sx, int yl, int yh);
|
||||||
|
extern void (*hcolfunc_post4) (int sx, int yl, int yh);
|
||||||
|
|
||||||
// [RH] Pointers to the different column and span drawers...
|
// [RH] Pointers to the different column and span drawers...
|
||||||
|
|
||||||
// The span blitting interface.
|
// The span blitting interface.
|
||||||
|
@ -116,7 +139,7 @@ extern void (*R_DrawTranslatedColumn)(void);
|
||||||
// Span drawing for rows, floor/ceiling. No Spectre effect needed.
|
// Span drawing for rows, floor/ceiling. No Spectre effect needed.
|
||||||
extern void (*R_DrawSpan)(void);
|
extern void (*R_DrawSpan)(void);
|
||||||
void R_SetupSpanBits(FTexture *tex);
|
void R_SetupSpanBits(FTexture *tex);
|
||||||
void R_SetSpanColormap(FDynamicColormap *colormap, int shade);
|
void R_SetSpanColormap();
|
||||||
void R_SetSpanSource(const BYTE *pixels);
|
void R_SetSpanSource(const BYTE *pixels);
|
||||||
|
|
||||||
// Span drawing for masked textures.
|
// Span drawing for masked textures.
|
||||||
|
@ -281,6 +304,15 @@ void R_FillColumnP_C (void);
|
||||||
void R_FillColumnHorizP_C (void);
|
void R_FillColumnHorizP_C (void);
|
||||||
void R_FillSpan_C (void);
|
void R_FillSpan_C (void);
|
||||||
|
|
||||||
|
// vars for R_DrawMaskedColumn
|
||||||
|
extern short* dc_mfloorclip;
|
||||||
|
extern short* dc_mceilingclip;
|
||||||
|
extern double dc_spryscale;
|
||||||
|
extern double dc_sprtopscreen;
|
||||||
|
extern bool dc_sprflipvert;
|
||||||
|
|
||||||
|
void R_DrawMaskedColumn(int x, const BYTE *column, const FTexture::Span *spans);
|
||||||
|
|
||||||
#ifdef X86_ASM
|
#ifdef X86_ASM
|
||||||
#define R_SetupDrawSlab R_SetupDrawSlabA
|
#define R_SetupDrawSlab R_SetupDrawSlabA
|
||||||
#define R_DrawSlab R_DrawSlabA
|
#define R_DrawSlab R_DrawSlabA
|
||||||
|
@ -325,12 +357,7 @@ void R_InitShadeMaps();
|
||||||
void R_InitFuzzTable (int fuzzoff);
|
void R_InitFuzzTable (int fuzzoff);
|
||||||
|
|
||||||
// [RH] Consolidate column drawer selection
|
// [RH] Consolidate column drawer selection
|
||||||
enum ESPSResult
|
enum ESPSResult;
|
||||||
{
|
|
||||||
DontDraw, // not useful to draw this
|
|
||||||
DoDraw0, // draw this as if r_columnmethod is 0
|
|
||||||
DoDraw1, // draw this as if r_columnmethod is 1
|
|
||||||
};
|
|
||||||
ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, DWORD color);
|
ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, DWORD color);
|
||||||
inline ESPSResult R_SetPatchStyle(FRenderStyle style, float alpha, int translation, DWORD color)
|
inline ESPSResult R_SetPatchStyle(FRenderStyle style, float alpha, int translation, DWORD color)
|
||||||
{
|
{
|
||||||
|
@ -353,18 +380,6 @@ extern void(*tmvline4_revsubclamp)();
|
||||||
// transmaskwallscan calls this to find out what column drawers to use
|
// transmaskwallscan calls this to find out what column drawers to use
|
||||||
bool R_GetTransMaskDrawers (fixed_t (**tmvline1)(), void (**tmvline4)());
|
bool R_GetTransMaskDrawers (fixed_t (**tmvline1)(), void (**tmvline4)());
|
||||||
|
|
||||||
// Retrieve column data for wallscan. Should probably be removed
|
|
||||||
// to just use the texture's GetColumn() method. It just exists
|
|
||||||
// for double-layer skies.
|
|
||||||
const BYTE *R_GetColumn (FTexture *tex, int col);
|
|
||||||
void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int col)=R_GetColumn);
|
|
||||||
|
|
||||||
// maskwallscan is exactly like wallscan but does not draw anything where the texture is color 0.
|
|
||||||
void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int col)=R_GetColumn);
|
|
||||||
|
|
||||||
// transmaskwallscan is like maskwallscan, but it can also blend to the background
|
|
||||||
void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int col)=R_GetColumn);
|
|
||||||
|
|
||||||
// Sets dc_colormap and dc_light to their appropriate values depending on the output format (pal vs true color)
|
// Sets dc_colormap and dc_light to their appropriate values depending on the output format (pal vs true color)
|
||||||
void R_SetColorMapLight(FColormap *base_colormap, float light, int shade);
|
void R_SetColorMapLight(FColormap *base_colormap, float light, int shade);
|
||||||
|
|
||||||
|
@ -373,4 +388,40 @@ void R_SetDSColorMapLight(FColormap *base_colormap, float light, int shade);
|
||||||
|
|
||||||
void R_SetTranslationMap(lighttable_t *translation);
|
void R_SetTranslationMap(lighttable_t *translation);
|
||||||
|
|
||||||
|
// Retrieve column data for wallscan. Should probably be removed
|
||||||
|
// to just use the texture's GetColumn() method. It just exists
|
||||||
|
// for double-layer skies.
|
||||||
|
const BYTE *R_GetColumn (FTexture *tex, int col);
|
||||||
|
void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, FTexture *rw_pic, fixed_t rw_offset, const BYTE *(*getcol)(FTexture *tex, int col)=R_GetColumn);
|
||||||
|
|
||||||
|
// maskwallscan is exactly like wallscan but does not draw anything where the texture is color 0.
|
||||||
|
void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, FTexture *rw_pic, fixed_t rw_offset, const BYTE *(*getcol)(FTexture *tex, int col)=R_GetColumn);
|
||||||
|
|
||||||
|
// transmaskwallscan is like maskwallscan, but it can also blend to the background
|
||||||
|
void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, FTexture *rw_pic, fixed_t rw_offset, const BYTE *(*getcol)(FTexture *tex, int col)=R_GetColumn);
|
||||||
|
|
||||||
|
extern void(*R_DrawColoredSpan)(int y, int x1, int x2);
|
||||||
|
extern void(*R_DrawTiltedSpan)(int y, int x1, int x2);
|
||||||
|
|
||||||
|
void R_DrawTiltedSpan_C(int y, int x1, int x2);
|
||||||
|
void R_DrawTiltedSpan_rgba(int y, int x1, int x2);
|
||||||
|
void R_DrawColoredSpan_C(int y, int x1, int x2);
|
||||||
|
void R_DrawColoredSpan_rgba(int y, int x1, int x2);
|
||||||
|
|
||||||
|
extern FVector3 ds_plane_sz, ds_plane_su, ds_plane_sv;
|
||||||
|
extern bool ds_plane_shade;
|
||||||
|
extern float ds_planelightfloat;
|
||||||
|
extern fixed_t ds_pviewx, ds_pviewy;
|
||||||
|
extern int ds_planeshade;
|
||||||
|
|
||||||
|
extern "C" BYTE *tiltlighting[MAXWIDTH];
|
||||||
|
extern "C" { void R_CalcTiltedLighting(double lval, double lend, int width); }
|
||||||
|
|
||||||
|
struct vissprite_t;
|
||||||
|
extern void(*R_FillTransColumn)(int x, int y1, int y2, int color, int alpha);
|
||||||
|
void R_FillTransColumn_C(int x, int y1, int y2, int color, int alpha);
|
||||||
|
void R_FillTransColumn_rgba(int x, int y1, int y2, int color, int alpha);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define DRAWER_INTERNALS
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
|
@ -3492,6 +3494,158 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DrawTiltedSpanRGBACommand : public DrawerCommand
|
||||||
|
{
|
||||||
|
int _y;
|
||||||
|
int _x1;
|
||||||
|
int _x2;
|
||||||
|
BYTE *dc_destorg;
|
||||||
|
fixed_t dc_light;
|
||||||
|
ShadeConstants dc_shade_constants;
|
||||||
|
const BYTE *ds_source;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DrawTiltedSpanRGBACommand(int y, int x1, int x2)
|
||||||
|
{
|
||||||
|
_y = y;
|
||||||
|
_x1 = x1;
|
||||||
|
_x2 = x2;
|
||||||
|
|
||||||
|
dc_destorg = ::dc_destorg;
|
||||||
|
ds_source = ::ds_source;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Execute(DrawerThread *thread) override
|
||||||
|
{
|
||||||
|
if (thread->line_skipped_by_thread(_y))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int y = _y;
|
||||||
|
int x1 = _x1;
|
||||||
|
int x2 = _x2;
|
||||||
|
|
||||||
|
// Slopes are broken currently in master.
|
||||||
|
// Until R_DrawTiltedPlane is fixed we are just going to fill with a solid color.
|
||||||
|
|
||||||
|
uint32_t *source = (uint32_t*)ds_source;
|
||||||
|
uint32_t *dest = ylookup[y] + x1 + (uint32_t*)dc_destorg;
|
||||||
|
|
||||||
|
int count = x2 - x1 + 1;
|
||||||
|
while (count > 0)
|
||||||
|
{
|
||||||
|
*(dest++) = source[0];
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class DrawColoredSpanRGBACommand : public DrawerCommand
|
||||||
|
{
|
||||||
|
int _y;
|
||||||
|
int _x1;
|
||||||
|
int _x2;
|
||||||
|
BYTE *dc_destorg;
|
||||||
|
fixed_t ds_light;
|
||||||
|
int ds_color;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DrawColoredSpanRGBACommand(int y, int x1, int x2)
|
||||||
|
{
|
||||||
|
_y = y;
|
||||||
|
_x1 = x1;
|
||||||
|
_x2 = x2;
|
||||||
|
|
||||||
|
dc_destorg = ::dc_destorg;
|
||||||
|
ds_light = ::ds_light;
|
||||||
|
ds_color = ::ds_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Execute(DrawerThread *thread) override
|
||||||
|
{
|
||||||
|
if (thread->line_skipped_by_thread(_y))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int y = _y;
|
||||||
|
int x1 = _x1;
|
||||||
|
int x2 = _x2;
|
||||||
|
|
||||||
|
uint32_t *dest = ylookup[y] + x1 + (uint32_t*)dc_destorg;
|
||||||
|
int count = (x2 - x1 + 1);
|
||||||
|
uint32_t light = calc_light_multiplier(ds_light);
|
||||||
|
uint32_t color = shade_pal_index_simple(ds_color, light);
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
dest[i] = color;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class FillTransColumnRGBACommand : public DrawerCommand
|
||||||
|
{
|
||||||
|
int _x;
|
||||||
|
int _y1;
|
||||||
|
int _y2;
|
||||||
|
int _color;
|
||||||
|
int _a;
|
||||||
|
BYTE *dc_destorg;
|
||||||
|
int dc_pitch;
|
||||||
|
fixed_t ds_light;
|
||||||
|
int ds_color;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FillTransColumnRGBACommand(int x, int y1, int y2, int color, int a)
|
||||||
|
{
|
||||||
|
_x = x;
|
||||||
|
_y1 = y1;
|
||||||
|
_y2 = y2;
|
||||||
|
_color = color;
|
||||||
|
_a = a;
|
||||||
|
|
||||||
|
dc_destorg = ::dc_destorg;
|
||||||
|
dc_pitch = ::dc_pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Execute(DrawerThread *thread) override
|
||||||
|
{
|
||||||
|
int x = _x;
|
||||||
|
int y1 = _y1;
|
||||||
|
int y2 = _y2;
|
||||||
|
int color = _color;
|
||||||
|
int a = _a;
|
||||||
|
|
||||||
|
int ycount = thread->count_for_thread(y1, y2 - y1 + 1);
|
||||||
|
if (ycount <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32_t fg = GPalette.BaseColors[color].d;
|
||||||
|
uint32_t fg_red = (fg >> 16) & 0xff;
|
||||||
|
uint32_t fg_green = (fg >> 8) & 0xff;
|
||||||
|
uint32_t fg_blue = fg & 0xff;
|
||||||
|
|
||||||
|
uint32_t alpha = a + 1;
|
||||||
|
uint32_t inv_alpha = 256 - alpha;
|
||||||
|
|
||||||
|
fg_red *= alpha;
|
||||||
|
fg_green *= alpha;
|
||||||
|
fg_blue *= alpha;
|
||||||
|
|
||||||
|
int spacing = dc_pitch * thread->num_cores;
|
||||||
|
uint32_t *dest = thread->dest_for_thread(y1, dc_pitch, ylookup[y1] + x + (uint32_t*)dc_destorg);
|
||||||
|
|
||||||
|
for (int y = 0; y < ycount; y++)
|
||||||
|
{
|
||||||
|
uint32_t bg_red = (*dest >> 16) & 0xff;
|
||||||
|
uint32_t bg_green = (*dest >> 8) & 0xff;
|
||||||
|
uint32_t bg_blue = (*dest) & 0xff;
|
||||||
|
|
||||||
|
uint32_t red = (fg_red + bg_red * inv_alpha) / 256;
|
||||||
|
uint32_t green = (fg_green + bg_green * inv_alpha) / 256;
|
||||||
|
uint32_t blue = (fg_blue + bg_blue * inv_alpha) / 256;
|
||||||
|
|
||||||
|
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
|
||||||
|
dest += spacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ApplySpecialColormapRGBACommand::ApplySpecialColormapRGBACommand(FSpecialColormap *colormap, DFrameBuffer *screen)
|
ApplySpecialColormapRGBACommand::ApplySpecialColormapRGBACommand(FSpecialColormap *colormap, DFrameBuffer *screen)
|
||||||
{
|
{
|
||||||
buffer = screen->GetBuffer();
|
buffer = screen->GetBuffer();
|
||||||
|
@ -3968,3 +4122,18 @@ void R_DrawFogBoundary_rgba(int x1, int x2, short *uclip, short *dclip)
|
||||||
R_DrawFogBoundarySection_rgba(t2, b2, x1);
|
R_DrawFogBoundarySection_rgba(t2, b2, x1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void R_DrawTiltedSpan_rgba(int y, int x1, int x2)
|
||||||
|
{
|
||||||
|
DrawerCommandQueue::QueueCommand<DrawTiltedSpanRGBACommand>(y, x1, x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_DrawColoredSpan_rgba(int y, int x1, int x2)
|
||||||
|
{
|
||||||
|
DrawerCommandQueue::QueueCommand<DrawColoredSpanRGBACommand>(y, x1, x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_FillTransColumn_rgba(int x, int y1, int y2, int color, int a)
|
||||||
|
{
|
||||||
|
DrawerCommandQueue::QueueCommand<FillTransColumnRGBACommand>(x, y1, y2, color, a);
|
||||||
|
}
|
||||||
|
|
|
@ -23,6 +23,11 @@
|
||||||
#ifndef __R_DRAW_RGBA__
|
#ifndef __R_DRAW_RGBA__
|
||||||
#define __R_DRAW_RGBA__
|
#define __R_DRAW_RGBA__
|
||||||
|
|
||||||
|
// Prevents files outside the DrawerContext class getting good ideas about
|
||||||
|
// accessing the private globals. Any drawer actions should be facilitated
|
||||||
|
// via the DrawerContext class!
|
||||||
|
#ifdef DRAWER_INTERNALS
|
||||||
|
|
||||||
#include "r_draw.h"
|
#include "r_draw.h"
|
||||||
#include "v_palette.h"
|
#include "v_palette.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -487,3 +492,5 @@ FORCEINLINE uint32_t alpha_blend(uint32_t fg, uint32_t bg)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
464
src/r_drawer_context.cpp
Normal file
464
src/r_drawer_context.cpp
Normal file
|
@ -0,0 +1,464 @@
|
||||||
|
// Emacs style mode select -*- C++ -*-
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// $Id:$
|
||||||
|
//
|
||||||
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||||
|
//
|
||||||
|
// This source is available for distribution and/or modification
|
||||||
|
// only under the terms of the DOOM Source Code License as
|
||||||
|
// published by id Software. All rights reserved.
|
||||||
|
//
|
||||||
|
// The source is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||||
|
// for more details.
|
||||||
|
//
|
||||||
|
// $Log:$
|
||||||
|
//
|
||||||
|
// DESCRIPTION:
|
||||||
|
// The actual span/column drawing functions.
|
||||||
|
// Here find the main potential for optimization,
|
||||||
|
// e.g. inline assembly, different algorithms.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define DRAWER_INTERNALS
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "templates.h"
|
||||||
|
#include "doomdef.h"
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
#include "r_local.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
#include "doomstat.h"
|
||||||
|
#include "st_stuff.h"
|
||||||
|
#include "g_game.h"
|
||||||
|
#include "g_level.h"
|
||||||
|
#include "r_data/r_translate.h"
|
||||||
|
#include "v_palette.h"
|
||||||
|
#include "r_data/colormaps.h"
|
||||||
|
#include "r_plane.h"
|
||||||
|
#include "r_draw_rgba.h"
|
||||||
|
#include "d_net.h"
|
||||||
|
#include "r_drawer_context.h"
|
||||||
|
|
||||||
|
#include "gi.h"
|
||||||
|
#include "stats.h"
|
||||||
|
#include "x86.h"
|
||||||
|
|
||||||
|
#ifdef X86_ASM
|
||||||
|
extern "C" void R_SetSpanSource_ASM (const BYTE *flat);
|
||||||
|
extern "C" void R_SetSpanSize_ASM (int xbits, int ybits);
|
||||||
|
extern "C" void R_SetSpanColormap_ASM (BYTE *colormap);
|
||||||
|
extern "C" void R_SetTiltedSpanSource_ASM(const BYTE *flat);
|
||||||
|
extern "C" BYTE *ds_curcolormap, *ds_cursource, *ds_curtiltedsource;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DCanvas *DrawerContext::Canvas()
|
||||||
|
{
|
||||||
|
return dc_canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t DrawerContext::FlatColor()
|
||||||
|
{
|
||||||
|
return dc_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
FColormap *DrawerContext::LightColormap()
|
||||||
|
{
|
||||||
|
return dc_fcolormap;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed_t DrawerContext::TextureFrac()
|
||||||
|
{
|
||||||
|
return dc_texturefrac;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed_t DrawerContext::TextureStep()
|
||||||
|
{
|
||||||
|
return dc_iscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
double DrawerContext::TextureMid()
|
||||||
|
{
|
||||||
|
return dc_texturemid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DrawerContext::SpanXBits()
|
||||||
|
{
|
||||||
|
return ds_xbits;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DrawerContext::SpanYBits()
|
||||||
|
{
|
||||||
|
return ds_ybits;
|
||||||
|
}
|
||||||
|
|
||||||
|
lighttable_t *DrawerContext::SpanLitColormap()
|
||||||
|
{
|
||||||
|
return ds_colormap;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DrawerContext::IsFuzzColumn()
|
||||||
|
{
|
||||||
|
return colfunc == fuzzcolfunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DrawerContext::IsFillColumn()
|
||||||
|
{
|
||||||
|
return colfunc == R_FillColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DrawerContext::IsBaseColumn()
|
||||||
|
{
|
||||||
|
return colfunc == basecolfunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetDest(int x, int y)
|
||||||
|
{
|
||||||
|
int pixelsize = r_swtruecolor ? 4 : 1;
|
||||||
|
dc_dest = dc_destorg + (ylookup[y] + x) * pixelsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetFlatColor(uint8_t color_index)
|
||||||
|
{
|
||||||
|
dc_color = color_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetLight(FColormap *base_colormap, float light, int shade)
|
||||||
|
{
|
||||||
|
R_SetColorMapLight(base_colormap, light, shade);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetX(int x)
|
||||||
|
{
|
||||||
|
dc_x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetY1(int y)
|
||||||
|
{
|
||||||
|
dc_yl = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetY2(int y)
|
||||||
|
{
|
||||||
|
dc_yh = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetSource(const BYTE *source)
|
||||||
|
{
|
||||||
|
dc_source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetTextureFrac(fixed_t pos)
|
||||||
|
{
|
||||||
|
dc_texturefrac = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetTextureStep(fixed_t step)
|
||||||
|
{
|
||||||
|
dc_iscale = step;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetTextureMid(double value)
|
||||||
|
{
|
||||||
|
dc_texturemid = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetDrawCount(int count)
|
||||||
|
{
|
||||||
|
dc_count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetSpanY(int y)
|
||||||
|
{
|
||||||
|
ds_y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetSpanX1(int x)
|
||||||
|
{
|
||||||
|
ds_x1 = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetSpanX2(int x)
|
||||||
|
{
|
||||||
|
ds_x2 = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetSpanXStep(dsfixed_t step)
|
||||||
|
{
|
||||||
|
ds_xstep = step;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetSpanYStep(dsfixed_t step)
|
||||||
|
{
|
||||||
|
ds_ystep = step;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetSpanXBits(int bits)
|
||||||
|
{
|
||||||
|
ds_xbits = bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetSpanYBits(int bits)
|
||||||
|
{
|
||||||
|
ds_ybits = bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetSpanXFrac(dsfixed_t frac)
|
||||||
|
{
|
||||||
|
ds_xfrac = frac;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetSpanYFrac(dsfixed_t frac)
|
||||||
|
{
|
||||||
|
ds_yfrac = frac;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetSpanLight(FColormap *base_colormap, float light, int shade)
|
||||||
|
{
|
||||||
|
R_SetDSColorMapLight(base_colormap ? base_colormap : &identitycolormap, light, shade);
|
||||||
|
R_SetSpanColormap();
|
||||||
|
}
|
||||||
|
|
||||||
|
ESPSResult DrawerContext::SetPatchStyle(FRenderStyle style, fixed_t alpha, int translation, DWORD color)
|
||||||
|
{
|
||||||
|
return R_SetPatchStyle(style, alpha, translation, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESPSResult DrawerContext::SetPatchStyle(FRenderStyle style, float alpha, int translation, DWORD color)
|
||||||
|
{
|
||||||
|
return R_SetPatchStyle(style, FLOAT2FIXED(alpha), translation, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::FinishSetPatchStyle()
|
||||||
|
{
|
||||||
|
R_FinishSetPatchStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetCanvas(DCanvas *canvas)
|
||||||
|
{
|
||||||
|
dc_canvas = canvas;
|
||||||
|
dc_destorg = canvas->GetBuffer();
|
||||||
|
|
||||||
|
if (r_swtruecolor != canvas->IsBgra())
|
||||||
|
{
|
||||||
|
r_swtruecolor = canvas->IsBgra();
|
||||||
|
R_InitColumnDrawers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetTranslationMap(lighttable_t *translation)
|
||||||
|
{
|
||||||
|
R_SetTranslationMap(translation ? translation : identitymap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetSpanSource(FTexture *tex)
|
||||||
|
{
|
||||||
|
R_SetupSpanBits(tex);
|
||||||
|
if (r_swtruecolor)
|
||||||
|
ds_source = (const BYTE*)tex->GetPixelsBgra();
|
||||||
|
else
|
||||||
|
ds_source = tex->GetPixels();
|
||||||
|
|
||||||
|
#ifdef X86_ASM
|
||||||
|
if (!r_swtruecolor && ds_source != ds_cursource)
|
||||||
|
{
|
||||||
|
R_SetSpanSource_ASM (ds_source);
|
||||||
|
}
|
||||||
|
if (!r_swtruecolor)
|
||||||
|
{
|
||||||
|
if (ds_source != ds_curtiltedsource)
|
||||||
|
R_SetTiltedSpanSource_ASM(ds_source);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetTiltedSpanState(FVector3 plane_sz, FVector3 plane_su, FVector3 plane_sv, bool plane_shade, float planelightfloat, fixed_t pviewx, fixed_t pviewy)
|
||||||
|
{
|
||||||
|
ds_plane_sz = plane_sz;
|
||||||
|
ds_plane_su = plane_su;
|
||||||
|
ds_plane_sv = plane_sv;
|
||||||
|
ds_plane_shade = plane_shade;
|
||||||
|
ds_planelightfloat = planelightfloat;
|
||||||
|
ds_pviewx = pviewx;
|
||||||
|
ds_pviewy = pviewy;
|
||||||
|
|
||||||
|
if (!plane_shade)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < viewwidth; ++i)
|
||||||
|
{
|
||||||
|
tiltlighting[i] = DrawerContext::SpanLitColormap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetSlabLight(const BYTE *colormap)
|
||||||
|
{
|
||||||
|
R_SetupDrawSlab(colormap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::DrawSlab(int dx, fixed_t v, int dy, fixed_t vi, const BYTE *source, int dest_x, int dest_y)
|
||||||
|
{
|
||||||
|
int pixelsize = r_swtruecolor ? 4 : 1;
|
||||||
|
R_DrawSlab(dx, v, dy, vi, source, (ylookup[dest_y] + dest_x) * pixelsize + dc_destorg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetSpanStyle(fixed_t alpha, bool additive, bool masked)
|
||||||
|
{
|
||||||
|
if (spanfunc != R_FillSpan)
|
||||||
|
{
|
||||||
|
if (masked)
|
||||||
|
{
|
||||||
|
if (alpha < OPAQUE || additive)
|
||||||
|
{
|
||||||
|
if (!additive)
|
||||||
|
{
|
||||||
|
spanfunc = R_DrawSpanMaskedTranslucent;
|
||||||
|
dc_srcblend = Col2RGB8[alpha >> 10];
|
||||||
|
dc_destblend = Col2RGB8[(OPAQUE - alpha) >> 10];
|
||||||
|
dc_srcalpha = alpha;
|
||||||
|
dc_destalpha = OPAQUE - alpha;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spanfunc = R_DrawSpanMaskedAddClamp;
|
||||||
|
dc_srcblend = Col2RGB8_LessPrecision[alpha >> 10];
|
||||||
|
dc_destblend = Col2RGB8_LessPrecision[FRACUNIT >> 10];
|
||||||
|
dc_srcalpha = alpha;
|
||||||
|
dc_destalpha = OPAQUE - alpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spanfunc = R_DrawSpanMasked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (alpha < OPAQUE || additive)
|
||||||
|
{
|
||||||
|
if (!additive)
|
||||||
|
{
|
||||||
|
spanfunc = R_DrawSpanTranslucent;
|
||||||
|
dc_srcblend = Col2RGB8[alpha >> 10];
|
||||||
|
dc_destblend = Col2RGB8[(OPAQUE - alpha) >> 10];
|
||||||
|
dc_srcalpha = alpha;
|
||||||
|
dc_destalpha = OPAQUE - alpha;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spanfunc = R_DrawSpanAddClamp;
|
||||||
|
dc_srcblend = Col2RGB8_LessPrecision[alpha >> 10];
|
||||||
|
dc_destblend = Col2RGB8_LessPrecision[FRACUNIT >> 10];
|
||||||
|
dc_srcalpha = alpha;
|
||||||
|
dc_destalpha = OPAQUE - alpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spanfunc = R_DrawSpan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::RtInitCols(BYTE *buffer)
|
||||||
|
{
|
||||||
|
rt_initcols(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::RtSpanCoverage(int x, int start, int stop)
|
||||||
|
{
|
||||||
|
rt_span_coverage(x, start, stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetMaskedColumnState(short *mfloorclip, short *mceilingclip, double spryscale, double sprtopscreen, bool sprflipvert)
|
||||||
|
{
|
||||||
|
dc_mfloorclip = mfloorclip;
|
||||||
|
dc_mceilingclip = mceilingclip;
|
||||||
|
dc_spryscale = spryscale;
|
||||||
|
dc_sprtopscreen = sprtopscreen;
|
||||||
|
dc_sprflipvert = sprflipvert;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::DrawMaskedColumn(int x, const BYTE *column, const FTexture::Span *spans)
|
||||||
|
{
|
||||||
|
R_DrawMaskedColumn(x, column, spans);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::DrawMaskedColumnHoriz(int x, const BYTE *column, const FTexture::Span *spans)
|
||||||
|
{
|
||||||
|
dc_x = x;
|
||||||
|
R_DrawMaskedColumnHoriz(column, spans);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::DrawFogBoundary(int x1, int x2, short *uclip, short *dclip)
|
||||||
|
{
|
||||||
|
R_DrawFogBoundary(x1, x2, uclip, dclip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::DrawRt4cols(int sx)
|
||||||
|
{
|
||||||
|
rt_draw4cols(sx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::DrawColumn()
|
||||||
|
{
|
||||||
|
colfunc();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::DrawSpan()
|
||||||
|
{
|
||||||
|
spanfunc();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::DrawHColumnPre()
|
||||||
|
{
|
||||||
|
hcolfunc_pre();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::DrawSimplePolySpan()
|
||||||
|
{
|
||||||
|
R_DrawSpan();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::SetBaseStyle()
|
||||||
|
{
|
||||||
|
colfunc = basecolfunc;
|
||||||
|
hcolfunc_post1 = rt_map1col;
|
||||||
|
hcolfunc_post4 = rt_map4cols;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::DrawWall(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, FTexture *rw_pic, fixed_t rw_offset, const BYTE *(*getcol)(FTexture *tex, int col))
|
||||||
|
{
|
||||||
|
wallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, rw_pic, rw_offset, getcol ? getcol : R_GetColumn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::DrawMaskedWall(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, FTexture *rw_pic, fixed_t rw_offset, const BYTE *(*getcol)(FTexture *tex, int col))
|
||||||
|
{
|
||||||
|
maskwallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, rw_pic, rw_offset, getcol ? getcol : R_GetColumn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::DrawTransMaskedWall(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, FTexture *rw_pic, fixed_t rw_offset, const BYTE *(*getcol)(FTexture *tex, int col))
|
||||||
|
{
|
||||||
|
transmaskwallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, rw_pic, rw_offset, getcol ? getcol : R_GetColumn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::DrawColoredSpan(int y, int x1, int x2)
|
||||||
|
{
|
||||||
|
R_DrawColoredSpan(y, x1, x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::DrawTiltedSpan(int y, int x1, int x2)
|
||||||
|
{
|
||||||
|
R_DrawTiltedSpan(y, x1, x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawerContext::FillTransColumn(int x, int y1, int y2, int color, int alpha)
|
||||||
|
{
|
||||||
|
R_FillTransColumn(x, y1, y2, color, alpha);
|
||||||
|
}
|
123
src/r_drawer_context.h
Normal file
123
src/r_drawer_context.h
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
// Emacs style mode select -*- C++ -*-
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// $Id:$
|
||||||
|
//
|
||||||
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||||
|
//
|
||||||
|
// This source is available for distribution and/or modification
|
||||||
|
// only under the terms of the DOOM Source Code License as
|
||||||
|
// published by id Software. All rights reserved.
|
||||||
|
//
|
||||||
|
// The source is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||||
|
// for more details.
|
||||||
|
//
|
||||||
|
// DESCRIPTION:
|
||||||
|
// System specific interface stuff.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __R_DRAWER_CONTEXT__
|
||||||
|
#define __R_DRAWER_CONTEXT__
|
||||||
|
|
||||||
|
#include "r_defs.h"
|
||||||
|
|
||||||
|
// [RH] Consolidate column drawer selection
|
||||||
|
enum ESPSResult
|
||||||
|
{
|
||||||
|
DontDraw, // not useful to draw this
|
||||||
|
DoDraw0, // draw this as if r_columnmethod is 0
|
||||||
|
DoDraw1, // draw this as if r_columnmethod is 1
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TiltedPlaneData;
|
||||||
|
|
||||||
|
// Immediate graphics context for column/span based software rendering.
|
||||||
|
class DrawerContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static DCanvas *Canvas(); // dc_destorg
|
||||||
|
|
||||||
|
static uint8_t FlatColor(); // dc_color
|
||||||
|
static FColormap *LightColormap(); // dc_fcolormap
|
||||||
|
static fixed_t TextureFrac(); // dc_texturefrac
|
||||||
|
static fixed_t TextureStep(); // dc_iscale
|
||||||
|
static double TextureMid(); // dc_texturemid
|
||||||
|
|
||||||
|
static int SpanXBits(); // ds_xbits
|
||||||
|
static int SpanYBits(); // ds_ybits
|
||||||
|
static lighttable_t *SpanLitColormap(); // ds_colormap
|
||||||
|
|
||||||
|
static bool IsFuzzColumn(); // colfunc == fuzzcolfunc
|
||||||
|
static bool IsFillColumn(); // colfunc == R_FillColumn
|
||||||
|
static bool IsBaseColumn(); // colfunc == basecolfunc
|
||||||
|
|
||||||
|
static void SetCanvas(DCanvas *canvas); // dc_destorg
|
||||||
|
|
||||||
|
static void SetFlatColor(uint8_t color_index); // dc_color
|
||||||
|
static void SetLight(FColormap *base_colormap, float light, int shade);
|
||||||
|
static void SetTranslationMap(lighttable_t *translation);
|
||||||
|
static void SetX(int x); // dc_x
|
||||||
|
static void SetY1(int y); // dc_yl
|
||||||
|
static void SetY2(int y); // dc_yh
|
||||||
|
static void SetSource(const BYTE *source); // dc_source
|
||||||
|
static void SetTextureFrac(fixed_t pos); // dc_texturefrac
|
||||||
|
static void SetTextureStep(fixed_t step); // dc_iscale
|
||||||
|
static void SetTextureMid(double value); // dc_texturemid
|
||||||
|
static void SetDest(int x, int y); // dc_dest
|
||||||
|
static void SetDrawCount(int count); // dc_count
|
||||||
|
|
||||||
|
static void SetSpanY(int y); // ds_y
|
||||||
|
static void SetSpanX1(int x); // ds_x1
|
||||||
|
static void SetSpanX2(int x); // ds_x2
|
||||||
|
static void SetSpanXStep(dsfixed_t step); // ds_xstep
|
||||||
|
static void SetSpanYStep(dsfixed_t step); // ds_ystep
|
||||||
|
static void SetSpanXBits(int bits); // ds_xbits
|
||||||
|
static void SetSpanYBits(int bits); // ds_ybits
|
||||||
|
static void SetSpanXFrac(dsfixed_t frac); // ds_xfrac
|
||||||
|
static void SetSpanYFrac(dsfixed_t frac); // ds_yfrac
|
||||||
|
static void SetSpanLight(FColormap *base_colormap, float light, int shade);
|
||||||
|
static void SetSpanSource(FTexture *texture);
|
||||||
|
static void SetSpanStyle(fixed_t alpha, bool additive, bool masked);
|
||||||
|
|
||||||
|
static void SetSlabLight(const BYTE *colormap);
|
||||||
|
|
||||||
|
static ESPSResult SetPatchStyle(FRenderStyle style, fixed_t alpha, int translation, DWORD color);
|
||||||
|
static ESPSResult SetPatchStyle(FRenderStyle style, float alpha, int translation, DWORD color);
|
||||||
|
// Call this after finished drawing the current thing, in case its style was STYLE_Shade
|
||||||
|
static void SetBaseStyle();
|
||||||
|
static void FinishSetPatchStyle();
|
||||||
|
|
||||||
|
static void SetMaskedColumnState(short *mfloorclip, short *mceilingclip, double spryscale, double sprtopscreen, bool sprflipvert);
|
||||||
|
static void SetTiltedSpanState(FVector3 plane_sz, FVector3 plane_su, FVector3 plane_sv, bool plane_shade, float planelightfloat, fixed_t pviewx, fixed_t pviewy);
|
||||||
|
|
||||||
|
static void RtInitCols(BYTE *buffer);
|
||||||
|
static void RtSpanCoverage(int x, int start, int stop);
|
||||||
|
|
||||||
|
static void DrawMaskedColumn(int x, const BYTE *column, const FTexture::Span *spans);
|
||||||
|
static void DrawMaskedColumnHoriz(int x, const BYTE *column, const FTexture::Span *spans);
|
||||||
|
|
||||||
|
static void DrawRt4cols(int sx);
|
||||||
|
static void DrawColumn();
|
||||||
|
static void DrawHColumnPre();
|
||||||
|
static void DrawSpan();
|
||||||
|
static void DrawSimplePolySpan();
|
||||||
|
|
||||||
|
static void DrawWall(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, FTexture *texture, fixed_t texturefrac, const BYTE *(*getcol)(FTexture *tex, int col) = nullptr);
|
||||||
|
static void DrawMaskedWall(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, FTexture *texture, fixed_t texturefrac, const BYTE *(*getcol)(FTexture *tex, int col) = nullptr);
|
||||||
|
static void DrawTransMaskedWall(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, FTexture *texture, fixed_t texturefrac, const BYTE *(*getcol)(FTexture *tex, int col) = nullptr);
|
||||||
|
|
||||||
|
static void DrawColoredSpan(int y, int x1, int x2);
|
||||||
|
static void DrawTiltedSpan(int y, int x1, int x2);
|
||||||
|
|
||||||
|
static void DrawSlab(int dx, fixed_t v, int dy, fixed_t vi, const BYTE *source, int dest_x, int dest_y);
|
||||||
|
|
||||||
|
static void FillTransColumn(int x, int y1, int y2, int color, int alpha);
|
||||||
|
|
||||||
|
static void DrawFogBoundary(int x1, int x2, short *uclip, short *dclip);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -38,6 +38,8 @@
|
||||||
** Let's hope so. :-)
|
** Let's hope so. :-)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define DRAWER_INTERNALS
|
||||||
|
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
|
@ -1128,26 +1130,26 @@ void R_DrawMaskedColumnHoriz (const BYTE *column, const FTexture::Span *span)
|
||||||
const int top = span->TopOffset;
|
const int top = span->TopOffset;
|
||||||
|
|
||||||
// calculate unclipped screen coordinates for post
|
// calculate unclipped screen coordinates for post
|
||||||
dc_yl = xs_RoundToInt(sprtopscreen + spryscale * top);
|
dc_yl = xs_RoundToInt(dc_sprtopscreen + dc_spryscale * top);
|
||||||
dc_yh = xs_RoundToInt(sprtopscreen + spryscale * (top + length) - 1);
|
dc_yh = xs_RoundToInt(dc_sprtopscreen + dc_spryscale * (top + length) - 1);
|
||||||
|
|
||||||
if (sprflipvert)
|
if (dc_sprflipvert)
|
||||||
{
|
{
|
||||||
swapvalues (dc_yl, dc_yh);
|
swapvalues (dc_yl, dc_yh);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dc_yh >= mfloorclip[dc_x])
|
if (dc_yh >= dc_mfloorclip[dc_x])
|
||||||
{
|
{
|
||||||
dc_yh = mfloorclip[dc_x] - 1;
|
dc_yh = dc_mfloorclip[dc_x] - 1;
|
||||||
}
|
}
|
||||||
if (dc_yl < mceilingclip[dc_x])
|
if (dc_yl < dc_mceilingclip[dc_x])
|
||||||
{
|
{
|
||||||
dc_yl = mceilingclip[dc_x];
|
dc_yl = dc_mceilingclip[dc_x];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dc_yl <= dc_yh)
|
if (dc_yl <= dc_yh)
|
||||||
{
|
{
|
||||||
if (sprflipvert)
|
if (dc_sprflipvert)
|
||||||
{
|
{
|
||||||
dc_texturefrac = (dc_yl*dc_iscale) - (top << FRACBITS)
|
dc_texturefrac = (dc_yl*dc_iscale) - (top << FRACBITS)
|
||||||
- fixed_t(CenterY * dc_iscale) - texturemid;
|
- fixed_t(CenterY * dc_iscale) - texturemid;
|
||||||
|
@ -1178,7 +1180,7 @@ void R_DrawMaskedColumnHoriz (const BYTE *column, const FTexture::Span *span)
|
||||||
}
|
}
|
||||||
fixed_t endfrac = dc_texturefrac + (dc_yh-dc_yl)*dc_iscale;
|
fixed_t endfrac = dc_texturefrac + (dc_yh-dc_yl)*dc_iscale;
|
||||||
const fixed_t maxfrac = length << FRACBITS;
|
const fixed_t maxfrac = length << FRACBITS;
|
||||||
if (dc_yh < mfloorclip[dc_x]-1 && endfrac < maxfrac - dc_iscale)
|
if (dc_yh < dc_mfloorclip[dc_x]-1 && endfrac < maxfrac - dc_iscale)
|
||||||
{
|
{
|
||||||
dc_yh++;
|
dc_yh++;
|
||||||
}
|
}
|
||||||
|
@ -1198,7 +1200,7 @@ nextpost:
|
||||||
span++;
|
span++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sprflipvert)
|
if (dc_sprflipvert)
|
||||||
{
|
{
|
||||||
unsigned int *front = horizspan[dc_x&3];
|
unsigned int *front = horizspan[dc_x&3];
|
||||||
unsigned int *back = dc_ctspan[dc_x&3] - 2;
|
unsigned int *back = dc_ctspan[dc_x&3] - 2;
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
** Please see r_drawt.cpp for a description of the globals used.
|
** Please see r_drawt.cpp for a description of the globals used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define DRAWER_INTERNALS
|
||||||
|
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define DRAWER_INTERNALS
|
||||||
|
|
||||||
// HEADER FILES ------------------------------------------------------------
|
// HEADER FILES ------------------------------------------------------------
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -150,17 +152,6 @@ angle_t xtoviewangle[MAXWIDTH+1];
|
||||||
bool foggy; // [RH] ignore extralight and fullbright?
|
bool foggy; // [RH] ignore extralight and fullbright?
|
||||||
int r_actualextralight;
|
int r_actualextralight;
|
||||||
|
|
||||||
void (*colfunc) (void);
|
|
||||||
void (*basecolfunc) (void);
|
|
||||||
void (*fuzzcolfunc) (void);
|
|
||||||
void (*transcolfunc) (void);
|
|
||||||
void (*spanfunc) (void);
|
|
||||||
|
|
||||||
void (*hcolfunc_pre) (void);
|
|
||||||
void (*hcolfunc_post1) (int hx, int sx, int yl, int yh);
|
|
||||||
void (*hcolfunc_post2) (int hx, int sx, int yl, int yh);
|
|
||||||
void (*hcolfunc_post4) (int sx, int yl, int yh);
|
|
||||||
|
|
||||||
cycle_t WallCycles, PlaneCycles, MaskedCycles, WallScanCycles;
|
cycle_t WallCycles, PlaneCycles, MaskedCycles, WallScanCycles;
|
||||||
|
|
||||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||||
|
@ -820,6 +811,7 @@ void R_SetupBuffer ()
|
||||||
ASM_PatchPitch ();
|
ASM_PatchPitch ();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
dc_canvas = RenderTarget;
|
||||||
dc_destorg = lineptr;
|
dc_destorg = lineptr;
|
||||||
for (int i = 0; i < RenderTarget->GetHeight(); i++)
|
for (int i = 0; i < RenderTarget->GetHeight(); i++)
|
||||||
{
|
{
|
||||||
|
|
16
src/r_main.h
16
src/r_main.h
|
@ -110,22 +110,6 @@ extern FColormap* fixedcolormap;
|
||||||
extern FSpecialColormap*realfixedcolormap;
|
extern FSpecialColormap*realfixedcolormap;
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Function pointers to switch refresh/drawing functions.
|
|
||||||
// Used to select shadow mode etc.
|
|
||||||
//
|
|
||||||
extern void (*colfunc) (void);
|
|
||||||
extern void (*basecolfunc) (void);
|
|
||||||
extern void (*fuzzcolfunc) (void);
|
|
||||||
extern void (*transcolfunc) (void);
|
|
||||||
// No shadow effects on floors.
|
|
||||||
extern void (*spanfunc) (void);
|
|
||||||
|
|
||||||
// [RH] Function pointers for the horizontal column drawers.
|
|
||||||
extern void (*hcolfunc_pre) (void);
|
|
||||||
extern void (*hcolfunc_post1) (int hx, int sx, int yl, int yh);
|
|
||||||
extern void (*hcolfunc_post2) (int hx, int sx, int yl, int yh);
|
|
||||||
extern void (*hcolfunc_post4) (int sx, int yl, int yh);
|
|
||||||
|
|
||||||
|
|
||||||
void R_InitTextureMapping ();
|
void R_InitTextureMapping ();
|
||||||
|
|
454
src/r_plane.cpp
454
src/r_plane.cpp
|
@ -58,7 +58,7 @@
|
||||||
#include "r_3dfloors.h"
|
#include "r_3dfloors.h"
|
||||||
#include "v_palette.h"
|
#include "v_palette.h"
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
#include "r_draw_rgba.h"
|
#include "r_drawer_context.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable:4244)
|
#pragma warning(disable:4244)
|
||||||
|
@ -138,8 +138,6 @@ FVector3 plane_sz, plane_su, plane_sv;
|
||||||
float planelightfloat;
|
float planelightfloat;
|
||||||
bool plane_shade;
|
bool plane_shade;
|
||||||
fixed_t pviewx, pviewy;
|
fixed_t pviewx, pviewy;
|
||||||
|
|
||||||
void R_DrawTiltedPlane_ASM (int y, int x1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float yslope[MAXHEIGHT];
|
float yslope[MAXHEIGHT];
|
||||||
|
@ -147,13 +145,6 @@ static fixed_t xscale, yscale;
|
||||||
static double xstepscale, ystepscale;
|
static double xstepscale, ystepscale;
|
||||||
static double basexfrac, baseyfrac;
|
static double basexfrac, baseyfrac;
|
||||||
|
|
||||||
#ifdef X86_ASM
|
|
||||||
extern "C" void R_SetSpanSource_ASM (const BYTE *flat);
|
|
||||||
extern "C" void R_SetSpanSize_ASM (int xbits, int ybits);
|
|
||||||
extern "C" void R_SetSpanColormap_ASM (BYTE *colormap);
|
|
||||||
extern "C" void R_SetTiltedSpanSource_ASM (const BYTE *flat);
|
|
||||||
extern "C" BYTE *ds_curcolormap, *ds_cursource, *ds_curtiltedsource;
|
|
||||||
#endif
|
|
||||||
void R_DrawSinglePlane (visplane_t *, fixed_t alpha, bool additive, bool masked);
|
void R_DrawSinglePlane (visplane_t *, fixed_t alpha, bool additive, bool masked);
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -220,304 +211,22 @@ void R_MapPlane (int y, int x1)
|
||||||
|
|
||||||
distance = planeheight * yslope[y];
|
distance = planeheight * yslope[y];
|
||||||
|
|
||||||
ds_xstep = xs_ToFixed(32-ds_xbits, distance * xstepscale);
|
DrawerContext::SetSpanXStep(xs_ToFixed(32 - DrawerContext::SpanXBits(), distance * xstepscale));
|
||||||
ds_ystep = xs_ToFixed(32-ds_ybits, distance * ystepscale);
|
DrawerContext::SetSpanYStep(xs_ToFixed(32 - DrawerContext::SpanYBits(), distance * ystepscale));
|
||||||
ds_xfrac = xs_ToFixed(32-ds_xbits, distance * basexfrac) + pviewx;
|
DrawerContext::SetSpanXFrac(xs_ToFixed(32 - DrawerContext::SpanXBits(), distance * basexfrac) + pviewx);
|
||||||
ds_yfrac = xs_ToFixed(32-ds_ybits, distance * baseyfrac) + pviewy;
|
DrawerContext::SetSpanYFrac(xs_ToFixed(32 - DrawerContext::SpanYBits(), distance * baseyfrac) + pviewy);
|
||||||
|
|
||||||
if (plane_shade)
|
if (plane_shade)
|
||||||
{
|
{
|
||||||
// Determine lighting based on the span's distance from the viewer.
|
// Determine lighting based on the span's distance from the viewer.
|
||||||
R_SetDSColorMapLight(basecolormap, GlobVis * fabs(CenterY - y), planeshade);
|
DrawerContext::SetSpanLight(basecolormap, GlobVis * fabs(CenterY - y), planeshade);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef X86_ASM
|
DrawerContext::SetSpanY(y);
|
||||||
if (!r_swtruecolor && ds_colormap != ds_curcolormap)
|
DrawerContext::SetSpanX1(x1);
|
||||||
R_SetSpanColormap_ASM (ds_colormap);
|
DrawerContext::SetSpanX2(x2);
|
||||||
#endif
|
|
||||||
|
|
||||||
ds_y = y;
|
DrawerContext::DrawSpan();
|
||||||
ds_x1 = x1;
|
|
||||||
ds_x2 = x2;
|
|
||||||
|
|
||||||
spanfunc ();
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// R_CalcTiltedLighting
|
|
||||||
//
|
|
||||||
// Calculates the lighting for one row of a tilted plane. If the definition
|
|
||||||
// of GETPALOOKUP changes, this needs to change, too.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
void R_CalcTiltedLighting (double lval, double lend, int width)
|
|
||||||
{
|
|
||||||
double lstep;
|
|
||||||
BYTE *lightfiller;
|
|
||||||
BYTE *basecolormapdata = basecolormap->Maps;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
if (width == 0 || lval == lend)
|
|
||||||
{ // Constant lighting
|
|
||||||
lightfiller = basecolormapdata + (GETPALOOKUP(lval, planeshade) << COLORMAPSHIFT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lstep = (lend - lval) / width;
|
|
||||||
if (lval >= MAXLIGHTVIS)
|
|
||||||
{ // lval starts "too bright".
|
|
||||||
lightfiller = basecolormapdata + (GETPALOOKUP(lval, planeshade) << COLORMAPSHIFT);
|
|
||||||
for (; i <= width && lval >= MAXLIGHTVIS; ++i)
|
|
||||||
{
|
|
||||||
tiltlighting[i] = lightfiller;
|
|
||||||
lval += lstep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lend >= MAXLIGHTVIS)
|
|
||||||
{ // lend ends "too bright".
|
|
||||||
lightfiller = basecolormapdata + (GETPALOOKUP(lend, planeshade) << COLORMAPSHIFT);
|
|
||||||
for (; width > i && lend >= MAXLIGHTVIS; --width)
|
|
||||||
{
|
|
||||||
tiltlighting[width] = lightfiller;
|
|
||||||
lend -= lstep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (width > 0)
|
|
||||||
{
|
|
||||||
lval = FIXED2DBL(planeshade) - lval;
|
|
||||||
lend = FIXED2DBL(planeshade) - lend;
|
|
||||||
lstep = (lend - lval) / width;
|
|
||||||
if (lstep < 0)
|
|
||||||
{ // Going from dark to light
|
|
||||||
if (lval < 1.)
|
|
||||||
{ // All bright
|
|
||||||
lightfiller = basecolormapdata;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (lval >= NUMCOLORMAPS)
|
|
||||||
{ // Starts beyond the dark end
|
|
||||||
BYTE *clight = basecolormapdata + ((NUMCOLORMAPS-1) << COLORMAPSHIFT);
|
|
||||||
while (lval >= NUMCOLORMAPS && i <= width)
|
|
||||||
{
|
|
||||||
tiltlighting[i++] = clight;
|
|
||||||
lval += lstep;
|
|
||||||
}
|
|
||||||
if (i > width)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while (i <= width && lval >= 0)
|
|
||||||
{
|
|
||||||
tiltlighting[i++] = basecolormapdata + (xs_ToInt(lval) << COLORMAPSHIFT);
|
|
||||||
lval += lstep;
|
|
||||||
}
|
|
||||||
lightfiller = basecolormapdata;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // Going from light to dark
|
|
||||||
if (lval >= (NUMCOLORMAPS-1))
|
|
||||||
{ // All dark
|
|
||||||
lightfiller = basecolormapdata + ((NUMCOLORMAPS-1) << COLORMAPSHIFT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (lval < 0 && i <= width)
|
|
||||||
{
|
|
||||||
tiltlighting[i++] = basecolormapdata;
|
|
||||||
lval += lstep;
|
|
||||||
}
|
|
||||||
if (i > width)
|
|
||||||
return;
|
|
||||||
while (i <= width && lval < (NUMCOLORMAPS-1))
|
|
||||||
{
|
|
||||||
tiltlighting[i++] = basecolormapdata + (xs_ToInt(lval) << COLORMAPSHIFT);
|
|
||||||
lval += lstep;
|
|
||||||
}
|
|
||||||
lightfiller = basecolormapdata + ((NUMCOLORMAPS-1) << COLORMAPSHIFT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (; i <= width; i++)
|
|
||||||
{
|
|
||||||
tiltlighting[i] = lightfiller;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // extern "C"
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// R_MapTiltedPlane
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void R_MapTiltedPlane_C (int y, int x1)
|
|
||||||
{
|
|
||||||
int x2 = spanend[y];
|
|
||||||
int width = x2 - x1;
|
|
||||||
double iz, uz, vz;
|
|
||||||
BYTE *fb;
|
|
||||||
DWORD u, v;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
iz = plane_sz[2] + plane_sz[1]*(centery-y) + plane_sz[0]*(x1-centerx);
|
|
||||||
|
|
||||||
// Lighting is simple. It's just linear interpolation from start to end
|
|
||||||
if (plane_shade)
|
|
||||||
{
|
|
||||||
uz = (iz + plane_sz[0]*width) * planelightfloat;
|
|
||||||
vz = iz * planelightfloat;
|
|
||||||
R_CalcTiltedLighting (vz, uz, width);
|
|
||||||
}
|
|
||||||
|
|
||||||
uz = plane_su[2] + plane_su[1]*(centery-y) + plane_su[0]*(x1-centerx);
|
|
||||||
vz = plane_sv[2] + plane_sv[1]*(centery-y) + plane_sv[0]*(x1-centerx);
|
|
||||||
|
|
||||||
fb = ylookup[y] + x1 + dc_destorg;
|
|
||||||
|
|
||||||
BYTE vshift = 32 - ds_ybits;
|
|
||||||
BYTE ushift = vshift - ds_xbits;
|
|
||||||
int umask = ((1 << ds_xbits) - 1) << ds_ybits;
|
|
||||||
|
|
||||||
#if 0 // The "perfect" reference version of this routine. Pretty slow.
|
|
||||||
// Use it only to see how things are supposed to look.
|
|
||||||
i = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
double z = 1.f/iz;
|
|
||||||
|
|
||||||
u = SQWORD(uz*z) + pviewx;
|
|
||||||
v = SQWORD(vz*z) + pviewy;
|
|
||||||
R_SetDSColorMapLight(tiltlighting[i], 0, 0);
|
|
||||||
fb[i++] = ds_colormap[ds_source[(v >> vshift) | ((u >> ushift) & umask)]];
|
|
||||||
iz += plane_sz[0];
|
|
||||||
uz += plane_su[0];
|
|
||||||
vz += plane_sv[0];
|
|
||||||
} while (--width >= 0);
|
|
||||||
#else
|
|
||||||
//#define SPANSIZE 32
|
|
||||||
//#define INVSPAN 0.03125f
|
|
||||||
//#define SPANSIZE 8
|
|
||||||
//#define INVSPAN 0.125f
|
|
||||||
#define SPANSIZE 16
|
|
||||||
#define INVSPAN 0.0625f
|
|
||||||
|
|
||||||
double startz = 1.f/iz;
|
|
||||||
double startu = uz*startz;
|
|
||||||
double startv = vz*startz;
|
|
||||||
double izstep, uzstep, vzstep;
|
|
||||||
|
|
||||||
izstep = plane_sz[0] * SPANSIZE;
|
|
||||||
uzstep = plane_su[0] * SPANSIZE;
|
|
||||||
vzstep = plane_sv[0] * SPANSIZE;
|
|
||||||
x1 = 0;
|
|
||||||
width++;
|
|
||||||
|
|
||||||
while (width >= SPANSIZE)
|
|
||||||
{
|
|
||||||
iz += izstep;
|
|
||||||
uz += uzstep;
|
|
||||||
vz += vzstep;
|
|
||||||
|
|
||||||
double endz = 1.f/iz;
|
|
||||||
double endu = uz*endz;
|
|
||||||
double endv = vz*endz;
|
|
||||||
DWORD stepu = SQWORD((endu - startu) * INVSPAN);
|
|
||||||
DWORD stepv = SQWORD((endv - startv) * INVSPAN);
|
|
||||||
u = SQWORD(startu) + pviewx;
|
|
||||||
v = SQWORD(startv) + pviewy;
|
|
||||||
|
|
||||||
for (i = SPANSIZE-1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
fb[x1] = *(tiltlighting[x1] + ds_source[(v >> vshift) | ((u >> ushift) & umask)]);
|
|
||||||
x1++;
|
|
||||||
u += stepu;
|
|
||||||
v += stepv;
|
|
||||||
}
|
|
||||||
startu = endu;
|
|
||||||
startv = endv;
|
|
||||||
width -= SPANSIZE;
|
|
||||||
}
|
|
||||||
if (width > 0)
|
|
||||||
{
|
|
||||||
if (width == 1)
|
|
||||||
{
|
|
||||||
u = SQWORD(startu);
|
|
||||||
v = SQWORD(startv);
|
|
||||||
fb[x1] = *(tiltlighting[x1] + ds_source[(v >> vshift) | ((u >> ushift) & umask)]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
double left = width;
|
|
||||||
iz += plane_sz[0] * left;
|
|
||||||
uz += plane_su[0] * left;
|
|
||||||
vz += plane_sv[0] * left;
|
|
||||||
|
|
||||||
double endz = 1.f/iz;
|
|
||||||
double endu = uz*endz;
|
|
||||||
double endv = vz*endz;
|
|
||||||
left = 1.f/left;
|
|
||||||
DWORD stepu = SQWORD((endu - startu) * left);
|
|
||||||
DWORD stepv = SQWORD((endv - startv) * left);
|
|
||||||
u = SQWORD(startu) + pviewx;
|
|
||||||
v = SQWORD(startv) + pviewy;
|
|
||||||
|
|
||||||
for (; width != 0; width--)
|
|
||||||
{
|
|
||||||
fb[x1] = *(tiltlighting[x1] + ds_source[(v >> vshift) | ((u >> ushift) & umask)]);
|
|
||||||
x1++;
|
|
||||||
u += stepu;
|
|
||||||
v += stepv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_MapTiltedPlane_rgba (int y, int x1)
|
|
||||||
{
|
|
||||||
int x2 = spanend[y];
|
|
||||||
|
|
||||||
// Slopes are broken currently in master.
|
|
||||||
// Until R_DrawTiltedPlane is fixed we are just going to fill with a solid color.
|
|
||||||
|
|
||||||
uint32_t *source = (uint32_t*)ds_source;
|
|
||||||
int source_width = 1 << ds_xbits;
|
|
||||||
int source_height = 1 << ds_ybits;
|
|
||||||
|
|
||||||
uint32_t *dest = ylookup[y] + x1 + (uint32_t*)dc_destorg;
|
|
||||||
|
|
||||||
int count = x2 - x1 + 1;
|
|
||||||
while (count > 0)
|
|
||||||
{
|
|
||||||
*(dest++) = source[0];
|
|
||||||
count--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// R_MapColoredPlane
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void R_MapColoredPlane_C (int y, int x1)
|
|
||||||
{
|
|
||||||
memset (ylookup[y] + x1 + dc_destorg, ds_color, spanend[y] - x1 + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_MapColoredPlane_rgba(int y, int x1)
|
|
||||||
{
|
|
||||||
uint32_t *dest = ylookup[y] + x1 + (uint32_t*)dc_destorg;
|
|
||||||
int count = (spanend[y] - x1 + 1);
|
|
||||||
uint32_t light = calc_light_multiplier(ds_light);
|
|
||||||
uint32_t color = shade_pal_index_simple(ds_color, light);
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
dest[i] = color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1014,7 +723,7 @@ static void R_DrawSky (visplane_t *pl)
|
||||||
rw_offset = 0;
|
rw_offset = 0;
|
||||||
|
|
||||||
frontyScale = rw_pic->Scale.Y;
|
frontyScale = rw_pic->Scale.Y;
|
||||||
dc_texturemid = skymid * frontyScale;
|
DrawerContext::SetTextureMid(skymid * frontyScale);
|
||||||
|
|
||||||
if (1 << frontskytex->HeightBits == frontskytex->GetHeight())
|
if (1 << frontskytex->HeightBits == frontskytex->GetHeight())
|
||||||
{ // The texture tiles nicely
|
{ // The texture tiles nicely
|
||||||
|
@ -1023,8 +732,8 @@ static void R_DrawSky (visplane_t *pl)
|
||||||
lastskycol[x] = 0xffffffff;
|
lastskycol[x] = 0xffffffff;
|
||||||
lastskycol_bgra[x] = 0xffffffff;
|
lastskycol_bgra[x] = 0xffffffff;
|
||||||
}
|
}
|
||||||
wallscan (pl->left, pl->right, (short *)pl->top, (short *)pl->bottom, swall, lwall,
|
DrawerContext::DrawWall (pl->left, pl->right, (short *)pl->top, (short *)pl->bottom, swall, lwall,
|
||||||
frontyScale, backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns);
|
frontyScale, rw_pic, rw_offset, backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // The texture does not tile nicely
|
{ // The texture does not tile nicely
|
||||||
|
@ -1047,7 +756,7 @@ static void R_DrawSkyStriped (visplane_t *pl)
|
||||||
if (topfrac < 0) topfrac += frontskytex->GetHeight();
|
if (topfrac < 0) topfrac += frontskytex->GetHeight();
|
||||||
yl = 0;
|
yl = 0;
|
||||||
yh = short((frontskytex->GetHeight() - topfrac) * frontyScale);
|
yh = short((frontskytex->GetHeight() - topfrac) * frontyScale);
|
||||||
dc_texturemid = topfrac - iscale * (1 - CenterY);
|
DrawerContext::SetTextureMid(topfrac - iscale * (1 - CenterY));
|
||||||
|
|
||||||
while (yl < viewheight)
|
while (yl < viewheight)
|
||||||
{
|
{
|
||||||
|
@ -1061,11 +770,11 @@ static void R_DrawSkyStriped (visplane_t *pl)
|
||||||
lastskycol[x] = 0xffffffff;
|
lastskycol[x] = 0xffffffff;
|
||||||
lastskycol_bgra[x] = 0xffffffff;
|
lastskycol_bgra[x] = 0xffffffff;
|
||||||
}
|
}
|
||||||
wallscan (pl->left, pl->right, top, bot, swall, lwall, rw_pic->Scale.Y,
|
DrawerContext::DrawWall(pl->left, pl->right, top, bot, swall, lwall, rw_pic->Scale.Y,
|
||||||
backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns);
|
rw_pic, rw_offset, backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns);
|
||||||
yl = yh;
|
yl = yh;
|
||||||
yh += drawheight;
|
yh += drawheight;
|
||||||
dc_texturemid = iscale * (centery-yl-1);
|
DrawerContext::SetTextureMid(iscale * (centery-yl-1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1086,7 +795,7 @@ int R_DrawPlanes ()
|
||||||
int i;
|
int i;
|
||||||
int vpcount = 0;
|
int vpcount = 0;
|
||||||
|
|
||||||
ds_color = 3;
|
DrawerContext::SetFlatColor(3);
|
||||||
|
|
||||||
for (i = 0; i < MAXVISPLANES; i++)
|
for (i = 0; i < MAXVISPLANES; i++)
|
||||||
{
|
{
|
||||||
|
@ -1111,7 +820,7 @@ void R_DrawHeightPlanes(double height)
|
||||||
visplane_t *pl;
|
visplane_t *pl;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ds_color = 3;
|
DrawerContext::SetFlatColor(3);
|
||||||
|
|
||||||
DVector3 oViewPos = ViewPos;
|
DVector3 oViewPos = ViewPos;
|
||||||
DAngle oViewAngle = ViewAngle;
|
DAngle oViewAngle = ViewAngle;
|
||||||
|
@ -1151,8 +860,8 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
|
||||||
|
|
||||||
if (r_drawflat)
|
if (r_drawflat)
|
||||||
{ // [RH] no texture mapping
|
{ // [RH] no texture mapping
|
||||||
ds_color += 4;
|
DrawerContext::SetFlatColor(DrawerContext::FlatColor() + 4);
|
||||||
R_MapVisPlane (pl, R_MapColoredPlane);
|
R_MapVisPlane (pl, [](int y, int x1) { DrawerContext::DrawColoredSpan(y, x1, spanend[y]); });
|
||||||
}
|
}
|
||||||
else if (pl->picnum == skyflatnum)
|
else if (pl->picnum == skyflatnum)
|
||||||
{ // sky flat
|
{ // sky flat
|
||||||
|
@ -1175,13 +884,9 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
|
||||||
{ // Don't waste time on a masked texture if it isn't really masked.
|
{ // Don't waste time on a masked texture if it isn't really masked.
|
||||||
masked = false;
|
masked = false;
|
||||||
}
|
}
|
||||||
R_SetupSpanBits(tex);
|
|
||||||
double xscale = pl->xform.xScale * tex->Scale.X;
|
double xscale = pl->xform.xScale * tex->Scale.X;
|
||||||
double yscale = pl->xform.yScale * tex->Scale.Y;
|
double yscale = pl->xform.yScale * tex->Scale.Y;
|
||||||
if (r_swtruecolor)
|
DrawerContext::SetSpanSource(tex);
|
||||||
ds_source = (const BYTE*)tex->GetPixelsBgra();
|
|
||||||
else
|
|
||||||
ds_source = tex->GetPixels();
|
|
||||||
|
|
||||||
basecolormap = pl->colormap;
|
basecolormap = pl->colormap;
|
||||||
planeshade = LIGHT2SHADE(pl->lightlevel);
|
planeshade = LIGHT2SHADE(pl->lightlevel);
|
||||||
|
@ -1544,13 +1249,13 @@ void R_DrawSkyPlane (visplane_t *pl)
|
||||||
bool fakefixed = false;
|
bool fakefixed = false;
|
||||||
if (fixedcolormap)
|
if (fixedcolormap)
|
||||||
{
|
{
|
||||||
R_SetColorMapLight(fixedcolormap, 0, 0);
|
DrawerContext::SetLight(fixedcolormap, 0, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fakefixed = true;
|
fakefixed = true;
|
||||||
fixedcolormap = &NormalLight;
|
fixedcolormap = &NormalLight;
|
||||||
R_SetColorMapLight(fixedcolormap, 0, 0);
|
DrawerContext::SetLight(fixedcolormap, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_DrawSky (pl);
|
R_DrawSky (pl);
|
||||||
|
@ -1567,13 +1272,6 @@ void R_DrawSkyPlane (visplane_t *pl)
|
||||||
|
|
||||||
void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked)
|
void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked)
|
||||||
{
|
{
|
||||||
#ifdef X86_ASM
|
|
||||||
if (!r_swtruecolor && ds_source != ds_cursource)
|
|
||||||
{
|
|
||||||
R_SetSpanSource_ASM (ds_source);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (alpha <= 0)
|
if (alpha <= 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -1583,8 +1281,8 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t
|
||||||
double xstep, ystep, leftxfrac, leftyfrac, rightxfrac, rightyfrac;
|
double xstep, ystep, leftxfrac, leftyfrac, rightxfrac, rightyfrac;
|
||||||
double x;
|
double x;
|
||||||
|
|
||||||
xscale = xs_ToFixed(32 - ds_xbits, _xscale);
|
xscale = xs_ToFixed(32 - DrawerContext::SpanXBits(), _xscale);
|
||||||
yscale = xs_ToFixed(32 - ds_ybits, _yscale);
|
yscale = xs_ToFixed(32 - DrawerContext::SpanYBits(), _yscale);
|
||||||
if (planeang != 0)
|
if (planeang != 0)
|
||||||
{
|
{
|
||||||
double cosine = cos(planeang), sine = sin(planeang);
|
double cosine = cos(planeang), sine = sin(planeang);
|
||||||
|
@ -1631,15 +1329,14 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t
|
||||||
planeheight = fabs(pl->height.Zat0() - ViewPos.Z);
|
planeheight = fabs(pl->height.Zat0() - ViewPos.Z);
|
||||||
|
|
||||||
GlobVis = r_FloorVisibility / planeheight;
|
GlobVis = r_FloorVisibility / planeheight;
|
||||||
ds_light = 0;
|
|
||||||
if (fixedlightlev >= 0)
|
if (fixedlightlev >= 0)
|
||||||
{
|
{
|
||||||
R_SetDSColorMapLight(basecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
DrawerContext::SetSpanLight(basecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
||||||
plane_shade = false;
|
plane_shade = false;
|
||||||
}
|
}
|
||||||
else if (fixedcolormap)
|
else if (fixedcolormap)
|
||||||
{
|
{
|
||||||
R_SetDSColorMapLight(fixedcolormap, 0, 0);
|
DrawerContext::SetSpanLight(fixedcolormap, 0, 0);
|
||||||
plane_shade = false;
|
plane_shade = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1647,61 +1344,8 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t
|
||||||
plane_shade = true;
|
plane_shade = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spanfunc != R_FillSpan)
|
DrawerContext::SetSpanStyle(alpha, additive, masked);
|
||||||
{
|
|
||||||
if (masked)
|
|
||||||
{
|
|
||||||
if (alpha < OPAQUE || additive)
|
|
||||||
{
|
|
||||||
if (!additive)
|
|
||||||
{
|
|
||||||
spanfunc = R_DrawSpanMaskedTranslucent;
|
|
||||||
dc_srcblend = Col2RGB8[alpha>>10];
|
|
||||||
dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10];
|
|
||||||
dc_srcalpha = alpha;
|
|
||||||
dc_destalpha = OPAQUE - alpha;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spanfunc = R_DrawSpanMaskedAddClamp;
|
|
||||||
dc_srcblend = Col2RGB8_LessPrecision[alpha>>10];
|
|
||||||
dc_destblend = Col2RGB8_LessPrecision[FRACUNIT>>10];
|
|
||||||
dc_srcalpha = alpha;
|
|
||||||
dc_destalpha = OPAQUE - alpha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spanfunc = R_DrawSpanMasked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (alpha < OPAQUE || additive)
|
|
||||||
{
|
|
||||||
if (!additive)
|
|
||||||
{
|
|
||||||
spanfunc = R_DrawSpanTranslucent;
|
|
||||||
dc_srcblend = Col2RGB8[alpha>>10];
|
|
||||||
dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10];
|
|
||||||
dc_srcalpha = alpha;
|
|
||||||
dc_destalpha = OPAQUE - alpha;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spanfunc = R_DrawSpanAddClamp;
|
|
||||||
dc_srcblend = Col2RGB8_LessPrecision[alpha>>10];
|
|
||||||
dc_destblend = Col2RGB8_LessPrecision[FRACUNIT>>10];
|
|
||||||
dc_srcalpha = alpha;
|
|
||||||
dc_destalpha = OPAQUE - alpha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spanfunc = R_DrawSpan;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
R_MapVisPlane (pl, R_MapPlane);
|
R_MapVisPlane (pl, R_MapPlane);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1733,14 +1377,14 @@ void R_DrawTiltedPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lxscale = _xscale * ifloatpow2[ds_xbits];
|
lxscale = _xscale * ifloatpow2[DrawerContext::SpanXBits()];
|
||||||
lyscale = _yscale * ifloatpow2[ds_ybits];
|
lyscale = _yscale * ifloatpow2[DrawerContext::SpanYBits()];
|
||||||
xscale = 64.f / lxscale;
|
xscale = 64.f / lxscale;
|
||||||
yscale = 64.f / lyscale;
|
yscale = 64.f / lyscale;
|
||||||
zeroheight = pl->height.ZatPoint(ViewPos);
|
zeroheight = pl->height.ZatPoint(ViewPos);
|
||||||
|
|
||||||
pviewx = xs_ToFixed(32 - ds_xbits, pl->xform.xOffs * pl->xform.xScale);
|
pviewx = xs_ToFixed(32 - DrawerContext::SpanXBits(), pl->xform.xOffs * pl->xform.xScale);
|
||||||
pviewy = xs_ToFixed(32 - ds_ybits, pl->xform.yOffs * pl->xform.yScale);
|
pviewy = xs_ToFixed(32 - DrawerContext::SpanYBits(), pl->xform.yOffs * pl->xform.yScale);
|
||||||
planeang = (pl->xform.Angle + pl->xform.baseAngle).Radians();
|
planeang = (pl->xform.Angle + pl->xform.baseAngle).Radians();
|
||||||
|
|
||||||
// p is the texture origin in view space
|
// p is the texture origin in view space
|
||||||
|
@ -1810,42 +1454,22 @@ void R_DrawTiltedPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t
|
||||||
|
|
||||||
if (fixedlightlev >= 0)
|
if (fixedlightlev >= 0)
|
||||||
{
|
{
|
||||||
R_SetDSColorMapLight(basecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
DrawerContext::SetSpanLight(basecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
||||||
plane_shade = false;
|
plane_shade = false;
|
||||||
}
|
}
|
||||||
else if (fixedcolormap)
|
else if (fixedcolormap)
|
||||||
{
|
{
|
||||||
R_SetDSColorMapLight(fixedcolormap, 0, 0);
|
DrawerContext::SetSpanLight(fixedcolormap, 0, 0);
|
||||||
plane_shade = false;
|
plane_shade = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
R_SetDSColorMapLight(basecolormap, 0, 0);
|
DrawerContext::SetSpanLight(basecolormap, 0, 0);
|
||||||
plane_shade = true;
|
plane_shade = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!plane_shade)
|
DrawerContext::SetTiltedSpanState(plane_sz, plane_su, plane_sv, plane_shade, planelightfloat, pviewx, pviewy);
|
||||||
{
|
R_MapVisPlane (pl, [](int y, int x1) { DrawerContext::DrawTiltedSpan(y, x1, spanend[y]); });
|
||||||
for (int i = 0; i < viewwidth; ++i)
|
|
||||||
{
|
|
||||||
tiltlighting[i] = ds_colormap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(X86_ASM)
|
|
||||||
if (!r_swtruecolor)
|
|
||||||
{
|
|
||||||
if (ds_source != ds_curtiltedsource)
|
|
||||||
R_SetTiltedSpanSource_ASM(ds_source);
|
|
||||||
R_MapVisPlane(pl, R_DrawTiltedPlane_ASM);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
R_MapVisPlane(pl, R_MapTiltedPlane);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
R_MapVisPlane (pl, R_MapTiltedPlane);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -93,14 +93,6 @@ void R_DrawNormalPlane (visplane_t *pl, double xscale, double yscale, fixed_t al
|
||||||
void R_DrawTiltedPlane (visplane_t *pl, double xscale, double yscale, fixed_t alpha, bool additive, bool masked);
|
void R_DrawTiltedPlane (visplane_t *pl, double xscale, double yscale, fixed_t alpha, bool additive, bool masked);
|
||||||
void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1));
|
void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1));
|
||||||
|
|
||||||
extern void(*R_MapColoredPlane)(int y, int x1);
|
|
||||||
extern void(*R_MapTiltedPlane)(int y, int x1);
|
|
||||||
|
|
||||||
void R_MapTiltedPlane_C(int y, int x1);
|
|
||||||
void R_MapTiltedPlane_rgba(int y, int x);
|
|
||||||
void R_MapColoredPlane_C(int y, int x1);
|
|
||||||
void R_MapColoredPlane_rgba(int y, int x1);
|
|
||||||
|
|
||||||
visplane_t *R_FindPlane
|
visplane_t *R_FindPlane
|
||||||
( const secplane_t &height,
|
( const secplane_t &height,
|
||||||
FTextureID picnum,
|
FTextureID picnum,
|
||||||
|
|
541
src/r_segs.cpp
541
src/r_segs.cpp
|
@ -52,6 +52,7 @@
|
||||||
#include "r_3dfloors.h"
|
#include "r_3dfloors.h"
|
||||||
#include "v_palette.h"
|
#include "v_palette.h"
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
|
#include "r_drawer_context.h"
|
||||||
|
|
||||||
#define WALLYREPEAT 8
|
#define WALLYREPEAT 8
|
||||||
|
|
||||||
|
@ -172,19 +173,19 @@ CVAR(Bool, r_drawmirrors, true, 0)
|
||||||
float *MaskedSWall;
|
float *MaskedSWall;
|
||||||
float MaskedScaleY;
|
float MaskedScaleY;
|
||||||
|
|
||||||
static void BlastMaskedColumn (void (*blastfunc)(const BYTE *pixels, const FTexture::Span *spans), FTexture *tex)
|
static void BlastMaskedColumn (int x, void (*blastfunc)(int x, const BYTE *pixels, const FTexture::Span *spans), FTexture *tex)
|
||||||
{
|
{
|
||||||
// calculate lighting
|
// calculate lighting
|
||||||
if (fixedcolormap == NULL && fixedlightlev < 0)
|
if (fixedcolormap == NULL && fixedlightlev < 0)
|
||||||
{
|
{
|
||||||
R_SetColorMapLight(basecolormap, rw_light, wallshade);
|
DrawerContext::SetLight(basecolormap, rw_light, wallshade);
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_iscale = xs_Fix<16>::ToFix(MaskedSWall[dc_x] * MaskedScaleY);
|
DrawerContext::SetTextureStep(xs_Fix<16>::ToFix(MaskedSWall[x] * MaskedScaleY));
|
||||||
if (sprflipvert)
|
if (sprflipvert)
|
||||||
sprtopscreen = CenterY + dc_texturemid * spryscale;
|
sprtopscreen = CenterY + DrawerContext::TextureMid() * spryscale;
|
||||||
else
|
else
|
||||||
sprtopscreen = CenterY - dc_texturemid * spryscale;
|
sprtopscreen = CenterY - DrawerContext::TextureMid() * spryscale;
|
||||||
|
|
||||||
// killough 1/25/98: here's where Medusa came in, because
|
// killough 1/25/98: here's where Medusa came in, because
|
||||||
// it implicitly assumed that the column was all one patch.
|
// it implicitly assumed that the column was all one patch.
|
||||||
|
@ -194,10 +195,12 @@ static void BlastMaskedColumn (void (*blastfunc)(const BYTE *pixels, const FText
|
||||||
// the Medusa effect. The fix is to construct true columns
|
// the Medusa effect. The fix is to construct true columns
|
||||||
// when forming multipatched textures (see r_data.c).
|
// when forming multipatched textures (see r_data.c).
|
||||||
|
|
||||||
|
DrawerContext::SetMaskedColumnState(mfloorclip, mceilingclip, spryscale, sprtopscreen, sprflipvert);
|
||||||
|
|
||||||
// draw the texture
|
// draw the texture
|
||||||
const FTexture::Span *spans;
|
const FTexture::Span *spans;
|
||||||
const BYTE *pixels = tex->GetColumn (maskedtexturecol[dc_x] >> FRACBITS, &spans);
|
const BYTE *pixels = tex->GetColumn (maskedtexturecol[x] >> FRACBITS, &spans);
|
||||||
blastfunc (pixels, spans);
|
blastfunc (x, pixels, spans);
|
||||||
rw_light += rw_lightstep;
|
rw_light += rw_lightstep;
|
||||||
spryscale += rw_scalestep;
|
spryscale += rw_scalestep;
|
||||||
}
|
}
|
||||||
|
@ -243,7 +246,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
||||||
// [RH] modified because we don't use user-definable translucency maps
|
// [RH] modified because we don't use user-definable translucency maps
|
||||||
ESPSResult drawmode;
|
ESPSResult drawmode;
|
||||||
|
|
||||||
drawmode = R_SetPatchStyle (LegacyRenderStyles[curline->linedef->flags & ML_ADDTRANS ? STYLE_Add : STYLE_Translucent],
|
drawmode = DrawerContext::SetPatchStyle (LegacyRenderStyles[curline->linedef->flags & ML_ADDTRANS ? STYLE_Add : STYLE_Translucent],
|
||||||
(float)MIN(curline->linedef->alpha, 1.), 0, 0);
|
(float)MIN(curline->linedef->alpha, 1.), 0, 0);
|
||||||
|
|
||||||
if ((drawmode == DontDraw && !ds->bFogBoundary && !ds->bFakeBoundary))
|
if ((drawmode == DontDraw && !ds->bFogBoundary && !ds->bFakeBoundary))
|
||||||
|
@ -295,7 +298,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
||||||
// [RH] Draw fog partition
|
// [RH] Draw fog partition
|
||||||
if (ds->bFogBoundary)
|
if (ds->bFogBoundary)
|
||||||
{
|
{
|
||||||
R_DrawFogBoundary (x1, x2, mceilingclip, mfloorclip);
|
DrawerContext::DrawFogBoundary (x1, x2, mceilingclip, mfloorclip);
|
||||||
if (ds->maskedtexturecol == -1)
|
if (ds->maskedtexturecol == -1)
|
||||||
{
|
{
|
||||||
goto clearfog;
|
goto clearfog;
|
||||||
|
@ -313,9 +316,9 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
||||||
rw_scalestep = ds->iscalestep;
|
rw_scalestep = ds->iscalestep;
|
||||||
|
|
||||||
if (fixedlightlev >= 0)
|
if (fixedlightlev >= 0)
|
||||||
R_SetColorMapLight(basecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
DrawerContext::SetLight(basecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
||||||
else if (fixedcolormap != NULL)
|
else if (fixedcolormap != NULL)
|
||||||
R_SetColorMapLight(fixedcolormap, 0, 0);
|
DrawerContext::SetLight(fixedcolormap, 0, 0);
|
||||||
|
|
||||||
// find positioning
|
// find positioning
|
||||||
texheight = tex->GetScaledHeightDouble();
|
texheight = tex->GetScaledHeightDouble();
|
||||||
|
@ -326,11 +329,11 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
||||||
}
|
}
|
||||||
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
|
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
|
||||||
{
|
{
|
||||||
dc_texturemid = MAX(frontsector->GetPlaneTexZ(sector_t::floor), backsector->GetPlaneTexZ(sector_t::floor)) + texheight;
|
DrawerContext::SetTextureMid(MAX(frontsector->GetPlaneTexZ(sector_t::floor), backsector->GetPlaneTexZ(sector_t::floor)) + texheight);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dc_texturemid = MIN(frontsector->GetPlaneTexZ(sector_t::ceiling), backsector->GetPlaneTexZ(sector_t::ceiling));
|
DrawerContext::SetTextureMid(MIN(frontsector->GetPlaneTexZ(sector_t::ceiling), backsector->GetPlaneTexZ(sector_t::ceiling)));
|
||||||
}
|
}
|
||||||
|
|
||||||
rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid);
|
rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid);
|
||||||
|
@ -349,21 +352,21 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
||||||
{
|
{
|
||||||
// rowoffset is added before the multiply so that the masked texture will
|
// rowoffset is added before the multiply so that the masked texture will
|
||||||
// still be positioned in world units rather than texels.
|
// still be positioned in world units rather than texels.
|
||||||
dc_texturemid += rowoffset - ViewPos.Z;
|
DrawerContext::SetTextureMid(DrawerContext::TextureMid() + rowoffset - ViewPos.Z);
|
||||||
textop = dc_texturemid;
|
textop = DrawerContext::TextureMid();
|
||||||
dc_texturemid *= MaskedScaleY;
|
DrawerContext::SetTextureMid(DrawerContext::TextureMid() * MaskedScaleY);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// rowoffset is added outside the multiply so that it positions the texture
|
// rowoffset is added outside the multiply so that it positions the texture
|
||||||
// by texels instead of world units.
|
// by texels instead of world units.
|
||||||
textop = dc_texturemid + rowoffset / MaskedScaleY - ViewPos.Z;
|
textop = DrawerContext::TextureMid() + rowoffset / MaskedScaleY - ViewPos.Z;
|
||||||
dc_texturemid = (dc_texturemid - ViewPos.Z) * MaskedScaleY + rowoffset;
|
DrawerContext::SetTextureMid((DrawerContext::TextureMid() - ViewPos.Z) * MaskedScaleY + rowoffset);
|
||||||
}
|
}
|
||||||
if (sprflipvert)
|
if (sprflipvert)
|
||||||
{
|
{
|
||||||
MaskedScaleY = -MaskedScaleY;
|
MaskedScaleY = -MaskedScaleY;
|
||||||
dc_texturemid -= tex->GetHeight() << FRACBITS;
|
DrawerContext::SetTextureMid(DrawerContext::TextureMid() - tex->GetHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
// [RH] Don't bother drawing segs that are completely offscreen
|
// [RH] Don't bother drawing segs that are completely offscreen
|
||||||
|
@ -438,9 +441,9 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
||||||
// draw the columns one at a time
|
// draw the columns one at a time
|
||||||
if (drawmode == DoDraw0)
|
if (drawmode == DoDraw0)
|
||||||
{
|
{
|
||||||
for (dc_x = x1; dc_x < x2; ++dc_x)
|
for (int x = x1; x < x2; ++x)
|
||||||
{
|
{
|
||||||
BlastMaskedColumn (R_DrawMaskedColumn, tex);
|
BlastMaskedColumn (x, DrawerContext::DrawMaskedColumn, tex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -451,29 +454,29 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
||||||
if (x1 >= x2)
|
if (x1 >= x2)
|
||||||
goto clearfog;
|
goto clearfog;
|
||||||
|
|
||||||
dc_x = x1;
|
int x = x1;
|
||||||
|
|
||||||
while ((dc_x < stop) && (dc_x & 3))
|
while ((x < stop) && (x & 3))
|
||||||
{
|
{
|
||||||
BlastMaskedColumn (R_DrawMaskedColumn, tex);
|
BlastMaskedColumn (x, DrawerContext::DrawMaskedColumn, tex);
|
||||||
dc_x++;
|
x++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (dc_x < stop)
|
while (x < stop)
|
||||||
{
|
{
|
||||||
rt_initcols(nullptr);
|
DrawerContext::RtInitCols(nullptr);
|
||||||
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex); dc_x++;
|
BlastMaskedColumn (x, DrawerContext::DrawMaskedColumnHoriz, tex);
|
||||||
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex); dc_x++;
|
BlastMaskedColumn (x + 1, DrawerContext::DrawMaskedColumnHoriz, tex);
|
||||||
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex); dc_x++;
|
BlastMaskedColumn (x + 2, DrawerContext::DrawMaskedColumnHoriz, tex);
|
||||||
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex);
|
BlastMaskedColumn (x + 3, DrawerContext::DrawMaskedColumnHoriz, tex);
|
||||||
rt_draw4cols (dc_x - 3);
|
DrawerContext::DrawRt4cols (x);
|
||||||
dc_x++;
|
x += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (dc_x < x2)
|
while (x < x2)
|
||||||
{
|
{
|
||||||
BlastMaskedColumn (R_DrawMaskedColumn, tex);
|
BlastMaskedColumn (x, DrawerContext::DrawMaskedColumn, tex);
|
||||||
dc_x++;
|
x++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -483,13 +486,13 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
||||||
{
|
{
|
||||||
// rowoffset is added before the multiply so that the masked texture will
|
// rowoffset is added before the multiply so that the masked texture will
|
||||||
// still be positioned in world units rather than texels.
|
// still be positioned in world units rather than texels.
|
||||||
dc_texturemid = (dc_texturemid - ViewPos.Z + rowoffset) * MaskedScaleY;
|
DrawerContext::SetTextureMid((DrawerContext::TextureMid() - ViewPos.Z + rowoffset) * MaskedScaleY);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// rowoffset is added outside the multiply so that it positions the texture
|
// rowoffset is added outside the multiply so that it positions the texture
|
||||||
// by texels instead of world units.
|
// by texels instead of world units.
|
||||||
dc_texturemid = (dc_texturemid - ViewPos.Z) * MaskedScaleY + rowoffset;
|
DrawerContext::SetTextureMid((DrawerContext::TextureMid() - ViewPos.Z) * MaskedScaleY + rowoffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
WallC.sz1 = ds->sz1;
|
WallC.sz1 = ds->sz1;
|
||||||
|
@ -535,7 +538,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
||||||
}
|
}
|
||||||
|
|
||||||
clearfog:
|
clearfog:
|
||||||
R_FinishSetPatchStyle ();
|
DrawerContext::FinishSetPatchStyle ();
|
||||||
if (ds->bFakeBoundary & 3)
|
if (ds->bFakeBoundary & 3)
|
||||||
{
|
{
|
||||||
R_RenderFakeWallRange(ds, x1, x2);
|
R_RenderFakeWallRange(ds, x1, x2);
|
||||||
|
@ -567,11 +570,11 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover)
|
||||||
|
|
||||||
fixed_t Alpha = Scale(rover->alpha, OPAQUE, 255);
|
fixed_t Alpha = Scale(rover->alpha, OPAQUE, 255);
|
||||||
ESPSResult drawmode;
|
ESPSResult drawmode;
|
||||||
drawmode = R_SetPatchStyle (LegacyRenderStyles[rover->flags & FF_ADDITIVETRANS ? STYLE_Add : STYLE_Translucent],
|
drawmode = DrawerContext::SetPatchStyle (LegacyRenderStyles[rover->flags & FF_ADDITIVETRANS ? STYLE_Add : STYLE_Translucent],
|
||||||
Alpha, 0, 0);
|
Alpha, 0, 0);
|
||||||
|
|
||||||
if(drawmode == DontDraw) {
|
if(drawmode == DontDraw) {
|
||||||
R_FinishSetPatchStyle();
|
DrawerContext::FinishSetPatchStyle();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,26 +616,26 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover)
|
||||||
{
|
{
|
||||||
rowoffset += rw_pic->GetHeight();
|
rowoffset += rw_pic->GetHeight();
|
||||||
}
|
}
|
||||||
dc_texturemid = (planez - ViewPos.Z) * yscale;
|
DrawerContext::SetTextureMid((planez - ViewPos.Z) * yscale);
|
||||||
if (rw_pic->bWorldPanning)
|
if (rw_pic->bWorldPanning)
|
||||||
{
|
{
|
||||||
// rowoffset is added before the multiply so that the masked texture will
|
// rowoffset is added before the multiply so that the masked texture will
|
||||||
// still be positioned in world units rather than texels.
|
// still be positioned in world units rather than texels.
|
||||||
|
|
||||||
dc_texturemid = dc_texturemid + rowoffset * yscale;
|
DrawerContext::SetTextureMid(DrawerContext::TextureMid() + rowoffset * yscale);
|
||||||
rw_offset = xs_RoundToInt(rw_offset * xscale);
|
rw_offset = xs_RoundToInt(rw_offset * xscale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// rowoffset is added outside the multiply so that it positions the texture
|
// rowoffset is added outside the multiply so that it positions the texture
|
||||||
// by texels instead of world units.
|
// by texels instead of world units.
|
||||||
dc_texturemid += rowoffset;
|
DrawerContext::SetTextureMid(DrawerContext::TextureMid() + rowoffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fixedlightlev >= 0)
|
if (fixedlightlev >= 0)
|
||||||
R_SetColorMapLight(basecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
DrawerContext::SetLight(basecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
||||||
else if (fixedcolormap != NULL)
|
else if (fixedcolormap != NULL)
|
||||||
R_SetColorMapLight(fixedcolormap, 0, 0);
|
DrawerContext::SetLight(fixedcolormap, 0, 0);
|
||||||
|
|
||||||
WallC.sz1 = ds->sz1;
|
WallC.sz1 = ds->sz1;
|
||||||
WallC.sz2 = ds->sz2;
|
WallC.sz2 = ds->sz2;
|
||||||
|
@ -660,7 +663,7 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover)
|
||||||
|
|
||||||
PrepLWall (lwall, curline->sidedef->TexelLength*xscale, ds->sx1, ds->sx2);
|
PrepLWall (lwall, curline->sidedef->TexelLength*xscale, ds->sx1, ds->sx2);
|
||||||
wallscan_np2_ds(ds, x1, x2, wallupper, walllower, MaskedSWall, lwall, yscale);
|
wallscan_np2_ds(ds, x1, x2, wallupper, walllower, MaskedSWall, lwall, yscale);
|
||||||
R_FinishSetPatchStyle();
|
DrawerContext::FinishSetPatchStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
// kg3D - walls of fake floors
|
// kg3D - walls of fake floors
|
||||||
|
@ -1065,360 +1068,6 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a column with support for non-power-of-two ranges
|
|
||||||
uint32_t wallscan_drawcol1(int x, int y1, int y2, uint32_t uv_start, uint32_t uv_step, uint32_t uv_max, const BYTE *source, DWORD(*draw1column)())
|
|
||||||
{
|
|
||||||
int pixelsize = r_swtruecolor ? 4 : 1;
|
|
||||||
if (uv_max == 0) // power of two
|
|
||||||
{
|
|
||||||
int count = y2 - y1;
|
|
||||||
|
|
||||||
dc_source = source;
|
|
||||||
dc_dest = (ylookup[y1] + x) * pixelsize + dc_destorg;
|
|
||||||
dc_count = count;
|
|
||||||
dc_iscale = uv_step;
|
|
||||||
dc_texturefrac = uv_start;
|
|
||||||
draw1column();
|
|
||||||
|
|
||||||
uint64_t step64 = uv_step;
|
|
||||||
uint64_t pos64 = uv_start;
|
|
||||||
return (uint32_t)(pos64 + step64 * count);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint32_t uv_pos = uv_start;
|
|
||||||
|
|
||||||
uint32_t left = y2 - y1;
|
|
||||||
while (left > 0)
|
|
||||||
{
|
|
||||||
uint32_t available = uv_max - uv_pos;
|
|
||||||
uint32_t next_uv_wrap = available / uv_step;
|
|
||||||
if (available % uv_step != 0)
|
|
||||||
next_uv_wrap++;
|
|
||||||
uint32_t count = MIN(left, next_uv_wrap);
|
|
||||||
|
|
||||||
dc_source = source;
|
|
||||||
dc_dest = (ylookup[y1] + x) * pixelsize + dc_destorg;
|
|
||||||
dc_count = count;
|
|
||||||
dc_iscale = uv_step;
|
|
||||||
dc_texturefrac = uv_pos;
|
|
||||||
draw1column();
|
|
||||||
|
|
||||||
left -= count;
|
|
||||||
uv_pos += uv_step * count;
|
|
||||||
if (uv_pos >= uv_max)
|
|
||||||
uv_pos -= uv_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
return uv_pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw four columns with support for non-power-of-two ranges
|
|
||||||
void wallscan_drawcol4(int x, int y1, int y2, uint32_t *uv_pos, uint32_t *uv_step, uint32_t uv_max, const BYTE **source, void(*draw4columns)())
|
|
||||||
{
|
|
||||||
int pixelsize = r_swtruecolor ? 4 : 1;
|
|
||||||
if (uv_max == 0) // power of two, no wrap handling needed
|
|
||||||
{
|
|
||||||
int count = y2 - y1;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
bufplce[i] = source[i];
|
|
||||||
vplce[i] = uv_pos[i];
|
|
||||||
vince[i] = uv_step[i];
|
|
||||||
|
|
||||||
uint64_t step64 = uv_step[i];
|
|
||||||
uint64_t pos64 = uv_pos[i];
|
|
||||||
uv_pos[i] = (uint32_t)(pos64 + step64 * count);
|
|
||||||
}
|
|
||||||
dc_dest = (ylookup[y1] + x) * pixelsize + dc_destorg;
|
|
||||||
dc_count = count;
|
|
||||||
draw4columns();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dc_dest = (ylookup[y1] + x) * pixelsize + dc_destorg;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
bufplce[i] = source[i];
|
|
||||||
|
|
||||||
uint32_t left = y2 - y1;
|
|
||||||
while (left > 0)
|
|
||||||
{
|
|
||||||
// Find which column wraps first
|
|
||||||
uint32_t count = left;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
uint32_t available = uv_max - uv_pos[i];
|
|
||||||
uint32_t next_uv_wrap = available / uv_step[i];
|
|
||||||
if (available % uv_step[i] != 0)
|
|
||||||
next_uv_wrap++;
|
|
||||||
count = MIN(next_uv_wrap, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw until that column wraps
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
vplce[i] = uv_pos[i];
|
|
||||||
vince[i] = uv_step[i];
|
|
||||||
}
|
|
||||||
dc_count = count;
|
|
||||||
draw4columns();
|
|
||||||
|
|
||||||
// Wrap the uv position
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
uv_pos[i] += uv_step[i] * count;
|
|
||||||
if (uv_pos[i] >= uv_max)
|
|
||||||
uv_pos[i] -= uv_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
left -= count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculates a wrapped uv start position value for a column
|
|
||||||
void calc_uv_start_and_step(int y1, float swal, double yrepeat, uint32_t uv_height, int fracbits, uint32_t &uv_start_out, uint32_t &uv_step_out)
|
|
||||||
{
|
|
||||||
double uv_stepd = swal * yrepeat;
|
|
||||||
|
|
||||||
// Find start uv in [0-uv_height[ range.
|
|
||||||
// Not using xs_ToFixed because it rounds the result and we need something that always rounds down to stay within the range.
|
|
||||||
double v = (dc_texturemid + uv_stepd * (y1 - CenterY + 0.5)) / uv_height;
|
|
||||||
v = v - floor(v);
|
|
||||||
v *= uv_height;
|
|
||||||
v *= (1 << fracbits);
|
|
||||||
|
|
||||||
uv_start_out = (uint32_t)v;
|
|
||||||
uv_step_out = xs_ToFixed(fracbits, uv_stepd);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef DWORD(*Draw1ColumnFuncPtr)();
|
|
||||||
typedef void(*Draw4ColumnsFuncPtr)();
|
|
||||||
|
|
||||||
void wallscan_any(
|
|
||||||
int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat,
|
|
||||||
const BYTE *(*getcol)(FTexture *tex, int x),
|
|
||||||
void(setupwallscan(int bits,Draw1ColumnFuncPtr &draw1, Draw4ColumnsFuncPtr &draw2)))
|
|
||||||
{
|
|
||||||
if (rw_pic->UseType == FTexture::TEX_Null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint32_t uv_height = rw_pic->GetHeight();
|
|
||||||
uint32_t fracbits = 32 - rw_pic->HeightBits;
|
|
||||||
uint32_t uv_max = uv_height << fracbits;
|
|
||||||
|
|
||||||
DWORD(*draw1column)();
|
|
||||||
void(*draw4columns)();
|
|
||||||
setupwallscan(fracbits, draw1column, draw4columns);
|
|
||||||
|
|
||||||
fixed_t xoffset = rw_offset;
|
|
||||||
|
|
||||||
bool fixed = (fixedcolormap != NULL || fixedlightlev >= 0);
|
|
||||||
if (fixed)
|
|
||||||
{
|
|
||||||
palookupoffse[0] = dc_colormap;
|
|
||||||
palookupoffse[1] = dc_colormap;
|
|
||||||
palookupoffse[2] = dc_colormap;
|
|
||||||
palookupoffse[3] = dc_colormap;
|
|
||||||
palookuplight[0] = 0;
|
|
||||||
palookuplight[1] = 0;
|
|
||||||
palookuplight[2] = 0;
|
|
||||||
palookuplight[3] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fixedcolormap)
|
|
||||||
R_SetColorMapLight(fixedcolormap, 0, 0);
|
|
||||||
else
|
|
||||||
R_SetColorMapLight(basecolormap, 0, 0);
|
|
||||||
|
|
||||||
float light = rw_light;
|
|
||||||
|
|
||||||
// Calculate where 4 column alignment begins and ends:
|
|
||||||
int aligned_x1 = clamp((x1 + 3) / 4 * 4, x1, x2);
|
|
||||||
int aligned_x2 = clamp(x2 / 4 * 4, x1, x2);
|
|
||||||
|
|
||||||
// First unaligned columns:
|
|
||||||
for (int x = x1; x < aligned_x1; x++, light += rw_lightstep)
|
|
||||||
{
|
|
||||||
int y1 = uwal[x];
|
|
||||||
int y2 = dwal[x];
|
|
||||||
if (y2 <= y1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!fixed)
|
|
||||||
R_SetColorMapLight(basecolormap, light, wallshade);
|
|
||||||
|
|
||||||
const BYTE *source = getcol(rw_pic, (lwal[x] + xoffset) >> FRACBITS);
|
|
||||||
|
|
||||||
uint32_t uv_start, uv_step;
|
|
||||||
calc_uv_start_and_step(y1, swal[x], yrepeat, uv_height, fracbits, uv_start, uv_step);
|
|
||||||
|
|
||||||
wallscan_drawcol1(x, y1, y2, uv_start, uv_step, uv_max, source, draw1column);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The aligned columns
|
|
||||||
for (int x = aligned_x1; x < aligned_x2; x += 4)
|
|
||||||
{
|
|
||||||
// Find y1, y2, light and uv values for four columns:
|
|
||||||
int y1[4] = { uwal[x], uwal[x + 1], uwal[x + 2], uwal[x + 3] };
|
|
||||||
int y2[4] = { dwal[x], dwal[x + 1], dwal[x + 2], dwal[x + 3] };
|
|
||||||
|
|
||||||
const BYTE *source[4];
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
source[i] = getcol(rw_pic, (lwal[x + i] + xoffset) >> FRACBITS);
|
|
||||||
|
|
||||||
float lights[4];
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
lights[i] = light;
|
|
||||||
light += rw_lightstep;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t uv_pos[4], uv_step[4];
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
calc_uv_start_and_step(y1[i], swal[x + i], yrepeat, uv_height, fracbits, uv_pos[i], uv_step[i]);
|
|
||||||
|
|
||||||
// Figure out where we vertically can start and stop drawing 4 columns in one go
|
|
||||||
int middle_y1 = y1[0];
|
|
||||||
int middle_y2 = y2[0];
|
|
||||||
for (int i = 1; i < 4; i++)
|
|
||||||
{
|
|
||||||
middle_y1 = MAX(y1[i], middle_y1);
|
|
||||||
middle_y2 = MIN(y2[i], middle_y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we got an empty column in our set we cannot draw 4 columns in one go:
|
|
||||||
bool empty_column_in_set = false;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if (y2[i] <= y1[i])
|
|
||||||
empty_column_in_set = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty_column_in_set || middle_y2 <= middle_y1)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if (y2[i] <= y1[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!fixed)
|
|
||||||
R_SetColorMapLight(basecolormap, lights[i], wallshade);
|
|
||||||
wallscan_drawcol1(x + i, y1[i], y2[i], uv_pos[i], uv_step[i], uv_max, source[i], draw1column);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the first rows where not all 4 columns are active
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if (!fixed)
|
|
||||||
R_SetColorMapLight(basecolormap, lights[i], wallshade);
|
|
||||||
|
|
||||||
if (y1[i] < middle_y1)
|
|
||||||
uv_pos[i] = wallscan_drawcol1(x + i, y1[i], middle_y1, uv_pos[i], uv_step[i], uv_max, source[i], draw1column);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the area where all 4 columns are active
|
|
||||||
if (!fixed)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if (r_swtruecolor)
|
|
||||||
{
|
|
||||||
palookupoffse[i] = basecolormap->Maps;
|
|
||||||
palookuplight[i] = LIGHTSCALE(lights[i], wallshade);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
palookupoffse[i] = basecolormap->Maps + (GETPALOOKUP(lights[i], wallshade) << COLORMAPSHIFT);
|
|
||||||
palookuplight[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wallscan_drawcol4(x, middle_y1, middle_y2, uv_pos, uv_step, uv_max, source, draw4columns);
|
|
||||||
|
|
||||||
// Draw the last rows where not all 4 columns are active
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if (!fixed)
|
|
||||||
R_SetColorMapLight(basecolormap, lights[i], wallshade);
|
|
||||||
|
|
||||||
if (middle_y2 < y2[i])
|
|
||||||
uv_pos[i] = wallscan_drawcol1(x + i, middle_y2, y2[i], uv_pos[i], uv_step[i], uv_max, source[i], draw1column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The last unaligned columns:
|
|
||||||
for (int x = aligned_x2; x < x2; x++, light += rw_lightstep)
|
|
||||||
{
|
|
||||||
int y1 = uwal[x];
|
|
||||||
int y2 = dwal[x];
|
|
||||||
if (y2 <= y1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!fixed)
|
|
||||||
R_SetColorMapLight(basecolormap, light, wallshade);
|
|
||||||
|
|
||||||
const BYTE *source = getcol(rw_pic, (lwal[x] + xoffset) >> FRACBITS);
|
|
||||||
|
|
||||||
uint32_t uv_start, uv_step;
|
|
||||||
calc_uv_start_and_step(y1, swal[x], yrepeat, uv_height, fracbits, uv_start, uv_step);
|
|
||||||
|
|
||||||
wallscan_drawcol1(x, y1, y2, uv_start, uv_step, uv_max, source, draw1column);
|
|
||||||
}
|
|
||||||
|
|
||||||
NetUpdate ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void wallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x))
|
|
||||||
{
|
|
||||||
wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4)
|
|
||||||
{
|
|
||||||
setupvline(bits);
|
|
||||||
line1 = dovline1;
|
|
||||||
line4 = dovline4;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void maskwallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x))
|
|
||||||
{
|
|
||||||
if (!rw_pic->bMasked) // Textures that aren't masked can use the faster wallscan.
|
|
||||||
{
|
|
||||||
wallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4)
|
|
||||||
{
|
|
||||||
setupmvline(bits);
|
|
||||||
line1 = domvline1;
|
|
||||||
line4 = domvline4;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void transmaskwallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x))
|
|
||||||
{
|
|
||||||
static fixed_t(*tmvline1)();
|
|
||||||
static void(*tmvline4)();
|
|
||||||
if (!R_GetTransMaskDrawers(&tmvline1, &tmvline4))
|
|
||||||
{
|
|
||||||
// The current translucency is unsupported, so draw with regular maskwallscan instead.
|
|
||||||
maskwallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4)
|
|
||||||
{
|
|
||||||
setuptmvline(bits);
|
|
||||||
line1 = reinterpret_cast<DWORD(*)()>(tmvline1);
|
|
||||||
line4 = tmvline4;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void wallscan_striped (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat)
|
void wallscan_striped (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat)
|
||||||
{
|
{
|
||||||
FDynamicColormap *startcolormap = basecolormap;
|
FDynamicColormap *startcolormap = basecolormap;
|
||||||
|
@ -1444,7 +1093,7 @@ void wallscan_striped (int x1, int x2, short *uwal, short *dwal, float *swal, fi
|
||||||
{
|
{
|
||||||
down[j] = clamp (most3[j], up[j], dwal[j]);
|
down[j] = clamp (most3[j], up[j], dwal[j]);
|
||||||
}
|
}
|
||||||
wallscan (x1, x2, up, down, swal, lwal, yrepeat);
|
DrawerContext::DrawWall (x1, x2, up, down, swal, lwal, yrepeat, rw_pic, rw_offset);
|
||||||
up = down;
|
up = down;
|
||||||
down = (down == most1) ? most2 : most1;
|
down = (down == most1) ? most2 : most1;
|
||||||
}
|
}
|
||||||
|
@ -1455,7 +1104,7 @@ void wallscan_striped (int x1, int x2, short *uwal, short *dwal, float *swal, fi
|
||||||
*lit->p_lightlevel, lit->lightsource != NULL) + r_actualextralight);
|
*lit->p_lightlevel, lit->lightsource != NULL) + r_actualextralight);
|
||||||
}
|
}
|
||||||
|
|
||||||
wallscan (x1, x2, up, dwal, swal, lwal, yrepeat);
|
DrawerContext::DrawWall (x1, x2, up, dwal, swal, lwal, yrepeat, rw_pic, rw_offset);
|
||||||
basecolormap = startcolormap;
|
basecolormap = startcolormap;
|
||||||
wallshade = startshade;
|
wallshade = startshade;
|
||||||
}
|
}
|
||||||
|
@ -1464,20 +1113,20 @@ static void call_wallscan(int x1, int x2, short *uwal, short *dwal, float *swal,
|
||||||
{
|
{
|
||||||
if (mask)
|
if (mask)
|
||||||
{
|
{
|
||||||
if (colfunc == basecolfunc)
|
if (DrawerContext::IsBaseColumn())
|
||||||
{
|
{
|
||||||
maskwallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat);
|
DrawerContext::DrawMaskedWall(x1, x2, uwal, dwal, swal, lwal, yrepeat, rw_pic, rw_offset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
transmaskwallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat);
|
DrawerContext::DrawTransMaskedWall(x1, x2, uwal, dwal, swal, lwal, yrepeat, rw_pic, rw_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (fixedcolormap != NULL || fixedlightlev >= 0 || !(frontsector->e && frontsector->e->XFloor.lightlist.Size()))
|
if (fixedcolormap != NULL || fixedlightlev >= 0 || !(frontsector->e && frontsector->e->XFloor.lightlist.Size()))
|
||||||
{
|
{
|
||||||
wallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat);
|
DrawerContext::DrawWall(x1, x2, uwal, dwal, swal, lwal, yrepeat, rw_pic, rw_offset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1513,14 +1162,14 @@ void wallscan_np2(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t
|
||||||
|
|
||||||
if (yrepeat >= 0)
|
if (yrepeat >= 0)
|
||||||
{ // normal orientation: draw strips from top to bottom
|
{ // normal orientation: draw strips from top to bottom
|
||||||
partition = top - fmod(top - dc_texturemid / yrepeat - ViewPos.Z, scaledtexheight);
|
partition = top - fmod(top - DrawerContext::TextureMid() / yrepeat - ViewPos.Z, scaledtexheight);
|
||||||
if (partition == top)
|
if (partition == top)
|
||||||
{
|
{
|
||||||
partition -= scaledtexheight;
|
partition -= scaledtexheight;
|
||||||
}
|
}
|
||||||
up = uwal;
|
up = uwal;
|
||||||
down = most1;
|
down = most1;
|
||||||
dc_texturemid = (partition - ViewPos.Z) * yrepeat + texheight;
|
DrawerContext::SetTextureMid((partition - ViewPos.Z) * yrepeat + texheight);
|
||||||
while (partition > bot)
|
while (partition > bot)
|
||||||
{
|
{
|
||||||
int j = OWallMost(most3, partition - ViewPos.Z, &WallC);
|
int j = OWallMost(most3, partition - ViewPos.Z, &WallC);
|
||||||
|
@ -1535,16 +1184,16 @@ void wallscan_np2(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t
|
||||||
down = (down == most1) ? most2 : most1;
|
down = (down == most1) ? most2 : most1;
|
||||||
}
|
}
|
||||||
partition -= scaledtexheight;
|
partition -= scaledtexheight;
|
||||||
dc_texturemid -= texheight;
|
DrawerContext::SetTextureMid(DrawerContext::TextureMid() - texheight);
|
||||||
}
|
}
|
||||||
call_wallscan(x1, x2, up, dwal, swal, lwal, yrepeat, mask);
|
call_wallscan(x1, x2, up, dwal, swal, lwal, yrepeat, mask);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // upside down: draw strips from bottom to top
|
{ // upside down: draw strips from bottom to top
|
||||||
partition = bot - fmod(bot - dc_texturemid / yrepeat - ViewPos.Z, scaledtexheight);
|
partition = bot - fmod(bot - DrawerContext::TextureMid() / yrepeat - ViewPos.Z, scaledtexheight);
|
||||||
up = most1;
|
up = most1;
|
||||||
down = dwal;
|
down = dwal;
|
||||||
dc_texturemid = (partition - ViewPos.Z) * yrepeat + texheight;
|
DrawerContext::SetTextureMid((partition - ViewPos.Z) * yrepeat + texheight);
|
||||||
while (partition < top)
|
while (partition < top)
|
||||||
{
|
{
|
||||||
int j = OWallMost(most3, partition - ViewPos.Z, &WallC);
|
int j = OWallMost(most3, partition - ViewPos.Z, &WallC);
|
||||||
|
@ -1559,7 +1208,7 @@ void wallscan_np2(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t
|
||||||
up = (up == most1) ? most2 : most1;
|
up = (up == most1) ? most2 : most1;
|
||||||
}
|
}
|
||||||
partition -= scaledtexheight;
|
partition -= scaledtexheight;
|
||||||
dc_texturemid -= texheight;
|
DrawerContext::SetTextureMid(DrawerContext::TextureMid() - texheight);
|
||||||
}
|
}
|
||||||
call_wallscan(x1, x2, uwal, down, swal, lwal, yrepeat, mask);
|
call_wallscan(x1, x2, uwal, down, swal, lwal, yrepeat, mask);
|
||||||
}
|
}
|
||||||
|
@ -1612,9 +1261,9 @@ void R_RenderSegLoop ()
|
||||||
fixed_t xoffset = rw_offset;
|
fixed_t xoffset = rw_offset;
|
||||||
|
|
||||||
if (fixedlightlev >= 0)
|
if (fixedlightlev >= 0)
|
||||||
R_SetColorMapLight(basecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
DrawerContext::SetLight(basecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
||||||
else if (fixedcolormap != NULL)
|
else if (fixedcolormap != NULL)
|
||||||
R_SetColorMapLight(fixedcolormap, 0, 0);
|
DrawerContext::SetLight(fixedcolormap, 0, 0);
|
||||||
|
|
||||||
// clip wall to the floor and ceiling
|
// clip wall to the floor and ceiling
|
||||||
for (x = x1; x < x2; ++x)
|
for (x = x1; x < x2; ++x)
|
||||||
|
@ -1695,7 +1344,7 @@ void R_RenderSegLoop ()
|
||||||
{ // one sided line
|
{ // one sided line
|
||||||
if (midtexture->UseType != FTexture::TEX_Null && viewactive)
|
if (midtexture->UseType != FTexture::TEX_Null && viewactive)
|
||||||
{
|
{
|
||||||
dc_texturemid = rw_midtexturemid;
|
DrawerContext::SetTextureMid(rw_midtexturemid);
|
||||||
rw_pic = midtexture;
|
rw_pic = midtexture;
|
||||||
xscale = rw_pic->Scale.X * rw_midtexturescalex;
|
xscale = rw_pic->Scale.X * rw_midtexturescalex;
|
||||||
yscale = rw_pic->Scale.Y * rw_midtexturescaley;
|
yscale = rw_pic->Scale.Y * rw_midtexturescaley;
|
||||||
|
@ -1738,7 +1387,7 @@ void R_RenderSegLoop ()
|
||||||
}
|
}
|
||||||
if (viewactive)
|
if (viewactive)
|
||||||
{
|
{
|
||||||
dc_texturemid = rw_toptexturemid;
|
DrawerContext::SetTextureMid(rw_toptexturemid);
|
||||||
rw_pic = toptexture;
|
rw_pic = toptexture;
|
||||||
xscale = rw_pic->Scale.X * rw_toptexturescalex;
|
xscale = rw_pic->Scale.X * rw_toptexturescalex;
|
||||||
yscale = rw_pic->Scale.Y * rw_toptexturescaley;
|
yscale = rw_pic->Scale.Y * rw_toptexturescaley;
|
||||||
|
@ -1784,7 +1433,7 @@ void R_RenderSegLoop ()
|
||||||
}
|
}
|
||||||
if (viewactive)
|
if (viewactive)
|
||||||
{
|
{
|
||||||
dc_texturemid = rw_bottomtexturemid;
|
DrawerContext::SetTextureMid(rw_bottomtexturemid);
|
||||||
rw_pic = bottomtexture;
|
rw_pic = bottomtexture;
|
||||||
xscale = rw_pic->Scale.X * rw_bottomtexturescalex;
|
xscale = rw_pic->Scale.X * rw_bottomtexturescalex;
|
||||||
yscale = rw_pic->Scale.Y * rw_bottomtexturescaley;
|
yscale = rw_pic->Scale.Y * rw_bottomtexturescaley;
|
||||||
|
@ -2974,7 +2623,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
|
||||||
}
|
}
|
||||||
|
|
||||||
yscale = decal->ScaleY;
|
yscale = decal->ScaleY;
|
||||||
dc_texturemid = WallSpriteTile->TopOffset + (zpos - ViewPos.Z) / yscale;
|
DrawerContext::SetTextureMid(WallSpriteTile->TopOffset + (zpos - ViewPos.Z) / yscale);
|
||||||
|
|
||||||
// Clip sprite to drawseg
|
// Clip sprite to drawseg
|
||||||
x1 = MAX<int>(clipper->x1, x1);
|
x1 = MAX<int>(clipper->x1, x1);
|
||||||
|
@ -3011,11 +2660,11 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
|
||||||
|
|
||||||
rw_light = rw_lightleft + (x1 - WallC.sx1) * rw_lightstep;
|
rw_light = rw_lightleft + (x1 - WallC.sx1) * rw_lightstep;
|
||||||
if (fixedlightlev >= 0)
|
if (fixedlightlev >= 0)
|
||||||
R_SetColorMapLight(usecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
DrawerContext::SetLight(usecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
||||||
else if (fixedcolormap != NULL)
|
else if (fixedcolormap != NULL)
|
||||||
R_SetColorMapLight(fixedcolormap, 0, 0);
|
DrawerContext::SetLight(fixedcolormap, 0, 0);
|
||||||
else if (!foggy && (decal->RenderFlags & RF_FULLBRIGHT))
|
else if (!foggy && (decal->RenderFlags & RF_FULLBRIGHT))
|
||||||
R_SetColorMapLight(usecolormap, 0, 0);
|
DrawerContext::SetLight(usecolormap, 0, 0);
|
||||||
else
|
else
|
||||||
calclighting = true;
|
calclighting = true;
|
||||||
|
|
||||||
|
@ -3024,7 +2673,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
|
||||||
{
|
{
|
||||||
sprflipvert = true;
|
sprflipvert = true;
|
||||||
yscale = -yscale;
|
yscale = -yscale;
|
||||||
dc_texturemid -= WallSpriteTile->GetHeight();
|
DrawerContext::SetTextureMid(DrawerContext::TextureMid() - WallSpriteTile->GetHeight());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3034,10 +2683,9 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
|
||||||
MaskedScaleY = float(1 / yscale);
|
MaskedScaleY = float(1 / yscale);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
dc_x = x1;
|
|
||||||
ESPSResult mode;
|
ESPSResult mode;
|
||||||
|
|
||||||
mode = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor);
|
mode = DrawerContext::SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor);
|
||||||
|
|
||||||
// R_SetPatchStyle can modify basecolormap.
|
// R_SetPatchStyle can modify basecolormap.
|
||||||
if (rereadcolormap)
|
if (rereadcolormap)
|
||||||
|
@ -3053,48 +2701,50 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
|
||||||
{
|
{
|
||||||
int stop4;
|
int stop4;
|
||||||
|
|
||||||
|
int x = x1;
|
||||||
|
|
||||||
if (mode == DoDraw0)
|
if (mode == DoDraw0)
|
||||||
{ // 1 column at a time
|
{ // 1 column at a time
|
||||||
stop4 = dc_x;
|
stop4 = x;
|
||||||
}
|
}
|
||||||
else // DoDraw1
|
else // DoDraw1
|
||||||
{ // up to 4 columns at a time
|
{ // up to 4 columns at a time
|
||||||
stop4 = x2 & ~3;
|
stop4 = x2 & ~3;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((dc_x < stop4) && (dc_x & 3))
|
while ((x < stop4) && (x & 3))
|
||||||
{
|
{
|
||||||
if (calclighting)
|
if (calclighting)
|
||||||
{ // calculate lighting
|
{ // calculate lighting
|
||||||
R_SetColorMapLight(usecolormap, rw_light, wallshade);
|
DrawerContext::SetLight(usecolormap, rw_light, wallshade);
|
||||||
}
|
}
|
||||||
R_WallSpriteColumn (R_DrawMaskedColumn);
|
R_WallSpriteColumn (x, DrawerContext::DrawMaskedColumn);
|
||||||
dc_x++;
|
x++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (dc_x < stop4)
|
while (x < stop4)
|
||||||
{
|
{
|
||||||
if (calclighting)
|
if (calclighting)
|
||||||
{ // calculate lighting
|
{ // calculate lighting
|
||||||
R_SetColorMapLight(usecolormap, rw_light, wallshade);
|
DrawerContext::SetLight(usecolormap, rw_light, wallshade);
|
||||||
}
|
}
|
||||||
rt_initcols(nullptr);
|
DrawerContext::RtInitCols(nullptr);
|
||||||
for (int zz = 4; zz; --zz)
|
for (int zz = 0; zz < 4; ++zz)
|
||||||
{
|
{
|
||||||
R_WallSpriteColumn (R_DrawMaskedColumnHoriz);
|
R_WallSpriteColumn (x + zz, DrawerContext::DrawMaskedColumnHoriz);
|
||||||
dc_x++;
|
|
||||||
}
|
}
|
||||||
rt_draw4cols (dc_x - 4);
|
DrawerContext::DrawRt4cols (x);
|
||||||
|
x += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (dc_x < x2)
|
while (x < x2)
|
||||||
{
|
{
|
||||||
if (calclighting)
|
if (calclighting)
|
||||||
{ // calculate lighting
|
{ // calculate lighting
|
||||||
R_SetColorMapLight(usecolormap, rw_light, wallshade);
|
DrawerContext::SetLight(usecolormap, rw_light, wallshade);
|
||||||
}
|
}
|
||||||
R_WallSpriteColumn (R_DrawMaskedColumn);
|
R_WallSpriteColumn (x, DrawerContext::DrawMaskedColumn);
|
||||||
dc_x++;
|
x++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3103,14 +2753,11 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
|
||||||
// needrepeat will be 0, and the while will fail.
|
// needrepeat will be 0, and the while will fail.
|
||||||
mceilingclip = floorclip;
|
mceilingclip = floorclip;
|
||||||
mfloorclip = wallbottom;
|
mfloorclip = wallbottom;
|
||||||
R_FinishSetPatchStyle ();
|
DrawerContext::FinishSetPatchStyle ();
|
||||||
} while (needrepeat--);
|
} while (needrepeat--);
|
||||||
|
|
||||||
colfunc = basecolfunc;
|
DrawerContext::SetBaseStyle();
|
||||||
hcolfunc_post1 = rt_map1col;
|
DrawerContext::FinishSetPatchStyle ();
|
||||||
hcolfunc_post4 = rt_map4cols;
|
|
||||||
|
|
||||||
R_FinishSetPatchStyle ();
|
|
||||||
done:
|
done:
|
||||||
WallC = savecoord;
|
WallC = savecoord;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define DRAWER_INTERNALS
|
||||||
|
|
||||||
#include "r_local.h"
|
#include "r_local.h"
|
||||||
#include "v_palette.h"
|
#include "v_palette.h"
|
||||||
|
|
382
src/r_things.cpp
382
src/r_things.cpp
|
@ -58,7 +58,7 @@
|
||||||
#include "r_plane.h"
|
#include "r_plane.h"
|
||||||
#include "r_segs.h"
|
#include "r_segs.h"
|
||||||
#include "r_3dfloors.h"
|
#include "r_3dfloors.h"
|
||||||
#include "r_draw_rgba.h"
|
#include "r_drawer_context.h"
|
||||||
#include "v_palette.h"
|
#include "v_palette.h"
|
||||||
#include "r_data/r_translate.h"
|
#include "r_data/r_translate.h"
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
|
@ -229,12 +229,6 @@ vissprite_t *R_NewVisSprite (void)
|
||||||
return *(vissprite_p-1);
|
return *(vissprite_p-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// R_DrawMaskedColumn
|
|
||||||
// Used for sprites and masked mid textures.
|
|
||||||
// Masked means: partly transparent, i.e. stored
|
|
||||||
// in posts/runs of opaque pixels.
|
|
||||||
//
|
|
||||||
short* mfloorclip;
|
short* mfloorclip;
|
||||||
short* mceilingclip;
|
short* mceilingclip;
|
||||||
|
|
||||||
|
@ -243,88 +237,6 @@ double sprtopscreen;
|
||||||
|
|
||||||
bool sprflipvert;
|
bool sprflipvert;
|
||||||
|
|
||||||
void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *span)
|
|
||||||
{
|
|
||||||
int pixelsize = r_swtruecolor ? 4 : 1;
|
|
||||||
const fixed_t centeryfrac = FLOAT2FIXED(CenterY);
|
|
||||||
const fixed_t texturemid = FLOAT2FIXED(dc_texturemid);
|
|
||||||
while (span->Length != 0)
|
|
||||||
{
|
|
||||||
const int length = span->Length;
|
|
||||||
const int top = span->TopOffset;
|
|
||||||
|
|
||||||
// calculate unclipped screen coordinates for post
|
|
||||||
dc_yl = xs_RoundToInt(sprtopscreen + spryscale * top);
|
|
||||||
dc_yh = xs_RoundToInt(sprtopscreen + spryscale * (top + length)) - 1;
|
|
||||||
|
|
||||||
if (sprflipvert)
|
|
||||||
{
|
|
||||||
swapvalues (dc_yl, dc_yh);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dc_yh >= mfloorclip[dc_x])
|
|
||||||
{
|
|
||||||
dc_yh = mfloorclip[dc_x] - 1;
|
|
||||||
}
|
|
||||||
if (dc_yl < mceilingclip[dc_x])
|
|
||||||
{
|
|
||||||
dc_yl = mceilingclip[dc_x];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dc_yl <= dc_yh)
|
|
||||||
{
|
|
||||||
if (sprflipvert)
|
|
||||||
{
|
|
||||||
dc_texturefrac = (dc_yl*dc_iscale) - (top << FRACBITS)
|
|
||||||
- FixedMul (centeryfrac, dc_iscale) - texturemid;
|
|
||||||
const fixed_t maxfrac = length << FRACBITS;
|
|
||||||
while (dc_texturefrac >= maxfrac)
|
|
||||||
{
|
|
||||||
if (++dc_yl > dc_yh)
|
|
||||||
goto nextpost;
|
|
||||||
dc_texturefrac += dc_iscale;
|
|
||||||
}
|
|
||||||
fixed_t endfrac = dc_texturefrac + (dc_yh-dc_yl)*dc_iscale;
|
|
||||||
while (endfrac < 0)
|
|
||||||
{
|
|
||||||
if (--dc_yh < dc_yl)
|
|
||||||
goto nextpost;
|
|
||||||
endfrac -= dc_iscale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dc_texturefrac = texturemid - (top << FRACBITS)
|
|
||||||
+ (dc_yl*dc_iscale) - FixedMul (centeryfrac-FRACUNIT, dc_iscale);
|
|
||||||
while (dc_texturefrac < 0)
|
|
||||||
{
|
|
||||||
if (++dc_yl > dc_yh)
|
|
||||||
goto nextpost;
|
|
||||||
dc_texturefrac += dc_iscale;
|
|
||||||
}
|
|
||||||
fixed_t endfrac = dc_texturefrac + (dc_yh-dc_yl)*dc_iscale;
|
|
||||||
const fixed_t maxfrac = length << FRACBITS;
|
|
||||||
if (dc_yh < mfloorclip[dc_x]-1 && endfrac < maxfrac - dc_iscale)
|
|
||||||
{
|
|
||||||
dc_yh++;
|
|
||||||
}
|
|
||||||
else while (endfrac >= maxfrac)
|
|
||||||
{
|
|
||||||
if (--dc_yh < dc_yl)
|
|
||||||
goto nextpost;
|
|
||||||
endfrac -= dc_iscale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dc_source = column + top;
|
|
||||||
dc_dest = (ylookup[dc_yl] + dc_x) * pixelsize + dc_destorg;
|
|
||||||
dc_count = dc_yh - dc_yl + 1;
|
|
||||||
colfunc ();
|
|
||||||
}
|
|
||||||
nextpost:
|
|
||||||
span++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// [ZZ]
|
// [ZZ]
|
||||||
// R_ClipSpriteColumnWithPortals
|
// R_ClipSpriteColumnWithPortals
|
||||||
//
|
//
|
||||||
|
@ -361,7 +273,7 @@ static inline void R_CollectPortals()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool R_ClipSpriteColumnWithPortals(vissprite_t* spr)
|
bool R_ClipSpriteColumnWithPortals(int x, vissprite_t* spr)
|
||||||
{
|
{
|
||||||
// [ZZ] 10.01.2016: don't clip sprites from the root of a skybox.
|
// [ZZ] 10.01.2016: don't clip sprites from the root of a skybox.
|
||||||
if (CurrentPortalInSkybox)
|
if (CurrentPortalInSkybox)
|
||||||
|
@ -380,7 +292,7 @@ static inline bool R_ClipSpriteColumnWithPortals(vissprite_t* spr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// now if current column is covered by this drawseg, we clip it away
|
// now if current column is covered by this drawseg, we clip it away
|
||||||
if ((dc_x >= seg->x1) && (dc_x < seg->x2))
|
if ((x >= seg->x1) && (x < seg->x2))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,15 +321,15 @@ void R_DrawVisSprite (vissprite_t *vis)
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed_t centeryfrac = FLOAT2FIXED(CenterY);
|
fixed_t centeryfrac = FLOAT2FIXED(CenterY);
|
||||||
R_SetColorMapLight(vis->Style.BaseColormap, 0, vis->Style.ColormapNum << FRACBITS);
|
DrawerContext::SetLight(vis->Style.BaseColormap, 0, vis->Style.ColormapNum << FRACBITS);
|
||||||
|
|
||||||
mode = R_SetPatchStyle (vis->Style.RenderStyle, vis->Style.Alpha, vis->Translation, vis->FillColor);
|
mode = DrawerContext::SetPatchStyle (vis->Style.RenderStyle, vis->Style.Alpha, vis->Translation, vis->FillColor);
|
||||||
|
|
||||||
if (vis->Style.RenderStyle == LegacyRenderStyles[STYLE_Shaded])
|
if (vis->Style.RenderStyle == LegacyRenderStyles[STYLE_Shaded])
|
||||||
{ // For shaded sprites, R_SetPatchStyle sets a dc_colormap to an alpha table, but
|
{ // For shaded sprites, R_SetPatchStyle sets a dc_colormap to an alpha table, but
|
||||||
// it is the brightest one. We need to get back to the proper light level for
|
// it is the brightest one. We need to get back to the proper light level for
|
||||||
// this sprite.
|
// this sprite.
|
||||||
R_SetColorMapLight(dc_fcolormap, 0, vis->Style.ColormapNum << FRACBITS);
|
DrawerContext::SetLight(DrawerContext::LightColormap(), 0, vis->Style.ColormapNum << FRACBITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode != DontDraw)
|
if (mode != DontDraw)
|
||||||
|
@ -436,65 +348,67 @@ void R_DrawVisSprite (vissprite_t *vis)
|
||||||
tex = vis->pic;
|
tex = vis->pic;
|
||||||
spryscale = vis->yscale;
|
spryscale = vis->yscale;
|
||||||
sprflipvert = false;
|
sprflipvert = false;
|
||||||
dc_iscale = FLOAT2FIXED(1 / vis->yscale);
|
DrawerContext::SetTextureStep(FLOAT2FIXED(1 / vis->yscale));
|
||||||
frac = vis->startfrac;
|
frac = vis->startfrac;
|
||||||
xiscale = vis->xiscale;
|
xiscale = vis->xiscale;
|
||||||
dc_texturemid = vis->texturemid;
|
DrawerContext::SetTextureMid(vis->texturemid);
|
||||||
|
|
||||||
if (vis->renderflags & RF_YFLIP)
|
if (vis->renderflags & RF_YFLIP)
|
||||||
{
|
{
|
||||||
sprflipvert = true;
|
sprflipvert = true;
|
||||||
spryscale = -spryscale;
|
spryscale = -spryscale;
|
||||||
dc_iscale = -dc_iscale;
|
DrawerContext::SetTextureStep(-DrawerContext::TextureStep());
|
||||||
dc_texturemid -= vis->pic->GetHeight();
|
DrawerContext::SetTextureMid(DrawerContext::TextureMid() - vis->pic->GetHeight());
|
||||||
sprtopscreen = CenterY + dc_texturemid * spryscale;
|
sprtopscreen = CenterY + DrawerContext::TextureMid() * spryscale;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprflipvert = false;
|
sprflipvert = false;
|
||||||
sprtopscreen = CenterY - dc_texturemid * spryscale;
|
sprtopscreen = CenterY - DrawerContext::TextureMid() * spryscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_x = vis->x1;
|
int x = vis->x1;
|
||||||
x2 = vis->x2;
|
x2 = vis->x2;
|
||||||
|
|
||||||
if (dc_x < x2)
|
if (x < x2)
|
||||||
{
|
{
|
||||||
while ((dc_x < stop4) && (dc_x & 3))
|
DrawerContext::SetMaskedColumnState(mfloorclip, mceilingclip, spryscale, sprtopscreen, sprflipvert);
|
||||||
|
|
||||||
|
while ((x < stop4) && (x & 3))
|
||||||
{
|
{
|
||||||
pixels = tex->GetColumn (frac >> FRACBITS, &spans);
|
pixels = tex->GetColumn (frac >> FRACBITS, &spans);
|
||||||
if (ispsprite || !R_ClipSpriteColumnWithPortals(vis))
|
if (ispsprite || !R_ClipSpriteColumnWithPortals(x, vis))
|
||||||
R_DrawMaskedColumn (pixels, spans);
|
DrawerContext::DrawMaskedColumn (x, pixels, spans);
|
||||||
dc_x++;
|
x++;
|
||||||
frac += xiscale;
|
frac += xiscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (dc_x < stop4)
|
while (x < stop4)
|
||||||
{
|
{
|
||||||
rt_initcols(nullptr);
|
DrawerContext::RtInitCols(nullptr);
|
||||||
for (int zz = 4; zz; --zz)
|
for (int zz = 0; zz < 4; ++zz)
|
||||||
{
|
{
|
||||||
pixels = tex->GetColumn (frac >> FRACBITS, &spans);
|
pixels = tex->GetColumn (frac >> FRACBITS, &spans);
|
||||||
if (ispsprite || !R_ClipSpriteColumnWithPortals(vis))
|
if (ispsprite || !R_ClipSpriteColumnWithPortals(x + zz, vis))
|
||||||
R_DrawMaskedColumnHoriz (pixels, spans);
|
DrawerContext::DrawMaskedColumnHoriz (x + zz, pixels, spans);
|
||||||
dc_x++;
|
|
||||||
frac += xiscale;
|
frac += xiscale;
|
||||||
}
|
}
|
||||||
rt_draw4cols (dc_x - 4);
|
DrawerContext::DrawRt4cols(x);
|
||||||
|
x += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (dc_x < x2)
|
while (x < x2)
|
||||||
{
|
{
|
||||||
pixels = tex->GetColumn (frac >> FRACBITS, &spans);
|
pixels = tex->GetColumn (frac >> FRACBITS, &spans);
|
||||||
if (ispsprite || !R_ClipSpriteColumnWithPortals(vis))
|
if (ispsprite || !R_ClipSpriteColumnWithPortals(x, vis))
|
||||||
R_DrawMaskedColumn (pixels, spans);
|
DrawerContext::DrawMaskedColumn (x, pixels, spans);
|
||||||
dc_x++;
|
x++;
|
||||||
frac += xiscale;
|
frac += xiscale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R_FinishSetPatchStyle ();
|
DrawerContext::FinishSetPatchStyle ();
|
||||||
|
|
||||||
NetUpdate ();
|
NetUpdate ();
|
||||||
}
|
}
|
||||||
|
@ -511,7 +425,7 @@ void R_DrawWallSprite(vissprite_t *spr)
|
||||||
WallT.InitFromWallCoords(&spr->wallc);
|
WallT.InitFromWallCoords(&spr->wallc);
|
||||||
PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2);
|
PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2);
|
||||||
iyscale = 1 / spr->yscale;
|
iyscale = 1 / spr->yscale;
|
||||||
dc_texturemid = (spr->gzt - ViewPos.Z) * iyscale;
|
DrawerContext::SetTextureMid((spr->gzt - ViewPos.Z) * iyscale);
|
||||||
if (spr->renderflags & RF_XFLIP)
|
if (spr->renderflags & RF_XFLIP)
|
||||||
{
|
{
|
||||||
int right = (spr->pic->GetWidth() << FRACBITS) - 1;
|
int right = (spr->pic->GetWidth() << FRACBITS) - 1;
|
||||||
|
@ -539,11 +453,11 @@ void R_DrawWallSprite(vissprite_t *spr)
|
||||||
rw_lightstep = float((GlobVis / spr->wallc.sz2 - rw_lightleft) / (spr->wallc.sx2 - spr->wallc.sx1));
|
rw_lightstep = float((GlobVis / spr->wallc.sz2 - rw_lightleft) / (spr->wallc.sx2 - spr->wallc.sx1));
|
||||||
rw_light = rw_lightleft + (x1 - spr->wallc.sx1) * rw_lightstep;
|
rw_light = rw_lightleft + (x1 - spr->wallc.sx1) * rw_lightstep;
|
||||||
if (fixedlightlev >= 0)
|
if (fixedlightlev >= 0)
|
||||||
R_SetColorMapLight(usecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
DrawerContext::SetLight(usecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
||||||
else if (fixedcolormap != NULL)
|
else if (fixedcolormap != NULL)
|
||||||
R_SetColorMapLight(fixedcolormap, 0, 0);
|
DrawerContext::SetLight(fixedcolormap, 0, 0);
|
||||||
else if (!foggy && (spr->renderflags & RF_FULLBRIGHT))
|
else if (!foggy && (spr->renderflags & RF_FULLBRIGHT))
|
||||||
R_SetColorMapLight(usecolormap, 0, 0);
|
DrawerContext::SetLight(usecolormap, 0, 0);
|
||||||
else
|
else
|
||||||
calclighting = true;
|
calclighting = true;
|
||||||
|
|
||||||
|
@ -553,7 +467,7 @@ void R_DrawWallSprite(vissprite_t *spr)
|
||||||
{
|
{
|
||||||
sprflipvert = true;
|
sprflipvert = true;
|
||||||
iyscale = -iyscale;
|
iyscale = -iyscale;
|
||||||
dc_texturemid -= spr->pic->GetHeight();
|
DrawerContext::SetTextureMid(DrawerContext::TextureMid() - spr->pic->GetHeight());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -562,10 +476,9 @@ void R_DrawWallSprite(vissprite_t *spr)
|
||||||
|
|
||||||
MaskedScaleY = (float)iyscale;
|
MaskedScaleY = (float)iyscale;
|
||||||
|
|
||||||
dc_x = x1;
|
|
||||||
ESPSResult mode;
|
ESPSResult mode;
|
||||||
|
|
||||||
mode = R_SetPatchStyle (spr->Style.RenderStyle, spr->Style.Alpha, spr->Translation, spr->FillColor);
|
mode = DrawerContext::SetPatchStyle (spr->Style.RenderStyle, spr->Style.Alpha, spr->Translation, spr->FillColor);
|
||||||
|
|
||||||
// R_SetPatchStyle can modify basecolormap.
|
// R_SetPatchStyle can modify basecolormap.
|
||||||
if (rereadcolormap)
|
if (rereadcolormap)
|
||||||
|
@ -581,71 +494,74 @@ void R_DrawWallSprite(vissprite_t *spr)
|
||||||
{
|
{
|
||||||
int stop4;
|
int stop4;
|
||||||
|
|
||||||
|
int x = x1;
|
||||||
|
|
||||||
if (mode == DoDraw0)
|
if (mode == DoDraw0)
|
||||||
{ // 1 column at a time
|
{ // 1 column at a time
|
||||||
stop4 = dc_x;
|
stop4 = x;
|
||||||
}
|
}
|
||||||
else // DoDraw1
|
else // DoDraw1
|
||||||
{ // up to 4 columns at a time
|
{ // up to 4 columns at a time
|
||||||
stop4 = x2 & ~3;
|
stop4 = x2 & ~3;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((dc_x < stop4) && (dc_x & 3))
|
while ((x < stop4) && (x & 3))
|
||||||
{
|
{
|
||||||
if (calclighting)
|
if (calclighting)
|
||||||
{ // calculate lighting
|
{ // calculate lighting
|
||||||
R_SetColorMapLight(usecolormap, rw_light, shade);
|
DrawerContext::SetLight(usecolormap, rw_light, shade);
|
||||||
}
|
}
|
||||||
if (!R_ClipSpriteColumnWithPortals(spr))
|
if (!R_ClipSpriteColumnWithPortals(x, spr))
|
||||||
R_WallSpriteColumn(R_DrawMaskedColumn);
|
R_WallSpriteColumn(x, DrawerContext::DrawMaskedColumn);
|
||||||
dc_x++;
|
x++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (dc_x < stop4)
|
while (x < stop4)
|
||||||
{
|
{
|
||||||
if (calclighting)
|
if (calclighting)
|
||||||
{ // calculate lighting
|
{ // calculate lighting
|
||||||
R_SetColorMapLight(usecolormap, rw_light, shade);
|
DrawerContext::SetLight(usecolormap, rw_light, shade);
|
||||||
}
|
}
|
||||||
rt_initcols(nullptr);
|
DrawerContext::RtInitCols(nullptr);
|
||||||
for (int zz = 4; zz; --zz)
|
for (int zz = 0; zz < 4; ++zz)
|
||||||
{
|
{
|
||||||
if (!R_ClipSpriteColumnWithPortals(spr))
|
if (!R_ClipSpriteColumnWithPortals(x + zz, spr))
|
||||||
R_WallSpriteColumn(R_DrawMaskedColumnHoriz);
|
R_WallSpriteColumn(x + zz, DrawerContext::DrawMaskedColumnHoriz);
|
||||||
dc_x++;
|
|
||||||
}
|
}
|
||||||
rt_draw4cols(dc_x - 4);
|
DrawerContext::DrawRt4cols(x);
|
||||||
|
x += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (dc_x < x2)
|
while (x < x2)
|
||||||
{
|
{
|
||||||
if (calclighting)
|
if (calclighting)
|
||||||
{ // calculate lighting
|
{ // calculate lighting
|
||||||
R_SetColorMapLight(usecolormap, rw_light, shade);
|
DrawerContext::SetLight(usecolormap, rw_light, shade);
|
||||||
}
|
}
|
||||||
if (!R_ClipSpriteColumnWithPortals(spr))
|
if (!R_ClipSpriteColumnWithPortals(x, spr))
|
||||||
R_WallSpriteColumn(R_DrawMaskedColumn);
|
R_WallSpriteColumn(x, DrawerContext::DrawMaskedColumn);
|
||||||
dc_x++;
|
x++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
R_FinishSetPatchStyle();
|
DrawerContext::FinishSetPatchStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void R_WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans))
|
void R_WallSpriteColumn (int x, void (*drawfunc)(int x, const BYTE *column, const FTexture::Span *spans))
|
||||||
{
|
{
|
||||||
float iscale = swall[dc_x] * MaskedScaleY;
|
float iscale = swall[x] * MaskedScaleY;
|
||||||
dc_iscale = FLOAT2FIXED(iscale);
|
DrawerContext::SetTextureStep(FLOAT2FIXED(iscale));
|
||||||
spryscale = 1 / iscale;
|
spryscale = 1 / iscale;
|
||||||
if (sprflipvert)
|
if (sprflipvert)
|
||||||
sprtopscreen = CenterY + dc_texturemid * spryscale;
|
sprtopscreen = CenterY + DrawerContext::TextureMid() * spryscale;
|
||||||
else
|
else
|
||||||
sprtopscreen = CenterY - dc_texturemid * spryscale;
|
sprtopscreen = CenterY - DrawerContext::TextureMid() * spryscale;
|
||||||
|
|
||||||
const BYTE *column;
|
const BYTE *column;
|
||||||
const FTexture::Span *spans;
|
const FTexture::Span *spans;
|
||||||
column = WallSpriteTile->GetColumn (lwall[dc_x] >> FRACBITS, &spans);
|
column = WallSpriteTile->GetColumn (lwall[x] >> FRACBITS, &spans);
|
||||||
dc_texturefrac = 0;
|
DrawerContext::SetTextureFrac(0);
|
||||||
drawfunc (column, spans);
|
DrawerContext::SetMaskedColumnState(mfloorclip, mceilingclip, spryscale, sprtopscreen, sprflipvert);
|
||||||
|
drawfunc (x, column, spans);
|
||||||
rw_light += rw_lightstep;
|
rw_light += rw_lightstep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,18 +571,18 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
// Do setup for blending.
|
// Do setup for blending.
|
||||||
R_SetColorMapLight(spr->Style.BaseColormap, 0, spr->Style.ColormapNum << FRACBITS);
|
DrawerContext::SetLight(spr->Style.BaseColormap, 0, spr->Style.ColormapNum << FRACBITS);
|
||||||
mode = R_SetPatchStyle(spr->Style.RenderStyle, spr->Style.Alpha, spr->Translation, spr->FillColor);
|
mode = DrawerContext::SetPatchStyle(spr->Style.RenderStyle, spr->Style.Alpha, spr->Translation, spr->FillColor);
|
||||||
|
|
||||||
if (mode == DontDraw)
|
if (mode == DontDraw)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (colfunc == fuzzcolfunc || colfunc == R_FillColumn)
|
if (DrawerContext::IsFuzzColumn() || DrawerContext::IsFillColumn())
|
||||||
{
|
{
|
||||||
flags = DVF_OFFSCREEN | DVF_SPANSONLY;
|
flags = DVF_OFFSCREEN | DVF_SPANSONLY;
|
||||||
}
|
}
|
||||||
else if (colfunc != basecolfunc)
|
else if (!DrawerContext::IsBaseColumn())
|
||||||
{
|
{
|
||||||
flags = DVF_OFFSCREEN;
|
flags = DVF_OFFSCREEN;
|
||||||
}
|
}
|
||||||
|
@ -692,32 +608,32 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop
|
||||||
{
|
{
|
||||||
if (!(flags & DVF_SPANSONLY) && (x & 3) == 0)
|
if (!(flags & DVF_SPANSONLY) && (x & 3) == 0)
|
||||||
{
|
{
|
||||||
rt_initcols(OffscreenColorBuffer + x * OffscreenBufferHeight);
|
DrawerContext::RtInitCols(OffscreenColorBuffer + x * OffscreenBufferHeight);
|
||||||
}
|
}
|
||||||
for (FCoverageBuffer::Span *span = OffscreenCoverageBuffer->Spans[x]; span != NULL; span = span->NextSpan)
|
for (FCoverageBuffer::Span *span = OffscreenCoverageBuffer->Spans[x]; span != NULL; span = span->NextSpan)
|
||||||
{
|
{
|
||||||
if (flags & DVF_SPANSONLY)
|
if (flags & DVF_SPANSONLY)
|
||||||
{
|
{
|
||||||
dc_x = x;
|
DrawerContext::SetX(x);
|
||||||
dc_yl = span->Start;
|
DrawerContext::SetY1(span->Start);
|
||||||
dc_yh = span->Stop - 1;
|
DrawerContext::SetY2(span->Stop - 1);
|
||||||
dc_count = span->Stop - span->Start;
|
DrawerContext::SetDrawCount(span->Stop - span->Start);
|
||||||
dc_dest = (ylookup[span->Start] + x) * pixelsize + dc_destorg;
|
DrawerContext::SetDest(x, span->Start);
|
||||||
colfunc();
|
DrawerContext::DrawColumn();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rt_span_coverage(x, span->Start, span->Stop - 1);
|
DrawerContext::RtSpanCoverage(x, span->Start, span->Stop - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(flags & DVF_SPANSONLY) && (x & 3) == 3)
|
if (!(flags & DVF_SPANSONLY) && (x & 3) == 3)
|
||||||
{
|
{
|
||||||
rt_draw4cols(x - 3);
|
DrawerContext::DrawRt4cols(x - 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R_FinishSetPatchStyle();
|
DrawerContext::FinishSetPatchStyle();
|
||||||
NetUpdate();
|
NetUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2585,7 +2501,7 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void R_DrawMaskedSegsBehindParticle (const vissprite_t *vis)
|
void R_DrawMaskedSegsBehindParticle (const vissprite_t *vis)
|
||||||
{
|
{
|
||||||
const int x1 = vis->x1;
|
const int x1 = vis->x1;
|
||||||
const int x2 = vis->x2;
|
const int x2 = vis->x2;
|
||||||
|
@ -2610,120 +2526,24 @@ static void R_DrawMaskedSegsBehindParticle (const vissprite_t *vis)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void R_DrawParticle_C (vissprite_t *vis)
|
void R_DrawParticle(vissprite_t *vis)
|
||||||
{
|
{
|
||||||
DWORD *bg2rgb;
|
|
||||||
int spacing;
|
|
||||||
BYTE *dest;
|
|
||||||
DWORD fg;
|
|
||||||
BYTE color = vis->Style.BaseColormap->Maps[(vis->Style.ColormapNum << COLORMAPSHIFT) + vis->startfrac];
|
BYTE color = vis->Style.BaseColormap->Maps[(vis->Style.ColormapNum << COLORMAPSHIFT) + vis->startfrac];
|
||||||
int yl = vis->y1;
|
int yl = vis->y1;
|
||||||
int ycount = vis->y2 - yl + 1;
|
int yh = vis->y2;
|
||||||
int x1 = vis->x1;
|
int x1 = vis->x1;
|
||||||
int countbase = vis->x2 - x1;
|
int countbase = vis->x2 - x1;
|
||||||
|
|
||||||
R_DrawMaskedSegsBehindParticle(vis);
|
R_DrawMaskedSegsBehindParticle(vis);
|
||||||
|
|
||||||
// vis->renderflags holds translucency level (0-255)
|
// vis->renderflags holds translucency level (0-255)
|
||||||
{
|
int alpha = vis->renderflags;
|
||||||
fixed_t fglevel, bglevel;
|
|
||||||
DWORD *fg2rgb;
|
|
||||||
|
|
||||||
fglevel = ((vis->renderflags + 1) << 8) & ~0x3ff;
|
|
||||||
bglevel = FRACUNIT-fglevel;
|
|
||||||
fg2rgb = Col2RGB8[fglevel>>10];
|
|
||||||
bg2rgb = Col2RGB8[bglevel>>10];
|
|
||||||
fg = fg2rgb[color];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
spacing = RenderTarget->GetPitch() - countbase;
|
|
||||||
dest = ylookup[yl] + x1 + dc_destorg;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
int count = countbase;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
DWORD bg = bg2rgb[*dest];
|
|
||||||
bg = (fg+bg) | 0x1f07c1f;
|
|
||||||
*dest++ = RGB32k.All[bg & (bg>>15)];
|
|
||||||
} while (--count);
|
|
||||||
dest += spacing;
|
|
||||||
} while (--ycount);*/
|
|
||||||
|
|
||||||
// original was row-wise
|
|
||||||
// width = countbase
|
|
||||||
// height = ycount
|
|
||||||
|
|
||||||
spacing = RenderTarget->GetPitch();
|
|
||||||
|
|
||||||
for (int x = x1; x < (x1 + countbase); x++)
|
for (int x = x1; x < (x1 + countbase); x++)
|
||||||
{
|
{
|
||||||
dc_x = x;
|
if (R_ClipSpriteColumnWithPortals(x, vis))
|
||||||
if (R_ClipSpriteColumnWithPortals(vis))
|
|
||||||
continue;
|
continue;
|
||||||
dest = ylookup[yl] + x + dc_destorg;
|
DrawerContext::FillTransColumn(x, yl, yh, color, alpha);
|
||||||
for (int y = 0; y < ycount; y++)
|
|
||||||
{
|
|
||||||
DWORD bg = bg2rgb[*dest];
|
|
||||||
bg = (fg+bg) | 0x1f07c1f;
|
|
||||||
*dest = RGB32k.All[bg & (bg>>15)];
|
|
||||||
dest += spacing;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_DrawParticle_rgba(vissprite_t *vis)
|
|
||||||
{
|
|
||||||
int spacing;
|
|
||||||
uint32_t *dest;
|
|
||||||
BYTE color = vis->Style.BaseColormap->Maps[vis->startfrac];
|
|
||||||
int yl = vis->y1;
|
|
||||||
int ycount = vis->y2 - yl + 1;
|
|
||||||
int x1 = vis->x1;
|
|
||||||
int countbase = vis->x2 - x1;
|
|
||||||
|
|
||||||
R_DrawMaskedSegsBehindParticle(vis);
|
|
||||||
|
|
||||||
DrawerCommandQueue::WaitForWorkers();
|
|
||||||
|
|
||||||
uint32_t fg = shade_pal_index_simple(color, calc_light_multiplier(LIGHTSCALE(0, vis->Style.ColormapNum << FRACBITS)));
|
|
||||||
uint32_t fg_red = (fg >> 16) & 0xff;
|
|
||||||
uint32_t fg_green = (fg >> 8) & 0xff;
|
|
||||||
uint32_t fg_blue = fg & 0xff;
|
|
||||||
|
|
||||||
// vis->renderflags holds translucency level (0-255)
|
|
||||||
fixed_t fglevel = ((vis->renderflags + 1) << 8) & ~0x3ff;
|
|
||||||
uint32_t alpha = fglevel * 256 / FRACUNIT;
|
|
||||||
uint32_t inv_alpha = 256 - alpha;
|
|
||||||
|
|
||||||
fg_red *= alpha;
|
|
||||||
fg_green *= alpha;
|
|
||||||
fg_blue *= alpha;
|
|
||||||
|
|
||||||
spacing = RenderTarget->GetPitch();
|
|
||||||
|
|
||||||
for (int x = x1; x < (x1 + countbase); x++)
|
|
||||||
{
|
|
||||||
dc_x = x;
|
|
||||||
if (R_ClipSpriteColumnWithPortals(vis))
|
|
||||||
continue;
|
|
||||||
dest = ylookup[yl] + x + (uint32_t*)dc_destorg;
|
|
||||||
for (int y = 0; y < ycount; y++)
|
|
||||||
{
|
|
||||||
uint32_t bg_red = (*dest >> 16) & 0xff;
|
|
||||||
uint32_t bg_green = (*dest >> 8) & 0xff;
|
|
||||||
uint32_t bg_blue = (*dest) & 0xff;
|
|
||||||
|
|
||||||
uint32_t red = (fg_red + bg_red * inv_alpha) / 256;
|
|
||||||
uint32_t green = (fg_green + bg_green * inv_alpha) / 256;
|
|
||||||
uint32_t blue = (fg_blue + bg_blue * inv_alpha) / 256;
|
|
||||||
|
|
||||||
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
|
|
||||||
dest += spacing;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2769,9 +2589,7 @@ void R_DrawVoxel(const FVector3 &globalpos, FAngle viewangle,
|
||||||
sprcosang = FLOAT2FIXED(dasprang.Cos()) >> 2;
|
sprcosang = FLOAT2FIXED(dasprang.Cos()) >> 2;
|
||||||
sprsinang = FLOAT2FIXED(-dasprang.Sin()) >> 2;
|
sprsinang = FLOAT2FIXED(-dasprang.Sin()) >> 2;
|
||||||
|
|
||||||
R_SetupDrawSlab(colormap);
|
DrawerContext::SetSlabLight(colormap);
|
||||||
|
|
||||||
int pixelsize = r_swtruecolor ? 4 : 1;
|
|
||||||
|
|
||||||
// Select mip level
|
// Select mip level
|
||||||
i = abs(DMulScale6(dasprx - globalposx, cosang, daspry - globalposy, sinang));
|
i = abs(DMulScale6(dasprx - globalposx, cosang, daspry - globalposy, sinang));
|
||||||
|
@ -3026,25 +2844,25 @@ void R_DrawVoxel(const FVector3 &globalpos, FAngle viewangle,
|
||||||
if (!(flags & DVF_OFFSCREEN))
|
if (!(flags & DVF_OFFSCREEN))
|
||||||
{
|
{
|
||||||
// Draw directly to the screen.
|
// Draw directly to the screen.
|
||||||
R_DrawSlab(xxr - xxl, yplc[xxl], z2 - z1, yinc, col, (ylookup[z1] + lxt + xxl) * pixelsize + dc_destorg);
|
DrawerContext::DrawSlab(xxr - xxl, yplc[xxl], z2 - z1, yinc, col, lxt + xxl, z1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Record the area covered and possibly draw to an offscreen buffer.
|
// Record the area covered and possibly draw to an offscreen buffer.
|
||||||
dc_yl = z1;
|
DrawerContext::SetY1(z1);
|
||||||
dc_yh = z2 - 1;
|
DrawerContext::SetY2(z2 - 1);
|
||||||
dc_count = z2 - z1;
|
DrawerContext::SetDrawCount(z2 - z1);
|
||||||
dc_iscale = yinc;
|
DrawerContext::SetTextureStep(yinc);
|
||||||
for (int x = xxl; x < xxr; ++x)
|
for (int x = xxl; x < xxr; ++x)
|
||||||
{
|
{
|
||||||
OffscreenCoverageBuffer->InsertSpan(lxt + x, z1, z2);
|
OffscreenCoverageBuffer->InsertSpan(lxt + x, z1, z2);
|
||||||
if (!(flags & DVF_SPANSONLY))
|
if (!(flags & DVF_SPANSONLY))
|
||||||
{
|
{
|
||||||
dc_x = lxt + x;
|
DrawerContext::RtInitCols(OffscreenColorBuffer + ((lxt + x) & ~3) * OffscreenBufferHeight);
|
||||||
rt_initcols(OffscreenColorBuffer + (dc_x & ~3) * OffscreenBufferHeight);
|
DrawerContext::SetX(lxt + x);
|
||||||
dc_source = col;
|
DrawerContext::SetSource(col);
|
||||||
dc_texturefrac = yplc[xxl];
|
DrawerContext::SetTextureFrac(yplc[xxl]);
|
||||||
hcolfunc_pre();
|
DrawerContext::DrawHColumnPre();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,11 +96,8 @@ struct vissprite_t
|
||||||
|
|
||||||
struct particle_t;
|
struct particle_t;
|
||||||
|
|
||||||
extern void(*R_DrawParticle)(vissprite_t *);
|
|
||||||
void R_DrawParticle_C (vissprite_t *);
|
|
||||||
void R_DrawParticle_rgba (vissprite_t *);
|
|
||||||
|
|
||||||
void R_ProjectParticle (particle_t *, const sector_t *sector, int shade, int fakeside);
|
void R_ProjectParticle (particle_t *, const sector_t *sector, int shade, int fakeside);
|
||||||
|
void R_DrawParticle (vissprite_t *vis);
|
||||||
|
|
||||||
extern int MaxVisSprites;
|
extern int MaxVisSprites;
|
||||||
|
|
||||||
|
@ -112,7 +109,6 @@ extern vissprite_t **vissprite_p;
|
||||||
extern short zeroarray[MAXWIDTH];
|
extern short zeroarray[MAXWIDTH];
|
||||||
extern short screenheightarray[MAXWIDTH];
|
extern short screenheightarray[MAXWIDTH];
|
||||||
|
|
||||||
// vars for R_DrawMaskedColumn
|
|
||||||
extern short* mfloorclip;
|
extern short* mfloorclip;
|
||||||
extern short* mceilingclip;
|
extern short* mceilingclip;
|
||||||
extern double spryscale;
|
extern double spryscale;
|
||||||
|
@ -126,8 +122,7 @@ extern double pspriteyscale;
|
||||||
extern FTexture *WallSpriteTile;
|
extern FTexture *WallSpriteTile;
|
||||||
|
|
||||||
|
|
||||||
void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *spans);
|
void R_WallSpriteColumn (int x, void (*drawfunc)(int x, const BYTE *column, const FTexture::Span *spans));
|
||||||
void R_WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans));
|
|
||||||
|
|
||||||
void R_CacheSprite (spritedef_t *sprite);
|
void R_CacheSprite (spritedef_t *sprite);
|
||||||
void R_SortVisSprites (int (*compare)(const void *, const void *), size_t first);
|
void R_SortVisSprites (int (*compare)(const void *, const void *), size_t first);
|
||||||
|
|
109
src/v_draw.cpp
109
src/v_draw.cpp
|
@ -43,8 +43,7 @@
|
||||||
#include "r_defs.h"
|
#include "r_defs.h"
|
||||||
#include "r_utility.h"
|
#include "r_utility.h"
|
||||||
#ifndef NO_SWRENDER
|
#ifndef NO_SWRENDER
|
||||||
#include "r_draw.h"
|
#include "r_drawer_context.h"
|
||||||
#include "r_draw_rgba.h"
|
|
||||||
#include "r_main.h"
|
#include "r_main.h"
|
||||||
#include "r_things.h"
|
#include "r_things.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -130,12 +129,14 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
|
||||||
static short bottomclipper[MAXWIDTH], topclipper[MAXWIDTH];
|
static short bottomclipper[MAXWIDTH], topclipper[MAXWIDTH];
|
||||||
const BYTE *translation = NULL;
|
const BYTE *translation = NULL;
|
||||||
|
|
||||||
if (r_swtruecolor != IsBgra())
|
DCanvas *destorgsave = DrawerContext::Canvas();
|
||||||
|
if (screen->GetBuffer() == NULL)
|
||||||
{
|
{
|
||||||
r_swtruecolor = IsBgra();
|
I_FatalError("Attempt to write to buffer of hardware canvas");
|
||||||
R_InitColumnDrawers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DrawerContext::SetCanvas(screen);
|
||||||
|
|
||||||
if (parms.masked)
|
if (parms.masked)
|
||||||
{
|
{
|
||||||
spanptr = &spans;
|
spanptr = &spans;
|
||||||
|
@ -172,22 +173,15 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
|
||||||
|
|
||||||
if (translation != NULL)
|
if (translation != NULL)
|
||||||
{
|
{
|
||||||
R_SetTranslationMap((lighttable_t *)translation);
|
DrawerContext::SetTranslationMap((lighttable_t *)translation);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
R_SetTranslationMap(identitymap);
|
DrawerContext::SetTranslationMap(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fixedcolormap = dc_fcolormap;
|
fixedcolormap = DrawerContext::LightColormap();
|
||||||
ESPSResult mode = R_SetPatchStyle (parms.style, parms.Alpha, 0, parms.fillcolor);
|
ESPSResult mode = DrawerContext::SetPatchStyle (parms.style, parms.Alpha, 0, parms.fillcolor);
|
||||||
|
|
||||||
BYTE *destorgsave = dc_destorg;
|
|
||||||
dc_destorg = screen->GetBuffer();
|
|
||||||
if (dc_destorg == NULL)
|
|
||||||
{
|
|
||||||
I_FatalError("Attempt to write to buffer of hardware canvas");
|
|
||||||
}
|
|
||||||
|
|
||||||
double x0 = parms.x - parms.left * parms.destwidth / parms.texwidth;
|
double x0 = parms.x - parms.left * parms.destwidth / parms.texwidth;
|
||||||
double y0 = parms.y - parms.top * parms.destheight / parms.texheight;
|
double y0 = parms.y - parms.top * parms.destheight / parms.texheight;
|
||||||
|
@ -220,11 +214,11 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
|
||||||
assert(spryscale > 0);
|
assert(spryscale > 0);
|
||||||
|
|
||||||
sprflipvert = false;
|
sprflipvert = false;
|
||||||
//dc_iscale = FLOAT2FIXED(iyscale);
|
//DrawerContext::SetTextureStep(FLOAT2FIXED(iyscale));
|
||||||
//dc_texturemid = (-y0) * iyscale;
|
//DrawerContext::SetTextureMid((-y0) * iyscale);
|
||||||
//dc_iscale = 0xffffffffu / (unsigned)spryscale;
|
//DrawerContext::SetTextureStep(0xffffffffu / (unsigned)spryscale);
|
||||||
dc_iscale = FLOAT2FIXED(1 / spryscale);
|
DrawerContext::SetTextureStep(FLOAT2FIXED(1 / spryscale));
|
||||||
dc_texturemid = (CenterY - 1 - sprtopscreen) * dc_iscale / 65536;
|
DrawerContext::SetTextureMid((CenterY - 1 - sprtopscreen) * DrawerContext::TextureStep() / 65536);
|
||||||
fixed_t frac = 0;
|
fixed_t frac = 0;
|
||||||
double xiscale = img->GetWidth() / parms.destwidth;
|
double xiscale = img->GetWidth() / parms.destwidth;
|
||||||
double x2 = x0 + parms.destwidth;
|
double x2 = x0 + parms.destwidth;
|
||||||
|
@ -278,14 +272,14 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
|
||||||
mode = DoDraw0;
|
mode = DoDraw0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_x = int(x0);
|
int x = int(x0);
|
||||||
int x2_i = int(x2);
|
int x2_i = int(x2);
|
||||||
fixed_t xiscale_i = FLOAT2FIXED(xiscale);
|
fixed_t xiscale_i = FLOAT2FIXED(xiscale);
|
||||||
|
|
||||||
if (mode == DoDraw0)
|
if (mode == DoDraw0)
|
||||||
{
|
{
|
||||||
// One column at a time
|
// One column at a time
|
||||||
stop4 = dc_x;
|
stop4 = x;
|
||||||
}
|
}
|
||||||
else // DoDraw1`
|
else // DoDraw1`
|
||||||
{
|
{
|
||||||
|
@ -293,42 +287,44 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
|
||||||
stop4 = x2_i & ~3;
|
stop4 = x2_i & ~3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dc_x < x2_i)
|
if (x < x2_i)
|
||||||
{
|
{
|
||||||
while ((dc_x < stop4) && (dc_x & 3))
|
DrawerContext::SetMaskedColumnState(mfloorclip, mceilingclip, spryscale, sprtopscreen, sprflipvert);
|
||||||
|
|
||||||
|
while ((x < stop4) && (x & 3))
|
||||||
{
|
{
|
||||||
pixels = img->GetColumn(frac >> FRACBITS, spanptr);
|
pixels = img->GetColumn(frac >> FRACBITS, spanptr);
|
||||||
R_DrawMaskedColumn(pixels, spans);
|
DrawerContext::DrawMaskedColumn(x, pixels, spans);
|
||||||
dc_x++;
|
x++;
|
||||||
frac += xiscale_i;
|
frac += xiscale_i;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (dc_x < stop4)
|
while (x < stop4)
|
||||||
{
|
{
|
||||||
rt_initcols(nullptr);
|
DrawerContext::RtInitCols(nullptr);
|
||||||
for (int zz = 4; zz; --zz)
|
for (int zz = 0; zz < 4; ++zz)
|
||||||
{
|
{
|
||||||
pixels = img->GetColumn(frac >> FRACBITS, spanptr);
|
pixels = img->GetColumn(frac >> FRACBITS, spanptr);
|
||||||
R_DrawMaskedColumnHoriz(pixels, spans);
|
DrawerContext::DrawMaskedColumnHoriz(x + zz, pixels, spans);
|
||||||
dc_x++;
|
|
||||||
frac += xiscale_i;
|
frac += xiscale_i;
|
||||||
}
|
}
|
||||||
rt_draw4cols(dc_x - 4);
|
DrawerContext::DrawRt4cols(x);
|
||||||
|
x += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (dc_x < x2_i)
|
while (x < x2_i)
|
||||||
{
|
{
|
||||||
pixels = img->GetColumn(frac >> FRACBITS, spanptr);
|
pixels = img->GetColumn(frac >> FRACBITS, spanptr);
|
||||||
R_DrawMaskedColumn(pixels, spans);
|
DrawerContext::DrawMaskedColumn(x, pixels, spans);
|
||||||
dc_x++;
|
x++;
|
||||||
frac += xiscale_i;
|
frac += xiscale_i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CenterY = centeryback;
|
CenterY = centeryback;
|
||||||
}
|
}
|
||||||
R_FinishSetPatchStyle ();
|
DrawerContext::FinishSetPatchStyle ();
|
||||||
|
|
||||||
dc_destorg = destorgsave;
|
DrawerContext::SetCanvas(destorgsave);
|
||||||
|
|
||||||
if (ticdup != 0 && menuactive == MENU_Off)
|
if (ticdup != 0 && menuactive == MENU_Off)
|
||||||
{
|
{
|
||||||
|
@ -1024,9 +1020,11 @@ void DCanvas::PUTTRANSDOT (int xx, int yy, int basecolor, int level)
|
||||||
|
|
||||||
if (IsBgra())
|
if (IsBgra())
|
||||||
{
|
{
|
||||||
|
int inv_level = 64 - level;
|
||||||
|
|
||||||
uint32_t *spot = (uint32_t*)GetBuffer() + oldyyshifted + xx;
|
uint32_t *spot = (uint32_t*)GetBuffer() + oldyyshifted + xx;
|
||||||
|
|
||||||
uint32_t fg = shade_pal_index_simple(basecolor, calc_light_multiplier(0));
|
uint32_t fg = GPalette.BaseColors[basecolor].d;
|
||||||
uint32_t fg_red = (fg >> 16) & 0xff;
|
uint32_t fg_red = (fg >> 16) & 0xff;
|
||||||
uint32_t fg_green = (fg >> 8) & 0xff;
|
uint32_t fg_green = (fg >> 8) & 0xff;
|
||||||
uint32_t fg_blue = fg & 0xff;
|
uint32_t fg_blue = fg & 0xff;
|
||||||
|
@ -1035,9 +1033,9 @@ void DCanvas::PUTTRANSDOT (int xx, int yy, int basecolor, int level)
|
||||||
uint32_t bg_green = (*spot >> 8) & 0xff;
|
uint32_t bg_green = (*spot >> 8) & 0xff;
|
||||||
uint32_t bg_blue = (*spot) & 0xff;
|
uint32_t bg_blue = (*spot) & 0xff;
|
||||||
|
|
||||||
uint32_t red = (fg_red + bg_red + 1) / 2;
|
uint32_t red = (fg_red * level + bg_red * inv_level + 1) / 64;
|
||||||
uint32_t green = (fg_green + bg_green + 1) / 2;
|
uint32_t green = (fg_green * level + bg_green * inv_level + 1) / 64;
|
||||||
uint32_t blue = (fg_blue + bg_blue + 1) / 2;
|
uint32_t blue = (fg_blue * level + bg_blue * inv_level + 1) / 64;
|
||||||
|
|
||||||
*spot = 0xff000000 | (red << 16) | (green << 8) | blue;
|
*spot = 0xff000000 | (red << 16) | (green << 8) | blue;
|
||||||
}
|
}
|
||||||
|
@ -1399,16 +1397,15 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,
|
||||||
sinrot = sin(rotation.Radians());
|
sinrot = sin(rotation.Radians());
|
||||||
|
|
||||||
// Setup constant texture mapping parameters.
|
// Setup constant texture mapping parameters.
|
||||||
R_SetupSpanBits(tex);
|
|
||||||
if (colormap)
|
if (colormap)
|
||||||
R_SetSpanColormap(colormap, clamp(shade >> FRACBITS, 0, NUMCOLORMAPS - 1));
|
DrawerContext::SetSpanLight(colormap, 0, clamp(shade >> FRACBITS, 0, NUMCOLORMAPS - 1));
|
||||||
else
|
else
|
||||||
R_SetSpanColormap(&identitycolormap, 0);
|
DrawerContext::SetSpanLight(nullptr, 0, 0);
|
||||||
R_SetSpanSource(r_swtruecolor ? (const BYTE*)tex->GetPixelsBgra() : tex->GetPixels());
|
DrawerContext::SetSpanSource(tex);
|
||||||
scalex = double(1u << (32 - ds_xbits)) / scalex;
|
scalex = double(1u << (32 - DrawerContext::SpanXBits())) / scalex;
|
||||||
scaley = double(1u << (32 - ds_ybits)) / scaley;
|
scaley = double(1u << (32 - DrawerContext::SpanYBits())) / scaley;
|
||||||
ds_xstep = xs_RoundToInt(cosrot * scalex);
|
DrawerContext::SetSpanXStep(xs_RoundToInt(cosrot * scalex));
|
||||||
ds_ystep = xs_RoundToInt(sinrot * scaley);
|
DrawerContext::SetSpanYStep(xs_RoundToInt(sinrot * scaley));
|
||||||
|
|
||||||
// Travel down the right edge and create an outline of that edge.
|
// Travel down the right edge and create an outline of that edge.
|
||||||
pt1 = toppt;
|
pt1 = toppt;
|
||||||
|
@ -1472,9 +1469,9 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,
|
||||||
#if 0
|
#if 0
|
||||||
memset(this->Buffer + y * this->Pitch + x1, (int)tex, x2 - x1);
|
memset(this->Buffer + y * this->Pitch + x1, (int)tex, x2 - x1);
|
||||||
#else
|
#else
|
||||||
ds_y = y;
|
DrawerContext::SetSpanY(y);
|
||||||
ds_x1 = x1;
|
DrawerContext::SetSpanX1(x1);
|
||||||
ds_x2 = x2 - 1;
|
DrawerContext::SetSpanX2(x2 - 1);
|
||||||
|
|
||||||
DVector2 tex(x1 - originx, y - originy);
|
DVector2 tex(x1 - originx, y - originy);
|
||||||
if (dorotate)
|
if (dorotate)
|
||||||
|
@ -1483,10 +1480,10 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,
|
||||||
tex.X = t * cosrot - tex.Y * sinrot;
|
tex.X = t * cosrot - tex.Y * sinrot;
|
||||||
tex.Y = tex.Y * cosrot + t * sinrot;
|
tex.Y = tex.Y * cosrot + t * sinrot;
|
||||||
}
|
}
|
||||||
ds_xfrac = xs_RoundToInt(tex.X * scalex);
|
DrawerContext::SetSpanXFrac(xs_RoundToInt(tex.X * scalex));
|
||||||
ds_yfrac = xs_RoundToInt(tex.Y * scaley);
|
DrawerContext::SetSpanYFrac(xs_RoundToInt(tex.Y * scaley));
|
||||||
|
|
||||||
R_DrawSpan();
|
DrawerContext::DrawSimplePolySpan();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
x += xinc;
|
x += xinc;
|
||||||
|
|
Loading…
Reference in a new issue