Exemple #1
0
void CGameServer::PrecacheList()
{
	TMsg("Precaching entities... ");

	size_t iPrecaches = s_aPrecacheClasses.size();
	if (m_pWorkListener)
		m_pWorkListener->SetAction("Precaching entities", iPrecaches);

	size_t i = 0;

	for (auto it = s_aPrecacheClasses.begin(); it != s_aPrecacheClasses.end(); it++)
	{
		CPrecacheItem* pPrecacheItem = &it->second;

		CEntityRegistration* pRegistration = &CBaseEntity::GetEntityRegistration()[pPrecacheItem->m_sClass];
		pRegistration->m_pfnPrecacheCallback();

		if (m_pWorkListener)
			m_pWorkListener->WorkProgress(++i);
	}

	s_aPrecacheClasses.clear();

	// Do this in this order, dependencies matter
	CParticleSystemLibrary::ClearUnreferenced();
	CModelLibrary::ClearUnreferenced();
	CTextureLibrary::ClearUnreferenced();
	CMaterialLibrary::ClearUnreferenced();
	CSoundLibrary::ClearUnreferenced();

	TMsg("Done.\n");
	TMsg(sprintf(tstring("%d models, %d materials, %d textures, %d sounds and %d particle systems precached.\n"), CModelLibrary::GetNumModelsLoaded(), CMaterialLibrary::GetNumMaterials(), CTextureLibrary::GetNumTextures(), CSoundLibrary::GetNumSoundsLoaded(), CParticleSystemLibrary::GetNumParticleSystemsLoaded()));

	m_bAllowPrecaches = false;
}
Exemple #2
0
void ReloadShaders(class CCommand* pCommand, tvector<tstring>& asTokens, const tstring& sCommand)
{
	CShaderLibrary::CompileShaders();
	if (CShaderLibrary::Get()->IsCompiled())
		TMsg("Shaders reloaded.\n");
	else
		TMsg("Shaders compile failed. See shaders.txt\n");
}
Exemple #3
0
void CGameServer::ClientDisconnect(int iClient)
{
	if (!GameNetwork()->IsHost() && iClient == GameNetwork()->GetClientID())
	{
		TMsg("Disconnected from server.\n");
	}
	else
	{
		TMsg(sprintf(tstring("Client %d (") + GameNetwork()->GetClientNickname(iClient) + ") disconnected.\n", iClient));

		CApplication::Get()->OnClientDisconnect(iClient);

		if (GetGame())
			GetGame()->OnClientDisconnect(iClient);
	}
}
Exemple #4
0
void CGameServer::ClientEnterGame(int iClient)
{
	TMsg(sprintf(tstring("Client %d (") + GameNetwork()->GetClientNickname(iClient) + ") entering game.\n", iClient));

	if (GetGame())
		GetGame()->OnClientEnterGame(iClient);

	for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++)
	{
		CBaseEntity* pEntity = CBaseEntity::GetEntity(i);

		if (!pEntity)
			continue;

		::CreateEntity.RunCommand(sprintf(tstring("%s %d %d"), pEntity->GetClassName(), pEntity->GetHandle(), pEntity->GetSpawnSeed()), iClient);
	}

	CGameServerNetwork::UpdateNetworkVariables(iClient, true);

	// Update entities after all creations have been run, so we don't refer to entities that haven't been created yet.
	for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++)
	{
		CBaseEntity* pEntity = CBaseEntity::GetEntity(i);

		if (!pEntity)
			continue;

		pEntity->ClientUpdate(iClient);
	}

	GameNetwork()->CallFunction(iClient, "EnterGame");

	GameNetwork()->CallFunction(iClient, "LoadingDone");
}
Exemple #5
0
void CGameServer::Initialize()
{
	if (m_pWorkListener)
		m_pWorkListener->BeginProgress();

	m_bGotClientInfo = false;
	m_bLoading = true;

	TMsg("Initializing game server\n");

	ReadLevels();

	GameNetwork()->ClearRegisteredFunctions();

	RegisterNetworkFunctions();

	DestroyAllEntities(tvector<tstring>(), true);

	CParticleSystemLibrary::ClearInstances();

	if (!m_pCameraManager)
		m_pCameraManager = new CCameraManager();

	if (m_pWorkListener)
		m_pWorkListener->EndProgress();

	if (m_pWorkListener)
		m_pWorkListener->SetAction("Pending network actions", 0);
}
Exemple #6
0
CConsole* CApplication::GetConsole()
{
	if (m_pConsole == NULL)
	{
		m_pConsole = new CConsole();

		if (developer.GetBool())
			TMsg("Developer mode ON.\n");
	}

	return m_pConsole;
}
Exemple #7
0
void SetCVar(CCommand* pCommand, tvector<tstring>& asTokens, const tstring& sCommand)
{
	CVar* pCVar = dynamic_cast<CVar*>(pCommand);
	TAssert(pCVar);
	if (!pCVar)
		return;

	if (asTokens.size() > 1)
		pCVar->SetValue(asTokens[1]);

	TMsg(sprintf(tstring("%s = %s\n"), pCVar->GetName().c_str(), pCVar->GetValue().c_str()));
}
Exemple #8
0
void CGameServer::Delete(CBaseEntity* pEntity)
{
	TAssert(GameNetwork()->IsHost() || IsLoading());
	if (!(GameNetwork()->IsHost() || IsLoading()))
		TMsg("WARNING: CGameServer::Delete() when not host or not loading.\n");

	if (GameNetwork()->IsHost())
		GameNetwork()->CallFunction(NETWORK_TOCLIENTS, "DestroyEntity", pEntity->GetHandle());

	CNetworkParameters p;
	p.i1 = (int)pEntity->GetHandle();
	DestroyEntity(CONNECTION_GAME, &p);
}
Exemple #9
0
void FireInput(class CCommand* pCommand, tvector<tstring>& asTokens, const tstring& sCommand)
{
	if (!CVar::GetCVarBool("cheats"))
		return;

	if (asTokens.size() < 3)
	{
		TMsg("Format: ent_input entityname input [optional args]\n");
		return;
	}

	tvector<CBaseEntity*> apEntities;
	CBaseEntity::FindEntitiesByName(asTokens[1], apEntities);

	if (!apEntities.size())
	{
		if (CVar::GetCVarBool("debug_entity_outputs"))
			TMsg("Console -> none\n");
		else
			TError("No entities found that match name \"" + asTokens[1] + "\".\n");

		return;
	}

	tstring sArgs;
	for (size_t i = 3; i < asTokens.size(); i++)
		sArgs += asTokens[i] + " ";

	for (size_t i = 0; i < apEntities.size(); i++)
	{
		CBaseEntity* pTargetEntity = apEntities[i];

		if (CVar::GetCVarBool("debug_entity_outputs"))
			TMsg("Console -> " + tstring(pTargetEntity->GetClassName()) + "(\"" + pTargetEntity->GetName() + "\")." + asTokens[2] + "(\"" + sArgs + "\")\n");

		pTargetEntity->CallInput(asTokens[2], sArgs);
	}
}
Exemple #10
0
void CGameServer::ReadLevels()
{
	for (size_t i = 0; i < m_apLevels.size(); i++)
		m_apLevels[i].reset();

	m_apLevels.clear();

	if (m_pWorkListener)
		m_pWorkListener->SetAction("Reading meta-structures", 0);

	ReadLevels("levels");

	TMsg(sprintf(tstring("Read %d levels from disk.\n"), m_apLevels.size()));
}
void CCharacterController::PreStep(btCollisionWorld* pCollisionWorld)
{
	int i = 0;
	while (RecoverFromPenetration(pCollisionWorld))
	{
		i++;

		if (i > phys_maxpenetrationrecover.GetInt())
		{
			TMsg(tsprintf("%f Character controller couldn't recover from penetration.\n", GameServer()->GetGameTime()));
			break;
		}
	}
}
void CALLBACK GLDebugCallback(GLenum iSource, GLenum iType, GLuint id, GLenum iSeverity, GLsizei iLength, const GLchar* pszMessage, GLvoid* pUserParam)
{
	if (iType != GL_DEBUG_TYPE_PERFORMANCE_ARB)
	{
		TAssert(iSeverity != GL_DEBUG_SEVERITY_HIGH_ARB);
		TAssert(iSeverity != GL_DEBUG_SEVERITY_MEDIUM_ARB);
	}

	if (gl_debug.GetBool())
	{
		tstring sMessage = "OpenGL Debug Message (";

		if (iSource == GL_DEBUG_SOURCE_API_ARB)
			sMessage += "Source: API ";
		else if (iSource == GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB)
			sMessage += "Source: Window System ";
		else if (iSource == GL_DEBUG_SOURCE_SHADER_COMPILER_ARB)
			sMessage += "Source: Shader Compiler ";
		else if (iSource == GL_DEBUG_SOURCE_THIRD_PARTY_ARB)
			sMessage += "Source: Third Party ";
		else if (iSource == GL_DEBUG_SOURCE_APPLICATION_ARB)
			sMessage += "Source: Application ";
		else if (iSource == GL_DEBUG_SOURCE_OTHER_ARB)
			sMessage += "Source: Other ";

		if (iType == GL_DEBUG_TYPE_ERROR_ARB)
			sMessage += "Type: Error ";
		else if (iType == GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB)
			sMessage += "Type: Deprecated Behavior ";
		else if (iType == GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB)
			sMessage += "Type: Undefined Behavior ";
		else if (iType == GL_DEBUG_TYPE_PORTABILITY_ARB)
			sMessage += "Type: Portability ";
		else if (iType == GL_DEBUG_TYPE_PERFORMANCE_ARB)
			sMessage += "Type: Performance ";
		else if (iType == GL_DEBUG_TYPE_OTHER_ARB)
			sMessage += "Type: Other ";

		if (iSeverity == GL_DEBUG_SEVERITY_HIGH_ARB)
			sMessage += "Severity: High) ";
		else if (iSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB)
			sMessage += "Severity: Medium) ";
		else if (iSeverity == GL_DEBUG_SEVERITY_LOW_ARB)
			sMessage += "Severity: Low) ";

		sMessage += convertstring<GLchar, tchar>(pszMessage) + "\n";

		TMsg(convertstring<GLchar, tchar>(sMessage).c_str());
	}
}
Exemple #13
0
void CCommand::Run(tstring sCommand)
{
	tvector<tstring> asTokens;
	tstrtok(sCommand, asTokens);

	if (asTokens.size() == 0)
		return;

	tmap<tstring, CCommand*>::iterator it = GetCommands().find(asTokens[0]);
	if (it == GetCommands().end())
	{
		TMsg("Unrecognized command.\n");
		return;
	}

	CCommand* pCommand = it->second;
	pCommand->m_pfnCallback(pCommand, asTokens, sCommand);
}
Exemple #14
0
void CGameServer::SetClientNickname(int iClient, const tstring& sNickname)
{
	if (iClient == GetClientIndex() && Game()->GetNumLocalPlayers())
	{
		Game()->GetLocalPlayer(0)->SetPlayerName(sNickname);
		return;
	}

	for (size_t i = 0; i < Game()->GetNumPlayers(); i++)
	{
		if (Game()->GetPlayer(i)->GetClient() == iClient)
		{
			Game()->GetPlayer(i)->SetPlayerName(sNickname);
			return;
		}
	}

	TMsg(sprintf(tstring("Can't find client %d to give nickname %s.\n"), iClient, sNickname.c_str()));
}
Exemple #15
0
void CGameServer::ClientInfo(int iConnection, CNetworkParameters* p)
{
	if (m_iClient != p->i1)
		CGame::ClearLocalPlayers(NULL);

	m_iClient = p->i1;
	float flNewGameTime = p->fl2;
	if (flNewGameTime - m_flGameTime > 0.1f)
		TMsg(sprintf(tstring("New game time from server %.1f different!\n"), flNewGameTime - m_flGameTime));

	m_flGameTime = flNewGameTime;

	// Can't send any client commands until we've gotten the client info because we need m_iClient filled out properly.
	if (!m_bGotClientInfo)
	{
		GameNetwork()->SetRunningClientFunctions(false);
		SendNickname.RunCommand(m_sNickname);
	}

	m_bGotClientInfo = true;
}
Exemple #16
0
size_t CGameServer::CreateEntity(const tstring& sClassName, size_t iHandle, size_t iSpawnSeed)
{
	if (CVar::GetCVarBool("net_debug"))
		TMsg(tstring("Creating entity: ") + sClassName + "\n");

	auto it = CBaseEntity::GetEntityRegistration().find(sClassName);
	if (it == CBaseEntity::GetEntityRegistration().end())
	{
		TAssert(!"Entity does not exist. Did you forget to REGISTER_ENTITY ?");
		return ~0;
	}

	CBaseEntity::s_iOverrideEntityListIndex = iHandle;
	iHandle = it->second.m_pfnCreateCallback();
	CBaseEntity::s_iOverrideEntityListIndex = ~0;

	CEntityHandle<CBaseEntity> hEntity(iHandle);
	hEntity->m_sClassName = sClassName;

	hEntity->SetSaveDataDefaults();

	size_t iPostSeed = mtrand();

	if (iSpawnSeed)
		hEntity->SetSpawnSeed(iSpawnSeed);
	else
		hEntity->SetSpawnSeed(mtrand()%99999);	// Don't pick a number so large that it can't fit in (int)

	hEntity->SetSpawnTime(GameServer()->GetGameTime());

	hEntity->Spawn();

	mtsrand(iPostSeed);

	if (dynamic_cast<CGame*>(hEntity.GetPointer()))
		m_hGame = CEntityHandle<CGame>(hEntity->GetHandle());

	return iHandle;
}
Exemple #17
0
void ShowStatus(class CCommand* pCommand, tvector<tstring>& asTokens, const tstring& sCommand)
{
	TMsg(tstring("Level: ") + CVar::GetCVarValue("game_level") + "\n");
	TMsg(sprintf(tstring("Clients: %d Entities: %d/%d\n"), GameNetwork()->GetClientsConnected(), CBaseEntity::GetNumEntities(), GameServer()->GetMaxEntities()));

	for (size_t i = 0; i < Game()->GetNumPlayers(); i++)
	{
		const CPlayer* pPlayer = Game()->GetPlayer(i);
		if (!pPlayer)
			continue;

		if (pPlayer->GetClient() < 0)
			TMsg("Local: ");
		else
			TMsg(sprintf(tstring("%d: "), pPlayer->GetClient()));

		TMsg(pPlayer->GetPlayerName());

		TMsg("\n");
	}
}
void CGameServerNetwork::UpdateNetworkVariables(int iClient, bool bForceAll)
{
	if (!GameNetwork()->IsConnected())
		return;

	double flTime = GameServer()->GetGameTime();

	size_t iMaxEnts = GameServer()->GetMaxEntities();
	for (size_t i = 0; i < iMaxEnts; i++)
	{
		CBaseEntity* pEntity = CBaseEntity::GetEntity(i);
		if (!pEntity)
			continue;

		const tchar* pszClassName = pEntity->GetClassName();

		CEntityRegistration* pRegistration = NULL;
		do
		{
			pRegistration = pEntity->GetRegisteredEntity(pszClassName);

			TAssert(pRegistration);
			if (!pRegistration)
				break;

			size_t iNetVarsSize = pRegistration->m_aNetworkVariables.size();
			for (size_t j = 0; j < iNetVarsSize; j++)
			{
				CNetworkedVariableData* pVarData = &pRegistration->m_aNetworkVariables[j];
				CNetworkedVariableBase* pVariable = pVarData->GetNetworkedVariableBase(pEntity);

				if (!bForceAll)
				{
					if (!pVariable->IsDirty())
						continue;

					if (flTime - pVariable->m_flLastUpdate < pVarData->m_flUpdateInterval)
						continue;
				}

				// For one, m_flLastUpdate needs to be a double
				pVariable->m_flLastUpdate = (float)flTime;
				// For two, it's shit.
				TUnimplemented();
				// Try some testing or something.

				CNetworkParameters p;
				p.ui1 = pEntity->GetHandle();

				size_t iDataSize;
				void* pValue = pVariable->Serialize(iDataSize);

				if (net_replication_debug.GetBool())
				{
					if (iDataSize >= 4)
						TMsg(tstring("Updating ") + pVarData->GetName() + sprintf(tstring(" (%x) (%f) (%d)\n"), *(unsigned int*)pValue, *(float*)pValue, *(int*)pValue));
					else
						TMsg(tstring("Updating ") + pVarData->GetName() + "\n");
				}

				p.CreateExtraData(iDataSize + strlen(pVarData->GetName())+1);
				strcpy((char*)p.m_pExtraData, pVarData->GetName());
				memcpy((unsigned char*)(p.m_pExtraData) + strlen(pVarData->GetName())+1, pValue, iDataSize);

				// UV stands for UpdateValue
				GameNetwork()->CallFunctionParameters(iClient, "UV", &p);

				// Only reset the dirty flag if all clients got the message.
				if (iClient == NETWORK_TOCLIENTS)
					pVariable->SetDirty(false);
			}

			pszClassName = pRegistration->m_pszParentClass;
		} while (pszClassName);
	}
}
Exemple #19
0
CGameServer::CGameServer(IWorkListener* pWorkListener)
{
	TAssert(!s_pGameServer);
	s_pGameServer = this;

	m_bAllowPrecaches = false;

	GameNetwork()->SetCallbacks(this, CGameServer::ClientConnectCallback, CGameServer::ClientEnterGameCallback, CGameServer::ClientDisconnectCallback);

	m_pWorkListener = pWorkListener;

	m_iMaxEnts = g_cfgEngine.read("MaxEnts", 1024);

	CBaseEntity::s_apEntityList.resize(m_iMaxEnts);

	m_pCameraManager = NULL;

	m_iSaveCRC = 0;

	m_bLoading = true;
	m_bRestartLevel = false;

	m_flHostTime = 0;
	m_flGameTime = 0;
	m_flFrameTime = 0;
	m_flTimeScale = 1;
	m_flNextClientInfoUpdate = 0;
	m_iFrame = 0;

	size_t iPostSeed = mtrand();

	if (m_pWorkListener)
		m_pWorkListener->BeginProgress();

	TMsg("Creating physics model... ");
	GamePhysics();	// Just make sure it exists.
	TMsg("Done.\n");

	TMsg("Registering entities... ");

	if (m_pWorkListener)
		m_pWorkListener->SetAction("Registering entities", CBaseEntity::GetEntityRegistration().size());

	tmap<tstring, bool> abRegistered;

	for (tmap<tstring, CEntityRegistration>::iterator it = CBaseEntity::GetEntityRegistration().begin(); it != CBaseEntity::GetEntityRegistration().end(); it++)
		abRegistered[it->first] = false;

	tvector<tstring> asRegisterStack;

	size_t i = 0;
	for (tmap<tstring, CEntityRegistration>::iterator it = CBaseEntity::GetEntityRegistration().begin(); it != CBaseEntity::GetEntityRegistration().end(); it++)
	{
		CEntityRegistration* pRegistration = &it->second;

		if (abRegistered[it->first])
			continue;

		asRegisterStack.clear();
		asRegisterStack.push_back(it->first);

		// Make sure I register all parent classes before I register this one.
		if (pRegistration->m_pszParentClass)
		{
			tstring sThisClass = it->first;
			tstring sParentClass = pRegistration->m_pszParentClass;
			while (!abRegistered[sParentClass])
			{
				// Push to the top, we'll register from the top first.
				asRegisterStack.push_back(sParentClass);

				CEntityRegistration* pRegistration = &CBaseEntity::GetEntityRegistration()[sParentClass];

				sThisClass = sParentClass;
				sParentClass = pRegistration->m_pszParentClass?pRegistration->m_pszParentClass:"";

				if (!sParentClass.length())
					break;
			}
		}

		// The top of the stack is the highest entity on the tree that I must register first.
		while (asRegisterStack.size())
		{
			CBaseEntity::GetEntityRegistration()[asRegisterStack.back()].m_pfnRegisterCallback();
			abRegistered[asRegisterStack.back()] = true;
			asRegisterStack.pop_back();
		}

		if (m_pWorkListener)
			m_pWorkListener->WorkProgress(++i);
	}
	TMsg("Done.\n");

	mtsrand(iPostSeed);

	CBaseEntity::s_iNextEntityListIndex = 0;

	m_iPort = 0;
	m_iClient = NETWORK_LOCAL;

	m_bHalting = false;

	if (m_pWorkListener)
		m_pWorkListener->EndProgress();
}
Exemple #20
0
bool CGeppetto::BuildFromInputScript(const tstring& sScript)
{
	FILE* fp = tfopen_asset(GetPath(sScript), "r");
	if (!fp)
	{
		TError("Could not read input script '" + sScript + "'\n");
		return false;
	}

	std::shared_ptr<CData> pData(new CData());
	CDataSerializer::Read(fp, pData.get());

	CData* pOutput = pData->FindChild("Output");
	if (!pOutput)
	{
		TError("Could not find Output section in input script '" + sScript + "'\n");
		return false;
	}

	CData* pGame = pData->FindChild("Game");
	if (!pGame)
	{
		TError("Could not find Game section in input script '" + sScript + "'\n");
		return false;
	}

	t.SetGameDirectory(FindAbsolutePath(GetPath(pGame->GetValueString())));

	tstring sOutputDir = ToForwardSlashes(pOutput->GetValueString());
	t.SetOutputDirectory(GetDirectory(sOutputDir));
	t.SetOutputFile(GetFilename(sOutputDir));
	t.SetScriptDirectory(GetDirectory((GetPath(sScript))));

	m_sOutput = FindAbsolutePath(t.GetGameDirectory() + T_DIR_SEP + pOutput->GetValueString());

	CData* pSceneAreas = pData->FindChild("SceneAreas");
	CData* pMesh = pData->FindChild("Mesh");
	CData* pPhysics = pData->FindChild("Physics");
	CData* pPhysicsShapes = pData->FindChild("PhysicsShapes");

	// Find all file modification times.
	time_t iScriptModificationTime = GetFileModificationTime(sScript.c_str());
	time_t iOutputModificationTime = GetFileModificationTime(m_sOutput.c_str());

	tmap<tstring, time_t> aiSceneModificationTimes;

	if (pSceneAreas)
	{
		for (size_t i = 0; i < pSceneAreas->GetNumChildren(); i++)
		{
			CData* pArea = pSceneAreas->GetChild(i);

			if (pArea->GetKey() != "Area")
				continue;

			tstring sFile = pArea->FindChildValueString("File");
			TAssert(sFile.length());
			if (!sFile.length())
				continue;

			auto it = aiSceneModificationTimes.find(sFile);
			if (it == aiSceneModificationTimes.end())
				aiSceneModificationTimes[sFile] = GetFileModificationTime(sFile.c_str());
		}
	}

	time_t iInputModificationTime = 0;
	if (pMesh)
		iInputModificationTime = GetFileModificationTime(pMesh->GetValueString().c_str());
	time_t iPhysicsModificationTime = 0;
	if (pPhysics)
		iPhysicsModificationTime = GetFileModificationTime(pPhysics->GetValueString().c_str());

	bool bRecompile = false;
	if (iScriptModificationTime > iOutputModificationTime)
		bRecompile = true;
	else if (iInputModificationTime > iOutputModificationTime)
		bRecompile = true;
	else if (iPhysicsModificationTime > iOutputModificationTime)
		bRecompile = true;
	else if (m_iBinaryModificationTime > iOutputModificationTime)
		bRecompile = true;
	else
	{
		for (auto it = aiSceneModificationTimes.begin(); it != aiSceneModificationTimes.end(); it++)
		{
			if (it->second > iOutputModificationTime)
			{
				bRecompile = true;
				break;
			}
		}
	}

	if (!bRecompile)
	{
		if (m_bForceCompile)
		{
			TMsg("Forcing rebuild even though no changes detected.\n");
		}
		else
		{
			TMsg("No changes detected. Skipping '" + m_sOutput + "'.\n\n");
			return true;
		}
	}

	CData* pGlobalTransforms = pData->FindChild("UseGlobalTransforms");
	if (pGlobalTransforms)
		t.UseGlobalTransformations();
	else
		t.UseLocalTransformations();

	t.UseUV();
	t.UseNormals();

	if (pMesh)
	{
		tstring sExtension = pMesh->GetValueString().substr(pMesh->GetValueString().length()-4);
		if (sExtension == ".png")
		{
			TUnimplemented();	// Not updated since the switch to materials.
			int x, y, n;
			unsigned char* pData = stbi_load((GetPath(pMesh->GetValueString())).c_str(), &x, &y, &n, 0);

			if (!pData)
			{
				TError("Couldn't load '" + pMesh->GetValueString() + "', reason: " + stbi_failure_reason() + "\n");
				return false;
			}

			stbi_image_free(pData); // Don't need it, just need the dimensions.

			Vector vecUp = Vector(0, 0, 0.5f) * ((float)y/100);
			Vector vecLeft = Vector(0, 0.5f, 0) * ((float)x/100);

			t.UseNormals(false);

			if (IsAbsolutePath(pMesh->GetValueString()))
				t.AddMaterial(GetPath(pMesh->GetValueString()));
			else
				t.AddMaterial(t.GetOutputDirectory() + "/" + pMesh->GetValueString(), GetPath(pMesh->GetValueString()));
			t.AddVertex(0, -vecLeft + vecUp, Vector2D(0.0f, 1.0f));
			t.AddVertex(0, -vecLeft - vecUp, Vector2D(0.0f, 0.0f));
			t.AddVertex(0, vecLeft - vecUp, Vector2D(1.0f, 0.0f));

			t.AddVertex(0, -vecLeft + vecUp, Vector2D(0.0f, 1.0f));
			t.AddVertex(0, vecLeft - vecUp, Vector2D(1.0f, 0.0f));
			t.AddVertex(0, vecLeft + vecUp, Vector2D(1.0f, 1.0f));
		}
		else if (sExtension == ".mat")
		{
			CMaterialHandle hMaterial(pMesh->GetValueString());
			if (!hMaterial.IsValid())
			{
				TError("Input material  '" + pMesh->GetValueString() + "' does not exist or is invalid.\n");
				return false;
			}

			if (!hMaterial->m_ahTextures.size())
			{
				TError("Input material  '" + pMesh->GetValueString() + "' has no textures.\n");
				return false;
			}

			float w = (float)hMaterial->m_ahTextures[0]->m_iWidth;
			float h = (float)hMaterial->m_ahTextures[0]->m_iHeight;

			Vector vecUp = Vector(0, 0.5f, 0) * (h/hMaterial->m_iTexelsPerMeter);
			Vector vecRight = Vector(0, 0, 0.5f) * (w/hMaterial->m_iTexelsPerMeter);

			t.UseNormals(false);

			t.AddMaterial(pMesh->GetValueString());

			t.AddVertex(0, -vecRight + vecUp, Vector2D(0.0f, 1.0f));
			t.AddVertex(0, -vecRight - vecUp, Vector2D(0.0f, 0.0f));
			t.AddVertex(0, vecRight - vecUp, Vector2D(1.0f, 0.0f));

			t.AddVertex(0, -vecRight + vecUp, Vector2D(0.0f, 1.0f));
			t.AddVertex(0, vecRight - vecUp, Vector2D(1.0f, 0.0f));
			t.AddVertex(0, vecRight + vecUp, Vector2D(1.0f, 1.0f));
		}
		else
		{
			TMsg("Reading model '" + GetPath(pMesh->GetValueString()) + "' ...");
			std::shared_ptr<CConversionScene> pScene(new CConversionScene());
			CModelConverter c(pScene.get());

			if (!c.ReadModel(GetPath(pMesh->GetValueString())))
			{
				TError("Couldn't read '" + GetPath(pMesh->GetValueString()) + "'.\n");
				return false;
			}
			TMsg(" Done.\n");

			TMsg("Building toy mesh ...");
			LoadSceneIntoToy(pScene.get(), &t);
			TMsg(" Done.\n");
		}
	}

	if (pPhysics)
	{
		TMsg("Reading physics model '" + GetPath(pPhysics->GetValueString()) + "' ...");
		std::shared_ptr<CConversionScene> pScene(new CConversionScene());
		CModelConverter c(pScene.get());

		if (!c.ReadModel(GetPath(pPhysics->GetValueString())))
		{
			TError("Couldn't read '" + GetPath(pPhysics->GetValueString()) + "'.\n");
			return false;
		}
		TMsg(" Done.\n");

		TMsg("Building toy physics model ...");
		LoadSceneIntoToyPhysics(pScene.get(), &t);
		TMsg(" Done.\n");
	}

	if (pPhysicsShapes)
	{
		for (size_t i = 0; i < pPhysicsShapes->GetNumChildren(); i++)
		{
			CData* pShape = pPhysicsShapes->GetChild(i);

			TAssert(pShape->GetKey() == "Box");
			if (pShape->GetKey() != "Box")
				continue;

			TRS trs = pShape->GetValueTRS();

			t.AddPhysBox(trs);
		}
	}

	if (pSceneAreas)
		LoadSceneAreas(pSceneAreas);

	return Compile();
}
Exemple #21
0
bool CGeppetto::LoadSceneAreas(CData* pData)
{
	tmap<tstring, std::shared_ptr<CConversionScene> > asScenes;
	tmap<tstring, size_t> aiSceneIDs;

	size_t iSceneArea = 0;

	for (size_t i = 0; i < pData->GetNumChildren(); i++)
	{
		CData* pArea = pData->GetChild(i);

		if (pArea->GetKey() == "NeighborDistance")
		{
			t.SetNeighborDistance(pArea->GetValueFloat());
			continue;
		}

		if (pArea->GetKey() == "UseGlobalTransforms")
		{
			t.UseGlobalTransformations();
			continue;
		}

		if (pArea->GetKey() == "UseLocalTransforms")
		{
			t.UseLocalTransformations();
			continue;
		}

		TAssert(pArea->GetKey() == "Area");
		if (pArea->GetKey() != "Area")
			continue;

		tstring sFile = pArea->FindChildValueString("File");
		TAssert(sFile.length());
		if (!sFile.length())
			continue;

		tstring sMesh = pArea->FindChildValueString("Mesh");
		TAssert(sMesh.length());
		if (!sMesh.length())
			continue;

		tstring sPhysics = pArea->FindChildValueString("Physics");

		auto it = asScenes.find(sFile);
		if (it == asScenes.end())
		{
			TMsg("Reading model '" + GetPath(sFile) + "' ...");
			std::shared_ptr<CConversionScene> pScene(new CConversionScene());
			CModelConverter c(pScene.get());

			if (!c.ReadModel(GetPath(sFile)))
			{
				TError("Couldn't read '" + GetPath(sFile) + "'.\n");
				return false;
			}
			TMsg(" Done.\n");

			asScenes[sFile] = pScene;
		}

		iSceneArea++;

		CToyUtil ts;

		if (t.IsUsingUV())
			ts.UseUV();
		if (t.IsUsingNormals())
			ts.UseNormals();

		ts.SetGameDirectory(t.GetGameDirectory());
		ts.SetOutputDirectory(t.GetOutputDirectory());
		ts.SetOutputFile(tsprintf(t.GetOutputFile() + "_sa%d_" + pArea->GetValueString().tolower(), iSceneArea));
		ts.UseLocalTransformations(t.IsUsingLocalTransformations());

		CConversionSceneNode* pMeshNode = asScenes[sFile]->FindSceneNode(sMesh);
		CConversionSceneNode* pPhysicsNode = nullptr;
		if (sPhysics.length())
		{
			pPhysicsNode = asScenes[sFile]->FindSceneNode(sPhysics);
		
			if (!pPhysicsNode)
				TError("Couldn't find a scene node in '" + sFile + "' named '" + sMesh + "'\n");
		}

		TAssert(pMeshNode);

		TMsg("Building scene area toy ...");

		Matrix4x4 mUpLeftSwap(Vector(1, 0, 0), Vector(0, 0, 1), Vector(0, -1, 0));

		if (pMeshNode)
			LoadSceneNodeIntoToy(asScenes[sFile].get(), pMeshNode, mUpLeftSwap, &ts);
		else
			TError("Couldn't find a scene node in '" + sFile + "' named '" + sMesh + "'\n");

		if (pPhysicsNode)
			LoadSceneNodeIntoToyPhysics(asScenes[sFile].get(), pPhysicsNode, mUpLeftSwap, &ts);

		TMsg(" Done.\n");

		tstring sGameOutput = pArea->FindChildValueString("Output");
		if (!sGameOutput.length())
			sGameOutput = t.GetOutputDirectory() + "/" + ts.GetOutputFile() + ".toy";

		tstring sFileOutput = FindAbsolutePath(t.GetGameDirectory() + T_DIR_SEP + sGameOutput);

		TMsg(tsprintf(" Mesh materials: %d\n", ts.GetNumMaterials()));
		TMsg(tsprintf(" Mesh tris: %d\n", ts.GetNumVerts() / 3));
		TMsg(tsprintf(" Physics tris: %d\n", ts.GetNumPhysIndices() / 3));
		if (t.IsUsingUV())
			TMsg(" Using UV's\n");
		if (t.IsUsingNormals())
			TMsg(" Using normals\n");

		TMsg("Writing scene area toy '" + sFileOutput + "' ...");
		if (ts.Write(sFileOutput))
			TMsg(" Done.\n");
		else
			TMsg(" FAILED!\n");

		aiSceneIDs[pArea->GetValueString()] = t.AddSceneArea(sGameOutput);
	}

	for (size_t i = 0; i < pData->GetNumChildren(); i++)
	{
		CData* pArea = pData->GetChild(i);

		if (pArea->GetKey() != "Area")
			continue;

		size_t iArea = aiSceneIDs[pArea->GetValueString()];

		for (size_t i = 0; i < pArea->GetNumChildren(); i++)
		{
			CData* pNeighbor = pArea->GetChild(i);

			if (pNeighbor->GetKey() == "Neighbor")
			{
				TAssert(aiSceneIDs.find(pNeighbor->GetValueString()) != aiSceneIDs.end());
				if (aiSceneIDs.find(pNeighbor->GetValueString()) == aiSceneIDs.end())
				{
					TError("Couldn't find area \"" + pNeighbor->GetValueString() + "\"\n");
					continue;
				}

				t.AddSceneAreaNeighbor(iArea, aiSceneIDs[pNeighbor->GetValueString()]);
				continue;
			}

			if (pNeighbor->GetKey() == "Visible")
			{
				TAssert(aiSceneIDs.find(pNeighbor->GetValueString()) != aiSceneIDs.end());
				if (aiSceneIDs.find(pNeighbor->GetValueString()) == aiSceneIDs.end())
				{
					TError("Couldn't find area \"" + pNeighbor->GetValueString() + "\"\n");
					continue;
				}

				t.AddSceneAreaVisible(iArea, aiSceneIDs[pNeighbor->GetValueString()]);
				continue;
			}
		}
	}

	return true;
}
void CApplication::OpenWindow(size_t iWidth, size_t iHeight, bool bFullscreen, bool bResizeable)
{
	glfwInit();

	m_bFullscreen = bFullscreen;

	if (HasCommandLineSwitch("--fullscreen"))
		m_bFullscreen = true;

	if (HasCommandLineSwitch("--windowed"))
		m_bFullscreen = false;

	m_iWindowWidth = iWidth;
	m_iWindowHeight = iHeight;

    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 0);
    glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE);

	glfwOpenWindowHint(GLFW_WINDOW_RESIZABLE, bResizeable?GL_TRUE:GL_FALSE);

	if (m_bMultisampling)
		glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 4);

	if (HasCommandLineSwitch("--debug-gl"))
	{
		glfwOpenWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);

		if (!glDebugMessageCallbackARB)
			TMsg("Your drivers do not support GL_ARB_debug_output, so no GL debug output will be shown.\n");
	}

	glfwOpenWindowHint(GLFW_DEPTH_BITS, 16);
	glfwOpenWindowHint(GLFW_RED_BITS, 8);
	glfwOpenWindowHint(GLFW_GREEN_BITS, 8);
	glfwOpenWindowHint(GLFW_BLUE_BITS, 8);
	glfwOpenWindowHint(GLFW_ALPHA_BITS, 8);

	TMsg(sprintf(tstring("Opening %dx%d %s %s window.\n"), iWidth, iHeight, bFullscreen?"fullscreen":"windowed", bResizeable?"resizeable":"fixed-size"));

	if (!(m_pWindow = (size_t)glfwOpenWindow(iWidth, iHeight, m_bFullscreen?GLFW_FULLSCREEN:GLFW_WINDOWED, WindowTitle().c_str(), NULL)))
	{
		glfwTerminate();
		return;
	}

	int iScreenWidth;
	int iScreenHeight;

	GetScreenSize(iScreenWidth, iScreenHeight);

	if (!m_bFullscreen)
	{
		// The taskbar is at the bottom of the screen. Pretend the screen is smaller so the window doesn't clip down into it.
		// Also the window's title bar at the top takes up space.
		iScreenHeight -= 70;

		int iWindowX = (int)(iScreenWidth/2-m_iWindowWidth/2);
		int iWindowY = (int)(iScreenHeight/2-m_iWindowHeight/2);
		glfwSetWindowPos((GLFWwindow)m_pWindow, iWindowX, iWindowY);
	}

	glfwSetWindowCloseCallback(&CApplication::WindowCloseCallback);
	glfwSetWindowSizeCallback(&CApplication::WindowResizeCallback);
	glfwSetKeyCallback(&CApplication::KeyEventCallback);
	glfwSetCharCallback(&CApplication::CharEventCallback);
	glfwSetMousePosCallback(&CApplication::MouseMotionCallback);
	glfwSetMouseButtonCallback(&CApplication::MouseInputCallback);
	glfwSetScrollCallback(&CApplication::MouseWheelCallback);
	glfwSwapInterval( 1 );
	glfwSetTime( 0.0 );

	InitJoystickInput();

	SetMouseCursorEnabled(true);

	GLenum err = gl3wInit();
	if (0 != err)
		exit(0);

	DumpGLInfo();

	if (glDebugMessageCallbackARB)
	{
		glDebugMessageCallbackARB(GLDebugCallback, nullptr);

		tstring sMessage("OpenGL Debug Output Activated");
		glDebugMessageInsertARB(GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_OTHER_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, sMessage.length(), sMessage.c_str());
	}

	glEnable(GL_CULL_FACE);
	glEnable(GL_DEPTH_TEST);
	glLineWidth(1.0);

	m_bIsOpen = true;

	m_pRenderer = CreateRenderer();
	m_pRenderer->Initialize();

	glgui::RootPanel()->SetSize((float)m_iWindowWidth, (float)m_iWindowHeight);
}
Exemple #23
0
void CLevel::SaveToFile()
{
	if (!m_sFile.length())
	{
		TAssert(m_sFile.length());
		TError("Can't find level file \'" + m_sFile + "\' to save.\n");
		return;
	}

	std::basic_ofstream<tchar> f(m_sFile.c_str());

	tstring sMessage = "// Generated by the Tinker Engine\n// Feel free to modify\n\n";
	f.write(sMessage.data(), sMessage.length());

	tstring sName = "Name: " + m_sName + "\n";
	f.write(sName.data(), sName.length());

	tstring sGameMode = "GameMode: " + m_sGameMode + "\n\n";
	f.write(sGameMode.data(), sGameMode.length());

	for (size_t i = 0; i < m_aLevelEntities.size(); i++)
	{
		auto pEntity = &m_aLevelEntities[i];

		tstring sEntity = "Entity: " + pEntity->GetClass() + "\n{\n";
		f.write(sEntity.data(), sEntity.length());

		if (pEntity->GetName().length())
		{
			tstring sName = "\tName: " + pEntity->GetName() + "\n";
			f.write(sName.data(), sName.length());
		}

		for (auto it = pEntity->GetParameters().begin(); it != pEntity->GetParameters().end(); it++)
		{
			if (it->first == "Name")
				continue;

			tstring sName = "\t" + it->first + ": " + it->second + "\n";
			f.write(sName.data(), sName.length());
		}

		for (size_t j = 0; j < pEntity->GetOutputs().size(); j++)
		{
			auto pOutput = &pEntity->GetOutputs()[j];
			tstring sOutput = "\n\tOutput: " + pOutput->m_sOutput + "\n\t{\n";
			f.write(sOutput.data(), sOutput.length());

			if (pOutput->m_sTargetName.length())
			{
				tstring sTarget = "\t\tTarget: " + pOutput->m_sTargetName + "\n";
				f.write(sTarget.data(), sTarget.length());
			}

			if (pOutput->m_sInput.length())
			{
				tstring sInput = "\t\tInput: " + pOutput->m_sInput + "\n";
				f.write(sInput.data(), sInput.length());
			}

			if (pOutput->m_sArgs.length())
			{
				tstring sArgs = "\t\tArgs: " + pOutput->m_sArgs + "\n";
				f.write(sArgs.data(), sArgs.length());
			}

			if (pOutput->m_bKill)
			{
				tstring sKill = "\t\tKill: yes\n";
				f.write(sKill.data(), sKill.length());
			}

			tstring sClose = "\t}\n";
			f.write(sClose.data(), sClose.length());
		}

		tstring sClose = "}\n\n";
		f.write(sClose.data(), sClose.length());
	}

	TMsg("Wrote level file '" + m_sFile + "'\n");
}
Exemple #24
0
void CLevelEntity::SetParameterValue(const tstring& sKey, const tstring& sValue)
{
	auto it = m_asParameters.find(sKey);
	if (it == m_asParameters.end())
	{
		if (!sValue.length())
			return;

		m_asParameters[sKey] = sValue;
	}
	else
	{
		if (!sValue.length())
		{
			m_asParameters.erase(sKey);
			Dirtify();
			return;
		}

		tstring& sCurrentValue = it->second;
		if (sCurrentValue == sValue)
			return;

		sCurrentValue = sValue;
	}

	Dirtify();

	CSaveData oSaveData;
	CSaveData* pSaveData = CBaseEntity::FindSaveDataValuesByHandle(("C" + GetClass()).c_str(), sKey.c_str(), &oSaveData);

	if (!pSaveData)
		TMsg("Level entity " + GetClass() + ":" + GetName() + " has unregistered savedata value: " + sKey + "\n");

	if (pSaveData && pSaveData->m_pszHandle && pSaveData->m_bDefault)
	{
		// Special case.
		if (strcmp(pSaveData->m_pszHandle, "Model") == 0)
		{
			m_hMaterialModel = CMaterialLibrary::AddMaterial(sValue);

			// Don't continue to erasing the default parameters if it's a model, since models have special processing.
			return;
		}

		if (strcmp(pSaveData->m_pszType, "bool") == 0)
		{
			bool bValue = UnserializeString_bool(sValue);

			bool b = *((bool*)&pSaveData->m_oDefault[0]);
			if (bValue == b)
				m_asParameters.erase(sKey);
		}
		else
		{
			if (strcmp(pSaveData->m_pszType, "size_t") == 0)
			{
				size_t i = *((size_t*)&pSaveData->m_oDefault[0]);
				if (stoi(sValue) == i)
					m_asParameters.erase(sKey);
			}
			else if (strcmp(pSaveData->m_pszType, "float") == 0)
			{
				float f = *((float*)&pSaveData->m_oDefault[0]);
				if (stof(sValue) == f)
					m_asParameters.erase(sKey);
			}
			else if (strcmp(pSaveData->m_pszType, "Vector") == 0)
			{
				if (CanUnserializeString_TVector(sValue))
				{
					Vector v = *((Vector*)&pSaveData->m_oDefault[0]);
					if (UnserializeString_TVector(sValue) == v)
						m_asParameters.erase(sKey);
				}
			}
			else if (strcmp(pSaveData->m_pszType, "Vector2D") == 0)
			{
				if (CanUnserializeString_Vector2D(sValue))
				{
					Vector2D v = *((Vector2D*)&pSaveData->m_oDefault[0]);
					if (UnserializeString_Vector2D(sValue) == v)
						m_asParameters.erase(sKey);
				}
			}
			else if (strcmp(pSaveData->m_pszType, "EAngle") == 0)
			{
				if (CanUnserializeString_EAngle(sValue))
				{
					EAngle v = *((EAngle*)&pSaveData->m_oDefault[0]);
					if (UnserializeString_EAngle(sValue) == v)
						m_asParameters.erase(sKey);
				}
			}
			else if (strcmp(pSaveData->m_pszType, "Matrix4x4") == 0)
			{
				if (CanUnserializeString_Matrix4x4(sValue))
				{
					Matrix4x4 m = *((Matrix4x4*)&pSaveData->m_oDefault[0]);
					if (UnserializeString_Matrix4x4(sValue) == m)
						m_asParameters.erase(sKey);
				}
			}
			else if (strcmp(pSaveData->m_pszType, "AABB") == 0)
			{
				if (CanUnserializeString_AABB(sValue))
				{
					AABB b = *((AABB*)&pSaveData->m_oDefault[0]);
					if (UnserializeString_AABB(sValue) == b)
						m_asParameters.erase(sKey);
				}
			}
			else
			{
				TUnimplemented();
			}
		}
	}
}
Exemple #25
0
void CAOGenerator::Generate()
{
    double flTimeStarted = Application()->GetTime();

    if (!m_eAOMethod)
        return;

    m_pWorkListener->BeginProgress();
    m_pWorkListener->SetAction("Setting up", 0);

    m_bIsGenerating = true;
    m_bStopGenerating = false;
    m_bDoneGenerating = false;
    m_bIsBleeding = false;

    m_flLowestValue = -1;
    m_flHighestValue = 0;

    if (SMAKWindow())
        SMAKWindow()->ClearDebugLines();

    memset(&m_bPixelMask[0], 0, m_iWidth*m_iHeight*sizeof(bool));

    if (m_eAOMethod == AOMETHOD_SHADOWMAP)
    {
        ShadowMapSetupScene();
        GenerateShadowMaps();
    }
    else
    {
        if (m_eAOMethod == AOMETHOD_RENDER)
            RenderSetupScene();
        // In AO debug mode we need this to do the debug rendering, so do it anyways.
        else if (ao_debug.GetBool())
            RenderSetupScene();

        GenerateByTexel();
    }

    size_t i;

    m_pWorkListener->SetAction("Averaging reads", m_iWidth*m_iHeight);

    // Average out all of the reads.
    for (i = 0; i < m_iWidth*m_iHeight; i++)
    {
        // Don't immediately return, just skip this loop. We have cleanup work to do.
        if (m_bStopGenerating)
            break;

        if (m_eAOMethod == AOMETHOD_SHADOWMAP)
            m_avecShadowValues[i] = Vector(m_avecShadowValues[i].x, m_avecShadowValues[i].x, m_avecShadowValues[i].x);

        if (m_aiShadowReads[i])
            m_avecShadowValues[i] /= (float)m_aiShadowReads[i];
        else
            m_avecShadowValues[i] = Vector(0,0,0);

        m_pWorkListener->WorkProgress(i);
    }

    if (m_eAOMethod == AOMETHOD_RENDER || m_eAOMethod == AOMETHOD_SHADOWMAP)
    {
        if (m_eAOMethod == AOMETHOD_SHADOWMAP)
        {
            m_oAOFB.Destroy();
            CRenderer::UnloadVertexDataFromGL(m_iScene);
            CRenderer::UnloadVertexDataFromGL(m_iSceneDepth);
        }
        else
        {
            for (size_t i = 0; i < m_aiSceneMaterials.size(); i++)
                CRenderer::UnloadVertexDataFromGL(m_aiSceneMaterials[i]);

            m_oRenderFB.Destroy();
        }
    }

    // Somebody get this ao some clotters and morphine, STAT!
    m_bIsBleeding = true;
    if (!m_bStopGenerating)
        Bleed();
    m_bIsBleeding = false;

    if (!m_bStopGenerating)
        m_bDoneGenerating = true;
    m_bIsGenerating = false;

    // One last call to let them know we're done.
    m_pWorkListener->EndProgress();

    double flTimeEnded = Application()->GetTime();
    double flTimePassed = flTimeEnded - flTimeStarted;
    TMsg(sprintf("AO generation completed in %f seconds\n", flTimePassed));
}