123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- import sqlite3
- import os
- import re
- import string
- import stat
- import popen2
- import glob
- import sys
- import pprint
- # Detect Mirrord Roms
- # Rom Type Mapping
- #
- # 0 ROM only
- # 1 ROM and RAM
- # 2 ROM and Save RAM
- # 3 ROM and DSP1 chip
- # 4 ROM, RAM and DSP1 chip
- # 5 ROM, Save RAM and DSP1 chip
- # 19 ROM and Super FX chip
- # 227 ROM, RAM and GameBoy data
- # 246 ROM and DSP2 chip
- # Process /Users/david/Devel/arch/snes/roms/Teenage Mutant Ninja Turtles IV - Turtles in Time (U) [!].smc
- # 0 uCON64 2.0.0 Apple (PPC) 1999-2005
- # 1 Uses code from various people. See 'developers.html' for more!
- # 2 This may be freely redistributed under the terms of the GNU Public License
- # 4 /Users/david/Devel/arch/snes/roms/Teenage Mutant Ninja Turtles IV - Turtles in Time (U) [!].smc
- # 6 Multi Game Doctor (2)/Multi Game Hunter/MGH
- # 8 00007fb0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ........
- # 9 00007fc0 54 2e 4d 2e 4e 2e 54 2e 20 34 20 20 20 20 20 20 T.M.N.T. 4
- # 10 00007fd0 20 20 20 20 20 20 00 0a 00 01 a4 00 7c e9 83 16 ......|...
- # 12 Super Nintendo Entertainment System/SNES/Super Famicom
- # 13 T.M.N.T. 4
- # 14 Konami
- # 15 U.S.A.
- # 16 1048576 Bytes (8.0000 Mb)
- # 18 Padded: Maybe, 105 Bytes (0.0008 Mb)
- # 19 Interleaved/Swapped: No
- # 20 Backup unit/emulator header: No
- # 21 HiROM: No
- # 22 Internal size: 8 Mb
- # 23 ROM type: (0) ROM
- # 24 ROM speed: 200 ns (SlowROM)
- # 25 SRAM: No
- # 26 Version: 1.0
- # 27 Checksum: Ok, 0x1683 (calculated) == 0x1683 (internal)
- # 28 Inverse checksum: Ok, 0xe97c (calculated) == 0xe97c (internal)
- # 29 Checksum (CRC32): 0x5940bd99
- # 31 This ROM has no backup unit header
- swc_header_tpl = '''
- Backup unit header info (SWC)
- 00000000 20 00 0c 00 00 00 00 00 aa bb 04 00 00 00 00 00 ...............
- 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- [0-1] File size: 262144 Bytes (2.0000 Mb) => Matches
- [2:7] Run program in mode: 3
- [2:6] Split: No => Matches
- [2:5] SRAM mapping mode: LoROM => Matches
- [2:4] DRAM mapping mode: LoROM => Matches
- [2:3-2] SRAM size: 0 kB => Matches
- [2:1] Run program in mode: 3
- [2:0] External cartridge memory: Disabled
- '''
- def createdb():
- try:
- os.unlink("roms.sqlite3")
- except:
- pass
- conn = sqlite3.connect('roms.sqlite3')
- c = conn.cursor()
- c.execute('''create table roms
- (
- file_name text,
- file_ext text,
- file_size integer,
- rom_size integer,
- rom_mb real,
- rom_padded integer,
- rom_trainer integer,
- rom_backup integer,
- rom_name text,
- rom_vendor text,
- rom_region text,
- rom_hirom integer,
- rom_internalsize integer,
- rom_type integer,
- rom_speed integer,
- rom_sram integer,
- rom_version real,
- rom_chk integer,
- swc_size integer,
- swc_mode integer,
- swc_split text,
- swc_sram_mode text,
- swc_dram_mode text,
- swc_sram_size text
- )''')
- return conn, c
- def process(conn, c, file_name, out):
- file_ext = os.path.splitext(file_name)[1].replace(".", '')
- file_size = os.stat(file_name)[stat.ST_SIZE]
- rom_size = 0
- rom_mb = 0
- rom_padded = 0
- rom_trainer = 0
- rom_backup = 0
- rom_name = ''
- rom_vendor = ''
- rom_region = ''
- rom_hirom = 0
- rom_internalsize = 0
- rom_type = 0
- rom_speed = 0
- rom_sram = 0
- rom_version = 0
- rom_chk = 0
- swc_size = 0
- swc_mode = 0
- swc_split = ''
- swc_sram_mode = ''
- swc_dram_mode = ''
- swc_sram_size = ''
- print "-" * 60
- print "Process %s" % file_name
- try:
- rom_name = out[13]
- rom_vendor = out[14]
- rom_region = out[15]
- try:
- rom_size = int(out[16].split(" ")[0])
- rom_mb = float(
- re.compile("([\d.]+) Mb").search(out[16]).groups()[0])
- except:
- print "Broken..."
- return
- if not "No" in out[18]:
- rom_padded = int(
- re.compile("([\d.]+) Bytes").search(out[18]).groups()[0])
- for idx, line in enumerate(out):
- if line is None:
- continue
- if "Backup unit/emulator header: Yes" in line:
- rom_backup = int(
- re.compile("([\d.]+) Bytes").search(line).groups()[0])
- if "Intro/Trainer:" in line:
- rom_trainer = int(
- re.compile("([\d.]+) Bytes").search(line).groups()[0])
- if "HiROM: Yes" in line:
- rom_hirom = 1
- if "Internal size:" in line:
- rom_internalsize = int(
- re.compile("([\d.]+) Mb").search(line).groups()[0])
- if "ROM type:" in line:
- try:
- rom_type = int(
- re.compile("([\d]+)").search(line).groups()[0])
- except:
- pass
- if "ROM speed:" in line:
- rom_speed = int(
- re.compile("([\d]+) ns").search(line).groups()[0])
- if "SRAM: Yes" in line:
- rom_sram = int(
- re.compile("([\d]+) kBytes").search(line).groups()[0])
- if "Version:" in line:
- rom_version = float(
- re.compile("([\d.]+)").search(line).groups()[0])
- if "Checksum: Ok" in line:
- rom_chk = 1
- except:
- for idx, line in enumerate(out):
- if line is None:
- continue
- print idx, line
- sys.exit()
- query = """INSERT INTO roms
- VALUES
- (
- ?,?,?,?,?,
- ?,?,?,?,?,
- ?,?,?,?,?,
- ?,?,?,?,?,
- ?,?,?,?) """
- data = (file_name,
- file_ext,
- file_size,
- rom_size,
- rom_mb,
- rom_padded,
- rom_trainer,
- rom_backup,
- rom_name,
- rom_vendor,
- rom_region,
- rom_hirom,
- rom_internalsize,
- rom_type,
- rom_speed,
- rom_sram,
- rom_version,
- rom_chk,
- swc_size,
- swc_mode,
- swc_split,
- swc_sram_mode,
- swc_dram_mode,
- swc_sram_size)
- c.execute(query, data)
- conn.commit()
- def ucon64_info(filename):
- cmd = "ucon64 --dbuh -snes \"%s\"" % filename
- r, w, e = popen2.popen3(cmd)
- err = e.readlines()
- out = r.readlines()
- r.close()
- e.close()
- w.close()
- if len(err):
- return False, err
- return out, err
- def clean(s):
- s = s.replace("\n", "")
- if not len(s):
- return None
- return s
- def main():
- conn, c = createdb()
- path = sys.argv[1]
- files = glob.glob(path + "/*")
- for filename in files:
- try:
- r, err = ucon64_info(filename)
- if not r:
- print err
- continue
- r = map(clean, r)
- process(conn, c, filename, r)
- except (KeyboardInterrupt, SystemExit):
- print "Saving DB..."
- c.close()
- conn.commit()
- conn.close()
- sys.exit(-1)
- c.close()
- conn.commit()
- conn.close()
- if __name__ == "__main__":
- main()
|