Ejemplo n.º 1
0
def discard_extra_map_stuff(data: ScnDataReader):
    data.mark("Extra map stuff")
    # NB: Values from genie-rs skip way past random map data in AOE1 files.
    # data.int32(debug='_map_row_offset')
    # data.float32(debug='_map_min_x')
    # data.float32(debug='_map_min_y')
    # data.float32(debug='_map_max_x')
    # data.float32(debug='_map_max_y')
    # data.float32(debug='_map_max_x')
    # data.float32(debug='_map_max_y')
    # data.uint16(debug='_additional_terrain_count')
    # data.uint16(debug='_borders_used')
    # data.uint16(debug='_max_terrain')
    # data.uint16(debug='_tile_width')
    # data.uint16(debug='_tile_height')
    # data.uint16(debug='_tile_half_width')
    # data.uint16(debug='_tile_half_height')
    # data.uint16(debug='_elev_height')
    # data.uint16(debug='_current_row')
    # data.uint16(debug='_current_column')
    # data.uint16(debug='_block_begin_row')
    # data.uint16(debug='_block_end_row')
    # data.uint16(debug='_block_begin_column')
    # data.uint16(debug='_block_end_column')
    # data.int32(debug='_seach_map_pointer')
    # data.int32(debug='_seach_map_rows_pointer')
    # data.uint8(debug='_any_frame_change')
    # data.uint8(debug='_map_visible')
    # data.uint8(debug='_map_fog_of_war')
    # data.read(21 + 157 * 4)
    data.read(68)
Ejemplo n.º 2
0
    def read_de(data: ScnDataReader):
        base = ScnEngineProperties.read_de(data)

        # expecting global victory conditions around here somewhere
        for i in range(0, 8):
            data.uint32(debug='unknown value a {}'.format(i))
        data.uint32(debug='unknown value b')  # 900
        data.uint32(debug='unknown value c')  # 9000

        # expecting diplomacy
        for i in range(0, 16):
            for j in range(0, 16):
                val = data.uint32()
                logging.debug("Unknown value from=%d to=%d val=%d", i, j,
                              val)  # lots of '3'.

        # expecting 12 individual victory conditions for each player
        for i in range(0, 16):
            for j in range(0, 12):
                # TODO read these ???
                data.read(60)

        check3 = data.int32(debug='check value 3')
        if check3 != -99:
            raise Exception(
                "Check value did not match in scenario data, giving up")

        # Probably allied victory
        for i in range(0, 16):
            data.uint32(debug='allied victory player {}'.format(i))

        # disabled tech
        for i in range(0, 16):
            for j in range(0, 20):
                disabled_tech_id = data.uint32()
                logging.debug("Disabled tech player %d, position %d: %d", i, j,
                              disabled_tech_id)

        data.uint32(debug='unknown field 1')
        data.uint32(debug='unknown field 2')
        data.uint32(debug='unknown field 3')  # might be full tech tree

        for j in range(0, 16):  # maybe ?
            data.uint32(debug='starting age player {}'.format(j))

        check4 = data.int32(debug='check value 2')
        if check4 != -99:
            raise Exception(
                "Check value did not match in scenario data, giving up")

        # view ?
        data.float32()
        data.float32()

        game_properties = ScnGameProperties(base)
        logging.debug(game_properties)
        return game_properties
Ejemplo n.º 3
0
def load(file_name: str):
    if not (file_name.endswith(".slp")):
        raise Exception("SLP file must end with .slp")

    with open(file_name, 'rb') as f:
        all_data = f.read()
        data = ScnDataReader(all_data)

    header = SlpHeader.read(data)
    frames = []
    for i in range(0, header.frames):
        data.mark('frame {}'.format(i))
        frame_info = SlpFrameInfo.read(data)
        # Sub-reader for outline data (identified by offset)
        outline_region_start = frame_info.outline_table_offset
        outline_region_end = outline_region_start + frame_info.height * 4
        outline_reader = ScnDataReader(
            all_data[outline_region_start:outline_region_end])
        frame_outline = SlpOutline.read(outline_reader, frame_info.height)
        # Sub-reader for pixel offsets
        command_offset_region_start = frame_info.command_table_offset
        command_offset_region_end = command_offset_region_start + frame_info.height * 4
        command_offset_reader = ScnDataReader(
            all_data[command_offset_region_start:command_offset_region_end])
        command_offset = SlpCommandOffset.read(command_offset_reader,
                                               frame_info.height)
        # Sub-reader for pixel data (very inefficient..)
        command_data_reader = ScnDataReader(all_data)
        command_data_reader.read(
            command_offset.row[0]
        )  # read and discard so that we don't need to do maths to find in-file offset
        rows = []
        for y in range(0, frame_info.height):
            row = SlpRow.read(command_data_reader, frame_outline.row[y])
            rows.append(row)
        frames.append(SlpFrame(frame_info, rows))
    return SlpFile(header, frames)
