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_things.h
12 /// \brief Rendering of moving objects, sprites
13 
14 #ifndef __R_THINGS__
15 #define __R_THINGS__
16 
17 #include "r_plane.h"
18 #include "r_patch.h"
19 #include "r_picformats.h"
20 #include "r_portal.h"
21 #include "r_defs.h"
22 #include "r_skins.h"
23 
24 // --------------
25 // SPRITE LOADING
26 // --------------
27 
28 #define FEETADJUST (4<<FRACBITS) // R_AddSingleSpriteDef
29 
30 boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 wadnum, UINT16 startlump, UINT16 endlump);
31 
32 //faB: find sprites in wadfile, replace existing, add new ones
33 //     (only sprites from namelist are added or replaced)
34 void R_AddSpriteDefs(UINT16 wadnum);
35 
36 // ---------------------
37 // MASKED COLUMN DRAWING
38 // ---------------------
39 
40 // vars for R_DrawMaskedColumn
41 extern INT16 *mfloorclip;
42 extern INT16 *mceilingclip;
43 extern fixed_t spryscale;
44 extern fixed_t sprtopscreen;
45 extern fixed_t sprbotscreen;
46 extern fixed_t windowtop;
47 extern fixed_t windowbottom;
48 extern INT32 lengthcol;
49 
50 void R_DrawMaskedColumn(column_t *column);
51 void R_DrawFlippedMaskedColumn(column_t *column);
52 
53 // ----------------
54 // SPRITE RENDERING
55 // ----------------
56 
57 // Constant arrays used for psprite clipping
58 //  and initializing clipping.
59 extern INT16 negonearray[MAXVIDWIDTH];
60 extern INT16 screenheightarray[MAXVIDWIDTH];
61 
62 fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
63 
64 //SoM: 6/5/2000: Light sprites correctly!
65 void R_AddSprites(sector_t *sec, INT32 lightlevel);
66 void R_InitSprites(void);
67 void R_ClearSprites(void);
68 
69 boolean R_ThingVisible (mobj_t *thing);
70 
71 boolean R_ThingVisibleWithinDist (mobj_t *thing,
72 		fixed_t        draw_dist,
73 		fixed_t nights_draw_dist);
74 
75 boolean R_PrecipThingVisible (precipmobj_t *precipthing,
76 		fixed_t precip_draw_dist);
77 
78 boolean R_ThingHorizontallyFlipped (mobj_t *thing);
79 boolean R_ThingVerticallyFlipped (mobj_t *thing);
80 
81 boolean R_ThingIsPaperSprite (mobj_t *thing);
82 boolean R_ThingIsFloorSprite (mobj_t *thing);
83 
84 boolean R_ThingIsFullBright (mobj_t *thing);
85 boolean R_ThingIsFullDark (mobj_t *thing);
86 
87 // --------------
88 // MASKED DRAWING
89 // --------------
90 /** Used to count the amount of masked elements
91  * per portal to later group them in separate
92  * drawnode lists.
93  */
94 typedef struct
95 {
96 	size_t drawsegs[2];
97 	size_t vissprites[2];
98 	fixed_t viewx, viewy, viewz;			/**< View z stored at the time of the BSP traversal for the view/portal. Masked sorting/drawing needs it. */
99 	sector_t* viewsector;
100 } maskcount_t;
101 
102 void R_DrawMasked(maskcount_t* masks, UINT8 nummasks);
103 
104 // ----------
105 // VISSPRITES
106 // ----------
107 
108 // number of sprite lumps for spritewidth,offset,topoffset lookup tables
109 // Fab: this is a hack : should allocate the lookup tables per sprite
110 #define MAXVISSPRITES 2048 // added 2-2-98 was 128
111 
112 #define VISSPRITECHUNKBITS 6	// 2^6 = 64 sprites per chunk
113 #define VISSPRITESPERCHUNK (1 << VISSPRITECHUNKBITS)
114 #define VISSPRITEINDEXMASK (VISSPRITESPERCHUNK - 1)
115 
116 typedef enum
117 {
118 	// actual cuts
119 	SC_NONE       = 0,
120 	SC_TOP        = 1,
121 	SC_BOTTOM     = 1<<1,
122 	// other flags
123 	SC_PRECIP     = 1<<2,
124 	SC_LINKDRAW   = 1<<3,
125 	SC_FULLBRIGHT = 1<<4,
126 	SC_FULLDARK   = 1<<5,
127 	SC_VFLIP      = 1<<6,
128 	SC_ISSCALED   = 1<<7,
129 	SC_ISROTATED  = 1<<8,
130 	SC_SHADOW     = 1<<9,
131 	SC_SHEAR      = 1<<10,
132 	SC_SPLAT      = 1<<11,
133 	// masks
134 	SC_CUTMASK    = SC_TOP|SC_BOTTOM,
135 	SC_FLAGMASK   = ~SC_CUTMASK
136 } spritecut_e;
137 
138 // A vissprite_t is a thing that will be drawn during a refresh,
139 // i.e. a sprite object that is partly visible.
140 typedef struct vissprite_s
141 {
142 	// Doubly linked list.
143 	struct vissprite_s *prev;
144 	struct vissprite_s *next;
145 
146 	// Bonus linkdraw pointer.
147 	struct vissprite_s *linkdraw;
148 
149 	mobj_t *mobj; // for easy access
150 
151 	INT32 x1, x2;
152 
153 	fixed_t gx, gy; // for line side calculation
154 	fixed_t gz, gzt; // global bottom/top for silhouette clipping
155 	fixed_t pz, pzt; // physical bottom/top for sorting with 3D floors
156 
157 	fixed_t startfrac; // horizontal position of x1
158 	fixed_t xscale, scale; // projected horizontal and vertical scales
159 	fixed_t thingscale; // the object's scale
160 	fixed_t sortscale; // sortscale only differs from scale for paper sprites, floor sprites, and MF2_LINKDRAW
161 	fixed_t sortsplat; // the sortscale from behind the floor sprite
162 	fixed_t scalestep; // only for paper sprites, 0 otherwise
163 	fixed_t paperoffset, paperdistance; // for paper sprites, offset/dist relative to the angle
164 	fixed_t xiscale; // negative if flipped
165 
166 	angle_t centerangle; // for paper sprites
167 	angle_t viewangle; // for floor sprites, the viewpoint's current angle
168 
169 	struct {
170 		fixed_t tan; // The amount to shear the sprite vertically per row
171 		INT32 offset; // The center of the shearing location offset from x1
172 	} shear;
173 
174 	fixed_t texturemid;
175 	patch_t *patch;
176 
177 	lighttable_t *colormap; // for color translation and shadow draw
178 	                        // maxbright frames as well
179 
180 	UINT8 *transmap; // for MF2_SHADOW sprites, which translucency table to use
181 
182 	INT32 mobjflags;
183 
184 	INT32 heightsec; // height sector for underwater/fake ceiling support
185 
186 	extracolormap_t *extra_colormap; // global colormaps
187 
188 	// Precalculated top and bottom screen coords for the sprite.
189 	fixed_t thingheight; // The actual height of the thing (for 3D floors)
190 	sector_t *sector; // The sector containing the thing.
191 	INT16 sz, szt;
192 
193 	spritecut_e cut;
194 	UINT32 renderflags;
195 	UINT8 rotateflags;
196 
197 	fixed_t spritexscale, spriteyscale;
198 	fixed_t spritexoffset, spriteyoffset;
199 
200 	fixed_t shadowscale;
201 
202 	INT16 clipbot[MAXVIDWIDTH], cliptop[MAXVIDWIDTH];
203 
204 	INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
205 } vissprite_t;
206 
207 extern UINT32 visspritecount;
208 
209 void R_ClipSprites(drawseg_t* dsstart, portal_t* portal);
210 void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal);
211 
212 boolean R_SpriteIsFlashing(vissprite_t *vis);
213 UINT8 *R_GetSpriteTranslation(vissprite_t *vis);
214 
215 // ----------
216 // DRAW NODES
217 // ----------
218 
219 // A drawnode is something that points to a 3D floor, 3D side, or masked
220 // middle texture. This is used for sorting with sprites.
221 typedef struct drawnode_s
222 {
223 	visplane_t *plane;
224 	drawseg_t *seg;
225 	drawseg_t *thickseg;
226 	ffloor_t *ffloor;
227 	vissprite_t *sprite;
228 
229 	struct drawnode_s *next;
230 	struct drawnode_s *prev;
231 } drawnode_t;
232 
233 void R_InitDrawNodes(void);
234 
235 // -----------------------
236 // SPRITE FRAME CHARACTERS
237 // -----------------------
238 
239 // Functions to go from sprite character ID to frame number
240 // for 2.1 compatibility this still uses the old 'A' + frame code
241 // The use of symbols tends to be painful for wad editors though
242 // So the future version of this tries to avoid using symbols
243 // as much as possible while also defining all 64 slots in a sane manner
244 // 2.1:    [[ ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~   ]]
245 // Future: [[ ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!@ ]]
R_Frame2Char(UINT8 frame)246 FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame)
247 {
248 #if 0 // 2.1 compat
249 	return 'A' + frame;
250 #else
251 	if (frame < 26) return 'A' + frame;
252 	if (frame < 36) return '0' + (frame - 26);
253 	if (frame < 62) return 'a' + (frame - 36);
254 	if (frame == 62) return '!';
255 	if (frame == 63) return '@';
256 	return '\xFF';
257 #endif
258 }
259 
R_Char2Frame(char cn)260 FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn)
261 {
262 #if 0 // 2.1 compat
263 	if (cn == '+') return '\\' - 'A'; // PK3 can't use backslash, so use + instead
264 	return cn - 'A';
265 #else
266 	if (cn >= 'A' && cn <= 'Z') return (cn - 'A');
267 	if (cn >= '0' && cn <= '9') return (cn - '0') + 26;
268 	if (cn >= 'a' && cn <= 'z') return (cn - 'a') + 36;
269 	if (cn == '!') return 62;
270 	if (cn == '@') return 63;
271 	return 255;
272 #endif
273 }
274 
275 // "Left" and "Right" character symbols for additional rotation functionality
276 #define ROT_L 17
277 #define ROT_R 18
278 
R_Rotation2Char(UINT8 rot)279 FUNCMATH FUNCINLINE static ATTRINLINE char R_Rotation2Char(UINT8 rot)
280 {
281 	if (rot <=     9) return '0' + rot;
282 	if (rot <=    16) return 'A' + (rot - 10);
283 	if (rot == ROT_L) return 'L';
284 	if (rot == ROT_R) return 'R';
285 	return '\xFF';
286 }
287 
R_Char2Rotation(char cn)288 FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Rotation(char cn)
289 {
290 	if (cn >= '0' && cn <= '9') return (cn - '0');
291 	if (cn >= 'A' && cn <= 'G') return (cn - 'A') + 10;
292 	if (cn == 'L') return ROT_L;
293 	if (cn == 'R') return ROT_R;
294 	return 255;
295 }
296 
297 #endif //__R_THINGS__
298