1
2 //**************************************************************************
3 //**
4 //** h2_main.c : Heretic 2 : Raven Software, Corp.
5 //**
6 //** $RCSfile: h2_main.c,v $
7 //** $Revision: 1.50 $
8 //** $Date: 96/01/16 13:02:28 $
9 //** $Author: bgokey $
10 //**
11 //**************************************************************************
12
13 // HEADER FILES ------------------------------------------------------------
14
15 #ifndef MUSTDIE
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #endif
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <time.h>
22 #include "h2def.h"
23 #include "p_local.h"
24 #include "soundst.h"
25
26 // MACROS ------------------------------------------------------------------
27
28 #define CONFIG_FILE_NAME "hexen.cfg"
29 #define MAXWADFILES 20
30
31 // TYPES -------------------------------------------------------------------
32
33 typedef struct
34 {
35 char *name;
36 void (*func)(char **args, int tag);
37 int requiredArgs;
38 int tag;
39 } execOpt_t;
40
41 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
42
43 void R_ExecuteSetViewSize(void);
44 void D_CheckNetGame(void);
45 void G_BuildTiccmd(ticcmd_t *cmd);
46 void F_Drawer(void);
47 boolean F_Responder(event_t *ev);
48 void I_StartupKeyboard(void);
49 void I_StartupJoystick(void);
50 void I_ShutdownKeyboard(void);
51 void S_InitScript(void);
52
53 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
54
55 void H2_ProcessEvents(void);
56 void H2_DoAdvanceDemo(void);
57 void H2_AdvanceDemo(void);
58 void H2_StartTitle(void);
59 void H2_PageTicker(void);
60
61 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
62
63 static void DrawMessage(void);
64 static void PageDrawer(void);
65 static void HandleArgs(void);
66 static void CheckRecordFrom(void);
67 static void AddWADFile(char *file);
68 static void DrawAndBlit(void);
69 static void ExecOptionFILE(char **args, int tag);
70 static void ExecOptionSCRIPTS(char **args, int tag);
71 static void ExecOptionDEVMAPS(char **args, int tag);
72 static void ExecOptionSKILL(char **args, int tag);
73 static void ExecOptionPLAYDEMO(char **args, int tag);
74 static void ExecOptionMAXZONE(char **args, int tag);
75 static void CreateSavePath(void);
76 static void WarpCheck(void);
77
78 #ifdef TIMEBOMB
79 static void DoTimeBomb(void);
80 #endif
81
82 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
83
84 extern boolean automapactive;
85 extern boolean MenuActive;
86 extern boolean askforquit;
87 extern char *SavePath;
88
89 // PUBLIC DATA DEFINITIONS -------------------------------------------------
90
91 boolean DevMaps; // true = Map development mode
92 char *DevMapsDir = ""; // development maps directory
93 boolean shareware; // true if only episode 1 present
94 boolean nomonsters; // checkparm of -nomonsters
95 boolean respawnparm; // checkparm of -respawn
96 boolean randomclass; // checkparm of -randclass
97 boolean debugmode; // checkparm of -debug
98 boolean ravpic; // checkparm of -ravpic
99 boolean cdrom; // true if cd-rom mode active
100 boolean cmdfrag; // true if a CMD_FRAG packet should be sent out
101 boolean singletics; // debug flag to cancel adaptiveness
102 boolean artiskip; // whether shift-enter skips an artifact
103 int maxzone = 0x800000; // Maximum allocated for zone heap (8meg default)
104 skill_t startskill;
105 int startepisode;
106 int startmap;
107 boolean autostart;
108 boolean advancedemo;
109 FILE *debugfile;
110 event_t events[MAXEVENTS];
111 int eventhead;
112 int eventtail;
113
114 // PRIVATE DATA DEFINITIONS ------------------------------------------------
115
116 static int WarpMap;
117 static int demosequence;
118 static int pagetic;
119 static char *pagename;
120 #ifdef __NeXT__
121 static char *wadfiles[MAXWADFILES] =
122 {
123 "/Novell/H2/source/hexen.wad"
124 };
125 #else
126 #ifndef MUSTDIE
127 static char *wadfiles[MAXWADFILES] =
128 {
129 "hexen.wad",
130 PREFIX "/share/doom/hexen.wad"
131 };
132 #else
133 static char *wadfiles[MAXWADFILES] =
134 {
135 "HEXEN.WAD"
136 };
137 #endif
138 #endif
139 static execOpt_t ExecOptions[] =
140 {
141 { "-file", ExecOptionFILE, 1, 0 },
142 { "-scripts", ExecOptionSCRIPTS, 1, 0 },
143 { "-devmaps", ExecOptionDEVMAPS, 1, 0 },
144 { "-skill", ExecOptionSKILL, 1, 0 },
145 { "-playdemo", ExecOptionPLAYDEMO, 1, 0 },
146 { "-timedemo", ExecOptionPLAYDEMO, 1, 0 },
147 { "-maxzone", ExecOptionMAXZONE, 1, 0 },
148 { NULL, NULL, 0, 0 } // Terminator
149 };
150
151 // CODE --------------------------------------------------------------------
152
153 //==========================================================================
154 //
155 // H2_Main
156 //
157 //==========================================================================
158 void InitMapMusicInfo(void);
159
H2_Main(void)160 void H2_Main(void)
161 {
162 int p;
163
164 M_FindResponseFile();
165 setbuf(stdout, NULL);
166 startepisode = 1;
167 autostart = false;
168 startskill = sk_medium;
169 startmap = 1;
170 shareware = false; // Always false for Hexen
171
172 HandleArgs();
173
174 // Initialize subsystems
175
176 ST_Message("V_Init: allocate screens.\n");
177 V_Init();
178
179 // Load defaults before initing other systems
180 ST_Message("M_LoadDefaults: Load system defaults.\n");
181 M_LoadDefaults(CONFIG_FILE_NAME);
182
183 // Now that the savedir is loaded from .CFG, make sure it exists
184 CreateSavePath();
185
186 // HEXEN MODIFICATION:
187 // There is a realloc() in W_AddFile() that might fail if the zone
188 // heap has been previously allocated, so we need to initialize the
189 // WAD files BEFORE the zone memory initialization.
190 ST_Message("W_Init: Init WADfiles.\n");
191 W_InitMultipleFiles(wadfiles);
192
193 #ifdef TIMEBOMB
194 DoTimeBomb();
195 #endif
196
197 ST_Message("Z_Init: Init zone memory allocation daemon.\n");
198 Z_Init();
199
200 #ifdef __WATCOMC__
201 I_StartupKeyboard();
202 I_StartupJoystick();
203 #endif
204
205 ST_Message("MN_Init: Init menu system.\n");
206 MN_Init();
207
208 ST_Message("CT_Init: Init chat mode data.\n");
209 CT_Init();
210
211 InitMapMusicInfo(); // Init music fields in mapinfo
212
213 //#ifdef __WATCOMC__
214 ST_Message("S_InitScript\n");
215 S_InitScript();
216 //#endif
217
218 ST_Message("SN_InitSequenceScript: Registering sound sequences.\n");
219 SN_InitSequenceScript();
220 ST_Message("I_Init: Setting up machine state.\n");
221 I_Init();
222
223 ST_Message("ST_Init: Init startup screen.\n");
224 ST_Init();
225
226 S_StartSongName("orb", true);
227
228 // Show version message now, so it's visible during R_Init()
229 ST_Message("Executable: "VERSIONTEXT".\n");
230
231 ST_Message("R_Init: Init Hexen refresh daemon");
232 R_Init();
233 ST_Message("\n");
234
235 if (M_CheckParm("-net")) ST_NetProgress(); // Console player found
236
237 ST_Message("P_Init: Init Playloop state.\n");
238 P_Init();
239
240 // Check for command line warping. Follows P_Init() because the
241 // MAPINFO.TXT script must be already processed.
242 WarpCheck();
243
244 if(autostart)
245 {
246 ST_Message("Warp to Map %d (\"%s\":%d), Skill %d\n",
247 WarpMap, P_GetMapName(startmap), startmap, startskill+1);
248 }
249
250 ST_Message("D_CheckNetGame: Checking network game status.\n");
251 D_CheckNetGame();
252
253 ST_Message("SB_Init: Loading patches.\n");
254 SB_Init();
255
256 CheckRecordFrom();
257
258 p = M_CheckParm("-record");
259 if(p && p < myargc-1)
260 {
261 G_RecordDemo(startskill, 1, startepisode, startmap, myargv[p+1]);
262 H2_GameLoop(); // Never returns
263 }
264
265 p = M_CheckParm("-playdemo");
266 if(p && p < myargc-1)
267 {
268 singledemo = true; // Quit after one demo
269 G_DeferedPlayDemo(myargv[p+1]);
270 H2_GameLoop(); // Never returns
271 }
272
273 p = M_CheckParm("-timedemo");
274 if(p && p < myargc-1)
275 {
276 G_TimeDemo(myargv[p+1]);
277 H2_GameLoop(); // Never returns
278 }
279
280 p = M_CheckParm("-loadgame");
281 if(p && p < myargc-1)
282 {
283 G_LoadGame(atoi(myargv[p+1]));
284 }
285
286 if(gameaction != ga_loadgame)
287 {
288 UpdateState |= I_FULLSCRN;
289 BorderNeedRefresh = true;
290 if(autostart || netgame)
291 {
292 G_StartNewInit();
293 G_InitNew(startskill, startepisode, startmap);
294 }
295 else
296 {
297 H2_StartTitle();
298 }
299 }
300 H2_GameLoop(); // Never returns
301 }
302
303 //==========================================================================
304 //
305 // HandleArgs
306 //
307 //==========================================================================
308
HandleArgs(void)309 static void HandleArgs(void)
310 {
311 int p;
312 execOpt_t *opt;
313
314 nomonsters = M_ParmExists("-nomonsters");
315 respawnparm = M_ParmExists("-respawn");
316 randomclass = M_ParmExists("-randclass");
317 ravpic = M_ParmExists("-ravpic");
318 artiskip = M_ParmExists("-artiskip");
319 debugmode = M_ParmExists("-debug");
320 deathmatch = M_ParmExists("-deathmatch");
321 cdrom = M_ParmExists("-cdrom");
322 cmdfrag = M_ParmExists("-cmdfrag");
323
324 // Process command line options
325 for(opt = ExecOptions; opt->name != NULL; opt++)
326 {
327 p = M_CheckParm(opt->name);
328 if(p && p < myargc-opt->requiredArgs)
329 {
330 opt->func(&myargv[p], opt->tag);
331 }
332 }
333
334 // Look for an external device driver
335 //I_CheckExternDriver();
336 }
337
338 //==========================================================================
339 //
340 // WarpCheck
341 //
342 //==========================================================================
343
WarpCheck(void)344 static void WarpCheck(void)
345 {
346 int p;
347 int map;
348
349 p = M_CheckParm("-warp");
350 if(p && p < myargc-1)
351 {
352 WarpMap = atoi(myargv[p+1]);
353 map = P_TranslateMap(WarpMap);
354 if(map == -1)
355 { // Couldn't find real map number
356 startmap = 1;
357 ST_Message("-WARP: Invalid map number.\n");
358 }
359 else
360 { // Found a valid startmap
361 startmap = map;
362 autostart = true;
363 }
364 }
365 else
366 {
367 WarpMap = 1;
368 startmap = P_TranslateMap(1);
369 if(startmap == -1)
370 {
371 startmap = 1;
372 }
373 }
374 }
375
376 //==========================================================================
377 //
378 // ExecOptionSKILL
379 //
380 //==========================================================================
381
ExecOptionSKILL(char ** args,int tag)382 static void ExecOptionSKILL(char **args, int tag)
383 {
384 startskill = args[1][0]-'1';
385 autostart = true;
386 }
387
388 //==========================================================================
389 //
390 // ExecOptionFILE
391 //
392 //==========================================================================
393
ExecOptionFILE(char ** args,int tag)394 static void ExecOptionFILE(char **args, int tag)
395 {
396 int p;
397
398 p = M_CheckParm("-file");
399 while(++p != myargc && myargv[p][0] != '-')
400 {
401 AddWADFile(myargv[p]);
402 }
403 }
404
405
406 //==========================================================================
407 //
408 // ExecOptionPLAYDEMO
409 //
410 //==========================================================================
411
ExecOptionPLAYDEMO(char ** args,int tag)412 static void ExecOptionPLAYDEMO(char **args, int tag)
413 {
414 char file[256];
415
416 sprintf(file, "%s.lmp", args[1]);
417 AddWADFile(file);
418 ST_Message("Playing demo %s.lmp.\n", args[1]);
419 }
420
421 //==========================================================================
422 //
423 // ExecOptionSCRIPTS
424 //
425 //==========================================================================
426
ExecOptionSCRIPTS(char ** args,int tag)427 static void ExecOptionSCRIPTS(char **args, int tag)
428 {
429 sc_FileScripts = true;
430 sc_ScriptsDir = args[1];
431 }
432
433 //==========================================================================
434 //
435 // ExecOptionDEVMAPS
436 //
437 //==========================================================================
438
ExecOptionDEVMAPS(char ** args,int tag)439 static void ExecOptionDEVMAPS(char **args, int tag)
440 {
441 DevMaps = true;
442 ST_Message("Map development mode enabled:\n");
443 ST_Message("[config ] = %s\n", args[1]);
444 SC_OpenFileCLib(args[1]);
445 SC_MustGetStringName("mapsdir");
446 SC_MustGetString();
447 ST_Message("[mapsdir ] = %s\n", sc_String);
448 DevMapsDir = malloc(strlen(sc_String)+1);
449 strcpy(DevMapsDir, sc_String);
450 SC_MustGetStringName("scriptsdir");
451 SC_MustGetString();
452 ST_Message("[scriptsdir] = %s\n", sc_String);
453 sc_FileScripts = true;
454 sc_ScriptsDir = malloc(strlen(sc_String)+1);
455 strcpy(sc_ScriptsDir, sc_String);
456 while(SC_GetString())
457 {
458 if(SC_Compare("file"))
459 {
460 SC_MustGetString();
461 AddWADFile(sc_String);
462 }
463 else
464 {
465 SC_ScriptError(NULL);
466 }
467 }
468 SC_Close();
469 }
470
471
superatol(char * s)472 long superatol(char *s)
473 {
474 long int n=0, r=10, x, mul=1;
475 char *c=s;
476
477 for (; *c; c++)
478 {
479 x = (*c & 223) - 16;
480
481 if (x == -3)
482 {
483 mul = -mul;
484 }
485 else if (x == 72 && r == 10)
486 {
487 n -= (r=n);
488 if (!r) r=16;
489 if (r<2 || r>36) return -1;
490 }
491 else
492 {
493 if (x>10) x-=39;
494 if (x >= r) return -1;
495 n = (n*r) + x;
496 }
497 }
498 return(mul*n);
499 }
500
501
ExecOptionMAXZONE(char ** args,int tag)502 static void ExecOptionMAXZONE(char **args, int tag)
503 {
504 int size;
505
506 size = superatol(args[1]);
507 if (size < MINIMUM_HEAP_SIZE) size = MINIMUM_HEAP_SIZE;
508 if (size > MAXIMUM_HEAP_SIZE) size = MAXIMUM_HEAP_SIZE;
509 maxzone = size;
510 }
511
512 //==========================================================================
513 //
514 // H2_GameLoop
515 //
516 //==========================================================================
517
H2_GameLoop(void)518 void H2_GameLoop(void)
519 {
520 if(M_CheckParm("-debugfile"))
521 {
522 char filename[20];
523 sprintf(filename, "debug%i.txt", consoleplayer);
524 debugfile = fopen(filename,"w");
525 }
526
527 I_InitGraphics();
528
529 I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE));
530
531 while(1)
532 {
533 // Frame syncronous IO operations
534 I_StartFrame();
535
536 // Process one or more tics
537 if(singletics)
538 {
539 I_StartTic();
540 H2_ProcessEvents();
541 G_BuildTiccmd(&netcmds[consoleplayer][maketic%BACKUPTICS]);
542 if(advancedemo)
543 {
544 H2_DoAdvanceDemo();
545 }
546 G_Ticker();
547 gametic++;
548 maketic++;
549 }
550 else
551 {
552 // Will run at least one tic
553 TryRunTics();
554 }
555
556 // Move positional sounds
557 S_UpdateSounds(players[displayplayer].mo);
558
559 DrawAndBlit();
560 }
561 }
562
563 //==========================================================================
564 //
565 // H2_ProcessEvents
566 //
567 // Send all the events of the given timestamp down the responder chain.
568 //
569 //==========================================================================
570
H2_ProcessEvents(void)571 void H2_ProcessEvents(void)
572 {
573 event_t *ev;
574
575 for(; eventtail != eventhead; eventtail = (++eventtail)&(MAXEVENTS-1))
576 {
577 ev = &events[eventtail];
578 if(F_Responder(ev))
579 {
580 continue;
581 }
582 if(MN_Responder(ev))
583 {
584 continue;
585 }
586 G_Responder(ev);
587 }
588 }
589
590 //==========================================================================
591 //
592 // H2_PostEvent
593 //
594 // Called by the I/O functions when input is detected.
595 //
596 //==========================================================================
597
H2_PostEvent(event_t * ev)598 void H2_PostEvent(event_t *ev)
599 {
600 events[eventhead] = *ev;
601 eventhead = (++eventhead)&(MAXEVENTS-1);
602 }
603
604 //==========================================================================
605 //
606 // DrawAndBlit
607 //
608 //==========================================================================
609
DrawAndBlit(void)610 static void DrawAndBlit(void)
611 {
612 // Change the view size if needed
613 if(setsizeneeded)
614 {
615 R_ExecuteSetViewSize();
616 }
617
618 // Do buffered drawing
619 switch(gamestate)
620 {
621 case GS_LEVEL:
622 if(!gametic)
623 {
624 break;
625 }
626 if(automapactive)
627 {
628 AM_Drawer();
629 }
630 else
631 {
632 R_RenderPlayerView(&players[displayplayer]);
633 }
634 CT_Drawer();
635 UpdateState |= I_FULLVIEW;
636 SB_Drawer();
637 break;
638 case GS_INTERMISSION:
639 IN_Drawer();
640 break;
641 case GS_FINALE:
642 F_Drawer();
643 break;
644 case GS_DEMOSCREEN:
645 PageDrawer();
646 break;
647 }
648
649 if(paused && !MenuActive && !askforquit)
650 {
651 #if 0
652 for gl
653 if (use_gl)
654 {
655 if(!netgame)
656 {
657 OGL_DrawPatch(160, viewwindowy+5, W_GetNumForName("PAUSED"));
658 }
659 else
660 {
661 OGL_DrawPatch(160, 70, W_GetNumGorName("PAUSED"));
662 }
663 }
664 else
665 #endif
666 {
667 if(!netgame)
668 {
669 V_DrawPatch(160, viewwindowy+5, W_CacheLumpName("PAUSED",
670 PU_CACHE));
671 }
672 else
673 {
674 V_DrawPatch(160, 70, W_CacheLumpName("PAUSED",
675 PU_CACHE));
676 }
677 }
678 }
679
680 // Draw current message
681 DrawMessage();
682
683 // Draw Menu
684 MN_Drawer();
685
686 // Send out any new accumulation
687 NetUpdate();
688
689 // Flush buffered stuff to screen
690 I_UpdateNoBlit();
691 I_FinishUpdate();
692 }
693
694 //==========================================================================
695 //
696 // DrawMessage
697 //
698 //==========================================================================
699
DrawMessage(void)700 static void DrawMessage(void)
701 {
702 player_t *player;
703
704 player = &players[consoleplayer];
705 if(player->messageTics <= 0 || !player->message)
706 { // No message
707 return;
708 }
709 if(player->yellowMessage)
710 {
711 MN_DrTextAYellow(player->message,
712 160-MN_TextAWidth(player->message)/2, 1);
713 }
714 else
715 {
716 MN_DrTextA(player->message, 160-MN_TextAWidth(player->message)/2, 1);
717 }
718 }
719
720 //==========================================================================
721 //
722 // H2_PageTicker
723 //
724 //==========================================================================
725
H2_PageTicker(void)726 void H2_PageTicker(void)
727 {
728 if(--pagetic < 0)
729 {
730 H2_AdvanceDemo();
731 }
732 }
733
734 //==========================================================================
735 //
736 // PageDrawer
737 //
738 //==========================================================================
739
PageDrawer(void)740 static void PageDrawer(void)
741 {
742 #if 0
743 if (use_gl)
744 {
745 for gl
746 OGL_DrawRawScreen(W_GetNumForName(pagename));
747 if (demosequence == 1)
748 {
749 OGL_DrawPatch(4, 160, W_GetNumForName("ADVISOR");
750 UpdateState |= I_FULLSCRN;
751 }
752 }
753 else
754 #endif
755 {
756 V_DrawRawScreen(W_CacheLumpName(pagename, PU_CACHE));
757 if(demosequence == 1)
758 {
759 V_DrawPatch(4, 160, W_CacheLumpName("ADVISOR", PU_CACHE));
760 UpdateState |= I_FULLSCRN;
761 }
762 }
763 }
764
765 //==========================================================================
766 //
767 // H2_AdvanceDemo
768 //
769 // Called after each demo or intro demosequence finishes.
770 //
771 //==========================================================================
772
H2_AdvanceDemo(void)773 void H2_AdvanceDemo(void)
774 {
775 advancedemo = true;
776 }
777
778 //==========================================================================
779 //
780 // H2_DoAdvanceDemo
781 //
782 //==========================================================================
783
H2_DoAdvanceDemo(void)784 void H2_DoAdvanceDemo(void)
785 {
786 players[consoleplayer].playerstate = PST_LIVE; // don't reborn
787 advancedemo = false;
788 usergame = false; // can't save/end game here
789 paused = false;
790 gameaction = ga_nothing;
791 demosequence = (demosequence+1)%7;
792 switch(demosequence)
793 {
794 case 0:
795 pagetic = 280;
796 gamestate = GS_DEMOSCREEN;
797 pagename = "TITLE";
798 S_StartSongName("hexen", true);
799 break;
800 case 1:
801 pagetic = 210;
802 gamestate = GS_DEMOSCREEN;
803 pagename = "TITLE";
804 break;
805 case 2:
806 BorderNeedRefresh = true;
807 UpdateState |= I_FULLSCRN;
808 G_DeferedPlayDemo("demo1");
809 break;
810 case 3:
811 pagetic = 200;
812 gamestate = GS_DEMOSCREEN;
813 pagename = "CREDIT";
814 break;
815 case 4:
816 BorderNeedRefresh = true;
817 UpdateState |= I_FULLSCRN;
818 G_DeferedPlayDemo("demo2");
819 break;
820 case 5:
821 pagetic = 200;
822 gamestate = GS_DEMOSCREEN;
823 pagename = "CREDIT";
824 break;
825 case 6:
826 BorderNeedRefresh = true;
827 UpdateState |= I_FULLSCRN;
828 G_DeferedPlayDemo("demo3");
829 break;
830 }
831 }
832
833 //==========================================================================
834 //
835 // H2_StartTitle
836 //
837 //==========================================================================
838
H2_StartTitle(void)839 void H2_StartTitle(void)
840 {
841 gameaction = ga_nothing;
842 demosequence = -1;
843 H2_AdvanceDemo();
844 }
845
846 //==========================================================================
847 //
848 // CheckRecordFrom
849 //
850 // -recordfrom <savegame num> <demoname>
851 //
852 //==========================================================================
853
CheckRecordFrom(void)854 static void CheckRecordFrom(void)
855 {
856 int p;
857
858 p = M_CheckParm("-recordfrom");
859 if(!p || p > myargc-2)
860 { // Bad args
861 return;
862 }
863 G_LoadGame(atoi(myargv[p+1]));
864 G_DoLoadGame(); // Load the gameskill etc info from savegame
865 G_RecordDemo(gameskill, 1, gameepisode, gamemap, myargv[p+2]);
866 H2_GameLoop(); // Never returns
867 }
868
869 //==========================================================================
870 //
871 // AddWADFile
872 //
873 //==========================================================================
874
AddWADFile(char * file)875 static void AddWADFile(char *file)
876 {
877 int i;
878 char *new;
879
880 ST_Message("Adding external file: %s\n", file);
881 i = 0;
882 while(wadfiles[i])
883 {
884 i++;
885 }
886 new = malloc(strlen(file)+1);
887 strcpy(new, file);
888 wadfiles[i] = new;
889 }
890
891 #ifdef __WATCOMC__
892 /*
893 void CleanExit(void)
894 {
895 union REGS regs;
896
897 I_ShutdownKeyboard();
898 regs.x.eax = 0x3;
899 int386(0x10, ®s, ®s);
900 printf("Exited from HEXEN: Beyond Heretic.\n");
901 exit(1);
902 }
903 */
904 #endif
905
906 //==========================================================================
907 //
908 // FixedDiv
909 //
910 //==========================================================================
911
912 /* fixed_t FixedDiv(fixed_t a, fixed_t b)
913 {
914 if((abs(a)>>14) >= abs(b))
915 {
916 return((a^b)<0 ? MININT : MAXINT);
917 }
918 return(FixedDiv2(a, b));
919 }
920 */
921
922 //==========================================================================
923 //
924 // CreateSavePath
925 //
926 //==========================================================================
927
928
929
CreateSavePath(void)930 static void CreateSavePath(void)
931 {
932 static char creationPath[255];
933 int len;
934 char *homedir;
935
936 if(cdrom == true)
937 {
938 SavePath = "/cdrom/hexndata";
939 }
940 len = strlen(SavePath);
941 if (len >= 120) I_Error("Save path too long\n");
942 strcpy(creationPath, SavePath);
943
944 /* XXX Create a save path in home directory */
945 #ifndef MUSTDIE
946 homedir=getenv("HOME");
947 if (!homedir) I_Error("Cannot locate home directory!\n");
948 strcpy(creationPath,homedir);
949 strcat(creationPath,"/.hexendata/");
950 #else
951 strcpy(creationPath,"HEXNDATA\\");
952 #endif
953 mkdir(creationPath,0700);
954 SavePath=creationPath;
955 }
956
957 #ifdef TIMEBOMB
958 //==========================================================================
959 //
960 // DoTimeBomb
961 //
962 //==========================================================================
963
DoTimeBomb(void)964 static void DoTimeBomb(void)
965 {
966 #ifdef __WATCOMC__
967 time_t timeOfDay;
968 struct tm timeBuffer;
969
970 timeOfDay = time(NULL);
971 _localtime(&timeOfDay, &timeBuffer);
972 if(timeBuffer.tm_year != TIMEBOMB_YEAR
973 || timeBuffer.tm_yday < TIMEBOMB_STARTDATE
974 || timeBuffer.tm_yday > TIMEBOMB_ENDDATE)
975 {
976 I_Error("W_InitWadfiles: Wad file doesn't have IWAD or PWAD id\n");
977 }
978
979 printf("\n===============================================================================\n");
980 printf(" Hexen: Beyond Heretic\n\n");
981 printf(" Beta -- Do Not Distribute!\n");
982 printf(" Press any key to continue.\n");
983 printf("===============================================================================\n");
984
985 getch();
986 printf("\n");
987 #endif
988 }
989 #endif
990