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'))
class ScriptCastV4(mrc.Block): unk1 = mrc.Bytes(0x00, length=0x14) script_id = mrc.UInt16_BE(0x14) unk4_size = mrc.UInt16_BE(0x16) unk3 = mrc.UInt32_BE(0x18) unk4 = mrc.UInt32_BE(0x1c, count=mrc.Ref('unk4_size')) @property def repr(self): return 'script_id={}'.format(self.script_id)
class ScriptContextV4(mrc.Block): #test = mrc.Bytes() unk1 = mrc.Bytes(0x00, length=0x8) list_count = mrc.UInt32_BE(0x08) list_count_2 = mrc.UInt32_BE(0x0c) list_offset = mrc.UInt16_BE(0x10) unk2 = mrc.UInt16_BE(0x12) unk3 = mrc.Bytes(0x14, length=22) entries = mrc.BlockField(ScriptContextEntry, mrc.Ref('list_offset'), count=mrc.Ref('list_count'))
class ResourceFork(mrc.Block): """ """ resourceDataOffset = mrc.UInt32_BE(0x00) resourceMapOffset = mrc.UInt32_BE(0x04) resourceDataSize = mrc.UInt32_BE(0x08) resourceMapSize = mrc.UInt32_BE(0x0c) resourceData = mrc.BlockField(ResourceData, offset=mrc.Ref("resourceDataOffset"), length=mrc.Ref("resourceDataSize")) resourceMap = mrc.BlockField(MapData, offset=mrc.Ref("resourceMapOffset"), length=mrc.Ref("resourceMapSize"))
class ScriptCastV4(mrc.Block): unk1 = mrc.Bytes(0x00, length=0x14) script_id = mrc.UInt16_BE(0x14) var_count = mrc.UInt16_BE(0x16) unk2 = mrc.UInt32_BE(0x18) vars = mrc.UInt32_BE(0x1c, count=mrc.Ref('var_count')) code = mrc.Bytes(mrc.EndOffset('vars'), length=mrc.Ref('code_len')) unk3 = mrc.Bytes(mrc.EndOffset('code')) @property def code_len(self): return self.vars[0] if self.vars else 0 @property def repr(self): return 'script_id={}'.format(self.script_id)
class ScriptString(mrc.Block): length = mrc.UInt32_BE(0x00) value = mrc.CString(0x04, length=mrc.Ref('length'), encoding='latin1') @property def repr(self): return self.value
class ScriptString(mrc.Block): length = mrc.UInt32_BE(0x00) value = mrc.CStringN(0x04, length=mrc.Ref('length')) @property def repr(self): return self.value.decode('utf-8')
class ScriptFloat(mrc.Block): length = mrc.Const(mrc.UInt32_BE(0x00), 0x0a) sign = mrc.Bits16(0x04, bits=0x8000) exponent = mrc.Bits16(0x04, bits=0x7fff) integer = mrc.Bits64(0x06, bits=0x8000000000000000) fraction = mrc.Bits64(0x06, bits=0x7fffffffffffffff) @property def value(self): if (self.exponent == 0): f64exp = 0 elif (self.exponent == 0x7fff): f64exp = 0x7ff else: normexp = self.exponent - 0x3fff # value range from -0x3ffe to 0x3fff if not (-0x3fe <= normexp < 0x3ff): raise ValueError('Exponent too big for a float64') f64exp = normexp + 0x3ff f64fract = self.fraction >> 11 f64bin = utils.to_uint64_be(f64fract + (f64exp << 52) + 0x80000000 * self.sign) f64 = utils.from_float64_be(f64bin) return f64 @property def repr(self): return self.value
class ScriptFloat(mrc.Block): length = mrc.UInt32_BE(0x00), data = mrc.Bytes(0x04, length=mrc.Ref('length')) @property def repr(self): return self.data.hex()
class ResourceData(mrc.Block): """ Read the Resource Data. Currently only reads the first element, instead of them all. """ length = mrc.UInt32_BE(0x00) data = mrc.Bytes(offset=0x04, length=mrc.Ref("length"))
class FramesV4(mrc.Block): size = mrc.UInt32_BE(0x00) unk1 = mrc.UInt32_BE(0x04) unk2 = mrc.UInt32_BE(0x08) unk3 = mrc.UInt16_BE(0x0c) unk4 = mrc.UInt16_BE(0x0e) unk5 = mrc.UInt16_BE(0x10) unk6 = mrc.UInt16_BE(0x12) frames = mrc.BlockField(FrameV4, 0x14, stream=True, length=mrc.Ref('size_frames')) @property def size_frames(self): return self.size - 0x14
class TestB(mrc.Block): i16 = mrc.Int16_BE() i32 = mrc.Int32_BE() i64 = mrc.Int64_BE() ui16 = mrc.UInt16_BE() ui32 = mrc.UInt32_BE() ui64 = mrc.UInt64_BE() f32 = mrc.Float32_BE() f64 = mrc.Float64_BE()
class ScriptConstantFloat(mrc.Block): offset = mrc.UInt32_BE(0x00) value = mrc.StoreRef(ScriptFloat, mrc.Ref('_parent._parent.consts_store'), offset=mrc.Ref('offset'), size=None) @property def repr(self): return self.value.repr
class ScriptFunction(mrc.Block): name_index = mrc.UInt16_BE(0x00) unk1 = mrc.UInt16_BE(0x02) length = mrc.UInt32_BE(0x04) offset = mrc.UInt32_BE(0x08) args_count = mrc.UInt16_BE(0x0c) args_offset = mrc.UInt32_BE(0x0e) vars_count = mrc.UInt16_BE(0x12) vars_offset = mrc.UInt32_BE(0x14) unk2 = mrc.UInt16_BE(0x18) unk8 = mrc.UInt16_BE(0x1a) unk9 = mrc.UInt16_BE(0x1c) unk10 = mrc.UInt16_BE(0x1e) unk11 = mrc.UInt16_BE(0x20) unk12 = mrc.UInt16_BE(0x22) unk13 = mrc.UInt16_BE(0x24) unk14 = mrc.UInt16_BE(0x26) unk15 = mrc.UInt16_BE(0x28) code = mrc.StoreRef(ScriptCode, mrc.Ref('_parent.code_store'), offset=mrc.Ref('offset'), size=mrc.Ref('length')) args = mrc.StoreRef(ScriptArguments, mrc.Ref('_parent.code_store'), offset=mrc.Ref('args_offset')) vars = mrc.StoreRef(ScriptVariables, mrc.Ref('_parent.code_store'), offset=mrc.Ref('vars_offset')) @property def args_size(self): return self.args_count * 2 @property def vars_size(self): return self.vars_count * 2 @property def repr(self): return '{}'.format(self.name)
class SoundV4(mrc.Block): unk1 = mrc.UInt16_BE(0x00) unk2 = mrc.UInt32_BE(0x04) unk3 = mrc.UInt16_BE(0x0c) channels = mrc.UInt16_BE(0x14) sample_rate = mrc.UInt16_BE(0x16) unk4 = mrc.UInt16_BE(0x18) length = mrc.UInt32_BE(0x1e) unk5 = mrc.UInt16_BE(0x22) length_copy = mrc.UInt32_BE(0x24) unk6 = mrc.UInt16_BE(0x28) playback_rate = mrc.UInt16_BE(0x2a) unk7 = mrc.UInt16_BE(0x2c) sample_bits = mrc.UInt16_BE(0x3e) data = mrc.Bytes(0x4e) @property def sample_width(self): return self.sample_bits // 8 @property def sample_signedness(self): return 'unsigned' if self.sample_bits == 8 else 'signed' def __init__(self, *argc, **argv): self.audio = aud.Wave(self, mrc.Ref('data'), channels=mrc.Ref('channels'), sample_rate=mrc.Ref('sample_rate'), format_type=int, field_size=mrc.Ref('sample_width'), signedness=mrc.Ref('sample_signedness'), endian='big') super().__init__(*argc, **argv) @property def repr(self): return 'channels={}, sample_rate={}, length={}, sample_bits={}'.format( self.channels, self.sample_rate, self.length, self.sample_bits)
class ConfigV4(mrc.Block): length = mrc.UInt16_BE(0x00) ver1 = mrc.UInt16_BE(0x02) movie_rect = mrc.BlockField(Rect, 0x04) cast_array_start = mrc.UInt16_BE(0x0c) cast_array_end = mrc.UInt16_BE(0x0e) frame_rate = mrc.UInt8(0x10) light_switch = mrc.UInt8(0x11) unk1 = mrc.Int16_BE(0x12) comment_font = mrc.Int16_BE(0x14) comment_size = mrc.Int16_BE(0x16) comment_style = mrc.UInt8(0x18) comment_style_2 = mrc.UInt8(0x19) stage_colour = mrc.Int16_BE(0x1a) bit_depth = mrc.Int16_BE(0x1c) colour_flag = mrc.UInt8(0x1e) unk5 = mrc.UInt8(0x1f) unk6 = mrc.Int32_BE(0x20) unk7 = mrc.Int16_BE(0x24) unk8 = mrc.Int16_BE(0x26) unk9 = mrc.Int32_BE(0x28) unk10 = mrc.Int32_BE(0x2c) unk11 = mrc.Int32_BE(0x30) unk12 = mrc.UInt8(0x34) unk17 = mrc.UInt8(0x35) unk13 = mrc.Int16_BE(0x36) unk14 = mrc.Int16_BE(0x38) protection_bits = mrc.Int16_BE(0x3a) unk15 = mrc.UInt32_BE(0x3c) checksum = mrc.UInt32_BE(0x40) unk16 = mrc.UInt16_BE(0x44) palette_id = mrc.UInt16_BE(0x46) unk4 = mrc.Bytes(0x48, length=0x08) @property def checksum_v4(self): return checksum_v4(self.export_data())
class ScoreV4(mrc.Block): size = mrc.UInt32_BE(0x00) unk1 = mrc.UInt32_BE(0x04) unk2 = mrc.UInt32_BE(0x08) unk3 = mrc.UInt16_BE(0x0c) unk4 = mrc.UInt16_BE(0x0e) unk5 = mrc.UInt16_BE(0x10) unk6 = mrc.UInt16_BE(0x12) frames = mrc.BlockField(FrameV4, 0x14, stream=True, length=mrc.Ref('size_frames')) extra = mrc.Bytes(mrc.EndOffset('frames')) @property def size_frames(self): return self.size - 0x14 @property def repr(self): return 'num_frames={}'.format(len(self.frames))
class MapData(mrc.Block): """ Read the Resource Map Data. Only the header is implemented. """ resourceDataOffset = mrc.UInt32_BE(0x00) resourceMapOffset = mrc.UInt32_BE(0x04) resourceDataSize = mrc.UInt32_BE(0x08) resourceMapSize = mrc.UInt32_BE(0x0c) nextResourceMap = mrc.UInt32_BE(0x10) fileRef = mrc.UInt16_BE(0x14) attributes = mrc.UInt16_BE(0x16) typeListOffset = mrc.UInt16_BE(0x18) nameListOffset = mrc.UInt16_BE(0x1a) typeCount = mrc.UInt16_BE(0x1c) def get_count(self): """The type count is off by -1.""" return self.typeCount + 1
class ScriptConstantV5(mrc.Block): SCRIPT_CONSTANT_TYPES = { 0x0001: ScriptConstantString, 0x0004: ScriptConstantUInt32, 0x0009: ScriptConstantFloat } const_type = mrc.UInt32_BE(0x00, enum=ScriptConstantType) const = mrc.BlockField(SCRIPT_CONSTANT_TYPES, 0x04, block_type=mrc.Ref('const_type')) @property def repr(self): return '{}: {}'.format(self.const_type, self.const.repr)
class CastV4(mrc.Block): CAST_MAP = { CastType.BITMAP: BitmapCastV4, #CastType.SOUND: SoundCastV4, CastType.SCRIPT: ScriptCastV4, CastType.SHAPE: ShapeCastV4, } size1 = mrc.UInt16_BE(0x00) size2 = mrc.UInt32_BE(0x02) cast_type = mrc.UInt8(0x06, enum=CastType) unk1 = mrc.UInt8(0x07) detail = mrc.BlockField(CAST_MAP, 0x08, block_type=mrc.Ref('cast_type'), default_klass=mrc.Unknown) garbage = mrc.Bytes(mrc.EndOffset('detail')) @property def repr(self): return f'size1: {self.size1}, size2: {self.size2}, cast_type: {self.cast_type}'
class ScriptFunction(mrc.Block): name_index = mrc.UInt16_BE(0x00) unk1 = mrc.UInt16_BE(0x02) length = mrc.UInt32_BE(0x04) offset = mrc.UInt32_BE(0x08) arg_count = mrc.UInt16_BE(0x0c) unk2 = mrc.UInt32_BE(0x0e) var_count = mrc.UInt16_BE(0x12) unk3 = mrc.UInt32_BE(0x14) count3 = mrc.UInt16_BE(0x18) unk4 = mrc.UInt32_BE(0x1a) unk5 = mrc.UInt32_BE(0x1e) unk6 = mrc.UInt16_BE(0x22) count4 = mrc.UInt16_BE(0x24) unk7 = mrc.UInt32_BE(0x26) code = mrc.StoreRef(mrc.Unknown, mrc.Ref('_parent.code_store'), offset=mrc.Ref('offset'), size=mrc.Ref('length'))
class Inner(mrc.Block): field = mrc.UInt32_BE(0x00)
class ScriptConstantUInt32(mrc.Block): value = mrc.UInt32_BE(0x00) @property def repr(self): return '{}'.format(self.value)
class ResourceType(mrc.Block): type = mrc.UInt32_BE(0x00) resourceCount = mrc.UInt16_BE(0x04) resourceListOffset = mrc.UInt16_BE(0x02)
class SordV4(mrc.Block): unk1 = mrc.Bytes(0x00, length=0xc) count = mrc.UInt32_BE(0x0c) unk2 = mrc.UInt16_BE(0x10) unk3 = mrc.UInt16_BE(0x12) index = mrc.UInt16_BE(0x14, count=mrc.Ref('count'))
class TextV4(mrc.Block): unk1 = mrc.UInt32_BE(0x00) length = mrc.UInt32_BE(0x04) unk2 = mrc.UInt32_BE(0x08) data = mrc.Bytes(0xc, length=mrc.Ref('length')) unk3 = mrc.Bytes(mrc.EndOffset('data'))
class CastListV4(mrc.Block): index = mrc.UInt32_BE(0x00, stream=True)
class ConfigV4(mrc.Block): length = mrc.UInt16_BE(0x00) ver1 = mrc.UInt16_BE(0x02) movie_rect = mrc.BlockField(Rect, 0x04) cast_array_start = mrc.UInt16_BE(0x0c) cast_array_end = mrc.UInt16_BE(0x0e) frame_rate = mrc.UInt8(0x10) light_switch = mrc.UInt8(0x11) unk1 = mrc.Int16_BE(0x12) comment_font = mrc.Int16_BE(0x14) comment_size = mrc.Int16_BE(0x16) comment_style = mrc.UInt8(0x18) comment_style_2 = mrc.UInt8(0x19) stage_colour = mrc.Int16_BE(0x1a) bit_depth = mrc.Int16_BE(0x1c) colour_flag = mrc.UInt8(0x1e) unk5 = mrc.UInt8(0x1f) unk6 = mrc.Int32_BE(0x20) unk7 = mrc.Int16_BE(0x24) unk8 = mrc.Int16_BE(0x26) unk9 = mrc.Int32_BE(0x28) unk10 = mrc.Int32_BE(0x2c) unk11 = mrc.Int32_BE(0x30) unk12 = mrc.UInt8(0x34) unk17 = mrc.UInt8(0x35) unk13 = mrc.Int16_BE(0x36) unk14 = mrc.Int16_BE(0x38) protection_bits = mrc.Int16_BE(0x3a) unk15 = mrc.UInt32_BE(0x3c) checksum = mrc.UInt32_BE(0x40) unk16 = mrc.UInt16_BE(0x44) palette_id = mrc.UInt16_BE(0x46) unk4 = mrc.Bytes(0x48, length=0x08) @property def checksum_v4(self): mult = lambda a, b: (a * b) & 0xffffffff stack = [] ax = self.movie_rect.right ax += 6 stack.append(ax) ax = self.movie_rect.bottom ax += 5 stack.append(ax) ax = self.movie_rect.left ax += 4 stack.append(ax) ax = self.movie_rect.top ax += 3 stack.append(ax) ax = self.ver1 ax += 2 cx = self.length cx += 1 ax *= cx stack.append(ax) ax = stack.pop() // stack.pop() stack.append(ax) ax = mult(stack.pop(), stack.pop()) stack.append(ax) ax = stack.pop() // stack.pop() stack.append(ax) ax = mult(stack.pop(), stack.pop()) bx = ax ax = self.cast_array_start ax += 7 bx -= ax stack.append(bx) ax = self.cast_array_end ax += 8 stack.append(ax) ax = mult(stack.pop(), stack.pop()) temp_sum = ax ax = self.frame_rate ax += 9 temp_sum -= ax ax = self.light_switch ax += 10 temp_sum -= ax ax = self.unk1 ax += 11 temp_sum += ax stack.append(temp_sum) ax = self.comment_font ax += 12 stack.append(ax) temp_sum = mult(stack.pop(), stack.pop()) ax = self.comment_size ax += 13 temp_sum += ax stack.append(temp_sum) ax = self.comment_style ax += 14 stack.append(ax) temp_sum = mult(stack.pop(), stack.pop()) ax = self.stage_colour ax += 15 temp_sum += ax ax = self.bit_depth ax += 16 temp_sum += ax ax = self.colour_flag ax += 17 temp_sum += ax stack.append(temp_sum) ax = self.unk5 ax += 18 stack.append(ax) temp_sum = mult(stack.pop(), stack.pop()) eax = self.unk6 eax += 19 temp_sum += eax stack.append(temp_sum) ax = self.unk7 ax += 20 stack.append(ax) temp_sum = mult(stack.pop(), stack.pop()) ax = self.unk8 ax += 21 temp_sum += ax ax = self.unk9 ax += 22 temp_sum += ax ax = self.unk10 ax += 23 temp_sum += ax ax = self.unk11 ax += 24 temp_sum += ax stack.append(temp_sum) ax = self.unk12 ax += 25 stack.append(ax) temp_sum = mult(stack.pop(), stack.pop()) ax = self.unk13 ax += 26 temp_sum += ax stack.append(temp_sum) ax = self.unk14 ax += 27 stack.append(ax) ax = mult(stack.pop(), stack.pop()) stack.append(ax) ax = 0xe06 ax = self.protection_bits * ax ax -= 0x00bb0000 stack.append(ax) ax = mult(stack.pop(), stack.pop()) ax ^= 0x72616c66 # 'ralf' return ax
class HEAD(mrc.Block): unk1 = mrc.UInt32_BE(0x00) unk2 = mrc.UInt32_BE(0x04) palettes = mrc.BlockField(Palette, 0x08, count=10) unk3 = mrc.Bytes(0x1408, length=0x50) unk4 = mrc.Bytes(0x1458, length=0x20)