]> git.mxchange.org Git - quix0rs-blobwars.git/blob - src/CPak.cpp
Use UNIX line endings everywhere.
[quix0rs-blobwars.git] / src / CPak.cpp
1 /*
2 Copyright (C) 2004 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 "headers.h"
22
23 Pak::Pak()
24 {
25         input = NULL;
26         fd = NULL;
27         
28         numberOfFiles = 0;
29         listPos = 0;
30         currentFile = NULL;
31
32         strcpy(pakFilename, "");
33         strcpy(filename, "");
34 }
35
36 Pak::~Pak()
37 {
38         if (input != NULL)
39                 delete[] input;
40                 
41         input = NULL;
42         
43         if (fd != NULL)
44                 delete[] fd;
45         
46         fd = NULL;
47 }
48
49 void Pak::showPakErrorAndExit()
50 {
51         printf("\nFatal Error: The Blob Wars PAK file was either not found or was not accessable.\n");
52         printf("(If you compiled from source did you forget to run make install?)\n");
53         printf("The path to the file was expected to be,\n\n");
54         printf(PAKFULLPATH"\n\n");
55         printf("Please try running the game again. If problems persist either reinstall the game or check,\n\n");
56         printf("http://www.parallelrealities.co.uk/blobWars.php\n\n");
57         printf("for updates.\n\n");
58         exit(1);
59 }
60
61 void Pak::setPakFile(const char *pakFilename)
62 {
63         #if USEPAK
64         strcpy(this->pakFilename, pakFilename);
65         
66         debug(("Pak : Filename set to %s\n", pakFilename));
67
68         FILE *pak = fopen(pakFilename, "rb");
69
70         if (!pak)
71         {
72                 showPakErrorAndExit();
73         }
74
75         fseek(pak, (-sizeof(Uint32)) * 2, SEEK_END);
76         fread(&listPos, sizeof(Uint32), 1, pak);
77         fread(&numberOfFiles, sizeof(Uint32), 1, pak);
78         
79         debug(("Pak : File list resides at %d\n", (int)listPos));
80         debug(("Pak : Number of files are %d\n", (int)numberOfFiles));
81         
82         fd = new FileData[numberOfFiles];
83         
84         fseek(pak, listPos, SEEK_SET);
85         
86         int result = 0;
87         
88         for (unsigned int i = 0 ; i < numberOfFiles ; i++)
89         {
90                 result = fread(&fd[i], sizeof(FileData), 1, pak);
91                 
92                 if (!result)
93                 {
94                         fclose(pak);
95                         showPakErrorAndExit();
96                 }
97                 
98                 debug(("Read FileData #%d / %d : %s\n", (i + 1), numberOfFiles, fd[i].filename));
99         }
100         
101         fclose(pak);
102         
103         #endif
104 }
105
106 bool Pak::unpack(const char *filename, unsigned char **buffer)
107 {
108         debug(("Pak : Unpacking %s...\n", filename));
109         
110         currentFile = NULL;
111         
112         for (unsigned int i = 0 ; i < numberOfFiles ; i++)
113         {
114                 if (strcmp(filename, fd[i].filename) == 0)
115                 {
116                         currentFile = &fd[i];
117                         break;
118                 }
119         }
120         
121         if (currentFile == NULL)
122         {
123                 return false;
124         }
125         
126         FILE *pak = fopen(pakFilename, "rb");
127         if (!pak)
128         {
129                 showPakErrorAndExit();
130         }
131         
132         fseek(pak, currentFile->location, SEEK_SET);
133
134         if (input != NULL)
135         {
136                 delete[] input;
137         }
138
139         input = NULL;
140         
141         input = new unsigned char[(int)(currentFile->cSize * 1.01) + 12];
142         *buffer = new unsigned char[currentFile->fSize + 1];
143
144         fread(input, 1, currentFile->cSize, pak);
145         
146         uLongf fSize = (uLongf)currentFile->fSize;
147         
148         uncompress(*buffer, &fSize, input, currentFile->cSize);
149         (*buffer)[currentFile->fSize] = 0;
150
151         fclose(pak);
152         
153         if (input != NULL)
154                 delete[] input;
155
156         input = NULL;
157         
158         debug(("Pak : Unpack %s...Done\n", filename));
159
160         return true;
161 }
162
163 bool Pak::fileExists(const char *filename)
164 {
165         unsigned int hashcode = 0;
166         unsigned int length = strlen(filename);
167         
168         for (unsigned int i = 0 ; i < length ; i++)
169         {
170                 hashcode = hashcode + (filename[i] * 31 ^ (length - i));
171         }
172         
173         for (unsigned int i = 0 ; i < numberOfFiles ; i++)
174         {
175                 if (strcmp(fd[i].filename, filename) == 0)
176                 {
177                         return true;
178                 }
179         }
180         
181         return false;
182 }
183
184 unsigned int Pak::getUncompressedSize()
185 {
186         return (unsigned int)currentFile->fSize;
187 }