--- /dev/null
+// WL_GAME.C\r
+\r
+#include "WL_DEF.H"\r
+#pragma hdrstop\r
+\r
+#ifdef MYPROFILE\r
+#include <TIME.H>\r
+#endif\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+ LOCAL CONSTANTS\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+ GLOBAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+boolean ingame,fizzlein;\r
+unsigned latchpics[NUMLATCHPICS];\r
+gametype gamestate;\r
+\r
+long spearx,speary;\r
+unsigned spearangle;\r
+boolean spearflag;\r
+\r
+//\r
+// ELEVATOR BACK MAPS - REMEMBER (-1)!!\r
+//\r
+int ElevatorBackTo[]={1,1,7,3,5,3};\r
+\r
+void ScanInfoPlane (void);\r
+void SetupGameLevel (void);\r
+void DrawPlayScreen (void);\r
+void LoadLatchMem (void);\r
+void GameLoop (void);\r
+\r
+/*\r
+=============================================================================\r
+\r
+ LOCAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+\r
+//===========================================================================\r
+//===========================================================================\r
+\r
+\r
+/*\r
+==========================\r
+=\r
+= SetSoundLoc - Given the location of an object (in terms of global\r
+= coordinates, held in globalsoundx and globalsoundy), munges the values\r
+= for an approximate distance from the left and right ear, and puts\r
+= those values into leftchannel and rightchannel.\r
+=\r
+= JAB\r
+=\r
+==========================\r
+*/\r
+\r
+ fixed globalsoundx,globalsoundy;\r
+ int leftchannel,rightchannel;\r
+#define ATABLEMAX 15\r
+byte righttable[ATABLEMAX][ATABLEMAX * 2] = {\r
+{ 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 0, 0, 0, 0, 0, 1, 3, 5, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 4, 0, 0, 0, 0, 0, 2, 4, 6, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 4, 1, 0, 0, 0, 1, 2, 4, 6, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 6, 5, 4, 2, 1, 0, 1, 2, 3, 5, 7, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 6, 5, 4, 3, 2, 2, 3, 3, 5, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 4, 4, 4, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 5, 5, 6, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}\r
+};\r
+byte lefttable[ATABLEMAX][ATABLEMAX * 2] = {\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 5, 3, 1, 0, 0, 0, 0, 0, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 6, 4, 2, 0, 0, 0, 0, 0, 4, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 6, 4, 2, 1, 0, 0, 0, 1, 4, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 7, 5, 3, 2, 1, 0, 1, 2, 4, 5, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 5, 3, 3, 2, 2, 3, 4, 5, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 6, 5, 4, 4, 4, 4, 5, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 6, 6, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},\r
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}\r
+};\r
+\r
+void\r
+SetSoundLoc(fixed gx,fixed gy)\r
+{\r
+ fixed xt,yt;\r
+ int x,y;\r
+\r
+//\r
+// translate point to view centered coordinates\r
+//\r
+ gx -= viewx;\r
+ gy -= viewy;\r
+\r
+//\r
+// calculate newx\r
+//\r
+ xt = FixedByFrac(gx,viewcos);\r
+ yt = FixedByFrac(gy,viewsin);\r
+ x = (xt - yt) >> TILESHIFT;\r
+\r
+//\r
+// calculate newy\r
+//\r
+ xt = FixedByFrac(gx,viewsin);\r
+ yt = FixedByFrac(gy,viewcos);\r
+ y = (yt + xt) >> TILESHIFT;\r
+\r
+ if (y >= ATABLEMAX)\r
+ y = ATABLEMAX - 1;\r
+ else if (y <= -ATABLEMAX)\r
+ y = -ATABLEMAX;\r
+ if (x < 0)\r
+ x = -x;\r
+ if (x >= ATABLEMAX)\r
+ x = ATABLEMAX - 1;\r
+ leftchannel = lefttable[x][y + ATABLEMAX];\r
+ rightchannel = righttable[x][y + ATABLEMAX];\r
+\r
+#if 0\r
+ CenterWindow(8,1);\r
+ US_PrintSigned(leftchannel);\r
+ US_Print(",");\r
+ US_PrintSigned(rightchannel);\r
+ VW_UpdateScreen();\r
+#endif\r
+}\r
+\r
+/*\r
+==========================\r
+=\r
+= SetSoundLocGlobal - Sets up globalsoundx & globalsoundy and then calls\r
+= UpdateSoundLoc() to transform that into relative channel volumes. Those\r
+= values are then passed to the Sound Manager so that they'll be used for\r
+= the next sound played (if possible).\r
+=\r
+= JAB\r
+=\r
+==========================\r
+*/\r
+void PlaySoundLocGlobal(word s,fixed gx,fixed gy)\r
+{\r
+ SetSoundLoc(gx,gy);\r
+ SD_PositionSound(leftchannel,rightchannel);\r
+ if (SD_PlaySound(s))\r
+ {\r
+ globalsoundx = gx;\r
+ globalsoundy = gy;\r
+ }\r
+}\r
+\r
+void UpdateSoundLoc(void)\r
+{\r
+ if (SoundPositioned)\r
+ {\r
+ SetSoundLoc(globalsoundx,globalsoundy);\r
+ SD_SetPosition(leftchannel,rightchannel);\r
+ }\r
+}\r
+\r
+/*\r
+** JAB End\r
+*/\r
+\r
+\r
+/*\r
+==========================\r
+=\r
+= ClearMemory\r
+=\r
+==========================\r
+*/\r
+\r
+void ClearMemory (void)\r
+{\r
+ PM_UnlockMainMem();\r
+ SD_StopDigitized();\r
+ MM_SortMem ();\r
+}\r
+\r
+\r
+/*\r
+==========================\r
+=\r
+= ScanInfoPlane\r
+=\r
+= Spawn all actors and mark down special places\r
+=\r
+==========================\r
+*/\r
+\r
+void ScanInfoPlane (void)\r
+{\r
+ unsigned x,y,i,j;\r
+ int tile;\r
+ unsigned far *start;\r
+\r
+ start = mapsegs[1];\r
+ for (y=0;y<mapheight;y++)\r
+ for (x=0;x<mapwidth;x++)\r
+ {\r
+ tile = *start++;\r
+ if (!tile)\r
+ continue;\r
+\r
+ switch (tile)\r
+ {\r
+ case 19:\r
+ case 20:\r
+ case 21:\r
+ case 22:\r
+ SpawnPlayer(x,y,NORTH+tile-19);\r
+ break;\r
+\r
+ case 23:\r
+ case 24:\r
+ case 25:\r
+ case 26:\r
+ case 27:\r
+ case 28:\r
+ case 29:\r
+ case 30:\r
+\r
+ case 31:\r
+ case 32:\r
+ case 33:\r
+ case 34:\r
+ case 35:\r
+ case 36:\r
+ case 37:\r
+ case 38:\r
+\r
+ case 39:\r
+ case 40:\r
+ case 41:\r
+ case 42:\r
+ case 43:\r
+ case 44:\r
+ case 45:\r
+ case 46:\r
+\r
+ case 47:\r
+ case 48:\r
+ case 49:\r
+ case 50:\r
+ case 51:\r
+ case 52:\r
+ case 53:\r
+ case 54:\r
+\r
+ case 55:\r
+ case 56:\r
+ case 57:\r
+ case 58:\r
+ case 59:\r
+ case 60:\r
+ case 61:\r
+ case 62:\r
+\r
+ case 63:\r
+ case 64:\r
+ case 65:\r
+ case 66:\r
+ case 67:\r
+ case 68:\r
+ case 69:\r
+ case 70:\r
+ case 71:\r
+ case 72:\r
+ case 73: // TRUCK AND SPEAR!\r
+ case 74:\r
+\r
+ SpawnStatic(x,y,tile-23);\r
+ break;\r
+\r
+//\r
+// P wall\r
+//\r
+ case 98:\r
+ if (!loadedgame)\r
+ gamestate.secrettotal++;\r
+ break;\r
+\r
+//\r
+// guard\r
+//\r
+ case 180:\r
+ case 181:\r
+ case 182:\r
+ case 183:\r
+ if (gamestate.difficulty<gd_hard)\r
+ break;\r
+ tile -= 36;\r
+ case 144:\r
+ case 145:\r
+ case 146:\r
+ case 147:\r
+ if (gamestate.difficulty<gd_medium)\r
+ break;\r
+ tile -= 36;\r
+ case 108:\r
+ case 109:\r
+ case 110:\r
+ case 111:\r
+ SpawnStand(en_guard,x,y,tile-108);\r
+ break;\r
+\r
+\r
+ case 184:\r
+ case 185:\r
+ case 186:\r
+ case 187:\r
+ if (gamestate.difficulty<gd_hard)\r
+ break;\r
+ tile -= 36;\r
+ case 148:\r
+ case 149:\r
+ case 150:\r
+ case 151:\r
+ if (gamestate.difficulty<gd_medium)\r
+ break;\r
+ tile -= 36;\r
+ case 112:\r
+ case 113:\r
+ case 114:\r
+ case 115:\r
+ SpawnPatrol(en_guard,x,y,tile-112);\r
+ break;\r
+\r
+ case 124:\r
+ SpawnDeadGuard (x,y);\r
+ break;\r
+//\r
+// officer\r
+//\r
+ case 188:\r
+ case 189:\r
+ case 190:\r
+ case 191:\r
+ if (gamestate.difficulty<gd_hard)\r
+ break;\r
+ tile -= 36;\r
+ case 152:\r
+ case 153:\r
+ case 154:\r
+ case 155:\r
+ if (gamestate.difficulty<gd_medium)\r
+ break;\r
+ tile -= 36;\r
+ case 116:\r
+ case 117:\r
+ case 118:\r
+ case 119:\r
+ SpawnStand(en_officer,x,y,tile-116);\r
+ break;\r
+\r
+\r
+ case 192:\r
+ case 193:\r
+ case 194:\r
+ case 195:\r
+ if (gamestate.difficulty<gd_hard)\r
+ break;\r
+ tile -= 36;\r
+ case 156:\r
+ case 157:\r
+ case 158:\r
+ case 159:\r
+ if (gamestate.difficulty<gd_medium)\r
+ break;\r
+ tile -= 36;\r
+ case 120:\r
+ case 121:\r
+ case 122:\r
+ case 123:\r
+ SpawnPatrol(en_officer,x,y,tile-120);\r
+ break;\r
+\r
+\r
+//\r
+// ss\r
+//\r
+ case 198:\r
+ case 199:\r
+ case 200:\r
+ case 201:\r
+ if (gamestate.difficulty<gd_hard)\r
+ break;\r
+ tile -= 36;\r
+ case 162:\r
+ case 163:\r
+ case 164:\r
+ case 165:\r
+ if (gamestate.difficulty<gd_medium)\r
+ break;\r
+ tile -= 36;\r
+ case 126:\r
+ case 127:\r
+ case 128:\r
+ case 129:\r
+ SpawnStand(en_ss,x,y,tile-126);\r
+ break;\r
+\r
+\r
+ case 202:\r
+ case 203:\r
+ case 204:\r
+ case 205:\r
+ if (gamestate.difficulty<gd_hard)\r
+ break;\r
+ tile -= 36;\r
+ case 166:\r
+ case 167:\r
+ case 168:\r
+ case 169:\r
+ if (gamestate.difficulty<gd_medium)\r
+ break;\r
+ tile -= 36;\r
+ case 130:\r
+ case 131:\r
+ case 132:\r
+ case 133:\r
+ SpawnPatrol(en_ss,x,y,tile-130);\r
+ break;\r
+\r
+//\r
+// dogs\r
+//\r
+ case 206:\r
+ case 207:\r
+ case 208:\r
+ case 209:\r
+ if (gamestate.difficulty<gd_hard)\r
+ break;\r
+ tile -= 36;\r
+ case 170:\r
+ case 171:\r
+ case 172:\r
+ case 173:\r
+ if (gamestate.difficulty<gd_medium)\r
+ break;\r
+ tile -= 36;\r
+ case 134:\r
+ case 135:\r
+ case 136:\r
+ case 137:\r
+ SpawnStand(en_dog,x,y,tile-134);\r
+ break;\r
+\r
+\r
+ case 210:\r
+ case 211:\r
+ case 212:\r
+ case 213:\r
+ if (gamestate.difficulty<gd_hard)\r
+ break;\r
+ tile -= 36;\r
+ case 174:\r
+ case 175:\r
+ case 176:\r
+ case 177:\r
+ if (gamestate.difficulty<gd_medium)\r
+ break;\r
+ tile -= 36;\r
+ case 138:\r
+ case 139:\r
+ case 140:\r
+ case 141:\r
+ SpawnPatrol(en_dog,x,y,tile-138);\r
+ break;\r
+\r
+//\r
+// boss\r
+//\r
+#ifndef SPEAR\r
+ case 214:\r
+ SpawnBoss (x,y);\r
+ break;\r
+ case 197:\r
+ SpawnGretel (x,y);\r
+ break;\r
+ case 215:\r
+ SpawnGift (x,y);\r
+ break;\r
+ case 179:\r
+ SpawnFat (x,y);\r
+ break;\r
+ case 196:\r
+ SpawnSchabbs (x,y);\r
+ break;\r
+ case 160:\r
+ SpawnFakeHitler (x,y);\r
+ break;\r
+ case 178:\r
+ SpawnHitler (x,y);\r
+ break;\r
+#else\r
+ case 106:\r
+ SpawnSpectre (x,y);\r
+ break;\r
+ case 107:\r
+ SpawnAngel (x,y);\r
+ break;\r
+ case 125:\r
+ SpawnTrans (x,y);\r
+ break;\r
+ case 142:\r
+ SpawnUber (x,y);\r
+ break;\r
+ case 143:\r
+ SpawnWill (x,y);\r
+ break;\r
+ case 161:\r
+ SpawnDeath (x,y);\r
+ break;\r
+\r
+#endif\r
+\r
+//\r
+// mutants\r
+//\r
+ case 252:\r
+ case 253:\r
+ case 254:\r
+ case 255:\r
+ if (gamestate.difficulty<gd_hard)\r
+ break;\r
+ tile -= 18;\r
+ case 234:\r
+ case 235:\r
+ case 236:\r
+ case 237:\r
+ if (gamestate.difficulty<gd_medium)\r
+ break;\r
+ tile -= 18;\r
+ case 216:\r
+ case 217:\r
+ case 218:\r
+ case 219:\r
+ SpawnStand(en_mutant,x,y,tile-216);\r
+ break;\r
+\r
+ case 256:\r
+ case 257:\r
+ case 258:\r
+ case 259:\r
+ if (gamestate.difficulty<gd_hard)\r
+ break;\r
+ tile -= 18;\r
+ case 238:\r
+ case 239:\r
+ case 240:\r
+ case 241:\r
+ if (gamestate.difficulty<gd_medium)\r
+ break;\r
+ tile -= 18;\r
+ case 220:\r
+ case 221:\r
+ case 222:\r
+ case 223:\r
+ SpawnPatrol(en_mutant,x,y,tile-220);\r
+ break;\r
+\r
+//\r
+// ghosts\r
+//\r
+#ifndef SPEAR\r
+ case 224:\r
+ SpawnGhosts (en_blinky,x,y);\r
+ break;\r
+ case 225:\r
+ SpawnGhosts (en_clyde,x,y);\r
+ break;\r
+ case 226:\r
+ SpawnGhosts (en_pinky,x,y);\r
+ break;\r
+ case 227:\r
+ SpawnGhosts (en_inky,x,y);\r
+ break;\r
+#endif\r
+ }\r
+\r
+ }\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+==================\r
+=\r
+= SetupGameLevel\r
+=\r
+==================\r
+*/\r
+\r
+void SetupGameLevel (void)\r
+{\r
+ int x,y,i;\r
+ unsigned far *map,tile,spot;\r
+\r
+\r
+ if (!loadedgame)\r
+ {\r
+ gamestate.TimeCount=\r
+ gamestate.secrettotal=\r
+ gamestate.killtotal=\r
+ gamestate.treasuretotal=\r
+ gamestate.secretcount=\r
+ gamestate.killcount=\r
+ gamestate.treasurecount=0;\r
+ }\r
+\r
+ if (demoplayback || demorecord)\r
+ US_InitRndT (false);\r
+ else\r
+ US_InitRndT (true);\r
+\r
+//\r
+// load the level\r
+//\r
+ CA_CacheMap (gamestate.mapon+10*gamestate.episode);\r
+ mapon-=gamestate.episode*10;\r
+\r
+ mapwidth = mapheaderseg[mapon]->width;\r
+ mapheight = mapheaderseg[mapon]->height;\r
+\r
+ if (mapwidth != 64 || mapheight != 64)\r
+ Quit ("Map not 64*64!");\r
+\r
+\r
+//\r
+// copy the wall data to a data segment array\r
+//\r
+ memset (tilemap,0,sizeof(tilemap));\r
+ memset (actorat,0,sizeof(actorat));\r
+ map = mapsegs[0];\r
+ for (y=0;y<mapheight;y++)\r
+ for (x=0;x<mapwidth;x++)\r
+ {\r
+ tile = *map++;\r
+ if (tile<AREATILE)\r
+ {\r
+ // solid wall\r
+ tilemap[x][y] = tile;\r
+ (unsigned)actorat[x][y] = tile;\r
+ }\r
+ else\r
+ {\r
+ // area floor\r
+ tilemap[x][y] = 0;\r
+ (unsigned)actorat[x][y] = 0;\r
+ }\r
+ }\r
+\r
+//\r
+// spawn doors\r
+//\r
+ InitActorList (); // start spawning things with a clean slate\r
+ InitDoorList ();\r
+ InitStaticList ();\r
+\r
+ map = mapsegs[0];\r
+ for (y=0;y<mapheight;y++)\r
+ for (x=0;x<mapwidth;x++)\r
+ {\r
+ tile = *map++;\r
+ if (tile >= 90 && tile <= 101)\r
+ {\r
+ // door\r
+ switch (tile)\r
+ {\r
+ case 90:\r
+ case 92:\r
+ case 94:\r
+ case 96:\r
+ case 98:\r
+ case 100:\r
+ SpawnDoor (x,y,1,(tile-90)/2);\r
+ break;\r
+ case 91:\r
+ case 93:\r
+ case 95:\r
+ case 97:\r
+ case 99:\r
+ case 101:\r
+ SpawnDoor (x,y,0,(tile-91)/2);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+//\r
+// spawn actors\r
+//\r
+ ScanInfoPlane ();\r
+\r
+//\r
+// take out the ambush markers\r
+//\r
+ map = mapsegs[0];\r
+ for (y=0;y<mapheight;y++)\r
+ for (x=0;x<mapwidth;x++)\r
+ {\r
+ tile = *map++;\r
+ if (tile == AMBUSHTILE)\r
+ {\r
+ tilemap[x][y] = 0;\r
+ if ( (unsigned)actorat[x][y] == AMBUSHTILE)\r
+ actorat[x][y] = NULL;\r
+\r
+ if (*map >= AREATILE)\r
+ tile = *map;\r
+ if (*(map-1-mapwidth) >= AREATILE)\r
+ tile = *(map-1-mapwidth);\r
+ if (*(map-1+mapwidth) >= AREATILE)\r
+ tile = *(map-1+mapwidth);\r
+ if ( *(map-2) >= AREATILE)\r
+ tile = *(map-2);\r
+\r
+ *(map-1) = tile;\r
+ }\r
+ }\r
+\r
+\r
+\r
+//\r
+// have the caching manager load and purge stuff to make sure all marks\r
+// are in memory\r
+//\r
+ CA_LoadAllSounds ();\r
+\r
+}\r
+\r
+\r
+//==========================================================================\r
+\r
+\r
+/*\r
+===================\r
+=\r
+= DrawPlayBorderSides\r
+=\r
+= To fix window overwrites\r
+=\r
+===================\r
+*/\r
+\r
+void DrawPlayBorderSides (void)\r
+{\r
+ int xl,yl;\r
+\r
+ xl = 160-viewwidth/2;\r
+ yl = (200-STATUSLINES-viewheight)/2;\r
+\r
+ VWB_Bar (0,0,xl-1,200-STATUSLINES,127);\r
+ VWB_Bar (xl+viewwidth+1,0,xl-2,200-STATUSLINES,127);\r
+\r
+ VWB_Vlin (yl-1,yl+viewheight,xl-1,0);\r
+ VWB_Vlin (yl-1,yl+viewheight,xl+viewwidth,125);\r
+}\r
+\r
+\r
+/*\r
+===================\r
+=\r
+= DrawAllPlayBorderSides\r
+=\r
+===================\r
+*/\r
+\r
+void DrawAllPlayBorderSides (void)\r
+{\r
+ unsigned i,temp;\r
+\r
+ temp = bufferofs;\r
+ for (i=0;i<3;i++)\r
+ {\r
+ bufferofs = screenloc[i];\r
+ DrawPlayBorderSides ();\r
+ }\r
+ bufferofs = temp;\r
+}\r
+\r
+/*\r
+===================\r
+=\r
+= DrawPlayBorder\r
+=\r
+===================\r
+*/\r
+void DrawAllPlayBorder (void)\r
+{\r
+ unsigned i,temp;\r
+\r
+ temp = bufferofs;\r
+ for (i=0;i<3;i++)\r
+ {\r
+ bufferofs = screenloc[i];\r
+ DrawPlayBorder ();\r
+ }\r
+ bufferofs = temp;\r
+}\r
+\r
+/*\r
+===================\r
+=\r
+= DrawPlayBorder\r
+=\r
+===================\r
+*/\r
+\r
+void DrawPlayBorder (void)\r
+{\r
+ int xl,yl;\r
+\r
+ VWB_Bar (0,0,320,200-STATUSLINES,127);\r
+\r
+ xl = 160-viewwidth/2;\r
+ yl = (200-STATUSLINES-viewheight)/2;\r
+ VWB_Bar (xl,yl,viewwidth,viewheight,0);\r
+\r
+ VWB_Hlin (xl-1,xl+viewwidth,yl-1,0);\r
+ VWB_Hlin (xl-1,xl+viewwidth,yl+viewheight,125);\r
+ VWB_Vlin (yl-1,yl+viewheight,xl-1,0);\r
+ VWB_Vlin (yl-1,yl+viewheight,xl+viewwidth,125);\r
+ VWB_Plot (xl-1,yl+viewheight,124);\r
+}\r
+\r
+\r
+\r
+/*\r
+===================\r
+=\r
+= DrawPlayScreen\r
+=\r
+===================\r
+*/\r
+\r
+void DrawPlayScreen (void)\r
+{\r
+ int i,j,p,m;\r
+ unsigned temp;\r
+\r
+ VW_FadeOut ();\r
+\r
+ temp = bufferofs;\r
+\r
+ CA_CacheGrChunk (STATUSBARPIC);\r
+\r
+ for (i=0;i<3;i++)\r
+ {\r
+ bufferofs = screenloc[i];\r
+ DrawPlayBorder ();\r
+ VWB_DrawPic (0,200-STATUSLINES,STATUSBARPIC);\r
+ }\r
+\r
+ bufferofs = temp;\r
+\r
+ UNCACHEGRCHUNK (STATUSBARPIC);\r
+\r
+ DrawFace ();\r
+ DrawHealth ();\r
+ DrawLives ();\r
+ DrawLevel ();\r
+ DrawAmmo ();\r
+ DrawKeys ();\r
+ DrawWeapon ();\r
+ DrawScore ();\r
+}\r
+\r
+\r
+\r
+//==========================================================================\r
+\r
+/*\r
+==================\r
+=\r
+= StartDemoRecord\r
+=\r
+==================\r
+*/\r
+\r
+#define MAXDEMOSIZE 8192\r
+\r
+void StartDemoRecord (int levelnumber)\r
+{\r
+ MM_GetPtr (&demobuffer,MAXDEMOSIZE);\r
+ MM_SetLock (&demobuffer,true);\r
+ demoptr = (char far *)demobuffer;\r
+ lastdemoptr = demoptr+MAXDEMOSIZE;\r
+\r
+ *demoptr = levelnumber;\r
+ demoptr += 4; // leave space for length\r
+ demorecord = true;\r
+}\r
+\r
+\r
+/*\r
+==================\r
+=\r
+= FinishDemoRecord\r
+=\r
+==================\r
+*/\r
+\r
+char demoname[13] = "DEMO?.";\r
+\r
+void FinishDemoRecord (void)\r
+{\r
+ long length,level;\r
+\r
+ demorecord = false;\r
+\r
+ length = demoptr - (char far *)demobuffer;\r
+\r
+ demoptr = ((char far *)demobuffer)+1;\r
+ *(unsigned far *)demoptr = length;\r
+\r
+ CenterWindow(24,3);\r
+ PrintY+=6;\r
+ US_Print(" Demo number (0-9):");\r
+ VW_UpdateScreen();\r
+\r
+ if (US_LineInput (px,py,str,NULL,true,2,0))\r
+ {\r
+ level = atoi (str);\r
+ if (level>=0 && level<=9)\r
+ {\r
+ demoname[4] = '0'+level;\r
+ CA_WriteFile (demoname,(void far *)demobuffer,length);\r
+ }\r
+ }\r
+\r
+\r
+ MM_FreePtr (&demobuffer);\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+==================\r
+=\r
+= RecordDemo\r
+=\r
+= Fades the screen out, then starts a demo. Exits with the screen faded\r
+=\r
+==================\r
+*/\r
+\r
+void RecordDemo (void)\r
+{\r
+ int level,esc;\r
+\r
+ CenterWindow(26,3);\r
+ PrintY+=6;\r
+ CA_CacheGrChunk(STARTFONT);\r
+ fontnumber=0;\r
+ US_Print(" Demo which level(1-10):");\r
+ VW_UpdateScreen();\r
+ VW_FadeIn ();\r
+ esc = !US_LineInput (px,py,str,NULL,true,2,0);\r
+ if (esc)\r
+ return;\r
+\r
+ level = atoi (str);\r
+ level--;\r
+\r
+ SETFONTCOLOR(0,15);\r
+ VW_FadeOut ();\r
+\r
+#ifndef SPEAR\r
+ NewGame (gd_hard,level/10);\r
+ gamestate.mapon = level%10;\r
+#else\r
+ NewGame (gd_hard,0);\r
+ gamestate.mapon = level;\r
+#endif\r
+\r
+ StartDemoRecord (level);\r
+\r
+ DrawPlayScreen ();\r
+ VW_FadeIn ();\r
+\r
+ startgame = false;\r
+ demorecord = true;\r
+\r
+ SetupGameLevel ();\r
+ StartMusic ();\r
+ PM_CheckMainMem ();\r
+ fizzlein = true;\r
+\r
+ PlayLoop ();\r
+\r
+ demoplayback = false;\r
+\r
+ StopMusic ();\r
+ VW_FadeOut ();\r
+ ClearMemory ();\r
+\r
+ FinishDemoRecord ();\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+==================\r
+=\r
+= PlayDemo\r
+=\r
+= Fades the screen out, then starts a demo. Exits with the screen faded\r
+=\r
+==================\r
+*/\r
+\r
+void PlayDemo (int demonumber)\r
+{\r
+ int length;\r
+\r
+#ifdef DEMOSEXTERN\r
+// debug: load chunk\r
+#ifndef SPEARDEMO\r
+ int dems[4]={T_DEMO0,T_DEMO1,T_DEMO2,T_DEMO3};\r
+#else\r
+ int dems[1]={T_DEMO0};\r
+#endif\r
+\r
+ CA_CacheGrChunk(dems[demonumber]);\r
+ demoptr = grsegs[dems[demonumber]];\r
+ MM_SetLock (&grsegs[dems[demonumber]],true);\r
+#else\r
+ demoname[4] = '0'+demonumber;\r
+ CA_LoadFile (demoname,&demobuffer);\r
+ MM_SetLock (&demobuffer,true);\r
+ demoptr = (char far *)demobuffer;\r
+#endif\r
+\r
+ NewGame (1,0);\r
+ gamestate.mapon = *demoptr++;\r
+ gamestate.difficulty = gd_hard;\r
+ length = *((unsigned far *)demoptr)++;\r
+ demoptr++;\r
+ lastdemoptr = demoptr-4+length;\r
+\r
+ VW_FadeOut ();\r
+\r
+ SETFONTCOLOR(0,15);\r
+ DrawPlayScreen ();\r
+ VW_FadeIn ();\r
+\r
+ startgame = false;\r
+ demoplayback = true;\r
+\r
+ SetupGameLevel ();\r
+ StartMusic ();\r
+ PM_CheckMainMem ();\r
+ fizzlein = true;\r
+\r
+ PlayLoop ();\r
+\r
+#ifdef DEMOSEXTERN\r
+ UNCACHEGRCHUNK(dems[demonumber]);\r
+#else\r
+ MM_FreePtr (&demobuffer);\r
+#endif\r
+\r
+ demoplayback = false;\r
+\r
+ StopMusic ();\r
+ VW_FadeOut ();\r
+ ClearMemory ();\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+==================\r
+=\r
+= Died\r
+=\r
+==================\r
+*/\r
+\r
+#define DEATHROTATE 2\r
+\r
+void Died (void)\r
+{\r
+ float fangle;\r
+ long dx,dy;\r
+ int iangle,curangle,clockwise,counter,change;\r
+\r
+ gamestate.weapon = -1; // take away weapon\r
+ SD_PlaySound (PLAYERDEATHSND);\r
+//\r
+// swing around to face attacker\r
+//\r
+ dx = killerobj->x - player->x;\r
+ dy = player->y - killerobj->y;\r
+\r
+ fangle = atan2(dy,dx); // returns -pi to pi\r
+ if (fangle<0)\r
+ fangle = M_PI*2+fangle;\r
+\r
+ iangle = fangle/(M_PI*2)*ANGLES;\r
+\r
+ if (player->angle > iangle)\r
+ {\r
+ counter = player->angle - iangle;\r
+ clockwise = ANGLES-player->angle + iangle;\r
+ }\r
+ else\r
+ {\r
+ clockwise = iangle - player->angle;\r
+ counter = player->angle + ANGLES-iangle;\r
+ }\r
+\r
+ curangle = player->angle;\r
+\r
+ if (clockwise<counter)\r
+ {\r
+ //\r
+ // rotate clockwise\r
+ //\r
+ if (curangle>iangle)\r
+ curangle -= ANGLES;\r
+ do\r
+ {\r
+ change = tics*DEATHROTATE;\r
+ if (curangle + change > iangle)\r
+ change = iangle-curangle;\r
+\r
+ curangle += change;\r
+ player->angle += change;\r
+ if (player->angle >= ANGLES)\r
+ player->angle -= ANGLES;\r
+\r
+ ThreeDRefresh ();\r
+ CalcTics ();\r
+ } while (curangle != iangle);\r
+ }\r
+ else\r
+ {\r
+ //\r
+ // rotate counterclockwise\r
+ //\r
+ if (curangle<iangle)\r
+ curangle += ANGLES;\r
+ do\r
+ {\r
+ change = -tics*DEATHROTATE;\r
+ if (curangle + change < iangle)\r
+ change = iangle-curangle;\r
+\r
+ curangle += change;\r
+ player->angle += change;\r
+ if (player->angle < 0)\r
+ player->angle += ANGLES;\r
+\r
+ ThreeDRefresh ();\r
+ CalcTics ();\r
+ } while (curangle != iangle);\r
+ }\r
+\r
+//\r
+// fade to red\r
+//\r
+ FinishPaletteShifts ();\r
+\r
+ bufferofs += screenofs;\r
+ VW_Bar (0,0,viewwidth,viewheight,4);\r
+ IN_ClearKeysDown ();\r
+ FizzleFade(bufferofs,displayofs+screenofs,viewwidth,viewheight,70,false);\r
+ bufferofs -= screenofs;\r
+ IN_UserInput(100);\r
+ SD_WaitSoundDone ();\r
+\r
+ if (tedlevel == false) // SO'S YA DON'T GET KILLED WHILE LAUNCHING!\r
+ gamestate.lives--;\r
+\r
+ if (gamestate.lives > -1)\r
+ {\r
+ gamestate.health = 100;\r
+ gamestate.weapon = gamestate.bestweapon\r
+ = gamestate.chosenweapon = wp_pistol;\r
+ gamestate.ammo = STARTAMMO;\r
+ gamestate.keys = 0;\r
+ gamestate.attackframe = gamestate.attackcount =\r
+ gamestate.weaponframe = 0;\r
+\r
+ DrawKeys ();\r
+ DrawWeapon ();\r
+ DrawAmmo ();\r
+ DrawHealth ();\r
+ DrawFace ();\r
+ DrawLives ();\r
+ }\r
+\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+===================\r
+=\r
+= GameLoop\r
+=\r
+===================\r
+*/\r
+\r
+void GameLoop (void)\r
+{\r
+ int i,xl,yl,xh,yh;\r
+ char num[20];\r
+ boolean died;\r
+#ifdef MYPROFILE\r
+ clock_t start,end;\r
+#endif\r
+\r
+restartgame:\r
+ ClearMemory ();\r
+ SETFONTCOLOR(0,15);\r
+ DrawPlayScreen ();\r
+ died = false;\r
+restart:\r
+ do\r
+ {\r
+ if (!loadedgame)\r
+ gamestate.score = gamestate.oldscore;\r
+ DrawScore();\r
+\r
+ startgame = false;\r
+ if (loadedgame)\r
+ loadedgame = false;\r
+ else\r
+ SetupGameLevel ();\r
+\r
+#ifdef SPEAR\r
+ if (gamestate.mapon == 20) // give them the key allways\r
+ {\r
+ gamestate.keys |= 1;\r
+ DrawKeys ();\r
+ }\r
+#endif\r
+\r
+ ingame = true;\r
+ StartMusic ();\r
+ PM_CheckMainMem ();\r
+ if (!died)\r
+ PreloadGraphics ();\r
+ else\r
+ died = false;\r
+\r
+ fizzlein = true;\r
+ DrawLevel ();\r
+\r
+startplayloop:\r
+ PlayLoop ();\r
+\r
+#ifdef SPEAR\r
+ if (spearflag)\r
+ {\r
+ SD_StopSound();\r
+ SD_PlaySound(GETSPEARSND);\r
+ if (DigiMode != sds_Off)\r
+ {\r
+ long lasttimecount = TimeCount;\r
+\r
+ while(TimeCount < lasttimecount+150)\r
+ //while(DigiPlaying!=false)\r
+ SD_Poll();\r
+ }\r
+ else\r
+ SD_WaitSoundDone();\r
+\r
+ ClearMemory ();\r
+ gamestate.oldscore = gamestate.score;\r
+ gamestate.mapon = 20;\r
+ SetupGameLevel ();\r
+ StartMusic ();\r
+ PM_CheckMainMem ();\r
+ player->x = spearx;\r
+ player->y = speary;\r
+ player->angle = spearangle;\r
+ spearflag = false;\r
+ Thrust (0,0);\r
+ goto startplayloop;\r
+ }\r
+#endif\r
+\r
+ StopMusic ();\r
+ ingame = false;\r
+\r
+ if (demorecord && playstate != ex_warped)\r
+ FinishDemoRecord ();\r
+\r
+ if (startgame || loadedgame)\r
+ goto restartgame;\r
+\r
+ switch (playstate)\r
+ {\r
+ case ex_completed:\r
+ case ex_secretlevel:\r
+ gamestate.keys = 0;\r
+ DrawKeys ();\r
+ VW_FadeOut ();\r
+\r
+ ClearMemory ();\r
+\r
+ LevelCompleted (); // do the intermission\r
+#ifdef SPEARDEMO\r
+ if (gamestate.mapon == 1)\r
+ {\r
+ died = true; // don't "get psyched!"\r
+\r
+ VW_FadeOut ();\r
+\r
+ ClearMemory ();\r
+\r
+ CheckHighScore (gamestate.score,gamestate.mapon+1);\r
+\r
+ #pragma warn -sus\r
+ #ifndef JAPAN\r
+ _fstrcpy(MainMenu[viewscores].string,STR_VS);\r
+ #endif\r
+ MainMenu[viewscores].routine = CP_ViewScores;\r
+ #pragma warn +sus\r
+\r
+ return;\r
+ }\r
+#endif\r
+\r
+#ifdef JAPDEMO\r
+ if (gamestate.mapon == 3)\r
+ {\r
+ died = true; // don't "get psyched!"\r
+\r
+ VW_FadeOut ();\r
+\r
+ ClearMemory ();\r
+\r
+ CheckHighScore (gamestate.score,gamestate.mapon+1);\r
+\r
+ #pragma warn -sus\r
+ #ifndef JAPAN\r
+ _fstrcpy(MainMenu[viewscores].string,STR_VS);\r
+ #endif\r
+ MainMenu[viewscores].routine = CP_ViewScores;\r
+ #pragma warn +sus\r
+\r
+ return;\r
+ }\r
+#endif\r
+\r
+ gamestate.oldscore = gamestate.score;\r
+\r
+#ifndef SPEAR\r
+ //\r
+ // COMING BACK FROM SECRET LEVEL\r
+ //\r
+ if (gamestate.mapon == 9)\r
+ gamestate.mapon = ElevatorBackTo[gamestate.episode]; // back from secret\r
+ else\r
+ //\r
+ // GOING TO SECRET LEVEL\r
+ //\r
+ if (playstate == ex_secretlevel)\r
+ gamestate.mapon = 9;\r
+#else\r
+\r
+#define FROMSECRET1 3\r
+#define FROMSECRET2 11\r
+\r
+ //\r
+ // GOING TO SECRET LEVEL\r
+ //\r
+ if (playstate == ex_secretlevel)\r
+ switch(gamestate.mapon)\r
+ {\r
+ case FROMSECRET1: gamestate.mapon = 18; break;\r
+ case FROMSECRET2: gamestate.mapon = 19; break;\r
+ }\r
+ else\r
+ //\r
+ // COMING BACK FROM SECRET LEVEL\r
+ //\r
+ if (gamestate.mapon == 18 || gamestate.mapon == 19)\r
+ switch(gamestate.mapon)\r
+ {\r
+ case 18: gamestate.mapon = FROMSECRET1+1; break;\r
+ case 19: gamestate.mapon = FROMSECRET2+1; break;\r
+ }\r
+#endif\r
+ else\r
+ //\r
+ // GOING TO NEXT LEVEL\r
+ //\r
+ gamestate.mapon++;\r
+\r
+\r
+ break;\r
+\r
+ case ex_died:\r
+ Died ();\r
+ died = true; // don't "get psyched!"\r
+\r
+ if (gamestate.lives > -1)\r
+ break; // more lives left\r
+\r
+ VW_FadeOut ();\r
+\r
+ ClearMemory ();\r
+\r
+ CheckHighScore (gamestate.score,gamestate.mapon+1);\r
+\r
+ #pragma warn -sus\r
+ #ifndef JAPAN\r
+ _fstrcpy(MainMenu[viewscores].string,STR_VS);\r
+ #endif\r
+ MainMenu[viewscores].routine = CP_ViewScores;\r
+ #pragma warn +sus\r
+\r
+ return;\r
+\r
+ case ex_victorious:\r
+\r
+#ifndef SPEAR\r
+ VW_FadeOut ();\r
+#else\r
+ VL_FadeOut (0,255,0,17,17,300);\r
+#endif\r
+ ClearMemory ();\r
+\r
+ Victory ();\r
+\r
+ ClearMemory ();\r
+\r
+ CheckHighScore (gamestate.score,gamestate.mapon+1);\r
+\r
+ #pragma warn -sus\r
+ #ifndef JAPAN\r
+ _fstrcpy(MainMenu[viewscores].string,STR_VS);\r
+ #endif\r
+ MainMenu[viewscores].routine = CP_ViewScores;\r
+ #pragma warn +sus\r
+\r
+ return;\r
+\r
+ default:\r
+ ClearMemory ();\r
+ break;\r
+ }\r
+\r
+ } while (1);\r
+\r
+}\r
+\r