Source code for mrcrowbar.lib.games.jill

"""File format classes for the games Jill of the Jungle (DOS, 1992) and 
Xargon (DOS, 1994)."""

import itertools

from mrcrowbar import models as mrc
from mrcrowbar.lib.hardware import ibm_pc
from mrcrowbar.lib.images import base as img
from mrcrowbar.lib.audio import base as aud
from mrcrowbar import utils


# source: Xargon source code release - https://www.classicdosgames.com/game/Xargon.html

PC_SPEAKER_NOTE_TABLE = [
    64   ,67   ,71   ,76   ,80   ,85   ,90   ,95   ,101  ,107  ,114  ,121   ,0    ,0    ,0    ,0,
    128  ,135  ,143  ,152  ,161  ,170  ,181  ,191  ,203  ,215  ,228  ,242   ,0    ,0    ,0    ,0,
    256  ,271  ,287  ,304  ,322  ,341  ,362  ,383  ,406  ,430  ,456  ,483   ,0    ,0    ,0    ,0,
    512  ,542  ,574  ,608  ,645  ,683  ,724  ,767  ,812  ,861  ,912  ,967   ,0    ,0    ,0    ,0,
    1024 ,1084 ,1149 ,1217 ,1290 ,1366 ,1448 ,1534 ,1625 ,1722 ,1825 ,1933  ,0    ,0    ,0    ,0,
    2048 ,2169 ,2298 ,2435 ,2580 ,2733 ,2896 ,3068 ,3250 ,3444 ,3649 ,3866  ,0    ,0    ,0    ,0,
    4096 ,4339 ,4597 ,4870 ,5160 ,5467 ,5792 ,6137 ,6501 ,6888 ,7298 ,7732  ,0    ,0    ,0    ,0,
    8192 ,8679 ,9195 ,9741 ,10321,10935,11585,12274,13003,13777,14596,15646 ,0    ,0    ,0    ,0,
    16384,17358,18390,19483,20642,21870,23170,24548,26007,27554,29192,30928 ,0    ,0    ,0    ,0
]


[docs] class Sound( mrc.Block ): SAMPLE_RATE = 6000 raw_data = mrc.Bytes( 0x00 ) def __init__( self, *args, **kwargs ): super().__init__( *args, **kwargs ) self.wave = aud.Wave( self, mrc.Ref( 'raw_data' ), channels=1, sample_rate=SAMPLE_RATE, format_type=int, field_size=1, signedness='unsigned', endian=None )
[docs] class Text( mrc.Block ): data = mrc.Bytes( 0x00 )
[docs] class VCLFile( mrc.Block ): sound_offsets = mrc.UInt32_LE( 0x00, count=50 ) sound_sizes = mrc.UInt16_LE( 0xc8, count=50 ) sound_freqs = mrc.UInt16_LE( 0x12c, count=50 ) text_offsets = mrc.UInt32_LE( 0x190, count=40 ) text_lengths = mrc.UInt16_LE( 0x230, count=40 ) raw_data = mrc.Bytes( 0x280 ) def __init__( self, *args, **kwargs ): super().__init__( *args, **kwargs ) self.sounds = mrc.LinearStore( self, mrc.Ref( 'raw_data' ), Sound, offsets=mrc.Ref( 'sound_offsets' ), sizes=mrc.Ref( 'sound_sizes' ), base_offset=-0x280 )
# source: http://www.shikadi.net/moddingwiki/SHA_Format
[docs] class Tileset( mrc.Block ): num_shapes = mrc.UInt8( 0x00 ) num_rots = mrc.UInt16_LE( 0x01 ) len_cga = mrc.UInt16_LE( 0x03 ) len_ega = mrc.UInt16_LE( 0x05 ) len_vga = mrc.UInt16_LE( 0x07 ) colour_depth = mrc.UInt8( 0x09 ) flags = mrc.UInt16_LE( 0x0a )
[docs] class SHAFile( mrc.Block ): tileset_offsets = mrc.UInt32_LE( 0x0000, count=128 ) tileset_sizes = mrc.UInt16_LE( 0x0200, count=128 ) tileset_data = mrc.Bytes( 0x0300 ) tilesets = mrc.StoreRef( Tileset, mrc.Ref( 'store' ), mrc.Ref( 'tileset_offsets' ), mrc.Ref( 'tileset_sizes' ), count=128 ) def __init__( self, *args, **kwargs ): self.store = mrc.Store( self, mrc.Ref( 'tileset_data' ) ) super().__init__( *args, **kwargs )
[docs] class JillLoader( mrc.Loader ): """Loader for the game Jill of the Jungle (DOS, 1992).""" _SEP = mrc.Loader._SEP _JILL_FILE_CLASS_MAP = { _SEP+'JN([1-3])(SAVE)\.([0-9])$': None, _SEP+'(JILL)([1-3])\.(VCL)$': VCLFile, _SEP+'(JILL)([1-3])\.(SHA)$': SHAFile, _SEP+'(JILL)\.(DMA)$': None, _SEP+'(.*)\.(DDT)$': None, _SEP+'(.*)\.JN([1-3])$': None } def __init__( self ): super().__init__( self._JILL_FILE_CLASS_MAP )
[docs] class XargonLoader( mrc.Loader ): """Loader for the game Xargon (DOS, 1994).""" _SEP = mrc.Loader._SEP _XARGON_FILE_CLASS_MAP = { _SEP+'(AUDIO).XR([1-3])$': VCLFile, _SEP+'(BOARD)_([0-9A-Z]+).XR([1-3])$': None, _SEP+'(DEMO)([1-3]).XR([1-3])$': None, _SEP+'(GRAPHICS).XR([1-3])$': SHAFile, _SEP+'(INTRO).XR([1-3])$': None, _SEP+'(MAP).XR([1-3])$': None, _SEP+'(SONG)_([0-9]+).XR([1-3])$': None, _SEP+'(STORY).XR([1-3])$': None, _SEP+'(TILES).XR([1-3])$': None, } def __init__( self ): super().__init__( self._XARGON_FILE_CLASS_MAP )