175 lines
6.0 KiB
Python
Executable File
175 lines
6.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
from glob import glob
|
|
from objlib import get_obj_funcs
|
|
import os
|
|
import json
|
|
import re
|
|
|
|
EXPECTED_TOTAL_FUNCS = 1991
|
|
EXPECTED_TOTAL_BYTES = 490440
|
|
APPVEYOR_CACHE = 'C:\\mgs-cache\\last-progress.json'
|
|
|
|
OVERLAY_NAMES = ['abst', 'brf', 'camera', 'change', 'd00a', 'd01a', 'd03a', 'd11c', 'd16e', 'd18a',
|
|
'd18ar', 'demosel', 'ending', 'endingr', 'opening', 'option', 'preope', 'rank', 'roll', 's00a',
|
|
's01a', 's02a', 's02b', 's02c', 's02d', 's02e', 's03a', 's03ar', 's03b', 's03c', 's03d', 's03dr',
|
|
's03e', 's03er', 's04a', 's04b', 's04br', 's04c', 's05a', 's06a', 's07a', 's07b', 's07br', 's07c',
|
|
's07cr', 's08a', 's08b', 's08br', 's08c', 's08cr', 's09a', 's09ar', 's10a', 's10ar', 's11a',
|
|
's11b', 's11c', 's11d', 's11e', 's11g', 's11h', 's11i', 's12a', 's12b', 's12c', 's13a', 's14e',
|
|
's15a', 's15b', 's15c', 's16a', 's16b', 's16c', 's16d', 's17a', 's17ar', 's18a', 's18ar', 's19a',
|
|
's19ar', 's19b', 's19br', 's20a', 's20ar', 'select', 'select1', 'select2', 'select3', 'select4',
|
|
'selectd', 'sound', 'title']
|
|
EXPECTED_OVERLAY_COUNT = 92
|
|
EXPECTED_OVERLAY_TOTAL_SIZE = 7881522
|
|
|
|
assert len(OVERLAY_NAMES) == EXPECTED_OVERLAY_COUNT
|
|
|
|
objs = glob('../obj/**/*.obj', recursive=True)
|
|
|
|
def deps_has(deps, name):
|
|
for dep in deps:
|
|
if name in dep:
|
|
return True
|
|
return False
|
|
|
|
c_funcs = 0
|
|
s_funcs = 0
|
|
c_bytes = 0
|
|
s_bytes = 0
|
|
|
|
overlays_c_funcs = 0
|
|
overlays_s_funcs = 0
|
|
overlays_c_bytes = 0
|
|
overlays_s_bytes = 0
|
|
|
|
done_names = {}
|
|
|
|
for obj in objs:
|
|
deps_file = obj.replace('.obj', '.c.asm.preproc.deps')
|
|
is_c_obj = os.path.exists(deps_file)
|
|
deps = []
|
|
if os.path.exists(deps_file):
|
|
with open(deps_file) as f:
|
|
deps = [line.rstrip() for line in f]
|
|
|
|
if 'psyq' in obj or '_fixme' in obj or 'snake_vr' in obj or "program_bottom" in obj:
|
|
continue
|
|
|
|
is_overlay = 'overlays' in obj
|
|
|
|
for name, segments in get_obj_funcs(obj):
|
|
name = name.decode()
|
|
code_len = sum([len(x[1]) for x in segments])
|
|
if name in done_names or "SafetyCheck" in name:
|
|
# duplicate because the original INCLUDE_ASM objs are read too, lazy fix
|
|
continue
|
|
done_names[name] = obj
|
|
if not is_c_obj or deps_has(deps, name):
|
|
if not is_overlay:
|
|
s_funcs += 1
|
|
s_bytes += code_len
|
|
else:
|
|
overlays_s_funcs += 1
|
|
overlays_s_bytes += code_len
|
|
else:
|
|
if not is_overlay:
|
|
c_funcs += 1
|
|
# to generate matches.txt
|
|
#print("0x" + name[name.rfind("_")+1:])
|
|
c_bytes += code_len
|
|
else:
|
|
overlays_c_funcs += 1
|
|
overlays_c_bytes += code_len
|
|
|
|
total_funcs = c_funcs + s_funcs
|
|
total_bytes = c_bytes + s_bytes
|
|
|
|
overlay_count = 0
|
|
overlay_bytes = 0
|
|
for overlay in OVERLAY_NAMES:
|
|
overlay_bin = os.path.join("../obj", f"{overlay}.bin")
|
|
if not os.path.exists(overlay_bin):
|
|
continue
|
|
|
|
overlay_count += 1
|
|
overlay_bytes += os.path.getsize(overlay_bin)
|
|
|
|
c_funcs_extra = ''
|
|
c_bytes_extra = ''
|
|
overlays_c_funcs_extra = ''
|
|
overlays_c_bytes_extra = ''
|
|
overlay_count_extra = ''
|
|
overlay_bytes_extra = ''
|
|
|
|
if os.environ.get('APPVEYOR'):
|
|
dirr = os.path.dirname(APPVEYOR_CACHE)
|
|
if not os.path.exists(dirr):
|
|
os.mkdir(dirr)
|
|
|
|
if os.path.exists(APPVEYOR_CACHE):
|
|
with open(APPVEYOR_CACHE, 'r') as f:
|
|
delta_obj = json.load(f)
|
|
|
|
c_funcs_delta = c_funcs - delta_obj['c_funcs']
|
|
c_bytes_delta = c_bytes - delta_obj['c_bytes']
|
|
c_funcs_extra = ' ({:+})'.format(c_funcs_delta)
|
|
c_bytes_extra = ' ({:+})'.format(c_bytes_delta)
|
|
|
|
overlays_c_funcs_delta = overlays_c_funcs - (delta_obj['overlays_c_funcs'] if 'overlays_c_funcs' in delta_obj else 0)
|
|
overlays_c_bytes_delta = overlays_c_bytes - (delta_obj['overlays_c_bytes'] if 'overlays_c_bytes' in delta_obj else 0)
|
|
overlays_c_funcs_extra = ' ({:+})'.format(overlays_c_funcs_delta)
|
|
overlays_c_bytes_extra = ' ({:+})'.format(overlays_c_bytes_delta)
|
|
|
|
overlay_count_delta = overlay_count - (delta_obj['overlay_count'] if 'overlay_count' in delta_obj else 0)
|
|
overlay_bytes_delta = overlay_bytes - (delta_obj['overlay_bytes'] if 'overlay_bytes' in delta_obj else 0)
|
|
overlay_count_extra = ' ({:+})'.format(overlay_count_delta)
|
|
overlay_bytes_extra = ' ({:+})'.format(overlay_bytes_delta)
|
|
|
|
with open(APPVEYOR_CACHE, 'w') as f:
|
|
json.dump(dict(c_funcs=c_funcs, c_bytes=c_bytes,
|
|
overlay_count=overlay_count, overlay_bytes=overlay_bytes,
|
|
overlays_c_funcs=overlays_c_funcs, overlays_c_bytes=overlays_c_bytes
|
|
), f)
|
|
|
|
msg = os.environ.get('APPVEYOR_REPO_COMMIT_MESSAGE')
|
|
if msg:
|
|
msg = re.sub(r'#(\d+)', r'[#\1](https://github.com/FoxdieTeam/mgs_reversing/pull/\1)', msg)
|
|
print(msg)
|
|
msg_ext = os.environ.get('APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED')
|
|
if msg_ext:
|
|
print(msg_ext)
|
|
|
|
print('SLPM_862.47 reversed funcs: {:,}{} / {:,} | {:.2f}%'.format(
|
|
c_funcs,
|
|
c_funcs_extra,
|
|
total_funcs,
|
|
c_funcs / total_funcs * 100))
|
|
|
|
print('SLPM_862.47 reversed bytes: {:,}{} / {:,} | {:.2f}%'.format(
|
|
c_bytes,
|
|
c_bytes_extra,
|
|
total_bytes,
|
|
c_bytes / total_bytes * 100))
|
|
|
|
print('Overlays: {:,}{} funcs, {:,}{} bytes reversed'.format(
|
|
overlays_c_funcs,
|
|
overlays_c_funcs_extra,
|
|
overlays_c_bytes,
|
|
overlays_c_bytes_extra))
|
|
|
|
print('Imported overlays count: {:,}{} / {:,} | {:.2f}%'.format(
|
|
overlay_count,
|
|
overlay_count_extra,
|
|
EXPECTED_OVERLAY_COUNT,
|
|
overlay_count / EXPECTED_OVERLAY_COUNT * 100))
|
|
|
|
print('Imported overlays bytes: {:,}{} / {:,} | {:.2f}%'.format(
|
|
overlay_bytes,
|
|
overlay_bytes_extra,
|
|
EXPECTED_OVERLAY_TOTAL_SIZE,
|
|
overlay_bytes / EXPECTED_OVERLAY_TOTAL_SIZE * 100))
|
|
|
|
if total_funcs != EXPECTED_TOTAL_FUNCS or total_bytes != EXPECTED_TOTAL_BYTES:
|
|
print('Warning: Totals seem incorrect, did someone forget to delete a .s?')
|
|
print('.. or rename a .s without renaming the xdef inside it?')
|