Ejemplo n.º 4
0
    def read_classic(data: ScnDataReader):
        base = ScnEngineProperties.read_classic(data)
        version = base.rge_version
        if version <= 1.13:
            for i in range(0, 16):
                # skip past player names
                player_name = data.string_fixed(size=256)
            raise Exception(
                "Not implemented: Don't know how to read player base properties from <1.13 file"
            )
        else:
            player_start_resources = []
            for i in range(0, 16):
                # Ignoring at the moment
                this_player_start_resources = ScnPlayerStartResources.read(
                    data, version)
                player_start_resources.append(this_player_start_resources)

        if version >= 1.02:
            check5 = data.int32()
            if check5 != -99:
                raise Exception(
                    "Check value did not match in scenario data, giving up")

        victory_conquest = data.uint32()
        victory_ruins = data.uint32()
        victory_artifacts = data.uint32()
        victory_discoveries = data.uint32()
        victory_exploration = data.uint32()
        victory_gold = data.uint32()
        victory_all_flag = data.boolean32()

        if version >= 1.13:
            mp_victory_type = data.uint32()
            victory_score = data.uint32()
            victory_time = data.uint32()

        for i in range(0, 16):
            for j in range(0, 16):
                stance = data.uint32()
                logging.debug("Diplomacy from=%d to=%d stance=%d", i, j,
                              stance)

        # 12 victory conditions for each player
        for i in range(0, 16):
            for j in range(0, 12):
                # TODO read these ???
                individual_victory_blob = data.read(60)

        if version >= 1.02:
            check5 = data.int32()
            if check5 != -99:
                raise Exception(
                    "Check value did not match in scenario data, giving up")

        # Allied victory
        for i in range(0, 16):
            allied_victory = data.uint32()

        if version >= 1.24:
            raise Exception(
                "Not implemented: Don't know how to read team information from >=1.24 file"
            )

        if version >= 1.18:
            # Also has disabled units and building, where are they in older versions?
            raise Exception(
                "Not implemented: Don't know how to read tech tree from >=1.18 file"
            )
        elif version > 1.03:
            for i in range(0, 16):
                for j in range(0, 20):
                    disabled_tech_id = data.uint32()
                    logging.debug("Disabled tech player %d, position %d: %d",
                                  i, j, disabled_tech_id)

        if version > 1.04:
            data.uint32()  # No idea

        if version >= 1.12:
            data.uint32()  # No idea
            full_tech_tree = data.boolean32()

        if version > 1.05:
            for i in range(0, 16):
                player_start_age = data.uint32()

        if version >= 1.02:
            check6 = data.int32()
            if check6 != -99:
                raise Exception(
                    "Check value did not match in scenario data, giving up")

        if version >= 1.19:
            # 'view'??
            data.uint32()
            data.uint32()

        if version >= 1.21:
            raise Exception(
                "Not implemented: Don't know how to read map type from >=1.21 file"
            )

        if version >= 1.21:
            raise Exception(
                "Not implemented: Don't know how to read base priorities from >=1.21 file"
            )

        game_properties = ScnGameProperties(base)
        logging.debug(game_properties)
        return game_properties
Ejemplo n.º 5
0
    def read_classic(data: ScnDataReader):
        # TODO actually store this stuff
        version = data.float32(debug='version')
        if version > 1.13:
            for i in range(0, 16):
                # skip past player names
                player_name = data.string_fixed(size=256)

        if version > 1.16:
            raise Exception("Not implemented: player string table not understood")

        if version > 1.13:
            for i in range(0, 16):
                player_base = ScnPlayerBaseProperties.read(data)
                logging.debug(player_base)

        is_conquest = False
        if version > 1.07:
            is_conquest = data.boolean8()

        # Something to do with timelines?
        check1 = data.uint16()
        check2 = data.uint16()
        check3 = data.float32()
        if check1 != 0 or check2 != 0 or check3 < -1 or check3 > 1:
            raise Exception("Unexpected values in scenario data, giving up")

        filename = data.string16(debug='filename')

        if version > 1.16:
            raise Exception("Not implemented: scenario instruction string table not understood")

        if version > 1.22:
            raise Exception("Not implemented: scout string table not understood")

        description = data.string16(debug='description')

        if version >= 1.11:
            hints_message = data.string16(debug='hints_message')
            win_message = data.string16(debug='win_message')
            loss_message = data.string16(debug='loss_message')
            history_message = data.string16(debug='history_message')

        if version > 1.22:
            raise Exception("Not implemented: scout data not understood")

        pregame_cinematic = data.string16(debug='pregame_cinematic')
        victory_cinematic = data.string16(debug='victory_cinematic')
        loss_cinematic = data.string16(debug='loss_cinematic')

        if version >= 1.09:
            mission_bmp = data.string16()
            logging.debug("mission_bmp='%s'", mission_bmp)

        if version >= 1.10:
            mission_image = data.uint32()
            width = data.uint32()
            height = data.uint32()
            orientation = data.uint16()
            if width > 0 or height > 0:
                raise Exception("Mission BMP data not understood")

        for i in range(0, 16):
            player_build_list = data.string16()
            logging.debug("Player %d build list %s", i, player_build_list)

        for i in range(0, 16):
            player_city_plan = data.string16()
            logging.debug("Player %d city plan %s", i, player_city_plan)

        if version >= 1.08:
            for i in range(0, 16):
                player_personality = data.string16()
                logging.debug("Player %d personality %s", i, player_personality)

        for i in range(0, 16):
            """ Embedded files """
            build_list_length = data.uint32()
            city_plan_length = data.uint32()
            ai_rules_length = data.uint32() if version >= 1.08 else 0
            data.read(build_list_length)
            data.read(city_plan_length)
            data.read(ai_rules_length)

        if version >= 1.20:
            raise Exception("Not implemented: AI rules not understood")

        if version >= 1.02:
            check4 = data.int32()
            if check4 != -99:
                raise Exception("Check value did not match in scenario data, giving up")

        rge_scen = ScnEngineProperties(
            version
        )
        logging.debug(rge_scen)
        return rge_scen
