void ReadIndexXML(xmlNode * a_node) { xmlNode *cur_node=NULL; for (cur_node = a_node; cur_node; cur_node = cur_node->next) { if (cur_node->type==XML_ELEMENT_NODE){ if(!xmlStrcasecmp(cur_node->name,(xmlChar*)"Category")){ xmlDocPtr doc; char tmp[100]; Category[num_category].Name=NULL; MY_XMLSTRCPY(&Category[num_category].Name, (char*)cur_node->children->content); num_category++; //we load the category now safe_snprintf(tmp,sizeof(tmp),"languages/%s/Encyclopedia/%s.xml",lang,cur_node->children->content); doc=xmlReadFile(tmp, NULL, 0); if (doc==NULL) { safe_snprintf(tmp,sizeof(tmp),"languages/en/Encyclopedia/%s.xml",cur_node->children->content); doc=xmlReadFile(tmp, NULL, 0); } if(doc==NULL) { return; } ReadCategoryXML(xmlDocGetRootElement(doc)); xmlFreeDoc(doc); } } ReadIndexXML(cur_node->children); } }
void parse_knowledge_item(xmlNode *in) { xmlNode * cur; int id = -1; char * strID=NULL; char * string=NULL; for(cur=in;cur;cur=cur->next){ if(cur->type == XML_ELEMENT_NODE){ if(!xmlStrcasecmp(cur->name,(xmlChar*)"Knowledge")){ if ((strID=(char*)xmlGetProp(cur,(xmlChar*)"ID"))==NULL){ LOG_ERROR("Knowledge Item does not contain an ID property."); } else { id = atoi(strID); if(cur->children && cur->children->content && MY_XMLSTRCPY(&string, (char*)cur->children->content)!=-1){ if (read_book(string, 2, id + KNOWLEDGE_BOOK_OFFSET) != NULL) { knowledge_list[id].has_book = 1; } } else { #ifndef OSX LOG_ERROR("An error occured when parsing the content of the <%s>-tag on line %d - Check it for letters that cannot be translated into iso8859-1\n", cur->name, cur->line); #else LOG_ERROR("An error occured when parsing the content of the <%s>-tag - Check it for letters that cannot be translated into iso8859-1\n", cur->name); #endif } xmlFree(strID); free(string); string = NULL; } } } } return; }
// Construct a new icon object from the xml information // Virtual_Icon * Container::icon_xml_factory(const xmlNodePtr cur) { std::string the_type, help_name, help_text, param_name; const char *help_str; int image_id = -1, alt_image_id = -1; get_xml_field_string(the_type, "type", cur); get_xml_field_int(&image_id, "image_id", cur); get_xml_field_int(&alt_image_id, "alt_image_id", cur); get_xml_field_string(help_name, "help_name", cur); get_xml_field_string(help_text, "help_text", cur); get_xml_field_string(param_name, "param_name", cur); std::vector<CommandQueue::Line> *menu_lines_ptr = 0; std::vector<CommandQueue::Line> menu_lines; { char *text = (char*)(cur->children ? cur->children->content : NULL); char *parsed = 0; MY_XMLSTRCPY(&parsed, text); if (parsed) { std::istringstream lines(parsed); std::string line; while (std::getline(lines, line)) if (!line.empty()) menu_lines.push_back(CommandQueue::Line(line)); free(parsed); if (!menu_lines.empty()) menu_lines_ptr = &menu_lines; } } if (the_type.empty() || (image_id<0) || (alt_image_id<0) || (help_name.empty() && help_text.empty()) || param_name.empty()) { LOG_ERROR("icon window factory: xml field error type=[%s] image_id=[%d] alt_image_id=[%d] help_name=[%s] help_text=[%s] param_name=[%s]\n", the_type.c_str(), image_id, alt_image_id, help_name.c_str(), help_text.c_str(), param_name.c_str() ); return 0; } if (!help_text.empty()) help_str = help_text.c_str(); else help_str = get_named_string("tooltips", help_name.c_str()); if (the_type == "keypress") return new Keypress_Icon(image_id, alt_image_id, help_str, param_name.c_str(), menu_lines_ptr); else if (the_type == "window") return new Window_Icon(image_id, alt_image_id, help_str, param_name.c_str(), menu_lines_ptr); else if (the_type == "action_mode") return new Actionmode_Icon(image_id, alt_image_id, help_str, param_name.c_str(), menu_lines_ptr); else if (the_type == "#command") return new Command_Icon(image_id, alt_image_id, help_str, param_name.c_str(), menu_lines_ptr); return 0; }
void add_xml_str_to_page(xmlNode * cur, int type, book * b, page *p) { char * string=NULL; if(cur->children && cur->children->content && MY_XMLSTRCPY(&string, (char*)cur->children->content)!=-1){ add_str_to_page(string, type, b, p); } else { #ifndef OSX LOG_ERROR("An error occured when parsing the content of the <%s>-tag on line %d - Check it for letters that cannot be translated into iso8859-1\n", cur->name, cur->line); #else LOG_ERROR("An error occured when parsing the content of the <%s>-tag - Check it for letters that cannot be translated into iso8859-1\n", cur->name); #endif } free(string); }
// helper function for reading xml strings, perhaps make generally available? // bool get_xml_field_string(std::string &ret_string, const char *field_name, const xmlNodePtr cur) { char *tmp = (char*)xmlGetProp(cur, (xmlChar *)field_name); if (!tmp) return false; char *parsed = 0; MY_XMLSTRCPY(&parsed, tmp); xmlFree(tmp); if (!parsed) return false; ret_string = parsed; free(parsed); return true; }
void ParsePage(xmlAttr *a_node) { xmlAttr *cur_attr=NULL; for (cur_attr = a_node; cur_attr; cur_attr = cur_attr->next) { if (cur_attr->type==XML_ATTRIBUTE_NODE){ //name="" if(!xmlStrcasecmp(cur_attr->name,(xmlChar*)"name")){ Page[numpage].Name=NULL; MY_XMLSTRCPY(&Page[numpage].Name, (char*)cur_attr->children->content); } } } }
// A helper function for reading xml string properties // void Achievements_System::get_string_props(const xmlNodePtr cur, std::string * strings_p[], const char* strings[], size_t count) { for (size_t i=0; i<count; ++i) { char *tmp = (char*)xmlGetProp(cur, (xmlChar *)strings[i]); char *parsed = 0; if (!tmp) continue; MY_XMLSTRCPY(&parsed, tmp); if (parsed) { *(strings_p[i]) = parsed; free(parsed); } xmlFree(tmp); } }
void add_xml_image_to_page(xmlNode * cur, book * b, page *p) { char *image_path; int x,y,w,h; float u_start,v_start,u_end,v_end; _image *img; char *text=NULL; x=xmlGetInt(cur,(xmlChar*)"x"); y=xmlGetInt(cur,(xmlChar*)"y"); w=xmlGetInt(cur,(xmlChar*)"w"); h=xmlGetInt(cur,(xmlChar*)"h"); u_start=xmlGetFloat(cur,(xmlChar*)"u_start"); u_end=xmlGetFloat(cur,(xmlChar*)"u_end"); if(!u_end) u_end=1; v_start=xmlGetFloat(cur,(xmlChar*)"v_start"); if(!v_start) v_start=1; v_end=xmlGetFloat(cur,(xmlChar*)"v_end"); image_path=(char*)xmlGetProp(cur,(xmlChar*)"src"); if(!image_path) return; img=create_image(image_path, x, y, w, h, u_start, v_start, u_end, v_end); if(cur->children && cur->children->content){ MY_XMLSTRCPY(&text, (char*)cur->children->content); } if(add_image_to_page(text, img, b, p)==NULL) free(img); xmlFree(image_path); if(text) free(text); }
// Read the achievements xml file and create all the achievement objects, // the global settings and the textures. // Achievements_System::Achievements_System(void) : size(32), display(32), y_win_offset(10), per_row(5), min_rows(1), max_rows(12), border(2), prev("[<]"), next("[>]"), close("[close]"), too_many("Too many achievement windows open already"), xml_fail("Failed to load achievement data"), texture_fail("Failed to load achievement texture"), close_help("Close or +ctrl close all"), no_next_help("No more pages"), no_prev_help("No previous page"), next_help("Next page"), prev_help("Previous page"), max_title_len(0), max_detail_lines(2), max_windows(15), win_pos_x(100), win_pos_y(50), control_used(false), current_scale(1.0) { xmlDocPtr doc; xmlNodePtr cur; char const *error_prefix = "Reading xml: "; std::ostringstream langpath; langpath << "languages/" << lang << "/achievements.xml"; if ((doc = xmlReadFile(langpath.str().c_str(), NULL, 0)) == NULL) { const char *path = "languages/en/achievements.xml"; if ((doc = xmlReadFile(path, NULL, 0)) == NULL) { LOG_ERROR("%sCan't open file [%s]\n", error_prefix, path ); return; } } if ((cur = xmlDocGetRootElement (doc)) == NULL) { LOG_ERROR("%sEmpty xml document\n", error_prefix ); xmlFreeDoc(doc); return; } if (xmlStrcasecmp (cur->name, (const xmlChar *) "achievements_system")) { LOG_ERROR("%sNot achievements system.\n", error_prefix ); xmlFreeDoc(doc); return; } for (cur = cur->xmlChildrenNode; cur; cur = cur->next) { if (!xmlStrcasecmp(cur->name, (const xmlChar *)"achievement")) { char *text = (char*)(cur->children ? cur->children->content : NULL); char *title = (char*)xmlGetProp(cur, (xmlChar *)"title"); int achievement_id = -1, image_id = -1; int *props_p[2] = { &achievement_id, &image_id }; const char *props_s[2] = { "achievement_id", "image_id" }; get_int_props(cur, props_p, props_s, 2); if ((text == NULL) || (achievement_id < 0) || (image_id < 0) || (title == NULL)) { LOG_WARNING("%sInvalid achievements node\n", error_prefix ); continue; } char *proc_title = 0; char *proc_text = 0; MY_XMLSTRCPY(&proc_title, title); MY_XMLSTRCPY(&proc_text, text); xmlFree(title); if ((achievement_id < 0) || (achievement_id >= MAX_ACHIEVEMENTS)) LOG_ERROR("%sInvalid achievement id=%lu\n", error_prefix, achievement_id ); else { achievements.resize(achievement_id+1, 0); if (achievements[achievement_id]) LOG_ERROR("%sDuplicate achievement id=%lu\n", error_prefix, achievement_id ); else { achievements[achievement_id] = new Achievement(achievement_id, image_id, proc_title, proc_text); if (achievements[achievement_id]->get_title().size() > max_title_len) max_title_len = achievements[achievement_id]->get_title().size(); } } if (proc_title) free(proc_title); if (proc_text) free(proc_text); } else if (!xmlStrcasecmp(cur->name, (const xmlChar *)"image_settings")) { int *props_p[2] = { &size, &display }; const char * props_s[2] = { "size", "display" }; get_int_props(cur, props_p, props_s, 2); } else if (!xmlStrcasecmp(cur->name, (const xmlChar *)"window_settings")) { int *props_p[4] = { &per_row, &min_rows, &max_rows, &border }; const char *props_s[4] = { "per_row", "min_rows", "max_rows", "border" }; get_int_props(cur, props_p, props_s, 4); std::string * ctrl_p[3] = { &prev, &next, &close }; const char* ctrl_s[3] = { "prev", "next", "close" }; get_string_props(cur, ctrl_p, ctrl_s, 3); } else if (!xmlStrcasecmp(cur->name, (const xmlChar *)"strings")) { const size_t count = 8; std::string * strings_p[count] = { &too_many, &xml_fail, &texture_fail, &close_help, &no_next_help, &no_prev_help, &next_help, &prev_help }; const char* strings_s[count] = { "too_many", "xml_fail", "texture_fail", "close_help", "no_next_help", "no_prev_help", "next_help", "prev_help" }; get_string_props(cur, strings_p, strings_s, count); } else if (!xmlStrcasecmp(cur->name, (const xmlChar *)"texture")) { char *path = (char*)(cur->children ? cur->children->content : NULL); char buffer[1024]; if (check_image_name(path, sizeof(buffer), buffer) == 1) { textures.push_back(load_texture_cached(buffer, tt_gui)); } } } xmlFreeDoc(doc); }
// Load colours from the XML file. // void Colour_Container::load_xml(void) { char const *error_prefix = __PRETTY_FUNCTION__; std::string file_name = "named_colours.xml"; if (!el_file_exists_anywhere(file_name.c_str())) return; xmlDocPtr doc; xmlNodePtr cur; if ((doc = xmlReadFile(file_name.c_str(), NULL, 0)) == NULL) { LOG_ERROR("%s : Can't open file [%s]\n", error_prefix, file_name.c_str() ); return; } if ((cur = xmlDocGetRootElement (doc)) == NULL) { LOG_ERROR("%s : Empty xml document\n", error_prefix ); xmlFreeDoc(doc); return; } if (xmlStrcasecmp (cur->name, (const xmlChar *) "named_colours")) { LOG_ERROR("%s : no named_colours element\n", error_prefix ); xmlFreeDoc(doc); return; } for (cur = cur->xmlChildrenNode; cur; cur = cur->next) { if (!xmlStrcasecmp(cur->name, (const xmlChar *)"colour")) { const int NUM_STR = 5; char *read_strings[NUM_STR] = {NULL, NULL, NULL, NULL, NULL}; const char *names[NUM_STR] = {"name", "r", "g", "b", "a"}; for (int i=0; i<NUM_STR; i++) { char *tmp = (char*)xmlGetProp(cur, (xmlChar *)names[i]); if (!tmp) continue; MY_XMLSTRCPY(&read_strings[i], tmp); xmlFree(tmp); } if (read_strings[0]) { GLfloat col_vals[NUM_STR-1] = { -1.0f, -1.0f, -1.0f, 1.0f}; for (int i=1; i<NUM_STR; i++) { if (read_strings[i]) { GLfloat tmpcol = -1.0f; std::stringstream ss(read_strings[i]); if( (ss >> tmpcol).fail() ) continue; col_vals[i-1] = tmpcol; } } bool valid = true; for (int i=0; i<NUM_STR-1; i++) if (col_vals[i] < 0) valid = false; if (valid && (NUM_STR == 5)) add(read_strings[0], Colour_Tuple(col_vals[0],col_vals[1],col_vals[2],col_vals[3])); } for (int i=0; i<NUM_STR; i++) if (read_strings[i]) free(read_strings[i]); } } xmlFreeDoc(doc); }
void ReadCategoryXML(xmlNode * a_node) { xmlNode *cur_node=NULL; for (cur_node = a_node; cur_node; cur_node = cur_node->next) { if (cur_node->type==XML_ELEMENT_NODE){ //<Page> if(!xmlStrcasecmp(cur_node->name,(xmlChar*)"Page")){ if(numpage < MAX_ENC_PAGES-1){ numpage++; numtext=0; numimage=0; x=2; y=2; ParsePage(cur_node->properties); } else { LOG_ERROR("Too many Enc Pages, limit of %d hit", MAX_ENC_PAGES); return; } } //<Size> if(!xmlStrcasecmp(cur_node->name,(xmlChar*)"Size")) { if (cur_node->children != NULL) size = (xmlStrcasecmp ((xmlChar*)"Big", cur_node->children->content) == 0) ? 1 : 0; } //<Color> if(!xmlStrcasecmp(cur_node->name,(xmlChar*)"Color")){ ParseColor(cur_node->properties); if (cur_node->children != NULL) GetColorFromName (cur_node->children->content); } //<Text> if(!xmlStrcasecmp(cur_node->name,(xmlChar*)"Text")){ _Text *T=(_Text*)malloc(sizeof(_Text)); _Text *t=&Page[numpage].T; T->Next=NULL; ParseText(cur_node->properties); T->x=x; T->y=y; T->size=size; T->r=r; T->g=g; T->b=b; T->text=NULL; T->ref=NULL; lastextlen = 0; if (cur_node->children != NULL) { MY_XMLSTRCPY (&T->text, (char*)cur_node->children->content); lastextlen = strlen (T->text) * ((T->size) ? 11 : 8); x += lastextlen; } while (t->Next != NULL) t = t->Next; t->Next = T; } //<nl> if(!xmlStrcasecmp(cur_node->name,(xmlChar*)"nl")){ x=2; y+=(size)?18:15; } //<nlkx> if(!xmlStrcasecmp(cur_node->name,(xmlChar*)"nlkx")){ y+=(size)?18:15; x-=lastextlen; } //<Image> if(!xmlStrcasecmp(cur_node->name,(xmlChar*)"image")){ _Image *I=(_Image*)malloc(sizeof(_Image)); _Image *i=&Page[numpage].I; xposupdate=1; yposupdate=1; ParseImage(cur_node->properties); I->mouseover=mouseover; mouseover=0; while(i->Next!=NULL)i=i->Next; I->id=id; I->Next=NULL; if(!I->mouseover){ I->x=x; I->y=y; I->xend=x+xend; I->yend=y+yend; if(xposupdate) x+=xend; if(yposupdate) y+=yend-((size)?18:15); }else{ I->x=i->x; I->y=i->y; I->xend=i->xend; I->yend=i->yend; } I->u=u; I->v=v; I->uend=uend; I->vend=vend; i->Next=I; numimage++; } //<sImage> if(!xmlStrcasecmp(cur_node->name,(xmlChar*)"simage")){ _Image *I=(_Image*)malloc(sizeof(_Image)); _Image *i=&Page[numpage].I; int picsperrow,xtile,ytile; float ftsize; xposupdate=1; yposupdate=1; ParseSimage(cur_node->properties); picsperrow=isize/tsize; xtile=tid%picsperrow; ytile=tid/picsperrow; ftsize=(float)tsize/isize; #ifdef NEW_TEXTURES u = ftsize * xtile; v = ftsize * ytile; uend = u + ftsize; vend = v + ftsize; #else /* NEW_TEXTURES */ u=ftsize*xtile; v=-ftsize*ytile; uend=u+ftsize; vend=v-ftsize; #endif /* NEW_TEXTURES */ I->mouseover=mouseover; mouseover=0; while(i->Next!=NULL)i=i->Next; I->id=id; I->Next=NULL; if(!I->mouseover){ I->x=x; I->y=y; I->xend=x+(tsize*((float)ssize/100)); I->yend=y+(tsize*((float)ssize/100)); if(xposupdate) x+=(tsize*((float)ssize/100)); if(yposupdate) y+=(tsize*((float)ssize/100))-((size)?18:15); }else{ I->x=i->x; I->y=i->y; I->xend=i->xend; I->yend=i->yend; } I->u=u; I->v=v; I->uend=uend; I->vend=vend; i->Next=I; numimage++; } //<ddsImage> if(!xmlStrcasecmp(cur_node->name,(xmlChar*)"ddsimage")){ _Image *I=(_Image*)malloc(sizeof(_Image)); _Image *i=&Page[numpage].I; int picsperrow,xtile,ytile; float ftsize; xposupdate=1; yposupdate=1; ParseSimage(cur_node->properties); if(size==99) size=99; picsperrow=isize/tsize; xtile=tid%picsperrow; ytile=tid/picsperrow; ftsize=(float)tsize/isize; u=ftsize*xtile; v=ftsize*ytile; uend=u+ftsize; vend=v+ftsize; I->mouseover=mouseover; mouseover=0; while(i->Next!=NULL)i=i->Next; I->id=id; I->Next=NULL; if(!I->mouseover){ I->x=x; I->y=y; I->xend=x+(tsize*((float)ssize/100)); I->yend=y+(tsize*((float)ssize/100)); if(xposupdate) x+=(tsize*((float)ssize/100)); if(yposupdate) y+=(tsize*((float)ssize/100))-((size)?18:15); }else{ I->x=i->x; I->y=i->y; I->xend=i->xend; I->yend=i->yend; } I->u=u; I->v=v; I->uend=uend; I->vend=vend; i->Next=I; numimage++; } //<Pos> if(!xmlStrcasecmp(cur_node->name,(xmlChar*)"pos")){ ParsePos(cur_node->properties); } //<link> if(!xmlStrcasecmp(cur_node->name,(xmlChar*)"link")){ _Text *T=(_Text*)malloc(sizeof(_Text)); _Text *t=&Page[numpage].T; ParseLink(cur_node->properties); T->Next=NULL; T->x=x; T->y=y; T->size=size; T->r=r; T->g=g; T->b=b; T->text=NULL; T->ref=NULL; MY_XMLSTRCPY(&T->text, s); MY_XMLSTRCPY(&T->ref, ss); while(t->Next!=NULL)t=t->Next; t->Next=T; x+=strlen(T->text)*((T->size)?11:8); lastextlen=strlen(T->text)*((T->size)?11:8); #ifdef ENCYCL_NAVIGATION save_raw_page_link(T->ref, T->text, numpage); #endif } // See if this is the new maximum length. if(Page[numpage].max_y < y) { Page[numpage].max_y = y; } } ReadCategoryXML(cur_node->children); } }