StdStrBuf StdCompilerConfigRead::ReadString() { // Virtual key? if (pKey->Virtual) { excNotFound("Could not read value %s! Parent key doesn't exist!", pKey->Name.getData()); return StdStrBuf(); } // Wrong type? if (pKey->Type != REG_SZ) { excNotFound("Wrong value type!"); return StdStrBuf(); } // Get size of string DWORD iSize; if (RegQueryValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(), 0, NULL, NULL, &iSize) != ERROR_SUCCESS) { excNotFound("Could not read value %s!", pKey->Name.getData()); return StdStrBuf(); } // Allocate string StdBuf Result; Result.SetSize(iSize); // Read if (RegQueryValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(), 0, NULL, reinterpret_cast<BYTE *>(Result.getMData()), &iSize) != ERROR_SUCCESS) { excNotFound("Could not read value %s!", pKey->Name.getData()); return StdStrBuf(); } // Check size if (wcslen(getBufPtr<wchar_t>(Result)) + 1 != iSize / sizeof(wchar_t)) { excCorrupt("Wrong size of a string!"); return StdStrBuf(); } return StdStrBuf(getBufPtr<wchar_t>(Result)); }
StdStrBuf C4TeamList::GetTeamDistName(TeamDist eTeamDist) const { switch (eTeamDist) { case TEAMDIST_Free: return(StdStrBuf(LoadResStr("IDS_MSG_TEAMDIST_FREE"), true)); case TEAMDIST_Host: return(StdStrBuf(LoadResStr("IDS_MSG_TEAMDIST_HOST"), true)); case TEAMDIST_None: return(StdStrBuf(LoadResStr("IDS_MSG_TEAMDIST_NONE"), true)); case TEAMDIST_Random: return(StdStrBuf(LoadResStr("IDS_MSG_TEAMDIST_RND"), true)); case TEAMDIST_RandomInv: return(StdStrBuf(LoadResStr("IDS_MSG_TEAMDIST_RNDINV"), true)); default: return(FormatString("TEAMDIST_undefined(%d)", (int) eTeamDist)); } }
void ShowGfxErrorDialog() { // Application.Close will eventually post a quit message. We need to discard // that, so DialogBox() doesn't immediately exit. auto msg = MSG(); while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0) { if (msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } int ret = DialogBox(Application.GetInstance(), MAKEINTRESOURCE(IDD_GFXERROR), NULL, GfxErrProcedure); if (ret == 0 || ret == -1) { LPVOID lpMsgBuf; DWORD err = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); LogF("Error in GfxErrorDlg: %d - %s", err, StdStrBuf((wchar_t*)lpMsgBuf).getData()); LocalFree(lpMsgBuf); } // If we discarded a quit message, re-post it now if (msg.message == WM_QUIT) PostQuitMessage(msg.wParam); }
// 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; }
StdMeshLoader::StdMeshXML::StdMeshXML(const char* filename, const char* xml_data): FileName(filename) { Document.Parse(xml_data); if (Document.Error()) Error(StdStrBuf(Document.ErrorDesc()), Document.ErrorRow()); }
StdStrBuf C4KeyCodeEx::KeyShift2String(C4KeyShiftState eShift) { // query map const C4KeyShiftMapEntry *pCheck = KeyShiftMap; while (pCheck->szName) if (eShift == pCheck->eShift) break; else ++pCheck; return StdStrBuf(pCheck->szName); }
StdStrBuf C4RankSystem::GetRankName(int iRank, bool fReturnLastIfOver) { if (iRank<0) return StdStrBuf(); // if a new-style ranklist is loaded, seek there if (pszRankNames) { if (iRankNum<=0) return StdStrBuf(); // overflow check if (iRank>=iRankNum*(iRankExtNum+1)) { // rank undefined: Fallback to last rank if (!fReturnLastIfOver) return StdStrBuf(); iRank = iRankNum*(iRankExtNum+1)-1; } StdStrBuf sResult; if (iRank >= iRankNum) { // extended rank composed of two parts int iExtension = iRank / iRankNum - 1; iRank = iRank % iRankNum; sResult.Format(pszRankExtensions[iExtension], pszRankNames[iRank]); } else { // simple rank sResult.Ref(pszRankNames[iRank]); } return sResult; } #ifdef _WIN32 // old-style registry fallback while (iRank>=0) { char keyname[30]; StdCopyStrBuf rankname; sprintf(keyname,"Rank%03d",iRank+1); rankname = GetRegistryString(Register,keyname); if (!rankname.isNull()) return rankname; if (!fReturnLastIfOver) return StdStrBuf(); --iRank; } #endif return StdStrBuf(); }
StdStrBuf C4Network2Address::toString() const { switch (eProtocol) { case P_UDP: return FormatString("UDP:%s:%d", inet_ntoa(addr.sin_addr), htons(addr.sin_port)); case P_TCP: return FormatString("TCP:%s:%d", inet_ntoa(addr.sin_addr), htons(addr.sin_port)); default: return StdStrBuf("INVALID"); } }
bool C4ObjectInfoCore::Compile(const char *szSource) { bool ret = CompileFromBuf_LogWarn<StdCompilerINIRead>( mkNamingAdapt(*this, "ObjectInfo"), StdStrBuf(szSource), "ObjectInfo"); // DeathMessages are not allowed to stay forever if ('@' == DeathMessage[0]) DeathMessage[0] = ' '; return ret; }
BOOL C4ObjectInfoCore::Compile(const char *szSource) { bool ret = CompileFromBuf_LogWarn<StdCompilerINIRead>( mkNamingAdapt(*this, "ObjectInfo"), StdStrBuf(szSource), "ObjectInfo"); // Do a promotion update to set physicals right Physical.PromotionUpdate(Rank); // DeathMessages are not allowed to stay forever if ('@' == DeathMessage[0]) DeathMessage[0] = ' '; return ret; }
StdStrBuf C4TeamList::GetScriptPlayerName() const { // get a name to assign to a new script player. Try to avoid name conflicts if (!sScriptPlayerNames.getLength()) return StdStrBuf(LoadResStr("IDS_TEXT_COMPUTER")); // default name // test available script names int32_t iNameIdx = 0; StdStrBuf sOut; while (sScriptPlayerNames.GetSection(iNameIdx++, &sOut, '|')) if (!Game.PlayerInfos.GetActivePlayerInfoByName(sOut.getData())) return sOut; // none are available: Return a random name sScriptPlayerNames.GetSection(SafeRandom(iNameIdx-1), &sOut, '|'); return sOut; }
void C4ScenarioParameters::SetValue(const char *id, int32_t value, bool only_if_larger) { if (only_if_larger) { auto i = Parameters.find(StdStrBuf(id)); if (i != Parameters.end()) if (i->second >= value) // could become smaller. don't set. return; } // just update map Parameters[StdCopyStrBuf(id)] = value; }
bool C4Record::StreamFile(const char *szLocalFilename, const char *szAddAs) { // Load file into memory StdBuf FileData; if (!FileData.LoadFromFile(szLocalFilename)) return false; // Prepend name StdBuf Packed = DecompileToBuf<StdCompilerBinWrite>( mkInsertAdapt(StdStrBuf(szAddAs), FileData, false)); // Add to stream C4RecordChunkHead Head = {0, RCT_File}; Stream(Head, Packed); return true; }
StdStrBuf C4KeyboardInput::GetKeyCodeNameByKeyName(const char *szKeyName, bool fShort, int32_t iIndex) { C4CustomKey *pKey = GetKeyByName(szKeyName); if (pKey) { const C4CustomKey::CodeList &codes = pKey->GetCodes(); if ((size_t)iIndex < codes.size()) { C4KeyCodeEx code = codes[iIndex]; return code.ToString(true, fShort); } } // Error return StdStrBuf(); }
void StdCompilerConfigRead::String(char *szString, size_t iMaxLength, RawCompileType eType) { if (!LastString) LastString.Take(ReadString()); if (!LastString.getLength()) { *szString='\0'; return; } // when reading identifiers, only take parts of the string if (eType == RCT_Idtf || eType == RCT_IdtfAllowEmpty) { const char *s = LastString.getData(); size_t ncpy = 0; while (isalnum((unsigned char)s[ncpy])) ++ncpy; SCopy(LastString.getData(), szString, std::min(iMaxLength, ncpy)); LastString.Take(StdStrBuf(s+ncpy, true)); } else { SCopy(LastString.getData(), szString, iMaxLength); } }
void StdCompilerConfigRead::String(char **pszString, RawCompileType eType) { if (!LastString) LastString.Take(ReadString()); // when reading identifiers, only take parts of the string if (eType == RCT_Idtf || eType == RCT_IdtfAllowEmpty) { const char *s = LastString.getData(); size_t ncpy = 0; while (isalnum((unsigned char)s[ncpy])) ++ncpy; StdStrBuf Result(LastString.getData(), ncpy, true); Result.getMData()[ncpy] = '\0'; *pszString = Result.GrabPointer(); LastString.Take(StdStrBuf(s+ncpy, true)); } else { *pszString = LastString.GrabPointer(); } }
void C4PlayerInfoCore::CompileFunc(StdCompiler *pComp) { C4ValueNumbers numbers; pComp->Name("Player"); pComp->Value(mkNamingAdapt(toC4CStr(PrefName),"Name", "Neuling")); pComp->Value(mkNamingAdapt(toC4CStr(Comment), "Comment", "")); pComp->Value(mkNamingAdapt(Rank, "Rank", 0)); pComp->Value(mkNamingAdapt(toC4CStr(RankName),"RankName", LoadResStr("IDS_MSG_RANK"))); // TODO: check if this would be desirable pComp->Value(mkNamingAdapt(TotalScore, "Score", 0)); pComp->Value(mkNamingAdapt(Rounds, "Rounds", 0)); pComp->Value(mkNamingAdapt(RoundsWon, "RoundsWon", 0)); pComp->Value(mkNamingAdapt(RoundsLost, "RoundsLost", 0)); pComp->Value(mkNamingAdapt(TotalPlayingTime, "TotalPlayingTime", 0)); pComp->Value(mkNamingAdapt(mkParAdapt(ExtraData, &numbers), "ExtraData", C4ValueMapData())); pComp->Value(mkNamingAdapt(numbers, "ExtraDataValues")); if (pComp->isCompiler()) { numbers.Denumerate(); ExtraData.Denumerate(&numbers); } pComp->Value(mkNamingAdapt(toC4CStr(LeagueName),"LeagueName", "")); pComp->NameEnd(); pComp->Name("Preferences"); pComp->Value(mkNamingAdapt(PrefColor, "Color", 0)); pComp->Value(mkNamingAdapt(PrefColorDw, "ColorDw", 0xffu)); pComp->Value(mkNamingAdapt(PrefColor2Dw, "AlternateColorDw", 0u)); pComp->Value(mkNamingAdapt(PrefPosition, "Position", 0)); pComp->Value(mkNamingAdapt(PrefMouse, "Mouse", 1)); pComp->Value(mkNamingAdapt(OldPrefControl, "Control", 1)); pComp->Value(mkNamingAdapt(OldPrefControlStyle, "AutoStopControl", 0)); pComp->Value(mkNamingAdapt(OldPrefAutoContextMenu, "AutoContextMenu", -1)); // compiling default is -1 (if this is detected, AutoContextMenus will be defaulted by control style) pComp->Value(mkNamingAdapt(PrefControl, "ControlSet", StdStrBuf())); pComp->Value(mkNamingAdapt(PrefClonkSkin, "ClonkSkin", 0)); pComp->NameEnd(); pComp->Value(mkNamingAdapt(LastRound, "LastRound")); pComp->Value(mkNamingAdapt(Achievements, "Achievements")); }
C4ChartDialog::C4ChartDialog() : Dialog(DialogWidth, DialogHeight, LoadResStr("IDS_NET_STATISTICS"), false) { // register singleton pChartDlg = this; // add main chart switch component C4GUI::ComponentAligner caAll(GetContainedClientRect(), 5,5); pChartTabular = new C4GUI::Tabular(caAll.GetAll(), C4GUI::Tabular::tbTop); AddElement(pChartTabular); // add some graphs as subcomponents AddChart(StdStrBuf("oc")); AddChart(StdStrBuf("FPS")); AddChart(StdStrBuf("NetIO")); if (::Network.isEnabled()) AddChart(StdStrBuf("Pings")); AddChart(StdStrBuf("Control")); AddChart(StdStrBuf("APM")); }
bool StdCompilerConfigRead::Separator(Sep eSep) { // ensure string is loaded in case value begins with a separator if (!LastString.getData()) LastString.Take(ReadString()); if (LastString.getData()) { // separator within string: check if it is there if (LastString.getLength() && *LastString.getData() == SeparatorToChar(eSep)) { LastString.Take(StdStrBuf(LastString.getData()+1, true)); return true; } else { return false; } } else { // No separators outside strings return false; } }
void C4ScenarioParameterDefs::RegisterScriptConstants(const C4ScenarioParameters &values) { // register constants for all parameters in script engine // old-style: one constant per parameter for (const auto & Parameter : Parameters) { StdStrBuf constant_name; constant_name.Format("SCENPAR_%s", Parameter.GetID()); int32_t constant_value = values.GetValueByID(Parameter.GetID(), Parameter.GetDefault()); ::ScriptEngine.RegisterGlobalConstant(constant_name.getData(), C4VInt(constant_value)); } // new-style: all constants in a proplist auto scenpar = C4PropList::NewStatic(nullptr, nullptr, &Strings.P[P_SCENPAR]); for (const auto & Parameter : Parameters) { int32_t constant_value = values.GetValueByID(Parameter.GetID(), Parameter.GetDefault()); scenpar->SetPropertyByS(Strings.RegString(StdStrBuf(Parameter.GetID())), C4VInt(constant_value)); } scenpar->Freeze(); ::ScriptEngine.RegisterGlobalConstant("SCENPAR", C4Value(scenpar)); }
BOOL C4Folder::Compile(const char *szSource) { Default(); return CompileFromBuf_LogWarn<StdCompilerINIRead>(*this, StdStrBuf(szSource), C4CFN_FolderCore); }
void C4TeamList::CompileFunc(StdCompiler *pComp) { // if (pComp->isCompiler()) Clear(); - do not clear, because this would corrupt the fCustom-flag pComp->Value(mkNamingAdapt(fActive, "Active", true)); pComp->Value(mkNamingAdapt(fCustom, "Custom", true)); pComp->Value(mkNamingAdapt(fAllowHostilityChange, "AllowHostilityChange", false)); pComp->Value(mkNamingAdapt(fAllowTeamSwitch, "AllowTeamSwitch", false)); pComp->Value(mkNamingAdapt(fAutoGenerateTeams, "AutoGenerateTeams", false)); pComp->Value(mkNamingAdapt(iLastTeamID, "LastTeamID", 0)); StdEnumEntry<TeamDist> TeamDistEntries[] = { { "Free", TEAMDIST_Free }, { "Host", TEAMDIST_Host }, { "None", TEAMDIST_None }, { "Random", TEAMDIST_Random }, { "RandomInv", TEAMDIST_RandomInv }, }; pComp->Value(mkNamingAdapt(mkEnumAdaptT<uint8_t>(eTeamDist, TeamDistEntries), "TeamDistribution", TEAMDIST_Free)); pComp->Value(mkNamingAdapt(fTeamColors, "TeamColors", false)); pComp->Value(mkNamingAdapt(iMaxScriptPlayers, "MaxScriptPlayers", 0)); pComp->Value(mkNamingAdapt(mkParAdapt(sScriptPlayerNames, StdCompiler::RCT_All), "ScriptPlayerNames", StdStrBuf())); int32_t iOldTeamCount = iTeamCount; pComp->Value(mkNamingCountAdapt(iTeamCount, "Team")); if (pComp->isCompiler()) { while (iOldTeamCount--) delete ppList[iOldTeamCount]; delete [] ppList; if ((iTeamCapacity = iTeamCount)) { ppList = new C4Team *[iTeamCapacity]; memset(ppList, 0, sizeof(C4Team *)*iTeamCapacity); } else ppList = NULL; } if (iTeamCount) { // Force compiler to spezialize mkPtrAdaptNoNull(*ppList); // Save team list, using map-function. pComp->Value(mkNamingAdapt( mkArrayAdaptMap(ppList, iTeamCount, mkPtrAdaptNoNull<C4Team>), "Team")); } if (pComp->isCompiler()) { // adjust last team ID, which may not be set properly for player-generated team files iLastTeamID = std::max(GetLargestTeamID(), iLastTeamID); // force automatic generation of teams if none are defined if (!iTeamCount) fAutoGenerateTeams = true; } }
void C4StartupNetListEntry::SetReference(C4Network2Reference *pRef) { // safety: clear previous ClearRef(); // set info this->pRef = pRef; int32_t iIcon = pRef->getIcon(); if (!Inside<int32_t>(iIcon, 0, C4StartupScenSel_IconCount-1)) iIcon = C4StartupScenSel_DefaultIcon_Scenario; pIcon->SetFacet(C4Startup::Get()->Graphics.fctScenSelIcons.GetPhase(iIcon)); pIcon->SetAnimated(false, 0); pIcon->SetBounds(rctIconSmall); int32_t iPlrCnt = pRef->isEditor() ? pRef->Parameters.PlayerInfos.GetActivePlayerCount(false) : pRef->Parameters.Clients.getClientCnt(); C4Client *pHost = pRef->Parameters.Clients.getHost(); sInfoText[0].Format(LoadResStr("IDS_NET_REFONCLIENT"), pRef->getTitle(), pHost ? pHost->getName() : "unknown"); if (pRef->isEditor()) { sInfoText[1].Format(LoadResStr("IDS_NET_INFOEDITOR"), (int)iPlrCnt, StdStrBuf(pRef->getGameStatus().getDescription(), true).getData()); } else { sInfoText[1].Format(LoadResStr("IDS_NET_INFOPLRSGOALDESC"), (int)iPlrCnt, (int)pRef->Parameters.MaxPlayers, pRef->getGameGoalString().getData(), StdStrBuf(pRef->getGameStatus().getDescription(), true).getData()); } if (pRef->getTime() > 0) { StdStrBuf strDuration; strDuration.Format("%02d:%02d:%02d", pRef->getTime()/3600, (pRef->getTime() % 3600) / 60, pRef->getTime() % 60); sInfoText[1].Append(" - "); sInfoText[1].Append(strDuration); } sInfoText[2].Format(LoadResStr("IDS_DESC_VERSION"), pRef->getGameVersion().GetString().getData()); sInfoText[3].Format("%s: %s", LoadResStr("IDS_CTL_COMMENT"), pRef->getComment()); StdStrBuf sAddress; for (int i=0; i<pRef->getAddrCnt(); ++i) { if (i) sAddress.Append(", "); sAddress.Append(pRef->getAddr(i).toString()); } // editor reference if (pRef->isEditor()) AddStatusIcon(C4GUI::Ico_Editor, LoadResStr("IDS_CNS_CONSOLE")); // password if (pRef->isPasswordNeeded()) AddStatusIcon(C4GUI::Ico_Ex_LockedFrontal, LoadResStr("IDS_NET_INFOPASSWORD")); // league if (pRef->Parameters.isLeague()) AddStatusIcon(C4GUI::Ico_Ex_League, pRef->Parameters.getLeague()); // lobby active if (pRef->getGameStatus().isLobbyActive()) AddStatusIcon(C4GUI::Ico_Lobby, LoadResStr("IDS_DESC_EXPECTING")); // game running if (pRef->getGameStatus().isPastLobby()) AddStatusIcon(C4GUI::Ico_GameRunning, LoadResStr("IDS_NET_INFOINPROGR")); // runtime join if (pRef->isJoinAllowed() && pRef->getGameStatus().isPastLobby()) // A little workaround to determine RuntimeJoin... AddStatusIcon(C4GUI::Ico_RuntimeJoin, LoadResStr("IDS_NET_RUNTIMEJOINFREE")); // official server if (pRef->isOfficialServer() && !Config.Network.UseAlternateServer) // Offical server icon is only displayed if references are obtained from official league server { fIsImportant = true; AddStatusIcon(C4GUI::Ico_OfficialServer, LoadResStr("IDS_NET_OFFICIALSERVER")); } // list participating player/client names if (pRef->isEditor()) { sInfoText[4].Format("%s%s", LoadResStr("IDS_DESC_CLIENTS"), iPlrCnt ? pRef->Parameters.Clients.GetAllClientNames().getData() : LoadResStr("IDS_CTL_NONE")); } else { sInfoText[4].Format("%s: %s", LoadResStr("IDS_CTL_PLAYER"), iPlrCnt ? pRef->Parameters.PlayerInfos.GetActivePlayerNames(false).getData() : LoadResStr("IDS_CTL_NONE")); } // disabled if join is not possible for some reason C4GameVersion verThis; if (!pRef->isJoinAllowed() || !(pRef->getGameVersion() == verThis)) { fIsEnabled = false; } // store sort order iSortOrder = pRef->getSortOrder(); // all references expire after a while SetTimeout(TT_Reference); UpdateSmallState(); UpdateText(); }
BOOL C4Scenario::Compile(const char *szSource, bool fLoadSection) { if (!fLoadSection) Default(); return CompileFromBuf_LogWarn<StdCompilerINIRead>(mkParAdapt(*this, fLoadSection), StdStrBuf(szSource), C4CFN_ScenarioCore); }
StdMesh *StdMeshLoader::LoadMeshXml(const char* xml_data, size_t size, const StdMeshMatManager& manager, StdMeshSkeletonLoader& skel_loader, const char* filename) { StdMeshXML xml(filename ? filename : "<unknown>", xml_data); std::unique_ptr<StdMesh> mesh(new StdMesh); TiXmlElement* mesh_elem = xml.RequireFirstChild(NULL, "mesh"); // Load shared geometry, if any TiXmlElement* sharedgeometry_elem = mesh_elem->FirstChildElement("sharedgeometry"); if(sharedgeometry_elem != NULL) xml.LoadGeometry(*mesh, mesh->SharedVertices, sharedgeometry_elem); TiXmlElement* submeshes_elem = xml.RequireFirstChild(mesh_elem, "submeshes"); TiXmlElement* submesh_elem_base = xml.RequireFirstChild(submeshes_elem, "submesh"); for (TiXmlElement* submesh_elem = submesh_elem_base; submesh_elem != NULL; submesh_elem = submesh_elem->NextSiblingElement("submesh")) { mesh->SubMeshes.push_back(StdSubMesh()); StdSubMesh& submesh = mesh->SubMeshes.back(); const char* material = xml.RequireStrAttribute(submesh_elem, "material"); submesh.Material = manager.GetMaterial(material); if (!submesh.Material) xml.Error(FormatString("There is no such material named '%s'", material), submesh_elem); const char* usesharedvertices = submesh_elem->Attribute("usesharedvertices"); const std::vector<StdMesh::Vertex>* vertices; if(!usesharedvertices || strcmp(usesharedvertices, "true") != 0) { TiXmlElement* geometry_elem = xml.RequireFirstChild(submesh_elem, "geometry"); xml.LoadGeometry(*mesh, submesh.Vertices, geometry_elem); vertices = &submesh.Vertices; } else { if(mesh->SharedVertices.empty()) xml.Error(StdCopyStrBuf("Submesh specifies to use shared vertices but there is no shared geometry"), submesh_elem); vertices = &mesh->SharedVertices; } TiXmlElement* faces_elem = xml.RequireFirstChild(submesh_elem, "faces"); int FaceCount = xml.RequireIntAttribute(faces_elem, "count"); submesh.Faces.resize(FaceCount); unsigned int i = 0; for (TiXmlElement* face_elem = faces_elem->FirstChildElement("face"); face_elem != NULL && i < submesh.Faces.size(); face_elem = face_elem->NextSiblingElement("face"), ++i) { int v[3]; v[0] = xml.RequireIntAttribute(face_elem, "v1"); v[1] = xml.RequireIntAttribute(face_elem, "v2"); v[2] = xml.RequireIntAttribute(face_elem, "v3"); for (unsigned int j = 0; j < 3; ++j) { if (v[j] < 0 || static_cast<unsigned int>(v[j]) >= vertices->size()) xml.Error(FormatString("Vertex index v%u (%d) is out of range", j+1, v[j]), face_elem); submesh.Faces[i].Vertices[j] = v[j]; } } } // We allow bounding box to be empty if it's only due to Z direction since // this is what goes inside the screen in Clonk. if(mesh->BoundingBox.x1 == mesh->BoundingBox.x2 || mesh->BoundingBox.y1 == mesh->BoundingBox.y2) xml.Error(StdCopyStrBuf("Bounding box is empty"), mesh_elem); // Read skeleton, if any TiXmlElement* skeletonlink_elem = mesh_elem->FirstChildElement("skeletonlink"); if (skeletonlink_elem) { const char* name = xml.RequireStrAttribute(skeletonlink_elem, "name"); StdCopyStrBuf xml_filename(name); xml_filename.Append(".xml"); StdCopyStrBuf skeleton_filename; StdMeshSkeletonLoader::MakeFullSkeletonPath(skeleton_filename, filename, xml_filename.getData()); mesh->Skeleton = skel_loader.GetSkeletonByName(skeleton_filename); if (!mesh->Skeleton) xml.Error(FormatString("Failed to load '%s'", skeleton_filename.getData()), skeletonlink_elem); // Vertex<->Bone assignments for shared geometry if (sharedgeometry_elem) { TiXmlElement* boneassignments_elem = xml.RequireFirstChild(mesh_elem, "boneassignments"); xml.LoadBoneAssignments(*mesh, mesh->SharedVertices, boneassignments_elem); } // Vertex<->Bone assignments for all vertices (need to go through SubMeshes again...) unsigned int submesh_index = 0; for (TiXmlElement* submesh_elem = submesh_elem_base; submesh_elem != NULL; submesh_elem = submesh_elem->NextSiblingElement("submesh"), ++submesh_index) { StdSubMesh& submesh = mesh->SubMeshes[submesh_index]; if (!submesh.Vertices.empty()) { TiXmlElement* boneassignments_elem = xml.RequireFirstChild(submesh_elem, "boneassignments"); xml.LoadBoneAssignments(*mesh, submesh.Vertices, boneassignments_elem); } } } else { // Mesh has no skeleton // Bone assignements do not make sense then, as the // actual bones are defined in the skeleton file. for (TiXmlElement* submesh_elem = submesh_elem_base; submesh_elem != NULL; submesh_elem = submesh_elem->NextSiblingElement("submesh")) { TiXmlElement* boneassignments_elem = submesh_elem->FirstChildElement("boneassignments"); if (boneassignments_elem) xml.Error(StdStrBuf("Mesh has bone assignments, but no skeleton"), boneassignments_elem); } TiXmlElement* boneassignments_elem = mesh_elem->FirstChildElement("boneassignments"); if (boneassignments_elem) xml.Error(StdStrBuf("Mesh has bone assignments, but no skeleton"), boneassignments_elem); } return mesh.release(); }
void C4Network2IRCClient::OnNumericCommand(const char *szSender, int iCommand, const char *szParameters) { bool fShowMessage = true; // Get target StdStrBuf Target = ircExtractPar(&szParameters); // Handle command switch(iCommand) { case 433: // Nickname already in use { StdStrBuf DesiredNick = ircExtractPar(&szParameters); // Automatically try to choose a new one DesiredNick.AppendChar('_'); Send("NICK", DesiredNick.getData()); break; } case 376: // End of MOTD case 422: // MOTD missing // Let's take this a sign that the connection is established. OnConnected(); break; case 331: // No topic set case 332: // Topic notify / change { // Get Channel name and topic StdStrBuf Channel = ircExtractPar(&szParameters); StdStrBuf Topic = (iCommand == 332 ? ircExtractPar(&szParameters) : StdStrBuf("")); // Set it AddChannel(Channel.getData())->OnTopic(Topic.getData()); // Log if(Topic.getLength()) PushMessage(MSG_Status, szSender, Channel.getData(), FormatString(LoadResStr("IDS_MSG_TOPICIN"), Channel.getData(), Topic.getData()).getData()); } break; case 333: // Last topic change fShowMessage = false; // ignore break; case 353: // Names in channel { // Get Channel name and name list StdStrBuf Junk = ircExtractPar(&szParameters); // ??! StdStrBuf Channel = ircExtractPar(&szParameters); StdStrBuf Names = ircExtractPar(&szParameters); // Set it AddChannel(Channel.getData())->OnUsers(Names.getData(), Prefixes.getData()); fShowMessage = false; } break; case 366: // End of names list { // Get Channel name StdStrBuf Channel = ircExtractPar(&szParameters); // Finish AddChannel(Channel.getData())->OnUsersEnd(); fShowMessage = false; // Notify if(pNotify) pNotify->PushEvent(Ev_IRC_Message, this); } break; case 4: // Server version fShowMessage = false; // ignore break; case 5: // Server support string { while(szParameters && *szParameters) { // Get support-token. StdStrBuf Token = ircExtractPar(&szParameters); StdStrBuf Parameter; Parameter.CopyUntil(Token.getData(), '='); // Check if it's interesting and safe data if so. if(SEqualNoCase(Parameter.getData(), "PREFIX")) Prefixes.Copy(SSearch(Token.getData(), "=")); } fShowMessage = false; } break; } // Show embedded message, if any? if(fShowMessage) { // Check if first parameter is some sort of channel name C4Network2IRCChannel *pChannel = NULL; if(szParameters && *szParameters && *szParameters != ':') pChannel = getChannel(ircExtractPar(&szParameters).getData()); // Go over other parameters const char *pMsg = szParameters; while(pMsg && *pMsg && *pMsg != ':') pMsg = SSearch(pMsg, " "); // Show it if(pMsg && *pMsg) if(!pChannel) PushMessage(MSG_Server, szSender, Nick.getData(), pMsg + 1); else PushMessage(MSG_Status, szSender, pChannel->getName(), pMsg + 1); } }
virtual StdStrBuf LoadShaderCode(const char* filename) { StdStrBuf ret; if (!Group.LoadEntryString(filename, &ret)) return StdStrBuf(); return ret; }
StdStrBuf C4KeyCodeEx::KeyCode2String(C4KeyCode wCode, bool fHumanReadable, bool fShort) { // Gamepad keys if (Key_IsGamepad(wCode)) { int iGamepad = Key_GetGamepad(wCode); int gamepad_event = Key_GetGamepadEvent(wCode); switch (gamepad_event) { case KEY_JOY_Left: return FormatString("Joy%dLeft", iGamepad+1); case KEY_JOY_Up: return FormatString("Joy%dUp", iGamepad+1); case KEY_JOY_Down: return FormatString("Joy%dDown", iGamepad+1); case KEY_JOY_Right: return FormatString("Joy%dRight", iGamepad+1); default: if (Key_IsGamepadAxis(wCode)) { if (fHumanReadable) // This is still not great, but it is not really possible to assign unknown axes to "left/right" "up/down"... return FormatString("[%d] %s", int(1 + Key_GetGamepadAxisIndex(wCode)), Key_IsGamepadAxisHigh(wCode) ? "Max" : "Min"); else return FormatString("Joy%dAxis%d%s", iGamepad+1, static_cast<int>(Key_GetGamepadAxisIndex(wCode)+1), Key_IsGamepadAxisHigh(wCode) ? "Max" : "Min"); } else { // button if (fHumanReadable) // If there should be gamepads around with A B C D... on the buttons, we might create a display option to show letters instead... return FormatString("< %d >", int(1 + Key_GetGamepadButtonIndex(wCode))); else return FormatString("Joy%d%c", iGamepad+1, static_cast<char>(Key_GetGamepadButtonIndex(wCode) + 'A')); } } } // Mouse keys if (Key_IsMouse(wCode)) { int mouse_id = Key_GetMouse(wCode); int mouse_event = Key_GetMouseEvent(wCode); const char *mouse_str = "Mouse"; switch (mouse_event) { case KEY_MOUSE_Move: return FormatString("%s%dMove", mouse_str, mouse_id); case KEY_MOUSE_Wheel1Up: return FormatString("%s%dWheel1Up", mouse_str, mouse_id); case KEY_MOUSE_Wheel1Down: return FormatString("%s%dWheel1Down", mouse_str, mouse_id); case KEY_MOUSE_ButtonLeft: return FormatString("%s%dLeft", mouse_str, mouse_id); case KEY_MOUSE_ButtonRight: return FormatString("%s%dRight", mouse_str, mouse_id); case KEY_MOUSE_ButtonMiddle: return FormatString("%s%dMiddle", mouse_str, mouse_id); case KEY_MOUSE_ButtonLeftDouble: return FormatString("%s%dLeftDouble", mouse_str, mouse_id); case KEY_MOUSE_ButtonRightDouble: return FormatString("%s%dRightDouble", mouse_str, mouse_id); case KEY_MOUSE_ButtonMiddleDouble: return FormatString("%s%dMiddleDouble", mouse_str, mouse_id); default: // extended mouse button { uint8_t btn = Key_GetMouseEvent(wCode); if (btn >= KEY_MOUSE_Button1Double) return FormatString("%s%dButton%dDouble", mouse_str, mouse_id, int(btn-KEY_MOUSE_Button1Double)); else return FormatString("%s%dButton%d", mouse_str, mouse_id, int(btn-KEY_MOUSE_Button1)); } } } // it's a keyboard key if (!fHumanReadable) { // for config files and such: dump scancode return FormatString("$%x", static_cast<unsigned int>(wCode)); } #if defined(USE_WIN32_WINDOWS) || (defined(_WIN32) && defined(USE_GTK)) // Query map const C4KeyCodeMapEntry *pCheck = KeyCodeMap; while (pCheck->szName) if (wCode == pCheck->wCode) return StdStrBuf((pCheck->szShortName && fShort) ? pCheck->szShortName : pCheck->szName); else ++pCheck; // TODO: Works? // StdStrBuf Name; Name.SetLength(1000); // int res = GetKeyNameText(wCode, Name.getMData(), Name.getSize()); // if(!res) // // not found: Compose as direct code // return FormatString("\\x%x", (DWORD) wCode); // // Set size // Name.SetLength(res); // return Name; wchar_t buf[100]; int len = GetKeyNameText(wCode<<16, buf, 100); if (len > 0) { // buf is nullterminated name return StdStrBuf(buf); } #elif defined (USE_COCOA) // query map const C4KeyCodeMapEntry *pCheck = KeyCodeMap; while (pCheck->szName) if (wCode == pCheck->wCode) return StdStrBuf((pCheck->szShortName && fShort) ? pCheck->szShortName : pCheck->szName); else ++pCheck; // not found: Compose as direct code return FormatString("\\x%x", static_cast<unsigned int>(wCode)); #elif defined(USE_GTK) Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default()); KeySym keysym = (KeySym)XkbKeycodeToKeysym(dpy,wCode+8,0,0); char* name = NULL; if (keysym != NoSymbol) { // is the keycode without shift modifiers mapped to a symbol? name = gtk_accelerator_get_label_with_keycode(gdk_display_get_default(), keysym, wCode+8, (GdkModifierType)0); } if (name) { // is there a string representation of the keysym? // prevent memleak StdStrBuf buf; buf.Copy(name); g_free(name); return buf; } #elif defined(USE_SDL_MAINLOOP) StdStrBuf buf; buf.Copy(SDL_GetScancodeName(static_cast<SDL_Scancode>(wCode))); if (!buf.getLength()) buf.Format("\\x%x", wCode); return buf; #endif return FormatString("$%x", static_cast<unsigned int>(wCode)); }
bool C4ParticleDefCore::Compile(char *particle_source, const char *name) { return CompileFromBuf_LogWarn<StdCompilerINIRead>(mkNamingAdapt(*this, "Particle"), StdStrBuf(particle_source), name); }
int32_t C4ScenarioParameters::GetValueByID(const char *id, int32_t default_value) const { // return map value if name is in map. Otherwise, return default value. auto i = Parameters.find(StdStrBuf(id)); if (i != Parameters.end()) return i->second; else return default_value; }