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; }
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"); }
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); } }
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"); }
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); }
CConsole* CApplication::GetConsole() { if (m_pConsole == NULL) { m_pConsole = new CConsole(); if (developer.GetBool()) TMsg("Developer mode ON.\n"); } return m_pConsole; }
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())); }
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); }
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); } }
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()); } }
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); }
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())); }
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; }
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; }
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); } }
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(); }
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(); }
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); }
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"); }
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(); } } } }
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)); }