mirror of
https://github.com/robmcmullen/atrcopy.git
synced 2025-01-04 00:29:36 +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 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 spartados import SpartaDosDiskImage
|
||||||
from cartridge import A8CartHeader
|
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
|
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 ataridos import AtariDosDiskImage, AtariDosFile
|
||||||
from spartados import SpartaDosDiskImage
|
from spartados import SpartaDosDiskImage
|
||||||
from cartridge import AtariCartImage, get_known_carts
|
from cartridge import AtariCartImage, get_known_carts
|
||||||
|
from mame import MameZipImage
|
||||||
from errors import *
|
from errors import *
|
||||||
|
|
||||||
|
|
||||||
@ -84,6 +85,11 @@ class AtariCartSegmentParser(SegmentParser):
|
|||||||
return self.image_type(r, self.cart_type)
|
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):
|
def guess_parser_for_mime(mime, r):
|
||||||
parsers = mime_parsers[mime]
|
parsers = mime_parsers[mime]
|
||||||
found = None
|
found = None
|
||||||
@ -103,6 +109,13 @@ def guess_parser_for_system(mime_base, r):
|
|||||||
return mime, p
|
return mime, p
|
||||||
return None, None
|
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 = {
|
mime_parsers = {
|
||||||
"application/vnd.atari8bit.atr": [
|
"application/vnd.atari8bit.atr": [
|
||||||
@ -114,20 +127,27 @@ mime_parsers = {
|
|||||||
"application/vnd.atari8bit.xex": [
|
"application/vnd.atari8bit.xex": [
|
||||||
XexSegmentParser,
|
XexSegmentParser,
|
||||||
],
|
],
|
||||||
|
"application/vnd.mame_rom": [
|
||||||
|
MameZipParser,
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
mime_parse_order = [
|
mime_parse_order = [
|
||||||
"application/vnd.atari8bit.atr",
|
"application/vnd.atari8bit.atr",
|
||||||
"application/vnd.atari8bit.xex",
|
"application/vnd.atari8bit.xex",
|
||||||
|
"CARTS", # Will get filled in below
|
||||||
|
"application/vnd.mame_rom",
|
||||||
]
|
]
|
||||||
|
|
||||||
pretty_mime = {
|
pretty_mime = {
|
||||||
"application/vnd.atari8bit.atr": "Atari 8-bit Disk Image",
|
"application/vnd.atari8bit.atr": "Atari 8-bit Disk Image",
|
||||||
"application/vnd.atari8bit.xex": "Atari 8-bit Executable",
|
"application/vnd.atari8bit.xex": "Atari 8-bit Executable",
|
||||||
|
"application/vnd.mame_rom": "MAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
grouped_carts = get_known_carts()
|
grouped_carts = get_known_carts()
|
||||||
sizes = sorted(grouped_carts.keys())
|
sizes = sorted(grouped_carts.keys())
|
||||||
|
cart_order = []
|
||||||
for k in sizes:
|
for k in sizes:
|
||||||
if k > 128:
|
if k > 128:
|
||||||
key = "application/vnd.atari8bit.large_cart"
|
key = "application/vnd.atari8bit.large_cart"
|
||||||
@ -136,13 +156,15 @@ for k in sizes:
|
|||||||
key = "application/vnd.atari8bit.%dkb_cart" % k
|
key = "application/vnd.atari8bit.%dkb_cart" % k
|
||||||
pretty = "Atari 8-bit %dKB Cartridge" % k
|
pretty = "Atari 8-bit %dKB Cartridge" % k
|
||||||
if key not in mime_parsers:
|
if key not in mime_parsers:
|
||||||
mime_parse_order.append(key)
|
cart_order.append(key)
|
||||||
pretty_mime[key] = pretty
|
pretty_mime[key] = pretty
|
||||||
mime_parsers[key] = []
|
mime_parsers[key] = []
|
||||||
for c in grouped_carts[k]:
|
for c in grouped_carts[k]:
|
||||||
t = c[0]
|
t = c[0]
|
||||||
kclass = type("AtariCartSegmentParser%d" % t, (AtariCartSegmentParser,), {'cart_type': t, 'cart_info': c, 'menu_name': "%s Cartridge" % c[1]})
|
kclass = type("AtariCartSegmentParser%d" % t, (AtariCartSegmentParser,), {'cart_type': t, 'cart_info': c, 'menu_name': "%s Cartridge" % c[1]})
|
||||||
mime_parsers[key].append(kclass)
|
mime_parsers[key].append(kclass)
|
||||||
|
i = mime_parse_order.index("CARTS")
|
||||||
|
mime_parse_order[i:i+1] = cart_order
|
||||||
|
|
||||||
|
|
||||||
known_segment_parsers = [DefaultSegmentParser]
|
known_segment_parsers = [DefaultSegmentParser]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import bisect
|
import bisect
|
||||||
|
import cStringIO
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
@ -95,6 +96,11 @@ class SegmentData(object):
|
|||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self.data)
|
return len(self.data)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def stringio(self):
|
||||||
|
buf = cStringIO.StringIO(self.data[:])
|
||||||
|
return buf
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
return self.data
|
return self.data
|
||||||
|
Loading…
Reference in New Issue
Block a user