Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- # SPDX-License-Identifier: CC0-1.0
- import struct
- from pathlib import Path
- import shutil
- from convert import split
- def pixel_de4_to_dd4_tile8(i, fn):
- with open(fn, 'wb+') as o:
- data_big = i.read(2)
- times = 0
- packed_tile = bytearray(32)
- while data_big:
- pixels, = struct.unpack('<H', data_big)
- rom_pixels = ((pixels & 0x0001)
- | (pixels & 0x0002) << 1
- | (pixels & 0x0004) << 2
- | (pixels & 0x0008) << 3
- | (pixels & 0x0100) >> 7
- | (pixels & 0x0200) >> 6
- | (pixels & 0x0400) >> 5
- | (pixels & 0x0800) >> 4)
- assert not (rom_pixels & ~0xFF)
- pos = (times%4)*8 + times//4
- packed_tile[pos] = rom_pixels
- data_big = i.read(2)
- times += 1
- if times == 32:
- times = 0
- o.write(packed_tile)
- assert times < 32
- def pixel_de4_to_dd4_tile16(i, path_low, path_high):
- '''Convert from a DotEmu format to a "Double Dragon" 16x16 format
- The de4 (DotEmu) format holds 8 bits per pixel of which only the
- lowest 4 store data. Each byte read represents a pixel, the tiles
- have all their pixels together and ordered from left to right, top
- to bottom.
- de4_tile16 EXPLAIN
- path_low and path_high need to be Path like objects (with an open
- method)
- '''
- with path_low.open('wb+') as ol, path_high.open('wb+') as oh:
- data_big = i.read(4)
- times = 0
- packed_tile = bytearray(128)
- while data_big:
- pixels, = struct.unpack('<I', data_big)
- rom_pixels_low = ((pixels & 0x0001)
- | (pixels & 0x0000_0002) << 3
- | (pixels & 0x0000_0100) >> 7
- | (pixels & 0x0000_0200) >> 4
- | (pixels & 0x0001_0000) >> 14
- | (pixels & 0x0002_0000) >> 11
- | (pixels & 0x0100_0000) >> 21
- | (pixels & 0x0200_0000) >> 18)
- rom_pixels_high = ((pixels & 0x0004) >> 2
- | (pixels & 0x0000_0008) << 1
- | (pixels & 0x0000_0400) >> 9
- | (pixels & 0x0000_0800) >> 6
- | (pixels & 0x0004_0000) >> 16
- | (pixels & 0x0008_0000) >> 13
- | (pixels & 0x0400_0000) >> 23
- | (pixels & 0x0800_0000) >> 20)
- assert not (rom_pixels_low & ~0xFF)
- assert not (rom_pixels_high & ~0xFF)
- pos_low = (times%4)*16 + times//4
- offset = 64
- packed_tile[pos_low] = rom_pixels_low
- packed_tile[offset + pos_low] = rom_pixels_high
- data_big = i.read(4)
- times += 1
- if times == 64:
- times = 0
- ol.write(packed_tile[:64])
- oh.write(packed_tile[64:])
- assert times < 64
- class MappedFiles:
- def __init__(self, filenames, sizes, mode):
- assert len(filenames) == len(sizes)
- self.filenames = filenames
- self.sizes = sizes
- self.mode = mode
- self.files = []
- # XXX Start is unused
- self.starts = []
- self.ends = []
- end = 0
- for s in self.sizes:
- self.starts.append(end)
- end += s
- self.ends.append(end)
- self.end = end
- self.pos = 0
- def __enter__(self):
- for fn in self.filenames:
- self.files.append(open(fn, self.mode))
- return self
- def __exit__(self, type, value, traceback):
- for f in self.files:
- # TODO If a exception is raised it should continue closing
- # the files anyway
- f.close()
- def write(self, data):
- while data:
- assert self.pos < self.end
- file_index = next(i for i, v in enumerate(self.ends)
- if v > self.pos)
- max_write_length = self.ends[file_index] - self.pos
- write_length = min(len(data), max_write_length)
- self.files[file_index].write(data[:write_length])
- self.pos += write_length
- data = data[write_length:]
- class MappedFilesPathLike:
- def __init__(self, filenames, sizes):
- self.filenames = filenames
- self.sizes = sizes
- self.mf = None
- def open(self, mode):
- if self.mf is None:
- self.mf = MappedFiles(self.filenames, self.sizes, mode)
- return self.mf
- def ddragon(outdir):
- ddragon = outdir / 'ddragon'
- ddragon.mkdir(exist_ok=True)
- with open('ddragon_hd6309.bin', 'rb') as i:
- maincpu_parts = [
- (ddragon / '21j-1-5.26', 0x8000),
- (ddragon / '21j-2-3.25', 0x8000),
- (ddragon / '21j-3.24', 0x8000),
- (ddragon / '21j-4-1.23', 0x8000)
- ]
- split(i, maincpu_parts)
- sub_source = Path('ddragon_hd63701.bin')
- sub = Path(ddragon / '21jm-0.ic55')
- shutil.copyfile(sub_source, sub)
- soundcpu_source = Path('ddragon_m6809.bin')
- soundcpu = Path(ddragon / '21j-0-1')
- shutil.copyfile(soundcpu_source, soundcpu)
- with open('ddragon_gfxdata1.bin', 'rb') as i:
- pixel_de4_to_dd4_tile8(i, ddragon / '21j-5')
- with open('ddragon_gfxdata2.bin', 'rb') as i:
- size = 0x01_0000
- low0 = ddragon / '21j-a'
- low1 = ddragon / '21j-b'
- low2 = ddragon / '21j-c'
- low3 = ddragon / '21j-d'
- high0 = ddragon / '21j-e'
- high1 = ddragon / '21j-f'
- high2 = ddragon / '21j-g'
- high3 = ddragon / '21j-h'
- low = MappedFilesPathLike([low0, low1, low2, low3],
- [size]*4)
- high = MappedFilesPathLike([high0, high1, high2, high3],
- [size]*4)
- pixel_de4_to_dd4_tile16(i, low, high)
- with open('ddragon_gfxdata3.bin', 'rb') as i:
- size = 0x01_0000
- low0 = ddragon / '21j-8'
- low1 = ddragon / '21j-9'
- high0 = ddragon / '21j-i'
- high1 = ddragon / '21j-j'
- low = MappedFilesPathLike([low0, low1],
- [size]*2)
- high = MappedFilesPathLike([high0, high1],
- [size]*2)
- pixel_de4_to_dd4_tile16(i, low, high)
- with open('ddragon_adpcm.bin', 'rb') as i:
- adpcm_parts = [
- (ddragon / '21j-6', 0x01_0000),
- (ddragon / '21j-7', 0x01_0000)
- ]
- split(i, adpcm_parts)
- with open('proms.bin', 'rb') as i:
- proms_parts = [
- (ddragon / '21j-k-0', 0x0100),
- (ddragon / '21j-l-0', 0x0200)
- ]
- split(i, proms_parts)
- def ddragon2(outdir):
- ddragon2 = outdir / 'ddragon2'
- ddragon2.mkdir(exist_ok=True)
- with open('ddragon2_hd6309.bin', 'rb') as i:
- maincpu_parts = [
- (ddragon2 / '26a9-04.bin', 0x8000),
- (ddragon2 / '26aa-03.bin', 0x8000),
- (ddragon2 / '26ab-0.bin', 0x8000),
- (ddragon2 / '26ac-0e.63', 0x8000)
- ]
- split(i, maincpu_parts)
- sub_source = Path('ddragon2_z80sub.bin')
- sub = Path(ddragon2 / '26ae-0.bin')
- shutil.copyfile(sub_source, sub)
- soundcpu_source = Path('ddragon2_z80sound.bin')
- soundcpu = Path(ddragon2 / '26ad-0.bin')
- shutil.copyfile(soundcpu_source, soundcpu)
- with open('ddragon2_gfxdata1.bin', 'rb') as i:
- pixel_de4_to_dd4_tile8(i, ddragon2 / '26a8-0e.19')
- with open('ddragon2_gfxdata2.bin', 'rb') as i:
- low0 = ddragon2 / '26j0-0.bin'
- low1 = ddragon2 / '26j1-0.bin'
- low2 = ddragon2 / '26af-0.bin'
- high0 = ddragon2 / '26j2-0.bin'
- high1 = ddragon2 / '26j3-0.bin'
- high2 = ddragon2 / '26a10-0.bin'
- low = MappedFilesPathLike([low0, low1, low2],
- [0x02_0000, 0x02_0000, 0x02_0000])
- high = MappedFilesPathLike([high0, high1, high2],
- [0x02_0000, 0x02_0000, 0x02_0000])
- pixel_de4_to_dd4_tile16(i, low, high)
- with open('ddragon2_gfxdata3.bin', 'rb') as i:
- low = Path(ddragon2 / '26j4-0.bin')
- high = Path(ddragon2 / '26j5-0.bin')
- pixel_de4_to_dd4_tile16(i, low, high)
- with open('ddragon2_oki.bin', 'rb') as i:
- proms_parts = [
- (ddragon2 / '26j6-0.bin', 0x02_0000),
- (ddragon2 / '26j7-0.bin', 0x02_0000)
- ]
- split(i, proms_parts)
- with open('proms.bin', 'rb') as i:
- proms_parts = [
- ('unk_prom', 0x0100),
- (ddragon2 / 'prom.16', 0x0200)
- ]
- split(i, proms_parts)
- def dragon_convert():
- outdir = Path('mame')
- outdir.mkdir(exist_ok=True)
- ddragon(outdir)
- ddragon2(outdir)
- if __name__ == '__main__':
- dragon_convert()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement