from typing import BinaryIO LOGO = '0x24ffae51699aa2213d84820a84e409ad11248b98c0817f21a352be199309ce2010464a4af82731ec58c7e83382e3cebf85f4df94ce4b09c194568ac01372a7fc9f844d73a3ca9a615897a327fc039876231dc7610304ae56bf38840040a70efdff52fe036f9530f197fbc08560d68025a963be03014e38e2f9a234ffbb3e0344780090cb88113a9465c07c6387f03cafd625e48b380aac7221d4f807' def gba_get_info(opt: str, inf: BinaryIO): match opt.lower(): case 'nintendologo': inf.seek(0x004) if LOGO == hex(int.from_bytes(inf.read(156))): return 'OK' else: return 'NOK' case 'title': inf.seek(0x0A0) return inf.read(12).decode() case 'gamecode': inf.seek(0x0AC) return _gamecode_lookup(inf.read(4).decode()) case 'makercode': inf.seek(0x0B0) return _maker_lookup(inf.read(2).decode()) case 'softwareversion': inf.seek(0x0BC) return str(int.from_bytes(inf.read(1))) case 'complement': return complement_check(inf) case _: return 'Unknown' def _gamecode_lookup(code: str) -> str: gamecode = [] match code[:1]: case 'A': gamecode.append('Normal game (2001-2003)') case 'B': gamecode.append('Normal game (2003+)') case 'C': gamecode.append('Normal game (not yet used)') case 'F': gamecode.append('Famicom/NES') case 'K': gamecode.append('Acceleration sensor') case 'P': gamecode.append('For e-Reader (dot-code scanner)') case 'R': gamecode.append('Rumble and Z-axis gyro sensor') case 'U': gamecode.append('RTC and solar sensor') case 'V': gamecode.append('Rumble motor') case '_': gamecode.append('Unknown') match code[3:]: case 'D': gamecode.append('German') case 'E': gamecode.append('USA/English') case 'F': gamecode.append('French') case 'I': gamecode.append('Italian') case 'J': gamecode.append('Japanese') case 'P': gamecode.append('Europe/elsewhere') case 'S': gamecode.append('Spanish') case '_': gamecode.append('Unknown') return '{} ({})'.format(code, f'Type: {gamecode[0]} | Language: {gamecode[1]})') def _maker_lookup(code: str) -> str: match code: case '01': return 'Nintendo ({})'.format(code) case 'A4': return 'Konami ({})'.format(code) case _: return 'Unknown ({})'.format(code) def complement_check(data: BinaryIO) -> str: data.seek(0x000) data = data.read() if len(data) >= 189: checksum = 0 for b in data[0x0A0:0x0BC]: checksum = (checksum - b) & 0xFF return '{} ({}/{})'.format((checksum - 0x19) & 0xFF == int.from_bytes(data[0x0BD:0x0BE]), (checksum - 0x19) & 0xFF, int.from_bytes(data[0x0BD:0x0BE])) else: return 'False (Invalid data length)'