class Interactive(mrc.Block): """Represents a single interactive piece placed in a level.""" #: Raw value for the x position of the left edge. x_raw = mrc.Int16_BE(0x00, range=range(-8, 1601)) #: The y position of the top edge. y = mrc.Int16_BE(0x02, range=range(-41, 201)) #: Index of the InteractiveInfo block in the accompanying GroundDAT. obj_id = mrc.UInt16_BE(0x04, range=range(0, 16)) #: If 1, blit image behind background. draw_back = mrc.Bits(0x06, 0b10000000) #: If 1, draw piece flipped vertically. draw_masked = mrc.Bits(0x06, 0b01000000) #: If 1, draw piece as a hole. draw_upsidedown = mrc.Bits(0x07, 0b10000000) #: Check to ensure the last chunk of the block is empty. mod_check = mrc.Const(mrc.UInt16_BE(0x06, bitmask=b'\x3f\x7f'), 0x000f) @property def x(self): """The x position of the left edge.""" return (self.x_raw - 16) - ((self.x_raw - 16) % 8) @property def repr(self): return "obj_id={}, x={}, y={}".format(self.obj_id, self.x, self.y)
class Rect(mrc.Block): top = mrc.Int16_BE(0x00) left = mrc.Int16_BE(0x02) bottom = mrc.Int16_BE(0x04) right = mrc.Int16_BE(0x06) @property def width(self): return self.right - self.left @property def height(self): return self.bottom - self.top @property def repr(self): return f'top={self.top}, left={self.left}, bottom={self.bottom}, right={self.right}, width={self.width}, height={self.height}'
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 Rect(mrc.Block): top = mrc.Int16_BE(0x00) left = mrc.Int16_BE(0x02) bottom = mrc.Int16_BE(0x04) right = mrc.Int16_BE(0x06) @property def width(self): return self.right - self.left @property def height(self): return self.bottom - self.top @property def repr(self): return 'top={}, left={}, bottom={}, right={}, width={}, height={}'.format( self.top, self.left, self.bottom, self.right, self.width, self.height)
class ScriptContextEntry(mrc.Block): unk1 = mrc.UInt16_BE(0x00) unk2 = mrc.UInt16_BE(0x02) unk3 = mrc.UInt16_BE(0x04) index = mrc.UInt16_BE(0x06) # for mmap.entries unk4 = mrc.Bits16(0x08, 0b1111111111111011) active = mrc.Bits16(0x08, 0b0000000000000100) link = mrc.Int16_BE(0x0a) @property def repr(self): return 'index: {}, active: {}'.format(self.index, self.active)
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 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 ScriptV4(mrc.Block): unk1 = mrc.Bytes(0x00, length=0x10) code_store_offset = mrc.UInt16_BE(0x10) unk2 = mrc.Bytes(0x12, length=0x1c) cast_id = mrc.UInt16_BE(0x2e) factory_name_id = mrc.Int16_BE(0x30) unk9 = mrc.Bytes(0x32, length=0xe) globals_offset = mrc.UInt16_BE(0x40) globals_count = mrc.UInt16_BE(0x42) unk3 = mrc.Bytes(0x44, length=4) functions_count = mrc.UInt16_BE(0x48) unk4 = mrc.UInt16_BE(0x4a) functions_offset = mrc.UInt16_BE(0x4c) consts_count = mrc.UInt16_BE(0x4e) unk6 = mrc.UInt16_BE(0x50) consts_offset = mrc.UInt16_BE(0x52) unk7 = mrc.UInt16_BE(0x54) consts_unk = mrc.UInt16_BE(0x56) unk8 = mrc.UInt16_BE(0x58) consts_base = mrc.UInt16_BE(0x5a) @property def code_store_size(self): return self.functions_offset - self.code_store_offset @code_store_size.setter def code_store_size(self, value): self.functions_offset = value + self.code_store_offset @property def code_store_base(self): return -self.code_store_offset code_store_raw = mrc.Bytes(mrc.Ref('code_store_offset'), length=mrc.Ref('code_store_size')) globals = mrc.BlockField(ScriptGlobal, mrc.Ref('globals_offset'), count=mrc.Ref('globals_count')) functions = mrc.BlockField(ScriptFunction, mrc.Ref('functions_offset'), count=mrc.Ref('functions_count')) consts = mrc.BlockField(ScriptConstantV4, mrc.Ref('consts_offset'), count=mrc.Ref('consts_count')) consts_raw = mrc.Bytes(mrc.EndOffset('consts')) @property def consts_store_offset(self): return self.consts_base - self.get_field_end_offset('consts') #test = mrc.Bytes( 0x00 ) def __init__(self, *args, **kwargs): self.consts_store = mrc.Store( self, mrc.Ref('consts_raw'), base_offset=mrc.Ref('consts_store_offset')) self.code_store = mrc.Store(self, mrc.Ref('code_store_raw'), base_offset=mrc.Ref('code_store_base')) super().__init__(*args, **kwargs)