//===========================================================================// // File: MW4Application.cpp // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 08/25/97 JMA Infrastructure changes. // // 08/25/97 ECH Infrastructure changes. // // 08/27/98 BDB Made it MW4 // // 09/29/98 BDB added gosFX shit // //---------------------------------------------------------------------------// // Copyright (C) 1995-97, Virtual World Entertainment, Inc. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include "MW4AppHeaders.hpp" #include "MW4Application.hpp" #include #include // [help] FILE/fopen/fprintf used by MW4_ShowCommandLineHelp #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mw4\mw4shell.hpp" #include "mw4\hudcomp.hpp" #include #include #include #include #include #include #include #include #include #if 0 extern MidLevelRenderer::MLRTexture *g_BergerName; extern bool s_NoAbzug; #endif #include "..\buildnum\buildnum.h" // current version and build number #include "..\missionLang\resource.h" // current version and build number #include "eula.h" // jcem - start #include "ctcls.h" #include "ctcl.h" // jcem extern Time g_fLastGameStart; void CTCL_API CTCL_DoGame1st(); #pragma data_seg(".SHARED_DATA") // all data in this section must be INITIALIZED!!!!!!!!!!!!! BOOL g_bLaunched = FALSE; #pragma data_seg() #pragma comment(linker, "/section:.SHARED_DATA,RWS") extern bool g_bTeslaIsCameraShip; extern CamerashipParams g_CamerashipParams; extern int g_bUseOrgJoy; extern bool g_bNoWeaponRangeCheck; extern bool g_bPRTest; extern bool g_bMRTest; extern int g_bNoPlasma; extern bool g_bNoTOCKeys; extern float g_fZoomMarginLR; extern float g_fZoomFOVA; extern float g_fZoomFOVB; extern float g_fZoomTime; extern Time g_PlasmaClearTime; extern Time g_TOC_ADT; extern Time g_AUX_ADT; extern bool g_UseMSRSP; extern int g_nTypeOfMFDs; // 0 - no MFDs, 1 - orginal(5+1=dual & single), 2 - B&W(3 + 1=1 dual), 3 - color(3 + 1=2 dual), 4 - split dual 640x480 // [tmon] Display-device override in Main/Radar/MFD1/MFD2 order; -1 = auto-detect. // Defined in CoreTech GameOS VideoCard.cpp and consumed by FindVideoCards(). extern int g_naMonitorOverride[4]; extern int g_nRIOType; extern DWORD g_dwRIOBaud; // [tbaud] extern LONG g_ThrottleDir; extern bool g_bCanSuicideAllways; extern bool g_f3dtarget; extern char g_szTeslaAddr[128]; extern DWORD g_dwTeslaAddr; extern void (__stdcall *g_pfnCTCL_Proc)(); extern int (_stdcall* g_pfnCTCL_GetType)(); int _stdcall __CTCL_GetType(); extern int _stdcall VehGetShutdownState(); extern int (_stdcall *g_pfnVehGetShutdownState)(); extern int g_nCTCL; BOOL __stdcall CTCL_Before(); void __stdcall CTCL_After(); void __stdcall CTCL_Proc(); extern bool g_bCOOP; // COin OPeration extern int g_nCoinCount; extern int g_nCoinPerGame; extern bool g_bUseCam; extern bool g_bUseJPD; // Use Joystick as Pointing Device extern bool g_bOldLOG; extern int g_nMechViewType; // jcem - end extern void _stdcall ExitGameOS(); // ngLog addition #include extern DWORD LogMode; bool __stdcall AlreadyRunning(); #ifdef LAB_ONLY extern bool saveMapBspDifference; #endif //############################################################################# //############################# GameEngine ############################## //############################################################################# char *Command_Line; extern void * __cdecl GetMech4SpecialGameData(int data_type, ...); #ifdef LAB_ONLY bool Bloat = true; #endif int bloatSizeTable[8] = { 16, 32, 64, 128, 256, 1024, 2048, 4096 }; #define BLOAT_MEMORY_LAB_ONLY(heap)\ {\ if (Bloat)\ {\ int total_bloat = Random::GetLessThan(8);\ Min_Clamp(total_bloat, 4);\ for (int i = 0; i < total_bloat; ++i)\ {\ int size_to_alloc = Random::GetLessThan(8);\ gos_Malloc(bloatSizeTable[size_to_alloc], heap);\ }\ }\ } #define BLOAT_MEMORY_REL(heap)\ {\ int total_bloat = Random::GetLessThan(8);\ Min_Clamp(total_bloat, 4);\ for (int i = 0; i < total_bloat; ++i)\ {\ int size_to_alloc = Random::GetLessThan(8);\ gos_Malloc(bloatSizeTable[size_to_alloc], heap);\ }\ } #ifdef LAB_ONLY #define BLOAT_MEMORY BLOAT_MEMORY_LAB_ONLY #else #define BLOAT_MEMORY BLOAT_MEMORY_REL #endif extern bool(__cdecl *NoCDMessageFunction)(void); extern bool gNoDialogs; //sanghoon begin extern bool use_shgui; extern int SCREENS; //sanghoon end bool gRunEula=true; bool gNoCD=false; bool gNoAutoConfig=false; extern bool gShowScriptErrors; bool _cdecl NoCDWarning(void) { return WinMessageBox(MWApplication::GetInstance()->GetLocString(IDS_INSERTCD),MWApplication::GetInstance()->GetLocString(IDS_PLAY_CD_MESSAGE)); } bool IsPlayCDPresent() { if(gNoCD) return true; char cd_path[256]; DWORD size=sizeof(cd_path); gos_LoadDataFromRegistry( "CDPath", cd_path, &size, TRUE ); if (size>0) { char *tmpptr=cd_path; if(tmpptr[0]=='\\' && tmpptr[1]=='\\') tmpptr+=2; while(*tmpptr!='\\' && *tmpptr) tmpptr++; if(*tmpptr=='\0') tmpptr[0]='\\'; tmpptr[1]='\0'; char vlabel[256]; bool res=gos_GetDriveLabel(cd_path,vlabel,256); if(!res) return false; if(strcmpi(vlabel,"MECHWARR_01") && strcmpi(vlabel,"MECHWARR_02")) return false; } else { STOP(("%s",MWApplication::GetInstance()->GetLocString(IDS_BADSETUP))); } return true; } bool IsFirstRun() { DWORD frun=false; DWORD size=sizeof(frun); gos_LoadDataFromRegistry( "FIRSTRUN", &frun, &size, FALSE ); return !frun; } bool RunAutoConfigIfNeeded() { #if 0 // jcem if (IsFirstRun()) { if(!gos_DoesFileExist("autoconfig.exe")) return true; //STOP(("Cannot Locate Autoconfig.exe")); ExecuteAndWait("autoconfig.exe"); } #endif // jcem return true; } extern void __stdcall EnterWindowMode(); extern void __stdcall EnterFullScreenMode(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void _stdcall InitializeGameEngine() { // Set_Heap_Check(1, 100); // //--------------------- // Initialize libraries //--------------------- // // bool needflip=Environment.fullScreen && IsFirstRun(); //sanghoon begin bool needflip=false; //sanghoon end if(needflip){ //sanghoon begin //MessageBeep(MB_ICONEXCLAMATION); //sanghoon end EnterWindowMode(); } Stuff::InitializeClasses(4800, 40000); #if defined(LAB_ONLY) if (!CallDebuggerMenuItem("Debugger\\Options\\Show percentages as milliseconds", gosMenu_CheckMark)) CallDebuggerMenuItem("Debugger\\Options\\Show percentages as milliseconds", gosMenu_Activated); #endif BLOAT_MEMORY(Stuff::g_Heap); if(!gNoAutoConfig) RunAutoConfigIfNeeded(); NotationFile startup_ini("options.ini", NotationFile::Standard, true); g_CamerashipParams.LoadOptions(startup_ini); Stuff::Page *compage = startup_ini.FindPage("special commands"); if(compage!=NULL) { bool kill; if(compage->GetEntry("killgame",&kill) && kill) { compage->SetEntry("killgame",false); startup_ini.Save(); ExitGameOS(); } } Page *page=startup_ini.FindPage("graphics options"); if(page!=NULL) { //Original //page->GetEntry("videodriverindex",&Environment.FullScreenDevice); //sanghoon Environment.FullScreenDevice=0; page->GetEntry("antialias",&Environment.AntiAlias); page->GetEntry("bitdepth",&Environment.bitDepth); } page=startup_ini.FindPage("sound options"); if(page!=NULL) { page->GetEntry("hardwaremixing",&Environment.soundMixInHardware); } page=startup_ini.FindPage("special commands"); if(page!=NULL) { page->GetEntry("AutoTorsoCenter",&VehicleInterface::perminateTorsoMode); //Original //page->GetEntry("HudDamageMode",&VehicleInterface::hudDamageMode); //page->GetEntry("HudTargetDamageMode",&VehicleInterface::hudTargetDamageMode); //sanghoon VehicleInterface::hudDamageMode=false; VehicleInterface::hudTargetDamageMode=false; } MidLevelRenderer::InitializeClasses(&startup_ini, 2048, 2048); gosFX::InitializeClasses(&startup_ini); ElementRenderer::InitializeClasses(&startup_ini); Compost::InitializeClasses(&startup_ini); Adept::InitializeClasses(&startup_ini); BLOAT_MEMORY(Adept::g_Heap); MechWarrior4::InitializeClasses(&startup_ini); BLOAT_MEMORY(MechWarrior4::Heap); HUDText::LoadFontSizeDelta (&startup_ini); VehicleInterface::LoadMouseYFlag (&startup_ini); VehicleInterface::LoadMouseMinMax (&startup_ini); #if 0 WORD day, month, year; gos_GetUnformattedDate(&year, &month, &day); if (year > 2000) { // this is just to make it look a little less obvious! int port = 24000; gos_SaveDataToRegistry("proxyport",&port, 4); STOP(("MechWarrior4 Beta has expired")); gos_TerminateApplication(); } if (year == 2000) { if (month >= 12) { int port = 24000; gos_SaveDataToRegistry("proxyport",&port, 4); STOP(("MechWarrior4 Beta has expired")); gos_TerminateApplication(); } } int port = 0; DWORD size = 4; gos_LoadDataFromRegistry("proxyport",&port,&size); if (size > 0) { STOP(("MechWarrior4 Beta has expired")); } #endif // //---------------------------------------------------------- // Parse command line and verify that game name has been set //---------------------------------------------------------- // if (Application::TestClasses) MW4Testall(); // //-------------------------------------- // Create and initialize the application //-------------------------------------- // gos_PushCurrentHeap(MechWarrior4::Heap); MWApplication *MW_Application = new MWApplication(MWApplication::DefaultData,true); Check_Object(MW_Application); //Adept::Application::GetInstance() = MW_Application; GlobalPointers::AddGlobalPointer(MW_Application, ApplicationGlobalPointerIndex); MW_Application->Initialize(); // Set the Localized No CD Message for Stuff DataBase NoCDMessageFunction=NoCDWarning; // //--------------------------------------------------------- // If we have a resource build command, build the resources //--------------------------------------------------------- // if (Adept::Application::BuildOK) { Verify(!NotationFile::s_cachedIncludes); NotationFile::s_cachedIncludes = new stlport::map; Tool::Instance = new MWTool(); Check_Object(Tool::Instance); gos_PushCurrentHeap(gosFX::Heap); gosFX::EffectLibrary::Instance = new ResourceEffectLibrary(true); gos_PopCurrentHeap(); Stuff::NotationFile build_script("Content\\MechWarrior4.build"); FileDependencies deps; Tool::Instance->BuildResources(&build_script, VER_CONTENTVERSION, &deps); delete gosFX::EffectLibrary::Instance; Verify(!gosFX::EffectLibrary::Instance); Adept::Application::BuildOK = false; delete Tool::Instance; Tool::Instance = NULL; stlport::map *map = (stlport::map*)NotationFile::s_cachedIncludes; stlport::map::iterator seeker = map->begin(); while (seeker != map->end()) { FileStream *file = (*seeker).second; Check_Object(file); delete file; ++seeker; } delete map; NotationFile::s_cachedIncludes = NULL; } else if (!gos_DoesFileExist("Resource\\Variants")) gos_CreateDirectory("Resource\\Variants"); //-------------------------------------- // Run the Eula //-------------------------------------- if(gRunEula && Application::RunOK && !gNoDialogs) { bool gotlicense=false; while(!gotlicense) { MString ename,wname; ename=MWApplication::GetInstance()->GetLocString(IDS_EULA_FILENAME); wname=MWApplication::GetInstance()->GetLocString(IDS_WARRANTY_FILENAME); if(!FirstRunEula(ename,wname)) { MString msg,cap; msg=MWApplication::GetInstance()->GetLocString(IDS_EULA_FAIL_MESSAGE); cap=MWApplication::GetInstance()->GetLocString(IDS_EULA_FAIL_CAPTION); if(EulaDeclineMsg(msg,cap)) { ExitGameOS(); } } else { gotlicense=true; } } //-------------------------------------- // Verify the CD //-------------------------------------- if(!gNoCD) { bool res=true; while(!IsPlayCDPresent() && res) { res=NoCDWarning(); if(!res) ExitGameOS(); } } } if(needflip) EnterFullScreenMode(); if (!MWApplication::AutoLaunchServerGame) { if(!gos_GetMachineInformation(gos_Info_UsingHardwareRenderer)) { MString msg,cap; msg=MWApplication::GetInstance()->GetLocString(IDS_NOHARDWARE); cap=MWApplication::GetInstance()->GetLocString(IDS_HARDWAREERROR); WinMessageBox(cap,msg,1); ExitGameOS(); } } // //------------------------------------------------------------------ // Now that we are out of building mode, reset the file hooks to use // resources //------------------------------------------------------------------ // Environment.HookGetFile = Application::GetFileForGOS; Environment.HookDoesFileExist = Application::FindFileForGOS; Environment.defaultPlayerName = NULL; // // Now that resources are built. Add another layer in the getfile and find file change that can // watch for .mw4 file requests and potentially remap them for 8.3 compatibility. // // Environment.HookGetFile = MWApplication::MW4GetFileForGOS; // Environment.HookDoesFileExist = MWApplication::MW4FindFileForGOS; // //----------------------------------------------- // Terminate the game if running is not permitted //----------------------------------------------- // if (!Adept::Application::RunOK) { gos_TerminateApplication(); } else { // generate the keys... MWApplication::GetInstance()->localKey = MWApplication::GetInstance()->GetUniqueKey(); // //-------------------------------------------------------- // We have disabled building, so load up the required data //-------------------------------------------------------- // ResourceManager::Instance->OpenResourceFile( "Resource\\textures.mw4", NULL, TexturesResourceFileID, VER_CONTENTVERSION, true, false ); ResourceManager::Instance->OpenResourceFile( "Resource\\core.mw4", NULL, CoreResourceFileID, VER_CONTENTVERSION, true, false ); ResourceManager::Instance->OpenResourceFile( "Resource\\props.mw4", NULL, PropsResourceFileID, VER_CONTENTVERSION, true, false ); MWApplication::GetInstance()->LoadLookupTables(); } //#ifdef LAB_ONLY // g_BergerName = MidLevelRenderer::MLRTexturePool::Instance->Add ("bf"); //#endif BLOAT_MEMORY(MechWarrior4::Heap); gos_PopCurrentHeap(); // jcem - begin if (!CTCL_Before()) { gos_TerminateApplication(); } // jcem - end } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void _stdcall TerminateGameEngine() { // //------------------- // Shut down the game //------------------- // // jcem - start CTCL_After(); if ( ServerBrowser::GetGameList() ) { ServerBrowser::GetGameList()->ShutdownPing(); ServerBrowser::DestroyGameList(); } // jcem - end gos_PushCurrentHeap(MechWarrior4::Heap); Adept::Application::GetInstance()->StopGame(); Adept::Application::GetInstance()->Terminate(); Unregister_Object(Adept::Application::GetInstance()); delete Adept::Application::GetInstance(); GlobalPointers::ClearPointer(ApplicationGlobalPointerIndex); // //------------------------------------------------------ // If we are shutting down a tool run, kill off the tool //------------------------------------------------------ // if (Tool::Instance) { Unregister_Object(Tool::Instance); delete Tool::Instance; } gos_PopCurrentHeap(); // //----------------------- // Shutdown the libraries //----------------------- // { NotationFile startup_ini("options.ini", NotationFile::Standard, true); MechWarrior4::TerminateClasses(&startup_ini); Adept::TerminateClasses(&startup_ini); Compost::TerminateClasses(&startup_ini); ElementRenderer::TerminateClasses(&startup_ini); gosFX::TerminateClasses(&startup_ini); MidLevelRenderer::TerminateClasses(&startup_ini); Page *page=startup_ini.SetPage("graphics options"); Check_Object(page); // MSL 5.02 Prevent Option Overwrite // page->SetEntry("bitdepth",Environment.bitDepth); page->SetEntry("videodriverindex",Environment.FullScreenDevice); // MSL 5.02 Prevent Option Overwrite // page->SetEntry("antialias",Environment.AntiAlias); page=startup_ini.SetPage("sound options"); Check_Object(page); page->SetEntry("hardwaremixing",Environment.soundMixInHardware); page=startup_ini.SetPage("special commands"); Check_Object(page); page->SetEntry("AutoTorsoCenter",VehicleInterface::perminateTorsoMode); //Original //page->SetEntry("HudDamageMode",VehicleInterface::hudDamageMode); //page->SetEntry("HudTargetDamageMode",VehicleInterface::hudTargetDamageMode); startup_ini.Save(); } Stuff::TerminateClasses(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // char * MakeArgumentString(char *start) { char *current_pos = start; int length = -1; while (current_pos != NULL) { if (*current_pos == '-') { length = current_pos - start - 1; break; } if (*current_pos == '\0') { length = current_pos - start; break; } ++current_pos; } // CHECK FOR NO PARAMETERS if (length == -1) { STOP(("INVALID PARAMETER : No parameter specified")); } // CHECK FOR A SPACE AT THE END OF THE PARAMETER if (start[length] != ' ' && start[length] != '\0') { STOP(("INVALID PARAMETER : No space after parameter")); } // CHECK FOR ALL SPACES { for (int i = 0; i < length; ++i) { if (start[i] != ' ') break; } if (i == length) { STOP(("INVALID PARAMETER : No parameter specified")); } } char *argument_string = new char [length+1]; // can't use strcopy since we don't have a null after the parameter strncpy(argument_string, start, length); argument_string[length] = '\0'; return argument_string; } //======================================================================== //======================================================================== #ifdef _DEBUG //extern "C" void __stdcall RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const DWORD *lpArguments); //extern "C" DWORD __stdcall GetCurrentThreadId(void); WINBASEAPI VOID WINAPI RaiseException( DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, CONST DWORD *lpArguments ); WINBASEAPI DWORD WINAPI GetCurrentThreadId( VOID ); typedef struct tagTHREADNAME_INFO { DWORD dwType; // must be 0x1000 char * szName; // pointer to name (in user addr space) DWORD dwThreadID; // thread ID (-1=caller thread) DWORD dwFlags; // reserved for future use, must be zero } THREADNAME_INFO; void __stdcall SetThreadName(DWORD dwThreadID, char *szThreadName) { THREADNAME_INFO info; info.dwType = 0x1000; info.szName = szThreadName; info.dwThreadID = dwThreadID; info.dwFlags = 0; __try { RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info ); } __except (-1) { } } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // //extern "C" DWORD __stdcall GetEnvironmentVariableA(char * lpName, char * lpBuffer, DWORD nSize); WINBASEAPI DWORD WINAPI GetEnvironmentVariableA( LPCSTR lpName, LPSTR lpBuffer, DWORD nSize ); // [help] --------------------------------------------------------------------- // Complete command-line reference, shown by "MW4.exe -help". // // MW4 is a GUI-subsystem application, so there is no console to print to when it // is launched normally. -help therefore writes the full reference to // mw4-help.txt next to the executable, opens it in Notepad, and exits without // starting the game. If Notepad cannot be launched, a message box reports where // the file was written. // // KEEP THIS IN SYNC when adding or changing a command-line switch. static const char* const g_apszCommandLineHelp[] = { "BattleTech: FireStorm - MW4.exe command line reference", "======================================================", "", "Usage: MW4.exe [options]", "", "Options may appear in any order and are case-insensitive. An option that takes", "a value must be followed by a single space and then the value, for example:", "", " MW4.exe -tmfds 4 -tmon 1,2,3,4 -tbaud 115200", "", "Values outside the documented range are ignored and the default is kept.", "", "", "DISPLAY AND VIDEO", "-----------------", " -window Run in a window instead of fullscreen.", " -fullscreen Force fullscreen. Overrides -window.", " -tmfds <0-4> MFD output mode:", " 0 = no MFDs", " 1 = original 1280x480 span (5 channels + radar)", " 2 = black and white (3 channels + 1 dual)", " 3 = colour (3 channels + 2 dual)", " 4 = split dual 640x480 - drives two independent", " MFD monitors, so no span hardware is needed", " -tmon ,,, Hard-assign display devices in the order", " main, radar, MFD1, MFD2. Values are 1-based; a", " value of 0 leaves that slot auto-detected.", " Separators may be ',' '/' or ':'.", " MFD1 and MFD2 only apply with -tmfds 4.", " Example: -tmon 1,2,4,3 swaps the two MFD panels.", " -mechview <1|2> Show the rotating mech view. 1 = on the radar", " -mv <1|2> screen, 2 = on the main screen. Default: off.", " -3dt Draw the MFD target as a live 3D model instead of", " the pre-rendered 2D bitmaps.", " -capdev <0-7> Select which device screen captures come from:", " 0 main, 1 radar, 2 mission review, 3 hudchat,", " 4 nav, 5 weapon, 6 target, 7 armor", "", "", "AUDIO AND PLASMA DISPLAY", "------------------------", " -nosound Disable all sound output.", " -noplasma Disable the COM2 plasma score display.", " -pctime Plasma display clear time. Minimum 3.", "", "", "POD HARDWARE AND ARCADE (CTCL)", "------------------------------", " -ctcltype <1-3> CTCL role for this machine:", " -ctcl <1-3> 1 = console, 2 = game pod, 3 = cameraship.", " Default when absent: console.", " -dragon Disable CTCL entirely and run standalone.", " -coop Co-operative arcade mode. Implies 1 coin per game", " and the game-pod role.", " -#coop Co-op with an explicit coin count. A negative", " value selects the cameraship role instead.", " -trio <0|1> RIO cockpit board protocol. 0 = original board,", " 1 = newer protocol (different framing and acks).", " -tbaud <9600-921600> Force the COM1 baud rate for the RIO board. Use", " for replica boards with a high-speed UART. The", " wire protocol is unchanged; only the rate differs.", " -useorgjoy Use the original joystick axis mapping.", " -ojoy Same as -useorgjoy.", " -usetockeys Enable TOC keys. They are disabled by default.", " -tocadt TOC auto-detect timeout. Minimum 5.", " -auxadt AUX auto-detect timeout. Minimum 3.", " -usecam Force camera mode. Implied by the cameraship role.", " -suicide Allow self-destruct at any time.", " -jpd Enable JPD input handling.", "", "", "ZOOM AND FIELD OF VIEW", "----------------------", " -zmfova <0.01-0.5> Zoom field-of-view, stage A.", " -zmfovb <0.01-0.5> Zoom field-of-view, stage B. A and B are swapped", " automatically so that A is the wider of the two.", " -zmmrgn <0.01-0.49> Zoom left/right margin, as a fraction of width.", " -zmtime <0, or 0.05-3.0> Zoom transition time in seconds. 0 = instant.", "", "", "MULTIPLAYER AND NETWORK", "-----------------------", " -serve Automatically host a server game on startup.", " -lobby Indicates the game was started from a lobby.", " -game Load the named game/mission file.", " -gamename Name advertised for the hosted game.", " -playername Player name to use.", " -password Password for the hosted or joined game.", " -advertiseport Port used to advertise the server.", " -ipx Use IPX in the server browser.", " -nodplay Disable DirectPlay networking.", " -directplayprotocol Force use of the DirectPlay protocol.", " -secure Enable secure networking for the game session.", " -set_internet Configure network settings for internet play.", " -set_lan Configure network settings for LAN play.", " -win32dedicated Run as a Win32 dedicated server. Disables sound", " and rendering and uses the dedicated server UI.", " -allowmultiple Allow more than one instance of the game to run.", " -oldmpui Use the older multiplayer user interface.", "", "", "LOGGING AND DIAGNOSTICS", "-----------------------", " -zlogstyle ZLog output style.", " -zlogflush ZLog flush behaviour.", " -zlogbuffer ZLog buffer size.", " -zlogname ZLog output file name.", " -olog Write the legacy .log match report instead of the", " newer .rpt format.", " -gamestats Save game statistics.", " -help Show this reference and exit without starting.", "", "", "DEVELOPMENT AND TEST BUILDS", "---------------------------", "The following are only active in LAB (Debug, Armor and Profile) builds. In a", "Release build they are accepted and ignored.", "", " -build Rebuild the resource packages at startup.", " -norun Do not run the game after building.", " -demo Demo mode.", " -rekey Re-key resources.", " -bloat Enable bloat diagnostics.", " -reportnotresourced Report assets that are not in a resource package.", " -armorlevel <0-4> Assertion/armor checking level.", " -leak Memory trace level.", " -diskfirst Prefer loose files on disk over packaged data.", " -testclasses Run internal class self-tests.", " -aistats Enable AI statistics collection.", " -bspmap Save BSP map differences.", " -showscripterrors Display script errors as they occur.", " -mrtest Mission review test mode.", " -prtest Print report test mode.", " -nowrc Disable weapon range checking.", " -regs Debug builds only: enable script regions.", " -spew Debug builds only: enable script spews.", "", "", "OTHER", "-----", " -nocd Skip the CD check. (The CD check is already", " disabled unconditionally in this build.)", " -noeula Skip the end user licence agreement screen.", " -noautoconfig Skip automatic video and sound configuration.", "", "", "RECOGNISED BUT INACTIVE", "-----------------------", " -join Parsed for compatibility but has no effect; the", " code that consumed it is commented out.", " -noabzug Parsed only in a disabled code path.", "", "", "RELATED CONFIGURATION", "---------------------", "Most persistent settings live in options.ini next to MW4.exe rather than on the", "command line. See OPTIONS-INI.md in the source repository for a full reference.", "Arcade pod assignments live in c:\\ctcl.ini.", NULL }; static void MW4_ShowCommandLineHelp() { char szDir[MAX_PATH]; char szPath[MAX_PATH]; // Write next to the executable rather than the working directory, so the file // is easy to find no matter how the game was launched. szDir[0] = '\0'; GetModuleFileNameA(NULL, szDir, sizeof(szDir)); char* pSlash = strrchr(szDir, '\\'); if (pSlash) *(pSlash + 1) = '\0'; else szDir[0] = '\0'; sprintf(szPath, "%smw4-help.txt", szDir); FILE* f = fopen(szPath, "wt"); if (!f) { MessageBoxA(NULL, "Could not write mw4-help.txt next to MW4.exe.\n" "Check that the folder is writable.", "MW4 command line help", MB_OK | MB_ICONWARNING); return; } for (int i = 0; g_apszCommandLineHelp[i] != NULL; i++) fprintf(f, "%s\n", g_apszCommandLineHelp[i]); fclose(f); // Open it for the user. WinExec is used rather than ShellExecute to avoid a // dependency on shellapi.h in this translation unit. char szCmd[MAX_PATH + 32]; sprintf(szCmd, "notepad.exe \"%s\"", szPath); if (WinExec(szCmd, SW_SHOWNORMAL) < 32) { char szMsg[MAX_PATH + 128]; sprintf(szMsg, "The MW4.exe command line reference was written to:\n\n%s", szPath); MessageBoxA(NULL, szMsg, "MW4 command line help", MB_OK | MB_ICONINFORMATION); } } void __stdcall GetGameOSEnvironment(char* CommandLine) { #ifdef _DEBUG // // name that thread // SetThreadName(GetCurrentThreadId(), "MainThread"); #endif // //----------------------------------------------- // This is where to set GOS environment settings. //----------------------------------------------- // Command_Line = CommandLine; if (true) { static char szFullCommandLine[256]; strcpy(szFullCommandLine, CommandLine); strcat(szFullCommandLine, " "); char szMech4EnvironmentVariable[256]; szMech4EnvironmentVariable[0] = 0; GetEnvironmentVariableA("mw4", szMech4EnvironmentVariable, sizeof(szMech4EnvironmentVariable)); strcat(szFullCommandLine, szMech4EnvironmentVariable); CommandLine = szFullCommandLine; Command_Line = szFullCommandLine; } Environment.applicationName = "BattleTech Firestorm"; // "MechWarrior Vengeance"; Environment.version = VER_PRODUCTVERSION_STR; Environment.directoryPath = "code\\MW4Application;Binaries\\MW4"; Environment.screenWidth = 800; Environment.screenHeight = 600; Environment.bitDepth = 16; Environment.FullScreenDevice = 0; Environment.Renderer = 0; Environment.disableZBuffer = false; Environment.AntiAlias = false; Environment.MegMemoryRequired = 192; Environment.MinimumTextureMemory = 5*1024; // cards with less than this video memory - use Blade Environment.Key_FullScreen = 0; Environment.Key_SwitchMonitors = 0; Environment.Key_Exit = 0; Environment.debugLog = "Mechwarrior4.txt"; Environment.spew = "GameOS_Memory"; //GROUP_ADEPT_RESOURCE; #if defined(_ARMOR) Environment.memoryTraceLevel = 5; #endif Environment.TimeStampSpew = false; Environment.MaxTimeDelta = 0.25f; Environment.MinimumTimeDelta = 0.25f; Environment.soundHiFi = false; Environment.soundDevice = 0; Environment.soundChannels = 32; Environment.allowMultipleApps = false; Environment.AllowJoinInProgress = true; Environment.NetworkGame = true; Environment.NetworkMaxPlayers = 16; Environment.NetworkGUID[0] = 0x95; Environment.NetworkGUID[1] = 0x78; Environment.NetworkGUID[2] = 0xFF; Environment.NetworkGUID[3] = 0xD5; Environment.NetworkGUID[4] = 0x13; Environment.NetworkGUID[5] = 0x81; Environment.NetworkGUID[6] = 0x9F; Environment.NetworkGUID[7] = 0x47; Environment.NetworkGUID[8] = 0xBB; Environment.NetworkGUID[9] = 0xD5; Environment.NetworkGUID[10] = 0xD3; Environment.NetworkGUID[11] = 0x95; Environment.NetworkGUID[12] = 0xE5; Environment.NetworkGUID[13] = 0x51; Environment.NetworkGUID[14] = 0xD0; Environment.NetworkGUID[15] = 0xA8; Environment.allowDoubleClicks = true; #ifdef LAB_ONLY Environment.GetGameInformation = GameInfo; #else Environment.GetGameInformation = NULL; #endif Environment.RaidDataSource = "MechWarrior 4:Raid4"; Environment.RaidFilePath = "\\\\cpaas2\\mw\\test\\goserrors"; Environment.RaidCustomFields = "AssignedTo=jmayo;Area=GOSRaid"; Environment.RaidDescTemplate = "Description:\n\nSteps to Repro:\n\nResult:\n\nExpected:\n\nNotes:\n\n"; Environment.InitializeGameEngine = InitializeGameEngine; Environment.DoGameLogic = &MWApplication::StartUpDoShellLogic; Environment.UpdateRenderers = &MWApplication::UpdateDisplay; Environment.TerminateGameEngine = TerminateGameEngine; Environment.GetSpecialGameData = GetMech4SpecialGameData; if (MWApplication::Win32DedicatedServer) { Environment.InitializeGameEngine = CDedicatedServerUI::InitializeGameEngine; Environment.DoGameLogic = &MWApplication::DoShellLogic; Environment.UpdateRenderers = NULL; Environment.TerminateGameEngine = CDedicatedServerUI::TerminateGameEngine; } gos_EnableSetting(gos_Set_IgnoreMaxUV, 1); // // // DWORD __stdcall gos_EnableSetting( gosSetting Setting, DWORD Value ); // //------------------------------------------------------------------- // we need to parse out our commandline options, so convert it all to // lowercase //------------------------------------------------------------------- // static char all_lower[1024]; strncpy(all_lower, CommandLine, sizeof(all_lower)); all_lower[sizeof(all_lower)-1] = '\0'; char *p; int i = strlen(all_lower); for (p=all_lower; i>0; ++p,--i) *p=(char)tolower(*p); // //-------------------------------------------------------------------------- // Check the various options that don't affect debugging during log playback //-------------------------------------------------------------------------- // Environment.allowMultipleApps = (strstr(all_lower, "-allowmultiple") != NULL); MWApplication::RunFromLobby = (strstr(all_lower, "-lobby") != NULL); char *token; #ifdef LAB_ONLY token = strstr(all_lower, "-game "); if (token && token[6]) { MWApplication::GameFile = MakeArgumentString(&token[6]); } MWApplication::DemoMode = (strstr(all_lower, "-demo") != NULL); #endif token = strstr(all_lower, "-gamename "); if (token && token[10]) { MWApplication::NetGameName = MakeArgumentString(&token[10]); } token = strstr(all_lower, "-password "); if (token && token[10]) { MWApplication::NetPassword = MakeArgumentString(&token[10]); } token = strstr(all_lower, "-playername "); if (token && token[12]) { MWApplication::NetPlayerName = MakeArgumentString(&token[12]); } token = strstr(all_lower, "-advertiseport "); if ( token && token[15]) { int port = atoi(&token[15]); if ( port <= 0 ) { STOP(("INVALID PARAMETER : Advertise port invalid.")); } int valSize = sizeof(port); gos_SaveDataToRegistry( (char *) ZONE_ADVERTISE_PORT_KEY, &port, valSize); Environment.ZoneAdvertisePort = port; } MWApplication::SaveGameStats = (strstr(all_lower, "-gamestats") != NULL); MWApplication::AutoLaunchServerGame = (strstr(all_lower, "-serve") != NULL); //MWApplication::AutoLaunchClientGame = (strstr(all_lower, "-join") != NULL); Environment.DirectPlayProtocol = (strstr(all_lower, "-directplayprotocol") != NULL); if (MWApplication::AutoLaunchServerGame || MWApplication::AutoLaunchClientGame) { if (MWApplication::NetPlayerName == NULL) { STOP(("Cant autolaunch without -playername specified")); } if (MWApplication::NetGameName == NULL) { STOP(("Cant autolaunch without -gamename specified")); } } //////////////////////////////////////////////////////////////////////////// // START - ngLog addition //////////////////////////////////////////////////////////////////////////// // Set defaults #if !defined(NO_LOG) MW4log_options_init(); // Style of local logging // -zlogstyle: // 0 - Disable local logging (default) // 1 - Append/Create to specified logfile. // 2 - Create/overwrite any existing log file. // 3 - Rotate: If logname exists, create unique identifier // and create new logfile with this unique name. // 4 - Use unique names and individual logs for each map. // Also forces a call to the zStats backend processor // (local zStats processing is currently not supported) // token = strstr(all_lower, "-zlogstyle "); if(token && token[11]) { z_style = atoi(&token[11]); } // Flushing semantics for local logging // -zlogflush: // 0 - Flush on every write (default). // 1 - Flush after "zlogbuffer" lines written. // 2 - Wait for system to write out buffer. token = strstr(all_lower, "-zlogflush "); if(token && token[11]) { z_flush = atoi(&token[11]); } // Size (in terms of lines) of internal buffer for local log flushing // (Default = 10 lines of buffer). token = strstr(all_lower, "-zlogbuffer "); if(token && token[12]) { z_buffer = atoi(&token[12]); } // Name of local log to generate (if not zStats-style log) // (Default = "MW4_log.log") token = strstr(all_lower, "-zlogname "); if(token && token[10]) { strcpy(z_logname, MakeArgumentString(&token[10])); } #endif // !defined(NO_LOG) //////////////////////////////////////////////////////////////////////////// // END - ngLog addition - END //////////////////////////////////////////////////////////////////////////// // //----------------------------------------------------------------------- // If we aren't playing back a log file, allow setting these other things //----------------------------------------------------------------------- // if (!LogMode) { Environment.soundDisable = (strstr(all_lower, "-nosound") != NULL); Environment.fullScreen = (strstr(all_lower, "-window") == NULL); //sanghoon begin use_shgui=Environment.fullScreen?1:0; //sanghoon end gNoAutoConfig= (strstr(all_lower, "-noautoconfig") != NULL); Application::TestClasses = false; Application::RunOK = true; Application::BuildOK = false; gRunEula= true; MW4AI::Statistics::SetEnabled(false); Network::bUseNewUI = true; gNoCD= false; gShowScriptErrors = (strstr(all_lower, "-showscripterrors") != NULL); #ifdef LAB_ONLY gShowScriptErrors = true; gNoCD = (strstr(all_lower, "-nocd") != NULL); if (strstr(all_lower, "-fullscreen")) Environment.fullScreen=1; Application::TestClasses = (strstr(all_lower, "-testclasses") != NULL); Application::RunOK = (strstr(all_lower, "-norun") == NULL); Application::BuildOK = (strstr(all_lower, "-build") != NULL); Application::ReportNotResourced = (strstr(all_lower, "-reportnotresourced") != NULL); gRunEula= (strstr(all_lower, "-noeula") == NULL); MW4AI::Statistics::SetEnabled(strstr(all_lower, "-aistats") != NULL); Network::bUseNewUI = (strstr(all_lower, "-oldmpui") == NULL); MWApplication::DplayNetGame = (strstr(all_lower, "-nodplay") == NULL); if (strstr(all_lower, "-set_internet") != NULL) { int port; gos_SaveStringToRegistry((char *)ZONE_SERVER_KEY, (char *)ZONE_SERVER_INTERNET_ADDRESS, strlen(ZONE_SERVER_INTERNET_ADDRESS)+1); gos_SaveStringToRegistry(GAMESPY_MASTER_SERVER_KEY, GAMESPY_MASTER_INTERNET_ADDR, strlen(GAMESPY_MASTER_INTERNET_ADDR)+1); port = GAMESPY_MASTER_INTERNET_HEARTBEAT_PORT; gos_SaveDataToRegistry(GAMESPY_MASTER_HEARTBEAT_PORT_KEY, &port, sizeof(port)); port = GAMESPY_MASTER_INTERNET_QUERY_PORT; gos_SaveDataToRegistry(GAMESPY_MASTER_QUERY_PORT_KEY, &port, sizeof(port)); port = GAMESPY_MASTER_INTERNET_SERVERLIST_PORT; gos_SaveDataToRegistry(GAMESPY_MASTER_SERVERLIST_PORT_KEY, &port, sizeof(port)); } else if (strstr(all_lower, "-set_lan") != NULL) { int port; gos_SaveStringToRegistry((char *)ZONE_SERVER_KEY, (char *)ZONE_SERVER_LAN_ADDRESS, strlen(ZONE_SERVER_LAN_ADDRESS)+1); gos_SaveStringToRegistry(GAMESPY_MASTER_SERVER_KEY, GAMESPY_MASTER_LAN_ADDR, strlen(GAMESPY_MASTER_LAN_ADDR)+1); port = GAMESPY_MASTER_LAN_HEARTBEAT_PORT; gos_SaveDataToRegistry(GAMESPY_MASTER_HEARTBEAT_PORT_KEY, &port, sizeof(port)); port = GAMESPY_MASTER_LAN_QUERY_PORT; gos_SaveDataToRegistry(GAMESPY_MASTER_QUERY_PORT_KEY, &port, sizeof(port)); port = GAMESPY_MASTER_LAN_SERVERLIST_PORT; gos_SaveDataToRegistry(GAMESPY_MASTER_SERVERLIST_PORT_KEY, &port, sizeof(port)); } saveMapBspDifference = (strstr(all_lower, "-bspmap") != NULL);; #endif gNoCD = true; // jcem MWApplication::SecureNetGame = (strstr(all_lower, "-secure") != NULL); ServerBrowser::IPX = (strstr(all_lower, "-ipx") != NULL); Application::s_DiskFirst = false; #ifdef LAB_ONLY MWApplication::ReKeyResources = (strstr(all_lower, "-rekey") != NULL); Bloat = (strstr(all_lower, "-bloat") != NULL); token = strstr(all_lower, "-armorlevel "); if (token && token[12]>='0' && token[12]<='4') ArmorLevel = token[12]-'0'; token = strstr(all_lower, "-leak "); if (token && token[6]) { Environment.memoryTraceLevel = atoi(&token[6]); } #endif Application::s_DiskFirst = (strstr(all_lower, "-diskfirst") != NULL); #if 0 s_NoAbzug = (strstr(all_lower, "-noabzug") != NULL); #endif } // [help] -help is handled at the top of WinMain (see MW4_ShowCommandLineHelp), // which runs before this and exits the process. The old partial list that used // to live here was incomplete and only reached the debug log, so it was removed // in favour of a single maintained reference. if (MWApplication::AutoLaunchServerGame || MWApplication::Win32DedicatedServer) { Environment.soundDisable = true; Environment.fullScreen = false; } } Scalar GetNumber(const char* token, bool bAllowFloat = false) { while((*token == ' ') || (*token == '\t')) { token++; } const char *tokenStart = token; char c; bool b1st = true; bool bsign = false; bool bDotExist = false; while(((c = *token) == '-') || (c == '+') || (('0' <= c) && (c <= '9')) || (bAllowFloat && (c == '.'))) { if ((c == '-') || (c == '+')) { if (!b1st) break; if (c == '-') bsign = !bsign; tokenStart = ++token; } else { b1st = false; if (c == '.') { if (bDotExist) { break; } bDotExist = true; } token++; } } if (tokenStart < token) { char sz[256]; memcpy(sz, tokenStart, token - tokenStart); sz[token - tokenStart] = '\0'; Scalar f = atof(sz); if (bsign) return -f; return f; } else { return 0.0; } } HINSTANCE g_hInst; int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow ) { #ifdef _DEBUG // jcem Vector3D::TestClass(); #endif // _DEBUG #ifdef _ICECAP StopCAPAll (); #endif // jcem - begin g_pfnVehGetShutdownState = VehGetShutdownState; if (g_bLaunched || (CTCL_GetApplType() != _EAT_None)) return 0; g_bLaunched = TRUE; // jcem - end g_hInst = hInst; static char all_lower[1024]; strncpy(all_lower, lpCmdLine, sizeof(all_lower)); all_lower[sizeof(all_lower)-1] = '\0'; char *p; int i = strlen(all_lower); for (p=all_lower; i>0; ++p,--i) *p=(char)tolower(*p); // [help] Handle -help before anything is initialised: write the full command // line reference next to the exe, open it, and exit without starting the game. if (strstr(all_lower, "-help")) { MW4_ShowCommandLineHelp(); return 0; } char *token; // jcem - begin token = strstr(all_lower, "-ctcltype "); if (token) { token = &token[10]; } else { token = strstr(all_lower, "-ctcl "); if (token) { token = &token[6]; } } if (token) { if (token[0]>='1' && token[0]<='3') { g_nCTCL = (token[0]-'0'); } else { g_nCTCL = _ECTCL_Console; } } else { g_nCTCL = _ECTCL_Console; } // MechViewType : 0 - no mechview, 1 - on radar screen, 2 - on main screen token = strstr(all_lower, "-mechview "); if (token) { token = &token[10]; } else { token = strstr(all_lower, "-mv "); if (token) { token = &token[4]; } } if (token) { if (token[0]>='1' && token[0]<='2') { g_nMechViewType = (token[0]-'0'); } else { g_nMechViewType = 0; } } else { g_nMechViewType = 0; } token = strstr(all_lower, "-#coop "); if (token) { g_bCOOP = true; g_nCoinPerGame = GetNumber(&token[7]); if (g_nCoinPerGame < 0) { g_nCTCL = _ECTCL_CameraShip; g_nCoinPerGame = 0; } else { g_nCTCL = _ECTCL_Game; } } else { g_bCOOP = (strstr(all_lower, "-coop") != NULL); if (g_bCOOP) { g_nCoinPerGame = 1; g_nCTCL = _ECTCL_Game; } } if (strstr(all_lower, "-dragon") != NULL) g_nCTCL = _ECTCL_None; if (g_nCTCL != _ECTCL_None) { g_pfnCTCL_Proc = CTCL_Proc; } g_pfnCTCL_GetType = __CTCL_GetType; g_bUseJPD = (strstr(all_lower, "-jpd") != NULL); g_bUseOrgJoy = (strstr(all_lower, "-useorgjoy") != NULL); if (!g_bUseOrgJoy) { g_bUseOrgJoy = (strstr(all_lower, "-ojoy") != NULL); } g_bNoWeaponRangeCheck = (strstr(all_lower, "-nowrc") != NULL); g_bPRTest = (strstr(all_lower, "-prtest") != NULL); g_bMRTest = (strstr(all_lower, "-mrtest") != NULL); g_bNoPlasma = (strstr(all_lower, "-noplasma") != NULL); g_bNoTOCKeys = (strstr(all_lower, "-usetockeys") == NULL); token = strstr(all_lower, "-zmmrgn "); if (token) { Scalar f = GetNumber(token, true); if ((0.01 <= fabs(f)) && (fabs(f) <= 0.49)) { g_fZoomMarginLR = f; } } float fZoomFOVA = g_fZoomFOVA; float fZoomFOVB = g_fZoomFOVB; token = strstr(all_lower, "-zmfova "); if (token) { Scalar f = GetNumber(token, true); if ((0.01 <= fabs(f)) && (fabs(f) <= 0.5)) { fZoomFOVA = f; } } token = strstr(all_lower, "-zmfovb "); if (token) { Scalar f = GetNumber(token, true); if ((0.01 <= fabs(f)) && (fabs(f) <= 0.5)) { fZoomFOVB = f; } } if (fZoomFOVA < fZoomFOVB) { float f; f = fZoomFOVB; fZoomFOVB = fZoomFOVA; fZoomFOVA = f; } g_fZoomFOVA = fZoomFOVA; g_fZoomFOVB = fZoomFOVB; token = strstr(all_lower, "-zmtime "); if (token) { Scalar f = GetNumber(token, true); if (Stuff::Close_Enough(f, 0.0)) { g_fZoomTime = 0.0f; } else { if ((0.05 <= fabs(f)) && (fabs(f) <= 3.0)) { g_fZoomTime = f; } } } token = strstr(all_lower, "-pctime "); if (token) { Scalar f = GetNumber(token, true); if (f >= 3.0) { g_PlasmaClearTime = f; } } token = strstr(all_lower, "-tocadt "); if (token) { Scalar f = GetNumber(token, true); if (f >= 5.0) { g_TOC_ADT = f; } } token = strstr(all_lower, "-auxadt "); if (token) { Scalar f = GetNumber(token, true); if (f >= 3.0) { g_AUX_ADT = f; } } token = strstr(all_lower, "-tmfds "); if (token && token[7]) { int n = atoi(&token[7]); if ((0 <= n) && (n <= 4)) // 0 - no MFDs, 1 - orginal(5+1=dual & single), 2 - B&W(3 + 1=1 dual), 3 - color(3 + 1=2 dual), 4 - split dual 640x480 g_nTypeOfMFDs = n; } // [tmon] Hard-assign the display devices when DirectDraw enumerates them in an // unexpected order. Syntax: -tmon
,,, // Values are 1-based (the normal case is "-tmon 1,2,3,4"); a value of 0 leaves that // slot to auto-detection, so "-tmon 2,1,0,0" only swaps main and radar. Separators // may be ',' '/' or ':'. mfd1/mfd2 are only used by -tmfds 4. token = strstr(all_lower, "-tmon "); if (token) { const char* p = &token[6]; int slot = 0; while (slot < 4) { while (*p == ' ') p++; if ((*p < '0') || ('9' < *p)) break; int v = atoi(p); while (('0' <= *p) && (*p <= '9')) p++; // 0 = leave auto-detected, otherwise convert 1-based to a 0-based device index g_naMonitorOverride[slot] = (0 < v) ? (v - 1) : -1; slot++; if ((*p == ',') || (*p == '/') || (*p == ':')) p++; else break; } } token = strstr(all_lower, "-trio "); if (token && token[6]) { int n = atoi(&token[6]); if ((n == 0) || (n == 1)) g_nRIOType = n; } token = strstr(all_lower, "-tbaud "); // [tbaud] force COM1 baud; must match the RIO board's UART rate if (token && token[7]) { int n = atoi(&token[7]); if ((9600 <= n) && (n <= 921600)) g_dwRIOBaud = (DWORD)n; } g_bCanSuicideAllways = (strstr(all_lower, "-suicide") != NULL); g_f3dtarget = (strstr(all_lower, "-3dt") != NULL); g_bOldLOG = (strstr(all_lower, "-olog") != NULL); #ifdef _DEBUG if (strstr(all_lower, "-regs") != NULL) { bool __stdcall CheckScriptRegions(); void __stdcall EnableScriptRegions(); if (!CheckScriptRegions()) EnableScriptRegions(); } else if (strstr(all_lower, "-spew") != NULL) { bool __stdcall CheckScriptSpews(); void __stdcall EnableScriptSpews(); if (!CheckScriptSpews()) EnableScriptSpews(); } #endif // _DEBUG if (g_nCTCL == _ECTCL_CameraShip) { g_bUseCam = true; } else { token = strstr(all_lower, "-usecam"); if (token) { g_bUseCam = true; } } token = strstr(all_lower, "-capdev "); if (token) { int nCapDev = (int)GetNumber(&token[8], false); if ((0 <= nCapDev) && (nCapDev < 8)) { // 0 - main, 1 - radar, 2 - mr // 3 - hudchat(left/top), 4 - nav(top/center), 5 - weapon(right/top) // 6 - target(left/top), 7 - armor(right/bottom) extern DWORD gCaptureDevice; gCaptureDevice = (DWORD)nCapDev; } } // jcem - end MWApplication::Win32DedicatedServer = (strstr(all_lower, "-win32dedicated") != NULL); if (MWApplication::Win32DedicatedServer) { Platform=Platform_MFC; RunFromOtherApp( hInst, ::GetDesktopWindow(), lpCmdLine ); CDedicatedServerUI::Run(hInst, hPrevInst, lpCmdLine, nCmdShow); } else { Platform=Platform_Game; RunFromWinMain( hInst, hPrevInst, lpCmdLine, nCmdShow ); } // jcem - begin g_bLaunched = FALSE; g_pfnVehGetShutdownState = NULL; g_pfnCTCL_GetType = NULL; // jcem - end return 0; } // jcem - start int __stdcall CTCL_GetType(void* instance, int args, void* data[]) { return CTCL_GetType(); } int __stdcall CTCL_IsConsole(void* instance, int args, void* data[]) { return CTCL_IsConsole(); } int __stdcall CTCL_IsConsoleX(void* instance, int args, void* data[]) { return CTCL_IsConsoleX(); } int __stdcall CTCL_Get(void* instance, int args, void* data[]) { // mw4 project - mw4shell.cpp int nRet = 0, param_number = VALUEPARM(0); switch (param_number) { case _CTCL_GetTeslaCountAll: ASSERT(CTCL_IsConsole()); nRet = CTCL_GetTeslaCountAll(); break; case _CTCL_GetTeslaCount: ASSERT(CTCL_IsConsole()); nRet = CTCL_GetTeslaCount(); break; case _CTCL_GetTeslaInfo: { ASSERT(CTCL_IsConsole()); int nIdx = INTPARM(1); ASSERT((0 <= nIdx) && (nIdx < CTCL_GetTeslaCountAll())); STeslaInfo TI; CTCL_GetTeslaInfo(nIdx, TI); nRet = TI.m_nLauncherConnection; INTPARM(2) = TI.m_nConnection2; INTPARM(3) = TI.m_nApplType; INTPARM(4) = TI.m_nApplState; INTPARM(5) = TI.m_nGameState; int nGameTime = TI.m_nGameTime; int nGameIsServer = TI.m_nGameIsServer; if ((TI.m_nApplType != _EAT_None) && (TI.m_nApplState == _EAS_Launched)) { switch(TI.m_nGameState) { default: case _EGS_None: case _EGS_Idle: case _EGS_Closing: nGameTime = -1; // indetermined nGameIsServer = 2; // indetermined break; case _EGS_Preparing: nGameTime = -1; // indetermined break; case _EGS_Running: //if (!nGameIsServer) // nGameTime = -1; // indetermined break; } } else { nGameTime = -1; // indetermined nGameIsServer = 2; // indetermined } INTPARM(6) = nGameTime; INTPARM(7) = nGameIsServer; break; } case _CTCL_GetTeslaName: { ASSERT(CTCL_IsConsole()); int nIdx = INTPARM(1); ASSERT((0 <= nIdx) && (nIdx < CTCL_GetTeslaCountll())); strcpy(STRPARM(2), CTCL_GetTeslaName(nIdx)); break; } case _CTCL_GetInviteCOOP: gosASSERT(FALSE); break; default: break; } return nRet; } int __stdcall CTCL_Set(void* instance, int args, void* data[]) { // mw4 project - mw4shell.cpp int nRet = 0, param_number = VALUEPARM(0); switch (param_number) { case _CTCL_GetTeslaCountAll: case _CTCL_GetTeslaCount: ASSERT(CTCL_IsConsole()); ASSERT(FALSE); break; case _CTCL_GetTeslaInfo: case _CTCL_GetTeslaName: gosASSERT(FALSE); break; case _CTCL_OrderAppl: { ASSERT(CTCL_IsConsole()); int nIdx = INTPARM(1); ASSERT((0 <= nIdx) && (nIdx < CTCL_GetTeslaCountAll())); CTCL_OrderAppl(nIdx, VALUEPARM(2), _EAT_MW4); } break; case _CTCL_SetInviteCOOP: gosASSERT(FALSE); break; default: break; } return nRet; } BOOL __stdcall CTCL_Before() { BOOL bRet; gos_PushCurrentHeap(MechWarrior4::Heap); if (g_nCTCL != _ECTCL_None) { if (g_nCTCL != _ECTCL_Console) { // _ECTCL_Game or _ECTCL_CameraShip CTCL_SetApplType(_EAT_MW4); CTCL_SetApplState(_EAS_PreLaunch); } if (CTCL_Start(g_nCTCL)) { bRet = TRUE; } else { bRet = FALSE; } } else { bRet = TRUE; } gos_PopCurrentHeap(); return bRet; } void __stdcall CTCL_After() { gos_PushCurrentHeap(MechWarrior4::Heap); if (g_nCTCL != _ECTCL_None) { CTCL_SetApplState(_EAS_PostLaunch); g_pfnCTCL_Proc = NULL; CTCL_Stop(); if (g_nCTCL != _ECTCL_Console) { // _ECTCL_Game or _ECTCL_CameraShip CTCL_SetGameState(_EGS_None); CTCL_SetApplState(_EAS_None); CTCL_SetApplType(_EAT_None); } } gos_PopCurrentHeap(); } void __stdcall CTCL_Proc() { gos_PushCurrentHeap(MechWarrior4::Heap); CTCL_Run(); gos_PopCurrentHeap(); } void CTCL_API CTCL_DoTerminateAppl() { gos_TerminateApplication(); } void CTCL_API CTCL_DoMainShell() { if (MW4Shell::Instance) MW4Shell::Instance->StartMainShell(); } void CTCL_API CTCL_DoCreateGame() { //$$COOP g_fLastGameStart = gos_GetElapsedTime(); gos_NetStartGame(NULL, MWApplication::SecureNetGame); CancelDialup(NULL, 0, NULL); LoadMPConnectionSettings(NULL, 0, NULL); InitConnectionWizard(NULL, 0, NULL); ConnectionIndex = 0; PreConnect(NULL, 0, NULL); char* pcsz = &g_aPlayerInfos[0].m_szName[0];; if (*pcsz == '\0') pcsz = &g_szTeslaAddr[0]; if (*pcsz == '\x01') pcsz++; CTCL_DefaultHostSetup(0); int error = Mech4CreateGame(&g_szGameName[0], pcsz/*PlayerName*/, NULL/*GamePassword*/); if (error == 0) { CTCL_DoGame1st(); } else { if (g_bCOOP) { g_InviteCOOP.m_pParent = NULL; g_InviteCOOP.Clear(); } g_nMech4Comm = 0; gos_NetEndGame(); // gos_NetDoneStartGame(); ? MW4Shell::Instance->StartMainShell(); if (!g_bCOOP) { CTCL_DoSendGameReturn(_EGR_ErrCreateSession); } } } void CTCL_API CTCL_DoJoinGame() { gos_NetStartGame(NULL, MWApplication::SecureNetGame); CancelDialup(NULL, 0, NULL); LoadMPConnectionSettings(NULL, 0, NULL); InitConnectionWizard(NULL, 0, NULL); ConnectionIndex = 0; PreConnect(NULL, 0, NULL); CreateBrowsers(NULL, 0, NULL); #if 0 if (0 < GetTotalGameCount(NULL, 0, NULL)) RefreshGameList(); else #endif UpdateGameList(NULL, 0, NULL); g_nMech4Comm = 1; g_dwJoinStartTicks = GetTickCount(); } void CTCL_API CTCL_CheckJoinGame() { extern int __stdcall gos_GameIsExist( const char* pcszGameName); if (gos_GameIsExist(&g_szGameName[0])) { MWApplication* app = MWApplication::GetInstance(); app->haveNetworkMap = false; char* pcsz = &g_aPlayerInfos[0].m_szName[0]; if (*pcsz == '\0') pcsz = &g_szTeslaAddr[0]; if (*pcsz == '\x01') pcsz++; int error = gos_JoinGame(&g_szGameName[0], pcsz/*PlayerName*/, NULL/*GamePassword*/, NULL/*NGPassword*/); if (error == 0) { CTCL_DoGame1st(); } else { if (g_bCOOP) { g_InviteCOOP.m_pParent = NULL; g_InviteCOOP.Clear(); } g_nMech4Comm = 0; gos_NetEndGame(); // gos_NetDoneStartGame(); ? MW4Shell::Instance->StartMainShell(); if (!g_bCOOP) { CTCL_DoSendGameReturn(_EGR_ErrJoinSession); } } } else { if ((g_dwJoinStartTicks + 25000) <= GetTickCount()) { if (g_bCOOP) { g_InviteCOOP.m_pParent = NULL; g_InviteCOOP.Clear(); } g_nMech4Comm = 0; gos_NetEndGame(); // gos_NetDoneStartGame(); ? MW4Shell::Instance->StartMainShell(); if (!g_bCOOP) { CTCL_DoSendGameReturn(_EGR_ErrJoinSession); } } } } void CTCL_API CTCL_DoGame1st() { MWApplication* app = MWApplication::GetInstance(); /*MWApplication *app = Cast_Object(MWApplication *, Application::GetInstance()); NetMissionParameters::MWNetMissionParameters *params = app->GetLocalNetParams(); Str_Copy(params->m_serverName, GameName, STRING_SIZE); Str_Copy(params->m_serverIP, LocalIPAddress, STRING_SIZE);*/ gos_NetDoneStartGame(); DWORD networking; networking = reinterpret_cast(gos_NetInformation(gos_Networking, 0)); app->networkingFlag = (networking)?true:false; if (app->networkingFlag) { //$$COOP DWORD server = reinterpret_cast(gos_NetInformation(gos_AmITheServer, 0)); app->serverFlag = (server)?true:false; if (Network::GetInstance() == NULL) { gos_PushCurrentHeap(MechWarrior4::Heap); Verify(!Network::GetInstance()); GlobalPointers::AddGlobalPointer(new Network, NetworkGlobalPointerIndex); Register_Object(Network::GetInstance()); gos_PopCurrentHeap(); } if (app->serverFlag) { ASSERT(g_bIsServer); // save the options that were set app->SaveServerOptions(); #if defined(LAB_ONLY) MWGameInfo::g_lastGameType = MWGameInfo::g_currentGameType; MWGameInfo::g_currentGameType = MWGameInfo::MultiServer; #endif //app->LoadServerOptions(); app->SendRequestConnectionMessage(); } else { ASSERT(!g_bIsServer); app->GetLocalNetParams()->ResetParameters(); app->GetServerNetParams()->ResetParameters(); app->haveNetworkMap = false; } g_fLastGameStart = gos_GetElapsedTime(); if (g_bCOOP) { if (app->serverFlag) { MW4Shell::Instance->StartNetworkServerExecute(); g_nMech4Comm = 0; } else { MW4Shell::Instance->StartNetworkClientExecute(); g_nMech4Comm = 2; } } else { for (int i = 0; i < Maximum_Lancemates; ++i) { app->lancemateConnectionData[i].Disconnect(); } app->memoryDiffKiller.Init(); g_nMech4Comm = 2; } } else { // is this possible? if (g_bCOOP) { g_InviteCOOP.m_pParent = NULL; g_InviteCOOP.Clear(); } g_nMech4Comm = 0; gos_NetEndGame(); MW4Shell::Instance->StartMainShell(); if (!g_bCOOP) { if (g_bIsServer) CTCL_DoSendGameReturn(_EGR_ErrCreateSession); else CTCL_DoSendGameReturn(_EGR_ErrJoinSession); } } } void CTCL_API CTCL_StartGame(BOOL bRealLaunch) { //$$COOP if (bRealLaunch) { g_nMech4Comm = 11; } else { MW4Shell::Instance->EndAllScripts(); MW4Shell::Instance->currentShellRunning = MW4Shell::MainShellRunning; //MW4Shell::NoShellRunning; MW4Shell::Instance->shellCommand = MW4Shell::StartNetworkGameCommand; MW4Shell::Instance->shellStart = MW4Shell::MainShellStart; g_nMech4Comm = 9; } } int _stdcall __CTCL_GetType() { return g_nCTCL; } // jcem - end