Streamline the archive loading mechanism
authorThomas Perl <thp@thpinfo.com>
Sat, 13 Feb 2010 15:23:14 +0000 (13 16:23 +0100)
committerThomas Perl <thp@thpinfo.com>
Sat, 13 Feb 2010 15:23:14 +0000 (13 16:23 +0100)
Only load the archive once (in the main function)
and pass a reference to the archive object to the
initialization functions for graphics, sound and
input (which will read the data from the archive).

13 files changed:
archive.cc
archive.hh
archivetool.cc
graphics.cc
graphics.h
input.c
input.h
makefile
sound.cc
sound.h
tennix.cc [moved from tennix.c with 99% similarity]
tennixpy.cc
tennixpy.h

index fb435c9..5546173 100644 (file)
@@ -21,6 +21,7 @@
  *
  **/
 
+#include <iostream>
 
 #include <libgen.h>
 #include <stdio.h>
 
 #include "archive.hh"
 
-TennixArchive::TennixArchive(const char* filename)
+TennixArchive::TennixArchive(const char* filename, const char* fallback)
 {
     fp = fopen(filename, "rb");
+    if (fp == NULL && fallback != NULL) {
+        fp = fopen(fallback, "rb");
+    }
     assert(fp != NULL);
 
     offset = sizeof(TennixArchiveHeader)*fread(&(header), sizeof(TennixArchiveHeader), 1, fp);
@@ -65,23 +69,28 @@ TennixArchive::TennixArchive(const char* filename)
     building = 0;
 }
 
+std::ostream&
+operator<<(std::ostream& out, TennixArchiveHeader& header)
+{
+    out << "Header: " << header.header << std::endl;
+    out << "Version: " <<
+        (int)header.versionmajor << '.' <<
+        (int)header.versionminor << std::endl;
+    out << "Master key: " << header.key << std::endl;
+    out << "Items: " << header.items;
+
+    return out;
+}
 
-void
-TennixArchive::dump()
+std::ostream&
+operator<<(std::ostream& out, TennixArchiveItem& item)
 {
-    int x;
-    fprintf(stderr, "Tennix Archive\n");
-    fprintf(stderr, "Header: %s\n", header.header);
-    fprintf(stderr, "Version: %d.%d\n", header.versionmajor, header.versionminor);
-    fprintf(stderr, "Master key: %d\n", header.key);
-    fprintf(stderr, "Items: %d\n", header.items);
-    for (x = 0; x < header.items; x++) {
-        fprintf(stderr, "===========\n");
-        fprintf(stderr, "File: %s (#%d)\n", items[x].filename, x);
-        fprintf(stderr, "Size: %d\n", items[x].length);
-        fprintf(stderr, "Offset: %d\n", items[x].offset);
-        fprintf(stderr, "Key: %d\n", items[x].key);
-    }
+    out << "File: " << item.filename << std::endl;
+    out << "Size: " << item.length << std::endl;
+    out << "Offset: " << item.offset << std::endl;
+    out << "Key: " << (int)item.key;
+
+    return out;
 }
 
 int
@@ -191,3 +200,18 @@ TennixArchive::buildFile(char* filename)
     free(blobs);
 }
 
+std::ostream&
+operator<<(std::ostream& out, TennixArchive& archive)
+{
+    out << "Tennix Archive" << std::endl;
+    out << archive.header << std::endl;
+
+    for (int i=0; i<archive.header.items; i++) {
+        out << "=======================" << std::endl;
+        out << archive.items[i] << std::endl;
+    }
+    out << "=== END OF ARCHIVE ====" << std::endl;
+
+    return out;
+}
+
index c0ba7a6..0ec2509 100644 (file)
@@ -23,6 +23,8 @@
  *
  **/
 
