-
Notifications
You must be signed in to change notification settings - Fork 8
/
make-patch.py
117 lines (93 loc) · 3.37 KB
/
make-patch.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
from multiprocessing.pool import ThreadPool, TimeoutError
from sys import argv
import os, csv, time, subprocess, hashlib
devkitppc = os.environ.get('DEVKITPPC')
path_cc = os.path.join(devkitppc, "bin", "powerpc-eabi-gcc")
path_objcopy = os.path.join(devkitppc, "bin", "powerpc-eabi-objcopy")
gct_print = False
stage1_hash_md5 = ""
stage1_size = 0
extra_build_flags = []
def build(game):
print(game["Title"])
flags = []
flags.append("-D" + game["Title"] + "=1")
title_str = game["Title"]
# pad to 9 bytes
if len(title_str) == 7:
title_str += "\\0\\0"
flags.append("-DPAYLOAD=\"" + title_str + "\"")
for key, value in game.items():
if key != "Title":
flags.append("-D" + key + "=" + value)
flags.append("-DSTAGE1_HASH_MD5_STR=\"" + stage1_hash_md5 + "\"")
flags.append("-DSTAGE1_SIZE=" + str(stage1_size))
flags += extra_build_flags
out_path = os.path.join("build", game["Title"])
subprocess.run([path_cc, "-o" + out_path + ".o", "-xassembler-with-cpp", "wwfcPatch.s", "-c", "-mregnames", "-I" + os.path.join("..", "include")] + flags).check_returncode()
subprocess.run([path_objcopy, out_path + ".o", out_path + ".bin", "-O", "binary"])
raw = open(out_path + ".bin", "rb").read()
text = ""
while True:
assert(len(raw) >= 8)
text += "{:02X}{:02X}{:02X}{:02X} {:02X}{:02X}{:02X}{:02X}\n".format(raw[0], raw[1], raw[2], raw[3], raw[4], raw[5], raw[6], raw[7])
raw = raw[8:]
if len(raw) == 0:
break
if gct_print:
print("$WiiLink WFC [" + game["Title"] + "]\n" + text)
with open(out_path + ".txt", "w") as txtfile:
txtfile.write(text)
if __name__ == "__main__":
try:
os.mkdir("build")
except:
pass
game_list = []
with open(os.path.join("..", "gamedefs.csv")) as csv_file:
reader = csv.DictReader(csv_file, delimiter=",", dialect="excel")
for game in reader:
game_list.append(game)
try:
stage1_data = open(os.path.join("..", "stage1", "build", "stage1.bin"), "rb").read()
stage1_hash_md5 = hashlib.md5(b"\x01\x2C" + stage1_data).hexdigest()
stage1_size = len(stage1_data)
except:
print('WARNING: Unable to read stage1.bin, using all zero hash')
stage1_hash_md5 = "0" * 16
stage1_size = 0
pool_count = -1
title_id = ""
for i in range(len(argv)):
if i == 0:
continue
if argv[i].startswith("-j"):
if len(argv[i]) == 2:
pool_count = 0
else:
pool_count = int(argv[i][2:])
elif argv[i].startswith("-g") or argv[i].startswith("-t"):
title_id = argv[i][2:]
elif argv[i] == '-p':
gct_print = True
elif argv[i].startswith("-D"):
extra_build_flags.append(argv[i])
if title_id != "":
map_game_list = []
for game in game_list:
if game["Title"].startswith(title_id):
map_game_list.append(game)
if map_game_list == []:
print("No title for " + title_id)
else:
map_game_list = game_list
if pool_count == -1:
for game in map_game_list:
build(game)
exit()
if pool_count == 0:
pool = ThreadPool()
else:
pool = ThreadPool(pool_count)
pool.map(build, map_game_list)
pool.close()