summaryrefslogtreecommitdiff
path: root/progress.py
diff options
context:
space:
mode:
authorAloXado320 <38191089+AloXado320@users.noreply.github.com>2023-11-05 15:57:14 -0500
committerGitHub <noreply@github.com>2023-11-05 13:57:14 -0700
commit959c933714e07e9832851df27a04ded23df00d81 (patch)
treea74bffb36cc8626af128e23162cd401dd7334d09 /progress.py
parent596fa15e8dd834eac7c2af2311f61d018a038e2f (diff)
Document progress.py and correct readme (#483)
* Document progress.py and adjust readme
Diffstat (limited to 'progress.py')
-rw-r--r--progress.py394
1 files changed, 268 insertions, 126 deletions
diff --git a/progress.py b/progress.py
index 3db8bc38a..734d61d7f 100644
--- a/progress.py
+++ b/progress.py
@@ -6,51 +6,61 @@ import csv
import os
import re
+# Script arguments.
parser = argparse.ArgumentParser(description="Computes current progress throughout the whole project.")
parser.add_argument("format", nargs="?", default="text", choices=["text", "verbose", "totalBadge", "gameBadge", "mainBadge", "endingBadge", "racingBadge", "audioBadge", "osBadge", "bytesToDecompile", "globalAsmFuncs", "m2cFuncs", "nonmatchingFuncs"])
+parser.add_argument("-d", "--debug", dest='debug', action='store_true',
+ help="Adds additional debug information, outputs files parsed and score for each file")
+parser.add_argument("-n", "--nonmatching", dest='nonmatching', action='store_true',
+ help="Tracks progress counting non matching functions")
args = parser.parse_args()
-NON_MATCHING_PATTERN = r"#ifdef\s+NON_MATCHING.*?#pragma\s+GLOBAL_ASM\s*\(\s*\"(.*?)\"\s*\).*?#endif"
-MIPS_TO_C_FUNC_COUNT_PATTERN = r"#ifdef\s+MIPS_TO_C.*?GLOBAL_ASM\s*\(\s*\"(.*?)\"\s*\).*?#endif"
-NON_MATCHING_FUNC_COUNT_PATTERN = r"#ifdef\s+NON_MATCHING.*?GLOBAL_ASM\s*\(\s*\"(.*?)\"\s*\).*?#endif"
-GLOBAL_ASM_FUNC_COUNT_PATTERN = r"GLOBAL_ASM\s*\(\s*\"(.*?)\"\s*\)."
+# Patterns for "NON_MATCHING" defines, one of those is used depending of the project.
+NON_MATCHING_FUNC_PATTERN = r"#ifdef\s+NON_MATCHING.*?GLOBAL_ASM\s*\(\s*\"(.*?)\"\s*\).*?#endif"
+NON_MATCHING_PRAGMA_PATTERN = r"#ifdef\s+NON_MATCHING.*?#pragma\s+GLOBAL_ASM\s*\(\s*\"(.*?)\"\s*\).*?#endif"
+# Gets the assembly file around a NON_MATCHING define.
def GetNonMatchingFunctions(files):
functions = []
for file in files:
with open(file) as f:
- functions += re.findall(NON_MATCHING_PATTERN, f.read(), re.DOTALL)
+ functions += re.findall(NON_MATCHING_FUNC_PATTERN, f.read(), re.DOTALL)
+ functions += re.findall(NON_MATCHING_PRAGMA_PATTERN, f.read(), re.DOTALL)
return functions
+# Pattern for "MIPS_TO_C" define
+MIPS_TO_C_FUNC_PATTERN = r"#ifdef\s+MIPS_TO_C.*?GLOBAL_ASM\s*\(\s*\"(.*?)\"\s*\).*?#endif"
+
+# Gets the assembly file around a MIPS_TO_C define.
def CountMipsToCFunctions(files):
functions = []
for file in files:
with open(file) as f:
- functions += re.findall(MIPS_TO_C_FUNC_COUNT_PATTERN, f.read(), re.DOTALL)
+ functions += re.findall(MIPS_TO_C_FUNC_PATTERN, f.read(), re.DOTALL)
return functions
-def CountNonMatchingFunctions(files):
- functions = []
- for file in files:
- with open(file) as f:
- functions += re.findall(NON_MATCHING_FUNC_COUNT_PATTERN, f.read(), re.DOTALL)
+# Pattern for "GLOBAL_ASM" macros
+GLOBAL_ASM_FUNC_PATTERN = r"GLOBAL_ASM\s*\(\s*\"(.*?)\"\s*\)."
- return functions
+# Gets the assembly file defined in a GLOBAL_ASM macro.
def CountGlobalAsmFunctions(files):
functions = []
for file in files:
with open(file) as f:
- functions += re.findall(GLOBAL_ASM_FUNC_COUNT_PATTERN, f.read(), re.DOTALL)
+ functions += re.findall(GLOBAL_ASM_FUNC_PATTERN, f.read(), re.DOTALL)
return functions
+# Regex to find a non static C function. Consists of 3 groups, comment documentation, function type and function name.
+# We only take the function name here for simple needs.
C_FUNCTION_PATERN_REGEX = r'^(?<!static\s)(?:(\/[*][*!][*]*\n(?:[^/]*\n)+?\s*[*]\/\n)(?:\s*)*?)?(?:\s*UNUSED\s+)?([^\s]+)\s(?:\s|[*])*?([0-9A-Za-z_]+)\s*[(][^)]*[)]\s*{'
+# Gets the function name and the C file which has it.
def GetCFunctions(files):
functions = []
@@ -58,14 +68,18 @@ def GetCFunctions(files):
with open(file) as f:
source_code = f.read()
+ # Parse regex pattern
matches = re.finditer(C_FUNCTION_PATERN_REGEX, source_code, re.MULTILINE)
for match in matches:
+ # Group 3 has functions names taken from the regex
function_name = match.group(3)
+ # Get the C file which has the function
functions.append((file, function_name))
return functions
+# Reads the string of all lines in a file.
def ReadAllLines(fileName):
lineList = list()
with open(fileName) as f:
@@ -73,6 +87,7 @@ def ReadAllLines(fileName):
return lineList
+# Gets the file on an extension in a path and it's subdirectories.
def GetFiles(path, ext):
files = []
@@ -83,6 +98,7 @@ def GetFiles(path, ext):
return files
+# Gets the file on an extension in a path and it's subdirectories except the ones under a blacklist.
def GetFilesBlackList(path, ext, blacklist=[]):
files = []
@@ -95,163 +111,237 @@ def GetFilesBlackList(path, ext, blacklist=[]):
return files
+# Gets the file on an extension in a path and only it's subdirectories under a whilelist.
def GetFilesWhiteList(path, ext, whitelist=[]):
files = []
- for root, dirs, filenames in os.walk(path):
- if root == path or any(subdir in root for subdir in whitelist):
- for filename in filenames:
- if filename.endswith(ext):
- files.append(os.path.join(root, filename))
+ for r, d, f in os.walk(path):
+ if r == path or any(subdir in r for subdir in whitelist):
+ for file in f:
+ if file.endswith(ext):
+ files.append(os.path.join(r, file))
return files
-gameExclusiveDirs=["audio", "os", "ending", "racing"]
+# Segments have their own folder, used later for the following:
+# Whilelist (C Functions list, includes src folder and only these subdirectories).
+# Blacklist (For main segment, includes all folders in nonmatching except these subdirectories).
+gameExclusiveDirs=["ending", "racing", "os", "audio"]
-nonMatchingFunctions = GetNonMatchingFunctions(GetFiles("src", ".c"))
+# Get non matching functions and count how many there is.
+# If --nonmatching is set, then the score counts their progress by excluding their asm file.
+nonMatchingFunctions = GetNonMatchingFunctions(GetFiles("src", ".c")) if args.nonmatching else []
+TotalNonMatchingFunctions = len(GetNonMatchingFunctions(GetFiles("src", ".c")))
+
+# Counts how many functions are under a MIPS_TO_C define and GLOBAL_ASM macro respectively.
TotalMipsToCFunctions = len(CountMipsToCFunctions(GetFiles("src", ".c")))
-TotalNonMatchingFunctions = len(CountNonMatchingFunctions(GetFiles("src", ".c")))
TotalGlobalAsmFunctions = len(CountGlobalAsmFunctions(GetFiles("src", ".c")))
-TotalCFunctions = len(GetCFunctions(GetFilesWhiteList("src", ".c", gameExclusiveDirs)))
-TotalCFunctions -= TotalGlobalAsmFunctions + (TotalGlobalAsmFunctions - TotalNonMatchingFunctions - TotalMipsToCFunctions)
+# Counts how many functions are decompiled. To account for the uncompiled functions,
+# we do a bit of subtraction from functions with NON_MATCHING and MIPS_TO_C defines
+# and GLOBAL_ASM macros without the defines mentioned.
+# If --nonmatching is set, then we exclude non matching count subsraction.
+TotalCFunctions = len(GetCFunctions(GetFilesWhiteList("src", ".c", gameExclusiveDirs)))
+TotalCFunctions -= TotalGlobalAsmFunctions + (TotalGlobalAsmFunctions - (TotalNonMatchingFunctions if args.nonmatching else 0) - TotalMipsToCFunctions)
-def GetNonMatchingSize(path):
+# Gets the non matching size for each segment depending of the path set.
+def GetNotMatchingSize(path):
size = 0
+ files = []
+ # Asm non matching files for main segment.
if (path == "main"):
- size += getDataBlackList("asm/non_matchings", gameExclusiveDirs)
-
- elif (path == "racing"):
- size += getData("asm/non_matchings/racing")
+ files = GetFilesBlackList("asm/non_matchings", ".s", gameExclusiveDirs)
+ # Asm non matching files for ending segment.
elif (path == "ending"):
- size += getData("asm/non_matchings/ending")
+ files = GetFiles("asm/non_matchings/ending", ".s")
+ # Asm non matching files for racing segment.
+ elif (path == "racing"):
+ files = GetFiles("asm/non_matchings/racing", ".s")
+
+ # Asm non matching files for libultra segment.
elif (path == "os"):
- size += getData("asm/non_matchings/os")
+ files = GetFiles("asm/non_matchings/os", ".s")
+ # Asm non matching files for libultra segment.
elif (path == "audio"):
- size += getData("asm/non_matchings/audio")
-
- else: size = getData(path)
+ files = GetFiles("asm/non_matchings/audio", ".s")
- return size
-
-def getData(path):
- size = 0
-
- asmFiles = GetFiles(path, ".s")
-
- for asmFilePath in asmFiles:
- if asmFilePath not in nonMatchingFunctions:
- asmLines = ReadAllLines(asmFilePath)
+ # Asm non matching files for a path specified, in a general case:
+ # asm/non_matchings and it's subdirectories (for total segment).
+ else:
+ files = GetFiles(path, ".s")
- for asmLine in asmLines:
- if (asmLine.startswith("/*")):
- size += 4
+ # Get the total size for the files specified above.
+ size = GetAsmSize(files)
return size
-def getDataBlackList(path, bl=[]):
+# Gets the assembly size of a file using a text pattern.
+def GetAsmSize(path):
size = 0
-
- asmFiles = GetFilesBlackList(path, ".s", bl)
+ asmFiles = path
for asmFilePath in asmFiles:
if asmFilePath not in nonMatchingFunctions:
asmLines = ReadAllLines(asmFilePath)
+ # Checks each line if it starts with a comment, for context:
+ # split/splat programs generate assembly files with comments to
+ # provide additional information of the mips instruction such as:
+ # /* Hex Location - Address location - Instruction in Hex */
for asmLine in asmLines:
+ # If there's a comment, assume there's an instruction there
+ # as well, each mips instruction is 4 bytes long.
if (asmLine.startswith("/*")):
size += 4
return size
-mapFile = ReadAllLines("build/us/mk64.us.map")
-src = 0
+# Size for all object segments.
+total = 0
+
+# Sizes for each object segment.
segMain = 0
segEnding = 0
segRacing = 0
-audio = 0
libultra = 0
+audio = 0
+
+# List of objects parsed for all segments (Debug).
+obj_list_total = []
+
+# List of objects parsed for each segment (Debug).
+obj_list_game = []
+obj_list_main = []
+obj_list_ending = []
+obj_list_racing = []
+obj_list_libultra = []
+obj_list_audio = []
+# Read the linker map file, has correct results with a matching one.
+mapFile = ReadAllLines("build/us/mk64.us.map")
+
+# Check for every line in the map file.
for line in mapFile:
lineSplit = list(filter(None, line.split(" ")))
+ # Check if is a memory segment list by a pattern.
if (len(lineSplit) == 4 and lineSplit[0].startswith(".")):
section = lineSplit[0]
size = int(lineSplit[2], 16)
objFile = lineSplit[3]
- if (section == ".text"):
+ # Checks for the ".text" line to get the function size of a file and
+ # store the size for each segment by checking their respective folders
+ # Ensure we parse files that have an actual size value.
+ # Also list object files parsed (Debug).
+ if (section == ".text") and size > 0:
+ # This takes the size of every C file in the src directory
+ # including subdirectories.
if (objFile.startswith("build/us/src")):
- src += size
+ total += size
+ if args.debug:
+ obj_list_total.append("File: " + str(objFile.rstrip("\n")) + " - Size: " + str(size))
+ # This takes the size of every C file in the src directory
+ # excluding subdirectories using an additional check.
if (objFile.startswith("build/us/src") and objFile.count("/") == 3):
segMain += size
+ if args.debug:
+ obj_list_main.append("File: " + str(objFile.rstrip("\n")) + " - Size: " + str(size))
+ # Object size for ending segment.
if (objFile.startswith("build/us/src/ending")):
segEnding += size
+ if args.debug:
+ obj_list_ending.append("File: " + str(objFile.rstrip("\n")) + " - Size: " + str(size))
+ # Object size for racing segment.
if (objFile.startswith("build/us/src/racing")):
segRacing += size
+ if args.debug:
+ obj_list_racing.append("File: " + str(objFile.rstrip("\n")) + " - Size: " + str(size))
+ # Object size for libultra segment.
if (objFile.startswith("build/us/src/os")):
libultra += size
+ if args.debug:
+ obj_list_libultra.append("File: " + str(objFile.rstrip("\n")) + " - Size: " + str(size))
+ # Object size for audio segment.
if (objFile.startswith("build/us/src/audio")):
audio += size
+ if args.debug:
+ obj_list_audio.append("File: " + str(objFile.rstrip("\n")) + " - Size: " + str(size))
+
+# List game object files (Main + Ending + Racing) (Debug).
+obj_list_game = obj_list_main + obj_list_ending + obj_list_racing
+
+# Asm size for all segments not decompiled.
+nonMatchingTotal = GetNotMatchingSize("asm/non_matchings")
+
+# Asm size for each segment not decompiled.
+nonMatchingMain = GetNotMatchingSize("main")
+nonMatchingEnding = GetNotMatchingSize("ending")
+nonMatchingRacing = GetNotMatchingSize("racing")
+nonMatchingLibultra = GetNotMatchingSize("os")
+nonMatchingAudio = GetNotMatchingSize("audio")
+
+# Set total size for each segment.
+seg_main_size = segMain # 744112
+seg_ending_size = segEnding # 20032
+seg_racing_size = segRacing # 174224
+libultra_size = libultra # 48848
+audio_size = audio # 86912
+
+# Set total size for game segment (Main + Ending + Racing).
+game = segMain + segEnding + segRacing # 938368
+game_code_size = seg_main_size + seg_ending_size + seg_racing_size # 938368
-nonMatchingASM = GetNonMatchingSize("asm/non_matchings")
-
-nonMatchingMain = GetNonMatchingSize("main")
-nonMatchingEnding = GetNonMatchingSize("ending")
-nonMatchingRacing = GetNonMatchingSize("racing")
-nonMatchingLibultra = GetNonMatchingSize("os")
-nonMatchingAudio = GetNonMatchingSize("audio")
-
-game = segMain + segEnding + segRacing
+# Set total size for all segments.
+total_code_size = game_code_size + libultra_size + audio_size # 1074128
+# Set progress size depending of the size of non matching files for each segments.
segMain -= nonMatchingMain
segEnding -= nonMatchingEnding
segRacing -= nonMatchingRacing
-audio -= nonMatchingAudio
libultra -= nonMatchingLibultra
+audio -= nonMatchingAudio
-src -= nonMatchingASM
+# Set progress size for game segment (Main + Ending + Racing).
game -= nonMatchingMain + nonMatchingEnding + nonMatchingRacing
-decompilable = src
-
-seg_main_size = 744112
-seg_ending_size = 20032
-seg_racing_size = 174224
-
-libultra_size = 48848
-audio_size = 86912
-
-game_code_size = seg_main_size + seg_ending_size + seg_racing_size # 938368
-total_code_size = seg_main_size + seg_ending_size + seg_racing_size + libultra_size + audio_size # 1074128
+# Set progress size for all segments.
+total -= nonMatchingTotal
+# Set remaining size substacting total size with progress size.
+decompilable = total
remaining_size = total_code_size - decompilable
+# Set percentage progress for each segment.
segMainPct = 100 * segMain / seg_main_size
segEndingPct = 100 * segEnding / seg_ending_size
segRacingPct = 100 * segRacing / seg_racing_size
-
libultraPct = 100 * libultra / libultra_size
audioPct = 100 * audio / audio_size
+# Set percentage progress for game segment (Main + Ending + Racing).
gamePct = 100 * game / game_code_size
-srcPct = 100 * src / total_code_size
-def get_string_from_table(num, table):
- if 0 <= num < len(table):
- return table[num]
+# Set percentage progress for all segments.
+totalPct = 100 * total / total_code_size
+
+# Gets a string from a table index position.
+def get_string_from_table(idx, table):
+ if 0 <= idx < len(table):
+ return table[idx]
else:
return "Number out of range"
+# Finds the closest divisible of a number to get a result without decimals.
def find_closest_divisible(number, divisor):
closest_smaller = number - (number % divisor)
closest_larger = closest_smaller + divisor
@@ -261,6 +351,7 @@ def find_closest_divisible(number, divisor):
else:
return closest_larger
+# Centers a text around a specified filled character and how long it should be.
def center_text(text, total_width, fill_character=" "):
empty_spaces = total_width - len(text)
left_padding = empty_spaces // 2
@@ -268,6 +359,8 @@ def center_text(text, total_width, fill_character=" "):
centered_text = fill_character * left_padding + text + fill_character * right_padding
return centered_text
+# Moves a base character around a filled character depending of the position set.
+# Simulates a lap line progress like in the original game.
def move_character_from_bar(position, total_length, charbase="0", charfill="1"):
if position < 0:
position = 0
@@ -280,6 +373,8 @@ def move_character_from_bar(position, total_length, charbase="0", charfill="1"):
return "".join(line)
+# Checks the progress of a condition depending of where the total is.
+# Tracks the progress which cup are we using a table set by a condition.
def check_table_cond(cond, total, table):
if total > cond:
sym = " (V)"
@@ -290,6 +385,14 @@ def check_table_cond(cond, total, table):
return str(table[cond]) + str(sym)
+# Lists detailed progress for each badge set and the object files parsed on it (Debug).
+def list_detailed_progress_and_files(pct, prog, size, objlist, charseg):
+ print("Percentage progress: " + str(pct) + "%")
+ print("Size progress: " + str(prog))
+ print("Size total: " + str(size))
+ print(str(charseg) + " object files: \n" + "\n".join(objlist))
+
+# All the cups in the game in order.
mkCups = [
"Mushroom Cup",
"Flower Cup",
@@ -297,6 +400,7 @@ mkCups = [
"Special Cup",
]
+# All the courses in the game in order.
mkCourses = [
"Luigi Raceway",
"Moo Moo Farm",
@@ -316,70 +420,108 @@ mkCourses = [
"Rainbow Road",
]
+# Shows total segment progress.
if args.format == 'totalBadge':
- print(str(round(srcPct, 2))+"%")
+ if not args.debug:
+ print(str(round(totalPct, 2))+"%")
+ else:
+ list_detailed_progress_and_files(totalPct, total, total_code_size, obj_list_total, "Total")
+# Shows game segment progress (Main + Ending + Racing).
elif args.format == 'gameBadge':
- print(str(round(gamePct, 2))+"%")
+ if not args.debug:
+ print(str(round(gamePct, 2))+"%")
+ else:
+ list_detailed_progress_and_files(gamePct, game, game_code_size, obj_list_game, "Game")
+# Shows main segment progress.
elif args.format == 'mainBadge':
- print(str(round(segMainPct, 2))+"%")
+ if not args.debug:
+ print(str(round(segMainPct, 2))+"%")
+ else:
+ list_detailed_progress_and_files(segMainPct, segMain, seg_main_size, obj_list_main, "Main")
+# Shows ending segment progress.
elif args.format == 'endingBadge':
- print(str(round(segEndingPct, 2))+"%")
+ if not args.debug:
+ print(str(round(segEndingPct, 2))+"%")
+ else:
+ list_detailed_progress_and_files(segEndingPct, segEnding, seg_ending_size, obj_list_ending, "Ending")
+# Shows racing segment progress.
elif args.format == 'racingBadge':
- print(str(round(segRacingPct, 2))+"%")
-elif args.format == 'audioBadge':
- print(str(round(audioPct, 2))+"%")
+ if not args.debug:
+ print(str(round(segRacingPct, 2)) + "%")
+ else:
+ list_detailed_progress_and_files(segRacingPct, segRacing, seg_racing_size, obj_list_racing, "Racing")
+# Shows libultra segment progress.
elif args.format == 'osBadge':
- print(str(round(libultraPct, 2))+"%")
+ if not args.debug:
+ print(str(round(libultraPct, 2))+"%")
+ else:
+ list_detailed_progress_and_files(libultraPct, libultra, libultra_size, obj_list_libultra, "Libultra")
+# Shows audio segment progress.
+elif args.format == 'audioBadge':
+ if not args.debug:
+ print(str(round(audioPct, 2)) + "%")
+ else:
+ list_detailed_progress_and_files(audioPct, audio, audio_size, obj_list_audio, "Audio")
+# Shows current bytes left to decompile out of the total.
elif args.format == 'bytesToDecompile':
print(str(remaining_size)+" of "+str(total_code_size)+"\n")
+# Shows how many GLOBAL_ASM functions are left.
elif args.format == 'globalAsmFuncs':
print(str(TotalGlobalAsmFunctions))
+# Shows how many MIPS_TO_C functions are left.
elif args.format == 'm2cFuncs':
print(str(TotalMipsToCFunctions))
+# Shows how many NON_MATCHING functions are left.
elif args.format == 'nonmatchingFuncs':
print(str(TotalNonMatchingFunctions))
+# Shows decompilation progress output in a fancy way.
elif args.format == 'text':
- bytesPerTotalLaps = total_code_size // 47
- srcDivNear = find_closest_divisible(src, 49)
- lapTotalCounts = int(srcDivNear / bytesPerTotalLaps)
- curLapProgress = int(((srcDivNear % bytesPerTotalLaps) * 66) / (bytesPerTotalLaps))
- curLapCount = int((lapTotalCounts % 3) + 1)
- curCourseCount = int(lapTotalCounts / 3)
- curCupCount = int((lapTotalCounts / 12) % 12)
-
- print(str(center_text("", 67, "=")))
- print(str(center_text(" All Cups (Decompilation) ", 67)))
- print(str(center_text(" " + str(round(srcPct, 2))+"% Complete ", 67, "-")))
- print(str(center_text(" # Decompiled functions: " + str(TotalCFunctions) + " ", 67)))
- print(str(center_text(" # GLOBAL_ASM remaining: " + str(TotalGlobalAsmFunctions) + " ", 67)))
- print(str(center_text(" # NON_MATCHING remaining: " + str(TotalNonMatchingFunctions) + " ", 67)))
- print(str(center_text(" # MIPS_TO_C remaining: " + str(TotalMipsToCFunctions) + " ", 67)))
- print(str(center_text(" Game Status ", 67, "-")))
-
+ outputLength = 67 # Horizontal length of the text in the terminal output
+ # "Magic" number is 48, which is 3 laps * 4 courses * 3 cups
+ bytesPerTotalLaps = total_code_size // 47 # Total size // (Magic number - 1)
+ srcDivNear = find_closest_divisible(total, 49) # Correct division by diving closest divisible with (Magic number + 1)
+ lapTotalCounts = int(srcDivNear / bytesPerTotalLaps) # Game progress count, sets where are we in a simulated game, can be between 0 - 47
+ curLapProgress = int(((srcDivNear % bytesPerTotalLaps) * (outputLength - 1)) / (bytesPerTotalLaps)) # Progress of a lap depending of the output length
+ curLapCount = int((lapTotalCounts % 3) + 1) # Lap count, can be between 1 - 3 (3 laps total)
+ curCourseCount = int(lapTotalCounts / 3) # Course count, can be between 0 - 15 (16 courses total)
+ curCupCount = int((lapTotalCounts / 12) % 12) # Cup count, can be between 0 - 3 (4 cups total)
+
+ # Print current decompilation progress.
+ print(str(center_text((str(" Non Matching progress mode ") if args.nonmatching else str("")), outputLength, "=")))
+ print(str(center_text(" All Cups (Decompilation) ", outputLength)))
+ print(str(center_text(" " + str(round(totalPct, 2))+"% Complete ", outputLength, "-")))
+ print(str(center_text(" # Decompiled functions: " + str(TotalCFunctions) + " ", outputLength)))
+ print(str(center_text(" # GLOBAL_ASM remaining: " + str(TotalGlobalAsmFunctions) + " ", outputLength)))
+ print(str(center_text(" # NON_MATCHING remaining: " + str(TotalNonMatchingFunctions) + " ", outputLength)))
+ print(str(center_text(" # MIPS_TO_C remaining: " + str(TotalMipsToCFunctions) + " ", outputLength)))
+ print(str(center_text(" Game Status ", outputLength, "-")))
+
+ # Simlautes an All Cups race, prints how much the player has been progressing.
if TotalGlobalAsmFunctions > 0:
- print(str(center_text(check_table_cond(0, curCupCount, mkCups) + " - " + check_table_cond(1, curCupCount, mkCups), 67)))
- print(str(center_text(check_table_cond(2, curCupCount, mkCups) + " - " + check_table_cond(3, curCupCount, mkCups), 67)))
- print(str(center_text(" Lap Progress Bar and Race Status", 67, "-")))
- print(str(move_character_from_bar(curLapProgress, 67, "O", "-")))
- print(str(center_text("We are in " + str(get_string_from_table(curCupCount, mkCups)) + " racing at " + str(get_string_from_table(curCourseCount, mkCourses)) + " (Lap " + str(curLapCount) + "/3)", 67)))
+ print(str(center_text(check_table_cond(0, curCupCount, mkCups) + " - " + check_table_cond(1, curCupCount, mkCups), outputLength)))
+ print(str(center_text(check_table_cond(2, curCupCount, mkCups) + " - " + check_table_cond(3, curCupCount, mkCups), outputLength)))
+ print(str(center_text(" Lap Progress Bar and Race Status ", outputLength, "-")))
+ print(str(move_character_from_bar(curLapProgress, outputLength, "O", "-")))
+ print(str(center_text("We are in " + str(get_string_from_table(curCupCount, mkCups)) + " racing at " + str(get_string_from_table(curCourseCount, mkCourses)) + " (Lap " + str(curLapCount) + "/3)", outputLength)))
else:
- print(str(center_text("Mushroom Cup (V) - Flower Cup (V)", 67)))
- print(str(center_text("Star Cup (V) - Special Cup (V)", 67)))
- print(str(center_text("We finished All Cups! We got all 4 Gold Cups!", 67)))
+ print(str(center_text("Mushroom Cup (V) - Flower Cup (V)", outputLength)))
+ print(str(center_text("Star Cup (V) - Special Cup (V)", outputLength)))
+ print(str(center_text("We finished All Cups! We got all 4 Gold Cups!", outputLength)))
- print(str(center_text("", 67, "=")))
+ print(str(center_text((str(" Non Matching progress mode ") if args.nonmatching else str("")), outputLength, "=")))
+# Shows decompilation progress output in verbose mode.
elif args.format == 'verbose':
- print("Total decompilable bytes remaining: "+str(remaining_size)+" out of "+str(total_code_size)+"\n")
- print(str(src) + "/" + str(total_code_size) + " bytes " + "decompiled" + " in total code " + str(srcPct) + "%\n")
- print(str(TotalCFunctions) + " decompiled functions - " +str(TotalGlobalAsmFunctions)+" GLOBAL_ASM functions remaining."+"\n")
+ adjective = "decompiled" if args.nonmatching else "matched"
+
+ print("Total decompilable bytes remaining: " + str(remaining_size)+ " out of " + str(total_code_size)+"\n")
+ print(str(total) + "/" + str(total_code_size) + " bytes " + adjective + " in total code " + str(totalPct) + "%")
+ print(str(game) + "/" + str(game_code_size) + " bytes " + adjective + " in game code " + str(gamePct) + "%\n")
+ print(str(TotalCFunctions) + " " + adjective + " functions - " + str(TotalGlobalAsmFunctions)+" GLOBAL_ASM functions remaining."+"")
print(str(TotalNonMatchingFunctions)+" NON_MATCHING functions - " + str(TotalMipsToCFunctions) + " MIPS_TO_C functions." +"\n")
- print("------------------------------------\n")
- print(str(segMain) + "/" + str(seg_main_size) + " bytes " + "decompiled" + " in segMain " + str(segMainPct) + "%\n")
- print(str(segEnding) + "/" + str(seg_ending_size) + " bytes " + "decompiled" + " in segEnding " + str(segEndingPct) + "%\n")
- print(str(segRacing) + "/" + str(seg_racing_size) + " bytes " + "decompiled" + " in segRacing " + str(segRacingPct) + "%\n")
- print(str(game) + "/" + str(game_code_size) + " bytes " + "decompiled" + " in game code " + str(gamePct) + "%\n")
- print("------------------------------------\n")
- print(str(audio) + "/" + str(audio_size) + " bytes " + "decompiled" + " in audio " + str(audioPct) + "%\n")
- print(str(libultra) + "/" + str(libultra_size) + " bytes " + "decompiled" + " in libultra " + str(libultraPct) + "%\n")
+ print(str(segMain) + "/" + str(seg_main_size) + " bytes " + adjective + " in segMain " + str(segMainPct) + "%")
+ print(str(segEnding) + "/" + str(seg_ending_size) + " bytes " + adjective + " in segEnding " + str(segEndingPct) + "%")
+ print(str(segRacing) + "/" + str(seg_racing_size) + " bytes " + adjective + " in segRacing " + str(segRacingPct) + "%")
+ print(str(audio) + "/" + str(audio_size) + " bytes " + adjective + " in audio " + str(audioPct) + "%")
+ print(str(libultra) + "/" + str(libultra_size) + " bytes " + adjective + " in libultra " + str(libultraPct) + "%\n")
else:
print("Unknown format argument: " + args.format)