C4DefGraphicsPtrBackup::C4DefGraphicsPtrBackup(C4DefGraphics *pSourceGraphics): MeshMaterialUpdate(::MeshMaterialManager), pMeshUpdate(NULL) { // assign graphics + def pGraphicsPtr = pSourceGraphics; pDef = pSourceGraphics->pDef; // assign name const char *szName = pGraphicsPtr->GetName(); if (szName) SCopy(szName, Name, C4MaxName); else *Name=0; // Remove all mesh materials that were loaded from this definition for(StdMeshMatManager::Iterator iter = ::MeshMaterialManager.Begin(); iter != MeshMaterialManager.End(); ) { StdStrBuf Filename; Filename.Copy(pDef->Filename); Filename.Append("/"); Filename.Append(GetFilename(iter->FileName.getData())); if(Filename == iter->FileName) iter = ::MeshMaterialManager.Remove(iter, &MeshMaterialUpdate); else ++iter; } // assign mesh update if(pSourceGraphics->Type == C4DefGraphics::TYPE_Mesh) pMeshUpdate = new StdMeshUpdate(*pSourceGraphics->Mesh); // create next graphics recursively C4DefGraphics *pNextGfx = pGraphicsPtr->pNext; if (pNextGfx) pNext = new C4DefGraphicsPtrBackup(pNextGfx); else pNext = NULL; }
bool C4PlayerList::Save(C4Group &hGroup, bool fStoreTiny, const C4PlayerInfoList &rStoreList) { StdStrBuf sTempFilename; bool fSuccess = true; // Save to external player files and add to group for (C4Player *pPlr=First; pPlr; pPlr=pPlr->Next) { // save only those in the list, and only those with a filename C4PlayerInfo *pNfo = rStoreList.GetPlayerInfoByID(pPlr->ID); if (!pNfo) continue; if (!pNfo->GetFilename() || !*pNfo->GetFilename()) continue;; // save over original file? bool fStoreOnOriginal = (!fStoreTiny && pNfo->GetType() == C4PT_User); // Create temporary file sTempFilename.Copy(Config.AtTempPath(pNfo->GetFilename())); if (fStoreOnOriginal) if (!C4Group_CopyItem(pPlr->Filename, sTempFilename.getData())) return false; // Open group C4Group PlrGroup; if (!PlrGroup.Open(sTempFilename.getData(), !fStoreOnOriginal)) return false; // Save player if (!pPlr->Save(PlrGroup, true, fStoreOnOriginal)) return false; PlrGroup.Close(); // Add temp file to group if (!hGroup.Move(sTempFilename.getData(), pNfo->GetFilename())) return false; } return fSuccess; }
void C4Console::PlayerJoin() { // Get player file name(s) StdCopyStrBuf c4pfile(""); if (!FileSelect(&c4pfile, "OpenClonk Player\0*.ocp\0\0", OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_EXPLORER )) return; // Multiple players if (DirectoryExists(c4pfile.getData())) { const char *cptr = c4pfile.getData() + SLen(c4pfile.getData()) + 1; while (*cptr) { StdStrBuf f; f.Copy(c4pfile.getData()); f.AppendBackslash(); f.Append(cptr); cptr += SLen(cptr)+1; ::Players.JoinNew(f.getData()); } } // Single player else { ::Players.JoinNew(c4pfile.getData()); } }
bool OpenLog() { // open sLogFileName = C4CFN_Log; int iLog = 2; #ifdef _WIN32 while (!(C4LogFile = _fsopen(Config.AtUserDataPath(sLogFileName.getData()), "wt", _SH_DENYWR))) #elif defined(HAVE_SYS_FILE_H) int fd = 0; while (!(fd = open(Config.AtUserDataPath(sLogFileName.getData()), O_WRONLY | O_CREAT, 0644)) || flock(fd, LOCK_EX|LOCK_NB)) #else while (!(C4LogFile = fopen(Config.AtUserDataPath(sLogFileName.getData()), "wb"))) #endif { // Already locked by another instance? #if !defined(_WIN32) && defined(HAVE_SYS_FILE_H) if (fd) close(fd); #else if (C4LogFile) fclose(C4LogFile); #endif // If the file does not yet exist, the directory is r/o // don't go on then, or we have an infinite loop if (access(Config.AtUserDataPath(sLogFileName.getData()), 0)) return false; // try different name sLogFileName.Format(C4CFN_LogEx, iLog++); } #if !defined(_WIN32) && defined(HAVE_SYS_FILE_H) ftruncate(fd, 0); C4LogFile = fdopen(fd, "wb"); #endif // save start time time(&C4LogStartTime); return true; }
void C4GameOverDlg::SetNetResult(const char *szResultString, C4RoundResults::NetResult eResultType, size_t iPendingStreamingData, bool fIsStreaming) { // add info about pending streaming data StdStrBuf sResult(szResultString); if (fIsStreaming) { sResult.AppendChar('|'); sResult.AppendFormat("[!]Transmitting record to league server... (%d kb remaining)", int(iPendingStreamingData/1024)); } // message linebreak into box StdStrBuf sBrokenResult; C4GUI::GetRes()->TextFont.BreakMessage(sResult.getData(), pNetResultLabel->GetBounds().Wdt, &sBrokenResult, true); pNetResultLabel->SetText(sBrokenResult.getData(), false); // all done? if (eResultType != C4RoundResults::NR_None && !fIsStreaming) { // a final result is determined and all streaming data has been transmitted fIsNetDone = true; } // network error? if (eResultType == C4RoundResults::NR_NetError) { // disconnected. Do not show winners/losers for (int32_t i=0; i<iPlrListCount; ++i) ppPlayerLists[i]->SetMode(C4PlayerInfoListBox::PILBM_EvaluationNoWinners); } }
bool C4TexMapEntry::Init() { // Find material iMaterialIndex = ::MaterialMap.Get(Material.getData()); if (!MatValid(iMaterialIndex)) { DebugLogF("Error initializing material %s-%s: Invalid material!", Material.getData(), Texture.getData()); return false; } pMaterial = &::MaterialMap.Map[iMaterialIndex]; // Find texture StdStrBuf FirstTexture; FirstTexture.CopyUntil(Texture.getData(), '-'); C4Texture * sfcTexture = ::TextureMap.GetTexture(FirstTexture.getData()); if (!sfcTexture) { DebugLogF("Error initializing material %s-%s: Invalid texture!", Material.getData(), FirstTexture.getData()); Clear(); return false; } // Get overlay properties int32_t iOverlayType=pMaterial->OverlayType; int32_t iZoom=0; if (iOverlayType & C4MatOv_Exact) iZoom=1; if (iOverlayType & C4MatOv_HugeZoom) iZoom=4; // Create pattern MatPattern.Set(sfcTexture->Surface32, iZoom); return true; }
bool C4DownloadDlg::DownloadFile(const char *szDLType, C4GUI::Screen *pScreen, const char *szURL, const char *szSaveAsFilename, const char *szNotFoundMessage) { // log it LogF(LoadResStr("IDS_PRC_DOWNLOADINGFILE"), szURL); // show download dialog C4DownloadDlg *pDlg = new C4DownloadDlg(szDLType); if (!pDlg->ShowModal(pScreen, szURL, szSaveAsFilename)) { // show an appropriate error const char *szError = pDlg->GetError(); if (!szError || !*szError) szError = LoadResStr("IDS_PRC_UNKOWNERROR"); StdStrBuf sError; sError.Format(LoadResStr("IDS_PRC_DOWNLOADERROR"), GetFilename(szURL), szError); // it's a 404: display extended message if (SSearch(szError, "404") && szNotFoundMessage) { sError.Append("|"); sError.Append(szNotFoundMessage); } // display message pScreen->ShowMessageModal(sError.getData(), FormatString(LoadResStr("IDS_CTL_DL_TITLE"), szDLType).getData(), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Error, NULL); delete pDlg; return false; } LogF(LoadResStr("IDS_PRC_DOWNLOADCOMPLETE"), szURL); delete pDlg; return true; }
bool C4MaterialMap::LoadEnumeration(C4Group &hGroup) { // Load enumeration map (from savegame), succeed if not present StdStrBuf mapbuf; if (!hGroup.LoadEntryString(C4CFN_MatMap, &mapbuf)) return true; // Sort material array by enumeration map, fail if some missing const char *csearch; char cmatname[C4M_MaxName+1]; int32_t cmat=0; if (!(csearch = SSearch(mapbuf.getData(),"[Enumeration]"))) { return false; } csearch=SAdvanceSpace(csearch); while (IsIdentifier(*csearch)) { SCopyIdentifier(csearch,cmatname,C4M_MaxName); if (!SortEnumeration(cmat,cmatname)) { // Output error message! return false; } cmat++; csearch+=SLen(cmatname); csearch=SAdvanceSpace(csearch); } return true; }
void C4Network2ResDlg::ListItem::Update(const C4Network2Res *pByRes) { // update progress label iProgress = pByRes->getPresentPercent(); if (iProgress < 100) { StdStrBuf progress; progress.Format("%d%%", iProgress); if (pProgress) pProgress->SetText(progress.getData()); else { pProgress = new C4GUI::Label(progress.getData(), GetBounds().Wdt - IconLabelSpacing, 0, ARight); pProgress->SetToolTip(LoadResStr("IDS_NET_RESPROGRESS_DESC")); AddElement(pProgress); } } else if (pProgress) { delete pProgress; pProgress=NULL; } // update disk icon if (IsSavePossible()) { if (!pSaveBtn) { pSaveBtn = new C4GUI::CallbackButtonEx<C4Network2ResDlg::ListItem, C4GUI::IconButton>(C4GUI::Ico_Save, GetToprightCornerRect(16,16,2,1), 0, this, &ListItem::OnButtonSave); AddElement(pSaveBtn); } } else if (pSaveBtn) delete pSaveBtn; }
bool ShaderLogF(const char *strMessage ...) { va_list args; va_start(args, strMessage); StdStrBuf Buf; Buf.FormatV(strMessage, args); return ShaderLog(Buf.getData()); }
static int RunFile(const char * filename, bool checkOnly) { C4Group File; if (!File.Open(GetWorkingDirectory())) { fprintf(stderr, "Open failed: %s\n", File.GetError()); return 1; } // get scripts StdStrBuf fn; File.ResetSearch(); if (!File.FindNextEntry(filename, &fn)) { fprintf(stderr, "FindNextEntry failed: %s\n", File.GetError()); return 1; } InitializeC4Script(); GameScript.Load(File, fn.getData(), nullptr, nullptr); if (!checkOnly) RunLoadedC4Script(); ClearC4Script(); return ScriptEngine.errCnt; }
// Helper for IRC command parameter parsing StdStrBuf ircExtractPar(const char **ppPar) { // No parameter left? if(!ppPar || !*ppPar || !**ppPar) return StdStrBuf(""); // Last parameter? StdStrBuf Result; if(**ppPar == ':') { // Reference everything after the double-colon Result.Ref(*ppPar + 1); *ppPar = NULL; } else { // Copy until next space (or end of string) Result.CopyUntil(*ppPar, ' '); // Go over parameters *ppPar += Result.getLength(); if(**ppPar == ' ') (*ppPar)++; else *ppPar = NULL; } // Done return Result; }
size_t C4AulDebug::UnpackPacket(const StdBuf &rInBuf, const C4NetIO::addr_t &addr) { // Find line separation const char *pSep = reinterpret_cast<const char *>(memchr(rInBuf.getData(), '\n', rInBuf.getSize())); if (!pSep) return 0; // Check if it's windows-style separation int iSize = pSep - getBufPtr<char>(rInBuf) + 1, iLength = iSize - 1; if (iLength && *(pSep - 1) == '\r') iLength--; // Copy the line StdStrBuf Buf; Buf.Copy(getBufPtr<char>(rInBuf), iLength); // Password line? if (fConnected) { ProcessLineResult result = ProcessLine(Buf); // Send answer SendLine(result.okay ? "OK" : "ERR", result.answer.length() > 0 ? result.answer.c_str() : NULL); } else if (!Password.getSize() || Password == Buf) { fConnected = true; SendLine("HLO", "This is " C4ENGINECAPTION ", " C4VERSION); Log("C4Aul debugger connected successfully!"); } else C4NetIOTCP::Close(PeerAddr); // Consume line return iSize; }
size_t C4Network2IRCClient::UnpackPacket(const StdBuf &rInBuf, const C4NetIO::addr_t &addr) { // Find line seperation const char *pSep = reinterpret_cast<const char *>(memchr(rInBuf.getData(), '\n', rInBuf.getSize())); if(!pSep) return 0; // Check if it's actually correct seperation (rarely the case) int iSize = pSep - getBufPtr<char>(rInBuf) + 1, iLength = iSize - 1; if(iLength && *(pSep - 1) == '\r') iLength--; // Copy the line StdStrBuf Buf; Buf.Copy(getBufPtr<char>(rInBuf), iLength); // Ignore prefix const char *pMsg = Buf.getData(); StdStrBuf Prefix; if(*pMsg == ':') { Prefix.CopyUntil(pMsg + 1, ' '); pMsg += Prefix.getLength() + 1; } // Strip whitespace while(*pMsg == ' ') pMsg++; // Ignore empty message if(!*pMsg) return iSize; // Get command StdStrBuf Cmd; Cmd.CopyUntil(pMsg, ' '); // Precess command const char *szParameters = SSearch(pMsg, " "); OnCommand(Prefix.getData(), Cmd.getData(), szParameters ? szParameters : ""); // Consume the line return iSize; }
bool ValidateString(char *szString, ValidationOption eOption) { // validate in a StdStrBuf. Does one alloc and copy :( StdStrBuf buf; buf.Copy(szString); bool fInvalid = ValidateString(buf, eOption); return fInvalid; }
void C4MusicSystem::LoadMoreMusic() { StdStrBuf MoreMusicFile; // load MoreMusic.txt if (!MoreMusicFile.LoadFromFile(Config.AtUserDataPath(C4CFN_MoreMusic))) return; // read contents char *pPos = MoreMusicFile.getMData(); while (pPos && *pPos) { // get line char szLine[1024 + 1]; SCopyUntil(pPos, szLine, '\n', 1024); pPos = strchr(pPos, '\n'); if (pPos) pPos++; // remove leading whitespace char *pLine = szLine; while (*pLine == ' ' || *pLine == '\t' || *pLine == '\r') pLine++; // and whitespace at end char *p = pLine + strlen(pLine) - 1; while (*p == ' ' || *p == '\t' || *p == '\r') { *p = 0; --p; } // comment? if (*pLine == '#') { // might be a "directive" if (SEqual(pLine, "#clear")) ClearSongs(); continue; } // try to load file(s) LoadDir(pLine); } }
void C4GameSave::WriteDescPlayers(StdStrBuf &sBuf, bool fByTeam, int32_t idTeam) { // write out all players; only if they match the given team if specified C4PlayerInfo *pPlr; bool fAnyPlrWritten = false; for (int i = 0; (pPlr = Game.PlayerInfos.GetPlayerInfoByIndex(i)); i++) if (pPlr->HasJoined() && !pPlr->IsRemoved() && !pPlr->IsInvisible()) { if (fByTeam) { if (idTeam) { // match team if (pPlr->GetTeam() != idTeam) continue; } else { // must be in no known team if (Game.Teams.GetTeamByID(pPlr->GetTeam())) continue; } } if (fAnyPlrWritten) sBuf.Append(", "); else if (fByTeam && idTeam) { C4Team *pTeam = Game.Teams.GetTeamByID(idTeam); if (pTeam) sBuf.AppendFormat("%s: ", pTeam->GetName()); } sBuf.Append(pPlr->GetName()); fAnyPlrWritten = true; } if (fAnyPlrWritten) WriteDescLineFeed(sBuf); }
bool C4Network2Res::SetByFile(const char *strFilePath, bool fTemp, C4Network2ResType eType, int32_t iResID, const char *szResName, bool fSilent) { CStdLock FileLock(&FileCSec); // default resource name: relative path if (!szResName) szResName = Config.AtRelativePath(strFilePath); SCopy(strFilePath, szFile, sizeof(szFile)-1); // group? C4Group Grp; if (Reloc.Open(Grp, strFilePath)) return SetByGroup(&Grp, fTemp, eType, iResID, szResName, fSilent); // so it needs to be a file StdStrBuf szFullFile; if (!Reloc.LocateItem(szFile, szFullFile)) { if (!fSilent) LogF("SetByFile: file %s not found!", strFilePath); return false; } // calc checksum uint32_t iCRC32; if (!GetFileCRC(szFullFile.getData(), &iCRC32)) return false; #ifdef C4NET2RES_DEBUG_LOG // log LogSilentF("Network: Resource: complete %d:%s is file %s (%s)", iResID, szResName, szFile, fTemp ? "temp" : "static"); #endif // set core Core.Set(eType, iResID, Config.AtRelativePath(szFullFile.getData()), iCRC32); // set own data fDirty = true; fTempFile = fTemp; fStandaloneFailed = false; fRemoved = false; iLastReqTime = time(NULL); fLoading = false; // ok return true; }
bool C4Application::SetGameFont(const char *szFontFace, int32_t iFontSize) { #ifndef USE_CONSOLE // safety if (!szFontFace || !*szFontFace || iFontSize<1 || SLen(szFontFace)>=static_cast<int>(sizeof Config.General.RXFontName)) return false; // first, check if the selected font can be created at all // check regular font only - there's no reason why the other fonts couldn't be created CStdFont TestFont; if (!::FontLoader.InitFont(&TestFont, szFontFace, C4FontLoader::C4FT_Main, iFontSize, &::GraphicsResource.Files)) return false; // OK; reinit all fonts StdStrBuf sOldFont; sOldFont.Copy(Config.General.RXFontName); int32_t iOldFontSize = Config.General.RXFontSize; SCopy(szFontFace, Config.General.RXFontName); Config.General.RXFontSize = iFontSize; if (!::GraphicsResource.InitFonts() || !C4Startup::Get()->Graphics.InitFonts()) { // failed :o // shouldn't happen. Better restore config. SCopy(sOldFont.getData(), Config.General.RXFontName); Config.General.RXFontSize = iOldFontSize; return false; } #endif // save changes return true; }
bool C4PlayerInfoCore::Load(C4Group &hGroup) { // New version StdStrBuf Source; if (hGroup.LoadEntryString(C4CFN_PlayerInfoCore,&Source)) { // Compile StdStrBuf GrpName = hGroup.GetFullName(); GrpName.Append(DirSep C4CFN_PlayerInfoCore); if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(*this, Source, GrpName.getData())) return false; // Pref for AutoContextMenus is still undecided: default by player's control style if (OldPrefAutoContextMenu == -1) OldPrefAutoContextMenu = OldPrefControlStyle; // Determine true color from indexed pref color if (!PrefColorDw) PrefColorDw = GetPrefColorValue(PrefColor); // Validate colors PrefColorDw &= 0xffffff; PrefColor2Dw &= 0xffffff; // Validate name C4Markup::StripMarkup(PrefName); // Success return true; } // Old version no longer supported - sorry return false; }
BOOL C4GameObjects::Save(const char *szFilename, BOOL fSaveGame, bool fSaveInactive) { // Enumerate Enumerate(); InactiveObjects.Enumerate(); Game.ScriptEngine.Strings.EnumStrings(); // Decompile objects to buffer StdStrBuf Buffer; bool fSuccess = DecompileToBuf_Log<StdCompilerINIWrite>( mkParAdapt(*this, false, !fSaveGame), &Buffer, szFilename); // Decompile inactives if (fSaveInactive) { StdStrBuf InactiveBuffer; fSuccess &= DecompileToBuf_Log<StdCompilerINIWrite>( mkParAdapt(InactiveObjects, false, !fSaveGame), &InactiveBuffer, szFilename); Buffer.Append("\r\n"); Buffer.Append(InactiveBuffer); } // Denumerate InactiveObjects.Denumerate(); Denumerate(); // Error? if (!fSuccess) return FALSE; // Write return Buffer.SaveToFile(szFilename); }
void C4ValueMapData::CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers) { bool deserializing = pComp->isDeserializer(); C4ValueMapNames *pOldNames = pNames; if (deserializing) Reset(); // Compile item count int32_t iValueCnt; if (!deserializing) iValueCnt = pNames ? pNames->iSize : 0; pComp->Value(mkDefaultAdapt(iValueCnt, 0)); // nuthing 2do for no items if (!iValueCnt) return; // Separator (';') pComp->Separator(StdCompiler::SEP_SEP2); // Data char **ppNames = !deserializing ? pNames->pNames : new char * [iValueCnt]; if (deserializing) for (int32_t i = 0; i < iValueCnt; i++) ppNames[i] = nullptr; C4Value *pValues = !deserializing ? pData : new C4Value [iValueCnt]; // Compile try { for (int32_t i = 0; i < iValueCnt; i++) { // Separate if (i) pComp->Separator(); // Name StdStrBuf Name; if (!deserializing) Name.Ref(ppNames[i]); pComp->Value(mkParAdapt(Name, StdCompiler::RCT_Idtf)); if (deserializing) ppNames[i] = Name.GrabPointer(); // Separator ('=') pComp->Separator(StdCompiler::SEP_SET); // Value pComp->Value(mkParAdapt(pValues[i], numbers)); } } catch (...) { // make sure no mem is leaked on compiler error in name list if (deserializing) { for (int32_t i = 0; i < iValueCnt; i++) if (ppNames[i]) free(ppNames[i]); delete [] ppNames; delete [] pValues; } throw; } // Set if (deserializing) { // Set CreateTempNameList(); pNames->SetNameArray(const_cast<const char **>(ppNames), iValueCnt); for (int32_t i = 0; i < iValueCnt; i++) free(ppNames[i]); delete [] ppNames; delete [] pData; pData = pValues; // Assign old name list if (pOldNames) SetNameList(pOldNames); } }
void C4StartupAboutDlg::OnRegisterBtn(C4GUI::Control *btn) { // open hardcoded registration URL // URL needs lowercase language code, two-character code only StdStrBuf sLangCode; sLangCode.Format("%.2s", Config.General.Language); sLangCode.ToLowerCase(); OpenURL(FormatString("http://www.clonk.de/register.php?lng=%s&product=cr", sLangCode.getData()).getData()); }
bool C4InteractiveThread::ThreadLogDebug(const char *szMessage, ...) { // format message va_list lst; va_start(lst, szMessage); StdStrBuf Msg = FormatStringV(szMessage, lst); // send to main thread return PushEvent(Ev_LogDebug, Msg.GrabPointer()); }
bool ValidateString(char *szString, ValidationOption eOption, size_t iMaxSize) { // validate in a StdStrBuf. Does one alloc and copy :( StdStrBuf buf; buf.Copy(szString); bool fInvalid = ValidateString(buf, eOption); if (fInvalid) SCopy(buf.getData(), szString, iMaxSize); return fInvalid; }
void C4StartupMainDlg::OnShown() { // Incoming update if (Application.IncomingUpdate) { C4UpdateDlg::ApplyUpdate(Application.IncomingUpdate.getData(), false, GetScreen()); Application.IncomingUpdate.Clear(); } // Manual update by command line or url if (Application.CheckForUpdates) { C4UpdateDlg::CheckForUpdates(GetScreen(), false); Application.CheckForUpdates = false; } // Automatic update else { if (Config.Network.AutomaticUpdate) C4UpdateDlg::CheckForUpdates(GetScreen(), true); } // first start evaluation if (Config.General.FirstStart) { Config.General.FirstStart = false; } // first thing that's needed is a new player, if there's none - independent of // first start bool fHasPlayer = false; StdStrBuf sSearchPath; const char *szFn; sSearchPath.Format("%s%s", (const char *)Config.General.ExePath, (const char *)Config.General.PlayerPath); for (DirectoryIterator i(sSearchPath.getData()); szFn = *i; i++) { szFn = Config.AtExeRelativePath(szFn); if (*GetFilename(szFn) == '.') continue; // ignore ".", ".." and private files (".*") if (!WildcardMatch(C4CFN_PlayerFiles, GetFilename(szFn))) continue; fHasPlayer = true; break; } if (!fHasPlayer) { // no player created yet: Create one C4GUI::Dialog *pDlg; GetScreen()->ShowModalDlg(pDlg = new C4StartupPlrPropertiesDlg(NULL, NULL), true); } // make sure participants are updated after switching back from player // selection UpdateParticipants(); // First show if (fFirstShown) { // Activate the application (trying to prevent flickering half-focus in // win32...) Application.Activate(); // Set the focus to the start button (we might still not have the focus // after the update-check sometimes... :/) SetFocus(pStartButton, false); } fFirstShown = false; }
bool C4FullScreen::ViewportCheck() { int iPlrNum; C4Player *pPlr; // Not active if (!Active) return false; // Determine film mode bool fFilm = (Game.C4S.Head.Replay && Game.C4S.Head.Film); // Check viewports switch (::Viewports.GetViewportCount()) { // No viewports: create no-owner viewport case 0: iPlrNum = NO_OWNER; // Film mode: create viewport for first player (instead of no-owner) if (fFilm) if ((pPlr = ::Players.First)) iPlrNum = pPlr->Number; // Create viewport ::Viewports.CreateViewport(iPlrNum, iPlrNum==NO_OWNER); // Non-film (observer mode) if (!fFilm) { // Activate mouse control ::MouseControl.Init(iPlrNum); // Display message for how to open observer menu (this message will be cleared if any owned viewport opens) StdStrBuf sKey; sKey.Format("<c ffff00><%s></c>", Game.KeyboardInput.GetKeyCodeNameByKeyName("FullscreenMenuOpen", false).getData()); ::GraphicsSystem.FlashMessage(FormatString(LoadResStr("IDS_MSG_PRESSORPUSHANYGAMEPADBUTT"), sKey.getData()).getData()); } break; // One viewport: do nothing case 1: break; // More than one viewport: remove all no-owner viewports default: ::Viewports.CloseViewport(NO_OWNER, true); break; } // Look for no-owner viewport C4Viewport *pNoOwnerVp = ::Viewports.GetViewport(NO_OWNER); // No no-owner viewport found if (!pNoOwnerVp) { // Close any open fullscreen menu CloseMenu(); } // No-owner viewport present else { // movie mode: player present, and no valid viewport assigned? if (Game.C4S.Head.Replay && Game.C4S.Head.Film && (pPlr = ::Players.First)) // assign viewport to joined player pNoOwnerVp->Init(pPlr->Number, true); } // Done return true; }
StdStrBuf C4Shader::Build(const ShaderSliceList &Slices, bool fDebug) { // At the start of the shader set the #version and number of // available uniforms StdStrBuf Buf; #ifndef USE_CONSOLE GLint iMaxFrags = 0, iMaxVerts = 0; glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &iMaxFrags); glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &iMaxVerts); #else int iMaxFrags = INT_MAX, iMaxVerts = INT_MAX; #endif Buf.Format("#version %d\n" "#define MAX_FRAGMENT_UNIFORM_COMPONENTS %d\n" "#define MAX_VERTEX_UNIFORM_COMPONENTS %d\n", C4Shader_Version, iMaxFrags, iMaxVerts); // Put slices int iPos = -1, iNextPos = -1; do { iPos = iNextPos; iNextPos = C4Shader_LastPosition+1; // Add all slices at the current level if (fDebug && iPos > 0) Buf.AppendFormat("\t// Position %d:\n", iPos); for (ShaderSliceList::const_iterator pSlice = Slices.begin(); pSlice != Slices.end(); pSlice++) { if (pSlice->Position < iPos) continue; if (pSlice->Position > iPos) { iNextPos = Min(iNextPos, pSlice->Position); continue; } // Same position - add slice! if (fDebug) { if (pSlice->Source.getLength()) Buf.AppendFormat("\t// Slice from %s:\n", pSlice->Source.getData()); else Buf.Append("\t// Built-in slice:\n"); } Buf.Append(pSlice->Text); if (Buf[Buf.getLength()-1] != '\n') Buf.AppendChar('\n'); } // Add seperator - only priority (-1) is top-level if (iPos == -1) { Buf.Append("void main() {\n"); } } while (iNextPos <= C4Shader_LastPosition); // Terminate Buf.Append("}\n"); return Buf; }
C4Network2ClientListBox::ClientListItem::ClientListItem(class C4Network2ClientListBox *pForDlg, int iClientID) // ctor : ListItem(pForDlg, iClientID), pStatusIcon(nullptr), pName(nullptr), pPing(nullptr), pActivateBtn(nullptr), pKickBtn(nullptr), last_sound_time(0) { // get associated client const C4Client *pClient = GetClient(); // get size int iIconSize = ::GraphicsResource.TextFont.GetLineHeight(); if (pForDlg->IsStartup()) iIconSize *= 2; int iWidth = pForDlg->GetItemWidth(); int iVerticalIndent = 2; SetBounds(C4Rect(0, 0, iWidth, iIconSize+2*iVerticalIndent)); C4GUI::ComponentAligner ca(GetContainedClientRect(), 0,iVerticalIndent); // create subcomponents bool fIsHost = pClient && pClient->isHost(); pStatusIcon = new C4GUI::Icon(ca.GetFromLeft(iIconSize), fIsHost ? C4GUI::Ico_Host : C4GUI::Ico_Client); StdStrBuf sNameLabel; if (pClient) { if (pForDlg->IsStartup()) sNameLabel.Ref(pClient->getName()); else sNameLabel.Format("%s:%s", pClient->getName(), pClient->getNick()); } else { sNameLabel.Ref("???"); } pName = new C4GUI::Label(sNameLabel.getData(), iIconSize + IconLabelSpacing,iVerticalIndent, ALeft); int iPingRightPos = GetBounds().Wdt - IconLabelSpacing; if (::Network.isHost()) iPingRightPos -= 48; if (::Network.isHost() && pClient && !pClient->isHost()) { // activate/deactivate and kick btns for clients at host if (!pForDlg->IsStartup()) { pActivateBtn = new C4GUI::CallbackButtonEx<C4Network2ClientListBox::ClientListItem, C4GUI::IconButton>(C4GUI::Ico_Active, GetToprightCornerRect(std::max(iIconSize, 16),std::max(iIconSize, 16),2,1,1), 0, this, &ClientListItem::OnButtonActivate); fShownActive = true; } pKickBtn = new C4GUI::CallbackButtonEx<C4Network2ClientListBox::ClientListItem, C4GUI::IconButton>(C4GUI::Ico_Kick, GetToprightCornerRect(std::max(iIconSize, 16),std::max(iIconSize, 16),2,1,0), 0, this, &ClientListItem::OnButtonKick); pKickBtn->SetToolTip(LoadResStrNoAmp("IDS_NET_KICKCLIENT")); } if (!pForDlg->IsStartup()) if (pClient && !pClient->isLocal()) { // wait time pPing = new C4GUI::Label("???", iPingRightPos, iVerticalIndent, ARight); pPing->SetToolTip(LoadResStr("IDS_DESC_CONTROLWAITTIME")); } // add components AddElement(pStatusIcon); AddElement(pName); if (pPing) AddElement(pPing); if (pActivateBtn) AddElement(pActivateBtn); if (pKickBtn) AddElement(pKickBtn); // add to listbox (will eventually get moved) pForDlg->AddElement(this); // first-time update Update(); }
bool LogSilentF(const char *strMessage, ...) { va_list args; va_start(args, strMessage); // Compose formatted message StdStrBuf Buf; Buf.FormatV(strMessage, args); // Log return LogSilent(Buf.getData()); }