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(¤tScript[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