Use decomp-toolkit

This commit is contained in:
Luke Street
2022-11-27 23:57:46 -05:00
parent ef221d5c96
commit 607753a08f
11 changed files with 570 additions and 1206 deletions
-232
View File
@@ -1,232 +0,0 @@
ifneq ($(findstring MINGW,$(shell uname)),)
WINDOWS := 1
endif
ifneq ($(findstring MSYS,$(shell uname)),)
WINDOWS := 1
endif
# If 0, tells the console to chill out. (Quiets the make process.)
VERBOSE ?= 0
# If GENERATE_MAP set to 1, tells LDFLAGS to generate a mapfile, which makes linking take several minutes.
GENERATE_MAP ?= 0
# Enable non-matching code & various fixes
NONMATCHING ?= 0
ifeq ($(VERBOSE),0)
QUIET := @
endif
#-------------------------------------------------------------------------------
# Files
#-------------------------------------------------------------------------------
NAME := mp1
VERSION ?= 0
VERSION_NUM := $(VERSION)
ifeq ($(VERSION),kor)
VERSION_NUM := 2
endif
BUILD_DIR := build/$(NAME).$(VERSION)
# Inputs
S_FILES := $(wildcard asm/*.s)
C_FILES := $(wildcard src/*.c)
CPP_FILES := $(wildcard src/*.cpp)
CPP_FILES += $(wildcard src/*.cp)
LDSCRIPT := $(BUILD_DIR)/ldscript.lcf
# Outputs
DOL := $(BUILD_DIR)/main.dol
ELF := $(DOL:.dol=.elf)
MAP := $(BUILD_DIR)/MetroidPrime.MAP
ifeq ($(GENERATE_MAP),1)
MAPGEN := -map $(MAP)
endif
include obj_files.mk
O_FILES := $(METROTRK_FILES) \
$(METROIDPRIME) $(WORLDFORMAT) $(WEAPONS) $(METARENDER) $(GUISYS) $(COLLISION) \
$(KYOTO_1) $(ZLIB_FILES) $(KYOTO_2) $(AI_FILES) \
$(AR_FILES) $(BASE_FILES) $(DB_FILES) $(DSP_FILES) $(DVD_FILES) $(GX_FILES) $(MTX_FILES) \
$(OS_FILES) $(PAD_FILES) $(VI_FILES) $(MSL_PPCEABI_BARE_H) $(MSL_COMMON_MATH) $(MUSYX_FILES) \
$(DTK_FILES) $(CARD_FILES) $(SI_FILES) $(EXI_FILES) $(THP_FILES) \
$(GBA_FILES)
DEPENDS := $(O_FILES:.o=.d)
# If a specific .o file is passed as a target, also process its deps
DEPENDS += $(MAKECMDGOALS:.o=.d)
#-------------------------------------------------------------------------------
# Tools
#-------------------------------------------------------------------------------
MWCC_VERSION := 1.3.2
MWLD_VERSION := 1.3.2
# Programs
export WINEDEBUG ?= -all
ifeq ($(WINDOWS),1)
WINE :=
AS := $(DEVKITPPC)/bin/powerpc-eabi-as.exe
CPP := $(DEVKITPPC)/bin/powerpc-eabi-cpp.exe -P
PYTHON := py
SHA1SUM := sha1sum
else
WIBO := $(shell command -v wibo 2> /dev/null)
ifdef WIBO
WINE ?= wibo
else
WINE ?= wine
endif
DEVKITPPC ?= /opt/devkitpro/devkitPPC
DEPENDS := $(DEPENDS:.d=.d.unix)
AS := $(DEVKITPPC)/bin/powerpc-eabi-as
CPP := $(DEVKITPPC)/bin/powerpc-eabi-cpp -P
PYTHON := python3
SHA1SUM := shasum -a 1
endif
CC = $(WINE) tools/mwcc_compiler/$(MWCC_VERSION)/mwcceppc.exe
LD := $(WINE) tools/mwcc_compiler/$(MWLD_VERSION)/mwldeppc.exe
ELF2DOL := tools/elf2dol
METROIDBUILDINFO := tools/metroidbuildinfo
TRANSFORM_DEP := tools/transform-dep.py
FRANK := tools/franklite.py
# Options
INCLUDES := -i include/ -i libc/
ASM_INCLUDES := -I include/
# DotKuribo/llvm-project
CLANG_CC ?= clang-kuribo
CLANG_CFLAGS := --target=ppc32-kuribo -mcpu=750 -nostdlib -fno-exceptions -fno-rtti -O3 -Wall -Wno-trigraphs -Wno-inline-new-delete -Wno-unused-private-field -fpermissive -std=gnu++11 $(ASM_INCLUDES)
ASFLAGS := -mgekko $(ASM_INCLUDES) --defsym version=$(VERSION_NUM)
ifeq ($(VERBOSE),1)
# this set of LDFLAGS outputs warnings.
LDFLAGS := $(MAPGEN) -fp fmadd -nodefaults
endif
ifeq ($(VERBOSE),0)
# this set of LDFLAGS generates no warnings.
LDFLAGS := $(MAPGEN) -fp fmadd -nodefaults -w off
endif
DEFINES = -DPRIME1 -DVERSION=$(VERSION_NUM) -DNONMATCHING=$(NONMATCHING)
CFLAGS_BASE = -proc gekko -nodefaults -Cpp_exceptions off -RTTI off -fp hard -fp_contract on -O4,p -maxerrors 1 -enum int -inline auto -str reuse -nosyspath -MMD $(DEFINES) $(INCLUDES)
CFLAGS = $(CFLAGS_BASE) -use_lmw_stmw on -str reuse,pool,readonly -gccinc -inline deferred,noauto -common on
CFLAGS_RUNTIME = $(CFLAGS_BASE) -use_lmw_stmw on -str reuse,pool,readonly -gccinc -inline deferred,auto
CFLAGS_MUSYX = $(CFLAGS_BASE) -fp hard -fp_contract off -str reuse,pool,readonly
ifeq ($(VERBOSE),0)
# this set of ASFLAGS generates no warnings.
ASFLAGS += -W
endif
$(METROTRK_FILES): MWCC_VERSION := 1.2.5
$(METROTRK_FILES): CFLAGS := $(CFLAGS_BASE)
$(BASE_FILES): MWCC_VERSION := 1.2.5
$(BASE_FILES): CFLAGS := $(CFLAGS_BASE)
$(AI_FILES): MWCC_VERSION := 1.2.5
$(AI_FILES): CFLAGS := $(CFLAGS_BASE)
$(OS_FILES): MWCC_VERSION := 1.2.5
$(OS_FILES): CFLAGS := $(CFLAGS_BASE)
$(CARD_FILES): MWCC_VERSION := 1.2.5
$(CARD_FILES): CFLAGS := $(CFLAGS_BASE)
$(DVD_FILES): MWCC_VERSION := 1.2.5
$(DVD_FILES): CFLAGS := $(CFLAGS_BASE)
$(DSP_FILES): MWCC_VERSION := 1.2.5
$(DSP_FILES): CFLAGS := $(CFLAGS_BASE)
$(MUSYX_FILES): CFLAGS := $(CFLAGS_MUSYX)
$(ZLIB_FILES): CFLAGS := $(CFLAGS_RUNTIME)
$(MSL_PPCEABI_BARE_H): CFLAGS := $(CFLAGS_RUNTIME)
$(MSL_COMMON_MATH): CFLAGS := $(CFLAGS_RUNTIME)
$(PAD_FILES): MWCC_VERSION := 1.2.5
$(PAD_FILES): CFLAGS := $(CFLAGS_BASE)
$(DTK_FILES): MWCC_VERSION := 1.2.5
$(DTK_FILES): CFLAGS := $(CFLAGS_BASE)
$(SI_FILES): MWCC_VERSION := 1.2.5
$(SI_FILES): CFLAGS := $(CFLAGS_BASE)
$(DB_FILES): MWCC_VERSION := 1.2.5
$(DB_FILES): CFLAGS := $(CFLAGS_BASE)
$(GBA_FILES): MWCC_VERSION := 1.2.5
$(GBA_FILES): CFLAGS := $(CFLAGS_BASE)
#-------------------------------------------------------------------------------
# Recipes
#-------------------------------------------------------------------------------
### Default target ###
default: all
all: $(DOL)
.PHONY: tools
$(LDSCRIPT): ldscript.lcf
$(QUIET) $(CPP) -MMD -MP -MT $@ -MF $@.d -I include/ -I . -DBUILD_DIR=$(BUILD_DIR) -o $@ $<
$(DOL): $(ELF) | tools
$(QUIET) $(ELF2DOL) $< $@
$(METROIDBUILDINFO) $@ buildstrings/$(NAME).$(VERSION).build
$(QUIET) $(SHA1SUM) -c sha1/$(NAME).$(VERSION).sha1
ifneq ($(findstring -map,$(LDFLAGS)),)
$(QUIET) $(PYTHON) tools/calcprogress.py $(DOL) $(MAP)
endif
clean:
$(RM) -r $(BUILD_DIR)
$(MAKE) -C tools clean
tools:
$(MAKE) -C tools
# ELF creation makefile instructions
$(ELF): $(O_FILES) $(LDSCRIPT)
@echo Linking ELF $@
$(QUIET) @echo $(O_FILES) > $(BUILD_DIR)/o_files
$(QUIET) $(LD) $(LDFLAGS) -o $@ -lcf $(LDSCRIPT) @$(BUILD_DIR)/o_files
%.d.unix: %.d $(TRANSFORM_DEP)
@echo Processing $<
$(QUIET) $(PYTHON) $(TRANSFORM_DEP) $< $@
-include $(DEPENDS)
$(BUILD_DIR)/%.o: %.s
@echo "Assembling" $<
$(QUIET) mkdir -p $(dir $@)
$(QUIET) $(AS) $(ASFLAGS) -o $@ $<
$(BUILD_DIR)/%.clang.o: %.cpp
@echo "Clang " $<
$(QUIET) mkdir -p $(dir $@)
$(QUIET) $(CLANG_CC) $(CLANG_CFLAGS) -c -o $@ $<
$(BUILD_DIR)/%.ep.o: $(BUILD_DIR)/%.o
@echo Frank is fixing $<
$(QUIET) mkdir -p $(dir $@)
$(QUIET) $(PYTHON) $(FRANK) $< $@
$(BUILD_DIR)/%.o: %.c
@echo "Compiling " $<
$(QUIET) mkdir -p $(dir $@)
$(QUIET) $(CC) $(CFLAGS) -c -o $(dir $@) $<
$(BUILD_DIR)/%.o: %.cp
@echo "Compiling " $<
$(QUIET) mkdir -p $(dir $@)
$(QUIET) $(CC) $(CFLAGS) -c -o $(dir $@) $<
$(BUILD_DIR)/%.o: %.cpp
@echo "Compiling " $<
$(QUIET) mkdir -p $(dir $@)
$(QUIET) $(CC) $(CFLAGS) -c -o $(dir $@) $<
### Debug Print ###
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
+18 -9
View File
@@ -23,9 +23,10 @@ Dependencies
Windows:
--------
- Install [ninja](https://github.com/ninja-build/ninja/releases) and add it to `%PATH%`.
- Install [devkitPro](https://github.com/devkitPro/installer/releases/latest) with GameCube development package.
- Open `C:\devkitPro\msys2\msys2.exe`
- Run the following:
- Install GameCube development packages:
```
pacman -Sy --noconfirm --needed msys2-keyring
pacman -Su --noconfirm --needed gcc git gamecube-dev
@@ -33,25 +34,28 @@ Windows:
macOS:
------
- Install wine:
- Install [ninja](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages):
```
brew tap gcenx/wine
brew install wine-crossover
sudo xattr -r -d com.apple.quarantine "/Applications/Wine Crossover.app"
brew install ninja
```
- Install [wine-crossover](https://github.com/Gcenx/homebrew-wine):
```
brew install --cask --no-quarantine gcenx/wine/wine-crossover
```
- Install [devkitPro](https://github.com/devkitPro/pacman/releases/latest).
- Run the following:
- Install GameCube development packages:
```
sudo dkp-pacman -Syu --noconfirm --needed gamecube-dev
```
Linux:
------
- Install [ninja](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages).
- Install wine from your package manager.
- Faster alternative: [WiBo](https://github.com/decompals/WiBo), a minimal 32-bit Windows binary wrapper.
Ensure the binary is in `PATH`.
- Install [devkitPro](https://devkitpro.org/wiki/devkitPro_pacman).
- Run the following:
- Install GameCube development packages:
```
sudo dkp-pacman -Syu --noconfirm --needed gamecube-dev
```
@@ -64,8 +68,13 @@ Building
git clone https://github.com/PrimeDecomp/prime.git
```
- Download [GC_WII_COMPILERS.zip](https://cdn.discordapp.com/attachments/727918646525165659/917185027656286218/GC_WII_COMPILERS.zip)
- Extract the contents of the `GC` directory to `tools/mwcc_compiler`
- Extract the _contents_ of the `GC` directory to `tools/mwcc_compiler`.
- Resulting structure should be (for example) `tools/mwcc_compiler/1.3.2/mwcceppc.exe`
- Configure:
```
python configure.py
```
- Build:
```
make -j
ninja
```
+466 -279
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
v0.1.0
+16 -5
View File
@@ -27,6 +27,8 @@ import math
import argparse
import json
from configure import LIBS
###############################################
# #
# Constants #
@@ -88,13 +90,22 @@ if __name__ == "__main__":
parser.add_argument("-o", "--output", help="JSON output file")
args = parser.parse_args()
# HACK: Check asm or src in obj_file.mk
# HACK: Check asm or src in configure.py
# to avoid counting .comm/.lcomm as decompiled
asm_objs = []
with open('obj_files.mk', 'r') as file:
for line in file:
if "asm/" in line:
asm_objs.append(line.strip().rsplit('/', 1)[-1].rstrip('\\'))
for lib in LIBS:
for obj in lib["objects"]:
is_asm = False
obj_name = None
if type(obj) is list:
obj_name = obj[0]
is_asm = not obj[1]
else:
obj_name = obj
is_asm = True
if is_asm:
name = obj_name.split('/')[-1]
asm_objs.append(f"{name}.o")
# Sum up DOL section sizes
dol_handle = open(args.dol, "rb")
-15
View File
@@ -1,15 +0,0 @@
CC := gcc
CFLAGS := -O3 -Wall -s
default: all
all: elf2dol metroidbuildinfo
elf2dol: elf2dol.c
$(CC) $(CFLAGS) -o $@ $^
metroidbuildinfo: metroidbuildinfo.c
$(CC) $(CFLAGS) -o $@ $^
clean:
$(RM) elf2dol metroidbuildinfo
+29 -26
View File
@@ -8,50 +8,53 @@ script_dir = os.path.dirname(os.path.realpath(__file__))
root_dir = os.path.abspath(os.path.join(script_dir, ".."))
src_dir = os.path.join(root_dir, "src")
include_dirs = [
os.path.join(root_dir, "include"),
os.path.join(root_dir, "libc"),
os.path.join(root_dir, "include"),
os.path.join(root_dir, "libc"),
]
include_pattern = re.compile(r'^#include\s*[<"](.+?)[>"]$')
guard_pattern = re.compile(r'^#ifndef\s+(.*)$')
guard_pattern = re.compile(r"^#ifndef\s+(.*)$")
defines = set()
def import_h_file(in_file, r_path) -> str:
rel_path = os.path.join(root_dir, r_path, in_file)
if os.path.exists(rel_path):
return import_c_file(rel_path)
return import_c_file(rel_path)
for include_dir in include_dirs:
inc_path = os.path.join(include_dir, in_file)
if os.path.exists(inc_path):
return import_c_file(inc_path)
inc_path = os.path.join(include_dir, in_file)
if os.path.exists(inc_path):
return import_c_file(inc_path)
else:
print("Failed to locate", in_file)
return ""
print("Failed to locate", in_file)
return ""
def import_c_file(in_file) -> str:
in_file = os.path.relpath(in_file, root_dir)
out_text = ''
out_text = ""
with open(in_file) as file:
for idx, line in enumerate(file):
guard_match = guard_pattern.match(line.strip())
if idx == 0:
if guard_match:
if guard_match[1] in defines:
break
defines.add(guard_match[1])
print("Processing file", in_file)
include_match = include_pattern.match(line.strip())
if include_match:
out_text += f"/* \"{in_file}\" line {idx} \"{include_match[1]}\" */\n"
out_text += import_h_file(include_match[1], os.path.dirname(in_file))
out_text += f"/* end \"{include_match[1]}\" */\n"
else:
out_text += line
for idx, line in enumerate(file):
guard_match = guard_pattern.match(line.strip())
if idx == 0:
if guard_match:
if guard_match[1] in defines:
break
defines.add(guard_match[1])
print("Processing file", in_file)
include_match = include_pattern.match(line.strip())
if include_match:
out_text += f'/* "{in_file}" line {idx} "{include_match[1]}" */\n'
out_text += import_h_file(include_match[1], os.path.dirname(in_file))
out_text += f'/* end "{include_match[1]}" */\n'
else:
out_text += line
return out_text
def main():
parser = argparse.ArgumentParser(
description="""Create a context file which can be used for decomp.me"""
@@ -69,4 +72,4 @@ def main():
if __name__ == "__main__":
main()
main()
-22
View File
@@ -1,22 +0,0 @@
from sys import argv
def nextU32(f):
dat = f.read(4)
return int.from_bytes(dat, 'big')
with open(argv[1], 'rb') as dol:
offsets = [nextU32(dol) for i in range(18)]
addresses = [nextU32(dol) for i in range(18)]
sizes = [nextU32(dol) for i in range(18)]
target = int(argv[2], 16)
for i in range(0, 0x18):
offset = offsets[i]
size = sizes[i]
if offset <= target < offset + size:
section = i
delta = target - offset
break
print(hex(addresses[section] + delta))
+40
View File
@@ -0,0 +1,40 @@
import argparse
import urllib.request
import os
import stat
from pathlib import Path
REPO = "https://github.com/encounter/decomp-toolkit"
def main():
parser = argparse.ArgumentParser()
parser.add_argument("tag_file", help="file containing GitHub tag")
parser.add_argument("output", type=Path, help="output file path")
args = parser.parse_args()
with open(args.tag_file, "r") as f:
tag = f.readline().rstrip()
uname = os.uname()
suffix = ""
platform = uname.sysname.lower()
if platform == "darwin":
platform = "macos"
elif platform == "windows":
suffix = ".exe"
arch = uname.machine.lower()
if arch == "amd64":
arch = "x86_64"
url = f"{REPO}/releases/download/{tag}/dtk-{platform}-{arch}{suffix}"
output = args.output
# print(f"Downloading {url} to {output}")
urllib.request.urlretrieve(url, output)
st = os.stat(output)
os.chmod(output, st.st_mode | stat.S_IEXEC)
if __name__ == "__main__":
main()
-504
View File
File diff suppressed because it is too large Load Diff
-114
View File
@@ -1,114 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define VERSION_MAX_LEN (size_t)(35)
#define METROID_BUILD_INFO_TAG "!#$MetroidBuildInfo!#$"
void* memmem(const void* l, size_t l_len, const void* s, size_t s_len) {
register char *cur, *last;
const char* cl = (const char*)l;
const char* cs = (const char*)s;
/* we need something to compare */
if (l_len == 0 || s_len == 0)
return NULL;
/* "s" must be smaller or equal to "l" */
if (l_len < s_len)
return NULL;
/* special case where s_len == 1 */
if (s_len == 1)
return memchr(l, (int)*cs, l_len);
/* the last position where its possible to find "s" in "l" */
last = (char*)cl + l_len - s_len;
for (cur = (char*)cl; cur <= last; cur++)
if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0)
return cur;
return NULL;
}
int main(int argc, const char* argv[]) {
if (argc < 3) {
fprintf(stdout, "\t--- METROID BUILD INFO ---\n"
"\tWritten by Phillip \"Antidote\" Stephens\n"
"\tReleased under the MIT License\n\n"
"\tSets the MetroidBuildInfo tag value in a given binary\n"
"\tThe version string can be a maximum of 35 characters,\n"
"\texcluding null terminator\n"
"\t--------------------------\n"
);
fprintf(stdout, "Usage:\n"
"\tmetroidbuildinfo <binary> <build_file>\n");
return -1;
}
/* Let's try to get the source binary */
FILE* source = fopen(argv[1], "rb");
if (!source) {
fprintf(stderr, "Unable to open '%s'\nPlease ensure the file exists!\n", argv[1]);
return -2;
}
char build_string[36] = {0};
FILE* build = fopen(argv[2], "rb");
if (!build) {
fprintf(stderr, "Unable to open '%s'\nPlease ensure the file exists!\n", argv[2]);
return -3;
}
size_t read_len = fread(build_string, 1, 35, build);
fclose(build);
if (read_len <= 0) {
fprintf(stderr, "Empty file %s specified for build version!\n", argv[2]);
return -4;
}
build_string[strcspn(build_string, "\r\n")] = '\0';
/* Get source length */
fseek(source, 0, SEEK_END);
size_t source_len = ftell(source);
rewind(source);
void* source_buf = malloc(source_len);
if (source_buf == NULL) {
fprintf(stderr, "Unable to allocate buffer of size %zubytes!\n", source_len);
return -5;
}
fread(source_buf, 1, source_len, source);
fclose(source);
/* Find the build info tag so we can stuff our version info in the binary */
void* ptr =
memmem(source_buf, source_len, METROID_BUILD_INFO_TAG, strlen(METROID_BUILD_INFO_TAG));
if (ptr == NULL) {
fprintf(stderr, "Unable to find build info tag in source!\n");
return -6;
}
/* Lets actually copy over the build string */
strcpy(ptr + strlen(METROID_BUILD_INFO_TAG), build_string);
/* Now attempt to open the target file */
FILE* target = fopen(argv[1], "wb");
if (!target) {
fprintf(stderr, "Unable to open '%s'\nPlease ensure you have write permissions!\n", argv[1]);
return -7;
}
/* Finally write the buffer to the target file */
fwrite(source_buf, 1, source_len, target);
fclose(target);
/* Don't leak */
free(source_buf);
return 0;
}