mirror of
https://github.com/spicyjpeg/573in1.git
synced 2025-01-22 19:52:05 +01:00
Update cartdb, fix system IDs, change sorting criteria
This commit is contained in:
parent
ada89001a5
commit
123c6fa14d
743
data/games.json
743
data/games.json
File diff suppressed because it is too large
Load Diff
Binary file not shown.
BIN
data/zs01.cartdb
BIN
data/zs01.cartdb
Binary file not shown.
@ -295,6 +295,29 @@ bool isValidRegion(const char *region) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isValidUpgradeRegion(const char *region) {
|
||||
if (!region[0] || !__builtin_strchr("aejksu", region[0]))
|
||||
return false;
|
||||
if (!region[1] || !__builtin_strchr("abcdefrstuvwxyz", region[1]))
|
||||
return false;
|
||||
|
||||
if (region[2]) {
|
||||
if (!__builtin_strchr("abcdz", region[2]))
|
||||
return false;
|
||||
|
||||
if (region[2] == 'z') {
|
||||
if (!__builtin_isdigit(region[3]) || !__builtin_isdigit(region[4]))
|
||||
return false;
|
||||
|
||||
region += 2;
|
||||
}
|
||||
if (region[3])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Parser *newCartParser(Dump &dump, FormatType formatType, uint8_t flags) {
|
||||
switch (formatType) {
|
||||
case SIMPLE:
|
||||
|
@ -11,9 +11,10 @@ namespace cart {
|
||||
|
||||
/* Cartridge data parsers */
|
||||
|
||||
static constexpr size_t CODE_LENGTH = 5;
|
||||
static constexpr size_t REGION_MIN_LENGTH = 2;
|
||||
static constexpr size_t REGION_MAX_LENGTH = 5;
|
||||
static constexpr size_t CODE_LENGTH = 5;
|
||||
static constexpr size_t CODE_PREFIX_LENGTH = 2;
|
||||
static constexpr size_t REGION_MIN_LENGTH = 2;
|
||||
static constexpr size_t REGION_MAX_LENGTH = 5;
|
||||
|
||||
class Parser {
|
||||
protected:
|
||||
@ -100,6 +101,7 @@ public:
|
||||
};
|
||||
|
||||
bool isValidRegion(const char *region);
|
||||
bool isValidUpgradeRegion(const char *region);
|
||||
Parser *newCartParser(Dump &dump, FormatType formatType, uint8_t flags = 0);
|
||||
Parser *newCartParser(Dump &dump);
|
||||
|
||||
@ -118,7 +120,14 @@ public:
|
||||
char code[8], region[8], name[96];
|
||||
|
||||
inline int compare(const char *_code, const char *_region) const {
|
||||
int diff = __builtin_strncmp(code, _code, CODE_LENGTH + 1);
|
||||
int diff = __builtin_strncmp(
|
||||
&code[CODE_PREFIX_LENGTH], &_code[CODE_PREFIX_LENGTH],
|
||||
CODE_LENGTH - CODE_PREFIX_LENGTH + 1
|
||||
);
|
||||
if (diff)
|
||||
return diff;
|
||||
|
||||
diff = __builtin_strncmp(code, _code, CODE_PREFIX_LENGTH);
|
||||
if (diff)
|
||||
return diff;
|
||||
|
||||
@ -130,7 +139,7 @@ public:
|
||||
inline bool requiresCartID(void) const {
|
||||
if (flags & DATA_HAS_CART_ID)
|
||||
return true;
|
||||
if ((flags & DATA_HAS_TRACE_ID) && (traceIDType != TID_81))
|
||||
if ((flags & DATA_HAS_TRACE_ID) && (traceIDType >= TID_82_BIG_ENDIAN))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -383,10 +383,11 @@ class DBEntry:
|
||||
else:
|
||||
self.installIDPrefix = 0
|
||||
|
||||
# Implement the comparison overload so sorting will work.
|
||||
# Implement the comparison overload so sorting will work. The 3-digit number
|
||||
# in the game code is used as a key.
|
||||
def __lt__(self, entry: Any) -> bool:
|
||||
return ( self.code, self.region, self.name ) < \
|
||||
( entry.code, entry.region, entry.name )
|
||||
return ( self.code[2:], self.code[0:2], self.region, self.name ) < \
|
||||
( entry.code[2:], entry.code[0:2], entry.region, entry.name )
|
||||
|
||||
def requiresCartID(self) -> bool:
|
||||
if self.flags & DataFlag.DATA_HAS_CART_ID:
|
||||
|
@ -21,16 +21,18 @@ class GameEntry:
|
||||
code: str
|
||||
region: str
|
||||
name: str
|
||||
mameID: str
|
||||
|
||||
installCart: str | None = None
|
||||
gameCart: str | None = None
|
||||
ioBoard: str | None = None
|
||||
mameID: str | None = None
|
||||
installCart: str | None = None
|
||||
gameCart: str | None = None
|
||||
ioBoard: str | None = None
|
||||
lockedToIOBoard: bool = False
|
||||
|
||||
# Implement the comparison overload so sorting will work.
|
||||
# Implement the comparison overload so sorting will work. The 3-digit number
|
||||
# in the game code is used as a key.
|
||||
def __lt__(self, entry: Any) -> bool:
|
||||
return ( self.code, self.region, self.name ) < \
|
||||
( entry.code, entry.region, entry.name )
|
||||
return ( self.code[2:], self.code[0:2], self.region, self.name ) < \
|
||||
( entry.code[2:], entry.code[0:2], entry.region, entry.name )
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{self.code} {self.region}"
|
||||
@ -56,11 +58,12 @@ class GameDB:
|
||||
code: str = entryObj["code"].strip().upper()
|
||||
region: str = entryObj["region"].strip().upper()
|
||||
name: str = entryObj["name"]
|
||||
mameID: str = entryObj["id"]
|
||||
|
||||
installCart: str | None = entryObj.get("installCart", None)
|
||||
gameCart: str | None = entryObj.get("gameCart", None)
|
||||
ioBoard: str | None = entryObj.get("ioBoard", None)
|
||||
mameID: str | None = entryObj.get("id", None)
|
||||
installCart: str | None = entryObj.get("installCart", None)
|
||||
gameCart: str | None = entryObj.get("gameCart", None)
|
||||
ioBoard: str | None = entryObj.get("ioBoard", None)
|
||||
lockedToIOBoard: bool = entryObj.get("lockedToIOBoard", False)
|
||||
|
||||
if GAME_CODE_REGEX.fullmatch(code.encode("ascii")) is None:
|
||||
raise ValueError(f"invalid game code: {code}")
|
||||
@ -68,7 +71,8 @@ class GameDB:
|
||||
raise ValueError(f"invalid game region: {region}")
|
||||
|
||||
entry: GameEntry = GameEntry(
|
||||
code, region, name, mameID, installCart, gameCart, ioBoard
|
||||
code, region, name, mameID, installCart, gameCart, ioBoard,
|
||||
lockedToIOBoard
|
||||
)
|
||||
|
||||
# Store all entries indexed by their game code and first two characters
|
||||
@ -239,8 +243,10 @@ def processDump(
|
||||
matches: list[GameEntry] = sorted(db.lookup(parser.code, parser.region))
|
||||
|
||||
if exportFile:
|
||||
matchList: str = " ".join(game.mameID for game in matches)
|
||||
_, flags = str(parser.flags).split(".", 1)
|
||||
matchList: str = " ".join(
|
||||
(game.mameID or f"[{game}]") for game in matches
|
||||
)
|
||||
|
||||
exportFile.write(
|
||||
f"{dump.chipType.name},{nameHint},{parser.code},{parser.region},"
|
||||
@ -254,15 +260,17 @@ def processDump(
|
||||
|
||||
if game.hasCartID():
|
||||
if not (parser.flags & DataFlag.DATA_HAS_CART_ID):
|
||||
raise RuntimeError("dump has a cartridge ID but game does not")
|
||||
raise RuntimeError("game has a cartridge ID but dump does not")
|
||||
else:
|
||||
if parser.flags & DataFlag.DATA_HAS_CART_ID:
|
||||
raise RuntimeError("game has a cartridge ID but dump does not")
|
||||
raise RuntimeError("dump has a cartridge ID but game does not")
|
||||
|
||||
if game.hasSystemID():
|
||||
parser.flags |= DataFlag.DATA_HAS_SYSTEM_ID
|
||||
if game.hasSystemID() and game.lockedToIOBoard:
|
||||
if not (parser.flags & DataFlag.DATA_HAS_SYSTEM_ID):
|
||||
raise RuntimeError("game has a system ID but dump does not")
|
||||
else:
|
||||
parser.flags &= ~DataFlag.DATA_HAS_SYSTEM_ID
|
||||
if parser.flags & DataFlag.DATA_HAS_SYSTEM_ID:
|
||||
raise RuntimeError("dump has a system ID but game does not")
|
||||
|
||||
logging.info(f"imported {dump.chipType.name}: {game.getFullName()}")
|
||||
return DBEntry(parser.code, parser.region, game.name, dump, parser)
|
||||
|
Loading…
x
Reference in New Issue
Block a user