]> 4ch.mooo.com Git - 16.git/blobdiff - src/lib/hb/game/wl_game.c
going to start wolf3d core core (loop with input only) work soon. I was mostly brains...
[16.git] / src / lib / hb / game / wl_game.c
diff --git a/src/lib/hb/game/wl_game.c b/src/lib/hb/game/wl_game.c
new file mode 100755 (executable)
index 0000000..9f63d9f
--- /dev/null
@@ -0,0 +1,1484 @@
+// 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