Skip to content

Commit 51c4886

Browse files
authored
Merge pull request #148 from RevoSucks/extract_assets_1
Unpack/post process asset bins into simple file structure
2 parents cbf1027 + b0a1ddd commit 51c4886

File tree

3 files changed

+123
-0
lines changed

3 files changed

+123
-0
lines changed

Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ SPLAT := $(PYTHON) -m splat split
156156
SPLAT_YAML := $(TARGET)-$(VERSION).yaml
157157

158158
ENCRYPT_LIBLEO := $(PYTHON) tools/encrypt_libleo.py
159+
EXTRACT_ASSETS := tools/extract_assets.sh
159160

160161
IINC := -Iinclude -Isrc -Isrc/libnaudio -Iassets/$(VERSION) -I. -I$(BUILD_DIR)
161162
IINC += -Ilib/ultralib/include -Ilib/ultralib/include/PR -Ilib/ultralib/include/ido
@@ -342,6 +343,7 @@ extract:
342343
$(V)$(RM) -r asm/$(VERSION) assets/$(VERSION)
343344
$(V)$(CAT) yamls/$(VERSION)/header.yaml yamls/$(VERSION)/rom.yaml > $(SPLAT_YAML)
344345
$(V)$(SPLAT) $(SPLAT_FLAGS) $(SPLAT_YAML)
346+
$(V)$(EXTRACT_ASSETS)
345347

346348
lib: $(ULTRALIB_LIB)
347349

tools/extract_assets.sh

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env bash
2+
3+
# Unpack assets from ROM extraction.
4+
5+
# TODO: The packed bins do not depend on their extracted contents yet so modifying these files will do nothing. Add dependencies
6+
7+
tools/unpack_asset.py assets/us/n64_logo_texture.bin
8+
tools/unpack_asset.py assets/us/fonts.bin
9+
tools/unpack_asset.py assets/us/backgrounds.bin
10+
tools/unpack_asset.py assets/us/battle_headers.bin
11+
tools/unpack_asset.py assets/us/common_menu0_ui.bin
12+
tools/unpack_asset.py assets/us/common_menu1_ui.bin
13+
tools/unpack_asset.py assets/us/common_menu2_ui.bin
14+
tools/unpack_asset.py assets/us/area_select_ui.bin
15+
tools/unpack_asset.py assets/us/menu_select_ui.bin
16+
tools/unpack_asset.py assets/us/stadium_select_ui.bin
17+
tools/unpack_asset.py assets/us/title_ui.bin
18+
tools/unpack_asset.py assets/us/52F6D0.bin # unused UI
19+
tools/unpack_asset.py assets/us/battle_portraits.bin
20+
tools/unpack_asset.py assets/us/stadium_models.bin
21+
tools/unpack_asset.py assets/us/5C7A70.bin # unk FRAGMENT
22+
tools/unpack_asset.py assets/us/pokedex_area_model.bin
23+
tools/unpack_asset.py assets/us/sushi_go_round.bin
24+
tools/unpack_asset.py assets/us/order_select_ui.bin
25+
tools/unpack_asset.py assets/us/cup_ball_select_ui.bin
26+
tools/unpack_asset.py assets/us/trade_select_ui.bin
27+
tools/unpack_asset.py assets/us/kids_club_select_ui.bin
28+
tools/unpack_asset.py assets/us/gym_leader_castle_clear_gfx.bin
29+
tools/unpack_asset.py assets/us/rental_rules_ui.bin
30+
tools/unpack_asset.py assets/us/sushi_go_round_sprites.bin
31+
tools/unpack_asset.py assets/us/kids_club_game_ui.bin
32+
tools/unpack_asset.py assets/us/gallery_ui.bin
33+
tools/unpack_asset.py assets/us/album_ui.bin
34+
tools/unpack_asset.py assets/us/6A9750.bin # print UI
35+
tools/unpack_asset.py assets/us/snap_select_ui.bin
36+
tools/unpack_asset.py assets/us/cup_clear_ui.bin
37+
tools/unpack_asset.py assets/us/gb_pak_select_ui.bin
38+
tools/unpack_asset.py assets/us/victory_palace_plate_text.bin
39+
tools/unpack_asset.py assets/us/run_rattata_run_flag_gfx.bin
40+
tools/unpack_asset.py assets/us/kanto_gb_map.bin
41+
tools/unpack_asset.py assets/us/6CA730.bin # unused 15 type BGs
42+
tools/unpack_asset.py assets/us/6E2F90.bin # blank file
43+
tools/unpack_asset.py assets/us/battle_ui.bin
44+
tools/unpack_asset.py assets/us/transfer_pak_error_ui.bin
45+
tools/unpack_asset.py assets/us/6EB340.bin
46+
tools/unpack_asset.py assets/us/6EC4D0.bin
47+
tools/unpack_asset.py assets/us/badge_ui.bin
48+
tools/unpack_asset.py assets/us/gym_leader_castle_ui.bin
49+
# 70D3A0 needs special processing. not a normal asset bin
50+
# 7820E0 isnt a normal asset bin either
51+
tools/unpack_asset.py assets/us/textdata.bin
52+
tools/unpack_asset.py assets/us/798CD0.bin
53+
tools/unpack_asset.py assets/us/snap_mode_ui.bin
54+
tools/unpack_asset.py assets/us/copyright.bin

