diff --git a/bin/Makefile b/bin/Makefile
index c9a0063..f463fc6 100644
--- a/bin/Makefile
+++ b/bin/Makefile
@@ -1,26 +1,44 @@
DEBUG = 1
APPNAME = Lephisto
-OBJ := ../src/main.o \
+OBJS := ../src/main.o \
../src/physics.o \
../src/opengl.o \
../src/ship.o \
../src/pilot.o
-CFLAGS = -Wall `sdl-config --cflags`
+CFLAGS = -Wall `sdl-config --cflags` `xml2-config --cflags`
ifdef DEBUG
CFLAGS += -g3 -DDEBUG
else
CFLAGS += -O2
endif
-LDFLAGS = -lm `sdl-config --libs` -lSDL_image -lGL
+LDFLAGS = -lm `sdl-config --libs` `xml2-config --libs` -lSDL_image -lGL
+
+DOBJS = ship.xml \
+ fleet.xml \
+ outfit.xml \
+ planet.xml \
+ ssys.xml
+
+%.xml:
+ @sed -e '/^> data
%.o: ../src/%.c
- gcc -c $(CFLAGS) -o $@ $<
+ @gcc -c $(CFLAGS) -o $@ $<
+ @echo -e "\tCC $@"
-all: $(OBJ)
- gcc $(LDFLAGS) -o $(APPNAME) $(OBJ)
+all: data $(OBJS)
+ @gcc $(LDFLAGS) -o $(APPNAME) $(OBJS)
+ @echo -e "\tLD $(APPNAME)"
+
+data_init:
+ @echo -e '\n' > data
+
+data: data_init $(DOBJS)
+ @echo -e '' >> data
+ @echo -e "\tCreating data\n"
clean:
- rm -rf $(OBJ) $(APPNAME)
+ rm -rf $(OBJS) $(APPNAME)
diff --git a/bin/data b/bin/data
new file mode 100644
index 0000000..f30b048
--- /dev/null
+++ b/bin/data
@@ -0,0 +1,178 @@
+-e
+
+
+
+ ../gfx/ship.png
+ 1
+
+ 240
+ 120
+ 360
+
+
+ 50
+ 80
+ 240
+ 80
+ 50
+ 40
+
+
+ 2
+ 30
+ 20
+ 20
+
+
+ laser
+
+
+
+ gfx/enemyship.png
+ 1
+
+ 180
+ 100
+ 260
+
+
+ 160
+ 120
+ 360
+ 90
+ 60
+ 50
+
+
+ 9
+ 130
+ 60
+ 40
+
+
+
+
+
+
+
+ 2
+
+ Mr. Test
+
+
+
+ 2
+
+ Ship
+
+
+
+ 2
+
+ Ship
+ Ship
+ Ship
+ Ship
+
+
+
+
+
+
+ 0
+ 1
+ 0
+
+ laser
+
+ laser_green
+
+
+ 7
+ 7
+ 600
+ 400
+ 18
+ 500
+
+
+
+
+
+
+ 10
+ 15
+
+
+ 1
+ 1
+ 0
+ 1
+
+ KonoSphere
+
+
+
+ 125
+ -345
+
+
+ 1
+ 1
+ 0
+ 1
+
+ SaraCraft
+
+
+
+
+
+ 15
+ 8
+
+
+ 50
+ 0
+ 0
+ 2
+
+
+ KonoSphere
+
+
+ Test
+ Merchant Ship
+ Merchant Ship
+ Merchant Ship
+ Sml Merchant Convoy
+ Sml Merchant Convoy
+
+
+ KonoSys
+
+
+
+
+ 47
+ 33
+
+
+ 27
+ 0
+ 0
+ 2
+
+
+ SaraCraft
+
+
+ Merchant Ship
+ Merchant Ship
+
+
+ SaraSys
+
+
+
+-e
diff --git a/dat/faction.xml b/dat/faction.xml
new file mode 100644
index 0000000..77c3ea9
--- /dev/null
+++ b/dat/faction.xml
@@ -0,0 +1,22 @@
+
+
+
+ Player
+
+
+ Noob Merchant
+
+ '3'
+
+
+
+
+
+ Pirate
+
+ 2
+
+
+
+
+
diff --git a/dat/fleet.xml b/dat/fleet.xml
new file mode 100644
index 0000000..a95ab57
--- /dev/null
+++ b/dat/fleet.xml
@@ -0,0 +1,24 @@
+
+
+
+ 2
+
+ Mr. Test
+
+
+
+ 2
+
+ Ship
+
+
+
+ 2
+
+ Ship
+ Ship
+ Ship
+ Ship
+
+
+
diff --git a/dat/outfit.xml b/dat/outfit.xml
new file mode 100644
index 0000000..e597fa0
--- /dev/null
+++ b/dat/outfit.xml
@@ -0,0 +1,22 @@
+
+
+
+
+ 0
+ 1
+ 0
+
+ laser
+
+ laser_green
+
+
+ 7
+ 7
+ 600
+ 400
+ 18
+ 500
+
+
+
diff --git a/dat/planet.xml b/dat/planet.xml
new file mode 100644
index 0000000..34d4d29
--- /dev/null
+++ b/dat/planet.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ 10
+ 15
+
+
+ 1
+ 1
+ 0
+ 1
+
+ KonoSphere
+
+
+
+ 125
+ -345
+
+
+ 1
+ 1
+ 0
+ 1
+
+ SaraCraft
+
+
diff --git a/dat/ship.xml b/dat/ship.xml
new file mode 100644
index 0000000..28d6a4c
--- /dev/null
+++ b/dat/ship.xml
@@ -0,0 +1,54 @@
+
+
+
+ ../gfx/ship.png
+ 1
+
+ 240
+ 120
+ 360
+
+
+ 50
+ 80
+ 240
+ 80
+ 50
+ 40
+
+
+ 2
+ 30
+ 20
+ 20
+
+
+ laser
+
+
+
+ gfx/enemyship.png
+ 1
+
+ 180
+ 100
+ 260
+
+
+ 160
+ 120
+ 360
+ 90
+ 60
+ 50
+
+
+ 9
+ 130
+ 60
+ 40
+
+
+
+
+
diff --git a/dat/ssys.xml b/dat/ssys.xml
new file mode 100644
index 0000000..85fdb37
--- /dev/null
+++ b/dat/ssys.xml
@@ -0,0 +1,51 @@
+
+
+
+
+ 15
+ 8
+
+
+ 50
+ 0
+ 0
+ 2
+
+
+ KonoSphere
+
+
+ Test
+ Merchant Ship
+ Merchant Ship
+ Merchant Ship
+ Sml Merchant Convoy
+ Sml Merchant Convoy
+
+
+ KonoSys
+
+
+
+
+ 47
+ 33
+
+
+ 27
+ 0
+ 0
+ 2
+
+
+ SaraCraft
+
+
+ Merchant Ship
+ Merchant Ship
+
+
+ SaraSys
+
+
+
diff --git a/gfx/enemyship.png b/gfx/enemyship.png
new file mode 100644
index 0000000..2d45128
Binary files /dev/null and b/gfx/enemyship.png differ
diff --git a/src/def.h b/src/def.h
index d90f00b..9b0e851 100644
--- a/src/def.h
+++ b/src/def.h
@@ -1,6 +1,9 @@
#pragma once
#define MALLOC_L(type)(malloc(sizeof(type)))
+#define CALLOC_L(type)(calloc(1, sizeof(type)))
typedef float FP;
+#define DATA "data"
+
diff --git a/src/log.h b/src/log.h
index 58d599f..0e3acf7 100644
--- a/src/log.h
+++ b/src/log.h
@@ -1,8 +1,9 @@
#pragma once
+#include
#include
#define LOG(str, args...)(fprintf(stdout, str"\n", ## args))
-#define WARN(str, args...)(fprintf(stderr, "[%d] "str"\n", 0, ## args))
+#define WARN(str, args...)(fprintf(stderr, "[%d] "str"\n", SDL_GetTicks(), ## args))
#ifdef DEBUG
# undef DEBUG
diff --git a/src/main.c b/src/main.c
index e1a4d34..67dd15b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -10,86 +10,77 @@
#include "ship.h"
#include "pilot.h"
+static int quit = 0;
+
+// Prototypes.
+static void handle_keydown(SDLKey key);
+static void handle_keyup(SDLKey key);
+
+// Update.
+static void update_all(void);
+
int main(int argc, const char** argv) {
- int quit = 0;
SDL_Event event;
+ // Default window params.
gl_screen.w = 800;
gl_screen.h = 640;
gl_screen.fullscreen = 0;
-
- gl_init();
-
- gl_texture* tex;
- if((tex = gl_newSprite("../gfx/ship.png", 6, 6)) == NULL) {
- WARN("Unable to load image");
- return -1;
+ if(gl_init()) {
+ // Initializes video output.
+ WARN("Error initializing video output, exiting...");
+ exit(EXIT_FAILURE);
}
- Ship* ship = MALLOC_L(Ship);
- ship->gfx_ship = tex;
- ship->mass = 1;
- ship->class = SHIP_CLASS_CIVILIAN;
- Pilot* player = pilot_create(ship, "player", NULL, NULL, PILOT_PLAYER);
- gl_bindCamera(&player->solid->pos);
- int tflag = 0;
- unsigned int time = SDL_GetTicks();
- FP dt;
+ // Data loading.
+ ships_load();
+
+ // Main looops.
while(!quit) {
+ // Event loop.
while(SDL_PollEvent(&event)) {
switch(event.type) {
- case SDL_KEYDOWN:
- switch(event.key.keysym.sym) {
- case SDLK_ESCAPE:
- quit = 1;
- break;
- case SDLK_a:
- tflag ^= 1;
- break;
- case SDLK_d:
- tflag ^=2;
- case SDLK_w:
- tflag ^= 8;
- break;
- default:
- break;
- }
- break;
- case SDL_KEYUP:
- switch(event.key.keysym.sym) {
- case SDLK_a:
- tflag ^= 1;
- break;
- case SDLK_d:
- tflag ^= 2;
- break;
- case SDLK_w:
- tflag ^= 8;
- break;
- default:
- break;
- }
- break;
+ case SDL_KEYDOWN:
+ handle_keydown(event.key.keysym.sym);
+ break;
+ case SDL_KEYUP:
+ handle_keyup(event.key.keysym.sym);
+ break;
+ case SDL_QUIT:
+ quit = 1;
+ break;
}
}
- dt = (FP)(SDL_GetTicks() - time) / 1000.0;
- if(tflag & 1) player->solid->dir += 200.0 / 180.0*M_PI*dt;
- if(tflag & 2) player->solid->dir -= 200.0 / 180.0*M_PI*dt;
- if(tflag & 8) player->solid->force = 340;
- else player->solid->force = 0;
- glClear(GL_COLOR_BUFFER_BIT);
- player->update(player, dt);
- SDL_GL_SwapBuffers();
- time = SDL_GetTicks();
- SDL_Delay(5);
+ update_all();
}
-
- pilot_free(player);
- free(ship);
- gl_free(tex);
-
- gl_exit();
-
- return 0;
+ // Unload data.
+ ships_free();
+ gl_exit(); // Kills video output.
+ exit(EXIT_SUCCESS);
+}
+
+// Handle keydown events.
+static void handle_keydown(SDLKey key) {
+ switch(key) {
+ case SDLK_ESCAPE:
+ quit = 1;
+ break;
+ default:
+ break;
+ }
+}
+
+// Handle keyup events.
+static void handle_keyup(SDLKey key) {
+ switch(key) {
+ default:
+ break;
+ }
+}
+
+// Update all the things.
+static void update_all(void) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ SDL_GL_SwapBuffers();
}
diff --git a/src/opengl.c b/src/opengl.c
index 78b8cd6..fff296f 100644
--- a/src/opengl.c
+++ b/src/opengl.c
@@ -62,18 +62,21 @@ gl_texture* gl_newImage(const char* path) {
tmp = IMG_Load(path); // Load the surface.
if(tmp == 0) {
WARN("'%s' could not be opened: %s", path, IMG_GetError());
- return 0;
+ return NULL;
}
surface = SDL_DisplayFormatAlpha(tmp); // Set the surface to what we use.
if(surface == 0) {
WARN("Error converting image to screen format: %s", SDL_GetError());
- return 0;
+ return NULL;
}
SDL_FreeSurface(tmp); // Free the temp surface.
- flip_surface(surface);
+ if(flip_surface(surface)) {
+ WARN("Error flipping surface");
+ return NULL;
+ }
// Set up the texture defaults.
gl_texture* texture = MALLOC_L(gl_texture);
@@ -117,11 +120,11 @@ gl_texture* gl_newImage(const char* path) {
texture->rw, texture->rh, surface->format->BytesPerPixel*8, RGBMASK);
if(tmp == NULL) {
WARN("Unable to create POT surface %s", SDL_GetError());
- return 0;
+ return NULL;
}
if(SDL_FillRect(tmp, NULL, SDL_MapRGBA(surface->format, 0, 0, 0, SDL_ALPHA_TRANSPARENT))) {
WARN("Unable to fill rect: %s", SDL_GetError());
- return 0;
+ return NULL;
}
SDL_BlitSurface(surface, &rtemp, tmp, &rtemp);
@@ -181,8 +184,8 @@ void gl_blitSprite(gl_texture* sprite, Vec2* pos, const int sx, const int sy) {
glMatrixMode(GL_PROJECTION);
glPushMatrix(); // Projection translation matrix.
- glTranslatef(gl_camera->x - pos->x - sprite->sw / 2.0,
- gl_camera->y - pos->y - sprite->sh/2.0, 0.0f);
+ glTranslatef(pos->x - gl_camera->x - sprite->sw/2.0,
+ pos->y - gl_camera->y - sprite->sh/2.0, 0.0f);
// Actual blitting....
glBindTexture(GL_TEXTURE_2D, sprite->texture);
@@ -204,7 +207,7 @@ void gl_blitSprite(gl_texture* sprite, Vec2* pos, const int sx, const int sy) {
}
// Just straight out blit the thing at position.
-void gl_blit(gl_texture* texture, Vec2* pos) {
+void gl_blitStatic(gl_texture* texture, Vec2* pos) {
glMatrixMode(GL_PROJECTION);
glPushMatrix(); // Set up translation matrix.
glTranslatef(pos->x, pos->y, 0);
@@ -242,7 +245,8 @@ int gl_init(void) {
}
// FFUUUU Ugly cursor thing.
- SDL_ShowCursor(SDL_DISABLE);
+ // -- Ok, Maybe for now.
+ //SDL_ShowCursor(SDL_DISABLE);
flags |= SDL_FULLSCREEN* gl_screen.fullscreen;
depth = SDL_VideoModeOK(gl_screen.w, gl_screen.h, gl_screen.depth, flags); // Test set up.
@@ -297,7 +301,7 @@ int gl_init(void) {
// Clean up our mess.
void gl_exit(void) {
- SDL_ShowCursor(SDL_ENABLE);
+ //SDL_ShowCursor(SDL_ENABLE);
SDL_Quit();
}
diff --git a/src/opengl.h b/src/opengl.h
index 0a86287..1d41a24 100644
--- a/src/opengl.h
+++ b/src/opengl.h
@@ -31,7 +31,7 @@ void gl_free(gl_texture* texture);
// Rendering.
void gl_blitSprite(gl_texture* sprite, Vec2* pos, const int sx, const int sy);
-void gl_blit(gl_texture* texture, Vec2* pos);
+void gl_blitStatic(gl_texture* texture, Vec2* pos);
void gl_bindCamera(Vec2* pos);
// Initialize/cleanup.
diff --git a/src/pilot.c b/src/pilot.c
index f4787ae..9da617d 100644
--- a/src/pilot.c
+++ b/src/pilot.c
@@ -6,6 +6,9 @@
// Stack of pilot id's to assure uniqueness.
static unsigned int pilot_id = 0;
+// Stack of pilots - yes, they come in stacks now.
+static Pilot* pilot_stack = NULL;
+
static void pilot_update(Pilot* pilot, const FP dt);
static void pilot_render(Pilot* pilot);
diff --git a/src/pilot.h b/src/pilot.h
index 16c6a14..21b2d71 100644
--- a/src/pilot.h
+++ b/src/pilot.h
@@ -6,6 +6,7 @@
#define PILOT_PLAYER 1 // Pilot is a player.
struct Pilot {
+ struct Pilot* next;
int id; // Pilot's id.
char* name; // Pilot's name (if unique).
diff --git a/src/ship.c b/src/ship.c
index 77e2920..1b3e23f 100644
--- a/src/ship.c
+++ b/src/ship.c
@@ -1,2 +1,140 @@
+#include
+#include "libxml/xmlreader.h"
+
+#include "log.h"
#include "ship.h"
+#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"
+
+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;
+ while(tmp != NULL)
+ if(strcmp((tmp++)->name, name)==0) break;
+
+ return tmp;
+}
+
+Ship* ship_parse(xmlNodePtr node) {
+ xmlNodePtr cur;
+ Ship* tmp = CALLOC_L(Ship);
+
+ 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)
+ tmp->gfx_ship = gl_newSprite((char*)cur->content, 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);
+ }
+ }
+ }
+ DEBUG("Loaded ship '%s'", tmp->name);
+ return tmp;
+}
+
+int ships_load(void) {
+ xmlTextReaderPtr reader;
+ xmlNodePtr node;
+ Ship* tmp = NULL;
+
+ if((reader == xmlNewTextReaderFilename(DATA)) == NULL) {
+ WARN("XML error reading " 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_free((ship_stack+i)->gfx_ship);
+ }
+ free(ship_stack);
+ ship_stack = NULL;
+}
+
diff --git a/src/ship.h b/src/ship.h
index ee3db4f..ce1600d 100644
--- a/src/ship.h
+++ b/src/ship.h
@@ -28,3 +28,8 @@ typedef struct {
int cap_cargo, cap_weapon;
} Ship;
+int ships_load(void);
+void ships_free(void);
+
+Ship* get_ship(const char* name);
+