Example #1
0
//-----------------------------------------------------------------------------
// Purpose: Return the directory where this .exe is running from
// Output : char
//-----------------------------------------------------------------------------
char *UTIL_GetBaseDir( void )
{
	static char	basedir[ MAX_PATH ];
	int j;
	char *pBuffer = NULL;

	basedir[ 0 ] = 0;

	if ( Sys_GetExecutableName( basedir ) )
	{

		pBuffer = strrchr( basedir,'\\' );

		if ( *pBuffer )
		{
			*(pBuffer+1) = '\0';
		}


		j = strlen( basedir );
		if (j > 0)
		{
			if ( ( basedir[ j-1 ] == '\\' ) || 
				 ( basedir[ j-1 ] == '/' ) )
			{
				basedir[ j-1 ] = 0;
			}
		}
	}

	return basedir;
}
bool FileSystem_GetExecutableDir( char *exedir, int exeDirLen )
{
	exedir[0] = 0;

	if ( s_bUseVProjectBinDir )
	{
		const char *pProject = GetVProjectCmdLineValue();
		if ( !pProject )
		{
			// Check their registry.
			pProject = getenv( GAMEDIR_TOKEN );
		}
		if ( pProject )
		{
			Q_snprintf( exedir, exeDirLen, "%s%c..%cbin", pProject, CORRECT_PATH_SEPARATOR, CORRECT_PATH_SEPARATOR );
			return true;
		}
		return false;
	}

	if ( !Sys_GetExecutableName( exedir, exeDirLen ) )
		return false;
	Q_StripFilename( exedir );

	if ( IsX360() )
	{
		// The 360 can have its exe and dlls reside on different volumes
		// use the optional basedir as the exe dir
		if ( CommandLine()->FindParm( "-basedir" ) )
		{
			strcpy( exedir, CommandLine()->ParmValue( "-basedir", "" ) );
		}
	}

	Q_FixSlashes( exedir );

	// Return the bin directory as the executable dir if it's not in there
	// because that's really where we're running from...
	char ext[MAX_PATH];
	Q_StrRight( exedir, 4, ext, sizeof( ext ) );
	if ( ext[0] != CORRECT_PATH_SEPARATOR || Q_stricmp( ext+1, "bin" ) != 0 )
	{
		Q_strncat( exedir, CORRECT_PATH_SEPARATOR_S, exeDirLen, COPY_ALL_CHARACTERS );
		Q_strncat( exedir, "bin", exeDirLen, COPY_ALL_CHARACTERS );
		Q_FixSlashes( exedir );
	}
	
	return true;
}
//-----------------------------------------------------------------------------
// Adds the platform folder to the search path.
//-----------------------------------------------------------------------------
void FileSystem_AddSearchPath_Platform( IFileSystem *pFileSystem, const char *szGameInfoPath )
{
	char platform[MAX_PATH];
	if ( pFileSystem->IsSteam() )
	{
		// Steam doesn't support relative paths
		Q_strncpy( platform, "platform", MAX_PATH );
	}
	else
	{
		if ( !Sys_GetExecutableName( platform, sizeof( platform ) ) )
		{
			// fall back to old method if we can't get the executable name
			Q_strncpy( platform, szGameInfoPath, MAX_PATH );
			Q_StripTrailingSlash( platform );
			Q_strncat( platform, "/../platform", MAX_PATH, MAX_PATH );
		}
		else
		{
			Q_StripFilename( platform );
			Q_StripTrailingSlash( platform );
			Q_FixSlashes( platform );

			// remove bin folder if necessary
			int nLen = Q_strlen( platform );
			if ( ( nLen > 4 )
					&& platform[ nLen - 4 ] == CORRECT_PATH_SEPARATOR
					&& !Q_stricmp( "bin", platform + ( nLen - 3 ) )
				)
			{
				Q_StripLastDir( platform, sizeof( platform ) );
				Q_StripTrailingSlash( platform );
			}
			// go into platform folder
			Q_strncat( platform, "/platform", MAX_PATH, MAX_PATH );
		}
	}

	pFileSystem->AddSearchPath( platform, "PLATFORM" );
}
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	HANDLE hObject = NULL;
	BOOL (*IsDebuggerPresent)(void) = (BOOL (*)(void))GetProcAddress(GetModuleHandle("kernel32.dll"), "IsDebuggerPresent");

	if (!IsDebuggerPresent())
	{
		hObject = CreateMutex(NULL, FALSE, "ValveHalfLifeLauncherMutex");

		DWORD dwStatus = WaitForSingleObject(hObject, 0);

		if (dwStatus && dwStatus != WAIT_ABANDONED)
		{
			MessageBox(NULL, "Could not launch game.\nOnly one instance of this game can be run at a time.", "Error", MB_ICONERROR);
			return 0;
		}
	}

	WSAData WSAData;
	WSAStartup(2, &WSAData);

	registry->Init();
	CommandLine()->CreateCmdLine(GetCommandLine());
	CommandLine()->AppendParm("-nomaster", NULL);

	char szFileName[256];
	Sys_GetExecutableName(szFileName, sizeof(szFileName));
	char *szExeName = strrchr(szFileName, '\\') + 1;

	if (stricmp(szExeName, "hl.exe") && CommandLine()->CheckParm("-game") == NULL)
	{
		szExeName[strlen(szExeName) - 4] = '\0';
		CommandLine()->AppendParm("-game", szExeName);
	}

	const char *_szGameName;
	static char szGameName[32];
	const char *szGameStr = CommandLine()->CheckParm("-game", &_szGameName);
	strcpy(szGameName, _szGameName);

	if (szGameStr && !strnicmp(&szGameStr[6], "czero", 5))
		CommandLine()->AppendParm("-forcevalve", NULL);

	if (registry->ReadInt("CrashInitializingVideoMode", FALSE))
	{
		registry->WriteInt("CrashInitializingVideoMode", FALSE);

		if (strcmp(registry->ReadString("EngineDLL", "hw.dll"), "hw.dll"))
		{
			if (registry->ReadInt("EngineD3D", FALSE))
			{
				registry->WriteInt("EngineD3D", FALSE);

				if (MessageBox(NULL, "The game has detected that the previous attempt to start in D3D video mode failed.\nThe game will now run attempt to run in openGL mode.", "Video mode change failure", MB_OKCANCEL | MB_ICONWARNING) != IDOK)
					return 0;
			}
			else
			{
				registry->WriteString("EngineDLL", "sw.dll");

				if (MessageBox(NULL, "The game has detected that the previous attempt to start in openGL video mode failed.\nThe game will now run in software mode.", "Video mode change failure", MB_OKCANCEL | MB_ICONWARNING) != IDOK)
					return 0;
			}

			registry->WriteInt("ScreenWidth", 640);
			registry->WriteInt("ScreenHeight", 480);
			registry->WriteInt("ScreenBPP", 16);
		}
	}

	while (1)
	{
		HINTERFACEMODULE hFileSystem = LoadFilesystemModule();

		if (!hFileSystem)
			break;

		MH_Init(szGameName);

		CreateInterfaceFn fsCreateInterface = (CreateInterfaceFn)Sys_GetFactory(hFileSystem);
		g_pFileSystem = (IFileSystem *)fsCreateInterface(FILESYSTEM_INTERFACE_VERSION, NULL);
		g_pFileSystem->Mount();
		g_pFileSystem->AddSearchPath(Sys_GetLongPathName(), "ROOT");

		static char szNewCommandParams[2048];
		const char *pszEngineDLL;
		int iResult = ENGINE_RESULT_NONE;

		szNewCommandParams[0] = 0;
		SetEngineDLL(pszEngineDLL);

		g_blobfootprintClient.m_hDll = NULL;

		IEngine *engineAPI = NULL;
		HINTERFACEMODULE hEngine;
		bool bUseBlobDLL = false;

		if (FIsBlob(pszEngineDLL))
		{
			Sys_CloseDEP();
			SetupExceptHandler3();
			NLoadBlobFile(pszEngineDLL, &g_blobfootprintClient, (void **)&engineAPI);
			bUseBlobDLL = true;
		}
		else
		{
			hEngine = Sys_LoadModule(pszEngineDLL);

			if (!hEngine)
			{
				static char msg[512];
				wsprintf(msg, "Could not load %s.\nPlease try again at a later time.", pszEngineDLL);
				MessageBox(NULL, msg, "Fatal Error", MB_ICONERROR);
				break;
			}

			CreateInterfaceFn engineCreateInterface = (CreateInterfaceFn)Sys_GetFactory(hEngine);
			engineAPI = (IEngine *)engineCreateInterface(VENGINE_LAUNCHER_API_VERSION, NULL);

			if (!engineCreateInterface || !engineAPI)
				Sys_FreeModule(hEngine);
		}

		if (engineAPI)
		{
			MH_LoadEngine(bUseBlobDLL ? NULL : (HMODULE)hEngine);
			iResult = engineAPI->Run(hInstance, Sys_GetLongPathName(), CommandLine()->GetCmdLine(), szNewCommandParams, Sys_GetFactoryThis(), Sys_GetFactory(hFileSystem));
			MH_ExitGame(iResult);

			if (bUseBlobDLL)
				FreeBlob(&g_blobfootprintClient);
			else
				Sys_FreeModule(hEngine);
		}

		if (iResult == ENGINE_RESULT_NONE || iResult > ENGINE_RESULT_UNSUPPORTEDVIDEO)
			break;

		bool bContinue;

		switch (iResult)
		{
			case ENGINE_RESULT_RESTART:
			{
				bContinue = true;
				break;
			}

			case ENGINE_RESULT_UNSUPPORTEDVIDEO:
			{
				bContinue = OnVideoModeFailed();
				break;
			}
		}

		CommandLine()->RemoveParm("-sw");
		CommandLine()->RemoveParm("-startwindowed");
		CommandLine()->RemoveParm("-windowed");
		CommandLine()->RemoveParm("-window");
		CommandLine()->RemoveParm("-full");
		CommandLine()->RemoveParm("-fullscreen");
		CommandLine()->RemoveParm("-soft");
		CommandLine()->RemoveParm("-software");
		CommandLine()->RemoveParm("-gl");
		CommandLine()->RemoveParm("-d3d");
		CommandLine()->RemoveParm("-w");
		CommandLine()->RemoveParm("-width");
		CommandLine()->RemoveParm("-h");
		CommandLine()->RemoveParm("-height");
		CommandLine()->RemoveParm("-novid");

		if (strstr(szNewCommandParams, "-game"))
			CommandLine()->RemoveParm("-game");

		if (strstr(szNewCommandParams, "+load"))
			CommandLine()->RemoveParm("+load");

		CommandLine()->AppendParm(szNewCommandParams, NULL);

		g_pFileSystem->Unmount();
		Sys_FreeModule(hFileSystem);
		MH_Shutdown();

		if (!bContinue)
			break;
	}

	registry->Shutdown();

	if (hObject)
	{
		ReleaseMutex(hObject);
		CloseHandle(hObject);
	}

	WSACleanup();
	MH_Shutdown();
	TerminateProcess(GetCurrentProcess(), 1);
	return 1;
}