mirror of
https://github.com/robmcmullen/atrcopy.git
synced 2025-01-01 10:30:58 +00:00
Added MAME segment parsing from Omnivore
This commit is contained in:
parent
d8b100fd95
commit
f969d27e43
@ -14,7 +14,7 @@ from kboot import KBootImage, add_xexboot_header
|
||||
from segments import SegmentData, SegmentSaver, DefaultSegment, EmptySegment, ObjSegment, RawSectorsSegment, user_bit_mask, match_bit_mask, comment_bit_mask, data_bit_mask, selected_bit_mask, diff_bit_mask, not_user_bit_mask, interleave_segments
|
||||
from spartados import SpartaDosDiskImage
|
||||
from cartridge import A8CartHeader
|
||||
from parsers import SegmentParser, DefaultSegmentParser, guess_parser_for_mime, guess_parser_for_system, iter_known_segment_parsers, mime_parse_order
|
||||
from parsers import SegmentParser, DefaultSegmentParser, guess_parser_for_mime, guess_parser_for_system, iter_parsers, iter_known_segment_parsers, mime_parse_order
|
||||
from utils import to_numpy
|
||||
|
||||
|
||||
|
65
atrcopy/mame.py
Normal file
65
atrcopy/mame.py
Normal file
@ -0,0 +1,65 @@
|
||||
import zipfile
|
||||
|
||||
import numpy as np
|
||||
|
||||
from errors import *
|
||||
from segments import SegmentData, EmptySegment, ObjSegment
|
||||
from diskimages import DiskImageBase
|
||||
from utils import to_numpy
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MameZipImage(DiskImageBase):
|
||||
def __init__(self, rawdata, filename=""):
|
||||
self.zipdata = rawdata
|
||||
fh = self.zipdata.stringio
|
||||
if zipfile.is_zipfile(fh):
|
||||
with zipfile.ZipFile(fh) as zf:
|
||||
self.check_zip_size(zf)
|
||||
self.create_rawdata(zf)
|
||||
else:
|
||||
raise InvalidDiskImage("Not a MAME zip file")
|
||||
DiskImageBase.__init__(self, self.rawdata, filename)
|
||||
|
||||
def __str__(self):
|
||||
return "MAME Zip file, %d ROMs, orig_size=%d, uncompressed=%d" % (len(self.zip_segment_info), len(self.zipdata), len(self.rawdata))
|
||||
|
||||
def setup(self):
|
||||
self.check_size()
|
||||
|
||||
def strict_check(self):
|
||||
pass
|
||||
|
||||
def relaxed_check(self):
|
||||
pass
|
||||
|
||||
def check_zip_size(self, zf):
|
||||
for item in zf.infolist():
|
||||
_, r = divmod(item.file_size, 256)
|
||||
if r > 0:
|
||||
raise InvalidDiskImage("zip entry not 256 byte multiple")
|
||||
|
||||
def create_rawdata(self, zf):
|
||||
roms = []
|
||||
segment_info = []
|
||||
offset = 0
|
||||
for item in zf.infolist():
|
||||
rom = np.fromstring(zf.open(item).read(), dtype=np.uint8)
|
||||
roms.append(rom)
|
||||
segment_info.append((offset, item.file_size, item.filename, item.CRC))
|
||||
offset += item.file_size
|
||||
data = np.concatenate(roms)
|
||||
self.zip_segment_info = segment_info
|
||||
self.rawdata = SegmentData(data)
|
||||
|
||||
def check_size(self):
|
||||
pass
|
||||
|
||||
def parse_segments(self):
|
||||
r = self.rawdata
|
||||
self.segments = []
|
||||
for offset, size, name, crc in self.zip_segment_info:
|
||||
end = offset + size
|
||||
self.segments.append(ObjSegment(r[offset:end], 0, offset, offset, end, name=name))
|
@ -6,6 +6,7 @@ from kboot import KBootImage
|
||||
from ataridos import AtariDosDiskImage, AtariDosFile
|
||||
from spartados import SpartaDosDiskImage
|
||||
from cartridge import AtariCartImage, get_known_carts
|
||||
from mame import MameZipImage
|
||||
from errors import *
|
||||
|
||||
|
||||
@ -84,6 +85,11 @@ class AtariCartSegmentParser(SegmentParser):
|
||||
return self.image_type(r, self.cart_type)
|
||||
|
||||
|
||||
class MameZipParser(SegmentParser):
|
||||
menu_name = "MAME ROM Zipfile"
|
||||
image_type = MameZipImage
|
||||
|
||||
|
||||
def guess_parser_for_mime(mime, r):
|
||||
parsers = mime_parsers[mime]
|
||||
found = None
|
||||
@ -103,6 +109,13 @@ def guess_parser_for_system(mime_base, r):
|
||||
return mime, p
|
||||
return None, None
|
||||
|
||||
def iter_parsers(r):
|
||||
for mime in mime_parse_order:
|
||||
p = guess_parser_for_mime(mime, r)
|
||||
if p is not None:
|
||||
return mime, p
|
||||
return None, None
|
||||
|
||||
|
||||
mime_parsers = {
|
||||
"application/vnd.atari8bit.atr": [
|
||||
@ -114,20 +127,27 @@ mime_parsers = {
|
||||
"application/vnd.atari8bit.xex": [
|
||||
XexSegmentParser,
|
||||
],
|
||||
"application/vnd.mame_rom": [
|
||||
MameZipParser,
|
||||
],
|
||||
}
|
||||
|
||||
mime_parse_order = [
|
||||
"application/vnd.atari8bit.atr",
|
||||
"application/vnd.atari8bit.xex",
|
||||
"CARTS", # Will get filled in below
|
||||
"application/vnd.mame_rom",
|
||||
]
|
||||
|
||||
pretty_mime = {
|
||||
"application/vnd.atari8bit.atr": "Atari 8-bit Disk Image",
|
||||
"application/vnd.atari8bit.xex": "Atari 8-bit Executable",
|
||||
"application/vnd.mame_rom": "MAME"
|
||||
}
|
||||
|
||||
grouped_carts = get_known_carts()
|
||||
sizes = sorted(grouped_carts.keys())
|
||||
cart_order = []
|
||||
for k in sizes:
|
||||
if k > 128:
|
||||
key = "application/vnd.atari8bit.large_cart"
|
||||
@ -136,13 +156,15 @@ for k in sizes:
|
||||
key = "application/vnd.atari8bit.%dkb_cart" % k
|
||||
pretty = "Atari 8-bit %dKB Cartridge" % k
|
||||
if key not in mime_parsers:
|
||||
mime_parse_order.append(key)
|
||||
cart_order.append(key)
|
||||
pretty_mime[key] = pretty
|
||||
mime_parsers[key] = []
|
||||
for c in grouped_carts[k]:
|
||||
t = c[0]
|
||||
kclass = type("AtariCartSegmentParser%d" % t, (AtariCartSegmentParser,), {'cart_type': t, 'cart_info': c, 'menu_name': "%s Cartridge" % c[1]})
|
||||
mime_parsers[key].append(kclass)
|
||||
i = mime_parse_order.index("CARTS")
|
||||
mime_parse_order[i:i+1] = cart_order
|
||||
|
||||
|
||||
known_segment_parsers = [DefaultSegmentParser]
|
||||
|
@ -1,4 +1,5 @@
|
||||
import bisect
|
||||
import cStringIO
|
||||
|
||||
import numpy as np
|
||||
|
||||
@ -95,6 +96,11 @@ class SegmentData(object):
|
||||
|
||||
def __len__(self):
|
||||
return len(self.data)
|
||||
|
||||
@property
|
||||
def stringio(self):
|
||||
buf = cStringIO.StringIO(self.data[:])
|
||||
return buf
|
||||
|
||||
def get_data(self):
|
||||
return self.data
|
||||
|
Loading…
Reference in New Issue
Block a user