diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index f5a15e839..79277bd47 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -27,18 +27,18 @@ jobs: mingw-w64-i686-zlib - name: Checkout repository uses: actions/checkout@v4 - - name: Build pd.exe + - name: Build pd.i686.exe run: make -f Makefile.port -j - - name: Build pd.pal.exe + - name: Build pd.pal.i686.exe run: make -f Makefile.port -j ROMID=pal-final - - name: Build pd.jpn.exe + - name: Build pd.jpn.i686.exe run: make -f Makefile.port -j ROMID=jpn-final - name: Prepare artifact for packaging run: | mkdir -p bin/data - cp build/ntsc-final-port/pd.exe bin/ - cp build/pal-final-port/pd.pal.exe bin/ - cp build/jpn-final-port/pd.jpn.exe bin/ + cp build/ntsc-final-i686-windows/pd.i686.exe bin/ + cp build/pal-final-i686-windows/pd.pal.i686.exe bin/ + cp build/jpn-final-i686-windows/pd.jpn.i686.exe bin/ cp /mingw32/bin/{SDL2.dll,zlib1.dll,libgcc_s_dw2-1.dll,libwinpthread-1.dll} bin/ touch bin/data/put_your_rom_here.txt - name: Upload artifact @@ -58,18 +58,18 @@ jobs: sudo apt-get install git gcc g++ gcc-multilib g++-multilib make libsdl2-dev zlib1g-dev libsdl2-dev:i386 zlib1g-dev:i386 - name: Checkout repository uses: actions/checkout@v4 - - name: Build pd.exe + - name: Build pd.i686 run: make -f Makefile.port TARGET_PLATFORM=i686-linux -j2 - - name: Build pd.pal.exe + - name: Build pd.pal.i686 run: make -f Makefile.port TARGET_PLATFORM=i686-linux -j2 ROMID=pal-final - - name: Build pd.jpn.exe + - name: Build pd.jpn.i686 run: make -f Makefile.port TARGET_PLATFORM=i686-linux -j2 ROMID=jpn-final - name: Prepare artifact for packaging run: | mkdir -p bin/data - cp build/ntsc-final-port/pd.exe bin/pd - cp build/pal-final-port/pd.pal.exe bin/pd.pal - cp build/jpn-final-port/pd.jpn.exe bin/pd.jpn + cp build/ntsc-final-i686-linux/pd.i686 bin/pd + cp build/pal-final-i686-linux/pd.pal.i686 bin/pd.pal + cp build/jpn-final-i686-linux/pd.jpn.i686 bin/pd.jpn touch bin/data/put_your_rom_here.txt - name: Upload artifact uses: actions/upload-artifact@v4 @@ -78,10 +78,81 @@ jobs: path: bin/ retention-days: 0 + build-x86_64-windows: + runs-on: windows-latest + defaults: + run: + shell: msys2 {0} + steps: + - name: Install MSYS2 + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: >- + git + make + mingw-w64-x86_64-toolchain + mingw-w64-x86_64-python + mingw-w64-x86_64-SDL2 + mingw-w64-x86_64-zlib + - name: Checkout repository + uses: actions/checkout@v4 + - name: Build pd.x86_64.exe + run: make -f Makefile.port -j + - name: Build pd.pal.x86_64.exe + run: make -f Makefile.port -j ROMID=pal-final + - name: Build pd.jpn.x86_64.exe + run: make -f Makefile.port -j ROMID=jpn-final + - name: Prepare artifact for packaging + run: | + mkdir -p bin/data + cp build/ntsc-final-x86_64-windows/pd.x86_64.exe bin/ + cp build/pal-final-x86_64-windows/pd.pal.x86_64.exe bin/ + cp build/jpn-final-x86_64-windows/pd.jpn.x86_64.exe bin/ + cp /mingw64/bin/{SDL2.dll,zlib1.dll,libwinpthread-1.dll,libgcc_s_seh-1.dll} bin/ + touch bin/data/put_your_rom_here.txt + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: pd-x86_64-windows + path: bin/ + retention-days: 0 + + build-x86_64-linux: + runs-on: ubuntu-latest + steps: + - name: Install dependencies + run: | + sudo dpkg --add-architecture amd64 + sudo apt-get update + sudo apt-get install git gcc g++ gcc-multilib g++-multilib make libsdl2-dev zlib1g-dev libsdl2-2.0-0 + - name: Checkout repository + uses: actions/checkout@v4 + - name: Build pd.x86_64 + run: make -f Makefile.port TARGET_PLATFORM=x86_64-linux -j2 + - name: Build pd.pal.x86_64 + run: make -f Makefile.port TARGET_PLATFORM=x86_64-linux -j2 ROMID=pal-final + - name: Build pd.jpn.x86_64 + run: make -f Makefile.port TARGET_PLATFORM=x86_64-linux -j2 ROMID=jpn-final + - name: Prepare artifact for packaging + run: | + mkdir -p bin/data + cp build/ntsc-final-x86_64-linux/pd.x86_64 bin/pd + cp build/pal-final-x86_64-linux/pd.pal.x86_64 bin/pd.pal + cp build/jpn-final-x86_64-linux/pd.jpn.x86_64 bin/pd.jpn + touch bin/data/put_your_rom_here.txt + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: pd-x86_64-linux + path: bin/ + retention-days: 0 + build-flatpak-bundle: name: "Build flatpak bundle" runs-on: ubuntu-latest - needs: [build-i686-linux] + needs: [build-i686-linux, build-x86_64-linux] container: image: bilelmoussaoui/flatpak-github-actions:freedesktop-23.08 options: --privileged @@ -89,7 +160,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: - name: pd-i686-linux + name: pd-x86_64-linux path: dist/linux/bin/ - uses: flatpak/flatpak-github-actions/flatpak-builder@v6 @@ -117,7 +188,7 @@ jobs: publish-latest-build: runs-on: ubuntu-latest if: github.ref == 'refs/heads/port' - needs: [build-i686-windows, build-i686-linux, build-flatpak-bundle] + needs: [build-i686-windows, build-i686-linux, build-x86_64-windows, build-x86_64-linux, build-flatpak-bundle] permissions: contents: write steps: @@ -132,7 +203,9 @@ jobs: mkdir ci-release pushd ci-artifacts tar czf ../ci-release/pd-i686-linux.tar.gz pd-i686-linux + tar czf ../ci-release/pd-x86_64-linux.tar.gz pd-x86_64-linux zip -r ../ci-release/pd-i686-windows.zip pd-i686-windows + zip -r ../ci-release/pd-x86_64-windows.zip pd-x86_64-windows mv io.github.fgsfdsfgs.perfect_dark.flatpak/io.github.fgsfdsfgs.perfect_dark.flatpak ../ci-release/ popd git tag --force ci-dev-build port diff --git a/.gitignore b/.gitignore index 036ef12cf..3d0bebd42 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ src/assets/*/textures/*.bin src/generated tools/mkrom/mkrom /.vs +CppProperties.json +.idea diff --git a/Makefile.port b/Makefile.port index fe36ef222..470e4382f 100644 --- a/Makefile.port +++ b/Makefile.port @@ -79,36 +79,42 @@ ifeq ($(TARGET_PLATFORM),) TARGET_PLATFORM := $(HOST_PLATFORM) endif -ifeq (,$(findstring clean,$(MAKECMDGOALS))) - $(info Host platform: $(HOST_PLATFORM)) - $(info Target platform: $(TARGET_PLATFORM)) -endif +# Get the arch part from the platform designator. +HOST_ARCH := $(word 1,$(subst -, ,$(HOST_PLATFORM))) +TARGET_ARCH := $(word 1,$(subst -, ,$(TARGET_PLATFORM))) -# Set whether the target arch is 64- or 32-bit. +# Gather platform parameters. +# Whether the platform is 64 bit. ifneq (,$(findstring 64,$(TARGET_PLATFORM))$(findstring armv8,$(TARGET_PLATFORM))) - # TODO: we're not 64-bit compatible yet, error out if building the actual game - ifeq (,$(findstring clean,$(MAKECMDGOALS))) - $(error 64-bit target platforms are not supported yet) - endif - TARGET_64BIT = 1 -else # TODO - TARGET_64BIT = 0 + TARGET_64BIT := 1 +else + TARGET_64BIT := 0 +endif +# Whether the target is big-endian or little-endian. +TARGET_BIG_ENDIAN = 0 # TODO +# Executable extension. +ifneq (,$(findstring windows,$(TARGET_PLATFORM))) + BIN_EXTENSION := .exe +else + BIN_EXTENSION := endif -# Set whether the target is big-endian or little-endian. -TARGET_BIG_ENDIAN = 0 # TODO +ifeq (,$(findstring clean,$(MAKECMDGOALS))) + $(info Host platform: $(HOST_PLATFORM) (arch $(HOST_ARCH))) + $(info Target platform: $(TARGET_PLATFORM) (arch $(TARGET_ARCH))) +endif # The VERSION constant is used in the source to handle version-specific code. ifeq ($(ROMID),ntsc-final) - BIN_NAME = pd.exe + BIN_NAME = pd.$(TARGET_ARCH)$(BIN_EXTENSION) VERSION = 2 IS_PAL = 0 else ifeq ($(ROMID),pal-final) - BIN_NAME = pd.pal.exe + BIN_NAME = pd.pal.$(TARGET_ARCH)$(BIN_EXTENSION) VERSION = 4 IS_PAL = 1 else ifeq ($(ROMID),jpn-final) - BIN_NAME = pd.jpn.exe + BIN_NAME = pd.jpn.$(TARGET_ARCH)$(BIN_EXTENSION) VERSION = 5 IS_PAL = 0 else @@ -118,6 +124,7 @@ endif VERSION_HASH := $(shell git rev-parse --short HEAD) VERSION_BRANCH := $(shell git rev-parse --abbrev-ref HEAD) VERSION_TARGET := $(TARGET_PLATFORM) +VERSION_ARCH := $(TARGET_ARCH) VERSION_ROMID := $(ROMID) ifeq ($(VERSION_BRANCH),) @@ -127,10 +134,13 @@ ifeq ($(VERSION_BRANCH),HEAD) VERSION_BRANCH := port-custom endif +BUILDID := $(ROMID)-$(TARGET_PLATFORM) + DEFINES := \ VERSION=$(VERSION) \ VERSION_HASH=\"$(VERSION_HASH)\" \ VERSION_TARGET=\"$(VERSION_TARGET)\" \ + VERSION_ARCH=\"$(VERSION_ARCH)\" \ VERSION_ROMID=\"$(VERSION_ROMID)\" \ VERSION_BRANCH=\"$(VERSION_BRANCH)\" \ MATCHING=0 \ @@ -143,10 +153,14 @@ ifeq ($(DEBUG),1) DEFINES := $(DEFINES) DEBUG=1 endif +ifeq (1,$(TARGET_64BIT)) + DEFINES += PLATFORM_64BIT=1 +endif + C_DEFINES := $(foreach d,$(DEFINES),-D$(d)) A_DIR := src/assets/$(ROMID) -B_DIR := build/$(ROMID)-port +B_DIR := build/$(BUILDID) G_DIR := src/generated/$(ROMID) ifneq (,$(findstring windows,$(TARGET_PLATFORM))) @@ -277,6 +291,7 @@ LDFLAGS := $(TARGET_LDFLAGS) # Make ROMID available as an environment variable to all tooling. # (We use this a lot) export ROMID +export BUILDID BIN := $(B_DIR)/$(BIN_NAME) @@ -333,7 +348,7 @@ $(B_DIR)/%.res: dist/windows/%.rc # Clean rules clean: - rm -rf build/$(ROMID)-port + rm -rf build/$(BUILDID) allclean: rm -rf build/* diff --git a/README.md b/README.md index 77dddb984..881e26a19 100644 --- a/README.md +++ b/README.md @@ -45,15 +45,17 @@ There are minor graphics- and gameplay-related issues, and possibly occasional c * in practice the game will have issues running faster than ~165 FPS, so use VSync or `Video.FramerateLimit` to cap it. * emulate the Transfer Pak functionality the game has on the Nintendo 64 to unlock some cheats automatically. -Currently only 32-bit platforms are supported, namely x86 Windows and Linux. -Note that 32-bit binaries will still work on 64-bit versions of those platforms, -though you might have to install some additional libraries. +Currently both 32-bit and 64-bit platforms should be supported. +The port is tested on i686 and x86_64, both on Windows and on Linux. +ARM platforms might be supported, but are mostly untested. ## Download Latest [automatic builds](https://github.com/fgsfdsfgs/perfect_dark/actions) of the netplay branch for supported platforms: -* [i686-windows (`port-net`)](https://nightly.link/fgsfdsfgs/perfect_dark/workflows/c-cpp/port-net/pd-i686-windows.zip) -* [i686-linux (`port-net`)](https://nightly.link/fgsfdsfgs/perfect_dark/workflows/c-cpp/port-net/pd-i686-linux.zip) +* [x86_64-windows (`port-net`)](https://nightly.link/fgsfdsfgs/perfect_dark/workflows/c-cpp/port-net/pd-net-x86_64-windows.zip) +* [i686-windows (`port-net`)](https://nightly.link/fgsfdsfgs/perfect_dark/workflows/c-cpp/port-net/pd-net-i686-windows.zip) +* [x86_64-linux (`port-net`)](https://nightly.link/fgsfdsfgs/perfect_dark/workflows/c-cpp/port-net/pd-net-x86_64-linux.zip) +* [i686-linux (`port-net`)](https://nightly.link/fgsfdsfgs/perfect_dark/workflows/c-cpp/port-net/pd-net-i686-linux.zip) If you are looking for regular builds (the `port` branch), see [this link](https://github.com/fgsfdsfgs/perfect_dark/blob/port/README.md#download). @@ -61,13 +63,15 @@ If you are looking for regular builds (the `port` branch), see [this link](https You must already have a Perfect Dark ROM to run the game, as specified above. -1. Create a directory named `data` next to `pd.exe` if it's not there. +This assumes that you're using an x86_64 build. If you aren't, replace `x86_64` below with your arch (e.g. `i686`). + +1. Create a directory named `data` next to `pd.x86_64` if it's not there. 2. Put your Perfect Dark NTSC ROM named `pd.ntsc-final.z64` into it. -3. Run `pd.exe`. +3. Run the `pd.x86_64` executable. If you want to use a PAL or JPN ROM instead, put them into the `data` directory and run the appropriate executable: -* PAL: ROM name `pd.pal-final.z64`, EXE name `pd.pal.exe`. -* JPN: ROM name `pd.jpn-final.z64`, EXE name `pd.jpn.exe`. +* PAL: ROM name `pd.pal-final.z64`, executable name `pd.pal.x86_64`. +* JPN: ROM name `pd.jpn-final.z64`, executable name `pd.jpn.x86_64`. Optionally, you can also put your Perfect Dark for GameBoy Color ROM named `pd.gbc` in the `data` directory if you want to emulate having the Nintendo 64's Transfer Pak and unlock some cheats automatically. @@ -111,44 +115,46 @@ Controls can be rebound in `pd.ini`. Default control scheme is as follows: ### Windows 1. Install [MSYS2](https://www.msys2.org). -2. Open the `MINGW32` prompt. (**NOTE:** _not_ the `MSYS` prompt or the `MINGW64` prompt) +2. Open the `MINGW64` prompt if building for x86_64, or the `MINGW32` prompt if building for i686. (**NOTE:** _do not_ use the `MSYS` prompt) 3. Install dependencies: - `pacman -S mingw-w64-i686-toolchain mingw-w64-i686-SDL2 mingw-w64-i686-zlib make git` + `pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-SDL2 mingw-w64-x86_64-zlib mingw-w64-i686-toolchain mingw-w64-i686-SDL2 mingw-w64-i686-zlib make git` 4. Get the source code: `git clone -b port-net --recursive https://github.com/fgsfdsfgs/perfect_dark.git && cd perfect_dark` 5. Run `make -f Makefile.port`. * Add ` ROMID=pal-final` or ` ROMID=jpn-final` at the end of the command if you want to build a PAL or JPN executable respectively. -6. The resulting executable will be at `build/ntsc-final-port/pd.exe`. +6. The resulting executable will be at `build/ntsc-final-x86_64-windows/pd.x86_64.exe` (or at `build/ntsc-final-i686-windows/pd.i686.exe` if building for i686). 7. If you don't know where you downloaded the source to, you can run `explorer .` to open the current directory. ### Linux -1. Ensure you have gcc, g++ (version 10.0+) and 32-bit versions of SDL2 (version 2.0.12+), libGL and ZLib installed on your system. - * On a 64-bit system you also need to have `gcc-multilib` and `g++-multilib` (or your distro's analogues) installed. +1. Ensure you have gcc, g++ (version 10.0+) and SDL2 (version 2.0.12+), libGL and ZLib installed on your system. + * If you wish to crosscompile, you will also need to have libraries and compilers for the target platform installed, e.g. `gcc-multilib` and `g++-multilib` for x86_64 -> i686 crosscompilation. 2. Get the source code: `git clone -b port-net --recursive https://github.com/fgsfdsfgs/perfect_dark.git && cd perfect_dark` 3. Run the following command: - * On a 64-bit system: ```make -f Makefile.port TARGET_PLATFORM=i686-linux``` - * On a 32-bit system: ```make -f Makefile.port``` + * ```make -f Makefile.port``` * Add ` ROMID=pal-final` or ` ROMID=jpn-final` at the end of the command if you want to build a PAL or JPN executable respectively. -4. The resulting executable will be at `build/ntsc-final-port/pd.exe`. + * Add ` TARGET_PLATFORM=your-target` at the end of the command if you want to crosscompile. +4. The resulting executable will be at `build/ntsc-final-/pd.` (for example `build/ntsc-final-x86_64-linux/pd.x86_64`). -Currently only `i686-linux` and `i686-windows` are supported, using `gcc -m32` and `i686-w64-mingw32-gcc` as compilers, respectively. -Alternate compilers can be specified by passing `TOOLCHAIN=i686-whatever-` as a command line argument. +### Notes -You can build an executable with PAL or JPN ROM support by adding `ROMID=pal-final` or `ROMID=jpn-final` to the `make` command. -You will need to provide a `jpn-final` or `pal-final` ROM to run those, named `pd.jpn-final.z64` or `pd.pal-final.z64`. +Alternate compilers can be specified by passing `TOOLCHAIN=arch-whatever-` as a command line argument. -It might be possible to build a 32-bit ARM executable, but this has not been tested. +You will need to provide a `jpn-final` or `pal-final` ROM to run executables built for those regions, named `pd.jpn-final.z64` or `pd.pal-final.z64`. + +It might be possible to build and run the game on an ARM/AArch64 platform, but this has not been tested. ## Credits * the original [decompilation project](https://github.com/n64decomp/perfect_dark) authors; +* Ryan Dwyer for the above, additional help, and `pd-extract`; * doomhack for the only other publicly available [PD porting effort](https://github.com/doomhack/perfect_dark) I could find; * [sm64-port](https://github.com/sm64-port/sm64-port) authors for the audio mixer and some other changes; * [Ship of Harkinian team](https://github.com/Kenix3/libultraship/tree/main/src/graphic/Fast3D), Emill and MaikelChan for the libultraship version of fast3d that this port uses; * lieff for [minimp3](https://github.com/lieff/minimp3); * Mouse Injector and 1964GEPD authors for some of the 60FPS- and mouselook-related fixes; +* Raf for the 64-bit port; * NicNamSam for the icon; * everyone who has submitted pull requests and issues to this repository and tested the port; * probably more I'm forgetting. diff --git a/dist/linux/io.github.fgsfdsfgs.perfect_dark.sh b/dist/linux/io.github.fgsfdsfgs.perfect_dark.sh index 0e163c2a9..28ff8213b 100644 --- a/dist/linux/io.github.fgsfdsfgs.perfect_dark.sh +++ b/dist/linux/io.github.fgsfdsfgs.perfect_dark.sh @@ -10,14 +10,15 @@ done # Default to pd as executable but switch to jpn/pal if the NTSC rom # is missing but JPN/PAL are present. -executable="pd" +# TODO: Other arch +executable="pd.x86_64" if [ -f ${XDG_DATA_HOME}/roms/pd.ntsc-final.z64 ] | \ [ -f ${XDG_DATA_HOME}/roms/pd.ntsc-1.0.z64 ]; then - executable="pd" + executable="pd.x86_64" elif [ -f ${XDG_DATA_HOME}/roms/pd.jpn-final.z64 ]; then - executable="pd.jpn" + executable="pd.jpn.x86_64" elif [ -f ${XDG_DATA_HOME}/roms/pd.pal-final.z64 ]; then - executable="pd.pal" + executable="pd.pal.x86_64" fi # If first parameter passed to this script is one of the pd executables, diff --git a/include/PR/R4300.h b/include/PR/R4300.h index 061ed8158..d5212ec6a 100644 --- a/include/PR/R4300.h +++ b/include/PR/R4300.h @@ -22,6 +22,7 @@ #define __R4300_H__ #include +#include "platform.h" /* * Segment base addresses and sizes diff --git a/include/PR/gbi.h b/include/PR/gbi.h index d8fd26bf8..7663d3033 100644 --- a/include/PR/gbi.h +++ b/include/PR/gbi.h @@ -22,6 +22,12 @@ #include #include "gbiex.h" +#include + +#ifndef PLATFORM_N64 +#include "platform.h" +#endif + /* * To use the F3DEX ucodes, define F3DEX_GBI before include this file. @@ -594,10 +600,10 @@ #define G_BL_0 3 #define GBL_c1(m1a, m1b, m2a, m2b) \ - (m1a) << 30 | (m1b) << 26 | (m2a) << 22 | (m2b) << 18 + (u32)(m1a) << 30 | (u32)(m1b) << 26 | (u32)(m2a) << 22 | (u32)(m2b) << 18 #define GBL_c2(m1a, m1b, m2a, m2b) \ - (m1a) << 28 | (m1b) << 24 | (m2a) << 20 | (m2b) << 16 + (u32)(m1a) << 28 | (u32)(m1b) << 24 | (u32)(m2a) << 20 | (u32)(m2b) << 16 #define RM_AA_ZB_OPA_SURF(clk) \ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \ @@ -1053,7 +1059,7 @@ typedef struct { // 4x4 float matrix typedef float Mtx_t[4][4]; #else -typedef long Mtx_t[4][4]; +typedef int32_t Mtx_t[4][4]; #endif typedef union { @@ -1306,6 +1312,14 @@ typedef union { /* * Graphics DMA Packet */ +#ifdef PLATFORM_64BIT +typedef struct { + intptr_t par : 24; + intptr_t cmd : 8; + intptr_t len : 32; + uintptr_t addr; +} Gdma; +#else typedef struct { #ifdef PLATFORM_BIG_ENDIAN int cmd:8; @@ -1319,6 +1333,7 @@ typedef struct { unsigned int addr; #endif } Gdma; +#endif /* * Graphics Immediate Mode Packet types @@ -1357,6 +1372,9 @@ typedef struct { unsigned char z4:4; unsigned char pad:8; unsigned char cmd:8; +#ifdef PLATFORM_64BIT + unsigned char pad2[4]; +#endif unsigned char x1:4; unsigned char y1:4; unsigned char x2:4; @@ -1365,6 +1383,9 @@ typedef struct { unsigned char y3:4; unsigned char x4:4; unsigned char y4:4; +#ifdef PLATFORM_64BIT + unsigned char pad3[4]; +#endif #endif } Gtri4; @@ -1538,8 +1559,8 @@ typedef struct { * Generic Gfx Packet */ typedef struct { - unsigned int w0; - unsigned int w1; + uintptr_t w0; + uintptr_t w1; } Gwords; // xxxxxxxx 11223344 44555566 66666777 @@ -1596,7 +1617,11 @@ typedef struct { */ typedef union { Gwords words; +#ifdef PLATFORM_64BIT + u8 bytes[16]; +#else u8 bytes[8]; +#endif Gdma dma; Gvtx vtx; Gtri tri; @@ -1619,12 +1644,19 @@ typedef union { Gloadtlut loadtlut; #endif GunkC0 unkc0; +#ifdef PLATFORM_64BIT + long long int force_structure_alignment[2]; +#else long long int force_structure_alignment; +#endif } Gfx; #ifdef PLATFORM_BIG_ENDIAN #define GFX_W0_BYTE(i) (i) #define GFX_W1_BYTE(i) (4 + (i)) +#elif PLATFORM_64BIT +#define GFX_W0_BYTE(i) (3 - (i)) +#define GFX_W1_BYTE(i) (11 - (i)) #else #define GFX_W0_BYTE(i) (3 - (i)) #define GFX_W1_BYTE(i) (7 - (i)) @@ -1642,12 +1674,12 @@ typedef union { Gfx *_g = (Gfx *)(pkt); \ \ _g->words.w0 = _SHIFTL((c), 24, 8) | _SHIFTL((l), 0, 24); \ - _g->words.w1 = (unsigned int)(s); \ + _g->words.w1 = (uintptr_t)(s); \ } #define gsDma0p(c, s, l) \ { \ - _SHIFTL((c), 24, 8) | _SHIFTL((l), 0, 24), (unsigned int)(s) \ + _SHIFTL((c), 24, 8) | _SHIFTL((l), 0, 24), (uintptr_t)(s) \ } #define gDma1p(pkt, c, s, l, p) \ @@ -1656,14 +1688,14 @@ typedef union { \ _g->words.w0 = (_SHIFTL((c), 24, 8) | _SHIFTL((p), 16, 8) | \ _SHIFTL((l), 0, 16)); \ - _g->words.w1 = (unsigned int)(s); \ + _g->words.w1 = (uintptr_t)(s); \ } #define gsDma1p(c, s, l, p) \ { \ (_SHIFTL((c), 24, 8) | _SHIFTL((p), 16, 8) | \ _SHIFTL((l), 0, 16)), \ - (unsigned int)(s) \ + (uintptr_t)(s) \ } #define gDma2p(pkt, c, adrs, len, idx, ofs) \ @@ -1671,14 +1703,14 @@ typedef union { Gfx *_g = (Gfx *)(pkt); \ _g->words.w0 = (_SHIFTL((c),24,8)|_SHIFTL(((len)-1)/8,19,5)| \ _SHIFTL((ofs)/8,8,8)|_SHIFTL((idx),0,8)); \ - _g->words.w1 = (unsigned int)(adrs); \ + _g->words.w1 = (uintptr_t)(adrs); \ } #define gsDma2p(c, adrs, len, idx, ofs) \ { \ (_SHIFTL((c),24,8)|_SHIFTL(((len)-1)/8,19,5)| \ _SHIFTL((ofs)/8,8,8)|_SHIFTL((idx),0,8)), \ - (unsigned int)(adrs) \ + (uintptr_t)(adrs) \ } #define gSPNoOp(pkt) gDma0p(pkt, G_SPNOOP, 0, 0) @@ -1727,12 +1759,12 @@ typedef union { Gfx *_g = (Gfx *)(pkt); \ \ _g->words.w0 = _SHIFTL((c), 24, 8); \ - _g->words.w1 = (unsigned int)(p0); \ + _g->words.w1 = (uintptr_t)(p0); \ } #define gsImmp1(c, p0) \ { \ - _SHIFTL((c), 24, 8), (unsigned int)(p0) \ + _SHIFTL((c), 24, 8), (uintptr_t)(p0) \ } #define gImmp2(pkt, c, p0, p1) \ @@ -1769,13 +1801,13 @@ typedef union { \ _g->words.w0 = (_SHIFTL((c), 24, 8) | _SHIFTL((p0), 8, 16) | \ _SHIFTL((p1), 0, 8)); \ - _g->words.w1 = (unsigned int) (dat); \ + _g->words.w1 = (uintptr_t) (dat); \ } #define gsImmp21(c, p0, p1, dat) \ { \ _SHIFTL((c), 24, 8) | _SHIFTL((p0), 8, 16) | _SHIFTL((p1), 0, 8), \ - (unsigned int) (dat) \ + (uintptr_t) (dat) \ } #define gMoveWd(pkt, index, offset, data) \ @@ -1918,7 +1950,7 @@ typedef union { \ _g->words.w0 = _SHIFTL(G_CULLDL, 24, 8) | \ ((0x0f & (vstart))*40); \ - _g->words.w1 = (unsigned int)((0x0f & ((vend)+1))*40); \ + _g->words.w1 = (uintptr_t)((0x0f & ((vend)+1))*40); \ } // Removed in PD @@ -2239,12 +2271,12 @@ typedef union { Gfx *_g = (Gfx *)(pkt); \ \ _g->words.w0 = _SHIFTL(G_SETGEOMETRYMODE, 24, 8); \ - _g->words.w1 = (unsigned int)(word); \ + _g->words.w1 = (uintptr_t)(word); \ } #define gsSPSetGeometryMode(word) \ { \ - _SHIFTL(G_SETGEOMETRYMODE, 24, 8), (unsigned int)(word) \ + _SHIFTL(G_SETGEOMETRYMODE, 24, 8), (uintptr_t)(word) \ } #define gSPClearGeometryMode(pkt, word) \ @@ -2252,12 +2284,12 @@ typedef union { Gfx *_g = (Gfx *)(pkt); \ \ _g->words.w0 = _SHIFTL(G_CLEARGEOMETRYMODE, 24, 8); \ - _g->words.w1 = (unsigned int)(word); \ + _g->words.w1 = (uintptr_t)(word); \ } #define gsSPClearGeometryMode(word) \ { \ - _SHIFTL(G_CLEARGEOMETRYMODE, 24, 8), (unsigned int)(word) \ + _SHIFTL(G_CLEARGEOMETRYMODE, 24, 8), (uintptr_t)(word) \ } #define gSPSetOtherMode(pkt, cmd, sft, len, data) \ @@ -2266,13 +2298,13 @@ typedef union { \ _g->words.w0 = (_SHIFTL(cmd, 24, 8) | _SHIFTL(sft, 8, 8) | \ _SHIFTL(len, 0, 8)); \ - _g->words.w1 = (unsigned int)(data); \ + _g->words.w1 = (uintptr_t)(data); \ } #define gsSPSetOtherMode(cmd, sft, len, data) \ { \ _SHIFTL(cmd, 24, 8) | _SHIFTL(sft, 8, 8) | _SHIFTL(len, 0, 8), \ - (unsigned int)(data) \ + (uintptr_t)(data) \ } /* @@ -2323,14 +2355,14 @@ typedef union { \ _g->words.w0 = _SHIFTL(cmd, 24, 8) | _SHIFTL(fmt, 21, 3) | \ _SHIFTL(siz, 19, 2) | _SHIFTL((width)-1, 0, 12); \ - _g->words.w1 = (unsigned int)(i); \ + _g->words.w1 = (uintptr_t)(i); \ } #define gsSetImage(cmd, fmt, siz, width, i) \ { \ _SHIFTL(cmd, 24, 8) | _SHIFTL(fmt, 21, 3) | \ _SHIFTL(siz, 19, 2) | _SHIFTL((width)-1, 0, 12), \ - (unsigned int)(i) \ + (uintptr_t)(i) \ } #define gDPSetColorImage(pkt, f, s, w, i) gSetImage(pkt, G_SETCIMG, f, s, w, i) @@ -2356,13 +2388,13 @@ typedef union { Gfx *_g = (Gfx *)(pkt); \ \ _g->words.w0 = _SHIFTL(G_SETCOMBINE, 24, 8) | _SHIFTL(muxs0, 0, 24); \ - _g->words.w1 = (unsigned int)(muxs1); \ + _g->words.w1 = (uintptr_t)(muxs1); \ } #define gsDPSetCombine(muxs0, muxs1) \ { \ _SHIFTL(G_SETCOMBINE, 24, 8) | _SHIFTL(muxs0, 0, 24), \ - (unsigned int)(muxs1) \ + (uintptr_t)(muxs1) \ } #define GCCc0w0(saRGB0, mRGB0, saA0, mA0) \ @@ -2435,12 +2467,12 @@ typedef union { Gfx *_g = (Gfx *)(pkt); \ \ _g->words.w0 = _SHIFTL(c, 24, 8); \ - _g->words.w1 = (unsigned int)(d); \ + _g->words.w1 = (uintptr_t)(d); \ } #define gsDPSetColor(c, d) \ { \ - _SHIFTL(c, 24, 8), (unsigned int)(d) \ + _SHIFTL(c, 24, 8), (uintptr_t)(d) \ } #define DPRGBColor(pkt, cmd, r, g, b, a) \ @@ -2521,13 +2553,13 @@ typedef union { Gfx *_g = (Gfx *)(pkt); \ \ _g->words.w0 = _SHIFTL(G_RDPSETOTHERMODE,24,8)|_SHIFTL(mode0,0,24); \ - _g->words.w1 = (unsigned int)(mode1); \ + _g->words.w1 = (uintptr_t)(mode1); \ } #define gsDPSetOtherMode(mode0, mode1) \ { \ _SHIFTL(G_RDPSETOTHERMODE,24,8)|_SHIFTL(mode0,0,24), \ - (unsigned int)(mode1) \ + (uintptr_t)(mode1) \ } /* diff --git a/include/PR/gu.h b/include/PR/gu.h index 7744bdf92..3b5518c7b 100644 --- a/include/PR/gu.h +++ b/include/PR/gu.h @@ -35,7 +35,7 @@ #define OS_M_PI 3.14159265358979323846 #define M_DTOR (3.14159265358979323846/180.0) -#define FTOFIX32(x) (long)((x) * (float)0x00010000) +#define FTOFIX32(x) (int)((x) * (float)0x00010000) #define FIX32TOF(x) ((float)(x) * (1.0f / (float)0x00010000)) #define FTOFRAC8(x) ((int) MIN(((x) * (128.0f)), 127.0f) & 0xff) diff --git a/include/PR/n_libaudio.h b/include/PR/n_libaudio.h index 4f82c2471..d672986e8 100644 --- a/include/PR/n_libaudio.h +++ b/include/PR/n_libaudio.h @@ -28,6 +28,7 @@ extern "C" { #include #include +#include "platform.h" struct var8009c340 { u8 surround; @@ -256,7 +257,7 @@ typedef struct { ALOscStop stopOsc; ALSeqMarker *loopStart; ALSeqMarker *loopEnd; - s32 loopCount; /* -1 = loop forever, 0 = no loop */ + intptr_t loopCount; /* -1 = loop forever, 0 = no loop */ u8 unk88; u8 unk89; } N_ALSeqPlayer; @@ -284,9 +285,19 @@ typedef struct { ALOscInit initOsc; ALOscUpdate updateOsc; ALOscStop stopOsc; + +#ifdef PLATFORM_64BIT + s32 _pad1_; + f32 unk7c; + s32 _pad2_; + f32 unk80; +#else f32 unk7c; f32 unk80; +#endif + void *queue; + u8 unk88; u8 unk89; } N_ALCSPlayer; diff --git a/include/PR/os_pi.h b/include/PR/os_pi.h index 0c7459784..eca4eae88 100644 --- a/include/PR/os_pi.h +++ b/include/PR/os_pi.h @@ -37,7 +37,7 @@ extern "C" { #include #include "os_thread.h" #include "os_message.h" - +#include #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) @@ -198,7 +198,7 @@ extern u32 osPiGetStatus(void); extern s32 osPiGetDeviceType(void); extern s32 osPiWriteIo(u32, u32); extern s32 osPiReadIo(u32, u32 *); -extern s32 osPiStartDma(OSIoMesg *, s32, s32, u32, void *, u32, +extern s32 osPiStartDma(OSIoMesg *, s32, s32, uintptr_t, void *, u32, OSMesgQueue *); extern void osCreatePiManager(OSPri, OSMesgQueue *, OSMesg *, s32); diff --git a/port/include/preprocess.h b/port/include/preprocess.h index 5d930dcd5..450a641fc 100644 --- a/port/include/preprocess.h +++ b/port/include/preprocess.h @@ -3,32 +3,30 @@ #include -typedef void (*preprocessfunc)(u8 *data, u32 size); +typedef u8 *(*preprocessfunc)(u8 *data, u32 size, u32 *outSize); -void preprocessAnimations(u8 *data, u32 size); -void preprocessMpConfigs(u8 *data, u32 size); -void preprocessFont(u8 *data, u32 size); -void preprocessJpnFont(u8 *data, u32 size); -void preprocessALBankFile(u8 *data, u32 size); -void preprocessALCMidiHdr(u8 *data, u32 size); -void preprocessSequences(u8 *data, u32 size); -void preprocessFiringRange(u8 *data, u32 size); -void preprocessTexturesList(u8 *data, u32 size); +u8* preprocessAnimations(u8 *data, u32 size, u32 *outSize); +u8* preprocessMpConfigs(u8 *data, u32 size, u32 *outSize); +u8* preprocessFont(u8 *data, u32 size, u32 *outSize); +u8* preprocessJpnFont(u8 *data, u32 size, u32 *outSize); +u8* preprocessALBankFile(u8 *data, u32 size, u32 *outSize); +u8 *preprocessALCMidiHdr(u8 *data, u32 size, u32 *outSize); +u8* preprocessSequences(u8 *data, u32 size, u32 *outSize); +u8* preprocessTexturesList(u8 *data, u32 size, u32 *outSize); -void preprocessBgSection1Header(u8 *data, u32 size); -void preprocessBgSection1(u8 *data, u32 size); -void preprocessBgSection2Header(u8 *data, u32 size); +void preprocessBgSection1(u8* data, u32 size, u32 ofs); void preprocessBgSection2(u8 *data, u32 size); +void preprocessBgSection3(u8* data, u32 size); +void preprocessBgSection1Header(u8 *data, u32 size); +void preprocessBgSection2Header(u8 *data, u32 size); void preprocessBgSection3Header(u8 *data, u32 size); -void preprocessBgSection3(u8 *data, u32 size); -void preprocessBgRoom(u8 *data, u32 ofs); -void preprocessBgLights(u8 *data, u32 ofs); +u32 preprocessBgRoom(u8* data, u32 size, u32 room_ofs); -void preprocessLangFile(u8 *data, u32 size); -void preprocessPadsFile(u8 *data, u32 size); -void preprocessTilesFile(u8 *data, u32 size); -void preprocessSetupFile(u8 *data, u32 size); -void preprocessModelFile(u8 *data, u32 size); -void preprocessGunFile(u8 *data, u32 size); +u8 *preprocessLangFile(u8 *data, u32 size, u32 *outSize); +u8 *preprocessPadsFile(u8 *data, u32 size, u32 *outSize); +u8 *preprocessTilesFile(u8 *data, u32 size, u32 *outSize); +u8 *preprocessSetupFile(u8 *data, u32 size, u32 *outSize); +u8 *preprocessModelFile(u8 *data, u32 size, u32 *outSize); +u8 *preprocessGunFile(u8 *data, u32 size, u32 *outSize); #endif diff --git a/port/include/preprocess/common.h b/port/include/preprocess/common.h new file mode 100644 index 000000000..1927eaef7 --- /dev/null +++ b/port/include/preprocess/common.h @@ -0,0 +1,59 @@ +#ifndef _IN_PREPROCESS_COMMON_H +#define _IN_PREPROCESS_COMMON_H + +#include +#include +#include +#include + +#include +#include "types.h" +#include "constants.h" + +#include "platform.h" +#include "system.h" +#include "romdata.h" +#include "preprocess.h" + +#define MAX_PTR_MARKERS (1024 * 8) + +#define PD_ALIGN(val, size) (((val) + ((size) - 1)) & ~((size) - 1)) + +#define PD_PTR_BASE(x, b) (void *)((u8 *)b + (uintptr_t)x) +#define PD_PTR_BASEOFS(x, b, d) (void *)((u8 *)b - d + (uintptr_t)x) + +static inline f32 swapF32(f32 x) { *(u32*)&x = PD_BE32(*(u32*)&x); return x; } +static inline u32 swapU32(u32 x) { return PD_BE32(x); } +static inline s32 swapS32(s32 x) { return PD_BE32(x); } +static inline u16 swapU16(u16 x) { return PD_BE16(x); } +static inline s16 swapS16(s16 x) { return PD_BE16(x); } +static inline void* swapPtr(void** x) { return (void*)PD_BEPTR((uintptr_t)x); } +static inline struct coord swapCrd(struct coord crd) { crd.x = swapF32(crd.x); crd.y = swapF32(crd.y); crd.z = swapF32(crd.z); return crd; } +static inline u32 swapUnk(u32 x) { assert(0 && "unknown type"); return x; } + +#define PD_SWAPPED_VAL(x) _Generic((x), \ + f32: swapF32, \ + u32: swapU32, \ + s32: swapS32, \ + u16: swapU16, \ + s16: swapS16, \ + struct coord: swapCrd, \ + default: swapUnk \ +)(x) + +#define PD_SWAP_VAL(x) x = PD_SWAPPED_VAL(x) + +#define PD_SWAP_PTR(x) x = swapPtr((void *)(x)) + +// ptr marker functions + +struct ptrmarker { + u32 ptr_src; + uintptr_t ptr_host; +}; + +void ptrAdd(u32 ptr_src, uintptr_t ptr_host); +struct ptrmarker* ptrFind(uintptr_t ptr_src); +void ptrReset(void); + +#endif diff --git a/port/include/preprocess/gbi.h b/port/include/preprocess/gbi.h new file mode 100644 index 000000000..3752ceebe --- /dev/null +++ b/port/include/preprocess/gbi.h @@ -0,0 +1,15 @@ +#ifndef _IN_PREPROCESS_GBI_H +#define _IN_PREPROCESS_GBI_H + +#include "preprocess/common.h" + +// gbi related functions +void gbiReset(void); +void gbiSetSegment(int segment, u32 offset); +void gbiSetVtx(u32 src_offset, u32 dst_offset); +u32 gbiConvertGdl(u8 *dst, u32 dstpos, u8 *src, u32 srcpos, int segment_cmds); +void gbiConvertVtx(u8* dst, u32 dstpos, int count); +void gbiGdlRewriteAddrs(u8* dst, u32 offset); +void gbiAddTexAddr(u32 src_offset, u32 dst_offset); + +#endif diff --git a/port/include/preprocess/setup.h b/port/include/preprocess/setup.h new file mode 100644 index 000000000..f281410c4 --- /dev/null +++ b/port/include/preprocess/setup.h @@ -0,0 +1,640 @@ +#ifndef _IN_SETUP_DECL +#define _IN_SETUP_DECL + +#include "preprocess/common.h" + +struct n64_stagesetup { + u32 ptr_waypoints; + u32 ptr_waygroups; + u32 ptr_cover; + u32 ptr_intro; + u32 ptr_props; + u32 ptr_paths; + u32 ptr_ailists; + u32 ptr_padfiledata; +}; + +struct n64_coord { + f32 x; + f32 y; + f32 z; +}; + +struct n64_defaultobj { + u16 extrascale; + u8 hidden2; + u8 type; + s16 modelnum; + s16 pad; + u32 flags; + u32 flags2; + u32 flags3; + u32 ptr_prop; + u32 ptr_model; + f32 realrot[3][3]; + u32 hidden; + union { + u32 ptr_geotilef; + u32 ptr_geoblock; + u32 ptr_geocyl; + u32 ptr_unkgeo; + }; + union { + u32 ptr_projectile; + u32 ptr_embedment; + }; + s16 damage; + s16 maxdamage; + u8 shadecol[4]; + u8 nextcol[4]; + u16 floorcol; + s8 geocount; + s8 _pad_; +}; + +struct n64_doorobj { + struct n64_defaultobj base; + f32 maxfrac; + f32 perimfrac; + f32 accel; + f32 decel; + f32 maxspeed; + u16 doorflags; + u16 doortype; + u32 keyflags; + s32 autoclosetime; + f32 frac; + f32 fracspeed; + s8 mode; + s8 glasshits; + s16 fadealpha; + s16 xludist; + s16 opadist; + struct n64_coord startpos; + f32 mtx98[3][3]; + u32 ptr_sibling; + s32 lastopen60; + s16 portalnum; + s8 soundtype; + s8 fadetime60; + s32 lastcalc60; + u8 laserfade; + u8 unusedmaybe[3]; + u8 shadeinfo1[4]; + u8 shadeinfo2[4]; + u8 actual1; + u8 actual2; + u8 extra1; + u8 extra2; +}; + +struct n64_doorscaleobj { + u32 unk00; + s32 scale; +}; + +struct n64_keyobj { + struct n64_defaultobj base; + u32 keyflags; +}; + +struct n64_alarmobj { + struct n64_defaultobj base; +}; + +struct n64_cctvobj { + struct n64_defaultobj base; + + s16 lookatpadnum; + s16 toleft; + //Mtxf camrotm; + f32 m[4][4]; + f32 yzero; + f32 yrot; + f32 yleft; + f32 yright; + f32 yspeed; + f32 ymaxspeed; + s32 seebondtime60; + f32 maxdist; + f32 xzero; +}; + +struct n64_ammocrateobj { + struct n64_defaultobj base; + s32 ammotype; +}; + +struct n64_gset { + u8 weaponnum; + u8 unk0639; + u8 unk063a; + u8 weaponfunc; +}; + +struct n64_weaponobj { + struct n64_defaultobj base; + + union { + struct n64_gset gset; + struct { + u8 weaponnum; + s8 unk5d; + s8 unk5e; + u8 gunfunc; + }; + }; + + s8 fadeouttimer60; + s8 dualweaponnum; + + union { + s16 timer240; + s16 team; + }; + + u32 ptr_dualweapon; +}; + +struct n64_packedchr { + s16 chrindex; + s8 unk02; + s8 typenum; + u32 spawnflags; + s16 chrnum; + u16 padnum; + u8 bodynum; + s8 headnum; + u16 ailistnum; + u16 padpreset; + u16 chrpreset; + u16 hearscale; + u16 viewdist; + u32 flags; + u32 flags2; + u8 team; + u8 squadron; + s16 chair; + u32 convtalk; + u8 tude; + u8 naturalanim; + u8 yvisang; + u8 teamscandist; +}; + +struct n64_tvscreen { + u32 ptr_cmdlist; + u16 offset; + s16 pause60; + u32 ptr_tconfig; + f32 rot; + f32 xscale; + f32 xscalefrac; + f32 xscaleinc; + f32 xscaleold; + f32 xscalenew; + f32 yscale; + f32 yscalefrac; + f32 yscaleinc; + f32 yscaleold; + f32 yscalenew; + f32 xmid; + f32 xmidfrac; + f32 xmidinc; + f32 xmidold; + f32 xmidnew; + f32 ymid; + f32 ymidfrac; + f32 ymidinc; + f32 ymidold; + f32 ymidnew; + u8 red; + u8 redold; + u8 rednew; + u8 green; + u8 greenold; + u8 greennew; + u8 blue; + u8 blueold; + u8 bluenew; + u8 alpha; + u8 alphaold; + u8 alphanew; + f32 colfrac; + f32 colinc; +}; + +struct n64_singlemonitorobj { + struct n64_defaultobj base; + struct n64_tvscreen screen; + s16 owneroffset; + s8 ownerpart; + u8 imagenum; +}; + +struct n64_multimonitorobj { + struct n64_defaultobj base; + struct n64_tvscreen screens[4]; + u8 imagenums[4]; +}; + +struct n64_hangingmonitorsobj { + struct n64_defaultobj base; +}; + +struct n64_autogunobj { + struct n64_defaultobj base; + s16 targetpad; + s8 firing; + u8 firecount; + f32 yzero; + f32 ymaxleft; + f32 ymaxright; + f32 yrot; + f32 yspeed; + f32 xzero; + f32 xrot; + f32 xspeed; + f32 maxspeed; + f32 aimdist; + f32 barrelspeed; + f32 barrelrot; + s32 lastseebond60; + s32 lastaimbond60; + s32 allowsoundframe; + u32 ptr_beam; + f32 shotbondsum; + u32 ptr_target; + u8 targetteam; + u8 ammoquantity; + s16 nextchrtest; +}; + +struct n64_linkgunsobj { + u32 unk00; + s16 offset1; + s16 offset2; +}; + +struct n64_debrisobj { + struct n64_defaultobj base; +}; + +struct n64_hatobj { + struct n64_defaultobj base; +}; + +struct n64_grenadeprobobj { // objtype 0x12 + u32 unk00; + s16 chrnum; + u16 probability; +}; + +struct n64_linkliftdoorobj { + u32 unk00; + u32 ptr_door; + u32 ptr_lift; + u32 ptr_next; + s32 stopnum; +}; + +struct n64_multiammocrateslot { + u16 modelnum; + u16 quantity; +}; + +struct n64_multiammocrateobj { + struct n64_defaultobj base; + struct n64_multiammocrateslot slots[19]; +}; + +struct n64_shieldobj { + struct n64_defaultobj base; + f32 initialamount; + f32 amount; + u32 unk64; +}; + +struct n64_tag { + u32 identifier; + u16 tagnum; + s16 cmdoffset; + u32 ptr_next; + u32 ptr_obj; +}; + +struct n64_objective { + u32 unk00; + s32 index; + u32 text; + u16 unk0c; + u8 flags; + s8 difficulties; +}; + +struct n64_stdobjective { + u32 cmd; +}; + +struct n64_objectivecmd { + u8 cmd0[4]; + u32 cmd1; +}; + +struct n64_briefingobj { + u32 unk00; + u32 type; + u32 text; + u32 ptr_next; +}; + +struct n64_padlockeddoorobj { + u32 unk00; + u32 ptr_door; + u32 ptr_lock; + u32 ptr_next; +}; + +struct n64_truckobj { + struct n64_defaultobj base; + u32 ptr_ailist; + u16 aioffset; + s16 aireturnlist; + f32 speed; + f32 wheelxrot; + f32 wheelyrot; + f32 speedaim; + f32 speedtime60; + f32 turnrot60; + f32 roty; + u32 ptr_path; + s32 nextstep; +}; + +struct n64_tankobj { + u8 _pad_[128]; +}; + +struct n64_heliobj { + struct n64_defaultobj base; + u32 ptr_ailist; + u16 aioffset; + s16 aireturnlist; + f32 rotoryrot; + f32 rotoryspeed; + f32 rotoryspeedaim; + f32 rotoryspeedtime; + f32 speed; + f32 speedaim; + f32 speedtime60; + f32 yrot; + u32 ptr_path; + s32 nextstep; +}; + +struct n64_glassobj { + struct n64_defaultobj base; + s16 portalnum; + s16 _pad_; +}; + +struct n64_safeobj { + struct n64_defaultobj base; +}; + +struct n64_safeitemobj { + u32 unk00; + u32 ptr_item; + u32 ptr_safe; + u32 ptr_door; + u32 ptr_next; +}; + +struct n64_cameraposobj { + s32 type; + f32 x; + f32 y; + f32 z; + f32 theta; + f32 verta; + s32 pad; +}; + +struct n64_tintedglassobj { + struct n64_defaultobj base; + s16 xludist; + s16 opadist; + s16 opacity; + s16 portalnum; + f32 unk64; +}; + +struct n64_liftobj { + struct n64_defaultobj base; + s16 pads[4]; + u32 ptr_doors[4]; + f32 dist; + f32 speed; + f32 accel; + f32 maxspeed; + s8 soundtype; + s8 levelcur; + s8 levelaim; + s8 _pad_; + struct n64_coord prevpos; +}; + +struct n64_linksceneryobj { + u32 unk00; + u32 ptr_trigger; + u32 ptr_unexp; + u32 ptr_exp; + u32 ptr_next; +}; + +struct n64_blockedpathobj { + u32 unk00; + u32 ptr_blocker; + s16 waypoint1; + s16 waypoint2; + u32 ptr_next; +}; + +struct n64_hov { + u8 type; + u8 flags; + s16 _pad_; + f32 bobycur; + f32 bobytarget; + f32 bobyspeed; + f32 yrot; + f32 bobpitchcur; + f32 bobpitchtarget; + f32 bobpitchspeed; + f32 bobrollcur; + f32 bobrolltarget; + f32 bobrollspeed; + f32 groundpitch; + f32 y; + f32 ground; + s32 prevframe60; + s32 prevgroundframe60; +}; + +struct n64_hoverbikeobj { + struct n64_defaultobj base; + struct n64_hov hov; + f32 speed[2]; + f32 prevpos[2]; + f32 w; + f32 rels[2]; + f32 exreal; + f32 ezreal; + f32 ezreal2; + f32 leanspeed; + f32 leandiff; + s32 maxspeedtime240; + f32 speedabs[2]; + f32 speedrel[2]; +}; + +struct n64_hoverpropobj { + struct n64_defaultobj base; + struct n64_hov hov; +}; + +struct n64_fanobj { + struct n64_defaultobj base; + f32 yrot; + f32 yrotprev; + f32 ymaxspeed; + f32 yspeed; + f32 yaccel; + s8 on; + u8 _pad_[3]; +}; + +struct n64_hovercarobj { + struct n64_defaultobj base; + u32 ptr_ailist; + u16 aioffset; + s16 aireturnlist; + f32 speed; + f32 speedaim; + f32 speedtime60; + f32 turnyspeed60; + f32 turnxspeed60; + f32 turnrot60; + f32 roty; + f32 rotx; + f32 rotz; + u32 ptr_path; + s32 nextstep; + s16 status; + s16 dead; + s16 deadtimer60; + s16 sparkstimer60; +}; + +struct n64_chopperobj { + struct n64_defaultobj base; + u32 ptr_ailist; + u16 aioffset; + s16 aireturnlist; + union { + struct { + f32 speed; + f32 speedaim; + f32 speedtime60; + }; + struct n64_coord fall; + }; + f32 turnyspeed60; + f32 turnxspeed60; + f32 turnrot60; + f32 roty; + f32 rotx; + f32 rotz; + u32 ptr_path; + s32 nextstep;// + s16 weaponsarmed; + s16 ontarget; + s16 target; + u8 attackmode; + u8 cw; + f32 vx; + f32 vy; + f32 vz; + f32 power; + f32 otx; + f32 oty; + f32 otz; + f32 bob; + f32 bobstrength; + s32 targetvisible; + s32 timer60; + s32 patroltimer60; + f32 gunturnyspeed60; + f32 gunturnxspeed60; + f32 gunroty; + f32 gunrotx; + f32 barrelrotspeed; + f32 barrelrot; + u32 ptr_fireslotthing; + s32 dead; +}; + +struct n64_escalatorobj { + struct n64_defaultobj base; + s32 frame; + struct n64_coord prevpos; +}; + +struct n64_textoverride { + u32 unk00; + s32 objoffset; + s32 weapon; + u32 obtaintext; + u32 ownertext; + u32 inventorytext; + u32 inventory2text; + u32 pickuptext; + u32 ptr_next; + u32 ptr_obj; +}; + +struct n64_criteria_roomentered { + u32 unk00; + u32 pad; + u32 status; + u32 ptr_next; +}; + +struct n64_criteria_throwinroom { + u32 unk00; + u32 unk04; + u32 pad; + u32 status; + u32 ptr_next; +}; + +struct n64_criteria_holograph { + u32 unk00; + u32 obj; + u32 status; + u32 ptr_next; +}; + +struct n64_ailist { + u32 ptr_list; + s32 id; +}; + +struct n64_path { + u32 ptr_pads; + u8 id; + u8 flags; + u16 len; +}; + +#endif diff --git a/port/include/romdata.h b/port/include/romdata.h index a1c23921e..07142f5d2 100644 --- a/port/include/romdata.h +++ b/port/include/romdata.h @@ -10,7 +10,7 @@ extern const char *g_RomName; s32 romdataInit(void); u8 *romdataFileLoad(s32 fileNum, u32 *outSize); -void romdataFilePreprocess(s32 fileNum, s32 loadType, u8 *data, u32 size); +void romdataFilePreprocess(s32 fileNum, s32 loadType, u8 *data, u32 size, u32 *outSize); void romdataFileFree(s32 fileNum); const char *romdataFileGetName(s32 fileNum); @@ -22,6 +22,7 @@ s32 romdataFileGetNumForName(const char *name); u8 *romdataSegGetData(const char *segName); u8 *romdataSegGetDataEnd(const char *segName); u32 romdataSegGetSize(const char *segName); +u32 romdataFileGetEstimatedSize(const u32 size, const u32 loadtype); s32 romdataCheckGbcRom(void); diff --git a/port/include/system.h b/port/include/system.h index be3216280..b1b9ce910 100644 --- a/port/include/system.h +++ b/port/include/system.h @@ -37,6 +37,7 @@ void sysGetHomePath(char *outPath, const u32 outLen); void *sysMemAlloc(const u32 size); void *sysMemZeroAlloc(const u32 size); +void *sysMemRealloc(void *ptr, const u32 newSize); void sysMemFree(void *ptr); // hns is specified in 100ns units diff --git a/port/src/libultra.c b/port/src/libultra.c index 74edd9782..708f97bd5 100644 --- a/port/src/libultra.c +++ b/port/src/libultra.c @@ -433,7 +433,7 @@ void osInvalDCache(void *a, s32 b) } -s32 osPiStartDma(OSIoMesg *mb, s32 priority, s32 direction, uintptr_t devAddr, void *vAddr, size_t nbytes, OSMesgQueue *mq) +s32 osPiStartDma(OSIoMesg *mb, s32 priority, s32 direction, uintptr_t devAddr, void *vAddr, u32 nbytes, OSMesgQueue *mq) { memcpy(vAddr, (const void *)devAddr, nbytes); return 0; diff --git a/port/src/pdmain.c b/port/src/pdmain.c index 3d038fc40..f6581551f 100644 --- a/port/src/pdmain.c +++ b/port/src/pdmain.c @@ -579,7 +579,7 @@ void mainTick(void) viUpdateMode(); } - rdpCreateTask(gdlstart, gdl, 0, (s32) &msg); + rdpCreateTask(gdlstart, gdl, 0, (uintptr_t) &msg); memaPrint(); profileSetMarker(PROFILE_MAINTICK_END); } diff --git a/port/src/preprocess.c b/port/src/preprocess.c deleted file mode 100644 index 16145ee40..000000000 --- a/port/src/preprocess.c +++ /dev/null @@ -1,1636 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "platform.h" -#include "data.h" -#include "bss.h" -#include "game/setuputils.h" -#include "game/texdecompress.h" -#include "preprocess.h" -#include "romdata.h" -#include "mod.h" -#include "system.h" - -static inline f32 swapF32(f32 x) { *(u32 *)&x = PD_BE32(*(u32 *)&x); return x; } -static inline u32 swapU32(u32 x) { return PD_BE32(x); } -static inline s32 swapS32(s32 x) { return PD_BE32(x); } -static inline u16 swapU16(u16 x) { return PD_BE16(x); } -static inline s16 swapS16(s16 x) { return PD_BE16(x); } -static inline void *swapPtr(void **x) { return (void *)PD_BEPTR((uintptr_t)x); } -static inline struct coord swapCrd(struct coord crd) { crd.x = swapF32(crd.x); crd.y = swapF32(crd.y); crd.z = swapF32(crd.z); return crd; } -static inline u32 swapUnk(u32 x) { assert(0 && "unknown type"); return x; } - -#define PD_SWAP_VAL(x) x = _Generic((x), \ - f32: swapF32, \ - u32: swapU32, \ - s32: swapS32, \ - u16: swapU16, \ - s16: swapS16, \ - struct coord: swapCrd, \ - default: swapUnk \ -)(x) - -#define PD_SWAP_PTR(x) x = swapPtr((void *)(x)) - -#define PD_PTR_BASE(x, b) (void *)((u8 *)b + (u32)x) -#define PD_PTR_BASEOFS(x, b, d) (void *)((u8 *)b - d + (u32)x) - -// HACK: to prevent double-swapping stuff, flag swapped offsets in a bitmap - -static u8 swapmap[0x40000 >> 3]; - -static inline u32 alreadySwapped(const intptr_t addr) { - const u32 mask = (1 << (addr & 7)); - const u32 old = swapmap[addr >> 3] & mask; - if (!old) { - swapmap[addr >> 3] |= mask; - } - return old; -} - -static inline void preprocessALWaveTable(ALWaveTable *tbl, u8 *bankBase) -{ - if (alreadySwapped((u8 *)tbl - bankBase)) { - return; - } - - PD_SWAP_VAL(tbl->len); - PD_SWAP_PTR(tbl->base); - - if (tbl->type == AL_ADPCM_WAVE) { - if (tbl->waveInfo.adpcmWave.loop ) { - PD_SWAP_PTR(tbl->waveInfo.adpcmWave.loop); - ALADPCMloop *loop = PD_PTR_BASE(tbl->waveInfo.adpcmWave.loop, bankBase); - PD_SWAP_VAL(loop->count); - PD_SWAP_VAL(loop->start); - PD_SWAP_VAL(loop->end); - for (s32 i = 0; i < 16; ++i) { - PD_SWAP_VAL(loop->state[i]); - } - } - if (tbl->waveInfo.adpcmWave.book) { - PD_SWAP_PTR(tbl->waveInfo.adpcmWave.book); - ALADPCMBook *book = PD_PTR_BASE(tbl->waveInfo.adpcmWave.book, bankBase); - PD_SWAP_VAL(book->npredictors); - PD_SWAP_VAL(book->order); - const s32 bookSize = book->order * book->npredictors * ADPCMVSIZE; - for (s32 i = 0; i < bookSize && i < 128; ++i) { - PD_SWAP_VAL(book->book[i]); - } - } - } else if (tbl->type == AL_RAW16_WAVE) { - if (tbl->waveInfo.rawWave.loop) { - PD_SWAP_PTR(tbl->waveInfo.rawWave.loop); - ALRawLoop *loop = PD_PTR_BASE(tbl->waveInfo.rawWave.loop, bankBase); - PD_SWAP_VAL(loop->count); - PD_SWAP_VAL(loop->start); - PD_SWAP_VAL(loop->end); - } - } -} - -static inline void preprocessALSound(ALSound *snd, u8 *bankBase) -{ - if (alreadySwapped((u8 *)snd - bankBase)) { - return; - } - - if (snd->envelope) { - PD_SWAP_PTR(snd->envelope); - if (!alreadySwapped((intptr_t)snd->envelope)) { - ALEnvelope *env = PD_PTR_BASE(snd->envelope, bankBase); - PD_SWAP_VAL(env->attackTime); - PD_SWAP_VAL(env->releaseTime); - PD_SWAP_VAL(env->decayTime); - } - } - - if (snd->keyMap) { - PD_SWAP_PTR(snd->keyMap); - } - - if (snd->wavetable) { - PD_SWAP_PTR(snd->wavetable); - preprocessALWaveTable(PD_PTR_BASE(snd->wavetable, bankBase), bankBase); - } -} - -static inline void preprocessALInstrument(ALInstrument *inst, u8 *bankBase) -{ - if (alreadySwapped((u8 *)inst - bankBase)) { - return; - } - - PD_SWAP_VAL(inst->bendRange); - PD_SWAP_VAL(inst->soundCount); - - for (s16 i = 0; i < inst->soundCount; ++i) { - PD_SWAP_PTR(inst->soundArray[i]); - preprocessALSound(PD_PTR_BASE(inst->soundArray[i], bankBase), bankBase); - } -} - -static inline void preprocessALBank(ALBank *bank, u8 *bankBase) -{ - if (alreadySwapped((u8 *)bank - bankBase)) { - return; - } - - PD_SWAP_VAL(bank->sampleRate); - PD_SWAP_VAL(bank->instCount); - - if (bank->percussion) { - PD_SWAP_PTR(bank->percussion); - preprocessALInstrument(PD_PTR_BASE(bank->percussion, bankBase), bankBase); - } - - for (s16 i = 0; i < bank->instCount; ++i) { - PD_SWAP_PTR(bank->instArray[i]); - preprocessALInstrument(PD_PTR_BASE(bank->instArray[i], bankBase), bankBase); - } -} - -static inline void preprocessGfx(Gfx *gdl, u8 *base, uintptr_t ofs) -{ - while (gdl) { - const s8 opcode = (s8)gdl->bytes[0]; - PD_SWAP_VAL(gdl->words.w0); - PD_SWAP_VAL(gdl->words.w1); - if (opcode == (s8)G_ENDDL) { - break; - } - - // mark all addresses in the DL as segmented - switch (opcode) { - case (s8)G_SETTIMG: - case (s8)G_SETCIMG: - case (s8)G_SETZIMG: - case G_MOVEMEM: - case G_MTX: - case G_VTX: - case G_COL: - case G_DL: - gdl->words.w1 |= 1; - break; - default: - break; - } - - ++gdl; - } -} - -static inline void preprocessVtx(Vtx *vtx) -{ - PD_SWAP_VAL(vtx->x); - PD_SWAP_VAL(vtx->y); - PD_SWAP_VAL(vtx->z); - PD_SWAP_VAL(vtx->s); - PD_SWAP_VAL(vtx->t); -} - -static u8 *preprocessModelGunDL(struct modelrodata_gundl *gundl, u8 *base, u32 ofs) -{ - PD_SWAP_PTR(gundl->baseaddr); - PD_SWAP_PTR(gundl->vertices); - PD_SWAP_VAL(gundl->numvertices); - PD_SWAP_VAL(gundl->unk12); - - Vtx *vtx = PD_PTR_BASEOFS(gundl->vertices, base, ofs); - for (s16 i = 0; i < gundl->numvertices; ++i, ++vtx) { - preprocessVtx(vtx); - } - - if (gundl->opagdl) { - PD_SWAP_PTR(gundl->opagdl); - preprocessGfx(PD_PTR_BASEOFS(gundl->opagdl, base, ofs), base, ofs); - gundl->opagdl = SEGADDR(gundl->opagdl); - } - - if (gundl->xlugdl) { - PD_SWAP_PTR(gundl->xlugdl); - preprocessGfx(PD_PTR_BASEOFS(gundl->xlugdl, base, ofs), base, ofs); - gundl->xlugdl = SEGADDR(gundl->xlugdl); - } - - u8 *lowptr = (u8 *)gundl->vertices; - if (gundl->opagdl && (u8 *)gundl->opagdl < lowptr) { - lowptr = (u8 *)gundl->opagdl; - } - if (gundl->xlugdl && (u8 *)gundl->xlugdl < lowptr) { - lowptr = (u8 *)gundl->xlugdl; - } - - return lowptr; -} - -static u8 *preprocessModelDL(struct modelrodata_dl *dl, u8 *base, u32 ofs) -{ - PD_SWAP_PTR(dl->colours); - PD_SWAP_PTR(dl->vertices); - - PD_SWAP_VAL(dl->numvertices); - PD_SWAP_VAL(dl->numcolours); - PD_SWAP_VAL(dl->mcount); - PD_SWAP_VAL(dl->rwdataindex); - - Vtx *vtx = PD_PTR_BASEOFS(dl->vertices, base, ofs); - for (s16 i = 0; i < dl->numvertices; ++i, ++vtx) { - preprocessVtx(vtx); - } - - if (dl->opagdl) { - PD_SWAP_PTR(dl->opagdl); - preprocessGfx(PD_PTR_BASEOFS(dl->opagdl, base, ofs), base, ofs); - dl->opagdl = SEGADDR(dl->opagdl); - } - - if (dl->xlugdl) { - PD_SWAP_PTR(dl->xlugdl); - preprocessGfx(PD_PTR_BASEOFS(dl->xlugdl, base, ofs), base, ofs); - dl->xlugdl = SEGADDR(dl->xlugdl); - } - - u8 *lowptr = (u8 *)dl->vertices; - if (dl->colours && (u8 *)dl->colours < lowptr) { - lowptr = (u8 *)dl->colours; - } - if (dl->opagdl && (u8 *)dl->opagdl < lowptr) { - lowptr = (u8 *)dl->opagdl; - } - if (dl->xlugdl && (u8 *)dl->xlugdl < lowptr) { - lowptr = (u8 *)dl->xlugdl; - } - - return lowptr; -} - -// returns the pointer to the start of the non-texture graphics data (verts, gdls, etc) -static u8 *preprocessModelNode(struct modelnode *node, u8 *base, u32 ofs) -{ - u8 *lowptr = NULL; - u8 *tmp = NULL; - - while (node) { - PD_SWAP_VAL(node->type); - PD_SWAP_PTR(node->child); - PD_SWAP_PTR(node->next); - PD_SWAP_PTR(node->parent); - PD_SWAP_PTR(node->rodata); - - if (node->rodata) { - union modelrodata* ro = PD_PTR_BASEOFS(node->rodata, base, ofs); - if (!lowptr || ((u8 *)node->rodata < lowptr)) { - lowptr = (u8 *)node->rodata; - } - - switch (node->type & 0xff) { - case MODELNODETYPE_CHRINFO: - PD_SWAP_VAL(ro->chrinfo.animpart); - PD_SWAP_VAL(ro->chrinfo.mtxindex); - PD_SWAP_VAL(ro->chrinfo.rwdataindex); - PD_SWAP_VAL(ro->chrinfo.unk04); - break; - case MODELNODETYPE_POSITION: - PD_SWAP_VAL(ro->position.drawdist); - PD_SWAP_VAL(ro->position.pos); - PD_SWAP_VAL(ro->position.part); - PD_SWAP_VAL(ro->position.mtxindex0); - PD_SWAP_VAL(ro->position.mtxindex1); - PD_SWAP_VAL(ro->position.mtxindex2); - break; - case MODELNODETYPE_GUNDL: - tmp = preprocessModelGunDL(&ro->gundl, base, ofs); - if (tmp && (!lowptr || tmp < lowptr)) { - lowptr = tmp; - } - break; - case MODELNODETYPE_05: - break; - case MODELNODETYPE_DISTANCE: - PD_SWAP_VAL(ro->distance.near); - PD_SWAP_VAL(ro->distance.far); - PD_SWAP_VAL(ro->distance.rwdataindex); - PD_SWAP_PTR(ro->distance.target); - // TODO: assuming target points to one of the nodes we'll swap by following node->next - break; - case MODELNODETYPE_REORDER: - PD_SWAP_VAL(ro->reorder.unk00); - PD_SWAP_VAL(ro->reorder.unk04); - PD_SWAP_VAL(ro->reorder.unk08); - PD_SWAP_VAL(ro->reorder.unk0c[0]); - PD_SWAP_VAL(ro->reorder.unk0c[1]); - PD_SWAP_VAL(ro->reorder.unk0c[2]); - PD_SWAP_VAL(ro->reorder.rwdataindex); - PD_SWAP_VAL(ro->reorder.side); - PD_SWAP_PTR(ro->reorder.unk18); - PD_SWAP_PTR(ro->reorder.unk1c); - break; - case MODELNODETYPE_BBOX: - PD_SWAP_VAL(ro->bbox.xmin); - PD_SWAP_VAL(ro->bbox.xmax); - PD_SWAP_VAL(ro->bbox.ymin); - PD_SWAP_VAL(ro->bbox.ymax); - PD_SWAP_VAL(ro->bbox.zmin); - PD_SWAP_VAL(ro->bbox.zmax); - PD_SWAP_VAL(ro->bbox.hitpart); - break; - case MODELNODETYPE_0B: - PD_SWAP_PTR(ro->type0b.baseaddr); - PD_SWAP_VAL(ro->type0b.rwdataindex); - PD_SWAP_VAL(ro->type0b.unk00); - PD_SWAP_PTR(ro->type0b.unk3c); - // TODO: do we need to swap the rest of the words? - break; - case MODELNODETYPE_CHRGUNFIRE: - PD_SWAP_PTR(ro->chrgunfire.baseaddr); - PD_SWAP_PTR(ro->chrgunfire.texture); - PD_SWAP_VAL(ro->chrgunfire.rwdataindex); - PD_SWAP_VAL(ro->chrgunfire.pos); - PD_SWAP_VAL(ro->chrgunfire.dim); - PD_SWAP_VAL(ro->chrgunfire.unk1c); - // TODO: do we swap contents of *texture or is it part of mdl->textureconfigs[]? - break; - case MODELNODETYPE_0D: - PD_SWAP_PTR(ro->type0d.baseaddr); - PD_SWAP_PTR(ro->type0d.unk10); - PD_SWAP_PTR(ro->type0d.unk14); - // TODO: do we need to swap the rest of the words? - break; - case MODELNODETYPE_0E: - case MODELNODETYPE_0F: - break; - case MODELNODETYPE_11: - PD_SWAP_PTR(ro->type11.unk14); - // TODO: do we need to swap the rest of the words? - break; - case MODELNODETYPE_TOGGLE: - PD_SWAP_VAL(ro->toggle.rwdataindex); - PD_SWAP_PTR(ro->toggle.target); - // TODO: assuming target points to one of the nodes we'll swap by following node->next - break; - case MODELNODETYPE_POSITIONHELD: - PD_SWAP_VAL(ro->positionheld.mtxindex); - PD_SWAP_VAL(ro->positionheld.pos); - break; - case MODELNODETYPE_STARGUNFIRE: - PD_SWAP_VAL(ro->stargunfire.unk00); - PD_SWAP_PTR(ro->stargunfire.baseaddr); - if (ro->stargunfire.gdl) { - PD_SWAP_PTR(ro->stargunfire.gdl); - preprocessGfx(PD_PTR_BASEOFS(ro->stargunfire.gdl, base, ofs), base, ofs); - ro->stargunfire.gdl = SEGADDR(ro->stargunfire.gdl); - if (!lowptr || (u8 *)ro->stargunfire.gdl < lowptr) { - lowptr = (u8 *)ro->stargunfire.gdl; - } - } - if (ro->stargunfire.vertices) { - PD_SWAP_PTR(ro->stargunfire.vertices); - Vtx *vtx = PD_PTR_BASEOFS(ro->stargunfire.vertices, base, ofs); - for (s32 i = 0; i < 4 * ro->stargunfire.unk00; ++i, ++vtx) { - preprocessVtx(vtx); - } - if (!lowptr || (u8 *)ro->stargunfire.vertices < lowptr) { - lowptr = (u8 *)ro->stargunfire.vertices; - } - } - break; - case MODELNODETYPE_HEADSPOT: - PD_SWAP_VAL(ro->headspot.rwdataindex); - break; - case MODELNODETYPE_DL: - tmp = preprocessModelDL(&ro->dl, base, ofs); - if (tmp && (!lowptr || tmp < lowptr)) { - lowptr = tmp; - } - break; - case 0x19: - PD_SWAP_VAL(ro->type19.numvertices); - for (s32 i = 0; i < ARRAYCOUNT(ro->type19.vertices); ++i) { - PD_SWAP_VAL(ro->type19.vertices[i]); - } - break; - default: - sysLogPrintf(LOG_ERROR, "preprocessModelNode: node at %p: unknown node->type: 0x%02x", node, node->type & 0xff); - break; - } - } - - if (node->child) { - node = PD_PTR_BASEOFS(node->child, base, ofs); - } else { - while (node) { - if (node->next) { - node = PD_PTR_BASEOFS(node->next, base, ofs); - break; - } - if (node->parent) { - node = PD_PTR_BASEOFS(node->parent, base, ofs); - } else { - node = NULL; - } - } - } - } - - return (u8 *)UNSEGADDR(lowptr); -} - -static inline void preprocessPadData(u8 *ptr, u32 size) -{ - // we'll try to avoid overwriting the next pad if possible in case the flags are wrong - u8 *end = ptr + size; - - // for some insane reason pads are packed - // header is always 1 word, the rest of the fields depends on the flags - u32 *header = (u32 *) ptr; - PD_SWAP_VAL(header[0]); - - const u32 flags = header[0] >> 14; - - ptr += 4; - - if ((flags & PADFLAG_INTPOS) || size <= 12) { - // position is 3x s16 - s16 *sbuffer = (s16 *) ptr; - PD_SWAP_VAL(sbuffer[0]); - PD_SWAP_VAL(sbuffer[1]); - PD_SWAP_VAL(sbuffer[2]); - ptr += 8; - } else if (size > 12) { - // position is 3x f32 - f32 *fbuffer = (f32 *) ptr; - PD_SWAP_VAL(fbuffer[0]); - PD_SWAP_VAL(fbuffer[1]); - PD_SWAP_VAL(fbuffer[2]); - ptr += 12; - } - - if (!(flags & (PADFLAG_UPALIGNTOX | PADFLAG_UPALIGNTOY | PADFLAG_UPALIGNTOZ)) && (end >= ptr + 12)) { - // up vector, 3x f32 - f32 *fbuffer = (f32 *) ptr; - PD_SWAP_VAL(fbuffer[0]); - PD_SWAP_VAL(fbuffer[1]); - PD_SWAP_VAL(fbuffer[2]); - ptr += 12; - } - - if (!(flags & (PADFLAG_LOOKALIGNTOX | PADFLAG_LOOKALIGNTOY | PADFLAG_LOOKALIGNTOZ)) && (end >= ptr + 12)) { - // look vector, 3x f32 - f32 *fbuffer = (f32 *) ptr; - PD_SWAP_VAL(fbuffer[0]); - PD_SWAP_VAL(fbuffer[1]); - PD_SWAP_VAL(fbuffer[2]); - ptr += 12; - } - - if ((flags & PADFLAG_HASBBOXDATA) && (end >= ptr + 24)) { - // bbox, 3x f32 mins + 3x f32 maxs - f32 *fbuffer = (f32 *) ptr; - PD_SWAP_VAL(fbuffer[0]); - PD_SWAP_VAL(fbuffer[1]); - PD_SWAP_VAL(fbuffer[2]); - PD_SWAP_VAL(fbuffer[3]); - PD_SWAP_VAL(fbuffer[4]); - PD_SWAP_VAL(fbuffer[5]); - } -} - -static inline void preprocessDefaultPropObj(struct defaultobj *obj) -{ - PD_SWAP_PTR(obj->projectile); - PD_SWAP_PTR(obj->geoblock); - PD_SWAP_PTR(obj->prop); - PD_SWAP_PTR(obj->model); - PD_SWAP_VAL(obj->flags); - PD_SWAP_VAL(obj->flags2); - PD_SWAP_VAL(obj->flags3); - PD_SWAP_VAL(obj->hidden); - PD_SWAP_VAL(obj->damage); - PD_SWAP_VAL(obj->maxdamage); - PD_SWAP_VAL(obj->extrascale); - PD_SWAP_VAL(obj->floorcol); - PD_SWAP_VAL(obj->modelnum); - PD_SWAP_VAL(obj->pad); - for (s32 i = 0; i < 3; ++i) { - for (s32 j = 0; j < 3; ++j) { - PD_SWAP_VAL(obj->realrot[i][j]); - } - } -} - -static inline void preprocessDefaultPropObjHdr(struct defaultobj *obj) -{ - // don't touch the other fields - PD_SWAP_VAL(obj->extrascale); -} - -static inline void preprocessTvScreenPropObj(struct tvscreen *scr) -{ - PD_SWAP_PTR(scr->cmdlist); - PD_SWAP_PTR(scr->tconfig); - PD_SWAP_VAL(scr->offset); - PD_SWAP_VAL(scr->pause60); - PD_SWAP_VAL(scr->rot); - PD_SWAP_VAL(scr->xscale); - PD_SWAP_VAL(scr->xscalefrac); - PD_SWAP_VAL(scr->xscaleinc); - PD_SWAP_VAL(scr->xscaleold); - PD_SWAP_VAL(scr->xscalenew); - PD_SWAP_VAL(scr->yscale); - PD_SWAP_VAL(scr->yscalefrac); - PD_SWAP_VAL(scr->yscaleinc); - PD_SWAP_VAL(scr->yscaleold); - PD_SWAP_VAL(scr->yscalenew); - PD_SWAP_VAL(scr->xmid); - PD_SWAP_VAL(scr->xmidfrac); - PD_SWAP_VAL(scr->xmidinc); - PD_SWAP_VAL(scr->xmidold); - PD_SWAP_VAL(scr->xmidnew); - PD_SWAP_VAL(scr->ymid); - PD_SWAP_VAL(scr->ymidfrac); - PD_SWAP_VAL(scr->ymidinc); - PD_SWAP_VAL(scr->ymidold); - PD_SWAP_VAL(scr->ymidnew); - PD_SWAP_VAL(scr->colfrac); - PD_SWAP_VAL(scr->colinc); -} - -static inline void preprocessHovPropObj(struct hov *hov) -{ - // don't think anything actually has to be swapped here -} - -static void preprocessPropObj(struct defaultobj *obj) -{ - // TODO: help me jesus - switch (obj->type) { - case OBJTYPE_GRENADEPROB: { - struct grenadeprobobj *grenadeprob = (struct grenadeprobobj *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_VAL(grenadeprob->chrnum); - PD_SWAP_VAL(grenadeprob->probability); - break; - } - case OBJTYPE_CHR: { - struct packedchr *chr = (struct packedchr *)obj; - PD_SWAP_VAL(chr->chrindex); - PD_SWAP_VAL(chr->spawnflags); - PD_SWAP_VAL(chr->chrnum); - PD_SWAP_VAL(chr->padnum); - PD_SWAP_VAL(chr->ailistnum); - PD_SWAP_VAL(chr->padpreset); - PD_SWAP_VAL(chr->chrpreset); - PD_SWAP_VAL(chr->hearscale); - PD_SWAP_VAL(chr->viewdist); - PD_SWAP_VAL(chr->flags); - PD_SWAP_VAL(chr->flags2); - PD_SWAP_VAL(chr->chair); - PD_SWAP_VAL(chr->convtalk); - break; - } - case OBJTYPE_DOOR: { - struct doorobj *door = (struct doorobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_PTR(door->sibling); - PD_SWAP_VAL(door->maxfrac); - PD_SWAP_VAL(door->perimfrac); - PD_SWAP_VAL(door->accel); - PD_SWAP_VAL(door->decel); - PD_SWAP_VAL(door->maxspeed); - PD_SWAP_VAL(door->frac); - PD_SWAP_VAL(door->fracspeed); - PD_SWAP_VAL(door->startpos); - PD_SWAP_VAL(door->keyflags); - PD_SWAP_VAL(door->autoclosetime); - PD_SWAP_VAL(door->doorflags); - PD_SWAP_VAL(door->doortype); - PD_SWAP_VAL(door->fadealpha); - PD_SWAP_VAL(door->xludist); - PD_SWAP_VAL(door->opadist); - break; - } - case OBJTYPE_DOORSCALE: { - struct doorscaleobj *doorsc = (struct doorscaleobj *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_VAL(doorsc->scale); - break; - } - case OBJTYPE_WEAPON: { - struct weaponobj *wpn = (struct weaponobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_PTR(wpn->dualweapon); - PD_SWAP_VAL(wpn->team); - break; - } - case OBJTYPE_KEY: { - struct keyobj *key = (struct keyobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_VAL(key->keyflags); - break; - } - case OBJTYPE_CCTV: { - struct cctvobj *cctv = (struct cctvobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_VAL(cctv->yzero); - PD_SWAP_VAL(cctv->yrot); - PD_SWAP_VAL(cctv->yleft); - PD_SWAP_VAL(cctv->yright); - PD_SWAP_VAL(cctv->yspeed); - PD_SWAP_VAL(cctv->ymaxspeed); - PD_SWAP_VAL(cctv->maxdist); - PD_SWAP_VAL(cctv->xzero); - PD_SWAP_VAL(cctv->seebondtime60); - PD_SWAP_VAL(cctv->lookatpadnum); - PD_SWAP_VAL(cctv->toleft); - break; - } - case OBJTYPE_AUTOGUN: { - struct autogunobj *agun = (struct autogunobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_VAL(agun->targetpad); - PD_SWAP_VAL(agun->yzero); - PD_SWAP_VAL(agun->ymaxleft); - PD_SWAP_VAL(agun->ymaxright); - PD_SWAP_VAL(agun->yrot); - PD_SWAP_VAL(agun->yspeed); - PD_SWAP_VAL(agun->xzero); - PD_SWAP_VAL(agun->xrot); - PD_SWAP_VAL(agun->xspeed); - PD_SWAP_VAL(agun->maxspeed); - PD_SWAP_VAL(agun->aimdist); - PD_SWAP_VAL(agun->barrelspeed); - PD_SWAP_VAL(agun->barrelrot); - PD_SWAP_VAL(agun->allowsoundframe); - PD_SWAP_PTR(agun->target); - break; - } - case OBJTYPE_SINGLEMONITOR: { - struct singlemonitorobj *mon = (struct singlemonitorobj *)obj; - preprocessDefaultPropObj(obj); - preprocessTvScreenPropObj((struct tvscreen *)&mon->screen); - PD_SWAP_VAL(mon->owneroffset); - break; - } - case OBJTYPE_MULTIMONITOR: { - struct multimonitorobj *mmon = (struct multimonitorobj *)obj; - preprocessDefaultPropObj(obj); - preprocessTvScreenPropObj((struct tvscreen *)&mmon->screens[0]); - preprocessTvScreenPropObj((struct tvscreen *)&mmon->screens[1]); - preprocessTvScreenPropObj((struct tvscreen *)&mmon->screens[2]); - preprocessTvScreenPropObj((struct tvscreen *)&mmon->screens[3]); - break; - } - case OBJTYPE_SHIELD: { - struct shieldobj *shld = (struct shieldobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_VAL(shld->initialamount); - PD_SWAP_VAL(shld->amount); - break; - } - case OBJTYPE_TINTEDGLASS: { - struct tintedglassobj *tgls = (struct tintedglassobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_VAL(tgls->xludist); - PD_SWAP_VAL(tgls->opadist); - PD_SWAP_VAL(tgls->opacity); - PD_SWAP_VAL(tgls->portalnum); - PD_SWAP_VAL(tgls->unk64); - break; - } - case OBJTYPE_LIFT: { - struct liftobj *lift = (struct liftobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_PTR(lift->doors[0]); - PD_SWAP_PTR(lift->doors[1]); - PD_SWAP_PTR(lift->doors[2]); - PD_SWAP_PTR(lift->doors[3]); - PD_SWAP_VAL(lift->pads[0]); - PD_SWAP_VAL(lift->pads[1]); - PD_SWAP_VAL(lift->pads[2]); - PD_SWAP_VAL(lift->pads[3]); - PD_SWAP_VAL(lift->dist); - PD_SWAP_VAL(lift->speed); - PD_SWAP_VAL(lift->accel); - PD_SWAP_VAL(lift->maxspeed); - break; - } - case OBJTYPE_HOVERPROP: { - struct hoverpropobj *hprop = (struct hoverpropobj *)obj; - preprocessDefaultPropObj(obj); - preprocessHovPropObj(&hprop->hov); - break; - } - case OBJTYPE_HOVERBIKE: { - struct hoverbikeobj *hbike = (struct hoverbikeobj *)obj; - preprocessDefaultPropObj(obj); - preprocessHovPropObj(&hbike->hov); - break; - } - case OBJTYPE_FAN: { - struct fanobj *fan = (struct fanobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_VAL(fan->yrot); - PD_SWAP_VAL(fan->yrotprev); - PD_SWAP_VAL(fan->ymaxspeed); - PD_SWAP_VAL(fan->yspeed); - PD_SWAP_VAL(fan->yaccel); - break; - } - case OBJTYPE_GLASS: { - struct glassobj *gls = (struct glassobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_VAL(gls->portalnum); - break; - } - case OBJTYPE_AMMOCRATE: { - struct ammocrateobj *ammo = (struct ammocrateobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_VAL(ammo->ammotype); - break; - } - case OBJTYPE_MULTIAMMOCRATE: { - struct multiammocrateobj *mammo = (struct multiammocrateobj *)obj; - preprocessDefaultPropObj(obj); - for (s32 i = 0; i < ARRAYCOUNT(mammo->slots); ++i) { - PD_SWAP_VAL(mammo->slots[i].modelnum); - PD_SWAP_VAL(mammo->slots[i].quantity); - } - break; - } - case OBJTYPE_TRUCK: { - struct truckobj *truck = (struct truckobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_PTR(truck->ailist); - break; - } - case OBJTYPE_HOVERCAR: { - struct hovercarobj *car = (struct hovercarobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_PTR(car->ailist); - break; - } - case OBJTYPE_CHOPPER: { - struct chopperobj *chop = (struct chopperobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_PTR(chop->ailist); - break; - } - case OBJTYPE_HELI: { - struct heliobj *heli = (struct heliobj *)obj; - preprocessDefaultPropObj(obj); - PD_SWAP_PTR(heli->ailist); - break; - } - case OBJTYPE_TAG: { - struct tag *tag = (struct tag *)obj; - PD_SWAP_PTR(tag->next); - PD_SWAP_PTR(tag->obj); - PD_SWAP_VAL(tag->cmdoffset); - PD_SWAP_VAL(tag->tagnum); - break; - } - case OBJTYPE_RENAMEOBJ: { - struct textoverride *over = (struct textoverride *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_PTR(over->next); - PD_SWAP_PTR(over->obj); - PD_SWAP_VAL(over->objoffset); - PD_SWAP_VAL(over->weapon); - PD_SWAP_VAL(over->obtaintext); - PD_SWAP_VAL(over->ownertext); - PD_SWAP_VAL(over->inventorytext); - PD_SWAP_VAL(over->inventory2text); - PD_SWAP_VAL(over->pickuptext); - break; - } - case OBJTYPE_BRIEFING: { - struct briefingobj *brief = (struct briefingobj *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_PTR(brief->next); - PD_SWAP_VAL(brief->type); - PD_SWAP_VAL(brief->text); - break; - } - case OBJTYPE_CAMERAPOS: { - struct cameraposobj *campos = (struct cameraposobj *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_VAL(campos->x); - PD_SWAP_VAL(campos->y); - PD_SWAP_VAL(campos->z); - PD_SWAP_VAL(campos->theta); - PD_SWAP_VAL(campos->verta); - PD_SWAP_VAL(campos->pad); - break; - } - case OBJTYPE_BEGINOBJECTIVE: { - struct objective *objective = (struct objective *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_VAL(objective->index); - PD_SWAP_VAL(objective->text); - PD_SWAP_VAL(objective->unk0c); - break; - } - case OBJTYPE_ENDOBJECTIVE: { - break; - } - case OBJTYPE_PADEFFECT: { - struct padeffectobj *padeff = (struct padeffectobj *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_VAL(padeff->pad); - PD_SWAP_VAL(padeff->effect); - break; - } - case OBJTYPE_LINKGUNS: { - struct linkgunsobj *linkg = (struct linkgunsobj *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_VAL(linkg->offset1); - PD_SWAP_VAL(linkg->offset2); - break; - } - case OBJTYPE_LINKLIFTDOOR: { - struct linkliftdoorobj *linkd = (struct linkliftdoorobj *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_PTR(linkd->door); - PD_SWAP_PTR(linkd->lift); - PD_SWAP_PTR(linkd->next); - PD_SWAP_VAL(linkd->stopnum); - break; - } - case OBJTYPE_SAFEITEM: { - struct safeitemobj *linki = (struct safeitemobj *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_PTR(linki->item); - PD_SWAP_PTR(linki->safe); - PD_SWAP_PTR(linki->door); - PD_SWAP_PTR(linki->next); - break; - } - case OBJTYPE_PADLOCKEDDOOR: { - struct padlockeddoorobj *linkp = (struct padlockeddoorobj *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_PTR(linkp->door); - PD_SWAP_PTR(linkp->lock); - PD_SWAP_PTR(linkp->next); - break; - } - case OBJTYPE_CONDITIONALSCENERY: { - struct linksceneryobj *links = (struct linksceneryobj *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_PTR(links->trigger); - PD_SWAP_PTR(links->unexp); - PD_SWAP_PTR(links->exp); - PD_SWAP_PTR(links->next); - break; - } - case OBJTYPE_BLOCKEDPATH: { - struct blockedpathobj *blkp = (struct blockedpathobj *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_PTR(blkp->blocker); - PD_SWAP_PTR(blkp->next); - PD_SWAP_VAL(blkp->waypoint1); - PD_SWAP_VAL(blkp->waypoint2); - break; - } - case OBJTYPE_MINE: - case OBJTYPE_ESCASTEP: - case OBJTYPE_HANGINGMONITORS: - case OBJTYPE_BASIC: - case OBJTYPE_ALARM: - case OBJTYPE_DEBRIS: - case OBJTYPE_GASBOTTLE: - case OBJTYPE_29: - case OBJTYPE_SAFE: - case OBJTYPE_HAT: { - preprocessDefaultPropObj(obj); - break; - } - case OBJECTIVETYPE_ENTERROOM: { - struct criteria_roomentered *obte = (struct criteria_roomentered *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_PTR(obte->next); - PD_SWAP_VAL(obte->pad); - PD_SWAP_VAL(obte->status); - break; - } - case OBJECTIVETYPE_THROWINROOM: { - struct criteria_throwinroom *obtt = (struct criteria_throwinroom *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_PTR(obtt->next); - PD_SWAP_VAL(obtt->unk04); - PD_SWAP_VAL(obtt->pad); - PD_SWAP_VAL(obtt->status); - break; - } - case OBJECTIVETYPE_HOLOGRAPH: { - struct criteria_holograph *obth = (struct criteria_holograph *)obj; - preprocessDefaultPropObjHdr(obj); - PD_SWAP_PTR(obth->next); - PD_SWAP_VAL(obth->obj); - PD_SWAP_VAL(obth->status); - break; - } - case OBJECTIVETYPE_DESTROYOBJ: - case OBJECTIVETYPE_COMPFLAGS: - case OBJECTIVETYPE_FAILFLAGS: - case OBJECTIVETYPE_COLLECTOBJ: - case OBJECTIVETYPE_THROWOBJ: { - u32 *cmd = (u32 *)obj; - PD_SWAP_VAL(cmd[1]); - break; - } - default: { - sysFatalError("Unknown object type in prop list: %02x\nat %p", obj->type, obj); - break; - } - } -} - -static void preprocessIntroScript(s32 *cmd) -{ - while (cmd[0] != PD_BE32(INTROCMD_END)) { - PD_SWAP_VAL(cmd[0]); - switch (cmd[0]) { - case INTROCMD_HILL: - case INTROCMD_OUTFIT: - case INTROCMD_CREDITOFFSET: - case INTROCMD_4: - PD_SWAP_VAL(cmd[1]); - cmd += 2; - break; - case INTROCMD_SPAWN: - case INTROCMD_CASE: - case INTROCMD_CASERESPAWN: - case INTROCMD_WATCHTIME: - PD_SWAP_VAL(cmd[1]); - PD_SWAP_VAL(cmd[2]); - cmd += 3; - break; - case INTROCMD_AMMO: - case INTROCMD_WEAPON: - PD_SWAP_VAL(cmd[1]); - PD_SWAP_VAL(cmd[2]); - PD_SWAP_VAL(cmd[3]); - cmd += 4; - break; - case INTROCMD_3: - PD_SWAP_VAL(cmd[1]); - PD_SWAP_VAL(cmd[2]); - PD_SWAP_VAL(cmd[3]); - PD_SWAP_VAL(cmd[4]); - PD_SWAP_VAL(cmd[5]); - PD_SWAP_VAL(cmd[6]); - PD_SWAP_VAL(cmd[7]); - cmd += 8; - break; - case INTROCMD_6: - PD_SWAP_VAL(cmd[1]); - PD_SWAP_VAL(cmd[2]); - PD_SWAP_VAL(cmd[3]); - PD_SWAP_VAL(cmd[4]); - PD_SWAP_VAL(cmd[5]); - PD_SWAP_VAL(cmd[6]); - PD_SWAP_VAL(cmd[7]); - PD_SWAP_VAL(cmd[8]); - PD_SWAP_VAL(cmd[9]); - cmd += 10; - break; - default: - cmd += 1; - break; - } - } - PD_SWAP_VAL(cmd[0]); -} - -void preprocessAnimations(u8 *data, u32 size) -{ - // set the anim table pointers as well - extern u8 *_animationsTableRomStart; - extern u8 *_animationsTableRomEnd; - - // the animation table is at the end of the segment - u32 *animtbl = (void *)(data + size - 0x38a0); - _animationsTableRomStart = (u8 *)animtbl; - _animationsTableRomEnd = data + size; - - PD_SWAP_VAL(*animtbl); - const u32 count = *animtbl++; - - struct animtableentry *anim = (struct animtableentry *)animtbl; - for (u32 i = 0; i < count; ++i, ++anim) { - PD_SWAP_VAL(anim->numframes); - PD_SWAP_VAL(anim->bytesperframe); - PD_SWAP_VAL(anim->headerlen); - PD_SWAP_VAL(anim->data); - // if an external replacement exists, replace the table entry and mark the offset - if (modAnimationLoadDescriptor(i, anim) > 0) { - anim->data = 0xffffffff; - } - } -} - -void preprocessMpConfigs(u8 *data, u32 size) -{ - const u32 count = size / sizeof(struct mpconfig); - struct mpconfig *cfg = (struct mpconfig *)data; - for (u32 i = 0; i < count; ++i, ++cfg) { - PD_SWAP_VAL(cfg->setup.options); - PD_SWAP_VAL(cfg->setup.teamscorelimit); - PD_SWAP_VAL(cfg->setup.chrslots); -#if MAX_PLAYERS > 4 - // make space for the extra players - cfg->setup.chrslots = (cfg->setup.chrslots & 0x000f) | ((cfg->setup.chrslots & 0x0ff0) << 4); -#endif - // TODO: are these required or are they always 0? - PD_SWAP_VAL(cfg->setup.fileguid.deviceserial); - PD_SWAP_VAL(cfg->setup.fileguid.fileid); - // convert MPWEAPON_ to take classic weapons and JPN weapons into account - for (s32 j = 0; j < ARRAYCOUNT(cfg->setup.weapons); ++j) { -#if VERSION == VERSION_JPN_FINAL /* TODO: replace with runtime check */ - if (cfg->setup.weapons[j] >= 0x24) { - // weapons after and including the shield need to be shifted - cfg->setup.weapons[j] += (MPWEAPON_SHIELD - MPWEAPON_PP9I); - } - if (cfg->setup.weapons[j] >= 0x19) { - // weapons after the combat knife also need to be shifted up in JPN - cfg->setup.weapons[j]++; - } -#else - // in other versions we only care about the shield and above - if (cfg->setup.weapons[j] >= 0x25) { - cfg->setup.weapons[j] += (MPWEAPON_SHIELD - MPWEAPON_PP9I); - } -#endif - } - } -} - -void preprocessFont(u8 *data, u32 size) -{ - struct font *fnt = (struct font *)data; - - for (s32 i = 0; i < ARRAYCOUNT(fnt->kerning); ++i) { - PD_SWAP_VAL(fnt->kerning[i]); - } - - s32 numchars = 94; - -#if PAL - // PAL has more characters in these fonts - extern u8 *_fonthandelgothicsmSegmentRomStart; - extern u8 *_fonthandelgothicxsSegmentRomStart; - extern u8 *_fonthandelgothicmdSegmentRomStart; - if (data == _fonthandelgothicsmSegmentRomStart - || data == _fonthandelgothicxsSegmentRomStart - || data == _fonthandelgothicmdSegmentRomStart) { - numchars = 135; - } -#endif - - for (s32 i = 0; i < numchars; ++i) { - PD_SWAP_VAL(fnt->chars[i].kerningindex); - PD_SWAP_PTR(fnt->chars[i].pixeldata); - } -} - -void preprocessJpnFont(u8 *data, u32 size) -{ - // ??? -} - -void preprocessALBankFile(u8 *data, u32 size) -{ - memset(swapmap, 0, sizeof(swapmap)); - - ALBankFile *bankf = (ALBankFile *)data; - PD_SWAP_VAL(bankf->revision); - PD_SWAP_VAL(bankf->bankCount); - - for (s16 i = 0; i < bankf->bankCount; ++i) { - PD_SWAP_PTR(bankf->bankArray[i]); - preprocessALBank(PD_PTR_BASE(bankf->bankArray[i], data), data); - } -} - -void preprocessALCMidiHdr(u8 *data, u32 size) -{ - ALCMidiHdr *hdr = (ALCMidiHdr *)data; - PD_SWAP_VAL(hdr->division); - for (s32 i = 0; i < ARRAYCOUNT(hdr->trackOffset); ++i) { - PD_SWAP_VAL(hdr->trackOffset[i]); - } -} - -void preprocessSequences(u8 *data, u32 size) -{ - struct seqtable *seq = (struct seqtable *)data; - PD_SWAP_VAL(seq->count); - - for (s16 i = 0; i < seq->count; ++i) { - PD_SWAP_VAL(seq->entries[i].binlen); - PD_SWAP_VAL(seq->entries[i].ziplen); - PD_SWAP_VAL(seq->entries[i].romaddr); - } -} - -void preprocessTexturesList(u8 *data, u32 size) -{ - struct texture *tex = (struct texture *)data; - const u32 count = size / sizeof(*tex); - for (u32 i = 0; i < count; ++i, ++tex) { - // TODO: it sure looks like none of the fields except soundsurfacetype, surfacetype and dataoffset are set - // just swap the last 3 bytes of the first word... - const u32 dofs = (u32)tex->dataoffset << 8; - tex->dataoffset = PD_BE32(dofs); - // ...and the surface types in the first byte - const u8 tmp = tex->soundsurfacetype; - tex->soundsurfacetype = tex->surfacetype; - tex->surfacetype = tmp; - } -} - -void preprocessTextureRGBA32Embedded(u32* dest, u32 size_bytes) -{ - for (uint32_t i = 0; i < size_bytes; i += 4, ++dest) { - *dest = PD_BE32(*dest); - } -} - -void preprocessModel(u8 *base, u32 ofs) -{ - struct modeldef *mdl = (struct modeldef *)base; - - PD_SWAP_VAL(mdl->nummatrices); - PD_SWAP_VAL(mdl->numparts); - PD_SWAP_VAL(mdl->numtexconfigs); - PD_SWAP_VAL(mdl->rwdatalen); - PD_SWAP_VAL(mdl->scale); - - if (mdl->skel) { - PD_SWAP_PTR(mdl->skel); - if ((u32)mdl->skel >= 0x10000) { - // skeleton is a pointer instead of an index - // preprocessSkeleton((struct skeleton *)(base + (u32)mdl->skel)); // TODO - } - } - - if (mdl->parts) { - PD_SWAP_PTR(mdl->parts); - struct modelnode **parts = PD_PTR_BASEOFS(mdl->parts, base, ofs); - for (s16 i = 0; i < mdl->numparts; ++i) { - PD_SWAP_PTR(parts[i]); - } - s16 *partnums = (s16 *)&parts[mdl->numparts]; - for (s16 i = 0; i < mdl->numparts; ++i) { - PD_SWAP_VAL(partnums[i]); - } - } - - u8 *texturesEnd = NULL; - if (mdl->rootnode) { - PD_SWAP_PTR(mdl->rootnode); - texturesEnd = preprocessModelNode(PD_PTR_BASEOFS(mdl->rootnode, base, ofs), base, ofs); - } - - if (mdl->texconfigs) { - PD_SWAP_PTR(mdl->texconfigs); - struct textureconfig *texconfigs = PD_PTR_BASEOFS(mdl->texconfigs, base, ofs); - for (s16 i = 0; i < mdl->numtexconfigs; ++i) { - PD_SWAP_VAL(texconfigs[i].texturenum); - if ((texconfigs[i].texturenum & 0xf000000) == 0x5000000) { - // embedded texture; we need to unswizzle this - u8 *texdata = PD_PTR_BASEOFS(texconfigs[i].textureptr, base, ofs); - // figure out the max possible size the texture can have, because sometimes the texconfig is wrong - const u32 maxSize = (texturesEnd > texconfigs[i].textureptr) ? (texturesEnd - texconfigs[i].textureptr) : 0; - // figure out the format and unswizzle - const s32 format = texConfigToFormat(&texconfigs[i]); - texSwizzleInternal(texdata, texconfigs[i].width, texconfigs[i].height, format, maxSize); - - if (format == TEXFORMAT_RGBA32) { - // for some reason, RGBA32 embedded textures don't need to be byte-swapped, - // so we byte-swap them here, which will be undone when the renderer imports it - u32 size_bytes = texconfigs[i].width * texconfigs[i].height * 4; - preprocessTextureRGBA32Embedded((u32*)texdata, size_bytes); - } - } - } - } -} - -void preprocessLangFile(u8 *data, u32 size) -{ - // lang banks are just an offset table + text data right after - // offsets are from the beginning of the bank - // however we cannot byteswap them in advance because the length of the - // offset table is unknown, so that's done in lang.c on demand instead -} - -void preprocessPadsFile(u8 *data, u32 size) -{ - struct padsfileheader *hdr = (void *)data; - - PD_SWAP_VAL(hdr->numpads); - PD_SWAP_VAL(hdr->numcovers); - - for (s32 i = 0; i < hdr->numpads; ++i) { - if (hdr->padoffsets[i]) { - PD_SWAP_VAL(hdr->padoffsets[i]); - const u32 size = (i + 1 < hdr->numpads && hdr->padoffsets[i + 1]) ? - (PD_BE16(hdr->padoffsets[i + 1]) - hdr->padoffsets[i]) : 0x40; - preprocessPadData(PD_PTR_BASE(hdr->padoffsets[i], hdr), size); - } - } - - if (hdr->numcovers && hdr->coversoffset) { - PD_SWAP_VAL(hdr->coversoffset); - struct coverdefinition *def = PD_PTR_BASE(hdr->coversoffset, hdr); - for (s32 i = 0; i < hdr->numcovers; ++i, ++def) { - PD_SWAP_VAL(def->flags); - PD_SWAP_VAL(def->look); - PD_SWAP_VAL(def->pos); - } - } - - if (hdr->waypointsoffset) { - PD_SWAP_VAL(hdr->waypointsoffset); - struct waypoint *wp = PD_PTR_BASE(hdr->waypointsoffset, hdr); - // the terminator is 0xFFFFFFFF, same for the s32 lists - // TODO: the game checks for >= 0, so maybe something's terminated with a random negative number? - while (wp->padnum != (s32)0xFFFFFFFF) { - PD_SWAP_VAL(wp->padnum); - PD_SWAP_VAL(wp->groupnum); - PD_SWAP_VAL(wp->step); - if (wp->neighbours) { - PD_SWAP_PTR(wp->neighbours); - s32 *nbr = PD_PTR_BASE(wp->neighbours, hdr); - while (*nbr != (s32)0xFFFFFFFF) { - PD_SWAP_VAL(*nbr); - ++nbr; - } - } - ++wp; - } - } - - if (hdr->waygroupsoffset) { - PD_SWAP_VAL(hdr->waygroupsoffset); - struct waygroup *wg = PD_PTR_BASE(hdr->waygroupsoffset, hdr); - while (wg->neighbours) { - PD_SWAP_VAL(wg->step); - if (wg->neighbours) { - PD_SWAP_PTR(wg->neighbours); - s32 *nbr = PD_PTR_BASE(wg->neighbours, hdr); - while (*nbr != (s32)0xFFFFFFFF) { - PD_SWAP_VAL(*nbr); - ++nbr; - } - } - if (wg->waypoints) { - PD_SWAP_PTR(wg->waypoints); - s32 *wgwp = PD_PTR_BASE(wg->waypoints, hdr); - while (*wgwp != (s32)0xFFFFFFFF) { - PD_SWAP_VAL(*wgwp); - ++wgwp; - } - } - ++wg; - } - } -} - -void preprocessTilesFile(u8 *data, u32 size) -{ - u32 *roomTable = (u32 *)data; - PD_SWAP_VAL(roomTable[0]); - - const u32 numRooms = roomTable[0]; - ++roomTable; - - u32 *rooms = roomTable; - // rooms[numRooms] is the end offset - for (u32 i = 0; i <= numRooms; ++i) { - PD_SWAP_VAL(rooms[i]); - } - - struct geo *geo = (struct geo *)(data + rooms[0]); - struct geo *end = (struct geo *)(data + rooms[numRooms]); - - while (geo < end) { - PD_SWAP_VAL(geo->flags); - switch (geo->type) { - case GEOTYPE_TILE_I: { - struct geotilei *tile = (struct geotilei *)geo; - PD_SWAP_VAL(tile->floorcol); - PD_SWAP_VAL(tile->floortype); - for (u32 i = 0; i < geo->numvertices; ++i) { - PD_SWAP_VAL(tile->vertices[i][0]); - PD_SWAP_VAL(tile->vertices[i][1]); - PD_SWAP_VAL(tile->vertices[i][2]); - } - geo = (struct geo *)((u8 *)geo + (uintptr_t)(geo->numvertices - 0x40) * 6 + 0x18e); - break; - } - case GEOTYPE_TILE_F: { - struct geotilef *tile = (struct geotilef *)geo; - PD_SWAP_VAL(tile->floorcol); - PD_SWAP_VAL(tile->floortype); - for (u32 i = 0; i < geo->numvertices; ++i) { - PD_SWAP_VAL(tile->vertices[i].x); - PD_SWAP_VAL(tile->vertices[i].y); - PD_SWAP_VAL(tile->vertices[i].z); - } - geo = (struct geo *)((u8 *)geo + (uintptr_t)(geo->numvertices - 0x40) * 12 + 0x310); - break; - } - case GEOTYPE_BLOCK: { - struct geoblock *blk = (struct geoblock *)geo; - PD_SWAP_VAL(blk->ymin); - PD_SWAP_VAL(blk->ymax); - for (u32 i = 0; i < geo->numvertices; ++i) { - PD_SWAP_VAL(blk->vertices[i][0]); - PD_SWAP_VAL(blk->vertices[i][1]); - } - geo = (struct geo *)((u8 *)geo + sizeof(struct geoblock)); - break; - } - case GEOTYPE_CYL: { - struct geocyl *cyl = (struct geocyl *)geo; - PD_SWAP_VAL(cyl->x); - PD_SWAP_VAL(cyl->z); - PD_SWAP_VAL(cyl->radius); - PD_SWAP_VAL(cyl->ymin); - PD_SWAP_VAL(cyl->ymax); - geo = (struct geo *)((u8 *)geo + sizeof(struct geocyl)); - break; - } - default: - break; - } - } -} - -void preprocessSetupFile(u8 *data, u32 size) -{ - struct stagesetup *set = (void *)data; - - if (set->intro) { - // intro commands are made up of a command id + up to 3 args, which can have any value, even 0x0c (end marker) - // so we have to swap each type by hand here as well - PD_SWAP_PTR(set->intro); - preprocessIntroScript(PD_PTR_BASE(set->intro, set)); - } - - if (set->props) { - PD_SWAP_PTR(set->props); - // commands are casted to non-trivial structs elsewhere, so we'll have to parse the fucking list - // and swap each type by hand - struct defaultobj *obj = PD_PTR_BASE(set->props, set); - while (obj->type != OBJTYPE_END) { - preprocessPropObj(obj); - obj = (struct defaultobj *)((u32 *)obj + setupGetCmdLength((u32 *)obj)); - } - } - - if (set->paths) { - PD_SWAP_PTR(set->paths); - struct path *p = PD_PTR_BASE(set->paths, set); - while ((u8 *)p < data + size && p->pads) { - PD_SWAP_PTR(p->pads); - s32 *pp = PD_PTR_BASE(p->pads, set); - while ((u8 *)pp < data + size) { - PD_SWAP_VAL(*pp); - if (*pp < 0) { - break; - } - ++pp; - } - ++p; - } - } - - if (set->ailists) { - PD_SWAP_PTR(set->ailists); - struct ailist *p = PD_PTR_BASE(set->ailists, set); - while ((u8 *)p < data + size && p->list) { - PD_SWAP_VAL(p->id); - PD_SWAP_PTR(p->list); - // the actual command lists are made up of variable length instructions, - // but they don't do any wonky word casting, so they should probably work as is - ++p; - } - } - - // the rest of the pointers are set after loading -} - -void preprocessModelFile(u8 *data, u32 size) -{ - preprocessModel(data, 0x5000000); -} - -void preprocessGunFile(u8 *data, u32 size) -{ - preprocessModel(data, 0x5000000); -} - -void preprocessBgSection1Header(u8 *data, u32 size) -{ - u32 *header = (u32 *)data; - PD_SWAP_VAL(header[0]); // inflatedsize - PD_SWAP_VAL(header[1]); // section1size - PD_SWAP_VAL(header[2]); // primcompsize -} - -void preprocessBgSection1(u8 *data, u32 ofs) { - struct { - u32 unk00; - u32 roomsofs; - u32 portalsofs; - u32 commandsofs; - u32 lightsofs; - u32 stanofs; - } *header = (void *)data; - - PD_SWAP_VAL(header->unk00); - PD_SWAP_VAL(header->roomsofs); - PD_SWAP_VAL(header->portalsofs); - - struct bgroom *rm = PD_PTR_BASEOFS(header->roomsofs, data, ofs); - for (++rm; rm->unk00; ++rm) { - PD_SWAP_VAL(rm->unk00); - PD_SWAP_VAL(rm->pos); - } - - struct bgportal *portals = PD_PTR_BASEOFS(header->portalsofs, data, ofs); - s32 numportals = 0; - for (struct bgportal *prt = portals; prt->verticesoffset; ++prt) { - ++numportals; - } - - s32 maxbatchnum = 0; - for (s32 i = 0; i < numportals; ++i) { - PD_SWAP_VAL(portals[i].verticesoffset); - PD_SWAP_VAL(portals[i].roomnum1); - PD_SWAP_VAL(portals[i].roomnum2); - if (portals[i].verticesoffset > maxbatchnum) { - maxbatchnum = portals[i].verticesoffset; - } - } - - uintptr_t pvoffset = sizeof(portals[0]) * (numportals + 1); - for (s32 i = 1; i <= maxbatchnum; i++) { - struct portalvertices *pverts = PD_PTR_BASE(pvoffset, portals); - for (u32 j = 0; j < pverts->count; ++j) { - PD_SWAP_VAL(pverts->vertices[j]); - } - pvoffset += 4 + pverts->count * 12; - } - - if (header->commandsofs) { - PD_SWAP_VAL(header->commandsofs); - struct bgcmd *cmd = PD_PTR_BASEOFS(header->commandsofs, data, ofs); - for (; cmd->type != 0x00; cmd++) { - PD_SWAP_VAL(cmd->param); - } - } - - if (header->lightsofs) { - PD_SWAP_VAL(header->lightsofs); - // data swapping done later in preprocessBgLights - } - - if (header->stanofs) { - PD_SWAP_VAL(header->stanofs); - // unused, so won't swap the contents - } -} - -void preprocessBgSection2Header(u8 *data, u32 size) -{ - u16 *header = (u16 *)data; - PD_SWAP_VAL(header[0]); // inflatedsize - PD_SWAP_VAL(header[1]); // section2compsize -} - -void preprocessBgSection2(u8 *data, u32 size) -{ - // section2 is a texture id list - u16 *section2 = (u16 *)data; - for (s32 i = 0; i < size; ++i) { - PD_SWAP_VAL(section2[i]); - } -} - -void preprocessBgSection3Header(u8 *data, u32 size) -{ - u16 *header = (u16 *)data; - PD_SWAP_VAL(header[0]); - PD_SWAP_VAL(header[1]); -} - -void preprocessBgSection3(u8 *data, u32 size) -{ - // room bounding boxes, 6x s16 per room - s16 *bbox = (s16 *)data; - for (s32 i = 1; i < g_Vars.roomcount; ++i) { - PD_SWAP_VAL(*bbox); ++bbox; - PD_SWAP_VAL(*bbox); ++bbox; - PD_SWAP_VAL(*bbox); ++bbox; - PD_SWAP_VAL(*bbox); ++bbox; - PD_SWAP_VAL(*bbox); ++bbox; - PD_SWAP_VAL(*bbox); ++bbox; - } - - // gfxdatalen list - u16 *gfxdatalen = (u16 *)bbox; - for (s32 i = 1; i < g_Vars.roomcount; ++i) { - PD_SWAP_VAL(*gfxdatalen); ++gfxdatalen; - } -} - -void preprocessBgRoom(u8 *data, u32 ofs) { - struct roomgfxdata *rgfx = (void *)data; - - PD_SWAP_VAL(rgfx->numvertices); - PD_SWAP_VAL(rgfx->numcolours); - PD_SWAP_VAL(rgfx->numlights); - PD_SWAP_VAL(rgfx->lightsindex); - PD_SWAP_PTR(rgfx->vertices); - PD_SWAP_PTR(rgfx->opablocks); - PD_SWAP_PTR(rgfx->xlublocks); - PD_SWAP_PTR(rgfx->colours); - - // numvertices is actually 0 in the data because fuck you - const s32 numverts = ((uintptr_t) rgfx->colours - (uintptr_t) rgfx->vertices) / sizeof(Vtx); - Vtx *vertices = NULL; - if (rgfx->vertices) { - vertices = PD_PTR_BASEOFS(rgfx->vertices, data, ofs); - Vtx *vtx = vertices; - for (s32 i = 0; i < numverts; ++i, ++vtx) { - preprocessVtx(vtx); - } - } - - // here's hoping that xlublocks and opablocks aren't completely separate trees - - struct roomblock *blk = rgfx->blocks; - struct roomblock *end = (void *)vertices; - struct coord *tmp; - - for (; blk + 1 <= end; blk++) { - PD_SWAP_PTR(blk->next); - switch (blk->type) { - case ROOMBLOCKTYPE_LEAF: - if (blk->gdl) { - PD_SWAP_PTR(blk->gdl); - preprocessGfx(PD_PTR_BASEOFS(blk->gdl, data, ofs), data, ofs); - } - PD_SWAP_PTR(blk->vertices); - PD_SWAP_PTR(blk->colours); - break; - case ROOMBLOCKTYPE_PARENT: - PD_SWAP_PTR(blk->child); - PD_SWAP_PTR(blk->unk0c); - tmp = PD_PTR_BASEOFS(blk->unk0c, data, ofs); - for (s32 i = 0; i < 2; ++i) { - PD_SWAP_VAL(tmp[i].x); - PD_SWAP_VAL(tmp[i].y); - PD_SWAP_VAL(tmp[i].z); - } - if ((u8 *)tmp < (u8 *)end) { - end = (void *)tmp; - } - break; - default: - break; - } - } -} - -void preprocessBgLights(u8 *data, u32 ofs) -{ - struct light *lbase = (void *)data; - if (!lbase) { - return; - } - - for (s32 i = 0; i < g_Vars.roomcount; ++i) { - if (g_Rooms[i].numlights) { - struct light *lit = &lbase[g_Rooms[i].lightindex]; - for (s32 j = 0; j < g_Rooms[i].numlights; ++j, ++lit) { - PD_SWAP_VAL(lit->colour); - PD_SWAP_VAL(lit->roomnum); - for (s32 k = 0; k < ARRAYCOUNT(lit->bbox); ++k) { - PD_SWAP_VAL(lit->bbox[k].x); - PD_SWAP_VAL(lit->bbox[k].y); - PD_SWAP_VAL(lit->bbox[k].z); - } - } - } - } -} diff --git a/port/src/preprocess/common.c b/port/src/preprocess/common.c new file mode 100644 index 000000000..31b45a79a --- /dev/null +++ b/port/src/preprocess/common.c @@ -0,0 +1,31 @@ +#include "preprocess/common.h" + +static struct ptrmarker ptrMarkers[MAX_PTR_MARKERS]; +static int numPtrMarkers; + +void ptrAdd(u32 ptr_src, uintptr_t ptr_host) +{ + if (numPtrMarkers >= ARRAYCOUNT(ptrMarkers)) { + sysFatalError("ptrAdd(%p, %p): ptrmarker limit exceeded", (void *)(uintptr_t)ptr_src, (void *)ptr_host); + } + + ptrMarkers[numPtrMarkers].ptr_src = ptr_src; + ptrMarkers[numPtrMarkers].ptr_host = ptr_host; + numPtrMarkers++; +} + +struct ptrmarker *ptrFind(uintptr_t ptr_src) +{ + for (int i = 0; i < numPtrMarkers; i++) { + if (ptrMarkers[i].ptr_src == ptr_src) { + return &ptrMarkers[i]; + } + } + + return NULL; +} + +void ptrReset(void) +{ + numPtrMarkers = 0; +} diff --git a/port/src/preprocess/filebg.c b/port/src/preprocess/filebg.c new file mode 100644 index 000000000..55f173364 --- /dev/null +++ b/port/src/preprocess/filebg.c @@ -0,0 +1,524 @@ +#include +#include +#include +#include + +#include "data.h" +#include "bss.h" + +#include "preprocess/common.h" +#include "preprocess/gbi.h" + +/** + * 4 bytes decompressed size of primary data + * 4 bytes compressed size of section 1 in its entirety + * 4 bytes compressed size of primary data + * Section 1: + * Primary: (zipped) + * 4 bytes null + * 4 bytes pointer to room table + * 4 bytes pointer to portal table + * 4 bytes pointer to bgcmds + * 4 bytes pointer to lights table + * 4 bytes null + * (room table) + * (portal table) + * (bgcmds) + * (lights table) + * room 1 (zipped) + * room 2 (zipped) + * ... + * Section 2: + * 2 bytes decompressed size of section (mask with 0x7fff) + * 2 bytes compressed size of section + * Texture ID list (zipped) + * Section 3: + * 2 bytes decompressed size of section (mask with 0x7fff) + * 2 bytes compressed size of section + * Zipped: + * (room bbox table) + * (list of roomgfxdata sizes) + * (list of light counts per room) + */ + +struct fileheader { + u32 primary_infsize; + u32 section1_cmpsize; + u32 primary_cmpsize; +}; + +struct sectionheader { + u16 infsize; + u16 cmpsize; +}; + +struct n64_primaryheader { + u32 unused1; + u32 ptr_rooms; + u32 ptr_portals; + u32 ptr_bgcmds; + u32 ptr_lights; + u32 unused2; +}; + +struct host_primaryheader { + uintptr_t unused1; + uintptr_t ptr_rooms; + uintptr_t ptr_portals; + uintptr_t ptr_bgcmds; + uintptr_t ptr_lights; + uintptr_t unused2; +}; + +struct n64_bgroom { + u32 ptr_gfxdata; + struct coord pos; + u8 br_light_min; + u8 br_light_max; +}; + +struct n64_roomblock { + u8 type; + u32 ptr_next; + u32 ptr_gdl; + u32 ptr_vertices; + u32 ptr_colours; +}; + +struct n64_roomgfxdata { + u32 ptr_vertices; + u32 ptr_colours; + u32 ptr_opablocks; + u32 ptr_xlublocks; + s16 lightsindex; + s16 numlights; + s16 numvertices; + s16 numcolours; + // roomblocks[] +}; + +struct vtx { + s16 coord[3]; + u8 flag; + u8 color; + u16 s; + u16 t; +}; + +static void convertPrimaryRooms(u8 *dst, u32 *dstpos, u8 *src, u32 *srcpos) +{ + struct n64_bgroom *n64_rooms = (struct n64_bgroom *) &src[*srcpos]; + struct bgroom *host_rooms = (struct bgroom *) &dst[*dstpos]; + + s32 numRooms = 0; + + for (int i = 1; n64_rooms[i].ptr_gfxdata != 0; i++) { + numRooms++; + } + + for (int i = 0; i < numRooms + 1; i++) { + host_rooms[i].unk00 = PD_BE32(n64_rooms[i].ptr_gfxdata); + host_rooms[i].pos = PD_SWAPPED_VAL(n64_rooms[i].pos); + host_rooms[i].br_light_min = n64_rooms[i].br_light_min; + host_rooms[i].br_light_max = n64_rooms[i].br_light_max; + } + + *srcpos += sizeof(*n64_rooms) * (numRooms + 2); + *dstpos += sizeof(*host_rooms) * (numRooms +2); +} + +static void convertPrimaryPortals(u8 *dst, u32 *dstpos, u8 *src, u32 *srcpos, u32 *src_portalvtxs, u32 *dst_portalvtxs) +{ + struct bgportal *n64_portals = (struct bgportal *) &src[*srcpos]; + struct bgportal *host_portals = (struct bgportal *) &dst[*dstpos]; + + // Count portals + int numportals = 0; + + for (int i = 0; n64_portals[i].verticesoffset != 0; i++) { + numportals++; + } + + // Convert portals + for (int i = 0; i < numportals; i++) { + host_portals[i].verticesoffset = PD_BE16(n64_portals[i].verticesoffset); + host_portals[i].roomnum1 = PD_BE16(n64_portals[i].roomnum1); + host_portals[i].roomnum2 = PD_BE16(n64_portals[i].roomnum2); + host_portals[i].flags = n64_portals[i].flags; + } + + *srcpos += sizeof(*n64_portals) * (numportals + 1); + *dstpos += sizeof(*host_portals) * (numportals + 1); + + *src_portalvtxs = *srcpos; + *dst_portalvtxs = *dstpos; + + while (1) { + struct portalvertices *n64_pvertices = (struct portalvertices *)&src[*srcpos]; + struct portalvertices *host_pvertices = (struct portalvertices *)&dst[*dstpos]; + + host_pvertices->count = n64_pvertices->count; + + for (int j = 0; j < host_pvertices->count; j++) { + host_pvertices->vertices[j] = PD_SWAPPED_VAL(n64_pvertices->vertices[j]); + } + + *srcpos += 4 + host_pvertices->count * 12; + *dstpos += 4 + host_pvertices->count * 12; + + if (host_pvertices->count == 0) break; + } +} + +static void convertPrimaryBgCmds(u8 *dst, u32 *dstpos, u8 *src, u32 dst_portalvtxs, u32 src_portalvtxs) +{ + struct bgcmd *n64_cmds = (struct bgcmd *) src; + struct bgcmd *host_cmds = (struct bgcmd *) &dst[*dstpos]; + int num_cmds = 0; + + for (int i = 0; n64_cmds[i].type != 0; i++) { + num_cmds++; + } + + num_cmds++; + + for (int i = 0; i < num_cmds; i++) { + host_cmds[i].type = n64_cmds[i].type; + host_cmds[i].len = n64_cmds[i].len; + host_cmds[i].param = PD_BE32(n64_cmds[i].param); + + if (host_cmds[i].type == 0x64) { + u32 offset = host_cmds[i].param - src_portalvtxs; + host_cmds[i].param = dst_portalvtxs + offset; + } + } + + *dstpos += sizeof(*host_cmds) * num_cmds; +} + +static void convertPrimaryLights(u8 *dst, u32 *dstpos, u8 *src, u32 *srcpos, u32 end) +{ + struct light *n64_lights = (struct light *) &src[*srcpos]; + struct light *host_lights = (struct light *) &dst[*dstpos]; + int num_lights = (end - *srcpos) / sizeof(struct light); + + for (int i = 0; i < num_lights; i++) { + host_lights[i].roomnum = PD_BE16(n64_lights[i].roomnum); + host_lights[i].colour = PD_BE16(n64_lights[i].colour); + host_lights[i].brightness = n64_lights[i].brightness; + host_lights[i].sparkable = n64_lights[i].sparkable; + host_lights[i].healthy = n64_lights[i].healthy; + host_lights[i].on = n64_lights[i].on; + host_lights[i].sparking = n64_lights[i].sparking; + host_lights[i].vulnerable = n64_lights[i].vulnerable; + host_lights[i].brightnessmult = n64_lights[i].brightnessmult; + host_lights[i].dirx = n64_lights[i].dirx; + host_lights[i].diry = n64_lights[i].diry; + host_lights[i].dirz = n64_lights[i].dirz; + + for (int j = 0; j < 4; j++) { + host_lights[i].bbox[j].x = PD_BE16(n64_lights[i].bbox[j].x); + host_lights[i].bbox[j].y = PD_BE16(n64_lights[i].bbox[j].y); + host_lights[i].bbox[j].z = PD_BE16(n64_lights[i].bbox[j].z); + } + } + + *srcpos += sizeof(*n64_lights) * num_lights; + *dstpos += sizeof(*host_lights) * num_lights; +} + +#define BLOCK_LEAF 0 +#define BLOCK_PARENT 1 + +void relinkPtr(uintptr_t* ptr) +{ + if (!*ptr) return; + + struct ptrmarker* marker = ptrFind(*ptr); + if (!marker) { + sysFatalError("[BG] WARNING: Unable to relink pointer: %p\n", ptr); + } + + *ptr = marker->ptr_host; +} + +static u32 convertRoomGfxData(u8 *dst, u8 *src, u32 infsize, u32 src_ofs) +{ + ptrReset(); + gbiReset(); + + u32 dst_roomoffset = src_ofs; + + uintptr_t gdls_addr[64]; + int numgdls = 0; + + struct n64_roomgfxdata *src_header = (struct n64_roomgfxdata*)src; + struct roomgfxdata *dst_header = (struct roomgfxdata*)dst; + + dst_header->vertices = (void *)(uintptr_t)PD_BE32(src_header->ptr_vertices); + dst_header->colours = (void *)(uintptr_t)PD_BE32(src_header->ptr_colours); + dst_header->opablocks = (void *)(uintptr_t)PD_BE32(src_header->ptr_opablocks); + dst_header->xlublocks = (void *)(uintptr_t)PD_BE32(src_header->ptr_xlublocks); + dst_header->lightsindex = PD_BE16(src_header->lightsindex); + dst_header->numlights = PD_BE16(src_header->numlights); + dst_header->numvertices = PD_BE16(src_header->numvertices); + dst_header->numcolours = PD_BE16(src_header->numcolours); + + intptr_t endpos = (uintptr_t)dst_header->vertices - src_ofs; + uintptr_t curpos_src = sizeof(struct n64_roomgfxdata); + uintptr_t curpos_dst = sizeof(struct roomgfxdata); + + // roomblocks + int ncoords = 0; + + // save the ptr to roomblocks here to iterate later to fix the pointers + struct roomblock *ptr_dst_roomblocks = (struct roomblock*)&dst[curpos_dst]; + + int numblocks = 0; + while ((intptr_t)(curpos_src + sizeof(struct n64_roomblock)) <= endpos) { + struct n64_roomblock *src_roomblock = (struct n64_roomblock*)&src[curpos_src]; + struct roomblock *dest_roomblock = (struct roomblock*)&dst[curpos_dst]; + + dest_roomblock->type = src_roomblock->type; + dest_roomblock->next = (void *)(uintptr_t)PD_BE32(src_roomblock->ptr_next); + dest_roomblock->gdl = (void *)(uintptr_t)PD_BE32(src_roomblock->ptr_gdl); + dest_roomblock->vertices = (void *)(uintptr_t)PD_BE32(src_roomblock->ptr_vertices); + dest_roomblock->colours = (void *)(uintptr_t)PD_BE32(src_roomblock->ptr_colours); + + ptrAdd(curpos_src + src_ofs, curpos_dst + dst_roomoffset); + + if (src_roomblock->type == BLOCK_PARENT) { + ncoords++; + uintptr_t vtx_ptr = (uintptr_t)dest_roomblock->vertices - src_ofs; + if (vtx_ptr < endpos) endpos = vtx_ptr; + } + else if (src_roomblock->ptr_gdl) { + gdls_addr[numgdls++] = PD_BE32(src_roomblock->ptr_gdl) - src_ofs; + } + + curpos_src += sizeof(struct n64_roomblock); + curpos_dst += sizeof(struct roomblock); + numblocks++; + } + + // block coords + for (size_t i = 0; i < ncoords; i++) { + u32 *src_coord = (u32*)(src + curpos_src); + u32 *dst_coord = (u32*)(dst + curpos_dst); + + dst_coord[0] = PD_BE32(src_coord[0]); + dst_coord[1] = PD_BE32(src_coord[1]); + dst_coord[2] = PD_BE32(src_coord[2]); + + dst_coord[3] = PD_BE32(src_coord[3]); + dst_coord[4] = PD_BE32(src_coord[4]); + dst_coord[5] = PD_BE32(src_coord[5]); + + ptrAdd(curpos_src + src_ofs, curpos_dst + dst_roomoffset); + + curpos_src += 6 * sizeof(u32); + curpos_dst += 6 * sizeof(u32); + } + + curpos_dst = ALIGN8(curpos_dst); + + // vertices + uintptr_t ptr_src_vertices = curpos_src = ALIGN8((uintptr_t)dst_header->vertices - src_ofs); + uintptr_t ptr_dst_vertices = curpos_dst + dst_roomoffset; + + ptrAdd(curpos_src + src_ofs, curpos_dst + dst_roomoffset); + + uintptr_t vtx_end = (uintptr_t)dst_header->colours - src_ofs; + + while (dst_header->colours && curpos_src < vtx_end) { + struct vtx *src_vtx = (struct vtx*)(src + curpos_src); + struct vtx *dst_vtx = (struct vtx*)(dst + curpos_dst); + + dst_vtx->coord[0] = PD_BE16(src_vtx->coord[0]); + dst_vtx->coord[1] = PD_BE16(src_vtx->coord[1]); + dst_vtx->coord[2] = PD_BE16(src_vtx->coord[2]); + + dst_vtx->flag = src_vtx->flag; + dst_vtx->color = src_vtx->color; + + dst_vtx->s = PD_BE16(src_vtx->s); + dst_vtx->t = PD_BE16(src_vtx->t); + + curpos_src += sizeof(struct vtx); + curpos_dst += sizeof(struct vtx); + } + + curpos_dst = ALIGN8(curpos_dst); + + // colors + uintptr_t ptr_src_colors = 0; + uintptr_t ptr_dst_colors = 0; + + if (dst_header->colours) { + ptr_src_colors = curpos_src = ALIGN8((uintptr_t)dst_header->colours - src_ofs); + ptr_dst_colors = curpos_dst + dst_roomoffset; + + ptrAdd(curpos_src + src_ofs, curpos_dst + dst_roomoffset); + + uintptr_t col_end = (numgdls > 0) ? gdls_addr[0] : infsize; + size_t col_len = col_end - curpos_src; + + memcpy(dst + curpos_dst, src + curpos_src, col_len); + curpos_src += col_len; + curpos_dst += col_len; + } + + // gdls + gbiSetVtx(src_header->ptr_vertices, ptr_src_vertices); + gbiSetSegment(0x0e, (uintptr_t)dst_header->vertices); + + uintptr_t gdlstart = curpos_dst; + for (size_t i = 0; i < numgdls; i++) { + ptrAdd(gdls_addr[i] + src_ofs, curpos_dst + dst_roomoffset); + curpos_dst = gbiConvertGdl(dst, curpos_dst, src, gdls_addr[i], 1); + } + + // relink ptrs: roomblocks + for (size_t i = 0; i < numblocks; i++) { + struct roomblock *block = (struct roomblock*)&ptr_dst_roomblocks[i]; + + relinkPtr((uintptr_t*)&block->next); + + if (block->type == BLOCK_LEAF) { + relinkPtr((uintptr_t*)&block->gdl); + u32 offset_vtx = (uintptr_t)block->vertices - ptr_src_vertices - src_ofs; + u32 offset_col = (uintptr_t)block->colours - ptr_src_colors - src_ofs; + + block->vertices = (void *)(ptr_dst_vertices + offset_vtx); + block->colours = (void *)(ptr_dst_colors + offset_col); + } + else { + relinkPtr((uintptr_t*)&block->gdl); // child + relinkPtr((uintptr_t*)&block->vertices); // coord + } + } + + // relink ptrs: header + relinkPtr((uintptr_t*)&dst_header->vertices); + relinkPtr((uintptr_t*)&dst_header->colours); + relinkPtr((uintptr_t*)&dst_header->opablocks); + relinkPtr((uintptr_t*)&dst_header->xlublocks); + + return curpos_dst; +} + +static u32 convertSection1(u8 *dst, u8 *src, u32 ofs) +{ + // Convert primary + u32 srcpos = 0; + u32 dstpos = 0; + struct host_primaryheader *host_primary_header = (struct host_primaryheader *) dst; + struct n64_primaryheader *n64_primary_header = (struct n64_primaryheader *) src; + srcpos += sizeof(struct n64_primaryheader); + dstpos += sizeof(*host_primary_header); + + u32 src_bgcmds = PD_BE32(n64_primary_header->ptr_bgcmds) - ofs; + + host_primary_header->unused1 = 0; + host_primary_header->unused2 = 0; + + host_primary_header->ptr_rooms = dstpos + ofs; + convertPrimaryRooms(dst, &dstpos, src, &srcpos); + + if (n64_primary_header->ptr_lights) { + host_primary_header->ptr_lights = dstpos + ofs; + srcpos = PD_BE32(n64_primary_header->ptr_lights) - ofs; + convertPrimaryLights(dst, &dstpos, src, &srcpos, src_bgcmds); + } + + host_primary_header->ptr_portals = dstpos + ofs; + srcpos = PD_BE32(n64_primary_header->ptr_portals) - ofs; + u32 src_portalvtxs, dst_portalvtxs; + convertPrimaryPortals(dst, &dstpos, src, &srcpos, &src_portalvtxs, &dst_portalvtxs); + + host_primary_header->ptr_bgcmds = dstpos + ofs; + convertPrimaryBgCmds(dst, &dstpos, &src[src_bgcmds], dst_portalvtxs, src_portalvtxs); + + return dstpos; +} + +void preprocessBgSection1(u8 *data, u32 size, u32 ofs) +{ + u8 *dst = sysMemZeroAlloc(size); + + u32 newSize = convertSection1(dst, data, ofs); + + if (newSize > size) { + sysFatalError("overflow when trying to preprocess a bg file, size %d newsize %d", size, newSize); + } + + memcpy(data, dst, newSize); + sysMemFree(dst); +} + +u32 preprocessBgRoom(u8 *data, u32 size, u32 room_ofs) +{ + size *= 2; + u8 *dst = sysMemZeroAlloc(size); + u32 newSize = convertRoomGfxData(dst, data, size, room_ofs); + + if (newSize > size) { + sysFatalError("overflow when trying to preprocess a bg room, size %d newsize %d", size, newSize); + } + + memcpy(data, dst, newSize); + sysMemFree(dst); + + return newSize; +} + +void preprocessBgSection1Header(u8* data, u32 size) +{ + u32* header = (u32*)data; + PD_SWAP_VAL(header[0]); // inflatedsize + PD_SWAP_VAL(header[1]); // section1size + PD_SWAP_VAL(header[2]); // primcompsize +} + +void preprocessBgSection2Header(u8* data, u32 size) +{ + u16* header = (u16*)data; + PD_SWAP_VAL(header[0]); // inflatedsize + PD_SWAP_VAL(header[1]); // section2compsize +} + +void preprocessBgSection2(u8* data, u32 size) +{ + // section2 is a texture id list + u16* section2 = (u16*)data; + for (s32 i = 0; i < size; ++i) { + PD_SWAP_VAL(section2[i]); + } +} + +void preprocessBgSection3Header(u8* data, u32 size) +{ + u16* header = (u16*)data; + PD_SWAP_VAL(header[0]); + PD_SWAP_VAL(header[1]); +} + +void preprocessBgSection3(u8* data, u32 size) +{ + // room bounding boxes, 6x s16 per room + s16* bbox = (s16*)data; + for (s32 i = 1; i < g_Vars.roomcount; ++i) { + PD_SWAP_VAL(*bbox); ++bbox; + PD_SWAP_VAL(*bbox); ++bbox; + PD_SWAP_VAL(*bbox); ++bbox; + PD_SWAP_VAL(*bbox); ++bbox; + PD_SWAP_VAL(*bbox); ++bbox; + PD_SWAP_VAL(*bbox); ++bbox; + } + + // gfxdatalen list + u16* gfxdatalen = (u16*)bbox; + for (s32 i = 1; i < g_Vars.roomcount; ++i) { + PD_SWAP_VAL(*gfxdatalen); ++gfxdatalen; + } +} diff --git a/port/src/preprocess/filelang.c b/port/src/preprocess/filelang.c new file mode 100644 index 000000000..9869202fb --- /dev/null +++ b/port/src/preprocess/filelang.c @@ -0,0 +1,92 @@ +#include +#include +#include + +#include "preprocess/common.h" + +static int getNextNonZero(u8 *src, u32 offset, size_t len) +{ + u32 *ptr = (u32 *) &src[offset]; + u32 *end = (u32 *) &src[len]; + + while (ptr < end) { + if (*ptr != 0) { + return PD_BE32(*ptr); + } + + ptr++; + } + + return 0; +} + +static int getNumStrings(u8 *src, size_t len) +{ + u32 ptr_table_len = getNextNonZero(src, 0, len); + + if (ptr_table_len) { + return ptr_table_len / sizeof(u32); + } + + return 1; +} + +static u32 convertLangFile(u8 *dst, u8 *src, size_t srclen) +{ + // Convert it + u32 *src_offsets = (u32 *) src; + size_t src_ptr_table_len = PD_BE32(src_offsets[0]); + size_t src_str_table_len = srclen - src_ptr_table_len; + int num_strings = getNumStrings(src, srclen); + size_t dst_ptr_table_len = num_strings * sizeof(uintptr_t); + size_t dst_str_table_len = src_str_table_len; + + int cur_dst_offset = dst_ptr_table_len; + + uintptr_t *dst_offsets = (uintptr_t *) dst; + + for (int i = 0; i < num_strings; i++) { + u32 src_offset = PD_BE32(src_offsets[i]); + + if (src_offset) { + // Write pointer + dst_offsets[i] = (cur_dst_offset); + + // Write string + u32 end = getNextNonZero(src, (i + 1) * 4, num_strings * 4); + + if (!end) { + end = srclen; + } + + size_t len = end - src_offset; + len = ALIGN4(len); + memcpy(&dst[cur_dst_offset], &src[src_offset], len); + + cur_dst_offset += len; + } else { + // Write pointer + dst_offsets[i] = 0; + } + } + + return ALIGN16(cur_dst_offset); +} + +u8 *preprocessLangFile(u8 *data, u32 size, u32 *outSize) { + u32 newSizeEstimated = romdataFileGetEstimatedSize(size, LOADTYPE_LANG); + u8 *dst = sysMemZeroAlloc(newSizeEstimated); + + u32 newSize = convertLangFile(dst, data, size); + + if (newSize > newSizeEstimated) { + sysFatalError("overflow when trying to preprocess a lang file, size %d newsize %d", size, newSize); + } + + memcpy(data, dst, newSize); + sysMemFree(dst); + + *outSize = newSize; + + return 0; +} diff --git a/port/src/preprocess/filemodel.c b/port/src/preprocess/filemodel.c new file mode 100644 index 000000000..c2ff8c100 --- /dev/null +++ b/port/src/preprocess/filemodel.c @@ -0,0 +1,884 @@ +#include +#include +#include + +#include "types.h" +#include "gbi.h" +#include "game/texdecompress.h" + +#include "preprocess/common.h" +#include "preprocess/gbi.h" + +enum contenttype { + /* 0*/ CT_MODELDEF, + /* 1*/ CT_NODE, + /* 2*/ CT_TEXCONFIG, + /* 3*/ CT_TEXDATA, + /* 4*/ CT_PARTS, + /* 5*/ CT_VTXCOL, + /* 6*/ CT_GDL, + /* 7*/ CT_RODATA_CHRINFO, + /* 8*/ CT_RODATA_POSITION, + /* 9*/ CT_RODATA_GUNDL, + /*10*/ CT_RODATA_DISTANCE, + /*11*/ CT_RODATA_REORDER, + /*12*/ CT_RODATA_BBOX, + /*13*/ CT_RODATA_CHRGUNFIRE, + /*14*/ CT_RODATA_11, + /*15*/ CT_RODATA_TOGGLE, + /*16*/ CT_RODATA_POSITIONHELD, + /*17*/ CT_RODATA_STARGUNFIRE, + /*18*/ CT_RODATA_HEADSPOT, + /*19*/ CT_RODATA_DL, + /*20*/ CT_RODATA_19, + /*21*/ CT_VTXCOL4, // CT_VTXCOL but aligned to 4 bytes instead of 8 + /*22*/ CT_SKIP, // to skip padding data +}; + +struct marker { + u32 src_offset; + u32 dst_offset; + u32 parent_src_offset; + enum contenttype type; +}; + +struct alignconfig { + int before; + int after; +}; + +static const struct alignconfig alignConfigs[] = { + /* 0*/ { 16, 4 }, + /* 1*/ { 4, 4 }, + /* 2*/ { 4, 4 }, + /* 3*/ { 8, 8 }, // CT_TEXDATA + /* 4*/ { 4, 4 }, + /* 5*/ { 8, 4 }, // CT_VTXCOL + /* 6*/ { 8, 8 }, // CT_GDL + /* 7*/ { 4, 4 }, + /* 8*/ { 4, 4 }, + /* 9*/ { 8, 4 }, // CT_GUNDL + /*10*/ { 4, 4 }, + /*11*/ { 4, 4 }, + /*12*/ { 4, 4 }, + /*13*/ { 4, 4 }, + /*14*/ { 4, 4 }, + /*15*/ { 4, 4 }, + /*16*/ { 4, 4 }, + /*17*/ { 8, 4 }, // CT_STARGUNFIRE + /*18*/ { 4, 4 }, + /*19*/ { 8, 4 }, // CT_RODATA_DL + /*20*/ { 4, 4 }, + /*21*/ { 4, 4 }, + /*22*/ { 4, 4 } +}; + +static struct marker contentMarkers[1024]; +static int numContentMarkers; + +struct n64_modeldef { + u32 ptr_rootnode; + u32 ptr_skel; + u32 ptr_parts; + s16 numparts; + s16 nummatrices; + u32 scale; + u16 rwdatalen; + u16 numtexconfigs; + u32 ptr_texconfigs; +}; + +struct n64_modelnode { + u16 type; + u32 ptr_rodata; + u32 ptr_parent; + u32 ptr_next; + u32 ptr_prev; + u32 ptr_child; +}; + +struct n64_modelrodata_gundl { + u32 ptr_opagdl; + u32 ptr_xlugdl; + u32 ptr_baseaddr; + u32 ptr_vertices; + s16 numvertices; + s16 unk12; +}; + +struct n64_modelrodata_distance { + f32 near; + f32 far; + u32 ptr_target; + u16 rwdataindex; +}; + +struct n64_modelrodata_reorder { + f32 unk00; + f32 unk04; + f32 unk08; + f32 unk0c[3]; + u32 ptr_node_unk18; + u32 ptr_node_unk1c; + s16 side; + u16 rwdataindex; +}; + +struct n64_modelrodata_chrgunfire { + struct coord pos; + struct coord dim; + u32 ptr_texture; + f32 unk1c; + u16 rwdataindex; + u32 ptr_baseaddr; +}; + +struct n64_modelrodata_type11 { + u32 unk00; + u32 unk04; + u32 unk08; + u32 unk0c; + u32 unk10; + u32 ptr_unk14; // not used + u32 extra1; + u32 extra2; +}; + +struct n64_modelrodata_toggle { + u32 ptr_target; + u16 rwdataindex; +}; + +struct n64_modelrodata_stargunfire { + u32 unk00; + u32 ptr_vertices; + u32 ptr_gdl; + u32 ptr_baseaddr; +}; + +struct n64_modelrodata_dl { + u32 ptr_opagdl; + u32 ptr_xlugdl; + u32 ptr_colours; + u32 ptr_vertices; // colours follow this array + s16 numvertices; + s16 mcount; + u16 rwdataindex; + u16 numcolours; +}; + +struct n64_textureconfig { + u32 ptr; + u8 width; + u8 height; + u8 level; + u8 format; + u8 depth; + u8 s; + u8 t; + u8 unk0b; +}; + +static inline uintptr_t minPtr(uintptr_t a, uintptr_t b) { + return (a && (a < b || !b)) ? a : b; +} + +static inline uintptr_t minPtr3(uintptr_t a, uintptr_t b, uintptr_t c) { + return minPtr(minPtr(a, b), c); +} + +static struct marker *findMarker(u32 src_offset) +{ + for (int i = 0; i < numContentMarkers; i++) { + if (contentMarkers[i].src_offset == src_offset) { + return &contentMarkers[i]; + } + } + + return NULL; +} + +static void setMarker(u32 src_offset, enum contenttype type, u32 parent_src_offset) +{ + if (src_offset == 0) { + return; + } + + src_offset &= 0x00ffffff; + + if (findMarker(src_offset)) { + return; + } + + if (numContentMarkers >= ARRAYCOUNT(contentMarkers)) { + sysFatalError("setMarker: marker limit exceeded"); + } + + contentMarkers[numContentMarkers].src_offset = src_offset; + contentMarkers[numContentMarkers].type = type; + contentMarkers[numContentMarkers].parent_src_offset = parent_src_offset; + numContentMarkers++; +} + +static const enum contenttype nodeTypeToContentType[] = { + /*0x00*/ -1, + /*0x01*/ CT_RODATA_CHRINFO, + /*0x02*/ CT_RODATA_POSITION, + /*0x03*/ -1, + /*0x04*/ CT_RODATA_GUNDL, + /*0x05*/ -1, + /*0x06*/ -1, + /*0x07*/ -1, + /*0x08*/ CT_RODATA_DISTANCE, + /*0x09*/ CT_RODATA_REORDER, + /*0x0a*/ CT_RODATA_BBOX, + /*0x0b*/ -1, + /*0x0c*/ CT_RODATA_CHRGUNFIRE, + /*0x0d*/ -1, + /*0x0e*/ -1, + /*0x0f*/ -1, + /*0x10*/ -1, + /*0x11*/ CT_RODATA_11, + /*0x12*/ CT_RODATA_TOGGLE, + /*0x13*/ -1, + /*0x14*/ -1, + /*0x15*/ CT_RODATA_POSITIONHELD, + /*0x16*/ CT_RODATA_STARGUNFIRE, + /*0x17*/ CT_RODATA_HEADSPOT, + /*0x18*/ CT_RODATA_DL, + /*0x19*/ CT_RODATA_19, +}; + +static void populateMarkers(u8 *src) +{ + numContentMarkers = 0; + + setMarker(0x05000000, CT_MODELDEF, 0); + + for (int i = 0; i < numContentMarkers; i++) { + struct marker *marker = &contentMarkers[i]; + void *src_thing = &src[marker->src_offset]; + int numvtx = 0; + u32 colstart = 0; + + switch (marker->type) { + case CT_MODELDEF: + struct n64_modeldef *src_modeldef = src_thing; + int num_texconfigs = PD_BE16(src_modeldef->numtexconfigs); + u32 texconfigpos = PD_BE32(src_modeldef->ptr_texconfigs); + setMarker(PD_BE32(src_modeldef->ptr_rootnode), CT_NODE, marker->src_offset); + setMarker(PD_BE32(src_modeldef->ptr_parts), CT_PARTS, marker->src_offset); + + for (int i = 0; i < num_texconfigs; i++) { + setMarker(texconfigpos + sizeof(struct n64_textureconfig) * i, CT_TEXCONFIG, marker->src_offset); + } + break; + case CT_NODE: + struct n64_modelnode *src_node = src_thing; + u32 node_type = PD_BE16(src_node->type) & 0xff; + setMarker(PD_BE32(src_node->ptr_rodata), nodeTypeToContentType[node_type], marker->src_offset); + setMarker(PD_BE32(src_node->ptr_parent), CT_NODE, marker->src_offset); + setMarker(PD_BE32(src_node->ptr_next), CT_NODE, marker->src_offset); + setMarker(PD_BE32(src_node->ptr_prev), CT_NODE, marker->src_offset); + setMarker(PD_BE32(src_node->ptr_child), CT_NODE, marker->src_offset); + break; + case CT_TEXCONFIG: + struct n64_textureconfig *src_texconfig = src_thing; + if ((PD_BE32(src_texconfig->ptr) & 0xff000000) == 0x05000000) { + setMarker(PD_BE32(src_texconfig->ptr), CT_TEXDATA, marker->src_offset); + } + break; + case CT_PARTS: + struct n64_modeldef *src_modeldef2 = (struct n64_modeldef *) src; + u32 *src_parts = (u32 *) src_thing; + int num_parts = PD_BE16(src_modeldef2->numparts); + + for (int i = 0; i < num_parts; i++) { + setMarker(PD_BE32(src_parts[i]), CT_NODE, marker->src_offset); + } + break; + case CT_RODATA_CHRINFO: + break; + case CT_RODATA_POSITION: + break; + case CT_RODATA_GUNDL: + struct n64_modelrodata_gundl *src_gundl = src_thing; + setMarker(PD_BE32(src_gundl->ptr_opagdl), CT_GDL, marker->src_offset); + setMarker(PD_BE32(src_gundl->ptr_xlugdl), CT_GDL, marker->src_offset); + setMarker(PD_BE32(src_gundl->ptr_vertices), CT_VTXCOL, marker->src_offset); + break; + case CT_RODATA_DISTANCE: + struct n64_modelrodata_distance *src_dist = src_thing; + setMarker(PD_BE32(src_dist->ptr_target), CT_NODE, marker->src_offset); + break; + case CT_RODATA_REORDER: + struct n64_modelrodata_reorder *src_reorder = src_thing; + setMarker(PD_BE32(src_reorder->ptr_node_unk18), CT_NODE, marker->src_offset); + setMarker(PD_BE32(src_reorder->ptr_node_unk1c), CT_NODE, marker->src_offset); + break; + case CT_RODATA_CHRGUNFIRE: + struct n64_modelrodata_chrgunfire *src_chrgunfire = src_thing; + setMarker(PD_BE32(src_chrgunfire->ptr_texture), CT_TEXCONFIG, marker->src_offset); + break; + case CT_RODATA_TOGGLE: + struct n64_modelrodata_toggle *src_toggle = src_thing; + setMarker(PD_BE32(src_toggle->ptr_target), CT_NODE, marker->src_offset); + break; + case CT_RODATA_STARGUNFIRE: + struct n64_modelrodata_stargunfire *src_stargunfire = src_thing; + colstart = PD_BE32(src_stargunfire->unk00)*4*(sizeof(s16) * 6); + u32 vtxstart = PD_BE32(src_stargunfire->ptr_vertices); + u32 vtxend = vtxstart + colstart; + colstart = ALIGN8(vtxstart + colstart); + setMarker(vtxstart, CT_VTXCOL4, marker->src_offset); + if (vtxend != colstart) { + setMarker(vtxend, CT_SKIP, marker->src_offset); + } + setMarker(colstart, CT_VTXCOL, marker->src_offset); + setMarker(PD_BE32(src_stargunfire->ptr_gdl), CT_GDL, marker->src_offset); + break; + case CT_RODATA_DL: + struct n64_modelrodata_dl *src_dl = src_thing; + setMarker(PD_BE32(src_dl->ptr_opagdl), CT_GDL, marker->src_offset); + setMarker(PD_BE32(src_dl->ptr_xlugdl), CT_GDL, marker->src_offset); + setMarker(PD_BE32(src_dl->ptr_colours), CT_VTXCOL, marker->src_offset); + setMarker(PD_BE32(src_dl->ptr_vertices), CT_VTXCOL, marker->src_offset); + break; + case CT_TEXDATA: + case CT_VTXCOL: + case CT_GDL: + case CT_RODATA_BBOX: + case CT_RODATA_11: + case CT_RODATA_POSITIONHELD: + case CT_RODATA_HEADSPOT: + case CT_RODATA_19: + break; + default: + break; + } + } +} + +static void sortMarkers(void) +{ + for (int i = 0; i < numContentMarkers - 1; i++) { + u32 min_offset = 0xffffffff; + int min_index = -1; + + for (int j = i + 1; j < numContentMarkers; j++) { + if (contentMarkers[j].src_offset < min_offset) { + min_offset = contentMarkers[j].src_offset; + min_index = j; + } + } + + if (min_index >= 0 && contentMarkers[min_index].src_offset < contentMarkers[i].src_offset) { + struct marker tmp = contentMarkers[i]; + contentMarkers[i] = contentMarkers[min_index]; + contentMarkers[min_index] = tmp; + } + } +} + +static u32 convertContent(u8 *dst, u8 *src, u32 src_file_len) +{ + u32 dstpos = 0; + + for (int i = 0; i < numContentMarkers; i++) { + struct marker *marker = &contentMarkers[i]; + void *src_thing = &src[marker->src_offset]; + u32 src_end = i < numContentMarkers - 1 ? contentMarkers[i + 1].src_offset : src_file_len; + u32 src_len = src_end - marker->src_offset; + + dstpos = PD_ALIGN(dstpos, alignConfigs[marker->type].before); + + marker->dst_offset = dstpos; + void *dst_thing = &dst[dstpos]; + + switch (marker->type) { + case CT_MODELDEF: + struct n64_modeldef *src_modeldef = src_thing; + struct modeldef *dst_modeldef = dst_thing; + dst_modeldef->skel = (void *)(uintptr_t)PD_BE32(src_modeldef->ptr_skel); + dst_modeldef->numparts = PD_BE16(src_modeldef->numparts); + dst_modeldef->nummatrices = PD_BE16(src_modeldef->nummatrices); + dst_modeldef->scale = PD_BE32(src_modeldef->scale); + dst_modeldef->rwdatalen = PD_BE16(src_modeldef->rwdatalen); + dst_modeldef->numtexconfigs = PD_BE16(src_modeldef->numtexconfigs); + dstpos += sizeof(*dst_modeldef); + break; + case CT_NODE: + struct n64_modelnode *src_node = src_thing; + struct modelnode *dst_node = dst_thing; + dst_node->type = PD_BE16(src_node->type); + dstpos += sizeof(*dst_node); + break; + case CT_TEXCONFIG: + struct n64_textureconfig *src_texconfig = src_thing; + struct textureconfig *dst_texconfig = dst_thing; + + while (src_len >= sizeof(*src_texconfig)) { + if ((PD_BE32(src_texconfig->ptr) & 0xff000000) != 0x05000000) { + dst_texconfig->textureptr = (void *)(uintptr_t)PD_BE32(src_texconfig->ptr); + } + + dst_texconfig->width = src_texconfig->width; + dst_texconfig->height = src_texconfig->height; + dst_texconfig->level = src_texconfig->level; + dst_texconfig->format = src_texconfig->format; + dst_texconfig->depth = src_texconfig->depth; + dst_texconfig->s = src_texconfig->s; + dst_texconfig->t = src_texconfig->t; + dst_texconfig->unk0b = src_texconfig->unk0b; + + dstpos += sizeof(*dst_texconfig); + src_len -= sizeof(*src_texconfig); + src_texconfig++; + dst_texconfig++; + } + break; + case CT_TEXDATA: + memcpy(dst_thing, src_thing, src_len); + dstpos += src_len; + break; + case CT_PARTS: + struct n64_modeldef *src_modeldef2 = (struct n64_modeldef *) src; + u32 *src_parts = (u32 *) src_thing; + uintptr_t *dst_parts = (uintptr_t *) dst_thing; + int num_parts = PD_BE16(src_modeldef2->numparts); + u16 *src_nums = (u16 *) &src_parts[num_parts]; + u16 *dst_nums = (u16 *) &dst_parts[num_parts]; + + for (int i = 0; i < num_parts; i++) { + dst_nums[i] = PD_BE16(src_nums[i]); + } + dstpos += num_parts * sizeof(uintptr_t) + num_parts * sizeof(u16); + if (num_parts) { + dstpos = ALIGN8(dstpos); + } + break; + case CT_VTXCOL: + case CT_VTXCOL4: + memcpy(dst_thing, src_thing, src_len); + dstpos += src_len; + break; + case CT_GDL: + struct marker *parent = findMarker(marker->parent_src_offset); + u32 src_vtx; + u32 dst_vtx; + + if (parent->type == CT_RODATA_GUNDL) { + struct n64_modelrodata_gundl *src_rodata = (struct n64_modelrodata_gundl *) &src[parent->src_offset]; + struct modelrodata_gundl *dst_rodata = (struct modelrodata_gundl *) &dst[parent->dst_offset]; + src_vtx = PD_BE32(src_rodata->ptr_vertices) & 0x00ffffff; + dst_vtx = ((uintptr_t)dst_rodata->vertices) & 0x00ffffff; + } else if (parent->type == CT_RODATA_STARGUNFIRE) { + struct n64_modelrodata_stargunfire *src_rodata = (struct n64_modelrodata_stargunfire *) &src[parent->src_offset]; + struct modelrodata_stargunfire *dst_rodata = (struct modelrodata_stargunfire *) &dst[parent->dst_offset]; + src_vtx = PD_BE32(src_rodata->ptr_vertices) & 0x00ffffff; + dst_vtx = ((uintptr_t)dst_rodata->vertices) & 0x00ffffff; + } else if (parent->type == CT_RODATA_DL) { + struct n64_modelrodata_dl *src_rodata = (struct n64_modelrodata_dl *) &src[parent->src_offset]; + struct modelrodata_dl *dst_rodata = (struct modelrodata_dl *) &dst[parent->dst_offset]; + src_vtx = PD_BE32(src_rodata->ptr_vertices) & 0x00ffffff; + dst_vtx = ((uintptr_t)dst_rodata->vertices) & 0x00ffffff; + } + + dstpos = gbiConvertGdl(dst, dstpos, src, marker->src_offset, 0); + break; + case CT_RODATA_CHRINFO: + struct modelrodata_chrinfo *src_chrinfo = src_thing; + struct modelrodata_chrinfo *dst_chrinfo = dst_thing; + dst_chrinfo->animpart = PD_BE16(src_chrinfo->animpart); + dst_chrinfo->mtxindex = PD_BE16(src_chrinfo->mtxindex); + dst_chrinfo->unk04 = PD_BE32(src_chrinfo->unk04); + dst_chrinfo->rwdataindex = PD_BE16(src_chrinfo->rwdataindex); + dstpos += sizeof(*dst_chrinfo); + break; + case CT_RODATA_POSITION: + struct modelrodata_position *src_position = src_thing; + struct modelrodata_position *dst_position = dst_thing; + dst_position->pos = PD_SWAPPED_VAL(src_position->pos); + dst_position->part = PD_BE16(src_position->part); + dst_position->mtxindexes[0] = PD_BE16(src_position->mtxindexes[0]); + dst_position->mtxindexes[1] = PD_BE16(src_position->mtxindexes[1]); + dst_position->mtxindexes[2] = PD_BE16(src_position->mtxindexes[2]); + dst_position->drawdist = PD_SWAPPED_VAL(src_position->drawdist); + dstpos += sizeof(*dst_position); + break; + case CT_RODATA_GUNDL: + struct n64_modelrodata_gundl *src_gundl = src_thing; + struct modelrodata_gundl *dst_gundl = dst_thing; + dst_gundl->vertices = NULL; + dst_gundl->numvertices = PD_BE16(src_gundl->numvertices); + dst_gundl->unk12 = PD_BE16(src_gundl->unk12); + dstpos += sizeof(*dst_gundl); + break; + case CT_RODATA_DISTANCE: + struct n64_modelrodata_distance *src_dist = src_thing; + struct modelrodata_distance *dst_dist = dst_thing; + dst_dist->near = PD_SWAPPED_VAL(src_dist->near); + dst_dist->far = PD_SWAPPED_VAL(src_dist->far); + dst_dist->rwdataindex = PD_BE16(src_dist->rwdataindex); + dstpos += sizeof(*dst_dist); + break; + case CT_RODATA_REORDER: + struct n64_modelrodata_reorder *src_reorder = src_thing; + struct modelrodata_reorder *dst_reorder = dst_thing; + dst_reorder->unk00 = PD_SWAPPED_VAL(src_reorder->unk00); + dst_reorder->unk04 = PD_SWAPPED_VAL(src_reorder->unk04); + dst_reorder->unk08 = PD_SWAPPED_VAL(src_reorder->unk08); + dst_reorder->unk0c[0] = PD_SWAPPED_VAL(src_reorder->unk0c[0]); + dst_reorder->unk0c[1] = PD_SWAPPED_VAL(src_reorder->unk0c[1]); + dst_reorder->unk0c[2] = PD_SWAPPED_VAL(src_reorder->unk0c[2]); + dst_reorder->side = PD_BE16(src_reorder->side); + dst_reorder->rwdataindex = PD_BE16(src_reorder->rwdataindex); + dstpos += sizeof(*dst_reorder); + break; + case CT_RODATA_BBOX: + struct modelrodata_bbox *src_bbox = src_thing; + struct modelrodata_bbox *dst_bbox = dst_thing; + dst_bbox->hitpart = PD_BE32(src_bbox->hitpart); + dst_bbox->xmin = PD_SWAPPED_VAL(src_bbox->xmin); + dst_bbox->xmax = PD_SWAPPED_VAL(src_bbox->xmax); + dst_bbox->ymin = PD_SWAPPED_VAL(src_bbox->ymin); + dst_bbox->ymax = PD_SWAPPED_VAL(src_bbox->ymax); + dst_bbox->zmin = PD_SWAPPED_VAL(src_bbox->zmin); + dst_bbox->zmax = PD_SWAPPED_VAL(src_bbox->zmax); + dstpos += sizeof(*dst_bbox); + break; + case CT_RODATA_CHRGUNFIRE: + struct n64_modelrodata_chrgunfire *src_chrgunfire = src_thing; + struct modelrodata_chrgunfire *dst_chrgunfire = dst_thing; + dst_chrgunfire->pos = PD_SWAPPED_VAL(src_chrgunfire->pos); + dst_chrgunfire->dim = PD_SWAPPED_VAL(src_chrgunfire->dim); + dst_chrgunfire->unk1c = PD_SWAPPED_VAL(src_chrgunfire->unk1c); + dst_chrgunfire->rwdataindex = PD_BE16(src_chrgunfire->rwdataindex); + dst_chrgunfire->baseaddr = NULL; + dstpos += sizeof(*dst_chrgunfire); + break; + case CT_RODATA_11: + struct n64_modelrodata_type11 *src_type11 = src_thing; + struct modelrodata_type11 *dst_type11 = dst_thing; + dst_type11->unk00 = PD_BE32(src_type11->unk00); + dst_type11->unk04 = PD_BE32(src_type11->unk04); + dst_type11->unk08 = PD_BE32(src_type11->unk08); + dst_type11->unk0c = PD_BE32(src_type11->unk0c); + dst_type11->unk10 = PD_BE32(src_type11->unk10); + dst_type11->unk14 = NULL; + dst_type11->unk18 = PD_BE32(src_type11->extra1); + dst_type11->unk1c = PD_BE32(src_type11->extra2); + dstpos += sizeof(*dst_type11); + break; + case CT_RODATA_TOGGLE: + struct n64_modelrodata_toggle *src_toggle = src_thing; + struct modelrodata_toggle *dst_toggle = dst_thing; + dst_toggle->rwdataindex = PD_BE16(src_toggle->rwdataindex); + dstpos += sizeof(*dst_toggle); + break; + case CT_RODATA_POSITIONHELD: + struct modelrodata_positionheld *src_posheld = src_thing; + struct modelrodata_positionheld *dst_posheld = dst_thing; + dst_posheld->pos = PD_SWAPPED_VAL(src_posheld->pos); + dst_posheld->mtxindex = PD_BE16(src_posheld->mtxindex); + dst_posheld->unk10 = PD_BE32(src_posheld->unk10); + dstpos += sizeof(*dst_posheld); + break; + case CT_RODATA_STARGUNFIRE: + struct n64_modelrodata_stargunfire *src_stargunfire = src_thing; + struct modelrodata_stargunfire *dst_stargunfire = dst_thing; + dst_stargunfire->unk00 = PD_BE32(src_stargunfire->unk00); + dstpos += sizeof(*dst_stargunfire); + break; + case CT_RODATA_HEADSPOT: + struct modelrodata_headspot *src_headspot = src_thing; + struct modelrodata_headspot *dst_headspot = dst_thing; + dst_headspot->rwdataindex = PD_BE16(src_headspot->rwdataindex); + dstpos += sizeof(*dst_headspot); + break; + case CT_RODATA_DL: + struct n64_modelrodata_dl *src_dl = src_thing; + struct modelrodata_dl *dst_dl = dst_thing; + dst_dl->numvertices = PD_BE16(src_dl->numvertices); + dst_dl->mcount = PD_BE16(src_dl->mcount); + dst_dl->rwdataindex = PD_BE16(src_dl->rwdataindex); + dst_dl->numcolours = PD_BE16(src_dl->numcolours); + dstpos += sizeof(*dst_dl); + break; + case CT_RODATA_19: + struct modelrodata_type19 *src_type19 = src_thing; + struct modelrodata_type19 *dst_type19 = dst_thing; + u32 *src_vertices = src_thing + sizeof(u32); + u32 *dst_vertices = dst_thing + sizeof(u32); + int num_vertices = PD_BE32(src_type19->numvertices); + + dst_type19->numvertices = (num_vertices); + dstpos += sizeof(u32); + + for (int i = 0; i < num_vertices; i++) { + dst_vertices[i * 3 + 0] = PD_BE32(src_vertices[i * 3 + 0]); + dst_vertices[i * 3 + 1] = PD_BE32(src_vertices[i * 3 + 1]); + dst_vertices[i * 3 + 2] = PD_BE32(src_vertices[i * 3 + 2]); + dstpos += sizeof(u32) * 3; + } + break; + case CT_SKIP: + break; + } + + dstpos = PD_ALIGN(dstpos, alignConfigs[marker->type].after); + } + + return dstpos; +} + +static u32 resolvePointer(u32 src_offset) +{ + if (src_offset == 0) { + return 0; + } + + struct marker *marker = findMarker(src_offset & 0x00ffffff); + return marker ? (0x05000000 | marker->dst_offset) : 0; +} + +static u8 *relinkPointers(u8 *dst, u8 *src) +{ + uintptr_t textures_end = 0; + + for (int i = 0; i < numContentMarkers; i++) { + struct marker *marker = &contentMarkers[i]; + void *src_thing = &src[marker->src_offset]; + void *dst_thing = &dst[marker->dst_offset]; + + uintptr_t lowestptr = 0; + + switch (marker->type) { + case CT_MODELDEF: + struct n64_modeldef *src_modeldef = src_thing; + struct modeldef *dst_modeldef = dst_thing; + dst_modeldef->rootnode = (void *)(uintptr_t)resolvePointer(PD_BE32(src_modeldef->ptr_rootnode)); + dst_modeldef->parts = (void *)(uintptr_t)resolvePointer(PD_BE32(src_modeldef->ptr_parts)); + dst_modeldef->texconfigs = (void *)(uintptr_t)resolvePointer(PD_BE32(src_modeldef->ptr_texconfigs)); + break; + case CT_NODE: + struct n64_modelnode *src_node = src_thing; + struct modelnode *dst_node = dst_thing; + dst_node->rodata = (void *)(uintptr_t)resolvePointer(PD_BE32(src_node->ptr_rodata)); + dst_node->parent = (void *)(uintptr_t)resolvePointer(PD_BE32(src_node->ptr_parent)); + dst_node->next = (void *)(uintptr_t)resolvePointer(PD_BE32(src_node->ptr_next)); + dst_node->prev = (void *)(uintptr_t)resolvePointer(PD_BE32(src_node->ptr_prev)); + dst_node->child = (void *)(uintptr_t)resolvePointer(PD_BE32(src_node->ptr_child)); + + lowestptr = (uintptr_t)dst_node->rodata; + break; + case CT_TEXCONFIG: + struct n64_textureconfig *src_texconfig = src_thing; + struct textureconfig *dst_texconfig = dst_thing; + if ((PD_BE32(src_texconfig->ptr) & 0xff000000) == 0x05000000) { + dst_texconfig->textureptr = (void *)(uintptr_t)resolvePointer(PD_BE32(src_texconfig->ptr)); + gbiAddTexAddr(PD_BE32(src_texconfig->ptr), (uintptr_t)dst_texconfig->textureptr); + } + break; + case CT_PARTS: + struct n64_modeldef *src_modeldef2 = (struct n64_modeldef *) src; + u32 *src_parts = (u32 *) src_thing; + uintptr_t *dst_parts = (uintptr_t *) dst_thing; + int num_parts = PD_BE16(src_modeldef2->numparts); + + for (int i = 0; i < num_parts; i++) { + dst_parts[i] = (resolvePointer(PD_BE32(src_parts[i]))); + } + break; + case CT_RODATA_CHRINFO: + break; + case CT_RODATA_POSITION: + break; + case CT_RODATA_GUNDL: + struct n64_modelrodata_gundl *src_gundl = src_thing; + struct modelrodata_gundl *dst_gundl = dst_thing; + dst_gundl->opagdl = (void *)(uintptr_t)resolvePointer(PD_BE32(src_gundl->ptr_opagdl)); + dst_gundl->xlugdl = (void *)(uintptr_t)resolvePointer(PD_BE32(src_gundl->ptr_xlugdl)); + dst_gundl->vertices = (void *)(uintptr_t)resolvePointer(PD_BE32(src_gundl->ptr_vertices)); + + gbiConvertVtx(dst, ((uintptr_t)dst_gundl->vertices) & 0x00ffffff, dst_gundl->numvertices); + + gbiSetVtx(PD_BE32(src_gundl->ptr_vertices), (uintptr_t)dst_gundl->vertices); + gbiSetSegment(0x04, (uintptr_t)dst_gundl->vertices); + + gbiGdlRewriteAddrs(dst, (uintptr_t)dst_gundl->opagdl); + gbiGdlRewriteAddrs(dst, (uintptr_t)dst_gundl->xlugdl); + + if (dst_gundl->opagdl) dst_gundl->opagdl = SEGADDR(dst_gundl->opagdl); + if (dst_gundl->xlugdl) dst_gundl->xlugdl = SEGADDR(dst_gundl->xlugdl); + + lowestptr = minPtr3((uintptr_t)dst_gundl->opagdl, (uintptr_t)dst_gundl->xlugdl, (uintptr_t)dst_gundl->vertices); + break; + case CT_RODATA_DISTANCE: + struct n64_modelrodata_distance *src_dist = src_thing; + struct modelrodata_distance *dst_dist = dst_thing; + dst_dist->target = (void *)(uintptr_t)resolvePointer(PD_BE32(src_dist->ptr_target)); + break; + case CT_RODATA_REORDER: + struct n64_modelrodata_reorder *src_reorder = src_thing; + struct modelrodata_reorder *dst_reorder = dst_thing; + dst_reorder->unk18 = (void *)(uintptr_t)resolvePointer(PD_BE32(src_reorder->ptr_node_unk18)); + dst_reorder->unk1c = (void *)(uintptr_t)resolvePointer(PD_BE32(src_reorder->ptr_node_unk1c)); + break; + case CT_RODATA_CHRGUNFIRE: + struct n64_modelrodata_chrgunfire *src_chrgunfire = src_thing; + struct modelrodata_chrgunfire *dst_chrgunfire = dst_thing; + dst_chrgunfire->texture = (void *)(uintptr_t)resolvePointer(PD_BE32(src_chrgunfire->ptr_texture)); + if ((PD_BE32((u32)(uintptr_t)dst_chrgunfire->texture) & 0xff000000) == 0x05000000) { + gbiAddTexAddr(PD_BE32((u32)(uintptr_t)dst_chrgunfire->texture), (uintptr_t)dst_chrgunfire->texture); + } + break; + case CT_RODATA_TOGGLE: + struct n64_modelrodata_toggle *src_toggle = src_thing; + struct modelrodata_toggle *dst_toggle = dst_thing; + dst_toggle->target = (void *)(uintptr_t)resolvePointer(PD_BE32(src_toggle->ptr_target)); + break; + case CT_RODATA_STARGUNFIRE: + struct n64_modelrodata_stargunfire *src_stargunfire = src_thing; + struct modelrodata_stargunfire *dst_stargunfire = dst_thing; + dst_stargunfire->vertices = (void *)(uintptr_t)resolvePointer(PD_BE32(src_stargunfire->ptr_vertices)); + dst_stargunfire->gdl = (void *)(uintptr_t)resolvePointer(PD_BE32(src_stargunfire->ptr_gdl)); + + gbiConvertVtx(dst, ((uintptr_t)dst_stargunfire->vertices) & 0x00ffffff, dst_stargunfire->unk00*4); + + gbiSetVtx(PD_BE32(src_stargunfire->ptr_vertices), (uintptr_t)dst_stargunfire->vertices); + gbiSetSegment(0x04, (uintptr_t)dst_stargunfire->vertices); + gbiGdlRewriteAddrs(dst, (uintptr_t)dst_stargunfire->gdl); + if (dst_stargunfire->gdl) dst_stargunfire->gdl = SEGADDR(dst_stargunfire->gdl); + + lowestptr = minPtr((uintptr_t)dst_stargunfire->gdl, (uintptr_t)dst_stargunfire->vertices); + break; + case CT_RODATA_DL: + struct n64_modelrodata_dl *src_dl = src_thing; + struct modelrodata_dl *dst_dl = dst_thing; + dst_dl->opagdl = (void *)(uintptr_t)resolvePointer(PD_BE32(src_dl->ptr_opagdl)); + dst_dl->xlugdl = (void *)(uintptr_t)resolvePointer(PD_BE32(src_dl->ptr_xlugdl)); + dst_dl->colours = (void *)(uintptr_t)resolvePointer(PD_BE32(src_dl->ptr_colours)); + dst_dl->vertices = (void *)(uintptr_t)resolvePointer(PD_BE32(src_dl->ptr_vertices)); + + gbiConvertVtx(dst, ((uintptr_t)dst_dl->vertices) & 0x00ffffff, dst_dl->numvertices); + + gbiSetVtx(PD_BE32(src_dl->ptr_vertices), (uintptr_t)dst_dl->vertices); + gbiSetSegment(0x04, (uintptr_t)dst_dl->vertices); + gbiGdlRewriteAddrs(dst, (uintptr_t)dst_dl->opagdl); + gbiGdlRewriteAddrs(dst, (uintptr_t)dst_dl->xlugdl); + + if (dst_dl->opagdl) dst_dl->opagdl = SEGADDR(dst_dl->opagdl); + if (dst_dl->xlugdl) dst_dl->xlugdl = SEGADDR(dst_dl->xlugdl); + + lowestptr = minPtr3((uintptr_t)dst_dl->opagdl, (uintptr_t)dst_dl->xlugdl, (uintptr_t)dst_dl->colours); + lowestptr = minPtr(lowestptr, (uintptr_t)dst_dl->vertices); + break; + case CT_TEXDATA: + case CT_VTXCOL: + case CT_VTXCOL4: + case CT_GDL: + case CT_RODATA_BBOX: + case CT_RODATA_11: + case CT_RODATA_POSITIONHELD: + case CT_RODATA_HEADSPOT: + case CT_RODATA_19: + default: + break; + } + + textures_end = minPtr(textures_end, lowestptr); + } + + return (u8*)textures_end; +} + +static void preprocessTextureRGBA32Embedded(u32* dest, u32 size_bytes) +{ + for (uint32_t i = 0; i < size_bytes; i += 4, ++dest) { + *dest = PD_BE32(*dest); + } +} + +static void preprocessModelTextures(u8 *base, u8 *textures_end) +{ + struct modeldef* mdl = (struct modeldef*)base; + if (!mdl->texconfigs) return; + + u32 ofs = 0x5000000; + struct textureconfig* texconfigs = PD_PTR_BASEOFS(mdl->texconfigs, base, ofs); + for (s16 i = 0; i < mdl->numtexconfigs; ++i) { + if ((texconfigs[i].texturenum & 0xf000000) == 0x5000000) { + // embedded texture; we need to unswizzle this + u8* texdata = PD_PTR_BASEOFS(texconfigs[i].textureptr, base, ofs); + // figure out the max possible size the texture can have, because sometimes the texconfig is wrong + const u32 maxSize = (textures_end > texconfigs[i].textureptr) ? (textures_end - texconfigs[i].textureptr) : 0; + // figure out the format and unswizzle + const s32 format = texConfigToFormat(&texconfigs[i]); + texSwizzleInternal(texdata, texconfigs[i].width, texconfigs[i].height, format, maxSize); + + if (format == TEXFORMAT_RGBA32) { + // for some reason, RGBA32 embedded textures don't need to be byte-swapped, + // so we byte-swap them here, which will be undone when the renderer imports it + u32 size_bytes = texconfigs[i].width * texconfigs[i].height * 4; + preprocessTextureRGBA32Embedded((u32*)texdata, size_bytes); + } + } + } +} + +static int convertModel(u8* dst, u8* src, u32 srclen) +{ + u32 dstpos; + + populateMarkers(src); + sortMarkers(); + + dstpos = convertContent(dst, src, srclen); + u8* tex_end = relinkPointers(dst, src); + preprocessModelTextures(dst, tex_end); + + return dstpos; +} + +u8 *preprocessModelFile(u8 *data, u32 size, u32 *outSize) +{ + gbiReset(); + + u32 newSizeEstimated = romdataFileGetEstimatedSize(size, LOADTYPE_MODEL); + u8 *dst = sysMemZeroAlloc(newSizeEstimated); + + u32 newSize = convertModel(dst, data, size); + + if (newSize > newSizeEstimated) { + sysFatalError("overflow when trying to preprocess model, size %d newsize %d", size, newSize); + } + + memcpy(data, dst, newSize); + sysMemFree(dst); + + *outSize = newSize; + + return 0; +} + +u8 *preprocessGunFile(u8 *data, u32 size, u32 *outSize) +{ + gbiReset(); + + u32 newSizeEstimated = romdataFileGetEstimatedSize(size, LOADTYPE_MODEL); + u8 *dst = sysMemZeroAlloc(newSizeEstimated+128); + + u32 newSize = convertModel(dst, data, size); + + if (newSize > newSizeEstimated) { + sysFatalError("overflow when trying to preprocess model, size %d newsize %d", size, newSize); + } + + memcpy(data, dst, newSize); + sysMemFree(dst); + + *outSize = newSize; + + return 0; +} diff --git a/port/src/preprocess/filepads.c b/port/src/preprocess/filepads.c new file mode 100644 index 000000000..1ba7e59d2 --- /dev/null +++ b/port/src/preprocess/filepads.c @@ -0,0 +1,293 @@ +#include +#include +#include + +#include "preprocess/common.h" + +#include "constants.h" + +struct n64_header { + s32 num_pads; + s32 num_covers; + u32 ptr_waypoints; + u32 ptr_waygroups; + u32 ptr_cover; +}; + +struct host_header { + s32 num_pads; + s32 num_covers; + uintptr_t ptr_waypoints; + uintptr_t ptr_waygroups; + uintptr_t ptr_cover; +}; + +struct padheader { + u32 flags : 18; + u32 room : 10; + u32 liftnum : 4; +}; + +struct n64_waypoint { + s32 padnum; + u32 ptr_neighbours; + s32 groupnum; + s32 step; +}; + +struct n64_waygroup { + u32 ptr_neighbours; + u32 ptr_waypoints; + s32 step; +}; + +static u32 convertPads(u8 *dst, u32 dstpos, u8 *src, u32 srcpos, int num_pads) +{ + u16 *src_offsets = (u16 *) &src[srcpos]; + u16 *dst_offsets = (u16 *) &dst[dstpos]; + + dstpos += num_pads * sizeof(u16); + + for (int i = 0; i < num_pads; i++) { + srcpos = PD_BE16(src_offsets[i]); + + dst_offsets[i] = (dstpos); + + // Header + u32 n64_padheader = PD_BE32(*(u32 *) &src[srcpos]); + struct padheader *host_padheader = (struct padheader *) &dst[dstpos]; + u32 flags = (n64_padheader >> 14) & 0x3ffff; + + *(u32*)host_padheader = (n64_padheader); + + srcpos += sizeof(struct padheader); + dstpos += sizeof(struct padheader); + + // Position + if (flags & PADFLAG_INTPOS) { + s16 *srcptr = (s16 *) &src[srcpos]; + s16 *dstptr = (s16 *) &dst[dstpos]; + + dstptr[0] = PD_BE16(srcptr[0]); + dstptr[1] = PD_BE16(srcptr[1]); + dstptr[2] = PD_BE16(srcptr[2]); + + srcpos += 8; + dstpos += 8; + } else { + u32 *srcptr = (u32 *) &src[srcpos]; + u32 *dstptr = (u32 *) &dst[dstpos]; + + dstptr[0] = PD_BE32(srcptr[0]); + dstptr[1] = PD_BE32(srcptr[1]); + dstptr[2] = PD_BE32(srcptr[2]); + + srcpos += 12; + dstpos += 12; + } + + // Up + if ((flags & (PADFLAG_UPALIGNTOX | PADFLAG_UPALIGNTOY | PADFLAG_UPALIGNTOZ)) == 0) { + u32 *srcptr = (u32 *) &src[srcpos]; + u32 *dstptr = (u32 *) &dst[dstpos]; + + dstptr[0] = PD_BE32(srcptr[0]); + dstptr[1] = PD_BE32(srcptr[1]); + dstptr[2] = PD_BE32(srcptr[2]); + + srcpos += 12; + dstpos += 12; + } + + // Look + if ((flags & (PADFLAG_LOOKALIGNTOX | PADFLAG_LOOKALIGNTOY | PADFLAG_LOOKALIGNTOZ)) == 0) { + u32 *srcptr = (u32 *) &src[srcpos]; + u32 *dstptr = (u32 *) &dst[dstpos]; + + dstptr[0] = PD_BE32(srcptr[0]); + dstptr[1] = PD_BE32(srcptr[1]); + dstptr[2] = PD_BE32(srcptr[2]); + + srcpos += 12; + dstpos += 12; + } + + // Bbox + if (flags & PADFLAG_HASBBOXDATA) { + u32 *srcptr = (u32 *) &src[srcpos]; + u32 *dstptr = (u32 *) &dst[dstpos]; + + dstptr[0] = PD_BE32(srcptr[0]); + dstptr[1] = PD_BE32(srcptr[1]); + dstptr[2] = PD_BE32(srcptr[2]); + dstptr[3] = PD_BE32(srcptr[3]); + dstptr[4] = PD_BE32(srcptr[4]); + dstptr[5] = PD_BE32(srcptr[5]); + + srcpos += 4 * 6; + dstpos += 4 * 6; + } + } + + return dstpos; +} + +static u32 convertWayPoints(u8 *dst, u32 dstpos, u8 *src, u32 srcpos) +{ + struct n64_waypoint *n64_waypoints = (struct n64_waypoint *) &src[srcpos]; + struct waypoint *host_waypoints = (struct waypoint *) &dst[dstpos]; + int num_waypoints; + + for (num_waypoints = 0; n64_waypoints[num_waypoints].padnum != -1; num_waypoints++); + + dstpos += (num_waypoints + 1) * sizeof(struct waypoint); + + u32 *host_neighbours = (u32 *) &dst[dstpos]; + int n = 0; + + for (int i = 0; i < num_waypoints; i++) { + host_waypoints[i].padnum = PD_BE32(n64_waypoints[i].padnum); + host_waypoints[i].neighbours = (void *)(uintptr_t)dstpos; + host_waypoints[i].groupnum = PD_BE32(n64_waypoints[i].groupnum); + host_waypoints[i].step = 0; + + u32 *n64_neighbours = (u32 *) &src[PD_BE32(n64_waypoints[i].ptr_neighbours)]; + + for (int j = 0; n64_neighbours[j] != 0xffffffff; j++) { + host_neighbours[n++] = PD_BE32(n64_neighbours[j]); + dstpos += 4; + } + + host_neighbours[n++] = 0xffffffff; + dstpos += 4; + } + + // Terminator + host_waypoints[num_waypoints].padnum = 0xffffffff; + host_waypoints[num_waypoints].neighbours = NULL; + host_waypoints[num_waypoints].groupnum = 0; + host_waypoints[num_waypoints].step = 0; + + return dstpos; +} + +static u32 convertWayGroups(u8 *dst, u32 dstpos, u8 *src, u32 srcpos) +{ + struct n64_waygroup *n64_waygroups = (struct n64_waygroup *) &src[srcpos]; + struct waygroup *host_waygroups = (struct waygroup *) &dst[dstpos]; + int num_waygroups; + + for (num_waygroups = 0; n64_waygroups[num_waygroups].ptr_neighbours != 0; num_waygroups++); + + dstpos += (num_waygroups + 1) * sizeof(struct waygroup); + + // Waygroups and child waypoints + u32 *host_waypoints = (u32 *) &dst[dstpos]; + int n = 0; + + for (int i = 0; i < num_waygroups; i++) { + host_waygroups[i].waypoints = (void *)(uintptr_t)dstpos; + host_waygroups[i].step = 0; + + u32 *n64_waypoints = (u32 *) &src[PD_BE32(n64_waygroups[i].ptr_waypoints)]; + + for (int j = 0; n64_waypoints[j] != 0xffffffff; j++) { + host_waypoints[n++] = PD_BE32(n64_waypoints[j]); + dstpos += 4; + } + + host_waypoints[n++] = 0xffffffff; + dstpos += 4; + } + + // Terminator + host_waygroups[num_waygroups].neighbours = NULL; + host_waygroups[num_waygroups].waypoints = NULL; + host_waygroups[num_waygroups].step = 0; + + // Waygroup neighbours + u32 *host_neighbours = (u32 *) &dst[dstpos]; + n = 0; + + for (int i = 0; i < num_waygroups; i++) { + host_waygroups[i].neighbours = (void *)(uintptr_t)dstpos; + + u32 *n64_neighbours = (u32 *) &src[PD_BE32(n64_waygroups[i].ptr_neighbours)]; + + for (int j = 0; n64_neighbours[j] != 0xffffffff; j++) { + host_neighbours[n++] = PD_BE32(n64_neighbours[j]); + dstpos += 4; + } + + host_neighbours[n++] = 0xffffffff; + dstpos += 4; + } + + return dstpos; +} + +static u32 convertCover(u8 *dst, u32 dstpos, u8 *src, u32 srcpos, int num_covers) +{ + struct coverdefinition *n64_covers = (struct coverdefinition *) &src[srcpos]; + struct coverdefinition *host_covers = (struct coverdefinition *) &dst[dstpos]; + + for (int i = 0; i < num_covers; i++) { + host_covers[i].pos = PD_SWAPPED_VAL(n64_covers[i].pos); + host_covers[i].look = PD_SWAPPED_VAL(n64_covers[i].look); + host_covers[i].flags = PD_BE16(n64_covers[i].flags); + host_covers[i].unk1a = PD_BE16(n64_covers[i].unk1a); + } + + dstpos += num_covers * sizeof(struct coverdefinition); + + return dstpos; +} + +static u32 convertPadsFile(u8 *dst, u8 *src) +{ + u32 dstpos = 0; + struct n64_header *n64_header = (struct n64_header *) src; + struct host_header *host_header = (struct host_header *) dst; + + int num_pads = PD_BE32(n64_header->num_pads); + int num_covers = PD_BE32(n64_header->num_covers); + host_header->num_pads = (num_pads); + host_header->num_covers = (num_covers); + + dstpos += sizeof(struct host_header); + + // Pads + dstpos = convertPads(dst, dstpos, src, sizeof(struct n64_header), num_pads); + + // Waypoints + host_header->ptr_waypoints = (dstpos); + dstpos = convertWayPoints(dst, dstpos, src, PD_BE32(n64_header->ptr_waypoints)); + + // Waygroups + host_header->ptr_waygroups = (dstpos); + dstpos = convertWayGroups(dst, dstpos, src, PD_BE32(n64_header->ptr_waygroups)); + + // Cover + host_header->ptr_cover = (dstpos); + dstpos = convertCover(dst, dstpos, src, PD_BE32(n64_header->ptr_cover), num_covers); + + return dstpos; +} + +u8* preprocessPadsFile(u8 *data, u32 size, u32 *outSize) { + u32 newSizeEstimated = romdataFileGetEstimatedSize(size, LOADTYPE_PADS); + u8* dst = sysMemZeroAlloc(newSizeEstimated); + + u32 newSize = convertPadsFile(dst, data); + + if (newSize > newSizeEstimated) { + sysFatalError("overflow when trying to preprocess a pads file, size %d newsize %d", size, newSize); + } + + memcpy(data, dst, newSize); + sysMemFree(dst); + + *outSize = newSize; + + return 0; +} diff --git a/port/src/preprocess/filesetup.c b/port/src/preprocess/filesetup.c new file mode 100644 index 000000000..5e5ab9cc9 --- /dev/null +++ b/port/src/preprocess/filesetup.c @@ -0,0 +1,1192 @@ +#include +#include +#include + +#include "types.h" + +#include "preprocess/common.h" +#include "preprocess/setup.h" + +extern u32 chraiGetAilistLength(u8 *list); + +static inline void convF32(f32 *dst, f32 src) { *(u32*)dst = PD_BE32(*(u32*)&src); } +static inline void convU32(u32 *dst, u32 src) { *dst = PD_BE32(src); } +static inline void convS32(s32 *dst, s32 src) { *dst = PD_BE32(src); } +static inline void convU16(u16 *dst, u32 src) { *dst = PD_BE16(src); } +static inline void convS16(s16 *dst, s32 src) { *dst = PD_BE16(src); } +static inline void cpyByte(u8 *dst, u8 src) { *dst = src; } +static inline void convCoord(struct coord* dst, struct n64_coord src) { convF32(&dst->x, src.x); convF32(&dst->y, src.y); convF32(&dst->z, src.z); } +static inline void convUnk(u32 x) { assert(0 && "unknown type"); } + +#define PD_CONV_VAL(dst, src) _Generic((dst), \ + f32: convF32, \ + u32: convU32, \ + s32: convS32, \ + u16: convU16, \ + s16: convS16, \ + u8: cpyByte, \ + s8: cpyByte, \ + struct coord: convCoord, \ + default: convUnk \ +)(&dst, src) + +#define PD_CONV_ARRAY(dst, src) { for (int i = 0; i < ARRAYCOUNT(dst); i++) PD_CONV_VAL(dst[i], src[i]); } +#define PD_CONV_ARRAY2D(dst, src) { \ + for (int i = 0; i < ARRAYCOUNT(dst); i++) \ + for (int j = 0; j < ARRAYCOUNT(dst); j++) PD_CONV_VAL(dst[i][j], src[i][j]); \ +} + +#define PD_CONV_PTR(dst, src, type) dst = (type)(uintptr_t)PD_BE32(src) + +static inline u32 objSizeN64(struct n64_defaultobj *obj) +{ + switch (obj->type) { + case OBJTYPE_CHR: return sizeof(struct n64_packedchr) / sizeof(u32); + case OBJTYPE_DOOR: return sizeof(struct n64_doorobj) / sizeof(u32); + case OBJTYPE_DOORSCALE: return sizeof(struct n64_doorscaleobj) / sizeof(u32); + case OBJTYPE_BASIC: return sizeof(struct n64_defaultobj) / sizeof(u32); + case OBJTYPE_DEBRIS: return sizeof(struct n64_debrisobj) / sizeof(u32); + case OBJTYPE_GLASS: return sizeof(struct n64_glassobj) / sizeof(u32); + case OBJTYPE_TINTEDGLASS: return sizeof(struct n64_tintedglassobj) / sizeof(u32); + case OBJTYPE_SAFE: return sizeof(struct n64_safeobj) / sizeof(u32); + case OBJTYPE_GASBOTTLE: return sizeof(struct gasbottleobj) / sizeof(u32); + case OBJTYPE_KEY: return sizeof(struct n64_keyobj) / sizeof(u32); + case OBJTYPE_ALARM: return sizeof(struct n64_alarmobj) / sizeof(u32); + case OBJTYPE_CCTV: return sizeof(struct n64_cctvobj) / sizeof(u32); + case OBJTYPE_AMMOCRATE: return sizeof(struct n64_ammocrateobj) / sizeof(u32); + case OBJTYPE_WEAPON: return sizeof(struct n64_weaponobj) / sizeof(u32); + case OBJTYPE_SINGLEMONITOR: return sizeof(struct n64_singlemonitorobj) / sizeof(u32); + case OBJTYPE_MULTIMONITOR: return sizeof(struct n64_multimonitorobj) / sizeof(u32); + case OBJTYPE_HANGINGMONITORS: return sizeof(struct n64_hangingmonitorsobj) / sizeof(u32); + case OBJTYPE_AUTOGUN: return sizeof(struct n64_autogunobj) / sizeof(u32); + case OBJTYPE_LINKGUNS: return sizeof(struct linkgunsobj) / sizeof(u32); + case OBJTYPE_HAT: return sizeof(struct n64_hatobj) / sizeof(u32); + case OBJTYPE_GRENADEPROB: return sizeof(struct grenadeprobobj) / sizeof(u32); + case OBJTYPE_LINKLIFTDOOR: return sizeof(struct n64_linkliftdoorobj) / sizeof(u32); + case OBJTYPE_SAFEITEM: return sizeof(struct n64_safeitemobj) / sizeof(u32); + case OBJTYPE_MULTIAMMOCRATE: return sizeof(struct n64_multiammocrateobj) / sizeof(u32); + case OBJTYPE_SHIELD: return sizeof(struct n64_shieldobj) / sizeof(u32); + case OBJTYPE_TAG: return sizeof(struct n64_tag) / sizeof(u32); + case OBJTYPE_RENAMEOBJ: return sizeof(struct n64_textoverride) / sizeof(u32); + case OBJTYPE_BEGINOBJECTIVE: return sizeof(struct n64_objective) / sizeof(u32); + case OBJTYPE_ENDOBJECTIVE: return 1; + case OBJECTIVETYPE_DESTROYOBJ: return 2; + case OBJECTIVETYPE_COMPFLAGS: return 2; + case OBJECTIVETYPE_FAILFLAGS: return 2; + case OBJECTIVETYPE_COLLECTOBJ: return 2; + case OBJECTIVETYPE_THROWOBJ: return 2; + case OBJECTIVETYPE_HOLOGRAPH: return sizeof(struct n64_criteria_holograph) / sizeof(u32); + case OBJECTIVETYPE_1F: return 1; + case OBJECTIVETYPE_ENTERROOM: return sizeof(struct n64_criteria_roomentered) / sizeof(u32); + case OBJECTIVETYPE_THROWINROOM: return sizeof(struct n64_criteria_throwinroom) / sizeof(u32); + case OBJTYPE_22: return 1; + case OBJTYPE_BRIEFING: return sizeof(struct n64_briefingobj) / sizeof(u32); + case OBJTYPE_PADLOCKEDDOOR: return sizeof(struct n64_padlockeddoorobj) / sizeof(u32); + case OBJTYPE_TRUCK: return sizeof(struct n64_truckobj) / sizeof(u32); + case OBJTYPE_HELI: return sizeof(struct n64_heliobj) / sizeof(u32); + case OBJTYPE_TANK: return 32; + case OBJTYPE_CAMERAPOS: return sizeof(struct n64_cameraposobj) / sizeof(u32); + case OBJTYPE_LIFT: return sizeof(struct n64_liftobj) / sizeof(u32); + case OBJTYPE_CONDITIONALSCENERY: return sizeof(struct n64_linksceneryobj) / sizeof(u32); + case OBJTYPE_BLOCKEDPATH: return sizeof(struct n64_blockedpathobj) / sizeof(u32); + case OBJTYPE_HOVERBIKE: return sizeof(struct n64_hoverbikeobj) / sizeof(u32); + case OBJTYPE_HOVERPROP: return sizeof(struct n64_hoverpropobj) / sizeof(u32); + case OBJTYPE_FAN: return sizeof(struct n64_fanobj) / sizeof(u32); + case OBJTYPE_HOVERCAR: return sizeof(struct n64_hovercarobj) / sizeof(u32); + case OBJTYPE_CHOPPER: return sizeof(struct n64_chopperobj) / sizeof(u32); + case OBJTYPE_PADEFFECT: return sizeof(struct padeffectobj) / sizeof(u32); + case OBJTYPE_MINE: return sizeof(struct n64_weaponobj) / sizeof(u32); + case OBJTYPE_ESCASTEP: return sizeof(struct n64_escalatorobj) / sizeof(u32); + } + + return 1; +} + +static void convTvScreen(struct tvscreen* dstobj, struct n64_tvscreen* srcobj) +{ + PD_CONV_PTR(dstobj->cmdlist, srcobj->ptr_cmdlist, u32*); + PD_CONV_VAL(dstobj->offset, srcobj->offset); + PD_CONV_VAL(dstobj->pause60, srcobj->pause60); + PD_CONV_PTR(dstobj->tconfig, srcobj->ptr_tconfig, struct textureconfig*); + PD_CONV_VAL(dstobj->rot, srcobj->rot); + PD_CONV_VAL(dstobj->xscale, srcobj->xscale); + PD_CONV_VAL(dstobj->xscalefrac, srcobj->xscalefrac); + PD_CONV_VAL(dstobj->xscaleinc, srcobj->xscaleinc); + PD_CONV_VAL(dstobj->xscaleold, srcobj->xscaleold); + PD_CONV_VAL(dstobj->xscalenew, srcobj->xscalenew); + PD_CONV_VAL(dstobj->yscale, srcobj->yscale); + PD_CONV_VAL(dstobj->yscalefrac, srcobj->yscalefrac); + PD_CONV_VAL(dstobj->yscaleinc, srcobj->yscaleinc); + PD_CONV_VAL(dstobj->yscaleold, srcobj->yscaleold); + PD_CONV_VAL(dstobj->yscalenew, srcobj->yscalenew); + PD_CONV_VAL(dstobj->xmid, srcobj->xmid); + PD_CONV_VAL(dstobj->xmidfrac, srcobj->xmidfrac); + PD_CONV_VAL(dstobj->xmidinc, srcobj->xmidinc); + PD_CONV_VAL(dstobj->xmidold, srcobj->xmidold); + PD_CONV_VAL(dstobj->xmidnew, srcobj->xmidnew); + PD_CONV_VAL(dstobj->ymid, srcobj->ymid); + PD_CONV_VAL(dstobj->ymidfrac, srcobj->ymidfrac); + PD_CONV_VAL(dstobj->ymidinc, srcobj->ymidinc); + PD_CONV_VAL(dstobj->ymidold, srcobj->ymidold); + PD_CONV_VAL(dstobj->ymidnew, srcobj->ymidnew); + PD_CONV_VAL(dstobj->red, srcobj->red); + PD_CONV_VAL(dstobj->redold, srcobj->redold); + PD_CONV_VAL(dstobj->rednew, srcobj->rednew); + PD_CONV_VAL(dstobj->green, srcobj->green); + PD_CONV_VAL(dstobj->greenold, srcobj->greenold); + PD_CONV_VAL(dstobj->greennew, srcobj->greennew); + PD_CONV_VAL(dstobj->blue, srcobj->blue); + PD_CONV_VAL(dstobj->blueold, srcobj->blueold); + PD_CONV_VAL(dstobj->bluenew, srcobj->bluenew); + PD_CONV_VAL(dstobj->alpha, srcobj->alpha); + PD_CONV_VAL(dstobj->alphaold, srcobj->alphaold); + PD_CONV_VAL(dstobj->alphanew, srcobj->alphanew); + PD_CONV_VAL(dstobj->colfrac, srcobj->colfrac); + PD_CONV_VAL(dstobj->colinc, srcobj->colinc); +} + +static void convertDefaultObjHdr(struct defaultobj* dstobj, struct n64_defaultobj* srcobj) +{ + PD_CONV_VAL(dstobj->extrascale, srcobj->extrascale); + + /* 'header' is like this inside a u32: + u16 unk00_1, + u8 unk00_2, + u8 type, + */ + u16 *dst_unk00_1 = (u16*)&dstobj->extrascale; + u8 *dst_unk00_2 = (u8*)(dst_unk00_1 + 1); + + u16 *src_unk00_1 = (u16*)&srcobj->extrascale; + u8 *src_unk00_2 = (u8*)(src_unk00_1 + 1); + + *dst_unk00_1 = PD_BE16(*src_unk00_1); + dst_unk00_2[0] = src_unk00_2[0]; + dst_unk00_2[1] = src_unk00_2[1]; +} + +static void convertDefaultObj(struct defaultobj* dstobj, struct n64_defaultobj* srcobj) +{ + PD_CONV_VAL(dstobj->extrascale, srcobj->extrascale); + PD_CONV_VAL(dstobj->hidden2, srcobj->hidden2); + PD_CONV_VAL(dstobj->type, srcobj->type); + PD_CONV_VAL(dstobj->modelnum, srcobj->modelnum); + PD_CONV_VAL(dstobj->pad, srcobj->pad); + PD_CONV_VAL(dstobj->flags, srcobj->flags); + PD_CONV_VAL(dstobj->flags2, srcobj->flags2); + PD_CONV_VAL(dstobj->flags3, srcobj->flags3); + PD_CONV_PTR(dstobj->prop, srcobj->ptr_prop, struct prop*); + PD_CONV_PTR(dstobj->model, srcobj->ptr_model, struct model*); + PD_CONV_ARRAY2D(dstobj->realrot, srcobj->realrot); + PD_CONV_VAL(dstobj->hidden, srcobj->hidden); + PD_CONV_PTR(dstobj->unkgeo, srcobj->ptr_unkgeo, struct geocyl*); + PD_CONV_VAL(dstobj->damage, srcobj->damage); + PD_CONV_VAL(dstobj->maxdamage, srcobj->maxdamage); + PD_CONV_ARRAY(dstobj->shadecol, srcobj->shadecol); + PD_CONV_ARRAY(dstobj->nextcol, srcobj->nextcol); + PD_CONV_VAL(dstobj->floorcol, srcobj->floorcol); + PD_CONV_VAL(dstobj->geocount, srcobj->geocount); +} + +static u32 convertProps(u8* dst, u8* src) +{ + u8* start = dst; + struct n64_defaultobj* cmd = (struct n64_defaultobj*)src; + + int i = 0; + u8 type = cmd->type; + + while (type != OBJTYPE_END) { + //sysLogPrintf(LOG_NOTE, "#%03d obj 0x%02x (%s)", ++i, type, objName(cmd)); + switch (type) { + case OBJTYPE_DOOR: + { + struct n64_doorobj* srcobj = (struct n64_doorobj*)cmd; + struct doorobj* dstobj = (struct doorobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_VAL(dstobj->maxfrac, srcobj->maxfrac); + PD_CONV_VAL(dstobj->perimfrac, srcobj->perimfrac); + PD_CONV_VAL(dstobj->accel, srcobj->accel); + PD_CONV_VAL(dstobj->decel, srcobj->decel); + PD_CONV_VAL(dstobj->maxspeed, srcobj->maxspeed); + PD_CONV_VAL(dstobj->doorflags, srcobj->doorflags); + PD_CONV_VAL(dstobj->doortype, srcobj->doortype); + PD_CONV_VAL(dstobj->keyflags, srcobj->keyflags); + PD_CONV_VAL(dstobj->autoclosetime, srcobj->autoclosetime); + PD_CONV_VAL(dstobj->frac, srcobj->frac); + PD_CONV_VAL(dstobj->fracspeed, srcobj->fracspeed); + PD_CONV_VAL(dstobj->mode, srcobj->mode); + PD_CONV_VAL(dstobj->glasshits, srcobj->glasshits); + PD_CONV_VAL(dstobj->fadealpha, srcobj->fadealpha); + PD_CONV_VAL(dstobj->xludist, srcobj->xludist); + PD_CONV_VAL(dstobj->opadist, srcobj->opadist); + PD_CONV_VAL(dstobj->startpos, srcobj->startpos); + PD_CONV_ARRAY2D(dstobj->mtx98, srcobj->mtx98); + PD_CONV_PTR(dstobj->sibling, srcobj->ptr_sibling, struct doorobj*); + PD_CONV_VAL(dstobj->lastopen60, srcobj->lastopen60); + PD_CONV_VAL(dstobj->portalnum, srcobj->portalnum); + PD_CONV_VAL(dstobj->soundtype, srcobj->soundtype); + PD_CONV_VAL(dstobj->fadetime60, srcobj->fadetime60); + PD_CONV_VAL(dstobj->lastcalc60, srcobj->lastcalc60); + PD_CONV_VAL(dstobj->laserfade, srcobj->laserfade); + PD_CONV_ARRAY(dstobj->unusedmaybe, srcobj->unusedmaybe); + PD_CONV_ARRAY(dstobj->shadeinfo1, srcobj->shadeinfo1); + PD_CONV_ARRAY(dstobj->shadeinfo2, srcobj->shadeinfo2); + + PD_CONV_VAL(dstobj->actual1, srcobj->actual1); + PD_CONV_VAL(dstobj->actual2, srcobj->actual2); + PD_CONV_VAL(dstobj->extra1, srcobj->extra1); + PD_CONV_VAL(dstobj->extra2, srcobj->extra2); + + dst += sizeof(struct doorobj); + break; + } + case OBJTYPE_DOORSCALE: + { + struct n64_doorscaleobj* srcobj = (struct n64_doorscaleobj*)cmd; + struct doorscaleobj* dstobj = (struct doorscaleobj*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_VAL(dstobj->scale, srcobj->scale); + + dst += sizeof(struct doorscaleobj); + break; + } + case OBJTYPE_BASIC: + case OBJTYPE_HANGINGMONITORS: + case OBJTYPE_DEBRIS: + case OBJTYPE_HAT: + case OBJTYPE_ALARM: + { + struct n64_defaultobj* srcobj = (struct n64_defaultobj*)cmd; + struct defaultobj* dstobj = (struct defaultobj*)dst; + + convertDefaultObj(dstobj, cmd); + + dst += sizeof(struct defaultobj); + break; + } + case OBJTYPE_KEY: + { + struct n64_keyobj* srcobj = (struct n64_keyobj*)cmd; + struct keyobj* dstobj = (struct keyobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + PD_CONV_VAL(dstobj->keyflags, srcobj->keyflags); + + dst += sizeof(struct keyobj); + src += sizeof(struct n64_keyobj); + break; + } + case OBJTYPE_CCTV: + { + struct n64_cctvobj* srcobj = (struct n64_cctvobj*)cmd; + struct cctvobj* dstobj = (struct cctvobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_VAL(dstobj->lookatpadnum, srcobj->lookatpadnum); + PD_CONV_VAL(dstobj->toleft, srcobj->toleft); + PD_CONV_VAL(dstobj->yzero, srcobj->yzero); + PD_CONV_VAL(dstobj->yrot, srcobj->yrot); + PD_CONV_VAL(dstobj->yleft, srcobj->yleft); + PD_CONV_VAL(dstobj->yright, srcobj->yright); + PD_CONV_VAL(dstobj->yspeed, srcobj->yspeed); + PD_CONV_VAL(dstobj->ymaxspeed, srcobj->ymaxspeed); + PD_CONV_VAL(dstobj->seebondtime60, srcobj->seebondtime60); + PD_CONV_VAL(dstobj->maxdist, srcobj->maxdist); + PD_CONV_VAL(dstobj->xzero, srcobj->xzero); + + dst += sizeof(struct cctvobj); + break; + } + case OBJTYPE_AMMOCRATE: + { + struct n64_ammocrateobj* srcobj = (struct n64_ammocrateobj*)cmd; + struct ammocrateobj* dstobj = (struct ammocrateobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + PD_CONV_VAL(dstobj->ammotype, srcobj->ammotype); + + dst += sizeof(struct ammocrateobj); + break; + } + case OBJTYPE_WEAPON: + case OBJTYPE_MINE: + { + struct n64_weaponobj* srcobj = (struct n64_weaponobj*)cmd; + struct weaponobj* dstobj = (struct weaponobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_VAL(dstobj->weaponnum, srcobj->weaponnum); + PD_CONV_VAL(dstobj->unk5d, srcobj->unk5d); + PD_CONV_VAL(dstobj->unk5e, srcobj->unk5e); + PD_CONV_VAL(dstobj->gunfunc, srcobj->gunfunc); + + PD_CONV_VAL(dstobj->fadeouttimer60, srcobj->fadeouttimer60); + PD_CONV_VAL(dstobj->dualweaponnum, srcobj->dualweaponnum); + + PD_CONV_VAL(dstobj->team, srcobj->team); + + PD_CONV_PTR(dstobj->dualweapon, srcobj->ptr_dualweapon, struct weaponobj*); + + dst += sizeof(struct weaponobj); + break; + } + case OBJTYPE_CHR: + { + struct n64_packedchr* srcobj = (struct n64_packedchr*)cmd; + struct packedchr* dstobj = (struct packedchr*)dst; + + PD_CONV_VAL(dstobj->chrindex, srcobj->chrindex); + PD_CONV_VAL(dstobj->unk02, srcobj->unk02); + PD_CONV_VAL(dstobj->typenum, srcobj->typenum); + PD_CONV_VAL(dstobj->spawnflags, srcobj->spawnflags); + PD_CONV_VAL(dstobj->chrnum, srcobj->chrnum); + PD_CONV_VAL(dstobj->padnum, srcobj->padnum); + PD_CONV_VAL(dstobj->bodynum, srcobj->bodynum); + PD_CONV_VAL(dstobj->headnum, srcobj->headnum); + PD_CONV_VAL(dstobj->ailistnum, srcobj->ailistnum); + PD_CONV_VAL(dstobj->padpreset, srcobj->padpreset); + PD_CONV_VAL(dstobj->chrpreset, srcobj->chrpreset); + PD_CONV_VAL(dstobj->hearscale, srcobj->hearscale); + PD_CONV_VAL(dstobj->viewdist, srcobj->viewdist); + PD_CONV_VAL(dstobj->flags, srcobj->flags); + PD_CONV_VAL(dstobj->flags2, srcobj->flags2); + PD_CONV_VAL(dstobj->team, srcobj->team); + PD_CONV_VAL(dstobj->squadron, srcobj->squadron); + PD_CONV_VAL(dstobj->chair, srcobj->chair); + PD_CONV_VAL(dstobj->convtalk, srcobj->convtalk); + PD_CONV_VAL(dstobj->tude, srcobj->tude); + PD_CONV_VAL(dstobj->naturalanim, srcobj->naturalanim); + PD_CONV_VAL(dstobj->yvisang, srcobj->yvisang); + PD_CONV_VAL(dstobj->teamscandist, srcobj->teamscandist); + + dst += sizeof(struct packedchr); + break; + } + case OBJTYPE_SINGLEMONITOR: + { + struct n64_singlemonitorobj* srcobj = (struct n64_singlemonitorobj*)cmd; + struct singlemonitorobj* dstobj = (struct singlemonitorobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + convTvScreen(&dstobj->screen, &srcobj->screen); + + PD_CONV_VAL(dstobj->owneroffset, srcobj->owneroffset); + PD_CONV_VAL(dstobj->ownerpart, srcobj->ownerpart); + PD_CONV_VAL(dstobj->imagenum, srcobj->imagenum); + + dst += sizeof(struct singlemonitorobj); + break; + } + case OBJTYPE_MULTIMONITOR: + { + struct n64_multimonitorobj* srcobj = (struct n64_multimonitorobj*)cmd; + struct multimonitorobj* dstobj = (struct multimonitorobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + for (size_t i = 0; i < 4; i++) + convTvScreen(&dstobj->screens[i], &srcobj->screens[i]); + + PD_CONV_ARRAY(dstobj->imagenums, srcobj->imagenums); + dst += sizeof(struct multimonitorobj); + break; + } + case OBJTYPE_AUTOGUN: + { + struct n64_autogunobj* srcobj = (struct n64_autogunobj*)cmd; + struct autogunobj* dstobj = (struct autogunobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_VAL(dstobj->targetpad, srcobj->targetpad); + PD_CONV_VAL(dstobj->firing, srcobj->firing); + PD_CONV_VAL(dstobj->firecount, srcobj->firecount); + PD_CONV_VAL(dstobj->yzero, srcobj->yzero); + PD_CONV_VAL(dstobj->ymaxleft, srcobj->ymaxleft); + PD_CONV_VAL(dstobj->ymaxright, srcobj->ymaxright); + PD_CONV_VAL(dstobj->yrot, srcobj->yrot); + PD_CONV_VAL(dstobj->yspeed, srcobj->yspeed); + PD_CONV_VAL(dstobj->xzero, srcobj->xzero); + PD_CONV_VAL(dstobj->xrot, srcobj->xrot); + PD_CONV_VAL(dstobj->xspeed, srcobj->xspeed); + PD_CONV_VAL(dstobj->maxspeed, srcobj->maxspeed); + PD_CONV_VAL(dstobj->aimdist, srcobj->aimdist); + PD_CONV_VAL(dstobj->barrelspeed, srcobj->barrelspeed); + PD_CONV_VAL(dstobj->barrelrot, srcobj->barrelrot); + PD_CONV_VAL(dstobj->lastseebond60, srcobj->lastseebond60); + PD_CONV_VAL(dstobj->lastaimbond60, srcobj->lastaimbond60); + PD_CONV_VAL(dstobj->allowsoundframe, srcobj->allowsoundframe); + PD_CONV_PTR(dstobj->beam, srcobj->ptr_beam, struct beam*); + PD_CONV_VAL(dstobj->shotbondsum, srcobj->shotbondsum); + PD_CONV_PTR(dstobj->target, srcobj->ptr_target, struct prop*); + PD_CONV_VAL(dstobj->targetteam, srcobj->targetteam); + PD_CONV_VAL(dstobj->ammoquantity, srcobj->ammoquantity); + PD_CONV_VAL(dstobj->nextchrtest, srcobj->nextchrtest); + + dst += sizeof(struct autogunobj); + break; + } + case OBJTYPE_LINKGUNS: + { + struct n64_linkgunsobj* srcobj = (struct n64_linkgunsobj*)cmd; + struct linkgunsobj* dstobj = (struct linkgunsobj*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_VAL(dstobj->offset1, srcobj->offset1); + PD_CONV_VAL(dstobj->offset2, srcobj->offset2); + + dst += sizeof(struct linkgunsobj); + break; + } + case OBJTYPE_GRENADEPROB: + { + struct n64_grenadeprobobj* srcobj = (struct n64_grenadeprobobj*)cmd; + struct grenadeprobobj* dstobj = (struct grenadeprobobj*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_VAL(dstobj->chrnum, srcobj->chrnum); + PD_CONV_VAL(dstobj->probability, srcobj->probability); + + dst += sizeof(struct grenadeprobobj); + break; + } + case OBJTYPE_LINKLIFTDOOR: + { + struct n64_linkliftdoorobj* srcobj = (struct n64_linkliftdoorobj*)cmd; + struct linkliftdoorobj* dstobj = (struct linkliftdoorobj*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_PTR(dstobj->door, srcobj->ptr_door, struct prop*); + PD_CONV_PTR(dstobj->lift, srcobj->ptr_lift, struct prop*); + PD_CONV_PTR(dstobj->next, srcobj->ptr_next, struct linkliftdoorobj*); + PD_CONV_VAL(dstobj->stopnum, srcobj->stopnum); + + dst += sizeof(struct linkliftdoorobj); + break; + } + case OBJTYPE_MULTIAMMOCRATE: + { + struct n64_multiammocrateobj* srcobj = (struct n64_multiammocrateobj*)cmd; + struct multiammocrateobj* dstobj = (struct multiammocrateobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + for (size_t i = 0; i < 19; i++) { + PD_CONV_VAL(dstobj->slots[i].modelnum, srcobj->slots[i].modelnum); + PD_CONV_VAL(dstobj->slots[i].quantity, srcobj->slots[i].quantity); + } + + dst += sizeof(struct multiammocrateobj); + break; + } + case OBJTYPE_SHIELD: + { + struct n64_shieldobj* srcobj = (struct n64_shieldobj*)cmd; + struct shieldobj* dstobj = (struct shieldobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_VAL(dstobj->initialamount, srcobj->initialamount); + PD_CONV_VAL(dstobj->amount, srcobj->amount); + PD_CONV_VAL(dstobj->unk64, srcobj->unk64); + + dst += sizeof(struct shieldobj); + break; + } + case OBJTYPE_TAG: + { + struct n64_tag* srcobj = (struct n64_tag*)cmd; + struct tag* dstobj = (struct tag*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_VAL(dstobj->tagnum, srcobj->tagnum); + PD_CONV_VAL(dstobj->cmdoffset, srcobj->cmdoffset); + PD_CONV_PTR(dstobj->next, srcobj->ptr_next, struct tag*); + PD_CONV_PTR(dstobj->obj, srcobj->ptr_obj, struct defaultobj*); + + dst += sizeof(struct tag); + break; + } + case OBJTYPE_BEGINOBJECTIVE: + { + struct n64_objective* srcobj = (struct n64_objective*)cmd; + struct objective* dstobj = (struct objective*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_VAL(dstobj->index, srcobj->index); + PD_CONV_VAL(dstobj->text, srcobj->text); + PD_CONV_VAL(dstobj->unk0c, srcobj->unk0c); + PD_CONV_VAL(dstobj->flags, srcobj->flags); + PD_CONV_VAL(dstobj->difficulties, srcobj->difficulties); + + dst += sizeof(struct objective); + break; + } + case OBJTYPE_ENDOBJECTIVE: + case OBJECTIVETYPE_1F: + case OBJTYPE_22: + case OBJTYPE_GASBOTTLE: + case OBJTYPE_29: + case OBJTYPE_SAFE: + { + struct n64_stdobjective* srcobj = (struct n64_stdobjective*)cmd; + struct n64_stdobjective* dstobj = (struct n64_stdobjective*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + + dst += sizeof(struct n64_stdobjective); + break; + } + case OBJECTIVETYPE_DESTROYOBJ: + case OBJECTIVETYPE_COMPFLAGS: + case OBJECTIVETYPE_FAILFLAGS: + case OBJECTIVETYPE_COLLECTOBJ: + case OBJECTIVETYPE_THROWOBJ: + { + struct n64_objectivecmd* srcobj = (struct n64_objectivecmd*)cmd; + struct n64_objectivecmd* dstobj = (struct n64_objectivecmd*)dst; + + PD_CONV_ARRAY(dstobj->cmd0, srcobj->cmd0); + PD_CONV_VAL(dstobj->cmd1, srcobj->cmd1); + + dst += sizeof(struct n64_objectivecmd); + break; + } + case OBJECTIVETYPE_HOLOGRAPH: + { + struct n64_criteria_holograph* srcobj = (struct n64_criteria_holograph*)cmd; + struct criteria_holograph* dstobj = (struct criteria_holograph*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_VAL(dstobj->obj, srcobj->obj); + PD_CONV_VAL(dstobj->status, srcobj->status); + PD_CONV_PTR(dstobj->next, srcobj->ptr_next, struct criteria_holograph*); + + dst += sizeof(struct criteria_holograph); + break; + } + case OBJECTIVETYPE_ENTERROOM: + { + struct n64_criteria_roomentered* srcobj = (struct n64_criteria_roomentered*)cmd; + struct criteria_roomentered* dstobj = (struct criteria_roomentered*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_VAL(dstobj->pad, srcobj->pad); + PD_CONV_VAL(dstobj->status, srcobj->status); + PD_CONV_PTR(dstobj->next, srcobj->ptr_next, struct criteria_roomentered*); + + dst += sizeof(struct criteria_roomentered); + break; + } + case OBJECTIVETYPE_THROWINROOM: + { + struct n64_criteria_throwinroom* srcobj = (struct n64_criteria_throwinroom*)cmd; + struct criteria_throwinroom* dstobj = (struct criteria_throwinroom*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_VAL(dstobj->pad, srcobj->pad); + PD_CONV_VAL(dstobj->status, srcobj->status); + PD_CONV_PTR(dstobj->next, srcobj->ptr_next, struct criteria_throwinroom*); + + dst += sizeof(struct criteria_throwinroom); + break; + } + case OBJTYPE_BRIEFING: + { + struct n64_briefingobj* srcobj = (struct n64_briefingobj*)cmd; + struct briefingobj* dstobj = (struct briefingobj*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_VAL(dstobj->type, srcobj->type); + PD_CONV_VAL(dstobj->text, srcobj->text); + PD_CONV_PTR(dstobj->next, srcobj->ptr_next, struct briefingobj*); + + dst += sizeof(struct briefingobj); + break; + } + case OBJTYPE_RENAMEOBJ: + { + struct n64_textoverride* srcobj = (struct n64_textoverride*)cmd; + struct textoverride* dstobj = (struct textoverride*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_VAL(dstobj->objoffset, srcobj->objoffset); + PD_CONV_VAL(dstobj->weapon, srcobj->weapon); + PD_CONV_VAL(dstobj->obtaintext, srcobj->obtaintext); + PD_CONV_VAL(dstobj->ownertext, srcobj->ownertext); + PD_CONV_VAL(dstobj->inventorytext, srcobj->inventorytext); + PD_CONV_VAL(dstobj->inventory2text, srcobj->inventory2text); + PD_CONV_VAL(dstobj->pickuptext, srcobj->pickuptext); + PD_CONV_PTR(dstobj->next, srcobj->ptr_next, struct textoverride*); + PD_CONV_PTR(dstobj->obj, srcobj->ptr_obj, struct defaultobj*); + + dst += sizeof(struct textoverride); + break; + } + case OBJTYPE_PADLOCKEDDOOR: + { + struct n64_padlockeddoorobj* srcobj = (struct n64_padlockeddoorobj*)cmd; + struct padlockeddoorobj* dstobj = (struct padlockeddoorobj*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_PTR(dstobj->door, srcobj->ptr_door, struct doorobj*); + PD_CONV_PTR(dstobj->lock, srcobj->ptr_lock, struct defaultobj*); + PD_CONV_PTR(dstobj->next, srcobj->ptr_next, struct padlockeddoorobj*); + + dst += sizeof(struct padlockeddoorobj); + break; + } + case OBJTYPE_TRUCK: + { + struct n64_truckobj* srcobj = (struct n64_truckobj*)cmd; + struct truckobj* dstobj = (struct truckobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_PTR(dstobj->ailist, srcobj->ptr_ailist, u8*); + PD_CONV_VAL(dstobj->aioffset, srcobj->aioffset); + PD_CONV_VAL(dstobj->aireturnlist, srcobj->aireturnlist); + PD_CONV_VAL(dstobj->speed, srcobj->speed); + PD_CONV_VAL(dstobj->wheelxrot, srcobj->wheelxrot); + PD_CONV_VAL(dstobj->wheelyrot, srcobj->wheelyrot); + PD_CONV_VAL(dstobj->speedaim, srcobj->speedaim); + PD_CONV_VAL(dstobj->speedtime60, srcobj->speedtime60); + PD_CONV_VAL(dstobj->turnrot60, srcobj->turnrot60); + PD_CONV_VAL(dstobj->roty, srcobj->roty); + PD_CONV_PTR(dstobj->path, srcobj->ptr_path, struct path*); + PD_CONV_VAL(dstobj->nextstep, srcobj->nextstep); + + dst += sizeof(struct truckobj); + break; + } + case OBJTYPE_HELI: + { + struct n64_heliobj* srcobj = (struct n64_heliobj*)cmd; + struct heliobj* dstobj = (struct heliobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_PTR(dstobj->ailist, srcobj->ptr_ailist, u8*); + PD_CONV_VAL(dstobj->aioffset, srcobj->aioffset); + PD_CONV_VAL(dstobj->aireturnlist, srcobj->aireturnlist); + PD_CONV_VAL(dstobj->rotoryrot, srcobj->rotoryrot); + PD_CONV_VAL(dstobj->rotoryspeed, srcobj->rotoryspeed); + PD_CONV_VAL(dstobj->rotoryspeedaim, srcobj->rotoryspeedaim); + PD_CONV_VAL(dstobj->rotoryspeedtime, srcobj->rotoryspeedtime); + PD_CONV_VAL(dstobj->speed, srcobj->speed); + PD_CONV_VAL(dstobj->speedaim, srcobj->speedaim); + PD_CONV_VAL(dstobj->speedtime60, srcobj->speedtime60); + PD_CONV_VAL(dstobj->yrot, srcobj->yrot); + PD_CONV_PTR(dstobj->path, srcobj->ptr_path, struct path*); + PD_CONV_VAL(dstobj->nextstep, srcobj->nextstep); + + dst += sizeof(struct heliobj); + break; + } + case OBJTYPE_GLASS: + { + struct n64_glassobj* srcobj = (struct n64_glassobj*)cmd; + struct glassobj* dstobj = (struct glassobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + PD_CONV_VAL(dstobj->portalnum, srcobj->portalnum); + + dst += sizeof(struct glassobj); + break; + } + case OBJTYPE_SAFEITEM: + { + struct n64_safeitemobj* srcobj = (struct n64_safeitemobj*)cmd; + struct safeitemobj* dstobj = (struct safeitemobj*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_PTR(dstobj->item, srcobj->ptr_item, struct defaultobj*); + PD_CONV_PTR(dstobj->safe, srcobj->ptr_safe, struct safeobj*); + PD_CONV_PTR(dstobj->door, srcobj->ptr_door, struct doorobj*); + PD_CONV_PTR(dstobj->next, srcobj->ptr_next, struct safeitemobj*); + + dst += sizeof(struct safeitemobj); + break; + } + case OBJTYPE_TANK: + { + dst += sizeof(struct n64_tankobj); + break; + } + case OBJTYPE_CAMERAPOS: + { + struct n64_cameraposobj* srcobj = (struct n64_cameraposobj*)cmd; + struct cameraposobj* dstobj = (struct cameraposobj*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_VAL(dstobj->x, srcobj->x); + PD_CONV_VAL(dstobj->y, srcobj->y); + PD_CONV_VAL(dstobj->z, srcobj->z); + PD_CONV_VAL(dstobj->theta, srcobj->theta); + PD_CONV_VAL(dstobj->verta, srcobj->verta); + PD_CONV_VAL(dstobj->pad, srcobj->pad); + + dst += sizeof(struct cameraposobj); + break; + } + case OBJTYPE_TINTEDGLASS: + { + struct n64_tintedglassobj* srcobj = (struct n64_tintedglassobj*)cmd; + struct tintedglassobj* dstobj = (struct tintedglassobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_VAL(dstobj->xludist, srcobj->xludist); + PD_CONV_VAL(dstobj->opadist, srcobj->opadist); + PD_CONV_VAL(dstobj->opacity, srcobj->opacity); + PD_CONV_VAL(dstobj->portalnum, srcobj->portalnum); + PD_CONV_VAL(dstobj->unk64, srcobj->unk64); + + dst += sizeof(struct tintedglassobj); + break; + } + case OBJTYPE_LIFT: + { + struct n64_liftobj* srcobj = (struct n64_liftobj*)cmd; + struct liftobj* dstobj = (struct liftobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_ARRAY(dstobj->pads, srcobj->pads); + for (int k = 0; k < 4; k++) + PD_CONV_PTR(dstobj->doors[k], srcobj->ptr_doors[k], struct doorobj*); + PD_CONV_VAL(dstobj->dist, srcobj->dist); + PD_CONV_VAL(dstobj->speed, srcobj->speed); + PD_CONV_VAL(dstobj->accel, srcobj->accel); + PD_CONV_VAL(dstobj->maxspeed, srcobj->maxspeed); + PD_CONV_VAL(dstobj->soundtype, srcobj->soundtype); + PD_CONV_VAL(dstobj->levelcur, srcobj->levelcur); + PD_CONV_VAL(dstobj->levelaim, srcobj->levelaim); + PD_CONV_VAL(dstobj->prevpos, srcobj->prevpos); + + dst += sizeof(struct liftobj); + break; + } + case OBJTYPE_CONDITIONALSCENERY: + { + struct n64_linksceneryobj* srcobj = (struct n64_linksceneryobj*)cmd; + struct linksceneryobj* dstobj = (struct linksceneryobj*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_PTR(dstobj->trigger, srcobj->ptr_trigger, struct defaultobj*); + PD_CONV_PTR(dstobj->unexp, srcobj->ptr_unexp, struct defaultobj*); + PD_CONV_PTR(dstobj->exp, srcobj->ptr_exp, struct defaultobj*); + PD_CONV_PTR(dstobj->next, srcobj->ptr_next, struct linksceneryobj*); + + dst += sizeof(struct linksceneryobj); + break; + } + case OBJTYPE_BLOCKEDPATH: + { + struct n64_blockedpathobj* srcobj = (struct n64_blockedpathobj*)cmd; + struct blockedpathobj* dstobj = (struct blockedpathobj*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_PTR(dstobj->blocker, srcobj->ptr_blocker, struct defaultobj*); + PD_CONV_VAL(dstobj->waypoint1, srcobj->waypoint1); + PD_CONV_VAL(dstobj->waypoint2, srcobj->waypoint2); + PD_CONV_PTR(dstobj->next, srcobj->ptr_next, struct blockedpathobj*); + + dst += sizeof(struct blockedpathobj); + break; + } + case OBJTYPE_HOVERBIKE: { + struct n64_hoverbikeobj* srcobj = (struct n64_hoverbikeobj*)cmd; + struct hoverbikeobj* dstobj = (struct hoverbikeobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_VAL(dstobj->hov.type, srcobj->hov.type); + PD_CONV_VAL(dstobj->hov.flags, srcobj->hov.flags); + PD_CONV_VAL(dstobj->hov.bobycur, srcobj->hov.bobycur); + PD_CONV_VAL(dstobj->hov.bobytarget, srcobj->hov.bobytarget); + PD_CONV_VAL(dstobj->hov.bobyspeed, srcobj->hov.bobyspeed); + PD_CONV_VAL(dstobj->hov.yrot, srcobj->hov.yrot); + PD_CONV_VAL(dstobj->hov.bobpitchcur, srcobj->hov.bobpitchcur); + PD_CONV_VAL(dstobj->hov.bobpitchtarget, srcobj->hov.bobpitchtarget); + PD_CONV_VAL(dstobj->hov.bobpitchspeed, srcobj->hov.bobpitchspeed); + PD_CONV_VAL(dstobj->hov.bobrollcur, srcobj->hov.bobrollcur); + PD_CONV_VAL(dstobj->hov.bobrolltarget, srcobj->hov.bobrolltarget); + PD_CONV_VAL(dstobj->hov.bobrollspeed, srcobj->hov.bobrollspeed); + PD_CONV_VAL(dstobj->hov.groundpitch, srcobj->hov.groundpitch); + PD_CONV_VAL(dstobj->hov.y, srcobj->hov.y); + PD_CONV_VAL(dstobj->hov.ground, srcobj->hov.ground); + PD_CONV_VAL(dstobj->hov.prevframe60, srcobj->hov.prevframe60); + PD_CONV_VAL(dstobj->hov.prevgroundframe60, srcobj->hov.prevgroundframe60); + + PD_CONV_ARRAY(dstobj->speed, srcobj->speed); + PD_CONV_VAL(dstobj->exreal, srcobj->exreal); + PD_CONV_VAL(dstobj->ezreal, srcobj->ezreal); + PD_CONV_VAL(dstobj->ezreal2, srcobj->ezreal2); + PD_CONV_VAL(dstobj->leanspeed, srcobj->leanspeed); + PD_CONV_VAL(dstobj->leandiff, srcobj->leandiff); + PD_CONV_VAL(dstobj->maxspeedtime240, srcobj->maxspeedtime240); + PD_CONV_ARRAY(dstobj->prevpos, srcobj->prevpos); + PD_CONV_ARRAY(dstobj->rels, srcobj->rels); + PD_CONV_ARRAY(dstobj->speedabs, srcobj->speedabs); + PD_CONV_ARRAY(dstobj->speedrel, srcobj->speedrel); + + dst += sizeof(struct hoverbikeobj); + break; + } + case OBJTYPE_HOVERPROP: + { + struct n64_hoverpropobj* srcobj = (struct n64_hoverpropobj*)cmd; + struct hoverpropobj* dstobj = (struct hoverpropobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_VAL(dstobj->hov.type, srcobj->hov.type); + PD_CONV_VAL(dstobj->hov.flags, srcobj->hov.flags); + PD_CONV_VAL(dstobj->hov.bobycur, srcobj->hov.bobycur); + PD_CONV_VAL(dstobj->hov.bobytarget, srcobj->hov.bobytarget); + PD_CONV_VAL(dstobj->hov.bobyspeed, srcobj->hov.bobyspeed); + PD_CONV_VAL(dstobj->hov.yrot, srcobj->hov.yrot); + PD_CONV_VAL(dstobj->hov.bobpitchcur, srcobj->hov.bobpitchcur); + PD_CONV_VAL(dstobj->hov.bobpitchtarget, srcobj->hov.bobpitchtarget); + PD_CONV_VAL(dstobj->hov.bobpitchspeed, srcobj->hov.bobpitchspeed); + PD_CONV_VAL(dstobj->hov.bobrollcur, srcobj->hov.bobrollcur); + PD_CONV_VAL(dstobj->hov.bobrolltarget, srcobj->hov.bobrolltarget); + PD_CONV_VAL(dstobj->hov.bobrollspeed, srcobj->hov.bobrollspeed); + PD_CONV_VAL(dstobj->hov.groundpitch, srcobj->hov.groundpitch); + PD_CONV_VAL(dstobj->hov.y, srcobj->hov.y); + PD_CONV_VAL(dstobj->hov.ground, srcobj->hov.ground); + PD_CONV_VAL(dstobj->hov.prevframe60, srcobj->hov.prevframe60); + PD_CONV_VAL(dstobj->hov.prevgroundframe60, srcobj->hov.prevgroundframe60); + + dst += sizeof(struct hoverpropobj); + break; + } + case OBJTYPE_FAN: + { + struct n64_fanobj* srcobj = (struct n64_fanobj*)cmd; + struct fanobj* dstobj = (struct fanobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_VAL(dstobj->yrot, srcobj->yrot); + PD_CONV_VAL(dstobj->yrotprev, srcobj->yrotprev); + PD_CONV_VAL(dstobj->ymaxspeed, srcobj->ymaxspeed); + PD_CONV_VAL(dstobj->yspeed, srcobj->yspeed); + PD_CONV_VAL(dstobj->yaccel, srcobj->yaccel); + PD_CONV_VAL(dstobj->on, srcobj->on); + + dst += sizeof(struct fanobj); + break; + } + case OBJTYPE_HOVERCAR: + { + struct n64_hovercarobj* srcobj = (struct n64_hovercarobj*)cmd; + struct hovercarobj* dstobj = (struct hovercarobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_PTR(dstobj->ailist, srcobj->ptr_ailist, u8*); + PD_CONV_VAL(dstobj->aioffset, srcobj->aioffset); + PD_CONV_VAL(dstobj->aireturnlist, srcobj->aireturnlist); + PD_CONV_VAL(dstobj->speed, srcobj->speed); + PD_CONV_VAL(dstobj->speedaim, srcobj->speedaim); + PD_CONV_VAL(dstobj->speedtime60, srcobj->speedtime60); + PD_CONV_VAL(dstobj->turnyspeed60, srcobj->turnyspeed60); + PD_CONV_VAL(dstobj->turnxspeed60, srcobj->turnxspeed60); + PD_CONV_VAL(dstobj->turnrot60, srcobj->turnrot60); + PD_CONV_VAL(dstobj->roty, srcobj->roty); + PD_CONV_VAL(dstobj->rotx, srcobj->rotx); + PD_CONV_VAL(dstobj->rotz, srcobj->rotz); + PD_CONV_PTR(dstobj->path, srcobj->ptr_path, struct path*); + PD_CONV_VAL(dstobj->nextstep, srcobj->nextstep); + PD_CONV_VAL(dstobj->status, srcobj->status); + PD_CONV_VAL(dstobj->dead, srcobj->dead); + PD_CONV_VAL(dstobj->deadtimer60, srcobj->deadtimer60); + PD_CONV_VAL(dstobj->sparkstimer60, srcobj->sparkstimer60); + + dst += sizeof(struct hovercarobj); + break; + } + case OBJTYPE_PADEFFECT: + { + struct padeffectobj* srcobj = (struct padeffectobj*)cmd; + struct padeffectobj* dstobj = (struct padeffectobj*)dst; + + convertDefaultObjHdr((struct defaultobj*)dstobj, cmd); + PD_CONV_VAL(dstobj->effect, srcobj->effect); + PD_CONV_VAL(dstobj->pad, srcobj->pad); + + dst += sizeof(struct padeffectobj); + break; + } + case OBJTYPE_CHOPPER: + { + struct n64_chopperobj* srcobj = (struct n64_chopperobj*)cmd; + struct chopperobj* dstobj = (struct chopperobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_PTR(dstobj->ailist, srcobj->ptr_ailist, u8*); + PD_CONV_VAL(dstobj->aioffset, srcobj->aioffset); + PD_CONV_VAL(dstobj->aireturnlist, srcobj->aireturnlist); + PD_CONV_VAL(dstobj->speed, srcobj->speed); + PD_CONV_VAL(dstobj->speedaim, srcobj->speedaim); + PD_CONV_VAL(dstobj->speedtime60, srcobj->speedtime60); + PD_CONV_VAL(dstobj->turnyspeed60, srcobj->turnyspeed60); + PD_CONV_VAL(dstobj->turnxspeed60, srcobj->turnxspeed60); + PD_CONV_VAL(dstobj->turnrot60, srcobj->turnrot60); + PD_CONV_VAL(dstobj->roty, srcobj->roty); + PD_CONV_VAL(dstobj->rotx, srcobj->rotx); + PD_CONV_VAL(dstobj->rotz, srcobj->rotz); + PD_CONV_PTR(dstobj->path, srcobj->ptr_path, struct path*); + PD_CONV_VAL(dstobj->nextstep, srcobj->nextstep); + PD_CONV_VAL(dstobj->weaponsarmed, srcobj->weaponsarmed); + PD_CONV_VAL(dstobj->ontarget, srcobj->ontarget); + PD_CONV_VAL(dstobj->target, srcobj->target); + PD_CONV_VAL(dstobj->attackmode, srcobj->attackmode); + PD_CONV_VAL(dstobj->cw, srcobj->cw); + PD_CONV_VAL(dstobj->vx, srcobj->vx); + PD_CONV_VAL(dstobj->vy, srcobj->vy); + PD_CONV_VAL(dstobj->vz, srcobj->vz); + PD_CONV_VAL(dstobj->power, srcobj->power); + PD_CONV_VAL(dstobj->otx, srcobj->otx); + PD_CONV_VAL(dstobj->oty, srcobj->oty); + PD_CONV_VAL(dstobj->otz, srcobj->otz); + PD_CONV_VAL(dstobj->bob, srcobj->bob); + PD_CONV_VAL(dstobj->bobstrength, srcobj->bobstrength); + PD_CONV_VAL(dstobj->targetvisible, srcobj->targetvisible); + PD_CONV_VAL(dstobj->timer60, srcobj->timer60); + PD_CONV_VAL(dstobj->patroltimer60, srcobj->patroltimer60); + PD_CONV_VAL(dstobj->gunturnyspeed60, srcobj->gunturnyspeed60); + PD_CONV_VAL(dstobj->gunturnxspeed60, srcobj->gunturnxspeed60); + PD_CONV_VAL(dstobj->gunroty, srcobj->gunroty); + PD_CONV_VAL(dstobj->gunrotx, srcobj->gunrotx); + PD_CONV_VAL(dstobj->barrelrotspeed, srcobj->barrelrotspeed); + PD_CONV_VAL(dstobj->barrelrot, srcobj->barrelrot); + PD_CONV_PTR(dstobj->fireslotthing, srcobj->ptr_fireslotthing, struct fireslotthing*); + PD_CONV_VAL(dstobj->dead, srcobj->dead); + + dst += sizeof(struct chopperobj); + break; + } + case OBJTYPE_ESCASTEP: + { + struct n64_escalatorobj* srcobj = (struct n64_escalatorobj*)cmd; + struct escalatorobj* dstobj = (struct escalatorobj*)dst; + + convertDefaultObj(&dstobj->base, cmd); + + PD_CONV_VAL(dstobj->frame, srcobj->frame); + PD_CONV_VAL(dstobj->prevpos, srcobj->prevpos); + + dst += sizeof(struct escalatorobj); + break; + } + } + + cmd = (struct n64_defaultobj*)((u32*)cmd + objSizeN64(cmd)); + type = cmd->type; + } + + *(u32*)(dst) = PD_BE32(OBJTYPE_END); + dst += sizeof(u32); + + return (u32)(dst - start); +} + +static uintptr_t convertIntro(u8 *dst, u8 *src) +{ + u8 cmd_size[] = { + 3, // INTROCMD_SPAWN + 4, // INTROCMD_WEAPON + 4, // INTROCMD_AMMO + 8, // INTROCMD_3 + 2, // INTROCMD_4 + 2, // INTROCMD_OUTFIT + 10, // INTROCMD_6 + 3, // INTROCMD_WATCHTIME + 2, // INTROCMD_CREDITOFFSET + 3, // INTROCMD_CASE + 3, // INTROCMD_CASERESPAWN + 2, // INTROCMD_HILL + 1, // the INTROCMD_END constant itself + }; + + s32* dstintro = (s32*)dst; + s32* srcintro = (s32*)src; + + while (true) { + s32 cmd = dstintro[0] = PD_BE32(srcintro[0]); + u8 size = cmd_size[*dstintro]; + for (int i = 1; i < size; i++) { + dstintro[i] = PD_BE32(srcintro[i]); + } + + dstintro += size; + srcintro += size; + + if (cmd == INTROCMD_END) break; + } + + return (u32)((u8*)dstintro - dst); +} + +static u32 convertPaths(u8 *dst, u8 *src) +{ + struct n64_path* srcpath = (struct n64_path*)src; + struct path* dstpath = (struct path*)dst; + + while (true) { + PD_CONV_PTR(dstpath->pads, srcpath->ptr_pads, s32*); + PD_CONV_VAL(dstpath->id, srcpath->id); + PD_CONV_VAL(dstpath->flags, srcpath->flags); + PD_CONV_VAL(dstpath->len, srcpath->len); + + if (srcpath->ptr_pads == 0) break; + + dstpath++; + srcpath++; + } + + // extra pointer for the end marker + return (u32)((u8*)dstpath - dst + sizeof(uintptr_t)); +} + +static u32 convertPads(struct path *dstpaths, u8 *dst, u8 *src, u32 dstpos) +{ + u32 start = dstpos; + s32 *dstpads = (s32 *)&dst[dstpos]; + while (dstpaths->pads) { + s32 *pads = (s32 *)&src[(uintptr_t)dstpaths->pads]; + dstpaths->pads = (s32 *)(uintptr_t)dstpos; + + while (*pads) { + s32 p = PD_BE32(*pads++); + *dstpads++ = p; + dstpos += sizeof(s32); + if (p == -1) break; + } + + dstpaths++; + } + + return dstpos - start; +} + +static u32 convertAiLists(u8* dst, u8* src) +{ + struct n64_ailist* srcailist = (struct n64_ailist *)src; + struct ailist* dstailist = (struct ailist *)dst; + + while (true) { + // at this point these fields are already converted, so we just assign + dstailist->list = (u8 *)(uintptr_t)srcailist->ptr_list; + dstailist->id = srcailist->id; + + + if (srcailist->ptr_list == 0) break; + + dstailist++; + srcailist++; + } + + return (u32)((u8 *)dstailist - dst + sizeof(uintptr_t)); +} + +static u32 convertLists(u8 *dst, u8 *src, u32 dstpos, u32 src_ofs) +{ + ptrReset(); + struct n64_ailist *src_ailists = (struct n64_ailist*)&src[src_ofs]; + + // count the lists and pre-convert the fields + int nlists = 0; + for (struct n64_ailist *tmp = src_ailists; tmp->ptr_list; tmp++, nlists++) { + tmp->ptr_list = PD_BE32(tmp->ptr_list); + tmp->id = PD_BE32(tmp->id); + } + + for (struct n64_ailist *ailist = src_ailists; ailist->ptr_list; ailist++) { + // update the src list pointers here + uintptr_t src_ptr_list = (uintptr_t) ailist->ptr_list; + ailist->ptr_list = dstpos; + + // multiple ailists can point to the same list, so we need to check if it was already copied + struct ptrmarker *marker = ptrFind(src_ptr_list); + if (marker) { + ailist->ptr_list = marker->ptr_host; + continue; + } + + ptrAdd(src_ptr_list, dstpos); + + u8 *list = &src[src_ptr_list]; + u32 listsize = chraiGetAilistLength(list); + memcpy(dst + dstpos, list, listsize); + + dstpos += PD_ALIGN(listsize, 4); + } + + return dstpos; +} + +static u32 convertSetup(u8 *dst, u8 *src, u32 srclen) +{ + struct n64_stagesetup *src_header = (struct n64_stagesetup*)src; + struct stagesetup *dst_header = (struct stagesetup*)dst; + + src_header->ptr_props = PD_BE32(src_header->ptr_props); + src_header->ptr_intro = PD_BE32(src_header->ptr_intro); + src_header->ptr_ailists = PD_BE32(src_header->ptr_ailists); + src_header->ptr_paths = PD_BE32(src_header->ptr_paths); + + u32 srcpos = sizeof(*src_header); + u32 dstpos = sizeof(*dst_header); + + srcpos = src_header->ptr_props; + dst_header->props = (u32 *)(uintptr_t)dstpos; + dstpos += convertProps(&dst[dstpos], &src[srcpos]); + + srcpos = src_header->ptr_intro; + dst_header->intro = (s32 *)(uintptr_t)dstpos; + dstpos += convertIntro(&dst[dstpos], &src[srcpos]); + + // write the lists bytecodes before the ailists entries + dstpos = convertLists(dst, src, dstpos, src_header->ptr_ailists); + + srcpos = src_header->ptr_ailists; + dst_header->ailists = (struct ailist *)(uintptr_t)dstpos; + dstpos += convertAiLists(&dst[dstpos], &src[srcpos]); + + srcpos = src_header->ptr_paths; + dst_header->paths = (struct path *)(uintptr_t)dstpos; + dstpos += convertPaths(&dst[dstpos], &src[srcpos]); + + dstpos += convertPads((struct path*)&dst[(uintptr_t)dst_header->paths], dst, src, dstpos); + + return dstpos; +} + +u8 *preprocessSetupFile(u8 *data, u32 size, u32 *outSize) { + u32 newSizeEstimated = romdataFileGetEstimatedSize(size, LOADTYPE_SETUP); + u8 *dst = sysMemZeroAlloc(newSizeEstimated); + + u32 newSize = convertSetup(dst, data, size); + + if (newSize > newSizeEstimated) { + sysFatalError("overflow when trying to preprocess a model file, size %d newsize %d", size, newSize); + } + + memcpy(data, dst, newSize); + sysMemFree(dst); + + *outSize = newSize; + + return 0; +} diff --git a/port/src/preprocess/filetiles.c b/port/src/preprocess/filetiles.c new file mode 100644 index 000000000..e1284b995 --- /dev/null +++ b/port/src/preprocess/filetiles.c @@ -0,0 +1,103 @@ +#include +#include +#include + +#include "preprocess/common.h" + +struct tile { + u8 type; + u8 numvertices; + u16 flags; + u16 floortype; + u8 xmin; + u8 ymin; + u8 zmin; + u8 xmax; + u8 ymax; + u8 zmax; + u16 floorcol; +}; + +static u32 convertTiles(u8 *dst, u8 *src, size_t srclen) +{ + int num_rooms = PD_BE32(*(u32 *) src); + + size_t src_ptr_table_len = (num_rooms + 1) * 4; + size_t dst_ptr_table_len = (num_rooms + 1) * sizeof(u32); + + u32 *src_offsets = (u32 *) &src[4]; + + size_t data_len = srclen - src_ptr_table_len - 4; + + *(u32 *) dst = (num_rooms); + + u32 *dst_offsets = (u32 *) (dst + sizeof(u32)); + u32 cur_dst_offset = dst_ptr_table_len + sizeof(u32); + + u32 cur_src_offset = PD_BE32(src_offsets[0]); + u32 end_src_offset = PD_BE32(src_offsets[num_rooms]); + int room = 0; + + while (1) { + // Check if this is a new room and write the pointer offset if so + while (room < (num_rooms + 1) && PD_BE32(src_offsets[room]) == cur_src_offset) { + dst_offsets[room] = (cur_dst_offset); + room++; + } + + if (cur_src_offset >= end_src_offset) { + break; + } + + // Write tile data + struct tile *n64tile = (struct tile *) &src[cur_src_offset]; + struct tile hosttile; + + hosttile.type = n64tile->type; + hosttile.numvertices = n64tile->numvertices; + hosttile.flags = PD_BE16(n64tile->flags); + hosttile.floortype = PD_BE16(n64tile->floortype); + hosttile.xmin = n64tile->xmin; + hosttile.ymin = n64tile->ymin; + hosttile.zmin = n64tile->zmin; + hosttile.xmax = n64tile->xmax; + hosttile.ymax = n64tile->ymax; + hosttile.zmax = n64tile->zmax; + hosttile.floorcol = PD_BE16(n64tile->floorcol); + + memcpy(&dst[cur_dst_offset], &hosttile, sizeof(struct tile)); + + cur_dst_offset += sizeof(struct tile); + cur_src_offset += sizeof(struct tile); + + // Write tile vertices + for (int i = 0; i < hosttile.numvertices; i++) { + *(s16 *) &dst[cur_dst_offset + 0] = PD_BE16(*(s16 *) &src[cur_src_offset + 0]); + *(s16 *) &dst[cur_dst_offset + 2] = PD_BE16(*(s16 *) &src[cur_src_offset + 2]); + *(s16 *) &dst[cur_dst_offset + 4] = PD_BE16(*(s16 *) &src[cur_src_offset + 4]); + cur_dst_offset += 6; + cur_src_offset += 6; + } + } + + return ALIGN16(cur_dst_offset); +} + +u8 *preprocessTilesFile(u8 *data, u32 size, u32 *outSize) +{ + u32 newSizeEstimated = romdataFileGetEstimatedSize(size, LOADTYPE_TILES); + u8 *dst = sysMemZeroAlloc(newSizeEstimated); + + u32 newSize = convertTiles(dst, data, size); + + if (newSize > newSizeEstimated) { + sysFatalError("overflow when trying to preprocess a tiles file, size %d newsize %d", size, newSize); + } + + memcpy(data, dst, newSize); + sysMemFree(dst); + + *outSize = newSize; + + return 0; +} diff --git a/port/src/preprocess/gbi.c b/port/src/preprocess/gbi.c new file mode 100644 index 000000000..e6c371097 --- /dev/null +++ b/port/src/preprocess/gbi.c @@ -0,0 +1,208 @@ +#include +#include +#include +#include + +#include "preprocess/common.h" +#include "preprocess/gbi.h" + +#if UINTPTR_MAX > 0xFFFFFFFFu +#define HOST_DWORDS_PER_CMD 2 +#else +#define HOST_DWORDS_PER_CMD 1 +#endif + +struct vtx { + s16 x; + s16 y; + s16 z; + u8 flags; + u8 colour; + s16 s; + s16 t; +}; + +struct texaddr { + u32 src; + u32 dst; +}; + +static u32 gbiSegments[16]; +static u32 srcVtxOffset; +static u32 dstVtxOffset; + +static struct texaddr texAddrs[64]; +static int numTexAddrs; + +void gbiReset(void) +{ + for (int i = 0; i < ARRAYCOUNT(gbiSegments); i++) { + gbiSegments[i] = 0; + } + + srcVtxOffset = 0; + dstVtxOffset = 0; + numTexAddrs = 0; +} + +void gbiSetSegment(int segment, u32 offset) +{ + gbiSegments[segment] = offset & 0x00ffffff; +} + +void gbiSetVtx(u32 src_offset, u32 dst_offset) +{ + srcVtxOffset = src_offset & 0x00ffffff; + dstVtxOffset = dst_offset & 0x00ffffff; +} + +void gbiAddTexAddr(u32 src_offset, u32 dst_offset) +{ + texAddrs[numTexAddrs].src = src_offset & 0x00ffffff; + texAddrs[numTexAddrs++].dst = dst_offset & 0x00ffffff; +} + +u32 gbiFindTexAddr(u32 src_offset) +{ + for (int i = 0; i < numTexAddrs; i++) { + if (texAddrs[i].src == src_offset) + return texAddrs[i].dst; + } + + return 0; +} + +void gbiConvertVtx(u8 *dst, u32 offset, int count) +{ + if (!offset) return; + struct vtx* vtxs = (struct vtx*)(dst + offset); + + for (int i = 0; i < count; i++) { + struct vtx* vtx = &vtxs[i]; + + vtx->x = PD_BE16(vtx->x); + vtx->y = PD_BE16(vtx->y); + vtx->z = PD_BE16(vtx->z); + vtx->s = PD_BE16(vtx->s); + vtx->t = PD_BE16(vtx->t); + } +} + +#define CMD_IS_VTX(cmd) ((cmd & 0xff00000000000000) == 0x0400000000000000) +#define CMD_IS_DL(cmd) ((cmd & 0xff00000000000000) == 0x0600000000000000) +#define CMD_IS_COL(cmd) ((cmd & 0xff00000000000000) == 0x0700000000000000) +#define CMD_IS_ENDDL(cmd) ((cmd & 0xff00000000000000) == 0xb800000000000000) +#define CMD_IS_MOVEWORD(cmd) ((cmd & 0xff00000000000000) == 0xbc00000000000000) +#define CMD_IS_MOVEMEM(cmd) ((cmd & 0xff00000000000000) == 0x0300000000000000) +#define CMD_IS_MTX(cmd) ((cmd & 0xff00000000000000) == 0x0100000000000000) +#define CMD_IS_SETTIMG(cmd) ((cmd & 0xff00000000000000) == 0xfd00000000000000) +#define CMD_IS_SETZIMG(cmd) ((cmd & 0xff00000000000000) == 0xfe00000000000000) +#define CMD_IS_SETCIMG(cmd) ((cmd & 0xff00000000000000) == 0xff00000000000000) + +#define CMD_HAS_ADDR(cmd) CMD_IS_VTX(cmd) \ + || CMD_IS_COL(cmd) \ + || CMD_IS_MOVEWORD(cmd) \ + || CMD_IS_SETTIMG(cmd) + + +#define CMD_IS_SEGMENTED(cmd) ( CMD_IS_MOVEMEM(cmd) \ + || CMD_IS_MTX(cmd) \ + || CMD_IS_VTX(cmd) \ + || CMD_IS_COL(cmd) \ + || CMD_IS_DL(cmd) \ + || CMD_IS_SETTIMG(cmd) \ + || CMD_IS_SETCIMG(cmd) \ + || CMD_IS_SETZIMG(cmd)) + +/** + * Segment 5 is the start of the model file. The data in these files shifts + * depending on the pointer size, so this function adjusts the offset accordingly. + */ +static u64 gbiRewriteAddr(u64 cmd, u8 opcode) +{ + u8 segment = (cmd & 0x0f000000) >> 24; + u32 offset = cmd & 0x00ffffff; + + if (segment == 5) { + if (opcode == 0xfd) { + offset = gbiFindTexAddr(offset); + } + else { + if (offset < srcVtxOffset) { + sysFatalError("Tried to load data from offset 0x%x but segment starts at 0x%x\n", offset, srcVtxOffset); + } + + offset = offset - srcVtxOffset + dstVtxOffset; + } + } + + return (cmd & 0xffffffffff000000) | offset; +} + +void gbiGdlRewriteAddrs(u8 *dst, u32 offset) +{ + if (!offset) return; + + u64 *cmds = (u64 *)(dst + (offset & 0x00ffffff)); + if (!cmds) return; + + u64 cmd; + + do { + cmd = *cmds; + Gfx* gfxcmd = (Gfx *)cmds; + int idx = 0; + u8 opcode = (cmd >> 24) & 0xff; + +#if HOST_DWORDS_PER_CMD == 2 + idx = 1; + opcode = (cmd >> 24) & 0xff; +#endif + cmd = (u64)opcode << 56; + + if (CMD_HAS_ADDR(cmd)) { + cmds[idx] = gbiRewriteAddr(cmds[idx], opcode); + } + + if (CMD_IS_SEGMENTED(cmd)) { + gfxcmd->words.w1 |= 1; + } + + cmds += HOST_DWORDS_PER_CMD; + } while (!CMD_IS_ENDDL(cmd)); +} + +u32 gbiConvertGdl(u8 *dst, u32 dstpos, u8 *src, u32 srcpos, int segment_cmds) +{ + dstpos = ALIGN8(dstpos); + + u64 *n64_cmd = (u64*)&src[srcpos]; + u64 *host_cmd = (u64*)&dst[dstpos]; + u64 cmd; + + do { + cmd = PD_BE64(*n64_cmd); + +#if HOST_DWORDS_PER_CMD == 2 + host_cmd[0] = ((cmd & 0xffffffff00000000) >> 32); + host_cmd[1] = (cmd & 0xffffffff); + + if (segment_cmds && CMD_IS_SEGMENTED(cmd)) { + host_cmd[1] |= 1; + } +#else + host_cmd[0] = (cmd >> 32) | ((cmd & 0xffffffff) << 32); + + if (segment_cmds && CMD_IS_SEGMENTED(cmd)) { + Gfx* gfxcmd = (Gfx*)host_cmd; + gfxcmd->words.w1 |= 1; + } +#endif + + dstpos += sizeof(*host_cmd) * HOST_DWORDS_PER_CMD; + host_cmd += HOST_DWORDS_PER_CMD; + n64_cmd++; + } while (!CMD_IS_ENDDL(cmd)); + + return dstpos; +} diff --git a/port/src/preprocess/misc.c b/port/src/preprocess/misc.c new file mode 100644 index 000000000..6853a4e7a --- /dev/null +++ b/port/src/preprocess/misc.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include + +#include "data.h" +#include "bss.h" +#include "game/setuputils.h" +#include "game/texdecompress.h" +#include "mod.h" + +#include "preprocess/common.h" + +u8 *preprocessAnimations(u8* data, u32 size, u32* outSize) +{ + // set the anim table pointers as well + extern u8 *_animationsTableRomStart; + extern u8 *_animationsTableRomEnd; + + // the animation table is at the end of the segment + u32 *animtbl = (void *)(data + size - 0x38a0); + _animationsTableRomStart = (u8 *)animtbl; + _animationsTableRomEnd = data + size; + + PD_SWAP_VAL(*animtbl); + const u32 count = *animtbl++; + + struct animtableentry *anim = (struct animtableentry *)animtbl; + for (u32 i = 0; i < count; ++i, ++anim) { + PD_SWAP_VAL(anim->numframes); + PD_SWAP_VAL(anim->bytesperframe); + PD_SWAP_VAL(anim->headerlen); + PD_SWAP_VAL(anim->data); + // if an external replacement exists, replace the table entry and mark the offset + if (modAnimationLoadDescriptor(i, anim) > 0) { + anim->data = 0xffffffff; + } + } + + return NULL; +} + +u8 *preprocessMpConfigs(u8* data, u32 size, u32* outSize) +{ + const u32 count = size / sizeof(struct mpconfig); + struct mpconfig *cfg = (struct mpconfig *)data; + for (u32 i = 0; i < count; ++i, ++cfg) { + PD_SWAP_VAL(cfg->setup.options); + PD_SWAP_VAL(cfg->setup.teamscorelimit); + PD_SWAP_VAL(cfg->setup.chrslots); +#if MAX_PLAYERS > 4 + // make space for the extra players + cfg->setup.chrslots = (cfg->setup.chrslots & 0x000f) | ((cfg->setup.chrslots & 0x0ff0) << 4); +#endif + // TODO: are these required or are they always 0? + PD_SWAP_VAL(cfg->setup.fileguid.deviceserial); + PD_SWAP_VAL(cfg->setup.fileguid.fileid); + // convert MPWEAPON_ to take classic weapons and JPN weapons into account + for (s32 j = 0; j < ARRAYCOUNT(cfg->setup.weapons); ++j) { +#if VERSION == VERSION_JPN_FINAL /* TODO: replace with runtime check */ + if (cfg->setup.weapons[j] >= 0x24) { + // weapons after and including the shield need to be shifted + cfg->setup.weapons[j] += (MPWEAPON_SHIELD - MPWEAPON_PP9I); + } + if (cfg->setup.weapons[j] >= 0x19) { + // weapons after the combat knife also need to be shifted up in JPN + cfg->setup.weapons[j]++; + } +#else + // in other versions we only care about the shield and above + if (cfg->setup.weapons[j] >= 0x25) { + cfg->setup.weapons[j] += (MPWEAPON_SHIELD - MPWEAPON_PP9I); + } +#endif + } + } + + return NULL; +} + +u8 *preprocessTexturesList(u8* data, u32 size, u32* outSize) +{ + struct texture *tex = (struct texture *)data; + const u32 count = size / sizeof(*tex); + for (u32 i = 0; i < count; ++i, ++tex) { + // TODO: it sure looks like none of the fields except soundsurfacetype, surfacetype and dataoffset are set + // just swap the last 3 bytes of the first word... + const u32 dofs = (u32)tex->dataoffset << 8; + tex->dataoffset = PD_BE32(dofs); + // ...and the surface types in the first byte + const u8 tmp = tex->soundsurfacetype; + tex->soundsurfacetype = tex->surfacetype; + tex->surfacetype = tmp; + } + + return NULL; +} diff --git a/port/src/preprocess/segaudio.c b/port/src/preprocess/segaudio.c new file mode 100644 index 000000000..3ddbdf5f3 --- /dev/null +++ b/port/src/preprocess/segaudio.c @@ -0,0 +1,362 @@ +#include +#include +#include + +#include "libaudio.h" + +#include "preprocess/common.h" + +struct n64_adpcm_waveinfo { + u32 loop; // ptr to ALADPCMloop + u32 book; // ptr to ALADPCMBook +}; + +struct n64_raw_waveinfo { + u32 loop; // ptr to ALRawLoop +}; + +struct n64_wavetable { + u32 base; + s32 len; + u8 type; + u8 flags; + union { + struct n64_adpcm_waveinfo adpcmWave; + struct n64_raw_waveinfo rawWave; + } waveInfo; +}; + +struct n64_sound { + u32 envelope; // ptr to ALEnvelope + u32 keyMap; // ptr to ALKeyMap + u32 wavetable; // ptr to struct n64_wavetable + u8 samplePan; + u8 sampleVolume; + u8 flags; +}; + +struct n64_instrument { + u8 volume; + u8 pan; + u8 priority; + u8 flags; + u8 tremType; + u8 tremRate; + u8 tremDepth; + u8 tremDelay; + u8 vibType; + u8 vibRate; + u8 vibDepth; + u8 vibDelay; + s16 bendRange; + s16 soundCount; + u32 soundArray[1]; // ptr to struct n64_sound +}; + +struct n64_bank { + s16 instCount; + u8 flags; + u8 pad; + s32 sampleRate; + u32 percussion; // ptr to struct n64_instrument + u32 instArray[1]; // ptr to struct n64_instrument +}; + +struct n64_bankfile { + s16 revision; + s16 bankCount; + u32 bankArray[1]; // ptr to struct n64_bank +}; + +// only proceeds to convert the next item if it's not already converted +#define AL_NEXT_ITEM(field, func) { \ + struct ptrmarker *marker = ptrFind(srcpos); \ + if (marker == NULL) { \ + field = (void *)(uintptr_t)(dstpos); \ + ptrAdd(srcpos, (uintptr_t)(field)); \ + dstpos = func(dst, dstpos, src, srcpos); \ + } else { \ + field = (void *)marker->ptr_host; } \ +} + +static u32 convertAudioEnvelope(u8 *dst, u32 dstpos, u8 *src, u32 srcpos) +{ + ALEnvelope *n64_envelope = (ALEnvelope *) &src[srcpos]; + ALEnvelope *host_envelope = (ALEnvelope *) &dst[dstpos]; + + dstpos += sizeof(ALEnvelope); + + host_envelope->attackTime = PD_BE32(n64_envelope->attackTime); + host_envelope->decayTime = PD_BE32(n64_envelope->decayTime); + host_envelope->releaseTime = PD_BE32(n64_envelope->releaseTime); + host_envelope->attackVolume = n64_envelope->attackVolume; + host_envelope->decayVolume = n64_envelope->decayVolume; + + return dstpos; +} + +static u32 convertAudioKeyMap(u8 *dst, u32 dstpos, u8 *src, u32 srcpos) +{ + ALKeyMap *n64_keymap = (ALKeyMap *) &src[srcpos]; + ALKeyMap *host_keymap = (ALKeyMap *) &dst[dstpos]; + + dstpos += sizeof(ALKeyMap); + + host_keymap->velocityMin = n64_keymap->velocityMin; + host_keymap->velocityMax = n64_keymap->velocityMax; + host_keymap->keyMin = n64_keymap->keyMin; + host_keymap->keyMax = n64_keymap->keyMax; + host_keymap->keyBase = n64_keymap->keyBase; + host_keymap->detune = n64_keymap->detune; + + return dstpos; +} + +static u32 convertAudioAdpcmLoop(u8 *dst, u32 dstpos, u8 *src, u32 srcpos) +{ + ALADPCMloop *n64_loop = (ALADPCMloop *) &src[srcpos]; + ALADPCMloop *host_loop = (ALADPCMloop *) &dst[dstpos]; + + dstpos += sizeof(ALADPCMloop); + + host_loop->start = PD_BE32(n64_loop->start); + host_loop->end = PD_BE32(n64_loop->end); + host_loop->count = PD_BE32(n64_loop->count); + + for (int i = 0; i < ARRAYCOUNT(host_loop->state); i++) { + host_loop->state[i] = PD_BE16(n64_loop->state[i]); + } + + return dstpos; +} + +static u32 convertAudioAdpcmBook(u8 *dst, u32 dstpos, u8 *src, u32 srcpos) +{ + ALADPCMBook *n64_book = (ALADPCMBook *) &src[srcpos]; + ALADPCMBook *host_book = (ALADPCMBook *) &dst[dstpos]; + + dstpos += sizeof(ALADPCMBook); + + host_book->order = PD_BE32(n64_book->order); + host_book->npredictors = PD_BE32(n64_book->npredictors); + + for (int i = 0; i < ARRAYCOUNT(host_book->book); i++) { + host_book->book[i] = PD_BE16(n64_book->book[i]); + } + + return dstpos; +} + +static u32 convertAudioRawLoop(u8 *dst, u32 dstpos, u8 *src, u32 srcpos) +{ + ALRawLoop *n64_loop = (ALRawLoop *) &src[srcpos]; + ALRawLoop *host_loop = (ALRawLoop *) &dst[dstpos]; + + dstpos += sizeof(ALRawLoop); + + host_loop->start = PD_BE32(n64_loop->start); + host_loop->end = PD_BE32(n64_loop->end); + host_loop->count = PD_BE32(n64_loop->count); + + return dstpos; +} + +static u32 convertAudioWaveTable(u8 *dst, u32 dstpos, u8 *src, u32 srcpos) +{ + struct n64_wavetable *n64_wavetable = (struct n64_wavetable *) &src[srcpos]; + ALWaveTable *host_wavetable = (ALWaveTable *) &dst[dstpos]; + + dstpos += sizeof(ALWaveTable); + + host_wavetable->base = (void *)(uintptr_t)PD_BE32(n64_wavetable->base); + host_wavetable->len = PD_BE32(n64_wavetable->len); + host_wavetable->type = n64_wavetable->type; + host_wavetable->flags = n64_wavetable->flags; + + if (host_wavetable->type == AL_ADPCM_WAVE) { + if (n64_wavetable->waveInfo.adpcmWave.loop) { + srcpos = PD_BE32(n64_wavetable->waveInfo.adpcmWave.loop); + AL_NEXT_ITEM(host_wavetable->waveInfo.adpcmWave.loop, convertAudioAdpcmLoop); + } else { + host_wavetable->waveInfo.adpcmWave.loop = NULL; + } + + if (n64_wavetable->waveInfo.adpcmWave.book) { + srcpos = PD_BE32(n64_wavetable->waveInfo.adpcmWave.book); + AL_NEXT_ITEM(host_wavetable->waveInfo.adpcmWave.book, convertAudioAdpcmBook); + } else { + host_wavetable->waveInfo.adpcmWave.book = NULL; + } + } else if (host_wavetable->type == AL_RAW16_WAVE) { + if (n64_wavetable->waveInfo.rawWave.loop) { + srcpos = PD_BE32(n64_wavetable->waveInfo.rawWave.loop); + AL_NEXT_ITEM(host_wavetable->waveInfo.rawWave.loop, convertAudioRawLoop); + } else { + host_wavetable->waveInfo.rawWave.loop = NULL; + } + } + + return dstpos; +} + +static u32 convertAudioSound(u8 *dst, u32 dstpos, u8 *src, u32 srcpos) +{ + struct n64_sound *n64_sound = (struct n64_sound *) &src[srcpos]; + ALSound *host_sound = (ALSound *) &dst[dstpos]; + + dstpos += sizeof(ALSound); + + if (n64_sound->envelope) { + srcpos = PD_BE32(n64_sound->envelope); + AL_NEXT_ITEM(host_sound->envelope, convertAudioEnvelope); + } else { + host_sound->envelope = NULL; + } + + if (n64_sound->keyMap) { + srcpos = PD_BE32(n64_sound->keyMap); + AL_NEXT_ITEM(host_sound->keyMap, convertAudioKeyMap); + } else { + host_sound->keyMap = NULL; + } + + if (n64_sound->wavetable) { + srcpos = PD_BE32(n64_sound->wavetable); + AL_NEXT_ITEM(host_sound->wavetable, convertAudioWaveTable); + } else { + host_sound->wavetable = NULL; + } + + host_sound->samplePan = n64_sound->samplePan; + host_sound->sampleVolume = n64_sound->sampleVolume; + host_sound->flags = n64_sound->flags; + + return dstpos; +} + +static u32 convertAudioInstrument(u8 *dst, u32 dstpos, u8 *src, u32 srcpos) +{ + struct n64_instrument *n64_instrument = (struct n64_instrument *) &src[srcpos]; + ALInstrument *host_instrument = (ALInstrument *) &dst[dstpos]; + const s16 soundCount = PD_BE16(n64_instrument->soundCount); + + host_instrument->volume = n64_instrument->volume; + host_instrument->pan = n64_instrument->pan; + host_instrument->priority = n64_instrument->priority; + host_instrument->flags = n64_instrument->flags; + host_instrument->tremType = n64_instrument->tremType; + host_instrument->tremRate = n64_instrument->tremRate; + host_instrument->tremDepth = n64_instrument->tremDepth; + host_instrument->tremDelay = n64_instrument->tremDelay; + host_instrument->vibType = n64_instrument->vibType; + host_instrument->vibRate = n64_instrument->vibRate; + host_instrument->vibDepth = n64_instrument->vibDepth; + host_instrument->vibDelay = n64_instrument->vibDelay; + host_instrument->bendRange = PD_BE16(n64_instrument->bendRange); + host_instrument->soundCount = (soundCount); + + dstpos = dstpos + sizeof(ALInstrument) + sizeof(uintptr_t) * (soundCount - 1); + + for (int i = 0; i < soundCount; i++) { + srcpos = PD_BE32(n64_instrument->soundArray[i]); + AL_NEXT_ITEM(host_instrument->soundArray[i], convertAudioSound); + } + + return dstpos; +} + +static u32 convertAudioBank(u8 *dst, u32 dstpos, u8 *src, u32 srcpos) +{ + struct n64_bank *n64_bank = (struct n64_bank *) &src[srcpos]; + ALBank *host_bank = (ALBank *) &dst[dstpos]; + const s16 instCount = PD_BE16(n64_bank->instCount); + + host_bank->instCount = (instCount); + host_bank->flags = n64_bank->flags; + host_bank->pad = n64_bank->pad; + host_bank->sampleRate = PD_BE32(n64_bank->sampleRate); + + dstpos = dstpos + sizeof(ALBank) + sizeof(uintptr_t) * (instCount - 1); + + if (n64_bank->percussion) { + srcpos = PD_BE32(n64_bank->percussion); + AL_NEXT_ITEM(host_bank->percussion, convertAudioInstrument); + } else { + host_bank->percussion = 0; + } + + for (int i = 0; i < instCount; i++) { + srcpos = PD_BE32(n64_bank->instArray[i]); + AL_NEXT_ITEM(host_bank->instArray[i], convertAudioInstrument); + } + + return dstpos; +} + +static u32 convertAudioBankFile(u8 *dst, u8 *src) +{ + struct n64_bankfile *n64_bankfile = (struct n64_bankfile *)src; + ALBankFile *host_bankfile = (ALBankFile *)dst; + const s16 bankCount = PD_BE16(n64_bankfile->bankCount); + + host_bankfile->revision = PD_BE16(n64_bankfile->revision); + host_bankfile->bankCount = (bankCount); + + u32 dstpos = sizeof(ALBankFile) + sizeof(uintptr_t) * (bankCount - 1); + + for (int i = 0; i < bankCount; i++) { + host_bankfile->bankArray[i] = (void *)(uintptr_t)(dstpos); + u32 srcpos = PD_BE32(n64_bankfile->bankArray[i]); + dstpos = convertAudioBank(dst, dstpos, src, srcpos); + } + + return dstpos; +} + +u8 *preprocessALBankFile(u8 *src, u32 size, u32 *outSize) +{ + ptrReset(); + + const u32 dstlen = size * 3; // this should overshoot any possible bank size, but * 2 also works for vanilla banks + u8 *dst = sysMemZeroAlloc(dstlen); + + u32 reallen = convertAudioBankFile(dst, src); + if (reallen > dstlen || ALIGN16(reallen) > dstlen) { + sysFatalError("overflow when trying to preprocess an ALBankFile, size %u dstlen %u reallen %u", size, dstlen, reallen); + } + + reallen = ALIGN16(reallen); + + if (reallen < dstlen) { + dst = sysMemRealloc(dst, reallen); + } + + *outSize = reallen; + + return dst; +} + + +u8 *preprocessALCMidiHdr(u8 *data, u32 size, u32 *outSize) +{ + ALCMidiHdr *hdr = (ALCMidiHdr *)data; + PD_SWAP_VAL(hdr->division); + for (s32 i = 0; i < ARRAYCOUNT(hdr->trackOffset); ++i) { + PD_SWAP_VAL(hdr->trackOffset[i]); + } + return NULL; +} + +u8 *preprocessSequences(u8* data, u32 size, u32 *outSize) +{ + struct seqtable *seq = (struct seqtable *)data; + PD_SWAP_VAL(seq->count); + + for (s16 i = 0; i < seq->count; ++i) { + PD_SWAP_VAL(seq->entries[i].binlen); + PD_SWAP_VAL(seq->entries[i].ziplen); + PD_SWAP_VAL(seq->entries[i].romaddr); + } + + return NULL; +} diff --git a/port/src/preprocess/segfonts.c b/port/src/preprocess/segfonts.c new file mode 100644 index 000000000..20dbdc7ec --- /dev/null +++ b/port/src/preprocess/segfonts.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include + +#include "preprocess/common.h" + +struct n64_fontchar { + u8 index; + s8 baseline; + u8 height; + u8 width; + s32 kerningindex; + u32 pixeldata; +}; + +struct n64_fontcharjpn { + u16 index; + s8 baseline; + u8 height; + u8 width; + s16 kerningindex; + u32 pixeldata; +}; + +u8 *preprocessFont(u8 *src, u32 srclen, u32 *outSize) +{ + int num_chars = 94; +#if VERSION == VERSION_PAL_FINAL + // PAL has more characters in these fonts + extern u8* _fonthandelgothicsmSegmentRomStart; + extern u8* _fonthandelgothicxsSegmentRomStart; + extern u8* _fonthandelgothicmdSegmentRomStart; + if (src == _fonthandelgothicsmSegmentRomStart + || src == _fonthandelgothicxsSegmentRomStart + || src == _fonthandelgothicmdSegmentRomStart) { + num_chars = 135; + } +#endif + + size_t dstlen = srclen - (num_chars * sizeof(struct n64_fontchar)) + (num_chars * sizeof(struct fontchar)) + 0x20; + u8* dst = sysMemZeroAlloc(dstlen); + + // Kerning table + s32 *src_kerning_table = (s32 *)src; + s32 *dst_kerning_table = (s32 *)dst; + + for (int i = 0; i < 13 * 13; i++) { + dst_kerning_table[i] = PD_BE32(src_kerning_table[i]); + } + + u32 src_offset = PD_ALIGN(13 * 13 * 4, sizeof(u32)); + u32 dst_offset = PD_ALIGN(13 * 13 * 4, sizeof(uintptr_t)); + + // Character table +#if VERSION == VERSION_JPN_FINAL + struct n64_fontcharjpn *src_char_table = (struct n64_fontcharjpn *) &src[src_offset]; + struct fontchar *dst_char_table = (struct fontchar *) &dst[dst_offset]; + u32 diff = (dst_offset + num_chars * sizeof(struct fontchar)) - (src_offset + num_chars * sizeof(struct n64_fontcharjpn)); + + for (int i = 0; i < num_chars; i++) { + dst_char_table[i].index = PD_BE16(src_char_table[i].index); + dst_char_table[i].baseline = src_char_table[i].baseline; + dst_char_table[i].height = src_char_table[i].height; + dst_char_table[i].width = src_char_table[i].width; + dst_char_table[i].kerningindex = PD_BE16(src_char_table[i].kerningindex); + dst_char_table[i].pixeldata = (void *)(uintptr_t)(src_char_table[i].pixeldata ? PD_BE32(src_char_table[i].pixeldata) + diff : 0); + } + + src_offset += num_chars * sizeof(struct n64_fontcharjpn); + dst_offset += num_chars * sizeof(struct fontchar); +#else + struct n64_fontchar *src_char_table = (struct n64_fontchar *) &src[src_offset]; + struct fontchar *dst_char_table = (struct fontchar *) &dst[dst_offset]; + u32 diff = (dst_offset + num_chars * sizeof(struct fontchar)) - (src_offset + num_chars * sizeof(struct n64_fontchar)); + + for (int i = 0; i < num_chars; i++) { + dst_char_table[i].index = src_char_table[i].index; + dst_char_table[i].baseline = src_char_table[i].baseline; + dst_char_table[i].height = src_char_table[i].height; + dst_char_table[i].width = src_char_table[i].width; + dst_char_table[i].kerningindex = PD_BE32(src_char_table[i].kerningindex); + dst_char_table[i].pixeldata = (void *)(uintptr_t)(src_char_table[i].pixeldata ? PD_BE32(src_char_table[i].pixeldata) + diff : 0); + } + + src_offset += num_chars * sizeof(struct n64_fontchar); + dst_offset += num_chars * sizeof(struct fontchar); +#endif + + // Pixel data + u32 len = srclen - src_offset; + memcpy(&dst[dst_offset], &src[src_offset], len); + + if (outSize) *outSize = ALIGN16(dst_offset + len); + + return dst; +} + +u8 *preprocessJpnFont(u8* data, u32 size, u32* outSize) +{ + // ??? + return NULL; +} diff --git a/port/src/romdata.c b/port/src/romdata.c index 0f9a7fc32..8a3acd782 100644 --- a/port/src/romdata.c +++ b/port/src/romdata.c @@ -4,7 +4,6 @@ #include #include #include -#include #include "lib/rzip.h" #include "romdata.h" #include "fs.h" @@ -239,6 +238,17 @@ static inline void romdataLoadRom(void) romDataSegSize = dataSegLen; } +static inline void romdataUpdateSegStartEnd(struct romfile* seg) +{ + if (seg->segstart) { + *seg->segstart = seg->data; + } + + if (seg->segend) { + *seg->segend = seg->data + seg->size; + } +} + static inline void romdataInitSegment(struct romfile *seg) { if (!seg->data) { @@ -254,7 +264,7 @@ static inline void romdataInitSegment(struct romfile *seg) seg->size = seg[1].data - seg->data; } else { // this is the last segment, calculate based on rom size - seg->size = (u8 *)g_RomFileSize - seg->data; + seg->size = (uintptr_t)g_RomFileSize - (uintptr_t)seg->data; } } @@ -272,7 +282,7 @@ static inline void romdataInitSegment(struct romfile *seg) if (g_RomFile) { newData = g_RomFile + (uintptr_t)seg->data; seg->source = SRC_ROM; - sysLogPrintf(LOG_NOTE, "loading segment %s from ROM (offset %08x pointer %p)", seg->name, (u32)seg->data, newData); + sysLogPrintf(LOG_NOTE, "loading segment %s from ROM (offset %08x pointer %p)", seg->name, (uintptr_t)seg->data, newData); } else { sysFatalError("No ROM or external file for segment:\n%s", seg->name); } @@ -284,17 +294,19 @@ static inline void romdataInitSegment(struct romfile *seg) seg->data = newData; - if (seg->segstart) { - *seg->segstart = seg->data; - } - - if (seg->segend) { - *seg->segend = seg->data + seg->size; - } + romdataUpdateSegStartEnd(seg); // call the post load function if any if (seg->preprocess && !seg->preprocessed) { - seg->preprocess(seg->data, seg->size); + newData = seg->preprocess(seg->data, seg->size, &seg->size); + + if (newData) { + if (seg->source == SRC_EXTERNAL) + sysMemFree(seg->data); + seg->data = newData; + romdataUpdateSegStartEnd(seg); + } + seg->preprocessed = 1; } } @@ -497,7 +509,7 @@ u8 *romdataFileLoad(s32 fileNum, u32 *outSize) return out; } -void romdataFilePreprocess(s32 fileNum, s32 loadType, u8 *data, u32 size) +void romdataFilePreprocess(s32 fileNum, s32 loadType, u8 *data, u32 size, u32 *outSize) { if (fileNum < 1 || fileNum >= ROMDATA_MAX_FILES) { sysLogPrintf(LOG_ERROR, "romdataFilePreprocess: invalid file num %d", fileNum); @@ -515,7 +527,7 @@ void romdataFilePreprocess(s32 fileNum, s32 loadType, u8 *data, u32 size) } } // then preprocess - filePreprocFuncs[loadType](data, size); + filePreprocFuncs[loadType](data, size, outSize); // fileSlots[fileNum].preprocessed = 1; } } @@ -574,3 +586,21 @@ u32 romdataSegGetSize(const char *segName) { return romdataGetSeg(segName)->size; } + +u32 romdataFileGetEstimatedSize(const u32 size, const u32 loadtype) +{ +#ifdef PLATFORM_64BIT + switch (loadtype) { + case LOADTYPE_BG: return (u32)(size * 1.1f); + case LOADTYPE_TILES: return (u32)(size * 1.1f); + case LOADTYPE_LANG: return (u32)(size * 1.3f); + case LOADTYPE_SETUP: return (u32)(size * 1.5f); + case LOADTYPE_PADS: return (u32)(size * 1.7f); + case LOADTYPE_MODEL: return (u32)(size * 1.7f); + case LOADTYPE_GUN: return (u32)(size * 1.7f); + default: + sysLogPrintf(LOG_WARNING, "romdataFileGetEstimatedSize: wrong loadtype %d", loadtype); + } +#endif + return size; +} diff --git a/port/src/system.c b/port/src/system.c index 608345ae9..f732af311 100644 --- a/port/src/system.c +++ b/port/src/system.c @@ -300,6 +300,11 @@ void *sysMemZeroAlloc(const u32 size) return calloc(1, size); } +void *sysMemRealloc(void *ptr, const u32 newSize) +{ + return realloc(ptr, newSize); +} + void sysMemFree(void *ptr) { free(ptr); diff --git a/src/game/activemenu.c b/src/game/activemenu.c index 0813b3f6a..93cac78fb 100644 --- a/src/game/activemenu.c +++ b/src/game/activemenu.c @@ -177,7 +177,7 @@ MenuItemHandlerResult amPickTargetMenuList(s32 operation, struct menuitem *item, gdl = text0f153628(gdl); gdl = textRenderProjected(gdl, &x, &y, g_MpAllChrConfigPtrs[chrindex]->name, g_CharsHandelGothicSm, g_FontHandelGothicSm, colour, viGetWidth(), viGetHeight(), 0, 0); gdl = text0f153780(gdl); - return (s32)gdl; + return (uintptr_t)gdl; } case MENUOP_GETOPTIONHEIGHT: data->list.value = LINEHEIGHT; diff --git a/src/game/bg.c b/src/game/bg.c index c6dddc699..0b71bbdf4 100644 --- a/src/game/bg.c +++ b/src/game/bg.c @@ -47,6 +47,7 @@ #include "preprocess.h" #include "system.h" #include "video.h" +#include "platform.h" #endif #define BGCMD_END 0x00 @@ -97,7 +98,7 @@ u16 g_BgUnloadDelay240; u16 g_BgUnloadDelay240_2; u32 var800a4bf4; RoomNum g_GlareRooms[100]; -u32 *g_BgPrimaryData2; +uintptr_t *g_BgPrimaryData2; struct bgroom *g_BgRooms; struct bgportal *g_BgPortals; struct portalmetric *g_PortalMetrics; @@ -113,7 +114,7 @@ struct portalcamcacheitem *g_PortalCameraCache; struct bgsnake g_BgSnake; s32 g_StageIndex = 1; -u32 var8007fc04 = 0; +uintptr_t var8007fc04 = 0; u8 *var8007fc08 = NULL; #if VERSION < VERSION_NTSC_1_0 @@ -763,7 +764,7 @@ Gfx *bgRenderGdlInXray(Gfx *gdl, s8 *readgdl, Vtx *vertices, s16 arg3[3]) gdl = bgProcessXrayTri(gdl, &xraydata, dmemvertices[x], dmemvertices[y], dmemvertices[z], dmemcolours[x], dmemcolours[y], dmemcolours[z], inrange[x], inrange[y], inrange[z]); } - readgdl += 8; + readgdl += sizeof(Gfx); } gdl = bgRenderXrayData(gdl, &xraydata); @@ -1468,7 +1469,7 @@ void bgReset(s32 stagenum) u32 section2compsize; u32 section2start; u32 section1compsize; - u32 scratch; + uintptr_t scratch; var8007fc0c = 8; @@ -1509,6 +1510,11 @@ void bgReset(s32 stagenum) primcompsize = *(u32 *)&header[8]; var8007fc54 = inflatedsize - primcompsize; var8007fc54 -= 0xc; + +#ifdef PLATFORM_64BIT + inflatedsize = romdataFileGetEstimatedSize(inflatedsize, LOADTYPE_BG); +#endif + inflatedsize = ALIGN16(inflatedsize); // Allocate space for the primary bg data @@ -1529,7 +1535,7 @@ void bgReset(s32 stagenum) bgInflate((u8 *) scratch, g_BgPrimaryData, primcompsize); #ifndef PLATFORM_N64 - preprocessBgSection1(g_BgPrimaryData, 0x0f000000); + preprocessBgSection1(g_BgPrimaryData, inflatedsize, 0x0f000000); #endif // Shrink the allocation (ie. free the scratch space) @@ -1606,7 +1612,7 @@ void bgReset(s32 stagenum) var800a4920 = *(u32 *)g_BgPrimaryData; if (var800a4920 == 0) { - g_BgPrimaryData2 = (u32 *)g_BgPrimaryData; + g_BgPrimaryData2 = (uintptr_t*)g_BgPrimaryData; g_BgRooms = (struct bgroom *)(g_BgPrimaryData2[1] + g_BgPrimaryData - 0x0f000000); goto foo; foo:; g_Vars.roomcount = 0; @@ -1998,10 +2004,6 @@ void bgBuildTables(s32 stagenum) numlightsptr++; } -#ifndef PLATFORM_N64 - preprocessBgLights(g_BgLightsFileData, 0); -#endif - // Free the section 3 allocation mempRealloc(section3, 0, MEMPOOL_STAGE); @@ -2820,6 +2822,11 @@ void bgLoadRoom(s32 roomnum) #endif } +#ifdef PLATFORM_64BIT + alloclen = alloclen * 4; // just to be safe for now, adjust properly later #TODO +#endif + + #ifdef PLATFORM_N64 bgGarbageCollectRooms(alloclen, false); @@ -2856,7 +2863,7 @@ void bgLoadRoom(s32 roomnum) // Inflate the data to the left side of the allocation inflatedlen = bgInflate(memaddr, allocation, g_BgRooms[roomnum + 1].unk00 - g_BgRooms[roomnum].unk00); #ifndef PLATFORM_N64 - preprocessBgRoom(allocation, g_BgRooms[roomnum].unk00); + inflatedlen = preprocessBgRoom(allocation, inflatedlen, g_BgRooms[roomnum].unk00); #endif g_Rooms[roomnum].gfxdata = (struct roomgfxdata *)allocation; @@ -2937,7 +2944,7 @@ void bgLoadRoom(s32 roomnum) // Copy gdls to the right-side of the allocation // and build a pointer array to them - texCopyGdls((void *) gfxblocks[0], (void *) (allocation + alloclen - (gfxblocks[numgdls] - gfxblocks[0])), (u32) (gfxblocks[numgdls] - gfxblocks[0])); + texCopyGdls((void *) gfxblocks[0], (void *) (allocation + alloclen - (gfxblocks[numgdls] - gfxblocks[0])), (uintptr_t) (gfxblocks[numgdls] - gfxblocks[0])); for (i = 0; i < numgdls + 1; i++) { gdlpointers[i] = gfxblocks[i] + (allocation + alloclen - gfxblocks[numgdls]); @@ -3640,7 +3647,7 @@ bool bgTestHitOnObj(struct coord *arg0, struct coord *arg1, struct coord *arg2, Gfx *imggdl = NULL; s32 texturenum; f32 lowestsqdist = MAXFLOAT; - s32 offset; + uintptr_t offset; s32 numvertices; Gfx *tri4gdl; s32 count; @@ -4243,7 +4250,7 @@ bool bgTestHitInVtxBatch(struct coord *arg0, struct coord *arg1, struct coord *a vtx = bgFindVerticesForGdl(roomnum, gdl); iter = &gdl[batch->gbicmdindex]; - vtx = (Vtx *)((UNSEGADDR(iter->words.w1) & 0xffffff) + (s32)vtx); + vtx = (Vtx *)((UNSEGADDR(iter->words.w1) & 0xffffff) + (uintptr_t)vtx); numvertices = (((u32) iter->bytes[GFX_W0_BYTE(1)] >> 4) & 0xf) + 1; ptr = var800a6470; diff --git a/src/game/bondgun.c b/src/game/bondgun.c index 19ef22a4f..a42c1f734 100644 --- a/src/game/bondgun.c +++ b/src/game/bondgun.c @@ -54,6 +54,7 @@ #include "data.h" #include "types.h" #ifndef PLATFORM_N64 +#include "platform.h" #include "game/stagetable.h" #include "video.h" #include "net/net.h" @@ -167,8 +168,13 @@ u32 fill2[1]; Lights1 var80070090 = gdSPDefLights1(0x96, 0x96, 0x96, 0xff, 0xff, 0xff, 0xb2, 0x4d, 0x2e); +#ifdef PLATFORM_64BIT +u32 g_BgunGunMemBaseSizeDefault = 150 * 1024 * 2; // #TODO adjust these values properly +u32 g_BgunGunMemBaseSize4Mb2P = 120 * 1024 * 2; +#else u32 g_BgunGunMemBaseSizeDefault = 150 * 1024; u32 g_BgunGunMemBaseSize4Mb2P = 120 * 1024; +#endif u16 g_CartFileNums[] = { FILE_GCARTRIDGE, @@ -3796,17 +3802,17 @@ void bgunTickGunLoad(void) { s32 i; s32 numthistick; - u32 remaining; + u64 remaining; s32 padding; - u32 allocsize; - u32 loadsize; - u32 ptr; + u64 allocsize; + u64 loadsize; + uintptr_t ptr; struct player *player = g_Vars.currentplayer; struct modeldef *modeldef; struct fileinfo *fileinfo; struct fileinfo *gunfileinfo; - s32 newvalue; - u32 end; + uintptr_t newvalue; + uintptr_t end; u32 stack; #if VERSION >= VERSION_NTSC_1_0 u32 stack2; @@ -3828,7 +3834,7 @@ void bgunTickGunLoad(void) *player->gunctrl.loadmemptr = ptr; *player->gunctrl.loadmemremaining = remaining; - loadsize = ALIGN64(fileGetInflatedSize(player->gunctrl.loadfilenum)) + 0x8000; + loadsize = ALIGN64(fileGetInflatedSize(player->gunctrl.loadfilenum, LOADTYPE_MODEL)) + 0x8000; osSyncPrintf("BriGun: Loading - %s, pMem 0x%08x Size %d\n"); @@ -3846,6 +3852,9 @@ void bgunTickGunLoad(void) // Reserve some space for textures allocsize = fileGetLoadedSize(player->gunctrl.loadfilenum) + 0xe00; +#ifdef PLATFORM_64BIT + allocsize += 0xe00; +#endif osSyncPrintf("BriGun: Used size %d (Ob Size %d)\n"); osSyncPrintf("BriGun: block len %d usedsize %d\n"); @@ -3856,7 +3865,7 @@ void bgunTickGunLoad(void) fileinfo = &g_FileInfo[player->gunctrl.loadfilenum]; fileinfo->allocsize = allocsize; - end = ALIGN16((s32)ptr + allocsize); + end = ALIGN16((uintptr_t)ptr + allocsize); allocsize = end - ptr; if (1); remaining -= allocsize; @@ -3927,7 +3936,7 @@ void bgunTickGunLoad(void) modeldef0f1a7560(modeldef, player->gunctrl.loadfilenum, 0x05000000, modeldef, &player->gunctrl.texpool, false); - fileGetInflatedSize(player->gunctrl.loadfilenum); + fileGetInflatedSize(player->gunctrl.loadfilenum, LOADTYPE_MODEL); fileGetLoadedSize(player->gunctrl.loadfilenum); fileGetLoadedSize(player->gunctrl.loadfilenum); fileGetLoadedSize(player->gunctrl.loadfilenum); @@ -3940,7 +3949,7 @@ void bgunTickGunLoad(void) newvalue = ALIGN64(texGetPoolLeftPos(&player->gunctrl.texpool)); remaining = *player->gunctrl.loadmemremaining; - remaining -= (s32)(newvalue - *player->gunctrl.loadmemptr); + remaining -= (intptr_t)(newvalue - *player->gunctrl.loadmemptr); *player->gunctrl.loadmemptr = newvalue; *player->gunctrl.loadmemremaining = remaining; @@ -4089,8 +4098,8 @@ void bgunTickMasterLoad(void) player->gunctrl.gunloadstate = GUNLOADSTATE_MODEL; player->gunctrl.loadfilenum = handfilenum; player->gunctrl.loadtomodeldef = &player->gunctrl.handmodeldef; - player->gunctrl.loadmemptr = (u32 *) &player->gunctrl.handmemloadptr; - player->gunctrl.loadmemremaining = (u32 *) &player->gunctrl.handmemloadremaining; + player->gunctrl.loadmemptr = (uintptr_t *) &player->gunctrl.handmemloadptr; + player->gunctrl.loadmemremaining = (uintptr_t*) &player->gunctrl.handmemloadremaining; } bgunTickGunLoad(); @@ -4117,8 +4126,8 @@ void bgunTickMasterLoad(void) player->gunctrl.gunloadstate = GUNLOADSTATE_MODEL; player->gunctrl.loadfilenum = filenum; player->gunctrl.loadtomodeldef = &player->gunctrl.gunmodeldef; - player->gunctrl.loadmemptr = (u32 *) &player->gunctrl.memloadptr; - player->gunctrl.loadmemremaining = (u32 *) &player->gunctrl.memloadremaining; + player->gunctrl.loadmemptr = (uintptr_t*) &player->gunctrl.memloadptr; + player->gunctrl.loadmemremaining = (uintptr_t*) &player->gunctrl.memloadremaining; } bgunTickGunLoad(); @@ -4159,8 +4168,8 @@ void bgunTickMasterLoad(void) player->gunctrl.loadfilenum = filenum; player->gunctrl.gunloadstate = GUNLOADSTATE_MODEL; player->gunctrl.loadtomodeldef = &player->gunctrl.cartmodeldef; - player->gunctrl.loadmemptr = (u32 *) &player->gunctrl.memloadptr; - player->gunctrl.loadmemremaining = (u32 *) &player->gunctrl.memloadremaining; + player->gunctrl.loadmemptr = (uintptr_t *) &player->gunctrl.memloadptr; + player->gunctrl.loadmemremaining = (uintptr_t*) &player->gunctrl.memloadremaining; break; } @@ -4186,18 +4195,18 @@ void bgunTickMasterLoad(void) modelInit(&hand->handmodel, player->gunctrl.handmodeldef, hand->handsavedata, false); } - hand->unk0dcc = (s32 *) player->gunctrl.memloadptr; + hand->unk0dcc = (uintptr_t *) player->gunctrl.memloadptr; - value = bgunCreateModelCmdList(&hand->gunmodel, player->gunctrl.gunmodeldef->rootnode, (s32 *) player->gunctrl.memloadptr); + value = bgunCreateModelCmdList(&hand->gunmodel, player->gunctrl.gunmodeldef->rootnode, (uintptr_t *) player->gunctrl.memloadptr); sum += value; player->gunctrl.memloadptr += value; player->gunctrl.memloadremaining -= value; if (player->gunctrl.handmodeldef != 0) { - hand->unk0dd0 = (s32 *) player->gunctrl.memloadptr; + hand->unk0dd0 = (uintptr_t*) player->gunctrl.memloadptr; - value = bgunCreateModelCmdList(&hand->handmodel, player->gunctrl.handmodeldef->rootnode, (s32 *) player->gunctrl.memloadptr); + value = bgunCreateModelCmdList(&hand->handmodel, player->gunctrl.handmodeldef->rootnode, (uintptr_t*) player->gunctrl.memloadptr); sum += value; player->gunctrl.memloadptr += value; @@ -6465,7 +6474,7 @@ void bgunDisarm(struct prop *attackerprop) * * With this function stubbed, part of the CMP150 model does not render. */ -void bgunExecuteModelCmdList(s32 *ptr) +void bgunExecuteModelCmdList(uintptr_t *ptr) { union modelrwdata *rwdata; struct modelnode *node; @@ -6522,7 +6531,7 @@ void bgunExecuteModelCmdList(s32 *ptr) * iterate the command list to update part visibility rather than iterate the * full model tree. */ -s32 bgunCreateModelCmdList(struct model *model, struct modelnode *nodearg, s32 *ptr) +s32 bgunCreateModelCmdList(struct model *model, struct modelnode *nodearg, uintptr_t *ptr) { s32 len = 0; struct modelnode *node = nodearg; @@ -6539,11 +6548,11 @@ s32 bgunCreateModelCmdList(struct model *model, struct modelnode *nodearg, s32 * rwdata->distance.visible = false; node->child = rodata->distance.target; ptr[0] = 0; - ptr[1] = (s32)rwdata; - ptr[2] = (s32)node; - ptr[3] = (s32)rodata->distance.target; + ptr[1] = (uintptr_t)rwdata; + ptr[2] = (uintptr_t)node; + ptr[3] = (uintptr_t)rodata->distance.target; ptr += 4; - len += 16; + len += 4 * sizeof(uintptr_t); break; case MODELNODETYPE_TOGGLE: rodata = node->rodata; @@ -6551,36 +6560,36 @@ s32 bgunCreateModelCmdList(struct model *model, struct modelnode *nodearg, s32 * rwdata->toggle.visible = true; node->child = rodata->toggle.target; ptr[0] = 1; - ptr[1] = (s32)rwdata; - ptr[2] = (s32)node; - ptr[3] = (s32)rodata->toggle.target; + ptr[1] = (uintptr_t)rwdata; + ptr[2] = (uintptr_t)node; + ptr[3] = (uintptr_t)rodata->toggle.target; ptr += 4; - len += 16; + len += 4 * sizeof(uintptr_t); break; case MODELNODETYPE_HEADSPOT: rwdata = modelGetNodeRwData(model, node); rwdata->headspot.headmodeldef = NULL; rwdata->headspot.rwdatas = NULL; ptr[0] = 2; - ptr[1] = (s32)rwdata; + ptr[1] = (uintptr_t)rwdata; ptr += 2; - len += 8; + len += 2 * sizeof(uintptr_t); break; case MODELNODETYPE_0B: rwdata = modelGetNodeRwData(model, node); rwdata->type0b.unk00 = 0; ptr[0] = 3; - ptr[1] = (s32)rwdata; + ptr[1] = (uintptr_t)rwdata; ptr += 2; - len += 8; + len += 2 * sizeof(uintptr_t); break; case MODELNODETYPE_CHRGUNFIRE: rwdata = modelGetNodeRwData(model, node); rwdata->chrgunfire.visible = false; ptr[0] = 4; - ptr[1] = (s32)rwdata; + ptr[1] = (uintptr_t)rwdata; ptr += 2; - len += 8; + len += 2 * sizeof(uintptr_t); break; case MODELNODETYPE_DL: rodata = node->rodata; @@ -6589,12 +6598,12 @@ s32 bgunCreateModelCmdList(struct model *model, struct modelnode *nodearg, s32 * rwdata->dl.gdl = rodata->dl.opagdl; rwdata->dl.colours = (void *)ALIGN8((uintptr_t)&rodata->dl.vertices[rodata->dl.numvertices]); ptr[0] = 5; - ptr[1] = (s32)rwdata; - ptr[2] = (s32)rwdata->dl.vertices; - ptr[3] = (s32)rwdata->dl.gdl; - ptr[4] = (s32)rwdata->dl.colours; + ptr[1] = (uintptr_t)rwdata; + ptr[2] = (uintptr_t)rwdata->dl.vertices; + ptr[3] = (uintptr_t)rwdata->dl.gdl; + ptr[4] = (uintptr_t)rwdata->dl.colours; ptr += 5; - len += 20; + len += 5 * sizeof(uintptr_t); break; } @@ -6618,7 +6627,7 @@ s32 bgunCreateModelCmdList(struct model *model, struct modelnode *nodearg, s32 * } *ptr = 6; - len += 4; + len += sizeof(uintptr_t); return len; } diff --git a/src/game/chr.c b/src/game/chr.c index 8d6e20f9e..79dce823f 100644 --- a/src/game/chr.c +++ b/src/game/chr.c @@ -3868,13 +3868,13 @@ void chr0f0260c4(struct model *model, s32 hitpart, struct modelnode *node, struc } if (rwdata->gdl == rodata->opagdl) { - gdlptr = (Gfx *)((uintptr_t)rodata->colours + ((u32)UNSEGADDR(rodata->opagdl) & 0xffffff)); + gdlptr = (Gfx *)((uintptr_t)rodata->colours + ((uintptr_t)UNSEGADDR(rodata->opagdl) & 0xffffff)); } else { gdlptr = rwdata->gdl; } if (rodata->xlugdl) { - gdlptr2 = (Gfx *)((uintptr_t)rodata->colours + ((u32)UNSEGADDR(rodata->xlugdl) & 0xffffff)); + gdlptr2 = (Gfx *)((uintptr_t)rodata->colours + ((uintptr_t)UNSEGADDR(rodata->xlugdl) & 0xffffff)); } else { gdlptr2 = NULL; } @@ -4028,13 +4028,13 @@ void chrBruise(struct model *model, s32 hitpart, struct modelnode *node, struct // use the space... after the model definition's colour table? // Let's hope that's not being used by other instances... if (rwdata->gdl == rodata->opagdl) { - gdlptr = (Gfx *)((uintptr_t)rodata->colours + ((u32)UNSEGADDR(rodata->opagdl) & 0xffffff)); + gdlptr = (Gfx *)((uintptr_t)rodata->colours + ((uintptr_t)UNSEGADDR(rodata->opagdl) & 0xffffff)); } else { gdlptr = rwdata->gdl; } if (rodata->xlugdl) { - gdlptr2 = (Gfx *)((uintptr_t)rodata->colours + ((u32)UNSEGADDR(rodata->xlugdl) & 0xffffff)); + gdlptr2 = (Gfx *)((uintptr_t)rodata->colours + ((uintptr_t)UNSEGADDR(rodata->xlugdl) & 0xffffff)); } else { gdlptr2 = NULL; } @@ -4170,13 +4170,13 @@ void chrBruise(struct model *model, s32 hitpart, struct modelnode *node, struct } if (rwdata->gdl == rodata->opagdl) { - gdlptr = (Gfx *)((uintptr_t)rodata->colours + ((u32)UNSEGADDR(rodata->opagdl) & 0xffffff)); + gdlptr = (Gfx *)((uintptr_t)rodata->colours + ((uintptr_t)UNSEGADDR(rodata->opagdl) & 0xffffff)); } else { gdlptr = rwdata->gdl; } if (rodata->xlugdl) { - gdlptr2 = (Gfx *)((uintptr_t)rodata->colours + ((u32)UNSEGADDR(rodata->xlugdl) & 0xffffff)); + gdlptr2 = (Gfx *)((uintptr_t)rodata->colours + ((uintptr_t)UNSEGADDR(rodata->xlugdl) & 0xffffff)); } else { gdlptr2 = NULL; } @@ -4218,7 +4218,7 @@ void chrBruise(struct model *model, s32 hitpart, struct modelnode *node, struct coordinate = vertices[i].z + (s32)spd4.f[2]; if (coordinate == bestcoords[2]) { - if ((uintptr_t)rwdata->colours == ALIGN8((u32)rodata->vertices + rodata->numvertices * sizeof(Vtx))) { + if ((uintptr_t)rwdata->colours == ALIGN8((uintptr_t)rodata->vertices + rodata->numvertices * sizeof(Vtx))) { Col *colours = vtxstoreAllocate(rodata->numcolours, VTXSTORETYPE_CHRCOL, 0, 0); s32 j; @@ -4365,13 +4365,13 @@ void chrDisfigure(struct chrdata *chr, struct coord *exppos, f32 damageradius) if (rwdata->vertices != rodata->vertices && (uintptr_t)rwdata->colours != ALIGN8((uintptr_t)&rodata->vertices[rodata->numvertices])) { if (rwdata->gdl == rodata->opagdl) { - gdlptr = (Gfx *)((uintptr_t)rodata->colours + ((s32)UNSEGADDR(rodata->opagdl) & 0xffffff)); + gdlptr = (Gfx *)((uintptr_t)rodata->colours + ((uintptr_t)UNSEGADDR(rodata->opagdl) & 0xffffff)); } else { gdlptr = rwdata->gdl; } if (rodata->xlugdl) { - gdlptr2 = (Gfx *)((uintptr_t)rodata->colours + ((s32)UNSEGADDR(rodata->xlugdl) & 0xffffff)); + gdlptr2 = (Gfx *)((uintptr_t)rodata->colours + ((uintptr_t)UNSEGADDR(rodata->xlugdl) & 0xffffff)); } else { gdlptr2 = NULL; } diff --git a/src/game/chrai.c b/src/game/chrai.c index ea5294dc0..1dfaefb71 100644 --- a/src/game/chrai.c +++ b/src/game/chrai.c @@ -814,3 +814,19 @@ u32 chraiGetCommandLength(u8 *ailist, u32 aioffset) return 1; } + +// used by ext_setup +u32 chraiGetAilistLength(u8* list) +{ + if (!list) return 0; + + u8* cmd = list; + + while (true) { + u8 type = cmd[1]; + cmd += chraiGetCommandLength(cmd, 0); + if (type == AICMD_END) break; + } + + return (u32)(cmd - list); +} diff --git a/src/game/dlights.c b/src/game/dlights.c index c00836a0a..93d59f826 100644 --- a/src/game/dlights.c +++ b/src/game/dlights.c @@ -28,6 +28,7 @@ #include "lib/lib_317f0.h" #include "data.h" #include "types.h" +#include "platform.h" const char var7f1a78e0[] = "LIGHTS : Hit occured on light %d in room %d\n"; const char var7f1a7910[] = "L2(%d) -> "; @@ -592,7 +593,11 @@ void func0f001c0c(void) table2size = align16(g_NumPortals * 4); table3size = align16(g_Vars.roomcount * 4); table4size = align16((u32)var8009cae0 * (u32)var8009cae0); +#ifdef PLATFORM_64BIT + sp68 = align16(g_Vars.roomcount * 8 * 2); +#else sp68 = align16(g_Vars.roomcount * 8); +#endif mempGetStageFree(); @@ -1049,7 +1054,7 @@ bool lightTickBroken(s32 roomnum, s32 lightnum) lightGetBboxCentre(roomnum, lightnum, ¢re); - room = (void *) ((u8 *) g_BgRooms + (u32) room); + room = (void *) ((u8 *) g_BgRooms + (uintptr_t) room); centre.x += room->pos.x; centre.y += room->pos.y; centre.z += room->pos.z; @@ -1695,11 +1700,19 @@ void func0f004c6c(void) u8 *ptr; u8 *backupptr; +#ifdef PLATFORM_64BIT + sp44 = align16(0x2000 * 2); + sp40 = align16(g_NumPortals * 4 * 2); + sp3c = align16(g_NumPortals * 0xc * 2); + sp38 = align16(g_NumPortals * 4 * 2); + sp34 = align16(g_NumPortals * 2 * 2); +#else sp44 = align16(0x2000); sp40 = align16(g_NumPortals * 4); sp3c = align16(g_NumPortals * 0xc); sp38 = align16(g_NumPortals * 4); sp34 = align16(g_NumPortals * 2); +#endif for (i = 0, s4 = sp38; i < g_NumPortals; i++) { if (i != 0) { diff --git a/src/game/dyntex.c b/src/game/dyntex.c index 97ebf827c..f132f6cc7 100644 --- a/src/game/dyntex.c +++ b/src/game/dyntex.c @@ -79,7 +79,7 @@ void dyntexUpdateLinear(Vtx *vertices, struct dyntextype *type) s32 i; for (i = 0; i < type->numvertices; i++) { - Vtx *vertex = (Vtx *)((s32)vertices + g_DyntexVertices[type->vertexlistoffset + i].offset); + Vtx *vertex = (Vtx *)((uintptr_t)vertices + g_DyntexVertices[type->vertexlistoffset + i].offset); vertex->t = g_DyntexVertices[type->vertexlistoffset + i].t + tmp; vertex->s = g_DyntexVertices[type->vertexlistoffset + i].s; @@ -91,7 +91,7 @@ void dyntexUpdateReset(Vtx *vertices, struct dyntextype *type) s32 i; for (i = 0; i < type->numvertices; i++) { - Vtx *vertex = (Vtx *)((s32)vertices + g_DyntexVertices[type->vertexlistoffset + i].offset); + Vtx *vertex = (Vtx *)((uintptr_t)vertices + g_DyntexVertices[type->vertexlistoffset + i].offset); vertex->s = 0; vertex->t = 0; @@ -104,7 +104,7 @@ void dyntexUpdateMonitor(Vtx *vertices, struct dyntextype *type) s32 i; for (i = 0; i < type->numvertices; i++) { - Vtx *vertex = (Vtx *)((s32)vertices + g_DyntexVertices[type->vertexlistoffset + i].offset); + Vtx *vertex = (Vtx *)((uintptr_t)vertices + g_DyntexVertices[type->vertexlistoffset + i].offset); vertex->t = g_DyntexVertices[type->vertexlistoffset + i].t - tmp; vertex->s = g_DyntexVertices[type->vertexlistoffset + i].s; @@ -124,7 +124,7 @@ void dyntexUpdateOcean(Vtx *vertices, struct dyntextype *type) mainOverrideVariable("ripsize", &ripsize); for (i = 0; i < type->numvertices; i++) { - Vtx *vertex = (Vtx *)((s32)vertices + g_DyntexVertices[type->vertexlistoffset + i].offset); + Vtx *vertex = (Vtx *)((uintptr_t)vertices + g_DyntexVertices[type->vertexlistoffset + i].offset); angle = ((g_DyntexVertices[type->vertexlistoffset + i].t % modula) / (f32) modula + f24) * M_BADTAU; vertex->t = g_DyntexVertices[type->vertexlistoffset + i].t + (s16) (sinf(angle) * ripsize); @@ -140,7 +140,7 @@ void dyntexUpdateArrows(Vtx *vertices, struct dyntextype *type) s32 i; for (i = 0; i < type->numvertices; i++) { - Vtx *vertex = (Vtx *)((s32)vertices + g_DyntexVertices[type->vertexlistoffset + i].offset); + Vtx *vertex = (Vtx *)((uintptr_t)vertices + g_DyntexVertices[type->vertexlistoffset + i].offset); vertex->s = g_DyntexVertices[type->vertexlistoffset + i].s + tmp; vertex->t = g_DyntexVertices[type->vertexlistoffset + i].t; @@ -182,7 +182,7 @@ void dyntexTickRoom(s32 roomnum, Vtx *vertices) // @bug: Using i for both outer and inner loops for (i = 0; i < type->numvertices; i++) { - Vtx *vertex = (Vtx *)((s32)vertices + g_DyntexVertices[type->vertexlistoffset + i].offset); + Vtx *vertex = (Vtx *)((uintptr_t)vertices + g_DyntexVertices[type->vertexlistoffset + i].offset); g_DyntexVertices[type->vertexlistoffset + i].s = vertex->s; g_DyntexVertices[type->vertexlistoffset + i].t = vertex->t; diff --git a/src/game/file.c b/src/game/file.c index 6bad0b536..95e486c25 100644 --- a/src/game/file.c +++ b/src/game/file.c @@ -11,7 +11,7 @@ #include "data.h" #include "types.h" #ifndef PLATFORM_N64 -#include "romdata.h" +#include "system.h" #endif /** @@ -4114,7 +4114,7 @@ u32 g_FileTable[] = { (uintptr_t) &_filenamesSegmentRomStart, }; #else // PLATFORM_N64 -u32 g_FileTable[NUM_FILES + 1]; // TODO: this is only used to get the filenum, remove this +uintptr_t g_FileTable[NUM_FILES + 1]; // TODO: this is only used to get the filenum, remove this #endif // PLATFORM_N64 romptr_t fileGetRomAddress(s32 filenum) @@ -4126,7 +4126,7 @@ romptr_t fileGetRomAddress(s32 filenum) #endif } -u32 fileGetRomSizeByTableAddress(u32 *filetableaddr) +u32 fileGetRomSizeByTableAddress(uintptr_t *filetableaddr) { #ifdef PLATFORM_N64 u32 size; @@ -4146,10 +4146,10 @@ u32 fileGetRomSizeByTableAddress(u32 *filetableaddr) s32 fileGetRomSize(s32 filenum) { - return fileGetRomSizeByTableAddress((u32 *)&g_FileTable[filenum]); + return fileGetRomSizeByTableAddress((uintptr_t*)&g_FileTable[filenum]); } -u32 file0f166ea8(u32 *filetableaddr) +u32 file0f166ea8(uintptr_t *filetableaddr) { return 0; } @@ -4158,7 +4158,7 @@ void fileLoad(u8 *dst, u32 allocationlen, romptr_t *romaddrptr, struct fileinfo { #ifndef PLATFORM_N64 // load the file first - const s32 filenum = (u32 *)romaddrptr - g_FileTable; + const s32 filenum = (uintptr_t *)romaddrptr - g_FileTable; u32 romsize = 0; u8 *filedata = romdataFileLoad(filenum, &romsize); if (!filedata) { @@ -4176,7 +4176,7 @@ void fileLoad(u8 *dst, u32 allocationlen, romptr_t *romaddrptr, struct fileinfo dmaExec(dst, *romaddrptr, romsize); } else { // DMA the compressed data to scratch space then inflate - u8 *scratch = (dst + allocationlen) - ((romsize + 7) & 0xfffffff8); + u8 *scratch = (dst + allocationlen) - ((romsize + 7) & (uintptr_t)~7); if ((uintptr_t)scratch - (uintptr_t)dst < 8) { info->loadedsize = 0; @@ -4209,7 +4209,7 @@ void fileLoad(u8 *dst, u32 allocationlen, romptr_t *romaddrptr, struct fileinfo #ifndef PLATFORM_N64 // byteswap/preprocess file according to g_LoadType right after inflating it const u32 dstsize = allocationlen ? info->loadedsize : romsize; - romdataFilePreprocess(filenum, g_LoadType, dst, dstsize); + romdataFilePreprocess(filenum, g_LoadType, dst, dstsize, &info->loadedsize); g_LoadType = LOADTYPE_NONE; #endif } @@ -4241,7 +4241,7 @@ void fileLoadPartToAddr(u16 filenum, void *memaddr, s32 offset, u32 len) { u32 stack[2]; - if (fileGetRomSizeByTableAddress((u32 *)&g_FileTable[filenum])) { + if (fileGetRomSizeByTableAddress((uintptr_t*)&g_FileTable[filenum])) { #ifdef PLATFORM_N64 dmaExec(memaddr, (romptr_t) g_FileTable[filenum] + offset, len); #else @@ -4255,11 +4255,11 @@ void fileLoadPartToAddr(u16 filenum, void *memaddr, s32 offset, u32 len) } } -u32 fileGetInflatedSize(s32 filenum) +u32 fileGetInflatedSize(s32 filenum, u32 loadtype) { u8 *ptr; u8 buffer[0x50]; - u32 *romaddrptr; + uintptr_t *romaddrptr; #if VERSION < VERSION_NTSC_1_0 char message[128]; #endif @@ -4283,7 +4283,7 @@ u32 fileGetInflatedSize(s32 filenum) } if (rzipIs1173(ptr)) { - return (ptr[2] << 16) | (ptr[3] << 8) | ptr[4]; + return romdataFileGetEstimatedSize((ptr[2] << 16) | (ptr[3] << 8) | ptr[4], loadtype); } #if VERSION < VERSION_NTSC_1_0 @@ -4300,7 +4300,7 @@ u32 fileGetInflatedSize(s32 filenum) return 0; } -void *fileLoadToNew(s32 filenum, u32 method) +void *fileLoadToNew(s32 filenum, u32 method, u32 loadtype) { struct fileinfo *info = &g_FileInfo[filenum]; u32 stack; @@ -4308,7 +4308,7 @@ void *fileLoadToNew(s32 filenum, u32 method) if (method == FILELOADMETHOD_EXTRAMEM || method == FILELOADMETHOD_DEFAULT) { if (info->loadedsize == 0) { - info->loadedsize = (fileGetInflatedSize(filenum) + 0x20) & 0xfffffff0; + info->loadedsize = (fileGetInflatedSize(filenum, loadtype) + 0x20) & 0xfffffff0; if (method == FILELOADMETHOD_EXTRAMEM) { info->loadedsize += 0x8000; @@ -4317,7 +4317,7 @@ void *fileLoadToNew(s32 filenum, u32 method) ptr = mempAlloc(info->loadedsize, MEMPOOL_STAGE); info->allocsize = info->loadedsize; - fileLoad(ptr, info->loadedsize, (u32 *)&g_FileTable[filenum], info); + fileLoad(ptr, info->loadedsize, (uintptr_t*)&g_FileTable[filenum], info); if (method != FILELOADMETHOD_EXTRAMEM) { mempRealloc(ptr, info->loadedsize, MEMPOOL_STAGE); @@ -4343,7 +4343,7 @@ void *fileLoadToAddr(s32 filenum, s32 method, u8 *ptr, u32 size) if (method == FILELOADMETHOD_EXTRAMEM || method == FILELOADMETHOD_DEFAULT) { info->allocsize = size; - fileLoad(ptr, size, (u32 *)&g_FileTable[filenum], info); + fileLoad(ptr, size, (uintptr_t*)&g_FileTable[filenum], info); } else { while (1); } diff --git a/src/game/filemgr.c b/src/game/filemgr.c index 3cee8c3c0..389f793ad 100644 --- a/src/game/filemgr.c +++ b/src/game/filemgr.c @@ -411,7 +411,7 @@ struct menudialogdef g_FilemgrErrorMenuDialog = { * For a file listing, iterate the devices until the one at optionindex is found. * Depending on operation, return the device name or index of the first file. */ -s32 filemgrGetDeviceNameOrStartIndex(s32 listnum, s32 operation, s32 optionindex) +uintptr_t filemgrGetDeviceNameOrStartIndex(s32 listnum, s32 operation, s32 optionindex) { u16 names[] = { L_OPTIONS_111, // "Game Pak" @@ -428,7 +428,7 @@ s32 filemgrGetDeviceNameOrStartIndex(s32 listnum, s32 operation, s32 optionindex if (g_FileLists[listnum]->devicestartindexes[i] != -1) { if (remaining == 0) { if (operation == MENUOP_GETOPTGROUPTEXT) { - return (s32)langGet(names[i]); + return (uintptr_t)langGet(names[i]); } return g_FileLists[listnum]->devicestartindexes[i]; @@ -1252,7 +1252,7 @@ void func0f1097d0(s32 device) thing = memaAlloc(align16(g_FileTypeSizes[g_Menus[g_MpPlayerNum].fm.filetypeplusone - 1])); if (thing) { - filemgrSaveOrLoad(&g_FilemgrFileToCopy, g_Menus[g_MpPlayerNum].fm.filetypeplusone + 103, (s32) thing); + filemgrSaveOrLoad(&g_FilemgrFileToCopy, g_Menus[g_MpPlayerNum].fm.filetypeplusone + 103, (uintptr_t) thing); } else { filemgrPushErrorDialog(FILEERROR_OUTOFMEMORY); } diff --git a/src/game/gfxmemory.c b/src/game/gfxmemory.c index 7bce8d1ac..0b34f71d3 100644 --- a/src/game/gfxmemory.c +++ b/src/game/gfxmemory.c @@ -11,6 +11,7 @@ #include "lib/str.h" #include "data.h" #include "types.h" +#include "platform.h" /** * This file handles memory usage for graphics related tasks. @@ -170,7 +171,11 @@ void *gfxAllocateMatrix(void) LookAt *gfxAllocateLookAt(s32 count) { void *ptr = g_GfxMemPos; +#ifdef PLATFORM_64BIT + g_GfxMemPos += count * (sizeof(LookAt) * 2); +#else g_GfxMemPos += count * (sizeof(LookAt) / 2); +#endif return ptr; } diff --git a/src/game/lang.c b/src/game/lang.c index b2e595371..b4c7bbd20 100644 --- a/src/game/lang.c +++ b/src/game/lang.c @@ -59,12 +59,12 @@ bool g_Jpn = VERSION == VERSION_JPN_FINAL ? true : false; u8 *g_LangBuffer = NULL; u8 *g_LangBufferPos = NULL; s32 g_LangBufferSize = 0; -u32 *g_LangBanks[69]; +uintptr_t *g_LangBanks[69]; struct jpncharpixels *g_JpnCharCachePixels; struct jpncacheitem *g_JpnCacheCacheItems; s32 g_LanguageId = LANGUAGE_NTSC_EN; #else -u32 *g_LangBanks[69]; +uintptr_t *g_LangBanks[69]; struct jpncharpixels *g_JpnCharCachePixels; struct jpncacheitem *g_JpnCacheCacheItems; bool g_Jpn = false; @@ -377,25 +377,28 @@ s32 langGetFileId(s32 bank) void langLoad(s32 bank) { #if VERSION >= VERSION_PAL_BETA - s32 len = fileGetInflatedSize(langGetFileId(bank)); + s32 len = fileGetInflatedSize(langGetFileId(bank), LOADTYPE_LANG); - if ((s32)g_LangBuffer + len + g_LangBufferSize - (s32)g_LangBufferPos >= 0) { - s32 len2 = (s32)g_LangBuffer + g_LangBufferSize - (s32)g_LangBufferPos; + if ((uintptr_t)g_LangBuffer + len + g_LangBufferSize - (uintptr_t)g_LangBufferPos >= 0) { + s32 len2 = (uintptr_t)g_LangBuffer + g_LangBufferSize - (uintptr_t)g_LangBufferPos; len2 = len2 / 32 * 32; + g_LoadType = LOADTYPE_LANG; g_LangBanks[bank] = fileLoadToAddr(langGetFileId(bank), FILELOADMETHOD_DEFAULT, (u8 *)g_LangBufferPos, len2); - g_LangBufferPos = (u8 *)(align32((s32)g_LangBufferPos + len)); + g_LangBufferPos = (u8 *)(align32((uintptr_t)g_LangBufferPos + len)); } else { CRASH(); } #else s32 file_id = langGetFileId(bank); - g_LangBanks[bank] = fileLoadToNew(file_id, FILELOADMETHOD_DEFAULT); + g_LoadType = LOADTYPE_LANG; + g_LangBanks[bank] = fileLoadToNew(file_id, FILELOADMETHOD_DEFAULT, LOADTYPE_LANG); #endif } void langLoadToAddr(s32 bank, u8 *dst, s32 size) { s32 file_id = langGetFileId(bank); + g_LoadType = LOADTYPE_LANG; g_LangBanks[bank] = fileLoadToAddr(file_id, FILELOADMETHOD_DEFAULT, dst, size); } @@ -418,11 +421,11 @@ char *langGet(s32 textid) { s32 bankindex = textid >> 9; s32 textindex = textid & 0x1ff; - u32 *bank = g_LangBanks[bankindex]; - u32 addr; + uintptr_t *bank = (uintptr_t*)g_LangBanks[bankindex]; + uintptr_t addr; if (bank && bank[textindex]) { - addr = (uintptr_t)bank + PD_BE32(bank[textindex]); + addr = (uintptr_t)bank + bank[textindex]; } else { addr = 0; } diff --git a/src/game/langreset.c b/src/game/langreset.c index 71bbd0cfc..beabbde03 100644 --- a/src/game/langreset.c +++ b/src/game/langreset.c @@ -6,6 +6,7 @@ #include "lib/memp.h" #include "data.h" #include "types.h" +#include "platform.h" extern u8 *g_LangBuffer; extern s32 g_LangBufferSize; @@ -45,21 +46,37 @@ void langReset(s32 stagenum) } } +#ifdef PLATFORM_64BIT + size *= 2; +#endif + g_LangBuffer = mempAlloc(ALIGN16(size), MEMPOOL_STAGE); g_LangBufferSize = size; langReload(); #else // Versions prior to PAL load the language directly - g_LangBanks[LANGBANK_GUN] = fileLoadToNew(langGetFileId(LANGBANK_GUN), FILELOADMETHOD_DEFAULT); - g_LangBanks[LANGBANK_MPMENU] = fileLoadToNew(langGetFileId(LANGBANK_MPMENU), FILELOADMETHOD_DEFAULT); - g_LangBanks[LANGBANK_PROPOBJ] = fileLoadToNew(langGetFileId(LANGBANK_PROPOBJ), FILELOADMETHOD_DEFAULT); - g_LangBanks[LANGBANK_MPWEAPONS] = fileLoadToNew(langGetFileId(LANGBANK_MPWEAPONS), FILELOADMETHOD_DEFAULT); - g_LangBanks[LANGBANK_OPTIONS] = fileLoadToNew(langGetFileId(LANGBANK_OPTIONS), FILELOADMETHOD_DEFAULT); - g_LangBanks[LANGBANK_MISC] = fileLoadToNew(langGetFileId(LANGBANK_MISC), FILELOADMETHOD_DEFAULT); + g_LoadType = LOADTYPE_LANG; // find be a better way to do this.. + g_LangBanks[LANGBANK_GUN] = fileLoadToNew(langGetFileId(LANGBANK_GUN), FILELOADMETHOD_DEFAULT, LOADTYPE_LANG); + + g_LoadType = LOADTYPE_LANG; + g_LangBanks[LANGBANK_MPMENU] = fileLoadToNew(langGetFileId(LANGBANK_MPMENU), FILELOADMETHOD_DEFAULT, LOADTYPE_LANG); + + g_LoadType = LOADTYPE_LANG; + g_LangBanks[LANGBANK_PROPOBJ] = fileLoadToNew(langGetFileId(LANGBANK_PROPOBJ), FILELOADMETHOD_DEFAULT, LOADTYPE_LANG); + + g_LoadType = LOADTYPE_LANG; + g_LangBanks[LANGBANK_MPWEAPONS] = fileLoadToNew(langGetFileId(LANGBANK_MPWEAPONS), FILELOADMETHOD_DEFAULT, LOADTYPE_LANG); + + g_LoadType = LOADTYPE_LANG; + g_LangBanks[LANGBANK_OPTIONS] = fileLoadToNew(langGetFileId(LANGBANK_OPTIONS), FILELOADMETHOD_DEFAULT, LOADTYPE_LANG); + + g_LoadType = LOADTYPE_LANG; + g_LangBanks[LANGBANK_MISC] = fileLoadToNew(langGetFileId(LANGBANK_MISC), FILELOADMETHOD_DEFAULT, LOADTYPE_LANG); if (stagenum == STAGE_CREDITS) { - g_LangBanks[LANGBANK_TITLE] = fileLoadToNew(langGetFileId(LANGBANK_TITLE), FILELOADMETHOD_DEFAULT); + g_LoadType = LOADTYPE_LANG; + g_LangBanks[LANGBANK_TITLE] = fileLoadToNew(langGetFileId(LANGBANK_TITLE), FILELOADMETHOD_DEFAULT, LOADTYPE_LANG); } #endif } diff --git a/src/game/mainmenu.c b/src/game/mainmenu.c index be898224d..5c7c3dcd5 100644 --- a/src/game/mainmenu.c +++ b/src/game/mainmenu.c @@ -107,15 +107,15 @@ MenuItemHandlerResult menuhandlerControlStyleImpl(s32 operation, struct menuitem break; case MENUOP_GETOPTIONTEXT: if (data->list.value > 7) { - return (intptr_t) "Ext"; + return (uintptr_t) "Ext"; } else { - return (intptr_t) langGet(g_ControlStyleOptions[data->list.value]); + return (uintptr_t) langGet(g_ControlStyleOptions[data->list.value]); } case MENUOP_GETOPTGROUPTEXT: if (data->list.value > 1) { - return (intptr_t) "Port"; + return (uintptr_t) "Port"; } else { - return (intptr_t) langGet(categories[data->list.value]); + return (uintptr_t) langGet(categories[data->list.value]); } case MENUOP_GETGROUPSTARTINDEX: data->list.groupstartindex = data->list.value * 4; @@ -201,9 +201,9 @@ MenuItemHandlerResult menuhandlerAimControl(s32 operation, struct menuitem *item break; case MENUOP_GETOPTIONTEXT: #if VERSION >= VERSION_PAL_FINAL - return (s32) langGet(options[index][data->dropdown.value]); + return (uintptr_t) langGet(options[index][data->dropdown.value]); #else - return (s32) langGet(options[data->dropdown.value]); + return (uintptr_t) langGet(options[data->dropdown.value]); #endif case MENUOP_SET: optionsSetAimControl(playernum, data->dropdown.value); @@ -230,7 +230,7 @@ MenuItemHandlerResult menuhandlerSoundMode(s32 operation, struct menuitem *item, data->dropdown.value = 4; break; case MENUOP_GETOPTIONTEXT: - return (s32) langGet(options[data->dropdown.value]); + return (uintptr_t) langGet(options[data->dropdown.value]); case MENUOP_SET: sndSetSoundMode(data->dropdown.value); g_Vars.modifiedfiles |= MODFILE_GAME; @@ -255,7 +255,7 @@ MenuItemHandlerResult menuhandlerScreenSize(s32 operation, struct menuitem *item data->dropdown.value = 3; break; case MENUOP_GETOPTIONTEXT: - return (s32) langGet(options[data->dropdown.value]); + return (uintptr_t) langGet(options[data->dropdown.value]); case MENUOP_SET: optionsSetScreenSize(data->dropdown.value); g_Vars.modifiedfiles |= MODFILE_GAME; @@ -279,7 +279,7 @@ MenuItemHandlerResult menuhandlerScreenRatio(s32 operation, struct menuitem *ite data->dropdown.value = 2; break; case MENUOP_GETOPTIONTEXT: - return (s32) langGet(options[data->dropdown.value]); + return (uintptr_t) langGet(options[data->dropdown.value]); case MENUOP_SET: optionsSetScreenRatio(data->dropdown.value); g_Vars.modifiedfiles |= MODFILE_GAME; @@ -307,7 +307,7 @@ MenuItemHandlerResult menuhandlerLanguage(s32 operation, struct menuitem *item, data->dropdown.value = 5; break; case MENUOP_GETOPTIONTEXT: - return (s32)langGet(labels[data->dropdown.value]); + return (uintptr_t)langGet(labels[data->dropdown.value]); case MENUOP_SET: g_Vars.language = data->dropdown.value; langSetEuropean(g_Vars.language); @@ -338,7 +338,7 @@ MenuItemHandlerResult menuhandlerScreenSplit(s32 operation, struct menuitem *ite data->dropdown.value = 2; break; case MENUOP_GETOPTIONTEXT: - return (s32) langGet(options[data->dropdown.value]); + return (uintptr_t) langGet(options[data->dropdown.value]); case MENUOP_SET: if (data->dropdown.value != (u32)optionsGetScreenSplit()) { optionsSetScreenSplit(data->dropdown.value); @@ -1458,7 +1458,7 @@ MenuItemHandlerResult menuhandlerCoopBuddy(s32 operation, struct menuitem *item, extra = 0; } - return (s32)langGet(labels[data->dropdown.value + extra]); + return (uintptr_t)langGet(labels[data->dropdown.value + extra]); } case MENUOP_SET: { @@ -1577,7 +1577,7 @@ MenuItemHandlerResult menuhandlerAntiPlayer(s32 operation, struct menuitem *item data->dropdown.value = 2; break; case MENUOP_GETOPTIONTEXT: - return (s32) langGet(labels[data->dropdown.value]); + return (uintptr_t) langGet(labels[data->dropdown.value]); case MENUOP_SET: g_Vars.pendingantiplayernum = data->dropdown.value; g_Vars.modifiedfiles |= MODFILE_GAME; @@ -2017,11 +2017,11 @@ MenuItemHandlerResult menuhandlerMissionList(s32 operation, struct menuitem *ite if (data->list.value < data->list.unk04u32) { // Regular stage such as "dataDyne Central - Defection" // Return the name before the dash, such as "dataDyne Central" - return (s32) langGet(g_SoloStages[data->list.value].name1); + return (uintptr_t) langGet(g_SoloStages[data->list.value].name1); } // Special stages have no dash and suffix, so just return the name - return (s32) langGet(g_SoloStages[func0f104720(data->list.value - data->list.unk04u32)].name1); + return (uintptr_t) langGet(g_SoloStages[func0f104720(data->list.value - data->list.unk04u32)].name1); case MENUOP_SET: sp188 = data->list.value; menuhandlerMissionList(MENUOP_GETOPTIONCOUNT, item, &sp178); @@ -2084,9 +2084,9 @@ MenuItemHandlerResult menuhandlerMissionList(s32 operation, struct menuitem *ite break; case MENUOP_GETOPTGROUPTEXT: if (data->list.unk0c == data->list.value) { - return (s32) langGet(groups[9].name); // "Special Assignments" + return (uintptr_t) langGet(groups[9].name); // "Special Assignments" } - return (s32) langGet(groups[data->list.value].name); + return (uintptr_t) langGet(groups[data->list.value].name); case MENUOP_GETGROUPSTARTINDEX: if (data->list.unk0c == data->list.value) { menuhandlerMissionList(MENUOP_GETOPTIONCOUNT, item, &sp13c); @@ -2230,7 +2230,7 @@ MenuItemHandlerResult menuhandlerMissionList(s32 operation, struct menuitem *ite gdl = text0f153780(gdl); - return (s32) gdl; + return (uintptr_t) gdl; case MENUOP_GETOPTIONHEIGHT: data->list.value = 42; break; @@ -4380,7 +4380,7 @@ MenuItemHandlerResult menuhandlerFrInventoryList(s32 operation, struct menuitem break; case MENUOP_GETOPTIONTEXT: g_FrFocusedSlotIndex = data->list.value; - return (s32)bgunGetName(frGetWeaponBySlot(data->list.value)); + return (uintptr_t)bgunGetName(frGetWeaponBySlot(data->list.value)); case MENUOP_SET: g_FrFocusedSlotIndex = data->list.value; return 0; @@ -4410,7 +4410,7 @@ MenuItemHandlerResult menuhandlerInventoryList(s32 operation, struct menuitem *i data->list.value = invGetCount(); break; case MENUOP_GETOPTIONTEXT: - return (s32)invGetNameByIndex(data->list.value); + return (uintptr_t)invGetNameByIndex(data->list.value); case MENUOP_SET: { s32 weaponnum = invGetWeaponNumByIndex(data->list.value); @@ -4848,9 +4848,9 @@ MenuItemHandlerResult menuhandlerCinema(s32 operation, struct menuitem *item, un case MENUOP_GETOPTIONTEXT: if (data->list.value == 0) { sprintf(g_StringPointer, langGet(L_OPTIONS_448)); // "Play All" - return (s32) g_StringPointer; + return (uintptr_t) g_StringPointer; } - return (s32) langGet(g_Cutscenes[data->list.value - 1].name); + return (uintptr_t) langGet(g_Cutscenes[data->list.value - 1].name); case MENUOP_SET: if (data->list.value == 0) { // Play all @@ -4874,7 +4874,7 @@ MenuItemHandlerResult menuhandlerCinema(s32 operation, struct menuitem *item, un data->list.value = ARRAYCOUNT(groups); break; case MENUOP_GETOPTGROUPTEXT: - return (s32) langGet(groups[data->list.value].name); + return (uintptr_t) langGet(groups[data->list.value].name); case MENUOP_GETGROUPSTARTINDEX: data->list.groupstartindex = groups[data->list.value].first_cutscene_index; break; diff --git a/src/game/menu.c b/src/game/menu.c index 01c18f75b..c1552bb59 100644 --- a/src/game/menu.c +++ b/src/game/menu.c @@ -49,6 +49,7 @@ #include "data.h" #include "types.h" #ifndef PLATFORM_N64 +#include "platform.h" #include "video.h" #include "input.h" #include "net/net.h" @@ -476,7 +477,7 @@ char *menuResolveText(uintptr_t thing, void *dialogoritem) // Text ID if (thing < 0x5a00) { - return langGet((u32)thing); + return langGet((uintptr_t)thing); } #ifdef PLATFORM_N64 // unreliable otherwise, the above check should be enough? @@ -1870,7 +1871,7 @@ Gfx *menuRenderModel(Gfx *gdl, struct menumodel *menumodel, s32 modeltype) bodyfilenum = g_HeadsAndBodies[bodynum].filenum; - totalfilelen = fileGetInflatedSize(bodyfilenum); + totalfilelen = fileGetInflatedSize(bodyfilenum, LOADTYPE_MODEL); totalfilelen = ALIGN64(totalfilelen); if (g_HeadsAndBodies[bodynum].unk00_01) { @@ -1878,10 +1879,14 @@ Gfx *menuRenderModel(Gfx *gdl, struct menumodel *menumodel, s32 modeltype) headfilenum = 0xffff; } else { headfilenum = g_HeadsAndBodies[headnum].filenum; - totalfilelen += ALIGN64(fileGetInflatedSize(headfilenum)); + totalfilelen += ALIGN64(fileGetInflatedSize(headfilenum, LOADTYPE_MODEL)); } +#ifdef PLATFORM_64BIT + totalfilelen += 0x6000; +#else totalfilelen += 0x4000; +#endif texInitPool(&texpool, menumodel->allocstart + totalfilelen, menumodel->alloclen - totalfilelen); @@ -1903,12 +1908,16 @@ Gfx *menuRenderModel(Gfx *gdl, struct menumodel *menumodel, s32 modeltype) modelInit(&menumodel->bodymodel, menumodel->bodymodeldef, menumodel->rwdata, true); animInit(&menumodel->bodyanim); +#ifdef PLATFORM_64BIT + menumodel->bodymodel.rwdatalen = 256 + 128; +#else menumodel->bodymodel.rwdatalen = 256; +#endif menumodel->bodymodel.anim = &menumodel->bodyanim; body0f02ce8c(bodynum, headnum, menumodel->bodymodeldef, menumodel->headmodeldef, totalfilelen * 0, &menumodel->bodymodel, false, 1); } else { - totalfilelen = ALIGN64(fileGetInflatedSize(menumodel->newparams)) + 0x4000; + totalfilelen = ALIGN64(fileGetInflatedSize(menumodel->newparams, LOADTYPE_MODEL)) + 0x4000; if (1); texInitPool(&texpool, &menumodel->allocstart[(u32)totalfilelen], menumodel->alloclen - totalfilelen); @@ -1922,7 +1931,11 @@ Gfx *menuRenderModel(Gfx *gdl, struct menumodel *menumodel, s32 modeltype) modelInit(&menumodel->bodymodel, menumodel->bodymodeldef, menumodel->rwdata, true); animInit(&menumodel->bodyanim); +#ifdef PLATFORM_64BIT + menumodel->bodymodel.rwdatalen = 256+128; +#else menumodel->bodymodel.rwdatalen = 256; +#endif menumodel->bodymodel.anim = &menumodel->bodyanim; } @@ -3903,11 +3916,19 @@ void menuReset(void) } for (i = 0; i < max; i++) { +#ifdef PLATFORM_64BIT + menuResetModel(&g_Menus[i].menumodel, IS4MB() ? 0xb400 : 0x38400, true); // 50% more +#else menuResetModel(&g_Menus[i].menumodel, IS4MB() ? 0xb400 : 0x25800, true); +#endif } if (IS8MB()) { +#ifdef PLATFORM_64BIT + menuResetModel(&g_MenuData.hudpiece, 0x12c00, true); // 50% more +#else menuResetModel(&g_MenuData.hudpiece, 0xc800, true); +#endif } g_MenuData.hudpiece.newparams = MENUMODELPARAMS_SET_FILENUM(FILE_GHUDPIECE); diff --git a/src/game/menuitem.c b/src/game/menuitem.c index 45ef26518..00a88515c 100644 --- a/src/game/menuitem.c +++ b/src/game/menuitem.c @@ -576,7 +576,7 @@ Gfx *menuitemListRender(Gfx *gdl, struct menurendercontext *context) spb8.type19.gdl = gdl; spb8.type19.unk04 = optionindex; - spb8.type19.renderdata2 = (void *)((uintptr_t)&renderdata & 0xffffffff); + spb8.type19.renderdata2 = (void *)((uintptr_t)&renderdata); spb8.type19.unk0c = sp15c.list.unk04; gdl = (Gfx *) context->item->handler(MENUOP_RENDER, context->item, &spb8); @@ -799,7 +799,7 @@ bool menuitemListTick(struct menuitem *item, struct menuinputs *inputs, u32 tick void menuitemDropdownInit(struct menuitem *item, union menuitemdata *data) { - s32 (*handler)(s32 operation, struct menuitem *item, union handlerdata *data); + uintptr_t (*handler)(s32 operation, struct menuitem *item, union handlerdata *data); union handlerdata handlerdata; union handlerdata handlerdata2; @@ -1884,7 +1884,7 @@ Gfx *menuitemModelRender(Gfx *gdl, struct menurendercontext *context) renderdata.unk10 = true; data.type19.gdl = gdl; - data.type19.unk04 = (s32)&renderdata; + data.type19.unk04 = (intptr_t)&renderdata; data.type19.renderdata2 = &renderdata; gdl = (Gfx *)context->item->handler(MENUOP_RENDER, context->item, &data); diff --git a/src/game/modeldef.c b/src/game/modeldef.c index 0d0913ff7..b3c3307a6 100644 --- a/src/game/modeldef.c +++ b/src/game/modeldef.c @@ -131,13 +131,13 @@ void modeldef0f1a7560(struct modeldef *modeldef, u16 filenum, u32 arg2, struct m s5 = gdl; if (gdl) { - s32 v1 = allocsize - (loadedsize - (s32)(((uintptr_t)modeldef + (UNSEGADDR(gdl) & 0xffffff)) - (uintptr_t)modeldef)); - sp84 = (s32)v1 + (s32)((uintptr_t)modeldef - ((uintptr_t)modeldef + (UNSEGADDR(gdl) & 0xffffff))); + s32 v1 = allocsize - (loadedsize - (uintptr_t)(((uintptr_t)modeldef + (UNSEGADDR(gdl) & 0xffffff)) - (uintptr_t)modeldef)); + sp84 = (uintptr_t)v1 + (uintptr_t)((uintptr_t)modeldef - ((uintptr_t)modeldef + (UNSEGADDR(gdl) & 0xffffff))); texCopyGdls((Gfx *)((uintptr_t)modeldef + (UNSEGADDR(gdl) & 0xffffff)), (Gfx *)(v1 + (uintptr_t)modeldef), - loadedsize - (s32)(((uintptr_t)modeldef + (UNSEGADDR(gdl) & 0xffffff)) - (uintptr_t)modeldef)); - texLoadFromConfigs(modeldef->texconfigs, modeldef->numtexconfigs, texpool, (uintptr_t)modeldef2 - arg2); + loadedsize - (uintptr_t)(((uintptr_t)modeldef + (UNSEGADDR(gdl) & 0xffffff)) - (uintptr_t)modeldef)); + texLoadFromConfigs(modeldef->texconfigs, modeldef->numtexconfigs, texpool, (uintptr_t)modeldef2 - (uintptr_t)arg2); while (node) { prevnode = node; @@ -190,7 +190,7 @@ struct modeldef *modeldefLoad(u16 fileid, u8 *dst, s32 size, struct texpool *arg if (dst) { modeldef = fileLoadToAddr(fileid, FILELOADMETHOD_EXTRAMEM, dst, size); } else { - modeldef = fileLoadToNew(fileid, FILELOADMETHOD_EXTRAMEM); + modeldef = fileLoadToNew(fileid, FILELOADMETHOD_EXTRAMEM, LOADTYPE_MODEL); } modelPromoteTypeToPointer(modeldef); diff --git a/src/game/modelmgr.c b/src/game/modelmgr.c index 5251e8d58..70fefead6 100644 --- a/src/game/modelmgr.c +++ b/src/game/modelmgr.c @@ -7,6 +7,8 @@ #include "data.h" #include "types.h" +#include "system.h" + struct model *g_ModelSlots; struct anim *g_AnimSlots; s32 g_ModelNumObjs; @@ -107,6 +109,10 @@ struct model *modelmgrInstantiateModel(struct modeldef *modeldef, bool withanim) struct model *model = NULL; u32 *rwdatas = NULL; s16 datalen = -1; + s16 extra = 0; +#ifdef PLATFORM_64BIT + extra = 128; +#endif s32 i; if (!g_ModelIsLvResetting) { @@ -146,7 +152,7 @@ struct model *modelmgrInstantiateModel(struct modeldef *modeldef, bool withanim) } else { // At this point, it's during gameplay. A model instance slot has // been found or allocated, but rwdata needs to be allocated. - if (modeldef->rwdatalen < 256) { + if (modeldef->rwdatalen < 256+extra) { bool done = false; u32 stack; @@ -179,7 +185,7 @@ struct model *modelmgrInstantiateModel(struct modeldef *modeldef, bool withanim) // 256 words (0x400 bytes) or less -> try type 3 // First looking for unused slots with an existing rwdata allocation - if (!done && modeldef->rwdatalen <= 256) { + if (!done && modeldef->rwdatalen <= 256+extra) { for (i = 0; i < NUMTYPE3(); i++) { if (g_ModelRwdataBindings[2][i].model == NULL && g_ModelRwdataBindings[2][i].rwdata != NULL) { osSyncPrintf("MotInst: Using cache entry type 3 %d (0x%08x) - Bytes=%d\n"); @@ -193,10 +199,10 @@ struct model *modelmgrInstantiateModel(struct modeldef *modeldef, bool withanim) } // Type 3 again, but looking for null rwdata allocations - if (!done && modeldef->rwdatalen <= 256) { + if (!done && modeldef->rwdatalen <= 256+extra) { for (i = 0; i < NUMTYPE3(); i++) { if (g_ModelRwdataBindings[2][i].model == NULL && g_ModelRwdataBindings[2][i].rwdata == NULL) { - g_ModelRwdataBindings[2][i].rwdata = mempAlloc(256 * 4, MEMPOOL_STAGE); + g_ModelRwdataBindings[2][i].rwdata = mempAlloc((256+128) * 4, MEMPOOL_STAGE); rwdatas = g_ModelRwdataBindings[2][i].rwdata; g_ModelRwdataBindings[2][i].model = model; break; @@ -204,7 +210,7 @@ struct model *modelmgrInstantiateModel(struct modeldef *modeldef, bool withanim) } } } else { - // empty + sysLogPrintf(LOG_WARNING, "Unable to allocate rwdata"); } if (withanim) { @@ -213,6 +219,8 @@ struct model *modelmgrInstantiateModel(struct modeldef *modeldef, bool withanim) datalen = IS4MB() ? 52 : 256; } + datalen += extra; + if (datalen < modeldef->rwdatalen) { datalen = modeldef->rwdatalen; } diff --git a/src/game/modelmgrreset.c b/src/game/modelmgrreset.c index 1d6600514..2f268e06e 100644 --- a/src/game/modelmgrreset.c +++ b/src/game/modelmgrreset.c @@ -101,17 +101,17 @@ void modelmgrAllocateSlots(s32 numobjs, s32 numchrs) if (NUMTYPE1()) { g_ModelRwdataBindings[0] = (struct modelrwdatabinding *) ptr; - ptr += NUMTYPE1() * 8; + ptr += NUMTYPE1() * sizeof(struct modelrwdatabinding); } if (NUMTYPE2()) { g_ModelRwdataBindings[1] = (struct modelrwdatabinding *) ptr; - ptr += NUMTYPE2() * 8; + ptr += NUMTYPE2() * sizeof(struct modelrwdatabinding); } if (NUMTYPE3()) { g_ModelRwdataBindings[2] = (struct modelrwdatabinding *) ptr; - ptr += NUMTYPE3() * 8; + ptr += NUMTYPE3() * sizeof(struct modelrwdatabinding); } g_ModelSlots = (struct model *) ptr; diff --git a/src/game/mplayer/ingame.c b/src/game/mplayer/ingame.c index 4286739f0..7da28b8ed 100644 --- a/src/game/mplayer/ingame.c +++ b/src/game/mplayer/ingame.c @@ -56,14 +56,14 @@ MenuItemHandlerResult mpStatsForPlayerDropdownHandler(s32 operation, struct menu mpchr = MPCHR(a1); if (v0 == data->list.value) { - return (s32) mpchr->name; + return (uintptr_t) mpchr->name; } v0++; } } - return (s32) ""; + return (uintptr_t) ""; case MENUOP_SET: v0 = 0; @@ -711,7 +711,7 @@ MenuItemHandlerResult mpAwardsMenuHandler(s32 operation, struct menuitem *item, } } - return (s32) gdl; + return (uintptr_t) gdl; } return 0; diff --git a/src/game/mplayer/scenarios.c b/src/game/mplayer/scenarios.c index 07b604ed8..511fd9ada 100644 --- a/src/game/mplayer/scenarios.c +++ b/src/game/mplayer/scenarios.c @@ -141,7 +141,7 @@ MenuItemHandlerResult menuhandlerMpSlowMotion(s32 operation, struct menuitem *it data->dropdown.value = 3; break; case MENUOP_GETOPTIONTEXT: - return (s32)langGet(labels[data->dropdown.value]); + return (uintptr_t)langGet(labels[data->dropdown.value]); case MENUOP_SET: g_MpSetup.options &= ~(MPOPTION_SLOWMOTION_ON | MPOPTION_SLOWMOTION_SMART); @@ -338,7 +338,7 @@ MenuItemHandlerResult scenarioScenarioMenuHandler(s32 operation, struct menuitem if (challengeIsFeatureUnlocked(g_MpScenarioOverviews[i].requirefeature) && (teamgame || g_MpScenarioOverviews[i].teamonly == false)) { if (count == data->list.value) { - return (s32)langGet(g_MpScenarioOverviews[i].name); + return (uintptr_t)langGet(g_MpScenarioOverviews[i].name); } count++; @@ -383,7 +383,7 @@ MenuItemHandlerResult scenarioScenarioMenuHandler(s32 operation, struct menuitem } break; case MENUOP_GETOPTGROUPTEXT: - return (s32)langGet(groups[data->list.value].textid); + return (uintptr_t)langGet(groups[data->list.value].textid); case MENUOP_GETGROUPSTARTINDEX: for (i = 0; i < groups[data->list.value].startindex; i++) { if (challengeIsFeatureUnlocked(g_MpScenarioOverviews[i].requirefeature) diff --git a/src/game/mplayer/setup.c b/src/game/mplayer/setup.c index 815a43aca..3a333a49f 100644 --- a/src/game/mplayer/setup.c +++ b/src/game/mplayer/setup.c @@ -180,7 +180,7 @@ MenuItemHandlerResult mpArenaMenuHandler(s32 operation, struct menuitem *item, u for (i = 0; i < ARRAYCOUNT(g_MpArenas); i++) { if (challengeIsFeatureUnlocked(g_MpArenas[i].requirefeature)) { if (count == data->list.value) { - return (s32)langGet(g_MpArenas[i].name); + return (uintptr_t)langGet(g_MpArenas[i].name); } count++; @@ -229,7 +229,7 @@ MenuItemHandlerResult mpArenaMenuHandler(s32 operation, struct menuitem *item, u && count > 0) { count++; } - return (s32)langGet(groups[count].name); + return (uintptr_t)langGet(groups[count].name); case MENUOP_GETGROUPSTARTINDEX: groupindex = data->list.value; @@ -291,7 +291,7 @@ MenuItemHandlerResult menuhandlerMpWeaponSlot(s32 operation, struct menuitem *it data->dropdown.value = mpGetNumWeaponOptions(); break; case MENUOP_GETOPTIONTEXT: - return (s32) mpGetWeaponLabel(data->dropdown.value); + return (uintptr_t) mpGetWeaponLabel(data->dropdown.value); case MENUOP_SET: mpSetWeaponSlot(item->param3, data->dropdown.value); break; @@ -314,7 +314,7 @@ MenuItemHandlerResult menuhandlerMpWeaponSetDropdown(s32 operation, struct menui data->dropdown.value = func0f189058(item->param); break; case MENUOP_GETOPTIONTEXT: - return (s32) mpGetWeaponSetName(data->dropdown.value); + return (uintptr_t) mpGetWeaponSetName(data->dropdown.value); case MENUOP_SET: mpSetWeaponSet(data->dropdown.value); break; @@ -380,7 +380,7 @@ MenuItemHandlerResult menuhandlerMpAimControl(s32 operation, struct menuitem *it data->dropdown.value = 2; break; case MENUOP_GETOPTIONTEXT: - return (s32) langGet(labels[data->dropdown.value]); + return (uintptr_t) langGet(labels[data->dropdown.value]); case MENUOP_SET: optionsSetAimControl(g_MpPlayerNum, data->dropdown.value); break; @@ -770,7 +770,7 @@ MenuItemHandlerResult mpChallengesListHandler(s32 operation, struct menuitem *it loopx += 13; } - return (s32) gdl; + return (uintptr_t) gdl; case MENUOP_GETOPTIONHEIGHT: data->list.value = 26; break; @@ -1004,7 +1004,7 @@ MenuItemHandlerResult mpMedalMenuHandler(s32 operation, struct menuitem *item, u ((renderdata->x + 20) << 2) * g_ScaleX, (renderdata->y + 11) << 2, G_TX_RENDERTILE, 0, 0x0160, 1024 / g_ScaleX, -1024); - return (s32) gdl; + return (uintptr_t) gdl; } return 0; @@ -2085,11 +2085,11 @@ MenuItemHandlerResult mpLoadSettingsMenuHandler(s32 operation, struct menuitem * break; case MENUOP_GETOPTIONTEXT: if (data->list.value < mpGetNumUnlockedPresets()) { - return (s32)mpGetPresetNameBySlot(data->list.value); + return (uintptr_t)mpGetPresetNameBySlot(data->list.value); } if (g_FileLists[1] != NULL) { func0f0d564c(g_FileLists[1]->files[data->list.value - mpGetNumUnlockedPresets()].name, g_StringPointer, false); - return (s32)g_StringPointer; + return (uintptr_t)g_StringPointer; } break; case MENUOP_SET: @@ -2127,10 +2127,10 @@ MenuItemHandlerResult mpLoadSettingsMenuHandler(s32 operation, struct menuitem * break; case MENUOP_GETOPTGROUPTEXT: if (data->list.value == 0) { - return (s32)langGet(L_MPMENU_141); // "Presets" + return (uintptr_t)langGet(L_MPMENU_141); // "Presets" } if (g_FileLists[1] != NULL) { - return (s32)filemgrGetDeviceNameOrStartIndex(1, operation, data->list.value - 1); + return (uintptr_t)filemgrGetDeviceNameOrStartIndex(1, operation, data->list.value - 1); } break; case MENUOP_GETGROUPSTARTINDEX: @@ -2224,7 +2224,7 @@ MenuItemHandlerResult mpLoadPlayerMenuHandler(s32 operation, struct menuitem *it break; case MENUOP_GETOPTIONTEXT: filemgrGetSelectName(g_StringPointer, &g_FileLists[0]->files[data->list.value], FILETYPE_MPPLAYER); - return (s32)g_StringPointer; + return (uintptr_t)g_StringPointer; case MENUOP_SET: file = &g_FileLists[0]->files[data->list.value]; available = true; @@ -2788,7 +2788,7 @@ MenuItemHandlerResult mpAddChangeSimulantMenuHandler(s32 operation, struct menui for (i = 0; i < ARRAYCOUNT(g_BotProfiles); i++) { if (challengeIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) { if (count == data->list.value) { - return (s32)langGet(g_BotProfiles[i].name); + return (uintptr_t)langGet(g_BotProfiles[i].name); } count++; @@ -2849,7 +2849,7 @@ MenuItemHandlerResult mpAddChangeSimulantMenuHandler(s32 operation, struct menui data->list.value = 2; break; case MENUOP_GETOPTGROUPTEXT: - return (s32)langGet(groups[data->list.value].name); + return (uintptr_t)langGet(groups[data->list.value].name); case MENUOP_GETGROUPSTARTINDEX: for (i = 0; i < groups[data->list.value].offset; i++) { if (challengeIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) { @@ -2956,14 +2956,14 @@ MenuItemHandlerResult mpBotDifficultyMenuHandler(s32 operation, struct menuitem if (challengeIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) { if (count == data->dropdown.value) { // "Meat", "Easy", "Normal" etc - return (s32) langGet(L_MISC_082 + i); + return (uintptr_t) langGet(L_MISC_082 + i); } count++; } } - return (s32)"\n"; + return (uintptr_t)"\n"; } return 0; @@ -3564,10 +3564,10 @@ MenuItemHandlerResult func0f17dac4(s32 operation, struct menuitem *item, union h break; case MENUOP_GETOPTIONTEXT: if ((g_MpSetup.options & MPOPTION_TEAMSENABLED) == 0) { - return (s32) "\n"; + return (uintptr_t) "\n"; } - return (s32) g_BossFile.teamnames[data->list.value]; + return (uintptr_t) g_BossFile.teamnames[data->list.value]; } return menuhandlerMpTeamsLabel(operation, item, data); @@ -3996,14 +3996,14 @@ MenuItemHandlerResult mpSelectTuneListHandler(s32 operation, struct menuitem *it s32 numtracks = mpGetNumUnlockedTracks(); if (data->list.value < numtracks) { - return (s32) mpGetTrackName(data->list.value); + return (uintptr_t) mpGetTrackName(data->list.value); } if (mpGetUsingMultipleTunes()) { - return (s32) langGet(var80085ce8[1 + data->list.value - numtracks]); + return (uintptr_t) langGet(var80085ce8[1 + data->list.value - numtracks]); } - return (s32) langGet(var80085ce8[data->list.value - numtracks]); + return (uintptr_t) langGet(var80085ce8[data->list.value - numtracks]); } case MENUOP_SET: { @@ -4711,7 +4711,7 @@ MenuItemHandlerResult mpChallengesListMenuHandler(s32 operation, struct menuitem marginleft += 13; } - return (s32)gdl; + return (uintptr_t)gdl; case MENUOP_GETOPTIONHEIGHT: data->list.value = 26; break; @@ -4846,15 +4846,15 @@ MenuItemHandlerResult menuhandlerMpLock(s32 operation, struct menuitem *item, un break; case MENUOP_GETOPTIONTEXT: if (mpGetLockType() == MPLOCKTYPE_CHALLENGE) { - return (s32) langGet(L_MPMENU_049); // "Challenge" + return (uintptr_t) langGet(L_MPMENU_049); // "Challenge" } if (data->dropdown.value <= 3) { - return (s32) langGet(labels[data->dropdown.value]); + return (uintptr_t) langGet(labels[data->dropdown.value]); } if (mpGetLockType() == MPLOCKTYPE_PLAYER) { - return (s32) g_PlayerConfigsArray[mpGetLockPlayerNum()].base.name; + return (uintptr_t) g_PlayerConfigsArray[mpGetLockPlayerNum()].base.name; } - return (s32) mpGetCurrentPlayerName(item); + return (uintptr_t) mpGetCurrentPlayerName(item); case MENUOP_SET: if (mpGetLockType() != MPLOCKTYPE_CHALLENGE) { mpSetLock(data->dropdown.value, g_MpPlayerNum); @@ -5114,7 +5114,7 @@ MenuItemHandlerResult menuhandlerPlayerTeam(s32 operation, struct menuitem *item #endif break; case MENUOP_GETOPTIONTEXT: - return (s32) &g_BossFile.teamnames[data->dropdown.value]; + return (uintptr_t) &g_BossFile.teamnames[data->dropdown.value]; case MENUOP_SET: g_Vars.mpplayerteams[item->param] = data->dropdown.value; break; @@ -5144,7 +5144,7 @@ MenuItemHandlerResult menuhandlerMpNumberOfSimulants(s32 operation, struct menui break; case MENUOP_GETOPTIONTEXT: sprintf(g_StringPointer, "%d\n", data->dropdown.value + 1); - return (s32) g_StringPointer; + return (uintptr_t) g_StringPointer; case MENUOP_SET: g_Vars.mpquickteamnumsims = data->dropdown.value + 1; break; @@ -5170,7 +5170,7 @@ MenuItemHandlerResult menuhandlerMpSimulantsPerTeam(s32 operation, struct menuit break; case MENUOP_GETOPTIONTEXT: sprintf(g_StringPointer, "%d\n", data->dropdown.value + 1); - return (s32) g_StringPointer; + return (uintptr_t) g_StringPointer; case MENUOP_SET: g_Vars.unk0004a0 = data->dropdown.value + 1; break; @@ -5206,7 +5206,7 @@ MenuItemHandlerResult mpQuickTeamSimulantDifficultyHandler(s32 operation, struct for (i = 0; i < NUM_BOTDIFFS; i++) { if (challengeIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) { if (count == data->dropdown.value) { - return (s32) langGet(i + L_MISC_082); + return (uintptr_t) langGet(i + L_MISC_082); } count++; diff --git a/src/game/nbomb.c b/src/game/nbomb.c index add22b7d9..5d34f969b 100644 --- a/src/game/nbomb.c +++ b/src/game/nbomb.c @@ -24,6 +24,7 @@ #include "lib/lib_317f0.h" #include "data.h" #include "types.h" +#include "platform.h" s16 var8009cb00; s32 var8009cb04; @@ -314,7 +315,11 @@ s32 nbombCalculateAlpha(struct nbomb *nbomb) Gfx *nbombCreateGdl(void) { Vtx *vertices; +#ifdef PLATFORM_64BIT + u32 gdlsizes[] = { 0x0a30*2, 0x0330*2 }; // 1 player, 2+ players +#else u32 gdlsizes[] = { 0x0a30, 0x0330 }; // 1 player, 2+ players +#endif Gfx *gdlstart; Gfx *gdl; s32 index = 0; diff --git a/src/game/objectives.c b/src/game/objectives.c index 01f38e962..9d079af7e 100644 --- a/src/game/objectives.c +++ b/src/game/objectives.c @@ -91,7 +91,7 @@ void tagsReset(void) g_NumTags = index; if (g_NumTags) { - u32 size = index * 4; + u32 size = index * sizeof(uintptr_t); g_TagPtrs = mempAlloc(ALIGN16(size), MEMPOOL_STAGE); for (index = 0; index < g_NumTags; index++) { diff --git a/src/game/player.c b/src/game/player.c index e4b83a20d..e5d7de700 100644 --- a/src/game/player.c +++ b/src/game/player.c @@ -71,6 +71,7 @@ #include "data.h" #include "types.h" #ifndef PLATFORM_N64 +#include "platform.h" #include "video.h" #include "input.h" #include "net/net.h" @@ -1434,6 +1435,9 @@ void playerTickChrBody(void) rwdatas = (u32 *)(allocation + offset1); osSyncPrintf("Gunmem: savedata 0x%08x\n", (uintptr_t)rwdatas); offset1 += 0x400; +#ifdef PLATFORM_64BIT + offset1 += 0x200; +#endif offset1 = ALIGN64(offset1); weaponobj = (struct weaponobj *)(allocation + offset1); @@ -1441,17 +1445,20 @@ void playerTickChrBody(void) offset1 += sizeof(struct weaponobj); offset1 = ALIGN64(offset1); - offset2 = offset1 + ALIGN64(fileGetInflatedSize(g_HeadsAndBodies[bodynum].filenum)); + offset2 = offset1 + ALIGN64(fileGetInflatedSize(g_HeadsAndBodies[bodynum].filenum, LOADTYPE_MODEL)); if (headnum >= 0) { - offset2 += ALIGN64(fileGetInflatedSize(g_HeadsAndBodies[headnum].filenum)); + offset2 += ALIGN64(fileGetInflatedSize(g_HeadsAndBodies[headnum].filenum, LOADTYPE_MODEL)); } if (weaponmodelnum >= 0) { - offset2 += ALIGN64(fileGetInflatedSize(g_ModelStates[weaponmodelnum].fileid)); + offset2 += ALIGN64(fileGetInflatedSize(g_ModelStates[weaponmodelnum].fileid, LOADTYPE_MODEL)); } offset2 += 0x4000; +#ifdef PLATFORM_64BIT + offset2 += 0x2000; +#endif bgunCalculateGunMemCapacity(); spe8 = g_Vars.currentplayer->gunmem2 + offset2; texInitPool(&texpool, spe8, bgunCalculateGunMemCapacity() - offset2); @@ -1474,6 +1481,10 @@ void playerTickChrBody(void) model->rwdatalen = 256; +#ifdef PLATFORM_64BIT + model->rwdatalen += 128; +#endif + texGetPoolLeftPos(&texpool); // @TODO: Figure out these arguments diff --git a/src/game/playerreset.c b/src/game/playerreset.c index 6e3e79aa2..64cb8a07f 100644 --- a/src/game/playerreset.c +++ b/src/game/playerreset.c @@ -243,7 +243,7 @@ void playerReset(void) cmd = (struct cmd32 *)((uintptr_t)cmd + 12); break; case INTROCMD_CREDITOFFSET: - thing = (struct gecreditsdata *)((s32)g_GeCreditsData + cmd->param1); + thing = (struct gecreditsdata *)((uintptr_t)g_GeCreditsData + cmd->param1); g_CurrentGeCreditsData = thing; while (thing->text1 || thing->text2) { thing++; @@ -438,6 +438,7 @@ void playerReset(void) g_Vars.currentplayer->bond2.unk00.y = 0; g_Vars.currentplayer->bond2.unk00.z = cosf(turnanglerad); + g_Vars.currentplayer->prop->pos.f[0] = g_Vars.currentplayer->bondprevpos.f[0] = pos.f[0]; g_Vars.currentplayer->prop->pos.f[1] = g_Vars.currentplayer->bondprevpos.f[1] = pos.f[1]; g_Vars.currentplayer->prop->pos.f[2] = g_Vars.currentplayer->bondprevpos.f[2] = pos.f[2]; diff --git a/src/game/propobj.c b/src/game/propobj.c index dbc2540c4..73d97eeec 100644 --- a/src/game/propobj.c +++ b/src/game/propobj.c @@ -15087,13 +15087,13 @@ bool func0f0849dc(struct model *model, struct modelnode *nodearg, struct coord * if (rwdata->gdl != NULL) { if (rwdata->gdl == rodata->opagdl) { - s3 = (Gfx *)((uintptr_t)rodata->colours + ((u32)UNSEGADDR(rodata->opagdl) & 0xffffff)); + s3 = (Gfx *)((uintptr_t)rodata->colours + ((uintptr_t)UNSEGADDR(rodata->opagdl) & 0xffffff)); } else { s3 = rwdata->gdl; } if (rodata->xlugdl != NULL) { - s5 = (void *)((uintptr_t)rodata->colours + ((u32)UNSEGADDR(rodata->xlugdl) & 0xffffff)); + s5 = (void *)((uintptr_t)rodata->colours + ((uintptr_t)UNSEGADDR(rodata->xlugdl) & 0xffffff)); } vertices = rwdata->vertices; @@ -15105,10 +15105,10 @@ bool func0f0849dc(struct model *model, struct modelnode *nodearg, struct coord * struct modelrodata_gundl *rodata = &node->rodata->gundl; if (rodata->opagdl != NULL) { - s3 = (Gfx *)((uintptr_t)rodata->baseaddr + ((u32)UNSEGADDR(rodata->opagdl) & 0xffffff)); + s3 = (Gfx *)((uintptr_t)rodata->baseaddr + ((uintptr_t)UNSEGADDR(rodata->opagdl) & 0xffffff)); if (rodata->xlugdl != NULL) { - s5 = (Gfx *)((uintptr_t)rodata->baseaddr + ((u32)UNSEGADDR(rodata->xlugdl) & 0xffffff)); + s5 = (Gfx *)((uintptr_t)rodata->baseaddr + ((uintptr_t)UNSEGADDR(rodata->xlugdl) & 0xffffff)); } vertices = (void *)(uintptr_t)rodata->baseaddr; diff --git a/src/game/propsndstop.c b/src/game/propsndstop.c index 93f2df6a1..4891021cb 100644 --- a/src/game/propsndstop.c +++ b/src/game/propsndstop.c @@ -8,6 +8,7 @@ void psStop(void) { + if (g_SndDisabled) return; s32 i; for (i = 0; i < (IS4MB() ? 30 : 40); i++) { diff --git a/src/game/setup.c b/src/game/setup.c index d1a773202..4cfa61cd7 100644 --- a/src/game/setup.c +++ b/src/game/setup.c @@ -1237,7 +1237,7 @@ void setupLoadBriefing(s32 stagenum, u8 *buffer, s32 bufferlen, struct briefing langLoadToAddr(briefing->langbank, langbuffer, langbufferlen); - start = (struct defaultobj *)((uintptr_t)setup + (u32)setup->props); + start = (struct defaultobj *)((uintptr_t)setup + (uintptr_t)setup->props); if (start != NULL) { struct defaultobj *obj; @@ -1319,18 +1319,18 @@ void setupLoadFiles(s32 stagenum) g_LoadType = LOADTYPE_SETUP; - g_GeCreditsData = (u8 *)fileLoadToNew(filenum, FILELOADMETHOD_DEFAULT); + g_GeCreditsData = (u8 *)fileLoadToNew(filenum, FILELOADMETHOD_DEFAULT, LOADTYPE_SETUP); setup = (struct stagesetup *)g_GeCreditsData; langLoad(langGetLangBankIndexFromStagenum(stagenum)); - g_StageSetup.intro = (s32 *)((uintptr_t)setup + (u32)setup->intro); - g_StageSetup.props = (u32 *)((uintptr_t)setup + (u32)setup->props); - g_StageSetup.paths = (struct path *)((uintptr_t)setup + (u32)setup->paths); - g_StageSetup.ailists = (struct ailist *)((uintptr_t)setup + (u32)setup->ailists); + g_StageSetup.intro = (s32 *)((uintptr_t)setup + (uintptr_t)setup->intro); + g_StageSetup.props = (u32 *)((uintptr_t)setup + (uintptr_t)setup->props); + g_StageSetup.paths = (struct path *)((uintptr_t)setup + (uintptr_t)setup->paths); + g_StageSetup.ailists = (struct ailist *)((uintptr_t)setup + (uintptr_t)setup->ailists); g_LoadType = LOADTYPE_PADS; - g_StageSetup.padfiledata = fileLoadToNew(g_Stages[g_StageIndex].padsfileid, FILELOADMETHOD_DEFAULT); + g_StageSetup.padfiledata = fileLoadToNew(g_Stages[g_StageIndex].padsfileid, FILELOADMETHOD_DEFAULT, LOADTYPE_PADS); g_StageSetup.waypoints = NULL; g_StageSetup.waygroups = NULL; @@ -1339,7 +1339,7 @@ void setupLoadFiles(s32 stagenum) // Convert ailist pointers from file-local to proper pointers if (g_StageSetup.ailists) { for (i = 0; g_StageSetup.ailists[i].list != NULL; i++) { - g_StageSetup.ailists[i].list = (u8 *)((uintptr_t)setup + (u32)g_StageSetup.ailists[i].list); + g_StageSetup.ailists[i].list = (u8 *)((uintptr_t)setup + (uintptr_t)g_StageSetup.ailists[i].list); } } @@ -1383,7 +1383,7 @@ void setupLoadFiles(s32 stagenum) // and calculate the path lengths if (g_StageSetup.paths) { for (i = 0; g_StageSetup.paths[i].pads != NULL; i++) { - g_StageSetup.paths[i].pads = (s32 *)((uintptr_t)g_StageSetup.paths[i].pads + (u32)setup); + g_StageSetup.paths[i].pads = (s32 *)((uintptr_t)g_StageSetup.paths[i].pads + (uintptr_t)setup); for (j = 0; g_StageSetup.paths[i].pads[j] >= 0; j++); @@ -1844,7 +1844,7 @@ void setupCreateProps(s32 stagenum) truck->speedtime60 = -1; truck->turnrot60 = 0; truck->roty = 0; - truck->ailist = ailistFindById((u32)truck->ailist); + truck->ailist = ailistFindById((uintptr_t)truck->ailist); truck->aioffset = 0; truck->aireturnlist = -1; truck->path = NULL; @@ -1866,7 +1866,7 @@ void setupCreateProps(s32 stagenum) car->roty = 0; car->rotx = 0; car->speedtime60 = -1; - car->ailist = ailistFindById((s32)car->ailist); + car->ailist = ailistFindById((uintptr_t)car->ailist); car->aioffset = 0; car->aireturnlist = -1; car->path = NULL; @@ -1895,7 +1895,7 @@ void setupCreateProps(s32 stagenum) chopper->gunrotx = 0; chopper->barrelrot = 0; chopper->barrelrotspeed = 0; - chopper->ailist = ailistFindById((u32)chopper->ailist); + chopper->ailist = ailistFindById((uintptr_t)chopper->ailist); chopper->aioffset = 0; chopper->aireturnlist = -1; chopper->path = NULL; @@ -1942,7 +1942,7 @@ void setupCreateProps(s32 stagenum) heli->yrot = 0; heli->speedtime60 = -1; heli->rotoryspeedtime = -1; - heli->ailist = ailistFindById((u32)heli->ailist); + heli->ailist = ailistFindById((uintptr_t)heli->ailist); heli->aioffset = 0; heli->aireturnlist = -1; heli->path = NULL; @@ -2131,8 +2131,8 @@ void setupCreateProps(s32 stagenum) case OBJTYPE_LINKLIFTDOOR: { struct linkliftdoorobj *link = (struct linkliftdoorobj *)obj; - s32 dooroffset = (s32)link->door; - s32 liftoffset = (s32)link->lift; + uintptr_t dooroffset = (uintptr_t)link->door; + uintptr_t liftoffset = (uintptr_t)link->lift; struct defaultobj *door = setupGetObjByCmdIndex(index + dooroffset); struct defaultobj *lift = setupGetObjByCmdIndex(index + liftoffset); @@ -2149,9 +2149,9 @@ void setupCreateProps(s32 stagenum) case OBJTYPE_SAFEITEM: { struct safeitemobj *link = (struct safeitemobj *)obj; - s32 itemoffset = (s32)link->item; - s32 safeoffset = (s32)link->safe; - s32 dooroffset = (s32)link->door; + uintptr_t itemoffset = (uintptr_t)link->item; + uintptr_t safeoffset = (uintptr_t)link->safe; + uintptr_t dooroffset = (uintptr_t)link->door; struct defaultobj *item = setupGetObjByCmdIndex(index + itemoffset); struct defaultobj *safe = setupGetObjByCmdIndex(index + safeoffset); struct defaultobj *door = setupGetObjByCmdIndex(index + dooroffset); @@ -2173,8 +2173,8 @@ void setupCreateProps(s32 stagenum) case OBJTYPE_PADLOCKEDDOOR: { struct padlockeddoorobj *link = (struct padlockeddoorobj *)obj; - s32 dooroffset = (s32)link->door; - s32 lockoffset = (s32)link->lock; + uintptr_t dooroffset = (uintptr_t)link->door; + uintptr_t lockoffset = (uintptr_t)link->lock; struct defaultobj *door = setupGetObjByCmdIndex(index + dooroffset); struct defaultobj *lock = setupGetObjByCmdIndex(index + lockoffset); @@ -2192,9 +2192,9 @@ void setupCreateProps(s32 stagenum) case OBJTYPE_CONDITIONALSCENERY: { struct linksceneryobj *link = (struct linksceneryobj *)obj; - s32 triggeroffset = (s32)link->trigger; - s32 unexpoffset = (s32)link->unexp; - s32 expoffset = (s32)link->exp; + uintptr_t triggeroffset = (uintptr_t)link->trigger; + uintptr_t unexpoffset = (uintptr_t)link->unexp; + uintptr_t expoffset = (uintptr_t)link->exp; struct defaultobj *trigger = setupGetObjByCmdIndex(index + triggeroffset); struct defaultobj *unexp = NULL; struct defaultobj *exp = NULL; @@ -2244,7 +2244,7 @@ void setupCreateProps(s32 stagenum) case OBJTYPE_BLOCKEDPATH: { struct blockedpathobj *blockedpath = (struct blockedpathobj *)obj; - s32 objoffset = (s32)blockedpath->blocker; + uintptr_t objoffset = (uintptr_t)blockedpath->blocker; struct defaultobj *blocker = setupGetObjByCmdIndex(index + objoffset); if (blocker && blocker->prop) { diff --git a/src/game/setuppads.c b/src/game/setuppads.c index 9e629fdad..52a7cba11 100644 --- a/src/game/setuppads.c +++ b/src/game/setuppads.c @@ -11,6 +11,7 @@ #include "lib/model.h" #include "data.h" #include "types.h" +#include "platform.h" /** * The function assumes that a pad file's data has been loaded from the ROM @@ -40,7 +41,11 @@ void setupPreparePads(void) s32 offset; g_PadsFile = (struct padsfileheader *)g_StageSetup.padfiledata; +#ifdef PLATFORM_64BIT + g_PadOffsets = (u16 *)(g_StageSetup.padfiledata + 0x20); +#else g_PadOffsets = (u16 *)(g_StageSetup.padfiledata + 0x14); +#endif padnum = 0; numpads = g_PadsFile->numpads; diff --git a/src/game/stars.c b/src/game/stars.c index 3f15c28a5..e787fb1c5 100644 --- a/src/game/stars.c +++ b/src/game/stars.c @@ -142,7 +142,7 @@ void starsReset(void) } count = 6 * g_StarGridSize * g_StarGridSize + 1; - g_StarData3 = (f32 *)(count * sizeof(f32) + (s32)g_StarPosIndexes); + g_StarData3 = (f32 *)(count * sizeof(f32) + (uintptr_t)g_StarPosIndexes); stars0f135c70(); diff --git a/src/game/tex.c b/src/game/tex.c index 953b5a464..b46b9e8b0 100644 --- a/src/game/tex.c +++ b/src/game/tex.c @@ -8,6 +8,7 @@ #include "gbiex.h" #include "textures.h" #include "types.h" +#include "platform.h" #define TXMODE_WRAP 0 #define TXMODE_CLAMP 1 @@ -861,7 +862,11 @@ s32 texLoadFromGdl(Gfx *instart, s32 gdlsizeinbytes, Gfx *outstart, struct texpo ingdl = instart; outgdl = outstart; +#ifdef PLATFORM_64BIT + numcmdsremaining = gdlsizeinbytes >> 4; +#else numcmdsremaining = gdlsizeinbytes >> 3; +#endif texResetTiles(); @@ -1157,12 +1162,17 @@ s32 texLoadFromGdl(Gfx *instart, s32 gdlsizeinbytes, Gfx *outstart, struct texpo void texCopyGdls(Gfx *src, Gfx *dst, s32 count) { +#ifdef PLATFORM_64BIT + count = (count >> 4); +#else count = (count >> 3); +#endif + src = src + (count - 1); dst = dst + (count - 1); while (count--) { - dst->force_structure_alignment = src->force_structure_alignment; + *dst = *src; dst--; src--; } diff --git a/src/game/texdecompress.c b/src/game/texdecompress.c index a6a4ce296..40e1e4a10 100644 --- a/src/game/texdecompress.c +++ b/src/game/texdecompress.c @@ -12,6 +12,7 @@ #include "types.h" #ifndef PLATFORM_N64 #include "mod.h" +#include "platform.h" #endif struct texture *g_Textures; @@ -2097,7 +2098,7 @@ void texInitPool(struct texpool *pool, u8 *start, s32 len) pool->start = start; pool->end = (struct tex *)(start + len); pool->leftpos = start; - pool->rightpos = (struct tex *)((s32)start + len); + pool->rightpos = (struct tex *)((uintptr_t)start + len); } struct tex *texFindInPool(s32 texturenum, struct texpool *pool) @@ -2144,7 +2145,7 @@ struct tex *texFindInPool(s32 texturenum, struct texpool *pool) s32 texGetPoolFreeBytes(struct texpool *pool) { - return (s32) pool->rightpos - (s32) pool->leftpos; + return (uintptr_t) pool->rightpos - (uintptr_t) pool->leftpos; } u8 *texGetPoolLeftPos(struct texpool *pool) @@ -2155,11 +2156,16 @@ u8 *texGetPoolLeftPos(struct texpool *pool) void texLoadFromDisplayList(Gfx *gdl, struct texpool *pool, s32 arg2) { u8 *bytes = (u8 *)gdl; + u8 ofs = 4; +#ifdef PLATFORM_64BIT + ofs = 8; +#endif + while (bytes[GFX_W0_BYTE(0)] != (u8)G_ENDDL) { // Look for GBI sequence: fd...... abcd.... if (bytes[GFX_W0_BYTE(0)] == G_SETTIMG && bytes[GFX_W1_BYTE(0)] == 0xab && bytes[GFX_W1_BYTE(1)] == 0xcd) { - texLoad((texnum_t *)((uintptr_t)bytes + 4), pool, arg2); + texLoad((texnum_t *)((uintptr_t)bytes + ofs), pool, arg2); } bytes += sizeof(Gfx); @@ -2269,7 +2275,7 @@ void texLoad(texnum_t *updateword, struct texpool *pool, bool unusedarg) // Copy the compressed texture to RAM dmaExec(alignedcompbuffer, (romptr_t) REF_SEG _texturesdataSegmentRomStart + (thisoffset & 0xfffffff8), - ((u32) (nextoffset - thisoffset) + 0x1f) >> 4 << 4); + ((uintptr_t) (nextoffset - thisoffset) + 0x1f) >> 4 << 4); compptr = (u8 *) alignedcompbuffer + (thisoffset & 7); } thisoffset = 0; @@ -2376,12 +2382,12 @@ void texLoad(texnum_t *updateword, struct texpool *pool, bool unusedarg) } } -void texLoadFromConfigs(struct textureconfig *configs, s32 numconfigs, struct texpool *pool, s32 arg3) +void texLoadFromConfigs(struct textureconfig *configs, s32 numconfigs, struct texpool *pool, uintptr_t arg3) { s32 i; for (i = 0; i < numconfigs; i++) { - if ((s32)configs[i].texturenum < NUM_TEXTURES) { + if ((uintptr_t)configs[i].texturenum < NUM_TEXTURES) { texLoad(&configs[i].texturenum, pool, true); configs[i].unk0b = 1; } else { diff --git a/src/game/texreset.c b/src/game/texreset.c index 1daf8c737..85297c81a 100644 --- a/src/game/texreset.c +++ b/src/game/texreset.c @@ -144,7 +144,7 @@ void texReset(void) g_BlurFbDirty = true; #endif - g_TexWords = mempAlloc(ALIGN16(g_TexNumConfigs * 4), MEMPOOL_STAGE); + g_TexWords = mempAlloc(ALIGN16(g_TexNumConfigs * sizeof(uintptr_t)), MEMPOOL_STAGE); for (i = 0; i < g_TexNumConfigs; i++) { g_TexWords[i] = NULL; diff --git a/src/game/texselect.c b/src/game/texselect.c index ee0ad8acd..c2abcf58b 100644 --- a/src/game/texselect.c +++ b/src/game/texselect.c @@ -302,7 +302,7 @@ void texSelect(Gfx **gdlptr, struct textureconfig *tconfig, u32 arg2, s32 arg3, #ifdef __sgi index = tconfig - g_TexWallhitConfigs; #else - index = ((s32) tconfig - (s32) g_TexWallhitConfigs) / sizeof(struct textureconfig); + index = ((uintptr_t) tconfig - (uintptr_t) g_TexWallhitConfigs) / sizeof(struct textureconfig); #endif if (index >= 0 && index < g_TexNumConfigs) { diff --git a/src/game/tilesreset.c b/src/game/tilesreset.c index ed074c028..f88795a12 100644 --- a/src/game/tilesreset.c +++ b/src/game/tilesreset.c @@ -18,7 +18,7 @@ void tilesReset(void) } g_LoadType = LOADTYPE_TILES; - g_TileFileData.u8 = fileLoadToNew(g_Stages[index].tilefileid, FILELOADMETHOD_DEFAULT); + g_TileFileData.u8 = fileLoadToNew(g_Stages[index].tilefileid, FILELOADMETHOD_DEFAULT, LOADTYPE_TILES); g_TileNumRooms = *g_TileFileData.u32; g_TileRooms = g_TileFileData.u32 + 1; diff --git a/src/game/title.c b/src/game/title.c index db1a78531..c37103a2e 100644 --- a/src/game/title.c +++ b/src/game/title.c @@ -838,8 +838,8 @@ Gfx *titleRenderPdLogoModel(Gfx *gdl, struct model *model, bool arg2, f32 arg3, rwdata = modelGetNodeRwData(model, node2); } - s1 = (Col *)ALIGN8(s5rodata->numvertices * sizeof(Vtx) + (s32)s5rodata->vertices); - s2 = (Col *)ALIGN8(s1rodata->numvertices * (s32) sizeof(Vtx) + (s32)s1rodata->vertices); + s1 = (Col *)ALIGN8(s5rodata->numvertices * sizeof(Vtx) + (uintptr_t)s5rodata->vertices); + s2 = (Col *)ALIGN8(s1rodata->numvertices * sizeof(Vtx) + (uintptr_t)s1rodata->vertices); a3 = s5rodata->vertices; t0 = s1rodata->vertices; @@ -882,8 +882,8 @@ Gfx *titleRenderPdLogoModel(Gfx *gdl, struct model *model, bool arg2, f32 arg3, spfc[j].a = alpha2; } - sp100 = (void *)ALIGN8(s5rodata->numvertices * sizeof(Vtx) + (s32)sp100); - spfc = (void *)ALIGN8(s5rodata->numcolours * sizeof(u32) + (s32)spfc); + sp100 = (void *)ALIGN8(s5rodata->numvertices * sizeof(Vtx) + (uintptr_t)sp100); + spfc = (void *)ALIGN8(s5rodata->numcolours * sizeof(u32) + (uintptr_t)spfc); } } diff --git a/src/game/trainingmenus.c b/src/game/trainingmenus.c index 4729e17c3..8a0d1a425 100644 --- a/src/game/trainingmenus.c +++ b/src/game/trainingmenus.c @@ -209,7 +209,7 @@ MenuItemHandlerResult frWeaponListMenuHandler(s32 operation, struct menuitem *it G_TX_RENDERTILE, 0, 0x0160, 1024 / g_ScaleX, -1024); } - return (s32)gdl; + return (uintptr_t)gdl; } return 0; @@ -279,7 +279,7 @@ MenuItemHandlerResult frDifficultyDropdownMenuHandler(s32 operation, struct menu } break; case MENUOP_GETOPTIONTEXT: - return (s32) langGet(names[data->dropdown.value]); + return (uintptr_t) langGet(names[data->dropdown.value]); case MENUOP_SET: frSetDifficulty(data->dropdown.value); menuPushDialog(&g_FrTrainingInfoPreGameMenuDialog); @@ -876,7 +876,7 @@ MenuItemHandlerResult frScoringMenuHandler(s32 operation, struct menuitem *item, gdl = menugfxDrawDialogBorderLine(gdl, renderdata->x + 90, renderdata->y + 50, renderdata->x + 96, renderdata->y + 51, linecolourmid, linecolourfig); #endif - return (s32)gdl; + return (uintptr_t)gdl; } return 0; @@ -1438,10 +1438,10 @@ MenuItemHandlerResult ciOfficeInformationMenuHandler(s32 operation, struct menui case MENUOP_GETOPTIONTEXT: if (data->list.value < numunlockedchrbios) { chrbio = ciGetChrBioByBodynum(ciGetChrBioBodynumBySlot(data->list.value)); - return (s32) langGet(chrbio->name); + return (uintptr_t) langGet(chrbio->name); } else { miscbio = ciGetMiscBio(ciGetMiscBioIndexBySlot(data->list.value - numunlockedchrbios)); - return (s32) langGet(miscbio->name); + return (uintptr_t) langGet(miscbio->name); } break; case MENUOP_SET: @@ -1459,7 +1459,7 @@ MenuItemHandlerResult ciOfficeInformationMenuHandler(s32 operation, struct menui data->list.value = 2; break; case MENUOP_GETOPTGROUPTEXT: - return (s32) langGet(groups[data->list.value].name); + return (uintptr_t) langGet(groups[data->list.value].name); case MENUOP_GETGROUPSTARTINDEX: data->list.groupstartindex = data->list.value == 0 ? 0 : numunlockedchrbios; break; @@ -1730,7 +1730,7 @@ MenuItemHandlerResult dtDeviceListMenuHandler(s32 operation, struct menuitem *it data->list.value = dtGetNumAvailable(); break; case MENUOP_GETOPTIONTEXT: - return (s32) bgunGetName(dtGetWeaponByDeviceIndex(dtGetIndexBySlot(data->list.value))); + return (uintptr_t) bgunGetName(dtGetWeaponByDeviceIndex(dtGetIndexBySlot(data->list.value))); case MENUOP_SET: g_DtSlot = data->list.value; menuPushDialog(&g_DtDetailsMenuDialog); @@ -2086,7 +2086,7 @@ MenuItemHandlerResult htHoloListMenuHandler(s32 operation, struct menuitem *item data->list.value = htGetNumUnlocked(); break; case MENUOP_GETOPTIONTEXT: - return (s32) htGetName(htGetIndexBySlot(data->list.value)); + return (uintptr_t) htGetName(htGetIndexBySlot(data->list.value)); case MENUOP_SET: var80088bb4 = data->list.value; menuPushDialog(&g_HtDetailsMenuDialog); @@ -2592,7 +2592,7 @@ MenuItemHandlerResult ciHangarInformationMenuHandler(s32 operation, struct menui break; case MENUOP_GETOPTIONTEXT: bio = ciGetHangarBio(ciGetHangarBioIndexBySlot(data->list.value)); - return (s32) langGet(bio->name); + return (uintptr_t) langGet(bio->name); case MENUOP_SET: g_HangarBioSlot = data->list.value; bioindex = ciGetHangarBioIndexBySlot(g_HangarBioSlot); @@ -2610,7 +2610,7 @@ MenuItemHandlerResult ciHangarInformationMenuHandler(s32 operation, struct menui data->list.value = 2; break; case MENUOP_GETOPTGROUPTEXT: - return (s32) langGet(groups[data->list.value].name); + return (uintptr_t) langGet(groups[data->list.value].name); case MENUOP_GETGROUPSTARTINDEX: data->list.groupstartindex = data->list.value == 0 ? 0 : groups[1].offset; break; @@ -2692,7 +2692,7 @@ MenuItemHandlerResult ciHangarTitleMenuHandler(s32 operation, struct menuitem *i gdl = text0f153780(gdl); - return (s32)gdl; + return (uintptr_t)gdl; } return 0; diff --git a/src/game/utils.c b/src/game/utils.c index 0432870f4..fa00c2e0e 100644 --- a/src/game/utils.c +++ b/src/game/utils.c @@ -69,10 +69,10 @@ u32 align16(u32 arg0) return arg0; } -u32 align32(u32 arg0) +uintptr_t align32(uintptr_t arg0) { if (arg0 & 0x1f) { - arg0 = (arg0 & 0xffffffe0) + 0x20; + arg0 = (arg0 & ((intptr_t)~0x1f)) + 0x20; } return arg0; diff --git a/src/game/vtxstore.c b/src/game/vtxstore.c index de494845e..4999ea6de 100644 --- a/src/game/vtxstore.c +++ b/src/game/vtxstore.c @@ -64,8 +64,8 @@ void vtxstoreFixRefs(void *find, void *replacement) case MODELNODETYPE_DL: rodata = &node->rodata->dl; - if (model->rwdatas[rodata->rwdataindex] == (u32) find) { - model->rwdatas[rodata->rwdataindex] = (u32) replacement; + if (model->rwdatas[rodata->rwdataindex] == (uintptr_t) find) { + model->rwdatas[rodata->rwdataindex] = (uintptr_t) replacement; } break; case MODELNODETYPE_DISTANCE: diff --git a/src/game/weatherreset.c b/src/game/weatherreset.c index 5c7c1683b..6ea5efc58 100644 --- a/src/game/weatherreset.c +++ b/src/game/weatherreset.c @@ -82,7 +82,9 @@ void weatherReset(void) #else g_WeatherData->windspeed = g_CurWeatherConfig->windspeed; // set up the weatherproof flags in all rooms - weatherResetRooms(); + if (g_Vars.stagenum != STAGE_TITLE) { + weatherResetRooms(); + } #endif g_WeatherData->audiohandles[0] = 0; diff --git a/src/include/bss.h b/src/include/bss.h index f9115d1f5..80b38acb4 100644 --- a/src/include/bss.h +++ b/src/include/bss.h @@ -250,7 +250,7 @@ extern struct seqchannel g_SeqChannels[3]; extern u32 g_AudioXReasonsActive[4]; extern s32 g_MusicXReasonMinDurations[4]; extern s32 g_MusicXReasonMaxDurations[4]; -extern u32 *g_LangBanks[69]; +extern uintptr_t *g_LangBanks[69]; extern struct jpncharpixels *g_JpnCharCachePixels; extern struct jpncacheitem *g_JpnCacheCacheItems; extern struct texture *g_Textures; diff --git a/src/include/constants.h b/src/include/constants.h index 71ced0769..2fd08e73f 100644 --- a/src/include/constants.h +++ b/src/include/constants.h @@ -56,9 +56,10 @@ #define ABS(val) ((val) > 0 ? (val) : -(val)) #define ABSF(val) ((val) > 0.0f ? (val) : -(val)) #define ALIGN2(val) (((val) | 1) ^ 0x1) +#define ALIGN4(val) (((val) | 3) ^ 0x3) #define ALIGN8(val) ((((val) + 0x7) | 0x7) ^ 0x7) #define ALIGN16(val) ((((val) + 0xf) | 0xf) ^ 0xf) -#define ALIGN64(val) (((((u32)(val)) + 0x3f) | 0x3f) ^ 0x3f) +#define ALIGN64(val) (((((uintptr_t)(val)) + 0x3f) | 0x3f) ^ 0x3f) #define ARRAYCOUNT(a) (s32)(sizeof(a) / sizeof(a[0])) #define CHRNAVSEED(chr) ((g_Vars.lvframe60 >> 9) * 128 + chr->chrnum * 8) #define CHRRACE(chr) (chr ? chr->race : RACE_HUMAN) diff --git a/src/include/game/bondgun.h b/src/include/game/bondgun.h index e4dad3663..8b35b5852 100644 --- a/src/include/game/bondgun.h +++ b/src/include/game/bondgun.h @@ -118,8 +118,8 @@ bool bgun0f0a27c8(void); void bgunHandlePlayerDead(void); bool bgunIsMissionCritical(s32 weaponnum); void bgunDisarm(struct prop *attacker); -void bgunExecuteModelCmdList(s32 *arg0); -s32 bgunCreateModelCmdList(struct model *model, struct modelnode *node, s32 *ptr); +void bgunExecuteModelCmdList(uintptr_t *arg0); +s32 bgunCreateModelCmdList(struct model *model, struct modelnode *node, uintptr_t *ptr); void bgunStartDetonateAnimation(s32 playernum); void bgunUpdateGangsta(struct hand *hand, s32 handnum, struct coord *arg2, struct weaponfunc *funcdef, Mtxf *arg4, Mtxf *arg5); void bgunUpdateSmoke(struct hand *hand, s32 handnum, s32 weaponnum, struct weaponfunc *funcdef); diff --git a/src/include/game/file.h b/src/include/game/file.h index d26f6ca61..24fee6c0a 100644 --- a/src/include/game/file.h +++ b/src/include/game/file.h @@ -4,12 +4,16 @@ #include "data.h" #include "types.h" +#ifndef PLATFORM_N64 +#include "romdata.h" +#endif + romptr_t fileGetRomAddress(s32 filenum); s32 fileGetRomSize(s32 filenum); void filesInit(void); void fileLoadPartToAddr(u16 filenum, void *memaddr, s32 offset, u32 len); -u32 fileGetInflatedSize(s32 filenum); -void *fileLoadToNew(s32 filenum, u32 method); +u32 fileGetInflatedSize(s32 filenum, u32 loadtype); +void *fileLoadToNew(s32 filenum, u32 method, u32 loadtype); void *fileLoadToAddr(s32 filenum, s32 method, u8 *ptr, u32 size); u32 fileGetLoadedSize(s32 filenum); u32 fileGetAllocationSize(s32 filenum); diff --git a/src/include/game/filemgr.h b/src/include/game/filemgr.h index c0f63bad8..80695df9d 100644 --- a/src/include/game/filemgr.h +++ b/src/include/game/filemgr.h @@ -16,7 +16,7 @@ void filemgrSetFileToDelete(struct filelistfile *file, s32 filetype); char *filemgrMenuTextFailReason(struct menuitem *item); char *filemgrMenuTextDeviceNameForError(struct menuitem *item); void filemgrPushErrorDialog(u16 errnum); -s32 filemgrGetDeviceNameOrStartIndex(s32 listnum, s32 operation, s32 optionindex); +uintptr_t filemgrGetDeviceNameOrStartIndex(s32 listnum, s32 operation, s32 optionindex); char *filemgrMenuTextErrorTitle(struct menuitem *item); char *filemgrMenuTextFileType(struct menuitem *item); void func0f10898c(void); diff --git a/src/include/game/texdecompress.h b/src/include/game/texdecompress.h index a6d92d548..4fc372967 100644 --- a/src/include/game/texdecompress.h +++ b/src/include/game/texdecompress.h @@ -33,7 +33,7 @@ s32 texGetPoolFreeBytes(struct texpool *pool); u8 *texGetPoolLeftPos(struct texpool *pool); void texLoadFromDisplayList(Gfx *gdl, struct texpool *pool, s32 arg2); void texLoad(texnum_t *updateword, struct texpool *pool, bool unusedarg); -void texLoadFromConfigs(struct textureconfig *configs, s32 numconfigs, struct texpool *pool, s32 arg3); +void texLoadFromConfigs(struct textureconfig *configs, s32 numconfigs, struct texpool *pool, uintptr_t arg3); void texLoadFromTextureNum(u32 arg0, struct texpool *pool); #ifndef PLATFORM_N64 void texSwizzleInternal(u8 *dst, s32 width, s32 height, s32 format, u32 dstlen); diff --git a/src/include/game/title.h b/src/include/game/title.h index 6dc4ed517..3e6771dc5 100644 --- a/src/include/game/title.h +++ b/src/include/game/title.h @@ -4,7 +4,7 @@ #include "data.h" #include "types.h" -#define TITLE_ALLOCSIZE 1024 * 286 +#define TITLE_ALLOCSIZE 1024 * 378 extern u32 var800624d4; extern u32 var800624d8; diff --git a/src/include/game/utils.h b/src/include/game/utils.h index 5e992a212..83ada1f98 100644 --- a/src/include/game/utils.h +++ b/src/include/game/utils.h @@ -7,7 +7,7 @@ void func0f176d70(s32 arg0); u32 align4(u32 arg0); u32 align16(u32 arg0); -u32 align32(u32 arg0); +uintptr_t align32(uintptr_t arg0); void utilsInit(void); void func0f1770ac(struct coord *a, struct coord *b, struct coord *out); bool func0f177164(struct coord *arg0, struct coord *arg1, u32 line, char *file); diff --git a/src/include/gunscript.h b/src/include/gunscript.h index 224c1dd7c..b3cd21870 100644 --- a/src/include/gunscript.h +++ b/src/include/gunscript.h @@ -17,10 +17,10 @@ { GUNCMD_PLAYSOUND, 0, keyframe, sound }, #define gunscript_include(unk1, address) \ - { GUNCMD_INCLUDE, unk1, 0, (u32)address }, + { GUNCMD_INCLUDE, unk1, 0, (uintptr_t)address }, #define gunscript_random(probability, address) \ - { GUNCMD_RANDOM, 0, probability, (u32)address }, + { GUNCMD_RANDOM, 0, probability, (uintptr_t)address }, #define gunscript_repeatuntilfull(triggerkey, dontloop, gototrigger) \ { GUNCMD_REPEATUNTILFULL, 0, triggerkey, (dontloop << 16) | gototrigger }, diff --git a/src/include/lib/mema.h b/src/include/lib/mema.h index c83878ef6..29f4b754b 100644 --- a/src/include/lib/mema.h +++ b/src/include/lib/mema.h @@ -6,13 +6,13 @@ void memaDefrag(void); void memaInit(void); -void memaReset(void *ptr, u32 size); +void memaReset(void *ptr, u64 size); void memaPrint(void); -void *memaAlloc(u32 size); -s32 memaGrow(s32 addr, u32 amount); -void _memaFree(s32 addr, s32 size); -void memaFree(void *addr, s32 size); -s32 memaGetLongestFree(void); -bool memaRealloc(s32 addr, u32 oldsize, u32 newsize); +void *memaAlloc(u64 size); +uintptr_t memaGrow(uintptr_t addr, u64 amount); +void _memaFree(uintptr_t addr, u64 size); +void memaFree(void *addr, u64 size); +u64 memaGetLongestFree(void); +bool memaRealloc(uintptr_t addr, u64 oldsize, u64 newsize); #endif diff --git a/src/include/lib/model.h b/src/include/lib/model.h index 8d6cef0c8..1e75e6b3b 100644 --- a/src/include/lib/model.h +++ b/src/include/lib/model.h @@ -97,7 +97,7 @@ void modelRenderNodeChrGunfire(struct modelrenderdata *renderdata, struct model void modelRender(struct modelrenderdata *renderdata, struct model *model); bool modelTestBboxNodeForHit(struct modelrodata_bbox *bbox, Mtxf *mtx, struct coord *arg2, struct coord *arg3); s32 modelTestForHit(struct model *model, struct coord *arg1, struct coord *arg2, struct modelnode **startnode); -void modelPromoteNodeOffsetsToPointers(struct modelnode *node, u32 vma, u32 fileramaddr); +void modelPromoteNodeOffsetsToPointers(struct modelnode *node, u32 vma, uintptr_t fileramaddr); void modelPromoteOffsetsToPointers(struct modeldef *modeldef, u32 arg1, uintptr_t arg2); s32 modelCalculateRwDataIndexes(struct modelnode *node); void modelAllocateRwData(struct modeldef *modeldef); diff --git a/src/include/lib/mp3.h b/src/include/lib/mp3.h index 6369dd7e8..92b720046 100644 --- a/src/include/lib/mp3.h +++ b/src/include/lib/mp3.h @@ -5,7 +5,7 @@ #include "types.h" void mp3Init(ALHeap *heap); -void mp3PlayFile(s32 romaddr, s32 filesize); +void mp3PlayFile(uintptr_t romaddr, s32 filesize); void func00037e1c(void); void func00037e38(void); void func00037e68(void); diff --git a/src/include/lib/rdp.h b/src/include/lib/rdp.h index 6d54e5e44..ee489b81b 100644 --- a/src/include/lib/rdp.h +++ b/src/include/lib/rdp.h @@ -5,6 +5,6 @@ #include "types.h" void rdpInit(void); -void rdpCreateTask(Gfx *gdlstart, Gfx *gdlend, u32 arg2, s32 msg); +void rdpCreateTask(Gfx *gdlstart, Gfx *gdlend, u32 arg2, uintptr_t msg); #endif diff --git a/src/include/lib/snd.h b/src/include/lib/snd.h index 0b96846c3..0f1056039 100644 --- a/src/include/lib/snd.h +++ b/src/include/lib/snd.h @@ -12,11 +12,11 @@ void snd0000ea80(u16 volume); void sndResetCurMp3(void); void sndLoadSfxCtl(void); void sndIncrementAges(void); -ALEnvelope *sndLoadEnvelope(u32 offset, u16 index); -ALKeyMap *sndLoadKeymap(u32 offset, u16 index); -ALADPCMBook *sndLoadAdpcmBook(u32 offset, u16 index); -ALADPCMloop *sndLoadAdpcmLoop(u32 offset, u16 index); -ALWaveTable *sndLoadWavetable(u32 offset, u16 index); +ALEnvelope *sndLoadEnvelope(uintptr_t offset, u16 index); +ALKeyMap *sndLoadKeymap(uintptr_t offset, u16 index); +ALADPCMBook* sndLoadAdpcmBook(uintptr_t offset, u16 index); +ALADPCMloop* sndLoadAdpcmLoop(uintptr_t offset, u16 index); +ALWaveTable* sndLoadWavetable(uintptr_t offset, u16 index); void sndSetSoundMode(s32 mode); ALSound *sndLoadSound(s16 soundnum); void seqInit(struct seqinstance *seq); diff --git a/src/include/platform.h b/src/include/platform.h index 30615f750..949ff31a6 100644 --- a/src/include/platform.h +++ b/src/include/platform.h @@ -29,11 +29,6 @@ #error "Unknown CPU arch." #endif -// TODO: remove this after 64-bit support is in place -#ifdef PLATFORM_64BIT - #error "64-bit platforms are currently not supported." -#endif - // detect endianness #if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ diff --git a/src/include/types.h b/src/include/types.h index d69e167f3..2ba79f756 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -27,7 +27,7 @@ typedef s32 PakErr1; typedef s32 PakErr2; typedef s32 MenuDialogHandlerResult; -typedef intptr_t MenuItemHandlerResult; +typedef uintptr_t MenuItemHandlerResult; typedef s16 RoomNum; #ifdef PLATFORM_N64 @@ -541,6 +541,8 @@ struct modelrodata_type11 { // type 0x11 u32 unk0c; u32 unk10; void *unk14; + u32 unk18; + u32 unk1c; }; struct modelrodata_toggle { // type 0x12 @@ -551,6 +553,7 @@ struct modelrodata_toggle { // type 0x12 struct modelrodata_positionheld { // type 0x15 struct coord pos; s16 mtxindex; + s32 unk10; }; struct modelrodata_stargunfire { // type 0x16 @@ -2309,8 +2312,8 @@ struct hand { /*0x0dbc*/ u32 fspare7; /*0x0dc0*/ u32 fspare8; /*0x0dc4*/ struct abmag abmag; - /*0x0dcc*/ s32 *unk0dcc; - /*0x0dd0*/ s32 *unk0dd0; + /*0x0dcc*/ uintptr_t *unk0dcc; + /*0x0dd0*/ uintptr_t *unk0dd0; /*0x0dd4*/ s32 unk0dd4; /*0x0dd8*/ Mtxf *unk0dd8; }; @@ -2357,8 +2360,8 @@ struct gunctrl { /*0x15b1*/ u8 gunloadstate; /*0x15b2*/ u16 loadfilenum; /*0x15b4*/ struct modeldef **loadtomodeldef; - /*0x15b8*/ u32 *loadmemptr; - /*0x15bc*/ u32 *loadmemremaining; + /*0x15b8*/ uintptr_t *loadmemptr; + /*0x15bc*/ uintptr_t*loadmemremaining; /*0x15c0*/ struct texpool texpool; /*0x15d0*/ u32 nexttexturetoload; /*0x15d4*/ struct fileinfo fileinfo; @@ -2850,6 +2853,7 @@ struct coverdefinition { struct coord pos; struct coord look; u16 flags; + u16 unk1a; }; struct cover { @@ -2862,9 +2866,9 @@ struct cover { struct padsfileheader { s32 numpads; s32 numcovers; - s32 waypointsoffset; - s32 waygroupsoffset; - s32 coversoffset; + uintptr_t waypointsoffset; + uintptr_t waygroupsoffset; + uintptr_t coversoffset; u16 padoffsets[1]; }; @@ -3354,8 +3358,8 @@ struct handlerdata_checkbox { }; struct handlerdata_dropdown { - u32 value; - u32 unk04; + uintptr_t value; + uintptr_t unk04; }; struct handlerdata_keyboard { @@ -3369,8 +3373,8 @@ struct handlerdata_label { struct handlerdata_list { union { - u32 value; - s32 values32; + uintptr_t value; + intptr_t values32; }; union { s32 unk04; @@ -3396,8 +3400,8 @@ struct menuitemrenderdata { struct handlerdata_type19 { Gfx *gdl; union { - s32 unk04; - u32 unk04u32; + intptr_t unk04; + uintptr_t unk04u32; }; struct menuitemrenderdata *renderdata2; s32 unk0c; @@ -3433,7 +3437,7 @@ struct menuitem { intptr_t param3; union { - s32 (*handler)(s32 operation, struct menuitem *item, union handlerdata *data); + uintptr_t (*handler)(s32 operation, struct menuitem *item, union handlerdata *data); void (*handlervoid)(s32 operation, struct menuitem *item, union handlerdata *data); }; }; @@ -3883,7 +3887,11 @@ struct menumodel { /*0x05e*/ s16 curanimnum; /*0x060*/ struct model bodymodel; /*0x084*/ struct anim bodyanim; +#ifdef PLATFORM_64BIT + /*0x110*/ u32 rwdata[256+128]; +#else /*0x110*/ u32 rwdata[256]; +#endif /*0x510*/ f32 curposx; /*0x514*/ f32 curposy; /*0x518*/ f32 curposz; @@ -5183,7 +5191,7 @@ struct shieldhit { }; struct bgroom { - u32 unk00; + uintptr_t unk00; struct coord pos; u8 br_light_min; u8 br_light_max; @@ -5246,7 +5254,7 @@ struct mplockinfo { struct boltbeam { union { - s32 unk00; + intptr_t unk00; struct prop *unk00_prop; }; @@ -5378,7 +5386,7 @@ struct guncmd { u8 type; u8 unk01; u16 unk02; - s32 unk04; + intptr_t unk04; }; struct pakthing { diff --git a/src/lib/dma.c b/src/lib/dma.c index e3701a677..698802c0b 100644 --- a/src/lib/dma.c +++ b/src/lib/dma.c @@ -181,8 +181,8 @@ void dmaExecHighPriority(void *memaddr, romptr_t romaddr, u32 len) */ void *dmaExecWithAutoAlign(void *memaddr, romptr_t romaddr, u32 len) { - u32 alignedrom = ALIGN2(romaddr); - u32 alignedmem = ALIGN16((uintptr_t) memaddr); + uintptr_t alignedrom = ALIGN2(romaddr); + uintptr_t alignedmem = ALIGN16((uintptr_t) memaddr); u32 offset = romaddr - alignedrom; // 0 or 1 u32 alignedlen = ALIGN16(offset + len); diff --git a/src/lib/main.c b/src/lib/main.c index 12ea8095c..01c4d805d 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -489,7 +489,7 @@ void mainInit(void) if (*(s16 *) receivedmsg == OS_SC_RETRACE_MSG) { viUpdateMode(); - rdpCreateTask(var8005dcc8, var8005dcc8 + ARRAYCOUNT(var8005dcc8), 0, (s32) &scdonemsg); + rdpCreateTask(var8005dcc8, var8005dcc8 + ARRAYCOUNT(var8005dcc8), 0, (uintptr_t) &scdonemsg); j++; } } @@ -611,7 +611,7 @@ void mainInit(void) if (*(s16 *) receivedmsg == OS_SC_RETRACE_MSG) { viUpdateMode(); - rdpCreateTask(var8005dcc8, var8005dcc8 + ARRAYCOUNT(var8005dcc8), 0, (s32) &scdonemsg); + rdpCreateTask(var8005dcc8, var8005dcc8 + ARRAYCOUNT(var8005dcc8), 0, (uintptr_t) &scdonemsg); i++; } } @@ -978,7 +978,7 @@ void mainLoop(void) { char message[80]; u32 stack2; - sprintf(message, "boss.c default: %08x type %d\n", (s32) msg, *(s16 *) msg); + sprintf(message, "boss.c default: %08x type %d\n", (uintptr_t) msg, *(s16 *) msg); crashSetMessage(message); CRASH(); } @@ -1092,7 +1092,7 @@ void mainTick(void) viUpdateMode(); } - rdpCreateTask(gdlstart, gdl, 0, (s32) &msg); + rdpCreateTask(gdlstart, gdl, 0, (uintptr_t) &msg); g_MainNumGfxTasks++; memaPrint(); func0f16cf94(); diff --git a/src/lib/mema.c b/src/lib/mema.c index 7cbe894c0..d0676ccff 100644 --- a/src/lib/mema.c +++ b/src/lib/mema.c @@ -38,8 +38,8 @@ #define MAX_SPACES 124 struct memaspace { - s32 addr; - u32 size; + uintptr_t addr; + u64 size; }; /** @@ -55,8 +55,8 @@ struct memaheap { struct memaspace end2; }; -s32 g_MemaHeapStart; -s32 g_MemaHeapSize; +uintptr_t g_MemaHeapStart; +u64 g_MemaHeapSize; struct memaheap g_MemaHeap; #if VERSION == VERSION_PAL_BETA @@ -65,8 +65,8 @@ u32 g_MemaLeastEverFree = 1000000; void memaSwap(struct memaspace *a, struct memaspace *b) { - u32 tempaddr = a->addr; - u32 tempsize = a->size; + uintptr_t tempaddr = a->addr; + u64 tempsize = a->size; a->addr = b->addr; a->size = b->size; b->addr = tempaddr; @@ -86,7 +86,7 @@ bool memaDefragPass(struct memaheap *heap) struct memaspace *prev = &heap->start; struct memaspace *curr = &heap->spaces[0]; struct memaspace *last = &heap->spaces[MAX_SPACES - 1]; - u32 addr = 0; + uintptr_t addr = 0; while (curr <= last) { if (curr->size != 0) { @@ -177,7 +177,7 @@ struct memaspace *memaMakeSlot(struct memaheap *heap) return best; } -void _memaFree(s32 addr, s32 size) +void _memaFree(uintptr_t addr, u64 size) { // Choose an index in the spaces array which we'll mark a space as free, // based on how far into the heap the allocation is. This is a rough @@ -215,7 +215,7 @@ void memaInit(void) // empty } -void memaReset(void *heapaddr, u32 heapsize) +void memaReset(void *heapaddr, u64 heapsize) { struct memaspace *space; @@ -398,14 +398,14 @@ void memaPrint(void) #endif } -void *memaAlloc(u32 size) +void *memaAlloc(u64 size) { - u32 addr; - u32 diff; + uintptr_t addr; + uintptr_t diff; s32 i; struct memaspace *curr; - u32 bestdiff; + uintptr_t bestdiff; struct memaspace *best; if (1); @@ -487,7 +487,7 @@ void *memaAlloc(u32 size) /** * Grow the allocation which currently *ends at* the given address. */ -s32 memaGrow(s32 addr, u32 amount) +uintptr_t memaGrow(uintptr_t addr, u64 amount) { struct memaspace *curr = &g_MemaHeap.spaces[0]; @@ -512,7 +512,7 @@ found: return addr; } -void memaFree(void *addr, s32 size) +void memaFree(void *addr, u64 size) { _memaFree((uintptr_t) addr, size); } @@ -526,7 +526,7 @@ void mema00012cd4(void) * Find and return the largest amount of contiguous free space in the pool. * ie. the biggest allocation that mema can currently make. */ -s32 memaGetLongestFree(void) +u64 memaGetLongestFree(void) { struct memaspace *curr; s32 biggest = 0; @@ -550,7 +550,7 @@ s32 memaGetLongestFree(void) return 0; } -bool memaRealloc(s32 addr, u32 oldsize, u32 newsize) +bool memaRealloc(uintptr_t addr, u64 oldsize, u64 newsize) { if (newsize > oldsize) { if (!memaGrow(addr + oldsize, newsize - oldsize)) { diff --git a/src/lib/memp.c b/src/lib/memp.c index 99b8bf476..6c59b91c5 100644 --- a/src/lib/memp.c +++ b/src/lib/memp.c @@ -6,6 +6,7 @@ #include "lib/memp.h" #include "data.h" #include "types.h" +#include "system.h" /** * memp - memory pool allocation system. @@ -178,10 +179,12 @@ void *mempAllocFromBank(struct memorypool *pool, u32 size, u8 poolnum) } if (pool->leftpos > pool->rightpos) { + sysLogPrintf(LOG_NOTE, "#warning: memory pool %x is full. Req: %d\n", pool, size); return 0; } if (pool->leftpos + size > pool->rightpos) { + sysLogPrintf(LOG_NOTE, "#warning: memory pool %x is full. Req: %d\n", pool, size); return 0; } diff --git a/src/lib/model.c b/src/lib/model.c index ee446a962..929f5c7b4 100644 --- a/src/lib/model.c +++ b/src/lib/model.c @@ -3853,10 +3853,10 @@ s32 modelTestForHit(struct model *model, struct coord *arg1, struct coord *arg2, if (var) \ var = (void *)((uintptr_t)var + diff) -void modelPromoteNodeOffsetsToPointers(struct modelnode *node, u32 vma, u32 fileramaddr) +void modelPromoteNodeOffsetsToPointers(struct modelnode *node, u32 vma, uintptr_t fileramaddr) { union modelrodata *rodata; - s32 diff = fileramaddr - vma; + uintptr_t diff = fileramaddr - vma; while (node) { u32 type = node->type & 0xff; @@ -3949,7 +3949,7 @@ void modelPromoteNodeOffsetsToPointers(struct modelnode *node, u32 vma, u32 file */ void modelPromoteOffsetsToPointers(struct modeldef *modeldef, u32 vma, uintptr_t fileramaddr) { - s32 diff = fileramaddr - vma; + uintptr_t diff = fileramaddr - vma; s32 i; s16 *partnums; diff --git a/src/lib/modelasm_c.c b/src/lib/modelasm_c.c index c443b9b91..6570424bb 100644 --- a/src/lib/modelasm_c.c +++ b/src/lib/modelasm_c.c @@ -5,6 +5,7 @@ #include "lib/model.h" #include "lib/mtx.h" #include "types.h" +#include "platform.h" struct t0slot { u16 unk00; @@ -1158,6 +1159,18 @@ static u32 modelasmReadFrameData(void) * Each value is the byte offset into the rodata struct where that node type's * rwdataindex property can be found, or 0xff is there is none. */ + +#ifdef PLATFORM_64BIT +u8 var8005ef90[] = { + 0xff, 0x08, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0x10, 0x2a, 0xff, 0x48, + 0x24, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x08, 0xff, + 0xff, 0xff, 0xff, 0x00, + 0x24, 0x00, +}; +#else u8 var8005ef90[] = { 0xff, 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -1167,6 +1180,7 @@ u8 var8005ef90[] = { 0xff, 0xff, 0xff, 0x00, 0x14, 0x00, }; +#endif static union modelrwdata *modelasmGetNodeRwData(struct model *model, struct modelnode *node, bool is_head) { diff --git a/src/lib/mp3.c b/src/lib/mp3.c index 270340c1d..37e3de385 100644 --- a/src/lib/mp3.c +++ b/src/lib/mp3.c @@ -6,6 +6,7 @@ #include "lib/mp3.h" #include "mp3/mp3.h" #include "types.h" +#include "platform.h" /** * These two ABI commands are used in this file, but the format of the data @@ -60,7 +61,11 @@ void mp3Init(ALHeap *heap) var8009c6d8 = alHeapAlloc(heap, 256 * sizeof(var8009c6d8[0]), 1); var8009c6dc = alHeapAlloc(heap, 256 * sizeof(var8009c6dc[0]), 1); +#ifdef PLATFORM_64BIT + var8009c640 = alHeapAlloc(heap, 2*10500 * sizeof(struct mp3decfourbytes), 1); +#else var8009c640 = alHeapAlloc(heap, 10500 * sizeof(struct mp3decfourbytes), 1); +#endif var8009c644 = alHeapAlloc(heap, 8192 * sizeof(var8009c644[0]), 1); mp3mainInit(); @@ -88,7 +93,7 @@ void mp3Init(ALHeap *heap) func00038b90(func00038ba8); } -void mp3PlayFile(s32 romaddr, s32 filesize) +void mp3PlayFile(uintptr_t romaddr, s32 filesize) { if (g_Mp3Vars.var8009c3dc == NULL) { return; @@ -389,7 +394,7 @@ void func00038b90(void *fn) s32 func00038ba8(s32 arg0, u8 *arg1, s32 arg2, s32 arg3) { - u32 sp1c; + uintptr_t sp1c; ALDMAproc proc; if (arg3 != -1) { @@ -412,7 +417,7 @@ s32 func00038ba8(s32 arg0, u8 *arg1, s32 arg2, s32 arg3) void mp3Dma(void) { - u32 state; + uintptr_t state; ALDMAproc proc; proc = n_syn->dma(&state); diff --git a/src/lib/mp3/mp3.h b/src/lib/mp3/mp3.h index 14ac2c6f6..96447a84b 100644 --- a/src/lib/mp3/mp3.h +++ b/src/lib/mp3/mp3.h @@ -2,11 +2,15 @@ #define _IN_LIB_MP3_MP3_H #include #include "types.h" +#include "platform.h" struct mp3decfourbytes { u8 bytes[2]; s8 unk02; s8 unk03; +#ifdef PLATFORM_64BIT + u32 _pad_; +#endif }; struct asistream_scalefac { diff --git a/src/lib/naudio/n_load.c b/src/lib/naudio/n_load.c index 365774c4d..aa8070356 100644 --- a/src/lib/naudio/n_load.c +++ b/src/lib/naudio/n_load.c @@ -258,7 +258,7 @@ s32 n_alLoadParam(N_PVoice *filter, s32 paramID, void *param) Acmd *_decodeChunk(Acmd *ptr, N_PVoice *f, s32 tsam, s32 nbytes, s16 outp, s16 inp, u32 flags) { - s32 dramAlign, dramLoc; + intptr_t dramAlign, dramLoc; if (nbytes > 0) { dramLoc = (f->dc_dma)(f->dc_memin, nbytes, f->dc_dmaState); diff --git a/src/lib/naudio/n_reverb.c b/src/lib/naudio/n_reverb.c index 39657dd89..98c5e30b9 100644 --- a/src/lib/naudio/n_reverb.c +++ b/src/lib/naudio/n_reverb.c @@ -47,8 +47,8 @@ Acmd *n_alFxPull(s32 sampleOffset, Acmd *p, s32 arg2) for (i = 0; i < r->section_count; i++) { d = &r->delay[i]; /* get the ALDelay structure */ - in_ptr = &r->input[j][-d->input]; - out_ptr = &r->input[j][-d->output]; + in_ptr = &r->input[j][(s32)-d->input]; + out_ptr = &r->input[j][(s32)-d->output]; if (var8009c346[arg2] && var8009c344[arg2]) { d->ffcoef = -d->ffcoef; @@ -253,7 +253,7 @@ Acmd *_n_loadOutputBuffer(ALFx *r, ALDelay *d, s32 arg2, s32 buff, Acmd *p) fincount = d->rs->delta + (fratio * (f32)incount); count = (s32) fincount; d->rs->delta = fincount - (f32)count; - out_ptr = &r->input[arg2][-(d->output - d->rsdelta)]; + out_ptr = &r->input[arg2][(s32)-(d->output - d->rsdelta)]; ramalign = ((intptr_t)out_ptr & 0x7) >> 1; ptr = _n_loadBuffer(r, arg2, out_ptr - ramalign, rbuff, count + ramalign, ptr); @@ -265,7 +265,7 @@ Acmd *_n_loadOutputBuffer(ALFx *r, ALDelay *d, s32 arg2, s32 buff, Acmd *p) d->rs->first = 0; d->rsdelta += count - incount; } else { - out_ptr = &r->input[arg2][-d->output]; + out_ptr = &r->input[arg2][(s32)-d->output]; ptr = _n_loadBuffer(r, arg2, out_ptr, buff, FIXED_SAMPLE, ptr); } diff --git a/src/lib/rdp.c b/src/lib/rdp.c index f5c05f614..1782b372f 100644 --- a/src/lib/rdp.c +++ b/src/lib/rdp.c @@ -75,7 +75,7 @@ void rdpInit(void) g_RdpOutBufferEnd = (u16 *) ((uintptr_t) g_RdpOutBufferStart + size); } -void rdpCreateTask(Gfx *gdlstart, Gfx *gdlend, u32 arg2, s32 msg) +void rdpCreateTask(Gfx *gdlstart, Gfx *gdlend, u32 arg2, uintptr_t msg) { OSScTask *sctask; OSTask *task; diff --git a/src/lib/snd.c b/src/lib/snd.c index 997f868b5..ed76b4afa 100644 --- a/src/lib/snd.c +++ b/src/lib/snd.c @@ -64,7 +64,7 @@ struct curmp3 { }; s32 g_NumSounds; -u32 *g_ALSoundRomOffsets; +uintptr_t *g_ALSoundRomOffsets; s32 g_SndMaxFxBusses; u32 var80094eac; struct curmp3 g_SndCurMp3; @@ -105,6 +105,8 @@ s32 var8005dddc = 0; u8 *g_SndGuardStringPtr = NULL; +uintptr_t* g_SeqRomAddrs; + enum audioconfig_e { AUDIOCONFIG_00, AUDIOCONFIG_01, @@ -952,7 +954,7 @@ void sndLoadSfxCtl(void) u8 *buffer; ALBankFile *file; ALBank *bank; - u32 romaddr; + romptr_t romaddr; u32 size; g_ALSoundRomOffsets = NULL; @@ -966,14 +968,14 @@ void sndLoadSfxCtl(void) // then load the first 256 bytes of the bank. file = (ALBankFile *) buffer; romaddr = (romptr_t) REF_SEG _sfxctlSegmentRomStart; - romaddr += (u32)file->bankArray[0]; + romaddr += (uintptr_t)file->bankArray[0]; dmaExec(buffer, romaddr, size); // Get the ROM address of the first (and only) instrument, // then load the first 256 bytes of the instrument. bank = (ALBank *) buffer; romaddr = (romptr_t) REF_SEG _sfxctlSegmentRomStart; - romaddr += (u32)bank->instArray[0]; + romaddr += (uintptr_t)bank->instArray[0]; dmaExec(buffer, romaddr, size); // Get the soundCount (spoiler: there's 1545+1). @@ -984,12 +986,12 @@ void sndLoadSfxCtl(void) // Calculate the size of the ALInstrument and load it. The pointer is then // shifted forward to point to the instrument's ALSound array. This leaks // some memory but this is initialisation code so it's not much of an issue. - size = g_NumSounds * 4 + 20; + size = g_NumSounds * sizeof(uintptr_t) + 20; size = ALIGN16(size); g_ALSoundRomOffsets = alHeapAlloc(&g_SndHeap, 1, size); dmaExec(g_ALSoundRomOffsets, romaddr, size); - *(u32 *)&g_ALSoundRomOffsets += 0x10; + *(uintptr_t *)&g_ALSoundRomOffsets += 0x10; // Convert ctl-local offsets to ROM offsets for (i = 0; i < g_NumSounds; i++) { @@ -1027,11 +1029,11 @@ void sndIncrementAges(void) } #endif -ALEnvelope *sndLoadEnvelope(u32 offset, u16 cacheindex) +ALEnvelope *sndLoadEnvelope(uintptr_t offset, u16 cacheindex) { #if VERSION >= VERSION_NTSC_1_0 - u8 spaf[0x50]; - u8 sp5f[0x50]; + u8 spaf[0x90]; + u8 sp5f[0x90]; ALEnvelope *s2 = (ALEnvelope *)ALIGN16((uintptr_t)spaf); ALEnvelope *s1 = (ALEnvelope *)ALIGN16((uintptr_t)sp5f); s32 i; @@ -1041,14 +1043,14 @@ ALEnvelope *sndLoadEnvelope(u32 offset, u16 cacheindex) offset += (romptr_t) REF_SEG _sfxctlSegmentRomStart; do { - dmaExecHighPriority(s2, offset, 0x40); + dmaExecHighPriority(s2, offset, 16 * sizeof(uintptr_t)); sum1 = 0; for (i = 0; i < 16U; i++) { sum1 += ((u32 *)s2)[i]; } - dmaExecHighPriority(s1, offset, 0x40); + dmaExecHighPriority(s1, offset, 16 * sizeof(uintptr_t)); sum2 = 0; for (i = 0; i < 16U; i++) { @@ -1074,11 +1076,11 @@ ALEnvelope *sndLoadEnvelope(u32 offset, u16 cacheindex) return s1; } -ALKeyMap *sndLoadKeymap(u32 offset, u16 cacheindex) +ALKeyMap *sndLoadKeymap(uintptr_t offset, u16 cacheindex) { #if VERSION >= VERSION_NTSC_1_0 - u8 spaf[0x50]; - u8 sp5f[0x50]; + u8 spaf[0x90]; + u8 sp5f[0x90]; ALKeyMap *s2 = (ALKeyMap *)ALIGN16((uintptr_t)spaf); ALKeyMap *s1 = (ALKeyMap *)ALIGN16((uintptr_t)sp5f); s32 i; @@ -1088,14 +1090,14 @@ ALKeyMap *sndLoadKeymap(u32 offset, u16 cacheindex) offset += (romptr_t) REF_SEG _sfxctlSegmentRomStart; do { - dmaExecHighPriority(s2, offset, 0x40); + dmaExecHighPriority(s2, offset, 16 * sizeof(uintptr_t)); sum1 = 0; for (i = 0; i < 16U; i++) { sum1 += ((u32 *)s2)[i]; } - dmaExecHighPriority(s1, offset, 0x40); + dmaExecHighPriority(s1, offset, 16 * sizeof(uintptr_t)); sum2 = 0; for (i = 0; i < 16U; i++) { @@ -1121,7 +1123,7 @@ ALKeyMap *sndLoadKeymap(u32 offset, u16 cacheindex) return s1; } -ALADPCMBook *sndLoadAdpcmBook(u32 offset, u16 cacheindex) +ALADPCMBook *sndLoadAdpcmBook(uintptr_t offset, u16 cacheindex) { #if VERSION >= VERSION_NTSC_1_0 u8 spaf[0x150]; @@ -1168,11 +1170,11 @@ ALADPCMBook *sndLoadAdpcmBook(u32 offset, u16 cacheindex) return s1; } -ALADPCMloop *sndLoadAdpcmLoop(u32 offset, u16 cacheindex) +ALADPCMloop *sndLoadAdpcmLoop(uintptr_t offset, u16 cacheindex) { #if VERSION >= VERSION_NTSC_1_0 - u8 spaf[0x50]; - u8 sp5f[0x50]; + u8 spaf[0x90]; + u8 sp5f[0x90]; ALADPCMloop *s2 = (ALADPCMloop *)ALIGN16((uintptr_t)spaf); ALADPCMloop *s1 = (ALADPCMloop *)ALIGN16((uintptr_t)sp5f); s32 i; @@ -1186,14 +1188,14 @@ ALADPCMloop *sndLoadAdpcmLoop(u32 offset, u16 cacheindex) offset += (romptr_t) REF_SEG _sfxctlSegmentRomStart; do { - dmaExecHighPriority(s2, offset, 0x40); + dmaExecHighPriority(s2, offset, 16 * sizeof(uintptr_t)); sum1 = 0; for (i = 0; i < 16U; i++) { sum1 += ((u32 *)s2)[i]; } - dmaExecHighPriority(s1, offset, 0x40); + dmaExecHighPriority(s1, offset, 16 * sizeof(uintptr_t)); sum2 = 0; for (i = 0; i < 16U; i++) { @@ -1223,11 +1225,11 @@ ALADPCMloop *sndLoadAdpcmLoop(u32 offset, u16 cacheindex) return s1; } -ALWaveTable *sndLoadWavetable(u32 offset, u16 cacheindex) +ALWaveTable *sndLoadWavetable(uintptr_t offset, u16 cacheindex) { #if VERSION >= VERSION_NTSC_1_0 - u8 spaf[0x50]; - u8 sp5f[0x50]; + u8 spaf[0x90]; + u8 sp5f[0x90]; ALWaveTable *s2 = (ALWaveTable *)ALIGN16((uintptr_t)spaf); ALWaveTable *s1 = (ALWaveTable *)ALIGN16((uintptr_t)sp5f); s32 i; @@ -1238,14 +1240,14 @@ ALWaveTable *sndLoadWavetable(u32 offset, u16 cacheindex) offset += (romptr_t) REF_SEG _sfxctlSegmentRomStart; do { - dmaExecHighPriority(s2, offset, 0x40); + dmaExecHighPriority(s2, offset, 16 * sizeof(uintptr_t)); sum1 = 0; for (i = 0; i < 16U; i++) { sum1 += ((u32 *)s2)[i]; } - dmaExecHighPriority(s1, offset, 0x40); + dmaExecHighPriority(s1, offset, 16 * sizeof(uintptr_t)); sum2 = 0; for (i = 0; i < 16U; i++) { @@ -1448,13 +1450,17 @@ void sndInit(void) #endif #if VERSION >= VERSION_JPN_FINAL - u32 heaplen = 1024 * 441; + u32 heaplen = 1024 * 528; #elif VERSION >= VERSION_PAL_BETA - u32 heaplen = 1024 * 446; + u32 heaplen = 1024 * 533; #elif VERSION >= VERSION_NTSC_1_0 - u32 heaplen = 1024 * 441; + u32 heaplen = 1024 * 528; #else - u32 heaplen = 1024 * 438; + u32 heaplen = 1024 * 525; +#endif + +#ifdef PLATFORM_64BIT + heaplen = 1024 * 745; #endif g_Vars.langfilteron = false; @@ -1522,8 +1528,10 @@ void sndInit(void) dmaExec(g_SeqTable, (romptr_t) REF_SEG _sequencesSegmentRomStart, (len + 0xf) & ~0xf); // Promote segment-relative offsets to ROM addresses + g_SeqRomAddrs = mempAlloc(g_SeqTable->count * sizeof(uintptr_t), MEMPOOL_PERMANENT); + for (i = 0; i < g_SeqTable->count; i++) { - g_SeqTable->entries[i].romaddr += (romptr_t) REF_SEG _sequencesSegmentRomStart; + g_SeqRomAddrs[i] = g_SeqTable->entries[i].romaddr + (romptr_t) REF_SEG _sequencesSegmentRomStart; } synconfig.maxVVoices = 44; @@ -1635,7 +1643,7 @@ bool seqPlay(struct seqinstance *seq, s32 tracknum) return false; } - if (g_SeqTable->entries[seq->tracknum].romaddr < 0x10000) { + if (g_SeqRomAddrs[seq->tracknum] < 0x10000) { return false; } @@ -1684,12 +1692,12 @@ bool seqPlay(struct seqinstance *seq, s32 tracknum) binstart = seq->data; zipstart = binstart + binlen - ziplen; - dmaExec(zipstart, g_SeqTable->entries[seq->tracknum].romaddr, ziplen); + dmaExec(zipstart, g_SeqRomAddrs[seq->tracknum], ziplen); ziplen = rzipInflate(zipstart, binstart, scratch); } #ifndef PLATFORM_N64 - preprocessALCMidiHdr(binstart, ziplen); + preprocessALCMidiHdr(binstart, ziplen, NULL); #endif #if VERSION < VERSION_NTSC_1_0 diff --git a/src/lib/ultra/audio/bnkf.c b/src/lib/ultra/audio/bnkf.c index 3715d4280..0a8b41009 100644 --- a/src/lib/ultra/audio/bnkf.c +++ b/src/lib/ultra/audio/bnkf.c @@ -3,14 +3,14 @@ #include #include "types.h" -void _bnkfPatchBank(ALBank *bank, s32 offset, s32 table); -void _bnkfPatchInst(ALInstrument *inst, s32 offset, s32 table); -void _bnkfPatchSound(ALSound *s, s32 offset, s32 table); -void _bnkfPatchWaveTable(ALWaveTable *w, s32 offset, s32 table); +void _bnkfPatchBank(ALBank *bank, uintptr_t offset, uintptr_t table); +void _bnkfPatchInst(ALInstrument* inst, uintptr_t offset, uintptr_t table); +void _bnkfPatchSound(ALSound* s, uintptr_t offset, uintptr_t table); +void _bnkfPatchWaveTable(ALWaveTable* w, uintptr_t offset, uintptr_t table); void alSeqFileNew(ALSeqFile *file, u8 *base) { - intptr_t offset = (intptr_t) base; + uintptr_t offset = (uintptr_t) base; s32 i; /* @@ -23,8 +23,8 @@ void alSeqFileNew(ALSeqFile *file, u8 *base) void alBnkfNew(ALBankFile *file, u8 *table) { - intptr_t offset = (intptr_t) file; - intptr_t woffset = (intptr_t) table; + uintptr_t offset = (uintptr_t) file; + uintptr_t woffset = (uintptr_t) table; s32 i; @@ -45,7 +45,7 @@ void alBnkfNew(ALBankFile *file, u8 *table) } } -void _bnkfPatchBank(ALBank *bank, s32 offset, s32 table) +void _bnkfPatchBank(ALBank *bank, uintptr_t offset, uintptr_t table) { s32 i; @@ -69,7 +69,7 @@ void _bnkfPatchBank(ALBank *bank, s32 offset, s32 table) } } -void _bnkfPatchInst(ALInstrument *inst, s32 offset, s32 table) +void _bnkfPatchInst(ALInstrument *inst, uintptr_t offset, uintptr_t table) { s32 i; @@ -85,7 +85,7 @@ void _bnkfPatchInst(ALInstrument *inst, s32 offset, s32 table) } } -void _bnkfPatchSound(ALSound *s, s32 offset, s32 table) +void _bnkfPatchSound(ALSound *s, uintptr_t offset, uintptr_t table) { if (s->flags) { return; @@ -100,7 +100,7 @@ void _bnkfPatchSound(ALSound *s, s32 offset, s32 table) _bnkfPatchWaveTable(s->wavetable, offset, table); } -void _bnkfPatchWaveTable(ALWaveTable *w, s32 offset, s32 table) +void _bnkfPatchWaveTable(ALWaveTable *w, uintptr_t offset, uintptr_t table) { if (w->flags) { return; diff --git a/src/lib/ultra/audio/synthInternals.h b/src/lib/ultra/audio/synthInternals.h index 4e9dbd31e..89ab4cf7e 100644 --- a/src/lib/ultra/audio/synthInternals.h +++ b/src/lib/ultra/audio/synthInternals.h @@ -107,6 +107,9 @@ typedef struct ALParam_s { } yetstillmoredata; s32 unk1c; s32 unk20; +#ifdef PLATFORM_64BIT + u8 _pad_[8]; +#endif } ALParam; typedef struct { diff --git a/src/lib/ultra/io/pidma.c b/src/lib/ultra/io/pidma.c index 75d758d1b..1fc7b61d7 100644 --- a/src/lib/ultra/io/pidma.c +++ b/src/lib/ultra/io/pidma.c @@ -1,7 +1,7 @@ #include #include "piint.h" -s32 osPiStartDma(OSIoMesg *mb, s32 priority, s32 direction, u32 devAddr, void *dramAddr, u32 size, OSMesgQueue *mq) +s32 osPiStartDma(OSIoMesg *mb, s32 priority, s32 direction, uintptr_t devAddr, void *dramAddr, u32 size, OSMesgQueue *mq) { register s32 ret; diff --git a/src/lib/vi.c b/src/lib/vi.c index 9ad662b5b..b7668ab1c 100644 --- a/src/lib/vi.c +++ b/src/lib/vi.c @@ -16,6 +16,7 @@ #include "types.h" #ifndef PLATFORM_N64 #include "video.h" +#include "platform.h" #endif #define TO_U16_A(x) ((u16)(x)) @@ -220,7 +221,11 @@ void viReset(s32 stagenum) ptr = mempAlloc(fbsize * sizeof(u16) + 0x40, MEMPOOL_STAGE); +#ifdef PLATFORM_64BIT + ptr = (u8*)(((uintptr_t)ptr + 0x3f) & 0xffffffffffffffc0); +#else ptr = (u8 *)(((uintptr_t) ptr + 0x3f) & 0xffffffc0); +#endif g_FrameBuffers[0] = (u16 *) ptr; g_FrameBuffers[1] = (u16 *) (fbsize + ptr);