mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Say you have a higher plane in the foreground and a lower one behind. And then insert a sprite above the plane in the background, the top of which is higher than the height in the foreground. Should the sprite be drawn in front of the foreground plane? I think not. Sprites drawing in front of a plane if only part of them is above the plane is a rendering trick that allows sprites to extend into the floor. This doesn't make sense if the plane they extend into would be obscured anyway, or if they don't extend into the plane at all.
268 lines
7.4 KiB
C
268 lines
7.4 KiB
C
// SONIC ROBO BLAST 2
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
|
// Copyright (C) 1999-2020 by Sonic Team Junior.
|
|
//
|
|
// This program is free software distributed under the
|
|
// terms of the GNU General Public License, version 2.
|
|
// See the 'LICENSE' file for more details.
|
|
//-----------------------------------------------------------------------------
|
|
/// \file r_things.h
|
|
/// \brief Rendering of moving objects, sprites
|
|
|
|
#ifndef __R_THINGS__
|
|
#define __R_THINGS__
|
|
|
|
#include "r_plane.h"
|
|
#include "r_picformats.h"
|
|
#include "r_portal.h"
|
|
#include "r_defs.h"
|
|
#include "r_skins.h"
|
|
|
|
// --------------
|
|
// SPRITE LOADING
|
|
// --------------
|
|
|
|
#define FEETADJUST (4<<FRACBITS) // R_AddSingleSpriteDef
|
|
|
|
boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 wadnum, UINT16 startlump, UINT16 endlump);
|
|
|
|
//faB: find sprites in wadfile, replace existing, add new ones
|
|
// (only sprites from namelist are added or replaced)
|
|
void R_AddSpriteDefs(UINT16 wadnum);
|
|
|
|
// ---------------------
|
|
// MASKED COLUMN DRAWING
|
|
// ---------------------
|
|
|
|
// vars for R_DrawMaskedColumn
|
|
extern INT16 *mfloorclip;
|
|
extern INT16 *mceilingclip;
|
|
extern fixed_t spryscale;
|
|
extern fixed_t sprtopscreen;
|
|
extern fixed_t sprbotscreen;
|
|
extern fixed_t windowtop;
|
|
extern fixed_t windowbottom;
|
|
extern INT32 lengthcol;
|
|
|
|
void R_DrawMaskedColumn(column_t *column);
|
|
void R_DrawFlippedMaskedColumn(column_t *column);
|
|
|
|
// ----------------
|
|
// SPRITE RENDERING
|
|
// ----------------
|
|
|
|
// Constant arrays used for psprite clipping
|
|
// and initializing clipping.
|
|
extern INT16 negonearray[MAXVIDWIDTH];
|
|
extern INT16 screenheightarray[MAXVIDWIDTH];
|
|
|
|
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
|
|
|
|
//SoM: 6/5/2000: Light sprites correctly!
|
|
void R_AddSprites(sector_t *sec, INT32 lightlevel);
|
|
void R_InitSprites(void);
|
|
void R_ClearSprites(void);
|
|
void R_ClipSprites(drawseg_t* dsstart, portal_t* portal);
|
|
|
|
boolean R_ThingVisible (mobj_t *thing);
|
|
|
|
boolean R_ThingVisibleWithinDist (mobj_t *thing,
|
|
fixed_t draw_dist);
|
|
|
|
boolean R_PrecipThingVisible (precipmobj_t *precipthing,
|
|
fixed_t precip_draw_dist);
|
|
|
|
// --------------
|
|
// MASKED DRAWING
|
|
// --------------
|
|
/** Used to count the amount of masked elements
|
|
* per portal to later group them in separate
|
|
* drawnode lists.
|
|
*/
|
|
typedef struct
|
|
{
|
|
size_t drawsegs[2];
|
|
size_t vissprites[2];
|
|
fixed_t viewx, viewy, viewz; /**< View z stored at the time of the BSP traversal for the view/portal. Masked sorting/drawing needs it. */
|
|
sector_t* viewsector;
|
|
} maskcount_t;
|
|
|
|
void R_DrawMasked(maskcount_t* masks, UINT8 nummasks);
|
|
|
|
// ----------
|
|
// VISSPRITES
|
|
// ----------
|
|
|
|
// number of sprite lumps for spritewidth,offset,topoffset lookup tables
|
|
// Fab: this is a hack : should allocate the lookup tables per sprite
|
|
#define MAXVISSPRITES 2048 // added 2-2-98 was 128
|
|
|
|
#define VISSPRITECHUNKBITS 6 // 2^6 = 64 sprites per chunk
|
|
#define VISSPRITESPERCHUNK (1 << VISSPRITECHUNKBITS)
|
|
#define VISSPRITEINDEXMASK (VISSPRITESPERCHUNK - 1)
|
|
|
|
typedef enum
|
|
{
|
|
// actual cuts
|
|
SC_NONE = 0,
|
|
SC_TOP = 1,
|
|
SC_BOTTOM = 1<<1,
|
|
// other flags
|
|
SC_PRECIP = 1<<2,
|
|
SC_LINKDRAW = 1<<3,
|
|
SC_FULLBRIGHT = 1<<4,
|
|
SC_SEMIBRIGHT = 1<<5,
|
|
SC_VFLIP = 1<<6,
|
|
SC_ISSCALED = 1<<7,
|
|
SC_SHADOW = 1<<8,
|
|
// masks
|
|
SC_CUTMASK = SC_TOP|SC_BOTTOM,
|
|
SC_FLAGMASK = ~SC_CUTMASK
|
|
} spritecut_e;
|
|
|
|
// A vissprite_t is a thing that will be drawn during a refresh,
|
|
// i.e. a sprite object that is partly visible.
|
|
typedef struct vissprite_s
|
|
{
|
|
// Doubly linked list.
|
|
struct vissprite_s *prev;
|
|
struct vissprite_s *next;
|
|
|
|
// Bonus linkdraw pointer.
|
|
struct vissprite_s *linkdraw;
|
|
|
|
mobj_t *mobj; // for easy access
|
|
|
|
INT32 x1, x2;
|
|
|
|
fixed_t gx, gy; // for line side calculation
|
|
fixed_t gz, gzt; // global bottom/top for silhouette clipping and sorting with 3D floors
|
|
|
|
fixed_t startfrac; // horizontal position of x1
|
|
fixed_t scale, sortscale; // sortscale only differs from scale for paper sprites and MF2_LINKDRAW
|
|
fixed_t scalestep; // only for paper sprites, 0 otherwise
|
|
fixed_t paperoffset, paperdistance; // for paper sprites, offset/dist relative to the angle
|
|
fixed_t xiscale; // negative if flipped
|
|
|
|
angle_t centerangle; // for paper sprites
|
|
|
|
struct {
|
|
fixed_t tan; // The amount to shear the sprite vertically per row
|
|
INT32 offset; // The center of the shearing location offset from x1
|
|
} shear;
|
|
|
|
fixed_t texturemid;
|
|
patch_t *patch;
|
|
|
|
lighttable_t *colormap; // for color translation and shadow draw
|
|
// maxbright frames as well
|
|
|
|
UINT8 *transmap; // which translucency table to use
|
|
|
|
INT32 mobjflags;
|
|
|
|
INT32 heightsec; // height sector for underwater/fake ceiling support
|
|
|
|
extracolormap_t *extra_colormap; // global colormaps
|
|
|
|
fixed_t xscale;
|
|
|
|
// Precalculated top and bottom screen coords for the sprite.
|
|
sector_t *sector; // The sector containing the thing.
|
|
fixed_t pt, pb; // plane heights, also for sorting against 3D floors
|
|
INT16 sz, szt;
|
|
|
|
spritecut_e cut;
|
|
|
|
INT16 clipbot[MAXVIDWIDTH], cliptop[MAXVIDWIDTH];
|
|
|
|
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
|
} vissprite_t;
|
|
|
|
extern UINT32 visspritecount;
|
|
|
|
// ----------
|
|
// DRAW NODES
|
|
// ----------
|
|
|
|
// A drawnode is something that points to a 3D floor, 3D side, or masked
|
|
// middle texture. This is used for sorting with sprites.
|
|
typedef struct drawnode_s
|
|
{
|
|
visplane_t *plane;
|
|
drawseg_t *seg;
|
|
drawseg_t *thickseg;
|
|
ffloor_t *ffloor;
|
|
vissprite_t *sprite;
|
|
|
|
struct drawnode_s *next;
|
|
struct drawnode_s *prev;
|
|
} drawnode_t;
|
|
|
|
void R_InitDrawNodes(void);
|
|
|
|
// -----------------------
|
|
// SPRITE FRAME CHARACTERS
|
|
// -----------------------
|
|
|
|
// Functions to go from sprite character ID to frame number
|
|
// for 2.1 compatibility this still uses the old 'A' + frame code
|
|
// The use of symbols tends to be painful for wad editors though
|
|
// So the future version of this tries to avoid using symbols
|
|
// as much as possible while also defining all 64 slots in a sane manner
|
|
// 2.1: [[ ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ]]
|
|
// Future: [[ ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!@ ]]
|
|
FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame)
|
|
{
|
|
#if 0 // 2.1 compat
|
|
return 'A' + frame;
|
|
#else
|
|
if (frame < 26) return 'A' + frame;
|
|
if (frame < 36) return '0' + (frame - 26);
|
|
if (frame < 62) return 'a' + (frame - 36);
|
|
if (frame == 62) return '!';
|
|
if (frame == 63) return '@';
|
|
return '\xFF';
|
|
#endif
|
|
}
|
|
|
|
FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn)
|
|
{
|
|
#if 0 // 2.1 compat
|
|
if (cn == '+') return '\\' - 'A'; // PK3 can't use backslash, so use + instead
|
|
return cn - 'A';
|
|
#else
|
|
if (cn >= 'A' && cn <= 'Z') return (cn - 'A');
|
|
if (cn >= '0' && cn <= '9') return (cn - '0') + 26;
|
|
if (cn >= 'a' && cn <= 'z') return (cn - 'a') + 36;
|
|
if (cn == '!') return 62;
|
|
if (cn == '@') return 63;
|
|
return 255;
|
|
#endif
|
|
}
|
|
|
|
// "Left" and "Right" character symbols for additional rotation functionality
|
|
#define ROT_L 17
|
|
#define ROT_R 18
|
|
|
|
FUNCMATH FUNCINLINE static ATTRINLINE char R_Rotation2Char(UINT8 rot)
|
|
{
|
|
if (rot <= 9) return '0' + rot;
|
|
if (rot <= 16) return 'A' + (rot - 10);
|
|
if (rot == ROT_L) return 'L';
|
|
if (rot == ROT_R) return 'R';
|
|
return '\xFF';
|
|
}
|
|
|
|
FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Rotation(char cn)
|
|
{
|
|
if (cn >= '0' && cn <= '9') return (cn - '0');
|
|
if (cn >= 'A' && cn <= 'G') return (cn - 'A') + 10;
|
|
if (cn == 'L') return ROT_L;
|
|
if (cn == 'R') return ROT_R;
|
|
return 255;
|
|
}
|
|
|
|
#endif //__R_THINGS__
|