%20WL_MENU.C
///////////////////////////////////////////////////////////////////
/
//
// Handle moving gun around a menu
//
////////////////////////////////////////////////////////////////////
int HandleMenu(CP_iteminfo *item_i,CP_itemtype far *items,void
(*routine)(int w))
{
char key;
static int redrawitem=1,lastitem=-1;
int i,x,y,basey,exit,which,shape,timer;
ControlInfo ci;
which=item_i->curpos;
x=item_i->x&-8;
basey=item_i->y-2;
y=basey+which*13;
VWB_DrawPic(x,y,C_CURSOR1PIC);
SetTextColor(items+which,1);
if (redrawitem)
{
PrintX=item_i->x+item_i->indent;
PrintY=item_i->y+which*13;
US_Print((items+which)->string);
}
//
// CALL CUSTOM ROUTINE IF IT IS NEEDED
//
if (routine)
routine(which);
VW_UpdateScreen();
shape=C_CURSOR1PIC;
timer=8;
exit=0;
TimeCount=0;
IN_ClearKeysDown();
do
{
//
// CHANGE GUN SHAPE
//
if (TimeCount>timer)
{
TimeCount=0;
if (shape==C_CURSOR1PIC)
{
shape=C_CURSOR2PIC;
timer=8;
}
else
{
shape=C_CURSOR1PIC;
timer=70;
}
VWB_DrawPic(x,y,shape);
if (routine)
routine(which);
VW_UpdateScreen();
}
CheckPause();
//
// SEE IF ANY KEYS ARE PRESSED FOR INITIAL CHAR FINDING
//
key=LastASCII;
if (key)
{
int ok=0;
//
// CHECK FOR SCREEN CAPTURE
//
#ifndef SPEAR
if (Keyboard[sc_Tab] && Keyboard[sc_P] &&
MS_CheckParm("goobers"))
#else
if (Keyboard[sc_Tab] && Keyboard[sc_P] &&
MS_CheckParm("debugmode"))
#endif
PicturePause();
if (key>='a')
key-='a'-'A';
for (i=which+1;iamount;i++)
if ((items+i)->active && (items+i)->string[0]==key)
{
EraseGun(item_i,items,x,y,which);
which=i;
DrawGun(item_i,items,x,&y,which,basey,routine);
ok=1;
IN_ClearKeysDown();
break;
}
//
// DIDN'T FIND A MATCH FIRST TIME THRU. CHECK AGAIN.
//
if (!ok)
{
for (i=0;iactive && (items+i)->string[0]==key)
{
EraseGun(item_i,items,x,y,which);
which=i;
DrawGun(item_i,items,x,&y,which,basey,routine);
IN_ClearKeysDown();
break;
}
}
}
//
// GET INPUT
//
ReadAnyControl(&ci);
switch(ci.dir)
{
////////////////////////////////////////////////
//
// MOVE UP
//
case dir_North:
EraseGun(item_i,items,x,y,which);
//
// ANIMATE HALF-STEP
//
if (which && (items+which-1)->active)
{
y-=6;
DrawHalfStep(x,y);
}
//
// MOVE TO NEXT AVAILABLE SPOT
//
do
{
if (!which)
which=item_i->amount-1;
else
which--;
} while(!(items+which)->active);
DrawGun(item_i,items,x,&y,which,basey,routine);
//
// WAIT FOR BUTTON-UP OR DELAY NEXT MOVE
//
TicDelay(20);
break;
////////////////////////////////////////////////
//
// MOVE DOWN
//
case dir_South:
EraseGun(item_i,items,x,y,which);
//
// ANIMATE HALF-STEP
//
if (which!=item_i->amount-1 && (items+which+1)->active)
{
y+=6;
DrawHalfStep(x,y);
}
do
{
if (which==item_i->amount-1)
which=0;
else
which++;
} while(!(items+which)->active);
DrawGun(item_i,items,x,&y,which,basey,routine);
//
// WAIT FOR BUTTON-UP OR DELAY NEXT MOVE
//
TicDelay(20);
break;
}
if (ci.button0 ||
Keyboard[sc_Space] ||
Keyboard[sc_Enter])
exit=1;
if (ci.button1 ||
Keyboard[sc_Escape])
exit=2;
} while(!exit);
IN_ClearKeysDown();
//
// ERASE EVERYTHING
//
if (lastitem!=which)
{
VWB_Bar(x-1,y,25,16,BKGDCOLOR);
PrintX=item_i->x+item_i->indent;
PrintY=item_i->y+which*13;
US_Print((items+which)->string);
redrawitem=1;
}
else
redrawitem=0;
if (routine)
routine(which);
VW_UpdateScreen();
item_i->curpos=which;
lastitem=which;
switch(exit)
{
case 1:
//
// CALL THE ROUTINE
//
if ((items+which)->routine!=NULL)
{
ShootSnd();
MenuFadeOut();
(items+which)->routine(0);
}
return which;
case 2:
SD_PlaySound(ESCPRESSEDSND);
return -1;
}
return 0; // JUST TO SHUT UP THE ERROR MESSAGES!
}
//
// ERASE GUN & DE-HIGHLIGHT STRING
//
void EraseGun(CP_iteminfo *item_i,CP_itemtype far *items,int x,int y,int
which)
{
VWB_Bar(x-1,y,25,16,BKGDCOLOR);
SetTextColor(items+which,0);
PrintX=item_i->x+item_i->indent;
PrintY=item_i->y+which*13;
US_Print((items+which)->string);
VW_UpdateScreen();
}
//
// DRAW HALF STEP OF GUN TO NEXT POSITION
//
void DrawHalfStep(int x,int y)
{
VWB_DrawPic(x,y,C_CURSOR1PIC);
VW_UpdateScreen();
SD_PlaySound(MOVEGUN1SND);
TimeCount=0;
while(TimeCount<8);
}
//
// DRAW GUN AT NEW POSITION
//
void DrawGun(CP_iteminfo *item_i,CP_itemtype far *items,int x,int *y,int
which,int basey,void (*routine)(int w))
{
VWB_Bar(x-1,*y,25,16,BKGDCOLOR);
*y=basey+which*13;
VWB_DrawPic(x,*y,C_CURSOR1PIC);
SetTextColor(items+which,1);
PrintX=item_i->x+item_i->indent;
PrintY=item_i->y+which*13;
US_Print((items+which)->string);
//
// CALL CUSTOM ROUTINE IF IT IS NEEDED
//
if (routine)
routine(which);
VW_UpdateScreen();
SD_PlaySound(MOVEGUN2SND);
}
////////////////////////////////////////////////////////////////////
//
// DELAY FOR AN AMOUNT OF TICS OR UNTIL CONTROLS ARE INACTIVE
//
////////////////////////////////////////////////////////////////////
void TicDelay(int count)
{
ControlInfo ci;
TimeCount=0;
do
{
ReadAnyControl(&ci);
} while(TimeCountcurpos;
WindowX=PrintX=item_i->x+item_i->indent;
WindowY=PrintY=item_i->y;
WindowW=320;
WindowH=200;
for (i=0;iamount;i++)
{
SetTextColor(items+i,which==i);
PrintY=item_i->y+i*13;
if ((items+i)->active)
US_Print((items+i)->string);
else
{
SETFONTCOLOR(DEACTIVE,BKGDCOLOR);
US_Print((items+i)->string);
SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
}
US_Print("\n");
}
}
////////////////////////////////////////////////////////////////////
//
// SET TEXT COLOR (HIGHLIGHT OR NO)
//
////////////////////////////////////////////////////////////////////
void SetTextColor(CP_itemtype far *items,int hlight)
{
if (hlight)
{SETFONTCOLOR(color_hlite[items->active],BKGDCOLOR);}
else
{SETFONTCOLOR(color_norml[items->active],BKGDCOLOR);}
}
////////////////////////////////////////////////////////////////////
//
// WAIT FOR CTRLKEY-UP OR BUTTON-UP
//
////////////////////////////////////////////////////////////////////
void WaitKeyUp(void)
{
ControlInfo ci;
while(ReadAnyControl(&ci), ci.button0|
ci.button1|
ci.button2|
ci.button3|
Keyboard[sc_Space]|
Keyboard[sc_Enter]|
Keyboard[sc_Escape]);
}
////////////////////////////////////////////////////////////////////
//
// READ KEYBOARD, JOYSTICK AND MOUSE FOR INPUT
//
////////////////////////////////////////////////////////////////////
void ReadAnyControl(ControlInfo *ci)
{
int mouseactive=0;
IN_ReadControl(0,ci);
if (mouseenabled)
{
int mousey,mousex;
// READ MOUSE MOTION COUNTERS
// RETURN DIRECTION
// HOME MOUSE
// CHECK MOUSE BUTTONS
Mouse(3);
mousex=_CX;
mousey=_DX;
if (mouseydir=dir_North;
_CX=_DX=CENTER;
Mouse(4);
mouseactive=1;
}
else
if (mousey>CENTER+SENSITIVE)
{
ci->dir=dir_South;
_CX=_DX=CENTER;
Mouse(4);
mouseactive=1;
}
if (mousexdir=dir_West;
_CX=_DX=CENTER;
Mouse(4);
mouseactive=1;
}
else
if (mousex>CENTER+SENSITIVE)
{
ci->dir=dir_East;
_CX=_DX=CENTER;
Mouse(4);
mouseactive=1;
}
if (IN_MouseButtons())
{
ci->button0=IN_MouseButtons()&1;
ci->button1=IN_MouseButtons()&2;
ci->button2=IN_MouseButtons()&4;
ci->button3=false;
mouseactive=1;
}
}
if (joystickenabled && !mouseactive)
{
int jx,jy,jb;
INL_GetJoyDelta(joystickport,&jx,&jy);
if (jy<-SENSITIVE)
ci->dir=dir_North;
else
if (jy>SENSITIVE)
ci->dir=dir_South;
if (jx<-SENSITIVE)
ci->dir=dir_West;
else
if (jx>SENSITIVE)
ci->dir=dir_East;
jb=IN_JoyButtons();
if (jb)
{
ci->button0=jb&1;
ci->button1=jb&2;
if (joypadenabled)
{
ci->button2=jb&4;
ci->button3=jb&8;
}
else
ci->button2=ci->button3=false;
}
}
}
////////////////////////////////////////////////////////////////////
//
// DRAW DIALOG AND CONFIRM YES OR NO TO QUESTION
//
////////////////////////////////////////////////////////////////////
int Confirm(char far *string)
{
int xit=0,i,x,y,tick=0,time,whichsnd[2]={ESCPRESSEDSND,SHOOTSND};
Message(string);
IN_ClearKeysDown();
//
// BLINK CURSOR
//
x=PrintX;
y=PrintY;
TimeCount=0;
do
{
if (TimeCount>=10)
{
switch(tick)
{
case 0:
VWB_Bar(x,y,8,13,TEXTCOLOR);
break;
case 1:
PrintX=x;
PrintY=y;
US_Print("_");
}
VW_UpdateScreen();
tick^=1;
TimeCount=0;
}
#ifndef SPEAR
if (Keyboard[sc_Tab] && Keyboard[sc_P] &&
MS_CheckParm("goobers"))
PicturePause();
#endif
#ifdef SPANISH
} while(!Keyboard[sc_S] && !Keyboard[sc_N] && !Keyboard[sc_Escape]);
#else
} while(!Keyboard[sc_Y] && !Keyboard[sc_N] && !Keyboard[sc_Escape]);
#endif
#ifdef SPANISH
if (Keyboard[sc_S])
{
xit=1;
ShootSnd();
}
while(Keyboard[sc_S] || Keyboard[sc_N] || Keyboard[sc_Escape]);
#else
if (Keyboard[sc_Y])
{
xit=1;
ShootSnd();
}
while(Keyboard[sc_Y] || Keyboard[sc_N] || Keyboard[sc_Escape]);
#endif
IN_ClearKeysDown();
SD_PlaySound(whichsnd[xit]);
return xit;
}
#ifdef JAPAN
////////////////////////////////////////////////////////////////////
//
// DRAW MESSAGE & GET Y OR N
//
////////////////////////////////////////////////////////////////////
int GetYorN(int x,int y,int pic)
{
int xit=0,whichsnd[2]={ESCPRESSEDSND,SHOOTSND};
CA_CacheGrChunk(pic);
VWB_DrawPic(x * 8,y * 8,pic);
UNCACHEGRCHUNK(pic);
VW_UpdateScreen();
IN_ClearKeysDown();
do
{
#ifndef SPEAR
if (Keyboard[sc_Tab] && Keyboard[sc_P] &&
MS_CheckParm("goobers"))
PicturePause();
#endif
#ifdef SPANISH
} while(!Keyboard[sc_S] && !Keyboard[sc_N] && !Keyboard[sc_Escape]);
#else
} while(!Keyboard[sc_Y] && !Keyboard[sc_N] && !Keyboard[sc_Escape]);
#endif
#ifdef SPANISH
if (Keyboard[sc_S])
{
xit=1;
ShootSnd();
}
while(Keyboard[sc_S] || Keyboard[sc_N] || Keyboard[sc_Escape]);
#else
if (Keyboard[sc_Y])
{
xit=1;
ShootSnd();
}
while(Keyboard[sc_Y] || Keyboard[sc_N] || Keyboard[sc_Escape]);
#endif
IN_ClearKeysDown();
SD_PlaySound(whichsnd[xit]);
return xit;
}
#endif
////////////////////////////////////////////////////////////////////
//
// PRINT A MESSAGE IN A WINDOW
//
////////////////////////////////////////////////////////////////////
void Message(char far *string)
{
int h=0,w=0,mw=0,i,x,y,time;
fontstruct _seg *font;
CA_CacheGrChunk (STARTFONT+1);
fontnumber=1;
font=grsegs[STARTFONT+fontnumber];
h=font->height;
for (i=0;i<_fstrlen(string);i++)
if (string[i]=='\n')
{
if (w>mw)
mw=w;
w=0;
h+=font->height;
}
else
w+=font->width[string[i]];
if (w+10>mw)
mw=w+10;
PrintY=(WindowH/2)-h/2;
PrintX=WindowX=160-mw/2;
DrawWindow(WindowX-5,PrintY-5,mw+10,h+10,TEXTCOLOR);
DrawOutline(WindowX-5,PrintY-5,mw+10,h+10,0,HIGHLIGHT);
SETFONTCOLOR(0,TEXTCOLOR);
US_Print(string);
VW_UpdateScreen();
}
////////////////////////////////////////////////////////////////////
//
// THIS MAY BE FIXED A LITTLE LATER...
//
////////////////////////////////////////////////////////////////////
static int lastmusic;
void StartCPMusic(int song)
{
musicnames chunk;
if (audiosegs[STARTMUSIC + lastmusic]) // JDC
MM_FreePtr ((memptr *)&audiosegs[STARTMUSIC + lastmusic]);
lastmusic = song;
SD_MusicOff();
chunk = song;
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]);
}
}
void FreeMusic (void)
{
if (audiosegs[STARTMUSIC + lastmusic]) // JDC
MM_FreePtr ((memptr *)&audiosegs[STARTMUSIC + lastmusic]);
}
/////////////////////////////////////////////////////////////////////////
//
//
// IN_GetScanName() - Returns a string containing the name of the
// specified scan code
//
/////////////////////////////////////////////////////////////////////////
//
byte *
IN_GetScanName(ScanCode scan)
{
byte **p;
ScanCode far *s;
for (s = ExtScanCodes,p = ExtScanNames;*s;p++,s++)
if (*s == scan)
return(*p);
return(ScanNames[scan]);
}
/////////////////////////////////////////////////////////////////////////
//
//
// CHECK FOR PAUSE KEY (FOR MUSIC ONLY)
//
/////////////////////////////////////////////////////////////////////////
//
void CheckPause(void)
{
if (Paused)
{
switch(SoundStatus)
{
case 0: SD_MusicOn(); break;
case 1: SD_MusicOff(); break;
}
SoundStatus^=1;
VW_WaitVBL(3);
IN_ClearKeysDown();
Paused=false;
}
}
/////////////////////////////////////////////////////////////////////////
//
//
// DRAW GUN CURSOR AT CORRECT POSITION IN MENU
//
/////////////////////////////////////////////////////////////////////////
//
void DrawMenuGun(CP_iteminfo *iteminfo)
{
int x,y;
x=iteminfo->x;
y=iteminfo->y+iteminfo->curpos*13-2;
VWB_DrawPic(x,y,C_CURSOR1PIC);
}
/////////////////////////////////////////////////////////////////////////
//
//
// DRAW SCREEN TITLE STRIPES
//
/////////////////////////////////////////////////////////////////////////
//
void DrawStripes(int y)
{
#ifndef SPEAR
VWB_Bar(0,y,320,24,0);
VWB_Hlin(0,319,y+22,STRIPE);
#else
VWB_Bar(0,y,320,22,0);
VWB_Hlin(0,319,y+23,0);
#endif
}
void ShootSnd(void)
{
SD_PlaySound(SHOOTSND);
}
/////////////////////////////////////////////////////////////////////////
//
//
// CHECK FOR EPISODES
//
/////////////////////////////////////////////////////////////////////////
//
void CheckForEpisodes(void)
{
struct ffblk f;
//
// JAPANESE VERSION
//
#ifdef JAPAN
#ifdef JAPDEMO
if (!findfirst("*.WJ1",&f,FA_ARCH))
{
strcpy(extension,"WJ1");
#else
if (!findfirst("*.WJ6",&f,FA_ARCH))
{
strcpy(extension,"WJ6");
#endif
strcat(configname,extension);
strcat(SaveName,extension);
strcat(PageFileName,extension);
strcat(audioname,extension);
strcat(demoname,extension);
EpisodeSelect[1] =
EpisodeSelect[2] =
EpisodeSelect[3] =
EpisodeSelect[4] =
EpisodeSelect[5] = 1;
}
else
Quit("NO JAPANESE WOLFENSTEIN 3-D DATA FILES to be found!");
#else
//
// ENGLISH
//
#ifndef UPLOAD
#ifndef SPEAR
if (!findfirst("*.WL6",&f,FA_ARCH))
{
strcpy(extension,"WL6");
NewEmenu[2].active =
NewEmenu[4].active =
NewEmenu[6].active =
NewEmenu[8].active =
NewEmenu[10].active =
EpisodeSelect[1] =
EpisodeSelect[2] =
EpisodeSelect[3] =
EpisodeSelect[4] =
EpisodeSelect[5] = 1;
}
else
if (!findfirst("*.WL3",&f,FA_ARCH))
{
strcpy(extension,"WL3");
NewEmenu[2].active =
NewEmenu[4].active =
EpisodeSelect[1] =
EpisodeSelect[2] = 1;
}
else
#endif
#endif
#ifdef SPEAR
#ifndef SPEARDEMO
if (!findfirst("*.SOD",&f,FA_ARCH))
{
strcpy(extension,"SOD");
}
else
Quit("NO SPEAR OF DESTINY DATA FILES TO BE FOUND!");
#else
if (!findfirst("*.SDM",&f,FA_ARCH))
{
strcpy(extension,"SDM");
}
else
Quit("NO SPEAR OF DESTINY DEMO DATA FILES TO BE FOUND!");
#endif
#else
if (!findfirst("*.WL1",&f,FA_ARCH))
{
strcpy(extension,"WL1");
}
else
Quit("NO WOLFENSTEIN 3-D DATA FILES to be found!");
#endif
strcat(configname,extension);
strcat(SaveName,extension);
strcat(PageFileName,extension);
strcat(audioname,extension);
strcat(demoname,extension);
#ifndef SPEAR
#ifndef GOODTIMES
strcat(helpfilename,extension);
#endif
strcat(endfilename,extension);
#endif
#endif
}