tools/unpack_asset.py

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env python3
2+
3+
import sys
4+
import re
5+
import os
6+
from pathlib import Path
7+
import crunch64
8+
9+
# Asset unpacker v0.1 (WIP)
10+
11+
# Read a big endian 32-bit value from a bytearray file with a given offset.
12+
def read_32_be_value(file_arr, i):
13+
return (file_arr[i + 0] << 24) + (file_arr[i + 1] << 16) \
14+
+ (file_arr[i + 2] << 8) + (file_arr[i + 3])
15+
16+
# --------------------------
17+
# Main program
18+
# --------------------------
19+
20+
assets_path = "assets/us/"
21+
22+
filepath = Path(sys.argv[1])
23+
filename = os.path.splitext(os.path.basename(filepath))[0]
24+
25+
file = open(filepath, 'rb')
26+
file_header = bytearray(file.read(0x10))
27+
28+
#print("[DEBUG] File path:", filepath)
29+
#print("[DEBUG] File name:", filename)
30+
31+
# Magic check for multi asset bin. If no match, treat as a single asset bin, and just copy it to the expected folder.
32+
if file_header[0] != 0x00 or file_header[1] != 0x00 or file_header[2] != 0x00 or file_header[3] != 0x00 or file_header[4] != 0x00 or file_header[5] != 0x00 or file_header[6] != 0x00 or file_header[7] != 0x00:
33+
file_path_to_write = assets_path + filename + "/0/0.bin"
34+
os.makedirs(os.path.dirname(file_path_to_write), exist_ok=True)
35+
with open(file_path_to_write, 'wb') as f:
36+
fin = open(filepath, 'rb')
37+
f.write(fin.read())
38+
sys.exit(0)
39+
40+
# Otherwise, process as multi.
41+
bin_size = read_32_be_value(file_header, 8)
42+
file_count = read_32_be_value(file_header, 12)
43+
44+
#print("[DEBUG] Size:", hex(bin_size))
45+
#print("[DEBUG] File count:", file_count)
46+
47+
# Reallocate the file based on the bin size. First seek back to the start, then reallocate.
48+
file.seek(0, os.SEEK_SET)
49+
file_bytes = bytearray(file.read(bin_size))
50+
51+
file_num = 0
52+
while file_num < file_count:
53+
#print("[DEBUG] Processing File #:", file_num)
54+
# Get bin offset and bin size for the # file being processed.
55+
bin_offset = read_32_be_value(file_bytes, 0x10 + (file_num * 0x10) + 0)
56+
bin_size = read_32_be_value(file_bytes, 0x10 + (file_num * 0x10) + 4)
57+
#print("[DEBUG] File Offset:", hex(bin_offset))
58+
#print("[DEBUG] File Size:", hex(bin_size))
59+
# Seek to the file offset.
60+
file.seek(bin_offset, os.SEEK_SET)
61+
sub_file_bytes = bytearray(file.read(bin_size))
62+
file_path_to_write = assets_path + filename + "/" + str(file_num) + "/" + str(file_num) + ".bin"
63+
#print("[DEBUG] Path to write:", file_path_to_write)
64+
os.makedirs(os.path.dirname(file_path_to_write), exist_ok=True)
65+
file_to_write = open(file_path_to_write, 'wb')
66+
file_to_write.write(sub_file_bytes)
67+
file_num = file_num + 1

0 commit comments

Comments
 (0)