// Who When What
// --- ---------- -------------------------------------------------------------
// JLH 01/16/2010 Created this log ;-)
+// JLH 02/28/2010 Added functions to look inside .ZIP files and handle contents
//
#include "file.h"
// Private function prototypes
static int gzfilelength(gzFile gd);
+static bool CheckExtension(const char * filename, const char * ext);
//
// Generic ROM loading
{
// We really should have some kind of sanity checking for the ROM size here to prevent
// a buffer overflow... !!! FIX !!!
-#warning !!! FIX !!! Should have sanity checking for ROM size to prevent buffer overflow!
+#warning "!!! FIX !!! Should have sanity checking for ROM size to prevent buffer overflow!"
uint32 romSize = 0;
WriteLog("JaguarLoadROM: Attempting to load file '%s'...", path);
}
else
{
- WriteLog("GUI: Couldn't find correct ABS format: %02X %02X\n", jaguarMainROM[0], jaguarMainROM[1]);
+ WriteLog("GUI: Couldn't find correct ABS/COF format: %02X %02X\n", jaguarMainROM[0], jaguarMainROM[1]);
return false;
}
}
gzrewind(gd);
return length;
}
+
+//
+// Compare extension to passed in filename. If equal, return true; otherwise false.
+//
+static bool CheckExtension(const char * filename, const char * ext)
+{
+ const char * filenameExt = strrchr(filename, '.'); // Get the file's extension (if any)
+ return (strcasecmp(filenameExt, ext) == 0 ? true : false);
+}
+
+//
+// Get file from .ZIP
+// Returns the size of the file inside the .ZIP file that we're looking at
+//
+uint32 GetFileFromZIP(const char * zipFile, FileType type, uint8 * buffer)
+{
+#warning "!!! FIX !!! Should have sanity checking for ROM size to prevent buffer overflow!"
+ const char ftStrings[5][32] = { "Software", "EEPROM", "Label", "Box Art", "Controller Overlay" };
+ ZIP * zip = openzip(0, 0, zipFile);
+
+ if (zip == NULL)
+ {
+ WriteLog("FILE: Could not open file '%s'!\n", zipFile);
+ return 0;
+ }
+
+ while (readzip(zip))
+ {
+ zipent * ze = &zip->ent;
+ bool found = false;
+
+ if ((type == FT_LABEL) && (CheckExtension(ze->name, ".png") || CheckExtension(ze->name, ".jpg") || CheckExtension(ze->name, ".gif")))
+ {
+ found = true;
+ WriteLog("FILE: Found image file '%s'.\n", ze->name);
+ }
+
+ if ((type == FT_SOFTWARE) && (CheckExtension(ze->name, ".j64") || CheckExtension(ze->name, ".rom") || CheckExtension(ze->name, ".abs") || CheckExtension(ze->name, ".cof")))
+ {
+ found = true;
+ WriteLog("FILE: Found software file '%s'.\n", ze->name);
+ }
+
+ if ((type == FT_EEPROM) && (CheckExtension(ze->name, ".eep") || CheckExtension(ze->name, ".eeprom")))
+ {
+ found = true;
+ WriteLog("FILE: Found EEPROM file '%s'.\n", ze->name);
+ }
+
+ if (found)
+ {
+ WriteLog("FILE: Uncompressing...");
+
+ if (readuncompresszip(zip, ze, (char *)buffer) == 0)
+ {
+ WriteLog("success! (%u bytes)\n", ze->uncompressed_size);
+ return ze->uncompressed_size;
+ }
+ else
+ {
+ WriteLog("FAILED!\n");
+ return 0;
+ }
+ }
+ }
+
+ closezip(zip);
+
+ WriteLog("FILE: Failed to find file of type %s...\n", ftStrings[type]);
+ // Didn't find what we're looking for...
+ return 0;
+}
+
+//ParseFileType, etc.
+
if (romList[i].file[0] == 0)
{
// painter->drawPixmap(option.rect.x()+14, option.rect.y()+50, 433/2, 203/2, QPixmap(":/res/label-blank.png"));
- painter->drawPixmap(option.rect.x()+7, option.rect.y()+25, 433/4, 203/4, QPixmap(":/res/label-blank.png"));
+ painter->drawPixmap(option.rect.x()+7, option.rect.y()+25, 433/4, 203/4, QPixmap(":/res/label-blank.png"));
//Need to query the model for the data we're supposed to draw here...
// painter->drawText(17, 73, QString(romList[i].name));
// painter->setPen(Qt::white);
- painter->setPen(QColor(255, 128, 0, 255));
+ painter->setPen(QColor(255, 128, 0, 255));
// painter->drawText(QRect(option.rect.x()+20, option.rect.y()+73, 196, 70), Qt::TextWordWrap | Qt::AlignHCenter, QString(romList[i].name));
- painter->drawText(QRect(option.rect.x()+10, option.rect.y()+36, 196/2, 70/2), Qt::TextWordWrap | Qt::AlignHCenter, QString(romList[i].name));
+ painter->drawText(QRect(option.rect.x()+10, option.rect.y()+36, 196/2, 70/2), Qt::TextWordWrap | Qt::AlignHCenter, QString(romList[i].name));
}
else
{
//
// ZIP file support (mostly ripped from MAME--thx MAME team!)
+// Mostly this is here to simplify interfacing to zlib...
//
// Added by James L. Hammons
// (C) 2010 Underground Software
// Who When What
// --- ---------- -------------------------------------------------------------
// JLH 01/16/2010 Created this log ;-)
+// JLH 02/28/2010 Removed unnecessary cruft
//
#include <stdlib.h>
if (!gUnzipQuiet)
printf("Error in zipfile %s\n%s\n", zipname, usermsg);
/* Output to log file with all informations */
- WriteLog("Error in zipfile %s: %s\n", zipname, extmsg);
+// WriteLog("Error in zipfile %s: %s\n", zipname, extmsg);
}
/* -------------------------------------------------------------------------
------------------------------------------------------------------------- */
/* Use these to avoid structure padding and byte-ordering problems */
-static uint16_t read_word (char *buf) {
- unsigned char *ubuf = (unsigned char *) buf;
+static uint16_t read_word(char * buf)
+{
+ unsigned char * ubuf = (unsigned char *)buf;
return ((uint16_t)ubuf[1] << 8) | (uint16_t)ubuf[0];
}
/* Use these to avoid structure padding and byte-ordering problems */
-static uint32_t read_dword (char *buf) {
- unsigned char *ubuf = (unsigned char *) buf;
+static uint32_t read_dword(char * buf)
+{
+ unsigned char * ubuf = (unsigned char *)buf;
return ((uint32_t)ubuf[3] << 24) | ((uint32_t)ubuf[2] << 16) | ((uint32_t)ubuf[1] << 8) | (uint32_t)ubuf[0];
}
==0 not found
!=0 found, *offset valid
*/
-static int ecd_find_sig (char *buffer, int buflen, int *offset)
+static int ecd_find_sig(char * buffer, int buflen, int * offset)
{
static char ecdsig[] = { 'P', 'K', 0x05, 0x06 };
int i;
- for (i=buflen-22; i>=0; i--) {
- if (memcmp(buffer+i, ecdsig, 4) == 0) {
+
+ for(i=buflen-22; i>=0; i--)
+ {
+ if (memcmp(buffer+i, ecdsig, 4) == 0)
+ {
*offset = i;
return 1;
}
}
+
return 0;
}
/* allocate buffer */
buf = (char *)malloc(buf_length);
+
if (!buf)
{
return -1;
return -1;
}
- if (ecd_find_sig(buf, buf_length, &offset)) {
+ if (ecd_find_sig(buf, buf_length, &offset))
+ {
zip->ecd_length = buf_length - offset;
- zip->ecd = (char*)malloc( zip->ecd_length );
- if (!zip->ecd) {
+ zip->ecd = (char *)malloc(zip->ecd_length);
+
+ if (!zip->ecd)
+ {
free(buf);
return -1;
}
memcpy(zip->ecd, buf + offset, zip->ecd_length);
-
free(buf);
return 0;
}
free(buf);
- if (buf_length < zip->length) {
+ if (buf_length < zip->length)
+ {
/* double buffer */
- buf_length = 2*buf_length;
-
+ buf_length = 2 * buf_length;
WriteLog("Retry reading of zip ecd for %d bytes\n",buf_length);
- } else {
- return -1;
}
+ else
+ return -1;
}
}
/* allocate */
ZIP * zip = (ZIP *)malloc(sizeof(ZIP));
if (!zip)
- {
return 0;
- }
/* open */
zip->fp = fopen(zipfile, "rb");
zip->zipfile_comment = zip->ecd+ZIPECOM;
/* verify that we can work with this zipfile (no disk spanning allowed) */
- if ((zip->number_of_this_disk != zip->number_of_disk_start_cent_dir) ||
- (zip->total_entries_cent_dir_this_disk != zip->total_entries_cent_dir) ||
- (zip->total_entries_cent_dir < 1))
+ if ((zip->number_of_this_disk != zip->number_of_disk_start_cent_dir)
+ || (zip->total_entries_cent_dir_this_disk != zip->total_entries_cent_dir)
+ || (zip->total_entries_cent_dir < 1))
{
errormsg("Cannot span disks", ERROR_UNSUPPORTED, zipfile);
free(zip->ecd);
!=0 success
==0 error
*/
-struct zipent* readzip(ZIP* zip) {
+struct zipent * readzip(ZIP * zip)
+{
/* end of directory */
if (zip->cd_pos >= zip->size_of_cent_dir)
free(zip->ent.name);
free(zip->cd);
free(zip->ecd);
+
/* only if not suspended */
if (zip->fp)
fclose(zip->fp);
+
free(zip->zip);
free(zip);
}
}
}
-/* -------------------------------------------------------------------------
- Zip cache support
- ------------------------------------------------------------------------- */
-
-/* Use the zip cache */
-// No, don't
-//#define ZIP_CACHE
-
-#ifdef ZIP_CACHE
-
-/* ZIP cache entries */
-#define ZIP_CACHE_MAX 5
-
-/* ZIP cache buffer LRU ( Last Recently Used )
- zip_cache_map[0] is the newer
- zip_cache_map[ZIP_CACHE_MAX-1] is the older
-*/
-static ZIP* zip_cache_map[ZIP_CACHE_MAX];
-
-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;
-
-/*
- WriteLog("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 */
-
-/*
- WriteLog("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);
-}
-
-/* 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; */
-
- }
- }
-}
-
-#define cache_suspendzip(a) suspendzip(a)
-
-#else
-
-#define cache_openzip(a,b,c) openzip(a,b,c)
-#define cache_closezip(a) closezip(a)
-#define cache_suspendzip(a) closezip(a)
-
-#define unzip_cache_clear()
-
-#endif
-
/* -------------------------------------------------------------------------
Backward MAME compatibility
------------------------------------------------------------------------- */
//
int load_zipped_file(int pathtype, int pathindex, const char * zipfile, const char * filename, unsigned char ** buf, uint32_t * length)
{
- ZIP * zip;
- struct zipent * ent;
+ ZIP * zip = openzip(pathtype, pathindex, zipfile);
- zip = cache_openzip(pathtype, pathindex, zipfile);
if (!zip)
return -1;
/* NS981003: support for "load by CRC" */
char crc[9];
- ent = &(zip->ent);
+ struct zipent * ent = &(zip->ent);
sprintf(crc, "%08x", (unsigned int)ent->crc32);
if (filename == NULL || equal_filename(ent->name, filename)
if (readuncompresszip(zip, ent, (char *)*buf) != 0)
{
- cache_closezip(zip);
+ closezip(zip);
return -1;
}
- cache_suspendzip(zip);
+ suspendzip(zip);
return 0;
}
}
- cache_suspendzip(zip);
+ suspendzip(zip);
return -1;
}