def draw_full(self, ctx: cairo.Context, bma_chunks: List[int],
               bma_chunk_width: int, bma_chunk_height: int):
     if bma_chunk_width != self._cached__bma_chunk_width or self._cached__bma_chunks != bma_chunks:
         self._cached__bma_chunk_width = bma_chunk_width
         self._cached__bma_chunks = list(bma_chunks)
         self._cached = None
     if self._cached is None:
         drawer = DmaDrawer(self.dma)
         if self.fixed_room:
             rules = drawer.rules_from_fixed_room(self.fixed_room)
         else:
             rules = drawer.rules_from_bma(bma_chunks, bma_chunk_width)
         mappings = drawer.get_mappings_for_rules(
             rules, treat_outside_as_wall=True, variation_index=0)
         frame = pil_to_cairo_surface(
             drawer.draw(mappings, self.dpci, self.dpc, self.dpl,
                         None)[0].convert('RGBA'))
         self._cached = frame
     ctx.set_source_surface(self._cached)
     ctx.get_source().set_filter(cairo.Filter.NEAREST)
     ctx.paint()
Esempio n. 2
0
def draw_dungeon_map_bgs(rom, dungeon_map_bg_dir, config):
    os.makedirs(dungeon_map_bg_dir, exist_ok=True)
    dungeon_bin = FileType.DUNGEON_BIN.deserialize(rom.getFileByName('DUNGEON/dungeon.bin'), config)

    ground_dungeon_tilesets = HardcodedGroundDungeonTilesets.get_ground_dungeon_tilesets(
        get_binary_from_rom_ppmdu(rom, config.binaries['overlay/overlay_0011.bin']),
        config
    )
    dungeons = HardcodedDungeons.get_dungeon_list(
        get_binary_from_rom_ppmdu(rom, config.binaries['arm9.bin']),
        config
    )
    mappa = FileType.MAPPA_BIN.deserialize(rom.getFileByName('BALANCE/mappa_s.bin'))
    
    levels_by_id = config.script_data.level_list__by_id

    bg_list_bin = rom.getFileByName('MAP_BG/bg_list.dat')
    bg_list = FileType.BG_LIST_DAT.deserialize(bg_list_bin)

    for i, entry in enumerate(ground_dungeon_tilesets):
        if entry.ground_level >= 0xFFFF:
            continue
        level = levels_by_id[entry.ground_level]
        print(f"{i + 1}/{len(ground_dungeon_tilesets)-1} - {level.name}")
        print(entry)

        mappa_idx = dungeons[entry.dungeon_id].mappa_index
        start_offset = dungeons[entry.dungeon_id].start_after
        length = dungeons[entry.dungeon_id].number_floors
        if entry.dungeon_id == 71:
            print("DEEP CONCEALED RUINS SKIPPED")
            continue
        if entry.unk2 == 1:
            tileset_id = mappa.floor_lists[mappa_idx][start_offset].layout.tileset_id
        elif entry.unk2 == 100:
            tileset_id = mappa.floor_lists[mappa_idx][start_offset + length - 1].layout.tileset_id
        else:
            raise ValueError("Unknown unk2")
        if tileset_id == 170:
            tileset_id = 1
        dma: Dma = dungeon_bin.get(f'dungeon{tileset_id}.dma')
        dpl: Dpl = dungeon_bin.get(f'dungeon{tileset_id}.dpl')
        dpla: Dpla = dungeon_bin.get(f'dungeon{tileset_id}.dpla')
        dpci: Dpci = dungeon_bin.get(f'dungeon{tileset_id}.dpci')
        dpc: Dpc = dungeon_bin.get(f'dungeon{tileset_id}.dpc')

        bma: Bma = bg_list.level[level.mapid].get_bma(rom)

        duration = round(1000 / 60 * max(16, min(dpla.durations_per_frame_for_colors)))

        drawer = DmaDrawer(dma)
        rules = drawer.rules_from_bma(bma)
        mappings = drawer.get_mappings_for_rules(rules, treat_outside_as_wall=True, variation_index=0)
        frames = drawer.draw(mappings, dpci, dpc, dpl, dpla)
        frames[0].save(
            os.path.join(dungeon_map_bg_dir, level.name + '.gif'),
            save_all=True,
            append_images=frames[1:],
            duration=duration,
            loop=0,
            optimize=False
        )
        frames[0].save(
            os.path.join(dungeon_map_bg_dir, level.name + '.png')
        )