X-Git-Url: http://4ch.mooo.com/gitweb/?a=blobdiff_plain;f=16%2Fcawat%2FC5_PLAY.C;fp=16%2Fcawat%2FC5_PLAY.C;h=96f777576891b290648c887ef93d48e91433ad03;hb=2029bb3324ea380cfb686594ffaa9b038fdb820f;hp=0000000000000000000000000000000000000000;hpb=24c0b941ba2acf9e44115a3b41c511ecd5a9d22d;p=16.git diff --git a/16/cawat/C5_PLAY.C b/16/cawat/C5_PLAY.C new file mode 100644 index 00000000..96f77757 --- /dev/null +++ b/16/cawat/C5_PLAY.C @@ -0,0 +1,1425 @@ +/* Catacomb Armageddon Source Code + * Copyright (C) 1993-2014 Flat Rock Software + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +// C3_PLAY.C + +#include "DEF.H" +#include "gelib.h" +#pragma hdrstop + +/* +============================================================================= + + LOCAL CONSTANTS + +============================================================================= +*/ + +#define POINTTICS 6 +#define PAUSE 300 + +/* +============================================================================= + + GLOBAL VARIABLES + +============================================================================= +*/ + +byte bcolor; +short skytimer=-1,skytimer_reset; +short groundtimer=-1,groundtimer_reset; + +unsigned scolor,gcolor; +unsigned *skycolor,*groundcolor,debug_sky,debug_gnd; + +unsigned nocolorchange=0xFFFF; +byte BGFLAGS, // global that holds all current flags + bgflag; // used by BG changer, this flag is set when done + + +unsigned sky_daytonight[]={0x0909,0x0101,0x0808,0x0000,0xFFFF}; +//unsigned gnd_daytonight[]={0x0202,0xFFFF}; + +unsigned sky_lightning[]={0x0101,0x0909,0x0f0f,0x0808,0x0000,0xFFFF}; + +unsigned sky_colors[NUMLEVELS]={0x0000,0x0000,0x0000,0x0000,0x0808, + 0x0404,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0606, + 0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000}; +unsigned gnd_colors[NUMLEVELS]={0x0202,0x0202,0x0606,0x0202,0x0707, + 0x0505,0x0808,0x0606,0x0101,0x0808, + 0x0606,0x0404,0x0808,0x0c0c,0x0e0e, + 0x0808,0x0808,0x0c0c,0x0000,0x0707, + 0x0808}; + + +ControlInfo control; +boolean running=false; //,slowturn; + +int bordertime; +objtype objlist[MAXACTORS],*new,*obj,*player,*lastobj,*objfreelist; + +#if USE_INERT_LIST +inertobjtype inertobjlist[MAXINERTOBJ],*inert; +#endif + +unsigned farmapylookup[MAPSIZE]; +byte *nearmapylookup[MAPSIZE]; + +boolean singlestep,godmode; +int extravbls; +status_flags status_flag; +int status_delay; + +// +// replacing refresh manager +// +unsigned mapwidth,mapheight,tics,realtics; +boolean compatability; +byte *updateptr; +unsigned mapwidthtable[64]; +unsigned uwidthtable[UPDATEHIGH]; +unsigned blockstarts[UPDATEWIDE*UPDATEHIGH]; +#define UPDATESCREENSIZE (UPDATEWIDE*PORTTILESHIGH+2) +#define UPDATESPARESIZE (UPDATEWIDE*2+4) +#define UPDATESIZE (UPDATESCREENSIZE+2*UPDATESPARESIZE) +byte update[UPDATESIZE]; + +int mousexmove,mouseymove; +int pointcount,pointsleft; + +short BeepTime = 0; + +/* +============================================================================= + + LOCAL VARIABLES + +============================================================================= +*/ + +void CalcBounds (objtype *ob); +void DrawPlayScreen (void); +void PreFullDisplay(void); +void PostFullDisplay(boolean draw_view); + + +// +// near data map array (wall values only, get text number from far data) +// +byte tilemap[MAPSIZE][MAPSIZE]; +byte spotvis[MAPSIZE][MAPSIZE]; +objtype *actorat[MAPSIZE][MAPSIZE]; + +objtype dummyobj; + +int bordertime; +int objectcount; + +void StopMusic(void); +void StartMusic(void); + +void CalibrateJoystick(short joynum); + +//========================================================================== + +/////////////////////////////////////////////////////////////////////////// +// +// CenterWindow() - Generates a window of a given width & height in the +// middle of the screen +// +/////////////////////////////////////////////////////////////////////////// + +#define MAXX 320 +#define MAXY 120 + +void CenterWindow(word w,word h) +{ + US_DrawWindow(((MAXX / 8) - w) / 2,((MAXY / 8) - h) / 2,w,h); +} + +//=========================================================================== + + +/* +===================== += += CheckKeys += +===================== +*/ + +void CheckKeys (void) +{ + extern boolean autofire; + + if (screenfaded) // don't do anything with a faded screen + return; + +#if 0 +// +// pause key wierdness can't be checked as a scan code +// + if (Paused) + { + CenterWindow (8,3); + US_PrintCentered ("PAUSED"); + VW_UpdateScreen (); +// SD_MusicOff(); + IN_Ack(); +// SD_MusicOn(); + Paused = false; + if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement + } + else + if (Keyboard[sc_Enter]) // P = pause with no screen disruptioon + { +// SD_MusicOff(); + DisplaySMsg("PAUSED",NULL); + IN_Ack(); +// SD_MusicOn(); + if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement + } + else + if (Keyboard[sc_S]) + { + char *Text[] = {{"Slow Mode ON"},{"Slow Mode OFF"}}; + + SlowMode ^= 1; + extravbls = SlowMode << 3; + CenterWindow (8,3); + US_PrintCentered (Text[SlowMode]); + VW_UpdateScreen (); +// SD_MusicOff(); + IN_Ack(); +// SD_MusicOn(); + if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement + } +#endif + + +// F2 - SOUND OPTIONS +// + if (Keyboard[sc_F2]) + { + int height=7; + boolean ChoiceMade = false; + + if (AdLibPresent) + height++; + + VW_FixRefreshBuffer(); + CenterWindow(22,height); + US_Print( "\n 1 ) NO SOUND \n"); + US_Print( " 2 ) PC AUDIO \n"); + + if (AdLibPresent) + US_Print(" 3 ) ADLIB AUDIO\n"); + + US_Print( "\n ESC) EXIT "); + VW_UpdateScreen(); + + // Switch audio device ON/OFF & load sounds if there + // was a change in the device. + + do { + + if (Keyboard[1]) // ESC - Exit + ChoiceMade = true; + else + if (Keyboard[2]) // 1 - No Sound + { + SD_SetSoundMode(sdm_Off); + ChoiceMade = true; + } + else + if (Keyboard[3]) // 2 - PC Audio + { + SD_SetSoundMode(sdm_PC); +// if (oldsoundmode != sdm_PC) + CA_LoadAllSounds(); + ChoiceMade = true; + } + else + if ((Keyboard[4]) && AdLibPresent) // 3 - AdLib Audio + { + SD_SetSoundMode(sdm_AdLib); +// if (oldsoundmode != sdm_AdLib) + CA_LoadAllSounds(); + ChoiceMade = true; + } + + } while (!ChoiceMade); + tics = realtics = 1; + IN_ClearKeysDown(); + } + +// F5 - CALIBRATE JOYSTICK +// + if (Keyboard[sc_F5]) + { + CalibrateJoystick(0); + tics = realtics = 1; + IN_ClearKeysDown(); + } + +deadloop:; +// ESCAPE - quits game +// + if ((Keyboard[sc_Escape]) || (Flags & FL_DEAD)) + { + char ch; + + DisplaySMsg("Options", NULL); + status_flag = S_NONE; + + + if (Flags & FL_DEAD) + { + char choices[] = {sc_Escape,sc_R,sc_N,sc_Q,0}; + ch = DisplayMsg("Restore New Quit",choices); + } + else + { + char choices[] = {sc_Escape,sc_S,sc_R,sc_N,sc_Q,0}; + ch = DisplayMsg("Save Restore New Quit",choices); + } + DrawText(true); + + switch (ch) + { + case sc_S: + if (!(Flags & FL_DEAD)) + Keyboard[sc_F3] = true; + break; + + case sc_R: + Keyboard[sc_F4] = true; + break; + + case sc_N: + DisplaySMsg("Starting anew", NULL); + VW_WaitVBL(60); + playstate = ex_resetgame; + Flags &= ~FL_DEAD; + break; + + case sc_Q: + DisplaySMsg("FARE THEE WELL!", NULL); + VW_WaitVBL(120); + if (!Flags & FL_QUICK) + VW_FadeOut(); + NormalScreen(); + FreeUpMemory(); + Quit(NULL); + break; + } + tics = realtics = 1; + } + +// F1 - DISPLAY HELP +// + if (Keyboard[sc_F1]) + { + PrintHelp(); + +#ifdef TEXT_PRESENTER + + extern PresenterInfo MainHelpText; + + VW_FadeOut(); + + FreeUpMemory(); + if (!LoadPresenterScript("HELP.TXT",&MainHelpText)) + { + VW_FadeIn(); + CenterWindow(30,5); + US_CPrint("\nError loading HELP file.\n"); + US_CPrint("Press any key."); + IN_Ack(); + VW_FadeOut(); + } + else + { + VW_SetSplitScreen(200); + bufferofs = displayofs = screenloc[0]; + VW_Bar(0,0,320,200,0); + + Display640(); + Presenter(&MainHelpText); + Display320(); + } + FreePresenterScript(&MainHelpText); +#endif + VW_SetSplitScreen(120); + VW_SetScreen(screenloc[0],0); + screenpage = 0; + CacheScaleds(); + + bufferofs = 0; + RedrawStatusWindow(); + ThreeDRefresh(); + VW_FadeIn(); + Keyboard[sc_F1] = false; + tics = realtics = 1; + IN_ClearKeysDown(); + } + +// F3 - SAVE GAME +// + if ((Keyboard[sc_F3]) && (!(Flags & FL_DEAD))) + { + PreFullDisplay(); + GE_SaveGame(); + PostFullDisplay(true); + tics = realtics = 1; + IN_ClearKeysDown(); + } + +// F4 - LOAD GAME +// + if (Keyboard[sc_F4]) + { + PreFullDisplay(); + if (GE_LoadGame()) + { + loadedgame = true; + playstate = ex_loadedgame; + Flags &= ~FL_DEAD; + lasttext = -1; + PostFullDisplay(false); + } + else + if (playstate == ex_victorious) + { + PostFullDisplay(false); + Victory(false); + IN_Ack(); +// gamestate.mapon++; + } + else + PostFullDisplay(true); + Keyboard[sc_F5] = false; + tics = realtics = 1; + IN_ClearKeysDown(); + } + + if (Flags & FL_DEAD) + goto deadloop; + +// +// F10-? debug keys +// + if (Keyboard[sc_BackSpace]) + { + DebugKeys(); + if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement + lasttimecount = TimeCount; + } +} + +//------------------------------------------------------------------------- +// PreFullDisplay() +//------------------------------------------------------------------------- +void PreFullDisplay() +{ + VW_FadeOut(); + VW_SetSplitScreen(200); + bufferofs = displayofs = screenloc[0]; + VW_Bar(0,0,320,200,0); +} + +//------------------------------------------------------------------------- +// PostFullDisplay() +//------------------------------------------------------------------------- +void PostFullDisplay(boolean draw_view) +{ + VW_SetSplitScreen(120); + bufferofs = 0; + RedrawStatusWindow(); + if (draw_view) + { + ThreeDRefresh(); + VW_FadeIn(); + } +} + + +//=========================================================================== + +/* +############################################################################# + + The objlist data structure + +############################################################################# + +objlist containt structures for every actor currently playing. The structure +is accessed as a linked list starting at *player, ending when ob->next == +NULL. GetNewObj inserts a new object at the end of the list, meaning that +if an actor spawn another actor, the new one WILL get to think and react the +same frame. RemoveObj unlinks the given object and returns it to the free +list, but does not damage the objects ->next pointer, so if the current object +removes itself, a linked list following loop can still safely get to the +next element. + + + +############################################################################# +*/ + + +/* +========================= += += InitObjList += += Call to clear out the entire object list, returning them all to the free += list. Allocates a special spot for the player. += +========================= +*/ + +void InitObjList (void) +{ + int i; + + for (i=0;iprev; + memset (new,0,sizeof(*new)); + + if (lastobj) + lastobj->next = new; + new->prev = lastobj; // new->next is allready NULL from memset + + new->active = false; + lastobj = new; + + objectcount++; +} + +//=========================================================================== + +/* +========================= += += RemoveObj += += Add the given object back into the free list, and unlink it from it's += neighbors += +========================= +*/ + +void RemoveObj (objtype *gone) +{ + objtype **spotat; + + if (gone == player) + Quit ("RemoveObj: Tried to remove the player!"); + +// +// fix the next object's back link +// + if (gone == lastobj) + lastobj = (objtype *)gone->prev; + else + gone->next->prev = gone->prev; + +// +// fix the previous object's forward link +// + gone->prev->next = gone->next; + +// +// add it back in to the free list +// + gone->prev = objfreelist; + objfreelist = gone; + + objectcount--; +} + +#if USE_INERT_LIST + +//-------------------------------------------------------------------------- +// MoveObjToInert() +//-------------------------------------------------------------------------- +void MoveObjToInert(objtype *obj) +{ + + if (inert == &inertobjlist[MAXINERTOBJ]) + return; + +// Transfer info needed by inert objtype +// + inert->x = obj->x; + inert->y = obj->y; + inert->size = obj->size; + inert->viewx = obj->viewx; + inert->tilex = obj->tilex; + inert->tiley = obj->tiley; + inert->state = obj->state; + inert->ticcount = obj->ticcount; + +// Setup links between inert objects +// + if (inert != inertobjlist) + (inert-1)->next = inert; + inert->next = NULL; + inert++; + +// Free 'real' object from list. +// + RemoveObj(obj); +} + +#endif + +//========================================================================== + +/* +=================== += += PollControls += +=================== +*/ + +void PollControls (void) +{ + unsigned buttons; + + IN_ReadControl(0,&control); + + if (MousePresent) + { + Mouse(MButtons); + buttons = _BX; + Mouse(MDelta); + mousexmove = _CX; + mouseymove = _DX; + + if (buttons&1) + control.button0 = 1; + if (buttons&2) + control.button1 = 1; + + } + + if (Keyboard[sc_V] || Keyboard[sc_Tab]) + running = true; + else + running = false; +} + +//========================================================================== + +#if 0 +/* +================= += += StopMusic += +================= +*/ + +void StopMusic(void) +{ + int i; + + SD_MusicOff(); + for (i = 0;i < LASTMUSIC;i++) + if (audiosegs[STARTMUSIC + i]) + { + MM_SetPurge(&((memptr)audiosegs[STARTMUSIC + i]),3); + MM_SetLock(&((memptr)audiosegs[STARTMUSIC + i]),false); + } +} + +//========================================================================== + + +/* +================= += += StartMusic += +================= +*/ + +// JAB - Cache & start the appropriate music for this level +void StartMusic(void) +{ + musicnames chunk; + + SD_MusicOff(); + chunk = TOOHOT_MUS; +// if ((chunk == -1) || (MusicMode != smm_AdLib)) +//DEBUG control panel return; + + MM_BombOnError (false); + CA_CacheAudioChunk(STARTMUSIC + chunk); + MM_BombOnError (true); + if (mmerror) + mmerror = false; + else + { + MM_SetLock(&((memptr)audiosegs[STARTMUSIC + chunk]),true); + SD_StartMusic((MusicGroup far *)audiosegs[STARTMUSIC + chunk]); + } +} +#endif + +//========================================================================== + + +/* +=================== += += PlayLoop += +=================== +*/ + +void PlayLoop (void) +{ + char shot_color[3] = {4,9,14}; + + int allgems[5]={GEM_DELAY_TIME, // used for Q & D comparison + GEM_DELAY_TIME, // for having all gems... + GEM_DELAY_TIME, // the "allgems" declaration MUST + GEM_DELAY_TIME, // match the "gems" declaration in + GEM_DELAY_TIME // the gametype structure! + }; + +// int originx=0; +// int i=100; + signed long dx,dy,radius,psin,pcos,newx,newy; + int give; + short objnum; + signed long ox,oy,xl,xh,yl,yh,px,py,norm_dx,norm_dy; + short o_radius; + + void (*think)(); + + ingame = true; + playstate = TimeCount = 0; + gamestate.shotpower = handheight = 0; + pointcount = pointsleft = 0; + + status_flag = S_NONE; + +#if 0 + // setup sky/ground colors and effects (based on level) + // + switch (gamestate.mapon) + { + case 255: + if (!(BGFLAGS & BGF_NIGHT)) + { + InitBgChange(3*60,sky_daytonight,-1,NULL,BGF_NIGHT); + groundcolor = &gnd_colors[0]; + } + else + { + skycolor = &sky_colors[0]; + groundcolor = &gnd_colors[0]; + } + break; + + default: + skycolor = &sky_colors[gamestate.mapon]; + groundcolor = &gnd_colors[gamestate.mapon]; + skytimer = groundtimer = -1; + break; + } +#endif + + BGFLAGS |= BGF_NOT_LIGHTNING; + skytimer = groundtimer = -1; + + debug_gnd = *groundcolor; + debug_sky = *skycolor; + RedrawStatusWindow(); + ThreeDRefresh(); + if (screenfaded) + VW_FadeIn(); + +#ifndef PROFILE + fizzlein = true; // fizzle fade in the first refresh +#endif + TimeCount = lasttimecount = lastnuke = 0; + + PollControls (); // center mouse +// StartMusic (); + do + { +#ifndef PROFILE + PollControls(); +#else + control.xaxis = 1; + if (++TimeCount == 300) + return; +#endif + DisplayStatus(&status_flag); + + objnum=0; + for (obj = player;obj;obj = obj->next) + { + if ((obj->active >= yes) && (!(FreezeTime && (obj!=player)))) + { + if (obj->ticcount) + { + obj->ticcount-=realtics; + while ( obj->ticcount <= 0) + { + think = obj->state->think; + if (think) + { + statetype *oldstate=obj->state; + + think (obj); + if (!obj->state) + { + RemoveObj (obj); + goto nextactor; + } + if (obj->state != oldstate) + break; + } + + obj->state = obj->state->next; + if (!obj->state) + { + RemoveObj (obj); + goto nextactor; + } + if (!obj->state->tictime) + { + obj->ticcount = 0; + goto nextactor; + } + if (obj->state->tictime>0) + obj->ticcount += obj->state->tictime; + } + } + + think = obj->state->think; + if (think) + { + think (obj); + if (!obj->state) + RemoveObj (obj); + } +nextactor:; + } + + // keep a list of objects around the player for radar updates + // + if (obj == player) + { + px = player->x; + py = player->y; + psin = sintable[player->angle]; + pcos = costable[player->angle]; + xl = px-((long)RADAR_WIDTH< MAX_RADAR_BLIPS-2) + objnum = MAX_RADAR_BLIPS-2; + + ox = obj->x; + oy = obj->y; + + + if ((ox >= xl) && (ox <= xh) && (oy >= yl) && (oy <= yh)) + { + norm_dx = (dx = px-ox)>>TILESHIFT; + norm_dy = (dy = oy-py)>>TILESHIFT; + + o_radius = IntSqrt((norm_dx * norm_dx) + (norm_dy * norm_dy)); + + if (o_radius < RADAR_RADIUS) + { + newx = FixedByFrac(dy,pcos)-FixedByFrac(dx,psin); + newy = FixedByFrac(dy,psin)+FixedByFrac(dx,pcos); + + RadarXY[objnum][0]=newx>>TILESHIFT; + RadarXY[objnum][1]=newy>>TILESHIFT; + + // Define color to use for this object... + // + + switch (obj->obclass) + { + // NO GEM NEEDED + // + // THE WIZARD! (YOU) + // + case playerobj: + RadarXY[objnum++][2]=15; + break; + + // WIZARD'S SHOTS + // + case pshotobj: + case bigpshotobj: + RadarXY[objnum++][2]=shot_color[screenpage]; + break; + + // BATS (DK GRAY) + // + case batobj: + if (obj->active == always) + RadarXY[objnum++][2]=8; + break; + + // RABBITS (LT GRAY) + // + case bunnyobj: + if (obj->active == always) + RadarXY[objnum++][2]=7; + break; + + // RED GEM + // + // EYE, RED DEMON (DK RED) + // + case eyeobj: + case reddemonobj: + if (gamestate.gems[B_RGEM-B_RGEM]) + if (obj->active == always) + RadarXY[objnum++][2]=4; + break; + + // RED MAGE (LT RED) + // + case mageobj: + if (gamestate.gems[B_RGEM-B_RGEM]) + if (obj->active == always) + RadarXY[objnum++][2]=12; + break; + + // BLUE GEM + // + // SUCCUBUS (LT BLUE) + // + case succubusobj: + if (gamestate.gems[B_BGEM-B_RGEM]) + if (obj->active == always) + RadarXY[objnum++][2]=9; + break; + + // WATER DRAGON (DK BLUE) + // + case wetobj: + if (gamestate.gems[B_GGEM-B_RGEM]) + if (obj->active == always) + RadarXY[objnum++][2]=1; + break; + + + + // GREEN GEM + // + // GREEN TROLL (LT GREEN) + // + case fatdemonobj: + if (gamestate.gems[B_GGEM-B_RGEM]) + if (obj->active == always) + RadarXY[objnum++][2]=10; + break; + + // GODESS (DK GREEN) + // + case godessobj: + if (gamestate.gems[B_GGEM-B_RGEM]) + if (obj->active == always) + RadarXY[objnum++][2]=2; + break; + + // YELLOW GEM + // + // ANT (BROWN) + // + case antobj: + case treeobj: + if (gamestate.gems[B_YGEM-B_RGEM]) + if (obj->active == always) + RadarXY[objnum++][2]=6; + break; + + // SKELETON (YELLOW) + // + case skeletonobj: + if (gamestate.gems[B_YGEM-B_RGEM]) + if (obj->active == always) + RadarXY[objnum++][2]=14; + break; + + // PURPLE GEM + // + // ZOMBIE + // + case zombieobj: + if (gamestate.gems[B_PGEM-B_RGEM]) + if (obj->active == always) + RadarXY[objnum++][2]=13; + break; + + // ALL GEMS NEEDED + // + // NEMESIS + // + case grelmobj: + if (!memcmp(gamestate.gems,allgems,sizeof(gamestate.gems))) + if (obj->active == always) + RadarXY[objnum++][2]=15; + break; + } + } + } + } + RadarXY[objnum][2]=-1; // Signals end of RadarXY list... + +#if USE_INERT_LIST + if (inert != inertobjlist) + for (obj=(objtype *)inertobjlist;obj;obj=obj->next) + if (obj->ticcount) + { + obj->ticcount-=realtics; + while ( obj->ticcount <= 0) + { + obj->state = obj->state->next; + if (!obj->state) + Quit("Removable object in INERT list."); + + if (!obj->state->tictime) + { + obj->ticcount = 0; + goto nextactor; + } + + if (obj->state->tictime>0) + obj->ticcount += obj->state->tictime; + } + } +#endif + + if (bordertime) + { + bordertime -= realtics; + if (bordertime<=0) + { + bordertime = 0; + VW_ColorBorder(0); + } + } + +#if 1 +// random lightning? +// + if (BGFLAGS & (BGF_NOT_LIGHTNING)) + { + if ((scolor & 0xe0) && (!(random(20-realtics)))) + { + BGFLAGS &= ~BGF_NOT_LIGHTNING; + InitBgChange(1,sky_lightning,-1,NULL,BGF_NOT_LIGHTNING); + } + } + +// handle sky/ground color changes +// + if (skytimer != -1) + { + skytimer -= realtics; + if (skytimer < 0) + { + skycolor++; + if (*skycolor == 0xffff) + { + skytimer = -1; +// skycolor--; + skycolor = &scolor; + if (groundtimer == -1) + BGFLAGS |= bgflag; + } + else + skytimer = skytimer_reset; + } + } + + if (groundtimer != -1) + { + groundtimer -= realtics; + if (groundtimer < 0) + { + groundcolor++; + if (*groundcolor == 0xffff) + { + groundtimer = -1; +// groundcolor--; + groundcolor = &gcolor; + if (skytimer == -1) + BGFLAGS |= bgflag; + } + else + groundtimer = groundtimer_reset; + } + } +#endif + + +// +// Handle FreezeTime counter.. +// + if (FreezeTime) + { + if (FreezeTime<20*30) + if ((BeepTime+=realtics)>=60) + { + BeepTime -= 60; + SD_PlaySound(TICKSND); + } + + if ((FreezeTime-=realtics)<=0) + { + FreezeTime=0; + SD_PlaySound(TIMERETURNSND); + DisplaySMsg(NULL,NULL); + status_flag = S_NONE; + } + } + + +// refresh all +// + ThreeDRefresh (); + + if (Flags & FL_DEAD) + { + SD_PlaySound (GAMEOVERSND); + DisplaySMsg("DEAD",NULL); + DrawHealth(); + if (gamestate.potions) + { + bufferofs = displayofs = screenloc[screenpage]; + CenterWindow(35,3); + US_CPrint("\nYou should use your Cure Potions wisely\n"); + IN_Ack(); + } + } + +// check for win +// + if (playstate == ex_victorious) + { + Victory(true); +// Flags |= FL_DEAD; + IN_Ack(); +// gamestate.mapon++; + } + + CheckKeys(); + + }while (!playstate); +// StopMusic (); + + ingame = false; + if (bordertime) + { + bordertime = 0; + VW_ColorBorder(0); + } + + if (abortgame) + abortgame = false; +} + +//-------------------------------------------------------------------------- +// IntSqrt() - by Master Programmer, George Leritte! +//-------------------------------------------------------------------------- +int IntSqrt(long va) +{ +asm mov AX, word ptr va +asm mov DX, word ptr va+2 +asm mov bx,dx // {bx = integer square root of dx:ax} +asm or bx,ax // {if dx:ax=0 then return} +asm jz isq01 +asm mov bx,dx +asm shl bx,1 +asm or bl,ah +asm or bl,al +asm dec bx +asm add bx,dx // { initial guess} +asm jg isq10 +asm inc bx // { don't return zero} +asm jg isq10 +asm mov bx,7fffh +isq01:; + goto exitrout; + +isq10:; +asm push ax +asm push dx +asm div bx +asm sub ax,bx +asm cmp ax,1 +asm jbe isq90 +asm cmp ax,-1 +asm jae isq90 +asm sar ax,1 +asm add bx,ax +asm pop dx +asm pop ax +asm jmp isq10 +isq90:; +asm pop dx +asm pop ax +exitrout:; +asm mov ax,bx +} + +//------------------------------------------------------------------------- +// InitBgChange() +//------------------------------------------------------------------------- +void InitBgChange(short stimer, unsigned *scolors, short gtimer, unsigned *gcolors, byte flag) +{ + skytimer_reset = skytimer = stimer; + if (scolors) + skycolor = scolors; + + groundtimer_reset = groundtimer = gtimer; + if (gcolors) + groundcolor = gcolors; + + bgflag = flag; +} + +//////////////////////////////////////////////////////// +// +// DisplayStatus +// +// Stat_Flag - contains the type of status displayed +// -- also uses status_delay (global variable) will not +// change display until this variable is zero. +// -- heirarchy is determined by the series of if statements, +// to change it, rearrange th if statements. +// +//////////////////////////////////////////////////////// + +#define MESSAGEDELAY 25 +void DisplayStatus (status_flags *stat_flag) +{ + status_flags temp_status; + + + if (*stat_flag == S_TIMESTOP) + return; + + if (status_delay > 0) + { + status_delay -= realtics; + return; + } + else + status_delay = 0; + + // check for a change in status from previous call + + temp_status = S_VIEWING; //precaution + + if (Keyboard[sc_Control] || control.button0) + temp_status = S_MISSLE; + + if (Keyboard[sc_Z] && !Keyboard[sc_F10]) + temp_status = S_ZAPPER; + + if ((Keyboard[sc_X] && !Keyboard[sc_F10]) || Keyboard[sc_Enter]) + temp_status = S_XTER; + + if (control.x) + temp_status = S_TURN; + + if ((Keyboard[sc_V] || Keyboard[sc_Tab]) && control.x) + temp_status = S_QTURN; + + if (Keyboard[sc_Alt] && control.x) + temp_status = S_SIDESTEP; + + if (control.y < 0) + temp_status = S_ADVANCE; + + if (control.y > 0) + temp_status = S_RETREAT; + + if (Keyboard[sc_F5]) + temp_status = S_JOYSTICK; + + if (Keyboard[sc_F4]) + temp_status = S_RESTORING; + + if (Keyboard[sc_F3]) + temp_status = S_SAVING; + + if (Keyboard[sc_F2]) + temp_status = S_SND; + + if (Keyboard[sc_F1]) + temp_status = S_HELP; + + if (temp_status != *stat_flag) + { + *stat_flag = temp_status; + + + switch (*stat_flag) + { + case S_MISSLE: + DisplaySMsg("Magick Missile", NULL); + status_delay = MESSAGEDELAY; + break; + + case S_ZAPPER: + if (gamestate.bolts) + { + DisplaySMsg("Zapper", NULL); + status_delay = MESSAGEDELAY+10; + } + break; + + case S_XTER: + if (gamestate.nukes) + { + DisplaySMsg("Xterminator", NULL); + status_delay = MESSAGEDELAY+5; + } + break; + + case S_TURN: + DisplaySMsg("Turning", NULL); + status_delay = MESSAGEDELAY; + break; + + case S_QTURN: + DisplaySMsg("Quick Turning", NULL); + status_delay = MESSAGEDELAY; + break; + + case S_SIDESTEP: + DisplaySMsg("Sidestepping", NULL); + status_delay = MESSAGEDELAY; + break; + + case S_ADVANCE: + DisplaySMsg("Advancing", NULL); + status_delay = MESSAGEDELAY; + break; + + case S_RETREAT: + DisplaySMsg("Retreating", NULL); + status_delay = MESSAGEDELAY; + break; + + case S_JOYSTICK: + DisplaySMsg("Adjusting Joystick", NULL); + break; + + case S_RESTORING: + DisplaySMsg("Restoring", NULL); + break; + + case S_SAVING: + DisplaySMsg("Saving", NULL); + break; + + case S_SND: + DisplaySMsg("Select Sound", NULL); + break; + + case S_HELP: + DisplaySMsg("Getting Help", NULL); + break; + + case S_VIEWING: + DisplaySMsg("Viewing", NULL); + break; + } + bufferofs = displayofs = screenloc[screenpage]; + + } +}