]> git.mxchange.org Git - quix0rs-blobwars.git/blob - src/pak.cpp
Use UNIX line endings everywhere.
[quix0rs-blobwars.git] / src / pak.cpp
1 /*
2 Copyright (C) 2005 Parallel Realities
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.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20
21 #include "pak.h"
22
23 FILE *pak;
24 int dirs = 0, files = 0;
25 int totalFiles = 0;
26 Bytef *buffer;
27 Bytef *output;
28
29 FileData *fileData = NULL;
30
31 void cleanup()
32 {
33         if (buffer != NULL)
34         {
35                 delete[] buffer;
36         }
37         
38         if (output != NULL)
39         {
40                 delete[] output;
41         }
42 }
43
44 void countFiles(const char *dirName)
45 {
46         DIR *dirp, *dirp2;
47         dirent *dfile;
48         dirp = opendir(dirName);
49         char filename[1024];
50
51         while ((dfile = readdir(dirp)))
52         {
53                 if (dfile->d_name[0] == '.')
54                 {
55                         continue;
56                 }
57
58                 snprintf(filename, sizeof filename, "%s/%s", dirName, dfile->d_name);
59                 
60                 if (strlen(filename) > PAK_MAX_FILENAME - 1)
61                 {
62                         printf("\nERROR - '%s' exceeds maximum defined file length of %d\n", filename, PAK_MAX_FILENAME);
63                         exit(1);
64                 }
65
66                 dirp2 = opendir(filename);
67
68                 if (dirp2)
69                 {
70                         closedir(dirp2);
71                         countFiles(filename);
72                 }
73                 else
74                 {
75                         totalFiles++;
76                 }
77         }
78         
79         fileData = new FileData[totalFiles];
80 }
81
82 void recurseDirectory(const char *dirName)
83 {
84         DIR *dirp, *dirp2;
85         dirent *dfile;
86         gzFile fp;
87         FILE *infile;
88         char filename[1024];
89
90         uLongf cSize = 0;
91         uLongf fSize = 0;
92
93         dirp = opendir(dirName);
94
95         if (dirp == NULL)
96         {
97                 printf("%s: Directory does not exist or is not accessable\n", dirName);
98                 return;
99         }
100         
101         float percentage;
102         long filesize;
103
104         while ((dfile = readdir(dirp)))
105         {
106                 if (dfile->d_name[0] == '.')
107                 {
108                         continue;
109                 }
110
111                 snprintf(filename, sizeof filename, "%s/%s", dirName, dfile->d_name);
112
113                 dirp2 = opendir(filename);
114
115                 if (dirp2)
116                 {
117                         closedir(dirp2);
118                         recurseDirectory(filename);
119                 }
120                 else
121                 {
122                         infile = fopen(filename, "rb");
123                         if (!infile)
124                         {
125                                 printf("Couldn't open %s for reading!\n", filename);
126                                 closedir(dirp);
127                                 gzclose(pak);
128                                 exit(1);
129                         }
130                         
131                         fseek(infile, SEEK_SET, SEEK_END);
132                         
133                         filesize = ftell(infile);
134                         
135                         fclose(infile);
136                         
137                         if (buffer != NULL)
138                         {
139                                 delete[] buffer;
140                                 buffer = NULL;
141                         }
142                         
143                         buffer = new unsigned char[filesize];
144                         
145                         if (output != NULL)
146                         {
147                                 delete[] output;
148                                 output = NULL;
149                         }
150                         
151                         output = new unsigned char[(int)(filesize * 1.01) + 12];
152                         
153                         fp = gzopen(filename, "rb");
154
155                         if (!fp)
156                         {
157                                 printf("Couldn't open %s for reading!\n", filename);
158                                 closedir(dirp);
159                                 gzclose(pak);
160                                 exit(1);
161                         }
162                         else
163                         {
164                                 fSize = gzread(fp, buffer, filesize);
165                                 gzclose(fp);
166
167                                 cSize = (uLongf)((fSize * 1.01) + 12);
168                                 compress2(output, &cSize, buffer, fSize, 9);
169                                 
170                                 fileData[files].set(filename, fSize, cSize, ftell(pak));
171
172                                 fwrite(output, 1, cSize, pak);
173
174                                 files++;
175                                 
176                                 percentage = files;
177                                 percentage /= totalFiles;
178                                 percentage *= 100;
179
180                                 printf("\b\b\b\b%3.0f%%", percentage);
181                                 fflush(stdout);
182                         }
183                 }
184         }
185
186         closedir(dirp);
187
188         dirs++;
189 }
190
191 int main(int argc, char *argv[])
192 {
193         if (argc < 3)
194         {
195                 printf("Usage   : pak <directory names> <outputname>\n");
196                 printf("Example : pak data music gfx sound data.pak\n");
197                 exit(1);
198         }
199
200         pak = fopen(argv[argc - 1], "wb");
201         
202         for (int i = 1 ; i < (argc - 1) ; i++)
203         {
204                 countFiles(argv[i]);
205         }
206                 
207         printf("Paking...000%%");
208         fflush(stdout);
209         
210         output = NULL;
211         buffer = NULL;
212         
213         atexit(cleanup);
214
215         for (int i = 1 ; i < (argc - 1) ; i++)
216         {
217                 recurseDirectory(argv[i]);
218         }
219
220         unsigned int pos = ftell(pak);
221
222         for (int i = 0 ; i < files ; i++)
223         {
224                 if (fileData[i].fSize == 0)
225                 {
226                         break;
227                 }
228
229                 fwrite(&fileData[i], sizeof(FileData), 1, pak);
230         }
231         
232         unsigned int numberOfFiles = totalFiles;
233
234         fwrite(&pos, sizeof(unsigned int), 1, pak);
235         fwrite(&numberOfFiles, sizeof(unsigned int), 1, pak);
236
237         fclose(pak);
238
239         printf("\nPak: All Done. Added %d files\n", numberOfFiles);
240
241         return 0;
242 }