STARTUP.CPP 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. /*
  2. ** Command & Conquer Red Alert(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. /* $Header: /counterstrike/STARTUP.CPP 6 3/15/97 7:18p Steve_tall $ */
  19. /***********************************************************************************************
  20. *** 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 ***
  21. ***********************************************************************************************
  22. * *
  23. * Project Name : Command & Conquer *
  24. * *
  25. * File Name : STARTUP.CPP *
  26. * *
  27. * Programmer : Joe L. Bostic *
  28. * *
  29. * Start Date : October 3, 1994 *
  30. * *
  31. * Last Update : September 30, 1996 [JLB] *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * Prog_End -- Cleans up library systems in prep for game exit. *
  36. * main -- Initial startup routine (preps library systems). *
  37. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  38. #include "function.h"
  39. #include <conio.h>
  40. #include <io.h>
  41. #ifdef WIN32
  42. #include "ccdde.h"
  43. #include "ipx95.h"
  44. #endif //WIN32
  45. #ifdef MCIMPEG // Denzil 6/15/98
  46. #include "mcimovie.h"
  47. #endif
  48. #ifdef WOLAPI_INTEGRATION
  49. //#include "WolDebug.h"
  50. #endif
  51. bool Read_Private_Config_Struct(FileClass & file, NewConfigType * config);
  52. void Print_Error_End_Exit(char * string);
  53. void Print_Error_Exit(char * string);
  54. #ifdef WIN32
  55. //WinTimerClass * WinTimer;
  56. extern void Create_Main_Window ( HANDLE instance , int command_show , int width , int height);
  57. extern bool RA95AlreadyRunning;
  58. HINSTANCE ProgramInstance;
  59. void Check_Use_Compressed_Shapes (void);
  60. void Read_Setup_Options(RawFileClass *config_file);
  61. bool VideoBackBufferAllowed = true;
  62. #else
  63. BOOL Init_Timer_System(unsigned int freq, int partial = FALSE);
  64. BOOL Remove_Timer_System(VOID);
  65. #endif //WIN32
  66. const char* Game_Registry_Key();
  67. #if (ENGLISH)
  68. #define WINDOW_NAME "Red Alert"
  69. #endif
  70. #if (FRENCH)
  71. #define WINDOW_NAME "Alerte Rouge"
  72. #endif
  73. #if (GERMAN)
  74. #define WINDOW_NAME "Alarmstufe Rot"
  75. #endif
  76. /***********************************************************************************************
  77. * main -- Initial startup routine (preps library systems). *
  78. * *
  79. * This is the routine that is first called when the program starts up. It basically *
  80. * handles the command line parsing and setting up library systems. *
  81. * *
  82. * INPUT: argc -- Number of command line arguments. *
  83. * *
  84. * argv -- Pointer to array of command line argument strings. *
  85. * *
  86. * OUTPUT: Returns with execution failure code (if any). *
  87. * *
  88. * WARNINGS: none *
  89. * *
  90. * HISTORY: *
  91. * 03/20/1995 JLB : Created. *
  92. *=============================================================================================*/
  93. #ifdef WIN32
  94. //int PASCAL WinMain(HINSTANCE, HINSTANCE, char *, int )
  95. int PASCAL WinMain ( HINSTANCE instance , HINSTANCE , char * command_line , int command_show )
  96. #else //WIN32
  97. int main(int argc, char * argv[])
  98. #endif //WIN32
  99. {
  100. #ifdef WIN32
  101. #ifndef MPEGMOVIE // Denzil 6/10/98
  102. DDSCAPS surface_capabilities;
  103. #endif
  104. /*
  105. ** First thing to do is check if there is another instance of Red Alert already running
  106. ** and if so, switch to the existing instance and terminate ourselves.
  107. */
  108. SpawnedFromWChat = false;
  109. if (RA95AlreadyRunning) { //Set in the DDEServer constructor
  110. //MessageBox (NULL, "Error - attempt to restart Red Alert 95 when already running.", "Red Alert", MB_ICONEXCLAMATION|MB_OK);
  111. HWND ccwindow;
  112. ccwindow = FindWindow (WINDOW_NAME, WINDOW_NAME);
  113. if (ccwindow) {
  114. SetForegroundWindow ( ccwindow );
  115. ShowWindow ( ccwindow, SW_RESTORE );
  116. }
  117. return (EXIT_SUCCESS);
  118. }
  119. #endif
  120. //printf("in program.\n");getch();
  121. //printf("ram free = %ld\n",Ram_Free(MEM_NORMAL));getch();
  122. #ifdef WIN32
  123. if (Ram_Free(MEM_NORMAL) < 7000000) {
  124. #else
  125. void *temp_mem = malloc (13*1024*1024);
  126. if (temp_mem) {
  127. free (temp_mem);
  128. }else{
  129. //if (Ram_Free(MEM_NORMAL) < 13000000) {
  130. // if (Ram_Free(MEM_NORMAL) < 3500000) {
  131. #endif
  132. printf (TEXT_NO_RAM);
  133. #ifndef WIN32
  134. printf (TEXT_USE_START_MENU);
  135. getch();
  136. #endif
  137. #if (0)
  138. /*
  139. ** Take a stab at finding out how much memory there is available.
  140. */
  141. for ( int mem = 13*1024*1024 ; mem >0 ; mem -=1024 ) {
  142. temp_mem = malloc (mem);
  143. if (temp_mem){
  144. free (temp_mem);
  145. printf ("Memory available: %d", mem);
  146. break;
  147. }
  148. }
  149. getch();
  150. #endif //(0)
  151. return(EXIT_FAILURE);
  152. }
  153. #ifdef WIN32
  154. if (strstr(command_line, "f:\\projects\\c&c0") != NULL ||
  155. strstr(command_line, "F:\\PROJECTS\\C&C0") != NULL) {
  156. MessageBox(0, "Playing off of the network is not allowed.", "Red Alert", MB_OK|MB_ICONSTOP);
  157. return(EXIT_FAILURE);
  158. }
  159. int argc; //Command line argument count
  160. unsigned command_scan;
  161. char command_char;
  162. char * argv[20]; //Pointers to command line arguments
  163. char path_to_exe[132];
  164. ProgramInstance = instance;
  165. /*
  166. ** Get the full path to the .EXE
  167. */
  168. GetModuleFileName (instance, &path_to_exe[0], 132);
  169. /*
  170. ** First argument is supposed to be a pointer to the .EXE that is running
  171. **
  172. */
  173. argc=1; //Set argument count to 1
  174. argv[0]=&path_to_exe[0]; //Set 1st command line argument to point to full path
  175. /*
  176. ** Get pointers to command line arguments just like if we were in DOS
  177. **
  178. ** The command line we get is cr/zero? terminated.
  179. **
  180. */
  181. command_scan=0;
  182. do {
  183. /*
  184. ** Scan for non-space character on command line
  185. */
  186. do {
  187. command_char = *( command_line+command_scan++ );
  188. } while ( command_char==' ' );
  189. if ( command_char!=0 && command_char != 13 ) {
  190. argv[argc++]=command_line+command_scan-1;
  191. /*
  192. ** Scan for space character on command line
  193. */
  194. do {
  195. command_char = *( command_line+command_scan++ );
  196. } while ( command_char!=' ' && command_char != 0 && command_char!=13 );
  197. *( command_line+command_scan-1 ) = 0;
  198. }
  199. } while ( command_char != 0 && command_char != 13 && argc<20 );
  200. #endif //WIN32
  201. /*
  202. ** Remember the current working directory and drive.
  203. */
  204. unsigned olddrive;
  205. char oldpath[PATH_MAX];
  206. getcwd(oldpath, sizeof(oldpath));
  207. _dos_getdrive(&olddrive);
  208. /*
  209. ** Change directory to the where the executable is located. Handle the
  210. ** case where there is no path attached to argv[0].
  211. */
  212. char drive[_MAX_DRIVE];
  213. char path[_MAX_PATH];
  214. unsigned drivecount;
  215. _splitpath(argv[0], drive, path, NULL, NULL);
  216. if (!drive[0]) {
  217. drive[0] = ('A' + olddrive)-1;
  218. }
  219. if (!path[0]) {
  220. strcpy(path, ".");
  221. }
  222. _dos_setdrive(toupper((drive[0])-'A')+1, &drivecount);
  223. if (path[strlen(path)-1] == '\\') {
  224. path[strlen(path)-1] = '\0';
  225. }
  226. chdir(path);
  227. #ifdef WOLAPI_INTEGRATION
  228. // Look for special wolapi install program, used after the patch to version 3, to install "Shared Internet Components".
  229. WIN32_FIND_DATA wfd;
  230. HANDLE hWOLSetupFile = FindFirstFile( "wolsetup.exe", &wfd );
  231. bool bWOLSetupFile = ( hWOLSetupFile != INVALID_HANDLE_VALUE );
  232. // if( bWOLSetupFile )
  233. // debugprint( "Found wolsetup.exe\n" );
  234. FindClose( hWOLSetupFile );
  235. // Look for special registry entry that tells us when the setup exe has done its thing.
  236. HKEY hKey;
  237. RegOpenKeyEx( HKEY_LOCAL_MACHINE, Game_Registry_Key(), 0, KEY_READ, &hKey );
  238. DWORD dwValue;
  239. DWORD dwBufSize = sizeof( DWORD );
  240. if( RegQueryValueEx( hKey, "WolapiInstallComplete", 0, NULL, (LPBYTE)&dwValue, &dwBufSize ) == ERROR_SUCCESS )
  241. {
  242. // debugprint( "Found WolapiInstallComplete in registry\n" );
  243. // Setup has finished. Delete the setup exe and remove reg key.
  244. if( bWOLSetupFile )
  245. {
  246. if( DeleteFile( "wolsetup.exe" ) )
  247. RegDeleteValue( hKey, "WolapiInstallComplete" );
  248. }
  249. else
  250. RegDeleteValue( hKey, "WolapiInstallComplete" );
  251. }
  252. RegCloseKey( hKey );
  253. // I've been having problems getting the patch to delete "conquer.eng", which is present in the game
  254. // directory for 1.08, but which must NOT be present for this version (Aftermath mix files provide the
  255. // string overrides that the 1.08 separate conquer.eng did before Aftermath).
  256. // Delete conquer.eng if it's found.
  257. if( FindFirstFile( "conquer.eng", &wfd ) != INVALID_HANDLE_VALUE )
  258. DeleteFile( "conquer.eng" );
  259. #endif
  260. if (Parse_Command_Line(argc, argv)) {
  261. #if(TEN)
  262. //
  263. // Only allow the TEN version of the game to run if the TEN
  264. // or AllowSoloPlayOptions arguments are specified.
  265. //
  266. if (Session.AllowSolo==0 && Session.Type != GAME_TEN) {
  267. #ifdef WIN32
  268. MessageBox(NULL, "Red Alert for TEN\n (c) 1996 Westwood Studios",
  269. "Red Alert", MB_OK);
  270. exit(0);
  271. #else
  272. printf("\n");
  273. printf(" Red Alert for TEN\n");
  274. printf(" (c) 1996 Westwood Studios\n");
  275. printf("\n");
  276. exit(0);
  277. #endif // WIN32
  278. }
  279. #endif // TEN
  280. #if(MPATH)
  281. //
  282. // Only allow the MPATH version of the game to run if the MPATH
  283. // or AllowSoloPlayOptions arguments are specified.
  284. //
  285. if (Session.AllowSolo==0 && Session.Type != GAME_MPATH) {
  286. #ifdef WIN32
  287. MessageBox(NULL, "Red Alert for MPATH\n (c) 1996 Westwood Studios",
  288. "Red Alert", MB_OK);
  289. exit(0);
  290. #else
  291. printf("\n");
  292. printf(" Red Alert for MPATH\n");
  293. printf(" (c) 1996 Westwood Studios\n");
  294. printf("\n");
  295. exit(0);
  296. #endif // WIN32
  297. }
  298. #endif // MPATH
  299. #ifdef WIN32
  300. WindowsTimer = new WinTimerClass(60, FALSE);
  301. int time_test = WindowsTimer->Get_System_Tick_Count();
  302. Sleep (1000);
  303. if (WindowsTimer->Get_System_Tick_Count() == time_test){
  304. MessageBox(0, TEXT_ERROR_TIMER, TEXT_SHORT_TITLE, MB_OK|MB_ICONSTOP);
  305. return(EXIT_FAILURE);
  306. }
  307. #else //WIN32
  308. Init_Timer_System(60, true);
  309. #endif //WIN32
  310. RawFileClass cfile(CONFIG_FILE_NAME);
  311. #ifndef WIN32
  312. Install_Keyboard_Interrupt(Get_RM_Keyboard_Address(), Get_RM_Keyboard_Size());
  313. #endif //WIN32
  314. #ifdef NEVER
  315. Keyboard->IsLibrary = true;
  316. if (Debug_Flag) {
  317. Keyboard_Attributes_On(DEBUGINT);
  318. }
  319. #endif
  320. Keyboard = new KeyboardClass();
  321. #ifdef WIN32
  322. /*
  323. ** If there is loads of memory then use uncompressed shapes
  324. */
  325. Check_Use_Compressed_Shapes();
  326. #endif
  327. /*
  328. ** If there is not enough disk space free, don't allow the product to run.
  329. */
  330. if (Disk_Space_Available() < INIT_FREE_DISK_SPACE) {
  331. #ifdef WIN32
  332. char disk_space_message [512];
  333. sprintf (disk_space_message, TEXT_CRITICALLY_LOW, (INIT_FREE_DISK_SPACE) / (1024 * 1024));
  334. int reply = MessageBox(NULL, disk_space_message, TEXT_SHORT_TITLE, MB_ICONQUESTION|MB_YESNO);
  335. if (reply == IDNO) {
  336. if ( WindowsTimer )
  337. delete WindowsTimer;
  338. return (EXIT_FAILURE);
  339. }
  340. #else
  341. printf(TEXT_INSUFFICIENT);
  342. printf(TEXT_MUST_HAVE, INIT_FREE_DISK_SPACE / (1024 * 1024));
  343. printf("\n");
  344. if (Keyboard) Keyboard->Get();
  345. // Keyboard::IsLibrary = false;
  346. Remove_Keyboard_Interrupt();
  347. Remove_Timer_System();
  348. return(EXIT_FAILURE);
  349. #endif
  350. }
  351. if (cfile.Is_Available()) {
  352. Read_Private_Config_Struct(cfile, &NewConfig);
  353. #ifdef WIN32
  354. /*
  355. ** Set the options as requested by the ccsetup program
  356. */
  357. Read_Setup_Options( &cfile );
  358. Create_Main_Window( instance , command_show , ScreenWidth , ScreenHeight );
  359. SoundOn = Audio_Init ( MainWindow , 16 , false , 11025*2 , 0 );
  360. #else //WIN32
  361. if (!Debug_Quiet) {
  362. Audio_Init(NewConfig.DigitCard,
  363. NewConfig.Port,
  364. NewConfig.IRQ,
  365. NewConfig.DMA,
  366. PLAYBACK_RATE_NORMAL,
  367. // (NewConfig.Speed) ? PLAYBACK_RATE_SLOW : PLAYBACK_RATE_NORMAL,
  368. NewConfig.BitsPerSample,
  369. // 4,
  370. (Get_CPU() < 5) ? 3 : 5,
  371. // (NewConfig.Speed) ? 3 : 5,
  372. NewConfig.Reverse);
  373. SoundOn = true;
  374. } else {
  375. Audio_Init(0, -1, -1, -1, PLAYBACK_RATE_NORMAL, 8, 5, false);
  376. }
  377. #endif //WIN32
  378. #ifdef WIN32
  379. #ifdef MPEGMOVIE // Denzil 6/10/98
  380. if (!InitDDraw())
  381. return (EXIT_FAILURE);
  382. #else
  383. BOOL video_success = FALSE;
  384. /*
  385. ** Set 640x400 video mode. If its not available then try for 640x480
  386. */
  387. if (ScreenHeight == 400) {
  388. if (Set_Video_Mode (MainWindow, ScreenWidth, ScreenHeight, 8)) {
  389. video_success = TRUE;
  390. } else {
  391. if (Set_Video_Mode (MainWindow, ScreenWidth, 480, 8)) {
  392. video_success = TRUE;
  393. ScreenHeight = 480;
  394. }
  395. }
  396. } else {
  397. if (Set_Video_Mode (MainWindow, ScreenWidth, ScreenHeight, 8)) {
  398. video_success = TRUE;
  399. }
  400. }
  401. if (!video_success) {
  402. MessageBox(MainWindow, TEXT_VIDEO_ERROR, TEXT_SHORT_TITLE, MB_ICONEXCLAMATION|MB_OK);
  403. if (WindowsTimer) delete WindowsTimer;
  404. //if (Palette) delete Palette;
  405. return (EXIT_FAILURE);
  406. }
  407. if (ScreenWidth==320) {
  408. VisiblePage.Init( ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)0);
  409. ModeXBuff.Init( ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)(GBC_VISIBLE | GBC_VIDEOMEM));
  410. } else {
  411. VisiblePage.Init( ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)(GBC_VISIBLE | GBC_VIDEOMEM));
  412. /*
  413. ** Check that we really got a video memory page. Failure is fatal.
  414. */
  415. memset (&surface_capabilities, 0, sizeof(surface_capabilities));
  416. VisiblePage.Get_DD_Surface()->GetCaps(&surface_capabilities);
  417. if (surface_capabilities.dwCaps & DDSCAPS_SYSTEMMEMORY) {
  418. /*
  419. ** Aaaarrgghh!
  420. */
  421. WWDebugString(TEXT_DDRAW_ERROR);WWDebugString("\n");
  422. MessageBox(MainWindow, TEXT_DDRAW_ERROR, TEXT_SHORT_TITLE, MB_ICONEXCLAMATION|MB_OK);
  423. if (WindowsTimer) delete WindowsTimer;
  424. return (EXIT_FAILURE);
  425. }
  426. /*
  427. ** If we have enough left then put the hidpage in video memory unless...
  428. **
  429. ** If there is no blitter then we will get better performance with a system
  430. ** memory hidpage
  431. **
  432. ** Use a system memory page if the user has specified it via the ccsetup program.
  433. */
  434. unsigned video_memory = Get_Free_Video_Memory();
  435. unsigned video_capabilities = Get_Video_Hardware_Capabilities();
  436. if (video_memory < ScreenWidth*ScreenHeight ||
  437. (! (video_capabilities & VIDEO_BLITTER)) ||
  438. (video_capabilities & VIDEO_NO_HARDWARE_ASSIST) ||
  439. !VideoBackBufferAllowed) {
  440. HiddenPage.Init (ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)0);
  441. } else {
  442. //HiddenPage.Init (ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)0);
  443. HiddenPage.Init (ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)GBC_VIDEOMEM);
  444. /*
  445. ** Make sure we really got a video memory hid page. If we didnt then things
  446. ** will run very slowly.
  447. */
  448. memset (&surface_capabilities, 0, sizeof(surface_capabilities));
  449. HiddenPage.Get_DD_Surface()->GetCaps(&surface_capabilities);
  450. if (surface_capabilities.dwCaps & DDSCAPS_SYSTEMMEMORY) {
  451. /*
  452. ** Oh dear, big trub. This must be an IBM crAptiva or something similarly cruddy.
  453. ** We must redo the Hidden Page as system memory.
  454. */
  455. AllSurfaces.Remove_DD_Surface(HiddenPage.Get_DD_Surface()); // Remove the old surface from the AllSurfaces list
  456. HiddenPage.Get_DD_Surface()->Release();
  457. HiddenPage.Init (ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)0);
  458. } else {
  459. VisiblePage.Attach_DD_Surface(&HiddenPage);
  460. }
  461. }
  462. }
  463. ScreenHeight = 400;
  464. if (VisiblePage.Get_Height() == 480) {
  465. SeenBuff.Attach(&VisiblePage, 0, 40, 640, 400);
  466. HidPage.Attach(&HiddenPage, 0, 40, 640, 400);
  467. } else {
  468. SeenBuff.Attach(&VisiblePage, 0, 0, 640, 400);
  469. HidPage.Attach(&HiddenPage, 0, 0, 640, 400);
  470. }
  471. #endif // MPEGMOVIE - Denzil 6/10/98
  472. Options.Adjust_Variables_For_Resolution();
  473. /*
  474. ** Install the memory error handler
  475. */
  476. Memory_Error = &Memory_Error_Handler;
  477. WindowList[0][WINDOWWIDTH] = SeenBuff.Get_Width();
  478. WindowList[0][WINDOWHEIGHT] = SeenBuff.Get_Height();
  479. WindowList[WINDOW_EDITOR][WINDOWWIDTH] = SeenBuff.Get_Width();
  480. WindowList[WINDOW_EDITOR][WINDOWHEIGHT]= SeenBuff.Get_Height();
  481. WWMouse = new WWMouseClass(&SeenBuff, 48, 48);
  482. MouseInstalled = TRUE;
  483. CDFileClass::Set_CD_Drive (CDList.Get_First_CD_Drive());
  484. #else //WIN32
  485. Options.Adjust_Variables_For_Resolution();
  486. if (!Special.IsFromInstall) {
  487. BlackPalette.Set();
  488. // Set_Palette(Palette);
  489. Set_Video_Mode(MCGA_MODE);
  490. }
  491. MouseInstalled = Install_Mouse(32, 24, 320, 200);
  492. #endif //WIN32
  493. /*
  494. ** See if we should run the intro
  495. */
  496. INIClass ini;
  497. ini.Load(cfile);
  498. /*
  499. ** Check for forced intro movie run disabling. If the conquer
  500. ** configuration file says "no", then don't run the intro.
  501. ** Don't do this for TEN & MPath.
  502. */
  503. if (!Special.IsFromInstall && Session.Type != GAME_TEN &&
  504. Session.Type != GAME_MPATH) {
  505. Special.IsFromInstall = ini.Get_Bool("Intro", "PlayIntro", true);
  506. }
  507. SlowPalette = ini.Get_Bool("Options", "SlowPalette", false);
  508. /*
  509. ** Regardless of whether we should run it or not, here we're
  510. ** gonna change it to say "no" in the future.
  511. */
  512. if (Special.IsFromInstall) {
  513. BreakoutAllowed = true;
  514. // BreakoutAllowed = false;
  515. ini.Put_Bool("Intro", "PlayIntro", false);
  516. ini.Save(cfile);
  517. }
  518. #ifndef WOLAPI_INTEGRATION
  519. #ifdef WIN32
  520. /*
  521. ** If WChat has been trying to send us a game start packet then receive it and
  522. ** flag that we were spawned from WCHat so we dont play the into movie.
  523. */
  524. if (DDEServer.Get_MPlayer_Game_Info()){
  525. Check_From_WChat(NULL);
  526. }else{
  527. //Check_From_WChat("C&CSPAWN.INI");
  528. //if (Special.IsFromWChat){
  529. // DDEServer.Disable();
  530. //}
  531. }
  532. #endif //WIN32
  533. #endif
  534. /*
  535. ** If the intro is being run for the first time, then don't
  536. ** allow breaking out of it with the <ESC> key.
  537. */
  538. if (Special.IsFromInstall) {
  539. BreakoutAllowed = true;
  540. // BreakoutAllowed = false;
  541. }
  542. Memory_Error_Exit = Print_Error_End_Exit;
  543. Main_Game(argc, argv);
  544. #ifdef MPEGMOVIE // Denzil 6/15/98
  545. if (MpgSettings != NULL)
  546. delete MpgSettings;
  547. #ifdef MCIMPEG
  548. if (MciMovie != NULL)
  549. delete MciMovie;
  550. #endif
  551. #endif
  552. #ifdef WIN32
  553. VisiblePage.Clear();
  554. HiddenPage.Clear();
  555. #else //WIN32
  556. SeenPage.Clear();
  557. Set_Video_Mode(RESET_MODE);
  558. #endif //WIN32
  559. Memory_Error_Exit = Print_Error_Exit;
  560. #ifdef WIN32
  561. /*
  562. ** Flag that this is a clean shutdown (not killed with Ctrl-Alt-Del)
  563. */
  564. ReadyToQuit = 1;
  565. /*
  566. ** Post a message to our message handler to tell it to clean up.
  567. */
  568. PostMessage(MainWindow, WM_DESTROY, 0, 0);
  569. /*
  570. ** Wait until the message handler has dealt with the message
  571. */
  572. do
  573. {
  574. Keyboard->Check();
  575. }while (ReadyToQuit == 1);
  576. return (EXIT_SUCCESS);
  577. #else //WIN32
  578. Remove_Mouse();
  579. Sound_End();
  580. #endif //WIN32
  581. } else {
  582. puts(TEXT_SETUP_FIRST);
  583. Keyboard->Get();
  584. }
  585. #ifdef WIN32
  586. if (WindowsTimer) {
  587. delete WindowsTimer;
  588. WindowsTimer = NULL;
  589. }
  590. #else //WIN32
  591. Remove_Keyboard_Interrupt();
  592. Remove_Timer_System();
  593. #endif //WIN32
  594. }
  595. /*
  596. ** Restore the current drive and directory.
  597. */
  598. #ifndef WIN32
  599. _dos_setdrive(olddrive, &drivecount);
  600. chdir(oldpath);
  601. #endif //WIN32
  602. return(EXIT_SUCCESS);
  603. }
  604. /* Initialize DirectDraw and surfaces */
  605. bool InitDDraw(void)
  606. {
  607. DDSCAPS surface_capabilities;
  608. BOOL video_success = FALSE;
  609. /* Set 640x400 video mode. If its not available then try for 640x480 */
  610. if (ScreenHeight == 400)
  611. {
  612. if (Set_Video_Mode(MainWindow, ScreenWidth, ScreenHeight, 8))
  613. {
  614. video_success = TRUE;
  615. }
  616. else
  617. {
  618. if (Set_Video_Mode(MainWindow, ScreenWidth, 480, 8))
  619. {
  620. video_success = TRUE;
  621. ScreenHeight = 480;
  622. }
  623. }
  624. }
  625. else
  626. {
  627. if (Set_Video_Mode(MainWindow, ScreenWidth, ScreenHeight, 8))
  628. {
  629. video_success = TRUE;
  630. }
  631. }
  632. if (!video_success)
  633. {
  634. MessageBox(MainWindow, TEXT_VIDEO_ERROR, TEXT_SHORT_TITLE, MB_ICONEXCLAMATION|MB_OK);
  635. if (WindowsTimer)
  636. delete WindowsTimer;
  637. return false;
  638. }
  639. if (ScreenWidth == 320)
  640. {
  641. VisiblePage.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)0);
  642. ModeXBuff.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)(GBC_VISIBLE|GBC_VIDEOMEM));
  643. }
  644. else
  645. {
  646. VisiblePage.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)(GBC_VISIBLE|GBC_VIDEOMEM));
  647. /* Check that we really got a video memory page. Failure is fatal. */
  648. memset(&surface_capabilities, 0, sizeof(surface_capabilities));
  649. VisiblePage.Get_DD_Surface()->GetCaps(&surface_capabilities);
  650. if (surface_capabilities.dwCaps & DDSCAPS_SYSTEMMEMORY)
  651. {
  652. /* Aaaarrgghh! */
  653. WWDebugString(TEXT_DDRAW_ERROR);WWDebugString("\n");
  654. MessageBox(MainWindow, TEXT_DDRAW_ERROR, TEXT_SHORT_TITLE, MB_ICONEXCLAMATION|MB_OK);
  655. if (WindowsTimer)
  656. delete WindowsTimer;
  657. return false;
  658. }
  659. /* If we have enough left then put the hidpage in video memory unless...
  660. *
  661. * If there is no blitter then we will get better performance with a system
  662. * memory hidpage
  663. *
  664. * Use a system memory page if the user has specified it via the ccsetup program.
  665. */
  666. unsigned video_memory = Get_Free_Video_Memory();
  667. unsigned video_capabilities = Get_Video_Hardware_Capabilities();
  668. if (video_memory < ScreenWidth * ScreenHeight
  669. || (!(video_capabilities & VIDEO_BLITTER))
  670. || (video_capabilities & VIDEO_NO_HARDWARE_ASSIST)
  671. || !VideoBackBufferAllowed)
  672. {
  673. HiddenPage.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)0);
  674. }
  675. else
  676. {
  677. HiddenPage.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)GBC_VIDEOMEM);
  678. /* Make sure we really got a video memory hid page. If we didnt then things
  679. * will run very slowly.
  680. */
  681. memset(&surface_capabilities, 0, sizeof(surface_capabilities));
  682. HiddenPage.Get_DD_Surface()->GetCaps(&surface_capabilities);
  683. if (surface_capabilities.dwCaps & DDSCAPS_SYSTEMMEMORY)
  684. {
  685. /* Oh dear, big trub. This must be an IBM crAptiva or something similarly cruddy.
  686. * We must redo the Hidden Page as system memory.
  687. */
  688. AllSurfaces.Remove_DD_Surface(HiddenPage.Get_DD_Surface()); // Remove the old surface from the AllSurfaces list
  689. HiddenPage.Get_DD_Surface()->Release();
  690. HiddenPage.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)0);
  691. }
  692. else
  693. {
  694. VisiblePage.Attach_DD_Surface(&HiddenPage);
  695. }
  696. }
  697. }
  698. ScreenHeight = 400;
  699. if (VisiblePage.Get_Height() == 480)
  700. {
  701. SeenBuff.Attach(&VisiblePage, 0, 40, 640, 400);
  702. HidPage.Attach(&HiddenPage, 0, 40, 640, 400);
  703. }
  704. else
  705. {
  706. SeenBuff.Attach(&VisiblePage, 0, 0, 640, 400);
  707. HidPage.Attach(&HiddenPage, 0, 0, 640, 400);
  708. }
  709. return true;
  710. }
  711. /***********************************************************************************************
  712. * Prog_End -- Cleans up library systems in prep for game exit. *
  713. * *
  714. * This routine should be called before the game terminates. It handles cleaning up *
  715. * library systems so that a graceful return to the host operating system is achieved. *
  716. * *
  717. * INPUT: none *
  718. * *
  719. * OUTPUT: none *
  720. * *
  721. * WARNINGS: none *
  722. * *
  723. * HISTORY: *
  724. * 03/20/1995 JLB : Created. *
  725. *=============================================================================================*/
  726. #ifdef WIN32
  727. void __cdecl Prog_End(void)
  728. {
  729. Sound_End();
  730. if (WWMouse) {
  731. delete WWMouse;
  732. WWMouse = NULL;
  733. }
  734. if (WindowsTimer) {
  735. delete WindowsTimer;
  736. WindowsTimer = NULL;
  737. }
  738. }
  739. #else //WIN32
  740. void Prog_End(void)
  741. {
  742. if (Session.Type == GAME_MODEM || Session.Type == GAME_NULL_MODEM) {
  743. NullModem.Change_IRQ_Priority(0);
  744. }
  745. Set_Video_Mode(RESET_MODE);
  746. Remove_Keyboard_Interrupt();
  747. Remove_Mouse();
  748. Sound_End();
  749. Remove_Timer_System();
  750. }
  751. #endif //WIN32
  752. void Print_Error_End_Exit(char * string)
  753. {
  754. Prog_End();
  755. printf( "%s\n", string );
  756. exit(1);
  757. }
  758. void Print_Error_Exit(char * string)
  759. {
  760. printf( "%s\n", string );
  761. exit(1);
  762. }
  763. /***********************************************************************************************
  764. * Emergency_Exit -- Function to call when we want to exit unexpectedly. *
  765. * Use this function instead of exit(n) so everything is properly cleaned up.*
  766. * *
  767. * *
  768. * INPUT: Code to return to the OS *
  769. * *
  770. * OUTPUT: Nothing *
  771. * *
  772. * WARNINGS: None *
  773. * *
  774. * HISTORY: *
  775. * 3/13/97 1:32AM ST : Created *
  776. *=============================================================================================*/
  777. void Emergency_Exit ( int code )
  778. {
  779. #ifdef WIN32
  780. /*
  781. ** Clear out the video buffers so we dont glitch when we lose focus
  782. */
  783. VisiblePage.Clear();
  784. HiddenPage.Clear();
  785. BlackPalette.Set();
  786. Memory_Error_Exit = Print_Error_Exit;
  787. /*
  788. ** Flag that this is an emergency shut down - not a clean shutdown but
  789. ** not killed with Ctrl-Alt-Del either.
  790. */
  791. ReadyToQuit = 3;
  792. /*
  793. ** Post a message to our message handler to tell it to clean up.
  794. */
  795. PostMessage(MainWindow, WM_DESTROY, 0, 0);
  796. /*
  797. ** Wait until the message handler has dealt with the message
  798. */
  799. do
  800. {
  801. Keyboard->Check();
  802. }while (ReadyToQuit == 3);
  803. #else //WIN32
  804. /*
  805. ** Do the DOS end
  806. */
  807. Prog_End();
  808. #endif //WIN32
  809. exit ( code );
  810. }
  811. #ifdef WIN32
  812. /***********************************************************************************************
  813. * Read_Setup_Options -- Read stuff in from the INI file that we need to know sooner *
  814. * *
  815. * *
  816. * *
  817. * INPUT: Ptr to config file class *
  818. * *
  819. * OUTPUT: Nothing *
  820. * *
  821. * WARNINGS: None *
  822. * *
  823. * HISTORY: *
  824. * 6/7/96 4:09PM ST : Created *
  825. * 09/30/1996 JLB : Uses INI class. *
  826. *=============================================================================================*/
  827. void Read_Setup_Options( RawFileClass *config_file )
  828. {
  829. if (config_file->Is_Available()) {
  830. INIClass ini;
  831. ini.Load(*config_file);
  832. /*
  833. ** Read in the boolean options
  834. */
  835. VideoBackBufferAllowed = ini.Get_Bool("Options", "VideoBackBuffer", true);
  836. AllowHardwareBlitFills = ini.Get_Bool("Options", "HardwareFills", true);
  837. ScreenHeight = ini.Get_Bool("Options", "Resolution", false) ? 480 : 400;
  838. /*
  839. ** See if an alternative socket number has been specified
  840. */
  841. int socket = ini.Get_Int("Options", "Socket", 0);
  842. if (socket >0 ) {
  843. socket += 0x4000;
  844. if (socket >= 0x4000 && socket < 0x8000) {
  845. Ipx.Set_Socket (socket);
  846. }
  847. }
  848. /*
  849. ** See if a destination network has been specified
  850. */
  851. char netbuf [512];
  852. memset(netbuf, 0, sizeof(netbuf));
  853. char * netptr = netbuf;
  854. bool found = ini.Get_String("Options", "DestNet", NULL, netbuf, sizeof(netbuf));
  855. if (found && netptr != NULL && strlen(netbuf)) {
  856. NetNumType net;
  857. NetNodeType node;
  858. /*
  859. ** Scan the string, pulling off each address piece
  860. */
  861. int i = 0;
  862. char * p = strtok(netbuf,".");
  863. int x;
  864. while (p != NULL) {
  865. sscanf(p,"%x",&x); // convert from hex string to int
  866. if (i < 4) {
  867. net[i] = (char)x; // fill NetNum
  868. } else {
  869. node[i-4] = (char)x; // fill NetNode
  870. }
  871. i++;
  872. p = strtok(NULL,".");
  873. }
  874. /*
  875. ** If all the address components were successfully read, fill in the
  876. ** BridgeNet with a broadcast address to the network across the bridge.
  877. */
  878. if (i >= 4) {
  879. Session.IsBridge = 1;
  880. memset(node, 0xff, 6);
  881. Session.BridgeNet = IPXAddressClass(net, node);
  882. }
  883. }
  884. }
  885. }
  886. void Get_OS_Version (void)
  887. {
  888. WindowsNT = ((GetVersion() & 0x80000000) == 0) ? true : false;
  889. #if (0)
  890. OSVERSIONINFO osversion;
  891. if ( GetVersionEx (&osversion) ){
  892. WindowsNT = (osversion.dwPlatformId == VER_PLATFORM_WIN32_NT) ? true : false;
  893. OutputDebugString ("RA95 - Got OS version\n");
  894. }else{
  895. OutputDebugString ("RA95 - Failed to get OS version\n");
  896. char fuck [128];
  897. sprintf (fuck,"RA95 - Error code is %d\n", GetLastError());
  898. OutputDebugString (fuck);
  899. }
  900. #endif //(0)
  901. }
  902. #endif //WIN32