Ejemplo n.º 6
0
 def read(data: ScnDataReader):
     cmd_byte = data.uint8()
     if cmd_byte & 0x03 == 0x00:
         # "Lesser draw"
         draw_len = cmd_byte >> 2
         draw_px = data.read(draw_len)
         # if draw len == 0 ??
         return SlpDrawCommand(SlpDrawCommandType.PALETTE_PIXELS_DRAW,
                               draw_len, draw_px)
     elif cmd_byte & 0x03 == 0x01:
         # "Lesser skip"
         draw_len = cmd_byte >> 2
         if draw_len == 0:
             draw_len = data.uint8()
         return SlpDrawCommand(SlpDrawCommandType.TRANSPARENT_DRAW,
                               draw_len, b"")
     elif cmd_byte & 0x0F == 0x02:
         # "Greater draw"
         draw_len = ((cmd_byte & 0xF0) << 4) + data.uint8()
         draw_px = data.read(draw_len)
         return SlpDrawCommand(SlpDrawCommandType.PALETTE_PIXELS_DRAW,
                               draw_len, draw_px)
     elif cmd_byte & 0x0F == 0x03:
         # "Greater skip"
         draw_len = ((cmd_byte & 0xF0) << 4) + data.uint8()
         return SlpDrawCommand(SlpDrawCommandType.TRANSPARENT_DRAW,
                               draw_len, b"")
     elif cmd_byte & 0x0F == 0x06:
         # "Player color draw"
         draw_len = cmd_byte >> 4
         if draw_len == 0:
             draw_len = data.uint8()
         draw_px = data.read(draw_len)
         return SlpDrawCommand(SlpDrawCommandType.PLAYER_PIXELS_DRAW,
                               draw_len, draw_px)
     elif cmd_byte & 0x0F == 0x07:
         # "Fill"
         draw_len = cmd_byte >> 4
         if draw_len == 0:
             draw_len = data.uint8()
         draw_px = data.read(1)
         return SlpDrawCommand(SlpDrawCommandType.PALETTE_PIXEL_REPEAT,
                               draw_len, draw_px)
     elif cmd_byte & 0x0F == 0x0A:
         # "Player color fill"
         draw_len = cmd_byte >> 4
         if draw_len == 0:
             draw_len = data.uint8()
         draw_px = data.read(1)
         return SlpDrawCommand(SlpDrawCommandType.PLAYER_PIXEL_REPEAT,
                               draw_len, draw_px)
     elif cmd_byte & 0x0F == 0x0B:
         draw_len = cmd_byte >> 4
         if draw_len == 0:
             draw_len = data.uint8()
         return SlpDrawCommand(SlpDrawCommandType.SHADOW_DRAW, draw_len,
                               b"")
     elif cmd_byte & 0x0F == 0x0E:
         cmd_idx = cmd_byte >> 4
         return SlpDrawCommand(SlpDrawCommandType.EXTENDED_COMMAND, 1,
                               bytes([cmd_idx]))
     elif cmd_byte == 0x0F:  # ? Strange end of row??
         return SlpDrawCommand(SlpDrawCommandType.END_OF_ROW, 0, b"")
     print(cmd_byte)
     raise Exception("Unrecognised SLP draw byte, file may be corrupt.")
Ejemplo n.º 7
0
 def read(data: ScnDataReader):
     return DRSResourceType(data.read(4))