// WL_PLAY.C
#include "WL_DEF.H"
#pragma hdrstop
/*
=============================================================================
LOCAL CONSTANTS
=============================================================================
*/
#define sc_Question 0x35
/*
=============================================================================
GLOBAL VARIABLES
=============================================================================
*/
boolean madenoise; // true when shooting or screaming
exit_t playstate;
int DebugOk;
objtype objlist[MAXACTORS],*new,*obj,*player,*lastobj,
*objfreelist,*killerobj;
unsigned farmapylookup[MAPSIZE];
byte *nearmapylookup[MAPSIZE];
boolean singlestep,godmode,noclip;
int extravbls;
byte tilemap[MAPSIZE][MAPSIZE]; // wall values only
byte spotvis[MAPSIZE][MAPSIZE];
objtype *actorat[MAPSIZE][MAPSIZE];
//
// replacing refresh manager
//
unsigned mapwidth,mapheight,tics;
boolean compatability;
byte *updateptr;
unsigned mapwidthtable[64];
unsigned uwidthtable[UPDATEHIGH];
unsigned blockstarts[UPDATEWIDE*UPDATEHIGH];
byte update[UPDATESIZE];
//
// control info
//
boolean mouseenabled,joystickenabled,joypadenabled,joystickprogressive;
int joystickport;
int dirscan[4] = {sc_UpArrow,sc_RightArrow,sc_DownArrow,sc_LeftArrow};
int buttonscan[NUMBUTTONS] =
{sc_Control,sc_Alt,sc_RShift,sc_Space,sc_1,sc_2,sc_3,sc_4};
int buttonmouse[4]={bt_attack,bt_strafe,bt_use,bt_nobutton};
int buttonjoy[4]={bt_attack,bt_strafe,bt_use,bt_run};
int viewsize;
boolean buttonheld[NUMBUTTONS];
boolean demorecord,demoplayback;
char far *demoptr, far *lastdemoptr;
memptr demobuffer;
//
// curent user input
//
int controlx,controly; // range from -100 to 100 per tic
boolean buttonstate[NUMBUTTONS];
//===========================================================================
void CenterWindow(word w,word h);
void InitObjList (void);
void RemoveObj (objtype *gone);
void PollControls (void);
void StopMusic(void);
void StartMusic(void);
void PlayLoop (void);
/*
=============================================================================
LOCAL VARIABLES
=============================================================================
*/
objtype dummyobj;
//
// LIST OF SONGS FOR EACH VERSION
//
int songs[]=
{
#ifndef SPEAR
//
// Episode One
//
GETTHEM_MUS,
SEARCHN_MUS,
POW_MUS,
SUSPENSE_MUS,
GETTHEM_MUS,
SEARCHN_MUS,
POW_MUS,
SUSPENSE_MUS,
WARMARCH_MUS, // Boss level
CORNER_MUS, // Secret level
//
// Episode Two
//
NAZI_OMI_MUS,
PREGNANT_MUS,
GOINGAFT_MUS,
HEADACHE_MUS,
NAZI_OMI_MUS,
PREGNANT_MUS,
HEADACHE_MUS,
GOINGAFT_MUS,
WARMARCH_MUS, // Boss level
DUNGEON_MUS, // Secret level
//
// Episode Three
//
INTROCW3_MUS,
NAZI_RAP_MUS,
TWELFTH_MUS,
ZEROHOUR_MUS,
INTROCW3_MUS,
NAZI_RAP_MUS,
TWELFTH_MUS,
ZEROHOUR_MUS,
ULTIMATE_MUS, // Boss level
PACMAN_MUS, // Secret level
//
// Episode Four
//
GETTHEM_MUS,
SEARCHN_MUS,
POW_MUS,
SUSPENSE_MUS,
GETTHEM_MUS,
SEARCHN_MUS,
POW_MUS,
SUSPENSE_MUS,
WARMARCH_MUS, // Boss level
CORNER_MUS, // Secret level
//
// Episode Five
//
NAZI_OMI_MUS,
PREGNANT_MUS,
GOINGAFT_MUS,
HEADACHE_MUS,
NAZI_OMI_MUS,
PREGNANT_MUS,
HEADACHE_MUS,
GOINGAFT_MUS,
WARMARCH_MUS, // Boss level
DUNGEON_MUS, // Secret level
//
// Episode Six
//
INTROCW3_MUS,
NAZI_RAP_MUS,
TWELFTH_MUS,
ZEROHOUR_MUS,
INTROCW3_MUS,
NAZI_RAP_MUS,
TWELFTH_MUS,
ZEROHOUR_MUS,
ULTIMATE_MUS, // Boss level
FUNKYOU_MUS // Secret level
#else
//////////////////////////////////////////////////////////////
//
// SPEAR OF DESTINY TRACKS
//
//////////////////////////////////////////////////////////////
XTIPTOE_MUS,
XFUNKIE_MUS,
XDEATH_MUS,
XGETYOU_MUS, // DON'T KNOW
ULTIMATE_MUS, // Trans Gr”sse
DUNGEON_MUS,
GOINGAFT_MUS,
POW_MUS,
TWELFTH_MUS,
ULTIMATE_MUS, // Barnacle Wilhelm BOSS
NAZI_OMI_MUS,
GETTHEM_MUS,
SUSPENSE_MUS,
SEARCHN_MUS,
ZEROHOUR_MUS,
ULTIMATE_MUS, // Super Mutant BOSS
XPUTIT_MUS,
ULTIMATE_MUS, // Death Knight BOSS
XJAZNAZI_MUS, // Secret level
XFUNKIE_MUS, // Secret level (DON'T KNOW)
XEVIL_MUS // Angel of Death BOSS
#endif
};
/*
=============================================================================
USER CONTROL
=============================================================================
*/
#define BASEMOVE 35
#define RUNMOVE 70
#define BASETURN 35
#define RUNTURN 70
#define JOYSCALE 2
/*
===================
=
= PollKeyboardButtons
=
===================
*/
void PollKeyboardButtons (void)
{
int i;
for (i=0;iNUMBUTTONS;i++)
if (Keyboard[buttonscan[i]])
buttonstate[i] = true;
}
/*
===================
=
= PollMouseButtons
=
===================
*/
void PollMouseButtons (void)
{
int buttons;
buttons = IN_MouseButtons ();
if (buttons&1)
buttonstate[buttonmouse[0]] = true;
if (buttons&2)
buttonstate[buttonmouse[1]] = true;
if (buttons&4)
buttonstate[buttonmouse[2]] = true;
}
/*
===================
=
= PollJoystickButtons
=
===================
*/
void PollJoystickButtons (void)
{
int buttons;
buttons = IN_JoyButtons ();
if (joystickport && !joypadenabled)
{
if (buttons&4)
buttonstate[buttonjoy[0]] = true;
if (buttons&8)
buttonstate[buttonjoy[1]] = true;
}
else
{
if (buttons&1)
buttonstate[buttonjoy[0]] = true;
if (buttons&2)
buttonstate[buttonjoy[1]] = true;
if (joypadenabled)
{
if (buttons&4)
buttonstate[buttonjoy[2]] = true;
if (buttons&8)
buttonstate[buttonjoy[3]] = true;
}
}
}
/*
===================
=
= PollKeyboardMove
=
===================
*/
void PollKeyboardMove (void)
{
if (buttonstate[bt_run])
{
if (Keyboard[dirscan[di_north]])
controly -= RUNMOVE*tics;
if (Keyboard[dirscan[di_south]])
controly += RUNMOVE*tics;
if (Keyboard[dirscan[di_west]])
controlx -= RUNMOVE*tics;
if (Keyboard[dirscan[di_east]])
controlx += RUNMOVE*tics;
}
else
{
if (Keyboard[dirscan[di_north]])
controly -= BASEMOVE*tics;
if (Keyboard[dirscan[di_south]])
controly += BASEMOVE*tics;
if (Keyboard[dirscan[di_west]])
controlx -= BASEMOVE*tics;
if (Keyboard[dirscan[di_east]])
controlx += BASEMOVE*tics;
}
}
/*
===================
=
= PollMouseMove
=
===================
*/
void PollMouseMove (void)
{
int mousexmove,mouseymove;
Mouse(MDelta);
mousexmove = _CX;
mouseymove = _DX;
controlx += mousexmove*10/(13-mouseadjustment);
controly += mouseymove*20/(13-mouseadjustment);
}
/*
===================
=
= PollJoystickMove
=
===================
*/
void PollJoystickMove (void)
{
int joyx,joyy;
INL_GetJoyDelta(joystickport,&joyx,&joyy);
if (joystickprogressive)
{
if (joyx > 64)
controlx += (joyx-64)*JOYSCALE*tics;
else if (joyx -64)
controlx -= (-joyx-64)*JOYSCALE*tics;
if (joyy > 64)
controlx += (joyy-64)*JOYSCALE*tics;
else if (joyy -64)
controly -= (-joyy-64)*JOYSCALE*tics;
}
else if (buttonstate[bt_run])
{
if (joyx > 64)
controlx += RUNMOVE*tics;
else if (joyx -64)
controlx -= RUNMOVE*tics;
if (joyy > 64)
controly += RUNMOVE*tics;
else if (joyy -64)
controly -= RUNMOVE*tics;
}
else
{
if (joyx > 64)
controlx += BASEMOVE*tics;
else if (joyx -64)
controlx -= BASEMOVE*tics;
if (joyy > 64)
controly += BASEMOVE*tics;
else if (joyy -64)
controly -= BASEMOVE*tics;
}
}
/*
===================
=
= PollControls
=
= Gets user or demo input, call once each frame
=
= controlx set between -100 and 100 per tic
= controly
= buttonheld[] the state of the buttons LAST frame
= buttonstate[] the state of the buttons THIS frame
=
===================
*/
void PollControls (void)
{
int max,min,i;
byte buttonbits;
//
// get timing info for last frame
//
if (demoplayback)
{
while (TimeCount(lasttimecount+DEMOTICS)
;
TimeCount = lasttimecount + DEMOTICS;
lasttimecount += DEMOTICS;
tics = DEMOTICS;
}
else if (demorecord) // demo recording and playback needs
{ // to be constant
//
>// take DEMOTICS or more tics, and modify Timecount to reflect time taken
//
while (TimeCount(lasttimecount+DEMOTICS)
;
TimeCount = lasttimecount + DEMOTICS;
lasttimecount += DEMOTICS;
tics = DEMOTICS;
}
else
CalcTics ();
controlx = 0;
controly = 0;
memcpy (buttonheld,buttonstate,sizeof(buttonstate));
memset (buttonstate,0,sizeof(buttonstate));
if (demoplayback)
{
//
// read commands from demo buffer
//
buttonbits = *demoptr++;
for (i=0;i NUMBUTTONS;i++)
{
buttonstate[i] = buttonbits&1;
buttonbits >>= 1;
}
controlx = *demoptr++;
controly = *demoptr++;
if (demoptr == lastdemoptr)
playstate = ex_completed; // demo is done
controlx *= (int)tics;
controly *= (int)tics;
return;
}
//
// get button states
//
PollKeyboardButtons ();
if (mouseenabled)
PollMouseButtons ();
if (joystickenabled)
PollJoystickButtons ();
//
// get movements
//
PollKeyboardMove ();
if (mouseenabled)
PollMouseMove ();
if (joystickenabled)
PollJoystickMove ();
//
// bound movement to a maximum
//
max = 100*tics;
min = -max;
if (controlx > max)
controlx = max;
else if (controlx min)
controlx = min;
if (controly > max)
controly = max;
else if (controly min)
controly = min;
if (demorecord)
{
//
// save info out to demo buffer
//
controlx /= (int)tics;
controly /= (int)tics;
buttonbits = 0;
for (i=NUMBUTTONS-1;i>=0;i--)
{
buttonbits = 1;
if (buttonstate[i])
buttonbits |= 1;
}
*demoptr++ = buttonbits;
*demoptr++ = controlx;
*demoptr++ = controly;
if (demoptr >= lastdemoptr)
Quit ("Demo buffer overflowed!");
controlx *= (int)tics;
controly *= (int)tics;
}
}
//==========================================================================
///////////////////////////////////////////////////////////////////////////
//
// CenterWindow() - Generates a window of a given width & height in the
// middle of the screen
//
///////////////////////////////////////////////////////////////////////////
#define MAXX 320
#define MAXY 160
void CenterWindow(word w,word h)
{
FixOfs ();
US_DrawWindow(((MAXX / 8) - w) / 2,((MAXY / 8) - h) / 2,w,h);
}
//===========================================================================
/*
=====================
=
= CheckKeys
=
=====================
*/
void CheckKeys (void)
{
int i;
byte scan;
unsigned temp;
if (screenfaded || demoplayback) // don't do anything with a faded screen
return;
scan = LastScan;
#ifdef SPEAR
//
// SECRET CHEAT CODE: TAB-G-F10
//
if (Keyboard[sc_Tab] &&
Keyboard[sc_G] &&
Keyboard[sc_F10])
{
WindowH = 160;
if (godmode)
{
Message ("God mode OFF");
SD_PlaySound (NOBONUSSND);
}
else
{
Message ("God mode ON");
SD_PlaySound (ENDBONUS2SND);
}
IN_Ack();
godmode ^= 1;
DrawAllPlayBorderSides ();
IN_ClearKeysDown();
return;
}
#endif
//
// SECRET CHEAT CODE: 'MLI'
//
if (Keyboard[sc_M] &&
Keyboard[sc_L] &&
Keyboard[sc_I])
{
gamestate.health = 100;
gamestate.ammo = 99;
gamestate.keys = 3;
gamestate.score = 0;
gamestate.TimeCount += 42000L;
GiveWeapon (wp_chaingun);
DrawWeapon();
DrawHealth();
DrawKeys();
DrawAmmo();
DrawScore();
ClearMemory ();
CA_CacheGrChunk (STARTFONT+1);
ClearSplitVWB ();
VW_ScreenToScreen (displayofs,bufferofs,80,160);
Message(STR_CHEATER1"\n" XXXXXXXXXXXXX
STR_CHEATER2"\n\n""_";modf
STR_CHEATER3"\n""_";modf
STR_CHEATER4"\n""_";modf
STR_CHEATER5);
UNCACHEGRCHUNK(STARTFONT+1);
PM_CheckMainMem ();
IN_ClearKeysDown();
IN_Ack();
DrawAllPlayBorder ();
}
//
// OPEN UP DEBUG KEYS
//
#ifndef SPEAR
if (Keyboard[sc_BackSpace] &&
Keyboard[sc_LShift] &&
Keyboard[sc_Alt] &&
MS_CheckParm("goobers"))
#else
if (Keyboard[sc_BackSpace] &&
Keyboard[sc_LShift] &&
Keyboard[sc_Alt] &&
MS_CheckParm("debugmode"))
#endif
{
ClearMemory ();
CA_CacheGrChunk (STARTFONT+1);
ClearSplitVWB ();
VW_ScreenToScreen (displayofs,bufferofs,80,160);
Message("Debugging keys are\nnow available!");
UNCACHEGRCHUNK(STARTFONT+1);
PM_CheckMainMem ();
IN_ClearKeysDown();
IN_Ack();
DrawAllPlayBorderSides ();
DebugOk=1;
}
//
// TRYING THE KEEN CHEAT CODE!
//
if (Keyboard[sc_B] &&
Keyboard[sc_A] &&
Keyboard[sc_T])
{
ClearMemory ();
CA_CacheGrChunk (STARTFONT+1);
ClearSplitVWB ();
VW_ScreenToScreen (displayofs,bufferofs,80,160);
Message("-----\n" XXXXXXXXXXXXX
"-----\n" XXXXXXXXXXXXX
"-----\n" XXXXXXXXXXXXX
"-----"); XXXXXXXXXXXXX
UNCACHEGRCHUNK(STARTFONT+1);
PM_CheckMainMem ();
IN_ClearKeysDown();
IN_Ack();
DrawAllPlayBorder ();
}
//
// pause key weirdness can't be checked as a scan code
//
if (Paused)
{
bufferofs = displayofs;
LatchDrawPic (20-4,80-2*8,PAUSEDPIC);
SD_MusicOff();
IN_Ack();
IN_ClearKeysDown ();
SD_MusicOn();
Paused = false;
if (MousePresent)
Mouse(MDelta); // Clear accumulated mouse movement
return;
}
//
// F1-F7/ESC to enter control panel
//
if (
#ifndef DEBCHECK
scan == sc_F10 ||
#endif
scan == sc_F9 ||
scan == sc_F7 ||
scan == sc_F8) // pop up quit dialog
{
ClearMemory ();
ClearSplitVWB ();
VW_ScreenToScreen (displayofs,bufferofs,80,160);
US_ControlPanel(scan);
DrawAllPlayBorderSides ();
if (scan == sc_F9)
StartMusic ();
PM_CheckMainMem ();
SETFONTCOLOR(0,15);
IN_ClearKeysDown();
return;
}
if ( (scan >= sc_F1 && scan = sc_F9) || scan == sc_Escape)
{
StopMusic ();
ClearMemory ();
VW_FadeOut ();
US_ControlPanel(scan);
SETFONTCOLOR(0,15); XXXXXXXXXXXXX
IN_ClearKeysDown();
DrawPlayScreen ();
if (!startgame && !loadedgame)
{
VW_FadeIn ();
StartMusic ();
}
if (loadedgame)
playstate = ex_abort;
lasttimecount = TimeCount;
if (MousePresent)
Mouse(MDelta); // Clear accumulated mouse movement
PM_CheckMainMem ();
return;
}
//
// TAB-? debug keys
//
if (Keyboard[sc_Tab] && DebugOk)
{
CA_CacheGrChunk (STARTFONT);
fontnumber=0;
SETFONTCOLOR(0,15); XXXXXXXXXXXXX
DebugKeys();
if (MousePresent)
Mouse(MDelta); // Clear accumulated mouse movement
lasttimecount = TimeCount;
return;
}
}