154 lines
4.6 KiB
C
154 lines
4.6 KiB
C
#include <string.h>
|
|
#include "libxml/xmlreader.h"
|
|
|
|
#include "log.h"
|
|
#include "ship.h"
|
|
|
|
#define MAX_PATH_NAME 20 // Maximum size of the path.
|
|
|
|
#define XML_NODE_START 1
|
|
#define XML_NODE_TEXT 3
|
|
#define XML_NODE_CLOSE 15
|
|
#define XML_NODE_CDATA 4
|
|
|
|
#define XML_ID "Ships" // XML section identifier.
|
|
#define XML_SHIP "ship"
|
|
|
|
#define SHIP_DATA "../dat/ship.xml"
|
|
#define SHIP_GFX "../gfx/ship/"
|
|
|
|
static Ship* ship_stack = NULL;
|
|
static int ships;
|
|
|
|
// Get a ship based on it's name.
|
|
Ship* get_ship(const char* name) {
|
|
Ship* tmp = ship_stack;
|
|
int i;
|
|
for(i = 0; i < ships; i++)
|
|
if(strcmp((tmp+i)->name, name)==0) break;
|
|
|
|
return tmp+1;
|
|
}
|
|
|
|
Ship* ship_parse(xmlNodePtr node) {
|
|
xmlNodePtr cur;
|
|
Ship* tmp = CALLOC_L(Ship);
|
|
|
|
char str[MAX_PATH_NAME] = "\0";
|
|
|
|
tmp->name = (char*)xmlGetProp(node, (xmlChar*)"name");
|
|
|
|
node = node->xmlChildrenNode;
|
|
|
|
while((node = node->next)) {
|
|
if(strcmp((char*)node->name, "GFX")==0) {
|
|
cur = node->children;
|
|
if(strcmp((char*)cur->name, "text")==0) {
|
|
snprintf(str, strlen((char*)cur->content)+sizeof(SHIP_GFX),
|
|
SHIP_GFX"%s", (char*)cur->content);
|
|
tmp->gfx_ship = gl_newSprite(str, 6, 6);
|
|
}
|
|
}
|
|
else if(strcmp((char*)node->name, "class")==0) {
|
|
cur = node->children;
|
|
if(strcmp((char*)cur->name, "text")==0)
|
|
tmp->class = atoi((char*)cur->content);
|
|
}
|
|
else if(strcmp((char*)node->name, "movement")==0) {
|
|
cur = node->children;
|
|
while((cur = cur->next)) {
|
|
if(strcmp((char*)cur->name, "thrust")==0)
|
|
tmp->thrust = atoi((char*)cur->children->content);
|
|
else if(strcmp((char*)cur->name, "turn")==0)
|
|
tmp->turn = atoi((char*)cur->children->content);
|
|
else if(strcmp((char*)cur->name, "speed")==0)
|
|
tmp->speed = atoi((char*)cur->children->content);
|
|
}
|
|
}
|
|
else if(strcmp((char*)node->name, "health")==0) {
|
|
cur = node->children;
|
|
while((cur = cur->next)) {
|
|
if(strcmp((char*)cur->name, "armor")==0)
|
|
tmp->armor = (FP)atoi((char*)cur->children->content);
|
|
else if(strcmp((char*)cur->name, "shield")==0)
|
|
tmp->shield = (FP)atoi((char*)cur->children->content);
|
|
else if(strcmp((char*)cur->name, "energy")==0)
|
|
tmp->energy = (FP)atoi((char*)cur->children->content);
|
|
else if(strcmp((char*)cur->name, "armor_regen")==0)
|
|
tmp->armor_regen = (FP)(atoi((char*)cur->children->content))/60.0;
|
|
else if(strcmp((char*)cur->name, "shield_regen")==0)
|
|
tmp->shield_regen = (FP)(atoi((char*)cur->children->content))/60.0;
|
|
else if(strcmp((char*)cur->name, "energy_regen")==0)
|
|
tmp->energy_regen = (FP)(atoi((char*)cur->children->content))/60.0;
|
|
}
|
|
}
|
|
else if(strcmp((char*)node->name, "characteristics")==0) {
|
|
cur = node->children;
|
|
while((cur = cur->next)) {
|
|
if(strcmp((char*)cur->name, "crew")==0)
|
|
tmp->crew = atoi((char*)cur->children->content);
|
|
else if(strcmp((char*)cur->name, "mass")==0)
|
|
tmp->mass = (FP)atoi((char*)cur->children->content);
|
|
else if(strcmp((char*)cur->name, "cap_weapon")==0)
|
|
tmp->cap_weapon = atoi((char*)cur->children->content);
|
|
else if(strcmp((char*)cur->name, "cap_cargo")==0)
|
|
tmp->cap_cargo = atoi((char*)cur->children->content);
|
|
}
|
|
}
|
|
}
|
|
tmp->thrust *= tmp->mass; // Helps keep number sane.
|
|
|
|
DEBUG("Loaded ship '%s'", tmp->name);
|
|
return tmp;
|
|
}
|
|
|
|
int ships_load(void) {
|
|
xmlTextReaderPtr reader;
|
|
xmlNodePtr node;
|
|
Ship* tmp = NULL;
|
|
|
|
if((reader = xmlNewTextReaderFilename(SHIP_DATA)) == NULL) {
|
|
WARN("XML error reading " SHIP_DATA);
|
|
return -1;
|
|
}
|
|
|
|
// Get to the start of the "ships" section.
|
|
while(xmlTextReaderRead(reader)==1) {
|
|
if(xmlTextReaderNodeType(reader)==XML_NODE_START &&
|
|
strcmp((char*)xmlTextReaderConstName(reader), XML_ID) == 0) break;
|
|
}
|
|
|
|
xmlTextReaderRead(reader); // At ships node.
|
|
|
|
while(xmlTextReaderRead(reader)==1) {
|
|
if(xmlTextReaderNodeType(reader)==XML_NODE_START &&
|
|
strcmp((char*)xmlTextReaderConstName(reader), XML_SHIP)==0) {
|
|
|
|
node = xmlTextReaderCurrentNode(reader); // Node to process.
|
|
if(ship_stack == NULL) {
|
|
ship_stack = tmp = ship_parse(node);
|
|
ships = 1;
|
|
} else {
|
|
tmp = ship_parse(node);
|
|
ship_stack = realloc(ship_stack, sizeof(Ship)*(++ships));
|
|
memcpy(ship_stack+ships-1, tmp, sizeof(Ship));
|
|
free(tmp);
|
|
}
|
|
}
|
|
}
|
|
xmlFreeTextReader(reader);
|
|
return 0;
|
|
}
|
|
|
|
void ships_free(void) {
|
|
int i;
|
|
for(i = 0; i < ships; i++) {
|
|
if((ship_stack+i)->name)
|
|
free((ship_stack+i)->name);
|
|
gl_freeTexture((ship_stack+i)->gfx_ship);
|
|
}
|
|
free(ship_stack);
|
|
ship_stack = NULL;
|
|
}
|
|
|