diff --git a/bin/Makefile b/bin/Makefile
index 422d80d..de4299e 100644
--- a/bin/Makefile
+++ b/bin/Makefile
@@ -31,7 +31,7 @@ LDFLAGS = -lm $(LDLUA) $(LDSDL) $(LDXML) $(LDTTF) $(LDGL)
DATA = data
DATAFILES = $(shell find ../scripts/ai/ ../gfx/ ../dat/ -name '*.lua' -o -name '*.png' -o -name '*.xml')
-%.o: %.c
+%.o: %.c %.h
@gcc -c $(CFLAGS) -o $@ $<
@echo -e "\tCC $@"
diff --git a/dat/planet.xml b/dat/planet.xml
index 34d4d29..71834f0 100644
--- a/dat/planet.xml
+++ b/dat/planet.xml
@@ -11,7 +11,7 @@
0
1
- KonoSphere
+ konosphere.png
@@ -24,6 +24,6 @@
0
1
- SaraCraft
+ saracraft.png
diff --git a/dat/ssys.xml b/dat/ssys.xml
index 85fdb37..a3b8a56 100644
--- a/dat/ssys.xml
+++ b/dat/ssys.xml
@@ -6,7 +6,7 @@
8
- 50
+ 500
0
0
2
@@ -22,9 +22,6 @@
Sml Merchant Convoy
Sml Merchant Convoy
-
- KonoSys
-
@@ -44,8 +41,5 @@
Merchant Ship
Merchant Ship
-
- SaraSys
-
diff --git a/gfx/planet/konosphere.png b/gfx/planet/konosphere.png
new file mode 100644
index 0000000..20ccb16
Binary files /dev/null and b/gfx/planet/konosphere.png differ
diff --git a/gfx/planet/saracraft.png b/gfx/planet/saracraft.png
new file mode 100644
index 0000000..20ccb16
Binary files /dev/null and b/gfx/planet/saracraft.png differ
diff --git a/src/ai.c b/src/ai.c
index b747830..a813470 100644
--- a/src/ai.c
+++ b/src/ai.c
@@ -5,7 +5,7 @@
#include
-#include "def.h"
+#include "main.h"
#include "log.h"
#include "pilot.h"
#include "physics.h"
diff --git a/src/joystick.c b/src/joystick.c
index 5649a31..96e9293 100644
--- a/src/joystick.c
+++ b/src/joystick.c
@@ -1,6 +1,6 @@
#include
#include
-#include "def.h"
+#include "main.h"
#include "log.h"
#include "joystick.h"
diff --git a/src/main.c b/src/main.c
index f1ff217..432d4f8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -6,7 +6,7 @@
#include
#include
-#include "def.h"
+#include "main.h"
#include "log.h"
#include "physics.h"
#include "opengl.h"
@@ -196,11 +196,12 @@ int main(int argc, char** argv) {
// Data loading.
ships_load();
+ space_load();
// Testing.
pilot_create(get_ship("Ship"), "Player", NULL, NULL, PILOT_PLAYER);
gl_bindCamera(&player->solid->pos);
- space_init();
+ space_init("SaraSys");
pilot_create(get_ship("Test"), NULL, NULL, NULL, 0);
@@ -264,6 +265,8 @@ static void update_all(void) {
glClear(GL_COLOR_BUFFER_BIT);
space_render(dt);
+ planets_render();
+
pilots_update(dt);
display_fps(dt);
diff --git a/src/def.h b/src/main.h
similarity index 80%
rename from src/def.h
rename to src/main.h
index afd8def..1d24a79 100644
--- a/src/def.h
+++ b/src/main.h
@@ -5,5 +5,5 @@
#define ABS(X) ((X<0)?-X:X)
-#define DATA "data"
+#define DATA "data" // Data file.
diff --git a/src/opengl.c b/src/opengl.c
index af6d91b..efd0648 100644
--- a/src/opengl.c
+++ b/src/opengl.c
@@ -7,7 +7,7 @@
#include
#include
-#include "def.h"
+#include "main.h"
#include "log.h"
#include "pack.h"
#include "opengl.h"
diff --git a/src/pack.c b/src/pack.c
index bdb72de..d1760c2 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -53,7 +53,7 @@ static off_t getfilesize(const char* filename) {
}
// Return true if filename is a Packfile.
-int pack_check(char* filename) {
+int pack_check(const char* filename) {
int fd = open(filename, O_RDONLY);
if(fd == -1) {
ERR("Error opening %s: %s", filename, strerror(errno));
@@ -77,7 +77,7 @@ int pack_check(char* filename) {
ERR("Error writing to file: %s", strerror(errno)); \
free(buf); return -1; }
-int pack_files(char* outfile, char** infiles, uint32_t nfiles) {
+int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles) {
void* buf;
struct stat file;
int i, namesize;
@@ -162,7 +162,7 @@ int pack_files(char* outfile, char** infiles, uint32_t nfiles) {
#define READ(f,b,n) if(read(f,b,n) != n) { \
ERR("Too few bytes read. Expected more."); \
free(buf); return -1; }
-int pack_open(Packfile* file, char* packfile, char* filename) {
+int pack_open(Packfile* file, const char* packfile, const char* filename) {
int i, j;
uint32_t nfiles;
char* buf = (char*)malloc(MAX_FILENAME);
@@ -237,7 +237,7 @@ ssize_t pack_read(Packfile* file, void* buf, size_t count) {
}
// Loads an entire file into memory and returns a pointer to it.
-void* pack_readfile(char* packfile, char* filename, uint32_t* filesize) {
+void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesize) {
Packfile* file = (Packfile*)malloc(sizeof(Packfile));
void* buf;
int size, bytes;
diff --git a/src/pack.h b/src/pack.h
index 596b519..c35d08e 100644
--- a/src/pack.h
+++ b/src/pack.h
@@ -11,12 +11,12 @@ typedef struct {
// Packfile manipulation. Automatically allocated and freed (with open and close).
// Basic.
-int pack_check(char* filename);
-int pack_files(char* outfile, char** infiles, uint32_t nfiles);
-int pack_open(Packfile* file, char* packfile, char* filename);
-ssize_t pack_read(Packfile* file, void* buf, size_t count);
+int pack_check(const char* filename);
+int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles);
+int pack_open(Packfile* file, const char* packfile, const char* filename);
+ssize_t pack_read(Packfile* file, void* buf, const size_t count);
int pack_close(Packfile* file);
// Fancy stuff.
-void* pack_readfile(char* packfile, char* filename, uint32_t* filesize);
+void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesize);
diff --git a/src/physics.h b/src/physics.h
index e47ead4..77f6e28 100644
--- a/src/physics.h
+++ b/src/physics.h
@@ -1,5 +1,5 @@
#pragma once
-#include "def.h"
+#include "main.h"
#define VX(v) ((v).x)
#define VY(v) ((v).y)
diff --git a/src/pilot.c b/src/pilot.c
index 7e3b484..180f76d 100644
--- a/src/pilot.c
+++ b/src/pilot.c
@@ -3,7 +3,7 @@
#include
#include
-#include "def.h"
+#include "main.h"
#include "log.h"
#include "pilot.h"
diff --git a/src/pilot.h b/src/pilot.h
index 16f75d7..65e0d07 100644
--- a/src/pilot.h
+++ b/src/pilot.h
@@ -1,5 +1,5 @@
#pragma once
-#include "def.h"
+#include "main.h"
#include "physics.h"
#include "ai.h"
#include "ship.h"
diff --git a/src/player.c b/src/player.c
index 6ec1aac..2736bc6 100644
--- a/src/player.c
+++ b/src/player.c
@@ -1,5 +1,5 @@
#include
-#include "def.h"
+#include "main.h"
#include "pilot.h"
#include "log.h"
#include "player.h"
diff --git a/src/ship.c b/src/ship.c
index 60f7c05..af8be5f 100644
--- a/src/ship.c
+++ b/src/ship.c
@@ -1,16 +1,15 @@
#include
-#include
+#include
+#include "main.h"
#include "log.h"
#include "pack.h"
#include "ship.h"
-#define MAX_PATH_NAME 20 // Maximum size of the path.
+#define MAX_PATH_NAME 30 // 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"
@@ -125,42 +124,39 @@ Ship* ship_parse(xmlNodePtr parent) {
}
int ships_load(void) {
- xmlNodePtr node;
-
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 ships xml file: missing tag %s", XML_ID);
+ ERR("Malformed "SHIP_DATA" file: missing root element '"XML_ID"'");
return -1;
}
node = node->xmlChildrenNode; // First ship node.
if(node == NULL) {
- ERR("Malformed ships xml file: is missing ships");
+ ERR("Malformed "SHIP_DATA" file: Does not contain elements");
return -1;
}
do {
if(node->type == XML_NODE_START && strcmp((char*)node->name, XML_SHIP)==0) {
- 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);
- }
+ tmp = ship_parse(node);
+ ship_stack = realloc(ship_stack, sizeof(Ship)*(++ships));
+ memcpy(ship_stack+ships-1, tmp, sizeof(Ship));
+ free(tmp);
}
} while((node = node->next));
xmlFreeDoc(doc);
free(buf);
+ xmlCleanupParser();
+
return 0;
}
diff --git a/src/ship.h b/src/ship.h
index c6a7119..e998a45 100644
--- a/src/ship.h
+++ b/src/ship.h
@@ -1,5 +1,5 @@
#pragma once
-#include "def.h"
+#include "main.h"
#include "opengl.h"
enum ship_class { SHIP_CLASS_NULL, SHIP_CLASS_CIVILIAN };
diff --git a/src/space.c b/src/space.c
index f92ab51..c7b7006 100644
--- a/src/space.c
+++ b/src/space.c
@@ -1,3 +1,4 @@
+#include
#include
#include
@@ -6,20 +7,98 @@
#include "opengl.h"
#include "rng.h"
#include "pilot.h"
+#include "pack.h"
#include "space.h"
+#define MAX_PATH_NAME 30 // Max size of the path.
+
+#define XML_NODE_START 1
+#define XML_NODE_TEST 3
+
+#define XML_PLANET_ID "Planets"
+#define XML_PLANET_TAG "planet"
+
+#define XML_SYSTEM_ID "Systems"
+#define XML_SYSTEM_TAG "ssys"
+
+#define PLANET_DATA "../dat/planet.xml"
+#define SPACE_DATA "../dat/ssys.xml"
+
+#define PLANET_GFX "../gfx/planet/"
+
+// Planet types. I didn't take them from Star Trek, I promise.
+typedef enum {
+ PLANET_CLASS_A, // Geothermal.
+ PLANET_CLASS_B, // Geomorteus.
+ PLANET_CLASS_C, // Geoinactive.
+ PLANET_CLASS_D, // Asteroid/Moon.
+ PLANET_CLASS_E, // Geoplastic.
+ PLANET_CLASS_F, // Geometallic.
+ PLANET_CLASS_G, // GroCrystaline.
+ PLANET_CLASS_H, // Desert.
+ PLANET_CLASS_I, // Gas Supergiant.
+ PLANET_CLASS_J, // Gas Giant.
+ PLANET_CLASS_K, // Adaptable.
+ PLANET_CLASS_L, // Marginal.
+ PLANET_CLASS_M, // Terrestrial.
+ PLANET_CLASS_N, // Reducing.
+ PLANET_CLASS_O, // Pelagic.
+ PLANET_CLASS_P, // Glaciated.
+ PLANET_CLASS_Q, // Variable.
+ PLANET_CLASS_R, // Rogue.
+ PLANET_CLASS_S, // Ultragiant.
+ PLANET_CLASS_T, // Ultragiant.
+ PLANET_CLASS_X, // Demon.
+ PLANET_CLASS_Y, // Demon.
+ PLANER_CLASS_Z // Demon.
+} PlanetClass;
+
+typedef struct {
+ char* name;
+ double x, y; // Position in star system.
+ PlanetClass class;
+ gl_texture* gfx_space; // Graphics in space.
+} Planet;
+
+typedef struct {
+ char* name;
+ double x, y; // Position.
+ int stars, asteroids; // Un numero!
+ double interference; // Un uh.. Percentage.
+
+ // Factions.
+ Planet* planets; // Planets.
+ int nplanets;
+
+ // TODO: Throw some fleets here.
+} StarSystem;
+
+static StarSystem* systems = NULL;
+static int nsystems = 0;
+static StarSystem* cur_system = NULL; // Current star system.
+
#define STAR_BUF 100 // Area to leave around screen.
typedef struct {
- double x, y;
+ double x, y; // Position. It is simpler ligher to use two doubles than the physics.
double brightness;
} Star;
-Star* stars;
-int nstars;
+static Star* stars = NULL; // Star array.
+static int nstars = 0; // Total stars.
-void space_init(void) {
+static Planet* planet_get(const char* name);
+static StarSystem* system_parse(const xmlNodePtr parent);
+
+// Init the system.
+void space_init(const char* sysname) {
int i;
- nstars = (500*gl_screen.w*gl_screen.h + STAR_BUF*STAR_BUF)/(800*640);;
+ for(i = 0; i < nsystems; i++)
+ if(strcmp(sysname, systems[i].name)==0)
+ break;
+ if(i == nsystems) ERR("System %s not found in stack", sysname);
+ cur_system = systems++;
+
+ nstars = (cur_system->stars*gl_screen.w*gl_screen.h+STAR_BUF*STAR_BUF)/(800*640);
stars = malloc(sizeof(Star)*nstars);
for(i = 0; i < nstars; i++) {
stars[i].brightness = (double)RNG(50, 200)/256.;
@@ -28,6 +107,186 @@ void space_init(void) {
}
}
+// Load the planets of name 'name'.
+static Planet* planet_get(const char* name) {
+ Planet* tmp = NULL;
+
+ char str[MAX_PATH_NAME] = "\0";
+
+ uint32_t bufsize;
+ char* buf = pack_readfile(DATA, PLANET_DATA, &bufsize);
+
+ xmlNodePtr node, cur;
+ xmlDocPtr doc = xmlParseMemory(buf, bufsize);
+
+ node = doc->xmlChildrenNode;
+ if(strcmp((char*)node->name, XML_PLANET_ID)) {
+ ERR("Malformed "PLANET_DATA" file: missing root element '"XML_PLANET_ID"'");
+ return NULL;
+ }
+
+ node = node->xmlChildrenNode; // First system node.
+ if(node == NULL) {
+ ERR("Malformed "PLANET_DATA" file: does not contain elements");
+ return NULL;
+ }
+
+ do {
+ if(node->type == XML_NODE_START && strcmp((char*)node->name, XML_PLANET_TAG)==0) {
+ if(strcmp((char*)xmlGetProp(node, (xmlChar*)"name"), name)==0) { // Found.
+ tmp = CALLOC_L(Planet);
+ tmp->name = strdup(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(PLANET_GFX),
+ PLANET_GFX"%s", (char*)cur->content);
+ tmp->gfx_space = gl_newSprite(str, 1, 1);
+ }
+ }
+ else if(strcmp((char*)node->name, "pos")==0) {
+ cur = node->children;
+ while((cur = cur->next)) {
+ if(strcmp((char*)cur->name, "x")==0)
+ tmp->x = atof((char*)cur->children->content);
+ else if(strcmp((char*)cur->name, "y")==0)
+ tmp->y = atof((char*)cur->children->content);
+ }
+ }
+ else if(strcmp((char*)node->name, "general")==0) {
+ cur = node->children;
+ while((cur = cur->next)) {
+ if(strcmp((char*)cur->name, "class")==0)
+ tmp->class = atoi((char*)cur->children->content);
+ }
+ }
+ }
+ break;
+ }
+ }
+ } while((node = node->next));
+
+ xmlFreeDoc(doc);
+ free(buf);
+ xmlCleanupParser();
+
+ // Check elements.
+ if(tmp) {
+#define MELEMENT(o,s) if(o == 0) WARN("Planet '%s' missing '"s"' element", tmp->name)
+ MELEMENT(tmp->x, "x");
+ MELEMENT(tmp->x, "y");
+ MELEMENT(tmp->class, "class");
+#undef MELEMENT
+ } else
+ WARN("No planet found matching name '%s'", name);
+
+ return tmp;
+}
+
+// Parse node 'parent' which should be the node of a system.
+// Return the StarSystem fully loaded.
+static StarSystem* system_parse(const xmlNodePtr parent) {
+ Planet* planet = NULL;
+ StarSystem* tmp = CALLOC_L(StarSystem);
+ xmlNodePtr cur, node;
+
+ tmp->name = strdup((char*) xmlGetProp(parent, (xmlChar*)"name"));
+
+ node = parent->xmlChildrenNode;
+
+ while((node = node->next)) {
+ // Load all the things!
+ if(strcmp((char*)node->name, "pos")==0) {
+ cur = node->children;
+ while((cur = cur->next)) {
+ if(strcmp((char*)cur->name, "x")==0)
+ tmp->x = atof((char*)cur->children->content);
+ if(strcmp((char*)cur->name, "y")==0)
+ tmp->y = atof((char*)cur->children->content);
+ }
+ }
+ else if(strcmp((char*)node->name, "general")==0) {
+ cur = node->children;
+ while((cur = cur->next)) {
+ if(strcmp((char*)cur->name, "stars")==0)
+ tmp->stars = atoi((char*)cur->children->content);
+ else if(strcmp((char*)cur->name, "asteroids")==0)
+ tmp->asteroids = atoi((char*)cur->children->content);
+ else if(strcmp((char*)cur->name, "interference")==0)
+ tmp->interference = atof((char*)cur->children->content);
+ }
+ }
+ else if(strcmp((char*)node->name, "planets")==0) {
+ cur = node->children;
+ while((cur = cur->next)) {
+ if(strcmp((char*)cur->name, "planet")==0) {
+ planet = planet_get((const char*)cur->children->content);
+ tmp->planets = realloc(tmp->planets, sizeof(Planet)*(++tmp->nplanets));
+ memcpy(tmp->planets+tmp->nplanets-1, planet, sizeof(Planet));
+ free(planet);
+ }
+ }
+ }
+ }
+ // Check elements.
+#define MELEMENT(o,s) if(o == 0) WARN("Star System '%s' missing '"s"' element", tmp->name)
+ MELEMENT(tmp->x, "x");
+ MELEMENT(tmp->x, "y");
+ MELEMENT(tmp->stars, "stars");
+ /*MELEMENT(tmp->asteroids, "asteroids"); // Can be 0.
+ MELEMENT(tmp->interference, "interference");*/
+#undef MELEMENT
+ DEBUG("Loaded Star System '%s' with %d Planets%s", tmp->name, tmp->nplanets, (tmp->nplanets > 1) ? "s" : "");
+
+ return tmp;
+}
+
+// Load the ENTIRE universe into RAM. -- WOAH! -- Wasn't that bad. :P
+int space_load(void) {
+ uint32_t bufsize;
+ char* buf = pack_readfile(DATA, SPACE_DATA, &bufsize);
+
+ StarSystem* tmp;
+
+ xmlNodePtr node;
+ xmlDocPtr doc = xmlParseMemory(buf, bufsize);
+
+ node = doc->xmlChildrenNode;
+ if(strcmp((char*)node->name, XML_SYSTEM_ID)) {
+ ERR("Malformed "SPACE_DATA" file: missing root element '"XML_SYSTEM_ID"'");
+ return -1;
+ }
+ node = node->xmlChildrenNode; // First system node.
+ if(node == NULL) {
+ ERR("Malformed "SPACE_DATA" file: does not contain elements");
+ return -1;
+ }
+ do {
+ if(node->type == XML_NODE_START && strcmp((char*)node->name, XML_SYSTEM_TAG)==0) {
+ if(systems == NULL) {
+ systems = tmp = system_parse(node);
+ nsystems = 1;
+ } else {
+ tmp = system_parse(node);
+ systems = realloc(systems, sizeof(StarSystem)*(++nsystems));
+ memcpy(systems+nsystems-1, tmp, sizeof(StarSystem));
+ free(tmp);
+ }
+ }
+ } while((node = node->next));
+
+ xmlFreeDoc(doc);
+ free(buf);
+ xmlCleanupParser();
+
+ return 0;
+}
+
+// Render the system. -- Just playing god now.
void space_render(double dt) {
int i;
glMatrixMode(GL_PROJECTION);
@@ -51,7 +310,30 @@ void space_render(double dt) {
glPopMatrix(); // Projection translation matrix.
}
-void space_exit(void) {
- free(stars);
+// Render the planets.
+void planets_render(void) {
+ int i;
+ Vec2 v;
+ for(i = 0; i < cur_system->nplanets; i++) {
+ v.x = cur_system->planets[i].x;
+ v.y = cur_system->planets[i].y;
+ gl_blitSprite(cur_system->planets[i].gfx_space, &v, 0, 0);
+ }
+}
+
+// Clean up the system.
+void space_exit(void) {
+ int i,j;
+ for(i = 0; i < nsystems; i++) {
+ free(systems[i].name);
+ for(j = 0; j < systems[i].nplanets; j++) {
+ free(systems[i].planets[j].name);
+ if(systems[i].planets[j].gfx_space)
+ gl_freeTexture(systems[i].planets[j].gfx_space);
+ }
+ free(systems[i].planets);
+ }
+ free(systems);
+ if(stars) free(stars);
}
diff --git a/src/space.h b/src/space.h
index 1314f72..d4f77e9 100644
--- a/src/space.h
+++ b/src/space.h
@@ -1,8 +1,11 @@
#pragma once
-#include "def.h"
-void space_init(void);
+// Load/Exit.
+void space_init(const char* sysname);
+int space_load(void);
void space_exit(void);
+// Render.
void space_render(double dt);
+void planets_render(void);
diff --git a/utils/pack/main.c b/utils/pack/main.c
index db463b0..f92a76f 100644
--- a/utils/pack/main.c
+++ b/utils/pack/main.c
@@ -19,7 +19,7 @@ int main(int argc, char** argv) {
uint32_t nfiles = (uint32_t)argc - 2;
argv += 2;
- pack_files(outfile, argv, nfiles);
+ pack_files(outfile, (const char**)argv, nfiles);
exit(EXIT_SUCCESS);