H2_MAIN.C 21 KB

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