diff --git a/src/ship.c b/src/ship.c index df46f33..9b2029d 100644 --- a/src/ship.c +++ b/src/ship.c @@ -8,25 +8,27 @@ #include "toolkit.h" #include "ship.h" -#define XML_ID "Ships" /* XML section identifier. */ -#define XML_SHIP "ship" +#define XML_ID "Ships" /* XML section identifier. */ +#define XML_SHIP "ship" -#define SHIP_DATA "../dat/ship.xml" -#define SHIP_GFX "../gfx/ship/" -#define SHIP_EXT ".png" -#define SHIP_TARGET "_target" -#define SHIP_COMM "_comm" +#define SHIP_DATA "../dat/ship.xml" +#define SHIP_GFX "../gfx/ship/" +#define SHIP_EXT ".png" +#define SHIP_TARGET "_target" +#define SHIP_COMM "_comm" -#define VIEW_WIDTH 300 -#define VIEW_HEIGHT 300 +#define VIEW_WIDTH 300 +#define VIEW_HEIGHT 300 -#define BUTTON_WIDTH 80 +#define BUTTON_WIDTH 80 #define BUTTON_HEIGHT 30 +#define CHUNK_SIZE 32 + static Ship* ship_stack = NULL; static int ship_nstack = 0; -static Ship* ship_parse(xmlNodePtr parent); +static int ship_parse(Ship* tmp, xmlNodePtr parent); /* Get a ship based on it's name. */ Ship* ship_get(const char* name) { @@ -221,17 +223,22 @@ int ship_basePrice(Ship* s) { return price; } -static Ship* ship_parse(xmlNodePtr parent) { +static int ship_parse(Ship* tmp, xmlNodePtr parent) { xmlNodePtr cur, node; - Ship* tmp = CALLOC_L(Ship); ShipOutfit* otmp, *ocur; char str[PATH_MAX] = "\0"; char* stmp; - xmlr_attr(parent, "name", tmp->name); - if(tmp->name == NULL) WARN("Ship in "SHIP_DATA" has invalid or no name"); + /* Clear memory. */ + memset(tmp, 0, sizeof(Ship)); + /* Get name. */ + xmlr_attr(parent, "name", tmp->name); + if(tmp->name == NULL) + WARN("Ship in "SHIP_DATA" has invalid or no name."); + + /* Load data. */ node = parent->xmlChildrenNode; do { @@ -365,18 +372,17 @@ static Ship* ship_parse(xmlNodePtr parent) { MELEMENT(tmp->cap_weapon==0, "cap_weapon"); #undef MELEMENT - return tmp; + return 0; } int ships_load(void) { + int mem; uint32_t bufsize; char* buf = pack_readfile(DATA, SHIP_DATA, &bufsize); xmlNodePtr node; xmlDocPtr doc = xmlParseMemory(buf, bufsize); - Ship* tmp = NULL; - node = doc->xmlChildrenNode; /* Ships node. */ if(strcmp((char*)node->name, XML_ID)) { ERR("Malformed "SHIP_DATA" file: missing root element '"XML_ID"'"); @@ -389,14 +395,24 @@ int ships_load(void) { return -1; } + mem = 0; do { - if(node->type == XML_NODE_START && strcmp((char*)node->name, XML_SHIP)==0) { - tmp = ship_parse(node); - ship_stack = realloc(ship_stack, sizeof(Ship)*(++ship_nstack)); - memcpy(ship_stack+ship_nstack-1, tmp, sizeof(Ship)); - free(tmp); + if(xml_isNode(node, XML_SHIP)) { + ship_nstack++; + + /* Check to see if we need to grow the stack. */ + if(ship_nstack > mem) { + mem += CHUNK_SIZE; + ship_stack = realloc(ship_stack, sizeof(Ship)*mem); + } + + /* Load the ship. */ + ship_parse(&ship_stack[ship_nstack-1], node); } - } while((node = node->next)); + } while(xml_nextNode(node)); + + /* Shrink to minimum size - Won't change later. */ + ship_stack = realloc(ship_stack, sizeof(Ship) * ship_nstack); xmlFreeDoc(doc); free(buf);