Exemple #1
0
 def __init__(self, data):
     self.gfx_chunk_id = read_word(data, 0x0)
     self.num_sprites = data[0x2]
     self.script_entry_point = read_word(data, 0x3)
     self.unk_5 = read_word(data, 0x5)
     self.unk_7 = read_word(data, 0x7)
     self.width = data[0x9]
     self.height = data[0xA]
     self.unk_B = read_word(data, 0xB)
     self.unk_D = read_word(data, 0xD)
     self.unk_F = read_word(data, 0xF)
     self.max_x_velocity = read_word(data, 0x11)
     self.max_y_velocity = read_word(data, 0x13)
Exemple #2
0
 def __init__(self, data):
     self.gfx_chunk_id = read_word(data, 0x0)
     self.num_sprites = data[0x2]
     self.script_entry_point = read_word(data, 0x3)
     self.unk_5 = read_word(data, 0x5)
     self.unk_7 = read_word(data, 0x7)
     self.width = data[0x9]
     self.height = data[0xA]
     self.unk_B = read_word(data, 0xB)
     self.unk_D = read_word(data, 0xD)
     self.unk_F = read_word(data, 0xF)
     self.max_x_velocity = read_word(data, 0x11)
     self.max_y_velocity = read_word(data, 0x13)
Exemple #3
0
def rlew_expand(source, length):
    dest = bytearray()

    while len(dest) < length:

        value = read_word(source)
        if value != state.RLEWtag:
            # uncompressed
            write_word(dest, value)
        else:
            # compressed string
            count = read_word(source)
            value = read_word(source)
            for i in range(count):
                write_word(dest, value)

    return dest
Exemple #4
0
def carmack_expand(source, length):
    NEAR_TAG = 0xa7
    FAR_TAG = 0xa8

    length = length // 2
    source = bytearray(source)
    dest = bytearray()

    while length > 0:
        ch = read_word(source, byteorder='little')
        ch_high = ch >> 8

        if ch_high in (NEAR_TAG, FAR_TAG):
            count = ch & 0xff;
            if not count:
                # have to insert a word containing the tag byte
                ch |= source.pop(0)
                write_word(dest, ch)

                length -= 1;
            elif ch_high == NEAR_TAG:
                offset = source.pop(0)
                length -= count;

                if length >= 0:
                    start = -offset * 2
                    end = (-offset + count) * 2
                    if (-offset + count) >= 0:
                        end = len(dest)
                    dest += dest[start : end]

            elif ch_high == FAR_TAG:
                offset = read_word(source, byteorder='little')
                length -= count
                if length >= 0:
                    dest += dest[offset*2 : (offset + count) *2]

        else:
            write_word(dest, ch)
            length -= 1;

    return dest
Exemple #5
0
def load_animation_list(data, pos):
    chunks = []
    while True:
        chunk_id = read_word(data, pos)
        if chunk_id == 0xFFFF:
            break
        pos += 5

        chunks.append(chunk_id)

    return chunks
Exemple #6
0
def load_object_graphics_list(data, pos):
    chunks = []
    while True:
        chunk_id = read_word(data, pos)
        pos += 2
        if chunk_id == 0xFFFF:
            break

        chunks.append(chunk_id)

    return pos, chunks
Exemple #7
0
def decompress_data(data, decoded_data_len=None):
    if decoded_data_len is None:
        decoded_data_len = read_word(data, 0) + 1
        data = data[2:]

    scratch = array('B', itertools.repeat(0, 0x1000))
    dst = array('B')

    scratch_i = 0
    src_i = 0

    while True:
        al = data[src_i]
        src_i += 1

        for i in xrange(8):
            if al & 1:
                # Verbatim byte
                scratch[scratch_i] = data[src_i]
                scratch_i = (scratch_i + 1) % len(scratch)
                dst.append(data[src_i])
                if len(dst) == decoded_data_len:
                    return dst
                src_i += 1
            else:
                # Copy previous bytes from scratch area
                copy_src = read_word(data, src_i)
                src_i += 2

                copy_len = (copy_src >> 12) + 3
                copy_src = copy_src & 0xFFF

                for j in xrange(copy_len):
                    scratch[scratch_i] = scratch[copy_src]
                    scratch_i = (scratch_i + 1) % len(scratch)
                    dst.append(scratch[copy_src])
                    if len(dst) == decoded_data_len:
                        return dst
                    copy_src = (copy_src + 1) % len(scratch)
            al = al >> 1
def decompress_data(data, decoded_data_len=None):
    if decoded_data_len is None:
        decoded_data_len = read_word(data, 0) + 1
        data = data[2:]

    scratch = array('B', itertools.repeat(0, 0x1000))
    dst = array('B')

    scratch_i = 0
    src_i = 0

    while True:
        al = data[src_i]
        src_i += 1

        for i in xrange(8):
            if al & 1:
                # Verbatim byte
                scratch[scratch_i] = data[src_i]
                scratch_i = (scratch_i + 1) % len(scratch)
                dst.append(data[src_i])
                if len(dst) == decoded_data_len:
                    return dst
                src_i += 1
            else:
                # Copy previous bytes from scratch area
                copy_src = read_word(data, src_i)
                src_i += 2

                copy_len = (copy_src >> 12) + 3
                copy_src = copy_src & 0xFFF

                for j in xrange(copy_len):
                    scratch[scratch_i] = scratch[copy_src]
                    scratch_i = (scratch_i + 1) % len(scratch)
                    dst.append(scratch[copy_src])
                    if len(dst) == decoded_data_len:
                        return dst
                    copy_src = (copy_src + 1) % len(scratch)
            al = al >> 1
