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); +