📄 worldfile.cc
字号:
this->macros[macro].entityname = entityname; this->macros[macro].line = line; this->macros[macro].starttoken = starttoken; this->macros[macro].endtoken = endtoken; this->macro_count++; return macro;}///////////////////////////////////////////////////////////////////////////// Lookup a macro by name// Returns -1 if there is no macro with this name.int CWorldFile::LookupMacro(const char *macroname){ int i; CMacro *macro; for (i = 0; i < this->macro_count; i++) { macro = this->macros + i; if (strcmp(macro->macroname, macroname) == 0) return i; } return -1;}///////////////////////////////////////////////////////////////////////////// Dump the macro list for debuggingvoid CWorldFile::DumpMacros(){ printf("\n## begin macros\n"); for (int i = 0; i < this->macro_count; i++) { CMacro *macro = this->macros + i; printf("## [%s][%s]", macro->macroname, macro->entityname); for (int j = macro->starttoken; j <= macro->endtoken; j++) { if (this->tokens[j].type == TokenEOL) printf("[\\n]"); else printf("[%s]", GetTokenValue(j)); } printf("\n"); } printf("## end macros\n");}///////////////////////////////////////////////////////////////////////////// Clear the entity listvoid CWorldFile::ClearEntities(){ free(this->entities); this->entities = NULL; this->entity_size = 0; this->entity_count = 0;}///////////////////////////////////////////////////////////////////////////// Add a entityint CWorldFile::AddEntity(int parent, const char *type){ if (this->entity_count >= this->entity_size) { this->entity_size += 100; this->entities = (CEntity*) realloc(this->entities, this->entity_size * sizeof(this->entities[0])); } int entity = this->entity_count; this->entities[entity].parent = parent; this->entities[entity].type = type; this->entity_count++; return entity;}///////////////////////////////////////////////////////////////////////////// Get the number of entitiesint CWorldFile::GetEntityCount(){ return this->entity_count;}///////////////////////////////////////////////////////////////////////////// Get a entity's parent entityint CWorldFile::GetEntityParent(int entity){ if (entity < 0 || entity >= this->entity_count) return -1; return this->entities[entity].parent;}///////////////////////////////////////////////////////////////////////////// Get a entity (returns the entity type value)const char *CWorldFile::GetEntityType(int entity){ if (entity < 0 || entity >= this->entity_count) return NULL; return this->entities[entity].type;}///////////////////////////////////////////////////////////////////////////// Lookup a entity number by type name// Returns -1 if there is no entity with this typeint CWorldFile::LookupEntity(const char *type){ for (int entity = 0; entity < GetEntityCount(); entity++) { if (strcmp(GetEntityType(entity), type) == 0) return entity; } return -1;}///////////////////////////////////////////////////////////////////////////// Dump the entity list for debuggingvoid CWorldFile::DumpEntities(){ printf("\n## begin entities\n"); for (int i = 0; i < this->entity_count; i++) { CEntity *entity = this->entities + i; printf("## [%d][%d]", i, entity->parent); printf("[%s]\n", entity->type); } printf("## end entities\n");}///////////////////////////////////////////////////////////////////////////// Clear the property listvoid CWorldFile::ClearProperties(){ int i; CProperty *property; for (i = 0; i < this->property_count; i++) { property = this->properties + i; free(property->values); } free(this->properties); this->properties = NULL; this->property_size = 0; this->property_count = 0;}///////////////////////////////////////////////////////////////////////////// Add an propertyint CWorldFile::AddProperty(int entity, const char *name, int line){ int i; CProperty *property; // See if this property already exists; if it does, we dont need to // add it again. for (i = 0; i < this->property_count; i++) { property = this->properties + i; if (property->entity != entity) continue; if (strcmp(property->name, name) == 0) return i; } // Expand property array if necessary. if (i >= this->property_size) { this->property_size += 100; this->properties = (CProperty*) realloc(this->properties, this->property_size * sizeof(this->properties[0])); } property = this->properties + i; memset(property, 0, sizeof(CProperty)); property->entity = entity; property->name = name; property->value_count = 0; property->values = NULL; property->line = line; property->used = false; this->property_count++; return i;}///////////////////////////////////////////////////////////////////////////// Add an property valuevoid CWorldFile::AddPropertyValue(int property, int index, int value_token){ assert(property >= 0); CProperty *pproperty = this->properties + property; // Expand the array if it's too small if (index >= pproperty->value_count) { pproperty->value_count = index + 1; pproperty->values = (int*) realloc(pproperty->values, pproperty->value_count * sizeof(int)); } // Set the relevant value pproperty->values[index] = value_token;}///////////////////////////////////////////////////////////////////////////// Get an property int CWorldFile::GetProperty(int entity, const char *name){ // Find first instance of property for (int i = 0; i < this->property_count; i++) { CProperty *property = this->properties + i; if (property->entity != entity) continue; if (strcmp(property->name, name) == 0) return i; } return -1;}///////////////////////////////////////////////////////////////////////////// Set the value of an propertyvoid CWorldFile::SetPropertyValue(int property, int index, const char *value){ //assert(property >= 0 && property < this->property_count); if(property < 0 || property >= this->property_count) return; CProperty *pproperty = this->properties + property; assert(index >= 0 && index < pproperty->value_count); // Set the relevant value SetTokenValue(pproperty->values[index], value);}///////////////////////////////////////////////////////////////////////////// Get the value of an property const char *CWorldFile::GetPropertyValue(int property, int index){ assert(property >= 0); CProperty *pproperty = this->properties + property; // changed this as the assert prevents us for asking for a value // that does not exist in the array - it should fail nicely rather // than crashing out -rtv //assert(index < pproperty->value_count); if( !(index < pproperty->value_count) ) return NULL; pproperty->used = true; return GetTokenValue(pproperty->values[index]);}///////////////////////////////////////////////////////////////////////////// Dump the property list for debuggingvoid CWorldFile::DumpProperties(){ printf("\n## begin properties\n"); for (int i = 0; i < this->property_count; i++) { CProperty *property = this->properties + i; CEntity *entity = this->entities + property->entity; printf("## [%d]", property->entity); printf("[%s]", entity->type); printf("[%s]", property->name); for (int j = 0; j < property->value_count; j++) printf("[%s]", GetTokenValue(property->values[j])); printf("\n"); } printf("## end properties\n");}///////////////////////////////////////////////////////////////////////////// Read a stringconst char *CWorldFile::ReadString(int entity, const char *name, const char *value){ int property = GetProperty(entity, name); if (property < 0) return value; return GetPropertyValue(property, 0);}///////////////////////////////////////////////////////////////////////////// Write a stringvoid CWorldFile::WriteString(int entity, const char *name, const char *value){ int property = GetProperty(entity, name); if (property < 0) return; SetPropertyValue(property, 0, value); }///////////////////////////////////////////////////////////////////////////// Read an intint CWorldFile::ReadInt(int entity, const char *name, int value){ int property = GetProperty(entity, name); if (property < 0) return value; return atoi(GetPropertyValue(property, 0));}///////////////////////////////////////////////////////////////////////////// Write an intvoid CWorldFile::WriteInt(int entity, const char *name, int value){ char default_str[64]; snprintf(default_str, sizeof(default_str), "%d", value); WriteString(entity, name, default_str);}///////////////////////////////////////////////////////////////////////////// Read a floatdouble CWorldFile::ReadFloat(int entity, const char *name, double value){ int property = GetProperty(entity, name); if (property < 0) return value; return atof(GetPropertyValue(property, 0));}///////////////////////////////////////////////////////////////////////////// Read a length (includes unit conversion)double CWorldFile::ReadLength(int entity, const char *name, double value){ int property = GetProperty(entity, name); if (property < 0) return value; return atof(GetPropertyValue(property, 0)) * this->unit_length;}///////////////////////////////////////////////////////////////////////////// Write a length (includes units conversion)void CWorldFile::WriteLength(int entity, const char *name, double value){ char default_str[64]; snprintf(default_str, sizeof(default_str), "%.3f", value / this->unit_length); WriteString(entity, name, default_str);}///////////////////////////////////////////////////////////////////////////// Read an angle (includes unit conversion)double CWorldFile::ReadAngle(int entity, const char *name, double value){ int property = GetProperty(entity, name); if (property < 0) return value; return atof(GetPropertyValue(property, 0)) * this->unit_angle;}/* REMOVE?///////////////////////////////////////////////////////////////////////////// Read a booleanbool CWorldFile::ReadBool(int entity, const char *name, bool value){//return (bool) ReadInt(entity, name, value); int property = GetProperty(entity, name); if (property < 0) return value; const char *v = GetPropertyValue(property, 0); if (strcmp(v, "true") == 0 || strcmp(v, "yes") == 0) return true; else if (strcmp(v, "false") == 0 || strcmp(v, "no") == 0) return false; CProperty *pproperty = this->properties + property; PRINT_WARN3("worldfile %s:%d : '%s' is not a valid boolean value; assuming 'false'", this->filename, pproperty->line, v); return false;}*////////////////////////////////////////////////////////////////////////////// Read a color (included text -> RGB conversion).// We look up the color in one of the common color databases.uint32_t CWorldFile::ReadColor(int entity, const char *name, uint32_t value){ int property; const char *color; property = GetProperty(entity, name); if (property < 0) return value; color = GetPropertyValue(property, 0); // TODO: Hmmm, should do something with the default color here. return ::LookupColor(color);}///////////////////////////////////////////////////////////////////////////// Read a file name// Always returns an absolute path.// If the filename is entered as a relative path, we prepend// the world files path to it.// Known bug: will leak memory everytime it is called (but its not called often,// so I cant be bothered fixing it).const char *CWorldFile::ReadFilename(int entity, const char *name, const char *value){ int property = GetProperty(entity, name); if (property < 0) return value; const char *filename = GetPropertyValue(property, 0); if( filename[0] == '/' || filename[0] == '~' ) return filename; else if (this->filename[0] == '/' || this->filename[0] == '~') { // Note that dirname() modifies the contents, so // we need to make a copy of the filename. // There's no bounds-checking, but what the heck. char *tmp = strdup(this->filename); char *fullpath = (char*) malloc(PATH_MAX); memset(fullpath, 0, PATH_MAX); strcat( fullpath, dirname(tmp)); strcat( fullpath, "/" ); strcat( fullpath, filename ); assert(strlen(fullpath) + 1 < PATH_MAX); free(tmp); return fullpath; } else { // Prepend the path // Note that dirname() modifies the contents, so // we need to make a copy of the filename. // There's no bounds-checking, but what the heck. char *tmp = strdup(this->filename); char *fullpath = (char*) malloc(PATH_MAX); getcwd(fullpath, PATH_MAX); strcat( fullpath, "/" ); strcat( fullpath, dirname(tmp)); strcat( fullpath, "/" ); strcat( fullpath, filename ); assert(strlen(fullpath) + 1 < PATH_MAX); free(tmp); return fullpath; }}///////////////////////////////////////////////////////////////////////////// Read a string from a tupleconst char *CWorldFile::ReadTupleString(int entity, const char *name, int index, const char *value){ int property = GetProperty(entity, name); if (property < 0) return value; return GetPropertyValue(property, index);}///////////////////////////////////////////////////////////////////////////// Write a string to a tuplevoid CWorldFile::WriteTupleString(int entity, const char *name, int index, const char *value){ int property = GetProperty(entity, name); /* TODO if (property < 0) property = InsertProperty(entity, name); */ SetPropertyValue(property, index, value); }///////////////////////////////////////////////////////////////////////////// Read a float from a tupledouble CWorldFile::ReadTupleFloat(int entity, const char *name, int index, double value){ int property = GetProperty(entity, name); if (property < 0) return value; return atof(GetPropertyValue(property, index));}///////////////////////////////////////////////////////////////////////////// Write a float to a tuplevoid CWorldFile::WriteTupleFloat(int entity, const char *name, int index, double value){ char default_str[64]; snprintf(default_str, sizeof(default_str), "%.3f", value); WriteTupleString(entity, name, index, default_str);}///////////////////////////////////////////////////////////////////////////// Read a length from a tuple (includes unit conversion)double CWorldFile::ReadTupleLength(int entity, const char *name, int index, double value){ int property = GetProperty(entity, name); if (property < 0) return value; return atof(GetPropertyValue(property, index)) * this->unit_length;}///////////////////////////////////////////////////////////////////////////// Write a length to a tuple (includes unit conversion)void CWorldFile::WriteTupleLength(int entity, const char *name, int index, double value){ char default_str[64]; snprintf(default_str, sizeof(default_str), "%.3f", value / this->unit_length); WriteTupleString(entity, name, index, default_str);}///////////////////////////////////////////////////////////////////////////// Read an angle from a tuple (includes unit conversion)double CWorldFile::ReadTupleAngle(int entity, const char *name, int index, double value){ int property = GetProperty(entity, name); if (property < 0) return value; return atof(GetPropertyValue(property, index)) * this->unit_angle;}///////////////////////////////////////////////////////////////////////////// Write an angle to a tuple (includes unit conversion)void CWorldFile::WriteTupleAngle(int entity, const char *name, int index, double value){ char default_str[64]; snprintf(default_str, sizeof(default_str), "%.3f", value / this->unit_angle); WriteTupleString(entity, name, index, default_str);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -