1 /*
2 	sw32_rsurf.c
3 
4 	surface-related refresh code
5 
6 	Copyright (C) 1996-1997  Id Software, Inc.
7 
8 	This program is free software; you can redistribute it and/or
9 	modify it under the terms of the GNU General Public License
10 	as published by the Free Software Foundation; either version 2
11 	of the License, or (at your option) any later version.
12 
13 	This program is distributed in the hope that it will be useful,
14 	but WITHOUT ANY WARRANTY; without even the implied warranty of
15 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 
17 	See the GNU General Public License for more details.
18 
19 	You should have received a copy of the GNU General Public License
20 	along with this program; if not, write to:
21 
22 		Free Software Foundation, Inc.
23 		59 Temple Place - Suite 330
24 		Boston, MA  02111-1307, USA
25 
26 */
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30 
31 #define NH_DEFINE
32 #include "namehack.h"
33 
34 #include "QF/render.h"
35 #include "QF/sys.h"
36 
37 #include "compat.h"
38 #include "r_internal.h"
39 
40 drawsurf_t  sw32_r_drawsurf;
41 
42 static int         lightleft, blocksize, sourcetstep;
43 static int         lightright, lightleftstep, lightrightstep, blockdivshift;
44 static unsigned int blockdivmask;
45 static byte       *prowdestbase;
46 static byte       *psource;
47 static int         surfrowbytes;
48 static int        *r_lightptr;
49 static int         r_stepback;
50 static int         r_lightwidth;
51 static int         r_numhblocks, r_numvblocks;
52 static byte       *r_source, *r_sourcemax;
53 
54 static void R_DrawSurfaceBlock8_mip0 (void);
55 static void R_DrawSurfaceBlock8_mip1 (void);
56 static void R_DrawSurfaceBlock8_mip2 (void);
57 static void R_DrawSurfaceBlock8_mip3 (void);
58 static void R_DrawSurfaceBlock16_mip0 (void);
59 static void R_DrawSurfaceBlock16_mip1 (void);
60 static void R_DrawSurfaceBlock16_mip2 (void);
61 static void R_DrawSurfaceBlock16_mip3 (void);
62 static void R_DrawSurfaceBlock32_mip0 (void);
63 static void R_DrawSurfaceBlock32_mip1 (void);
64 static void R_DrawSurfaceBlock32_mip2 (void);
65 static void R_DrawSurfaceBlock32_mip3 (void);
66 
67 static void (*surfmiptable8[4]) (void) = {
68 	R_DrawSurfaceBlock8_mip0,
69 	R_DrawSurfaceBlock8_mip1,
70 	R_DrawSurfaceBlock8_mip2,
71 	R_DrawSurfaceBlock8_mip3
72 };
73 
74 static void (*surfmiptable16[4]) (void) = {
75 	R_DrawSurfaceBlock16_mip0,
76 	R_DrawSurfaceBlock16_mip1,
77 	R_DrawSurfaceBlock16_mip2,
78 	R_DrawSurfaceBlock16_mip3
79 };
80 
81 static void (*surfmiptable32[4]) (void) = {
82 	R_DrawSurfaceBlock32_mip0,
83 	R_DrawSurfaceBlock32_mip1,
84 	R_DrawSurfaceBlock32_mip2,
85 	R_DrawSurfaceBlock32_mip3
86 };
87 
88 static int blocklights[34 * 34];	//FIXME make dynamic
89 
90 
91 static void
R_AddDynamicLights(void)92 R_AddDynamicLights (void)
93 {
94 	msurface_t *surf;
95 	unsigned int lnum;
96 	int         sd, td;
97 	float       dist, rad, minlight;
98 	vec3_t      impact, local, lightorigin;
99 	int         s, t;
100 	int         i;
101 	int         smax, tmax;
102 	mtexinfo_t *tex;
103 
104 	surf = sw32_r_drawsurf.surf;
105 	smax = (surf->extents[0] >> 4) + 1;
106 	tmax = (surf->extents[1] >> 4) + 1;
107 	tex = surf->texinfo;
108 
109 	for (lnum = 0; lnum < r_maxdlights; lnum++) {
110 		if (!(surf->dlightbits[lnum / 32] & (1 << (lnum % 32))))
111 			continue;					// not lit by this light
112 
113 		VectorSubtract (r_dlights[lnum].origin, currententity->origin,
114 						lightorigin);
115 		rad = r_dlights[lnum].radius;
116 		dist = DotProduct (lightorigin, surf->plane->normal) -
117 			surf->plane->dist;
118 		rad -= fabs (dist);
119 		minlight = r_dlights[lnum].minlight;
120 		if (rad < minlight)
121 			continue;
122 		minlight = rad - minlight;
123 
124 		for (i = 0; i < 3; i++)
125 			impact[i] = lightorigin[i] - surf->plane->normal[i] * dist;
126 
127 		local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
128 		local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3];
129 
130 		local[0] -= surf->texturemins[0];
131 		local[1] -= surf->texturemins[1];
132 
133 		for (t = 0; t < tmax; t++) {
134 			td = local[1] - t * 16;
135 			if (td < 0)
136 				td = -td;
137 			for (s = 0; s < smax; s++) {
138 				sd = local[0] - s * 16;
139 				if (sd < 0)
140 					sd = -sd;
141 				if (sd > td)
142 					dist = sd + (td >> 1);
143 				else
144 					dist = td + (sd >> 1);
145 				if (dist < minlight)
146 					blocklights[t * smax + s] += (rad - dist) * 256;
147 			}
148 		}
149 	}
150 }
151 
152 /*
153 	R_BuildLightMap
154 
155 	Combine and scale multiple lightmaps into the 8.8 format in blocklights
156 */
157 static void
R_BuildLightMap(void)158 R_BuildLightMap (void)
159 {
160 	int         smax, tmax;
161 	int         t;
162 	int         i, size;
163 	byte       *lightmap;
164 	unsigned int scale;
165 	int         maps;
166 	msurface_t *surf;
167 
168 	surf = sw32_r_drawsurf.surf;
169 
170 	smax = (surf->extents[0] >> 4) + 1;
171 	tmax = (surf->extents[1] >> 4) + 1;
172 	size = smax * tmax;
173 	lightmap = surf->samples;
174 
175 	if (!r_worldentity.model->lightdata) {
176 		for (i = 0; i < size; i++)
177 			blocklights[i] = 0;
178 		return;
179 	}
180 	// clear to ambient
181 	for (i = 0; i < size; i++)
182 		blocklights[i] = r_refdef.ambientlight << 8;
183 
184 	// add all the lightmaps
185 	if (lightmap)
186 		for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++) {
187 			scale = sw32_r_drawsurf.lightadj[maps];	// 8.8 fraction
188 			for (i = 0; i < size; i++)
189 				blocklights[i] += lightmap[i] * scale;
190 			lightmap += size;			// skip to next lightmap
191 		}
192 	// add all the dynamic lights
193 	if (surf->dlightframe == r_framecount)
194 		R_AddDynamicLights ();
195 
196 //	// LordHavoc: changed to positive (not inverse) lighting
197 //	for (i = 0; i < size; i++) {
198 //		t = bound(256, blocklights[i] >> (8 - VID_CBITS),
199 //				  256 * (VID_GRADES - 1));
200 //		blocklights[i] = t;
201 //	}
202 	// bound, invert, and shift
203 	for (i = 0; i < size; i++) {
204 		t = (255 * 256 - blocklights[i]) >> (8 - VID_CBITS);
205 
206 		if (t < (1 << 6))
207 			t = (1 << 6);
208 
209 		blocklights[i] = t;
210 	}
211 }
212 
213 void
sw32_R_DrawSurface(void)214 sw32_R_DrawSurface (void)
215 {
216 	byte       *basetptr;
217 	int         smax, tmax, twidth;
218 	int         u;
219 	int         soffset, basetoffset, texwidth;
220 	int         horzblockstep;
221 	byte       *pcolumndest;
222 	void        (*pblockdrawer) (void);
223 	texture_t  *mt;
224 
225 	// calculate the lightings
226 	R_BuildLightMap ();
227 
228 	surfrowbytes = sw32_r_drawsurf.rowbytes;
229 
230 	mt = sw32_r_drawsurf.texture;
231 
232 	r_source = (byte *) mt + mt->offsets[sw32_r_drawsurf.surfmip];
233 
234 	// the fractional light values should range from 0 to
235 	// (VID_GRADES - 1) << 16 from a source range of 0 - 255
236 
237 	texwidth = mt->width >> sw32_r_drawsurf.surfmip;
238 
239 	blocksize = 16 >> sw32_r_drawsurf.surfmip;
240 	blockdivshift = 4 - sw32_r_drawsurf.surfmip;
241 	blockdivmask = (1 << blockdivshift) - 1;
242 
243 	r_lightwidth = (sw32_r_drawsurf.surf->extents[0] >> 4) + 1;
244 
245 	r_numhblocks = sw32_r_drawsurf.surfwidth >> blockdivshift;
246 	r_numvblocks = sw32_r_drawsurf.surfheight >> blockdivshift;
247 
248 //==============================
249 
250 	smax = mt->width >> sw32_r_drawsurf.surfmip;
251 	twidth = texwidth;
252 	tmax = mt->height >> sw32_r_drawsurf.surfmip;
253 	sourcetstep = texwidth;
254 	r_stepback = tmax * twidth;
255 
256 	soffset = sw32_r_drawsurf.surf->texturemins[0];
257 	basetoffset = sw32_r_drawsurf.surf->texturemins[1];
258 
259 	switch (sw32_r_pixbytes) {
260 	case 1:
261 		pblockdrawer = surfmiptable8[sw32_r_drawsurf.surfmip];
262 		break;
263 	case 2:
264 		pblockdrawer = surfmiptable16[sw32_r_drawsurf.surfmip];
265 		break;
266 	case 4:
267 		pblockdrawer = surfmiptable32[sw32_r_drawsurf.surfmip];
268 		break;
269 	default:
270 		Sys_Error("R_DrawSurface: unsupported r_pixbytes %i", sw32_r_pixbytes);
271 		pblockdrawer = NULL;
272 	}
273 
274 	horzblockstep = blocksize * sw32_r_pixbytes;
275 
276 	r_sourcemax = r_source + (tmax * smax);
277 
278 	// << 16 components are to guarantee positive values for %
279 	basetptr = r_source + (((basetoffset >> sw32_r_drawsurf.surfmip) +
280 							(tmax << 16)) % tmax) * twidth;
281 	soffset = (((soffset >> sw32_r_drawsurf.surfmip) + (smax << 16)) % smax);
282 
283 	pcolumndest = (byte *) sw32_r_drawsurf.surfdat;
284 
285 	for (u = 0; u < r_numhblocks; u++) {
286 		r_lightptr = blocklights + u;
287 
288 		prowdestbase = pcolumndest;
289 
290 		psource = basetptr + soffset;
291 
292 		(*pblockdrawer) ();
293 
294 		soffset = soffset + blocksize;
295 		if (soffset >= smax)
296 			soffset = 0;
297 
298 		pcolumndest += horzblockstep;
299 	}
300 }
301 
302 //=============================================================================
303 
304 static void
R_DrawSurfaceBlock8_mip0(void)305 R_DrawSurfaceBlock8_mip0 (void)
306 {
307 	int         v, i, b, lightstep, light;
308 	unsigned char pix, *prowdest;
309 
310 	prowdest = prowdestbase;
311 
312 	for (v = 0; v < r_numvblocks; v++) {
313 		// FIXME: make these locals?
314 		// FIXME: use delta rather than both right and left, like ASM?
315 		lightleft = r_lightptr[0];
316 		lightright = r_lightptr[1];
317 		r_lightptr += r_lightwidth;
318 		lightleftstep = (r_lightptr[0] - lightleft) >> 4;
319 		lightrightstep = (r_lightptr[1] - lightright) >> 4;
320 
321 		for (i = 0; i < 16; i++) {
322 			lightstep = (lightleft - lightright) >> 4;
323 
324 			light = lightright;
325 
326 			for (b = 15; b >= 0; b--) {
327 				pix = psource[b];
328 				prowdest[b] = vid.colormap8[(light & 0xFF00) + pix];
329 				light += lightstep;
330 			}
331 
332 			psource += sourcetstep;
333 			lightright += lightrightstep;
334 			lightleft += lightleftstep;
335 			prowdest += surfrowbytes;
336 		}
337 
338 		if (psource >= r_sourcemax)
339 			psource -= r_stepback;
340 	}
341 }
342 
343 static void
R_DrawSurfaceBlock8_mip1(void)344 R_DrawSurfaceBlock8_mip1 (void)
345 {
346 	int         v, i, b, lightstep, light;
347 	unsigned char pix, *prowdest;
348 
349 	prowdest = prowdestbase;
350 
351 	for (v = 0; v < r_numvblocks; v++) {
352 		// FIXME: make these locals?
353 		// FIXME: use delta rather than both right and left, like ASM?
354 		lightleft = r_lightptr[0];
355 		lightright = r_lightptr[1];
356 		r_lightptr += r_lightwidth;
357 		lightleftstep = (r_lightptr[0] - lightleft) >> 3;
358 		lightrightstep = (r_lightptr[1] - lightright) >> 3;
359 
360 		for (i = 0; i < 8; i++) {
361 			lightstep = (lightleft - lightright) >> 3;
362 
363 			light = lightright;
364 
365 			for (b = 7; b >= 0; b--) {
366 				pix = psource[b];
367 				prowdest[b] = vid.colormap8[(light & 0xFF00) + pix];
368 				light += lightstep;
369 			}
370 
371 			psource += sourcetstep;
372 			lightright += lightrightstep;
373 			lightleft += lightleftstep;
374 			prowdest += surfrowbytes;
375 		}
376 
377 		if (psource >= r_sourcemax)
378 			psource -= r_stepback;
379 	}
380 }
381 
382 static void
R_DrawSurfaceBlock8_mip2(void)383 R_DrawSurfaceBlock8_mip2 (void)
384 {
385 	int         v, i, b, lightstep, light;
386 	unsigned char pix, *prowdest;
387 
388 	prowdest = prowdestbase;
389 
390 	for (v = 0; v < r_numvblocks; v++) {
391 		// FIXME: make these locals?
392 		// FIXME: use delta rather than both right and left, like ASM?
393 		lightleft = r_lightptr[0];
394 		lightright = r_lightptr[1];
395 		r_lightptr += r_lightwidth;
396 		lightleftstep = (r_lightptr[0] - lightleft) >> 2;
397 		lightrightstep = (r_lightptr[1] - lightright) >> 2;
398 
399 		for (i = 0; i < 4; i++) {
400 			lightstep = (lightleft - lightright) >> 2;
401 
402 			light = lightright;
403 
404 			for (b = 3; b >= 0; b--) {
405 				pix = psource[b];
406 				prowdest[b] = vid.colormap8[(light & 0xFF00) + pix];
407 				light += lightstep;
408 			}
409 
410 			psource += sourcetstep;
411 			lightright += lightrightstep;
412 			lightleft += lightleftstep;
413 			prowdest += surfrowbytes;
414 		}
415 
416 		if (psource >= r_sourcemax)
417 			psource -= r_stepback;
418 	}
419 }
420 
421 static void
R_DrawSurfaceBlock8_mip3(void)422 R_DrawSurfaceBlock8_mip3 (void)
423 {
424 	int         v, i, b, lightstep, light;
425 	unsigned char pix, *prowdest;
426 
427 	prowdest = prowdestbase;
428 
429 	for (v = 0; v < r_numvblocks; v++) {
430 		// FIXME: make these locals?
431 		// FIXME: use delta rather than both right and left, like ASM?
432 		lightleft = r_lightptr[0];
433 		lightright = r_lightptr[1];
434 		r_lightptr += r_lightwidth;
435 		lightleftstep = (r_lightptr[0] - lightleft) >> 1;
436 		lightrightstep = (r_lightptr[1] - lightright) >> 1;
437 
438 		for (i = 0; i < 2; i++) {
439 			lightstep = (lightleft - lightright) >> 1;
440 
441 			light = lightright;
442 
443 			for (b = 1; b >= 0; b--) {
444 				pix = psource[b];
445 				prowdest[b] = vid.colormap8[(light & 0xFF00) + pix];
446 				light += lightstep;
447 			}
448 
449 			psource += sourcetstep;
450 			lightright += lightrightstep;
451 			lightleft += lightleftstep;
452 			prowdest += surfrowbytes;
453 		}
454 
455 		if (psource >= r_sourcemax)
456 			psource -= r_stepback;
457 	}
458 }
459 
460 static void
R_DrawSurfaceBlock16_mip0(void)461 R_DrawSurfaceBlock16_mip0 (void)
462 {
463 	int         k, v;
464 	int         lightstep, light;
465 	unsigned short *prowdest;
466 
467 	prowdest = (unsigned short *) prowdestbase;
468 
469 	for (v = 0; v < r_numvblocks; v++)
470 	{
471 		lightleft = r_lightptr[0];
472 		lightright = r_lightptr[1];
473 		r_lightptr += r_lightwidth;
474 		lightleftstep = (r_lightptr[0] - lightleft) >> 4;
475 		lightrightstep = (r_lightptr[1] - lightright) >> 4;
476 
477 		for (k = 0; k < 16; k++)
478 		{
479 			light = lightleft;
480 			lightstep = (lightright - lightleft) >> 4;
481 
482 			prowdest[0] = vid.colormap16[(light & 0xFF00) + psource[0]];
483 			light += lightstep;
484 			prowdest[1] = vid.colormap16[(light & 0xFF00) + psource[1]];
485 			light += lightstep;
486 			prowdest[2] = vid.colormap16[(light & 0xFF00) + psource[2]];
487 			light += lightstep;
488 			prowdest[3] = vid.colormap16[(light & 0xFF00) + psource[3]];
489 			light += lightstep;
490 			prowdest[4] = vid.colormap16[(light & 0xFF00) + psource[4]];
491 			light += lightstep;
492 			prowdest[5] = vid.colormap16[(light & 0xFF00) + psource[5]];
493 			light += lightstep;
494 			prowdest[6] = vid.colormap16[(light & 0xFF00) + psource[6]];
495 			light += lightstep;
496 			prowdest[7] = vid.colormap16[(light & 0xFF00) + psource[7]];
497 			light += lightstep;
498 			prowdest[8] = vid.colormap16[(light & 0xFF00) + psource[8]];
499 			light += lightstep;
500 			prowdest[9] = vid.colormap16[(light & 0xFF00) + psource[9]];
501 			light += lightstep;
502 			prowdest[10] = vid.colormap16[(light & 0xFF00) + psource[10]];
503 			light += lightstep;
504 			prowdest[11] = vid.colormap16[(light & 0xFF00) + psource[11]];
505 			light += lightstep;
506 			prowdest[12] = vid.colormap16[(light & 0xFF00) + psource[12]];
507 			light += lightstep;
508 			prowdest[13] = vid.colormap16[(light & 0xFF00) + psource[13]];
509 			light += lightstep;
510 			prowdest[14] = vid.colormap16[(light & 0xFF00) + psource[14]];
511 			light += lightstep;
512 			prowdest[15] = vid.colormap16[(light & 0xFF00) + psource[15]];
513 
514 			psource += sourcetstep;
515 			lightright += lightrightstep;
516 			lightleft += lightleftstep;
517 			prowdest += (surfrowbytes >> 1);
518 		}
519 
520 		if (psource >= r_sourcemax)
521 			psource -= r_stepback;
522 	}
523 }
524 
525 static void
R_DrawSurfaceBlock16_mip1(void)526 R_DrawSurfaceBlock16_mip1 (void)
527 {
528 	int         k, v;
529 	int         lightstep, light;
530 	unsigned short *prowdest;
531 
532 	prowdest = (unsigned short *) prowdestbase;
533 
534 	for (v = 0; v < r_numvblocks; v++)
535 	{
536 		lightleft = r_lightptr[0];
537 		lightright = r_lightptr[1];
538 		r_lightptr += r_lightwidth;
539 		lightleftstep = (r_lightptr[0] - lightleft) >> 3;
540 		lightrightstep = (r_lightptr[1] - lightright) >> 3;
541 
542 		for (k = 0; k < 8; k++)
543 		{
544 			light = lightleft;
545 			lightstep = (lightright - lightleft) >> 3;
546 
547 			prowdest[0] = vid.colormap16[(light & 0xFF00) + psource[0]];
548 			light += lightstep;
549 			prowdest[1] = vid.colormap16[(light & 0xFF00) + psource[1]];
550 			light += lightstep;
551 			prowdest[2] = vid.colormap16[(light & 0xFF00) + psource[2]];
552 			light += lightstep;
553 			prowdest[3] = vid.colormap16[(light & 0xFF00) + psource[3]];
554 			light += lightstep;
555 			prowdest[4] = vid.colormap16[(light & 0xFF00) + psource[4]];
556 			light += lightstep;
557 			prowdest[5] = vid.colormap16[(light & 0xFF00) + psource[5]];
558 			light += lightstep;
559 			prowdest[6] = vid.colormap16[(light & 0xFF00) + psource[6]];
560 			light += lightstep;
561 			prowdest[7] = vid.colormap16[(light & 0xFF00) + psource[7]];
562 
563 			psource += sourcetstep;
564 			lightright += lightrightstep;
565 			lightleft += lightleftstep;
566 			prowdest += (surfrowbytes >> 1);
567 		}
568 
569 		if (psource >= r_sourcemax)
570 			psource -= r_stepback;
571 	}
572 }
573 
574 static void
R_DrawSurfaceBlock16_mip2(void)575 R_DrawSurfaceBlock16_mip2 (void)
576 {
577 	int         k, v;
578 	int         lightstep, light;
579 	unsigned short *prowdest;
580 
581 	prowdest = (unsigned short *) prowdestbase;
582 
583 	for (v = 0; v < r_numvblocks; v++)
584 	{
585 		lightleft = r_lightptr[0];
586 		lightright = r_lightptr[1];
587 		r_lightptr += r_lightwidth;
588 		lightleftstep = (r_lightptr[0] - lightleft) >> 2;
589 		lightrightstep = (r_lightptr[1] - lightright) >> 2;
590 
591 		for (k = 0; k < 4; k++)
592 		{
593 			light = lightleft;
594 			lightstep = (lightright - lightleft) >> 2;
595 
596 			prowdest[0] = vid.colormap16[(light & 0xFF00) + psource[0]];
597 			light += lightstep;
598 			prowdest[1] = vid.colormap16[(light & 0xFF00) + psource[1]];
599 			light += lightstep;
600 			prowdest[2] = vid.colormap16[(light & 0xFF00) + psource[2]];
601 			light += lightstep;
602 			prowdest[3] = vid.colormap16[(light & 0xFF00) + psource[3]];
603 
604 			psource += sourcetstep;
605 			lightright += lightrightstep;
606 			lightleft += lightleftstep;
607 			prowdest += (surfrowbytes >> 1);
608 		}
609 
610 		if (psource >= r_sourcemax)
611 			psource -= r_stepback;
612 	}
613 }
614 
615 static void
R_DrawSurfaceBlock16_mip3(void)616 R_DrawSurfaceBlock16_mip3 (void)
617 {
618 	int v;
619 	unsigned short *prowdest;
620 
621 	prowdest = (unsigned short *) prowdestbase;
622 
623 	for (v = 0; v < r_numvblocks; v++)
624 	{
625 		lightleft = r_lightptr[0];
626 		lightright = r_lightptr[1];
627 		r_lightptr += r_lightwidth;
628 		lightleftstep = (r_lightptr[0] - lightleft) >> 1;
629 		lightrightstep = (r_lightptr[1] - lightright) >> 1;
630 
631 		prowdest[0] = vid.colormap16[(lightleft & 0xFF00) + psource[0]];
632 		prowdest[1] = vid.colormap16[(((lightleft + lightright) >> 1) &
633 									  0xFF00) + psource[1]];
634 		psource += sourcetstep;
635 		lightright += lightrightstep;
636 		lightleft += lightleftstep;
637 		prowdest += (surfrowbytes >> 1);
638 
639 		prowdest[0] = vid.colormap16[(lightleft & 0xFF00) + psource[0]];
640 		prowdest[1] = vid.colormap16[(((lightleft + lightright) >> 1) &
641 									  0xFF00) + psource[1]];
642 		psource += sourcetstep;
643 		prowdest += (surfrowbytes >> 1);
644 
645 		if (psource >= r_sourcemax)
646 			psource -= r_stepback;
647 	}
648 }
649 
650 static void
R_DrawSurfaceBlock32_mip0(void)651 R_DrawSurfaceBlock32_mip0 (void)
652 {
653 	int         k, v;
654 	int         lightstep, light;
655 	unsigned int *prowdest;
656 
657 	prowdest = (unsigned int *) prowdestbase;
658 
659 	for (v = 0; v < r_numvblocks; v++)
660 	{
661 		lightleft = r_lightptr[0];
662 		lightright = r_lightptr[1];
663 		r_lightptr += r_lightwidth;
664 		lightleftstep = (r_lightptr[0] - lightleft) >> 4;
665 		lightrightstep = (r_lightptr[1] - lightright) >> 4;
666 
667 		for (k = 0; k < 16; k++)
668 		{
669 			light = lightleft;
670 			lightstep = (lightright - lightleft) >> 4;
671 
672 			prowdest[0] = vid.colormap32[(light & 0xFF00) + psource[0]];
673 			light += lightstep;
674 			prowdest[1] = vid.colormap32[(light & 0xFF00) + psource[1]];
675 			light += lightstep;
676 			prowdest[2] = vid.colormap32[(light & 0xFF00) + psource[2]];
677 			light += lightstep;
678 			prowdest[3] = vid.colormap32[(light & 0xFF00) + psource[3]];
679 			light += lightstep;
680 			prowdest[4] = vid.colormap32[(light & 0xFF00) + psource[4]];
681 			light += lightstep;
682 			prowdest[5] = vid.colormap32[(light & 0xFF00) + psource[5]];
683 			light += lightstep;
684 			prowdest[6] = vid.colormap32[(light & 0xFF00) + psource[6]];
685 			light += lightstep;
686 			prowdest[7] = vid.colormap32[(light & 0xFF00) + psource[7]];
687 			light += lightstep;
688 			prowdest[8] = vid.colormap32[(light & 0xFF00) + psource[8]];
689 			light += lightstep;
690 			prowdest[9] = vid.colormap32[(light & 0xFF00) + psource[9]];
691 			light += lightstep;
692 			prowdest[10] = vid.colormap32[(light & 0xFF00) + psource[10]];
693 			light += lightstep;
694 			prowdest[11] = vid.colormap32[(light & 0xFF00) + psource[11]];
695 			light += lightstep;
696 			prowdest[12] = vid.colormap32[(light & 0xFF00) + psource[12]];
697 			light += lightstep;
698 			prowdest[13] = vid.colormap32[(light & 0xFF00) + psource[13]];
699 			light += lightstep;
700 			prowdest[14] = vid.colormap32[(light & 0xFF00) + psource[14]];
701 			light += lightstep;
702 			prowdest[15] = vid.colormap32[(light & 0xFF00) + psource[15]];
703 
704 			psource += sourcetstep;
705 			lightright += lightrightstep;
706 			lightleft += lightleftstep;
707 			prowdest += (surfrowbytes >> 2);
708 		}
709 
710 		if (psource >= r_sourcemax)
711 			psource -= r_stepback;
712 	}
713 }
714 
715 static void
R_DrawSurfaceBlock32_mip1(void)716 R_DrawSurfaceBlock32_mip1 (void)
717 {
718 	int         k, v;
719 	int         lightstep, light;
720 	unsigned int *prowdest;
721 
722 	prowdest = (unsigned int *) prowdestbase;
723 
724 	for (v = 0; v < r_numvblocks; v++)
725 	{
726 		lightleft = r_lightptr[0];
727 		lightright = r_lightptr[1];
728 		r_lightptr += r_lightwidth;
729 		lightleftstep = (r_lightptr[0] - lightleft) >> 3;
730 		lightrightstep = (r_lightptr[1] - lightright) >> 3;
731 
732 		for (k = 0; k < 8; k++)
733 		{
734 			light = lightleft;
735 			lightstep = (lightright - lightleft) >> 3;
736 
737 			prowdest[0] = vid.colormap32[(light & 0xFF00) + psource[0]];
738 			light += lightstep;
739 			prowdest[1] = vid.colormap32[(light & 0xFF00) + psource[1]];
740 			light += lightstep;
741 			prowdest[2] = vid.colormap32[(light & 0xFF00) + psource[2]];
742 			light += lightstep;
743 			prowdest[3] = vid.colormap32[(light & 0xFF00) + psource[3]];
744 			light += lightstep;
745 			prowdest[4] = vid.colormap32[(light & 0xFF00) + psource[4]];
746 			light += lightstep;
747 			prowdest[5] = vid.colormap32[(light & 0xFF00) + psource[5]];
748 			light += lightstep;
749 			prowdest[6] = vid.colormap32[(light & 0xFF00) + psource[6]];
750 			light += lightstep;
751 			prowdest[7] = vid.colormap32[(light & 0xFF00) + psource[7]];
752 
753 			psource += sourcetstep;
754 			lightright += lightrightstep;
755 			lightleft += lightleftstep;
756 			prowdest += (surfrowbytes >> 2);
757 		}
758 
759 		if (psource >= r_sourcemax)
760 			psource -= r_stepback;
761 	}
762 }
763 
764 static void
R_DrawSurfaceBlock32_mip2(void)765 R_DrawSurfaceBlock32_mip2 (void)
766 {
767 	int         k, v;
768 	int         lightstep, light;
769 	unsigned int *prowdest;
770 
771 	prowdest = (unsigned int *) prowdestbase;
772 
773 	for (v = 0; v < r_numvblocks; v++)
774 	{
775 		lightleft = r_lightptr[0];
776 		lightright = r_lightptr[1];
777 		r_lightptr += r_lightwidth;
778 		lightleftstep = (r_lightptr[0] - lightleft) >> 2;
779 		lightrightstep = (r_lightptr[1] - lightright) >> 2;
780 
781 		for (k = 0; k < 4; k++)
782 		{
783 			light = lightleft;
784 			lightstep = (lightright - lightleft) >> 2;
785 
786 			prowdest[0] = vid.colormap32[(light & 0xFF00) + psource[0]];
787 			light += lightstep;
788 			prowdest[1] = vid.colormap32[(light & 0xFF00) + psource[1]];
789 			light += lightstep;
790 			prowdest[2] = vid.colormap32[(light & 0xFF00) + psource[2]];
791 			light += lightstep;
792 			prowdest[3] = vid.colormap32[(light & 0xFF00) + psource[3]];
793 
794 			psource += sourcetstep;
795 			lightright += lightrightstep;
796 			lightleft += lightleftstep;
797 			prowdest += (surfrowbytes >> 2);
798 		}
799 
800 		if (psource >= r_sourcemax)
801 			psource -= r_stepback;
802 	}
803 }
804 
805 static void
R_DrawSurfaceBlock32_mip3(void)806 R_DrawSurfaceBlock32_mip3 (void)
807 {
808 	int v;
809 	unsigned int *prowdest;
810 
811 	prowdest = (unsigned int *) prowdestbase;
812 
813 	for (v = 0; v < r_numvblocks; v++)
814 	{
815 		lightleft = r_lightptr[0];
816 		lightright = r_lightptr[1];
817 		r_lightptr += r_lightwidth;
818 		lightleftstep = (r_lightptr[0] - lightleft) >> 1;
819 		lightrightstep = (r_lightptr[1] - lightright) >> 1;
820 
821 		prowdest[0] = vid.colormap32[(lightleft & 0xFF00) + psource[0]];
822 		prowdest[1] = vid.colormap32[(((lightleft + lightright) >> 1) &
823 									  0xFF00) + psource[1]];
824 		psource += sourcetstep;
825 		lightright += lightrightstep;
826 		lightleft += lightleftstep;
827 		prowdest += (surfrowbytes >> 2);
828 
829 		prowdest[0] = vid.colormap32[(lightleft & 0xFF00) + psource[0]];
830 		prowdest[1] = vid.colormap32[(((lightleft + lightright) >> 1) &
831 									  0xFF00) + psource[1]];
832 		psource += sourcetstep;
833 		lightright += lightrightstep;
834 		lightleft += lightleftstep;
835 		prowdest += (surfrowbytes >> 2);
836 
837 		if (psource >= r_sourcemax)
838 			psource -= r_stepback;
839 	}
840 }
841 
842 /*
843 void
844 R_DrawSurfaceBlock32 (void)
845 {
846 	int         k, v;
847 	int         lightstep, light;
848 	unsigned int *prowdest;
849 
850 	prowdest = prowdestbase;
851 
852 	for (v = 0; v < r_numvblocks; v++) {
853 
854 		lightleft = r_lightptr[0];
855 		lightright = r_lightptr[1];
856 		r_lightptr += r_lightwidth;
857 		lightleftstep = (r_lightptr[0] - lightleft) >> blockdivshift;
858 		lightrightstep = (r_lightptr[1] - lightright) >> blockdivshift;
859 
860 		for (k = 0; k < blocksize; k++) {
861 			int         b;
862 
863 			lightstep = (lightright - lightleft) >> blockdivshift;
864 
865 			light = lightleft;
866 
867 			for (b = 0;b < blocksize;b++, light += lightstep)
868 				prowdest[b] = vid.colormap32[(light & 0xFF00) + psource[b]];
869 
870 			psource += sourcetstep;
871 			lightright += lightrightstep;
872 			lightleft += lightleftstep;
873 			prowdest += (surfrowbytes >> 2);
874 		}
875 
876 		if (psource >= r_sourcemax)
877 			psource -= r_stepback;
878 	}
879 }
880 */
881