Exemple #1
0
class RGBColour(Colour):
    r_raw = mrc.UInt8(0x00)
    g_raw = mrc.UInt8(0x01)
    b_raw = mrc.UInt8(0x02)

    @property
    def r(self):
        return self.r_raw / 255

    @r.setter
    def r(self, value):
        self.r_raw = round(value * 255)

    @property
    def g(self):
        return self.g_raw / 255

    @g.setter
    def g(self, value):
        self.g_raw = round(value * 255)

    @property
    def b(self):
        return self.b_raw / 255

    @b.setter
    def b(self, value):
        self.b_raw = round(value * 255)
Exemple #2
0
class VGM150(mrc.Block):
    magic = mrc.Const(mrc.Bytes(0x00, length=0x04, default=b'Vgm '), b'Vgm ')
    eof_offset = mrc.UInt32_LE(0x04)
    version = mrc.UInt32_LE(0x08)
    sn76489_clock = mrc.UInt32_LE(0x0c)
    ym2413_clock = mrc.UInt32_LE(0x10)
    gd3_offset = mrc.UInt32_LE(0x14)
    total_sample_count = mrc.UInt32_LE(0x18)
    loop_offset = mrc.UInt32_LE(0x1c)
    loop_sample_count = mrc.UInt32_LE(0x20)
    rate = mrc.UInt32_LE(0x24)
    sn76489_feedback = mrc.UInt16_LE(0x28)
    sn76489_shiftwidth = mrc.UInt8(0x2a)
    sn76489_flags = mrc.UInt8(0x2b)
    ym2612_clock = mrc.UInt32_LE(0x2c)
    ym2151_clock = mrc.UInt32_LE(0x30)
    vgm_data_offset_raw = mrc.UInt32_LE(0x34)
    header_extra = mrc.Bytes(0x38, length=0x08, default=b'\x00' * 8)

    @property
    def vgm_data_offset(self):
        if self.version >= 0x150:
            return self.vgm_data_offset_raw + 0x34
        return 0x40

    vgm_data = mrc.ChunkField(COMMAND_MAP,
                              mrc.Ref('vgm_data_offset'),
                              id_field=mrc.UInt8,
                              id_enum=Command,
                              default_klass=mrc.Unknown,
                              stream_end=b'\x66')
    extra = mrc.Bytes(mrc.EndOffset('vgm_data'), default=b'')
Exemple #3
0
class RegisterWrite8(mrc.Block):
    register = mrc.UInt8(0x00)
    value = mrc.UInt8(0x00)

    @property
    def repr(self):
        return f'register=0x{self.register:02x}, value=0x{self.value:02x}'
Exemple #4
0
class TerrainInfo(mrc.Block):

    width = mrc.UInt8(0x0000)
    height = mrc.UInt8(0x0001)
    base_offset = mrc.UInt16_LE(0x0002)
    mask_rel_offset = mrc.UInt16_LE(0x0004)
    unknown_1 = mrc.UInt16_LE(0x0006)

    vgagr = mrc.StoreRef(TerrainImage,
                         mrc.Ref('_parent._vgagr.terrain_store.store'),
                         mrc.Ref('base_offset'), mrc.Ref('size'))

    @property
    def size(self):
        return self.width * self.height * 5 // 8

    @property
    def mask_offset(self):
        return self.mask_rel_offset - self.base_offset
        #return self.width*self.height*4//8

    @property
    def mask_stride(self):
        return self.width * self.height * 4 // 8

    @property
    def mask_size(self):
        return self.width * self.height // 8
Exemple #5
0
class VGAColour( img.Colour ):
    r_raw =         mrc.UInt8( 0x00, range=range( 0, 64 ) )
    g_raw =         mrc.UInt8( 0x01, range=range( 0, 64 ) )
    b_raw =         mrc.UInt8( 0x02, range=range( 0, 64 ) )

    @property
    def r( self ):
        return self.r_raw / 63

    @r.setter
    def r( self, value ):
        self.r_raw = round( value * 63 )

    @property
    def g( self ):
        return self.g_raw / 63

    @g.setter
    def g( self, value ):
        self.g_raw = round( value * 63 )

    @property
    def b( self ):
        return self.b_raw / 63

    @b.setter
    def b( self, value ):
        self.b_raw = round( value * 63 )
