| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217 |
- //
- // Copyright 2020 Electronic Arts Inc.
- //
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code 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.
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
- // in the hope that it will be useful, but with permitted additional restrictions
- // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
- // distributed with this program. You should have received a copy of the
- // GNU General Public License along with permitted additional restrictions
- // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
- /* $Header: /counterstrike/STARTUP.CPP 6 3/15/97 7:18p Steve_tall $ */
- /***********************************************************************************************
- *** 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 : Command & Conquer *
- * *
- * File Name : STARTUP.CPP *
- * *
- * Programmer : Joe L. Bostic *
- * *
- * Start Date : October 3, 1994 *
- * *
- * Last Update : September 30, 1996 [JLB] *
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * Prog_End -- Cleans up library systems in prep for game exit. *
- * main -- Initial startup routine (preps library systems). *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "function.h"
- #include <conio.h>
- #include <io.h>
- #ifdef WIN32
- #include "ccdde.h"
- #include "ipx95.h"
- #endif //WIN32
- #ifdef MCIMPEG // Denzil 6/15/98
- #include "mcimovie.h"
- #endif
- #ifdef WOLAPI_INTEGRATION
- //#include "WolDebug.h"
- #endif
- extern char RedAlertINI[_MAX_PATH];
- bool Read_Private_Config_Struct(FileClass & file, NewConfigType * config);
- void Print_Error_End_Exit(char * string);
- void Print_Error_Exit(char * string);
- #ifdef WIN32
- //WinTimerClass * WinTimer;
- extern void Create_Main_Window ( HANDLE instance , int command_show , int width , int height);
- extern bool RA95AlreadyRunning;
- HINSTANCE ProgramInstance;
- void Check_Use_Compressed_Shapes (void);
- void Read_Setup_Options(RawFileClass *config_file);
- bool VideoBackBufferAllowed = true;
- #else
- BOOL Init_Timer_System(unsigned int freq, int partial = FALSE);
- BOOL Remove_Timer_System(VOID);
- #endif //WIN32
- const char* Game_Registry_Key();
- #if (ENGLISH)
- #define WINDOW_NAME "Red Alert"
- #endif
- #if (FRENCH)
- #define WINDOW_NAME "Alerte Rouge"
- #endif
- #if (GERMAN)
- #define WINDOW_NAME "Alarmstufe Rot"
- #endif
- // Added. ST - 5/14/2019
- bool ProgEndCalled = false;
- extern "C"{
- extern char *BigShapeBufferStart;
- extern char *TheaterShapeBufferStart;
- extern BOOL UseBigShapeBuffer;
- extern bool IsTheaterShape;
- }
- extern void Free_Heaps(void);
- extern void DLL_Shutdown(void);
- BOOL WINAPI DllMain(HINSTANCE instance, unsigned int fdwReason, void *lpvReserved)
- {
- lpvReserved;
- switch (fdwReason) {
- case DLL_PROCESS_ATTACH:
- ProgramInstance = instance;
- break;
- case DLL_PROCESS_DETACH:
- if (WindowsTimer) {
- delete WindowsTimer;
- WindowsTimer = NULL;
- }
-
- /*
- ** Red Alert doesn't clean up memory. Do some of that here.
- */
- MFCD::Free_All();
- if (BigShapeBufferStart) {
- Free(BigShapeBufferStart);
- BigShapeBufferStart = NULL;
- }
- if (TheaterShapeBufferStart) {
- Free(TheaterShapeBufferStart);
- TheaterShapeBufferStart = NULL;
- }
- if (_ShapeBuffer) {
- delete [] _ShapeBuffer;
- _ShapeBuffer = NULL;
- }
- DLL_Shutdown();
- Free_Heaps();
- break;
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- break;
- }
-
- return true;
- }
- /***********************************************************************************************
- * main -- Initial startup routine (preps library systems). *
- * *
- * This is the routine that is first called when the program starts up. It basically *
- * handles the command line parsing and setting up library systems. *
- * *
- * INPUT: argc -- Number of command line arguments. *
- * *
- * argv -- Pointer to array of command line argument strings. *
- * *
- * OUTPUT: Returns with execution failure code (if any). *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 03/20/1995 JLB : Created. *
- *=============================================================================================*/
- #ifdef WIN32
- //int PASCAL WinMain(HINSTANCE, HINSTANCE, char *, int )
- //PG int PASCAL WinMain ( HINSTANCE instance , HINSTANCE , char * command_line , int command_show )
- int DLL_Startup(const char * command_line_in)
- #else //WIN32
- int main(int argc, char * argv[])
- #endif //WIN32
- {
- #ifdef WIN32
- RunningAsDLL = true;
- int command_show = SW_HIDE;
- HINSTANCE instance = ProgramInstance;
- char command_line[1024];
- strcpy(command_line, command_line_in);
- #ifndef MPEGMOVIE // Denzil 6/10/98
- //PG DDSCAPS surface_capabilities;
- #endif
- /*
- ** First thing to do is check if there is another instance of Red Alert already running
- ** and if so, switch to the existing instance and terminate ourselves.
- */
- SpawnedFromWChat = false;
- #if (0)//PG
- if (RA95AlreadyRunning) { //Set in the DDEServer constructor
- //MessageBox (NULL, "Error - attempt to restart Red Alert 95 when already running.", "Red Alert", MB_ICONEXCLAMATION|MB_OK);
- HWND ccwindow;
- ccwindow = FindWindow (WINDOW_NAME, WINDOW_NAME);
- if (ccwindow) {
- SetForegroundWindow ( ccwindow );
- ShowWindow ( ccwindow, SW_RESTORE );
- }
- return (EXIT_SUCCESS);
- }
- #endif
- #endif
- //printf("in program.\n");getch();
- //printf("ram free = %ld\n",Ram_Free(MEM_NORMAL));getch();
- #ifdef WIN32
- if (Ram_Free(MEM_NORMAL) < 7000000) {
- #else
- void *temp_mem = malloc (13*1024*1024);
- if (temp_mem) {
- free (temp_mem);
- }else{
- //if (Ram_Free(MEM_NORMAL) < 13000000) {
- // if (Ram_Free(MEM_NORMAL) < 3500000) {
- #endif
- printf (TEXT_NO_RAM);
- #ifndef WIN32
- printf (TEXT_USE_START_MENU);
- getch();
- #endif
- #if (0)
- /*
- ** Take a stab at finding out how much memory there is available.
- */
- for ( int mem = 13*1024*1024 ; mem >0 ; mem -=1024 ) {
- temp_mem = malloc (mem);
- if (temp_mem){
- free (temp_mem);
- printf ("Memory available: %d", mem);
- break;
- }
- }
- getch();
- #endif //(0)
- return(EXIT_FAILURE);
- }
- #ifdef WIN32
- if (strstr(command_line, "f:\\projects\\c&c0") != NULL ||
- strstr(command_line, "F:\\PROJECTS\\C&C0") != NULL) {
- MessageBox(0, "Playing off of the network is not allowed.", "Red Alert", MB_OK|MB_ICONSTOP);
- return(EXIT_FAILURE);
- }
- int argc; //Command line argument count
- unsigned command_scan;
- char command_char;
- char * argv[20]; //Pointers to command line arguments
- char path_to_exe[132];
- ProgramInstance = instance;
- /*
- ** Get the full path to the .EXE
- */
- GetModuleFileName (instance, &path_to_exe[0], 132);
- /*
- ** First argument is supposed to be a pointer to the .EXE that is running
- **
- */
- argc=1; //Set argument count to 1
- argv[0]=&path_to_exe[0]; //Set 1st command line argument to point to full path
- /*
- ** Get pointers to command line arguments just like if we were in DOS
- **
- ** The command line we get is cr/zero? terminated.
- **
- */
- command_scan=0;
- do {
- /*
- ** Scan for non-space character on command line
- */
- do {
- command_char = *( command_line+command_scan++ );
- } while ( command_char==' ' );
- if ( command_char!=0 && command_char != 13 ) {
- argv[argc++]=command_line+command_scan-1;
- /*
- ** Scan for space character on command line
- */
- bool in_quotes = false;
- do {
- command_char = *( command_line+command_scan++ );
- if (command_char == '"') {
- in_quotes = !in_quotes;
- }
- } while ( (in_quotes || command_char!=' ') && command_char != 0 && command_char!=13 );
- *( command_line+command_scan-1 ) = 0;
- }
- } while ( command_char != 0 && command_char != 13 && argc<20 );
- #endif //WIN32
- /*
- ** Remember the current working directory and drive.
- */
- #if (0)//PG
- unsigned olddrive;
- char oldpath[MAX_PATH];
- getcwd(oldpath, sizeof(oldpath));
- _dos_getdrive(&olddrive);
- /*
- ** Change directory to the where the executable is located. Handle the
- ** case where there is no path attached to argv[0].
- */
- char drive[_MAX_DRIVE];
- char path[_MAX_PATH];
- unsigned drivecount;
- _splitpath(argv[0], drive, path, NULL, NULL);
- if (!drive[0]) {
- drive[0] = ('A' + olddrive)-1;
- }
- if (!path[0]) {
- strcpy(path, ".");
- }
- _dos_setdrive(toupper((drive[0])-'A')+1, &drivecount);
- if (path[strlen(path)-1] == '\\') {
- path[strlen(path)-1] = '\0';
- }
- chdir(path);
- #endif
- #ifdef WOLAPI_INTEGRATION
- // Look for special wolapi install program, used after the patch to version 3, to install "Shared Internet Components".
- WIN32_FIND_DATA wfd;
- HANDLE hWOLSetupFile = FindFirstFile( "wolsetup.exe", &wfd );
- bool bWOLSetupFile = ( hWOLSetupFile != INVALID_HANDLE_VALUE );
- // if( bWOLSetupFile )
- // debugprint( "Found wolsetup.exe\n" );
- FindClose( hWOLSetupFile );
- // Look for special registry entry that tells us when the setup exe has done its thing.
- HKEY hKey;
- RegOpenKeyEx( HKEY_LOCAL_MACHINE, Game_Registry_Key(), 0, KEY_READ, &hKey );
- DWORD dwValue;
- DWORD dwBufSize = sizeof( DWORD );
- if( RegQueryValueEx( hKey, "WolapiInstallComplete", 0, NULL, (LPBYTE)&dwValue, &dwBufSize ) == ERROR_SUCCESS )
- {
- // debugprint( "Found WolapiInstallComplete in registry\n" );
- // Setup has finished. Delete the setup exe and remove reg key.
- if( bWOLSetupFile )
- {
- if( DeleteFile( "wolsetup.exe" ) )
- RegDeleteValue( hKey, "WolapiInstallComplete" );
- }
- else
- RegDeleteValue( hKey, "WolapiInstallComplete" );
- }
- RegCloseKey( hKey );
- // I've been having problems getting the patch to delete "conquer.eng", which is present in the game
- // directory for 1.08, but which must NOT be present for this version (Aftermath mix files provide the
- // string overrides that the 1.08 separate conquer.eng did before Aftermath).
- // Delete conquer.eng if it's found.
- if( FindFirstFile( "conquer.eng", &wfd ) != INVALID_HANDLE_VALUE )
- DeleteFile( "conquer.eng" );
- #endif
- if (Parse_Command_Line(argc, argv)) {
- #if(TEN)
- //
- // Only allow the TEN version of the game to run if the TEN
- // or AllowSoloPlayOptions arguments are specified.
- //
- if (Session.AllowSolo==0 && Session.Type != GAME_TEN) {
- #ifdef WIN32
- MessageBox(NULL, "Red Alert for TEN\n (c) 1996 Westwood Studios",
- "Red Alert", MB_OK);
- exit(0);
- #else
- printf("\n");
- printf(" Red Alert for TEN\n");
- printf(" (c) 1996 Westwood Studios\n");
- printf("\n");
- exit(0);
- #endif // WIN32
- }
- #endif // TEN
- #if(MPATH)
- //
- // Only allow the MPATH version of the game to run if the MPATH
- // or AllowSoloPlayOptions arguments are specified.
- //
- if (Session.AllowSolo==0 && Session.Type != GAME_MPATH) {
- #ifdef WIN32
- MessageBox(NULL, "Red Alert for MPATH\n (c) 1996 Westwood Studios",
- "Red Alert", MB_OK);
- exit(0);
- #else
- printf("\n");
- printf(" Red Alert for MPATH\n");
- printf(" (c) 1996 Westwood Studios\n");
- printf("\n");
- exit(0);
- #endif // WIN32
- }
- #endif // MPATH
- #ifdef WIN32
- WindowsTimer = new WinTimerClass(60, FALSE);
- #if (0)//PG
- int time_test = WindowsTimer->Get_System_Tick_Count();
- Sleep (1000);
- if (WindowsTimer->Get_System_Tick_Count() == time_test){
- MessageBox(0, TEXT_ERROR_TIMER, TEXT_SHORT_TITLE, MB_OK|MB_ICONSTOP);
- return(EXIT_FAILURE);
- }
- #endif
- #else //WIN32
- Init_Timer_System(60, true);
- #endif //WIN32
- ////////////////////////////////////////
- // The editor needs to load the Red Alert ini file from a different location than the real game. - 7/18/2019 JAS
- char* red_alert_file_path = nullptr;
- if (RunningFromEditor)
- {
- red_alert_file_path = RedAlertINI;
- }
- else
- {
- red_alert_file_path = CONFIG_FILE_NAME;
- }
- RawFileClass cfile(red_alert_file_path);
- //RawFileClass cfile(CONFIG_FILE_NAME);
- // end of change - 7/18/2019 JAS
- ////////////////////////////////////////
- #ifndef WIN32
- Install_Keyboard_Interrupt(Get_RM_Keyboard_Address(), Get_RM_Keyboard_Size());
- #endif //WIN32
- #ifdef NEVER
- Keyboard->IsLibrary = true;
- if (Debug_Flag) {
- Keyboard_Attributes_On(DEBUGINT);
- }
- #endif
- Keyboard = new KeyboardClass();
- #ifdef WIN32
- /*
- ** If there is loads of memory then use uncompressed shapes
- */
- Check_Use_Compressed_Shapes();
- #endif
- /*
- ** If there is not enough disk space free, don't allow the product to run.
- */
- if (Disk_Space_Available() < INIT_FREE_DISK_SPACE) {
- #ifdef WIN32
- #if (0)//PG
- char disk_space_message [512];
- sprintf(disk_space_message, TEXT_CRITICALLY_LOW); //PG , (INIT_FREE_DISK_SPACE) / (1024 * 1024));
- int reply = MessageBox(NULL, disk_space_message, TEXT_SHORT_TITLE, MB_ICONQUESTION|MB_YESNO);
- if (reply == IDNO) {
- if ( WindowsTimer )
- delete WindowsTimer;
- return (EXIT_FAILURE);
- }
- #endif
- #else
- printf(TEXT_INSUFFICIENT);
- printf(TEXT_MUST_HAVE, INIT_FREE_DISK_SPACE / (1024 * 1024));
- printf("\n");
- if (Keyboard) Keyboard->Get();
- // Keyboard::IsLibrary = false;
- Remove_Keyboard_Interrupt();
- Remove_Timer_System();
- return(EXIT_FAILURE);
- #endif
- }
- if (cfile.Is_Available()) {
- Read_Private_Config_Struct(cfile, &NewConfig);
- #ifdef WIN32
- /*
- ** Set the options as requested by the ccsetup program
- */
- Read_Setup_Options( &cfile );
- Create_Main_Window( instance , command_show , ScreenWidth , ScreenHeight );
- SoundOn = Audio_Init ( MainWindow , 16 , false , 11025*2 , 0 );
- #else //WIN32
- if (!Debug_Quiet) {
- Audio_Init(NewConfig.DigitCard,
- NewConfig.Port,
- NewConfig.IRQ,
- NewConfig.DMA,
- PLAYBACK_RATE_NORMAL,
- // (NewConfig.Speed) ? PLAYBACK_RATE_SLOW : PLAYBACK_RATE_NORMAL,
- NewConfig.BitsPerSample,
- // 4,
- (Get_CPU() < 5) ? 3 : 5,
- // (NewConfig.Speed) ? 3 : 5,
- NewConfig.Reverse);
- SoundOn = true;
- } else {
- Audio_Init(0, -1, -1, -1, PLAYBACK_RATE_NORMAL, 8, 5, false);
- }
- #endif //WIN32
- #ifdef WIN32
- #ifdef MPEGMOVIE // Denzil 6/10/98
- if (!InitDDraw())
- return (EXIT_FAILURE);
- #else
- BOOL video_success = FALSE;
- /*
- ** Set 640x400 video mode. If its not available then try for 640x480
- */
- if (ScreenHeight == 400) {
- if (Set_Video_Mode (MainWindow, ScreenWidth, ScreenHeight, 8)) {
- video_success = TRUE;
- } else {
- if (Set_Video_Mode (MainWindow, ScreenWidth, 480, 8)) {
- video_success = TRUE;
- ScreenHeight = 480;
- }
- }
- } else {
- if (Set_Video_Mode (MainWindow, ScreenWidth, ScreenHeight, 8)) {
- video_success = TRUE;
- }
- }
- if (!video_success) {
- MessageBox(MainWindow, TEXT_VIDEO_ERROR, TEXT_SHORT_TITLE, MB_ICONEXCLAMATION|MB_OK);
- if (WindowsTimer) delete WindowsTimer;
- //if (Palette) delete Palette;
- return (EXIT_FAILURE);
- }
- if (ScreenWidth==320) {
- VisiblePage.Init( ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)0);
- ModeXBuff.Init( ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)(GBC_VISIBLE | GBC_VIDEOMEM));
- } else {
- #if (1) //ST - 1/3/2019 2:11PM
- VisiblePage.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)0);
- HiddenPage.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)0);
- #else
- VisiblePage.Init( ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)(GBC_VISIBLE | GBC_VIDEOMEM));
- /*
- ** Check that we really got a video memory page. Failure is fatal.
- */
- memset (&surface_capabilities, 0, sizeof(surface_capabilities));
- VisiblePage.Get_DD_Surface()->GetCaps(&surface_capabilities);
- if (surface_capabilities.dwCaps & DDSCAPS_SYSTEMMEMORY) {
- /*
- ** Aaaarrgghh!
- */
- WWDebugString(TEXT_DDRAW_ERROR);WWDebugString("\n");
- MessageBox(MainWindow, TEXT_DDRAW_ERROR, TEXT_SHORT_TITLE, MB_ICONEXCLAMATION|MB_OK);
- if (WindowsTimer) delete WindowsTimer;
- return (EXIT_FAILURE);
- }
- /*
- ** If we have enough left then put the hidpage in video memory unless...
- **
- ** If there is no blitter then we will get better performance with a system
- ** memory hidpage
- **
- ** Use a system memory page if the user has specified it via the ccsetup program.
- */
- unsigned video_memory = Get_Free_Video_Memory();
- unsigned video_capabilities = Get_Video_Hardware_Capabilities();
- if (video_memory < (unsigned int)(ScreenWidth*ScreenHeight) ||
- (! (video_capabilities & VIDEO_BLITTER)) ||
- (video_capabilities & VIDEO_NO_HARDWARE_ASSIST) ||
- !VideoBackBufferAllowed) {
- HiddenPage.Init (ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)0);
- } else {
- //HiddenPage.Init (ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)0);
- HiddenPage.Init (ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)GBC_VIDEOMEM);
- /*
- ** Make sure we really got a video memory hid page. If we didnt then things
- ** will run very slowly.
- */
- memset (&surface_capabilities, 0, sizeof(surface_capabilities));
- HiddenPage.Get_DD_Surface()->GetCaps(&surface_capabilities);
- if (surface_capabilities.dwCaps & DDSCAPS_SYSTEMMEMORY) {
- /*
- ** Oh dear, big trub. This must be an IBM Aptiva or something similarly cruddy.
- ** We must redo the Hidden Page as system memory.
- */
- AllSurfaces.Remove_DD_Surface(HiddenPage.Get_DD_Surface()); // Remove the old surface from the AllSurfaces list
- HiddenPage.Get_DD_Surface()->Release();
- HiddenPage.Init (ScreenWidth , ScreenHeight , NULL , 0 , (GBC_Enum)0);
- } else {
- VisiblePage.Attach_DD_Surface(&HiddenPage);
- }
- }
- #endif
- }
- ScreenHeight = 3072;
- if (VisiblePage.Get_Height() == 480) {
- SeenBuff.Attach(&VisiblePage, 0, 40, 3072, 3072);
- HidPage.Attach(&HiddenPage, 0, 40, 3072, 3072);
- } else {
- SeenBuff.Attach(&VisiblePage, 0, 0, 3072, 3072);
- HidPage.Attach(&HiddenPage, 0, 0, 3072, 3072);
- }
- #endif // MPEGMOVIE - Denzil 6/10/98
-
- Options.Adjust_Variables_For_Resolution();
- /*
- ** Install the memory error handler
- */
- Memory_Error = &Memory_Error_Handler;
- WindowList[0][WINDOWWIDTH] = SeenBuff.Get_Width();
- WindowList[0][WINDOWHEIGHT] = SeenBuff.Get_Height();
- WindowList[WINDOW_EDITOR][WINDOWWIDTH] = SeenBuff.Get_Width();
- WindowList[WINDOW_EDITOR][WINDOWHEIGHT]= SeenBuff.Get_Height();
- ////////////////////////////////////////
- // The editor needs to not start the mouse up. - 7/22/2019 JAS
- if (!RunningFromEditor)
- {
- WWMouse = new WWMouseClass(&SeenBuff, 48, 48);
- MouseInstalled = TRUE;
- }
- //PG CDFileClass::Set_CD_Drive (CDList.Get_First_CD_Drive());
- #else //WIN32
- Options.Adjust_Variables_For_Resolution();
- if (!Special.IsFromInstall) {
- BlackPalette.Set();
- // Set_Palette(Palette);
- Set_Video_Mode(MCGA_MODE);
- }
- MouseInstalled = Install_Mouse(32, 24, 320, 200);
- #endif //WIN32
- /*
- ** See if we should run the intro
- */
- INIClass ini;
- ini.Load(cfile);
- /*
- ** Check for forced intro movie run disabling. If the conquer
- ** configuration file says "no", then don't run the intro.
- ** Don't do this for TEN & MPath.
- */
- if (!Special.IsFromInstall && Session.Type != GAME_TEN &&
- Session.Type != GAME_MPATH) {
- Special.IsFromInstall = ini.Get_Bool("Intro", "PlayIntro", true);
- }
- SlowPalette = ini.Get_Bool("Options", "SlowPalette", false);
- /*
- ** Regardless of whether we should run it or not, here we're
- ** gonna change it to say "no" in the future.
- */
- if (Special.IsFromInstall) {
- BreakoutAllowed = true;
- // BreakoutAllowed = false;
- ini.Put_Bool("Intro", "PlayIntro", false);
- ini.Save(cfile);
- }
- #ifndef WOLAPI_INTEGRATION
- #ifdef WIN32
- /*
- ** If WChat has been trying to send us a game start packet then receive it and
- ** flag that we were spawned from WCHat so we dont play the into movie.
- */
- if (DDEServer.Get_MPlayer_Game_Info()){
- Check_From_WChat(NULL);
- }else{
- //Check_From_WChat("C&CSPAWN.INI");
- //if (Special.IsFromWChat){
- // DDEServer.Disable();
- //}
- }
- #endif //WIN32
- #endif
- /*
- ** If the intro is being run for the first time, then don't
- ** allow breaking out of it with the <ESC> key.
- */
- if (Special.IsFromInstall) {
- BreakoutAllowed = true;
- // BreakoutAllowed = false;
- }
- Memory_Error_Exit = Print_Error_End_Exit;
- Main_Game(argc, argv);
- if (RunningAsDLL) { //PG
- return (EXIT_SUCCESS);
- }
- #ifdef MPEGMOVIE // Denzil 6/15/98
- if (MpgSettings != NULL)
- delete MpgSettings;
-
- #ifdef MCIMPEG
- if (MciMovie != NULL)
- delete MciMovie;
- #endif
- #endif
-
- #ifdef WIN32
- VisiblePage.Clear();
- HiddenPage.Clear();
- #else //WIN32
- SeenPage.Clear();
- Set_Video_Mode(RESET_MODE);
- #endif //WIN32
- Memory_Error_Exit = Print_Error_Exit;
- #ifdef WIN32
- /*
- ** Flag that this is a clean shutdown (not killed with Ctrl-Alt-Del)
- */
- ReadyToQuit = 1;
- /*
- ** Post a message to our message handler to tell it to clean up.
- */
- PostMessage(MainWindow, WM_DESTROY, 0, 0);
- /*
- ** Wait until the message handler has dealt with the message
- */
- do
- {
- Keyboard->Check();
- }while (ReadyToQuit == 1);
- return (EXIT_SUCCESS);
- #else //WIN32
- Remove_Mouse();
- Sound_End();
- #endif //WIN32
- } else {
- if (!RunningFromEditor)
- {
- puts(TEXT_SETUP_FIRST);
- Keyboard->Get();
- }
- }
- #ifdef WIN32
- if (WindowsTimer) {
- delete WindowsTimer;
- WindowsTimer = NULL;
- }
- #else //WIN32
- Remove_Keyboard_Interrupt();
- Remove_Timer_System();
- #endif //WIN32
- }
- /*
- ** Restore the current drive and directory.
- */
- #ifndef WIN32
- _dos_setdrive(olddrive, &drivecount);
- chdir(oldpath);
- #endif //WIN32
- return(EXIT_SUCCESS);
- }
- /* Initialize DirectDraw and surfaces */
- bool InitDDraw(void)
- {
- VisiblePage.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)(GBC_VISIBLE | GBC_VIDEOMEM));
- HiddenPage.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)GBC_VIDEOMEM);
- VisiblePage.Attach_DD_Surface(&HiddenPage);
- SeenBuff.Attach(&VisiblePage, 0, 0, 3072, 3072);
- HidPage.Attach(&HiddenPage, 0, 0, 3072, 3072);
- #if (0)//PG
- DDSCAPS surface_capabilities;
- BOOL video_success = FALSE;
- /* Set 640x400 video mode. If its not available then try for 640x480 */
- if (ScreenHeight == 400)
- {
- if (Set_Video_Mode(MainWindow, ScreenWidth, ScreenHeight, 8))
- {
- video_success = TRUE;
- }
- else
- {
- if (Set_Video_Mode(MainWindow, ScreenWidth, 480, 8))
- {
- video_success = TRUE;
- ScreenHeight = 480;
- }
- }
- }
- else
- {
- if (Set_Video_Mode(MainWindow, ScreenWidth, ScreenHeight, 8))
- {
- video_success = TRUE;
- }
- }
- if (!video_success)
- {
- MessageBox(MainWindow, TEXT_VIDEO_ERROR, TEXT_SHORT_TITLE, MB_ICONEXCLAMATION|MB_OK);
- if (WindowsTimer)
- delete WindowsTimer;
- return false;
- }
- if (ScreenWidth == 320)
- {
- VisiblePage.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)0);
- ModeXBuff.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)(GBC_VISIBLE|GBC_VIDEOMEM));
- }
- else
- {
- VisiblePage.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)(GBC_VISIBLE|GBC_VIDEOMEM));
- /* Check that we really got a video memory page. Failure is fatal. */
- memset(&surface_capabilities, 0, sizeof(surface_capabilities));
- VisiblePage.Get_DD_Surface()->GetCaps(&surface_capabilities);
- if (surface_capabilities.dwCaps & DDSCAPS_SYSTEMMEMORY)
- {
- /* Aaaarrgghh! */
- WWDebugString(TEXT_DDRAW_ERROR);WWDebugString("\n");
- MessageBox(MainWindow, TEXT_DDRAW_ERROR, TEXT_SHORT_TITLE, MB_ICONEXCLAMATION|MB_OK);
- if (WindowsTimer)
- delete WindowsTimer;
-
- return false;
- }
- /* If we have enough left then put the hidpage in video memory unless...
- *
- * If there is no blitter then we will get better performance with a system
- * memory hidpage
- *
- * Use a system memory page if the user has specified it via the ccsetup program.
- */
- unsigned video_memory = Get_Free_Video_Memory();
- unsigned video_capabilities = Get_Video_Hardware_Capabilities();
- if (video_memory < ScreenWidth * ScreenHeight
- || (!(video_capabilities & VIDEO_BLITTER))
- || (video_capabilities & VIDEO_NO_HARDWARE_ASSIST)
- || !VideoBackBufferAllowed)
- {
- HiddenPage.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)0);
- }
- else
- {
- HiddenPage.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)GBC_VIDEOMEM);
- /* Make sure we really got a video memory hid page. If we didnt then things
- * will run very slowly.
- */
- memset(&surface_capabilities, 0, sizeof(surface_capabilities));
- HiddenPage.Get_DD_Surface()->GetCaps(&surface_capabilities);
-
- if (surface_capabilities.dwCaps & DDSCAPS_SYSTEMMEMORY)
- {
- /* Oh dear, big trub. This must be an IBM Aptiva or something similarly cruddy.
- * We must redo the Hidden Page as system memory.
- */
- AllSurfaces.Remove_DD_Surface(HiddenPage.Get_DD_Surface()); // Remove the old surface from the AllSurfaces list
- HiddenPage.Get_DD_Surface()->Release();
- HiddenPage.Init(ScreenWidth, ScreenHeight, NULL, 0, (GBC_Enum)0);
- }
- else
- {
- VisiblePage.Attach_DD_Surface(&HiddenPage);
- }
- }
- }
- ScreenHeight = 400;
- if (VisiblePage.Get_Height() == 480)
- {
- SeenBuff.Attach(&VisiblePage, 0, 40, 3072, 3072);
- HidPage.Attach(&HiddenPage, 0, 40, 3072, 3072);
- }
- else
- {
- SeenBuff.Attach(&VisiblePage, 0, 0, 3072, 3072);
- HidPage.Attach(&HiddenPage, 0, 0, 3072, 3072);
- }
- #endif
- return true;
- }
- /***********************************************************************************************
- * Prog_End -- Cleans up library systems in prep for game exit. *
- * *
- * This routine should be called before the game terminates. It handles cleaning up *
- * library systems so that a graceful return to the host operating system is achieved. *
- * *
- * INPUT: why - text description of exit reason *
- * fatal - indicates a fatal error *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 03/20/1995 JLB : Created. *
- * 08/07/2019 ST : Added why and fatal params *
- *=============================================================================================*/
- #ifdef WIN32
- void __cdecl Prog_End(const char *why, bool fatal)
- {
- GlyphX_Debug_Print("Prog_End()");
-
- if (why) {
- GlyphX_Debug_Print(why);
- }
- if (fatal) {
- *((int*)0) = 0;
- }
- if (Session.Type == GAME_GLYPHX_MULTIPLAYER) {
- return;
- }
- Sound_End();
- if (WWMouse) {
- delete WWMouse;
- WWMouse = NULL;
- }
- if (WindowsTimer) {
- delete WindowsTimer;
- WindowsTimer = NULL;
- }
- ProgEndCalled = true;
- }
- #else //WIN32
- void Prog_End(void)
- {
- if (Session.Type == GAME_MODEM || Session.Type == GAME_NULL_MODEM) {
- NullModem.Change_IRQ_Priority(0);
- }
- Set_Video_Mode(RESET_MODE);
- Remove_Keyboard_Interrupt();
- Remove_Mouse();
- Sound_End();
- Remove_Timer_System();
- }
- #endif //WIN32
- void Print_Error_End_Exit(char * string)
- {
- Prog_End(string, true);
- printf( "%s\n", string );
- if (!RunningAsDLL) {
- exit(1);
- }
- }
- void Print_Error_Exit(char * string)
- {
- GlyphX_Debug_Print(string);
-
- printf( "%s\n", string );
- if (!RunningAsDLL) {
- exit(1);
- }
- }
- /***********************************************************************************************
- * Emergency_Exit -- Function to call when we want to exit unexpectedly. *
- * Use this function instead of exit(n) so everything is properly cleaned up.*
- * *
- * *
- * INPUT: Code to return to the OS *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 3/13/97 1:32AM ST : Created *
- *=============================================================================================*/
- void Emergency_Exit ( int code )
- {
- if (RunningAsDLL) { //PG
- return;
- }
- #ifdef WIN32
- /*
- ** Clear out the video buffers so we dont glitch when we lose focus
- */
- VisiblePage.Clear();
- HiddenPage.Clear();
- BlackPalette.Set();
- Memory_Error_Exit = Print_Error_Exit;
- /*
- ** Flag that this is an emergency shut down - not a clean shutdown but
- ** not killed with Ctrl-Alt-Del either.
- */
- ReadyToQuit = 3;
- /*
- ** Post a message to our message handler to tell it to clean up.
- */
- PostMessage(MainWindow, WM_DESTROY, 0, 0);
- /*
- ** Wait until the message handler has dealt with the message
- */
- do
- {
- Keyboard->Check();
- }while (ReadyToQuit == 3);
- #else //WIN32
- /*
- ** Do the DOS end
- */
- Prog_End();
- #endif //WIN32
- exit ( code );
- }
- #ifdef WIN32
- /***********************************************************************************************
- * Read_Setup_Options -- Read stuff in from the INI file that we need to know sooner *
- * *
- * *
- * *
- * INPUT: Ptr to config file class *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 6/7/96 4:09PM ST : Created *
- * 09/30/1996 JLB : Uses INI class. *
- *=============================================================================================*/
- void Read_Setup_Options( RawFileClass *config_file )
- {
- if (config_file->Is_Available()) {
- INIClass ini;
- ini.Load(*config_file);
- /*
- ** Read in the boolean options
- */
- VideoBackBufferAllowed = ini.Get_Bool("Options", "VideoBackBuffer", true);
- AllowHardwareBlitFills = ini.Get_Bool("Options", "HardwareFills", true);
- ScreenHeight = ini.Get_Bool("Options", "Resolution", false) ? 3072 : 3072;
- /*
- ** See if an alternative socket number has been specified
- */
- int socket = ini.Get_Int("Options", "Socket", 0);
- if (socket >0 ) {
- socket += 0x4000;
- if (socket >= 0x4000 && socket < 0x8000) {
- Ipx.Set_Socket (socket);
- }
- }
- /*
- ** See if a destination network has been specified
- */
- char netbuf [512];
- memset(netbuf, 0, sizeof(netbuf));
- char * netptr = netbuf;
- bool found = ini.Get_String("Options", "DestNet", NULL, netbuf, sizeof(netbuf));
- if (found && netptr != NULL && strlen(netbuf)) {
- NetNumType net;
- NetNodeType node;
- /*
- ** Scan the string, pulling off each address piece
- */
- int i = 0;
- char * p = strtok(netbuf,".");
- int x;
- while (p != NULL) {
- sscanf(p,"%x",&x); // convert from hex string to int
- if (i < 4) {
- net[i] = (char)x; // fill NetNum
- } else {
- node[i-4] = (char)x; // fill NetNode
- }
- i++;
- p = strtok(NULL,".");
- }
- /*
- ** If all the address components were successfully read, fill in the
- ** BridgeNet with a broadcast address to the network across the bridge.
- */
- if (i >= 4) {
- Session.IsBridge = 1;
- memset(node, 0xff, 6);
- Session.BridgeNet = IPXAddressClass(net, node);
- }
- }
- }
- }
- void Get_OS_Version (void)
- {
- //PG
- //WindowsNT = ((GetVersion() & 0x80000000) == 0) ? true : false;
- #if (0)
- OSVERSIONINFO osversion;
- if ( GetVersionEx (&osversion) ){
- WindowsNT = (osversion.dwPlatformId == VER_PLATFORM_WIN32_NT) ? true : false;
- OutputDebugString ("RA95 - Got OS version\n");
- }else{
- OutputDebugString ("RA95 - Failed to get OS version\n");
- char debugstr [128];
- sprintf (debugstr, "RA95 - Error code is %d\n", GetLastError());
- OutputDebugString (debugstr);
- }
- #endif //(0)
- }
- #endif //WIN32
|