Display roles are auto-detected in FindVideoCards(): the main view takes the
first hardware-rasterizing device that is not a 1280x480-capable span, the radar
takes the next, and mode 4's two MFD panels take the two after that. That works
until DirectDraw enumerates the adapters in an unexpected order, at which point
the wrong content appears on the wrong monitor with no way to correct it.
Adds an override that keeps auto-detection as the default:
-tmon <main>,<radar>,<mfd1>,<mfd2>
Values are 1-based, so the normal case is "-tmon 1,2,3,4". A value of 0 leaves
that slot auto-detected, so "-tmon 2,1,0,0" swaps only main and radar. Separators
may be ',' '/' or ':'. mfd1/mfd2 are only meaningful with -tmfds 4. Omitting the
switch entirely preserves existing behaviour exactly.
Implementation:
- Parsed in MW4Application's WinMain alongside -tmfds. That runs before GameOS
calls FindVideoCards(), so the values are in place for device selection.
- Stored in g_naMonitorOverride[4] (VideoCard.cpp), extern'd in MW4Application.cpp.
- ApplyMonitorOverride() validates the index against NumDevices, so a stale -tmon
on a machine with fewer monitors falls back to auto-detection rather than
breaking startup.
- Ordering matters and is deliberate: main and radar are applied BEFORE the mode 4
MFD search so that search still skips whichever devices the operator picked;
mfd1/mfd2 are applied after it. Partial overrides therefore compose correctly.
Role map: main = Environment.FullScreenDevice, radar = g_nNonDualHead,
mfd1 = g_nMFD1, mfd2 = g_nMFD2. The mode 1 span (g_nDualHead) is intentionally
not overridable -- it is detected by 1280x480 mode support, which only the span
card advertises, so that detection is reliable.
Also adds a SPEW line logging the final role -> device map and device count.
Note this is only visible in Profile/LAB builds; SPEW compiles out in Release
(gos2X/Gos.h), so in Release the order is determined by observation.
Verified: compiles clean, console launches. Multi-monitor testing pending.
Co-authored-by: Claude Opus 5 (Anthropic) <noreply@anthropic.com>
Co-authored-by: GitHub Copilot <copilot@github.com>
1946 lines
54 KiB
C++
1946 lines
54 KiB
C++
//===========================================================================//
|
|
// 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 <windows.h>
|
|
#include <MW4DedicatedUI\DedicatedUI.hpp>
|
|
#include <GameOS\GameOS.hpp>
|
|
#include <GameOS\Platform.hpp>
|
|
#include <GameOs\Network.hpp>
|
|
#include <gosFX\gosFX.hpp>
|
|
#include <gosFX\EffectLibrary.hpp>
|
|
#include <Adept\Application.hpp>
|
|
#include <MW4\MWApplication.hpp>
|
|
#include <gosScript\gosScriptHeaders.hpp>
|
|
#include <Adept\ResourceImagePool.hpp>
|
|
#include <MW4\MWMission.hpp>
|
|
#include <MW4\MWPlayer.hpp>
|
|
#include <Compost\Compost.hpp>
|
|
#include <mw4\gameinfo.hpp>
|
|
#include <Adept\ResourceEffectLibrary.hpp>
|
|
#include <mw4\ai_statistics.hpp>
|
|
#include "mw4\mw4shell.hpp"
|
|
#include "mw4\hudcomp.hpp"
|
|
|
|
#include <Adept\GlobalPointerManager.hpp>
|
|
|
|
#include <MW4\MWTool.hpp>
|
|
#include <Stuff\Random.hpp>
|
|
|
|
#include <MLR\MLR.hpp>
|
|
#include <MLR\MLRTexturePool.hpp>
|
|
#include <MLR\MLRTexture.hpp>
|
|
#include <adept\gamespy\gamespy.h>
|
|
#include <GameOS\GUNGameList.h>
|
|
#include <process.h>
|
|
|
|
#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 <mw4/nglog_mw4.hpp>
|
|
|
|
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<MString, FileStream*>;
|
|
|
|
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<MString, FileStream*> *map = (stlport::map<MString, FileStream*>*)NotationFile::s_cachedIncludes;
|
|
stlport::map<MString, FileStream*>::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
|
|
);
|
|
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 <name> specified"));
|
|
}
|
|
|
|
if (MWApplication::NetGameName == NULL)
|
|
{
|
|
STOP(("Cant autolaunch without -gamename <name> 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
|
|
}
|
|
|
|
if (strstr(all_lower, "-help"))
|
|
{
|
|
SPEWALWAYS((NULL, "Command line options:\n"));
|
|
SPEWALWAYS((NULL, "-allowmultiple"));
|
|
SPEWALWAYS((NULL, "-lobby"));
|
|
SPEWALWAYS((NULL, "-game <file>"));
|
|
SPEWALWAYS((NULL, "-gamename <name>"));
|
|
SPEWALWAYS((NULL, "-playername <name>"));
|
|
SPEWALWAYS((NULL, "-serve"));
|
|
SPEWALWAYS((NULL, "-join"));
|
|
SPEWALWAYS((NULL, "-nosound"));
|
|
SPEWALWAYS((NULL, "-window"));
|
|
|
|
SPEWALWAYS((NULL, "-zlogstyle <value>"));
|
|
SPEWALWAYS((NULL, "-zlogflush <value>"));
|
|
SPEWALWAYS((NULL, "-zlogbuffer <size>"));
|
|
SPEWALWAYS((NULL, "-zlogname <filename>"));
|
|
|
|
SPEWALWAYS((NULL, "-secure"));
|
|
|
|
SPEWALWAYS((NULL, "-ipx"));
|
|
|
|
|
|
#ifdef LAB_ONLY
|
|
SPEWALWAYS((NULL, "-nodplay"));
|
|
SPEWALWAYS((NULL, "-dontuseipx"));
|
|
SPEWALWAYS((NULL, "-dontusetcp"));
|
|
SPEWALWAYS((NULL, "-dontusegamespy"));
|
|
SPEWALWAYS((NULL, "-dontusegun"));
|
|
SPEWALWAYS((NULL, "-aistats"));
|
|
SPEWALWAYS((NULL, "-oldmpui"));
|
|
SPEWALWAYS((NULL, "-testclasses"));
|
|
SPEWALWAYS((NULL, "-build"));
|
|
SPEWALWAYS((NULL, "-norun"));
|
|
SPEWALWAYS((NULL, "-demo"));
|
|
SPEWALWAYS((NULL, "-rekey"));
|
|
SPEWALWAYS((NULL, "-bloat"));
|
|
SPEWALWAYS((NULL, "-reportnotresourced"));
|
|
SPEWALWAYS((NULL, "-armorlevel <n>"));
|
|
SPEWALWAYS((NULL, "-leak <n>"));
|
|
SPEWALWAYS((NULL, "-diskfirst"));
|
|
#endif
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
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 <main>,<radar>,<mfd1>,<mfd2>
|
|
// 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<DWORD>(gos_NetInformation(gos_Networking, 0));
|
|
|
|
app->networkingFlag = (networking)?true:false;
|
|
|
|
if (app->networkingFlag)
|
|
{
|
|
//$$COOP
|
|
DWORD server = reinterpret_cast<DWORD>(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
|