Restructure build workflow

* All segments are now extracted from the base ROM; the base ROM is no
longer a compile time dependency
* ROM segments are now positioned relatively to each rather than with
hard coded addresses
* Piracy checksums are calculated during build
This commit is contained in:
Ryan Dwyer committed 2020-08-25 20:40:35 +10:00
1 parent 4fd334f73a
commit 23b6bd2643
34 files changed
+3239 -2725

No files matched your search

+150 -189
View File
@@ -1,6 +1,7 @@
# User configurable
ROMID ?= ntsc-final
MATCHING ?= 1
PIRACYCHECKS ?= 1
QEMU_IRIX ?= tools/irix/qemu-irix
@@ -67,7 +68,7 @@ CFLAGS := -DVERSION=$(VERSION) \
-I src/include \
-mips2
C_FILES := $(shell find src/boot src/lib src/game src/inflate src/gvars src/mpconfigs src/mpstrings/$(ROMID) src/firingrange -name '*.c')
C_FILES := $(shell find src/boot src/lib src/game src/inflate src/gvars src/mpconfigs src/mpstrings/$(ROMID) src/firingrange src/filenames -name '*.c')
O_FILES := $(patsubst src/%.c, $(B_DIR)/%.o, $(C_FILES))
ASSET_AUDIO_FILES := Arecep01M Arecep02M Arecep03M Arecep04M Arecep05M Arecep06M Arlguard1M Arltech01M Arltech02M Arltech03M Arltech04M Arltech05M Arltech06M Ascie2aM Ascie2bM Ascie2cM Ascie2dM Ascie2eM Ascie2fM Ascie2gM Ascie3aM Ascie3bM Ascie3cM Ascie3dM Ascie3eM Ascie3gM Ascien10aM Ascien2_aM Ascien3_aM Ascien4_aM Ascien5_aM Ascien6_aM Ascien7_aM Ascien9_aM AvilgrimM Awepgd01M Awepgd02M Awepgd03M Awepsc01M Awepsc02M Awepsc03M Aa51elv01M Aa51elv02M Aa51elv03M Aa51grd01M Aa51grd02M Aa51grd03M Aa51grd04M Aa51grd05M Aa51grd06M Aa51grd07M Aa51grd08M Aa51grd09M Aa51grd10M Aa51jo1M Aa51jo2M Aa51jo3M Aa51jo4M Aa51jo5M Aa51jo6M Aa51jon01M Aa51jon02M Aa51jon03M Aa51jon04M Aa51jon05M Aa51jon06M Aa51jon07M Aa51jon08M Aa51jon09M Aa51jon10M Aa51jon11M Aa51jon12M Aa51jon14M Aa51jon15M Aa51sci1M Aaf1jo01M Aaf1jo02M Aaf1jo03M Aaf1pr01M Aaf1pr02M Aaf1pr03M Aaf1pr04M Aaf1pr05M Aaf1pr06M Aaf1pr07M Aaf1pr08M Aaf1pr09M Aaf1pr10M Aaf1tr01M Aaf1tr02M Aaf1tr03M Aairbgd01M Aairbgd02M Aairbgd03M Aairbgd04M Aairbgd05M Aairbgd06M Aairbgd07M Aairbgd08M Aairbgd09M Aairbgd10M Aairbgd11M Aairbgd12M Aairbgd13M Aairbgd14M Aairbgd15M Aairbgd16M Aairstw01M Aairstw02M Aairstw03M Aassael01M Aassael02M Aassael03M Aassael04M Aassael05M Aassael06M Absewrk01M Absewrk02M Absewrk03M Absewrk04M Absewrk05M Acetael01M Achdroid1M Achdroid2M Acsec01M Acsec02M Acsec03M Acstan1M Acstan2M Adevr01M Adevr02M Adevr03M Adevr04M Adevr05M Adevr06M Adevr07M Adevr08M Adevr09M Adevr10M Adevr11M Adevr12M Aexec01M Aexec02M Aexec04M Aexec05M Aexec06M Aexec07M Aexec08M Aexec09M Aexec10M Aexec11M Aexec12M Aexec13M Aexec14M Ahelic01M Ahelic02M Ahelic03M Ahologd01M AholohopkM Ainvcar01M Ainvcar02M Ainvcar03M Ainvcar04M Ainvcar05M Ainvcar06M Ainvcar07M Ainvcar08M Ainvcar09M Ainvcar10M Ainvcar11M Ainvcar12M AinvfarrM AinvfemaM AinvfostM AinvgrimM AinvhopkM AinvmaleM Ajoexec01M Ajoexec02M Ajosci01M Ajosci02M Ajosci03M Alabacc1M Alabacc2M Alabacc3M Alabacc4M Alabacc5M Alabacc6M Alabtech1M Alabtech2M Alabtech3M Alabtech5M Alabtech6M Alabtech7M Alabtech8M Alabtech9M Aoffwrk01M Aoffwrk02M Aoffwrk03M Aoffwrk04M Am1_l1_aM Am1_l1_bM Am1_l1_cM Am1_l1_dM Am1_l2_aM Am1_l2_bM Am1_l2_cM Am1_l2_dM Am1_l3_aM Am1_l3_bM Am1_l3_cM Am1_l3_dM Am2_l1_aM Am2_l1_bM Am2_l1_cM Am2_l1_dM Am3_l1_aM Am3_l1_bM Am3_l1_cM Am3_l1_dM Am3_l2_aM Am3_l2_bM Am3_l2_cM Am3_l2_dM Am4_l1_aM Am4_l1_bM Am4_l1_cM Am4_l1_dM Am4_l2_aM Am4_l2_bM Am4_l2_cM Am4_l2_dM Am4_l3_aM Am4_l3_bM Am4_l3_cM Am4_l3_dM Am5_l1_aM Am5_l1_bM Am5_l1_cM Am5_l1_dM Am5_l2_aM Am5_l2_bM Am5_l2_cM Am5_l2_dM Am5_l3_aM Am5_l3_bM Am5_l3_cM Am5_l3_dM Am6_l1_aM Am6_l1_bM Am6_l1_cM Am6_l1_dM Am6_l2_aM Am6_l2_bM Am6_l2_cM Am6_l2_dM Am7_l1_aM Am7_l1_bM Am7_l1_cM Am7_l1_dM Am8_l1_aM Am8_l1_bM Am8_l1_cM Am8_l1_dM Am9_l1_aM Am9_l1_bM Am9_l1_cM Am9_l1_dM Ap1_01_joM Ap1_02_caM Ap1_03_joM Ap1_04_caM Ap1_05_joM Ap1_06_caM Ap1_07_joM Ap1_08_caM Ap2_01_joM Ap2_02_joM Ap2_03_drM Ap2_04_joM Ap2_05_joM Ap2_06_drM Ap2_07_drM Ap3_01_gdM Ap3_02_joM Ap3_03_joM Ap4_01_dvM Ap4_02_joM Ap4_03_dvM Ap4_04_joM Ap4_05_dvM Ap4_06_joM Ap4_07_blM Ap4_08_dvM Ap4_09_dvM Ap5_01_joM Ap5_02_joM Ap5_03_joM Ap6_01_joM Ap6_02_caM Ap6_03_joM Ap6_04_caM Ap6_05_joM Ap6_06_caM Ap7_01_caM Ap7_02_joM Ap7_03_caM Ap7_04_joM Ap8_01_dvM Ap8_02_blM Ap8_03_dvM Ap8_04_blM Ap8_06_blM Ap8_07_trM Ap8_08_dvM Ap8_09_trM Ap8_10_blM Ap9_01_joM Ap9_02_caM Ap9_03_joM Ap10_01_caM Ap10_02_caM Ap10_03_caM Ap10_04_caM Ap10_05_joM Ap10_06_caM Ap10_07_joM Ap10_08_caM Ap10_09_joM Ap11_01_jnM Ap11_02_joM Ap11_03_jnM Ap11_04_joM Ap11_05_jnM Ap11_06_joM Ap11_07_jnM Ap11_08_joM Ap12_01_jnM Ap12_02_joM Ap12_03_jnM Ap12_04_joM Ap12_05_jnM Ap12_06_joM Ap12_07_jnM Ap12_08_joM Ap12_09_jnM Ap12_10_joM Ap13_01_joM Ap13_02_suM Ap13_03_joM Ap13_04_suM Ap13_06_suM Ap14_03_suM Ap14_04_joM Ap14_05_suM Ap14_07_joM Ap15_01_elM Ap15_02_elM Ap15_03_joM Ap15_04_jnM Ap15_05_elM Ap15_06_joM Ap15_07_elM Ap15_08_joM Ap15_09_elM Ap15_10_joM Ap15_11_elM Ap16_01_joM Ap16_02_caM Ap16_04_caM Ap16_05_joM Ap16_06_caM Ap17_01_trM Ap17_02_prM Ap17_03_trM Ap17_04_prM Ap17_05_trM Ap17_06_trM Ap18_01_joM Ap18_02_elM Ap18_03_elM Ap18_04_joM Ap18_05_elM Ap19_01_caM Ap19_02_caM Ap19_03_joM Ap19_04_caM Ap19_05_joM Ap19_06_joM Ap20_01_joM Ap20_02_prM Ap20_03_joM Ap20_04_prM Ap20_05_joM Ap20_06_blM Ap20_07_trM Ap20_08_trM Ap21_01_elM Ap21_02_joM Ap21_03_elM Ap21_04_joM Ap22_01_elM Ap22_02_joM Ap22_03_elM Ap22_04_joM Ap23_01_joM Ap23_02_drM Ap23_03_joM Ap23_04_drM Ap23_05_joM Ap23_06_drM Ap23_07_joM Ap23_08_drM Ap24_01_caM Ap24_02_joM Ap24_03_caM Ap24_04_joM Ap24_05_caM Ap24_06_caM Ap24_07_joM Ap24_08_joM Ap25_01_joM Ap25_02_joM Ap26_01_joM Ap26_02_dvM Ap26_03_joM Ap26_04_dvM Ap26_05_dvM Ap26_06_joM Ap26_07_dvM Ap26_08_dvM Ap27_01_joM Ap27_02_elM Ap27_03_elM Ap27_04_joM Ap27_05_joM Ap27_06_elM Ap28_01_elM Ap28_02_joM Ap28_03_elM Ap28_04_joM Ap28_05_elM Ap28_06_joM Ap29_01_elM Ap29_02_joM Ap29_03_elM Ap29_04_joM Ap29_05_joM Ap29_06_elM Ap29_07_joM Ap29_08_elM Ap29_09_joM Ap29_10_elM Apelelv01M Apelgrd01M Ap29_11_joM Am3l2carrM Aelvcet01M Aelvcet02M Ajorep01M Line truncated
@@ -113,56 +114,139 @@ ASSET_FILES := $(ASSET_AUDIO_FILES) $(ASSET_CHR_FILES) $(ASSET_GUN_FILES) $(ASSE
ASSET_O_FILES := $(patsubst %, %.o, $(ASSET_FILES))
UCODE_BIN_FILES := \
$(B_DIR)/ucode/boot.bin \
$(B_DIR)/ucode/filenames.bin \
$(B_DIR)/ucode/firingrange.bin \
$(B_DIR)/ucode/game.bin \
$(B_DIR)/ucode/gamedata.bin \
$(B_DIR)/ucode/gvars.bin \
$(B_DIR)/ucode/lib.bin \
$(B_DIR)/ucode/inflate.bin \
$(B_DIR)/ucode/mpconfigs.bin \
$(B_DIR)/ucode/mpstringsE.bin \
$(B_DIR)/ucode/mpstringsJ.bin \
$(B_DIR)/ucode/mpstringsP.bin \
$(B_DIR)/ucode/mpstringsG.bin \
$(B_DIR)/ucode/mpstringsF.bin \
$(B_DIR)/ucode/mpstringsS.bin \
$(B_DIR)/ucode/mpstringsI.bin
SEGMENT_O_FILES := \
$(B_DIR)/accessingpak.o \
$(B_DIR)/animations.o \
$(B_DIR)/copyright.o \
$(B_DIR)/fonts.o \
$(B_DIR)/romheader.o \
$(B_DIR)/rspboot.o \
$(B_DIR)/seq.ctl.o \
$(B_DIR)/seq.tbl.o \
$(B_DIR)/sfx.ctl.o \
$(B_DIR)/sfx.tbl.o \
$(B_DIR)/sequences.o \
$(B_DIR)/textures.o \
$(B_DIR)/unknown1.o \
$(B_DIR)/unknown2.o
default: all
default: rom
################################################################################
# Audio files
# ROM Finalisation Stages
# The final ROM image takes stage3 and calculates the ROM CRC.
$(B_DIR)/pd.z64: $(B_DIR)/stage3.bin $(ASSET_FILES)
@cp $< $@.tmp
tools/patchromcrc $@.tmp --write && mv $@.tmp $@
# Stage3 takes stage2, compresses the code segments, inserts them and truncates
# the ROM to 32MB.
$(B_DIR)/stage3.bin: $(B_DIR)/stage2.bin $(B_DIR)/segments/gamezips.bin
@cp $< $@.tmp
MATCHING=$(MATCHING) tools/packrom $@.tmp && mv $@.tmp $@
# Stage2 takes stage1 and calculates the piracy checksums.
$(B_DIR)/stage2.bin: $(B_DIR)/stage1.bin
@cp $< $@.tmp
PIRACYCHECKS=$(PIRACYCHECKS) tools/patchpiracysums $@.tmp $(B_DIR)/pd.map && mv $@.tmp $@
$(B_DIR)/stage1.bin: $(B_DIR)/stage1.elf
$(TOOLCHAIN)-objcopy $< $@ -O binary
# Link all objects together with ld to make stage1.elf
$(B_DIR)/stage1.elf: $(O_FILES) $(SEGMENT_O_FILES) $(ASSET_O_FILES) ld/pd.ld
cpp -DROMID=$(ROMID) -DVERSION=$(VERSION) -P ld/pd.ld -o $(B_DIR)/pd.ld
$(TOOLCHAIN)-ld --no-check-sections -T $(B_DIR)/pd.ld --print-map -o $@ > $(B_DIR)/pd.map
$(B_DIR)/segments/gamezips.bin: $(B_DIR)/segments/game.bin
ROMID=$(ROMID) tools/mkgamezips
################################################################################
# Testing Related
# ---------------------
# This works a little backwards, in that the ROM has to be built to at least
# stage 2, then extract-segment is used to slice out the segments.
SEGMENT_FILES := \
$(B_DIR)/segments/boot.bin \
$(B_DIR)/segments/filenames.bin \
$(B_DIR)/segments/firingrange.bin \
$(B_DIR)/segments/game.bin \
$(B_DIR)/segments/data.bin \
$(B_DIR)/segments/gvars.bin \
$(B_DIR)/segments/lib.bin \
$(B_DIR)/segments/inflate.bin \
$(B_DIR)/segments/mpconfigs.bin \
$(B_DIR)/segments/mpstringsE.bin \
$(B_DIR)/segments/mpstringsJ.bin \
$(B_DIR)/segments/mpstringsP.bin \
$(B_DIR)/segments/mpstringsG.bin \
$(B_DIR)/segments/mpstringsF.bin \
$(B_DIR)/segments/mpstringsS.bin \
$(B_DIR)/segments/mpstringsI.bin
test: $(SEGMENT_FILES) $(ASSET_FILES)
@md5sum --quiet -c checksums.$(ROMID).md5
$(B_DIR)/segments/%.bin: $(B_DIR)/stage2.bin
@B_DIR=$(B_DIR) tools/extract-segment $*
################################################################################
# Raw data segments
$(B_DIR)/animations.o: $(E_DIR)/segments/animations.bin
TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@
$(B_DIR)/fonts.o: $(E_DIR)/segments/fonts.bin
TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@
$(B_DIR)/rspboot.o: $(E_DIR)/segments/rspboot.bin
TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@
$(B_DIR)/seq.ctl.o: $(E_DIR)/segments/seq.ctl.bin
TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@
$(B_DIR)/seq.tbl.o: $(E_DIR)/segments/seq.tbl.bin
TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@
$(B_DIR)/sfx.ctl.o: $(E_DIR)/segments/sfx.ctl.bin
TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@
$(B_DIR)/sfx.tbl.o: $(E_DIR)/segments/sfx.tbl.bin
TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@
$(B_DIR)/sequences.o: $(E_DIR)/segments/sequences.bin
TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@
$(B_DIR)/textures.o: $(E_DIR)/segments/textures.bin
TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@
$(B_DIR)/unknown1.o: $(E_DIR)/segments/unknown1.bin
TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@
$(B_DIR)/unknown2.o: $(E_DIR)/segments/unknown2.bin
TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@
################################################################################
# Files
# Audio
$(B_DIR)/files/A%M: $(E_DIR)/files/A%M
@mkdir -p $(B_DIR)/files
cp $< $@
audio: $(ASSET_AUDIO_FILES)
################################################################################
# BG seg files
# BG segs
$(B_DIR)/files/bgdata/bg_%.seg: $(E_DIR)/files/bgdata/bg_%.seg
@mkdir -p $(B_DIR)/files/bgdata
cp $< $@
bgsegs: $(ASSET_BG_SEG_FILES)
################################################################################
# BG pad files
# BG pads
$(B_DIR)/files/bgdata/bg_%_padsZ: $(E_DIR)/files/bgdata/bg_%_padsZ
@mkdir -p $(B_DIR)/files/bgdata
cp $< $@
pads: $(ASSET_BG_PADS_FILES)
################################################################################
# BG tile files
# BG tiles
src/files/bgdata/bg_%_tiles.o: src/files/bgdata/bg_%_tiles.s
$(TOOLCHAIN)-as --defsym VERSION=$(VERSION) -march=vr4300 -mabi=32 -I src/include -EB -o $@ $<
@@ -172,29 +256,17 @@ $(B_DIR)/files/bgdata/bg_%_tiles.elf: src/files/bgdata/bg_%_tiles.o
$(TOOLCHAIN)-ld -T ld/zero.ld -o $@
rm -f build/zero.tmp.o
tiles: $(ASSET_BG_TILES_FILES)
################################################################################
# Chr files
# Chrs
$(B_DIR)/files/C%Z: $(E_DIR)/files/C%Z
@mkdir -p $(B_DIR)/files
cp $< $@
chrs: $(ASSET_CHR_FILES)
################################################################################
# Gun files
# Guns
$(B_DIR)/files/G%Z: $(E_DIR)/files/G%Z
@mkdir -p $(B_DIR)/files
cp $< $@
guns: $(ASSET_GUN_FILES)
################################################################################
# Lang files
# Lang
$(B_DIR)/files/lang/L%.o: src/files/lang/$(ROMID)/%.c
@mkdir -p $(B_DIR)/files/lang
$(QEMU_IRIX) -silent -L $(IRIX_ROOT) $(IRIX_ROOT)/usr/bin/cc -c $(CFLAGS) $< -o $@ -O2
@@ -213,136 +285,29 @@ $(B_DIR)/files/L%J: $(B_DIR)/files/L%J.bin
$(B_DIR)/files/L%P: $(B_DIR)/files/L%P.bin
tools/rarezip $< > $@
lang: $(ASSET_LANG_FILES)
################################################################################
# OB seg files
# OB seg
$(B_DIR)/files/ob/ob_mid.seg:
@mkdir -p $(B_DIR)/files/ob
> $@
obseg: $(ASSET_OB_SEG_FILES)
################################################################################
# Prop files
# Props
$(B_DIR)/files/P%Z: $(E_DIR)/files/P%Z
@mkdir -p $(B_DIR)/files
cp $< $@
props: $(ASSET_PROP_FILES)
################################################################################
# Stage setup files
# Stage setups
$(B_DIR)/files/U%.elf: $(B_DIR)/files/setup/%.o
@mkdir -p $(B_DIR)/files
cp $< build/zero.tmp.o
$(TOOLCHAIN)-ld -T ld/zero.ld -o $@
rm -f build/zero.tmp.o
stagesetup: $(ASSET_SPSETUP_FILES) $(ASSET_MPSETUP_FILES)
################################################################################
# Boot
$(B_DIR)/ucode/boot.bin: $(B_DIR)/pd.bin
@mkdir -p $(B_DIR)/ucode
@B_DIR=$(B_DIR) tools/extract-segment boot
boot: $(B_DIR)/ucode/boot.bin
################################################################################
# Lib
$(B_DIR)/ucode/lib.bin: $(B_DIR)/pd.bin
@mkdir -p $(B_DIR)/ucode
@B_DIR=$(B_DIR) tools/extract-segment lib
lib: $(B_DIR)/ucode/lib.bin
################################################################################
# Game data file
$(B_DIR)/ucode/gamedata.bin: $(B_DIR)/pd.bin
@mkdir -p $(B_DIR)/ucode
@B_DIR=$(B_DIR) tools/extract-segment gamedata
setup: $(B_DIR)/ucode/gamedata.bin
################################################################################
# Inflate
$(B_DIR)/ucode/inflate.bin: $(B_DIR)/pd.bin
@mkdir -p $(B_DIR)/ucode
@B_DIR=$(B_DIR) tools/extract-segment inflate
inflate: $(B_DIR)/ucode/inflate.bin
################################################################################
# Main game
$(B_DIR)/ucode/game.bin: $(B_DIR)/pd.bin
@mkdir -p $(B_DIR)/ucode
@B_DIR=$(B_DIR) tools/extract-segment game
game: $(B_DIR)/ucode/game.bin
################################################################################
# gVars
$(B_DIR)/ucode/gvars.bin: $(B_DIR)/pd.bin
@mkdir -p $(B_DIR)/ucode
@B_DIR=$(B_DIR) tools/extract-segment gvars
gvars: $(B_DIR)/ucode/gvars.bin
################################################################################
# MpConfigs
$(B_DIR)/ucode/mpconfigs.bin: $(B_DIR)/pd.bin
@mkdir -p $(B_DIR)/ucode
@B_DIR=$(B_DIR) tools/extract-segment mpconfigs
mpconfigs: $(B_DIR)/ucode/mpconfigs.bin
################################################################################
# MpStrings
$(B_DIR)/ucode/mpstrings%.bin: $(B_DIR)/pd.bin
@mkdir -p $(B_DIR)/ucode
@B_DIR=$(B_DIR) tools/extract-segment $(notdir $(basename $@))
mpstrings: $(B_DIR)/ucode/mpstringsE.bin \
$(B_DIR)/ucode/mpstringsJ.bin \
$(B_DIR)/ucode/mpstringsP.bin \
$(B_DIR)/ucode/mpstringsG.bin \
$(B_DIR)/ucode/mpstringsF.bin \
$(B_DIR)/ucode/mpstringsS.bin \
$(B_DIR)/ucode/mpstringsI.bin
################################################################################
# Miscellaneous
extract:
ROMID=$(ROMID) tools/extract
$(B_DIR)/ucode/gamezips.bin: $(B_DIR)/ucode/game.bin
tools/mkgamezips
test: all
@md5sum --quiet -c checksums.$(ROMID).md5
# General target to convert any finalised file into a raw object for ld
$(B_DIR)/files/%.o: $(B_DIR)/files/%
/bin/echo -e ".data\n.incbin \"$<\"" > $(B_DIR)/file.s
$(TOOLCHAIN)-as -mabi=32 -mips2 -I src/include -EB -o $@ $(B_DIR)/file.s
rm -f file.s
TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@
$(B_DIR)/%.o: src/%.c
@mkdir -p $(dir $@)
/usr/bin/env python3 tools/asmpreproc/asm-processor.py -O2 $< | $(QEMU_IRIX) -silent -L $(IRIX_ROOT) $(IRIX_ROOT)/usr/bin/cc -c $(CFLAGS) tools/asmpreproc/include-stdin.c -o $@ -O2
/usr/bin/env python3 tools/asmpreproc/asm-processor.py -O2 $< --post-process $@ --assembler "$(TOOLCHAIN)-as -march=vr4300 -mabi=32" --asm-prelude tools/asmpreproc/prelude.s
################################################################################
# Testing Files
$(B_DIR)/files/%.bin: $(B_DIR)/files/%.elf
$(TOOLCHAIN)-objcopy $< $@ -O binary
@@ -350,37 +315,33 @@ $(B_DIR)/files/%.bin: $(B_DIR)/files/%.elf
$(B_DIR)/files/%Z: $(B_DIR)/files/%.bin
tools/rarezip $< > $@
$(B_DIR)/ucode/filenames.elf: $(B_DIR)/filenames.o
@mkdir -p $(B_DIR)/ucode
cp $< build/zero.tmp.o
$(TOOLCHAIN)-ld -T ld/zero.ld -o $@
rm -f build/zero.tmp.o
################################################################################
# Miscellaneous
$(B_DIR)/ucode/filenames.bin: $(B_DIR)/ucode/filenames.elf
$(TOOLCHAIN)-objcopy $< $@ -O binary
$(B_DIR)/romheader.o: src/romheader/romheader.s
$(TOOLCHAIN)-as --defsym VERSION=$(VERSION) -march=vr4300 -mabi=32 -I src/include -EB -o $@ $<
$(B_DIR)/ucode/firingrange.elf: $(B_DIR)/firingrange/firingrange.o
@mkdir -p $(B_DIR)/ucode
cp $< build/zero.tmp.o
$(TOOLCHAIN)-ld -T ld/zero.ld -o $@
rm -f build/zero.tmp.o
$(B_DIR)/accessingpak.bin: $(E_DIR)/segments/accessingpak.bin
tools/rarezip $< > $@
$(B_DIR)/ucode/firingrange.bin: $(B_DIR)/ucode/firingrange.elf
$(TOOLCHAIN)-objcopy $< $@ -O binary
$(B_DIR)/copyright.bin: $(E_DIR)/segments/copyright.bin
tools/rarezip $< > $@
$(B_DIR)/pd.elf: $(O_FILES) $(ASSET_O_FILES) ld/pd.ld
cpp -DROMID=$(ROMID) -DVERSION=$(VERSION) -P ld/pd.ld -o $(B_DIR)/pd.ld
$(TOOLCHAIN)-ld --no-check-sections -T $(B_DIR)/pd.ld --print-map -o $@ > $(B_DIR)/pd.map
$(B_DIR)/accessingpak.o: $(B_DIR)/accessingpak.bin
TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@
$(B_DIR)/pd.bin: $(B_DIR)/pd.elf
@mkdir -p $(B_DIR)/ucode
$(TOOLCHAIN)-objcopy $< $@ -O binary
$(B_DIR)/copyright.o: $(B_DIR)/copyright.bin
TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@
all: $(UCODE_BIN_FILES) $(ASSET_O_FILES)
$(B_DIR)/%.o: src/%.c
@mkdir -p $(dir $@)
/usr/bin/env python3 tools/asmpreproc/asm-processor.py -O2 $< | $(QEMU_IRIX) -silent -L $(IRIX_ROOT) $(IRIX_ROOT)/usr/bin/cc -c $(CFLAGS) tools/asmpreproc/include-stdin.c -o $@ -O2
/usr/bin/env python3 tools/asmpreproc/asm-processor.py -O2 $< --post-process $@ --assembler "$(TOOLCHAIN)-as -march=vr4300 -mabi=32" --asm-prelude tools/asmpreproc/prelude.s
rom: $(UCODE_BIN_FILES) $(B_DIR)/ucode/gamezips.bin $(ASSET_O_FILES)
TOOLCHAIN=$(TOOLCHAIN) tools/buildrom
tools/checksum $(B_DIR)/pd.z64 --write
extract:
ROMID=$(ROMID) tools/extract
rom: $(B_DIR)/pd.z64
clean:
rm -rf build/$(ROMID)
@@ -389,5 +350,5 @@ allclean:
rm -rf build/*
codeclean:
rm -f $(B_DIR)/ucode/*.bin
rm -f $(B_DIR)/segments/*.bin
find $(B_DIR)/{boot,game,gvars,inflate,lib} -name '*.o' -delete
-1
View File
@@ -38,7 +38,6 @@ Before you do anything you need an existing ROM to extract assets from.
## Compiling
* Run `make` to build the assets that will be included in the ROM. These files will be written to `build/ntsc-final` and are matching what's in the `extracted/ntsc-final` folder.
* Run `make rom` to build the ROM. The ROM will be written to `build/ntsc-final/pd.z64`.
## How do I know the built files are matching?
+15 -14
View File
@@ -2013,17 +2013,18 @@ ea5a2ff4e5e0a68822f62feff2c40af4 build/jap-final/files/bgdata/bg_uff_tilesZ
f0068491f441172310f2b6868c03739d build/jap-final/files/bgdata/bg_wax_padsZ
ea5a2ff4e5e0a68822f62feff2c40af4 build/jap-final/files/bgdata/bg_wax_tilesZ
d41d8cd98f00b204e9800998ecf8427e build/jap-final/files/ob/ob_mid.seg
39ef58f5babf5d619bec8b2629c26bc8 build/jap-final/ucode/boot.bin
333e8b4f6fe9dc9b59cf3e61b4e0c224 build/jap-final/ucode/firingrange.bin
bd6e5fc360d5e0c35ea3605e2514f205 build/jap-final/ucode/game.bin
22d5e92bffcc67b222cf3697e96106f6 build/jap-final/ucode/gamedata.bin
843285fdc0e80a77576eeb73940d2fd3 build/jap-final/ucode/inflate.bin
c550660ff4ba024113ddb38103bf79f8 build/jap-final/ucode/lib.bin
c47d9377956666bc0e77d6cba3dc68fb build/jap-final/ucode/mpconfigs.bin
529b54a03375af2ff74eb3367cbac294 build/jap-final/ucode/mpstringsE.bin
4d1eb9e58e090aa91301917c518b5b5f build/jap-final/ucode/mpstringsF.bin
0dfdacb249cb79aacb979509015fbab9 build/jap-final/ucode/mpstringsG.bin
3df64b3553f9d9b77f55e7abaccb8e04 build/jap-final/ucode/mpstringsI.bin
b60f7439adaf8b1e150ab54b590da411 build/jap-final/ucode/mpstringsJ.bin
529b54a03375af2ff74eb3367cbac294 build/jap-final/ucode/mpstringsP.bin
9e9ad9fdc9b6a3c249a370760fa23b26 build/jap-final/ucode/mpstringsS.bin
538d2b75945eae069b29c46193e74790 build/jap-final/pd.z64
39ef58f5babf5d619bec8b2629c26bc8 build/jap-final/segments/boot.bin
333e8b4f6fe9dc9b59cf3e61b4e0c224 build/jap-final/segments/firingrange.bin
bd6e5fc360d5e0c35ea3605e2514f205 build/jap-final/segments/game.bin
22d5e92bffcc67b222cf3697e96106f6 build/jap-final/segments/data.bin
843285fdc0e80a77576eeb73940d2fd3 build/jap-final/segments/inflate.bin
c550660ff4ba024113ddb38103bf79f8 build/jap-final/segments/lib.bin
c47d9377956666bc0e77d6cba3dc68fb build/jap-final/segments/mpconfigs.bin
529b54a03375af2ff74eb3367cbac294 build/jap-final/segments/mpstringsE.bin
4d1eb9e58e090aa91301917c518b5b5f build/jap-final/segments/mpstringsF.bin
0dfdacb249cb79aacb979509015fbab9 build/jap-final/segments/mpstringsG.bin
3df64b3553f9d9b77f55e7abaccb8e04 build/jap-final/segments/mpstringsI.bin
b60f7439adaf8b1e150ab54b590da411 build/jap-final/segments/mpstringsJ.bin
529b54a03375af2ff74eb3367cbac294 build/jap-final/segments/mpstringsP.bin
9e9ad9fdc9b6a3c249a370760fa23b26 build/jap-final/segments/mpstringsS.bin
+15 -14
View File
@@ -2011,17 +2011,18 @@ ea5a2ff4e5e0a68822f62feff2c40af4 build/ntsc-1.0/files/bgdata/bg_uff_tilesZ
f0068491f441172310f2b6868c03739d build/ntsc-1.0/files/bgdata/bg_wax_padsZ
ea5a2ff4e5e0a68822f62feff2c40af4 build/ntsc-1.0/files/bgdata/bg_wax_tilesZ
d41d8cd98f00b204e9800998ecf8427e build/ntsc-1.0/files/ob/ob_mid.seg
402561223a33f48461e302e1cca12129 build/ntsc-1.0/ucode/boot.bin
cb373c94109322d081a57b142fdd9999 build/ntsc-1.0/ucode/firingrange.bin
5181a0d11cf8f24370a3f2d3b29e522e build/ntsc-1.0/ucode/game.bin
b21679a1b2dabd721bc4afee11bf5266 build/ntsc-1.0/ucode/gamedata.bin
843285fdc0e80a77576eeb73940d2fd3 build/ntsc-1.0/ucode/inflate.bin
3155eece856e9fbd9bc47d03463cfc1b build/ntsc-1.0/ucode/lib.bin
fe4034c01c91bd10e488fe93389b4104 build/ntsc-1.0/ucode/mpconfigs.bin
529b54a03375af2ff74eb3367cbac294 build/ntsc-1.0/ucode/mpstringsE.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-1.0/ucode/mpstringsF.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-1.0/ucode/mpstringsG.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-1.0/ucode/mpstringsI.bin
302f7aa0464c781187551fcd3870aec2 build/ntsc-1.0/ucode/mpstringsJ.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-1.0/ucode/mpstringsP.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-1.0/ucode/mpstringsS.bin
7f4171b0c8d17815be37913f535e4e93 build/ntsc-1.0/pd.z64
402561223a33f48461e302e1cca12129 build/ntsc-1.0/segments/boot.bin
cb373c94109322d081a57b142fdd9999 build/ntsc-1.0/segments/firingrange.bin
5181a0d11cf8f24370a3f2d3b29e522e build/ntsc-1.0/segments/game.bin
b21679a1b2dabd721bc4afee11bf5266 build/ntsc-1.0/segments/data.bin
843285fdc0e80a77576eeb73940d2fd3 build/ntsc-1.0/segments/inflate.bin
3155eece856e9fbd9bc47d03463cfc1b build/ntsc-1.0/segments/lib.bin
fe4034c01c91bd10e488fe93389b4104 build/ntsc-1.0/segments/mpconfigs.bin
529b54a03375af2ff74eb3367cbac294 build/ntsc-1.0/segments/mpstringsE.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-1.0/segments/mpstringsF.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-1.0/segments/mpstringsG.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-1.0/segments/mpstringsI.bin
302f7aa0464c781187551fcd3870aec2 build/ntsc-1.0/segments/mpstringsJ.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-1.0/segments/mpstringsP.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-1.0/segments/mpstringsS.bin
+15 -14
View File
@@ -2010,17 +2010,18 @@ ea5a2ff4e5e0a68822f62feff2c40af4 build/ntsc-beta/files/bgdata/bg_uff_tilesZ
c6f0dd6193685637763d426dfce837fb build/ntsc-beta/files/bgdata/bg_wax_padsZ
ea5a2ff4e5e0a68822f62feff2c40af4 build/ntsc-beta/files/bgdata/bg_wax_tilesZ
d41d8cd98f00b204e9800998ecf8427e build/ntsc-beta/files/ob/ob_mid.seg
74cb41628ed5784a8ad48c6398b0ce83 build/ntsc-beta/ucode/boot.bin
a12b5437510403bb09b3cceb45dd2a10 build/ntsc-beta/ucode/firingrange.bin
daae19f7ce11d3f3e1f98d543ad856f5 build/ntsc-beta/ucode/game.bin
cab47b8c30b1be608c1c5c1db08342de build/ntsc-beta/ucode/gamedata.bin
d13f25c1c59fb96346ac23301ccd9d7d build/ntsc-beta/ucode/inflate.bin
14aa42e2f0f215d931900d25ab70e576 build/ntsc-beta/ucode/lib.bin
8aaec8cc806ec62d2f70eaa08282e9c0 build/ntsc-beta/ucode/mpconfigs.bin
d52a0fc2e90e03b610879b50df4c0fd4 build/ntsc-beta/ucode/mpstringsE.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-beta/ucode/mpstringsF.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-beta/ucode/mpstringsG.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-beta/ucode/mpstringsI.bin
302f7aa0464c781187551fcd3870aec2 build/ntsc-beta/ucode/mpstringsJ.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-beta/ucode/mpstringsP.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-beta/ucode/mpstringsS.bin
aa93f4df16fceada399a749f5ad2f273 build/ntsc-beta/pd.z64
74cb41628ed5784a8ad48c6398b0ce83 build/ntsc-beta/segments/boot.bin
a12b5437510403bb09b3cceb45dd2a10 build/ntsc-beta/segments/firingrange.bin
daae19f7ce11d3f3e1f98d543ad856f5 build/ntsc-beta/segments/game.bin
cab47b8c30b1be608c1c5c1db08342de build/ntsc-beta/segments/data.bin
d13f25c1c59fb96346ac23301ccd9d7d build/ntsc-beta/segments/inflate.bin
14aa42e2f0f215d931900d25ab70e576 build/ntsc-beta/segments/lib.bin
8aaec8cc806ec62d2f70eaa08282e9c0 build/ntsc-beta/segments/mpconfigs.bin
d52a0fc2e90e03b610879b50df4c0fd4 build/ntsc-beta/segments/mpstringsE.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-beta/segments/mpstringsF.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-beta/segments/mpstringsG.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-beta/segments/mpstringsI.bin
302f7aa0464c781187551fcd3870aec2 build/ntsc-beta/segments/mpstringsJ.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-beta/segments/mpstringsP.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-beta/segments/mpstringsS.bin
+15 -14
View File
@@ -2011,17 +2011,18 @@ ea5a2ff4e5e0a68822f62feff2c40af4 build/ntsc-final/files/bgdata/bg_uff_tilesZ
f0068491f441172310f2b6868c03739d build/ntsc-final/files/bgdata/bg_wax_padsZ
ea5a2ff4e5e0a68822f62feff2c40af4 build/ntsc-final/files/bgdata/bg_wax_tilesZ
d41d8cd98f00b204e9800998ecf8427e build/ntsc-final/files/ob/ob_mid.seg
2a1aa1eff3cdfe5dc3e91a2e773a55b9 build/ntsc-final/ucode/boot.bin
cb373c94109322d081a57b142fdd9999 build/ntsc-final/ucode/firingrange.bin
ed0462324d1287de21611707172d316a build/ntsc-final/ucode/game.bin
11c9c4c2737f66e7312949909b894dcc build/ntsc-final/ucode/gamedata.bin
843285fdc0e80a77576eeb73940d2fd3 build/ntsc-final/ucode/inflate.bin
6a227624d708b43a10f220e005aef486 build/ntsc-final/ucode/lib.bin
fe4034c01c91bd10e488fe93389b4104 build/ntsc-final/ucode/mpconfigs.bin
529b54a03375af2ff74eb3367cbac294 build/ntsc-final/ucode/mpstringsE.bin
302f7aa0464c781187551fcd3870aec2 build/ntsc-final/ucode/mpstringsJ.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-final/ucode/mpstringsP.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-final/ucode/mpstringsF.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-final/ucode/mpstringsG.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-final/ucode/mpstringsI.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-final/ucode/mpstringsS.bin
e03b088b6ac9e0080440efed07c1e40f build/ntsc-final/pd.z64
2a1aa1eff3cdfe5dc3e91a2e773a55b9 build/ntsc-final/segments/boot.bin
cb373c94109322d081a57b142fdd9999 build/ntsc-final/segments/firingrange.bin
ed0462324d1287de21611707172d316a build/ntsc-final/segments/game.bin
11c9c4c2737f66e7312949909b894dcc build/ntsc-final/segments/data.bin
843285fdc0e80a77576eeb73940d2fd3 build/ntsc-final/segments/inflate.bin
6a227624d708b43a10f220e005aef486 build/ntsc-final/segments/lib.bin
fe4034c01c91bd10e488fe93389b4104 build/ntsc-final/segments/mpconfigs.bin
529b54a03375af2ff74eb3367cbac294 build/ntsc-final/segments/mpstringsE.bin
302f7aa0464c781187551fcd3870aec2 build/ntsc-final/segments/mpstringsJ.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-final/segments/mpstringsP.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-final/segments/mpstringsF.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-final/segments/mpstringsG.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-final/segments/mpstringsI.bin
e4f45399a4f97e3fd6733f0f6919d28d build/ntsc-final/segments/mpstringsS.bin
+15 -14
View File
@@ -2011,17 +2011,18 @@ ea5a2ff4e5e0a68822f62feff2c40af4 build/pal-beta/files/bgdata/bg_uff_tilesZ
f0068491f441172310f2b6868c03739d build/pal-beta/files/bgdata/bg_wax_padsZ
ea5a2ff4e5e0a68822f62feff2c40af4 build/pal-beta/files/bgdata/bg_wax_tilesZ
d41d8cd98f00b204e9800998ecf8427e build/pal-beta/files/ob/ob_mid.seg
541e374b58a36056f73ad02a2bbb5f75 build/pal-beta/ucode/boot.bin
333e8b4f6fe9dc9b59cf3e61b4e0c224 build/pal-beta/ucode/firingrange.bin
ad5835b91b7e252ef8f4a421a44eb12b build/pal-beta/ucode/game.bin
bca5001a5dd0ef9aab24ba085f27eb40 build/pal-beta/ucode/gamedata.bin
843285fdc0e80a77576eeb73940d2fd3 build/pal-beta/ucode/inflate.bin
7a859fcb6e89426543b5a207cc388f82 build/pal-beta/ucode/lib.bin
fe4034c01c91bd10e488fe93389b4104 build/pal-beta/ucode/mpconfigs.bin
529b54a03375af2ff74eb3367cbac294 build/pal-beta/ucode/mpstringsE.bin
bed567631daf314f79ec8a2aa994f3a0 build/pal-beta/ucode/mpstringsF.bin
27be1b7f42826d0910b2fd549f969a63 build/pal-beta/ucode/mpstringsG.bin
fed3dc54a3564f477fb7d548ac365514 build/pal-beta/ucode/mpstringsI.bin
302f7aa0464c781187551fcd3870aec2 build/pal-beta/ucode/mpstringsJ.bin
529b54a03375af2ff74eb3367cbac294 build/pal-beta/ucode/mpstringsP.bin
d9501d67ead982fdd5cb5ffaf3091201 build/pal-beta/ucode/mpstringsS.bin
ad2de210a3455ba5ec541f0c78d91444 build/pal-beta/pd.z64
541e374b58a36056f73ad02a2bbb5f75 build/pal-beta/segments/boot.bin
333e8b4f6fe9dc9b59cf3e61b4e0c224 build/pal-beta/segments/firingrange.bin
ad5835b91b7e252ef8f4a421a44eb12b build/pal-beta/segments/game.bin
bca5001a5dd0ef9aab24ba085f27eb40 build/pal-beta/segments/data.bin
843285fdc0e80a77576eeb73940d2fd3 build/pal-beta/segments/inflate.bin
7a859fcb6e89426543b5a207cc388f82 build/pal-beta/segments/lib.bin
fe4034c01c91bd10e488fe93389b4104 build/pal-beta/segments/mpconfigs.bin
529b54a03375af2ff74eb3367cbac294 build/pal-beta/segments/mpstringsE.bin
bed567631daf314f79ec8a2aa994f3a0 build/pal-beta/segments/mpstringsF.bin
27be1b7f42826d0910b2fd549f969a63 build/pal-beta/segments/mpstringsG.bin
fed3dc54a3564f477fb7d548ac365514 build/pal-beta/segments/mpstringsI.bin
302f7aa0464c781187551fcd3870aec2 build/pal-beta/segments/mpstringsJ.bin
529b54a03375af2ff74eb3367cbac294 build/pal-beta/segments/mpstringsP.bin
d9501d67ead982fdd5cb5ffaf3091201 build/pal-beta/segments/mpstringsS.bin
+15 -14
View File
@@ -2011,17 +2011,18 @@ ea5a2ff4e5e0a68822f62feff2c40af4 build/pal-final/files/bgdata/bg_uff_tilesZ
f0068491f441172310f2b6868c03739d build/pal-final/files/bgdata/bg_wax_padsZ
ea5a2ff4e5e0a68822f62feff2c40af4 build/pal-final/files/bgdata/bg_wax_tilesZ
d41d8cd98f00b204e9800998ecf8427e build/pal-final/files/ob/ob_mid.seg
7c4233976802db99f90c6c0fede1080b build/pal-final/ucode/boot.bin
333e8b4f6fe9dc9b59cf3e61b4e0c224 build/pal-final/ucode/firingrange.bin
4e506821044251aecc10ec332389c576 build/pal-final/ucode/game.bin
1c49c171e829a5407f0ae5fd28a123cd build/pal-final/ucode/gamedata.bin
843285fdc0e80a77576eeb73940d2fd3 build/pal-final/ucode/inflate.bin
b83973db626573e024608444e5d74461 build/pal-final/ucode/lib.bin
7f5540dd6fff2039b2ce05bf57ac5611 build/pal-final/ucode/mpconfigs.bin
529b54a03375af2ff74eb3367cbac294 build/pal-final/ucode/mpstringsE.bin
4d1eb9e58e090aa91301917c518b5b5f build/pal-final/ucode/mpstringsF.bin
0dfdacb249cb79aacb979509015fbab9 build/pal-final/ucode/mpstringsG.bin
3df64b3553f9d9b77f55e7abaccb8e04 build/pal-final/ucode/mpstringsI.bin
302f7aa0464c781187551fcd3870aec2 build/pal-final/ucode/mpstringsJ.bin
529b54a03375af2ff74eb3367cbac294 build/pal-final/ucode/mpstringsP.bin
9e9ad9fdc9b6a3c249a370760fa23b26 build/pal-final/ucode/mpstringsS.bin
d9b5cd305d228424891ce38e71bc9213 build/pal-final/pd.z64
7c4233976802db99f90c6c0fede1080b build/pal-final/segments/boot.bin
333e8b4f6fe9dc9b59cf3e61b4e0c224 build/pal-final/segments/firingrange.bin
4e506821044251aecc10ec332389c576 build/pal-final/segments/game.bin
1c49c171e829a5407f0ae5fd28a123cd build/pal-final/segments/data.bin
843285fdc0e80a77576eeb73940d2fd3 build/pal-final/segments/inflate.bin
b83973db626573e024608444e5d74461 build/pal-final/segments/lib.bin
7f5540dd6fff2039b2ce05bf57ac5611 build/pal-final/segments/mpconfigs.bin
529b54a03375af2ff74eb3367cbac294 build/pal-final/segments/mpstringsE.bin
4d1eb9e58e090aa91301917c518b5b5f build/pal-final/segments/mpstringsF.bin
0dfdacb249cb79aacb979509015fbab9 build/pal-final/segments/mpstringsG.bin
3df64b3553f9d9b77f55e7abaccb8e04 build/pal-final/segments/mpstringsI.bin
302f7aa0464c781187551fcd3870aec2 build/pal-final/segments/mpstringsJ.bin
529b54a03375af2ff74eb3367cbac294 build/pal-final/segments/mpstringsP.bin
9e9ad9fdc9b6a3c249a370760fa23b26 build/pal-final/segments/mpstringsS.bin
+2014 -2016
View File
File diff suppressed because it is too large. Load diff
+408 -50
View File
@@ -8,36 +8,57 @@
#define VERSION_PAL_FINAL 4
#define VERSION_JAP_FINAL 5
#define BEGIN_SEG(name) \
_##name##SegmentStart = ADDR(.name); \
_##name##SegmentRomStart = __rompos; \
.name __rampos : AT(__rompos)
#define END_SEG(name) \
__rompos += SIZEOF(.name); \
__rampos = ADDR(.name) + SIZEOF(.name); \
_##name##SegmentEnd = ADDR(.name) + SIZEOF(.name); \
_##name##SegmentRomEnd = __rompos;
#define BEGIN_NOLOAD(name) \
_##name##SegmentStart = ADDR(.name); \
_##name##SegmentRomStart = __rompos; \
.name (NOLOAD) : AT(__rompos)
#define END_NOLOAD(name) \
__rompos += SIZEOF(.name); \
_##name##SegmentEnd = ADDR(.name) + SIZEOF(.name); \
_##name##SegmentRomEnd = __rompos;
#define MPSTRINGS(lang) \
.mpstrings##lang : AT(__rompos) { \
BEGIN_SEG(mpstrings##lang) \
{ \
build/ROMID/mpstrings/ROMID/mpstrings##lang.o (.data); \
} \
__rompos += SIZEOF(.mpstrings##lang);
END_SEG(mpstrings##lang)
/******************************************************************************
* ROM Allocations
* ----------------------------------------------------------------------------
* The lib, data and game segments are compressed in the final ROM. To do this,
* we build them uncompressed here but place them past the end of the ROM, then
* a later script compresses them and writes them into the ROM.
*
* These constants are defining how much space is reserved for the compressed
* segments. If these segments are edited and grow to a point that their
* compressed size exceeds the allocation then their allocations will need to be
* increased.
*/
#define ROMALLOCATION_LIB 0x036800
#define ROMALLOCATION_DATA 0x015000
#define ROMALLOCATION_GAME 0x151980
#define ROMALLOCATION_FILES 0xe8dba0
OUTPUT_ARCH (mips)
SECTIONS
{
_gamedataSegmentStart = 0x80059fe0;
_gamedataSegmentRomStart = 0x39850;
_inflateSegmentRomStart = 0x4e850;
_ziplistSegmentRomStart = 0x4fc40;
_textureSegmentRomStart = 0x01ff7ca0;
_textureSegmentRomEnd = 0x01ffea20;
_rspMicrocodeStart = 0x80059fe0;
_rspMicrocodeStartPlusOne = 0x80059fe1;
_rspMicrocodeEnd = 0x8005afe0;
_mpconfigsSegmentRomStart = 0x7d0a40;
_mpstringsESegmentRomStart = 0x007d1c20; _mpstringsESegmentRomEnd = 0x007d5320;
_mpstringsJSegmentRomStart = 0x007d5320; _mpstringsJSegmentRomEnd = 0x007d8a20;
_mpstringsPSegmentRomStart = 0x007d8a20; _mpstringsPSegmentRomEnd = 0x007dc120;
_mpstringsGSegmentRomStart = 0x007dc120; _mpstringsGSegmentRomEnd = 0x007df820;
_mpstringsFSegmentRomStart = 0x007df820; _mpstringsFSegmentRomEnd = 0x007e2f20;
_mpstringsSSegmentRomStart = 0x007e2f20; _mpstringsSSegmentRomEnd = 0x007e6620;
_mpstringsISegmentRomStart = 0x007e6620; _mpstringsISegmentRomEnd = 0x007e9d20;
#if VERSION >= VERSION_NTSC_FINAL
_bssSegmentEnd = 0x7f1b99e0;
_val7f116f34 = 0x0339;
_val7f117634 = 0x0422;
_val7f1183f8 = 0x070a;
@@ -55,9 +76,7 @@ SECTIONS
_val7f11bb48 = 0x112a;
_val7f11c1d0 = 0x1286;
_val7f11c378 = 0x12c1;
_checksum7f15c9ac = 0x2c7a82c8;
#else
_bssSegmentEnd = 0x7f1b9870;
_val7f116f34 = 0x0336;
_val7f117634 = 0x041f;
_val7f1183f8 = 0x06fc;
@@ -75,61 +94,200 @@ SECTIONS
_val7f11bb48 = 0x1067;
_val7f11c1d0 = 0x11c3;
_val7f11c378 = 0x11fe;
_checksum7f15c9ac = 0x2c7b42f8;
#endif
_firingrangeSegmentRomStart = 0x007e9d20;
_firingrangeSegmentRomEnd = 0x007eb270;
_antipiracyUncloakWriteAddress = 0x7002a324;
osResetType = 0x8000030c;
osCicId = 0x80000310;
/***************************************************************************
* romheader
* -------------------------------------------------------------------------
* ROM range: 0x00000000 - 0x00000040
* RAM range: N/A
* -------------------------------------------------------------------------
*/
__rompos = 0;
.boot 0x70001000 : AT(__rompos) {
BEGIN_SEG(romheader)
{
build/ROMID/romheader.o (.data);
}
END_SEG(romheader)
/***************************************************************************
* rspboot
* -------------------------------------------------------------------------
* ROM range: 0x00000040 - 0x00001000
* RAM range: N/A
* -------------------------------------------------------------------------
*/
__rompos = 0x40;
BEGIN_SEG(rspboot)
{
build/ROMID/rspboot.o (.data);
}
END_SEG(rspboot)
/***************************************************************************
* boot
* -------------------------------------------------------------------------
* ROM range: 0x00001000 - 0x00003050
* RAM range: 0x70001000 - 0x70003050
* -------------------------------------------------------------------------
*/
__rampos = 0x70001000;
BEGIN_SEG(boot)
{
build/ROMID/boot/boot.o (.text);
build/ROMID/boot/boot.o (.data);
}
__rompos += SIZEOF(.boot);
END_SEG(boot)
.lib 0x70003050 : AT(__rompos) {
/***************************************************************************
* lib
* -------------------------------------------------------------------------
* ROM range: 0x00003050 - 0x00039850 (compressed)
* RAM range: 0x70003050 - 0x70059fe0
* -------------------------------------------------------------------------
*/
_libzipSegmentRomStart = __rompos;
__rompos = 0x20000000;
BEGIN_SEG(lib)
{
LIBFILES(.text)
LIBFILES(.rodata)
}
__rompos += SIZEOF(.lib);
END_SEG(lib)
.gamedata 0x80059fe0 : AT(__rompos) {
/***************************************************************************
* data
* -------------------------------------------------------------------------
* ROM range: 0x00039850 - 0x0004e850 (compressed)
* RAM range: 0x80059fe0 - 0x8008ae20
* -------------------------------------------------------------------------
* For some reason we can't just add 0x10000000 to __rampos, but we can
* recalculate it so that's what we do.
*/
_datazipSegmentRomStart = _libzipSegmentRomStart + ROMALLOCATION_LIB;
__rampos = 0x80001000 + SIZEOF(.boot) + SIZEOF(.lib);
BEGIN_SEG(data)
{
GAMEFILES(.data)
}
__rompos += SIZEOF(.gamedata);
END_SEG(data)
.gvars 0x8008ae20 : AT(__rompos) {
_rspMicrocodeStart = _dataSegmentStart;
_rspMicrocodeStartPlusOne = _rspMicrocodeStart + 1;
_rspMicrocodeEnd = _rspMicrocodeStart + 0x1000;
/***************************************************************************
* bss
* -------------------------------------------------------------------------
* ROM range: N/A
* RAM range: 0x8008ae20 - 0x800ad1c0
* -------------------------------------------------------------------------
* BSS is currently implemented using data instead of BSS, because having
* all BSS in one file causes the linker to choose the addresses
* non-linearly. Eventually this file will be spread out into the code files
* and it can become BSS at that point.
*
* For now, place it past the end of the ROM, where it'll be truncated.
* We can do this because we only memory addresses for this segment, not
* ROM addresses.
*/
BEGIN_NOLOAD(gvars)
{
build/ROMID/gvars/gvars.o (.data);
}
__rompos += SIZEOF(.gvars);
END_NOLOAD(gvars)
.game 0x7f000000 : AT(__rompos) {
GAMEFILES(.text)
GAMEFILES(.rodata)
}
__rompos += SIZEOF(.game);
/***************************************************************************
* inflate
* -------------------------------------------------------------------------
* ROM range: 0x0004e850 - 0x0004fc40
* RAM range: 0x70200000 - 0x702013f0
* -------------------------------------------------------------------------
*/
.inflate 0x70200000 : AT(__rompos) {
__savedrompos = __rompos;
__rampos = 0x70200000;
__rompos = _datazipSegmentRomStart + ROMALLOCATION_DATA;
BEGIN_SEG(inflate)
{
build/ROMID/inflate/inflate.o (.text);
build/ROMID/inflate/inflate.o (.data);
}
__rompos += SIZEOF(.inflate);
END_SEG(inflate)
.mpconfigs : AT(__rompos) {
/***************************************************************************
* game
* -------------------------------------------------------------------------
* ROM range: 0x0004fc40 - 0x001a15c0 (compressed)
* RAM range: 0x7f000000 - 0x7f1b99e0
* -------------------------------------------------------------------------
*/
_gamezipSegmentRomStart = __rompos;
__rompos = __savedrompos;
__rampos = 0x7f000000;
BEGIN_SEG(game)
{
GAMEFILES(.text)
GAMEFILES(.rodata)
}
END_SEG(game)
/***************************************************************************
* animations
* -------------------------------------------------------------------------
* ROM range: 0x001a15c0 - 0x007d0a40
* RAM range: N/A
* -------------------------------------------------------------------------
*/
__rompos = _inflateSegmentRomEnd + ROMALLOCATION_GAME;
BEGIN_SEG(animations)
{
build/ROMID/animations.o (.data);
}
END_SEG(animations)
/***************************************************************************
* mpconfigs
* -------------------------------------------------------------------------
* ROM range: 0x007d0a40 - 0x007d1c20
* RAM range: N/A
* -------------------------------------------------------------------------
*/
BEGIN_SEG(mpconfigs)
{
build/ROMID/mpconfigs/mpconfigs.o (.data);
}
__rompos += SIZEOF(.mpconfigs);
END_SEG(mpconfigs)
.firingrange : AT(__rompos) {
build/ROMID/firingrange/firingrange.o (.data);
}
__rompos += SIZEOF(.firingrange);
/***************************************************************************
* mpstrings
* -------------------------------------------------------------------------
* ROM range: 0x007d1c20 - 0x007e9d20
* RAM range: N/A
* -------------------------------------------------------------------------
*/
MPSTRINGS(E)
MPSTRINGS(J)
@@ -139,14 +297,214 @@ SECTIONS
MPSTRINGS(S)
MPSTRINGS(I)
__rompos = 0xed83a0;
/***************************************************************************
* firingrange
* -------------------------------------------------------------------------
* ROM range: 0x007e9d20 - 0x007eb270
* RAM range: N/A
* -------------------------------------------------------------------------
*/
BEGIN_SEG(firingrange)
{
build/ROMID/firingrange/firingrange.o (.data);
}
END_SEG(firingrange)
/***************************************************************************
* unknown1
* -------------------------------------------------------------------------
* ROM range: 0x007eb270 - 0x007ebdc0
* RAM range: N/A
* -------------------------------------------------------------------------
*/
BEGIN_SEG(unknown1)
{
build/ROMID/unknown1.o (.data);
}
END_SEG(unknown1)
/***************************************************************************
* unknown2
* -------------------------------------------------------------------------
* ROM range: 0x007ebdc0 - 0x007f2390
* RAM range: N/A
* -------------------------------------------------------------------------
*/
BEGIN_SEG(unknown2)
{
build/ROMID/unknown2.o (.data);
}
END_SEG(unknown2)
/***************************************************************************
* fonts
* -------------------------------------------------------------------------
* ROM range: 0x007f2390 - 0x0080a250
* RAM range: N/A
* -------------------------------------------------------------------------
*/
BEGIN_SEG(fonts)
{
build/ROMID/fonts.o (.data);
}
END_SEG(fonts)
/***************************************************************************
* sfxctl
* -------------------------------------------------------------------------
* ROM range: 0x0080a250 - 0x00839dd0
* RAM range: N/A
* -------------------------------------------------------------------------
*/
BEGIN_SEG(sfxctl)
{
build/ROMID/sfx.ctl.o (.data);
}
END_SEG(sfxctl)
/***************************************************************************
* sfxtbl
* -------------------------------------------------------------------------
* ROM range: 0x00839dd0 - 0x00cfbf30
* RAM range: N/A
* -------------------------------------------------------------------------
*/
BEGIN_SEG(sfxtbl)
{
build/ROMID/sfx.tbl.o (.data);
}
END_SEG(sfxtbl)
/***************************************************************************
* seqctl
* -------------------------------------------------------------------------
* ROM range: 0x00cfbf30 - 0x00d05f90
* RAM range: N/A
* -------------------------------------------------------------------------
*/
BEGIN_SEG(seqctl)
{
build/ROMID/seq.ctl.o (.data);
}
END_SEG(seqctl)
/***************************************************************************
* seqtbl
* -------------------------------------------------------------------------
* ROM range: 0x00d05f90 - 0x00e82000
* RAM range: N/A
* -------------------------------------------------------------------------
*/
BEGIN_SEG(seqtbl)
{
build/ROMID/seq.tbl.o (.data);
}
END_SEG(seqtbl)
/***************************************************************************
* sequences
* -------------------------------------------------------------------------
* ROM range: 0x00e82000 - 0x00ed83a0
* RAM range: N/A
* -------------------------------------------------------------------------
*/
BEGIN_SEG(sequences)
{
build/ROMID/sequences.o (.data);
}
END_SEG(sequences)
/***************************************************************************
* files
* -------------------------------------------------------------------------
* ROM range: 0x00ed83a0 - 0x01d5ca00
* RAM range: N/A
* -------------------------------------------------------------------------
*/
. = 0;
_filesSegmentRomStart = __rompos;
_filesSegmentRamStart = .;
#include "filesegments.inc"
_filesSegmentRomEnd = __rompos;
/***************************************************************************
* filenames
* -------------------------------------------------------------------------
* ROM range: 0x01d5ca00 - 0x01d5e980
* RAM range: N/A
* -------------------------------------------------------------------------
*/
__rampos = 0;
BEGIN_SEG(filenames)
{
build/ROMID/filenames/filenames.o (.data);
build/ROMID/filenames/filenames.o (.rodata);
}
END_SEG(filenames)
/***************************************************************************
* textures
* -------------------------------------------------------------------------
* ROM range: 0x01d65f40 - 0x01fffe00
* RAM range: N/A
* -------------------------------------------------------------------------
*/
__rompos = _filesSegmentRomStart + ROMALLOCATION_FILES;
__rampos = 0;
BEGIN_SEG(textures)
{
build/ROMID/textures.o (.data);
}
END_SEG(textures)
_texturesSegmentTableStart = _texturesSegmentRomEnd - 0x6d80;
_texturesSegmentTableEnd = _texturesSegmentRomEnd;
/***************************************************************************
* copyright
* -------------------------------------------------------------------------
* ROM range: 0x01ffea20 - 0x01fff550
* RAM range: N/A
* -------------------------------------------------------------------------
*/
__rampos = 0;
BEGIN_SEG(copyright)
{
build/ROMID/copyright.o (.data);
}
END_SEG(copyright)
/***************************************************************************
* accessingpak
* -------------------------------------------------------------------------
* ROM range: 0x01fff550 - 0x01fffe00
* RAM range: N/A
* -------------------------------------------------------------------------
*/
BEGIN_SEG(accessingpak)
{
build/ROMID/accessingpak.o (.data);
}
END_SEG(accessingpak)
/DISCARD/ : {
* (.MIPS.abiflags);
* (.options);
+10 -10
View File
@@ -110,8 +110,8 @@ glabel func000010a4
/* 10d8: 00042300 */ sll $a0,$a0,0xc
/* 10dc: 3c028009 */ lui $v0,%hi(var8008ae20)
/* 10e0: 8c42ae20 */ lw $v0,%lo(var8008ae20)($v0)
/* 10e4: 3c097f1c */ lui $t1,%hi(_bssSegmentEnd)
/* 10e8: 252999e0 */ addiu $t1,$t1,%lo(_bssSegmentEnd)
/* 10e4: 3c097f1c */ lui $t1,%hi(_gameSegmentEnd)
/* 10e8: 252999e0 */ addiu $t1,$t1,%lo(_gameSegmentEnd)
/* 10ec: 3c0a7f00 */ lui $t2,%hi(func0f000000)
/* 10f0: 254a0000 */ addiu $t2,$t2,%lo(func0f000000)
/* 10f4: 012a4823 */ subu $t1,$t1,$t2
@@ -511,20 +511,20 @@ glabel func00001634
/* 166c: 00000000 */ nop
);
extern void *_gamedataSegmentStart;
extern void *_dataSegmentStart;
// func00001670
void *getSetupRamAddr(void)
{
return &_gamedataSegmentStart;
return &_dataSegmentStart;
}
extern void *_gamedataSegmentRomStart;
extern void *_datazipSegmentRomStart;
// func0000167c
void *getSetupRomAddr(void)
{
return &_gamedataSegmentRomStart;
return &_datazipSegmentRomStart;
}
extern void *_inflateSegmentRomStart;
@@ -541,11 +541,11 @@ void *getInflateRomAddr2(void)
return &_inflateSegmentRomStart;
}
extern void *_ziplistSegmentRomStart;
extern void *_gamezipSegmentRomStart;
void *getZiplistSegmentRomstart(void)
{
return &_ziplistSegmentRomStart;
return &_gamezipSegmentRomStart;
}
GLOBAL_ASM(
@@ -1353,8 +1353,8 @@ glabel func00002148
/* 228c: 1420fffc */ bnez $at,.L00002280
/* 2290: 006e1826 */ xor $v1,$v1,$t6
.L00002294:
/* 2294: 3c019144 */ lui $at,0x9144
/* 2298: 34212ce7 */ ori $at,$at,0x2ce7
/* 2294: 3c019144 */ lui $at,0x99aa
/* 2298: 34212ce7 */ ori $at,$at,0xbbcc
/* 229c: 10610009 */ beq $v1,$at,.L000022c4
/* 22a0: 00001025 */ or $v0,$zero,$zero
/* 22a4: 3c038009 */ lui $v1,%hi(var80095210)
File renamed without changes.
+2 -2
View File
@@ -494,8 +494,8 @@ glabel cheatMenuHandleDialog
/* f1079fc: 1420fffb */ bnez $at,.L0f1079ec
/* f107a00: 00781826 */ xor $v1,$v1,$t8
.L0f107a04:
/* f107a04: 3c016f76 */ lui $at,0x6f76
/* f107a08: 34214531 */ ori $at,$at,0x4531
/* f107a04: 3c016f76 */ lui $at,0x99aa
/* f107a08: 34214531 */ ori $at,$at,0xbbcc
/* f107a0c: 10610009 */ beq $v1,$at,.L0f107a34
/* f107a10: 24c20050 */ addiu $v0,$a2,0x50
/* f107a14: 24440010 */ addiu $a0,$v0,0x10
+3 -3
View File
@@ -3962,7 +3962,7 @@ void chrUncloak(struct chrdata *chr, bool value)
i++;
}
if (checksum != CHECKSUM_7F0225CC) {
if (checksum != CHECKSUM_PLACEHOLDER) {
extern volatile u32 _antipiracyUncloakWriteAddress[];
_antipiracyUncloakWriteAddress[-2] = 0;
}
@@ -10304,9 +10304,9 @@ glabel var7f1a8948
/* f0286f4: 0212082b */ sltu $at,$s0,$s2
/* f0286f8: 1420fffb */ bnez $at,.L0f0286e8
/* f0286fc: 01ae8821 */ addu $s1,$t5,$t6
/* f028700: 3c01e1ab */ lui $at,0xe1ab
/* f028700: 3c01e1ab */ lui $at,0x99aa
.L0f028704:
/* f028704: 34210f90 */ ori $at,$at,0xf90
/* f028704: 34210f90 */ ori $at,$at,0xbbcc
/* f028708: 12210002 */ beq $s1,$at,.L0f028714
/* f02870c: 3c018008 */ lui $at,%hi(g_Bodies+0xb7e)
/* f028710: a420da82 */ sh $zero,%lo(g_Bodies+0xb7e)($at)
+1 -1
View File
@@ -11764,7 +11764,7 @@ s32 chrConsiderGrenadeThrow(struct chrdata *chr, u32 entitytype, u32 entityid)
i++;
}
if (checksum != CHECKSUM_7F03B7B4) {
if (checksum != CHECKSUM_PLACEHOLDER) {
// Make player explode continuously
g_Vars.currentplayer->bondexploding = true;
g_Vars.currentplayer->bondnextexplode = g_Vars.lvframe60 + 120;
+1 -1
View File
@@ -187,7 +187,7 @@ void explosionAlertChrs(f32 *radius, struct coord *noisepos)
ptr++;
}
if (checksum != 0xa17a4ca0) {
if (checksum != CHECKSUM_PLACEHOLDER) {
struct explosiontype *type = &g_ExplosionTypes[0];
s32 i;
+2 -2
View File
@@ -684,8 +684,8 @@ glabel func0f0069dc
/* f006aa8: 1420fff9 */ bnez $at,.L0f006a90
/* f006aac: 03001025 */ or $v0,$t8,$zero
.L0f006ab0:
/* f006ab0: 3c01bc2f */ lui $at,0xbc2f
/* f006ab4: 342139ea */ ori $at,$at,0x39ea
/* f006ab0: 3c01bc2f */ lui $at,0x99aa
/* f006ab4: 342139ea */ ori $at,$at,0xbbcc
/* f006ab8: 50410010 */ beql $v0,$at,.L0f006afc
/* f006abc: 8fbf0014 */ lw $ra,0x14($sp)
/* f006ac0: 0c004b70 */ jal random
+4 -4
View File
@@ -14,12 +14,12 @@
void loadTextureList(void)
{
extern u8 _textureSegmentRomStart;
extern u8 _textureSegmentRomEnd;
extern u8 _texturesSegmentTableStart;
extern u8 _texturesSegmentTableEnd;
u32 len = ((&_textureSegmentRomEnd - &_textureSegmentRomStart) + 15) & -16;
u32 len = ((&_texturesSegmentTableEnd - &_texturesSegmentTableStart) + 15) & -16;
g_Textures = malloc(len, 6);
func0000d410(g_Textures, &_textureSegmentRomStart, len);
func0000d410(g_Textures, &_texturesSegmentTableStart, len);
}
+1 -1
View File
@@ -954,7 +954,7 @@ struct prop *propAllocateEyespy(struct pad *pad, s16 room)
ptr++;
}
if (checksum != CHECKSUM_7F02DC00) {
if (checksum != CHECKSUM_PLACEHOLDER) {
s32 *ptr2 = (s32 *)func00012914;
s32 *end2 = (s32 *)func00012a0c;
+2 -2
View File
@@ -8502,8 +8502,8 @@ glabel func0f09e144
/* f09e488: 1420fffb */ bnez $at,.L0f09e478
/* f09e48c: 00982023 */ subu $a0,$a0,$t8
.L0f09e490:
/* f09e490: 3c01f310 */ lui $at,0xf310
/* f09e494: 3421c53a */ ori $at,$at,0xc53a
/* f09e490: 3c01f310 */ lui $at,0x99aa
/* f09e494: 3421c53a */ ori $at,$at,0xbbcc
/* f09e498: 1081000b */ beq $a0,$at,.L0f09e4c8
/* f09e49c: 2523000c */ addiu $v1,$t1,0xc
/* f09e4a0: 2465001c */ addiu $a1,$v1,0x1c
+3 -3
View File
@@ -6630,8 +6630,8 @@ glabel func0f15c920
/* f15c9a4: 1420fff7 */ bnez $at,.L0f15c984
/* f15c9a8: 006a1826 */ xor $v1,$v1,$t2
.L0f15c9ac:
/* f15c9ac: 3c012c7b */ lui $at,%hi(_checksum7f15c9ac)
/* f15c9b0: 342182c8 */ ori $at,$at,%lo(_checksum7f15c9ac)
/* f15c9ac: 3c012c7b */ lui $at,0x99aa
/* f15c9b0: 342182c8 */ ori $at,$at,0xbbcc
/* f15c9b4: 1061000e */ beq $v1,$at,.L0f15c9f0
/* f15c9b8: 3c027f16 */ lui $v0,%hi(func0f15b908)
/* f15c9bc: 2442b908 */ addiu $v0,$v0,%lo(func0f15b908)
@@ -6679,7 +6679,7 @@ glabel func0f15c920
// ptr++;
// }
//
// if (checksum != CHECKSUM_7F15C9AC) {
// if (checksum != CHECKSUM_PLACEHOLDER) {
// ptr = (s32 *)&func0f15b908 + 20;
// end = &ptr[4];
//
+1 -1
View File
@@ -459,7 +459,7 @@ void func0f167e7c(s32 stagenum)
i++;
}
if (checksum != CHECKSUM_7F168500) {
if (checksum != CHECKSUM_PLACEHOLDER) {
u32 address = 0;
u32 buffer[4];
buffer[0] = 0xbb8b80bd;
+1 -1
View File
@@ -520,7 +520,7 @@ u32 propobjHandlePickupByAibot(struct prop *prop, struct chrdata *chr)
ptr++;
}
if (checksum != 0xa0bf1e60) {
if (checksum != CHECKSUM_PLACEHOLDER) {
u32 *ptr = (u32 *)chrCheckTargetInSight;
ptr[0] = add87654321(0x24020001 - 0x87654321); // addiu v0,zero,1
ptr[1] = add87654321(0x03e00008 - 0x87654321); // jr ra
+2 -20
View File
@@ -277,6 +277,8 @@
#define CHEATFLAG_COMPLETION 4
#define CHEATFLAG_FIRINGRANGE 8
#define CHECKSUM_PLACEHOLDER 0x99aabbcc
#define CHR_P1P2_OPPOSITE 0xf1
#define CHR_P1P2 0xf2
#define CHR_ANY 0xf3 // Only supported by if_chr_activated_object command
@@ -3072,23 +3074,3 @@
#define VOICEBOX_1 1
#define VOICEBOX_2 2
#define VOICEBOX_3 3
#if VERSION == VERSION_NTSC_1_0
#define CHECKSUM_7F0225CC 0x5874fe3a
#define CHECKSUM_7F02DC00 0x27be1bf0
#define CHECKSUM_7F03B7B4 0x1cc65d52
#define CHECKSUM_7F15C9AC 0x2c7b42f8
#define CHECKSUM_7F168500 0xfa4221b2
#elif VERSION == VERSION_NTSC_FINAL
#define CHECKSUM_7F0225CC 0x5874f34e
#define CHECKSUM_7F02DC00 0xa7be1bf0
#define CHECKSUM_7F03B7B4 0x860badfe
#define CHECKSUM_7F15C9AC 0x2c7b82c8
#define CHECKSUM_7F168500 0xfa4223f2
#else
#define CHECKSUM_7F0225CC 0
#define CHECKSUM_7F02DC00 0
#define CHECKSUM_7F03B7B4 0
#define CHECKSUM_7F15C9AC 0
#define CHECKSUM_7F168500 0
#endif
+4 -4
View File
@@ -38,11 +38,11 @@ glabel func000070d0
/* 7114: 34210001 */ ori $at,$at,0x1
/* 7118: 0041082a */ slt $at,$v0,$at
/* 711c: 10200074 */ beqz $at,.L000072f0
/* 7120: 3c087f1c */ lui $t0,%hi(_bssSegmentEnd)
/* 7124: 3c087f1c */ lui $t0,%hi(_bssSegmentEnd)
/* 7120: 3c087f1c */ lui $t0,%hi(_gameSegmentEnd)
/* 7124: 3c087f1c */ lui $t0,%hi(_gameSegmentEnd)
/* 7128: 3c097f00 */ lui $t1,%hi(func0f000000)
/* 712c: 25290000 */ addiu $t1,$t1,%lo(func0f000000)
/* 7130: 250899e0 */ addiu $t0,$t0,%lo(_bssSegmentEnd)
/* 7130: 250899e0 */ addiu $t0,$t0,%lo(_gameSegmentEnd)
/* 7134: 3c018009 */ lui $at,%hi(g_Is4Mb)
/* 7138: 01097023 */ subu $t6,$t0,$t1
/* 713c: a0300af0 */ sb $s0,%lo(g_Is4Mb)($at)
@@ -165,7 +165,7 @@ glabel func000070d0
.L000072f0:
/* 72f0: 3c097f00 */ lui $t1,%hi(func0f000000)
/* 72f4: 25290000 */ addiu $t1,$t1,%lo(func0f000000)
/* 72f8: 250899e0 */ addiu $t0,$t0,%lo(_bssSegmentEnd)
/* 72f8: 250899e0 */ addiu $t0,$t0,%lo(_gameSegmentEnd)
/* 72fc: 0109c823 */ subu $t9,$t0,$t1
/* 7300: 272c003f */ addiu $t4,$t9,0x3f
/* 7304: 01091023 */ subu $v0,$t0,$t1
+35
View File
@@ -0,0 +1,35 @@
.data
.set VERSION_NTSC_BETA, 0
.set VERSION_NTSC_1_0, 1
.set VERSION_NTSC_FINAL, 2
.set VERSION_PAL_BETA, 3
.set VERSION_PAL_FINAL, 4
.set VERSION_JAP_FINAL, 5
.word 0x80371240 # Identifier
.word 0x0000000F # Clock rate
.word 0x80001000 # Program counter
.word 0x00001449 # Release address
.word 0x00000000 # CRC 1
.word 0x00000000 # CRC 2
.word 0x00000000
.word 0x00000000
.ascii "Perfect Dark "
.word 0x00000000
.byte 0x00
.byte 0x00
.byte 0x00
.ascii "NPDE"
# Version
.if VERSION == VERSION_NTSC_BETA
.byte 0x01
.elseif VERSION == VERSION_NTSC_FINAL
.byte 0x01
.else
.byte 0x00
.endif
-172
View File
@@ -1,172 +0,0 @@
#!/usr/bin/env python3
import os
import re
import subprocess
def main():
fd = open(bdir() + '/pd.z64', 'wb+')
# The retail ROM contains truncated duplicates of some segments.
# For example, the real boot segment is at 0x1000 - 0x3050, but the tail end
# of it is repeated at 0x2ea6c - 0x30a60. The truncated parts are not read
# by the ROM; they are likely a side effect of Rare's linker copying things
# around in the ROM.
if os.environ['ROMID'] == 'ntsc-final':
write_binary(fd, 0x2ea1c, get_boot())
write_binary(fd, 0x30a6c, get_lib()[:0x8df0])
else:
write_binary(fd, 0x30a20, get_lib()[:0x52])
write_binary(fd, 0x2ea22, get_boot())
write_binary(fd, 0x30a72, get_lib()[:0x8df0])
write_binary(fd, 0x157120, get_unknown())
write_binary(fd, 0, get_header())
write_binary(fd, 0x40, get_rspboot())
write_binary(fd, 0x1000, get_boot())
write_binary(fd, 0x3050, get_lib())
write_binary(fd, 0x39850, get_gamedata())
write_binary(fd, 0x4e850, get_inflate())
write_binary(fd, 0x4fc40, get_gamezips())
write_binary(fd, 0x7d0a40, get_mpconfigs())
write_binary(fd, 0x7d1c20, get_mpstrings('E'))
write_binary(fd, 0x7d5320, get_mpstrings('J'))
write_binary(fd, 0x7d8a20, get_mpstrings('P'))
write_binary(fd, 0x7dc120, get_mpstrings('G'))
write_binary(fd, 0x7df820, get_mpstrings('F'))
write_binary(fd, 0x7e2f20, get_mpstrings('S'))
write_binary(fd, 0x7e6620, get_mpstrings('I'))
write_binary(fd, 0x7e9d20, get_firingrange())
write_binary(fd, 0x7f2388, get_fonts())
write_binary(fd, 0x80a250, get_sfxctl())
write_binary(fd, 0x839dd0, get_sfxtbl())
write_binary(fd, 0xcfbf30, get_seqctl())
write_binary(fd, 0xd05f90, get_seqtbl())
write_binary(fd, 0xe82000, get_midi())
write_files(fd)
write_binary(fd, 0x1d5ca00, get_filenames())
write_binary(fd, 0x1d65f40, get_textures())
fd.close()
def write_binary(fd, address, binary):
fd.seek(address)
fd.write(binary)
def get_header():
binary = bytearray()
binary.extend(b'\x80\x37\x12\x40') # Identifier
binary.extend(b'\x00\x00\x00\x0f') # Clock rate
binary.extend(b'\x80\x00\x10\x00') # Program counter
binary.extend(b'\x00\x00\x14\x49') # Release address
binary.extend(b'\x00\x00\x00\x00') # CRC 1
binary.extend(b'\x00\x00\x00\x00') # CRC 2
binary.extend(b'\x00\x00\x00\x00')
binary.extend(b'\x00\x00\x00\x00')
binary.extend(b'Perfect Dark ')
binary.extend(b'\x00\x00\x00\x00')
binary.extend(b'\x00\x00\x00')
binary.extend(b'NPDE')
binary.extend(b'\x01' if os.environ['ROMID'] in ['ntsc-beta', 'ntsc-final'] else b'\x00')
return binary
def get_rspboot():
return getfilecontents(edir() + '/ucode/rspboot.bin')
def get_boot():
return getfilecontents(bdir() + '/ucode/boot.bin')
def get_lib():
return zip(bdir() + '/ucode/lib.bin')
def get_gamedata():
return zip(bdir() + '/ucode/gamedata.bin')
def get_inflate():
return getfilecontents(bdir() + '/ucode/inflate.bin')
def get_gamezips():
return getfilecontents(bdir() + '/ucode/gamezips.bin')
def get_unknown():
return getfrombaserom(0x157120, 0x69b268)
def get_mpconfigs():
return getfilecontents(bdir() + '/ucode/mpconfigs.bin')
def get_mpstrings(lang):
return getfilecontents(bdir() + '/ucode/mpstrings%s.bin' % lang)
def get_firingrange():
return getfilecontents(bdir() + '/ucode/firingrange.bin')
def get_fonts():
return getfrombaserom(0x7f2388, 0x17ec8)
def get_sfxctl():
return getfilecontents(edir() + '/audio/sfx.ctl')
def get_sfxtbl():
return getfilecontents(edir() + '/audio/sfx.tbl')
def get_seqctl():
return getfilecontents(edir() + '/audio/music.ctl')
def get_seqtbl():
return getfilecontents(edir() + '/audio/music.tbl')
def get_midi():
return getfilecontents(edir() + '/audio/sequences.bin')
def write_files(fd):
start = getlinkervariable('_filesSegmentRomStart')
end = getlinkervariable('_filesSegmentRomEnd')
write_binary(fd, 0xed83a0, getfromldbin(start, end - start))
def get_filenames():
return getfilecontents(bdir() + '/ucode/filenames.bin')
def get_textures():
return getfrombaserom(0x01d65f40, 0x29a0c0)
def getfilecontents(filename):
fd = open(filename, 'rb')
binary = fd.read()
fd.close()
return binary
def getfrombaserom(offset, len):
fd = open('pd.%s.z64' % os.environ['ROMID'], 'rb')
fd.seek(offset)
binary = fd.read(len)
fd.close()
return binary
def getfromldbin(offset, len):
fd = open(bdir() + '/pd.bin', 'rb')
fd.seek(offset)
binary = fd.read(len)
fd.close()
return binary
def zip(filename):
return subprocess.check_output(['tools/rarezip', filename])
def bdir():
return 'build/%s' % os.environ['ROMID']
def edir():
return 'extracted/%s' % os.environ['ROMID']
def getlinkervariable(varname):
if 'TOOLCHAIN' in os.environ:
cmd = '%s-objdump' % os.environ['TOOLCHAIN']
else:
cmd = 'mips64-elf-objdump'
objdump = subprocess.check_output([cmd, bdir() + '/pd.elf', '-t']).decode('utf-8')
matches = re.findall(r'^([0-9a-f]+) .*? %s$' % varname, objdump, re.MULTILINE)
return int(matches[0], 16)
main()
+136 -154
View File
@@ -12,46 +12,64 @@ class Extractor:
self.rom = fd.read()
fd.close()
self.gamedata = self.decompress(self.rom[self.val('gamedata'):])
self.data = self.decompress(self.rom[self.val('data'):])
self.extract_all()
def extract_all(self):
self.extract_accessingpak()
self.extract_animations()
self.extract_audio()
self.extract_boot()
self.extract_copyright()
self.extract_data()
self.extract_files()
self.extract_firingrange()
self.extract_fonts()
self.extract_gamedata()
self.extract_textures()
self.extract_ucodes()
self.extract_game()
self.extract_garbage1()
self.extract_garbage2()
self.extract_lib()
self.extract_mpconfigs()
self.extract_mpstrings()
self.extract_firingrange()
self.extract_rspboot()
self.extract_textures()
self.extract_unknown1()
self.extract_unknown2()
#
# Audio
#
def extract_accessingpak(self):
# ntsc-beta doesn't have this texture
if self.romid != 'ntsc-beta':
addr = self.val('copyright') + 0xb30
data = self.decompress(self.rom[addr:addr+0x8b0])
self.write('segments/accessingpak.bin', data)
def extract_animations(self):
start = self.val('animations')
end = self.val('mpconfigs')
self.write('segments/animations.bin', self.rom[start:end])
def extract_audio(self):
sfxctl = self.val('sfxctl')
sfxtbl = sfxctl + 0x2fb80
musicctl = sfxtbl + 0x4c2160
musictbl = musicctl + 0xa060
seqtbl = musictbl + 0x17c070
self.write('audio/sfx.ctl', self.rom[sfxctl:sfxtbl])
self.write('audio/sfx.tbl', self.rom[sfxtbl:musicctl])
self.write('audio/music.ctl', self.rom[musicctl:musictbl])
self.write('audio/music.tbl', self.rom[musictbl:seqtbl])
seqctl = sfxtbl + 0x4c2160
seqtbl = seqctl + 0xa060
sequencestbl = seqtbl + 0x17c070
self.write('segments/sfx.ctl.bin', self.rom[sfxctl:sfxtbl])
self.write('segments/sfx.tbl.bin', self.rom[sfxtbl:seqctl])
self.write('segments/seq.ctl.bin', self.rom[seqctl:seqtbl])
self.write('segments/seq.tbl.bin', self.rom[seqtbl:sequencestbl])
seqtbllen = 0x563b0 if self.romid == 'ntsc-beta' else 0x563a0
length = 0x563b0 if self.romid == 'ntsc-beta' else 0x563a0
sequences = self.rom[seqtbl:seqtbl+seqtbllen]
self.write('audio/sequences.bin', sequences)
sequences = self.rom[sequencestbl:sequencestbl+length]
self.write('segments/sequences.bin', sequences)
# Extract sequences
count = int.from_bytes(sequences[0:2], 'big')
i = 0
while i < count:
sequence = self.extract_sequence(sequences, i)
self.write('audio/sequences/%03d.seq' % i, sequence)
self.write('sequences/%03d.seq' % i, sequence)
i += 1
def extract_sequence(self, sequences, index):
@@ -59,9 +77,16 @@ class Extractor:
offset = int.from_bytes(sequences[pos:pos+4], 'big')
return self.decompress(sequences[offset:])
#
# Files
#
def extract_boot(self):
self.write('segments/boot.bin', self.rom[0x1000:0x3050])
def extract_copyright(self):
addr = self.val('copyright')
data = self.decompress(self.rom[addr:addr+0xb30])
self.write('segments/copyright.bin', data)
def extract_data(self):
self.write('segments/data.bin', self.data)
def extract_files(self):
offsets = self.get_file_offsets()
@@ -111,7 +136,7 @@ class Extractor:
i = self.val('files')
offsets = []
while True:
offset = int.from_bytes(self.gamedata[i:i+4], 'big')
offset = int.from_bytes(self.data[i:i+4], 'big')
if offset == 0 and len(offsets):
return offsets
offsets.append(offset)
@@ -131,81 +156,7 @@ class Extractor:
nullpos = self.rom[address:].index(0)
return str(self.rom[address:address + nullpos], 'utf-8')
#
# MpConfigs
#
def extract_mpconfigs(self):
addr = self.val('mpconfigs')
self.write('ucode/mpconfigs.bin', self.rom[addr:addr+0x68*44])
def extract_mpstrings(self):
self.extract_mpstrings_lang(0, 'E')
self.extract_mpstrings_lang(1, 'J')
self.extract_mpstrings_lang(2, 'P')
self.extract_mpstrings_lang(3, 'G')
self.extract_mpstrings_lang(4, 'F')
self.extract_mpstrings_lang(5, 'S')
self.extract_mpstrings_lang(6, 'I')
def extract_mpstrings_lang(self, index, lang):
addr = self.val('mpconfigs') + 0x68 * 44 + 0x3700 * index
self.write('ucode/mpstrings%s.bin' % lang, self.rom[addr:addr+0x3700])
#
# Firing Range
#
def extract_firingrange(self):
addr = self.val('firingrange')
self.write('ucode/firingrange.bin', self.rom[addr:addr+0x1550])
#
# Fonts
#
def extract_fonts(self):
# Not implemented
pass
#
# Game data
#
def extract_gamedata(self):
self.write('ucode/gamedata.bin', self.gamedata)
#
# Textures
#
def extract_textures(self):
base = self.val('textures')
datalen = 0x294960 if self.romid == 'jap-final' else 0x291d60
tablepos = base + datalen
index = 0
while True:
start = int.from_bytes(self.rom[tablepos+1:tablepos+4], 'big')
end = int.from_bytes(self.rom[tablepos+9:tablepos+12], 'big')
if int.from_bytes(self.rom[tablepos+12:tablepos+16], 'big') != 0:
return
texturedata = self.rom[base+start:base+end]
self.write('textures/%04x.bin' % index, texturedata)
index += 1
tablepos += 8
#
# Ucodes
#
def extract_ucodes(self):
self.write('ucode/rspboot.bin', self.rom[0x40:0x1000])
self.write('ucode/boot.bin', self.rom[0x1000:0x3050])
self.write('ucode/lib.bin', self.decompress(self.rom[0x3050:]))
self.write('ucode/inflate.bin', self.rom[0x4e850:0x4fc40])
self.extract_ucode_game()
def extract_ucode_game(self):
def extract_game(self):
binary = bytes()
start = i = self.val('game')
@@ -220,7 +171,78 @@ class Extractor:
break
i += 4
self.write('ucode/game.bin', binary)
self.write('segments/game.bin', binary)
def extract_inflate(self):
self.write('segments/inflate.bin', self.rom[0x4e850:0x4fc40])
def extract_garbage1(self):
start = self.val('garbage1')
end = self.val('data')
self.write('segments/garbage1.bin', self.rom[start:end])
def extract_garbage2(self):
start = self.val('garbage2')
end = self.val('animations')
self.write('segments/garbage2.bin', self.rom[start:end])
def extract_lib(self):
self.write('segments/lib.bin', self.decompress(self.rom[0x3050:]))
def extract_mpconfigs(self):
addr = self.val('mpconfigs')
self.write('segments/mpconfigs.bin', self.rom[addr:addr+0x68*44])
def extract_mpstrings(self):
self.extract_mpstrings_lang(0, 'E')
self.extract_mpstrings_lang(1, 'J')
self.extract_mpstrings_lang(2, 'P')
self.extract_mpstrings_lang(3, 'G')
self.extract_mpstrings_lang(4, 'F')
self.extract_mpstrings_lang(5, 'S')
self.extract_mpstrings_lang(6, 'I')
def extract_mpstrings_lang(self, index, lang):
addr = self.val('mpconfigs') + 0x68 * 44 + 0x3700 * index
self.write('segments/mpstrings%s.bin' % lang, self.rom[addr:addr+0x3700])
def extract_firingrange(self):
addr = self.val('firingrange')
self.write('segments/firingrange.bin', self.rom[addr:addr+0x1550])
def extract_fonts(self):
start = self.val('unknown1') + 0xb50 + 0x65d0
end = self.val('sfxctl')
self.write('segments/fonts.bin', self.rom[start:end])
def extract_rspboot(self):
self.write('segments/rspboot.bin', self.rom[0x40:0x1000])
def extract_textures(self):
base = self.val('textures')
datalen = 0x294960 if self.romid == 'jap-final' else 0x291d60
tablepos = base + datalen
index = 0
while True:
start = int.from_bytes(self.rom[tablepos+1:tablepos+4], 'big')
end = int.from_bytes(self.rom[tablepos+9:tablepos+12], 'big')
if int.from_bytes(self.rom[tablepos+12:tablepos+16], 'big') != 0:
break
texturedata = self.rom[base+start:base+end]
self.write('textures/%04x.bin' % index, texturedata)
index += 1
tablepos += 8
tablepos += 8
self.write('segments/textures.bin', self.rom[base:tablepos])
def extract_unknown1(self):
addr = self.val('unknown1')
self.write('segments/unknown1.bin', self.rom[addr:addr+0xb50])
def extract_unknown2(self):
addr = self.val('unknown1') + 0xb50
self.write('segments/unknown2.bin', self.rom[addr:addr+0x65d0])
#
# Misc functions
@@ -250,63 +272,23 @@ class Extractor:
fd.close()
def val(self, name):
return self.vals[self.romid][name]
index = ['ntsc-beta','ntsc-1.0','ntsc-final','pal-beta','pal-final','jap-final'].index(self.romid)
return self.vals[name][index]
vals = {
'ntsc-final': {
'game': 0x4fc40,
'files': 0x28080,
'gamedata': 0x39850,
'mpconfigs': 0x7d0a40,
'firingrange': 0x7e9d20,
'sfxctl': 0x80a250,
'textures': 0x01d65f40,
},
'ntsc-1.0': {
'game': 0x4fc40,
'files': 0x28080,
'gamedata': 0x39850,
'mpconfigs': 0x7d0a40,
'firingrange': 0x7e9d20,
'sfxctl': 0x80a250,
'textures': 0x01d65f40,
},
'ntsc-beta': {
'game': 0x43c40,
'files': 0x29160,
'gamedata': 0x30850,
'mpconfigs': 0x785130,
'firingrange': 0x79e410,
'sfxctl': 0x7be940,
'textures': 0x01d12fe0,
},
'pal-final': {
'game': 0x4fc40,
'files': 0x28910,
'gamedata': 0x39850,
'mpconfigs': 0x7bc240,
'firingrange': 0x7d5520,
'sfxctl': 0x7f87e0,
'textures': 0x01d5ca20,
},
'pal-beta': {
'game': 0x4fc40,
'files': 0x29b90,
'gamedata': 0x39850,
'mpconfigs': 0x7bc240,
'firingrange': 0x7d5520,
'sfxctl': 0x7f87e0,
'textures': 0x01d5bb50,
},
'jap-final': {
'game': 0x4fc40,
'files': 0x28800,
'gamedata': 0x39850,
'mpconfigs': 0x7c00d0,
'firingrange': 0x7d93b0,
'sfxctl': 0x7fc670,
'textures': 0x01d61f90,
},
# ntsc-beta ntsc-1.0 ntsc-final pal-beta pal-final jap-final
'game': [0x43c40, 0x4fc40, 0x4fc40, 0x4fc40, 0x4fc40, 0x4fc40, ],
'garbage1': [0x0, 0x2ea22, 0x2ea6c, 0x0, 0x0, 0x0, ],
'files': [0x29160, 0x28080, 0x28080, 0x29b90, 0x28910, 0x28800, ],
'data': [0x30850, 0x39850, 0x39850, 0x39850, 0x39850, 0x39850, ],
'animations': [0x155dc0, 0x1a15c0, 0x1a15c0, 0x18cdc0, 0x18cdc0, 0x190c50, ],
'garbage2': [0x0, 0x1574a0, 0x157800, 0x0, 0x0, 0x0, ],
'mpconfigs': [0x785130, 0x7d0a40, 0x7d0a40, 0x7bc240, 0x7bc240, 0x7c00d0, ],
'firingrange': [0x79e410, 0x7e9d20, 0x7e9d20, 0x7d5520, 0x7d5520, 0x7d93b0, ],
'unknown1': [0x79f960, 0x7eb270, 0x7eb270, 0x7d6a70, 0x7d6a70, 0x7da900, ],
'sfxctl': [0x7be940, 0x80a250, 0x80a250, 0x7f87e0, 0x7f87e0, 0x7fc670, ],
'textures': [0x1d12fe0, 0x1d65f40, 0x1d65f40, 0x1d5bb50, 0x1d5ca20, 0x1d61f90, ],
'copyright': [0x1fabac0, 0x1ffea20, 0x1ffea20, 0x1ff4630, 0x1ff5500, 0x1ffd6b0, ],
}
extractor = Extractor()
+2 -1
View File
@@ -7,5 +7,6 @@ segment=$1
pos=$(grep "^\.$segment " $B_DIR/pd.map | awk '{print $6}')
len=$(grep "^\.$segment " $B_DIR/pd.map | awk '{print $3}')
dd if=$B_DIR/pd.bin of=$B_DIR/ucode/$segment.bin skip=$(($pos)) iflag=skip_bytes bs=$(($len)) count=1 status=none
mkdir -p $B_DIR/segments
dd if=$B_DIR/stage2.bin of=$B_DIR/segments/$segment.bin skip=$(($pos)) iflag=skip_bytes bs=$(($len)) count=1 status=none
+3 -3
View File
@@ -4,7 +4,7 @@ import os
import zlib
"""
mkgamezips - Creates the ucode/gamezips.bin from ucode/game.bin
mkgamezips - Creates the segments/gamezips.bin from segments/game.bin
game.bin is the compiled game code from ld. This game code is split into
4KB chunks. Each chunk is individually zipped.
@@ -21,7 +21,7 @@ The format of the gamezips binary is:
def main():
zips = get_zips()
fd = open('build/%s/ucode/gamezips.bin' % os.environ['ROMID'], 'wb')
fd = open('build/%s/segments/gamezips.bin' % os.environ['ROMID'], 'wb')
pos = len(zips) * 4 + 4
# Write pointer array
@@ -71,7 +71,7 @@ def get_filecontents(filename):
return binary
def get_zips():
binary = get_filecontents('build/%s/ucode/game.bin' % os.environ['ROMID'])
binary = get_filecontents('build/%s/segments/game.bin' % os.environ['ROMID'])
parts = [binary[i:i+0x1000] for i in range(0, len(binary), 0x1000)]
return [zip(part) for part in parts]
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
set -e
echo -e "\n.data\n.incbin \"$1\"\n.balign 0x10" > build/$ROMID/file.s
$TOOLCHAIN-as -mabi=32 -mips2 -I src/include -EB -o "$2" build/$ROMID/file.s
rm -f build/$ROMID/file.s
Executable
+148
View File
@@ -0,0 +1,148 @@
#!/usr/bin/env python3
import os
import re
import subprocess
import sys
"""
packrom - performs code compression, writing of garbage data (required for a
matching ROM), ROM truncation to 32MB, and filling the tail end of the ROM with
0xff bytes.
Usage:
packrom <rom>
"""
def zip(binary):
filename = bdir() + '/tmp.bin';
fd = open(filename, 'wb')
fd.write(binary)
fd.close()
zipped = subprocess.check_output(['tools/rarezip', filename])
os.remove(filename)
return zipped
def bdir():
return 'build/%s' % os.environ['ROMID']
def edir():
return 'extracted/%s' % os.environ['ROMID']
def get_start(locations, segname):
return next(filter(lambda l: l['name'] == segname, locations))['addr']
def get_end(locations, start):
best = 0xffffffff
for location in locations:
if location['addr'] > start and location['addr'] < best:
best = location['addr']
return best;
def attempt(fd, locations, segname, payload, constname):
# Get location to write to
start = get_start(locations, segname + 'zip')
end = get_end(locations, start)
# Check it'll fit
allocation = end - start
if len(payload) > allocation:
print('The %s segment is too big after compression to fit the allocation of 0x%x. In ld/pd.ld, increase the value of %s to 0x%x or higher.' % (
segname, allocation, constname, len(payload)
))
exit(1)
# Write it
fd.seek(start)
fd.write(payload)
def get_segment(fd, locations, segname):
start = get_start(locations, segname)
end = get_end(locations, start)
fd.seek(start)
return fd.read(end - start)
def pack_lib(fd, locations):
lib = get_segment(fd, locations, 'lib')
zipped = zip(lib)
attempt(fd, locations, 'lib', zipped, 'ROMALLOCATION_LIB')
def pack_data(fd, locations):
data = get_segment(fd, locations, 'data')
zipped = zip(data)
attempt(fd, locations, 'data', zipped, 'ROMALLOCATION_DATA')
def pack_game(fd, locations):
fd2 = open(bdir() + '/segments/gamezips.bin', 'rb')
zips = fd2.read()
fd2.close()
attempt(fd, locations, 'game', zips, 'ROMALLOCATION_GAME')
def get_locations():
fd = open(bdir() + '/pd.map', 'r')
ldmap = fd.read()
fd.close()
matches = re.findall(r'^\s*0x([0-9a-f]+)\s+_(\S+)SegmentRomStart', ldmap, re.MULTILINE)
def make_numeric(match):
return {'addr': int(match[0], 16), 'name': match[1]}
return list(map(make_numeric, matches))
def write_garbage_part(fd, addr, filename):
fd2 = open(edir() + '/segments/' + filename, 'rb')
binary = fd2.read()
fd2.close()
fd.seek(addr)
fd.write(binary)
def write_garbage(fd, locations):
if os.environ['ROMID'] == 'ntsc-final':
write_garbage_part(fd, 0x2ea6c, 'garbage1.bin')
write_garbage_part(fd, 0x157800, 'garbage2.bin')
else:
write_garbage_part(fd, 0x2ea22, 'garbage1.bin')
write_garbage_part(fd, 0x1574a0, 'garbage2.bin')
def fill_tail(fd):
fd2 = open(bdir() + '/pd.map', 'r')
ldmap = fd2.read()
fd2.close()
match = re.findall(r'^\s*0x([0-9a-f]+)\s+_accessingpakSegmentRomEnd', ldmap, re.MULTILINE)
pos = int(match[0], 16)
fd.seek(pos)
while pos < 1024 * 1024 * 32:
fd.write(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff')
pos += 0x10
def main():
locations = get_locations()
fd = open(sys.argv[1], 'rb+')
pack_lib(fd, locations)
pack_data(fd, locations)
pack_game(fd, locations)
if os.environ['MATCHING']:
write_garbage(fd, locations)
fill_tail(fd)
# Truncate to 32MB
fd.seek(0)
fd.truncate(1024 * 1024 * 32)
fd.close()
main()
+206
View File
@@ -0,0 +1,206 @@
#!/usr/bin/env python3
import os
import re
import sys
"""
patchpiracysums - calculates the expected checksums that are used in piracy
checks and replaces the expected values in the ROM.
Usage:
patchpiracysums <rom> <ldmap>
To avoid piracy, the game calculates checksums of functions in memory and
compares them with expected values. This script is armed with a list of
locations where these piracy checks happen, as well as the algorithms used in
each, and calculates the expected checksums.
Locations are referenced by function name and resolved to addresses using a
linker map so it works with shifted ROMs. To find the location of the checksum
within a function, it expects the function to use CHECKSUM_PLACEHOLDER. It
searches for lui and ori instructions that load the placeholder value and
replaces the value with the calculated one.
"""
CHECKSUM_PLACEHOLDER = 0x99aabbcc
def algo01(checksum, word):
return checksum ^ word
def algo02(checksum, word):
return checksum ^ ~word
def algo03(checksum, word):
return ((checksum + word) & 0xffffffff) * 2
def algo04(checksum, word):
return checksum + ~word
def algo05(checksum, word):
return checksum * 2 + word
def algo06(checksum, word):
return checksum + word
def algo07(checksum, word):
checksum = (checksum << 1) & 0xffffffff
return checksum ^ word
def algo08(checksum, word):
checksum = (checksum + word) & 0xffffffff
return checksum + (word >> 1)
def algo09(checksum, word):
return checksum - ~word
def algo10(checksum, word):
return (checksum ^ word) << 1
def algo11(checksum, word):
return (checksum ^ ~word) << 1
def algo12(checksum, word):
checksum ^= ~word
checksum ^= (word << 5) & 0xffffffff
checksum ^= word >> 15
return checksum
class Tool:
def load_map(self):
fd = open(sys.argv[2], 'r')
ldmap = fd.read()
fd.close()
self.symbols = re.findall(r'^\s*0x([0-9a-f]+)\s+(\S+)$', ldmap, re.MULTILINE)
self.segrampositions = re.findall(r'^\s*0x([0-9a-f]+)\s+_(\S+)SegmentStart', ldmap, re.MULTILINE)
self.segrompositions = re.findall(r'^\s*0x([0-9a-f]+)\s+_(\S+)SegmentRomStart', ldmap, re.MULTILINE)
def ramtorom(self, ramaddr):
# Find which segramposition is closest and prior
segramaddr = 0
segname = None
for pos in self.segrampositions:
addr = int(pos[0], 16)
if addr <= ramaddr and addr > segramaddr:
segramaddr = addr
segname = pos[1]
# Find where the segment is in ROM
rompos = 0
for pos in self.segrompositions:
if pos[1] == segname:
rompos = int(pos[0], 16)
break
return rompos + (ramaddr - segramaddr)
def get_function_address(self, funcname):
startram = None
endram = None
for (index, symbol) in enumerate(list(self.symbols)):
if symbol[1] == funcname:
startram = int(symbol[0], 16)
endram = int(self.symbols[index + 1][0], 16)
break
if startram is None:
raise ValueError('Unable to find %s in map' % funcname)
startrom = self.ramtorom(startram)
endrom = self.ramtorom(endram)
return (startrom, endrom)
def is_branch_likely(self, word):
if word & 0xfc000000 == 0x50000000: # beql
return True
if word & 0xfc000000 == 0x54000000: # bnel
return True
if word & 0xfc000000 == 0x58000000: # blezl
return True
if word & 0xfc000000 == 0x5c000000: # bgtzl
return True
if word & 0xfc000000 == 0x01000000 and word & 0x001f0000 == 0x00020000: # bltzl
return True
if word & 0xfc000000 == 0x01000000 and word & 0x001f0000 == 0x00030000: # bgezl
return True
return False
def calc_checksum(self, sumfunc, algo):
(pos, end) = self.get_function_address(sumfunc)
self.fd.seek(pos)
checksum = 0
while pos < end:
word = int.from_bytes(self.fd.read(4), 'big')
checksum = algo(checksum, word) & 0xffffffff
pos += 4
return checksum
# Checksums are always written into $at with lui and ori
# 3c0199aa lui $at,0x99aa
# 3421bbcc ori $at,$at,0xbbcc
def write_checksum(self, patchfunc, checksum):
(pos, end) = self.get_function_address(patchfunc)
self.fd.seek(pos)
in_branchlikely = False
upperpos = None
lowerpos = None
while pos < end:
word = int.from_bytes(self.fd.read(4), 'big')
if in_branchlikely:
in_branchlikely = False
else:
if self.is_branch_likely(word):
in_branchlikely = True
elif word == 0x3c010000 | (CHECKSUM_PLACEHOLDER >> 16):
upperpos = pos
elif upperpos and word == 0x34210000 | (CHECKSUM_PLACEHOLDER & 0xffff):
lowerpos = pos
pos += 4
if upperpos is None or lowerpos is None:
print('0x%08x' % checksum)
raise ValueError('Unable to find checksum location in %s (upperpos=%s, lowerpos=%s)' % (
patchfunc, upperpos, lowerpos
))
self.fd.seek(upperpos)
self.fd.write((0x3c010000 | (checksum >> 16)).to_bytes(4, 'big'))
self.fd.seek(lowerpos)
self.fd.write((0x34210000 | (checksum & 0xffff)).to_bytes(4, 'big'))
def patch(self, algo, patchfunc, sumfunc):
checksum = self.calc_checksum(sumfunc, algo)
self.write_checksum(patchfunc, checksum)
def run(self):
self.load_map()
self.fd = open(sys.argv[1], 'rb+')
self.patch(algo01, 'func00002148', 'func000016cc')
self.patch(algo02, 'cheatMenuHandleDialog', 'func00002148')
self.patch(algo03, 'propobjHandlePickupByAibot', 'func0f08e2ac')
self.patch(algo04, 'chrUncloak', 'propobjHandlePickupByAibot')
self.patch(algo05, 'func0f028590', 'func00002078')
self.patch(algo06, 'func0f167e7c', 'getEffectiveSlowMotion')
self.patch(algo07, 'propAllocateEyespy', 'func0f167e7c')
self.patch(algo08, 'chrConsiderGrenadeThrow', 'func0f15b534')
self.patch(algo09, 'func0f09e144', 'func0f0953cc')
self.patch(algo10, 'explosionAlertChrs', 'func0f084cf0')
self.patch(algo11, 'func0f0069dc', 'func00015fd0')
self.patch(algo12, 'func0f15c920', 'func0f0069dc')
self.fd.close()
if os.environ['PIRACYCHECKS']:
tool = Tool()
tool.run()
File renamed without changes.