kirby64/tools/progress2.py
2022-12-18 20:26:39 -05:00

154 lines
4.0 KiB
Python

#!/usr/bin/env python3
import argparse
import csv
try:
import git
except Exception as e:
pass
import os
import re
parser = argparse.ArgumentParser(description="Computes current progress throughout the whole project.")
parser.add_argument("-m", "--matching", dest='matching', action='store_true',
help="Output matching progress instead of decompilation progress")
parser.add_argument("-c", "--csv", dest="csv", action="store_true",
help="Output results in CSV format")
args = parser.parse_args()
NON_MATCHING_PATTERN = r"#ifdef\s+NON_MATCHING.*?#else\nGLOBAL_ASM\s*\(\s*\"(.*?)\"\s*\).*?#endif"
M2C_PATTERN = r"#ifdef\s+MIPS_TO_C.*?#else\nGLOBAL_ASM\s*\(\s*\"(.*?)\"\s*\).*?#endif"
def GetNonMatchingFunctions(files):
functions = []
for file in files:
with open(file) as f:
functions += re.findall(NON_MATCHING_PATTERN, f.read(), re.DOTALL)
if not args.matching:
with open(file) as f:
functions += re.findall(M2C_PATTERN, f.read(), re.DOTALL)
return functions
def ReadAllLines(fileName):
lineList = list()
with open(fileName) as f:
lineList = f.readlines()
return lineList
def GetFiles(path, ext):
files = []
for r, d, f in os.walk(path):
for file in f:
if file.endswith(ext):
files.append(os.path.join(r, file))
return files
nonMatchingFunctions = GetNonMatchingFunctions(GetFiles("src", ".c")) if not args.matching else []
def GetNonMatchingSize(path):
size = 0
asmFiles = GetFiles(path, ".s")
for asmFilePath in asmFiles:
if asmFilePath not in nonMatchingFunctions:
asmLines = ReadAllLines(asmFilePath)
for asmLine in asmLines:
if (asmLine.startswith("/*")):
size += 4
return size
mapFile = ReadAllLines("build/us/kirby.us.map")
src = 0
code = 0
boot = 0
ovl = 0
asm = 0
for line in mapFile:
lineSplit = list(filter(None, line.split(" ")))
if (len(lineSplit) == 4 and lineSplit[0].startswith(".")):
section = lineSplit[0]
size = int(lineSplit[2], 16)
objFile = lineSplit[3]
if (section == ".text"):
if (objFile.startswith("build/us/src")):
src += size
if (objFile.startswith("build/us/libultra.a")):
src += size
if (objFile.startswith("build/us/libn_audio.a")):
src += size
elif (objFile.startswith("build/us/asm")):
asm += size
nonMatchingASM = GetNonMatchingSize("asm/non_matchings")
src -= nonMatchingASM
asm += nonMatchingASM
total_decompilable_code = \
0x38DF0 + \
0x22EA0 + \
0x2DCF0 + \
0x3F210 + \
0x8EC0 + \
0x29860 + \
0x3CC0 + \
0x29F50 + \
0x6C20 + \
0x4AE50 + \
0x18210 + \
0x5920 + \
0x78C0 + \
0xA8A0 + \
0x7CC0 + \
0xB270 + \
0x142E0 + \
0x9CB0 + \
0x94C0 + \
0x11120 + \
0xE0
codeSize = total_decompilable_code
# Do I go with my approach or oot's?
total = src + asm
total2 = codeSize
srcPct = 100 * src / total
asmPct = 100 * asm / total
srcPct2 = 100 * src / total2
asmPct2 = 100 * asm / total2
compiled_bytes = total
bytesPerShard = compiled_bytes / 74
adjective = "decompiled" if not args.matching else "matched"
print("------------------------------------")
print(str(total) + " total bytes of decompilable code.")
print(str(src) + " bytes " + adjective + " in src.\n")
print(" OoT Approach (src + asm): " + str(srcPct) + "%")
print("Kirby64 Approach (pre-calculated): " + str(srcPct2) + "%\n")
print("------------------------------------")
heartPieces = int(src / bytesPerShard)
rupees = int(((src % bytesPerShard) * 100) / bytesPerShard)
if (rupees > 0):
print("You have " + str(heartPieces) + "/74 Crystal Shards and " + str(rupees) + " rupee(s).")
else:
print("You have " + str(heartPieces) + "/74 Crystal Shards.")
print("------------------------------------")