Fairly large restructuring of the 'BSType' code

- class has been renamed to 'Bankswitch'
- it is now a proper (static) class with namespacing

'Bankswitch' now contains all logic for determing what a proper ROM filename is.
So some functions have moved from LauncherFilterDialog to here (that class will be removed soon).

In the process, implemented issue 261 (file extension determines BS type to use).
This commit is contained in:
Stephen Anthony 2018-08-31 09:18:35 -02:30
parent 731a76e1a9
commit f098636965
13 changed files with 449 additions and 305 deletions

View File

@ -1,127 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2018 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef BSTYPE_HXX
#define BSTYPE_HXX
#include "bspf.hxx"
// Currently supported bankswitch schemes
enum class BSType {
_AUTO, _0840, _2IN1, _4IN1, _8IN1, _16IN1, _32IN1,
_64IN1, _128IN1, _2K, _3E, _3EP, _3F, _4A50,
_4K, _4KSC, _AR, _BF, _BFSC, _BUS, _CDF,
_CM, _CTY, _CV, _CVP, _DASH, _DF, _DFSC,
_DPC, _DPCP, _E0, _E7, _E78K, _EF, _EFSC,
_F0, _F4, _F4SC, _F6, _F6SC, _F8, _F8SC,
_FA, _FA2, _FE, _MDM, _SB, _UA, _WD,
_X07,
#ifdef CUSTOM_ARM
_CUSTOM,
#endif
NumSchemes
};
// Info about the various bankswitch schemes, useful for displaying
// in GUI dropdown boxes, etc
struct BSDescription {
const char* const name;
const char* const desc;
};
static BSDescription BSList[int(BSType::NumSchemes)] = {
{ "AUTO", "Auto-detect" },
{ "0840", "0840 (8K ECONObank)" },
{ "2IN1", "2IN1 Multicart (4-32K)" },
{ "4IN1", "4IN1 Multicart (8-32K)" },
{ "8IN1", "8IN1 Multicart (16-64K)" },
{ "16IN1", "16IN1 Multicart (32-128K)" },
{ "32IN1", "32IN1 Multicart (64/128K)" },
{ "64IN1", "64IN1 Multicart (128/256K)" },
{ "128IN1", "128IN1 Multicart (256/512K)" },
{ "2K", "2K (64-2048 bytes Atari)" },
{ "3E", "3E (32K Tigervision)" },
{ "3E+", "3E+ (TJ modified DASH)" },
{ "3F", "3F (512K Tigervision)" },
{ "4A50", "4A50 (64K 4A50 + ram)" },
{ "4K", "4K (4K Atari)" },
{ "4KSC", "4KSC (CPUWIZ 4K + ram)" },
{ "AR", "AR (Supercharger)" },
{ "BF", "BF (CPUWIZ 256K)" },
{ "BFSC", "BFSC (CPUWIZ 256K + ram)" },
{ "BUS", "BUS (Experimental)" },
{ "CDF", "CDF (Chris, Darrell, Fred)" },
{ "CM", "CM (SpectraVideo CompuMate)" },
{ "CTY", "CTY (CDW - Chetiry)" },
{ "CV", "CV (Commavid extra ram)" },
{ "CV+", "CV+ (Extended Commavid)" },
{ "DASH", "DASH (Experimental)" },
{ "DF", "DF (CPUWIZ 128K)" },
{ "DFSC", "DFSC (CPUWIZ 128K + ram)" },
{ "DPC", "DPC (Pitfall II)" },
{ "DPC+", "DPC+ (Enhanced DPC)" },
{ "E0", "E0 (8K Parker Bros)" },
{ "E7", "E7 (16K M-network)" },
{ "E78K", "E78K (8K M-network)" },
{ "EF", "EF (64K H. Runner)" },
{ "EFSC", "EFSC (64K H. Runner + ram)" },
{ "F0", "F0 (Dynacom Megaboy)" },
{ "F4", "F4 (32K Atari)" },
{ "F4SC", "F4SC (32K Atari + ram)" },
{ "F6", "F6 (16K Atari)" },
{ "F6SC", "F6SC (16K Atari + ram)" },
{ "F8", "F8 (8K Atari)" },
{ "F8SC", "F8SC (8K Atari + ram)" },
{ "FA", "FA (CBS RAM Plus)" },
{ "FA2", "FA2 (CBS RAM Plus 24/28K)" },
{ "FE", "FE (8K Decathlon)" },
{ "MDM", "MDM (Menu Driven Megacart)" },
{ "SB", "SB (128-256K SUPERbank)" },
{ "UA", "UA (8K UA Ltd.)" },
{ "WD", "WD (Experimental)" },
{ "X07", "X07 (64K AtariAge)" },
#ifdef CUSTOM_ARM
{ "CUSTOM", "CUSTOM (ARM)" }
#endif
};
class Bankswitch
{
public:
// Convert BSType enum to string
static string typeToName(BSType type) { return BSList[int(type)].name; }
// Convert string to BSType enum
static BSType nameToType(const string& name)
{
for(int i = 0; i < int(BSType::NumSchemes); ++i)
if(BSPF::equalsIgnoreCase(BSList[i].name, name))
return BSType(i);
return BSType::_AUTO;
}
private:
// Following constructors and assignment operators not supported
Bankswitch() = delete;
Bankswitch(const Bankswitch&) = delete;
Bankswitch(Bankswitch&&) = delete;
Bankswitch& operator=(const Bankswitch&) = delete;
Bankswitch& operator=(Bankswitch&&) = delete;
};
#endif

186
src/emucore/Bankswitch.cxx Normal file
View File

