//----------------------------------------------------------------------------- // Purpose: Called to Shutdown the game UI system //----------------------------------------------------------------------------- void CGameUI::Shutdown() { // notify all the modules of Shutdown g_VModuleLoader.ShutdownPlatformModules(); // unload the modules them from memory g_VModuleLoader.UnloadPlatformModules(); ModInfo().FreeModInfo(); // release platform mutex // close the mutex if (g_hMutex) { Sys_ReleaseMutex(g_hMutex); } if (g_hWaitMutex) { Sys_ReleaseMutex(g_hWaitMutex); } steamapicontext->Clear(); #ifndef _X360 // SteamAPI_Shutdown(); << Steam shutdown is controlled by engine #endif ConVar_Unregister(); DisconnectTier3Libraries(); DisconnectTier2Libraries(); DisconnectTier1Libraries(); }
//----------------------------------------------------------------------------- // Purpose: Called to Shutdown the game UI system //----------------------------------------------------------------------------- void CGameUI::Shutdown() { // notify all the modules of Shutdown g_VModuleLoader.ShutdownPlatformModules(); // unload the modules them from memory g_VModuleLoader.UnloadPlatformModules(); // free mod info ModInfo().FreeModInfo(); // release platform mutex // close the mutex if (g_hMutex) { Sys_ReleaseMutex(g_hMutex); } if (g_hWaitMutex) { Sys_ReleaseMutex(g_hWaitMutex); } }
void ParamVisitor::visitCell(AstCell* nodep) { // Cell: Check for parameters in the instantiation. nodep->iterateChildren(*this); if (!nodep->modp()) nodep->v3fatalSrc("Not linked?"); if (nodep->paramsp() || 1 // Need to look for interfaces; could track when one exists, but should be harmless to always do this ) { UINFO(4,"De-parameterize: "<<nodep<<endl); // Create new module name with _'s between the constants if (debug()>=10) nodep->dumpTree(cout,"-cell:\t"); // Evaluate all module constants V3Const::constifyParamsEdit(nodep); // Make sure constification worked // Must be a separate loop, as constant conversion may have changed some pointers. //if (debug()) nodep->dumpTree(cout,"-cel2:\t"); string longname = nodep->modp()->name(); bool any_overrides = false; longname += "_"; if (debug()>8) nodep->paramsp()->dumpTreeAndNext(cout,"-cellparams:\t"); for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) { if (!pinp->exprp()) continue; // No-connect AstVar* modvarp = pinp->modVarp(); if (!modvarp) { pinp->v3error("Parameter not found in sub-module: Param "<<pinp->name()<<" of "<<nodep->prettyName()); } else if (!modvarp->isGParam()) { pinp->v3error("Attempted parameter setting of non-parameter: Param "<<pinp->name()<<" of "<<nodep->prettyName()); } else { AstConst* constp = pinp->exprp()->castConst(); AstConst* origconstp = modvarp->valuep()->castConst(); if (!constp) { //if (debug()) pinp->dumpTree(cout,"error:"); pinp->v3error("Can't convert defparam value to constant: Param "<<pinp->name()<<" of "<<nodep->prettyName()); pinp->exprp()->replaceWith(new AstConst(pinp->fileline(), V3Number(pinp->fileline(), modvarp->width(), 0))); } else if (origconstp && constp->sameTree(origconstp)) { // Setting parameter to its default value. Just ignore it. // This prevents making additional modules, and makes coverage more // obvious as it won't show up under a unique module page name. } else { longname += "_" + paramSmallName(nodep->modp(),pinp->modVarp())+constp->num().ascii(false); any_overrides = true; } } } IfaceRefRefs ifaceRefRefs; for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) { AstVar* modvarp = pinp->modVarp(); if (modvarp->isIfaceRef()) { AstIfaceRefDType* portIrefp = modvarp->subDTypep()->castIfaceRefDType(); //UINFO(9," portIfaceRef "<<portIrefp<<endl); if (!pinp->exprp() || !pinp->exprp()->castVarRef() || !pinp->exprp()->castVarRef()->varp() || !pinp->exprp()->castVarRef()->varp()->subDTypep() || !pinp->exprp()->castVarRef()->varp()->subDTypep()->castIfaceRefDType()) { pinp->v3error("Interface port '"<<modvarp->prettyName()<<"' is not connected to interface/modport pin expression"); } else { AstIfaceRefDType* pinIrefp = pinp->exprp()->castVarRef()->varp()->subDTypep()->castIfaceRefDType(); //UINFO(9," pinIfaceRef "<<pinIrefp<<endl); if (portIrefp->ifaceViaCellp() != pinIrefp->ifaceViaCellp()) { UINFO(9," IfaceRefDType needs reconnect "<<pinIrefp<<endl); longname += "_" + paramSmallName(nodep->modp(),pinp->modVarp())+paramValueNumber(pinIrefp); any_overrides = true; ifaceRefRefs.push_back(make_pair(portIrefp,pinIrefp)); } } } } if (!any_overrides) { UINFO(8,"Cell parameters all match original values, skipping expansion.\n"); } else { // If the name is very long, we don't want to overwhelm the filename limit // We don't do this always, as it aids debugability to have intuitive naming. // TODO can use new V3Name hash replacement instead of this string newname = longname; if (longname.length()>30) { LongMap::iterator iter = m_longMap.find(longname); if (iter != m_longMap.end()) { newname = iter->second; } else { newname = nodep->modp()->name(); newname += "__pi"+cvtToStr(++m_longId); // We use all upper case above, so lower here can't conflict m_longMap.insert(make_pair(longname, newname)); } } UINFO(4,"Name: "<<nodep->modp()->name()<<"->"<<longname<<"->"<<newname<<endl); // // Already made this flavor? AstNodeModule* modp = NULL; ModNameMap::iterator iter = m_modNameMap.find(newname); if (iter != m_modNameMap.end()) modp = iter->second.m_modp; if (!modp) { // Deep clone of new module // Note all module internal variables will be re-linked to the new modules by clone // However links outside the module (like on the upper cells) will not. modp = nodep->modp()->cloneTree(false); modp->name(newname); modp->user5(false); // We need to re-recurse this module once changed nodep->modp()->addNextHere(modp); // Keep tree sorted by cell occurrences m_modNameMap.insert(make_pair(modp->name(), ModInfo(modp))); iter = m_modNameMap.find(newname); VarCloneMap* clonemapp = &(iter->second.m_cloneMap); UINFO(4," De-parameterize to new: "<<modp<<endl); // Grab all I/O so we can remap our pins later // Note we allow multiple users of a parameterized model, thus we need to stash this info. for (AstNode* stmtp=modp->stmtsp(); stmtp; stmtp = stmtp->nextp()) { if (AstVar* varp = stmtp->castVar()) { if (varp->isIO() || varp->isGParam() || varp->isIfaceRef()) { // Cloning saved a pointer to the new node for us, so just follow that link. AstVar* oldvarp = varp->clonep()->castVar(); //UINFO(8,"Clone list 0x"<<hex<<(uint32_t)oldvarp<<" -> 0x"<<(uint32_t)varp<<endl); clonemapp->insert(make_pair(oldvarp, varp)); } } } // Relink parameter vars to the new module relinkPins(clonemapp, nodep->paramsp()); // Fix any interface references for (IfaceRefRefs::iterator it=ifaceRefRefs.begin(); it!=ifaceRefRefs.end(); ++it) { AstIfaceRefDType* portIrefp = it->first; AstIfaceRefDType* pinIrefp = it->second; AstIfaceRefDType* cloneIrefp = portIrefp->clonep()->castIfaceRefDType(); UINFO(8," IfaceOld "<<portIrefp<<endl); UINFO(8," IfaceTo "<<pinIrefp<<endl); if (!cloneIrefp) portIrefp->v3fatalSrc("parameter clone didn't hit AstIfaceRefDType"); UINFO(8," IfaceClo "<<cloneIrefp<<endl); cloneIrefp->ifacep(pinIrefp->ifaceViaCellp()); UINFO(8," IfaceNew "<<cloneIrefp<<endl); } // Assign parameters to the constants specified // DOES clone() so must be finished with module clonep() before here for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) { AstVar* modvarp = pinp->modVarp(); if (modvarp && pinp->exprp()) { AstConst* constp = pinp->exprp()->castConst(); // Remove any existing parameter if (modvarp->valuep()) modvarp->valuep()->unlinkFrBack()->deleteTree(); // Set this parameter to value requested by cell modvarp->valuep(constp->cloneTree(false)); } } } else { UINFO(4," De-parameterize to old: "<<modp<<endl); } // Have child use this module instead. nodep->modp(modp); nodep->modName(newname); // We need to relink the pins to the new module VarCloneMap* clonemapp = &(iter->second.m_cloneMap); relinkPins(clonemapp, nodep->pinsp()); UINFO(8," Done with "<<modp<<endl); } // if any_overrides // Delete the parameters from the cell; they're not relevant any longer. if (nodep->paramsp()) nodep->paramsp()->unlinkFrBackWithNext()->deleteTree(); UINFO(8," Done with "<<nodep<<endl); //if (debug()>=10) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("param-out.tree")); } // Now remember to process the child module at the end of the module m_todoModps.insert(make_pair(nodep->modp()->level(),nodep->modp())); }
//----------------------------------------------------------------------------- // Purpose: Initialization //----------------------------------------------------------------------------- void CGameUI::Initialize( CreateInterfaceFn factory ) { MEM_ALLOC_CREDIT(); ConnectTier1Libraries( &factory, 1 ); ConnectTier2Libraries( &factory, 1 ); ConVar_Register( FCVAR_CLIENTDLL ); ConnectTier3Libraries( &factory, 1 ); enginesound = (IEngineSound *)factory(IENGINESOUND_CLIENT_INTERFACE_VERSION, NULL); engine = (IVEngineClient *)factory( VENGINE_CLIENT_INTERFACE_VERSION, NULL ); bik = (IBik*)factory( BIK_INTERFACE_VERSION, NULL ); #ifndef _X360 SteamAPI_InitSafe(); steamapicontext->Init(); #endif CGameUIConVarRef var( "gameui_xbox" ); m_bIsConsoleUI = var.IsValid() && var.GetBool(); vgui::VGui_InitInterfacesList( "GameUI", &factory, 1 ); vgui::VGui_InitMatSysInterfacesList( "GameUI", &factory, 1 ); // load localization file g_pVGuiLocalize->AddFile( "Resource/gameui_%language%.txt", "GAME", true ); // load mod info ModInfo().LoadCurrentGameInfo(); // load localization file for kb_act.lst g_pVGuiLocalize->AddFile( "Resource/valve_%language%.txt", "GAME", true ); bool bFailed = false; enginevguifuncs = (IEngineVGui *)factory( VENGINE_VGUI_VERSION, NULL ); enginesurfacefuncs = (vgui::ISurface *)factory(VGUI_SURFACE_INTERFACE_VERSION, NULL); gameuifuncs = (IGameUIFuncs *)factory( VENGINE_GAMEUIFUNCS_VERSION, NULL ); xboxsystem = (IXboxSystem *)factory( XBOXSYSTEM_INTERFACE_VERSION, NULL ); #ifdef _X360 xonline = (IXOnline *)factory( XONLINE_INTERFACE_VERSION, NULL ); #endif #ifdef SWARM_DLL g_pMatchExtSwarm = ( IMatchExtSwarm * ) factory( IMATCHEXT_SWARM_INTERFACE, NULL ); #endif #ifdef SDK_DLL g_pMatchExtSwarm = ( IMatchExtSwarm * ) factory( IMATCHEXT_SWARM_INTERFACE, NULL ); #endif bFailed = !enginesurfacefuncs || !gameuifuncs || !enginevguifuncs || !xboxsystem || #ifdef _X360 !xonline || #endif #ifdef SWARM_DLL !g_pMatchExtSwarm || #endif #ifdef SDK_DLL !g_pMatchExtSwarm || #endif !g_pMatchFramework; if ( bFailed ) { Error( "CGameUI::Initialize() failed to get necessary interfaces\n" ); } // setup base panel UI_BASEMOD_PANEL_CLASS& factoryBasePanel = ConstructUiBaseModPanelClass(); // explicit singleton instantiation factoryBasePanel.SetBounds( 0, 0, 640, 480 ); factoryBasePanel.SetPaintBorderEnabled( false ); factoryBasePanel.SetPaintBackgroundEnabled( true ); factoryBasePanel.SetPaintEnabled( true ); factoryBasePanel.SetVisible( true ); factoryBasePanel.SetMouseInputEnabled( IsPC() ); // factoryBasePanel.SetKeyBoardInputEnabled( IsPC() ); factoryBasePanel.SetKeyBoardInputEnabled( true ); vgui::VPANEL rootpanel = enginevguifuncs->GetPanel( PANEL_GAMEUIDLL ); factoryBasePanel.SetParent( rootpanel ); }
//----------------------------------------------------------------------------- // Purpose: Called to setup the game UI //----------------------------------------------------------------------------- void CGameUI::Start(struct cl_enginefuncs_s *engineFuncs, int interfaceVersion, IBaseSystem *system) { // TRACE_FUNCTION("CGameUI::Start"); // m_pMaster = NULL; // copy the engine interface // memcpy(&gEngfuncs, engineFuncs, sizeof(gEngfuncs)); // engine = &gEngfuncs; // set SystemWrapper for demo player // g_pSystemWrapper = system; // load mod info ModInfo().LoadCurrentGameInfo(); // Determine Tracker location. // ...If running with Steam, Tracker is in a well defined location relative to the game dir. Use it if there. // ...Otherwise get the tracker location from the registry key if (FindPlatformDirectory(m_szPlatformDir, sizeof(m_szPlatformDir))) { // add the tracker directory to the search path // add localized version first if we're not in english char language[128]; if (vgui::system()->GetRegistryString("HKEY_LOCAL_MACHINE\\Software\\Valve\\Steam\\Language", language, sizeof(language))) { if (strlen(language) > 0 && stricmp(language, "english")) { char path[256]; sprintf(path, "platform_%s", language); vgui::filesystem()->AddSearchPath(path, "PLATFORM"); } } vgui::filesystem()->AddSearchPath("platform", "PLATFORM"); // setup config file directory char szConfigDir[512]; strcpy(szConfigDir, m_szPlatformDir); strcat(szConfigDir, "config"); /* // make sure the path exists _finddata_t findData; long findHandle = _findfirst(steamPath, &findData); if (steamPath && findHandle != -1) { // put the config dir directly under steam _snprintf(szConfigDir, sizeof(szConfigDir), "%s/config", steamPath); _findclose(findHandle); } else { // we're not running steam, so just put the config dir under the platform _snprintf(szConfigDir, sizeof(szConfigDir), "%sconfig", m_szPlatformDir); } */ // add the path vgui::filesystem()->AddSearchPath(szConfigDir, "CONFIG"); // make sure the config directory has been created _mkdir(szConfigDir); vgui::ivgui()->DPrintf("Platform config directory: %s\n", szConfigDir); // user dialog configuration vgui::system()->SetUserConfigFile("InGameDialogConfig.vdf", "CONFIG"); // localization vgui::localize()->AddFile(vgui::filesystem(), "Resource/platform_%language%.txt"); vgui::localize()->AddFile(vgui::filesystem(), "Resource/vgui_%language%.txt"); //!! hack to work around problem with userinfo not being uploaded (and therefore *Tracker field) //!! this is done to make sure the *tracker userinfo field is set before we connect so that it //!! will get communicated to the server //!! this needs to be changed to a system where it is communicated to server when known but not before //!! addendum: this may very happen now with the platform changes; needs to be tested before this code //!! can be removed { // get the last known userID from the registry and set it in our userinfo string HKEY key; DWORD bufSize = sizeof(m_szPlatformDir); unsigned int lastUserID = 0; bufSize = sizeof(lastUserID); if (ERROR_SUCCESS == g_pVCR->Hook_RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Valve\\Tracker", 0, KEY_READ, &key)) { g_pVCR->Hook_RegQueryValueEx(key, "LastUserID", NULL, NULL, (unsigned char *)&lastUserID, &bufSize); // close the registry key g_pVCR->Hook_RegCloseKey(key); } if (lastUserID) { char buf[32]; sprintf(buf, "%d", lastUserID); engine->PlayerInfo_SetValueForKey("*tracker", buf); } } } // task bar - needs to be first thing created g_pTaskbar = new CTaskbar(staticPanel,"TaskBar"); g_pTaskbar->SetVisible(false); // FOR SRC // vgui::surface()->SetWorkspaceInsets( 0, 0, 0, g_pTaskbar->GetTall() ); // Start loading tracker if (m_szPlatformDir[0] != 0) { vgui::ivgui()->DPrintf2("Initializing platform...\n"); // open a mutex Sys_SetLastError(SYS_NO_ERROR); // primary mutex is the platform.exe name char szExeName[sizeof(m_szPlatformDir) + 32]; sprintf(szExeName, "%splatform.exe", m_szPlatformDir); // convert the backslashes in the path string to be forward slashes so it can be used as a mutex name for (char *ch = szExeName; *ch != 0; ch++) { *ch = tolower(*ch); if (*ch == '\\') { *ch = '/'; } } g_hMutex = Sys_CreateMutex("ValvePlatformUIMutex"); g_hWaitMutex = Sys_CreateMutex("ValvePlatformWaitMutex"); if (g_hMutex == NULL || g_hWaitMutex == NULL || Sys_GetLastError() == SYS_ERROR_INVALID_HANDLE) { // error, can't get handle to mutex if (g_hMutex) { Sys_ReleaseMutex(g_hMutex); } if (g_hWaitMutex) { Sys_ReleaseMutex(g_hWaitMutex); } g_hMutex = NULL; g_hWaitMutex = NULL; Error("Tracker Error: Could not access Tracker, bad mutex\n"); return; } unsigned int waitResult = Sys_WaitForSingleObject(g_hMutex, 0); if (!(waitResult == SYS_WAIT_OBJECT_0 || waitResult == SYS_WAIT_ABANDONED)) { // mutex locked, need to close other tracker // get the wait mutex, so that tracker.exe knows that we're trying to acquire ValveTrackerMutex waitResult = Sys_WaitForSingleObject(g_hWaitMutex, 0); if (waitResult == SYS_WAIT_OBJECT_0 || waitResult == SYS_WAIT_ABANDONED) { Sys_EnumWindows(SendShutdownMsgFunc, 1); } } m_bTryingToLoadTracker = true; // now we are set up to check every frame to see if we can Start tracker } staticPanel->SetBackgroundRenderState(CBasePanel::BACKGROUND_DESKTOPIMAGE); // start mp3 playing //engine->pfnClientCmd("mp3 loop media/gamestartup.mp3\n"); // SRC version //engine->ClientCmd("loop media/gamestartup.mp3\n"); }