⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainmenus.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//*******************************************************************
//
// 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(&currentMode) == 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(&currentMode);

	currentMode.m_Width=nWidth;
	currentMode.m_Height=nHeight;

	if (m_pClientDE->SetRenderMode(&currentMode) != 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 + -