Exemple #6
0
class PRSFile(mrc.Block):
    magic = mrc.Const(mrc.Bytes(0x00, length=0x18),
                      b'PRS Format Resource File')
    unk1 = mrc.UInt8(0x18)
    unk2 = mrc.UInt8(0x19)
    unk3 = mrc.UInt8(0x1f)
    chunks = mrc.BlockField(PRSChunk, 0x30, stream=True)
Exemple #7
0
class VGAColour(img.Colour):
    r_raw = mrc.UInt8(0x00, range=range(0, 64))
    g_raw = mrc.UInt8(0x01, range=range(0, 64))
    b_raw = mrc.UInt8(0x02, range=range(0, 64))

    @property
    def r_8(self):
        return self.r_raw * 255 // 63

    @r_8.setter
    def r_8(self, value):
        self.r_raw = value * 63 // 255

    @property
    def g_8(self):
        return self.g_raw * 255 // 63

    @g_8.setter
    def g_8(self, value):
        self.g_raw = value * 63 // 255

    @property
    def b_8(self):
        return self.b_raw * 255 // 63

    @b_8.setter
    def b_8(self, value):
        self.b_raw = value * 63 // 255
Exemple #8
0
class MacBinary(mrc.Block):
    version_old = mrc.Const(mrc.UInt8(0x00), 0)
    name_size = mrc.UInt8(0x01, range=range(1, 64))
    name = mrc.Bytes(0x02, length=mrc.Ref('name_size'))
    type = mrc.Bytes(0x41, length=4)
    creator = mrc.Bytes(0x45, length=4)
    locked = mrc.Bits(0x49, 0b10000000)
    invisible = mrc.Bits(0x49, 0b01000000)
    bundle = mrc.Bits(0x49, 0b00100000)
    system = mrc.Bits(0x49, 0b00010000)
    bozo = mrc.Bits(0x49, 0b00001000)
    busy = mrc.Bits(0x49, 0b00000100)
    changed = mrc.Bits(0x49, 0b00000010)
    inited = mrc.Bits(0x49, 0b00000001)
    const1 = mrc.Const(mrc.UInt8(0x4a), 0)
    pos_y = mrc.UInt16_BE(0x4b)
    pos_x = mrc.UInt16_BE(0x4d)
    folder_id = mrc.UInt16_BE(0x4f)
    protected = mrc.Bits(0x51, 0b00000001)
    const2 = mrc.Const(mrc.UInt8(0x52), 0)
    data_size = mrc.UInt32_BE(0x53)
    resource_size = mrc.UInt32_BE(0x57)
    created = mrc.UInt32_BE(0x5a)
    modified = mrc.UInt32_BE(0x5e)

    data = mrc.Bytes(0x80, length=mrc.Ref('data_size'))
    resource = mrc.Bytes(mrc.EndOffset('data', align=0x80),
                         length=mrc.Ref('resource_size'))
Exemple #9
0
class SpeakAndSpellROM( mrc.Block ):
    count_a = mrc.UInt8( 0x00 )
    count_b = mrc.UInt8( 0x01 )
    count_c = mrc.UInt8( 0x02 )
    count_d = mrc.UInt8( 0x03 )
    offset_a = mrc.Pointer( mrc.UInt16_LE( 0x04 ), mrc.EndOffset( 'common' ) )
    offset_b = mrc.Pointer( mrc.UInt16_LE( 0x06 ), mrc.EndOffset( 'list_a' ) )
    offset_c = mrc.Pointer( mrc.UInt16_LE( 0x08 ), mrc.EndOffset( 'list_b' ) )
    offset_d = mrc.Pointer( mrc.UInt16_LE( 0x0a ), mrc.EndOffset( 'list_c' ) )
    
    @property
    def common_len( self ):
        return (self.offset_a - 0x0c) // 2

    @common_len.setter
    def common_len( self, value ):
        self.offset_a = value * 2 + 0x0c 

    common = mrc.UInt16_LE( 0x0c, count=mrc.Ref( 'common_len' ) ) 
    list_a = mrc.UInt16_LE( mrc.Ref( 'offset_a' ), count=mrc.Ref( 'count_a' ) ) 
    list_b = mrc.UInt16_LE( mrc.Ref( 'offset_b' ), count=mrc.Ref( 'count_b' ) ) 
    list_c = mrc.UInt16_LE( mrc.Ref( 'offset_c' ), count=mrc.Ref( 'count_c' ) ) 
    list_d = mrc.UInt16_LE( mrc.Ref( 'offset_d' ), count=mrc.Ref( 'count_d' ) ) 

    raw_data = mrc.Bytes( mrc.EndOffset( 'list_d' ) )
