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