#!/usr/bin/env python # Game ID and title of the game. ID has to be four characters, title can be up to 11 GAME_ID = "DTGM" GAME_TITLE = "DMGTRIS" # Version of the game as embedded in the rom GAME_VERSION = "0x01" # Mapper type and sram size MAPPER_TYPE = "MBC5+RAM+BATTERY" SRAM_AMOUNT = "0x04" # Rom filename, without extension ROM_NAME = "PandorasBlocks" # Extra flags RGBASM_FLAGS = ["-Q", "25"] RGBLINK_FLAGS = [] RGBFIX_FLAGS = ["-c"] # You will not be likely to need to change these options. OLD_LICENSEE = "0x33" PAD_VALUE = "0xFF" LICENSEE = "HB" # Do not edit below this line. import sys, shutil, hashlib, subprocess from pathlib import Path def clean(): shutil.rmtree("./bin", ignore_errors=True) shutil.rmtree("./obj", ignore_errors=True) def assemble(file, out, extra = []): cmd = [ "rgbasm", "-p", PAD_VALUE, "-Isrc/", "-Isrc/include", "-Wall", "-Wextra" ] cmd += RGBASM_FLAGS cmd += extra cmd += [ "-o", out, file ] result = subprocess.run(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, text=True) if result.returncode == 0: return True else: print(result.stdout) return False def link(files, out, extra = []): cmd = [ "rgblink", "-p", PAD_VALUE ] cmd += RGBLINK_FLAGS cmd += extra cmd += [ "-o", out ] cmd += files result = subprocess.run(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, text=True) if result.returncode == 0: return True else: print(result.stdout) return False def fix(file, extra = []): cmd = [ "rgbfix", "-v", "-p", PAD_VALUE, "-i", GAME_ID, "-k", LICENSEE, "-l", OLD_LICENSEE, "-m", MAPPER_TYPE, "-n", GAME_VERSION, "-r", SRAM_AMOUNT, "-t", GAME_TITLE ] cmd += RGBFIX_FLAGS cmd += extra cmd += [file] result = subprocess.run(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, text=True) if result.returncode == 0: return True else: print(result.stdout) return False def build(): # Make sure the output directories exist. Path("./bin").mkdir(exist_ok=True) Path("./obj").mkdir(exist_ok=True) Path("./obj/a").mkdir(exist_ok=True) Path("./obj/n").mkdir(exist_ok=True) # RGBASM pass files = [f for f in Path("./src").glob("*.asm") if f.is_file()] for file in files: # Check if the file needs reassembly digest_file = Path(f"./obj/{file.stem}.sha256") n_file = Path(f"./obj/n/{file.stem}.o") a_file = Path(f"./obj/a/{file.stem}.o") old_digest = "" new_digest = "" if digest_file.exists(): old_digest = digest_file.read_text() with file.open("rb") as f: new_digest = hashlib.file_digest(f, "sha256").hexdigest() if old_digest != new_digest: print(f"Assembling {file.name}...") n_file.unlink(missing_ok=True) n_result = assemble(str(file), str(n_file), []) if not n_result: print("Aborting.") return a_file.unlink(missing_ok=True) a_result = assemble(str(file), str(a_file), ["-D" "BUILD_POCKET"]) if not a_result: print("Aborting.") return digest_file.write_text(new_digest) # RGBLINK + RGBFIX pass print(f"Linking bin/{ROM_NAME}.gbc...") n_files = [str(f) for f in Path("./obj/n").glob("*.o") if f.is_file()] Path(f"./bin/{ROM_NAME}.gbc").unlink(missing_ok=True) Path(f"./bin/{ROM_NAME}.map").unlink(missing_ok=True) Path(f"./bin/{ROM_NAME}.sym").unlink(missing_ok=True) n_result = link(n_files, f"bin/{ROM_NAME}.gbc", ["-m", f"bin/{ROM_NAME}.map", "-n", f"bin/{ROM_NAME}.sym"]) if not n_result: print("Aborting.") return print(f"Fixing bin/{ROM_NAME}.gbc...") n_result = fix(f"bin/{ROM_NAME}.gbc") if not n_result: print("Aborting.") return print(f"Linking bin/{ROM_NAME}.pocket...") Path(f"./bin/{ROM_NAME}.pocket").unlink(missing_ok=True) a_files = [str(f) for f in Path("./obj/a").glob("*.o") if f.is_file()] a_result = link(a_files, f"bin/{ROM_NAME}.pocket") if not a_result: print("Aborting.") return print(f"Fixing bin/{ROM_NAME}.pocket...") a_result = fix(f"bin/{ROM_NAME}.pocket", ["-L", "src/include/pocket-logo.1bpp"]) if not a_result: print("Aborting.") return if __name__ == "__main__": if sys.argv[-1] == "clean": clean() if sys.argv[-1] == "rebuild": clean(); build() else: build()