1 /*
2 Copyright (C) 1997-2001 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 
21 // gl_script.c - scripted texture rendering - MrG
22 
23 #include "gl_local.h"
24 
25 void CIN_FreeCin (int texnum);
26 
27 extern float	r_turbsin[];
28 
29 #define		TURBSCALE (256.0 / (2 * M_PI))
30 
31 #define		TOK_DELIMINATORS "\r\n\t "
32 
33 float		rs_realtime = 0;
34 rscript_t	*rs_rootscript = NULL;
35 void setRenderDynamic (void);
36 
RS_ListScripts(void)37 void RS_ListScripts (void)
38 {
39 	rscript_t	*rs;
40 	int			i;
41 
42 	for (i = 0, rs = rs_rootscript; rs; rs = rs->next, i++)
43 		ri.Con_Printf (PRINT_ALL, ">> %s\n", rs->name);
44 }
45 
RS_Random(rs_stage_t * stage,msurface_t * surf)46 int	RS_Random(rs_stage_t *stage, msurface_t *surf)
47 {
48 	random_stage_t	*randStage = stage->rand_stage;
49 	int number = 0, i;
50 	glpoly_t *poly;
51 
52 	for (poly=surf->polys ; poly ; poly=poly->next)
53 		number += poly->center[0] + poly->center[1] + poly->center[2];
54 
55 	for (i=0; i<(number%stage->rand_count) && randStage; randStage = randStage->next)
56 		;
57 
58 	return  randStage->texture->texnum;
59 }
60 
RS_Animate(rs_stage_t * stage)61 int RS_Animate (rs_stage_t *stage)
62 {
63 	anim_stage_t	*anim = stage->last_anim;
64 	float			time = rs_realtime * 1000 -
65 		(stage->last_anim_time + stage->anim_delay);
66 
67 	while (stage->last_anim_time < rs_realtime)
68 	{
69 		anim = anim->next;
70 		if (!anim)
71 			anim = stage->anim_stage;
72 		stage->last_anim_time += stage->anim_delay;
73 	}
74 
75 	stage->last_anim = anim;
76 
77 	return anim->texture->texnum;
78 }
RS_AnimateSkin(rs_stage_t * stage)79 void *RS_AnimateSkin (rs_stage_t *stage)
80 {
81 	anim_stage_t	*anim = stage->last_anim;
82 	float			time = rs_realtime * 1000 -
83 		(stage->last_anim_time + stage->anim_delay);
84 
85 	while (stage->last_anim_time < rs_realtime)
86 	{
87 		anim = anim->next;
88 		if (!anim)
89 			anim = stage->anim_stage;
90 		stage->last_anim_time += stage->anim_delay;
91 	}
92 
93 	stage->last_anim = anim;
94 
95 	return anim->texture;
96 }
97 
cutDot(vec3_t vec1,vec3_t vec2)98 float cutDot (vec3_t vec1, vec3_t vec2)
99 {
100 	float dot = DotProduct(vec1, vec2);
101 	if (dot>1) return 1;
102 	if (dot<-1) return -1;
103 	return dot;
104 }
105 
RS_ResetScript(rscript_t * rs)106 void RS_ResetScript (rscript_t *rs)
107 {
108 	rs_stage_t		*stage = rs->stage, *tmp_stage;
109 	anim_stage_t	*anim, *tmp_anim;
110 	random_stage_t	*randStage, *tmp_rand;
111 
112 	rs->name[0] = 0;
113 
114 	while (stage != NULL)
115 	{
116 		if (stage->anim_count)
117 		{
118 			anim = stage->anim_stage;
119 			while (anim != NULL)
120 			{
121 				tmp_anim = anim;
122 				if (anim->texture)
123 					if (anim->texture->is_cin)
124 						CIN_FreeCin(anim->texture->texnum);
125 				anim = anim->next;
126 				free (tmp_anim);
127 			}
128 		}
129 		if (stage->rand_count)
130 		{
131 			randStage = stage->rand_stage;
132 			while (randStage != NULL)
133 			{
134 				tmp_rand = randStage;
135 				if (randStage->texture)
136 					if (randStage->texture->is_cin)
137 						CIN_FreeCin(randStage->texture->texnum);
138 				randStage = randStage->next;
139 				free (tmp_rand);
140 			}
141 		}
142 
143 		tmp_stage = stage;
144 		stage = stage->next;
145 
146 		free (tmp_stage);
147 	}
148 
149 	rs->picsize.enable = false;
150 	rs->picsize.width = 0;
151 	rs->picsize.height = 0;
152 	rs->model = false;
153 	rs->mirror = false;
154 	rs->stage = NULL;
155 	rs->dontflush = false;
156 	rs->subdivide = 0;
157 	rs->warpdist = 0;
158 	rs->warpsmooth = 0;
159 	rs->warpspeed = 0;
160 	rs->ready = false;
161 	rs->glarescript.enabled = false;
162 	rs->glarescript.name[0] = 0;
163 	rs->glarescript.script = NULL;
164 	rs->glaretexture.enabled = false;
165 	rs->glaretexture.name[0] = 0;
166 	rs->glaretexture.texture = NULL;
167 	rs->glarecolor.blue = 0;
168 	rs->glarecolor.green = 0;
169 	rs->glarecolor.red = 0;
170 	rs->glarecolor.enabled = false;
171 
172 
173 }
174 
RS_ClearStage(rs_stage_t * stage)175 void RS_ClearStage (rs_stage_t *stage)
176 {
177 	anim_stage_t	*anim = stage->anim_stage, *tmp_anim;
178 	random_stage_t	*randStage = stage->rand_stage, *tmp_rand;
179 
180 
181 	while (anim != NULL)
182 	{
183 		tmp_anim = anim;
184 		anim = anim->next;
185 		free (tmp_anim);
186 	}
187 	while (randStage != NULL)
188 	{
189 		tmp_rand = randStage;
190 		randStage = randStage->next;
191 		free (tmp_rand);
192 	}
193 
194 	stage->last_anim = 0;
195 	stage->last_anim_time = 0;
196 	stage->anim_count = 0;
197 
198 	stage->anim_delay = 0;
199 	stage->anim_stage = NULL;
200 
201 	stage->rand_count = 0;
202 	stage->rand_stage = NULL;
203 
204 	stage->has_alpha = false;
205 	stage->alphamask = false;
206 
207 	stage->alphafunc = 0;
208 
209 	stage->alphashift.max = 0;
210 	stage->alphashift.min = 0;
211 	stage->alphashift.speed = 0;
212 
213 	stage->blendfunc.blend = false;
214 	stage->blendfunc.dest = stage->blendfunc.source = 0;
215 
216 	stage->colormap.enabled = false;
217 	stage->colormap.red = 0;
218 	stage->colormap.green = 0;
219 	stage->colormap.blue = 0;
220 
221 	stage->scale.scaleX = 0;
222 	stage->scale.scaleY = 0;
223 	stage->scale.typeX = 0;
224 	stage->scale.typeY = 0;
225 
226 	stage->offset.offX = 0;
227 	stage->offset.offY = 0;
228 
229 	stage->scroll.speedX = 0;
230 	stage->scroll.speedY = 0;
231 	stage->scroll.typeX = 0;
232 	stage->scroll.typeY = 0;
233 
234 	stage->frames.enabled = false;
235 	stage->frames.start = 0;
236 	stage->frames.end = 0;
237 
238 	stage->rot_speed = 0;
239 
240 	VectorClear(stage->origin);
241 	VectorClear(stage->angle);
242 
243 	stage->texture = NULL;
244 
245 
246 	stage->depthhack = 0;
247 	stage->envmap = false;
248 	stage->dynamic = false;
249 	stage->detail = false;
250 
251 	stage->lightmap = true;
252 
253 	stage->next = NULL;
254 }
255 
RS_NewScript(char * name)256 rscript_t *RS_NewScript (char *name)
257 {
258 	rscript_t	*rs;
259 
260 	if (!rs_rootscript)
261 	{
262 		rs_rootscript = (rscript_t *)malloc(sizeof(rscript_t));
263 		rs = rs_rootscript;
264 	}
265 	else
266 	{
267 		rs = rs_rootscript;
268 
269 		while (rs->next != NULL)
270 			rs = rs->next;
271 
272 		rs->next = (rscript_t *)malloc(sizeof(rscript_t));
273 		rs = rs->next;
274 	}
275 
276 	strncpy (rs->name, name, sizeof(rs->name));
277 
278 	rs->stage = NULL;
279 	rs->next = NULL;
280 	rs->dontflush = false;
281 	rs->subdivide = 0;
282 	rs->warpdist = 0.0f;
283 	rs->warpsmooth = 0.0f;
284 	rs->ready = false;
285 	rs->mirror = false;
286 	rs->model = false;
287 	rs->picsize.enable = false;
288 	rs->picsize.width = 0;
289 	rs->picsize.height = 0;
290 	rs->glaretexture.enabled = false;
291 	rs->glaretexture.name[0] = 0;
292 	rs->glaretexture.texture = NULL;
293 	rs->glarescript.enabled = false;
294 	rs->glarescript.name[0] = 0;
295 	rs->glarescript.script = NULL;
296 	rs->glarecolor.blue = 0;
297 	rs->glarecolor.green = 0;
298 	rs->glarecolor.red = 0;
299 	rs->glarecolor.enabled = false;
300 
301 	return rs;
302 }
303 
RS_NewStage(rscript_t * rs)304 rs_stage_t *RS_NewStage (rscript_t *rs)
305 {
306 	rs_stage_t	*stage;
307 
308 	if (rs->stage == NULL)
309 	{
310 		rs->stage = (rs_stage_t *)malloc(sizeof(rs_stage_t));
311 		stage = rs->stage;
312 	}
313 	else
314 	{
315 		stage = rs->stage;
316 		while (stage->next != NULL)
317 			stage = stage->next;
318 
319 		stage->next = (rs_stage_t *)malloc(sizeof(rs_stage_t));
320 		stage = stage->next;
321 	}
322 
323 	strncpy (stage->name, "***r_notexture***", sizeof(stage->name));
324 
325 	stage->rand_stage = NULL;
326 	stage->anim_stage = NULL;
327 	stage->next = NULL;
328 	stage->last_anim = NULL;
329 
330 	RS_ClearStage (stage);
331 
332 	return stage;
333 }
334 
RS_FreeAllScripts(void)335 void RS_FreeAllScripts (void)
336 {
337 	rscript_t	*rs = rs_rootscript, *tmp_rs;
338 
339 	while (rs != NULL)
340 	{
341 		tmp_rs = rs->next;
342 		RS_ResetScript(rs);
343 		free (rs);
344 		rs = tmp_rs;
345 	}
346 	rs_rootscript = NULL;
347 }
348 
RS_ReloadImageScriptLinks(void)349 void RS_ReloadImageScriptLinks (void)
350 {
351 	image_t		*image;
352 	int	i;
353 
354 	for (i=0, image=gltextures ; i<numgltextures ; i++,image++)
355 		image->script = RS_FindScript(image->bare_name);
356 
357 }
358 
RS_FreeScript(rscript_t * rs)359 void RS_FreeScript(rscript_t *rs)
360 {
361 	rscript_t	*tmp_rs;
362 
363 	if (!rs)
364 		return;
365 
366 	if (rs_rootscript == rs)
367 	{
368 		rs_rootscript = rs_rootscript->next;
369 
370 		RS_ResetScript(rs);
371 		free (rs);
372 
373 		return;
374 	}
375 
376 	tmp_rs = rs_rootscript;
377 	while (tmp_rs->next != rs)
378 		tmp_rs = tmp_rs->next;
379 	tmp_rs->next = rs->next;
380 
381 	RS_ResetScript (rs);
382 	free (rs);
383 }
384 
RS_FreeUnmarked(void)385 void RS_FreeUnmarked (void)
386 {
387 	rscript_t	*rs = rs_rootscript, *tmp_rs;
388 
389 	while (rs != NULL)
390 	{
391 		tmp_rs = rs->next;
392 
393 		if (!rs->dontflush)
394 			RS_FreeScript(rs);
395 
396 		rs = tmp_rs;
397 	}
398 }
399 
RS_FindImageScript(image_t * image)400 rscript_t *RS_FindImageScript(image_t *image)
401 {
402 	if (!image)
403 		return NULL;
404 
405 	return image->script;
406 
407 	return NULL;
408 }
409 
RS_FindScript(char * name)410 rscript_t *RS_FindScript(char *name)
411 {
412 	rscript_t	*rs = rs_rootscript;
413 
414 	while (rs != NULL)
415 	{
416 		if (!_stricmp(rs->name, name))
417 		{
418 			if (rs->stage)
419 			   return rs;
420 			else
421 			   return NULL;
422 		}
423 
424 		rs = rs->next;
425 	}
426 
427 	return NULL;
428 }
429 
RS_ReadyScript(rscript_t * rs)430 void RS_ReadyScript (rscript_t *rs)
431 {
432 	rs_stage_t		*stage;
433 	anim_stage_t	*anim;
434 	random_stage_t	*randStage;
435 	char			mode;
436 
437 	if (!rs)
438 		return;
439 
440 	if (rs->ready)
441 		return;
442 
443 	mode = (rs->dontflush) ? it_pic : it_wall;
444 	stage = rs->stage;
445 
446 	if (rs->glaretexture.enabled )
447 	{
448 		rs->glaretexture.texture = GL_FindImage (rs->glaretexture.name, mode);
449 		if (!rs->glaretexture.texture)
450 			rs->glaretexture.enabled = false;
451 	}
452 
453 	if (rs->glarescript.enabled)
454 	{
455 		if (_stricmp(rs->name, rs->glarescript.name)) //no recusive searches thanks
456 		{
457 			rs->glarescript.script = RS_FindScript(rs->glarescript.name);
458 			if (rs->glarescript.script)
459 				RS_ReadyScript(rs->glarescript.script);
460 		}
461 	}
462 
463 	while (stage != NULL)
464 	{
465 		//set anim
466 		anim = stage->anim_stage;
467 		while (anim != NULL)
468 		{
469 			anim->texture = GL_FindImage (anim->name, mode);
470 			if (!anim->texture)
471 				anim->texture = r_notexture;
472 
473 			anim = anim->next;
474 		}
475 
476 		//set tiling
477 		randStage = stage->rand_stage;
478 		while (randStage != NULL)
479 		{
480 			randStage->texture = GL_FindImage (randStage->name, mode);
481 			if (!randStage->texture)
482 				randStage->texture = r_notexture;
483 
484 			randStage = randStage->next;
485 		}
486 
487 		//set name
488 		if (stage->name[0])
489 			stage->texture = GL_FindImage (stage->name, mode);
490 		if (!stage->texture)
491 			stage->texture = r_notexture;
492 
493 		//check alpha
494 		if (stage->blendfunc.blend)
495 			stage->has_alpha = true;
496 		else
497 			stage->has_alpha = false;
498 
499 		stage = stage->next;
500 	}
501 
502 	rs->ready = true;
503 }
504 
505 
RS_UpdateRegistration(void)506 void RS_UpdateRegistration (void)
507 {
508 	rscript_t		*rs = rs_rootscript;
509 	rs_stage_t		*stage;
510 	anim_stage_t	*anim;
511 	random_stage_t	*randStage;
512 	int				mode;
513 
514 	while (rs != NULL)
515 	{
516 		mode = (rs->dontflush) ? it_pic : it_wall;
517 		stage = rs->stage;
518 
519 		if (rs->glarescript.enabled)
520 			rs->glarescript.script = NULL;
521 
522 		if (rs->glaretexture.enabled)
523 		{
524 			rs->glaretexture.texture = GL_FindImage (rs->glaretexture.name, mode);
525 			if (!rs->glaretexture.texture)
526 				rs->glaretexture.texture = r_notexture;
527 		}
528 
529 		while (stage != NULL)
530 		{
531 			anim = stage->anim_stage;
532 			while (anim != NULL)
533 			{
534 				anim->texture = GL_FindImage(anim->name,mode);
535 				if (!anim->texture)
536 					anim->texture = r_notexture;
537 				anim = anim->next;
538 			}
539 
540 			randStage = (random_stage_t*)stage->rand_stage;
541 			while (randStage != NULL)
542 			{
543 				randStage->texture = GL_FindImage(randStage->name,mode);
544 				if (!randStage->texture)
545 					randStage->texture = r_notexture;
546 				randStage = randStage->next;
547 			}
548 
549 			if (stage->name[0])
550 			{
551 				stage->texture = GL_FindImage(stage->name, mode);
552 			}
553 
554 			if (!stage->texture)
555 				stage->texture = r_notexture;
556 
557 			stage = stage->next;
558 		}
559 
560 		rs = rs->next;
561 	}
562 }
563 
RS_BlendID(char * blend)564 int RS_BlendID (char *blend)
565 {
566 	if (!blend[0])
567 		return 0;
568 	if (!_stricmp (blend, "GL_ZERO"))
569 		return GL_ZERO;
570 	if (!_stricmp (blend, "GL_ONE"))
571 		return GL_ONE;
572 	if (!_stricmp (blend, "GL_DST_COLOR"))
573 		return GL_DST_COLOR;
574 	if (!_stricmp (blend, "GL_ONE_MINUS_DST_COLOR"))
575 		return GL_ONE_MINUS_DST_COLOR;
576 	if (!_stricmp (blend, "GL_SRC_ALPHA"))
577 		return GL_SRC_ALPHA;
578 	if (!_stricmp (blend, "GL_ONE_MINUS_SRC_ALPHA"))
579 		return GL_ONE_MINUS_SRC_ALPHA;
580 	if (!_stricmp (blend, "GL_DST_ALPHA"))
581 		return GL_DST_ALPHA;
582 	if (!_stricmp (blend, "GL_ONE_MINUS_DST_ALPHA"))
583 		return GL_ONE_MINUS_DST_ALPHA;
584 	if (!_stricmp (blend, "GL_SRC_ALPHA_SATURATE"))
585 		return GL_SRC_ALPHA_SATURATE;
586 	if (!_stricmp (blend, "GL_SRC_COLOR"))
587 		return GL_SRC_COLOR;
588 	if (!_stricmp (blend, "GL_ONE_MINUS_SRC_COLOR"))
589 		return GL_ONE_MINUS_SRC_COLOR;
590 
591 	return 0;
592 }
593 
RS_FuncName(char * text)594 int RS_FuncName (char *text)
595 {
596 	if (!_stricmp (text, "static"))			// static
597 		return 0;
598 	else if (!_stricmp (text, "sine"))		// sine wave
599 		return 1;
600 	else if (!_stricmp (text, "cosine"))	// cosine wave
601 		return 2;
602 
603 	return 0;
604 }
605 
606 /*
607 scriptname
608 {
609 	subdivide <size>
610 	vertexwarp <speed> <distance> <smoothness>
611 	safe
612 	{
613 		map <texturename>
614 		scroll <xtype> <xspeed> <ytype> <yspeed>
615 		blendfunc <source> <dest>
616 		alphashift <speed> <min> <max>
617 		anim <delay> <tex1> <tex2> <tex3> ... end
618 		envmap
619 		nolightmap
620 		alphamask
621 	}
622 }
623 */
624 
rs_stage_map(rs_stage_t * stage,char ** token)625 void rs_stage_map (rs_stage_t *stage, char **token)
626 {
627 	*token = strtok (NULL, TOK_DELIMINATORS);
628 
629 	strncpy (stage->name, *token, sizeof(stage->name));
630 }
631 
rs_stage_model(rs_stage_t * stage,char ** token)632 void rs_stage_model (rs_stage_t *stage, char **token)
633 {
634 	*token = strtok (NULL, TOK_DELIMINATORS);
635 
636 	strncpy (stage->model, *token, sizeof(stage->model));
637 }
638 
rs_stage_colormap(rs_stage_t * stage,char ** token)639 void rs_stage_colormap (rs_stage_t *stage, char **token)
640 {
641 	stage->colormap.enabled = true;
642 
643 	*token = strtok (NULL, TOK_DELIMINATORS);
644 	stage->colormap.red = atoi(*token);
645 
646 	*token = strtok (NULL, TOK_DELIMINATORS);
647 	stage->colormap.green = atoi(*token);
648 
649 	*token = strtok (NULL, TOK_DELIMINATORS);
650 	stage->colormap.blue = atoi(*token);
651 }
652 
rs_stage_frames(rs_stage_t * stage,char ** token)653 void rs_stage_frames (rs_stage_t *stage, char **token)
654 {
655 	stage->frames.enabled = true;
656 
657 	*token = strtok (NULL, TOK_DELIMINATORS);
658 	stage->frames.speed = atof(*token);
659 
660 	*token = strtok (NULL, TOK_DELIMINATORS);
661 	stage->frames.start = atoi(*token);
662 
663 	*token = strtok (NULL, TOK_DELIMINATORS);
664 	stage->frames.end = atoi(*token);
665 }
666 
rs_stage_offset(rs_stage_t * stage,char ** token)667 void rs_stage_offset (rs_stage_t *stage, char **token)
668 {
669 	*token = strtok (NULL, TOK_DELIMINATORS);
670 	stage->offset.offX = atof(*token);
671 	*token = strtok (NULL, TOK_DELIMINATORS);
672 	stage->offset.offY = atof(*token);
673 }
674 
rs_stage_scroll(rs_stage_t * stage,char ** token)675 void rs_stage_scroll (rs_stage_t *stage, char **token)
676 {
677 	*token = strtok (NULL, TOK_DELIMINATORS);
678 	stage->scroll.typeX = RS_FuncName(*token);
679 	*token = strtok (NULL, TOK_DELIMINATORS);
680 	stage->scroll.speedX = atof(*token);
681 
682 	*token = strtok (NULL, TOK_DELIMINATORS);
683 	stage->scroll.typeY = RS_FuncName(*token);
684 	*token = strtok (NULL, TOK_DELIMINATORS);
685 	stage->scroll.speedY = atof(*token);
686 }
687 
rs_stage_blendfunc(rs_stage_t * stage,char ** token)688 void rs_stage_blendfunc (rs_stage_t *stage, char **token)
689 {
690 	stage->blendfunc.blend = true;
691 
692 	*token = strtok (NULL, TOK_DELIMINATORS);
693 
694 	if (!Q_stricmp (*token, "add"))
695 	{
696 		stage->blendfunc.source = GL_ONE;
697 		stage->blendfunc.dest = GL_ONE;
698 	}
699 	else if (!Q_stricmp (*token, "blend"))
700 	{
701 		stage->blendfunc.source = GL_SRC_ALPHA;
702 		stage->blendfunc.dest = GL_ONE_MINUS_SRC_ALPHA;
703 	}
704 	else if (!Q_stricmp (*token, "filter"))
705 	{
706 		stage->blendfunc.source = GL_ZERO;
707 		stage->blendfunc.dest = GL_SRC_COLOR;
708 	}
709 	else
710 	{
711 		stage->blendfunc.source = RS_BlendID (*token);
712 
713 		*token = strtok (NULL, TOK_DELIMINATORS);
714 		stage->blendfunc.dest = RS_BlendID (*token);
715 	}
716 }
717 
rs_stage_alphashift(rs_stage_t * stage,char ** token)718 void rs_stage_alphashift (rs_stage_t *stage, char **token)
719 {
720 	*token = strtok (NULL, TOK_DELIMINATORS);
721 	stage->alphashift.speed = (float)atof(*token);
722 
723 	*token = strtok (NULL, TOK_DELIMINATORS);
724 	stage->alphashift.min = (float)atof(*token);
725 
726 	*token = strtok (NULL, TOK_DELIMINATORS);
727 	stage->alphashift.max = (float)atof(*token);
728 }
729 
rs_stage_random(rs_stage_t * stage,char ** token)730 void rs_stage_random (rs_stage_t *stage, char **token)
731 {
732 	random_stage_t	*rand = (random_stage_t *)malloc(sizeof(random_stage_t));
733 
734 	stage->rand_stage = rand;
735 	stage->rand_count = 0;
736 
737 	*token = strtok(NULL, TOK_DELIMINATORS);
738 
739 	while (_stricmp (*token, "end"))
740 	{
741 		stage->rand_count++;
742 
743 		strncpy (stage->name, *token, sizeof(stage->name));
744 
745 		stage->texture = NULL;
746 
747 		*token = strtok(NULL, TOK_DELIMINATORS);
748 
749 		if (!_stricmp (*token, "end"))
750 		{
751 			rand->next = NULL;
752 			break;
753 		}
754 
755 		rand->next = (random_stage_t *)malloc(sizeof(random_stage_t));
756 		rand = rand->next;
757 	}
758 }
759 
rs_stage_anim(rs_stage_t * stage,char ** token)760 void rs_stage_anim (rs_stage_t *stage, char **token)
761 {
762 	anim_stage_t	*anim = (anim_stage_t *)malloc(sizeof(anim_stage_t));
763 
764 	*token = strtok (NULL, TOK_DELIMINATORS);
765 	stage->anim_delay = (float)atof(*token);
766 
767 	stage->anim_stage = anim;
768 	stage->last_anim = anim;
769 
770 	*token = strtok(NULL, TOK_DELIMINATORS);
771 
772 	while (_stricmp (*token, "end"))
773 	{
774 		stage->anim_count++;
775 
776 		strncpy (anim->name, *token, sizeof(anim->name));
777 
778 		anim->texture = NULL;
779 
780 		*token = strtok(NULL, TOK_DELIMINATORS);
781 
782 		if (!_stricmp (*token, "end"))
783 		{
784 			anim->next = NULL;
785 			break;
786 		}
787 
788 		anim->next = (anim_stage_t *)malloc(sizeof(anim_stage_t));
789 		anim = anim->next;
790 	}
791 }
792 
rs_stage_depthhack(rs_stage_t * stage,char ** token)793 void rs_stage_depthhack (rs_stage_t *stage, char **token)
794 {
795 	*token = strtok (NULL, TOK_DELIMINATORS);
796 	stage->depthhack = (float)atof(*token);
797 }
798 
rs_stage_envmap(rs_stage_t * stage,char ** token)799 void rs_stage_envmap (rs_stage_t *stage, char **token)
800 {
801 	stage->envmap = true;
802 }
803 
rs_stage_dynamic(rs_stage_t * stage,char ** token)804 void rs_stage_dynamic (rs_stage_t *stage, char **token)
805 {
806 	stage->dynamic = true;
807 }
808 
rs_stage_detail(rs_stage_t * stage,char ** token)809 void rs_stage_detail (rs_stage_t *stage, char **token)
810 {
811 	stage->detail = true;
812 }
813 
rs_stage_nolightmap(rs_stage_t * stage,char ** token)814 void rs_stage_nolightmap (rs_stage_t *stage, char **token)
815 {
816 	stage->lightmap = false;
817 }
818 
rs_stage_alphamask(rs_stage_t * stage,char ** token)819 void rs_stage_alphamask (rs_stage_t *stage, char **token)
820 {
821 	stage->alphamask = true;
822 }
823 
rs_stage_rotate(rs_stage_t * stage,char ** token)824 void rs_stage_rotate (rs_stage_t *stage, char **token)
825 {
826 	*token = strtok (NULL, TOK_DELIMINATORS);
827 	stage->rot_speed = (float)atof(*token);
828 }
829 
rs_stage_origin(rs_stage_t * stage,char ** token)830 void rs_stage_origin (rs_stage_t *stage, char **token)
831 {
832 	*token = strtok (NULL, TOK_DELIMINATORS);
833 	stage->origin[0] = (float)atof(*token);
834 
835 	*token = strtok (NULL, TOK_DELIMINATORS);
836 	stage->origin[1] = (float)atof(*token);
837 
838 	*token = strtok (NULL, TOK_DELIMINATORS);
839 	stage->origin[2] = (float)atof(*token);
840 }
841 
rs_stage_angle(rs_stage_t * stage,char ** token)842 void rs_stage_angle (rs_stage_t *stage, char **token)
843 {
844 	*token = strtok (NULL, TOK_DELIMINATORS);
845 	stage->angle[0] = (float)atof(*token);
846 
847 	*token = strtok (NULL, TOK_DELIMINATORS);
848 	stage->angle[1] = (float)atof(*token);
849 
850 	*token = strtok (NULL, TOK_DELIMINATORS);
851 	stage->angle[2] = (float)atof(*token);
852 }
853 
rs_stage_scale(rs_stage_t * stage,char ** token)854 void rs_stage_scale (rs_stage_t *stage, char **token)
855 {
856 	*token = strtok (NULL, TOK_DELIMINATORS);
857 	stage->scale.typeX = RS_FuncName(*token);
858 	*token = strtok (NULL, TOK_DELIMINATORS);
859 	stage->scale.scaleX = atof(*token);
860 
861 	*token = strtok (NULL, TOK_DELIMINATORS);
862 	stage->scale.typeY = RS_FuncName(*token);
863 	*token = strtok (NULL, TOK_DELIMINATORS);
864 	stage->scale.scaleY = atof(*token);
865 }
866 
rs_stage_alphafunc(rs_stage_t * stage,char ** token)867 void rs_stage_alphafunc (rs_stage_t *stage, char **token)
868 {
869 	*token = strtok (NULL, TOK_DELIMINATORS);
870 
871 	if (!_stricmp (*token, "normal"))
872 		stage->alphafunc = ALPHAFUNC_NORMAL;
873 	else if (!_stricmp (*token, "-normal"))
874 		stage->alphafunc = -ALPHAFUNC_NORMAL;
875 	else if (!_stricmp (*token, "gloss"))
876 		stage->alphafunc = ALPHAFUNC_GLOSS;
877 	else if (!_stricmp (*token, "-gloss"))
878 		stage->alphafunc = -ALPHAFUNC_GLOSS;
879 	else if (!_stricmp (*token, "basic"))
880 		stage->alphafunc = ALPHAFUNC_BASIC;
881 	else if (!_stricmp (*token, "-basic"))
882 		stage->alphafunc = -ALPHAFUNC_BASIC;
883 }
884 
885 static rs_stagekey_t rs_stagekeys[] =
886 {
887 	{	"colormap",		&rs_stage_colormap		},
888 	{	"map",			&rs_stage_map			},
889 	{	"model",		&rs_stage_model			},
890 	{	"scroll",		&rs_stage_scroll		},
891 	{	"offset",		&rs_stage_offset		},
892 	{	"frames",		&rs_stage_frames		},
893 	{	"blendfunc",	&rs_stage_blendfunc		},
894 	{	"alphashift",	&rs_stage_alphashift	},
895 	{	"rand",			&rs_stage_random		},
896 	{	"anim",			&rs_stage_anim			},
897 	{	"envmap",		&rs_stage_envmap		},
898 	{	"depthhack",	&rs_stage_depthhack		},
899 	{	"nolightmap",	&rs_stage_nolightmap	},
900 	{	"alphamask",	&rs_stage_alphamask		},
901 	{	"rotate",		&rs_stage_rotate		},
902 	{	"origin",		&rs_stage_origin		},
903 	{	"angle",		&rs_stage_angle			},
904 	{	"scale",		&rs_stage_scale			},
905 	{	"dynamic",		&rs_stage_dynamic		},
906 	{	"detail",		&rs_stage_detail		},
907 	{	"alphafunc",	&rs_stage_alphafunc		},
908 
909 	{	NULL,			NULL					}
910 };
911 
912 static int num_stagekeys = sizeof (rs_stagekeys) / sizeof(rs_stagekeys[0]) - 1;
913 
914 // =====================================================
915 
rs_script_safe(rscript_t * rs,char ** token)916 void rs_script_safe (rscript_t *rs, char **token)
917 {
918 	rs->dontflush = true;
919 }
920 
rs_script_subdivide(rscript_t * rs,char ** token)921 void rs_script_subdivide (rscript_t *rs, char **token)
922 {
923 	int divsize, p2divsize;
924 
925 	*token = strtok (NULL, TOK_DELIMINATORS);
926 	divsize = atoi (*token);
927 
928 	// cap max & min subdivide sizes
929 	if (divsize > 128)
930 		divsize = 128;
931 	else if (divsize <= 8)
932 		divsize = 8;
933 
934 	// find the next smallest valid ^2 size, if not already one
935 	for (p2divsize = 2; p2divsize <= divsize ; p2divsize <<= 1 );
936 
937 	p2divsize >>= 1;
938 
939 	rs->subdivide = (char)p2divsize;
940 }
941 
rs_script_vertexwarp(rscript_t * rs,char ** token)942 void rs_script_vertexwarp (rscript_t *rs, char **token)
943 {
944 	*token = strtok(NULL, TOK_DELIMINATORS);
945 	rs->warpspeed = atof (*token);
946 	*token = strtok(NULL, TOK_DELIMINATORS);
947 	rs->warpdist = atof (*token);
948 	*token = strtok(NULL, TOK_DELIMINATORS);
949 	rs->warpsmooth = atof (*token);
950 
951 	if (rs->warpsmooth < 0.001f)
952 		rs->warpsmooth = 0.001f;
953 	else if (rs->warpsmooth > 1.0f)
954 		rs->warpsmooth = 1.0f;
955 }
956 
rs_script_lightglare(rscript_t * rs,char ** token)957 void rs_script_lightglare (rscript_t *rs, char **token)
958 {
959 	*token = strtok(NULL, TOK_DELIMINATORS);
960 	rs->glarecolor.red = atoi(*token);
961 	*token = strtok(NULL, TOK_DELIMINATORS);
962 	rs->glarecolor.green = atoi(*token);
963 	*token = strtok(NULL, TOK_DELIMINATORS);
964 	rs->glarecolor.blue = atoi(*token);
965 
966 	rs->glarecolor.enabled = true;
967 }
968 
rs_script_lightglarescript(rscript_t * rs,char ** token)969 void rs_script_lightglarescript (rscript_t *rs, char **token)
970 {
971 	*token = strtok (NULL, TOK_DELIMINATORS);
972 
973 	strncpy (rs->glarescript.name, *token, sizeof(rs->glarescript.name));
974 
975 	rs->glarescript.enabled = true;
976 }
977 
rs_script_lightglaretex(rscript_t * rs,char ** token)978 void rs_script_lightglaretex (rscript_t *rs, char **token)
979 {
980 	*token = strtok (NULL, TOK_DELIMINATORS);
981 
982 	strncpy (rs->glaretexture.name, *token, sizeof(rs->glaretexture.name));
983 
984 	rs->glaretexture.enabled = true;
985 }
rs_script_mirror(rscript_t * rs,char ** token)986 void rs_script_mirror (rscript_t *rs, char **token)
987 {
988 	rs->mirror = true;
989 }
990 
rs_script_model(rscript_t * rs,char ** token)991 void rs_script_model (rscript_t *rs, char **token)
992 {
993 	rs->model = true;
994 }
995 
rs_script_picsize(rscript_t * rs,char ** token)996 void rs_script_picsize (rscript_t *rs, char **token)
997 {
998 	rs->picsize.enable = true;
999 
1000 	*token = strtok(NULL, TOK_DELIMINATORS);
1001 	rs->picsize.width = atof (*token);
1002 
1003 	*token = strtok(NULL, TOK_DELIMINATORS);
1004 	rs->picsize.height = atof (*token);
1005 }
1006 
1007 static rs_scriptkey_t rs_scriptkeys[] =
1008 {
1009 	{	"safe",			&rs_script_safe			},
1010 	{	"subdivide",	&rs_script_subdivide	},
1011 	{	"vertexwarp",	&rs_script_vertexwarp	},
1012 	{	"mirror",		&rs_script_mirror		},
1013 	{	"model",		&rs_script_model		},
1014 	{	"picsize",		&rs_script_picsize		},
1015 	{	"glarecolor",	&rs_script_lightglare	},
1016  	{	"glaretexture", &rs_script_lightglaretex},
1017 	{	"glarescript",	&rs_script_lightglarescript	},
1018 	{	NULL,			NULL					}
1019 };
1020 
1021 static int num_scriptkeys = sizeof (rs_scriptkeys) / sizeof(rs_scriptkeys[0]) - 1;
1022 
1023 // =====================================================
1024 
RS_LoadScript(char * script)1025 void RS_LoadScript(char *script)
1026 {
1027 	qboolean		inscript = false, instage = false;
1028 	char			ignored = 0;
1029 	char			*token, *fbuf, *buf;
1030 	rscript_t		*rs = NULL;
1031 	rs_stage_t		*stage;
1032 	unsigned char	tcmod = 0;
1033 	unsigned int	len, i;
1034 
1035 	len = ri.FS_LoadFile (script, (void **)&fbuf);
1036 
1037 	if (!fbuf || len < 16)
1038 	{
1039 		ri.Con_Printf (PRINT_ALL, "Could not load script %s\n", script);
1040 		return;
1041 	}
1042 
1043 	buf = (char *)malloc(len+1);
1044 	memcpy (buf, fbuf, len);
1045 	buf[len] = 0;
1046 
1047 	ri.FS_FreeFile (fbuf);
1048 
1049 	token = strtok (buf, TOK_DELIMINATORS);
1050 
1051 	while (token != NULL)
1052 	{
1053 		if (!_stricmp (token, "/*") || !_stricmp (token, "["))
1054 			ignored++;
1055 		else if (!_stricmp (token, "*/") || !_stricmp (token, "]"))
1056 			ignored--;
1057 
1058 		if (!_stricmp (token, "//"))
1059 		{
1060 			//IGNORE
1061 		}
1062 		else if (!inscript && !ignored)
1063 		{
1064 			if (!_stricmp (token, "{"))
1065 			{
1066 				inscript = true;
1067 			}
1068 			else
1069 			{
1070 				rs = RS_FindScript(token);
1071 
1072 				if (rs)
1073 					RS_FreeScript(rs);
1074 
1075 				rs = RS_NewScript(token);
1076 			}
1077 		}
1078 		else if (inscript && !ignored)
1079 		{
1080 			if (!_stricmp(token, "}"))
1081 			{
1082 				if (instage)
1083 				{
1084 					instage = false;
1085 				}
1086 				else
1087 				{
1088 					inscript = false;
1089 				}
1090 			}
1091 			else if (!_stricmp(token, "{"))
1092 			{
1093 				if (!instage) {
1094 					instage = true;
1095 					stage = RS_NewStage(rs);
1096 				}
1097 			}
1098 			else
1099 			{
1100 				if (instage && !ignored)
1101 				{
1102 					for (i = 0; i < num_stagekeys; i++) {
1103 						if (!_stricmp (rs_stagekeys[i].stage, token))
1104 						{
1105 							rs_stagekeys[i].func (stage, &token);
1106 							break;
1107 						}
1108 					}
1109 				}
1110 				else
1111 				{
1112 					for (i = 0; i < num_scriptkeys; i++)
1113 					{
1114 						if (!_stricmp (rs_scriptkeys[i].script, token))
1115 						{
1116 							rs_scriptkeys[i].func (rs, &token);
1117 							break;
1118 						}
1119 					}
1120 				}
1121 			}
1122 		}
1123 
1124 		token = strtok (NULL, TOK_DELIMINATORS);
1125 	}
1126 
1127 	free(buf);
1128 }
1129 
RS_ScanPathForScripts(void)1130 void RS_ScanPathForScripts (void)
1131 {
1132 	char			script[MAX_OSPATH];
1133 	char			dirstring[1024], *c;
1134 	int			npakscripts, i;
1135 	char			*dir = ri.FS_Gamedir();
1136 	char			*basedir = va("./%s", BASEDIRNAME);
1137 	char			**pakscripts;
1138 	char			*currentScript;
1139 	void			*delstuff;
1140 
1141 	if (pakscripts = ri.FS_ListPak("scripts/", &npakscripts))
1142 	{
1143 		for (i=0; i<npakscripts; i++)
1144 		{
1145 			int len;
1146 			char *p = NULL;
1147 
1148 			currentScript = pakscripts[i];
1149 
1150 			len = strlen(currentScript);
1151 
1152 			//can never work
1153 			if (len<8)
1154 				continue;
1155 
1156 			// /scripts/ directory only
1157 			if (	toupper(currentScript[0])!='S'
1158 				||	toupper(currentScript[1])!='C'
1159 				||	toupper(currentScript[2])!='R'
1160 				||	toupper(currentScript[3])!='I'
1161 				||	toupper(currentScript[4])!='P'
1162 				||	toupper(currentScript[5])!='T'
1163 				||	toupper(currentScript[6])!='S'
1164 				||	currentScript[7]!='/'
1165 				)
1166 				continue;
1167 
1168 			//no subdirs, only used per specific map
1169 			p = strstr(&currentScript[8], "/");
1170 			if (p)
1171 				continue;
1172 
1173 			//load .rscript files
1174 
1175 			if (	currentScript[len-8]!='.'
1176 				||	toupper(currentScript[len-7])!='R'
1177 				||	toupper(currentScript[len-6])!='S'
1178 				||	toupper(currentScript[len-5])!='C'
1179 				||	toupper(currentScript[len-4])!='R'
1180 				||	toupper(currentScript[len-3])!='I'
1181 				||	toupper(currentScript[len-2])!='P'
1182 				||	toupper(currentScript[len-1])!='T'
1183 				)
1184 				continue;
1185 
1186 			RS_LoadScript (currentScript);
1187 		}
1188 	}
1189 
1190 	if (strcmp(dir,basedir))
1191 	{
1192 		Com_sprintf (dirstring, sizeof(dirstring), "%s/scripts/*.rscript", basedir);
1193 		currentScript = Sys_FindFirst (dirstring, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM);
1194 
1195 		if (currentScript != NULL)
1196 		{
1197 			do
1198 			{
1199 				if (currentScript[0] == '.')
1200 					continue;
1201 
1202 				c = COM_SkipPath(currentScript);
1203 				Com_sprintf(script, MAX_OSPATH, "scripts/%s", c);
1204 				RS_LoadScript (script);
1205 			}
1206 			while ((currentScript = Sys_FindNext( 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM)) != NULL);
1207 		}
1208 		Sys_FindClose ();
1209 
1210 	}
1211 
1212 	Com_sprintf (dirstring, sizeof(dirstring), "%s/scripts/*.rscript", dir);
1213 	currentScript = Sys_FindFirst (dirstring, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM);
1214 	if (currentScript != NULL)
1215 	{
1216 		do
1217 		{
1218 			if (currentScript[0] == '.')
1219 				continue;
1220 
1221 			c = COM_SkipPath(currentScript);
1222 			Com_sprintf(script, MAX_OSPATH, "scripts/%s", c);
1223 			RS_LoadScript (script);
1224 		}
1225 		while ((currentScript = Sys_FindNext( 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM)) != NULL);
1226 	}
1227 	Sys_FindClose ();
1228 }
1229 
RS_RotateST(float * os,float * ot,float degrees,msurface_t * fa)1230 __inline void RS_RotateST (float *os, float *ot, float degrees, msurface_t *fa)
1231 {
1232 	float cost = cos(degrees), sint = sin(degrees);
1233 	float is = *os, it = *ot, c_s, c_t;
1234 
1235 	c_s = fa->c_s - (int)fa->c_s;
1236 	c_t = fa->c_t - (int)fa->c_t;
1237 /*
1238 	*os = cost * (is - 0.5f) - sint * (it - 0.5f) + 0.5f;
1239 	*ot = cost * (it - 0.5f) + sint * (is - 0.5f) + 0.5f;
1240 */
1241 	*os = cost * (is - c_s) + sint * (c_t - it) + c_s;
1242 	*ot = cost * (it - c_t) + sint * (is - c_s) + c_t;
1243 
1244 }
1245 
1246 
RS_RotateST2(float * os,float * ot,float degrees)1247 __inline void RS_RotateST2 (float *os, float *ot, float degrees)
1248 {
1249 	float cost = cos(degrees), sint = sin(degrees);
1250 	float is = *os, it = *ot;
1251 
1252 	*os = cost * (is - 0.5) + sint * (0.5 - it) + 0.5;
1253 	*ot = cost * (it - 0.5) + sint * (is - 0.5) + 0.5;
1254 }
1255 
RS_SetEnvmap(vec3_t v,float * os,float * ot)1256 void RS_SetEnvmap (vec3_t v, float *os, float *ot)
1257 {
1258 	vec3_t vert;
1259 
1260 	vert[0] = v[0]*r_world_matrix[0]+v[1]*r_world_matrix[4]+v[2]*r_world_matrix[8] +r_world_matrix[12];
1261 	vert[1] = v[0]*r_world_matrix[1]+v[1]*r_world_matrix[5]+v[2]*r_world_matrix[9] +r_world_matrix[13];
1262 	vert[2] = v[0]*r_world_matrix[2]+v[1]*r_world_matrix[6]+v[2]*r_world_matrix[10]+r_world_matrix[14];
1263 
1264 	VectorNormalize (vert);
1265 
1266 	*os = vert[0];
1267 	*ot = vert[1];
1268 }
1269 
RS_ScaleTexcoords(rs_stage_t * stage,float * os,float * ot)1270 void RS_ScaleTexcoords (rs_stage_t *stage, float *os, float *ot)
1271 {
1272 	float	txm = 0, tym = 0;
1273 
1274 	// scale
1275 	if (stage->scale.scaleX)
1276 	{
1277 		switch (stage->scale.typeX)
1278 		{
1279 		case 0:	// static
1280 			*os *= stage->scale.scaleX;
1281 			break;
1282 		case 1:	// sine
1283 			*os *= stage->scale.scaleX*sin(rs_realtime*0.05);
1284 			break;
1285 		case 2:	// cosine
1286 			*os *= stage->scale.scaleX*cos(rs_realtime*0.05);
1287 			break;
1288 		}
1289 	}
1290 
1291 	if (stage->scale.scaleY)
1292 	{
1293 		switch (stage->scale.typeY)
1294 		{
1295 		case 0:	// static
1296 			*ot *= stage->scale.scaleY;
1297 			break;
1298 		case 1:	// sine
1299 			*ot *= stage->scale.scaleY*sin(rs_realtime*0.05);
1300 			break;
1301 		case 2:	// cosine
1302 			*ot *= stage->scale.scaleY*cos(rs_realtime*0.05);
1303 			break;
1304 		}
1305 	}
1306 }
1307 
RS_SetTexcoords(rs_stage_t * stage,float * os,float * ot,msurface_t * fa)1308 void RS_SetTexcoords (rs_stage_t *stage, float *os, float *ot, msurface_t *fa)
1309 {
1310 	if (fa->flags & SURF_DRAWTURB)
1311 	{
1312 		*os *= 0.015625; //(1/64)
1313 		*ot *= 0.015625; //(1/64)
1314 	}
1315 
1316 	*os += stage->offset.offX;
1317 	*ot += stage->offset.offY;
1318 
1319 	// rotate
1320 	if (stage->rot_speed)
1321 	{
1322 		ri.Con_Printf( PRINT_DEVELOPER, "offset TCx=%f y=%f\n", *os, *ot );
1323 		RS_RotateST (os, ot, -stage->rot_speed * rs_realtime * 0.0087266388888888888888888888888889, fa);
1324 	}
1325 
1326 	RS_ScaleTexcoords(stage, os, ot);
1327 
1328 	if (stage->rot_speed)
1329 	{
1330 		*os -= stage->offset.offX;
1331 		*ot -= stage->offset.offY;
1332 	}
1333 }
1334 
RS_SetTexcoords2D(rs_stage_t * stage,float * os,float * ot)1335 void RS_SetTexcoords2D (rs_stage_t *stage, float *os, float *ot)
1336 {
1337 	float	txm = 0, tym = 0;
1338 
1339 	*os += stage->offset.offX;
1340 	*ot += stage->offset.offY;
1341 
1342 	// rotate
1343 	if (stage->rot_speed)
1344 		RS_RotateST2 (os, ot, -stage->rot_speed * rs_realtime * 0.0087266388888888888888888888888889);
1345 
1346 	// scale
1347 	if (stage->scale.scaleX)
1348 	{
1349 		switch (stage->scale.typeX)
1350 		{
1351 		case 0:	// static
1352 			*os *= stage->scale.scaleX;
1353 			break;
1354 		case 1:	// sine
1355 			*os *= stage->scale.scaleX*sin(rs_realtime*0.05);
1356 			break;
1357 		case 2:	// cosine
1358 			*os *= stage->scale.scaleX*cos(rs_realtime*0.05);
1359 			break;
1360 		}
1361 	}
1362 
1363 	if (stage->scale.scaleY)
1364 	{
1365 		switch (stage->scale.typeY)
1366 		{
1367 		case 0:	// static
1368 			*ot *= stage->scale.scaleY;
1369 			break;
1370 		case 1:	// sine
1371 			*ot *= stage->scale.scaleY*sin(rs_realtime*0.05);
1372 			break;
1373 		case 2:	// cosine
1374 			*ot *= stage->scale.scaleY*cos(rs_realtime*0.05);
1375 			break;
1376 		}
1377 
1378 	}
1379 
1380 	if (stage->scroll.speedX)
1381 	{
1382 		switch(stage->scroll.typeX)
1383 		{
1384 			case 0:	// static
1385 				txm=rs_realtime*stage->scroll.speedX;
1386 				break;
1387 			case 1:	// sine
1388 				txm=sin(rs_realtime*stage->scroll.speedX);
1389 				break;
1390 			case 2:	// cosine
1391 				txm=cos(rs_realtime*stage->scroll.speedX);
1392 				break;
1393 		}
1394 	}
1395 	else
1396 		txm=0;
1397 
1398 	if (stage->scroll.speedY)
1399 	{
1400 		switch(stage->scroll.typeY)
1401 		{
1402 			case 0:	// static
1403 				tym=rs_realtime*stage->scroll.speedY;
1404 				break;
1405 			case 1:	// sine
1406 				tym=sin(rs_realtime*stage->scroll.speedY);
1407 				break;
1408 			case 2:	// cosine
1409 				tym=cos(rs_realtime*stage->scroll.speedY);
1410 				break;
1411 		}
1412 	}
1413 	else
1414 		tym=0;
1415 
1416 	*os += txm;
1417 	*ot += tym;
1418 }
1419 
RS_AlphaFunc(int alphafunc,float alpha,vec3_t normal,vec3_t org)1420 float RS_AlphaFunc (int alphafunc, float alpha, vec3_t normal, vec3_t org)
1421 {
1422 	vec3_t	forward, dir;
1423 	float temp;
1424 
1425 	if (!abs(alphafunc))
1426 		goto endalpha;
1427 
1428 	if (alphafunc == ALPHAFUNC_GLOSS)
1429 	{
1430 		//glossmap stuff here...
1431 	}
1432 	else if (alphafunc == ALPHAFUNC_NORMAL)
1433 	{
1434 		VectorSubtract(org, r_newrefdef.vieworg, dir);
1435 		VectorNormalize(dir);
1436 		alpha *= fabs(cutDot(dir, normal));
1437 	}
1438 
1439 endalpha:
1440 
1441 	if (alpha<0) alpha = 0;
1442 	if (alpha>1) alpha = 1;
1443 	if (alphafunc<0) alpha = 1-alpha;
1444 
1445 	return alpha;
1446 }
1447 
RS_AlphaFuncAlias(int alphafunc,float alpha,vec3_t normal,vec3_t org)1448 float RS_AlphaFuncAlias (int alphafunc, float alpha, vec3_t normal, vec3_t org)
1449 {
1450 	vec3_t	forward;
1451 	float oldalpha = alpha;
1452 
1453 	if (!abs(alphafunc))
1454 		goto endalpha;
1455 
1456 	if (alphafunc == ALPHAFUNC_GLOSS)
1457 	{
1458 		//glossmap stuff here...
1459 	}
1460 
1461 endalpha:
1462 
1463 	if (alpha<0) alpha = 0;
1464 	if (alpha>1) alpha = 1;
1465 	if (alphafunc<0) alpha = 1-alpha;
1466 
1467 	return alpha;
1468 }
1469 
1470 image_t *R_TextureAnimation (mtexinfo_t *tex);
surfaceScript(msurface_t * surf)1471 rscript_t	*surfaceScript(msurface_t *surf)
1472 {
1473 	image_t *image = R_TextureAnimation( surf->texinfo );
1474 
1475 	if (image && image->script)
1476 	{
1477 		rscript_t *rs = image->script;
1478 
1479 		RS_ReadyScript(rs);
1480 
1481 		return rs;
1482 	}
1483 	return NULL;
1484 }
1485 
1486 qboolean lightmaptoggle;
ToggleLightmap(qboolean toggle)1487 void ToggleLightmap (qboolean toggle)
1488 {
1489 	if (toggle==lightmaptoggle)
1490 		return;
1491 
1492 	lightmaptoggle = toggle;
1493 	if (toggle)
1494 	{
1495 		SetVertexOverbrights(false);
1496 		GL_EnableMultitexture( true );
1497 		SetLightingMode ();
1498 	}
1499 	else
1500 	{
1501 		GL_EnableMultitexture( false );
1502 		SetVertexOverbrights(true);
1503 	}
1504 }
1505 
RS_DrawSurface(msurface_t * surf,qboolean lightmap)1506 void RS_DrawSurface (msurface_t *surf, qboolean lightmap)
1507 {
1508 	glpoly_t	*p;
1509 	float		*v;
1510 	int			i, nv = surf->polys->numverts;
1511 	vec3_t		wv, vieworg, vectors[3];
1512 	rscript_t	*rs = surfaceScript(surf);
1513 	rs_stage_t	*stage = rs->stage;
1514 	float		os, ot, alpha;
1515 	float		scale, time = rs_realtime * rs->warpspeed, txm, tym;
1516 	qboolean	depthmaskscript = stage->has_alpha;
1517 
1518 
1519 	//for envmap by normals
1520 	AngleVectors (r_newrefdef.viewangles, vectors[0], vectors[1], vectors[2]);
1521 
1522 	if (depthmaskscript)
1523 		qglDepthMask(false);
1524 
1525 	if (!lightmap)
1526 		SetVertexOverbrights(true);
1527 	else
1528 		lightmaptoggle = true;
1529 
1530 	do
1531 	{
1532 		if (stage->detail && !rs_detail->value)
1533 			continue;
1534 
1535 		if (lightmap && stage->lightmap)
1536 		{
1537 
1538 			ToggleLightmap(true);
1539 			GL_ShadeModel (GL_FLAT);
1540 
1541 			if (stage->colormap.enabled)
1542 				qglDisable (GL_TEXTURE_2D);
1543 			else if (stage->dynamic)
1544 			{
1545 				if (surf->dynamic.enabled && surf->dynamic.image)
1546 					GL_MBind (GL_TEXTURE0, surf->dynamic.image->texnum);
1547 				else
1548 				{
1549 					setRenderDynamic ();
1550 					GL_MBind (GL_TEXTURE0, r_dynamicimage->texnum);
1551 				}
1552 			}
1553 			else if (stage->rand_count)
1554 				GL_MBind (GL_TEXTURE0, RS_Random(stage, surf));
1555 			else if (stage->anim_count)
1556 				GL_MBind (GL_TEXTURE0, RS_Animate(stage));
1557 			else
1558 				GL_MBind (GL_TEXTURE0, stage->texture->texnum);
1559 		}
1560 		else
1561 		{
1562 			if (!stage->lightmap && lightmap)
1563 				ToggleLightmap(false);
1564 			GL_ShadeModel (GL_SMOOTH);
1565 
1566 			if (stage->colormap.enabled)
1567 				qglDisable (GL_TEXTURE_2D);
1568 			else if (stage->dynamic)
1569 			{
1570 				if (surf->dynamic.enabled && surf->dynamic.image)
1571 					GL_Bind (surf->dynamic.image->texnum);
1572 				else
1573 				{
1574 					setRenderDynamic ();
1575 					GL_Bind (r_dynamicimage->texnum);
1576 				}
1577 			}
1578 			else if (stage->rand_count)
1579 				GL_Bind (RS_Random(stage, surf));
1580 			else if (stage->anim_count)
1581 				GL_Bind (RS_Animate(stage));
1582 			else
1583 				GL_Bind (stage->texture->texnum);
1584 		}
1585 
1586 		if (stage->blendfunc.blend)
1587 		{
1588 			GL_BlendFunction(stage->blendfunc.source, stage->blendfunc.dest);
1589 			GLSTATE_ENABLE_BLEND
1590 		}
1591 		else if (surf->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66) && !stage->alphamask)
1592 		{
1593 			GL_BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1594 			GLSTATE_ENABLE_BLEND
1595 		}
1596 		else
1597 		{
1598 			GLSTATE_DISABLE_BLEND
1599 		}
1600 
1601 		// sane defaults
1602 		alpha = 1.0f;
1603 
1604 		if (stage->alphashift.min || stage->alphashift.speed)
1605 		{
1606 			if (!stage->alphashift.speed && stage->alphashift.min > 0)
1607 			{
1608 				alpha = stage->alphashift.min;
1609 			}
1610 			else if (stage->alphashift.speed)
1611 			{
1612 				alpha = sin (rs_realtime * stage->alphashift.speed);
1613 				alpha = (alpha + 1.0)*0.5f;
1614 				if (alpha > stage->alphashift.max)
1615 					alpha = stage->alphashift.max;
1616 				if (alpha < stage->alphashift.min)
1617 					alpha = stage->alphashift.min;
1618 			}
1619 		}
1620 
1621 		if (surf->texinfo->flags & SURF_TRANS33 && surf->texinfo->flags & SURF_TRANS66)
1622 			alpha *= DIV254BY255;
1623 		else if (surf->texinfo->flags & SURF_TRANS33)
1624 			alpha *= 0.33333;
1625 		else if (surf->texinfo->flags & SURF_TRANS66)
1626 			alpha *= 0.66666;
1627 
1628 		if (stage->scroll.speedX)
1629 		{
1630 			switch (stage->scroll.typeX)
1631 			{
1632 			case 0:	// static
1633 				txm = rs_realtime*stage->scroll.speedX;
1634 				break;
1635 			case 1:	// sine
1636 				txm = sin (rs_realtime*stage->scroll.speedX);
1637 				break;
1638 			case 2:	// cosine
1639 				txm = cos (rs_realtime*stage->scroll.speedX);
1640 				break;
1641 			}
1642 		}
1643 		else
1644 			txm=0;
1645 
1646 		if (stage->scroll.speedY)
1647 		{
1648 			switch (stage->scroll.typeY)
1649 			{
1650 			case 0:	// static
1651 				tym = rs_realtime*stage->scroll.speedY;
1652 				break;
1653 			case 1:	// sine
1654 				tym = sin (rs_realtime*stage->scroll.speedY);
1655 				break;
1656 			case 2:	// cosine
1657 				tym = cos (rs_realtime*stage->scroll.speedY);
1658 				break;
1659 			}
1660 		} else
1661 			tym=0;
1662 
1663 		if (surf->texinfo->flags & SURF_FLOWING)
1664 		{
1665 			float scroll;
1666 
1667 			scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
1668 			if(scroll == 0.0)
1669 				scroll = -64.0;
1670 
1671 			txm += scroll;
1672 		}
1673 
1674 		qglColor4f (1, 1, 1, alpha);
1675 
1676 		if (stage->alphamask)
1677 		{
1678 			GLSTATE_ENABLE_ALPHATEST
1679 		}
1680 		else
1681 		{
1682 			GLSTATE_DISABLE_ALPHATEST
1683 		}
1684 
1685 		if (rs->subdivide || surf->flags & SURF_DRAWTURB)
1686 		{
1687 			glpoly_t *bp;
1688 			int i;
1689 
1690 			for (bp = surf->polys; bp; bp = bp->next)
1691 			{
1692 				p = bp;
1693 
1694 				qglBegin(GL_TRIANGLE_FAN);
1695 				for (i = 0, v = p->verts[0]; i < p->numverts; i++, v += VERTEXSIZE)
1696 				{
1697 
1698 					if (stage->envmap)
1699 					{
1700 						RS_SetEnvmap (v, &os, &ot);
1701 						//move by normal & position
1702 						os-=DotProduct (surf->plane->normal, vectors[1] ) + (r_newrefdef.vieworg[0]-r_newrefdef.vieworg[1]+r_newrefdef.vieworg[2])*0.0025;
1703 						ot+=DotProduct (surf->plane->normal, vectors[2] ) + (-r_newrefdef.vieworg[0]+r_newrefdef.vieworg[1]-r_newrefdef.vieworg[2])*0.0025;
1704 
1705 						if (surf->texinfo->flags & SURF_FLOWING)
1706 							txm = tym = 0;
1707 					}
1708 					else if (fabs(stage->depthhack))
1709 					{
1710 						vec3_t vec;
1711 
1712 						VectorSubtract(p->center, r_newrefdef.vieworg, vec);
1713 						VectorNormalize(vec);
1714 
1715 						os = v[3] + cutDot(vec, surf->texinfo->vecs[0])*stage->depthhack*0.01;
1716 						ot = v[4] + cutDot(vec, surf->texinfo->vecs[1])*stage->depthhack*0.01;
1717 					}
1718 					else
1719 					{
1720 					/*	if (surf->dynamic.enabled)
1721 						{
1722 							vec3_t org;
1723 
1724 							VectorSubtract ( v, surf->center, org );
1725 							os = DotProduct ( org, surf->plane->normal ) + 0.5f;
1726 							ot = DotProduct ( org, surf->plane->normal ) + 0.5f;
1727 						}
1728 						else*/
1729 						{
1730 							os = v[3];
1731 							ot = v[4];
1732 						}
1733 					}
1734 					RS_SetTexcoords (stage, &os, &ot, surf);
1735 
1736 					if (stage->lightmap && lightmap && !stage->colormap.enabled )
1737 					{
1738 						qglMTexCoord2fSGIS(GL_TEXTURE0, os+txm, ot+tym);
1739 						qglMTexCoord2fSGIS(GL_TEXTURE1, v[5], v[6]);
1740 					}
1741 					else
1742 					{
1743 						float red=255, green=255, blue=255;
1744 
1745 						if (stage->lightmap && p->vertexlight)
1746 						{
1747 							red = p->vertexlight[i*3+0]/255.0f;
1748 							green = p->vertexlight[i*3+1]/255.0f;
1749 							blue = p->vertexlight[i*3+2]/255.0f;
1750 						}
1751 
1752 						if (stage->colormap.enabled)
1753 						{
1754 							red *= stage->colormap.red/255.0f;
1755 							green *= stage->colormap.green/255.0f;
1756 							blue *= stage->colormap.blue/255.0f;
1757 						}
1758 
1759 						alpha = RS_AlphaFunc(stage->alphafunc, alpha, surf->plane->normal, p->center);
1760 						if (red>1)red=1; if (red<0) red = 0;
1761 						if (green>1)green=1; if (green<0) green = 0;
1762 						if (blue>1)blue=1; if (blue<0) blue = 0;
1763 
1764 						qglColor4f (red, green, blue, alpha);
1765 
1766 						if (!stage->colormap.enabled)
1767 							qglTexCoord2f (os+txm, ot+tym);
1768 					}
1769 
1770 					if (!rs->warpsmooth)
1771 						qglVertex3fv (v);
1772 					else
1773 					{
1774 						scale = rs->warpdist * sin(v[0]*rs->warpsmooth+time)*sin(v[1]*rs->warpsmooth+time)*sin(v[2]*rs->warpsmooth+time);
1775 						VectorMA (v, scale, surf->plane->normal, wv);
1776 						qglVertex3fv (wv);
1777 					}
1778 				}
1779 				qglEnd();
1780 			}
1781 		}
1782 		else
1783 		{
1784 			for (p = surf->polys; p; p = p->chain)
1785 			{
1786 				qglBegin (GL_TRIANGLE_FAN);
1787 
1788 				for (i = 0, v = p->verts[0]; i < nv; i++, v += VERTEXSIZE)
1789 				{
1790 
1791 					if (stage->envmap)
1792 					{
1793 						RS_SetEnvmap (v, &os, &ot);
1794 						//move by normal & position
1795 						os-=DotProduct (surf->plane->normal, vectors[1] ) + (r_newrefdef.vieworg[0]-r_newrefdef.vieworg[1]+r_newrefdef.vieworg[2])*0.0025;
1796 						ot+=DotProduct (surf->plane->normal, vectors[2] ) + (-r_newrefdef.vieworg[0]+r_newrefdef.vieworg[1]-r_newrefdef.vieworg[2])*0.0025;
1797 
1798 						if (surf->texinfo->flags & SURF_FLOWING)
1799 							txm = tym = 0;
1800 					}
1801 					else if (fabs(stage->depthhack))
1802 					{
1803 						vec3_t vec;
1804 
1805 						VectorSubtract(p->center, r_newrefdef.vieworg, vec);
1806 						VectorNormalize(vec);
1807 
1808 						os = v[3] + cutDot(vec, surf->texinfo->vecs[0])*stage->depthhack*0.01;
1809 						ot = v[4] + cutDot(vec, surf->texinfo->vecs[1])*stage->depthhack*0.01;
1810 					}
1811 					else
1812 					{
1813 						os = v[3];
1814 						ot = v[4];
1815 					}
1816 					RS_SetTexcoords (stage, &os, &ot, surf);
1817 
1818 					if (stage->lightmap && lightmap && !stage->colormap.enabled )
1819 					{
1820 						qglMTexCoord2fSGIS(GL_TEXTURE0, os+txm, ot+tym);
1821 						qglMTexCoord2fSGIS(GL_TEXTURE1, v[5], v[6]);
1822 					}
1823 					else
1824 					{
1825 						float red=255, green=255, blue=255;
1826 
1827 						if (stage->lightmap && p->vertexlight)
1828 						{
1829 							red = p->vertexlight[i*3+0]/255.0f;
1830 							green = p->vertexlight[i*3+1]/255.0f;
1831 							blue = p->vertexlight[i*3+2]/255.0f;
1832 						}
1833 
1834 						if (stage->colormap.enabled)
1835 						{
1836 							red *= stage->colormap.red/255.0f;
1837 							green *= stage->colormap.green/255.0f;
1838 							blue *= stage->colormap.blue/255.0f;
1839 						}
1840 
1841 						alpha = RS_AlphaFunc(stage->alphafunc, alpha, surf->plane->normal, v);
1842 						if (red>1)red=1; if (red<0) red = 0;
1843 						if (green>1)green=1; if (green<0) green = 0;
1844 						if (blue>1)blue=1; if (blue<0) blue = 0;
1845 
1846 						qglColor4f (red, green, blue, alpha);
1847 
1848 						qglTexCoord2f (os+txm, ot+tym);
1849 					}
1850 
1851 					if (!rs->warpsmooth)
1852 						qglVertex3fv (v);
1853 					else
1854 					{
1855 						scale = rs->warpdist * sin(v[0]*rs->warpsmooth+time)*sin(v[1]*rs->warpsmooth+time)*sin(v[2]*rs->warpsmooth+time);
1856 						VectorMA (v, scale, surf->plane->normal, wv);
1857 						qglVertex3fv (wv);
1858 					}
1859 				}
1860 
1861 				qglEnd ();
1862 
1863 			}
1864 		}
1865 
1866 		qglColor4f(1,1,1,1);
1867 		if (stage->colormap.enabled)
1868 			qglEnable (GL_TEXTURE_2D);
1869 
1870 	} while (stage = stage->next);
1871 
1872 	if (!lightmap)
1873 		SetVertexOverbrights(false);
1874 	else
1875 		ToggleLightmap(true);
1876 
1877 	GLSTATE_DISABLE_BLEND
1878 	GLSTATE_DISABLE_ALPHATEST
1879 	GLSTATE_DISABLE_TEXGEN
1880 	GL_ShadeModel (GL_SMOOTH);
1881 
1882 	if (depthmaskscript)
1883 		qglDepthMask(true);
1884 }
1885 
1886 //for special cases only
RS_DrawSurfaceTexture(msurface_t * surf,rscript_t * rs)1887 void RS_DrawSurfaceTexture (msurface_t *surf, rscript_t *rs)
1888 {
1889 	glpoly_t	*p;
1890 	float		*v;
1891 	int			i, nv;
1892 	vec3_t		wv, vieworg, vectors[3];
1893 	rs_stage_t	*stage;
1894 	float		os, ot, alpha;
1895 	float		scale, time, txm, tym;
1896 
1897 	if (!rs)
1898 		return;
1899 
1900 	nv = surf->polys->numverts;
1901 	stage = rs->stage;
1902 	time = rs_realtime * rs->warpspeed;
1903 
1904 	//for envmap by normals
1905 	AngleVectors (r_newrefdef.viewangles, vectors[0], vectors[1], vectors[2]);
1906 
1907 	SetVertexOverbrights(true);
1908 
1909 	do
1910 	{
1911 		if (stage->detail && !rs_detail->value)
1912 			continue;
1913 
1914 		if (stage->colormap.enabled)
1915 			qglDisable (GL_TEXTURE_2D);
1916 		else if (stage->dynamic)
1917 		{
1918 			if (surf->dynamic.enabled && surf->dynamic.image)
1919 				GL_Bind (surf->dynamic.image->texnum);
1920 			else
1921 			{
1922 				setRenderDynamic ();
1923 				GL_Bind (r_dynamicimage->texnum);
1924 			}
1925 		}
1926 		else if (stage->rand_count)
1927 			GL_Bind (RS_Random(stage, surf));
1928 		else if (stage->anim_count)
1929 			GL_Bind (RS_Animate(stage));
1930 		else
1931 			GL_Bind (stage->texture->texnum);
1932 
1933 		if (stage->blendfunc.blend)
1934 		{
1935 			GL_BlendFunction(stage->blendfunc.source, stage->blendfunc.dest);
1936 			GLSTATE_ENABLE_BLEND
1937 		}
1938 		else if (surf->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66) && !stage->alphamask)
1939 		{
1940 			GL_BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1941 			GLSTATE_ENABLE_BLEND
1942 		}
1943 		else
1944 		{
1945 			GLSTATE_DISABLE_BLEND
1946 		}
1947 
1948 		// sane defaults
1949 		alpha = 1.0f;
1950 
1951 		if (stage->alphashift.min || stage->alphashift.speed)
1952 		{
1953 			if (!stage->alphashift.speed && stage->alphashift.min > 0)
1954 			{
1955 				alpha = stage->alphashift.min;
1956 			}
1957 			else if (stage->alphashift.speed)
1958 			{
1959 				alpha = sin (rs_realtime * stage->alphashift.speed);
1960 				alpha = (alpha + 1)*0.5f;
1961 				if (alpha > stage->alphashift.max)
1962 					alpha = stage->alphashift.max;
1963 				if (alpha < stage->alphashift.min)
1964 					alpha = stage->alphashift.min;
1965 			}
1966 		}
1967 
1968 		if (stage->scroll.speedX)
1969 		{
1970 			switch (stage->scroll.typeX)
1971 			{
1972 			case 0:	// static
1973 				txm = rs_realtime*stage->scroll.speedX;
1974 				break;
1975 			case 1:	// sine
1976 				txm = sin (rs_realtime*stage->scroll.speedX);
1977 				break;
1978 			case 2:	// cosine
1979 				txm = cos (rs_realtime*stage->scroll.speedX);
1980 				break;
1981 			}
1982 		}
1983 		else
1984 			txm=0;
1985 
1986 		if (stage->scroll.speedY)
1987 		{
1988 			switch (stage->scroll.typeY)
1989 			{
1990 			case 0:	// static
1991 				tym = rs_realtime*stage->scroll.speedY;
1992 				break;
1993 			case 1:	// sine
1994 				tym = sin (rs_realtime*stage->scroll.speedY);
1995 				break;
1996 			case 2:	// cosine
1997 				tym = cos (rs_realtime*stage->scroll.speedY);
1998 				break;
1999 			}
2000 		} else
2001 			tym=0;
2002 
2003 		qglColor4f (1, 1, 1, alpha);
2004 
2005 		if (stage->alphamask)
2006 		{
2007 			GLSTATE_ENABLE_ALPHATEST
2008 		}
2009 		else
2010 		{
2011 			GLSTATE_DISABLE_ALPHATEST
2012 		}
2013 
2014 		if (rs->subdivide || surf->flags & SURF_DRAWTURB)
2015 		{
2016 			glpoly_t *bp;
2017 			int i;
2018 
2019 			for (bp = surf->polys; bp; bp = bp->next)
2020 			{
2021 				p = bp;
2022 
2023 				qglBegin(GL_TRIANGLE_FAN);
2024 				for (i = 0, v = p->verts[0]; i < p->numverts; i++, v += VERTEXSIZE)
2025 				{
2026 					if (stage->envmap)
2027 					{
2028 						RS_SetEnvmap (v, &os, &ot);
2029 						//move by normal & position
2030 						os-=DotProduct (surf->plane->normal, vectors[1] ) + (r_newrefdef.vieworg[0]-r_newrefdef.vieworg[1]+r_newrefdef.vieworg[2])*0.0025;
2031 						ot+=DotProduct (surf->plane->normal, vectors[2] ) + (-r_newrefdef.vieworg[0]+r_newrefdef.vieworg[1]-r_newrefdef.vieworg[2])*0.0025;
2032 
2033 						if (surf->texinfo->flags & SURF_FLOWING)
2034 							txm = tym = 0;
2035 					}
2036 					else if (fabs(stage->depthhack))
2037 					{
2038 						vec3_t vec;
2039 
2040 						VectorSubtract(p->center, r_newrefdef.vieworg, vec);
2041 						VectorNormalize(vec);
2042 
2043 						os = v[3] + cutDot(vec, surf->texinfo->vecs[0])*stage->depthhack*0.01;
2044 						ot = v[4] + cutDot(vec, surf->texinfo->vecs[1])*stage->depthhack*0.01;
2045 					}
2046 					else
2047 					{
2048 						os = v[3];
2049 						ot = v[4];
2050 					}
2051 					RS_SetTexcoords (stage, &os, &ot, surf);
2052 					{
2053 						float red=255, green=255, blue=255;
2054 
2055 						if (stage->lightmap && p->vertexlight)
2056 						{
2057 							red = p->vertexlight[i*3+0]/255.0f;
2058 							green = p->vertexlight[i*3+1]/255.0f;
2059 							blue = p->vertexlight[i*3+2]/255.0f;
2060 						}
2061 
2062 						if (stage->colormap.enabled)
2063 						{
2064 							red *= stage->colormap.red/255.0f;
2065 							green *= stage->colormap.green/255.0f;
2066 							blue *= stage->colormap.blue/255.0f;
2067 						}
2068 
2069 						alpha = RS_AlphaFunc(stage->alphafunc, alpha, surf->plane->normal, v);
2070 						if (red>1)red=1; if (red<0) red = 0;
2071 						if (green>1)green=1; if (green<0) green = 0;
2072 						if (blue>1)blue=1; if (blue<0) blue = 0;
2073 
2074 						qglColor4f (red, green, blue, alpha);
2075 
2076 						qglTexCoord2f (os+txm, ot+tym);
2077 					}
2078 
2079 					if (!rs->warpsmooth)
2080 						qglVertex3fv (v);
2081 					else
2082 					{
2083 						scale = rs->warpdist * sin(v[0]*rs->warpsmooth+time)*sin(v[1]*rs->warpsmooth+time)*sin(v[2]*rs->warpsmooth+time);
2084 						VectorMA (v, scale, surf->plane->normal, wv);
2085 						qglVertex3fv (wv);
2086 					}
2087 				}
2088 				qglEnd();
2089 			}
2090 		}
2091 		else
2092 		{
2093 			for (p = surf->polys; p; p = p->chain)
2094 			{
2095 				qglBegin (GL_TRIANGLE_FAN);
2096 
2097 				for (i = 0, v = p->verts[0]; i < nv; i++, v += VERTEXSIZE)
2098 				{
2099 
2100 					if (stage->envmap)
2101 					{
2102 						RS_SetEnvmap (v, &os, &ot);
2103 						//move by normal & position
2104 						os-=DotProduct (surf->plane->normal, vectors[1] ) + (r_newrefdef.vieworg[0]-r_newrefdef.vieworg[1]+r_newrefdef.vieworg[2])*0.0025;
2105 						ot+=DotProduct (surf->plane->normal, vectors[2] ) + (-r_newrefdef.vieworg[0]+r_newrefdef.vieworg[1]-r_newrefdef.vieworg[2])*0.0025;
2106 
2107 						if (surf->texinfo->flags & SURF_FLOWING)
2108 							txm = tym = 0;
2109 					}
2110 					else if (fabs(stage->depthhack))
2111 					{
2112 						vec3_t vec;
2113 
2114 						VectorSubtract(p->center, r_newrefdef.vieworg, vec);
2115 						VectorNormalize(vec);
2116 
2117 						os = v[3] + cutDot(vec, surf->texinfo->vecs[0])*stage->depthhack*0.01;
2118 						ot = v[4] + cutDot(vec, surf->texinfo->vecs[1])*stage->depthhack*0.01;
2119 					}
2120 					else
2121 					{
2122 						os = v[3];
2123 						ot = v[4];
2124 					}
2125 					RS_SetTexcoords (stage, &os, &ot, surf);
2126 					{
2127 						float red=255, green=255, blue=255;
2128 
2129 						if (stage->lightmap && p->vertexlight)
2130 						{
2131 							red = p->vertexlight[i*3+0]/255.0f;
2132 							green = p->vertexlight[i*3+1]/255.0f;
2133 							blue = p->vertexlight[i*3+2]/255.0f;
2134 						}
2135 
2136 						if (stage->colormap.enabled)
2137 						{
2138 							red *= stage->colormap.red/255.0f;
2139 							green *= stage->colormap.green/255.0f;
2140 							blue *= stage->colormap.blue/255.0f;
2141 						}
2142 
2143 						alpha = RS_AlphaFunc(stage->alphafunc, alpha, surf->plane->normal, v);
2144 						if (red>1)red=1; if (red<0) red = 0;
2145 						if (green>1)green=1; if (green<0) green = 0;
2146 						if (blue>1)blue=1; if (blue<0) blue = 0;
2147 
2148 						qglColor4f (red, green, blue, alpha);
2149 
2150 						qglTexCoord2f (os+txm, ot+tym);
2151 					}
2152 
2153 					if (!rs->warpsmooth)
2154 						qglVertex3fv (v);
2155 					else
2156 					{
2157 						scale = rs->warpdist * sin(v[0]*rs->warpsmooth+time)*sin(v[1]*rs->warpsmooth+time)*sin(v[2]*rs->warpsmooth+time);
2158 						VectorMA (v, scale, surf->plane->normal, wv);
2159 						qglVertex3fv (wv);
2160 					}
2161 				}
2162 
2163 				qglEnd ();
2164 
2165 			}
2166 		}
2167 
2168 		qglColor4f(1,1,1,1);
2169 		if (stage->colormap.enabled)
2170 			qglEnable (GL_TEXTURE_2D);
2171 
2172 	} while (stage = stage->next);
2173 
2174 	SetVertexOverbrights(false);
2175 }
2176 
RS_DrawSurfaceBlack(msurface_t * surf)2177 void RS_DrawSurfaceBlack (msurface_t *surf)
2178 {
2179 	int			i, nv, alpha;
2180 	glpoly_t	*p;
2181 	float		os, ot, *v;
2182 	rscript_t	*rs = surfaceScript(surf), *glarescript;
2183 
2184 	nv = surf->polys->numverts;
2185 
2186 	alpha = 255;
2187 	if (surf->texinfo->flags & SURF_TRANS33)
2188 		alpha *= 0.33333;
2189 	else if (surf->texinfo->flags & SURF_TRANS66)
2190 		alpha *= 0.66666;
2191 
2192 	GLSTATE_DISABLE_ALPHATEST
2193 	qglDisable (GL_TEXTURE_2D);
2194 
2195 	if (alpha<255)
2196 	{
2197 		GL_BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2198 		GLSTATE_ENABLE_BLEND
2199 	}
2200 	else
2201 		GLSTATE_DISABLE_BLEND
2202 
2203 	if (rs && (rs->glaretexture.enabled || rs->glarecolor.enabled||rs->glarescript.enabled))
2204 		SetVertexOverbrights(true);
2205 
2206 	if (rs && (rs->glaretexture.enabled||rs->glarescript.enabled))
2207 		qglColor4ub(0, 0, 0, alpha);
2208 	else if (rs && rs->glarecolor.enabled)
2209 		qglColor4ub(rs->glarecolor.red, rs->glarecolor.green, rs->glarecolor.blue, alpha);
2210 	else
2211 		qglColor4ub(0, 0, 0, alpha);
2212 
2213 	if (surf->flags & SURF_DRAWTURB)
2214 	{
2215 		glpoly_t *bp;
2216 
2217 		for (bp = surf->polys; bp; bp = bp->next)
2218 		{
2219 			p = bp;
2220 
2221 			qglBegin(GL_TRIANGLE_FAN);
2222 			for (i = 0, v = p->verts[0]; i < p->numverts; i++, v += VERTEXSIZE)
2223 			{
2224 				qglTexCoord2f (v[3], v[4]);
2225 				qglVertex3fv (v);
2226 			}
2227 			qglEnd();
2228 		}
2229 	}
2230 	else
2231 	{
2232 		for (p = surf->polys; p; p = p->chain)
2233 		{
2234 			qglBegin (GL_TRIANGLE_FAN);
2235 
2236 			for (i = 0, v = p->verts[0]; i < nv; i++, v += VERTEXSIZE)
2237 			{
2238 				qglTexCoord2f (v[3], v[4]);
2239 				qglVertex3fv (v);
2240 			}
2241 
2242 			qglEnd();
2243 		}
2244 	}
2245 
2246 	qglColor4ub(255, 255, 255, 255);
2247 	qglEnable (GL_TEXTURE_2D);
2248 
2249 	if (r_newrefdef.rdflags & RDF_MOTIONBLUR)
2250 		return;
2251 
2252 	if (rs && ((rs->glaretexture.enabled && rs->glaretexture.texture)||rs->glarescript.enabled))
2253 	{
2254 		if (rs->glarescript.enabled)
2255 		{
2256 			RS_ReadyScript(rs->glarescript.script);
2257 			RS_DrawSurfaceTexture (surf, rs->glarescript.script);
2258 		}
2259 		else
2260 		{
2261 			if (rs->glarecolor.enabled)
2262 				qglColor4ub(rs->glarecolor.red, rs->glarecolor.green, rs->glarecolor.blue, alpha);
2263 			else
2264 				qglColor4ub(255, 255, 255, alpha);
2265 
2266 			GLSTATE_ENABLE_BLEND
2267 
2268 			GL_Bind(rs->glaretexture.texture->texnum);
2269 			GL_BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2270 
2271 			if (surf->flags & SURF_DRAWTURB)
2272 			{
2273 				glpoly_t *bp;
2274 
2275 				for (bp = surf->polys; bp; bp = bp->next)
2276 				{
2277 					p = bp;
2278 
2279 					qglBegin(GL_TRIANGLE_FAN);
2280 					for (i = 0, v = p->verts[0]; i < p->numverts; i++, v += VERTEXSIZE)
2281 					{
2282 						qglTexCoord2f (v[3], v[4]);
2283 						qglVertex3fv (v);
2284 					}
2285 					qglEnd();
2286 				}
2287 			}
2288 			else
2289 			{
2290 				for (p = surf->polys; p; p = p->chain)
2291 				{
2292 					qglBegin (GL_TRIANGLE_FAN);
2293 
2294 					for (i = 0, v = p->verts[0]; i < nv; i++, v += VERTEXSIZE)
2295 					{
2296 						qglTexCoord2f (v[3], v[4]);
2297 						qglVertex3fv (v);
2298 					}
2299 
2300 					qglEnd();
2301 				}
2302 			}
2303 			GLSTATE_DISABLE_BLEND
2304 		}
2305 	}
2306 
2307 	if (rs && (rs->glaretexture.enabled || rs->glarecolor.enabled || rs->glarescript.enabled))
2308 		SetVertexOverbrights(false);
2309 }
2310 
2311 rscript_t *rs_caustics;
2312 rscript_t *rs_goggles;
RS_LoadSpecialScripts(void)2313 void RS_LoadSpecialScripts (void)
2314 {
2315 	rs_caustics = RS_FindScript("gfx/caustics");
2316 	rs_goggles = RS_FindScript("gfx/goggles");
2317 }
2318 
2319 //add all specia effects here
RS_SpecialSurface(msurface_t * surf)2320 void RS_SpecialSurface (msurface_t *surf)
2321 {
2322 	rscript_t *rs;
2323 
2324 	//Underwater Caustics
2325 	if (surf->flags & SURF_UNDERWATER)
2326 			RS_DrawSurfaceTexture(surf, rs_caustics);
2327 
2328 	if (r_newrefdef.rdflags & RDF_IRGOGGLES)
2329 			RS_DrawSurfaceTexture(surf, rs_goggles);
2330 }
2331