marioparty4/configure.py
gamemasterplc 7e38ff60b0 Upgrade DTK and Extract more assets
Fixes alignment of extracted assets. Extracted assets are currently unused except for font.c.  logoNintendoData not extracted from bootdll.rel but its loader is decompiled.
2023-11-26 07:59:54 -06:00

321 lines
7.8 KiB
Python
Executable file

#!/usr/bin/env python3
###
# Generates build files for the project.
# This file also includes the project configuration,
# such as compiler flags and the object matching status.
#
# Usage:
# python3 configure.py
# ninja
#
# Append --help to see available options.
###
import sys
import argparse
from pathlib import Path
from tools.project import (
Object,
ProjectConfig,
calculate_progress,
generate_build,
is_windows,
)
# Game versions
DEFAULT_VERSION = 0
VERSIONS = [
"GMPE01_00", # USA 1.0
]
if len(VERSIONS) > 1:
versions_str = ", ".join(VERSIONS[:-1]) + f" or {VERSIONS[-1]}"
else:
versions_str = VERSIONS[0]
parser = argparse.ArgumentParser()
parser.add_argument(
"mode",
default="configure",
help="configure or progress (default: configure)",
nargs="?",
)
parser.add_argument(
"--version",
dest="version",
default=VERSIONS[DEFAULT_VERSION],
help=f"version to build ({versions_str})",
)
parser.add_argument(
"--build-dir",
dest="build_dir",
type=Path,
default=Path("build"),
help="base build directory (default: build)",
)
parser.add_argument(
"--compilers",
dest="compilers",
type=Path,
help="path to compilers (optional)",
)
parser.add_argument(
"--map",
dest="map",
action="store_true",
help="generate map file(s)",
)
parser.add_argument(
"--debug",
dest="debug",
action="store_true",
help="build with debug info (non-matching)",
)
if not is_windows():
parser.add_argument(
"--wrapper",
dest="wrapper",
type=Path,
help="path to wibo or wine (optional)",
)
parser.add_argument(
"--build-dtk",
dest="build_dtk",
type=Path,
help="path to decomp-toolkit source (optional)",
)
parser.add_argument(
"--sjiswrap",
dest="sjiswrap",
type=Path,
help="path to sjiswrap.exe (optional)",
)
parser.add_argument(
"--verbose",
dest="verbose",
action="store_true",
help="print verbose output",
)
args = parser.parse_args()
config = ProjectConfig()
config.version = args.version.upper()
if config.version not in VERSIONS:
sys.exit(f"Invalid version '{config.version}', expected {versions_str}")
version_num = VERSIONS.index(config.version)
# Apply arguments
config.build_dir = args.build_dir
config.build_dtk_path = args.build_dtk
config.compilers_path = args.compilers
config.debug = args.debug
config.generate_map = args.map
config.sjiswrap_path = args.sjiswrap
if not is_windows():
config.wrapper = args.wrapper
# Tool versions
config.compilers_tag = "20231018"
config.dtk_tag = "v0.6.3"
config.sjiswrap_tag = "v1.1.1"
config.wibo_tag = "0.6.3"
# Project
config.config_path = Path("config") / config.version / "config.yml"
config.check_sha_path = Path("config") / config.version / "build.sha1"
config.ldflags = [
"-fp hardware",
"-nodefaults",
]
# Base flags, common to most GC/Wii games.
# Generally leave untouched, with overrides added below.
cflags_base = [
"-nodefaults",
"-proc gekko",
"-align powerpc",
"-enum int",
"-fp hardware",
"-Cpp_exceptions off",
# "-W all",
"-O4,p",
"-inline auto",
'-pragma "cats off"',
'-pragma "warn_notinlined off"',
"-maxerrors 1",
"-nosyspath",
"-RTTI off",
"-fp_contract on",
"-str reuse",
"-i include",
f"-i build/{config.version}/include",
"-multibyte",
f"-DVERSION={version_num}",
]
# Debug flags
if config.debug:
cflags_base.extend(["-sym on", "-DDEBUG=1"])
else:
cflags_base.append("-DNDEBUG=1")
# Metrowerks library flags
cflags_runtime = [
*cflags_base,
"-use_lmw_stmw on",
"-str reuse,pool,readonly",
"-common off",
"-inline auto,deferred",
]
# REL flags
cflags_rel = [
*cflags_base,
"-O0,p",
"-enum int",
"-char unsigned",
"-fp_contract off",
"-sdata 0",
"-sdata2 0",
"-pool off",
]
# Game flags
cflags_game = [
*cflags_base,
"-O0,p",
"-enum int",
"-char unsigned",
"-fp_contract off",
]
config.linker_version = "GC/2.6"
config.rel_strip_partial = False
config.rel_empty_file = "REL/empty.c"
# Helper function for Dolphin libraries
def DolphinLib(lib_name, objects):
return {
"lib": lib_name,
"mw_version": "GC/2.6",
"cflags": cflags_base,
"host": False,
"objects": objects,
}
# Helper function for REL script objects
def Rel(lib_name, objects):
return {
"lib": lib_name,
"mw_version": "GC/2.6",
"cflags": cflags_rel,
"host": True,
"objects": objects,
}
Matching = True
NonMatching = False
config.warn_missing_config = True
config.warn_missing_source = False
config.libs = [
{
"lib": "Game",
"mw_version": config.linker_version,
"cflags": cflags_game,
"host": False,
"objects": [
Object(NonMatching, "game/main.c"),
Object(NonMatching, "game/pad.c"),
Object(Matching, "game/dvd.c"),
Object(NonMatching, "game/data.c"),
Object(Matching, "game/decode.c"),
Object(Matching, "game/font.c"),
Object(Matching, "game/init.c"),
Object(NonMatching, "game/jmp.c"),
Object(Matching, "game/malloc.c"),
Object(Matching, "game/memory.c"),
Object(Matching, "game/printfunc.c"),
Object(Matching, "game/process.c"),
Object(NonMatching, "game/sprman.c"),
Object(NonMatching, "game/sprput.c"),
Object(NonMatching, "game/hsfload.c"),
Object(NonMatching, "game/hsfdraw.c"),
Object(NonMatching, "game/hsfman.c"),
Object(Matching, "game/objmain.c"),
Object(NonMatching, "game/fault.c"),
Object(NonMatching, "game/frand.c"),
Object(Matching, "game/ovllist.c"),
Object(NonMatching, "game/window.c"),
Object(NonMatching, "game/messdata.c"),
Object(NonMatching, "game/card.c"),
Object(NonMatching, "game/armem.c"),
],
},
{
"lib": "Runtime.PPCEABI.H",
"mw_version": config.linker_version,
"cflags": cflags_runtime,
"host": False,
"objects": [
Object(Matching, "Runtime.PPCEABI.H/global_destructor_chain.c"),
Object(Matching, "Runtime.PPCEABI.H/__init_cpp_exceptions.cpp"),
],
},
{
"lib": "REL",
"mw_version": config.linker_version,
"cflags": cflags_rel,
"host": False,
"objects": [
Object(Matching, "REL/executor.c"),
Object(Matching, "REL/empty.c"), # Must be marked as matching
],
},
{
"lib": "_minigameDLL",
"mw_version": config.linker_version,
"cflags": cflags_rel,
"host": False,
"objects": [
Object(Matching, "REL/executor.c"),
Object(Matching, "REL/_minigameDLL/_minigameDLL.c"),
],
},
{
"lib": "bootDll",
"mw_version": config.linker_version,
"cflags": cflags_rel,
"host": False,
"objects": [
Object(Matching, "REL/executor.c"),
Object(NonMatching, "REL/bootDll/bootDll.c"),
Object(Matching, "REL/bootDll/nintendo_data.c"), #Waiting for REL asset extraction to be fixed
],
},
{
"lib": "subchrselDll",
"mw_version": config.linker_version,
"cflags": cflags_rel,
"host": False,
"objects": [
Object(Matching, "REL/executor.c"),
Object(Matching, "REL/subchrselDll/subchrselDll.c"),
],
},
]
if args.mode == "configure":
# Write build.ninja and objdiff.json
generate_build(config)
elif args.mode == "progress":
# Print progress and write progress.json
config.progress_each_module = args.verbose
calculate_progress(config)
else:
sys.exit("Unknown mode: " + args.mode)