+++ /dev/null
-/* Catacomb Apocalypse 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_WIZ.C\r
-\r
-#include "DEF.H"\r
-#include "gelib.h"\r
-#pragma hdrstop\r
-\r
-/*\r
-=============================================================================\r
-\r
- LOCAL CONSTANTS\r
-\r
-=============================================================================\r
-*/\r
-\r
-////////#define NUMSCROLLS 8\r
-\r
-#define SHOWITEMS 9\r
-\r
-#define NUKETIME 40\r
-#define NUMBOLTS 10\r
-#define BOLTTICS 6\r
-\r
-#define STATUSCOLOR 1\r
-#define TEXTCOLOR 14\r
-\r
-#define SIDEBARWIDTH 5\r
-\r
-#define BODYLINE 8\r
-#define POWERLINE 80\r
-\r
-#define SPECTILESTART 0 // 18\r
-\r
-\r
-#define SHOTDAMAGE 1\r
-#define BIGSHOTDAMAGE 3\r
-\r
-\r
-#define PLAYERSPEED 5120\r
-#define RUNSPEED (8192<<1)\r
-\r
-#define SHOTSPEED 10000\r
-\r
-//#define LASTWALLTILE 47\r
-//#define LASTSPECIALTILE 37\r
-\r
-#define LASTTILE (LASTWALLPIC-FIRSTWALLPIC) // 47\r
-\r
-#define FIRETIME 2\r
-\r
-#define HANDPAUSE 30\r
-\r
-#define RIGHTEDGE 205;\r
-#define LEFTEDGE 95;\r
-#define PRNY 32;\r
-#define WINX 10;\r
-#define WINY 32;\r
-\r
-/*\r
-=============================================================================\r
-\r
- GLOBAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-long lastnuke,lasthand;\r
-int lasttext;\r
-int handheight;\r
-int boltsleft,bolttimer;\r
-short RadarXY[MAX_RADAR_BLIPS][3]={-1,-1,-1};\r
-short radarx=RADARX,radary=RADARY,radar_xcenter=RADAR_XCENTER,radar_ycenter=RADAR_YCENTER;\r
-int key_x[4]={24,27,27,24},key_y[4]={30,57,30,57};\r
-\r
-boolean redraw_gems,button0down;\r
-\r
-/*\r
-=============================================================================\r
-\r
- LOCAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-int lastradar;\r
-unsigned lastfiretime;\r
-\r
-int strafeangle[9] = {0,90,180,270,45,135,225,315,0};\r
-\r
-short RotateAngle = -1; // -1 == No Angle to turn to...\r
-short FreezeTime = 0; // Stops all think (except player)\r
-short RotateSpeed; // Speed (and dir) to rotate..\r
-\r
-\r
-//===========================================================================\r
-\r
-void CalcBounds(objtype *ob);\r
-boolean VerifyGateExit(void);\r
-void DrawNSEWIcons(void);\r
-void DrawGems(void);\r
-void DrawRadar (void);\r
-void DrawChar (unsigned x, unsigned y, unsigned tile);\r
-void RedrawStatusWindow (void);\r
-void GiveBolt (void);\r
-void TakeBolt (void);\r
-void GiveNuke (void);\r
-void TakeNuke (void);\r
-void GivePotion (void);\r
-void TakePotion (void);\r
-void GiveKey (int keytype);\r
-void TakeKey (int keytype);\r
-////////////void GiveScroll (int scrolltype,boolean show);\r
-////////////void ReadScroll (int scroll);\r
-////////////void DrawScrolls(void);\r
-\r
-void DrawNum(short x,short y,short value,short maxdigits);\r
-\r
-//----------\r
-\r
-void Shoot (void);\r
-void BigShoot (void);\r
-void CastBolt (void);\r
-void CastNuke (void);\r
-void DrinkPotion (void);\r
-\r
-//----------\r
-void DrawHealth(void);\r
-\r
-void SpawnPlayer (int tilex, int tiley, int dir);\r
-void Thrust (int angle, unsigned speed);\r
-void T_Player (objtype *ob);\r
-\r
-//void AddPoints (int points);\r
-\r
-void ClipMove (objtype *ob, long xmove, long ymove);\r
-boolean ShotClipMove (objtype *ob, long xmove, long ymove);\r
-\r
-//===========================================================================\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= DrawChar\r
-=\r
-===============\r
-*/\r
-\r
-void DrawChar (unsigned x, unsigned y, unsigned tile)\r
-{\r
- unsigned junk = latchpics[0];\r
-\r
- EGAWRITEMODE(1);\r
-asm mov bx,[y]\r
-asm shl bx,1\r
-asm mov di,[WORD PTR ylookup+bx]\r
-asm add di,[x]\r
-asm mov si,[tile]\r
-asm shl si,1\r
-asm shl si,1\r
-asm shl si,1\r
-asm add si,[junk] // the damn inline assembler won't reference latchpics\r
-asm mov ax,[screenseg]\r
-asm mov es,ax\r
-asm mov ds,ax\r
-asm mov dx,SCREENWIDTH-1\r
-asm movsb\r
-asm add di,dx\r
-asm movsb\r
-asm add di,dx\r
-asm movsb\r
-asm add di,dx\r
-asm movsb\r
-asm add di,dx\r
-asm movsb\r
-asm add di,dx\r
-asm movsb\r
-asm add di,dx\r
-asm movsb\r
-asm add di,dx\r
-asm movsb\r
-\r
-asm mov ax,ss\r
-asm mov ds,ax\r
- EGAWRITEMODE(0);\r
-}\r
-\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= RedrawStatusWindow\r
-=\r
-===============\r
-*/\r
-\r
-void RedrawStatusWindow (void)\r
-{\r
- short keytype;\r
-\r
- EGABITMASK(0xff);\r
- for (keytype=0; keytype<4; keytype++)\r
- DrawNum(key_x[keytype],key_y[keytype],gamestate.keys[keytype],2);\r
- DrawNum(20,54,gamestate.potions,2);\r
- DrawNum(20,36,gamestate.nukes,2);\r
- DrawNum(20,18,gamestate.bolts,2);\r
-\r
- DrawHealth();\r
- DrawRadar();\r
- EGAWRITEMODE(0);\r
- DrawGems();\r
-//////// DrawScrolls();\r
- redraw_gems = false;\r
-}\r
-\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= GiveBolt\r
-=\r
-===============\r
-*/\r
-\r
-void GiveBolt (void)\r
-{\r
- if (gamestate.bolts == 99)\r
- return;\r
-\r
- SD_PlaySound (GETBOLTSND);\r
- DrawNum(20,18,++gamestate.bolts,2);\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= TakeBolt\r
-=\r
-===============\r
-*/\r
-\r
-void TakeBolt (void)\r
-{\r
- SD_PlaySound (USEBOLTSND);\r
- DrawNum(20,18,--gamestate.bolts,2);\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= GiveNuke\r
-=\r
-===============\r
-*/\r
-\r
-void GiveNuke (void)\r
-{\r
- if (gamestate.nukes == 99)\r
- return;\r
-\r
- SD_PlaySound (GETNUKESND);\r
- DrawNum(20,36,++gamestate.nukes,2);\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= TakeNuke\r
-=\r
-===============\r
-*/\r
-\r
-void TakeNuke (void)\r
-{\r
- SD_PlaySound (USENUKESND);\r
- DrawNum(20,36,--gamestate.nukes,2);\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= GivePotion\r
-=\r
-===============\r
-*/\r
-\r
-void GivePotion (void)\r
-{\r
- if (gamestate.potions == 99)\r
- return;\r
-\r
- SD_PlaySound (GETPOTIONSND);\r
- DrawNum(20,54,++gamestate.potions,2);\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= TakePotion\r
-=\r
-===============\r
-*/\r
-\r
-void TakePotion (void)\r
-{\r
- SD_PlaySound (USEPOTIONSND);\r
- DrawNum(20,54,--gamestate.potions,2);\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= GiveKey\r
-=\r
-===============\r
-*/\r
-\r
-void GiveKey (int keytype)\r
-{\r
- int i,j,x;\r
-\r
- if (gamestate.keys[keytype] == 99)\r
- return;\r
-\r
- SD_PlaySound (GETKEYSND);\r
- DrawNum(key_x[keytype],key_y[keytype],++gamestate.keys[keytype],2);\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= TakeKey\r
-=\r
-===============\r
-*/\r
-\r
-void TakeKey (int keytype)\r
-{\r
- int i,j,x;\r
- char *key_colors[] = {"a RED key",\r
- "a YELLOW key",\r
- "a GREEN key",\r
- "a BLUE key"};\r
-\r
-\r
- SD_PlaySound (USEKEYSND);\r
- DrawNum(key_x[keytype],key_y[keytype],--gamestate.keys[keytype],2);\r
- displayofs = bufferofs = screenloc[screenpage];\r
- CenterWindow(20,5);\r
- US_CPrint("\nYou use\n");\r
- US_CPrint(key_colors[keytype]);\r
- VW_UpdateScreen();\r
- VW_WaitVBL(120);\r
-}\r
-\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= GiveGem\r
-=\r
-===============\r
-*/\r
-\r
-void GiveGem (int gemtype)\r
-{\r
-#if 0\r
- int i,j,x;\r
-\r
- SD_PlaySound (GETKEYSND);\r
- DrawNum(key_x[keytype],key_y[keytype],++gamestate.keys[keytype],2);\r
-#endif\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= TakeGem\r
-=\r
-===============\r
-*/\r
-\r
-void TakeGem (int gemtype)\r
-{\r
-#if 0\r
- int i,j,x;\r
-\r
- SD_PlaySound (USEKEYSND);\r
- DrawNum(key_x[keytype],key_y[keytype],--gamestate.keys[keytype],2);\r
-#endif\r
-}\r
-\r
-/*\r
-===============\r
-=\r
-= DrawGem\r
-=\r
-===============\r
-*/\r
-\r
-void DrawGems()\r
-{\r
- short loop;\r
-\r
- redraw_gems = false;\r
-\r
- bufferofs = 0;\r
- LatchDrawPic (31,51,RADAR_BOTTOMPIC);\r
- for (loop=0; loop<5; loop++)\r
- if (gamestate.gems[loop])\r
- LatchDrawPic (32+loop,53,RADAR_RGEMPIC+loop);\r
-}\r
-\r
-//===========================================================================\r
-\r
-#if 0\r
-\r
-/*\r
-===============\r
-=\r
-= GiveScroll\r
-=\r
-===============\r
-*/\r
-\r
-void GiveScroll (int scrolltype,boolean show)\r
-{\r
- int i,j,x,y,scrollnum;\r
-\r
- SD_PlaySound (GETSCROLLSND);\r
- gamestate.scrolls[scrolltype] = true;\r
-\r
- y = 30 + ((scrolltype > 3) * 10);\r
- x = 26 + (scrolltype % 4);\r
- DrawChar(x,y,SCROLLCHARS+scrolltype);\r
-\r
- if (show)\r
- ReadScroll(scrolltype);\r
-}\r
-\r
-/*\r
-===============\r
-=\r
-= DrawScrolls\r
-=\r
-= Force draw of all scrolls\r
-=\r
-===============\r
-*/\r
-void DrawScrolls()\r
-{\r
- int loop,x,y;\r
-\r
- VW_Bar(210,30,30,18,0xf);\r
-\r
- for (loop=0;loop<8;loop++)\r
- if (gamestate.scrolls[loop])\r
- {\r
- y = 30 + ((loop > 3) * 10);\r
- x = 26 + (loop % 4);\r
- DrawChar(x,y,SCROLLCHARS+loop);\r
- }\r
-}\r
-#endif\r
-\r
-\r
-//===========================================================================\r
-\r
-#if 0\r
-/*\r
-===============\r
-=\r
-= GivePoints\r
-=\r
-===============\r
-*/\r
-\r
-void GivePoints (int points)\r
-{\r
- pointcount = 1;\r
- pointsleft += points;\r
-}\r
-#endif\r
-\r
-\r
-//===========================================================================\r
-\r
-#if 0\r
-/*\r
-===============\r
-=\r
-= AddPoints\r
-=\r
-===============\r
-*/\r
-\r
-void AddPoints (int points)\r
-{\r
- char str[10];\r
- int len,x,i;\r
-\r
- gamestate.score += points;\r
-\r
- ltoa (gamestate.score,str,10);\r
- len = strlen (str);\r
-\r
- x=24+(8-len);\r
- for (i=0;i<len;i++)\r
- DrawChar(x++,40,NUMBERCHARS+str[i]-'0');\r
-}\r
-#endif\r
-\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= DrawHealth\r
-=\r
-===============\r
-*/\r
-void DrawHealth()\r
-{\r
- char picnum;\r
- int percentage;\r
-\r
- percentage = PERCENTAGE(100,MAXBODY,gamestate.body,9);\r
-\r
- DrawNum(11,57,percentage,3);\r
-\r
- if (percentage > 75)\r
- picnum = FACE1PIC;\r
- else\r
- if (percentage > 50)\r
- picnum = FACE2PIC;\r
- else\r
- if (percentage > 25)\r
- picnum = FACE3PIC;\r
- else\r
- if (percentage)\r
- picnum = FACE4PIC;\r
- else\r
- {\r
- picnum = FACE5PIC;\r
- CA_CacheGrChunk (picnum);\r
- }\r
-\r
- bufferofs = 0;\r
- if (!percentage)\r
- {\r
- UNMARKGRCHUNK(picnum);\r
-// VW_DrawPic(8,14,picnum);\r
- VW_DrawPic(10,14,picnum);\r
- }\r
- else\r
- LatchDrawPic(10,14,picnum);\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= DrawFreezeTime\r
-=\r
-===============\r
-*/\r
-void DrawFreezeTime()\r
-{\r
- short temp = fontcolor;\r
- long percentage;\r
- percentage = PERCENTAGE(100,MAXFREEZETIME,(long)FreezeTime,7);\r
- fontcolor = 1 ^ 14;\r
- DrawNum(23,70,percentage,3);\r
- fontcolor = temp;\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= DrawNum\r
-=\r
-===============\r
-*/\r
-void DrawNum(short x,short y,short value,short maxdigits)\r
-{\r
- char str[10],len,i;\r
-\r
- itoa(value,str,10);\r
- len=strlen(str);\r
-\r
- for (i=len; i<maxdigits; i++)\r
- DrawChar(x++,y,BLANKCHAR);\r
-\r
- for (i=0;i<len;i++)\r
- DrawChar(x++,y,NUMBERCHARS+str[i]-'0');\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= GiveChest\r
-=\r
-===============\r
-*/\r
-\r
-void GiveChest(void)\r
-{\r
- char i;\r
-\r
- for (i=0;i<random(4);i++)\r
- {\r
- GiveBolt();\r
- SD_WaitSoundDone();\r
- }\r
-\r
- for (i=0;i<random(3);i++)\r
- {\r
- GiveNuke();\r
- SD_WaitSoundDone();\r
- }\r
-\r
- for (i=0;i<random(2);i++)\r
- {\r
- GivePotion();\r
- SD_WaitSoundDone();\r
- }\r
-}\r
-\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= GiveGoal\r
-=\r
-===============\r
-*/\r
-\r
-void GiveGoal (void)\r
-{\r
- SD_PlaySound (GETPOINTSSND);\r
- playstate = ex_victorious;\r
-}\r
-\r
-\r
-//===========================================================================\r
-\r
-#if 0\r
-/*\r
-===============\r
-=\r
-= DrawLevelNumber\r
-=\r
-===============\r
-*/\r
-\r
-void DrawLevelNumber (int number)\r
-{\r
- char str[10];\r
- int len;\r
- unsigned temp;\r
-\r
- bufferofs = 0;\r
- if (number<9)\r
- PrintX=13;\r
- else\r
- PrintX = 5;\r
- PrintY = 4;\r
- VW_Bar (5,4,16,9,STATUSCOLOR);\r
- temp = fontcolor;\r
- fontcolor = TEXTCOLOR^STATUSCOLOR;\r
- US_PrintUnsigned (number+1);\r
- fontcolor = temp;\r
-}\r
-#endif\r
-\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= DrawText\r
-=\r
-===============\r
-*/\r
-\r
-void DrawText (boolean draw_text_whether_it_needs_it_or_not)\r
-{\r
- unsigned number;\r
- char str[80];\r
- char far *text;\r
- unsigned temp;\r
-\r
- //\r
- // draw a new text description if needed\r
- //\r
- number = *(mapsegs[0]+farmapylookup[player->tiley]+player->tilex)-NAMESTART;\r
-\r
- if ( number>26 )\r
- number = 0;\r
-\r
- if ((number == lasttext) && (!draw_text_whether_it_needs_it_or_not))\r
- return;\r
-\r
- lasttext = number;\r
-\r
- text = (char _seg *)grsegs[LEVEL1TEXT+mapon]+textstarts[number];\r
-\r
- if (text[0] == '@')\r
- {\r
- bordertime = 20;//FLASHTICS;\r
- bcolor = 15;\r
- VW_ColorBorder (15 | 56);\r
- text++;\r
- }\r
-\r
- _fmemcpy (str,text,80);\r
- DisplayMsg(str,NULL);\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= DisplayMsg\r
-=\r
-===============\r
-*/\r
-\r
-char DisplayMsg(char *text,char *choices)\r
-{\r
- char ch=true;\r
- short temp;\r
-\r
- bufferofs = 0;\r
- PrintY = 1;\r
- WindowX = 20;\r
- WindowW = 270;\r
-\r
- VW_Bar (WindowX,2,WindowW,8,STATUSCOLOR);\r
- temp = fontcolor;\r
- fontcolor = TEXTCOLOR^STATUSCOLOR;\r
- US_CPrintLine (text);\r
- fontcolor = temp;\r
-\r
- if (choices)\r
- {\r
- ch=GetKeyChoice(choices,true);\r
- LastScan = 0;\r
- }\r
-\r
- return(ch);\r
-}\r
-\r
-/*\r
-===============\r
-=\r
-= DisplaySMsg\r
-=\r
-===============\r
-*/\r
-char DisplaySMsg(char *text,char *choices)\r
-{\r
- char ch=true;\r
- short temp;\r
-\r
- bufferofs = 0;\r
- PrintY = 69;\r
- WindowX = 98;\r
- WindowW = 115;\r
-\r
- VW_Bar(WindowX,PrintY+1,WindowW,8,STATUSCOLOR);\r
- temp = fontcolor;\r
- fontcolor = TEXTCOLOR^STATUSCOLOR;\r
- US_CPrintLine (text);\r
- fontcolor = temp;\r
-\r
- if (choices)\r
- {\r
- ch=GetKeyChoice(choices,true);\r
- LastScan = 0;\r
- }\r
-\r
- return(ch);\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= DrawRadar\r
-=\r
-===============\r
-*/\r
-\r
-void DrawRadar (void)\r
-{\r
- int angle,number;\r
- short objnum;\r
-\r
- bufferofs = 0;\r
- LatchDrawPic (radarx,radary,RADAR_TOPPIC);\r
-\r
- asm cli\r
- asm mov dx,GC_INDEX\r
- asm mov ax,2*256+GC_MODE\r
- asm out dx,ax // write mode 2\r
-\r
- asm mov ax,GC_DATAROTATE\r
- asm out dx,ax // no rotation / logical operation\r
-\r
- asm mov dx,SC_INDEX\r
- asm mov al,SC_MAPMASK\r
- asm mov ah,15\r
- asm out dx,ax // write to all four planes\r
- asm sti\r
-\r
- objnum = 0;\r
- while (RadarXY[objnum][2] != -1)\r
- {\r
- RadarBlip(radar_xcenter+RadarXY[objnum][0],radar_ycenter+RadarXY[objnum][1],RadarXY[objnum][2]);\r
- objnum++;\r
- }\r
-\r
- asm cli\r
- asm mov dx,GC_INDEX\r
- asm mov ax,255*256+GC_BITMASK\r
- asm out dx,ax // reset bitmask to %11111111\r
- asm sti\r
-}\r
-\r
-//===========================================================================\r
-\r
-\r
-//--------------------------------------------------------------------------\r
-// DrawNSEWIcons(void)\r
-//--------------------------------------------------------------------------\r
-\r
-void DrawRadarObj(short dx, short dy, unsigned sprnum,signed long psin,signed long pcos);\r
-\r
-void DrawNSEWIcons()\r
-{\r
- signed x,y;\r
-\r
- x = -FixedByFrac(RADAR_X_IRADIUS,costable[player->angle]);\r
- y = -FixedByFrac(RADAR_Y_IRADIUS,sintable[player->angle]);\r
-\r
- VWB_DrawSprite(radar_xcenter+x-3,radar_ycenter+y-3,NORTHICONSPR);\r
-\r
-}\r
-\r
-#if 0\r
-/*\r
-===============\r
-=\r
-= DrawBars\r
-=\r
-===============\r
-*/\r
-\r
-void DrawBars (void)\r
-{\r
- int i;\r
- unsigned source,dest,topline;\r
-\r
- for (i=0;i<3;i++)\r
- {\r
- bufferofs = screenloc[i];\r
- VW_Bar (34*8,POWERLINE,40,MAXSHOTPOWER,1);\r
- }\r
- EGAWRITEMODE(1);\r
- asm mov es,[screenseg]\r
-\r
-//\r
-// shot power\r
-//\r
- if (gamestate.shotpower)\r
- {\r
- topline = MAXSHOTPOWER - gamestate.shotpower;\r
-\r
- source = latchpics[SHOTPOWERPIC-FIRSTLATCHPIC]+topline*SIDEBARWIDTH;\r
- dest = (POWERLINE+topline)*SCREENWIDTH+34;\r
-\r
- asm mov si,[source]\r
- asm mov di,[dest]\r
-\r
- asm mov cx,[WORD PTR gamestate.shotpower]\r
-newline:\r
- asm mov al,[es:si]\r
- asm mov [es:di+PAGE1START],al\r
- asm mov [es:di+PAGE2START],al\r
- asm mov [es:di+PAGE3START],al\r
- asm mov al,[es:si+1]\r
- asm mov [es:di+1+PAGE1START],al\r
- asm mov [es:di+1+PAGE2START],al\r
- asm mov [es:di+1+PAGE3START],al\r
- asm mov al,[es:si+2]\r
- asm mov [es:di+2+PAGE1START],al\r
- asm mov [es:di+2+PAGE2START],al\r
- asm mov [es:di+2+PAGE3START],al\r
- asm mov al,[es:si+3]\r
- asm mov [es:di+3+PAGE1START],al\r
- asm mov [es:di+3+PAGE2START],al\r
- asm mov [es:di+3+PAGE3START],al\r
- asm mov al,[es:si+4]\r
- asm mov [es:di+4+PAGE1START],al\r
- asm mov [es:di+4+PAGE2START],al\r
- asm mov [es:di+4+PAGE3START],al\r
-\r
- asm add di,SCREENWIDTH\r
- asm add si,5\r
-\r
- asm loop newline\r
- }\r
-\r
-//\r
-// body\r
-//\r
- if (gamestate.body)\r
- {\r
- source = latchpics[BODYPIC-FIRSTLATCHPIC];\r
- dest = BODYLINE*SCREENWIDTH+34;\r
-\r
- asm mov si,[source]\r
- asm mov di,[dest]\r
-\r
- asm mov cx,[WORD PTR gamestate.body]\r
-newline2:\r
- asm mov al,[es:si]\r
- asm mov [es:di+PAGE1START],al\r
- asm mov [es:di+PAGE2START],al\r
- asm mov [es:di+PAGE3START],al\r
- asm mov al,[es:si+1]\r
- asm mov [es:di+1+PAGE1START],al\r
- asm mov [es:di+1+PAGE2START],al\r
- asm mov [es:di+1+PAGE3START],al\r
- asm mov al,[es:si+2]\r
- asm mov [es:di+2+PAGE1START],al\r
- asm mov [es:di+2+PAGE2START],al\r
- asm mov [es:di+2+PAGE3START],al\r
- asm mov al,[es:si+3]\r
- asm mov [es:di+3+PAGE1START],al\r
- asm mov [es:di+3+PAGE2START],al\r
- asm mov [es:di+3+PAGE3START],al\r
- asm mov al,[es:si+4]\r
- asm mov [es:di+4+PAGE1START],al\r
- asm mov [es:di+4+PAGE2START],al\r
- asm mov [es:di+4+PAGE3START],al\r
-\r
- asm add di,SCREENWIDTH\r
- asm add si,5\r
-\r
- asm loop newline2\r
- }\r
-\r
- if (gamestate.body != MAXBODY)\r
- {\r
- source = latchpics[NOBODYPIC-FIRSTLATCHPIC]+gamestate.body*SIDEBARWIDTH;\r
- dest = (BODYLINE+gamestate.body)*SCREENWIDTH+34;\r
- topline = MAXBODY-gamestate.body;\r
-\r
- asm mov si,[source]\r
- asm mov di,[dest]\r
-\r
- asm mov cx,[WORD PTR topline]\r
-newline3:\r
- asm mov al,[es:si]\r
- asm mov [es:di+PAGE1START],al\r
- asm mov [es:di+PAGE2START],al\r
- asm mov [es:di+PAGE3START],al\r
- asm mov al,[es:si+1]\r
- asm mov [es:di+1+PAGE1START],al\r
- asm mov [es:di+1+PAGE2START],al\r
- asm mov [es:di+1+PAGE3START],al\r
- asm mov al,[es:si+2]\r
- asm mov [es:di+2+PAGE1START],al\r
- asm mov [es:di+2+PAGE2START],al\r
- asm mov [es:di+2+PAGE3START],al\r
- asm mov al,[es:si+3]\r
- asm mov [es:di+3+PAGE1START],al\r
- asm mov [es:di+3+PAGE2START],al\r
- asm mov [es:di+3+PAGE3START],al\r
- asm mov al,[es:si+4]\r
- asm mov [es:di+4+PAGE1START],al\r
- asm mov [es:di+4+PAGE2START],al\r
- asm mov [es:di+4+PAGE3START],al\r
-\r
- asm add di,SCREENWIDTH\r
- asm add si,5\r
-\r
- asm loop newline3\r
- }\r
-\r
- EGAWRITEMODE(0);\r
-}\r
-#endif\r
-\r
-/////////////////////////////////////////////////////////////////////////////\r
-//\r
-// Check the object and make sure it is a monster. Used in making the sound\r
-// of a monster being shot.\r
-//\r
-/////////////////////////////////////////////////////////////////////////////\r
-\r
-boolean PlayMonsterSound(classtype objclass)\r
-{\r
- switch (objclass)\r
- {\r
- case solidobj:\r
- case realsolidobj:\r
- return false;\r
- default:\r
- return true;\r
- }\r
-}\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
- SHOTS\r
-\r
-=============================================================================\r
-*/\r
-\r
-void T_Pshot (objtype *ob);\r
-\r
-\r
-extern statetype s_pshot1;\r
-extern statetype s_pshot2;\r
-\r
-//extern statetype s_bigpshot1;\r
-//extern statetype s_bigpshot2;\r
-\r
-\r
-statetype s_pshot1 = {PSHOT1PIC,8,&T_Pshot,&s_pshot2};\r
-statetype s_pshot2 = {PSHOT2PIC,8,&T_Pshot,&s_pshot1};\r
-\r
-\r
-statetype s_pshot_exp1 = {PSHOT_EXP1PIC,7,NULL,&s_pshot_exp2};\r
-statetype s_pshot_exp2 = {PSHOT_EXP2PIC,7,NULL,&s_pshot_exp3};\r
-statetype s_pshot_exp3 = {PSHOT_EXP3PIC,7,NULL,NULL};\r
-\r
-\r
-//statetype s_shotexplode = {PSHOT2PIC,8,NULL,NULL};\r
-\r
-//statetype s_bigpshot1 = {BIGPSHOT1PIC,8,&T_Pshot,&s_bigpshot2};\r
-//statetype s_bigpshot2 = {BIGPSHOT2PIC,8,&T_Pshot,&s_bigpshot1};\r
-\r
-\r
-/*\r
-===================\r
-=\r
-= SpawnPShot\r
-=\r
-===================\r
-*/\r
-\r
-void SpawnPShot (void)\r
-{\r
- DSpawnNewObjFrac (player->x,player->y,&s_pshot1,PIXRADIUS*2);\r
- new->obclass = pshotobj;\r
- new->speed = SHOTSPEED;\r
- new->angle = player->angle;\r
- new->active = always;\r
-}\r
-\r
-#if 0\r
-void SpawnBigPShot (void)\r
-{\r
- SpawnNewObjFrac (player->x,player->y,&s_bigpshot1,24*PIXRADIUS);\r
- new->obclass = bigpshotobj;\r
- new->speed = SHOTSPEED;\r
- new->angle = player->angle;\r
-}\r
-#endif\r
-\r
-\r
-/*\r
-===================\r
-=\r
-= JimsShotClipMove\r
-=\r
-= Only checks corners, so the object better be less than one tile wide!\r
-=\r
-===================\r
-*/\r
-boolean JimsShotClipMove (objtype *ob, long xmove, long ymove)\r
-{\r
- int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;\r
- long intersect,basex,basey,pointx,pointy;\r
- unsigned inside,total,tile;\r
- objtype *check;\r
- boolean moveok;\r
-\r
-//\r
-// move player and check to see if any corners are in solid tiles\r
-//\r
-// basex = ob->x;\r
-// basey = ob->y;\r
-\r
-// ob->x += xmove;\r
-// ob->y += ymove;\r
-\r
-// CalcBounds (ob);\r
-\r
- xl = ob->xl>>TILESHIFT;\r
- yl = ob->yl>>TILESHIFT;\r
-\r
- xh = ob->xh>>TILESHIFT;\r
- yh = ob->yh>>TILESHIFT;\r
-\r
- for (y=yl;y<=yh;y++)\r
- for (x=xl;x<=xh;x++)\r
- {\r
- check = actorat[x][y];\r
-\r
- if ((!check) || (check == player) || (!(check->flags & of_shootable)))\r
- continue;\r
-\r
- ob->x -= xmove;\r
- ob->y -= ymove;\r
-\r
- if (check->obclass != solidobj)\r
- {\r
- if (PlayMonsterSound(check->obclass))\r
- SD_PlaySound (SHOOTMONSTERSND);\r
- if (ob->obclass == bigpshotobj)\r
- ShootActor (check,BIGSHOTDAMAGE);\r
- else\r
- ShootActor (check,SHOTDAMAGE);\r
- }\r
- else\r
- if (check->obclass == solidobj && (check->flags & of_forcefield))\r
- {\r
- if (PlayMonsterSound(check->obclass))\r
- SD_PlaySound (SHOOTMONSTERSND);\r
- if (ob->obclass == bigpshotobj)\r
- ShootActor (check,BIGSHOTDAMAGE);\r
- else\r
- ShootActor (check,SHOTDAMAGE);\r
- }\r
- ob->state = &s_pshot_exp1;\r
- ob->ticcount = ob->state->tictime;\r
- return(true);\r
- }\r
-\r
- return(false); // move is OK!\r
-\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= T_Pshot\r
-=\r
-===============\r
-*/\r
-#if 0\r
-void T_Pshot (objtype *ob)\r
-{\r
- objtype *check;\r
- long xmove,ymove,speed;\r
-\r
-//\r
-// check current position for monsters having moved into it\r
-//\r
- for (check = player->next; check; check=check->next)\r
- if ((check->flags & of_shootable)\r
- && ob->xl <= check->xh\r
- && ob->xh >= check->xl\r
- && ob->yl <= check->yh\r
- && ob->yh >= check->yl)\r
- {\r
-\r
- if (check->obclass != solidobj)\r
- {\r
- if (PlayMonsterSound(check->obclass))\r
- SD_PlaySound (SHOOTMONSTERSND);\r
- if (ob->obclass == bigpshotobj)\r
- ShootActor (check,BIGSHOTDAMAGE);\r
- else\r
- ShootActor (check,SHOTDAMAGE);\r
- }\r
-\r
- ob->state = &s_pshot_exp1;\r
- ob->ticcount = ob->state->tictime;\r
- return;\r
- }\r
-\r
-\r
-//\r
-// move ahead, possibly hitting a wall\r
-//\r
- speed = ob->speed*tics;\r
-\r
- xmove = FixedByFrac(speed,costable[ob->angle]);\r
- ymove = -FixedByFrac(speed,sintable[ob->angle]);\r
-\r
- if (ShotClipMove(ob,xmove,ymove))\r
- {\r
- ob->state = &s_pshot_exp1;\r
- ob->ticcount = ob->state->tictime;\r
- return;\r
- }\r
-\r
- ob->tilex = ob->x >> TILESHIFT;\r
- ob->tiley = ob->y >> TILESHIFT;\r
-\r
-//\r
-// check final position for monsters hit\r
-//\r
- for (check = player->next; check; check=check->next)\r
- if ((ob->flags & of_shootable)\r
- && ob->xl <= check->xh\r
- && ob->xh >= check->xl\r
- && ob->yl <= check->yh\r
- && ob->yh >= check->yl)\r
- {\r
- ShootActor (check,SHOTDAMAGE);\r
- ob->state = &s_pshot_exp1;\r
- ob->ticcount = ob->state->tictime;\r
- return;\r
- }\r
-}\r
-#endif\r
-\r
-\r
-\r
-void T_Pshot (objtype *ob)\r
-{\r
- objtype *check;\r
- long xmove,ymove,speed;\r
- int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;\r
- long intersect,basex,basey,pointx,pointy;\r
- unsigned inside,total,tile;\r
- boolean moveok;\r
-\r
-//\r
-// check current position for monsters having moved into it\r
-//\r
- for (check = player->next; check; check=check->next)\r
- if ((check->flags & of_shootable)\r
- && ob->xl <= check->xh\r
- && ob->xh >= check->xl\r
- && ob->yl <= check->yh\r
- && ob->yh >= check->yl)\r
- {\r
-\r
- if (check->obclass != solidobj)\r
- {\r
- if (PlayMonsterSound(check->obclass))\r
- SD_PlaySound (SHOOTMONSTERSND);\r
- if (ob->obclass == bigpshotobj)\r
- ShootActor (check,BIGSHOTDAMAGE);\r
- else\r
- ShootActor (check,SHOTDAMAGE);\r
- }\r
-\r
- ob->state = &s_pshot_exp1;\r
- ob->obclass = expobj;\r
- ob->ticcount = ob->state->tictime;\r
- return;\r
- }\r
-\r
-\r
-//\r
-// move ahead, possibly hitting a wall\r
-//\r
- speed = ob->speed*tics;\r
-\r
- xmove = FixedByFrac(speed,costable[ob->angle]);\r
- ymove = -FixedByFrac(speed,sintable[ob->angle]);\r
-\r
- if (ShotClipMove(ob,xmove,ymove))\r
- {\r
- ob->state = &s_pshot_exp1;\r
- ob->obclass = expobj;\r
- ob->ticcount = ob->state->tictime;\r
- return;\r
- }\r
-\r
- ob->tilex = ob->x >> TILESHIFT;\r
- ob->tiley = ob->y >> TILESHIFT;\r
-\r
-//\r
-// check final position for monsters hit\r
-//\r
-\r
- JimsShotClipMove(obj,xmove,ymove);\r
-\r
-}\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
- PLAYER ACTIONS\r
-\r
-=============================================================================\r
-*/\r
-\r
-/*\r
-===============\r
-=\r
-= BuildShotPower\r
-=\r
-===============\r
-*/\r
-\r
-void BuildShotPower (void)\r
-{\r
- int newlines,topline;\r
- long i;\r
- unsigned source,dest;\r
-\r
- if (gamestate.shotpower == MAXSHOTPOWER)\r
- return;\r
-\r
- newlines = 0;\r
- for (i=lasttimecount-realtics;i<lasttimecount;i++)\r
- newlines += (i&1);\r
-\r
- gamestate.shotpower += newlines;\r
-\r
- if (gamestate.shotpower > MAXSHOTPOWER)\r
- {\r
- newlines -= (gamestate.shotpower - MAXSHOTPOWER);\r
- gamestate.shotpower = MAXSHOTPOWER;\r
- }\r
-}\r
-\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= ClearShotPower\r
-=\r
-===============\r
-*/\r
-\r
-void ClearShotPower (void)\r
-{\r
- unsigned source,dest,topline;\r
-\r
-#if 0\r
- topline = MAXSHOTPOWER - gamestate.shotpower;\r
-\r
- source = latchpics[L_NOSHOT]+topline*SIDEBARWIDTH;\r
- dest = (POWERLINE+topline)*SCREENWIDTH+34;\r
-\r
- asm mov es,[screenseg]\r
- asm mov si,[source]\r
- asm mov di,[dest]\r
-\r
- if (!gamestate.shotpower)\r
- return;\r
-\r
- EGAWRITEMODE(1);\r
-\r
- asm mov cx,[WORD PTR gamestate.shotpower]\r
-newline:\r
- asm mov al,[es:si]\r
- asm mov [es:di+PAGE1START],al\r
- asm mov [es:di+PAGE2START],al\r
- asm mov [es:di+PAGE3START],al\r
- asm mov al,[es:si+1]\r
- asm mov [es:di+1+PAGE1START],al\r
- asm mov [es:di+1+PAGE2START],al\r
- asm mov [es:di+1+PAGE3START],al\r
- asm mov al,[es:si+2]\r
- asm mov [es:di+2+PAGE1START],al\r
- asm mov [es:di+2+PAGE2START],al\r
- asm mov [es:di+2+PAGE3START],al\r
- asm mov al,[es:si+3]\r
- asm mov [es:di+3+PAGE1START],al\r
- asm mov [es:di+3+PAGE2START],al\r
- asm mov [es:di+3+PAGE3START],al\r
- asm mov al,[es:si+4]\r
- asm mov [es:di+4+PAGE1START],al\r
- asm mov [es:di+4+PAGE2START],al\r
- asm mov [es:di+4+PAGE3START],al\r
-\r
- asm add di,SCREENWIDTH\r
- asm add si,5\r
-\r
- asm loop newline\r
-\r
- EGAWRITEMODE(0);\r
-#endif\r
-\r
- gamestate.shotpower = 0;\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= Shoot\r
-=\r
-===============\r
-*/\r
-\r
-void Shoot (void)\r
-{\r
- ClearShotPower ();\r
- SD_PlaySound (SHOOTSND);\r
- SpawnPShot ();\r
-}\r
-\r
-//===========================================================================\r
-\r
-#if 0\r
-/*\r
-===============\r
-=\r
-= BigShoot\r
-=\r
-===============\r
-*/\r
-\r
-void BigShoot (void)\r
-{\r
- ClearShotPower ();\r
- SD_PlaySound (BIGSHOOTSND);\r
- SpawnBigPShot ();\r
-}\r
-#endif\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= CastBolt\r
-=\r
-===============\r
-*/\r
-\r
-void CastBolt (void)\r
-{\r
- if (!gamestate.bolts)\r
- {\r
- SD_PlaySound (NOITEMSND);\r
- return;\r
- }\r
-\r
- TakeBolt ();\r
- boltsleft = NUMBOLTS;\r
- bolttimer = BOLTTICS;\r
- Shoot ();\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= ContinueBolt\r
-=\r
-===============\r
-*/\r
-\r
-void ContinueBolt (void)\r
-{\r
- bolttimer-=realtics;\r
- if (bolttimer<0)\r
- {\r
- boltsleft--;\r
- bolttimer = BOLTTICS;\r
- Shoot ();\r
- }\r
-}\r
-\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= CastNuke\r
-=\r
-===============\r
-*/\r
-\r
-void CastNuke (void)\r
-{\r
-// extern boolean autofire;\r
-\r
- int angle;\r
-\r
- if (!gamestate.nukes)\r
- {\r
- SD_PlaySound (NOITEMSND);\r
- return;\r
- }\r
-\r
-// if (!autofire)\r
- TakeNuke ();\r
- lastnuke = TimeCount;\r
-\r
- for (angle = 0; angle < ANGLES; angle+= ANGLES/16)\r
- {\r
- DSpawnNewObjFrac (player->x,player->y,&s_pshot1,24*PIXRADIUS);\r
- new->obclass = bigpshotobj;\r
- new->speed = SHOTSPEED;\r
- new->angle = angle;\r
- new->active = always;\r
- }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= DrinkPotion\r
-=\r
-===============\r
-*/\r
-\r
-void DrinkPotion (void)\r
-{\r
- unsigned source,dest,topline;\r
-\r
- if (!gamestate.potions)\r
- {\r
- SD_PlaySound (NOITEMSND);\r
- return;\r
- }\r
-\r
- DisplaySMsg("Curing", NULL);\r
- TakePotion ();\r
- gamestate.body = MAXBODY;\r
- VW_WaitVBL(30);\r
- status_flag = S_NONE;\r
-\r
-#if 0\r
-//\r
-// draw a full up bar\r
-//\r
- source = latchpics[L_BODYBAR];\r
- dest = BODYLINE*SCREENWIDTH+34;\r
-\r
- asm mov es,[screenseg]\r
- asm mov si,[source]\r
- asm mov di,[dest]\r
-\r
- EGAWRITEMODE(1);\r
-\r
- asm mov cx,MAXBODY\r
-newline:\r
- asm mov al,[es:si]\r
- asm mov [es:di+PAGE1START],al\r
- asm mov [es:di+PAGE2START],al\r
- asm mov [es:di+PAGE3START],al\r
- asm mov al,[es:si+1]\r
- asm mov [es:di+1+PAGE1START],al\r
- asm mov [es:di+1+PAGE2START],al\r
- asm mov [es:di+1+PAGE3START],al\r
- asm mov al,[es:si+2]\r
- asm mov [es:di+2+PAGE1START],al\r
- asm mov [es:di+2+PAGE2START],al\r
- asm mov [es:di+2+PAGE3START],al\r
- asm mov al,[es:si+3]\r
- asm mov [es:di+3+PAGE1START],al\r
- asm mov [es:di+3+PAGE2START],al\r
- asm mov [es:di+3+PAGE3START],al\r
- asm mov al,[es:si+4]\r
- asm mov [es:di+4+PAGE1START],al\r
- asm mov [es:di+4+PAGE2START],al\r
- asm mov [es:di+4+PAGE3START],al\r
- asm add di,SCREENWIDTH\r
- asm add si,5\r
-\r
- asm loop newline\r
-\r
- EGAWRITEMODE(0);\r
-#endif\r
-}\r
-\r
-\r
-\r
-//===========================================================================\r
-\r
-#if 0\r
-\r
-////////////////////////////////////////////////////////////////////////////\r
-//\r
-// GetScrollText\r
-//\r
-// parms - scroll -- the number of the scroll to display\r
-// returns - a far pointer to the scroll text\r
-//\r
-////////////////////////////////////////////////////////////////////////////\r
-\r
-char far *GetScrollText (int scroll)\r
-{\r
- boolean found;\r
- int i;\r
- char far *txt;\r
- unsigned ofset;\r
-\r
- CA_CacheGrChunk(SCROLLTEXT);\r
-\r
- found = false;\r
- i = 0;\r
-\r
- txt = (char _seg *)grsegs[SCROLLTEXT];\r
-\r
- while (!found)\r
- {\r
- while (*txt != '\n')\r
- {\r
- if (*txt == '\r')\r
- *txt = 0;\r
- txt++;\r
- }\r
- txt++;\r
- if (i == scroll)\r
- {\r
- found = true;\r
- ofset = FP_OFF(txt);\r
-\r
- while (*txt != '\n')\r
- {\r
- if (*txt == '\r')\r
- *txt = 0;\r
- txt++;\r
- }\r
- }\r
- i++;\r
- }\r
- txt = (char _seg *)grsegs[SCROLLTEXT]+ofset;\r
-\r
- UNMARKGRCHUNK(SCROLLTEXT);\r
- return(txt);\r
-} //End of GetScrollText\r
-\r
-//===========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= ReadScroll\r
-=\r
-===============\r
-*/\r
-\r
-extern boolean tileneeded[NUMFLOORS];\r
-\r
-void ReadScroll (int scroll)\r
-{\r
- PresenterInfo pi;\r
- int i;\r
- unsigned *skytemp,*gndtemp,blackcolor=0;\r
- char far *scrolltext;\r
-\r
- DisplaySMsg("Reading Scroll", NULL);\r
- bufferofs = displayofs = screenloc[screenpage];\r
-\r
- if (status_flag != S_TIMESTOP)\r
- status_flag = S_NONE;\r
-\r
- FreeUpMemory();\r
-\r
- CA_CacheGrChunk (SCROLLTOPPIC);\r
- CA_CacheGrChunk (SCROLL1PIC);\r
- CA_CacheGrChunk (SCROLLBOTTOMPIC);\r
-\r
- skytemp = skycolor;\r
- gndtemp = groundcolor;\r
- skycolor = groundcolor = &blackcolor;\r
-\r
- VW_Bar(0,0,VIEWWIDTH,VIEWHEIGHT,0);\r
- VW_DrawPic (10,0,SCROLLTOPPIC);\r
- VW_DrawPic (10,32,SCROLL1PIC);\r
- VW_DrawPic (10,88,SCROLLBOTTOMPIC);\r
-\r
- scrolltext = GetScrollText(scroll);\r
-\r
- pi.xl = LEFTEDGE;\r
- pi.yl = PRNY;\r
- pi.xh = RIGHTEDGE;\r
- pi.yh = PRNY+1;\r
- pi.bgcolor = 7;\r
- pi.script[0] = (char far *)scrolltext;\r
- Presenter(&pi);\r
-\r
- skycolor = skytemp;\r
- groundcolor = gndtemp;\r
-\r
- UNMARKGRCHUNK(SCROLL1PIC);\r
- UNMARKGRCHUNK(SCROLLTOPPIC);\r
- UNMARKGRCHUNK(SCROLLBOTTOMPIC);\r
- MM_FreePtr (&grsegs[SCROLL1PIC]);\r
- MM_FreePtr (&grsegs[SCROLLTOPPIC]);\r
- MM_FreePtr (&grsegs[SCROLLBOTTOMPIC]);\r
-\r
- CacheScaleds();\r
-\r
- IN_ClearKeysDown ();\r
- lasttext = -1;\r
- DisplayMsg("Press ENTER or ESC to exit.",NULL);\r
- while ((!Keyboard[sc_Escape]) && (!Keyboard[sc_Enter]));\r
- IN_ClearKeysDown ();\r
-\r
- if (status_flag == S_TIMESTOP)\r
- DisplaySMsg("Time Stopped: ",NULL);\r
-}\r
-\r
-#endif\r
-\r
-\r
-//===============\r
-//\r
-// StopTime()\r
-//\r
-//\r
-//===============\r
-void StopTime()\r
-{\r
- FreezeTime = MAXFREEZETIME;\r
- SD_PlaySound(FREEZETIMESND);\r
- DisplaySMsg("Time Stopped: ",NULL);\r
- status_flag = S_TIMESTOP;\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= TakeDamage\r
-=\r
-===============\r
-*/\r
-\r
-void TakeDamage (int points)\r
-{\r
- unsigned source,dest,topline;\r
-\r
- if (!gamestate.body || (bordertime && bcolor==FLASHCOLOR) || godmode)\r
- return;\r
-\r
- points = EasyDoDamage(points);\r
-\r
- if (points >= gamestate.body)\r
- {\r
- points = gamestate.body;\r
- Flags |= FL_DEAD;\r
- }\r
-\r
- bordertime = FLASHTICS<<2;\r
- bcolor = FLASHCOLOR;\r
- VW_ColorBorder (FLASHCOLOR);\r
-\r
- DisplaySMsg("Damaging blows!", NULL);\r
- status_flag = S_NONE;\r
- status_delay = 80;\r
-\r
- if (gamestate.body<MAXBODY/3)\r
- SD_PlaySound (TAKEDMGHURTSND);\r
- else\r
- SD_PlaySound (TAKEDAMAGESND);\r
-\r
- gamestate.body -= points;\r
-}\r
-\r
-/*\r
-=============================================================================\r
-\r
- INTERACTION\r
-\r
-=============================================================================\r
-*/\r
-\r
-\r
-#if 0\r
-/*\r
-==================\r
-=\r
-= OpenDoor\r
-=\r
-==================\r
-*/\r
-\r
-void OpenDoor (unsigned bx, unsigned by, unsigned doorbase)\r
-{\r
- int x,y;\r
- unsigned far *map;\r
-\r
- x=bx;\r
- y=by;\r
- map = mapsegs[0]+farmapylookup[y]+x;\r
- while (tilemap[x][y]-doorbase<4)\r
- {\r
- tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;\r
- map--;\r
- x--;\r
- }\r
- x=bx+1;\r
- map = mapsegs[0]+farmapylookup[y]+x;\r
- while (tilemap[x][y]-doorbase<4)\r
- {\r
- tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;\r
- map++;\r
- x++;\r
- }\r
- x=bx;\r
- y=by-1;\r
- map = mapsegs[0]+farmapylookup[y]+x;\r
- while (tilemap[x][y]-doorbase<4)\r
- {\r
- tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;\r
- map-=mapwidth;\r
- y--;\r
- }\r
- y=by+1;\r
- map = mapsegs[0]+farmapylookup[y]+x;\r
- while (tilemap[x][y]-doorbase<4)\r
- {\r
- tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;\r
- map+=mapwidth;\r
- y++;\r
- }\r
-}\r
-#endif\r
-\r
-#if 0\r
-/*\r
-==================\r
-=\r
-= RemoveWalls - similar to OpenDoor(), but on a different plane\r
-=\r
-==================\r
-*/\r
-void RemoveWalls (unsigned bx, unsigned by, unsigned remove_code)\r
-{\r
- int x,y;\r
- unsigned far *map,*p2;\r
-\r
- x=bx;\r
- y=by;\r
- p2 = *(mapsegs[2]+farmapylookup[y]+x);\r
- map = mapsegs[0]+farmapylookup[y]+x;\r
- while (*p2 == remove_code)\r
- {\r
- tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;\r
- map--;\r
- p2--;\r
- x--;\r
- }\r
- x=bx+1;\r
- p2 = *(mapsegs[2]+farmapylookup[y]+x);\r
- map = mapsegs[0]+farmapylookup[y]+x;\r
- while (*p2 == remove_code)\r
- {\r
- tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;\r
- map++;\r
- p2++;\r
- x++;\r
- }\r
- x=bx;\r
- y=by-1;\r
- p2 = *(mapsegs[2]+farmapylookup[y]+x);\r
- map = mapsegs[0]+farmapylookup[y]+x;\r
- while (*p2 == remove_code)\r
- {\r
- tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;\r
- map-=mapwidth;\r
- p2 -= mapwidth;\r
- y--;\r
- }\r
- y=by+1;\r
- p2 = *(mapsegs[2]+farmapylookup[y]+x);\r
- map = mapsegs[0]+farmapylookup[y]+x;\r
- while (*p2 == remove_code)\r
- {\r
- tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;\r
- map+=mapwidth;\r
- p2 += mapwidth;\r
- y++;\r
- }\r
-}\r
-#endif\r
-\r
-/*\r
-==================\r
-=\r
-= HitSpecialTile\r
-=\r
-= Returns true if the move is blocked\r
-=\r
-==================\r
-*/\r
-\r
-boolean HitSpecialTile (unsigned x, unsigned y, unsigned tile)\r
-{\r
- objtype *check;\r
- short keyspot;\r
- unsigned temp,spot,curmap=gamestate.mapon,newlevel;\r
- char *key_colors[] = {"a RED key",\r
- "a YELLOW key",\r
- "a GREEN key",\r
- "a BLUE key"};\r
-\r
- switch (tile)\r
- {\r
- case 44:\r
- playstate = ex_victorious;\r
- break;\r
-\r
- case 17:\r
- case 30:\r
- case 31:\r
- case 35:\r
- case 46:\r
- case 47:\r
- case 48:\r
- case 49:\r
- case 57:\r
- case 58:\r
- case 71:\r
- case 85:\r
- case 94:\r
-\r
- if (!playstate && !FreezeTime)\r
- {\r
-\r
- // Is this an openable door? (Is "openable" a word?)\r
- //\r
- spot = (*(mapsegs[2]+farmapylookup[y]+x)) >> 8;\r
- if (spot == CANT_OPEN_CODE) // CAN'T EVER OPEN (it's just for looks)\r
- {\r
- CenterWindow(30,4);\r
- US_CPrint("\nThis door is permanently blocked");\r
- VW_UpdateScreen();\r
- IN_ClearKeysDown();\r
- IN_Ack();\r
- return;\r
- }\r
-\r
- // make sure player has key to get into door\r
- //\r
-\r
- if (TILE_FLAGS(tile) & tf_EMBEDDED_KEY_COLOR)\r
- keyspot = GATE_KEY_COLOR(tile);\r
- else\r
- keyspot = (*(mapsegs[2]+farmapylookup[y+1]+x)) >> 8;\r
-\r
- if (keyspot--)\r
- if (!gamestate.keys[keyspot])\r
- {\r
- SD_PlaySound(HIT_GATESND);\r
- CenterWindow(20,5);\r
- US_CPrint("\nYou need\n");\r
- US_CPrint(key_colors[keyspot]);\r
- VW_UpdateScreen();\r
- IN_ClearKeysDown();\r
- IN_Ack();\r
- return;\r
- }\r
-\r
- //\r
- // deal with this gate (warp? simply open? whatever...)\r
- //\r
- switch (spot)\r
- {\r
- case NEXT_LEVEL_CODE: // WARP TO NEXT LEVEL\r
- newlevel = gamestate.mapon+1;\r
- playstate = ex_warped;\r
- break;\r
-\r
- case REMOVE_DOOR_CODE: // REMOVE DOOR\r
- (unsigned)actorat[x][y] = tilemap[x][y] = *(mapsegs[0]+farmapylookup[y]+x) = 0;\r
- *(mapsegs[2]+farmapylookup[y+1]+x) = 0; // key no longer needed\r
- if (keyspot>=0)\r
- TakeKey(keyspot);\r
- break;\r
-\r
- default: // WARP TO A LEVEL\r
- newlevel = spot;\r
- playstate = ex_warped;\r
- break;\r
- }\r
-\r
- if (playstate == ex_warped)\r
- {\r
- SD_PlaySound(HIT_GATESND);\r
-// levelinfo *li=&gamestate.levels[curmap];\r
-\r
-// OldAngle = FaceDoor(x,y);\r
-\r
- if (!VerifyGateExit())\r
- {\r
- IN_ClearKeysDown ();\r
- playstate = ex_stillplaying;\r
- break;\r
- }\r
-\r
-// FaceAngle(OldAngle);\r
-\r
- if (keyspot>=0)\r
- TakeKey(keyspot);\r
- *(mapsegs[2]+farmapylookup[y+1]+x) = 0; // key no longer needed\r
-\r
- gamestate.mapon = newlevel;\r
- SD_PlaySound(WARPUPSND);\r
- IN_ClearKeysDown ();\r
-\r
-// li->x = player->tilex;\r
-// li->y = player->tiley;\r
-// li->angle = player->angle+180;\r
-// if (li->angle > 360)\r
-// li->angle -= 360;\r
- }\r
- }\r
- break;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-//-------------------------------------------------------------------------\r
-// VerifyGateExit()\r
-//-------------------------------------------------------------------------\r
-boolean VerifyGateExit()\r
-{\r
- char choices[] = {sc_Escape,sc_Y,sc_N,0},ch;\r
-\r
- ch=DisplayMsg("Pass this way? Y/N",choices);\r
- DrawText(true);\r
-\r
- return(ch == sc_Y);\r
-}\r
-\r
-\r
-/*\r
-==================\r
-=\r
-= TouchActor\r
-=\r
-= Returns true if the move is blocked\r
-=\r
-==================\r
-*/\r
-\r
-boolean TouchActor (objtype *ob, objtype *check)\r
-{\r
- if (ob->xh < check->xl || ob->xl > check->xh ||\r
- ob->yh < check->yl || ob->yl > check->yh)\r
- return false; // not quite touching\r
-\r
- switch (check->obclass)\r
- {\r
- case bonusobj:\r
- switch (check->temp1)\r
- {\r
- case B_BOLT: GiveBolt (); break;\r
-\r
- case B_NUKE: GiveNuke (); break;\r
-\r
- case B_POTION: GivePotion (); break;\r
-\r
-// case B_RKEY2: GiveKey(B_RKEY-B_RKEY); break;\r
-\r
- case B_RKEY:\r
- case B_YKEY:\r
- case B_GKEY:\r
- case B_BKEY: GiveKey (check->temp1-B_RKEY); break;\r
-\r
-#if 0\r
- case B_SCROLL1:\r
- case B_SCROLL2:\r
- case B_SCROLL3:\r
- case B_SCROLL4:\r
- case B_SCROLL5:\r
- case B_SCROLL6:\r
- case B_SCROLL7:\r
- case B_SCROLL8: GiveScroll (check->temp1-B_SCROLL1,true); break;\r
-#endif\r
-\r
- case B_OLDCHEST:\r
- case B_CHEST: GiveChest (); break;\r
-\r
- case B_RGEM:\r
- case B_YGEM:\r
- case B_GGEM:\r
- case B_BGEM:\r
- case B_PGEM:\r
- SD_PlaySound(GETGEMSND);\r
- gamestate.gems[check->temp1-B_RGEM] = GEM_DELAY_TIME;\r
- redraw_gems = true;\r
- break;\r
-\r
- default:\r
- Quit("TouchActor(): INVALID BONUS");\r
- break;\r
- }\r
-\r
- (unsigned)actorat[check->tilex][check->tiley] = 0;\r
- RemoveObj (check);\r
-\r
- return false;\r
-\r
- case freezeobj:\r
- StopTime();\r
- (unsigned)actorat[check->tilex][check->tiley] = 0;\r
- RemoveObj(check);\r
- return(false);\r
- }\r
-\r
- return true;\r
-}\r
-\r
-\r
-/*\r
-==================\r
-=\r
-= CalcBounds\r
-=\r
-==================\r
-*/\r
-\r
-void CalcBounds (objtype *ob)\r
-{\r
-//\r
-// calculate hit rect\r
-//\r
- ob->xl = ob->x - ob->size;\r
- ob->xh = ob->x + ob->size;\r
- ob->yl = ob->y - ob->size;\r
- ob->yh = ob->y + ob->size;\r
-}\r
-\r
-\r
-/*\r
-===================\r
-=\r
-= LocationInActor\r
-=\r
-===================\r
-*/\r
-\r
-boolean LocationInActor (objtype *ob)\r
-{\r
- int x,y,xmin,ymin,xmax,ymax;\r
- objtype *check;\r
-\r
- CalcBounds (ob);\r
-\r
- xmin = (ob->x >> TILESHIFT)-2;\r
- ymin = (ob->y >> TILESHIFT)-2;\r
- xmax = xmin+5;\r
- ymax = ymin+5;\r
-\r
- for (x=xmin;x<xmax;x++)\r
- for (y=ymin;y<ymax;y++)\r
- {\r
- check = actorat[x][y];\r
- if (check>(objtype *)LASTTILE\r
- && (check->flags & of_shootable)\r
- && (check->obclass != bonusobj)\r
- && (check->obclass != freezeobj)\r
- && (check->obclass != solidobj)\r
- && ob->xl-SIZE_TEST <= check->xh\r
- && ob->xh+SIZE_TEST >= check->xl\r
- && ob->yl-SIZE_TEST <= check->yh\r
- && ob->yh+SIZE_TEST >= check->yl)\r
- return true;\r
- }\r
-\r
- return false;\r
-}\r
-\r
-/*\r
-===================\r
-=\r
-= ClipXMove\r
-=\r
-= Only checks corners, so the object better be less than one tile wide!\r
-=\r
-===================\r
-*/\r
-void ClipXMove (objtype *ob, long xmove)\r
-{\r
- int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;\r
- long intersect,basex,basey,pointx,pointy;\r
- unsigned inside,total,tile;\r
- objtype *check;\r
- boolean moveok;\r
- boolean invisible_present = false;\r
-\r
-//\r
-// move player and check to see if any corners are in solid tiles\r
-//\r
- basex = ob->x;\r
- basey = ob->y;\r
-\r
- ob->x += xmove;\r
-\r
- CalcBounds (ob);\r
-\r
- xl = ob->xl>>TILESHIFT;\r
- yl = ob->yl>>TILESHIFT;\r
-\r
- xh = ob->xh>>TILESHIFT;\r
- yh = ob->yh>>TILESHIFT;\r
-\r
- for (y=yl;y<=yh;y++)\r
- for (x=xl;x<=xh;x++)\r
- {\r
- check = actorat[x][y];\r
-\r
- if (!check)\r
- continue; // blank floor, walk ok\r
-\r
- if ((unsigned)check <= LASTTILE)\r
- {\r
- if (TILE_FLAGS((unsigned)check) & tf_SPECIAL)\r
- {\r
- HitSpecialTile(x,y,(unsigned)check-SPECTILESTART);\r
- goto blockmove;\r
- }\r
-\r
- if (TILE_FLAGS((unsigned)check) & tf_INVISIBLE_WALL)\r
- {\r
- invisible_present = true;\r
- goto blockmove;\r
- }\r
-\r
-\r
- if (TILE_FLAGS((unsigned)check) & tf_SOLID)\r
- {\r
- goto blockmove; // solid wall\r
- }\r
- }\r
-\r
- TouchActor(ob,check); // pick up items\r
- }\r
-\r
-//\r
-// check nearby actors\r
-//\r
- if (LocationInActor(ob))\r
- {\r
- ob->x -= xmove;\r
- if (LocationInActor(ob))\r
- {\r
- ob->x += xmove;\r
- if (LocationInActor(ob))\r
- ob->x -= xmove;\r
- }\r
- }\r
- return; // move is OK!\r
-\r
-\r
-blockmove:\r
-\r
-// if (!SD_SoundPlaying())\r
-// SD_PlaySound (HITWALLSND);\r
-\r
- moveok = false;\r
-\r
- do\r
- {\r
- xmove /= 2;\r
- if (moveok)\r
- {\r
- ob->x += xmove;\r
- }\r
- else\r
- {\r
- ob->x -= xmove;\r
- }\r
- CalcBounds (ob);\r
- xl = ob->xl>>TILESHIFT;\r
- yl = ob->yl>>TILESHIFT;\r
- xh = ob->xh>>TILESHIFT;\r
- yh = ob->yh>>TILESHIFT;\r
- if (tilemap[xl][yl] || tilemap[xh][yl]\r
- || tilemap[xh][yh] || tilemap[xl][yh] )\r
- {\r
- moveok = false;\r
- if (xmove>=-2048 && xmove <=2048)\r
- {\r
- ob->x = basex;\r
- ob->y = basey;\r
- return;\r
- }\r
- }\r
- else\r
- if (invisible_present)\r
- {\r
- moveok = false;\r
- if (xmove>=-2048 && xmove <=2048)\r
- {\r
- ob->x = basex;\r
- ob->y = basey;\r
- return;\r
- }\r
- }\r
- else\r
- if (xmove>=-2048 && xmove <=2048)\r
- return;\r
- moveok = true;\r
- } while (1);\r
-}\r
-\r
-\r
-/*\r
-===================\r
-=\r
-= ClipYMove\r
-=\r
-= Only checks corners, so the object better be less than one tile wide!\r
-=\r
-===================\r
-*/\r
-void ClipYMove (objtype *ob, long ymove)\r
-{\r
- int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;\r
- long intersect,basex,basey,pointx,pointy;\r
- unsigned inside,total,tile;\r
- objtype *check;\r
- boolean moveok;\r
- boolean invisible_present = false;\r
-\r
-//\r
-// move player and check to see if any corners are in solid tiles\r
-//\r
- basex = ob->x;\r
- basey = ob->y;\r
-\r
- ob->y += ymove;\r
-\r
- CalcBounds (ob);\r
-\r
- xl = ob->xl>>TILESHIFT;\r
- yl = ob->yl>>TILESHIFT;\r
-\r
- xh = ob->xh>>TILESHIFT;\r
- yh = ob->yh>>TILESHIFT;\r
-\r
- for (y=yl;y<=yh;y++)\r
- for (x=xl;x<=xh;x++)\r
- {\r
- check = actorat[x][y];\r
- if (!check)\r
- continue; // blank floor, walk ok\r
-\r
- if ((unsigned)check <= LASTTILE)\r
- {\r
- if (TILE_FLAGS((unsigned)check) & tf_SPECIAL) // <=LASTSPECIALTILE)\r
- {\r
- HitSpecialTile (x,y,(unsigned)check-SPECTILESTART);\r
- goto blockmove;\r
- }\r
-\r
- if (TILE_FLAGS((unsigned)check) & tf_INVISIBLE_WALL)\r
- {\r
- invisible_present = true;\r
- goto blockmove;\r
- }\r
-\r
-\r
- if (TILE_FLAGS((unsigned)check) & tf_SOLID) // LASTWALLTILE)\r
- {\r
- goto blockmove; // solid wall\r
- }\r
- }\r
-\r
- TouchActor(ob,check); // pick up items\r
- }\r
-\r
-//\r
-// check nearby actors\r
-//\r
- if (LocationInActor(ob))\r
- {\r
- if (LocationInActor(ob))\r
- {\r
- ob->y -= ymove;\r
- }\r
- }\r
- return; // move is OK!\r
-\r
-\r
-blockmove:\r
-\r
-// if (!SD_SoundPlaying())\r
-// SD_PlaySound (HITWALLSND);\r
-\r
- moveok = false;\r
-\r
- do\r
- {\r
- ymove /= 2;\r
- if (moveok)\r
- {\r
- ob->y += ymove;\r
- }\r
- else\r
- {\r
- ob->y -= ymove;\r
- }\r
- CalcBounds (ob);\r
- xl = ob->xl>>TILESHIFT;\r
- yl = ob->yl>>TILESHIFT;\r
- xh = ob->xh>>TILESHIFT;\r
- yh = ob->yh>>TILESHIFT;\r
- if (tilemap[xl][yl] || tilemap[xh][yl]\r
- || tilemap[xh][yh] || tilemap[xl][yh] )\r
- {\r
- moveok = false;\r
- if (ymove>=-2048 && ymove <=2048)\r
- {\r
- ob->x = basex;\r
- ob->y = basey;\r
- return;\r
- }\r
- }\r
- else\r
- if (invisible_present)\r
- {\r
- moveok = false;\r
- if (ymove>=-2048 && ymove <=2048)\r
- {\r
- ob->x = basex;\r
- ob->y = basey;\r
- return;\r
- }\r
- }\r
- else\r
- if (ymove>=-2048 && ymove <=2048)\r
- return;\r
- moveok = true;\r
- } while (1);\r
-}\r
-\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-===================\r
-=\r
-= ShotClipMove\r
-=\r
-= Only checks corners, so the object better be less than one tile wide!\r
-=\r
-===================\r
-*/\r
-\r
-boolean ShotClipMove (objtype *ob, long xmove, long ymove)\r
-{\r
- int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;\r
- long intersect,basex,basey,pointx,pointy;\r
- unsigned inside,total,spot,tile;\r
- objtype *check;\r
- boolean moveok;\r
-\r
-//\r
-// move shot and check to see if any corners are in solid tiles\r
-//\r
- basex = ob->x;\r
- basey = ob->y;\r
-\r
- ob->x += xmove;\r
- ob->y += ymove;\r
-\r
- CalcBounds (ob);\r
-\r
- xl = ob->xl>>TILESHIFT;\r
- yl = ob->yl>>TILESHIFT;\r
-\r
- xh = ob->xh>>TILESHIFT;\r
- yh = ob->yh>>TILESHIFT;\r
-\r
- for (y=yl;y<=yh;y++)\r
- for (x=xl;x<=xh;x++)\r
- {\r
- spot = (*(mapsegs[2]+farmapylookup[y]+x)) >> 8;\r
- if (spot == EXP_WALL_CODE)\r
- switch (ob->obclass)\r
- {\r
- case pshotobj:\r
- case bigpshotobj:\r
- ExplodeWall (x,y);\r
- goto blockmove;\r
-// break;\r
- }\r
-\r
- tile = *(mapsegs[0]+farmapylookup[y]+x);\r
- if (TILE_FLAGS(tile) & tf_SOLID)\r
- goto blockmove;\r
- }\r
- return false; // move is OK!\r
-\r
-\r
-blockmove:\r
-\r
- if (ob->obclass == pshotobj)\r
- SD_PlaySound (SHOOTWALLSND);\r
-\r
- moveok = false;\r
-\r
- do\r
- {\r
- xmove /= 2;\r
- ymove /= 2;\r
- if (moveok)\r
- {\r
- ob->x += xmove;\r
- ob->y += ymove;\r
- }\r
- else\r
- {\r
- ob->x -= xmove;\r
- ob->y -= ymove;\r
- }\r
- CalcBounds (ob);\r
- xl = ob->xl>>TILESHIFT;\r
- yl = ob->yl>>TILESHIFT;\r
- xh = ob->xh>>TILESHIFT;\r
- yh = ob->yh>>TILESHIFT;\r
- if (tilemap[xl][yl] || tilemap[xh][yl]\r
- || tilemap[xh][yh] || tilemap[xl][yh] )\r
- {\r
- moveok = false;\r
- if (xmove>=-2048 && xmove <=2048 && ymove>=-2048 && ymove <=2048)\r
- {\r
- ob->x = basex;\r
- ob->y = basey;\r
- return true;\r
- }\r
- }\r
- else\r
- {\r
- if (xmove>=-2048 && xmove <=2048 && ymove>=-2048 && ymove <=2048)\r
- return true;\r
- moveok = true;\r
- }\r
- } while (1);\r
-}\r
-\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
- PLAYER CONTROL\r
-\r
-=============================================================================\r
-*/\r
-\r
-\r
-\r
-void T_Player (objtype *ob);\r
-\r
-statetype s_player = {0,0,&T_Player,&s_player};\r
-\r
-/*\r
-===============\r
-=\r
-= SpawnPlayer\r
-=\r
-===============\r
-*/\r
-\r
-void SpawnPlayer (int tilex, int tiley, int dir)\r
-{\r
-#if 0\r
- levelinfo *li=&gamestate.levels[gamestate.mapon];\r
-\r
- if (li->x != -1)\r
- {\r
- tilex = li->x;\r
- tiley = li->y;\r
- player->angle = li->angle;\r
- }\r
- else\r
- player->angle = (1-dir)*90;\r
-#endif\r
-\r
- player->obclass = playerobj;\r
- player->active = always;\r
- player->tilex = tilex;\r
- player->tiley = tiley;\r
- player->x = ((long)tilex<<TILESHIFT)+TILEGLOBAL/2;\r
- player->y = ((long)tiley<<TILESHIFT)+TILEGLOBAL/2;\r
- player->state = &s_player;\r
- player->size = MINDIST;\r
- CalcBounds(player);\r
- player->angle = (1-dir)*90;\r
- if (player->angle<0)\r
- player->angle += ANGLES;\r
-}\r
-\r
-\r
-/*\r
-===================\r
-=\r
-= Thrust\r
-=\r
-===================\r
-*/\r
-\r
-void Thrust (int angle, unsigned speed)\r
-{\r
- long xmove,ymove;\r
-\r
- if (lasttimecount>>5 != ((lasttimecount-tics)>>5) )\r
- {\r
- //\r
- // walk sound\r
- //\r
- if (lasttimecount&32)\r
- SD_PlaySound (WALK1SND);\r
- else\r
- SD_PlaySound (WALK2SND);\r
- }\r
-\r
- xmove = FixedByFrac(speed,costable[angle]);\r
- ymove = -FixedByFrac(speed,sintable[angle]);\r
-\r
- ClipXMove(player,xmove);\r
- ClipYMove(player,ymove);\r
- player->tilex = player->x >> TILESHIFT;\r
- player->tiley = player->y >> TILESHIFT;\r
-}\r
-\r
-\r
-\r
-/*\r
-=======================\r
-=\r
-= ControlMovement\r
-=\r
-=======================\r
-*/\r
-\r
-void ControlMovement (objtype *ob)\r
-{\r
- int angle;\r
- long speed;\r
-\r
-\r
- if (control.button1)\r
- {\r
- //\r
- // strafing\r
- //\r
- //\r
- // side to side move\r
- //\r
- if (!mousexmove)\r
- speed = 0;\r
- else if (mousexmove<0)\r
- speed = -(long)mousexmove*300;\r
- else\r
- speed = -(long)mousexmove*300;\r
-\r
- if (control.xaxis == -1)\r
- {\r
- speed += PLAYERSPEED*tics;\r
- }\r
- else if (control.xaxis == 1)\r
- {\r
- speed -= PLAYERSPEED*tics;\r
- }\r
-\r
- if (speed > 0)\r
- {\r
- if (speed >= TILEGLOBAL)\r
- speed = TILEGLOBAL-1;\r
- angle = ob->angle + ANGLES/4;\r
- if (angle >= ANGLES)\r
- angle -= ANGLES;\r
- Thrust (angle,speed); // move to left\r
- }\r
- else if (speed < 0)\r
- {\r
- if (speed <= -TILEGLOBAL)\r
- speed = -TILEGLOBAL+1;\r
- angle = ob->angle - ANGLES/4;\r
- if (angle < 0)\r
- angle += ANGLES;\r
- Thrust (angle,-speed); // move to right\r
- }\r
- }\r
- else\r
- {\r
- //\r
- // not strafing\r
- //\r
-\r
- //\r
- // turning\r
- //\r
- if (control.xaxis == 1)\r
- {\r
- ob->angle -= tics;\r
- if (running) // fast turn\r
- ob->angle -= (tics<<1);\r
- }\r
- else if (control.xaxis == -1)\r
- {\r
- ob->angle+= tics;\r
- if (running) // fast turn\r
- ob->angle += (tics<<1);\r
- }\r
-\r
- ob->angle -= (mousexmove/10);\r
-\r
- if (ob->angle >= ANGLES)\r
- ob->angle -= ANGLES;\r
- if (ob->angle < 0)\r
- ob->angle += ANGLES;\r
-\r
- }\r
-\r
- //\r
- // forward/backwards move\r
- //\r
- if (!mouseymove)\r
- speed = 0;\r
- else if (mouseymove<0)\r
- speed = -(long)mouseymove*500;\r
- else\r
- speed = -(long)mouseymove*200;\r
-\r
- if (control.yaxis == -1)\r
- {\r
- speed += PLAYERSPEED*tics;\r
- }\r
- else if (control.yaxis == 1)\r
- {\r
- speed -= PLAYERSPEED*tics;\r
- }\r
-\r
- if (speed > 0)\r
- {\r
- if (speed >= TILEGLOBAL)\r
- speed = TILEGLOBAL-1;\r
- Thrust (ob->angle,speed); // move forwards\r
- }\r
- else if (speed < 0)\r
- {\r
- if (speed <= -TILEGLOBAL)\r
- speed = -TILEGLOBAL+1;\r
- angle = ob->angle + ANGLES/2;\r
- if (angle >= ANGLES)\r
- angle -= ANGLES;\r
- Thrust (angle,-speed); // move backwards\r
- }\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= T_Player\r
-=\r
-===============\r
-*/\r
-\r
-void T_Player (objtype *ob)\r
-{\r
-// extern boolean autofire;\r
-\r
- int angle,speed,scroll,loop;\r
- unsigned text,tilex,tiley;\r
- long lspeed;\r
-\r
-// boolean radar_moved=false;\r
-\r
-\r
- ControlMovement (ob);\r
-\r
-\r
- //\r
- // firing\r
- //\r
- if (boltsleft)\r
- {\r
- handheight+=(realtics<<2);\r
- if (handheight>MAXHANDHEIGHT)\r
- handheight = MAXHANDHEIGHT;\r
-\r
- ContinueBolt ();\r
- lasthand = lasttimecount;\r
- }\r
- else\r
- {\r
- if (control.button0)\r
- {\r
- handheight+=(realtics<<2);\r
- if (handheight>MAXHANDHEIGHT)\r
- handheight = MAXHANDHEIGHT;\r
- lasthand = lasttimecount;\r
-\r
- if (!button0down)\r
- Shoot();\r
-\r
-// if (!autofire)\r
- button0down=true;\r
- }\r
- else\r
- {\r
- if (lasttimecount > lasthand+HANDPAUSE)\r
- {\r
- handheight-=(realtics<<1);\r
- if (handheight<0)\r
- handheight = 0;\r
- }\r
-\r
- button0down = false;\r
- }\r
-}\r
-\r
-#if 0\r
- if (control.button0)\r
- {\r
- handheight+=(realtics<<2);\r
- if (handheight>MAXHANDHEIGHT)\r
- handheight = MAXHANDHEIGHT;\r
-\r
- if ((unsigned)TimeCount/FIRETIME != lastfiretime)\r
- BuildShotPower ();\r
- lasthand = lasttimecount;\r
- }\r
- else\r
- {\r
- if (lasttimecount > lasthand+HANDPAUSE)\r
- {\r
- handheight-=(realtics<<1);\r
- if (handheight<0)\r
- handheight = 0;\r
- }\r
-\r
- if (gamestate.shotpower)\r
- {\r
- lastfiretime = (unsigned)TimeCount/FIRETIME;\r
- Shoot ();\r
- }\r
- }\r
- }\r
-#endif\r
-\r
- //\r
- // special actions\r
- //\r
-\r
- if ((Keyboard[sc_Space] || Keyboard[sc_C]) && gamestate.body != MAXBODY)\r
- DrinkPotion ();\r
-\r
- if (Keyboard[sc_Z] && !boltsleft)\r
- CastBolt ();\r
-\r
- if ( (Keyboard[sc_Enter] || Keyboard[sc_X]) && ((TimeCount-lastnuke > NUKETIME))) //|| (autofire)))\r
- CastNuke ();\r
-\r
-#if 0\r
- scroll = LastScan-2;\r
- if ( scroll>=0 && scroll<NUMSCROLLS && gamestate.scrolls[scroll])\r
- ReadScroll (scroll);\r
-#endif\r
-\r
- DrawText(false);\r
- DrawHealth();\r
- if (FreezeTime)\r
- DrawFreezeTime();\r
- DrawRadar();\r
- EGAWRITEMODE(0);\r
- DrawNSEWIcons();\r
-\r
- if (redraw_gems)\r
- DrawGems();\r
-\r
-#if 0\r
-// gems fade out over time...\r
-//\r
- for (loop=0; loop<5; loop++)\r
- if (gamestate.gems[loop])\r
- {\r
- gamestate.gems[loop] -= realtics;\r
- if (gamestate.gems[loop] < 0)\r
- {\r
- gamestate.gems[loop] = 0;\r
- redraw_gems = true;\r
- }\r
- }\r
-#endif\r
-}\r
-\r
-#if 0\r
-//------------------------------------------------------------------------\r
-// FaceDir() -\r
-//\r
-// PARAMS : x,y - pixle coords to bring in to view.\r
-//\r
-// NOTE : Params CAN NOT be shifted fracs!\r
-//------------------------------------------------------------------------\r
-void FaceDir(short x,short y,boolean StopTime)\r
-{\r
- short diff;\r
-\r
- RotateAngle = CalcAngle(x-(player->x>>16l),(player->y>>16l)-y);\r
- FreezeTime = StopTime;\r
-\r
- diff = player->angle - RotateAngle;\r
-\r
- if (((diff>0) && (diff<180)) || ((diff<0) && (diff>-180)))\r
- RotateSpeed = -ROTATE_SPEED;\r
- else\r
- RotateSpeed = ROTATE_SPEED;\r
-}\r
-#endif\r
-\r
-#if 0\r
-//------------------------------------------------------------------------\r
-// CalcAngle() -\r
-//\r
-// DESC: Calculates the angle from a given dy & dx\r
-//------------------------------------------------------------------------\r
-short CalcAngle(short dx,short dy)\r
-{\r
- #define degtorad (180/PI)\r
- float angle;\r
- short diff;\r
- float rad_angle;\r
-\r
- if (dx)\r
- {\r
- angle = atan((float)dy/dx)* degtorad;\r
- if (angle<=0)\r
- angle += 180;\r
- if (dy>0)\r
- angle += 180;\r
- }\r
- else\r
- {\r
- // 90 Deg shift\r
-\r
- if (dy < 0)\r
- angle = 0 + 90; // Above player (NORTH)\r
- else\r
- angle = 180 + 90; // Below player (SOUTH)\r
- }\r
-\r
- if (!angle) // HACK\r
- angle++;\r
-\r
- return((short)abs(angle));\r
-}\r
-\r
-#endif\r
-\r
-#if 0\r
-\r
-//-------------------------------------------------------------------------\r
-// RotateView() -\r
-//\r
-// DESC : Rotates view (current view of game) to a dest angle.\r
-//-------------------------------------------------------------------------\r
-void RotateView()\r
-{\r
- short LastPos;\r
-\r
- // Store old angle position then change angle...\r
- //\r
-\r
- LastPos = player->angle;\r
-\r
- player->angle += RotateSpeed;\r
-\r
- // Check to see if we cranked past out dest angle...\r
- //\r
-\r
-\r
- if ((player->angle>ANGLES) || (!player->angle))\r
- player->angle = 1;\r
- else\r
- if (player->angle<1)\r
- player->angle = ANGLES;\r
-\r
- // Check to see if we over shot our dest angle...\r
- //\r
-\r
- if (((LastPos < RotateAngle) && (player->angle > RotateAngle) && (RotateSpeed > 0)) ||\r
- ((LastPos > RotateAngle) && (player->angle < RotateAngle) && (RotateSpeed < 0)))\r
- player->angle = RotateAngle;\r
-\r
- // Check for ending force turn....\r
- //\r
-\r
- if (player->angle == RotateAngle)\r
- RotateAngle = -1;\r
-\r
-}\r
-\r
-\r
-//--------------------------------------------------------------------------\r
-// InitRotate()\r
-//--------------------------------------------------------------------------\r
-void InitRotate(short DestAngle)\r
-{\r
- if (player->angle != DestAngle)\r
- {\r
- RotateAngle = DestAngle;\r
-\r
- if (player->angle > DestAngle)\r
- RotateSpeed = -ROTATE_SPEED;\r
- else\r
- RotateSpeed = ROTATE_SPEED;\r
-\r
- if (abs(player->angle - RotateAngle) > 180)\r
- RotateSpeed =- RotateSpeed;\r
- }\r
-}\r
-\r
-\r
-\r
-//------------------------------------------------------------------------\r
-// FaceAngle() -\r
-//\r
-// PARAMS : DestAngle - Destination angle to turn to\r
-//------------------------------------------------------------------------\r
-void FaceAngle(short DestAngle)\r
-{\r
- signed long dx,dy,radius,psin,pcos,newx,newy;\r
- int give;\r
- short objnum,LastPos;\r
- signed long ox,oy,xl,xh,yl,yh,px,py,norm_dx,norm_dy;\r
- short o_radius;\r
- void (*think)();\r
-\r
-\r
- // Calculate the direction we want to turn to...\r
- //\r
-\r
- InitRotate(DestAngle);\r
-\r
- RedrawStatusWindow();\r
-\r
- while (RotateAngle != -1)\r
- {\r
-\r
- RotateView();\r
-\r
-// PollControls();\r
-\r
- objnum=0;\r
-\r
- for (obj = player;obj;obj = obj->next)\r
- {\r
- if (obj->active >= yes)\r
- {\r
-\r
- // keep a list of objects around the player for radar updates\r
- //\r
- if (obj == player)\r
- {\r
- px = player->x;\r
- py = player->y;\r
- psin = sintable[player->angle];\r
- pcos = costable[player->angle];\r
- xl = px-((long)RADAR_WIDTH<<TILESHIFT)/2;\r
- xh = px+((long)RADAR_WIDTH<<TILESHIFT)/2-1;\r
- yl = py-((long)RADAR_HEIGHT<<TILESHIFT)/2;\r
- yh = py+((long)RADAR_HEIGHT<<TILESHIFT)/2;\r
- }\r
-\r
- if (objnum > MAX_RADAR_BLIPS-2)\r
- objnum = MAX_RADAR_BLIPS-2;\r
-\r
- ox = obj->x;\r
- oy = obj->y;\r
-\r
-\r
- if ((ox >= xl) && (ox <= xh) && (oy >= yl) && (oy <= yh))\r
- {\r
- norm_dx = (dx = px-ox)>>TILESHIFT;\r
- norm_dy = (dy = oy-py)>>TILESHIFT;\r
-\r
- o_radius = IntSqrt((norm_dx * norm_dx) + (norm_dy * norm_dy));\r
-\r
- if (o_radius < RADAR_RADIUS)\r
- {\r
- newx = FixedByFrac(dy,pcos)-FixedByFrac(dx,psin);\r
- newy = FixedByFrac(dy,psin)+FixedByFrac(dx,pcos);\r
-\r
- RadarXY[objnum][0]=newx>>TILESHIFT;\r
- RadarXY[objnum][1]=newy>>TILESHIFT;\r
-\r
- // Define color to use for this object...\r
- //\r
-\r
- switch (obj->obclass)\r
- {\r
- case playerobj:\r
- RadarXY[objnum++][2]=15;\r
- break;\r
-\r
- // RED GEM\r
- //\r
- // STOMPY (DK RED)\r
- //\r
- case invisdudeobj:\r
- case stompyobj:\r
- RadarXY[objnum++][2]=4;\r
- break;\r
-\r
- // BLOB (LT RED)\r
- //\r
- case blobobj:\r
- RadarXY[objnum++][2]=12;\r
- break;\r
-\r
- // BLUE GEM\r
- //\r
- // ROBOTANK (LT BLUE)\r
- //\r
- case robotankobj:\r
- case fmageobj:\r
- RadarXY[objnum++][2]=9;\r
- break;\r
-\r
-#if 1\r
- // BLUE DEMON (DK BLUE)\r
- //\r
- case demonobj:\r
- RadarXY[objnum++][2]=1;\r
- break;\r
-#endif\r
-\r
- // GREEN GEM\r
- //\r
- // WIZARD (LT GREEN)\r
- //\r
- case wizardobj:\r
- RadarXY[objnum++][2]=10;\r
- break;\r
-\r
- // AQUA MAN (DK GREEN)\r
- //\r
- case aquamanobj:\r
- RadarXY[objnum++][2]=2;\r
- break;\r
-\r
- // YELLOW GEM\r
- //\r
- // EQYPTIAN HEAD (BROWN)\r
- //\r
- case headobj:\r
- RadarXY[objnum++][2]=6;\r
- break;\r
-\r
- // RAMBONE (YELLOW)\r
- // TROLL\r
- case ramboneobj:\r
- case trollobj:\r
- RadarXY[objnum++][2]=14;\r
- break;\r
-\r
- // BUG (LIGHT GRAY)\r
- case bugobj:\r
- RadarXY[objnum++][2]=7;\r
- break;\r
-\r
- // RAY (DARK GRAY)\r
- case rayobj:\r
- RadarXY[objnum++][2]=8;\r
- break;\r
-\r
- // PURPLE GEM\r
- //\r
- // MEC DEMON (PURPLE)\r
- //\r
- case cyborgdemonobj:\r
- RadarXY[objnum++][2]=5;\r
- break;\r
-\r
- // EYE (LT PURPLE)\r
- //\r
- case eyeobj:\r
- case reyeobj:\r
- RadarXY[objnum++][2]=13;\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- RadarXY[objnum][2]=-1; // Signals end of RadarXY list...\r
-\r
-// refresh all\r
-//\r
-\r
- ThreeDRefresh();\r
- DrawRadar();\r
- EGAWRITEMODE(0);\r
- DrawNSEWIcons();\r
-\r
-// CheckKeys();\r
- }\r
-}\r
-\r
-\r
-//-------------------------------------------------------------------------\r
-// FaceDoor() - Turns the player to face a door (a tile) at a given TILE x & y\r
-//\r
-// RETURNS : Returns the orginal angle of the player.\r
-//------------------------------------------------------------------------\r
-short FaceDoor(short x, short y)\r
-{\r
- short p_x,p_y,angle,old_angle;\r
-\r
- old_angle = player->angle;\r
-\r
- p_x = player->x>>16l;\r
- p_y = player->y>>16l;\r
-\r
- if (p_x != x)\r
- {\r
- if (p_x > x)\r
- angle = 180; // Face Left\r
- else\r
- angle = 1; // Face Right\r
- }\r
-\r
- if (p_y != y)\r
- {\r
- if (p_y > y)\r
- angle = 90; // Face Up\r
- else\r
- angle = 270; // Face Down\r
- }\r
-\r
- FaceAngle(angle);\r
-\r
- return(old_angle);\r
-}\r
-\r
-\r
-#endif\r
-\r
-\r
-\r
-/*==========================================================================\r
-\r
- EXPLOSION SPAWNING ROUTINES\r
-\r
-===========================================================================*/\r
-\r
-statetype s_explode = {0,1,T_ExpThink,&s_explode};\r
-\r
-//-------------------------------------------------------------------------\r
-// SpawnExplosion()\r
-//------------------------------------------------------------------------\r
-void SpawnExplosion(fixed x, fixed y, short Delay)\r
-{\r
- DSpawnNewObjFrac(x,y,&s_explode,PIXRADIUS*7);\r
- new->obclass = expobj;\r
- new->active = always;\r
- new->temp1 = Delay;\r
-}\r
-\r
-\r
-//---------------------------------------------------------------------------\r
-// T_ExpThink()\r
-//---------------------------------------------------------------------------\r
-void T_ExpThink(objtype *obj)\r
-{\r
- if (obj->temp1)\r
- {\r
- if ((obj->temp1-=realtics) <= 0)\r
- obj->temp1 = 0;\r
- }\r
- else\r
- {\r
- obj->state = &s_pshot_exp1;\r
- obj->ticcount = obj->state->tictime;\r
- SD_PlaySound(BOOMSND);\r
- }\r
-}\r
-\r
-\r
-\r
-//-------------------------------------------------------------------------\r
-// SpawnBigExplosion()\r
-//------------------------------------------------------------------------\r
-void SpawnBigExplosion(fixed x, fixed y, short Delay, fixed Range)\r
-{\r
- SpawnExplosion(x-random(Range),y+random(Range),random(Delay));\r
- SpawnExplosion(x+random(Range),y-random(Range),random(Delay));\r
- SpawnExplosion(x-random(Range),y-random(Range),random(Delay));\r
- SpawnExplosion(x+random(Range),y+random(Range),random(Delay));\r
-}\r
-\r