[Change] Major rewrite of space.c. Let's pray we don't have a ton of bugs.
This commit is contained in:
parent
da4b261de7
commit
5a42e63e4a
@ -166,12 +166,12 @@ int input_getKeybind(char* keybind, KeybindType* type, int* reverse) {
|
|||||||
* @param value The value of the keypress (defined above).
|
* @param value The value of the keypress (defined above).
|
||||||
* @param abs Whether or not it's an absolute value (for the joystick).
|
* @param abs Whether or not it's an absolute value (for the joystick).
|
||||||
*/
|
*/
|
||||||
#define KEY(s) (strcmp(input_keybinds[keynum]->name, s)==0)
|
#define KEY(s) (strcmp(input_keybinds[keynum]->name, s)==0) /**< Shortcut for ease. */
|
||||||
#define INGAME() (!toolkit)
|
#define INGAME() (!toolkit) /**< Make sure player is in game. */
|
||||||
#define NOHYP() \
|
#define NOHYP() \
|
||||||
(player && !pilot_isFlag(player, PILOT_HYP_PREP) && \
|
(player && !pilot_isFlag(player, PILOT_HYP_PREP) && \
|
||||||
!pilot_isFlag(player, PILOT_HYP_BEGIN) && \
|
!pilot_isFlag(player, PILOT_HYP_BEGIN) && \
|
||||||
!pilot_isFlag(player, PILOT_HYPERSPACE))
|
!pilot_isFlag(player, PILOT_HYPERSPACE)) /**< Make sure player isn't jumping. */
|
||||||
static void input_key(int keynum, double value, int kabs) {
|
static void input_key(int keynum, double value, int kabs) {
|
||||||
unsigned int t;
|
unsigned int t;
|
||||||
|
|
||||||
|
418
src/space.c
418
src/space.c
@ -34,8 +34,10 @@
|
|||||||
#define PLANET_GFX_EXTERIOR_W 400
|
#define PLANET_GFX_EXTERIOR_W 400
|
||||||
#define PLANET_GFX_EXTERIOR_H 400
|
#define PLANET_GFX_EXTERIOR_H 400
|
||||||
|
|
||||||
/* Overcome warning due to zero value. */
|
#define CHUNK_SIZE 32 /**< Size to allocate by. */
|
||||||
|
#define CHUNK_SIZE_SMALL 8 /**< Smaller size to allocate chunks by. */
|
||||||
|
|
||||||
|
/* Overcome warning due to zero value. */
|
||||||
#define FLAG_XSET (1<<0)
|
#define FLAG_XSET (1<<0)
|
||||||
#define FLAG_YSET (1<<1)
|
#define FLAG_YSET (1<<1)
|
||||||
#define FLAG_ASTEROIDSSET (1<<2)
|
#define FLAG_ASTEROIDSSET (1<<2)
|
||||||
@ -48,11 +50,19 @@
|
|||||||
static char** planetname_stack = NULL;
|
static char** planetname_stack = NULL;
|
||||||
static char** systemname_stack = NULL;
|
static char** systemname_stack = NULL;
|
||||||
static int spacename_nstack = 0;
|
static int spacename_nstack = 0;
|
||||||
|
static int spacename_mstack = 0; /**< Size of memory in planet <->system stack. */
|
||||||
|
|
||||||
/* Star system stack and co. */
|
/* Star system stack. */
|
||||||
StarSystem* systems_stack = NULL; /* Star system stack. */
|
StarSystem* systems_stack = NULL; /* Star system stack. */
|
||||||
int systems_nstack = 0; /* Number of star systems. */
|
int systems_nstack = 0; /* Number of star systems. */
|
||||||
static int total_planets = 0; /* Total number of loaded planets - A little silly. */
|
static int systems_mstack = 0; /**< Number of memory allocated for star system stack. */
|
||||||
|
|
||||||
|
/* Planet Stack. */
|
||||||
|
static Planet* planet_stack = NULL; /**< Planet stack. */
|
||||||
|
static int planet_nstack = 0; /**< Planet stack size. */
|
||||||
|
static int planet_mstack = 0; /**< Memory size of planet stack. */
|
||||||
|
|
||||||
|
/* Misc. */
|
||||||
StarSystem* cur_system = NULL; /* Current star system. */
|
StarSystem* cur_system = NULL; /* Current star system. */
|
||||||
|
|
||||||
/* Fleet spawn rate. */
|
/* Fleet spawn rate. */
|
||||||
@ -71,14 +81,19 @@ static int nstars = 0; /* Total stars. */
|
|||||||
static int mstars = 0; /* Memory stars are taking. */
|
static int mstars = 0; /* Memory stars are taking. */
|
||||||
|
|
||||||
/* Intern. */
|
/* Intern. */
|
||||||
static Planet* planet_pull(const char* name);
|
/* Planet load. */
|
||||||
|
static int planet_parse(Planet* planet, const xmlNodePtr parent);
|
||||||
|
/* System load. */
|
||||||
|
static int systems_load(void);
|
||||||
|
static StarSystem* system_parse(StarSystem* system, const xmlNodePtr parent);
|
||||||
|
static void systemJumps(const xmlNodePtr parent);
|
||||||
|
/* Misc. */
|
||||||
static void space_renderStars(const double dt);
|
static void space_renderStars(const double dt);
|
||||||
static void space_addFleet(Fleet* fleet, int init);
|
static void space_addFleet(Fleet* fleet, int init);
|
||||||
static StarSystem* system_parse(const xmlNodePtr parent);
|
|
||||||
static void system_parseJumps(const xmlNodePtr parent);
|
|
||||||
static PlanetClass planetclass_get(const char a);
|
static PlanetClass planetclass_get(const char a);
|
||||||
/* Extern. */
|
/* Extern. */
|
||||||
extern void player_message(const char* fmt, ...);
|
extern void player_message(const char* fmt, ...);
|
||||||
|
|
||||||
void planets_minimap(const double res, const double w,
|
void planets_minimap(const double res, const double w,
|
||||||
const double h, const RadarShape shape);
|
const double h, const RadarShape shape);
|
||||||
int space_sysSave(xmlTextWriterPtr writer);
|
int space_sysSave(xmlTextWriterPtr writer);
|
||||||
@ -100,16 +115,16 @@ void planets_minimap(const double res, const double w,
|
|||||||
|
|
||||||
glBegin(GL_POINTS);
|
glBegin(GL_POINTS);
|
||||||
for(i = 0; i < cur_system->nplanets; i++) {
|
for(i = 0; i < cur_system->nplanets; i++) {
|
||||||
planet = &cur_system->planets[i];
|
planet = cur_system->planets[i];
|
||||||
|
|
||||||
col = faction_getColour(planet->faction);
|
col = faction_getColour(planet->faction);
|
||||||
if((col != &cHostile) && !planet_hasService(planet, PLANET_SERVICE_BASIC))
|
if((col != &cHostile) && !planet_hasService(planet, PLANET_SERVICE_BASIC))
|
||||||
col = &cInert; /* Override non-hostile planets without services. */
|
col = &cInert; /* Override non-hostile planets without services. */
|
||||||
COLOUR(*col);
|
COLOUR(*col);
|
||||||
|
|
||||||
r = (int)(cur_system->planets[i].gfx_space->sw / res);
|
r = (int)(cur_system->planets[i]->gfx_space->sw / res);
|
||||||
cx = (int)((cur_system->planets[i].pos.x - player->solid->pos.x) / res);
|
cx = (int)((cur_system->planets[i]->pos.x - player->solid->pos.x) / res);
|
||||||
cy = (int)((cur_system->planets[i].pos.y - player->solid->pos.y) / res);
|
cy = (int)((cur_system->planets[i]->pos.y - player->solid->pos.y) / res);
|
||||||
|
|
||||||
x = 0;
|
x = 0;
|
||||||
y = r;
|
y = r;
|
||||||
@ -238,7 +253,7 @@ int space_canHyperspace(Pilot* p) {
|
|||||||
if(p->fuel < HYPERSPACE_FUEL) return 0;
|
if(p->fuel < HYPERSPACE_FUEL) return 0;
|
||||||
|
|
||||||
for(i = 0; i < cur_system->nplanets; i++) {
|
for(i = 0; i < cur_system->nplanets; i++) {
|
||||||
d = vect_dist(&p->solid->pos, &cur_system->planets[i].pos);
|
d = vect_dist(&p->solid->pos, &cur_system->planets[i]->pos);
|
||||||
if(d < MIN_HYPERSPACE_DIST)
|
if(d < MIN_HYPERSPACE_DIST)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -270,7 +285,7 @@ char** space_getFactionPlanet(int* nplanets, int* factions, int nfactions) {
|
|||||||
|
|
||||||
for(i = 0; i < systems_nstack; i++)
|
for(i = 0; i < systems_nstack; i++)
|
||||||
for(j = 0; j < systems_stack[i].nplanets; j++) {
|
for(j = 0; j < systems_stack[i].nplanets; j++) {
|
||||||
planet = &systems_stack[i].planets[j];
|
planet = systems_stack[i].planets[j];
|
||||||
for(k = 0; k < nfactions; k++)
|
for(k = 0; k < nfactions; k++)
|
||||||
if(planet->faction == factions[k]) {
|
if(planet->faction == factions[k]) {
|
||||||
ntmp++;
|
ntmp++;
|
||||||
@ -305,7 +320,7 @@ char* space_getRndPlanet(void) {
|
|||||||
mtmp += 25;
|
mtmp += 25;
|
||||||
tmp = realloc(tmp, sizeof(char*) * mtmp);
|
tmp = realloc(tmp, sizeof(char*) * mtmp);
|
||||||
}
|
}
|
||||||
tmp[ntmp-1] = systems_stack[i].planets[j].name;
|
tmp[ntmp-1] = systems_stack[i].planets[j]->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = tmp[RNG(0, ntmp-1)];
|
res = tmp[RNG(0, ntmp-1)];
|
||||||
@ -353,15 +368,11 @@ char* planet_getSystem(char* planetname) {
|
|||||||
/* Get a planet based on it's name. */
|
/* Get a planet based on it's name. */
|
||||||
Planet* planet_get(char* planetname) {
|
Planet* planet_get(char* planetname) {
|
||||||
int i;
|
int i;
|
||||||
char* sysname;
|
|
||||||
StarSystem* sys;
|
|
||||||
|
|
||||||
sysname = planet_getSystem(planetname);
|
for(i = 0; i < planet_nstack; i++)
|
||||||
sys = system_get(sysname);
|
if(strcmp(planet_stack[i].name, planetname)==0)
|
||||||
|
return &planet_stack[i];
|
||||||
|
|
||||||
for(i = 0; i < sys->nplanets; i++)
|
|
||||||
if(strcmp(planetname, sys->planets[i].name)==0)
|
|
||||||
return &sys->planets[i];
|
|
||||||
DEBUG("Planet '%s' not found in the universe", planetname);
|
DEBUG("Planet '%s' not found in the universe", planetname);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -441,9 +452,9 @@ static void space_addFleet(Fleet* fleet, int init) {
|
|||||||
/* Get friendly planet to land on. */
|
/* Get friendly planet to land on. */
|
||||||
planet = NULL;
|
planet = NULL;
|
||||||
for(i = 0; i < cur_system->nplanets; i++)
|
for(i = 0; i < cur_system->nplanets; i++)
|
||||||
if(planet_hasService(&cur_system->planets[i], PLANET_SERVICE_BASIC) &&
|
if(planet_hasService(cur_system->planets[i], PLANET_SERVICE_BASIC) &&
|
||||||
!areEnemies(fleet->faction, cur_system->planets[i].faction)) {
|
!areEnemies(fleet->faction, cur_system->planets[i]->faction)) {
|
||||||
planet = &cur_system->planets[i];
|
planet = cur_system->planets[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,59 +545,95 @@ void space_init(const char* sysname) {
|
|||||||
sys_setFlag(cur_system, SYSTEM_KNOWN);
|
sys_setFlag(cur_system, SYSTEM_KNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the planets of name 'name'. */
|
/**
|
||||||
static Planet* planet_pull(const char* name) {
|
* @fn static int planets_load(void)
|
||||||
int i;
|
*
|
||||||
|
* @brief Load all the planets in the game.
|
||||||
Planet* tmp = NULL;
|
* @return 0 on success.
|
||||||
|
*/
|
||||||
char str[PATH_MAX] = "\0";
|
static int planets_load(void) {
|
||||||
char* tstr;
|
|
||||||
|
|
||||||
uint32_t flags = 0;
|
|
||||||
|
|
||||||
uint32_t bufsize;
|
uint32_t bufsize;
|
||||||
char* buf = pack_readfile(DATA, PLANET_DATA, &bufsize);
|
char* buf;
|
||||||
|
xmlNodePtr node;
|
||||||
|
xmlDocPtr doc;
|
||||||
|
|
||||||
xmlNodePtr node, cur, ccur;
|
buf = pack_readfile(DATA, PLANET_DATA, &bufsize);
|
||||||
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
|
doc = xmlParseMemory(buf, bufsize);
|
||||||
|
|
||||||
node = doc->xmlChildrenNode;
|
node = doc->xmlChildrenNode;
|
||||||
if(strcmp((char*)node->name, XML_PLANET_ID)) {
|
if(strcmp((char*)node->name, XML_PLANET_ID)) {
|
||||||
ERR("Malformed "PLANET_DATA" file: missing root element '"XML_PLANET_ID"'");
|
ERR("Malformed "PLANET_DATA" file: missing root element '"XML_PLANET_ID"'");
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node->xmlChildrenNode; /* First system node. */
|
node = node->xmlChildrenNode; /* First system node. */
|
||||||
if(node == NULL) {
|
if(node == NULL) {
|
||||||
ERR("Malformed "PLANET_DATA" file: does not contain elements");
|
ERR("Malformed "PLANET_DATA" file: does not contain elements");
|
||||||
return NULL;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize stack if needed. */
|
||||||
|
if(planet_stack == NULL) {
|
||||||
|
planet_mstack = CHUNK_SIZE;
|
||||||
|
planet_stack = malloc(sizeof(Planet) * planet_mstack);
|
||||||
|
planet_nstack = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if(xml_isNode(node, XML_PLANET_TAG)) {
|
if(xml_isNode(node, XML_PLANET_TAG)) {
|
||||||
tstr = xml_nodeProp(node, "name");
|
/* See if stack must grow. */
|
||||||
if(strcmp(tstr, name)==0) { /* Found. */
|
planet_nstack++;
|
||||||
tmp = CALLOC_L(Planet);
|
if(planet_nstack > planet_mstack) {
|
||||||
tmp->faction = -1; /* No faction. */
|
planet_mstack += CHUNK_SIZE;
|
||||||
tmp->name = tstr;
|
planet_stack = realloc(planet_stack, sizeof(Planet) * planet_mstack);
|
||||||
|
}
|
||||||
|
planet_parse(&planet_stack[planet_nstack-1], node);
|
||||||
|
}
|
||||||
|
} while(xml_nextNode(node));
|
||||||
|
|
||||||
node = node->xmlChildrenNode;
|
xmlFreeDoc(doc);
|
||||||
|
free(buf);
|
||||||
|
xmlCleanupParser();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn static int planet_parse(Planet* planet, const xmlNodePtr parent)
|
||||||
|
*
|
||||||
|
* @brief Parses a planet from an xml node.
|
||||||
|
* @param planet Planet to fill up.
|
||||||
|
* @param parent Node that contains planet data.
|
||||||
|
* @return 0 on success.
|
||||||
|
*/
|
||||||
|
static int planet_parse(Planet* planet, const xmlNodePtr parent) {
|
||||||
|
int i;
|
||||||
|
char str[PATH_MAX];
|
||||||
|
xmlNodePtr node, cur, ccur;
|
||||||
|
int len;
|
||||||
|
unsigned int flags;
|
||||||
|
|
||||||
|
/* Clear up memory for sane defaults. */
|
||||||
|
memset(planet, 0, sizeof(Planet));
|
||||||
|
str[0] = '\0';
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
|
/* Get the name. */
|
||||||
|
xmlr_attr(parent, "name", planet->name);
|
||||||
|
|
||||||
|
node = parent->xmlChildrenNode;
|
||||||
do {
|
do {
|
||||||
if(xml_isNode(node, "GFX")) {
|
if(xml_isNode(node, "GFX")) {
|
||||||
cur = node->children;
|
cur = node->children;
|
||||||
do {
|
do {
|
||||||
if(xml_isNode(cur, "space")) {
|
if(xml_isNode(cur, "space")) { /* Load space gfx. */
|
||||||
/* Load space gfx. */
|
|
||||||
snprintf(str, PATH_MAX, PLANET_GFX_SPACE"%s", xml_get(cur));
|
snprintf(str, PATH_MAX, PLANET_GFX_SPACE"%s", xml_get(cur));
|
||||||
tmp->gfx_space = gl_newImage(str);
|
planet->gfx_space = gl_newImage(str);
|
||||||
}
|
}
|
||||||
else if(xml_isNode(cur, "exterior")) {
|
else if(xml_isNode(cur, "exterior")) { /* Load land gfx. */
|
||||||
/* Load land gfx. */
|
len = strlen(xml_get(cur)) + sizeof(PLANET_GFX_EXTERIOR);
|
||||||
tmp->gfx_exterior = malloc(strlen(xml_get(cur))+sizeof(PLANET_GFX_EXTERIOR));
|
planet->gfx_exterior = malloc(len);
|
||||||
snprintf(tmp->gfx_exterior, strlen(xml_get(cur))+sizeof(PLANET_GFX_EXTERIOR),
|
snprintf(planet->gfx_exterior, len, PLANET_GFX_EXTERIOR"%s", xml_get(cur));
|
||||||
PLANET_GFX_EXTERIOR"%s", xml_get(cur));
|
|
||||||
}
|
}
|
||||||
} while(xml_nextNode(cur));
|
} while(xml_nextNode(cur));
|
||||||
}
|
}
|
||||||
@ -595,11 +642,11 @@ static Planet* planet_pull(const char* name) {
|
|||||||
do {
|
do {
|
||||||
if(xml_isNode(cur, "x")) {
|
if(xml_isNode(cur, "x")) {
|
||||||
flags |= FLAG_XSET;
|
flags |= FLAG_XSET;
|
||||||
tmp->pos.x = xml_getFloat(cur);
|
planet->pos.x = xml_getFloat(cur);
|
||||||
}
|
}
|
||||||
else if(xml_isNode(cur, "y")) {
|
else if(xml_isNode(cur, "y")) {
|
||||||
flags |= FLAG_YSET;
|
flags |= FLAG_YSET;
|
||||||
tmp->pos.y = xml_getFloat(cur);
|
planet->pos.y = xml_getFloat(cur);
|
||||||
}
|
}
|
||||||
} while(xml_nextNode(cur));
|
} while(xml_nextNode(cur));
|
||||||
}
|
}
|
||||||
@ -607,34 +654,34 @@ static Planet* planet_pull(const char* name) {
|
|||||||
cur = node->children;
|
cur = node->children;
|
||||||
do {
|
do {
|
||||||
if(xml_isNode(cur, "class"))
|
if(xml_isNode(cur, "class"))
|
||||||
tmp->class = planetclass_get(cur->children->content[0]);
|
planet->class = planetclass_get(cur->children->content[0]);
|
||||||
else if(xml_isNode(cur, "faction")) {
|
else if(xml_isNode(cur, "faction")) {
|
||||||
flags |= FLAG_FACTIONSET;
|
flags |= FLAG_FACTIONSET;
|
||||||
tmp->faction = faction_get(xml_get(cur));
|
planet->faction = faction_get(xml_get(cur));
|
||||||
}
|
}
|
||||||
else if(xml_isNode(cur, "description"))
|
else if(xml_isNode(cur, "description"))
|
||||||
tmp->description = strdup(xml_get(cur));
|
planet->description = strdup(xml_get(cur));
|
||||||
else if(xml_isNode(cur, "bar"))
|
else if(xml_isNode(cur, "bar"))
|
||||||
tmp->bar_description = strdup(xml_get(cur));
|
planet->bar_description = strdup(xml_get(cur));
|
||||||
else if(xml_isNode(cur, "services")) {
|
else if(xml_isNode(cur, "services")) {
|
||||||
flags |= FLAG_SERVICESET;
|
flags |= FLAG_SERVICESET;
|
||||||
tmp->services = xml_getInt(cur);
|
planet->services = xml_getInt(cur); /* Flags gotten by data. */
|
||||||
}
|
}
|
||||||
else if(xml_isNode(cur, "tech")) {
|
else if(xml_isNode(cur, "tech")) {
|
||||||
ccur = cur->children;
|
ccur = cur->children;
|
||||||
do {
|
do {
|
||||||
if(xml_isNode(ccur, "main")) {
|
if(xml_isNode(ccur, "main")) {
|
||||||
flags |= FLAG_TECHSET;
|
flags |= FLAG_TECHSET;
|
||||||
tmp->tech[0] = xml_getInt(ccur);
|
planet->tech[0] = xml_getInt(ccur);
|
||||||
}
|
}
|
||||||
else if(xml_isNode(ccur, "special")) {
|
else if(xml_isNode(ccur, "special")) {
|
||||||
for(i = 1; i < PLANET_TECH_MAX; i++)
|
for(i = 1; i < PLANET_TECH_MAX; i++)
|
||||||
if(tmp->tech[i]==0) {
|
if(planet->tech[i] == 0) {
|
||||||
tmp->tech[i] = xml_getInt(ccur);
|
planet->tech[i] = xml_getInt(ccur);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(i == PLANET_TECH_MAX) WARN("Planet '%s' has too many"
|
if(i == PLANET_TECH_MAX) WARN("Planet '%s' has too many"
|
||||||
"'special tech' entries", tmp->name);
|
"'special tech' entries", planet->name);
|
||||||
}
|
}
|
||||||
} while(xml_nextNode(ccur));
|
} while(xml_nextNode(ccur));
|
||||||
}
|
}
|
||||||
@ -642,68 +689,61 @@ static Planet* planet_pull(const char* name) {
|
|||||||
ccur = cur->children;
|
ccur = cur->children;
|
||||||
do {
|
do {
|
||||||
if(xml_isNode(ccur, "commodity")) {
|
if(xml_isNode(ccur, "commodity")) {
|
||||||
tmp->commodities = realloc(tmp->commodities,
|
planet->commodities = realloc(planet->commodities,
|
||||||
(tmp->ncommodities+1) * sizeof(Commodity*));
|
(planet->ncommodities+1) * sizeof(Commodity*));
|
||||||
tmp->commodities[tmp->ncommodities] =
|
planet->commodities[planet->ncommodities] =
|
||||||
commodity_get(xml_get(ccur));
|
commodity_get(xml_get(ccur));
|
||||||
tmp->ncommodities++;
|
planet->ncommodities++;
|
||||||
}
|
}
|
||||||
} while(xml_nextNode(ccur));
|
} while(xml_nextNode(ccur));
|
||||||
}
|
}
|
||||||
} while(xml_nextNode(cur));
|
} while(xml_nextNode(cur));
|
||||||
}
|
}
|
||||||
} while(xml_nextNode(node));
|
} while(xml_nextNode(node));
|
||||||
break;
|
|
||||||
} else
|
|
||||||
free(tstr); /* xmlGetProp mallocs the string. */
|
|
||||||
}
|
|
||||||
} while(xml_nextNode(node));
|
|
||||||
|
|
||||||
xmlFreeDoc(doc);
|
/* Verification. */
|
||||||
free(buf);
|
#define MELEMENT(o,s) if(o) WARN("Planet '%s' missing '"s"' element", planet->name)
|
||||||
xmlCleanupParser();
|
MELEMENT(planet->gfx_space==NULL, "GFX space");
|
||||||
|
MELEMENT(planet_hasService(planet, PLANET_SERVICE_LAND) &&
|
||||||
/* Check elements. */
|
planet->gfx_exterior==NULL, "GFX exterior");
|
||||||
if(tmp) {
|
|
||||||
#define MELEMENT(o,s) if(o) WARN("Planet '%s' missing '"s"' element", tmp->name)
|
|
||||||
MELEMENT(tmp->gfx_space==NULL, "GFX_space");
|
|
||||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
|
|
||||||
tmp->gfx_exterior==NULL, "GFX exterior");
|
|
||||||
MELEMENT((flags&FLAG_XSET)==0, "x");
|
MELEMENT((flags&FLAG_XSET)==0, "x");
|
||||||
MELEMENT((flags&FLAG_YSET)==0, "y");
|
MELEMENT((flags&FLAG_YSET)==0, "y");
|
||||||
MELEMENT(tmp->class==PLANET_CLASS_NULL, "class");
|
MELEMENT(planet->class==PLANET_CLASS_NULL, "class");
|
||||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
|
MELEMENT(planet_hasService(planet, PLANET_SERVICE_LAND) &&
|
||||||
tmp->description==NULL, "description");
|
planet->description==NULL, "description");
|
||||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
|
MELEMENT(planet_hasService(planet, PLANET_SERVICE_BASIC) &&
|
||||||
tmp->bar_description==NULL, "bar");
|
planet->bar_description==NULL, "bar");
|
||||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
|
MELEMENT(planet_hasService(planet, PLANET_SERVICE_BASIC) &&
|
||||||
(flags & FLAG_FACTIONSET)==0, "faction");
|
(flags&FLAG_FACTIONSET)==0, "faction");
|
||||||
MELEMENT((flags&FLAG_SERVICESET)==0, "services");
|
MELEMENT((flags&FLAG_SERVICESET)==0, "services");
|
||||||
|
MELEMENT((planet_hasService(planet, PLANET_SERVICE_OUTFITS) ||
|
||||||
MELEMENT((planet_hasService(tmp, PLANET_SERVICE_OUTFITS) ||
|
planet_hasService(planet, PLANET_SERVICE_SHIPYARD)) &&
|
||||||
planet_hasService(tmp, PLANET_SERVICE_SHIPYARD)) &&
|
|
||||||
(flags&FLAG_TECHSET)==0, "tech");
|
(flags&FLAG_TECHSET)==0, "tech");
|
||||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_COMMODITY) &&
|
MELEMENT(planet_hasService(planet, PLANET_SERVICE_COMMODITY) &&
|
||||||
(tmp->ncommodities==0), "commodity");
|
(planet->ncommodities==0), "commodity");
|
||||||
#undef MELEMENT
|
#undef MELEMENT
|
||||||
} else
|
|
||||||
WARN("No planet found matching name '%s'", name);
|
|
||||||
|
|
||||||
return tmp;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse node 'parent' which should be the node of a system. */
|
/* Parse node 'parent' which should be the node of a system. */
|
||||||
/* Return the StarSystem fully loaded. */
|
/* Return the StarSystem fully loaded. */
|
||||||
static StarSystem* system_parse(const xmlNodePtr parent) {
|
static StarSystem* system_parse(StarSystem* sys, const xmlNodePtr parent) {
|
||||||
Planet* planet = NULL;
|
Planet* planet;
|
||||||
SystemFleet* fleet = NULL;
|
SystemFleet* fleet;
|
||||||
StarSystem* tmp = CALLOC_L(StarSystem);
|
|
||||||
char* ptrc;
|
char* ptrc;
|
||||||
xmlNodePtr cur, node;
|
xmlNodePtr cur, node;
|
||||||
|
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
int size;
|
||||||
|
|
||||||
tmp->name = xml_nodeProp(parent, "name"); /* Already mallocs. */
|
/* Clear memory for sane defaults. */
|
||||||
|
memset(sys, 0, sizeof(StarSystem));
|
||||||
|
planet = NULL;
|
||||||
|
fleet = NULL;
|
||||||
|
size = 0;
|
||||||
|
|
||||||
|
sys->name = xml_nodeProp(parent, "name"); /* Already mallocs. */
|
||||||
|
|
||||||
node = parent->xmlChildrenNode;
|
node = parent->xmlChildrenNode;
|
||||||
|
|
||||||
@ -714,11 +754,11 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
|||||||
do {
|
do {
|
||||||
if(xml_isNode(cur, "x")) {
|
if(xml_isNode(cur, "x")) {
|
||||||
flags |= FLAG_XSET;
|
flags |= FLAG_XSET;
|
||||||
tmp->pos.x = xml_getFloat(cur);
|
sys->pos.x = xml_getFloat(cur);
|
||||||
}
|
}
|
||||||
if(xml_isNode(cur, "y")) {
|
if(xml_isNode(cur, "y")) {
|
||||||
flags |= FLAG_YSET;
|
flags |= FLAG_YSET;
|
||||||
tmp->pos.y = xml_getFloat(cur);
|
sys->pos.y = xml_getFloat(cur);
|
||||||
}
|
}
|
||||||
} while(xml_nextNode(cur));
|
} while(xml_nextNode(cur));
|
||||||
}
|
}
|
||||||
@ -726,22 +766,22 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
|||||||
cur = node->children;
|
cur = node->children;
|
||||||
do {
|
do {
|
||||||
if(xml_isNode(cur, "stars")) /* Non-zero. */
|
if(xml_isNode(cur, "stars")) /* Non-zero. */
|
||||||
tmp->stars = xml_getInt(cur);
|
sys->stars = xml_getInt(cur);
|
||||||
else if(xml_isNode(cur, "asteroids")) {
|
else if(xml_isNode(cur, "asteroids")) {
|
||||||
flags |= FLAG_ASTEROIDSSET;
|
flags |= FLAG_ASTEROIDSSET;
|
||||||
tmp->asteroids = xml_getInt(cur);
|
sys->asteroids = xml_getInt(cur);
|
||||||
}
|
}
|
||||||
else if(xml_isNode(cur, "interference")) {
|
else if(xml_isNode(cur, "interference")) {
|
||||||
flags |= FLAG_INTEFERENCESET;
|
flags |= FLAG_INTEFERENCESET;
|
||||||
tmp->interference = xml_getFloat(cur)/100;
|
sys->interference = xml_getFloat(cur)/100;
|
||||||
}
|
}
|
||||||
else if(xml_isNode(cur, "nebulae")) {
|
else if(xml_isNode(cur, "nebulae")) {
|
||||||
ptrc = xml_nodeProp(cur, "volatility");
|
ptrc = xml_nodeProp(cur, "volatility");
|
||||||
if(ptrc != NULL) { /* Has volatility. */
|
if(ptrc != NULL) { /* Has volatility. */
|
||||||
tmp->nebu_volatility = atof(ptrc);
|
sys->nebu_volatility = atof(ptrc);
|
||||||
free(ptrc);
|
free(ptrc);
|
||||||
}
|
}
|
||||||
tmp->nebu_density = xml_getFloat(cur);
|
sys->nebu_density = xml_getFloat(cur);
|
||||||
}
|
}
|
||||||
}while(xml_nextNode(cur));
|
}while(xml_nextNode(cur));
|
||||||
}
|
}
|
||||||
@ -751,20 +791,26 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
|||||||
do {
|
do {
|
||||||
if(cur && xml_isNode(cur, "planet")) {
|
if(cur && xml_isNode(cur, "planet")) {
|
||||||
/* Add planet to system. */
|
/* Add planet to system. */
|
||||||
total_planets++; /* Increase planet counter. */
|
sys->nplanets++;
|
||||||
planet = planet_pull(xml_get(cur));
|
if(sys->nplanets > size) {
|
||||||
tmp->planets = realloc(tmp->planets, sizeof(Planet)*(++tmp->nplanets));
|
size += CHUNK_SIZE_SMALL;
|
||||||
memcpy(tmp->planets+(tmp->nplanets-1), planet, sizeof(Planet));
|
sys->planets = realloc(sys->planets, sizeof(Planet*) * size);
|
||||||
|
}
|
||||||
|
planet = planet_get(xml_get(cur));
|
||||||
|
sys->planets[sys->nplanets-1] = planet;
|
||||||
|
|
||||||
/* Add planet <-> star system to name stack. */
|
/* Add planet <-> star system to name stack. */
|
||||||
spacename_nstack++;
|
spacename_nstack++;
|
||||||
|
if(spacename_nstack > spacename_mstack) {
|
||||||
|
spacename_mstack += CHUNK_SIZE;
|
||||||
planetname_stack = realloc(planetname_stack,
|
planetname_stack = realloc(planetname_stack,
|
||||||
sizeof(char*)*spacename_nstack);
|
sizeof(char*) * spacename_mstack);
|
||||||
systemname_stack = realloc(systemname_stack,
|
systemname_stack = realloc(systemname_stack,
|
||||||
sizeof(char*)*spacename_nstack);
|
sizeof(char*) * spacename_mstack);
|
||||||
|
}
|
||||||
planetname_stack[spacename_nstack-1] = planet->name;
|
planetname_stack[spacename_nstack-1] = planet->name;
|
||||||
systemname_stack[spacename_nstack-1] = tmp->name;
|
|
||||||
free(planet);
|
systemname_stack[spacename_nstack-1] = sys->name;
|
||||||
}
|
}
|
||||||
} while(xml_nextNode(cur));
|
} while(xml_nextNode(cur));
|
||||||
}
|
}
|
||||||
@ -776,17 +822,17 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
|||||||
fleet = CALLOC_L(SystemFleet);
|
fleet = CALLOC_L(SystemFleet);
|
||||||
fleet->fleet = fleet_get(xml_get(cur));
|
fleet->fleet = fleet_get(xml_get(cur));
|
||||||
if(fleet->fleet == NULL)
|
if(fleet->fleet == NULL)
|
||||||
WARN("Fleet %s for Star System %s not found", xml_get(cur), tmp->name);
|
WARN("Fleet %s for Star System %s not found", xml_get(cur), sys->name);
|
||||||
|
|
||||||
ptrc = xml_nodeProp(cur, "chance"); /* Malloc ptrc. */
|
ptrc = xml_nodeProp(cur, "chance"); /* Malloc ptrc. */
|
||||||
fleet->chance = atoi(ptrc);
|
fleet->chance = atoi(ptrc);
|
||||||
if(fleet->chance == 0)
|
if(fleet->chance == 0)
|
||||||
WARN("Fleet %s for Star System %s has 0%% chance to appear",
|
WARN("Fleet %s for Star System %s has 0%% chance to appear",
|
||||||
fleet->fleet->name, tmp->name);
|
fleet->fleet->name, sys->name);
|
||||||
if(ptrc) free(ptrc); /* Free the ptrc. */
|
if(ptrc) free(ptrc); /* Free the ptrc. */
|
||||||
|
|
||||||
tmp->fleets = realloc(tmp->fleets, sizeof(SystemFleet)*(++tmp->nfleets));
|
sys->fleets = realloc(sys->fleets, sizeof(SystemFleet)*(++sys->nfleets));
|
||||||
memcpy(tmp->fleets+(tmp->nfleets-1), fleet, sizeof(SystemFleet));
|
memcpy(sys->fleets+(sys->nfleets-1), fleet, sizeof(SystemFleet));
|
||||||
free(fleet);
|
free(fleet);
|
||||||
}
|
}
|
||||||
} while(xml_nextNode(cur));
|
} while(xml_nextNode(cur));
|
||||||
@ -794,19 +840,21 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
|||||||
} while(xml_nextNode(node));
|
} while(xml_nextNode(node));
|
||||||
|
|
||||||
/* Check elements. */
|
/* Check elements. */
|
||||||
#define MELEMENT(o,s) if((o) == 0) WARN("Star System '%s' missing '"s"' element", tmp->name)
|
#define MELEMENT(o,s) if((o) == 0) WARN("Star System '%s' missing '"s"' element", sys->name)
|
||||||
|
if(sys->name == NULL) WARN("Star System '%s' missing 'name' tag", sys->name);
|
||||||
MELEMENT(flags&FLAG_XSET, "x");
|
MELEMENT(flags&FLAG_XSET, "x");
|
||||||
MELEMENT(flags&FLAG_YSET, "y");
|
MELEMENT(flags&FLAG_YSET, "y");
|
||||||
MELEMENT(tmp->stars, "stars");
|
MELEMENT(sys->stars, "stars");
|
||||||
MELEMENT(flags&FLAG_ASTEROIDSSET, "asteroids"); /* Can be 0. */
|
MELEMENT(flags&FLAG_ASTEROIDSSET, "asteroids"); /* Can be 0. */
|
||||||
MELEMENT(flags&FLAG_INTEFERENCESET, "inteference");
|
MELEMENT(flags&FLAG_INTEFERENCESET, "inteference");
|
||||||
#undef MELEMENT
|
#undef MELEMENT
|
||||||
|
|
||||||
/* Post processing. */
|
/* Post processing. */
|
||||||
if(tmp->nplanets > 0)
|
if(sys->nplanets > 0)
|
||||||
/**< @todo Make dependant on overall planet faction. */
|
/**< @todo Make dependant on overall planet faction. */
|
||||||
tmp->faction = tmp->planets[0].faction;
|
sys->faction = sys->planets[0]->faction;
|
||||||
return tmp;
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the jumps into a system. */
|
/* Load the jumps into a system. */
|
||||||
@ -849,14 +897,38 @@ static void system_parseJumps(const xmlNodePtr parent) {
|
|||||||
} while(xml_nextNode(node));
|
} while(xml_nextNode(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the ENTIRE universe into RAM. -- WOAH! */
|
/**
|
||||||
/* -- Used a two system pass to first load the star systems_stack and then set jump routes. */
|
* @fn int space_load(void)
|
||||||
|
*
|
||||||
|
* @brief Load the ENTIRE universe into RAM. -- WOAH!
|
||||||
|
* @return 0 on success.
|
||||||
|
*/
|
||||||
int space_load(void) {
|
int space_load(void) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = planets_load();
|
||||||
|
if(ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = systems_load();
|
||||||
|
if(ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn int systems_load(void)
|
||||||
|
*
|
||||||
|
* @brief Load the entire systems, needs to be called after planets_load.
|
||||||
|
*
|
||||||
|
* Uses a two system pass to first load the star systems_stack and then set
|
||||||
|
* jump routes.
|
||||||
|
* @return 0 on success.
|
||||||
|
*/
|
||||||
|
static int systems_load(void) {
|
||||||
uint32_t bufsize;
|
uint32_t bufsize;
|
||||||
char* buf = pack_readfile(DATA, SYSTEM_DATA, &bufsize);
|
char* buf = pack_readfile(DATA, SYSTEM_DATA, &bufsize);
|
||||||
|
|
||||||
StarSystem* tmp;
|
|
||||||
|
|
||||||
xmlNodePtr node;
|
xmlNodePtr node;
|
||||||
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
|
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
|
||||||
|
|
||||||
@ -870,13 +942,24 @@ int space_load(void) {
|
|||||||
ERR("Malformed "SYSTEM_DATA" file: does not contain elements");
|
ERR("Malformed "SYSTEM_DATA" file: does not contain elements");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate if needed. */
|
||||||
|
if(systems_stack == NULL) {
|
||||||
|
systems_mstack = CHUNK_SIZE;
|
||||||
|
systems_stack = malloc(sizeof(StarSystem) * systems_mstack);
|
||||||
|
systems_nstack = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Fist pass - Load all the star systems_stack. */
|
/* Fist pass - Load all the star systems_stack. */
|
||||||
do {
|
do {
|
||||||
if(xml_isNode(node, XML_SYSTEM_TAG)) {
|
if(xml_isNode(node, XML_SYSTEM_TAG)) {
|
||||||
tmp = system_parse(node);
|
/* Check if memory needs to grow. */
|
||||||
systems_stack = realloc(systems_stack, sizeof(StarSystem)*(++systems_nstack));
|
systems_nstack++;
|
||||||
memcpy(systems_stack+systems_nstack-1, tmp, sizeof(StarSystem));
|
if(systems_nstack > systems_mstack) {
|
||||||
free(tmp);
|
systems_mstack += CHUNK_SIZE;
|
||||||
|
systems_stack = realloc(systems_stack, sizeof(StarSystem) * systems_mstack);
|
||||||
|
}
|
||||||
|
system_parse(&systems_stack[systems_nstack-1], node);
|
||||||
}
|
}
|
||||||
} while(xml_nextNode(node));
|
} while(xml_nextNode(node));
|
||||||
|
|
||||||
@ -894,7 +977,7 @@ int space_load(void) {
|
|||||||
|
|
||||||
DEBUG("Loaded %d star system%s with %d planet%s",
|
DEBUG("Loaded %d star system%s with %d planet%s",
|
||||||
systems_nstack, (systems_nstack==1) ? "" : "s",
|
systems_nstack, (systems_nstack==1) ? "" : "s",
|
||||||
total_planets, (total_planets==1) ? "" : "s");
|
planet_nstack, (planet_nstack==1) ? "" : "s");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -996,27 +1079,43 @@ void planets_render(void) {
|
|||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < cur_system->nplanets; i++)
|
for(i = 0; i < cur_system->nplanets; i++)
|
||||||
gl_blitSprite(cur_system->planets[i].gfx_space,
|
gl_blitSprite(cur_system->planets[i]->gfx_space,
|
||||||
cur_system->planets[i].pos.x, cur_system->planets[i].pos.y, 0, 0, NULL);
|
cur_system->planets[i]->pos.x, cur_system->planets[i]->pos.y,
|
||||||
|
0, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clean up the system. */
|
/* Clean up the system. */
|
||||||
void space_exit(void) {
|
void space_exit(void) {
|
||||||
int i,j;
|
int i;
|
||||||
|
|
||||||
/* Free the names. */
|
/* Free the names. */
|
||||||
/*if(planetname_stack) free(planetname_stack); */
|
if(planetname_stack) free(planetname_stack);
|
||||||
/*if(systemname_stack) free(systemname_stack); */
|
if(systemname_stack) free(systemname_stack);
|
||||||
if(planetname_stack) {
|
|
||||||
free(planetname_stack);
|
|
||||||
planetname_stack = NULL;
|
|
||||||
}
|
|
||||||
if(systemname_stack) {
|
|
||||||
free(systemname_stack);
|
|
||||||
systemname_stack = NULL;
|
|
||||||
}
|
|
||||||
spacename_nstack = 0;
|
spacename_nstack = 0;
|
||||||
|
|
||||||
|
/* Free the planets. */
|
||||||
|
for(i = 0; i < planet_nstack; i++) {
|
||||||
|
free(planet_stack[i].name);
|
||||||
|
|
||||||
|
if(planet_stack[i].description)
|
||||||
|
free(planet_stack[i].description);
|
||||||
|
if(planet_stack[i].bar_description)
|
||||||
|
free(planet_stack[i].bar_description);
|
||||||
|
|
||||||
|
/* Graphics. */
|
||||||
|
if(planet_stack[i].gfx_space)
|
||||||
|
gl_freeTexture(planet_stack[i].gfx_space);
|
||||||
|
if(planet_stack[i].gfx_exterior)
|
||||||
|
free(planet_stack[i].gfx_exterior);
|
||||||
|
|
||||||
|
/* Commodities. */
|
||||||
|
free(planet_stack[i].commodities);
|
||||||
|
}
|
||||||
|
free(planet_stack);
|
||||||
|
planet_stack = NULL;
|
||||||
|
planet_nstack = 0;
|
||||||
|
planet_mstack = 0;
|
||||||
|
|
||||||
/* Free the systems. */
|
/* Free the systems. */
|
||||||
for(i = 0; i < systems_nstack; i++) {
|
for(i = 0; i < systems_nstack; i++) {
|
||||||
free(systems_stack[i].name);
|
free(systems_stack[i].name);
|
||||||
@ -1025,33 +1124,18 @@ void space_exit(void) {
|
|||||||
if(systems_stack[i].jumps)
|
if(systems_stack[i].jumps)
|
||||||
free(systems_stack[i].jumps);
|
free(systems_stack[i].jumps);
|
||||||
|
|
||||||
/* Free some planets. */
|
|
||||||
for(j = 0; j < systems_stack[i].nplanets; j++) {
|
|
||||||
free(systems_stack[i].planets[j].name);
|
|
||||||
if(systems_stack[i].planets[j].description)
|
|
||||||
free(systems_stack[i].planets[j].description);
|
|
||||||
if(systems_stack[i].planets[j].bar_description)
|
|
||||||
free(systems_stack[i].planets[j].bar_description);
|
|
||||||
|
|
||||||
/* Graphics. */
|
|
||||||
if(systems_stack[i].planets[j].gfx_space)
|
|
||||||
gl_freeTexture(systems_stack[i].planets[j].gfx_space);
|
|
||||||
if(systems_stack[i].planets[j].gfx_exterior)
|
|
||||||
free(systems_stack[i].planets[j].gfx_exterior);
|
|
||||||
|
|
||||||
/* Commodities. */
|
|
||||||
free(systems_stack[i].planets[j].commodities);
|
|
||||||
}
|
|
||||||
free(systems_stack[i].planets);
|
free(systems_stack[i].planets);
|
||||||
}
|
}
|
||||||
free(systems_stack);
|
free(systems_stack);
|
||||||
systems_stack = NULL;
|
systems_stack = NULL;
|
||||||
systems_nstack = 0;
|
systems_nstack = 0;
|
||||||
|
systems_mstack = 0;
|
||||||
|
|
||||||
/* Stars must be set free too. */
|
/* Stars must be free too. */
|
||||||
if(stars) free(stars);
|
if(stars) free(stars);
|
||||||
stars = NULL;
|
stars = NULL;
|
||||||
nstars = 0;
|
nstars = 0;
|
||||||
|
mstars = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear all system knowledge. */
|
/* Clear all system knowledge. */
|
||||||
|
@ -115,7 +115,7 @@ typedef struct StarSystem_ {
|
|||||||
|
|
||||||
int faction; /**< Overall faction. */
|
int faction; /**< Overall faction. */
|
||||||
|
|
||||||
Planet* planets; /**< Planets. */
|
Planet** planets; /**< Planets. */
|
||||||
int nplanets; /**< Total number of planets. */
|
int nplanets; /**< Total number of planets. */
|
||||||
|
|
||||||
SystemFleet* fleets; /**< Fleets that can appear in the current system. */
|
SystemFleet* fleets; /**< Fleets that can appear in the current system. */
|
||||||
|
Loading…
Reference in New Issue
Block a user