1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 1997, 2005 - 3D Realms Entertainment
4
5 This file is part of Shadow Warrior version 1.2
6
7 Shadow Warrior is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22 Original Source: 1997 - Frank Maddin and Jim Norwood
23 Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
24 */
25 //-------------------------------------------------------------------------
26
27 // CTW NOTE
28 /*
29 Known remaining issues:
30 - Audio stuttering.
31 - CD Audio not looping properly (currently hard coded to restart about every 200 seconds.
32 - Hitting F5 to change resolution causes a crash (currently disabled).
33 - Multiplayer untested.
34
35 Things required to make savegames work:
36 - Load makesym.wpj and build it.
37 - In a DOS prompt, run "makesym sw.map swdata.map swcode.map"
38 - Copy swcode.map to swcode.sym and swdata.map to swdata.sym
39 */
40 // CTW NOTE END
41
42 #define MAIN
43 #define QUIET
44 #include "build.h"
45 #include "baselayer.h"
46 #include "cache1d.h"
47 #include "osd.h"
48 #ifdef RENDERTYPEWIN
49 # include "winlayer.h"
50 #endif
51
52 #include "keys.h"
53 #include "names2.h"
54 #include "panel.h"
55 #include "game.h"
56 #include "tags.h"
57 #include "sector.h"
58 #include "sprite.h"
59 #include "weapon.h"
60 #include "player.h"
61 #include "lists.h"
62 #include "net.h"
63 #include "pal.h"
64 #include "fx_man.h"
65
66 #include "mytypes.h"
67 //#include "config.h"
68
69 #include "menus.h"
70
71 #include "control.h"
72 #include "function.h"
73 #include "gamedefs.h"
74 #include "config.h"
75
76 #include "demo.h"
77 #include "cache.h"
78 //#include "exports.h"
79
80 #include "anim.h"
81
82 #include "colormap.h"
83 #include "break.h"
84 #include "ninja.h"
85 #include "light.h"
86 #include "track.h"
87 #include "jsector.h"
88 #include "keyboard.h"
89 #include "text.h"
90 #include "music.h"
91
92 #include "crc32.h"
93
94 #include "startwin.h"
95 #include "version.h"
96
97 #if DEBUG
98 #define BETA 0
99 #endif
100
101 #define STAT_SCREEN_PIC 5114
102 #define TITLE_PIC 2324
103 #define THREED_REALMS_PIC 2325
104 #define TITLE_ROT_FLAGS (ROTATE_SPRITE_CORNER|ROTATE_SPRITE_SCREEN_CLIP|ROTATE_SPRITE_NON_MASK)
105 #define PAL_SIZE (256*3)
106
107 char DemoName[15][16];
108
109 // Stupid WallMart version!
110 //#define PLOCK_VERSION TRUE
111
112 #if PLOCK_VERSION
113 BOOL Global_PLock = TRUE;
114 #else
115 BOOL Global_PLock = FALSE;
116 #endif
117
118 int GameVersion = 13; // 12 was original source release. For future releases increment by two.
119 char DemoText[3][64];
120 int DemoTextYstart = 0;
121
122 BOOL DoubleInitAWE32 = FALSE;
123 int Follow_posx=0,Follow_posy=0;
124
125 BOOL NoMeters = FALSE;
126 short IntroAnimCount = 0;
127 short PlayingLevel = -1;
128 BOOL GraphicsMode = FALSE;
129 char CacheLastLevel[32] = "";
130 BOOL CleanExit = FALSE;
131 extern char cachedebug;
132 BOOL DemoModeMenuInit = FALSE;
133 BOOL FinishAnim = 0;
134 BOOL CachePrintMode = FALSE;
135 BOOL ShortGameMode = FALSE;
136 BOOL ReloadPrompt = FALSE;
137 BOOL ReloadPromptMode = FALSE;
138 BOOL NewGame = TRUE;
139 BOOL InMenuLevel = FALSE;
140 BOOL LoadGameOutsideMoveLoop = FALSE;
141 BOOL LoadGameFromDemo = FALSE;
142 BOOL ArgCheat = FALSE;
143 extern BOOL NetBroadcastMode, NetModeOverride;
144 BOOL MultiPlayQuitFlag = FALSE;
145 //Miscellaneous variables
146 char MessageInputString[256];
147 char MessageOutputString[256];
148 BOOL MessageInputMode = FALSE;
149 BOOL ConInputMode = FALSE;
150 BOOL ConPanel = FALSE;
151 BOOL FinishedLevel = FALSE;
152 BOOL HelpInputMode = FALSE;
153 BOOL PanelUpdateMode = TRUE;
154 short HelpPage = 0;
155 short HelpPagePic[] = { 5115, 5116, 5117 };
156 BOOL InputMode = FALSE;
157 BOOL MessageInput = FALSE;
158 extern BOOL GamePaused;
159 short screenpeek = 0;
160 BOOL NoDemoStartup = FALSE;
161 BOOL FirstTimeIntoGame;
162 extern BYTE RedBookSong[40];
163
164 BOOL BorderAdjust = TRUE;
165 BOOL LocationInfo = 0;
166 VOID drawoverheadmap(int cposx, int cposy, int czoom, short cang);
167 int DispFrameRate = FALSE;
168 int DispMono = TRUE;
169 int Fog = FALSE;
170 int FogColor;
171 int PreCaching = TRUE;
172 int GodMode = FALSE;
173 int BotMode = FALSE;
174 short Skill = 2;
175 short BetaVersion = 900;
176 short TotalKillable;
177
178 AUTO_NET Auto;
179 BOOL AutoNet = FALSE;
180 BOOL HasAutoColor = FALSE;
181 BYTE AutoColor;
182
183 const GAME_SET gs_defaults = {
184 32768, // mouse speed
185 128, // music vol
186 192, // fx vol
187 2, // border
188 0, // brightness
189 0, // border tile
190 FALSE, // mouse aiming
191 FALSE, // mouse look
192 FALSE, // mouse invert
193 TRUE, // bobbing
194 FALSE, // tilting
195 TRUE, // shadows
196 FALSE, // auto run
197 TRUE, // crosshair
198 TRUE, // auto aim
199 TRUE, // messages
200 TRUE, // fx on
201 TRUE, // Music on
202 TRUE, // talking
203 TRUE, // ambient
204 FALSE, // Flip Stereo
205
206 // Network game settings
207 0, // GameType
208 0, // Level
209 0, // Monsters
210 FALSE, // HurtTeammate
211 TRUE, // SpawnMarkers Markers
212 FALSE, // TeamPlay
213 0, // Kill Limit
214 0, // Time Limit
215 0, // Color
216 0, // Parental Lock
217 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", // Password
218 TRUE, // nuke
219 TRUE, // voxels
220 FALSE, // stats
221 FALSE, // mouse aiming on
222 FALSE, // play cd
223 "track??.ogg", // ogg track name
224 8, // panel scale
225 };
226 GAME_SET gs;
227
228 char PlaxBits = 0;
229 BOOL PlayerTrackingMode = FALSE;
230 BOOL PauseMode = FALSE;
231 BOOL PauseKeySet = FALSE;
232 BOOL SlowMode = FALSE;
233 BOOL FrameAdvanceTics = 3;
234 BOOL ScrollMode2D = FALSE;
235
236 BOOL DebugSO = FALSE;
237 BOOL DebugPanel = FALSE;
238 BOOL DebugSector = FALSE;
239 BOOL DebugActor = FALSE;
240 BOOL DebugAnim = FALSE;
241 BOOL DebugOperate = FALSE;
242 BOOL DebugActorFreeze = FALSE;
243 VOID LoadingLevelScreen(char *level_name);
244
245 BYTE FakeMultiNumPlayers;
246
247 int totalsynctics;
248 int turn_scale = 256;
249 int move_scale = 256;
250
251 short Level = 0;
252 BOOL ExitLevel = FALSE;
253 SHORT OrigCommPlayers=0;
254 extern BYTE CommPlayers;
255 extern BOOL CommEnabled;
256 extern int bufferjitter;
257
258 BOOL CameraTestMode = FALSE;
259
260 char ds[256]; // debug string
261
262 extern short NormalVisibility;
263
264 extern int quotebot, quotebotgoal; // Multiplayer typing buffer
265 char recbuf[80]; // Used as a temp buffer to hold typing text
266
267 extern unsigned char palette_data[256][3]; // Global palette array
268
269 #define ACT_STATUE 0
270
271 int score;
272 BOOL QuitFlag = FALSE;
273 BOOL InGame = FALSE;
274
275 int CommandSetup = FALSE;
276
277 char UserMapName[80]="", buffer[80], ch;
278 char LevelName[20];
279
280 BYTE DebugPrintColor = 255;
281
282 int krandcount;
283
284 /// L O C A L P R O T O T Y P E S /////////////////////////////////////////////////////////
285 void BOT_DeleteAllBots( void );
286 VOID BotPlayerInsert(PLAYERp pp);
287 VOID SybexScreen(VOID);
288 VOID DosScreen(VOID);
289 VOID MenuLevel(VOID);
290 VOID StatScreen(PLAYERp mpp);
291 VOID InitRunLevel(VOID);
292 VOID RunLevel(VOID);
293 static int osdcmd_restartvid(const osdfuncparm_t *parm);
294 static int osdcmd_vidmode(const osdfuncparm_t *parm);
295 /////////////////////////////////////////////////////////////////////////////////////////////
296
297 static FILE *debug_fout = NULL;
298
DebugWriteString(char * string)299 VOID DebugWriteString(char *string)
300 {
301
302 #if BETA || !DEBUG
303 return;
304 #endif
305
306 if (!debug_fout)
307 {
308 if ((debug_fout = fopen("dbg.foo", "ab+")) == NULL)
309 return;
310 }
311
312 fprintf(debug_fout, "%s\n", string);
313
314 //fclose(debug_fout);
315 //debug_fout = NULL;
316
317 fflush(debug_fout);
318 }
319
DebugWriteLoc(char * fname,int line)320 VOID DebugWriteLoc(char *fname, int line)
321 {
322
323 #if BETA || !DEBUG
324 return;
325 #endif
326
327 if (!debug_fout)
328 {
329 if ((debug_fout = fopen("dbg.foo", "ab+")) == NULL)
330 return;
331 }
332
333 fprintf(debug_fout, "%s, %d\n", fname, line);
334
335 //fclose(debug_fout);
336 //debug_fout = NULL;
337
338 fflush(debug_fout);
339 }
340
341
342 extern BOOL DrawScreen;
343 #if RANDOM_DEBUG
344 FILE *fout_err;
345 BOOL RandomPrint;
krand1(char * file,unsigned line)346 int krand1(char *file, unsigned line)
347 {
348 ASSERT(!DrawScreen);
349 if (RandomPrint && !Prediction)
350 { extern ULONG MoveThingsCount;
351 sprintf(ds,"mtc %d, %s, line %d, %d",MoveThingsCount,file,line,randomseed);
352 DebugWriteString(ds);
353 }
354 randomseed = ((randomseed * 21 + 1) & 65535);
355 return (randomseed);
356 }
357
krand2()358 int krand2()
359 {
360 ASSERT(!DrawScreen);
361 randomseed = ((randomseed * 21 + 1) & 65535);
362 return (randomseed);
363 }
364
365 #else
krand1(void)366 int krand1(void)
367 {
368 ASSERT(!DrawScreen);
369 krandcount++;
370 randomseed = ((randomseed * 21 + 1) & 65535);
371 return (randomseed);
372 }
373
374 #endif
375
376 VOID *
CacheAlloc(void ** ptr,int size,unsigned char * lock_byte)377 CacheAlloc(void **ptr, int size, unsigned char *lock_byte)
378 {
379 if (*ptr == NULL)
380 {
381 *lock_byte = CACHE_LOCK_START;
382 allocache(ptr, size, lock_byte);
383 }
384 else
385 {
386 if (*lock_byte < CACHE_LOCK_START)
387 *lock_byte = CACHE_LOCK_START;
388 else
389 (*lock_byte)++;
390 }
391
392 return(*ptr);
393 }
394
395 VOID
CacheFree(void ** ptr,unsigned char * lock_byte)396 CacheFree(void **ptr, unsigned char *lock_byte)
397 {
398 if (*ptr == NULL)
399 {
400 ASSERT(*lock_byte == NULL);
401 }
402 else
403 {
404 if (*lock_byte < CACHE_LOCK_START)
405 *lock_byte = CACHE_UNLOCK_START;
406 }
407 }
408
409 /*
410 void HeapCheck(char *file, int line)
411 {
412 switch( _heapchk() )
413 {
414 case _HEAPOK:
415 //printf( "OK - heap is good\n" );
416 break;
417 case _HEAPEMPTY:
418 //printf( "OK - heap is empty\n" );
419 break;
420 case _HEAPBADBEGIN:
421 sprintf(ds, "ERROR - heap is damaged: %s, %d", file, line);
422 MONO_PRINT(ds);
423 DebugWriteString(ds);
424 setvmode(0x3);
425 printf( "%s\n", ds);
426 exit(0);
427 break;
428 case _HEAPBADNODE:
429 sprintf(ds, "ERROR - bad node in heap: %s, %d", file, line);
430 MONO_PRINT(ds);
431 DebugWriteString(ds);
432 setvmode(0x3);
433 printf( "%s\n", ds);
434 exit(0);
435 break;
436 }
437 }
438 */
439
440 #if DEBUG
441 BOOL
ValidPtr(VOID * ptr)442 ValidPtr(VOID * ptr)
443 {
444 MEM_HDRp mhp;
445 BYTEp check;
446
447 ASSERT(ptr != NULL);
448
449 mhp = (MEM_HDRp) (((BYTEp) ptr) - sizeof(MEM_HDR));
450
451 if (mhp->size == 0 || mhp->checksum == 0)
452 {
453 printf("ValidPtr(): Size or Checksum == 0!\n");
454 return (FALSE);
455 }
456
457 check = (BYTEp) & mhp->size;
458
459 if (mhp->checksum == check[0] + check[1] + check[2] + check[3])
460 return (TRUE);
461
462 printf("ValidPtr(): Checksum bad!\n");
463 return (FALSE);
464 }
465
466 VOID
PtrCheckSum(VOID * ptr,unsigned int * stored,unsigned int * actual)467 PtrCheckSum(VOID * ptr, unsigned int *stored, unsigned int *actual)
468 {
469 MEM_HDRp mhp;
470 BYTEp check;
471
472 ASSERT(ptr != NULL);
473
474 mhp = (MEM_HDRp) (((BYTEp) ptr) - sizeof(MEM_HDR));
475
476 check = (BYTEp) & mhp->size;
477
478 *stored = mhp->checksum;
479 *actual = check[0] + check[1] + check[2] + check[3];
480 }
481
482 VOID *
AllocMem(int size)483 AllocMem(int size)
484 {
485 BYTEp bp;
486 MEM_HDRp mhp;
487 BYTEp check;
488
489 ASSERT(size != 0);
490
491 bp = (BYTEp) malloc(size + sizeof(MEM_HDR));
492
493 // Used for debugging, we can remove this at ship time
494 if(bp == NULL)
495 {
496 TerminateGame();
497 printf("Memory could NOT be allocated in AllocMem: size = %d\n",size);
498 exit(0);
499 }
500
501 ASSERT(bp != NULL);
502
503 mhp = (MEM_HDRp) bp;
504
505 mhp->size = size;
506 check = (BYTEp) & mhp->size;
507 mhp->checksum = check[0] + check[1] + check[2] + check[3];
508
509 bp += sizeof(MEM_HDR);
510
511 return (bp);
512 }
513
514 VOID *
ReAllocMem(VOID * ptr,int size)515 ReAllocMem(VOID * ptr, int size)
516 {
517 BYTEp bp;
518 MEM_HDRp mhp;
519 BYTEp check;
520
521 ASSERT(size != 0);
522
523 ASSERT(ValidPtr(ptr));
524
525 mhp = (MEM_HDRp) (((BYTEp) ptr) - sizeof(MEM_HDR));
526
527 bp = (BYTEp) realloc(mhp, size + sizeof(MEM_HDR));
528
529 ASSERT(bp != NULL);
530
531 mhp = (MEM_HDRp) bp;
532
533 mhp->size = size;
534 check = (BYTEp) & mhp->size;
535 mhp->checksum = check[0] + check[1] + check[2] + check[3];
536
537 bp += sizeof(MEM_HDR);
538
539 ASSERT(ValidPtr(bp));
540
541 return (bp);
542 }
543
544
545 VOID *
CallocMem(int size,int num)546 CallocMem(int size, int num)
547 {
548 BYTEp bp;
549 MEM_HDRp mhp;
550 BYTEp check;
551 int num_bytes;
552
553 ASSERT(size != 0 && num != 0);
554
555 num_bytes = (size * num) + sizeof(MEM_HDR);
556 bp = (BYTEp) calloc(num_bytes, 1);
557
558 // Used for debugging, we can remove this at ship time
559 if(bp == NULL)
560 {
561 TerminateGame();
562 printf("Memory could NOT be allocated in CallocMem: size = %d, num = %d\n",size,num);
563 exit(0);
564 }
565
566 ASSERT(bp != NULL);
567
568 mhp = (MEM_HDRp) bp;
569
570 mhp->size = size;
571 check = (BYTEp) & mhp->size;
572 mhp->checksum = check[0] + check[1] + check[2] + check[3];
573
574 bp += sizeof(MEM_HDR);
575
576 return (bp);
577 }
578
579 VOID
FreeMem(VOID * ptr)580 FreeMem(VOID * ptr)
581 {
582 MEM_HDRp mhp;
583 BYTEp check;
584
585 ASSERT(ptr != NULL);
586
587 ASSERT(ValidPtr(ptr));
588
589 mhp = (MEM_HDRp) (((BYTEp) ptr) - sizeof(MEM_HDR));
590 check = (BYTEp)&mhp->size;
591
592 memset(mhp, 0xCC, mhp->size + sizeof(MEM_HDR));
593
594 free(mhp);
595 }
596
597 #else
598 BOOL
ValidPtr(VOID * ptr)599 ValidPtr(VOID * ptr)
600 {
601 return (TRUE);
602 }
603
604 VOID *
AllocMem(int size)605 AllocMem(int size)
606 {
607 return (malloc(size));
608 }
609
610 VOID *
CallocMem(int size,int num)611 CallocMem(int size, int num)
612 {
613 return (calloc(size, num));
614 }
615
616 VOID *
ReAllocMem(VOID * ptr,int size)617 ReAllocMem(VOID * ptr, int size)
618 {
619 return (realloc(ptr, size));
620 }
621
622 VOID
FreeMem(VOID * ptr)623 FreeMem(VOID * ptr)
624 {
625 free(ptr);
626 }
627
628 #endif
629
PointOnLine(int x,int y,int x1,int y1,int x2,int y2)630 int PointOnLine(int x, int y, int x1, int y1, int x2, int y2)
631 {
632 // the closer to 0 the closer to the line the point is
633 return( ((x2 - x1) * (y - y1)) - ((y2 - y1) * (x - x1)) );
634 }
635
636 int
Distance(int x1,int y1,int x2,int y2)637 Distance(int x1, int y1, int x2, int y2)
638 {
639 int min;
640
641 if ((x2 = x2 - x1) < 0)
642 x2 = -x2;
643
644 if ((y2 = y2 - y1) < 0)
645 y2 = -y2;
646
647 if (x2 > y2)
648 min = y2;
649 else
650 min = x2;
651
652 return (x2 + y2 - DIV2(min));
653 }
654
655 VOID
MapSetAll2D(BYTE fill)656 MapSetAll2D(BYTE fill)
657 {
658 int i;
659
660 for (i = 0; i < (MAXWALLS >> 3); i++)
661 show2dwall[i] = fill;
662 for (i = 0; i < (MAXSPRITES >> 3); i++)
663 show2dsprite[i] = fill;
664
665 //for (i = 0; i < (MAXSECTORS >> 3); i++)
666 for (i = 0; i < MAXSECTORS; i++)
667 {
668 if (sector[i].ceilingpicnum != 342 && sector[i].floorpicnum != 342)
669 show2dsector[i>>3] |= (1<<(i&7));
670 //show2dsector[i] = fill;
671 }
672 }
673
674 VOID
MapSetup(VOID)675 MapSetup(VOID)
676 {
677 #define NO_AUTO_MAPPING FALSE
678
679 #if NO_AUTO_MAPPING
680 MapSetAll2D(0xFF);
681 #else
682 automapping = TRUE;
683 #endif
684 }
685
686 VOID
setup2dscreen(VOID)687 setup2dscreen(VOID)
688 {
689 // qsetmode640350();
690 }
691
692
693
694 VOID
TerminateGame(VOID)695 TerminateGame(VOID)
696 {
697 int i,j;
698 int oldtotalclock;
699
700 DemoTerm();
701
702 ErrorCorrectionQuit();
703
704 uninitmultiplayers();
705
706 if (CleanExit)
707 {
708 SybexScreen();
709 //TenScreen();
710 }
711
712 ////--->>>> sound stuff was there
713 //uninitkeys();
714 KB_Shutdown();
715
716 uninitengine();
717 TermSetup();
718
719 //Terminate3DSounds(); // Kill the sounds linked list
720 UnInitSound();
721
722 uninittimer();
723
724 if (CleanExit)
725 DosScreen();
726
727 uninitgroupfile();
728 }
729
730 VOID
LoadLevel(char * filename)731 LoadLevel(char *filename)
732 {
733 int pos;
734
735 if (loadboard(filename, SW_SHAREWARE ? 1 : 0, &Player[0].posx, &Player[0].posy, &Player[0].posz, &Player[0].pang, &Player[0].cursectnum) == -1)
736 {
737 TerminateGame();
738 #ifdef RENDERTYPEWIN
739 {
740 char msg[256];
741 Bsnprintf(msg, 256, "Level not found: %s", filename);
742 wm_msgbox(NULL, msg);
743 }
744 #else
745 printf("Level Not Found: %s\n", filename);
746 #endif
747 exit(0);
748 }
749 }
750
751 VOID
LoadImages(char * filename)752 LoadImages(char *filename)
753 {
754 short ndx;
755 FILE *fin;
756
757 if (loadpics(filename, 32*1048576) == -1)
758 {
759 TerminateGame();
760 #ifdef RENDERTYPEWIN
761 {
762 wm_msgbox(NULL, "Art not found. Please check your GRP file.");
763 }
764 #else
765 printf("Art not found. Please check your GRP file.\n");
766 #endif
767 exit(-1);
768 }
769 }
770
LoadDemoRun(void)771 void LoadDemoRun(void)
772 {
773 short i;
774 FILE *fin;
775
776 fin = fopen("demos.run","r");
777 if (fin)
778 {
779 memset(DemoName,'\0',sizeof(DemoName));
780 for (i = 0; TRUE; i++)
781 {
782 if (fscanf(fin, "%s", DemoName[i]) == EOF)
783 break;
784 }
785
786 fclose(fin);
787 }
788
789 memset(DemoText,'\0',sizeof(DemoText));
790 fin = fopen("demotxt.run","r");
791 if (fin)
792 {
793 fgets(ds, 6, fin);
794 sscanf(ds,"%d",&DemoTextYstart);
795 for (i = 0; TRUE; i++)
796 {
797 if (fgets(DemoText[i], SIZ(DemoText[0])-1, fin) == NULL)
798 break;
799 }
800
801 fclose(fin);
802 }
803 }
804
DisplayDemoText(void)805 void DisplayDemoText(void)
806 {
807 short w,h;
808 short i;
809
810 for (i = 0; i < 3; i++)
811 {
812 MNU_MeasureString(DemoText[i], &w, &h);
813 PutStringTimer(Player, TEXT_TEST_COL(w), DemoTextYstart+(i*12), DemoText[i], 999);
814 }
815 }
816
817
Set_GameMode(void)818 void Set_GameMode(void)
819 {
820 extern int ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP;
821 int result;
822 char ch;
823
824 //DSPRINTF(ds,"ScreenMode %d, ScreenWidth %d, ScreenHeight %d",ScreenMode, ScreenWidth, ScreenHeight);
825 //MONO_PRINT(ds);
826 result = COVERsetgamemode(ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP);
827
828 if (result < 0)
829 {
830 buildprintf("Failure setting video mode %dx%dx%d %s! Attempting safer mode...",
831 ScreenWidth,ScreenHeight,ScreenBPP,ScreenMode?"fullscreen":"windowed");
832 ScreenMode = 0;
833 ScreenWidth = 640;
834 ScreenHeight = 480;
835 ScreenBPP = 8;
836
837 result = COVERsetgamemode(ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP);
838 if (result < 0)
839 {
840 uninitmultiplayers();
841 //uninitkeys();
842 KB_Shutdown();
843 uninitengine();
844 TermSetup();
845 UnInitSound();
846 uninittimer();
847 DosScreen();
848 uninitgroupfile();
849 exit(0);
850 }
851 }
852 }
853
MultiSharewareCheck(void)854 void MultiSharewareCheck(void)
855 {
856 if (!SW_SHAREWARE) return;
857 if (numplayers > 4)
858 {
859 wm_msgbox(NULL,"To play a Network game with more than 4 players you must purchase "
860 "the full version. Read the Ordering Info screens for details.");
861 uninitmultiplayers();
862 //uninitkeys();
863 KB_Shutdown();
864 uninitengine();
865 TermSetup();
866 UnInitSound();
867 uninittimer();
868 uninitgroupfile();
869 exit(0);
870 }
871 }
872
873
874 // Some mem crap for Jim
875 // I reserve 1 meg of heap space for our use out side the cache
876 int TotalMemory = 0;
877 int ActualHeap = 0;
878
InitAutoNet(VOID)879 VOID InitAutoNet(VOID)
880 {
881 if (!AutoNet)
882 return;
883
884 gs.NetGameType = Auto.Rules;
885 gs.NetLevel = Auto.Level;
886 gs.NetMonsters = Auto.Enemy;
887 gs.NetSpawnMarkers = Auto.Markers;
888 gs.NetTeamPlay = Auto.Team;
889 gs.NetHurtTeammate = Auto.HurtTeam;
890 gs.NetKillLimit = Auto.Kill;
891 gs.NetTimeLimit = Auto.Time;
892 gs.NetColor = Auto.Color;
893 gs.NetNuke = Auto.Nuke;
894 }
895
896
AnimateCacheCursor(void)897 void AnimateCacheCursor(void)
898 {
899 #if 0
900 struct rccoord old_pos;
901 static short cursor_num = 0;
902 static char cache_cursor[] = {'|','/','-','\\'};
903
904 if (GraphicsMode)
905 return;
906
907 cursor_num++;
908 if (cursor_num > 3)
909 cursor_num = 0;
910
911 //old_pos = _gettextposition();
912 //_settextposition( old_pos.row, old_pos.col );
913 //_settextposition( 24, 25);
914 _settextposition( 25, 0);
915 sprintf(ds,"Loading sound and graphics %c", cache_cursor[cursor_num]);
916 _outtext(ds);
917 //_settextposition( old_pos.row, old_pos.col );
918 #endif
919 }
920
COVERsetbrightness(int bright,unsigned char * pal)921 void COVERsetbrightness(int bright, unsigned char *pal)
922 {
923 setbrightness(bright, pal, 0);
924 }
925
926
927 static int netsuccess = 0;
928
929 int nextvoxid = 0; // JBF
930 static const char *deffile = "sw.def";
931
932 VOID
InitGame(VOID)933 InitGame(VOID)
934 {
935 extern int MovesPerPacket;
936 //void *ReserveMem=NULL;
937 int i;
938
939 DSPRINTF(ds,"InitGame...");
940 MONO_PRINT(ds);
941
942
943 if (initengine()) {
944 wm_msgbox("Build Engine Initialisation Error",
945 "There was a problem initialising the Build engine: %s", engineerrstr);
946 exit(1);
947 }
948
949 //initgroupfile("sw.grp"); // JBF: moving this close to start of program to detect shareware
950 InitSetup();
951
952 InitAutoNet();
953
954 inittimer(120);
955
956 CON_InitConsole(); // Init console command list
957
958 ////DSPRINTF(ds,"%s, %d",__FILE__,__LINE__); MONO_PRINT(ds);
959
960 //InitFX();
961
962 memcpy(palette_data,palette,768);
963 InitPalette();
964
965 // sets numplayers, connecthead, connectpoint2, myconnectindex
966 if (netsuccess) {
967 buildputs("Waiting for players...\n");
968 while (initmultiplayerscycle()) {
969 handleevents();
970 if (quitevent) {
971 return;
972 }
973 }
974 } else {
975 initsingleplayers();
976 }
977
978 initsynccrc();
979
980 // code to duplicate packets
981 if (numplayers > 4 && MovesPerPacket == 1)
982 {
983 MovesPerPacket = 2;
984 }
985
986 MultiSharewareCheck();
987
988 CommPlayers = numplayers;
989 OrigCommPlayers = CommPlayers;
990 if (numplayers > 1)
991 {
992 CommEnabled = TRUE;
993 if(!BotMode)
994 gNet.MultiGameType = MULTI_GAME_COMMBAT;
995 else
996 gNet.MultiGameType = MULTI_GAME_AI_BOTS;
997 NetBroadcastMode = (networkmode == MMULTI_MODE_P2P);
998 }
999
1000 LoadDemoRun();
1001 // Save off total heap for later calculations
1002 //TotalMemory = Z_AvailHeap();
1003 //DSPRINTF(ds,"Available Heap before LoadImages = %d", TotalMemory);
1004 //MONO_PRINT(ds);
1005 // Reserve 1.5 megs for normal program use
1006 // Generally, SW is consuming about a total of 11 megs including
1007 // all the cached in graphics, etc. per level, so even on a 16 meg
1008 // system, reserving 1.5 megs is fine.
1009 // Note that on a 16 meg machine, Ken was leaving us about
1010 // 24k for use outside the cache! This was causing out of mem problems
1011 // when songs, etc., greater than the remaining heap were being loaded.
1012 // Even if you pre-cache songs, etc. to help, reserving some heap is
1013 // a very smart idea since the game uses malloc throughout execution.
1014 //ReserveMem = AllocMem(1L<<20);
1015 //if(ReserveMem == 0) MONO_PRINT("Could not allocate 1.5 meg reserve!");
1016
1017 // LoadImages will now proceed to steal all the remaining heap space
1018 //_outtext("\n\n\n\n\n\n\n\n");
1019 //AnimateCacheCursor();
1020 buildputs("Loading sound and graphics...\n");
1021 LoadImages("tiles000.art");
1022
1023 // Now free it up for later use
1024 /*
1025 if(ReserveMem)
1026 {
1027 // Recalc TotalMemory for later reference
1028 ActualHeap = Z_AvailHeap() + 1536000L;
1029 FreeMem(ReserveMem);
1030 }
1031 */
1032
1033 Connect();
1034 SortBreakInfo();
1035 //parallaxyoffs = 40;
1036 parallaxyoffs = 0;
1037 parallaxtype = 1;
1038 pskyoff[0] = 0;
1039 pskybits = PlaxBits;
1040 // Default scale value for parallax skies
1041 parallaxyscale = 8192;
1042
1043 memset(Track, 0, sizeof(Track));
1044
1045 memset(Player, 0, sizeof(Player));
1046 for (i = 0; i < MAX_SW_PLAYERS; i++)
1047 INITLIST(&Player[i].PanelSpriteList);
1048
1049 LoadKVXFromScript( "swvoxfil.txt" ); // Load voxels from script file
1050 LoadPLockFromScript( "swplock.txt" ); // Get Parental Lock setup info
1051 if (!SW_SHAREWARE)
1052 LoadCustomInfoFromScript( "swcustom.txt" ); // Load user customisation information
1053
1054 if (!loaddefinitionsfile(deffile)) buildputs("Definitions file loaded.\n");
1055
1056 DemoModeMenuInit = TRUE;
1057 // precache as much stuff as you can
1058 if (UserMapName[0] == '\0')
1059 {
1060 AnimateCacheCursor();
1061 LoadLevel("$dozer.map");
1062 AnimateCacheCursor();
1063 SetupPreCache();
1064 DoTheCache();
1065 }
1066 else
1067 {
1068 AnimateCacheCursor();
1069 LoadLevel(UserMapName);
1070 AnimateCacheCursor();
1071 SetupPreCache();
1072 DoTheCache();
1073 }
1074
1075 Set_GameMode();
1076 GraphicsMode = TRUE;
1077 SetupAspectRatio();
1078
1079 COVERsetbrightness(gs.Brightness,&palette_data[0][0]);
1080
1081 InitFX(); // JBF: do it down here so we get a hold of the window handle
1082 InitMusic();
1083
1084 }
1085
1086
1087 /*
1088 Directory of C:\DEV\SW\MIDI
1089 EXECUT11 MID
1090 HROSHMA6 MID
1091 HOSHIA02 MID
1092 INTRO131 MID
1093 KOTEC2 MID
1094 KOTOKI12 MID
1095 NIPPON34 MID
1096 NOKI41 MID
1097 SANAI MID
1098 SIANRA23 MID
1099 TKYO2007 MID
1100 TYTAIK16 MID
1101 YOKOHA03 MID
1102 */
1103
1104 char LevelSong[16];
1105 short SongLevelNum;
1106 //#ifndef SW_SHAREWARE
1107 LEVEL_INFO LevelInfo[MAX_LEVELS_REG+2] =
1108 {
1109 {"title.map", "theme.mid", " ", " ", " " },
1110 {"$bullet.map", "e1l01.mid", "Seppuku Station", "0 : 55", "5 : 00" },
1111 {"$dozer.map", "e1l03.mid", "Zilla Construction", "4 : 59", "8 : 00" },
1112 {"$shrine.map", "e1l02.mid", "Master Leep's Temple", "3 : 16", "10 : 00" },
1113 {"$woods.map", "e1l04.mid", "Dark Woods of the Serpent", "7 : 06", "16 : 00" },
1114 {"$whirl.map", "yokoha03.mid", "Rising Son", "5 : 30", "10 : 00" },
1115 {"$tank.map", "nippon34.mid", "Killing Fields", "1 : 46", "4 : 00" },
1116 {"$boat.map", "execut11.mid", "Hara-Kiri Harbor", "1 : 56", "4 : 00" },
1117 {"$garden.map", "execut11.mid", "Zilla's Villa", "1 : 06", "2 : 00" },
1118 {"$outpost.map", "sanai.mid", "Monastery", "1 : 23", "3 : 00" },
1119 {"$hidtemp.map", "kotec2.mid", "Raider of the Lost Wang", "2 : 05", "4 : 10" },
1120 {"$plax1.map", "kotec2.mid", "Sumo Sky Palace", "6 : 32", "12 : 00" },
1121 {"$bath.map", "yokoha03.mid", "Bath House", "10 : 00", "10 : 00" },
1122 {"$airport.map", "nippon34.mid", "Unfriendly Skies", "2 : 59", "6 : 00" },
1123 {"$refiner.map", "kotoki12.mid", "Crude Oil", "2 : 40", "5 : 00" },
1124 {"$newmine.map", "hoshia02.mid", "Coolie Mines", "2 : 48", "6 : 00" },
1125 {"$subbase.map", "hoshia02.mid", "Subpen 7", "2 : 02", "4 : 00" },
1126 {"$rock.map", "kotoki12.mid", "The Great Escape", "3 : 18", "6 : 00" },
1127 {"$yamato.map", "sanai.mid", "Floating Fortress", "11 : 38", "20 : 00" },
1128 {"$seabase.map", "kotec2.mid", "Water Torture", "5 : 07", "10 : 00" },
1129 {"$volcano.map", "kotec2.mid", "Stone Rain", "9 : 15", "20 : 00" },
1130 {"$shore.map", "kotec2.mid", "Shanghai Shipwreck", "3 : 58", "8 : 00" },
1131 {"$auto.map", "kotec2.mid", "Auto Maul", "4 : 07", "8 : 00" },
1132 {"tank.map", "kotec2.mid", "Heavy Metal (DM only)", "10 : 00", "10 : 00" },
1133 {"$dmwoods.map", "kotec2.mid", "Ripper Valley (DM only)", "10 : 00", "10 : 00" },
1134 {"$dmshrin.map", "kotec2.mid", "House of Wang (DM only)", "10 : 00", "10 : 00" },
1135 {"$rush.map", "kotec2.mid", "Lo Wang Rally (DM only)", "10 : 00", "10 : 00" },
1136 {"shotgun.map", "kotec2.mid", "Ruins of the Ronin (CTF)", "10 : 00", "10 : 00" },
1137 {"$dmdrop.map", "kotec2.mid", "Killing Fields (CTF)", "10 : 00", "10 : 00" },
1138 {NULL, NULL, NULL, NULL, NULL}
1139 };
1140 /*#else
1141 LEVEL_INFO LevelInfo[MAX_LEVELS+2] = // Shareware
1142 {
1143 {"title.map", "theme.mid", " ", " ", " " },
1144 {"$bullet.map", "e1l01.mid", "Seppuku Station", "0 : 55", "5 : 00" },
1145 {"$dozer.map", "e1l03.mid", "Zilla Construction", "4 : 59", "8 : 00" },
1146 {"$shrine.map", "e1l02.mid", "Master Leep's Temple", "3 : 16", "10 : 00" },
1147 {"$woods.map", "e1l04.mid", "Dark Woods of the Serpent", "7 : 06", "16 : 00" },
1148 {NULL, NULL, NULL, NULL, NULL}
1149 };
1150 #endif*/
1151
1152 char EpisodeNames[2][MAX_EPISODE_NAME_LEN+2] = {
1153 "^Enter the Wang",
1154 "^Code of Honor"
1155 };
1156 char EpisodeSubtitles[2][MAX_EPISODE_SUBTITLE_LEN+1] = {
1157 "Four levels (Shareware Version)",
1158 "Eighteen levels (Full Version Only)"
1159 };
1160 char SkillNames[4][MAX_SKILL_NAME_LEN+2] = {
1161 "^Tiny grasshopper",
1162 "^I Have No Fear",
1163 "^Who Wants Wang",
1164 "^No Pain, No Gain"
1165 };
1166
InitNewGame(VOID)1167 VOID InitNewGame(VOID)
1168 {
1169 int i, ready_bak;
1170 int ver_bak;
1171
1172 //waitforeverybody(); // since ready flag resets after this point, need to carefully sync
1173
1174 for (i = 0; i < MAX_SW_PLAYERS; i++)
1175 {
1176 // don't jack with the playerreadyflag
1177 ready_bak = Player[i].playerreadyflag;
1178 ver_bak = Player[i].PlayerVersion;
1179 memset(&Player[i], 0, sizeof(Player[i]));
1180 Player[i].playerreadyflag = ready_bak;
1181 Player[i].PlayerVersion = ver_bak;
1182 INITLIST(&Player[i].PanelSpriteList);
1183 }
1184
1185 memset(puser, 0, sizeof(puser));
1186 }
1187
FindLevelInfo(char * map_name,short * level)1188 void FindLevelInfo(char *map_name, short *level)
1189 {
1190 char *ptr;
1191 char buff[16];
1192 short i,j;
1193
1194 for (j = 1; j <= MAX_LEVELS; j++)
1195 {
1196 if (LevelInfo[j].LevelName)
1197 {
1198 if (Bstrcasecmp(map_name, LevelInfo[j].LevelName) == 0)
1199 {
1200 *level = j;
1201 return;
1202 }
1203 }
1204 }
1205
1206 *level = 0;
1207 return;
1208 }
1209
1210 int ChopTics;
InitLevelGlobals(VOID)1211 VOID InitLevelGlobals(VOID)
1212 {
1213 extern char PlayerGravity;
1214 extern short wait_active_check_offset;
1215 //extern short Zombies;
1216 extern int PlaxCeilGlobZadjust, PlaxFloorGlobZadjust;
1217 extern BOOL left_foot;
1218 extern BOOL serpwasseen;
1219 extern BOOL sumowasseen;
1220 extern BOOL zillawasseen;
1221 extern short BossSpriteNum[3];
1222
1223 // A few IMPORTANT GLOBAL RESETS
1224 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
1225 MapSetup();
1226 //Zombies = 0;
1227 ChopTics = 0;
1228 dimensionmode = 3;
1229 zoom = 768;
1230 PlayerGravity = 24;
1231 wait_active_check_offset = 0;
1232 PlaxCeilGlobZadjust = PlaxFloorGlobZadjust = Z(500);
1233 pskyoff[0] = 0;
1234 pskybits = PlaxBits;
1235 FinishedLevel = FALSE;
1236 AnimCnt = 0;
1237 left_foot = FALSE;
1238 screenpeek = myconnectindex;
1239
1240 gNet.TimeLimitClock = gNet.TimeLimit;
1241
1242 serpwasseen = FALSE;
1243 sumowasseen = FALSE;
1244 zillawasseen = FALSE;
1245 memset(BossSpriteNum,-1,sizeof(BossSpriteNum));
1246 }
1247
InitLevelGlobals2(VOID)1248 VOID InitLevelGlobals2(VOID)
1249 {
1250 extern short Bunny_Count;
1251 // GLOBAL RESETS NOT DONE for LOAD GAME
1252 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1253 InitTimingVars();
1254 TotalKillable = 0;
1255 Bunny_Count = 0;
1256 }
1257
1258 VOID
InitLevel(VOID)1259 InitLevel(VOID)
1260 {
1261 static int DemoNumber = 0;
1262
1263 MONO_PRINT("InitLevel");
1264 Terminate3DSounds();
1265
1266 // A few IMPORTANT GLOBAL RESETS
1267 InitLevelGlobals();
1268 MONO_PRINT("InitLevelGlobals");
1269 if (!DemoMode)
1270 StopSong();
1271
1272 if (LoadGameOutsideMoveLoop)
1273 {
1274 MONO_PRINT("Returning from InitLevel");
1275 return;
1276 }
1277
1278 InitLevelGlobals2();
1279 MONO_PRINT("InitLevelGlobals2");
1280 if (DemoMode)
1281 {
1282 Level = 0;
1283 NewGame = TRUE;
1284 DemoInitOnce = FALSE;
1285 strcpy(DemoFileName, DemoName[DemoNumber]);
1286 DemoNumber++;
1287 if (!DemoName[DemoNumber][0])
1288 DemoNumber = 0;
1289
1290 // read header and such
1291 DemoPlaySetup();
1292
1293 strcpy(LevelName, DemoLevelName);
1294
1295 FindLevelInfo(LevelName, &Level);
1296 if (Level > 0)
1297 {
1298 strcpy(LevelSong, LevelInfo[Level].SongName);
1299 strcpy(LevelName, LevelInfo[Level].LevelName);
1300 UserMapName[0] = '\0';
1301 }
1302 else
1303 {
1304 strcpy(UserMapName, DemoLevelName);
1305 Level = 0;
1306 }
1307
1308 }
1309 else
1310 {
1311 if (Level < 0)
1312 Level = 0;
1313
1314 if (Level > MAX_LEVELS)
1315 Level = 1;
1316
1317 // extra code in case something is resetting these values
1318 if (NewGame)
1319 {
1320 //Level = 1;
1321 //DemoPlaying = FALSE;
1322 DemoMode = FALSE;
1323 //DemoRecording = FALSE;
1324 //DemoEdit = FALSE;
1325 }
1326
1327 if (UserMapName[0])
1328 {
1329 strcpy(LevelName, UserMapName);
1330
1331 Level = 0;
1332 FindLevelInfo(UserMapName, &Level);
1333
1334 if (Level > 0)
1335 {
1336 // user map is part of game - treat it as such
1337 strcpy(LevelSong, LevelInfo[Level].SongName);
1338 strcpy(LevelName, LevelInfo[Level].LevelName);
1339 UserMapName[0] = '\0';
1340 }
1341 }
1342 else
1343 {
1344 strcpy(LevelName, LevelInfo[Level].LevelName);
1345 strcpy(LevelSong, LevelInfo[Level].SongName);
1346 }
1347 }
1348
1349 PlayingLevel = Level;
1350
1351 if (NewGame)
1352 InitNewGame();
1353
1354 LoadingLevelScreen(LevelName);
1355 MONO_PRINT("LoadintLevelScreen");
1356 if (!DemoMode && !DemoInitOnce)
1357 DemoPlaySetup();
1358
1359 LoadLevel(LevelName);
1360
1361 if (!DemoMode)
1362 {
1363 char windowtitle[256];
1364
1365 if (UserMapName[0])
1366 Bsnprintf(windowtitle, sizeof(windowtitle), "User map: %s - %s", UserMapName, gameeditionname);
1367 else
1368 Bsnprintf(windowtitle, sizeof(windowtitle), "%s - %s", LevelInfo[Level].Description, gameeditionname);
1369
1370 windowtitle[sizeof(windowtitle)-1] = 0;
1371 wm_setwindowtitle(windowtitle);
1372 }
1373
1374 if (Bstrcasecmp(CacheLastLevel, LevelName) != 0)
1375 // clears gotpic and does some bit setting
1376 SetupPreCache();
1377 else
1378 memset(gotpic,0,sizeof(gotpic));
1379
1380 if (sector[0].extra != -1)
1381 {
1382 NormalVisibility = visibility = sector[0].extra;
1383 sector[0].extra = 0;
1384 }
1385 else
1386 NormalVisibility = visibility;
1387
1388 //
1389 // Do Player stuff first
1390 //
1391
1392 InitAllPlayers();
1393
1394 #if DEBUG
1395 // fake Multi-player game setup
1396 if (FakeMultiNumPlayers && !BotMode)
1397 {
1398 BYTE i;
1399
1400 // insert all needed players except the first one - its already tere
1401 for (i = 0; i < FakeMultiNumPlayers - 1; i++)
1402 {
1403 ManualPlayerInsert(Player);
1404 // reset control back to 1st player
1405 myconnectindex = 0;
1406 screenpeek = 0;
1407 }
1408 }
1409 #endif
1410
1411 // Put in the BOTS if called for
1412 if (FakeMultiNumPlayers && BotMode)
1413 {
1414 BYTE i;
1415
1416 // insert all needed players except the first one - its already tere
1417 for (i = 0; i < FakeMultiNumPlayers; i++)
1418 {
1419 BotPlayerInsert(Player);
1420 // reset control back to 1st player
1421 myconnectindex = 0;
1422 screenpeek = 0;
1423 }
1424 }
1425
1426 QueueReset();
1427 PreMapCombineFloors();
1428 InitMultiPlayerInfo();
1429 InitAllPlayerSprites();
1430
1431 //
1432 // Do setup for sprite, track, panel, sector, etc
1433 //
1434
1435 // Set levels up
1436 InitTimingVars();
1437
1438 SpriteSetup();
1439 SpriteSetupPost(); // post processing - already gone once through the loop
1440 InitLighting();
1441
1442 TrackSetup();
1443
1444 PlayerPanelSetup();
1445 MapSetup();
1446 SectorSetup();
1447 JS_InitMirrors();
1448 JS_InitLockouts(); // Setup the lockout linked lists
1449 JS_ToggleLockouts(); // Init lockouts on/off
1450
1451 PlaceSectorObjectsOnTracks();
1452 PlaceActorsOnTracks();
1453 PostSetupSectorObject();
1454 SetupMirrorTiles();
1455 initlava();
1456
1457 SongLevelNum = Level;
1458
1459 if (DemoMode)
1460 {
1461 DisplayDemoText();
1462 }
1463
1464
1465 if (ArgCheat)
1466 {
1467 BOOL bak = gs.Messages;
1468 gs.Messages = FALSE;
1469 EveryCheatToggle(&Player[0],NULL);
1470 gs.Messages = bak;
1471 GodMode = TRUE;
1472 }
1473
1474 // reset NewGame
1475 NewGame = FALSE;
1476
1477 DSPRINTF(ds,"End of InitLevel...");
1478 MONO_PRINT(ds);
1479
1480 #if 0
1481 #if DEBUG
1482 if (!cansee(43594, -92986, 0x3fffffff, 290,
1483 43180, -91707, 0x3fffffff, 290))
1484 {
1485 DSPRINTF(ds,"cansee failed");
1486 MONO_PRINT(ds);
1487 }
1488 #endif
1489 #endif
1490
1491 }
1492
1493
1494 VOID
TerminateLevel(VOID)1495 TerminateLevel(VOID)
1496 {
1497 VOID pClearSpriteList(PLAYERp pp);
1498 int i, nexti, stat, pnum, ndx;
1499 SECT_USERp *sectu;
1500
1501 //HEAP_CHECK();
1502
1503 DemoTerm();
1504
1505 // Free any track points
1506 for (ndx = 0; ndx < MAX_TRACKS; ndx++)
1507 {
1508 if (Track[ndx].TrackPoint)
1509 {
1510 FreeMem(Track[ndx].TrackPoint);
1511 // !JIM! I added null assigner
1512 Track[ndx].TrackPoint = NULL;
1513 }
1514 }
1515
1516 // Clear the tracks
1517 memset(Track, 0, sizeof(Track));
1518
1519 StopSound();
1520 Terminate3DSounds(); // Kill the 3d sounds linked list
1521 //ClearSoundLocks();
1522
1523 // Clear all anims and any memory associated with them
1524 // Clear before killing sprites - save a little time
1525 //AnimClear();
1526
1527 for (stat = STAT_PLAYER0; stat < STAT_PLAYER0 + CommPlayers; stat++)
1528 {
1529
1530 pnum = stat - STAT_PLAYER0;
1531
1532 TRAVERSE_SPRITE_STAT(headspritestat[stat], i, nexti)
1533 {
1534 if (User[i])
1535 memcpy(&puser[pnum], User[i], sizeof(USER));
1536 }
1537 }
1538
1539 // Kill User memory and delete sprites
1540 // for (stat = 0; stat < STAT_ALL; stat++)
1541 for (stat = 0; stat < MAXSTATUS; stat++)
1542 {
1543 TRAVERSE_SPRITE_STAT(headspritestat[stat], i, nexti)
1544 {
1545 KillSprite(i);
1546 }
1547 }
1548
1549 // Free SectUser memory
1550 for (sectu = &SectUser[0];
1551 sectu < &SectUser[MAXSECTORS];
1552 sectu++)
1553 {
1554 if (*sectu)
1555 {
1556 ////DSPRINTF(ds,"Sect User Free %d",sectu-SectUser);
1557 //MONO_PRINT(ds);
1558 FreeMem(*sectu);
1559 *sectu = NULL;
1560 }
1561 }
1562
1563 //memset(&User[0], 0, sizeof(User));
1564 memset(&SectUser[0], 0, sizeof(SectUser));
1565
1566 TRAVERSE_CONNECT(pnum)
1567 {
1568 PLAYERp pp = Player + pnum;
1569
1570 // Free panel sprites for players
1571 pClearSpriteList(pp);
1572
1573 pp->DoPlayerAction = NULL;
1574
1575 pp->SpriteP = NULL;
1576 pp->PlayerSprite = -1;
1577
1578 pp->UnderSpriteP = NULL;
1579 pp->PlayerUnderSprite = -1;
1580
1581 memset(pp->HasKey, 0, sizeof(pp->HasKey));
1582
1583 //pp->WpnFlags = 0;
1584 pp->CurWpn = NULL;
1585
1586 memset(pp->Wpn, 0, sizeof(pp->Wpn));
1587 memset(pp->InventorySprite, 0, sizeof(pp->InventorySprite));
1588 memset(pp->InventoryTics, 0, sizeof(pp->InventoryTics));
1589
1590 pp->Killer = -1;
1591
1592 INITLIST(&pp->PanelSpriteList);
1593 }
1594
1595 JS_UnInitLockouts();
1596
1597 //HEAP_CHECK();
1598 }
1599
1600 VOID
NewLevel(VOID)1601 NewLevel(VOID)
1602 {
1603
1604 DSPRINTF(ds,"NewLevel");
1605 MONO_PRINT(ds);
1606
1607 if (DemoPlaying)
1608 {
1609 FX_SetVolume(0); // Shut the hell up while game is loading!
1610 InitLevel();
1611 InitRunLevel();
1612
1613 DemoInitOnce = FALSE;
1614 if (DemoMode)
1615 {
1616 if (DemoModeMenuInit)
1617 {
1618 DemoModeMenuInit = FALSE;
1619 ForceMenus = TRUE;
1620 }
1621 }
1622
1623 DemoPlayBack();
1624
1625 if (DemoRecording && DemoEdit)
1626 {
1627 RunLevel();
1628 }
1629 }
1630 else
1631 {
1632 DSPRINTF(ds,"Calling FX_SetVolume");
1633 MONO_PRINT(ds);
1634 FX_SetVolume(0); // Shut the hell up while game is loading!
1635
1636 DSPRINTF(ds,"Calling InitLevel");
1637 MONO_PRINT(ds);
1638 InitLevel();
1639
1640 DSPRINTF(ds,"Calling RunLevel");
1641 MONO_PRINT(ds);
1642 RunLevel();
1643
1644 if (!QuitFlag)
1645 {
1646 // for good measure do this
1647 ready2send = 0;
1648 waitforeverybody();
1649 }
1650
1651 StatScreen(&Player[myconnectindex]);
1652 }
1653
1654 if (LoadGameFromDemo)
1655 LoadGameFromDemo = FALSE;
1656 else
1657 TerminateLevel();
1658
1659 InGame = FALSE;
1660
1661 if (SW_SHAREWARE)
1662 {
1663 if (FinishAnim)
1664 MenuLevel();
1665 }
1666 else
1667 {
1668 if (FinishAnim == ANIM_ZILLA || FinishAnim == ANIM_SERP)
1669 MenuLevel();
1670 }
1671 FinishAnim = 0;
1672 }
1673
1674 VOID
ResetKeys(VOID)1675 ResetKeys(VOID)
1676 {
1677 int i;
1678
1679 for (i = 0; i < MAXKEYBOARDSCAN; i++)
1680 {
1681 KEY_PRESSED(i) = 0;
1682 }
1683 }
1684
1685 BOOL
KeyPressed(VOID)1686 KeyPressed(VOID)
1687 {
1688 int i;
1689
1690 for (i = 0; i < MAXKEYBOARDSCAN; i++)
1691 {
1692 if (KEY_PRESSED(i))
1693 return (TRUE);
1694 }
1695
1696 return (FALSE);
1697 }
1698
1699 BYTEp
KeyPressedRange(BYTEp kb,BYTEp ke)1700 KeyPressedRange(BYTEp kb, BYTEp ke)
1701 {
1702 BYTEp k;
1703
1704 for (k = kb; k <= ke; k++)
1705 {
1706 if (*k)
1707 return (k);
1708 }
1709
1710 return (NULL);
1711 }
1712
1713 VOID
ResetKeyRange(BYTEp kb,BYTEp ke)1714 ResetKeyRange(BYTEp kb, BYTEp ke)
1715 {
1716 BYTEp k;
1717
1718 for (k = kb; k <= ke; k++)
1719 {
1720 *k = 0;
1721 }
1722 }
1723
1724
1725 VOID
LogoLevel(VOID)1726 LogoLevel(VOID)
1727 {
1728 char called;
1729 int fin;
1730 unsigned char pal[PAL_SIZE];
1731 UserInput uinfo = { FALSE, FALSE, dir_None };
1732 int i;
1733
1734
1735 DSPRINTF(ds,"LogoLevel...");
1736 MONO_PRINT(ds);
1737
1738 // start music at logo
1739 PlaySong(LevelInfo[0].SongName, RedBookSong[0], TRUE, TRUE);
1740
1741 DSPRINTF(ds,"After music stuff...");
1742 MONO_PRINT(ds);
1743
1744 // PreCache Anim
1745 LoadAnm(0);
1746
1747 if ((fin = kopen4load("3drealms.pal", 0)) != -1)
1748 {
1749 kread(fin, pal, PAL_SIZE);
1750 kclose(fin);
1751 setbrightness(gs.Brightness, pal, 2);
1752 }
1753 DSPRINTF(ds,"Just read in 3drealms.pal...");
1754 MONO_PRINT(ds);
1755
1756 //FadeOut(0, 0);
1757 ready2send = 0;
1758 totalclock = 0;
1759 ototalclock = 0;
1760
1761 DSPRINTF(ds,"About to display 3drealms pic...");
1762 MONO_PRINT(ds);
1763
1764 //FadeIn(0, 3);
1765
1766 ResetKeys();
1767 while (TRUE)
1768 {
1769 clearallviews(0);
1770 rotatesprite(0, 0, RS_SCALE, 0, THREED_REALMS_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
1771 nextpage();
1772
1773 handleevents();
1774 flushpackets();
1775
1776 CONTROL_GetUserInput(&uinfo);
1777 CONTROL_ClearUserInput(&uinfo);
1778 if (quitevent) break;
1779
1780 // taken from top of faketimerhandler
1781 // limits checks to max of 40 times a second
1782 if (totalclock >= ototalclock + synctics)
1783 {
1784 ototalclock += synctics;
1785 }
1786
1787 if (totalclock > 5*120 || KeyPressed() || uinfo.button0 || uinfo.button1)
1788 {
1789 break;
1790 }
1791 }
1792
1793 clearallviews(0);
1794 nextpage();
1795 setbrightness(gs.Brightness, &palette_data[0][0], 2);
1796
1797 // put up a blank screen while loading
1798
1799 DSPRINTF(ds,"End of LogoLevel...");
1800 MONO_PRINT(ds);
1801
1802 }
1803
1804 VOID
CreditsLevel(VOID)1805 CreditsLevel(VOID)
1806 {
1807 char called;
1808 int fin;
1809 int i;
1810 int curpic;
1811 int handle;
1812 ULONG timer = 0;
1813 int zero=0;
1814 short save;
1815 #define CREDITS1_PIC 5111
1816 #define CREDITS2_PIC 5118
1817
1818 // put up a blank screen while loading
1819
1820 // get rid of all PERM sprites!
1821 flushperms();
1822 save = gs.BorderNum;
1823 SetBorder(Player + myconnectindex,0);
1824 ClearStartMost();
1825 gs.BorderNum = save;
1826 clearallviews(0);
1827 nextpage();
1828
1829 // Lo Wang feel like singing!
1830 handle = PlaySound(DIGI_JG95012,&zero,&zero,&zero,v3df_none);
1831
1832 if (handle > 0)
1833 while(FX_SoundActive(handle))
1834 handleevents();
1835
1836 // try 14 then 2 then quit
1837 if (!PlaySong(NULL, 14, FALSE, TRUE))
1838 {
1839 if (!PlaySong(NULL, 2, FALSE, TRUE))
1840 {
1841 handle = PlaySound(DIGI_NOLIKEMUSIC,&zero,&zero,&zero,v3df_none);
1842 if (handle > 0)
1843 while(FX_SoundActive(handle))
1844 handleevents();
1845 return;
1846 }
1847 }
1848
1849 ready2send = 0;
1850 totalclock = 0;
1851 ototalclock = 0;
1852
1853 ResetKeys();
1854 curpic = CREDITS1_PIC;
1855
1856 while (TRUE)
1857 {
1858 handleevents();
1859 flushpackets();
1860
1861 // taken from top of faketimerhandler
1862 // limits checks to max of 40 times a second
1863 if (totalclock >= ototalclock + synctics)
1864 {
1865 ototalclock += synctics;
1866 timer += synctics;
1867 }
1868
1869 rotatesprite(0, 0, RS_SCALE, 0, curpic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
1870
1871 nextpage();
1872
1873 if (timer > 8*120)
1874 {
1875 curpic = CREDITS2_PIC;
1876 }
1877
1878 if (timer > 16*120)
1879 {
1880 timer = 0;
1881 curpic = CREDITS1_PIC;
1882 }
1883
1884
1885 if (!SongIsPlaying())
1886 break;
1887
1888 if (KEY_PRESSED(KEYSC_ESC))
1889 break;
1890 }
1891
1892 // put up a blank screen while loading
1893 clearallviews(0);
1894 nextpage();
1895 ResetKeys();
1896 StopSong();
1897 }
1898
1899
1900 VOID
SybexScreen(VOID)1901 SybexScreen(VOID)
1902 {
1903 UserInput uinfo;
1904
1905 if (!SW_SHAREWARE) return;
1906
1907 if (CommEnabled)
1908 return;
1909
1910 rotatesprite(0, 0, RS_SCALE, 0, 5261, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
1911 nextpage();
1912
1913 CONTROL_GetUserInput(&uinfo);
1914 CONTROL_ClearUserInput(&uinfo);
1915 ResetKeys();
1916 while (TRUE)
1917 {
1918 handleevents();
1919 CONTROL_GetUserInput(&uinfo);
1920 CONTROL_ClearUserInput(&uinfo);
1921 if (KeyPressed() || quitevent || uinfo.button0 || uinfo.button1)
1922 break;
1923 }
1924 }
1925
1926 // CTW REMOVED
1927 /*
1928 VOID
1929 TenScreen(VOID)
1930 {
1931 char called;
1932 int fin;
1933 char backup_pal[256*3];
1934 char pal[PAL_SIZE];
1935 char tempbuf[256];
1936 char *palook_bak = palookup[0];
1937 int i;
1938 ULONG bak;
1939 int bakready2send;
1940
1941 if (CommEnabled)
1942 return;
1943
1944 bak = totalclock;
1945
1946 flushperms();
1947 clearallviews(0);
1948 nextpage();
1949
1950 for (i = 0; i < 256; i++)
1951 tempbuf[i] = i;
1952 palookup[0] = tempbuf;
1953
1954 GetPaletteFromVESA(pal);
1955 memcpy(backup_pal, pal, PAL_SIZE);
1956
1957 if ((fin = kopen4load("ten.pal", 0)) != -1)
1958 {
1959 kread(fin, pal, PAL_SIZE);
1960 kclose(fin);
1961 }
1962
1963 // palette to black
1964 FadeOut(0, 0);
1965 bakready2send = ready2send;
1966 //totalclock = 0;
1967 //ototalclock = 0;
1968
1969 flushperms();
1970 // draw it
1971 rotatesprite(0, 0, RS_SCALE, 0, TEN_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
1972 // bring to the front - still back palette
1973 nextpage();
1974 // set pal
1975 SetPaletteToVESA(pal);
1976 //FadeIn(0, 3);
1977 ResetKeys();
1978
1979 while (!KeyPressed());
1980
1981 palookup[0] = palook_bak;
1982
1983 clearallviews(0);
1984 nextpage();
1985 SetPaletteToVESA(backup_pal);
1986
1987 // put up a blank screen while loading
1988 clearallviews(0);
1989 nextpage();
1990
1991 ready2send = bakready2send;
1992 totalclock = bak;
1993 }
1994 */
1995 // CTW REMOVED END
1996
1997 VOID
TitleLevel(VOID)1998 TitleLevel(VOID)
1999 {
2000 char called;
2001 int fin;
2002 unsigned char backup_pal[256*3];
2003 unsigned char pal[PAL_SIZE];
2004 unsigned char tempbuf[256];
2005 unsigned char *palook_bak = palookup[0];
2006 int i;
2007
2008 for (i = 0; i < 256; i++)
2009 tempbuf[i] = i;
2010 palookup[0] = tempbuf;
2011
2012 //GetPaletteFromVESA(pal);
2013 //memcpy(backup_pal, pal, PAL_SIZE);
2014
2015 clearallviews(0);
2016 nextpage();
2017
2018 // if ((fin = kopen4load("title.pal", 0)) != -1)
2019 // {
2020 // kread(fin, pal, PAL_SIZE);
2021 // kclose(fin);
2022 // SetPaletteToVESA(pal);
2023 // }
2024
2025 // clearallviews(0);
2026 // nextpage();
2027
2028 //FadeOut(0, 0);
2029 ready2send = 0;
2030 totalclock = 0;
2031 ototalclock = 0;
2032
2033 rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2034 nextpage();
2035 //FadeIn(0, 3);
2036
2037 ResetKeys();
2038 while (TRUE)
2039 {
2040 handleevents();
2041 flushpackets();
2042 OSD_DispatchQueued();
2043
2044 // taken from top of faketimerhandler
2045 // limits checks to max of 40 times a second
2046 if (totalclock >= ototalclock + synctics)
2047 {
2048 //void MNU_CheckForMenusAnyKey( void );
2049
2050 ototalclock += synctics;
2051 //MNU_CheckForMenusAnyKey();
2052 }
2053
2054 //if (UsingMenus)
2055 // MNU_DrawMenu();
2056
2057 //drawscreen as fast as you can
2058 rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2059
2060 nextpage();
2061
2062 if (totalclock > 5*120 || KeyPressed())
2063 {
2064 DemoMode = TRUE;
2065 DemoPlaying = TRUE;
2066 break;
2067 }
2068 }
2069
2070 palookup[0] = palook_bak;
2071
2072 // clearallviews(0);
2073 // nextpage();
2074 //SetPaletteToVESA(backup_pal);
2075
2076 // put up a blank screen while loading
2077 // clearallviews(0);
2078 // nextpage();
2079 }
2080
2081
DrawMenuLevelScreen(VOID)2082 VOID DrawMenuLevelScreen(VOID)
2083 {
2084 flushperms();
2085 clearallviews(0);
2086 rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 20, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2087 }
2088
DrawStatScreen(VOID)2089 VOID DrawStatScreen(VOID)
2090 {
2091 flushperms();
2092 clearallviews(0);
2093 rotatesprite(0, 0, RS_SCALE, 0, STAT_SCREEN_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2094 }
2095
DrawLoadLevelScreen(VOID)2096 VOID DrawLoadLevelScreen(VOID)
2097 {
2098 flushperms();
2099 clearallviews(0);
2100 rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 20, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2101 }
2102
2103 short PlayerQuitMenuLevel = -1;
2104
2105 VOID
IntroAnimLevel(VOID)2106 IntroAnimLevel(VOID)
2107 {
2108 DSPRINTF(ds,"IntroAnimLevel");
2109 MONO_PRINT(ds);
2110 playanm(0);
2111 }
2112
2113 VOID
MenuLevel(VOID)2114 MenuLevel(VOID)
2115 {
2116 BOOL MNU_StartNetGame(void);
2117 char called;
2118 int fin;
2119 extern int totalclocklock;
2120 short w,h;
2121
2122 DSPRINTF(ds,"MenuLevel...");
2123 MONO_PRINT(ds);
2124
2125 wm_setwindowtitle(gameeditionname);
2126
2127 if (gs.MusicOn)
2128 {
2129 PlaySong(LevelInfo[0].SongName, RedBookSong[0], TRUE, FALSE);
2130 }
2131
2132 if (AutoNet)
2133 {
2134 DrawMenuLevelScreen();
2135
2136 if (CommEnabled)
2137 {
2138 sprintf(ds,"Lo Wang is waiting for other players...");
2139 MNU_MeasureString(ds, &w, &h);
2140 MNU_DrawString(TEXT_TEST_COL(w), 170, ds, 1, 16);
2141
2142 sprintf(ds,"They are afraid!");
2143 MNU_MeasureString(ds, &w, &h);
2144 MNU_DrawString(TEXT_TEST_COL(w), 180, ds, 1, 16);
2145 }
2146
2147 nextpage();
2148
2149 waitforeverybody();
2150 FirstTimeIntoGame = TRUE;
2151 MNU_StartNetGame();
2152 FirstTimeIntoGame = FALSE;
2153 waitforeverybody();
2154 ExitLevel = FALSE;
2155 FinishedLevel = FALSE;
2156 BorderAdjust = TRUE;
2157 UsingMenus = FALSE;
2158 InMenuLevel = FALSE;
2159 return;
2160 }
2161
2162 // do demos only if not playing multi play
2163 if (!CommEnabled && CommPlayers <= 1 && !FinishAnim && !NoDemoStartup)
2164 {
2165 // demos exist - do demo instead
2166 if (DemoName[0][0] != '\0')
2167 {
2168 DemoMode = TRUE;
2169 DemoPlaying = TRUE;
2170 return;
2171 }
2172 }
2173
2174 DemoMode = FALSE;
2175 DemoPlaying = FALSE;
2176
2177 clearallviews(0);
2178 nextpage();
2179
2180 //FadeOut(0, 0);
2181 ready2send = 0;
2182 totalclock = 0;
2183 ototalclock = 0;
2184 ExitLevel = FALSE;
2185 InMenuLevel = TRUE;
2186
2187 DrawMenuLevelScreen();
2188
2189 if (CommEnabled)
2190 {
2191 sprintf(ds,"Lo Wang is waiting for other players...");
2192 MNU_MeasureString(ds, &w, &h);
2193 MNU_DrawString(TEXT_TEST_COL(w), 170, ds, 1, 16);
2194
2195 sprintf(ds,"They are afraid!");
2196 MNU_MeasureString(ds, &w, &h);
2197 MNU_DrawString(TEXT_TEST_COL(w), 180, ds, 1, 16);
2198 }
2199
2200 nextpage();
2201 //FadeIn(0, 3);
2202
2203 waitforeverybody();
2204
2205 // don't allow BorderAdjusting in these menus
2206 BorderAdjust = FALSE;
2207
2208 ResetKeys();
2209
2210 if (SW_SHAREWARE)
2211 {
2212 // go to ordering menu only if shareware
2213 if (FinishAnim)
2214 {
2215 ForceMenus = TRUE;
2216 ControlPanelType = ct_ordermenu;
2217 FinishAnim = 0;
2218 }
2219 }
2220 else
2221 {
2222 FinishAnim = 0;
2223 }
2224
2225 while (TRUE)
2226 {
2227 handleevents();
2228 OSD_DispatchQueued();
2229
2230 if (quitevent)
2231 {
2232 if (CommPlayers >= 2)
2233 MultiPlayQuitFlag = TRUE;
2234 else
2235 QuitFlag = TRUE;
2236 }
2237
2238 // taken from top of faketimerhandler
2239 // limits checks to max of 40 times a second
2240 if (totalclock >= ototalclock + synctics)
2241 {
2242 ototalclock += synctics;
2243 MNU_CheckForMenusAnyKey();
2244 if (CommEnabled)
2245 getpackets();
2246 }
2247
2248 if (CommEnabled)
2249 {
2250 if (MultiPlayQuitFlag)
2251 {
2252 short pnum;
2253 BYTE pbuf[1];
2254 QuitFlag = TRUE;
2255 pbuf[0] = PACKET_TYPE_MENU_LEVEL_QUIT;
2256 netbroadcastpacket(pbuf, 1); // TENSW
2257 break;
2258 }
2259
2260 if (PlayerQuitMenuLevel >= 0)
2261 {
2262 MenuCommPlayerQuit(PlayerQuitMenuLevel);
2263 PlayerQuitMenuLevel = -1;
2264 }
2265 }
2266
2267 if (ExitLevel)
2268 {
2269 // Quiting Level
2270 ExitLevel = FALSE;
2271 break;
2272 }
2273
2274 if (QuitFlag)
2275 {
2276 // Quiting Game
2277 break;
2278 }
2279
2280 // force the use of menus at all time
2281 if (!UsingMenus && !ConPanel)
2282 {
2283 ForceMenus = TRUE;
2284 MNU_CheckForMenusAnyKey();
2285 }
2286
2287 // must lock the clock for drawing so animations will happen
2288 totalclocklock = totalclock;
2289
2290 //drawscreen as fast as you can
2291 DrawMenuLevelScreen();
2292
2293 if (UsingMenus)
2294 MNU_DrawMenu();
2295
2296 nextpage();
2297 }
2298
2299 BorderAdjust = TRUE;
2300 //LoadGameOutsideMoveLoop = FALSE;
2301 KEY_PRESSED(KEYSC_ESC) = FALSE;
2302 KB_ClearKeysDown();
2303 //ExitMenus();
2304 UsingMenus = FALSE;
2305 InMenuLevel = FALSE;
2306 clearallviews(0);
2307 nextpage();
2308 }
2309
2310 VOID
SceneLevel(VOID)2311 SceneLevel(VOID)
2312 {
2313 BOOL dp_bak;
2314 BOOL dm_bak;
2315 FILE *fin;
2316 #define CINEMATIC_DEMO_FILE "$scene.dmo"
2317
2318 // make sure it exists
2319 if ((fin = fopen(CINEMATIC_DEMO_FILE,"rb")) == NULL)
2320 return;
2321 else
2322 fclose(fin);
2323
2324 strcpy(DemoFileName,CINEMATIC_DEMO_FILE);
2325
2326 dp_bak = DemoPlaying;
2327 dm_bak = DemoMode;
2328
2329 DemoMode = TRUE;
2330 DemoPlaying = TRUE;
2331 DemoOverride = TRUE;
2332 InitLevel();
2333 DemoOverride = FALSE;
2334
2335 ScenePlayBack();
2336 TerminateLevel();
2337 DemoMode = dm_bak;
2338 DemoPlaying = dp_bak;
2339 }
2340
2341 VOID
LoadingLevelScreen(char * level_name)2342 LoadingLevelScreen(char *level_name)
2343 {
2344 short w,h;
2345 extern BOOL DemoMode;
2346 extern char *MNU_LevelName[28];
2347 DrawLoadLevelScreen();
2348
2349 if (DemoMode)
2350 sprintf(ds,"DEMO");
2351 else
2352 sprintf(ds,"ENTERING");
2353
2354 MNU_MeasureString(ds, &w, &h);
2355 MNU_DrawString(TEXT_TEST_COL(w), 170, ds,1,16);
2356
2357 if (UserMapName[0])
2358 sprintf(ds,"%s",UserMapName);
2359 else
2360 sprintf(ds,"%s",LevelInfo[Level].Description);
2361
2362 MNU_MeasureString(ds, &w, &h);
2363 MNU_DrawString(TEXT_TEST_COL(w), 180, ds,1,16);
2364
2365 nextpage();
2366 }
2367
2368 VOID
gNextState(STATEp * State)2369 gNextState(STATEp *State)
2370 {
2371 // Transition to the next state
2372 *State = (*State)->NextState;
2373
2374 if (TEST((*State)->Tics, SF_QUICK_CALL))
2375 {
2376 (*(*State)->Animator)(0);
2377 *State = (*State)->NextState;
2378 }
2379 }
2380
2381 // Generic state control
2382 VOID
gStateControl(STATEp * State,int * tics)2383 gStateControl(STATEp *State, int *tics)
2384 {
2385 *tics += synctics;
2386
2387 // Skip states if too much time has passed
2388 while (*tics >= (*State)->Tics)
2389 {
2390 // Set Tics
2391 *tics -= (*State)->Tics;
2392 gNextState(State);
2393 }
2394
2395 // Call the correct animator
2396 if ((*State)->Animator)
2397 (*(*State)->Animator)(0);
2398 }
2399
BonusPunchSound(short SpriteNum)2400 int BonusPunchSound(short SpriteNum)
2401 {
2402 PLAYERp pp = Player + myconnectindex;
2403 PlaySound(DIGI_PLAYERYELL3, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2404 return(0);
2405 }
2406
BonusKickSound(short SpriteNum)2407 int BonusKickSound(short SpriteNum)
2408 {
2409 PLAYERp pp = Player + myconnectindex;
2410 PlaySound(DIGI_PLAYERYELL2, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2411 return(0);
2412 }
2413
BonusGrabSound(short SpriteNum)2414 int BonusGrabSound(short SpriteNum)
2415 {
2416 PLAYERp pp = Player + myconnectindex;
2417 PlaySound(DIGI_BONUS_GRAB, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2418 return(0);
2419 }
2420
2421 VOID
BonusScreen(PLAYERp pp)2422 BonusScreen(PLAYERp pp)
2423 {
2424 int minutes,seconds,second_tics;
2425 extern BOOL FinishedLevel;
2426 extern int PlayClock;
2427 extern short LevelSecrets;
2428 extern short TotalKillable;
2429 short w,h;
2430 short pic,limit;
2431 int zero=0;
2432 int handle = 0;
2433 short LI_Num;
2434
2435
2436 #define BONUS_SCREEN_PIC 5120
2437 #define BONUS_ANIM 5121
2438 #define BONUS_ANIM_FRAMES (5159-5121)
2439
2440 #define BREAK_LIGHT_RATE 18
2441
2442 #define BONUS_PUNCH 5121
2443 #define BONUS_KICK 5136
2444 #define BONUS_GRAB 5151
2445 #define BONUS_REST 5121
2446
2447 #define BONUS_TICS 8
2448 #define BONUS_GRAB_TICS 20
2449 #define BONUS_REST_TICS 50
2450
2451 static STATE s_BonusPunch[] =
2452 {
2453 {BONUS_PUNCH + 0, BONUS_TICS, NULL, &s_BonusPunch[1]},
2454 {BONUS_PUNCH + 1, BONUS_TICS, NULL, &s_BonusPunch[2]},
2455 {BONUS_PUNCH + 2, BONUS_TICS, NULL, &s_BonusPunch[3]},
2456 {BONUS_PUNCH + 2, 0|SF_QUICK_CALL, BonusPunchSound, &s_BonusPunch[4]},
2457 {BONUS_PUNCH + 3, BONUS_TICS, NULL, &s_BonusPunch[5]},
2458 {BONUS_PUNCH + 4, BONUS_TICS, NULL, &s_BonusPunch[6]},
2459 {BONUS_PUNCH + 5, BONUS_TICS, NULL, &s_BonusPunch[7]},
2460 {BONUS_PUNCH + 6, BONUS_TICS, NULL, &s_BonusPunch[8]},
2461 {BONUS_PUNCH + 7, BONUS_TICS, NULL, &s_BonusPunch[9]},
2462 {BONUS_PUNCH + 8, BONUS_TICS, NULL, &s_BonusPunch[10]},
2463 {BONUS_PUNCH + 9, BONUS_TICS, NULL, &s_BonusPunch[11]},
2464 {BONUS_PUNCH + 10, BONUS_TICS, NULL, &s_BonusPunch[12]},
2465 {BONUS_PUNCH + 11, BONUS_TICS, NULL, &s_BonusPunch[13]},
2466 {BONUS_PUNCH + 12, BONUS_TICS, NULL, &s_BonusPunch[14]},
2467 {BONUS_PUNCH + 14, 90, NULL, &s_BonusPunch[15]},
2468 {BONUS_PUNCH + 14, BONUS_TICS, NULL, &s_BonusPunch[15]},
2469 };
2470
2471 static STATE s_BonusKick[] =
2472 {
2473 {BONUS_KICK + 0, BONUS_TICS, NULL, &s_BonusKick[1]},
2474 {BONUS_KICK + 1, BONUS_TICS, NULL, &s_BonusKick[2]},
2475 {BONUS_KICK + 2, BONUS_TICS, NULL, &s_BonusKick[3]},
2476 {BONUS_KICK + 2, 0|SF_QUICK_CALL, BonusKickSound, &s_BonusKick[4]},
2477 {BONUS_KICK + 3, BONUS_TICS, NULL, &s_BonusKick[5]},
2478 {BONUS_KICK + 4, BONUS_TICS, NULL, &s_BonusKick[6]},
2479 {BONUS_KICK + 5, BONUS_TICS, NULL, &s_BonusKick[7]},
2480 {BONUS_KICK + 6, BONUS_TICS, NULL, &s_BonusKick[8]},
2481 {BONUS_KICK + 7, BONUS_TICS, NULL, &s_BonusKick[9]},
2482 {BONUS_KICK + 8, BONUS_TICS, NULL, &s_BonusKick[10]},
2483 {BONUS_KICK + 9, BONUS_TICS, NULL, &s_BonusKick[11]},
2484 {BONUS_KICK + 10, BONUS_TICS, NULL, &s_BonusKick[12]},
2485 {BONUS_KICK + 11, BONUS_TICS, NULL, &s_BonusKick[13]},
2486 {BONUS_KICK + 12, BONUS_TICS, NULL, &s_BonusKick[14]},
2487 {BONUS_KICK + 14, 90, NULL, &s_BonusKick[15]},
2488 {BONUS_KICK + 14, BONUS_TICS, NULL, &s_BonusKick[15]},
2489 };
2490
2491 static STATE s_BonusGrab[] =
2492 {
2493 {BONUS_GRAB + 0, BONUS_GRAB_TICS, NULL, &s_BonusGrab[1]},
2494 {BONUS_GRAB + 1, BONUS_GRAB_TICS, NULL, &s_BonusGrab[2]},
2495 {BONUS_GRAB + 2, BONUS_GRAB_TICS, NULL, &s_BonusGrab[3]},
2496 {BONUS_GRAB + 2, 0|SF_QUICK_CALL, BonusGrabSound, &s_BonusGrab[4]},
2497 {BONUS_GRAB + 3, BONUS_GRAB_TICS, NULL, &s_BonusGrab[5]},
2498 {BONUS_GRAB + 4, BONUS_GRAB_TICS, NULL, &s_BonusGrab[6]},
2499 {BONUS_GRAB + 5, BONUS_GRAB_TICS, NULL, &s_BonusGrab[7]},
2500 {BONUS_GRAB + 6, BONUS_GRAB_TICS, NULL, &s_BonusGrab[8]},
2501 {BONUS_GRAB + 7, BONUS_GRAB_TICS, NULL, &s_BonusGrab[9]},
2502 {BONUS_GRAB + 8, BONUS_GRAB_TICS, NULL, &s_BonusGrab[10]},
2503 {BONUS_GRAB + 9, 90, NULL, &s_BonusGrab[11]},
2504 {BONUS_GRAB + 9, BONUS_GRAB_TICS, NULL, &s_BonusGrab[11]},
2505 };
2506
2507 #if 1 // Turned off the standing animate because he looks like a FAG!
2508 static STATE s_BonusRest[] =
2509 {
2510 {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[1]},
2511 {BONUS_REST + 1, BONUS_REST_TICS, NULL, &s_BonusRest[2]},
2512 {BONUS_REST + 2, BONUS_REST_TICS, NULL, &s_BonusRest[3]},
2513 {BONUS_REST + 1, BONUS_REST_TICS, NULL, &s_BonusRest[0]},
2514 };
2515 #else
2516 static STATE s_BonusRest[] =
2517 {
2518 {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[1]},
2519 {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[0]},
2520 };
2521 #endif
2522
2523 static STATEp s_BonusAnim[] =
2524 {
2525 s_BonusPunch,
2526 s_BonusKick,
2527 s_BonusGrab
2528 };
2529
2530 STATEp State = s_BonusRest;
2531
2532 int Tics = 0;
2533 int line = 0;
2534 BOOL BonusDone;
2535 UserInput uinfo = { FALSE, FALSE, dir_None };
2536
2537 if(Level < 0) Level = 0;
2538
2539 flushperms();
2540 clearallviews(0);
2541 nextpage();
2542
2543 KB_ClearKeysDown();
2544
2545 totalclock = ototalclock = 0;
2546 limit = synctics;
2547
2548 if (gs.MusicOn)
2549 {
2550 PlaySong(voc[DIGI_ENDLEV].name, 3, TRUE, TRUE);
2551 }
2552
2553 // special case code because I don't care any more!
2554 if (FinishAnim)
2555 {
2556 rotatesprite(0, 0, RS_SCALE, 0, 5120, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2557 rotatesprite(158<<16, 86<<16, RS_SCALE, 0, State->Pic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2558 nextpage();
2559 FadeIn(0,0);
2560 }
2561
2562 BonusDone = FALSE;
2563 while (!BonusDone)
2564 {
2565 handleevents();
2566 flushpackets();
2567
2568 // taken from top of faketimerhandler
2569 if (totalclock < ototalclock + limit)
2570 {
2571 continue;
2572 }
2573 ototalclock += limit;
2574
2575 CONTROL_GetUserInput(&uinfo);
2576 CONTROL_ClearUserInput(&uinfo);
2577 if (KEY_PRESSED(KEYSC_SPACE) || KEY_PRESSED(KEYSC_ENTER) || uinfo.button0 || uinfo.button1)
2578 {
2579 if (State >= s_BonusRest && State < &s_BonusRest[SIZ(s_BonusRest)])
2580 {
2581 State = s_BonusAnim[STD_RANDOM_RANGE(SIZ(s_BonusAnim))];
2582 Tics = 0;
2583 }
2584 }
2585
2586 gStateControl(&State, &Tics);
2587 clearallviews(0);
2588 rotatesprite(0, 0, RS_SCALE, 0, 5120, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2589
2590 if (UserMapName[0])
2591 {
2592 sprintf(ds,"%s",UserMapName);
2593 MNU_MeasureString(ds, &w, &h);
2594 MNU_DrawString(TEXT_TEST_COL(w), 20, ds,1,19);
2595 }
2596 else
2597 {
2598 if (PlayingLevel <= 1)
2599 PlayingLevel = 1;
2600 sprintf(ds,"%s",LevelInfo[PlayingLevel].Description);
2601 MNU_MeasureString(ds, &w, &h);
2602 MNU_DrawString(TEXT_TEST_COL(w), 20, ds,1,19);
2603 }
2604
2605 sprintf(ds,"Completed");
2606 MNU_MeasureString(ds, &w, &h);
2607 MNU_DrawString(TEXT_TEST_COL(w), 30, ds,1,19);
2608
2609 rotatesprite(158<<16, 86<<16, RS_SCALE, 0, State->Pic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2610
2611 #define BONUS_LINE(i) (50 + ((i)*20))
2612
2613 line = 0;
2614 second_tics = (PlayClock/120);
2615 minutes = (second_tics/60);
2616 seconds = (second_tics%60);
2617 sprintf(ds,"Your Time: %2d : %02d", minutes, seconds);
2618 MNU_MeasureString(ds, &w, &h);
2619 MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2620
2621 if (!UserMapName[0])
2622 {
2623 line++;
2624 sprintf(ds,"3D Realms Best Time: %s", LevelInfo[PlayingLevel].BestTime);
2625 MNU_MeasureString(ds, &w, &h);
2626 MNU_DrawString(40, BONUS_LINE(line), ds,1,16);
2627
2628 line++;
2629 sprintf(ds,"Par Time: %s", LevelInfo[PlayingLevel].ParTime);
2630 MNU_MeasureString(ds, &w, &h);
2631 MNU_DrawString(40, BONUS_LINE(line), ds,1,16);
2632 }
2633
2634
2635 // always read secrets and kills from the first player
2636 line++;
2637 sprintf(ds,"Secrets: %d / %d", Player->SecretsFound, LevelSecrets);
2638 MNU_MeasureString(ds, &w, &h);
2639 MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2640
2641 line++;
2642 sprintf(ds,"Kills: %d / %d", Player->Kills, TotalKillable);
2643 MNU_MeasureString(ds, &w, &h);
2644 MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2645
2646
2647 sprintf(ds,"Press SPACE to continue");
2648 MNU_MeasureString(ds, &w, &h);
2649 MNU_DrawString(TEXT_TEST_COL(w), 185, ds,1,19);
2650
2651 nextpage();
2652 ScreenCaptureKeys();
2653
2654 if (State == State->NextState)
2655 BonusDone = TRUE;
2656 }
2657
2658 StopSound();
2659 Terminate3DSounds();
2660 }
2661
EndGameSequence(VOID)2662 VOID EndGameSequence(VOID)
2663 {
2664 BOOL anim_ok = TRUE;
2665 FadeOut(0, 5);
2666
2667 if ((gs.ParentalLock || Global_PLock) && FinishAnim == ANIM_SUMO)
2668 anim_ok = FALSE;
2669
2670 if (anim_ok)
2671 playanm(FinishAnim);
2672
2673 BonusScreen(Player + myconnectindex);
2674
2675 ExitLevel = FALSE;
2676 QuitFlag = FALSE;
2677 AutoNet = FALSE;
2678
2679 if (FinishAnim == ANIM_ZILLA)
2680 CreditsLevel();
2681
2682 ExitLevel = FALSE;
2683 QuitFlag = FALSE;
2684 AutoNet = FALSE;
2685
2686 if (SW_SHAREWARE) {
2687 Level = 0;
2688 } else {
2689 if (Level == 4 || Level == 20)
2690 {
2691 //CDAudio_Stop();
2692 //CDAudio_Play(2,TRUE); // Play theme after game ends
2693 Level=0;
2694 }
2695 else
2696 Level++;
2697 }
2698 }
2699
2700 VOID
StatScreen(PLAYERp mpp)2701 StatScreen(PLAYERp mpp)
2702 {
2703 int minutes,seconds,second_tics;
2704 extern BOOL FinishedLevel;
2705 extern int PlayClock;
2706 extern short LevelSecrets;
2707 extern short TotalKillable;
2708 short w,h;
2709 int zero=0;
2710 int handle=0;
2711
2712 short rows,cols,i,j;
2713 PLAYERp pp = NULL;
2714 int x,y;
2715 short death_total[MAX_SW_PLAYERS_REG];
2716 short kills[MAX_SW_PLAYERS_REG];
2717 short pal;
2718
2719 UserInput uinfo = { FALSE, FALSE, dir_None };
2720
2721 #define STAT_START_X 20
2722 #define STAT_START_Y 85
2723 #define STAT_OFF_Y 9
2724 #define STAT_HEADER_Y 14
2725
2726 #define SM_SIZ(num) ((num)*4)
2727
2728 #define STAT_TABLE_X (STAT_START_X + SM_SIZ(15))
2729 #define STAT_TABLE_XOFF SM_SIZ(6)
2730
2731 // No stats in bot games
2732 //if (BotMode) return;
2733
2734 ResetPalette(mpp);
2735 COVER_SetReverb(0); // Reset reverb
2736 StopSound();
2737
2738 if (FinishAnim)
2739 {
2740 EndGameSequence();
2741 return;
2742 }
2743
2744 if (gNet.MultiGameType != MULTI_GAME_COMMBAT)
2745 {
2746 if (!FinishedLevel)
2747 return;
2748 BonusScreen(mpp);
2749 return;
2750 }
2751
2752 flushperms();
2753 DrawStatScreen();
2754
2755 memset(death_total,0,sizeof(death_total));
2756 memset(kills,0,sizeof(kills));
2757
2758 sprintf(ds,"MULTIPLAYER TOTALS");
2759 MNU_MeasureString(ds, &w, &h);
2760 MNU_DrawString(TEXT_TEST_COL(w), 68, ds, 0, 0);
2761
2762 sprintf(ds,"PRESS SPACE BAR TO CONTINUE");
2763 MNU_MeasureString(ds, &w, &h);
2764 MNU_DrawString(TEXT_TEST_COL(w), 189, ds, 0, 0);
2765
2766 x = STAT_START_X;
2767 y = STAT_START_Y;
2768
2769 sprintf(ds," NAME 1 2 3 4 5 6 7 8 KILLS");
2770 DisplayMiniBarSmString(mpp, x, y, 0, ds);
2771 rows = OrigCommPlayers;
2772 cols = OrigCommPlayers;
2773 mpp = Player + myconnectindex;
2774
2775 y += STAT_HEADER_Y;
2776
2777 for (i = 0; i < rows; i++)
2778 {
2779 x = STAT_START_X;
2780 pp = Player + i;
2781
2782 sprintf(ds,"%d", i+1);
2783 DisplayMiniBarSmString(mpp, x, y, 0, ds);
2784
2785 sprintf(ds," %-13s", pp->PlayerName);
2786 DisplayMiniBarSmString(mpp, x, y, User[pp->PlayerSprite]->spal, ds);
2787
2788 x = STAT_TABLE_X;
2789 for (j = 0; j < cols; j++)
2790 {
2791 pal = 0;
2792 death_total[j] += pp->KilledPlayer[j];
2793
2794 if (i == j)
2795 {
2796 // don't add kill for self or team player
2797 pal = PALETTE_PLAYER0 + 4;
2798 kills[i] -= pp->KilledPlayer[j]; // subtract self kills
2799 }
2800 else
2801 if (gNet.TeamPlay)
2802 {
2803 if (User[pp->PlayerSprite]->spal == User[Player[j].PlayerSprite]->spal)
2804 {
2805 // don't add kill for self or team player
2806 pal = PALETTE_PLAYER0 + 4;
2807 kills[i] -= pp->KilledPlayer[j]; // subtract self kills
2808 } else
2809 kills[i] += pp->KilledPlayer[j]; // kills added here
2810 }
2811 else
2812 {
2813 kills[i] += pp->KilledPlayer[j]; // kills added here
2814 }
2815
2816 sprintf(ds,"%d", pp->KilledPlayer[j]);
2817 DisplayMiniBarSmString(mpp, x, y, pal, ds);
2818 x += STAT_TABLE_XOFF;
2819 }
2820
2821 y += STAT_OFF_Y;
2822 }
2823
2824
2825 // Deaths
2826
2827 x = STAT_START_X;
2828 y += STAT_OFF_Y;
2829
2830 sprintf(ds," DEATHS");
2831 DisplayMiniBarSmString(mpp, x, y, 0, ds);
2832 x = STAT_TABLE_X;
2833
2834 for (j = 0; j < cols; j++)
2835 {
2836 sprintf(ds,"%d",death_total[j]);
2837 DisplayMiniBarSmString(mpp, x, y, 0, ds);
2838 x += STAT_TABLE_XOFF;
2839 }
2840
2841 x = STAT_START_X;
2842 y += STAT_OFF_Y;
2843
2844 // Kills
2845 x = STAT_TABLE_X + SM_SIZ(50);
2846 y = STAT_START_Y + STAT_HEADER_Y;
2847
2848 for (i = 0; i < rows; i++)
2849 {
2850 pp = Player + i;
2851
2852 sprintf(ds,"%d", kills[i]);//pp->Kills);
2853 DisplayMiniBarSmString(mpp, x, y, 0, ds);
2854
2855 y += STAT_OFF_Y;
2856 }
2857
2858 nextpage();
2859
2860 KB_ClearKeysDown();
2861
2862 if (gs.MusicOn)
2863 {
2864 PlaySong(voc[DIGI_ENDLEV].name, 3, TRUE, TRUE);
2865 }
2866
2867 while (TRUE)
2868 {
2869 handleevents();
2870 flushpackets();
2871 if (quitevent) break;
2872
2873 CONTROL_GetUserInput(&uinfo);
2874 CONTROL_ClearUserInput(&uinfo);
2875 if (KEY_PRESSED(KEYSC_SPACE) || KEY_PRESSED(KEYSC_ENTER) || uinfo.button0 || uinfo.button1)
2876 {
2877 break;
2878 }
2879
2880 ScreenCaptureKeys();
2881 }
2882
2883 StopSound();
2884 Terminate3DSounds();
2885 }
2886
2887 VOID
GameIntro(VOID)2888 GameIntro(VOID)
2889 {
2890
2891 DSPRINTF(ds,"GameIntro...");
2892 MONO_PRINT(ds);
2893
2894 wm_setwindowtitle(gameeditionname);
2895
2896 if (DemoPlaying)
2897 return;
2898
2899 // this could probably be taken out and you could select skill level
2900 // from menu to start the game
2901 if (!CommEnabled && UserMapName[0])
2902 return;
2903
2904 Level = 1;
2905
2906
2907
2908
2909 if (!AutoNet)
2910 {
2911 LogoLevel();
2912 //CreditsLevel();
2913 //SceneLevel();
2914 //TitleLevel();
2915 IntroAnimLevel();
2916 IntroAnimCount = 0;
2917 }
2918
2919 MenuLevel();
2920 }
2921
2922 VOID
Control(VOID)2923 Control(VOID)
2924 {
2925
2926 InitGame();
2927
2928 MONO_PRINT("InitGame done");
2929 MNU_InitMenus();
2930 InGame = TRUE;
2931 GameIntro();
2932 //NewGame = TRUE;
2933
2934 while (!QuitFlag)
2935 {
2936 NewLevel();
2937 }
2938
2939 CleanExit = TRUE;
2940 TerminateGame();
2941 }
2942
2943
2944 void
_Assert(char * expr,char * strFile,unsigned uLine)2945 _Assert(char *expr, char *strFile, unsigned uLine)
2946 {
2947 sprintf(ds, "Assertion failed: %s %s, line %u", expr, strFile, uLine);
2948 MONO_PRINT(ds);
2949 TerminateGame();
2950 #if 1 //def RENDERTYPEWIN
2951 wm_msgbox(NULL, "%s", ds);
2952 #else
2953 printf("Assertion failed: %s\n %s, line %u\n", expr, strFile, uLine);
2954 #endif
2955 exit(0);
2956 }
2957
2958
2959 void
_ErrMsg(char * strFile,unsigned uLine,char * format,...)2960 _ErrMsg(char *strFile, unsigned uLine, char *format, ...)
2961 {
2962 va_list arglist;
2963
2964 //DSPRINTF(ds, "Error: %s, line %u", strFile, uLine);
2965 //MONO_PRINT(ds);
2966 TerminateGame();
2967
2968 #if 1 //def RENDERTYPEWIN
2969 {
2970 char msg[256], *p;
2971 Bsnprintf(msg, sizeof(msg), "Error: %s, line %u\n", strFile, uLine);
2972 p = &msg[strlen(msg)];
2973 va_start( arglist, format );
2974 Bvsnprintf(msg, sizeof(msg) - (p-msg), format, arglist);
2975 va_end(arglist);
2976 wm_msgbox(NULL, "%s", msg);
2977 }
2978 #else
2979 printf("Error: %s, line %u\n", strFile, uLine);
2980
2981 va_start( arglist, format );
2982 vprintf( format, arglist );
2983 va_end( arglist );
2984 #endif
2985
2986 exit(0);
2987 }
2988
2989 void
dsprintf(char * str,char * format,...)2990 dsprintf(char *str, char *format, ...)
2991 {
2992 va_list arglist;
2993
2994 va_start( arglist, format );
2995 vsprintf( str, format, arglist );
2996 va_end( arglist );
2997 }
2998
2999 void
dsprintf_null(char * str,char * format,...)3000 dsprintf_null(char *str, char *format, ...)
3001 {
3002 va_list arglist;
3003 }
3004
MoveLoop(void)3005 void MoveLoop(void)
3006 {
3007 int pnum;
3008
3009 getpackets();
3010
3011 if (PredictionOn && CommEnabled)
3012 {
3013 while (predictmovefifoplc < Player[myconnectindex].movefifoend)
3014 {
3015 DoPrediction(ppp);
3016 }
3017 }
3018
3019 //While you have new input packets to process...
3020 if (!CommEnabled)
3021 bufferjitter = 0;
3022
3023 while (Player[myconnectindex].movefifoend - movefifoplc > bufferjitter)
3024 {
3025 //Make sure you have at least 1 packet from everyone else
3026 TRAVERSE_CONNECT(pnum)
3027 {
3028 if (movefifoplc == Player[pnum].movefifoend)
3029 break;
3030 }
3031
3032 //Pnum is >= 0 only if last loop was broken, meaning a player wasn't caught up
3033 if (pnum >= 0)
3034 break;
3035
3036 domovethings();
3037
3038 #if DEBUG
3039 //if (DemoSyncRecord)
3040 // demosync_record();
3041 #endif
3042 }
3043
3044 if (!InputMode && !PauseKeySet)
3045 MNU_CheckForMenus();
3046 }
3047
3048
InitPlayerGameSettings(void)3049 void InitPlayerGameSettings(void)
3050 {
3051 int pnum;
3052
3053 // don't jack with auto aim settings if DemoMode is going
3054 // what the hell did I do this for?????????
3055 //if (DemoMode)
3056 // return;
3057
3058 if (CommEnabled)
3059 {
3060 // everyone gets the same Auto Aim
3061 TRAVERSE_CONNECT(pnum)
3062 {
3063 if (gNet.AutoAim)
3064 SET(Player[pnum].Flags, PF_AUTO_AIM);
3065 else
3066 RESET(Player[pnum].Flags, PF_AUTO_AIM);
3067 }
3068 }
3069 else
3070 {
3071 if (gs.AutoAim)
3072 SET(Player[myconnectindex].Flags, PF_AUTO_AIM);
3073 else
3074 RESET(Player[myconnectindex].Flags, PF_AUTO_AIM);
3075 }
3076
3077 // everyone had their own Auto Run
3078 if (gs.AutoRun)
3079 SET(Player[myconnectindex].Flags, PF_LOCK_RUN);
3080 else
3081 RESET(Player[myconnectindex].Flags, PF_LOCK_RUN);
3082
3083 if (gs.MouseAimingOn)
3084 SET(Player[myconnectindex].Flags, PF_MOUSE_AIMING_ON);
3085 else
3086 RESET(Player[myconnectindex].Flags, PF_MOUSE_AIMING_ON);
3087 }
3088
3089
InitRunLevel(VOID)3090 VOID InitRunLevel(VOID)
3091 {
3092 int i;
3093 if (DemoEdit)
3094 return;
3095
3096 if (LoadGameOutsideMoveLoop)
3097 {
3098 int SavePlayClock;
3099 extern int PlayClock;
3100 LoadGameOutsideMoveLoop = FALSE;
3101 // contains what is needed from calls below
3102 if (gs.Ambient)
3103 StartAmbientSound();
3104 SetCrosshair();
3105 PlaySong(LevelSong, -1, TRUE, TRUE);
3106 SetRedrawScreen(Player + myconnectindex);
3107 // crappy little hack to prevent play clock from being overwritten
3108 // for load games
3109 SavePlayClock = PlayClock;
3110 InitTimingVars();
3111 PlayClock = SavePlayClock;
3112 MONO_PRINT("Done with InitRunLevel");
3113 return;
3114 }
3115
3116 #if 0
3117 // ensure we are through the initialization code before sending the game
3118 // version. Otherwise, it is possible to send this too early and have it
3119 // blown away on the other side.
3120 waitforeverybody();
3121 #endif
3122
3123 SendVersion(GameVersion);
3124
3125 waitforeverybody();
3126
3127 StopSong();
3128
3129 if (Bstrcasecmp(CacheLastLevel, LevelName) != 0)
3130 DoTheCache();
3131
3132 if (CachePrintMode)
3133 cachedebug = TRUE;
3134
3135 // auto aim / auto run / etc
3136 InitPlayerGameSettings();
3137
3138 // send packets with player info
3139 InitNetPlayerOptions();
3140
3141 // Initialize Game part of network code (When ready2send != 0)
3142 InitNetVars();
3143
3144 {
3145 int track;
3146 if (Level == 0) {
3147 track = RedBookSong[4+RANDOM_RANGE(10)];
3148 } else {
3149 track = RedBookSong[Level];
3150 }
3151 PlaySong(LevelSong, track, TRUE, TRUE);
3152 }
3153
3154 InitPrediction(&Player[myconnectindex]);
3155
3156 if (!DemoInitOnce)
3157 DemoRecordSetup();
3158
3159 // everything has been inited at least once for RECORD
3160 DemoInitOnce = TRUE;
3161
3162 //DebugWriteLoc(__FILE__, __LINE__);
3163 waitforeverybody();
3164
3165 CheckVersion(GameVersion);
3166
3167 // IMPORTANT - MUST be right before game loop AFTER waitforeverybody
3168 InitTimingVars();
3169
3170 SetRedrawScreen(Player + myconnectindex);
3171
3172 FX_SetVolume(gs.SoundVolume); // Turn volume back up
3173 if (gs.Ambient)
3174 StartAmbientSound();
3175 }
3176
3177 VOID
RunLevel(VOID)3178 RunLevel(VOID)
3179 {
3180 int i;
3181 InitRunLevel();
3182
3183 FX_SetVolume(gs.SoundVolume);
3184 SetSongVolume(gs.MusicVolume);
3185
3186 #if 0
3187 waitforeverybody();
3188 #endif
3189 ready2send = 1;
3190
3191 while (TRUE)
3192 {
3193 handleevents();
3194 OSD_DispatchQueued();
3195
3196 if (quitevent)
3197 {
3198 if (CommPlayers >= 2)
3199 MultiPlayQuitFlag = TRUE;
3200 else
3201 QuitFlag = TRUE;
3202 }
3203
3204 //MONO_PRINT("Before MoveLoop");
3205 MoveLoop();
3206 //MONO_PRINT("After MoveLoop");
3207 //MONO_PRINT("Before DrawScreen");
3208 drawscreen(Player + screenpeek);
3209 //MONO_PRINT("After DrawScreen");
3210
3211 if (QuitFlag)
3212 break;
3213
3214 if (ExitLevel)
3215 {
3216 ExitLevel = FALSE;
3217 break;
3218 }
3219 }
3220
3221 ready2send = 0;
3222 }
3223
swexit(int exitval)3224 void swexit(int exitval)
3225 {
3226 exit(exitval);
3227 }
3228
DosScreen(VOID)3229 VOID DosScreen(VOID)
3230 {
3231 #if 0
3232 #ifdef SW_SHAREWARE
3233 #define DOS_SCREEN_NAME "SHADSW.BIN"
3234 #else
3235 #define DOS_SCREEN_NAME "SWREG.BIN"
3236 #endif
3237
3238 #define DOS_SCREEN_SIZE (4000-(80*2))
3239 #define DOS_SCREEN_PTR ((void *)(0xB8000))
3240 int fin;
3241 int i;
3242 char buffer[DOS_SCREEN_SIZE];
3243
3244 fin = kopen4load(DOS_SCREEN_NAME,0);
3245 if (fin == -1)
3246 return;
3247
3248 kread(fin, buffer, sizeof(buffer));
3249 memcpy(DOS_SCREEN_PTR, buffer, DOS_SCREEN_SIZE);
3250 kclose(fin);
3251 move_cursor(23,0);
3252 _displaycursor( _GCURSORON );
3253 #endif
3254 }
3255
AlphaMessage(VOID)3256 VOID AlphaMessage(VOID)
3257 {
3258 if (SW_SHAREWARE) {
3259 buildputs("SHADOW WARRIOR(tm) (Shareware Version)\n");
3260 } else {
3261 buildputs("SHADOW WARRIOR(tm)\n");
3262 }
3263 buildputs("Copyright (c) 1997 3D Realms Entertainment\n");
3264 }
3265
3266 typedef struct
3267 {
3268 char registered;
3269 char *arg_fmt;
3270 char *arg_descr;
3271 }CLI_ARG;
3272
3273 #if DEBUG
3274 CLI_ARG cli_dbg_arg[] =
3275 {
3276 {0, "-coop#", "Single Player Cooperative Mode" },
3277 {0, "-commbat#", "Single Player Commbat Mode" },
3278 {0, "-demosyncrecord", "Demo sync record" },
3279 {0, "-demosynctest", "Demo sync test" },
3280 {0, "-cam", "Camera test mode" },
3281 {0, "-debugactor", "No Actors" },
3282 {0, "-debuganim", "No Anims" },
3283 {0, "-debugso", "No Sector Objects" },
3284 {0, "-debugsector", "No Sector Movement" },
3285 {0, "-debugpanel", "No Panel" },
3286 {0, "-mono", "Mono" },
3287 {0, "-allsync", "Enable full sync testing" },
3288 };
3289 #endif
3290
3291
3292 CLI_ARG cli_arg[] =
3293 {
3294 {0, "-?", "This help message" },
3295 #if DEBUG
3296 {0, "-debug", "Debug Help Options" },
3297 #endif
3298 {1, "-map [mapname]", "Load a map" },
3299 {1, "-nocd<audio>", "No CD Red Book Audio" },
3300 {0, "-name [playername]", "Player Name" },
3301 {0, "-s#", "Skill (1-4)" },
3302 {0, "-f#", "Packet Duplication - 2, 4, 8" },
3303 {0, "-nopred<ict>", "Disable Net Prediction Method" },
3304 {0, "-level#", "Start at level# (Shareware: 1-4, full version 1-28)" },
3305 {0, "-dr[filename.dmo]", "Demo record. NOTE: Must use -level# with this option." },
3306 {0, "-dp[filename.dmo]", "Demo playback. NOTE: Must use -level# with this option." },
3307 {0, "-monst<ers>", "No Monsters" },
3308 {0, "-nodemo", "No demos on game startup" },
3309 {0, "-nometers", "Don't show air or boss meter bars in game"},
3310 {0, "-movescale [sc]", "Adjust movement scale: 256 = 1 unit" },
3311 {0, "-turnscale [sc]", "Adjust turning scale: 256 = 1 unit" },
3312 {0, "-extcompat", "Controller compatibility mode (with Duke 3D)"},
3313 {1, "-g[filename.grp]", "Load an extra GRP or ZIP file" },
3314 {1, "-h[filename.def]", "Use filename.def instead of SW.DEF" },
3315 {0, "-setup", "Displays the configuration dialogue box"},
3316 {0, "-nosetup", "Prevents display of the configuration dialogue box"},
3317
3318 #if 0 //def NET_MODE_MASTER_SLAVE
3319 {0, "-broad<cast>", "Broadcast network method (default)" },
3320 {0, "-master<slave>", "Master/Slave network method" },
3321 #endif
3322 };
3323
3324 /*
3325 Map -> User Map Name
3326 Auto -> Auto Start Game
3327 Rules -> 0=WangBang 1=WangBang (No Respawn) 2=CoOperative
3328 Level -> 0 to 24(?)
3329 Enemy -> 0=None 1=Easy 2=Norm 3=Hard 4=Insane
3330 Markers -> 0=Off 1=On
3331 Team -> 0=Off 1=On
3332 HurtTeam -> 0=Off 1=On
3333 KillLimit -> 0=Infinite 1=10 2=20 3=30 4=40 5=50 6=60 7=70 8=80 9=90 10=100
3334 TimeLimit -> 0=Infinite 1=3 2=5 3=10 4=20 5=30 6=45 7=60
3335 Color -> 0=Brown 1=Purple 2=Red 3=Yellow 4=Olive 5=Green
3336 Nuke -> 0=Off 1=On
3337
3338 Example Command Line:
3339 sw -map testmap.map -autonet 0,0,1,1,1,0,3,2,1,1 -f4 -name 1234567890 -net 12345678
3340 commit -map grenade -autonet 0,0,1,1,1,0,3,2,1,1 -name frank
3341 */
3342
3343 char isShareware = FALSE, useDarts = FALSE;
3344
DetectShareware(void)3345 int DetectShareware(void)
3346 {
3347 #define DOS_SCREEN_NAME_SW "SHADSW.BIN"
3348 #define DOS_SCREEN_NAME_REG "SWREG.BIN"
3349
3350 int h;
3351
3352 h = kopen4load(DOS_SCREEN_NAME_SW,1);
3353 if (h >= 0)
3354 {
3355 isShareware = TRUE;
3356 kclose(h);
3357 return 0;
3358 }
3359
3360 h = kopen4load(DOS_SCREEN_NAME_REG,1);
3361 if (h >= 0)
3362 {
3363 isShareware = FALSE;
3364 kclose(h);
3365 return 0;
3366 }
3367
3368 return 1; // heavens knows what this is...
3369 }
3370
3371
CommandLineHelp(CLI_ARG * args,int numargs)3372 void CommandLineHelp(CLI_ARG *args, int numargs)
3373 {
3374 int i;
3375
3376 const char *usagefmt = "Usage: %s [options]\n";
3377 const char *optionsfmt = "options: (%s)\n\n";
3378 #ifdef _WIN32
3379 const char *argfmt = "%s\t%s\n";
3380 const char *strargv0 = "sw";
3381 const char *stropts = "'/' may be used instead of '-', <> text is optional";
3382 #else
3383 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199409L
3384 const char *argfmt = " %s \u2014 %s\n";
3385 #else
3386 const char *argfmt = " %s -- %s\n";
3387 #endif
3388 const char *strargv0 = _buildargv[0];
3389 const char *stropts = "<> text is optional";
3390 #endif
3391
3392 char *str = NULL, *strapp;
3393 int len;
3394
3395 len = snprintf(NULL, 0, usagefmt, strargv0);
3396 len += snprintf(NULL, 0, optionsfmt, stropts);
3397 for (i=0;i < numargs;i++)
3398 {
3399 if (!args[i].arg_fmt || args[i].registered > SW_REGISTERED)
3400 continue;
3401 len += snprintf(NULL, 0, argfmt, args[i].arg_fmt, args[i].arg_descr);
3402 }
3403
3404 if (len < 0 || !(str = (char *)malloc(len + 1)))
3405 {
3406 wm_msgbox("Shadow Warrior Help", "Command line help not available");
3407 return;
3408 }
3409
3410 strapp = str;
3411 strapp += sprintf(strapp, usagefmt, strargv0);
3412 strapp += sprintf(strapp, optionsfmt, stropts);
3413 for (i=0;i < numargs;i++)
3414 {
3415 if (!args[i].arg_fmt || args[i].registered > SW_REGISTERED)
3416 continue;
3417 strapp += sprintf(strapp, argfmt, args[i].arg_fmt, args[i].arg_descr);
3418 }
3419
3420 wm_msgbox("Shadow Warrior Help", "%s", str);
3421 free(str);
3422 }
3423
3424 char grpfile[BMAX_PATH+1] = "sw.grp";
3425 const char *gameeditionname = "Unknown edition";
3426
app_main(int argc,char const * const argv[])3427 int app_main(int argc, char const * const argv[])
3428 {
3429 int i;
3430 int stat, nexti;
3431 char type;
3432 extern int MovesPerPacket;
3433 VOID DoSector(VOID);
3434 VOID gameinput(VOID);
3435 int cnt = 0;
3436 int netparam = 0, endnetparam = 0;
3437 ULONG TotalMemory;
3438 int configloaded;
3439 struct grpfile *gamegrp = NULL;
3440
3441 #ifdef RENDERTYPEWIN
3442 if (win_checkinstance()) {
3443 if (!wm_ynbox("Shadow Warrior","Another Build game is currently running. "
3444 "Do you wish to continue starting this copy?"))
3445 return 0;
3446 }
3447 #endif
3448
3449 #if defined(DATADIR)
3450 {
3451 const char *datadir = DATADIR;
3452 if (datadir && datadir[0]) {
3453 addsearchpath(datadir);
3454 }
3455 }
3456 #endif
3457
3458 {
3459 char *supportdir = Bgetsupportdir(TRUE);
3460 char *appdir = Bgetappdir();
3461 char dirpath[BMAX_PATH+1];
3462
3463 // the OSX app bundle, or on Windows the directory where the EXE was launched
3464 if (appdir) {
3465 addsearchpath(appdir);
3466 free(appdir);
3467 }
3468
3469 // the global support files directory
3470 if (supportdir) {
3471 Bsnprintf(dirpath, sizeof(dirpath), "%s/JFShadowWarrior", supportdir);
3472 addsearchpath(dirpath);
3473 free(supportdir);
3474 }
3475 }
3476
3477 // default behaviour is to write to the user profile directory, but
3478 // creating a 'user_profiles_disabled' file in the current working
3479 // directory where the game was launched makes the installation
3480 // "portable" by writing into the working directory
3481 if (access("user_profiles_disabled", F_OK) == 0) {
3482 char cwd[BMAX_PATH+1];
3483 if (getcwd(cwd, sizeof(cwd))) {
3484 addsearchpath(cwd);
3485 }
3486 } else {
3487 char *supportdir;
3488 char dirpath[BMAX_PATH+1];
3489 int asperr;
3490
3491 if ((supportdir = Bgetsupportdir(FALSE))) {
3492 #if defined(_WIN32) || defined(__APPLE__)
3493 const char *confdir = "JFShadowWarrior";
3494 #else
3495 const char *confdir = ".jfsw";
3496 #endif
3497 Bsnprintf(dirpath, sizeof(dirpath), "%s/%s", supportdir, confdir);
3498 asperr = addsearchpath(dirpath);
3499 if (asperr == -2) {
3500 if (Bmkdir(dirpath, S_IRWXU) == 0) {
3501 asperr = addsearchpath(dirpath);
3502 } else {
3503 asperr = -1;
3504 }
3505 }
3506 if (asperr == 0) {
3507 chdir(dirpath);
3508 }
3509 free(supportdir);
3510 }
3511 }
3512
3513 buildsetlogfile("sw.log");
3514
3515 OSD_RegisterFunction("restartvid", "restartvid: reinitialise the video mode", osdcmd_restartvid);
3516 OSD_RegisterFunction("vidmode", "vidmode [xdim ydim] [bpp] [fullscreen]: change the video mode", osdcmd_vidmode);
3517
3518 wm_setapptitle("JFShadowWarrior");
3519 buildprintf("\nJFShadowWarrior\n"
3520 "Based on Shadow Warrior by 3D Realms Entertainment.\n"
3521 "Additional improvements by Jonathon Fowler (http://www.jonof.id.au) and other contributors.\n"
3522 "See GPL.TXT for license terms.\n\n"
3523 "Version %s.\nBuilt %s %s.\n", game_version, game_date, game_time);
3524
3525 for (i=1;i<argc;i++) {
3526 char const *arg = argv[i];
3527
3528 #ifdef _WIN32
3529 if (*arg != '-' && *arg != '/') continue;
3530 #else
3531 if (*arg != '-') continue;
3532 #endif
3533
3534 arg++;
3535 if (!Bstrcasecmp(arg, "setup"))
3536 {
3537 CommandSetup = 1;
3538 }
3539 else
3540 if (!Bstrcasecmp(arg, "nosetup"))
3541 {
3542 CommandSetup = -1;
3543 }
3544 else
3545 if (!Bstrcasecmp(arg, "net"))
3546 {
3547 netparam = ++i;
3548 for (; i<argc; i++)
3549 if (!strcmp(argv[i], "--")) break;
3550 endnetparam = i;
3551 }
3552 else
3553 if (!Bstrcasecmp(arg, "?"))
3554 {
3555 CommandLineHelp(cli_arg, SIZ(cli_arg));
3556 return(0);
3557 }
3558 #if DEBUG
3559 else
3560 if (!Bstrcasecmp(arg, "debug"))
3561 {
3562 CommandLineHelp(cli_dbg_arg, SIZ(cli_dbg_arg));
3563 return(0);
3564 }
3565 #endif
3566 }
3567
3568 if (preinitengine()) {
3569 wm_msgbox("Build Engine Initialisation Error",
3570 "There was a problem initialising the Build engine: %s", engineerrstr);
3571 exit(1);
3572 }
3573
3574 configloaded = CONFIG_ReadSetup();
3575 if (getenv("SWGRP")) {
3576 strncpy(grpfile, getenv("SWGRP"), BMAX_PATH);
3577 }
3578
3579 ScanGroups();
3580 {
3581 // Try and identify grpfile in the set of GRPs.
3582 struct grpfile *first = NULL;
3583 for (gamegrp = foundgrps; gamegrp; gamegrp = gamegrp->next) {
3584 if (!gamegrp->ref) continue; // Not a recognised game file.
3585 if (!first) first = gamegrp;
3586 if (!Bstrcasecmp(gamegrp->name, grpfile)) {
3587 // Found it.
3588 break;
3589 }
3590 }
3591 if (!gamegrp && first) {
3592 // It wasn't found, so use the first recognised one scanned.
3593 gamegrp = first;
3594 }
3595 }
3596
3597 if (netparam) { // -net parameter on command line.
3598 netsuccess = initmultiplayersparms(endnetparam - netparam, &argv[netparam]);
3599 }
3600
3601 #if defined RENDERTYPEWIN || (defined RENDERTYPESDL && (defined __APPLE__ || defined HAVE_GTK))
3602 {
3603 struct startwin_settings settings;
3604
3605 memset(&settings, 0, sizeof(settings));
3606 settings.fullscreen = ScreenMode;
3607 settings.xdim3d = ScreenWidth;
3608 settings.ydim3d = ScreenHeight;
3609 settings.bpp3d = ScreenBPP;
3610 settings.forcesetup = ForceSetup;
3611 settings.usemouse = UseMouse;
3612 settings.usejoy = UseJoystick;
3613 settings.samplerate = MixRate;
3614 settings.bitspersample = NumBits;
3615 settings.channels = NumChannels;
3616 settings.selectedgrp = gamegrp;
3617 settings.netoverride = netparam > 0;
3618
3619 if (configloaded < 0 || (ForceSetup && CommandSetup == 0) || (CommandSetup > 0)) {
3620 if (startwin_run(&settings) == STARTWIN_CANCEL) {
3621 uninitengine();
3622 exit(0);
3623 }
3624 }
3625
3626 ScreenMode = settings.fullscreen;
3627 ScreenWidth = settings.xdim3d;
3628 ScreenHeight = settings.ydim3d;
3629 ScreenBPP = settings.bpp3d;
3630 ForceSetup = settings.forcesetup;
3631 UseMouse = settings.usemouse;
3632 UseJoystick = settings.usejoy;
3633 MixRate = settings.samplerate;
3634 NumBits = settings.bitspersample;
3635 NumChannels = settings.channels;
3636 gamegrp = settings.selectedgrp;
3637
3638 if (!netparam) {
3639 char modeparm[8];
3640 const char *parmarr[3] = { modeparm, NULL, NULL };
3641 int parmc = 0;
3642
3643 if (settings.joinhost) {
3644 strcpy(modeparm, "-nm");
3645 parmarr[1] = settings.joinhost;
3646 parmc = 2;
3647 } else if (settings.numplayers > 1 && settings.numplayers <= MAXPLAYERS) {
3648 sprintf(modeparm, "-nm:%d", settings.numplayers);
3649 parmc = 1;
3650 }
3651
3652 if (parmc > 0) {
3653 netsuccess = initmultiplayersparms(parmc, parmarr);
3654 }
3655
3656 if (settings.joinhost) {
3657 free(settings.joinhost);
3658 }
3659 }
3660 }
3661 #endif
3662
3663 if (gamegrp) {
3664 Bstrcpy(grpfile, gamegrp->name);
3665 gameeditionname = gamegrp->ref->name; // Points to static data, so won't be lost in FreeGroups().
3666 }
3667
3668 FreeGroups();
3669
3670 buildprintf("GRP file: %s\n", grpfile);
3671 initgroupfile(grpfile);
3672 if (!DetectShareware()) {
3673 if (SW_SHAREWARE) {
3674 buildputs("Detected shareware GRP\n");
3675 } else {
3676 buildputs("Detected registered GRP\n");
3677 }
3678 }
3679
3680 buildputs("\n");
3681 AlphaMessage();
3682 buildputs("\n");
3683
3684 if (SW_SHAREWARE) {
3685 // Zero out the maps that aren't in shareware version
3686 memset(&LevelInfo[MAX_LEVELS_SW+1], 0, sizeof(LEVEL_INFO)*(MAX_LEVELS_REG-MAX_LEVELS_SW));
3687 GameVersion++;
3688 }
3689
3690 for (i = 0; i < MAX_SW_PLAYERS; i++)
3691 INITLIST(&Player[i].PanelSpriteList);
3692
3693 DebugOperate = TRUE;
3694
3695 UserMapName[0] = '\0';
3696
3697 //LocationInfo = TRUE;
3698
3699 #if 0
3700 //#if DEBUG && SYNC_TEST
3701 // automatically record a demo
3702 DemoRecording = TRUE;
3703 DemoPlaying = FALSE;
3704 PreCaching = TRUE;
3705 DemoRecCnt = 0;
3706 strcpy(DemoFileName, "DMOTEST.DMO");
3707 //DemoSyncRecord = TRUE;
3708 #endif
3709
3710 #if DEBUG
3711 {
3712 FILE *fout;
3713 if ((fout = fopen("dbg.foo", "wb")) != NULL)
3714 {
3715 fprintf(fout, "Whoo-oo-ooooo wants some wang?\n");
3716 fclose(fout);
3717 }
3718 }
3719 #endif
3720
3721 for (cnt = 1; cnt < argc; cnt++)
3722 {
3723 char const *arg = argv[cnt];
3724
3725 #ifdef _WIN32
3726 if (*arg != '/' && *arg != '-') continue;
3727 #else
3728 if (*arg != '-') continue;
3729 #endif
3730
3731 // Store arg in command line array!
3732 CON_StoreArg(arg);
3733 arg++;
3734
3735 if (Bstrcasecmp(arg, "net") == 0)
3736 {
3737 for (; i<argc; i++)
3738 if (!strcmp(argv[i], "--")) break;
3739 }
3740 else
3741 if (Bstrncasecmp(arg, "autonet",7) == 0)
3742 {
3743 AutoNet = TRUE;
3744 cnt++;
3745 sscanf(argv[cnt],"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",&Auto.Rules,&Auto.Level,&Auto.Enemy,&Auto.Markers,
3746 &Auto.Team,&Auto.HurtTeam,&Auto.Kill,&Auto.Time,&Auto.Color,&Auto.Nuke);
3747 }
3748 else
3749 if (Bstrncasecmp(arg, "turnscale",9) == 0)
3750 {
3751 if (cnt <= argc-2)
3752 {
3753 cnt++;
3754 sscanf(argv[cnt], "%d",&turn_scale);
3755 }
3756 }
3757 else
3758 if (Bstrncasecmp(arg, "movescale",9) == 0)
3759 {
3760 if (cnt <= argc-2)
3761 {
3762 cnt++;
3763 sscanf(argv[cnt], "%d",&move_scale);
3764 }
3765 }
3766 else
3767 if (Bstrncasecmp(arg, "extcompat",9) == 0)
3768 {
3769 move_scale *= 5;
3770 turn_scale *= 5;
3771 }
3772 else
3773 if (Bstrncasecmp(arg, "cacheprint",10) == 0)
3774 {
3775 CachePrintMode = TRUE;
3776 }
3777 else
3778 if (Bstrncasecmp(arg, "setupfile",8) == 0)
3779 {
3780 // Passed by setup.exe
3781 // skip setupfile name
3782 cnt++;
3783 }
3784 else
3785 if (Bstrncasecmp(arg, "short",5) == 0)
3786 {
3787 ShortGameMode = TRUE;
3788 }
3789 else
3790 if (Bstrncasecmp(arg, "nodemo",6) == 0)
3791 {
3792 NoDemoStartup = TRUE;
3793 }
3794 #if DEBUG
3795 else
3796 if (Bstrncasecmp(arg, "allsync",3) == 0)
3797 {
3798 NumSyncBytes = MAXSYNCBYTES;
3799 }
3800 #endif
3801 else
3802 if (Bstrncasecmp(arg, "name",4) == 0)
3803 {
3804 if (cnt <= argc-2)
3805 {
3806 strncpy(CommPlayerName, argv[++cnt], SIZ(CommPlayerName)-1);
3807 CommPlayerName[SIZ(CommPlayerName)-1] = '\0';
3808 }
3809 }
3810 else
3811 if (Bstrncasecmp(arg, "f8",2) == 0)
3812 {
3813 MovesPerPacket = 8;
3814 }
3815 else
3816 if (Bstrncasecmp(arg, "f4",2) == 0)
3817 {
3818 MovesPerPacket = 4;
3819 }
3820 else
3821 if (Bstrncasecmp(arg, "f2",2) == 0)
3822 {
3823 MovesPerPacket = 2;
3824 }
3825 else
3826 if (Bstrncasecmp(arg, "monst", 5) == 0)
3827 {
3828 DebugActor = TRUE;
3829 }
3830 else
3831 if (Bstrncasecmp(arg, "nopredict",6) == 0)
3832 {
3833 extern BOOL PredictionOn;
3834 PredictionOn = FALSE;
3835 }
3836 else
3837 if (Bstrncasecmp(arg, "col", 3) == 0)
3838 // provides a way to force the player color for joiners
3839 // since -autonet does not seem to work for them
3840 {
3841 int temp;
3842 cnt++;
3843 sscanf(argv[cnt],"%d",&temp);
3844 AutoColor = temp;
3845 HasAutoColor = TRUE;
3846 }
3847 else
3848 if (Bstrncasecmp(arg, "level", 5) == 0)
3849 {
3850 if (strlen(arg) > 5)
3851 {
3852 strcpy(UserMapName,LevelInfo[atoi(&arg[5])].LevelName);
3853 }
3854 }
3855 else
3856 if (Bstrncasecmp(arg, "s", 1) == 0)
3857 {
3858 if (strlen(arg) > 1)
3859 Skill = atoi(&arg[1])-1;
3860
3861 Skill = max(Skill,0);
3862 Skill = min(Skill,3);
3863 }
3864 else
3865 if (Bstrncasecmp(arg, "nometers", 8) == 0)
3866 {
3867 NoMeters = TRUE;
3868 }
3869 else
3870 #if DEBUG
3871 if (Bstrncasecmp(arg, "commbat", 7) == 0)
3872 {
3873 if (strlen(arg) > 7)
3874 {
3875 FakeMultiNumPlayers = atoi(&arg[7]);
3876 gNet.MultiGameType = MULTI_GAME_COMMBAT;
3877 }
3878 }
3879 else
3880 if (Bstrncasecmp(arg, "coop", 4) == 0)
3881 {
3882 if (strlen(arg) > 4)
3883 {
3884 FakeMultiNumPlayers = atoi(&arg[4]);
3885 gNet.MultiGameType = MULTI_GAME_COOPERATIVE;
3886 }
3887 }
3888 else
3889 if (Bstrncasecmp(arg, "bots", 4) == 0)
3890 {
3891 if (strlen(arg) > 4)
3892 {
3893 FakeMultiNumPlayers = atoi(&arg[4]);
3894 printf("Adding %d BOT(s) to the game!\n",FakeMultiNumPlayers);
3895 gNet.MultiGameType = MULTI_GAME_AI_BOTS;
3896 BotMode = TRUE;
3897 }
3898 }
3899 else
3900 if (Bstrncasecmp(arg, "ddr", 3) == 0)
3901 {
3902 //NumSyncBytes = 8;
3903 DemoRecording = TRUE;
3904 DemoPlaying = FALSE;
3905 DemoRecCnt = 0;
3906 DemoDebugMode = TRUE;
3907
3908 if (strlen(arg) > 3)
3909 {
3910 strcpy(DemoFileName, &arg[2]);
3911 if (strchr(DemoFileName, '.') == 0)
3912 strcat(DemoFileName, ".dmo");
3913 }
3914 }
3915 else
3916 #endif
3917 if (Bstrncasecmp(arg, "dr", 2) == 0)
3918 {
3919 //NumSyncBytes = 8;
3920 DemoRecording = TRUE;
3921 DemoPlaying = FALSE;
3922 DemoRecCnt = 0;
3923
3924 if (strlen(arg) > 2)
3925 {
3926 strcpy(DemoFileName, &arg[2]);
3927 if (strchr(DemoFileName, '.') == 0)
3928 strcat(DemoFileName, ".dmo");
3929 }
3930 }
3931 else
3932 if (Bstrncasecmp(arg, "dp", 2) == 0)
3933 {
3934 DemoPlaying = TRUE;
3935 DemoRecording = FALSE;
3936 PreCaching = TRUE;
3937
3938 if (strlen(arg) > 2)
3939 {
3940 strcpy(DemoFileName, &arg[2]);
3941 if (strchr(DemoFileName, '.') == 0)
3942 strcat(DemoFileName, ".dmo");
3943 }
3944 }
3945
3946 #if 0 //def NET_MODE_MASTER_SLAVE
3947 else
3948 if (Bstrncasecmp(arg, "masterslave",6) == 0)
3949 {
3950 NetModeOverride = TRUE;
3951 NetBroadcastMode = FALSE;
3952 }
3953 else
3954 if (Bstrncasecmp(arg, "broadcast",5) == 0)
3955 {
3956 NetModeOverride = TRUE;
3957 NetBroadcastMode = TRUE;
3958 }
3959 #endif
3960
3961 else
3962 if (Bstrncasecmp(arg, "cheat",5) == 0)
3963 {
3964 ArgCheat = TRUE;
3965 }
3966 else
3967 if (Bstrncasecmp(arg, "demosynctest",12) == 0)
3968 {
3969 NumSyncBytes = 8;
3970 DemoSyncTest = TRUE;
3971 DemoSyncRecord = FALSE;
3972 }
3973 else
3974 if (Bstrncasecmp(arg, "demosyncrecord",12) == 0)
3975 {
3976 NumSyncBytes = 8;
3977 DemoSyncTest = FALSE;
3978 DemoSyncRecord = TRUE;
3979 }
3980 #if DEBUG
3981 else
3982 if (Bstrncasecmp(arg, "cam",3) == 0)
3983 {
3984 CameraTestMode = TRUE;
3985 }
3986 else
3987 if (FALSE && Bstrncasecmp(arg, "de", 2) == 0)
3988 {
3989 #if DEMO_FILE_TYPE == DEMO_FILE_GROUP
3990 DemoPlaying = TRUE;
3991 DemoRecording = FALSE;
3992
3993 if (strlen(arg) > 2)
3994 {
3995 strcpy(DemoFileName, &arg[2]);
3996 if (strchr(DemoFileName, '.') == 0)
3997 strcat(DemoFileName, ".dmo");
3998 }
3999 #else
4000 DemoEdit = TRUE;
4001 DemoPlaying = TRUE;
4002 DemoRecording = FALSE;
4003
4004 if (strlen(arg) > 2)
4005 {
4006 strcpy(DemoFileName, &arg[2]);
4007 if (strchr(DemoFileName, '.') == 0)
4008 strcat(DemoFileName, ".dmo");
4009 }
4010 #endif
4011 }
4012 else
4013 if (Bstrncasecmp(arg, "randprint",5) == 0)
4014 {
4015 RandomPrint = TRUE;
4016 }
4017 else
4018 if (Bstrncasecmp(arg, "level", 5) == 0)
4019 {
4020 if (strlen(arg) > 5)
4021 {
4022 strcpy(UserMapName,LevelInfo[atoi(&arg[5])].LevelName);
4023 }
4024 }
4025 else
4026 if (Bstrncasecmp(arg, "debugsecret", 10) == 0)
4027 {
4028 extern BOOL DebugSecret;
4029 DebugSecret = TRUE;
4030 }
4031 else
4032 if (Bstrncasecmp(arg, "debugactor", 10) == 0)
4033 {
4034 DebugActor = TRUE;
4035 }
4036 else
4037 if (Bstrncasecmp(arg, "mono", 4) == 0)
4038 {
4039 DispMono = TRUE;
4040 }
4041 else
4042 if (Bstrncasecmp(arg, "debugso", 7) == 0)
4043 {
4044 DebugSO = TRUE;
4045 }
4046 else
4047 if (Bstrncasecmp(arg, "nosyncprint",10) == 0)
4048 {
4049 extern BOOL SyncPrintMode;
4050 SyncPrintMode = FALSE;
4051 }
4052 else
4053 if (Bstrncasecmp(arg, "debuganim", 9) == 0)
4054 {
4055 DebugAnim = TRUE;
4056 }
4057 else
4058 if (Bstrncasecmp(arg, "debugsector", 11) == 0)
4059 {
4060 DebugSector = TRUE;
4061 }
4062 else
4063 if (Bstrncasecmp(arg, "debugpanel", 10) == 0)
4064 {
4065 DebugPanel = TRUE;
4066 }
4067 else
4068 if (FALSE && Bstrncasecmp(arg, "dt", 2) == 0)
4069 {
4070 if (strlen(arg) > 2)
4071 {
4072 strcpy(DemoTmpName, &arg[2]);
4073 if (strchr(DemoFileName, '.') == 0)
4074 strcat(DemoFileName, ".dmo");
4075 }
4076 }
4077 else
4078 if (Bstrncasecmp(arg, "nodemo", 6) == 0)
4079 {
4080 DemoRecording = FALSE;
4081 DemoPlaying = FALSE;
4082 PreCaching = TRUE;
4083 DemoRecCnt = 0;
4084
4085 DemoSyncTest = FALSE;
4086 DemoSyncRecord = FALSE;
4087 }
4088 #endif
4089
4090 else
4091 if (Bstrncasecmp(arg, "map", 3) == 0)
4092 {
4093 int fil;
4094
4095 strcpy(UserMapName, argv[++cnt]);
4096 if (strchr(UserMapName, '.') == 0)
4097 strcat(UserMapName, ".map");
4098
4099 if ((fil = kopen4load(UserMapName,0)) == -1)
4100 {
4101 kclose(fil);
4102 wm_msgbox(NULL, "ERROR: Could not find user map %s!",UserMapName);
4103 swexit(0);
4104 }
4105 else
4106 kclose(fil);
4107 }
4108
4109 else
4110 if (Bstrncasecmp(arg, "g", 1) == 0)
4111 {
4112 if (strlen(arg) > 1)
4113 {
4114 if (initgroupfile(arg+1) >= 0)
4115 buildprintf("Added %s\n", arg+1);
4116 }
4117 }
4118 else
4119 if (Bstrncasecmp(arg, "h", 1) == 0)
4120 {
4121 if (strlen(arg) > 1)
4122 {
4123 deffile = (arg+1);
4124 buildprintf("Using DEF file %s.\n", arg+1);
4125 }
4126 }
4127 }
4128
4129 Control();
4130
4131 return (0);
4132 }
4133
4134 VOID
ManualPlayerInsert(PLAYERp pp)4135 ManualPlayerInsert(PLAYERp pp)
4136 {
4137 PLAYERp npp = Player + numplayers;
4138 int i;
4139
4140 if (numplayers < MAX_SW_PLAYERS)
4141 {
4142 connectpoint2[numplayers - 1] = numplayers;
4143 connectpoint2[numplayers] = -1;
4144
4145 npp->posx = pp->posx;
4146 npp->posy = pp->posy;
4147 npp->posz = pp->posz;
4148 npp->pang = pp->pang;
4149 npp->cursectnum = pp->cursectnum;
4150
4151 myconnectindex = numplayers;
4152 screenpeek = numplayers;
4153
4154 sprintf(Player[myconnectindex].PlayerName,"PLAYER %d",myconnectindex+1);
4155
4156 Player[numplayers].movefifoend = Player[0].movefifoend;
4157
4158 // If IsAI = TRUE, new player will be a bot
4159 Player[myconnectindex].IsAI = FALSE;
4160
4161 CommPlayers++;
4162 numplayers++;
4163 }
4164
4165 }
4166
4167 VOID
BotPlayerInsert(PLAYERp pp)4168 BotPlayerInsert(PLAYERp pp)
4169 {
4170 PLAYERp npp = Player + numplayers;
4171 int i;
4172
4173 if (numplayers < MAX_SW_PLAYERS)
4174 {
4175 connectpoint2[numplayers - 1] = numplayers;
4176 connectpoint2[numplayers] = -1;
4177
4178 npp->posx = pp->posx;
4179 npp->posy = pp->posy;
4180 npp->posz = pp->posz-Z(100);
4181 npp->pang = pp->pang;
4182 npp->cursectnum = pp->cursectnum;
4183
4184 //myconnectindex = numplayers;
4185 //screenpeek = numplayers;
4186
4187 sprintf(Player[numplayers].PlayerName,"BOT %d",numplayers+1);
4188
4189 Player[numplayers].movefifoend = Player[0].movefifoend;
4190
4191 // If IsAI = TRUE, new player will be a bot
4192 Player[numplayers].IsAI = TRUE;
4193
4194 CommPlayers++;
4195 numplayers++;
4196 }
4197
4198 // SetFragBar(pp);
4199 }
4200
4201 VOID
ManualPlayerDelete(PLAYERp cur_pp)4202 ManualPlayerDelete(PLAYERp cur_pp)
4203 {
4204 short i, nexti;
4205 USERp u;
4206 short save_myconnectindex;
4207 PLAYERp pp;
4208
4209 if (numplayers > 1)
4210 {
4211 CommPlayers--;
4212 numplayers--;
4213 connectpoint2[numplayers - 1] = -1;
4214
4215 pp = Player + numplayers;
4216
4217 KillSprite(pp->PlayerSprite);
4218 pp->PlayerSprite = -1;
4219
4220 // Make sure enemys "forget" about deleted player
4221 TRAVERSE_SPRITE_STAT(headspritestat[STAT_ENEMY], i, nexti)
4222 {
4223 u = User[i];
4224 if (u->tgt_sp == pp->SpriteP)
4225 u->tgt_sp = Player[0].SpriteP;
4226 }
4227
4228 if (myconnectindex >= numplayers)
4229 myconnectindex = 0;
4230
4231 if (screenpeek >= numplayers)
4232 screenpeek = 0;
4233 }
4234 }
4235
4236 #if DEBUG
4237 VOID
SinglePlayInput(PLAYERp pp)4238 SinglePlayInput(PLAYERp pp)
4239 {
4240 int pnum = myconnectindex;
4241 BYTEp kp;
4242
4243 if (BUTTON(gamefunc_See_Co_Op_View) && !UsingMenus && !ConPanel && dimensionmode == 3)
4244 {
4245 short oldscreenpeek = screenpeek;
4246
4247 CONTROL_ClearButton(gamefunc_See_Co_Op_View);
4248 NextScreenPeek();
4249
4250 if (dimensionmode == 2 || dimensionmode == 5 || dimensionmode == 6)
4251 setup2dscreen();
4252
4253 if (dimensionmode != 2)
4254 {
4255 PLAYERp tp;
4256
4257 tp = Player + screenpeek;
4258 PlayerUpdatePanelInfo(tp);
4259 if (getrendermode() < 3)
4260 COVERsetbrightness(gs.Brightness,(char *)palette_data);
4261 else
4262 setpalettefade(0,0,0,0);
4263 memcpy(pp->temp_pal, palette_data, sizeof(palette_data));
4264 DoPlayerDivePalette(tp);
4265 DoPlayerNightVisionPalette(tp);
4266 // printf("SingPlayInput set_pal: tp->PlayerSprite = %d\n",tp->PlayerSprite);
4267 }
4268 }
4269
4270 if (!(KEY_PRESSED(KEYSC_ALT) | KEY_PRESSED(KEYSC_RALT)))
4271 return;
4272
4273
4274 if (!SW_SHAREWARE && KEY_PRESSED(KEYSC_M))
4275 {
4276 extern BOOL DebugActorFreeze;
4277
4278 KEY_PRESSED(KEYSC_M) = 0;
4279 DebugActorFreeze++;
4280 if (DebugActorFreeze > 2)
4281 DebugActorFreeze = 0;
4282
4283 if (DebugActorFreeze == 2)
4284 {
4285 short i, nexti;
4286
4287 TRAVERSE_SPRITE_STAT(headspritestat[STAT_ENEMY], i, nexti)
4288 {
4289 SET(sprite[i].cstat, CSTAT_SPRITE_INVISIBLE);
4290 if (TEST(sprite[i].cstat, CSTAT_SPRITE_BLOCK))
4291 {
4292 SET(sprite[i].extra, SPRX_BLOCK);
4293 RESET(sprite[i].cstat, CSTAT_SPRITE_BLOCK);
4294 }
4295 }
4296 }
4297
4298 if (DebugActorFreeze == 0)
4299 {
4300 short i, nexti;
4301
4302 TRAVERSE_SPRITE_STAT(headspritestat[STAT_ENEMY], i, nexti)
4303 {
4304 RESET(sprite[i].cstat, CSTAT_SPRITE_INVISIBLE);
4305 if (TEST(sprite[i].extra, SPRX_BLOCK))
4306 SET(sprite[i].cstat, CSTAT_SPRITE_BLOCK);
4307 }
4308 }
4309 }
4310
4311
4312 // Insert a player
4313 if (KEY_PRESSED(KEYSC_INS))
4314 // player
4315 {
4316 KEY_PRESSED(KEYSC_INS) = 0;
4317 ManualPlayerInsert(pp);
4318 // comes back looking through screenpeek
4319 InitPlayerSprite(Player + screenpeek);
4320 PlayerDeathReset(Player + screenpeek);
4321 SetFragBar(pp);
4322 }
4323
4324
4325 // Delete a player
4326 if (KEY_PRESSED(KEYSC_DEL))
4327 {
4328 KEY_PRESSED(KEYSC_DEL) = 0;
4329 ManualPlayerDelete(pp);
4330 }
4331
4332 // Move control to numbered player
4333
4334 if ((kp = KeyPressedRange(&KEY_PRESSED(KEYSC_1), &KEY_PRESSED(KEYSC_9))) && CommPlayers > 1)
4335 {
4336 short save_myconnectindex;
4337
4338 save_myconnectindex = myconnectindex;
4339
4340 myconnectindex = (intptr_t)kp - (intptr_t)(&KEY_PRESSED(KEYSC_1));
4341
4342 if (myconnectindex >= CommPlayers)
4343 myconnectindex = save_myconnectindex;
4344
4345 screenpeek = myconnectindex;
4346
4347 DoPlayerDivePalette(pp);
4348
4349 // Now check for item or pain palette stuff
4350 // This sets the palette to whatever it is of the player you
4351 // just chose to view the game through.
4352 // printf("SingPlayInput ALT+1-9 set_pal: pp->PlayerSprite = %d\n",pp->PlayerSprite);
4353 COVERsetbrightness(gs.Brightness,(char *)palette_data); // JBF: figure out what's going on here
4354
4355 DoPlayerNightVisionPalette(pp);
4356
4357 ResetKeyRange(&KEY_PRESSED(KEYSC_1), &KEY_PRESSED(KEYSC_9));
4358 }
4359
4360 #if 0
4361 if (KEY_PRESSED(KEYSC_T))
4362 {
4363 KEY_PRESSED(KEYSC_T) = 0;
4364 PlayerTrackingMode ^= 1;
4365 }
4366 #endif
4367
4368 if (KEY_PRESSED(KEYSC_H))
4369 {
4370 short pnum;
4371
4372 KEY_PRESSED(KEYSC_H) = 0;
4373
4374 TRAVERSE_CONNECT(pnum)
4375 {
4376 User[Player[pnum].PlayerSprite]->Health = 100;
4377 }
4378 }
4379 }
4380
4381 VOID
DebugKeys(PLAYERp pp)4382 DebugKeys(PLAYERp pp)
4383 {
4384 short w, h;
4385
4386 if (!(KEY_PRESSED(KEYSC_ALT) || KEY_PRESSED(KEYSC_RALT)))
4387 return;
4388
4389 if (InputMode)
4390 return;
4391
4392 if (CommEnabled)
4393 return;
4394
4395 //
4396 // visiblity adjust
4397 //
4398
4399 if (KEY_PRESSED(KEYSC_L) > 0)
4400 {
4401 if (KEY_PRESSED(KEYSC_LSHIFT) | KEY_PRESSED(KEYSC_RSHIFT)) // SHIFT
4402 {
4403 visibility = visibility - (visibility >> 3);
4404
4405 if (visibility < 128)
4406 visibility = 16348;
4407
4408 //if (visibility > 16384)
4409 // visibility = 128;
4410 }
4411 else
4412 {
4413 KEY_PRESSED(KEYSC_L) = 0;
4414
4415 visibility = visibility - (visibility >> 3);
4416
4417 if (visibility > 16384)
4418 visibility = 128;
4419 }
4420 }
4421
4422 //
4423 // parallax changes
4424 //
4425
4426 if (KEY_PRESSED(KEYSC_X))
4427 {
4428 if (KEY_PRESSED(KEYSC_LSHIFT))
4429 {
4430 KEY_PRESSED(KEYSC_LSHIFT) = FALSE;
4431 KEY_PRESSED(KEYSC_X) = 0;
4432
4433 parallaxyoffs += 10;
4434
4435 if (parallaxyoffs > 100)
4436 parallaxyoffs = 0;
4437 }
4438 else
4439 {
4440 KEY_PRESSED(KEYSC_X) = 0;
4441 parallaxtype++;
4442 if (parallaxtype > 2)
4443 parallaxtype = 0;
4444 }
4445 }
4446 }
4447
4448 #endif
4449
4450 VOID
ConKey(void)4451 ConKey( void )
4452 {
4453 #if DEBUG
4454 // Console Input Panel
4455 if (!ConPanel && dimensionmode == 3)
4456 {
4457 //if (KEY_PRESSED(KEYSC_TILDE) && KEY_PRESSED(KEYSC_LSHIFT))
4458 if (KEY_PRESSED(KEYSC_TILDE))
4459 {
4460 KEY_PRESSED(KEYSC_TILDE) = FALSE;
4461 //KEY_PRESSED(KEYSC_LSHIFT) = FALSE;
4462 KB_FlushKeyboardQueue();
4463 ConPanel = TRUE;
4464 InputMode = TRUE;
4465 ConInputMode = TRUE;
4466 if (!CommEnabled)
4467 GamePaused = TRUE;
4468 memset(MessageInputString, '\0', sizeof(MessageInputString));
4469 }
4470 }
4471 else
4472 if (ConPanel)
4473 {
4474 //if (KEY_PRESSED(KEYSC_TILDE) && KEY_PRESSED(KEYSC_LSHIFT))
4475 if (KEY_PRESSED(KEYSC_TILDE))
4476 {
4477 KEY_PRESSED(KEYSC_TILDE) = FALSE;
4478 //KEY_PRESSED(KEYSC_LSHIFT) = FALSE;
4479 KB_FlushKeyboardQueue();
4480 ConPanel = FALSE;
4481 ConInputMode = FALSE;
4482 InputMode = FALSE;
4483 if (!CommEnabled)
4484 GamePaused = FALSE;
4485 memset(MessageInputString, '\0', sizeof(MessageInputString));
4486 SetFragBar(Player + myconnectindex);
4487 }
4488 }
4489 #endif
4490 }
4491
4492 char WangBangMacro[10][64];
4493
4494 VOID
FunctionKeys(PLAYERp pp)4495 FunctionKeys(PLAYERp pp)
4496 {
4497 extern BOOL GamePaused;
4498 extern short QuickLoadNum;
4499 static int rts_delay = 0;
4500 int fn_key = 0;
4501
4502 rts_delay++;
4503
4504 if (KEY_PRESSED(sc_F1)) { fn_key = 1; }
4505 if (KEY_PRESSED(sc_F2)) { fn_key = 2; }
4506 if (KEY_PRESSED(sc_F3)) { fn_key = 3; }
4507 if (KEY_PRESSED(sc_F4)) { fn_key = 4; }
4508 if (KEY_PRESSED(sc_F5)) { fn_key = 5; }
4509 if (KEY_PRESSED(sc_F6)) { fn_key = 6; }
4510 if (KEY_PRESSED(sc_F7)) { fn_key = 7; }
4511 if (KEY_PRESSED(sc_F8)) { fn_key = 8; }
4512 if (KEY_PRESSED(sc_F9)) { fn_key = 9; }
4513 if (KEY_PRESSED(sc_F10)) { fn_key = 10; }
4514
4515 if (KEY_PRESSED(KEYSC_ALT) || KEY_PRESSED(KEYSC_RALT))
4516 {
4517 if (rts_delay > 16 && fn_key && CommEnabled && !gs.ParentalLock && !Global_PLock)
4518 {
4519 KEY_PRESSED(sc_F1 + fn_key - 1) = 0;
4520
4521 rts_delay = 0;
4522
4523 PlaySoundRTS(fn_key);
4524
4525 if (CommEnabled)
4526 {
4527 short pnum;
4528 PACKET_RTS p;
4529
4530 p.PacketType = PACKET_TYPE_RTS;
4531 p.RTSnum = fn_key;
4532
4533 netbroadcastpacket((BYTEp)(&p), sizeof(p)); // TENSW
4534 }
4535 }
4536
4537 return;
4538 }
4539
4540 if (KEY_PRESSED(KEYSC_LSHIFT) || KEY_PRESSED(KEYSC_RSHIFT))
4541 {
4542 if (fn_key && CommEnabled)
4543 {
4544 KEY_PRESSED(sc_F1 + fn_key - 1) = 0;
4545
4546 if (CommEnabled)
4547 {
4548 short pnum;
4549
4550 sprintf(ds,"SENT: %s",WangBangMacro[fn_key-1]);
4551 adduserquote(ds);
4552
4553 TRAVERSE_CONNECT(pnum)
4554 {
4555 if (pnum != myconnectindex)
4556 {
4557 sprintf(ds,"%s: %s",pp->PlayerName, WangBangMacro[fn_key-1]);
4558 SendMessage(pnum, ds);
4559 }
4560 }
4561 }
4562 }
4563
4564 return;
4565 }
4566
4567
4568 if (CommPlayers <= 1)
4569 {
4570 // F2 save menu
4571 if (KEY_PRESSED(KEYSC_F2))
4572 {
4573 KEY_PRESSED(KEYSC_F2) = 0;
4574 if (!TEST(pp->Flags, PF_DEAD))
4575 {
4576 ForceMenus = TRUE;
4577 ControlPanelType = ct_savemenu;
4578 }
4579 }
4580
4581 // F3 load menu
4582 if (KEY_PRESSED(KEYSC_F3))
4583 {
4584 KEY_PRESSED(KEYSC_F3) = 0;
4585 if (!TEST(pp->Flags, PF_DEAD))
4586 {
4587 ForceMenus = TRUE;
4588 ControlPanelType = ct_loadmenu;
4589 }
4590 }
4591
4592 // F6 option menu
4593 if (KEY_PRESSED(KEYSC_F6))
4594 {
4595 extern BOOL QuickSaveMode;
4596 KEY_PRESSED(KEYSC_F6) = 0;
4597 if (!TEST(pp->Flags, PF_DEAD))
4598 {
4599 ForceMenus = TRUE;
4600 ControlPanelType = ct_savemenu;
4601 QuickSaveMode = TRUE;
4602 }
4603 }
4604
4605 // F9 quick load
4606 if (KEY_PRESSED(KEYSC_F9))
4607 {
4608 KEY_PRESSED(KEYSC_F9) = 0;
4609
4610 if (!TEST(pp->Flags, PF_DEAD))
4611 {
4612 if (QuickLoadNum < 0)
4613 {
4614 PutStringInfoLine(pp, "Last saved game not found.");
4615 }
4616 else
4617 {
4618 KB_ClearKeysDown();
4619 ForceMenus = TRUE;
4620 ControlPanelType = ct_quickloadmenu;
4621 }
4622 }
4623 }
4624
4625 }
4626
4627
4628 // F4 sound menu
4629 if (KEY_PRESSED(KEYSC_F4))
4630 {
4631 KEY_PRESSED(KEYSC_F4) = 0;
4632 ForceMenus = TRUE;
4633 ControlPanelType = ct_soundmenu;
4634 }
4635
4636
4637 // F7 VIEW control
4638 if (KEY_PRESSED(KEYSC_F7))
4639 {
4640 KEY_PRESSED(KEYSC_F7) = 0;
4641
4642 if (KEY_PRESSED(KEYSC_LSHIFT) || KEY_PRESSED(KEYSC_RSHIFT))
4643 {
4644 if (TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE))
4645 pp->view_outside_dang = NORM_ANGLE(pp->view_outside_dang + 256);
4646 }
4647 else
4648 {
4649 if (TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE))
4650 {
4651 RESET(pp->Flags, PF_VIEW_FROM_OUTSIDE);
4652 }
4653 else
4654 {
4655 SET(pp->Flags, PF_VIEW_FROM_OUTSIDE);
4656 pp->camera_dist = 0;
4657 }
4658 }
4659 }
4660
4661 // F8 toggle messages
4662 if (KEY_PRESSED(KEYSC_F8))
4663 {
4664 KEY_PRESSED(KEYSC_F8) = 0;
4665
4666 gs.Messages ^= 1;
4667
4668 if (gs.Messages)
4669 PutStringInfoLine(pp, "Messages ON");
4670 else
4671 PutStringInfoLine(pp, "Messages OFF");
4672 }
4673
4674 // F10 quit menu
4675 if (KEY_PRESSED(KEYSC_F10))
4676 {
4677 KEY_PRESSED(KEYSC_F10) = 0;
4678 ForceMenus = TRUE;
4679 ControlPanelType = ct_quitmenu;
4680 }
4681
4682 // F11 gamma correction
4683 if (KEY_PRESSED(KEYSC_F11) > 0)
4684 {
4685 KEY_PRESSED(KEYSC_F11) = 0;
4686
4687 gs.Brightness++;
4688 if (gs.Brightness >= SLDR_BRIGHTNESSMAX)
4689 gs.Brightness = 0;
4690
4691 sprintf(ds,"Brightness level (%d)",gs.Brightness+1);
4692 PutStringInfoLine(pp, ds);
4693
4694 if(!pp->NightVision && pp->FadeAmt <= 0)
4695 {
4696 COVERsetbrightness(gs.Brightness,&palette_data[0][0]);
4697 }
4698
4699 //DoPlayerDivePalette(pp);
4700 //DoPlayerNightVisionPalette(pp);
4701 }
4702
4703 }
4704
PauseKey(PLAYERp pp)4705 VOID PauseKey(PLAYERp pp)
4706 {
4707 extern BOOL GamePaused,CheatInputMode;
4708 extern short QuickLoadNum;
4709 extern BOOL enabled;
4710
4711 if (KEY_PRESSED(sc_Pause) && !CommEnabled && !InputMode && !UsingMenus && !CheatInputMode && !ConPanel)
4712 {
4713 KEY_PRESSED(sc_Pause) = 0;
4714
4715 PauseKeySet ^= 1;
4716
4717 if (PauseKeySet)
4718 GamePaused = TRUE;
4719 else
4720 GamePaused = FALSE;
4721
4722 if (GamePaused)
4723 {
4724 short w,h;
4725 #define MSG_GAME_PAUSED "Game Paused"
4726 MNU_MeasureString(MSG_GAME_PAUSED, &w, &h);
4727 PutStringTimer(pp, TEXT_TEST_COL(w), 100, MSG_GAME_PAUSED, 999);
4728 PauseSong(TRUE);
4729 }
4730 else
4731 {
4732 pClearTextLine(pp, 100);
4733 PauseSong(FALSE);
4734 }
4735 }
4736
4737 if (!CommEnabled && TEST(pp->Flags, PF_DEAD))
4738 {
4739 if (ReloadPrompt)
4740 {
4741 if (QuickLoadNum < 0)
4742 {
4743 ReloadPrompt = FALSE;
4744 }
4745 else
4746 {
4747 ForceMenus = TRUE;
4748 ControlPanelType = ct_quickloadmenu;
4749 }
4750 }
4751 }
4752 }
4753
4754
4755
GetMessageInput(PLAYERp pp)4756 VOID GetMessageInput(PLAYERp pp)
4757 {
4758 int pnum = myconnectindex;
4759 short w,h;
4760 signed char MNU_InputSmallString(char *, short);
4761 signed char MNU_InputString(char *, short);
4762 static BOOL cur_show;
4763 static BOOL TeamSendAll, TeamSendTeam;
4764 #define TEAM_MENU "A - Send to ALL, T - Send to TEAM"
4765 static char HoldMessageInputString[256];
4766 int i;
4767 BOOL IsCommand(char *str);
4768
4769 if (!MessageInputMode && !ConInputMode)
4770 {
4771 if (BUTTON(gamefunc_SendMessage))
4772 {
4773 CONTROL_ClearButton(gamefunc_SendMessage);
4774 KB_FlushKeyboardQueue();
4775 MessageInputMode = TRUE;
4776 InputMode = TRUE;
4777 TeamSendTeam = FALSE;
4778 TeamSendAll = FALSE;
4779
4780 if (MessageInputMode)
4781 {
4782 memset(MessageInputString, '\0', sizeof(MessageInputString));
4783 }
4784 }
4785 }
4786 else
4787 if (MessageInputMode && !ConInputMode)
4788 {
4789 if (gs.BorderNum > BORDER_BAR+1)
4790 SetRedrawScreen(pp);
4791
4792 // get input
4793 switch(MNU_InputSmallString(MessageInputString, 320-20))
4794 {
4795 case -1: // Cancel Input (pressed ESC) or Err
4796 MessageInputMode = FALSE;
4797 InputMode = FALSE;
4798 KB_ClearKeysDown();
4799 KB_FlushKeyboardQueue();
4800 break;
4801 case FALSE: // Input finished (RETURN)
4802 if (MessageInputString[0] == '\0')
4803 {
4804 // no input
4805 MessageInputMode = FALSE;
4806 InputMode = FALSE;
4807 KB_ClearKeysDown();
4808 KB_FlushKeyboardQueue();
4809 CONTROL_ClearButton(gamefunc_Inventory);
4810 }
4811 else
4812 {
4813 if (gNet.TeamPlay)
4814 {
4815 if (memcmp(MessageInputString, TEAM_MENU, sizeof(TEAM_MENU)) != 0)
4816 {
4817 // see if its a command
4818 if (IsCommand(MessageInputString))
4819 {
4820 TeamSendAll = TRUE;
4821 }
4822 else
4823 {
4824 strcpy(HoldMessageInputString, MessageInputString);
4825 strcpy(MessageInputString, TEAM_MENU);
4826 break;
4827 }
4828 }
4829 else
4830 if (memcmp(MessageInputString, TEAM_MENU, sizeof(TEAM_MENU)) == 0)
4831 {
4832 strcpy(MessageInputString, HoldMessageInputString);
4833 TeamSendAll = TRUE;
4834 }
4835 }
4836
4837 SEND_MESSAGE:
4838
4839 // broadcast message
4840 MessageInputMode = FALSE;
4841 InputMode = FALSE;
4842 KB_ClearKeysDown();
4843 KB_FlushKeyboardQueue();
4844 CONTROL_ClearButton(gamefunc_Inventory);
4845 CON_ProcessUserCommand(); // Check to see if it's a cheat or command
4846
4847 for (i = 0; i < NUMGAMEFUNCTIONS; i++)
4848 CONTROL_ClearButton(i);
4849
4850 // Put who sent this
4851 sprintf(ds,"%s: %s",pp->PlayerName,MessageInputString);
4852
4853 if (gNet.TeamPlay)
4854 {
4855 TRAVERSE_CONNECT(pnum)
4856 {
4857 if (pnum != myconnectindex)
4858 {
4859 if (TeamSendAll)
4860 SendMessage(pnum, ds);
4861 else
4862 if (User[pp->PlayerSprite]->spal == User[Player[pnum].PlayerSprite]->spal)
4863 SendMessage(pnum, ds);
4864 }
4865 }
4866 }
4867 else
4868 TRAVERSE_CONNECT(pnum)
4869 {
4870 if (pnum != myconnectindex)
4871 {
4872 SendMessage(pnum, ds);
4873 }
4874 }
4875 adduserquote(MessageInputString);
4876 quotebot += 8;
4877 quotebotgoal = quotebot;
4878 }
4879 break;
4880
4881 case TRUE: // Got input
4882
4883 if (gNet.TeamPlay)
4884 {
4885 if (memcmp(MessageInputString, TEAM_MENU"a", sizeof(TEAM_MENU)+1) == 0)
4886 {
4887 strcpy(MessageInputString, HoldMessageInputString);
4888 TeamSendAll = TRUE;
4889 goto SEND_MESSAGE;
4890 }
4891 else
4892 if (memcmp(MessageInputString, TEAM_MENU"t", sizeof(TEAM_MENU)+1) == 0)
4893 {
4894 strcpy(MessageInputString, HoldMessageInputString);
4895 TeamSendTeam = TRUE;
4896 goto SEND_MESSAGE;
4897 }
4898 else
4899 {
4900 // reset the string if anything else is typed
4901 if (strlen(MessageInputString)+1 > sizeof(TEAM_MENU))
4902 {
4903 strcpy(MessageInputString, TEAM_MENU);
4904 }
4905 }
4906 }
4907
4908 break;
4909 }
4910 }
4911 }
4912
GetConInput(PLAYERp pp)4913 VOID GetConInput(PLAYERp pp)
4914 {
4915 int pnum = myconnectindex;
4916 short w,h;
4917 signed char MNU_InputSmallString(char *, short);
4918 signed char MNU_InputString(char *, short);
4919 static BOOL cur_show;
4920
4921 if (MessageInputMode || HelpInputMode)
4922 return;
4923
4924 ConKey();
4925
4926 // Console input commands
4927 if (ConInputMode && !MessageInputMode)
4928 {
4929 // get input
4930 switch(MNU_InputSmallString(MessageInputString, 250))
4931 {
4932 case -1: // Cancel Input (pressed ESC) or Err
4933 InputMode = FALSE;
4934 KB_ClearKeysDown();
4935 KB_FlushKeyboardQueue();
4936 memset(MessageInputString, '\0', sizeof(MessageInputString));
4937 break;
4938 case FALSE: // Input finished (RETURN)
4939 if (MessageInputString[0] == '\0')
4940 {
4941 InputMode = FALSE;
4942 KB_ClearKeysDown();
4943 KB_FlushKeyboardQueue();
4944 CONTROL_ClearButton(gamefunc_Inventory);
4945 memset(MessageInputString, '\0', sizeof(MessageInputString));
4946 }
4947 else
4948 {
4949 InputMode = FALSE;
4950 KB_ClearKeysDown();
4951 KB_FlushKeyboardQueue();
4952 CONTROL_ClearButton(gamefunc_Inventory);
4953 CON_ConMessage("%s", MessageInputString);
4954 CON_ProcessUserCommand(); // Check to see if it's a cheat or command
4955
4956 conbot += 6;
4957 conbotgoal = conbot;
4958 //addconquote(MessageInputString);
4959 // Clear it out after every entry
4960 memset(MessageInputString, '\0', sizeof(MessageInputString));
4961 }
4962 break;
4963 case TRUE: // Got input
4964 break;
4965 }
4966 }
4967 }
4968
4969
GetHelpInput(PLAYERp pp)4970 VOID GetHelpInput(PLAYERp pp)
4971 {
4972 extern BOOL GamePaused;
4973
4974 if (KEY_PRESSED(KEYSC_ALT) || KEY_PRESSED(KEYSC_RALT))
4975 return;
4976
4977 if (KEY_PRESSED(KEYSC_LSHIFT) || KEY_PRESSED(KEYSC_RSHIFT))
4978 return;
4979
4980 if (MessageInputMode || ConInputMode)
4981 return;
4982
4983 // F1 help menu
4984 if (!HelpInputMode)
4985 {
4986 if (KEY_PRESSED(KEYSC_F1))
4987 {
4988 KEY_PRESSED(KEYSC_F1) = FALSE;
4989 HelpPage = 0;
4990 HelpInputMode = TRUE;
4991 PanelUpdateMode = FALSE;
4992 InputMode = TRUE;
4993 if (!CommEnabled)
4994 GamePaused = TRUE;
4995 }
4996 }
4997 else
4998 if (HelpInputMode)
4999 {
5000 if (KEY_PRESSED(KEYSC_ESC))
5001 {
5002 KEY_PRESSED(KEYSC_ESC) = 0;
5003 KB_ClearKeysDown();
5004 PanelUpdateMode = TRUE;
5005 HelpInputMode = FALSE;
5006 InputMode = FALSE;
5007 if (!CommEnabled)
5008 GamePaused = FALSE;
5009 SetRedrawScreen(pp);
5010 }
5011
5012 if (KEY_PRESSED(KEYSC_SPACE) || KEY_PRESSED(KEYSC_ENTER) || KEY_PRESSED(KEYSC_PGDN) || KEY_PRESSED(KEYSC_DOWN) || KEY_PRESSED(KEYSC_RIGHT) || KEY_PRESSED(sc_kpad_3) || KEY_PRESSED(sc_kpad_2) || KEY_PRESSED(sc_kpad_6))
5013 {
5014 KEY_PRESSED(KEYSC_SPACE) = KEY_PRESSED(KEYSC_ENTER) = 0;
5015 KEY_PRESSED(KEYSC_PGDN) = 0;
5016 KEY_PRESSED(KEYSC_DOWN) = 0;
5017 KEY_PRESSED(KEYSC_RIGHT) = 0;
5018 KEY_PRESSED(sc_kpad_3) = 0;
5019 KEY_PRESSED(sc_kpad_2) = 0;
5020 KEY_PRESSED(sc_kpad_6) = 0;
5021
5022 HelpPage++;
5023 if (HelpPage >= (int)SIZ(HelpPagePic))
5024 // CTW MODIFICATION
5025 // "Oops! I did it again..."
5026 // HelpPage = SIZ(HelpPagePic) - 1;
5027 HelpPage = 0;
5028 // CTW MODIFICATION END
5029 }
5030
5031 if (KEY_PRESSED(KEYSC_PGUP) || KEY_PRESSED(KEYSC_UP) || KEY_PRESSED(KEYSC_LEFT) || KEY_PRESSED(sc_kpad_9) || KEY_PRESSED(sc_kpad_8) || KEY_PRESSED(sc_kpad_4))
5032 {
5033 KEY_PRESSED(KEYSC_PGUP) = 0;
5034 KEY_PRESSED(KEYSC_UP) = 0;
5035 KEY_PRESSED(KEYSC_LEFT) = 0;
5036 KEY_PRESSED(sc_kpad_8) = 0;
5037 KEY_PRESSED(sc_kpad_9) = 0;
5038 KEY_PRESSED(sc_kpad_4) = 0;
5039
5040 HelpPage--;
5041 if (HelpPage < 0)
5042 // CTW MODIFICATION
5043 // "Played with the logic, got lost in the game..."
5044 HelpPage = SIZ(HelpPagePic) - 1;
5045 // CTW MODIFICATION END
5046 }
5047 }
5048 }
5049
5050 short MirrorDelay;
5051 int MouseYAxisMode = -1;
5052
5053 VOID
getinput(SW_PACKET * loc)5054 getinput(SW_PACKET *loc)
5055 {
5056 BOOL found = FALSE;
5057 int i;
5058 PLAYERp pp = Player + myconnectindex;
5059 PLAYERp newpp = Player + myconnectindex;
5060 int pnum = myconnectindex;
5061 int inv_hotkey = 0;
5062
5063 #define TURBOTURNTIME (120/8)
5064 #define NORMALTURN (12+6)
5065 #define RUNTURN (28)
5066 #define PREAMBLETURN 3
5067 #define NORMALKEYMOVE 35
5068 #define MAXVEL ((NORMALKEYMOVE*2)+10)
5069 #define MAXSVEL ((NORMALKEYMOVE*2)+10)
5070 #define MAXANGVEL 100
5071 #define SET_LOC_KEY(loc, sync_num, key_test) SET(loc, ((!!(key_test)) << (sync_num)))
5072
5073 ControlInfo info;
5074 boolean running;
5075 int32 turnamount;
5076 static int32 turnheldtime;
5077 int32 keymove;
5078 int32 momx, momy;
5079 int aimvel;
5080 int mouseaxis;
5081
5082 extern BOOL MenuButtonAutoRun;
5083 extern BOOL MenuButtonAutoAim;
5084
5085 if (Prediction && CommEnabled)
5086 {
5087 newpp = ppp;
5088 }
5089
5090 // reset all syncbits
5091 loc->bits = 0;
5092 svel = vel = angvel = aimvel = 0;
5093
5094 // MAKE SURE THIS WILL GET SET
5095 SET_LOC_KEY(loc->bits, SK_QUIT_GAME, MultiPlayQuitFlag);
5096
5097 if (gs.MouseAimingType == 1) // while held
5098 {
5099 if (BUTTON(gamefunc_Mouse_Aiming))
5100 {
5101 SET(pp->Flags, PF_MOUSE_AIMING_ON);
5102 gs.MouseAimingOn = TRUE;
5103 }
5104 else
5105 {
5106 if (TEST(pp->Flags, PF_MOUSE_AIMING_ON))
5107 {
5108 SET_LOC_KEY(loc->bits, SK_LOOK_UP, TRUE);
5109 RESET(pp->Flags, PF_MOUSE_AIMING_ON);
5110 gs.MouseAimingOn = FALSE;
5111 }
5112 }
5113 }
5114 else
5115 if (gs.MouseAimingType == 0) // togglable button
5116 {
5117 if (BUTTON(gamefunc_Mouse_Aiming) && !BUTTONHELD(gamefunc_Mouse_Aiming))
5118 {
5119 FLIP(pp->Flags, PF_MOUSE_AIMING_ON);
5120 gs.MouseAimingOn = !gs.MouseAimingOn;
5121 if (!TEST(pp->Flags, PF_MOUSE_AIMING_ON))
5122 {
5123 SET_LOC_KEY(loc->bits, SK_LOOK_UP, TRUE);
5124 PutStringInfo(pp, "Mouse Aiming Off");
5125 }
5126 else
5127 {
5128 PutStringInfo(pp, "Mouse Aiming On");
5129 }
5130 }
5131 }
5132
5133 if (TEST(pp->Flags, PF_MOUSE_AIMING_ON))
5134 {
5135 mouseaxis = analog_lookingupanddown;
5136 }
5137 else
5138 {
5139 mouseaxis = MouseAnalogAxes[1];
5140 }
5141 if (mouseaxis != MouseYAxisMode)
5142 {
5143 CONTROL_MapAnalogAxis(1, mouseaxis, controldevice_mouse);
5144 MouseYAxisMode = mouseaxis;
5145 }
5146
5147 CONTROL_GetInput(&info);
5148
5149 info.dz = (info.dz * move_scale)>>8;
5150 info.dyaw = (info.dyaw * turn_scale)>>8;
5151
5152 PauseKey(pp);
5153
5154 if (PauseKeySet)
5155 return;
5156
5157 if (!MenuInputMode && !UsingMenus)
5158 {
5159 GetMessageInput(pp);
5160 GetConInput(pp);
5161 GetHelpInput(pp);
5162 }
5163
5164 // MAP KEY
5165 if (BUTTON(gamefunc_Map))
5166 {
5167 CONTROL_ClearButton(gamefunc_Map);
5168
5169 // Init follow coords
5170 Follow_posx = pp->posx;
5171 Follow_posy = pp->posy;
5172
5173 if (dimensionmode == 3)
5174 dimensionmode = 5;
5175 else
5176 if (dimensionmode == 5)
5177 dimensionmode = 6;
5178 else
5179 {
5180 MirrorDelay = 1;
5181 dimensionmode = 3;
5182 SetFragBar(pp);
5183 ScrollMode2D = FALSE;
5184 SetRedrawScreen(pp);
5185 }
5186 }
5187
5188 // Toggle follow map mode on/off
5189 if (dimensionmode == 5 || dimensionmode == 6)
5190 {
5191 if (BUTTON(gamefunc_Map_Follow_Mode) && !BUTTONHELD(gamefunc_Map_Follow_Mode))
5192 {
5193 ScrollMode2D = !ScrollMode2D;
5194 Follow_posx = pp->posx;
5195 Follow_posy = pp->posy;
5196 }
5197 }
5198
5199 // If in 2D follow mode, scroll around using glob vars
5200 // Tried calling this in domovethings, but key response it too poor, skips key presses
5201 // Note: ScrollMode2D = Follow mode, so this get called only during follow mode
5202 if (ScrollMode2D && pp == Player + myconnectindex && !Prediction)
5203 MoveScrollMode2D(Player + myconnectindex);
5204
5205 // !JIM! Added UsingMenus so that you don't move at all while using menus
5206 if (MenuInputMode || UsingMenus || ScrollMode2D || InputMode)
5207 return;
5208
5209 SET_LOC_KEY(loc->bits, SK_SPACE_BAR, ((!!KEY_PRESSED(KEYSC_SPACE)) | BUTTON(gamefunc_Open)));
5210
5211 running = BUTTON(gamefunc_Run) || TEST(pp->Flags, PF_LOCK_RUN);
5212
5213 if (BUTTON(gamefunc_Strafe) && !pp->sop)
5214 svel = -info.dyaw;
5215 else
5216 {
5217 if (info.dyaw > 0)
5218 angvel = labs((-info.dyaw));
5219 else
5220 angvel = info.dyaw;
5221 }
5222
5223 aimvel = info.dpitch;
5224 aimvel = min(127, aimvel);
5225 aimvel = max(-128, aimvel);
5226 if (gs.MouseInvert)
5227 aimvel = -aimvel;
5228
5229 svel -= info.dx;
5230 vel = -info.dz;
5231
5232 if (running)
5233 {
5234 if (pp->sop_control)
5235 turnamount = RUNTURN * 3;
5236 else
5237 turnamount = RUNTURN;
5238
5239 keymove = NORMALKEYMOVE << 1;
5240 }
5241 else
5242 {
5243 if (pp->sop_control)
5244 turnamount = NORMALTURN * 3;
5245 else
5246 turnamount = NORMALTURN;
5247
5248 keymove = NORMALKEYMOVE;
5249 }
5250
5251 if (BUTTON(gamefunc_Strafe) && !pp->sop)
5252 {
5253 if (BUTTON(gamefunc_Turn_Left))
5254 svel -= -keymove;
5255 if (BUTTON(gamefunc_Turn_Right))
5256 svel -= keymove;
5257 }
5258 else
5259 {
5260 if (BUTTON(gamefunc_Turn_Left))
5261 {
5262 turnheldtime += synctics;
5263 if (turnheldtime >= TURBOTURNTIME)
5264 angvel -= turnamount;
5265 else
5266 angvel -= PREAMBLETURN;
5267 }
5268 else
5269 if (BUTTON(gamefunc_Turn_Right))
5270 {
5271 turnheldtime += synctics;
5272 if (turnheldtime >= TURBOTURNTIME)
5273 angvel += turnamount;
5274 else
5275 angvel += PREAMBLETURN;
5276 }
5277 else
5278 {
5279 turnheldtime = 0;
5280 }
5281 }
5282
5283 if (BUTTON(gamefunc_Strafe_Left) && !pp->sop)
5284 svel += keymove;
5285
5286 if (BUTTON(gamefunc_Strafe_Right) && !pp->sop)
5287 svel += -keymove;
5288
5289 if (BUTTON(gamefunc_Move_Forward))
5290 {
5291 vel += keymove;
5292 //DSPRINTF(ds,"vel key %d",vel);
5293 //DebugWriteString(ds);
5294 }
5295 else
5296 {
5297 //DSPRINTF(ds,"vel %d",vel);
5298 //DebugWriteString(ds);
5299 }
5300
5301 if (BUTTON(gamefunc_Move_Backward))
5302 vel += -keymove;
5303
5304
5305 if (vel < -MAXVEL)
5306 vel = -MAXVEL;
5307 if (vel > MAXVEL)
5308 vel = MAXVEL;
5309 if (svel < -MAXSVEL)
5310 svel = -MAXSVEL;
5311 if (svel > MAXSVEL)
5312 svel = MAXSVEL;
5313 if (angvel < -MAXANGVEL)
5314 angvel = -MAXANGVEL;
5315 if (angvel > MAXANGVEL)
5316 angvel = MAXANGVEL;
5317
5318 momx = mulscale(vel, sintable[NORM_ANGLE(newpp->pang + 512)], 9);
5319 momy = mulscale(vel, sintable[NORM_ANGLE(newpp->pang)], 9);
5320
5321 momx += mulscale(svel, sintable[NORM_ANGLE(newpp->pang)], 9);
5322 momy += mulscale(svel, sintable[NORM_ANGLE(newpp->pang + 1536)], 9);
5323
5324 loc->vel = momx;
5325 loc->svel = momy;
5326 loc->angvel = angvel;
5327 loc->aimvel = aimvel;
5328
5329 if (MenuButtonAutoRun)
5330 {
5331 MenuButtonAutoRun = FALSE;
5332 if ((!!TEST(pp->Flags, PF_LOCK_RUN)) != gs.AutoRun)
5333 SET_LOC_KEY(loc->bits, SK_RUN_LOCK, TRUE);
5334 }
5335
5336 SET_LOC_KEY(loc->bits, SK_RUN_LOCK, BUTTON(gamefunc_AutoRun));
5337
5338 if (!CommEnabled)
5339 {
5340 if (MenuButtonAutoAim)
5341 {
5342 MenuButtonAutoAim = FALSE;
5343 if ((!!TEST(pp->Flags, PF_AUTO_AIM)) != gs.AutoAim)
5344 SET_LOC_KEY(loc->bits, SK_AUTO_AIM, TRUE);
5345 }
5346 }
5347 else
5348 if (KEY_PRESSED(sc_Pause))
5349 {
5350 SET_LOC_KEY(loc->bits, SK_PAUSE, KEY_PRESSED(sc_Pause));
5351 KEY_PRESSED(sc_Pause) = 0;
5352 }
5353
5354 SET_LOC_KEY(loc->bits, SK_CENTER_VIEW, BUTTON(gamefunc_Center_View));
5355
5356 SET_LOC_KEY(loc->bits, SK_RUN, BUTTON(gamefunc_Run));
5357 SET_LOC_KEY(loc->bits, SK_SHOOT, BUTTON(gamefunc_Fire));
5358
5359 // actually snap
5360 SET_LOC_KEY(loc->bits, SK_SNAP_UP, BUTTON(gamefunc_Aim_Up));
5361 SET_LOC_KEY(loc->bits, SK_SNAP_DOWN, BUTTON(gamefunc_Aim_Down));
5362
5363 // actually just look
5364 SET_LOC_KEY(loc->bits, SK_LOOK_UP, BUTTON(gamefunc_Look_Up));
5365 SET_LOC_KEY(loc->bits, SK_LOOK_DOWN, BUTTON(gamefunc_Look_Down));
5366
5367
5368 for (i = 0; i < MAX_WEAPONS_KEYS; i++)
5369 {
5370 if (BUTTON(gamefunc_Weapon_1 + i))
5371 {
5372 SET(loc->bits, i + 1);
5373 break;
5374 }
5375 }
5376
5377 if (BUTTON(gamefunc_Next_Weapon))
5378 {
5379 USERp u = User[pp->PlayerSprite];
5380 short next_weapon = u->WeaponNum + 1;
5381 short start_weapon;
5382
5383 CONTROL_ClearButton(gamefunc_Next_Weapon);
5384
5385 start_weapon = u->WeaponNum + 1;
5386
5387 if (u->WeaponNum == WPN_SWORD)
5388 start_weapon = WPN_STAR;
5389
5390 if (u->WeaponNum == WPN_FIST)
5391 {
5392 next_weapon = 14;
5393 }
5394 else
5395 {
5396 next_weapon = -1;
5397 for (i = start_weapon; TRUE; i++)
5398 {
5399 if (i >= MAX_WEAPONS_KEYS)
5400 {
5401 next_weapon = 13;
5402 break;
5403 }
5404
5405 if (TEST(pp->WpnFlags, BIT(i)) && pp->WpnAmmo[i])
5406 {
5407 next_weapon = i;
5408 break;
5409 }
5410 }
5411 }
5412
5413 SET(loc->bits, next_weapon + 1);
5414 }
5415
5416
5417 if (BUTTON(gamefunc_Previous_Weapon))
5418 {
5419 USERp u = User[pp->PlayerSprite];
5420 short prev_weapon = u->WeaponNum - 1;
5421 short start_weapon;
5422
5423 CONTROL_ClearButton(gamefunc_Previous_Weapon);
5424
5425 start_weapon = u->WeaponNum - 1;
5426
5427 if (u->WeaponNum == WPN_SWORD)
5428 {
5429 prev_weapon = 13;
5430 }
5431 else
5432 if (u->WeaponNum == WPN_STAR)
5433 {
5434 prev_weapon = 14;
5435 }
5436 else
5437 {
5438 prev_weapon = -1;
5439 for (i = start_weapon; TRUE; i--)
5440 {
5441 if (i <= -1)
5442 i = WPN_HEART;
5443
5444 if (TEST(pp->WpnFlags, BIT(i)) && pp->WpnAmmo[i])
5445 {
5446 prev_weapon = i;
5447 break;
5448 }
5449 }
5450 }
5451
5452 SET(loc->bits, prev_weapon + 1);
5453 }
5454
5455 inv_hotkey = 0;
5456 if (BUTTON(gamefunc_Med_Kit))
5457 inv_hotkey = INVENTORY_MEDKIT+1;
5458 if (BUTTON(gamefunc_Smoke_Bomb))
5459 inv_hotkey = INVENTORY_CLOAK+1;
5460 if (BUTTON(gamefunc_Night_Vision))
5461 inv_hotkey = INVENTORY_NIGHT_VISION+1;
5462 if (BUTTON(gamefunc_Gas_Bomb))
5463 inv_hotkey = INVENTORY_CHEMBOMB+1;
5464 if (BUTTON(gamefunc_Flash_Bomb) && dimensionmode == 3)
5465 inv_hotkey = INVENTORY_FLASHBOMB+1;
5466 if (BUTTON(gamefunc_Caltrops))
5467 inv_hotkey = INVENTORY_CALTROPS+1;
5468
5469 SET(loc->bits, inv_hotkey<<SK_INV_HOTKEY_BIT0);
5470
5471 SET_LOC_KEY(loc->bits, SK_INV_USE, BUTTON(gamefunc_Inventory));
5472
5473 SET_LOC_KEY(loc->bits, SK_OPERATE, BUTTON(gamefunc_Open));
5474 SET_LOC_KEY(loc->bits, SK_JUMP, BUTTON(gamefunc_Jump));
5475 SET_LOC_KEY(loc->bits, SK_CRAWL, BUTTON(gamefunc_Crouch));
5476
5477 SET_LOC_KEY(loc->bits, SK_TURN_180, BUTTON(gamefunc_TurnAround));
5478
5479 SET_LOC_KEY(loc->bits, SK_INV_LEFT, BUTTON(gamefunc_Inventory_Left));
5480 SET_LOC_KEY(loc->bits, SK_INV_RIGHT, BUTTON(gamefunc_Inventory_Right));
5481
5482 SET_LOC_KEY(loc->bits, SK_HIDE_WEAPON, BUTTON(gamefunc_Holster_Weapon));
5483
5484 // need BUTTON
5485 SET_LOC_KEY(loc->bits, SK_CRAWL_LOCK, KEY_PRESSED(KEYSC_NUM));
5486
5487 if (gNet.MultiGameType == MULTI_GAME_COOPERATIVE)
5488 {
5489 if (BUTTON(gamefunc_See_Co_Op_View))
5490 {
5491 CONTROL_ClearButton(gamefunc_See_Co_Op_View);
5492 NextScreenPeek();
5493
5494 if (dimensionmode != 2 && screenpeek == myconnectindex)
5495 {
5496 // JBF: figure out what's going on here
5497 COVERsetbrightness(gs.Brightness,&palette_data[0][0]);
5498 memcpy(pp->temp_pal, palette_data, sizeof(palette_data));
5499 DoPlayerDivePalette(pp); // Check Dive again
5500 DoPlayerNightVisionPalette(pp); // Check Night Vision again
5501 } else
5502 {
5503 PLAYERp tp = Player+screenpeek;
5504
5505 if (tp->FadeAmt<=0)
5506 memcpy(pp->temp_pal, palette_data, sizeof(palette_data));
5507 else
5508 memcpy(pp->temp_pal, tp->temp_pal, sizeof(tp->temp_pal));
5509 COVERsetbrightness(gs.Brightness,&palette_data[0][0]);
5510 DoPlayerDivePalette(tp);
5511 DoPlayerNightVisionPalette(tp);
5512 }
5513 }
5514 }
5515
5516 #if DEBUG
5517 DebugKeys(pp);
5518
5519 if (!CommEnabled) // Single player only keys
5520 SinglePlayInput(pp);
5521 #endif
5522
5523 FunctionKeys(pp);
5524
5525 if (BUTTON(gamefunc_Toggle_Crosshair))
5526 {
5527 CONTROL_ClearButton(gamefunc_Toggle_Crosshair);
5528 pToggleCrosshair(pp);
5529 }
5530 }
5531
5532 #define MAP_WHITE_SECTOR (LT_GREY + 2)
5533 #define MAP_RED_SECTOR (RED + 6)
5534 #define MAP_FLOOR_SPRITE (RED + 8)
5535 #define MAP_ENEMY (RED + 10)
5536 #define MAP_SPRITE (FIRE + 8)
5537 #define MAP_PLAYER (GREEN + 6)
5538
5539 #define MAP_BLOCK_SPRITE (DK_BLUE + 6)
5540
drawoverheadmap(int cposx,int cposy,int czoom,short cang)5541 void drawoverheadmap(int cposx, int cposy, int czoom, short cang)
5542 {
5543 int i, j, k, l, x1, y1, x2, y2, x3, y3, x4, y4, ox, oy, xoff, yoff;
5544 int dax, day, cosang, sinang, xspan, yspan, sprx, spry;
5545 int xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang;
5546 int xvect, yvect, xvect2, yvect2;
5547 char col;
5548 walltype *wal, *wal2;
5549 spritetype *spr;
5550 short p;
5551 static int pspr_ndx[8]={0,0,0,0,0,0,0,0};
5552 BOOL sprisplayer = FALSE;
5553 short txt_x, txt_y;
5554
5555 // draw location text
5556 if (gs.BorderNum <= BORDER_BAR-1)
5557 {
5558 txt_x = 7;
5559 txt_y = 168;
5560 } else
5561 {
5562 txt_x = 7;
5563 txt_y = 147;
5564 }
5565
5566 if (ScrollMode2D)
5567 {
5568 minigametext(txt_x,txt_y-7,"Follow Mode",0,2+8);
5569 }
5570
5571 if (UserMapName[0])
5572 sprintf(ds,"%s",UserMapName);
5573 else
5574 sprintf(ds,"%s",LevelInfo[Level].Description);
5575
5576 minigametext(txt_x,txt_y,ds,0,2+8);
5577
5578 //////////////////////////////////
5579
5580 xvect = sintable[(2048 - cang) & 2047] * czoom;
5581 yvect = sintable[(1536 - cang) & 2047] * czoom;
5582 xvect2 = mulscale(xvect, yxaspect, 16);
5583 yvect2 = mulscale(yvect, yxaspect, 16);
5584
5585 // Draw red lines
5586 for (i = 0; i < numsectors; i++)
5587 {
5588 startwall = sector[i].wallptr;
5589 endwall = sector[i].wallptr + sector[i].wallnum - 1;
5590
5591 z1 = sector[i].ceilingz;
5592 z2 = sector[i].floorz;
5593
5594 for (j = startwall, wal = &wall[startwall]; j <= endwall; j++, wal++)
5595 {
5596 k = wal->nextwall;
5597 if (k < 0)
5598 continue;
5599
5600 if ((show2dwall[j >> 3] & (1 << (j & 7))) == 0)
5601 continue;
5602 if ((k > j) && ((show2dwall[k >> 3] & (1 << (k & 7))) > 0))
5603 continue;
5604
5605 if (sector[wal->nextsector].ceilingz == z1)
5606 if (sector[wal->nextsector].floorz == z2)
5607 if (((wal->cstat | wall[wal->nextwall].cstat) & (16 + 32)) == 0)
5608 continue;
5609
5610 col = 152;
5611
5612 //if (dimensionmode == 2)
5613 if (dimensionmode == 6)
5614 {
5615 if (sector[i].floorz != sector[i].ceilingz)
5616 if (sector[wal->nextsector].floorz != sector[wal->nextsector].ceilingz)
5617 if (((wal->cstat | wall[wal->nextwall].cstat) & (16 + 32)) == 0)
5618 if (sector[i].floorz == sector[wal->nextsector].floorz)
5619 continue;
5620 if (sector[i].floorpicnum != sector[wal->nextsector].floorpicnum)
5621 continue;
5622 if (sector[i].floorshade != sector[wal->nextsector].floorshade)
5623 continue;
5624 col = 12;
5625 }
5626
5627 ox = wal->x - cposx;
5628 oy = wal->y - cposy;
5629 x1 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
5630 y1 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
5631
5632 wal2 = &wall[wal->point2];
5633 ox = wal2->x - cposx;
5634 oy = wal2->y - cposy;
5635 x2 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
5636 y2 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
5637
5638 drawline256(x1 + (xdim << 11), y1 + (ydim << 11), x2 + (xdim << 11), y2 + (ydim << 11), col);
5639 }
5640 }
5641
5642 // Draw sprites
5643 k = Player[screenpeek].PlayerSprite;
5644 for (i = 0; i < numsectors; i++)
5645 for (j = headspritesect[i]; j >= 0; j = nextspritesect[j])
5646 {
5647 TRAVERSE_CONNECT(p)
5648 {
5649 if(Player[p].PlayerSprite == j)
5650 {
5651 if(sprite[Player[p].PlayerSprite].xvel > 16)
5652 pspr_ndx[myconnectindex] = ((totalclock>>4)&3);
5653 sprisplayer = TRUE;
5654
5655 goto SHOWSPRITE;
5656 }
5657 }
5658 if ((show2dsprite[j >> 3] & (1 << (j & 7))) > 0)
5659 {
5660 SHOWSPRITE:
5661 spr = &sprite[j];
5662
5663 col = 56;
5664 if ((spr->cstat & 1) > 0)
5665 col = 248;
5666 if (j == k)
5667 col = 31;
5668
5669 sprx = spr->x;
5670 spry = spr->y;
5671
5672 k = spr->statnum;
5673 if ((k >= 1) && (k <= 8) && (k != 2)) // Interpolate moving
5674 {
5675 sprx = sprite[j].x;
5676 spry = sprite[j].y;
5677 }
5678
5679 switch (spr->cstat & 48)
5680 {
5681 case 0: // Regular sprite
5682 if(Player[p].PlayerSprite == j)
5683 {
5684 ox = sprx - cposx;
5685 oy = spry - cposy;
5686 x1 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
5687 y1 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
5688
5689 if (dimensionmode == 5 && (gNet.MultiGameType != MULTI_GAME_COMMBAT || j == Player[screenpeek].PlayerSprite))
5690 {
5691 ox = (sintable[(spr->ang + 512) & 2047] >> 7);
5692 oy = (sintable[(spr->ang) & 2047] >> 7);
5693 x2 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
5694 y2 = mulscale(oy, xvect, 16) + mulscale(ox, yvect, 16);
5695
5696 if (j == Player[screenpeek].PlayerSprite)
5697 {
5698 x2 = 0L;
5699 y2 = -(czoom << 5);
5700 }
5701
5702 x3 = mulscale(x2, yxaspect, 16);
5703 y3 = mulscale(y2, yxaspect, 16);
5704
5705 drawline256(x1 - x2 + (xdim << 11), y1 - y3 + (ydim << 11),
5706 x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
5707 drawline256(x1 - y2 + (xdim << 11), y1 + x3 + (ydim << 11),
5708 x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
5709 drawline256(x1 + y2 + (xdim << 11), y1 - x3 + (ydim << 11),
5710 x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
5711 }
5712 else
5713 {
5714 if (((gotsector[i >> 3] & (1 << (i & 7))) > 0) && (czoom > 192))
5715 {
5716 daang = (spr->ang - cang) & 2047;
5717 if (j == Player[screenpeek].PlayerSprite)
5718 {
5719 x1 = 0;
5720 //y1 = (yxaspect << 2);
5721 y1 = 0;
5722 daang = 0;
5723 }
5724
5725 // Special case tiles
5726 if (spr->picnum == 3123) break;
5727
5728 if(sprisplayer)
5729 {
5730 if (gNet.MultiGameType != MULTI_GAME_COMMBAT || j == Player[screenpeek].PlayerSprite)
5731 rotatesprite((x1 << 4) + (xdim << 15), (y1 << 4) + (ydim << 15), mulscale(czoom * (spr->yrepeat), yxaspect, 16), daang, 1196+pspr_ndx[myconnectindex], spr->shade, spr->pal, (spr->cstat & 2) >> 1, windowx1, windowy1, windowx2, windowy2);
5732 }
5733 else
5734 rotatesprite((x1 << 4) + (xdim << 15), (y1 << 4) + (ydim << 15), mulscale(czoom * (spr->yrepeat), yxaspect, 16), daang, spr->picnum, spr->shade, spr->pal, (spr->cstat & 2) >> 1, windowx1, windowy1, windowx2, windowy2);
5735 }
5736 }
5737 }
5738 break;
5739 case 16: // Rotated sprite
5740 x1 = sprx;
5741 y1 = spry;
5742 tilenum = spr->picnum;
5743 xoff = (int) ((signed char) ((picanm[tilenum] >> 8) & 255)) + ((int) spr->xoffset);
5744 if ((spr->cstat & 4) > 0)
5745 xoff = -xoff;
5746 k = spr->ang;
5747 l = spr->xrepeat;
5748 dax = sintable[k & 2047] * l;
5749 day = sintable[(k + 1536) & 2047] * l;
5750 l = tilesizx[tilenum];
5751 k = (l >> 1) + xoff;
5752 x1 -= mulscale(dax, k, 16);
5753 x2 = x1 + mulscale(dax, l, 16);
5754 y1 -= mulscale(day, k, 16);
5755 y2 = y1 + mulscale(day, l, 16);
5756
5757 ox = x1 - cposx;
5758 oy = y1 - cposy;
5759 x1 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
5760 y1 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
5761
5762 ox = x2 - cposx;
5763 oy = y2 - cposy;
5764 x2 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
5765 y2 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
5766
5767 drawline256(x1 + (xdim << 11), y1 + (ydim << 11),
5768 x2 + (xdim << 11), y2 + (ydim << 11), col);
5769
5770 break;
5771 case 32: // Floor sprite
5772 if (dimensionmode == 5)
5773 {
5774 tilenum = spr->picnum;
5775 xoff = (int) ((signed char) ((picanm[tilenum] >> 8) & 255)) + ((int) spr->xoffset);
5776 yoff = (int) ((signed char) ((picanm[tilenum] >> 16) & 255)) + ((int) spr->yoffset);
5777 if ((spr->cstat & 4) > 0)
5778 xoff = -xoff;
5779 if ((spr->cstat & 8) > 0)
5780 yoff = -yoff;
5781
5782 k = spr->ang;
5783 cosang = sintable[(k + 512) & 2047];
5784 sinang = sintable[k];
5785 xspan = tilesizx[tilenum];
5786 xrepeat = spr->xrepeat;
5787 yspan = tilesizy[tilenum];
5788 yrepeat = spr->yrepeat;
5789
5790 dax = ((xspan >> 1) + xoff) * xrepeat;
5791 day = ((yspan >> 1) + yoff) * yrepeat;
5792 x1 = sprx + mulscale(sinang, dax, 16) + mulscale(cosang, day, 16);
5793 y1 = spry + mulscale(sinang, day, 16) - mulscale(cosang, dax, 16);
5794 l = xspan * xrepeat;
5795 x2 = x1 - mulscale(sinang, l, 16);
5796 y2 = y1 + mulscale(cosang, l, 16);
5797 l = yspan * yrepeat;
5798 k = -mulscale(cosang, l, 16);
5799 x3 = x2 + k;
5800 x4 = x1 + k;
5801 k = -mulscale(sinang, l, 16);
5802 y3 = y2 + k;
5803 y4 = y1 + k;
5804
5805 ox = x1 - cposx;
5806 oy = y1 - cposy;
5807 x1 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
5808 y1 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
5809
5810 ox = x2 - cposx;
5811 oy = y2 - cposy;
5812 x2 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
5813 y2 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
5814
5815 ox = x3 - cposx;
5816 oy = y3 - cposy;
5817 x3 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
5818 y3 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
5819
5820 ox = x4 - cposx;
5821 oy = y4 - cposy;
5822 x4 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
5823 y4 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
5824
5825 drawline256(x1 + (xdim << 11), y1 + (ydim << 11),
5826 x2 + (xdim << 11), y2 + (ydim << 11), col);
5827
5828 drawline256(x2 + (xdim << 11), y2 + (ydim << 11),
5829 x3 + (xdim << 11), y3 + (ydim << 11), col);
5830
5831 drawline256(x3 + (xdim << 11), y3 + (ydim << 11),
5832 x4 + (xdim << 11), y4 + (ydim << 11), col);
5833
5834 drawline256(x4 + (xdim << 11), y4 + (ydim << 11),
5835 x1 + (xdim << 11), y1 + (ydim << 11), col);
5836
5837 }
5838 break;
5839 }
5840 }
5841 }
5842 // Draw white lines
5843 for (i = 0; i < numsectors; i++)
5844 {
5845 startwall = sector[i].wallptr;
5846 endwall = sector[i].wallptr + sector[i].wallnum - 1;
5847
5848 for (j = startwall, wal = &wall[startwall]; j <= endwall; j++, wal++)
5849 {
5850 if (wal->nextwall >= 0)
5851 continue;
5852
5853 if ((show2dwall[j >> 3] & (1 << (j & 7))) == 0)
5854 continue;
5855
5856 if (tilesizx[wal->picnum] == 0)
5857 continue;
5858 if (tilesizy[wal->picnum] == 0)
5859 continue;
5860
5861 ox = wal->x - cposx;
5862 oy = wal->y - cposy;
5863 x1 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
5864 y1 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
5865
5866 wal2 = &wall[wal->point2];
5867 ox = wal2->x - cposx;
5868 oy = wal2->y - cposy;
5869 x2 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
5870 y2 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
5871
5872 drawline256(x1 + (xdim << 11), y1 + (ydim << 11), x2 + (xdim << 11), y2 + (ydim << 11), 24);
5873 }
5874 }
5875
5876 }
5877
5878 extern int tilefileoffs[MAXTILES];//offset into the
5879 extern char tilefilenum[MAXTILES];//0-11
5880
5881 #if 0
5882 loadtile (short tilenume)
5883 {
5884 char *ptr;
5885 int i;
5886 char zerochar = 0;
5887
5888 if (walsiz[tilenume] <= 0)
5889 return;
5890
5891 i = tilefilenum[tilenume];
5892 if (i != artfilnum)
5893 {
5894 if (artfil != -1)
5895 kclose(artfil);
5896 artfilnum = i;
5897 artfilplc = 0L;
5898
5899 artfilename[7] = (i%10)+48;
5900 artfilename[6] = ((i/10)%10)+48;
5901 artfilename[5] = ((i/100)%10)+48;
5902 artfil = kopen4load(artfilename);
5903 faketimerhandler();
5904 }
5905
5906 if (waloff[tilenume] == 0)
5907 allocache(&waloff[tilenume],walsiz[tilenume],&zerochar);
5908
5909 if (artfilplc != tilefileoffs[tilenume])
5910 {
5911 klseek(artfil,tilefileoffs[tilenume]-artfilplc,SEEK_CUR);
5912 faketimerhandler();
5913 }
5914
5915 ptr = (char *)waloff[tilenume];
5916 kread(artfil,ptr,walsiz[tilenume]);
5917 faketimerhandler();
5918 artfilplc = tilefileoffs[tilenume]+walsiz[tilenume];
5919 }
5920 #endif
5921
5922 #if RANDOM_DEBUG
5923 int
RandomRange(int range,char * file,unsigned line)5924 RandomRange(int range, char *file, unsigned line)
5925 {
5926 ULONG rand_num;
5927 ULONG value;
5928 extern FILE * fout_err;
5929 extern ULONG MoveThingsCount;
5930
5931 if (RandomPrint && !Prediction)
5932 {
5933 sprintf(ds,"mtc %d, %s, line %d, %d",MoveThingsCount,file,line,randomseed);
5934 DebugWriteString(ds);
5935 }
5936
5937 if (range <= 0)
5938 return(0);
5939
5940 rand_num = krand2();
5941
5942 if (rand_num == 65535U)
5943 rand_num--;
5944
5945 // shift values to give more precision
5946 value = (rand_num << 14) / ((65535UL << 14) / range);
5947
5948 if (value >= range)
5949 value = range - 1;
5950
5951 return(value);
5952 }
5953 #else
5954 int
RandomRange(int range)5955 RandomRange(int range)
5956 {
5957 ULONG rand_num;
5958 ULONG value;
5959
5960 if (range <= 0)
5961 return(0);
5962
5963 rand_num = RANDOM();
5964
5965 if (rand_num == 65535U)
5966 rand_num--;
5967
5968 // shift values to give more precision
5969 value = (rand_num << 14) / ((65535UL << 14) / range);
5970
5971 if (value >= (ULONG)range)
5972 value = range - 1;
5973
5974 return(value);
5975 }
5976 #endif
5977
5978 int
StdRandomRange(int range)5979 StdRandomRange(int range)
5980 {
5981 ULONG rand_num;
5982 ULONG value;
5983
5984 if (range <= 0)
5985 return(0);
5986
5987 rand_num = STD_RANDOM();
5988
5989 if (rand_num == RAND_MAX)
5990 rand_num--;
5991
5992 // shift values to give more precision
5993 #if (RAND_MAX > 0x7fff)
5994 value = rand_num / (((int)RAND_MAX) / range);
5995 #else
5996 value = (rand_num << 14) / ((((int)RAND_MAX) << 14) / range);
5997 #endif
5998
5999 if (value >= (ULONG)range)
6000 value = range - 1;
6001
6002 return(value);
6003 }
6004
6005 void
NextScreenPeek(void)6006 NextScreenPeek(void)
6007 {
6008 int startpeek = screenpeek;
6009 do
6010 {
6011 screenpeek = connectpoint2[screenpeek];
6012 if (screenpeek < 0)
6013 screenpeek = connecthead;
6014 if (!Player[screenpeek].IsDisconnected)
6015 {
6016 CON_Message("Viewing %s", Player[screenpeek].PlayerName);
6017 break;
6018 }
6019 }
6020 while (screenpeek != startpeek);
6021 }
6022
6023 static int
osdcmd_restartvid(const osdfuncparm_t * parm)6024 osdcmd_restartvid(const osdfuncparm_t *parm)
6025 {
6026 extern BOOL RestartVideo;
6027 extern VMODE NewVideoMode;
6028
6029 RestartVideo = TRUE;
6030 NewVideoMode.x = xdim;
6031 NewVideoMode.y = ydim;
6032 NewVideoMode.bpp = bpp;
6033 NewVideoMode.fs = fullscreen;
6034
6035 return OSDCMD_OK;
6036 }
6037
6038 static int
osdcmd_vidmode(const osdfuncparm_t * parm)6039 osdcmd_vidmode(const osdfuncparm_t *parm)
6040 {
6041 extern BOOL RestartVideo;
6042 extern VMODE NewVideoMode;
6043
6044 int newx = xdim, newy = ydim, newbpp = bpp, newfullscreen = fullscreen;
6045
6046 if (parm->numparms < 1 || parm->numparms > 4) return OSDCMD_SHOWHELP;
6047
6048 switch (parm->numparms)
6049 {
6050 case 1: // bpp switch
6051 newbpp = Batol(parm->parms[0]);
6052 break;
6053 case 2: // res switch
6054 newx = Batol(parm->parms[0]);
6055 newy = Batol(parm->parms[1]);
6056 break;
6057 case 3: // res & bpp switch
6058 case 4:
6059 newx = Batol(parm->parms[0]);
6060 newy = Batol(parm->parms[1]);
6061 newbpp = Batol(parm->parms[2]);
6062 if (parm->numparms == 4)
6063 newfullscreen = (Batol(parm->parms[3]) != 0);
6064 break;
6065 }
6066
6067 if (checkvideomode(&newx, &newy, newbpp, newfullscreen, 0) >= 0)
6068 {
6069 RestartVideo = TRUE;
6070 NewVideoMode.x = newx;
6071 NewVideoMode.y = newy;
6072 NewVideoMode.bpp = newbpp;
6073 NewVideoMode.fs = newfullscreen;
6074 }
6075
6076 return OSDCMD_OK;
6077 }
6078
6079 #include "saveable.h"
6080
6081 static saveable_data saveable_build_data[] = {
6082 SAVE_DATA(sector),
6083 SAVE_DATA(sprite),
6084 SAVE_DATA(wall)
6085 };
6086
6087 saveable_module saveable_build = {
6088 // code
6089 NULL,
6090 0,
6091
6092 // data
6093 saveable_build_data,
6094 NUM_SAVEABLE_ITEMS(saveable_build_data)
6095 };
6096
6097 // vim:ts=4:sw=4:expandtab:
6098