Fix Python 3.10 incompatibility, add explicit DMA enable

This commit is contained in:
spicyjpeg 2024-12-27 23:50:33 +01:00
parent 4b57169e64
commit 7b4b3cb3a4
No known key found for this signature in database
GPG Key ID: 5CC87404C01DF393
18 changed files with 192 additions and 92 deletions

View File

@ -9,9 +9,7 @@
"identifiers": [ "darkhleg" ], "identifiers": [ "darkhleg" ],
"name": "Dark Horse Legend", "name": "Dark Horse Legend",
"year": 1998, "year": 1998
"flags": {}
}, },
{ {
"specifications": [ "GQ" ], "specifications": [ "GQ" ],
@ -70,9 +68,7 @@
"identifiers": [ "powyakex" ], "identifiers": [ "powyakex" ],
"name": "Jikkyou Powerful Pro Yakyuu EX", "name": "Jikkyou Powerful Pro Yakyuu EX",
"year": 1998, "year": 1998
"flags": {}
}, },
{ {
"specifications": [ "GC" ], "specifications": [ "GC" ],
@ -81,9 +77,7 @@
"identifiers": [ "jppyex98" ], "identifiers": [ "jppyex98" ],
"name": "Jikkyou Powerful Pro Yakyuu EX '98", "name": "Jikkyou Powerful Pro Yakyuu EX '98",
"year": 1998, "year": 1998
"flags": {}
}, },
{ {
"specifications": [ "GC" ], "specifications": [ "GC" ],
@ -92,9 +86,7 @@
"identifiers": [ "konam80sa", "konam80s", "konam80sk", "konam80su" ], "identifiers": [ "konam80sa", "konam80s", "konam80sk", "konam80su" ],
"name": "Konami 80's AC Special", "name": "Konami 80's AC Special",
"year": 1998, "year": 1998
"flags": {}
}, },
{ {
"specifications": [ "GC" ], "specifications": [ "GC" ],
@ -103,9 +95,7 @@
"identifiers": [ "konam80sj" ], "identifiers": [ "konam80sj" ],
"name": "Konami 80's Gallery", "name": "Konami 80's Gallery",
"year": 1998, "year": 1998
"flags": {}
}, },
{ {
"specifications": [ "GC", "GN" ], "specifications": [ "GC", "GN" ],
@ -244,9 +234,7 @@
"identifiers": [ "gchgchmp" ], "identifiers": [ "gchgchmp" ],
"name": "Gachaga Champ", "name": "Gachaga Champ",
"year": 1999, "year": 1999
"flags": {}
}, },
{ {
"specifications": [ "GQ" ], "specifications": [ "GQ" ],
@ -506,9 +494,7 @@
"identifiers": [ "hypbbc2p", "hypbbc2pk" ], "identifiers": [ "hypbbc2p", "hypbbc2pk" ],
"name": "Hyper Bishi Bashi Champ [2-player]", "name": "Hyper Bishi Bashi Champ [2-player]",
"year": 1999, "year": 1999
"flags": {}
}, },
{ {
"specifications": [ "GC" ], "specifications": [ "GC" ],
@ -580,7 +566,11 @@
"series": "PunchMania", "series": "PunchMania",
"year": 2000, "year": 2000,
"ioBoard": "GX700-PWB(F)" "ioBoard": "GX700-PWB(F)",
"gameCart": {
"pcb": "GX700-PWB(J)"
}
}, },
{ {
"specifications": [ "GQ" ], "specifications": [ "GQ" ],
@ -592,7 +582,11 @@
"series": "PunchMania", "series": "PunchMania",
"year": 2000, "year": 2000,
"ioBoard": "GX700-PWB(F)" "ioBoard": "GX700-PWB(F)",
"gameCart": {
"pcb": "GX700-PWB(J)"
}
}, },
{ {
"specifications": [ "GQ" ], "specifications": [ "GQ" ],
@ -636,9 +630,7 @@
"identifiers": [ "stepchmp" ], "identifiers": [ "stepchmp" ],
"name": "Step Champ", "name": "Step Champ",
"year": 1999, "year": 1999
"flags": {}
}, },
{ {
"specifications": [ "GE", "GK" ], "specifications": [ "GE", "GK" ],
@ -706,9 +698,7 @@
"identifiers": [ "animechmp" ], "identifiers": [ "animechmp" ],
"name": "Anime Champ", "name": "Anime Champ",
"year": 2000, "year": 2000
"flags": {}
}, },
{ {
"specifications": [ "GQ" ], "specifications": [ "GQ" ],
@ -720,7 +710,11 @@
"series": "PunchMania", "series": "PunchMania",
"year": 2000, "year": 2000,
"ioBoard": "GX700-PWB(F)" "ioBoard": "GX700-PWB(F)",
"gameCart": {
"pcb": "GX700-PWB(J)"
}
}, },
{ {
"specifications": [ "GQ" ], "specifications": [ "GQ" ],
@ -732,7 +726,11 @@
"series": "PunchMania", "series": "PunchMania",
"year": 2000, "year": 2000,
"ioBoard": "GX700-PWB(F)" "ioBoard": "GX700-PWB(F)",
"gameCart": {
"pcb": "GX700-PWB(J)"
}
}, },
{ {
"specifications": [ "GC" ], "specifications": [ "GC" ],
@ -754,7 +752,9 @@
"name": "Salary Man Champ [2-player]", "name": "Salary Man Champ [2-player]",
"year": 2000, "year": 2000,
"flags": {} "gameCart": {
"pcb": "PWB0000088954"
}
}, },
{ {
"specifications": [ "GC" ], "specifications": [ "GC" ],
@ -1047,9 +1047,7 @@
"identifiers": [ "gbbchmp" ], "identifiers": [ "gbbchmp" ],
"name": "Great Bishi Bashi Champ", "name": "Great Bishi Bashi Champ",
"year": 2002, "year": 2002
"flags": {}
}, },
{ {
"specifications": [ "GC" ], "specifications": [ "GC" ],

View File

@ -258,6 +258,17 @@ File *FATProvider::openFile(const char *path, uint32_t flags) {
return file; return file;
} }
bool FATProvider::deleteFile(const char *path) {
auto error = f_unlink(&_fs, path);
if (error) {
LOG_FS("%s: %s", _FATFS_ERROR_NAMES[error], path);
return false;
}
return true;
}
/* FatFs library API glue */ /* FatFs library API glue */
static constexpr int _MUTEX_TIMEOUT = 30000000; static constexpr int _MUTEX_TIMEOUT = 30000000;

View File

@ -72,6 +72,7 @@ public:
bool createDirectory(const char *path); bool createDirectory(const char *path);
File *openFile(const char *path, uint32_t flags); File *openFile(const char *path, uint32_t flags);
bool deleteFile(const char *path);
}; };
} }

