// nearly same as PicoCartLoad, but works with zipfiles int CartLoadZip(const char *fname, unsigned char **prom, unsigned int *psize) { unsigned char *rom=0; struct zipent* zipentry; int size; ZIP *zipfile = openzip(fname); if(!zipfile) return 1; // find first bin or smd while((zipentry = readzip(zipfile)) != 0) { char *ext; if(strlen(zipentry->name) < 5) continue; ext = zipentry->name+strlen(zipentry->name)-4; if(!strcasecmp(ext, ".bin") || !strcasecmp(ext, ".smd") || !strcasecmp(ext, ".gen")) break; } if(!zipentry) { closezip(zipfile); return 4; // no roms } size = zipentry->uncompressed_size; size=(size+3)&~3; // Round up to a multiple of 4 // Allocate space for the rom plus padding rom=PicoCartAlloc(size); if (rom==NULL) { closezip(zipfile); return 2; } if(readuncompresszip(zipfile, zipentry, (char *)rom) != 0) { free(rom); rom = 0; closezip(zipfile); return 5; // unzip failed } closezip(zipfile); // Check for SMD: if ((size&0x3fff)==0x200) { DecodeSmd(rom,size); size-=0x200; } // Decode and byteswap SMD else Byteswap(rom,size); // Just byteswap if (prom) *prom=rom; if (psize) *psize=size; return 0; }
static ZIP* cache_openzip(int pathtype, int pathindex, const char* zipfile) { ZIP* zip; unsigned i; /* search in the cache buffer */ for(i=0;i<ZIP_CACHE_MAX;++i) { if (zip_cache_map[i] && zip_cache_map[i]->pathtype == pathtype && zip_cache_map[i]->pathindex == pathindex && strcmp(zip_cache_map[i]->zip,zipfile)==0) { /* found */ unsigned j; /* logerror("Zip cache HIT for %s\n", zipfile); */ /* reset the zip directory */ rewindzip( zip_cache_map[i] ); /* store */ zip = zip_cache_map[i]; /* shift */ for(j=i;j>0;--j) zip_cache_map[j] = zip_cache_map[j-1]; /* set the first entry */ zip_cache_map[0] = zip; return zip_cache_map[0]; } } /* not found */ /* logerror("Zip cache FAIL for %s\n", zipfile); */ /* open the zip */ zip = openzip( pathtype, pathindex, zipfile ); if (!zip) return 0; /* close the oldest entry */ if (zip_cache_map[ZIP_CACHE_MAX-1]) { /* close last zip */ closezip(zip_cache_map[ZIP_CACHE_MAX-1]); /* reset the entry */ zip_cache_map[ZIP_CACHE_MAX-1] = 0; } /* shift */ for(i=ZIP_CACHE_MAX-1;i>0;--i) zip_cache_map[i] = zip_cache_map[i-1]; /* set the first entry */ zip_cache_map[0] = zip; return zip_cache_map[0]; }
static void cache_closezip(ZIP* zip) { unsigned i; /* search in the cache buffer */ for(i=0;i<ZIP_CACHE_MAX;++i) { if (zip_cache_map[i]==zip) { /* close zip */ closezip(zip); /* reset cache entry */ zip_cache_map[i] = 0; return; } } /* not found */ /* close zip */ closezip(zip); }
int ident_zip(char *fn) { ZIP* zip; struct zipent* zipf; printf("Zip file to ident = '%s'\n", fn); if ((zip = openzip(fn)) == 0) { printf("Error, cannot open zip file '%s' !\n", fn); return 1; }; while (zipf = readzip(zip)) { upper_case(zipf->name); romident(zipf->name, zipf->crc32, zipf->uncompressed_size); }; closezip(zip); return 0; }
/* CK980415 added to allow osd code to clear zip cache for auditing--each time the user opens up an audit for a game we should reread the zip */ void unzip_cache_clear() { unsigned i; /* search in the cache buffer for any zip info and clear it */ for(i=0;i<ZIP_CACHE_MAX;++i) { if (zip_cache_map[i] != NULL) { /* close zip */ closezip(zip_cache_map[i]); /* reset cache entry */ zip_cache_map[i] = 0; /* return; */ } } }
/* this code tries opening the image as a raw ZIP file, and if relevant, returns the * zip file and the entry */ char *mess_try_image_file_as_zip(int pathindex, const char *path, const struct IODevice *dev) { zip_file *zip = NULL; zip_entry *zipentry = NULL; char *name; const char *ext; int is_zip; char *new_path = NULL; char path_sep[2] = { PATH_SEPARATOR, '\0' }; name = osd_basename((char *) path); if (!name) goto done; ext = strrchr(name, '.'); is_zip = (ext && !mame_stricmp(ext, ".zip")); if (is_zip) { zip = openzip(FILETYPE_IMAGE, pathindex, path); if (!zip) goto done; while((zipentry = readzip(zip)) != NULL) { ext = strrchr(zipentry->name, '.'); if (!dev || (ext && findextension(dev->file_extensions, ext))) { new_path = malloc(strlen(path) + 1 + strlen(zipentry->name) + 1); if (!new_path) goto done; strcpy(new_path, path); strcat(new_path, path_sep); strcat(new_path, zipentry->name); break; } } } done: if (zip) closezip(zip); return new_path; }
static mame_file *image_fopen_custom(mess_image *img, int filetype, int read_or_write) { const char *sysname; char *lpExt; const game_driver *gamedrv = Machine->gamedrv; assert(img); if (!img->name) return NULL; if (img->fp) { /* If already open, we won't open the file again until it is closed. */ return NULL; } do { sysname = gamedrv->name; logerror("image_fopen: trying %s for system %s\n", img->name, sysname); img->fp = mame_fopen(sysname, img->name, filetype, read_or_write); if (img->fp && (read_or_write == OSD_FOPEN_READ)) { lpExt = strrchr( img->name, '.' ); if (lpExt && (mame_stricmp( lpExt, ".ZIP" ) == 0)) { int pathindex; int pathcount = osd_get_path_count(filetype); zip_file *zipfile; zip_entry *zipentry; char *newname; char *name; char *zipname; const char *ext; const struct IODevice *dev; mame_fclose( img->fp ); img->fp = NULL; dev = image_device(img); assert(dev); newname = NULL; zipname = image_malloc( img, strlen( sysname ) + 1 + strlen( img->name ) + 1 ); if( osd_is_absolute_path( img->name ) ) { strcpy( zipname, img->name ); } else { strcpy( zipname, sysname ); strcat( zipname, osd_path_separator() ); strcat( zipname, img->name ); } for (pathindex = 0; pathindex < pathcount; pathindex++) { zipfile = openzip(filetype, pathindex, zipname); if (zipfile) { zipentry = readzip(zipfile); while( zipentry ) { /* mess doesn't support paths in zip files */ name = osd_basename( zipentry->name ); lpExt = strrchr(name, '.'); if (lpExt) { lpExt++; ext = dev->file_extensions; while(*ext) { if( mame_stricmp( lpExt, ext ) == 0 ) { if( newname ) { image_freeptr( img, newname ); } newname = image_malloc(img, strlen(img->name) + 1 + strlen(name) + 1); if (!newname) return NULL; strcpy(newname, img->name); strcat(newname, osd_path_separator()); strcat(newname, name); } ext += strlen(ext) + 1; } } zipentry = readzip(zipfile); } closezip(zipfile); } if( !newname ) { return NULL; } img->fp = mame_fopen(sysname, newname, filetype, read_or_write); if (img->fp) { image_freeptr(img, img->name); img->name = newname; break; } } image_freeptr( img, zipname ); } } gamedrv = mess_next_compatible_driver(gamedrv); } while(!img->fp && gamedrv); if (img->fp) { logerror("image_fopen: found image %s for system %s\n", img->name, sysname); img->length = mame_fsize(img->fp); img->hash = NULL; } return img->fp; }