#!/usr/bin/env python3 import re import sys import io abbreviations = { "banshee_boardwalk": "BB", "big_donut": "BD", "block_fort": "BF", "bowsers_castle": "BC", "choco_mountain": "CM", "dks_jungle_parkway": "DKJ", "double_deck": "DD", "frappe_snowland": "FS", "kalimari_desert": "KD", "koopa_troopa_beach": "KTB", "luigi_raceway": "LR", "mario_raceway": "MR", "moo_moo_farm": "MMF", "rainbow_road": "RR", "royal_raceway": "RRW", "sherbet_land": "SL", "skyscraper": "SS", "toads_turnpike": "TT", "wario_stadium": "WS", "yoshi_valley": "YV", } texture_map = { "gTexture64275C": ("texture_64275C", "rgba16"), "gTexture64286C": ("texture_64286C", "rgba16"), "gTexture642978": ("texture_642978", "rgba16"), "gTexture64313C": ("texture_64313C", "rgba16"), "gTexture643A34": ("texture_643A34", "rgba16"), "gTexture643B3C": ("texture_643B3C", "rgba16"), "gTexture6442D4": ("texture_6442D4", "rgba16"), "gTexture64440C": ("texture_64440C", "rgba16"), "gTexture6446AC": ("texture_6446AC", "rgba16"), "gTexture6447C4": ("texture_6447C4", "rgba16"), "gTexture6449D4": ("texture_6449D4", "rgba16"), "gTexture645134": ("texture_645134", "rgba16"), "gTexture645660": ("texture_645660", "rgba16"), "gTexture6457D8": ("texture_6457D8", "rgba16"), "gTexture64619C": ("texture_64619C", "rgba16"), "gTexture6462C0": ("texture_6462C0", "rgba16"), "gTexture64647C": ("texture_64647C", "rgba16"), "gTexture646CA8": ("texture_646CA8", "rgba16"), "gTexture6473E4": ("texture_6473E4", "rgba16"), "gTexture647994": ("texture_647994", "rgba16"), "gTexture647F4C": ("texture_647F4C", "rgba16"), "gTexture648508": ("texture_648508", "rgba16"), "gTexture64ACAC": ("texture_64ACAC", "rgba16"), "gTexture64AF50": ("texture_64AF50", "rgba16"), "gTexture64B090": ("texture_64B090", "rgba16"), "gTexture64B3F8": ("texture_64B3F8", "rgba16"), "gTexture64B54C": ("texture_64B54C", "rgba16"), "gTexture64B8D8": ("texture_64B8D8", "rgba16"), "gTexture64BA50": ("texture_64BA50", "rgba16"), "gTexture64BB60": ("texture_64BB60", "rgba16"), "gTexture64BCCC": ("texture_64BCCC", "rgba16"), "gTexture64C11C": ("texture_64C11C", "rgba16"), "gTexture64C7B4": ("texture_64C7B4", "rgba16"), "gTexture64CC20": ("texture_64CC20", "rgba16"), "gTexture64F9E8": ("texture_64F9E8", "rgba16"), "gTexture64FBF4": ("texture_64FBF4", "rgba16"), "gTexture64FE68": ("texture_64FE68", "rgba16"), "gTexture65100C": ("texture_65100C", "rgba16"), "gTexture65112C": ("texture_65112C", "rgba16"), "gTexture65127C": ("texture_65127C", "rgba16"), "gTexture651428": ("texture_651428", "rgba16"), "gTexture651984": ("texture_651984", "rgba16"), "gTexture651B20": ("texture_651B20", "rgba16"), "gTexture651F40": ("texture_651F40", "rgba16"), "gTexture6522E0": ("texture_6522E0", "rgba16"), "gTexture6528DC": ("texture_6528DC", "rgba16"), "gTexture652B54": ("texture_652B54", "rgba16"), "gTexture65315C": ("texture_65315C", "rgba16"), "gTexture653608": ("texture_653608", "rgba16"), "gTexture653DB0": ("texture_653DB0", "rgba16"), "gTexture654460": ("texture_654460", "rgba16"), "gTexture654F74": ("texture_654F74", "rgba16"), "gTexture655998": ("texture_655998", "rgba16"), "gTexture655F38": ("texture_655F38", "rgba16"), "gTexture656AF4": ("texture_656AF4", "rgba16"), "gTexture6575C8": ("texture_6575C8", "rgba16"), "gTexture658370": ("texture_658370", "rgba16"), "gTexture65912C": ("texture_65912C", "rgba16"), "gTexture659EE8": ("texture_659EE8", "rgba16"), "gTexture65ADE0": ("texture_65ADE0", "rgba16"), "gTexture65BB3C": ("texture_65BB3C", "rgba16"), "gTexture65C8DC": ("texture_65C8DC", "rgba16"), "gTexture65D5D4": ("texture_65D5D4", "rgba16"), "gTexture65E2EC": ("texture_65E2EC", "rgba16"), "gTexture65E59C": ("texture_65E59C", "rgba16"), "gTexture65EAEC": ("texture_65EAEC", "rgba16"), "gTexture65EE38": ("texture_65EE38", "rgba16"), "gTexture65FB18": ("texture_65FB18", "rgba16"), "gTexture6607C0": ("texture_6607C0", "rgba16"), "gTexture6608C8": ("texture_6608C8", "rgba16"), "gTexture6609D0": ("texture_6609D0", "rgba16"), "gTexture660D8C": ("texture_660D8C", "rgba16"), "gTexture66262C": ("texture_66262C", "rgba16"), "gTexture662924": ("texture_662924", "rgba16"), "gTexture662A34": ("texture_662A34", "rgba16"), "gTexture663F90": ("texture_663F90", "rgba16"), "gTexture6640B4": ("texture_6640B4", "rgba16"), "gTexture6642A4": ("texture_6642A4", "rgba16"), "gTexture664408": ("texture_664408", "rgba16"), "gTexture6646B8": ("texture_6646B8", "rgba16"), "gTexture665C0C": ("texture_665C0C", "rgba16"), "gTexture6661AC": ("texture_6661AC", "rgba16"), "gTexture6663A4": ("texture_6663A4", "rgba16"), "gTexture667BAC": ("texture_667BAC", "rgba16"), "gTexture668228": ("texture_668228", "rgba16"), "gTexture668358": ("texture_668358", "rgba16"), "gTexture6684F8": ("texture_6684F8", "rgba16"), "gTexture668608": ("texture_668608", "rgba16"), "gTexture668728": ("texture_668728", "rgba16"), "gTexture668920": ("texture_668920", "rgba16"), "gTexture669570": ("texture_669570", "rgba16"), "gTexture66A3DC": ("texture_66A3DC", "rgba16"), "gTexture66ABA4": ("texture_66ABA4", "rgba16"), "gTexture66C7A8": ("texture_66C7A8", "rgba16"), "gTexture66C8F4": ("texture_66C8F4", "rgba16"), "gTexture66CA98": ("texture_66CA98", "rgba16"), "gTexture66CD64": ("texture_66CD64", "rgba16"), "gTexture66D024": ("texture_66D024", "rgba16"), "gTexture66D698": ("texture_66D698", "rgba16"), "gTexture66DB60": ("texture_66DB60", "rgba16"), "gTexture66DD38": ("texture_66DD38", "rgba16"), "gTexture66E608": ("texture_66E608", "rgba16"), "gTexture66EBF0": ("texture_66EBF0", "rgba16"), "gTexture66ED38": ("texture_66ED38", "rgba16"), "gTexture670AC8": ("texture_670AC8", "rgba16"), "gTexture671A88": ("texture_671A88", "rgba16"), "gTexture67291C": ("texture_67291C", "rgba16"), "gTexture673118": ("texture_673118", "rgba16"), "gTexture6733CC": ("texture_6733CC", "rgba16"), "gTexture6735DC": ("texture_6735DC", "rgba16"), "gTexture673990": ("texture_673990", "rgba16"), "gTexture673C68": ("texture_673C68", "rgba16"), "gTexture673FF8": ("texture_673FF8", "rgba16"), "gTexture674354": ("texture_674354", "rgba16"), "gTexture6747C4": ("texture_6747C4", "rgba16"), "gTexture67490C": ("texture_67490C", "rgba16"), "gTexture674B28": ("texture_674B28", "rgba16"), "gTexture674D58": ("texture_674D58", "rgba16"), "gTexture675064": ("texture_675064", "rgba16"), "gTexture675220": ("texture_675220", "rgba16"), "gTexture675434": ("texture_675434", "rgba16"), "gTexture676C6C": ("texture_676C6C", "rgba16"), "gTexture676D7C": ("texture_676D7C", "rgba16"), "gTexture676EA8": ("texture_676EA8", "rgba16"), "gTexture676FB0": ("texture_676FB0", "rgba16"), "gTexture6774D8": ("texture_6774D8", "rgba16"), "gTexture6775EC": ("texture_6775EC", "rgba16"), "gTexture677A40": ("texture_677A40", "rgba16"), "gTexture677F04": ("texture_677F04", "rgba16"), "gTexture678118": ("texture_678118", "rgba16"), "gTexture67842C": ("texture_67842C", "rgba16"), "gTexture67893C": ("texture_67893C", "rgba16"), "gTexture678CC8": ("texture_678CC8", "rgba16"), "gTexture679258": ("texture_679258", "rgba16"), "gTexture67973C": ("texture_67973C", "rgba16"), "gTexture679C04": ("texture_679C04", "rgba16"), "gTexture679D34": ("texture_679D34", "rgba16"), "gTexture67A1B8": ("texture_67A1B8", "rgba16"), "gTexture67A370": ("texture_67A370", "rgba16"), "gTexture67A91C": ("texture_67A91C", "rgba16"), "gTexture67ADF0": ("texture_67ADF0", "rgba16"), "gTexture67B388": ("texture_67B388", "rgba16"), "gTexture67B75C": ("texture_67B75C", "rgba16"), "gTexture67B864": ("texture_67B864", "rgba16"), "gTexture67B9B0": ("texture_67B9B0", "rgba16"), "gTexture67BBD8": ("texture_67BBD8", "rgba16"), "gTexture67BEE8": ("texture_67BEE8", "rgba16"), "gTexture67D304": ("texture_67D304", "rgba16"), "gTexture67DC20": ("texture_67DC20", "rgba16"), "gTexture67E010": ("texture_67E010", "rgba16"), "gTexture67E428": ("texture_67E428", "rgba16"), "gTexture67EEAC": ("texture_67EEAC", "rgba16"), "gTexture67EFEC": ("texture_67EFEC", "rgba16"), "gTexture67F15C": ("texture_67F15C", "rgba16"), "gTexture67F450": ("texture_67F450", "rgba16"), "gTexture67FE0C": ("texture_67FE0C", "rgba16"), "gTexture68272C": ("texture_68272C", "rgba16"), "gTexture682928": ("texture_682928", "rgba16"), "gTexture682B24": ("texture_682B24", "rgba16"), "gTexture682D20": ("texture_682D20", "rgba16"), "gTexture682F1C": ("texture_682F1C", "rgba16"), "gTexture683118": ("texture_683118", "rgba16"), "gTexture683314": ("texture_683314", "rgba16"), "gTexture6835F0": ("texture_6835F0", "rgba16"), "gTexture683844": ("texture_683844", "rgba16"), "gTexture6846DC": ("texture_6846DC", "rgba16"), "gTexture685108": ("texture_685108", "rgba16"), "gTexture6864E8": ("texture_6864E8", "rgba16"), "gTexture686CF0": ("texture_686CF0", "rgba16"), "gTexture6875A8": ("texture_6875A8", "rgba16"), "gTexture687EE8": ("texture_687EE8", "rgba16"), "gTexture68876C": ("texture_68876C", "rgba16"), "gTexture689230": ("texture_689230", "rgba16"), "gTexture689C00": ("texture_689C00", "rgba16"), "gTexture68A484": ("texture_68A484", "rgba16"), "gTexture68AC5C": ("texture_68AC5C", "rgba16"), "gTexture68B6A4": ("texture_68B6A4", "rgba16"), "gTexture68BE6C": ("texture_68BE6C", "rgba16"), "gTexture68C310": ("texture_68C310", "rgba16"), "gTexture68CDA0": ("texture_68CDA0", "rgba16"), "gTexture68D834": ("texture_68D834", "rgba16"), "gTexture68D940": ("texture_68D940", "rgba16"), "gTexture68DEC0": ("texture_68DEC0", "rgba16"), "gTexture68E2D0": ("texture_68E2D0", "rgba16"), "gTextureBricksRed": ("bricks_red", "rgba16"), "gTextureCastleBricks": ("castle_bricks", "rgba16"), "gTextureCastleBridge": ("castle_bridge", "rgba16"), "gTextureCheckerboardBlackWhite": ("checkerboard_black_white", "rgba16"), "gTextureCheckerboardBlueGray": ("checkerboard_blue_gray", "rgba16"), "gTextureCheckerboardBlueGreen": ("checkerboard_blue_green", "rgba16"), "gTextureCheckerboardPink": ("checkerboard_pink", "rgba16"), "gTextureCheckerboardYellowBlue": ("checkerbord_yellow_blue", "rgba16"), "gTextureCheckerboardYellowPink": ("checkerboard_yellow_pink", "rgba16"), "gTextureCrown": ("crown", "rgba16"), "gTextureCrownJewelBlue": ("crown_jewel_blue", "rgba16"), "gTextureCrownJewelPink": ("crown_jewel_pink", "rgba16"), "gTextureFenceBarbedWire": ("fence_barbed_wire", "rgba16"), "gTextureFencePostWooden": ("fence_post_wooden", "rgba16"), "gTextureFenceRope": ("fence_rope", "rgba16"), "gTextureFlagRed": ("flag_red", "rgba16"), "gTextureFlagRed2": ("flag_red_2", "rgba16"), "gTextureGrass1": ("grass_1", "rgba16"), "gTextureGrass10": ("grass_10", "rgba16"), "gTextureGrass11": ("grass_11", "rgba16"), "gTextureGrass12": ("grass_12", "rgba16"), "gTextureGrass2": ("grass_2", "rgba16"), "gTextureGrass3": ("grass_3", "rgba16"), "gTextureGrass4": ("grass_4", "rgba16"), "gTextureGrass5": ("grass_5", "rgba16"), "gTextureGrass6": ("grass_6", "rgba16"), "gTextureGrass7": ("grass_7", "rgba16"), "gTextureGrass8": ("grass_8", "rgba16"), "gTextureGrass9": ("grass_9", "rgba16"), "gTextureGrayCheckerboard": ("gray_checkerboard", "rgba16"), "gTextureGrayCobblestone": ("gray_cobblestone", "rgba16"), "gTextureMooMooFarmSignLeft": ("gTextureMooMooFarmSignLeft", "rgba16"), "gTextureMooMooFarmSignRight": ("gTextureMooMooFarmSignRight", "rgba16"), "gTextureNumberYellowBlue1": ("number_yellow_blue_1", "rgba16"), "gTextureNumberYellowBlue2": ("number_yellow_blue_2", "rgba16"), "gTextureNumberYellowBlue3": ("number_yellow_blue_3", "rgba16"), "gTextureNumberYellowBlue4": ("number_yellow_blue_4", "rgba16"), "gTextureRailroadCrossingTrack": ("railroad_crossing_track", "rgba16"), "gTextureRailroadTrack": ("railroad_track", "rgba16"), "gTextureRainbow": ("rainbow", "rgba16"), "gTextureRoad0": ("road_0", "rgba16"), "gTextureRoad1": ("road_1", "rgba16"), "gTextureRoad2": ("road_2", "rgba16"), "gTextureRoad3": ("road_3", "rgba16"), "gTextureRoad4": ("road_4", "rgba16"), "gTextureRoad5": ("road_5", "rgba16"), "gTextureRoadFinish0": ("road_finish_0", "rgba16"), "gTextureRoadFinish1": ("road_finish_1", "rgba16"), "gTextureRoofTile": ("roof_tile", "rgba16"), "gTextureSandFinish": ("sand_finish", "rgba16"), "gTextureSignBackside": ("sign_backside", "rgba16"), "gTextureSignBlue64": ("sign_blue_64", "rgba16"), "gTextureSignBowser0": ("sign_bowser_0", "rgba16"), "gTextureSignBowser1": ("sign_bowser_1", "rgba16"), "gTextureSignFallingRocks": ("sign_falling_rocks", "rgba16"), "gTextureSignGreenArrow": ("sign_green_arrow", "rgba16"), "gTextureSignKoopaAir0": ("sign_koopa_air_0", "rgba16"), "gTextureSignKoopaAir1": ("sign_koopa_air_1", "rgba16"), "gTextureSignLuigiFace0": ("sign_luigi_face_0", "rgba16"), "gTextureSignLuigiFace1": ("sign_luigi_face_1", "rgba16"), "gTextureSignLuigis0": ("sign_luigis_0", "rgba16"), "gTextureSignLuigis1": ("sign_luigis_1", "rgba16"), "gTextureSignMarioStar0": ("sign_mario_star_0", "rgba16"), "gTextureSignMarioStar1": ("sign_mario_star_1", "rgba16"), "gTextureSignMergingLanes": ("sign_merging_lanes", "rgba16"), "gTextureSignNintendo0": ("sign_nintendo_0", "rgba16"), "gTextureSignNintendo1": ("sign_nintendo_1", "rgba16"), "gTextureSignNintendoRed0": ("sign_nintendo_red_0", "rgba16"), "gTextureSignNintendoRed1": ("sign_nintendo_red_1", "rgba16"), "gTextureSignPinkArrow": ("sign_pink_arrow", "rgba16"), "gTextureSignShellShot0": ("sign_shell_shot_0", "rgba16"), "gTextureSignShellShot1": ("sign_shell_shot_1", "rgba16"), "gTextureSignToadGreen": ("sign_toad_green", "rgba16"), "gTextureSignToadRed": ("sign_toad_red", "rgba16"), "gTextureSignToadYellow": ("sign_toad_yellow", "rgba16"), "gTextureSignWarioFace": ("sign_wario_face", "rgba16"), "gTextureSignWelcome0": ("sign_welcome_0", "rgba16"), "gTextureSignWelcome1": ("sign_welcome_1", "rgba16"), "gTextureSignWoodenBack0": ("sign_wooden_back_0", "rgba16"), "gTextureSignWoodenBack1": ("sign_wooden_back_1", "rgba16"), "gTextureSignWoodRedArrow": ("sign_wood_red_arrow", "rgba16"), "gTextureSignYoshi": ("sign_yoshi", "rgba16"), "gTextureStainglassPeach0": ("stainglass_peach_0", "rgba16"), "gTextureStainglassPeach1": ("stainglass_peach_1", "rgba16"), "gTextureWaves1": ("waves_1", "rgba16"), "gTextureWaves2": ("waves_2", "rgba16"), "gTextureWheelSteamEngine": ("wheel_steam_engine", "rgba16"), "gTextureWheelSteamEngineReal": ("wheel_steam_engine_real", "rgba16"), "gTextureWoodBridgeSlats": ("wood_bridge_slats", "rgba16"), "gTextureWoodDoor0": ("wood_door_0", "rgba16"), "gTextureWoodDoor1": ("wood_door_1", "rgba16"), "gTexture643430": ("texture_643430", "ia16"), "gTexture66AEB8": ("texture_66AEB8", "ia16"), "gTexture685AC0": ("texture_685AC0", "ia16"), "gTextureStarOutline": ("star_outline", "ia16"), "gTextureWaves0": ("waves_0", "ia16"), } # Usage: linkonly_generator.py course_name = sys.argv[1] # This depends on the texture lists in each courses//course_offsets.c # look like: `{gTexture6447C4, 0x0106, 0x0800, 0x0},` texture_regex = re.compile(r"{\s*(\S+),\s+\S+,\s+(\S+),\s+\S+\s*}") h_string = "" c_string = "" with open(f"courses/{course_name}/course_offsets.c", "r") as offsets: h_string += "#ifndef COURSE_TEXTURES_H" h_string += "\n#define COURSE_TEXTURES_H" h_string += "\n\n#include " c_string += f"#include \"courses/{course_name}/course_textures.linkonly.h\"" textures = texture_regex.findall(offsets.read()) # Something wrong has occurred if not textures: print(f"Failed to find any texture entries in courses/{course_name}/course_offsets.c") exit(1) current_offset = 0 for texture in textures: texture_name = texture[0] if texture_name == "0x00000000": continue # This is stupid, but I can't think of a cleaner method :( if "MooMooFarm" in texture_name: texture_include_dir = "assets/courses/moo_moo_farm" texture_filename = f"{texture_name}.inc.c" else: texture_include_dir = "textures/standalone" texture_filename = f"{texture_map[texture_name][0]}.{texture_map[texture_name][1]}.inc.c" unique_texture_name = re.sub("gTexture", f"g{abbreviations[course_name]}Texture", texture_name) c_string += f"\n\n/* 0x050{current_offset:05X} */" c_string += f"\nu8 {unique_texture_name}[] = {{" c_string += f"\n\t#include \"{texture_include_dir}/{texture_filename}\"" c_string += f"\n}};" h_string += f"\n\n/* 0x050{current_offset:05X} */" h_string += f"\nextern u8 {unique_texture_name}[];" current_offset += int(texture[1], 16) c_string += "\n" h_string += "\n\n#endif\n" # Write to files only after we've generated their entire contents. That way if an # error occurs during the generation we don't write an incomplete file with io.open(f"courses/{course_name}/course_textures.linkonly.c", "w", newline="\n") as linkonlyc, io.open(f"courses/{course_name}/course_textures.linkonly.h", "w", newline="\n") as linkonlyh: linkonlyh.write(h_string) linkonlyc.write(c_string)