View File

@ -148,6 +148,7 @@ public:
virtual bool createDirectory(const char *path) { return false; } virtual bool createDirectory(const char *path) { return false; }
virtual File *openFile(const char *path, uint32_t flags) { return nullptr; } virtual File *openFile(const char *path, uint32_t flags) { return nullptr; }
virtual bool deleteFile(const char *path) { return false; }
virtual size_t loadData(util::Data &output, const char *path); virtual size_t loadData(util::Data &output, const char *path);
virtual size_t loadData(void *output, size_t length, const char *path); virtual size_t loadData(void *output, size_t length, const char *path);
virtual size_t saveData(const void *input, size_t length, const char *path); virtual size_t saveData(const void *input, size_t length, const char *path);

View File

@ -385,7 +385,8 @@ bool ISO9660Provider::_getRecord(
} }
bool ISO9660Provider::init(storage::Device &dev) { bool ISO9660Provider::init(storage::Device &dev) {
_dev = &dev; if (type)
return false;
// Locate and parse the primary volume descriptor. // Locate and parse the primary volume descriptor.
size_t numPVDSectors = util::min( size_t numPVDSectors = util::min(
@ -425,6 +426,7 @@ bool ISO9660Provider::init(storage::Device &dev) {
type = ISO9660; type = ISO9660;
capacity = uint64_t(pvd->volumeLength.le) * _dev->sectorLength; capacity = uint64_t(pvd->volumeLength.le) * _dev->sectorLength;
_dev = &dev;
LOG_FS("mounted ISO: %s", volumeLabel); LOG_FS("mounted ISO: %s", volumeLabel);
return true; return true;

View File

@ -182,6 +182,17 @@ File *HostProvider::openFile(const char *path, uint32_t flags) {
return file; return file;
} }
bool HostProvider::deleteFile(const char *path) {
int error = pcdrvUnlink(path);
if (error < 0) {
LOG_FS("PCDRV error %d: %s", error, path);
return false;
}
return true;
}
/* Virtual filesystem driver */ /* Virtual filesystem driver */
VFSMountPoint *VFSProvider::_getMounted(const char *path) { VFSMountPoint *VFSProvider::_getMounted(const char *path) {
@ -311,6 +322,15 @@ File *VFSProvider::openFile(const char *path, uint32_t flags) {
return mp->provider->openFile(&path[mp->pathOffset], flags); return mp->provider->openFile(&path[mp->pathOffset], flags);
} }
bool VFSProvider::deleteFile(const char *path) {
auto mp = _getMounted(path);
if (!mp)
return false;
return mp->provider->deleteFile(&path[mp->pathOffset]);
}
size_t VFSProvider::loadData(util::Data &output, const char *path) { size_t VFSProvider::loadData(util::Data &output, const char *path) {
auto mp = _getMounted(path); auto mp = _getMounted(path);

View File

@ -61,6 +61,7 @@ public:
bool createDirectory(const char *path); bool createDirectory(const char *path);
File *openFile(const char *path, uint32_t flags); File *openFile(const char *path, uint32_t flags);
bool deleteFile(const char *path);
}; };
/* Virtual filesystem driver */ /* Virtual filesystem driver */
@ -98,6 +99,7 @@ public:
bool createDirectory(const char *path); bool createDirectory(const char *path);
File *openFile(const char *path, uint32_t flags); File *openFile(const char *path, uint32_t flags);
bool deleteFile(const char *path);
size_t loadData(util::Data &output, const char *path); size_t loadData(util::Data &output, const char *path);
size_t loadData(void *output, size_t length, const char *path); size_t loadData(void *output, size_t length, const char *path);
size_t saveData(const void *input, size_t length, const char *path); size_t saveData(const void *input, size_t length, const char *path);

View File

@ -129,6 +129,7 @@ bool PackageProvider::getFileInfo(FileInfo &output, const char *path) {
__builtin_strncpy(output.name, ptr, sizeof(output.name)); __builtin_strncpy(output.name, ptr, sizeof(output.name));
output.size = entry->uncompLength; output.size = entry->uncompLength;
output.attributes = READ_ONLY | ARCHIVE; output.attributes = READ_ONLY | ARCHIVE;
return true; return true;
} }

View File

@ -32,6 +32,18 @@ namespace gpu {
static constexpr int _DMA_CHUNK_SIZE = 1; static constexpr int _DMA_CHUNK_SIZE = 1;
static constexpr int _DMA_TIMEOUT = 10000; static constexpr int _DMA_TIMEOUT = 10000;
void init(void) {
DMA_DPCR |= 0
| (DMA_DPCR_ENABLE << (DMA_GPU * 4))
| (DMA_DPCR_ENABLE << (DMA_OTC * 4));
TIMER_CTRL(0) = TIMER_CTRL_EXT_CLOCK;
TIMER_CTRL(1) = TIMER_CTRL_EXT_CLOCK;
GPU_GP1 = gp1_resetGPU();
GPU_GP1 = gp1_resetFIFO();
}
size_t upload(const RectWH &rect, const void *data, bool wait) { size_t upload(const RectWH &rect, const void *data, bool wait) {
size_t length = (rect.w * rect.h) / 2; size_t length = (rect.w * rect.h) / 2;

View File

@ -48,14 +48,6 @@ public:
/* Basic API */ /* Basic API */
static inline void init(void) {
GPU_GP1 = gp1_resetGPU();
GPU_GP1 = gp1_resetFIFO();
TIMER_CTRL(0) = TIMER_CTRL_EXT_CLOCK;
TIMER_CTRL(1) = TIMER_CTRL_EXT_CLOCK;
}
static inline bool isIdle(void) { static inline bool isIdle(void) {
return ( return (
!(DMA_CHCR(DMA_GPU) & DMA_CHCR_ENABLE) && (GPU_GP1 & GP1_STAT_CMD_READY) !(DMA_CHCR(DMA_GPU) & DMA_CHCR_ENABLE) && (GPU_GP1 & GP1_STAT_CMD_READY)
@ -66,6 +58,7 @@ static inline void enableDisplay(bool enable) {
GPU_GP1 = gp1_dispBlank(!enable); GPU_GP1 = gp1_dispBlank(!enable);
} }
void init(void);
size_t upload(const RectWH &rect, const void *data, bool wait = false); size_t upload(const RectWH &rect, const void *data, bool wait = false);
size_t download(const RectWH &rect, void *data, bool wait = false); size_t download(const RectWH &rect, void *data, bool wait = false);

View File

@ -46,6 +46,7 @@ void init(void) {
| (23 << 16) // Number of address lines | (23 << 16) // Number of address lines
| ( 4 << 24) // DMA read/write delay | ( 4 << 24) // DMA read/write delay
| BIU_CTRL_DMA_DELAY; | BIU_CTRL_DMA_DELAY;
DMA_DPCR |= DMA_DPCR_ENABLE << (DMA_PIO * 4);
#if 0 #if 0
// Revision D of the main board has footprints for either eight 8-bit RAM // Revision D of the main board has footprints for either eight 8-bit RAM
@ -158,12 +159,12 @@ void getRTCTime(util::Date &output) {
SYS573_RTC_CTRL &= ~SYS573_RTC_CTRL_READ; SYS573_RTC_CTRL &= ~SYS573_RTC_CTRL_READ;
output.year = (year & 15) + 10 * ((year >> 4) & 15); // 0-99 output.year = util::decodeBCD(year); // 0-99
output.month = (month & 15) + 10 * ((month >> 4) & 1); // 1-12 output.month = util::decodeBCD(month); // 1-12
output.day = (day & 15) + 10 * ((day >> 4) & 3); // 1-31 output.day = util::decodeBCD(day); // 1-31
output.hour = (hour & 15) + 10 * ((hour >> 4) & 3); // 0-23 output.hour = util::decodeBCD(hour); // 0-23
output.minute = (minute & 15) + 10 * ((minute >> 4) & 7); // 0-59 output.minute = util::decodeBCD(minute); // 0-59
output.second = (second & 15) + 10 * ((second >> 4) & 7); // 0-59 output.second = util::decodeBCD(second); // 0-59
output.year += (output.year < 70) ? 2000 : 1900; output.year += (output.year < 70) ? 2000 : 1900;
} }
@ -171,15 +172,13 @@ void getRTCTime(util::Date &output) {
void setRTCTime(const util::Date &value, bool stop) { void setRTCTime(const util::Date &value, bool stop) {
assert((value.year >= 1970) && (value.year <= 2069)); assert((value.year >= 1970) && (value.year <= 2069));
int _year = value.year % 100;
int weekday = value.getDayOfWeek() + 1; int weekday = value.getDayOfWeek() + 1;
int year = util::encodeBCD(value.year % 100);
int year = (_year % 10) | (((_year / 10) & 15) << 4); int month = util::encodeBCD(value.month);
int month = (value.month % 10) | (((value.month / 10) & 1) << 4); int day = util::encodeBCD(value.day);
int day = (value.day % 10) | (((value.day / 10) & 3) << 4); int hour = util::encodeBCD(value.hour);
int hour = (value.hour % 10) | (((value.hour / 10) & 3) << 4); int minute = util::encodeBCD(value.minute);
int minute = (value.minute % 10) | (((value.minute / 10) & 7) << 4); int second = util::encodeBCD(value.second);
int second = (value.second % 10) | (((value.second / 10) & 7) << 4);
SYS573_RTC_CTRL |= SYS573_RTC_CTRL_WRITE; SYS573_RTC_CTRL |= SYS573_RTC_CTRL_WRITE;

View File

@ -67,6 +67,10 @@ static constexpr int _DMA_CHUNK_SIZE_OUT = 32;
static constexpr int _DMA_TIMEOUT = 100000; static constexpr int _DMA_TIMEOUT = 100000;
void init(void) { void init(void) {
DMA_DPCR |= 0
| (DMA_DPCR_ENABLE << (DMA_MDEC_IN * 4))
| (DMA_DPCR_ENABLE << (DMA_MDEC_OUT * 4));
MDEC1 = MDEC_CTRL_RESET; MDEC1 = MDEC_CTRL_RESET;
MDEC1 = MDEC_CTRL_DMA_OUT | MDEC_CTRL_DMA_IN; MDEC1 = MDEC_CTRL_DMA_OUT | MDEC_CTRL_DMA_IN;

View File

@ -16,7 +16,6 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "common/util/hash.hpp"
#include "common/util/log.hpp" #include "common/util/log.hpp"
#include "common/util/templates.hpp" #include "common/util/templates.hpp"
#include "common/io.hpp" #include "common/io.hpp"
@ -417,22 +416,6 @@ static const ShellInfo _KONAMI_SHELLS[]{
} }
}; };
bool SonyKernelHeader::validateMagic(void) const {
return (
util::hash(magic, sizeof(magic)) == "Sony Computer Entertainment Inc."_h
);
}
bool OpenBIOSHeader::validateMagic(void) const {
return (util::hash(magic, sizeof(magic)) == "OpenBIOS"_h);
}
bool ShellInfo::validateHash(void) const {
return (util::hash(
reinterpret_cast<const uint8_t *>(header), sizeof(util::ExecutableHeader)
) == headerHash);
}
bool getShellInfo(ShellInfo &output) { bool getShellInfo(ShellInfo &output) {
for (auto &shell : _KONAMI_SHELLS) { for (auto &shell : _KONAMI_SHELLS) {
if (!shell.validateHash()) if (!shell.validateHash())

View File

@ -21,6 +21,7 @@
#include "common/util/hash.hpp" #include "common/util/hash.hpp"
#include "common/util/misc.hpp" #include "common/util/misc.hpp"
#include "common/util/string.hpp" #include "common/util/string.hpp"
#include "common/util/templates.hpp"
#include "ps1/registers.h" #include "ps1/registers.h"
namespace rom { namespace rom {
@ -117,20 +118,28 @@ public:
uint32_t flags; uint32_t flags;
uint8_t magic[32], _pad[4], version[36]; uint8_t magic[32], _pad[4], version[36];
bool validateMagic(void) const; inline bool validateMagic(void) const {
return (
util::hash(magic, sizeof(magic)) ==
"Sony Computer Entertainment Inc."_h
);
}
}; };
class OpenBIOSHeader { class OpenBIOSHeader {
public: public:
uint8_t magic[8]; uint32_t magic[2];
uint32_t idNameLength, idDescLength, idType; uint32_t idNameLength, idDescLength, idType;
uint8_t idData[24]; uint8_t idData[24];
inline bool validateMagic(void) const {
return (magic[0] == "Open"_c) && (magic[1] == "BIOS"_c);
}
inline size_t getBuildID(char *output) const { inline size_t getBuildID(char *output) const {
return util::hexToString(output, &idData[idNameLength], idDescLength); return util::hexToString(output, &idData[idNameLength], idDescLength);
} }
bool validateMagic(void) const;
}; };
class ShellInfo { class ShellInfo {
@ -140,7 +149,12 @@ public:
const util::ExecutableHeader *header; const util::ExecutableHeader *header;
bool validateHash(void) const; inline bool validateHash(void) const {
return (util::hash(
reinterpret_cast<const uint8_t *>(header),
sizeof(util::ExecutableHeader)
) == headerHash);
}
}; };
static const auto &sonyKernelHeader = static const auto &sonyKernelHeader =

View File

@ -51,6 +51,7 @@ void init(void) {
| (9 << 16) // Number of address lines | (9 << 16) // Number of address lines
| (0 << 24) // DMA read/write delay | (0 << 24) // DMA read/write delay
| BIU_CTRL_DMA_DELAY; | BIU_CTRL_DMA_DELAY;
DMA_DPCR |= DMA_DPCR_ENABLE << (DMA_SPU * 4);
SPU_CTRL = 0; SPU_CTRL = 0;
_waitForStatus(0x3f, 0); _waitForStatus(0x3f, 0);

View File

@ -23,6 +23,48 @@
namespace storage { namespace storage {
/* CD-ROM definitions */
static constexpr uint32_t CDROM_TOC_PREGAP = 150;
class MSF {
public:
uint8_t minute, second, frame;
inline void fromLBA(uint32_t lba) {
lba += CDROM_TOC_PREGAP;
minute = lba / 4500;
second = (lba / 75) % 60;
frame = lba % 75;
}
inline uint32_t toLBA(void) const {
return -CDROM_TOC_PREGAP
+ minute * 4500
+ second * 75
+ frame;
}
};
class BCDMSF {
public:
uint8_t minute, second, frame;
inline void fromLBA(uint32_t lba) {
lba += CDROM_TOC_PREGAP;
minute = util::encodeBCD(lba / 4500);
second = util::encodeBCD((lba / 75) % 60);
frame = util::encodeBCD(lba % 75);
}
inline uint32_t toLBA(void) const {
return -CDROM_TOC_PREGAP
+ util::decodeBCD(minute) * 4500
+ util::decodeBCD(second) * 75
+ util::decodeBCD(frame);
}
};
/* IDE register definitions */ /* IDE register definitions */
enum IDECS0Register { enum IDECS0Register {

View File

@ -91,6 +91,8 @@ template<typename T> static constexpr inline size_t countOf(T &array) {
return sizeof(array) / sizeof(array[0]); return sizeof(array) / sizeof(array[0]);
} }
/* Concatenation and BCD conversion */
static constexpr inline uint16_t concat2(uint8_t low, uint8_t high) { static constexpr inline uint16_t concat2(uint8_t low, uint8_t high) {
return low | (high << 8); return low | (high << 8);
} }
@ -130,6 +132,20 @@ static constexpr inline uint64_t concat8(
| (uint64_t(g) << 48) | (uint64_t(h) << 56); | (uint64_t(g) << 48) | (uint64_t(h) << 56);
} }
static constexpr inline uint8_t encodeBCD(uint8_t value) {
// output = units + tens * 16
// = units + tens * 10 + tens * 6
// = value + tens * 6
return value + (value / 10) * 6;
}
static constexpr inline uint8_t decodeBCD(uint8_t value) {
// output = low + high * 10
// = low + high * 16 - high * 6
// = value - high * 6
return value - (value >> 4) * 6;
}
/* Simple "smart" pointer */ /* Simple "smart" pointer */
class Data { class Data {

View File

@ -18,7 +18,7 @@ from collections.abc import Mapping
from dataclasses import dataclass from dataclasses import dataclass
from enum import IntEnum, IntFlag from enum import IntEnum, IntFlag
from struct import Struct from struct import Struct
from typing import Any, Self from typing import Any
from .util import JSONGroupedObject from .util import JSONGroupedObject
@ -57,7 +57,7 @@ class CartPCBType(IntEnum):
CART_PWB0000088954 = 13 CART_PWB0000088954 = 13
@staticmethod @staticmethod
def fromJSONObject(obj: str) -> Self: def fromJSONObject(obj: str):
return { return {
"unknown-x76f041": CartPCBType.CART_UNKNOWN_X76F041, "unknown-x76f041": CartPCBType.CART_UNKNOWN_X76F041,
"unknown-x76f041-ds2401": CartPCBType.CART_UNKNOWN_X76F041_DS2401, "unknown-x76f041-ds2401": CartPCBType.CART_UNKNOWN_X76F041_DS2401,
@ -107,7 +107,7 @@ class HeaderFlag(IntFlag):
REGION_LOWERCASE = 1 << 7 REGION_LOWERCASE = 1 << 7
@staticmethod @staticmethod
def fromJSONObject(obj: Mapping[str, Any]) -> Self: def fromJSONObject(obj: Mapping[str, Any]):
flags: HeaderFlag = HeaderFlag(0) flags: HeaderFlag = HeaderFlag(0)
flags |= { flags |= {
@ -167,7 +167,7 @@ class ChecksumFlag(IntFlag):
CHECKSUM_FORCE_GX_SPEC = 1 << 5 CHECKSUM_FORCE_GX_SPEC = 1 << 5
@staticmethod @staticmethod
def fromJSONObject(obj: Mapping[str, Any]) -> Self: def fromJSONObject(obj: Mapping[str, Any]):
flags: ChecksumFlag = ChecksumFlag(0) flags: ChecksumFlag = ChecksumFlag(0)
flags |= { flags |= {
@ -221,7 +221,7 @@ class IdentifierFlag(IntFlag):
PUBLIC_XID_PRESENT = 1 << 7 PUBLIC_XID_PRESENT = 1 << 7
@staticmethod @staticmethod
def fromJSONObject(obj: Mapping[str, Any]) -> Self: def fromJSONObject(obj: Mapping[str, Any]):
flags: IdentifierFlag = IdentifierFlag(0) flags: IdentifierFlag = IdentifierFlag(0)
flags |= { flags |= {
@ -274,7 +274,7 @@ class SignatureFlag(IntFlag):
SIGNATURE_PAD_WITH_FF = 1 << 2 SIGNATURE_PAD_WITH_FF = 1 << 2
@staticmethod @staticmethod
def fromJSONObject(obj: Mapping[str, Any]) -> Self: def fromJSONObject(obj: Mapping[str, Any]):
flags: SignatureFlag = SignatureFlag(0) flags: SignatureFlag = SignatureFlag(0)
flags |= { flags |= {
@ -316,7 +316,7 @@ class IOBoardType(IntEnum):
IO_BOARD_GUNMANIA = 6 IO_BOARD_GUNMANIA = 6
@staticmethod @staticmethod
def fromJSONObject(obj: str | None) -> Self: def fromJSONObject(obj: str | None):
return { return {
None: IOBoardType.IO_BOARD_NONE, None: IOBoardType.IO_BOARD_NONE,
"GX700-PWB(F)": IOBoardType.IO_BOARD_ANALOG, "GX700-PWB(F)": IOBoardType.IO_BOARD_ANALOG,
@ -347,7 +347,7 @@ class PCMCIADeviceType(IntEnum):
PCMCIA_FLASH_CARD_64 = 5 PCMCIA_FLASH_CARD_64 = 5
@staticmethod @staticmethod
def fromJSONObject(obj: str | None) -> Self: def fromJSONObject(obj: str | None):
return { return {
None: PCMCIADeviceType.PCMCIA_NONE, None: PCMCIADeviceType.PCMCIA_NONE,
"PWB0000100991": PCMCIADeviceType.PCMCIA_NETWORK_PCB, "PWB0000100991": PCMCIADeviceType.PCMCIA_NETWORK_PCB,
@ -372,7 +372,7 @@ class GameFlag(IntFlag):
GAME_RTC_HEADER_REQUIRED = 1 << 1 GAME_RTC_HEADER_REQUIRED = 1 << 1
@staticmethod @staticmethod
def fromJSONObject(obj: Mapping[str, Any]) -> Self: def fromJSONObject(obj: Mapping[str, Any]):
flags: GameFlag = GameFlag(0) flags: GameFlag = GameFlag(0)
for key, flag in { for key, flag in {
@ -412,7 +412,7 @@ class ROMHeaderInfo:
signatureFlags: SignatureFlag signatureFlags: SignatureFlag
@staticmethod @staticmethod
def fromJSONObject(obj: Mapping[str, Any]) -> Self: def fromJSONObject(obj: Mapping[str, Any]):
return ROMHeaderInfo( return ROMHeaderInfo(
bytes.fromhex(obj.get("signatureField", "").replace("-", " ")), bytes.fromhex(obj.get("signatureField", "").replace("-", " ")),
bytes.fromhex(obj.get("yearField", "").replace("-", " ")), bytes.fromhex(obj.get("yearField", "").replace("-", " ")),
@ -457,7 +457,7 @@ class CartInfo:
idFlags: IdentifierFlag idFlags: IdentifierFlag
@staticmethod @staticmethod
def fromJSONObject(obj: Mapping[str, Any]) -> Self: def fromJSONObject(obj: Mapping[str, Any]):
return CartInfo( return CartInfo(
CartPCBType.fromJSONObject(obj["pcb"]), CartPCBType.fromJSONObject(obj["pcb"]),
@ -523,7 +523,7 @@ class GameInfo:
gameCart: CartInfo | None = None gameCart: CartInfo | None = None
@staticmethod @staticmethod
def fromJSONObject(obj: Mapping[str, Any]) -> Self: def fromJSONObject(obj: Mapping[str, Any]):
rtcHeader: Mapping[str, Any] | None = obj.get("rtcHeader", None) rtcHeader: Mapping[str, Any] | None = obj.get("rtcHeader", None)
flashHeader: Mapping[str, Any] | None = obj.get("flashHeader", None) flashHeader: Mapping[str, Any] | None = obj.get("flashHeader", None)
installCart: Mapping[str, Any] | None = obj.get("installCart", None) installCart: Mapping[str, Any] | None = obj.get("installCart", None)