Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 1
/*
2
Copyright (C) 1996-1997 Id Software, Inc.
3
 
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
 
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
 
13
See the GNU General Public License for more details.
14
 
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, 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
 
25
drawsurf_t	r_drawsurf;
26
 
27
int				lightleft, sourcesstep, blocksize, sourcetstep;
28
int				lightdelta, lightdeltastep;
29
int				lightright, lightleftstep, lightrightstep, blockdivshift;
30
unsigned		blockdivmask;
31
void			*prowdestbase;
32
unsigned char	*pbasesource;
33
int				surfrowbytes;	// used by ASM files
34
unsigned		*r_lightptr;
35
int				r_stepback;
36
int				r_lightwidth;
37
int				r_numhblocks, r_numvblocks;
38
unsigned char	*r_source, *r_sourcemax;
39
 
40
void R_DrawSurfaceBlock8_mip0 (void);
41
void R_DrawSurfaceBlock8_mip1 (void);
42
void R_DrawSurfaceBlock8_mip2 (void);
43
void R_DrawSurfaceBlock8_mip3 (void);
44
 
45
static void	(*surfmiptable[4])(void) = {
46
	R_DrawSurfaceBlock8_mip0,
47
	R_DrawSurfaceBlock8_mip1,
48
	R_DrawSurfaceBlock8_mip2,
49
	R_DrawSurfaceBlock8_mip3
50
};
51
 
52
 
53
 
54
unsigned		blocklights[18*18];
55
 
56
/*
57
===============
58
R_AddDynamicLights
59
===============
60
*/
61
void 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
79
	{
80
		if ( !(surf->dlightbits & (1<
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
105
		{
106
			td = local[1] - t*16;
107
			if (td < 0)
108
				td = -td;
109
			for (s=0 ; 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
===============
144
R_BuildLightMap
145
 
146
Combine and scale multiple lightmaps into the 8.8 format in blocklights
147
===============
148
*/
149
void 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
169
			blocklights[i] = 0;
170
		return;
171
	}
172
 
173
// clear to ambient
174
	for (i=0 ; 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
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
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
===============
208
R_TextureAnimation
209
 
210
Returns the proper texture for a given time and base texture
211
===============
212
*/
213
texture_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
===============
245
R_DrawSurface
246
===============
247
*/
248
void 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
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
================
340
R_DrawSurfaceBlock8_mip0
341
================
342
*/
343
void 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
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
================
390
R_DrawSurfaceBlock8_mip1
391
================
392
*/
393
void 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
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
================
440
R_DrawSurfaceBlock8_mip2
441
================
442
*/
443
void 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
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
================
490
R_DrawSurfaceBlock8_mip3
491
================
492
*/
493
void 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
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
================
540
R_DrawSurfaceBlock16
541
 
542
FIXME: make this work
543
================
544
*/
545
void 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
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
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
================
592
R_GenTurbTile
593
================
594
*/
595
void 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
605
	{
606
		for (j=0 ; 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
================
618
R_GenTurbTile16
619
================
620
*/
621
void 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
631
	{
632
		for (j=0 ; 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
================
644
R_GenTile
645
================
646
*/
647
void 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