summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/quake/r_surf.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sdl/progs/quake/r_surf.c')
-rw-r--r--apps/plugins/sdl/progs/quake/r_surf.c678
1 files changed, 678 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/quake/r_surf.c b/apps/plugins/sdl/progs/quake/r_surf.c
new file mode 100644
index 0000000000..a2436d51b2
--- /dev/null
+++ b/apps/plugins/sdl/progs/quake/r_surf.c
@@ -0,0 +1,678 @@
1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20// r_surf.c: surface-related refresh code
21
22#include "quakedef.h"
23#include "r_local.h"
24
25drawsurf_t r_drawsurf;
26
27int lightleft, sourcesstep, blocksize, sourcetstep;
28int lightdelta, lightdeltastep;
29int lightright, lightleftstep, lightrightstep, blockdivshift;
30unsigned blockdivmask;
31void *prowdestbase;
32unsigned char *pbasesource;
33int surfrowbytes; // used by ASM files
34unsigned *r_lightptr;
35int r_stepback;
36int r_lightwidth;
37int r_numhblocks, r_numvblocks;
38unsigned char *r_source, *r_sourcemax;
39
40void R_DrawSurfaceBlock8_mip0 (void);
41void R_DrawSurfaceBlock8_mip1 (void);
42void R_DrawSurfaceBlock8_mip2 (void);
43void R_DrawSurfaceBlock8_mip3 (void);
44
45static void (*surfmiptable[4])(void) = {
46 R_DrawSurfaceBlock8_mip0,
47 R_DrawSurfaceBlock8_mip1,
48 R_DrawSurfaceBlock8_mip2,
49 R_DrawSurfaceBlock8_mip3
50};
51
52
53
54unsigned blocklights[18*18];
55
56/*
57===============
58R_AddDynamicLights
59===============
60*/
61void R_AddDynamicLights (void)
62{
63 msurface_t *surf;
64 int lnum;
65 int sd, td;
66 float dist, rad, minlight;
67 vec3_t impact, local;
68 int s, t;
69 int i;
70 int smax, tmax;
71 mtexinfo_t *tex;
72
73 surf = r_drawsurf.surf;
74 smax = (surf->extents[0]>>4)+1;
75 tmax = (surf->extents[1]>>4)+1;
76 tex = surf->texinfo;
77
78 for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
79 {
80 if ( !(surf->dlightbits & (1<<lnum) ) )
81 continue; // not lit by this light
82
83 rad = cl_dlights[lnum].radius;
84 dist = DotProduct (cl_dlights[lnum].origin, surf->plane->normal) -
85 surf->plane->dist;
86 rad -= fabs(dist);
87 minlight = cl_dlights[lnum].minlight;
88 if (rad < minlight)
89 continue;
90 minlight = rad - minlight;
91
92 for (i=0 ; i<3 ; i++)
93 {
94 impact[i] = cl_dlights[lnum].origin[i] -
95 surf->plane->normal[i]*dist;
96 }
97
98 local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
99 local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3];
100
101 local[0] -= surf->texturemins[0];
102 local[1] -= surf->texturemins[1];
103
104 for (t = 0 ; t<tmax ; t++)
105 {
106 td = local[1] - t*16;
107 if (td < 0)
108 td = -td;
109 for (s=0 ; s<smax ; s++)
110 {
111 sd = local[0] - s*16;
112 if (sd < 0)
113 sd = -sd;
114 if (sd > td)
115 dist = sd + (td>>1);
116 else
117 dist = td + (sd>>1);
118 if (dist < minlight)
119#ifdef QUAKE2
120 {
121 unsigned temp;
122 temp = (rad - dist)*256;
123 i = t*smax + s;
124 if (!cl_dlights[lnum].dark)
125 blocklights[i] += temp;
126 else
127 {
128 if (blocklights[i] > temp)
129 blocklights[i] -= temp;
130 else
131 blocklights[i] = 0;
132 }
133 }
134#else
135 blocklights[t*smax + s] += (rad - dist)*256;
136#endif
137 }
138 }
139 }
140}
141
142/*
143===============
144R_BuildLightMap
145
146Combine and scale multiple lightmaps into the 8.8 format in blocklights
147===============
148*/
149void R_BuildLightMap (void)
150{
151 int smax, tmax;
152 int t;
153 int i, size;
154 byte *lightmap;
155 unsigned scale;
156 int maps;
157 msurface_t *surf;
158
159 surf = r_drawsurf.surf;
160
161 smax = (surf->extents[0]>>4)+1;
162 tmax = (surf->extents[1]>>4)+1;
163 size = smax*tmax;
164 lightmap = surf->samples;
165
166 if (r_fullbright.value || !cl.worldmodel->lightdata)
167 {
168 for (i=0 ; i<size ; i++)
169 blocklights[i] = 0;
170 return;
171 }
172
173// clear to ambient
174 for (i=0 ; i<size ; i++)
175 blocklights[i] = r_refdef.ambientlight<<8;
176
177
178// add all the lightmaps
179 if (lightmap)
180 for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
181 maps++)
182 {
183 scale = r_drawsurf.lightadj[maps]; // 8.8 fraction
184 for (i=0 ; i<size ; i++)
185 blocklights[i] += lightmap[i] * scale;
186 lightmap += size; // skip to next lightmap
187 }
188
189// add all the dynamic lights
190 if (surf->dlightframe == r_framecount)
191 R_AddDynamicLights ();
192
193// bound, invert, and shift
194 for (i=0 ; i<size ; i++)
195 {
196 t = (255*256 - (int)blocklights[i]) >> (8 - VID_CBITS);
197
198 if (t < (1 << 6))
199 t = (1 << 6);
200
201 blocklights[i] = t;
202 }
203}
204
205
206/*
207===============
208R_TextureAnimation
209
210Returns the proper texture for a given time and base texture
211===============
212*/
213texture_t *R_TextureAnimation (texture_t *base)
214{
215 int reletive;
216 int count;
217
218 if (currententity->frame)
219 {
220 if (base->alternate_anims)
221 base = base->alternate_anims;
222 }
223
224 if (!base->anim_total)
225 return base;
226
227 reletive = (int)(cl.time*10) % base->anim_total;
228
229 count = 0;
230 while (base->anim_min > reletive || base->anim_max <= reletive)
231 {
232 base = base->anim_next;
233 if (!base)
234 Sys_Error ("R_TextureAnimation: broken cycle");
235 if (++count > 100)
236 Sys_Error ("R_TextureAnimation: infinite cycle");
237 }
238
239 return base;
240}
241
242
243/*
244===============
245R_DrawSurface
246===============
247*/
248void R_DrawSurface (void)
249{
250 unsigned char *basetptr;
251 int smax, tmax, twidth;
252 int u;
253 int soffset, basetoffset, texwidth;
254 int horzblockstep;
255 unsigned char *pcolumndest;
256 void (*pblockdrawer)(void);
257 texture_t *mt;
258
259// calculate the lightings
260 R_BuildLightMap ();
261
262 surfrowbytes = r_drawsurf.rowbytes;
263
264 mt = r_drawsurf.texture;
265
266 r_source = (byte *)mt + mt->offsets[r_drawsurf.surfmip];
267
268// the fractional light values should range from 0 to (VID_GRADES - 1) << 16
269// from a source range of 0 - 255
270
271 texwidth = mt->width >> r_drawsurf.surfmip;
272
273 blocksize = 16 >> r_drawsurf.surfmip;
274 blockdivshift = 4 - r_drawsurf.surfmip;
275 blockdivmask = (1 << blockdivshift) - 1;
276
277 r_lightwidth = (r_drawsurf.surf->extents[0]>>4)+1;
278
279 r_numhblocks = r_drawsurf.surfwidth >> blockdivshift;
280 r_numvblocks = r_drawsurf.surfheight >> blockdivshift;
281
282//==============================
283
284 if (r_pixbytes == 1)
285 {
286 pblockdrawer = surfmiptable[r_drawsurf.surfmip];
287 // TODO: only needs to be set when there is a display settings change
288 horzblockstep = blocksize;
289 }
290 else
291 {
292 pblockdrawer = R_DrawSurfaceBlock16;
293 // TODO: only needs to be set when there is a display settings change
294 horzblockstep = blocksize << 1;
295 }
296
297 smax = mt->width >> r_drawsurf.surfmip;
298 twidth = texwidth;
299 tmax = mt->height >> r_drawsurf.surfmip;
300 sourcetstep = texwidth;
301 r_stepback = tmax * twidth;
302
303 r_sourcemax = r_source + (tmax * smax);
304
305 soffset = r_drawsurf.surf->texturemins[0];
306 basetoffset = r_drawsurf.surf->texturemins[1];
307
308// << 16 components are to guarantee positive values for %
309 soffset = ((soffset >> r_drawsurf.surfmip) + (smax << 16)) % smax;
310 basetptr = &r_source[((((basetoffset >> r_drawsurf.surfmip)
311 + (tmax << 16)) % tmax) * twidth)];
312
313 pcolumndest = r_drawsurf.surfdat;
314
315 for (u=0 ; u<r_numhblocks; u++)
316 {
317 r_lightptr = blocklights + u;
318
319 prowdestbase = pcolumndest;
320
321 pbasesource = basetptr + soffset;
322
323 (*pblockdrawer)();
324
325 soffset = soffset + blocksize;
326 if (soffset >= smax)
327 soffset = 0;
328
329 pcolumndest += horzblockstep;
330 }
331}
332
333
334//=============================================================================
335
336#if !id386
337
338/*
339================
340R_DrawSurfaceBlock8_mip0
341================
342*/
343void R_DrawSurfaceBlock8_mip0 (void)
344{
345 int v, i, b, lightstep, lighttemp, light;
346 unsigned char pix, *psource, *prowdest;
347
348 psource = pbasesource;
349 prowdest = prowdestbase;
350
351 for (v=0 ; v<r_numvblocks ; v++)
352 {
353 // FIXME: make these locals?
354 // FIXME: use delta rather than both right and left, like ASM?
355 lightleft = r_lightptr[0];
356 lightright = r_lightptr[1];
357 r_lightptr += r_lightwidth;
358 lightleftstep = (r_lightptr[0] - lightleft) >> 4;
359 lightrightstep = (r_lightptr[1] - lightright) >> 4;
360
361 for (i=0 ; i<16 ; i++)
362 {
363 lighttemp = lightleft - lightright;
364 lightstep = lighttemp >> 4;
365
366 light = lightright;
367
368 for (b=15; b>=0; b--)
369 {
370 pix = psource[b];
371 prowdest[b] = ((unsigned char *)vid.colormap)
372 [(light & 0xFF00) + pix];
373 light += lightstep;
374 }
375
376 psource += sourcetstep;
377 lightright += lightrightstep;
378 lightleft += lightleftstep;
379 prowdest += surfrowbytes;
380 }
381
382 if (psource >= r_sourcemax)
383 psource -= r_stepback;
384 }
385}
386
387
388/*
389================
390R_DrawSurfaceBlock8_mip1
391================
392*/
393void R_DrawSurfaceBlock8_mip1 (void)
394{
395 int v, i, b, lightstep, lighttemp, light;
396 unsigned char pix, *psource, *prowdest;
397
398 psource = pbasesource;
399 prowdest = prowdestbase;
400
401 for (v=0 ; v<r_numvblocks ; v++)
402 {
403 // FIXME: make these locals?
404 // FIXME: use delta rather than both right and left, like ASM?
405 lightleft = r_lightptr[0];
406 lightright = r_lightptr[1];
407 r_lightptr += r_lightwidth;
408 lightleftstep = (r_lightptr[0] - lightleft) >> 3;
409 lightrightstep = (r_lightptr[1] - lightright) >> 3;
410
411 for (i=0 ; i<8 ; i++)
412 {
413 lighttemp = lightleft - lightright;
414 lightstep = lighttemp >> 3;
415
416 light = lightright;
417
418 for (b=7; b>=0; b--)
419 {
420 pix = psource[b];
421 prowdest[b] = ((unsigned char *)vid.colormap)
422 [(light & 0xFF00) + pix];
423 light += lightstep;
424 }
425
426 psource += sourcetstep;
427 lightright += lightrightstep;
428 lightleft += lightleftstep;
429 prowdest += surfrowbytes;
430 }
431
432 if (psource >= r_sourcemax)
433 psource -= r_stepback;
434 }
435}
436
437
438/*
439================
440R_DrawSurfaceBlock8_mip2
441================
442*/
443void R_DrawSurfaceBlock8_mip2 (void)
444{
445 int v, i, b, lightstep, lighttemp, light;
446 unsigned char pix, *psource, *prowdest;
447
448 psource = pbasesource;
449 prowdest = prowdestbase;
450
451 for (v=0 ; v<r_numvblocks ; v++)
452 {
453 // FIXME: make these locals?
454 // FIXME: use delta rather than both right and left, like ASM?
455 lightleft = r_lightptr[0];
456 lightright = r_lightptr[1];
457 r_lightptr += r_lightwidth;
458 lightleftstep = (r_lightptr[0] - lightleft) >> 2;
459 lightrightstep = (r_lightptr[1] - lightright) >> 2;
460
461 for (i=0 ; i<4 ; i++)
462 {
463 lighttemp = lightleft - lightright;
464 lightstep = lighttemp >> 2;
465
466 light = lightright;
467
468 for (b=3; b>=0; b--)
469 {
470 pix = psource[b];
471 prowdest[b] = ((unsigned char *)vid.colormap)
472 [(light & 0xFF00) + pix];
473 light += lightstep;
474 }
475
476 psource += sourcetstep;
477 lightright += lightrightstep;
478 lightleft += lightleftstep;
479 prowdest += surfrowbytes;
480 }
481
482 if (psource >= r_sourcemax)
483 psource -= r_stepback;
484 }
485}
486
487
488/*
489================
490R_DrawSurfaceBlock8_mip3
491================
492*/
493void R_DrawSurfaceBlock8_mip3 (void)
494{
495 int v, i, b, lightstep, lighttemp, light;
496 unsigned char pix, *psource, *prowdest;
497
498 psource = pbasesource;
499 prowdest = prowdestbase;
500
501 for (v=0 ; v<r_numvblocks ; v++)
502 {
503 // FIXME: make these locals?
504 // FIXME: use delta rather than both right and left, like ASM?
505 lightleft = r_lightptr[0];
506 lightright = r_lightptr[1];
507 r_lightptr += r_lightwidth;
508 lightleftstep = (r_lightptr[0] - lightleft) >> 1;
509 lightrightstep = (r_lightptr[1] - lightright) >> 1;
510
511 for (i=0 ; i<2 ; i++)
512 {
513 lighttemp = lightleft - lightright;
514 lightstep = lighttemp >> 1;
515
516 light = lightright;
517
518 for (b=1; b>=0; b--)
519 {
520 pix = psource[b];
521 prowdest[b] = ((unsigned char *)vid.colormap)
522 [(light & 0xFF00) + pix];
523 light += lightstep;
524 }
525
526 psource += sourcetstep;
527 lightright += lightrightstep;
528 lightleft += lightleftstep;
529 prowdest += surfrowbytes;
530 }
531
532 if (psource >= r_sourcemax)
533 psource -= r_stepback;
534 }
535}
536
537
538/*
539================
540R_DrawSurfaceBlock16
541
542FIXME: make this work
543================
544*/
545void R_DrawSurfaceBlock16 (void)
546{
547 int k;
548 unsigned char *psource;
549 int lighttemp, lightstep, light;
550 unsigned short *prowdest;
551
552 prowdest = (unsigned short *)prowdestbase;
553
554 for (k=0 ; k<blocksize ; k++)
555 {
556 unsigned short *pdest;
557 unsigned char pix;
558 int b;
559
560 psource = pbasesource;
561 lighttemp = lightright - lightleft;
562 lightstep = lighttemp >> blockdivshift;
563
564 light = lightleft;
565 pdest = prowdest;
566
567 for (b=0; b<blocksize; b++)
568 {
569 pix = *psource;
570 *pdest = vid.colormap16[(light & 0xFF00) + pix];
571 psource += sourcesstep;
572 pdest++;
573 light += lightstep;
574 }
575
576 pbasesource += sourcetstep;
577 lightright += lightrightstep;
578 lightleft += lightleftstep;
579 prowdest = (unsigned short *)((long)prowdest + surfrowbytes);
580 }
581
582 prowdestbase = prowdest;
583}
584
585#endif
586
587
588//============================================================================
589
590/*
591================
592R_GenTurbTile
593================
594*/
595void R_GenTurbTile (pixel_t *pbasetex, void *pdest)
596{
597 int *turb;
598 int i, j, s, t;
599 byte *pd;
600
601 turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
602 pd = (byte *)pdest;
603
604 for (i=0 ; i<TILE_SIZE ; i++)
605 {
606 for (j=0 ; j<TILE_SIZE ; j++)
607 {
608 s = (((j << 16) + turb[i & (CYCLE-1)]) >> 16) & 63;
609 t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63;
610 *pd++ = *(pbasetex + (t<<6) + s);
611 }
612 }
613}
614
615
616/*
617================
618R_GenTurbTile16
619================
620*/
621void R_GenTurbTile16 (pixel_t *pbasetex, void *pdest)
622{
623 int *turb;
624 int i, j, s, t;
625 unsigned short *pd;
626
627 turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
628 pd = (unsigned short *)pdest;
629
630 for (i=0 ; i<TILE_SIZE ; i++)
631 {
632 for (j=0 ; j<TILE_SIZE ; j++)
633 {
634 s = (((j << 16) + turb[i & (CYCLE-1)]) >> 16) & 63;
635 t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63;
636 *pd++ = d_8to16table[*(pbasetex + (t<<6) + s)];
637 }
638 }
639}
640
641
642/*
643================
644R_GenTile
645================
646*/
647void R_GenTile (msurface_t *psurf, void *pdest)
648{
649 if (psurf->flags & SURF_DRAWTURB)
650 {
651 if (r_pixbytes == 1)
652 {
653 R_GenTurbTile ((pixel_t *)
654 ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest);
655 }
656 else
657 {
658 R_GenTurbTile16 ((pixel_t *)
659 ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest);
660 }
661 }
662 else if (psurf->flags & SURF_DRAWSKY)
663 {
664 if (r_pixbytes == 1)
665 {
666 R_GenSkyTile (pdest);
667 }
668 else
669 {
670 R_GenSkyTile16 (pdest);
671 }
672 }
673 else
674 {
675 Sys_Error ("Unknown tile type");
676 }
677}
678