1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 1996, 2003 - 3D Realms Entertainment
4 Copyright (C) 2017-2019 Nuke.YKT
5
6 This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
7
8 Duke Nukem 3D is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
17 See the GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23 Original Source: 1996 - Todd Replogle
24 Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
25 */
26 //-------------------------------------------------------------------------
27
28 #include "types.h"
29 #include "develop.h"
30 #include "scriplib.h"
31 #include "file_lib.h"
32 #include "gamedefs.h"
33 #include "keyboard.h"
34 #include "util_lib.h"
35 #include "function.h"
36 #include "control.h"
37 #include "fx_man.h"
38 #include "sounds.h"
39 #include "config.h"
40 #include "sndcards.h"
41
42 #include "duke3d.h"
43
44 #include "warpfx.h"
45
46 extern int sendmessagecommand;
47 extern char recbuf[];
48 extern long lastvisinc;
49
50 int crashcnt;
51
typemode(void)52 void typemode(void)
53 {
54 short ch, hitstate, i, j;
55
56 if( ps[myconnectindex].gm&MODE_SENDTOWHOM )
57 {
58 if(sendmessagecommand != -1 || ud.multimode < 3)
59 {
60 tempbuf[0] = 4;
61 tempbuf[1] = 0;
62 recbuf[0] = 0;
63
64 if(ud.multimode < 3)
65 sendmessagecommand = 2;
66
67 strcat(recbuf,ud.user_name[myconnectindex]);
68 strcat(recbuf,": ");
69 strcat(recbuf,typebuf);
70 j = strlen(recbuf);
71 recbuf[j] = 0;
72 strcat(tempbuf+1,recbuf);
73
74 if(sendmessagecommand >= ud.multimode)
75 {
76 for(ch=connecthead;ch >= 0;ch=connectpoint2[ch])
77 if (ch != myconnectindex)
78 sendpacket(ch,tempbuf,j+1);
79 user_quote = recbuf;
80 user_quote_time = 160;
81 }
82 else if(sendmessagecommand >= 0)
83 sendpacket(sendmessagecommand,tempbuf,j+1);
84
85 sendmessagecommand = -1;
86 ps[myconnectindex].gm &= ~(MODE_TYPE|MODE_SENDTOWHOM);
87 }
88 else if(sendmessagecommand == -1)
89 {
90 sprintf(buf,"\"%s\"",typebuf);
91 gametext(320>>1,36,buf,0);
92 gametext(320>>1,50,"SEND MESSAGE TO...",0);
93 for(i=0;i<ud.multimode;i++)
94 {
95 if (i == myconnectindex)
96 {
97 sprintf(buf,"A. ALL");
98 }
99 else
100 {
101 sprintf(buf,"%ld. %s",i+1,ud.user_name[i]);
102 }
103 gametext((320>>1)-40,60+i*8,buf,0);
104 }
105
106 sprintf(buf,"PRESS 1-%ld FOR INDIVIDUAL PLAYER.",ud.multimode);
107 gametext(320>>1,60+ud.multimode*8,buf,0);
108 gametext(320>>1,68+ud.multimode*8,"'A' OR 'ENTER' FOR ALL PLAYERS",0);
109 gametext(320>>1,76+ud.multimode*8,"ESC ABORTS",0);
110
111 if( KB_KeyWaiting() )
112 {
113 i = KB_GetCh();
114
115 if(i == 'A' || i == 'a' || i == 13)
116 sendmessagecommand = ud.multimode;
117 else if(i >= '1' || i <= (ud.multimode + '1') )
118 sendmessagecommand = i - '1';
119 else
120 {
121 ps[myconnectindex].gm &= ~(MODE_TYPE|MODE_SENDTOWHOM);
122 sendmessagecommand = -1;
123 typebuf[0] = 0;
124 }
125
126 KB_ClearKeyDown(sc_1);
127 KB_ClearKeyDown(sc_2);
128 KB_ClearKeyDown(sc_3);
129 KB_ClearKeyDown(sc_4);
130 KB_ClearKeyDown(sc_5);
131 KB_ClearKeyDown(sc_6);
132 KB_ClearKeyDown(sc_7);
133 KB_ClearKeyDown(sc_8);
134 KB_ClearKeyDown(sc_A);
135 KB_ClearKeyDown(sc_Escape);
136 KB_ClearKeyDown(sc_Enter);
137 }
138 }
139 }
140 else
141 {
142 if(ud.screen_size > 0)
143 hitstate = strget(320>>1,200-59,typebuf,30,1);
144 else
145 hitstate = strget(320>>1,200-29,typebuf,30,1);
146
147 if(hitstate == 1)
148 {
149 KB_ClearKeyDown(sc_Enter);
150 ps[myconnectindex].gm |= MODE_SENDTOWHOM;
151 }
152 else if(hitstate == -1)
153 ps[myconnectindex].gm &= ~(MODE_TYPE|MODE_SENDTOWHOM);
154 else pub = NUMPAGES;
155 }
156 }
157
158
displayrest(long smoothratio)159 void displayrest(long smoothratio)
160 {
161 long a, i, j;
162
163 struct player_struct *pp;
164 walltype *wal;
165 long cposx,cposy,cang;
166
167 pp = &ps[screenpeek];
168
169 if( pp->pals_time > 0 && pp->loogcnt == 0)
170 {
171 palto( pp->pals[0],
172 pp->pals[1],
173 pp->pals[2],
174 pp->pals_time|128);
175
176 restorepalette = 1;
177 }
178 else if( restorepalette )
179 {
180 setbrightness(ud.brightness>>2,&pp->palette[0]);
181 restorepalette = 0;
182 }
183 else if (pp->loogcnt)
184 {
185 }
186
187 if(ud.show_help)
188 {
189 switch(ud.show_help)
190 {
191 case 1:
192 rotatesprite(0,0,65536L,0,TEXTSTORY,0,0,10+16+64, 0,0,xdim-1,ydim-1);
193 break;
194 case 2:
195 rotatesprite(0,0,65536L,0,F1HELP,0,0,10+16+64, 0,0,xdim-1,ydim-1);
196 break;
197 #ifdef RRRA
198 case 3:
199 rotatesprite(0,0,65536L,0,RRTILE1636,0,0,10+16+64, 0,0,xdim-1,ydim-1);
200 break;
201 #endif
202 }
203
204 if ( KB_KeyPressed(sc_Escape ) )
205 {
206 KB_ClearKeyDown(sc_Escape);
207 ud.show_help = 0;
208 if(ud.multimode < 2 && ud.recstat != 2)
209 {
210 ready2send = 1;
211 totalclock = ototalclock;
212 }
213 vscrn();
214 }
215 return;
216 }
217
218 i = pp->cursectnum;
219
220 show2dsector[i>>3] |= (1<<(i&7));
221 wal = &wall[sector[i].wallptr];
222 for(j=sector[i].wallnum;j>0;j--,wal++)
223 {
224 i = wal->nextsector;
225 if (i < 0) continue;
226 if (wal->cstat&0x0071) continue;
227 if (wall[wal->nextwall].cstat&0x0071) continue;
228 if (sector[i].lotag == 32767) continue;
229 if (sector[i].ceilingz >= sector[i].floorz) continue;
230 show2dsector[i>>3] |= (1<<(i&7));
231 }
232
233 if(ud.camerasprite == -1)
234 {
235 if( ud.overhead_on != 2 )
236 {
237 if(pp->newowner < 0)
238 {
239 displayweapon(screenpeek);
240 if(pp->over_shoulder_on == 0 )
241 displaymasks(screenpeek);
242 }
243 }
244
245 if( ud.overhead_on > 0 )
246 {
247 smoothratio = min(max(smoothratio,0),65536);
248 dointerpolations(smoothratio);
249 if( ud.scrollmode == 0 )
250 {
251 if(pp->newowner == -1)
252 {
253 if (screenpeek == myconnectindex && numplayers > 1)
254 {
255 cposx = omyx+mulscale16((long)(myx-omyx),smoothratio);
256 cposy = omyy+mulscale16((long)(myy-omyy),smoothratio);
257 cang = omyang+mulscale16((long)(((myang+1024-omyang)&2047)-1024),smoothratio);
258 }
259 else
260 {
261 cposx = pp->oposx+mulscale16((long)(pp->posx-pp->oposx),smoothratio);
262 cposy = pp->oposy+mulscale16((long)(pp->posy-pp->oposy),smoothratio);
263 cang = pp->oang+mulscale16((long)(((pp->ang+1024-pp->oang)&2047)-1024),smoothratio);
264 }
265 }
266 else
267 {
268 cposx = pp->oposx;
269 cposy = pp->oposy;
270 cang = pp->oang;
271 }
272 }
273 else
274 {
275
276 ud.fola += ud.folavel>>3;
277 ud.folx += (ud.folfvel*sintable[(512+2048-ud.fola)&2047])>>14;
278 ud.foly += (ud.folfvel*sintable[(512+1024-512-ud.fola)&2047])>>14;
279
280 cposx = ud.folx;
281 cposy = ud.foly;
282 cang = ud.fola;
283 }
284
285 if(ud.overhead_on == 2)
286 {
287 clearview(0L);
288 drawmapview(cposx,cposy,pp->zoom,cang);
289 }
290 drawoverheadmap( cposx,cposy,pp->zoom,cang);
291
292 restoreinterpolations();
293
294 if(ud.overhead_on == 2)
295 {
296 a = 0;
297 if (lastlevel)
298 minitext(1,a+6,"CLOSE ENCOUNTERS",0,2+8+16);
299 else
300 {
301 minitext(1,a+6,volume_names[ud.volume_number],0,2+8+16);
302 minitext(1,a+12,level_names[ud.volume_number*7 + ud.level_number],0,2+8+16);
303 }
304 }
305 }
306 }
307
308 coolgaugetext(screenpeek);
309 gutmeter(screenpeek);
310 operatefta();
311
312 if( KB_KeyPressed(sc_Escape) && ud.overhead_on == 0
313 && ud.show_help == 0
314 && ps[myconnectindex].newowner == -1)
315 {
316 if( (ps[myconnectindex].gm&MODE_MENU) == MODE_MENU && current_menu < 51)
317 {
318 KB_ClearKeyDown(sc_Escape);
319 ps[myconnectindex].gm &= ~MODE_MENU;
320 if(ud.multimode < 2 && ud.recstat != 2)
321 {
322 ready2send = 1;
323 totalclock = ototalclock;
324 cameraclock = totalclock;
325 cameradist = 65536L;
326 }
327 walock[MAXTILES-1] = 199;
328 vscrn();
329 }
330 else if( (ps[myconnectindex].gm&MODE_MENU) != MODE_MENU &&
331 ps[myconnectindex].newowner == -1 &&
332 (ps[myconnectindex].gm&MODE_TYPE) != MODE_TYPE)
333 {
334 KB_ClearKeyDown(sc_Escape);
335 FX_StopAllSounds();
336 clearsoundlocks();
337
338 intomenusounds();
339
340 ps[myconnectindex].gm |= MODE_MENU;
341
342 if(ud.multimode < 2 && ud.recstat != 2) ready2send = 0;
343
344 if(ps[myconnectindex].gm&MODE_GAME) cmenu(50);
345 else cmenu(0);
346 screenpeek = myconnectindex;
347 }
348 }
349
350 if(ps[myconnectindex].newowner == -1 && ud.overhead_on == 0 && ud.crosshair && ud.camerasprite == -1)
351 rotatesprite((160L-(ps[myconnectindex].look_ang>>1))<<16,100L<<16,32768L,0,CROSSHAIR,0,0,2+1,windowx1,windowy1,windowx2,windowy2);
352
353 if(ps[myconnectindex].gm&MODE_TYPE)
354 typemode();
355 else
356 menus();
357
358 if( ud.pause_on==1 && (ps[myconnectindex].gm&MODE_MENU) == 0 )
359 menutext(160,100,0,0,"GAME PAUSED");
360
361 if(ud.coords)
362 coords(screenpeek);
363 if(ud.tickrate)
364 tics();
365 }
366
367
updatesectorz(long x,long y,long z,short * sectnum)368 void updatesectorz(long x, long y, long z, short *sectnum)
369 {
370 walltype *wal;
371 long i, j, cz, fz;
372
373 getzsofslope(*sectnum,x,y,&cz,&fz);
374 if ((z >= cz) && (z <= fz))
375 if (inside(x,y,*sectnum) != 0) return;
376
377 if ((*sectnum >= 0) && (*sectnum < numsectors))
378 {
379 wal = &wall[sector[*sectnum].wallptr];
380 j = sector[*sectnum].wallnum;
381 do
382 {
383 i = wal->nextsector;
384 if (i >= 0)
385 {
386 getzsofslope(i,x,y,&cz,&fz);
387 if ((z >= cz) && (z <= fz))
388 if (inside(x,y,(short)i) == 1)
389 { *sectnum = i; return; }
390 }
391 wal++; j--;
392 } while (j != 0);
393 }
394
395 for(i=numsectors-1;i>=0;i--)
396 {
397 getzsofslope(i,x,y,&cz,&fz);
398 if ((z >= cz) && (z <= fz))
399 if (inside(x,y,(short)i) == 1)
400 { *sectnum = i; return; }
401 }
402
403 *sectnum = -1;
404 }
405
view(struct player_struct * pp,long * vx,long * vy,long * vz,short * vsectnum,short ang,short horiz)406 void view(struct player_struct *pp, long *vx, long *vy,long *vz,short *vsectnum, short ang, short horiz)
407 {
408 spritetype *sp;
409 long i, nx, ny, nz, hx, hy, hz, hitx, hity, hitz;
410 short bakcstat, hitsect, hitwall, hitsprite, daang;
411
412 nx = (sintable[(ang+1536)&2047]>>4);
413 ny = (sintable[(ang+1024)&2047]>>4);
414 nz = (horiz-100)*128;
415
416 sp = &sprite[pp->i];
417
418 bakcstat = sp->cstat;
419 sp->cstat &= (short)~0x101;
420
421 updatesectorz(*vx,*vy,*vz,vsectnum);
422 hitscan(*vx,*vy,*vz,*vsectnum,nx,ny,nz,&hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1);
423
424 if(*vsectnum < 0)
425 {
426 sp->cstat = bakcstat;
427 return;
428 }
429
430 hx = hitx-(*vx); hy = hity-(*vy);
431 if (klabs(nx)+klabs(ny) > klabs(hx)+klabs(hy))
432 {
433 *vsectnum = hitsect;
434 if (hitwall >= 0)
435 {
436 daang = getangle(wall[wall[hitwall].point2].x-wall[hitwall].x,
437 wall[wall[hitwall].point2].y-wall[hitwall].y);
438
439 i = nx*sintable[daang]+ny*sintable[(daang+1536)&2047];
440 if (klabs(nx) > klabs(ny)) hx -= mulscale28(nx,i);
441 else hy -= mulscale28(ny,i);
442 }
443 else if (hitsprite < 0)
444 {
445 if (klabs(nx) > klabs(ny)) hx -= (nx>>5);
446 else hy -= (ny>>5);
447 }
448 if (klabs(nx) > klabs(ny)) i = divscale16(hx,nx);
449 else i = divscale16(hy,ny);
450 if (i < cameradist) cameradist = i;
451 }
452 *vx = (*vx)+mulscale16(nx,cameradist);
453 *vy = (*vy)+mulscale16(ny,cameradist);
454 *vz = (*vz)+mulscale16(nz,cameradist);
455
456 cameradist = min(cameradist+((totalclock-cameraclock)<<10),65536);
457 cameraclock = totalclock;
458
459 updatesectorz(*vx,*vy,*vz,vsectnum);
460
461 sp->cstat = bakcstat;
462 }
463
464 //REPLACE FULLY
drawbackground(void)465 void drawbackground(void)
466 {
467 short dapicnum;
468 long x,y,x1,y1,x2,y2,topy;
469
470 flushperms();
471
472 switch(ud.m_volume_number)
473 {
474 #ifdef RRRA
475 default:dapicnum = RRTILE7629;break;
476 case 1:dapicnum = RRTILE7629;break;
477 case 2:dapicnum = RRTILE7629;break;
478 #else
479 default:dapicnum = BIGHOLE;break;
480 case 1:dapicnum = BIGHOLE;break;
481 case 2:dapicnum = BIGHOLE;break;
482 #endif
483 }
484
485 y1 = 0; y2 = ydim;
486 if( ready2send || ud.recstat == 2 )
487 {
488 if(ud.coop != 1)
489 {
490 if (ud.multimode > 1) y1 += scale(ydim,8,200);
491 if (ud.multimode > 4) y1 += scale(ydim,8,200);
492 }
493 if (ud.screen_size >= 8) y2 = scale(ydim,200-34,200);
494 }
495
496 for(y=y1;y<y2;y+=128)
497 for(x=0;x<xdim;x+=128)
498 rotatesprite(x<<16,y<<16,32768L,0,dapicnum,18,0,8+16+64+128,0,y1,xdim-1,y2-1);
499
500 if(ud.screen_size > 12)
501 {
502 y = 0;
503 if(ud.coop != 1)
504 {
505 if (ud.multimode > 1) y += 8;
506 if (ud.multimode > 4) y += 8;
507 }
508
509 x1 = max(windowx1-4,0);
510 y1 = max(windowy1-4,y);
511 x2 = min(windowx2+4,xdim-1);
512 y2 = min(windowy2+4,scale(ydim,200-34,200)-1);
513
514 for(y=y1+4;y<y2-4;y+=64)
515 {
516 rotatesprite(x1<<16,y<<16,65536L,0,VIEWBORDER,0,0,8+16+64+128,x1,y1,x2,y2);
517 rotatesprite((x2+1)<<16,(y+64)<<16,65536L,1024,VIEWBORDER,0,0,8+16+64+128,x1,y1,x2,y2);
518 }
519
520 for(x=x1+4;x<x2-4;x+=64)
521 {
522 rotatesprite((x+64)<<16,y1<<16,65536L,512,VIEWBORDER,0,0,8+16+64+128,x1,y1,x2,y2);
523 rotatesprite(x<<16,(y2+1)<<16,65536L,1536,VIEWBORDER,0,0,8+16+64+128,x1,y1,x2,y2);
524 }
525
526 rotatesprite(x1<<16,y1<<16,65536L,0,VIEWBORDER+1,0,0,8+16+64+128,x1,y1,x2,y2);
527 rotatesprite((x2+1)<<16,y1<<16,65536L,512,VIEWBORDER+1,0,0,8+16+64+128,x1,y1,x2,y2);
528 rotatesprite((x2+1)<<16,(y2+1)<<16,65536L,1024,VIEWBORDER+1,0,0,8+16+64+128,x1,y1,x2,y2);
529 rotatesprite(x1<<16,(y2+1)<<16,65536L,1536,VIEWBORDER+1,0,0,8+16+64+128,x1,y1,x2,y2);
530 }
531 }
532
533 #ifdef RRRA
534 // Floor Over Floor
535
536 // If standing in sector with SE42
537 // then draw viewing to SE41 and raise all =hi SE43 cielings.
538
539 // If standing in sector with SE43
540 // then draw viewing to SE40 and lower all =hi SE42 floors.
541
542 // If standing in sector with SE44
543 // then draw viewing to SE40.
544
545 // If standing in sector with SE45
546 // then draw viewing to SE41.
547
548 #define FOFTILE FOF
549 #define FOFTILEX 32
550 #define FOFTILEY 32
551 long tempsectorz[MAXSECTORS];
552 long tempsectorpicnum[MAXSECTORS];
553 //short tempcursectnum;
554
SE_150_Draw(int spnum,long x,long y,long z,short a,short h,long smoothratio)555 SE_150_Draw(int spnum,long x,long y,long z,short a,short h,long smoothratio)
556 {
557 int i=FOFTILE,j,k=0;
558 int floor1=spnum,floor2=0,ok=0,fofmode;
559 long offx,offy;
560
561 if(sprite[spnum].ang!=512) return;
562
563 tilesizx[FOFTILE] = 0;
564 tilesizy[FOFTILE] = 0;
565 if (!(gotpic[i>>3]&(1<<(i&7)))) return;
566 gotpic[i>>3] &= ~(1<<(i&7));
567
568 floor1=spnum;
569
570 if(sprite[spnum].lotag==152) fofmode=150;
571 if(sprite[spnum].lotag==153) fofmode=151;
572 if(sprite[spnum].lotag==154) fofmode=150;
573 if(sprite[spnum].lotag==155) fofmode=151;
574
575 // fofmode=sprite[spnum].lotag-2;
576
577 // sectnum=sprite[j].sectnum;
578 // sectnum=cursectnum;
579 ok++;
580
581 /* recursive?
582 for(j=0;j<MAXSPRITES;j++)
583 {
584 if(
585 sprite[j].sectnum==sectnum &&
586 sprite[j].picnum==1 &&
587 sprite[j].lotag==110
588 ) { DrawFloorOverFloor(j); break;}
589 }
590 */
591
592 // if(ok==0) { Message("no fof",RED); return; }
593
594 for(j=0;j<MAXSPRITES;j++)
595 {
596 if(
597 sprite[j].picnum==1 &&
598 sprite[j].lotag==fofmode &&
599 sprite[j].hitag==sprite[floor1].hitag
600 ) { floor1=j; fofmode=sprite[j].lotag; ok++; break;}
601 }
602 // if(ok==1) { Message("no floor1",RED); return; }
603
604 if(fofmode==150) k=151; else k=150;
605
606 for(j=0;j<MAXSPRITES;j++)
607 {
608 if(
609 sprite[j].picnum==1 &&
610 sprite[j].lotag==k &&
611 sprite[j].hitag==sprite[floor1].hitag
612 ) {floor2=j; ok++; break;}
613 }
614
615 // if(ok==2) { Message("no floor2",RED); return; }
616
617 for(j=0;j<MAXSPRITES;j++) // raise ceiling or floor
618 {
619 if(sprite[j].picnum==1 &&
620 sprite[j].lotag==k+2 &&
621 sprite[j].hitag==sprite[floor1].hitag
622 )
623 {
624 if(k==150)
625 {tempsectorz[sprite[j].sectnum]=sector[sprite[j].sectnum].floorz;
626 sector[sprite[j].sectnum].floorz+=(((z-sector[sprite[j].sectnum].floorz)/32768)+1)*32768;
627 tempsectorpicnum[sprite[j].sectnum]=sector[sprite[j].sectnum].floorpicnum;
628 sector[sprite[j].sectnum].floorpicnum=13;
629 }
630 else if(k==151)
631 {tempsectorz[sprite[j].sectnum]=sector[sprite[j].sectnum].ceilingz;
632 sector[sprite[j].sectnum].ceilingz+=(((z-sector[sprite[j].sectnum].ceilingz)/32768)-1)*32768;
633 tempsectorpicnum[sprite[j].sectnum]=sector[sprite[j].sectnum].ceilingpicnum;
634 sector[sprite[j].sectnum].ceilingpicnum=13;
635 }
636 }
637 }
638
639 i=floor1;
640 offx=x-sprite[i].x;
641 offy=y-sprite[i].y;
642 i=floor2;
643 drawrooms(offx+sprite[i].x,offy+sprite[i].y,z,a,h,sprite[i].sectnum);
644 animatesprites(offx+sprite[i].x,offy+sprite[i].y,a,smoothratio);
645 drawmasks();
646
647 for(j=0;j<MAXSPRITES;j++) // restore ceiling or floor
648 {
649 if(sprite[j].picnum==1 &&
650 sprite[j].lotag==k+2 &&
651 sprite[j].hitag==sprite[floor1].hitag
652 )
653 {
654 if(k==150)
655 {sector[sprite[j].sectnum].floorz=tempsectorz[sprite[j].sectnum];
656 sector[sprite[j].sectnum].floorpicnum=tempsectorpicnum[sprite[j].sectnum];
657 }
658 else if(k==151)
659 {sector[sprite[j].sectnum].ceilingz=tempsectorz[sprite[j].sectnum];
660 sector[sprite[j].sectnum].ceilingpicnum=tempsectorpicnum[sprite[j].sectnum];
661 }
662 }// end if
663 }// end for
664
665 } // end SE40
666
667
668
669
SE_150(long x,long y,long z,long a,long h,long smoothratio)670 void SE_150(long x,long y,long z,long a,long h, long smoothratio)
671 {
672 int i;
673
674 for (i = headspritestat[15]; i >= 0; i = nextspritestat[i])
675 {
676 switch(sprite[i].lotag)
677 {
678 // case 40:
679 // case 41:
680 // SE40_Draw(i,x,y,a,smoothratio);
681 // break;
682 case 152:
683 case 153:
684 case 154:
685 case 155:
686 if(ps[screenpeek].cursectnum == sprite[i].sectnum)
687 SE_150_Draw(i,x,y,z,a,h,smoothratio);
688 break;
689 }
690 }
691 }
692 #endif
693
694 static long oyrepeat=-1;
695 long tempoyrepeat;
696
displayrooms(short snum,long smoothratio)697 void displayrooms(short snum,long smoothratio)
698 {
699 long cposx,cposy,cposz,dst,j,fz,cz,hz,lz;
700 short sect, cang, k, choriz,tsect;
701 struct player_struct *p;
702 long tposx,tposy,tposz,dx,dy,thoriz,i;
703 short tang;
704
705 p = &ps[snum];
706
707 if(screencapt == 0 && (p->gm&MODE_MENU) && ( (current_menu/100) == 3 ) )
708 return;
709
710 if(pub > 0)
711 {
712 if(ud.screen_size > 8) drawbackground();
713 pub = 0;
714 }
715
716 if( ud.overhead_on == 2 || ud.show_help || p->cursectnum == -1)
717 return;
718
719 smoothratio = min(max(smoothratio,0),65536);
720
721 #ifdef RRRA
722 if (p->fogtype)
723 p->visibility = ud.const_visibility;
724 #endif
725
726 visibility = p->visibility;
727
728 if(ud.pause_on || ps[snum].on_crane > -1) smoothratio = 65536;
729
730 sect = p->cursectnum;
731 if(sect < 0 || sect >= MAXSECTORS) return;
732
733 dointerpolations(smoothratio);
734
735 animatecamsprite();
736
737 if(ud.camerasprite >= 0)
738 {
739 spritetype *s;
740
741 s = &sprite[ud.camerasprite];
742
743 if(s->yvel < 0) s->yvel = -100;
744 else if(s->yvel > 199) s->yvel = 300;
745
746 cang = hittype[ud.camerasprite].tempang+mulscale16((long)(((s->ang+1024-hittype[ud.camerasprite].tempang)&2047)-1024),smoothratio);
747
748 drawrooms(s->x,s->y,s->z-(4<<8),cang,s->yvel,s->sectnum);
749 animatesprites(s->x,s->y,cang,smoothratio);
750 drawmasks();
751 }
752 else
753 {
754 i = divscale22(1,64);
755 #ifdef RRRA
756 if (i != oyrepeat && !p->DrugMode)
757 #else
758 if (i != oyrepeat)
759 #endif
760 {
761 oyrepeat = i;
762 setaspect(oyrepeat,yxaspect);
763 }
764
765 if(screencapt)
766 {
767 walock[MAXTILES-1] = 199;
768 if (waloff[MAXTILES-1] == 0)
769 allocache((long *)&waloff[MAXTILES-1],100*160,&walock[MAXTILES-1]);
770 setviewtotile(MAXTILES-1,100L,160L);
771 }
772 else if( ( ud.screen_tilting && p->rotscrnang ) || ud.detail==0 || p->drink_amt > 89)
773 {
774 if (ud.screen_tilting) tang = p->rotscrnang; else tang = 0;
775
776 #ifdef RRRA
777 walock[MAXTILES-2] = 199;
778 if (p->drink_amt > 89)
779 {
780 if (waloff[MAXTILES-2] == 0)
781 allocache(&waloff[MAXTILES-2],320L*320L,&walock[MAXTILES-2]);
782 if ((tang&1023) == 0)
783 setviewtotile(MAXTILES-2,200L>>(1-ud.detail),320L>>(1-ud.detail));
784 else
785 setviewtotile(MAXTILES-2,320L>>(1-ud.detail),320L>>(1-ud.detail));
786 }
787 else
788 {
789 if (waloff[MAXTILES-2] == 0)
790 allocache(&waloff[MAXTILES-2],640L*640L,&walock[MAXTILES-2]);
791 if ((tang&1023) == 0)
792 setviewtotile(MAXTILES-2,480L>>(1-ud.detail),640L>>(1-ud.detail));
793 else
794 setviewtotile(MAXTILES-2,640L>>(1-ud.detail),640L>>(1-ud.detail));
795 }
796 #else
797 walock[MAXTILES-2] = 255;
798 if (waloff[MAXTILES-2] == 0)
799 allocache(&waloff[MAXTILES-2],320L*320L,&walock[MAXTILES-2]);
800 if ((tang&1023) == 0)
801 setviewtotile(MAXTILES-2,200L>>(1-ud.detail),320L>>(1-ud.detail));
802 else
803 setviewtotile(MAXTILES-2,320L>>(1-ud.detail),320L>>(1-ud.detail));
804 #endif
805 if ((tang&1023) == 512)
806 { //Block off unscreen section of 90� tilted screen
807 j = ((320-60)>>(1-ud.detail));
808 for(i=(60>>(1-ud.detail))-1;i>=0;i--)
809 {
810 startumost[i] = 1; startumost[i+j] = 1;
811 startdmost[i] = 0; startdmost[i+j] = 0;
812 }
813 }
814
815 i = (tang&511); if (i > 256) i = 512-i;
816 i = sintable[i+512]*8 + sintable[i]*5L;
817 setaspect(i>>1,yxaspect);
818 }
819
820 #ifdef RRRA
821 if (!(p->gm & MODE_MENU))
822 {
823 if (p->DrugMode > 0 && !(p->gm&MODE_TYPE) && !ud.pause_on)
824 {
825 int var_8c;
826 if (p->raat5f1 == 0)
827 {
828 p->raat5f3++;
829 var_8c = oyrepeat + p->raat5f3 * 5000;
830 if (oyrepeat * 3 < var_8c)
831 {
832 setaspect(oyrepeat * 3, yxaspect);
833 p->raat5f7 = oyrepeat * 3;
834 p->raat5f1 = 2;
835 }
836 else
837 {
838 setaspect(var_8c, yxaspect);
839 p->raat5f7 = var_8c;
840 }
841 setpal(p);
842 }
843 else if (p->raat5f1 == 3)
844 {
845 p->raat5f3--;
846 var_8c = oyrepeat + p->raat5f3 * 5000;
847 if (var_8c < oyrepeat)
848 {
849 setaspect(oyrepeat, yxaspect);
850 p->DrugMode = 0;
851 p->raat5f1 = 0;
852 p->raat5f5 = 0;
853 p->raat5f3 = 0;
854 }
855 else
856 {
857 setaspect(var_8c, yxaspect);
858 p->raat5f7 = var_8c;
859 }
860 setpal(p);
861 }
862 else if (p->raat5f1 == 2)
863 {
864 if (p->raat5f5 > 30)
865 {
866 p->raat5f1 = 1;
867 }
868 else
869 {
870 p->raat5f5++;
871 setaspect(p->raat5f5 * 500 + oyrepeat * 3, yxaspect);
872 p->raat5f7 = oyrepeat * 3 + p->raat5f5 * 500;
873 setpal(p);
874 }
875 }
876 else
877 {
878 if (p->raat5f5 < 1)
879 {
880 p->raat5f1 = 2;
881 p->DrugMode--;
882 if (p->DrugMode == 1)
883 p->raat5f1 = 3;
884 }
885 else
886 {
887 p->raat5f5--;
888 setaspect(p->raat5f5 * 500 + oyrepeat * 3, yxaspect);
889 p->raat5f7 = oyrepeat * 3 + p->raat5f5 * 500;
890 setpal(p);
891 }
892 }
893 }
894 }
895 else if (p->DrugMode > 0)
896 {
897 setaspect(p->raat5f7, yxaspect);
898 setpal(p);
899 }
900 #endif
901
902 if ( (snum == myconnectindex) && (numplayers > 1) )
903 {
904 cposx = omyx+mulscale16((long)(myx-omyx),smoothratio);
905 cposy = omyy+mulscale16((long)(myy-omyy),smoothratio);
906 cposz = omyz+mulscale16((long)(myz-omyz),smoothratio);
907 cang = omyang+mulscale16((long)(((myang+1024-omyang)&2047)-1024),smoothratio);
908 choriz = omyhoriz+omyhorizoff+mulscale16((long)(myhoriz+myhorizoff-omyhoriz-omyhorizoff),smoothratio);
909 sect = mycursectnum;
910 }
911 else
912 {
913 cposx = p->oposx+mulscale16((long)(p->posx-p->oposx),smoothratio);
914 cposy = p->oposy+mulscale16((long)(p->posy-p->oposy),smoothratio);
915 cposz = p->oposz+mulscale16((long)(p->posz-p->oposz),smoothratio);
916 cang = p->oang+mulscale16((long)(((p->ang+1024-p->oang)&2047)-1024),smoothratio);
917 choriz = p->ohoriz+p->ohorizoff+mulscale16((long)(p->horiz+p->horizoff-p->ohoriz-p->ohorizoff),smoothratio);
918 }
919 cang += p->look_ang;
920
921 if (p->newowner >= 0)
922 {
923 cang = p->ang+p->look_ang;
924 choriz = p->horiz+p->horizoff;
925 cposx = p->posx;
926 cposy = p->posy;
927 cposz = p->posz;
928 sect = sprite[p->newowner].sectnum;
929 smoothratio = 65536L;
930 }
931
932 else if( p->over_shoulder_on == 0 )
933 cposz += p->opyoff+mulscale16((long)(p->pyoff-p->opyoff),smoothratio);
934 else view(p,&cposx,&cposy,&cposz,§,cang,choriz);
935
936 cz = hittype[p->i].ceilingz;
937 fz = hittype[p->i].floorz;
938
939 if(earthquaketime > 0 && p->on_ground == 1)
940 {
941 cposz += 256-(((earthquaketime)&1)<<9);
942 cang += (2-((earthquaketime)&2))<<2;
943 }
944
945 if(sprite[p->i].pal == 1) cposz -= (18<<8);
946
947 if(p->newowner >= 0)
948 choriz = 100+sprite[p->newowner].shade;
949 else if(p->spritebridge == 0)
950 {
951 if( cposz < ( p->truecz + (4<<8) ) ) cposz = cz + (4<<8);
952 else if( cposz > ( p->truefz - (4<<8) ) ) cposz = fz - (4<<8);
953 }
954
955 if (sect >= 0)
956 {
957 getzsofslope(sect,cposx,cposy,&cz,&fz);
958 if (cposz < cz+(4<<8)) cposz = cz+(4<<8);
959 if (cposz > fz-(4<<8)) cposz = fz-(4<<8);
960 }
961
962 if(choriz > 299) choriz = 299;
963 else if(choriz < -99) choriz = -99;
964
965 #ifdef RRRA
966 SE_150(cposx,cposy,cposz,cang,choriz,smoothratio);
967 #endif
968
969 if ((gotpic[MIRROR>>3]&(1<<(MIRROR&7))) > 0)
970 {
971 dst = 0x7fffffff; i = 0;
972 for(k=0;k<mirrorcnt;k++)
973 {
974 j = klabs(wall[mirrorwall[k]].x-cposx);
975 j += klabs(wall[mirrorwall[k]].y-cposy);
976 if (j < dst) dst = j, i = k;
977 }
978
979 if( wall[mirrorwall[i]].overpicnum == MIRROR )
980 {
981 preparemirror(cposx,cposy,cposz,cang,choriz,mirrorwall[i],mirrorsector[i],&tposx,&tposy,&tang);
982
983 j = visibility;
984 visibility = (j>>1) + (j>>2);
985
986 drawrooms(tposx,tposy,cposz,tang,choriz,mirrorsector[i]+MAXSECTORS);
987
988 display_mirror = 1;
989 animatesprites(tposx,tposy,tang,smoothratio);
990 display_mirror = 0;
991
992 drawmasks();
993 completemirror(); //Reverse screen x-wise in this function
994 visibility = j;
995 }
996 gotpic[MIRROR>>3] &= ~(1<<(MIRROR&7));
997 }
998
999 if (sector[sect].lotag == 848)
1000 {
1001 short gs, tgsect, nextspr, geosect, geoid;
1002 int spr;
1003 drawrooms(cposx, cposy, cposz, cang, choriz, sect);
1004 animatesprites(cposx,cposy,cang,smoothratio);
1005 drawmasks();
1006 for (gs = 0; gs < geocnt; gs++)
1007 {
1008 tgsect = geosector[gs];
1009 spr = headspritesect[tgsect];
1010 while (spr != -1)
1011 {
1012 nextspr = nextspritesect[spr];
1013 changespritesect((short)spr, geosectorwarp[gs]);
1014 setsprite((short)spr,sprite[spr].x -= geox[gs],sprite[spr].y -= geoy[gs],sprite[spr].z);
1015 spr = nextspr;
1016 }
1017 if (geosector[gs] == sect)
1018 {
1019 geosect = geosectorwarp[gs];
1020 geoid = gs;
1021 }
1022 }
1023 cposx -= geox[geoid];
1024 cposy -= geoy[geoid];
1025 drawrooms(cposx, cposy, cposz, cang, choriz, sect);
1026 cposx += geox[geoid];
1027 cposy += geoy[geoid];
1028 for (gs = 0; gs < geocnt; gs++)
1029 {
1030 tgsect = geosectorwarp[gs];
1031 spr = headspritesect[tgsect];
1032 while (spr != -1)
1033 {
1034 nextspr = nextspritesect[spr];
1035 changespritesect((short)spr, geosector[gs]);
1036 setsprite((short)spr,sprite[spr].x += geox[gs],sprite[spr].y += geoy[gs],sprite[spr].z);
1037 spr = nextspr;
1038 }
1039 }
1040 animatesprites(cposx,cposy,cang,smoothratio);
1041 drawmasks();
1042 for (gs = 0; gs < geocnt; gs++)
1043 {
1044 tgsect = geosector[gs];
1045 spr = headspritesect[tgsect];
1046 while (spr != -1)
1047 {
1048 nextspr = nextspritesect[spr];
1049 changespritesect((short)spr, geosectorwarp2[gs]);
1050 setsprite((short)spr,sprite[spr].x -= geox2[gs],sprite[spr].y -= geoy2[gs],sprite[spr].z);
1051 spr = nextspr;
1052 }
1053 if (geosector[gs] == sect)
1054 {
1055 geosect = geosectorwarp2[gs];
1056 geoid = gs;
1057 }
1058 }
1059 cposx -= geox2[geoid];
1060 cposy -= geoy2[geoid];
1061 drawrooms(cposx, cposy, cposz, cang, choriz, sect);
1062 cposx += geox2[geoid];
1063 cposy += geoy2[geoid];
1064 for (gs = 0; gs < geocnt; gs++)
1065 {
1066 tgsect = geosectorwarp2[gs];
1067 spr = headspritesect[tgsect];
1068 while (spr != -1)
1069 {
1070 nextspr = nextspritesect[spr];
1071 changespritesect((short)spr, geosector[gs]);
1072 setsprite((short)spr,sprite[spr].x += geox2[gs],sprite[spr].y += geoy2[gs],sprite[spr].z);
1073 spr = nextspr;
1074 }
1075 }
1076 animatesprites(cposx,cposy,cang,smoothratio);
1077 drawmasks();
1078 }
1079 else
1080 {
1081 drawrooms(cposx, cposy, cposz, cang, choriz, sect);
1082 animatesprites(cposx, cposy, cang, smoothratio);
1083 drawmasks();
1084 }
1085
1086 if(screencapt == 1)
1087 {
1088 setviewback();
1089 walock[MAXTILES-1] = 190;
1090 screencapt = 0;
1091 }
1092 else if( ( ud.screen_tilting && p->rotscrnang) || ud.detail==0 || p->drink_amt > 89)
1093 {
1094 if (ud.screen_tilting) tang = p->rotscrnang; else tang = 0;
1095 setviewback();
1096 picanm[MAXTILES-2] &= 0xff0000ff;
1097 i = (tang&511); if (i > 256) i = 512-i;
1098 i = sintable[i+512]*8 + sintable[i]*5L;
1099 #ifdef RRRA
1100 if (p->drink_amt > 89)
1101 {
1102 if ((1-ud.detail) == 0) i >>= 1;
1103 }
1104 else
1105 {
1106 if ((1-ud.detail) == 0) i >>= 2;
1107 }
1108 #else
1109 if ((1-ud.detail) == 0) i >>= 1;
1110 #endif
1111 rotatesprite(160<<16,100<<16,i,tang+512,MAXTILES-2,0,0,4+2+64,windowx1,windowy1,windowx2,windowy2);
1112 walock[MAXTILES-2] = 199;
1113 }
1114 }
1115
1116 restoreinterpolations();
1117
1118 #ifdef RRRA
1119 if (p->fogtype) return;
1120 #endif
1121
1122 if (totalclock < lastvisinc)
1123 {
1124 if (klabs(p->visibility-ud.const_visibility) > 8)
1125 p->visibility += (ud.const_visibility-p->visibility)>>2;
1126 }
1127 else p->visibility = ud.const_visibility;
1128 }
1129
1130
1131
1132
1133
LocateTheLocator(short n,short sn)1134 short LocateTheLocator(short n,short sn)
1135 {
1136 short i;
1137
1138 i = headspritestat[7];
1139 while(i >= 0)
1140 {
1141 if( (sn == -1 || sn == SECT) && n == SLT )
1142 return i;
1143 i = nextspritestat[i];
1144 }
1145 return -1;
1146 }
1147
EGS(short whatsect,long s_x,long s_y,long s_z,short s_pn,signed char s_s,signed char s_xr,signed char s_yr,short s_a,short s_ve,long s_zv,short s_ow,signed char s_ss)1148 short EGS(short whatsect,long s_x,long s_y,long s_z,short s_pn,signed char s_s,signed char s_xr,signed char s_yr,short s_a,short s_ve,long s_zv,short s_ow,signed char s_ss)
1149 {
1150 short i;
1151 spritetype *s;
1152
1153 if (s_ow < 0)
1154 return 0;
1155
1156 i = insertsprite(whatsect,s_ss);
1157
1158 if( i < 0 )
1159 gameexit(" Too many sprites spawned.");
1160
1161 hittype[i].bposx = s_x;
1162 hittype[i].bposy = s_y;
1163 hittype[i].bposz = s_z;
1164
1165 s = &sprite[i];
1166
1167 s->x = s_x;
1168 s->y = s_y;
1169 s->z = s_z;
1170 s->cstat = 0;
1171 s->picnum = s_pn;
1172 s->shade = s_s;
1173 s->xrepeat = s_xr;
1174 s->yrepeat = s_yr;
1175 s->pal = 0;
1176
1177 s->ang = s_a;
1178 s->xvel = s_ve;
1179 s->zvel = s_zv;
1180 s->owner = s_ow;
1181 s->xoffset = 0;
1182 s->yoffset = 0;
1183 s->yvel = 0;
1184 s->clipdist = 0;
1185 s->pal = 0;
1186 s->lotag = 0;
1187
1188 hittype[i].picnum = sprite[s_ow].picnum;
1189
1190 hittype[i].lastvx = 0;
1191 hittype[i].lastvy = 0;
1192
1193 hittype[i].timetosleep = 0;
1194 hittype[i].actorstayput = -1;
1195 hittype[i].extra = -1;
1196 hittype[i].owner = s_ow;
1197 hittype[i].cgg = 0;
1198 hittype[i].movflag = 0;
1199 hittype[i].tempang = 0;
1200 hittype[i].dispicnum = 0;
1201 hittype[i].floorz = hittype[s_ow].floorz;
1202 hittype[i].ceilingz = hittype[s_ow].ceilingz;
1203
1204 T1=T3=T4=T6=0;
1205 if( actorscrptr[s_pn] )
1206 {
1207 s->extra = *actorscrptr[s_pn];
1208 T5 = *(actorscrptr[s_pn]+1);
1209 T2 = *(actorscrptr[s_pn]+2);
1210 s->hitag = *(actorscrptr[s_pn]+3);
1211 }
1212 else
1213 {
1214 T2=T5=0;
1215 s->extra = 0;
1216 s->hitag = 0;
1217 }
1218
1219 if (show2dsector[SECT>>3]&(1<<(SECT&7))) show2dsprite[i>>3] |= (1<<(i&7));
1220 else show2dsprite[i>>3] &= ~(1<<(i&7));
1221 /*
1222 if(s->sectnum < 0)
1223 {
1224 s->xrepeat = s->yrepeat = 0;
1225 changespritestat(i,5);
1226 }
1227 */
1228 return(i);
1229 }
1230
wallswitchcheck(short i)1231 char wallswitchcheck(short i)
1232 {
1233 switch(PN)
1234 {
1235 case HANDPRINTSWITCH:
1236 case HANDPRINTSWITCH+1:
1237 case ALIENSWITCH:
1238 case ALIENSWITCH+1:
1239 case MULTISWITCH:
1240 case MULTISWITCH+1:
1241 case MULTISWITCH+2:
1242 case MULTISWITCH+3:
1243 case ACCESSSWITCH:
1244 case ACCESSSWITCH2:
1245 case PULLSWITCH:
1246 case PULLSWITCH+1:
1247 case HANDSWITCH:
1248 case HANDSWITCH+1:
1249 case SLOTDOOR:
1250 case SLOTDOOR+1:
1251 case LIGHTSWITCH:
1252 case LIGHTSWITCH+1:
1253 case SPACELIGHTSWITCH:
1254 case SPACELIGHTSWITCH+1:
1255 case SPACEDOORSWITCH:
1256 case SPACEDOORSWITCH+1:
1257 case FRANKENSTINESWITCH:
1258 case FRANKENSTINESWITCH+1:
1259 case LIGHTSWITCH2:
1260 case LIGHTSWITCH2+1:
1261 case POWERSWITCH1:
1262 case POWERSWITCH1+1:
1263 case LOCKSWITCH1:
1264 case LOCKSWITCH1+1:
1265 case POWERSWITCH2:
1266 case POWERSWITCH2+1:
1267 case DIPSWITCH:
1268 case DIPSWITCH+1:
1269 case DIPSWITCH2:
1270 case DIPSWITCH2+1:
1271 case TECHSWITCH:
1272 case TECHSWITCH+1:
1273 case DIPSWITCH3:
1274 case DIPSWITCH3+1:
1275 case NUKEBUTTON:
1276 case NUKEBUTTON+1:
1277 #ifdef RRRA
1278 case MULTISWITCH2:
1279 case MULTISWITCH2+1:
1280 case MULTISWITCH2+2:
1281 case MULTISWITCH2+3:
1282 case RRTILE8464:
1283 case RRTILE8464+1:
1284 #endif
1285 return 1;
1286 }
1287 return 0;
1288 }