Skip to content
Snippets Groups Projects
data.py 2.15 KiB
Newer Older
  • Learn to ignore specific revisions
  • Vicki Pfau's avatar
    Vicki Pfau committed
    from retro._retro import GameDataGlue
    import os
    
    
    class GameData(GameDataGlue):
        def __getitem__(self, name):
            return self.get_variable(name)
    
        def __setitem__(self, name, value):
            return self.set_variable(name, value)
    
        def __delitem__(self, name):
            self.remove_variable(name)
    
        def __iter__(self):
            variables = self.list_variables()
            for v in variables.items():
                yield v
    
        def __contains__(self, name):
            variables = self.list_variables()
            return name in variables
    
    
    def parse_smd(header, body):
        import numpy as np
        try:
            if body[0x80] != b'E' or body[0x81] != b'A':
                return header + body
            body2 = b''
            for i in range(len(body) / 0x4000):
                block = body[i * 0x4000:(i + 1) * 0x4000]
                if not block:
                    break
                nb = np.fromstring(block, dtype=np.uint8)
                nb = np.flipud(nb.reshape(2, 0x2000))
                nb = nb.flatten(order='F')
                body2 += nb.tostring()
        except IndexError:
            return header + body
        return body2
    
    
    def groom_rom(rom):
        import hashlib
        with open(rom, 'rb') as r:
            # Read Super Magic Drive header
            header = r.read(512)
            body = r.read()
        body = parse_smd(header, body)
        header = b''
        return body, hashlib.sha1(body).hexdigest()
    
    
    def merge(*args, quiet=True):
        import retro
        known_hashes = {}
        for game in retro.list_games():
            shafile = os.path.join(retro.get_game_path(game), 'rom.sha')
            with open(shafile) as f:
                shas = f.read().strip().split('\n')
            for ext, platform in retro.EMU_EXTENSIONS.items():
                if game.endswith('-' + platform):
                    break
            for sha in shas:
                known_hashes[sha] = (game, ext)
        for rom in args:
            try:
                data, hash = groom_rom(rom)
            except IOError:
                continue
            if hash in known_hashes:
                game, ext = known_hashes[hash]
                if not quiet:
                    print('Importing', game)
                with open(os.path.join(retro.get_game_path(game), 'rom%s' % ext), 'wb') as f:
                    f.write(data)