18 #define W_CacheLumpName(a,b) W_GetNumForName(a)
19 #define V_DrawPatch(x,y,p) OGL_DrawPatch(x,y,p)
20 #define V_DrawRawScreen(a) OGL_DrawRawScreen(a)
23 boolean shareware = false; // true if only episode 1 present
24 boolean ExtendedWAD = false; // true if episodes 4 and 5 present
26 boolean nomonsters; // checkparm of -nomonsters
27 boolean respawnparm; // checkparm of -respawn
28 boolean debugmode; // checkparm of -debug
29 boolean ravpic; // checkparm of -ravpic
30 boolean cdrom; // true if cd-rom mode active
31 boolean singletics; // debug flag to cancel adaptiveness
32 boolean noartiskip; // whether shift-enter skips an artifact
38 extern boolean automapactive;
44 void D_CheckNetGame(void);
45 void D_ProcessEvents(void);
46 void G_BuildTiccmd(ticcmd_t *cmd);
47 void D_DoAdvanceDemo(void);
48 void D_PageDrawer (void);
49 void D_AdvanceDemo (void);
51 boolean F_Responder(event_t *ev);
53 //---------------------------------------------------------------------------
57 //---------------------------------------------------------------------------
59 fixed_t FixedDiv(fixed_t a, fixed_t b)
61 if((abs(a)>>14) >= abs(b))
63 return((a^b)<0 ? MININT : MAXINT);
65 return(FixedDiv2(a, b));
69 ===============================================================================
73 Events are asyncronous inputs generally generated by the game user.
75 Events can be discarded if no responder claims them
77 ===============================================================================
80 event_t events[MAXEVENTS];
84 //---------------------------------------------------------------------------
88 // Called by the I/O functions when input is detected.
90 //---------------------------------------------------------------------------
92 void D_PostEvent(event_t *ev)
94 events[eventhead] = *ev;
96 eventhead &= (MAXEVENTS-1);
99 //---------------------------------------------------------------------------
101 // PROC D_ProcessEvents
103 // Send all the events of the given timestamp down the responder chain.
105 //---------------------------------------------------------------------------
107 void D_ProcessEvents(void)
111 for(; eventtail != eventhead; eventtail = (++eventtail)&(MAXEVENTS-1))
113 ev = &events[eventtail];
126 //---------------------------------------------------------------------------
130 //---------------------------------------------------------------------------
132 void DrawMessage(void)
136 player = &players[consoleplayer];
137 if(player->messageTics <= 0 || !player->message)
141 MN_DrTextA(player->message, 160-MN_TextAWidth(player->message)/2, 1);
144 //---------------------------------------------------------------------------
148 // Draw current display, possibly wiping it from the previous.
150 //---------------------------------------------------------------------------
152 void R_ExecuteSetViewSize(void);
154 extern boolean finalestage;
158 extern boolean MenuActive;
159 extern boolean askforquit;
161 // Change the view size if needed
164 R_ExecuteSetViewSize();
168 // do buffered drawing
178 R_RenderPlayerView (&players[displayplayer]);
180 UpdateState |= I_FULLVIEW;
183 case GS_INTERMISSION:
194 if(paused && !MenuActive && !askforquit)
198 V_DrawPatch(160, viewwindowy+5, W_CacheLumpName("PAUSED",
203 V_DrawPatch(160, 70, W_CacheLumpName("PAUSED",
209 if( OGL_DrawFilter() )
210 BorderNeedRefresh = true;
213 // Handle player messages
219 // Send out any new accumulation
222 // Flush buffered stuff to screen
226 //---------------------------------------------------------------------------
230 //---------------------------------------------------------------------------
232 void D_DoomLoop(void)
234 if(M_CheckParm("-debugfile"))
237 sprintf(filename, "debug%i.txt", consoleplayer);
238 debugfile = fopen(filename,"w");
243 // Frame syncronous IO operations
246 // Process one or more tics
251 G_BuildTiccmd(&netcmds[consoleplayer][maketic%BACKUPTICS]);
260 // Will run at least one tic
264 // Move positional sounds
265 S_UpdateSounds(players[consoleplayer].mo);
271 ===============================================================================
275 ===============================================================================
288 = Handles timing for warped projection
293 void D_PageTicker (void)
308 extern boolean MenuActive;
310 void D_PageDrawer(void)
312 V_DrawRawScreen(W_CacheLumpName(pagename, PU_CACHE));
313 if(demosequence == 1)
315 V_DrawPatch(4, 160, W_CacheLumpName("ADVISOR", PU_CACHE));
317 UpdateState |= I_FULLSCRN;
325 = Called after each demo or intro demosequence finishes
329 void D_AdvanceDemo (void)
334 void D_DoAdvanceDemo (void)
336 players[consoleplayer].playerstate = PST_LIVE; // don't reborn
338 usergame = false; // can't save / end game here
340 gameaction = ga_nothing;
341 demosequence = (demosequence+1)%7;
342 switch (demosequence)
346 gamestate = GS_DEMOSCREEN;
348 S_StartSong(mus_titl, false);
352 gamestate = GS_DEMOSCREEN;
356 BorderNeedRefresh = true;
357 UpdateState |= I_FULLSCRN;
358 G_DeferedPlayDemo ("demo1");
362 gamestate = GS_DEMOSCREEN;
366 BorderNeedRefresh = true;
367 UpdateState |= I_FULLSCRN;
368 G_DeferedPlayDemo ("demo2");
372 gamestate = GS_DEMOSCREEN;
383 BorderNeedRefresh = true;
384 UpdateState |= I_FULLSCRN;
385 G_DeferedPlayDemo ("demo3");
399 void D_StartTitle (void)
401 gameaction = ga_nothing;
412 = -recordfrom <savegame num> <demoname>
416 void D_CheckRecordFrom (void)
421 p = M_CheckParm ("-recordfrom");
422 if (!p || p > myargc-2)
427 sprintf(file, SAVEGAMENAMECD"%c.hsg",myargv[p+1][0]);
431 sprintf(file, SAVEGAMENAME"%c.hsg",myargv[p+1][0]);
434 G_DoLoadGame (); // load the gameskill etc info from savegame
436 G_RecordDemo (gameskill, 1, gameepisode, gamemap, myargv[p+2]);
437 D_DoomLoop (); // never returns
448 #define MAXWADFILES 20
450 // MAPDIR should be defined as the directory that holds development maps
451 // for the -wart # # command
455 #define MAPDIR "/Novell/Heretic/data/"
457 #define SHAREWAREWADNAME "/Novell/Heretic/source/heretic1.wad"
459 char *wadfiles[MAXWADFILES] =
461 "/Novell/Heretic/source/heretic.wad",
462 "/Novell/Heretic/data/texture1.lmp",
463 "/Novell/Heretic/data/texture2.lmp",
464 "/Novell/Heretic/data/pnames.lmp"
469 #define MAPDIR "\\data\\"
471 #define SHAREWAREWADNAME "heretic1.wad"
473 char *wadfiles[MAXWADFILES] =
483 char *basedefault = "heretic.cfg";
495 _settextposition(23, 2);
499 _settextposition(24, 2);
504 void D_AddFile(char *file)
510 for(numwadfiles = 0; wadfiles[numwadfiles]; numwadfiles++);
511 new = malloc(strlen(file)+1);
513 if(strlen(exrnwads)+strlen(file) < 78)
517 strcat(exrnwads, ", ");
521 strcpy(exrnwads, "External Wadfiles: ");
523 strcat(exrnwads, file);
525 else if(strlen(exrnwads2)+strlen(file) < 79)
527 if(strlen(exrnwads2))
529 strcat(exrnwads2, ", ");
533 strcpy(exrnwads2, " ");
534 strcat(exrnwads, ",");
536 strcat(exrnwads2, file);
538 wadfiles[numwadfiles] = new;
541 //==========================================================
543 // Startup Thermo code
545 //==========================================================
549 //#define THERMCOLOR 3
555 char *startup; // * to text screen
556 char smsg[80]; // status bar line
559 // Heretic startup screen shit
564 void hgotoxy(int x,int y)
566 hscreen = (byte *)(0xb8000 + y*160 + x*2);
569 void hput(unsigned char c, unsigned char a)
575 void hprintf(char *string, unsigned char a)
585 for(i = 0; i < strlen(string); i++)
592 void drawstatus(void)
599 _settextposition(25, 2);
603 _settextposition(25, 1);
607 void status(char *string)
613 void DrawThermo(void)
616 unsigned char *screen;
625 progress = (98*thermCurrent)/thermMax;
626 screen = (char *)0xb8000 + (THERM_Y*160 + THERM_X*2);
627 for (i = 0;i < progress/2; i++)
640 *screen++ = (THERMCOLOR<<4)+15;
644 *screen++ = (THERMCOLOR<<4)+15;
648 *screen++ = 0x40 + THERMCOLOR;
655 *screen++ = 0x40 + THERMCOLOR;
658 progress = (50*thermCurrent)/thermMax+2;
659 // screen = (char *)0xb8000 + (THERM_Y*160 + THERM_X*2);
660 hgotoxy(THERM_X,THERM_Y);
661 for (i = 0; i < progress; i++)
672 void blitStartup(void)
682 textScreen = (byte *)0xb8000;
683 memcpy(textScreen, startup, 4000);
685 // Print version string
686 _setbkcolor(4); // Red
687 _settextcolor(14); // Yellow
688 _settextposition(3, 47);
689 _outtext(VERSION_TEXT);
692 _settextcursor(0x2000);
697 void tprintf(char *msg,int initflag)
719 for (add = start = i = 0; i <= strlen(tmsg); i++)
720 if ((tmsg[i] == '\n') || (!tmsg[i]))
723 strncpy(temp,tmsg+start,i-start);
724 _settextposition(MSG_Y+add,40-strlen(temp)/2);
729 _settextposition(25,1);
736 void CheckAbortStartup(void)
739 extern int lastpress;
742 { // Abort if escape pressed
755 void InitThermo(int max)
766 I_ShutdownKeyboard();
768 int386(0x10, ®s, ®s);
769 printf("Exited from HERETIC.\n");
774 //---------------------------------------------------------------------------
778 //---------------------------------------------------------------------------
780 void D_DoomMain(void)
790 M_FindResponseFile();
791 setbuf(stdout, NULL);
792 nomonsters = M_CheckParm("-nomonsters");
793 respawnparm = M_CheckParm("-respawn");
794 ravpic = M_CheckParm("-ravpic");
795 noartiskip = M_CheckParm("-noartiskip");
796 debugmode = M_CheckParm("-debug");
797 startskill = sk_medium;
802 // wadfiles[0] is a char * to the main wad
803 fp = fopen(wadfiles[0], "rb");
809 { // Change to look for shareware wad
810 wadfiles[0] = SHAREWAREWADNAME;
816 if(M_CheckParm("-cdrom"))
819 mkdir("c:\\heretic.cd");
823 // -FILE [filename] [filename] ...
824 // Add files to the wad list.
825 p = M_CheckParm("-file");
827 { // the parms after p are wadfile/lump names, until end of parms
828 // or another - preceded parm
829 while(++p != myargc && myargv[p][0] != '-')
831 D_AddFile(myargv[p]);
835 // -DEVMAP <episode> <map>
836 // Adds a map wad from the development directory to the wad list,
837 // and sets the start episode and the start map.
839 p = M_CheckParm("-devmap");
840 if(p && p < myargc-2)
844 sprintf(file, MAPDIR"E%cM%c.wad", e, m);
846 printf("DEVMAP: Episode %c, Map %c.\n", e, m);
847 startepisode = e-'0';
853 p = M_CheckParm("-playdemo");
856 p = M_CheckParm("-timedemo");
858 if (p && p < myargc-1)
860 sprintf(file, "%s.lmp", myargv[p+1]);
862 printf("Playing demo %s.lmp.\n", myargv[p+1]);
866 // get skill / episode / map from parms
868 if(M_CheckParm("-deathmatch"))
873 p = M_CheckParm("-skill");
874 if(p && p < myargc-1)
876 startskill = myargv[p+1][0]-'1';
880 p = M_CheckParm("-episode");
881 if(p && p < myargc-1)
883 startepisode = myargv[p+1][0]-'0';
888 p = M_CheckParm("-warp");
889 if(p && p < myargc-2)
891 startepisode = myargv[p+1][0]-'0';
892 startmap = myargv[p+2][0]-'0';
899 printf("V_Init: allocate screens.\n");
902 // Load defaults before initing other systems
903 printf("M_LoadDefaults: Load system defaults.\n");
906 printf("Z_Init: Init zone memory allocation daemon.\n");
909 printf("W_Init: Init WADfiles.\n");
910 W_InitMultipleFiles(wadfiles);
912 if(W_CheckNumForName("E2M1") == -1)
913 { // Can't find episode 2 maps, must be the shareware WAD
916 else if(W_CheckNumForName("EXTENDED") != -1)
917 { // Found extended lump, must be the extended WAD
926 // No use caching this if we're not going to use it - DDOI
927 startup = W_CacheLumpName("LOADING", PU_CACHE);
932 // Build status bar line!
936 status("DeathMatch...");
938 status("No Monsters...");
940 status("Respawning...");
944 sprintf(temp, "Warp to Episode %d, Map %d, Skill %d ",
945 startepisode, startmap, startskill+1);
948 wadprintf(); // print the added wadfiles
950 tprintf("MN_Init: Init menu system.\n",1);
955 tprintf("R_Init: Init Heretic refresh daemon.",1);
957 hprintf("Loading graphics",0x3f);
960 tprintf("P_Init: Init Playloop state.",1);
962 hprintf("Init game engine.",0x3f);
966 tprintf("I_Init: Setting up machine state.\n",1);
970 tprintf("D_CheckNetGame: Checking network game status.\n",1);
972 hprintf("Checking network game status.", 0x3f);
977 I_CheckExternDriver(); // Check for an external device driver
980 tprintf("SB_Init: Loading patches.\n",1);
985 // start the apropriate game based on parms
990 p = M_CheckParm("-record");
991 if(p && p < myargc-1)
993 G_RecordDemo(startskill, 1, startepisode, startmap, myargv[p+1]);
994 D_DoomLoop(); // Never returns
997 p = M_CheckParm("-playdemo");
998 if(p && p < myargc-1)
1000 singledemo = true; // Quit after one demo
1001 G_DeferedPlayDemo(myargv[p+1]);
1002 D_DoomLoop(); // Never returns
1005 p = M_CheckParm("-timedemo");
1006 if(p && p < myargc-1)
1008 G_TimeDemo(myargv[p+1]);
1009 D_DoomLoop(); // Never returns
1012 p = M_CheckParm("-loadgame");
1013 if(p && p < myargc-1)
1017 sprintf(file, SAVEGAMENAMECD"%c.hsg", myargv[p+1][0]);
1021 sprintf(file, SAVEGAMENAME"%c.hsg", myargv[p+1][0]);
1026 // Check valid episode and map
1027 if((autostart || netgame) && (devMap == false))
1029 if(M_ValidEpisodeMap(startepisode, startmap) == false)
1036 if(gameaction != ga_loadgame)
1038 UpdateState |= I_FULLSCRN;
1039 BorderNeedRefresh = true;
1040 if(autostart || netgame)
1042 G_InitNew(startskill, startepisode, startmap);
1050 _settextcursor(0x0607); // bring the cursor back
1052 D_DoomLoop(); // Never returns