dlgmainmenu.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** 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 ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Combat *
  23. * *
  24. * $Archive:: /Commando/Code/Commando/dlgmainmenu.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 2/12/02 1:28p $*
  29. * *
  30. * $Revision:: 29 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "dlgmainmenu.h"
  36. #include "assetmgr.h"
  37. #include "rendobj.h"
  38. #include "hanim.h"
  39. #include "gameinitmgr.h"
  40. #include "mainmenutransition.h"
  41. #include "menubackdrop.h"
  42. #include "scene.h"
  43. #include "dialogresource.h"
  44. #include "mesh.h"
  45. #include "meshgeometry.h"
  46. #include "dialogmgr.h"
  47. #include "gameinitmgr.h"
  48. #include "debug.h"
  49. #include "dialogcontrol.h"
  50. #include "specialbuilds.h"
  51. #include "buildnum.h"
  52. #include "campaign.h"
  53. #include "gamedata.h"
  54. #include "imagectrl.h"
  55. #include "init.h"
  56. #include "registry.h"
  57. #include "_globals.h"
  58. #include "dialogtests.h"
  59. #include "dlgwolwait.h"
  60. #include "nicenum.h"
  61. #include "dlgmessagebox.h"
  62. #include "translatedb.h"
  63. #include "string_ids.h"
  64. #include "gamespyadmin.h"
  65. ////////////////////////////////////////////////////////////////
  66. // Static member initialization
  67. ////////////////////////////////////////////////////////////////
  68. MainMenuDialogClass * MainMenuDialogClass::_TheInstance = NULL;
  69. bool MainMenuDialogClass::Animated = true;
  70. ////////////////////////////////////////////////////////////////
  71. //
  72. // MainMenuDialogClass
  73. //
  74. ////////////////////////////////////////////////////////////////
  75. MainMenuDialogClass::MainMenuDialogClass (void) :
  76. MenuDialogClass (IDD_MENU_MAIN),
  77. TitleTransModel (NULL),
  78. LogoModel (NULL),
  79. GizmoModel (NULL),
  80. IsStartingPractice (false)
  81. {
  82. LogoModel = WW3DAssetManager::Get_Instance ()->Create_Render_Obj ("IF_RENLOGO");
  83. TitleTransModel = WW3DAssetManager::Get_Instance ()->Create_Render_Obj ("IF_TITLETRANS");
  84. GizmoModel = WW3DAssetManager::Get_Instance ()->Create_Render_Obj ("IF_EVAGIZMO");
  85. RegistryClass reg(APPLICATION_SUB_KEY_NAME_OPTIONS);
  86. if (reg.Get_Int("DisableMenuAnim", 0) != 0) {
  87. Animated = false;
  88. }
  89. if (TitleTransModel != NULL && GizmoModel != NULL && Animated) {
  90. //
  91. // Play the gizmo animation
  92. //
  93. HAnimClass *gizmo_anim = WW3DAssetManager::Get_Instance ()->Get_HAnim ("IF_EVAGIZMO.IF_EVAGIZMO");
  94. if (gizmo_anim != NULL) {
  95. GizmoModel->Set_Animation (gizmo_anim, 0.0F, RenderObjClass::ANIM_MODE_LOOP);
  96. REF_PTR_RELEASE (gizmo_anim);
  97. }
  98. //
  99. // Add the gizmo to the transition model
  100. //
  101. TitleTransModel->Add_Sub_Object_To_Bone (GizmoModel, "IF_GIZMOBONE");
  102. }
  103. return ;
  104. }
  105. ////////////////////////////////////////////////////////////////
  106. //
  107. // ~MainMenuDialogClass
  108. //
  109. ////////////////////////////////////////////////////////////////
  110. MainMenuDialogClass::~MainMenuDialogClass (void)
  111. {
  112. if (TitleTransModel != NULL) {
  113. TitleTransModel->Remove ();
  114. }
  115. if (LogoModel != NULL) {
  116. LogoModel->Remove ();
  117. }
  118. REF_PTR_RELEASE (LogoModel);
  119. REF_PTR_RELEASE (TitleTransModel);
  120. REF_PTR_RELEASE (GizmoModel);
  121. return ;
  122. }
  123. ////////////////////////////////////////////////////////////////
  124. //
  125. // On_Menu_Activate
  126. //
  127. ////////////////////////////////////////////////////////////////
  128. void
  129. MainMenuDialogClass::On_Menu_Activate (bool onoff)
  130. {
  131. if (TitleTransModel != NULL) {
  132. //
  133. // Either add or remove the logo from the scene
  134. //
  135. if (onoff) {
  136. // Put the logo pack into the scene when reactivated.
  137. if (LogoModel && LogoModel->Peek_Scene() == NULL) {
  138. Get_BackDrop()->Peek_Scene()->Add_Render_Object(LogoModel);
  139. }
  140. //
  141. // Force-shutdown any interfaces that are running... (this could
  142. // happen if the user navigates through the multiplay menus and then
  143. // returns to the main menu).
  144. //
  145. GameInitMgrClass::Shutdown ();
  146. } else {
  147. //
  148. // Remove the logo from the screen
  149. //
  150. if (LogoModel != NULL) {
  151. LogoModel->Remove ();
  152. }
  153. }
  154. }
  155. MenuDialogClass::On_Menu_Activate (onoff);
  156. return ;
  157. }
  158. ////////////////////////////////////////////////////////////////
  159. //
  160. // On_Init_Dialog
  161. //
  162. ////////////////////////////////////////////////////////////////
  163. void
  164. MainMenuDialogClass::On_Init_Dialog (void)
  165. {
  166. Update_Version_Number ();
  167. #if defined(BETACLIENT) || defined(FREEDEDICATEDSERVER) || defined(MULTIPLAYERDEMO)
  168. Get_Dlg_Item(IDC_MENU_START_SP_GAME_BUTTON)->Enable(false);
  169. Get_Dlg_Item(IDC_MENU_START_PRACTICE_GAME_BUTTON)->Enable(false);
  170. #endif
  171. #ifndef BETACLIENT
  172. if (Get_Dlg_Item (IDC_BETA_TEST_TEXT) != NULL) {
  173. Get_Dlg_Item (IDC_BETA_TEST_TEXT)->Show (false);
  174. }
  175. #endif
  176. ImageCtrlClass *image_ctrl = (ImageCtrlClass *)Get_Dlg_Item (IDC_IMAGE);
  177. if (image_ctrl != NULL) {
  178. image_ctrl->Set_Texture ("ESRB_RATING.TGA");
  179. }
  180. return ;
  181. }
  182. ////////////////////////////////////////////////////////////////
  183. //
  184. // Get_Transition_In
  185. //
  186. ////////////////////////////////////////////////////////////////
  187. DialogTransitionClass *
  188. MainMenuDialogClass::Get_Transition_In (DialogBaseClass *prev_dlg)
  189. {
  190. MainMenuTransitionClass *transition = NULL;
  191. //
  192. // Add the transition model to the scene
  193. //
  194. if (TitleTransModel != NULL && TitleTransModel->Peek_Scene () == NULL) {
  195. Get_BackDrop ()->Peek_Scene ()->Add_Render_Object (TitleTransModel);
  196. }
  197. //
  198. // Add the logo to the screen
  199. //
  200. if (LogoModel != NULL && LogoModel->Peek_Scene () == NULL) {
  201. Get_BackDrop ()->Peek_Scene ()->Add_Render_Object (LogoModel);
  202. }
  203. //
  204. // We only want to transition between menu dialogs
  205. //
  206. if (prev_dlg == NULL ||
  207. (prev_dlg != QuitVerificationDialogClass::Get_Instance () &&
  208. prev_dlg != DlgWOLWait::Get_Instance ()))
  209. {
  210. transition = new MainMenuTransitionClass;
  211. transition->Set_Model (TitleTransModel);
  212. transition->Set_Camera (Get_BackDrop ()->Peek_Camera ());
  213. transition->Set_Type (DialogTransitionClass::SCREEN_IN);
  214. transition->Set_Dialogs (this, prev_dlg);
  215. //
  216. // Don't do the transition if something is missing
  217. //
  218. if (transition->Is_Valid () == false) {
  219. REF_PTR_RELEASE (transition);
  220. }
  221. }
  222. return transition;
  223. }
  224. ////////////////////////////////////////////////////////////////
  225. //
  226. // Get_Transition_Out
  227. //
  228. ////////////////////////////////////////////////////////////////
  229. DialogTransitionClass *
  230. MainMenuDialogClass::Get_Transition_Out (DialogBaseClass *next_dlg)
  231. {
  232. MainMenuTransitionClass *transition = NULL;
  233. //
  234. // We only want to transition between menu dialogs
  235. //
  236. if ( IsStartingPractice == false &&
  237. (next_dlg == NULL || next_dlg->As_MenuDialogClass () != NULL))
  238. {
  239. transition = new MainMenuTransitionClass;
  240. transition->Set_Model (TitleTransModel);
  241. transition->Set_Camera (Get_BackDrop ()->Peek_Camera ());
  242. transition->Set_Type (DialogTransitionClass::SCREEN_OUT);
  243. transition->Set_Dialogs (this, next_dlg);
  244. //
  245. // Don't do the transition if something is missing
  246. //
  247. if (transition->Is_Valid () == false) {
  248. REF_PTR_RELEASE (transition);
  249. }
  250. }
  251. return transition;
  252. }
  253. ////////////////////////////////////////////////////////////////
  254. //
  255. // Choose_Skirmish_Map
  256. //
  257. ////////////////////////////////////////////////////////////////
  258. StringClass
  259. MainMenuDialogClass::Choose_Skirmish_Map (void)
  260. {
  261. DynamicVectorClass<StringClass> map_list;
  262. WIN32_FIND_DATA find_info = { 0 };
  263. BOOL keep_going = TRUE;
  264. HANDLE file_find = NULL;
  265. StringClass file_filter;
  266. //
  267. // Look for any skirmish maps.
  268. //
  269. file_filter.Format("data\\skirmish*.mix");
  270. keep_going = TRUE;
  271. for (file_find = ::FindFirstFile (file_filter, &find_info);
  272. (file_find != INVALID_HANDLE_VALUE) && keep_going;
  273. keep_going = ::FindNextFile (file_find, &find_info))
  274. {
  275. map_list.Add (find_info.cFileName);
  276. }
  277. if (file_find != INVALID_HANDLE_VALUE) {
  278. ::FindClose (file_find);
  279. }
  280. if (map_list.Count() == 0) {
  281. //
  282. // No skirmish maps found. Look for a C&C map.
  283. //
  284. file_filter.Format("data\\c&c_*.mix");
  285. keep_going = TRUE;
  286. for (file_find = ::FindFirstFile (file_filter, &find_info);
  287. (file_find != INVALID_HANDLE_VALUE) && keep_going;
  288. keep_going = ::FindNextFile (file_find, &find_info))
  289. {
  290. map_list.Add (find_info.cFileName);
  291. }
  292. if (file_find != INVALID_HANDLE_VALUE) {
  293. ::FindClose (file_find);
  294. }
  295. }
  296. StringClass mapname;
  297. if (map_list.Count() > 0) {
  298. int choice = rand() % map_list.Count();
  299. mapname = map_list[choice];
  300. }
  301. return mapname;
  302. }
  303. ////////////////////////////////////////////////////////////////
  304. //
  305. // On_Command
  306. //
  307. ////////////////////////////////////////////////////////////////
  308. void
  309. MainMenuDialogClass::On_Command (int ctrl_id, int message_id, DWORD param)
  310. {
  311. bool allow_default = true;
  312. switch (ctrl_id)
  313. {
  314. case IDCANCEL:
  315. ctrl_id = IDC_MENU_QUIT_BUTTON;
  316. break;
  317. case IDC_MENU_START_PRACTICE_GAME_BUTTON:
  318. {
  319. StringClass mapname = Choose_Skirmish_Map();
  320. if (!mapname.Is_Empty()) {
  321. IsStartingPractice = true;
  322. const int SKIRMISH_LOAD_MENU_NUMBER = 96;
  323. CampaignManager::Select_Backdrop_Number(SKIRMISH_LOAD_MENU_NUMBER);
  324. GameInitMgrClass::Initialize_Skirmish();
  325. //
  326. // We will cycle on the same map until they get tired of practicing.
  327. //
  328. WWASSERT(The_Game() != NULL);
  329. The_Game()->Set_Map_Cycle(0, mapname);
  330. GameInitMgrClass::Start_Game(mapname, -1, 0);
  331. IsStartingPractice = false;
  332. }
  333. break;
  334. }
  335. case IDC_MENU_MP_LAN_GAME_BUTTON:
  336. //
  337. // Clear any gamespyadmin flags
  338. //
  339. cGameSpyAdmin::Reset();
  340. if (cNicEnum::Get_Num_Nics() > 0) {
  341. GameInitMgrClass::Initialize_LAN ();
  342. } else {
  343. DlgMsgBox::DoDialog(
  344. TRANSLATE(IDS_MP_UNABLE_INITIALIZE_LAN),
  345. TRANSLATE(IDS_MP_NO_LAN_IP_ADDRESSES_FOUND));
  346. allow_default = false;
  347. }
  348. break;
  349. case IDC_MENU_MP_INTERNET_GAME_BUTTON:
  350. START_DIALOG (InternetMainDialogClass);
  351. allow_default = false;
  352. break;
  353. default:
  354. break;
  355. }
  356. if (allow_default) {
  357. MenuDialogClass::On_Command (ctrl_id, message_id, param);
  358. }
  359. return ;
  360. }
  361. ////////////////////////////////////////////////////////////////
  362. //
  363. // Display
  364. //
  365. ////////////////////////////////////////////////////////////////
  366. void
  367. MainMenuDialogClass::Display (void)
  368. {
  369. //
  370. // Create the dialog if necessary, otherwise simply bring it to the front
  371. //
  372. if (_TheInstance == NULL) {
  373. //
  374. // Create the dialog
  375. //
  376. MainMenuDialogClass *dialog = new MainMenuDialogClass;
  377. //
  378. // Create the backdrop if necessary
  379. //
  380. if (Animated) {
  381. if (dialog->Get_BackDrop ()->Peek_Model () == NULL) {
  382. dialog->Get_BackDrop ()->Set_Model ("IF_BACK01");
  383. dialog->Get_BackDrop ()->Set_Animation ("IF_BACK01.IF_BACK01");
  384. /*RenderObjClass *model = WW3DAssetManager::Get_Instance ()->Create_Render_Obj ("IF_RENLOGO");
  385. if (model != NULL) {
  386. dialog->Get_BackDrop ()->Peek_Scene ()->Add_Render_Object(model);
  387. }*/
  388. }
  389. }
  390. //
  391. // Start the dialog
  392. //
  393. dialog->Start_Dialog ();
  394. REF_PTR_RELEASE (dialog);
  395. } else {
  396. if (_TheInstance->Is_Active_Menu () == false) {
  397. DialogMgrClass::Rollback (_TheInstance);
  398. }
  399. }
  400. return ;
  401. }
  402. ////////////////////////////////////////////////////////////////
  403. //
  404. // Update_Version_Number
  405. //
  406. ////////////////////////////////////////////////////////////////
  407. void
  408. MainMenuDialogClass::Update_Version_Number (void)
  409. {
  410. //
  411. // Version 1.0 by default
  412. //
  413. DWORD version_major = 1;
  414. DWORD version_minor = 0;
  415. Get_Version_Number(&version_major, &version_minor);
  416. //
  417. // Put the version string into the dialog
  418. //
  419. WideStringClass version_string;
  420. // Add build number temporarily. Will probably be removed for shipping.
  421. WideStringClass build_number(BuildInfoClass::Get_Build_Number_String(), true);
  422. WideStringClass build_initials(BuildInfoClass::Get_Builder_Initials(), true);
  423. WideStringClass build_date(BuildInfoClass::Get_Build_Date_String(), true);
  424. version_string.Format (L"v%d.%.3d %s-%s %s", (version_major >> 16), (version_major & 0xFFFF), build_initials, build_number, build_date);
  425. Set_Dlg_Item_Text (IDC_VERSION_STATIC, version_string);
  426. }
  427. //TRANSLATE_ME
  428. //const WCHAR * title = L"Unable to initialize LAN";
  429. //IDS_MP_UNABLE_INITIALIZE_LAN
  430. //const WCHAR * text = L"No LAN IP addresses found.";
  431. //IDS_MP_NO_LAN_IP_ADDRESSES_FOUND
  432. //DlgMsgBox::DoDialog(title, text);
  433. /*
  434. #ifdef MULTIPLAYERDEMO
  435. START_DIALOG (GameSpyMainDialogClass);
  436. #else
  437. START_DIALOG (InternetMainDialogClass);
  438. #endif
  439. */