538 lines
14 KiB
C++
538 lines
14 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/***********************************************************************************************
|
|
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
|
***********************************************************************************************
|
|
* *
|
|
* Project Name : Combat *
|
|
* *
|
|
* $Archive:: /Commando/Code/Commando/dlgmainmenu.cpp $*
|
|
* *
|
|
* Author:: Patrick Smith *
|
|
* *
|
|
* $Modtime:: 2/12/02 1:28p $*
|
|
* *
|
|
* $Revision:: 29 $*
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
|
|
#include "dlgmainmenu.h"
|
|
#include "assetmgr.h"
|
|
#include "rendobj.h"
|
|
#include "hanim.h"
|
|
#include "gameinitmgr.h"
|
|
#include "mainmenutransition.h"
|
|
#include "menubackdrop.h"
|
|
#include "scene.h"
|
|
#include "dialogresource.h"
|
|
#include "mesh.h"
|
|
#include "meshgeometry.h"
|
|
#include "dialogmgr.h"
|
|
#include "gameinitmgr.h"
|
|
#include "debug.h"
|
|
#include "dialogcontrol.h"
|
|
#include "specialbuilds.h"
|
|
#include "buildnum.h"
|
|
#include "campaign.h"
|
|
#include "gamedata.h"
|
|
#include "imagectrl.h"
|
|
#include "init.h"
|
|
#include "registry.h"
|
|
#include "_globals.h"
|
|
#include "dialogtests.h"
|
|
#include "dlgwolwait.h"
|
|
#include "nicenum.h"
|
|
#include "dlgmessagebox.h"
|
|
#include "translatedb.h"
|
|
#include "string_ids.h"
|
|
#include "gamespyadmin.h"
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Static member initialization
|
|
////////////////////////////////////////////////////////////////
|
|
MainMenuDialogClass * MainMenuDialogClass::_TheInstance = NULL;
|
|
bool MainMenuDialogClass::Animated = true;
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// MainMenuDialogClass
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
MainMenuDialogClass::MainMenuDialogClass (void) :
|
|
MenuDialogClass (IDD_MENU_MAIN),
|
|
TitleTransModel (NULL),
|
|
LogoModel (NULL),
|
|
GizmoModel (NULL),
|
|
IsStartingPractice (false)
|
|
{
|
|
LogoModel = WW3DAssetManager::Get_Instance ()->Create_Render_Obj ("IF_RENLOGO");
|
|
TitleTransModel = WW3DAssetManager::Get_Instance ()->Create_Render_Obj ("IF_TITLETRANS");
|
|
GizmoModel = WW3DAssetManager::Get_Instance ()->Create_Render_Obj ("IF_EVAGIZMO");
|
|
|
|
RegistryClass reg(APPLICATION_SUB_KEY_NAME_OPTIONS);
|
|
if (reg.Get_Int("DisableMenuAnim", 0) != 0) {
|
|
Animated = false;
|
|
}
|
|
|
|
|
|
if (TitleTransModel != NULL && GizmoModel != NULL && Animated) {
|
|
|
|
//
|
|
// Play the gizmo animation
|
|
//
|
|
HAnimClass *gizmo_anim = WW3DAssetManager::Get_Instance ()->Get_HAnim ("IF_EVAGIZMO.IF_EVAGIZMO");
|
|
if (gizmo_anim != NULL) {
|
|
GizmoModel->Set_Animation (gizmo_anim, 0.0F, RenderObjClass::ANIM_MODE_LOOP);
|
|
REF_PTR_RELEASE (gizmo_anim);
|
|
}
|
|
|
|
//
|
|
// Add the gizmo to the transition model
|
|
//
|
|
TitleTransModel->Add_Sub_Object_To_Bone (GizmoModel, "IF_GIZMOBONE");
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// ~MainMenuDialogClass
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
MainMenuDialogClass::~MainMenuDialogClass (void)
|
|
{
|
|
if (TitleTransModel != NULL) {
|
|
TitleTransModel->Remove ();
|
|
}
|
|
|
|
if (LogoModel != NULL) {
|
|
LogoModel->Remove ();
|
|
}
|
|
|
|
REF_PTR_RELEASE (LogoModel);
|
|
REF_PTR_RELEASE (TitleTransModel);
|
|
REF_PTR_RELEASE (GizmoModel);
|
|
return ;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// On_Menu_Activate
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
void
|
|
MainMenuDialogClass::On_Menu_Activate (bool onoff)
|
|
{
|
|
if (TitleTransModel != NULL) {
|
|
|
|
//
|
|
// Either add or remove the logo from the scene
|
|
//
|
|
if (onoff) {
|
|
|
|
// Put the logo pack into the scene when reactivated.
|
|
if (LogoModel && LogoModel->Peek_Scene() == NULL) {
|
|
Get_BackDrop()->Peek_Scene()->Add_Render_Object(LogoModel);
|
|
}
|
|
|
|
//
|
|
// Force-shutdown any interfaces that are running... (this could
|
|
// happen if the user navigates through the multiplay menus and then
|
|
// returns to the main menu).
|
|
//
|
|
GameInitMgrClass::Shutdown ();
|
|
} else {
|
|
|
|
//
|
|
// Remove the logo from the screen
|
|
//
|
|
if (LogoModel != NULL) {
|
|
LogoModel->Remove ();
|
|
}
|
|
}
|
|
}
|
|
|
|
MenuDialogClass::On_Menu_Activate (onoff);
|
|
return ;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// On_Init_Dialog
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
void
|
|
MainMenuDialogClass::On_Init_Dialog (void)
|
|
{
|
|
Update_Version_Number ();
|
|
|
|
#if defined(BETACLIENT) || defined(FREEDEDICATEDSERVER) || defined(MULTIPLAYERDEMO)
|
|
Get_Dlg_Item(IDC_MENU_START_SP_GAME_BUTTON)->Enable(false);
|
|
Get_Dlg_Item(IDC_MENU_START_PRACTICE_GAME_BUTTON)->Enable(false);
|
|
#endif
|
|
|
|
#ifndef BETACLIENT
|
|
if (Get_Dlg_Item (IDC_BETA_TEST_TEXT) != NULL) {
|
|
Get_Dlg_Item (IDC_BETA_TEST_TEXT)->Show (false);
|
|
}
|
|
#endif
|
|
|
|
ImageCtrlClass *image_ctrl = (ImageCtrlClass *)Get_Dlg_Item (IDC_IMAGE);
|
|
if (image_ctrl != NULL) {
|
|
image_ctrl->Set_Texture ("ESRB_RATING.TGA");
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// Get_Transition_In
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
DialogTransitionClass *
|
|
MainMenuDialogClass::Get_Transition_In (DialogBaseClass *prev_dlg)
|
|
{
|
|
MainMenuTransitionClass *transition = NULL;
|
|
|
|
//
|
|
// Add the transition model to the scene
|
|
//
|
|
if (TitleTransModel != NULL && TitleTransModel->Peek_Scene () == NULL) {
|
|
Get_BackDrop ()->Peek_Scene ()->Add_Render_Object (TitleTransModel);
|
|
}
|
|
|
|
//
|
|
// Add the logo to the screen
|
|
//
|
|
if (LogoModel != NULL && LogoModel->Peek_Scene () == NULL) {
|
|
Get_BackDrop ()->Peek_Scene ()->Add_Render_Object (LogoModel);
|
|
}
|
|
|
|
//
|
|
// We only want to transition between menu dialogs
|
|
//
|
|
if (prev_dlg == NULL ||
|
|
(prev_dlg != QuitVerificationDialogClass::Get_Instance () &&
|
|
prev_dlg != DlgWOLWait::Get_Instance ()))
|
|
{
|
|
transition = new MainMenuTransitionClass;
|
|
transition->Set_Model (TitleTransModel);
|
|
transition->Set_Camera (Get_BackDrop ()->Peek_Camera ());
|
|
transition->Set_Type (DialogTransitionClass::SCREEN_IN);
|
|
transition->Set_Dialogs (this, prev_dlg);
|
|
|
|
//
|
|
// Don't do the transition if something is missing
|
|
//
|
|
if (transition->Is_Valid () == false) {
|
|
REF_PTR_RELEASE (transition);
|
|
}
|
|
}
|
|
|
|
return transition;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// Get_Transition_Out
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
DialogTransitionClass *
|
|
MainMenuDialogClass::Get_Transition_Out (DialogBaseClass *next_dlg)
|
|
{
|
|
MainMenuTransitionClass *transition = NULL;
|
|
|
|
//
|
|
// We only want to transition between menu dialogs
|
|
//
|
|
if ( IsStartingPractice == false &&
|
|
(next_dlg == NULL || next_dlg->As_MenuDialogClass () != NULL))
|
|
{
|
|
transition = new MainMenuTransitionClass;
|
|
transition->Set_Model (TitleTransModel);
|
|
transition->Set_Camera (Get_BackDrop ()->Peek_Camera ());
|
|
transition->Set_Type (DialogTransitionClass::SCREEN_OUT);
|
|
transition->Set_Dialogs (this, next_dlg);
|
|
|
|
//
|
|
// Don't do the transition if something is missing
|
|
//
|
|
if (transition->Is_Valid () == false) {
|
|
REF_PTR_RELEASE (transition);
|
|
}
|
|
}
|
|
|
|
return transition;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// Choose_Skirmish_Map
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
StringClass
|
|
MainMenuDialogClass::Choose_Skirmish_Map (void)
|
|
{
|
|
DynamicVectorClass<StringClass> map_list;
|
|
WIN32_FIND_DATA find_info = { 0 };
|
|
BOOL keep_going = TRUE;
|
|
HANDLE file_find = NULL;
|
|
StringClass file_filter;
|
|
|
|
//
|
|
// Look for any skirmish maps.
|
|
//
|
|
file_filter.Format("data\\skirmish*.mix");
|
|
keep_going = TRUE;
|
|
for (file_find = ::FindFirstFile (file_filter, &find_info);
|
|
(file_find != INVALID_HANDLE_VALUE) && keep_going;
|
|
keep_going = ::FindNextFile (file_find, &find_info))
|
|
{
|
|
map_list.Add (find_info.cFileName);
|
|
}
|
|
|
|
if (file_find != INVALID_HANDLE_VALUE) {
|
|
::FindClose (file_find);
|
|
}
|
|
|
|
if (map_list.Count() == 0) {
|
|
//
|
|
// No skirmish maps found. Look for a C&C map.
|
|
//
|
|
file_filter.Format("data\\c&c_*.mix");
|
|
keep_going = TRUE;
|
|
for (file_find = ::FindFirstFile (file_filter, &find_info);
|
|
(file_find != INVALID_HANDLE_VALUE) && keep_going;
|
|
keep_going = ::FindNextFile (file_find, &find_info))
|
|
{
|
|
map_list.Add (find_info.cFileName);
|
|
}
|
|
|
|
if (file_find != INVALID_HANDLE_VALUE) {
|
|
::FindClose (file_find);
|
|
}
|
|
}
|
|
|
|
StringClass mapname;
|
|
if (map_list.Count() > 0) {
|
|
int choice = rand() % map_list.Count();
|
|
mapname = map_list[choice];
|
|
}
|
|
|
|
return mapname;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// On_Command
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
void
|
|
MainMenuDialogClass::On_Command (int ctrl_id, int message_id, DWORD param)
|
|
{
|
|
bool allow_default = true;
|
|
|
|
switch (ctrl_id)
|
|
{
|
|
case IDCANCEL:
|
|
ctrl_id = IDC_MENU_QUIT_BUTTON;
|
|
break;
|
|
|
|
case IDC_MENU_START_PRACTICE_GAME_BUTTON:
|
|
{
|
|
StringClass mapname = Choose_Skirmish_Map();
|
|
|
|
if (!mapname.Is_Empty()) {
|
|
IsStartingPractice = true;
|
|
const int SKIRMISH_LOAD_MENU_NUMBER = 96;
|
|
CampaignManager::Select_Backdrop_Number(SKIRMISH_LOAD_MENU_NUMBER);
|
|
GameInitMgrClass::Initialize_Skirmish();
|
|
|
|
//
|
|
// We will cycle on the same map until they get tired of practicing.
|
|
//
|
|
WWASSERT(The_Game() != NULL);
|
|
The_Game()->Set_Map_Cycle(0, mapname);
|
|
|
|
GameInitMgrClass::Start_Game(mapname, -1, 0);
|
|
IsStartingPractice = false;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case IDC_MENU_MP_LAN_GAME_BUTTON:
|
|
|
|
//
|
|
// Clear any gamespyadmin flags
|
|
//
|
|
cGameSpyAdmin::Reset();
|
|
|
|
if (cNicEnum::Get_Num_Nics() > 0) {
|
|
GameInitMgrClass::Initialize_LAN ();
|
|
} else {
|
|
DlgMsgBox::DoDialog(
|
|
TRANSLATE(IDS_MP_UNABLE_INITIALIZE_LAN),
|
|
TRANSLATE(IDS_MP_NO_LAN_IP_ADDRESSES_FOUND));
|
|
allow_default = false;
|
|
}
|
|
break;
|
|
|
|
case IDC_MENU_MP_INTERNET_GAME_BUTTON:
|
|
START_DIALOG (InternetMainDialogClass);
|
|
allow_default = false;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (allow_default) {
|
|
MenuDialogClass::On_Command (ctrl_id, message_id, param);
|
|
}
|
|
return ;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// Display
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
void
|
|
MainMenuDialogClass::Display (void)
|
|
{
|
|
//
|
|
// Create the dialog if necessary, otherwise simply bring it to the front
|
|
//
|
|
if (_TheInstance == NULL) {
|
|
|
|
//
|
|
// Create the dialog
|
|
//
|
|
MainMenuDialogClass *dialog = new MainMenuDialogClass;
|
|
|
|
//
|
|
// Create the backdrop if necessary
|
|
//
|
|
if (Animated) {
|
|
|
|
if (dialog->Get_BackDrop ()->Peek_Model () == NULL) {
|
|
dialog->Get_BackDrop ()->Set_Model ("IF_BACK01");
|
|
dialog->Get_BackDrop ()->Set_Animation ("IF_BACK01.IF_BACK01");
|
|
|
|
/*RenderObjClass *model = WW3DAssetManager::Get_Instance ()->Create_Render_Obj ("IF_RENLOGO");
|
|
if (model != NULL) {
|
|
dialog->Get_BackDrop ()->Peek_Scene ()->Add_Render_Object(model);
|
|
}*/
|
|
}
|
|
}
|
|
|
|
//
|
|
// Start the dialog
|
|
//
|
|
dialog->Start_Dialog ();
|
|
REF_PTR_RELEASE (dialog);
|
|
|
|
} else {
|
|
if (_TheInstance->Is_Active_Menu () == false) {
|
|
DialogMgrClass::Rollback (_TheInstance);
|
|
}
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// Update_Version_Number
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
void
|
|
MainMenuDialogClass::Update_Version_Number (void)
|
|
{
|
|
//
|
|
// Version 1.0 by default
|
|
//
|
|
DWORD version_major = 1;
|
|
DWORD version_minor = 0;
|
|
Get_Version_Number(&version_major, &version_minor);
|
|
|
|
//
|
|
// Put the version string into the dialog
|
|
//
|
|
WideStringClass version_string;
|
|
// Add build number temporarily. Will probably be removed for shipping.
|
|
WideStringClass build_number(BuildInfoClass::Get_Build_Number_String(), true);
|
|
WideStringClass build_initials(BuildInfoClass::Get_Builder_Initials(), true);
|
|
WideStringClass build_date(BuildInfoClass::Get_Build_Date_String(), true);
|
|
version_string.Format (L"v%d.%.3d %s-%s %s", (version_major >> 16), (version_major & 0xFFFF), build_initials, build_number, build_date);
|
|
Set_Dlg_Item_Text (IDC_VERSION_STATIC, version_string);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//TRANSLATE_ME
|
|
//const WCHAR * title = L"Unable to initialize LAN";
|
|
//IDS_MP_UNABLE_INITIALIZE_LAN
|
|
//const WCHAR * text = L"No LAN IP addresses found.";
|
|
//IDS_MP_NO_LAN_IP_ADDRESSES_FOUND
|
|
|
|
//DlgMsgBox::DoDialog(title, text);
|
|
|
|
/*
|
|
#ifdef MULTIPLAYERDEMO
|
|
START_DIALOG (GameSpyMainDialogClass);
|
|
#else
|
|
START_DIALOG (InternetMainDialogClass);
|
|
#endif
|
|
*/
|