Exemple #10
0
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)
Exemple #11
0
class RelocationInternalRef(mrc.Block):
    index = mrc.UInt8(0x00)
    check = mrc.Const(mrc.UInt8(0x01), 0)
    offset = mrc.UInt16_LE(0x02)

    @property
    def repr(self):
        return 'index=0x{:02x}, offset=0x{:04x}'.format(
            self.index, self.offset)
Exemple #12
0
class ShapeCastV4(mrc.Block):
    type = mrc.UInt16_BE(0x00, enum=ShapeType)
    rect = mrc.BlockField(Rect, 0x02)
    pattern = mrc.UInt16_BE(0x0a)
    fg_colour = mrc.UInt8(0x0c)
    bg_colour = mrc.UInt8(0x0d)
    fill_type = mrc.UInt8(0x0e)
    line_thickness = mrc.UInt8(0x0f)
    line_direction = mrc.UInt8(0x10)
Exemple #13
0
class Sprite(mrc.Block):
    script_id = mrc.UInt8(0x00)
    sprite_type = mrc.UInt8(0x01)
    x2 = mrc.UInt16_BE(0x02)
    flags = mrc.UInt16_BE(0x04)
    cast_id = mrc.UInt16_BE(0x06)
    start_x = mrc.UInt16_BE(0x08)
    start_y = mrc.UInt16_BE(0x0a)
    height = mrc.UInt16_BE(0x0c)
    width = mrc.UInt16_BE(0x0e)
Exemple #14
0
class VOCSoundData12(mrc.Block):
    sample_rate = mrc.UInt32_LE(0x00)
    sample_bits = mrc.UInt8(0x04)
    channels_raw = mrc.UInt8(0x05)
    codec = mrc.UInt16_LE(0x06)
    reserved = mrc.Const(mrc.UInt32_LE(0x08), 0)
    data = mrc.Bytes(0x0c)

    @property
    def channels(self):
        return self.channels_raw + 1
Exemple #15
0
class VOCExtra(mrc.Block):
    freq_divisor = mrc.UInt16_LE(0x00)
    codec = mrc.UInt8(0x02, enum=VOCCodec)
    channels_raw = mrc.UInt8(0x03)

    @property
    def channels(self):
        return self.channels_raw + 1

    @property
    def sample_rate(self):
        return 256000000 // ((self.channels) * (65536 - self.freq_divisor))
Exemple #16
0
class RGBAColour(RGBColour):
    r_raw = mrc.UInt8(0x00)
    g_raw = mrc.UInt8(0x01)
    b_raw = mrc.UInt8(0x02)
    a_raw = mrc.UInt8(0x03)

    @property
    def a(self):
        return self.a_raw / 255

    @a.setter
    def a(self, value):
        self.a_raw = round(value * 255)
Exemple #17
0
class SpriteChannelV4(mrc.Block):
    script_id = mrc.UInt8(0x00)
    type = mrc.UInt8(0x01, enum=SpriteType)
    fg_colour = mrc.UInt8(0x02)
    bg_colour = mrc.UInt8(0x03)
    line_size = mrc.Bits(0x04, 0b00000011)
    unk4 = mrc.Bits(0x04, 0b11111100)
    ink = mrc.Bits(0x05, 0b00111111)
    trails = mrc.Bits(0x05, 0b01000000)
    unk5 = mrc.Bits(0x05, 0b10000000)
    cast_id = mrc.UInt16_BE(0x06)
    y_pos = mrc.UInt16_BE(0x08)
    x_pos = mrc.UInt16_BE(0x0a)
    height = mrc.UInt16_BE(0x0c)
    width = mrc.UInt16_BE(0x0e)
Exemple #18
0
class Terrain(mrc.Block):
    """Represents a single terrain piece placed in a level."""

    #: Raw value for the x position of the left edge.
    x_raw = mrc.UInt16_BE(0x00, bitmask=b'\x0f\xff')
    #: If 1, blit image behind background.
    draw_back = mrc.Bits(0x00, 0b10000000)
    #: If 1, draw piece flipped vertically.
    draw_upsidedown = mrc.Bits(0x00, 0b01000000)
    #: If 1, draw piece as a hole.
    draw_erase = mrc.Bits(0x00, 0b00100000)
    #: Raw value (coarse component) for the y position of the top edge.
    y_raw_coarse = mrc.Int8(0x02)
    #: Raw value (fine component) for the y position of the top edge.
    y_raw_fine = mrc.Bits(0x03, 0b10000000)

    unknown_1 = mrc.Bits(0x03, 0b01000000)

    #: Index of the TerrainInfo block in the accompanying GroundDAT.
    obj_id = mrc.UInt8(0x03, bitmask=b'\x3f', range=range(0, 64))

    @property
    def x(self):
        """The x position of the left edge."""
        return (self.x_raw - 16)

    @property
    def y(self):
        """The y position of the top edge."""
        return (self.y_raw_coarse * 2 + self.y_raw_fine) - 4

    @property
    def repr(self):
        return "obj_id={}, x={}, y={}".format(self.obj_id, self.x, self.y)
