1 /* Tower Toppler - Nebulus
2  * Copyright (C) 2000-2012  Andreas R�ver
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  */
18 
19 #ifndef ARCHI_H
20 #define ARCHI_H
21 
22 #include <SDL.h>
23 
24 /* this module contains a simple archive access class. an archive
25  * is a collection of zlib compressed files with a header defining
26  * compressed, uncompressed size and the start of the data inside
27  * the archive
28  *
29  * because the file gets decompressed in one run and saved inside a
30  * memory block be careful not to create too big files
31  */
32 
33 class archive;
34 
35 /* this class is used to handle the access to the different files inside
36  * the archive(s)
37  */
38 class file {
39 
40 public:
41 
42   /* you need to give the archive with your file and
43    * the name of the file you want to open to the
44    * constructor
45    */
46   file(const archive *arc, const char *name);
47 
48   /* close the file and free memory
49    */
50   ~file();
51 
52   /* returns the size of the currently opened file
53    */
size(void)54   Uint32 size(void) { return fsize; }
55 
56   /* returns true if the current file is completely read
57    */
eof(void)58   bool eof(void) { return bufferpos >= fsize; }
59 
60   /* reads up to size bytes into the buffer, returning in result
61    * the real number read
62    */
63   Uint32 read(void *buf, Uint32 size);
64 
65   /* read one byte from currently opened file
66    */
67   Uint8 getbyte(void);
68 
69   /* read one word from currently opened file this read is endian save
70    */
71   Uint16 getword(void);
72 
73   /* chreates an RW operation type from this file */
74   SDL_RWops *rwOps(void);
75 
76 private:
77 
78   /* the buffer containing the uncompressed file data
79    */
80   Uint8* buffer;
81 
82   /* current position inside the file data
83    */
84   Uint32 bufferpos;
85 
86   /* size of the file
87    */
88   unsigned long fsize;
89 
90 };
91 
92 /* this class handles one archive, each archive can contain any number of
93  * files with 0 terminated names.
94  */
95 class archive {
96 
97 public:
98 
99   /* opens the archive, you must give the FILE handle to the
100    * file that is the archive to this constructor
101    */
102   archive(FILE *file);
103 
104   /* closes the archive and frees memory
105    */
106   ~archive();
107 
108   /* number of files inside the archive */
fileNumber(void)109   Uint8 fileNumber(void) { return filecount; }
110 
111   /* name of the n-th file */
fname(Uint8 idx)112   const char * fname(Uint8 idx) { return files[idx].name; }
113 
114 private:
115 
116   FILE *f;
117 
118   /* this structur contains all the information inside the
119    * header for one file, it's used build an array of
120    * files upon archive opening
121    */
122   typedef struct {
123     char *name;
124     Uint32 start, size, compress;
125   } fileindex;
126 
127   /* the pointer to the file array
128    */
129   fileindex *files;
130 
131   /* number of files inside the archive
132    */
133   Uint8 filecount;
134 
135   /* the constructor for the archive file must access the files and
136    * filecount members, so it must be a friend
137    */
138   friend file::file(const archive *arc, const char *name);
139 };
140 
141 /* it is arguably, if this is the right place for this declaration, but
142  * if you assume that everybody who wants to access an archive does need the
143  * class definition and this global variable at the same time, it's not so wrong
144  * either
145  */
146 extern archive * dataarchive;
147 
148 #endif
149 
150