/* =============== UI_ParseInfos =============== */ int UI_ParseInfos(char *buf, int max, char *infos[]) { char *token; int count; char key[MAX_TOKEN_CHARS]; char info[MAX_INFO_STRING]; count = 0; while(1) { token = Com_Parse(&buf); if(!token[0]) { break; } if(strcmp(token, "{")) { Com_Printf("Missing { in info file\n"); break; } if(count == max) { Com_Printf("Max infos exceeded\n"); break; } info[0] = '\0'; while(1) { token = Com_ParseExt(&buf, qtrue); if(!token[0]) { Com_Printf("Unexpected end of info file\n"); break; } if(!strcmp(token, "}")) { break; } Q_strncpyz(key, token, sizeof(key)); token = Com_ParseExt(&buf, qfalse); if(!token[0]) { strcpy(token, "<NULL>"); } Info_SetValueForKey(info, key, token); } //NOTE: extra space for arena number infos[count] = UI_Alloc(strlen(info) + strlen("\\num\\") + strlen(va("%d", MAX_ARENAS)) + 1); if(infos[count]) { strcpy(infos[count], info); count++; } } return count; }
/* =================== Com_ParseOnLine =================== */ const char *Com_ParseOnLine( const char *(*data_p) ) { if ( pi->ungetToken ) { pi->ungetToken = qfalse; return pi->token; } return Com_ParseExt( data_p, qfalse ); }
const char* Com_Parse( const char** data_p ) { if ( pi->ungetToken ) { pi->ungetToken = false; return pi->token; } return Com_ParseExt( data_p, true ); }
/* ================= Com_SkipRestOfLine Skips until a new line is found ================= */ void Com_SkipRestOfLine (char **parseData){ char *tok; while (1){ tok = Com_ParseExt(parseData, false); if (!tok[0]) break; } }
/* ================= Com_SkipBracedSection Skips until a matching close brace is found. Internal brace depths are properly skipped. ================= */ void Com_SkipBracedSection (char **parseData, int depth){ char *tok; do { tok = Com_ParseExt(parseData, true); if (tok[1] == 0){ if (tok[0] == '{') depth++; else if (tok[0] == '}') depth--; } } while (depth && *parseData); }
/* ================= CG_HeadModelVoiceChats ================= */ int CG_HeadModelVoiceChats(char *filename) { int len, i; fileHandle_t f; char buf[MAX_VOICEFILESIZE]; char **p, *ptr; char *token; len = trap_FS_FOpenFile(filename, &f, FS_READ); if(!f) { //trap_Print( va( "voice chat file not found: %s\n", filename ) ); return -1; } if(len >= MAX_VOICEFILESIZE) { trap_Print(va(S_COLOR_RED "voice chat file too large: %s is %i, max allowed is %i", filename, len, MAX_VOICEFILESIZE)); trap_FS_FCloseFile(f); return -1; } trap_FS_Read(buf, len, f); buf[len] = 0; trap_FS_FCloseFile(f); ptr = buf; p = &ptr; token = Com_ParseExt(p, qtrue); if(!token || token[0] == 0) { return -1; } for(i = 0; i < MAX_VOICEFILES; i++) { if(!Q_stricmp(token, voiceChatLists[i].name)) { return i; } } //FIXME: maybe try to load the .voice file which name is stored in token? return -1; }
/* ================= CG_ParseVoiceChats ================= */ int CG_ParseVoiceChats(const char *filename, voiceChatList_t * voiceChatList, int maxVoiceChats) { int len, i; fileHandle_t f; char buf[MAX_VOICEFILESIZE]; char **p, *ptr; char *token; voiceChat_t *voiceChats; qboolean compress; sfxHandle_t sound; compress = qtrue; if(cg_buildScript.integer) { compress = qfalse; } len = trap_FS_FOpenFile(filename, &f, FS_READ); if(!f) { trap_Print(va(S_COLOR_RED "voice chat file not found: %s\n", filename)); return qfalse; } if(len >= MAX_VOICEFILESIZE) { trap_Print(va(S_COLOR_RED "voice chat file too large: %s is %i, max allowed is %i", filename, len, MAX_VOICEFILESIZE)); trap_FS_FCloseFile(f); return qfalse; } trap_FS_Read(buf, len, f); buf[len] = 0; trap_FS_FCloseFile(f); ptr = buf; p = &ptr; Com_sprintf(voiceChatList->name, sizeof(voiceChatList->name), "%s", filename); voiceChats = voiceChatList->voiceChats; for(i = 0; i < maxVoiceChats; i++) { voiceChats[i].id[0] = 0; } token = Com_ParseExt(p, qtrue); if(!token || token[0] == 0) { return qtrue; } if(!Q_stricmp(token, "female")) { voiceChatList->gender = GENDER_FEMALE; } else if(!Q_stricmp(token, "male")) { voiceChatList->gender = GENDER_MALE; } else if(!Q_stricmp(token, "neuter")) { voiceChatList->gender = GENDER_NEUTER; } else { trap_Print(va(S_COLOR_RED "expected gender not found in voice chat file: %s\n", filename)); return qfalse; } voiceChatList->numVoiceChats = 0; while(1) { token = Com_ParseExt(p, qtrue); if(!token || token[0] == 0) { return qtrue; } Com_sprintf(voiceChats[voiceChatList->numVoiceChats].id, sizeof(voiceChats[voiceChatList->numVoiceChats].id), "%s", token); token = Com_ParseExt(p, qtrue); if(Q_stricmp(token, "{")) { trap_Print(va(S_COLOR_RED "expected { found %s in voice chat file: %s\n", token, filename)); return qfalse; } voiceChats[voiceChatList->numVoiceChats].numSounds = 0; while(1) { token = Com_ParseExt(p, qtrue); if(!token || token[0] == 0) { return qtrue; } if(!Q_stricmp(token, "}")) break; sound = trap_S_RegisterSound(token); voiceChats[voiceChatList->numVoiceChats].sounds[voiceChats[voiceChatList->numVoiceChats].numSounds] = sound; token = Com_ParseExt(p, qtrue); if(!token || token[0] == 0) { return qtrue; } Com_sprintf(voiceChats[voiceChatList->numVoiceChats].chats[voiceChats[voiceChatList->numVoiceChats].numSounds], MAX_CHATSIZE, "%s", token); if(sound) voiceChats[voiceChatList->numVoiceChats].numSounds++; if(voiceChats[voiceChatList->numVoiceChats].numSounds >= MAX_VOICESOUNDS) break; } voiceChatList->numVoiceChats++; if(voiceChatList->numVoiceChats >= maxVoiceChats) return qtrue; } return qtrue; }
static qboolean R_LoadMD5Anim(skelAnimation_t * skelAnim, void *buffer, int bufferSize, const char *name) { int i, j; md5Animation_t *anim; md5Frame_t *frame; md5Channel_t *channel; char *token; int version; char *buf_p; buf_p = buffer; skelAnim->type = AT_MD5; skelAnim->md5 = anim = ri.Hunk_Alloc(sizeof(*anim), h_low); // skip MD5Version indent string Com_ParseExt(&buf_p, qfalse); // check version token = Com_ParseExt(&buf_p, qfalse); version = atoi(token); if(version != MD5_VERSION) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: '%s' has wrong version (%i should be %i)\n", name, version, MD5_VERSION); return qfalse; } // skip commandline <arguments string> token = Com_ParseExt(&buf_p, qtrue); token = Com_ParseExt(&buf_p, qtrue); // parse numFrames <number> token = Com_ParseExt(&buf_p, qtrue); if(Q_stricmp(token, "numFrames")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected 'numFrames' found '%s' in model '%s'\n", token, name); return qfalse; } token = Com_ParseExt(&buf_p, qfalse); anim->numFrames = atoi(token); // parse numJoints <number> token = Com_ParseExt(&buf_p, qtrue); if(Q_stricmp(token, "numJoints")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected 'numJoints' found '%s' in model '%s'\n", token, name); return qfalse; } token = Com_ParseExt(&buf_p, qfalse); anim->numChannels = atoi(token); // parse frameRate <number> token = Com_ParseExt(&buf_p, qtrue); if(Q_stricmp(token, "frameRate")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected 'frameRate' found '%s' in model '%s'\n", token, name); return qfalse; } token = Com_ParseExt(&buf_p, qfalse); anim->frameRate = atoi(token); // parse numAnimatedComponents <number> token = Com_ParseExt(&buf_p, qtrue); if(Q_stricmp(token, "numAnimatedComponents")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected 'numAnimatedComponents' found '%s' in model '%s'\n", token, name); return qfalse; } token = Com_ParseExt(&buf_p, qfalse); anim->numAnimatedComponents = atoi(token); // parse hierarchy { token = Com_ParseExt(&buf_p, qtrue); if(Q_stricmp(token, "hierarchy")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected 'hierarchy' found '%s' in model '%s'\n", token, name); return qfalse; } token = Com_ParseExt(&buf_p, qfalse); if(Q_stricmp(token, "{")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected '{' found '%s' in model '%s'\n", token, name); return qfalse; } // parse all the channels anim->channels = ri.Hunk_Alloc(sizeof(md5Channel_t) * anim->numChannels, h_low); for(i = 0, channel = anim->channels; i < anim->numChannels; i++, channel++) { token = Com_ParseExt(&buf_p, qtrue); Q_strncpyz(channel->name, token, sizeof(channel->name)); //ri.Printf(PRINT_ALL, "RE_RegisterAnimation: '%s' has channel '%s'\n", name, channel->name); token = Com_ParseExt(&buf_p, qfalse); channel->parentIndex = atoi(token); if(channel->parentIndex >= anim->numChannels) { ri.Error(ERR_DROP, "RE_RegisterAnimation: '%s' has channel '%s' with bad parent index %i while numBones is %i\n", name, channel->name, channel->parentIndex, anim->numChannels); } token = Com_ParseExt(&buf_p, qfalse); channel->componentsBits = atoi(token); token = Com_ParseExt(&buf_p, qfalse); channel->componentsOffset = atoi(token); } // parse } token = Com_ParseExt(&buf_p, qtrue); if(Q_stricmp(token, "}")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected '}' found '%s' in model '%s'\n", token, name); return qfalse; } // parse bounds { token = Com_ParseExt(&buf_p, qtrue); if(Q_stricmp(token, "bounds")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected 'bounds' found '%s' in model '%s'\n", token, name); return qfalse; } token = Com_ParseExt(&buf_p, qfalse); if(Q_stricmp(token, "{")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected '{' found '%s' in model '%s'\n", token, name); return qfalse; } anim->frames = ri.Hunk_Alloc(sizeof(md5Frame_t) * anim->numFrames, h_low); for(i = 0, frame = anim->frames; i < anim->numFrames; i++, frame++) { // skip ( token = Com_ParseExt(&buf_p, qtrue); if(Q_stricmp(token, "(")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected '(' found '%s' in model '%s'\n", token, name); return qfalse; } for(j = 0; j < 3; j++) { token = Com_ParseExt(&buf_p, qfalse); frame->bounds[0][j] = atof(token); } // skip ) token = Com_ParseExt(&buf_p, qfalse); if(Q_stricmp(token, ")")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected ')' found '%s' in model '%s'\n", token, name); return qfalse; } // skip ( token = Com_ParseExt(&buf_p, qfalse); if(Q_stricmp(token, "(")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected '(' found '%s' in model '%s'\n", token, name); return qfalse; } for(j = 0; j < 3; j++) { token = Com_ParseExt(&buf_p, qfalse); frame->bounds[1][j] = atof(token); } // skip ) token = Com_ParseExt(&buf_p, qfalse); if(Q_stricmp(token, ")")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected ')' found '%s' in model '%s'\n", token, name); return qfalse; } } // parse } token = Com_ParseExt(&buf_p, qtrue); if(Q_stricmp(token, "}")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected '}' found '%s' in model '%s'\n", token, name); return qfalse; } // parse baseframe { token = Com_ParseExt(&buf_p, qtrue); if(Q_stricmp(token, "baseframe")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected 'baseframe' found '%s' in model '%s'\n", token, name); return qfalse; } token = Com_ParseExt(&buf_p, qfalse); if(Q_stricmp(token, "{")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected '{' found '%s' in model '%s'\n", token, name); return qfalse; } for(i = 0, channel = anim->channels; i < anim->numChannels; i++, channel++) { // skip ( token = Com_ParseExt(&buf_p, qtrue); if(Q_stricmp(token, "(")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected '(' found '%s' in model '%s'\n", token, name); return qfalse; } for(j = 0; j < 3; j++) { token = Com_ParseExt(&buf_p, qfalse); channel->baseOrigin[j] = atof(token); } // skip ) token = Com_ParseExt(&buf_p, qfalse); if(Q_stricmp(token, ")")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected ')' found '%s' in model '%s'\n", token, name); return qfalse; } // skip ( token = Com_ParseExt(&buf_p, qfalse); if(Q_stricmp(token, "(")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected '(' found '%s' in model '%s'\n", token, name); return qfalse; } for(j = 0; j < 3; j++) { token = Com_ParseExt(&buf_p, qfalse); channel->baseQuat[j] = atof(token); } QuatCalcW(channel->baseQuat); // skip ) token = Com_ParseExt(&buf_p, qfalse); if(Q_stricmp(token, ")")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected ')' found '%s' in model '%s'\n", token, name); return qfalse; } } // parse } token = Com_ParseExt(&buf_p, qtrue); if(Q_stricmp(token, "}")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected '}' found '%s' in model '%s'\n", token, name); return qfalse; } for(i = 0, frame = anim->frames; i < anim->numFrames; i++, frame++) { // parse frame <number> { token = Com_ParseExt(&buf_p, qtrue); if(Q_stricmp(token, "frame")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected 'baseframe' found '%s' in model '%s'\n", token, name); return qfalse; } token = Com_ParseExt(&buf_p, qfalse); if(Q_stricmp(token, va("%i", i))) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected '%i' found '%s' in model '%s'\n", token, name); return qfalse; } token = Com_ParseExt(&buf_p, qfalse); if(Q_stricmp(token, "{")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected '{' found '%s' in model '%s'\n", token, name); return qfalse; } frame->components = ri.Hunk_Alloc(sizeof(float) * anim->numAnimatedComponents, h_low); for(j = 0; j < anim->numAnimatedComponents; j++) { token = Com_ParseExt(&buf_p, qtrue); frame->components[j] = atof(token); } // parse } token = Com_ParseExt(&buf_p, qtrue); if(Q_stricmp(token, "}")) { ri.Printf(PRINT_WARNING, "RE_RegisterAnimation: expected '}' found '%s' in model '%s'\n", token, name); return qfalse; } } // everything went ok return qtrue; }
AttachmentDef* BG_LoadAttachmentDef_LoadObj(const char* name) { char* fileBuffer; if (FS_ReadFile(va("weapons/attachments/%s", name), &fileBuffer) < 0) { if (!strcmp(name, "nop")) { Com_Error(0, "Could not load weapon attachment file 'nop'"); } Com_Printf(0, "Could not load weapon attachment file '%s'.\n", name); return BG_LoadAttachmentDef_LoadObj("nop"); } char* fileData = fileBuffer; std::list<AttachmentPatch> patches; Com_BeginParseSession("attachment"); char* token = Com_ParseExt(&fileData); while (fileData) { if (token[0]) { AttachmentPatch patch; if (!_stricmp(token, "multiply")) { patch.operation = APO_MULTIPLY; } else if (!_stricmp(token, "add")) { patch.operation = APO_ADD; } else if (!_stricmp(token, "set")) { patch.operation = APO_REPLACE; } else { Com_Printf(0, "Attachment error in %s: unknown operation %s\n", name, token); continue; } token = Com_ParseExt(&fileData); if (!token) { Com_Printf(0, "Attachment error in %s: premature end of file\n", name); break; } patch.fieldName = strdup(token); token = Com_ParseExt(&fileData); if (!token) { Com_Printf(0, "Attachment error in %s: premature end of file\n", name); break; } if ((token[0] == '-' || isdigit(token[0])) && (token[1] == '\0' || isdigit(token[1]) || token[1] == '.')) { if (strchr(token, '.')) { patch.value = atof(token); patch.type = APT_FLOAT; } else { patch.integer = atoi(token); patch.type = APT_INTEGER; } } else { patch.string = strdup(token); patch.type = APT_STRING; } patches.push_back(patch); } token = Com_ParseExt(&fileData); } Com_EndParseSession(); FS_FreeFile(fileBuffer); // format the file AttachmentDef* adef = new AttachmentDef; adef->name = strdup(name); adef->numPatches = patches.size(); AttachmentPatch* apatches = new AttachmentPatch[adef->numPatches]; int n = 0; for (auto i = patches.begin(); i != patches.end(); i++) { apatches[n] = *i; n++; } adef->patches = apatches; return adef; }