+++ /dev/null
-// WL_PLAY.C\r
-\r
-#include "WL_DEF.H"\r
-#pragma hdrstop\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
- LOCAL CONSTANTS\r
-\r
-=============================================================================\r
-*/\r
-\r
-#define sc_Question 0x35\r
-\r
-/*\r
-=============================================================================\r
-\r
- GLOBAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-boolean madenoise; // true when shooting or screaming\r
-\r
-exit_t playstate;\r
-\r
-int DebugOk;\r
-\r
-objtype objlist[MAXACTORS],*new,*obj,*player,*lastobj,\r
- *objfreelist,*killerobj;\r
-\r
-unsigned farmapylookup[MAPSIZE];\r
-byte *nearmapylookup[MAPSIZE];\r
-\r
-boolean singlestep,godmode,noclip;\r
-int extravbls;\r
-\r
-byte tilemap[MAPSIZE][MAPSIZE]; // wall values only\r
-byte spotvis[MAPSIZE][MAPSIZE];\r
-objtype *actorat[MAPSIZE][MAPSIZE];\r
-\r
-//\r
-// replacing refresh manager\r
-//\r
-unsigned mapwidth,mapheight,tics;\r
-boolean compatability;\r
-byte *updateptr;\r
-unsigned mapwidthtable[64];\r
-unsigned uwidthtable[UPDATEHIGH];\r
-unsigned blockstarts[UPDATEWIDE*UPDATEHIGH];\r
-//uso: replace: byte update[UPDATESIZE];\r
-//uso: is needed? byte update[UPDATEHIGH][UPDATEWIDE];\r
-\r
-//\r
-// control info\r
-//\r
-boolean mouseenabled,joystickenabled,joypadenabled,joystickprogressive;\r
-int joystickport;\r
-int dirscan[4] = {sc_UpArrow,sc_RightArrow,sc_DownArrow,sc_LeftArrow};\r
-int buttonscan[NUMBUTTONS] =\r
- {sc_Control,sc_Alt,sc_RShift,sc_Space,sc_1,sc_2,sc_3,sc_4};\r
-int buttonmouse[4]={bt_attack,bt_strafe,bt_use,bt_nobutton};\r
-int buttonjoy[4]={bt_attack,bt_strafe,bt_use,bt_run};\r
-\r
-int viewsize;\r
-\r
-boolean buttonheld[NUMBUTTONS];\r
-\r
-boolean demorecord,demoplayback;\r
-char far *demoptr, far *lastdemoptr;\r
-memptr demobuffer;\r
-\r
-//\r
-// curent user input\r
-//\r
-int controlx,controly; // range from -100 to 100 per tic\r
-boolean buttonstate[NUMBUTTONS];\r
-\r
-\r
-\r
-//===========================================================================\r
-\r
-\r
-void CenterWindow(word w,word h);\r
-void InitObjList (void);\r
-void RemoveObj (objtype *gone);\r
-void PollControls (void);\r
-void StopMusic(void);\r
-void StartMusic(void);\r
-void PlayLoop (void);\r
-\r
-/*\r
-=============================================================================\r
-\r
- LOCAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-\r
-objtype dummyobj;\r
-\r
-//\r
-// LIST OF SONGS FOR EACH VERSION\r
-//\r
-int songs[]=\r
-{\r
-#ifndef SPEAR\r
- //\r
- // Episode One\r
- //\r
- GETTHEM_MUS,\r
- SEARCHN_MUS,\r
- POW_MUS,\r
- SUSPENSE_MUS,\r
- GETTHEM_MUS,\r
- SEARCHN_MUS,\r
- POW_MUS,\r
- SUSPENSE_MUS,\r
-\r
- WARMARCH_MUS, // Boss level\r
- CORNER_MUS, // Secret level\r
-\r
- //\r
- // Episode Two\r
- //\r
- NAZI_OMI_MUS,\r
- PREGNANT_MUS,\r
- GOINGAFT_MUS,\r
- HEADACHE_MUS,\r
- NAZI_OMI_MUS,\r
- PREGNANT_MUS,\r
- HEADACHE_MUS,\r
- GOINGAFT_MUS,\r
-\r
- WARMARCH_MUS, // Boss level\r
- DUNGEON_MUS, // Secret level\r
-\r
- //\r
- // Episode Three\r
- //\r
- INTROCW3_MUS,\r
- NAZI_RAP_MUS,\r
- TWELFTH_MUS,\r
- ZEROHOUR_MUS,\r
- INTROCW3_MUS,\r
- NAZI_RAP_MUS,\r
- TWELFTH_MUS,\r
- ZEROHOUR_MUS,\r
-\r
- ULTIMATE_MUS, // Boss level\r
- PACMAN_MUS, // Secret level\r
-\r
- //\r
- // Episode Four\r
- //\r
- GETTHEM_MUS,\r
- SEARCHN_MUS,\r
- POW_MUS,\r
- SUSPENSE_MUS,\r
- GETTHEM_MUS,\r
- SEARCHN_MUS,\r
- POW_MUS,\r
- SUSPENSE_MUS,\r
-\r
- WARMARCH_MUS, // Boss level\r
- CORNER_MUS, // Secret level\r
-\r
- //\r
- // Episode Five\r
- //\r
- NAZI_OMI_MUS,\r
- PREGNANT_MUS,\r
- GOINGAFT_MUS,\r
- HEADACHE_MUS,\r
- NAZI_OMI_MUS,\r
- PREGNANT_MUS,\r
- HEADACHE_MUS,\r
- GOINGAFT_MUS,\r
-\r
- WARMARCH_MUS, // Boss level\r
- DUNGEON_MUS, // Secret level\r
-\r
- //\r
- // Episode Six\r
- //\r
- INTROCW3_MUS,\r
- NAZI_RAP_MUS,\r
- TWELFTH_MUS,\r
- ZEROHOUR_MUS,\r
- INTROCW3_MUS,\r
- NAZI_RAP_MUS,\r
- TWELFTH_MUS,\r
- ZEROHOUR_MUS,\r
-\r
- ULTIMATE_MUS, // Boss level\r
- FUNKYOU_MUS // Secret level\r
-#else\r
-\r
- //////////////////////////////////////////////////////////////\r
- //\r
- // SPEAR OF DESTINY TRACKS\r
- //\r
- //////////////////////////////////////////////////////////////\r
- XTIPTOE_MUS,\r
- XFUNKIE_MUS,\r
- XDEATH_MUS,\r
- XGETYOU_MUS, // DON'T KNOW\r
- ULTIMATE_MUS, // Trans Gr\94sse\r
-\r
- DUNGEON_MUS,\r
- GOINGAFT_MUS,\r
- POW_MUS,\r
- TWELFTH_MUS,\r
- ULTIMATE_MUS, // Barnacle Wilhelm BOSS\r
-\r
- NAZI_OMI_MUS,\r
- GETTHEM_MUS,\r
- SUSPENSE_MUS,\r
- SEARCHN_MUS,\r
- ZEROHOUR_MUS,\r
- ULTIMATE_MUS, // Super Mutant BOSS\r
-\r
- XPUTIT_MUS,\r
- ULTIMATE_MUS, // Death Knight BOSS\r
-\r
- XJAZNAZI_MUS, // Secret level\r
- XFUNKIE_MUS, // Secret level (DON'T KNOW)\r
-\r
- XEVIL_MUS // Angel of Death BOSS\r
-\r
-#endif\r
-};\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
- USER CONTROL\r
-\r
-=============================================================================\r
-*/\r
-\r
-\r
-#define BASEMOVE 35\r
-#define RUNMOVE 70\r
-#define BASETURN 35\r
-#define RUNTURN 70\r
-\r
-#define JOYSCALE 2\r
-\r
-/*\r
-===================\r
-=\r
-= PollKeyboardButtons\r
-=\r
-===================\r
-*/\r
-\r
-void PollKeyboardButtons (void)\r
-{\r
- int i;\r
-\r
- for (i=0;i<NUMBUTTONS;i++)\r
- if (Keyboard[buttonscan[i]])\r
- buttonstate[i] = true;\r
-}\r
-\r
-\r
-/*\r
-===================\r
-=\r
-= PollMouseButtons\r
-=\r
-===================\r
-*/\r
-\r
-void PollMouseButtons (void)\r
-{\r
- int buttons;\r
-\r
- buttons = IN_MouseButtons ();\r
-\r
- if (buttons&1)\r
- buttonstate[buttonmouse[0]] = true;\r
- if (buttons&2)\r
- buttonstate[buttonmouse[1]] = true;\r
- if (buttons&4)\r
- buttonstate[buttonmouse[2]] = true;\r
-}\r
-\r
-\r
-\r
-/*\r
-===================\r
-=\r
-= PollJoystickButtons\r
-=\r
-===================\r
-*/\r
-\r
-void PollJoystickButtons (void)\r
-{\r
- int buttons;\r
-\r
- buttons = IN_JoyButtons ();\r
-\r
- if (joystickport && !joypadenabled)\r
- {\r
- if (buttons&4)\r
- buttonstate[buttonjoy[0]] = true;\r
- if (buttons&8)\r
- buttonstate[buttonjoy[1]] = true;\r
- }\r
- else\r
- {\r
- if (buttons&1)\r
- buttonstate[buttonjoy[0]] = true;\r
- if (buttons&2)\r
- buttonstate[buttonjoy[1]] = true;\r
- if (joypadenabled)\r
- {\r
- if (buttons&4)\r
- buttonstate[buttonjoy[2]] = true;\r
- if (buttons&8)\r
- buttonstate[buttonjoy[3]] = true;\r
- }\r
- }\r
-}\r
-\r
-\r
-/*\r
-===================\r
-=\r
-= PollKeyboardMove\r
-=\r
-===================\r
-*/\r
-\r
-void PollKeyboardMove (void)\r
-{\r
- if (buttonstate[bt_run])\r
- {\r
- if (Keyboard[dirscan[di_north]])\r
- controly -= RUNMOVE*tics;\r
- if (Keyboard[dirscan[di_south]])\r
- controly += RUNMOVE*tics;\r
- if (Keyboard[dirscan[di_west]])\r
- controlx -= RUNMOVE*tics;\r
- if (Keyboard[dirscan[di_east]])\r
- controlx += RUNMOVE*tics;\r
- }\r
- else\r
- {\r
- if (Keyboard[dirscan[di_north]])\r
- controly -= BASEMOVE*tics;\r
- if (Keyboard[dirscan[di_south]])\r
- controly += BASEMOVE*tics;\r
- if (Keyboard[dirscan[di_west]])\r
- controlx -= BASEMOVE*tics;\r
- if (Keyboard[dirscan[di_east]])\r
- controlx += BASEMOVE*tics;\r
- }\r
-}\r
-\r
-\r
-/*\r
-===================\r
-=\r
-= PollMouseMove\r
-=\r
-===================\r
-*/\r
-\r
-void PollMouseMove (void)\r
-{\r
- int mousexmove,mouseymove;\r
-\r
- Mouse(MDelta);\r
- mousexmove = _CX;\r
- mouseymove = _DX;\r
-\r
- controlx += mousexmove*10/(13-mouseadjustment);\r
- controly += mouseymove*20/(13-mouseadjustment);\r
-}\r
-\r
-\r
-\r
-/*\r
-===================\r
-=\r
-= PollJoystickMove\r
-=\r
-===================\r
-*/\r
-\r
-void PollJoystickMove (void)\r
-{\r
- int joyx,joyy;\r
-\r
- INL_GetJoyDelta(joystickport,&joyx,&joyy);\r
-\r
- if (joystickprogressive)\r
- {\r
- if (joyx > 64)\r
- controlx += (joyx-64)*JOYSCALE*tics;\r
- else if (joyx < -64)\r
- controlx -= (-joyx-64)*JOYSCALE*tics;\r
- if (joyy > 64)\r
- controlx += (joyy-64)*JOYSCALE*tics;\r
- else if (joyy < -64)\r
- controly -= (-joyy-64)*JOYSCALE*tics;\r
- }\r
- else if (buttonstate[bt_run])\r
- {\r
- if (joyx > 64)\r
- controlx += RUNMOVE*tics;\r
- else if (joyx < -64)\r
- controlx -= RUNMOVE*tics;\r
- if (joyy > 64)\r
- controly += RUNMOVE*tics;\r
- else if (joyy < -64)\r
- controly -= RUNMOVE*tics;\r
- }\r
- else\r
- {\r
- if (joyx > 64)\r
- controlx += BASEMOVE*tics;\r
- else if (joyx < -64)\r
- controlx -= BASEMOVE*tics;\r
- if (joyy > 64)\r
- controly += BASEMOVE*tics;\r
- else if (joyy < -64)\r
- controly -= BASEMOVE*tics;\r
- }\r
-}\r
-\r
-\r
-/*\r
-===================\r
-=\r
-= PollControls\r
-=\r
-= Gets user or demo input, call once each frame\r
-=\r
-= controlx set between -100 and 100 per tic\r
-= controly\r
-= buttonheld[] the state of the buttons LAST frame\r
-= buttonstate[] the state of the buttons THIS frame\r
-=\r
-===================\r
-*/\r
-\r
-void PollControls (void)\r
-{\r
- int max,min,i;\r
- byte buttonbits;\r
-\r
-//\r
-// get timing info for last frame\r
-//\r
- if (demoplayback)\r
- {\r
- while (TimeCount<lasttimecount+DEMOTICS)\r
- ;\r
- TimeCount = lasttimecount + DEMOTICS;\r
- lasttimecount += DEMOTICS;\r
- tics = DEMOTICS;\r
- }\r
- else if (demorecord) // demo recording and playback needs\r
- { // to be constant\r
-//\r
-// take DEMOTICS or more tics, and modify Timecount to reflect time taken\r
-//\r
- while (TimeCount<lasttimecount+DEMOTICS)\r
- ;\r
- TimeCount = lasttimecount + DEMOTICS;\r
- lasttimecount += DEMOTICS;\r
- tics = DEMOTICS;\r
- }\r
- else\r
- CalcTics ();\r
-\r
- controlx = 0;\r
- controly = 0;\r
- memcpy (buttonheld,buttonstate,sizeof(buttonstate));\r
- memset (buttonstate,0,sizeof(buttonstate));\r
-\r
- if (demoplayback)\r
- {\r
- //\r
- // read commands from demo buffer\r
- //\r
- buttonbits = *demoptr++;\r
- for (i=0;i<NUMBUTTONS;i++)\r
- {\r
- buttonstate[i] = buttonbits&1;\r
- buttonbits >>= 1;\r
- }\r
-\r
- controlx = *demoptr++;\r
- controly = *demoptr++;\r
-\r
- if (demoptr == lastdemoptr)\r
- playstate = ex_completed; // demo is done\r
-\r
- controlx *= (int)tics;\r
- controly *= (int)tics;\r
-\r
- return;\r
- }\r
-\r
-\r
-//\r
-// get button states\r
-//\r
- PollKeyboardButtons ();\r
-\r
- if (mouseenabled)\r
- PollMouseButtons ();\r
-\r
- if (joystickenabled)\r
- PollJoystickButtons ();\r
-\r
-//\r
-// get movements\r
-//\r
- PollKeyboardMove ();\r
-\r
- if (mouseenabled)\r
- PollMouseMove ();\r
-\r
- if (joystickenabled)\r
- PollJoystickMove ();\r
-\r
-//\r
-// bound movement to a maximum\r
-//\r
- max = 100*tics;\r
- min = -max;\r
- if (controlx > max)\r
- controlx = max;\r
- else if (controlx < min)\r
- controlx = min;\r
-\r
- if (controly > max)\r
- controly = max;\r
- else if (controly < min)\r
- controly = min;\r
-\r
- if (demorecord)\r
- {\r
- //\r
- // save info out to demo buffer\r
- //\r
- controlx /= (int)tics;\r
- controly /= (int)tics;\r
-\r
- buttonbits = 0;\r
-\r
- for (i=NUMBUTTONS-1;i>=0;i--)\r
- {\r
- buttonbits <<= 1;\r
- if (buttonstate[i])\r
- buttonbits |= 1;\r
- }\r
-\r
- *demoptr++ = buttonbits;\r
- *demoptr++ = controlx;\r
- *demoptr++ = controly;\r
-\r
- if (demoptr >= lastdemoptr)\r
- Quit ("Demo buffer overflowed!");\r
-\r
- controlx *= (int)tics;\r
- controly *= (int)tics;\r
- }\r
-}\r
-\r
-\r
-\r
-//==========================================================================\r
-\r
-\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// CenterWindow() - Generates a window of a given width & height in the\r
-// middle of the screen\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-\r
-#define MAXX 320\r
-#define MAXY 160\r
-\r
-void CenterWindow(word w,word h)\r
-{\r
- FixOfs ();\r
- US_DrawWindow(((MAXX / 8) - w) / 2,((MAXY / 8) - h) / 2,w,h);\r
-}\r
-\r
-//===========================================================================\r
-\r
-\r
-/*\r
-=====================\r
-=\r
-= CheckKeys\r
-=\r
-=====================\r
-*/\r
-\r
-void CheckKeys (void)\r
-{\r
- int i;\r
- byte scan;\r
- unsigned temp;\r
-\r
-\r
- if (screenfaded || demoplayback) // don't do anything with a faded screen\r
- return;\r
-\r
- scan = LastScan;\r
-\r
-\r
- #ifdef SPEAR\r
- //\r
- // SECRET CHEAT CODE: TAB-G-F10\r
- //\r
- if (Keyboard[sc_Tab] &&\r
- Keyboard[sc_G] &&\r
- Keyboard[sc_F10])\r
- {\r
- WindowH = 160;\r
- if (godmode)\r
- {\r
- Message ("God mode OFF");\r
- SD_PlaySound (NOBONUSSND);\r
- }\r
- else\r
- {\r
- Message ("God mode ON");\r
- SD_PlaySound (ENDBONUS2SND);\r
- }\r
-\r
- IN_Ack();\r
- godmode ^= 1;\r
- DrawAllPlayBorderSides ();\r
- IN_ClearKeysDown();\r
- return;\r
- }\r
- #endif\r
-\r
-\r
- //\r
- // SECRET CHEAT CODE: 'MLI'\r
- //\r
- if (Keyboard[sc_M] &&\r
- Keyboard[sc_L] &&\r
- Keyboard[sc_I])\r
- {\r
- gamestate.health = 100;\r
- gamestate.ammo = 99;\r
- gamestate.keys = 3;\r
- gamestate.score = 0;\r
- gamestate.TimeCount += 42000L;\r
- GiveWeapon (wp_chaingun);\r
-\r
- DrawWeapon();\r
- DrawHealth();\r
- DrawKeys();\r
- DrawAmmo();\r
- DrawScore();\r
-\r
- ClearMemory ();\r
- CA_CacheGrChunk (STARTFONT+1);\r
- ClearSplitVWB ();\r
- VW_ScreenToScreen (displayofs,bufferofs,80,160);\r
-\r
- Message(STR_CHEATER1"\n"\r
- STR_CHEATER2"\n\n"\r
- STR_CHEATER3"\n"\r
- STR_CHEATER4"\n"\r
- STR_CHEATER5);\r
-\r
- UNCACHEGRCHUNK(STARTFONT+1);\r
- PM_CheckMainMem ();\r
- IN_ClearKeysDown();\r
- IN_Ack();\r
-\r
- DrawAllPlayBorder ();\r
- }\r
-\r
- //\r
- // OPEN UP DEBUG KEYS\r
- //\r
-#ifndef SPEAR\r
- if (Keyboard[sc_BackSpace] &&\r
- Keyboard[sc_LShift] &&\r
- Keyboard[sc_Alt] &&\r
- MS_CheckParm("goobers"))\r
-#else\r
- if (Keyboard[sc_BackSpace] &&\r
- Keyboard[sc_LShift] &&\r
- Keyboard[sc_Alt] &&\r
- MS_CheckParm("debugmode"))\r
-#endif\r
- {\r
- ClearMemory ();\r
- CA_CacheGrChunk (STARTFONT+1);\r
- ClearSplitVWB ();\r
- VW_ScreenToScreen (displayofs,bufferofs,80,160);\r
-\r
- Message("Debugging keys are\nnow available!");\r
- UNCACHEGRCHUNK(STARTFONT+1);\r
- PM_CheckMainMem ();\r
- IN_ClearKeysDown();\r
- IN_Ack();\r
-\r
- DrawAllPlayBorderSides ();\r
- DebugOk=1;\r
- }\r
-\r
- //\r
- // TRYING THE KEEN CHEAT CODE!\r
- //\r
- if (Keyboard[sc_B] &&\r
- Keyboard[sc_A] &&\r
- Keyboard[sc_T])\r
- {\r
- ClearMemory ();\r
- CA_CacheGrChunk (STARTFONT+1);\r
- ClearSplitVWB ();\r
- VW_ScreenToScreen (displayofs,bufferofs,80,160);\r
-\r
- Message("Commander Keen is also\n"\r
- "available from Apogee, but\n"\r
- "then, you already know\n"\r
- "that - right, Cheatmeister?!");\r
-\r
- UNCACHEGRCHUNK(STARTFONT+1);\r
- PM_CheckMainMem ();\r
- IN_ClearKeysDown();\r
- IN_Ack();\r
-\r
- DrawAllPlayBorder ();\r
- }\r
-\r
-//\r
-// pause key weirdness can't be checked as a scan code\r
-//\r
- if (Paused)\r
- {\r
- bufferofs = displayofs;\r
- LatchDrawPic (20-4,80-2*8,PAUSEDPIC);\r
- SD_MusicOff();\r
- IN_Ack();\r
- IN_ClearKeysDown ();\r
- SD_MusicOn();\r
- Paused = false;\r
- if (MousePresent)\r
- Mouse(MDelta); // Clear accumulated mouse movement\r
- return;\r
- }\r
-\r
-\r
-//\r
-// F1-F7/ESC to enter control panel\r
-//\r
- if (\r
-#ifndef DEBCHECK\r
- scan == sc_F10 ||\r
-#endif\r
- scan == sc_F9 ||\r
- scan == sc_F7 ||\r
- scan == sc_F8) // pop up quit dialog\r
- {\r
- ClearMemory ();\r
- ClearSplitVWB ();\r
- VW_ScreenToScreen (displayofs,bufferofs,80,160);\r
- US_ControlPanel(scan);\r
-\r
- DrawAllPlayBorderSides ();\r
-\r
- if (scan == sc_F9)\r
- StartMusic ();\r
-\r
- PM_CheckMainMem ();\r
- SETFONTCOLOR(0,15);\r
- IN_ClearKeysDown();\r
- return;\r
- }\r
-\r
- if ( (scan >= sc_F1 && scan <= sc_F9) || scan == sc_Escape)\r
- {\r
- StopMusic ();\r
- ClearMemory ();\r
- VW_FadeOut ();\r
-\r
- US_ControlPanel(scan);\r
-\r
- SETFONTCOLOR(0,15);\r
- IN_ClearKeysDown();\r
- DrawPlayScreen ();\r
- if (!startgame && !loadedgame)\r
- {\r
- VW_FadeIn ();\r
- StartMusic ();\r
- }\r
- if (loadedgame)\r
- playstate = ex_abort;\r
- lasttimecount = TimeCount;\r
- if (MousePresent)\r
- Mouse(MDelta); // Clear accumulated mouse movement\r
- PM_CheckMainMem ();\r
- return;\r
- }\r
-\r
-//\r
-// TAB-? debug keys\r
-//\r
- if (Keyboard[sc_Tab] && DebugOk)\r
- {\r
- CA_CacheGrChunk (STARTFONT);\r
- fontnumber=0;\r
- SETFONTCOLOR(0,15);\r
- DebugKeys();\r
- if (MousePresent)\r
- Mouse(MDelta); // Clear accumulated mouse movement\r
- lasttimecount = TimeCount;\r
- return;\r
- }\r
-\r
-}\r
-\r
-\r
-//===========================================================================\r
-\r
-/*\r
-#############################################################################\r
-\r
- The objlist data structure\r
-\r
-#############################################################################\r
-\r
-objlist containt structures for every actor currently playing. The structure\r
-is accessed as a linked list starting at *player, ending when ob->next ==\r
-NULL. GetNewObj inserts a new object at the end of the list, meaning that\r
-if an actor spawn another actor, the new one WILL get to think and react the\r
-same frame. RemoveObj unlinks the given object and returns it to the free\r
-list, but does not damage the objects ->next pointer, so if the current object\r
-removes itself, a linked list following loop can still safely get to the\r
-next element.\r
-\r
-<backwardly linked free list>\r
-\r
-#############################################################################\r
-*/\r
-\r
-\r
-/*\r
-=========================\r
-=\r
-= InitActorList\r
-=\r
-= Call to clear out the actor object lists returning them all to the free\r
-= list. Allocates a special spot for the player.\r
-=\r
-=========================\r
-*/\r
-\r
-int objcount;\r
-\r
-void InitActorList (void)\r
-{\r
- int i;\r
-\r
-//\r
-// init the actor lists\r
-//\r
- for (i=0;i<MAXACTORS;i++)\r
- {\r
- objlist[i].prev = &objlist[i+1];\r
- objlist[i].next = NULL;\r
- }\r
-\r
- objlist[MAXACTORS-1].prev = NULL;\r
-\r
- objfreelist = &objlist[0];\r
- lastobj = NULL;\r
-\r
- objcount = 0;\r
-\r
-//\r
-// give the player the first free spots\r
-//\r
- GetNewActor ();\r
- player = new;\r
-\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=========================\r
-=\r
-= GetNewActor\r
-=\r
-= Sets the global variable new to point to a free spot in objlist.\r
-= The free spot is inserted at the end of the liked list\r
-=\r
-= When the object list is full, the caller can either have it bomb out ot\r
-= return a dummy object pointer that will never get used\r
-=\r
-=========================\r
-*/\r
-\r
-void GetNewActor (void)\r
-{\r
- if (!objfreelist)\r
- Quit ("GetNewActor: No free spots in objlist!");\r
-\r
- new = objfreelist;\r
- objfreelist = new->prev;\r
- memset (new,0,sizeof(*new));\r
-\r
- if (lastobj)\r
- lastobj->next = new;\r
- new->prev = lastobj; // new->next is allready NULL from memset\r
-\r
- new->active = false;\r
- lastobj = new;\r
-\r
- objcount++;\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=========================\r
-=\r
-= RemoveObj\r
-=\r
-= Add the given object back into the free list, and unlink it from it's\r
-= neighbors\r
-=\r
-=========================\r
-*/\r
-\r
-void RemoveObj (objtype *gone)\r
-{\r
- objtype **spotat;\r
-\r
- if (gone == player)\r
- Quit ("RemoveObj: Tried to remove the player!");\r
-\r
- gone->state = NULL;\r
-\r
-//\r
-// fix the next object's back link\r
-//\r
- if (gone == lastobj)\r
- lastobj = (objtype *)gone->prev;\r
- else\r
- gone->next->prev = gone->prev;\r
-\r
-//\r
-// fix the previous object's forward link\r
-//\r
- gone->prev->next = gone->next;\r
-\r
-//\r
-// add it back in to the free list\r
-//\r
- gone->prev = objfreelist;\r
- objfreelist = gone;\r
-\r
- objcount--;\r
-}\r
-\r
-/*\r
-=============================================================================\r
-\r
- MUSIC STUFF\r
-\r
-=============================================================================\r
-*/\r
-\r
-\r
-/*\r
-=================\r
-=\r
-= StopMusic\r
-=\r
-=================\r
-*/\r
-\r
-void StopMusic(void)\r
-{\r
- int i;\r
-\r
- SD_MusicOff();\r
- for (i = 0;i < LASTMUSIC;i++)\r
- if (audiosegs[STARTMUSIC + i])\r
- {\r
- MM_SetPurge(&((memptr)audiosegs[STARTMUSIC + i]),3);\r
- MM_SetLock(&((memptr)audiosegs[STARTMUSIC + i]),false);\r
- }\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-=================\r
-=\r
-= StartMusic\r
-=\r
-=================\r
-*/\r
-\r
-void StartMusic(void)\r
-{\r
- musicnames chunk;\r
-\r
- SD_MusicOff();\r
- chunk = songs[gamestate.mapon+gamestate.episode*10];\r
-\r
-// if ((chunk == -1) || (MusicMode != smm_AdLib))\r
-//DEBUG control panel return;\r
-\r
- MM_BombOnError (false);\r
- CA_CacheAudioChunk(STARTMUSIC + chunk);\r
- MM_BombOnError (true);\r
- if (mmerror)\r
- mmerror = false;\r
- else\r
- {\r
- MM_SetLock(&((memptr)audiosegs[STARTMUSIC + chunk]),true);\r
- SD_StartMusic((MusicGroup far *)audiosegs[STARTMUSIC + chunk]);\r
- }\r
-}\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
- PALETTE SHIFTING STUFF\r
-\r
-=============================================================================\r
-*/\r
-\r
-#define NUMREDSHIFTS 6\r
-#define REDSTEPS 8\r
-\r
-#define NUMWHITESHIFTS 3\r
-#define WHITESTEPS 20\r
-#define WHITETICS 6\r
-\r
-\r
-byte far redshifts[NUMREDSHIFTS][768];\r
-byte far whiteshifts[NUMREDSHIFTS][768];\r
-\r
-int damagecount,bonuscount;\r
-boolean palshifted;\r
-\r
-extern byte far gamepal;\r
-\r
-/*\r
-=====================\r
-=\r
-= InitRedShifts\r
-=\r
-=====================\r
-*/\r
-\r
-void InitRedShifts (void)\r
-{\r
- byte far *workptr, far *baseptr;\r
- int i,j,delta;\r
-\r
-\r
-//\r
-// fade through intermediate frames\r
-//\r
- for (i=1;i<=NUMREDSHIFTS;i++)\r
- {\r
- workptr = (byte far *)&redshifts[i-1][0];\r
- baseptr = &gamepal;\r
-\r
- for (j=0;j<=255;j++)\r
- {\r
- delta = 64-*baseptr;\r
- *workptr++ = *baseptr++ + delta * i / REDSTEPS;\r
- delta = -*baseptr;\r
- *workptr++ = *baseptr++ + delta * i / REDSTEPS;\r
- delta = -*baseptr;\r
- *workptr++ = *baseptr++ + delta * i / REDSTEPS;\r
- }\r
- }\r
-\r
- for (i=1;i<=NUMWHITESHIFTS;i++)\r
- {\r
- workptr = (byte far *)&whiteshifts[i-1][0];\r
- baseptr = &gamepal;\r
-\r
- for (j=0;j<=255;j++)\r
- {\r
- delta = 64-*baseptr;\r
- *workptr++ = *baseptr++ + delta * i / WHITESTEPS;\r
- delta = 62-*baseptr;\r
- *workptr++ = *baseptr++ + delta * i / WHITESTEPS;\r
- delta = 0-*baseptr;\r
- *workptr++ = *baseptr++ + delta * i / WHITESTEPS;\r
- }\r
- }\r
-}\r
-\r
-\r
-/*\r
-=====================\r
-=\r
-= ClearPaletteShifts\r
-=\r
-=====================\r
-*/\r
-\r
-void ClearPaletteShifts (void)\r
-{\r
- bonuscount = damagecount = 0;\r
-}\r
-\r
-\r
-/*\r
-=====================\r
-=\r
-= StartBonusFlash\r
-=\r
-=====================\r
-*/\r
-\r
-void StartBonusFlash (void)\r
-{\r
- bonuscount = NUMWHITESHIFTS*WHITETICS; // white shift palette\r
-}\r
-\r
-\r
-/*\r
-=====================\r
-=\r
-= StartDamageFlash\r
-=\r
-=====================\r
-*/\r
-\r
-void StartDamageFlash (int damage)\r
-{\r
- damagecount += damage;\r
-}\r
-\r
-\r
-/*\r
-=====================\r
-=\r
-= UpdatePaletteShifts\r
-=\r
-=====================\r
-*/\r
-\r
-void UpdatePaletteShifts (void)\r
-{\r
- int red,white;\r
-\r
- if (bonuscount)\r
- {\r
- white = bonuscount/WHITETICS +1;\r
- if (white>NUMWHITESHIFTS)\r
- white = NUMWHITESHIFTS;\r
- bonuscount -= tics;\r
- if (bonuscount < 0)\r
- bonuscount = 0;\r
- }\r
- else\r
- white = 0;\r
-\r
-\r
- if (damagecount)\r
- {\r
- red = damagecount/10 +1;\r
- if (red>NUMREDSHIFTS)\r
- red = NUMREDSHIFTS;\r
-\r
- damagecount -= tics;\r
- if (damagecount < 0)\r
- damagecount = 0;\r
- }\r
- else\r
- red = 0;\r
-\r
- if (red)\r
- {\r
- VW_WaitVBL(1);\r
- VL_SetPalette (redshifts[red-1]);\r
- palshifted = true;\r
- }\r
- else if (white)\r
- {\r
- VW_WaitVBL(1);\r
- VL_SetPalette (whiteshifts[white-1]);\r
- palshifted = true;\r
- }\r
- else if (palshifted)\r
- {\r
- VW_WaitVBL(1);\r
- VL_SetPalette (&gamepal); // back to normal\r
- palshifted = false;\r
- }\r
-}\r
-\r
-\r
-/*\r
-=====================\r
-=\r
-= FinishPaletteShifts\r
-=\r
-= Resets palette to normal if needed\r
-=\r
-=====================\r
-*/\r
-\r
-void FinishPaletteShifts (void)\r
-{\r
- if (palshifted)\r
- {\r
- palshifted = 0;\r
- VW_WaitVBL(1);\r
- VL_SetPalette (&gamepal);\r
- }\r
-}\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
- CORE PLAYLOOP\r
-\r
-=============================================================================\r
-*/\r
-\r
-\r
-/*\r
-=====================\r
-=\r
-= DoActor\r
-=\r
-=====================\r
-*/\r
-\r
-void DoActor (objtype *ob)\r
-{\r
- void (*think)(objtype *);\r
-\r
- if (!ob->active && !areabyplayer[ob->areanumber])\r
- return;\r
-\r
- if (!(ob->flags&(FL_NONMARK|FL_NEVERMARK)) )\r
- actorat[ob->tilex][ob->tiley] = NULL;\r
-\r
-//\r
-// non transitional object\r
-//\r
-\r
- if (!ob->ticcount)\r
- {\r
- think = ob->state->think;\r
- if (think)\r
- {\r
- think (ob);\r
- if (!ob->state)\r
- {\r
- RemoveObj (ob);\r
- return;\r
- }\r
- }\r
-\r
- if (ob->flags&FL_NEVERMARK)\r
- return;\r
-\r
- if ( (ob->flags&FL_NONMARK) && actorat[ob->tilex][ob->tiley])\r
- return;\r
-\r
- actorat[ob->tilex][ob->tiley] = ob;\r
- return;\r
- }\r
-\r
-//\r
-// transitional object\r
-//\r
- ob->ticcount-=tics;\r
- while ( ob->ticcount <= 0)\r
- {\r
- think = ob->state->action; // end of state action\r
- if (think)\r
- {\r
- think (ob);\r
- if (!ob->state)\r
- {\r
- RemoveObj (ob);\r
- return;\r
- }\r
- }\r
-\r
- ob->state = ob->state->next;\r
-\r
- if (!ob->state)\r
- {\r
- RemoveObj (ob);\r
- return;\r
- }\r
-\r
- if (!ob->state->tictime)\r
- {\r
- ob->ticcount = 0;\r
- goto think;\r
- }\r
-\r
- ob->ticcount += ob->state->tictime;\r
- }\r
-\r
-think:\r
- //\r
- // think\r
- //\r
- think = ob->state->think;\r
- if (think)\r
- {\r
- think (ob);\r
- if (!ob->state)\r
- {\r
- RemoveObj (ob);\r
- return;\r
- }\r
- }\r
-\r
- if (ob->flags&FL_NEVERMARK)\r
- return;\r
-\r
- if ( (ob->flags&FL_NONMARK) && actorat[ob->tilex][ob->tiley])\r
- return;\r
-\r
- actorat[ob->tilex][ob->tiley] = ob;\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-===================\r
-=\r
-= PlayLoop\r
-=\r
-===================\r
-*/\r
-long funnyticount;\r
-\r
-\r
-void PlayLoop (void)\r
-{\r
- int give;\r
- int helmetangle;\r
-\r
- playstate = TimeCount = lasttimecount = 0;\r
- frameon = 0;\r
- running = false;\r
- anglefrac = 0;\r
- facecount = 0;\r
- funnyticount = 0;\r
- memset (buttonstate,0,sizeof(buttonstate));\r
- ClearPaletteShifts ();\r
-\r
- if (MousePresent)\r
- Mouse(MDelta); // Clear accumulated mouse movement\r
-\r
- if (demoplayback)\r
- IN_StartAck ();\r
-\r
- do\r
- {\r
- if (virtualreality)\r
- {\r
- helmetangle = peek (0x40,0xf0);\r
- player->angle += helmetangle;\r
- if (player->angle >= ANGLES)\r
- player->angle -= ANGLES;\r
- }\r
-\r
-\r
- PollControls();\r
-\r
-//\r
-// actor thinking\r
-//\r
- madenoise = false;\r
-\r
- MoveDoors ();\r
- MovePWalls ();\r
-\r
- for (obj = player;obj;obj = obj->next)\r
- DoActor (obj);\r
-\r
- UpdatePaletteShifts ();\r
-\r
- ThreeDRefresh ();\r
-\r
- //\r
- // MAKE FUNNY FACE IF BJ DOESN'T MOVE FOR AWHILE\r
- //\r
- #ifdef SPEAR\r
- funnyticount += tics;\r
- if (funnyticount > 30l*70)\r
- {\r
- funnyticount = 0;\r
- StatusDrawPic (17,4,BJWAITING1PIC+(US_RndT()&1));\r
- facecount = 0;\r
- }\r
- #endif\r
-\r
- gamestate.TimeCount+=tics;\r
-\r
- SD_Poll ();\r
- UpdateSoundLoc(); // JAB\r
-\r
- if (screenfaded)\r
- VW_FadeIn ();\r
-\r
- CheckKeys();\r
-\r
-//\r
-// debug aids\r
-//\r
- if (singlestep)\r
- {\r
- VW_WaitVBL(14);\r
- lasttimecount = TimeCount;\r
- }\r
- if (extravbls)\r
- VW_WaitVBL(extravbls);\r
-\r
- if (demoplayback)\r
- {\r
- if (IN_CheckAck ())\r
- {\r
- IN_ClearKeysDown ();\r
- playstate = ex_abort;\r
- }\r
- }\r
-\r
-\r
- if (virtualreality)\r
- {\r
- player->angle -= helmetangle;\r
- if (player->angle < 0)\r
- player->angle += ANGLES;\r
- }\r
-\r
- }while (!playstate && !startgame);\r
-\r
- if (playstate != ex_died)\r
- FinishPaletteShifts ();\r
-}\r
-\r