+++ /dev/null
-/* Catacomb 3-D Source Code\r
- * Copyright (C) 1993-2014 Flat Rock Software\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License along\r
- * with this program; if not, write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
- */\r
-\r
-// C3_GAME.C\r
-\r
-#include "C3_DEF.H"\r
-#pragma hdrstop\r
-\r
-#ifdef PROFILE\r
-#include "TIME.H"\r
-#endif\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
- LOCAL CONSTANTS\r
-\r
-=============================================================================\r
-*/\r
-\r
-#define NUMLUMPS 25\r
-\r
-#define CONTROLSLUMP 0\r
-#define ORCLUMP 1\r
-#define TROLLLUMP 2\r
-#define WARPLUMP 3\r
-#define BOLTLUMP 4\r
-#define NUKELUMP 5\r
-#define POTIONLUMP 6\r
-#define RKEYLUMP 7\r
-#define YKEYLUMP 8\r
-#define GKEYLUMP 9\r
-#define BKEYLUMP 10\r
-#define SCROLLLUMP 11\r
-#define CHESTLUMP 12\r
-#define PLAYERLUMP 13\r
-#define WALL1LUMP 14\r
-#define WALL2LUMP 15\r
-#define BDOORLUMP 16\r
-#define DEMONLUMP 17\r
-#define MAGELUMP 18\r
-#define BATLUMP 19\r
-#define GRELLUMP 20\r
-#define GOALLUMP 21\r
-\r
-\r
-int lumpstart[NUMLUMPS] = {\r
-CONTROLS_LUMP_START,\r
-ORC_LUMP_START,\r
-TROLL_LUMP_START,\r
-WARP_LUMP_START,\r
-BOLT_LUMP_START,\r
-NUKE_LUMP_START,\r
-POTION_LUMP_START,\r
-RKEY_LUMP_START,\r
-YKEY_LUMP_START,\r
-GKEY_LUMP_START,\r
-BKEY_LUMP_START,\r
-SCROLL_LUMP_START,\r
-CHEST_LUMP_START,\r
-PLAYER_LUMP_START,\r
-WALL1_LUMP_START,\r
-WALL2_LUMP_START,\r
-BDOOR_LUMP_START,\r
-DEMON_LUMP_START,\r
-MAGE_LUMP_START,\r
-BAT_LUMP_START,\r
-GREL_LUMP_START,\r
-NEMESISPIC\r
-};\r
-\r
-\r
-int lumpend[NUMLUMPS] = {\r
-CONTROLS_LUMP_END,\r
-ORC_LUMP_END,\r
-TROLL_LUMP_END,\r
-WARP_LUMP_END,\r
-BOLT_LUMP_END,\r
-NUKE_LUMP_END,\r
-POTION_LUMP_END,\r
-RKEY_LUMP_END,\r
-YKEY_LUMP_END,\r
-GKEY_LUMP_END,\r
-BKEY_LUMP_END,\r
-SCROLL_LUMP_END,\r
-CHEST_LUMP_END,\r
-PLAYER_LUMP_END,\r
-WALL1_LUMP_END,\r
-WALL2_LUMP_END,\r
-BDOOR_LUMP_END,\r
-DEMON_LUMP_END,\r
-MAGE_LUMP_END,\r
-BAT_LUMP_END,\r
-GREL_LUMP_END,\r
-NEMESISPIC\r
-};\r
-\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
- GLOBAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-unsigned latchpics[NUMLATCHPICS];\r
-unsigned tileoffsets[NUMTILE16];\r
-unsigned textstarts[27];\r
-\r
-/*\r
-=============================================================================\r
-\r
- LOCAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-boolean lumpneeded[NUMLUMPS];\r
-\r
-\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
- InitObjList(); // start spawning things with a clean slate\r
-\r
- memset (lumpneeded,0,sizeof(lumpneeded));\r
-\r
- start = mapsegs[2];\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 1:\r
- case 2:\r
- case 3:\r
- case 4:\r
- lumpneeded[PLAYERLUMP] = true;\r
- SpawnPlayer(x,y,NORTH+tile-1);\r
- break;\r
-\r
- case 5:\r
- case 6:\r
- case 7:\r
- case 8:\r
- case 9:\r
- case 10:\r
- case 11:\r
- lumpneeded[tile-5+BOLTLUMP] = true;\r
- SpawnBonus(x,y,tile-5);\r
- break;\r
-\r
- case 12:\r
- case 13:\r
- case 14:\r
- case 15:\r
- case 16:\r
- case 17:\r
- case 18:\r
- case 19:\r
- lumpneeded[SCROLLLUMP] = true;\r
- SpawnBonus(x,y,B_SCROLL1+tile-12);\r
- break;\r
-\r
- case 20: // goal\r
- lumpneeded[GOALLUMP] = true;\r
- SpawnBonus(x,y,B_GOAL);\r
- break;\r
-\r
- case 21: // chest\r
- lumpneeded[CHESTLUMP] = true;\r
- SpawnBonus(x,y,B_CHEST);\r
- break;\r
-\r
- case 24:\r
- lumpneeded[WARPLUMP] = true;\r
- SpawnWarp (x,y,0);\r
- break;\r
-//------\r
- case 41:\r
- if (gamestate.difficulty <gd_Hard)\r
- break;\r
- case 36:\r
- if (gamestate.difficulty <gd_Normal)\r
- break;\r
- case 22:\r
- lumpneeded[TROLLLUMP] = true;\r
- SpawnTroll (x,y);\r
- break;\r
-\r
- case 42:\r
- if (gamestate.difficulty <gd_Hard)\r
- break;\r
- case 37:\r
- if (gamestate.difficulty <gd_Normal)\r
- break;\r
- case 23:\r
- lumpneeded[ORCLUMP] = true;\r
- SpawnOrc (x,y);\r
- break;\r
-\r
- case 43:\r
- if (gamestate.difficulty <gd_Hard)\r
- break;\r
- case 38:\r
- if (gamestate.difficulty <gd_Normal)\r
- break;\r
- case 25:\r
- lumpneeded[BATLUMP] = true;\r
- SpawnBat (x,y);\r
- break;\r
-\r
- case 44:\r
- if (gamestate.difficulty <gd_Hard)\r
- break;\r
- case 39:\r
- if (gamestate.difficulty <gd_Normal)\r
- break;\r
- case 26:\r
- lumpneeded[DEMONLUMP] = true;\r
- SpawnDemon (x,y);\r
- break;\r
-\r
- case 45:\r
- if (gamestate.difficulty <gd_Hard)\r
- break;\r
- case 40:\r
- if (gamestate.difficulty <gd_Normal)\r
- break;\r
- case 27:\r
- lumpneeded[MAGELUMP] = true;\r
- SpawnMage (x,y);\r
- break;\r
-\r
- case 28:\r
- lumpneeded[GRELLUMP] = true;\r
- SpawnNemesis (x,y);\r
- break;\r
-\r
- case 29:\r
- SpawnBounce (x,y,0);\r
- break;\r
-\r
- case 30:\r
- SpawnBounce (x,y,1);\r
- break;\r
-\r
- case 31:\r
- case 32:\r
- case 33:\r
- case 34:\r
- lumpneeded[WARPLUMP] = true;\r
- SpawnWarp (x,y,tile-30);\r
- break;\r
- }\r
- }\r
-\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-==================\r
-=\r
-= ScanText\r
-=\r
-==================\r
-*/\r
-\r
-void ScanText (void)\r
-{\r
- int i;\r
- char far *text;\r
-\r
- text = (char _seg *)grsegs[LEVEL1TEXT+mapon];\r
-\r
- textstarts[0] = 0;\r
-\r
- for (i=1;i<=26;i++)\r
- {\r
- while (*text != '\n')\r
- {\r
- if (*text == '\r')\r
- *text = 0;\r
- text++;\r
- }\r
- text++;\r
- textstarts[i] = FP_OFF(text);\r
- }\r
-\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-==================\r
-=\r
-= DrawEnterScreen\r
-=\r
-==================\r
-*/\r
-\r
-static char *levelnames[] =\r
- {\r
- "The Approach",\r
- "Nemesis's Keep",\r
- "Ground Floor",\r
- "Second Floor",\r
- "Third Floor",\r
- "Tower One",\r
- "Tower Two",\r
- "Secret Halls",\r
- "Access Floor",\r
- "The Dungeon",\r
- "Lower Dungeon",\r
- "Catacomb",\r
- "Lower Reaches",\r
- "The Warrens",\r
- "Hidden Caverns",\r
- "The Fens of Insanity",\r
- "Chaos Corridors",\r
- "The Labyrinth",\r
- "Halls of Blood",\r
- "Nemesis's Lair"\r
- };\r
-void DrawEnterScreen (void)\r
-{\r
- int x,y;\r
-\r
- VW_Bar(0,0,VIEWWIDTH,VIEWHEIGHT,9); // Medium blue\r
-\r
- x = (VIEWWIDTH - (18 * 8)) / 2 -3;\r
- y = (VIEWHEIGHT - (5 * 8)) / 2;\r
- VW_DrawPic(x / 8,y,ENTERPLAQUEPIC);\r
-\r
- WindowX = x;\r
- WindowW = 18 * 8;\r
- PrintY = (VIEWHEIGHT/2) + 3;\r
- US_CPrint (levelnames[gamestate.mapon]);\r
-}\r
-\r
-//==========================================================================\r
-\r
-boolean tileneeded[NUMFLOORS];\r
-\r
-\r
-/*\r
-==================\r
-=\r
-= CacheScaleds\r
-=\r
-==================\r
-*/\r
-\r
-void CacheScaleds (void)\r
-{\r
- int i,j;\r
- unsigned source,dest;\r
-\r
- FreeUpMemory ();\r
- CA_CacheGrChunk(LEVEL1TEXT+mapon);\r
- ScanText ();\r
-\r
-//\r
-// make sure we are displaying screenpage 0\r
-//\r
- if (screenpage)\r
- {\r
- source = screenloc[screenpage];\r
- dest = screenloc[0];\r
- VW_ScreenToScreen (source,dest,40,VIEWHEIGHT);\r
- screenpage = 0;\r
- VW_SetScreen (dest,0);\r
- displayofs = dest;\r
- }\r
-\r
-//\r
-// cache wall pictures\r
-//\r
- for (i=1;i<NUMFLOORS;i++)\r
- if (tileneeded[i])\r
- {\r
- SetupScaleWall (walllight1[i]);\r
- SetupScaleWall (walllight2[i]);\r
- SetupScaleWall (walldark1[i]);\r
- SetupScaleWall (walldark2[i]);\r
- }\r
-\r
-//\r
-// cache the actor pictures\r
-//\r
- for (i=0;i<NUMLUMPS;i++)\r
- if (lumpneeded[i])\r
- for (j=lumpstart[i];j<=lumpend[i];j++)\r
- SetupScalePic(j);\r
-\r
- source = screenloc[0];\r
- for (i=1;i<=2;i++)\r
- {\r
- dest = screenloc[i];\r
- VW_ScreenToScreen (source,dest,40,VIEWHEIGHT);\r
- }\r
-\r
- screenpage = 1;\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
- memset (tileneeded,0,sizeof(tileneeded));\r
-//\r
-// randomize if not a demo\r
-//\r
- if (DemoMode)\r
- {\r
- US_InitRndT(false);\r
- gamestate.difficulty = gd_Normal;\r
- }\r
- else\r
- US_InitRndT(true);\r
-\r
-//\r
-// load the level\r
-//\r
- CA_CacheMap (gamestate.mapon);\r
-\r
- mapwidth = mapheaderseg[mapon]->width;\r
- mapheight = mapheaderseg[mapon]->height;\r
-\r
-//\r
-// make a lookup table for the maps left edge\r
-//\r
- spot = 0;\r
- for (y=0;y<mapheight;y++)\r
- {\r
- farmapylookup[y] = spot;\r
- spot += mapwidth;\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<NUMFLOORS)\r
- {\r
- tileneeded[tile] = true;\r
- tilemap[x][y] = tile;\r
- if (tile>=EXPWALLSTART && tile<EXPWALLSTART+NUMEXPWALLS)\r
- {\r
- tileneeded[WALLEXP] = tileneeded[WALLEXP+1]\r
- = tileneeded[WALLEXP+2] = true;\r
- }\r
-\r
- if (tile>0)\r
- (unsigned)actorat[x][y] = tile;\r
- }\r
- }\r
-\r
-\r
-//\r
-// decide which graphics are needed and spawn actors\r
-//\r
- ScanInfoPlane ();\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
-= LatchDrawPic\r
-=\r
-=====================\r
-*/\r
-\r
-void LatchDrawPic (unsigned x, unsigned y, unsigned picnum)\r
-{\r
- unsigned wide, height, source, dest;\r
-\r
- wide = pictable[picnum-STARTPICS].width;\r
- height = pictable[picnum-STARTPICS].height;\r
- dest = bufferofs + ylookup[y]+x;\r
- source = latchpics[picnum-FIRSTLATCHPIC];\r
-\r
- EGAWRITEMODE(1);\r
- EGAMAPMASK(15);\r
-\r
-asm mov bx,[linewidth]\r
-asm sub bx,[wide]\r
-\r
-asm mov ax,[screenseg]\r
-asm mov es,ax\r
-asm mov ds,ax\r
-\r
-asm mov si,[source]\r
-asm mov di,[dest]\r
-asm mov dx,[height] // scan lines to draw\r
-asm mov ax,[wide]\r
-\r
-lineloop:\r
-asm mov cx,ax\r
-asm rep movsb\r
-asm add di,bx\r
-\r
-asm dec dx\r
-asm jnz lineloop\r
-\r
-asm mov ax,ss\r
-asm mov ds,ax // restore turbo's data segment\r
-\r
- EGAWRITEMODE(0);\r
-}\r
-\r
-\r
-//==========================================================================\r
-\r
-/*\r
-=====================\r
-=\r
-= Victory\r
-=\r
-=====================\r
-*/\r
-\r
-void Victory (void)\r
-{\r
- FreeUpMemory ();\r
- NormalScreen ();\r
- CA_CacheGrChunk (FINALEPIC);\r
- VWB_DrawPic (0,0,FINALEPIC);\r
- UNMARKGRCHUNK(FINALEPIC);\r
- VW_UpdateScreen ();\r
- SD_PlaySound (GETBOLTSND);\r
- SD_WaitSoundDone ();\r
- SD_PlaySound (GETNUKESND);\r
- SD_WaitSoundDone ();\r
- SD_PlaySound (GETPOTIONSND);\r
- SD_WaitSoundDone ();\r
- SD_PlaySound (GETKEYSND);\r
- SD_WaitSoundDone ();\r
- SD_PlaySound (GETSCROLLSND);\r
- SD_WaitSoundDone ();\r
- SD_PlaySound (GETPOINTSSND);\r
- SD_WaitSoundDone ();\r
- IN_ClearKeysDown ();\r
- IN_Ack();\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-===================\r
-=\r
-= Died\r
-=\r
-===================\r
-*/\r
-\r
-void Died (void)\r
-{\r
- unsigned page1,page2;\r
-//\r
-// fizzle fade screen to grey\r
-//\r
- FreeUpMemory ();\r
- SD_PlaySound (GAMEOVERSND);\r
- bufferofs = screenloc[(screenpage+1)%3];\r
- LatchDrawPic(0,0,DEADPIC);\r
- FizzleFade(bufferofs,displayofs,VIEWWIDTH,VIEWHEIGHT,false);\r
- IN_ClearKeysDown();\r
- IN_Ack();\r
- VW_SetScreen (bufferofs,0);\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-===================\r
-=\r
-= NormalScreen\r
-=\r
-===================\r
-*/\r
-\r
-void NormalScreen (void)\r
-{\r
- VW_SetSplitScreen (200);\r
- bufferofs = displayofs = SCREEN1START;\r
- VW_Bar(0,0,320,200,0);\r
- bufferofs = SCREEN2START;\r
- VW_Bar(0,0,320,200,0);\r
- VW_SetScreen (displayofs,0);\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
-\r
- screenpage = 0;\r
-\r
- bufferofs = 0;\r
- VW_Bar (0,0,320,STATUSLINES,7);\r
- for (i=0;i<3;i++)\r
- {\r
- bufferofs = screenloc[i];\r
- VW_Bar (0,0,320,VIEWHEIGHT,7);\r
- }\r
-\r
-\r
- VW_SetSplitScreen(144);\r
- VW_SetScreen(screenloc[0],0);\r
- bufferofs = 0;\r
-\r
- CA_CacheGrChunk (STATUSPIC);\r
- CA_CacheGrChunk (SIDEBARSPIC);\r
-\r
- VW_DrawPic (0,0,STATUSPIC);\r
-\r
- for (i=0;i<3;i++)\r
- {\r
- bufferofs = screenloc[i];\r
- VW_DrawPic (33,0,SIDEBARSPIC);\r
- }\r
-\r
- grneeded[STATUSPIC]&= ~ca_levelbit;\r
- grneeded[SIDEBARSPIC]&= ~ca_levelbit;\r
- MM_SetPurge(&grsegs[STATUSPIC],3);\r
- MM_SetPurge(&grsegs[SIDEBARSPIC],3);\r
-\r
- RedrawStatusWindow ();\r
- bufferofs = displayofs = screenloc[0];\r
-}\r
-\r
-\r
-//==========================================================================\r
-\r
-/*\r
-===================\r
-=\r
-= LoadLatchMem\r
-=\r
-===================\r
-*/\r
-\r
-void LoadLatchMem (void)\r
-{\r
- int i,j,p,m;\r
- byte far *src, far *dest;\r
- unsigned destoff;\r
-\r
- EGAWRITEMODE(0);\r
-\r
-//\r
-// draw some pics into latch memory\r
-//\r
-\r
-//\r
-// tile 8s\r
-//\r
- latchpics[0] = freelatch;\r
- src = (byte _seg *)grsegs[STARTTILE8];\r
- dest = MK_FP(0xa000,freelatch);\r
-\r
- for (i=0;i<NUMTILE8;i++)\r
- {\r
- for (p=0;p<4;p++)\r
- {\r
- m = 1<<p;\r
- asm mov dx,SC_INDEX\r
- asm mov al,SC_MAPMASK\r
- asm mov ah,[BYTE PTR m]\r
- asm out dx,ax\r
- for (j=0;j<8;j++)\r
- *(dest+j)=*src++;\r
- }\r
- dest+=8;\r
- }\r
-\r
-//\r
-// tile 16s\r
-//\r
- src = (byte _seg *)grsegs[STARTTILE16];\r
-\r
- for (i=0;i<NUMTILE16;i++)\r
- {\r
- CA_CacheGrChunk (STARTTILE16+i);\r
- src = (byte _seg *)grsegs[STARTTILE16+i];\r
- if (src)\r
- {\r
- tileoffsets[i] = FP_OFF(dest);\r
- for (p=0;p<4;p++)\r
- {\r
- m = 1<<p;\r
- asm mov dx,SC_INDEX\r
- asm mov al,SC_MAPMASK\r
- asm mov ah,[BYTE PTR m]\r
- asm out dx,ax\r
- for (j=0;j<32;j++)\r
- *(dest+j)=*src++;\r
- }\r
- dest+=32;\r
- MM_FreePtr (&grsegs[STARTTILE16+i]);\r
- UNMARKGRCHUNK(STARTTILE16+i);\r
- }\r
- else\r
- tileoffsets[i] = 0;\r
- }\r
-\r
-\r
-//\r
-// pics\r
-//\r
- destoff = FP_OFF(dest);\r
- for (i=FIRSTLATCHPIC+1;i<FIRSTSCALEPIC;i++)\r
- {\r
- latchpics[i-FIRSTLATCHPIC] = destoff;\r
- CA_CacheGrChunk (i);\r
- j = pictable[i-STARTPICS].width * pictable[i-STARTPICS].height;\r
- VW_MemToScreen (grsegs[i],destoff,j,1);\r
- destoff+=j;\r
- MM_FreePtr (&grsegs[i]);\r
- UNMARKGRCHUNK(i);\r
- }\r
-\r
- EGAMAPMASK(15);\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-===================\r
-=\r
-= FizzleFade\r
-=\r
-===================\r
-*/\r
-\r
-#define PIXPERFRAME 1600\r
-\r
-void FizzleFade (unsigned source, unsigned dest,\r
- unsigned width,unsigned height, boolean abortable)\r
-{\r
- unsigned drawofs,pagedelta;\r
- unsigned char maskb[8] = {1,2,4,8,16,32,64,128};\r
- unsigned x,y,p,frame;\r
- long rndval;\r
-\r
- pagedelta = dest-source;\r
- VW_SetScreen (dest,0);\r
- rndval = 1;\r
- y = 0;\r
-\r
-asm mov es,[screenseg]\r
-asm mov dx,SC_INDEX\r
-asm mov al,SC_MAPMASK\r
-asm out dx,al\r
-\r
- TimeCount=frame=0;\r
- do // while (1)\r
- {\r
- if (abortable)\r
- {\r
- IN_ReadControl(0,&c);\r
- if (c.button0 || c.button1 || Keyboard[sc_Space]\r
- || Keyboard[sc_Enter])\r
- {\r
- VW_ScreenToScreen (source,dest,width/8,height);\r
- return;\r
- }\r
- }\r
-\r
- for (p=0;p<PIXPERFRAME;p++)\r
- {\r
- //\r
- // seperate random value into x/y pair\r
- //\r
- asm mov ax,[WORD PTR rndval]\r
- asm mov dx,[WORD PTR rndval+2]\r
- asm mov bx,ax\r
- asm dec bl\r
- asm mov [BYTE PTR y],bl // low 8 bits - 1 = y xoordinate\r
- asm mov bx,ax\r
- asm mov cx,dx\r
- asm shr cx,1\r
- asm rcr bx,1\r
- asm shr bx,1\r
- asm shr bx,1\r
- asm shr bx,1\r
- asm shr bx,1\r
- asm shr bx,1\r
- asm shr bx,1\r
- asm shr bx,1\r
- asm mov [x],bx // next 9 bits = x xoordinate\r
- //\r
- // advance to next random element\r
- //\r
- asm shr dx,1\r
- asm rcr ax,1\r
- asm jnc noxor\r
- asm xor dx,0x0001\r
- asm xor ax,0x2000\r
-noxor:\r
- asm mov [WORD PTR rndval],ax\r
- asm mov [WORD PTR rndval+2],dx\r
-\r
- if (x>width || y>height)\r
- continue;\r
- drawofs = source+ylookup[y];\r
-\r
- asm mov cx,[x]\r
- asm mov si,cx\r
- asm and si,7\r
- asm mov dx,GC_INDEX\r
- asm mov al,GC_BITMASK\r
- asm mov ah,BYTE PTR [maskb+si]\r
- asm out dx,ax\r
-\r
- asm mov si,[drawofs]\r
- asm shr cx,1\r
- asm shr cx,1\r
- asm shr cx,1\r
- asm add si,cx\r
- asm mov di,si\r
- asm add di,[pagedelta]\r
-\r
- asm mov dx,GC_INDEX\r
- asm mov al,GC_READMAP // leave GC_INDEX set to READMAP\r
- asm out dx,al\r
-\r
- asm mov dx,SC_INDEX+1\r
- asm mov al,1\r
- asm out dx,al\r
- asm mov dx,GC_INDEX+1\r
- asm mov al,0\r
- asm out dx,al\r
-\r
- asm mov bl,[es:si]\r
- asm xchg [es:di],bl\r
-\r
- asm mov dx,SC_INDEX+1\r
- asm mov al,2\r
- asm out dx,al\r
- asm mov dx,GC_INDEX+1\r
- asm mov al,1\r
- asm out dx,al\r
-\r
- asm mov bl,[es:si]\r
- asm xchg [es:di],bl\r
-\r
- asm mov dx,SC_INDEX+1\r
- asm mov al,4\r
- asm out dx,al\r
- asm mov dx,GC_INDEX+1\r
- asm mov al,2\r
- asm out dx,al\r
-\r
- asm mov bl,[es:si]\r
- asm xchg [es:di],bl\r
-\r
- asm mov dx,SC_INDEX+1\r
- asm mov al,8\r
- asm out dx,al\r
- asm mov dx,GC_INDEX+1\r
- asm mov al,3\r
- asm out dx,al\r
-\r
- asm mov bl,[es:si]\r
- asm xchg [es:di],bl\r
-\r
- if (rndval == 1) // entire sequence has been completed\r
- {\r
- EGABITMASK(255);\r
- EGAMAPMASK(15);\r
- return;\r
- };\r
- }\r
- frame++;\r
- while (TimeCount<frame) // don't go too fast\r
- ;\r
- } while (1);\r
-\r
-\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-===================\r
-=\r
-= FizzleOut\r
-=\r
-===================\r
-*/\r
-\r
-void FizzleOut (int showlevel)\r
-{\r
- unsigned page1,page2;\r
-//\r
-// fizzle fade screen to grey\r
-//\r
- bufferofs = screenloc[(screenpage+1)%3];\r
- if (showlevel)\r
- DrawEnterScreen ();\r
- FizzleFade(bufferofs,displayofs,VIEWWIDTH,VIEWHEIGHT,false);\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-====================\r
-=\r
-= FreeUpMemory\r
-=\r
-====================\r
-*/\r
-\r
-void FreeUpMemory (void)\r
-{\r
- int i;\r
-\r
- for (i=0;i<NUMSCALEPICS;i++)\r
- if (shapedirectory[i])\r
- MM_SetPurge (&(memptr)shapedirectory[i],3);\r
-\r
- for (i=0;i<NUMSCALEWALLS;i++)\r
- if (walldirectory[i])\r
- MM_SetPurge (&(memptr)walldirectory[i],3);\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-==================\r
-=\r
-= DrawHighScores\r
-=\r
-==================\r
-*/\r
-\r
-void DrawHighScores(void)\r
-{\r
- char buffer[16],*str;\r
- word i,j,\r
- w,h,\r
- x,y;\r
- HighScore *s;\r
-\r
-\r
- CA_CacheGrChunk (HIGHSCORESPIC);\r
- VWB_DrawPic (0,0,HIGHSCORESPIC);\r
- MM_SetPurge (&grsegs[HIGHSCORESPIC],3);\r
- UNMARKGRCHUNK(HIGHSCORESPIC);\r
-\r
- for (i = 0,s = Scores;i < MaxScores;i++,s++)\r
- {\r
- PrintY = 68 + (16 * i);\r
-\r
- //\r
- // name\r
- //\r
- PrintX = 60;\r
- US_Print(s->name);\r
-\r
- //\r
- // level\r
- //\r
- ultoa(s->completed,buffer,10);\r
- for (str = buffer;*str;str++)\r
- *str = *str + (129 - '0'); // Used fixed-width numbers (129...)\r
- USL_MeasureString(buffer,&w,&h);\r
- PrintX = (25 * 8) - 8 - w;\r
- US_Print(buffer);\r
-\r
- //\r
- // score\r
- //\r
- ultoa(s->score,buffer,10);\r
- for (str = buffer;*str;str++)\r
- *str = *str + (129 - '0'); // Used fixed-width numbers (129...)\r
- USL_MeasureString(buffer,&w,&h);\r
- PrintX = (34 * 8) - 8 - w;\r
- US_Print(buffer);\r
- }\r
-\r
- fontcolor = F_BLACK;\r
-}\r
-\r
-\r
-\r
-/*\r
-=======================\r
-=\r
-= CheckHighScore\r
-=\r
-=======================\r
-*/\r
-\r
-void CheckHighScore (long score,word other)\r
-{\r
- word i,j;\r
- int n;\r
- HighScore myscore;\r
-\r
- strcpy(myscore.name,"");\r
- myscore.score = score;\r
- myscore.completed = other;\r
-\r
- for (i = 0,n = -1;i < MaxScores;i++)\r
- {\r
- if\r
- (\r
- (myscore.score > Scores[i].score)\r
- || (\r
- (myscore.score == Scores[i].score)\r
- && (myscore.completed > Scores[i].completed)\r
- )\r
- )\r
- {\r
- for (j = MaxScores;--j > i;)\r
- Scores[j] = Scores[j - 1];\r
- Scores[i] = myscore;\r
- n = i;\r
- HighScoresDirty = true;\r
- break;\r
- }\r
- }\r
-\r
- if (n != -1)\r
- {\r
- //\r
- // got a high score\r
- //\r
- DrawHighScores ();\r
- PrintY = 68 + (16 * n);\r
- PrintX = 60;\r
- US_LineInput(PrintX,PrintY,Scores[n].name,nil,true,MaxHighName,100);\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
-#ifdef PROFILE\r
- clock_t start,end;\r
-#endif\r
-\r
- DrawPlayScreen ();\r
-\r
-restart:\r
- if (!loadedgame)\r
- {\r
- gamestate.difficulty = restartgame;\r
- restartgame = gd_Continue;\r
- DrawEnterScreen ();\r
- }\r
-\r
- do\r
- {\r
- playstate = gd_Continue;\r
- if (!loadedgame)\r
- SetupGameLevel ();\r
- else\r
- loadedgame = false;\r
-\r
- CacheScaleds ();\r
-\r
-#ifdef PROFILE\r
-start = clock();\r
-while (start == clock());\r
-start++;\r
-#endif\r
- PlayLoop ();\r
-#ifdef PROFILE\r
-end = clock();\r
-itoa(end-start,str,10);\r
- Quit (str);\r
-#endif\r
-\r
-\r
- switch (playstate)\r
- {\r
- case ex_died:\r
- Died ();\r
- NormalScreen ();\r
- FreeUpMemory ();\r
- CheckHighScore (gamestate.score,gamestate.mapon+1);\r
- return;\r
- case ex_warped:\r
- FizzleOut (true);\r
- if (gamestate.mapon >= NUMLEVELS)\r
- {\r
- Victory ();\r
- FreeUpMemory ();\r
- CheckHighScore(gamestate.score,gamestate.mapon+1);\r
- return;\r
- }\r
- break;\r
- case ex_abort:\r
- FreeUpMemory ();\r
- return;\r
- case ex_resetgame:\r
- case ex_loadedgame:\r
- goto restart;\r
- case ex_victorious:\r
- Victory ();\r
- FreeUpMemory();\r
- CheckHighScore(gamestate.score,gamestate.mapon+1);\r
- return;\r
- }\r
-\r
- } while (1);\r
-\r
-}\r