Updated main.py - added GBA stuff.

Added gameboy_advance.py
This commit is contained in:
Yuuki Chan 2023-10-22 19:46:29 +09:00
parent 3b7e291904
commit 72ca194a05
2 changed files with 111 additions and 1 deletions

12
main.py
View file

@ -1,7 +1,8 @@
import sys import sys
from logger import Logger from logger import Logger
from rominfo.nintendo_ds import * from rominfo.nintendo_ds import nds_get_info
from rominfo.gameboy_advance import gba_get_info
logger = Logger('RomInfo') logger = Logger('RomInfo')
@ -18,6 +19,15 @@ if __name__ == '__main__':
if 'DSi ' in nds_get_info('unitcode', nds): if 'DSi ' in nds_get_info('unitcode', nds):
logger.info('Game revision : {} (DSi only)'.format(nds_get_info('gamerevision', nds))) logger.info('Game revision : {} (DSi only)'.format(nds_get_info('gamerevision', nds)))
logger.info('Game region : {}'.format(nds_get_info('region', nds))) logger.info('Game region : {}'.format(nds_get_info('region', nds)))
if sys.argv[1].endswith('.gba'):
with open(sys.argv[1], mode='rb') as gba:
logger.info('Logo : {}'.format(gba_get_info('nintendologo', gba)))
logger.info('Title : {}'.format(gba_get_info('title', gba)))
logger.info('Game code : {}'.format(gba_get_info('gamecode', gba)))
logger.info('Maker code : {}'.format(gba_get_info('makercode', gba)))
logger.info('Software version : {}'.format(gba_get_info('softwareversion', gba)))
logger.info('Complement check : {}'.format(gba_get_info('complement', gba)))
else: else:
logger.error('No ROM specified. App requires one argument.') logger.error('No ROM specified. App requires one argument.')

100
rominfo/gameboy_advance.py Normal file
View file

@ -0,0 +1,100 @@
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)'