1 /* FCE Ultra - NES/Famicom Emulator
3 * Copyright notice for this file:
4 * Copyright (C) 2002 Ben Parnell
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "zlib/unzip.h"
36 static void *desctable[8]={0,0,0,0,0,0,0,0};
47 void *MakeZipWrap(void *tz)
52 if(!(tmp=FCEU_malloc(sizeof(ZIPWRAP))))
55 unzGetCurrentFileInfo(tz,&ufo,0,0,0,0,0,0);
58 tmp->size=ufo.uncompressed_size;
59 if(!(tmp->data=FCEU_malloc(ufo.uncompressed_size)))
65 unzReadCurrentFile(tz,tmp->data,ufo.uncompressed_size);
69 unzCloseCurrentFile(tz);
77 #define strcasecmp strcmp
80 int FASTAPASS(2) FCEU_fopen(char *path, char *mode)
86 if((tz=unzOpen(path))) // If it's not a zip file, use regular file handlers.
87 // Assuming file type by extension usually works,
88 // but I don't like it. :)
90 if(unzGoToFirstFile(tz)==UNZ_OK)
94 char tempu[512]; // Longer filenames might be possible, but I don't
95 // think people would name files that long in zip files...
96 unzGetCurrentFileInfo(tz,0,tempu,512,0,0,0,0);
100 char *za=tempu+strlen(tempu)-4;
101 if(!strcasecmp(za,".nes") || !strcasecmp(za,".fds") ||
102 !strcasecmp(za,".nsf") || !strcasecmp(za,".unf") ||
103 !strcasecmp(za,".nez"))
108 if(!strcasecmp(tempu+strlen(tempu)-5,".unif"))
111 if(unzGoToNextFile(tz)!=UNZ_OK)
113 if(unzGoToFirstFile(tz)!=UNZ_OK) goto zpfail;
117 if(unzOpenCurrentFile(tz)!=UNZ_OK)
130 if(!(desctable[x]=MakeZipWrap(tz)))
132 return((x+1)|0x8000);
138 if((t=fopen(path,"rb")))
150 if((t=gzopen(path,mode)))
155 return((x+1)|0x4000);
161 if((t=fopen(path,mode)))
174 int FASTAPASS(1) FCEU_fclose(int stream)
179 gzclose(desctable[(stream&255)-1]);
180 desctable[(stream&255)-1]=0;
182 else if(stream&0x8000)
184 free(((ZIPWRAP*)desctable[(stream&255)-1])->data);
185 free(desctable[(stream&255)-1]);
186 desctable[(stream&255)-1]=0;
188 else // close zip file
191 fclose(desctable[stream-1]);
192 desctable[stream-1]=0;
199 size_t FASTAPASS(3) FCEU_fread(void *ptr, size_t size, size_t nmemb, int stream)
204 return gzread(desctable[(stream&255)-1],ptr,size*nmemb);
206 else if(stream&0x8000)
209 uint32 total=size*nmemb;
211 wz=(ZIPWRAP*)desctable[(stream&255)-1];
212 if(wz->location>=wz->size) return 0;
214 if((wz->location+total)>wz->size)
216 int ak=wz->size-wz->location;
217 memcpy((uint8*)ptr,wz->data+wz->location,ak);
218 wz->location=wz->size;
223 memcpy((uint8*)ptr,wz->data+wz->location,total);
231 return fread(ptr,size,nmemb,desctable[stream-1]);
237 size_t FASTAPASS(3) FCEU_fwrite(void *ptr, size_t size, size_t nmemb, int stream)
242 return gzwrite(desctable[(stream&255)-1],ptr,size*nmemb);
244 else if(stream&0x8000)
250 return fwrite(ptr,size,nmemb,desctable[stream-1]);
253 int FASTAPASS(3) FCEU_fseek(int stream, long offset, int whence)
258 return gzseek(desctable[(stream&255)-1],offset,whence);
260 else if(stream&0x8000)
263 wz=(ZIPWRAP*)desctable[(stream&255)-1];
267 case SEEK_SET:if(offset>=wz->size)
269 wz->location=offset;break;
270 case SEEK_CUR:if(offset+wz->location>wz->size)
272 wz->location+=offset;
279 return fseek(desctable[stream-1],offset,whence);
282 long FASTAPASS(1) FCEU_ftell(int stream)
287 return gztell(desctable[(stream&255)-1]);
289 else if(stream&0x8000)
291 return (((ZIPWRAP *)desctable[(stream&255)-1])->location);
295 return ftell(desctable[stream-1]);
298 void FASTAPASS(1)FCEU_rewind(int stream)
303 gzrewind(desctable[(stream&255)-1]);
305 else if(stream&0x8000)
307 ((ZIPWRAP *)desctable[(stream&255)-1])->location=0;
312 fseek(desctable[stream-1],0,SEEK_SET);
314 rewind(desctable[stream-1]);
318 int FASTAPASS(2) FCEU_read32(void *Bufo, int stream)
330 wz=(ZIPWRAP*)desctable[(stream&255)-1];
331 if(wz->location+4>wz->size)
333 memcpy(&t, wz->data+wz->location, 4);
336 else if(stream&0x4000)
337 gzread(desctable[(stream&255)-1],&t,4);
343 *(uint32*)Bufo=*(uint32*)x;
352 return read32(Bufo,desctable[stream-1]);
356 int FASTAPASS(1) FCEU_fgetc(int stream)
360 return gzgetc(desctable[(stream&255)-1]);
361 else if(stream&0x8000)
364 wz=(ZIPWRAP*)desctable[(stream&255)-1];
365 if(wz->location<wz->size)
366 return wz->data[wz->location++];
371 return fgetc(desctable[stream-1]);
374 long FASTAPASS(1) FCEU_fgetsize(int stream)
380 t=gztell(desctable[(stream&255)-1]);
381 gzrewind(desctable[(stream&255)-1]);
382 for(x=0;gzgetc(desctable[(stream&255)-1]) != EOF; x++);
383 gzseek(desctable[(stream&255)-1],t,SEEK_SET);
386 else if(stream&0x8000)
387 return ((ZIPWRAP*)desctable[(stream&255)-1])->size;
392 t=ftell(desctable[stream-1]);
393 fseek(desctable[stream-1],0,SEEK_END);
394 r=ftell(desctable[stream-1]);
395 fseek(desctable[stream-1],t,SEEK_SET);
400 int FASTAPASS(1) FCEU_fisarchive(int stream)