mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-26 11:40:44 +00:00
1cc9d13ccf
Files moved but not modified. Changes to follow in a subsequent commit. You down with CPP? git-svn-id: https://svn.eduke32.com/eduke32@6055 1a8010ca-5511-0410-912e-c29ae57300e0
5285 lines
156 KiB
C++
5285 lines
156 KiB
C++
//-------------------------------------------------------------------------
|
|
/*
|
|
Copyright (C) 1997, 2005 - 3D Realms Entertainment
|
|
|
|
This file is part of Shadow Warrior version 1.2
|
|
|
|
Shadow Warrior is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
Original Source: 1997 - Frank Maddin and Jim Norwood
|
|
Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
|
|
*/
|
|
//-------------------------------------------------------------------------
|
|
#include "build.h"
|
|
#include "osd.h"
|
|
|
|
#include "keys.h"
|
|
#include "names2.h"
|
|
#include "panel.h"
|
|
#include "game.h"
|
|
#include "tags.h"
|
|
#include "sector.h"
|
|
#include "sprite.h"
|
|
#include "weapon.h"
|
|
#include "player.h"
|
|
#include "jsector.h"
|
|
#include "control.h"
|
|
#include "menus.h"
|
|
#include "sw_strs.h"
|
|
#include "pal.h"
|
|
#include "demo.h"
|
|
|
|
#include "function.h"
|
|
#include "gamedefs.h"
|
|
#include "config.h"
|
|
#include "net.h"
|
|
#include "fx_man.h"
|
|
#include "music.h"
|
|
#include "text.h"
|
|
|
|
#include "colormap.h"
|
|
|
|
//#define PLOCK_VERSION TRUE
|
|
|
|
|
|
short TimeLimitTable[9] = {0,3,5,10,15,20,30,45,60};
|
|
|
|
short QuickLoadNum = -1;
|
|
char QuickLoadDescrDialog[32];
|
|
SWBOOL QuickSaveMode = FALSE;
|
|
SWBOOL SavePrompt = FALSE;
|
|
extern SWBOOL InMenuLevel, LoadGameOutsideMoveLoop, LoadGameFromDemo;
|
|
extern uint8_t RedBookSong[40];
|
|
extern SWBOOL ExitLevel, NewGame;
|
|
extern short Level, Skill;
|
|
extern SWBOOL MusicInitialized, FxInitialized;
|
|
SWBOOL MNU_CheckUserMap(MenuItem *item);
|
|
SWBOOL MNU_SaveGameCheck(MenuItem_p item);
|
|
SWBOOL MNU_TeamPlayCheck(MenuItem *item);
|
|
SWBOOL MNU_CoopPlayCheck(MenuItem *item);
|
|
SWBOOL MNU_StatCheck(MenuItem *item);
|
|
SWBOOL MNU_LoadGameCheck(MenuItem *item);
|
|
SWBOOL MNU_TenCheck(MenuItem *item);
|
|
static SWBOOL MNU_TryMusicInit(void);
|
|
static void MNU_UpLevel(void);
|
|
|
|
SWBOOL MNU_LoadSaveDraw(UserCall call, MenuItem *item);
|
|
SWBOOL MNU_LoadSaveMove(UserCall call, MenuItem *item);
|
|
|
|
SWBOOL MenuButtonAutoRun = FALSE;
|
|
SWBOOL MenuButtonAutoAim = FALSE;
|
|
// misc load-save vars
|
|
short LastSaveNum = 99;
|
|
char SaveGameDescr[10][80];
|
|
char BackupSaveGameDescr[80];
|
|
short screen_tile = -1;
|
|
|
|
SWBOOL MenuInputMode = FALSE;
|
|
int16_t MenuTextShade = 0;
|
|
SWBOOL passwordvalid = FALSE;
|
|
|
|
SWBOOL MNU_HurtTeammateCheck(MenuItem *item);
|
|
SWBOOL MNU_TeamPlayChange(void);
|
|
|
|
// Font pic table
|
|
unsigned short xlatfont[] =
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32
|
|
2274, 2294, 2274, 2277, 2278, 2280, 2295, 2282, 2283, 2281, 2286, 2297, 2285, // 45
|
|
2299, 2301, 2271, 2262, 2263, 2264, 2265, 2266, 2267, 2268, 2269, 2270, // 57
|
|
2292, 2293, 2296, 2287, 2298, 2300, 2275, 2236, 2237, 2238, 2239, 2240, // 69
|
|
2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, // 81
|
|
2253, 2254, 2255, 2256, 2257, 2258, 2259, 2260, 2261, 2290, 2289, 2291, // 93
|
|
2279, 2284, 2295, 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2243, 2244, // 105
|
|
2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, // 117
|
|
2257, 2258, 2259, 2260, 2261, 2282, 2288, 2283, 2272 // 126
|
|
};
|
|
|
|
int slidersettings [sldr_max] =
|
|
{
|
|
0, SENSE_DEFAULT, FXVOL_DEFAULT, MUSIC_DEFAULT, SCRSIZE_DEFAULT,
|
|
BRIGHTNESS_DEFAULT, BORDERTILE_DEFAULT, GAMETYPE_DEFAULT, NETLEVEL_DEFAULT,
|
|
MONSTERS_DEFAULT, KILLLIMIT_DEFAULT, TIMELIMIT_DEFAULT, PLAYERCOLOR_DEFAULT,
|
|
0,0, // video mode
|
|
32767>>12, 32767>>12, // advanced mouse scale
|
|
};
|
|
|
|
short buttonsettings[btn_max];
|
|
|
|
// EXTERNS ////////////////////////////
|
|
#define XDIM 320
|
|
#define YDIM 200
|
|
extern char DefaultPalette[];
|
|
extern SWBOOL QuitFlag;
|
|
|
|
void TerminateGame(void);
|
|
void ResetKeys(void);
|
|
|
|
// GLOBALS ////////////////////////////
|
|
|
|
char playertextbuffer[80]; // Used for various input strings
|
|
char playerbuflen = 0; // Current length of the string in
|
|
// the buffer
|
|
char maxtextlen; // max length allowed for current
|
|
|
|
static struct { int xdim,ydim; } validresolutions[MAXVALIDMODES];
|
|
static int numvalidresolutions = 0, validbpps[8], numvalidbpps = 0;
|
|
|
|
static void UpdateValidModes(int bpp, int fs)
|
|
{
|
|
int i, j;
|
|
|
|
numvalidresolutions = numvalidbpps = 0;
|
|
for (i=0; i<validmodecnt; i++)
|
|
{
|
|
if ((validmode[i].fs & 1) != fs) continue;
|
|
|
|
for (j=0; j<numvalidbpps; j++)
|
|
if (validbpps[j] == validmode[i].bpp) break;
|
|
if (j==numvalidbpps) validbpps[numvalidbpps++] = validmode[i].bpp;
|
|
|
|
if (validmode[i].bpp != bpp) continue;
|
|
|
|
validresolutions[numvalidresolutions].xdim = validmode[i].xdim;
|
|
validresolutions[numvalidresolutions].ydim = validmode[i].ydim;
|
|
numvalidresolutions++;
|
|
}
|
|
}
|
|
static SWBOOL ApplyModeSettings(void)
|
|
{
|
|
int lastx, lasty, lastbpp, lastfs;
|
|
int newx, newy, newbpp, newfs;
|
|
|
|
lastx = xdim; lasty = ydim; lastbpp = bpp; lastfs = fullscreen;
|
|
newx = validresolutions[slidersettings[sldr_videores]].xdim;
|
|
newy = validresolutions[slidersettings[sldr_videores]].ydim;
|
|
newbpp = validbpps[slidersettings[sldr_videobpp]];
|
|
newfs = buttonsettings[btn_videofs];
|
|
|
|
if (lastx == newx && lasty == newy && lastbpp == newbpp && lastfs == newfs) return FALSE;
|
|
|
|
if (setgamemode(newfs, newx, newy, newbpp))
|
|
setgamemode(lastfs, lastx, lasty, lastbpp);
|
|
else
|
|
{
|
|
extern int32_t ScreenMode,ScreenWidth,ScreenHeight,ScreenBPP; // Because I'm too lazy to include config.h
|
|
ScreenMode = newfs;
|
|
ScreenWidth = newx;
|
|
ScreenHeight = newy;
|
|
ScreenBPP = newbpp;
|
|
|
|
SetupAspectRatio();
|
|
SetRedrawScreen(Player + myconnectindex);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
MenuItem sound_i[] =
|
|
{
|
|
{DefButton(btn_music, 0, "Music"), OPT_XS, OPT_LINE(0), 1, m_defshade, 0, MNU_TryMusicInit, MNU_MusicCheck, NULL},
|
|
{DefSlider(sldr_musicvolume, 0, "Music Volume"), OPT_XS, OPT_LINE(1), 1, m_defshade, 0, MNU_TryMusicInit, MNU_MusicCheck, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(1), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
|
|
{DefButton(btn_sound, 0, "Sounds"), OPT_XS, OPT_LINE(2), 1, m_defshade, 0, NULL, MNU_FxCheck, NULL},
|
|
{DefSlider(sldr_sndfxvolume, 0, "Sound Volume"), OPT_XS, OPT_LINE(3), 1, m_defshade, 0, NULL, MNU_FxCheck, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(3), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
|
|
//{DefButton(btn_talking, 0, "Talking"), OPT_XS, OPT_LINE(4), 1, m_defshade, 0, NULL, MNU_FxCheck, NULL},
|
|
{DefButton(btn_ambience, 0, "Ambience"), OPT_XS, OPT_LINE(4), 1, m_defshade, 0, NULL, MNU_FxCheck, NULL},
|
|
{DefButton(btn_flipstereo, 0, "Flip Stereo"), OPT_XS, OPT_LINE(5), 1, m_defshade, 0, NULL, MNU_FxCheck, NULL},
|
|
//{DefButton(btn_playcd, 0, "Play CD"), OPT_XS, OPT_LINE(6), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefNone}
|
|
};
|
|
|
|
MenuGroup soundgroup = {110,5,"^Sound",sound_i,pic_optionstitl,0,m_defshade, NULL,NULL, 0};
|
|
|
|
MenuItem parental_i[] =
|
|
{
|
|
{DefButton(btn_parental, 0, "Kid Mode"), OPT_XS, OPT_LINE(0), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefOption(KEYSC_P, "Change Password"), OPT_XS, OPT_LINE(1), 1, m_defshade, 0, MNU_ParentalCustom, NULL, NULL},
|
|
{DefNone}
|
|
};
|
|
|
|
MenuGroup parentalgroup = {65, 5, "^Kid Mode", parental_i, pic_newgametitl, 0, m_defshade, MNU_DoParentalPassword,NULL,0};
|
|
|
|
MenuItem screen_i[] =
|
|
{
|
|
{DefSlider(sldr_scrsize, 0, "Screen Size"), OPT_XS, OPT_LINE(0), 1, m_defshade, 0, NULL, NULL, NULL}, //, MNU_BorderCheck},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(0), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
|
|
{DefSlider(sldr_bordertile, 0, "Border Tile"), OPT_XS, OPT_LINE(1), 1, m_defshade, 0, NULL, NULL, NULL}, //, MNU_BorderCheck},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(1), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
|
|
{DefSlider(sldr_brightness, KEYSC_B, "Brightness"), OPT_XS, OPT_LINE(2), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(2), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
|
|
{DefButton(btn_videofs, 0, "Fullscreen"), OPT_XS, OPT_LINE(4), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefSlider(sldr_videobpp, 0, "Colour"), OPT_XS, OPT_LINE(5), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(5), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefSlider(sldr_videores, 0, "Resolution"), OPT_XS, OPT_LINE(6), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(6), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefOption(0, "Apply Settings"), OPT_XSIDE, OPT_LINE(8), 1, m_defshade, 0, ApplyModeSettings, NULL, NULL},
|
|
{DefNone}
|
|
};
|
|
|
|
MenuGroup screengroup = {65, 5, "^Screen", screen_i, pic_newgametitl, 0, m_defshade, NULL,NULL, 0};
|
|
|
|
MenuItem mouse_i[] =
|
|
{
|
|
{DefSlider(sldr_mouse, 0, "Mouse Speed"), OPT_XS, OPT_LINE(0), 1, m_defshade, 0, NULL, MNU_MouseCheck, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(0), 0, m_defshade, 0, NULL, NULL, NULL}, // Blank line for mouse
|
|
|
|
{DefButton(btn_mouse_aim, 0, "Mouse Aiming"), OPT_XS, OPT_LINE(1), 1, m_defshade, 0, NULL, MNU_MouseCheck, NULL},
|
|
{DefButton(btn_mouse_invert, 0, "Invert Mouse"), OPT_XS, OPT_LINE(2), 1, m_defshade, 0, NULL, MNU_MouseCheck, NULL},
|
|
{DefNone}
|
|
};
|
|
|
|
MenuGroup mousegroup = {65, 5, "^Mouse", mouse_i, pic_newgametitl, 0, m_defshade, NULL,NULL, 0};
|
|
|
|
MenuGroup keysetupgroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_KeySetupCustom, NULL, 0};
|
|
|
|
static char MouseButtonFunctions[10][MAXFUNCTIONLENGTH];
|
|
static SWBOOL MNU_SetMouseButtonFunctions(MenuItem_p item);
|
|
static SWBOOL MNU_MouseButtonPostProcess(MenuItem_p item);
|
|
static SWBOOL MNU_MouseButtonSetupCustom(UserCall call, MenuItem_p item);
|
|
MenuGroup mousebuttongroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_MouseButtonSetupCustom, NULL, 0};
|
|
MenuItem mousesetup_i[] =
|
|
{
|
|
{DefLayer(0, "Left", &mousebuttongroup), OPT_XS, OPT_LINE(0), 1, m_defshade, 0, NULL, NULL, MNU_MouseButtonPostProcess},
|
|
{DefInert(0, MouseButtonFunctions[0]), OPT_XSIDE, OPT_LINE(0), 1, m_defshade, 0, NULL, MNU_SetMouseButtonFunctions, NULL},
|
|
{DefLayer(0, "Double Left", &mousebuttongroup), OPT_XS, OPT_LINE(1), 1, m_defshade, 6+0, NULL, NULL, MNU_MouseButtonPostProcess},
|
|
{DefInert(0, MouseButtonFunctions[6+0]), OPT_XSIDE, OPT_LINE(1), 1, m_defshade, 6+0, NULL, MNU_SetMouseButtonFunctions, NULL},
|
|
{DefLayer(0, "Right", &mousebuttongroup), OPT_XS, OPT_LINE(2), 1, m_defshade, 1, NULL, NULL, MNU_MouseButtonPostProcess},
|
|
{DefInert(0, MouseButtonFunctions[1]), OPT_XSIDE, OPT_LINE(2), 1, m_defshade, 1, NULL, MNU_SetMouseButtonFunctions, NULL},
|
|
{DefLayer(0, "Double Right", &mousebuttongroup), OPT_XS, OPT_LINE(3), 1, m_defshade, 6+1, NULL, NULL, MNU_MouseButtonPostProcess},
|
|
{DefInert(0, MouseButtonFunctions[6+1]), OPT_XSIDE, OPT_LINE(3), 1, m_defshade, 6+1, NULL, MNU_SetMouseButtonFunctions, NULL},
|
|
{DefLayer(0, "Middle", &mousebuttongroup), OPT_XS, OPT_LINE(4), 1, m_defshade, 2, NULL, NULL, MNU_MouseButtonPostProcess},
|
|
{DefInert(0, MouseButtonFunctions[2]), OPT_XSIDE, OPT_LINE(4), 1, m_defshade, 2, NULL, MNU_SetMouseButtonFunctions, NULL},
|
|
{DefLayer(0, "Double Middle", &mousebuttongroup), OPT_XS, OPT_LINE(5), 1, m_defshade, 6+2, NULL, NULL, MNU_MouseButtonPostProcess},
|
|
{DefInert(0, MouseButtonFunctions[6+2]), OPT_XSIDE, OPT_LINE(5), 1, m_defshade, 6+2, NULL, MNU_SetMouseButtonFunctions, NULL},
|
|
{DefLayer(0, "Thumb", &mousebuttongroup), OPT_XS, OPT_LINE(6), 1, m_defshade, 3, NULL, NULL, MNU_MouseButtonPostProcess},
|
|
{DefInert(0, MouseButtonFunctions[3]), OPT_XSIDE, OPT_LINE(6), 1, m_defshade, 3, NULL, MNU_SetMouseButtonFunctions, NULL},
|
|
{DefLayer(0, "Double Thumb", &mousebuttongroup), OPT_XS, OPT_LINE(7), 1, m_defshade, 6+3, NULL, NULL, MNU_MouseButtonPostProcess},
|
|
{DefInert(0, MouseButtonFunctions[6+3]), OPT_XSIDE, OPT_LINE(7), 1, m_defshade, 6+3, NULL, MNU_SetMouseButtonFunctions, NULL},
|
|
{DefLayer(0, "Wheel Up", &mousebuttongroup), OPT_XS, OPT_LINE(8), 1, m_defshade, 4, NULL, NULL, MNU_MouseButtonPostProcess},
|
|
{DefInert(0, MouseButtonFunctions[4]), OPT_XSIDE, OPT_LINE(8), 1, m_defshade, 4, NULL, MNU_SetMouseButtonFunctions, NULL},
|
|
{DefLayer(0, "Wheel Down", &mousebuttongroup), OPT_XS, OPT_LINE(9), 1, m_defshade, 5, NULL, NULL, MNU_MouseButtonPostProcess},
|
|
{DefInert(0, MouseButtonFunctions[5]), OPT_XSIDE, OPT_LINE(9), 1, m_defshade, 5, NULL, MNU_SetMouseButtonFunctions, NULL},
|
|
{DefNone}
|
|
};
|
|
MenuGroup mousesetupgroup = {65, 5, "^Mouse Setup", mousesetup_i, pic_newgametitl, 0, m_defshade, NULL, NULL, 0};
|
|
|
|
#define JOYSTICKITEMSPERPAGE 12
|
|
#define MAXJOYSTICKBUTTONPAGES (MAXJOYBUTTONS*2 / JOYSTICKITEMSPERPAGE)
|
|
static char JoystickButtonPageName[MAXJOYSTICKBUTTONPAGES][64];
|
|
static char JoystickButtonFunctions[MAXJOYBUTTONS*2][MAXFUNCTIONLENGTH];
|
|
static char JoystickButtonNames[MAXJOYBUTTONS*2][64];
|
|
static int JoystickButtonPage = 0;
|
|
static SWBOOL MNU_JoystickButtonsInitialise(MenuItem_p item);
|
|
static SWBOOL MNU_SetJoystickButtonFunctions(MenuItem_p item);
|
|
static SWBOOL MNU_JoystickButtonPostProcess(MenuItem_p item);
|
|
static SWBOOL MNU_JoystickButtonSetupCustom(UserCall call, MenuItem_p item);
|
|
static SWBOOL MNU_JoystickButtonNextPage(void);
|
|
MenuGroup joybuttonsgroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_JoystickButtonSetupCustom, NULL, 0};
|
|
MenuItem joybuttons_i[MAXJOYSTICKBUTTONPAGES][JOYSTICKITEMSPERPAGE*2+3] = // itemsperpage * Layer/Inert + Pagetext + Next + DefNone
|
|
{
|
|
// this menu gets defined by the call to MNU_JoystickButtonsInitialise
|
|
{ {DefNone} },
|
|
};
|
|
MenuGroup joybuttonssetupgroup = {65, 5, "^Joystick Setup", NULL, pic_newgametitl, 0, m_defshade, NULL, NULL, 0};
|
|
|
|
static char JoystickAxisName[64];
|
|
static char JoystickAxisPageName[64];
|
|
static char JoystickAxisFunctions[2][MAXFUNCTIONLENGTH];
|
|
static int JoystickAxisPage = 0;
|
|
static SWBOOL MNU_JoystickAxesInitialise(MenuItem_p item);
|
|
static SWBOOL MNU_SetJoystickAxisFunctions(MenuItem_p item);
|
|
static SWBOOL MNU_JoystickAxisPostProcess(MenuItem_p item);
|
|
static SWBOOL MNU_JoystickAxisSetupCustom(UserCall call, MenuItem_p item);
|
|
static SWBOOL MNU_JoystickAxisNextPage(void);
|
|
MenuGroup joyaxesgroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_JoystickAxisSetupCustom, NULL, 0};
|
|
MenuItem joyaxes_i[] =
|
|
{
|
|
{DefInert(0, JoystickAxisName), OPT_XS, OPT_LINE(0), 1, MENU_SHADE_INACTIVE, 0, NULL, NULL, NULL},
|
|
|
|
{DefSlider(sldr_joyaxisscale, 0, "Axis Scale"), OPT_XS, OPT_LINE(2), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(2), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
|
|
{DefSlider(sldr_joyaxisanalog, 0, "Analog"), OPT_XS, OPT_LINE(4), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(4), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefLayer(0, "Digital +ve", &joyaxesgroup), OPT_XS, OPT_LINE(5), 1, m_defshade, 1, NULL, NULL, MNU_JoystickAxisPostProcess},
|
|
{DefInert(0, JoystickAxisFunctions[1]), OPT_XSIDE, OPT_LINE(5), 1, m_defshade, 1, NULL, MNU_SetJoystickAxisFunctions, NULL},
|
|
{DefLayer(0, "Digital -ve", &joyaxesgroup), OPT_XS, OPT_LINE(6), 1, m_defshade, 0, NULL, NULL, MNU_JoystickAxisPostProcess},
|
|
{DefInert(0, JoystickAxisFunctions[0]), OPT_XSIDE, OPT_LINE(6), 1, m_defshade, 0, NULL, MNU_SetJoystickAxisFunctions, NULL},
|
|
|
|
{DefSlider(sldr_joyaxisdead, 0, "Dead Zone"), OPT_XS, OPT_LINE(8), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(8), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefSlider(sldr_joyaxissatur, 0, "Saturate"), OPT_XS, OPT_LINE(9), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(9), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
|
|
{DefInert(0, JoystickAxisPageName), OPT_XS, OPT_LINE(11), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefOption(0, "Next..."), OPT_XSIDE, OPT_LINE(11), 1, m_defshade, 0, MNU_JoystickAxisNextPage, NULL, NULL},
|
|
|
|
{DefNone},
|
|
};
|
|
MenuGroup joyaxessetupgroup = {65, 5, "^Joystick Axes", joyaxes_i, pic_newgametitl, 0, m_defshade, NULL, NULL, 1};
|
|
|
|
|
|
static char AdvancedMouseAxisFunctions[4][MAXAXISFUNCTIONLENGTH] = { "", "", "", "" };
|
|
static SWBOOL MNU_SetAdvancedMouseFunctions(MenuItem_p item);
|
|
static SWBOOL MNU_MouseDigitalPostProcess(MenuItem_p item);
|
|
static SWBOOL MNU_MouseDigitalSetupCustom(UserCall call, MenuItem_p item);
|
|
MenuGroup advancedmousedigigroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_MouseDigitalSetupCustom, NULL, 0};
|
|
MenuItem advancedmouse_i[] =
|
|
{
|
|
{DefSlider(sldr_mousescalex, 0, "X-Axis Scale"), OPT_XS, OPT_LINE(0), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(0), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefSlider(sldr_mousescaley, 0, "Y-Axis Scale"), OPT_XS, OPT_LINE(1), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(1), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefLayer(0, "Digital Up", &advancedmousedigigroup), OPT_XS, OPT_LINE(3), 1, m_defshade, 0, NULL, NULL, MNU_MouseDigitalPostProcess},
|
|
{DefInert(0, AdvancedMouseAxisFunctions[0]), OPT_XSIDE, OPT_LINE(3), 1, m_defshade, 0, NULL, MNU_SetAdvancedMouseFunctions, NULL},
|
|
{DefLayer(0, "Digital Down", &advancedmousedigigroup), OPT_XS, OPT_LINE(4), 1, m_defshade, 1, NULL, NULL, MNU_MouseDigitalPostProcess},
|
|
{DefInert(0, AdvancedMouseAxisFunctions[1]), OPT_XSIDE, OPT_LINE(4), 1, m_defshade, 1, NULL, MNU_SetAdvancedMouseFunctions, NULL},
|
|
{DefLayer(0, "Digital Left", &advancedmousedigigroup), OPT_XS, OPT_LINE(5), 1, m_defshade, 2, NULL, NULL, MNU_MouseDigitalPostProcess},
|
|
{DefInert(0, AdvancedMouseAxisFunctions[2]), OPT_XSIDE, OPT_LINE(5), 1, m_defshade, 2, NULL, MNU_SetAdvancedMouseFunctions, NULL},
|
|
{DefLayer(0, "Digital Right", &advancedmousedigigroup), OPT_XS, OPT_LINE(6), 1, m_defshade, 3, NULL, NULL, MNU_MouseDigitalPostProcess},
|
|
{DefInert(0, AdvancedMouseAxisFunctions[3]), OPT_XSIDE, OPT_LINE(6), 1, m_defshade, 3, NULL, MNU_SetAdvancedMouseFunctions, NULL},
|
|
{DefNone}
|
|
};
|
|
MenuGroup mouseadvancedgroup = {65, 5, "^Adv'd Mouse", advancedmouse_i, pic_newgametitl, 0, m_defshade, NULL, NULL, 0};
|
|
|
|
MenuItem inputsetup_i[] =
|
|
{
|
|
{DefLayer(0, "Keys Setup", &keysetupgroup),OPT_XS, OPT_LINE(0),1,m_defshade,0,NULL,NULL,NULL},
|
|
{DefLayer(0, "Mouse Setup", &mousesetupgroup),OPT_XS, OPT_LINE(1),1,m_defshade,0,NULL,NULL,NULL},
|
|
{DefLayer(0, "Joystick Buttons Setup", &joybuttonssetupgroup),OPT_XS,OPT_LINE(2),1,m_defshade,0,NULL,MNU_JoystickCheck,MNU_JoystickButtonsInitialise},
|
|
{DefLayer(0, "Joystick Axes Setup", &joyaxessetupgroup), OPT_XS, OPT_LINE(3),1,m_defshade,0,NULL,MNU_JoystickCheck,MNU_JoystickAxesInitialise},
|
|
{DefLayer(0, "Advanced Mouse Setup", &mouseadvancedgroup),OPT_XS, OPT_LINE(5),1,m_defshade,0,NULL,NULL,NULL},
|
|
{DefOption(0, "Apply Modern Defaults"), OPT_XS, OPT_LINE(7),1,m_defshade,0,MNU_LoadModernDefaults,NULL,NULL},
|
|
{DefOption(0, "Apply Classic Defaults"), OPT_XS, OPT_LINE(8),1,m_defshade,0,MNU_LoadClassicDefaults,NULL,NULL},
|
|
{DefNone}
|
|
};
|
|
MenuGroup inputsetupgroup = {65, 5, "^Input Setup", inputsetup_i, pic_newgametitl, 0, m_defshade, NULL,NULL, 0};
|
|
|
|
MenuItem options_i[] =
|
|
{
|
|
{DefLayer(0, "Screen Menu", &screengroup),OPT_XS, OPT_LINE(0), 1, m_defshade,0,NULL, NULL, NULL},
|
|
{DefLayer(0, "Mouse Menu", &mousegroup),OPT_XS, OPT_LINE(1), 1, m_defshade,0,NULL, MNU_MouseCheck, NULL},
|
|
{DefLayer(0, "Sound Menu", &soundgroup),OPT_XS, OPT_LINE(2), 1, m_defshade,0,MNU_TryMusicInit, MNU_MusicFxCheck, NULL},
|
|
{DefLayer(0, "Input Setup", &inputsetupgroup),OPT_XS, OPT_LINE(3), 1,m_defshade,0,NULL,NULL,NULL},
|
|
#ifndef PLOCK_VERSION // No need for this in weener version
|
|
{DefLayer(0, "Kid Mode", &parentalgroup),OPT_XS, OPT_LINE(4), 1, m_defshade,0,NULL, NULL, NULL},
|
|
#endif
|
|
{DefButton(btn_messages, 0, "Messages"), OPT_XS, OPT_LINE(5), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
// {DefButton(btn_bobbing, 0, "View Bobbing"), OPT_XS, OPT_LINE(7), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefButton(btn_shadows, 0, "Shadows"), OPT_XS, OPT_LINE(6), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefButton(btn_auto_run, 0, "Auto Run"), OPT_XS, OPT_LINE(7), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefButton(btn_crosshair, 0, "Crosshair"), OPT_XS, OPT_LINE(8), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefButton(btn_auto_aim, 0, "Auto-Aiming"), OPT_XS, OPT_LINE(9), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefButton(btn_voxels, 0, "Voxel Sprites"), OPT_XS, OPT_LINE(10), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefButton(btn_stats, 0, "Level Stats"), OPT_XS, OPT_LINE(11), 1, m_defshade, 0, NULL, MNU_StatCheck, NULL},
|
|
{DefNone}
|
|
};
|
|
|
|
MenuGroup optiongroup = {100, 5, "^Options", options_i, pic_optionstitl, 0, m_defshade, NULL,NULL, 0};
|
|
|
|
MenuItem skill_i[] =
|
|
{
|
|
{DefOption(KEYSC_E, &SkillNames[0][0]), 30, 46, pic_easy, m_defshade, 0, MNU_StartGame, NULL, NULL},
|
|
{DefOption(KEYSC_N, &SkillNames[1][0]), 30, 62, pic_normal, m_defshade, 0, MNU_StartGame, NULL, NULL},
|
|
{DefOption(KEYSC_H, &SkillNames[2][0]), 30, 78, pic_hard, m_defshade, 0, MNU_StartGame, NULL, NULL},
|
|
{DefOption(KEYSC_I, &SkillNames[3][0]), 30, 94, pic_impossible, m_defshade, 0, MNU_StartGame, NULL, NULL},
|
|
{DefNone}
|
|
};
|
|
|
|
MenuGroup skillgroup = {100, 5, "^Skill", skill_i, pic_newgametitl, 0, m_defshade, NULL, NULL, 2};
|
|
|
|
MenuItem episode_i[] =
|
|
{
|
|
{DefLayer(KEYSC_S, &EpisodeNames[0][0], &skillgroup), 30, 46, pic_episode1, m_defshade, 0, MNU_EpisodeCustom, NULL, NULL},
|
|
{DefLayer(KEYSC_F, &EpisodeNames[1][0], &skillgroup), 30, 78, pic_episode2, m_defshade, 0, MNU_EpisodeCustom, MNU_ShareWareCheck, MNU_ShareWareMessage},
|
|
//{DefLayer(KEYSC_S, NULL, &skillgroup), 60, 30, pic_episode1, m_defshade, 0, MNU_EpisodeCustom},
|
|
//{DefLayer(KEYSC_F, NULL, &skillgroup), 60, 46, pic_episode2, m_defshade, 0, MNU_EpisodeCustom},
|
|
//{DefLayer(KEYSC_T, NULL, &skillgroup), 60, 62, pic_episode3, m_defshade, 0, MNU_EpisodeCustom},
|
|
{DefNone}
|
|
};
|
|
|
|
MenuGroup episodegroup = {100, 5, "^Episode", episode_i, pic_newgametitl, 0, m_defshade, MNU_DoEpisodeSelect, NULL, 0};
|
|
|
|
extern char UserMapName[80];
|
|
|
|
MenuItem network_extra_i[] =
|
|
{
|
|
{DefSlider(sldr_monsters, 0, "Monsters"),OPT_XS, OPT_LINE(0), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE,OPT_LINE(0), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
|
|
{DefButton(btn_teamplay, 0, "Team Play"), OPT_XS, OPT_LINE(1), 1, m_defshade, 0, MNU_TeamPlayChange, MNU_TeamPlayCheck, NULL},
|
|
{DefButton(btn_friendlyfire, 0, "Hurt Teammate"),OPT_XS, OPT_LINE(2), 1, m_defshade, 0, NULL, MNU_HurtTeammateCheck, NULL},
|
|
{DefButton(btn_nuke, 0, "Play with Nuke"),OPT_XS, OPT_LINE(3), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefNone}
|
|
};
|
|
|
|
MenuGroup networkextragroup = {50, 5, "^Net Options", network_extra_i, pic_newgametitl, 0, m_defshade, NULL, NULL, 0};
|
|
|
|
MenuItem network_i[] =
|
|
{
|
|
{DefSlider(sldr_gametype, 0, "Game Type"), OPT_XS, OPT_LINE(0), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE-38, OPT_LINE(0), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
|
|
{DefSlider(sldr_netlevel, 0, "Level"), OPT_XS, OPT_LINE(1), 1, m_defshade, 0, NULL, MNU_CheckUserMap, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE-70, OPT_LINE(1), 0, m_defshade, 0, NULL, MNU_CheckUserMap, NULL},
|
|
{DefInert(0, " "), OPT_XS, OPT_LINE(2), pic_episode1, m_defshade, 0, NULL, MNU_CheckUserMap, NULL},
|
|
|
|
{DefButton(btn_markers, 0, "Markers"), OPT_XS, OPT_LINE(3), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
|
|
{DefSlider(sldr_killlimit, 0, "Kill Limit"),OPT_XS, OPT_LINE(4), 1, m_defshade, 0, NULL, MNU_CoopPlayCheck, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(4), 0, m_defshade, 0, NULL, MNU_CoopPlayCheck, NULL},
|
|
|
|
{DefSlider(sldr_timelimit, 0, "Time Limit"),OPT_XS, OPT_LINE(5), 1, m_defshade, 0, NULL, MNU_CoopPlayCheck, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(5), 0, m_defshade, 0, NULL, MNU_CoopPlayCheck, NULL},
|
|
|
|
{DefSlider(sldr_playercolor, 0, "Player Color"),OPT_XS, OPT_LINE(6), 1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefInert(0, NULL), OPT_XSIDE, OPT_LINE(6), 0, m_defshade, 0, NULL, NULL, NULL},
|
|
|
|
{DefLayer(0, "Other Options", &networkextragroup),OPT_XS, OPT_LINE(7), 1, m_defshade,0,NULL, NULL, NULL},
|
|
|
|
{DefInert(0, UserMapName), OPT_XSIDE, OPT_LINE(8), pic_episode1, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefOption(KEYSC_S, "Start Game"), OPT_XS, OPT_LINE(8), pic_episode1, m_defshade, 0, MNU_StartNetGame, NULL, NULL},
|
|
|
|
{DefNone}
|
|
|
|
};
|
|
|
|
MenuGroup networkgroup = {50, 5, "^Network Game", network_i, pic_newgametitl, 0, m_defshade, NULL, NULL, 0};
|
|
|
|
|
|
MenuItem load_i[] =
|
|
{
|
|
#define SD_YSTART 26
|
|
#define SD_XSTART 5
|
|
#define SD_YOFF 13
|
|
#define SD_LINE(line) (SD_YSTART + (line * SD_YOFF))
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(0), 0, m_defshade, 0, MNU_GetLoadCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(1), 0, m_defshade, 0, MNU_GetLoadCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(2), 0, m_defshade, 0, MNU_GetLoadCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(3), 0, m_defshade, 0, MNU_GetLoadCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(4), 0, m_defshade, 0, MNU_GetLoadCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(5), 0, m_defshade, 0, MNU_GetLoadCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(6), 0, m_defshade, 0, MNU_GetLoadCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(7), 0, m_defshade, 0, MNU_GetLoadCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(8), 0, m_defshade, 0, MNU_GetLoadCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(9), 0, m_defshade, 0, MNU_GetLoadCustom, NULL, NULL},
|
|
{DefNone}
|
|
};
|
|
|
|
MenuItem save_i[] =
|
|
{
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(0), 0, m_defshade, 0, MNU_GetSaveCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(1), 0, m_defshade, 0, MNU_GetSaveCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(2), 0, m_defshade, 0, MNU_GetSaveCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(3), 0, m_defshade, 0, MNU_GetSaveCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(4), 0, m_defshade, 0, MNU_GetSaveCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(5), 0, m_defshade, 0, MNU_GetSaveCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(6), 0, m_defshade, 0, MNU_GetSaveCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(7), 0, m_defshade, 0, MNU_GetSaveCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(8), 0, m_defshade, 0, MNU_GetSaveCustom, NULL, NULL},
|
|
{DefOption(0, NULL), SD_XSTART, SD_LINE(9), 0, m_defshade, 0, MNU_GetSaveCustom, NULL, NULL},
|
|
{DefNone}
|
|
};
|
|
|
|
// No actual submenus for this, just quit text.
|
|
MenuGroup quitgroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_QuitCustom, NULL, 0};
|
|
MenuGroup quickloadgroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_QuickLoadCustom, NULL, 0};
|
|
MenuGroup ordergroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_OrderCustom, NULL, 0};
|
|
|
|
// save and load function calls
|
|
MenuGroup SaveGameGroup = {100, 5, "^Save Game", save_i, pic_savegame, 0, m_defshade, MNU_LoadSaveDraw, MNU_LoadSaveMove, 0};
|
|
MenuGroup LoadGameGroup = {100, 5, "^Load Game", load_i, pic_loadgame, 0, m_defshade, MNU_LoadSaveDraw, MNU_LoadSaveMove, 0};
|
|
|
|
#define MAIN_YSTART 32
|
|
#define MAIN_YOFF 17
|
|
#define MAIN_XSTART 55
|
|
#define MAIN_LINE(line) (MAIN_YSTART + (MAIN_YOFF * line))
|
|
|
|
#define MAIN_MENU_COOL_STUFF "^Cool Stuff"
|
|
#define MAIN_MENU_HOW_TO_ORDER "^How to Order"
|
|
|
|
MenuItem main_i[] =
|
|
{
|
|
{DefLayer(KEYSC_N, "^New Game", &episodegroup), MAIN_XSTART, MAIN_LINE(0), pic_newgame, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefLayer(KEYSC_L, "^Load Game", &LoadGameGroup), MAIN_XSTART, MAIN_LINE(1), pic_load, m_defshade, 0, NULL, MNU_LoadGameCheck, NULL},
|
|
{DefLayer(KEYSC_S, "^Save Game", &SaveGameGroup), MAIN_XSTART, MAIN_LINE(2), pic_save, m_defshade, 0, NULL, MNU_SaveGameCheck, NULL},
|
|
{DefLayer(KEYSC_O, "^Options", &optiongroup), MAIN_XSTART, MAIN_LINE(3), pic_options, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefLayer(KEYSC_H, "^Oh Dear", &ordergroup), MAIN_XSTART, MAIN_LINE(4), pic_orderinfo, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefLayer(KEYSC_Q, "^Quit", &quitgroup), MAIN_XSTART, MAIN_LINE(5), pic_quit, m_defshade, 0, NULL, NULL, NULL},
|
|
{DefNone}
|
|
};
|
|
|
|
MenuGroup maingroup = {160, 15, NULL, main_i, pic_shadow_warrior, 0, m_defshade, NULL, NULL, 0};
|
|
|
|
CTLType ControlPanelType;
|
|
|
|
#define MaxLayers 10 // Maximum layers deep a menu can go
|
|
short menuarrayptr; // Index into menuarray
|
|
MenuGroup *menuarray[MaxLayers], *currentmenu;
|
|
SWBOOL UsingMenus = FALSE;
|
|
|
|
#define MAXDIALOG 2 // Maximum number of dialog strings allowed
|
|
char *dialog[MAXDIALOG];
|
|
|
|
// Global menu setting values ////////////////////////////////////////////////////////////////////
|
|
// Mouse slider vars
|
|
#define SENSE_MIN 75
|
|
#define SENSE_MUL 10
|
|
int SENSITIVITY = SENSE_MIN + (SENSE_DEFAULT *SENSE_MUL);
|
|
|
|
// Sound vars
|
|
#define FX_MIN 0
|
|
#define MUSIC_MIN 0
|
|
#define VOL_MUL 16
|
|
|
|
// User input data for all devices
|
|
UserInput mnu_input, mnu_input_buffered, order_input_buffered;
|
|
|
|
// Menu function call back pointer for multiplay menus
|
|
SWBOOL(*cust_callback)(UserCall call, MenuItem_p item);
|
|
UserCall cust_callback_call;
|
|
MenuItem_p cust_callback_item;
|
|
|
|
// Prototypes ///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
static void MNU_ClearDialog(void);
|
|
static SWBOOL MNU_Dialog(void);
|
|
void LoadSaveMsg(char *msg);
|
|
static void MNU_ItemPreProcess(MenuGroup *group);
|
|
static void MNU_SelectItem(MenuGroup *group, short index, SWBOOL draw);
|
|
static void MNU_PushItem(MenuItem *item, SWBOOL draw);
|
|
|
|
static int MNU_ControlAxisOffset(int num);
|
|
static int MNU_ControlAxisNum(int offset);
|
|
|
|
|
|
// F U N C T I O N S ////////////////////////////////////////////////////////////////////////////
|
|
|
|
// CUSTOM ROUTINES ////////////////////////////////////////////////////////////////////////////////
|
|
// CTW REMOVED
|
|
/*
|
|
SWBOOL
|
|
MNU_Ten(void)
|
|
{
|
|
TEN_Setup();
|
|
|
|
return(FALSE);
|
|
}
|
|
*/
|
|
// CTW REMOVED END
|
|
SWBOOL
|
|
MNU_DoEpisodeSelect(UserCall call, MenuItem *item)
|
|
{
|
|
short w,h;
|
|
char TempString[80];
|
|
char *extra_text;
|
|
|
|
extra_text = EpisodeSubtitles[0];
|
|
MNU_MeasureString(extra_text, &w, &h);
|
|
MNU_DrawString(30, 63, extra_text, 1, 16);
|
|
extra_text = EpisodeSubtitles[1];
|
|
MNU_MeasureString(extra_text, &w, &h);
|
|
MNU_DrawString(30, 96, extra_text, 1, 16);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_DoParentalPassword(UserCall call, MenuItem_p item)
|
|
{
|
|
short w,h;
|
|
signed char MNU_InputString(char *, short);
|
|
static SWBOOL cur_show;
|
|
char TempString[80];
|
|
char *extra_text;
|
|
|
|
|
|
extra_text = "This mode should remove most of the";
|
|
MNU_MeasureString(extra_text, &w, &h);
|
|
MNU_DrawString(TEXT_XCENTER(w), 60, extra_text, 1, 16);
|
|
extra_text = "offensive content. We still recommend";
|
|
MNU_MeasureString(extra_text, &w, &h);
|
|
MNU_DrawString(TEXT_XCENTER(w), 70, extra_text, 1, 16);
|
|
extra_text = "you review the game prior to play.";
|
|
MNU_MeasureString(extra_text, &w, &h);
|
|
MNU_DrawString(TEXT_XCENTER(w), 80, extra_text, 1, 16);
|
|
|
|
// get input
|
|
if (MenuInputMode)
|
|
{
|
|
switch (MNU_InputString(MessageInputString, 80))
|
|
{
|
|
case -1: // Cancel Input (pressed ESC) or Err
|
|
KB_ClearKeysDown();
|
|
KB_FlushKeyboardQueue();
|
|
MenuInputMode = FALSE;
|
|
memset(MessageInputString, '\0', sizeof(MessageInputString));
|
|
break;
|
|
case FALSE: // Input finished (RETURN)
|
|
if (MessageInputString[0] == '\0')
|
|
{
|
|
MenuInputMode = FALSE;
|
|
KB_ClearKeysDown();
|
|
KB_FlushKeyboardQueue();
|
|
memset(MessageInputString, '\0', sizeof(MessageInputString));
|
|
}
|
|
else
|
|
{
|
|
MenuInputMode = FALSE;
|
|
KB_ClearKeysDown();
|
|
KB_FlushKeyboardQueue();
|
|
|
|
if (gs.Password[0] != '\0' && passwordvalid == FALSE)
|
|
{
|
|
if (!Bstrcasecmp(gs.Password,MessageInputString))
|
|
{
|
|
passwordvalid = TRUE;
|
|
if (currentmenu->cursor == 0 && gs.ParentalLock == TRUE)
|
|
{
|
|
buttonsettings[btn_parental] = gs.ParentalLock = FALSE;
|
|
if (!InMenuLevel)
|
|
JS_ToggleLockouts();
|
|
}
|
|
|
|
if (currentmenu->cursor == 1) // Is it on the password line?
|
|
{
|
|
MenuInputMode = TRUE;
|
|
KB_ClearKeysDown();
|
|
KB_FlushKeyboardQueue();
|
|
}
|
|
//memset(gs.Password, '\0', sizeof(gs.Password));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (currentmenu->cursor == 1) // Is it on the password line?
|
|
{
|
|
strcpy(gs.Password,MessageInputString);
|
|
passwordvalid = FALSE;
|
|
}
|
|
}
|
|
|
|
memset(MessageInputString, '\0', sizeof(MessageInputString));
|
|
}
|
|
break;
|
|
case TRUE: // Got input
|
|
break;
|
|
}
|
|
|
|
//CON_Message("Password = '%s'",gs.Password);
|
|
//CON_Message("Passwordvalid = %d",passwordvalid);
|
|
|
|
if (gs.Password[0] != '\0' && passwordvalid == FALSE && currentmenu->cursor == 1)
|
|
{
|
|
sprintf(TempString,"Enter Old Password");
|
|
MNU_MeasureString(TempString, &w, &h);
|
|
MNU_DrawString(TEXT_XCENTER(w), MESSAGE_LINE-10, TempString,1,16);
|
|
}
|
|
else if (passwordvalid == TRUE && currentmenu->cursor == 1)
|
|
{
|
|
sprintf(TempString,"Enter New Password");
|
|
MNU_MeasureString(TempString, &w, &h);
|
|
MNU_DrawString(TEXT_XCENTER(w), MESSAGE_LINE-10, TempString,1,16);
|
|
}
|
|
else
|
|
{
|
|
sprintf(TempString,"Enter Password");
|
|
MNU_MeasureString(TempString, &w, &h);
|
|
MNU_DrawString(TEXT_XCENTER(w), MESSAGE_LINE-10, TempString,1,16);
|
|
}
|
|
|
|
MNU_MeasureString(MessageInputString, &w, &h);
|
|
|
|
cur_show ^= 1;
|
|
if (cur_show)
|
|
{
|
|
MNU_DrawString(TEXT_XCENTER(w), MESSAGE_LINE, MessageInputString,1,16);
|
|
rotatesprite((TEXT_XCENTER(w)+w+7)<<16,(MESSAGE_LINE+3)<<16,64<<9,0,COINCURSOR+((totalclock>>3)%7),0,0,MenuDrawFlags,0,0,xdim-1,ydim-1);
|
|
}
|
|
else
|
|
{
|
|
MNU_DrawString(TEXT_XCENTER(w), MESSAGE_LINE, MessageInputString,1,16);
|
|
rotatesprite((TEXT_XCENTER(w)+w+7)<<16,(MESSAGE_LINE+3)<<16,64<<9,0,COINCURSOR+((totalclock>>3)%7),0,0,MenuDrawFlags,0,0,xdim-1,ydim-1);
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_ParentalCustom(void)
|
|
{
|
|
|
|
if (MenuInputMode)
|
|
{
|
|
// toggle edit mode
|
|
MenuInputMode = FALSE;
|
|
memset(MessageInputString, '\0', sizeof(MessageInputString));
|
|
}
|
|
else
|
|
{
|
|
// clear keyboard buffer
|
|
while (KB_KeyWaiting())
|
|
{
|
|
if (KB_Getch() == 0)
|
|
KB_Getch();
|
|
}
|
|
|
|
// toggle edit mode
|
|
MenuInputMode = TRUE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL MNU_KeySetupCustom(UserCall call, MenuItem *item)
|
|
{
|
|
static int currentkey = 0, currentcol = 0;
|
|
static int currentmode = 0;
|
|
|
|
if (call == uc_touchup)
|
|
return TRUE;
|
|
|
|
if (cust_callback == NULL)
|
|
{
|
|
if (call != uc_setup)
|
|
return FALSE;
|
|
currentkey = 0;
|
|
currentcol = 0;
|
|
currentmode = 0;
|
|
}
|
|
|
|
cust_callback = MNU_KeySetupCustom;
|
|
cust_callback_call = call;
|
|
cust_callback_item = item;
|
|
|
|
{
|
|
short w, h = 0;
|
|
char *s = "Keys Setup";
|
|
rotatesprite(10 << 16, (5-3) << 16, MZ, 0, 2427,
|
|
m_defshade, 0, MenuDrawFlags|ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1);
|
|
MNU_MeasureStringLarge(s, &w, &h);
|
|
MNU_DrawStringLarge(TEXT_XCENTER(w), 5, s);
|
|
}
|
|
|
|
if (currentmode)
|
|
{
|
|
// customising a key
|
|
char *strs[] = { "Press the key to assign to", "\"%s\" %s", "or ESCAPE to cancel." };
|
|
char *col[2] = { "(primary)", "(secondary)" };
|
|
short w, h = 8;
|
|
int i, j, y;
|
|
|
|
if (KEY_PRESSED(KEYSC_ESC))
|
|
{
|
|
KB_ClearKeyDown(sc_Escape);
|
|
currentmode = 0;
|
|
}
|
|
else if (KB_GetLastScanCode() > 0)
|
|
{
|
|
KB_ClearKeyDown(KB_GetLastScanCode());
|
|
|
|
KeyboardKeys[currentkey][currentcol] = KB_GetLastScanCode();
|
|
if (currentkey != gamefunc_Show_Console)
|
|
{
|
|
CONTROL_MapKey(currentkey,
|
|
KeyboardKeys[currentkey][0],
|
|
KeyboardKeys[currentkey][1]);
|
|
}
|
|
else
|
|
{
|
|
OSD_CaptureKey(KB_GetLastScanCode());
|
|
}
|
|
|
|
currentmode = 0;
|
|
}
|
|
|
|
MNU_MeasureString(strs[0], &w, &h);
|
|
|
|
y = (YDIM - (h+3) * SIZ(strs)) / 2;
|
|
|
|
for (i=0; i<(int)SIZ(strs); i++)
|
|
{
|
|
w = 0;
|
|
sprintf(ds,strs[i],gamefunctions[currentkey],col[currentcol]);
|
|
for (j=0; ds[j]; j++) if (ds[j] == '_') ds[j] = ' ';
|
|
MNU_MeasureString(ds, &w, &h);
|
|
MNU_DrawString((XDIM - w)/2, y, ds, 0, 16);
|
|
y += h+3;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
// key list
|
|
#define PGSIZ 14
|
|
int topitem = 0, botitem = NUMGAMEFUNCTIONS;
|
|
int i,j;
|
|
char *morestr = "More...";
|
|
const char *p;
|
|
|
|
UserInput inpt = {FALSE,FALSE,dir_None};
|
|
CONTROL_GetUserInput(&inpt);
|
|
|
|
if (KEY_PRESSED(KEYSC_ESC) || inpt.button1)
|
|
{
|
|
KEY_PRESSED(KEYSC_ESC) = FALSE;
|
|
cust_callback = NULL;
|
|
CONTROL_ClearUserInput(&inpt);
|
|
return TRUE;
|
|
}
|
|
else if (KB_KeyPressed(sc_Delete))
|
|
{
|
|
KB_ClearKeyDown(sc_Delete);
|
|
if (currentkey != gamefunc_Show_Console)
|
|
{
|
|
KeyboardKeys[currentkey][currentcol] = 0xff;
|
|
CONTROL_MapKey(currentkey,
|
|
KeyboardKeys[currentkey][0],
|
|
KeyboardKeys[currentkey][1]);
|
|
}
|
|
}
|
|
else if (KB_KeyPressed(sc_Home))
|
|
{
|
|
currentkey = 0;
|
|
KB_ClearKeyDown(sc_Home);
|
|
}
|
|
else if (KB_KeyPressed(sc_End))
|
|
{
|
|
currentkey = NUMGAMEFUNCTIONS-1;
|
|
KB_ClearKeyDown(sc_End);
|
|
}
|
|
else if (KB_KeyPressed(sc_PgDn))
|
|
{
|
|
currentkey += PGSIZ;
|
|
if (currentkey >= NUMGAMEFUNCTIONS) currentkey = NUMGAMEFUNCTIONS-1;
|
|
KB_ClearKeyDown(sc_PgDn);
|
|
}
|
|
else if (KB_KeyPressed(sc_PgUp))
|
|
{
|
|
currentkey -= PGSIZ;
|
|
if (currentkey < 0) currentkey = 0;
|
|
KB_ClearKeyDown(sc_PgUp);
|
|
}
|
|
else if (inpt.button0)
|
|
{
|
|
currentmode = 1;
|
|
KB_ClearLastScanCode();
|
|
KB_ClearKeysDown();
|
|
}
|
|
else if (inpt.dir == dir_North) currentkey = max(0,currentkey-1);
|
|
else if (inpt.dir == dir_South) currentkey = min(NUMGAMEFUNCTIONS-1,currentkey+1);
|
|
else if (inpt.dir == dir_East) currentcol = 1;
|
|
else if (inpt.dir == dir_West) currentcol = 0;
|
|
|
|
if (currentkey == gamefunc_Show_Console) currentcol = 0;
|
|
|
|
CONTROL_ClearUserInput(&inpt);
|
|
|
|
if (NUMGAMEFUNCTIONS > PGSIZ)
|
|
{
|
|
topitem = currentkey - PGSIZ/2;
|
|
botitem = topitem + PGSIZ;
|
|
|
|
if (topitem < 0)
|
|
{
|
|
botitem += -topitem;
|
|
topitem = 0;
|
|
}
|
|
else if (botitem >= NUMGAMEFUNCTIONS)
|
|
{
|
|
botitem = NUMGAMEFUNCTIONS-1;
|
|
topitem = botitem - PGSIZ;
|
|
}
|
|
}
|
|
|
|
for (i = topitem; i <= botitem; i++)
|
|
{
|
|
for (j = 0; gamefunctions[i][j]; j++)
|
|
{
|
|
if (gamefunctions[i][j] == '_') ds[j] = ' ';
|
|
else ds[j] = gamefunctions[i][j];
|
|
}
|
|
ds[j] = 0;
|
|
|
|
j = OPT_LINE(0)+(i-topitem)*8;
|
|
MNU_DrawSmallString(OPT_XS, j, ds, (i==currentkey) ? 0 : 12, 16);
|
|
|
|
p = getkeyname(KeyboardKeys[i][0]);
|
|
if (!p || KeyboardKeys[i][0]==0xff) p = " -";
|
|
MNU_DrawSmallString(OPT_XSIDE, j, (char *)p, (i==currentkey) ? -5 : 12,
|
|
(i==currentkey && currentcol==0) ? 14 : 16);
|
|
|
|
if (i == gamefunc_Show_Console) continue;
|
|
|
|
p = getkeyname(KeyboardKeys[i][1]);
|
|
if (!p || KeyboardKeys[i][1]==0xff) p = " -";
|
|
MNU_DrawSmallString(OPT_XSIDE + 4*14, j, (char *)p, (i==currentkey) ? -5 : 12,
|
|
(i==currentkey && currentcol==1) ? 14 : 16);
|
|
}
|
|
|
|
{
|
|
short dx,dy;
|
|
dx = 0, dy = 8;
|
|
MNU_MeasureSmallString(morestr,&dx,&dy);
|
|
if (topitem > 0)
|
|
MNU_DrawSmallString(XDIM - OPT_XS - dx, OPT_LINE(0), morestr, 8,16);
|
|
if (botitem < NUMGAMEFUNCTIONS-1)
|
|
MNU_DrawSmallString(XDIM - OPT_XS - dx, OPT_LINE(0)+PGSIZ*8, morestr, 8,16);
|
|
}
|
|
#undef PGSIZ
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static int MNU_SelectButtonFunction(const char *buttonname, int *currentfunc)
|
|
{
|
|
const int PGSIZ = 9;
|
|
const char *strs[] = { "Select the function to assign to", "%s", "or ESCAPE to cancel." };
|
|
int topitem = 0, botitem = NUMGAMEFUNCTIONS-1;
|
|
int i, j, y;
|
|
short w, h=0;
|
|
int returnval = 0;
|
|
|
|
UserInput inpt = {FALSE,FALSE,dir_None};
|
|
CONTROL_GetUserInput(&inpt);
|
|
|
|
if (inpt.button1)
|
|
{
|
|
KB_ClearKeyDown(sc_Escape);
|
|
returnval = -1;
|
|
}
|
|
else if (KB_KeyPressed(sc_Home))
|
|
{
|
|
*currentfunc = 0;
|
|
KB_ClearKeyDown(sc_Home);
|
|
}
|
|
else if (KB_KeyPressed(sc_End))
|
|
{
|
|
*currentfunc = NUMGAMEFUNCTIONS-1; // -1 because the last one is the console and the top is 'none'
|
|
KB_ClearKeyDown(sc_End);
|
|
}
|
|
else if (KB_KeyPressed(sc_PgDn))
|
|
{
|
|
*currentfunc += PGSIZ;
|
|
if (*currentfunc >= NUMGAMEFUNCTIONS) *currentfunc = NUMGAMEFUNCTIONS-1;
|
|
KB_ClearKeyDown(sc_PgDn);
|
|
}
|
|
else if (KB_KeyPressed(sc_PgUp))
|
|
{
|
|
*currentfunc -= PGSIZ;
|
|
if (*currentfunc < 0) *currentfunc = 0;
|
|
KB_ClearKeyDown(sc_PgUp);
|
|
}
|
|
else if (inpt.button0)
|
|
{
|
|
returnval = 1;
|
|
}
|
|
else if (inpt.dir == dir_North) *currentfunc = max(0, *currentfunc-1);
|
|
else if (inpt.dir == dir_South) *currentfunc = min(NUMGAMEFUNCTIONS-1, *currentfunc+1);
|
|
|
|
CONTROL_ClearUserInput(&inpt);
|
|
|
|
if (NUMGAMEFUNCTIONS-1 > PGSIZ)
|
|
{
|
|
topitem = *currentfunc - PGSIZ/2;
|
|
botitem = topitem + PGSIZ;
|
|
|
|
if (topitem < 0)
|
|
{
|
|
botitem += -topitem;
|
|
topitem = 0;
|
|
}
|
|
else if (botitem >= NUMGAMEFUNCTIONS)
|
|
{
|
|
botitem = NUMGAMEFUNCTIONS-1;
|
|
topitem = botitem - PGSIZ;
|
|
}
|
|
}
|
|
|
|
y = OPT_LINE(0);
|
|
for (i=0; i<(int)SIZ(strs); i++)
|
|
{
|
|
w = 0;
|
|
sprintf(ds, strs[i], buttonname);
|
|
for (j=0; ds[j]; j++) if (ds[j] == '_') ds[j] = ' ';
|
|
MNU_MeasureString(ds, &w, &h);
|
|
MNU_DrawString((XDIM - w)/2, y, ds, 0, 16);
|
|
y += h;
|
|
}
|
|
|
|
for (i = topitem; i <= botitem; i++)
|
|
{
|
|
if (i == 0)
|
|
{
|
|
strcpy(ds, " -none-");
|
|
}
|
|
else
|
|
{
|
|
for (j = 0; gamefunctions[i-1][j]; j++)
|
|
{
|
|
if (gamefunctions[i-1][j] == '_') ds[j] = ' ';
|
|
else ds[j] = gamefunctions[i-1][j];
|
|
}
|
|
ds[j] = 0;
|
|
}
|
|
|
|
j = OPT_LINE(4)+(i-topitem)*8;
|
|
MNU_DrawSmallString(130, j, ds, (i == *currentfunc) ? 0 : 12, 16);
|
|
}
|
|
|
|
{
|
|
short dx = 0, dy = 8;
|
|
const char *morestr = "More...";
|
|
|
|
MNU_MeasureSmallString(morestr,&dx,&dy);
|
|
if (topitem > 0)
|
|
MNU_DrawSmallString(XDIM - OPT_XS - dx, OPT_LINE(4), morestr, 8,16);
|
|
if (botitem < NUMGAMEFUNCTIONS-1)
|
|
MNU_DrawSmallString(XDIM - OPT_XS - dx, OPT_LINE(4)+PGSIZ*8, morestr, 8,16);
|
|
}
|
|
|
|
return returnval;
|
|
}
|
|
|
|
|
|
static MenuItem_p mouse_button_item = NULL;
|
|
|
|
static SWBOOL MNU_MouseButtonPostProcess(MenuItem_p item)
|
|
{
|
|
mouse_button_item = item;
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL MNU_MouseButtonSetupCustom(UserCall call, MenuItem_p item)
|
|
{
|
|
static int currentfunc = 0;
|
|
|
|
if (call == uc_touchup)
|
|
return TRUE;
|
|
|
|
if (cust_callback == NULL)
|
|
{
|
|
if (call != uc_setup)
|
|
return FALSE;
|
|
if (mouse_button_item->tics >= 6)
|
|
{
|
|
currentfunc = MouseButtonsClicked[mouse_button_item->tics % 6];
|
|
}
|
|
else
|
|
{
|
|
currentfunc = MouseButtons[mouse_button_item->tics % 6];
|
|
}
|
|
currentfunc++;
|
|
|
|
cust_callback = MNU_MouseButtonSetupCustom;
|
|
cust_callback_call = call;
|
|
cust_callback_item = item;
|
|
}
|
|
|
|
{
|
|
short w, h = 0;
|
|
const char *s = "Mouse Setup";
|
|
|
|
rotatesprite(10 << 16, (5-3) << 16, MZ, 0, 2427,
|
|
m_defshade, 0, MenuDrawFlags|ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1);
|
|
MNU_MeasureStringLarge(s, &w, &h);
|
|
MNU_DrawStringLarge(TEXT_XCENTER(w), 5, s);
|
|
}
|
|
|
|
int selection = MNU_SelectButtonFunction(mouse_button_item->text, ¤tfunc);
|
|
switch (selection)
|
|
{
|
|
case -1: //cancel
|
|
cust_callback = NULL;
|
|
break;
|
|
case 1: //acknowledge
|
|
currentfunc--;
|
|
if (mouse_button_item->tics >= 6)
|
|
{
|
|
MouseButtonsClicked[mouse_button_item->tics % 6] = currentfunc;
|
|
CONTROL_MapButton(currentfunc, mouse_button_item->tics % 6, 1, controldevice_mouse);
|
|
}
|
|
else
|
|
{
|
|
MouseButtons[mouse_button_item->tics % 6] = currentfunc;
|
|
CONTROL_MapButton(currentfunc, mouse_button_item->tics % 6, 0, controldevice_mouse);
|
|
}
|
|
MNU_SetMouseButtonFunctions(mouse_button_item);
|
|
cust_callback = NULL;
|
|
break;
|
|
default: break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static SWBOOL MNU_SetMouseButtonFunctions(MenuItem_p item)
|
|
{
|
|
int button, clicked, function;
|
|
char *p;
|
|
|
|
clicked = item->tics >= 6;
|
|
button = item->tics % 6;
|
|
ASSERT(button >= 0 && button <= 5);
|
|
|
|
if (clicked)
|
|
{
|
|
function = MouseButtonsClicked[button];
|
|
}
|
|
else
|
|
{
|
|
function = MouseButtons[button];
|
|
}
|
|
|
|
if (function < 0)
|
|
{
|
|
strcpy(MouseButtonFunctions[item->tics], " -");
|
|
}
|
|
else
|
|
{
|
|
strcpy(MouseButtonFunctions[item->tics], CONFIG_FunctionNumToName(function));
|
|
for (p = MouseButtonFunctions[item->tics]; *p; p++)
|
|
{
|
|
if (*p == '_')
|
|
*p = ' ';
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static MenuItem_p mouse_digital_item = NULL;
|
|
|
|
static SWBOOL MNU_MouseDigitalPostProcess(MenuItem_p item)
|
|
{
|
|
mouse_digital_item = item;
|
|
return TRUE;
|
|
}
|
|
|
|
static SWBOOL MNU_MouseDigitalSetupCustom(UserCall call, MenuItem_p item)
|
|
{
|
|
static int currentfunc = 0;
|
|
|
|
if (call == uc_touchup)
|
|
return TRUE;
|
|
|
|
if (cust_callback == NULL)
|
|
{
|
|
if (call != uc_setup)
|
|
return FALSE;
|
|
currentfunc = MouseDigitalAxes[mouse_digital_item->tics/2][mouse_digital_item->tics%2];
|
|
currentfunc++;
|
|
|
|
cust_callback = MNU_MouseDigitalSetupCustom;
|
|
cust_callback_call = call;
|
|
cust_callback_item = item;
|
|
}
|
|
|
|
{
|
|
short w, h = 0;
|
|
const char *s = "Adv'd Mouse";
|
|
|
|
rotatesprite(10 << 16, (5-3) << 16, MZ, 0, 2427,
|
|
m_defshade, 0, MenuDrawFlags|ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1);
|
|
MNU_MeasureStringLarge(s, &w, &h);
|
|
MNU_DrawStringLarge(TEXT_XCENTER(w), 5, s);
|
|
}
|
|
|
|
int selection = MNU_SelectButtonFunction(mouse_digital_item->text, ¤tfunc);
|
|
switch (selection)
|
|
{
|
|
case -1: //cancel
|
|
cust_callback = NULL;
|
|
break;
|
|
case 1: //acknowledge
|
|
currentfunc--;
|
|
MouseDigitalAxes[mouse_digital_item->tics/2][mouse_digital_item->tics%2] = currentfunc;
|
|
CONTROL_MapDigitalAxis(mouse_digital_item->tics/2, currentfunc, mouse_digital_item->tics%2, controldevice_mouse);
|
|
MNU_SetAdvancedMouseFunctions(mouse_digital_item);
|
|
cust_callback = NULL;
|
|
break;
|
|
default: break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static SWBOOL MNU_SetAdvancedMouseFunctions(MenuItem_p item)
|
|
{
|
|
int axis;
|
|
char *p;
|
|
|
|
axis = item->tics;
|
|
ASSERT(axis >= 0 && axis < 4);
|
|
|
|
if (MouseDigitalAxes[axis/2][axis%2] < 0)
|
|
{
|
|
strcpy(AdvancedMouseAxisFunctions[axis], " -");
|
|
}
|
|
else
|
|
{
|
|
strcpy(AdvancedMouseAxisFunctions[axis], CONFIG_FunctionNumToName(MouseDigitalAxes[axis/2][axis%2]));
|
|
for (p = AdvancedMouseAxisFunctions[axis]; *p; p++)
|
|
{
|
|
if (*p == '_')
|
|
*p = ' ';
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static MenuItem_p joystick_button_item = NULL;
|
|
|
|
static SWBOOL MNU_JoystickButtonsInitialise(MenuItem_p mitem)
|
|
{
|
|
MenuItem_p item;
|
|
MenuItem templayer = { DefLayer(0, JoystickButtonNames[0], &joybuttonsgroup), OPT_XS, OPT_LINE(0), 1, m_defshade, 0, NULL, NULL, MNU_JoystickButtonPostProcess };
|
|
MenuItem tempinert = { DefInert(0, JoystickButtonFunctions[0]), OPT_XSIDE, OPT_LINE(0), 1, m_defshade, 0, NULL, MNU_SetJoystickButtonFunctions, NULL };
|
|
MenuItem temppagename = { DefInert(0, JoystickButtonPageName[0]), OPT_XS, OPT_LINE(JOYSTICKITEMSPERPAGE+1), 1, m_defshade, 0, NULL, NULL, NULL };
|
|
MenuItem tempnextpage = { DefOption(0, "Next..."), OPT_XSIDE, OPT_LINE(JOYSTICKITEMSPERPAGE+1), 1, m_defshade, 0, MNU_JoystickButtonNextPage, NULL, NULL };
|
|
MenuItem tempnone = { DefNone };
|
|
const char *hatdirs[] = { " Up", " Right", " Down", " Left" };
|
|
int button, page, pageitem;
|
|
|
|
if (joybuttonssetupgroup.items != NULL)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
page = 0;
|
|
pageitem = 0;
|
|
joybuttonssetupgroup.items = joybuttons_i[0];
|
|
item = &joybuttons_i[0][0];
|
|
|
|
for (button = 0; button < joynumbuttons * 2 + (joynumhats > 0) * 4; )
|
|
{
|
|
if (button < joynumbuttons * 2)
|
|
{
|
|
int dbutton = button / 2;
|
|
|
|
strcpy(JoystickButtonNames[dbutton], getjoyname(1, dbutton));
|
|
|
|
templayer.text = JoystickButtonNames[dbutton];
|
|
templayer.y = OPT_LINE(pageitem);
|
|
templayer.tics = dbutton;
|
|
memcpy(item, &templayer, sizeof(MenuItem));
|
|
item++;
|
|
|
|
tempinert.text = JoystickButtonFunctions[dbutton];
|
|
tempinert.y = OPT_LINE(pageitem);
|
|
tempinert.tics = dbutton;
|
|
memcpy(item, &tempinert, sizeof(MenuItem));
|
|
item++;
|
|
|
|
pageitem++;
|
|
|
|
strcpy(JoystickButtonNames[dbutton + MAXJOYBUTTONS], "Double ");
|
|
strcat(JoystickButtonNames[dbutton + MAXJOYBUTTONS], getjoyname(1, dbutton));
|
|
|
|
templayer.text = JoystickButtonNames[dbutton + MAXJOYBUTTONS];
|
|
templayer.y = OPT_LINE(pageitem);
|
|
templayer.tics = 128 | dbutton;
|
|
memcpy(item, &templayer, sizeof(MenuItem));
|
|
item++;
|
|
|
|
tempinert.text = JoystickButtonFunctions[dbutton + MAXJOYBUTTONS];
|
|
tempinert.y = OPT_LINE(pageitem);
|
|
tempinert.tics = 128 | dbutton;
|
|
memcpy(item, &tempinert, sizeof(MenuItem));
|
|
item++;
|
|
|
|
pageitem++;
|
|
|
|
button += 2;
|
|
}
|
|
else
|
|
{
|
|
int dir = button - joynumbuttons * 2;
|
|
int dbutton = joynumbuttons + dir;
|
|
|
|
strcpy(JoystickButtonNames[dbutton], getjoyname(2, 0));
|
|
strcat(JoystickButtonNames[dbutton], hatdirs[dir]);
|
|
|
|
templayer.text = JoystickButtonNames[dbutton];
|
|
templayer.y = OPT_LINE(pageitem);
|
|
templayer.tics = dbutton;
|
|
memcpy(item, &templayer, sizeof(MenuItem));
|
|
item++;
|
|
|
|
tempinert.text = JoystickButtonFunctions[dbutton];
|
|
tempinert.y = OPT_LINE(pageitem);
|
|
tempinert.tics = dbutton;
|
|
memcpy(item, &tempinert, sizeof(MenuItem));
|
|
item++;
|
|
|
|
pageitem++;
|
|
button++;
|
|
}
|
|
|
|
if (pageitem == JOYSTICKITEMSPERPAGE || button == joynumbuttons * 2 + (joynumhats > 0) * 4)
|
|
{
|
|
// next page
|
|
sprintf(JoystickButtonPageName[page], "Page %d / %d", page+1,
|
|
((joynumbuttons * 2 + (joynumhats > 0) * 4) / JOYSTICKITEMSPERPAGE) + 1);
|
|
|
|
temppagename.text = JoystickButtonPageName[page];
|
|
memcpy(item, &temppagename, sizeof(MenuItem));
|
|
item++;
|
|
|
|
memcpy(item, &tempnextpage, sizeof(MenuItem));
|
|
item++;
|
|
|
|
memcpy(item, &tempnone, sizeof(MenuItem));
|
|
|
|
page++;
|
|
pageitem = 0;
|
|
item = &joybuttons_i[page][0];
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static SWBOOL MNU_JoystickButtonPostProcess(MenuItem_p item)
|
|
{
|
|
joystick_button_item = item;
|
|
return TRUE;
|
|
}
|
|
|
|
static SWBOOL MNU_JoystickButtonSetupCustom(UserCall call, MenuItem *item)
|
|
{
|
|
static int currentfunc = 0;
|
|
|
|
if (call == uc_touchup)
|
|
return TRUE;
|
|
|
|
if (cust_callback == NULL)
|
|
{
|
|
if (call != uc_setup)
|
|
return FALSE;
|
|
|
|
if (joystick_button_item->tics & 128)
|
|
{
|
|
currentfunc = JoystickButtonsClicked[joystick_button_item->tics & 127];
|
|
}
|
|
else
|
|
{
|
|
currentfunc = JoystickButtons[joystick_button_item->tics & 127];
|
|
}
|
|
currentfunc++;
|
|
|
|
cust_callback = MNU_JoystickButtonSetupCustom;
|
|
cust_callback_call = call;
|
|
cust_callback_item = item;
|
|
}
|
|
|
|
{
|
|
short w, h = 0;
|
|
const char *s = "Joystick Setup";
|
|
|
|
rotatesprite(10 << 16, (5-3) << 16, MZ, 0, 2427,
|
|
m_defshade, 0, MenuDrawFlags|ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1);
|
|
MNU_MeasureStringLarge(s, &w, &h);
|
|
MNU_DrawStringLarge(TEXT_XCENTER(w), 5, s);
|
|
}
|
|
|
|
int selection = MNU_SelectButtonFunction(joystick_button_item->text, ¤tfunc);
|
|
switch (selection)
|
|
{
|
|
case -1: //cancel
|
|
cust_callback = NULL;
|
|
break;
|
|
case 1: //acknowledge
|
|
currentfunc--;
|
|
if (joystick_button_item->tics & 128)
|
|
{
|
|
JoystickButtonsClicked[joystick_button_item->tics & 127] = currentfunc;
|
|
CONTROL_MapButton(currentfunc, joystick_button_item->tics & 127, 1, controldevice_joystick);
|
|
}
|
|
else
|
|
{
|
|
JoystickButtons[joystick_button_item->tics & 127] = currentfunc;
|
|
CONTROL_MapButton(currentfunc, joystick_button_item->tics & 127, 0, controldevice_joystick);
|
|
}
|
|
MNU_SetJoystickButtonFunctions(joystick_button_item);
|
|
cust_callback = NULL;
|
|
break;
|
|
default: break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static SWBOOL MNU_JoystickButtonNextPage(void)
|
|
{
|
|
JoystickButtonPage = (JoystickButtonPage + 1) % (((joynumbuttons * 2 + (joynumhats > 0) * 4) / JOYSTICKITEMSPERPAGE) + 1);
|
|
joybuttonssetupgroup.items = &joybuttons_i[JoystickButtonPage][0];
|
|
joybuttonssetupgroup.cursor = 0;
|
|
MNU_ItemPreProcess(&joybuttonssetupgroup);
|
|
return TRUE;
|
|
}
|
|
|
|
static SWBOOL MNU_SetJoystickButtonFunctions(MenuItem_p item)
|
|
{
|
|
int button, clicked, function;
|
|
char *p;
|
|
|
|
clicked = (item->tics & 128) > 0;
|
|
button = item->tics & 127;
|
|
ASSERT(button >= 0 && button < MAXJOYBUTTONS);
|
|
|
|
if (clicked)
|
|
{
|
|
function = JoystickButtonsClicked[button];
|
|
}
|
|
else
|
|
{
|
|
function = JoystickButtons[button];
|
|
}
|
|
if (function < 0)
|
|
{
|
|
strcpy(JoystickButtonFunctions[button + clicked*MAXJOYBUTTONS], " -");
|
|
}
|
|
else
|
|
{
|
|
strcpy(JoystickButtonFunctions[button + clicked*MAXJOYBUTTONS], CONFIG_FunctionNumToName(function));
|
|
for (p = JoystickButtonFunctions[button + clicked*MAXJOYBUTTONS]; *p; p++)
|
|
{
|
|
if (*p == '_')
|
|
*p = ' ';
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static MenuItem_p joystick_axis_item = NULL;
|
|
|
|
static SWBOOL MNU_JoystickAxesInitialise(MenuItem_p mitem)
|
|
{
|
|
if (!CONTROL_JoyPresent)
|
|
{
|
|
return TRUE;
|
|
}
|
|
if (JoystickAxisPage < 0 || JoystickAxisPage >= joynumaxes)
|
|
{
|
|
JoystickAxisPage = 0;
|
|
}
|
|
|
|
strcpy(JoystickAxisName, getjoyname(0, JoystickAxisPage));
|
|
sprintf(JoystickAxisPageName, "Page %d / %d", JoystickAxisPage+1, joynumaxes);
|
|
slidersettings[sldr_joyaxisanalog] = MNU_ControlAxisOffset(JoystickAnalogAxes[JoystickAxisPage]);
|
|
slidersettings[sldr_joyaxisscale] = JoystickAnalogScale[JoystickAxisPage] >> 13;
|
|
slidersettings[sldr_joyaxisdead] = JoystickAnalogDead[JoystickAxisPage] >> 10;
|
|
slidersettings[sldr_joyaxissatur] = JoystickAnalogSaturate[JoystickAxisPage] >> 10;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static SWBOOL MNU_JoystickAxisPostProcess(MenuItem_p item)
|
|
{
|
|
joystick_axis_item = item;
|
|
return TRUE;
|
|
}
|
|
|
|
static SWBOOL MNU_JoystickAxisSetupCustom(UserCall call, MenuItem *item)
|
|
{
|
|
static int currentfunc = 0;
|
|
|
|
if (call == uc_touchup)
|
|
return TRUE;
|
|
|
|
if (cust_callback == NULL)
|
|
{
|
|
if (call != uc_setup)
|
|
return FALSE;
|
|
|
|
currentfunc = JoystickDigitalAxes[JoystickAxisPage][joystick_axis_item->tics];
|
|
currentfunc++;
|
|
|
|
cust_callback = MNU_JoystickAxisSetupCustom;
|
|
cust_callback_call = call;
|
|
cust_callback_item = item;
|
|
}
|
|
|
|
{
|
|
short w, h = 0;
|
|
const char *s = "Joystick Axes";
|
|
|
|
rotatesprite(10 << 16, (5-3) << 16, MZ, 0, 2427,
|
|
m_defshade, 0, MenuDrawFlags|ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1);
|
|
MNU_MeasureStringLarge(s, &w, &h);
|
|
MNU_DrawStringLarge(TEXT_XCENTER(w), 5, s);
|
|
}
|
|
|
|
int selection = MNU_SelectButtonFunction(joystick_axis_item->text, ¤tfunc);
|
|
switch (selection)
|
|
{
|
|
case -1: //cancel
|
|
cust_callback = NULL;
|
|
break;
|
|
case 1: //acknowledge
|
|
currentfunc--;
|
|
JoystickDigitalAxes[JoystickAxisPage][joystick_axis_item->tics] = currentfunc;
|
|
CONTROL_MapDigitalAxis(JoystickAxisPage, currentfunc, joystick_axis_item->tics, controldevice_joystick);
|
|
MNU_SetJoystickAxisFunctions(joystick_axis_item);
|
|
cust_callback = NULL;
|
|
break;
|
|
default: break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static SWBOOL MNU_JoystickAxisNextPage(void)
|
|
{
|
|
JoystickAxisPage = (JoystickAxisPage + 1) % MNU_ControlAxisOffset(analog_maxtype);
|
|
joyaxessetupgroup.cursor = 1;
|
|
MNU_ItemPreProcess(&joyaxessetupgroup);
|
|
MNU_JoystickAxesInitialise(NULL);
|
|
return TRUE;
|
|
}
|
|
|
|
static SWBOOL MNU_SetJoystickAxisFunctions(MenuItem_p item)
|
|
{
|
|
int function;
|
|
char *p;
|
|
|
|
function = JoystickDigitalAxes[JoystickAxisPage][item->tics];
|
|
if (function < 0)
|
|
{
|
|
strcpy(JoystickAxisFunctions[item->tics], " -");
|
|
}
|
|
else
|
|
{
|
|
strcpy(JoystickAxisFunctions[item->tics], CONFIG_FunctionNumToName(function));
|
|
for (p = JoystickAxisFunctions[item->tics]; *p; p++)
|
|
{
|
|
if (*p == '_')
|
|
*p = ' ';
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
SWBOOL
|
|
MNU_OrderCustom(UserCall call, MenuItem *item)
|
|
{
|
|
static signed char on_screen = 0,last_screen = 0;
|
|
UserInput order_input;
|
|
static int limitmove=0;
|
|
UserInput tst_input;
|
|
SWBOOL select_held = FALSE;
|
|
int zero = 0;
|
|
static SWBOOL DidOrderSound = FALSE;
|
|
short choose_snd;
|
|
static int wanghandle;
|
|
|
|
static short RegOrderScreen[] =
|
|
{
|
|
5262,
|
|
5261,
|
|
4979,
|
|
5111,
|
|
5118,
|
|
5113,
|
|
//5111,
|
|
//5118,
|
|
//4979,
|
|
//5261,
|
|
//5262
|
|
|
|
5114 // JBF: for my credits
|
|
};
|
|
static short SWOrderScreen[] =
|
|
{
|
|
5262,
|
|
5110,
|
|
5112,
|
|
5113,
|
|
5111,
|
|
5118,
|
|
4979,
|
|
|
|
5114 // JBF: for my credits
|
|
};
|
|
short *OrderScreen, OrderScreenSiz;
|
|
|
|
if (SW_SHAREWARE)
|
|
{
|
|
OrderScreen = SWOrderScreen;
|
|
OrderScreenSiz = SIZ(SWOrderScreen);
|
|
}
|
|
else
|
|
{
|
|
OrderScreen = RegOrderScreen;
|
|
OrderScreenSiz = SIZ(RegOrderScreen);
|
|
}
|
|
|
|
// Ignore the special touchup calls
|
|
if (call == uc_touchup)
|
|
return TRUE;
|
|
|
|
if (cust_callback == NULL)
|
|
{
|
|
if (call != uc_setup)
|
|
return FALSE;
|
|
}
|
|
|
|
if (SW_SHAREWARE && on_screen == 0 && !DidOrderSound)
|
|
{
|
|
DidOrderSound = TRUE;
|
|
choose_snd = STD_RANDOM_RANGE(1000);
|
|
if (choose_snd > 500 && !FX_SoundActive(wanghandle))
|
|
wanghandle = PlaySound(DIGI_WANGORDER1, &zero, &zero, &zero, v3df_dontpan);
|
|
else if (!FX_SoundActive(wanghandle))
|
|
wanghandle = PlaySound(DIGI_WANGORDER2, &zero, &zero, &zero, v3df_dontpan);
|
|
}
|
|
|
|
order_input.button0 = order_input.button1 = FALSE;
|
|
order_input.dir = dir_None;
|
|
|
|
// Zero out the input structure
|
|
tst_input.button0 = tst_input.button1 = FALSE;
|
|
tst_input.dir = dir_None;
|
|
|
|
if (!select_held)
|
|
{
|
|
CONTROL_GetUserInput(&tst_input);
|
|
//order_input_buffered.dir = tst_input.dir;
|
|
// Support a few other keys too
|
|
if (KEY_PRESSED(KEYSC_SPACE)||KEY_PRESSED(KEYSC_ENTER))
|
|
{
|
|
KEY_PRESSED(KEYSC_SPACE) = FALSE;
|
|
KEY_PRESSED(KEYSC_ENTER) = FALSE;
|
|
tst_input.dir = dir_South;
|
|
}
|
|
}
|
|
|
|
if (order_input_buffered.button0 || order_input_buffered.button1 || order_input_buffered.dir != dir_None)
|
|
{
|
|
if (tst_input.button0 == order_input_buffered.button0 &&
|
|
tst_input.button1 == order_input_buffered.button1 &&
|
|
tst_input.dir == order_input_buffered.dir)
|
|
{
|
|
select_held = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (labs(totalclock - limitmove) > 7)
|
|
{
|
|
order_input.button0 = order_input_buffered.button0;
|
|
order_input.button1 = order_input_buffered.button1;
|
|
order_input.dir = order_input_buffered.dir;
|
|
|
|
order_input_buffered.button0 = tst_input.button0;
|
|
order_input_buffered.button1 = tst_input.button1;
|
|
order_input_buffered.dir = tst_input.dir;
|
|
|
|
limitmove = totalclock;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
select_held = FALSE;
|
|
order_input_buffered.button0 = tst_input.button0;
|
|
order_input_buffered.button1 = tst_input.button1;
|
|
order_input_buffered.dir = tst_input.dir;
|
|
}
|
|
|
|
if (!KEY_PRESSED(KEYSC_ESC) && !order_input_buffered.button1)
|
|
{
|
|
cust_callback = MNU_OrderCustom;
|
|
cust_callback_call = call;
|
|
cust_callback_item = item;
|
|
}
|
|
else
|
|
{
|
|
KEY_PRESSED(KEYSC_ESC) = FALSE;
|
|
cust_callback = NULL;
|
|
DidOrderSound = FALSE;
|
|
on_screen = 0;
|
|
ExitMenus();
|
|
}
|
|
|
|
if (order_input.dir == dir_North)
|
|
{
|
|
on_screen--;
|
|
}
|
|
else if (order_input.dir == dir_South)
|
|
{
|
|
on_screen++;
|
|
}
|
|
else if (order_input.dir == dir_West)
|
|
{
|
|
on_screen--;
|
|
}
|
|
else if (order_input.dir == dir_East)
|
|
{
|
|
on_screen++;
|
|
}
|
|
|
|
// CTW MODIFICATION
|
|
// I reversed the logic in here to allow the user to loop around.
|
|
// Yeah... I changed default behavior just because I wanted to.
|
|
// AND YOU CAN'T STOP ME SUCKER!!!
|
|
if (on_screen < 0)
|
|
on_screen = OrderScreenSiz-1;
|
|
|
|
if (on_screen > OrderScreenSiz-1)
|
|
on_screen = 0;
|
|
// CTW MODIFICATION END
|
|
|
|
rotatesprite(0,0,RS_SCALE,0,OrderScreen[on_screen],0,0,
|
|
(ROTATE_SPRITE_CORNER|ROTATE_SPRITE_SCREEN_CLIP|ROTATE_SPRITE_NON_MASK|ROTATE_SPRITE_IGNORE_START_MOST),
|
|
0, 0, xdim-1, ydim-1);
|
|
|
|
if (on_screen == OrderScreenSiz-1)
|
|
{
|
|
// Jonathon's credits page hack :-)
|
|
|
|
static char *jtitle = "^Port Credits";
|
|
static char *jtext[] =
|
|
{
|
|
"*GAME AND ENGINE PORT",
|
|
" Jonathon \"JonoF\" Fowler",
|
|
"-",
|
|
"*\"POLYMOST\" 3D RENDERER",
|
|
"*NETWORKING, OTHER CODE",
|
|
" Ken \"Awesoken\" Silverman",
|
|
"-",
|
|
" Visit http://www.jonof.id.au/jfsw for the",
|
|
" source code, latest news, and updates of this port."
|
|
};
|
|
static char *scroller[] =
|
|
{
|
|
"This program is free software; you can redistribute it",
|
|
"and/or modify it under the terms of the GNU General",
|
|
"Public License as published by the Free Software",
|
|
"Foundation; either version 2 of the License, or (at your",
|
|
"option) any later version.",
|
|
"",
|
|
"This program is distributed in the hope that it will be",
|
|
"useful but WITHOUT ANY WARRANTY; without even the implied",
|
|
"warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR",
|
|
"PURPOSE. See the GNU General Public License (GPL.TXT) for",
|
|
"more details.",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"Thanks to these people for their input and contributions:",
|
|
"",
|
|
"Richard \"TerminX\" Gobeille,",
|
|
"Par \"Parkar\" Karlsson", // "Pär \"Parkar\" Karlsson",
|
|
"Ben \"ProAsm\" Smit",
|
|
"",
|
|
"and all those who submitted bug reports and ",
|
|
"supported the project financially!",
|
|
"",
|
|
"",
|
|
"--x--",
|
|
"",
|
|
"",
|
|
"",
|
|
""
|
|
};
|
|
const int numscrollerlines = SIZ(scroller);
|
|
short dimx, dimy;
|
|
int ycur = 54;
|
|
unsigned ji;
|
|
|
|
dimy = 0; MNU_MeasureString(jtitle, &dimx, &dimy);
|
|
MNU_DrawString(160-(dimx>>1), ycur, jtitle, 0, 0);
|
|
ycur += dimy + 8;
|
|
|
|
for (ji = 0; ji < SIZ(jtext); ji++)
|
|
{
|
|
switch (jtext[ji][0])
|
|
{
|
|
case '-':
|
|
ycur += 6;
|
|
break;
|
|
case '*':
|
|
dimx = dimy = 0;
|
|
MNU_MeasureString(&jtext[ji][1], &dimx, &dimy);
|
|
MNU_DrawString(160-(dimx>>1), ycur, &jtext[ji][1], 0, 16);
|
|
ycur += dimy+1;
|
|
break;
|
|
default:
|
|
if (ji>0 && jtext[ji-1][0] == '*') ycur += 3;
|
|
dimx = dimy = 0;
|
|
MNU_MeasureSmallString(&jtext[ji][1], &dimx, &dimy);
|
|
MNU_DrawSmallString(160-(dimx>>1), ycur, &jtext[ji][1], 0, 0);
|
|
ycur += dimy+1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
int m,i;
|
|
for (m=0, i=(totalclock/104)%numscrollerlines; m<4; m++,i++)
|
|
{
|
|
if (i == numscrollerlines)
|
|
i=0;
|
|
dimx = dimy = 0;
|
|
MNU_MeasureSmallString(scroller[i], &dimx, &dimy);
|
|
MNU_DrawSmallString(160-(dimx>>1), 154+(m*7), scroller[i], 0, 8);
|
|
}
|
|
}
|
|
|
|
//KB_ClearKeysDown();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL MNU_LoadModernDefaults(void)
|
|
{
|
|
SetDefaultKeyDefinitions(1);
|
|
SetMouseDefaults(1);
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL MNU_LoadClassicDefaults(void)
|
|
{
|
|
SetDefaultKeyDefinitions(0);
|
|
SetMouseDefaults(0);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
short EpisodeMenuSelection;
|
|
|
|
void
|
|
ExitMenus(void)
|
|
{
|
|
ControlPanelType = ct_mainmenu;
|
|
UsingMenus = FALSE;
|
|
|
|
if (LoadGameOutsideMoveLoop)
|
|
return;
|
|
|
|
ResumeGame();
|
|
SetRedrawScreen(&Player[myconnectindex]);
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_StartGame(void)
|
|
{
|
|
PLAYERp pp = Player + screenpeek;
|
|
int handle = 0;
|
|
int zero = 0;
|
|
|
|
// always assumed that a demo is playing
|
|
|
|
ready2send = 0;
|
|
Skill = currentmenu->cursor;
|
|
|
|
if (EpisodeMenuSelection >= 1)
|
|
Level = 5;
|
|
else
|
|
Level = 1;
|
|
|
|
ExitMenus();
|
|
DemoPlaying = FALSE;
|
|
ExitLevel = TRUE;
|
|
NewGame = TRUE;
|
|
DemoMode = FALSE;
|
|
CameraTestMode = FALSE;
|
|
|
|
//InitNewGame();
|
|
|
|
if (Skill == 0)
|
|
handle = PlaySound(DIGI_TAUNTAI3,&zero,&zero,&zero,v3df_none);
|
|
else if (Skill == 1)
|
|
handle = PlaySound(DIGI_NOFEAR,&zero,&zero,&zero,v3df_none);
|
|
else if (Skill == 2)
|
|
handle = PlaySound(DIGI_WHOWANTSWANG,&zero,&zero,&zero,v3df_none);
|
|
else if (Skill == 3)
|
|
handle = PlaySound(DIGI_NOPAIN,&zero,&zero,&zero,v3df_none);
|
|
|
|
if (handle > FX_Ok)
|
|
while (FX_SoundActive(handle))
|
|
handleevents();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void ResetMenuInput(void)
|
|
{
|
|
cust_callback = NULL;
|
|
InputMode = FALSE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_StartNetGame(void)
|
|
{
|
|
extern SWBOOL ExitLevel, ShortGameMode, DemoInitOnce, FirstTimeIntoGame;
|
|
extern short Level, Skill;
|
|
// CTW REMOVED
|
|
//extern int gTenActivated;
|
|
// CTW REMOVED END
|
|
int pnum;
|
|
|
|
// always assumed that a demo is playing
|
|
|
|
ready2send = 0;
|
|
// Skill can go negative here
|
|
Skill = gs.NetMonsters-1;
|
|
Level = gs.NetLevel + 1;
|
|
if (!AutoNet)
|
|
ExitMenus();
|
|
DemoPlaying = FALSE;
|
|
ExitLevel = TRUE;
|
|
NewGame = TRUE;
|
|
// restart demo for multi-play mode
|
|
DemoInitOnce = FALSE;
|
|
ResetMenuInput();
|
|
|
|
// TENSW: return if a joiner
|
|
if (/* CTW REMOVED gTenActivated && */ !AutoNet && FirstTimeIntoGame)
|
|
return TRUE;
|
|
|
|
// need to set gNet vars for self
|
|
// everone else gets a packet to set them
|
|
gNet.AutoAim = gs.AutoAim;
|
|
gNet.SpawnMarkers = gs.NetSpawnMarkers;
|
|
gNet.HurtTeammate = gs.NetHurtTeammate;
|
|
gNet.Nuke = gs.NetNuke;
|
|
gNet.KillLimit = gs.NetKillLimit*10;
|
|
gNet.TimeLimit = TimeLimitTable[gs.NetTimeLimit]*60*120;
|
|
|
|
if (ShortGameMode)
|
|
{
|
|
gNet.KillLimit /= 10;
|
|
gNet.TimeLimit /= 2;
|
|
}
|
|
|
|
gNet.TimeLimitClock = gNet.TimeLimit;
|
|
gNet.TeamPlay = gs.NetTeamPlay;
|
|
gNet.MultiGameType = gs.NetGameType+1;
|
|
|
|
if (gNet.MultiGameType == MULTI_GAME_COMMBAT_NO_RESPAWN)
|
|
{
|
|
gNet.MultiGameType = MULTI_GAME_COMMBAT;
|
|
gNet.NoRespawn = TRUE;
|
|
}
|
|
else
|
|
{
|
|
gNet.NoRespawn = FALSE;
|
|
}
|
|
|
|
if (CommEnabled)
|
|
{
|
|
PACKET_NEW_GAME p;
|
|
|
|
p.PacketType = PACKET_TYPE_NEW_GAME;
|
|
p.Level = Level;
|
|
p.Skill = Skill;
|
|
p.GameType = gs.NetGameType;
|
|
p.AutoAim = gs.AutoAim;
|
|
p.HurtTeammate = gs.NetHurtTeammate;
|
|
p.TeamPlay = gs.NetTeamPlay;
|
|
p.SpawnMarkers = gs.NetSpawnMarkers;
|
|
p.KillLimit = gs.NetKillLimit;
|
|
p.TimeLimit = gs.NetTimeLimit;
|
|
p.Nuke = gs.NetNuke;
|
|
|
|
netbroadcastpacket((uint8_t*)(&p), sizeof(p)); // TENSW
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
SWBOOL
|
|
MNU_EpisodeCustom(void)
|
|
{
|
|
EpisodeMenuSelection = currentmenu->cursor;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_QuitCustom(UserCall call, MenuItem_p item)
|
|
{
|
|
int select;
|
|
int ret;
|
|
extern SWBOOL DrawScreen;
|
|
|
|
// Ignore the special touchup calls
|
|
if (call == uc_touchup)
|
|
return TRUE;
|
|
|
|
if (cust_callback == NULL)
|
|
{
|
|
if (call != uc_setup)
|
|
return FALSE;
|
|
|
|
memset(dialog, 0, sizeof(dialog));
|
|
|
|
dialog[0] = S_QUITYN;
|
|
}
|
|
|
|
ret = MNU_Dialog();
|
|
|
|
if (DrawScreen)
|
|
return TRUE;
|
|
|
|
if (!ret)
|
|
{
|
|
if (!mnu_input.button1 && !KB_KeyPressed(sc_N))
|
|
{
|
|
cust_callback = MNU_QuitCustom;
|
|
cust_callback_call = call;
|
|
cust_callback_item = item;
|
|
}
|
|
else
|
|
{
|
|
cust_callback = NULL;
|
|
ExitMenus();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cust_callback = NULL;
|
|
ExitMenus();
|
|
}
|
|
|
|
if (KB_KeyPressed(sc_Y) || KB_KeyPressed(sc_Enter) || mnu_input.button0)
|
|
{
|
|
if (CommPlayers >= 2)
|
|
MultiPlayQuitFlag = TRUE;
|
|
else
|
|
QuitFlag = TRUE;
|
|
|
|
ExitMenus();
|
|
}
|
|
|
|
KB_ClearKeysDown();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_QuickLoadCustom(UserCall call, MenuItem_p item)
|
|
{
|
|
int select;
|
|
extern SWBOOL ReloadPrompt;
|
|
int bak;
|
|
PLAYERp pp = Player + myconnectindex;
|
|
extern short GlobInfoStringTime;
|
|
extern SWBOOL DrawScreen;
|
|
int ret;
|
|
|
|
if (cust_callback == NULL)
|
|
{
|
|
if (call != uc_setup)
|
|
return FALSE;
|
|
|
|
memset(dialog, 0, sizeof(dialog));
|
|
|
|
dialog[0] = "Load saved game";
|
|
sprintf(QuickLoadDescrDialog,"\"%s\" (Y/N)?",SaveGameDescr[QuickLoadNum]);
|
|
dialog[1] = QuickLoadDescrDialog;
|
|
}
|
|
|
|
// Ignore the special touchup calls
|
|
if (call == uc_touchup)
|
|
return TRUE;
|
|
|
|
ret = MNU_Dialog();
|
|
|
|
if (DrawScreen)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if (ret == FALSE)
|
|
{
|
|
if (KB_KeyPressed(sc_N) || KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter))
|
|
{
|
|
cust_callback = NULL;
|
|
if (ReloadPrompt)
|
|
{
|
|
ReloadPrompt = FALSE;
|
|
bak = GlobInfoStringTime;
|
|
GlobInfoStringTime = 999;
|
|
PutStringInfo(pp, "Press SPACE to restart");
|
|
GlobInfoStringTime = bak;
|
|
}
|
|
|
|
KB_ClearKeysDown();
|
|
ExitMenus();
|
|
}
|
|
else
|
|
{
|
|
cust_callback = MNU_QuickLoadCustom;
|
|
cust_callback_call = call;
|
|
cust_callback_item = item;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Y pressed
|
|
cust_callback = NULL;
|
|
|
|
KB_ClearKeysDown();
|
|
LoadSaveMsg("Loading...");
|
|
|
|
PauseAction();
|
|
|
|
ReloadPrompt = FALSE;
|
|
if (LoadGame(QuickLoadNum) == -1)
|
|
{
|
|
ResumeAction();
|
|
return FALSE;
|
|
}
|
|
|
|
ready2send = 1;
|
|
LastSaveNum = -1;
|
|
|
|
// do a load game here
|
|
KB_ClearKeysDown();
|
|
ExitMenus();
|
|
}
|
|
|
|
KB_ClearKeysDown();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// MENU FUNCTIONS /////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////
|
|
// Set some global menu related defaults
|
|
////////////////////////////////////////////////
|
|
void
|
|
MNU_InitMenus(void)
|
|
{
|
|
pClearTextLine(Player + myconnectindex, TEXT_INFO_LINE(0));
|
|
|
|
slidersettings[sldr_mouse] = gs.MouseSpeed/(MOUSE_SENS_MAX_VALUE/SLDR_MOUSESENSEMAX);
|
|
|
|
slidersettings[sldr_sndfxvolume] = gs.SoundVolume / (FX_VOL_MAX_VALUE/SLDR_SNDFXVOLMAX);
|
|
slidersettings[sldr_musicvolume] = gs.MusicVolume / (MUSIC_VOL_MAX_VALUE/SLDR_MUSICVOLMAX);
|
|
slidersettings[sldr_scrsize] = gs.BorderNum;
|
|
slidersettings[sldr_brightness] = gs.Brightness;
|
|
slidersettings[sldr_bordertile] = gs.BorderTile;
|
|
|
|
{
|
|
int i,newx=xdim,newy=ydim;
|
|
|
|
buttonsettings[btn_videofs] = fullscreen;
|
|
|
|
UpdateValidModes(bpp,fullscreen);
|
|
for (i=0; i<numvalidbpps; i++)
|
|
if (validbpps[i] == bpp)
|
|
slidersettings[sldr_videobpp] = i;
|
|
|
|
i = checkvideomode(&newx, &newy, bpp, fullscreen, 1);
|
|
if (i != 0x7fffffff && i >= 0)
|
|
for (i=0; i<numvalidresolutions; i++)
|
|
if (validresolutions[i].xdim == newx && validresolutions[i].ydim == newy)
|
|
slidersettings[sldr_videores] = i;
|
|
}
|
|
|
|
buttonsettings[btn_auto_run] = gs.AutoRun;
|
|
buttonsettings[btn_auto_aim] = gs.AutoAim;
|
|
buttonsettings[btn_messages] = gs.Messages;
|
|
buttonsettings[btn_crosshair] = gs.Crosshair;
|
|
// buttonsettings[btn_bobbing] = gs.Bobbing;
|
|
buttonsettings[btn_shadows] = gs.Shadows;
|
|
|
|
buttonsettings[btn_mouse_aim] = gs.MouseAimingType;
|
|
buttonsettings[btn_mouse_invert] = gs.MouseInvert;
|
|
buttonsettings[btn_sound] = gs.FxOn;
|
|
buttonsettings[btn_music] = gs.MusicOn;
|
|
buttonsettings[btn_talking] = gs.Talking;
|
|
|
|
buttonsettings[btn_voxels] = gs.Voxels;
|
|
buttonsettings[btn_ambience] = gs.Ambient;
|
|
buttonsettings[btn_playcd] = gs.PlayCD;
|
|
buttonsettings[btn_flipstereo] = gs.FlipStereo;
|
|
buttonsettings[btn_stats] = gs.Stats;
|
|
|
|
slidersettings[sldr_gametype] = gs.NetGameType;
|
|
slidersettings[sldr_netlevel] = gs.NetLevel;
|
|
slidersettings[sldr_monsters] = gs.NetMonsters;
|
|
slidersettings[sldr_killlimit] = gs.NetKillLimit;
|
|
slidersettings[sldr_timelimit] = gs.NetTimeLimit;
|
|
slidersettings[sldr_playercolor] = gs.NetColor;
|
|
|
|
buttonsettings[btn_nuke] = gs.NetNuke;
|
|
buttonsettings[btn_markers] = gs.NetSpawnMarkers;
|
|
buttonsettings[btn_teamplay] = gs.NetTeamPlay;
|
|
buttonsettings[btn_friendlyfire] = gs.NetHurtTeammate;
|
|
buttonsettings[btn_parental] = gs.ParentalLock;
|
|
|
|
slidersettings[sldr_mousescalex] = MouseAnalogScale[0]>>13;
|
|
slidersettings[sldr_mousescaley] = MouseAnalogScale[1]>>13;
|
|
|
|
slidersettings[sldr_joyaxisscale] = 0;
|
|
slidersettings[sldr_joyaxisanalog] = 0;
|
|
slidersettings[sldr_joyaxisdead] = 0;
|
|
slidersettings[sldr_joyaxissatur] = 0;
|
|
|
|
// Distinguish between Single or Multiplay for new game menu types
|
|
if (numplayers > 1)
|
|
main_i[0].child = &networkgroup;
|
|
else
|
|
// #ifdef SW_SHAREWARE
|
|
main_i[0].child = &episodegroup;
|
|
// #else
|
|
// main_i[0].child = &skillgroup;
|
|
// #endif
|
|
main_i[4].text = (SW_SHAREWARE) ? MAIN_MENU_HOW_TO_ORDER : MAIN_MENU_COOL_STUFF;
|
|
main_i[4].hotkey = (SW_SHAREWARE) ? KEYSC_H : KEYSC_C;
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Measure the pixel width of a graphic string
|
|
////////////////////////////////////////////////
|
|
static char lg_xlat_num[] = {0,1,2,3,4,5,6,7,8,9};
|
|
#define FONT_LARGE_ALPHA 3706
|
|
#define FONT_LARGE_DIGIT 3732
|
|
|
|
void
|
|
MNU_MeasureStringLarge(const char *string, short *w, short *h)
|
|
{
|
|
short ndx, width, height;
|
|
char c;
|
|
short pic;
|
|
|
|
width = 0;
|
|
height = *h;
|
|
|
|
for (ndx = 0; (c = string[ndx]) != 0; ndx++)
|
|
{
|
|
if (isalpha(c))
|
|
{
|
|
c = toupper(c);
|
|
pic = FONT_LARGE_ALPHA + (c - 'A');
|
|
}
|
|
else if (isdigit(c))
|
|
{
|
|
pic = FONT_LARGE_DIGIT + lg_xlat_num[(c - '0')];
|
|
}
|
|
else if (c == ' ')
|
|
{
|
|
width += 10; // Special case for space char
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
|
|
width += tilesiz[pic].x+1;
|
|
if (height < tilesiz[pic].y)
|
|
height = tilesiz[pic].y;
|
|
}
|
|
|
|
*w = width;
|
|
*h = height;
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Draw a string using a graphic font
|
|
////////////////////////////////////////////////
|
|
void
|
|
MNU_DrawStringLarge(short x, short y, const char *string)
|
|
{
|
|
int ndx, offset;
|
|
char c;
|
|
short pic;
|
|
|
|
offset = x;
|
|
|
|
for (ndx = 0; (c = string[ndx]) != 0; ndx++)
|
|
{
|
|
if (isalpha(c))
|
|
{
|
|
c = toupper(c);
|
|
pic = FONT_LARGE_ALPHA + (c - 'A');
|
|
}
|
|
else if (isdigit(c))
|
|
{
|
|
pic = FONT_LARGE_DIGIT + lg_xlat_num[(c - '0')];
|
|
}
|
|
else if (c == ' ')
|
|
{
|
|
offset += 10;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
|
|
rotatesprite(offset << 16, y << 16, MZ, 0, pic, MenuTextShade, 0, MenuDrawFlags|ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1);
|
|
offset += tilesiz[pic].x + 1;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////
|
|
// Measure the pixel width of a graphic string
|
|
////////////////////////////////////////////////
|
|
void
|
|
MNU_MeasureString(const char *string, short *w, short *h)
|
|
{
|
|
short ndx, width, height;
|
|
char c;
|
|
short ac;
|
|
|
|
if (string[0] == '^')
|
|
{
|
|
MNU_MeasureStringLarge(&string[1], w, h);
|
|
return;
|
|
}
|
|
|
|
width = 0;
|
|
height = *h;
|
|
|
|
for (ndx = 0; (c = string[ndx]) != 0; ndx++)
|
|
{
|
|
ac = c - '!' + STARTALPHANUM;
|
|
if ((ac < STARTALPHANUM || ac > ENDALPHANUM) && c != asc_Space)
|
|
break;
|
|
|
|
if (c > asc_Space && c < 127)
|
|
{
|
|
width += tilesiz[ac].x;
|
|
if (height < tilesiz[ac].y)
|
|
height = tilesiz[ac].y;
|
|
}
|
|
else if (c == asc_Space)
|
|
width += 4; // Special case for space char
|
|
}
|
|
|
|
*w = width;
|
|
*h = height;
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Draw a string using a graphic font
|
|
//
|
|
// MenuTextShade and MenuDrawFlags
|
|
////////////////////////////////////////////////
|
|
void
|
|
MNU_DrawString(short x, short y, const char *string, short shade, short pal)
|
|
{
|
|
int ndx, offset;
|
|
char c;
|
|
short ac;
|
|
|
|
if (string[0] == '^')
|
|
{
|
|
MNU_DrawStringLarge(x,y, &string[1]);
|
|
return;
|
|
}
|
|
|
|
offset = x;
|
|
|
|
for (ndx = 0; (c = string[ndx]) != 0; ndx++)
|
|
{
|
|
ac = c - '!' + STARTALPHANUM;
|
|
if ((ac < STARTALPHANUM || ac > ENDALPHANUM) && c != asc_Space)
|
|
break;
|
|
|
|
if (c > asc_Space && c < 127)
|
|
{
|
|
rotatesprite(offset<<16,y<<16,MZ,0,ac, shade, pal, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
offset += tilesiz[ac].x;
|
|
}
|
|
else if (c == asc_Space)
|
|
offset += 4; // Special case for space char
|
|
}
|
|
|
|
}
|
|
/* Original code
|
|
void
|
|
MNU_DrawString(short x, short y, char *string)
|
|
{
|
|
int ndx, offset;
|
|
char c;
|
|
|
|
if (string[0] == '^')
|
|
{
|
|
MNU_DrawStringLarge(x,y, &string[1]);
|
|
return;
|
|
}
|
|
|
|
offset = x;
|
|
|
|
for (ndx = 0; (c = string[ndx]) != 0; ndx++)
|
|
{
|
|
if (c > asc_Space && c < 127)
|
|
{
|
|
rotatesprite(offset << 16, y << 16, MZ, 0, xlatfont[c], MenuTextShade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
offset += tilesiz[xlatfont[c]].x;
|
|
} else
|
|
if (c == asc_Space)
|
|
offset += 4; // Special case for space char
|
|
}
|
|
|
|
}
|
|
*/
|
|
|
|
////////////////////////////////////////////////
|
|
// Measure the pixel width of a small font string
|
|
////////////////////////////////////////////////
|
|
void
|
|
MNU_MeasureSmallString(const char *string, short *w, short *h)
|
|
{
|
|
short ndx, width, height;
|
|
char c;
|
|
short ac;
|
|
|
|
width = 0;
|
|
height = *h;
|
|
|
|
for (ndx = 0; (c = string[ndx]) != 0; ndx++)
|
|
{
|
|
ac = (c - '!') + 2930;
|
|
if ((ac < 2930 || ac > 3023) && c != asc_Space)
|
|
break;
|
|
|
|
if (c > asc_Space && c < 127)
|
|
{
|
|
width += tilesiz[ac].x;
|
|
if (height < tilesiz[ac].y)
|
|
height = tilesiz[ac].y;
|
|
}
|
|
else if (c == asc_Space)
|
|
width += 4; // Special case for space char
|
|
}
|
|
|
|
*w = width;
|
|
*h = height;
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Draw a string using a small graphic font
|
|
////////////////////////////////////////////////
|
|
void
|
|
MNU_DrawSmallString(short x, short y, const char *string, short shade, short pal)
|
|
{
|
|
int ndx;
|
|
char c;
|
|
short ac,offset;
|
|
|
|
|
|
offset = x;
|
|
|
|
for (ndx = 0; (c = string[ndx]) != 0; ndx++)
|
|
{
|
|
ac = c - '!' + 2930;
|
|
if ((ac < 2930 || ac > 3023) && c != asc_Space)
|
|
break;
|
|
|
|
if (c > asc_Space && c < 127)
|
|
{
|
|
rotatesprite(offset<<16,y<<16,MZ,0,ac, shade, pal, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
|
|
offset += tilesiz[ac].x;
|
|
|
|
}
|
|
else if (c == asc_Space)
|
|
{
|
|
offset += 4; // Special case for space char
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Get an input string from user using small font
|
|
////////////////////////////////////////////////
|
|
|
|
signed char
|
|
MNU_InputSmallString(char *name, short pix_width)
|
|
{
|
|
char ch;
|
|
short w, h;
|
|
UserInput con_input;
|
|
|
|
#define ascii_backspace 8
|
|
#define ascii_esc 27
|
|
#define ascii_return 13
|
|
|
|
if (!MoveSkip4 && !MessageInputMode)
|
|
{
|
|
con_input.dir = dir_None;
|
|
CONTROL_GetUserInput(&con_input);
|
|
|
|
if (con_input.dir == dir_North)
|
|
{
|
|
CON_CommandHistory(1);
|
|
}
|
|
else if (con_input.dir == dir_South)
|
|
{
|
|
CON_CommandHistory(-1);
|
|
}
|
|
}
|
|
|
|
while (KB_KeyWaiting())
|
|
{
|
|
ch = KB_Getch();
|
|
|
|
// skip any extended key
|
|
if (ch == 0)
|
|
{
|
|
ch = KB_Getch();
|
|
if (ch == 104) // extended enter
|
|
ch = ascii_return;
|
|
else
|
|
continue;
|
|
}
|
|
|
|
if (ch == ascii_backspace)
|
|
{
|
|
name[strlen(name) - 1] = '\0';
|
|
continue;
|
|
}
|
|
else if (ch == ascii_esc)
|
|
{
|
|
return -1;
|
|
}
|
|
else if (ch == ascii_return)
|
|
{
|
|
return FALSE;
|
|
}
|
|
else if (!isprint(ch))
|
|
continue;
|
|
|
|
MNU_MeasureSmallString(name, &w, &h);
|
|
if (w < pix_width)
|
|
{
|
|
if (strlen(name) < 256) // Dont let it go too far!
|
|
sprintf(name, "%s%c", name, ch);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Draw dialog text on screen
|
|
////////////////////////////////////////////////
|
|
static SWBOOL
|
|
MNU_Dialog(void)
|
|
{
|
|
short ndx, linecnt, w[MAXDIALOG], h, x, y;
|
|
|
|
linecnt = 0;
|
|
h = 8;
|
|
|
|
for (ndx = 0; ndx < MAXDIALOG && dialog[ndx]; ndx++)
|
|
{
|
|
MNU_MeasureString(dialog[ndx], &w[ndx], &h);
|
|
ASSERT(w[ndx] < XDIM);
|
|
linecnt++;
|
|
}
|
|
|
|
y = ((YDIM - ((h * linecnt) + (linecnt * 2))) / 2);
|
|
|
|
for (ndx = 0; ndx < linecnt; ndx++)
|
|
{
|
|
x = ((XDIM - w[ndx]) / 2);
|
|
MNU_DrawString(x, y, dialog[ndx],1,16);
|
|
y += (h + 3);
|
|
}
|
|
|
|
mnu_input.button0 = mnu_input.button1 = FALSE;
|
|
CONTROL_ClearUserInput(&mnu_input);
|
|
CONTROL_GetUserInput(&mnu_input);
|
|
|
|
if (KB_KeyPressed(sc_Y) || KB_KeyPressed(sc_Enter) || mnu_input.button0)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Get an input string from user
|
|
////////////////////////////////////////////////
|
|
|
|
signed char
|
|
MNU_InputString(char *name, short pix_width)
|
|
{
|
|
char ch;
|
|
short w, h;
|
|
|
|
#define ascii_backspace 8
|
|
#define ascii_esc 27
|
|
#define ascii_return 13
|
|
|
|
while (KB_KeyWaiting())
|
|
{
|
|
ch = KB_Getch();
|
|
|
|
////DSPRINTF(ds, "%c %d", ch, ch);
|
|
//MONO_PRINT(ds);
|
|
|
|
// skip most extended keys
|
|
if (ch == 0)
|
|
{
|
|
ch = KB_Getch();
|
|
|
|
////DSPRINTF(ds, "extended key %c %d", ch, ch);
|
|
//MONO_PRINT(ds);
|
|
|
|
if (ch == 104) // extended enter
|
|
ch = ascii_return;
|
|
else
|
|
continue;
|
|
}
|
|
|
|
if (ch == ascii_backspace)
|
|
{
|
|
name[strlen(name) - 1] = '\0';
|
|
continue;
|
|
}
|
|
else if (ch == ascii_esc)
|
|
{
|
|
return -1;
|
|
}
|
|
else if (ch == ascii_return)
|
|
{
|
|
return FALSE;
|
|
}
|
|
else if (!isprint(ch))
|
|
continue;
|
|
|
|
MNU_MeasureString(name, &w, &h);
|
|
if (w < pix_width)
|
|
{
|
|
sprintf(name, "%s%c", name, ch);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
#define SS_XSTART 146L
|
|
#define SS_YSTART SD_YSTART
|
|
#define SS_BORDER_SIZE 5L
|
|
|
|
void LoadSaveMsg(char *msg)
|
|
{
|
|
short w,h;
|
|
|
|
flushperms();
|
|
DrawMenuLevelScreen();
|
|
strcpy((char *)ds, (char *)msg);
|
|
MNU_MeasureString(ds, &w, &h);
|
|
MNU_DrawString(TEXT_XCENTER(w), 170, ds, 1, 16);
|
|
nextpage();
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////
|
|
// Load Game menu
|
|
// This function gets called whenever you
|
|
// press enter on one of the load game
|
|
// spots.
|
|
// I'm figuring it need to do the following:
|
|
// . Load the game if there is one by calling: MNU_LoadGameCustom.
|
|
////////////////////////////////////////////////
|
|
SWBOOL
|
|
MNU_GetLoadCustom(void)
|
|
{
|
|
short load_num;
|
|
|
|
load_num = currentmenu->cursor;
|
|
|
|
// no saved game exists - don't do anything
|
|
if (SaveGameDescr[load_num][0] == '\0')
|
|
return FALSE;
|
|
|
|
if (InMenuLevel || DemoMode || DemoPlaying)
|
|
{
|
|
LoadSaveMsg("Loading...");
|
|
|
|
if (LoadGame(load_num) == -1)
|
|
return FALSE;
|
|
|
|
QuickLoadNum = load_num;
|
|
// the (Quick)Save menu should default to the last loaded game
|
|
SaveGameGroup.cursor = load_num;
|
|
|
|
ExitMenus();
|
|
ExitLevel = TRUE;
|
|
LoadGameOutsideMoveLoop = TRUE;
|
|
if (DemoMode || DemoPlaying)
|
|
LoadGameFromDemo = TRUE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LoadSaveMsg("Loading...");
|
|
|
|
PauseAction();
|
|
|
|
if (LoadGame(load_num) == -1)
|
|
{
|
|
ResumeAction();
|
|
return FALSE;
|
|
}
|
|
|
|
QuickLoadNum = load_num;
|
|
// the (Quick)Save menu should default to the last loaded game
|
|
SaveGameGroup.cursor = load_num;
|
|
|
|
ready2send = 1;
|
|
LastSaveNum = -1;
|
|
ExitMenus();
|
|
|
|
if (DemoMode)
|
|
{
|
|
ExitLevel = TRUE;
|
|
DemoPlaying = FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Save Game menu
|
|
// This function gets called whenever you
|
|
// press enter on one of the save game
|
|
// spots.
|
|
// I'm figuring it need to do the following:
|
|
// . Call MNU_GetInput to allow string input of description.
|
|
// . Save the game if there is one by calling: MNU_SaveGameCustom.
|
|
////////////////////////////////////////////////
|
|
SWBOOL
|
|
MNU_GetSaveCustom(void)
|
|
{
|
|
short save_num;
|
|
extern SWBOOL InMenuLevel, LoadGameOutsideMoveLoop;
|
|
|
|
save_num = currentmenu->cursor;
|
|
|
|
if (InMenuLevel)
|
|
return FALSE;
|
|
|
|
if (MenuInputMode)
|
|
{
|
|
PauseAction();
|
|
|
|
LoadSaveMsg("Saving...");
|
|
|
|
if (SaveGame(save_num) != -1)
|
|
{
|
|
QuickLoadNum = save_num;
|
|
|
|
LoadGameGroup.cursor = save_num;
|
|
LastSaveNum = -1;
|
|
}
|
|
|
|
ResumeAction();
|
|
ExitMenus();
|
|
|
|
// toggle edit mode
|
|
MenuInputMode = FALSE;
|
|
}
|
|
else
|
|
{
|
|
strcpy(BackupSaveGameDescr, SaveGameDescr[save_num]);
|
|
|
|
// clear keyboard buffer
|
|
while (KB_KeyWaiting())
|
|
{
|
|
if (KB_Getch() == 0)
|
|
KB_Getch();
|
|
}
|
|
|
|
// toggle edit mode
|
|
MenuInputMode = TRUE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Load/Save Touchup function
|
|
// This function gets called each frame by DrawMenus
|
|
////////////////////////////////////////////////
|
|
|
|
static SWBOOL
|
|
MNU_DrawLoadSave(short game_num)
|
|
{
|
|
// screen border
|
|
rotatesprite(SS_XSTART << 16, SS_YSTART << 16, MZ, 0, pic_loadsavescreen,
|
|
0, 0, MenuDrawFlags | ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1);
|
|
|
|
// description box
|
|
rotatesprite((SD_XSTART) << 16, (SD_YSTART) << 16, MZ, 0, pic_savedescr,
|
|
0, 0, MenuDrawFlags | ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1);
|
|
|
|
// cursor for text boxes
|
|
rotatesprite((SD_XSTART + 3) << 16, (SD_LINE(game_num) + 1) << 16, MZ, 0, pic_loadsavecursor,
|
|
0, 0, MenuDrawFlags | ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static char SaveGameInfo1[80];
|
|
static char SaveGameInfo2[80];
|
|
|
|
SWBOOL
|
|
MNU_LoadSaveMove(UserCall call, MenuItem_p item)
|
|
{
|
|
short i;
|
|
short game_num;
|
|
short tile;
|
|
static short SaveGameEpisode, SaveGameLevel, SaveGameSkill;
|
|
SWBOOL GotInput = FALSE;
|
|
|
|
if (!UsingMenus)
|
|
return TRUE;
|
|
|
|
game_num = currentmenu->cursor;
|
|
|
|
// read all descr first time through - LastSaveNum starts at 99
|
|
if (LastSaveNum == 99)
|
|
{
|
|
memset(SaveGameDescr, '\0', sizeof(SaveGameDescr));
|
|
|
|
for (i = 0; i < 10; i++)
|
|
LoadGameDescr(i, SaveGameDescr[i]);
|
|
}
|
|
|
|
// cursor has moved - read header
|
|
if (game_num != LastSaveNum)
|
|
{
|
|
screen_tile = LoadGameFullHeader(game_num, SaveGameDescr[game_num],
|
|
&SaveGameLevel, &SaveGameSkill);
|
|
|
|
sprintf(SaveGameInfo1, "Level %d, Skill %d", SaveGameLevel, SaveGameSkill+1);
|
|
SaveGameInfo2[0] = 0;
|
|
}
|
|
|
|
if (QuickSaveMode)
|
|
{
|
|
QuickSaveMode = FALSE;
|
|
MenuInputMode = TRUE;
|
|
strcpy(BackupSaveGameDescr, SaveGameDescr[game_num]);
|
|
KB_ClearKeysDown();
|
|
KB_FlushKeyboardQueue();
|
|
}
|
|
|
|
LastSaveNum = game_num;
|
|
|
|
// input mode check
|
|
if (MenuInputMode)
|
|
{
|
|
MenuItem *item = ¤tmenu->items[currentmenu->cursor];
|
|
|
|
if (SavePrompt)
|
|
{
|
|
if (KB_KeyPressed(sc_Y) || KB_KeyPressed(sc_Enter))
|
|
{
|
|
KB_ClearKeyDown(sc_Y);
|
|
KB_ClearKeyDown(sc_Enter);
|
|
SavePrompt = FALSE;
|
|
// use input
|
|
item->custom();
|
|
}
|
|
else if (KB_KeyPressed(sc_N))
|
|
{
|
|
KB_ClearKeyDown(sc_N);
|
|
strcpy(SaveGameDescr[game_num], BackupSaveGameDescr);
|
|
SavePrompt = FALSE;
|
|
MenuInputMode = FALSE;
|
|
}
|
|
}
|
|
else
|
|
// get input
|
|
switch (MNU_InputString(SaveGameDescr[game_num], 114))
|
|
{
|
|
case -1: // Cancel Input (pressed ESC) or Err
|
|
strcpy(SaveGameDescr[game_num], BackupSaveGameDescr);
|
|
MenuInputMode = FALSE;
|
|
KB_ClearKeysDown();
|
|
break;
|
|
case FALSE: // Input finished (RETURN)
|
|
// no input
|
|
if (SaveGameDescr[game_num][0] == '\0')
|
|
{
|
|
strcpy(SaveGameDescr[game_num], BackupSaveGameDescr);
|
|
MenuInputMode = FALSE;
|
|
}
|
|
else
|
|
{
|
|
GotInput = TRUE;
|
|
}
|
|
KB_ClearKeyDown(sc_Enter);
|
|
break;
|
|
case TRUE: // Got input
|
|
break;
|
|
}
|
|
|
|
if (GotInput)
|
|
{
|
|
if (BackupSaveGameDescr[0])
|
|
SavePrompt = TRUE;
|
|
|
|
if (!SavePrompt)
|
|
{
|
|
// use input
|
|
item->custom();
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_LoadSaveDraw(UserCall call, MenuItem_p item)
|
|
{
|
|
short i;
|
|
short game_num;
|
|
short tile;
|
|
|
|
game_num = currentmenu->cursor;
|
|
|
|
// misc drawing
|
|
MNU_DrawLoadSave(game_num);
|
|
|
|
// print game descriptions
|
|
for (i = 0; i < 10; i++)
|
|
{
|
|
if (i == game_num && MenuInputMode && !SavePrompt)
|
|
{
|
|
static SWBOOL cur_show;
|
|
char tmp[sizeof(SaveGameDescr[0])];
|
|
|
|
//cur_show ^= 1;
|
|
cur_show = (totalclock & 32);
|
|
if (cur_show)
|
|
{
|
|
// add a cursor to the end
|
|
sprintf(tmp, "%s_", SaveGameDescr[i]);
|
|
}
|
|
else
|
|
strcpy(tmp, SaveGameDescr[i]);
|
|
|
|
MNU_DrawString(SD_XSTART + 4, SD_YSTART + (i * SD_YOFF) + 2, tmp, 1, 16);
|
|
}
|
|
else if (SaveGameDescr[i][0] != '\0')
|
|
{
|
|
MNU_DrawString(SD_XSTART + 4, SD_YSTART + (i * SD_YOFF) + 2, SaveGameDescr[i], 1, 16);
|
|
}
|
|
}
|
|
|
|
if (screen_tile != -1)
|
|
{
|
|
// draw 160x100 save screen
|
|
rotatesprite((SS_XSTART + SS_BORDER_SIZE) << 16, (SS_YSTART + SS_BORDER_SIZE) << 16, (1 << 16), 0 + 512, screen_tile,
|
|
0, 0, MenuDrawFlags | ROTATE_SPRITE_CORNER | ROTATE_SPRITE_NON_MASK | ROTATE_SPRITE_YFLIP, 0, 0, xdim - 1, ydim - 1);
|
|
|
|
// draw info string
|
|
MNU_DrawString(SS_XSTART + 13, SS_YSTART + 100 + 10, SaveGameInfo1, 1, 16);
|
|
MNU_DrawString(SS_XSTART + 13, SS_YSTART + 100 + 18, SaveGameInfo2, 1, 16);
|
|
|
|
if (SavePrompt)
|
|
{
|
|
MNU_DrawString(SS_XSTART + SS_BORDER_SIZE + 5, SS_YSTART + SS_BORDER_SIZE + 47, "Overwrite previous", 1, 16);
|
|
MNU_DrawString(SS_XSTART + SS_BORDER_SIZE + 5, SS_YSTART + SS_BORDER_SIZE + 47 + 12, " saved game (Y/N)", 1, 16);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// draw 160x100 black pic
|
|
rotatesprite((SS_XSTART + SS_BORDER_SIZE) << 16, (SS_YSTART + SS_BORDER_SIZE) << 16, (1 << 16), 0, pic_loadsavescreenbak,
|
|
0, 0, MenuDrawFlags | ROTATE_SPRITE_CORNER | ROTATE_SPRITE_NON_MASK, 0, 0, xdim - 1, ydim - 1);
|
|
|
|
MNU_DrawString(SS_XSTART + SS_BORDER_SIZE + 60, SS_YSTART + SS_BORDER_SIZE + 47, "Empty", 1, 16);
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_ShareWareCheck(MenuItem *item)
|
|
{
|
|
if (SW_SHAREWARE)
|
|
{
|
|
SET(item->flags, mf_disabled);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_CheckUserMap(MenuItem *item)
|
|
{
|
|
if (UserMapName[0] == '\0')
|
|
RESET(item->flags, mf_disabled);
|
|
else
|
|
SET(item->flags, mf_disabled);
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_ShareWareMessage(MenuItem *item)
|
|
{
|
|
char *extra_text;
|
|
short w,h;
|
|
|
|
if (SW_SHAREWARE)
|
|
{
|
|
extra_text = "Be sure to call 800-3DREALMS today";
|
|
MNU_MeasureString(extra_text, &w, &h);
|
|
MNU_DrawString(TEXT_XCENTER(w), 110, extra_text, 1, 16);
|
|
extra_text = "and order the game.";
|
|
MNU_MeasureString(extra_text, &w, &h);
|
|
MNU_DrawString(TEXT_XCENTER(w), 120, extra_text, 1, 16);
|
|
extra_text = "You are only playing the first ";
|
|
MNU_MeasureString(extra_text, &w, &h);
|
|
MNU_DrawString(TEXT_XCENTER(w), 130, extra_text, 1, 16);
|
|
extra_text = "four levels, and are missing most";
|
|
MNU_MeasureString(extra_text, &w, &h);
|
|
MNU_DrawString(TEXT_XCENTER(w), 140, extra_text, 1, 16);
|
|
extra_text = "of the game, weapons and monsters.";
|
|
MNU_MeasureString(extra_text, &w, &h);
|
|
MNU_DrawString(TEXT_XCENTER(w), 150, extra_text, 1, 16);
|
|
extra_text = "See the ordering information.";
|
|
MNU_MeasureString(extra_text, &w, &h);
|
|
MNU_DrawString(TEXT_XCENTER(w), 160, extra_text, 1, 16);
|
|
SET(item->flags, mf_disabled);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_SaveGameCheck(MenuItem *item)
|
|
{
|
|
extern SWBOOL InMenuLevel;
|
|
extern SWBOOL DemoMode;
|
|
|
|
if (0) // JBF: Until we fix the symbol table dilemma, saving is off limits
|
|
{
|
|
SET(item->flags, mf_disabled);
|
|
return TRUE;
|
|
}
|
|
|
|
if (CommEnabled || numplayers > 1 || DemoMode)
|
|
{
|
|
SET(item->flags, mf_disabled);
|
|
return TRUE;
|
|
}
|
|
|
|
if (InMenuLevel)
|
|
SET(item->flags, mf_disabled);
|
|
else
|
|
{
|
|
if (TEST(Player[myconnectindex].Flags, PF_DEAD))
|
|
SET(item->flags, mf_disabled);
|
|
else
|
|
RESET(item->flags, mf_disabled);
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_TenCheck(MenuItem *item)
|
|
{
|
|
if (CommEnabled || numplayers > 1)
|
|
{
|
|
SET(item->flags, mf_disabled);
|
|
return TRUE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_LoadGameCheck(MenuItem *item)
|
|
{
|
|
|
|
if (0) // JBF: Until we fix the symbol table dilemma, loading is off limits
|
|
{
|
|
SET(item->flags, mf_disabled);
|
|
return TRUE;
|
|
}
|
|
|
|
if (CommEnabled || numplayers > 1)
|
|
{
|
|
SET(item->flags, mf_disabled);
|
|
return TRUE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_StatCheck(MenuItem *item)
|
|
{
|
|
if (CommEnabled || numplayers > 1)
|
|
{
|
|
SET(item->flags, mf_disabled);
|
|
return TRUE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_HurtTeammateCheck(MenuItem *item)
|
|
{
|
|
switch (gs.NetGameType+1)
|
|
{
|
|
// deathmatch and deathmatch no respawn
|
|
case MULTI_GAME_COMMBAT:
|
|
case MULTI_GAME_COMMBAT_NO_RESPAWN:
|
|
if (gs.NetTeamPlay)
|
|
RESET(item->flags, mf_disabled);
|
|
else
|
|
SET(item->flags, mf_disabled);
|
|
break;
|
|
// co-op
|
|
case MULTI_GAME_COOPERATIVE:
|
|
RESET(item->flags, mf_disabled);
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_TeamPlayCheck(MenuItem *item)
|
|
{
|
|
switch (gs.NetGameType+1)
|
|
{
|
|
// co-op
|
|
case MULTI_GAME_COOPERATIVE:
|
|
SET(item->flags, mf_disabled);
|
|
break;
|
|
default:
|
|
RESET(item->flags, mf_disabled);
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_CoopPlayCheck(MenuItem *item)
|
|
{
|
|
switch (gs.NetGameType+1)
|
|
{
|
|
// co-op
|
|
case MULTI_GAME_COOPERATIVE:
|
|
SET(item->flags, mf_disabled);
|
|
break;
|
|
default:
|
|
RESET(item->flags, mf_disabled);
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_TeamPlayChange(void)
|
|
{
|
|
// if team play changes then do a pre process again
|
|
MNU_ItemPreProcess(currentmenu);
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_MouseCheck(MenuItem *item)
|
|
{
|
|
if (!CONTROL_MousePresent)
|
|
{
|
|
SET(item->flags, mf_disabled);
|
|
}
|
|
else
|
|
{
|
|
RESET(item->flags, mf_disabled);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_JoystickCheck(MenuItem *item)
|
|
{
|
|
if (!CONTROL_JoyPresent)
|
|
{
|
|
SET(item->flags, mf_disabled);
|
|
}
|
|
else
|
|
{
|
|
RESET(item->flags, mf_disabled);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// This is only called when Enter is pressed
|
|
static SWBOOL
|
|
MNU_TryMusicInit(void)
|
|
{
|
|
if (PlaySong(0, RedBookSong[Level], TRUE, FALSE))
|
|
{
|
|
if (currentmenu->cursor == 0)
|
|
MNU_MusicCheck(¤tmenu->items[currentmenu->cursor+1]);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_MusicCheck(MenuItem *item)
|
|
{
|
|
if (SW_SHAREWARE)
|
|
{
|
|
if (MusicDevice < 0 || !MusicInitialized)
|
|
{
|
|
SET(item->flags, mf_disabled);
|
|
}
|
|
else
|
|
{
|
|
RESET(item->flags, mf_disabled);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Redbook audio stuff
|
|
//JBF
|
|
//if (!cdvalid)
|
|
// {
|
|
// SET(item->flags, mf_disabled); // Just don't let CD Redbook ever be invalid!
|
|
// }
|
|
//else
|
|
{
|
|
RESET(item->flags, mf_disabled);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_FxCheck(MenuItem *item)
|
|
{
|
|
if (FXDevice < 0 || !FxInitialized)
|
|
{
|
|
SET(item->flags, mf_disabled);
|
|
}
|
|
else
|
|
{
|
|
RESET(item->flags, mf_disabled);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SWBOOL
|
|
MNU_MusicFxCheck(MenuItem *item)
|
|
{
|
|
if (FXDevice < 0 && MusicDevice < 0)
|
|
{
|
|
SET(item->flags, mf_disabled);
|
|
}
|
|
else
|
|
{
|
|
RESET(item->flags, mf_disabled);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Do a toggle button
|
|
////////////////////////////////////////////////
|
|
void
|
|
MNU_DoButton(MenuItem_p item, SWBOOL draw)
|
|
{
|
|
int x, y;
|
|
SWBOOL state;
|
|
int last_value;
|
|
short shade = MENU_SHADE_DEFAULT;
|
|
extern char LevelSong[];
|
|
char *extra_text = NULL;
|
|
PLAYERp pp = &Player[myconnectindex];
|
|
int button_x,zero=0;
|
|
int handle=0;
|
|
extern SWBOOL MusicInitialized,FxInitialized;
|
|
|
|
button_x = OPT_XSIDE;
|
|
|
|
x = item->x;
|
|
y = item->y;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
{
|
|
shade = MENU_SHADE_INACTIVE;
|
|
}
|
|
|
|
if (!draw)
|
|
{
|
|
switch (item->button)
|
|
{
|
|
case btn_nuke:
|
|
gs.NetNuke = state = buttonsettings[item->button];
|
|
break;
|
|
case btn_voxels:
|
|
gs.Voxels = state = buttonsettings[item->button];
|
|
break;
|
|
case btn_stats:
|
|
gs.Stats = state = buttonsettings[item->button];
|
|
break;
|
|
case btn_markers:
|
|
gs.NetSpawnMarkers = state = buttonsettings[item->button];
|
|
break;
|
|
case btn_teamplay:
|
|
gs.NetTeamPlay = state = buttonsettings[item->button];
|
|
break;
|
|
case btn_friendlyfire:
|
|
gs.NetHurtTeammate = state = buttonsettings[item->button];
|
|
break;
|
|
case btn_crosshair:
|
|
gs.Crosshair = state = buttonsettings[item->button];
|
|
break;
|
|
case btn_auto_aim:
|
|
last_value = gs.AutoAim;
|
|
gs.AutoAim = state = buttonsettings[item->button];
|
|
if (gs.AutoAim != last_value)
|
|
MenuButtonAutoAim = TRUE;
|
|
break;
|
|
case btn_messages:
|
|
gs.Messages = state = buttonsettings[item->button];
|
|
break;
|
|
case btn_auto_run:
|
|
last_value = gs.AutoRun;
|
|
gs.AutoRun = state = buttonsettings[item->button];
|
|
if (gs.AutoRun != last_value)
|
|
MenuButtonAutoRun = TRUE;
|
|
break;
|
|
case btn_mouse_aim:
|
|
last_value = gs.MouseAimingType;
|
|
gs.MouseAimingType = state = buttonsettings[item->button];
|
|
if (gs.MouseAimingType != last_value)
|
|
{
|
|
//RESET(pp->Flags, PF_MOUSE_AIMING_ON);
|
|
//gs.MouseAimingOn = FALSE;
|
|
}
|
|
//extra_text = gs.MouseAimingType ? "Momentary" : "Toggle";
|
|
break;
|
|
case btn_mouse_invert:
|
|
gs.MouseInvert = state = buttonsettings[item->button];
|
|
break;
|
|
// case btn_bobbing:
|
|
// gs.Bobbing = state = buttonsettings[item->button];
|
|
// break;
|
|
case btn_sound:
|
|
|
|
if (!FxInitialized)
|
|
break;
|
|
|
|
last_value = gs.FxOn;
|
|
gs.FxOn = state = buttonsettings[item->button];
|
|
if (gs.FxOn != last_value)
|
|
{
|
|
if (!gs.FxOn)
|
|
StopFX();
|
|
}
|
|
break;
|
|
case btn_music:
|
|
last_value = gs.MusicOn;
|
|
gs.MusicOn = state = buttonsettings[item->button];
|
|
if (gs.MusicOn != last_value)
|
|
{
|
|
SWBOOL bak;
|
|
|
|
if (gs.MusicOn)
|
|
{
|
|
bak = DemoMode;
|
|
PlaySong(LevelSong, RedBookSong[Level], TRUE, TRUE);
|
|
DemoMode = bak;
|
|
}
|
|
else
|
|
{
|
|
bak = DemoMode;
|
|
StopSong();
|
|
DemoMode = bak;
|
|
|
|
if (SW_SHAREWARE)
|
|
{
|
|
handle = PlaySound(DIGI_NOLIKEMUSIC,&zero,&zero,&zero,v3df_none);
|
|
|
|
if (handle > FX_Ok)
|
|
while (FX_SoundActive(handle))
|
|
handleevents();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case btn_talking:
|
|
gs.Talking = state = buttonsettings[item->button];
|
|
break;
|
|
case btn_playcd:
|
|
last_value = gs.PlayCD;
|
|
gs.PlayCD = state = buttonsettings[item->button];
|
|
break;
|
|
case btn_ambience:
|
|
last_value = gs.Ambient;
|
|
gs.Ambient = state = buttonsettings[item->button];
|
|
if (gs.Ambient != last_value)
|
|
{
|
|
if (!InMenuLevel)
|
|
{
|
|
if (gs.Ambient)
|
|
StartAmbientSound();
|
|
else
|
|
StopAmbientSound();
|
|
}
|
|
}
|
|
break;
|
|
case btn_flipstereo:
|
|
last_value = gs.FlipStereo;
|
|
gs.FlipStereo = state = buttonsettings[item->button];
|
|
if (gs.FlipStereo != last_value)
|
|
FlipStereo();
|
|
break;
|
|
case btn_shadows:
|
|
gs.Shadows = state = buttonsettings[item->button];
|
|
break;
|
|
|
|
case btn_parental:
|
|
if (gs.Password[0] != '\0' && gs.ParentalLock == TRUE)
|
|
{
|
|
if (passwordvalid)
|
|
{
|
|
state = buttonsettings[btn_parental] = gs.ParentalLock = FALSE;
|
|
if (!InMenuLevel)
|
|
JS_ToggleLockouts();
|
|
}
|
|
else
|
|
{
|
|
state = buttonsettings[btn_parental] = gs.ParentalLock = TRUE;
|
|
MenuInputMode = TRUE;
|
|
memset(MessageInputString, '\0', sizeof(MessageInputString));
|
|
KB_ClearKeysDown();
|
|
KB_FlushKeyboardQueue();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gs.ParentalLock = state = buttonsettings[item->button];
|
|
if (!InMenuLevel)
|
|
JS_ToggleLockouts();
|
|
}
|
|
break;
|
|
|
|
case btn_videofs:
|
|
{
|
|
int lastx, lasty, lastbpp, newoffset, i;
|
|
|
|
state = buttonsettings[btn_videofs];
|
|
|
|
lastx = validresolutions[slidersettings[sldr_videores]].xdim;
|
|
lasty = validresolutions[slidersettings[sldr_videores]].ydim;
|
|
lastbpp = validbpps[slidersettings[sldr_videobpp]];
|
|
UpdateValidModes(lastbpp, buttonsettings[btn_videofs]);
|
|
|
|
// check if the last bpp is still a valid choice
|
|
for (i=0; i<numvalidbpps; i++)
|
|
if (validbpps[i] == lastbpp) break;
|
|
if (i == numvalidbpps)
|
|
{
|
|
// it wasn't
|
|
slidersettings[sldr_videobpp] = 0;
|
|
lastbpp = validbpps[0];
|
|
UpdateValidModes(lastbpp, buttonsettings[btn_videofs]);
|
|
}
|
|
else
|
|
{
|
|
slidersettings[sldr_videobpp] = i;
|
|
}
|
|
|
|
// find the nearest resolution to the one last selected
|
|
newoffset = 0;
|
|
for (i=0; i<numvalidresolutions; i++)
|
|
{
|
|
if (abs(lastx * lasty - validresolutions[i].xdim * validresolutions[i].ydim) <
|
|
abs(lastx * lasty - validresolutions[newoffset].xdim * validresolutions[newoffset].ydim))
|
|
newoffset = i;
|
|
}
|
|
slidersettings[sldr_videores] = newoffset;
|
|
} break;
|
|
|
|
default:
|
|
state = buttonsettings[item->button];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!draw)
|
|
return;
|
|
|
|
switch (item->button)
|
|
{
|
|
case btn_mouse_aim:
|
|
extra_text = gs.MouseAimingType ? "Momentary" : "Toggle";
|
|
break;
|
|
default: break;
|
|
}
|
|
|
|
|
|
state = buttonsettings[item->button];
|
|
|
|
// Draw the button
|
|
if (item->text)
|
|
{
|
|
if (state)
|
|
{
|
|
// set
|
|
rotatesprite(button_x << 16, y << 16, MZ, 0, pic_radiobuttn2, shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
}
|
|
else
|
|
{
|
|
// not set
|
|
rotatesprite(button_x << 16, y << 16, MZ, 0, pic_radiobuttn1, shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
}
|
|
|
|
MenuTextShade = shade;
|
|
MNU_DrawString(x, y, item->text, MenuTextShade, 16);
|
|
|
|
if (extra_text)
|
|
MNU_DrawString(OPT_XSIDE + tilesiz[pic_radiobuttn1].x + 6, y, extra_text, MenuTextShade, 16);
|
|
MenuTextShade = MENU_SHADE_DEFAULT;
|
|
}
|
|
else
|
|
{
|
|
if (state)
|
|
rotatesprite(x << 16, y << 16, MZ, 0, pic_radiobuttn2, 2, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
else
|
|
rotatesprite(x << 16, y << 16, MZ, 0, pic_radiobuttn1, 2, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
|
|
x += tilesiz[pic_radiobuttn1].x + 4;
|
|
|
|
// Draw the menu item text
|
|
rotatesprite(x << 16, y << 16, MZ, 0, item->pic, 2, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
}
|
|
|
|
}
|
|
|
|
//char *gametype[] = {"War [Respawn]","Cooperative","War [No Respawn]"};
|
|
char *gametype[] = {"WangBang (spawn)","WangBang (no spawn)","Cooperative"};
|
|
char *playercolors[] = {"Brown","Gray","Purple","Red","Yellow","Olive","Green","Blue"};
|
|
char *monsterskills[] = {"No Monsters","Easy","Normal","Hard","Insane!"};
|
|
|
|
void
|
|
MNU_DoSlider(short dir, MenuItem_p item, SWBOOL draw)
|
|
{
|
|
short offset, i, barwidth;
|
|
int x, y, knobx;
|
|
short shade = MENU_SHADE_DEFAULT;
|
|
char *extra_text=NULL;
|
|
char tmp_text[256];
|
|
|
|
memset(tmp_text,0,256);
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
{
|
|
shade = MENU_SHADE_INACTIVE;
|
|
dir = 0;
|
|
}
|
|
|
|
switch (item->slider)
|
|
{
|
|
case sldr_mouse:
|
|
barwidth = SLDR_MOUSESENSEMAX;
|
|
offset = slidersettings[sldr_mouse] += dir;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, SLDR_MOUSESENSEMAX-1);
|
|
|
|
slidersettings[sldr_mouse] = offset;
|
|
|
|
gs.MouseSpeed = offset * (MOUSE_SENS_MAX_VALUE/SLDR_MOUSESENSEMAX);
|
|
CONTROL_SetMouseSensitivity(gs.MouseSpeed);
|
|
break;
|
|
|
|
case sldr_sndfxvolume:
|
|
barwidth = SLDR_SNDFXVOLMAX;
|
|
offset = slidersettings[sldr_sndfxvolume] += dir;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, SLDR_SNDFXVOLMAX-1);
|
|
|
|
slidersettings[sldr_sndfxvolume] = offset;
|
|
gs.SoundVolume = FX_MIN + (offset * VOL_MUL);
|
|
FX_SetVolume(gs.SoundVolume);
|
|
break;
|
|
|
|
case sldr_musicvolume:
|
|
barwidth = SLDR_MUSICVOLMAX;
|
|
offset = slidersettings[sldr_musicvolume] += dir;
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, SLDR_MUSICVOLMAX-1);
|
|
|
|
slidersettings[sldr_musicvolume] = offset;
|
|
gs.MusicVolume = MUSIC_MIN + (offset * VOL_MUL);
|
|
SetSongVolume(gs.MusicVolume);
|
|
break;
|
|
|
|
case sldr_scrsize:
|
|
{
|
|
short bnum;
|
|
|
|
barwidth = SLDR_SCRSIZEMAX;
|
|
slidersettings[sldr_scrsize] = gs.BorderNum;
|
|
slidersettings[sldr_scrsize] -= dir;
|
|
offset = slidersettings[sldr_scrsize];
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
////DSPRINTF(ds,"BorderNum %d",gs.BorderNum);
|
|
//MONO_PRINT(ds);
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, SLDR_SCRSIZEMAX - 1);
|
|
|
|
bnum = offset;
|
|
|
|
offset = (SLDR_SCRSIZEMAX-1) - offset;
|
|
slidersettings[sldr_scrsize] = offset;
|
|
|
|
if (!BorderAdjust)
|
|
gs.BorderNum = bnum;
|
|
|
|
SetBorder(&Player[myconnectindex], bnum);
|
|
|
|
break;
|
|
}
|
|
|
|
case sldr_brightness:
|
|
barwidth = SLDR_BRIGHTNESSMAX;
|
|
offset = slidersettings[sldr_brightness] += dir;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, SLDR_BRIGHTNESSMAX - 1);
|
|
slidersettings[sldr_brightness] = offset;
|
|
|
|
if (gs.Brightness != offset)
|
|
{
|
|
gs.Brightness = offset;
|
|
COVERsetbrightness(gs.Brightness,&palette_data[0][0]);
|
|
}
|
|
break;
|
|
|
|
case sldr_bordertile:
|
|
barwidth = SLDR_BORDERTILEMAX;
|
|
offset = slidersettings[sldr_bordertile] += dir;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, SLDR_BORDERTILEMAX - 1);
|
|
slidersettings[sldr_bordertile] = offset;
|
|
|
|
if (gs.BorderTile != offset)
|
|
{
|
|
gs.BorderTile = offset;
|
|
|
|
SetRedrawScreen(&Player[myconnectindex]);
|
|
}
|
|
break;
|
|
|
|
case sldr_gametype:
|
|
barwidth = SLDR_GAMETYPEMAX;
|
|
offset = slidersettings[sldr_gametype] += dir;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, SLDR_GAMETYPEMAX - 1);
|
|
slidersettings[sldr_gametype] = offset;
|
|
|
|
extra_text = gametype[offset];
|
|
MNU_DrawString(OPT_XSIDE, item->y, extra_text, 1, 16);
|
|
gs.NetGameType = offset;
|
|
// friendly fire menu
|
|
MNU_ItemPreProcess(currentmenu);
|
|
break;
|
|
|
|
case sldr_netlevel:
|
|
barwidth = SLDR_NETLEVELMAX;
|
|
offset = slidersettings[sldr_netlevel] += dir;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, SLDR_NETLEVELMAX - 1);
|
|
slidersettings[sldr_netlevel] = offset;
|
|
|
|
// Show the currently selected level on next line
|
|
//extra_text = MNU_LevelName[offset];
|
|
//MNU_DrawString(OPT_XS, item->y+10, extra_text, 1, 16);
|
|
sprintf(tmp_text, "L%02d: %s", offset+1, LevelInfo[offset+1].Description);
|
|
MNU_DrawString(OPT_XS, item->y+10, tmp_text, 1, 16);
|
|
gs.NetLevel = offset;
|
|
break;
|
|
|
|
case sldr_monsters:
|
|
barwidth = SLDR_MONSTERSMAX;
|
|
offset = slidersettings[sldr_monsters] += dir;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, SLDR_MONSTERSMAX - 1);
|
|
slidersettings[sldr_monsters] = offset;
|
|
|
|
extra_text = monsterskills[offset];
|
|
MNU_DrawString(OPT_XSIDE+54, item->y, extra_text, 1, 16);
|
|
gs.NetMonsters = offset;
|
|
break;
|
|
|
|
case sldr_killlimit:
|
|
barwidth = SLDR_KILLLIMITMAX;
|
|
offset = slidersettings[sldr_killlimit] += dir;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, SLDR_KILLLIMITMAX - 1);
|
|
slidersettings[sldr_killlimit] = offset;
|
|
|
|
if (offset == 0)
|
|
{
|
|
strcpy(tmp_text,"Infinite\n");
|
|
}
|
|
else
|
|
{
|
|
sprintf(tmp_text,"%d",offset*10);
|
|
//itoa(offset*10,tmp_text,10);
|
|
}
|
|
MNU_DrawString(OPT_XSIDE+101, item->y, tmp_text, 1, 16);
|
|
gs.NetKillLimit = offset;
|
|
break;
|
|
|
|
case sldr_timelimit:
|
|
barwidth = SLDR_TIMELIMITMAX;
|
|
offset = slidersettings[sldr_timelimit] += dir;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, SLDR_TIMELIMITMAX - 1);
|
|
slidersettings[sldr_timelimit] = offset;
|
|
|
|
if (offset == 0)
|
|
{
|
|
strcpy(tmp_text,"Infinite\n");
|
|
}
|
|
else
|
|
{
|
|
sprintf(tmp_text,"%d Minutes\n",TimeLimitTable[offset]);
|
|
}
|
|
|
|
MNU_DrawString(OPT_XSIDE+86, item->y, tmp_text, 1, 16);
|
|
gs.NetTimeLimit = offset;
|
|
break;
|
|
|
|
case sldr_playercolor:
|
|
barwidth = SLDR_PLAYERCOLORMAX;
|
|
offset = slidersettings[sldr_playercolor] += dir;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, SLDR_PLAYERCOLORMAX - 1);
|
|
slidersettings[sldr_playercolor] = offset;
|
|
|
|
extra_text = playercolors[offset];
|
|
MNU_DrawString(OPT_XSIDE+78, item->y, extra_text, 1, PALETTE_PLAYER0+offset);
|
|
gs.NetColor = offset;
|
|
break;
|
|
|
|
case sldr_videores:
|
|
{
|
|
offset = max(0,min(slidersettings[sldr_videores] + dir, numvalidresolutions-1));
|
|
barwidth = numvalidresolutions;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
slidersettings[sldr_videores] = offset;
|
|
|
|
sprintf(tmp_text, "%dx%d", validresolutions[offset].xdim, validresolutions[offset].ydim);
|
|
MNU_DrawString(OPT_XSIDE, item->y+OPT_YINC, tmp_text, 1, 16);
|
|
} break;
|
|
|
|
case sldr_videobpp:
|
|
{
|
|
offset = max(0,min(slidersettings[sldr_videobpp] + dir, numvalidbpps-1));
|
|
barwidth = numvalidbpps;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
if (slidersettings[sldr_videobpp] != offset)
|
|
{
|
|
int lastx, lasty, newoffset, i;
|
|
|
|
slidersettings[sldr_videobpp] = offset;
|
|
|
|
// find the nearest resolution to the one last selected
|
|
lastx = validresolutions[slidersettings[sldr_videores]].xdim;
|
|
lasty = validresolutions[slidersettings[sldr_videores]].ydim;
|
|
UpdateValidModes(validbpps[offset], buttonsettings[btn_videofs]);
|
|
newoffset = 0;
|
|
for (i=0; i<numvalidresolutions; i++)
|
|
{
|
|
if (abs(lastx * lasty - validresolutions[i].xdim * validresolutions[i].ydim) <
|
|
abs(lastx * lasty - validresolutions[newoffset].xdim * validresolutions[newoffset].ydim))
|
|
newoffset = i;
|
|
}
|
|
slidersettings[sldr_videores] = newoffset;
|
|
}
|
|
|
|
sprintf(tmp_text, "%d bpp", validbpps[offset]);
|
|
MNU_DrawString(OPT_XSIDE+tilesiz[pic_slidelend].x+tilesiz[pic_sliderend].x+(barwidth+1)*tilesiz[pic_slidebar].x, item->y, tmp_text, 1, 16);
|
|
} break;
|
|
|
|
case sldr_mousescalex:
|
|
case sldr_mousescaley:
|
|
barwidth = 8+1+8;
|
|
offset = slidersettings[item->slider] + dir;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, barwidth-1);
|
|
|
|
if (slidersettings[item->slider] != offset)
|
|
{
|
|
slidersettings[item->slider] = offset;
|
|
MouseAnalogScale[item->slider - sldr_mousescalex] = offset<<13;
|
|
CONTROL_SetAnalogAxisScale(item->slider - sldr_mousescalex, offset<<13, controldevice_mouse);
|
|
}
|
|
|
|
sprintf(tmp_text, "%.2f", (float)(slidersettings[item->slider]<<13) / 65535.f);
|
|
MNU_DrawSmallString(OPT_XSIDE+tilesiz[pic_slidelend].x+tilesiz[pic_sliderend].x+(MAX_SLDR_WIDTH+1)*tilesiz[pic_slidebar].x, item->y+4, tmp_text, 1, 16);
|
|
break;
|
|
|
|
case sldr_joyaxisscale:
|
|
barwidth = 8+1+8;
|
|
offset = slidersettings[item->slider] + dir;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, barwidth-1);
|
|
|
|
if (slidersettings[item->slider] != offset)
|
|
{
|
|
slidersettings[item->slider] = offset;
|
|
JoystickAnalogScale[JoystickAxisPage] = offset<<13;
|
|
CONTROL_SetAnalogAxisScale(JoystickAxisPage, offset<<13, controldevice_joystick);
|
|
}
|
|
|
|
sprintf(tmp_text, "%.2f", (float)(slidersettings[item->slider]<<13) / 65535.f);
|
|
MNU_DrawSmallString(OPT_XSIDE+tilesiz[pic_slidelend].x+tilesiz[pic_sliderend].x+(MAX_SLDR_WIDTH+1)*tilesiz[pic_slidebar].x, item->y+4, tmp_text, 1, 16);
|
|
break;
|
|
|
|
case sldr_joyaxisanalog:
|
|
{
|
|
const char *p;
|
|
|
|
barwidth = MNU_ControlAxisOffset(analog_maxtype);
|
|
offset = slidersettings[item->slider] + dir;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, barwidth-1);
|
|
|
|
if (slidersettings[item->slider] != offset)
|
|
{
|
|
slidersettings[item->slider] = offset;
|
|
JoystickAnalogAxes[JoystickAxisPage] = MNU_ControlAxisNum(offset);
|
|
CONTROL_MapAnalogAxis(JoystickAxisPage, MNU_ControlAxisNum(offset), controldevice_joystick);
|
|
}
|
|
|
|
p = CONFIG_AnalogNumToName(MNU_ControlAxisNum(offset));
|
|
while (*p != 0 && *p != '_') p++;
|
|
if (*p == '_') p++;
|
|
MNU_DrawSmallString(OPT_XSIDE+tilesiz[pic_slidelend].x+tilesiz[pic_sliderend].x+(barwidth+1)*tilesiz[pic_slidebar].x, item->y+4, p, 1, 16);
|
|
}
|
|
break;
|
|
|
|
case sldr_joyaxisdead:
|
|
case sldr_joyaxissatur:
|
|
barwidth = (32768>>10)+1;
|
|
offset = slidersettings[item->slider] + dir;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
break;
|
|
|
|
offset = max(offset, 0);
|
|
offset = min(offset, barwidth-1);
|
|
|
|
if (slidersettings[item->slider] != offset)
|
|
{
|
|
slidersettings[item->slider] = offset;
|
|
if (item->slider == sldr_joyaxisdead)
|
|
{
|
|
JoystickAnalogDead[JoystickAxisPage] = min((offset<<10), 32767);
|
|
CONTROL_SetJoyAxisDead(JoystickAxisPage, JoystickAnalogDead[JoystickAxisPage]);
|
|
}
|
|
else
|
|
{
|
|
JoystickAnalogSaturate[JoystickAxisPage] = min((offset<<10), 32767);
|
|
CONTROL_SetJoyAxisSaturate(JoystickAxisPage, JoystickAnalogSaturate[JoystickAxisPage]);
|
|
}
|
|
}
|
|
|
|
sprintf(tmp_text, "%.2f%%", (float)(slidersettings[item->slider]<<10) / 32767.f);
|
|
MNU_DrawSmallString(OPT_XSIDE+tilesiz[pic_slidelend].x+tilesiz[pic_sliderend].x+(MAX_SLDR_WIDTH+1)*tilesiz[pic_slidebar].x, item->y+4, tmp_text, 1, 16);
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
|
|
if (!draw)
|
|
return;
|
|
|
|
// Now draw it
|
|
item++;
|
|
x = item->x;
|
|
y = item->y;
|
|
|
|
// Draw the left end cap of the bar
|
|
rotatesprite(x << 16, y << 16, MZ, 0, pic_slidelend, shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
|
|
x += tilesiz[pic_slidelend].x;
|
|
knobx = x;
|
|
|
|
// Draw the in between sections
|
|
for (i = 0; i < min(barwidth,MAX_SLDR_WIDTH); i++)
|
|
{
|
|
rotatesprite(x << 16, y << 16, MZ, 0, pic_slidebar, shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
x += tilesiz[pic_slidebar].x;
|
|
}
|
|
|
|
// Draw the right end cap
|
|
rotatesprite(x << 16, y << 16, MZ, 0, pic_sliderend, shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
|
|
// Draw the knob, compressing the X coordinate if the bar is too wide
|
|
if (barwidth > MAX_SLDR_WIDTH)
|
|
{
|
|
knobx += offset * (MAX_SLDR_WIDTH*tilesiz[pic_slidebar].x-tilesiz[pic_sliderknob].x) / (barwidth-1);
|
|
}
|
|
else
|
|
{
|
|
knobx += tilesiz[pic_slidebar].x * offset;
|
|
}
|
|
rotatesprite(knobx << 16, (y + 2) << 16, MZ, 0, pic_sliderknob, shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Start up menu array
|
|
////////////////////////////////////////////////
|
|
static void
|
|
MNU_SetupMenu(void)
|
|
{
|
|
MenuGroup *rootmenu;
|
|
|
|
static MenuGroup *rootmenulist[] =
|
|
{
|
|
&maingroup,
|
|
&SaveGameGroup,
|
|
&LoadGameGroup,
|
|
&soundgroup,
|
|
&optiongroup,
|
|
&quickloadgroup,
|
|
&quitgroup,
|
|
&ordergroup,
|
|
&episodegroup,
|
|
};
|
|
|
|
rootmenu = rootmenulist[ControlPanelType];
|
|
ASSERT(ControlPanelType < ct_max);
|
|
|
|
menuarrayptr = 0;
|
|
menuarray[0] = currentmenu = rootmenu;
|
|
if (ControlPanelType == ct_mainmenu)
|
|
|
|
mnu_input_buffered.button0 = mnu_input_buffered.button1 = FALSE;
|
|
mnu_input_buffered.dir = dir_None;
|
|
order_input_buffered.button0 = order_input_buffered.button1 = FALSE;
|
|
order_input_buffered.dir = dir_None;
|
|
ResetKeys();
|
|
|
|
// custom cust_callback starts out as null
|
|
cust_callback = NULL;
|
|
|
|
// for QuitCustom and QuickLoadCustom
|
|
if (currentmenu->items == NULL)
|
|
{
|
|
if (currentmenu->draw_custom)
|
|
currentmenu->draw_custom(uc_setup, NULL);
|
|
}
|
|
|
|
if (ControlPanelType == ct_mainmenu)
|
|
currentmenu->cursor = 0;
|
|
|
|
// disable any items necessary
|
|
MNU_ItemPreProcess(currentmenu);
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Draw an item
|
|
////////////////////////////////////////////////
|
|
static void
|
|
MNU_ClearFlags(MenuGroup *node)
|
|
{
|
|
MenuItem *i;
|
|
|
|
if (!node->items)
|
|
return;
|
|
|
|
for (i = node->items; i->type != mt_none; i++)
|
|
{
|
|
i->flags &= ~MenuSelectFlags;
|
|
if (i->child)
|
|
MNU_ClearFlags((MenuGroup *) i->child);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Pop a group off the menu stack
|
|
////////////////////////////////////////////////
|
|
static void
|
|
MNU_PopGroup(void)
|
|
{
|
|
if (!menuarrayptr)
|
|
return;
|
|
|
|
currentmenu = menuarray[--menuarrayptr];
|
|
|
|
SetFragBar(Player + myconnectindex);
|
|
//PanelRefresh(Player + myconnectindex);
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Push a group on to the menu stack
|
|
////////////////////////////////////////////////
|
|
static void
|
|
MNU_PushGroup(MenuGroup *node)
|
|
{
|
|
if (menuarrayptr == MaxLayers - 1)
|
|
return;
|
|
|
|
currentmenu = menuarray[++menuarrayptr] = node;
|
|
|
|
SetFragBar(Player + myconnectindex);
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Setup a new menu subgroup
|
|
////////////////////////////////////////////////
|
|
static void
|
|
MNU_SetupGroup(void)
|
|
{
|
|
MNU_SelectItem(currentmenu, currentmenu->cursor, FALSE);
|
|
MNU_DrawMenu();
|
|
}
|
|
|
|
static void
|
|
MNU_ItemPreProcess(MenuGroup *group)
|
|
{
|
|
MenuItem *item;
|
|
|
|
if (!group->items)
|
|
return;
|
|
|
|
// process all items when going down a level
|
|
// to see if anything is disabled
|
|
for (item = group->items; item->type != mt_none; item++)
|
|
{
|
|
if (item->preprocess)
|
|
item->preprocess(item);
|
|
}
|
|
}
|
|
|
|
void
|
|
MNU_ItemPostProcess(MenuGroup *group)
|
|
{
|
|
MenuItem *item;
|
|
int zero = 0;
|
|
|
|
if (!group->items)
|
|
return;
|
|
|
|
item = ¤tmenu->items[currentmenu->cursor];
|
|
|
|
if (item->postprocess)
|
|
{
|
|
item->postprocess(item);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Go to next menu subgroup
|
|
////////////////////////////////////////////////
|
|
static void
|
|
MNU_DownLevel(MenuGroup *group)
|
|
{
|
|
|
|
if (!group)
|
|
{
|
|
TerminateGame();
|
|
printf("MNU_DownLevel() - NULL card\n");
|
|
exit(0);
|
|
}
|
|
|
|
MNU_PushGroup(group);
|
|
|
|
if (group->items == NULL)
|
|
{
|
|
if (group->draw_custom && group->draw_custom(uc_setup, NULL))
|
|
MNU_PopGroup();
|
|
}
|
|
|
|
MNU_ItemPreProcess(currentmenu);
|
|
|
|
MNU_SetupGroup();
|
|
|
|
SetRedrawScreen(&Player[myconnectindex]);
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Go to previous menu subgroup
|
|
////////////////////////////////////////////////
|
|
static void
|
|
MNU_UpLevel(void)
|
|
{
|
|
int zero = 0;
|
|
static int handle1=0;
|
|
// if run out of menus then EXIT
|
|
if (!menuarrayptr)
|
|
{
|
|
if (!FX_SoundActive(handle1))
|
|
handle1 = PlaySound(DIGI_STARCLINK,&zero,&zero,&zero,v3df_dontpan);
|
|
ExitMenus();
|
|
return;
|
|
}
|
|
|
|
if (currentmenu->items)
|
|
currentmenu->items[currentmenu->cursor].flags &= ~mf_selected;
|
|
MNU_PopGroup();
|
|
MNU_SetupGroup();
|
|
|
|
SetRedrawScreen(&Player[myconnectindex]);
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Do a menu item action
|
|
////////////////////////////////////////////////
|
|
static void
|
|
MNU_DoItem(void)
|
|
{
|
|
MenuItem *item;
|
|
|
|
item = ¤tmenu->items[currentmenu->cursor];
|
|
if (!item) return;
|
|
|
|
if (TEST(item->flags, mf_disabled))
|
|
{
|
|
// Try to process again
|
|
if (item->preprocess)
|
|
item->preprocess(item);
|
|
|
|
// Check once more
|
|
if (TEST(item->flags, mf_disabled))
|
|
return;
|
|
}
|
|
|
|
switch (item->type)
|
|
{
|
|
case mt_option:
|
|
if (item->custom != NULL)
|
|
item->custom();
|
|
break;
|
|
case mt_button:
|
|
MNU_PushItem(item, FALSE);
|
|
if (item->custom != NULL)
|
|
item->custom();
|
|
break;
|
|
case mt_layer:
|
|
if (item->custom != NULL)
|
|
item->custom();
|
|
MNU_DownLevel(item->child);
|
|
break;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Draw an item icon or cursor
|
|
////////////////////////////////////////////////
|
|
static void
|
|
MNU_DrawItemIcon(MenuItem *item)
|
|
{
|
|
//void BorderRefreshClip(PLAYERp pp, short x, short y, short x2, short y2);
|
|
int x = item->x, y = item->y;
|
|
int scale = MZ;
|
|
short w,h;
|
|
|
|
if (item->text)
|
|
{
|
|
scale /= 2;
|
|
x -= mulscale17(tilesiz[pic_yinyang].x,scale) + 2;
|
|
y += 4;
|
|
}
|
|
else
|
|
{
|
|
scale -= (1<<13);
|
|
x -= ((tilesiz[pic_yinyang].x) / 2) - 3;
|
|
y += 8;
|
|
}
|
|
|
|
rotatesprite(x << 16, y << 16,
|
|
scale, 0, pic_yinyang, item->shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
|
|
SetRedrawScreen(&Player[myconnectindex]);
|
|
//BorderRefreshClip(&Player[myconnectindex], x - 24, y - 24, x + 24, y + 24);
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Draw an item
|
|
////////////////////////////////////////////////
|
|
static void
|
|
MNU_DrawItem(MenuItem *item)
|
|
{
|
|
char *ptr;
|
|
short px, py;
|
|
|
|
MNU_ItemPostProcess(currentmenu); // Put this in so things can be drawn on item select
|
|
|
|
if (!item->pic)
|
|
return;
|
|
|
|
MNU_DrawItemIcon(item);
|
|
|
|
// if text string skip this part
|
|
if (item->text)
|
|
return;
|
|
|
|
if (TEST(item->flags, mf_selected) && !TEST(item->flags, mf_disabled))
|
|
{
|
|
// Highlighted
|
|
if (item->type != mt_button)
|
|
rotatesprite(item->x << 16, item->y << 16, MZ, 0, item->pic,
|
|
-30 + STD_RANDOM_RANGE(50), PALETTE_MENU_HIGHLIGHT, MenuDrawFlags,
|
|
0, 0, xdim - 1, ydim - 1);
|
|
else
|
|
rotatesprite((item->x + tilesiz[pic_radiobuttn1].x + 4) << 16, item->y << 16,
|
|
MZ, 0, item->pic, item->shade, PALETTE_MENU_HIGHLIGHT, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
}
|
|
else
|
|
{
|
|
// Un highlighted
|
|
if (item->type != mt_button)
|
|
rotatesprite(item->x << 16, item->y << 16, MZ, 0, item->pic,
|
|
item->shade, 0, MenuDrawFlags, 0, 319, 199, 0);
|
|
else
|
|
rotatesprite((item->x + tilesiz[pic_radiobuttn1].x + 4) << 16, item->y << 16,
|
|
MZ, 0, item->pic, item->shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Draw the menu contents
|
|
////////////////////////////////////////////////
|
|
static void
|
|
MNU_DrawMenuContents(void)
|
|
{
|
|
MenuItem *item;
|
|
short w,h;
|
|
|
|
ASSERT(currentmenu != NULL);
|
|
|
|
if (currentmenu->text)
|
|
{
|
|
// Draw the backdrop bar
|
|
rotatesprite(10 << 16, (currentmenu->y-3) << 16, MZ, 0, 2427,
|
|
currentmenu->shade, 0, MenuDrawFlags|ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1);
|
|
MNU_MeasureStringLarge(currentmenu->text, &w, &h);
|
|
MNU_DrawString(TEXT_XCENTER(w), currentmenu->y, currentmenu->text, 1, 16);
|
|
}
|
|
else if (currentmenu->titlepic)
|
|
{
|
|
rotatesprite(currentmenu->x << 16, currentmenu->y << 16, MZ, 0, currentmenu->titlepic,
|
|
currentmenu->shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
}
|
|
|
|
if (!currentmenu->items)
|
|
return;
|
|
|
|
for (item = currentmenu->items; item->type != mt_none; item++)
|
|
{
|
|
if (item->pic)
|
|
{
|
|
if (item->type == mt_button)
|
|
{
|
|
// all drawing done here also
|
|
MNU_DoButton(item, TRUE);
|
|
}
|
|
else
|
|
{
|
|
if (item->text)
|
|
{
|
|
if (TEST(item->flags, mf_disabled))
|
|
MenuTextShade = MENU_SHADE_INACTIVE;
|
|
MNU_DrawString(item->x, item->y, item->text, MenuTextShade, 16);
|
|
MenuTextShade = MENU_SHADE_DEFAULT;
|
|
}
|
|
else
|
|
{
|
|
rotatesprite(item->x << 16, item->y << 16, MZ, 0, item->pic,
|
|
item->shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Is there a slider attached to this item? Draw it.
|
|
if (item->type == mt_slider)
|
|
MNU_DoSlider(0, item, TRUE);
|
|
}
|
|
|
|
MNU_SelectItem(currentmenu, currentmenu->cursor, TRUE);
|
|
|
|
if (currentmenu->draw_custom)
|
|
currentmenu->draw_custom(uc_touchup, NULL);
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Draw the menu
|
|
////////////////////////////////////////////////
|
|
void
|
|
MNU_DrawMenu(void)
|
|
{
|
|
if (cust_callback != NULL)
|
|
{
|
|
cust_callback(cust_callback_call, cust_callback_item);
|
|
return;
|
|
}
|
|
|
|
if (currentmenu->items || currentmenu->titlepic)
|
|
{
|
|
MNU_DrawMenuContents();
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Select a menu item
|
|
////////////////////////////////////////////////
|
|
void
|
|
MNU_SelectItem(MenuGroup *group, short index, SWBOOL draw)
|
|
{
|
|
MenuItem *item;
|
|
|
|
if (index != group->cursor)
|
|
{
|
|
item = &group->items[group->cursor];
|
|
item->flags &= ~mf_selected;
|
|
if (draw)
|
|
MNU_DrawItem(item);
|
|
}
|
|
|
|
group->cursor = index;
|
|
item = &group->items[group->cursor];
|
|
item->flags |= mf_selected;
|
|
if (draw)
|
|
MNU_DrawItem(item);
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Toggle a menu radio button on/off
|
|
////////////////////////////////////////////////
|
|
static void
|
|
MNU_PushItem(MenuItem *item, SWBOOL draw)
|
|
{
|
|
if (item->type != mt_button)
|
|
return;
|
|
|
|
buttonsettings[item->button] ^= 1;
|
|
|
|
// if (draw)
|
|
MNU_DoButton(item, draw);
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Go to next item on menu
|
|
////////////////////////////////////////////////
|
|
static void
|
|
MNU_NextItem(void)
|
|
{
|
|
MenuTag type;
|
|
MenuFlags flag;
|
|
|
|
type = currentmenu->items[currentmenu->cursor + 1].type;
|
|
flag = currentmenu->items[currentmenu->cursor + 1].flags;
|
|
|
|
if (type == mt_none)
|
|
MNU_SelectItem(currentmenu, 0, FALSE);
|
|
else
|
|
MNU_SelectItem(currentmenu, currentmenu->cursor + 1, FALSE);
|
|
|
|
type = currentmenu->items[currentmenu->cursor].type;
|
|
flag = currentmenu->items[currentmenu->cursor].flags;
|
|
|
|
if (type == mt_inert || flag == mf_disabled)
|
|
MNU_NextItem();
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Go to previous item on menu
|
|
////////////////////////////////////////////////
|
|
static void
|
|
MNU_PrevItem(void)
|
|
{
|
|
MenuTag type;
|
|
MenuFlags flag;
|
|
|
|
if (!currentmenu->cursor)
|
|
while (currentmenu->items[++currentmenu->cursor].type != mt_none) ;
|
|
|
|
MNU_SelectItem(currentmenu, currentmenu->cursor - 1, FALSE);
|
|
|
|
type = currentmenu->items[currentmenu->cursor].type;
|
|
flag = currentmenu->items[currentmenu->cursor].flags;
|
|
if (type == mt_inert || flag == mf_disabled)
|
|
MNU_PrevItem();
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Find hotkey press on current menu, if any.
|
|
////////////////////////////////////////////////
|
|
static SWBOOL
|
|
MNU_DoHotkey(void)
|
|
{
|
|
MenuItem_p item;
|
|
short index;
|
|
|
|
if (!currentmenu->items) return FALSE;
|
|
|
|
index = 0;
|
|
for (item = currentmenu->items; item->type != mt_none; item++)
|
|
{
|
|
if (KEY_PRESSED(item->hotkey) && item->hotkey != 0)
|
|
{
|
|
MNU_SelectItem(currentmenu, index, FALSE);
|
|
return TRUE;
|
|
}
|
|
index++;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Setup Menus
|
|
////////////////////////////////////////////////
|
|
void
|
|
SetupMenu(void)
|
|
{
|
|
if (!UsingMenus && !ConPanel) // Doing this check for multiplay
|
|
// menus
|
|
{
|
|
MNU_SetupMenu();
|
|
|
|
// Clear the previous ESC key press
|
|
KEY_PRESSED(KEYSC_ESC) = FALSE;
|
|
UsingMenus = TRUE;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Setup the main menu
|
|
// This function will not loop if in modem
|
|
// or network game, otherwise it stops the
|
|
// game play until user finished in menus.
|
|
////////////////////////////////////////////////
|
|
#define MNU_SENSITIVITY 10 // The menu's mouse sensitivity, should be real low
|
|
|
|
void MNU_DoMenu(CTLType type, PLAYERp pp)
|
|
{
|
|
SWBOOL resetitem;
|
|
UCHAR key;
|
|
int zero = 0;
|
|
static int handle2 = 0;
|
|
static int limitmove=0;
|
|
static SWBOOL select_held=FALSE;
|
|
|
|
resetitem = TRUE;
|
|
|
|
if (cust_callback != NULL)
|
|
{
|
|
cust_callback(cust_callback_call, cust_callback_item);
|
|
return;
|
|
}
|
|
|
|
//ControlPanelType = type;
|
|
SetupMenu();
|
|
|
|
// Zero out the input structure
|
|
mnu_input.button0 = mnu_input.button1 = FALSE;
|
|
mnu_input.dir = dir_None;
|
|
|
|
// should not get input if you are editing a save game slot
|
|
if (totalclock < limitmove) limitmove = totalclock;
|
|
if (!MenuInputMode)
|
|
{
|
|
UserInput tst_input;
|
|
SWBOOL select_held = FALSE;
|
|
|
|
|
|
// Zero out the input structure
|
|
tst_input.button0 = tst_input.button1 = FALSE;
|
|
tst_input.dir = dir_None;
|
|
|
|
if (!select_held)
|
|
{
|
|
CONTROL_GetUserInput(&tst_input);
|
|
mnu_input_buffered.dir = tst_input.dir;
|
|
}
|
|
|
|
if (mnu_input_buffered.button0 || mnu_input_buffered.button1)
|
|
{
|
|
if (tst_input.button0 == mnu_input_buffered.button0 &&
|
|
tst_input.button1 == mnu_input_buffered.button1)
|
|
{
|
|
select_held = TRUE;
|
|
}
|
|
else if (totalclock - limitmove > 7)
|
|
{
|
|
mnu_input.button0 = mnu_input_buffered.button0;
|
|
mnu_input.button1 = mnu_input_buffered.button1;
|
|
|
|
mnu_input_buffered.button0 = tst_input.button0;
|
|
mnu_input_buffered.button1 = tst_input.button1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
select_held = FALSE;
|
|
mnu_input_buffered.button0 = tst_input.button0;
|
|
mnu_input_buffered.button1 = tst_input.button1;
|
|
}
|
|
|
|
if (totalclock - limitmove > 7 && !select_held)
|
|
{
|
|
mnu_input.dir = mnu_input_buffered.dir;
|
|
|
|
if (mnu_input.dir != dir_None)
|
|
if (!FX_SoundActive(handle2))
|
|
handle2 = PlaySound(DIGI_STAR,&zero,&zero,&zero,v3df_dontpan);
|
|
|
|
limitmove = totalclock;
|
|
mnu_input_buffered.dir = dir_None;
|
|
}
|
|
}
|
|
|
|
if (mnu_input.dir == dir_North)
|
|
{
|
|
MNU_PrevItem();
|
|
resetitem = TRUE;
|
|
}
|
|
else if (mnu_input.dir == dir_South)
|
|
{
|
|
MNU_NextItem();
|
|
resetitem = TRUE;
|
|
}
|
|
else if (mnu_input.button0)
|
|
{
|
|
static int handle5=0;
|
|
if (!FX_SoundActive(handle5))
|
|
handle5 = PlaySound(DIGI_SWORDSWOOSH,&zero,&zero,&zero,v3df_dontpan);
|
|
KB_ClearKeysDown();
|
|
MNU_DoItem();
|
|
resetitem = TRUE;
|
|
}
|
|
else if (mnu_input.dir == dir_West
|
|
&& currentmenu->items[currentmenu->cursor].type == mt_slider)
|
|
{
|
|
MNU_DoSlider(-1, ¤tmenu->items[currentmenu->cursor], FALSE);
|
|
resetitem = TRUE;
|
|
}
|
|
else if (mnu_input.dir == dir_East
|
|
&& currentmenu->items[currentmenu->cursor].type == mt_slider)
|
|
{
|
|
MNU_DoSlider(1, ¤tmenu->items[currentmenu->cursor], FALSE);
|
|
resetitem = TRUE;
|
|
}
|
|
else if (mnu_input.button1 || BUTTON(gamefunc_Show_Menu))
|
|
{
|
|
static int handle3=0;
|
|
CONTROL_ClearButton(gamefunc_Show_Menu);
|
|
if (!FX_SoundActive(handle3))
|
|
handle3 = PlaySound(DIGI_SWORDSWOOSH,&zero,&zero,&zero,v3df_dontpan);
|
|
MNU_UpLevel();
|
|
resetitem = TRUE;
|
|
}
|
|
else if (MNU_DoHotkey())
|
|
{
|
|
static int handle4=0;
|
|
if (!FX_SoundActive(handle4))
|
|
handle4 = PlaySound(DIGI_STAR,&zero,&zero,&zero,v3df_dontpan);
|
|
resetitem = TRUE;
|
|
mnu_input_buffered.button0 = mnu_input_buffered.button1 = FALSE;
|
|
}
|
|
else
|
|
resetitem = FALSE;
|
|
|
|
// !FRANK! I added this because the old custom was only called for drawing
|
|
// Needed one for drawing and moving.
|
|
if (currentmenu->move_custom)
|
|
currentmenu->move_custom(uc_setup, NULL);
|
|
|
|
if (resetitem)
|
|
{
|
|
KB_ClearKeysDown();
|
|
ResetKeys();
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Checks to see if we should be in menus
|
|
////////////////////////////////////////////////
|
|
void
|
|
MNU_CheckForMenus(void)
|
|
{
|
|
extern SWBOOL GamePaused;
|
|
|
|
if (UsingMenus)
|
|
{
|
|
//if (MoveSkip2 == 0)
|
|
MNU_DoMenu(ct_mainmenu, Player + myconnectindex);
|
|
}
|
|
else
|
|
{
|
|
if ((KEY_PRESSED(KEYSC_ESC) || BUTTON(gamefunc_Show_Menu)) && dimensionmode == 3 && !ConPanel)
|
|
{
|
|
KEY_PRESSED(KEYSC_ESC) = 0;
|
|
CONTROL_ClearButton(gamefunc_Show_Menu);
|
|
KB_ClearKeysDown();
|
|
// setup sliders/buttons
|
|
MNU_InitMenus();
|
|
MNU_DoMenu(ct_mainmenu, Player + myconnectindex);
|
|
pMenuClearTextLine(Player + myconnectindex);
|
|
PauseGame();
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
MNU_CheckForMenusAnyKey(void)
|
|
{
|
|
if (UsingMenus)
|
|
{
|
|
//if (MoveSkip2 == 0)
|
|
MNU_DoMenu(ct_mainmenu, Player + myconnectindex);
|
|
}
|
|
else
|
|
{
|
|
if (KeyPressed())
|
|
{
|
|
ResetKeys();
|
|
KB_ClearKeysDown();
|
|
MNU_InitMenus();
|
|
MNU_DoMenu(ct_mainmenu, Player + myconnectindex);
|
|
pMenuClearTextLine(Player + myconnectindex);
|
|
}
|
|
}
|
|
}
|
|
|
|
static int MNU_ControlAxisOffset(int num)
|
|
{
|
|
switch (num)
|
|
{
|
|
case analog_turning: return 0;
|
|
case analog_strafing: return 1;
|
|
case analog_moving: return 2;
|
|
case analog_lookingupanddown: return 3;
|
|
case analog_maxtype: return 4;
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
static int MNU_ControlAxisNum(int offset)
|
|
{
|
|
switch (offset)
|
|
{
|
|
case 0: return analog_turning;
|
|
case 1: return analog_strafing;
|
|
case 2: return analog_moving;
|
|
case 3: return analog_lookingupanddown;
|
|
default: return analog_turning;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Miscellaneous Routines
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef struct RGB_color_typ
|
|
{
|
|
unsigned char red;
|
|
unsigned char green;
|
|
unsigned char blue;
|
|
} RGB_color, *RGB_color_ptr;
|
|
|
|
#define PALETTE_MASK 0x3c6
|
|
#define PALETTE_READ 0x3c7
|
|
#define PALETTE_WRITE 0x3c8
|
|
#define PALETTE_DATA 0x3c9
|
|
|
|
unsigned char palette_data[256][3]; // Global palette array
|
|
|
|
// V E R T I C A L R E T R A C E V A R I A B L E S //////////////////////////////////////////
|
|
|
|
#define VGA_INPUT_STATUS_1 0x3DA // VGA status register 1, bit 3 is the vsync
|
|
// 1 = retrace in progress
|
|
// 0 = no retrace
|
|
#define VGA_VSYNC_MASK 0x08 // Masks off unwanted bits of status register.
|
|
|
|
|
|
// These routines are not used and should not be used. Would interfere with VESA palette
|
|
// cards.
|
|
#if 0
|
|
/////////////////////////////////////////////////
|
|
// WaitForVsync
|
|
// Waits for a vertical retrace to occur. If one is in progress, it waits for the next one.
|
|
/////////////////////////////////////////////////
|
|
void
|
|
WaitForVsync(void)
|
|
{
|
|
while (inp(VGA_INPUT_STATUS_1) & VGA_VSYNC_MASK) ;
|
|
// Retrace in progress, wait.
|
|
|
|
// Wait for vsync, and exit.
|
|
while (!inp(VGA_INPUT_STATUS_1) & VGA_VSYNC_MASK) ;
|
|
}
|
|
|
|
void
|
|
Get_Palette(unsigned char *pal)
|
|
{
|
|
int i;
|
|
|
|
outp(PALETTE_READ, 0);
|
|
for (i = 0; i < 768; i++)
|
|
pal[i] = inp(PALETTE_DATA);
|
|
}
|
|
void
|
|
Set_Palette(unsigned char *buff)
|
|
{
|
|
int i;
|
|
|
|
outp(PALETTE_WRITE, 0); // Resets color ram pointer to 1st
|
|
// color
|
|
for (i = 0; i < 768; i++)
|
|
outp(PALETTE_DATA, buff[i]);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/*
|
|
=================================================================================================
|
|
=
|
|
= FadeOut - Fades the palette to color at assigned click rate
|
|
=
|
|
=================================================================================================
|
|
*/
|
|
// Heres some temp timer junk for this routine. Replace it with game timer stuff later.
|
|
//unsigned int *clock = (unsigned int *)0x046C;
|
|
|
|
void
|
|
Fade_Timer(int clicks)
|
|
{
|
|
// unsigned int now;
|
|
int now;
|
|
|
|
now = totalclock;
|
|
|
|
while (abs(totalclock - now) < clicks) handleevents();
|
|
}
|
|
|
|
void
|
|
FadeIn(unsigned char startcolor, unsigned int clicks)
|
|
{
|
|
int i, palreg, usereg, tmpreg1 = 0, tmpreg2 = 0;
|
|
RGB_color color;
|
|
unsigned char temp_pal[768], *palette;
|
|
|
|
if (getrendermode() >= 3) return;
|
|
|
|
palette = &palette_data[0][0];
|
|
|
|
color.red = palette_data[startcolor][0];
|
|
color.green = palette_data[startcolor][1];
|
|
color.blue = palette_data[startcolor][2];
|
|
|
|
usereg = 0;
|
|
for (i = 0; i < 768; i++)
|
|
{
|
|
if (usereg == 0)
|
|
temp_pal[i] = color.red;
|
|
else if (usereg == 1)
|
|
temp_pal[i] = color.green;
|
|
else
|
|
temp_pal[i] = color.blue;
|
|
|
|
if (++usereg > 2)
|
|
usereg = 0;
|
|
}
|
|
|
|
for (i = 0; i < 32; i++)
|
|
{
|
|
for (palreg = 0; palreg < 768; palreg++)
|
|
{
|
|
tmpreg1 = (int)(temp_pal[palreg]) + 2;
|
|
tmpreg2 = (int)(temp_pal[palreg]) - 2;
|
|
if (tmpreg1 > 255)
|
|
tmpreg1 = 255;
|
|
if (tmpreg2 < 0)
|
|
tmpreg2 = 0;
|
|
|
|
if (temp_pal[palreg] < palette[palreg])
|
|
{
|
|
if ((temp_pal[palreg] = tmpreg1) > palette[palreg])
|
|
temp_pal[palreg] = palette[palreg];
|
|
}
|
|
else if (temp_pal[palreg] > palette[palreg])
|
|
if ((temp_pal[palreg] = tmpreg2) < palette[palreg])
|
|
temp_pal[palreg] = palette[palreg];
|
|
|
|
}
|
|
|
|
set_pal(&temp_pal[0]);
|
|
|
|
// Delay clicks
|
|
Fade_Timer(clicks);
|
|
}
|
|
}
|
|
|
|
void
|
|
FadeOut(unsigned char targetcolor, unsigned int clicks)
|
|
{
|
|
int i, palreg, usereg = 0, tmpreg1 = 0, tmpreg2 = 0;
|
|
RGB_color color;
|
|
unsigned char temp_pal[768];
|
|
|
|
if (getrendermode() >= 3) return;
|
|
|
|
color.red = palette_data[targetcolor][0];
|
|
color.green = palette_data[targetcolor][1];
|
|
color.blue = palette_data[targetcolor][2];
|
|
|
|
memcpy(&temp_pal[0], &palette_data[0][0], 768);
|
|
|
|
for (i = 0; i < 32; i++)
|
|
{
|
|
for (palreg = 0; palreg < 768; palreg++)
|
|
{
|
|
tmpreg1 = (int)(temp_pal[palreg]) + 2;
|
|
tmpreg2 = (int)(temp_pal[palreg]) - 2;
|
|
if (tmpreg1 > 255)
|
|
tmpreg1 = 255;
|
|
if (tmpreg2 < 0)
|
|
tmpreg2 = 0;
|
|
|
|
if (usereg == 0)
|
|
{
|
|
if (temp_pal[palreg] < color.red)
|
|
{
|
|
if ((temp_pal[palreg] = tmpreg1) > color.red)
|
|
temp_pal[palreg] = color.red;
|
|
}
|
|
else if (temp_pal[palreg] > color.red)
|
|
if ((temp_pal[palreg] = tmpreg2) < color.red)
|
|
temp_pal[palreg] = color.red;
|
|
}
|
|
else if (usereg == 1)
|
|
{
|
|
if (temp_pal[palreg] < color.green)
|
|
{
|
|
if ((temp_pal[palreg] = tmpreg1) > color.green)
|
|
temp_pal[palreg] = color.green;
|
|
}
|
|
else if (temp_pal[palreg] > color.green)
|
|
if ((temp_pal[palreg] = tmpreg2) < color.green)
|
|
temp_pal[palreg] = color.green;
|
|
}
|
|
else if (usereg == 2)
|
|
{
|
|
if (temp_pal[palreg] < color.blue)
|
|
{
|
|
if ((temp_pal[palreg] = tmpreg1) > color.blue)
|
|
temp_pal[palreg] = color.blue;
|
|
}
|
|
else if (temp_pal[palreg] > color.blue)
|
|
if ((temp_pal[palreg] = tmpreg2) < color.blue)
|
|
temp_pal[palreg] = color.blue;
|
|
}
|
|
|
|
if (++usereg > 2)
|
|
usereg = 0;
|
|
}
|
|
|
|
|
|
set_pal(&temp_pal[0]);
|
|
|
|
// Delay clicks
|
|
Fade_Timer(clicks);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
#define FADE_DAMAGE_FACTOR 3 // 100 health / 32 shade cycles = 3.125
|
|
|
|
// Fades from 100% to 62.5% somewhat quickly,
|
|
// then from 62.5% to 37.5% slowly,
|
|
// then from 37.5% to 0% quickly.
|
|
// This seems to capture the pain caused by enemy shots, plus the extreme
|
|
// fade caused by being blinded or intense pain.
|
|
// Perhaps the next step would be to apply a gentle smoothing to the
|
|
// intersections of these lines.
|
|
static int faderamp[32] =
|
|
{
|
|
// y=64-4x
|
|
252,240,224,208,192,176,
|
|
|
|
// y=44.8-(16/20)x
|
|
160,156,152,152,148,
|
|
144,140,136,136,132,
|
|
128,124,120,120,116,
|
|
112,108,104,104,100,
|
|
|
|
// y=128-4x
|
|
96,80,64,48,32,16
|
|
};
|
|
|
|
unsigned char ppalette[MAX_SW_PLAYERS_REG][768];
|
|
|
|
//////////////////////////////////////////
|
|
// Set the amount of redness for damage
|
|
// the player just took
|
|
//////////////////////////////////////////
|
|
void
|
|
SetFadeAmt(PLAYERp pp, short damage, unsigned char startcolor)
|
|
{
|
|
int palreg, usereg = 0, tmpreg1 = 0, tmpreg2 = 0;
|
|
short fadedamage=0;
|
|
RGB_color color;
|
|
|
|
//CON_ConMessage("SetAmt: fadeamt = %d, startcolor = %d, pp = %d",pp->FadeAmt,startcolor,pp->StartColor);
|
|
|
|
if (abs(pp->FadeAmt) > 0 && startcolor == pp->StartColor)
|
|
return;
|
|
|
|
// Don't ever over ride flash bomb
|
|
if (pp->StartColor == 1 && abs(pp->FadeAmt) > 0)
|
|
return;
|
|
|
|
// Reset the palette
|
|
if (pp == Player + screenpeek)
|
|
{
|
|
if (getrendermode() < 3)
|
|
COVERsetbrightness(gs.Brightness,&palette_data[0][0]);
|
|
else
|
|
setpalettefade(0,0,0,0);
|
|
if (pp->FadeAmt <= 0)
|
|
GetPaletteFromVESA(&ppalette[screenpeek][0]);
|
|
}
|
|
|
|
if (damage < -150 && damage > -1000) fadedamage = 150;
|
|
else if (damage < -1000) // Underwater
|
|
fadedamage = abs(damage+1000);
|
|
else
|
|
fadedamage = abs(damage);
|
|
|
|
if (damage >= -5 && damage < 0)
|
|
fadedamage += 10;
|
|
|
|
// Don't let red to TOO red
|
|
if (startcolor == COLOR_PAIN && fadedamage > 100) fadedamage = 100;
|
|
|
|
pp->FadeAmt = fadedamage / FADE_DAMAGE_FACTOR;
|
|
|
|
if (pp->FadeAmt <= 0)
|
|
{
|
|
pp->FadeAmt = 0;
|
|
return;
|
|
}
|
|
|
|
// It's a health item, just do a preset flash amount
|
|
if (damage > 0)
|
|
pp->FadeAmt = 3;
|
|
|
|
pp->StartColor = startcolor;
|
|
|
|
pp->FadeTics = 0;
|
|
|
|
// Set player's palette to current game palette
|
|
GetPaletteFromVESA(pp->temp_pal);
|
|
|
|
color.red = palette_data[pp->StartColor][0];
|
|
color.green = palette_data[pp->StartColor][1];
|
|
color.blue = palette_data[pp->StartColor][2];
|
|
|
|
for (palreg = 0; palreg < 768; palreg++)
|
|
{
|
|
tmpreg1 = (int)(pp->temp_pal[palreg]) + ((2 * pp->FadeAmt) + 4);
|
|
tmpreg2 = (int)(pp->temp_pal[palreg]) - ((2 * pp->FadeAmt) + 4);
|
|
if (tmpreg1 > 255)
|
|
tmpreg1 = 255;
|
|
if (tmpreg2 < 0)
|
|
tmpreg2 = 0;
|
|
|
|
if (usereg == 0)
|
|
{
|
|
if (pp->temp_pal[palreg] < color.red)
|
|
{
|
|
if ((pp->temp_pal[palreg] = tmpreg1) > color.red)
|
|
pp->temp_pal[palreg] = color.red;
|
|
}
|
|
else if (pp->temp_pal[palreg] > color.red)
|
|
if ((pp->temp_pal[palreg] = tmpreg2) < color.red)
|
|
pp->temp_pal[palreg] = color.red;
|
|
}
|
|
else if (usereg == 1)
|
|
{
|
|
if (pp->temp_pal[palreg] < color.green)
|
|
{
|
|
if ((pp->temp_pal[palreg] = tmpreg1) > color.green)
|
|
pp->temp_pal[palreg] = color.green;
|
|
}
|
|
else if (pp->temp_pal[palreg] > color.green)
|
|
if ((pp->temp_pal[palreg] = tmpreg2) < color.green)
|
|
pp->temp_pal[palreg] = color.green;
|
|
}
|
|
else if (usereg == 2)
|
|
{
|
|
if (pp->temp_pal[palreg] < color.blue)
|
|
{
|
|
if ((pp->temp_pal[palreg] = tmpreg1) > color.blue)
|
|
pp->temp_pal[palreg] = color.blue;
|
|
}
|
|
else if (pp->temp_pal[palreg] > color.blue)
|
|
if ((pp->temp_pal[palreg] = tmpreg2) < color.blue)
|
|
pp->temp_pal[palreg] = color.blue;
|
|
}
|
|
|
|
if (++usereg > 2)
|
|
usereg = 0;
|
|
}
|
|
|
|
// Do initial palette set
|
|
if (pp == Player + screenpeek)
|
|
{
|
|
if (getrendermode() < 3) set_pal(pp->temp_pal);
|
|
else setpalettefade(color.red, color.green, color.blue, faderamp[min(31,max(0,32-abs(pp->FadeAmt)))]);
|
|
if (damage < -1000)
|
|
pp->FadeAmt = 1000; // Don't call DoPaletteFlash for underwater stuff
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////
|
|
// Do the screen reddness based on damage
|
|
//////////////////////////////////////////
|
|
#define MAXFADETICS 5
|
|
void
|
|
DoPaletteFlash(PLAYERp pp)
|
|
{
|
|
int i, palreg, tmpreg1 = 0, tmpreg2 = 0;
|
|
unsigned char *pal_ptr = &ppalette[screenpeek][0];
|
|
|
|
|
|
if (pp->FadeAmt <= 1)
|
|
{
|
|
pp->FadeAmt = 0;
|
|
pp->StartColor = 0;
|
|
if (pp == Player + screenpeek)
|
|
{
|
|
if (getrendermode() < 3)
|
|
COVERsetbrightness(gs.Brightness,&palette_data[0][0]);
|
|
else
|
|
setpalettefade(0,0,0,0);
|
|
memcpy(pp->temp_pal, palette_data, sizeof(palette_data));
|
|
DoPlayerDivePalette(pp); // Check Dive again
|
|
DoPlayerNightVisionPalette(pp); // Check Night Vision again
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
pp->FadeTics += synctics; // Add this frame's tic amount to
|
|
// counter
|
|
|
|
if (pp->FadeTics >= MAXFADETICS)
|
|
{
|
|
while (pp->FadeTics >= MAXFADETICS)
|
|
{
|
|
pp->FadeTics -= MAXFADETICS;
|
|
|
|
pp->FadeAmt--; // Decrement FadeAmt till it gets to
|
|
// 0 again.
|
|
}
|
|
}
|
|
else
|
|
return; // Return if they were not >
|
|
// MAXFADETICS
|
|
|
|
if (pp->FadeAmt > 32)
|
|
return;
|
|
|
|
if (pp->FadeAmt <= 1)
|
|
{
|
|
pp->FadeAmt = 0;
|
|
pp->StartColor = 0;
|
|
if (pp == Player + screenpeek)
|
|
{
|
|
if (getrendermode() < 3)
|
|
COVERsetbrightness(gs.Brightness,&palette_data[0][0]);
|
|
else
|
|
setpalettefade(0,0,0,0);
|
|
memcpy(pp->temp_pal, palette_data, sizeof(palette_data));
|
|
DoPlayerDivePalette(pp); // Check Dive again
|
|
DoPlayerNightVisionPalette(pp); // Check Night Vision again
|
|
}
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
//CON_Message("gamavalues = %d, %d, %d",pp->temp_pal[pp->StartColor],pp->temp_pal[pp->StartColor+1],pp->temp_pal[pp->StartColor+2]);
|
|
for (palreg = 0; palreg < 768; palreg++)
|
|
{
|
|
tmpreg1 = (int)(pp->temp_pal[palreg]) + 2;
|
|
tmpreg2 = (int)(pp->temp_pal[palreg]) - 2;
|
|
if (tmpreg1 > 255)
|
|
tmpreg1 = 255;
|
|
if (tmpreg2 < 0)
|
|
tmpreg2 = 0;
|
|
|
|
if (pp->temp_pal[palreg] < pal_ptr[palreg])
|
|
{
|
|
if ((pp->temp_pal[palreg] = tmpreg1) > pal_ptr[palreg])
|
|
pp->temp_pal[palreg] = pal_ptr[palreg];
|
|
}
|
|
else if (pp->temp_pal[palreg] > pal_ptr[palreg])
|
|
if ((pp->temp_pal[palreg] = tmpreg2) < pal_ptr[palreg])
|
|
pp->temp_pal[palreg] = pal_ptr[palreg];
|
|
|
|
}
|
|
|
|
// Only hard set the palette if this is currently the player's view
|
|
if (pp == Player + screenpeek)
|
|
{
|
|
if (getrendermode() < 3) set_pal(pp->temp_pal);
|
|
else
|
|
{
|
|
setpalettefade(
|
|
palette_data[pp->StartColor][0],
|
|
palette_data[pp->StartColor][1],
|
|
palette_data[pp->StartColor][2],
|
|
faderamp[min(31,max(0,32-abs(pp->FadeAmt)))]
|
|
);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void ResetPalette(PLAYERp pp)
|
|
{
|
|
if (getrendermode() < 3)
|
|
COVERsetbrightness(gs.Brightness,&palette_data[0][0]);
|
|
else
|
|
setpalettefade(0,0,0,0);
|
|
memcpy(pp->temp_pal, palette_data, sizeof(palette_data));
|
|
//DoPlayerDivePalette(pp); // Check Dive again
|
|
//DoPlayerNightVisionPalette(pp); // Check Night Vision again
|
|
pp->FadeAmt = 0;
|
|
pp->StartColor = 0;
|
|
pp->FadeTics = 0;
|
|
}
|
|
|
|
// vim:ts=4:sw=4:enc=utf-8:
|
|
|
|
|