2006-02-24 04:48:15 +00:00
|
|
|
// 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:
|
|
|
|
// Refresh of things, i.e. objects represented by sprites.
|
|
|
|
//
|
2011-01-02 18:02:27 +00:00
|
|
|
// This file contains some code from the Build Engine.
|
|
|
|
//
|
|
|
|
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
|
|
|
// Ken Silverman's official web site: "http://www.advsys.net/ken"
|
|
|
|
// See the included license file "BUILDLIC.TXT" for license info.
|
|
|
|
//
|
2006-02-24 04:48:15 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2009-12-18 03:05:38 +00:00
|
|
|
#include <algorithm>
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
#include "templates.h"
|
|
|
|
#include "doomdef.h"
|
|
|
|
#include "m_swap.h"
|
|
|
|
#include "m_argv.h"
|
|
|
|
#include "i_system.h"
|
|
|
|
#include "w_wad.h"
|
|
|
|
#include "r_local.h"
|
|
|
|
#include "c_console.h"
|
|
|
|
#include "c_cvars.h"
|
|
|
|
#include "c_dispatch.h"
|
|
|
|
#include "doomstat.h"
|
|
|
|
#include "v_video.h"
|
|
|
|
#include "sc_man.h"
|
|
|
|
#include "s_sound.h"
|
|
|
|
#include "sbar.h"
|
|
|
|
#include "gi.h"
|
2008-06-15 18:36:26 +00:00
|
|
|
#include "r_sky.h"
|
2008-09-14 23:54:38 +00:00
|
|
|
#include "cmdlib.h"
|
|
|
|
#include "g_level.h"
|
|
|
|
#include "d_net.h"
|
|
|
|
#include "colormatcher.h"
|
2008-09-15 00:47:31 +00:00
|
|
|
#include "d_netinf.h"
|
2008-09-15 14:11:05 +00:00
|
|
|
#include "r_bsp.h"
|
|
|
|
#include "r_plane.h"
|
|
|
|
#include "r_segs.h"
|
2011-01-29 11:09:38 +00:00
|
|
|
#include "r_3dfloors.h"
|
2008-09-15 14:11:05 +00:00
|
|
|
#include "v_palette.h"
|
2011-07-06 08:50:15 +00:00
|
|
|
#include "r_data/r_translate.h"
|
2011-07-06 07:35:36 +00:00
|
|
|
#include "r_data/colormaps.h"
|
|
|
|
#include "r_data/voxels.h"
|
2008-09-15 14:11:05 +00:00
|
|
|
|
2011-07-06 10:24:40 +00:00
|
|
|
|
|
|
|
void R_DeinitSpriteData();
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
extern fixed_t globaluclip, globaldclip;
|
|
|
|
|
|
|
|
|
|
|
|
#define MINZ (2048*4)
|
|
|
|
#define BASEYCENTER (100)
|
|
|
|
|
|
|
|
EXTERN_CVAR (Bool, st_scale)
|
2011-05-11 04:16:45 +00:00
|
|
|
EXTERN_CVAR(Bool, r_shadercolormaps)
|
2011-07-05 20:41:53 +00:00
|
|
|
EXTERN_CVAR(Int, r_drawfuzz)
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// Sprite rotation 0 is facing the viewer,
|
|
|
|
// rotation 1 is one angle turn CLOCKWISE around the axis.
|
|
|
|
// This is not the same as the angle,
|
|
|
|
// which increases counter clockwise (protractor).
|
|
|
|
//
|
|
|
|
fixed_t pspritexscale;
|
|
|
|
fixed_t pspriteyscale;
|
|
|
|
fixed_t pspritexiscale;
|
|
|
|
fixed_t sky1scale; // [RH] Sky 1 scale factor
|
|
|
|
fixed_t sky2scale; // [RH] Sky 2 scale factor
|
|
|
|
|
2009-09-20 03:50:05 +00:00
|
|
|
vissprite_t *VisPSprites[NUMPSPRITES];
|
|
|
|
int VisPSpritesX1[NUMPSPRITES];
|
|
|
|
FDynamicColormap *VisPSpritesBaseColormap[NUMPSPRITES];
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
static int spriteshade;
|
|
|
|
|
|
|
|
TArray<WORD> ParticlesInSubsec;
|
|
|
|
|
|
|
|
// constant arrays
|
|
|
|
// used for psprite clipping and initializing clipping
|
|
|
|
short zeroarray[MAXWIDTH];
|
|
|
|
short screenheightarray[MAXWIDTH];
|
|
|
|
|
|
|
|
CVAR (Bool, r_drawplayersprites, true, 0) // [RH] Draw player sprites?
|
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
CVAR (Bool, r_drawvoxels, true, 0)
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
//
|
|
|
|
// INITIALIZATION FUNCTIONS
|
|
|
|
//
|
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
int OffscreenBufferWidth, OffscreenBufferHeight;
|
|
|
|
BYTE *OffscreenColorBuffer;
|
|
|
|
FCoverageBuffer *OffscreenCoverageBuffer;
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
// [RH] particle globals
|
2006-12-21 04:34:43 +00:00
|
|
|
WORD NumParticles;
|
|
|
|
WORD ActiveParticles;
|
|
|
|
WORD InactiveParticles;
|
2006-02-24 04:48:15 +00:00
|
|
|
particle_t *Particles;
|
|
|
|
|
|
|
|
CVAR (Bool, r_particles, true, 0);
|
|
|
|
|
|
|
|
//
|
|
|
|
// GAME FUNCTIONS
|
|
|
|
//
|
|
|
|
int MaxVisSprites;
|
|
|
|
vissprite_t **vissprites;
|
|
|
|
vissprite_t **firstvissprite;
|
|
|
|
vissprite_t **vissprite_p;
|
|
|
|
vissprite_t **lastvissprite;
|
|
|
|
int newvissprite;
|
|
|
|
|
2006-05-12 03:14:40 +00:00
|
|
|
static vissprite_t **spritesorter;
|
|
|
|
static int spritesortersize = 0;
|
|
|
|
static int vsprcount;
|
2006-05-11 04:00:58 +00:00
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2006-05-12 03:14:40 +00:00
|
|
|
void R_DeinitSprites()
|
2006-05-09 15:07:45 +00:00
|
|
|
{
|
2011-07-06 10:24:40 +00:00
|
|
|
R_DeinitSpriteData();
|
2006-05-12 03:14:40 +00:00
|
|
|
|
|
|
|
// Free vissprites
|
|
|
|
for (int i = 0; i < MaxVisSprites; ++i)
|
2006-05-09 15:07:45 +00:00
|
|
|
{
|
2006-05-12 03:14:40 +00:00
|
|
|
delete vissprites[i];
|
2006-05-09 15:07:45 +00:00
|
|
|
}
|
2006-05-12 03:14:40 +00:00
|
|
|
free (vissprites);
|
|
|
|
vissprites = NULL;
|
|
|
|
vissprite_p = lastvissprite = NULL;
|
|
|
|
MaxVisSprites = 0;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2006-05-12 03:14:40 +00:00
|
|
|
// Free vissprites sorter
|
|
|
|
if (spritesorter != NULL)
|
|
|
|
{
|
|
|
|
delete[] spritesorter;
|
|
|
|
spritesortersize = 0;
|
|
|
|
spritesorter = NULL;
|
|
|
|
}
|
2011-01-02 18:02:27 +00:00
|
|
|
|
|
|
|
// Free offscreen buffer
|
|
|
|
if (OffscreenColorBuffer != NULL)
|
|
|
|
{
|
|
|
|
delete[] OffscreenColorBuffer;
|
|
|
|
OffscreenColorBuffer = NULL;
|
|
|
|
}
|
|
|
|
if (OffscreenCoverageBuffer != NULL)
|
|
|
|
{
|
|
|
|
delete OffscreenCoverageBuffer;
|
|
|
|
OffscreenCoverageBuffer = NULL;
|
|
|
|
}
|
|
|
|
OffscreenBufferHeight = OffscreenBufferWidth = 0;
|
2006-05-12 03:14:40 +00:00
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// R_ClearSprites
|
|
|
|
// Called at frame start.
|
|
|
|
//
|
|
|
|
void R_ClearSprites (void)
|
|
|
|
{
|
|
|
|
vissprite_p = firstvissprite;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// R_NewVisSprite
|
|
|
|
//
|
|
|
|
vissprite_t *R_NewVisSprite (void)
|
|
|
|
{
|
|
|
|
if (vissprite_p == lastvissprite)
|
|
|
|
{
|
|
|
|
ptrdiff_t firstvisspritenum = firstvissprite - vissprites;
|
|
|
|
ptrdiff_t prevvisspritenum = vissprite_p - vissprites;
|
|
|
|
|
|
|
|
MaxVisSprites = MaxVisSprites ? MaxVisSprites * 2 : 128;
|
2006-05-04 03:49:46 +00:00
|
|
|
vissprites = (vissprite_t **)M_Realloc (vissprites, MaxVisSprites * sizeof(vissprite_t));
|
2006-02-24 04:48:15 +00:00
|
|
|
lastvissprite = &vissprites[MaxVisSprites];
|
|
|
|
firstvissprite = &vissprites[firstvisspritenum];
|
|
|
|
vissprite_p = &vissprites[prevvisspritenum];
|
|
|
|
DPrintf ("MaxVisSprites increased to %d\n", MaxVisSprites);
|
|
|
|
|
|
|
|
// Allocate sprites from the new pile
|
|
|
|
for (vissprite_t **p = vissprite_p; p < lastvissprite; ++p)
|
|
|
|
{
|
|
|
|
*p = new vissprite_t;
|
|
|
|
}
|
|
|
|
}
|
2011-01-02 18:02:27 +00:00
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
vissprite_p++;
|
|
|
|
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* mceilingclip;
|
|
|
|
|
|
|
|
fixed_t spryscale;
|
|
|
|
fixed_t sprtopscreen;
|
|
|
|
|
|
|
|
bool sprflipvert;
|
|
|
|
|
|
|
|
void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *span)
|
|
|
|
{
|
|
|
|
while (span->Length != 0)
|
|
|
|
{
|
|
|
|
const int length = span->Length;
|
|
|
|
const int top = span->TopOffset;
|
|
|
|
|
|
|
|
// calculate unclipped screen coordinates for post
|
|
|
|
dc_yl = (sprtopscreen + spryscale * top) >> FRACBITS;
|
|
|
|
dc_yh = (sprtopscreen + spryscale * (top + length) - FRACUNIT) >> FRACBITS;
|
|
|
|
|
|
|
|
if (sprflipvert)
|
|
|
|
{
|
2010-07-23 21:19:59 +00:00
|
|
|
swapvalues (dc_yl, dc_yh);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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) - dc_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 = dc_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 + dc_destorg;
|
|
|
|
dc_count = dc_yh - dc_yl + 1;
|
|
|
|
colfunc ();
|
|
|
|
}
|
|
|
|
nextpost:
|
|
|
|
span++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// R_DrawVisSprite
|
|
|
|
// mfloorclip and mceilingclip should also be set.
|
|
|
|
//
|
|
|
|
void R_DrawVisSprite (vissprite_t *vis)
|
|
|
|
{
|
|
|
|
const BYTE *pixels;
|
|
|
|
const FTexture::Span *spans;
|
|
|
|
fixed_t frac;
|
|
|
|
FTexture *tex;
|
|
|
|
int x2, stop4;
|
|
|
|
fixed_t xiscale;
|
|
|
|
ESPSResult mode;
|
|
|
|
|
|
|
|
dc_colormap = vis->colormap;
|
|
|
|
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
mode = R_SetPatchStyle (vis->RenderStyle, vis->alpha, vis->Translation, vis->FillColor);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
if (mode != DontDraw)
|
|
|
|
{
|
|
|
|
if (mode == DoDraw0)
|
|
|
|
{
|
|
|
|
// One column at a time
|
|
|
|
stop4 = vis->x1;
|
|
|
|
}
|
|
|
|
else // DoDraw1
|
|
|
|
{
|
|
|
|
// Up to four columns at a time
|
|
|
|
stop4 = (vis->x2 + 1) & ~3;
|
|
|
|
}
|
|
|
|
|
|
|
|
tex = vis->pic;
|
|
|
|
spryscale = vis->yscale;
|
|
|
|
sprflipvert = false;
|
|
|
|
dc_iscale = 0xffffffffu / (unsigned)vis->yscale;
|
|
|
|
dc_texturemid = vis->texturemid;
|
|
|
|
frac = vis->startfrac;
|
|
|
|
xiscale = vis->xiscale;
|
|
|
|
|
|
|
|
sprtopscreen = centeryfrac - FixedMul (dc_texturemid, spryscale);
|
|
|
|
|
|
|
|
dc_x = vis->x1;
|
|
|
|
x2 = vis->x2 + 1;
|
|
|
|
|
|
|
|
if (dc_x < x2)
|
|
|
|
{
|
|
|
|
while ((dc_x < stop4) && (dc_x & 3))
|
|
|
|
{
|
|
|
|
pixels = tex->GetColumn (frac >> FRACBITS, &spans);
|
|
|
|
R_DrawMaskedColumn (pixels, spans);
|
|
|
|
dc_x++;
|
|
|
|
frac += xiscale;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (dc_x < stop4)
|
|
|
|
{
|
|
|
|
rt_initcols();
|
|
|
|
for (int zz = 4; zz; --zz)
|
|
|
|
{
|
|
|
|
pixels = tex->GetColumn (frac >> FRACBITS, &spans);
|
|
|
|
R_DrawMaskedColumnHoriz (pixels, spans);
|
|
|
|
dc_x++;
|
|
|
|
frac += xiscale;
|
|
|
|
}
|
|
|
|
rt_draw4cols (dc_x - 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (dc_x < x2)
|
|
|
|
{
|
|
|
|
pixels = tex->GetColumn (frac >> FRACBITS, &spans);
|
|
|
|
R_DrawMaskedColumn (pixels, spans);
|
|
|
|
dc_x++;
|
|
|
|
frac += xiscale;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
R_FinishSetPatchStyle ();
|
|
|
|
|
|
|
|
NetUpdate ();
|
|
|
|
}
|
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop, short *clipbot)
|
|
|
|
{
|
|
|
|
ESPSResult mode;
|
|
|
|
int flags = 0;
|
|
|
|
|
|
|
|
// Do setup for blending.
|
|
|
|
dc_colormap = spr->colormap;
|
|
|
|
mode = R_SetPatchStyle(spr->RenderStyle, spr->alpha, spr->Translation, spr->FillColor);
|
|
|
|
|
|
|
|
if (mode == DontDraw)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (colfunc == fuzzcolfunc || colfunc == R_FillColumnP)
|
|
|
|
{
|
|
|
|
flags = DVF_OFFSCREEN | DVF_SPANSONLY;
|
|
|
|
}
|
|
|
|
else if (colfunc != basecolfunc)
|
|
|
|
{
|
|
|
|
flags = DVF_OFFSCREEN;
|
|
|
|
}
|
|
|
|
if (flags != 0)
|
|
|
|
{
|
|
|
|
R_CheckOffscreenBuffer(RenderTarget->GetWidth(), RenderTarget->GetHeight(), !!(flags & DVF_SPANSONLY));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Render the voxel, either directly to the screen or offscreen.
|
|
|
|
R_DrawVoxel(spr->gx, spr->gy, spr->gz, spr->angle, spr->xscale, spr->yscale, spr->voxel, spr->colormap, cliptop, clipbot,
|
|
|
|
minslabz, maxslabz, flags);
|
|
|
|
|
|
|
|
// Blend the voxel, if that's what we need to do.
|
|
|
|
if (flags != 0)
|
|
|
|
{
|
|
|
|
for (int x = 0; x < viewwidth; ++x)
|
|
|
|
{
|
|
|
|
if (!(flags & DVF_SPANSONLY) && (x & 3) == 0)
|
|
|
|
{
|
|
|
|
rt_initcols(OffscreenColorBuffer + x * OffscreenBufferHeight);
|
|
|
|
}
|
|
|
|
for (FCoverageBuffer::Span *span = OffscreenCoverageBuffer->Spans[x]; span != NULL; span = span->NextSpan)
|
|
|
|
{
|
|
|
|
if (flags & DVF_SPANSONLY)
|
|
|
|
{
|
|
|
|
dc_x = x;
|
|
|
|
dc_yl = span->Start;
|
|
|
|
dc_yh = span->Stop - 1;
|
|
|
|
dc_count = span->Stop - span->Start;
|
|
|
|
dc_dest = ylookup[span->Start] + x + dc_destorg;
|
|
|
|
colfunc();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
unsigned int **tspan = &dc_ctspan[x & 3];
|
|
|
|
(*tspan)[0] = span->Start;
|
|
|
|
(*tspan)[1] = span->Stop - 1;
|
|
|
|
*tspan += 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!(flags & DVF_SPANSONLY) && (x & 3) == 3)
|
|
|
|
{
|
|
|
|
rt_draw4cols(x - 3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
R_FinishSetPatchStyle();
|
|
|
|
NetUpdate();
|
|
|
|
}
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
//
|
|
|
|
// R_ProjectSprite
|
|
|
|
// Generates a vissprite for a thing if it might be visible.
|
|
|
|
//
|
2011-01-29 11:09:38 +00:00
|
|
|
void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
fixed_t fx, fy, fz;
|
|
|
|
fixed_t tr_x;
|
|
|
|
fixed_t tr_y;
|
|
|
|
|
|
|
|
fixed_t gzt; // killough 3/27/98
|
|
|
|
fixed_t gzb; // [RH] use bottom of sprite, not actor
|
|
|
|
fixed_t tx, tx2;
|
|
|
|
fixed_t tz;
|
|
|
|
|
2011-03-29 05:20:33 +00:00
|
|
|
fixed_t xscale = FRACUNIT, yscale = FRACUNIT;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
int x1;
|
|
|
|
int x2;
|
|
|
|
|
2008-06-15 18:36:26 +00:00
|
|
|
FTextureID picnum;
|
2006-02-24 04:48:15 +00:00
|
|
|
FTexture *tex;
|
2011-01-02 18:02:27 +00:00
|
|
|
FVoxelDef *voxel;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
WORD flip;
|
|
|
|
|
|
|
|
vissprite_t* vis;
|
|
|
|
|
|
|
|
fixed_t iscale;
|
|
|
|
|
|
|
|
sector_t* heightsec; // killough 3/27/98
|
|
|
|
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
// Don't waste time projecting sprites that are definitely not visible.
|
2006-02-24 04:48:15 +00:00
|
|
|
if (thing == NULL ||
|
|
|
|
(thing->renderflags & RF_INVISIBLE) ||
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
!thing->RenderStyle.IsVisible(thing->alpha))
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// [RH] Interpolate the sprite's position to make it look smooth
|
|
|
|
fx = thing->PrevX + FixedMul (r_TicFrac, thing->x - thing->PrevX);
|
|
|
|
fy = thing->PrevY + FixedMul (r_TicFrac, thing->y - thing->PrevY);
|
|
|
|
fz = thing->PrevZ + FixedMul (r_TicFrac, thing->z - thing->PrevZ);
|
|
|
|
|
|
|
|
// transform the origin point
|
|
|
|
tr_x = fx - viewx;
|
|
|
|
tr_y = fy - viewy;
|
|
|
|
|
|
|
|
tz = DMulScale20 (tr_x, viewtancos, tr_y, viewtansin);
|
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
tex = NULL;
|
|
|
|
voxel = NULL;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2008-06-15 18:36:26 +00:00
|
|
|
if (thing->picnum.isValid())
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
picnum = thing->picnum;
|
|
|
|
|
|
|
|
tex = TexMan(picnum);
|
|
|
|
if (tex->UseType == FTexture::TEX_Null)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
flip = 0;
|
|
|
|
|
2006-10-20 04:04:04 +00:00
|
|
|
if (tex->Rotations != 0xFFFF)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2006-10-20 04:04:04 +00:00
|
|
|
// choose a different rotation based on player view
|
|
|
|
spriteframe_t *sprframe = &SpriteFrames[tex->Rotations];
|
|
|
|
angle_t ang = R_PointToAngle (fx, fy);
|
|
|
|
angle_t rot;
|
|
|
|
if (sprframe->Texture[0] == sprframe->Texture[1])
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2006-10-20 04:04:04 +00:00
|
|
|
rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9) >> 28;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
2006-10-20 04:04:04 +00:00
|
|
|
picnum = sprframe->Texture[rot];
|
|
|
|
flip = sprframe->Flip & (1 << rot);
|
|
|
|
tex = TexMan[picnum]; // Do not animate the rotation
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// decide which texture to use for the sprite
|
|
|
|
#ifdef RANGECHECK
|
|
|
|
if ((unsigned)thing->sprite >= (unsigned)sprites.Size ())
|
|
|
|
{
|
|
|
|
DPrintf ("R_ProjectSprite: invalid sprite number %i\n", thing->sprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
spritedef_t *sprdef = &sprites[thing->sprite];
|
|
|
|
if (thing->frame >= sprdef->numframes)
|
|
|
|
{
|
|
|
|
// If there are no frames at all for this sprite, don't draw it.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//picnum = SpriteFrames[sprdef->spriteframes + thing->frame].Texture[0];
|
|
|
|
// choose a different rotation based on player view
|
|
|
|
spriteframe_t *sprframe = &SpriteFrames[sprdef->spriteframes + thing->frame];
|
|
|
|
angle_t ang = R_PointToAngle (fx, fy);
|
|
|
|
angle_t rot;
|
|
|
|
if (sprframe->Texture[0] == sprframe->Texture[1])
|
|
|
|
{
|
|
|
|
rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9) >> 28;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28;
|
|
|
|
}
|
|
|
|
picnum = sprframe->Texture[rot];
|
|
|
|
flip = sprframe->Flip & (1 << rot);
|
|
|
|
tex = TexMan[picnum]; // Do not animate the rotation
|
2011-01-02 18:02:27 +00:00
|
|
|
if (r_drawvoxels)
|
|
|
|
{
|
|
|
|
voxel = sprframe->Voxel;
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-02 18:02:27 +00:00
|
|
|
if (voxel == NULL && (tex == NULL || tex->UseType == FTexture::TEX_Null))
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
// thing is behind view plane?
|
|
|
|
if (voxel == NULL && tz < MINZ)
|
2006-02-24 04:48:15 +00:00
|
|
|
return;
|
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
tx = DMulScale16 (tr_x, viewsin, -tr_y, viewcos);
|
|
|
|
|
|
|
|
// [RH] Flip for mirrors
|
|
|
|
if (MirrorFlags & RF_XFLIP)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2011-01-02 18:02:27 +00:00
|
|
|
tx = -tx;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
2011-01-02 18:02:27 +00:00
|
|
|
tx2 = tx >> 4;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
// too far off the side?
|
|
|
|
if ((abs(tx) >> 6) > abs(tz))
|
|
|
|
{
|
2006-02-24 04:48:15 +00:00
|
|
|
return;
|
2011-01-02 18:02:27 +00:00
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
if (voxel == NULL)
|
|
|
|
{
|
|
|
|
// [RH] Added scaling
|
|
|
|
int scaled_to = tex->GetScaledTopOffset();
|
|
|
|
int scaled_bo = scaled_to - tex->GetScaledHeight();
|
|
|
|
gzt = fz + thing->scaleY * scaled_to;
|
|
|
|
gzb = fz + thing->scaleY * scaled_bo;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xscale = FixedMul(thing->scaleX, voxel->Scale);
|
|
|
|
yscale = FixedMul(thing->scaleY, voxel->Scale);
|
|
|
|
gzt = fz + MulScale8(yscale, voxel->Voxel->Mips[0].PivotZ) - thing->floorclip;
|
|
|
|
gzb = fz + MulScale8(yscale, voxel->Voxel->Mips[0].PivotZ - (voxel->Voxel->Mips[0].SizeZ << 8));
|
|
|
|
if (gzt <= gzb)
|
|
|
|
return;
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// killough 3/27/98: exclude things totally separated
|
|
|
|
// from the viewer, by either water or fake ceilings
|
|
|
|
// killough 4/11/98: improve sprite clipping for underwater/fake ceilings
|
|
|
|
|
2009-05-23 10:21:33 +00:00
|
|
|
heightsec = thing->Sector->GetHeightSec();
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2009-05-23 10:21:33 +00:00
|
|
|
if (heightsec != NULL) // only clip things which are in special sectors
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
if (fakeside == FAKED_AboveCeiling)
|
|
|
|
{
|
|
|
|
if (gzt < heightsec->ceilingplane.ZatPoint (fx, fy))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (fakeside == FAKED_BelowFloor)
|
|
|
|
{
|
|
|
|
if (gzb >= heightsec->floorplane.ZatPoint (fx, fy))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (gzt < heightsec->floorplane.ZatPoint (fx, fy))
|
|
|
|
return;
|
|
|
|
if (gzb >= heightsec->ceilingplane.ZatPoint (fx, fy))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
if (voxel == NULL)
|
|
|
|
{
|
|
|
|
xscale = DivScale12 (centerxfrac, tz);
|
|
|
|
|
|
|
|
// [RH] Reject sprites that are off the top or bottom of the screen
|
|
|
|
if (MulScale12 (globaluclip, tz) > viewz - gzb ||
|
|
|
|
MulScale12 (globaldclip, tz) < viewz - gzt)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// [RH] Flip for mirrors and renderflags
|
|
|
|
if ((MirrorFlags ^ thing->renderflags) & RF_XFLIP)
|
|
|
|
{
|
|
|
|
flip = !flip;
|
|
|
|
}
|
|
|
|
|
|
|
|
// calculate edges of the shape
|
|
|
|
const fixed_t thingxscalemul = DivScale16(thing->scaleX, tex->xScale);
|
|
|
|
|
|
|
|
tx -= (flip ? (tex->GetWidth() - tex->LeftOffset - 1) : tex->LeftOffset) * thingxscalemul;
|
|
|
|
x1 = centerx + MulScale32 (tx, xscale);
|
|
|
|
|
|
|
|
// off the right side?
|
|
|
|
if (x1 > WindowRight)
|
|
|
|
return;
|
|
|
|
|
|
|
|
tx += tex->GetWidth() * thingxscalemul;
|
|
|
|
x2 = centerx + MulScale32 (tx, xscale);
|
|
|
|
|
|
|
|
// off the left side or too small?
|
|
|
|
if ((x2 < WindowLeft || x2 <= x1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
xscale = FixedDiv(FixedMul(thing->scaleX, xscale), tex->xScale);
|
|
|
|
iscale = (tex->GetWidth() << FRACBITS) / (x2 - x1);
|
|
|
|
x2--;
|
|
|
|
|
|
|
|
fixed_t yscale = SafeDivScale16(thing->scaleY, tex->yScale);
|
|
|
|
|
|
|
|
// store information in a vissprite
|
|
|
|
vis = R_NewVisSprite();
|
|
|
|
|
|
|
|
vis->xscale = xscale;
|
|
|
|
vis->yscale = Scale(InvZtoScale, yscale, tz << 4);
|
|
|
|
vis->idepth = (unsigned)DivScale32(1, tz) >> 1; // tz is 20.12, so idepth ought to be 12.20, but signed math makes it 13.19
|
|
|
|
vis->floorclip = FixedDiv (thing->floorclip, yscale);
|
|
|
|
vis->texturemid = (tex->TopOffset << FRACBITS) - FixedDiv (viewz - fz + thing->floorclip, yscale);
|
|
|
|
vis->x1 = x1 < WindowLeft ? WindowLeft : x1;
|
|
|
|
vis->x2 = x2 > WindowRight ? WindowRight : x2;
|
|
|
|
vis->angle = thing->angle;
|
|
|
|
|
|
|
|
if (flip)
|
|
|
|
{
|
|
|
|
vis->startfrac = (tex->GetWidth() << FRACBITS) - 1;
|
|
|
|
vis->xiscale = -iscale;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vis->startfrac = 0;
|
|
|
|
vis->xiscale = iscale;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vis->x1 > x1)
|
|
|
|
vis->startfrac += vis->xiscale * (vis->x1 - x1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vis = R_NewVisSprite();
|
|
|
|
|
|
|
|
vis->xscale = xscale;
|
|
|
|
vis->yscale = yscale;
|
|
|
|
vis->x1 = WindowLeft;
|
|
|
|
vis->x2 = WindowRight;
|
|
|
|
vis->idepth = (unsigned)DivScale32(1, MAX(tz, MINZ)) >> 1;
|
|
|
|
vis->floorclip = thing->floorclip;
|
|
|
|
|
|
|
|
fz -= thing->floorclip;
|
|
|
|
|
|
|
|
vis->angle = thing->angle + voxel->AngleOffset;
|
|
|
|
|
|
|
|
int voxelspin = (thing->flags & MF_DROPPED) ? voxel->DroppedSpin : voxel->PlacedSpin;
|
|
|
|
if (voxelspin != 0)
|
|
|
|
{
|
|
|
|
double ang = double(I_FPSTime()) * voxelspin / 1000;
|
|
|
|
vis->angle += angle_t(ang * (4294967296.f / 360));
|
|
|
|
}
|
|
|
|
|
|
|
|
// These are irrelevant for voxels.
|
|
|
|
vis->texturemid = 0x1CEDBEEF;
|
|
|
|
vis->startfrac = 0x1CEDBEEF;
|
|
|
|
vis->xiscale = 0x1CEDBEEF;
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// killough 3/27/98: save sector for special clipping later
|
|
|
|
vis->heightsec = heightsec;
|
|
|
|
vis->sector = thing->Sector;
|
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
vis->cx = tx2;
|
2009-02-07 03:01:38 +00:00
|
|
|
vis->depth = tz;
|
2006-02-24 04:48:15 +00:00
|
|
|
vis->gx = fx;
|
|
|
|
vis->gy = fy;
|
2011-01-02 18:02:27 +00:00
|
|
|
vis->gz = fz;
|
|
|
|
vis->gzb = gzb; // [RH] use gzb, not thing->z
|
2006-02-24 04:48:15 +00:00
|
|
|
vis->gzt = gzt; // killough 3/27/98
|
2011-01-02 18:02:27 +00:00
|
|
|
vis->renderflags = thing->renderflags;
|
2011-01-29 11:09:38 +00:00
|
|
|
if(thing->flags5 & MF5_BRIGHT) vis->renderflags |= RF_FULLBRIGHT; // kg3D
|
2011-01-02 18:02:27 +00:00
|
|
|
vis->RenderStyle = thing->RenderStyle;
|
|
|
|
vis->FillColor = thing->fillcolor;
|
2006-02-24 04:48:15 +00:00
|
|
|
vis->Translation = thing->Translation; // [RH] thing translation table
|
|
|
|
vis->FakeFlatStat = fakeside;
|
|
|
|
vis->alpha = thing->alpha;
|
2011-01-29 11:09:38 +00:00
|
|
|
vis->fakefloor = fakefloor;
|
|
|
|
vis->fakeceiling = fakeceiling;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
if (voxel != NULL)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2011-01-02 18:02:27 +00:00
|
|
|
vis->voxel = voxel->Voxel;
|
|
|
|
vis->bIsVoxel = true;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-01-02 18:02:27 +00:00
|
|
|
vis->pic = tex;
|
|
|
|
vis->bIsVoxel = false;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
// The software renderer cannot invert the source without inverting the overlay
|
|
|
|
// too. That means if the source is inverted, we need to do the reverse of what
|
|
|
|
// the invert overlay flag says to do.
|
|
|
|
INTBOOL invertcolormap = (vis->RenderStyle.Flags & STYLEF_InvertOverlay);
|
|
|
|
|
|
|
|
if (vis->RenderStyle.Flags & STYLEF_InvertSource)
|
|
|
|
{
|
|
|
|
invertcolormap = !invertcolormap;
|
|
|
|
}
|
|
|
|
|
|
|
|
FDynamicColormap *mybasecolormap = basecolormap;
|
|
|
|
|
2009-10-30 03:46:51 +00:00
|
|
|
// Sprites that are added to the scene must fade to black.
|
2009-10-30 03:53:00 +00:00
|
|
|
if (vis->RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0)
|
2009-10-30 03:46:51 +00:00
|
|
|
{
|
|
|
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, 0, mybasecolormap->Desaturate);
|
|
|
|
}
|
|
|
|
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
if (vis->RenderStyle.Flags & STYLEF_FadeToBlack)
|
|
|
|
{
|
|
|
|
if (invertcolormap)
|
2009-09-20 03:50:05 +00:00
|
|
|
{ // Fade to white
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(255,255,255), mybasecolormap->Desaturate);
|
|
|
|
invertcolormap = false;
|
|
|
|
}
|
|
|
|
else
|
2009-09-20 03:50:05 +00:00
|
|
|
{ // Fade to black
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(0,0,0), mybasecolormap->Desaturate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
// get light level
|
2009-09-20 03:50:05 +00:00
|
|
|
if (fixedcolormap != NULL)
|
|
|
|
{ // fixed map
|
2006-02-24 04:48:15 +00:00
|
|
|
vis->colormap = fixedcolormap;
|
|
|
|
}
|
2009-09-20 03:50:05 +00:00
|
|
|
else
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
if (invertcolormap)
|
|
|
|
{
|
|
|
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate);
|
|
|
|
}
|
2009-09-20 03:50:05 +00:00
|
|
|
if (fixedlightlev >= 0)
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
{
|
2009-09-20 03:50:05 +00:00
|
|
|
vis->colormap = mybasecolormap->Maps + fixedlightlev;
|
|
|
|
}
|
|
|
|
else if (!foggy && ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT)))
|
|
|
|
{ // full bright
|
|
|
|
vis->colormap = mybasecolormap->Maps;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // diminished light
|
|
|
|
vis->colormap = mybasecolormap->Maps + (GETPALOOKUP (
|
2011-01-02 18:02:27 +00:00
|
|
|
(fixed_t)DivScale12 (r_SpriteVisibility, MAX(tz, MINZ)), spriteshade) << COLORMAPSHIFT);
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// R_AddSprites
|
|
|
|
// During BSP traversal, this adds sprites by sector.
|
|
|
|
//
|
|
|
|
// killough 9/18/98: add lightlevel as parameter, fixing underwater lighting
|
|
|
|
// [RH] Save which side of heightsec sprite is on here.
|
|
|
|
void R_AddSprites (sector_t *sec, int lightlevel, int fakeside)
|
|
|
|
{
|
|
|
|
AActor *thing;
|
2011-01-29 11:09:38 +00:00
|
|
|
F3DFloor *rover;
|
|
|
|
F3DFloor *fakeceiling = NULL;
|
|
|
|
F3DFloor *fakefloor = NULL;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// BSP is traversed by subsector.
|
|
|
|
// A sector might have been split into several
|
|
|
|
// subsectors during BSP building.
|
|
|
|
// Thus we check whether it was already added.
|
|
|
|
if (sec->thinglist == NULL || sec->validcount == validcount)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Well, now it will be done.
|
|
|
|
sec->validcount = validcount;
|
|
|
|
|
|
|
|
spriteshade = LIGHT2SHADE(lightlevel + r_actualextralight);
|
|
|
|
|
|
|
|
// Handle all things in sector.
|
|
|
|
for (thing = sec->thinglist; thing; thing = thing->snext)
|
|
|
|
{
|
2011-01-29 11:09:38 +00:00
|
|
|
// find fake level
|
|
|
|
for(int i = 0; i < (int)frontsector->e->XFloor.ffloors.Size(); i++) {
|
|
|
|
rover = frontsector->e->XFloor.ffloors[i];
|
|
|
|
if(!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) continue;
|
|
|
|
if(!(rover->flags & FF_SOLID) || rover->alpha != 255) continue;
|
|
|
|
if(!fakefloor)
|
|
|
|
{
|
|
|
|
if(!(rover->top.plane->a) && !(rover->top.plane->b))
|
|
|
|
{
|
|
|
|
if(rover->top.plane->Zat0() <= thing->z) fakefloor = rover;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!(rover->bottom.plane->a) && !(rover->bottom.plane->b))
|
|
|
|
{
|
|
|
|
if(rover->bottom.plane->Zat0() >= thing->z + thing->height) fakeceiling = rover;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
R_ProjectSprite (thing, fakeside, fakefloor, fakeceiling);
|
|
|
|
fakeceiling = NULL;
|
|
|
|
fakefloor = NULL;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// R_DrawPSprite
|
|
|
|
//
|
|
|
|
void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_t sy)
|
|
|
|
{
|
|
|
|
fixed_t tx;
|
|
|
|
int x1;
|
|
|
|
int x2;
|
|
|
|
spritedef_t* sprdef;
|
|
|
|
spriteframe_t* sprframe;
|
2008-06-15 18:36:26 +00:00
|
|
|
FTextureID picnum;
|
2006-02-24 04:48:15 +00:00
|
|
|
WORD flip;
|
|
|
|
FTexture* tex;
|
|
|
|
vissprite_t* vis;
|
2009-09-20 03:50:05 +00:00
|
|
|
static vissprite_t avis[NUMPSPRITES];
|
|
|
|
bool noaccel;
|
|
|
|
|
|
|
|
assert(pspnum >= 0 && pspnum < NUMPSPRITES);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// decide which patch to use
|
2010-04-21 01:40:03 +00:00
|
|
|
if ( (unsigned)psp->sprite >= (unsigned)sprites.Size ())
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2010-04-21 01:40:03 +00:00
|
|
|
DPrintf ("R_DrawPSprite: invalid sprite number %i\n", psp->sprite);
|
2006-02-24 04:48:15 +00:00
|
|
|
return;
|
|
|
|
}
|
2010-04-21 01:40:03 +00:00
|
|
|
sprdef = &sprites[psp->sprite];
|
|
|
|
if (psp->frame >= sprdef->numframes)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2010-04-21 01:40:03 +00:00
|
|
|
DPrintf ("R_DrawPSprite: invalid sprite frame %i : %i\n", psp->sprite, psp->frame);
|
2006-02-24 04:48:15 +00:00
|
|
|
return;
|
|
|
|
}
|
2010-04-21 01:40:03 +00:00
|
|
|
sprframe = &SpriteFrames[sprdef->spriteframes + psp->frame];
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
picnum = sprframe->Texture[0];
|
|
|
|
flip = sprframe->Flip & 1;
|
|
|
|
tex = TexMan(picnum);
|
|
|
|
|
|
|
|
if (tex->UseType == FTexture::TEX_Null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// calculate edges of the shape
|
|
|
|
tx = sx-((320/2)<<FRACBITS);
|
2006-08-22 21:45:12 +00:00
|
|
|
|
|
|
|
tx -= tex->GetScaledLeftOffset() << FRACBITS;
|
2006-02-24 04:48:15 +00:00
|
|
|
x1 = (centerxfrac + FixedMul (tx, pspritexscale)) >>FRACBITS;
|
2009-09-20 03:50:05 +00:00
|
|
|
VisPSpritesX1[pspnum] = x1;
|
2006-08-22 21:45:12 +00:00
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
// off the right side
|
|
|
|
if (x1 > viewwidth)
|
|
|
|
return;
|
|
|
|
|
2006-08-22 21:45:12 +00:00
|
|
|
tx += tex->GetScaledWidth() << FRACBITS;
|
2006-02-24 04:48:15 +00:00
|
|
|
x2 = ((centerxfrac + FixedMul (tx, pspritexscale)) >>FRACBITS) - 1;
|
|
|
|
|
|
|
|
// off the left side
|
|
|
|
if (x2 < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// store information in a vissprite
|
2009-09-20 03:50:05 +00:00
|
|
|
vis = &avis[pspnum];
|
2006-02-24 04:48:15 +00:00
|
|
|
vis->renderflags = owner->renderflags;
|
|
|
|
vis->floorclip = 0;
|
2006-08-22 21:45:12 +00:00
|
|
|
|
|
|
|
|
2007-04-29 12:07:27 +00:00
|
|
|
vis->texturemid = MulScale16((BASEYCENTER<<FRACBITS) - sy, tex->yScale) + (tex->TopOffset << FRACBITS);
|
2006-08-22 21:45:12 +00:00
|
|
|
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
if (camera->player && (RenderTarget != screen ||
|
- Ported vlinetallasm4 to AMD64 assembly. Even with the increased number of
registers AMD64 provides, this routine still needs to be written as self-
modifying code for maximum performance. The additional registers do allow
for further optimization over the x86 version by allowing all four pixels
to be in flight at the same time. The end result is that AMD64 ASM is about
2.18 times faster than AMD64 C and about 1.06 times faster than x86 ASM.
(For further comparison, AMD64 C and x86 C are practically the same for
this function.) Should I port any more assembly to AMD64, mvlineasm4 is the
most likely candidate, but it's not used enough at this point to bother.
Also, this may or may not work with Linux at the moment, since it doesn't
have the eh_handler metadata. Win64 is easier, since I just need to
structure the function prologue and epilogue properly and use some
assembler directives/macros to automatically generate the metadata. And
that brings up another point: You need YASM to assemble the AMD64 code,
because NASM doesn't support the Win64 metadata directives.
- Added an SSE version of DoBlending. This is strictly C intrinsics.
VC++ still throws around unneccessary register moves. GCC seems to be
pretty close to optimal, requiring only about 2 cycles/color. They're
both faster than my hand-written MMX routine, so I don't need to feel
bad about not hand-optimizing this for x64 builds.
- Removed an extra instruction from DoBlending_MMX, transposed two
instructions, and unrolled it once, shaving off about 80 cycles from the
time required to blend 256 palette entries. Why? Because I tried writing
a C version of the routine using compiler intrinsics and was appalled by
all the extra movq's VC++ added to the code. GCC was better, but still
generated extra instructions. I only wanted a C version because I can't
use inline assembly with VC++'s x64 compiler, and x64 assembly is a bit
of a pain. (It's a pain because Linux and Windows have different calling
conventions, and you need to maintain extra metadata for functions.) So,
the assembly version stays and the C version stays out.
- Removed all the pixel doubling r_detail modes, since the one platform they
were intended to assist (486) actually sees very little benefit from them.
- Rewrote CheckMMX in C and renamed it to CheckCPU.
- Fixed: CPUID function 0x80000005 is specified to return detailed L1 cache
only for AMD processors, so we must not use it on other architectures, or
we end up overwriting the L1 cache line size with 0 or some other number
we don't actually understand.
SVN r1134 (trunk)
2008-08-09 03:13:43 +00:00
|
|
|
viewheight == RenderTarget->GetHeight() ||
|
2006-02-24 04:48:15 +00:00
|
|
|
(RenderTarget->GetWidth() > 320 && !st_scale)))
|
|
|
|
{ // Adjust PSprite for fullscreen views
|
|
|
|
AWeapon *weapon = NULL;
|
|
|
|
if (camera->player != NULL)
|
|
|
|
{
|
|
|
|
weapon = camera->player->ReadyWeapon;
|
|
|
|
}
|
2008-01-11 01:43:37 +00:00
|
|
|
if (pspnum <= ps_flash && weapon != NULL && weapon->YAdjust != 0)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
- Ported vlinetallasm4 to AMD64 assembly. Even with the increased number of
registers AMD64 provides, this routine still needs to be written as self-
modifying code for maximum performance. The additional registers do allow
for further optimization over the x86 version by allowing all four pixels
to be in flight at the same time. The end result is that AMD64 ASM is about
2.18 times faster than AMD64 C and about 1.06 times faster than x86 ASM.
(For further comparison, AMD64 C and x86 C are practically the same for
this function.) Should I port any more assembly to AMD64, mvlineasm4 is the
most likely candidate, but it's not used enough at this point to bother.
Also, this may or may not work with Linux at the moment, since it doesn't
have the eh_handler metadata. Win64 is easier, since I just need to
structure the function prologue and epilogue properly and use some
assembler directives/macros to automatically generate the metadata. And
that brings up another point: You need YASM to assemble the AMD64 code,
because NASM doesn't support the Win64 metadata directives.
- Added an SSE version of DoBlending. This is strictly C intrinsics.
VC++ still throws around unneccessary register moves. GCC seems to be
pretty close to optimal, requiring only about 2 cycles/color. They're
both faster than my hand-written MMX routine, so I don't need to feel
bad about not hand-optimizing this for x64 builds.
- Removed an extra instruction from DoBlending_MMX, transposed two
instructions, and unrolled it once, shaving off about 80 cycles from the
time required to blend 256 palette entries. Why? Because I tried writing
a C version of the routine using compiler intrinsics and was appalled by
all the extra movq's VC++ added to the code. GCC was better, but still
generated extra instructions. I only wanted a C version because I can't
use inline assembly with VC++'s x64 compiler, and x64 assembly is a bit
of a pain. (It's a pain because Linux and Windows have different calling
conventions, and you need to maintain extra metadata for functions.) So,
the assembly version stays and the C version stays out.
- Removed all the pixel doubling r_detail modes, since the one platform they
were intended to assist (486) actually sees very little benefit from them.
- Rewrote CheckMMX in C and renamed it to CheckCPU.
- Fixed: CPUID function 0x80000005 is specified to return detailed L1 cache
only for AMD processors, so we must not use it on other architectures, or
we end up overwriting the L1 cache line size with 0 or some other number
we don't actually understand.
SVN r1134 (trunk)
2008-08-09 03:13:43 +00:00
|
|
|
if (RenderTarget != screen || viewheight == RenderTarget->GetHeight())
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2008-01-11 01:43:37 +00:00
|
|
|
vis->texturemid -= weapon->YAdjust;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vis->texturemid -= FixedMul (StatusBar->GetDisplacement (),
|
|
|
|
weapon->YAdjust);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-01-11 01:43:37 +00:00
|
|
|
if (pspnum <= ps_flash)
|
|
|
|
{ // Move the weapon down for 1280x1024.
|
|
|
|
vis->texturemid -= BaseRatioSizes[WidescreenRatio][2];
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
vis->x1 = x1 < 0 ? 0 : x1;
|
|
|
|
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
|
2007-04-29 12:07:27 +00:00
|
|
|
vis->xscale = DivScale16(pspritexscale, tex->xScale);
|
|
|
|
vis->yscale = DivScale16(pspriteyscale, tex->yScale);
|
2006-02-24 04:48:15 +00:00
|
|
|
vis->Translation = 0; // [RH] Use default colors
|
|
|
|
vis->pic = tex;
|
|
|
|
|
|
|
|
if (flip)
|
|
|
|
{
|
2007-04-29 12:07:27 +00:00
|
|
|
vis->xiscale = -MulScale16(pspritexiscale, tex->xScale);
|
2006-02-24 04:48:15 +00:00
|
|
|
vis->startfrac = (tex->GetWidth() << FRACBITS) - 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-04-29 12:07:27 +00:00
|
|
|
vis->xiscale = MulScale16(pspritexiscale, tex->xScale);
|
2006-02-24 04:48:15 +00:00
|
|
|
vis->startfrac = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vis->x1 > x1)
|
|
|
|
vis->startfrac += vis->xiscale*(vis->x1-x1);
|
|
|
|
|
2009-09-20 03:50:05 +00:00
|
|
|
noaccel = false;
|
2006-02-24 04:48:15 +00:00
|
|
|
if (pspnum <= ps_flash)
|
|
|
|
{
|
|
|
|
vis->alpha = owner->alpha;
|
|
|
|
vis->RenderStyle = owner->RenderStyle;
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
|
|
|
|
// The software renderer cannot invert the source without inverting the overlay
|
|
|
|
// too. That means if the source is inverted, we need to do the reverse of what
|
|
|
|
// the invert overlay flag says to do.
|
|
|
|
INTBOOL invertcolormap = (vis->RenderStyle.Flags & STYLEF_InvertOverlay);
|
|
|
|
|
|
|
|
if (vis->RenderStyle.Flags & STYLEF_InvertSource)
|
|
|
|
{
|
|
|
|
invertcolormap = !invertcolormap;
|
|
|
|
}
|
|
|
|
|
|
|
|
FDynamicColormap *mybasecolormap = basecolormap;
|
|
|
|
|
|
|
|
if (vis->RenderStyle.Flags & STYLEF_FadeToBlack)
|
|
|
|
{
|
|
|
|
if (invertcolormap)
|
2009-09-20 03:50:05 +00:00
|
|
|
{ // Fade to white
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(255,255,255), mybasecolormap->Desaturate);
|
|
|
|
invertcolormap = false;
|
|
|
|
}
|
|
|
|
else
|
2009-09-20 03:50:05 +00:00
|
|
|
{ // Fade to black
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(0,0,0), mybasecolormap->Desaturate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-22 04:21:27 +00:00
|
|
|
if (realfixedcolormap != NULL)
|
2009-09-20 03:50:05 +00:00
|
|
|
{ // fixed color
|
2009-09-22 04:21:27 +00:00
|
|
|
vis->colormap = realfixedcolormap->Colormap;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
2009-09-20 03:50:05 +00:00
|
|
|
else
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
if (invertcolormap)
|
|
|
|
{
|
|
|
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate);
|
|
|
|
}
|
2009-09-20 03:50:05 +00:00
|
|
|
if (fixedlightlev >= 0)
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
{
|
2009-09-20 03:50:05 +00:00
|
|
|
vis->colormap = mybasecolormap->Maps + fixedlightlev;
|
|
|
|
}
|
|
|
|
else if (!foggy && psp->state->GetFullbright())
|
|
|
|
{ // full bright
|
|
|
|
vis->colormap = mybasecolormap->Maps; // [RH] use basecolormap
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // local light
|
|
|
|
vis->colormap = mybasecolormap->Maps + (GETPALOOKUP (0, spriteshade) << COLORMAPSHIFT);
|
- Updated lempar.c to v1.31.
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
SVN r710 (trunk)
2008-01-25 23:57:44 +00:00
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
if (camera->Inventory != NULL)
|
|
|
|
{
|
2009-09-20 03:50:05 +00:00
|
|
|
lighttable_t *oldcolormap = vis->colormap;
|
2006-02-24 04:48:15 +00:00
|
|
|
camera->Inventory->AlterWeaponSprite (vis);
|
2009-09-20 03:50:05 +00:00
|
|
|
if (vis->colormap != oldcolormap)
|
|
|
|
{
|
|
|
|
// The colormap has changed. Is it one we can easily identify?
|
|
|
|
// If not, then don't bother trying to identify it for
|
|
|
|
// hardware accelerated drawing.
|
2009-09-21 13:15:36 +00:00
|
|
|
if (vis->colormap < SpecialColormaps[0].Colormap ||
|
2011-05-11 04:16:45 +00:00
|
|
|
vis->colormap > SpecialColormaps.Last().Colormap)
|
2009-09-20 03:50:05 +00:00
|
|
|
{
|
|
|
|
noaccel = true;
|
|
|
|
}
|
|
|
|
// Has the basecolormap changed? If so, we can't hardware accelerate it,
|
|
|
|
// since we don't know what it is anymore.
|
|
|
|
else if (vis->colormap < mybasecolormap->Maps ||
|
|
|
|
vis->colormap >= mybasecolormap->Maps + NUMCOLORMAPS*256)
|
|
|
|
{
|
|
|
|
noaccel = true;
|
|
|
|
}
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
2011-05-11 04:16:45 +00:00
|
|
|
// If we're drawing with a special colormap, but shaders for them are disabled, do
|
|
|
|
// not accelerate.
|
|
|
|
if (!r_shadercolormaps && (vis->colormap >= SpecialColormaps[0].Colormap &&
|
|
|
|
vis->colormap <= SpecialColormaps.Last().Colormap))
|
|
|
|
{
|
|
|
|
noaccel = true;
|
|
|
|
}
|
2011-03-19 04:45:59 +00:00
|
|
|
// If the main colormap has fixed lights, and this sprite is being drawn with that
|
|
|
|
// colormap, disable acceleration so that the lights can remain fixed.
|
|
|
|
if (!noaccel &&
|
|
|
|
NormalLightHasFixedLights && mybasecolormap == &NormalLight &&
|
|
|
|
vis->pic->UseBasePalette())
|
|
|
|
{
|
|
|
|
noaccel = true;
|
|
|
|
}
|
2009-09-20 03:50:05 +00:00
|
|
|
VisPSpritesBaseColormap[pspnum] = mybasecolormap;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-09-20 03:50:05 +00:00
|
|
|
VisPSpritesBaseColormap[pspnum] = basecolormap;
|
2009-09-27 02:31:03 +00:00
|
|
|
vis->colormap = basecolormap->Maps;
|
2006-02-24 04:48:15 +00:00
|
|
|
vis->RenderStyle = STYLE_Normal;
|
|
|
|
}
|
2009-09-20 03:50:05 +00:00
|
|
|
|
|
|
|
// Check for hardware-assisted 2D. If it's available, and this sprite is not
|
|
|
|
// fuzzy, don't draw it until after the switch to 2D mode.
|
|
|
|
if (!noaccel && RenderTarget == screen && (DFrameBuffer *)screen->Accel2D)
|
|
|
|
{
|
|
|
|
FRenderStyle style = vis->RenderStyle;
|
|
|
|
style.CheckFuzz();
|
|
|
|
if (style.BlendOp != STYLEOP_Fuzz)
|
|
|
|
{
|
|
|
|
VisPSprites[pspnum] = vis;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
R_DrawVisSprite (vis);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-09-20 03:50:05 +00:00
|
|
|
//==========================================================================
|
2006-02-24 04:48:15 +00:00
|
|
|
//
|
|
|
|
// R_DrawPlayerSprites
|
|
|
|
//
|
2009-09-20 03:50:05 +00:00
|
|
|
//==========================================================================
|
|
|
|
|
2011-01-29 11:09:38 +00:00
|
|
|
void R_DrawPlayerSprites ()
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int lightnum;
|
|
|
|
pspdef_t* psp;
|
2011-01-29 11:09:38 +00:00
|
|
|
sector_t* sec = NULL;
|
2006-02-24 04:48:15 +00:00
|
|
|
static sector_t tempsec;
|
|
|
|
int floorlight, ceilinglight;
|
2011-01-29 11:09:38 +00:00
|
|
|
F3DFloor *rover;
|
2009-09-20 03:50:05 +00:00
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
if (!r_drawplayersprites ||
|
|
|
|
!camera->player ||
|
|
|
|
(players[consoleplayer].cheats & CF_CHASECAM))
|
|
|
|
return;
|
|
|
|
|
2011-01-29 11:09:38 +00:00
|
|
|
if(fixedlightlev < 0 && viewsector->e && viewsector->e->XFloor.lightlist.Size()) {
|
|
|
|
for(i = viewsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
|
|
|
|
if(viewz <= viewsector->e->XFloor.lightlist[i].plane.Zat0()) {
|
|
|
|
rover = viewsector->e->XFloor.lightlist[i].caster;
|
|
|
|
if(rover) {
|
|
|
|
if(rover->flags & FF_DOUBLESHADOW && viewz <= rover->bottom.plane->Zat0())
|
|
|
|
break;
|
|
|
|
sec = rover->model;
|
|
|
|
if(rover->flags & FF_FADEWALLS)
|
|
|
|
basecolormap = sec->ColorMap;
|
|
|
|
else
|
|
|
|
basecolormap = viewsector->e->XFloor.lightlist[i].extra_colormap;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(!sec) {
|
|
|
|
sec = viewsector;
|
|
|
|
basecolormap = sec->ColorMap;
|
|
|
|
}
|
|
|
|
floorlight = ceilinglight = sec->lightlevel;
|
|
|
|
} else {
|
|
|
|
// This used to use camera->Sector but due to interpolation that can be incorrect
|
|
|
|
// when the interpolated viewpoint is in a different sector than the camera.
|
|
|
|
sec = R_FakeFlat (viewsector, &tempsec, &floorlight,
|
|
|
|
&ceilinglight, false);
|
|
|
|
|
|
|
|
// [RH] set basecolormap
|
|
|
|
basecolormap = sec->ColorMap;
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// [RH] set foggy flag
|
2011-01-29 11:09:38 +00:00
|
|
|
foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE));
|
2006-02-24 04:48:15 +00:00
|
|
|
r_actualextralight = foggy ? 0 : extralight << 4;
|
|
|
|
|
|
|
|
// get light level
|
|
|
|
lightnum = ((floorlight + ceilinglight) >> 1) + r_actualextralight;
|
|
|
|
spriteshade = LIGHT2SHADE(lightnum) - 24*FRACUNIT;
|
|
|
|
|
|
|
|
// clip to screen bounds
|
|
|
|
mfloorclip = screenheightarray;
|
|
|
|
mceilingclip = zeroarray;
|
|
|
|
|
|
|
|
if (camera->player != NULL)
|
|
|
|
{
|
|
|
|
fixed_t centerhack = centeryfrac;
|
|
|
|
fixed_t ofsx, ofsy;
|
|
|
|
|
|
|
|
centery = viewheight >> 1;
|
|
|
|
centeryfrac = centery << FRACBITS;
|
|
|
|
|
|
|
|
P_BobWeapon (camera->player, &camera->player->psprites[ps_weapon], &ofsx, &ofsy);
|
|
|
|
|
|
|
|
// add all active psprites
|
|
|
|
for (i = 0, psp = camera->player->psprites;
|
|
|
|
i < NUMPSPRITES;
|
|
|
|
i++, psp++)
|
|
|
|
{
|
|
|
|
// [RH] Don't draw the targeter's crosshair if the player already has a crosshair set.
|
|
|
|
if (psp->state && (i != ps_targetcenter || CrosshairImage == NULL))
|
|
|
|
{
|
|
|
|
R_DrawPSprite (psp, i, camera, psp->sx + ofsx, psp->sy + ofsy);
|
|
|
|
}
|
|
|
|
// [RH] Don't bob the targeter.
|
|
|
|
if (i == ps_flash)
|
|
|
|
{
|
|
|
|
ofsx = ofsy = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
centeryfrac = centerhack;
|
|
|
|
centery = centerhack >> FRACBITS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-20 03:50:05 +00:00
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// R_DrawRemainingPlayerSprites
|
|
|
|
//
|
|
|
|
// Called from D_Display to draw sprites that were not drawn by
|
|
|
|
// R_DrawPlayerSprites().
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
void R_DrawRemainingPlayerSprites()
|
|
|
|
{
|
|
|
|
for (int i = 0; i < NUMPSPRITES; ++i)
|
|
|
|
{
|
|
|
|
vissprite_t *vis;
|
|
|
|
|
|
|
|
vis = VisPSprites[i];
|
|
|
|
VisPSprites[i] = NULL;
|
|
|
|
|
|
|
|
if (vis != NULL)
|
|
|
|
{
|
|
|
|
FDynamicColormap *colormap = VisPSpritesBaseColormap[i];
|
|
|
|
bool flip = vis->xiscale < 0;
|
2009-09-21 13:15:36 +00:00
|
|
|
FSpecialColormap *special = NULL;
|
2009-09-20 03:50:05 +00:00
|
|
|
PalEntry overlay = 0;
|
|
|
|
FColormapStyle colormapstyle;
|
|
|
|
bool usecolormapstyle = false;
|
|
|
|
|
2009-09-21 13:15:36 +00:00
|
|
|
if (vis->colormap >= SpecialColormaps[0].Colormap &&
|
|
|
|
vis->colormap < SpecialColormaps[SpecialColormaps.Size()].Colormap)
|
2009-09-20 03:50:05 +00:00
|
|
|
{
|
2009-09-21 13:15:36 +00:00
|
|
|
// Yuck! There needs to be a better way to store colormaps in the vissprite... :(
|
|
|
|
ptrdiff_t specialmap = (vis->colormap - SpecialColormaps[0].Colormap) / sizeof(FSpecialColormap);
|
|
|
|
special = &SpecialColormaps[specialmap];
|
2009-09-20 03:50:05 +00:00
|
|
|
}
|
|
|
|
else if (colormap->Color == PalEntry(255,255,255) &&
|
|
|
|
colormap->Desaturate == 0)
|
|
|
|
{
|
|
|
|
overlay = colormap->Fade;
|
|
|
|
overlay.a = BYTE(((vis->colormap - colormap->Maps) >> 8) * 255 / NUMCOLORMAPS);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
usecolormapstyle = true;
|
|
|
|
colormapstyle.Color = colormap->Color;
|
|
|
|
colormapstyle.Fade = colormap->Fade;
|
|
|
|
colormapstyle.Desaturate = colormap->Desaturate;
|
|
|
|
colormapstyle.FadeLevel = ((vis->colormap - colormap->Maps) >> 8) / float(NUMCOLORMAPS);
|
|
|
|
}
|
|
|
|
screen->DrawTexture(vis->pic,
|
|
|
|
viewwindowx + VisPSpritesX1[i],
|
2009-11-01 01:35:11 +00:00
|
|
|
viewwindowy + viewheight/2 - (vis->texturemid / 65536.0) * (vis->yscale / 65536.0) - 0.5,
|
- Changed all coordinates for DrawTexture() to floating point so that the
player sprites will retain the same precision they had when they were
rendered as part of the 3D view. (needed for propery alignment of flashes
on top of weapon sprites) It worked just fine for D3D, but software
rendering was another matter. I consequently did battle with imprecisions
in the whole masked texture drawing routines that had previously been
partially masked by only drawing on whole pixel boundaries. Particularly,
the tops of posts are calculated by multiplying by spryscale, and the
texture mapping coordinates are calculated by multiplying by dc_iscale
(where dc_iscale = 1 / spryscale). Since these are both 16.16 fixed point
values, there is a significant variance. For best results, the drawing
routines should only use one of these values, but that would mean
introducing division into the inner loop. If the division removed the
necessity for the fudge code in R_DrawMaskedColumn(), would it be worth it?
Or would the divide be slower than the fudging? Or would I be better off
doing it like Build and using transparent pixel checks instead, not
bothering with skipping transparent areas? For now, I chop off the
fractional part of the top coordinate for software drawing, since it was
the easiest thing to do (even if it wasn't the most correct thing to do).
SVN r1955 (trunk)
2009-11-01 01:27:33 +00:00
|
|
|
DTA_DestWidthF, FIXED2FLOAT(vis->pic->GetWidth() * vis->xscale),
|
|
|
|
DTA_DestHeightF, FIXED2FLOAT(vis->pic->GetHeight() * vis->yscale),
|
2009-09-20 03:50:05 +00:00
|
|
|
DTA_Translation, TranslationToTable(vis->Translation),
|
|
|
|
DTA_FlipX, flip,
|
|
|
|
DTA_TopOffset, 0,
|
|
|
|
DTA_LeftOffset, 0,
|
|
|
|
DTA_ClipLeft, viewwindowx,
|
|
|
|
DTA_ClipTop, viewwindowy,
|
|
|
|
DTA_ClipRight, viewwindowx + viewwidth,
|
|
|
|
DTA_ClipBottom, viewwindowy + viewheight,
|
|
|
|
DTA_Alpha, vis->alpha,
|
|
|
|
DTA_RenderStyle, vis->RenderStyle,
|
|
|
|
DTA_FillColor, vis->FillColor,
|
|
|
|
DTA_SpecialColormap, special,
|
2009-10-02 09:21:37 +00:00
|
|
|
DTA_ColorOverlay, overlay.d,
|
2009-09-20 03:50:05 +00:00
|
|
|
DTA_ColormapStyle, usecolormapstyle ? &colormapstyle : NULL,
|
|
|
|
TAG_DONE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// R_SortVisSprites
|
|
|
|
//
|
|
|
|
// [RH] The old code for this function used a bubble sort, which was far less
|
|
|
|
// than optimal with large numbers of sprites. I changed it to use the
|
|
|
|
// stdlib qsort() function instead, and now it is a *lot* faster; the
|
|
|
|
// more vissprites that need to be sorted, the better the performance
|
|
|
|
// gain compared to the old function.
|
|
|
|
//
|
|
|
|
// Sort vissprites by depth, far to near
|
2009-12-18 03:05:38 +00:00
|
|
|
static bool sv_compare(vissprite_t *a, vissprite_t *b)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2009-12-18 03:05:38 +00:00
|
|
|
return a->idepth > b->idepth;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
2006-05-11 04:00:58 +00:00
|
|
|
static drawseg_t **drawsegsorter;
|
|
|
|
static int drawsegsortersize = 0;
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
// Sort vissprites by leftmost column, left to right
|
|
|
|
static int STACK_ARGS sv_comparex (const void *arg1, const void *arg2)
|
|
|
|
{
|
|
|
|
return (*(vissprite_t **)arg2)->x1 - (*(vissprite_t **)arg1)->x1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sort drawsegs by rightmost column, left to right
|
|
|
|
static int STACK_ARGS sd_comparex (const void *arg1, const void *arg2)
|
|
|
|
{
|
|
|
|
return (*(drawseg_t **)arg2)->x2 - (*(drawseg_t **)arg1)->x2;
|
|
|
|
}
|
|
|
|
|
|
|
|
CVAR (Bool, r_splitsprites, true, CVAR_ARCHIVE)
|
|
|
|
|
|
|
|
// Split up vissprites that intersect drawsegs
|
|
|
|
void R_SplitVisSprites ()
|
|
|
|
{
|
|
|
|
size_t start, stop;
|
|
|
|
size_t numdrawsegs = ds_p - firstdrawseg;
|
|
|
|
size_t numsprites;
|
|
|
|
size_t spr, dseg, dseg2;
|
|
|
|
|
|
|
|
if (!r_splitsprites)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (numdrawsegs == 0 || vissprite_p - firstvissprite == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Sort drawsegs from left to right
|
|
|
|
if (numdrawsegs > drawsegsortersize)
|
|
|
|
{
|
|
|
|
if (drawsegsorter != NULL)
|
|
|
|
delete[] drawsegsorter;
|
|
|
|
drawsegsortersize = numdrawsegs * 2;
|
|
|
|
drawsegsorter = new drawseg_t *[drawsegsortersize];
|
|
|
|
}
|
|
|
|
for (dseg = dseg2 = 0; dseg < numdrawsegs; ++dseg)
|
|
|
|
{
|
|
|
|
// Drawsegs that don't clip any sprites don't need to be considered.
|
|
|
|
if (firstdrawseg[dseg].silhouette)
|
|
|
|
{
|
|
|
|
drawsegsorter[dseg2++] = &firstdrawseg[dseg];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
numdrawsegs = dseg2;
|
|
|
|
if (numdrawsegs == 0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
qsort (drawsegsorter, numdrawsegs, sizeof(drawseg_t *), sd_comparex);
|
|
|
|
|
|
|
|
// Now sort vissprites from left to right, and walk them simultaneously
|
|
|
|
// with the drawsegs, splitting any that intersect.
|
|
|
|
start = firstvissprite - vissprites;
|
|
|
|
|
|
|
|
int p = 0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
p++;
|
|
|
|
R_SortVisSprites (sv_comparex, start);
|
|
|
|
stop = vissprite_p - vissprites;
|
|
|
|
numsprites = stop - start;
|
|
|
|
|
|
|
|
spr = dseg = 0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
vissprite_t *vis = spritesorter[spr], *vis2;
|
|
|
|
|
|
|
|
// Skip drawsegs until we get to one that doesn't end before the sprite
|
|
|
|
// begins.
|
|
|
|
while (dseg < numdrawsegs && drawsegsorter[dseg]->x2 <= vis->x1)
|
|
|
|
{
|
|
|
|
dseg++;
|
|
|
|
}
|
|
|
|
// Now split the sprite against any drawsegs it intersects
|
|
|
|
for (dseg2 = dseg; dseg2 < numdrawsegs; dseg2++)
|
|
|
|
{
|
|
|
|
drawseg_t *ds = drawsegsorter[dseg2];
|
|
|
|
|
|
|
|
if (ds->x1 > vis->x2 || ds->x2 < vis->x1)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if ((vis->idepth < ds->siz1) != (vis->idepth < ds->siz2))
|
|
|
|
{ // The drawseg is crossed; find the x where the intersection occurs
|
|
|
|
int cross = Scale (vis->idepth - ds->siz1, ds->sx2 - ds->sx1, ds->siz2 - ds->siz1) + ds->sx1 + 1;
|
|
|
|
|
|
|
|
/* if (cross < ds->x1 || cross > ds->x2)
|
|
|
|
{ // The original seg is crossed, but the drawseg is not
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
*/ if (cross <= vis->x1 || cross >= vis->x2)
|
|
|
|
{ // Don't create 0-sized sprites
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
vis->bSplitSprite = true;
|
|
|
|
|
|
|
|
// Create a new vissprite for the right part of the sprite
|
|
|
|
vis2 = R_NewVisSprite ();
|
|
|
|
*vis2 = *vis;
|
|
|
|
vis2->startfrac += vis2->xiscale * (cross - vis2->x1);
|
|
|
|
vis->x2 = cross-1;
|
|
|
|
vis2->x1 = cross;
|
|
|
|
//vis2->alpha /= 2;
|
|
|
|
//vis2->RenderStyle = STYLE_Add;
|
|
|
|
|
|
|
|
if (vis->idepth < ds->siz1)
|
|
|
|
{ // Left is in back, right is in front
|
|
|
|
vis->sector = ds->curline->backsector;
|
|
|
|
vis2->sector = ds->curline->frontsector;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // Right is in front, left is in back
|
|
|
|
vis->sector = ds->curline->frontsector;
|
|
|
|
vis2->sector = ds->curline->backsector;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (dseg < numdrawsegs && ++spr < numsprites);
|
|
|
|
|
|
|
|
// Repeat for any new sprites that were added.
|
|
|
|
}
|
|
|
|
while (start = stop, stop != vissprite_p - vissprites);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-12-18 04:58:20 +00:00
|
|
|
#ifdef __GNUC__
|
|
|
|
static void swap(vissprite_t *&a, vissprite_t *&b)
|
|
|
|
{
|
|
|
|
vissprite_t *t = a;
|
|
|
|
a = b;
|
|
|
|
b = t;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-12-18 03:05:38 +00:00
|
|
|
void R_SortVisSprites (bool (*compare)(vissprite_t *, vissprite_t *), size_t first)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
vissprite_t **spr;
|
|
|
|
|
|
|
|
vsprcount = int(vissprite_p - &vissprites[first]);
|
|
|
|
|
|
|
|
if (vsprcount == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (spritesortersize < MaxVisSprites)
|
|
|
|
{
|
|
|
|
if (spritesorter != NULL)
|
|
|
|
delete[] spritesorter;
|
|
|
|
spritesorter = new vissprite_t *[MaxVisSprites];
|
|
|
|
spritesortersize = MaxVisSprites;
|
|
|
|
}
|
|
|
|
|
2009-12-18 08:19:34 +00:00
|
|
|
if (!(i_compatflags & COMPATF_SPRITESORT))
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2009-12-18 08:19:34 +00:00
|
|
|
for (i = 0, spr = firstvissprite; i < vsprcount; i++, spr++)
|
|
|
|
{
|
|
|
|
spritesorter[i] = *spr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// If the compatibility option is on sprites of equal distance need to
|
|
|
|
// be sorted in inverse order. This is most easily achieved by
|
|
|
|
// filling the sort array backwards before the sort.
|
|
|
|
for (i = 0, spr = firstvissprite + vsprcount-1; i < vsprcount; i++, spr--)
|
|
|
|
{
|
|
|
|
spritesorter[i] = *spr;
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
2009-12-18 03:05:38 +00:00
|
|
|
std::stable_sort(&spritesorter[0], &spritesorter[vsprcount], compare);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// R_DrawSprite
|
|
|
|
//
|
|
|
|
void R_DrawSprite (vissprite_t *spr)
|
|
|
|
{
|
|
|
|
static short clipbot[MAXWIDTH];
|
|
|
|
static short cliptop[MAXWIDTH];
|
|
|
|
drawseg_t *ds;
|
|
|
|
int i;
|
2011-01-02 18:02:27 +00:00
|
|
|
int x1, x2;
|
2006-02-24 04:48:15 +00:00
|
|
|
int r1, r2;
|
|
|
|
short topclip, botclip;
|
|
|
|
short *clip1, *clip2;
|
2011-01-29 11:09:38 +00:00
|
|
|
lighttable_t *colormap = spr->colormap;
|
|
|
|
F3DFloor *rover;
|
|
|
|
FDynamicColormap *mybasecolormap;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// [RH] Check for particles
|
2011-01-02 18:02:27 +00:00
|
|
|
if (!spr->bIsVoxel && spr->pic == NULL)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2011-01-29 11:09:38 +00:00
|
|
|
// kg3D - reject invisible parts
|
|
|
|
if ((fake3D & FAKE3D_CLIPBOTTOM) && spr->gz <= sclipBottom) return;
|
|
|
|
if ((fake3D & FAKE3D_CLIPTOP) && spr->gz >= sclipTop) return;
|
2006-02-24 04:48:15 +00:00
|
|
|
R_DrawParticle (spr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
x1 = spr->x1;
|
|
|
|
x2 = spr->x2;
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
// [RH] Quickly reject sprites with bad x ranges.
|
2011-01-02 18:02:27 +00:00
|
|
|
if (x1 > x2)
|
2006-02-24 04:48:15 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
// [RH] Sprites split behind a one-sided line can also be discarded.
|
|
|
|
if (spr->sector == NULL)
|
|
|
|
return;
|
|
|
|
|
2011-01-29 11:09:38 +00:00
|
|
|
// kg3D - reject invisible parts
|
|
|
|
if ((fake3D & FAKE3D_CLIPBOTTOM) && spr->gzt <= sclipBottom) return;
|
|
|
|
if ((fake3D & FAKE3D_CLIPTOP) && spr->gzb >= sclipTop) return;
|
|
|
|
|
|
|
|
// kg3D - correct colors now
|
|
|
|
if (!fixedcolormap && fixedlightlev < 0 && spr->sector->e && spr->sector->e->XFloor.lightlist.Size())
|
|
|
|
{
|
|
|
|
if (!(fake3D & FAKE3D_CLIPTOP))
|
|
|
|
{
|
|
|
|
sclipTop = spr->sector->ceilingplane.ZatPoint(viewx, viewy);
|
|
|
|
}
|
|
|
|
sector_t *sec = NULL;
|
|
|
|
for (i = spr->sector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
|
|
|
|
{
|
|
|
|
if (sclipTop <= spr->sector->e->XFloor.lightlist[i].plane.Zat0())
|
|
|
|
{
|
|
|
|
rover = spr->sector->e->XFloor.lightlist[i].caster;
|
|
|
|
if (rover)
|
|
|
|
{
|
|
|
|
if (rover->flags & FF_DOUBLESHADOW && sclipTop <= rover->bottom.plane->Zat0())
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
sec = rover->model;
|
|
|
|
if (rover->flags & FF_FADEWALLS)
|
|
|
|
{
|
|
|
|
mybasecolormap = sec->ColorMap;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mybasecolormap = spr->sector->e->XFloor.lightlist[i].extra_colormap;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// found new values, recalculate
|
|
|
|
if (sec)
|
|
|
|
{
|
|
|
|
INTBOOL invertcolormap = (spr->RenderStyle.Flags & STYLEF_InvertOverlay);
|
|
|
|
|
|
|
|
if (spr->RenderStyle.Flags & STYLEF_InvertSource)
|
|
|
|
{
|
|
|
|
invertcolormap = !invertcolormap;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sprites that are added to the scene must fade to black.
|
|
|
|
if (spr->RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0)
|
|
|
|
{
|
|
|
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, 0, mybasecolormap->Desaturate);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (spr->RenderStyle.Flags & STYLEF_FadeToBlack)
|
|
|
|
{
|
|
|
|
if (invertcolormap)
|
|
|
|
{ // Fade to white
|
|
|
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(255,255,255), mybasecolormap->Desaturate);
|
|
|
|
invertcolormap = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // Fade to black
|
|
|
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(0,0,0), mybasecolormap->Desaturate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// get light level
|
|
|
|
if (invertcolormap)
|
|
|
|
{
|
|
|
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate);
|
|
|
|
}
|
|
|
|
if (fixedlightlev >= 0)
|
|
|
|
{
|
|
|
|
spr->colormap = mybasecolormap->Maps + fixedlightlev;
|
|
|
|
}
|
|
|
|
else if (!foggy && (spr->renderflags & RF_FULLBRIGHT))
|
|
|
|
{ // full bright
|
|
|
|
spr->colormap = mybasecolormap->Maps;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // diminished light
|
|
|
|
spriteshade = LIGHT2SHADE(sec->lightlevel + r_actualextralight);
|
|
|
|
spr->colormap = mybasecolormap->Maps + (GETPALOOKUP (
|
|
|
|
(fixed_t)DivScale12 (r_SpriteVisibility, spr->depth), spriteshade) << COLORMAPSHIFT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
// [RH] Initialize the clipping arrays to their largest possible range
|
|
|
|
// instead of using a special "not clipped" value. This eliminates
|
|
|
|
// visual anomalies when looking down and should be faster, too.
|
|
|
|
topclip = 0;
|
|
|
|
botclip = viewheight;
|
|
|
|
|
|
|
|
// killough 3/27/98:
|
|
|
|
// Clip the sprite against deep water and/or fake ceilings.
|
|
|
|
// [RH] rewrote this to be based on which part of the sector is really visible
|
|
|
|
|
|
|
|
fixed_t scale = MulScale19 (InvZtoScale, spr->idepth);
|
2011-01-02 18:02:27 +00:00
|
|
|
fixed_t hzb = FIXED_MIN, hzt = FIXED_MAX;
|
|
|
|
|
|
|
|
if (spr->bIsVoxel && spr->floorclip != 0)
|
|
|
|
{
|
|
|
|
hzb = spr->gzb;
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
if (spr->heightsec && !(spr->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC))
|
2006-02-24 04:48:15 +00:00
|
|
|
{ // only things in specially marked sectors
|
|
|
|
if (spr->FakeFlatStat != FAKED_AboveCeiling)
|
|
|
|
{
|
2011-01-02 18:02:27 +00:00
|
|
|
fixed_t hz = spr->heightsec->floorplane.ZatPoint (spr->gx, spr->gy);
|
|
|
|
fixed_t h = (centeryfrac - FixedMul (hz-viewz, scale)) >> FRACBITS;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
if (spr->FakeFlatStat == FAKED_BelowFloor)
|
|
|
|
{ // seen below floor: clip top
|
2011-01-02 18:02:27 +00:00
|
|
|
if (!spr->bIsVoxel && h > topclip)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
topclip = MIN<short> (h, viewheight);
|
|
|
|
}
|
2011-01-02 18:02:27 +00:00
|
|
|
hzt = MIN(hzt, hz);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // seen in the middle: clip bottom
|
2011-01-02 18:02:27 +00:00
|
|
|
if (!spr->bIsVoxel && h < botclip)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
botclip = MAX<short> (0, h);
|
|
|
|
}
|
2011-01-02 18:02:27 +00:00
|
|
|
hzb = MAX(hzb, hz);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (spr->FakeFlatStat != FAKED_BelowFloor)
|
|
|
|
{
|
2011-01-02 18:02:27 +00:00
|
|
|
fixed_t hz = spr->heightsec->ceilingplane.ZatPoint (spr->gx, spr->gy);
|
|
|
|
fixed_t h = (centeryfrac - FixedMul (hz-viewz, scale)) >> FRACBITS;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
if (spr->FakeFlatStat == FAKED_AboveCeiling)
|
|
|
|
{ // seen above ceiling: clip bottom
|
2011-01-02 18:02:27 +00:00
|
|
|
if (!spr->bIsVoxel && h < botclip)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
botclip = MAX<short> (0, h);
|
|
|
|
}
|
2011-01-02 18:02:27 +00:00
|
|
|
hzb = MAX(hzb, hz);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // seen in the middle: clip top
|
2011-01-02 18:02:27 +00:00
|
|
|
if (!spr->bIsVoxel && h > topclip)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
topclip = MIN<short> (h, viewheight);
|
|
|
|
}
|
2011-01-02 18:02:27 +00:00
|
|
|
hzt = MIN(hzt, hz);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// killough 3/27/98: end special clipping for deep water / fake ceilings
|
2011-01-02 18:02:27 +00:00
|
|
|
else if (!spr->bIsVoxel && spr->floorclip)
|
2006-02-24 04:48:15 +00:00
|
|
|
{ // [RH] Move floorclip stuff from R_DrawVisSprite to here
|
|
|
|
int clip = ((centeryfrac - FixedMul (spr->texturemid -
|
|
|
|
(spr->pic->GetHeight() << FRACBITS) +
|
|
|
|
spr->floorclip, spr->yscale)) >> FRACBITS);
|
|
|
|
if (clip < botclip)
|
|
|
|
{
|
|
|
|
botclip = MAX<short> (0, clip);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-29 11:09:38 +00:00
|
|
|
if (fake3D & FAKE3D_CLIPBOTTOM)
|
|
|
|
{
|
|
|
|
if (!spr->bIsVoxel)
|
|
|
|
{
|
|
|
|
fixed_t h = sclipBottom;
|
|
|
|
if (spr->fakefloor)
|
|
|
|
{
|
|
|
|
fixed_t floorz = spr->fakefloor->top.plane->Zat0();
|
|
|
|
if (viewz > floorz && floorz == sclipBottom )
|
|
|
|
{
|
|
|
|
h = spr->fakefloor->bottom.plane->Zat0();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
h = (centeryfrac - FixedMul(h-viewz, scale)) >> FRACBITS;
|
|
|
|
if (h < botclip)
|
|
|
|
{
|
|
|
|
botclip = MAX<short>(0, h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
hzb = MAX(hzb, sclipBottom);
|
|
|
|
}
|
|
|
|
if (fake3D & FAKE3D_CLIPTOP)
|
|
|
|
{
|
|
|
|
if (!spr->bIsVoxel)
|
|
|
|
{
|
|
|
|
fixed_t h = sclipTop;
|
|
|
|
|
|
|
|
if (spr->fakeceiling != NULL)
|
|
|
|
{
|
|
|
|
fixed_t ceilingz = spr->fakeceiling->bottom.plane->Zat0();
|
|
|
|
if (viewz < ceilingz && ceilingz == sclipTop)
|
|
|
|
{
|
|
|
|
h = spr->fakeceiling->top.plane->Zat0();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
h = (centeryfrac - FixedMul (h-viewz, scale)) >> FRACBITS;
|
|
|
|
if (h > topclip)
|
|
|
|
{
|
|
|
|
topclip = MIN<short>(h, viewheight);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
hzt = MIN(hzt, sclipTop);
|
|
|
|
}
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
#if 0
|
|
|
|
// [RH] Sprites that were split by a drawseg should also be clipped
|
|
|
|
// by the sector's floor and ceiling. (Not sure how/if to handle this
|
|
|
|
// with fake floors, since those already do clipping.)
|
|
|
|
if (spr->bSplitSprite &&
|
|
|
|
(spr->heightsec == NULL || (spr->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC)))
|
|
|
|
{
|
|
|
|
fixed_t h = spr->sector->floorplane.ZatPoint (spr->gx, spr->gy);
|
|
|
|
h = (centeryfrac - FixedMul (h-viewz, scale)) >> FRACBITS;
|
|
|
|
if (h < botclip)
|
|
|
|
{
|
|
|
|
botclip = MAX<short> (0, h);
|
|
|
|
}
|
|
|
|
h = spr->sector->ceilingplane.ZatPoint (spr->gx, spr->gy);
|
|
|
|
h = (centeryfrac - FixedMul (h-viewz, scale)) >> FRACBITS;
|
|
|
|
if (h > topclip)
|
|
|
|
{
|
|
|
|
topclip = MIN<short> (h, viewheight);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
if (topclip >= botclip)
|
|
|
|
{
|
2011-01-29 11:09:38 +00:00
|
|
|
spr->colormap = colormap;
|
2011-01-02 18:02:27 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = x2 - x1 + 1;
|
|
|
|
clip1 = clipbot + x1;
|
|
|
|
clip2 = cliptop + x1;
|
2006-02-24 04:48:15 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
*clip1++ = botclip;
|
|
|
|
*clip2++ = topclip;
|
|
|
|
} while (--i);
|
|
|
|
|
|
|
|
// Scan drawsegs from end to start for obscuring segs.
|
|
|
|
// The first drawseg that is closer than the sprite is the clip seg.
|
|
|
|
|
|
|
|
// Modified by Lee Killough:
|
|
|
|
// (pointer check was originally nonportable
|
|
|
|
// and buggy, by going past LEFT end of array):
|
|
|
|
|
|
|
|
// for (ds=ds_p-1 ; ds >= drawsegs ; ds--) old buggy code
|
|
|
|
|
|
|
|
for (ds = ds_p; ds-- > firstdrawseg; ) // new -- killough
|
|
|
|
{
|
2011-01-29 11:09:38 +00:00
|
|
|
// kg3D - no clipping on fake segs
|
|
|
|
if(ds->fake) continue;
|
2006-02-24 04:48:15 +00:00
|
|
|
// determine if the drawseg obscures the sprite
|
2011-01-02 18:02:27 +00:00
|
|
|
if (ds->x1 > x2 || ds->x2 < x1 ||
|
2006-02-24 04:48:15 +00:00
|
|
|
(!(ds->silhouette & SIL_BOTH) && ds->maskedtexturecol == -1 &&
|
|
|
|
!ds->bFogBoundary) )
|
|
|
|
{
|
|
|
|
// does not cover sprite
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
r1 = MAX<int> (ds->x1, x1);
|
|
|
|
r2 = MIN<int> (ds->x2, x2);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2009-02-07 03:01:38 +00:00
|
|
|
fixed_t neardepth, fardepth;
|
|
|
|
if (ds->sz1 < ds->sz2)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2009-02-07 03:01:38 +00:00
|
|
|
neardepth = ds->sz1, fardepth = ds->sz2;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-07 03:01:38 +00:00
|
|
|
neardepth = ds->sz2, fardepth = ds->sz1;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
2009-02-07 03:01:38 +00:00
|
|
|
if (neardepth > spr->depth || (fardepth > spr->depth &&
|
2006-02-24 04:48:15 +00:00
|
|
|
// Check if sprite is in front of draw seg:
|
2010-11-19 04:01:15 +00:00
|
|
|
DMulScale32(spr->gy - ds->curline->v1->y, ds->curline->v2->x - ds->curline->v1->x,
|
|
|
|
ds->curline->v1->x - spr->gx, ds->curline->v2->y - ds->curline->v1->y) <= 0))
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
// seg is behind sprite, so draw the mid texture if it has one
|
|
|
|
if (ds->maskedtexturecol != -1 || ds->bFogBoundary)
|
|
|
|
R_RenderMaskedSegRange (ds, r1, r2);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// clip this piece of the sprite
|
|
|
|
// killough 3/27/98: optimized and made much shorter
|
|
|
|
// [RH] Optimized further (at least for VC++;
|
|
|
|
// other compilers should be at least as good as before)
|
|
|
|
|
|
|
|
if (ds->silhouette & SIL_BOTTOM) //bottom sil
|
|
|
|
{
|
|
|
|
clip1 = clipbot + r1;
|
|
|
|
clip2 = openings + ds->sprbottomclip + r1 - ds->x1;
|
|
|
|
i = r2 - r1 + 1;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (*clip1 > *clip2)
|
|
|
|
*clip1 = *clip2;
|
|
|
|
clip1++;
|
|
|
|
clip2++;
|
|
|
|
} while (--i);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ds->silhouette & SIL_TOP) // top sil
|
|
|
|
{
|
|
|
|
clip1 = cliptop + r1;
|
|
|
|
clip2 = openings + ds->sprtopclip + r1 - ds->x1;
|
|
|
|
i = r2 - r1 + 1;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (*clip1 < *clip2)
|
|
|
|
*clip1 = *clip2;
|
|
|
|
clip1++;
|
|
|
|
clip2++;
|
|
|
|
} while (--i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// all clipping has been performed, so draw the sprite
|
|
|
|
|
2011-01-02 18:02:27 +00:00
|
|
|
if (!spr->bIsVoxel)
|
|
|
|
{
|
|
|
|
mfloorclip = clipbot;
|
|
|
|
mceilingclip = cliptop;
|
|
|
|
R_DrawVisSprite (spr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// If it is completely clipped away, don't bother drawing it.
|
|
|
|
if (cliptop[x2] >= clipbot[x2])
|
|
|
|
{
|
|
|
|
for (i = x1; i < x2; ++i)
|
|
|
|
{
|
|
|
|
if (cliptop[i] < clipbot[i])
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (i == x2)
|
|
|
|
{
|
2011-01-29 11:09:38 +00:00
|
|
|
spr->colormap = colormap;
|
2011-01-02 18:02:27 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int minvoxely = spr->gzt <= hzt ? 0 : (spr->gzt - hzt) / spr->yscale;
|
|
|
|
int maxvoxely = spr->gzb > hzb ? INT_MAX : (spr->gzt - hzb) / spr->yscale;
|
|
|
|
R_DrawVisVoxel(spr, minvoxely, maxvoxely, cliptop, clipbot);
|
|
|
|
}
|
2011-01-29 11:09:38 +00:00
|
|
|
spr->colormap = colormap;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
2011-01-29 11:09:38 +00:00
|
|
|
// kg3D:
|
|
|
|
// R_DrawMasked contains sorting
|
|
|
|
// original renamed to R_DrawMaskedSingle
|
|
|
|
|
|
|
|
void R_DrawMaskedSingle (bool renew)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
drawseg_t *ds;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
R_SplitVisSprites ();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
for (i = vsprcount; i > 0; i--)
|
|
|
|
{
|
|
|
|
R_DrawSprite (spritesorter[i-1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// render any remaining masked mid textures
|
|
|
|
|
|
|
|
// Modified by Lee Killough:
|
|
|
|
// (pointer check was originally nonportable
|
|
|
|
// and buggy, by going past LEFT end of array):
|
|
|
|
|
|
|
|
// for (ds=ds_p-1 ; ds >= drawsegs ; ds--) old buggy code
|
|
|
|
|
2011-01-29 11:09:38 +00:00
|
|
|
if (renew)
|
|
|
|
{
|
|
|
|
fake3D |= FAKE3D_REFRESHCLIP;
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
for (ds = ds_p; ds-- > firstdrawseg; ) // new -- killough
|
|
|
|
{
|
2011-01-29 11:09:38 +00:00
|
|
|
// kg3D - no fake segs
|
|
|
|
if (ds->fake) continue;
|
2006-02-24 04:48:15 +00:00
|
|
|
if (ds->maskedtexturecol != -1 || ds->bFogBoundary)
|
|
|
|
{
|
|
|
|
R_RenderMaskedSegRange (ds, ds->x1, ds->x2);
|
|
|
|
}
|
|
|
|
}
|
2011-01-29 11:09:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void R_DrawHeightPlanes(fixed_t height); // kg3D - fake planes
|
|
|
|
|
|
|
|
void R_DrawMasked (void)
|
|
|
|
{
|
|
|
|
R_SortVisSprites (sv_compare, firstvissprite - vissprites);
|
|
|
|
|
|
|
|
if (height_top == NULL)
|
|
|
|
{ // kg3D - no visible 3D floors, normal rendering
|
|
|
|
R_DrawMaskedSingle(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // kg3D - correct sorting
|
|
|
|
HeightLevel *hl;
|
|
|
|
|
|
|
|
// ceilings
|
|
|
|
for (hl = height_cur; hl != NULL && hl->height >= viewz; hl = hl->prev)
|
|
|
|
{
|
|
|
|
if (hl->next)
|
|
|
|
{
|
|
|
|
fake3D = FAKE3D_CLIPBOTTOM | FAKE3D_CLIPTOP;
|
|
|
|
sclipTop = hl->next->height;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fake3D = FAKE3D_CLIPBOTTOM;
|
|
|
|
}
|
|
|
|
sclipBottom = hl->height;
|
|
|
|
R_DrawMaskedSingle(true);
|
|
|
|
R_DrawHeightPlanes(hl->height);
|
|
|
|
}
|
|
|
|
|
|
|
|
// floors
|
|
|
|
fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPTOP;
|
|
|
|
sclipTop = height_top->height;
|
|
|
|
R_DrawMaskedSingle(true);
|
|
|
|
hl = height_top;
|
|
|
|
for (hl = height_top; hl != NULL && hl->height < viewz; hl = hl->next)
|
|
|
|
{
|
|
|
|
R_DrawHeightPlanes(hl->height);
|
|
|
|
if (hl->next)
|
|
|
|
{
|
|
|
|
fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPTOP | FAKE3D_CLIPBOTTOM;
|
|
|
|
sclipTop = hl->next->height;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPBOTTOM;
|
|
|
|
}
|
|
|
|
sclipBottom = hl->height;
|
|
|
|
R_DrawMaskedSingle(true);
|
|
|
|
}
|
|
|
|
R_3D_DeleteHeights();
|
|
|
|
fake3D = 0;
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
// draw the psprites on top of everything but does not draw on side views
|
|
|
|
if (!viewangleoffset)
|
|
|
|
{
|
|
|
|
R_DrawPlayerSprites ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// [RH] Particle functions
|
|
|
|
//
|
|
|
|
|
2007-01-09 16:32:44 +00:00
|
|
|
// [BC] Allow the maximum number of particles to be specified by a cvar (so people
|
|
|
|
// with lots of nice hardware can have lots of particles!).
|
|
|
|
CUSTOM_CVAR( Int, r_maxparticles, 4000, CVAR_ARCHIVE )
|
|
|
|
{
|
|
|
|
if ( self == 0 )
|
|
|
|
self = 4000;
|
|
|
|
else if ( self < 100 )
|
|
|
|
self = 100;
|
|
|
|
|
|
|
|
if ( gamestate != GS_STARTUP )
|
|
|
|
{
|
|
|
|
R_DeinitParticles( );
|
|
|
|
R_InitParticles( );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
void R_InitParticles ()
|
|
|
|
{
|
2010-03-02 04:51:16 +00:00
|
|
|
const char *i;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2008-03-12 02:56:11 +00:00
|
|
|
if ((i = Args->CheckValue ("-numparticles")))
|
2006-02-24 04:48:15 +00:00
|
|
|
NumParticles = atoi (i);
|
2007-01-09 16:32:44 +00:00
|
|
|
// [BC] Use r_maxparticles now.
|
|
|
|
else
|
|
|
|
NumParticles = r_maxparticles;
|
|
|
|
|
|
|
|
// This should be good, but eh...
|
|
|
|
if ( NumParticles < 100 )
|
2006-02-24 04:48:15 +00:00
|
|
|
NumParticles = 100;
|
|
|
|
|
2010-12-14 00:50:02 +00:00
|
|
|
R_DeinitParticles();
|
2006-05-09 03:40:15 +00:00
|
|
|
Particles = new particle_t[NumParticles];
|
2006-02-24 04:48:15 +00:00
|
|
|
R_ClearParticles ();
|
2006-05-12 03:14:40 +00:00
|
|
|
atterm (R_DeinitParticles);
|
|
|
|
}
|
|
|
|
|
|
|
|
void R_DeinitParticles()
|
|
|
|
{
|
|
|
|
if (Particles != NULL)
|
|
|
|
{
|
|
|
|
delete[] Particles;
|
|
|
|
Particles = NULL;
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void R_ClearParticles ()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
memset (Particles, 0, NumParticles * sizeof(particle_t));
|
|
|
|
ActiveParticles = NO_PARTICLE;
|
|
|
|
InactiveParticles = 0;
|
|
|
|
for (i = 0; i < NumParticles-1; i++)
|
|
|
|
Particles[i].tnext = i + 1;
|
|
|
|
Particles[i].tnext = NO_PARTICLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Group particles by subsectors. Because particles are always
|
|
|
|
// in motion, there is little benefit to caching this information
|
|
|
|
// from one frame to the next.
|
|
|
|
|
|
|
|
void R_FindParticleSubsectors ()
|
|
|
|
{
|
|
|
|
if (ParticlesInSubsec.Size() < (size_t)numsubsectors)
|
|
|
|
{
|
|
|
|
ParticlesInSubsec.Reserve (numsubsectors - ParticlesInSubsec.Size());
|
|
|
|
}
|
|
|
|
|
|
|
|
clearbufshort (&ParticlesInSubsec[0], numsubsectors, NO_PARTICLE);
|
|
|
|
|
|
|
|
if (!r_particles)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (WORD i = ActiveParticles; i != NO_PARTICLE; i = Particles[i].tnext)
|
|
|
|
{
|
|
|
|
subsector_t *ssec = R_PointInSubsector (Particles[i].x, Particles[i].y);
|
2009-05-15 10:39:40 +00:00
|
|
|
int ssnum = int(ssec-subsectors);
|
2007-12-25 10:07:58 +00:00
|
|
|
Particles[i].subsector = ssec;
|
2006-02-24 04:48:15 +00:00
|
|
|
Particles[i].snext = ParticlesInSubsec[ssnum];
|
|
|
|
ParticlesInSubsec[ssnum] = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade, int fakeside)
|
|
|
|
{
|
|
|
|
fixed_t tr_x;
|
|
|
|
fixed_t tr_y;
|
|
|
|
fixed_t tx, ty;
|
|
|
|
fixed_t tz, tiz;
|
|
|
|
fixed_t xscale, yscale;
|
|
|
|
int x1, x2, y1, y2;
|
|
|
|
vissprite_t* vis;
|
|
|
|
sector_t* heightsec = NULL;
|
2006-09-14 00:02:31 +00:00
|
|
|
BYTE* map;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// transform the origin point
|
|
|
|
tr_x = particle->x - viewx;
|
|
|
|
tr_y = particle->y - viewy;
|
|
|
|
|
|
|
|
tz = DMulScale20 (tr_x, viewtancos, tr_y, viewtansin);
|
|
|
|
|
|
|
|
// particle is behind view plane?
|
|
|
|
if (tz < MINZ)
|
|
|
|
return;
|
|
|
|
|
|
|
|
tx = DMulScale20 (tr_x, viewsin, -tr_y, viewcos);
|
|
|
|
|
|
|
|
// Flip for mirrors
|
|
|
|
if (MirrorFlags & RF_XFLIP)
|
|
|
|
{
|
|
|
|
tx = viewwidth - tx - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// too far off the side?
|
|
|
|
if (tz <= abs (tx))
|
|
|
|
return;
|
|
|
|
|
|
|
|
tiz = 268435456 / tz;
|
|
|
|
xscale = centerx * tiz;
|
|
|
|
|
|
|
|
// calculate edges of the shape
|
|
|
|
int psize = particle->size << (12-3);
|
|
|
|
|
|
|
|
x1 = MAX<int> (WindowLeft, (centerxfrac + MulScale12 (tx-psize, xscale)) >> FRACBITS);
|
|
|
|
x2 = MIN<int> (WindowRight, (centerxfrac + MulScale12 (tx+psize, xscale)) >> FRACBITS);
|
|
|
|
|
|
|
|
if (x1 >= x2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
yscale = MulScale16 (yaspectmul, xscale);
|
|
|
|
ty = particle->z - viewz;
|
|
|
|
psize <<= 4;
|
|
|
|
y1 = (centeryfrac - FixedMul (ty+psize, yscale)) >> FRACBITS;
|
|
|
|
y2 = (centeryfrac - FixedMul (ty-psize, yscale)) >> FRACBITS;
|
|
|
|
|
|
|
|
// Clip the particle now. Because it's a point and projected as its subsector is
|
|
|
|
// entered, we don't need to clip it to drawsegs like a normal sprite.
|
|
|
|
|
|
|
|
// Clip particles behind walls.
|
|
|
|
if (y1 < ceilingclip[x1]) y1 = ceilingclip[x1];
|
|
|
|
if (y1 < ceilingclip[x2-1]) y1 = ceilingclip[x2-1];
|
|
|
|
if (y2 >= floorclip[x1]) y2 = floorclip[x1] - 1;
|
|
|
|
if (y2 >= floorclip[x2-1]) y2 = floorclip[x2-1] - 1;
|
|
|
|
|
|
|
|
if (y1 > y2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Clip particles above the ceiling or below the floor.
|
2009-05-23 10:21:33 +00:00
|
|
|
heightsec = sector->GetHeightSec();
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
const secplane_t *topplane;
|
|
|
|
const secplane_t *botplane;
|
2008-06-15 18:36:26 +00:00
|
|
|
FTextureID toppic;
|
|
|
|
FTextureID botpic;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
if (heightsec) // only clip things which are in special sectors
|
|
|
|
{
|
|
|
|
if (fakeside == FAKED_AboveCeiling)
|
|
|
|
{
|
|
|
|
topplane = §or->ceilingplane;
|
|
|
|
botplane = &heightsec->ceilingplane;
|
2008-08-16 20:19:35 +00:00
|
|
|
toppic = sector->GetTexture(sector_t::ceiling);
|
|
|
|
botpic = heightsec->GetTexture(sector_t::ceiling);
|
2006-02-24 04:48:15 +00:00
|
|
|
map = heightsec->ColorMap->Maps;
|
|
|
|
}
|
|
|
|
else if (fakeside == FAKED_BelowFloor)
|
|
|
|
{
|
|
|
|
topplane = &heightsec->floorplane;
|
|
|
|
botplane = §or->floorplane;
|
2008-08-16 20:19:35 +00:00
|
|
|
toppic = heightsec->GetTexture(sector_t::floor);
|
|
|
|
botpic = sector->GetTexture(sector_t::floor);
|
2006-02-24 04:48:15 +00:00
|
|
|
map = heightsec->ColorMap->Maps;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
topplane = &heightsec->ceilingplane;
|
|
|
|
botplane = &heightsec->floorplane;
|
2008-08-16 20:19:35 +00:00
|
|
|
toppic = heightsec->GetTexture(sector_t::ceiling);
|
|
|
|
botpic = heightsec->GetTexture(sector_t::floor);
|
2006-02-24 04:48:15 +00:00
|
|
|
map = sector->ColorMap->Maps;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
topplane = §or->ceilingplane;
|
|
|
|
botplane = §or->floorplane;
|
2008-08-16 20:19:35 +00:00
|
|
|
toppic = sector->GetTexture(sector_t::ceiling);
|
|
|
|
botpic = sector->GetTexture(sector_t::floor);
|
2006-02-24 04:48:15 +00:00
|
|
|
map = sector->ColorMap->Maps;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (botpic != skyflatnum && particle->z < botplane->ZatPoint (particle->x, particle->y))
|
|
|
|
return;
|
|
|
|
if (toppic != skyflatnum && particle->z >= topplane->ZatPoint (particle->x, particle->y))
|
|
|
|
return;
|
|
|
|
|
|
|
|
// store information in a vissprite
|
|
|
|
vis = R_NewVisSprite ();
|
|
|
|
vis->heightsec = heightsec;
|
|
|
|
vis->xscale = xscale;
|
|
|
|
// vis->yscale = FixedMul (xscale, InvZtoScale);
|
|
|
|
vis->yscale = xscale;
|
2009-02-07 03:01:38 +00:00
|
|
|
vis->depth = tz;
|
2006-02-24 04:48:15 +00:00
|
|
|
vis->idepth = (DWORD)DivScale32 (1, tz) >> 1;
|
|
|
|
vis->cx = tx;
|
|
|
|
vis->gx = particle->x;
|
|
|
|
vis->gy = particle->y;
|
2011-04-13 02:34:48 +00:00
|
|
|
vis->gz = particle->z; // kg3D
|
2011-01-02 18:02:27 +00:00
|
|
|
vis->gzb = y1;
|
2006-02-24 04:48:15 +00:00
|
|
|
vis->gzt = y2;
|
|
|
|
vis->x1 = x1;
|
|
|
|
vis->x2 = x2;
|
|
|
|
vis->Translation = 0;
|
|
|
|
vis->startfrac = particle->color;
|
|
|
|
vis->pic = NULL;
|
2011-01-02 18:02:27 +00:00
|
|
|
vis->bIsVoxel = false;
|
2006-02-24 04:48:15 +00:00
|
|
|
vis->renderflags = particle->trans;
|
|
|
|
vis->FakeFlatStat = fakeside;
|
|
|
|
vis->floorclip = 0;
|
|
|
|
|
2009-09-20 03:50:05 +00:00
|
|
|
if (fixedlightlev >= 0)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
vis->colormap = map + fixedlightlev;
|
|
|
|
}
|
|
|
|
else if (fixedcolormap)
|
|
|
|
{
|
|
|
|
vis->colormap = fixedcolormap;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Using MulScale15 instead of 16 makes particles slightly more visible
|
|
|
|
// than regular sprites.
|
|
|
|
vis->colormap = map + (GETPALOOKUP (MulScale15 (tiz, r_SpriteVisibility),
|
|
|
|
shade) << COLORMAPSHIFT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void R_DrawMaskedSegsBehindParticle (const vissprite_t *vis)
|
|
|
|
{
|
|
|
|
const int x1 = vis->x1;
|
|
|
|
const int x2 = vis->x2;
|
|
|
|
|
|
|
|
// Draw any masked textures behind this particle so that when the
|
|
|
|
// particle is drawn, it will be in front of them.
|
|
|
|
for (unsigned int p = InterestingDrawsegs.Size(); p-- > FirstInterestingDrawseg; )
|
|
|
|
{
|
|
|
|
drawseg_t *ds = &drawsegs[InterestingDrawsegs[p]];
|
2011-01-29 11:09:38 +00:00
|
|
|
// kg3D - no fake segs
|
|
|
|
if(ds->fake) continue;
|
2006-02-24 04:48:15 +00:00
|
|
|
if (ds->x1 >= x2 || ds->x2 < x1)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (Scale (ds->siz2 - ds->siz1, (x2 + x1)/2 - ds->sx1, ds->sx2 - ds->sx1) + ds->siz1 < vis->idepth)
|
|
|
|
{
|
|
|
|
R_RenderMaskedSegRange (ds, MAX<int> (ds->x1, x1), MIN<int> (ds->x2, x2-1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void R_DrawParticle (vissprite_t *vis)
|
|
|
|
{
|
|
|
|
DWORD *bg2rgb;
|
|
|
|
int spacing;
|
2006-09-14 00:02:31 +00:00
|
|
|
BYTE *dest;
|
2006-02-24 04:48:15 +00:00
|
|
|
DWORD fg;
|
2006-09-14 00:02:31 +00:00
|
|
|
BYTE color = vis->colormap[vis->startfrac];
|
2011-01-02 18:02:27 +00:00
|
|
|
int yl = vis->gzb;
|
2006-02-24 04:48:15 +00:00
|
|
|
int ycount = vis->gzt - yl + 1;
|
|
|
|
int x1 = vis->x1;
|
|
|
|
int countbase = vis->x2 - x1 + 1;
|
|
|
|
|
|
|
|
R_DrawMaskedSegsBehindParticle (vis);
|
|
|
|
|
|
|
|
// vis->renderflags holds translucency level (0-255)
|
|
|
|
{
|
|
|
|
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];
|
|
|
|
}
|
|
|
|
|
- Ported vlinetallasm4 to AMD64 assembly. Even with the increased number of
registers AMD64 provides, this routine still needs to be written as self-
modifying code for maximum performance. The additional registers do allow
for further optimization over the x86 version by allowing all four pixels
to be in flight at the same time. The end result is that AMD64 ASM is about
2.18 times faster than AMD64 C and about 1.06 times faster than x86 ASM.
(For further comparison, AMD64 C and x86 C are practically the same for
this function.) Should I port any more assembly to AMD64, mvlineasm4 is the
most likely candidate, but it's not used enough at this point to bother.
Also, this may or may not work with Linux at the moment, since it doesn't
have the eh_handler metadata. Win64 is easier, since I just need to
structure the function prologue and epilogue properly and use some
assembler directives/macros to automatically generate the metadata. And
that brings up another point: You need YASM to assemble the AMD64 code,
because NASM doesn't support the Win64 metadata directives.
- Added an SSE version of DoBlending. This is strictly C intrinsics.
VC++ still throws around unneccessary register moves. GCC seems to be
pretty close to optimal, requiring only about 2 cycles/color. They're
both faster than my hand-written MMX routine, so I don't need to feel
bad about not hand-optimizing this for x64 builds.
- Removed an extra instruction from DoBlending_MMX, transposed two
instructions, and unrolled it once, shaving off about 80 cycles from the
time required to blend 256 palette entries. Why? Because I tried writing
a C version of the routine using compiler intrinsics and was appalled by
all the extra movq's VC++ added to the code. GCC was better, but still
generated extra instructions. I only wanted a C version because I can't
use inline assembly with VC++'s x64 compiler, and x64 assembly is a bit
of a pain. (It's a pain because Linux and Windows have different calling
conventions, and you need to maintain extra metadata for functions.) So,
the assembly version stays and the C version stays out.
- Removed all the pixel doubling r_detail modes, since the one platform they
were intended to assist (486) actually sees very little benefit from them.
- Rewrote CheckMMX in C and renamed it to CheckCPU.
- Fixed: CPUID function 0x80000005 is specified to return detailed L1 cache
only for AMD processors, so we must not use it on other architectures, or
we end up overwriting the L1 cache line size with 0 or some other number
we don't actually understand.
SVN r1134 (trunk)
2008-08-09 03:13:43 +00:00
|
|
|
spacing = RenderTarget->GetPitch() - countbase;
|
2006-02-24 04:48:15 +00:00
|
|
|
dest = ylookup[yl] + x1 + dc_destorg;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
int count = countbase;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
DWORD bg = bg2rgb[*dest];
|
|
|
|
bg = (fg+bg) | 0x1f07c1f;
|
|
|
|
*dest++ = RGB32k[0][0][bg & (bg>>15)];
|
|
|
|
} while (--count);
|
|
|
|
dest += spacing;
|
|
|
|
} while (--ycount);
|
|
|
|
}
|
2011-01-02 18:02:27 +00:00
|
|
|
|
|
|
|
static fixed_t distrecip(fixed_t y)
|
|
|
|
{
|
|
|
|
y >>= 3;
|
|
|
|
return y == 0 ? 0 : SafeDivScale32(centerxwide, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern fixed_t baseyaspectmul;
|
|
|
|
|
|
|
|
void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t dasprang,
|
|
|
|
fixed_t daxscale, fixed_t dayscale, FVoxel *voxobj,
|
|
|
|
lighttable_t *colormap, short *daumost, short *dadmost, int minslabz, int maxslabz, int flags)
|
|
|
|
{
|
|
|
|
int i, j, k, x, y, syoff, ggxstart, ggystart, nxoff;
|
|
|
|
fixed_t cosang, sinang, sprcosang, sprsinang;
|
|
|
|
int backx, backy, gxinc, gyinc;
|
|
|
|
int daxscalerecip, dayscalerecip, cnt, gxstart, gystart, dazscale;
|
|
|
|
int lx, rx, nx, ny, x1=0, y1=0, x2=0, y2=0, yplc, yinc=0;
|
|
|
|
int yoff, xs=0, ys=0, xe, ye, xi=0, yi=0, cbackx, cbacky, dagxinc, dagyinc;
|
|
|
|
kvxslab_t *voxptr, *voxend;
|
|
|
|
FVoxelMipLevel *mip;
|
|
|
|
|
|
|
|
const int nytooclose = centerxwide * 2100, nytoofar = 32768*32768 - 1048576;
|
|
|
|
const int xdimenscale = Scale(centerxwide, yaspectmul, 160);
|
|
|
|
const fixed_t globalposx = viewx >> 12;
|
|
|
|
const fixed_t globalposy = -viewy >> 12;
|
|
|
|
const fixed_t globalposz = -viewz >> 8;
|
|
|
|
|
|
|
|
dasprx = dasprx >> 12;
|
|
|
|
daspry = -daspry >> 12;
|
|
|
|
dasprz = -dasprz >> 8;
|
|
|
|
daxscale >>= 10;
|
|
|
|
dayscale >>= 10;
|
|
|
|
|
|
|
|
cosang = viewcos >> 2;
|
|
|
|
sinang = -viewsin >> 2;
|
|
|
|
sprcosang = finecosine[dasprang >> ANGLETOFINESHIFT] >> 2;
|
|
|
|
sprsinang = -finesine[dasprang >> ANGLETOFINESHIFT] >> 2;
|
|
|
|
|
|
|
|
R_SetupDrawSlab(colormap);
|
|
|
|
|
|
|
|
// Select mip level
|
|
|
|
i = abs(DMulScale8(dasprx - globalposx, viewcos, daspry - globalposy, -viewsin));
|
|
|
|
i = DivScale6(i, MIN(daxscale, dayscale));
|
|
|
|
j = FocalLengthX >> 3;
|
|
|
|
for (k = 0; k < voxobj->NumMips; ++k)
|
|
|
|
{
|
|
|
|
if (i < j) { break; }
|
|
|
|
i >>= 1;
|
|
|
|
}
|
|
|
|
if (k >= voxobj->NumMips) k = voxobj->NumMips - 1;
|
|
|
|
|
|
|
|
mip = &voxobj->Mips[k]; if (mip->SlabData == NULL) return;
|
|
|
|
|
|
|
|
minslabz >>= k;
|
|
|
|
maxslabz >>= k;
|
|
|
|
|
|
|
|
daxscale <<= (k+8); dayscale <<= (k+8);
|
|
|
|
dazscale = FixedDiv(dayscale, baseyaspectmul);
|
|
|
|
daxscale = FixedDiv(daxscale, yaspectmul);
|
|
|
|
daxscale = Scale(daxscale, xdimenscale, centerxwide << 9);
|
|
|
|
dayscale = Scale(dayscale, FixedMul(xdimenscale, viewingrangerecip), centerxwide << 9);
|
|
|
|
|
|
|
|
daxscalerecip = (1<<30) / daxscale;
|
|
|
|
dayscalerecip = (1<<30) / dayscale;
|
|
|
|
|
|
|
|
x = FixedMul(globalposx - dasprx, daxscalerecip);
|
|
|
|
y = FixedMul(globalposy - daspry, daxscalerecip);
|
|
|
|
backx = (DMulScale10(x, sprcosang, y, sprsinang) + mip->PivotX) >> 8;
|
|
|
|
backy = (DMulScale10(y, sprcosang, x, -sprsinang) + mip->PivotY) >> 8;
|
|
|
|
cbackx = clamp(backx, 0, mip->SizeX - 1);
|
|
|
|
cbacky = clamp(backy, 0, mip->SizeY - 1);
|
|
|
|
|
|
|
|
sprcosang = MulScale14(daxscale, sprcosang);
|
|
|
|
sprsinang = MulScale14(daxscale, sprsinang);
|
|
|
|
|
|
|
|
x = (dasprx - globalposx) - DMulScale18(mip->PivotX, sprcosang, mip->PivotY, -sprsinang);
|
|
|
|
y = (daspry - globalposy) - DMulScale18(mip->PivotY, sprcosang, mip->PivotX, sprsinang);
|
|
|
|
|
|
|
|
cosang = FixedMul(cosang, dayscalerecip);
|
|
|
|
sinang = FixedMul(sinang, dayscalerecip);
|
|
|
|
|
|
|
|
gxstart = y*cosang - x*sinang;
|
|
|
|
gystart = x*cosang + y*sinang;
|
|
|
|
gxinc = DMulScale10(sprsinang, cosang, sprcosang, -sinang);
|
|
|
|
gyinc = DMulScale10(sprcosang, cosang, sprsinang, sinang);
|
|
|
|
if ((abs(globalposz - dasprz) >> 10) >= abs(dazscale)) return;
|
|
|
|
|
|
|
|
x = 0; y = 0; j = MAX(mip->SizeX, mip->SizeY);
|
|
|
|
fixed_t *ggxinc = (fixed_t *)alloca((j + 1) * sizeof(fixed_t) * 2);
|
|
|
|
fixed_t *ggyinc = ggxinc + (j + 1);
|
|
|
|
for (i = 0; i <= j; i++)
|
|
|
|
{
|
|
|
|
ggxinc[i] = x; x += gxinc;
|
|
|
|
ggyinc[i] = y; y += gyinc;
|
|
|
|
}
|
|
|
|
|
|
|
|
syoff = DivScale21(globalposz - dasprz, dazscale) + (mip->PivotZ << 7);
|
|
|
|
yoff = (abs(gxinc) + abs(gyinc)) >> 1;
|
|
|
|
|
|
|
|
for (cnt = 0; cnt < 8; cnt++)
|
|
|
|
{
|
|
|
|
switch (cnt)
|
|
|
|
{
|
|
|
|
case 0: xs = 0; ys = 0; xi = 1; yi = 1; break;
|
|
|
|
case 1: xs = mip->SizeX-1; ys = 0; xi = -1; yi = 1; break;
|
|
|
|
case 2: xs = 0; ys = mip->SizeY-1; xi = 1; yi = -1; break;
|
|
|
|
case 3: xs = mip->SizeX-1; ys = mip->SizeY-1; xi = -1; yi = -1; break;
|
|
|
|
case 4: xs = 0; ys = cbacky; xi = 1; yi = 2; break;
|
|
|
|
case 5: xs = mip->SizeX-1; ys = cbacky; xi = -1; yi = 2; break;
|
|
|
|
case 6: xs = cbackx; ys = 0; xi = 2; yi = 1; break;
|
|
|
|
case 7: xs = cbackx; ys = mip->SizeY-1; xi = 2; yi = -1; break;
|
|
|
|
}
|
|
|
|
xe = cbackx; ye = cbacky;
|
|
|
|
if (cnt < 4)
|
|
|
|
{
|
|
|
|
if ((xi < 0) && (xe >= xs)) continue;
|
|
|
|
if ((xi > 0) && (xe <= xs)) continue;
|
|
|
|
if ((yi < 0) && (ye >= ys)) continue;
|
|
|
|
if ((yi > 0) && (ye <= ys)) continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((xi < 0) && (xe > xs)) continue;
|
|
|
|
if ((xi > 0) && (xe < xs)) continue;
|
|
|
|
if ((yi < 0) && (ye > ys)) continue;
|
|
|
|
if ((yi > 0) && (ye < ys)) continue;
|
|
|
|
xe += xi; ye += yi;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = ksgn(ys-backy)+ksgn(xs-backx)*3+4;
|
|
|
|
switch(i)
|
|
|
|
{
|
|
|
|
case 6: case 7: x1 = 0; y1 = 0; break;
|
|
|
|
case 8: case 5: x1 = gxinc; y1 = gyinc; break;
|
|
|
|
case 0: case 3: x1 = gyinc; y1 = -gxinc; break;
|
|
|
|
case 2: case 1: x1 = gxinc+gyinc; y1 = gyinc-gxinc; break;
|
|
|
|
}
|
|
|
|
switch(i)
|
|
|
|
{
|
|
|
|
case 2: case 5: x2 = 0; y2 = 0; break;
|
|
|
|
case 0: case 1: x2 = gxinc; y2 = gyinc; break;
|
|
|
|
case 8: case 7: x2 = gyinc; y2 = -gxinc; break;
|
|
|
|
case 6: case 3: x2 = gxinc+gyinc; y2 = gyinc-gxinc; break;
|
|
|
|
}
|
|
|
|
BYTE oand = (1 << int(xs<backx)) + (1 << (int(ys<backy)+2));
|
|
|
|
BYTE oand16 = oand + 16;
|
|
|
|
BYTE oand32 = oand + 32;
|
|
|
|
|
|
|
|
if (yi > 0) { dagxinc = gxinc; dagyinc = FixedMul(gyinc, viewingrangerecip); }
|
|
|
|
else { dagxinc = -gxinc; dagyinc = -FixedMul(gyinc, viewingrangerecip); }
|
|
|
|
|
|
|
|
/* Fix for non 90 degree viewing ranges */
|
|
|
|
nxoff = FixedMul(x2 - x1, viewingrangerecip);
|
|
|
|
x1 = FixedMul(x1, viewingrangerecip);
|
|
|
|
|
|
|
|
ggxstart = gxstart + ggyinc[ys];
|
|
|
|
ggystart = gystart - ggxinc[ys];
|
|
|
|
|
|
|
|
for (x = xs; x != xe; x += xi)
|
|
|
|
{
|
|
|
|
BYTE *slabxoffs = &mip->SlabData[mip->OffsetX[x]];
|
|
|
|
short *xyoffs = &mip->OffsetXY[x * (mip->SizeY + 1)];
|
|
|
|
|
|
|
|
nx = FixedMul(ggxstart + ggxinc[x], viewingrangerecip) + x1;
|
|
|
|
ny = ggystart + ggyinc[x];
|
|
|
|
for (y = ys; y != ye; y += yi, nx += dagyinc, ny -= dagxinc)
|
|
|
|
{
|
|
|
|
if ((ny <= nytooclose) || (ny >= nytoofar)) continue;
|
|
|
|
voxptr = (kvxslab_t *)(slabxoffs + xyoffs[y]);
|
|
|
|
voxend = (kvxslab_t *)(slabxoffs + xyoffs[y+1]);
|
|
|
|
if (voxptr >= voxend) continue;
|
|
|
|
|
|
|
|
lx = MulScale32(nx >> 3, distrecip(ny+y1)) + centerx;
|
|
|
|
if (lx < 0) lx = 0;
|
|
|
|
rx = MulScale32((nx + nxoff) >> 3, distrecip(ny+y2)) + centerx;
|
|
|
|
if (rx > viewwidth) rx = viewwidth;
|
|
|
|
if (rx <= lx) continue;
|
|
|
|
rx -= lx;
|
|
|
|
|
|
|
|
fixed_t l1 = distrecip(ny-yoff);
|
|
|
|
fixed_t l2 = distrecip(ny+yoff);
|
|
|
|
for (; voxptr < voxend; voxptr = (kvxslab_t *)((BYTE *)voxptr + voxptr->zleng + 3))
|
|
|
|
{
|
|
|
|
const BYTE *col = voxptr->col;
|
|
|
|
int zleng = voxptr->zleng;
|
|
|
|
int ztop = voxptr->ztop;
|
|
|
|
fixed_t z1, z2;
|
|
|
|
|
|
|
|
if (ztop < minslabz)
|
|
|
|
{
|
|
|
|
int diff = minslabz - ztop;
|
|
|
|
ztop = minslabz;
|
|
|
|
col += diff;
|
|
|
|
zleng -= diff;
|
|
|
|
}
|
|
|
|
if (ztop + zleng > maxslabz)
|
|
|
|
{
|
|
|
|
int diff = ztop + zleng - maxslabz;
|
|
|
|
zleng -= diff;
|
|
|
|
}
|
|
|
|
if (zleng <= 0) continue;
|
|
|
|
|
|
|
|
j = (ztop << 15) - syoff;
|
|
|
|
if (j < 0)
|
|
|
|
{
|
|
|
|
k = j + (zleng << 15);
|
|
|
|
if (k < 0)
|
|
|
|
{
|
|
|
|
if ((voxptr->backfacecull & oand32) == 0) continue;
|
|
|
|
z2 = MulScale32(l2, k) + centery; /* Below slab */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((voxptr->backfacecull & oand) == 0) continue; /* Middle of slab */
|
|
|
|
z2 = MulScale32(l1, k) + centery;
|
|
|
|
}
|
|
|
|
z1 = MulScale32(l1, j) + centery;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((voxptr->backfacecull & oand16) == 0) continue;
|
|
|
|
z1 = MulScale32(l2, j) + centery; /* Above slab */
|
|
|
|
z2 = MulScale32(l1, j + (zleng << 15)) + centery;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zleng == 1)
|
|
|
|
{
|
|
|
|
yplc = 0; yinc = 0;
|
|
|
|
if (z1 < daumost[lx]) z1 = daumost[lx];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (z2-z1 >= 1024) yinc = FixedDiv(zleng, z2 - z1);
|
|
|
|
else if (z2 > z1) yinc = (((1 << 24) - 1) / (z2 - z1)) * zleng >> 8;
|
|
|
|
if (z1 < daumost[lx]) { yplc = yinc*(daumost[lx]-z1); z1 = daumost[lx]; } else yplc = 0;
|
|
|
|
}
|
|
|
|
if (z2 > dadmost[lx]) z2 = dadmost[lx];
|
|
|
|
z2 -= z1; if (z2 <= 0) continue;
|
|
|
|
|
|
|
|
if (!(flags & DVF_OFFSCREEN))
|
|
|
|
{
|
|
|
|
// Draw directly to the screen.
|
|
|
|
R_DrawSlab(rx, yplc, z2, yinc, col, ylookup[z1] + lx + dc_destorg);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Record the area covered and possibly draw to an offscreen buffer.
|
|
|
|
dc_yl = z1;
|
|
|
|
dc_yh = z1 + z2 - 1;
|
|
|
|
dc_count = z2;
|
|
|
|
dc_iscale = yinc;
|
|
|
|
for (int x = 0; x < rx; ++x)
|
|
|
|
{
|
|
|
|
OffscreenCoverageBuffer->InsertSpan(lx + x, z1, z1 + z2);
|
|
|
|
if (!(flags & DVF_SPANSONLY))
|
|
|
|
{
|
|
|
|
dc_x = lx + x;
|
|
|
|
rt_initcols(OffscreenColorBuffer + (dc_x & ~3) * OffscreenBufferHeight);
|
|
|
|
dc_source = col;
|
|
|
|
dc_texturefrac = yplc;
|
|
|
|
hcolfunc_pre();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// FCoverageBuffer Constructor
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
FCoverageBuffer::FCoverageBuffer(int lists)
|
|
|
|
: Spans(NULL), FreeSpans(NULL)
|
|
|
|
{
|
|
|
|
NumLists = lists;
|
|
|
|
Spans = new Span *[lists];
|
|
|
|
memset(Spans, 0, sizeof(Span*)*lists);
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// FCoverageBuffer Destructor
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
FCoverageBuffer::~FCoverageBuffer()
|
|
|
|
{
|
|
|
|
if (Spans != NULL)
|
|
|
|
{
|
|
|
|
delete[] Spans;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// FCoverageBuffer :: Clear
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
void FCoverageBuffer::Clear()
|
|
|
|
{
|
|
|
|
SpanArena.FreeAll();
|
|
|
|
memset(Spans, 0, sizeof(Span*)*NumLists);
|
|
|
|
FreeSpans = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// FCoverageBuffer :: InsertSpan
|
|
|
|
//
|
|
|
|
// start is inclusive.
|
|
|
|
// stop is exclusive.
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
void FCoverageBuffer::InsertSpan(int listnum, int start, int stop)
|
|
|
|
{
|
|
|
|
assert(unsigned(listnum) < NumLists);
|
|
|
|
assert(start < stop);
|
|
|
|
|
|
|
|
Span **span_p = &Spans[listnum];
|
|
|
|
Span *span;
|
|
|
|
|
|
|
|
if (*span_p == NULL || (*span_p)->Start > stop)
|
|
|
|
{ // This list is empty or the first entry is after this one, so we can just insert the span.
|
|
|
|
goto addspan;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Insert the new span in order, merging with existing ones.
|
|
|
|
while (*span_p != NULL)
|
|
|
|
{
|
|
|
|
if ((*span_p)->Stop < start) // ===== (existing span)
|
|
|
|
{ // Span ends before this one starts. // ++++ (new span)
|
|
|
|
span_p = &(*span_p)->NextSpan;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Does the new span overlap or abut the existing one?
|
|
|
|
if ((*span_p)->Start <= start)
|
|
|
|
{
|
|
|
|
if ((*span_p)->Stop >= stop) // =============
|
|
|
|
{ // The existing span completely covers this one. // +++++
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Extend the existing span with the new one. // ======
|
|
|
|
span = *span_p; // +++++++
|
|
|
|
span->Stop = stop; // (or) +++++
|
|
|
|
|
|
|
|
// Free up any spans we just covered up.
|
|
|
|
span_p = &(*span_p)->NextSpan;
|
|
|
|
while (*span_p != NULL && (*span_p)->Start <= stop && (*span_p)->Stop <= stop)
|
|
|
|
{
|
|
|
|
Span *span = *span_p; // ====== ======
|
|
|
|
*span_p = span->NextSpan; // +++++++++++++
|
|
|
|
span->NextSpan = FreeSpans;
|
|
|
|
FreeSpans = span;
|
|
|
|
}
|
|
|
|
if (*span_p != NULL && (*span_p)->Start <= stop) // ======= ========
|
|
|
|
{ // Our new span connects two existing spans. // ++++++++++++++
|
|
|
|
// They should all be collapsed into a single span.
|
|
|
|
span->Stop = (*span_p)->Stop;
|
|
|
|
span = *span_p;
|
|
|
|
*span_p = span->NextSpan;
|
|
|
|
span->NextSpan = FreeSpans;
|
|
|
|
FreeSpans = span;
|
|
|
|
}
|
|
|
|
goto check;
|
|
|
|
}
|
|
|
|
else if ((*span_p)->Start <= stop) // =====
|
|
|
|
{ // The new span extends the existing span from // ++++
|
|
|
|
// the beginning. // (or) ++++
|
|
|
|
(*span_p)->Start = start;
|
|
|
|
goto check;
|
|
|
|
}
|
|
|
|
else // ======
|
|
|
|
{ // No overlap, so insert a new span. // +++++
|
|
|
|
goto addspan;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Append a new span to the end of the list.
|
|
|
|
addspan:
|
|
|
|
span = AllocSpan();
|
|
|
|
span->NextSpan = *span_p;
|
|
|
|
span->Start = start;
|
|
|
|
span->Stop = stop;
|
|
|
|
*span_p = span;
|
|
|
|
check:
|
|
|
|
#ifdef _DEBUG
|
|
|
|
// Validate the span list: Spans must be in order, and there must be
|
|
|
|
// at least one pixel between spans.
|
|
|
|
for (span = Spans[listnum]; span != NULL; span = span->NextSpan)
|
|
|
|
{
|
|
|
|
assert(span->Start < span->Stop);
|
|
|
|
if (span->NextSpan != NULL)
|
|
|
|
{
|
|
|
|
assert(span->Stop < span->NextSpan->Start);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// FCoverageBuffer :: AllocSpan
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
FCoverageBuffer::Span *FCoverageBuffer::AllocSpan()
|
|
|
|
{
|
|
|
|
Span *span;
|
|
|
|
|
|
|
|
if (FreeSpans != NULL)
|
|
|
|
{
|
|
|
|
span = FreeSpans;
|
|
|
|
FreeSpans = span->NextSpan;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
span = (Span *)SpanArena.Alloc(sizeof(Span));
|
|
|
|
}
|
|
|
|
return span;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// R_CheckOffscreenBuffer
|
|
|
|
//
|
|
|
|
// Allocates the offscreen coverage buffer and optionally the offscreen
|
|
|
|
// color buffer. If they already exist but are the wrong size, they will
|
|
|
|
// be reallocated.
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
void R_CheckOffscreenBuffer(int width, int height, bool spansonly)
|
|
|
|
{
|
|
|
|
if (OffscreenCoverageBuffer == NULL)
|
|
|
|
{
|
|
|
|
assert(OffscreenColorBuffer == NULL && "The color buffer cannot exist without the coverage buffer");
|
|
|
|
OffscreenCoverageBuffer = new FCoverageBuffer(width);
|
|
|
|
}
|
2011-02-19 08:59:43 +00:00
|
|
|
else if (OffscreenCoverageBuffer->NumLists != (unsigned)width)
|
2011-01-02 18:02:27 +00:00
|
|
|
{
|
|
|
|
delete OffscreenCoverageBuffer;
|
|
|
|
OffscreenCoverageBuffer = new FCoverageBuffer(width);
|
|
|
|
if (OffscreenColorBuffer != NULL)
|
|
|
|
{
|
|
|
|
delete[] OffscreenColorBuffer;
|
|
|
|
OffscreenColorBuffer = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
OffscreenCoverageBuffer->Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!spansonly)
|
|
|
|
{
|
|
|
|
if (OffscreenColorBuffer == NULL)
|
|
|
|
{
|
|
|
|
OffscreenColorBuffer = new BYTE[width * height];
|
|
|
|
}
|
|
|
|
else if (OffscreenBufferWidth != width || OffscreenBufferHeight != height)
|
|
|
|
{
|
|
|
|
delete[] OffscreenColorBuffer;
|
|
|
|
OffscreenColorBuffer = new BYTE[width * height];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
OffscreenBufferWidth = width;
|
|
|
|
OffscreenBufferHeight = height;
|
|
|
|
}
|