Exemple #19
0
class Resource(mrc.Block):
    offset = mrc.UInt16_LE(0x00)
    size = mrc.UInt16_LE(0x02)
    preload = mrc.Bits(0x04, 0b01000000)
    sharable = mrc.Bits(0x04, 0b00100000)
    movable = mrc.Bits(0x04, 0b00010000)
    in_memory = mrc.Bits(0x04, 0b00000100)
    unk1 = mrc.Bits(0x04, 0b10001111)
    discardable = mrc.Bits(0x05, 0b00010000)
    unk2 = mrc.Bits(0x05, 0b11101111)
    resource_id_low = mrc.UInt8(0x06)
    int_id = mrc.Bits(0x07, 0b10000000)
    resource_id_high = mrc.Bits(0x07, 0b01111111)
    reserved = mrc.Bytes(0x08, length=0x04)

    @property
    def resource_id(self):
        return (self.resource_id_high << 8) + self.resource_id_low

    @resource_id.setter
    def resource_id(self, value):
        self.resouce_id_high = (value >> 8) & 0b01111111
        self.resource_id_low = value & 0b11111111

    @property
    def repr(self):
        return 'offset=0x{:04x}, size=0x{:04x}, resource_id=0x{:04x}, int_id={}'.format(
            self.offset, self.size, self.resource_id, self.int_id)
Exemple #20
0
class EntryBundle(mrc.Block):
    # awful hack for validating blockfield
    INDICATOR_MAP = {k: FixedSegmentIndicator for k in range(1, 255)}
    INDICATOR_MAP[0] = EmptySegmentIndicator
    INDICATOR_MAP[255] = MovableSegmentIndicator

    count = mrc.UInt8(0x00)
    indicator = mrc.UInt8(0x01)
    indicators = mrc.BlockField(INDICATOR_MAP,
                                0x02,
                                count=mrc.Ref('count'),
                                block_type=mrc.Ref('indicator'))

    @property
    def repr(self):
        return 'count={}, indicator={}'.format(self.count, self.indicator)
Exemple #21
0
class ImportedName(mrc.Block):
    size = mrc.UInt8(0x00)
    name = mrc.Bytes(0x01, length=mrc.Ref('size'))

    @property
    def repr(self):
        return 'name={}'.format(self.name)
Exemple #22
0
class B800Char(mrc.Block):
    _palette = ibm_pc.EGA_DEFAULT_PALETTE

    code_point = mrc.UInt8(0x00)
    fg_blink = mrc.Bits(0x01, 0b10000000)
    bg_colour = mrc.Bits(0x01, 0b01110000)
    fg_colour = mrc.Bits(0x01, 0b00001111)

    @property
    def char(self):
        return CP437[self.code_point]

    def ansi_format(self):
        return ansi.format_string(self.char,
                                  self._palette[self.fg_colour],
                                  self._palette[self.bg_colour],
                                  blink=self.fg_blink)

    def __str__(self):
        return self.ansi_format()

    def __repr__(self):
        return '<{}: char {}, bg {}, fg {}>'.format(self.__class__.__name__,
                                                    self.char, self.bg_colour,
                                                    self.fg_colour)
Exemple #23
0
class SoundCastV4Extra(mrc.Block):
    name_size = mrc.UInt8(0x00)
    name = mrc.CString(0x01, length=mrc.Ref('name_size'))

    @property
    def repr(self):
        return 'name={}'.format(self.name)
Exemple #24
0
class SongPositionChannel(mrc.Block):
    pattern_num_raw = mrc.UInt16_LE(0x00)
    transpose = mrc.UInt8(0x02)

    @property
    def pattern_num(self):
        return self.pattern_num_raw // 2
