Reorganise repository and rename globals to setup

This commit is contained in:
Ryan Dwyer 2019-09-29 11:57:51 +10:00
parent 66e581a77c
commit 0994436231
9 changed files with 105 additions and 117 deletions

View File

@ -59,16 +59,16 @@ E_SETUP_BIN_FILES := $(patsubst src/setup/%.c, $(E_DIR)/files/setup/U%.bin, $(SE
B_SETUP_BINZ_FILES := $(patsubst src/setup/%.c, $(B_DIR)/files/U%Z, $(SETUP_C_FILES))
E_SETUP_BINZ_FILES := $(patsubst src/setup/%.c, $(E_DIR)/files/U%Z, $(SETUP_C_FILES))
setup: $(B_SETUP_BINZ_FILES)
stagesetup: $(B_SETUP_BINZ_FILES)
$(B_DIR)/files/setup/%.o: src/setup/%.c $(SETUP_H_FILES)
mkdir -p $(B_DIR)/files/setup
$(QEMU_IRIX) -silent -L $(IRIX_ROOT) $(IRIX_ROOT)/usr/bin/cc -c $(CFLAGS) -o $@ -O2 $<
$(B_DIR)/files/setup/%.elf: $(B_DIR)/files/setup/%.o
cp $< build/setup.tmp.o
$(TOOLCHAIN)-ld -T setup.ld -o $@
rm -f build/setup.tmp.o
cp $< build/zero.tmp.o
$(TOOLCHAIN)-ld -T ld/zero.ld -o $@
rm -f build/zero.tmp.o
$(B_DIR)/files/setup/U%.bin: $(B_DIR)/files/setup/%.elf
$(TOOLCHAIN)-objcopy $< $@ -O binary
@ -95,9 +95,9 @@ $(B_DIR)/files/lang/%.o: src/lang/%.c
$(QEMU_IRIX) -silent -L $(IRIX_ROOT) $(IRIX_ROOT)/usr/bin/cc -c $(CFLAGS) -o $@ -O2 $<
$(B_DIR)/files/lang/%.elf: $(B_DIR)/files/lang/%.o
cp $< build/setup.tmp.o
$(TOOLCHAIN)-ld -T setup.ld -o $@
rm -f build/setup.tmp.o
cp $< build/zero.tmp.o
$(TOOLCHAIN)-ld -T ld/zero.ld -o $@
rm -f build/zero.tmp.o
$(B_DIR)/files/lang/L%.bin: $(B_DIR)/files/lang/%.elf
$(TOOLCHAIN)-objcopy $< $@ -O binary
@ -115,20 +115,21 @@ $(B_DIR)/files/L%Z: $(B_DIR)/files/lang/L%.bin
tools/rarezip $< > $@
################################################################################
# Globals file
# Game setup file
globals: $(B_DIR)/Uglobals
setup: $(B_DIR)/ucode/setup.bin
$(B_DIR)/globals.o: src/globals.c $(SETUP_H_FILES)
$(B_DIR)/setup.o: src/setup.c $(SETUP_H_FILES)
mkdir -p $(B_DIR)
$(QEMU_IRIX) -silent -L $(IRIX_ROOT) $(IRIX_ROOT)/usr/bin/cc -c $(CFLAGS) -o $@ -O2 $<
$(B_DIR)/globals.elf: $(B_DIR)/globals.o
cp $< build/globals.tmp.o
$(TOOLCHAIN)-ld -e 0x80059fe0 -T globals.ld -o $@
rm -f build/globals.tmp.o
$(B_DIR)/setup.elf: $(B_DIR)/setup.o
cp $< build/setup.tmp.o
$(TOOLCHAIN)-ld -e 0x80059fe0 -T ld/setup.ld -o $@
rm -f build/setup.tmp.o
$(B_DIR)/Uglobals: $(B_DIR)/globals.elf
$(B_DIR)/ucode/setup.bin: $(B_DIR)/setup.elf
mkdir -p $(B_DIR)/ucode
$(TOOLCHAIN)-objcopy $< $@ -O binary
################################################################################
@ -165,7 +166,7 @@ test: $(B_SETUP_BINZ_FILES) $(B_LANG_BINZ_FILES)
--exclude=bgdata \
--exclude=ob \
$(E_DIR)/files $(B_DIR)/files
@diff -q $(E_DIR)/Uglobals $(B_DIR)/Uglobals
@diff -q $(E_DIR)/ucode/setup.bin $(B_DIR)/ucode/setup.bin
testall:
REGION=ntsc RELEASE=final make test
@ -178,9 +179,9 @@ testall:
################################################################################
# Miscellaneous
all: setup lang globals
all: setup lang stagesetup
rom: $(B_SETUP_BINZ_FILES) $(B_DIR)/Uglobals
rom: $(B_SETUP_BINZ_FILES) $(B_DIR)/ucode/setup.bin
tools/inject pd.$(ROMID).z64
clean:

View File

@ -1,10 +1,27 @@
# Perfect Dark Decompilation (WIP)
This repository contains a work-in-progress decompilation of Perfect Dark for the Nintendo 64. So far only the stage setup files and lang files are decompiled.
This repository contains a work-in-progress decompilation of Perfect Dark for the Nintendo 64.
## I have no idea what you're talking about
## Roadmap
Go have a look at the level scripts in the src/setup directory. Here's a mapping table for your convenience:
| Section | Progress |
| --------------- | ----------------------------------------- |
| 0x40 rspboot | Won't disassemble as source is likely ASM |
| 0x1000 boot | Not started |
| 0x3050 library | Not started |
| 0x39850 setup | About 50% identified |
| 0x4e850 rarezip | 2/8 functions done |
| 0x5032e game | Not started |
| Lang files | Done |
| Setup files | Done |
| Prop files | Not started |
| Character files | Not started |
| Gun files | Not started |
| BG files | Not started |
| Pad files | Not started |
| Tile files | Not started |
If you want to browse the stage setup files, use this table to find the filename:
| Stage | File |
| ---------------- | ------------------------------------ |
@ -30,17 +47,11 @@ Go have a look at the level scripts in the src/setup directory. Here's a mapping
| WAR! | [setupstat.c](src/setup/setupstat.c) |
| The Duel | [setupate.c](src/setup/setupate.c) |
| CI Training | [setupdish.c](src/setup/setupdish.c) |
| Global Functions | [globals.c](src/globals.c) |
| Common Functions | [setup.c](src/setup.c) |
There is also a stagetable.txt in the repository root which includes multiplayer stages.
## What can I do with this?
You can read and modify the level scripting easily, then recompile it into a playable ROM file. Assuming you have a ROM already of course (it's not included in the repo). The only supported version is the NTSC 8.7 final version. Other versions will be supported eventually.
You can use this to make mods without having to deal with the GE Setup Editor's interface. Or you can use it for practicing speedruns (eg. start a level at a particular location with particular objectives completed). Or you could make ROMs to help figure out how certain commands work.
## Okay, how? Show me how to make an edit
## Compiling
Install the following:
@ -51,43 +62,10 @@ Install the following:
Then:
1. Save your existing ROM file into the root of the repository with the name `pd.ntsc-final.z64`. It should not be byteswapped (the first four bytes should be `0x80371240`).
2. Edit a setup file. Open up `src/setup/setupame.c` (Defection), find the symbol `func0422_intro` and add `explosions_around_chr(CHR_JOANNA)` as the first statement.
2. Run `make extract`. This will create an `extracted/ntsc-final` containing assets from your ROM.
3. Make edits to the C files in the `src` directory if desired.
3. Run `make rom`. This will create a ROM file at `build/ntsc-final/pd.z64`.
4. Play the ROM.
5. Start Defection, watch the intro and admire Joanna jumping from the dropship into a sea of explosions to her fiery death.
## Where's the list of commands? Is there a reference?
See `src/include/commands.h` and `src/include/constants.h` for a start.
## Whats with all this beginloop and endloop stuff?
All scripting is a series of labels and gotos. To give some structure to the code, I made a macro called `beginloop` that replaces a `label` + `yield`, and a macro called `endloop` that replaces a `goto_first` when used in this context. Most loops use the label and yield consecutively which allows this to work.
I don't think Rare had constructs like this though. There's a few rare places where yields are done at the end of the loop, and some where there's a dprint (comment) between the label and yield. In these cases my macros can't and aren't used.
I also added a `reloop` macro, which is selectively used to replace a `goto_first` within a loop. It's basically a `continue` statement for those familiar with programming.
## Can I edit global functions?
Well, yes but no. They won't be injected into the ROM because I'm lazy and haven't written code to do that. The stage files will though.
The global functions are at src/globals.c.
## How much stuff can I add before I run out of space?
Lots. If all the usual file space is exhaused, there's about 300KB of unused ROM space from other locations which will also be used. Considering each command averages only a couple of bytes, you're looking at about 10,000 to 100,000 commands you can add before you run out.
## How do I know the built files are matching?
1. With your ROM in place from earlier, run `make extract`. This will create an `extracted/ntsc-final` directory and populate it with the binaries from your ROM.
2. Without making any modifications to the setup files, run `make` to build them as usual. These will be compiled at `build/ntsc-final/files`.
3. Run `make test`. This will compare the setup binaries in `extracted` with the ones in `build`. If you get no output then they're matching. Try making a change to a file and repeat the `make` and `make test` steps again to see it identify the mismatching files.
## I want to see support for PAL, JAP and other versions
It's next on my to do list.
## Can you do the same for GoldenEye?
I might do, but my focus is on PD for now.
Run `make` followed by `make test`. If `make test` produces no output then everything is matching.

View File

@ -3,13 +3,13 @@ OUTPUT_ARCH (mips)
SECTIONS
{
.data 0x80059fe0 : AT(0x0000) {
build/globals.tmp.o (.data);
.text 0x70200000 : AT(0x0000) {
build/rarezip.tmp.o (.text);
build/rarezip.tmp.o (.data);
}
/DISCARD/ : {
* (.MIPS.abiflags);
* (.options);

20
ld/setup.ld Normal file
View File

@ -0,0 +1,20 @@
/*OUTPUT_FORMAT ("elf32-bigmips")*/
OUTPUT_ARCH (mips)
SECTIONS
{
.data 0x80059fe0 : AT(0x0000) {
build/setup.tmp.o (.data);
}
/DISCARD/ : {
* (.MIPS.abiflags);
* (.options);
* (.gnu.attributes);
* (.pdr);
* (.mdebug);
* (.gptab.bss);
* (.gptab.data);
* (.reginfo);
}
}

24
ld/zero.ld Normal file
View File

@ -0,0 +1,24 @@
/*OUTPUT_FORMAT ("elf32-bigmips")*/
OUTPUT_ARCH (mips)
SECTIONS
{
.data 0x00000000 : AT(0x0000) {
build/zero.tmp.o (.data);
}
.rodata : AT(SIZEOF(.data)) {
build/zero.tmp.o (.rodata);
}
/DISCARD/ : {
* (.MIPS.abiflags);
* (.options);
* (.gnu.attributes);
* (.pdr);
* (.mdebug);
* (.gptab.bss);
* (.gptab.data);
* (.reginfo);
}
}

View File

@ -1,35 +0,0 @@
/*OUTPUT_FORMAT ("elf32-bigmips")*/
OUTPUT_ARCH (mips)
SECTIONS
{
_LnameXDataStart = ADDR(.data);
_LnameXDataRomStart = 0x0000;
.data 0x00000000 : AT(0x0000) {
build/setup.tmp.o (.data);
}
_LnameXDataEnd = ADDR(.data) + SIZEOF(.data);
_LnameXDataRomEnd = 0x0000 + SIZEOF(.data);
_LnameXRODataStart = ADDR(.rodata);
_LnameXRODataRomStart = _LnameXDataRomEnd;
.rodata : AT(_LnameXDataRomEnd) {
build/setup.tmp.o (.rodata);
}
_LnameXRODataEnd = ADDR( .rodata) + SIZEOF( .rodata);
_LnameXRODataRomEnd = _LnameXDataRomEnd + SIZEOF( .rodata);
/DISCARD/ : {
* (.MIPS.abiflags);
* (.options);
* (.gnu.attributes);
* (.pdr);
* (.mdebug);
* (.gptab.bss);
* (.gptab.data);
* (.reginfo);
}
}

View File

@ -26,7 +26,7 @@ class Extractor:
self.rom = fd.read()
fd.close()
self.globals = self.decompress(self.rom[self.val('globals'):])
self.setup = self.decompress(self.rom[self.val('setup'):])
self.extract_all()
def extract_all(self):
@ -110,7 +110,7 @@ class Extractor:
i = self.val('files')
offsets = []
while True:
offset = int.from_bytes(self.globals[i:i+4], 'big')
offset = int.from_bytes(self.setup[i:i+4], 'big')
if offset == 0 and len(offsets):
return offsets
offsets.append(offset)
@ -143,7 +143,7 @@ class Extractor:
#
def extract_globals(self):
self.write('Uglobals', self.globals)
self.write('ucode/setup.bin', self.setup)
#
# Textures
@ -208,37 +208,37 @@ class Extractor:
'ntsc-final': {
'game': 0x4fc40,
'files': 0x28080,
'globals': 0x39850,
'setup': 0x39850,
'sfxctl': 0x80a250,
},
'ntsc-1.0': {
'game': 0x4fc40,
'files': 0x28080,
'globals': 0x39850,
'setup': 0x39850,
'sfxctl': 0x80a250,
},
'ntsc-beta': {
'game': 0x43c40,
'files': 0x29160,
'globals': 0x30850,
'setup': 0x30850,
'sfxctl': 0x7be940,
},
'pal-final': {
'game': 0x4fc40,
'files': 0x28910,
'globals': 0x39850,
'setup': 0x39850,
'sfxctl': 0x7f87e0,
},
'pal-beta': {
'game': 0x4fc40,
'files': 0x29b90,
'globals': 0x39850,
'setup': 0x39850,
'sfxctl': 0x7f87e0,
},
'jap-final': {
'game': 0x4fc40,
'files': 0x28800,
'globals': 0x39850,
'setup': 0x39850,
'sfxctl': 0x7fc670,
},
}

View File

@ -34,19 +34,19 @@ class Injector:
self.rompart3 = rombuffer[0x001a15c0:0x00ed83a0]
self.rompart4 = rombuffer[0x01d5ca00:]
fp = open('build/ntsc-final/Uglobals', 'rb')
globals = fp.read()
fp = open('build/ntsc-final/ucode/setup.bin', 'rb')
setup = fp.read()
fp.close()
self.globaltop = globals[0:0x28080]
self.globalbot = globals[0x2a000:]
self.globaltop = setup[0:0x28080]
self.globalbot = setup[0x2a000:]
self.files = []
i = 0
while i <= 0x7dd:
romnameaddr = int.from_bytes(rombuffer[0x01d5ca00 + i * 4:0x01d5ca00 + i * 4 + 4], 'big') + 0x01d5ca00
romdataaddr = int.from_bytes(globals[0x28080 + i * 4:0x28080 + i * 4 + 4], 'big')
romdataaddr = int.from_bytes(setup[0x28080 + i * 4:0x28080 + i * 4 + 4], 'big')
name = ''
while rombuffer[romnameaddr] != 0: