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;
95 eventhead = (++eventhead)&(MAXEVENTS-1);
98 //---------------------------------------------------------------------------
100 // PROC D_ProcessEvents
102 // Send all the events of the given timestamp down the responder chain.
104 //---------------------------------------------------------------------------
106 void D_ProcessEvents(void)
110 for(; eventtail != eventhead; eventtail = (++eventtail)&(MAXEVENTS-1))
112 ev = &events[eventtail];
125 //---------------------------------------------------------------------------
129 //---------------------------------------------------------------------------
131 void DrawMessage(void)
135 player = &players[consoleplayer];
136 if(player->messageTics <= 0 || !player->message)
140 MN_DrTextA(player->message, 160-MN_TextAWidth(player->message)/2, 1);
143 //---------------------------------------------------------------------------
147 // Draw current display, possibly wiping it from the previous.
149 //---------------------------------------------------------------------------
151 void R_ExecuteSetViewSize(void);
153 extern boolean finalestage;
157 extern boolean MenuActive;
158 extern boolean askforquit;
160 // Change the view size if needed
163 R_ExecuteSetViewSize();
167 // do buffered drawing
177 R_RenderPlayerView (&players[displayplayer]);
179 UpdateState |= I_FULLVIEW;
182 case GS_INTERMISSION:
193 if(paused && !MenuActive && !askforquit)
197 V_DrawPatch(160, viewwindowy+5, W_CacheLumpName("PAUSED",
202 V_DrawPatch(160, 70, W_CacheLumpName("PAUSED",
208 if( OGL_DrawFilter() )
209 BorderNeedRefresh = true;
212 // Handle player messages
218 // Send out any new accumulation
221 // Flush buffered stuff to screen
225 //---------------------------------------------------------------------------
229 //---------------------------------------------------------------------------
231 void D_DoomLoop(void)
233 if(M_CheckParm("-debugfile"))
236 sprintf(filename, "debug%i.txt", consoleplayer);
237 debugfile = fopen(filename,"w");
242 // Frame syncronous IO operations
245 // Process one or more tics
250 G_BuildTiccmd(&netcmds[consoleplayer][maketic%BACKUPTICS]);
259 // Will run at least one tic
263 // Move positional sounds
264 S_UpdateSounds(players[consoleplayer].mo);
270 ===============================================================================
274 ===============================================================================
287 = Handles timing for warped projection
292 void D_PageTicker (void)
307 extern boolean MenuActive;
309 void D_PageDrawer(void)
311 V_DrawRawScreen(W_CacheLumpName(pagename, PU_CACHE));
312 if(demosequence == 1)
314 V_DrawPatch(4, 160, W_CacheLumpName("ADVISOR", PU_CACHE));
316 UpdateState |= I_FULLSCRN;
324 = Called after each demo or intro demosequence finishes
328 void D_AdvanceDemo (void)
333 void D_DoAdvanceDemo (void)
335 players[consoleplayer].playerstate = PST_LIVE; // don't reborn
337 usergame = false; // can't save / end game here
339 gameaction = ga_nothing;
340 demosequence = (demosequence+1)%7;
341 switch (demosequence)
345 gamestate = GS_DEMOSCREEN;
347 S_StartSong(mus_titl, false);
351 gamestate = GS_DEMOSCREEN;
355 BorderNeedRefresh = true;
356 UpdateState |= I_FULLSCRN;
357 G_DeferedPlayDemo ("demo1");
361 gamestate = GS_DEMOSCREEN;
365 BorderNeedRefresh = true;
366 UpdateState |= I_FULLSCRN;
367 G_DeferedPlayDemo ("demo2");
371 gamestate = GS_DEMOSCREEN;
382 BorderNeedRefresh = true;
383 UpdateState |= I_FULLSCRN;
384 G_DeferedPlayDemo ("demo3");
398 void D_StartTitle (void)
400 gameaction = ga_nothing;
411 = -recordfrom <savegame num> <demoname>
415 void D_CheckRecordFrom (void)
420 p = M_CheckParm ("-recordfrom");
421 if (!p || p > myargc-2)
426 sprintf(file, SAVEGAMENAMECD"%c.hsg",myargv[p+1][0]);
430 sprintf(file, SAVEGAMENAME"%c.hsg",myargv[p+1][0]);
433 G_DoLoadGame (); // load the gameskill etc info from savegame
435 G_RecordDemo (gameskill, 1, gameepisode, gamemap, myargv[p+2]);
436 D_DoomLoop (); // never returns
447 #define MAXWADFILES 20
449 // MAPDIR should be defined as the directory that holds development maps
450 // for the -wart # # command
454 #define MAPDIR "/Novell/Heretic/data/"
456 #define SHAREWAREWADNAME "/Novell/Heretic/source/heretic1.wad"
458 char *wadfiles[MAXWADFILES] =
460 "/Novell/Heretic/source/heretic.wad",
461 "/Novell/Heretic/data/texture1.lmp",
462 "/Novell/Heretic/data/texture2.lmp",
463 "/Novell/Heretic/data/pnames.lmp"
468 #define MAPDIR "\\data\\"
470 #define SHAREWAREWADNAME "heretic1.wad"
472 char *wadfiles[MAXWADFILES] =
482 char *basedefault = "heretic.cfg";
494 _settextposition(23, 2);
498 _settextposition(24, 2);
503 void D_AddFile(char *file)
509 for(numwadfiles = 0; wadfiles[numwadfiles]; numwadfiles++);
510 new = malloc(strlen(file)+1);
512 if(strlen(exrnwads)+strlen(file) < 78)
516 strcat(exrnwads, ", ");
520 strcpy(exrnwads, "External Wadfiles: ");
522 strcat(exrnwads, file);
524 else if(strlen(exrnwads2)+strlen(file) < 79)
526 if(strlen(exrnwads2))
528 strcat(exrnwads2, ", ");
532 strcpy(exrnwads2, " ");
533 strcat(exrnwads, ",");
535 strcat(exrnwads2, file);
537 wadfiles[numwadfiles] = new;
540 //==========================================================
542 // Startup Thermo code
544 //==========================================================
548 //#define THERMCOLOR 3
554 char *startup; // * to text screen
555 char smsg[80]; // status bar line
558 // Heretic startup screen shit
563 void hgotoxy(int x,int y)
565 hscreen = (byte *)(0xb8000 + y*160 + x*2);
568 void hput(unsigned char c, unsigned char a)
574 void hprintf(char *string, unsigned char a)
584 for(i = 0; i < strlen(string); i++)
591 void drawstatus(void)
598 _settextposition(25, 2);
602 _settextposition(25, 1);
606 void status(char *string)
612 void DrawThermo(void)
615 unsigned char *screen;
624 progress = (98*thermCurrent)/thermMax;
625 screen = (char *)0xb8000 + (THERM_Y*160 + THERM_X*2);
626 for (i = 0;i < progress/2; i++)
639 *screen++ = (THERMCOLOR<<4)+15;
643 *screen++ = (THERMCOLOR<<4)+15;
647 *screen++ = 0x40 + THERMCOLOR;
654 *screen++ = 0x40 + THERMCOLOR;
657 progress = (50*thermCurrent)/thermMax+2;
658 // screen = (char *)0xb8000 + (THERM_Y*160 + THERM_X*2);
659 hgotoxy(THERM_X,THERM_Y);
660 for (i = 0; i < progress; i++)
671 void blitStartup(void)
681 textScreen = (byte *)0xb8000;
682 memcpy(textScreen, startup, 4000);
684 // Print version string
685 _setbkcolor(4); // Red
686 _settextcolor(14); // Yellow
687 _settextposition(3, 47);
688 _outtext(VERSION_TEXT);
691 _settextcursor(0x2000);
696 void tprintf(char *msg,int initflag)
718 for (add = start = i = 0; i <= strlen(tmsg); i++)
719 if ((tmsg[i] == '\n') || (!tmsg[i]))
722 strncpy(temp,tmsg+start,i-start);
723 _settextposition(MSG_Y+add,40-strlen(temp)/2);
728 _settextposition(25,1);
735 void CheckAbortStartup(void)
738 extern int lastpress;
741 { // Abort if escape pressed
754 void InitThermo(int max)
765 I_ShutdownKeyboard();
767 int386(0x10, ®s, ®s);
768 printf("Exited from HERETIC.\n");
773 //---------------------------------------------------------------------------
777 //---------------------------------------------------------------------------
779 void D_DoomMain(void)
789 M_FindResponseFile();
790 setbuf(stdout, NULL);
791 nomonsters = M_CheckParm("-nomonsters");
792 respawnparm = M_CheckParm("-respawn");
793 ravpic = M_CheckParm("-ravpic");
794 noartiskip = M_CheckParm("-noartiskip");
795 debugmode = M_CheckParm("-debug");
796 startskill = sk_medium;
801 // wadfiles[0] is a char * to the main wad
802 fp = fopen(wadfiles[0], "rb");
808 { // Change to look for shareware wad
809 wadfiles[0] = SHAREWAREWADNAME;
815 if(M_CheckParm("-cdrom"))
818 mkdir("c:\\heretic.cd");
822 // -FILE [filename] [filename] ...
823 // Add files to the wad list.
824 p = M_CheckParm("-file");
826 { // the parms after p are wadfile/lump names, until end of parms
827 // or another - preceded parm
828 while(++p != myargc && myargv[p][0] != '-')
830 D_AddFile(myargv[p]);
834 // -DEVMAP <episode> <map>
835 // Adds a map wad from the development directory to the wad list,
836 // and sets the start episode and the start map.
838 p = M_CheckParm("-devmap");
839 if(p && p < myargc-2)
843 sprintf(file, MAPDIR"E%cM%c.wad", e, m);
845 printf("DEVMAP: Episode %c, Map %c.\n", e, m);
846 startepisode = e-'0';
852 p = M_CheckParm("-playdemo");
855 p = M_CheckParm("-timedemo");
857 if (p && p < myargc-1)
859 sprintf(file, "%s.lmp", myargv[p+1]);
861 printf("Playing demo %s.lmp.\n", myargv[p+1]);
865 // get skill / episode / map from parms
867 if(M_CheckParm("-deathmatch"))
872 p = M_CheckParm("-skill");
873 if(p && p < myargc-1)
875 startskill = myargv[p+1][0]-'1';
879 p = M_CheckParm("-episode");
880 if(p && p < myargc-1)
882 startepisode = myargv[p+1][0]-'0';
887 p = M_CheckParm("-warp");
888 if(p && p < myargc-2)
890 startepisode = myargv[p+1][0]-'0';
891 startmap = myargv[p+2][0]-'0';
898 printf("V_Init: allocate screens.\n");
901 // Load defaults before initing other systems
902 printf("M_LoadDefaults: Load system defaults.\n");
905 printf("Z_Init: Init zone memory allocation daemon.\n");
908 printf("W_Init: Init WADfiles.\n");
909 W_InitMultipleFiles(wadfiles);
911 if(W_CheckNumForName("E2M1") == -1)
912 { // Can't find episode 2 maps, must be the shareware WAD
915 else if(W_CheckNumForName("EXTENDED") != -1)
916 { // Found extended lump, must be the extended WAD
925 // No use caching this if we're not going to use it - DDOI
926 startup = W_CacheLumpName("LOADING", PU_CACHE);
931 // Build status bar line!
935 status("DeathMatch...");
937 status("No Monsters...");
939 status("Respawning...");
943 sprintf(temp, "Warp to Episode %d, Map %d, Skill %d ",
944 startepisode, startmap, startskill+1);
947 wadprintf(); // print the added wadfiles
949 tprintf("MN_Init: Init menu system.\n",1);
954 tprintf("R_Init: Init Heretic refresh daemon.",1);
956 hprintf("Loading graphics",0x3f);
959 tprintf("P_Init: Init Playloop state.",1);
961 hprintf("Init game engine.",0x3f);
965 tprintf("I_Init: Setting up machine state.\n",1);
969 tprintf("D_CheckNetGame: Checking network game status.\n",1);
971 hprintf("Checking network game status.", 0x3f);
976 I_CheckExternDriver(); // Check for an external device driver
979 tprintf("SB_Init: Loading patches.\n",1);
984 // start the apropriate game based on parms
989 p = M_CheckParm("-record");
990 if(p && p < myargc-1)
992 G_RecordDemo(startskill, 1, startepisode, startmap, myargv[p+1]);
993 D_DoomLoop(); // Never returns
996 p = M_CheckParm("-playdemo");
997 if(p && p < myargc-1)
999 singledemo = true; // Quit after one demo
1000 G_DeferedPlayDemo(myargv[p+1]);
1001 D_DoomLoop(); // Never returns
1004 p = M_CheckParm("-timedemo");
1005 if(p && p < myargc-1)
1007 G_TimeDemo(myargv[p+1]);
1008 D_DoomLoop(); // Never returns
1011 p = M_CheckParm("-loadgame");
1012 if(p && p < myargc-1)
1016 sprintf(file, SAVEGAMENAMECD"%c.hsg", myargv[p+1][0]);
1020 sprintf(file, SAVEGAMENAME"%c.hsg", myargv[p+1][0]);
1025 // Check valid episode and map
1026 if((autostart || netgame) && (devMap == false))
1028 if(M_ValidEpisodeMap(startepisode, startmap) == false)
1035 if(gameaction != ga_loadgame)
1037 UpdateState |= I_FULLSCRN;
1038 BorderNeedRefresh = true;
1039 if(autostart || netgame)
1041 G_InitNew(startskill, startepisode, startmap);
1049 _settextcursor(0x0607); // bring the cursor back
1051 D_DoomLoop(); // Never returns