1 /* Catacomb Apocalypse Source Code
\r
2 * Copyright (C) 1993-2014 Flat Rock Software
\r
4 * This program is free software; you can redistribute it and/or modify
\r
5 * it under the terms of the GNU General Public License as published by
\r
6 * the Free Software Foundation; either version 2 of the License, or
\r
7 * (at your option) any later version.
\r
9 * This program is distributed in the hope that it will be useful,
\r
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
12 * GNU General Public License for more details.
\r
14 * You should have received a copy of the GNU General Public License along
\r
15 * with this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
32 =============================================================================
\r
36 =============================================================================
\r
41 =============================================================================
\r
45 =============================================================================
\r
48 typedef enum demo_screens {sc_logo,sc_title,sc_credits1,sc_credits2,sc_credits3,sc_credits4,sc_end} demo_screens;
\r
65 PresenterInfo MainHelpText;
\r
67 GameDiff restartgame;
\r
68 boolean loadedgame,abortgame,ingame;
\r
71 memptr scalesegs[NUMPICS];
\r
72 char str[80],str2[20];
\r
73 unsigned tedlevelnum;
\r
83 boolean LoadShapes = true;
\r
84 boolean EASYMODEON = false;
\r
86 void DisplayIntroText(void);
\r
89 =============================================================================
\r
93 =============================================================================
\r
98 //===========================================================================
\r
102 #define MyInterrupt 0x60
\r
103 void interrupt (*intaddr)();
\r
104 void interrupt (*oldintaddr)();
\r
105 char *JHParmStrings[] = {"no386",nil};
\r
110 extern void far jabhack2(void);
\r
111 extern int far CheckIs386(void);
\r
115 oldintaddr = getvect(MyInterrupt);
\r
117 for (i = 1;i < _argc;i++)
\r
118 if (US_CheckParm(_argv[i],JHParmStrings) == 0)
\r
124 setvect(MyInterrupt,intaddr);
\r
131 setvect(MyInterrupt,oldintaddr);
\r
136 //===========================================================================
\r
139 =====================
\r
143 = Set up new game to start from the beginning
\r
145 =====================
\r
148 void NewGame (void)
\r
152 memset (&gamestate,0,sizeof(gamestate));
\r
153 gamestate.mapon = starting_level;
\r
154 gamestate.body = MAXBODY;
\r
157 BGFLAGS = BGF_NOT_LIGHTNING;
\r
160 boltsleft = bolttimer = 0;
\r
162 // memset (gamestate.levels,-1,sizeof(gamestate.levels));
\r
165 //===========================================================================
\r
167 #define RLETAG 0xABCD
\r
177 boolean SaveTheGame(int file)
\r
179 word i,compressed,expanded;
\r
183 // save the sky and ground colors
\r
184 if (!CA_FarWrite(file,(void far *)&skycolor,sizeof(skycolor)))
\r
186 if (!CA_FarWrite(file,(void far *)&groundcolor,sizeof(groundcolor)))
\r
189 if (!CA_FarWrite(file,(void far *)&FreezeTime,sizeof(FreezeTime)))
\r
192 if (!CA_FarWrite(file,(void far *)&gamestate,sizeof(gamestate)))
\r
195 if (!CA_FarWrite(file,(void far *)&EASYMODEON,sizeof(EASYMODEON)))
\r
198 expanded = mapwidth * mapheight * 2;
\r
199 MM_GetPtr (&bigbuffer,expanded);
\r
201 for (i = 0;i < 3;i+=2) // Write planes 0 and 2
\r
204 // leave a word at start of compressed data for compressed length
\r
206 compressed = (unsigned)CA_RLEWCompress ((unsigned huge *)mapsegs[i]
\r
207 ,expanded,((unsigned huge *)bigbuffer)+1,RLETAG);
\r
209 *(unsigned huge *)bigbuffer = compressed;
\r
211 if (!CA_FarWrite(file,(void far *)bigbuffer,compressed+2) )
\r
213 MM_FreePtr (&bigbuffer);
\r
218 for (o = player;o;o = o->next)
\r
219 if (!CA_FarWrite(file,(void far *)o,sizeof(objtype)))
\r
221 MM_FreePtr (&bigbuffer);
\r
225 MM_FreePtr (&bigbuffer);
\r
230 //===========================================================================
\r
241 boolean LoadTheGame(int file)
\r
244 objtype *obj,*prev,*next,*followed;
\r
245 unsigned compressed,expanded;
\r
246 unsigned far *map,tile;
\r
252 playstate = ex_loadedgame;
\r
253 // load the sky and ground colors
\r
254 if (!CA_FarRead(file,(void far *)&skycolor,sizeof(skycolor)))
\r
256 if (!CA_FarRead(file,(void far *)&groundcolor,sizeof(groundcolor)))
\r
259 if (!CA_FarRead(file,(void far *)&FreezeTime,sizeof(FreezeTime)))
\r
262 if (!CA_FarRead(file,(void far *)&gamestate,sizeof(gamestate)))
\r
265 if (!CA_FarRead(file,(void far *)&EASYMODEON,sizeof(EASYMODEON)))
\r
268 SetupGameLevel (); // load in and cache the base old level
\r
270 if (!FindFile(Filename,"SAVE GAME",-1))
\r
271 Quit("Error: Can't find saved game file!");
\r
273 expanded = mapwidth * mapheight * 2;
\r
274 MM_GetPtr (&bigbuffer,expanded);
\r
276 for (i = 0;i < 3;i+=2) // Read planes 0 and 2
\r
278 if (!CA_FarRead(file,(void far *)&compressed,sizeof(compressed)) )
\r
280 MM_FreePtr (&bigbuffer);
\r
284 if (!CA_FarRead(file,(void far *)bigbuffer,compressed) )
\r
286 MM_FreePtr (&bigbuffer);
\r
290 CA_RLEWexpand ((unsigned huge *)bigbuffer,
\r
291 (unsigned huge *)mapsegs[i],expanded,RLETAG);
\r
294 MM_FreePtr (&bigbuffer);
\r
296 // copy the wall data to a data segment array again, to handle doors and
\r
297 // bomb walls that are allready opened
\r
299 memset (tilemap,0,sizeof(tilemap));
\r
300 memset (actorat,0,sizeof(actorat));
\r
302 for (y=0;y<mapheight;y++)
\r
303 for (x=0;x<mapwidth;x++)
\r
306 if (tile<NUMFLOORS)
\r
308 if (tile != INVISIBLEWALL)
\r
309 tilemap[x][y] = tile;
\r
311 (unsigned)actorat[x][y] = tile;
\r
316 // Read the object list back in - assumes at least one object in list
\r
324 if (!CA_FarRead(file,(void far *)new,sizeof(objtype)))
\r
326 followed = new->next;
\r
329 actorat[new->tilex][new->tiley] = new; // drop a new marker
\r
340 //===========================================================================
\r
350 void ResetGame(void)
\r
361 //===========================================================================
\r
365 ==========================
\r
369 = Shuts down all ID_?? managers
\r
371 ==========================
\r
374 void ShutdownId (void)
\r
387 //===========================================================================
\r
390 ==========================
\r
394 = Load a few things right away
\r
396 ==========================
\r
399 void InitGame (void)
\r
401 unsigned segstart,seglength;
\r
403 unsigned *blockstart;
\r
405 // US_TextScreen();
\r
419 US_SetLoadSaveHooks(LoadTheGame,SaveTheGame,ResetGame);
\r
423 // load in and lock down some basic chunks
\r
428 CA_MarkGrChunk(STARTFONT);
\r
429 CA_MarkGrChunk(STARTTILE8);
\r
430 CA_MarkGrChunk(STARTTILE8M);
\r
431 CA_MarkGrChunk(HAND1PICM);
\r
433 CA_MarkGrChunk(NORTHICONSPR);
\r
434 CA_CacheMarks (NULL);
\r
436 MM_SetLock (&grsegs[STARTFONT],true);
\r
437 MM_SetLock (&grsegs[STARTTILE8],true);
\r
438 MM_SetLock (&grsegs[STARTTILE8M],true);
\r
439 MM_SetLock (&grsegs[HAND1PICM],true);
\r
445 // build some tables
\r
447 for (i=0;i<MAPSIZE;i++)
\r
448 nearmapylookup[i] = &tilemap[0][0]+MAPSIZE*i;
\r
450 for (i=0;i<PORTTILESHIGH;i++)
\r
451 uwidthtable[i] = UPDATEWIDE*i;
\r
453 blockstart = &blockstarts[0];
\r
454 for (y=0;y<UPDATEHIGH;y++)
\r
455 for (x=0;x<UPDATEWIDE;x++)
\r
456 *blockstart++ = SCREENWIDTH*16*y+x*TILEWIDTH;
\r
458 BuildTables (); // 3-d tables
\r
463 // US_FinishTextScreen();
\r
468 // reclaim the memory from the linked in text screen
\r
470 segstart = FP_SEG(&introscn);
\r
471 seglength = 4000/16;
\r
472 if (FP_OFF(&introscn))
\r
477 MML_UseSpace (segstart,seglength);
\r
480 VW_SetScreenMode (GRMODE);
\r
481 ge_textmode = false;
\r
482 // VW_ColorBorder (3);
\r
483 VW_ClearVideo (BLACK);
\r
486 // initialize variables
\r
488 updateptr = &update[0];
\r
489 *(unsigned *)(updateptr + UPDATEWIDE*PORTTILESHIGH) = UPDATETERMINATE;
\r
492 VW_SetLineWidth(SCREENWIDTH);
\r
495 //===========================================================================
\r
497 void clrscr (void); // can't include CONIO.H because of name conflicts...
\r
500 ==========================
\r
504 ==========================
\r
507 void Quit (char *error, ...)
\r
510 unsigned finscreen;
\r
514 va_start(ap,error);
\r
520 CA_CacheGrChunk (PIRACY);
\r
521 finscreen = (unsigned)grsegs[PIRACY];
\r
527 if (error && *error)
\r
536 movedata (finscreen,0,0xb800,0,4000);
\r
547 _argv[1] = "LAST.SHL";
\r
548 _argv[2] = "ENDSCN.SCN";
\r
550 if (execv("LOADSCN.EXE", _argv) == -1)
\r
553 puts("Couldn't find executable LOADSCN.EXE.\n");
\r
562 //===========================================================================
\r
572 void TEDDeath(void)
\r
575 execlp("TED5.EXE","TED5.EXE","/LAUNCH",NULL);
\r
578 //===========================================================================
\r
581 ====================
\r
583 = DisplayDepartment
\r
585 ====================
\r
587 void DisplayDepartment(char *text)
\r
596 VW_Bar(WindowX,PrintY+1,WindowW,7,0);
\r
599 US_CPrintLine (text);
\r
606 =====================
\r
610 =====================
\r
613 static char *ParmStrings[] = {"easy","normal","hard",""};
\r
615 void DemoLoop (void)
\r
618 /////////////////////////////////////////////////////////////////////////////
\r
620 /////////////////////////////////////////////////////////////////////////////
\r
622 displayofs = bufferofs = 0;
\r
623 VW_Bar (0,0,320,200,0);
\r
627 // Read in all the graphic images needed for the title sequence
\r
630 IN_ReadControl(0,&control);
\r
634 if (stricmp(_argv[2], "1") == 0)
\r
637 EASYMODEON = false;
\r
641 if (stricmp(_argv[3], "1") == 0)
\r
644 bufferofs = displayofs = 0;
\r
645 VW_Bar(0,0,320,200,0);
\r
649 playstate = ex_loadedgame;
\r
650 Keyboard[sc_Enter] = true;
\r
651 VW_Bar(0,0,320,200,0);
\r
654 VW_Bar(0,0,320,200,0);
\r
660 restartgame = gd_Normal;
\r
665 //-------------------------------------------------------------------------
\r
666 // DisplayIntroText()
\r
667 //-------------------------------------------------------------------------
\r
668 void DisplayIntroText()
\r
672 #ifdef TEXT_PRESENTER
\r
673 char *toptext = "You stand before the gate leading into the Towne "
\r
674 "of Morbidity.... "
\r
677 char *bottomtext = "Enter now boldly to defeat the evil Nemesis "
\r
678 "deep inside the catacombs."
\r
683 char oldfontcolor=fontcolor;
\r
688 #ifdef TEXT_PRESENTER
\r
694 pi.script[0] = (char far *)toptext;
\r
699 pi.script[0] = (char far *)bottomtext;
\r
709 US_Print (" A chilling wind greets you at the entrance\n");
\r
710 US_Print (" to the Sanctuary of the Dead.\n");
\r
715 US_Print (" Shall you proceed as\n");
\r
719 US_Print ("ovice or");
\r
723 US_Print ("arrior ?");
\r
727 fontcolor = oldfontcolor;
\r
731 boolean ChooseGameLevel()
\r
733 char choices[] = {sc_Escape,sc_E,sc_N,sc_H,0},ch;
\r
735 CenterWindow(20,10);
\r
737 US_Print("\n Choose difficulty level:\n");
\r
738 US_Print(" (E)asy\n");
\r
739 US_Print(" (N)ormal\n");
\r
740 US_Print(" (H)ard\n");
\r
741 US_Print("\n (ESC)ape aborts\n");
\r
743 // VW_UpdateScreen();
\r
744 if ((ch=GetKeyChoice(choices)) == sc_Escape)
\r
746 while (Keyboard[sc_Escape]);
\r
752 restartgame = gd_Easy;
\r
755 restartgame = gd_Normal;
\r
757 restartgame = gd_Hard;
\r
764 //===========================================================================
\r
767 ==========================
\r
771 ==========================
\r
774 void SetupScalePic (unsigned picnum)
\r
781 scnum = picnum-FIRSTSCALEPIC;
\r
783 if (shapedirectory[scnum])
\r
785 MM_SetPurge (&(memptr)shapedirectory[scnum],0);
\r
786 return; // allready in memory
\r
789 CA_CacheGrChunk (picnum);
\r
790 DeplanePic (picnum);
\r
791 shapesize[scnum] = BuildCompShape (&shapedirectory[scnum]);
\r
792 grneeded[picnum]&= ~ca_levelbit;
\r
793 MM_FreePtr (&grsegs[picnum]);
\r
796 //===========================================================================
\r
799 ==========================
\r
803 ==========================
\r
806 void SetupScaleWall (unsigned picnum)
\r
815 scnum = picnum-FIRSTWALLPIC;
\r
817 if (walldirectory[scnum])
\r
819 MM_SetPurge (&walldirectory[scnum],0);
\r
820 return; // allready in memory
\r
823 CA_CacheGrChunk (picnum);
\r
824 DeplanePic (picnum);
\r
825 MM_GetPtr(&walldirectory[scnum],64*64);
\r
826 dest = (byte far *)walldirectory[scnum];
\r
829 *dest++ = spotvis[y][x];
\r
830 grneeded[picnum]&= ~ca_levelbit;
\r
831 MM_FreePtr (&grsegs[picnum]);
\r
834 //===========================================================================
\r
837 ==========================
\r
841 ==========================
\r
844 void SetupScaling (void)
\r
850 // build the compiled scalers
\r
852 for (i=1;i<=VIEWWIDTH/2;i++)
\r
853 BuildCompScale (i*2,&scaledirectory[i]);
\r
856 //===========================================================================
\r
860 void RF_FixOfs (void)
\r
864 void HelpScreens (void)
\r
878 #define MINMEMORY 400000l
\r
880 void CheckMemory(void)
\r
882 unsigned finscreen;
\r
884 if (Flags & FL_NOMEMCHECK)
\r
887 if (mminfo.nearheap+mminfo.farheap+mminfo.EMSmem+mminfo.XMSmem
\r
891 CA_CacheGrChunk (OUTOFMEM);
\r
892 finscreen = (unsigned)grsegs[OUTOFMEM];
\r
894 movedata (finscreen,7,0xb800,0,4000);
\r
900 //===========================================================================
\r
904 ==========================
\r
908 ==========================
\r
911 char *MainParmStrings[] = {"q","l","ver","nomemcheck","helptest",nil};
\r
917 starting_level = 0;
\r
919 for (i = 1;i < _argc;i++)
\r
921 switch (US_CheckParm(_argv[i],MainParmStrings))
\r
928 starting_level = atoi(_argv[i]+1);
\r
929 if ((starting_level < 0) || (starting_level > LASTMAP-1))
\r
930 starting_level = 0;
\r
934 printf("%s\n", GAMENAME);
\r
935 printf("Copyright 1992-93 Softdisk Publishing\n");
\r
936 printf("%s %s\n",VERSION,REVISION);
\r
942 Flags |= FL_NOMEMCHECK;
\r
946 Flags |= (FL_HELPTEST|FL_QUICK);
\r
952 if (stricmp(_argv[1], "^(a@&r`"))
\r
953 Quit("You must type CATAPOC to run CATACOMB APOCALYPSE\n");
\r
957 MainHelpText.xl = 0;
\r
958 MainHelpText.yl = 0;
\r
959 MainHelpText.xh = 639;
\r
960 MainHelpText.yh = 199;
\r
961 MainHelpText.bgcolor = 7;
\r
962 MainHelpText.ltcolor = 15;
\r
963 MainHelpText.dkcolor = 8;
\r
974 // if (!LoadTextFile("MAINHELP."EXT,&MainHelpText))
\r
975 // Quit("Can't load MAINHELP."EXT);
\r
986 //-------------------------------------------------------------------------
\r
988 //-------------------------------------------------------------------------
\r
989 void Display640(void)
\r
991 // Can you believe it takes all this just to change to 640 mode!!???!
\r
993 VW_ScreenToScreen(0,FREESTART-STATUSLEN,40,80);
\r
994 VW_SetLineWidth(80);
\r
996 VW_Bar (0,0,640,200,0);
\r
997 VW_SetScreenMode(EGA640GR);
\r
998 VW_SetLineWidth(80);
\r
1002 //-------------------------------------------------------------------------
\r
1004 //-------------------------------------------------------------------------
\r
1005 void Display320(void)
\r
1007 // Can you believe it takes all this just to change to 320 mode!!???!
\r
1009 VW_ColorBorder(0);
\r
1011 VW_SetLineWidth(40);
\r
1013 VW_Bar (0,0,320,200,0);
\r
1014 VW_SetScreenMode(EGA320GR);
\r
1015 VW_SetLineWidth(40);
\r
1017 VW_ScreenToScreen(FREESTART-STATUSLEN,0,40,80);
\r
1020 void PrintHelp(void)
\r
1022 char oldfontcolor = fontcolor;
\r
1028 bufferofs = displayofs = screenloc[0];
\r
1029 VW_Bar(0,0,320,200,0);
\r
1033 VW_Bar(0, 0, 640, 200, 7);
\r
1035 fontcolor = (7 ^ 1);
\r
1036 US_Print ("\n\n SUMMARY OF GAME CONTROLS\n\n");
\r
1038 fontcolor = (7 ^ 4);
\r
1039 US_Print (" ACTION\n\n");
\r
1041 US_Print ("Arrow keys, joystick, or mouse\n");
\r
1042 US_Print ("TAB or V while turning\n");
\r
1043 US_Print ("ALT or Button 2 while turning\n");
\r
1044 US_Print ("CTRL or Button 1\n");
\r
1046 US_Print ("X or Enter\n");
\r
1047 US_Print ("F1\n");
\r
1048 US_Print ("F2\n");
\r
1049 US_Print ("F3\n");
\r
1050 US_Print ("F4\n");
\r
1051 US_Print ("F5\n");
\r
1052 US_Print ("ESC\n\n");
\r
1053 fontcolor = (7 ^ 0);
\r
1055 US_Print (" (See complete Instructions for more info)\n");
\r
1057 US_Print ("\n copyright (c) 1992-93 Softdisk Publishing\n");
\r
1059 fontcolor = (7 ^ 8);
\r
1063 US_Print (" REACTION\n\n");
\r
1064 US_Print ("Move and turn\n");
\r
1065 US_Print ("Turn quickly (Quick Turn)\n");
\r
1066 US_Print ("Move sideways\n");
\r
1067 US_Print ("Shoot a Missile\n");
\r
1068 US_Print ("Shoot a Zapper\n");
\r
1069 US_Print ("Shoot an Xterminator\n");
\r
1070 US_Print ("Help (this screen)\n");
\r
1071 US_Print ("Sound control\n");
\r
1072 US_Print ("Save game position\n");
\r
1073 US_Print ("Restore a saved game\n");
\r
1074 US_Print ("Joystick control\n");
\r
1075 US_Print ("System options\n\n\n");
\r
1077 VW_UpdateScreen();
\r
1079 VW_ColorBorder(8 | 56);
\r
1082 fontcolor = oldfontcolor;
\r