void C4StartupMainDlg::UpdateParticipants() { // First validate all participants (files must exist) std::string strPlayers(Config.General.Participants); std::vector<char> strPlayer(1025); *Config.General.Participants=0; for (int i = 0; SCopySegment(strPlayers.c_str(), i, &strPlayer[0], ';', strPlayer.size() - 1, true); i++) { const char *szPlayer = &strPlayer[0]; std::string strPlayerFile(Config.General.UserDataPath); strPlayerFile.append(szPlayer); if (!szPlayer || !*szPlayer) continue; if (!FileExists(strPlayerFile.c_str())) continue; if (!SEqualNoCase(GetExtension(szPlayer), "ocp")) continue; // additional sanity check to clear strange exe-path-only entries in player list? SAddModule(Config.General.Participants, szPlayer); } // Draw selected players - we are currently displaying the players stored in Config.General.Participants. // Existence of the player files is not validated and player filenames are displayed directly // (names are not loaded from the player core). strPlayers = LoadResStr("IDS_DESC_PLRS"); if (!Config.General.Participants[0]) strPlayers.append(LoadResStr("IDS_DLG_NOPLAYERSSELECTED")); else for (int i = 0; SCopySegment(Config.General.Participants, i, &strPlayer[0], ';', 1024, true); i++) { if (i > 0) strPlayers.append(", "); strPlayers.append(GetFilenameOnly(&strPlayer[0])); } pParticipantsLbl->SetText(strPlayers.c_str()); }
void C4StartupMainDlg::UpdateParticipants() { // First validate all participants (files must exist) StdStrBuf strPlayers, strPlayer; strPlayer.SetLength(1024 + 1); strPlayers.Copy(Config.General.Participants); *Config.General.Participants = 0; for (int i = 0; SCopySegment(strPlayers.getData(), i, strPlayer.getMData(), ';', 1024, true); i++) { const char *szPlayer = strPlayer.getData(); if (!szPlayer || !*szPlayer) continue; if (!FileExists(szPlayer)) continue; if (!SEqualNoCase(GetExtension(szPlayer), "c4p")) continue; // additional sanity check to clear strange exe-path-only // entries in player list? SAddModule(Config.General.Participants, szPlayer); } // Draw selected players - we are currently displaying the players stored in // Config.General.Participants. // Existence of the player files is not validated and player filenames are // displayed directly // (names are not loaded from the player core). strPlayers.Format(LoadResStr("IDS_DESC_PLRS")); if (!Config.General.Participants[0]) strPlayers.Append(LoadResStr("IDS_DLG_NOPLAYERSSELECTED")); else for (int i = 0; SCopySegment(Config.General.Participants, i, strPlayer.getMData(), ';', 1024, true); i++) { if (i > 0) strPlayers.Append(", "); strPlayers.Append(C4Language::IconvClonk( GetFilenameOnly(strPlayer.getData())).getData()); } pParticipantsLbl->SetText(strPlayers.getData()); }
void C4StartupMainDlg::OnPlayerSelContextRemovePlr(C4GUI::Element *pTarget, const int &iIndex) { char szPlayer[1024+1]; if (SCopySegment(Config.General.Participants, iIndex, szPlayer, ';', 1024, true)) SRemoveModule(Config.General.Participants, szPlayer, false); UpdateParticipants(); }
int32_t C4SoundSystem::LoadEffects(C4Group &hGroup, const char *namespace_prefix, bool group_is_root) { // Local definition sounds: If there is a Sound.ocg in the group, load the sound from there if(group_is_root && hGroup.FindEntry(C4CFN_Sound)) { C4Group g; g.OpenAsChild(&hGroup, C4CFN_Sound, false, false); return LoadEffects(g, namespace_prefix, false); } int32_t iNum=0; char szFilename[_MAX_FNAME+1]; char szFileType[_MAX_FNAME+1]; C4SoundEffect *nsfx; // Process segmented list of file types for (int32_t i = 0; SCopySegment(C4CFN_SoundFiles, i, szFileType, '|', _MAX_FNAME); i++) { // Search all sound files in group hGroup.ResetSearch(); while (hGroup.FindNextEntry(szFileType, szFilename)) // Create and load effect if ((nsfx = new C4SoundEffect)) { if (nsfx->Load(szFilename, hGroup, namespace_prefix)) { // Overload same name effects RemoveEffect(nsfx->Name); // Add effect nsfx->Next=FirstSound; FirstSound=nsfx; iNum++; } else delete nsfx; } } // Load subgroups from Sound.ocg and other subgroups if (!group_is_root) { hGroup.ResetSearch(); while (hGroup.FindNextEntry(C4CFN_SoundSubgroups, szFilename)) { // Load from subgroup as a sub-namespace // get namespace name StdStrBuf sub_namespace; if (namespace_prefix) { sub_namespace.Copy(namespace_prefix); sub_namespace.Append("::"); } sub_namespace.Append(szFilename, strlen(szFilename) - strlen(C4CFN_SoundSubgroups) + 1); // load from child group C4Group subgroup; if (subgroup.OpenAsChild(&hGroup, szFilename, false, false)) { iNum += LoadEffects(subgroup, sub_namespace.getData(), false); } } } return iNum; }
int32_t C4FontLoader::LoadDefs(C4Group &hGroup, C4Config &rCfg) { // load vector fonts char fn[_MAX_PATH+1], fnDef[32]; int32_t i=0; while (SCopySegment(C4CFN_FontFiles, i++, fnDef, '|', 31)) { hGroup.ResetSearch(); while (hGroup.FindNextEntry(fnDef, fn)) { C4VectorFont *pVecFon = new C4VectorFont(); if (pVecFon->Init(hGroup, fn, rCfg)) { pVecFon->pNext = pVectorFonts; pVectorFonts = pVecFon; } else delete pVecFon; } } // load definition file StdStrBuf DefFileContent; if (!hGroup.LoadEntryString(C4CFN_FontDefs, DefFileContent)) return 0; std::vector<C4FontDef> NewFontDefs; if (!CompileFromBuf_LogWarn<StdCompilerINIRead>( mkNamingAdapt(mkSTLContainerAdapt(NewFontDefs), "Font"), DefFileContent, C4CFN_FontDefs)) return 0; // Copy the new FontDefs into the list FontDefs.insert(FontDefs.end(), NewFontDefs.begin(), NewFontDefs.end()); // done return NewFontDefs.size(); }
int32_t C4TextureMap::LoadMap(C4Group &hGroup, const char *szEntryName, BOOL *pOverloadMaterials, BOOL *pOverloadTextures) { char *bpMap; char szLine[100+1]; int32_t cnt, iIndex, iTextures = 0; // Load text file into memory if (!hGroup.LoadEntry(szEntryName,&bpMap,NULL,1)) return 0; // Scan text buffer lines for (cnt=0; SCopySegment(bpMap,cnt,szLine,0x0A,100); cnt++) if ( (szLine[0]!='#') && (SCharCount('=',szLine)==1) ) { SReplaceChar(szLine,0x0D,0x00); if (Inside<int32_t>( iIndex = strtol(szLine,NULL,10), 0, C4M_MaxTexIndex-1 )) { const char *szMapping = szLine+SCharPos('=',szLine)+1; StdStrBuf Material, Texture; Material.CopyUntil(szMapping, '-'); Texture.Copy(SSearch(szMapping, "-")); if (AddEntry(iIndex, Material.getData(), Texture.getData())) iTextures++; } } else { if (SEqual2(szLine, "OverloadMaterials")) { fOverloadMaterials = TRUE; if(pOverloadMaterials) *pOverloadMaterials = TRUE; } if (SEqual2(szLine, "OverloadTextures")) { fOverloadTextures = TRUE; if(pOverloadTextures) *pOverloadTextures = TRUE; } } // Delete buffer, return entry count delete [] bpMap; fEntriesAdded=false; return iTextures; }
int32_t C4SoundSystem::LoadEffects(C4Group &hGroup, BOOL fStatic) { int32_t iNum = 0; char szFilename[_MAX_FNAME + 1]; char szFileType[_MAX_FNAME + 1]; C4SoundEffect *nsfx; // Process segmented list of file types for (int32_t i = 0; SCopySegment(C4CFN_SoundFiles, i, szFileType, '|', _MAX_FNAME); i++) { // Search all sound files in group hGroup.ResetSearch(); while (hGroup.FindNextEntry(szFileType, szFilename)) // Create and load effect if (nsfx = new C4SoundEffect) if (nsfx->Load(szFilename, hGroup, fStatic)) { // Overload same name effects RemoveEffect(szFilename); // Add effect nsfx->Next = FirstSound; FirstSound = nsfx; iNum++; } else delete nsfx; } return iNum; }
void C4ObjectInfoCore::Default(C4ID n_id, C4DefList *pDefs, const char *cpNames) { // Def C4Def *pDef=NULL; if (pDefs) pDef = pDefs->ID2Def(n_id); // Defaults id=n_id; Participation=1; Rank=0; Experience=0; Rounds=0; DeathCount=0; Birthday=0; TotalPlayingTime=0; SCopy("Clonk",Name,C4MaxName); SCopy("Clonk",TypeName,C4MaxName); sRankName.Copy("Clonk"); sNextRankName.Clear(); NextRankExp=0; DeathMessage[0]='\0'; *PortraitFile=0; Age=0; ExtraData.Reset(); // Type if (pDef) SCopy(pDef->GetName(),TypeName,C4MaxName); // Name if (cpNames) { // Name file reference if (SSearchNoCase(cpNames,C4CFN_Names)) SCopy(GetAName(cpNames),Name,C4MaxName); // Name list else { SCopySegment(cpNames,Random(SCharCount(0x0A,cpNames)),Name,0x0A,C4MaxName+1); SClearFrontBack(Name); SReplaceChar(Name,0x0D,0x00); } if (!Name[0]) SCopy("Clonk",Name,C4MaxName); } #ifdef C4ENGINE if (pDefs) UpdateCustomRanks(pDefs); #endif // Physical Physical.Default(); if (pDef) Physical = pDef->Physical; Physical.PromotionUpdate(Rank); // Old format }
int C4RankSystem::Init(const char *szRegister, const char *szDefRanks, int iRankBase) { // Init SCopy(szRegister,Register,256); RankBase=iRankBase; // Check registry for present rank names and set defaults #ifdef _WIN32 int crank=0; char rankname[C4MaxName+1],keyname[30]; BOOL Checking=TRUE; while (Checking) { sprintf(keyname,"Rank%03d",crank+1); if (GetRegistryString(Register,keyname,rankname,C4MaxName+1)) { // Rank present crank++; } else { // Rank not defined, check for default if (SCopySegment(szDefRanks,crank,rankname,'|',C4MaxName) && SetRegistryString(Register,keyname,rankname)) crank++; else Checking=FALSE; } } return crank; #else // clear any loaded rank names Clear(); if (!szDefRanks) return 0; // make a copy szRankNames = new char[strlen(szDefRanks) + 1]; strcpy (szRankNames, szDefRanks); // split into substrings by replacing the | with zeros for (char * p = szRankNames; *p; ++p) if (*p == '|') { *p = 0; ++iRankNum; } ++ iRankNum; // The last rank is already terminated by zero // build a list of substrings pszRankNames = new char *[iRankNum]; char * p = szRankNames; for (int i = 0; i < iRankNum; ++i) { pszRankNames[i] = p; p += strlen(p) + 1; } return iRankNum; #endif }
BOOL C4UpdatePackage::DoGrpUpdate(C4Group *pUpdateData, C4GroupEx *pGrpTo) { char *pData; // sort entries if (pUpdateData->LoadEntry(C4CFN_UpdateEntries, &pData, NULL, 1)) { // delete all entries that do not appear in the entries list char strItemName[_MAX_FNAME + 1], strItemName2[_MAX_FNAME + 1]; pGrpTo->ResetSearch(); while (pGrpTo->FindNextEntry("*", strItemName)) { BOOL fGotIt = FALSE; for (int i = 0; fGotIt = SCopySegment(pData, i, strItemName2, '|', _MAX_FNAME); i++) { // remove seperator char *pSep = strchr(strItemName2, '='); if (pSep) *pSep = '\0'; // in list? if (SEqual(strItemName, strItemName2)) break; } if (!fGotIt) pGrpTo->DeleteEntry(strItemName); } // set entry times, set sort list char strSortList[32767] = ""; for (int i = 0; SCopySegment(pData, i, strItemName, '|', _MAX_FNAME); i++) { // get time (if given) char *pTime = strchr(strItemName, '='); if (pTime) *pTime++ = '\0'; // set if (pTime) pGrpTo->SetEntryTime(strItemName, atoi(pTime)); // update EntryCRC32. This will make updates to old groups invalid // however, it's needed so updates will update the EntryCRC of *unchanged* // files correctly pGrpTo->EntryCRC32(strItemName); // copy to sort list SAppend(strItemName, strSortList); SAppendChar('|', strSortList); } // sort by list pGrpTo->Sort(strSortList); delete[] pData; } // copy header from update group pGrpTo->SetHead(*pUpdateData); // ok return TRUE; }
C4GUI::ContextMenu *C4StartupMainDlg::OnPlayerSelContextRemove(C4GUI::Element *pBtn, int32_t iX, int32_t iY) { C4GUI::ContextMenu *pCtx = new C4GUI::ContextMenu(); char szPlayer[1024+1]; for (int i = 0; SCopySegment(Config.General.Participants, i, szPlayer, ';', 1024, true); i++) if (*szPlayer) pCtx->AddItem(GetFilenameOnly(szPlayer), "Remove this player from participation list", C4GUI::Ico_Player, new C4GUI::CBMenuHandlerEx<C4StartupMainDlg, int>(this, &C4StartupMainDlg::OnPlayerSelContextRemovePlr, i), nullptr); return pCtx; }
bool C4UpdatePackage::DoGrpUpdate(C4Group *pUpdateData, C4GroupEx *pGrpTo) { char *pData; // sort entries if (pUpdateData->LoadEntry(C4CFN_UpdateEntries, &pData, nullptr, 1)) { // delete all entries that do not appear in the entries list char strItemName[_MAX_FNAME+1], strItemName2[_MAX_FNAME+1]; pGrpTo->ResetSearch(); while (pGrpTo->FindNextEntry("*", strItemName)) { bool fGotIt = false; for (int i = 0; (fGotIt = SCopySegment(pData, i, strItemName2, '|', _MAX_FNAME)); i++) { // remove separator char *pSep = strchr(strItemName2, '='); if (pSep) *pSep = '\0'; // in list? if (SEqual(strItemName, strItemName2)) break; } if (!fGotIt) pGrpTo->DeleteEntry(strItemName); } // set entry times, set sort list char strSortList[32767] = ""; for (int i = 0; SCopySegment(pData, i, strItemName, '|', _MAX_FNAME); i++) { // strip checksum/time (if given) char *pTime = strchr(strItemName, '='); if (pTime) *pTime = '\0'; // copy to sort list SAppend(strItemName, strSortList); SAppendChar('|', strSortList); } // sort by list pGrpTo->Sort(strSortList); delete[] pData; } // copy header from update group pGrpTo->SetHead(*pUpdateData); // ok return true; }
BOOL C4ComponentHost::Load(const char *szName, C4GroupSet &hGroupSet, const char *szFilename, const char *szLanguage) { // Clear any old stuff Clear(); // Store name & filename SCopy(szName, Name); SCopy(szFilename, Filename); // Load component - try all segmented filenames char strEntry[_MAX_FNAME + 1], strEntryWithLanguage[_MAX_FNAME + 1]; for (int iFilename = 0; SCopySegment(Filename, iFilename, strEntry, '|', _MAX_FNAME); iFilename++) { // Try to insert all language codes provided into the filename char strCode[3] = ""; for (int iLang = 0; SCopySegment(szLanguage ? szLanguage : "", iLang, strCode, ',', 2); iLang++) { // Insert language code sprintf(strEntryWithLanguage, strEntry, strCode); if (hGroupSet.LoadEntryString(strEntryWithLanguage, Data)) { if (pConfig->General.fUTF8) Data.EnsureUnicode(); // Store actual filename C4Group *pGroup = hGroupSet.FindEntry(strEntryWithLanguage); pGroup->FindEntry(strEntryWithLanguage, Filename); CopyFilePathFromGroup(*pGroup); // Got it return TRUE; } // Couldn't insert language code anyway - no point in trying other // languages if (!SSearch(strEntry, "%s")) break; } } // Truncate any additional segments from stored filename SReplaceChar(Filename, '|', 0); // skip full path (unknown) FilePath[0] = 0; // Not loaded return FALSE; }
bool RestoreWindowPosition(HWND hwnd, const char *szWindowName, const char *szSubKey, bool fHidden) { char buffer2[5]; int x,y,wdt,hgt; bool fSetSize=true; StdCopyStrBuf regstr = GetRegistryString(szSubKey,szWindowName); // No position stored: cannot restore if (regstr.isNull()) return false; if (regstr == "Maximized") return !!ShowWindow(hwnd,SW_MAXIMIZE | SW_NORMAL); if (regstr == "Minimized") return !!ShowWindow(hwnd,SW_MINIMIZE | SW_NORMAL); SCopySegment(regstr.getData(),0,buffer2,',',4); sscanf(buffer2,"%i",&x); SCopySegment(regstr.getData(),1,buffer2,',',4); sscanf(buffer2,"%i",&y); if (SCopySegment(regstr.getData(),2,buffer2,',',4)) sscanf(buffer2,"%i",&wdt); else fSetSize=false; if (SCopySegment(regstr.getData(),3,buffer2,',',4)) sscanf(buffer2,"%i",&hgt); else fSetSize=false; if (!fSetSize) { RECT winpos; if (!GetWindowRect(hwnd,&winpos)) return false; wdt=winpos.right-winpos.left; hgt=winpos.bottom-winpos.top; } // Move window WINDOWPLACEMENT wp; memset(&wp, 0, sizeof(WINDOWPLACEMENT)); wp.length = sizeof(WINDOWPLACEMENT); GetWindowPlacement(hwnd, &wp); RECT normalpos; normalpos.left = x; normalpos.right = wdt + x; normalpos.top = y; normalpos.bottom = hgt + y; wp.rcNormalPosition = normalpos; if (SetWindowPlacement(hwnd, &wp)) return false; // Hide window if (fHidden) return !!ShowWindow(hwnd, SW_HIDE); // Show window return !!ShowWindow(hwnd, SW_NORMAL); }
bool C4Language::LoadLanguage(const char *strLanguages) { // Clear old string table ClearLanguage(); // Try to load string table according to language sequence char strLanguageCode[2 + 1]; for (int i = 0; SCopySegment(strLanguages, i, strLanguageCode, ',', 2, true); i++) if (InitStringTable(strLanguageCode)) return true; // No matching string table found: hardcoded fallback to US if (InitStringTable("US")) return true; // No string table present: this is really bad Log("Error loading language string table."); return false; }
void C4ObjectInfoCore::Default(C4ID n_id, C4DefList *pDefs, const char *cpNames) { // Def C4Def *pDef=NULL; if (pDefs) pDef = pDefs->ID2Def(n_id); // Defaults id=n_id; Participation=1; Rank=0; Experience=0; Rounds=0; DeathCount=0; Birthday=0; TotalPlayingTime=0; SCopy("Clonk",Name,C4MaxName); SCopy("Clonk",TypeName,C4MaxName); sRankName.Copy("Clonk"); sNextRankName.Clear(); NextRankExp=0; DeathMessage[0]='\0'; Age=0; ExtraData.Reset(); // Type if (pDef) SCopy(pDef->GetName(),TypeName,C4MaxName); // Name if (cpNames) { SCopySegment(cpNames,Random(SCharCount(0x0A,cpNames)),Name,0x0A,C4MaxName+1); SClearFrontBack(Name); SReplaceChar(Name,0x0D,0x00); if (!Name[0]) SCopy("Clonk",Name,C4MaxName); } if (pDefs) UpdateCustomRanks(pDefs); }
bool C4Extra::Init() { // no group: OK if (ExtraGroups.empty()) return true; // load from all definitions that are activated // add first definition first, so the priority will be lowest // (according to definition load/overload order) char szSegment[_MAX_PATH+1]; for (int cseg=0; SCopySegment(Game.DefinitionFilenames,cseg,szSegment,';',_MAX_PATH); cseg++) { for(auto & ExtraGroup : ExtraGroups) { if(LoadDef(*ExtraGroup, GetFilename(szSegment))) { break; } } } // done, success return true; }
bool C4ComponentHost::GetLanguageString(const char *szLanguage, StdStrBuf &rTarget) { const char *cptr; // No good parameters if (!szLanguage || !Data) return false; // Search for two-letter language identifier in text body, i.e. "DE:" char langindex[4] = ""; for (int clseg = 0; SCopySegment(szLanguage ? szLanguage : "", clseg, langindex, ',', 2); clseg++) { SAppend(":", langindex); if (cptr = SSearch(Data.getData(), langindex)) { // Return the according string int iEndPos = SCharPos('\r', cptr); if (iEndPos < 0) iEndPos = SCharPos('\n', cptr); if (iEndPos < 0) iEndPos = strlen(cptr); rTarget.Copy(cptr, iEndPos); return true; } } // Language string not found return false; }
bool C4Sky::Init(bool fSavegame) { int32_t skylistn; // reset scrolling pos+speed // not in savegame, because it will have been loaded from game data there if (!fSavegame) { x=y=xdir=ydir=0; ParX=ParY=10; ParallaxMode=0; } // Check for sky bitmap in scenario file Surface = new C4Surface(); bool loaded = !!Surface->LoadAny(Game.ScenarioFile,C4CFN_Sky,true,true, C4SF_Tileable | C4SF_MipMap); // Else, evaluate scenario core landscape sky default list if (!loaded) { // Scan list sections SReplaceChar(Game.C4S.Landscape.SkyDef,',',';'); // modifying the C4S here...! skylistn=SCharCount(';',Game.C4S.Landscape.SkyDef)+1; char str[402]; SCopySegment(Game.C4S.Landscape.SkyDef,SeededRandom(Game.RandomSeed,skylistn),str,';'); SClearFrontBack(str); // Sky tile specified, try load if (*str && !SEqual(str,"Default")) { // Check for sky tile in scenario file loaded = !!Surface->LoadAny(Game.ScenarioFile,str,true,true, C4SF_Tileable | C4SF_MipMap); if (!loaded) { loaded = !!Surface->LoadAny(::GraphicsResource.Files, str, true, false, C4SF_Tileable | C4SF_MipMap); } } } if (loaded) { // surface loaded, store first color index FadeClr1=FadeClr2=0xffffffff; // set parallax scroll mode switch (Game.C4S.Landscape.SkyScrollMode) { case 0: // default: no scrolling break; case 1: // go with the wind in xdir, and do some parallax scrolling in ydir ParallaxMode=C4SkyPM_Wind; ParY=20; break; case 2: // parallax in both directions ParX=ParY=20; break; } } // Else, try creating default Surface if (!loaded) { SetFadePalette(Game.C4S.Landscape.SkyDefFade); delete Surface; Surface = 0; } // Load sky shaders: regular sprite shaders with OC_SKY define const char* const SkyDefines[] = { "OC_SKY", NULL }; if (!pDraw->PrepareSpriteShader(Shader, "Sky", Surface ? C4SSC_BASE : 0, &::GraphicsResource.Files, SkyDefines, NULL)) return false; if (!pDraw->PrepareSpriteShader(ShaderLight, "SkyLight", (Surface ? C4SSC_BASE : 0) | C4SSC_LIGHT, &::GraphicsResource.Files, SkyDefines, NULL)) return false; // no sky - using fade in newgfx if (!Surface) return true; // Store size if (Surface) { int iWdt,iHgt; if (Surface->GetSurfaceSize(iWdt, iHgt)) { Width = iWdt; Height = iHgt; } } // Success return true; }
bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) { // Determine player C4Player *pPlr = ::Players.Get(Player); // Activate if (SEqual2(szCommand,"ActivateMenu:")) { if (C4GameOverDlg::IsShown()) return false; // no new menus during game over dlg if (SEqual(szCommand+13,"Main")) return ActivateMain(Player); if (SEqual(szCommand+13,"Hostility")) return ActivateHostility(Player); if (SEqual(szCommand+13,"NewPlayer")) return ActivateNewPlayer(Player); if (SEqual(szCommand+13,"Goals")) { ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::ActivateGoalMenu(::Players.Get(Player)), CDT_Queue); return true; } if (SEqual(szCommand+13,"Rules")) return ActivateRules(Player); if (SEqual(szCommand+13,"Host")) return ActivateHost(Player); if (SEqual(szCommand+13,"Client")) return ActivateClient(Player); if (SEqual(szCommand+13,"Options")) return ActivateOptions(Player); if (SEqual(szCommand+13,"Display")) return ActivateDisplay(Player); if (SEqual(szCommand+13,"Save:Game")) return ActivateSavegame(Player); if (SEqual(szCommand+13,"TeamSel")) return pPlr ? pPlr->ActivateMenuTeamSelection(true) : false; if (SEqual(szCommand+13,"Surrender")) return ActivateSurrender(Player); if (SEqual(szCommand+13,"Observer")) return ActivateObserver(); } // JoinPlayer if (SEqual2(szCommand,"JoinPlayer:")) { // not in league or replay mode if (Game.Parameters.isLeague() || Game.C4S.Head.Replay) return false; // join player // 2do: not for observers and such? Players.JoinNew(szCommand+11); return true; } // SetHostility if (SEqual2(szCommand,"SetHostility:")) { // only if allowed if (!Game.Teams.IsHostilityChangeAllowed()) return false; int32_t iOpponent; sscanf(szCommand+13,"%i",&iOpponent); C4Player *pOpponent = ::Players.Get(iOpponent); if (!pOpponent || pOpponent->GetType() != C4PT_User) return false; ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::SetHostility(::Players.Get(Player), pOpponent, !::Players.HostilityDeclared(Player, pOpponent->Number)), CDT_Queue); return true; } // Abort if (SEqual2(szCommand,"Abort")) { FullScreen.ShowAbortDlg(); return true; } // Surrender if (SEqual2(szCommand,"Surrender")) { ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::Surrender(::Players.Get(Player)), CDT_Queue); return true; } // Save game if (SEqual2(szCommand, "Save:Game:")) { char strFilename[_MAX_PATH + 1]; SCopySegment(szCommand, 2, strFilename, ':', _MAX_PATH); char strTitle[_MAX_PATH + 1]; SCopy(szCommand + SCharPos(':', szCommand, 2) + 1, strTitle, _MAX_PATH); Game.QuickSave(strFilename, strTitle); ActivateSavegame(Player); return true; } // Kick if (SEqual2(szCommand,"Host:Kick:")) { int iClientID = atoi(szCommand+10); if (iClientID && ::Network.isEnabled()) { if (Game.Parameters.isLeague() && ::Players.GetAtClient(iClientID)) ::Network.Vote(VT_Kick, true, iClientID); else { C4Client *pClient = Game.Clients.getClientByID(iClientID); if (pClient) Game.Clients.CtrlRemove(pClient, LoadResStr("IDS_MSG_KICKBYMENU")); Close(true); } } return true; } // Part if (SEqual2(szCommand,"Part")) { if (::Network.isEnabled()) { if (Game.Parameters.isLeague() && ::Players.GetLocalByIndex(0)) ::Network.Vote(VT_Kick, true, ::Control.ClientID()); else { Game.RoundResults.EvaluateNetwork(C4RoundResults::NR_NetError, LoadResStr("IDS_ERR_GAMELEFTVIAPLAYERMENU")); ::Network.Clear(); } } return true; } // Options if (SEqual2(szCommand,"Options:")) { // Music if (SEqual(szCommand + 8, "Music")) { Application.MusicSystem.ToggleOnOff(); } // Sound if (SEqual(szCommand + 8, "Sound")) { if (Config.Sound.RXSound) { Application.SoundSystem.Clear(); Config.Sound.RXSound = false; } else { Config.Sound.RXSound = true; if (!Application.SoundSystem.Init()) { Log(LoadResStr("IDS_PRC_NOSND")); } } } // Reopen with updated options ActivateOptions(Player, GetSelection()); return true; } // Display if (SEqual2(szCommand,"Display:")) { // Upper board if (SEqual(szCommand + 8, "UpperBoard")) { Config.Graphics.UpperBoard = !Config.Graphics.UpperBoard; ::Viewports.RecalculateViewports(); } // FPS if (SEqual(szCommand + 8, "FPS")) Config.General.FPS = !Config.General.FPS; // Player names if (SEqual(szCommand + 8, "PlayerNames")) Config.Graphics.ShowCrewNames = !Config.Graphics.ShowCrewNames; // Clonk names if (SEqual(szCommand + 8, "ClonkNames")) Config.Graphics.ShowCrewCNames = !Config.Graphics.ShowCrewCNames; // Clock if (SEqual(szCommand + 8, "Clock")) Config.Graphics.ShowClock = !Config.Graphics.ShowClock; // Reopen with updated options ActivateDisplay(Player, GetSelection()); return true; } // Goal info if (SEqual2(szCommand,"Player:Goal:") || SEqual2(szCommand,"Player:Rule:")) { if (!ValidPlr(Player)) return false; // observers may not look at goal/rule info, because it requires queue activation Close(true); C4Object *pObj; C4ID idItem(szCommand+12); C4Def * pDef = C4Id2Def(idItem); if (pDef && (pObj = ::Objects.Find(pDef))) ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::ActivateGoal(::Players.Get(Player), pObj), CDT_Queue); else return false; return true; } // Team selection if (SEqual2(szCommand, "TeamSel:")) { Close(true); int32_t idTeam = atoi(szCommand+8); // OK, join this team if (pPlr) pPlr->DoTeamSelection(idTeam); return true; } // Team switch if (SEqual2(szCommand, "TeamSwitch:")) { Close(true); int32_t idTeam = atoi(szCommand+11); // check if it's still allowed if (!Game.Teams.IsTeamSwitchAllowed()) return false; // OK, join this team ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::SetTeam(::Players.Get(Player), idTeam), CDT_Queue); return true; } // Observe if (SEqual2(szCommand, "Observe:")) { const char *szObserverTarget = szCommand+8; C4Viewport *pVP = ::Viewports.GetViewport(NO_OWNER); if (pVP) // viewport may have closed meanwhile { if (SEqual(szObserverTarget, "Free")) { // free view pVP->Init(NO_OWNER, true); return true; } else { // view following player int32_t iPlr = atoi(szObserverTarget); if (ValidPlr(iPlr)) { pVP->Init(iPlr, true); return true; } } } return false; } // No valid command return false; }
bool C4FontLoader::InitFont(CStdFont &rFont, const char *szFontName, FontType eType, int32_t iSize, C4GroupSet *pGfxGroups, bool fDoShadow) { // safety if (!szFontName || !*szFontName) { LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // get font to load // pFontDefs may be NULL if no fonts are loaded; but then iFontDefCount is zero as well // the function must not be aborted, because a standard windows font may be loaded std::vector<C4FontDef>::iterator pFontDefC = FontDefs.begin(), pFontDef = FontDefs.end(); while (pFontDefC != FontDefs.end()) { // check font if (pFontDefC->Name == szFontName) { int32_t iSizeDiff = Abs(pFontDefC->iSize - iSize); // better match than last font? if (pFontDef == FontDefs.end() || Abs(pFontDef->iSize - iSize) >= iSizeDiff) pFontDef = pFontDefC; } // check next one ++pFontDefC; } // if def has not been found, use the def as font name // determine font def string const char *szFontString = szFontName; // special: Fonts without shadow are always newly rendered if (!fDoShadow) { pFontDef=FontDefs.end(); } if (pFontDef!=FontDefs.end()) switch (eType) { case C4FT_Log: szFontString = pFontDef->LogFont.getData(); break; case C4FT_MainSmall:szFontString = pFontDef->SmallFont.getData(); break; case C4FT_Main: szFontString = pFontDef->Font.getData(); break; case C4FT_Caption: szFontString = pFontDef->CaptionFont.getData(); break; case C4FT_Title: szFontString = pFontDef->TitleFont.getData(); break; default: LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; // invalid call } // font not assigned? if (!*szFontString) { // invalid call or spec LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // get font name char FontFaceName[C4MaxName+1], FontParam[C4MaxName+1]; SCopyUntil(szFontString, FontFaceName, ',', C4MaxName); // is it an image file? const char *szExt = GetExtension(FontFaceName); if (SEqualNoCase(szExt, "png") || SEqualNoCase(szExt, "bmp")) { // image file name: load bitmap font from image file // if no graphics group is given, do not load yet if (!pGfxGroups) { LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // indent given? int32_t iIndent = 0; if (SCopySegment(szFontString, 1, FontParam, ',', C4MaxName)) sscanf(FontParam, "%i", &iIndent); // load font face from gfx group int32_t iGrpId; C4Group *pGrp = pGfxGroups->FindEntry(FontFaceName, NULL, &iGrpId); if (!pGrp) { LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // check if it's already loaded from that group with that parameters if (!rFont.IsSameAsID(FontFaceName, iGrpId, iIndent)) { // it's not; so (re-)load it now! if (rFont.IsInitialized()) { // reloading rFont.Clear(); LogF(LoadResStr("IDS_PRC_UPDATEFONT"), FontFaceName, iIndent, 0); } C4Surface sfc; if (!sfc.Load(*pGrp, FontFaceName)) { LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // init font from face try { rFont.Init(GetFilenameOnly(FontFaceName), &sfc, iIndent); } catch (std::runtime_error & e) { LogFatal(e.what()); LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } rFont.id = iGrpId; } } else { int32_t iDefFontSize; DWORD dwDefWeight=FW_NORMAL; #if defined(_WIN32) && !defined(HAVE_FREETYPE) switch (eType) { case C4FT_Log: iDefFontSize = 8; break; case C4FT_MainSmall:iDefFontSize = iSize+1; break; case C4FT_Main: iDefFontSize = iSize+4; break; case C4FT_Caption: iDefFontSize = iSize+6; dwDefWeight = FW_BOLD; break; case C4FT_Title: iDefFontSize = iSize*3; break; default: LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; // invalid call } #else switch (eType) { case C4FT_Log: iDefFontSize = iSize*12/14; break; case C4FT_MainSmall:iDefFontSize = iSize*13/14; break; case C4FT_Main: iDefFontSize = iSize; break; case C4FT_Caption: iDefFontSize = iSize*16/14; /*dwDefWeight = FW_MEDIUM;*/ break; case C4FT_Title: iDefFontSize = iSize*22/14; /*dwDefWeight = FW_MEDIUM;*/ break; default: LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; // invalid call } #endif // regular font name: let WinGDI or Freetype draw a font with the given parameters // font size given? if (SCopySegment(szFontString, 1, FontParam, ',', C4MaxName)) sscanf(FontParam, "%i", &iDefFontSize); // font weight given? if (SCopySegment(szFontString, 2, FontParam, ',', C4MaxName)) sscanf(FontParam, "%i", &dwDefWeight); // check if it's already loaded from that group with that parameters if (!rFont.IsSameAs(FontFaceName, iDefFontSize, dwDefWeight)) { // it's not; so (re-)load it now! if (rFont.IsInitialized()) { // reloading rFont.Clear(); LogF(LoadResStr("IDS_PRC_UPDATEFONT"), FontFaceName, iDefFontSize, dwDefWeight); } // init with given font name try { // check if one of the internally listed fonts should be used C4VectorFont * pFont = pVectorFonts; while (pFont) { if (SEqual(pFont->Name.getData(), FontFaceName)) { if (InitFont(rFont, pFont, iDefFontSize, dwDefWeight, fDoShadow)) break; } pFont = pFont->pNext; } // no internal font matching? Then create one using the given face/filename (using a system font) if (!pFont) { pFont = new C4VectorFont(); if (pFont->Init(FontFaceName, iDefFontSize, dwDefWeight, Config.General.LanguageCharset)) { AddVectorFont(pFont); if (!InitFont(rFont, pFont, iDefFontSize, dwDefWeight, fDoShadow)) throw std::runtime_error(FormatString("Error initializing font %s", FontFaceName).getData()); } else { delete pFont; // no match for font face found throw std::runtime_error(FormatString("Font face %s undefined", FontFaceName).getData()); } } } catch (std::runtime_error & e) { LogFatal(e.what()); LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } rFont.id = 0; } } // done, success return true; }
BOOL C4ComponentHost::LoadAppend(const char *szName, C4Group &hGroup, const char *szFilename, const char *szLanguage) { Clear(); // Store name & filename SCopy(szName, Name); SCopy(szFilename, Filename); // Load component (segmented filename) char str1[_MAX_FNAME + 1], str2[_MAX_FNAME + 1]; int iFileCnt = 0, iFileSizeSum = 0; int cseg, clseg; for (cseg = 0; SCopySegment(Filename, cseg, str1, '|', _MAX_FNAME); cseg++) { char szLang[3] = ""; for (clseg = 0; SCopySegment(szLanguage ? szLanguage : "", clseg, szLang, ',', 2); clseg++) { sprintf(str2, str1, szLang); // Check existance size_t iFileSize; if (hGroup.FindEntry(str2, NULL, &iFileSize)) { iFileCnt++; iFileSizeSum += 1 + iFileSize; break; } if (!SSearch(str1, "%s")) break; } } // No matching files found? if (!iFileCnt) return FALSE; // Allocate memory Data.SetLength(iFileSizeSum); // Search files to read contents char *pPos = Data.getMData(); *pPos = 0; for (cseg = 0; SCopySegment(Filename, cseg, str1, '|', _MAX_FNAME); cseg++) { char szLang[3] = ""; for (clseg = 0; SCopySegment(szLanguage ? szLanguage : "", clseg, szLang, ',', 2); clseg++) { sprintf(str2, str1, szLang); // Load data char *pTemp; if (hGroup.LoadEntry(str2, &pTemp, NULL, 1)) { *pPos++ = '\n'; SCopy(pTemp, pPos, Data.getPtr(Data.getLength()) - pPos); pPos += SLen(pPos); delete[] pTemp; break; } delete[] pTemp; if (!SSearch(str1, "%s")) break; } } SReplaceChar(Filename, '|', 0); CopyFilePathFromGroup(hGroup); return !!iFileCnt; }