Exemple #25
0
class NEBase(mrc.Block):
    ne_magic = mrc.Const(mrc.Bytes(0x00, length=2), b'NE')

    entry_offset = mrc.UInt16_LE(0x04)

    flags = mrc.UInt16_LE(0x0c)

    heap_size = mrc.UInt16_LE(0x10)
    stack_size = mrc.UInt16_LE(0x12)
    ip_offset = mrc.UInt16_LE(0x14)
    cs_id = mrc.UInt16_LE(0x16)
    sp_offset = mrc.UInt16_LE(0x18)
    ss_id = mrc.UInt16_LE(0x1a)
    segtable_count = mrc.UInt16_LE(0x1c)
    modref_count = mrc.UInt16_LE(0x1e)
    nonresnames_size = mrc.UInt16_LE(0x20)
    segtable_offset = mrc.UInt16_LE(0x22)
    restable_offset = mrc.UInt16_LE(0x24)
    resnames_offset = mrc.UInt16_LE(0x26)
    modref_offset = mrc.UInt16_LE(0x28)
    impnames_offset = mrc.UInt16_LE(0x2a)
    nonresnames_rel_offset = mrc.UInt32_LE(0x2c)
    movable_count = mrc.UInt16_LE(0x30)
    sector_shift = mrc.UInt16_LE(0x32)

    exe_type = mrc.UInt8(0x36)
    unk1 = mrc.Bytes(0x37, length=9)

    @property
    def impnames_size(self):
        return self.entry_offset - self.impnames_offset
Exemple #26
0
class SAMTileset8( mrc.Block ):
    count = mrc.UInt8( 0x00 )
    width_raw = mrc.UInt8( 0x01 )
    height = mrc.UInt8( 0x02 )
    mask_data = mrc.Bytes( 0x03, 
                        length=0x7fd, 
                        transform=img.Planarizer(
                            bpp=5, 
                            plane_size=mrc.Ref( 'plane_size' ),
                            row_planar_size=1,
                            plane_order=(0,)
                        ) )
    image_data = mrc.Bytes( 0x03, 
                        length=0x7fd, 
                        transform=img.Planarizer(
                            bpp=5, 
                            plane_size=mrc.Ref( 'plane_size' ),
                            row_planar_size=1,
                            plane_order=(1,2,3,4)
                        ) )

    def __init__( self, *args, **kwargs ):
        super().__init__( *args, **kwargs )
        self.image = img.IndexedImage( 
                        self,
                        width=mrc.Ref( 'width' ),
                        height=mrc.Ref( 'height' ),
                        source=mrc.Ref( 'image_data' ),
                        frame_count=mrc.Ref( 'count' ),
                        palette=ibm_pc.EGA_DEFAULT_PALETTE
                    )
        self.mask = img.IndexedImage( 
                        self,
                        width=mrc.Ref( 'width' ),
                        height=mrc.Ref( 'height' ),
                        source=mrc.Ref( 'mask_data' ),
                        frame_count=mrc.Ref( 'count' ),
                        palette=ibm_pc.EGA_DEFAULT_PALETTE
                    )

    @property
    def plane_size( self ):
        return self.count*self.width_raw*self.height
    
    @property
    def width( self ):
        return self.width_raw*8
Exemple #27
0
        class Test(mrc.Block):
            count = mrc.UInt8(0x00)
            elements = mrc.BlockField(ElementRef, count=mrc.Ref('count'))
            raw_data = mrc.Bytes(mrc.EndOffset('elements'))

            def __init__(self, *args, **kwargs):
                self.store = mrc.Store(self, mrc.Ref('raw_data'))
                super().__init__(*args, **kwargs)
Exemple #28
0
class ResidentName(mrc.Block):
    size = mrc.UInt8(0x00)
    name = mrc.Bytes(0x01, length=mrc.Ref('size'))
    index = mrc.UInt16_LE(mrc.EndOffset('name'))

    @property
    def repr(self):
        return 'index=0x{:02x}, name={}'.format(self.index, self.name)
class Accelerator( mrc.Block ):
    RANGE = 0xC8

    axis_raw = mrc.UInt8( 0x06 )

    @property
    def axis( self ):
        return min( max( (255*(self.axis_raw)//self.RANGE), 0 ), 255 )
Exemple #30
0
class ResidentNameTable(mrc.Block):
    module_name_size = mrc.UInt8(0x00)
    module_name = mrc.Bytes(0x01, length=mrc.Ref('module_name_size'))
    padding = mrc.UInt16_LE(mrc.EndOffset('module_name'))
    resnames = mrc.BlockField(ResidentName,
                              mrc.EndOffset('padding'),
                              stream=True,
                              stream_end=b'\x00')