diff --git a/.gitignore b/.gitignore index 4131ba3..fe281e9 100644 --- a/.gitignore +++ b/.gitignore @@ -24,5 +24,6 @@ *.tsv *.pdf *bin/Lephisto +*bin/data diff --git a/bin/Makefile b/bin/Makefile index f463fc6..f69e2fd 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -1,11 +1,11 @@ DEBUG = 1 APPNAME = Lephisto -OBJS := ../src/main.o \ - ../src/physics.o \ - ../src/opengl.o \ - ../src/ship.o \ - ../src/pilot.o +OBJS := $(shell find ../src/ -name '*.c' -print) +OBJS := $(OBJS:../src/%.c=../src/%.o) + +DATA = data +DATAFILES = $(shell find ../gfx/ ../dat/ -name '*.png' -o -name '*.xml' -print) CFLAGS = -Wall `sdl-config --cflags` `xml2-config --cflags` ifdef DEBUG @@ -16,29 +16,18 @@ endif 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 '/^<?xml.*/d' ../dat/$@ >> data - %.o: ../src/%.c @gcc -c $(CFLAGS) -o $@ $< @echo -e "\tCC $@" all: data $(OBJS) @gcc $(LDFLAGS) -o $(APPNAME) $(OBJS) - @echo -e "\tLD $(APPNAME)" + @echo "\tLD $(APPNAME)" -data_init: - @echo -e '<?xml version="1.0" encoding="UTF-8"?>\n<Data>' > data - -data: data_init $(DOBJS) - @echo -e '</data>' >> data - @echo -e "\tCreating data\n" +data: $(DATAFILES) + @echo -e "\tCreating data..\n" + @ls -1 $(DATAFILES) | cpio --quiet -o > $(DATA) clean: - rm -rf $(OBJS) $(APPNAME) + @echo -e "\tRemoving data.." + rm -rf $(OBJS) $(APPNAME) $(DATA) diff --git a/bin/data b/bin/data deleted file mode 100644 index f30b048..0000000 --- a/bin/data +++ /dev/null @@ -1,178 +0,0 @@ --e <?xml version="1.0" encoding="UTF-8"?> -<Data> -<Ships> - <ship name="Ship"> - <GFX>../gfx/ship.png</GFX> - <class>1</class> - <movement> - <thrust>240</thrust> - <turn>120</turn> - <speed>360</speed> - </movement> - <health> - <shield>50</shield> - <armor>80</armor> - <energy>240</energy> - <shield_regen>80</shield_regen> - <armor_regen>50</armor_regen> - <energy_regen>40</energy_regen> - </health> - <characteristics> - <crew>2</crew> - <mass>30</mass> - <cap_weapon>20</cap_weapon> - <cap_cargo>20</cap_cargo> - </caracteristics> - <outfits> - <outfit quantity='2'>laser</outfit> - </outfits> - </ship> - <ship name="Mr. Test"> - <GFX>gfx/enemyship.png</GFX> - <class>1</class> - <movement> - <thrust>180</thrust> - <turn>100</turn> - <speed>260</speed> - </movement> - <health> - <shield>160</shield> - <armor>120</armor> - <energy>360</energy> - <shieldregen>90</shieldregen> - <armorregen>60</armorregen> - <energyregen>50</energyregen> - </health> - <characteristics> - <crew>9</crew> - <mass>130</mass> - <cap_weapon>60</cap_weapon> - <cap_cargo>40</cap_cargo> - </caracteristics> - <outfits> - </outfits> - </ship> -</Ships> -<Fleets> - <fleet name="Test"> - <faction>2</faction> - <pilots> - <pilot chance='100'>Mr. Test</pilot> - </pilots> - </fleet> - <fleet name="Merchant Ship"> - <faction>2</faction> - <pilots> - <pilot chance='100'>Ship</pilot> - </pilots> - </fleet> - <fleet name="Sml Merchant Convoy"> - <faction>2</faction> - <pilots> - <pilot chance='80'>Ship</pilot> - <pilot chance='80'>Ship</pilot> - <pilot chance='60'>Ship</pilot> - <pilot chance='60'>Ship</pilot> - </pilots> - </fleet> -</Fleets> -<Outfits> - <outfit name="laser"> - <general> - <max>0</max> - <type>1</type> - <tech>0</tech> - </general> - <sound>laser</sound> - <GFX> - <game>laser_green</game> - </GFX> - <parameters> - <parameter>7</parameter> - <parameter>7</parameter> - <parameter>600</parameter> - <parameter>400</parameter> - <parameter>18</parameter> - <parameter>500</parameter> - </parameters> - </outfit> -</Outfits> -<Planets> - <planet name="KonoSphere"> - <pos> - <x>10</x> - <y>15</y> - </pos> - <general> - <class>1</class> - <services>1</services> - <tech>0</tech> - <commodities>1</commodities> - </general> - <GFX>KonoSphere</GFX> - </planet> - <planet name="SaraCraft"> - <pos> - <x>125</x> - <y>-345</y> - </pos> - <general> - <class>1</class> - <services>1</services> - <tech>0</tech> - <commodities>1</commodities> - </general> - <GFX>SaraCraft</GFX> - </planet> -</Planets> -<Systems> - <ssys name="SaraSys"> - <pos> - <x>15</x> - <y>8</y> - </pos> - <general> - <stars>50</stars> - <asteroids>0</asteroids> - <interference>0</interference> - <faction>2</faction> - </general> - <planets> - <planet>KonoSphere</planet> - </planets> - <fleets> - <fleet chance="100">Test</fleet> - <fleet chance="60">Merchant Ship</fleet> - <fleet chance="50">Merchant Ship</fleet> - <fleet chance="40">Merchant Ship</fleet> - <fleet chance="50">Sml Merchant Convoy</fleet> - <fleet chance="40">Sml Merchant Convoy</fleet> - </fleets> - <paths> - <path>KonoSys</path> - </paths> -</ssys> - <ssys name="KonoSys"> - <pos> - <x>47</x> - <y>33</y> - </pos> - <general> - <stars>27</stars> - <asteroids>0</asteroids> - <interference>0</interference> - <faction>2</faction> - </general> - <planets> - <planet>SaraCraft</planet> - </planets> - <fleets> - <fleet chance="80">Merchant Ship</fleet> - <fleet chance="60">Merchant Ship</fleet> - </fleets> - <paths> - <path>SaraSys</path> - </paths> - </ssys> -</Systems> --e </data> diff --git a/dat/ship.xml b/dat/ship.xml index 28d6a4c..fe51cb9 100644 --- a/dat/ship.xml +++ b/dat/ship.xml @@ -4,8 +4,8 @@ <GFX>../gfx/ship.png</GFX> <class>1</class> <movement> - <thrust>240</thrust> - <turn>120</turn> + <thrust>400</thrust> + <turn>960</turn> <speed>360</speed> </movement> <health> @@ -18,7 +18,7 @@ </health> <characteristics> <crew>2</crew> - <mass>30</mass> + <mass>7</mass> <cap_weapon>20</cap_weapon> <cap_cargo>20</cap_cargo> </caracteristics> @@ -26,7 +26,7 @@ <outfit quantity='2'>laser</outfit> </outfits> </ship> - <ship name="Mr. Test"> + <ship name="Miss. Test"> <GFX>gfx/enemyship.png</GFX> <class>1</class> <movement> @@ -52,3 +52,4 @@ </outfits> </ship> </Ships> + diff --git a/gfx/ship/enemyship.png b/gfx/ship/enemyship.png new file mode 100644 index 0000000..2d45128 Binary files /dev/null and b/gfx/ship/enemyship.png differ diff --git a/gfx/ship/ship.png b/gfx/ship/ship.png new file mode 100644 index 0000000..4c845ef Binary files /dev/null and b/gfx/ship/ship.png differ diff --git a/src/joystick.c b/src/joystick.c new file mode 100644 index 0000000..a402beb --- /dev/null +++ b/src/joystick.c @@ -0,0 +1,27 @@ +#include <SDL.h> +#include "def.h" +#include "log.h" +#include "joystick.h" + +static SDL_Joystick* joystick; + +int joystick_init(void) { + int indjoystick, numjoysticks, i; + indjoystick = 1; + + // Init the SDL subsys. + SDL_InitSubSystem(SDL_INIT_JOYSTICK); + + // Figure out how many joysticks there are. + numjoysticks = SDL_NumJoysticks(); + LOG("%d joysticks detected", numjoysticks); + for(i = 0; i < numjoysticks; i++) + LOG("\t\t%d. %s", i, SDL_JoystickName(i)); + + // Start using that bitch. + LOG("Using joystick %d", indjoystick); + joystick = SDL_JoystickOpen(indjoystick); + + return 0; +} + diff --git a/src/joystick.h b/src/joystick.h new file mode 100644 index 0000000..d2081c1 --- /dev/null +++ b/src/joystick.h @@ -0,0 +1,2 @@ +int joystick_init(void); + diff --git a/src/main.c b/src/main.c index 67dd15b..796954c 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,5 @@ #include <SDL.h> #include <stdlib.h> -#include <math.h> #include "def.h" #include "log.h" @@ -8,10 +7,14 @@ #include "physics.h" #include "opengl.h" #include "ship.h" +#include "player.h" +#include "joystick.h" #include "pilot.h" static int quit = 0; +static unsigned int time = 0; + // Prototypes. static void handle_keydown(SDLKey key); static void handle_keyup(SDLKey key); @@ -32,9 +35,22 @@ int main(int argc, const char** argv) { exit(EXIT_FAILURE); } + // Input. + if(joystick_init()) + WARN("Error initializing joystick input"); + // Data loading. ships_load(); + // Testing. + unsigned int player_id; + player_id = pilot_create(get_ship("Ship"), "Player", NULL, NULL, PILOT_PLAYER); + gl_bindCamera(&get_pilot(player_id)->solid->pos); + + pilot_create(get_ship("Miss. Test"), NULL, NULL, NULL, 0); + + time = SDL_GetTicks(); + // Main looops. while(!quit) { // Event loop. @@ -54,6 +70,7 @@ int main(int argc, const char** argv) { update_all(); } // Unload data. + pilots_free(); ships_free(); gl_exit(); // Kills video output. exit(EXIT_SUCCESS); @@ -65,6 +82,18 @@ static void handle_keydown(SDLKey key) { case SDLK_ESCAPE: quit = 1; break; + case SDLK_a: + case SDLK_LEFT: + player_setFlag(PLAYER_FLAG_MOV_LEFT); + break; + case SDLK_d: + case SDLK_RIGHT: + player_setFlag(PLAYER_FLAG_MOV_RIGHT); + break; + case SDLK_w: + case SDLK_UP: + player_setFlag(PLAYER_FLAG_MOV_ACC); + break; default: break; } @@ -73,14 +102,34 @@ static void handle_keydown(SDLKey key) { // Handle keyup events. static void handle_keyup(SDLKey key) { switch(key) { + case SDLK_a: + case SDLK_LEFT: + player_rmFlag(PLAYER_FLAG_MOV_LEFT); + break; + case SDLK_d: + case SDLK_RIGHT: + player_rmFlag(PLAYER_FLAG_MOV_RIGHT); + break; + case SDLK_w: + case SDLK_UP: + player_rmFlag(PLAYER_FLAG_MOV_ACC); + break; default: break; } } // Update all the things. +// Pilots: +// -- Think (ai). +// -- Solid. static void update_all(void) { + FP dt = (FP)(SDL_GetTicks() - time) / 1000.0; + time = SDL_GetTicks(); glClear(GL_COLOR_BUFFER_BIT); + + pilots_update(dt); + SDL_GL_SwapBuffers(); } diff --git a/src/physics.c b/src/physics.c index 1db4525..d5cf44f 100644 --- a/src/physics.c +++ b/src/physics.c @@ -22,8 +22,12 @@ // Since dt isn't actually differential this gives us an // error, so watch out with big values for dt. // ======================================================== - +#if 0 static void simple_update(Solid* obj, const FP dt) { + // Make sure angle doesn't flip. + obj->dir += obj->dir_vel/360.0*dt; + if(obj->dir > 2*M_PI) obj->dir -= 2*M_PI; + if(obj->dir < 0.0) obj->dir += 2*M_PI; if(obj->force) { Vec2 acc; acc.x = obj->force / obj->mass * COS(obj->dir); @@ -32,13 +36,14 @@ static void simple_update(Solid* obj, const FP dt) { obj->pos.x += acc.x * dt; obj->vel.y += acc.y * dt; - obj->pos.x += obj->vel.x * dt + 0.5 * acc.x / obj->mass * dt * dt; - obj->pos.y += obj->vel.y * dt + 0.5 * acc.y / obj->mass * dt * dt; + obj->pos.x += obj->vel.x * dt + 0.5 * acc.x * dt*dt; + obj->pos.y += obj->vel.y * dt + 0.5 * acc.y * dt*dt; } else { obj->pos.x += obj->vel.x * dt; obj->pos.y += obj->vel.y * dt; } } +#endif // ==Runge-Kutta 4th method.=============================== // d^2 x(t) / d t^2 = a, a = constant(acceleration) @@ -57,6 +62,11 @@ static void simple_update(Solid* obj, const FP dt) { #define RK4_N 4 static void rk4_update(Solid* obj, const FP dt) { + // Make sure angle doesn't flip. + obj->dir += obj->dir_vel/360.0*dt; + if(obj->dir > 2*M_PI) obj->dir -= 2*M_PI; + if(obj->dir < 0.0) obj->dir += 2*M_PI; + FP h = dt / RK4_N; // Step. if(obj->force) { // Force applied on object. diff --git a/src/physics.h b/src/physics.h index 5c6b34f..032ee4e 100644 --- a/src/physics.h +++ b/src/physics.h @@ -8,7 +8,7 @@ typedef struct { // Describe any solid in 2D space. struct Solid { - FP mass, force, dir; // Properties. + FP mass, force, dir, dir_vel; // Properties. Vec2 vel, pos; // Position/velocity vectors. void(*update)(struct Solid*, const FP); // Update method. }; diff --git a/src/pilot.c b/src/pilot.c index 9da617d..f39eaa8 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -1,17 +1,38 @@ +#include <string.h> #include <math.h> #include <stdlib.h> #include <assert.h> + +#include "log.h" #include "pilot.h" // 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 Pilot** pilot_stack; +static int pilots = 0; +extern void player_think(Pilot* pilot, const FP dt); // Player. static void pilot_update(Pilot* pilot, const FP dt); static void pilot_render(Pilot* pilot); +// Pull a pilot out of the pilot_stack based on id. +Pilot* get_pilot(unsigned int id) { + // Regular search. +#if 0 + for(int i = 0; i < pilots; i++) + if(pilot_stack[i]->id == id) + return pilot_stack[i]; + return NULL; +#endif + // Dichotomical search. + int i, n; + for(i = 0, n = pilots/2; n > 0; n /= 2) + i += (pilot_stack[i+n]->id > id) ? 0 : n; + return (pilot_stack[i]->id == id) ? pilot_stack[i] : NULL; +} + // Render the pilot. static void pilot_render(Pilot* pilot) { int sprite; @@ -46,13 +67,11 @@ static void pilot_update(Pilot* pilot, const FP dt) { // flags : Tweaking the pilot. // ======================================================== void pilot_init(Pilot* pilot, Ship* ship, char* name, const Vec2* vel, const Vec2* pos, const int flags) { - pilot->id = pilot_id++; // New unique pilot id based on pilot_id. - + pilot->id = ++pilot_id; // New unique pilot id based on pilot_id, Can't be 0. + pilot->ship = ship; - if(name == NULL) - pilot->name = ship->name; - else - pilot->name = name; + + pilot->name = strdup((name == NULL) ? ship->name:name); pilot->solid = solid_create(ship->mass, vel, pos); @@ -60,24 +79,48 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, const Vec2* vel, const Vec pilot->shield = ship->shield; pilot->energy = ship->energy; - if(flags & PILOT_PLAYER) - pilot->think = NULL; // Players don't need to thing! :P + if(flags & PILOT_PLAYER) { + pilot->think = (void*)player_think; // Players don't need to thing! :P + pilot->think = NULL; + } else + pilot->think = NULL; pilot->update = pilot_update; } -// Create a new pilot - Params are same as pilot_init. -Pilot* pilot_create(Ship* ship, char* name, const Vec2* vel, const Vec2* pos, const int flags) { +// Create a new pilot - Params are same as pilot_init. Return pilot's id. +unsigned int pilot_create(Ship* ship, char* name, const Vec2* vel, const Vec2* pos, const int flags) { Pilot* dyn = MALLOC_L(Pilot); - assert(dyn != NULL); + if(dyn == NULL) { + WARN("Unable to allocate memory."); + return 0; + } pilot_init(dyn, ship, name, vel, pos, flags); - return dyn; + + // Add to the stack. + pilot_stack = realloc(pilot_stack, ++pilots*sizeof(Pilot*)); + pilot_stack[pilots-1] = dyn; + return dyn->id; } // Free the prisoned pilot! -void pilot_free(Pilot* pilot) { - solid_free(pilot->solid); - free(pilot); - pilot = NULL; +void pilots_free(void) { + int i; + for(i = 0; i < pilots; i++) { + solid_free(pilot_stack[i]->solid); + free(pilot_stack[i]->name); + free(pilot_stack[i]); + } + free(pilot_stack); +} + +// Update all pilots. +void pilots_update(FP dt) { + int i; + for(i = pilots-1; i >= 0; i--) { + if(pilot_stack[i]->think != NULL) + pilot_stack[i]->think(pilot_stack[i]); + pilot_stack[i]->update(pilot_stack[i], dt); + } } diff --git a/src/pilot.h b/src/pilot.h index 21b2d71..5f101ef 100644 --- a/src/pilot.h +++ b/src/pilot.h @@ -6,8 +6,7 @@ #define PILOT_PLAYER 1 // Pilot is a player. struct Pilot { - struct Pilot* next; - int id; // Pilot's id. + unsigned int id; // Pilots id. char* name; // Pilot's name (if unique). Ship* ship; // Pilots ship. @@ -19,15 +18,22 @@ struct Pilot { void (*update)(struct Pilot*, const FP); // Update the pilot. void (*think)(struct Pilot*); // AI thinking for the pilot. - unsigned int flags; // Used for AI etc. + unsigned int properties; // Used for AI etc. }; typedef struct Pilot Pilot; +Pilot* get_pilot(unsigned int id); + +// Creation. void pilot_init(Pilot* dest, Ship* ship, char* name, const Vec2* vel, const Vec2* pos, const int flags); -Pilot* pilot_create(Ship* ship, char* name, const Vec2* vel, +unsigned int pilot_create(Ship* ship, char* name, const Vec2* vel, const Vec2* pos, const int flags); -void pilot_free(Pilot* src); +// Cleanup. +void pilot_free(void); + +// Update. +void pilots_update(FP dt); diff --git a/src/player.c b/src/player.c new file mode 100644 index 0000000..3123e82 --- /dev/null +++ b/src/player.c @@ -0,0 +1,33 @@ +#include "def.h" +#include "pilot.h" +#include "log.h" +#include "player.h" + +static unsigned int player_flags = PLAYER_FLAG_NULL; + +// To be used in pilot.c +void player_think(Pilot* player, const FP dt) { + player->solid->dir_vel = 0.0; + if(player_isFlag(PLAYER_FLAG_MOV_LEFT)) + player->solid->dir_vel += player->ship->turn; + if(player_isFlag(PLAYER_FLAG_MOV_RIGHT)) + player->solid->dir_vel -= player->ship->turn; + + player->solid->force = (player_isFlag(PLAYER_FLAG_MOV_ACC)) ? player->ship->thrust : 0.0; +} + +// Flag manipulationz. +int player_isFlag(unsigned int flag) { + return player_flags & flag; +} + +void player_setFlag(unsigned int flag) { + if(!player_isFlag(flag)) + player_flags |= flag; +} + +void player_rmFlag(unsigned int flag) { + if(player_isFlag(flag)) + player_flags ^= flag; +} + diff --git a/src/player.h b/src/player.h new file mode 100644 index 0000000..fe98097 --- /dev/null +++ b/src/player.h @@ -0,0 +1,11 @@ +#pragma once + +#define PLAYER_FLAG_NULL (1<<0) +#define PLAYER_FLAG_MOV_LEFT (1<<1) +#define PLAYER_FLAG_MOV_RIGHT (1<<2) +#define PLAYER_FLAG_MOV_ACC (1<<3) + +int player_isFlag(unsigned int flag); +void player_setFlag(unsigned int flag); +void player_rmFlag(unsigned int flag); + diff --git a/src/ship.c b/src/ship.c index 1b3e23f..197b16e 100644 --- a/src/ship.c +++ b/src/ship.c @@ -4,6 +4,8 @@ #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 @@ -12,22 +14,28 @@ #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; - while(tmp != NULL) - if(strcmp((tmp++)->name, name)==0) break; + int i; + for(i = 0; i < ships; i++) + if(strcmp((tmp+i)->name, name)==0) break; - return tmp; + 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; @@ -35,8 +43,10 @@ Ship* ship_parse(xmlNodePtr node) { while((node = node->next)) { if(strcmp((char*)node->name, "GFX")==0) { cur = node->children; - if(strcmp((char*)cur->name, "text")==0) + if(strcmp((char*)cur->name, "text")==0) { + snprintf(str, sizeof(cur->content)+4, "../gfx/%s", (char*)cur->content); tmp->gfx_ship = gl_newSprite((char*)cur->content, 6, 6); + } } else if(strcmp((char*)node->name, "class")==0) { cur = node->children; @@ -85,6 +95,8 @@ Ship* ship_parse(xmlNodePtr node) { } } } + tmp->thrust *= tmp->mass; // Helps keep number sane. + DEBUG("Loaded ship '%s'", tmp->name); return tmp; } diff --git a/utils/pack/Makefile b/utils/pack/Makefile new file mode 100644 index 0000000..c7de177 --- /dev/null +++ b/utils/pack/Makefile @@ -0,0 +1,4 @@ +CFLAGS += -g + +all: + $(CC) $(CFLAGS) -o pack pack.c \ No newline at end of file diff --git a/utils/pack/pack b/utils/pack/pack new file mode 100755 index 0000000..2404313 Binary files /dev/null and b/utils/pack/pack differ diff --git a/utils/pack/pack.c b/utils/pack/pack.c new file mode 100644 index 0000000..f2ab738 --- /dev/null +++ b/utils/pack/pack.c @@ -0,0 +1,75 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <fcntl.h> // creat() and co. +#include <sys/stat.h> // S_IRUSR +#include <unistd.h> +#include <errno.h> +#include <string.h> + +#define USAGE "Usage: %s output input\n", argv[0] +#define PERMS S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH + +const uint64_t magic = 0x25524573; // sER% + +off_t getfilesize(const char* filename); +int fileexists(const char* filename); + +int main(int argc, char** argv) { + switch(argc) { + case 1: + printf("Missing output file\n"); + case 2: + printf("Missing input file/s\n\n"); + goto usage; + break; + } + + int i, namesize; + int outfd, infd; + uint32_t nfiles = (uint32_t)argc - 2; + + for(namesize = 0; i < nfiles; i++) { + // Make sure file exists before writing. + if(!fileexists(argv[i+2])) { + printf("File %s does not exist!\n", argv[i+2]); + goto failure; + } + namesize += strlen(argv[i+2]); + } + + // Create the output file. + outfd = creat(argv[1], PERMS); + if(outfd == -1) goto failure; + + // Magic number. + write(outfd, &magic, sizeof(magic)); + + close(outfd); + + exit(EXIT_SUCCESS); + +usage: + printf(USAGE); +failure: + exit(EXIT_FAILURE); +} + +// Grab file size. +off_t getfilesize(const char* filename) { + struct stat file; + if(!stat(filename, &file)) + return file.st_size; + + printf("Unable to get filesize of %s\n", filename); + return 0; +} + +// Does the file exist? +int fileexists(const char* filename) { + struct stat file; + if(!stat(filename, &file)) + return 1; + return 0; +} +