diff options
| author | AloXado320 <38191089+AloXado320@users.noreply.github.com> | 2023-11-05 15:57:14 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-05 13:57:14 -0700 |
| commit | 959c933714e07e9832851df27a04ded23df00d81 (patch) | |
| tree | a74bffb36cc8626af128e23162cd401dd7334d09 /progress.py | |
| parent | 596fa15e8dd834eac7c2af2311f61d018a038e2f (diff) | |
Document progress.py and correct readme (#483)
* Document progress.py and adjust readme
Diffstat (limited to 'progress.py')
| -rw-r--r-- | progress.py | 394 |
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) |
