mirror of https://github.com/stella-emu/stella.git
Loading from ZIP files now works from the ROM launcher. Still TODO
is add support for from the commandline, as well as optimizations (automatically loading the first ROM when only one exists, or when the name of the ZIP file itself is used). git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2608 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
28fa4af875
commit
29cc0df572
|
@ -83,8 +83,8 @@ void FilesystemNodeZIP::setFlags(const string& zipfile,
|
||||||
if(_virtualFile.size() != 0)
|
if(_virtualFile.size() != 0)
|
||||||
{
|
{
|
||||||
_isVirtual = true;
|
_isVirtual = true;
|
||||||
_path += (BSPF_PATH_SEPARATOR + _virtualFile);
|
_path += ("/" + _virtualFile);
|
||||||
_shortPath += (BSPF_PATH_SEPARATOR + _virtualFile);
|
_shortPath += ("/" + _virtualFile);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_isVirtual = false;
|
_isVirtual = false;
|
||||||
|
@ -112,6 +112,32 @@ bool FilesystemNodeZIP::getChildren(AbstractFSList& myList, ListMode mode,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool FilesystemNodeZIP::read(uInt8*& image, uInt32& size) const
|
||||||
|
{
|
||||||
|
cerr << "FilesystemNodeZIP::read" << endl
|
||||||
|
<< " zfile: " << _zipFile << endl
|
||||||
|
<< " vfile: " << _virtualFile << endl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
ZipHandler& zip = OSystem::zip(_zipFile);
|
||||||
|
bool found = false;
|
||||||
|
while(zip.hasNext() && !found)
|
||||||
|
{
|
||||||
|
const string& next = zip.next();
|
||||||
|
cerr << "searching: " << next << endl;
|
||||||
|
found = _virtualFile == next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(found)
|
||||||
|
{
|
||||||
|
cerr << "decompressing ...\n";
|
||||||
|
return zip.decompress(image, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool FilesystemNodeZIP::isAbsolute() const
|
bool FilesystemNodeZIP::isAbsolute() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,6 +66,8 @@ class FilesystemNodeZIP : public AbstractFSNode
|
||||||
bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const;
|
bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const;
|
||||||
AbstractFSNode* getParent() const;
|
AbstractFSNode* getParent() const;
|
||||||
|
|
||||||
|
bool read(uInt8*& image, uInt32& size) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FilesystemNodeZIP(const string& zipfile, const string& virtualfile,
|
FilesystemNodeZIP(const string& zipfile, const string& virtualfile,
|
||||||
Common::SharedPtr<AbstractFSNode> realnode);
|
Common::SharedPtr<AbstractFSNode> realnode);
|
||||||
|
|
|
@ -82,9 +82,22 @@ string ZipHandler::next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool ZipHandler::decompress(uInt8* buffer, uInt32 length)
|
bool ZipHandler::decompress(uInt8*& image, uInt32& length)
|
||||||
{
|
{
|
||||||
return myZip && (zip_file_decompress(myZip, buffer, length) == ZIPERR_NONE);
|
if(myZip)
|
||||||
|
{
|
||||||
|
length = myZip->header.uncompressed_length;
|
||||||
|
image = new uInt8[length];
|
||||||
|
if(zip_file_decompress(myZip, image, length) != ZIPERR_NONE)
|
||||||
|
{
|
||||||
|
delete[] image; image = 0;
|
||||||
|
length = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
|
|
|
@ -80,7 +80,7 @@ class ZipHandler
|
||||||
string next(); // Get next file
|
string next(); // Get next file
|
||||||
|
|
||||||
// Decompress the currently selected file, return false on any errors
|
// Decompress the currently selected file, return false on any errors
|
||||||
bool decompress(uInt8* buffer, uInt32 length);
|
bool decompress(uInt8*& image, uInt32& length);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Replaces functionaity of various osd_xxxx functions
|
// Replaces functionaity of various osd_xxxx functions
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
// Copyright (C) 2002-2004 The ScummVM project
|
// Copyright (C) 2002-2004 The ScummVM project
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "SharedPtr.hxx"
|
#include "SharedPtr.hxx"
|
||||||
#include "FSNodeFactory.hxx"
|
#include "FSNodeFactory.hxx"
|
||||||
|
@ -154,6 +156,26 @@ bool FilesystemNode::rename(const string& newfile)
|
||||||
return (_realNode && _realNode->exists()) ? _realNode->rename(newfile) : false;
|
return (_realNode && _realNode->exists()) ? _realNode->rename(newfile) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool FilesystemNode::read(uInt8*& image, uInt32& size) const
|
||||||
|
{
|
||||||
|
// First let the private subclass attempt to open the file
|
||||||
|
if(_realNode->read(image, size))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Otherwise, assume the file is either gzip'ed or not compressed at all
|
||||||
|
gzFile f = gzopen(getPath().c_str(), "rb");
|
||||||
|
if(f)
|
||||||
|
{
|
||||||
|
image = new uInt8[512 * 1024];
|
||||||
|
size = gzread(f, image, 512 * 1024);
|
||||||
|
gzclose(f);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string FilesystemNode::createAbsolutePath(
|
string FilesystemNode::createAbsolutePath(
|
||||||
const string& p, const string& startpath, const string& ext)
|
const string& p, const string& startpath, const string& ext)
|
||||||
|
|
|
@ -228,12 +228,23 @@ class FilesystemNode
|
||||||
virtual bool makeDir();
|
virtual bool makeDir();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Rename the current node path with the new given name.
|
* Rename the current node path with the new given name.
|
||||||
*
|
*
|
||||||
* @return bool true if the node was renamed, false otherwise.
|
* @return bool true if the node was renamed, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool rename(const string& newfile);
|
virtual bool rename(const string& newfile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read data (binary format) into the given buffer.
|
||||||
|
*
|
||||||
|
* @param buffer The buffer to containing the data
|
||||||
|
* This will be allocated by the method, and must be
|
||||||
|
* freed by the caller.
|
||||||
|
* @param size Holds the size of the created buffer.
|
||||||
|
* @return True if the read succeeded, else false for any reason
|
||||||
|
*/
|
||||||
|
virtual bool read(uInt8*& buffer, uInt32& size) const;
|
||||||
|
|
||||||
// TODO - this function is deprecated, and will be removed soon ...
|
// TODO - this function is deprecated, and will be removed soon ...
|
||||||
/**
|
/**
|
||||||
Create an absolute pathname from the given path (if it isn't already
|
Create an absolute pathname from the given path (if it isn't already
|
||||||
|
@ -366,12 +377,23 @@ class AbstractFSNode
|
||||||
virtual bool makeDir() = 0;
|
virtual bool makeDir() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Rename the current node path with the new given name.
|
* Rename the current node path with the new given name.
|
||||||
*
|
*
|
||||||
* @return bool true if the node was renamed, false otherwise.
|
* @return bool true if the node was renamed, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool rename(const string& newfile) = 0;
|
virtual bool rename(const string& newfile) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read data (binary format) into the given buffer.
|
||||||
|
*
|
||||||
|
* @param buffer The buffer to containing the data
|
||||||
|
* This will be allocated by the method, and must be
|
||||||
|
* freed by the caller.
|
||||||
|
* @param size Holds the size of the created buffer.
|
||||||
|
* @return True if the read succeeded, else false for any reason
|
||||||
|
*/
|
||||||
|
virtual bool read(uInt8*& buffer, uInt32& size) const { return false; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The parent node of this directory.
|
* The parent node of this directory.
|
||||||
* The parent of the root is the root itself.
|
* The parent of the root is the root itself.
|
||||||
|
|
|
@ -345,3 +345,16 @@ string MD5(const uInt8* buffer, uInt32 length)
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string MD5(const FilesystemNode& node)
|
||||||
|
{
|
||||||
|
uInt8* image = 0;
|
||||||
|
uInt32 size = 0;
|
||||||
|
if(!node.read(image, size))
|
||||||
|
return EmptyString;
|
||||||
|
|
||||||
|
const string& md5 = MD5(image, size);
|
||||||
|
delete[] image;
|
||||||
|
return md5;
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#ifndef MD5_HXX
|
#ifndef MD5_HXX
|
||||||
#define MD5_HXX
|
#define MD5_HXX
|
||||||
|
|
||||||
|
#include "FSNode.hxx"
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,4 +33,13 @@
|
||||||
*/
|
*/
|
||||||
string MD5(const uInt8* buffer, uInt32 length);
|
string MD5(const uInt8* buffer, uInt32 length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the MD5 Message-Digest of the file contained in 'node'.
|
||||||
|
The digest consists of 32 hexadecimal digits.
|
||||||
|
|
||||||
|
@param node The file node to compute the digest of
|
||||||
|
@return The message-digest
|
||||||
|
*/
|
||||||
|
string MD5(const FilesystemNode& node);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <zlib.h>
|
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#ifdef HAVE_GETTIMEOFDAY
|
#ifdef HAVE_GETTIMEOFDAY
|
||||||
|
@ -71,8 +70,6 @@
|
||||||
|
|
||||||
#include "OSystem.hxx"
|
#include "OSystem.hxx"
|
||||||
|
|
||||||
#define MAX_ROM_SIZE 512 * 1024
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
OSystem::OSystem()
|
OSystem::OSystem()
|
||||||
: myEventHandler(NULL),
|
: myEventHandler(NULL),
|
||||||
|
@ -662,20 +659,6 @@ string OSystem::getROMInfo(const FilesystemNode& romfile)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string OSystem::MD5FromFile(const FilesystemNode& file)
|
|
||||||
{
|
|
||||||
string md5 = "";
|
|
||||||
|
|
||||||
uInt8* image = 0;
|
|
||||||
uInt32 size = 0;
|
|
||||||
if((image = openROM(file, md5, size)) != 0)
|
|
||||||
if(image != 0 && size > 0)
|
|
||||||
delete[] image;
|
|
||||||
|
|
||||||
return md5;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void OSystem::logMessage(const string& message, uInt8 level)
|
void OSystem::logMessage(const string& message, uInt8 level)
|
||||||
{
|
{
|
||||||
|
@ -725,7 +708,7 @@ Console* OSystem::openConsole(const FilesystemNode& romfile, string& md5,
|
||||||
// and that the md5 (and hence the cart) has changed
|
// and that the md5 (and hence the cart) has changed
|
||||||
if(props.get(Cartridge_MD5) != cartmd5)
|
if(props.get(Cartridge_MD5) != cartmd5)
|
||||||
{
|
{
|
||||||
string name = props.get(Cartridge_Name);
|
const string& name = props.get(Cartridge_Name);
|
||||||
if(!myPropSet->getMD5(cartmd5, props))
|
if(!myPropSet->getMD5(cartmd5, props))
|
||||||
{
|
{
|
||||||
// Cart md5 wasn't found, so we create a new props for it
|
// Cart md5 wasn't found, so we create a new props for it
|
||||||
|
@ -771,7 +754,7 @@ Console* OSystem::openConsole(const FilesystemNode& romfile, string& md5,
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt8* OSystem::openROM(const FilesystemNode& romfile, string& md5, uInt32& size)
|
uInt8* OSystem::openROM(const FilesystemNode& rom, string& md5, uInt32& size)
|
||||||
{
|
{
|
||||||
// This method has a documented side-effect:
|
// This method has a documented side-effect:
|
||||||
// It not only loads a ROM and creates an array with its contents,
|
// It not only loads a ROM and creates an array with its contents,
|
||||||
|
@ -779,32 +762,7 @@ uInt8* OSystem::openROM(const FilesystemNode& romfile, string& md5, uInt32& size
|
||||||
// contain a valid name
|
// contain a valid name
|
||||||
|
|
||||||
uInt8* image = 0;
|
uInt8* image = 0;
|
||||||
|
if(!rom.read(image, size))
|
||||||
// FIXME - this entire code to be replaced by romfile.read(...)
|
|
||||||
#if 0
|
|
||||||
// First try to load as ZIP archive
|
|
||||||
if(loadFromZIP(file, &image, size))
|
|
||||||
{
|
|
||||||
// Empty file means it *was* a ZIP file, but it didn't contain
|
|
||||||
// a valid ROM
|
|
||||||
if(image == 0)
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
// Assume the file is either gzip'ed or not compressed at all
|
|
||||||
gzFile f = gzopen(romfile.getPath().c_str(), "rb");
|
|
||||||
if(!f)
|
|
||||||
return image;
|
|
||||||
|
|
||||||
image = new uInt8[MAX_ROM_SIZE];
|
|
||||||
size = gzread(f, image, MAX_ROM_SIZE);
|
|
||||||
gzclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zero-byte files should be automatically discarded
|
|
||||||
if(size == 0)
|
|
||||||
{
|
{
|
||||||
delete[] image;
|
delete[] image;
|
||||||
return (uInt8*) 0;
|
return (uInt8*) 0;
|
||||||
|
@ -820,108 +778,11 @@ uInt8* OSystem::openROM(const FilesystemNode& romfile, string& md5, uInt32& size
|
||||||
// be an entry in stella.pro. In that case, we use the rom name
|
// be an entry in stella.pro. In that case, we use the rom name
|
||||||
// and reinsert the properties object
|
// and reinsert the properties object
|
||||||
Properties props;
|
Properties props;
|
||||||
if(!myPropSet->getMD5(md5, props))
|
myPropSet->getMD5WithInsert(rom, md5, props);
|
||||||
{
|
|
||||||
props.set(Cartridge_MD5, md5);
|
|
||||||
props.set(Cartridge_Name, romfile.getName());
|
|
||||||
myPropSet->insert(props, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool OSystem::loadFromZIP(const string& filename, uInt8** image, uInt32& size)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
#if 0 // FIXME
|
|
||||||
// First determine if this actually is a ZIP file
|
|
||||||
// by seeing if it contains the '.zip' extension
|
|
||||||
size_t extpos = BSPF_findIgnoreCase(filename, ".zip");
|
|
||||||
if(extpos == string::npos)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Now get the file after the .zip extension (if any)
|
|
||||||
string archive = filename, fileinzip = "";
|
|
||||||
if(filename.size() > extpos + 4)
|
|
||||||
{
|
|
||||||
archive = filename.substr(0, extpos + 4);
|
|
||||||
fileinzip = filename.substr(extpos + 5);
|
|
||||||
if(fileinzip.size() == 0)
|
|
||||||
return true; // This was a ZIP file, but invalid name
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open archive
|
|
||||||
FilesystemNode searchnode(fileinzip);
|
|
||||||
unzFile tz;
|
|
||||||
bool found = false;
|
|
||||||
if((tz = unzOpen(archive.c_str())) != NULL)
|
|
||||||
{
|
|
||||||
if(unzGoToFirstFile(tz) == UNZ_OK)
|
|
||||||
{
|
|
||||||
unz_file_info ufo;
|
|
||||||
|
|
||||||
for(;;) // Loop through all files for valid 2600 images
|
|
||||||
{
|
|
||||||
// Longer filenames might be possible, but I don't
|
|
||||||
// think people would name files that long in zip files...
|
|
||||||
char currfile[1024];
|
|
||||||
|
|
||||||
unzGetCurrentFileInfo(tz, &ufo, currfile, 1024, 0, 0, 0, 0);
|
|
||||||
currfile[1023] = '\0';
|
|
||||||
|
|
||||||
if(strlen(currfile) >= 4 &&
|
|
||||||
!BSPF_startsWithIgnoreCase(filename, "__MACOSX"))
|
|
||||||
{
|
|
||||||
// Grab 3-character extension
|
|
||||||
const char* ext = currfile + strlen(currfile) - 4;
|
|
||||||
|
|
||||||
if(BSPF_equalsIgnoreCase(ext, ".a26") || BSPF_equalsIgnoreCase(ext, ".bin") ||
|
|
||||||
BSPF_equalsIgnoreCase(ext, ".rom"))
|
|
||||||
{
|
|
||||||
// Either match the first file or the one we're looking for
|
|
||||||
if(fileinzip.empty() || searchnode == FilesystemNode(currfile))
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan the next file in the zip
|
|
||||||
if(unzGoToNextFile(tz) != UNZ_OK)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now see if we got a valid image
|
|
||||||
if(!found || ufo.uncompressed_size <= 0)
|
|
||||||
{
|
|
||||||
unzClose(tz);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
size = ufo.uncompressed_size;
|
|
||||||
*image = new uInt8[size];
|
|
||||||
|
|
||||||
// We don't have to check for any return errors from these functions,
|
|
||||||
// since if there are, 'image' will not contain a valid ROM and the
|
|
||||||
// calling method can take care of it
|
|
||||||
unzOpenCurrentFile(tz);
|
|
||||||
unzReadCurrentFile(tz, *image, size);
|
|
||||||
unzCloseCurrentFile(tz);
|
|
||||||
unzClose(tz);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unzClose(tz);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string OSystem::getROMInfo(const Console* console)
|
string OSystem::getROMInfo(const Console* console)
|
||||||
{
|
{
|
||||||
|
|
|
@ -432,13 +432,6 @@ class OSystem
|
||||||
*/
|
*/
|
||||||
const string& buildInfo() const { return myBuildInfo; }
|
const string& buildInfo() const { return myBuildInfo; }
|
||||||
|
|
||||||
/**
|
|
||||||
Calculate the MD5sum of the given file.
|
|
||||||
|
|
||||||
@param file File node of potential ROM file
|
|
||||||
*/
|
|
||||||
string MD5FromFile(const FilesystemNode& file);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Issue a quit event to the OSystem.
|
Issue a quit event to the OSystem.
|
||||||
*/
|
*/
|
||||||
|
@ -701,21 +694,6 @@ class OSystem
|
||||||
*/
|
*/
|
||||||
uInt8* openROM(const FilesystemNode& rom, string& md5, uInt32& size);
|
uInt8* openROM(const FilesystemNode& rom, string& md5, uInt32& size);
|
||||||
|
|
||||||
/**
|
|
||||||
Open the given ZIP archive, parsing filename for the contents of the
|
|
||||||
desired file to load. If the filename ends in '.zip', use the first
|
|
||||||
file found in the archive, otherwise traverse the archive and use the
|
|
||||||
file specified after '.zip' in the filename.
|
|
||||||
|
|
||||||
@param name The absolute pathname of the file
|
|
||||||
@param image Pointer to the array, with size >=0 indicating valid data
|
|
||||||
@param size The amount of data read into the image array
|
|
||||||
|
|
||||||
@return True if this was a zip file (regardless of whether it
|
|
||||||
actually loaded any valid data, else false
|
|
||||||
*/
|
|
||||||
bool loadFromZIP(const string& filename, uInt8** image, uInt32& size);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Gets all possible info about the given console.
|
Gets all possible info about the given console.
|
||||||
|
|
||||||
|
|
|
@ -148,6 +148,23 @@ bool PropertiesSet::getMD5(const string& md5, Properties& properties,
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void PropertiesSet::getMD5WithInsert(const FilesystemNode& rom,
|
||||||
|
const string& md5, Properties& properties)
|
||||||
|
{
|
||||||
|
if(!getMD5(md5, properties))
|
||||||
|
{
|
||||||
|
// Create a name suitable for using in properties
|
||||||
|
size_t pos = rom.getName().find_last_of("/\\");
|
||||||
|
const string& name = pos == string::npos ? rom.getName() :
|
||||||
|
rom.getName().substr(pos+1);
|
||||||
|
|
||||||
|
properties.set(Cartridge_MD5, md5);
|
||||||
|
properties.set(Cartridge_Name, name);
|
||||||
|
insert(properties, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void PropertiesSet::insert(const Properties& properties, bool save)
|
void PropertiesSet::insert(const Properties& properties, bool save)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
|
#include "FSNode.hxx"
|
||||||
#include "Props.hxx"
|
#include "Props.hxx"
|
||||||
|
|
||||||
class OSystem;
|
class OSystem;
|
||||||
|
@ -84,6 +85,21 @@ class PropertiesSet
|
||||||
bool getMD5(const string& md5, Properties& properties,
|
bool getMD5(const string& md5, Properties& properties,
|
||||||
bool useDefaults = false) const;
|
bool useDefaults = false) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the property from the set with the given MD5, at the same time
|
||||||
|
checking if it exists. If it doesn't, insert a temporary copy into
|
||||||
|
the set.
|
||||||
|
|
||||||
|
@param file The node representing the
|
||||||
|
@param md5 The md5 of the property to get
|
||||||
|
@param properties The properties with the given MD5, or the default
|
||||||
|
properties if not found
|
||||||
|
@param defaults Use the built-in defaults, ignoring any properties
|
||||||
|
from an external file
|
||||||
|
*/
|
||||||
|
void getMD5WithInsert(const FilesystemNode& rom, const string& md5,
|
||||||
|
Properties& properties);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Insert the properties into the set. If a duplicate is inserted
|
Insert the properties into the set. If a duplicate is inserted
|
||||||
the old properties are overwritten with the new ones.
|
the old properties are overwritten with the new ones.
|
||||||
|
|
|
@ -226,10 +226,8 @@ const string& LauncherDialog::selectedRomMD5()
|
||||||
|
|
||||||
// Make sure we have a valid md5 for this ROM
|
// Make sure we have a valid md5 for this ROM
|
||||||
if(myGameList->md5(item) == "")
|
if(myGameList->md5(item) == "")
|
||||||
{
|
myGameList->setMd5(item, MD5(node));
|
||||||
const string& md5 = instance().MD5FromFile(node);
|
|
||||||
myGameList->setMd5(item, md5);
|
|
||||||
}
|
|
||||||
return myGameList->md5(item);
|
return myGameList->md5(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,51 +351,6 @@ void LauncherDialog::loadDirListing()
|
||||||
if(myCurrentNode.isDirectory())
|
if(myCurrentNode.isDirectory())
|
||||||
myCurrentNode.getChildren(files, FilesystemNode::kListAll);
|
myCurrentNode.getChildren(files, FilesystemNode::kListAll);
|
||||||
|
|
||||||
#if 0
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unzFile tz;
|
|
||||||
if((tz = unzOpen(myCurrentNode.getPath().c_str())) != NULL)
|
|
||||||
{
|
|
||||||
if(unzGoToFirstFile(tz) == UNZ_OK)
|
|
||||||
{
|
|
||||||
unz_file_info ufo;
|
|
||||||
|
|
||||||
for(;;) // Loop through all files for valid 2600 images
|
|
||||||
{
|
|
||||||
// Longer filenames might be possible, but I don't
|
|
||||||
// think people would name files that long in zip files...
|
|
||||||
char filename[1024];
|
|
||||||
|
|
||||||
unzGetCurrentFileInfo(tz, &ufo, filename, 1024, 0, 0, 0, 0);
|
|
||||||
filename[1023] = '\0';
|
|
||||||
|
|
||||||
if(strlen(filename) >= 4 &&
|
|
||||||
!BSPF_startsWithIgnoreCase(filename, "__MACOSX"))
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
// Grab 3-character extension
|
|
||||||
const char* ext = filename + strlen(filename) - 4;
|
|
||||||
|
|
||||||
if(BSPF_equalsIgnoreCase(ext, ".a26") || BSPF_equalsIgnoreCase(ext, ".bin") ||
|
|
||||||
BSPF_equalsIgnoreCase(ext, ".rom"))
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
FilesystemNode newFile(FilesystemNode::createAbsolutePath(
|
|
||||||
filename, myCurrentNode.getPath(), ""));
|
|
||||||
files.push_back(newFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan the next file in the zip
|
|
||||||
if(unzGoToNextFile(tz) != UNZ_OK)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Add '[..]' to indicate previous folder
|
// Add '[..]' to indicate previous folder
|
||||||
if(myCurrentNode.hasParent())
|
if(myCurrentNode.hasParent())
|
||||||
myGameList->appendGame(" [..]", "", "", true);
|
myGameList->appendGame(" [..]", "", "", true);
|
||||||
|
@ -445,11 +398,11 @@ void LauncherDialog::loadRomInfo()
|
||||||
{
|
{
|
||||||
// Make sure we have a valid md5 for this ROM
|
// Make sure we have a valid md5 for this ROM
|
||||||
if(myGameList->md5(item) == "")
|
if(myGameList->md5(item) == "")
|
||||||
myGameList->setMd5(item, instance().MD5FromFile(node));
|
myGameList->setMd5(item, MD5(node));
|
||||||
|
|
||||||
// Get the properties for this entry
|
// Get the properties for this entry
|
||||||
Properties props;
|
Properties props;
|
||||||
instance().propSet().getMD5(myGameList->md5(item), props);
|
instance().propSet().getMD5WithInsert(node, myGameList->md5(item), props);
|
||||||
|
|
||||||
myRomInfoWidget->setProperties(props);
|
myRomInfoWidget->setProperties(props);
|
||||||
}
|
}
|
||||||
|
@ -527,11 +480,12 @@ bool LauncherDialog::matchPattern(const string& s, const string& pattern) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
int LauncherDialog::filesInArchive(const string& archive)
|
int LauncherDialog::filesInArchive(const string& archive)
|
||||||
{
|
{
|
||||||
int count = -1;
|
int count = -1;
|
||||||
#if 0
|
|
||||||
unzFile tz;
|
unzFile tz;
|
||||||
if((tz = unzOpen(archive.c_str())) != NULL)
|
if((tz = unzOpen(archive.c_str())) != NULL)
|
||||||
{
|
{
|
||||||
|
@ -566,9 +520,9 @@ int LauncherDialog::filesInArchive(const string& archive)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void LauncherDialog::handleKeyDown(StellaKey key, StellaMod mod, char ascii)
|
void LauncherDialog::handleKeyDown(StellaKey key, StellaMod mod, char ascii)
|
||||||
|
|
|
@ -96,7 +96,6 @@ class LauncherDialog : public Dialog
|
||||||
void handleContextMenu();
|
void handleContextMenu();
|
||||||
void setListFilters();
|
void setListFilters();
|
||||||
bool matchPattern(const string& s, const string& pattern) const;
|
bool matchPattern(const string& s, const string& pattern) const;
|
||||||
int filesInArchive(const string& archive);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ButtonWidget* myStartButton;
|
ButtonWidget* myStartButton;
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "ProgressDialog.hxx"
|
#include "ProgressDialog.hxx"
|
||||||
#include "FSNode.hxx"
|
#include "FSNode.hxx"
|
||||||
#include "MessageBox.hxx"
|
#include "MessageBox.hxx"
|
||||||
|
#include "MD5.hxx"
|
||||||
#include "Props.hxx"
|
#include "Props.hxx"
|
||||||
#include "PropsSet.hxx"
|
#include "PropsSet.hxx"
|
||||||
#include "Settings.hxx"
|
#include "Settings.hxx"
|
||||||
|
@ -147,7 +148,7 @@ void RomAuditDialog::auditRoms()
|
||||||
{
|
{
|
||||||
// Calculate the MD5 so we can get the rest of the info
|
// Calculate the MD5 so we can get the rest of the info
|
||||||
// from the PropertiesSet (stella.pro)
|
// from the PropertiesSet (stella.pro)
|
||||||
const string& md5 = instance().MD5FromFile(files[idx]);
|
const string& md5 = MD5(files[idx]);
|
||||||
instance().propSet().getMD5(md5, props);
|
instance().propSet().getMD5(md5, props);
|
||||||
const string& name = props.get(Cartridge_Name);
|
const string& name = props.get(Cartridge_Name);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue