summaryrefslogtreecommitdiff
path: root/src/refresh/sw/sw.h
blob: d00681a308f70b93bf0c8f2690d3efd128aff025 (plain)
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);