@ -0,0 +1,186 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2018 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include "Bankswitch.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string Bankswitch::typeToName(Bankswitch::Type type)
{
return BSList[int(type)].name;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bankswitch::Type Bankswitch::nameToType(const string& name)
{
for(int i = 0; i < int(Bankswitch::Type::NumSchemes); ++i)
if(BSPF::equalsIgnoreCase(BSList[i].name, name))
return Bankswitch::Type(i);
return Bankswitch::Type::_AUTO;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bankswitch::Type Bankswitch::typeFromExtension(const FilesystemNode& file)
{
const string& name = file.getPath();
string::size_type idx = name.find_last_of('.');
if(idx != string::npos)
{
auto it = ourExtensions.find(name.c_str() + idx + 1);
if(it != ourExtensions.end())
return it->second;
}
return Bankswitch::Type::_AUTO;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Bankswitch::isValidRomName(const FilesystemNode& file, string& ext)
{
const string& name = file.getPath();
string::size_type idx = name.find_last_of('.');
if(idx != string::npos)
{
const char* const e = name.c_str() + idx + 1;
auto it = ourExtensions.find(e);
if(it != ourExtensions.end())
{
ext = e;
return true;
}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Bankswitch::isValidRomName(const FilesystemNode& file)
{
string extension; // not actually used
return isValidRomName(file, extension);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bankswitch::Description Bankswitch::BSList[int(Bankswitch::Type::NumSchemes)] = {
{ "AUTO", "Auto-detect" },
{ "0840", "0840 (8K ECONObank)" },
{ "2IN1", "2IN1 Multicart (4-32K)" },
{ "4IN1", "4IN1 Multicart (8-32K)" },
{ "8IN1", "8IN1 Multicart (16-64K)" },
{ "16IN1", "16IN1 Multicart (32-128K)" },
{ "32IN1", "32IN1 Multicart (64/128K)" },
{ "64IN1", "64IN1 Multicart (128/256K)" },
{ "128IN1", "128IN1 Multicart (256/512K)" },
{ "2K", "2K (64-2048 bytes Atari)" },
{ "3E", "3E (32K Tigervision)" },
{ "3E+", "3E+ (TJ modified DASH)" },
{ "3F", "3F (512K Tigervision)" },
{ "4A50", "4A50 (64K 4A50 + ram)" },
{ "4K", "4K (4K Atari)" },
{ "4KSC", "4KSC (CPUWIZ 4K + ram)" },
{ "AR", "AR (Supercharger)" },
{ "BF", "BF (CPUWIZ 256K)" },
{ "BFSC", "BFSC (CPUWIZ 256K + ram)" },
{ "BUS", "BUS (Experimental)" },
{ "CDF", "CDF (Chris, Darrell, Fred)" },
{ "CM", "CM (SpectraVideo CompuMate)" },
{ "CTY", "CTY (CDW - Chetiry)" },
{ "CV", "CV (Commavid extra ram)" },
{ "CV+", "CV+ (Extended Commavid)" },
{ "DASH", "DASH (Experimental)" },
{ "DF", "DF (CPUWIZ 128K)" },
{ "DFSC", "DFSC (CPUWIZ 128K + ram)" },
{ "DPC", "DPC (Pitfall II)" },
{ "DPC+", "DPC+ (Enhanced DPC)" },
{ "E0", "E0 (8K Parker Bros)" },
{ "E7", "E7 (16K M-network)" },
{ "E78K", "E78K (8K M-network)" },
{ "EF", "EF (64K H. Runner)" },
{ "EFSC", "EFSC (64K H. Runner + ram)" },
{ "F0", "F0 (Dynacom Megaboy)" },
{ "F4", "F4 (32K Atari)" },
{ "F4SC", "F4SC (32K Atari + ram)" },
{ "F6", "F6 (16K Atari)" },
{ "F6SC", "F6SC (16K Atari + ram)" },
{ "F8", "F8 (8K Atari)" },
{ "F8SC", "F8SC (8K Atari + ram)" },
{ "FA", "FA (CBS RAM Plus)" },
{ "FA2", "FA2 (CBS RAM Plus 24/28K)" },
{ "FE", "FE (8K Decathlon)" },
{ "MDM", "MDM (Menu Driven Megacart)" },
{ "SB", "SB (128-256K SUPERbank)" },
{ "UA", "UA (8K UA Ltd.)" },
{ "WD", "WD (Experimental)" },
{ "X07", "X07 (64K AtariAge)" },
#ifdef CUSTOM_ARM
{ "CUSTOM", "CUSTOM (ARM)" }
#endif
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bankswitch::ExtensionMap Bankswitch::ourExtensions = {
// Normal file extensions that don't actually tell us anything
// about the bankswitch type to use
{ "a26", Bankswitch::Type::_AUTO },
{ "bin", Bankswitch::Type::_AUTO },
{ "rom", Bankswitch::Type::_AUTO },
{ "gz", Bankswitch::Type::_AUTO },
{ "zip", Bankswitch::Type::_AUTO },
{ "cu", Bankswitch::Type::_AUTO },
// Types from UnoCart and HarmonyCart
{ "084", Bankswitch::Type::_0840 },
{ "2K", Bankswitch::Type::_2K },
{ "3E", Bankswitch::Type::_3E },
{ "3EP", Bankswitch::Type::_3EP },
{ "3F", Bankswitch::Type::_3F },
{ "4A5", Bankswitch::Type::_4A50 },
{ "4K", Bankswitch::Type::_4K },
{ "4KS", Bankswitch::Type::_4KSC },
{ "AR", Bankswitch::Type::_AR },
{ "BF", Bankswitch::Type::_BF },
{ "BFS", Bankswitch::Type::_BFSC },
{ "BUS", Bankswitch::Type::_BUS },
{ "CDF", Bankswitch::Type::_CDF },
{ "CM", Bankswitch::Type::_CM },
{ "CTY", Bankswitch::Type::_CTY },
{ "CV", Bankswitch::Type::_CV },
{ "CVP", Bankswitch::Type::_CVP },
{ "DAS", Bankswitch::Type::_DASH },
{ "DF", Bankswitch::Type::_DF },
{ "DFS", Bankswitch::Type::_DFSC },
{ "DPC", Bankswitch::Type::_DPC },
{ "DPP", Bankswitch::Type::_DPCP },
{ "E0", Bankswitch::Type::_E0 },
{ "E7", Bankswitch::Type::_E7 },
{ "E78", Bankswitch::Type::_E78K },
{ "EF", Bankswitch::Type::_EF },
{ "EFS", Bankswitch::Type::_EFSC },
{ "F0", Bankswitch::Type::_F0 },
{ "F4", Bankswitch::Type::_F4 },
{ "F4S", Bankswitch::Type::_F4SC },
{ "F6", Bankswitch::Type::_F6 },
{ "F6S", Bankswitch::Type::_F6SC },
{ "F8", Bankswitch::Type::_F8 },
{ "F8S", Bankswitch::Type::_F8SC },
{ "FA", Bankswitch::Type::_FA },
{ "FA2", Bankswitch::Type::_FA2 },
{ "FE", Bankswitch::Type::_FE },
{ "MDM", Bankswitch::Type::_MDM },
{ "SB", Bankswitch::Type::_SB },
{ "UA", Bankswitch::Type::_UA },
{ "WD", Bankswitch::Type::_WD }
};

106
src/emucore/Bankswitch.hxx Normal file
View File

@ -0,0 +1,106 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2018 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef BANKSWITCH_HXX
#define BANKSWITCH_HXX
#include <map>
#include "FSNode.hxx"
#include "bspf.hxx"
/**
This class contains all information about the bankswitch schemes supported
by Stella, as well as convenience functions to map from scheme type to
readable string, and vice-versa.
It also includes all logic that determines what a 'valid' rom filename is.
That is, all extensions that represent valid schemes.
@author Stephen Anthony
*/
class Bankswitch
{
public:
// Currently supported bankswitch schemes
enum class Type {
_AUTO, _0840, _2IN1, _4IN1, _8IN1, _16IN1, _32IN1,
_64IN1, _128IN1, _2K, _3E, _3EP, _3F, _4A50,
_4K, _4KSC, _AR, _BF, _BFSC, _BUS, _CDF,
_CM, _CTY, _CV, _CVP, _DASH, _DF, _DFSC,
_DPC, _DPCP, _E0, _E7, _E78K, _EF, _EFSC,
_F0, _F4, _F4SC, _F6, _F6SC, _F8, _F8SC,
_FA, _FA2, _FE, _MDM, _SB, _UA, _WD,
_X07,
#ifdef CUSTOM_ARM
_CUSTOM,
#endif
NumSchemes
};
// Info about the various bankswitch schemes, useful for displaying
// in GUI dropdown boxes, etc
struct Description {
const char* const name;
const char* const desc;
};
static Description BSList[int(Type::NumSchemes)];
public:
// Convert BSType enum to string
static string typeToName(Bankswitch::Type type);
// Convert string to BSType enum
static Bankswitch::Type nameToType(const string& name);
// Determine bankswitch type by filename extension
// Use '_AUTO' if unknown
static Bankswitch::Type typeFromExtension(const FilesystemNode& file);
/**
Is this a valid ROM filename (does it have a valid extension?).
@param name File node of potential ROM file
@param ext The extension extracted from the given file
*/
static bool isValidRomName(const FilesystemNode& name, string& ext);
/**
Convenience function when extension isn't needed.
*/
static bool isValidRomName(const FilesystemNode& name);
private:
struct TypeComparator {
bool operator() (const string& a, const string& b) const {
return BSPF::compareIgnoreCase(a, b) < 0;
}
};
using ExtensionMap = std::map<string, Bankswitch::Type, TypeComparator>;
static ExtensionMap ourExtensions;
private:
// Following constructors and assignment operators not supported
Bankswitch() = delete;
Bankswitch(const Bankswitch&) = delete;
Bankswitch(Bankswitch&&) = delete;
Bankswitch& operator=(const Bankswitch&) = delete;
Bankswitch& operator=(Bankswitch&&) = delete;
};
#endif

View File

@ -66,23 +66,30 @@
#include "CartDetector.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
unique_ptr<Cartridge> CartDetector::create(const BytePtr& image, uInt32 size,
string& md5, const string& propertiesType, const OSystem& osystem)
unique_ptr<Cartridge> CartDetector::create(const FilesystemNode& file,
const BytePtr& image, uInt32 size, string& md5,
const string& propertiesType, const OSystem& osystem)
{
unique_ptr<Cartridge> cartridge;
BSType type = Bankswitch::nameToType(propertiesType),
Bankswitch::Type type = Bankswitch::nameToType(propertiesType),
detectedType = type;
string id;
// Collect some info about the ROM
ostringstream buf;
// First inspect the file extension itself
// If a valid type is found, it will override the one passed into this method
Bankswitch::Type typeByName = Bankswitch::typeFromExtension(file);
if(typeByName != Bankswitch::Type::_AUTO)
type = detectedType = typeByName;
// See if we should try to auto-detect the cartridge type
// If we ask for extended info, always do an autodetect
if(type == BSType::_AUTO || osystem.settings().getBool("rominfo"))
if(type == Bankswitch::Type::_AUTO || osystem.settings().getBool("rominfo"))
{
detectedType = autodetectType(image, size);
if(type != BSType::_AUTO && type != detectedType)
if(type != Bankswitch::Type::_AUTO && type != detectedType)
cerr << "Auto-detection not consistent: "
<< Bankswitch::typeToName(type) << ", "
<< Bankswitch::typeToName(detectedType) << endl;
@ -96,7 +103,7 @@ unique_ptr<Cartridge> CartDetector::create(const BytePtr& image, uInt32 size,
// Check for multicart first; if found, get the correct part of the image
switch(type)
{
case BSType::_2IN1:
case Bankswitch::Type::_2IN1:
// Make sure we have a valid sized image
if(size == 2*2048 || size == 2*4096 || size == 2*8192 || size == 2*16384)
{
@ -109,7 +116,7 @@ unique_ptr<Cartridge> CartDetector::create(const BytePtr& image, uInt32 size,
Bankswitch::typeToName(type) + "'");
break;
case BSType::_4IN1:
case Bankswitch::Type::_4IN1:
// Make sure we have a valid sized image
if(size == 4*2048 || size == 4*4096 || size == 4*8192)
{
@ -122,7 +129,7 @@ unique_ptr<Cartridge> CartDetector::create(const BytePtr& image, uInt32 size,
Bankswitch::typeToName(type) + "'");
break;
case BSType::_8IN1:
case Bankswitch::Type::_8IN1:
// Make sure we have a valid sized image
if(size == 8*2048 || size == 8*4096 || size == 8*8192)
{
@ -135,7 +142,7 @@ unique_ptr<Cartridge> CartDetector::create(const BytePtr& image, uInt32 size,
Bankswitch::typeToName(type) + "'");
break;
case BSType::_16IN1:
case Bankswitch::Type::_16IN1:
// Make sure we have a valid sized image
if(size == 16*2048 || size == 16*4096 || size == 16*8192)
{
@ -148,7 +155,7 @@ unique_ptr<Cartridge> CartDetector::create(const BytePtr& image, uInt32 size,
Bankswitch::typeToName(type) + "'");
break;
case BSType::_32IN1:
case Bankswitch::Type::_32IN1:
// Make sure we have a valid sized image
if(size == 32*2048 || size == 32*4096)
{
@ -161,7 +168,7 @@ unique_ptr<Cartridge> CartDetector::create(const BytePtr& image, uInt32 size,
Bankswitch::typeToName(type) + "'");
break;
case BSType::_64IN1:
case Bankswitch::Type::_64IN1:
// Make sure we have a valid sized image
if(size == 64*2048 || size == 64*4096)
{
@ -174,7 +181,7 @@ unique_ptr<Cartridge> CartDetector::create(const BytePtr& image, uInt32 size,
Bankswitch::typeToName(type) + "'");
break;
case BSType::_128IN1:
case Bankswitch::Type::_128IN1:
// Make sure we have a valid sized image
if(size == 128*2048 || size == 128*4096)
{
@ -205,7 +212,7 @@ unique_ptr<Cartridge> CartDetector::create(const BytePtr& image, uInt32 size,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
unique_ptr<Cartridge>
CartDetector::createFromMultiCart(const BytePtr& image, uInt32& size,
uInt32 numroms, string& md5, BSType type, string& id, const OSystem& osystem)
uInt32 numroms, string& md5, Bankswitch::Type type, string& id, const OSystem& osystem)
{
// Get a piece of the larger image
uInt32 i = osystem.settings().getInt("romloadcount");
@ -222,105 +229,105 @@ CartDetector::createFromMultiCart(const BytePtr& image, uInt32& size,
// Move to the next game the next time this ROM is loaded
osystem.settings().setValue("romloadcount", (i+1)%numroms);
if(size <= 2048) type = BSType::_2K;
else if(size == 4096) type = BSType::_4K;
else if(size == 8192) type = BSType::_F8;
else /* default */ type = BSType::_4K;
if(size <= 2048) type = Bankswitch::Type::_2K;
else if(size == 4096) type = Bankswitch::Type::_4K;
else if(size == 8192) type = Bankswitch::Type::_F8;
else /* default */ type = Bankswitch::Type::_4K;
return createFromImage(slice, size, type, md5, osystem);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
unique_ptr<Cartridge>
CartDetector::createFromImage(const BytePtr& image, uInt32 size, BSType type,
CartDetector::createFromImage(const BytePtr& image, uInt32 size, Bankswitch::Type type,
const string& md5, const OSystem& osystem)
{
// We should know the cart's type by now so let's create it
switch(type)
{
case BSType::_0840:
case Bankswitch::Type::_0840:
return make_unique<Cartridge0840>(image, size, osystem.settings());
case BSType::_2K:
case Bankswitch::Type::_2K:
return make_unique<Cartridge2K>(image, size, osystem.settings());
case BSType::_3E:
case Bankswitch::Type::_3E:
return make_unique<Cartridge3E>(image, size, osystem.settings());
case BSType::_3EP:
case Bankswitch::Type::_3EP:
return make_unique<Cartridge3EPlus>(image, size, osystem.settings());
case BSType::_3F:
case Bankswitch::Type::_3F:
return make_unique<Cartridge3F>(image, size, osystem.settings());
case BSType::_4A50:
case Bankswitch::Type::_4A50:
return make_unique<Cartridge4A50>(image, size, osystem.settings());
case BSType::_4K:
case Bankswitch::Type::_4K:
return make_unique<Cartridge4K>(image, size, osystem.settings());
case BSType::_4KSC:
case Bankswitch::Type::_4KSC:
return make_unique<Cartridge4KSC>(image, size, osystem.settings());
case BSType::_AR:
case Bankswitch::Type::_AR:
return make_unique<CartridgeAR>(image, size, osystem.settings());
case BSType::_BUS:
case Bankswitch::Type::_BUS:
return make_unique<CartridgeBUS>(image, size, osystem.settings());
case BSType::_CDF:
case Bankswitch::Type::_CDF:
return make_unique<CartridgeCDF>(image, size, osystem.settings());
case BSType::_CM:
case Bankswitch::Type::_CM:
return make_unique<CartridgeCM>(image, size, osystem.settings());
case BSType::_CTY:
case Bankswitch::Type::_CTY:
return make_unique<CartridgeCTY>(image, size, osystem);
case BSType::_CV:
case Bankswitch::Type::_CV:
return make_unique<CartridgeCV>(image, size, osystem.settings());
case BSType::_CVP:
case Bankswitch::Type::_CVP:
return make_unique<CartridgeCVPlus>(image, size, osystem.settings());
case BSType::_DASH:
case Bankswitch::Type::_DASH:
return make_unique<CartridgeDASH>(image, size, osystem.settings());
case BSType::_DPC:
case Bankswitch::Type::_DPC:
return make_unique<CartridgeDPC>(image, size, osystem.settings());
case BSType::_DPCP:
case Bankswitch::Type::_DPCP:
return make_unique<CartridgeDPCPlus>(image, size, osystem.settings());
case BSType::_E0:
case Bankswitch::Type::_E0:
return make_unique<CartridgeE0>(image, size, osystem.settings());
case BSType::_E7:
case Bankswitch::Type::_E7:
return make_unique<CartridgeE7>(image, size, osystem.settings());
case BSType::_E78K:
case Bankswitch::Type::_E78K:
return make_unique<CartridgeE78K>(image, size, osystem.settings());
case BSType::_EF:
case Bankswitch::Type::_EF:
return make_unique<CartridgeEF>(image, size, osystem.settings());
case BSType::_EFSC:
case Bankswitch::Type::_EFSC:
return make_unique<CartridgeEFSC>(image, size, osystem.settings());
case BSType::_BF:
case Bankswitch::Type::_BF:
return make_unique<CartridgeBF>(image, size, osystem.settings());
case BSType::_BFSC:
case Bankswitch::Type::_BFSC:
return make_unique<CartridgeBFSC>(image, size, osystem.settings());
case BSType::_DF:
case Bankswitch::Type::_DF:
return make_unique<CartridgeDF>(image, size, osystem.settings());
case BSType::_DFSC:
case Bankswitch::Type::_DFSC:
return make_unique<CartridgeDFSC>(image, size, osystem.settings());
case BSType::_F0:
case Bankswitch::Type::_F0:
return make_unique<CartridgeF0>(image, size, osystem.settings());
case BSType::_F4:
case Bankswitch::Type::_F4:
return make_unique<CartridgeF4>(image, size, osystem.settings());
case BSType::_F4SC:
case Bankswitch::Type::_F4SC:
return make_unique<CartridgeF4SC>(image, size, osystem.settings());
case BSType::_F6:
case Bankswitch::Type::_F6:
return make_unique<CartridgeF6>(image, size, osystem.settings());
case BSType::_F6SC:
case Bankswitch::Type::_F6SC:
return make_unique<CartridgeF6SC>(image, size, osystem.settings());
case BSType::_F8:
case Bankswitch::Type::_F8:
return make_unique<CartridgeF8>(image, size, md5, osystem.settings());
case BSType::_F8SC:
case Bankswitch::Type::_F8SC:
return make_unique<CartridgeF8SC>(image, size, osystem.settings());
case BSType::_FA:
case Bankswitch::Type::_FA:
return make_unique<CartridgeFA>(image, size, osystem.settings());
case BSType::_FA2:
case Bankswitch::Type::_FA2:
return make_unique<CartridgeFA2>(image, size, osystem);
case BSType::_FE:
case Bankswitch::Type::_FE:
return make_unique<CartridgeFE>(image, size, osystem.settings());
case BSType::_MDM:
case Bankswitch::Type::_MDM:
return make_unique<CartridgeMDM>(image, size, osystem.settings());
case BSType::_UA:
case Bankswitch::Type::_UA:
return make_unique<CartridgeUA>(image, size, osystem.settings());
case BSType::_SB:
case Bankswitch::Type::_SB:
return make_unique<CartridgeSB>(image, size, osystem.settings());
case BSType::_WD:
case Bankswitch::Type::_WD:
return make_unique<CartridgeWD>(image, size, osystem.settings());
case BSType::_X07:
case Bankswitch::Type::_X07:
return make_unique<CartridgeX07>(image, size, osystem.settings());
default:
return nullptr; // The remaining types have already been handled
@ -328,36 +335,36 @@ CartDetector::createFromImage(const BytePtr& image, uInt32 size, BSType type,
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BSType CartDetector::autodetectType(const BytePtr& image, uInt32 size)
Bankswitch::Type CartDetector::autodetectType(const BytePtr& image, uInt32 size)
{
// Guess type based on size
BSType type = BSType::_AUTO;
Bankswitch::Type type = Bankswitch::Type::_AUTO;
if(isProbablyCVPlus(image,size))
{
type = BSType::_CVP;
type = Bankswitch::Type::_CVP;
}
else if((size % 8448) == 0 || size == 6144)
{
type = BSType::_AR;
type = Bankswitch::Type::_AR;
}
else if(size < 2048) // Sub2K images
{
type = BSType::_2K;
type = Bankswitch::Type::_2K;
}
else if((size == 2048) ||
(size == 4096 && memcmp(image.get(), image.get() + 2048, 2048) == 0))
{
type = isProbablyCV(image, size) ? BSType::_CV : BSType::_2K;
type = isProbablyCV(image, size) ? Bankswitch::Type::_CV : Bankswitch::Type::_2K;
}
else if(size == 4096)
{
if(isProbablyCV(image, size))
type = BSType::_CV;
type = Bankswitch::Type::_CV;
else if(isProbably4KSC(image, size))
type = BSType::_4KSC;
type = Bankswitch::Type::_4KSC;
else
type = BSType::_4K;
type = Bankswitch::Type::_4K;
}
else if(size == 8*1024) // 8K
{
@ -366,141 +373,141 @@ BSType CartDetector::autodetectType(const BytePtr& image, uInt32 size)
bool f8 = searchForBytes(image.get(), size, signature, 3, 2);
if(isProbablySC(image, size))
type = BSType::_F8SC;
type = Bankswitch::Type::_F8SC;
else if(memcmp(image.get(), image.get() + 4096, 4096) == 0)
type = BSType::_4K;
type = Bankswitch::Type::_4K;
else if(isProbablyE0(image, size))
type = BSType::_E0;
type = Bankswitch::Type::_E0;
else if(isProbably3E(image, size))
type = BSType::_3E;
type = Bankswitch::Type::_3E;
else if(isProbably3F(image, size))
type = BSType::_3F;
type = Bankswitch::Type::_3F;
else if(isProbablyUA(image, size))
type = BSType::_UA;
type = Bankswitch::Type::_UA;
else if(isProbablyFE(image, size) && !f8)
type = BSType::_FE;
type = Bankswitch::Type::_FE;
else if(isProbably0840(image, size))
type = BSType::_0840;
type = Bankswitch::Type::_0840;
else if(isProbablyE78K(image, size))
type = BSType::_E78K;
type = Bankswitch::Type::_E78K;
else
type = BSType::_F8;
type = Bankswitch::Type::_F8;
}
else if(size == 8*1024 + 3) // 8195 bytes (Experimental)
{
type = BSType::_WD;
type = Bankswitch::Type::_WD;
}
else if(size >= 10240 && size <= 10496) // ~10K - Pitfall2
{
type = BSType::_DPC;
type = Bankswitch::Type::_DPC;
}
else if(size == 12*1024) // 12K
{
type = BSType::_FA;
type = Bankswitch::Type::_FA;
}
else if(size == 16*1024) // 16K
{
if(isProbablySC(image, size))
type = BSType::_F6SC;
type = Bankswitch::Type::_F6SC;
else if(isProbablyE7(image, size))
type = BSType::_E7;
type = Bankswitch::Type::_E7;
else if(isProbably3E(image, size))
type = BSType::_3E;
type = Bankswitch::Type::_3E;
/* no known 16K 3F ROMS
else if(isProbably3F(image, size))
type = BSType::_3F;
type = Bankswitch::Type::_3F;
*/
else
type = BSType::_F6;
type = Bankswitch::Type::_F6;
}
else if(size == 24*1024 || size == 28*1024) // 24K & 28K
{
type = BSType::_FA2;
type = Bankswitch::Type::_FA2;
}
else if(size == 29*1024) // 29K
{
if(isProbablyARM(image, size))
type = BSType::_FA2;
type = Bankswitch::Type::_FA2;
else /*if(isProbablyDPCplus(image, size))*/
type = BSType::_DPCP;
type = Bankswitch::Type::_DPCP;
}
else if(size == 32*1024) // 32K
{
if(isProbablySC(image, size))
type = BSType::_F4SC;
type = Bankswitch::Type::_F4SC;
else if(isProbably3E(image, size))
type = BSType::_3E;
type = Bankswitch::Type::_3E;
else if(isProbably3F(image, size))
type = BSType::_3F;
type = Bankswitch::Type::_3F;
else if (isProbablyBUS(image, size))
type = BSType::_BUS;
type = Bankswitch::Type::_BUS;
else if (isProbablyCDF(image, size))
type = BSType::_CDF;
type = Bankswitch::Type::_CDF;
else if(isProbablyDPCplus(image, size))
type = BSType::_DPCP;
type = Bankswitch::Type::_DPCP;
else if(isProbablyCTY(image, size))
type = BSType::_CTY;
type = Bankswitch::Type::_CTY;
else if(isProbablyFA2(image, size))
type = BSType::_FA2;
type = Bankswitch::Type::_FA2;
else
type = BSType::_F4;
type = Bankswitch::Type::_F4;
}
else if(size == 64*1024) // 64K
{
if(isProbably3E(image, size))
type = BSType::_3E;
type = Bankswitch::Type::_3E;
else if(isProbably3F(image, size))
type = BSType::_3F;
type = Bankswitch::Type::_3F;
else if(isProbably4A50(image, size))
type = BSType::_4A50;
type = Bankswitch::Type::_4A50;
else if(isProbablyEF(image, size, type))
; // type has been set directly in the function
else if(isProbablyX07(image, size))
type = BSType::_X07;
type = Bankswitch::Type::_X07;
else
type = BSType::_F0;
type = Bankswitch::Type::_F0;
}
else if(size == 128*1024) // 128K
{
if(isProbably3E(image, size))
type = BSType::_3E;
type = Bankswitch::Type::_3E;
else if(isProbablyDF(image, size, type))
; // type has been set directly in the function
else if(isProbably3F(image, size))
type = BSType::_3F;
type = Bankswitch::Type::_3F;
else if(isProbably4A50(image, size))
type = BSType::_4A50;
type = Bankswitch::Type::_4A50;
else if(isProbablySB(image, size))
type = BSType::_SB;
type = Bankswitch::Type::_SB;
}
else if(size == 256*1024) // 256K
{
if(isProbably3E(image, size))
type = BSType::_3E;
type = Bankswitch::Type::_3E;
else if(isProbablyBF(image, size, type))
; // type has been set directly in the function
else if(isProbably3F(image, size))
type = BSType::_3F;
type = Bankswitch::Type::_3F;
else /*if(isProbablySB(image, size))*/
type = BSType::_SB;
type = Bankswitch::Type::_SB;
}
else // what else can we do?
{
if(isProbably3E(image, size))
type = BSType::_3E;
type = Bankswitch::Type::_3E;
else if(isProbably3F(image, size))
type = BSType::_3F;
type = Bankswitch::Type::_3F;
else
type = BSType::_4K; // Most common bankswitching type
type = Bankswitch::Type::_4K; // Most common bankswitching type
}
// Variable sized ROM formats are independent of image size and come last
if(isProbablyDASH(image, size))
type = BSType::_DASH;
type = Bankswitch::Type::_DASH;
else if(isProbably3EPlus(image, size))
type = BSType::_3EP;
type = Bankswitch::Type::_3EP;
else if(isProbablyMDM(image, size))
type = BSType::_MDM;
type = Bankswitch::Type::_MDM;
return type;
}
@ -774,7 +781,7 @@ bool CartDetector::isProbablyE78K(const BytePtr& image, uInt32 size)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDetector::isProbablyEF(const BytePtr& image, uInt32 size, BSType& type)
bool CartDetector::isProbablyEF(const BytePtr& image, uInt32 size, Bankswitch::Type& type)
{
// Newer EF carts store strings 'EFEF' and 'EFSC' starting at address $FFF8
// This signature is attributed to "RevEng" of AtariAge
@ -782,12 +789,12 @@ bool CartDetector::isProbablyEF(const BytePtr& image, uInt32 size, BSType& type)
uInt8 efsc[] = { 'E', 'F', 'S', 'C' };
if(searchForBytes(image.get()+size-8, 8, efef, 4, 1))
{
type = BSType::_EF;
type = Bankswitch::Type::_EF;
return true;
}
else if(searchForBytes(image.get()+size-8, 8, efsc, 4, 1))
{
type = BSType::_EFSC;
type = Bankswitch::Type::_EFSC;
return true;
}
@ -814,7 +821,7 @@ bool CartDetector::isProbablyEF(const BytePtr& image, uInt32 size, BSType& type)
// the SC variant
if(isEF)
{
type = isProbablySC(image, size) ? BSType::_EFSC : BSType::_EF;
type = isProbablySC(image, size) ? Bankswitch::Type::_EFSC : Bankswitch::Type::_EF;
return true;
}
@ -822,7 +829,7 @@ bool CartDetector::isProbablyEF(const BytePtr& image, uInt32 size, BSType& type)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDetector::isProbablyBF(const BytePtr& image, uInt32 size, BSType& type)
bool CartDetector::isProbablyBF(const BytePtr& image, uInt32 size, Bankswitch::Type& type)
{
// BF carts store strings 'BFBF' and 'BFSC' starting at address $FFF8
// This signature is attributed to "RevEng" of AtariAge
@ -830,12 +837,12 @@ bool CartDetector::isProbablyBF(const BytePtr& image, uInt32 size, BSType& type)
uInt8 bfsc[] = { 'B', 'F', 'S', 'C' };
if(searchForBytes(image.get()+size-8, 8, bf, 4, 1))
{
type = BSType::_BF;
type = Bankswitch::Type::_BF;
return true;
}
else if(searchForBytes(image.get()+size-8, 8, bfsc, 4, 1))
{
type = BSType::_BFSC;
type = Bankswitch::Type::_BFSC;
return true;
}
@ -863,7 +870,7 @@ bool CartDetector::isProbablyCDF(const BytePtr& image, uInt32 size)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDetector::isProbablyDF(const BytePtr& image, uInt32 size, BSType& type)
bool CartDetector::isProbablyDF(const BytePtr& image, uInt32 size, Bankswitch::Type& type)
{
// BF carts store strings 'DFDF' and 'DFSC' starting at address $FFF8
@ -872,12 +879,12 @@ bool CartDetector::isProbablyDF(const BytePtr& image, uInt32 size, BSType& type)
uInt8 dfsc[] = { 'D', 'F', 'S', 'C' };
if(searchForBytes(image.get()+size-8, 8, df, 4, 1))
{
type = BSType::_DF;
type = Bankswitch::Type::_DF;
return true;
}
else if(searchForBytes(image.get()+size-8, 8, dfsc, 4, 1))
{
type = BSType::_DFSC;
type = Bankswitch::Type::_DFSC;
return true;
}

View File

@ -22,8 +22,8 @@ class Cartridge;
class Properties;
class OSystem;
#include "Bankswitch.hxx"
#include "bspf.hxx"
#include "BSType.hxx"
/**
Auto-detect cart type based on various attributes (file size, signatures,
@ -45,8 +45,9 @@ class CartDetector
@param system The osystem associated with the system
@return Pointer to the new cartridge object allocated on the heap
*/
static unique_ptr<Cartridge> create(const BytePtr& image, uInt32 size,
string& md5, const string& dtype, const OSystem& system);
static unique_ptr<Cartridge> create(const FilesystemNode& file,
const BytePtr& image, uInt32 size, string& md5,
const string& dtype, const OSystem& system);
private:
/**
@ -65,7 +66,7 @@ class CartDetector
*/
static unique_ptr<Cartridge>
createFromMultiCart(const BytePtr& image, uInt32& size,
uInt32 numroms, string& md5, BSType type, string& id,
uInt32 numroms, string& md5, Bankswitch::Type type, string& id,
const OSystem& osystem);
/**
@ -80,7 +81,7 @@ class CartDetector
@return Pointer to the new cartridge object allocated on the heap
*/
static unique_ptr<Cartridge>
createFromImage(const BytePtr& image, uInt32 size, BSType type,
createFromImage(const BytePtr& image, uInt32 size, Bankswitch::Type type,
const string& md5, const OSystem& osystem);
/**
@ -91,7 +92,7 @@ class CartDetector
@return The "best guess" for the cartridge type
*/
static BSType autodetectType(const BytePtr& image, uInt32 size);
static Bankswitch::Type autodetectType(const BytePtr& image, uInt32 size);
/**
Search the image for the specified byte signature
@ -152,7 +153,7 @@ class CartDetector
/**
Returns true if the image is probably a BF/BFSC bankswitching cartridge
*/
static bool isProbablyBF(const BytePtr& image, uInt32 size, BSType& type);
static bool isProbablyBF(const BytePtr& image, uInt32 size, Bankswitch::Type& type);
/**
Returns true if the image is probably a BUS bankswitching cartridge
@ -187,7 +188,7 @@ class CartDetector
/**
Returns true if the image is probably a DF/DFSC bankswitching cartridge
*/
static bool isProbablyDF(const BytePtr& image, uInt32 size, BSType& type);
static bool isProbablyDF(const BytePtr& image, uInt32 size, Bankswitch::Type& type);
/**
Returns true if the image is probably a DPC+ bankswitching cartridge
@ -212,7 +213,7 @@ class CartDetector
/**
Returns true if the image is probably an EF/EFSC bankswitching cartridge
*/
static bool isProbablyEF(const BytePtr& image, uInt32 size, BSType& type);
static bool isProbablyEF(const BytePtr& image, uInt32 size, Bankswitch::Type& type);
/**
Returns true if the image is probably an F6 bankswitching cartridge

View File

@ -472,7 +472,7 @@ unique_ptr<Console> OSystem::openConsole(const FilesystemNode& romfile, string&
string cartmd5 = md5;
const string& type = props.get(Cartridge_Type);
unique_ptr<Cartridge> cart =
CartDetector::create(image, size, cartmd5, type, *this);
CartDetector::create(romfile, image, size, cartmd5, type, *this);
// It's possible that the cart created was from a piece of the image,
// and that the md5 (and hence the cart) has changed

View File

@ -2,6 +2,7 @@ MODULE := src/emucore
MODULE_OBJS := \
src/emucore/AtariVox.o \
src/emucore/Bankswitch.o \
src/emucore/Booster.o \
src/emucore/Cart.o \
src/emucore/CartDetector.o \

View File

@ -15,7 +15,7 @@
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include "BSType.hxx"
#include "Bankswitch.hxx"
#include "Console.hxx"
#include "MouseControl.hxx"
#include "SaveKey.hxx"
@ -116,8 +116,8 @@ GameInfoDialog::GameInfoDialog(
new StaticTextWidget(myTab, font, xpos, ypos+1, lwidth, fontHeight, "Type (*)");
pwidth = font.getStringWidth("CM (SpectraVideo CompuMate)");
items.clear();
for(int i = 0; i < int(BSType::NumSchemes); ++i)
VarList::push_back(items, BSList[i].desc, BSList[i].name);
for(uInt32 i = 0; i < uInt32(Bankswitch::Type::NumSchemes); ++i)
VarList::push_back(items, Bankswitch::BSList[i].desc, Bankswitch::BSList[i].name);
myType = new PopUpWidget(myTab, font, xpos+lwidth, ypos,
pwidth, lineHeight, items, "");
wid.push_back(myType);

View File

@ -16,7 +16,7 @@
//============================================================================
#include "bspf.hxx"
#include "BSType.hxx"
#include "Bankswitch.hxx"
#include "Control.hxx"
#include "Dialog.hxx"
#include "OSystem.hxx"
@ -53,8 +53,8 @@ GlobalPropsDialog::GlobalPropsDialog(GuiObject* boss, const GUI::Font& font)
// Bankswitch type
new StaticTextWidget(this, font, xpos, ypos+1, "Bankswitch type");
for(int i = 0; i < int(BSType::NumSchemes); ++i)
VarList::push_back(items, BSList[i].desc, BSList[i].name);
for(uInt32 i = 0; i < uInt32(Bankswitch::Type::NumSchemes); ++i)
VarList::push_back(items, Bankswitch::BSList[i].desc, Bankswitch::BSList[i].name);
myBSType = new PopUpWidget(this, font, xpos+lwidth, ypos,
pwidth, lineHeight, items, "");
wid.push_back(myBSType);

View File

@ -16,6 +16,7 @@
//============================================================================
#include "bspf.hxx"
#include "Bankswitch.hxx"
#include "BrowserDialog.hxx"
#include "ContextMenu.hxx"
#include "DialogContainer.hxx"
@ -200,9 +201,8 @@ const string& LauncherDialog::selectedRomMD5()
if(item < 0)
return EmptyString;
string extension;
const FilesystemNode node(myGameList->path(item));
if(node.isDirectory() || !LauncherFilterDialog::isValidRomName(node, extension))
if(node.isDirectory() || !Bankswitch::isValidRomName(node))
return EmptyString;
// Make sure we have a valid md5 for this ROM
@ -321,9 +321,8 @@ void LauncherDialog::loadRomInfo()
int item = myList->getSelected();
if(item < 0) return;
string extension;
const FilesystemNode node(myGameList->path(item));
if(!node.isDirectory() && LauncherFilterDialog::isValidRomName(node, extension))
if(!node.isDirectory() && Bankswitch::isValidRomName(node))
{
// Make sure we have a valid md5 for this ROM
if(myGameList->md5(item) == "")

View File

@ -123,27 +123,6 @@ bool LauncherFilterDialog::isValidRomName(const string& name,
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool LauncherFilterDialog::isValidRomName(const FilesystemNode& node, string& ext)
{
const string& name = node.getPath();
string::size_type idx = name.find_last_of('.');
if(idx != string::npos)
{
const char* const e = name.c_str() + idx + 1;
for(uInt32 i = 0; i < 5; ++i)
{
if(BSPF::equalsIgnoreCase(e, ourRomTypes[1][i]))
{
ext = e;
return true;
}
}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherFilterDialog::loadConfig()
{

View File

@ -47,14 +47,6 @@ class LauncherFilterDialog : public Dialog, public CommandSender
*/
static bool isValidRomName(const string& name, const StringList& exts);
/**
Is this a valid ROM filename (does it have a valid extension?).
@param name File node of potential ROM file
@param ext The extension extracted from the given file
*/
static bool isValidRomName(const FilesystemNode& name, string& ext);
private:
void loadConfig() override;
void saveConfig() override;

View File

@ -17,7 +17,7 @@
#include "bspf.hxx"
#include "Launcher.hxx"
#include "LauncherFilterDialog.hxx"
#include "Bankswitch.hxx"
#include "BrowserDialog.hxx"
#include "DialogContainer.hxx"
#include "EditTextWidget.hxx"
@ -136,7 +136,7 @@ void RomAuditDialog::auditRoms()
{
string extension;
if(files[idx].isFile() &&
LauncherFilterDialog::isValidRomName(files[idx], extension))
Bankswitch::isValidRomName(files[idx], extension))
{
bool renameSucceeded = false;