+#include <iostream>
+
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -48,6 +50,9 @@ struct _TennixArchiveItem {
 
 typedef struct _TennixArchiveItem TennixArchiveItem;
 
+std::ostream&
+operator<<(std::ostream& out, TennixArchiveItem& item);
+
 struct _TennixArchiveHeader {
     char header[TENNIX_ARCHIVE_HEADER_LEN];
     uint8_t versionmajor; /* major file version */
@@ -58,6 +63,8 @@ struct _TennixArchiveHeader {
 
 typedef struct _TennixArchiveHeader TennixArchiveHeader;
 
+std::ostream&
+operator<<(std::ostream& out, TennixArchiveHeader& header);
 
 class TennixArchive {
     private:
@@ -79,7 +86,7 @@ class TennixArchive {
             fp = NULL;
         }
 
-        TennixArchive(const char* filename);
+        TennixArchive(const char* filename, const char* fallback=NULL);
 
         ~TennixArchive() {
             if (fp != NULL) {
@@ -111,7 +118,12 @@ class TennixArchive {
         /* only for building/utility mode: */
         void appendItem(char* filename, char* data, uint32_t length);
         void buildFile(char* filename);
-        void dump();
+
+        friend std::ostream& operator<<(std::ostream& out, TennixArchive& archive);
 };
 
+/* Used for dumping the contents of a TennixArchive */
+std::ostream&
+operator<<(std::ostream& out, TennixArchive& archive);
+
 #endif
index dda07a7..870889e 100644 (file)
@@ -72,9 +72,8 @@ int main(int argc, char* argv[])
             fprintf(stderr, "Usage: %s archive.tnx\n", bn);
             exit(EXIT_FAILURE);
         }
-        tnxar = new TennixArchive(argv[1]);
-        tnxar->dump();
-        delete tnxar;
+        TennixArchive archive(argv[1]);
+        std::cerr << archive << std::endl;
     } else if(strcmp(bn, "extract") == 0) {
         if (argc < 2 || argc > 3) {
             fprintf(stderr, "Usage: %s archive.tnx [file]\n", bn);
index 26e44df..486819d 100644 (file)
@@ -107,12 +107,11 @@ static const char* graphics[] = {
 #endif
 };
 
-void init_graphics() {
+void init_graphics(TennixArchive& tnxar) {
     int i;
     char *d;
     SDL_Surface* data;
     SDL_Surface* tmp;
-    TennixArchive* tnxar;
     struct SDL_RWops* rw;
     const char* font_data = NULL;
 
@@ -147,26 +146,17 @@ void init_graphics() {
         fprintf( stderr, "Cannot create buffer surface: %s\n", SDL_GetError());
     }
 
-    tnxar = new TennixArchive(ARCHIVE_FILE);
-#if 0
-    if (tnxar == NULL) {
-        /* not found in cwd - try installed... */
-        tnxar = tnxar_open(ARCHIVE_FILE_INSTALLED);
-        assert(tnxar != NULL);
-    }
-#endif
-
     font_freelist = freelist_create();
 
     /* Load fonts from resource file */
     for (i=0; i<FONT_COUNT; i++) {
         if (font_desc[i].filename != NULL) {
-            assert(tnxar->setItemFilename(font_desc[i].filename) != 0);
-            font_data = tnxar->getItemBytes();
+            assert(tnxar.setItemFilename(font_desc[i].filename) != 0);
+            font_data = tnxar.getItemBytes();
             freelist_append(font_freelist, font_data);
         }
         assert(font_data != NULL);
-        rw = SDL_RWFromMem((void*)font_data, tnxar->getItemSize());
+        rw = SDL_RWFromMem((void*)font_data, tnxar.getItemSize());
         fonts[i].data = TTF_OpenFontRW(rw, 1, font_desc[i].size);
         if (fonts[i].data == NULL) {
             fprintf(stderr, "TTF error: %s\n", TTF_GetError());
@@ -180,9 +170,9 @@ void init_graphics() {
     updatescr();
 
     for( i=0; i<GR_COUNT; i++) {
-        if (tnxar->setItemFilename(graphics[i]) != 0 ) {
-            d = tnxar->getItemBytes();
-            tmp = IMG_Load_RW(SDL_RWFromMem(d, tnxar->getItemSize()), 1);
+        if (tnxar.setItemFilename(graphics[i]) != 0 ) {
+            d = tnxar.getItemBytes();
+            tmp = IMG_Load_RW(SDL_RWFromMem(d, tnxar.getItemSize()), 1);
             free(d);
         } else {
             fprintf(stderr, "Cannot find file: %s\n", graphics[i]);
@@ -207,8 +197,6 @@ void init_graphics() {
         rectangle(40+BUTTON_BORDER*2, (HEIGHT-40)/2+20+BUTTON_BORDER, (WIDTH-80)*i/(GR_COUNT+SOUND_MAX)-BUTTON_BORDER*2, 10, 170, 250, 170);
         updatescr();
     }
-
-    delete tnxar;
 }
 
 void uninit_graphics() {
index 7a94fd0..c95f85f 100644 (file)
@@ -24,6 +24,7 @@
 #ifndef __GRAPHICS_H
 #define __GRAPHICS_H
 
+#include "archive.hh"
 #include "tennix.h"
 
 #include "SDL_image.h"
@@ -126,7 +127,7 @@ enum {
 #define GR_CTT_FIRST GR_CTT_HARD
 #define GR_CTT_LAST GR_CTT_GRASS
 
-void init_graphics();
+void init_graphics(TennixArchive& tnxar);
 void uninit_graphics();
 int get_image_width(image_id);
 int get_image_height(image_id);
diff --git a/input.c b/input.c
index 9e6ce96..ef2c175 100644 (file)
--- a/input.c
+++ b/input.c
@@ -28,6 +28,7 @@
 #include "game.h"
 #include "input.h"
 #include "util.h"
+#include "archive.hh"
 
 static InputDevice devices[MAX_INPUT_DEVICES];
 static int devices_count;
@@ -36,7 +37,7 @@ static int devices_count;
 #include "tennixpy.h"
 #endif
 
-void init_input()
+void init_input(TennixArchive& tnxar)
 {
     int n, x;
 
@@ -123,7 +124,7 @@ void init_input()
 
 #ifdef TENNIX_PYTHON
     /* This will init Python and load all available bots */
-    tennixpy_init();
+    tennixpy_init(tnxar);
 #endif
 
 }
diff --git a/input.h b/input.h
index 1547056..f3f8213 100644 (file)
--- a/input.h
+++ b/input.h
@@ -24,6 +24,7 @@
 #ifndef __INPUT_H
 #define __INPUT_H
 
+#include "archive.hh"
 #include "graphics.h"
 
 #ifdef TENNIX_PYTHON
@@ -110,7 +111,7 @@ typedef struct {
     int exclusive_to_player;
 } InputDevice;
 
-void init_input();
+void init_input(TennixArchive& tnxar);
 void uninit_input();
 
 #ifdef TENNIX_PYTHON
index 49788fc..56ac8a4 100644 (file)
--- a/makefile
+++ b/makefile
@@ -76,7 +76,7 @@ else
   CFLAGS += $$(sdl-config --cflags)
 endif
 
-SRC = tennix.c game.c graphics.cc input.c util.c sound.cc animation.c network.c
+SRC = tennix.cc game.c graphics.cc input.c util.c sound.cc animation.c network.c
 OBJ = tennix.o game.o graphics.o input.o util.o sound.o animation.o archive.o SDL_rotozoom.o network.o
 ifeq ($(MSYSTEM),MINGW32)
   OBJ += tennixres.o
@@ -115,14 +115,14 @@ install: tennix
        install -m 644 tennix.tnx $(DESTDIR)$(DATADIR)/tennix/
 
 archive.o: archive.cc archive.cc
-tennix.o: tennix.c tennix.h game.h graphics.h input.h util.h animation.h sound.h locations.h util.h
+tennix.o: tennix.cc tennix.h game.h graphics.h input.h util.h animation.h sound.h locations.h util.h archive.hh
 graphics.o: graphics.cc graphics.h tennix.h archive.hh sound.h
 game.o: game.c game.h graphics.h tennix.h sound.h input.h util.h network.h
 sound.o: sound.cc sound.h tennix.h archive.hh graphics.h
-input.o: input.c input.h tennix.h graphics.h game.h util.h tennixpy.h
+input.o: input.c input.h tennix.h graphics.h game.h util.h tennixpy.h archive.hh
 util.o: util.c util.h tennix.h
 animation.o: animation.c animation.h graphics.h tennix.h credits.h
-tennixpy.o: tennixpy.cc tennix.c tennix.h game.h archive.hh
+tennixpy.o: tennixpy.cc tennix.h game.h archive.hh
 network.o: network.c network.h game.h
 SDL_rotozoom.o: SDL_rotozoom.c SDL_rotozoom.h
 
index 0902017..f36c620 100644 (file)
--- a/sound.cc
+++ b/sound.cc
@@ -109,11 +109,10 @@ static int voice_queue_position = 0;
 int voice_finished_flag = 1;
 static int available_channels = 0;
 
-void init_sound() {
+void init_sound(TennixArchive& tnxar) {
     int i;
     char *d;
     Mix_Chunk* data;
-    TennixArchive* tnxar;
 
     if( Mix_OpenAudio( 44100, AUDIO_S16SYS, 2, 1024) < 0) {
         fprintf( stderr, "Error initializing SDL_mixer: %s\n", Mix_GetError());
@@ -123,7 +122,6 @@ void init_sound() {
 
     draw_button(40, (HEIGHT-40)/2, WIDTH-80, 40, 100, 100, 100, 1);
     store_screen();
-    updatescr();
 
     /* +1 because of zero-based indexing AND +1 for voice channel */
     available_channels = Mix_AllocateChannels(LAST_SOUNDEFFECT_ID+1+1);
@@ -134,19 +132,10 @@ void init_sound() {
                 LAST_SOUNDEFFECT_ID+1+1);
     }
 
-    tnxar = new TennixArchive(ARCHIVE_FILE);
-#if 0
-    if (tnxar == NULL) {
-        /* not found in cwd - try installed... */
-        tnxar = tnxar_open(ARCHIVE_FILE_INSTALLED);
-        assert(tnxar != NULL);
-    }
-#endif
-
     for( i=0; i<SOUND_MAX; i++) {
-        if (tnxar->setItemFilename(samples[i]) != 0) {
-            d = tnxar->getItemBytes();
-            data = Mix_LoadWAV_RW(SDL_RWFromMem(d, tnxar->getItemSize()), 0);
+        if (tnxar.setItemFilename(samples[i]) != 0) {
+            d = tnxar.getItemBytes();
+            data = Mix_LoadWAV_RW(SDL_RWFromMem(d, tnxar.getItemSize()), 0);
             free(d);
         } else {
             fprintf(stderr, "Cannot find %s\n", samples[i]);
@@ -164,8 +153,6 @@ void init_sound() {
         updatescr();
     }
 
-    delete tnxar;
-
     clear_screen();
     store_screen();
     updatescr();
diff --git a/sound.h b/sound.h
index b126c38..87b765a 100644 (file)
--- a/sound.h
+++ b/sound.h
@@ -24,6 +24,8 @@
 #ifndef __SOUND_H
 #define __SOUND_H
 
+#include "archive.hh"
+
 #include "SDL_mixer.h"
 
 #define FADE_OUT_MS 500
@@ -137,7 +139,7 @@ typedef struct {
     Mix_Chunk* data;
 } Sound;
 
-void init_sound();
+void init_sound(TennixArchive& tnxar);
 
 void play_sample_n(sound_id id, int n);
 #define play_sample(id) play_sample_n(id,0)
similarity index 99%
rename from tennix.c
rename to tennix.cc
index 9145b4e..8b730a2 100644 (file)
--- a/tennix.c
+++ b/tennix.cc
@@ -32,6 +32,7 @@
 #endif
 
 #include "tennix.h"
+#include "archive.hh"
 #include "game.h"
 #include "graphics.h"
 #include "sound.h"
@@ -109,6 +110,7 @@ int main( int argc, char** argv) {
     TennixNet* connection = NULL;
     char* net_host = NULL;
     bool net_master = false;
+    TennixArchive* tnxar = NULL;
 
     MenuButton btn_back = {
         NULL, /* not needed for image-based button */
@@ -243,10 +245,12 @@ int main( int argc, char** argv) {
     SDL_ShowCursor( SDL_DISABLE);
     SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, 1);
 
-    init_graphics();
-    init_sound();
-    init_input();
+    tnxar = new TennixArchive(ARCHIVE_FILE, ARCHIVE_FILE_INSTALLED);
+    init_graphics(*tnxar);
+    init_sound(*tnxar);
+    init_input(*tnxar);
     init_network();
+    delete tnxar;
 
     if (net_host != NULL) {
         connection = network_connect(net_host, net_master);
index 1ed4728..7f2c87e 100644 (file)
@@ -266,13 +266,12 @@ PyObject* tennixpy_get_position(PyObject* self, PyObject* args)
     }
 }
 
-void tennixpy_init()
+void tennixpy_init(TennixArchive& tnxar)
 {
     PyObject* tennix_module;
     /*PyObject* bot_module;*/
     /*FILE* fp;*/
     char* data;
-    TennixArchive* tnxar;
     /*const char* argv[] = {""};*/
 
     /* Search for modules in CWD */
@@ -287,19 +286,9 @@ void tennixpy_init()
     }
     Py_DECREF(bot_module);*/
 
-    tnxar = new TennixArchive(ARCHIVE_FILE);
-
-#if 0
-    if (tnxar == NULL) {
-        /* not found in cwd - try installed... */
-        tnxar = tnxar_open(ARCHIVE_FILE_INSTALLED);
-        assert(tnxar != NULL);
-    }
-#endif
-
-    if (tnxar->setItemFilename("defaultbot.py") != 0) {
+    if (tnxar.setItemFilename("defaultbot.py") != 0) {
         fprintf(stderr, "Loading computer players:");
-        data = tnxar->getItemBytes();
+        data = tnxar.getItemBytes();
         if (PyRun_SimpleString(data) != 0) {
             PyErr_Print();
         } else {
@@ -307,7 +296,6 @@ void tennixpy_init()
         }
         free(data);
     }
-    delete tnxar;
 
     /*fp = fopen("defaultbot.py", "r");
     PyRun_SimpleFile(fp, "defaultbot.py");
index a54f8c7..a3ab98d 100644 (file)
@@ -27,6 +27,8 @@
 
 #ifdef TENNIX_PYTHON
 
+#include "archive.hh"
+
 extern PyThreadState* _py_save;
 
 PyObject* tennixpy_register_bot(PyObject* self, PyObject* bot_class);
@@ -45,7 +47,7 @@ PyObject* tennixpy_get_position(PyObject* self, PyObject* args);
 
 PyObject* tennixpy_create_module(void);
 
-void tennixpy_init();
+void tennixpy_init(TennixArchive& tnxar);
 void tennixpy_uninit();
 
 #endif