Add cartdb files, implement GX706 checksum workaround

This commit is contained in:
spicyjpeg 2023-06-15 09:13:55 +02:00
parent 95546643b9
commit 6b33d4edd1
No known key found for this signature in database
GPG Key ID: 5CC87404C01DF393
10 changed files with 58 additions and 24 deletions

0
CMakePresets.json Executable file → Normal file
View File

0
cmake/setup.cmake Executable file → Normal file
View File

BIN
data/x76f041.cartdb Normal file

Binary file not shown.

BIN
data/zs01.cartdb Normal file

Binary file not shown.

View File

@ -46,6 +46,7 @@ enum DumpFlag : uint8_t {
// | DATA_HAS_CODE_PREFIX | | Optional | Mandatory |
// | DATA_HAS_*_ID | | Optional | Optional |
// | DATA_HAS_PUBLIC_SECTION | Mandatory | | Optional |
// | DATA_GX706_WORKAROUND | | | Optional |
enum DataFlag : uint8_t {
DATA_HAS_CODE_PREFIX = 1 << 0,
@ -54,7 +55,8 @@ enum DataFlag : uint8_t {
DATA_HAS_INSTALL_ID = 1 << 3,
DATA_HAS_SYSTEM_ID = 1 << 4,
DATA_HAS_PUBLIC_SECTION = 1 << 5,
DATA_CHECKSUM_INVERTED = 1 << 6
DATA_CHECKSUM_INVERTED = 1 << 6,
DATA_GX706_WORKAROUND = 1 << 7
};
static constexpr int NUM_CHIP_TYPES = 4;

View File

@ -66,10 +66,10 @@ IdentifierSet *BasicParser::getIdentifiers(void) {
}
bool BasicParser::validate(void) {
return (
Parser::validate()
&& _getHeader()->validateChecksum(flags & DATA_CHECKSUM_INVERTED)
);
if (!Parser::validate())
return false;
return _getHeader()->validateChecksum(flags & DATA_CHECKSUM_INVERTED);
}
size_t ExtendedParser::getCode(char *output) const {
@ -78,6 +78,9 @@ size_t ExtendedParser::getCode(char *output) const {
__builtin_memcpy(output, header->code, sizeof(header->code));
output[sizeof(header->code)] = 0;
if (flags & DATA_GX706_WORKAROUND)
output[1] = 'X';
return __builtin_strlen(output);
}
@ -113,10 +116,21 @@ void ExtendedParser::flush(void) {
}
bool ExtendedParser::validate(void) {
return (
Parser::validate()
&& _getHeader()->validateChecksum(flags & DATA_CHECKSUM_INVERTED)
);
if (!Parser::validate())
return false;
auto header = _getHeader();
char region = header->region[1];
if (flags & DATA_GX706_WORKAROUND)
header->region[1] = 'X';
bool valid = header->validateChecksum(flags & DATA_CHECKSUM_INVERTED);
if (flags & DATA_GX706_WORKAROUND)
header->region[1] = region;
return valid;
}
/* Data format identification */
@ -128,7 +142,7 @@ public:
uint8_t flags;
};
static constexpr int _NUM_KNOWN_FORMATS = 9;
static constexpr int _NUM_KNOWN_FORMATS = 12;
static const KnownFormat _KNOWN_FORMATS[_NUM_KNOWN_FORMATS]{
{
@ -144,6 +158,10 @@ static const KnownFormat _KNOWN_FORMATS[_NUM_KNOWN_FORMATS]{
.name = "basic + TID",
.format = BASIC,
.flags = DATA_HAS_TRACE_ID | DATA_CHECKSUM_INVERTED
}, {
.name = "basic + SID",
.format = BASIC,
.flags = DATA_HAS_CART_ID | DATA_CHECKSUM_INVERTED
}, {
.name = "basic + TID, SID",
.format = BASIC,
@ -160,15 +178,18 @@ static const KnownFormat _KNOWN_FORMATS[_NUM_KNOWN_FORMATS]{
.flags = DATA_HAS_CODE_PREFIX | DATA_HAS_TRACE_ID | DATA_HAS_CART_ID
| DATA_HAS_INSTALL_ID | DATA_HAS_SYSTEM_ID | DATA_CHECKSUM_INVERTED
}, {
// Used by early (pre-digital-I/O) Bemani games
.name = "extended (no IDs)",
.format = EXTENDED,
.flags = DATA_HAS_CODE_PREFIX | DATA_CHECKSUM_INVERTED
}, {
// Used by early (pre-digital-I/O) Bemani games
.name = "extended alt. (no IDs)",
.name = "extended (no IDs, alt)",
.format = EXTENDED,
.flags = DATA_HAS_CODE_PREFIX
}, {
// Used by GX706
.name = "extended (no IDs, GX706)",
.format = EXTENDED,
.flags = DATA_HAS_CODE_PREFIX | DATA_GX706_WORKAROUND
}, {
// Used by GE936/GK936 and all ZS01 Bemani games
.name = "extended + all IDs",

View File

@ -101,7 +101,7 @@ public:
uint8_t traceIDParam, installIDPrefix;
uint16_t year;
uint8_t dataKey[8];
char code[8], region[8], name[64];
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);

View File

@ -15,14 +15,14 @@
extern "C" const uint8_t _resources[];
extern "C" const size_t _resourcesSize;
static const char _DEFAULT_RESOURCE_ZIP_PATH[] = "/cartToolResources.zip";
static const char _DEFAULT_RESOURCE_ZIP_PATH[] = "cartToolResources.zip";
static const char *const _UI_SOUND_PATHS[ui::NUM_UI_SOUNDS]{
"assets/sound/startup.vag", // ui::SOUND_STARTUP
"assets/sounds/move.vag", // ui::SOUND_MOVE
"assets/sounds/enter.vag", // ui::SOUND_ENTER
"assets/sounds/exit.vag", // ui::SOUND_EXIT
"assets/sounds/click.vag" // ui::SOUND_CLICK
"assets/sounds/startup.vag", // ui::SOUND_STARTUP
"assets/sounds/move.vag", // ui::SOUND_MOVE
"assets/sounds/enter.vag", // ui::SOUND_ENTER
"assets/sounds/exit.vag", // ui::SOUND_EXIT
"assets/sounds/click.vag" // ui::SOUND_CLICK
};
int main(int argc, const char **argv) {

View File

@ -47,6 +47,7 @@ class DataFlag(IntFlag):
DATA_HAS_SYSTEM_ID = 1 << 4
DATA_HAS_PUBLIC_SECTION = 1 << 5
DATA_CHECKSUM_INVERTED = 1 << 6
DATA_GX706_WORKAROUND = 1 << 7
# Character 0: always G
# Character 1: region related? (can be B, C, E, K, L, N, Q, U, X)
@ -242,6 +243,9 @@ class ExtendedParser(Parser):
data: bytes = _getPublicData(dump, flags, _EXTENDED_HEADER_STRUCT.size)
ids: IdentifierSet = IdentifierSet(dump.data[_EXTENDED_HEADER_STRUCT.size + 16:])
if flags & DataFlag.DATA_GX706_WORKAROUND:
data = data[0:1] + b"X" + data[2:]
code, year, region, checksum = _EXTENDED_HEADER_STRUCT.unpack(data)
code: bytes = code.rstrip(b"\0")
@ -267,7 +271,7 @@ class ExtendedParser(Parser):
## Cartridge database
DB_ENTRY_STRUCT: Struct = Struct("< 6B H 8s 8s 8s 64s")
DB_ENTRY_STRUCT: Struct = Struct("< 6B H 8s 8s 8s 96s")
@dataclass
class GameEntry:

View File

@ -129,6 +129,10 @@ _KNOWN_FORMATS: Sequence[tuple[str, Type, DataFlag]] = (
"basic + TID",
BasicParser,
DataFlag.DATA_HAS_TRACE_ID | DataFlag.DATA_CHECKSUM_INVERTED
), (
"basic + SID",
BasicParser,
DataFlag.DATA_HAS_CART_ID | DataFlag.DATA_CHECKSUM_INVERTED
), (
"basic + TID, SID",
BasicParser,
@ -147,15 +151,18 @@ _KNOWN_FORMATS: Sequence[tuple[str, Type, DataFlag]] = (
| DataFlag.DATA_HAS_CART_ID | DataFlag.DATA_HAS_INSTALL_ID
| DataFlag.DATA_HAS_SYSTEM_ID | DataFlag.DATA_CHECKSUM_INVERTED
), (
# Used by early (pre-digital-I/O) Bemani games
"extended (no IDs)",
ExtendedParser,
DataFlag.DATA_HAS_CODE_PREFIX | DataFlag.DATA_CHECKSUM_INVERTED
), (
# Used by early (pre-digital-I/O) Bemani games
"extended alt. (no IDs)",
"extended (no IDs, alt)",
ExtendedParser,
DataFlag.DATA_HAS_CODE_PREFIX
), (
# Used by GX706
"extended (no IDs, GX706)",
ExtendedParser,
DataFlag.DATA_HAS_CODE_PREFIX | DataFlag.DATA_GX706_WORKAROUND
), (
# Used by GE936/GK936 and all ZS01 Bemani games
"extended + all IDs",