init.cpp 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136
  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. *** Confidential - Westwood Studios ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Commando *
  23. * *
  24. * $Archive:: /Commando/Code/Commando/init.cpp $*
  25. * *
  26. * $Author:: Steve_t $*
  27. * *
  28. * $Modtime:: 10/16/02 11:10a $*
  29. * *
  30. * $Revision:: 258 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * Commando_Assert_Handler -- Commando callback function for WWASSERT's *
  35. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  36. #include "init.h"
  37. #include "debug.h"
  38. #include "wwmath.h"
  39. #include "ww3d.h"
  40. #include "wwphys.h"
  41. #include "WWAudio.H"
  42. #include "wwsaveload.h"
  43. #include "input.h"
  44. #include "inputconfigmgr.h"
  45. //#include "gamesettings.h"
  46. #include "ffactory.h"
  47. #include "assets.h"
  48. #include "_globals.h"
  49. #include "combatgmode.h" // gamemode
  50. #include "langmode.h" // gamemode
  51. #include "wolgmode.h" // gamemode
  52. #include "movie.h" // gamemode
  53. #include "gamemenu.h" // gamemode
  54. #include "overlay.h" // gamemode
  55. #include "multihud.h" // gamemode
  56. #include "console.h" // gamemode
  57. #include "textdisplay.h" // gamemode
  58. #include "scorescreen.h" // gamemode
  59. #include "msgloop.h"
  60. #include "Resource.H"
  61. #include "miscutil.h"
  62. #include "cnetwork.h"
  63. #include "mathutil.h"
  64. #include "win.h"
  65. #include "Part_Ldr.H"
  66. #include "savegame.H"
  67. #include "systemsettings.h"
  68. #include "gamedata.h"
  69. #include "sphereobj.h"
  70. #include "ringobj.h"
  71. #include "diagnostics.h"
  72. #include "devoptions.h"
  73. #include "translatedb.h"
  74. #include "useroptions.h"
  75. #include "pathmgr.h"
  76. #include "string_ids.h"
  77. #include "soundrobj.h"
  78. #include "crandom.h"
  79. #include "systimer.h"
  80. #include "renegadedialogmgr.h"
  81. #include "campaign.h"
  82. #include "diaglog.h"
  83. #include "mpsettingsmgr.h"
  84. #include "mixfile.h"
  85. #include "ffactorylist.h"
  86. #include "gameinitmgr.h"
  87. #include "serverfps.h"
  88. #include "nicenum.h"
  89. #include "encyclopediamgr.h"
  90. #include "texturethumbnail.h"
  91. #include "playermanager.h"
  92. #include "teammanager.h"
  93. #include "stackdump.h"
  94. #include "registry.h"
  95. #include "bandwidthgraph.h"
  96. #include "buildnum.h"
  97. #include "dx8wrapper.h"
  98. #include "autostart.h"
  99. #include "except.h"
  100. #include "wwmemlog.h"
  101. #include "except.h"
  102. #include "consolemode.h"
  103. #include "serversettings.h"
  104. #include "pscene.h"
  105. #include "dazzle.h"
  106. #include "skinpackagemgr.h"
  107. #include "modpackagemgr.h"
  108. #include "GameSpy_QnR.h"
  109. #include "gamespyadmin.h"
  110. #include "shutdown.h"
  111. #include "specialbuilds.h"
  112. extern const char *VALUE_NAME_TEXTURE_FILTER_MODE;
  113. /*
  114. ** Define IMMEDIATE_LOAD if you want to have the game start right
  115. ** up in a given level (for profiling for example)
  116. */
  117. // HACK: ATI demo loads the demo level bypassing the mainmenu
  118. #ifdef ATI_DEMO_HACK
  119. #define IMMEDIATE_LOAD 1
  120. #define IMMEDIATE_LOAD_LEVELNAME "MDD_0807.mix"
  121. #else
  122. #define IMMEDIATE_LOAD 0
  123. #define IMMEDIATE_LOAD_LEVELNAME "MDD_0803.mix"
  124. #endif
  125. /*
  126. ** This defines the subdirectory where the game will load all data from
  127. */
  128. const char * DATA_SUBDIRECTORY = "DATA\\";
  129. const char * SAVE_SUBDIRECTORY = "DATA\\SAVE\\";
  130. const char * CONFIG_SUBDIRECTORY = "DATA\\CONFIG\\";
  131. const char * MOVIES_SUBDIRECTORY = "DATA\\MOVIES\\";
  132. #define STRINGS_FILENAME "STRINGS.TDB"
  133. #define CONV_DB_FILENAME "CONV10.CDB"
  134. /*
  135. ** DebugDisplayHandler
  136. */
  137. TextDebugDisplayHandlerClass TextDisplayHandler;
  138. /*
  139. ** Used to modify where game entries are kept in the registry.
  140. */
  141. extern char DefaultRegistryModifier[1024];
  142. /*
  143. ** Static global lod settings for particles
  144. */
  145. static const float _ParticleLODScreenSizes[17] =
  146. {
  147. 0.0025f,
  148. 0.0050f,
  149. 0.0075f,
  150. 0.0100f,
  151. 0.0300f,
  152. 0.0500f,
  153. 0.0700f,
  154. 0.0900f,
  155. 0.1000f,
  156. 0.3000f,
  157. 0.5000f,
  158. 1.0000f,
  159. 1.2500f,
  160. 1.5000f,
  161. 1.7500f,
  162. 2.0000f,
  163. NO_MAX_SCREEN_SIZE
  164. };
  165. /***********************************************************************************************
  166. * Append_To_Assert_History -- keeps a timestamped history of asserts. *
  167. * *
  168. * INPUT: *
  169. * *
  170. * OUTPUT: *
  171. * *
  172. * WARNINGS: *
  173. * *
  174. * HISTORY: *
  175. * 9/26/2001 tss : Created. *
  176. *=============================================================================================*/
  177. void Append_To_Assert_History(const char * message)
  178. {
  179. if (message == NULL) {
  180. //
  181. // bail
  182. //
  183. return;
  184. }
  185. FILE * file = ::fopen("_asserts.txt", "at");
  186. if (file == NULL) {
  187. return;
  188. }
  189. char line[2000] = "";
  190. //
  191. // Blank lines plus timestamp
  192. //
  193. ::sprintf(line, "\n\nWhen: %s\n", cMiscUtil::Get_Text_Time());
  194. ::fwrite(line, 1, ::strlen(line), file);
  195. //
  196. // version #
  197. //
  198. ::sprintf(line, "Version: %d\n", DebugManager::Get_Version_Number());
  199. ::fwrite(line, 1, ::strlen(line), file);
  200. //
  201. // Full filename
  202. //
  203. char full_filename[MAX_PATH];
  204. ::GetModuleFileName(NULL, full_filename, sizeof(full_filename));
  205. ::sprintf(line, "Filename: %s\n", full_filename);
  206. ::fwrite(line, 1, ::strlen(line), file);
  207. //
  208. // File size
  209. //
  210. HANDLE hfile = ::CreateFile(full_filename, 0, 0, NULL, OPEN_EXISTING, 0L, NULL);
  211. if (hfile != INVALID_HANDLE_VALUE)
  212. {
  213. DWORD file_size = ::GetFileSize(hfile, NULL);
  214. ::CloseHandle(hfile);
  215. ::sprintf(line, "Filesize: %d\n", file_size);
  216. ::fwrite(line, 1, ::strlen(line), file);
  217. }
  218. //
  219. // The assert message itself
  220. //
  221. ::sprintf(line, "Assert: %s\n", message);
  222. ::fwrite(line, 1, ::strlen(line), file);
  223. ::fclose(file);
  224. }
  225. /***********************************************************************************************
  226. * Commando_Assert_Handler -- Commando callback function for WWASSERT's *
  227. * *
  228. * INPUT: *
  229. * *
  230. * OUTPUT: *
  231. * *
  232. * WARNINGS: *
  233. * *
  234. * HISTORY: *
  235. * 3/28/2000 gth : Created. *
  236. *=============================================================================================*/
  237. void Commando_Assert_Handler(const char * message)
  238. {
  239. if (message == NULL) {
  240. //
  241. // bail
  242. //
  243. return;
  244. }
  245. //
  246. // TSS092601
  247. //
  248. Append_To_Assert_History(message);
  249. //
  250. // If the exception handler is try to quit the game then don't show an assert.
  251. //
  252. if (Is_Trying_To_Exit()) {
  253. ExitProcess(0);
  254. }
  255. //
  256. // Hand the message off to the scrolling debug screen
  257. //
  258. DebugManager::Display( message );
  259. //
  260. //
  261. // IF YOU WANT TO DISABLE CERTAIN ACTIONS HERE, USE
  262. // THE REGISTRY SWITCHES!!!!!!!!!!!!!
  263. //
  264. //
  265. #ifdef WWDEBUG
  266. Copy_Logs(DebugManager::Get_Version_Number());
  267. #endif // WWDEBUG
  268. RegistryClass registry( APPLICATION_SUB_KEY_NAME_DEBUG );
  269. if ( registry.Is_Valid() ) {
  270. registry.Set_Int( VALUE_NAME_APPLICATION_CRASH_VERSION, 0 );
  271. }
  272. #ifdef WWDEBUG
  273. if (cDevOptions::SoundEffectOnAssert.Is_True() &&
  274. WWAudioClass::Get_Instance() != NULL) {
  275. //
  276. // Sound effect
  277. //
  278. WWAudioClass::Get_Instance()->Create_Instant_Sound("Debug_Assertion", Matrix3D(1));
  279. }
  280. if (cDevOptions::DisplayLogfileOnAssert.Is_True()) {
  281. //
  282. // Open up the logfile so that the user can see the assert
  283. // at the bottom.
  284. //
  285. cNetwork::Shell_Command(DebugManager::Logfile_Name());
  286. }
  287. //LOG_CALL_STACK;
  288. if (cDevOptions::BreakToDebuggerOnAssert.Is_True()) {
  289. if (cDevOptions::ShutdownInputOnAssert.Is_True()) {
  290. //
  291. // This input shutdown is to help those of us who still have the
  292. // DirectInput / debugger problem. For some of us the registry fix
  293. // doesn't help.
  294. //
  295. Input::Shutdown();
  296. }
  297. /*
  298. m
  299. $m mm m
  300. "$mmmmm m$" mmmmmmm$"
  301. """$m m$ m$""""""
  302. mmmmmmm$$$$$$$$$"mmmm
  303. mmm$$$$$$$$$$$$$$$$$$ m$$$$m " m "
  304. $$$$$$$$$$$$$$$$$$$$$$ $$$$$$"$$$
  305. mmmmmmmmmmmmmmmmmmmmm $$$$$$$$$$
  306. $$$$$$$$$$$$$$$$$$$$$ $$$$$$$""" m
  307. "$$$$$$$$$$$$$$$$$$$$$ $$$$$$ " "
  308. """""""$$$$$$$$$$$m """"
  309. mmmmmmmm" m$ "$mmmmm
  310. $$"""""" "$ """"""$$
  311. m$" "m "
  312. */
  313. _asm int 0x03;
  314. }
  315. if (cDevOptions::ExitThreadOnAssert.Is_True()) {
  316. ExitThread(1);
  317. }
  318. #endif // WWDEBUG
  319. }
  320. /*
  321. **
  322. */
  323. void _stdcall AudioTextCallback(AudibleSoundClass *sound_obj, const StringClass &text, uint32 user_param)
  324. {
  325. Vector3 red = Vector3( 1, 0.5f, 0.5f );
  326. StringClass str;
  327. str.Format( "%s\n", (const char *)text );
  328. DebugManager::Display_Text( str, red );
  329. }
  330. /*
  331. **
  332. */
  333. class LoggingFileFactoryClass : public SimpleFileFactoryClass {
  334. public:
  335. virtual FileClass * Get_File( const char * filename ) {
  336. FileClass * file = BaseFactory->Get_File( filename );
  337. Debug_Say(( "FILE_LOG : %s %s\n", filename, ((file==NULL||!file->Is_Available())?"MISSING":"") ));
  338. return file;
  339. }
  340. void Set_Base_Factory( FileFactoryClass * factory ) { BaseFactory = factory; }
  341. private:
  342. FileFactoryClass * BaseFactory;
  343. };
  344. /*
  345. **
  346. */
  347. class StrippingFileFactoryClass : public SimpleFileFactoryClass {
  348. public:
  349. virtual FileClass * Get_File( const char * filename ) {
  350. StringClass stripped(true);
  351. Strip_Path_From_Filename( stripped, filename );
  352. return BaseFactory->Get_File( stripped );
  353. }
  354. void Set_Base_Factory( FileFactoryClass * factory ) { BaseFactory = factory; }
  355. private:
  356. FileFactoryClass * BaseFactory;
  357. };
  358. /*
  359. **
  360. */
  361. SimpleFileFactoryClass RenegadeWritingFileFactory;
  362. SimpleFileFactoryClass RenegadeBaseFileFactory;
  363. MixFileFactoryClass * AlwaysMixFileFactory;
  364. FileFactoryListClass _RenegadeFileFactory;
  365. StrippingFileFactoryClass AudioFileFactory;
  366. LoggingFileFactoryClass LoggingFileFactory;
  367. /*
  368. **
  369. */
  370. void Construct_Directory_Structure(void)
  371. {
  372. //
  373. // Lookup the path of the executable
  374. //
  375. char path[MAX_PATH] = { 0 };
  376. ::GetModuleFileName (NULL, path, sizeof (path));
  377. //
  378. // Strip off the filename
  379. //
  380. char *filename = ::strrchr (path, '\\');
  381. if (filename != NULL) {
  382. filename[1] = 0;
  383. }
  384. StringClass data_dir(path,true);
  385. data_dir += "data";
  386. StringClass save_dir(data_dir + "\\save",true);
  387. StringClass config_dir(data_dir + "\\config",true);
  388. //
  389. // Create the data directory if necessary
  390. //
  391. if (GetFileAttributes (data_dir) == 0xFFFFFFFF) {
  392. ::CreateDirectory (data_dir, NULL);
  393. }
  394. //
  395. // Create the save directory if necessary
  396. //
  397. if (GetFileAttributes (save_dir) == 0xFFFFFFFF) {
  398. ::CreateDirectory (save_dir, NULL);
  399. }
  400. //
  401. // Create the config directory if necessary
  402. //
  403. if (GetFileAttributes (config_dir) == 0xFFFFFFFF) {
  404. ::CreateDirectory (config_dir, NULL);
  405. }
  406. return ;
  407. }
  408. static bool Verify_Log_Directory(const StringClass& folder)
  409. {
  410. if (GetFileAttributes(folder)!=0xffffffff) return true;
  411. //HANDLE file;
  412. //file = CreateFile(folder, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  413. //if (file!=INVALID_HANDLE_VALUE) {
  414. // CloseHandle(file);
  415. // return true;
  416. //}
  417. if (CreateDirectory(folder,NULL)) {
  418. return true;
  419. }
  420. if (GetLastError() == ERROR_ALREADY_EXISTS) {
  421. return(true);
  422. }
  423. return false;
  424. }
  425. static bool Create_Log_File_Name(const StringClass& folder, StringClass& filename,bool use_numbering)
  426. {
  427. StringClass original(filename);
  428. if (!use_numbering) {
  429. filename.Format("%s\\%s",folder,original);
  430. return true;
  431. }
  432. for (int i=0;i<999;++i) {
  433. HANDLE file;
  434. filename.Format("%s\\%3.3d%s",folder,i,original);
  435. file = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
  436. if (file!=INVALID_HANDLE_VALUE) {
  437. CloseHandle(file);
  438. return true;
  439. }
  440. }
  441. return false;
  442. }
  443. static void Copy_Log(const StringClass& folder,const char* filename,bool use_numbering)
  444. {
  445. RawFileClass raw_log_file(filename);
  446. if (raw_log_file.Is_Available()) {
  447. int size=raw_log_file.Size();
  448. if (size) {
  449. StringClass log_file_name(filename);
  450. if (Create_Log_File_Name(folder,log_file_name,use_numbering)) {
  451. DWORD written;
  452. HANDLE file;
  453. file = CreateFile(log_file_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  454. if (INVALID_HANDLE_VALUE != file) {
  455. raw_log_file.Open();
  456. unsigned char* memory=new unsigned char[size];
  457. raw_log_file.Read(memory,size);
  458. raw_log_file.Close();
  459. WriteFile(file, memory, size, &written, NULL);
  460. delete[] memory;
  461. CloseHandle(file);
  462. }
  463. }
  464. }
  465. }
  466. }
  467. static class CopyThreadClass : public ThreadClass
  468. {
  469. public:
  470. unsigned Version;
  471. CopyThreadClass()
  472. :
  473. Version(0),
  474. ThreadClass("LogCopyThread", &Exception_Handler) {}
  475. void Thread_Function()
  476. {
  477. // Write log to network folder
  478. char computer_name[MAX_COMPUTERNAME_LENGTH + 1];
  479. DWORD size = sizeof(computer_name);
  480. ::GetComputerName(computer_name, &size);
  481. RegistryClass reg(APPLICATION_SUB_KEY_NAME_DEBUG);
  482. char path[MAX_PATH];
  483. reg.Get_String("LogPath", path, sizeof(path), "\\\\tanya\\game\\projects\\renegade\\_error_logs");
  484. strcat(path, "\\");
  485. StringClass folder_name(0,true);
  486. folder_name.Format("%s%d.%d",path,Version>>16,Version&0xffff);
  487. if (!Verify_Log_Directory(folder_name)) return;
  488. folder_name+="\\";
  489. folder_name+=computer_name;
  490. if (!Verify_Log_Directory(folder_name)) return;
  491. Copy_Log(folder_name,DebugManager::Logfile_Name(),true); //"_logfile.txt",true);
  492. Copy_Log(folder_name,"_asserts.txt",true);
  493. Copy_Log(folder_name,"_except.txt",true);
  494. Copy_Log(folder_name,"sysinfo.txt",false);
  495. }
  496. } CopyThread;
  497. void Copy_Logs(unsigned version)
  498. {
  499. RegistryClass registry( APPLICATION_SUB_KEY_NAME_DEBUG );
  500. if ( registry.Is_Valid() ) {
  501. if (registry.Get_Int( VALUE_NAME_DISABLE_LOG_COPYING,0 )) return;
  502. }
  503. if (CopyThread.Is_Running()) return;
  504. CopyThread.Version=version;
  505. CopyThread.Execute();
  506. int time=TIMEGETTIME();
  507. while (TIMEGETTIME()-time<5000) {
  508. if (!CopyThread.Is_Running()) {
  509. break;
  510. }
  511. Sleep(100);
  512. }
  513. }
  514. void Application_Exception_Callback(void)
  515. {
  516. #ifdef WWDEBUG
  517. Copy_Logs(DebugManager::Get_Version_Number());
  518. #endif // WWDEBUG
  519. RegistryClass registry( APPLICATION_SUB_KEY_NAME_DEBUG );
  520. if ( registry.Is_Valid() ) {
  521. registry.Set_Int( VALUE_NAME_APPLICATION_CRASH_VERSION, 0 );
  522. }
  523. }
  524. bool RestartNeeded = true;
  525. /***********************************************************************************************
  526. * Get_Version_Number -- Collate version information. *
  527. * *
  528. * *
  529. * *
  530. * INPUT: Ptr to var to fill with major version number *
  531. * Ptr to var to fill with minor version number *
  532. * *
  533. * *
  534. * OUTPUT: Nothing *
  535. * *
  536. * WARNINGS: None *
  537. * *
  538. * HISTORY: *
  539. * 12/3/2001 11:26PM ST : Created *
  540. *=============================================================================================*/
  541. void Get_Version_Number(unsigned long *major, unsigned long *minor)
  542. {
  543. // Version info removed per Legal review requirements. LFeenanEA - 8th February 2025
  544. unsigned long version_major = 0;
  545. unsigned long version_minor = 0;
  546. }
  547. /*
  548. **
  549. */
  550. #if 0
  551. #define FIRST_CHAR 'a'
  552. #define LAST_CHAR 'z'
  553. #include "realcrc.h"
  554. int CRC_Next( unsigned char ** p, int length )
  555. {
  556. int ret = 0;
  557. if ( length == -1 ) {
  558. return 1;
  559. }
  560. if ( **p == LAST_CHAR ) {
  561. *p = *p-1;
  562. ret |= CRC_Next( p, length-1 );
  563. *p = *p+1;
  564. **p = FIRST_CHAR;
  565. } else {
  566. **p = **p+1;
  567. }
  568. return ret;
  569. }
  570. void CRC_Check( void )
  571. {
  572. Debug_Say(( "CRC_Check\n" ));
  573. int count = 0;
  574. #define MAX_STRING 10
  575. #define GOAL_CRC 65729409
  576. int start = timeGetTime();
  577. unsigned char string[MAX_STRING+1];
  578. for ( int length = 1; length <= MAX_STRING; length++ )
  579. {
  580. unsigned char * p = &string[length-1];
  581. string[length] = 0;
  582. for ( int i = 0; i < length; i++ ) {
  583. string[i] = FIRST_CHAR;
  584. }
  585. while ( 1 ) {
  586. /* if ( (count & 0x0FFFF) == 0 ) {
  587. Debug_Say(( "Checking %d \"%s\"\n", count, string ));
  588. }*/
  589. int crc = CRC_String( (char *)string );
  590. if ( crc == GOAL_CRC ) {
  591. Debug_Say(( "CRC MATCH \"%s\" (count %d) at %d\n\n", string, count, timeGetTime()-start ));
  592. }
  593. count++;
  594. if ( CRC_Next( &p, length-1 ) != 0 ) {
  595. break;
  596. }
  597. }
  598. Debug_Say(( "End length %d (count %d) at %d\n", length, count, timeGetTime()-start ));
  599. }
  600. // strcpy( string, "miketheheadlesschickenisgod" );
  601. // Debug_Say(( "CRC %d\n", crc ));
  602. return;
  603. }
  604. #endif
  605. /*
  606. **
  607. */
  608. bool Game_Init(void)
  609. {
  610. WWMEMLOG(MEM_GAMEINIT);
  611. // Set registry key to 1 for the duration of the init. This way we know if the program crashed while the init.
  612. RegistryClass registry( APPLICATION_SUB_KEY_NAME_DEBUG );
  613. if ( registry.Is_Valid() ) {
  614. registry.Set_Int( VALUE_NAME_GAME_INITIALIZATION_IN_PROGRESS, 1 );
  615. unsigned crash_version=registry.Get_Int( VALUE_NAME_APPLICATION_CRASH_VERSION, 0 );
  616. #ifdef WWDEBUG
  617. if (crash_version) Copy_Logs(crash_version);
  618. #endif // WWDEBUG
  619. registry.Set_Int( VALUE_NAME_APPLICATION_CRASH_VERSION, 0 );
  620. }
  621. //
  622. // Ensure our directory structure exists
  623. //
  624. Construct_Directory_Structure ();
  625. //
  626. // Initialize our debugging framework
  627. //
  628. DebugManager::Init();
  629. DebugManager::Load_Registry_Settings( APPLICATION_SUB_KEY_NAME_DEBUG );
  630. WWDebug_Install_Assert_Handler(Commando_Assert_Handler);
  631. BuildInfoClass::Log_Build_Info();
  632. //CRC_Check();
  633. Get_Version_Number(NULL, NULL);
  634. // setup Writing Factory
  635. RenegadeWritingFileFactory.Set_Sub_Directory( DATA_SUBDIRECTORY );
  636. _TheWritingFileFactory = &RenegadeWritingFileFactory;
  637. RenegadeBaseFileFactory.Set_Sub_Directory( DATA_SUBDIRECTORY );
  638. RenegadeBaseFileFactory.Append_Sub_Directory( SAVE_SUBDIRECTORY );
  639. RenegadeBaseFileFactory.Append_Sub_Directory( CONFIG_SUBDIRECTORY );
  640. _TheSimpleFileFactory->Set_Sub_Directory( DATA_SUBDIRECTORY );
  641. _TheSimpleFileFactory->Append_Sub_Directory( SAVE_SUBDIRECTORY );
  642. _TheSimpleFileFactory->Append_Sub_Directory( CONFIG_SUBDIRECTORY );
  643. _TheSimpleFileFactory->Set_Strip_Path( true );
  644. _RenegadeFileFactory.Add_FileFactory( &RenegadeBaseFileFactory, "" );
  645. _RenegadeFileFactory.Add_FileFactory( new MixFileFactoryClass( "Always2.dat", &RenegadeBaseFileFactory ), "Always2.dat" );
  646. _RenegadeFileFactory.Add_FileFactory( new MixFileFactoryClass( "Always.dbs", &RenegadeBaseFileFactory ), "Always.dbs" );
  647. _RenegadeFileFactory.Add_FileFactory( new MixFileFactoryClass( "Always.dat", &RenegadeBaseFileFactory ), "Always.dat" );
  648. //
  649. // Search for all mix files in the data directory
  650. //
  651. WIN32_FIND_DATA find_info = { 0 };
  652. BOOL keep_going = TRUE;
  653. HANDLE file_find = NULL;
  654. for (file_find = ::FindFirstFile ("data\\*.mix", &find_info);
  655. (file_find != INVALID_HANDLE_VALUE) && keep_going;
  656. keep_going = ::FindNextFile (file_find, &find_info))
  657. {
  658. //
  659. // Add this mix file to our mix file factory list
  660. //
  661. _RenegadeFileFactory.Add_FileFactory( new MixFileFactoryClass (find_info.cFileName, &RenegadeBaseFileFactory ), find_info.cFileName );
  662. }
  663. //
  664. // Close the search handle
  665. //
  666. if (file_find != INVALID_HANDLE_VALUE) {
  667. ::FindClose (file_find);
  668. }
  669. _TheFileFactory = &_RenegadeFileFactory;
  670. // Logging File Factory
  671. if ( DebugManager::Is_File_Logging_Enabled() ) {
  672. LoggingFileFactory.Set_Base_Factory( &_RenegadeFileFactory );
  673. _TheFileFactory = &LoggingFileFactory;
  674. }
  675. AudioFileFactory.Set_Base_Factory( _TheFileFactory );
  676. //Setup_Mix_File();
  677. // Lets seed the Random Generator, a little
  678. int count = TIMEGETTIME() & 0xFF;
  679. while ( count-- > 0 ) {
  680. FreeRandom.Get_Int();
  681. }
  682. // Thumbnail manager pre init will ensure that thumbnail database
  683. // is up-to-date.
  684. bool show_thumbnail_pre_init_dialog = true;
  685. #ifdef WWDEBUG
  686. show_thumbnail_pre_init_dialog = cDevOptions::ShowThumbnailPreInitDialog.Get();
  687. #endif // WWDEBUG
  688. // ThumbnailManagerClass::Pre_Init(show_thumbnail_pre_init_dialog);
  689. //
  690. // Create an instance of the sound library
  691. //
  692. new WWAudioClass(ConsoleBox.Is_Exclusive());
  693. WWAudioClass::Get_Instance()->Initialize( APPLICATION_SUB_KEY_NAME_SOUND );
  694. WWAudioClass::Get_Instance()->Set_File_Factory( &AudioFileFactory );
  695. // Install text callback
  696. WWAudioClass::Get_Instance()->Register_Text_Callback(AudioTextCallback,0);
  697. //
  698. // Load the multiplayer settings
  699. //
  700. MPSettingsMgrClass::Load_Settings ();
  701. /*
  702. **
  703. */
  704. WW3DAssetManager * asset_manager = new WW3DAssetManager;
  705. // asset_manager->Open_Texture_File_Cache("cache_");
  706. asset_manager->Set_WW3D_Load_On_Demand( true );
  707. asset_manager->Register_Prototype_Loader(&_ParticleEmitterLoader);
  708. asset_manager->Register_Prototype_Loader(&_SphereLoader);
  709. asset_manager->Register_Prototype_Loader(&_RingLoader);
  710. asset_manager->Register_Prototype_Loader (&_SoundRenderObjLoader);
  711. asset_manager->Set_Activate_Fog_On_Load (true);
  712. //GameSettings::Init();
  713. // Initialize WWMath
  714. WWMath::Init();
  715. // Initialize the pathfind system
  716. PathMgrClass::Initialize ();
  717. // Initialize WW3D
  718. switch ( WW3D::Init(MainWindow, NULL, ConsoleBox.Is_Exclusive() ? true : false)) {
  719. case WW3D_ERROR_OK: // Success!
  720. break;
  721. case WW3D_ERROR_DIRECTX8_INITIALIZATION_FAILED:
  722. default:
  723. WWDEBUG_SAY(("WW3D::Init Failed!\r\n"));
  724. ::MessageBox(NULL,
  725. "DirectX 8.0 or later is required to play C&C:Renegade.",
  726. "Renegade Graphics Initialization Error.",
  727. MB_OK);
  728. return false;
  729. }
  730. if (ConsoleBox.Is_Exclusive()) {
  731. WW3D::Enable_Decals(false);
  732. PhysicsSceneClass * scene = PhysicsSceneClass::Get_Instance();
  733. scene->Set_Max_Simultaneous_Shadows(0);
  734. DazzleRenderObjClass::Enable_Dazzle_Rendering(false);
  735. } else {
  736. if ( WW3D::Registry_Load_Render_Device( APPLICATION_SUB_KEY_NAME_RENDER, true ) != WW3D_ERROR_OK ) {
  737. WWDEBUG_SAY(("WW3D::Registry_Load_Render_Device Failed!\r\n"));
  738. return false;
  739. }
  740. if ( WW3D::Registry_Save_Render_Device( APPLICATION_SUB_KEY_NAME_RENDER ) != WW3D_ERROR_OK ) {
  741. WWDEBUG_SAY(("WW3D::Registry_Save_Render_Device Failed!\r\n"));
  742. return false;
  743. }
  744. WW3D::Enable_Static_Sort_Lists (true);
  745. }
  746. if (AutoRestart.Get_Restart_Flag() || ServerSettingsClass::Is_Command_Line_Mode() || ConsoleBox.Is_Exclusive()) {
  747. if (!ConsoleBox.Is_Exclusive()) {
  748. ::ShowWindow( MainWindow, SW_MINIMIZE ); // minimize if we are starting automatically.
  749. }
  750. ConsoleBox.Init();
  751. } else {
  752. ::ShowWindow( MainWindow, SW_SHOW ); // show the (initially hidden) window
  753. }
  754. // Clear screen
  755. for (int frame=0;frame<3;++frame) {
  756. WW3D::Begin_Render(true,true,Vector3(0.0f,0.0f,0.0f));
  757. WW3D::End_Render();
  758. }
  759. ParticleEmitterClass::Set_Default_Remove_On_Complete(false); // (gth) 09/17/2000 - by default emitters shouldn't self-destruct
  760. for (int i=0; i<17; i++) {
  761. ParticleBufferClass::Set_LOD_Max_Screen_Size(i,_ParticleLODScreenSizes[i]);
  762. }
  763. if ( cUserOptions::PermitDiagLogging.Is_True() &&
  764. DebugManager::Is_Diag_Logging_Enabled() ) {
  765. DiagLogClass::Init();
  766. }
  767. WWPhys::Init();
  768. WWSaveLoad::Init();
  769. //
  770. // Load the strings table
  771. //
  772. TranslateDBClass::Initialize();
  773. FileClass *file = _TheFileFactory->Get_File( STRINGS_FILENAME );
  774. if (file != NULL) {
  775. file->Open (FileClass::READ); // Open or the file
  776. if ( file->Is_Available() ) {
  777. ChunkLoadClass cload (file); // Load the database
  778. SaveLoadSystemClass::Load(cload);
  779. }
  780. file->Close (); // Close the file
  781. _TheFileFactory->Return_File (file);
  782. }
  783. //TranslateDBClass::Set_Current_Language (TranslateDBClass::LANGID_CHINESE);
  784. //
  785. // Initialize the input control system
  786. //
  787. bool dinput_avail = (ConsoleBox.Is_Exclusive()) ? false : true;
  788. Input::Init(dinput_avail);
  789. Input::Load_Registry( APPLICATION_SUB_KEY_NAME_CONTROLS );
  790. InputConfigMgrClass::Initialize();
  791. //
  792. // Initialize the skin selection framework
  793. //
  794. SkinPackageMgrClass::Initialize ();
  795. ModPackageMgrClass::Initialize ();
  796. ModPackageMgrClass::Build_List ();
  797. //
  798. // Load the conversation database
  799. //
  800. file = _TheFileFactory->Get_File( CONV_DB_FILENAME );
  801. if (file != NULL) {
  802. file->Open (FileClass::READ); // Open or the file
  803. if ( file->Is_Available() ) {
  804. ChunkLoadClass cload (file); // Load the database
  805. SaveLoadSystemClass::Load(cload);
  806. }
  807. file->Close (); // Close the file
  808. _TheFileFactory->Return_File (file);
  809. }
  810. //
  811. // Check to make sure the code version matches the strings
  812. // table version
  813. //
  814. if (TranslateDBClass::Get_Version_Number () != STRINGS_VER) {
  815. MessageBox( 0,
  816. "This build of Renegade is out of sync with the strings database (strings.tdb). Strings will be incorrect and may cause the game to crash.",
  817. "Version Error",
  818. MB_OK | MB_ICONEXCLAMATION | MB_SETFOREGROUND );
  819. }
  820. //
  821. // Note: Due to interdependencies (yuck!) between these subsystems, here's the
  822. // order they need to be initialized in:
  823. //
  824. // - Physics Scene Class (via CombatManager::Scene_Init)
  825. // - SystemSettings
  826. // - RenegadeDialogMgrClass
  827. //
  828. //
  829. CombatManager::Scene_Init();
  830. if (!ConsoleBox.Is_Exclusive()) {
  831. SystemSettings::Init();
  832. }
  833. RenegadeDialogMgrClass::Initialize();
  834. cNetwork::Onetime_Init();
  835. cServerFps::Create_Instance();
  836. cPlayerManager::Onetime_Init();
  837. cTeamManager::Onetime_Init();
  838. cGameData::Onetime_Init();
  839. cBandwidthGraph::Onetime_Init();
  840. cNetUtil::Wsa_Init();
  841. CombatManager::Init(ConsoleBox.Is_Exclusive() ? false : true);
  842. CampaignManager::Init();
  843. // This order is also draw and think order
  844. GameModeManager::Add( new CombatGameModeClass );
  845. GameModeManager::Add( new LanGameModeClass );
  846. GameModeManager::Add( new WolGameModeClass );
  847. GameModeManager::Add( new OverlayGameModeClass );
  848. GameModeManager::Add( new MenuGameModeClass2 ); // Putting menu after overlay so we see the text
  849. GameModeManager::Add( new MovieGameModeClass );
  850. GameModeManager::Add( new ConsoleGameModeClass );
  851. GameModeManager::Add( new ScoreScreenGameModeClass );
  852. //GameModeManager::Add( new LobbyGameModeClass );
  853. GameModeManager::Add( new TextDisplayGameModeClass );
  854. GameModeManager::Add( new Overlay3DGameModeClass );
  855. GameModeManager::Find( "Overlay3D" )->Activate();
  856. GameModeManager::Find( "Overlay" )->Activate();
  857. GameModeManager::Find( "Console" )->Activate();
  858. GameModeManager::Find( "Menu" )->Activate();
  859. GameModeManager::Find( "TextDisplay" )->Activate();
  860. // After TextDisplay is created, install the Display Handler
  861. DebugManager::Set_Display_Handler(&TextDisplayHandler);
  862. //DEADMENU MenuManager::Set_Menu( "Menu_Main" );
  863. // Load the accelerator table and hand it off to WWLIB.
  864. // Note: Accelerator tables that are loaded from resources (like
  865. // we are doing here) do not need to be manually freed. Windows
  866. // will cleanup for us when the process terminates.
  867. HACCEL haccel = ::LoadAccelerators (::GetModuleHandle (NULL), MAKEINTRESOURCE (IDR_ACCELERATOR));
  868. if (haccel) {
  869. ::Add_Accelerator (MainWindow, haccel);
  870. }
  871. //WW3D::Set_Texture_Reduction( 1 );
  872. //
  873. // Initialize the encyclopedia logic
  874. //
  875. EncyclopediaMgrClass::Initialize ();
  876. #if (IMMEDIATE_LOAD)
  877. // Immediately load up the specified level
  878. GameInitMgrClass::Initialize_SP ();
  879. GameInitMgrClass::Start_Game (IMMEDIATE_LOAD_LEVELNAME);
  880. #endif
  881. cDiagnostics::Init();
  882. //cHelpText::Init();
  883. //
  884. // NIC initialization
  885. //
  886. cNicEnum::Init();
  887. if ( registry.Is_Valid() ) {
  888. registry.Set_Int( VALUE_NAME_GAME_INITIALIZATION_IN_PROGRESS, 0 );
  889. registry.Set_Int( VALUE_NAME_APPLICATION_CRASH_VERSION, DebugManager::Get_Version_Number() );
  890. }
  891. #if (IMMEDIATE_LOAD==0)
  892. #if 0 // Not anymore
  893. //
  894. // Start the main menu
  895. //
  896. RenegadeDialogMgrClass::Goto_Location (RenegadeDialogMgrClass::LOC_MAIN_MENU);
  897. #else
  898. //
  899. // Parse the server settings files if they will be used soon to make sure there are no errors.
  900. //
  901. if (ServerSettingsClass::Is_Command_Line_Mode()) {
  902. if (!ServerSettingsClass::Parse(false)) {
  903. AutoRestart.Set_Restart_Flag(false);
  904. Game_Shutdown();
  905. return (false);
  906. }
  907. }
  908. //
  909. // If this is a post crash restart (or a FDS starting up) then just go straight into the game.
  910. //
  911. if (AutoRestart.Get_Restart_Flag()) {
  912. AutoRestart.Restart_Game();
  913. } else if (cGameSpyAdmin::Is_Gamespy_Game()) {
  914. if (!ConsoleBox.Is_Exclusive()) {
  915. RenegadeDialogMgrClass::Goto_Location (RenegadeDialogMgrClass::LOC_SPLASH_IN);
  916. }
  917. } else {
  918. MovieGameModeClass * mode = (MovieGameModeClass *)GameModeManager::Find ("Movie");
  919. if ( mode ) {
  920. mode->Activate();
  921. mode->Startup_Movies( );
  922. }
  923. }
  924. #endif
  925. #endif
  926. //
  927. // Send our Spy Usage Info off to Gamespy
  928. //
  929. GameSpyQnR.TrackUsage();
  930. return true;
  931. }
  932. /***********************************************************************************************
  933. * Build_Registry_Location_String -- Get a complete path to a registry location *
  934. * *
  935. * *
  936. * *
  937. * INPUT: Game base path *
  938. * Base modifier path *
  939. * Sub path *
  940. * *
  941. * OUTPUT: Ptr to complete path *
  942. * *
  943. * WARNINGS: None *
  944. * *
  945. * HISTORY: *
  946. * 11/9/2001 3:39PM ST : Created *
  947. *=============================================================================================*/
  948. char *Build_Registry_Location_String(char *base, char *modifier, char *sub)
  949. {
  950. static char _whole_registry_string[1024];
  951. WWASSERT(base != NULL);
  952. WWASSERT(sub != NULL);
  953. if (modifier == NULL) {
  954. modifier = DefaultRegistryModifier;
  955. }
  956. if (base && *base != 0) {
  957. strcpy(_whole_registry_string, base);
  958. }
  959. if (modifier && *modifier != 0) {
  960. strcat(_whole_registry_string, "\\");
  961. strcat(_whole_registry_string, modifier);
  962. }
  963. if (sub && *sub != 0) {
  964. strcat(_whole_registry_string, "\\");
  965. strcat(_whole_registry_string, sub);
  966. }
  967. return(_whole_registry_string);
  968. }