1 // SONIC ROBO BLAST 2
2 //-----------------------------------------------------------------------------
3 // Copyright (C) 1993-1996 by id Software, Inc.
4 // Copyright (C) 1998-2000 by DooM Legacy Team.
5 // Copyright (C) 1999-2020 by Sonic Team Junior.
6 //
7 // This program is free software distributed under the
8 // terms of the GNU General Public License, version 2.
9 // See the 'LICENSE' file for more details.
10 //-----------------------------------------------------------------------------
11 /// \file  r_defs.h
12 /// \brief Refresh/rendering module, shared data struct definitions
13 
14 #ifndef __R_DEFS__
15 #define __R_DEFS__
16 
17 // Some more or less basic data types we depend on.
18 #include "m_fixed.h"
19 
20 // We rely on the thinker data struct to handle sound origins in sectors.
21 #include "d_think.h"
22 // SECTORS do store MObjs anyway.
23 #include "p_mobj.h"
24 
25 #include "screen.h" // MAXVIDWIDTH, MAXVIDHEIGHT
26 
27 #ifdef HWRENDER
28 #include "m_aatree.h"
29 #endif
30 
31 #include "taglist.h"
32 
33 //
34 // ClipWallSegment
35 // Clips the given range of columns
36 // and includes it in the new clip list.
37 //
38 typedef struct
39 {
40 	INT32 first;
41 	INT32 last;
42 } cliprange_t;
43 
44 // Silhouette, needed for clipping segs (mainly) and sprites representing things.
45 #define SIL_NONE   0
46 #define SIL_BOTTOM 1
47 #define SIL_TOP    2
48 #define SIL_BOTH   3
49 
50 // This could be wider for >8 bit display.
51 // Indeed, true color support is possible precalculating 24bpp lightmap/colormap LUT
52 // from darkening PLAYPAL to all black.
53 // Could even use more than 32 levels.
54 typedef UINT8 lighttable_t;
55 
56 #define CMF_FADEFULLBRIGHTSPRITES  1
57 #define CMF_FOG 4
58 
59 // ExtraColormap type. Use for extra_colormaps from now on.
60 typedef struct extracolormap_s
61 {
62 	UINT8 fadestart, fadeend;
63 	UINT8 flags;
64 
65 	// store rgba values in combined bitwise
66 	// also used in OpenGL instead lighttables
67 	INT32 rgba; // similar to maskcolor in sw mode
68 	INT32 fadergba; // The colour the colourmaps fade to
69 
70 	lighttable_t *colormap;
71 
72 #ifdef EXTRACOLORMAPLUMPS
73 	lumpnum_t lump; // for colormap lump matching, init to LUMPERROR
74 	char lumpname[9]; // for netsyncing
75 #endif
76 
77 	struct extracolormap_s *next;
78 	struct extracolormap_s *prev;
79 } extracolormap_t;
80 
81 //
82 // INTERNAL MAP TYPES used by play and refresh
83 //
84 
85 /** Your plain vanilla vertex.
86   */
87 typedef struct
88 {
89 	fixed_t x, y;
90 	boolean floorzset, ceilingzset;
91 	fixed_t floorz, ceilingz;
92 } vertex_t;
93 
94 // Forward of linedefs, for sectors.
95 struct line_s;
96 
97 /** Degenerate version of ::mobj_t, storing only a location.
98   * Used for sound origins in sectors, hoop centers, and the like. Does not
99   * handle sound from moving objects (doppler), because position is probably
100   * just buffered, not updated.
101   */
102 typedef struct
103 {
104 	thinker_t thinker; ///< Not used for anything.
105 	fixed_t x;         ///< X coordinate.
106 	fixed_t y;         ///< Y coordinate.
107 	fixed_t z;         ///< Z coordinate.
108 } degenmobj_t;
109 
110 #include "p_polyobj.h"
111 
112 // Store fake planes in a resizable array insted of just by
113 // heightsec. Allows for multiple fake planes.
114 /** Flags describing 3Dfloor behavior and appearance.
115   */
116 typedef enum
117 {
118 	FF_EXISTS            = 0x1,        ///< Always set, to check for validity.
119 	FF_BLOCKPLAYER       = 0x2,        ///< Solid to player, but nothing else
120 	FF_BLOCKOTHERS       = 0x4,        ///< Solid to everything but player
121 	FF_SOLID             = 0x6,        ///< Clips things.
122 	FF_RENDERSIDES       = 0x8,        ///< Renders the sides.
123 	FF_RENDERPLANES      = 0x10,       ///< Renders the floor/ceiling.
124 	FF_RENDERALL         = 0x18,       ///< Renders everything.
125 	FF_SWIMMABLE         = 0x20,       ///< Is a water block.
126 	FF_NOSHADE           = 0x40,       ///< Messes with the lighting?
127 	FF_CUTSOLIDS         = 0x80,       ///< Cuts out hidden solid pixels.
128 	FF_CUTEXTRA          = 0x100,      ///< Cuts out hidden translucent pixels.
129 	FF_CUTLEVEL          = 0x180,      ///< Cuts out all hidden pixels.
130 	FF_CUTSPRITES        = 0x200,      ///< Final step in making 3D water.
131 	FF_BOTHPLANES        = 0x400,      ///< Render inside and outside planes.
132 	FF_EXTRA             = 0x800,      ///< Gets cut by ::FF_CUTEXTRA.
133 	FF_TRANSLUCENT       = 0x1000,     ///< See through!
134 	FF_FOG               = 0x2000,     ///< Fog "brush."
135 	FF_INVERTPLANES      = 0x4000,     ///< Only render inside planes.
136 	FF_ALLSIDES          = 0x8000,     ///< Render inside and outside sides.
137 	FF_INVERTSIDES       = 0x10000,    ///< Only render inside sides.
138 	FF_DOUBLESHADOW      = 0x20000,    ///< Make two lightlist entries to reset light?
139 	FF_FLOATBOB          = 0x40000,    ///< Floats on water and bobs if you step on it.
140 	FF_NORETURN          = 0x80000,    ///< Used with ::FF_CRUMBLE. Will not return to its original position after falling.
141 	FF_CRUMBLE           = 0x100000,   ///< Falls 2 seconds after being stepped on, and randomly brings all touching crumbling 3dfloors down with it, providing their master sectors share the same tag (allows crumble platforms above or below, to also exist).
142 	FF_SHATTERBOTTOM     = 0x200000,   ///< Used with ::FF_BUSTUP. Like FF_SHATTER, but only breaks from the bottom. Good for springing up through rubble.
143 	FF_MARIO             = 0x400000,   ///< Acts like a question block when hit from underneath. Goodie spawned at top is determined by master sector.
144 	FF_BUSTUP            = 0x800000,   ///< You can spin through/punch this block and it will crumble!
145 	FF_QUICKSAND         = 0x1000000,  ///< Quicksand!
146 	FF_PLATFORM          = 0x2000000,  ///< You can jump up through this to the top.
147 	FF_REVERSEPLATFORM   = 0x4000000,  ///< A fall-through floor in normal gravity, a platform in reverse gravity.
148 	FF_INTANGIBLEFLATS   = 0x6000000,  ///< Both flats are intangible, but the sides are still solid.
149 	FF_SHATTER           = 0x8000000,  ///< Used with ::FF_BUSTUP. Bustable on mere touch.
150 	FF_SPINBUST          = 0x10000000, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames.
151 	FF_STRONGBUST        = 0x20000000, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee).
152 	FF_RIPPLE            = 0x40000000, ///< Ripple the flats
153 	FF_COLORMAPONLY      = 0x80000000, ///< Only copy the colormap, not the lightlevel
154 	FF_GOOWATER          = FF_SHATTERBOTTOM, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
155 } ffloortype_e;
156 
157 typedef struct ffloor_s
158 {
159 	fixed_t *topheight;
160 	INT32 *toppic;
161 	INT16 *toplightlevel;
162 	fixed_t *topxoffs;
163 	fixed_t *topyoffs;
164 	angle_t *topangle;
165 
166 	fixed_t *bottomheight;
167 	INT32 *bottompic;
168 	fixed_t *bottomxoffs;
169 	fixed_t *bottomyoffs;
170 	angle_t *bottomangle;
171 
172 	// Pointers to pointers. Yup.
173 	struct pslope_s **t_slope;
174 	struct pslope_s **b_slope;
175 
176 	size_t secnum;
177 	ffloortype_e flags;
178 	struct line_s *master;
179 
180 	struct sector_s *target;
181 
182 	struct ffloor_s *next;
183 	struct ffloor_s *prev;
184 
185 	INT32 lastlight;
186 	INT32 alpha;
187 	tic_t norender; // for culling
188 
189 	// these are saved for netgames, so do not let Lua touch these!
190 	ffloortype_e spawnflags; // flags the 3D floor spawned with
191 	INT32 spawnalpha; // alpha the 3D floor spawned with
192 
193 	void *fadingdata; // fading FOF thinker
194 } ffloor_t;
195 
196 
197 // This struct holds information for shadows casted by 3D floors.
198 // This information is contained inside the sector_t and is used as the base
199 // information for casted shadows.
200 typedef struct lightlist_s
201 {
202 	fixed_t height;
203 	INT16 *lightlevel;
204 	extracolormap_t **extra_colormap; // pointer-to-a-pointer, so we can react to colormap changes
205 	INT32 flags;
206 	ffloor_t *caster;
207 	struct pslope_s *slope; // FF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh.
208 } lightlist_t;
209 
210 
211 // This struct is used for rendering walls with shadows casted on them...
212 typedef struct r_lightlist_s
213 {
214 	fixed_t height;
215 	fixed_t heightstep;
216 	fixed_t botheight;
217 	fixed_t botheightstep;
218 	fixed_t startheight; // for repeating midtextures
219 	INT16 lightlevel;
220 	extracolormap_t *extra_colormap;
221 	lighttable_t *rcolormap;
222 	ffloortype_e flags;
223 	INT32 lightnum;
224 } r_lightlist_t;
225 
226 // Slopes
227 typedef enum {
228 	SL_NOPHYSICS = 1, /// This plane will have no physics applied besides the positioning.
229 	SL_DYNAMIC = 1<<1, /// This plane slope will be assigned a thinker to make it dynamic.
230 } slopeflags_t;
231 
232 typedef struct pslope_s
233 {
234 	UINT16 id; // The number of the slope, mostly used for netgame syncing purposes
235 	struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later
236 
237 	// The plane's definition.
238 	vector3_t o;		/// Plane origin.
239 	vector3_t normal;	/// Plane normal.
240 
241 	vector2_t d;		/// Precomputed normalized projection of the normal over XY.
242 	fixed_t zdelta;		/// Precomputed Z unit increase per XY unit.
243 
244 	// This values only check and must be updated if the slope itself is modified
245 	angle_t zangle;		/// Precomputed angle of the plane going up from the ground (not measured in degrees).
246 	angle_t xydirection;/// Precomputed angle of the normal's projection on the XY plane.
247 
248 	UINT8 flags; // Slope options
249 } pslope_t;
250 
251 typedef enum
252 {
253 	// flipspecial - planes with effect
254 	SF_FLIPSPECIAL_FLOOR       =  1,
255 	SF_FLIPSPECIAL_CEILING     =  1<<1,
256 	SF_FLIPSPECIAL_BOTH        =  (SF_FLIPSPECIAL_FLOOR|SF_FLIPSPECIAL_CEILING),
257 	// triggerspecial - conditions under which plane touch causes effect
258 	SF_TRIGGERSPECIAL_TOUCH    =  1<<2,
259 	SF_TRIGGERSPECIAL_HEADBUMP =  1<<3,
260 	// invertprecip - inverts presence of precipitation
261 	SF_INVERTPRECIP            =  1<<4,
262 } sectorflags_t;
263 
264 
265 typedef enum
266 {
267 	CRUMBLE_NONE, // No crumble thinker
268 	CRUMBLE_WAIT, // Don't float on water because this is supposed to wait for a crumble
269 	CRUMBLE_ACTIVATED, // Crumble thinker activated, but hasn't fallen yet
270 	CRUMBLE_FALL, // Crumble thinker is falling
271 	CRUMBLE_RESTORE, // Crumble thinker is about to restore to original position
272 } crumblestate_t;
273 
274 //
275 // The SECTORS record, at runtime.
276 // Stores things/mobjs.
277 //
278 typedef struct sector_s
279 {
280 	fixed_t floorheight;
281 	fixed_t ceilingheight;
282 	INT32 floorpic;
283 	INT32 ceilingpic;
284 	INT16 lightlevel;
285 	INT16 special;
286 	taglist_t tags;
287 
288 	// origin for any sounds played by the sector
289 	// also considered the center for e.g. Mario blocks
290 	degenmobj_t soundorg;
291 
292 	// if == validcount, already checked
293 	size_t validcount;
294 
295 	// list of mobjs in sector
296 	mobj_t *thinglist;
297 
298 	// thinker_ts for reversable actions
299 	void *floordata; // floor move thinker
300 	void *ceilingdata; // ceiling move thinker
301 	void *lightingdata; // lighting change thinker
302 	void *fadecolormapdata; // fade colormap thinker
303 
304 	// floor and ceiling texture offsets
305 	fixed_t floor_xoffs, floor_yoffs;
306 	fixed_t ceiling_xoffs, ceiling_yoffs;
307 
308 	// flat angle
309 	angle_t floorpic_angle;
310 	angle_t ceilingpic_angle;
311 
312 	INT32 heightsec; // other sector, or -1 if no other sector
313 	INT32 camsec; // used for camera clipping
314 
315 	INT32 floorlightsec, ceilinglightsec;
316 	INT32 crumblestate; // used for crumbling and bobbing
317 
318 	// list of mobjs that are at least partially in the sector
319 	// thinglist is a subset of touching_thinglist
320 	struct msecnode_s *touching_thinglist;
321 
322 	size_t linecount;
323 	struct line_s **lines; // [linecount] size
324 
325 	// Improved fake floor hack
326 	ffloor_t *ffloors;
327 	size_t *attached;
328 	boolean *attachedsolid;
329 	size_t numattached;
330 	size_t maxattached;
331 	lightlist_t *lightlist;
332 	INT32 numlights;
333 	boolean moved;
334 
335 	// per-sector colormaps!
336 	extracolormap_t *extra_colormap;
337 	boolean colormap_protected;
338 
339 	// This points to the master's floorheight, so it can be changed in realtime!
340 	fixed_t *gravity; // per-sector gravity
341 	boolean verticalflip; // If gravity < 0, then allow flipped physics
342 	sectorflags_t flags;
343 
344 	// Sprite culling feature
345 	struct line_s *cullheight;
346 
347 	// Current speed of ceiling/floor. For Knuckles to hold onto stuff.
348 	fixed_t floorspeed, ceilspeed;
349 
350 	// list of precipitation mobjs in sector
351 	precipmobj_t *preciplist;
352 	struct mprecipsecnode_s *touching_preciplist;
353 
354 	// Eternity engine slope
355 	pslope_t *f_slope; // floor slope
356 	pslope_t *c_slope; // ceiling slope
357 	boolean hasslope; // The sector, or one of its visible FOFs, contains a slope
358 
359 	// for fade thinker
360 	INT16 spawn_lightlevel;
361 
362 	// colormap structure
363 	extracolormap_t *spawn_extra_colormap;
364 } sector_t;
365 
366 //
367 // Move clipping aid for linedefs.
368 //
369 typedef enum
370 {
371 	ST_HORIZONTAL,
372 	ST_VERTICAL,
373 	ST_POSITIVE,
374 	ST_NEGATIVE
375 } slopetype_t;
376 
377 #define HORIZONSPECIAL 41
378 
379 #define NUMLINEARGS 6
380 #define NUMLINESTRINGARGS 2
381 
382 typedef struct line_s
383 {
384 	// Vertices, from v1 to v2.
385 	vertex_t *v1;
386 	vertex_t *v2;
387 
388 	fixed_t dx, dy; // Precalculated v2 - v1 for side checking.
389 
390 	// Animation related.
391 	INT16 flags;
392 	INT16 special;
393 	taglist_t tags;
394 	INT32 args[NUMLINEARGS];
395 	char *stringargs[NUMLINESTRINGARGS];
396 
397 	// Visual appearance: sidedefs.
398 	UINT16 sidenum[2]; // sidenum[1] will be 0xffff if one-sided
399 	fixed_t alpha; // translucency
400 	INT32 executordelay;
401 
402 	fixed_t bbox[4]; // bounding box for the extent of the linedef
403 
404 	// To aid move clipping.
405 	slopetype_t slopetype;
406 
407 	// Front and back sector.
408 	// Note: redundant? Can be retrieved from SideDefs.
409 	sector_t *frontsector;
410 	sector_t *backsector;
411 
412 	size_t validcount; // if == validcount, already checked
413 	polyobj_t *polyobj; // Belongs to a polyobject?
414 
415 	char *text; // a concatenation of all front and back texture names, for linedef specials that require a string.
416 	INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
417 } line_t;
418 
419 typedef struct
420 {
421 	// add this to the calculated texture column
422 	fixed_t textureoffset;
423 
424 	// add this to the calculated texture top
425 	fixed_t rowoffset;
426 
427 	// Texture indices.
428 	// We do not maintain names here.
429 	INT32 toptexture, bottomtexture, midtexture;
430 
431 	// Linedef the sidedef belongs to
432 	line_t *line;
433 
434 	// Sector the sidedef is facing.
435 	sector_t *sector;
436 
437 	INT16 special; // the special of the linedef this side belongs to
438 	INT16 repeatcnt; // # of times to repeat midtexture
439 
440 	char *text; // a concatenation of all top, bottom, and mid texture names, for linedef specials that require a string.
441 
442 	extracolormap_t *colormap_data; // storage for colormaps; not applied to sectors.
443 } side_t;
444 
445 //
446 // A subsector.
447 // References a sector.
448 // Basically, this is a list of linesegs, indicating the visible walls that define
449 //  (all or some) sides of a convex BSP leaf.
450 //
451 typedef struct subsector_s
452 {
453 	sector_t *sector;
454 	INT16 numlines;
455 	UINT16 firstline;
456 	struct polyobj_s *polyList; // haleyjd 02/19/06: list of polyobjects
457 	size_t validcount;
458 } subsector_t;
459 
460 // Sector list node showing all sectors an object appears in.
461 //
462 // There are two threads that flow through these nodes. The first thread
463 // starts at touching_thinglist in a sector_t and flows through the m_thinglist_next
464 // links to find all mobjs that are entirely or partially in the sector.
465 // The second thread starts at touching_sectorlist in an mobj_t and flows
466 // through the m_sectorlist_next links to find all sectors a thing touches. This is
467 // useful when applying friction or push effects to sectors. These effects
468 // can be done as thinkers that act upon all objects touching their sectors.
469 // As an mobj moves through the world, these nodes are created and
470 // destroyed, with the links changed appropriately.
471 //
472 // For the links, NULL means top or end of list.
473 
474 typedef struct msecnode_s
475 {
476 	sector_t *m_sector; // a sector containing this object
477 	struct mobj_s *m_thing;  // this object
478 	struct msecnode_s *m_sectorlist_prev;  // prev msecnode_t for this thing
479 	struct msecnode_s *m_sectorlist_next;  // next msecnode_t for this thing
480 	struct msecnode_s *m_thinglist_prev;  // prev msecnode_t for this sector
481 	struct msecnode_s *m_thinglist_next;  // next msecnode_t for this sector
482 	boolean visited; // used in search algorithms
483 } msecnode_t;
484 
485 typedef struct mprecipsecnode_s
486 {
487 	sector_t *m_sector; // a sector containing this object
488 	struct precipmobj_s *m_thing;  // this object
489 	struct mprecipsecnode_s *m_sectorlist_prev;  // prev msecnode_t for this thing
490 	struct mprecipsecnode_s *m_sectorlist_next;  // next msecnode_t for this thing
491 	struct mprecipsecnode_s *m_thinglist_prev;  // prev msecnode_t for this sector
492 	struct mprecipsecnode_s *m_thinglist_next;  // next msecnode_t for this sector
493 	boolean visited; // used in search algorithms
494 } mprecipsecnode_t;
495 
496 // for now, only used in hardware mode
497 // maybe later for software as well?
498 // that's why it's moved here
499 typedef struct light_s
500 {
501 	UINT16 type;          // light,... (cfr #define in hwr_light.c)
502 
503 	float light_xoffset;
504 	float light_yoffset;  // y offset to adjust corona's height
505 
506 	UINT32 corona_color;   // color of the light for static lighting
507 	float corona_radius;  // radius of the coronas
508 
509 	UINT32 dynamic_color;  // color of the light for dynamic lighting
510 	float dynamic_radius; // radius of the light ball
511 	float dynamic_sqrradius; // radius^2 of the light ball
512 } light_t;
513 
514 typedef struct lightmap_s
515 {
516 	float s[2], t[2];
517 	light_t *light;
518 	struct lightmap_s *next;
519 } lightmap_t;
520 
521 //
522 // The lineseg.
523 //
524 typedef struct seg_s
525 {
526 	vertex_t *v1;
527 	vertex_t *v2;
528 
529 	INT32 side;
530 
531 	fixed_t offset;
532 
533 	angle_t angle;
534 
535 	side_t *sidedef;
536 	line_t *linedef;
537 
538 	// Sector references.
539 	// Could be retrieved from linedef, too. backsector is NULL for one sided lines
540 	sector_t *frontsector;
541 	sector_t *backsector;
542 
543 	fixed_t length;	// precalculated seg length
544 #ifdef HWRENDER
545 	// new pointers so that AdjustSegs doesn't mess with v1/v2
546 	void *pv1; // polyvertex_t
547 	void *pv2; // polyvertex_t
548 	float flength; // length of the seg, used by hardware renderer
549 
550 	lightmap_t *lightmaps; // for static lightmap
551 #endif
552 
553 	// Why slow things down by calculating lightlists for every thick side?
554 	size_t numlights;
555 	r_lightlist_t *rlights;
556 	polyobj_t *polyseg;
557 	boolean dontrenderme;
558 	boolean glseg;
559 } seg_t;
560 
561 //
562 // BSP node.
563 //
564 typedef struct
565 {
566 	// Partition line.
567 	fixed_t x, y;
568 	fixed_t dx, dy;
569 
570 	// Bounding box for each child.
571 	fixed_t bbox[2][4];
572 
573 	// If NF_SUBSECTOR its a subsector.
574 	UINT16 children[2];
575 } node_t;
576 
577 #if defined(_MSC_VER)
578 #pragma pack(1)
579 #endif
580 
581 // posts are runs of non masked source pixels
582 typedef struct
583 {
584 	UINT8 topdelta; // -1 is the last post in a column
585 	UINT8 length;   // length data bytes follows
586 } ATTRPACK post_t;
587 
588 #if defined(_MSC_VER)
589 #pragma pack()
590 #endif
591 
592 // column_t is a list of 0 or more post_t, (UINT8)-1 terminated
593 typedef post_t column_t;
594 
595 //
596 // OTHER TYPES
597 //
598 
599 #ifndef MAXFFLOORS
600 #define MAXFFLOORS 40
601 #endif
602 
603 //
604 // ?
605 //
606 typedef struct drawseg_s
607 {
608 	seg_t *curline;
609 	INT32 x1;
610 	INT32 x2;
611 
612 	fixed_t scale1;
613 	fixed_t scale2;
614 	fixed_t scalestep;
615 
616 	INT32 silhouette; // 0 = none, 1 = bottom, 2 = top, 3 = both
617 
618 	fixed_t bsilheight; // do not clip sprites above this
619 	fixed_t tsilheight; // do not clip sprites below this
620 
621 	// Pointers to lists for sprite clipping, all three adjusted so [x1] is first value.
622 	INT16 *sprtopclip;
623 	INT16 *sprbottomclip;
624 	INT16 *maskedtexturecol;
625 
626 	struct visplane_s *ffloorplanes[MAXFFLOORS];
627 	INT32 numffloorplanes;
628 	struct ffloor_s *thicksides[MAXFFLOORS];
629 	INT16 *thicksidecol;
630 	INT32 numthicksides;
631 	fixed_t frontscale[MAXVIDWIDTH];
632 
633 	UINT8 portalpass; // if > 0 and <= portalrender, do not affect sprite clipping
634 
635 	fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures
636 
637 	vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes
638 } drawseg_t;
639 
640 typedef enum
641 {
642 	PALETTE         = 0,  // 1 byte is the index in the doom palette (as usual)
643 	INTENSITY       = 1,  // 1 byte intensity
644 	INTENSITY_ALPHA = 2,  // 2 byte: alpha then intensity
645 	RGB24           = 3,  // 24 bit rgb
646 	RGBA32          = 4,  // 32 bit rgba
647 } pic_mode_t;
648 
649 #ifdef ROTSPRITE
650 typedef struct
651 {
652 	INT32 angles;
653 	void **patches;
654 } rotsprite_t;
655 #endif
656 
657 // Patches.
658 // A patch holds one or more columns.
659 // Patches are used for sprites and all masked pictures, and we compose
660 // textures from the TEXTURES list of patches.
661 //
662 typedef struct
663 {
664 	INT16 width, height;
665 	INT16 leftoffset, topoffset;
666 
667 	INT32 *columnofs; // Column offsets. This is relative to patch->columns
668 	UINT8 *columns; // Software column data
669 
670 	void *hardware; // OpenGL patch, allocated whenever necessary
671 	void *flats[4]; // The patch as flats
672 
673 #ifdef ROTSPRITE
674 	rotsprite_t *rotated; // Rotated patches
675 #endif
676 } patch_t;
677 
678 #if defined(_MSC_VER)
679 #pragma pack(1)
680 #endif
681 
682 typedef struct
683 {
684 	INT16 width;          // bounding box size
685 	INT16 height;
686 	INT16 leftoffset;     // pixels to the left of origin
687 	INT16 topoffset;      // pixels below the origin
688 	INT32 columnofs[8];     // only [width] used
689 	// the [0] is &columnofs[width]
690 } ATTRPACK softwarepatch_t;
691 
692 #ifdef _MSC_VER
693 #pragma warning(disable :  4200)
694 #endif
695 
696 // a pic is an unmasked block of pixels, stored in horizontal way
697 typedef struct
698 {
699 	INT16 width;
700 	UINT8 zero;       // set to 0 allow autodetection of pic_t
701 	                 // mode instead of patch or raw
702 	UINT8 mode;       // see pic_mode_t above
703 	INT16 height;
704 	INT16 reserved1; // set to 0
705 	UINT8 data[0];
706 } ATTRPACK pic_t;
707 
708 #ifdef _MSC_VER
709 #pragma warning(default : 4200)
710 #endif
711 
712 #if defined(_MSC_VER)
713 #pragma pack()
714 #endif
715 
716 typedef enum
717 {
718 	RF_HORIZONTALFLIP   = 0x0001,   // Flip sprite horizontally
719 	RF_VERTICALFLIP     = 0x0002,   // Flip sprite vertically
720 	RF_ABSOLUTEOFFSETS  = 0x0004,   // Sprite uses the object's offsets absolutely, instead of relatively
721 	RF_FLIPOFFSETS      = 0x0008,   // Relative object offsets are flipped with the sprite
722 
723 	RF_SPLATMASK        = 0x00F0,   // --Floor sprite flags
724 	RF_SLOPESPLAT       = 0x0010,   // Rotate floor sprites by a slope
725 	RF_OBJECTSLOPESPLAT = 0x0020,   // Rotate floor sprites by the object's standing slope
726 	RF_NOSPLATBILLBOARD = 0x0040,   // Don't billboard floor sprites (faces forward from the view angle)
727 	RF_NOSPLATROLLANGLE = 0x0080,   // Don't rotate floor sprites by the object's rollangle (uses rotated patches instead)
728 
729 	RF_BLENDMASK        = 0x0F00,   // --Blending modes
730 	RF_FULLBRIGHT       = 0x0100,   // Sprite is drawn at full brightness
731 	RF_FULLDARK         = 0x0200,   // Sprite is drawn completely dark
732 	RF_NOCOLORMAPS      = 0x0400,   // Sprite is not drawn with colormaps
733 
734 	RF_SPRITETYPEMASK   = 0x7000,   // ---Different sprite types
735 	RF_PAPERSPRITE      = 0x1000,   // Paper sprite
736 	RF_FLOORSPRITE      = 0x2000,   // Floor sprite
737 
738 	RF_SHADOWDRAW       = 0x10000,  // Stretches and skews the sprite like a shadow.
739 	RF_SHADOWEFFECTS    = 0x20000,  // Scales and becomes transparent like a shadow.
740 	RF_DROPSHADOW       = (RF_SHADOWDRAW | RF_SHADOWEFFECTS | RF_FULLDARK),
741 } renderflags_t;
742 
743 typedef enum
744 {
745 	SRF_SINGLE      = 0,   // 0-angle for all rotations
746 	SRF_3D          = 1,   // Angles 1-8
747 	SRF_3DGE        = 2,   // 3DGE, ZDoom and Doom Legacy all have 16-angle support. Why not us?
748 	SRF_3DMASK      = SRF_3D|SRF_3DGE, // 3
749 	SRF_LEFT        = 4,   // Left side uses single patch
750 	SRF_RIGHT       = 8,   // Right side uses single patch
751 	SRF_2D          = SRF_LEFT|SRF_RIGHT, // 12
752 	SRF_NONE        = 0xff // Initial value
753 } spriterotateflags_t;     // SRF's up!
754 
755 //
756 // Sprites are patches with a special naming convention so they can be
757 //  recognized by R_InitSprites.
758 // The base name is NNNNFx or NNNNFxFx, with x indicating the rotation,
759 //  x = 0, 1-8, 9+A-G, L/R
760 // The sprite and frame specified by a thing_t is range checked at run time.
761 // A sprite is a patch_t that is assumed to represent a three dimensional
762 //  object and may have multiple rotations predrawn.
763 // Horizontal flipping is used to save space, thus NNNNF2F5 defines a mirrored patch.
764 // Some sprites will only have one picture used for all views: NNNNF0
765 // Some sprites will take the entirety of the left side: NNNNFL
766 // Or the right side: NNNNFR
767 // Or both, mirrored: NNNNFLFR
768 //
769 typedef struct
770 {
771 	// If false use 0 for any position.
772 	// Note: as eight entries are available, we might as well insert the same
773 	//  name eight times.
774 	UINT8 rotate; // see spriterotateflags_t above
775 
776 	// Lump to use for view angles 0-7/15.
777 	lumpnum_t lumppat[16]; // lump number 16 : 16 wad : lump
778 	size_t lumpid[16]; // id in the spriteoffset, spritewidth, etc. tables
779 
780 	// Flip bits (1 = flip) to use for view angles 0-7/15.
781 	UINT16 flip;
782 
783 #ifdef ROTSPRITE
784 	rotsprite_t *rotated[2][16]; // Rotated patches
785 #endif
786 } spriteframe_t;
787 
788 //
789 // A sprite definition:  a number of animation frames.
790 //
791 typedef struct
792 {
793 	size_t numframes;
794 	spriteframe_t *spriteframes;
795 } spritedef_t;
796 
797 #endif
798