📄 mainmenus.cpp
字号:
//*******************************************************************
//
// MODULE : MainMenus.CPP
//
// PURPOSE : Blood 2 Menus
//
// CREATED : 9/25/1998
//
//*******************************************************************
#include <stdio.h>
#include "MainMenus.h"
#include "ClientRes.h"
#include "stack.h"
#include "dynarray.h"
#include "VKDefs.h"
#include "SharedDefs.h"
#include "ClientUtilities.h"
#include "LoadSave.h"
#include "BloodClientShell.h"
#include "MenuBase.h"
#include "MenuCommands.h"
#include "SoundTypes.h"
//*******************************************************************
// Global variable declarations
#define TRACK_BUFFER_SIZE 8
//*******************************************************************
//*******************************************************************
// Constructor
CMainMenus::CMainMenus()
{
m_bInit = DFALSE;
m_pClientDE = DNULL;
m_hSurfBackground = DNULL;
m_hSurfWork = DNULL;
m_hSurfSliderBar = DNULL;
m_hSurfSliderTab = DNULL;
m_pCurrentMenu = DNULL;
m_pTopLevelMenu = DNULL;
m_pSmallFont = DNULL;
m_pLargeFont = DNULL;
m_pTitleFont = DNULL;
m_hstrVersion = DNULL;
m_lpszBackground = DNULL;
m_bShiftState = DFALSE;
m_bInMessageBox = DFALSE;
m_bLowResolution = DFALSE;
m_bEnglish = DFALSE;
m_hAmbientSound = DNULL;
m_pLargeFadeFonts=DNULL;
m_nNumLargeFadeFonts=7;
m_hSurfUpArrow=DNULL;
m_hSurfDownArrow=DNULL;
m_nYesVKeyCode=VK_Y;
m_nNoVKeyCode=VK_N;
m_nMenuHeight=280;
m_titlePos.x=82;
m_titlePos.y=52;
m_optionsPos.x=180;
m_optionsPos.y=140;
}
//*******************************************************************
// Destructor
CMainMenus::~CMainMenus()
{
if ( m_bInit )
{
Term();
}
}
//*******************************************************************
// Initialization
DBOOL CMainMenus::Init(CClientDE* pClientDE)
{
if (!pClientDE)
{
return DFALSE;
}
m_pClientDE = pClientDE;
// Set the English flag
HSTRING hString=m_pClientDE->FormatString(IDS_BLOOD2_LANGUAGE);
if (hString && _mbsicmp((const unsigned char*)"english", (const unsigned char*)m_pClientDE->GetStringData(hString)) != 0)
{
m_bEnglish=DFALSE;
}
else
{
m_bEnglish=DTRUE;
}
m_pClientDE->FreeString(hString);
hString=DNULL;
// Load the virtual key codes for yes responses
hString=m_pClientDE->FormatString(IDS_MENU_VKEY_YES);
if (hString)
{
m_nYesVKeyCode=atoi(m_pClientDE->GetStringData(hString));
m_pClientDE->FreeString(hString);
hString=DNULL;
}
// Load the virtual key codes for no responses
hString=m_pClientDE->FormatString(IDS_MENU_VKEY_NO);
if (hString)
{
m_nNoVKeyCode=atoi(m_pClientDE->GetStringData(hString));
m_pClientDE->FreeString(hString);
hString=DNULL;
}
// Init the SharedResourceMgr class
m_sharedResourceMgr.Init(m_pClientDE);
// Determine if we need to set the low resolution flag
RMode currentMode;
if (m_pClientDE->GetRenderMode(¤tMode) == LT_OK)
{
if (currentMode.m_Width < 512 || currentMode.m_Height < 384)
{
m_bLowResolution=DTRUE;
m_nMenuHeight=180;
}
}
// Initialize the surfaces
if ( !InitSurfaces() )
{
return DFALSE;
}
// Initialize the fonts
InitFonts();
// Initialize the message box
m_messageBox.Create(m_pClientDE, "interface/mainmenus/dialog.pcx", GetSmallFont(), DNULL, DNULL);
m_messageBox.SetTextColor(SETRGB(220,190,170));
// Initialize the individual menus
m_mainMenu.Init (m_pClientDE, this, DNULL, MENU_ID_MAINMENU, m_nMenuHeight);
m_singlePlayerMenu.Init (m_pClientDE, this, &m_mainMenu, MENU_ID_SINGLEPLAYER, m_nMenuHeight);
m_bloodBathMenu.Init (m_pClientDE, this, &m_mainMenu, MENU_ID_BLOODBATH, m_nMenuHeight);
m_optionsMenu.Init (m_pClientDE, this, &m_mainMenu, MENU_ID_OPTIONS, m_nMenuHeight);
m_difficultyMenu.Init (m_pClientDE, this, &m_singlePlayerMenu,MENU_ID_DIFFICULTY, m_nMenuHeight);
m_customLevelMenu.Init (m_pClientDE, this, &m_singlePlayerMenu,MENU_ID_CUSTOM_LEVEL, m_nMenuHeight);
m_loadGameMenu.Init (m_pClientDE, this, &m_singlePlayerMenu,MENU_ID_LOAD_GAME, m_nMenuHeight);
m_saveGameMenu.Init (m_pClientDE, this, &m_singlePlayerMenu,MENU_ID_SAVE_GAME, m_nMenuHeight);
m_controlsMenu.Init (m_pClientDE, this, &m_optionsMenu, MENU_ID_CONTROLS, m_nMenuHeight);
m_soundMenu.Init (m_pClientDE, this, &m_optionsMenu, MENU_ID_SOUND, m_nMenuHeight);
m_displayMenu.Init (m_pClientDE, this, &m_optionsMenu, MENU_ID_DISPLAY, m_nMenuHeight);
m_characterMenu.Init (m_pClientDE, this, &m_bloodBathMenu, MENU_ID_CHARACTER, m_nMenuHeight);
m_characterFilesMenu.Init (m_pClientDE, this, &m_characterMenu, MENU_ID_CHARACTERFILES, 100);
m_characterSelectMenu.Init (m_pClientDE, this, &m_singlePlayerMenu,MENU_ID_CHARACTERSELECT,m_nMenuHeight);
m_mouseMenu.Init (m_pClientDE, this, &m_optionsMenu ,MENU_ID_MOUSE ,m_nMenuHeight);
m_keyboardMenu.Init (m_pClientDE, this, &m_optionsMenu ,MENU_ID_KEYBOARD ,m_nMenuHeight);
m_joystickMenu.Init (m_pClientDE, this, &m_optionsMenu ,MENU_ID_JOYSTICK ,m_nMenuHeight);
// Add each menu to the array
m_menuArray.SetSize(0);
m_menuArray.Add(&m_mainMenu);
m_menuArray.Add(&m_singlePlayerMenu);
m_menuArray.Add(&m_bloodBathMenu);
m_menuArray.Add(&m_optionsMenu);
m_menuArray.Add(&m_difficultyMenu);
m_menuArray.Add(&m_customLevelMenu);
m_menuArray.Add(&m_loadGameMenu);
m_menuArray.Add(&m_saveGameMenu);
m_menuArray.Add(&m_controlsMenu);
m_menuArray.Add(&m_soundMenu);
m_menuArray.Add(&m_characterMenu);
m_menuArray.Add(&m_characterFilesMenu);
m_menuArray.Add(&m_characterSelectMenu);
m_menuArray.Add(&m_mouseMenu);
m_menuArray.Add(&m_keyboardMenu);
m_menuArray.Add(&m_joystickMenu);
// Build each menu
unsigned int i;
for (i=0; i < m_menuArray.GetSize(); i++)
{
m_menuArray[i]->Build();
}
// This is done after the build above because it shouldn't be built until the user
// actually wants to go into the menu.
m_menuArray.Add(&m_displayMenu);
SetCurrentMenu(MENU_ID_MAINMENU, MENU_ID_MAINMENU);
// Load the version string
m_hstrVersion = m_pClientDE->FormatString(IDS_VERSION);
return DTRUE;
}
//*******************************************************************
// Initialize the fonts
void CMainMenus::InitFonts()
{
m_pSmallFont = new CLTGUIFont;
m_pLargeFont = new CLTGUIFont;
// Initialize the bitmap fonts if we are in english
if (IsEnglish())
{
char *lpszSmallFontPath="interface/fonts/MenuFont1.pcx";
char *lpszSmallWidthPath="interface/fonts/MenuFont1.fnt";
char *lpszLargeFontPath="interface/fonts/MenuFont1.pcx";
char *lpszLargeWidthPath="interface/fonts/MenuFont1.fnt";
if ( !m_pSmallFont->Init(m_pClientDE, lpszSmallFontPath, lpszSmallWidthPath) )
{
char szString[512];
sprintf(szString, "Cannot load font: %s", lpszSmallFontPath);
m_pClientDE->CPrint(szString);
}
if ( !m_pLargeFont->Init(m_pClientDE, lpszLargeFontPath, lpszLargeWidthPath) )
{
char szString[512];
sprintf(szString, "Cannot load font: %s", lpszLargeFontPath);
m_pClientDE->CPrint(szString);
delete []m_pLargeFont;
m_pLargeFont=DNULL;
}
// Load the large fading fonts
m_pLargeFadeFonts = new CLTGUIFont[m_nNumLargeFadeFonts];
int i;
for (i=0; i < m_nNumLargeFadeFonts; i++)
{
char szPath[512];
// Check to see if we should be loading a disabled font
if (m_nNumLargeFadeFonts > 1 && i==m_nNumLargeFadeFonts-1)
{
sprintf(szPath, "interface/mainmenus/mm_font_dis.pcx", i+1);
}
else
{
sprintf(szPath, "interface/mainmenus/mm_font_0%d.pcx", i+1);
}
if ( !m_pLargeFadeFonts[i].Init(m_pClientDE, szPath, "interface/mainmenus/mm_font.fnt") )
{
char szString[512];
sprintf(szString, "Cannot load font: %s", szPath);
m_pClientDE->CPrint(szString);
delete []m_pLargeFadeFonts;
// Set it to the large font
m_pLargeFadeFonts=m_pLargeFont;
m_nNumLargeFadeFonts=1;
}
}
}
else
{
m_nNumLargeFadeFonts=0;
// Initialize the engine fonts for non-english resource files
InitEngineFont(m_pSmallFont, IDS_MENU_FONT_SMALL_NAME, IDS_MENU_FONT_SMALL_WIDTH, IDS_MENU_FONT_SMALL_HEIGHT);
InitEngineFont(m_pLargeFont, IDS_MENU_FONT_LARGE_NAME, IDS_MENU_FONT_LARGE_WIDTH, IDS_MENU_FONT_LARGE_HEIGHT);
// Initialize a title font if we aren't in english
if (!IsEnglish())
{
m_pTitleFont = new CLTGUIFont;
InitEngineFont(m_pTitleFont, IDS_MENU_FONT_TITLE_NAME, IDS_MENU_FONT_TITLE_WIDTH, IDS_MENU_FONT_TITLE_HEIGHT);
}
}
// Set the wrapping method
HSTRING hString=m_pClientDE->FormatString(IDS_FONT_WRAP_USE_SPACES);
if (_mbsicmp((const unsigned char*)m_pClientDE->GetStringData(hString), (const unsigned char*)"1") == 0)
{
CLTGUIFont::SetWrapMethod(DTRUE);
}
else
{
CLTGUIFont::SetWrapMethod(DFALSE);
}
}
//*******************************************************************
// Initialize an engine font from string IDs that represent the name, width, and height
DBOOL CMainMenus::InitEngineFont(CLTGUIFont *pFont, int nNameID, int nWidthID, int nHeightID)
{
if (!pFont)
{
return DFALSE;
}
// Get the font name, width, and height
HSTRING hName=m_pClientDE->FormatString(nNameID);
HSTRING hWidth=m_pClientDE->FormatString(nWidthID);
HSTRING hHeight=m_pClientDE->FormatString(nHeightID);
int nWidth=atoi(m_pClientDE->GetStringData(hWidth));
int nHeight=atoi(m_pClientDE->GetStringData(hHeight));
// Initialize the font
DBOOL bResult;
bResult=pFont->Init(m_pClientDE, m_pClientDE->GetStringData(hName), nWidth, nHeight, DFALSE, DFALSE, DFALSE);
if (!bResult)
{
char szString[1024];
sprintf(szString, "Cannot initialize font: %s", m_pClientDE->GetStringData(hName));
m_pClientDE->CPrint(szString);
}
// Free the strings
m_pClientDE->FreeString(hName);
m_pClientDE->FreeString(hWidth);
m_pClientDE->FreeString(hHeight);
return bResult;
}
//*******************************************************************
// Termination
void CMainMenus::Term()
{
// Terminate the SharedResourceMgr class
m_sharedResourceMgr.Term();
// Terminate the surfaces
TermSurfaces();
// Terminate the message box
m_messageBox.Destroy();
// Term the menus
// Build each menu
unsigned int i;
for (i=0; i < m_menuArray.GetSize(); i++)
{
m_menuArray[i]->Term();
}
// Terminate the fonts
if ( m_pSmallFont )
{
m_pSmallFont->Term();
delete m_pSmallFont;
m_pSmallFont=DNULL;
}
if ( m_pLargeFont )
{
m_pLargeFont->Term();
delete m_pLargeFont;
m_pLargeFont=DNULL;
}
if ( m_pTitleFont )
{
m_pTitleFont->Term();
delete m_pTitleFont;
m_pTitleFont=DNULL;
}
if ( m_lpszBackground )
{
delete []m_lpszBackground;
m_lpszBackground=DNULL;
}
if ( m_pLargeFadeFonts )
{
int i;
for (i=0; i < m_nNumLargeFadeFonts; i++)
{
m_pLargeFadeFonts[i].Term();
}
delete []m_pLargeFadeFonts;
m_pLargeFadeFonts=DNULL;
}
// Free the version string
if (m_pClientDE)
{
m_pClientDE->FreeString(m_hstrVersion);
m_hstrVersion = NULL;
}
}
//*******************************************************************
// Initialize the surfaces
DBOOL CMainMenus::InitSurfaces()
{
if ( m_pClientDE )
{
// The background image
#ifdef _ADDON
m_hSurfBackground = m_pClientDE->CreateSurfaceFromBitmap("interface_ao\\background.pcx");
#else
m_hSurfBackground = m_pClientDE->CreateSurfaceFromBitmap("interface/mainmenus/background.pcx");
#endif
// The working surface
m_hSurfWork = m_pClientDE->CreateSurface(640, 480);
// The slider bar surface
m_hSurfSliderBar = m_pClientDE->CreateSurfaceFromBitmap("interface/mainmenus/SliderBar.pcx");
// The slider tab surface
m_hSurfSliderTab = m_pClientDE->CreateSurfaceFromBitmap("interface/mainmenus/SliderTab.pcx");
// The up arrow surface
m_hSurfUpArrow = m_pClientDE->CreateSurfaceFromBitmap("interface/mainmenus/UpArrow.pcx");
// The down arrow surface
m_hSurfDownArrow = m_pClientDE->CreateSurfaceFromBitmap("interface/mainmenus/DownArrow.pcx");
}
else
{
return DFALSE;
}
return DTRUE;
}
//*******************************************************************
// Terminate ths surfaces
void CMainMenus::TermSurfaces()
{
if (m_pClientDE)
{
if (m_hSurfBackground)
{
m_pClientDE->DeleteSurface(m_hSurfBackground);
m_hSurfBackground = NULL;
}
if (m_hSurfWork)
{
m_pClientDE->DeleteSurface(m_hSurfWork);
m_hSurfWork = NULL;
}
if (m_hSurfSliderBar)
{
m_pClientDE->DeleteSurface(m_hSurfSliderBar);
m_hSurfSliderBar = NULL;
}
if (m_hSurfSliderTab)
{
m_pClientDE->DeleteSurface(m_hSurfSliderTab);
m_hSurfSliderTab = NULL;
}
if (m_hSurfUpArrow)
{
m_pClientDE->DeleteSurface(m_hSurfUpArrow);
m_hSurfUpArrow = NULL;
}
if (m_hSurfDownArrow)
{
m_pClientDE->DeleteSurface(m_hSurfDownArrow);
m_hSurfDownArrow = NULL;
}
}
}
//*******************************************************************
// Sets the screen resolution
DBOOL CMainMenus::SwitchResolution(int nWidth, int nHeight)
{
RMode currentMode;
m_pClientDE->GetRenderMode(¤tMode);
currentMode.m_Width=nWidth;
currentMode.m_Height=nHeight;
if (m_pClientDE->SetRenderMode(¤tMode) != LT_OK)
{
return DFALSE;
}
else
{
if (nWidth < 512 || nHeight < 384)
{
SetLowResolution(DTRUE);
}
else
{
SetLowResolution(DFALSE);
}
return DTRUE;
}
}
//*******************************************************************
// Switches between low and high resolution menus
void CMainMenus::SetLowResolution(DBOOL bLow)
{
m_bLowResolution=bLow;
// Set all of the menu heights
if (m_bLowResolution)
{
m_nMenuHeight=180;
}
else
{
m_nMenuHeight=280;
}
unsigned int i;
for (i=0; i < m_menuArray.GetSize(); i++)
{
// Set the menu height
m_menuArray[i]->SetMenuHeight(m_nMenuHeight);
// Tell it whether to use high rez or low rez fonts
m_menuArray[i]->SetLowResolutionFonts(m_bLowResolution);
}
}
//*******************************************************************
// Called when the menus get or lose focus
void CMainMenus::SetFocus(DBOOL bFocus)
{
if (bFocus)
{
// Pause all of the sounds
m_pClientDE->PauseSounds();
// Play one of the 4 ambient sounds
int nSound=GetRandom(1,4);
#ifdef _DEMO
if (nSound == 1) nSound = 2;
if (nSound == 3) nSound = 4;
#endif
char szSoundPath[256];
sprintf(szSoundPath, "/Sounds/Interface/MainMenus/ambient0%d.wav", nSound);
m_hAmbientSound=PlaySound(szSoundPath, DTRUE, DTRUE, DTRUE);
}
else
{
// Stop the ambient sound
if (m_hAmbientSound)
{
m_pClientDE->KillSound(m_hAmbientSound);
m_hAmbientSound=DNULL;
}
// Resume all of the sounds
m_pClientDE->ResumeSounds();
}
}
//*******************************************************************
// Plays a sound
HSOUNDDE CMainMenus::PlaySound(char *lpszSound, DBOOL bStream, DBOOL bLoop, DBOOL bGetHandle)
{
PlaySoundInfo playSoundInfo;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -