1 /*
2 Copyright (C) 1994-1995 Apogee Software, Ltd.
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 // RT_DRAW.C
21
22 #include "profile.h"
23 #include "rt_def.h"
24 #include <string.h>
25
26 #ifdef DOS
27 #include <dos.h>
28 #include <conio.h>
29 #endif
30
31 #include "watcom.h"
32 #include "sprites.h"
33 #include "rt_actor.h"
34 #include "rt_stat.h"
35 #include "rt_draw.h"
36 #include "_rt_draw.h"
37 #include "rt_dr_a.h"
38 #include "rt_fc_a.h"
39 #include "rt_scale.h"
40 #include "rt_floor.h"
41 #include "rt_main.h"
42 #include "rt_playr.h"
43 #include "rt_door.h"
44 #include "rt_ted.h"
45 #include "isr.h"
46 #include "rt_util.h"
47 #include "engine.h"
48 #include "z_zone.h"
49 #include "w_wad.h"
50 #include "lumpy.h"
51 #include "rt_menu.h"
52 #include "rt_game.h"
53 #include "rt_vid.h"
54 #include "rt_view.h"
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include "rt_cfg.h"
58 #include "rt_str.h"
59 #include "develop.h"
60 #include "rt_sound.h"
61 #include "rt_msg.h"
62 #include "modexlib.h"
63 #include "rt_rand.h"
64 #include "rt_net.h"
65 #include "rt_sc_a.h"
66 //MED
67 #include "memcheck.h"
68
69 /*
70 =============================================================================
71
72 Global Variables GLOBAL VARIABLES
73
74 =============================================================================
75 */
76
77 int whereami=-1;
78
79 byte * shadingtable;
80
81 word tilemap[MAPSIZE][MAPSIZE]; // wall values only
82 byte spotvis[MAPSIZE][MAPSIZE];
83 byte mapseen[MAPSIZE][MAPSIZE];
84 unsigned long * lights;
85
86 int wstart;
87
88
89 const int dirangle8[9] = {0,FINEANGLES/8,2*FINEANGLES/8,3*FINEANGLES/8,4*FINEANGLES/8,
90 5*FINEANGLES/8,6*FINEANGLES/8,7*FINEANGLES/8,8*FINEANGLES/8};
91
92 const int dirangle16[16] = {0,FINEANGLES/16,2*FINEANGLES/16,3*FINEANGLES/16,
93 4*FINEANGLES/16,5*FINEANGLES/16,6*FINEANGLES/16,
94 7*FINEANGLES/16,8*FINEANGLES/16,9*FINEANGLES/16,
95 10*FINEANGLES/16,11*FINEANGLES/16,12*FINEANGLES/16,
96 13*FINEANGLES/16,14*FINEANGLES/16,15*FINEANGLES/16};
97
98 //
99 // math tables
100 //
101
102 short tantable[FINEANGLES];
103 long sintable[FINEANGLES+FINEANGLEQUAD+1],
104 *costable = sintable+(FINEANGLES/4);
105
106 //
107 // refresh variables
108 //
109
110 fixed viewx,viewy; // the focal point
111 int viewangle;
112 int c_startx, c_starty;
113 fixed viewsin,viewcos;
114 int tics;
115
116 //
117 // ray tracing variables
118 //
119
120 long xintercept,yintercept;
121
122 int doublestep=0;
123 int hp_startfrac;
124 int hp_srcstep;
125
126 int levelheight;
127
128 int actortime=0;
129 int drawtime=0;
130
131 visobj_t vislist[MAXVISIBLE],*visptr,*visstep,*farthest;
132
133 int firstcoloffset=0;
134
135 /*
136 ==================
137 =
138 = Local Variables
139 =
140 ==================
141 */
142 static int nonbobpheight;
143
144 static visobj_t * sortedvislist[MAXVISIBLE];
145
146 static const fixed mindist = 0x1000;
147
148 static int walltime=0;
149
150 static int weaponbobx, weaponboby;
151
152 static int pretics[3];
153 static int preindex;
154 static int netlump;
155 static int gmasklump;
156
157 static const int weaponshape[NUMWEAPGRAPHICS] =
158 {
159 #if (SHAREWARE == 0)
160
161 W_KNIFE,
162 #endif
163
164 W_MALEPISTOL1,
165 W_MRIGHTPISTOL1,
166 W_MP40,
167 W_BAZOOKA,
168 W_HEATSEEKER,
169 W_DRUNK,
170 W_FIREBOMB,
171 W_FIREWALL,
172 W_GODHAND,
173
174
175 #if (SHAREWARE == 0)
176 W_SPLIT,
177 W_KES,
178 W_BAT,
179 W_DOG,
180 W_FEMALEPISTOL1,
181 W_BMALEPISTOL1
182 #endif
183 };
184
185 void SetColorLightLevel (int x, int y, visobj_t * sprite, int dir, int color, int fullbright);
186 void DrawRotatedScreen(int cx, int cy, byte *destscreen, int angle, int scale, int masked);
187 void InterpolateMaskedWall (visobj_t * plane);
188 void InterpolateDoor (visobj_t * plane);
189 void InterpolateWall (visobj_t * plane);
190
191 /*
192 ==================
193 =
194 = BuildTables
195 =
196 ==================
197 */
198
BuildTables(void)199 void BuildTables (void)
200 {
201 byte * table;
202 byte * ptr;
203 long length;
204 int i;
205
206 //
207 // load in tables file
208 //
209
210 table=W_CacheLumpName("tables",PU_STATIC, CvtNull, 1);
211 ptr=table;
212
213 //
214 // get size of first table
215 //
216
217 memcpy(&length,ptr,sizeof(int));
218 SwapIntelLong(&length);
219
220 //
221 // skip first table
222 //
223
224 ptr+=(length+1)*sizeof(int);
225
226 //
227 // get size of sin/cos table
228 //
229
230 memcpy(&length,ptr,sizeof(int));
231 SwapIntelLong(&length);
232 ptr+=sizeof(int);
233
234 //
235 // get sin/cos table
236 //
237 memcpy(&sintable[0],ptr,length*sizeof(long));
238 SwapIntelLongArray(&sintable[0], length);
239 ptr+=(length)*sizeof(int);
240
241 //
242 // get size of tangent table
243 //
244
245 memcpy(&length,ptr,sizeof(int));
246 SwapIntelLong(&length);
247 ptr+=sizeof(int);
248
249 //
250 // get tangent table
251 //
252 memcpy(tantable,ptr,length*sizeof(short));
253 SwapIntelShortArray(tantable, length);
254 ptr+=(length)*sizeof(short);
255
256 //
257 // get size of gamma table
258 //
259
260 memcpy(&length,ptr,sizeof(int));
261 SwapIntelLong(&length);
262 ptr+=sizeof(int);
263
264 //
265 // get gamma table
266 //
267 memcpy(&gammatable[0],ptr,length*sizeof(byte));
268 table=W_CacheLumpName("tables",PU_CACHE, CvtNull, 1);
269
270 costable = (fixed *)&(sintable[FINEANGLES/4]);
271
272 wstart=W_GetNumForName("WALLSTRT");
273 #if (SHAREWARE==0)
274 netlump=W_GetNumForName("net1");
275 #endif
276 gmasklump=W_GetNumForName("p_gmask");
277
278 preindex=0;
279 pretics[0]=0x10000;
280 pretics[2]=0x10000;
281 pretics[1]=0x10000;
282
283 for(i=0;i<ANGLES;i++)
284 {angletodir[i] = (i + (ANGLES/16))/(ANGLES/8);
285 if (angletodir[i] == 8)
286 angletodir[i] = 0;
287 }
288
289 // Check out VENDOR.DOC file
290 CheckVendor();
291
292 if (!quiet)
293 printf("RT_DRAW: Tables Initialized\n");
294 }
295
296
297 /*
298 ========================
299 =
300 = TransformObject
301 =
302 ========================
303 */
304
TransformObject(int x,int y,int * dispx,int * dispheight)305 boolean TransformObject (int x, int y, int *dispx, int *dispheight)
306 {
307
308 fixed gx,gy,gxt,gyt,nx,ny;
309
310
311 //
312 // translate point to view centered coordinates
313 //
314 gx = x-viewx;
315 gy = y-viewy;
316
317 //
318 // calculate newx
319 //
320 gxt = FixedMul(gx,viewcos);
321 gyt = FixedMul(gy,viewsin);
322 nx = gxt-gyt;
323
324 if (nx<MINZ)
325 return false;
326
327 // the midpoint could put parts of the shape
328 // into an adjacent wall
329 //
330 // calculate newy
331 //
332 gxt = FixedMul(gx,viewsin);
333 gyt = FixedMul(gy,viewcos);
334 ny = gyt+gxt;
335
336
337 //
338 // calculate perspective ratio
339 //
340
341 *dispx = centerx + ny*scale/nx; // DEBUG: use assembly divide
342
343 *dispheight = heightnumerator/nx;
344
345 return true;
346 }
347
348
349 /*
350 ========================
351 =
352 = TransformPoint
353 =
354 ========================
355 */
356
TransformPoint(int x,int y,int * screenx,int * height,int * texture,int vertical)357 void TransformPoint (int x, int y, int * screenx, int * height, int * texture, int vertical)
358 {
359
360 fixed gxt,gyt,nx,ny;
361 fixed gxtt,gytt;
362 int gx,gy;
363 int vx,vy;
364 int svs,svc;
365
366
367 //
368 // translate point to view centered coordinates
369 //
370 gx = x-viewx;
371 gy = y-viewy;
372
373 //
374 // calculate newx
375 //
376 gxt = FixedMul(gx,viewcos);
377 gyt = FixedMul(gy,viewsin);
378 nx =gxt-gyt;
379
380 if (nx<10)
381 nx=10;
382
383
384 //
385 // calculate newy
386 //
387 gxtt = FixedMul(gx,viewsin);
388 gytt = FixedMul(gy,viewcos);
389 ny = gytt+gxtt;
390
391 // too close, don't overflow the divid'
392
393
394 *screenx = centerx + ((ny*scale)/nx); // DEBUG: use assembly divide
395
396 *height = heightnumerator/nx;
397
398
399 if (*screenx<0)
400 {
401 svc=(-centerx)*viewcos;
402 svs=(-centerx)*viewsin;
403 vx=(scale*viewcos)+svs;
404 vy=(-scale*viewsin)+svc;
405 if (vertical)
406 {
407 if ((viewcos-viewsin)==0)
408 {
409 *height=20000<<HEIGHTFRACTION;
410 return;
411 }
412 gy=FixedScale(gx,vy,vx);
413 y=gy+viewy;
414 gyt = FixedMul(gy,viewsin);
415 nx =gxt-gyt;
416 if (nx<10)
417 nx=10;
418 *screenx = 0;
419 *height = heightnumerator/nx;
420 }
421 else
422 {
423 if ((-viewsin-viewcos)==0)
424 {
425 *height=20000<<HEIGHTFRACTION;
426 return;
427 }
428 gx=FixedScale(gy,vx,vy);
429 x=gx+viewx;
430 gxt = FixedMul(gx,viewcos);
431 nx =gxt-gyt;
432 if (nx<10)
433 nx=10;
434 *screenx = 0;
435 *height = heightnumerator/nx;
436 }
437 }
438 else if (*screenx>=viewwidth)
439 {
440 svc=(centerx)*viewcos;
441 svs=(centerx)*viewsin;
442 vx=(scale*viewcos)+svs;
443 vy=(-scale*viewsin)+svc;
444 if (vertical)
445 {
446 if ((viewcos+viewsin)==0)
447 {
448 *height=20000<<HEIGHTFRACTION;
449 return;
450 }
451 gy=FixedScale(gx,vy,vx);
452 y=gy+viewy;
453 gyt = FixedMul(gy,viewsin);
454 nx =gxt-gyt;
455 if (nx<10)
456 nx=10;
457 *screenx = viewwidth-1;
458 *height = heightnumerator/nx;
459 }
460 else
461 {
462 if ((-viewsin+viewcos)==0)
463 {
464 *height=20000<<HEIGHTFRACTION;
465 return;
466 }
467 gx=FixedScale(gy,vx,vy);
468 x=gx+viewx;
469 gxt = FixedMul(gx,viewcos);
470 nx =gxt-gyt;
471 if (nx<10)
472 nx=10;
473 *screenx = viewwidth-1;
474 *height = heightnumerator/nx;
475 }
476 }
477 if (vertical)
478 *texture=(y-*texture)&0xffff;
479 else
480 *texture=(x-*texture)&0xffff;
481 }
482
483 /*
484 ========================
485 =
486 = TransformSimplePoint
487 =
488 ========================
489 */
490
TransformSimplePoint(int x,int y,int * screenx,int * height,int * texture,int vertical)491 boolean TransformSimplePoint (int x, int y, int * screenx, int * height, int * texture, int vertical)
492 {
493
494 fixed gxt,gyt,nx,ny;
495 fixed gxtt,gytt;
496 int gx,gy;
497
498
499 //
500 // translate point to view centered coordinates
501 //
502 gx = x-viewx;
503 gy = y-viewy;
504
505 //
506 // calculate newx
507 //
508 gxt = FixedMul(gx,viewcos);
509 gyt = FixedMul(gy,viewsin);
510 nx =gxt-gyt;
511
512 if (nx<MINZ)
513 return false;
514
515
516 //
517 // calculate newy
518 //
519 gxtt = FixedMul(gx,viewsin);
520 gytt = FixedMul(gy,viewcos);
521 ny = gytt+gxtt;
522
523 // too close, don't overflow the divid'
524
525
526 *screenx = centerx + ((ny*scale)/nx); // DEBUG: use assembly divide
527
528 *height = heightnumerator/nx;
529
530 if (vertical)
531 *texture=(y-*texture)&0xffff;
532 else
533 *texture=(x-*texture)&0xffff;
534
535 return true;
536 }
537
538
539 /*
540 ========================
541 =
542 = TransformPlane
543 =
544 ========================
545 */
546
TransformPlane(int x1,int y1,int x2,int y2,visobj_t * plane)547 boolean TransformPlane (int x1, int y1, int x2, int y2, visobj_t * plane)
548 {
549 boolean result2;
550 boolean result1;
551 boolean vertical;
552 int txstart,txend;
553
554 vertical=((x2-x1)==0);
555 plane->viewx=vertical;
556 txstart=plane->texturestart;
557 txend=plane->textureend;
558 result1=TransformSimplePoint(x1,y1,&(plane->x1),&(plane->h1),&(plane->texturestart),vertical);
559 result2=TransformSimplePoint(x2,y2,&(plane->x2),&(plane->h2),&(plane->textureend),vertical);
560 if (result1==true)
561 {
562 if (plane->x1>=viewwidth)
563 return false;
564 if (result2==false)
565 {
566 plane->textureend=txend;
567 TransformPoint(x2,y2,&(plane->x2),&(plane->h2),&(plane->textureend),vertical);
568 }
569 }
570 else
571 {
572 if (result2==false)
573 return false;
574 else
575 {
576 if (plane->x2<0)
577 return false;
578 plane->texturestart=txstart;
579 TransformPoint(x1,y1,&(plane->x1),&(plane->h1),&(plane->texturestart),vertical);
580 }
581 }
582 if (plane->x1<0)
583 {
584 plane->texturestart=txstart;
585 TransformPoint(x1,y1,&(plane->x1),&(plane->h1),&(plane->texturestart),vertical);
586 }
587 if (plane->x2>=viewwidth)
588 {
589 plane->textureend=txend;
590 TransformPoint(x2,y2,&(plane->x2),&(plane->h2),&(plane->textureend),vertical);
591 }
592
593 plane->viewheight=(plane->h1+plane->h2)>>1;
594
595 if ((plane->viewheight>=(2000<<HEIGHTFRACTION)) || (plane->x1>=viewwidth-1) || (plane->x2<=0))
596 return false;
597
598 return true;
599 }
600
601 //==========================================================================
602
603 /*
604 ====================
605 =
606 = CalcHeight
607 =
608 = Calculates the height of xintercept,yintercept from viewx,viewy
609 =
610 ====================
611 */
612
CalcHeight(void)613 int CalcHeight (void)
614 {
615 fixed gxt,gyt,nx;
616 long gx,gy;
617
618 whereami=0;
619
620 gx = xintercept-viewx;
621 gxt = FixedMul(gx,viewcos);
622
623 gy = yintercept-viewy;
624 gyt = FixedMul(gy,viewsin);
625
626 nx = gxt-gyt;
627
628 if (nx<mindist)
629 nx=mindist; // don't let divide overflo'
630
631 return (heightnumerator/nx);
632 }
633
634
635
636 #if 0
637 //==========================================================================
638
639 //******************************************************************************
640 //
641 // NextPlaneptr
642 //
643 //******************************************************************************
644
645 void NextPlaneptr ( void )
646 {
647 if (planeptr < &planelist[MAXPLANES-1]) // don't let it overflo'
648 planeptr++;
649 }
650
651 //******************************************************************************
652 //
653 // RestPlaneptr
654 //
655 //******************************************************************************
656
657 void ResetPlaneptr ( void )
658 {
659 planeptr = &planelist[0];
660 }
661
662 //******************************************************************************
663 //
664 // NextVisptr
665 //
666 //******************************************************************************
667
668 void NextVisptr ( void )
669 {
670 if (visptr < &vislist[MAXVISIBLE-1]) // don't let it overflo'
671 visptr++;
672 }
673
674 //******************************************************************************
675 //
676 // ResetVisptr
677 //
678 //******************************************************************************
679
680 void ResetVisptr ( void )
681 {
682 visptr = &vislist[0];
683 }
684
685 #endif
686
687 //==========================================================================
688
689
690
691 /*
692 =====================
693 =
694 = StatRotate
695 =
696 =====================
697 */
698
StatRotate(statobj_t * temp)699 int StatRotate (statobj_t *temp)
700 {
701 int angle;
702 int dx,dy;
703
704 whereami=2;
705
706 dx = temp->x - player->x;
707 dy = player->y - temp->y;
708 angle = atan2_appx(dx,dy);
709
710 angle = angle-VANG180-dirangle8[temp->count];
711 angle+=ANGLES/16;
712 while (angle>=ANGLES)
713 angle-=ANGLES;
714 while (angle<0)
715 angle+=ANGLES;
716
717 return angle/(ANGLES/8);
718
719 }
720
721
722
723
724 /*
725 =====================
726 =
727 = CalcRotate
728 =
729 =====================
730 */
731
CalcRotate(objtype * ob)732 int CalcRotate (objtype *ob)
733 {
734 int angle,viewangle;
735 int dx,dy;
736 int rotation;
737
738 whereami=1;
739
740 // this isn't exactly correct, as it should vary by a trig value'
741 // but it is close enough with only eight rotations
742 /*
743 if (ob->obclass == b_robobossobj)
744 viewangle = player->angle;
745 else
746 viewangle = player->angle + (centerx - ob->viewx)/8;*/
747 dx = ob->x - player->x;
748 dy = player->y - ob->y;
749 viewangle = atan2_appx(dx,dy);
750
751 if ((ob->obclass >= p_bazookaobj) || (ob->obclass == missileobj))
752 {angle = viewangle - ob->angle;
753 #if (0)
754 Debug("\nviewangle: %d, angle: %d",viewangle,angle);
755 #endif
756 }
757 else if ((ob->obclass > wallopobj) && (ob->obclass != b_darksnakeobj))
758 angle = (viewangle-ANG180)- ob->angle;
759 else if (ob->state->rotate == 16)
760 angle = (viewangle-ANG180)- dirangle16[ob->dir];
761 else
762 angle = (viewangle-ANG180)- dirangle8[ob->dir];
763
764 if (ob->state->rotate == true)
765 angle += ANGLES/16;
766 else if (ob->state->rotate == 16)
767 angle += ANGLES/32;
768
769 while (angle>=ANGLES)
770 angle-=ANGLES;
771 while (angle<0)
772 angle+=ANGLES;
773
774 if (ob->state->rotate == 2) // 2 rotation pain frame
775 {rotation = 4*(angle/(ANG180));
776 return rotation;
777 }
778
779 if (ob->state->rotate == 16)
780 {rotation = angle/(ANGLES/16);
781 #if (0)
782 Debug("\nrotation: %d", rotation);
783 #endif
784 return rotation;
785 }
786 rotation = angle/(ANGLES/8);
787 return rotation;
788
789 }
790
791
792
793 #if 0
794 /*
795 =====================
796 =
797 = DrawMaskedWalls
798 =
799 =====================
800 */
801
802 void DrawMaskedWalls (void)
803 {
804
805
806 int i,numvisible;
807 int gx,gy;
808 unsigned short int *tilespot;
809 byte *visspot;
810 boolean result;
811 statobj_t *statptr;
812 objtype *obj;
813 maskedwallobj_t* tmwall;
814
815 whereami=6;
816
817 //
818 // place maskwall objects
819 //
820 for(tmwall=FIRSTMASKEDWALL;tmwall;tmwall=tmwall->next)
821 {
822 if (spotvis[tmwall->tilex][tmwall->tiley])
823 {
824 mapseen[tmwall->tilex][tmwall->tiley]=1;
825 if (tmwall->vertical)
826 {
827 gx=(tmwall->tilex<<16)+0x8000;
828 gy=(tmwall->tiley<<16);
829 visptr->texturestart=0;
830 visptr->textureend=0;
831 if (viewx<gx)
832 result=TransformPlane(gx,gy,gx,gy+0xffff,visptr);
833 else
834 result=TransformPlane(gx,gy+0xffff,gx,gy,visptr);
835 visptr->shapenum=tmwall->bottomtexture;
836 visptr->altshapenum=tmwall->midtexture;
837 visptr->viewx=tmwall->toptexture;
838 visptr->shapesize=2;
839 }
840 else
841 {
842 gx=(tmwall->tilex<<16);
843 gy=(tmwall->tiley<<16)+0x8000;
844 visptr->texturestart=0;
845 visptr->textureend=0;
846 if (viewy<gy)
847 result=TransformPlane(gx+0xffff,gy,gx,gy,visptr);
848 else
849 result=TransformPlane(gx,gy,gx+0xffff,gy,visptr);
850 visptr->shapenum=tmwall->bottomtexture;
851 visptr->altshapenum=tmwall->midtexture;
852 visptr->viewx=tmwall->toptexture;
853 visptr->shapesize=2;
854 }
855 if ((tmwall->flags&MW_TOPFLIPPING) &&
856 (nonbobpheight>64)
857 )
858 {
859 visptr->viewx++;
860 }
861 else if ((tmwall->flags&MW_BOTTOMFLIPPING) &&
862 (nonbobpheight>maxheight-32)
863 )
864 {
865 visptr->shapenum++;
866 }
867 if ((visptr < &vislist[MAXVISIBLE-1]) && (result==true)) // don't let it overflo'
868 visptr++;
869 }
870 }
871 }
872 #endif
873
874 /*
875 ======================
876 =
877 = SortScaleds
878 = Sort the scaleds using a HEAPSORT
879 =
880 ======================
881 */
882
883 #define SGN(x) ((x>0) ? (1) : ((x==0) ? (0) : (-1)))
884
885 /*--------------------------------------------------------------------------*/
CompareHeights(s1p,s2p)886 int CompareHeights(s1p,s2p) visobj_t **s1p,**s2p;
887 {
888 whereami=3;
889 return SGN((*s1p)->viewheight-(*s2p)->viewheight);
890 }
891
SwitchPointers(s1p,s2p)892 void SwitchPointers(s1p,s2p) visobj_t **s1p,**s2p;
893 {
894 visobj_t * temp;
895
896 whereami=4;
897 temp=*s1p;
898 *s1p=*s2p;
899 *s2p=temp;
900 }
901
902
SortVisibleList(int numvisible,visobj_t * vlist)903 void SortVisibleList( int numvisible, visobj_t * vlist )
904 {
905 int i;
906
907 whereami=5;
908 for (i=0;i<numvisible;i++)
909 sortedvislist[i]=&(vlist[i]);
910 hsort((char *)&(sortedvislist[0]),numvisible,sizeof(visobj_t *),&CompareHeights,&SwitchPointers);
911 }
912
913 /*
914 =====================
915 =
916 = DrawScaleds
917 =
918 = Draws all objects that are visible
919 =
920 =====================
921 */
922
923 #define HF_1 (24)
924 #define HF_2 (72)
925
DrawScaleds(void)926 void DrawScaleds (void)
927 {
928
929
930 int i,numvisible;
931 int gx,gy;
932 unsigned short int *tilespot;
933 byte *visspot;
934 boolean result;
935 statobj_t *statptr;
936 objtype *obj;
937 maskedwallobj_t* tmwall;
938
939 whereami=6;
940
941 //
942 // place maskwall objects
943 //
944 for(tmwall=FIRSTMASKEDWALL;tmwall;tmwall=tmwall->next)
945 {
946 if (spotvis[tmwall->tilex][tmwall->tiley])
947 {
948 mapseen[tmwall->tilex][tmwall->tiley]=1;
949 if (tmwall->vertical)
950 {
951 gx=(tmwall->tilex<<16)+0x8000;
952 gy=(tmwall->tiley<<16);
953 visptr->texturestart=0;
954 visptr->textureend=0;
955 if (viewx<gx)
956 result=TransformPlane(gx,gy,gx,gy+0xffff,visptr);
957 else
958 result=TransformPlane(gx,gy+0xffff,gx,gy,visptr);
959 visptr->shapenum=tmwall->bottomtexture;
960 visptr->altshapenum=tmwall->midtexture;
961 visptr->viewx=tmwall->toptexture;
962 visptr->shapesize=2;
963 }
964 else
965 {
966 gx=(tmwall->tilex<<16);
967 gy=(tmwall->tiley<<16)+0x8000;
968 visptr->texturestart=0;
969 visptr->textureend=0;
970 if (viewy<gy)
971 result=TransformPlane(gx+0xffff,gy,gx,gy,visptr);
972 else
973 result=TransformPlane(gx,gy,gx+0xffff,gy,visptr);
974 visptr->shapenum=tmwall->bottomtexture;
975 visptr->altshapenum=tmwall->midtexture;
976 visptr->viewx=tmwall->toptexture;
977 visptr->shapesize=2;
978 }
979 if ((tmwall->flags&MW_TOPFLIPPING) &&
980 (nonbobpheight>64)
981 )
982 {
983 visptr->viewx++;
984 }
985 else if ((tmwall->flags&MW_BOTTOMFLIPPING) &&
986 (nonbobpheight>maxheight-32)
987 )
988 {
989 visptr->shapenum++;
990 }
991 if ((visptr < &vislist[MAXVISIBLE-1]) && (result==true)) // don't let it overflo'
992 visptr++;
993 }
994 }
995 //
996 // place static objects
997 //
998 UpdateClientControls();
999 for (statptr = firstactivestat ; statptr; statptr=statptr->nextactive)
1000 { //redraw:
1001 if((visptr->shapenum = statptr->shapenum) == NOTHING)
1002 continue;
1003
1004 visptr->shapenum += shapestart;
1005 if ((visptr->shapenum <= shapestart) ||
1006 (visptr->shapenum >= shapestop))
1007 Error("actor shapenum %d out of range (%d-%d)",visptr->shapenum,shapestart,shapestop);
1008
1009 visspot = statptr->visspot;
1010 if (!((*(visspot-0)) ||
1011 (*(visspot-1)) ||
1012 (*(visspot+1)) ||
1013 (*(visspot-129)) ||
1014 (*(visspot-128)) ||
1015 (*(visspot-127)) ||
1016 (*(visspot+129)) ||
1017 (*(visspot+128)) ||
1018 (*(visspot+127))))
1019 {statptr->flags &= ~FL_VISIBLE;
1020 continue; // not visible
1021 }
1022
1023 result = TransformObject (statptr->x,statptr->y,&(visptr->viewx),&(visptr->viewheight));
1024
1025 if ((result==false) || (visptr->viewheight< (1<<(HEIGHTFRACTION+2))))
1026 continue; // to close to the object
1027 statptr->flags |= FL_SEEN;
1028
1029 statptr->flags |= FL_VISIBLE;
1030
1031 if (statptr->flags & FL_ROTATING)
1032 visptr->shapenum += StatRotate(statptr);
1033
1034 if (statptr->flags&FL_TRANSLUCENT)
1035 {
1036 visptr->shapesize=1;
1037 if (statptr->flags&FL_FADING)
1038 visptr->h2=transparentlevel;
1039 else
1040 visptr->h2=FIXEDTRANSLEVEL;
1041 SetSpriteLightLevel(statptr->x,statptr->y,visptr,0,(statptr->flags&FL_FULLLIGHT));
1042 }
1043 else if (statptr->flags&FL_SOLIDCOLOR)
1044 {
1045 visptr->shapesize=4;
1046 visptr->h2=statptr->hitpoints;
1047 }
1048 else if (statptr->flags&FL_COLORED)
1049 {
1050 visptr->shapesize=0;
1051 #if (DEVELOPMENT == 1)
1052 if ((statptr->hitpoints>=0) &&
1053 (statptr->hitpoints<MAXPLAYERCOLORS))
1054 {
1055 #endif
1056 SetColorLightLevel(statptr->x,statptr->y,visptr,
1057 0,statptr->hitpoints,
1058 (statptr->flags&FL_FULLLIGHT));
1059 #if (DEVELOPMENT == 1)
1060 }
1061 else
1062 {
1063 Error("Illegal color map for sprite type %d\n",statptr->itemnumber);
1064 }
1065 #endif
1066 }
1067 else
1068 {
1069 visptr->shapesize=0;
1070 SetSpriteLightLevel(statptr->x,statptr->y,visptr,0,(statptr->flags&FL_FULLLIGHT));
1071 }
1072
1073 visptr->h1=pheight-statptr->z;
1074
1075 if ((statptr->itemnumber != (unsigned int)-1) &&
1076 (statptr->flags&FL_HEIGHTFLIPPABLE)
1077 )
1078 {
1079 if (statptr->itemnumber==stat_disk)
1080 {
1081 int value;
1082 value=nonbobpheight-statptr->z-32;
1083 if ((value<=HF_2) && (value>HF_1))
1084 {
1085 visptr->shapenum++;
1086 }
1087 else if ((value<=HF_1) && (value>=-HF_1))
1088 {
1089 visptr->shapenum+=2;
1090 }
1091 else if ((value<-HF_1) && (value>=-HF_2))
1092 {
1093 visptr->shapenum+=3;
1094 }
1095 else if (value<-HF_2)
1096 {
1097 visptr->shapenum+=4;
1098 }
1099 }
1100 else if ((nonbobpheight-statptr->z)<-16)
1101 {
1102 visptr->shapenum++;
1103 }
1104 }
1105
1106 if (visptr < &vislist[MAXVISIBLE-1]) // don't let it overflo'
1107 visptr++;
1108
1109
1110 }
1111 //
1112 // place active objects
1113 //
1114 UpdateClientControls();
1115 for (obj = firstactive;obj;obj=obj->nextactive)
1116 {
1117 if (obj==player)
1118 continue;
1119
1120 if ((visptr->shapenum = obj->shapenum) == NOTHING)
1121 continue; // no shape
1122
1123 visptr->shapenum += shapestart;
1124 if ((visptr->shapenum <= shapestart) ||
1125 (visptr->shapenum >= shapestop))
1126 Error("actor shapenum %d out of range (%d-%d)",visptr->shapenum,shapestart,shapestop);
1127 visspot = &spotvis[obj->tilex][obj->tiley];
1128 tilespot = &tilemap[obj->tilex][obj->tiley];
1129
1130 //
1131 // could be in any of the nine surrounding tiles
1132 //
1133 if (*visspot
1134 || ( *(visspot-1))
1135 || ( *(visspot+1))
1136 || ( *(visspot-129))
1137 || ( *(visspot-128))
1138 || ( *(visspot-127))
1139 || ( *(visspot+129))
1140 || ( *(visspot+128))
1141 || ( *(visspot+127)) )
1142 {
1143
1144 // result = TransformObject (obj->drawx, obj->drawy,&(visptr->viewx),&(visptr->viewheight));
1145 result = TransformObject (obj->x, obj->y,&(visptr->viewx),&(visptr->viewheight));
1146 if ((result==false) || (visptr->viewheight< (1<<(HEIGHTFRACTION+2))))
1147 continue; // to close to the object
1148 if (obj->state->rotate)
1149 visptr->shapenum += CalcRotate (obj);
1150
1151 visptr->shapesize=0;
1152
1153 if (player->flags&FL_SHROOMS)
1154 {
1155 visptr->shapesize=4;
1156 visptr->h2=(GetTicCount()&0xff);
1157 }
1158 if (obj->obclass==playerobj)
1159 {
1160 if (obj->flags&FL_GODMODE)
1161 {
1162 visptr->shapesize=4;
1163 visptr->h2=240+(GetTicCount()&0x7);
1164 }
1165 else if (obj->flags & FL_COLORED)
1166 {
1167 playertype *pstate;
1168
1169 M_LINKSTATE(obj,pstate);
1170 #if (DEVELOPMENT == 1)
1171 if ((pstate->uniformcolor>=0) &&
1172 (pstate->uniformcolor<MAXPLAYERCOLORS))
1173 {
1174 #endif
1175 SetColorLightLevel(obj->x,obj->y,visptr,
1176 obj->dir,pstate->uniformcolor,
1177 (obj->flags&FL_FULLLIGHT) );
1178 #if (DEVELOPMENT == 1)
1179 }
1180 else
1181 {
1182 Error("Illegal color map for players\n");
1183 }
1184 #endif
1185 }
1186 else
1187 SetSpriteLightLevel(obj->x,obj->y,visptr,obj->dir,(obj->flags&FL_FULLLIGHT));
1188
1189 }
1190 else
1191 {
1192 if ((obj->obclass >= b_darianobj) && (obj->obclass <= b_robobossobj) &&
1193 MISCVARS->redindex)
1194 {
1195 visptr->colormap=redmap+((MISCVARS->redindex-1)<<8);
1196 }
1197 else
1198 {
1199 SetSpriteLightLevel(obj->x,obj->y,visptr,obj->dir,(obj->flags&FL_FULLLIGHT));
1200 }
1201 }
1202
1203 visptr->h1= pheight - obj->z;
1204
1205 if (obj->obclass==diskobj)
1206 {
1207 int value;
1208 value=nonbobpheight-obj->z-32;
1209 if ((value<=HF_2) && (value>HF_1))
1210 {
1211 visptr->shapenum++;
1212 }
1213 else if ((value<=HF_1) && (value>=-HF_1))
1214 {
1215 visptr->shapenum+=2;
1216 }
1217 else if ((value<-HF_1) && (value>=-HF_2))
1218 {
1219 visptr->shapenum+=3;
1220 }
1221 else if (value<-HF_2)
1222 {
1223 visptr->shapenum+=4;
1224 }
1225 }
1226 else if ( (obj->obclass==pillarobj) &&
1227 ((nonbobpheight-obj->z)<-16)
1228 )
1229 {
1230 visptr->shapenum++;
1231 }
1232
1233 if (visptr < &vislist[MAXVISIBLE-1]) // don't let it overflo'
1234 visptr++;
1235 obj->flags |= FL_SEEN;
1236 obj->flags |= FL_VISIBLE;
1237 }
1238 else
1239 obj->flags &= ~FL_VISIBLE;
1240 }
1241 //
1242 // draw from back to front
1243 //
1244 numvisible = visptr-&vislist[0];
1245 if (!numvisible)
1246 return; // no visible objects
1247 SortVisibleList( numvisible, &vislist[0] );
1248 UpdateClientControls();
1249 for (i = 0; i<numvisible; i++)
1250 {
1251 //
1252 // draw farthest
1253 //
1254
1255 if (sortedvislist[i]->shapesize==4) {
1256
1257 ScaleSolidShape(sortedvislist[i]);
1258
1259 } else if (sortedvislist[i]->shapesize==3) {
1260
1261 InterpolateDoor (sortedvislist[i]);
1262
1263 } else if (sortedvislist[i]->shapesize==2) {
1264
1265 InterpolateMaskedWall (sortedvislist[i]);
1266
1267 } else if (sortedvislist[i]->shapesize==1) {
1268
1269 ScaleTransparentShape(sortedvislist[i]);
1270
1271 } else {
1272
1273 ScaleShape(sortedvislist[i]);
1274
1275 }
1276
1277 }
1278 }
1279
1280 //==========================================================================
1281
1282
1283
1284
1285
1286 /*
1287 ==============
1288 =
1289 = DrawPlayerWeapon
1290 =
1291 = Draw the player's hand'
1292 =
1293 ==============
1294 */
1295
DrawPlayerWeapon(void)1296 void DrawPlayerWeapon (void)
1297 {
1298 int shapenum,index;
1299 int xdisp=0;
1300 int ydisp=0;
1301 int female,black;
1302 int altshape=0;
1303
1304 whereami=7;
1305
1306 SoftError("\n attackframe: %d, weaponframe: %d, weapondowntics: %d"
1307 " weaponuptics: %d",locplayerstate->attackframe,
1308 locplayerstate->weaponframe,locplayerstate->weapondowntics,
1309 locplayerstate->weaponuptics);
1310
1311 if ((locplayerstate->NETCAPTURED == 1) && (!locplayerstate->HASKNIFE))
1312 return;
1313
1314 if (locplayerstate->weapon != -1)
1315 {female = ((locplayerstate->player == 1) || (locplayerstate->player == 3));
1316 black = (locplayerstate->player == 2);
1317
1318 if (((locplayerstate->NETCAPTURED >= 1) || (locplayerstate->NETCAPTURED == -2)) && (locplayerstate->HASKNIFE == 1)) // if raising or lowering
1319 {index = 0;
1320 shapenum = gunsstart + weaponshape[index] + locplayerstate->weaponframe;
1321 }
1322 else if (locplayerstate->weapon != wp_twopistol)
1323 {if (locplayerstate->weapon==wp_pistol)
1324 {if (female)
1325 index = NUMWEAPGRAPHICS-2;
1326 else if (black)
1327 index = NUMWEAPGRAPHICS-1;
1328 else
1329 #if (SHAREWARE == 0)
1330 index = 1;
1331 #else
1332 index = 0;
1333 #endif
1334 }
1335 else
1336 #if (SHAREWARE == 0)
1337
1338 index = locplayerstate->weapon + 1;
1339 #else
1340 index = locplayerstate->weapon;
1341 #endif
1342
1343 if ((index<0) || (index>=NUMWEAPGRAPHICS))
1344 Error ("Weapon shapenum out of range\n");
1345 shapenum = gunsstart + weaponshape[index] + locplayerstate->weaponframe;
1346
1347 #if (SHAREWARE == 0)
1348 if ((shapenum < W_GetNumForName("KNIFE1")) ||
1349 (shapenum > W_GetNumForName("DOGPAW4"))
1350 )
1351 #else
1352 if ((shapenum < W_GetNumForName("MPIST11")) ||
1353 (shapenum > W_GetNumForName("GODHAND8"))
1354 )
1355 #endif
1356 Error("\n illegal weapon shapenum %d, index %d, weaponframe %d",
1357 shapenum,index,locplayerstate->weaponframe);
1358 }
1359
1360 else
1361 {
1362 #if (SHAREWARE == 0)
1363 if (female)
1364 {altshape = W_FLEFTPISTOL1;
1365 shapenum = W_FRIGHTPISTOL1;
1366 }
1367 else if (black)
1368 {altshape = W_BMLEFTPISTOL1;
1369 shapenum = W_BMRIGHTPISTOL1;
1370 }
1371 else
1372 #endif
1373 {altshape = W_MLEFTPISTOL1;
1374 shapenum = W_MRIGHTPISTOL1;
1375 }
1376
1377 altshape += gunsstart;
1378 shapenum += gunsstart;
1379 if (locplayerstate->weaponframe > 2)
1380 altshape += (locplayerstate->weaponframe - 3);
1381 else
1382 shapenum += locplayerstate->weaponframe;
1383 }
1384
1385 if (!(locplayerstate->NETCAPTURED) ||
1386 (locplayerstate->NETCAPTURED == -1) ||
1387 (locplayerstate->HASKNIFE == 0))
1388 {switch (locplayerstate->weapon)
1389 {
1390
1391 case wp_godhand:
1392 break;
1393
1394 case wp_mp40:
1395 break;
1396
1397 case wp_firewall:
1398 ydisp = 10;
1399 break;
1400
1401 case wp_bazooka:
1402 break;
1403
1404 case wp_heatseeker:
1405 ydisp = 20;
1406 break;
1407
1408 case wp_pistol:
1409 break;
1410
1411 case wp_twopistol:
1412 xdisp = 80;
1413 break;
1414
1415 case wp_drunk:
1416 ydisp = 10;
1417 break;
1418
1419 case wp_firebomb:
1420 break;
1421
1422
1423
1424 #if (SHAREWARE == 0)
1425
1426 case wp_kes:
1427 break;
1428
1429 case wp_bat:
1430 xdisp = 20;
1431 break;
1432
1433 case wp_split:
1434 ydisp = 20;
1435 break;
1436
1437
1438 case wp_dog:
1439 break;
1440
1441
1442 #endif
1443
1444 default:
1445 Error("Illegal weapon value = %ld\n",locplayerstate->weapon);
1446 break;
1447 }
1448 }
1449 else
1450 xdisp = 60;
1451
1452
1453
1454
1455 if (altshape)
1456 {
1457 int temp;
1458 int delta;
1459
1460 temp = weaponscale;
1461 delta = FixedMul((weaponbobx<<9),weaponscale);
1462 weaponscale += delta;
1463 ScaleWeapon(xdisp - weaponbobx,ydisp + weaponboby + locplayerstate->weaponheight,shapenum);
1464 weaponscale -= delta;
1465 ScaleWeapon(weaponbobx - 80,ydisp + weaponboby + locplayerstate->weaponheight,altshape);
1466 weaponscale = temp;
1467 }
1468 else
1469 {
1470 int temp;
1471 int delta;
1472
1473 temp = weaponscale;
1474 delta = FixedMul((weaponbobx<<9),weaponscale);
1475 weaponscale -= delta;
1476 ScaleWeapon(xdisp + weaponbobx,ydisp + weaponboby + locplayerstate->weaponheight,shapenum);
1477 weaponscale = temp;
1478 }
1479 }
1480 }
1481
AdaptDetail(void)1482 void AdaptDetail ( void )
1483 {
1484 #if PROFILE
1485 return;
1486 #else
1487
1488 whereami=8;
1489 if ((preindex<0) || (preindex>2))
1490 Error("preindex out of range\n");
1491 pretics[preindex]=(pretics[0]+pretics[1]+pretics[2]+(tics<<16)+0x8000)>>2;
1492 if (pretics[preindex]>GOLOWER)
1493 {
1494 pretics[0]=GOHIGHER;
1495 pretics[1]=GOHIGHER;
1496 pretics[2]=GOHIGHER;
1497 doublestep++;
1498 if (doublestep>2) doublestep=2;
1499 }
1500 else if (pretics[preindex]<GOHIGHER)
1501 {
1502 if (doublestep>0)
1503 doublestep--;
1504 }
1505 preindex++;
1506 if (preindex>2)
1507 preindex=0;
1508 #endif
1509 }
1510
1511
1512
1513 /*
1514 =====================
1515 =
1516 = CalcTics
1517 =
1518 =====================
1519 */
1520
CalcTics(void)1521 void CalcTics (void)
1522 {
1523
1524 #if PROFILE
1525 tics=PROFILETICS;
1526 GetTicCount()+=PROFILETICS;
1527 oldtime=GetTicCount();
1528 return;
1529 #else
1530 #if (DEVELOPMENT == 1)
1531 int i;
1532 #endif
1533 volatile int tc;
1534
1535 whereami=9;
1536 // SoftError("InCalcTics\n");
1537 // SoftError("CT GetTicCount()=%ld\n",GetTicCount());
1538 // SoftError("CT oldtime=%ld\n",oldtime);
1539
1540 //
1541 // calculate tics since last refresh for adaptive timing
1542 //
1543
1544 tc=GetTicCount();
1545 while (tc==oldtime) { tc=GetTicCount(); } /* endwhile */
1546 tics=tc-oldtime;
1547
1548 // SoftError("CT GetTicCount()=%ld\n",GetTicCount());
1549 // if (tics>MAXTICS)
1550 // {
1551 // tc-=(tics-MAXTICS);
1552 // GetTicCount() = tc;
1553 // tics = MAXTICS;
1554 // }
1555
1556 if (demoplayback || demorecord)
1557 {
1558 if (tics>MAXTICS)
1559 {
1560 tc=oldtime+MAXTICS;
1561 tics=MAXTICS;
1562 ISR_SetTime(tc);
1563 }
1564 }
1565 oldtime=tc;
1566 #if (DEVELOPMENT == 1)
1567 if (graphicsmode==true)
1568 {
1569 int drawntics;
1570
1571 VGAWRITEMAP(1);
1572 drawntics=tics;
1573 if (drawntics>MAXDRAWNTICS)
1574 drawntics=MAXDRAWNTICS;
1575 for (i=0;i<drawntics;i++)
1576 *((byte *)displayofs+screenofs+(SCREENBWIDE*3)+i)=egacolor[15];
1577 }
1578 /*
1579 if (drawtime>MAXDRAWNTICS)
1580 drawtime=MAXDRAWNTICS;
1581 for (i=0;i<drawtime;i++)
1582 *((byte *)displayofs+screenofs+(SCREENBWIDE*5)+i)=egacolor[2];
1583 if (walltime>MAXDRAWNTICS)
1584 walltime=MAXDRAWNTICS;
1585 for (i=0;i<walltime;i++)
1586 *((byte *)displayofs+screenofs+(SCREENBWIDE*7)+i)=egacolor[14];
1587 if (actortime>MAXDRAWNTICS)
1588 actortime=MAXDRAWNTICS;
1589 for (i=0;i<actortime;i++)
1590 *((byte *)displayofs+screenofs+(SCREENBWIDE*9)+i)=egacolor[4];
1591 }
1592 */
1593 #endif
1594 #endif
1595
1596 }
1597
1598 /*
1599 ==========================
1600 =
1601 = SetSpriteLightLevel
1602 =
1603 ==========================
1604 */
1605
SetSpriteLightLevel(int x,int y,visobj_t * sprite,int dir,int fullbright)1606 void SetSpriteLightLevel (int x, int y, visobj_t * sprite, int dir, int fullbright)
1607 {
1608 int i;
1609 int lv;
1610 int intercept;
1611
1612 whereami=10;
1613
1614 if (MISCVARS->GASON==1)
1615 {
1616 sprite->colormap=greenmap+(MISCVARS->gasindex<<8);
1617 return;
1618 }
1619
1620 if (fulllight || fullbright)
1621 {
1622 sprite->colormap=colormap+(1<<12);
1623 return;
1624 }
1625
1626 if (fog)
1627 {
1628 i=(sprite->viewheight>>normalshade)+minshade;
1629 if (i>maxshade) i=maxshade;
1630 sprite->colormap=colormap+(i<<8);
1631 }
1632 else
1633 {
1634 if (lightsource)
1635 {
1636 if (dir==east || dir==west)
1637 intercept=(x>>11)&0x1c;
1638 else
1639 intercept=(y>>11)&0x1c;
1640
1641 lv=(((LightSourceAt(x>>16,y>>16)>>intercept)&0xf)>>1);
1642 i=maxshade-(sprite->viewheight>>normalshade)-lv;
1643 if (i<minshade) i=minshade;
1644 sprite->colormap=colormap+(i<<8);
1645 }
1646 else
1647 {
1648 i=maxshade-(sprite->viewheight>>normalshade);
1649 if (i<minshade) i=minshade;
1650 sprite->colormap=colormap+(i<<8);
1651 }
1652 }
1653 }
1654
1655 /*
1656 ==========================
1657 =
1658 = SetColorLightLevel
1659 =
1660 ==========================
1661 */
1662
SetColorLightLevel(int x,int y,visobj_t * sprite,int dir,int color,int fullbright)1663 void SetColorLightLevel (int x, int y, visobj_t * sprite, int dir, int color, int fullbright)
1664 {
1665 int i;
1666 int lv;
1667 int intercept;
1668 int height;
1669 byte * map;
1670
1671
1672 whereami=11;
1673 height=sprite->viewheight<<1;
1674 map=playermaps[color];
1675 if (MISCVARS->GASON==1)
1676 {
1677 sprite->colormap=greenmap+(MISCVARS->gasindex<<8);
1678 return;
1679 }
1680
1681 if ((fulllight) || (fullbright))
1682 {
1683 sprite->colormap=map+(1<<12);
1684 return;
1685 }
1686
1687 if (fog)
1688 {
1689 i=(height>>normalshade)+minshade;
1690 if (i>maxshade) i=maxshade;
1691 sprite->colormap=map+(i<<8);
1692 }
1693 else
1694 {
1695 if (lightsource)
1696 {
1697 if (dir==east || dir==west)
1698 intercept=(x>>11)&0x1c;
1699 else
1700 intercept=(y>>11)&0x1c;
1701
1702 lv=(((LightSourceAt(x>>16,y>>16)>>intercept)&0xf)>>1);
1703 i=maxshade-(height>>normalshade)-lv;
1704 if (i<minshade) i=minshade;
1705 sprite->colormap=map+(i<<8);
1706 }
1707 else
1708 {
1709 i=maxshade-(height>>normalshade);
1710 if (i<minshade) i=minshade;
1711 sprite->colormap=map+(i<<8);
1712 }
1713 }
1714 }
1715
1716 /*
1717 ==========================
1718 =
1719 = SetWallLightLevel
1720 =
1721 ==========================
1722 */
1723
SetWallLightLevel(wallcast_t * post)1724 void SetWallLightLevel (wallcast_t * post)
1725 {
1726 int la;
1727 int lv;
1728 int i;
1729
1730 whereami=12;
1731 if (MISCVARS->GASON==1)
1732 {
1733 shadingtable=greenmap+(MISCVARS->gasindex<<8);
1734 return;
1735 }
1736
1737 switch (post->posttype)
1738 {
1739 case 0:
1740 la=0;
1741 break;
1742 case 1:
1743 la=4;
1744 break;
1745 case 2:
1746 la=(4-gamestate.difficulty);
1747 break;
1748 case 3:
1749 la=3+(4-gamestate.difficulty);
1750 break;
1751 }
1752
1753 if (lightsource)
1754 {
1755 int x,y;
1756 int intercept;
1757
1758 x=post->offset>>7;
1759 y=post->offset&0x7f;
1760 intercept=(post->texture>>11)&0x1c;
1761 lv=(((LightSourceAt(x,y)>>intercept)&0xf)>>1);
1762 }
1763 else
1764 lv=0;
1765 if (fulllight)
1766 {
1767 if (fog)
1768 {
1769 i =16+minshade-lv+la;
1770 if (i>maxshade+la) i=maxshade+la;
1771 shadingtable=colormap+(i<<8);
1772 }
1773 else
1774 {
1775 i =maxshade-16-lv+la;
1776 if (i>=maxshade) i=maxshade;
1777 if (i<minshade+la) i=minshade+la;
1778 shadingtable=colormap+(i<<8);
1779 }
1780 return;
1781 }
1782 if (fog)
1783 {
1784 i =(post->wallheight>>normalshade)+minshade-lv+la;
1785 if (i>maxshade+la) i=maxshade+la;
1786 shadingtable=colormap+(i<<8);
1787 }
1788 else
1789 {
1790 i =maxshade-(post->wallheight>>normalshade)-lv+la;
1791 if (i>=maxshade) i=maxshade;
1792 if (i<minshade+la) i=minshade+la;
1793 shadingtable=colormap+(i<<8);
1794 }
1795 }
1796
1797
1798
1799 /*
1800 ====================
1801 =
1802 = DrawWallPost
1803 =
1804 ====================
1805 */
1806
DrawWallPost(wallcast_t * post,byte * buf)1807 void DrawWallPost ( wallcast_t * post, byte * buf)
1808 {
1809 int ht;
1810 int topscreen;
1811 int bottomscreen;
1812 byte * src;
1813 byte * src2;
1814
1815 whereami=42;
1816 if (post->lump)
1817 src=W_CacheLumpNum(post->lump,PU_CACHE, CvtNull, 1);
1818 if (post->alttile!=0)
1819 {
1820 if (post->alttile==-1)
1821 {
1822 ht=maxheight+32;
1823 dc_invscale = post->wallheight<<(10-HEIGHTFRACTION);
1824 dc_texturemid = (pheight<<SFRACBITS)+(SFRACUNIT>>1);
1825 topscreen = centeryfrac - FixedMul(dc_texturemid,dc_invscale);
1826 bottomscreen = topscreen + (dc_invscale*ht);
1827 dc_yh = ((bottomscreen-1)>>SFRACBITS)+1;
1828 if (dc_yh < 0)
1829 {
1830 post->floorclip=-1;
1831 post->ceilingclip=0;
1832 }
1833 else if (dc_yh >= viewheight)
1834 {
1835 post->floorclip=viewheight-1;
1836 post->ceilingclip=viewheight;
1837 }
1838 else
1839 {
1840 post->floorclip=dc_yh-1;
1841 post->ceilingclip=dc_yh;
1842 }
1843 return;
1844 }
1845 else
1846 {
1847 ht=nominalheight;
1848 src2=W_CacheLumpNum(post->alttile,PU_CACHE, CvtNull, 1);
1849 }
1850 }
1851 else
1852 {
1853 ht=maxheight+32;
1854 src2=src;
1855 }
1856
1857 dc_invscale = post->wallheight<<(10-HEIGHTFRACTION);
1858 dc_texturemid = (pheight<<SFRACBITS)+(SFRACUNIT>>1);
1859 topscreen = centeryfrac - FixedMul(dc_texturemid,dc_invscale);
1860 bottomscreen = topscreen + (dc_invscale*ht);
1861 dc_yl = (topscreen+SFRACUNIT-1)>>SFRACBITS;
1862 dc_yh = ((bottomscreen-1)>>SFRACBITS)+1;
1863
1864 if (dc_yl >= viewheight)
1865 {
1866 post->ceilingclip=viewheight;
1867 post->floorclip=viewheight-1;
1868 return;
1869 }
1870 else if (dc_yl < 0)
1871 dc_yl = 0;
1872
1873 dc_iscale = (64<<(16+HEIGHTFRACTION))/post->wallheight;
1874
1875 if (dc_yh < 0)
1876 {
1877 post->floorclip=-1;
1878 post->ceilingclip=0;
1879 goto bottomcheck;
1880 }
1881 else if (dc_yh > viewheight)
1882 dc_yh = viewheight;
1883
1884 post->ceilingclip=dc_yl;
1885 post->floorclip=dc_yh-1;
1886 dc_source=src2+((post->texture>>4)&0xfc0);
1887 R_DrawWallColumn (buf);
1888
1889 bottomcheck:
1890
1891 if (ht!=nominalheight)
1892 return;
1893
1894 dc_texturemid-=(nominalheight<<SFRACBITS);
1895 topscreen = centeryfrac - FixedMul(dc_texturemid,dc_invscale);
1896 bottomscreen = topscreen + (dc_invscale<<6);
1897 dc_yl = (topscreen+SFRACUNIT-1)>>SFRACBITS;
1898 dc_yh = ((bottomscreen-1)>>SFRACBITS);
1899
1900 if (dc_yl >= viewheight)
1901 return;
1902 else if (dc_yl < 0)
1903 dc_yl = 0;
1904 if (dc_yh < 0)
1905 return;
1906 else if (dc_yh > viewheight)
1907 dc_yh = viewheight;
1908 post->floorclip=dc_yh-1;
1909 dc_source=src+((post->texture>>4)&0xfc0);
1910 R_DrawWallColumn (buf);
1911 }
1912
1913 /*
1914 ====================
1915 =
1916 = DrawWalls
1917 =
1918 ====================
1919 */
1920
DrawWalls(void)1921 void DrawWalls (void)
1922 {
1923 char * buf;
1924 int plane;
1925 wallcast_t * post;
1926
1927 whereami=13;
1928
1929 plane = 0;
1930
1931 if (doublestep>1)
1932 {
1933 #ifdef DOS
1934 for (plane=0;plane<4;plane+=2)
1935 #endif
1936 {
1937 VGAMAPMASK((1<<plane)+(1<<(plane+1)));
1938 buf=(byte *)(bufferofs);
1939 #ifdef DOS
1940 for (post=&posts[plane];post<&posts[viewwidth];post+=4,buf++)
1941 #else
1942 for (post=&posts[plane];post<&posts[viewwidth];post+=2,buf+=2)
1943 #endif
1944 {
1945 SetWallLightLevel(post);
1946 DrawWallPost(post,buf);
1947 #ifndef DOS
1948 DrawWallPost(post,buf+1);
1949 #endif
1950 (post+1)->ceilingclip=post->ceilingclip;
1951 (post+1)->floorclip=post->floorclip;
1952 }
1953 }
1954 }
1955 else
1956 {
1957 #ifdef DOS
1958 for (plane=0;plane<4;plane++)
1959 #endif
1960 {
1961 VGAWRITEMAP(plane);
1962 buf=(byte *)(bufferofs);
1963 #ifdef DOS
1964 for (post=&posts[plane];post<&posts[viewwidth];post+=4,buf++)
1965 #else
1966 for (post=&posts[plane];post<&posts[viewwidth];post++,buf++)
1967 #endif
1968 {
1969 SetWallLightLevel(post);
1970 DrawWallPost(post,buf);
1971 }
1972 }
1973 }
1974 }
1975
1976
1977 /*
1978 ====================
1979 =
1980 = TransformDoors
1981 =
1982 ====================
1983 */
1984
TransformDoors(void)1985 void TransformDoors( void )
1986 {
1987 int i;
1988 int numvisible;
1989 boolean result;
1990 int gx,gy;
1991 visobj_t visdoorlist[MAXVISIBLEDOORS],*doorptr;
1992
1993 whereami=14;
1994 doorptr=&visdoorlist[0];
1995 //
1996 // place door objects
1997 //
1998
1999 for (i = 0;i<doornum;i++)
2000 {
2001 if (spotvis[doorobjlist[i]->tilex][doorobjlist[i]->tiley])
2002 {
2003 mapseen[doorobjlist[i]->tilex][doorobjlist[i]->tiley]=1;
2004 doorptr->texturestart=0;
2005 doorptr->textureend=0;
2006 if (doorobjlist[i]->vertical)
2007 {
2008 gx=(doorobjlist[i]->tilex<<16)+0x8000;
2009 gy=(doorobjlist[i]->tiley<<16);
2010 if (viewx<gx)
2011 result=TransformPlane(gx,gy,gx,gy+0xffff,doorptr);
2012 else
2013 result=TransformPlane(gx,gy+0xffff,gx,gy,doorptr);
2014 }
2015 else
2016 {
2017 gx=(doorobjlist[i]->tilex<<16);
2018 gy=(doorobjlist[i]->tiley<<16)+0x8000;
2019 if (viewy<gy)
2020 result=TransformPlane(gx+0xffff,gy,gx,gy,doorptr);
2021 else
2022 result=TransformPlane(gx,gy,gx+0xffff,gy,doorptr);
2023 }
2024 if (result==true)
2025 {
2026 doorptr->viewx=0;
2027 doorptr->shapenum=doorobjlist[i]->texture;
2028 doorptr->altshapenum=doorobjlist[i]->alttexture;
2029 if (doorobjlist[i]->texture==doorobjlist[i]->basetexture)
2030 {
2031 doorptr->shapesize=(doorobjlist[i]->tilex<<7)+doorobjlist[i]->tiley;
2032 if (doorptr < &visdoorlist[MAXVISIBLEDOORS-1]) // don't let it overflo'
2033 doorptr++;
2034 }
2035 else
2036 {
2037 doorptr->shapesize=3;
2038 memcpy(visptr,doorptr,sizeof(visobj_t));
2039 if (visptr < &vislist[MAXVISIBLE-1])
2040 visptr++;
2041 }
2042 }
2043 }
2044 }
2045 //
2046 // draw from back to front
2047 //
2048 numvisible = doorptr-&visdoorlist[0];
2049 if (!numvisible)
2050 return;
2051 SortVisibleList( numvisible, &visdoorlist[0] );
2052 for (i = 0; i<numvisible; i++)
2053 {
2054 //
2055 // draw farthest
2056 //
2057 InterpolateWall (sortedvislist[i]);
2058 }
2059 }
2060
2061
2062 /*
2063 ====================
2064 =
2065 = TransformPushWalls
2066 =
2067 ====================
2068 */
2069
TransformPushWalls(void)2070 void TransformPushWalls( void )
2071 {
2072 int i;
2073 int gx,gy;
2074 byte *visspot;
2075 visobj_t *savedptr;
2076 int numvisible;
2077 boolean result;
2078
2079 whereami=15;
2080 savedptr=visptr;
2081 //
2082 // place pwall objects
2083 //
2084 for (i = 0;i<pwallnum;i++)
2085 {
2086 if ((pwallobjlist[i]->action==pw_pushed) || (pwallobjlist[i]->action==pw_npushed))
2087 continue;
2088 visspot = &spotvis[pwallobjlist[i]->x>>16][pwallobjlist[i]->y>>16];
2089 if (*visspot
2090 || ( *(visspot-1))
2091 || ( *(visspot+1))
2092 || ( *(visspot-128))
2093 || ( *(visspot+128)))
2094 {
2095 gx=pwallobjlist[i]->x;
2096 gy=pwallobjlist[i]->y;
2097 mapseen[gx>>16][gy>>16]=1;
2098 if (viewx<gx)
2099 {
2100 if (viewy<gy)
2101 {
2102 visptr->texturestart=(gx-0x8000)&0xffff;
2103 visptr->textureend=visptr->texturestart;
2104 result=TransformPlane(gx+0x7fff,gy-0x8000,gx-0x8000,gy-0x8000,visptr);
2105 visptr->texturestart^=0xffff;
2106 visptr->textureend^=0xffff;
2107 visptr->shapenum=pwallobjlist[i]->texture;
2108 visptr->shapesize=((pwallobjlist[i]->x>>16)<<7)+(pwallobjlist[i]->y>>16);
2109 visptr->viewx+=2;
2110 if ((visptr < &vislist[MAXVISIBLE-1]) && (result==true)) // don't let it overflo'
2111 visptr++;
2112 visptr->texturestart=(gy-0x8000)&0xffff;
2113 visptr->textureend=visptr->texturestart;//-0xffff;
2114 result=TransformPlane(gx-0x8000,gy-0x8000,gx-0x8000,gy+0x7fff,visptr);
2115 }
2116 else
2117 {
2118 visptr->texturestart=(gy-0x8000)&0xffff;
2119 visptr->textureend=visptr->texturestart;//-0xffff;
2120 result=TransformPlane(gx-0x8000,gy-0x8000,gx-0x8000,gy+0x7fff,visptr);
2121 visptr->shapenum=pwallobjlist[i]->texture;
2122 visptr->shapesize=((pwallobjlist[i]->x>>16)<<7)+(pwallobjlist[i]->y>>16);
2123 visptr->viewx+=2;
2124 if ((visptr < &vislist[MAXVISIBLE-1]) && (result==true)) // don't let it overflo'
2125 visptr++;
2126 visptr->texturestart=(gx-0x8000)&0xffff;
2127 visptr->textureend=visptr->texturestart;//-0xffff;
2128 result=TransformPlane(gx-0x8000,gy+0x7fff,gx+0x7fff,gy+0x7fff,visptr);
2129 }
2130 }
2131 else
2132 {
2133 if (viewy<gy)
2134 {
2135 visptr->texturestart=(gy-0x8000)&0xffff;
2136 visptr->textureend=visptr->texturestart;
2137 result=TransformPlane(gx+0x7fff,gy+0x7fff,gx+0x7fff,gy-0x8000,visptr);
2138 visptr->texturestart^=0xffff;
2139 visptr->textureend^=0xffff;
2140 visptr->shapenum=pwallobjlist[i]->texture;
2141 visptr->shapesize=((pwallobjlist[i]->x>>16)<<7)+(pwallobjlist[i]->y>>16);
2142 visptr->viewx+=2;
2143 if ((visptr < &vislist[MAXVISIBLE-1]) && (result==true)) // don't let it overflo'
2144 visptr++;
2145 visptr->texturestart=(gx-0x8000)&0xffff;
2146 visptr->textureend=visptr->texturestart;
2147 result=TransformPlane(gx+0x7fff,gy-0x8000,gx-0x8000,gy-0x8000,visptr);
2148 visptr->texturestart^=0xffff;
2149 visptr->textureend^=0xffff;
2150 }
2151 else
2152 {
2153 visptr->texturestart=(gx-0x8000)&0xffff;
2154 visptr->textureend=visptr->texturestart;//-0xffff;
2155 result=TransformPlane(gx-0x8000,gy+0x7fff,gx+0x7fff,gy+0x7fff,visptr);
2156 visptr->shapenum=pwallobjlist[i]->texture;
2157 visptr->shapesize=((pwallobjlist[i]->x>>16)<<7)+(pwallobjlist[i]->y>>16);
2158 visptr->viewx+=2;
2159 if ((visptr < &vislist[MAXVISIBLE-1]) && (result==true)) // don't let it overflo'
2160 visptr++;
2161 visptr->texturestart=(gy-0x8000)&0xffff;
2162 visptr->textureend=visptr->texturestart;
2163 result=TransformPlane(gx+0x7fff,gy+0x7fff,gx+0x7fff,gy-0x8000,visptr);
2164 visptr->texturestart^=0xffff;
2165 visptr->textureend^=0xffff;
2166 }
2167 }
2168 visptr->viewx+=2;
2169 visptr->shapenum=pwallobjlist[i]->texture;
2170 visptr->shapesize=((pwallobjlist[i]->x>>16)<<7)+(pwallobjlist[i]->y>>16);
2171 if ((visptr < &vislist[MAXVISIBLE-1]) && (result==true)) // don't let it overflo'
2172 visptr++;
2173 }
2174 }
2175
2176
2177 //
2178 // draw from back to front
2179 //
2180 numvisible = visptr-savedptr;
2181 if (!numvisible)
2182 return;
2183 SortVisibleList( numvisible, savedptr );
2184 for (i = 0; i<numvisible; i++)
2185 {
2186 //
2187 // draw farthest
2188 //
2189 if (sortedvislist[i]->shapenum & 0x1000)
2190 sortedvislist[i]->shapenum=animwalls[sortedvislist[i]->shapenum&0x3ff].texture;
2191 sortedvislist[i]->altshapenum=0;
2192 InterpolateWall (sortedvislist[i]);
2193 }
2194 visptr=savedptr;
2195 }
2196
2197 /*
2198 ====================
2199 =
2200 = WallRefresh
2201 =
2202 ====================
2203 */
2204
WallRefresh(void)2205 void WallRefresh (void)
2206 {
2207 volatile int dtime;
2208 int mag;
2209 int yzangle;
2210
2211 whereami=16;
2212 firstcoloffset=(firstcoloffset+(tics<<8))&65535;
2213
2214 dtime=GetFastTics();
2215 if (missobj)
2216 {
2217 viewangle=missobj->angle;
2218 viewx=missobj->x-costable[viewangle];
2219 viewy=missobj->y+sintable[viewangle];
2220 pheight = missobj->z + 32;
2221 nonbobpheight=pheight;
2222 spotvis[missobj->tilex][missobj->tiley]=1;
2223 yzangle=missobj->yzangle;
2224 }
2225 else
2226 {
2227 if (player->flags&FL_SHROOMS)
2228 {
2229 viewangle = (player->angle + FixedMulShift(FINEANGLES,sintable[(GetTicCount()<<5)&(FINEANGLES-1)],(16+4)))&(FINEANGLES-1);
2230 ChangeFocalWidth(FixedMulShift(40,sintable[(GetTicCount()<<5)&(FINEANGLES-1)],16));
2231 }
2232 else
2233 viewangle = player->angle;
2234 if ((viewangle<0) && (viewangle>=FINEANGLES))
2235 Error ("View angle out of range = %ld\n",viewangle);
2236 viewx = player->x;
2237 viewy = player->y;
2238 pheight = player->z + locplayerstate->playerheight + locplayerstate->heightoffset;
2239 nonbobpheight=pheight;
2240 if (
2241 (
2242 (player->z == nominalheight) ||
2243 (IsPlatform(player->tilex,player->tiley)) ||
2244 (DiskAt(player->tilex,player->tiley))
2245 ) &&
2246 (!(player->flags & FL_DOGMODE)) &&
2247 (BobbinOn==true) &&
2248 (GamePaused==false)
2249 )
2250 {
2251 int mag;
2252
2253 mag=(player->speed>MAXBOB ? MAXBOB : player->speed);
2254
2255 pheight+=FixedMulShift(mag,sintable[(GetTicCount()<<7)&2047],28);
2256
2257 weaponbobx=FixedMulShift(mag,costable[((GetTicCount()<<5))&(FINEANGLES-1)],27);
2258 weaponboby=FixedMulShift(mag,sintable[((GetTicCount()<<5))&((FINEANGLES/2)-1)],26);
2259 }
2260 else
2261 {
2262 weaponbobx=0;
2263 weaponboby=0;
2264 }
2265 yzangle=player->yzangle;
2266 spotvis[player->tilex][player->tiley]=1;
2267 }
2268
2269 if (yzangle > ANG180)
2270 pheight -= (sintable[yzangle&2047] >> 14);
2271 else
2272 pheight += (sintable[yzangle&2047] >> 14);
2273
2274 viewx -= (FixedMul(sintable[yzangle&2047],costable[viewangle&2047])>>1);
2275 viewy += (FixedMul(sintable[yzangle&2047],sintable[viewangle&2047])>>1);
2276
2277 // Set YZ angle
2278
2279 centery=viewheight>>1;
2280
2281 if (yzangle>ANG180)
2282 centery-=FixedMul(FINEANGLES-yzangle,yzangleconverter);
2283 else
2284 centery+=FixedMul(yzangle,yzangleconverter);
2285
2286 centeryfrac=(centery<<16);
2287
2288 if (pheight < 1)
2289 pheight = 1;
2290 else if (pheight > maxheight+30)
2291 pheight = maxheight+30;
2292
2293 if (nonbobpheight < 1)
2294 nonbobpheight = 1;
2295 else if (nonbobpheight > maxheight+30)
2296 nonbobpheight = maxheight+30;
2297
2298 // Set light level of touchplates etc.
2299
2300 mag=7+((3-gamestate.difficulty)<<2);
2301
2302 transparentlevel=FixedMul(mag,sintable[(GetTicCount()<<5)&(FINEANGLES-1)])+mag;
2303
2304 viewsin = sintable[viewangle];
2305 viewcos = costable[viewangle];
2306 c_startx=(scale*viewcos)-(centerx*viewsin);
2307 c_starty=(-scale*viewsin)-(centerx*viewcos);
2308 Refresh ();
2309 UpdateClientControls();
2310 TransformPushWalls();
2311 TransformDoors();
2312 UpdateClientControls();
2313 DrawWalls();
2314 UpdateClientControls();
2315 walltime=GetFastTics()-dtime;
2316
2317 }
2318
2319
2320 /*
2321 ====================
2322 =
2323 = GetRainBoundingBox
2324 =
2325 ====================
2326 */
2327
GetRainBoundingBox(int * xmin,int * xmax,int * ymin,int * ymax)2328 void GetRainBoundingBox (int * xmin, int * xmax, int * ymin, int * ymax)
2329 {
2330 wallcast_t * post;
2331 int x,y;
2332
2333 // zero out all boundaries by default
2334
2335 *xmax=0;
2336 *ymax=0;
2337 *xmin=127<<16;
2338 *ymin=127<<16;
2339
2340 // check player's x and y
2341
2342 if (viewx<(*xmin))
2343 (*xmin)=viewx;
2344 else if (viewx>(*xmax))
2345 (*xmax)=viewx;
2346
2347 if (viewy<(*ymin))
2348 (*ymin)=viewy;
2349 else if (viewy>(*ymax))
2350 (*ymax)=viewy;
2351
2352 for (post=&posts[0];post<&posts[viewwidth];post+=(viewwidth>>2))
2353 {
2354 x=(post->offset>>7)<<16;
2355 y=(post->offset&0x7f)<<16;
2356
2357 if (x<(*xmin))
2358 (*xmin)=x;
2359 else if (x>(*xmax))
2360 (*xmax)=x;
2361
2362 if (y<(*ymin))
2363 (*ymin)=y;
2364 else if (y>(*ymax))
2365 (*ymax)=y;
2366 }
2367 }
2368
2369 /*
2370 ========================
2371 =
2372 = InterpolateWall
2373 =
2374 ========================
2375 */
2376
InterpolateWall(visobj_t * plane)2377 void InterpolateWall (visobj_t * plane)
2378 {
2379 int d1,d2;
2380 int top;
2381 int topinc;
2382 int bot;
2383 int botinc;
2384 int i;
2385 int texture;
2386 int dh;
2387 int dx;
2388 int height;
2389 byte * buf;
2390
2391 whereami=17;
2392 dx=(plane->x2-plane->x1+1);
2393 if (plane->h1<=0 || plane->h2<=0 || dx==0)
2394 return;
2395 d1=(1<<(16+HEIGHTFRACTION)) / plane->h1;
2396 d2=(1<<(16+HEIGHTFRACTION)) / plane->h2;
2397 dh=(((plane->h2-plane->h1)<<DHEIGHTFRACTION)+(1<<(DHEIGHTFRACTION-1)))/dx;
2398 top=0;
2399 topinc=FixedMulShift(d1,plane->textureend-plane->texturestart,4);
2400 bot=d2*dx;
2401 botinc=d1-d2;
2402 height=plane->h1<<DHEIGHTFRACTION;
2403 buf=(byte *)bufferofs;
2404 if (plane->x1>=viewwidth)
2405 return;
2406 for (i=plane->x1;i<=plane->x2;i++)
2407 {
2408 if ((i>=0 && i<viewwidth)&&(posts[i].wallheight<=(height>>DHEIGHTFRACTION)))
2409 {
2410 if (bot)
2411 {
2412 texture=((top/bot)+(plane->texturestart>>4))&0xfc0;
2413 posts[i].texture=texture<<4;
2414 posts[i].lump=plane->shapenum;
2415 posts[i].alttile=plane->altshapenum;
2416 posts[i].posttype=plane->viewx;
2417 posts[i].offset=plane->shapesize;
2418 posts[i].wallheight=height>>DHEIGHTFRACTION;
2419 }
2420 }
2421 top+=topinc;
2422 bot+=botinc;
2423 height+=dh;
2424 }
2425 }
2426
2427
2428 /*
2429 ========================
2430 =
2431 = InterpolateDoor
2432 =
2433 ========================
2434 */
2435
InterpolateDoor(visobj_t * plane)2436 void InterpolateDoor (visobj_t * plane)
2437 {
2438 int d1,d2;
2439 int top;
2440 int topinc;
2441 int bot;
2442 int botinc;
2443 int i;
2444 int texture;
2445 int dh;
2446 int dx;
2447 int height;
2448 int bottomscreen;
2449 byte * shape;
2450 byte * shape2;
2451 byte * buf;
2452 patch_t *p;
2453 int pl;
2454
2455 whereami=18;
2456 dx=(plane->x2-plane->x1+1);
2457 if (plane->h1<=0 || plane->h2<=0 || dx==0)
2458 return;
2459 shape=W_CacheLumpNum(plane->shapenum,PU_CACHE, Cvt_patch_t, 1);
2460 shape2=W_CacheLumpNum(plane->altshapenum,PU_CACHE, Cvt_patch_t, 1);
2461 p=(patch_t *)shape;
2462 d1=(1<<(16+HEIGHTFRACTION)) / plane->h1;
2463 d2=(1<<(16+HEIGHTFRACTION)) / plane->h2;
2464 dh=(((plane->h2-plane->h1)<<DHEIGHTFRACTION)+(1<<(DHEIGHTFRACTION-1)))/dx;
2465 topinc=FixedMulShift(d1,plane->textureend-plane->texturestart,4);
2466 botinc=d1-d2;
2467 if (plane->x1>=viewwidth)
2468 return;
2469 #ifdef DOS
2470 for (pl=0;pl<4;pl++)
2471 #endif
2472 {
2473 #ifdef DOS
2474 top=topinc*pl;
2475 bot=(d2*dx)+(pl*botinc);
2476 height=(plane->h1<<DHEIGHTFRACTION)+(dh*pl);
2477 buf=(byte *)bufferofs+((pl+plane->x1)>>2);
2478 VGAWRITEMAP((plane->x1+pl)&3);
2479
2480 for (i=plane->x1+pl;i<=plane->x2;i+=4,buf++)
2481 #else
2482 top=0;
2483 bot=(d2*dx);
2484 height=(plane->h1<<DHEIGHTFRACTION);
2485 buf=(byte *)bufferofs+(plane->x1);
2486
2487 for (i=plane->x1;i<=plane->x2;i++,buf++)
2488 #endif
2489 {
2490 if ((i>=0 && i<viewwidth) && (bot!=0) && (posts[i].wallheight<=(height>>DHEIGHTFRACTION)) )
2491 {
2492 dc_invscale=height>>(HEIGHTFRACTION+DHEIGHTFRACTION-10);
2493 dc_iscale = 0xffffffffu/(unsigned)dc_invscale;
2494 dc_texturemid=((pheight-nominalheight+p->topoffset)<<SFRACBITS)+(SFRACUNIT>>1);
2495 sprtopoffset=centeryfrac - FixedMul(dc_texturemid,dc_invscale);
2496
2497 texture=((top/bot)+(plane->texturestart>>4))>>6;
2498 SetLightLevel(height>>DHEIGHTFRACTION);
2499 ScaleMaskedPost (p->collumnofs[texture]+shape,buf);
2500
2501 if (levelheight>1)
2502 {
2503 sprtopoffset-=(dc_invscale<<6)*(levelheight-1);
2504 bottomscreen =sprtopoffset + (dc_invscale*nominalheight);
2505 dc_yl = (sprtopoffset+SFRACUNIT-1)>>SFRACBITS;
2506 dc_yh = ((bottomscreen-1)>>SFRACBITS)+1;
2507 if (dc_yl >= viewheight)
2508 continue;
2509 else if (dc_yl < 0)
2510 dc_yl = 0;
2511 if (dc_yh > viewheight)
2512 dc_yh = viewheight;
2513
2514 dc_source=shape2+((texture<<6)&0xfc0);
2515 R_DrawWallColumn (buf);
2516 }
2517 }
2518
2519 #ifdef DOS
2520 top+=topinc<<2;
2521 bot+=botinc<<2;
2522 height+=dh<<2;
2523 #else
2524 top+=topinc;
2525 bot+=botinc;
2526 height+=dh;
2527 #endif
2528 }
2529 }
2530 }
2531
2532
2533 /*
2534 ========================
2535 =
2536 = InterpolateMaskedWall
2537 =
2538 ========================
2539 */
2540
InterpolateMaskedWall(visobj_t * plane)2541 void InterpolateMaskedWall (visobj_t * plane)
2542 {
2543 int d1,d2;
2544 int top;
2545 int topinc;
2546 int bot;
2547 int botinc;
2548 int i;
2549 int j;
2550 int texture;
2551 int dh;
2552 int dx;
2553 int height;
2554 byte * shape;
2555 byte * shape2;
2556 byte * shape3;
2557 byte * buf;
2558 transpatch_t *p;
2559 patch_t *p2;
2560 patch_t *p3;
2561 int pl;
2562 boolean drawbottom,drawmiddle,drawtop;
2563 int topoffset;
2564
2565 whereami=19;
2566 dx=(plane->x2-plane->x1+1);
2567 if (plane->h1<=0 || plane->h2<=0 || dx==0)
2568 return;
2569 if (plane->altshapenum>=0)
2570 {
2571 drawmiddle=true;
2572 shape2=W_CacheLumpNum(plane->altshapenum,PU_CACHE, Cvt_patch_t, 1);
2573 p2=(patch_t *)shape2;
2574 topoffset=p2->topoffset;
2575 }
2576 else
2577 {
2578 drawmiddle=false;
2579 }
2580 if (plane->viewx>=0)
2581 {
2582 drawtop=true;
2583 shape3=W_CacheLumpNum(plane->viewx,PU_CACHE, Cvt_patch_t, 1);
2584 p3=(patch_t *)shape3;
2585 topoffset=p3->topoffset;
2586 }
2587 else
2588 {
2589 drawtop=false;
2590 }
2591 if (plane->shapenum>=0)
2592 {
2593 drawbottom=true;
2594 shape=W_CacheLumpNum(plane->shapenum,PU_CACHE, Cvt_transpatch_t, 1);
2595 p = (transpatch_t *)shape;
2596 topoffset=p->topoffset;
2597 }
2598 else
2599 {
2600 drawbottom=false;
2601 }
2602
2603 d1=(1<<(16+HEIGHTFRACTION)) / plane->h1;
2604 d2=(1<<(16+HEIGHTFRACTION)) / plane->h2;
2605 dh=(((plane->h2-plane->h1)<<DHEIGHTFRACTION)+(1<<(DHEIGHTFRACTION-1)))/dx;
2606 topinc=FixedMulShift(d1,plane->textureend-plane->texturestart,4);
2607 botinc=d1-d2;
2608 if (plane->x1>=viewwidth)
2609 return;
2610 #ifdef DOS
2611 for (pl=0;pl<4;pl++)
2612 #endif
2613 {
2614 #ifdef DOS
2615 int planenum;
2616
2617 top=topinc*pl;
2618 bot=(d2*dx)+(pl*botinc);
2619 height=(plane->h1<<DHEIGHTFRACTION)+(dh*pl);
2620 buf=(byte *)bufferofs+((pl+plane->x1)>>2);
2621 planenum=((plane->x1+pl)&3);
2622 VGAWRITEMAP(planenum);
2623 VGAREADMAP(planenum);
2624 for (i=plane->x1+pl;i<=plane->x2;i+=4,buf++)
2625 #else
2626 top=0;
2627 bot=(d2*dx);
2628 height=(plane->h1<<DHEIGHTFRACTION);
2629 buf=(byte *)bufferofs+(plane->x1);
2630 for (i=plane->x1;i<=plane->x2;i++,buf++)
2631 #endif
2632 {
2633 if ((i>=0 && i<viewwidth) && (bot!=0) && (posts[i].wallheight<=(height>>DHEIGHTFRACTION)) )
2634 {
2635 dc_invscale=height>>(HEIGHTFRACTION+DHEIGHTFRACTION-10);
2636 dc_iscale = 0xffffffffu/(unsigned)dc_invscale;
2637 dc_texturemid=((pheight-nominalheight+topoffset)<<SFRACBITS)+(SFRACUNIT>>1);
2638 sprtopoffset=centeryfrac - FixedMul(dc_texturemid,dc_invscale);
2639
2640 texture=((top/bot)+(plane->texturestart>>4))>>6;
2641 SetLightLevel(height>>DHEIGHTFRACTION);
2642 if (drawbottom==true)
2643 ScaleTransparentPost (p->collumnofs[texture]+shape,buf,(p->translevel+8));
2644 for (j=0;j<levelheight-2;j++)
2645 {
2646 sprtopoffset-=(dc_invscale<<6);
2647 dc_texturemid+=(1<<22);
2648 if (drawmiddle==true)
2649 ScaleMaskedPost (p2->collumnofs[texture]+shape2,buf);
2650 }
2651 if (levelheight>1)
2652 {
2653 sprtopoffset-=(dc_invscale<<6);
2654 dc_texturemid+=(1<<22);
2655 if (drawtop==true)
2656 ScaleMaskedPost (p3->collumnofs[texture]+shape3,buf);
2657 }
2658 }
2659 #ifdef DOS
2660 top+=topinc<<2;
2661 bot+=botinc<<2;
2662 height+=dh<<2;
2663 #else
2664 top+=topinc;
2665 bot+=botinc;
2666 height+=dh;
2667 #endif
2668 }
2669 }
2670 }
2671
2672 /*
2673 ========================
2674 =
2675 = DrawPlayerLocation
2676 =
2677 ========================
2678 */
2679 #define PLX (320-24)
2680 #define PLY 16
DrawPlayerLocation(void)2681 void DrawPlayerLocation ( void )
2682 {
2683 int i;
2684 char buf[30];
2685
2686 CurrentFont=tinyfont;
2687
2688 whereami=20;
2689 VGAMAPMASK(15);
2690 for (i=0;i<18;i++)
2691 #ifdef DOS
2692 memset((byte *)bufferofs+(ylookup[i+PLY])+(PLX>>2),0,6);
2693 #else
2694 memset((byte *)bufferofs+(ylookup[i+PLY])+PLX,0,6);
2695 #endif
2696 px=PLX;
2697 py=PLY;
2698 VW_DrawPropString(strupr(itoa(player->x,&buf[0],16)));
2699 px=PLX;
2700 py=PLY+6;
2701 VW_DrawPropString(strupr(itoa(player->y,&buf[0],16)));
2702 px=PLX;
2703 py=PLY+12;
2704 VW_DrawPropString(strupr(itoa(player->angle,&buf[0],16)));
2705 }
2706
2707
2708
2709 /*
2710 ========================
2711 =
2712 = ThreeDRefresh
2713 =
2714 ========================
2715 */
2716
2717
2718 int playerview=0;
ThreeDRefresh(void)2719 void ThreeDRefresh (void)
2720 {
2721 objtype * tempptr;
2722
2723 whereami=21;
2724 tempptr=player;
2725 #if (DEVELOPMENT == 1)
2726 if (Keyboard[sc_9])
2727 {
2728 while (Keyboard[sc_9])
2729 {
2730 IN_UpdateKeyboard();
2731 }
2732 playerview++;
2733 if (playerview>numplayers)
2734 playerview=1;
2735 }
2736 if (playerview!=0)
2737 {
2738 player=PLAYER[playerview-1];
2739 }
2740 #endif
2741
2742 //
2743 // Erase old messages
2744 //
2745
2746 RestoreMessageBackground();
2747
2748 bufferofs += screenofs;
2749
2750 RefreshClear();
2751
2752 UpdateClientControls ();
2753
2754 //
2755 // follow the walls from there to the right, drawwing as we go
2756 //
2757
2758 visptr = &vislist[0];
2759 WallRefresh ();
2760
2761 UpdateClientControls ();
2762
2763 if (fandc)
2764 DrawPlanes();
2765
2766 UpdateClientControls ();
2767
2768 //
2769 // draw all the scaled images
2770 //
2771 DrawScaleds(); // draw scaled stuff
2772
2773 UpdateClientControls ();
2774
2775 if (!missobj)
2776 {
2777 if (locplayerstate->NETCAPTURED && (locplayerstate->NETCAPTURED != -2))
2778 {
2779 int value;
2780
2781 if (locplayerstate->NETCAPTURED < 0)
2782 value = -locplayerstate->NETCAPTURED;
2783 else
2784 value = locplayerstate->NETCAPTURED;
2785 DrawScreenSizedSprite(netlump+value-1);
2786 }
2787 DrawPlayerWeapon (); // draw player's hand'
2788
2789 if (SCREENEYE)
2790 DrawScreenSprite(SCREENEYE->targettilex,SCREENEYE->targettiley,SCREENEYE->state->condition + GIBEYE1 + shapestart);
2791 UpdateClientControls ();
2792
2793 if (player->flags&FL_GASMASK)
2794 DrawScreenSizedSprite(gmasklump);
2795
2796
2797 if ( SHOW_PLAYER_STATS() )
2798 {
2799 DrawStats ();
2800 }
2801
2802 DoBorderShifts ();
2803
2804 UpdateClientControls ();
2805 }
2806
2807 bufferofs -= screenofs;
2808 DrawMessages();
2809 bufferofs += screenofs;
2810
2811 if ( ((GamePaused==true) && (!Keyboard[sc_LShift])) ||
2812 (controlupdatestarted==0)
2813 )
2814 DrawPause ();
2815
2816 //
2817 // show screen and time last cycle
2818 //
2819 if ((fizzlein==true) && (modemgame==false))
2820 {
2821 if (newlevel==true)
2822 ShutdownClientControls();
2823 bufferofs-=screenofs;
2824 DrawPlayScreen (true);
2825 RotateBuffer(0,FINEANGLES,FINEANGLES*8,FINEANGLES,(VBLCOUNTER*3)/4);
2826 bufferofs+=screenofs;
2827 fizzlein = false;
2828 StartupClientControls();
2829 }
2830
2831 bufferofs -= screenofs;
2832
2833 UpdateClientControls ();
2834
2835 if (HUD == true)
2836 DrawPlayerLocation();
2837
2838 FlipPage();
2839 gamestate.frame++;
2840
2841 player=tempptr;
2842 }
2843
2844
2845 //******************************************************************************
2846 //
2847 // FlipPage
2848 //
2849 //******************************************************************************
2850
FlipPage(void)2851 void FlipPage ( void )
2852 {
2853 #ifdef DOS
2854 unsigned displaytemp;
2855
2856 whereami=22;
2857 displayofs = bufferofs;
2858
2859 displaytemp = displayofs;
2860 if ( ( SHAKETICS != 0xFFFF ) && ( !inmenu ) && ( !GamePaused ) &&
2861 ( !fizzlein ) )
2862 {
2863 ScreenShake ();
2864 }
2865
2866
2867 // _disable();
2868 OUTP(CRTC_INDEX,CRTC_STARTHIGH);
2869 OUTP(CRTC_DATA,((displayofs&0x0000ffff)>>8));
2870
2871
2872 if (SHAKETICS != 0xFFFF)
2873 {
2874 if (SHAKETICS > 0)
2875 {
2876 OUTP (CRTC_INDEX, CRTC_STARTLOW);
2877 OUTP (CRTC_DATA, (displayofs&0x000000FF));
2878 displayofs = displaytemp;
2879 }
2880 else
2881 {
2882 displayofs = displaytemp;
2883 OUTP(CRTC_INDEX,CRTC_STARTHIGH);
2884 OUTP(CRTC_DATA,((displayofs&0x0000ffff)>>8));
2885 OUTP (CRTC_INDEX, CRTC_STARTLOW);
2886 OUTP (CRTC_DATA, (displayofs&0x000000FF));
2887 SHAKETICS = 0xFFFF;
2888 }
2889 }
2890 // _enable();
2891
2892 bufferofs += screensize;
2893 if (bufferofs > page3start)
2894 bufferofs = page1start;
2895 #else
2896
2897 whereami=22;
2898
2899 if ( ( SHAKETICS != 0xFFFF ) && ( !inmenu ) && ( !GamePaused ) &&
2900 ( !fizzlein ) )
2901 {
2902 ScreenShake ();
2903 }
2904
2905 /* TODO some shake thing */
2906
2907 /* just call the one in modexlib.c */
2908 XFlipPage();
2909
2910 #endif
2911 }
2912
2913
2914 //******************************************************************************
2915 //
2916 // TurnShakeOff
2917 //
2918 //******************************************************************************
TurnShakeOff(void)2919 void TurnShakeOff
2920 (
2921 void
2922 )
2923
2924 {
2925 // _disable();
2926 OUTP (CRTC_INDEX, CRTC_STARTHIGH );
2927 OUTP (CRTC_DATA, ( ( displayofs & 0x0000ffff ) >> 8 ) );
2928 OUTP (CRTC_INDEX, CRTC_STARTLOW);
2929 OUTP (CRTC_DATA, (displayofs&0x000000FF));
2930 // _enable();
2931 }
2932
2933 //******************************************************************************
2934 //
2935 // DrawScaledScreen
2936 //
2937 //******************************************************************************
2938
DrawScaledScreen(int x,int y,int step,byte * src)2939 void DrawScaledScreen(int x, int y, int step, byte * src)
2940 {
2941 int xfrac;
2942 int yfrac;
2943 int plane;
2944 int i,j;
2945 byte * p;
2946 byte * buf;
2947 int xsize;
2948 int ysize;
2949
2950 xsize=(320<<16)/step;
2951 if (xsize>320) xsize=320;
2952 ysize=(200<<16)/step;
2953 if (ysize>200) ysize=200;
2954
2955 #ifdef DOS
2956 for (plane=x;plane<x+4;plane++)
2957 #endif
2958 {
2959 yfrac=0;
2960 #ifdef DOS
2961 VGAWRITEMAP(plane&3);
2962 #endif
2963 for (j=y;j<y+ysize;j++)
2964 {
2965 p=src+(320*(yfrac>>16));
2966 #ifdef DOS
2967 buf=(byte *)bufferofs+ylookup[j]+(plane>>2);
2968 #else
2969 buf=(byte *)bufferofs+ylookup[j]+x;
2970 #endif
2971 #ifdef DOS
2972 xfrac=(plane-x)*step;
2973 #else
2974 xfrac=0;
2975 #endif
2976 yfrac+=step;
2977 #ifdef DOS
2978 for (i=plane;i<x+xsize;i+=4)
2979 #else
2980 for (i=x;i<x+xsize;i++)
2981 #endif
2982 {
2983 *buf=*(p+(xfrac>>16));
2984 buf++;
2985 #ifdef DOS
2986 xfrac+=(step<<2);
2987 #else
2988 xfrac+=step;
2989 #endif
2990 }
2991 }
2992 }
2993 }
2994
2995
2996 //******************************************************************************
2997 //
2998 // DoLoadGameSequence
2999 //
3000 //******************************************************************************
3001
DoLoadGameSequence(void)3002 void DoLoadGameSequence ( void )
3003 {
3004 int x;
3005 int y;
3006 int dx;
3007 int dy;
3008 int s;
3009 int ds;
3010 int time;
3011 int i;
3012 byte * destscreen;
3013
3014 fizzlein=false;
3015 x=(18+SaveGamePicX)<<16;
3016 y=(30+SaveGamePicY)<<16;
3017 time=VBLCOUNTER;
3018 s=0x2000000;
3019 dx=(-x)/time;
3020 dy=(-y)/time;
3021 ds=-((s-0x1000000)/time);
3022
3023 destscreen=SafeMalloc(64000);
3024
3025 SetupScreen(false);
3026 ThreeDRefresh();
3027 FlipPage();
3028 FlipPage();
3029
3030 VL_CopyPlanarPageToMemory ( (byte *)bufferofs, destscreen );
3031 VL_CopyDisplayToHidden ();
3032
3033 CalcTics();
3034 for (i=0;i<time;i+=tics)
3035 {
3036 CalcTics();
3037 DrawScaledScreen((x>>16),(y>>16),(s>>8),destscreen);
3038 FlipPage();
3039 x+=(dx*tics);
3040 if (x<0) x=0;
3041 y+=(dy*tics);
3042 if (y<0) y=0;
3043 s+=(ds*tics);
3044 }
3045 DrawScaledScreen(0,0,0x10000,destscreen);
3046 FlipPage();
3047 VL_CopyDisplayToHidden ();
3048 SafeFree(destscreen);
3049 CalcTics();
3050 CalcTics();
3051 }
3052
3053 //******************************************************************************
3054 //
3055 // StartupRotateBuffer
3056 //
3057 //******************************************************************************
3058 byte * RotatedImage;
3059 boolean RotateBufferStarted = false;
StartupRotateBuffer(int masked)3060 void StartupRotateBuffer ( int masked)
3061 {
3062 int i,a,b;
3063
3064 if (RotateBufferStarted == true)
3065 return;
3066
3067 RotateBufferStarted = true;
3068
3069 RotatedImage=SafeMalloc(131072);
3070 if (masked==0)
3071 memset(RotatedImage,0,131072);
3072 else
3073 memset(RotatedImage,0xff,131072);
3074 #ifdef DOS
3075 for (i=0;i<4;i++)
3076 #endif
3077 {
3078 VGAREADMAP(i);
3079 for (a=0;a<200;a++)
3080 #ifdef DOS
3081 for (b=0;b<80;b++)
3082 *(RotatedImage+99+i+((a+28)<<9)+(b<<2))=*((byte *)bufferofs+(a*linewidth)+b);
3083 #else
3084 for (b=0;b<320;b++)
3085 *(RotatedImage+99+((a+28)<<9)+b)=*((byte *)bufferofs+(a*linewidth)+b);
3086 #endif
3087 }
3088 }
3089
3090 //******************************************************************************
3091 //
3092 // ShutdownRotateBuffer
3093 //
3094 //******************************************************************************
3095
ShutdownRotateBuffer(void)3096 void ShutdownRotateBuffer ( void )
3097 {
3098 if (RotateBufferStarted == false)
3099 return;
3100
3101 RotateBufferStarted = false;
3102 SafeFree(RotatedImage);
3103 }
3104
3105 //******************************************************************************
3106 //
3107 // ScaleAndRotateBuffer
3108 //
3109 //******************************************************************************
3110
ScaleAndRotateBuffer(int startangle,int endangle,int startscale,int endscale,int time)3111 void ScaleAndRotateBuffer (int startangle, int endangle, int startscale, int endscale, int time)
3112 {
3113 int anglestep;
3114 int scalestep;
3115 int angle;
3116 int scale;
3117 int i;
3118
3119 anglestep=((endangle-startangle)<<16)/time;
3120 scalestep=((endscale-startscale)<<6)/time;
3121
3122 angle=(startangle<<16);
3123 scale=(startscale<<6);
3124
3125 CalcTics();
3126 CalcTics();
3127 for (i=0;i<time;i+=tics)
3128 {
3129 DrawRotatedScreen(160,100, (byte *)bufferofs,(angle>>16)&(FINEANGLES-1),scale>>6,0);
3130 FlipPage();
3131 scale+=(scalestep*tics);
3132 angle+=(anglestep*tics);
3133 CalcTics();
3134 }
3135 DrawRotatedScreen(160,100, (byte *)bufferofs,endangle&(FINEANGLES-1),endscale,0);
3136 FlipPage();
3137 DrawRotatedScreen(160,100, (byte *)bufferofs,endangle&(FINEANGLES-1),endscale,0);
3138 FlipPage();
3139 DrawRotatedScreen(160,100, (byte *)bufferofs,endangle&(FINEANGLES-1),endscale,0);
3140 CalcTics();
3141 CalcTics();
3142 }
3143
3144 //******************************************************************************
3145 //
3146 // RotateBuffer
3147 //
3148 //******************************************************************************
3149
RotateBuffer(int startangle,int endangle,int startscale,int endscale,int time)3150 void RotateBuffer (int startangle, int endangle, int startscale, int endscale, int time)
3151 {
3152 int savetics;
3153
3154 //save off fastcounter
3155
3156 savetics=GetFastTics();
3157
3158 StartupRotateBuffer (0);
3159
3160 ScaleAndRotateBuffer (startangle, endangle, startscale, endscale, time);
3161
3162 ShutdownRotateBuffer ();
3163
3164 // restore fast counter
3165 SetFastTics(savetics);
3166 }
3167
3168
3169 //******************************************************************************
3170 //
3171 // DrawRotatedScreen
3172 //
3173 //******************************************************************************
3174
DrawRotatedScreen(int cx,int cy,byte * destscreen,int angle,int scale,int masked)3175 void DrawRotatedScreen(int cx, int cy, byte *destscreen, int angle, int scale, int masked)
3176 {
3177 int c, s;
3178 int xst, xct;
3179 int y;
3180 int plane;
3181 byte * screen;
3182
3183 c = FixedMulShift(scale,costable[angle],11);
3184 s = FixedMulShift(scale,sintable[angle],11);
3185 xst = (((-cx)*s)+(128<<16))-(cy*c);
3186 xct = (((-cx)*c)+(256<<16)+(1<<18)-(1<<16))+(cy*s);
3187 #ifdef DOS
3188 mr_xstep=s<<2;
3189 mr_ystep=c<<2;
3190 #else
3191 mr_xstep=s;
3192 mr_ystep=c;
3193 #endif
3194 screen=destscreen;
3195
3196 if (masked==0)
3197 {
3198 #ifdef DOS
3199 for (plane=0;plane<4;plane++,xst+=s,xct+=c)
3200 #endif
3201 {
3202 mr_yfrac=xct;
3203 mr_xfrac=xst;
3204 VGAWRITEMAP(plane);
3205 for (y=0; y<200; y++,mr_xfrac+=c,mr_yfrac-=s)
3206 #ifdef DOS
3207 DrawRotRow(((320-plane)>>2)+1,screen+ylookup[y]+(plane>>2),RotatedImage);
3208 #else
3209 DrawRotRow(320,screen+ylookup[y],RotatedImage);
3210 #endif
3211 }
3212 }
3213 else
3214 {
3215 #ifdef DOS
3216 for (plane=0;plane<4;plane++,xst+=s,xct+=c)
3217 #endif
3218 {
3219 mr_yfrac=xct;
3220 mr_xfrac=xst;
3221 VGAWRITEMAP(plane);
3222 for (y=0; y<200; y++,mr_xfrac+=c,mr_yfrac-=s)
3223 #ifdef DOS
3224 DrawMaskedRotRow(((320-plane)>>2)+1,screen+ylookup[y]+(plane>>2),RotatedImage);
3225 #else
3226 DrawMaskedRotRow(320,screen+ylookup[y],RotatedImage);
3227 #endif
3228 }
3229 }
3230 }
3231
3232
3233 //******************************************************************************
3234 //
3235 // DrawScaledPost
3236 //
3237 //******************************************************************************
3238
DrawScaledPost(int height,byte * src,int offset,int x)3239 void DrawScaledPost ( int height, byte * src, int offset, int x)
3240 {
3241 patch_t *p;
3242
3243 p=(patch_t *)src;
3244 dc_invscale=(height<<16)/p->origsize;
3245 dc_iscale=(p->origsize<<16)/height;
3246 dc_texturemid=(((p->origsize>>1)+p->topoffset)<<SFRACBITS)+(SFRACUNIT>>1);
3247 sprtopoffset=centeryfrac - FixedMul(dc_texturemid,dc_invscale);
3248 shadingtable=colormap+(1<<12);
3249 VGAWRITEMAP(x&3);
3250 #ifdef DOS
3251 ScaleMaskedPost(((p->collumnofs[offset])+src), (byte *)bufferofs+(x>>2));
3252 #else
3253 ScaleMaskedPost(((p->collumnofs[offset])+src), (byte *)bufferofs+x);
3254 #endif
3255 }
3256
3257
3258
ApogeeTitle(void)3259 void ApogeeTitle (void)
3260 {
3261 byte pal[768];
3262 int angle;
3263 int scale;
3264 int x,y;
3265 int danglex;
3266 int anglex;
3267 int dy,dangle,dscale;
3268 int time;
3269
3270 CalcTics();
3271 CalcTics();
3272 IN_ClearKeysDown();
3273 viewwidth=320;
3274 viewheight=200;
3275 memcpy(&pal[0],W_CacheLumpName("ap_pal",PU_CACHE, CvtNull, 1),768);
3276 shadingtable=colormap+(1<<12);
3277 VL_NormalizePalette(&pal[0]);
3278 SwitchPalette(&pal[0],35);
3279 // DrawWorld();
3280 // RotateBuffer(0,FINEANGLES*6,FINEANGLES*48,FINEANGLES,(VBLCOUNTER*2));
3281 // DoLaserShoot("apogee");
3282 // DoZIntro();
3283
3284 VL_ClearBuffer (bufferofs, 255);
3285 DrawNormalSprite (0, 0, W_GetNumForName("ap_titl"));
3286
3287 StartupRotateBuffer (1);
3288
3289 //save off fastcounter
3290
3291 #define APOGEEXANGLE 913
3292 #define APOGEEXMAG 180
3293 #define APOGEESTARTY 0
3294 #define APOGEEENDY 100
3295
3296 #define APOGEESCALESTART (FINEANGLES<<4)
3297 #define APOGEESCALEEND (FINEANGLES)
3298 #define APOGEESONGTIME (124-1)
3299
3300 time = APOGEESONGTIME;
3301
3302 anglex=0;
3303 danglex=(APOGEEXANGLE<<16)/time;
3304
3305 y=APOGEESTARTY<<16;
3306 dy=((APOGEEENDY-APOGEESTARTY)<<16)/time;
3307
3308 dscale=((APOGEESCALEEND-APOGEESCALESTART)<<16)/time;
3309 scale=APOGEESCALESTART<<16;
3310
3311 angle=0;
3312 dangle=(FINEANGLES<<17)/time;
3313
3314 MU_StartSong(song_apogee);
3315
3316 CalcTics();
3317
3318 while (time>=0)
3319 {
3320 VL_DrawPostPic (W_GetNumForName("ap_wrld"));
3321 IN_PumpEvents();
3322
3323 x=100+FixedMul(APOGEEXMAG,sintable[anglex>>16]);
3324
3325 DrawRotatedScreen(x,y>>16,(byte *)bufferofs,(angle>>16)&(FINEANGLES-1),scale>>16,1);
3326 FlipPage();
3327 CalcTics();
3328 angle+=dangle*tics;
3329 scale+=dscale*tics;
3330 y+=dy*tics;
3331 anglex+=danglex*tics;
3332 time-=tics;
3333 if ((LastScan) || IN_GetMouseButtons())
3334 goto apogeeexit;
3335 }
3336 CalcTics();
3337 CalcTics();
3338 VL_DrawPostPic (W_GetNumForName("ap_wrld"));
3339 DrawRotatedScreen(x,y>>16,(byte *)bufferofs,0,APOGEESCALEEND,1);
3340 FlipPage();
3341
3342 while (MU_SongPlaying())
3343 {
3344 IN_PumpEvents();
3345 if ((LastScan) || IN_GetMouseButtons())
3346 goto apogeeexit;
3347 }
3348
3349 apogeeexit:
3350 ShutdownRotateBuffer ();
3351 }
3352
3353 #if (SHAREWARE==0)
3354
DopefishTitle(void)3355 void DopefishTitle (void)
3356 {
3357 int shapenum;
3358 int height;
3359
3360 shapenum=W_GetNumForName("scthead1");
3361 CalcTics();
3362 CalcTics();
3363 IN_ClearKeysDown();
3364 MU_StartSong( song_secretmenu);
3365 viewwidth=320;
3366 viewheight=200;
3367 SwitchPalette(origpal,35);
3368 oldtime=GetTicCount();
3369 FlipPage();
3370 for (height=1;height<200;height+=(tics<<2))
3371 {
3372 DrawPositionedScaledSprite (160, 100, shapenum, height, 0);
3373 FlipPage();
3374 CalcTics();
3375 if ((LastScan) || IN_GetMouseButtons())
3376 break;
3377 }
3378 SD_Play ( SD_DOPEFISHSND );
3379 oldtime=GetTicCount();
3380 for (height=0;height<FINEANGLES<<1;height+=(tics<<5))
3381 {
3382 DrawPositionedScaledSprite (160+FixedMul(60,costable[height&(FINEANGLES-1)]), 100+FixedMul(60,sintable[height&(FINEANGLES-1)]), shapenum, 200, 0);
3383 FlipPage();
3384 VL_CopyPlanarPage ( (byte *) displayofs, (byte *) bufferofs );
3385 CalcTics();
3386 if ((LastScan) || IN_GetMouseButtons())
3387 break;
3388 }
3389 SD_Play ( SD_DOPEFISHSND );
3390 FlipPage();
3391 }
3392
3393 #endif
3394
3395 //******************************************************************************
3396 //
3397 // RotationFun
3398 //
3399 //******************************************************************************
3400
RotationFun(void)3401 void RotationFun ( void )
3402 {
3403 int angle;
3404 int scale;
3405 int x,y;
3406 word buttons;
3407
3408 //save off fastcounter
3409
3410
3411 angle=0;
3412 scale=FINEANGLES;
3413
3414 StartupRotateBuffer (0);
3415
3416 CalcTics();
3417 CalcTics();
3418 while (!Keyboard[sc_Escape])
3419 {
3420 IN_UpdateKeyboard ();
3421 DrawRotatedScreen(160,100,(byte *)bufferofs,angle,scale,0);
3422 FlipPage();
3423 CalcTics();
3424 INL_GetMouseDelta(&x, &y);
3425 buttons=IN_GetMouseButtons ();
3426 angle=(angle-x)&(FINEANGLES-1);
3427 if (buttons & (1 << 0))
3428 {
3429 if (scale>0)
3430 scale-=30;
3431 }
3432 else if (buttons & (1 << 1))
3433 {
3434 scale+=30;
3435 }
3436 }
3437 CalcTics();
3438 CalcTics();
3439 Keyboard[sc_Escape]=0;
3440
3441 ShutdownRotateBuffer ();
3442 }
3443
3444 boolean ScreenSaverStarted=false;
3445 screensaver_t * ScreenSaver;
3446 #define PAUSETIME (70)
3447
3448 //******************************************************************************
3449 //
3450 // SetupScreenSaverPhase
3451 //
3452 //******************************************************************************
SetupScreenSaverPhase(void)3453 void SetupScreenSaverPhase ( void )
3454 {
3455 if (ScreenSaverStarted==false)
3456 return;
3457
3458 if (ScreenSaver->phase==0)
3459 {
3460 ScreenSaver->x=160;
3461 ScreenSaver->y=100;
3462 ScreenSaver->angle=0;
3463 ScreenSaver->scale=FINEANGLES;
3464 ScreenSaver->dangle=FINEANGLES/VBLCOUNTER;
3465 ScreenSaver->dx=0;
3466 ScreenSaver->dy=0;
3467 ScreenSaver->dscale=((FINEANGLES<<2)-(FINEANGLES))/VBLCOUNTER;
3468 ScreenSaver->time=VBLCOUNTER;
3469 }
3470 else if (ScreenSaver->phase==1)
3471 {
3472 ScreenSaver->x=160;
3473 ScreenSaver->y=100;
3474 ScreenSaver->angle=0;
3475 ScreenSaver->scale=FINEANGLES<<2;
3476 ScreenSaver->dangle=FINEANGLES/VBLCOUNTER;
3477 ScreenSaver->dx=RandomNumber("StartupScreen",0)>>5;
3478 ScreenSaver->dy=RandomNumber("StartupScreen",0)>>5;
3479 ScreenSaver->dscale=0;
3480 ScreenSaver->time=-1;
3481 }
3482 }
3483
3484 //******************************************************************************
3485 //
3486 // StartupScreenSaver
3487 //
3488 //******************************************************************************
StartupScreenSaver(void)3489 void StartupScreenSaver ( void )
3490 {
3491 if (ScreenSaverStarted==true)
3492 return;
3493
3494 ScreenSaverStarted=true;
3495
3496 StartupRotateBuffer (0);
3497
3498 ScreenSaver=(screensaver_t *)SafeMalloc(sizeof(screensaver_t));
3499 ScreenSaver->phase=0;
3500 ScreenSaver->pausetime=PAUSETIME;
3501 ScreenSaver->pausex=120;
3502 ScreenSaver->pausey=84;
3503 SetupScreenSaverPhase();
3504 }
3505
3506 //******************************************************************************
3507 //
3508 // ShutdownScreenSaver
3509 //
3510 //******************************************************************************
ShutdownScreenSaver(void)3511 void ShutdownScreenSaver ( void )
3512 {
3513 if (ScreenSaverStarted==false)
3514 return;
3515
3516 ScreenSaverStarted=false;
3517
3518 ShutdownRotateBuffer ();
3519 SafeFree(ScreenSaver);
3520 }
3521
3522 //******************************************************************************
3523 //
3524 // UpdateScreenSaver
3525 //
3526 //******************************************************************************
3527
3528 #define SPINSIZE 40
3529 #define MAXSPEED 8
UpdateScreenSaver(void)3530 void UpdateScreenSaver ( void )
3531 {
3532 if (ScreenSaver->time!=-1)
3533 {
3534 ScreenSaver->time-=tics;
3535 if (ScreenSaver->time<0)
3536 {
3537 ScreenSaver->phase++;
3538 SetupScreenSaverPhase();
3539 }
3540 }
3541 ScreenSaver->x+=ScreenSaver->dx*tics;
3542 ScreenSaver->y+=ScreenSaver->dy*tics;
3543 ScreenSaver->angle=(ScreenSaver->angle+(ScreenSaver->dangle*tics))&(FINEANGLES-1);
3544 ScreenSaver->scale+=ScreenSaver->dscale*tics;
3545 if (ScreenSaver->x<SPINSIZE)
3546 {
3547 ScreenSaver->x=SPINSIZE;
3548 ScreenSaver->dx=abs(ScreenSaver->dx);
3549 ScreenSaver->dy+=(RandomNumber("Rotate",0)>>6)-2;
3550 }
3551 else if (ScreenSaver->x>320-SPINSIZE)
3552 {
3553 ScreenSaver->x=320-SPINSIZE;
3554 ScreenSaver->dx=-(abs(ScreenSaver->dx));
3555 ScreenSaver->dy+=(RandomNumber("Rotate",0)>>6)-2;
3556 }
3557 if (ScreenSaver->y<SPINSIZE)
3558 {
3559 ScreenSaver->y=SPINSIZE;
3560 ScreenSaver->dy=abs(ScreenSaver->dy);
3561 ScreenSaver->dx+=(RandomNumber("Rotate",0)>>6)-2;
3562 }
3563 else if (ScreenSaver->y>200-SPINSIZE)
3564 {
3565 ScreenSaver->y=200-SPINSIZE;
3566 ScreenSaver->dy=-(abs(ScreenSaver->dy));
3567 ScreenSaver->dx+=(RandomNumber("Rotate",0)>>6)-2;
3568 }
3569
3570 if (abs(ScreenSaver->dx)>MAXSPEED)
3571 ScreenSaver->dx=SGN(ScreenSaver->dx)*MAXSPEED;
3572
3573 if (abs(ScreenSaver->dy)>MAXSPEED)
3574 ScreenSaver->dy=SGN(ScreenSaver->dy)*MAXSPEED;
3575
3576 DrawRotatedScreen(ScreenSaver->x,ScreenSaver->y, (byte *)bufferofs,ScreenSaver->angle,ScreenSaver->scale,0);
3577
3578 ScreenSaver->pausetime-=tics;
3579 if (ScreenSaver->pausetime<=0)
3580 {
3581 ScreenSaver->pausetime=PAUSETIME;
3582 ScreenSaver->pausex=RandomNumber ("pausex",0)%240;
3583 ScreenSaver->pausey=RandomNumber ("pausey",0)%168;
3584 }
3585 DrawPauseXY (ScreenSaver->pausex, ScreenSaver->pausey);
3586
3587 FlipPage();
3588 }
3589 #if 0
3590
3591 //******************************************************************************
3592 //
3593 // DoLaserShoot
3594 //
3595 //******************************************************************************
3596 void DoLaserShoot (char * name)
3597 {
3598
3599 int sourcex;
3600 int lastx;
3601 int sourceheight;
3602 int destheight;
3603 int sourcestep;
3604 int xstep;
3605 int hstep;
3606 int midx;
3607 int startx;
3608 int dx;
3609 int f;
3610 int s;
3611 int height;
3612 int x;
3613 int sx;
3614 int size;
3615 patch_t *p;
3616 byte * shape;
3617
3618 DrawWorld();
3619 midx=160;
3620 shape=W_CacheLumpName(name,PU_CACHE);
3621 p=(patch_t *)shape;
3622 size=p->origsize;
3623
3624 startx=midx-(size>>1)-(p->leftoffset);
3625
3626 sourcex=0;
3627 lastx=startx+p->width;
3628 sourcestep=(320*65536)/p->width;
3629 sourceheight=p->origsize<<3;
3630 destheight=p->origsize;
3631 CalcTics();
3632 CalcTics();
3633
3634
3635 for (x=startx;x<lastx;x+=tics,sourcex+=(sourcestep*tics))
3636 {
3637 for (f=startx;f<=x;f++)
3638 DrawScaledPost(destheight,shape,f-startx,f);
3639 height=sourceheight<<16;
3640 if (x<=midx)
3641 {
3642 dx=x-(sourcex>>16);
3643 xstep=1;
3644 }
3645 else
3646 {
3647 dx=(sourcex>>16)-x;
3648 xstep=-1;
3649 }
3650 sx=sourcex>>16;
3651 if (dx)
3652 hstep=((-destheight+sourceheight)<<16)/dx;
3653 else
3654 hstep=0;
3655 for (s=0;s<dx;s++,height-=hstep,sx+=xstep)
3656 DrawScaledPost(height>>16,shape,x-startx,sx);
3657 FlipPage();
3658 CalcTics();
3659 DrawWorld();
3660 break;
3661 }
3662
3663 // Write out one more time so that the rest of the screen is clear
3664
3665 for (f=startx;f<lastx;f++)
3666 DrawScaledPost(destheight,shape,f-startx,f);
3667 FlipPage();
3668 }
3669
3670 //******************************************************************************
3671 //
3672 // DoIntro
3673 //
3674 //******************************************************************************
3675
3676 #define MAXMAG (80)
3677 #define OSCTIME (5*VBLCOUNTER)
3678 #define OSCXSHIFT (4)
3679 #define OSCTSHIFT (4)
3680
3681 void DoIntro (void)
3682 {
3683 byte * shape;
3684 byte * origshape;
3685 int mag;
3686 int currentmag;
3687 int magstep;
3688 int time;
3689 int x;
3690 int t;
3691
3692 shadingtable=colormap+(1<<12);
3693
3694 origshape=W_CacheLumpName("ap_wrld",PU_CACHE);
3695
3696 mag=MAXMAG<<16;
3697 magstep = (MAXMAG<<16)/OSCTIME;
3698 time = OSCTIME;
3699 t=0;
3700
3701 CalcTics();
3702
3703 while (time>0)
3704 {
3705 int yoffset;
3706 int ylow;
3707 int yhigh;
3708 int offset;
3709 int postheight;
3710 byte * src;
3711
3712 shape=origshape;
3713 VL_ClearBuffer (bufferofs, 0);
3714 currentmag=mag>>16;
3715 for (x=0;x<320;x++,shape+=200)
3716 {
3717 VGAWRITEMAP(x&3);
3718 src=shape;
3719 offset=(t+(x<<OSCXSHIFT))&(FINEANGLES-1);
3720 yoffset=FixedMul(currentmag,sintable[offset]);
3721 ylow=yoffset;
3722 if (ylow<0)
3723 {
3724 src-=ylow;
3725 ylow=0;
3726 }
3727 if (ylow>199)
3728 ylow=199;
3729 yhigh=yoffset+200;
3730 if (yhigh>199)
3731 {
3732 yhigh=199;
3733 }
3734 if (yhigh<0)
3735 yhigh=0;
3736 postheight=yhigh-ylow+1;
3737 if (postheight>0)
3738 #ifdef DOS
3739 DrawSkyPost((byte *)bufferofs + (x>>2) + ylookup[ylow],src,postheight);
3740 #else
3741 DrawSkyPost((byte *)bufferofs + x + ylookup[ylow],src,postheight);
3742 #endif
3743 }
3744 FlipPage();
3745 CalcTics();
3746 mag -= (magstep * tics);
3747 time -= tics;
3748 t += (tics<<OSCTSHIFT);
3749 if (mag<0) mag = 0;
3750 }
3751 }
3752
3753
3754 //******************************************************************************
3755 //
3756 // DoZIntro
3757 //
3758 //******************************************************************************
3759
3760 #define ZMAXMAG (199)
3761 #define ZOSCTIME (3*VBLCOUNTER)
3762 #define ZOSCXSHIFT (2)
3763 #define ZOSCXSTEP ( (FINEANGLES<<(ZOSCXSHIFT+16))/320 )
3764 #define ZOSCTSHIFT (2)
3765
3766 void DoZIntro (void)
3767 {
3768 byte * shape;
3769 int mag;
3770 int currentmag;
3771 int magstep;
3772 int time;
3773 int x;
3774 int t;
3775
3776 SetViewSize (MAXVIEWSIZES-1);
3777
3778 shadingtable=colormap+(1<<12);
3779
3780 shape=W_CacheLumpName("ap_wrld",PU_CACHE);
3781
3782 mag=ZMAXMAG<<16;
3783 magstep = (ZMAXMAG<<16)/ZOSCTIME;
3784 time = ZOSCTIME;
3785 t=0;
3786
3787 CalcTics();
3788
3789
3790 while (time>0)
3791 {
3792 int zoffset;
3793 int hoffset;
3794 int offset;
3795 int srcoffset;
3796 int bottomscreen;
3797 int src;
3798 // int i;
3799
3800
3801 VL_ClearBuffer (bufferofs, 0);
3802 currentmag=mag>>16;
3803
3804 srcoffset=0;
3805 for (x=0;x<320;)
3806 {
3807 VGAWRITEMAP(x&3);
3808
3809 offset=(t+(FixedMul(x,ZOSCXSTEP)))&(FINEANGLES-1);
3810 zoffset=FixedMul(currentmag,sintable[offset]);
3811 // hoffset=FixedMulShift(currentmag,sintable[offset],17);
3812 hoffset=0;
3813 dc_texturemid=((100+hoffset)<<SFRACBITS)+(SFRACUNIT>>1);
3814
3815 dc_invscale=((200+zoffset)<<16)/200;
3816 dc_iscale=0xffffffffu/(unsigned)dc_invscale;
3817
3818 srcoffset+=dc_invscale;
3819 sprtopoffset=centeryfrac - FixedMul(dc_texturemid,dc_invscale);
3820 bottomscreen = sprtopoffset + (dc_invscale*200);
3821 dc_yl = (sprtopoffset+SFRACUNIT-1)>>SFRACBITS;
3822 dc_yh = ((bottomscreen-1)>>SFRACBITS);
3823 if (dc_yh >= viewheight)
3824 dc_yh = viewheight-1;
3825 if (dc_yl < 0)
3826 dc_yl = 0;
3827 if (dc_yl <= dc_yh)
3828 {
3829 src=srcoffset>>16;
3830 if (src>319)
3831 src=319;
3832 if (src<0)
3833 src=0;
3834 dc_source=shape+(src * 200);
3835 // if (RandomNumber("hello",0)<128)
3836 #ifdef DOS
3837 R_DrawColumn ((byte *)bufferofs+(x>>2));
3838 #else
3839 R_DrawColumn ((byte *)bufferofs+x);
3840 #endif
3841 }
3842 // srcoffset+=0x10000;
3843 x++;
3844 if ((LastScan) || IN_GetMouseButtons())
3845 return;
3846 }
3847 FlipPage();
3848 CalcTics();
3849 mag -= (magstep * tics);
3850 // mag += FixedMulShift((magstep * tics),sintable[time&(FINEANGLES-1)],19);
3851 time -= tics;
3852 t += (tics<<ZOSCTSHIFT);
3853 if (mag<0) mag = 0;
3854 }
3855 }
3856 #endif
3857
3858
3859
3860 // Old Stuff
3861
3862 /*
3863 int y1;
3864 int y2;
3865
3866 if (post->alttile!=0)
3867 {
3868 ht=nominalheight;
3869 src2=W_CacheLumpNum(1+post->alttile,PU_CACHE);
3870 // src2+=8;
3871 }
3872 else
3873 {
3874 ht=maxheight;
3875 src2=src;
3876 }
3877 hp_srcstep=(64<<(16+HEIGHTFRACTION))/post->wallheight;
3878 y1 = (((centery<<HFRACTION)-(post->wallheight*pheight)+(1<<(HFRACTION-1))));
3879 y2 = (((post->wallheight*ht)+y1)>>HFRACTION);
3880
3881 if ((y1>>HFRACTION)>=viewheight)
3882 {
3883 post->ceilingclip=viewheight-1;
3884 post->floorclip=viewheight-1;
3885 return;
3886 }
3887 else if (y1<0)
3888 {
3889 hp_startfrac=FixedMulShift(-y1,hp_srcstep,HFRACTION);
3890 y1=0;
3891 post->ceilingclip=0;
3892 }
3893 else
3894 {
3895 hp_startfrac=FixedMulShift(255-(y1&0xff),hp_srcstep,HFRACTION);
3896 y1>>=HFRACTION;
3897 post->ceilingclip=y1;
3898 }
3899 if (y2<0)
3900 {
3901 post->floorclip=0;
3902 post->ceilingclip=0;
3903 }
3904 else if (y2>viewheight)
3905 {
3906 DrawHeightPost(viewheight-y1, src2+((post->texture>>4)&0xfc0), buf+ylookup[y1]);
3907 post->floorclip=viewheight-1;
3908 }
3909 else
3910 {
3911 DrawHeightPost(y2-y1, src2+((post->texture>>4)&0xfc0), buf+ylookup[y1]);
3912 post->floorclip=y2-1;
3913 }
3914
3915 if (ht==maxheight)
3916 return;
3917
3918 y1 = (((centery<<HFRACTION)-(post->wallheight*(pheight-ht))+(1<<(HFRACTION-1))));
3919 y2 = (((post->wallheight<<6)+y1)>>HFRACTION);
3920
3921 if ((y1>>HFRACTION)>=viewheight)
3922 return;
3923 else if (y1<0)
3924 {
3925 hp_startfrac=FixedMulShift(-y1,hp_srcstep,HFRACTION);
3926 y1=0;
3927 }
3928 else
3929 {
3930 hp_startfrac=FixedMulShift(255-(y1&0xff),hp_srcstep,HFRACTION);
3931 y1>>=HFRACTION;
3932 }
3933 if (y2<0)
3934 return;
3935 else if (y2>viewheight)
3936 {
3937 DrawHeightPost(viewheight-y1, src+((post->texture>>4)&0xfc0), buf+ylookup[y1]);
3938 post->floorclip=viewheight-1;
3939 }
3940 else
3941 {
3942 DrawHeightPost(y2-y1, src+((post->texture>>4)&0xfc0), buf+ylookup[y1]);
3943 post->floorclip=y2-1;
3944 }
3945 }
3946 */
3947
3948
3949
3950
3951
3952
3953 //******************************************************************************
3954 //
3955 // DrawBackground
3956 //
3957 //******************************************************************************
3958
DrawBackground(byte * bkgnd)3959 void DrawBackground ( byte * bkgnd )
3960 {
3961 int plane;
3962 int size;
3963
3964 size=linewidth*200;
3965
3966 #ifdef DOS
3967 for (plane=0;plane<4;plane++)
3968 #endif
3969 {
3970 VGAWRITEMAP(plane);
3971 memcpy((byte *)bufferofs,bkgnd,size);
3972 bkgnd+=size;
3973 }
3974 }
3975
3976
3977 //******************************************************************************
3978 //
3979 // PrepareBackground
3980 //
3981 //******************************************************************************
3982
PrepareBackground(byte * bkgnd)3983 void PrepareBackground ( byte * bkgnd )
3984 {
3985 int plane;
3986 int size;
3987
3988 size=linewidth*200;
3989
3990 #ifdef DOS
3991 for (plane=0;plane<4;plane++)
3992 #endif
3993 {
3994 VGAREADMAP(plane);
3995 memcpy(bkgnd,(byte *)bufferofs,size);
3996 bkgnd+=size;
3997 }
3998 }
3999
4000 //******************************************************************************
4001 //
4002 // WarpString
4003 //
4004 //******************************************************************************
4005
WarpString(int x,int y,int endx,int endy,int time,byte * back,char * str)4006 void WarpString (
4007 int x, int y, int endx, int endy,
4008 int time, byte * back, char * str
4009 )
4010 {
4011 int dx;
4012 int dy;
4013 int cx;
4014 int cy;
4015 int starttime;
4016
4017
4018 LastScan = 0;
4019
4020
4021 dx=((endx-x)<<16)/time;
4022 dy=((endy-y)<<16)/time;
4023 cx=x<<16;
4024 cy=y<<16;
4025 starttime=time;
4026
4027 CalcTics();
4028
4029 while (time>0)
4030 {
4031
4032 DrawBackground ( back );
4033 US_ClippedPrint (cx>>16, cy>>16, str);
4034 FlipPage();
4035
4036 CalcTics();
4037 cx+=dx*tics;
4038 cy+=dy*tics;
4039 time-=tics;
4040 if (LastScan != 0)
4041 break;
4042 }
4043
4044 // DrawBackground ( back );
4045 // US_ClippedPrint (endx, endy, str);
4046 // FlipPage();
4047
4048 }
4049
4050
4051 #if (SHAREWARE==1)
4052 //******************************************************************************
4053 //
4054 // DoEndCinematic
4055 //
4056 //******************************************************************************
4057
4058 //******************************************************************************
4059 //
4060 // WarpSprite
4061 //
4062 //******************************************************************************
4063
WarpSprite(int x,int y,int endx,int endy,int time,byte * back,int shape)4064 void WarpSprite (
4065 int x, int y, int endx, int endy,
4066 int time, byte * back, int shape
4067 )
4068 {
4069 int dx;
4070 int dy;
4071 int cx;
4072 int cy;
4073 int starttime;
4074
4075 LastScan = 0;
4076
4077 dx=((endx-x)<<16)/time;
4078 dy=((endy-y)<<16)/time;
4079 cx=x<<16;
4080 cy=y<<16;
4081 starttime=time;
4082
4083 CalcTics();
4084
4085 while (time>0)
4086 {
4087 DrawBackground ( back );
4088 DrawUnScaledSprite (cx>>16, cy>>16, shape, 16);
4089 FlipPage();
4090 CalcTics();
4091 cx+=dx*tics;
4092 cy+=dy*tics;
4093 time-=tics;
4094 if (LastScan != 0)
4095 break;
4096 }
4097 }
4098
4099
4100 char *EndCinematicPicNames[5] =
4101 {
4102 "lwgshoo2",
4103 "hg2shoo2",
4104 "ankshoo1",
4105 "ligrise4",
4106 "tritoss5",
4107
4108 };
4109
4110 #define NUMENDMESSAGES 24
4111
4112
4113 char *EndCinematicText[NUMENDMESSAGES] =
4114 {
4115 "You've won the battle, Cassatt.\n"
4116 "But when the Oscuridos return,\n"
4117 "will you be ready as they wage\n"
4118 "their Dark War?",
4119
4120 "Armed with only a pistol and 30\n"
4121 "bucks, you must stop the minions of\n"
4122 "El Oscuro before they kill millions\n"
4123 "of innocent people.",
4124
4125 "But for now, hey, enjoy the medal\n"
4126 "you received and take a vacation.\n"
4127 "You've earned it. Maybe on \n"
4128 "San Nicolas Island . . ." ,
4129
4130 "Thanks for playing. If you liked\n"
4131 "\"The HUNT Begins\", check Ordering\n"
4132 "Info for information about \n"
4133 "continuing your adventure.",
4134
4135 "Okay, you can stop reading now.",
4136
4137 "Press a key. That's all there is.\n"
4138 "Thanks.",
4139
4140 "Are you lazy, or illiterate?\n"
4141 "PRESS A KEY.",
4142
4143 "Look, this is pointless. You\n"
4144 "are done. Push off.",
4145
4146 "Okay, show's over. Nothing\n"
4147 "more to see here.",
4148
4149 "Wow, you must like this fine\n"
4150 "background screen.",
4151
4152 "For waiting this long, you get . . .\n"
4153 "nothing! Go away!",
4154
4155 "I mean, I like you as a friend,\n"
4156 "but . . .",
4157
4158 "\"Bob\"",
4159
4160 "All right, um . . . you found the\n"
4161 "secret message! Congratulations!",
4162
4163 "Didn't work, huh? Okay, how about\n"
4164 "this . . .",
4165
4166 "THE END",
4167
4168 "Dang. Thought I had you there.",
4169
4170 "Stop watching.",
4171
4172 "You know that if you registered,\n"
4173 "there would be a lot more cool\n"
4174 "stuff happening right now.",
4175
4176 "Episode IV: A New Hope\n",
4177
4178 "Just think of all the new secret\n"
4179 "messages you could find hidden\n"
4180 "in the registered version!",
4181
4182 "Someone right now is probably\n"
4183 "enjoying the really exciting\n"
4184 "ending of the registered version.",
4185
4186 "ROTT was filmed before\n"
4187 "a live audience.",
4188
4189 "No animals were harmed during the\n"
4190 "creation of this video game, although\n"
4191 "one dog did get its butt spanked\n"
4192 "when it peed on the carpet.\n",
4193
4194
4195 };
4196 char NextGameString1[] = "The Developers of Incredible Power";
4197 char NextGameString2[] = "shall return";
4198
DoEndCinematic(void)4199 void DoEndCinematic ( void )
4200 {
4201 int trilogo;
4202 int group;
4203 int world;
4204 int width;
4205 int height;
4206 int x,y;
4207 int shape;
4208 int time1,time2;
4209 byte * tmp;
4210 byte * sky;
4211 byte * bkgnd;
4212 int i;
4213
4214 byte pal[768];
4215
4216
4217 viewwidth = MAXSCREENWIDTH;
4218 viewheight = MAXSCREENHEIGHT;
4219
4220 MU_StartSong(song_youwin);
4221
4222 bkgnd=SafeMalloc(800*linewidth);
4223
4224 trilogo=W_GetNumForName("trilogo");
4225 world=W_GetNumForName("ap_wrld");
4226 group=W_GetNumForName("mmbk");
4227 VL_DrawPostPic (trilogo);
4228 PrepareBackground ( bkgnd );
4229
4230 WarpSprite (160, -100, 160, 100, (VBLCOUNTER*3), bkgnd, W_GetNumForName("youwin"));
4231 if (LastScan !=0)
4232 goto fadelogo;
4233
4234 I_Delay(30);
4235 fadelogo:
4236 MenuFadeOut();
4237 ClearGraphicsScreen();
4238 memcpy(&pal[0],W_CacheLumpName("ap_pal",PU_CACHE,CvtNull,1),768);
4239 VL_NormalizePalette(&pal[0]);
4240 SwitchPalette(&pal[0],35);
4241
4242 VL_DrawPostPic (world);
4243 PrepareBackground ( bkgnd );
4244
4245 WarpSprite (160, 250, 160, 100, (VBLCOUNTER*3), bkgnd, W_GetNumForName("wrldsafe"));
4246 if (LastScan !=0)
4247 goto fadeworld;
4248
4249 I_Delay(10);
4250 if (LastScan !=0)
4251 goto fadeworld;
4252
4253 WarpSprite (160, 100, 160, -50, (VBLCOUNTER*3), bkgnd, W_GetNumForName("wrldsafe"));
4254 if (LastScan !=0)
4255 goto fadeworld;
4256
4257 I_Delay(20);
4258
4259 fadeworld:
4260 MenuFadeOut();
4261 ClearGraphicsScreen();
4262 MenuFadeIn();
4263
4264
4265 sky=W_CacheLumpNum(W_GetNumForName("SKYSTART")+2,PU_CACHE,CvtNull,1);
4266 tmp=sky;
4267 for (x=0;x<256;x++)
4268 {
4269 VGAWRITEMAP(x&3);
4270 for (y=0;y<200;y++)
4271 {
4272 #ifdef DOS
4273 *((byte *)bufferofs+ylookup[y]+(x>>2))=*tmp++;
4274 #else
4275 *((byte *)bufferofs+ylookup[y]+x)=*tmp++;
4276 #endif
4277 }
4278 }
4279 tmp=sky;
4280 for (x=256;x<320;x++)
4281 {
4282 VGAWRITEMAP(x&3);
4283 for (y=0;y<200;y++)
4284 {
4285 #ifdef DOS
4286 *((byte *)bufferofs+ylookup[y]+(x>>2))=*tmp++;
4287 #else
4288 *((byte *)bufferofs+ylookup[y]+x)=*tmp++;
4289 #endif
4290 }
4291 }
4292
4293 for(i=0;i<5;i++)
4294 {
4295 int tx,ty;
4296
4297 tx = 32 + (i << 6);
4298 ty = 100;
4299 shape = W_GetNumForName(EndCinematicPicNames[i]);
4300 DrawUnScaledSprite (tx, ty, shape,16);
4301 }
4302
4303 PrepareBackground ( bkgnd );
4304
4305 //CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_CACHE);
4306 CurrentFont = smallfont;
4307 LastScan = 0;
4308
4309 for(i=0;i<NUMENDMESSAGES;i++)
4310 {
4311 if (i>3)
4312 I_Delay(50);
4313
4314 US_MeasureStr (&width, &height, &(EndCinematicText[i][0]));
4315 if (LastScan !=0)
4316 break;
4317
4318 x=(320-width)>>1;
4319 y=(200-height)>>1;
4320 time1 = (300 - y)*(VBLCOUNTER*4)/300;
4321 time2 = VBLCOUNTER*4-time1;
4322
4323 WarpString (x, 250, x, y-50,time1, bkgnd, EndCinematicText[i]);
4324 if (LastScan !=0)
4325 break;
4326 I_Delay(40);
4327 if (LastScan !=0)
4328 break;
4329
4330 if (i<=3)
4331 I_Delay(40);
4332 if (LastScan !=0)
4333 break;
4334
4335 WarpString (x, y-50, x, -50, time2, bkgnd, EndCinematicText[i]);
4336 if (LastScan !=0)
4337 break;
4338
4339
4340 }
4341
4342 if (LastScan!=0)
4343 goto finalfade;
4344
4345 sky=W_CacheLumpNum(W_GetNumForName("SKYSTART")+2,PU_CACHE,CvtNull,1);
4346 tmp=sky;
4347 for (x=0;x<256;x++)
4348 {
4349 VGAWRITEMAP(x&3);
4350 for (y=0;y<200;y++)
4351 {
4352 #ifdef DOS
4353 *((byte *)bufferofs+ylookup[y]+(x>>2))=*tmp++;
4354 #else
4355 *((byte *)bufferofs+ylookup[y]+x)=*tmp++;
4356 #endif
4357 }
4358 }
4359 tmp=sky;
4360 for (x=256;x<320;x++)
4361 {
4362 VGAWRITEMAP(x&3);
4363 for (y=0;y<200;y++)
4364 {
4365 #ifdef DOS
4366 *((byte *)bufferofs+ylookup[y]+(x>>2))=*tmp++;
4367 #else
4368 *((byte *)bufferofs+ylookup[y]+x)=*tmp++;
4369 #endif
4370 }
4371 }
4372
4373 for(i=0;i<5;i++)
4374 {
4375 int tx,ty;
4376
4377 tx = 32 + (i << 6);
4378 ty = 100;
4379 shape = W_GetNumForName(EndCinematicPicNames[i]);
4380 DrawUnScaledSprite (tx, ty, shape,16);
4381 }
4382
4383
4384 shape = W_GetNumForName("robogrd3");
4385 PrepareBackground ( bkgnd );
4386 WarpSprite (420,100,300,100,VBLCOUNTER*3,bkgnd,shape);
4387 if (LastScan !=0)
4388 goto finalfade;
4389
4390 PrepareBackground ( bkgnd );
4391 WarpString (200,80,200,80,VBLCOUNTER*3,bkgnd, "Am I late?");
4392 if (LastScan !=0)
4393 goto finalfade;
4394
4395
4396 I_Delay(20);
4397 finalfade:
4398
4399 MenuFadeOut();
4400 VL_ClearVideo (0);
4401 I_Delay(10);
4402
4403 if (LastScan == 0)
4404 {
4405 US_MeasureStr (&width, &height, NextGameString1);
4406 x=(320-width)>>1;
4407 y=(200-height)>>1;
4408 US_ClippedPrint (x,y-6, NextGameString1);
4409 US_MeasureStr (&width, &height, NextGameString2);
4410 x=(320-width)>>1;
4411 y=(200-height)>>1;
4412 US_ClippedPrint (x,y+6, NextGameString2);
4413 FlipPage();
4414 VL_FadeIn(0,255,origpal,150);
4415 I_Delay(50);
4416 VL_FadeOut(0,255,0,0,0,150);
4417 VL_ClearVideo (0);
4418 I_Delay(10);
4419 }
4420
4421 SafeFree(bkgnd);
4422 }
4423 #else
4424
4425 // REGISTERED VERSION ======================================================
4426
4427 static char burnCastle1Msg []=
4428 "The monastery burns.\n"
4429 "\n"
4430 "El Oscuro is dead.\n"
4431 "\n"
4432 "The world is safe.\n";
4433
4434 // If all Snake Eggs not destroyed on final level:
4435
4436
4437 static char notDoneMsg[] =
4438 "Unfortunately not all\n"
4439 "of El Oscuro's larvae\n"
4440 "were destroyed.\n"
4441 "\n"
4442 "Thirty years later,\n"
4443 "a descendant of\n"
4444 "El Oscuro wiped out\n"
4445 "the entire world,\n"
4446 "but nice job anyway.\n";
4447
4448 static char tryAgainMsg[] =
4449 "Try Again.\n"
4450 "\n"
4451 "The world will not be\n"
4452 "safe until all of El\n"
4453 "Oscuro's larvae are\n"
4454 "destroyed. Find them.\n";
4455
4456 // If all snake eggs destroyed:
4457 static char doneMsg[] =
4458 "You have destroyed\n"
4459 "El Oscuro and all his\n"
4460 "descendants. Well done!\n";
4461
4462 // On Triad background, in bigger font.
4463 static char youWin1Msg[] =
4464 "So, HUNT Members, how\n"
4465 "do you think the\n"
4466 "mission went?\n";
4467
4468 // Place menu pix of characters here (maybe modem frame too?)
4469 static char youWin2Msg[] =
4470 "Barrett: Well, I think\n"
4471 "I got shin splints from\n"
4472 "all those jump pads.\n"
4473 "But hey, action-wise,\n"
4474 "I've been in tougher\n"
4475 "bar fights, for crying\n"
4476 "out loud.\n";
4477
4478 static char youWin3Msg[] =
4479 "Cassatt: Apart from\n"
4480 "the other HUNT members\n"
4481 "saying I look like\n"
4482 "Richard Mulligan, it\n"
4483 "was quite a success.\n"
4484 "And some of the\n"
4485 "monastery's ironwork\n"
4486 "was very nice.\n";
4487
4488 static char youWin4Msg[] =
4489 "Ni: it was quite easy,\n"
4490 "actually. I just\n"
4491 "pictured the enemy\n"
4492 "having the face of\n"
4493 "my ex-husband, and\n"
4494 "man, I was a force\n"
4495 "of Nature.\n";
4496
4497 static char youWin5Msg[] =
4498 "Wendt: I was kind of\n"
4499 "disappointed. I think\n"
4500 "I used the missile\n"
4501 "weapons way too much.\n"
4502 "Next time, bullets\n"
4503 "only. Nothing sweeter\n"
4504 "than a head shot from\n"
4505 "a hundred feet.\n";
4506
4507 static char youWin6Msg[] =
4508 "Freeley: I'm still\n"
4509 "trying to adjust in\n"
4510 "the aftermath. It's\n"
4511 "kinda tough. I mean,\n"
4512 "I save the damn world,\n"
4513 "and all people ask\n"
4514 "about is my name.\n"
4515 "Sheesh.\n";
4516
4517 // On caching screen
4518
4519 static char youWin7Msg[] =
4520 "The HUNT is victorious!\n"
4521 "\n"
4522 " THE END\n";
4523
4524
4525 static char youWin8Msg[] =
4526 "Now go and celebrate!\n"
4527 "\n"
4528 " THE REAL END";
4529
4530 #define NUMEXPLOSIONTYPES 4
4531
4532 typedef struct {
4533 char name[11];
4534 byte numframes;
4535 } ExplosionInfoType;
4536
4537 ExplosionInfoType ExplosionInfo[NUMEXPLOSIONTYPES]=
4538 {
4539 {"EXPLOS1\0",20},
4540 {"EXP1\0",20},
4541 {"GREXP1\0",25},
4542 {"PART1\0",12},
4543 #if 0
4544 {"GUTS1\0",12},
4545 {"ORGAN1\0",12},
4546 {"RIB1\0",12},
4547 {"GPINK1\0",12},
4548 {"GHEAD1\0",12},
4549 {"GARM1\0",12},
4550 {"GLEG1\0",12},
4551 {"GHUM1\0",12},
4552 {"GHIP1\0",12},
4553 {"GLIMB1\0",12},
4554 #endif
4555 };
4556
4557
4558 typedef struct {
4559 byte which;
4560 byte frame;
4561 byte x;
4562 byte y;
4563 } ExplosionType;
4564
4565 #define MAXTRANSMITTEREXPLOSIONS 30
4566
4567 static ExplosionType Explosions[MAXTRANSMITTEREXPLOSIONS];
4568
ResetTransmitterExplosion(ExplosionType * Explosion)4569 void ResetTransmitterExplosion ( ExplosionType * Explosion )
4570 {
4571 Explosion->which=RandomNumber("Explosion",0)%NUMEXPLOSIONTYPES;
4572 Explosion->frame=0;
4573 Explosion->x=(RandomNumber("Explosion",2)>>1)+(160-64);
4574 Explosion->y=(RandomNumber("Explosion",3)>>1);
4575 }
4576
CacheTransmitterExplosions(void)4577 void CacheTransmitterExplosions ( void )
4578 {
4579 int i,j,num;
4580
4581 for (i=0;i<NUMEXPLOSIONTYPES;i++)
4582 {
4583 num=W_GetNumForName(ExplosionInfo[i].name);
4584 for (j=0;j<ExplosionInfo[i].numframes;j++)
4585 {
4586 W_CacheLumpNum(num+j, PU_CACHE, Cvt_patch_t, 1);
4587 }
4588 }
4589 }
4590
SetupTransmitterExplosions(void)4591 void SetupTransmitterExplosions ( void )
4592 {
4593 int i;
4594
4595 for (i=0;i<MAXTRANSMITTEREXPLOSIONS;i++)
4596 {
4597 ResetTransmitterExplosion(&Explosions[i]);
4598 }
4599 }
UpdateTransmitterExplosions(void)4600 void UpdateTransmitterExplosions ( void )
4601 {
4602 int i;
4603 for (i=0;i<MAXTRANSMITTEREXPLOSIONS;i++)
4604 {
4605 Explosions[i].frame+=tics;
4606 if (Explosions[i].frame>=(ExplosionInfo[Explosions[i].which].numframes<<1))
4607 {
4608 ResetTransmitterExplosion(&Explosions[i]);
4609 SD_Play(SD_EXPLODEFLOORSND+(RandomNumber("Explosion",4)>>7));
4610 }
4611 }
4612 }
4613
DrawTransmitterExplosions(void)4614 void DrawTransmitterExplosions ( void )
4615 {
4616 int i;
4617 for (i=0;i<MAXTRANSMITTEREXPLOSIONS;i++)
4618 {
4619 DrawUnScaledSprite (
4620 Explosions[i].x,
4621 Explosions[i].y,
4622 (W_GetNumForName(ExplosionInfo[Explosions[i].which].name) +
4623 (Explosions[i].frame>>1)),
4624 16
4625 );
4626 }
4627 }
4628
DoTransmitterExplosion(void)4629 void DoTransmitterExplosion ( void )
4630 {
4631 byte * back;
4632 int i;
4633
4634 VL_ClearVideo(0);
4635 back=SafeMalloc(800*linewidth);
4636
4637 CalcTics();
4638 CalcTics();
4639 DrawNormalSprite(0,0,W_GetNumForName("transmit"));
4640 PrepareBackground ( back );
4641 SetupTransmitterExplosions ();
4642 CacheTransmitterExplosions ();
4643 DrawBackground ( back );
4644 FlipPage();
4645 VL_FadeIn (0, 255, origpal, 30);
4646 SHAKETICS=VBLCOUNTER*15;
4647 for (i=0;i<(VBLCOUNTER*15);i+=tics)
4648 {
4649 DrawBackground ( back );
4650 DrawTransmitterExplosions ();
4651 FlipPage();
4652 CalcTics();
4653 UpdateTransmitterExplosions ();
4654 }
4655 VL_FadeOut (0, 255, 63, 63, 63, 150);
4656 screenfaded=false;
4657 SD_Play(SD_PLAYERTCSND);
4658 SD_Play(SD_PLAYERTBSND);
4659 SD_Play(SD_PLAYERDWSND);
4660 SD_Play(SD_PLAYERLNSND);
4661 SD_Play(SD_PLAYERIPFSND);
4662 VL_FadeOut (0, 255, 0, 0, 0, 30);
4663 TurnShakeOff();
4664
4665 SafeFree(back);
4666 }
4667
ShowTransmitter(void)4668 void ShowTransmitter ( void )
4669 {
4670 MenuFadeOut();
4671 DrawNormalSprite(0,0,W_GetNumForName("transmit"));
4672 FlipPage();
4673 VL_FadeIn (0, 255, origpal, 30);
4674 I_Delay(30);
4675 VL_FadeOut (0, 255, 0, 0, 0, 30);
4676 }
4677
ShowFinalDoor(void)4678 void ShowFinalDoor ( void )
4679 {
4680 byte pal[768];
4681
4682 MenuFadeOut();
4683
4684 VL_ClearBuffer (bufferofs, 0);
4685 DrawNormalSprite (0, (200-120)>>1, W_GetNumForName("finldoor"));
4686 FlipPage();
4687 memcpy(&pal[0],W_CacheLumpName("findrpal",PU_CACHE,CvtNull, 1),768);
4688 VL_NormalizePalette(&pal[0]);
4689 SD_Play(SD_OPENDOORSND);
4690 VL_FadeIn (0, 255, pal, 30);
4691 I_Delay(30);
4692 VL_FadeOut (0, 255, 0, 0, 0, 30);
4693 }
4694
ShowFinalFire(void)4695 void ShowFinalFire ( void )
4696 {
4697 byte pal[768];
4698
4699 MenuFadeOut();
4700
4701 VL_ClearBuffer (bufferofs, 0);
4702 DrawNormalSprite (0, (200-120)>>1, W_GetNumForName("finlfire"));
4703 FlipPage();
4704 memcpy(&pal[0],W_CacheLumpName("finfrpal",PU_CACHE,CvtNull, 1),768);
4705 VL_NormalizePalette(&pal[0]);
4706 SD_Play(SD_BAZOOKAFIRESND);
4707 VL_FadeIn (0, 255, pal, 30);
4708 SD_Play(SD_FIREBOMBFIRESND);
4709 I_Delay(2);
4710 SD_Play(SD_HEATSEEKFIRESND);
4711 I_Delay(2);
4712 SD_Play(SD_DRUNKFIRESND);
4713 SD_Play(SD_HEATSEEKFIRESND);
4714 I_Delay(2);
4715 SD_Play(SD_ATKMP40SND);
4716 SD_Play(SD_ATKMP40SND);
4717 I_Delay(2);
4718 SD_Play(SD_HEATSEEKFIRESND);
4719 SD_Play(SD_FIREBOMBFIRESND);
4720 I_Delay(2);
4721 SD_Play(SD_ATKMP40SND);
4722 SD_Play(SD_HEATSEEKFIRESND);
4723 I_Delay(2);
4724 SD_Play(SD_DRUNKFIRESND);
4725 I_Delay(2);
4726 SD_Play(SD_FIREBOMBFIRESND);
4727 I_Delay(2);
4728 SD_Play(SD_HEATSEEKFIRESND);
4729 SD_Play(SD_ATKMP40SND);
4730 I_Delay(2);
4731 SD_Play(SD_DRUNKFIRESND);
4732 SD_Play(SD_HEATSEEKFIRESND);
4733 I_Delay(2);
4734 SD_Play(SD_FIREBOMBFIRESND);
4735 SD_Play(SD_ATKMP40SND);
4736 I_Delay(2);
4737 SD_Play(SD_DRUNKFIRESND);
4738 I_Delay(2);
4739 SD_Play(SD_HEATSEEKFIRESND);
4740 SD_Play(SD_FIREBOMBFIRESND);
4741 I_Delay(2);
4742 SD_Play(SD_ATKMP40SND);
4743 SD_Play(SD_HEATSEEKFIRESND);
4744 I_Delay(2);
4745 SD_Play(SD_DRUNKFIRESND);
4746 SD_Play(SD_FIREBOMBFIRESND);
4747 I_Delay(2);
4748 SD_Play(SD_HEATSEEKFIRESND);
4749 SD_Play(SD_DRUNKFIRESND);
4750 SD_Play(SD_BAZOOKAFIRESND);
4751 I_Delay(4);
4752 VL_FadeOut (0, 255, 0, 0, 0, 30);
4753 }
4754
ScrollString(int cy,char * string,byte * bkgnd,int scrolltime,int pausetime)4755 void ScrollString ( int cy, char * string, byte * bkgnd, int scrolltime, int pausetime )
4756 {
4757 int x,y;
4758 int width,height;
4759 int time1,time2;
4760
4761 LastScan=0;
4762 US_MeasureStr (&width, &height, string);
4763
4764 x=(320-width)>>1;
4765 y=cy-(height>>1);
4766 time1 = ((220 - y)*scrolltime)/(220+height);
4767 time2 = scrolltime-time1;
4768
4769 WarpString (x, 210, x, y, time1, bkgnd, string);
4770
4771 if (LastScan !=0)
4772 return;
4773
4774 I_Delay(pausetime);
4775
4776 if (LastScan !=0)
4777 return;
4778
4779 WarpString (x, y, x, -10-height, time2, bkgnd, string);
4780 }
4781
DoBurningCastle(void)4782 void DoBurningCastle ( void )
4783 {
4784 byte * back;
4785
4786 LastScan=0;
4787 VL_ClearVideo(0);
4788 back=SafeMalloc(800*linewidth);
4789
4790 DrawNormalSprite(0,0,W_GetNumForName("finale"));
4791 PrepareBackground ( back );
4792 CurrentFont = smallfont;
4793 FlipPage();
4794 VL_FadeIn (0, 255, origpal, 30);
4795 CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_STATIC, Cvt_font_t, 1 );
4796 ScrollString ( 150, &burnCastle1Msg[0], back, 4*VBLCOUNTER, 80);
4797 W_CacheLumpName ("newfnt1", PU_CACHE, Cvt_font_t, 1);
4798 VL_FadeOut (0, 255, 0, 0, 0, 80);
4799 SafeFree(back);
4800 }
4801
DoFailedScreen(void)4802 void DoFailedScreen ( void )
4803 {
4804 byte * back;
4805
4806 back=SafeMalloc(800*linewidth);
4807
4808 VL_DrawPostPic (W_GetNumForName("trilogo"));
4809 PrepareBackground ( back );
4810 CurrentFont = smallfont;
4811 FlipPage();
4812 VL_FadeIn (0, 255, origpal, 30);
4813 ScrollString ( 100, ¬DoneMsg[0], back, 4*VBLCOUNTER, 100);
4814 VL_FadeOut (0, 255, 0, 0, 0, 80);
4815 SafeFree(back);
4816 }
4817
DoTryAgainScreen(void)4818 void DoTryAgainScreen ( void )
4819 {
4820 byte * back;
4821
4822 back=SafeMalloc(800*linewidth);
4823
4824 VL_DrawPostPic (W_GetNumForName("trilogo"));
4825 PrepareBackground ( back );
4826 CurrentFont = smallfont;
4827 FlipPage();
4828 VL_FadeIn (0, 255, origpal, 30);
4829 ScrollString ( 100, tryAgainMsg, back, 4*VBLCOUNTER, 80);
4830 VL_FadeOut (0, 255, 0, 0, 0, 80);
4831 SafeFree(back);
4832 }
4833
ResetWorldExplosion(ExplosionType * Explosion)4834 void ResetWorldExplosion ( ExplosionType * Explosion )
4835 {
4836 Explosion->which=RandomNumber("Explosion",0)%NUMEXPLOSIONTYPES;
4837 Explosion->frame=0;
4838 // RandomNumber("Explosion",1)%ExplosionInfo[Explosions[i].which].numframes;
4839 Explosion->x=(RandomNumber("Explosion",2))+64;
4840 Explosion->y=(RandomNumber("Explosion",3)%180);
4841 }
4842
SetupWorldExplosions(void)4843 void SetupWorldExplosions ( void )
4844 {
4845 int i;
4846
4847 for (i=0;i<MAXTRANSMITTEREXPLOSIONS;i++)
4848 {
4849 ResetWorldExplosion(&Explosions[i]);
4850 }
4851 }
UpdateWorldExplosions(void)4852 void UpdateWorldExplosions ( void )
4853 {
4854 int i;
4855 for (i=0;i<MAXTRANSMITTEREXPLOSIONS;i++)
4856 {
4857 Explosions[i].frame+=tics;
4858 if (Explosions[i].frame>=(ExplosionInfo[Explosions[i].which].numframes<<1))
4859 {
4860 ResetWorldExplosion(&Explosions[i]);
4861 SD_Play(SD_EXPLODEFLOORSND+(RandomNumber("Explosion",4)>>7));
4862 }
4863 }
4864 }
4865
DestroyEarth(void)4866 void DestroyEarth ( void )
4867 {
4868 byte * back;
4869 int i;
4870
4871 VL_ClearVideo(0);
4872 back=SafeMalloc(800*linewidth);
4873
4874 CalcTics();
4875 CalcTics();
4876 DrawNormalSprite(0,0,W_GetNumForName("ourearth"));
4877 PrepareBackground ( back );
4878 SetupWorldExplosions ();
4879 CacheTransmitterExplosions ();
4880 DrawBackground ( back );
4881 FlipPage();
4882 VL_FadeIn (0, 255, origpal, 30);
4883 SHAKETICS=VBLCOUNTER*10;
4884 for (i=0;i<(VBLCOUNTER*10);i+=tics)
4885 {
4886 DrawBackground ( back );
4887 DrawTransmitterExplosions ();
4888 FlipPage();
4889 CalcTics();
4890 UpdateWorldExplosions ();
4891 }
4892 VL_FadeOut (0, 255, 63, 63, 63, 150);
4893 screenfaded=false;
4894 if (gamestate.violence==vl_excessive)
4895 SD_Play(SD_YOUSUCKSND);
4896 VL_FadeOut (0, 255, 0, 0, 0, 50);
4897 TurnShakeOff();
4898
4899 SafeFree(back);
4900 }
4901
DestroyedAllEggs(void)4902 boolean DestroyedAllEggs ( void )
4903 {
4904 statobj_t * temp;
4905
4906 for(temp=FIRSTSTAT;temp;temp=temp->statnext)
4907 {
4908 if (temp->itemnumber==stat_tomlarva)
4909 return false;
4910 }
4911 return true;
4912 }
4913
DoSanNicolas(void)4914 void DoSanNicolas ( void )
4915 {
4916 byte pal[768];
4917
4918 LastScan=0;
4919 VL_ClearVideo(0);
4920 DrawNormalSprite(0,16,W_GetNumForName("nicolas"));
4921 DrawNormalSprite(10,200-58,W_GetNumForName("budgcut"));
4922 FlipPage();
4923 memcpy(&pal[0],W_CacheLumpName("nicpal",PU_CACHE, CvtNull, 1),768);
4924 VL_NormalizePalette(&pal[0]);
4925 VL_FadeIn (0, 255, pal, 30);
4926 I_Delay(60);
4927 VL_FadeOut (0, 255, 0, 0, 0, 80);
4928 }
4929
PlayerQuestionScreen(void)4930 void PlayerQuestionScreen ( void )
4931 {
4932 byte * back;
4933
4934 back=SafeMalloc(800*linewidth);
4935
4936 VL_DrawPostPic (W_GetNumForName("trilogo"));
4937 PrepareBackground ( back );
4938 CurrentFont = smallfont;
4939 FlipPage();
4940 VL_FadeIn (0, 255, origpal, 30);
4941 CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_STATIC, Cvt_font_t, 1);
4942 ScrollString ( 100, &doneMsg[0], back, 4*VBLCOUNTER, 40);
4943 ScrollString ( 100, &youWin1Msg[0], back, 4*VBLCOUNTER, 50);
4944 VL_DrawPostPic (W_GetNumForName("trilogo"));
4945 DrawXYPic ( 8, 100-24, W_GetNumForName("player2"));
4946 PrepareBackground ( back );
4947 CurrentFont = smallfont;
4948 SD_Play(SD_PLAYERTBSND);
4949 ScrollString ( 100, &youWin2Msg[0], back, 4*VBLCOUNTER, 100);
4950 VL_DrawPostPic (W_GetNumForName("trilogo"));
4951 DrawXYPic ( 8, 100-24, W_GetNumForName("player1"));
4952 PrepareBackground ( back );
4953 SD_Play(SD_PLAYERTCSND);
4954 ScrollString ( 100, &youWin3Msg[0], back, 4*VBLCOUNTER, 100);
4955 VL_DrawPostPic (W_GetNumForName("trilogo"));
4956 DrawXYPic ( 8, 100-24, W_GetNumForName("player4"));
4957 PrepareBackground ( back );
4958 SD_Play(SD_PLAYERLNSND);
4959 ScrollString ( 100, &youWin4Msg[0], back, 4*VBLCOUNTER, 100);
4960 VL_DrawPostPic (W_GetNumForName("trilogo"));
4961 DrawXYPic ( 8, 100-24, W_GetNumForName("player3"));
4962 PrepareBackground ( back );
4963 SD_Play(SD_PLAYERDWSND);
4964 ScrollString ( 100, &youWin5Msg[0], back, 4*VBLCOUNTER, 100);
4965 VL_DrawPostPic (W_GetNumForName("trilogo"));
4966 DrawXYPic ( 8, 100-24, W_GetNumForName("player5"));
4967 PrepareBackground ( back );
4968 SD_Play(SD_PLAYERIPFSND);
4969 ScrollString ( 100, &youWin6Msg[0], back, 4*VBLCOUNTER, 100);
4970 W_CacheLumpName ("newfnt1", PU_CACHE, Cvt_font_t, 1);
4971 VL_FadeOut (0, 255, 0, 0, 0, 80);
4972 SafeFree(back);
4973 }
4974
DoYouWin(void)4975 void DoYouWin ( void )
4976 {
4977 pic_t * pic;
4978 byte * back;
4979
4980 back=SafeMalloc(800*linewidth);
4981 LastScan=0;
4982 VL_ClearVideo(0);
4983 pic = (pic_t *) W_CacheLumpNum (W_GetNumForName ("mmbk"), PU_CACHE, Cvt_pic_t, 1);
4984 VWB_DrawPic (0, 0, pic);
4985 PrepareBackground ( back );
4986 FlipPage();
4987 VL_FadeIn (0, 255, origpal, 30);
4988 CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_STATIC, Cvt_font_t, 1);
4989 ScrollString ( 100, &youWin7Msg[0], back, 4*VBLCOUNTER, 300);
4990 W_CacheLumpName ("newfnt1", PU_CACHE, Cvt_font_t, 1);
4991 VL_FadeOut (0, 255, 0, 0, 0, 80);
4992 SafeFree(back);
4993 }
4994
DoFinalEnd(void)4995 void DoFinalEnd ( void )
4996 {
4997 pic_t * pic;
4998 byte * back;
4999
5000 back=SafeMalloc(800*linewidth);
5001 LastScan=0;
5002 VL_ClearVideo(0);
5003 pic = (pic_t *) W_CacheLumpNum (W_GetNumForName ("mmbk"), PU_CACHE, Cvt_pic_t, 1);
5004 VWB_DrawPic (0, 0, pic);
5005 DrawNormalSprite(0,0,W_GetNumForName("sombrero"));
5006 DrawNormalSprite(0,0,W_GetNumForName("amflag"));
5007 DrawNormalSprite(0,0,W_GetNumForName("witchhat"));
5008 DrawNormalSprite(0,0,W_GetNumForName("esterhat"));
5009 DrawNormalSprite(0,0,W_GetNumForName("santahat"));
5010 PrepareBackground ( back );
5011 FlipPage();
5012 VL_FadeIn (0, 255, origpal, 30);
5013 CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_STATIC, Cvt_font_t, 1);
5014 ScrollString ( 100, &youWin8Msg[0], back, 4*VBLCOUNTER, 100);
5015 W_CacheLumpName ("newfnt1", PU_CACHE, Cvt_font_t, 1);
5016 VL_FadeOut (0, 255, 0, 0, 0, 80);
5017 SafeFree(back);
5018 VL_ClearVideo(0);
5019 }
5020
5021 static char dipMsg[] =
5022 "The Developers of Incredible Power!\n"
5023 "\n"
5024 "Susan Tom Jim Stephen\n"
5025 "Mark William Chuck\n";
5026
5027 static char creditsMsg[] =
5028 "Rise of the Triad Credits\n";
5029
5030 static char credits1Msg[] =
5031 "Programmers\n"
5032 "\n"
5033 "Mark Dochtermann\n"
5034 "William Scarboro\n"
5035 "Jim Dose'\n"
5036 "Nolan Martin\n";
5037
5038 static char credits2Msg[] =
5039 "Creative Director\n"
5040 "\n"
5041 "Tom Hall\n";
5042
5043 static char credits3Msg[] =
5044 "Artists\n"
5045 "\n"
5046 "Stephen Hornback\n"
5047 "Tim Neveu\n"
5048 "Chuck Jones\n"
5049 "Susan Singer\n"
5050 "James Storey\n"
5051 "Cygnus Multimedia\n";
5052
5053 static char credits4Msg[] =
5054 "Level Designers\n"
5055 "\n"
5056 "Tom Hall\n"
5057 "Joseph Selinske\n"
5058 "Marianna Vayntrub\n"
5059 "Joe Siegler\n";
5060 static char credits5Msg[] =
5061 "Music\n"
5062 "\n"
5063 "Lee Jackson\n"
5064 "Bobby Prince\n";
5065
5066 static char credits6Msg[] =
5067 "Robot Models\n"
5068 "\n"
5069 "Gregor Punchatz\n";
5070
5071 static char credits7Msg[] =
5072 "Special Thanks\n"
5073 "\n"
5074 "George Broussard\n"
5075 "Scott Miller\n"
5076 "Steven Blackburn\n"
5077 "Apogee Technical Support\n"
5078 "Apogee Support Staff\n"
5079 "John Carmack\n"
5080 "Ken Silverman\n";
5081
5082 static char credits8Msg[] =
5083 "The Hand of God\n"
5084 "\n"
5085 "Tim Neveu's Hand\n";
5086
5087 static char credits9Msg[] =
5088 "Dog Snout and Paw\n"
5089 "\n"
5090 "Loki\n"
5091 "The Carpet Wetting Maestro\n";
5092
5093 static char credits10Msg[] =
5094 "Krist's chair\n"
5095 "\n"
5096 "Stephen Blackburn's Comfy Chair\n"
5097 "Marianna's Paper and Glue\n";
5098
5099 static char credits11Msg[] =
5100 "Character Voices\n"
5101 "\n"
5102 "Darian - Mark Dochtermann\n"
5103 "Krist - Joe Siegler\n"
5104 "NME - Sound CD#4005\n"
5105 "Oscuro - Tom Hall\n"
5106 "Low Guard - Steve Quarrella\n"
5107 "High Guard - Steven Blackburn\n"
5108 "Over Patrol - Chuck Jones\n";
5109
5110 static char credits12Msg[] =
5111 "Character Voices Continued\n"
5112 "\n"
5113 "Strike Team - Scott Miller\n"
5114 "Lightning Guard - William Scarboro\n"
5115 "Triad Enforcer - George Broussard\n"
5116 "All Monks - Tom Hall\n"
5117 "Taradino - Joe Selinske\n"
5118 "Lorelei - Pau Suet Ying\n"
5119 "Ian Paul - Jim Dose'\n"
5120 "Doug - Lee Jackson\n"
5121 "Thi - Susan Singer\n";
5122
5123 static char actorsMsg[] =
5124 "The Actors\n";
5125
5126 static char actors1Msg[] =
5127 "Low Guard\n"
5128 "\n"
5129 "Steve Quarrella\n";
5130
5131 static char actors2Msg[] =
5132 "High Guard\n"
5133 "\n"
5134 "Steven Blackburn\n";
5135
5136 static char actors3Msg[] =
5137 "Over Patrol\n"
5138 "\n"
5139 "Nolan Martin\n";
5140
5141 static char actors4Msg[] =
5142 "Strike Team\n"
5143 "\n"
5144 "Scott Miller\n";
5145
5146 static char actors5Msg[] =
5147 "Lightning Guard\n"
5148 "\n"
5149 "Kevin Green\n";
5150
5151 static char actors6Msg[] =
5152 "Triad Enforcer\n"
5153 "\n"
5154 "George Broussard\n";
5155
5156 static char actors7Msg[] =
5157 "Death Monk\n"
5158 "\n"
5159 "Lee Jackson\n";
5160
5161 static char actors8Msg[] =
5162 "Deathfire Monk\n"
5163 "\n"
5164 "Allen Blum III\n";
5165
5166 static char actors9Msg[] =
5167 "Robot Guard\n"
5168 "\n"
5169 "Himself\n";
5170
5171 static char actors10Msg[] =
5172 "General Darian\n"
5173 "\n"
5174 "Steve Maines\n";
5175
5176 static char actors11Msg[] =
5177 "Sebastian Krist\n"
5178 "\n"
5179 "Joe Siegler\n";
5180
5181 static char actors12Msg[] =
5182 "The NME\n"
5183 "\n"
5184 "Himself\n";
5185
5186 static char actors13Msg[] =
5187 "El Oscuro\n"
5188 "\n"
5189 "Tom Hall\n";
5190
5191
5192 static char cut1Msg[] =
5193 "Deathfire Monk\n"
5194 "\n"
5195 "Mark Dochtermann\n";
5196
5197
5198 static char cut2Msg[] =
5199 "Over Patrol\n"
5200 "\n"
5201 "Pat Miller\n";
5202
5203
5204 static char cut3Msg[] =
5205 "Low Guard\n"
5206 "\n"
5207 "Marianna Vayntrub\n";
5208
5209
5210 static char cut4Msg[] =
5211 "Strike Team\n"
5212 "\n"
5213 "Ann Grauerholz\n";
5214
5215 static char cut5Msg[] =
5216 "Lightning Guard\n"
5217 "\n"
5218 "William Scarboro\n";
5219
5220
5221 static char cut6Msg[] =
5222 "High Guard\n"
5223 "\n"
5224 "Stephen Hornback\n";
5225
5226
5227
5228 static char playersCutMsg[] =
5229 "Actors who were\n"
5230 "cut from the game\n";
5231
DIPCredits(void)5232 void DIPCredits ( void )
5233 {
5234 byte * back;
5235
5236 back=SafeMalloc(800*linewidth);
5237
5238 VL_DrawPostPic (W_GetNumForName("trilogo"));
5239 PrepareBackground ( back );
5240 FlipPage();
5241 VL_FadeIn (0, 255, origpal, 30);
5242 CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_STATIC, Cvt_font_t, 1);
5243 ScrollString ( 100, &creditsMsg[0], back, 4*VBLCOUNTER, 30);
5244 CurrentFont = smallfont;
5245 ScrollString ( 100, &credits1Msg[0], back, 4*VBLCOUNTER, 50);
5246 ScrollString ( 100, &credits2Msg[0], back, 4*VBLCOUNTER, 50);
5247 ScrollString ( 100, &credits3Msg[0], back, 4*VBLCOUNTER, 50);
5248 ScrollString ( 100, &credits4Msg[0], back, 4*VBLCOUNTER, 50);
5249 ScrollString ( 100, &credits5Msg[0], back, 4*VBLCOUNTER, 50);
5250 ScrollString ( 100, &credits6Msg[0], back, 4*VBLCOUNTER, 50);
5251 ScrollString ( 100, &credits7Msg[0], back, 4*VBLCOUNTER, 50);
5252 ScrollString ( 100, &credits8Msg[0], back, 4*VBLCOUNTER, 50);
5253 ScrollString ( 100, &credits9Msg[0], back, 4*VBLCOUNTER, 50);
5254 ScrollString ( 100, &credits10Msg[0], back, 4*VBLCOUNTER, 50);
5255 ScrollString ( 100, &credits11Msg[0], back, 4*VBLCOUNTER, 80);
5256 ScrollString ( 100, &credits12Msg[0], back, 4*VBLCOUNTER, 80);
5257
5258 CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_STATIC, Cvt_font_t, 1);
5259 ScrollString ( 100, &actorsMsg[0], back, 4*VBLCOUNTER, 50);
5260
5261 CurrentFont = smallfont;
5262 VL_DrawPostPic (W_GetNumForName("trilogo"));
5263 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("lwgshoo2"));
5264 PrepareBackground ( back );
5265 ScrollString ( 100, &actors1Msg[0], back, 4*VBLCOUNTER, 50);
5266
5267 VL_DrawPostPic (W_GetNumForName("trilogo"));
5268 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("hg2shoo2"));
5269 PrepareBackground ( back );
5270 ScrollString ( 100, &actors2Msg[0], back, 4*VBLCOUNTER, 50);
5271
5272 VL_DrawPostPic (W_GetNumForName("trilogo"));
5273 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("obpshoo1"));
5274 PrepareBackground ( back );
5275 ScrollString ( 100, &actors3Msg[0], back, 4*VBLCOUNTER, 50);
5276
5277 VL_DrawPostPic (W_GetNumForName("trilogo"));
5278 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("ankshoo1"));
5279 PrepareBackground ( back );
5280 ScrollString ( 100, &actors4Msg[0], back, 4*VBLCOUNTER, 50);
5281
5282 VL_DrawPostPic (W_GetNumForName("trilogo"));
5283 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("ligrise4"));
5284 PrepareBackground ( back );
5285 ScrollString ( 100, &actors5Msg[0], back, 4*VBLCOUNTER, 50);
5286
5287 VL_DrawPostPic (W_GetNumForName("trilogo"));
5288 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("tritoss5"));
5289 PrepareBackground ( back );
5290 ScrollString ( 100, &actors6Msg[0], back, 4*VBLCOUNTER, 50);
5291
5292 VL_DrawPostPic (W_GetNumForName("trilogo"));
5293 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("monkdr4"));
5294 PrepareBackground ( back );
5295 ScrollString ( 100, &actors7Msg[0], back, 4*VBLCOUNTER, 50);
5296
5297 VL_DrawPostPic (W_GetNumForName("trilogo"));
5298 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("allksh4"));
5299 PrepareBackground ( back );
5300 ScrollString ( 100, &actors8Msg[0], back, 4*VBLCOUNTER, 50);
5301
5302 VL_DrawPostPic (W_GetNumForName("trilogo"));
5303 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("robogrd1"));
5304 PrepareBackground ( back );
5305 ScrollString ( 100, &actors9Msg[0], back, 4*VBLCOUNTER, 50);
5306
5307 VL_DrawPostPic (W_GetNumForName("trilogo"));
5308 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("darshoo1"));
5309 PrepareBackground ( back );
5310 ScrollString ( 100, &actors10Msg[0], back, 4*VBLCOUNTER, 50);
5311
5312 VL_DrawPostPic (W_GetNumForName("trilogo"));
5313 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("hdope8"));
5314 PrepareBackground ( back );
5315 ScrollString ( 100, &actors11Msg[0], back, 4*VBLCOUNTER, 50);
5316
5317 VL_DrawPostPic (W_GetNumForName("trilogo"));
5318 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("rbody101"));
5319 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("rhead101"));
5320 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("rsw01"));
5321 PrepareBackground ( back );
5322 ScrollString ( 100, &actors12Msg[0], back, 4*VBLCOUNTER, 50);
5323
5324 VL_DrawPostPic (W_GetNumForName("trilogo"));
5325 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("tomfly21"));
5326 PrepareBackground ( back );
5327 ScrollString ( 100, &actors13Msg[0], back, 4*VBLCOUNTER, 50);
5328
5329 VL_DrawPostPic (W_GetNumForName("trilogo"));
5330 PrepareBackground ( back );
5331 CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_STATIC, Cvt_font_t, 1);
5332 ScrollString ( 100, &playersCutMsg[0], back, 4*VBLCOUNTER, 40);
5333
5334 CurrentFont = smallfont;
5335 VL_DrawPostPic (W_GetNumForName("trilogo"));
5336 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("cutmark"));
5337 PrepareBackground ( back );
5338 ScrollString ( 100, &cut1Msg[0], back, 4*VBLCOUNTER, 50);
5339
5340 VL_DrawPostPic (W_GetNumForName("trilogo"));
5341 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("cutpat"));
5342 PrepareBackground ( back );
5343 ScrollString ( 100, &cut2Msg[0], back, 4*VBLCOUNTER, 50);
5344
5345 VL_DrawPostPic (W_GetNumForName("trilogo"));
5346 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("cutmari"));
5347 PrepareBackground ( back );
5348 ScrollString ( 100, &cut3Msg[0], back, 4*VBLCOUNTER, 50);
5349
5350 VL_DrawPostPic (W_GetNumForName("trilogo"));
5351 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("cutann"));
5352 PrepareBackground ( back );
5353 ScrollString ( 100, &cut4Msg[0], back, 4*VBLCOUNTER, 50);
5354
5355 VL_DrawPostPic (W_GetNumForName("trilogo"));
5356 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("cutwill"));
5357 PrepareBackground ( back );
5358 ScrollString ( 100, &cut5Msg[0], back, 4*VBLCOUNTER, 50);
5359
5360 VL_DrawPostPic (W_GetNumForName("trilogo"));
5361 DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("cutstev"));
5362 PrepareBackground ( back );
5363 ScrollString ( 100, &cut6Msg[0], back, 4*VBLCOUNTER, 50);
5364
5365 VL_FadeOut (0, 255, 0, 0, 0, 80);
5366
5367 DrawNormalSprite(0,0,W_GetNumForName("grouppic"));
5368 PrepareBackground ( back );
5369 FlipPage();
5370 VL_FadeIn (0, 255, origpal, 30);
5371 ScrollString ( 175, &dipMsg[0], back, 4*VBLCOUNTER, 140);
5372 VL_FadeOut (0, 255, 0, 0, 0, 80);
5373
5374 W_CacheLumpName ("newfnt1", PU_CACHE, Cvt_font_t, 1);
5375 SafeFree(back);
5376 }
5377
DoEndCinematic(void)5378 void DoEndCinematic ( void )
5379 {
5380 viewwidth = MAXSCREENWIDTH;
5381 viewheight = MAXSCREENHEIGHT;
5382 MU_FadeOut ( 1000 );
5383 MU_StopSong ();
5384
5385 ShowFinalDoor();
5386 ShowTransmitter ();
5387 ShowFinalFire();
5388 DoTransmitterExplosion();
5389 MU_StartSong(song_youwin);
5390 DoBurningCastle ();
5391 DoSanNicolas();
5392 if (DestroyedAllEggs () == true)
5393 {
5394 PlayerQuestionScreen();
5395 DIPCredits();
5396 DoYouWin();
5397 if (LastScan !=0)
5398 {
5399 IN_UpdateKeyboard();
5400 return;
5401 }
5402 DoFinalEnd();
5403 }
5404 else
5405 {
5406 MU_StartSong(song_gameover);
5407 DoFailedScreen();
5408 DestroyEarth();
5409 DoTryAgainScreen ();
5410 playstate=ex_warped;
5411 gamestate.mapon=33;
5412 }
5413 IN_UpdateKeyboard();
5414 }
5415
DoInBetweenCinematic(int yoffset,int lump,int delay,char * string)5416 void DoInBetweenCinematic (int yoffset, int lump, int delay, char * string )
5417 {
5418 int width,height;
5419 int x,y;
5420
5421 VL_FadeOut (0, 255, 0, 0, 0, 20);
5422 VL_ClearBuffer (bufferofs, 0);
5423 DrawNormalSprite(0,yoffset,lump);
5424
5425 CurrentFont=smallfont;
5426 US_MeasureStr (&width, &height, string);
5427 x=(320-width)>>1;
5428 y=190-height;
5429 US_ClippedPrint (x, y, string);
5430 FlipPage();
5431 VL_FadeIn(0,255,origpal,20);
5432 I_Delay (delay);
5433 VL_FadeOut (0, 255, 0, 0, 0, 20);
5434 }
5435 #endif
5436
5437
5438 //******************************************************************************
5439 //
5440 // DoCreditScreen
5441 //
5442 //******************************************************************************
5443
5444 #define NUMFIRSTCREDITMESSAGES 22
5445 #define NUMSECONDCREDITMESSAGES 28
5446
5447 typedef struct CreditType {
5448 char text[80];
5449 byte font;
5450 byte endy;
5451 } CreditType;
5452
5453 CreditType FirstCredits[NUMFIRSTCREDITMESSAGES] =
5454 {
5455 {"Rise of the Triad Credits",0,0},
5456 {"COPYRIGHT (c) 1995 Apogee Software Ltd.",1,10},
5457 {"Apogee's Developers of Incredible Power",1,20},
5458 {"Creative Director",0,30},
5459 {"Tom Hall",1,40},
5460 {"Programmers",0,50},
5461 {"Mark Dochtermann William Scarboro",1,60},
5462 {"Jim Dose' Nolan Martin",1,66},
5463 {"Artists",0,76},
5464 {"Stephen Hornback Chuck Jones",1,86},
5465 {"Susan Singer Tim Neveu",1,92},
5466 {"James Storey Cygnus Multimedia",1,98},
5467 {"Level Designers",0,108},
5468 {"Joseph Selinske Tom Hall",1,118},
5469 {"Marianna Vayntrub Joe Siegler",1,124},
5470 {"Musicians",0,134},
5471 {"Lee Jackson Robert Prince",1,144},
5472 {"Uniforms",0,154},
5473 {"D.J. Goodwin Matt McKinney",1,164},
5474 {"Special Thanks",0,174},
5475 {"John Carmack Ken Silverman Gregor Punchatz",1,184},
5476 };
5477
5478 CreditType SecondCredits[NUMSECONDCREDITMESSAGES] =
5479 {
5480 {"Rise of the Triad Credits",0,0},
5481 {"COPYRIGHT (c) 1995 Apogee Software Ltd.",1,10},
5482 {"Executive Producers",0,20},
5483 {"George Broussard Scott Miller",1,30},
5484 {"Manual Design",0,40},
5485 {"Robert Atkins",1,50},
5486 {"Beta Testers",0,60},
5487 {"Steven Blackburn",1,70},
5488 {"Todd Aubin Mike Bartelt",1,76},
5489 {"Wayne Benner Neil Bonner",1,82},
5490 {"Glenn Brensinger Douglas Brewer",1,88},
5491 {"David Butler Daniel Creeron",1,94},
5492 {"Scott Darling Jason Ewasiuk",1,100},
5493 {"Craig Hamilton Ken Heckbert",1,106},
5494 {"Terry Herrin Greg Hively",1,112},
5495 {"John Howard Douglas Howell",1,118},
5496 {"Dennis Kurek Hank Leukart",1,124},
5497 {"Jim Lietzan Ken Mayer",1,130},
5498 {"Wayne Millard Penny Plant",1,136},
5499 {"Brian Prinner Jeff Rausch",1,142},
5500 {"Kelly Rogers Neil Rubenking",1,148},
5501 {"Steven Salter Chris White",1,154},
5502 {"Special Thanks",0,162},
5503 {"Apogee Technical Support Pau Suet Ying",1,172},
5504 {"Anthony, Zach, Rajan, Miki, Loki",1,178},
5505 {"Nathan, Petro, Tim, Jake, MacKay",1,184},
5506 {"Loyal, Ric, Teller, Amano",1,190},
5507 };
5508
DrawPreviousCredits(int num,CreditType * Credits)5509 void DrawPreviousCredits ( int num, CreditType * Credits )
5510 {
5511 int width;
5512 int height;
5513 int x,y;
5514 int i;
5515
5516 for(i=0;i<num;i++)
5517 {
5518 if (Credits[i].font==0)
5519 CurrentFont=smallfont;
5520 else
5521 CurrentFont=tinyfont;
5522 US_MeasureStr (&width, &height, &(Credits[i].text[0]));
5523 x=(320-width)>>1;
5524 y=Credits[i].endy;
5525 US_ClippedPrint (x, y+4, &Credits[i].text[0]);
5526 }
5527 }
5528
5529 #define CREDITSTARTY 220
5530 //******************************************************************************
5531 //
5532 // WarpCreditString
5533 //
5534 //******************************************************************************
5535
5536 extern boolean dopefish;
WarpCreditString(int time,byte * back,int num,CreditType * Credits)5537 void WarpCreditString ( int time, byte * back, int num, CreditType * Credits)
5538 {
5539 int dy;
5540 int cy;
5541 int x;
5542 int y;
5543 int width;
5544 int height;
5545 boolean soundplayed;
5546
5547
5548 LastScan = 0;
5549
5550 if (Credits[num].font==0)
5551 CurrentFont=smallfont;
5552 else
5553 CurrentFont=tinyfont;
5554 US_MeasureStr (&width, &height, &(Credits[num].text[0]));
5555
5556 x=(320-width)>>1;
5557 y=Credits[num].endy;
5558 dy=((y-CREDITSTARTY)<<16)/time;
5559 cy=CREDITSTARTY<<16;
5560
5561 CalcTics();
5562
5563 soundplayed=false;
5564
5565 while (time>0)
5566 {
5567 DrawBackground ( back );
5568 DrawPreviousCredits ( num, Credits );
5569 if (Credits[num].font==0)
5570 CurrentFont=smallfont;
5571 else
5572 CurrentFont=tinyfont;
5573 US_ClippedPrint (x, (cy>>16)+4, &Credits[num].text[0]);
5574 if ( ((cy>>16)<196) && (soundplayed==false))
5575 {
5576 if ((dopefish==true) && (SD_Started==true))
5577 {
5578 int snd;
5579
5580 do
5581 {
5582 snd=(RandomNumber("DoCredits",0)+RandomNumber("DoCredits",0))%MAXSOUNDS;
5583 }
5584 while (SD_SoundOkay ( snd ) == false);
5585 SD_Play ( snd );
5586 }
5587 else
5588 {
5589 // SD_Play ( SD_BAZOOKAFIRESND );
5590 #if (SHAREWARE == 0)
5591 SD_Play ( SD_BAZOOKAFIRESND + (RandomNumber("DoCredits",1)%13) );
5592 #else
5593 SD_Play ( SD_BAZOOKAFIRESND + (RandomNumber("DoCredits",1)%6) );
5594 #endif
5595 soundplayed=true;
5596 }
5597 }
5598 FlipPage();
5599 CalcTics();
5600 cy+=dy*tics;
5601 time-=tics;
5602 if (LastScan != 0)
5603 break;
5604 }
5605 }
5606
DoCreditScreen(void)5607 void DoCreditScreen ( void )
5608 {
5609 int trilogo;
5610 int time;
5611 byte * bkgnd;
5612 font_t * oldfont;
5613 int i;
5614
5615 viewwidth = MAXSCREENWIDTH;
5616 viewheight = MAXSCREENHEIGHT;
5617
5618 bkgnd=SafeMalloc(800*linewidth);
5619 trilogo=W_GetNumForName("trilogo");
5620 VL_DrawPostPic (trilogo);
5621 PrepareBackground ( bkgnd );
5622
5623 oldfont=CurrentFont;
5624
5625 for(i=0;i<NUMFIRSTCREDITMESSAGES;i++)
5626 {
5627 time = (CREDITSTARTY - FirstCredits[i].endy)*(VBLCOUNTER*1)/CREDITSTARTY;
5628 // time = VBLCOUNTER;
5629 WarpCreditString ( time, bkgnd, i, FirstCredits );
5630 IN_PumpEvents();
5631 // SD_Play ( SD_EXPLODESND );
5632 if (LastScan !=0)
5633 break;
5634 }
5635 i=NUMFIRSTCREDITMESSAGES;
5636 DrawBackground ( bkgnd );
5637 DrawPreviousCredits ( i, FirstCredits );
5638 FlipPage();
5639 IN_PumpEvents();
5640
5641 I_Delay(40);
5642
5643 for(i=0;i<NUMSECONDCREDITMESSAGES;i++)
5644 {
5645 time = (CREDITSTARTY - SecondCredits[i].endy)*(VBLCOUNTER/2)/CREDITSTARTY;
5646 // time = VBLCOUNTER;
5647 WarpCreditString ( time, bkgnd, i, SecondCredits );
5648 IN_PumpEvents();
5649 // SD_Play ( SD_EXPLODESND );
5650 if (LastScan !=0)
5651 break;
5652 }
5653 i=NUMSECONDCREDITMESSAGES;
5654 DrawBackground ( bkgnd );
5655 DrawPreviousCredits ( i, SecondCredits );
5656 FlipPage();
5657 IN_PumpEvents();
5658
5659 I_Delay(40);
5660 MenuFadeOut();
5661 VL_ClearVideo (0);
5662
5663 SafeFree(bkgnd);
5664 CurrentFont=oldfont;
5665 }
5666
5667
5668 #define NUMSTORYLINES 16
5669
5670 char * MicroStory[NUMSTORYLINES] =
5671 {
5672 "You are a member of HUNT, the",
5673 "High-Risk United Nations Taskforce.",
5674 "Stranded on an island in the",
5675 "Pacific, you must battle a master",
5676 "of pyrotechnics, hundreds of",
5677 "members of a death cult, and their",
5678 "leader, El Oscuro.",
5679 "\0",
5680 "You must reach the transmitter",
5681 "that is signalling the systematic",
5682 "destruction of Los Angeles.",
5683 "\0",
5684 "If you fail, millions will die",
5685 "and you will be tortured.",
5686 "\0",
5687 "So, you know, don't fail."
5688 };
5689
DoMicroStoryScreen(void)5690 void DoMicroStoryScreen ( void )
5691 {
5692 pic_t * pic;
5693 int x,y;
5694 int i;
5695
5696 VL_FadeOut (0, 255, 0, 0, 0, 20);
5697
5698 pic=(pic_t *)W_CacheLumpName("mmbk",PU_CACHE,Cvt_pic_t,1);
5699 VWB_DrawPic (0, 0, pic);
5700 CheckHolidays();
5701
5702 x=15;
5703 y=30;
5704
5705 IFont = ( cfont_t * )W_CacheLumpName( "sifont", PU_CACHE, Cvt_cfont_t, 1);
5706 for(i=0;i<NUMSTORYLINES;i++)
5707 {
5708 DrawIntensityString (x, y, MicroStory[i], 241);
5709 y += 9;
5710 }
5711
5712 FlipPage();
5713 MenuFadeIn();
5714 I_Delay (280);
5715
5716 VL_FadeOut (0, 255, 0, 0, 0, 20);
5717 }
5718
5719 #ifndef DOS
5720
DrawMenuPost(int height,byte * src,byte * buf)5721 void DrawMenuPost (int height, byte * src, byte * buf)
5722 {
5723 int frac = hp_startfrac;
5724 while (height--) {
5725 *buf = src[frac >> 16];
5726
5727 buf += linewidth;
5728 frac += hp_srcstep;
5729 }
5730 }
5731
DrawMapPost(int height,byte * src,byte * buf)5732 void DrawMapPost (int height, byte * src, byte * buf)
5733 {
5734 int frac = 0;
5735 while (height--) {
5736 *buf = src[frac >> 16];
5737
5738 buf += linewidth;
5739 frac += hp_srcstep;
5740 }
5741 }
5742
DrawRotRow(int count,byte * dest,byte * src)5743 void DrawRotRow(int count, byte * dest, byte * src)
5744 {
5745 unsigned eax, ecx, edx;
5746
5747 ecx = mr_yfrac;
5748 edx = mr_xfrac;
5749
5750 while (count--) {
5751 eax = edx >> 16;
5752 if (eax < 256 && (ecx >> 16) < 512) {
5753 eax = (eax << 9) | ((ecx << 7) >> (32-9));
5754 } else {
5755 eax = 0;
5756 }
5757
5758 *dest++ = src[eax];
5759
5760 edx += mr_xstep;
5761 ecx += mr_ystep;
5762 }
5763 }
5764
DrawMaskedRotRow(int count,byte * dest,byte * src)5765 void DrawMaskedRotRow(int count, byte * dest, byte * src)
5766 {
5767 unsigned eax;
5768 unsigned xfrac, yfrac;
5769
5770 xfrac = mr_xfrac;
5771 yfrac = mr_yfrac;
5772
5773 while (count--) {
5774 eax = xfrac >> 16;
5775 if (eax < 256 && (yfrac >> 16) < 512) {
5776 eax = (eax << 9) | ((yfrac << 7) >> (32-9));
5777 } else {
5778 eax = 0;
5779 }
5780
5781 if (src[eax] != 0xff) *dest = src[eax];
5782 dest++;
5783
5784 xfrac += mr_xstep;
5785 yfrac += mr_ystep;
5786 }
5787 }
5788
DrawSkyPost(byte * buf,byte * src,int height)5789 void DrawSkyPost (byte * buf, byte * src, int height)
5790 {
5791 while (height--) {
5792 *buf = shadingtable[*src];
5793
5794 buf += linewidth;
5795 src++;
5796 }
5797 }
5798
5799 #define CEILINGCOLOR 24
5800 #define FLOORCOLOR 32
5801
RefreshClear(void)5802 void RefreshClear (void)
5803 {
5804 int start, base;
5805
5806 memset(spotvis, 0, sizeof(spotvis));
5807
5808 if (fandc) {
5809 return;
5810 }
5811
5812 start = min(centery, viewheight);
5813
5814 if (start > 0) {
5815 VL_Bar(0, 0, MAXSCREENWIDTH, start, CEILINGCOLOR);
5816 } else {
5817 start = 0;
5818 }
5819
5820 base = start;
5821
5822 start = min(viewheight-start, viewheight);
5823 if (start > 0) {
5824 VL_Bar(0, base, MAXSCREENWIDTH, start, FLOORCOLOR);
5825 }
5826 }
5827
5828 #endif
5829
5830 #if 0
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878 typedef struct {
5879 int x;
5880 int y;
5881 int angle;
5882 int speed;
5883 int color;
5884 int endx;
5885 int endy;
5886 int plane;
5887 int time;
5888 } ParticleType;
5889
5890 #define NUMPARTICLES 300
5891 #define PARTICLETHINKTIME 5
5892 #define Fix(a) (a &= (FINEANGLES-1))
5893 ParticleType * Particle;
5894 int numparticles;
5895
5896 //******************************************************************************
5897 //
5898 // InitializeParticles
5899 //
5900 //******************************************************************************
5901
5902 void InitializeParticles (void)
5903 {
5904 int i;
5905 ParticleType * part;
5906
5907 Particle=(ParticleType *)SafeMalloc ( sizeof(ParticleType) * numparticles );
5908 memset ( Particle, 0, sizeof(ParticleType) * numparticles );
5909
5910 for (i=0;i<numparticles;i++)
5911 {
5912 part=&Particle[i];
5913 part->x=((RandomNumber("hello",0)*RandomNumber("hello",0))%viewwidth)<<16;
5914 part->y=((RandomNumber("hello",0)*RandomNumber("hello",0))%viewheight)<<16;
5915 // part->x=(((RandomNumber("hello",0)*RandomNumber("hello",0))%(viewwidth-40)+20)<<16);
5916 // part->y=(((RandomNumber("hello",0)*RandomNumber("hello",0))%(viewheight-40)+20)<<16);
5917 part->angle=(RandomNumber("hello",0)*RandomNumber("hello",0))%FINEANGLES;
5918 // part->speed=(RandomNumber("hello",0)%2)<<16;
5919 part->speed=(1<<16)-1;
5920 part->color=RandomNumber("hello",0);
5921 part->endx=-1;
5922 part->endy=-1;
5923 part->plane=(part->x>>16)&3;
5924 part->time=(RandomNumber("",0)%PARTICLETHINKTIME)+1;
5925 // part->color=255;
5926 }
5927 }
5928
5929 //******************************************************************************
5930 //
5931 // ShutdownParticles
5932 //
5933 //******************************************************************************
5934
5935 void ShutdownParticles (void)
5936 {
5937 SafeFree(Particle);
5938 }
5939
5940
5941 void AdjustParticleAngle(int maxadjust, int *currangle,int targetangle)
5942 {
5943 int dangle,i,magangle;
5944
5945 for(i=0;i<maxadjust;i++)
5946 {
5947 dangle = *currangle - targetangle;
5948
5949 if (dangle)
5950 {
5951 magangle = abs(dangle);
5952 if (magangle > (ANGLES/2))
5953 {
5954 if (dangle > 0)
5955 (*currangle) ++;
5956 else
5957 (*currangle) --;
5958 }
5959 else
5960 {
5961 if (dangle > 0)
5962 (*currangle) --;
5963 else
5964 (*currangle) ++;
5965 }
5966 Fix(*currangle);
5967 }
5968 }
5969 }
5970
5971 //******************************************************************************
5972 //
5973 // UpdateParticles
5974 //
5975 //******************************************************************************
5976
5977 //#define MAXADJUST (FINEANGLES/40)
5978 #define MAXADJUST (FINEANGLES/20)
5979 void UpdateParticles (int type)
5980 {
5981 int i;
5982 int dx,dy;
5983 ParticleType * target;
5984 ParticleType * part;
5985
5986 if (type==0)
5987 {
5988 for (i=0;i<numparticles-1;i++)
5989 {
5990 int angle;
5991
5992 part=&Particle[i];
5993 // target=&Particle[numparticles-1];
5994 // target=&Particle[i+1];
5995 target=&Particle[(RandomNumber("",0)*RandomNumber("",0))%numparticles];
5996 part->x+=-FixedMul (part->speed, costable[part->angle]);
5997 part->y+= FixedMul (part->speed, sintable[part->angle]);
5998 part->plane=(part->x>>16)&3;
5999
6000 dx = part->x - target->x;
6001 dy = target->y - part->y;
6002 if (dx && dy)
6003 {
6004 angle = atan2_appx(dx,dy);
6005 AdjustParticleAngle(MAXADJUST,&(part->angle),angle);
6006 }
6007 }
6008 part=&Particle[numparticles-1];
6009 part->x+=-FixedMul (part->speed, costable[part->angle]);
6010 part->y+= FixedMul (part->speed, sintable[part->angle]);
6011 part->plane=(part->x>>16)&3;
6012
6013 dx=part->x>>16;
6014 dy=part->y>>16;
6015
6016 if ( (dx<20) || (dx>(viewwidth-20)) )
6017 {
6018 if ( part->angle < (FINEANGLES/2) )
6019 {
6020 part->angle=FINEANGLES/2-part->angle;
6021 Fix(part->angle);
6022 }
6023 else
6024 {
6025 part->angle=FINEANGLES-part->angle;
6026 Fix(part->angle);
6027 }
6028 }
6029 if ( (dy<20) || (dy>(viewheight-20)) )
6030 {
6031 part->angle=FINEANGLES-part->angle;
6032 Fix(part->angle);
6033 }
6034 }
6035 else
6036 {
6037 for (i=0;i<numparticles;i++)
6038 {
6039 int angle;
6040
6041 part=&Particle[i];
6042 if ((part->x>>16)!=part->endx)
6043 part->x+=-FixedMul (part->speed, costable[part->angle]);
6044 else
6045 part->x=part->endx<<16;
6046 if ((part->y>>16)!=part->endy)
6047 part->y+= FixedMul (part->speed, sintable[part->angle]);
6048 else
6049 part->y=part->endy<<16;
6050 part->plane=(part->x>>16)&3;
6051
6052 part->time--;
6053 if (part->time==0)
6054 {
6055 part->time=PARTICLETHINKTIME;
6056 dx = part->x - (part->endx<<16);
6057 dy = (part->endy<<16) - part->y;
6058 if (dx && dy)
6059 {
6060 angle = atan2_appx(dx,dy);
6061 AdjustParticleAngle(MAXADJUST,&(part->angle),angle);
6062 }
6063 }
6064 }
6065 }
6066 }
6067
6068 //******************************************************************************
6069 //
6070 // DrawParticles
6071 //
6072 //******************************************************************************
6073
6074 void DrawParticles (void)
6075 {
6076 int i;
6077 int dx,dy;
6078 int plane;
6079 ParticleType * part;
6080
6081 VL_ClearBuffer (bufferofs, 0);
6082 #ifdef DOS
6083 for (plane=0;plane<4;plane++)
6084 #endif
6085 {
6086 VGAWRITEMAP(plane);
6087 for (i=0;i<numparticles;i++)
6088 {
6089 part=&Particle[i];
6090 if (part->plane!=plane)
6091 continue;
6092 dx=part->x>>16;
6093 dy=part->y>>16;
6094 if (dx<0) dx=0;
6095 if (dx>=viewwidth) dx=viewwidth-1;
6096 if (dy<0) dy=0;
6097 if (dy>=viewheight) dy=viewheight-1;
6098 #ifdef DOS
6099 *( (byte *) bufferofs + (dx>>2) + ylookup[dy] ) = part->color;
6100 #else
6101 *( (byte *) bufferofs + dx + ylookup[dy] ) = part->color;
6102 #endif
6103 }
6104 }
6105 }
6106
6107 void DrawParticleTemplate (void)
6108 {
6109 byte pal[768];
6110
6111 viewwidth=320;
6112 viewheight=200;
6113 memcpy(&pal[0],W_CacheLumpName("ap_pal",PU_CACHE),768);
6114 VL_NormalizePalette(&pal[0]);
6115 SwitchPalette(&pal[0],35);
6116 VL_ClearBuffer (bufferofs, 255);
6117 DrawNormalSprite (0, 0, W_GetNumForName("ap_titl"));
6118 }
6119
6120 void DrawAlternateParticleTemplate (void)
6121 {
6122 viewwidth=320;
6123 viewheight=200;
6124 VL_ClearBuffer (bufferofs, 255);
6125 DrawNormalSprite (0, 0, W_GetNumForName("LIFE_C1"));
6126 }
6127
6128 int CountParticles (void)
6129 {
6130 int plane,a,b;
6131 int count;
6132
6133 count=0;
6134 #ifdef DOS
6135 for (plane=0;plane<4;plane++)
6136 #endif
6137 {
6138 VGAREADMAP(plane);
6139 for (a=0;a<200;a++)
6140 {
6141 #ifdef DOS
6142 for (b=0;b<80;b++)
6143 #else
6144 for (b=0;b<320;b++)
6145 #endif
6146 {
6147 if (*((byte *)bufferofs+(a*linewidth)+b)!=255)
6148 count++;
6149 }
6150 }
6151 }
6152 return count;
6153 }
6154
6155 void AssignParticles (void)
6156 {
6157 int plane,a,b;
6158 byte pixel;
6159 ParticleType * part;
6160
6161 part=&Particle[0];
6162
6163 #ifdef DOS
6164 for (plane=0;plane<4;plane++)
6165 #endif
6166 {
6167 VGAREADMAP(plane);
6168 for (a=0;a<200;a++)
6169 {
6170 #ifdef DOS
6171 for (b=0;b<80;b++)
6172 #else
6173 for (b=0;b<320;b++)
6174 #endif
6175 {
6176 pixel = *((byte *)bufferofs+(a*linewidth)+b);
6177 if (pixel!=255)
6178 {
6179 #ifdef DOS
6180 part->endx=plane+(b<<2);
6181 #else
6182 part->endx=b;
6183 #endif
6184 part->endy=a;
6185 part->color=pixel;
6186 part++;
6187 }
6188 }
6189 }
6190 }
6191 }
6192
6193 //******************************************************************************
6194 //
6195 // ParticleIntro
6196 //
6197 //******************************************************************************
6198
6199 void ParticleIntro (void)
6200 {
6201 int i,j;
6202
6203
6204 SetViewSize (MAXVIEWSIZES-1);
6205 numparticles=NUMPARTICLES;
6206 DrawAlternateParticleTemplate ();
6207 // DrawParticleTemplate ();
6208 numparticles=CountParticles ();
6209 InitializeParticles ();
6210 AssignParticles();
6211 // numparticles>>=1;
6212
6213 CalcTics();
6214 CalcTics();
6215 LastScan=0;
6216 for (i=0;i<VBLCOUNTER*15;i+=tics)
6217 {
6218 DrawParticles();
6219 FlipPage();
6220 for (j=0;j<tics;j++)
6221 {
6222 UpdateParticles(0);
6223 }
6224 CalcTics();
6225 if ((LastScan) || IN_GetMouseButtons())
6226 break;;
6227 }
6228 LastScan=0;
6229 for (i=0;i<VBLCOUNTER*15;i+=tics)
6230 {
6231 DrawParticles();
6232 FlipPage();
6233 for (j=0;j<tics;j++)
6234 {
6235 UpdateParticles(1);
6236 }
6237 CalcTics();
6238 if ((LastScan) || IN_GetMouseButtons())
6239 break;;
6240 }
6241 ShutdownParticles ();
6242 }
6243
6244 #endif
6245
6246