1 /* gngb, a game boy color emulator
2 * Copyright (C) 2001 Peponas Thomas & Peponas Mathieu
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (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 Library 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 #include <config.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <time.h>
23 #include <fcntl.h>
24 #ifdef HAVE_UNISTD_H
25 #include <unistd.h>
26 #endif
27 #include <stdio.h>
28 #include <errno.h>
29 #ifdef HAVE_DIRENT_H
30 #include <dirent.h>
31 #endif
32
33
34 #include <stdlib.h>
35 #include <string.h>
36 #include "fileio.h"
37
38 #ifdef HAVE_LIBZ
39 #include "unzip.h"
40 #include <zlib.h>
41 #endif
42
43 #ifdef HAVE_LIBBZ2
44 #include <bzlib.h>
45 #endif
46
47
get_type_file(char * filename)48 char get_type_file(char *filename) {
49 FILE *file_tmp;
50 char str[10];
51 int i;
52 struct {
53 char *sign;
54 int len;
55 char type;
56 } tab_sign[]={
57 {"PK\003\004",4,ZIP_ARCH_FILE_TYPE},
58 {"\037\213",2,GZIP_FILE_TYPE},
59 {"BZh",3,BZIP_FILE_TYPE},
60 {NULL,0,UNKNOW_FILE_TYPE}};
61
62 if (!(file_tmp=fopen(filename,"rb"))) return UNKNOW_FILE_TYPE;
63 fread(str,1,10,file_tmp);
64 fclose(file_tmp);
65
66 for(i=0;tab_sign[i].sign;i++) {
67 if (!memcmp(str,tab_sign[i].sign,tab_sign[i].len)) return tab_sign[i].type;
68 }
69
70 return NORMAL_FILE_TYPE;
71 }
72
gngb_file_open(char * filename,char * mode,char type)73 GNGB_FILE *gngb_file_open(char *filename,char *mode,char type) {
74 GNGB_FILE *f=(GNGB_FILE *)malloc(sizeof(GNGB_FILE));
75 if (!f) return NULL;
76
77 if (type!=UNKNOW_FILE_TYPE) f->type=type;
78 else f->type=get_type_file(filename);
79
80 switch(f->type) {
81 case GZIP_FILE_TYPE:
82 #ifdef HAVE_LIBZ
83 f->stream=(char *)gzopen(filename,mode);
84 #else
85 fprintf(stderr,"Gzip file unsupported\n");
86 return NULL;
87 #endif
88 break;
89
90 case ZIP_ARCH_FILE_TYPE:
91 #ifdef HAVE_LIBZ
92 f->stream=(char *)unzOpen(filename);
93 #else
94 fprintf(stderr,"Zip file unsupported\n");
95 return NULL;
96 #endif
97 break;
98
99 case BZIP_FILE_TYPE:
100 #ifdef HAVE_LIBBZ2
101 f->stream=(char *)BZ2_bzopen(filename,mode);
102 break;
103 #else
104 fprintf(stderr,"Bzip2 file unsupported\n");
105 return NULL;
106 #endif
107 break;
108
109 case NORMAL_FILE_TYPE:
110 case GB_ROM_FILE_TYPE:
111 f->stream=(char *)fopen(filename,mode);
112 break;
113 default:
114 return NULL;
115 }
116
117 if (!f->stream) {
118 free(f);
119 return NULL;
120 }
121 return f;
122 }
123
gngb_file_close(GNGB_FILE * f)124 int gngb_file_close(GNGB_FILE *f) {
125
126 switch(f->type) {
127 case NORMAL_FILE_TYPE:
128 case GB_ROM_FILE_TYPE:return fclose((FILE *)f->stream);
129
130 case GZIP_FILE_TYPE:
131 #ifdef HAVE_LIBZ
132 return gzclose((gzFile)f->stream);
133 #else
134 fprintf(stderr,"Gzip file unsupported\n");
135 return -1;
136 #endif
137
138 case ZIP_ARCH_FILE_TYPE:
139 #ifdef HAVE_LIBZ
140 unzCloseCurrentFile((unzFile)f->stream);
141 return unzClose((unzFile)f->stream);
142 #else
143 fprintf(stderr,"Zip file unsupported\n");
144 return -1;
145 #endif
146
147 case BZIP_FILE_TYPE:
148 #ifdef HAVE_LIBBZ2
149 BZ2_bzclose((BZFILE *)f->stream);
150 return 0;
151 #else
152 fprintf(stderr,"Bzip2 file unsupported\n");
153 return -1;
154 #endif
155 break;
156 default:return -1;
157 }
158
159 }
160
gngb_file_read(void * ptr,size_t size,size_t nmemb,GNGB_FILE * f)161 int gngb_file_read(void *ptr, size_t size, size_t nmemb,GNGB_FILE *f) {
162 switch(f->type) {
163 case NORMAL_FILE_TYPE:
164 case GB_ROM_FILE_TYPE:return fread(ptr,size,nmemb,(FILE *)f->stream);
165
166 case GZIP_FILE_TYPE:
167 #ifdef HAVE_LIBZ
168 return gzread((gzFile)f->stream,ptr,size*nmemb);
169 #else
170 fprintf(stderr,"Gzip file unsupported\n");
171 return -1;
172 #endif
173
174 case ZIP_ARCH_FILE_TYPE:
175 #ifdef HAVE_LIBZ
176 return unzReadCurrentFile((unzFile)f->stream,ptr,size*nmemb);
177 #else
178 fprintf(stderr,"Zip file unsupported\n");
179 return -1;
180 #endif
181
182 case BZIP_FILE_TYPE:
183 #ifdef HAVE_LIBBZ2
184 return BZ2_bzread((BZFILE *)f->stream,ptr,size*nmemb);
185 #else
186 fprintf(stderr,"Bzip2 file unsupported\n");
187 return -1;
188 #endif
189 break;
190
191 default:return -1;
192 }
193 }
194
gngb_file_write(const void * ptr,size_t size,size_t nmemb,GNGB_FILE * f)195 int gngb_file_write(const void *ptr, size_t size, size_t nmemb,GNGB_FILE *f) {
196 switch(f->type) {
197 case NORMAL_FILE_TYPE:
198 case GB_ROM_FILE_TYPE:
199 return fwrite(ptr,size,nmemb,(FILE *)(f->stream));
200
201 case GZIP_FILE_TYPE:
202 #ifdef HAVE_LIBZ
203 return gzwrite((gzFile)f->stream,ptr,size*nmemb);
204 #else
205 fprintf(stderr,"Gzip file unsupported\n");
206 return -1;
207 #endif
208
209 case ZIP_ARCH_FILE_TYPE:
210 #ifdef HAVE_LIBZ
211 fprintf(stderr,"Write for Unzip file unsupported\n");
212 return -1;
213 #else
214 fprintf(stderr,"Zip file unsupported\n");
215 return -1;
216 #endif
217
218 case BZIP_FILE_TYPE:
219 #ifdef HAVE_LIBBZ2
220 return BZ2_bzwrite((BZFILE *)f->stream,ptr,size*nmemb);
221 #else
222 fprintf(stderr,"Bzip2 file unsupported\n");
223 return -1;
224 #endif
225
226 default:return -1;
227 }
228 }
229
gngb_file_seek(GNGB_FILE * f,long offset,int whence)230 int gngb_file_seek(GNGB_FILE *f, long offset, int whence) {
231 switch(f->type) {
232 case NORMAL_FILE_TYPE:
233 case GB_ROM_FILE_TYPE:return fseek((FILE *)f->stream,offset,whence);
234
235 case BZIP_FILE_TYPE:
236 #ifdef HAVE_LIBBZ2
237 fprintf(stderr,"fseek for Bzip file: unsuported\n");
238 return -1;
239 #else
240 fprintf(stderr,"Bzip2 file unsupported\n");
241 return -1;
242 #endif
243
244
245 case GZIP_FILE_TYPE:
246 #ifdef HAVE_LIBZ
247 fprintf(stderr,"fseek for Gzip file: unsuported\n");
248 return -1;
249 #else
250 fprintf(stderr,"Gzip file unsupported\n");
251 return -1;
252 #endif
253
254 case ZIP_ARCH_FILE_TYPE:
255 #ifdef HAVE_LIBZ
256 fprintf(stderr,"fseek for Zip file unsupported\n");
257 return -1;
258 #else
259 fprintf(stderr,"Zip file unsupported\n");
260 return -1;
261 #endif
262
263 default:return -1;
264 }
265 }
266
gngb_file_eof(GNGB_FILE * f)267 int gngb_file_eof(GNGB_FILE *f) {
268 switch(f->type) {
269 case NORMAL_FILE_TYPE:
270 case GB_ROM_FILE_TYPE:return feof((FILE *)f->stream);
271
272 case GZIP_FILE_TYPE:
273 #ifdef HAVE_LIBZ
274 fprintf(stderr,"feof for Gzip file: unsuported\n");
275 return -1;
276 #else
277 fprintf(stderr,"Gzip file unsupported\n");
278 return -1;
279 #endif
280
281 case ZIP_ARCH_FILE_TYPE:
282 #ifdef HAVE_LIBZ
283 fprintf(stderr,"feof for Unzip file unsupported\n");
284 return -1;
285 #else
286 fprintf(stderr,"Zip file unsupported\n");
287 return -1;
288 #endif
289
290 case BZIP_FILE_TYPE:
291 #ifdef HAVE_LIBBZ2
292 fprintf(stderr,"feof for Bzip file: unsuported\n");
293 return -1;
294 #else
295 fprintf(stderr,"Bzip2 file unsupported\n");
296 return -1;
297 #endif
298
299
300 default:return -1;
301 }
302 }
303
304 #ifdef HAVE_LIBZ
305
zip_file_open_next_rom(unzFile file)306 int zip_file_open_next_rom(unzFile file) {
307 char header[0x200];
308
309 unzGoToFirstFile(file);
310 do {
311 unzOpenCurrentFile(file);
312 unzReadCurrentFile(file,header,0x200);
313 unzCloseCurrentFile(file);
314 #ifdef WORD_BIGENDIAN
315 if ((*((unsigned long *)(header+0x104)))==0xCEED6666) {
316 #else
317 if ((*((unsigned long *)(header+0x104)))==0x6666EDCE) {
318 #endif
319 /* Gameboy Roms */
320 unzOpenCurrentFile(file);
321 return 0;
322 }
323 }while(unzGoToNextFile(file)!=UNZ_END_OF_LIST_OF_FILE);
324 printf("titi\n");
325 return -1;
326 }
327
328 #endif
329
330