blob: 66ce4123bf9edc0657895446b70b8e901770837e [file] [log] [blame]
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D 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
aint32_t with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
#include "duke3d.h"
#include "mouse.h"
#include "animlib.h"
#include "control.h"
#include "../../Engine/src/filesystem.h"
#include "SDL.h"
#include "premap.h"
#include "../../Engine/src/display.h"
extern SDL_Surface *surface;
extern short inputloc;
extern int recfilep;
extern uint8_t vgacompatible;
short probey=0,lastprobey=0,last_menu,globalskillsound=-1;
short sh,onbar,buttonstat,deletespot;
short last_zero,last_fifty,last_threehundred = 0;
static uint8_t fileselect = 1, menunamecnt;
static char menuname[256][17];
// File tree info
//
uint8_t szCurrentDirectory[1024] = {'\0'};
#define FILETYPE_DIRECTORY 0
#define FILETYPE_FILE 1
typedef struct fileentry
{
uint8_t filename[16];
int type;
}FILEENTRY;
typedef struct filelist
{
FILEENTRY *files;
}FILELIST;
FILELIST m_Files;// = NULL;
//
//
#define MENU_SELECT_EPISODE 100
#define MENU_USER_MAP 101
// CTW - REMOVED
/* Error codes */
/*
#define eTenBnNotInWindows 3801
#define eTenBnBadGameIni 3802
#define eTenBnBadTenIni 3803
#define eTenBnBrowseCancel 3804
#define eTenBnBadTenInst 3805
int tenBnStart(void);
void tenBnSetBrowseRtn(uint8_t *(*rtn)(uint8_t *str, int len));
void tenBnSetExitRtn(void (*rtn)(void));
void tenBnSetEndRtn(void (*rtn)(void));*/
// CTW END - REMOVED
void dummyfunc(void)
{
}
void dummymess(int i,uint8_t *c)
{
}
// CTW - REMOVED
/*
void TENtext(void)
{
int32_t dacount,dalastcount;
puts("\nDuke Nukem 3D has been licensed exclusively to TEN (Total");
puts("Entertainment Network) for wide-area networked (WAN) multiplayer");
puts("games.\n");
puts("The multiplayer code within Duke Nukem 3D has been highly");
puts("customized to run best on TEN, where you'll experience fast and");
puts("stable performance, plus other special benefits.\n");
puts("We do not authorize or recommend the use of Duke Nukem 3D with");
puts("gaming services other than TEN.\n");
puts("Duke Nukem 3D is protected by United States copyright law and");
puts("international treaty.\n");
puts("For the best online multiplayer gaming experience, please call TEN");
puts("at 800-8040-TEN, or visit TEN's Web Site at www.ten.net.\n");
puts("Press any key to continue.\n");
_bios_timeofday(0,&dacount);
while( _bios_keybrd(1) == 0 )
{
_bios_timeofday(0,&dalastcount);
if( (dacount+240) < dalastcount ) break;
}
}
*/
// CTW END - REMOVED
void cmenu(short cm)
{
current_menu = cm;
if( (cm >= 1000 && cm <= 1010) )
return;
if( cm == 0 )
probey = last_zero;
else if(cm == 50)
probey = last_fifty;
else if(cm >= 300 && cm < 400)
probey = last_threehundred;
else if(cm == 110)
probey = 1;
else probey = 0;
lastprobey = -1;
}
void savetemp(char *fn,uint8_t* daptr,int32_t dasiz)
{
int fp;
char full[256];
snprintf(full, "%s/%s", game_dir, fn);
fp = rb->open(full,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666);
write(fp,(uint8_t *)daptr,dasiz);
close(fp);
}
void getangplayers(short snum)
{
short i,a;
for(i=connecthead;i>=0;i=connectpoint2[i])
{
if(i != snum)
{
a = ps[snum].ang+getangle(ps[i].posx-ps[snum].posx,ps[i].posy-ps[snum].posy);
a = a-1024;
rotatesprite(
(320<<15) + (((sintable[(a+512)&2047])>>7)<<15),
(320<<15) - (((sintable[a&2047])>>8)<<15),
klabs(sintable[((a>>1)+768)&2047]<<2),0,APLAYER,0,ps[i].palookup,0,0,0,xdim-1,ydim-1);
}
}
}
int loadpheader(uint8_t spot,int32 *vn,int32 *ln,int32 *psk,int32 *nump)
{
char fn[] = "game0.sav";
int32_t fil;
int32_t bv;
fn[4] = spot+'0';
char fullfn[256];
sprintf(fullfn, "%s/%s", game_dir, fn);
if ((fil = TCkopen4load(fullfn,0)) == -1) return(-1);
tiles[MAXTILES-3].lock = 255;
kdfread(&bv,4,1,fil);
if(bv != BYTEVERSION)
{
FTA(114,&ps[myconnectindex],1);
kclose(fil);
return 1;
}
kdfread(nump,sizeof(int32),1,fil);
kdfread(tempbuf,19,1,fil);
kdfread(vn,sizeof(int32),1,fil);
kdfread(ln,sizeof(int32),1,fil);
kdfread(psk,sizeof(int32),1,fil);
if (tiles[MAXTILES-3].data == NULL)
allocache(&tiles[MAXTILES-3].data,160*100,&tiles[MAXTILES-3].lock);
tiles[MAXTILES-3].dim.width = 100;
tiles[MAXTILES-3].dim.height = 160;
kdfread(tiles[MAXTILES-3].data,160,100,fil);
kclose(fil);
return(0);
}
int loadplayer(int8_t spot)
{
short k,music_changed;
char fn[] = "game0.sav";
char mpfn[] = "gameA_00.sav";
char *fnptr, scriptptrs[MAXSCRIPTSIZE];
int32_t fil, bv, i, j, x;
int32 nump;
if(spot < 0)
{
multiflag = 1;
multiwhat = 0;
multipos = -spot-1;
return -1;
}
if( multiflag == 2 && multiwho != myconnectindex )
{
fnptr = mpfn;
mpfn[4] = spot + 'A';
if(ud.multimode > 9)
{
mpfn[6] = (multiwho/10) + '0';
mpfn[7] = (multiwho%10) + '0';
}
else mpfn[7] = multiwho + '0';
}
else
{
fnptr = fn;
fn[4] = spot + '0';
}
char fullfn[256];
sprintf(fullfn, "%s/%s", game_dir, fnptr);
if ((fil = TCkopen4load(fullfn,0)) == -1) return(-1);
if(ud.recstat != 2)
ready2send = 0;
kdfread(&bv,4,1,fil);
if(bv != BYTEVERSION)
{
rb->splashf(HZ, "wrong version (%d != %d)", bv, BYTEVERSION);
FTA(114,&ps[myconnectindex],1);
kclose(fil);
if(ud.recstat != 2)
{
// FIX_00084: Various bugs in the load game (single player) option if ESC is hit or if wrong version
ototalclock = totalclock;
ready2send = 1;
}
return 1;
}
kdfread(&nump,sizeof(nump),1,fil);
if(nump != numplayers)
{
rb->splash(HZ, "wrong num players");
kclose(fil);
if(ud.recstat != 2)
{
// FIX_00084: Various bugs in the load game (single player) option if ESC is hit or if wrong version
ototalclock = totalclock;
ready2send = 1;
}
FTA(124,&ps[myconnectindex],1);
return 1;
}
if(numplayers > 1)
{
pub = NUMPAGES;
pus = NUMPAGES;
vscrn();
drawbackground();
menutext(160,100,0,0,"LOADING...");
nextpage();
}
waitforeverybody();
FX_StopAllSounds();
clearsoundlocks();
MUSIC_StopSong();
if(numplayers > 1)
kdfread(&buf,19,1,fil);
else
kdfread(&ud.savegame[spot][0],19,1,fil);
music_changed = (music_select != (ud.volume_number*11) + ud.level_number);
kdfread(&ud.volume_number,sizeof(ud.volume_number),1,fil);
kdfread(&ud.level_number,sizeof(ud.level_number),1,fil);
kdfread(&ud.player_skill,sizeof(ud.player_skill),1,fil);
ud.m_level_number = ud.level_number;
ud.m_volume_number = ud.volume_number;
ud.m_player_skill = ud.player_skill;
//Fake read because lseek won't work with compression
tiles[MAXTILES-3].lock = 1;
if (tiles[MAXTILES-3].data == NULL)
allocache(&tiles[MAXTILES-3].data,160*100,&tiles[MAXTILES-3].lock);
tiles[MAXTILES-3].dim.width = 100;
tiles[MAXTILES-3].dim.height = 160;
kdfread(tiles[MAXTILES-3].data,160,100,fil);
kdfread(&numwalls,2,1,fil);
kdfread(&wall[0],sizeof(walltype),MAXWALLS,fil);
kdfread(&numsectors,2,1,fil);
kdfread(&sector[0],sizeof(sectortype),MAXSECTORS,fil);
kdfread(&sprite[0],sizeof(spritetype),MAXSPRITES,fil);
kdfread(&headspritesect[0],2,MAXSECTORS+1,fil);
kdfread(&prevspritesect[0],2,MAXSPRITES,fil);
kdfread(&nextspritesect[0],2,MAXSPRITES,fil);
kdfread(&headspritestat[0],2,MAXSTATUS+1,fil);
kdfread(&prevspritestat[0],2,MAXSPRITES,fil);
kdfread(&nextspritestat[0],2,MAXSPRITES,fil);
kdfread(&numcyclers,sizeof(numcyclers),1,fil);
kdfread(&cyclers[0][0],12,MAXCYCLERS,fil);
kdfread(ps,sizeof(ps),1,fil);
kdfread(po,sizeof(po),1,fil);
kdfread(&numanimwalls,sizeof(numanimwalls),1,fil);
kdfread(&animwall,sizeof(animwall),1,fil);
kdfread(&msx[0],sizeof(int32_t),sizeof(msx)/sizeof(int32_t),fil);
kdfread(&msy[0],sizeof(int32_t),sizeof(msy)/sizeof(int32_t),fil);
kdfread((short *)&spriteqloc,sizeof(short),1,fil);
kdfread((short *)&spriteqamount,sizeof(short),1,fil);
kdfread((short *)&spriteq[0],sizeof(short),spriteqamount,fil);
kdfread(&mirrorcnt,sizeof(short),1,fil);
kdfread(&mirrorwall[0],sizeof(short),64,fil);
kdfread(&mirrorsector[0],sizeof(short),64,fil);
kdfread(&show2dsector[0],sizeof(uint8_t ),MAXSECTORS>>3,fil);
kdfread(&actortype[0],sizeof(uint8_t ),MAXTILES,fil);
kdfread(&boardfilename[0],sizeof(boardfilename),1,fil);
kdfread(&numclouds,sizeof(numclouds),1,fil);
kdfread(&clouds[0],sizeof(short)<<7,1,fil);
kdfread(&cloudx[0],sizeof(short)<<7,1,fil);
kdfread(&cloudy[0],sizeof(short)<<7,1,fil);
kdfread(&scriptptrs[0],1,MAXSCRIPTSIZE,fil);
kdfread(&script[0],4,MAXSCRIPTSIZE,fil);
for(i=0;i<MAXSCRIPTSIZE;i++)
if( scriptptrs[i] )
{
j = (int32_t)script[i]+(int32_t)&script[0];
script[i] = j;
}
kdfread(&actorscrptr[0],4,MAXTILES,fil);
for(i=0;i<MAXTILES;i++)
if(actorscrptr[i])
{
j = (int32_t)actorscrptr[i]+(int32_t)&script[0];
actorscrptr[i] = (int32_t *)j;
}
kdfread(&scriptptrs[0],1,MAXSPRITES,fil);
kdfread(&hittype[0],sizeof(struct weaponhit),MAXSPRITES,fil);
for(i=0;i<MAXSPRITES;i++)
{
j = (int32_t)(&script[0]);
if( scriptptrs[i]&1 ) T2 += j;
if( scriptptrs[i]&2 ) T5 += j;
if( scriptptrs[i]&4 ) T6 += j;
}
kdfread(&lockclock,sizeof(lockclock),1,fil);
kdfread(&pskybits,sizeof(pskybits),1,fil);
kdfread(&pskyoff[0],sizeof(pskyoff[0]),MAXPSKYTILES,fil);
kdfread(&animatecnt,sizeof(animatecnt),1,fil);
kdfread(&animatesect[0],2,MAXANIMATES,fil);
kdfread(&animateptr[0],4,MAXANIMATES,fil);
for(i = animatecnt-1;i>=0;i--) animateptr[i] = (int32_t *)((int32_t)animateptr[i]+(int32_t)(&sector[0]));
kdfread(&animategoal[0],4,MAXANIMATES,fil);
kdfread(&animatevel[0],4,MAXANIMATES,fil);
kdfread(&earthquaketime,sizeof(earthquaketime),1,fil);
kdfread(&ud.from_bonus,sizeof(ud.from_bonus),1,fil);
kdfread(&ud.secretlevel,sizeof(ud.secretlevel),1,fil);
kdfread(&ud.respawn_monsters,sizeof(ud.respawn_monsters),1,fil);
ud.m_respawn_monsters = ud.respawn_monsters;
kdfread(&ud.respawn_items,sizeof(ud.respawn_items),1,fil);
ud.m_respawn_items = ud.respawn_items;
kdfread(&ud.respawn_inventory,sizeof(ud.respawn_inventory),1,fil);
ud.m_respawn_inventory = ud.respawn_inventory;
kdfread(&ud.god,sizeof(ud.god),1,fil);
kdfread(&ud.auto_run,sizeof(ud.auto_run),1,fil);
kdfread(&ud.crosshair,sizeof(ud.crosshair),1,fil);
kdfread(&ud.monsters_off,sizeof(ud.monsters_off),1,fil);
ud.m_monsters_off = ud.monsters_off;
kdfread(&ud.last_level,sizeof(ud.last_level),1,fil);
kdfread(&ud.eog,sizeof(ud.eog),1,fil);
kdfread(&ud.coop,sizeof(ud.coop),1,fil);
ud.m_coop = ud.coop;
kdfread(&ud.marker,sizeof(ud.marker),1,fil);
ud.m_marker = ud.marker;
kdfread(&ud.ffire,sizeof(ud.ffire),1,fil);
ud.m_ffire = ud.ffire;
kdfread(&camsprite,sizeof(camsprite),1,fil);
kdfread(&connecthead,sizeof(connecthead),1,fil);
kdfread(connectpoint2,sizeof(connectpoint2),1,fil);
kdfread(&numplayersprites,sizeof(numplayersprites),1,fil);
kdfread((short *)&frags[0][0],sizeof(frags),1,fil);
kdfread(&randomseed,sizeof(randomseed),1,fil);
kdfread(&global_random,sizeof(global_random),1,fil);
kdfread(&parallaxyscale,sizeof(parallaxyscale),1,fil);
kclose(fil);
if(ps[myconnectindex].over_shoulder_on != 0)
{
cameradist = 0;
cameraclock = 0;
ps[myconnectindex].over_shoulder_on = 1;
}
screenpeek = myconnectindex;
clearbufbyte(gotpic,sizeof(gotpic),0L);
clearsoundlocks();
cacheit();
docacheit();
if(music_changed == 0)
music_select = (ud.volume_number*11) + ud.level_number;
playmusic(&music_fn[0][music_select][0]);
ps[myconnectindex].gm = MODE_GAME;
ud.recstat = 0;
if(ps[myconnectindex].jetpack_on)
spritesound(DUKE_JETPACK_IDLE,ps[myconnectindex].i);
restorepalette = 1;
setpal(&ps[myconnectindex]);
vscrn();
FX_SetReverb(0);
if(ud.lockout == 0)
{
for(x=0;x<numanimwalls;x++)
if( wall[animwall[x].wallnum].extra >= 0 )
wall[animwall[x].wallnum].picnum = wall[animwall[x].wallnum].extra;
}
else
{
for(x=0;x<numanimwalls;x++)
switch(wall[animwall[x].wallnum].picnum)
{
case FEMPIC1:
wall[animwall[x].wallnum].picnum = BLANKSCREEN;
break;
case FEMPIC2:
case FEMPIC3:
wall[animwall[x].wallnum].picnum = SCREENBREAK6;
break;
}
}
numinterpolations = 0;
startofdynamicinterpolations = 0;
k = headspritestat[3];
while(k >= 0)
{
switch(sprite[k].lotag)
{
case 31:
setinterpolation(&sector[sprite[k].sectnum].floorz);
break;
case 32:
setinterpolation(&sector[sprite[k].sectnum].ceilingz);
break;
case 25:
setinterpolation(&sector[sprite[k].sectnum].floorz);
setinterpolation(&sector[sprite[k].sectnum].ceilingz);
break;
case 17:
setinterpolation(&sector[sprite[k].sectnum].floorz);
setinterpolation(&sector[sprite[k].sectnum].ceilingz);
break;
case 0:
case 5:
case 6:
case 11:
case 14:
case 15:
case 16:
case 26:
case 30:
setsectinterpolate(k);
break;
}
k = nextspritestat[k];
}
for(i=numinterpolations-1;i>=0;i--) bakipos[i] = *curipos[i];
for(i = animatecnt-1;i>=0;i--)
setinterpolation(animateptr[i]);
show_shareware = 0;
everyothertime = 0;
clearbufbyte(playerquitflag,MAXPLAYERS,0x01010101);
resetmys();
ready2send = 1;
flushpackets();
clearfifo();
waitforeverybody();
resettimevars();
return(0);
}
int saveplayer(int8_t spot)
{
int32_t i, j;
char fn[] = "game0.sav";
char mpfn[] = "gameA_00.sav";
char *fnptr,scriptptrs[MAXSCRIPTSIZE];
FILE *fil;
int32_t bv = BYTEVERSION;
char fullpathsavefilename[256];
if(spot < 0)
{
multiflag = 1;
multiwhat = 1;
multipos = -spot-1;
return -1;
}
waitforeverybody();
if( multiflag == 2 && multiwho != myconnectindex )
{
fnptr = mpfn;
mpfn[4] = spot + 'A';
if(ud.multimode > 9)
{
mpfn[6] = (multiwho/10) + '0';
mpfn[7] = multiwho + '0';
}
else mpfn[7] = multiwho + '0';
}
else
{
fnptr = fn;
fn[4] = spot + '0';
}
// Are we loading a TC?
if(getGameDir()[0] != '\0')
{
// Yes
sprintf(fullpathsavefilename, "%s/%s", getGameDir(), fnptr);
}
else
{
// No
sprintf(fullpathsavefilename, "%s", fnptr);
}
if ((fil = fopen(fullpathsavefilename,"wb")) == 0) return(-1);
ready2send = 0;
dfwrite(&bv,4,1,fil);
dfwrite(&ud.multimode,sizeof(ud.multimode),1,fil);
dfwrite(&ud.savegame[spot][0],19,1,fil);
dfwrite(&ud.volume_number,sizeof(ud.volume_number),1,fil);
dfwrite(&ud.level_number,sizeof(ud.level_number),1,fil);
dfwrite(&ud.player_skill,sizeof(ud.player_skill),1,fil);
dfwrite(tiles[MAXTILES-1].data,160,100,fil);
dfwrite(&numwalls,2,1,fil);
dfwrite(&wall[0],sizeof(walltype),MAXWALLS,fil);
dfwrite(&numsectors,2,1,fil);
dfwrite(&sector[0],sizeof(sectortype),MAXSECTORS,fil);
dfwrite(&sprite[0],sizeof(spritetype),MAXSPRITES,fil);
dfwrite(&headspritesect[0],2,MAXSECTORS+1,fil);
dfwrite(&prevspritesect[0],2,MAXSPRITES,fil);
dfwrite(&nextspritesect[0],2,MAXSPRITES,fil);
dfwrite(&headspritestat[0],2,MAXSTATUS+1,fil);
dfwrite(&prevspritestat[0],2,MAXSPRITES,fil);
dfwrite(&nextspritestat[0],2,MAXSPRITES,fil);
dfwrite(&numcyclers,sizeof(numcyclers),1,fil);
dfwrite(&cyclers[0][0],12,MAXCYCLERS,fil);
dfwrite(ps,sizeof(ps),1,fil);
dfwrite(po,sizeof(po),1,fil);
dfwrite(&numanimwalls,sizeof(numanimwalls),1,fil);
dfwrite(&animwall,sizeof(animwall),1,fil);
dfwrite(&msx[0],sizeof(int32_t),sizeof(msx)/sizeof(int32_t),fil);
dfwrite(&msy[0],sizeof(int32_t),sizeof(msy)/sizeof(int32_t),fil);
dfwrite(&spriteqloc,sizeof(short),1,fil);
dfwrite(&spriteqamount,sizeof(short),1,fil);
dfwrite(&spriteq[0],sizeof(short),spriteqamount,fil);
dfwrite(&mirrorcnt,sizeof(short),1,fil);
dfwrite(&mirrorwall[0],sizeof(short),64,fil);
dfwrite(&mirrorsector[0],sizeof(short),64,fil);
dfwrite(&show2dsector[0],sizeof(uint8_t ),MAXSECTORS>>3,fil);
dfwrite(&actortype[0],sizeof(uint8_t ),MAXTILES,fil);
dfwrite(&boardfilename[0],sizeof(boardfilename),1,fil);
dfwrite(&numclouds,sizeof(numclouds),1,fil);
dfwrite(&clouds[0],sizeof(short)<<7,1,fil);
dfwrite(&cloudx[0],sizeof(short)<<7,1,fil);
dfwrite(&cloudy[0],sizeof(short)<<7,1,fil);
for(i=0;i<MAXSCRIPTSIZE;i++)
{
if( (int32_t)script[i] >= (int32_t)(&script[0]) && (int32_t)script[i] < (int32_t)(&script[MAXSCRIPTSIZE]) )
{
scriptptrs[i] = 1;
j = (int32_t)script[i] - (int32_t)&script[0];
script[i] = j;
}
else scriptptrs[i] = 0;
}
dfwrite(&scriptptrs[0],1,MAXSCRIPTSIZE,fil);
dfwrite(&script[0],4,MAXSCRIPTSIZE,fil);
for(i=0;i<MAXSCRIPTSIZE;i++)
if( scriptptrs[i] )
{
j = script[i]+(int32_t)&script[0];
script[i] = j;
}
for(i=0;i<MAXTILES;i++)
if(actorscrptr[i])
{
j = (int32_t)actorscrptr[i]-(int32_t)&script[0];
actorscrptr[i] = (int32_t *)j;
}
dfwrite(&actorscrptr[0],4,MAXTILES,fil);
for(i=0;i<MAXTILES;i++)
if(actorscrptr[i])
{
j = (int32_t)actorscrptr[i]+(int32_t)&script[0];
actorscrptr[i] = (int32_t *)j;
}
for(i=0;i<MAXSPRITES;i++)
{
scriptptrs[i] = 0;
if(actorscrptr[PN] == 0) continue;
j = (int32_t)&script[0];
if(T2 >= j && T2 < (int32_t)(&script[MAXSCRIPTSIZE]) )
{
scriptptrs[i] |= 1;
T2 -= j;
}
if(T5 >= j && T5 < (int32_t)(&script[MAXSCRIPTSIZE]) )
{
scriptptrs[i] |= 2;
T5 -= j;
}
if(T6 >= j && T6 < (int32_t)(&script[MAXSCRIPTSIZE]) )
{
scriptptrs[i] |= 4;
T6 -= j;
}
}
dfwrite(&scriptptrs[0],1,MAXSPRITES,fil);
dfwrite(&hittype[0],sizeof(struct weaponhit),MAXSPRITES,fil);
for(i=0;i<MAXSPRITES;i++)
{
if(actorscrptr[PN] == 0) continue;
j = (int32_t)&script[0];
if(scriptptrs[i]&1)
T2 += j;
if(scriptptrs[i]&2)
T5 += j;
if(scriptptrs[i]&4)
T6 += j;
}
dfwrite(&lockclock,sizeof(lockclock),1,fil);
dfwrite(&pskybits,sizeof(pskybits),1,fil);
dfwrite(&pskyoff[0],sizeof(pskyoff[0]),MAXPSKYTILES,fil);
dfwrite(&animatecnt,sizeof(animatecnt),1,fil);
dfwrite(&animatesect[0],2,MAXANIMATES,fil);
for(i = animatecnt-1;i>=0;i--) animateptr[i] = (int32_t *)((int32_t)animateptr[i]-(int32_t)(&sector[0]));
dfwrite(&animateptr[0],4,MAXANIMATES,fil);
for(i = animatecnt-1;i>=0;i--) animateptr[i] = (int32_t *)((int32_t)animateptr[i]+(int32_t)(&sector[0]));
dfwrite(&animategoal[0],4,MAXANIMATES,fil);
dfwrite(&animatevel[0],4,MAXANIMATES,fil);
dfwrite(&earthquaketime,sizeof(earthquaketime),1,fil);
dfwrite(&ud.from_bonus,sizeof(ud.from_bonus),1,fil);
dfwrite(&ud.secretlevel,sizeof(ud.secretlevel),1,fil);
dfwrite(&ud.respawn_monsters,sizeof(ud.respawn_monsters),1,fil);
dfwrite(&ud.respawn_items,sizeof(ud.respawn_items),1,fil);
dfwrite(&ud.respawn_inventory,sizeof(ud.respawn_inventory),1,fil);
dfwrite(&ud.god,sizeof(ud.god),1,fil);
dfwrite(&ud.auto_run,sizeof(ud.auto_run),1,fil);
dfwrite(&ud.crosshair,sizeof(ud.crosshair),1,fil);
dfwrite(&ud.monsters_off,sizeof(ud.monsters_off),1,fil);
dfwrite(&ud.last_level,sizeof(ud.last_level),1,fil);
dfwrite(&ud.eog,sizeof(ud.eog),1,fil);
dfwrite(&ud.coop,sizeof(ud.coop),1,fil);
dfwrite(&ud.marker,sizeof(ud.marker),1,fil);
dfwrite(&ud.ffire,sizeof(ud.ffire),1,fil);
dfwrite(&camsprite,sizeof(camsprite),1,fil);
dfwrite(&connecthead,sizeof(connecthead),1,fil);
dfwrite(connectpoint2,sizeof(connectpoint2),1,fil);
dfwrite(&numplayersprites,sizeof(numplayersprites),1,fil);
dfwrite((short *)&frags[0][0],sizeof(frags),1,fil);
dfwrite(&randomseed,sizeof(randomseed),1,fil);
dfwrite(&global_random,sizeof(global_random),1,fil);
dfwrite(&parallaxyscale,sizeof(parallaxyscale),1,fil);
fclose(fil);
if(ud.multimode < 2)
{
strcpy(fta_quotes[122],"GAME SAVED");
FTA(122,&ps[myconnectindex],1);
}
ready2send = 1;
waitforeverybody();
ototalclock = totalclock;
return(0);
}
#define LMB (buttonstat&1)
#define RMB (buttonstat&2)
// FIX_00036: Mouse wheel can now be used in menu
#define WHEELUP (buttonstat&8)
#define WHEELDOWN (buttonstat&16)
ControlInfo minfo;
int probe(int x,int y,int i,int n)
{
return( probeXduke(x, y, i, n, 65536L) );
}
int probeXduke(int x,int y,int i,int n, int32_t spriteSize)
{
short centre;
int32 mouseSens;
static int32_t delay_counter_up = 0, delay_counter_down = 0, delay_up = 50, delay_down = 50;
static int32_t mi = 0;
// FIX_00075: Bad Sensitivity aint32_t Y axis when using mouse in menu (Thanks to Turrican)
mouseSens = CONTROL_GetMouseSensitivity_Y();
mouseSens = mouseSens ? mouseSens : 1;
if( ((ControllerType == controltype_keyboardandmouse)||
(ControllerType == controltype_joystickandmouse)) )
//&& CONTROL_MousePresent )
{
memset(&minfo, 0, sizeof(ControlInfo));
CONTROL_GetInput( &minfo );
//mouseY = CONTROL_GetMouseY();
//mi = mouseY;
mi += minfo.dz / mouseSens;
mi += minfo.dpitch / mouseSens;
}
else minfo.dz = minfo.dyaw = 0;
if( x == (320>>1) )
centre = 320>>2;
else centre = 0;
if( KB_KeyPressed( sc_UpArrow ) || KB_KeyPressed( sc_PgUp ) || KB_KeyPressed( sc_kpad_8 ) ||
(mi < -1024) || WHEELUP)
{
// FIX_00060: Repeat key function was not working in the menu
if(delay_counter_up==0 || (totalclock-delay_counter_up)>delay_up || (mi < -1024) || WHEELUP)
{
mi = 0;
sound(KICK_HIT);
probey--;
if(probey < 0) probey = n-1;
minfo.dz = 0;
minfo.dpitch = 0;
if (delay_counter_up && (totalclock-delay_counter_up)>delay_up)
delay_up = 10;
delay_counter_up = totalclock;
}
}
else
{
KB_ClearKeyDown( sc_UpArrow );
KB_ClearKeyDown( sc_kpad_8 );
KB_ClearKeyDown( sc_PgUp );
delay_counter_up = 0;
delay_up = 50;
}
if( KB_KeyPressed( sc_DownArrow ) || KB_KeyPressed( sc_PgDn ) || KB_KeyPressed( sc_kpad_2 )
|| (mi > 1024) || WHEELDOWN )
{
if(delay_counter_down==0 || (totalclock-delay_counter_down)>delay_down || (mi > 1024) || WHEELDOWN)
{
mi = 0;
sound(KICK_HIT);
probey++;
minfo.dz = 0;
minfo.dpitch = 0;
if (delay_counter_down && (totalclock-delay_counter_down)>delay_down)
delay_down = 10;
delay_counter_down = totalclock;
}
}
else
{
KB_ClearKeyDown( sc_DownArrow );
KB_ClearKeyDown( sc_kpad_2 );
KB_ClearKeyDown( sc_PgDn );
delay_counter_down = 0;
delay_down = 50;
}
if(probey >= n)
probey = 0;
if(centre)
{
// rotatesprite(((320>>1)+(centre)+54)<<16,(y+(probey*i)-4)<<16,65536L,0,SPINNINGNUKEICON+6-((6+(totalclock>>3))%7),sh,0,10,0,0,xdim-1,ydim-1);
// rotatesprite(((320>>1)-(centre)-54)<<16,(y+(probey*i)-4)<<16,65536L,0,SPINNINGNUKEICON+((totalclock>>3)%7),sh,0,10,0,0,xdim-1,ydim-1);
rotatesprite(((320>>1)+(centre>>1)+70)<<16,(y+(probey*i)-4)<<16,spriteSize,0,SPINNINGNUKEICON+6-((6+(totalclock>>3))%7),sh,0,10,0,0,xdim-1,ydim-1);
rotatesprite(((320>>1)-(centre>>1)-70)<<16,(y+(probey*i)-4)<<16,spriteSize,0,SPINNINGNUKEICON+((totalclock>>3)%7),sh,0,10,0,0,xdim-1,ydim-1);
}
else
rotatesprite((x-tiles[BIGFNTCURSOR].dim.width-4)<<16,(y+(probey*i)-4)<<16,spriteSize,0,SPINNINGNUKEICON+(((totalclock>>3))%7),sh,0,10,0,0,xdim-1,ydim-1);
if( KB_KeyPressed(sc_Space) || KB_KeyPressed( sc_kpad_Enter ) || KB_KeyPressed( sc_Enter ) || (LMB))// && !onbar) )
{
if(current_menu != 110)
sound(PISTOL_BODYHIT);
KB_ClearKeyDown( sc_Enter );
KB_ClearKeyDown( sc_Space );
KB_ClearKeyDown( sc_kpad_Enter );
return(probey);
}
else if( KB_KeyPressed( sc_Escape ) || (RMB) )
{
onbar = 0;
KB_ClearKeyDown( sc_Escape );
sound(EXITMENUSOUND);
return(-1);
}
else
{
if(onbar == 0) return(-probey-2);
if ( KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed( sc_kpad_4 ) || ((buttonstat&1) && minfo.dyaw < -128 ) )
return(probey);
else if ( KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_kpad_6 ) || ((buttonstat&1) && minfo.dyaw > 128 ) )
return(probey);
else return(-probey-2);
}
}
int menutext(int x,int y,short s,short p,char *t)
{
short i, ac, centre;
y -= 12;
i = centre = 0;
if( x == (320>>1) )
{
while( *(t+i) )
{
if(*(t+i) == ' ')
{
centre += 5;
i++;
continue;
}
ac = 0;
if(*(t+i) >= '0' && *(t+i) <= '9')
ac = *(t+i) - '0' + BIGALPHANUM-10;
else if(*(t+i) >= 'a' && *(t+i) <= 'z')
ac = toupper(*(t+i)) - 'A' + BIGALPHANUM;
else if(*(t+i) >= 'A' && *(t+i) <= 'Z')
ac = *(t+i) - 'A' + BIGALPHANUM;
else switch(*(t+i))
{
case '-':
ac = BIGALPHANUM-11;
break;
case '.':
ac = BIGPERIOD;
break;
case '\'':
ac = BIGAPPOS;
break;
case ',':
ac = BIGCOMMA;
break;
case '!':
ac = BIGX;
break;
case '?':
ac = BIGQ;
break;
case ';':
ac = BIGSEMI;
break;
case ':':
ac = BIGSEMI;
break;
default:
centre += 5;
i++;
continue;
}
centre += tiles[ac].dim.width-1;
i++;
}
}
if(centre)
x = (320-centre-10)>>1;
while(*t)
{
if(*t == ' ') {x+=5;t++;continue;}
ac = 0;
if(*t >= '0' && *t <= '9')
ac = *t - '0' + BIGALPHANUM-10;
else if(*t >= 'a' && *t <= 'z')
ac = toupper(*t) - 'A' + BIGALPHANUM;
else if(*t >= 'A' && *t <= 'Z')
ac = *t - 'A' + BIGALPHANUM;
else switch(*t)
{
case '-':
ac = BIGALPHANUM-11;
break;
case '.':
ac = BIGPERIOD;
break;
case ',':
ac = BIGCOMMA;
break;
case '!':
ac = BIGX;
break;
case '\'':
ac = BIGAPPOS;
break;
case '?':
ac = BIGQ;
break;
case ';':
ac = BIGSEMI;
break;
case ':':
ac = BIGCOLIN;
break;
default:
x += 5;
t++;
continue;
}
rotatesprite(x<<16,y<<16,65536L,0,ac,s,p,10+16,0,0,xdim-1,ydim-1);
x += tiles[ac].dim.width;
t++;
}
return (x);
}
int menutextc(int x,int y,short s,short p,char *t)
{
short i, ac, centre;
s += 8;
y -= 12;
i = centre = 0;
// if( x == (320>>1) )
{
while( *(t+i) )
{
if(*(t+i) == ' ')
{
centre += 5;
i++;
continue;
}
ac = 0;
if(*(t+i) >= '0' && *(t+i) <= '9')
ac = *(t+i) - '0' + BIGALPHANUM+26+26;
if(*(t+i) >= 'a' && *(t+i) <= 'z')
ac = *(t+i) - 'a' + BIGALPHANUM+26;
if(*(t+i) >= 'A' && *(t+i) <= 'Z')
ac = *(t+i) - 'A' + BIGALPHANUM;
else switch(*t)
{
case '-':
ac = BIGALPHANUM-11;
break;
case '.':
ac = BIGPERIOD;
break;
case ',':
ac = BIGCOMMA;
break;
case '!':
ac = BIGX;
break;
case '?':
ac = BIGQ;
break;
case ';':
ac = BIGSEMI;
break;
case ':':
ac = BIGCOLIN;
break;
}
centre += tiles[ac].dim.width-1;
i++;
}
}
x -= centre>>1;
while(*t)
{
if(*t == ' ') {x+=5;t++;continue;}
ac = 0;
if(*t >= '0' && *t <= '9')
ac = *t - '0' + BIGALPHANUM+26+26;
if(*t >= 'a' && *t <= 'z')
ac = *t - 'a' + BIGALPHANUM+26;
if(*t >= 'A' && *t <= 'Z')
ac = *t - 'A' + BIGALPHANUM;
switch(*t)
{
case '-':
ac = BIGALPHANUM-11;
break;
case '.':
ac = BIGPERIOD;
break;
case ',':
ac = BIGCOMMA;
break;
case '!':
ac = BIGX;
break;
case '?':
ac = BIGQ;
break;
case ';':
ac = BIGSEMI;
break;
case ':':
ac = BIGCOLIN;
break;
}
rotatesprite(x<<16,y<<16,65536L,0,ac,s,p,10+16,0,0,xdim-1,ydim-1);
x += tiles[ac].dim.width;
t++;
}
return (x);
}
void bar(int x,int y,short *p,short dainc,uint8_t damodify,short s, short pa)
{
short xloc;
uint8_t rev;
if(dainc < 0) { dainc = -dainc; rev = 1; }
else rev = 0;
y-=2;
if(damodify)
{
if(rev == 0)
{
if( KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed( sc_kpad_4 ) || ((buttonstat&1) && minfo.dyaw < -256 ) ) // && onbar) )
{
KB_ClearKeyDown( sc_LeftArrow );
KB_ClearKeyDown( sc_kpad_4 );
*p -= dainc;
if(*p < 0)
*p = 0;
sound(KICK_HIT);
}
if( KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_kpad_6 ) || ((buttonstat&1) && minfo.dyaw > 256 ) )//&& onbar) )
{
KB_ClearKeyDown( sc_RightArrow );
KB_ClearKeyDown( sc_kpad_6 );
*p += dainc;
if(*p > 63)
*p = 63;
sound(KICK_HIT);
}
}
else
{
if( KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_kpad_6 ) || ((buttonstat&1) && minfo.dyaw > 256 ))//&& onbar ))
{
KB_ClearKeyDown( sc_RightArrow );
KB_ClearKeyDown( sc_kpad_6 );
*p -= dainc;
if(*p < 0)
*p = 0;
sound(KICK_HIT);
}
if( KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed( sc_kpad_4 ) || ((buttonstat&1) && minfo.dyaw < -256 ))// && onbar) )
{
KB_ClearKeyDown( sc_LeftArrow );
KB_ClearKeyDown( sc_kpad_4 );
*p += dainc;
if(*p > 64)
*p = 64;
sound(KICK_HIT);
}
}
}
xloc = *p;
rotatesprite( (x+22)<<16,(y-3)<<16,65536L,0,SLIDEBAR,s,pa,10,0,0,xdim-1,ydim-1);
if(rev == 0)
rotatesprite( (x+xloc+1)<<16,(y+1)<<16,65536L,0,SLIDEBAR+1,s,pa,10,0,0,xdim-1,ydim-1);
else
rotatesprite( (x+(65-xloc) )<<16,(y+1)<<16,65536L,0,SLIDEBAR+1,s,pa,10,0,0,xdim-1,ydim-1);
}
#define SHX(X) 0
// ((x==X)*(-sh))
#define PHX(X) 0
// ((x==X)?1:2)
#define MWIN(X) rotatesprite( 320<<15,200<<15,X,0,MENUSCREEN,-16,0,10+64,0,0,xdim-1,ydim-1)
#define MWINXY(X,OX,OY) rotatesprite( ( 320+(OX) )<<15, ( 200+(OY) )<<15,X,0,MENUSCREEN,-16,0,10+64,0,0,xdim-1,ydim-1)
int32 volnum,levnum,plrskl,numplr;
short lastsavedpos = -1;
void dispnames(void)
{
short x, c = 160;
c += 64;
for(x = 0;x <= 108;x += 12)
rotatesprite((c+91-64)<<16,(x+56)<<16,65536L,0,TEXTBOX,24,0,10,0,0,xdim-1,ydim-1);
rotatesprite(22<<16,97<<16,65536L,0,WINDOWBORDER2,24,0,10,0,0,xdim-1,ydim-1);
rotatesprite(180<<16,97<<16,65536L,1024,WINDOWBORDER2,24,0,10,0,0,xdim-1,ydim-1);
rotatesprite(99<<16,50<<16,65536L,512,WINDOWBORDER1,24,0,10,0,0,xdim-1,ydim-1);
rotatesprite(103<<16,144<<16,65536L,1024+512,WINDOWBORDER1,24,0,10,0,0,xdim-1,ydim-1);
minitext(c,48,ud.savegame[0],2,10+16);
minitext(c,48+12,ud.savegame[1],2,10+16);
minitext(c,48+12+12,ud.savegame[2],2,10+16);
minitext(c,48+12+12+12,ud.savegame[3],2,10+16);
minitext(c,48+12+12+12+12,ud.savegame[4],2,10+16);
minitext(c,48+12+12+12+12+12,ud.savegame[5],2,10+16);
minitext(c,48+12+12+12+12+12+12,ud.savegame[6],2,10+16);
minitext(c,48+12+12+12+12+12+12+12,ud.savegame[7],2,10+16);
minitext(c,48+12+12+12+12+12+12+12+12,ud.savegame[8],2,10+16);
minitext(c,48+12+12+12+12+12+12+12+12+12,ud.savegame[9],2,10+16);
}
int getfilenames(char kind[6])
{
DIR *dir;
struct dirent *dent;
int add_this;
uint8_t *ptr = NULL;
int len = 0;
int subdirs = 0;
if (strcmp(kind,"SUBD") == 0)
subdirs = 1;
dir = opendir(getGameDir());
if (dir == NULL)
return(-1);
do
{
add_this = 0;
dent = readdir(dir);
if (dent != NULL)
{
if (subdirs)
{
if (rb->dir_exists(dent->d_name))
add_this = 1;
} /* if */
else
{
/* need to expand support if this assertion ever fails. */
assert(stricmp(kind, "*.MAP") == 0);
len = strlen(dent->d_name);
if (len >= 5)
{
ptr = ((uint8_t *) dent->d_name) + len;
ptr += strlen(ptr) - 4;
if (stricmp(ptr, ".MAP") == 0)
add_this = 1;
} /* if */
} /* else */
if (add_this)
{
strcpy(menuname[menunamecnt],dent->d_name);
menuname[menunamecnt][16] = subdirs;
menunamecnt++;
} /* if */
} /* if */
} while (dent != NULL);
closedir(dir);
return(0);
}
void sortfilenames()
{
uint8_t sortbuffer[17];
int32_t i, j, k;
for(i=1;i<menunamecnt;i++)
for(j=0;j<i;j++)
{
k = 0;
while ((menuname[i][k] == menuname[j][k]) && (menuname[i][k] != 0) && (menuname[j][k] != 0))
k++;
if (menuname[i][k] < menuname[j][k])
{
memcpy(&sortbuffer[0],&menuname[i][0],sizeof(menuname[0]));
memcpy(&menuname[i][0],&menuname[j][0],sizeof(menuname[0]));
memcpy(&menuname[j][0],&sortbuffer[0],sizeof(menuname[0]));
}
}
}
int32_t quittimer = 0;
void gameexitanycase(void)
{
KB_FlushKeyboardQueue();
if( gamequit == 0 && ( numplayers > 1 ) )
{
if(ps[myconnectindex].gm&MODE_GAME)
{
gamequit = 1;
quittimer = totalclock+120;
sound(SHORT_CIRCUIT);
}
else
{
sendlogoff();
gameexit(" ");
sound(NITEVISION_ONOFF);
}
}
else if( numplayers < 2 )
gameexit(" ");
if( ( totalclock > quittimer ) && ( gamequit == 1) )
{
gameexit("Timed out.");
}
}
void menus(void)
{
short c,x;
volatile int32_t l;
int i,j;
static int lastkeysetup = 0;
static int waiting4key = false;
static int current_resolution = 0;
char text[512];
getpackets();
if(((ControllerType == controltype_keyboardandmouse)||
(ControllerType == controltype_joystickandmouse))
//&& CONTROL_MousePresent
)
{
if(buttonstat != 0 && !onbar) // anti-repeat
{
x = MOUSE_GetButtons()<<3;
if( x )
{
buttonstat = x<<3;
}
else
{
buttonstat = 0;
}
}
else
buttonstat = MOUSE_GetButtons();
}
else buttonstat = 0;
if( (ps[myconnectindex].gm&MODE_MENU) == 0 )
{
tiles[MAXTILES-3].lock = 1;
return;
}
ps[myconnectindex].gm &= (0xff-MODE_TYPE);
ps[myconnectindex].fta = 0;
x = 0;
sh = 4-(sintable[(totalclock<<4)&2047]>>11);
if(!(current_menu >= 1000 && current_menu <= 2999 && current_menu >= 300 && current_menu <= 369))
vscrn();
// printf("Current menu=%d, game mode=%d, last menu =%d\n", current_menu, ps[myconnectindex].gm, last_menu);
switch(current_menu)
{
case 25000:
gametext(160,90,"SELECT A SAVE SPOT BEFORE",0,2+8+16);
gametext(160,90+9,"YOU QUICK RESTORE.",0,2+8+16);
x = probe(186,124,0,0);
if(x >= -1)
{
if(ud.multimode < 2 && ud.recstat != 2)
{
ready2send = 1;
totalclock = ototalclock;
}
ps[myconnectindex].gm &= ~MODE_MENU;
}
break;
case 20000:
x = probe(326,190,0,0);
gametext(160,50-8,"YOU ARE PLAYING THE SHAREWARE",0,2+8+16);
gametext(160,59-8,"VERSION OF DUKE NUKEM 3D. WHILE",0,2+8+16);
gametext(160,68-8,"THIS VERSION IS REALLY COOL, YOU",0,2+8+16);
gametext(160,77-8,"ARE MISSING OVER 75% OF THE TOTAL",0,2+8+16);
gametext(160,86-8,"GAME, ALONG WITH OTHER GREAT EXTRAS",0,2+8+16);
gametext(160,95-8,"AND GAMES, WHICH YOU'LL GET WHEN",0,2+8+16);
gametext(160,104-8,"YOU ORDER THE COMPLETE VERSION AND",0,2+8+16);
gametext(160,113-8,"GET THE FINAL TWO EPISODES.",0,2+8+16);
gametext(160,113+8,"PLEASE READ THE 'HOW TO ORDER' ITEM",0,2+8+16);
gametext(160,122+8,"ON THE MAIN MENU IF YOU WISH TO",0,2+8+16);
gametext(160,131+8,"UPGRADE TO THE FULL REGISTERED",0,2+8+16);
gametext(160,140+8,"VERSION OF DUKE NUKEM 3D.",0,2+8+16);
gametext(160,149+16,"PRESS ANY KEY...",0,2+8+16);
if( x >= -1 ) cmenu(100);
break;
case 15001:
case 15000:
gametext(160,90,"LOAD last game:",0,2+8+16);
sprintf(text,"\"%s\"",ud.savegame[lastsavedpos]);
gametext(160,99,text,0,2+8+16);
gametext(160,99+9,"(Y/N)",0,2+8+16);
_handle_events();
if( KB_KeyPressed(sc_Escape) || KB_KeyPressed(sc_N) || RMB)
{
if(sprite[ps[myconnectindex].i].extra <= 0)
{
enterlevel(MODE_GAME);
return;
}
KB_ClearKeyDown(sc_N);
KB_ClearKeyDown(sc_Escape);
ps[myconnectindex].gm &= ~MODE_MENU;
if(ud.multimode < 2 && ud.recstat != 2)
{
ready2send = 1;
totalclock = ototalclock;
}
}
if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB )
{
KB_FlushKeyboardQueue();
FX_StopAllSounds();
if(ud.multimode > 1)
{
loadplayer(-1-lastsavedpos);
ps[myconnectindex].gm = MODE_GAME;
}
else
{
c = loadplayer(lastsavedpos);
if(c == 0)
ps[myconnectindex].gm = MODE_GAME;
}
}
probe(186,124+9,0,0);
break;
case 10000: // parental
case 10001:
c = (320>>1)-120;
rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
menutext(320>>1,24,0,0,"ADULT MODE");
x = probe(c+6,43,16,2);
if(x == -1)
{
cmenu(702);
probey = 6;
break;
}
menutext(c,43,SHX(-2),PHX(-2),"ADULT MODE");
menutext(c+160+40,43,0,0,ud.lockout?"OFF":"ON");
menutext(c,43+16,SHX(-3),PHX(-3),"ENTER PASSWORD");
if(current_menu == 10001)
{
gametext(160,43+16+16+16-12,"ENTER PASSWORD",0,2+8+16);
x = strget((320>>1),43+16+16+16,buf,19, 998);
if(x == 1) // user hit enter key
{
if(ud.pwlockout[0] == 0 || ud.lockout == 0 ) // if already unlocked then we set pwd or reset pwd is there is already one
strcpy(&ud.pwlockout[0],buf);
else if( strcmp(buf,&ud.pwlockout[0]) == 0 ) // if (pwd was up AND lockout is true (locked) AND pwd is good)
{
ud.lockout = 0;
buf[0] = 0;
for(x=0;x<numanimwalls;x++)
if( wall[animwall[x].wallnum].picnum != W_SCREENBREAK &&
wall[animwall[x].wallnum].picnum != W_SCREENBREAK+1 &&
wall[animwall[x].wallnum].picnum != W_SCREENBREAK+2 )
if( wall[animwall[x].wallnum].extra >= 0 )
wall[animwall[x].wallnum].picnum = wall[animwall[x].wallnum].extra;
}
current_menu = 10000;
KB_ClearKeyDown(sc_Enter);
KB_ClearKeyDown(sc_kpad_Enter);
KB_FlushKeyboardQueue();
}
else if(x==-1) // pressed esc while typing. We discard the text.
{
*buf = 0;
current_menu = 10000;
KB_ClearKeyDown(sc_Escape);
}
}
else
{
if(x == 0)
{
if( ud.lockout == 1 )
{
if(ud.pwlockout[0] == 0)
{
ud.lockout = 0;
for(x=0;x<numanimwalls;x++)
if( wall[animwall[x].wallnum].picnum != W_SCREENBREAK &&
wall[animwall[x].wallnum].picnum != W_SCREENBREAK+1 &&
wall[animwall[x].wallnum].picnum != W_SCREENBREAK+2 )
if( wall[animwall[x].wallnum].extra >= 0 )
wall[animwall[x].wallnum].picnum = wall[animwall[x].wallnum].extra;
}
else
{
buf[0] = 0;
current_menu = 10001;
inputloc = 0;
KB_FlushKeyboardQueue();
}
}
else
{
ud.lockout = 1;
for(x=0;x<numanimwalls;x++)
switch(wall[animwall[x].wallnum].picnum)
{
case FEMPIC1:
wall[animwall[x].wallnum].picnum = BLANKSCREEN;
break;
case FEMPIC2:
case FEMPIC3:
wall[animwall[x].wallnum].picnum = SCREENBREAK6;
break;
}
}
}
else if(x == 1)
{
current_menu = 10001; // ask for password change
inputloc = 0;
*buf = 0;
KB_FlushKeyboardQueue();
}
}
break;
case 1000:
case 1001:
case 1002:
case 1003:
case 1004:
case 1005:
case 1006:
case 1007:
case 1008:
case 1009:
rotatesprite(160<<16,200<<15,65536L,0,MENUSCREEN,16,0,10+64,0,0,xdim-1,ydim-1);
rotatesprite(160<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
menutext(160,24,0,0,"LOAD GAME");
rotatesprite(101<<16,97<<16,65536,512,MAXTILES-3,-32,0,4+10+64,0,0,xdim-1,ydim-1);
dispnames();
sprintf((char*)tempbuf,"PLAYERS: %-2d ",numplr);
gametext(160,158,(char*)tempbuf,0,2+8+16);
sprintf((char*)tempbuf,"EPISODE: %-2d / LEVEL: %-2d / SKILL: %-2d",1+volnum,1+levnum,plrskl);
gametext(160,170,(char*)tempbuf,0,2+8+16);
gametext(160,90,"LOAD game:",0,2+8+16);
sprintf((char*)tempbuf,"\"%s\"",ud.savegame[current_menu-1000]);
gametext(160,99,(char*)tempbuf,0,2+8+16);
gametext(160,99+9,"(Y/N)",0,2+8+16);
_handle_events();
if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB )
{
lastsavedpos = current_menu-1000;
KB_FlushKeyboardQueue();
//if(ud.multimode < 2 && ud.recstat != 2)
//{
// ready2send = 1;
// totalclock = ototalclock;
//}
if(ud.multimode > 1)
{
if( ps[myconnectindex].gm&MODE_GAME )
{
loadplayer(-1-lastsavedpos);
ps[myconnectindex].gm = MODE_GAME;
}
else
{
tempbuf[0] = 126;
tempbuf[1] = lastsavedpos;
for(x=connecthead;x>=0;x=connectpoint2[x])
if(x != myconnectindex)
sendpacket(x,(uint8_t*)tempbuf,2);
getpackets();
loadplayer(lastsavedpos);
multiflag = 0;
}
}
else
{
// FIX_00084: Various bugs in the load game (single player) option if ESC is hit or if wrong version
c = loadplayer(lastsavedpos);
if(c == 0)
{
ps[myconnectindex].gm = MODE_GAME;
if (ud.recstat != 2) // if not playing a demo then ..
totalclock = ototalclock;
}
else
cmenu(1010); // failed loading game
}
break;
}
if( KB_KeyPressed(sc_N) || KB_KeyPressed(sc_Escape) || RMB)
{
KB_ClearKeyDown(sc_N);
KB_ClearKeyDown(sc_Escape);
sound(EXITMENUSOUND);
cmenu(300);
// FIX_00084: Various bugs in the load game (single player) option if ESC is hit or if wrong version
// simply get back w/o changing anything.
}
break;
case 1010: //loading a saved game failed
gametext(160,99,"YOU CAN'T LOAD THIS GAME",0,2+8+16);
gametext(160,99+9,"EITHER A WONG VERSION",0,2+8+16);
gametext(160,99+9+9,"OR BAD # OF PLAYERS OR...",0,2+8+16);
_handle_events();
if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Escape) || KB_KeyPressed(sc_Enter)
|| RMB) {
KB_ClearKeyDown(sc_Space);
KB_ClearKeyDown(sc_Escape);
KB_ClearKeyDown(sc_Enter);
sound(EXITMENUSOUND);
cmenu(300);
}
break;
case 1500:
_handle_events();
if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB )
{
KB_FlushKeyboardQueue();
cmenu(100);
}
if( KB_KeyPressed(sc_N) || KB_KeyPressed(sc_Escape) || RMB)
{
KB_ClearKeyDown(sc_N);
KB_ClearKeyDown(sc_Escape);
if(ud.multimode < 2 && ud.recstat != 2)
{
ready2send = 1;
totalclock = ototalclock;
}
ps[myconnectindex].gm &= ~MODE_MENU;
sound(EXITMENUSOUND);
break;
}
probe(186,124,0,0);
gametext(160,90,"ABORT this game?",0,2+8+16);
gametext(160,90+9,"(Y/N)",0,2+8+16);
break;
case 2000:
case 2001:
case 2002:
case 2003:
case 2004:
case 2005:
case 2006:
case 2007:
case 2008:
case 2009:
rotatesprite(160<<16,200<<15,65536L,0,MENUSCREEN,16,0,10+64,0,0,xdim-1,ydim-1);
rotatesprite(160<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
menutext(160,24,0,0,"SAVE GAME");
rotatesprite(101<<16,97<<16,65536L,512,MAXTILES-3,-32,0,4+10+64,0,0,xdim-1,ydim-1);
sprintf(text,"PLAYERS: %-2d ",ud.multimode);
gametext(160,158,text,0,2+8+16);
sprintf(text,"EPISODE: %-2d / LEVEL: %-2d / SKILL: %-2d",1+ud.volume_number,1+ud.level_number,ud.player_skill);
gametext(160,170,text,0,2+8+16);
dispnames();
gametext(160,90,"OVERWRITE previous SAVED game?",0,2+8+16);
gametext(160,90+9,"(Y/N)",0,2+8+16);
_handle_events();
if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB )
{
KB_FlushKeyboardQueue();
inputloc = strlen(&ud.savegame[current_menu-2000][0]);
cmenu(current_menu-2000+360);
KB_FlushKeyboardQueue();
break;
}
if( KB_KeyPressed(sc_N) || KB_KeyPressed(sc_Escape) || RMB)
{
KB_ClearKeyDown(sc_N);
KB_ClearKeyDown(sc_Escape);
cmenu(351);
sound(EXITMENUSOUND);
}
probe(186,124,0,0);
break;
case 990: // credits
case 991:
case 992:
case 993:
case 994:
case 995:
case 996:
case 997:
c = 160;
if (!PLUTOPAK) {
//rotatesprite(c<<16,200<<15,65536L,0,MENUSCREEN,16,0,10+64,0,0,xdim-1,ydim-1);
rotatesprite(c<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
menutext(c,24,0,0,"CREDITS");
l = 7;
} else {
l = 2;
}
if(KB_KeyPressed(sc_Escape)) { cmenu(0); break; }
if( KB_KeyPressed( sc_LeftArrow ) ||
KB_KeyPressed( sc_kpad_4 ) ||
KB_KeyPressed( sc_UpArrow ) ||
KB_KeyPressed( sc_PgUp ) ||
KB_KeyPressed( sc_kpad_8 ) )
{
KB_ClearKeyDown(sc_LeftArrow);
KB_ClearKeyDown(sc_kpad_4);
KB_ClearKeyDown(sc_UpArrow);
KB_ClearKeyDown(sc_PgUp);
KB_ClearKeyDown(sc_kpad_8);
sound(KICK_HIT);
current_menu--;
if(current_menu < 990) current_menu = 990+l;
}
else if(
KB_KeyPressed( sc_PgDn ) ||
KB_KeyPressed( sc_Enter ) ||
KB_KeyPressed( sc_Space ) ||
KB_KeyPressed( sc_kpad_Enter ) ||
KB_KeyPressed( sc_RightArrow ) ||
KB_KeyPressed( sc_DownArrow ) ||
KB_KeyPressed( sc_kpad_2 ) ||
KB_KeyPressed( sc_kpad_9 ) ||
KB_KeyPressed( sc_kpad_6 ) )
{
KB_ClearKeyDown(sc_PgDn);
KB_ClearKeyDown(sc_Enter);
KB_ClearKeyDown(sc_RightArrow);
KB_ClearKeyDown(sc_kpad_Enter);
KB_ClearKeyDown(sc_kpad_6);
KB_ClearKeyDown(sc_kpad_9);
KB_ClearKeyDown(sc_kpad_2);
KB_ClearKeyDown(sc_DownArrow);
KB_ClearKeyDown(sc_Space);
sound(KICK_HIT);
current_menu++;
if(current_menu > 990+l) current_menu = 990;
}
if (!PLUTOPAK) { // This is Jonathon Fowler code. Text respects the true 1.3/1.3d --mk
switch (current_menu) {
case 990:
gametext(c,40, "ORIGINAL CONCEPT",0,2+8+16);
gametext(c,40+9, "TODD REPLOGLE",0,2+8+16);
gametext(c,40+9+9, "ALLEN H. BLUM III",0,2+8+16);
gametext(c,40+9+9+9+9, "PRODUCED & DIRECTED BY",0,2+8+16);
gametext(c,40+9+9+9+9+9, "GREG MALONE",0,2+8+16);
gametext(c,40+9+9+9+9+9+9+9, "EXECUTIVE PRODUCER",0,2+8+16);
gametext(c,40+9+9+9+9+9+9+9+9, "GEORGE BROUSSARD",0,2+8+16);
gametext(c,40+9+9+9+9+9+9+9+9+9+9, "BUILD ENGINE",0,2+8+16);
gametext(c,40+9+9+9+9+9+9+9+9+9+9+9,"KEN SILVERMAN",0,2+8+16);
break;
case 991:
gametext(c,40, "GAME PROGRAMMING",0,2+8+16);
gametext(c,40+9, "TODD REPLOGLE",0,2+8+16);
gametext(c,40+9+9+9, "3D ENGINE/TOOLS/NET",0,2+8+16);
gametext(c,40+9+9+9+9, "KEN SILVERMAN",0,2+8+16);
gametext(c,40+9+9+9+9+9+9, "NETWORK LAYER/SETUP PROGRAM",0,2+8+16);
gametext(c,40+9+9+9+9+9+9+9, "MARK DOCHTERMANN",0,2+8+16);
break;
case 992:
gametext(c,40, "MAP DESIGN",0,2+8+16);
gametext(c,40+9, "ALLEN H BLUM III",0,2+8+16);
gametext(c,40+9+9, "RICHARD GRAY",0,2+8+16);
gametext(c,40+9+9+9+9, "3D MODELING",0,2+8+16);
gametext(c,40+9+9+9+9+9, "CHUCK JONES",0,2+8+16);
gametext(c,40+9+9+9+9+9+9, "SAPPHIRE CORPORATION",0,2+8+16);
gametext(c,40+9+9+9+9+9+9+9+9, "ARTWORK",0,2+8+16);
gametext(c,40+9+9+9+9+9+9+9+9+9, "DIRK JONES, STEPHEN HORNBACK",0,2+8+16);
gametext(c,40+9+9+9+9+9+9+9+9+9+9, "JAMES STOREY, DAVID DEMARET",0,2+8+16);
gametext(c,40+9+9+9+9+9+9+9+9+9+9+9,"DOUGLAS R WOOD",0,2+8+16);
break;
case 993:
gametext(c,40, "SOUND ENGINE",0,2+8+16);
gametext(c,40+9, "JIM DOSE",0,2+8+16);
gametext(c,40+9+9+9, "SOUND & MUSIC DEVELOPMENT",0,2+8+16);
gametext(c,40+9+9+9+9, "ROBERT PRINCE",0,2+8+16);
gametext(c,40+9+9+9+9+9, "LEE JACKSON",0,2+8+16);
gametext(c,40+9+9+9+9+9+9+9, "VOICE TALENT",0,2+8+16);
gametext(c,40+9+9+9+9+9+9+9+9, "LANI MINELLA - VOICE PRODUCER",0,2+8+16);
gametext(c,40+9+9+9+9+9+9+9+9+9, "JON ST. JOHN AS \"DUKE NUKEM\"",0,2+8+16);
break;
case 994:
gametext(c,60, "GRAPHIC DESIGN",0,2+8+16);
gametext(c,60+9, "PACKAGING, MANUAL, ADS",0,2+8+16);
gametext(c,60+9+9, "ROBERT M. ATKINS",0,2+8+16);
gametext(c,60+9+9+9, "MICHAEL HADWIN",0,2+8+16);
gametext(c,60+9+9+9+9+9, "SPECIAL THANKS TO",0,2+8+16);
gametext(c,60+9+9+9+9+9+9, "STEVEN BLACKBURN, TOM HALL",0,2+8+16);
gametext(c,60+9+9+9+9+9+9+9, "SCOTT MILLER, JOE SIEGLER",0,2+8+16);
gametext(c,60+9+9+9+9+9+9+9+9, "TERRY NAGY, COLLEEN COMPTON",0,2+8+16);
gametext(c,60+9+9+9+9+9+9+9+9+9, "HASH INC., FORMGEN, INC.",0,2+8+16);
break;
case 995:
gametext(c,49, "THE 3D REALMS BETA TESTERS",0,2+8+16);
gametext(c,49+9+9, "NATHAN ANDERSON, WAYNE BENNER",0,2+8+16);
gametext(c,49+9+9+9, "GLENN BRENSINGER, ROB BROWN",0,2+8+16);
gametext(c,49+9+9+9+9, "ERIK HARRIS, KEN HECKBERT",0,2+8+16);
gametext(c,49+9+9+9+9+9, "TERRY HERRIN, GREG HIVELY",0,2+8+16);
gametext(c,49+9+9+9+9+9+9, "HANK LEUKART, ERIC BAKER",0,2+8+16);
gametext(c,49+9+9+9+9+9+9+9, "JEFF RAUSCH, KELLY ROGERS",0,2+8+16);
gametext(c,49+9+9+9+9+9+9+9+9, "MIKE DUNCAN, DOUG HOWELL",0,2+8+16);
gametext(c,49+9+9+9+9+9+9+9+9+9, "BILL BLAIR",0,2+8+16);
break;
case 996:
gametext(c,32, "COMPANY PRODUCT SUPPORT",0,2+8+16);
gametext(c,32+9+9, "THE FOLLOWING COMPANIES WERE COOL",0,2+8+16);
gametext(c,32+9+9+9, "ENOUGH TO GIVE US LOTS OF STUFF",0,2+8+16);
gametext(c,32+9+9+9+9, "DURING THE MAKING OF DUKE NUKEM 3D.",0,2+8+16);
gametext(c,32+9+9+9+9+9+9, "ALTEC LANSING MULTIMEDIA",0,2+8+16);
gametext(c,32+9+9+9+9+9+9+9, "FOR TONS OF SPEAKERS AND THE",0,2+8+16);
gametext(c,32+9+9+9+9+9+9+9+9, "THX-LICENSED SOUND SYSTEM",0,2+8+16);
gametext(c,32+9+9+9+9+9+9+9+9+9, "FOR INFO CALL 1-800-548-0620",0,2+8+16);
gametext(c,32+9+9+9+9+9+9+9+9+9+9+9,"CREATIVE LABS, INC.",0,2+8+16);
gametext(c,32+9+9+9+9+9+9+9+9+9+9+9+9+9,"THANKS FOR THE HARDWARE, GUYS.",0,2+8+16);
break;
case 997:
gametext(c,50, "DUKE NUKEM IS A TRADEMARK OF",0,2+8+16);
gametext(c,50+9, "3D REALMS ENTERTAINMENT",0,2+8+16);
gametext(c,50+9+9+9, "DUKE NUKEM",0,2+8+16);
gametext(c,50+9+9+9+9, "(C) 1996 3D REALMS ENTERTAINMENT",0,2+8+16);
if (VOLUMEONE) {
gametext(c,106, "PLEASE READ LICENSE.DOC FOR SHAREWARE",0,2+8+16);
gametext(c,106+9, "DISTRIBUTION GRANTS AND RESTRICTIONS",0,2+8+16);
}
gametext(c,VOLUMEONE?134:115, "MADE IN DALLAS, TEXAS USA",0,2+8+16);
break;
}
}
switch(current_menu)
{
case 990:
case 991:
case 992:
rotatesprite(160<<16,200<<15,65536L,0,2504+current_menu-990,0,0,10+64,0,0,xdim-1,ydim-1);
break;
}
break;
case 0: // main menu
c = (320>>1);
rotatesprite(c<<16,28<<16,65536L,0,INGAMEDUKETHREEDEE,0,0,10,0,0,xdim-1,ydim-1);
rotatesprite((c+100)<<16,36<<16,65536L,0,PLUTOPAKSPRITE+2,(sintable[(totalclock<<4)&2047]>>11),0,2+8,0,0,xdim-1,ydim-1);
x = probe(c,67,16,6);
if(x >= 0)
{
if( ud.multimode > 1 && x == 0 && ud.recstat != 2)
{
if( movesperpacket == 4 && myconnectindex != connecthead )
break;
last_zero = 0;
cmenu( 600 );
}
else
{
last_zero = x;
switch(x)
{
case 0:
cmenu(100);
break;
case 1: cmenu(200);break;
case 2:
if(movesperpacket == 4 && connecthead != myconnectindex)
break;
cmenu(300);
break;
case 3: KB_FlushKeyboardQueue();cmenu(400);break; // help
case 4: cmenu(990);break; // credit
case 5: cmenu(501);break; // quit
}
}
}
if(KB_KeyPressed(sc_Q)) cmenu(501);
if(x == -1)
{
// FIX_00069: Hitting Esc at the menu screen shows an empty green screen
if(ud.recstat == 2) // playing demo
ps[myconnectindex].gm &= ~MODE_MENU;
}
if(movesperpacket == 4)
{
if( myconnectindex == connecthead )
menutext(c,67,SHX(-2),PHX(-2),"NEW GAME");
else
menutext(c,67,SHX(-2),1,"NEW GAME");
}
else
menutext(c,67,SHX(-2),PHX(-2),"NEW GAME");
menutext(c,67+16,SHX(-3),PHX(-3),"OPTIONS");
if(movesperpacket == 4 && connecthead != myconnectindex)
menutext(c,67+16+16,SHX(-4),1,"LOAD GAME");
else menutext(c,67+16+16,SHX(-4),PHX(-4),"LOAD GAME");
if(VOLUMEONE)
menutext(c,67+16+16+16,SHX(-5),PHX(-5),"HOW TO ORDER");
else
menutext(c,67+16+16+16,SHX(-5),PHX(-5),"HELP");
menutext(c,67+16+16+16+16,SHX(-6),PHX(-6),"CREDITS");
menutext(c,67+16+16+16+16+16,SHX(-7),PHX(-7),"QUIT");
break;
// CTW END - MODIFICATION
case 50: // general menu as cmenu(0) but for multiplayer games
c = (320>>1);
rotatesprite(c<<16,32<<16,65536L,0,INGAMEDUKETHREEDEE,0,0,10,0,0,xdim-1,ydim-1);
rotatesprite((c+100)<<16,36<<16,65536L,0,PLUTOPAKSPRITE+2,(sintable[(totalclock<<4)&2047]>>11),0,2+8,0,0,xdim-1,ydim-1);
x = probe(c,67,16,7);
switch(x)
{
case 0:
if(movesperpacket == 4 && myconnectindex != connecthead)
break;
if(ud.multimode < 2 || ud.recstat == 2)
cmenu(1500);
else
{
cmenu(600);
last_fifty = 0;
}
break;
case 1:
if(movesperpacket == 4 && connecthead != myconnectindex)
break;
if(ud.recstat != 2)
{
last_fifty = 1;
cmenu(350);
setview(0,0,xdim-1,ydim-1);
}
break;
case 2:
if(movesperpacket == 4 && connecthead != myconnectindex)
break;
last_fifty = 2;
cmenu(300);
break;
case 3:
last_fifty = 3;
cmenu(200);
break;
case 4:
last_fifty = 4;
KB_FlushKeyboardQueue();
cmenu(400);
break;
case 5:
if(numplayers < 2)
{
last_fifty = 5;
cmenu(503);
}
break;
case 6:
last_fifty = 6;
cmenu(502);
break;
case -1:
ps[myconnectindex].gm &= ~MODE_MENU;
if(ud.multimode < 2 && ud.recstat != 2)
{
ready2send = 1;
totalclock = ototalclock;
}
break;
}
if( KB_KeyPressed(sc_Q) )
cmenu(502);
if(movesperpacket == 4 && connecthead != myconnectindex)
{
menutext(c,67+16*0 ,SHX(-2),1,"NEW GAME");
menutext(c,67+16*1 ,SHX(-3),1,"SAVE GAME");
menutext(c,67+16*2 ,SHX(-4),1,"LOAD GAME");
}
else
{
menutext(c,67+16*0 ,SHX(-2),PHX(-2),"NEW GAME");
menutext(c,67+16*1 ,SHX(-3),PHX(-3),"SAVE GAME");
menutext(c,67+16*2 ,SHX(-4),PHX(-4),"LOAD GAME");
}
menutext(c,67+16*3 ,SHX(-5),PHX(-5),"OPTIONS");
if(VOLUMEONE)
menutext(c,67+16*4 ,SHX(-6),PHX(-6),"HOW TO ORDER");
else
menutext(c,67+16*4 ,SHX(-6),PHX(-6)," HELP");
if(numplayers > 1)
menutext(c,67+16*5 ,SHX(-7),1,"QUIT TO TITLE");
else menutext(c,67+16*5 ,SHX(-7),PHX(-7),"QUIT TO TITLE");
menutext(c,67+16*6,SHX(-8),PHX(-8),"QUIT GAME");
break;
case 100: // Title menu
rotatesprite(160<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
menutext(160,24,0,0,"SELECT AN EPISODE");
if(PLUTOPAK)
{ //////if(boardfilename[0])
//
// uncomment this for user map
//x = probe(160,60,20,5);
x = probe(160,60,20,4);
//////else x = probe(160,60,20,4);
}
else
{
if(boardfilename[0])
x = probe(160,60,20,4);
else x = probe(160,60,20,3);
}
if(x >= 0)
{
if (VOLUMEONE)
{
if(x > 0)
cmenu(20000);
else
{
ud.m_volume_number = x;
ud.m_level_number = 0;
cmenu(110);
}
}
else
{
if((x == 3 && boardfilename[0])&&!PLUTOPAK)
{
ud.m_volume_number = 0;
ud.m_level_number = 7;
}
else
/*
if(x == 4 && boardfilename[0])
{
ud.m_volume_number = 0;
ud.m_level_number = 7;
}
*/
// USER MAP
if((x == 4)&&PLUTOPAK)
{
//CONSOLE_Printf("MENU_USER_MAP");
//
//[Todo: generate file list starting from .\\maps]")
cmenu(MENU_USER_MAP); // cmenu(101)
break;
}
else
{
ud.m_volume_number = x;
ud.m_level_number = 0;
}
cmenu(110);
}
}
else if(x == -1)
{
if(ps[myconnectindex].gm&MODE_GAME) cmenu(50);
else cmenu(0);
}
menutext(160,60,SHX(-2),PHX(-2),volume_names[0]);
c = 80;
if (VOLUMEONE)
{
menutext(160,60+20,SHX(-3),1,volume_names[1]);
menutext(160,60+20+20,SHX(-4),1,volume_names[2]);
if(PLUTOPAK)
menutext(160,60+20+20,SHX(-5),1,volume_names[3]);
}
else
{
menutext(160,60+20,SHX(-3),PHX(-3),volume_names[1]);
menutext(160,60+20+20,SHX(-4),PHX(-4),volume_names[2]);
if(PLUTOPAK)
{
menutext(160,60+20+20+20,SHX(-5),PHX(-5),volume_names[3]);
//if(boardfilename[0])
//{
// uncomment this for usermap
//menutext(160,60+20+20+20+20,SHX(-6),PHX(-6),"USER MAP");
//gametextpal(160,60+20+20+20+20+3,boardfilename,16+(sintable[(totalclock<<4)&2047]>>11),2);
//}
}
else
{ /*
if(boardfilename[0])
{
menutext(160,60+20+20+20,SHX(-6),PHX(-6),"USER MAP");
gametext(160,60+20+20+20+6,boardfilename,2,2+8+16);
}
*/
}
}
break;
case 101: // MENU_USER_MAP
c = (320>>1);
rotatesprite(c<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
menutext(c,24,0,0,"USER MAP");
// Draw USER MAP background
{
int y, x1;
int32_t xPos, xPos2;
int32_t yPos; //yPos2;
xPos = ( xdim *32) / 320;
yPos = ( ydim *30) / 200;
xPos2 = ( xdim *282) / 320;
//yPos2 = ( ydim *130) / 200;
for(y=yPos; y < (ydim - (yPos*2)); y+=128)
{
for(x1=xPos; x1 < xPos2; x1+=128)
{
rotatesprite(x1<<16,y<<16,65536L,0,BIGHOLE,8,0,1+8+16+64+128,0,0, xdim - xPos, ydim - (yPos*2));
}
}
}
c = (320>>1)-120;
x = probe(c,70,19,4);
if(x == -1)
{
cmenu(MENU_SELECT_EPISODE);
}
break;
case 110:
c = (320>>1);
rotatesprite(c<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
menutext(c,24,0,0,"SELECT SKILL");
x = probe(c,70,19,4);
if(x >= 0)
{
switch(x)
{
case 0: globalskillsound = JIBBED_ACTOR6;break;
case 1: globalskillsound = BONUS_SPEECH1;break;
case 2: globalskillsound = DUKE_GETWEAPON2;break;
case 3: globalskillsound = JIBBED_ACTOR5;break;
}
sound(globalskillsound);
ud.m_player_skill = x+1;
if(x == 3) ud.m_respawn_monsters = 1;
else ud.m_respawn_monsters = 0;
ud.m_monsters_off = ud.monsters_off = 0;
ud.m_respawn_items = 0;
ud.m_respawn_inventory = 0;
ud.multimode = 1;
// if (ud.showcinematics)
//if(ud.m_volume_number == 3) // not needed to play cinematics. Black screen not nice
//{
// flushperms();
// setview(0,0,xdim-1,ydim-1);
// clearview(0L);
// nextpage();
//}
newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill);
enterlevel(MODE_GAME);
}
else if(x == -1)
{
cmenu(100);
KB_FlushKeyboardQueue();
}
menutext(c,70,SHX(-2),PHX(-2),skill_names[0]);
menutext(c,70+19,SHX(-3),PHX(-3),skill_names[1]);
menutext(c,70+19+19,SHX(-4),PHX(-4),skill_names[2]);
menutext(c,70+19+19+19,SHX(-5),PHX(-5),skill_names[3]);
break;
case 200:
rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
menutext(320>>1,24,0,0,"OPTIONS");
c = (320>>1)-120;
x = probe(c+6,43,16,6);
if(x == -1)
{ if(ps[myconnectindex].gm&MODE_GAME) cmenu(50);else cmenu(0); }
switch(x)
{
case 0:
cmenu(702); // game options
break;
case 1:
cmenu(703); // keybaord setup
probey = 7;
break;
case 2:
cmenu(701); // mouse setup
break;
case 3:
cmenu(700); // sound setup
break;
case 4:
cmenu(706); // Video setup
lastkeysetup = 0;
current_resolution = 0; // in case we don't find it
for(i=0; i<validmodecnt; i++)
{
if(validmodexdim[i] == xdim && validmodeydim[i] == ydim)