More work on the ROM audit functionality.

git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1430 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2008-03-14 19:34:57 +00:00
parent bea44bafff
commit ea4305760b
10 changed files with 150 additions and 169 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FSNode.hxx,v 1.13 2008-02-06 13:45:21 stephena Exp $
// $Id: FSNode.hxx,v 1.14 2008-03-14 19:34:56 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -140,6 +140,11 @@ class AbstractFilesystemNode
*/
static bool makeDir(const string& path);
/**
Rename the given file/directory with a new name.
*/
static bool rename(const string& oldpath, const string& newpath);
/* TODO:
bool isReadable();
bool isWriteable();

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: OSystem.cxx,v 1.117 2008-03-13 22:58:06 stephena Exp $
// $Id: OSystem.cxx,v 1.118 2008-03-14 19:34:56 stephena Exp $
//============================================================================
#include <cassert>
@ -566,6 +566,36 @@ bool OSystem::openROM(const string& rom, string& md5, uInt8** image, int* size)
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool OSystem::isValidRomName(const string& filename, string& extension)
{
string::size_type idx = filename.find_last_of('.');
if(idx != string::npos)
{
extension = filename.substr(idx+1);
return BSPF_strncasecmp(extension.c_str(), "bin", 3) == 0 ||
BSPF_strncasecmp(extension.c_str(), "a26", 3) == 0 ||
BSPF_strncasecmp(extension.c_str(), "zip", 3) == 0 ||
BSPF_strncasecmp(extension.c_str(), "rom", 3) == 0 ||
BSPF_strncasecmp(extension.c_str(), "gz", 2) == 0 ;
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string OSystem::MD5FromFile(const string& filename)
{
uInt8* image;
int size = -1;
string md5 = "";
if(openROM(filename, md5, &image, &size))
if(size != -1)
delete[] image;
return md5;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string OSystem::getROMInfo(const string& romfile)
{

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: OSystem.hxx,v 1.61 2008-03-13 22:58:06 stephena Exp $
// $Id: OSystem.hxx,v 1.62 2008-03-14 19:34:56 stephena Exp $
//============================================================================
#ifndef OSYSTEM_HXX
@ -55,7 +55,7 @@ typedef Common::Array<Resolution> ResolutionList;
other objects belong.
@author Stephen Anthony
@version $Id: OSystem.hxx,v 1.61 2008-03-13 22:58:06 stephena Exp $
@version $Id: OSystem.hxx,v 1.62 2008-03-14 19:34:56 stephena Exp $
*/
class OSystem
{
@ -344,6 +344,21 @@ class OSystem
*/
bool openROM(const string& rom, string& md5, uInt8** image, int* size);
/**
Is this a valid ROM filename (does it have a valid extension?).
@param filename Filename of potential ROM file
@param extension The extension extracted from the given file
*/
bool isValidRomName(const string& filename, string& extension);
/**
Calculate the MD5sum of the given file.
@param filename Filename of potential ROM file
*/
string MD5FromFile(const string& filename);
/**
Issue a quit event to the OSystem.
*/

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FSNodeGP2X.cxx,v 1.6 2008-02-06 13:45:23 stephena Exp $
// $Id: FSNodeGP2X.cxx,v 1.7 2008-03-14 19:34:56 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -227,3 +227,11 @@ bool AbstractFilesystemNode::makeDir(const string& path)
{
return mkdir(path.c_str(), 0777) == 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool AbstractFilesystemNode::rename(const string& oldpath,
const string& newpath)
{
// TODO - implement this
return false;
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: LauncherDialog.cxx,v 1.79 2008-03-13 22:58:06 stephena Exp $
// $Id: LauncherDialog.cxx,v 1.80 2008-03-14 19:34:56 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -31,7 +31,6 @@
#include "MD5.hxx"
#include "OptionsDialog.hxx"
#include "OSystem.hxx"
#include "ProgressDialog.hxx"
#include "Props.hxx"
#include "PropsSet.hxx"
#include "RomInfoWidget.hxx"
@ -174,15 +173,16 @@ LauncherDialog::~LauncherDialog()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string LauncherDialog::selectedRomMD5()
{
string extension;
int item = myList->getSelected();
if(item < 0 || myGameList->isDir(item) ||
!isValidRomName(myGameList->name(item)))
!instance()->isValidRomName(myGameList->name(item), extension))
return "";
// Make sure we have a valid md5 for this ROM
if(myGameList->md5(item) == "")
{
const string& md5 = MD5FromFile(myGameList->path(item));
const string& md5 = instance()->MD5FromFile(myGameList->path(item));
myGameList->setMd5(item, md5);
}
return myGameList->md5(item);
@ -273,103 +273,6 @@ void LauncherDialog::loadDirListing()
myGameList->sortByName();
}
/*
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::loadListFromDisk()
{
string romdir = instance()->settings().getString("romdir");
FilesystemNode dir(romdir);
FSList files = dir.listDir(FilesystemNode::kListFilesOnly);
// Create a progress dialog box to show the progress of processing
// the ROMs, since this is usually a time-consuming operation
ProgressDialog progress(this, instance()->launcherFont(),
"Loading ROM info from disk ...");
progress.setRange(0, files.size() - 1, 10);
// Create a entry for the GameList for each file
Properties props;
for(unsigned int idx = 0; idx < files.size(); idx++)
{
// Calculate the MD5 so we can get the rest of the info
// from the PropertiesSet (stella.pro)
const string& md5 = MD5FromFile(files[idx].path());
instance()->propSet().getMD5(md5, props);
const string& name = props.get(Cartridge_Name);
// Indicate that this ROM doesn't have a properties entry
myGameList->appendGame(name, files[idx].path(), md5);
// Update the progress bar, indicating one more ROM has been processed
progress.setProgress(idx);
}
progress.done();
// Sort the list by rom name (since that's what we see in the listview)
myGameList->sortByName();
// And create a cache file, so that the next time Stella starts,
// we don't have to do this time-consuming operation again
createListCache();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::loadListFromCache()
{
string cacheFile = instance()->cacheFile();
ifstream in(cacheFile.c_str());
if(!in)
{
loadListFromDisk();
return;
}
// It seems terribly ugly that we need to use char arrays
// instead of strings. Or maybe I don't know the correct way ??
char buf[2048];
string line, name, path, note;
string::size_type pos1, pos2; // The locations of the two '|' characters
// Keep reading until all lines have been inspected
while(!in.eof())
{
in.getline(buf, 2048);
line = buf;
// Now split the line into three parts
pos1 = line.find("|", 0);
if(pos1 == string::npos) continue;
pos2 = line.find("|", pos1+1);
if(pos2 == string::npos) continue;
path = line.substr(0, pos1);
name = line.substr(pos1+1, pos2-pos1-1);
note = line.substr(pos2+1);
// Add this game to the list
// We don't do sorting, since it's assumed to be done by loadListFromDisk()
myGameList->appendGame(name, path, note);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::createListCache()
{
string cacheFile = instance()->cacheFile();
ofstream out(cacheFile.c_str());
// Write the gamelist to the cachefile (sorting is already done)
for (int i = 0; i < (int) myGameList->size(); ++i)
{
out << myGameList->path(i) << "|"
<< myGameList->name(i) << "|"
<< myGameList->md5(i)
<< endl;
}
out.close();
}
*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::loadRomInfo()
{
@ -377,11 +280,12 @@ void LauncherDialog::loadRomInfo()
int item = myList->getSelected();
if(item < 0 || myGameList->isDir(item)) return;
if(isValidRomName(myGameList->name(item)))
string extension;
if(instance()->isValidRomName(myGameList->name(item), extension))
{
// Make sure we have a valid md5 for this ROM
if(myGameList->md5(item) == "")
myGameList->setMd5(item, MD5FromFile(myGameList->path(item)));
myGameList->setMd5(item, instance()->MD5FromFile(myGameList->path(item)));
// Get the properties for this entry
Properties props;
@ -394,36 +298,6 @@ void LauncherDialog::loadRomInfo()
myRomInfoWidget->clearProperties();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string LauncherDialog::MD5FromFile(const string& path)
{
uInt8* image;
int size = -1;
string md5 = "";
if(instance()->openROM(path, md5, &image, &size))
if(size != -1)
delete[] image;
return md5;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool LauncherDialog::isValidRomName(const string& filename)
{
string::size_type idx = filename.find_last_of('.');
if(idx != string::npos)
{
string ext = filename.substr(idx+1);
return BSPF_strncasecmp(ext.c_str(), "bin", 3) == 0 ||
BSPF_strncasecmp(ext.c_str(), "a26", 3) == 0 ||
BSPF_strncasecmp(ext.c_str(), "zip", 3) == 0 ||
BSPF_strncasecmp(ext.c_str(), "rom", 3) == 0 ||
BSPF_strncasecmp(ext.c_str(), "gz", 2) == 0 ;
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
int data, int id)
@ -439,6 +313,7 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
{
const string& rom = myGameList->path(item);
const string& md5 = myGameList->md5(item);
string extension;
// Directory's should be selected (ie, enter them and redisplay)
if(myGameList->isDir(item))
@ -449,7 +324,8 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
myCurrentNode = rom;
updateListing();
}
else if(!isValidRomName(rom) || !instance()->createConsole(rom, md5))
else if(!instance()->isValidRomName(rom, extension) ||
!instance()->createConsole(rom, md5))
{
// TODO - show messagebox that ROM couldn't be started
cerr << "Error: invalid ROM (name or file)\n";

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: LauncherDialog.hxx,v 1.33 2008-03-12 22:04:53 stephena Exp $
// $Id: LauncherDialog.hxx,v 1.34 2008-03-14 19:34:56 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -61,13 +61,6 @@ class LauncherDialog : public Dialog
*/
string selectedRomMD5();
/**
Is this a valid ROM filename (does it have a valid extension?)
@param filename Filename of potential ROM file
*/
static bool isValidRomName(const string& filename);
protected:
virtual void handleCommand(CommandSender* sender, int cmd, int data, int id);
@ -95,7 +88,6 @@ class LauncherDialog : public Dialog
void enableButtons(bool enable);
void loadDirListing();
void loadRomInfo();
string MD5FromFile(const string& path);
private:
int mySelectedItem;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: RomAuditDialog.cxx,v 1.1 2008-03-14 15:23:24 stephena Exp $
// $Id: RomAuditDialog.cxx,v 1.2 2008-03-14 19:34:56 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -24,7 +24,10 @@
#include "BrowserDialog.hxx"
#include "DialogContainer.hxx"
#include "EditTextWidget.hxx"
#include "ProgressDialog.hxx"
#include "FSNode.hxx"
#include "Props.hxx"
#include "PropsSet.hxx"
#include "Settings.hxx"
#include "RomAuditDialog.hxx"
@ -70,11 +73,11 @@ RomAuditDialog::RomAuditDialog(OSystem* osystem, DialogContainer* parent,
b = addButton(font, _w - 2 * (kButtonWidth + 7), _h - 24, "Audit", kOKCmd);
wid.push_back(b);
addOKWidget(b);
b = addButton(font, _w - (kButtonWidth + 10), _h - 24, "Cancel", kCloseCmd);
b = addButton(font, _w - (kButtonWidth + 10), _h - 24, "Close", kCloseCmd);
wid.push_back(b);
addCancelWidget(b);
#else
b = addButton(font, _w - 2 * (kButtonWidth + 7), _h - 24, "Cancel", kCloseCmd);
b = addButton(font, _w - 2 * (kButtonWidth + 7), _h - 24, "Close", kCloseCmd);
wid.push_back(b);
addCancelWidget(b);
b = addButton(font, _w - (kButtonWidth + 10), _h - 24, "Audit", kOKCmd);
@ -103,7 +106,52 @@ void RomAuditDialog::loadConfig()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomAuditDialog::auditRoms()
{
cerr << "do rom audit\n";
const string& auditPath = myRomPath->getEditString();
FilesystemNode node(auditPath);
FSList files = node.listDir(FilesystemNode::kListFilesOnly);
// Create a progress dialog box to show the progress of processing
// the ROMs, since this is usually a time-consuming operation
ProgressDialog progress(this, instance()->launcherFont(),
"Auditing ROM files ...");
progress.setRange(0, files.size() - 1, 10);
// Create a entry for the GameList for each file
Properties props;
int renamed = 0, notfound = 0;
for(unsigned int idx = 0; idx < files.size(); idx++)
{
string extension;
if(!files[idx].isDirectory() &&
instance()->isValidRomName(files[idx].path(), extension))
{
// Calculate the MD5 so we can get the rest of the info
// from the PropertiesSet (stella.pro)
const string& md5 = instance()->MD5FromFile(files[idx].path());
instance()->propSet().getMD5(md5, props);
const string& name = props.get(Cartridge_Name);
// Only rename the file if we found a valid properties entry
if(name != "" && name != files[idx].path())
{
const string& newfile =
auditPath + BSPF_PATH_SEPARATOR + name + "." + extension;
if(FilesystemNode::rename(files[idx].path(), newfile))
renamed++;
}
else
notfound++;
}
// Update the progress bar, indicating one more ROM has been processed
progress.setProgress(idx);
}
progress.done();
cerr << "scanned files: " << (files.size() - 1) << endl;
cerr << "renamed files: " << renamed << endl;
cerr << "files without properties: " << notfound << endl;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FSNodePOSIX.cxx,v 1.12 2008-02-06 13:45:24 stephena Exp $
// $Id: FSNodePOSIX.cxx,v 1.13 2008-03-14 19:34:56 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -231,3 +231,12 @@ bool AbstractFilesystemNode::makeDir(const string& path)
{
return mkdir(path.c_str(), 0777) == 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool AbstractFilesystemNode::rename(const string& oldpath,
const string& newpath)
{
cerr << "rename: " << oldpath << " -> " << newpath << endl;
// TODO - implement this
return true;
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FSNodeWin32.cxx,v 1.12 2008-02-06 13:45:24 stephena Exp $
// $Id: FSNodeWin32.cxx,v 1.13 2008-03-14 19:34:56 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -280,3 +280,12 @@ bool AbstractFilesystemNode::makeDir(const string& path)
{
return CreateDirectory(path.c_str(), NULL) != 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool AbstractFilesystemNode::rename(const string& oldpath,
const string& newpath)
{
cerr << "rename: " << oldpath << " -> " << newpath << endl;
// TODO - implement this
return false;
}

View File

@ -271,20 +271,9 @@ bool AbstractFilesystemNode::makeDir(const string& path)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string AbstractFilesystemNode::modTime(const string& path)
bool AbstractFilesystemNode::rename(const string& oldpath,
const string& newpath)
{
WIN32_FILE_ATTRIBUTE_DATA attr;
static TCHAR unicodeString[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, path.c_str(), strlen(path.c_str()) + 1, unicodeString, sizeof(unicodeString));
BOOL b = GetFileAttributesEx(unicodeString, GetFileExInfoStandard, &attr);
if(b == 0) return "";
ostringstream buf;
buf << attr.ftLastWriteTime.dwHighDateTime << attr.ftLastWriteTime.dwLowDateTime;
return buf.str();
// TODO - implement this
return false;
}