1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
|
/*
Copyright (C) 1997-2001 Id Software, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "shared/shared.h"
#include "common/bsp.h"
#include "common/cmd.h"
#include "common/common.h"
#include "common/cvar.h"
#include "common/files.h"
#include "common/math.h"
#include "client/client.h"
#include "client/video.h"
#include "refresh/refresh.h"
#include "refresh/images.h"
#include "refresh/models.h"
#include "system/system.h"
#define REF_VERSION "SOFT 0.01"
/*
====================================================
CONSTANTS
====================================================
*/
#define DSURF_SKY 2
#define DSURF_TURB 4
#define DSURF_BACKGROUND 8
#define CACHE_SIZE 32
#define VID_BYTES 4 // can be 4 or 3
#define TEX_BYTES 4 // must be 4
#define MAXVERTS 64 // max points in a surface polygon
#define MAXWORKINGVERTS (MAXVERTS + 4) // max points in an intermediate
// polygon (while processing)
#define MAXHEIGHT 1200
#define MAXWIDTH 1600
#define INFINITE_DISTANCE 0x10000 // distance that's always guaranteed to
// be farther away than anything in
// the scene
#define WARP_WIDTH 320
#define WARP_HEIGHT 240
#define PARTICLE_Z_CLIP 8.0
#define TRANSPARENT_COLOR 0xFF
#define TURB_SIZE 64 // base turbulent texture size
#define TURB_MASK (TURB_SIZE - 1)
#define CYCLE 128 // turbulent cycle size
#define DS_SPAN_LIST_END -128
#define NUMSTACKEDGES 3000
#define MINEDGES NUMSTACKEDGES
#define MAXEDGES 30000
#define NUMSTACKSURFACES 1000
#define MINSURFACES NUMSTACKSURFACES
#define MAXSURFACES 10000
#define MAXSPANS 3000
// flags in finalvert_t.flags
#define ALIAS_LEFT_CLIP 0x0001
#define ALIAS_TOP_CLIP 0x0002
#define ALIAS_RIGHT_CLIP 0x0004
#define ALIAS_BOTTOM_CLIP 0x0008
#define ALIAS_Z_CLIP 0x0010
#define ALIAS_XY_CLIP_MASK 0x000F
#define SURFCACHE_SIZE_AT_320X240 1024*768
#define BMODEL_FULLY_CLIPPED 0x10 // value returned by R_BmodelCheckBBox ()
// if bbox is trivially rejected
#define CLIP_EPSILON 0.001
#define BACKFACE_EPSILON 0.01
#define NEAR_CLIP 0.01
#define ALIAS_Z_CLIP_PLANE 4
// turbulence stuff
#define AMP 8*0x10000
#define AMP2 3
#define SPEED 20
/*
====================================================
TYPES
====================================================
*/
typedef unsigned char pixel_t;
typedef struct {
pixel_t *buffer; // invisible buffer
int rowbytes; // may be > width if displayed in a window
// can be negative for stupid dibs
int width;
int height;
} viddef_t;
typedef struct {
vrect_t vrect; // subwindow in video for refresh
int vrectright, vrectbottom; // right & bottom screen coords
float vrectrightedge; // rightmost right edge we care about,
// for use in edge list
float fvrectx, fvrecty; // for floating-point compares
float fvrectx_adj, fvrecty_adj; // left and top edges, for clamping
int vrect_x_adj_shift20; // (vrect.x + 0.5 - epsilon) << 20
int vrectright_adj_shift20; // (vrectright + 0.5 - epsilon) << 20
float fvrectright_adj, fvrectbottom_adj; // right and bottom edges, for clamping
float fvrectright; // rightmost edge, for Alias clamping
float fvrectbottom; // bottommost edge, for Alias clamping
// values for perspective projection
float xcenter, ycenter;
float xscale, yscale;
float xscaleinv, yscaleinv;
float xscaleshrink, yscaleshrink;
float scale_for_mip;
// particle values
int vrectright_particle, vrectbottom_particle;
int pix_min, pix_max, pix_shift;
} oldrefdef_t;
typedef struct {
float u, v;
float s, t;
float zi;
} emitpoint_t;
typedef struct finalvert_s {
int u, v, s, t;
int l;
int zi;
int flags;
float xyz[3]; // eye space
} finalvert_t;
typedef struct {
void *pskin;
int skinwidth;
int skinheight;
} affinetridesc_t;
typedef struct drawsurf_s {
byte *surfdat; // destination for generated surface
int rowbytes; // destination logical width in bytes
mface_t *surf; // description for surface to generate
fixed8_t lightadj[MAX_LIGHTMAPS]; // adjust for lightmap levels for dynamic lighting
image_t *image;
int surfmip; // mipmapped ratio of surface texels / world pixels
int surfwidth; // in mipmapped texels
int surfheight; // in mipmapped texels
} drawsurf_t;
// clipped bmodel edges
typedef struct bedge_s {
mvertex_t *v[2];
struct bedge_s *pnext;
} bedge_t;
typedef struct clipplane_s {
vec3_t normal;
float dist;
struct clipplane_s *next;
byte leftedge;
byte rightedge;
byte reserved[2];
} clipplane_t;
#define MAX_BLOCKLIGHTS 1024
#define LIGHTMAP_BYTES 3
typedef int blocklight_t;
typedef struct surfcache_s {
struct surfcache_s *next;
struct surfcache_s **owner; // NULL is an empty chunk of memory
int lightadj[MAX_LIGHTMAPS]; // checked for strobe flush
int dlight;
int size; // including header
unsigned width;
unsigned height; // DEBUG only needed for debug
float mipscale;
image_t *image;
byte data[4]; // width*height elements
} surfcache_t;
typedef struct espan_s {
int u, v, count;
struct espan_s *pnext;
} espan_t;
// used by the polygon drawer (R_POLY.C) and sprite setup code (R_SPRITE.C)
typedef struct {
int nump;
emitpoint_t *pverts;
byte *pixels; // image
int pixel_width; // image width
int pixel_height; // image height
vec3_t vup, vright, vpn; // in worldspace, for plane eq
float dist;
float s_offset, t_offset;
float viewer_position[3];
void (*drawspanlet)(void);
int alpha;
int one_minus_alpha;
} polydesc_t;
// FIXME: compress, make a union if that will help
// insubmodel is only 1, flags is fewer than 32, spanstate could be a byte
typedef struct surf_s {
struct surf_s *next; // active surface stack in r_edge.c
struct surf_s *prev; // used in r_edge.c for active surf stack
struct espan_s *spans; // pointer to linked list of spans to draw
int key; // sorting key (BSP order)
int last_u; // set during tracing
int spanstate; // 0 = not in span
// 1 = in span
// -1 = in inverted span (end before start)
int flags; // currentface flags
mface_t *msurf;
entity_t *entity;
float nearzi; // nearest 1/z on surface, for mipmapping
qboolean insubmodel;
float d_ziorigin, d_zistepu, d_zistepv;
} surf_t;
typedef struct edge_s {
fixed16_t u;
fixed16_t u_step;
struct edge_s *prev, *next;
uint16_t surfs[2];
struct edge_s *nextremove;
float nearzi;
medge_t *owner;
} edge_t;
typedef struct maliasst_s {
signed short s;
signed short t;
} maliasst_t;
typedef struct maliastri_s {
unsigned short index_xyz[3];
unsigned short index_st[3];
} maliastri_t;
typedef struct maliasvert_s {
uint8_t v[3];
uint8_t lightnormalindex;
} maliasvert_t;
typedef struct maliasframe_s {
vec3_t scale;
vec3_t translate;
vec3_t bounds[2];
vec_t radius;
maliasvert_t *verts;
} maliasframe_t;
typedef struct {
finalvert_t *a, *b, *c;
} aliastriangleparms_t;
/*
====================================================
VARS
====================================================
*/
extern int r_framecount; // sequence # of current frame since Quake started
extern qboolean r_dowarp;
extern affinetridesc_t r_affinetridesc;
void D_DrawSurfaces(void);
void D_WarpScreen(void);
//=======================================================================//
extern drawsurf_t r_drawsurf;
extern int c_surf;
extern byte r_warpbuffer[WARP_WIDTH * WARP_HEIGHT * VID_BYTES];
extern float d_sdivzstepu, d_tdivzstepu, d_zistepu;
extern float d_sdivzstepv, d_tdivzstepv, d_zistepv;
extern float d_sdivzorigin, d_tdivzorigin, d_ziorigin;
extern fixed16_t sadjust, tadjust;
extern fixed16_t bbextents, bbextentt;
void D_DrawTurbulent16(espan_t *pspan, int *warptable);
void D_DrawSpans16(espan_t *pspans);
void D_DrawZSpans(espan_t *pspans);
surfcache_t *D_CacheSurface(mface_t *surface, int miplevel);
extern pixel_t *d_viewbuffer;
extern int d_screenrowbytes;
extern short *d_pzbuffer;
extern int d_zrowbytes;
extern int d_zwidth;
extern byte *d_spantable[MAXHEIGHT];
extern short *d_zspantable[MAXHEIGHT];
extern int d_minmip;
extern float d_scalemip[3];
extern viddef_t vid;
extern oldrefdef_t r_refdef;
//===================================================================
extern int cachewidth;
extern pixel_t *cacheblock;
extern int r_drawnpolycount;
extern int sintable[CYCLE * 2];
extern int intsintable[CYCLE * 2];
extern int blanktable[CYCLE * 2];
extern vec3_t vup, base_vup;
extern vec3_t vpn, base_vpn;
extern vec3_t vright, base_vright;
extern surf_t *auxsurfaces;
extern surf_t *surfaces, *surface_p, *surf_max;
// surfaces are generated in back to front order by the bsp, so if a surf
// pointer is greater than another one, it should be drawn in front
// surfaces[1] is the background, and is used as the active surface stack.
// surfaces[0] is a dummy, because index 0 is used to indicate no surface
// attached to an edge_t
//===================================================================
extern vec3_t sxformaxis[4]; // s axis transformed into viewspace
extern vec3_t txformaxis[4]; // t axis transformed into viewspac
extern void R_TransformVector(vec3_t in, vec3_t out);
//===========================================================================
extern cvar_t *sw_aliasstats;
extern cvar_t *sw_clearcolor;
extern cvar_t *sw_drawflat;
extern cvar_t *sw_draworder;
extern cvar_t *sw_maxedges;
extern cvar_t *sw_maxsurfs;
extern cvar_t *sw_mipcap;
extern cvar_t *sw_mipscale;
extern cvar_t *sw_mode;
extern cvar_t *sw_reportsurfout;
extern cvar_t *sw_reportedgeout;
extern cvar_t *sw_surfcacheoverride;
extern cvar_t *sw_waterwarp;
extern cvar_t *sw_drawsird;
extern cvar_t *sw_dynamic;
extern cvar_t *sw_modulate;
extern cvar_t *r_fullbright;
extern cvar_t *r_drawentities;
extern cvar_t *r_drawworld;
extern cvar_t *r_lerpmodels;
extern cvar_t *r_speeds;
extern cvar_t *vid_fullscreen;
extern cvar_t *vid_gamma;
extern clipplane_t view_clipplanes[4];
extern int *pfrustum_indexes[4];
//=============================================================================
void R_RenderWorld(void);
//=============================================================================
extern cplane_t screenedge[4];
extern vec3_t r_origin;
extern entity_t r_worldentity;
extern model_t *currentmodel;
extern entity_t *currententity;
extern vec3_t modelorg;
extern vec3_t r_entorigin;
extern vec3_t entity_rotation[3];
extern int r_visframecount;
extern mface_t *r_alpha_surfaces;
//=============================================================================
//
// current entity info
//
extern qboolean insubmodel;
void R_DrawAlphaSurfaces(void);
void R_DrawSprite(void);
void R_DrawBeam(entity_t *e);
void R_RenderFace(mface_t *fa, int clipflags);
void R_RenderBmodelFace(bedge_t *pedges, mface_t *psurf);
void R_TransformPlane(cplane_t *p, float *normal, float *dist);
void R_TransformFrustum(void);
void R_DrawSubmodelPolygons(mmodel_t *pmodel, int clipflags, mnode_t *topnode);
void R_DrawSolidClippedSubmodelPolygons(mmodel_t *pmodel, mnode_t *topnode);
void R_AliasDrawModel(void);
void R_BeginEdgeFrame(void);
void R_ScanEdges(void);
void R_MarkLights(mnode_t *headnode);
void R_RotateBmodel(void);
extern int c_faceclip;
extern int r_polycount;
extern int r_wholepolycount;
extern fixed16_t sadjust, tadjust;
extern fixed16_t bbextents, bbextentt;
extern mvertex_t *r_ptverts, *r_ptvertsmax;
extern int r_currentkey;
extern int r_currentbkey;
void R_DrawParticles(void);
extern int r_amodels_drawn;
extern edge_t *auxedges;
extern int r_numallocatededges;
extern edge_t *r_edges, *edge_p, *edge_max;
extern edge_t *newedges[MAXHEIGHT];
extern edge_t *removeedges[MAXHEIGHT];
extern fixed8_t r_aliasblendcolor[3];
extern int r_alias_alpha;
extern int r_alias_one_minus_alpha;
extern int r_outofsurfaces;
extern int r_outofedges;
extern int r_maxvalidedgeoffset;
extern aliastriangleparms_t aliastriangleparms;
void R_DrawTriangle(void);
void R_AliasClipTriangle(finalvert_t *index0, finalvert_t *index1, finalvert_t *index2);
void R_AliasProjectAndClipTestFinalVert(finalvert_t *fv);
extern float r_time1;
extern int r_frustum_indexes[4 * 6];
extern int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs;
extern qboolean r_surfsonstack;
extern mleaf_t *r_viewleaf;
extern int r_viewcluster, r_oldviewcluster;
extern int r_clipflags;
extern int r_dlightframecount;
extern bsp_t *r_worldmodel;
extern blocklight_t blocklights[MAX_BLOCKLIGHTS * LIGHTMAP_BYTES]; // allow some very large lightmaps
void R_PrintAliasStats(void);
void R_PrintTimes(void);
void R_LightPoint(vec3_t p, vec3_t color);
void R_SetupFrame(void);
void R_BuildLightMap(void);
extern refdef_t r_newrefdef;
//====================================================================
void R_NewMap(void);
void R_InitCaches(void);
void R_FreeCaches(void);
void D_FlushCaches(void);
void D_SCDump_f(void);
void R_InitTurb(void);
void R_InitImages(void);
void R_ShutdownImages(void);
void R_BuildGammaTable(void);
void R_InitSkyBox(void);
void R_EmitSkyBox(void);
void R_ApplySIRDAlgorithum(void);
void R_IMFlatShadedQuad(vec3_t a, vec3_t b, vec3_t c, vec3_t d, color_t color, float alpha);
void R_InitDraw(void);
|