Exemple #9
0
def load_palette_cycle_list(data, pos):
    active_cycles = read_word(data, pos)
    pos += 2

    cycles = []

    while True:
        speed = data[pos]
        if speed == 0:
            pos += 1
            break
        first = data[pos + 1]
        last = data[pos + 2]
        pos += 3

        cycles.append((speed, first, last))

        while True:
            val_d = read_word(data, pos)
            pos += 2
            if val_d == 0xFFFF:
                break

    return pos, active_cycles, cycles
Exemple #10
0
def load_palette_list(data, pos):
    pals = []

    while True:
        chunk_id = read_word(data, pos)
        pos += 2
        if chunk_id == 0xFFFF:
            break

        load_position = data[pos]
        pos += 1

        pals.append((chunk_id, load_position))

    return pos, pals
Exemple #11
0
def load_object_list(data, pos):
    objects = []

    while True:
        xpos = read_word(data, pos)
        if xpos == 0xFFFF:
            pos += 2
            break
        ypos = read_word(data, pos + 2)
        width = read_word(data, pos + 4)
        height = read_word(data, pos + 6)
        type_id = read_word(data, pos + 8)
        unk4 = read_word(data, pos + 10)
        user_data = read_word(data, pos + 12)

        objects.append(
            ObjectInstance(xpos, ypos, width, height, type_id, unk4,
                           user_data))

        pos += 14

    return pos, objects
Exemple #12
0
    def load(self, data):
        self.raw_data = data

        self.music_command = data[0x4]
        self.music_track = data[0x5]

        self.special_objs_type = data[0x7]
        self.special_obj_x = read_word(data, 0x8)
        self.special_obj_y = read_word(data, 0xA)
        self.special_obj_type = read_word(data, 0xC)
        self.special_obj_unk1 = read_word(data, 0xE)
        self.special_obj_user_data = read_word(data, 0x10)

        self.next_level = read_word(data, 0x16)
        self.sprite_sizes = read_word(data, 0x18)

        self.flags = data[0x1C]

        self.width = read_word(data, 0x29)
        self.height = read_word(data, 0x2B)

        self.tilemap_chunk = read_word(data, 0x2E)
        self.tileset_chunk = read_word(data, 0x30)
        self.metatile_chunk = read_word(data, 0x32)

        self.load_list = LoadList()
        self.load_list.load(data[0x43:])
Exemple #13
0
def simple_scale_shape(vbuf, shape_num):
    view_width, view_height = id_vh.state.view_width, id_vh.state.view_height
    xcenter = view_width // 2
    height = view_height + 1

    shape, shape_bytes = id_pm.get_sprite(shape_num)

    scale = height >> 1
    pixheight = scale * de.SPRITE_SCALE_FACTOR
    actx = xcenter - scale
    upperedge = view_height // 2 - scale

    # cmdptr=(word *) shape->dataofs;
    cmdptr = iter(shape.dataofs)

    i = shape.left_pix
    pixcnt = i * pixheight
    rpix = (pixcnt >> 6) + actx

    # for(i=shape->leftpix,pixcnt=i*pixheight,rpix=(pixcnt>>6)+actx;i<=shape->rightpix;i++,cmdptr++)
    while i <= shape.right_pix:
        lpix = rpix
        if lpix >= view_width:
            break

        pixcnt += pixheight
        rpix = (pixcnt >> 6) + actx

        if lpix != rpix and rpix > 0:

            if lpix < 0:
                lpix = 0
            if rpix > view_width:
                rpix = view_width
                i = shape.right_pix + 1

            # cline points to the offset indicated by the next cmdptr item
            # cline=(byte *)shape + *cmdptr;
            cline = shape_bytes[next(cmdptr):]
            while lpix < rpix:
                # turn into bytearray to pop when moving the pointer
                # maybe better to iterate some other way
                line = bytearray(cline)
                endy = read_word(line, byteorder='little')
                while endy:
                    endy >>= 1
                    newstart = read_word(line, byteorder='little', signed=True)
                    starty = read_word(line, byteorder='little') >> 1
                    j = starty
                    ycnt = j * pixheight
                    screndy = (ycnt >> 6) + upperedge

                    if screndy < 0:
                        vmem_index = lpix
                    else:
                        vmem_index = screndy * vbuf.pitch + lpix

                    while j < endy:
                        scrstarty = screndy
                        ycnt += pixheight
                        screndy = (ycnt >> 6) + upperedge
                        if scrstarty != screndy and screndy > 0:
                            col = shape_bytes[newstart + j]
                            if scrstarty < 0:
                                scrstarty = 0
                            if screndy > view_height:
                                screndy = view_height
                                j = endy

                            while scrstarty < screndy:
                                vbuf[vmem_index] = col
                                vmem_index += vbuf.pitch
                                scrstarty += 1
                        j += 1

                    endy = read_word(line, byteorder='little')
                lpix += 1
        i += 1
Exemple #14
0
def read_image(data):
    """Deinterleaves a length-prefixed image"""
    data_len = read_word(data, 0) * 4
    return interleave_planar(data[2:2+data_len])