Reverted back to master, branch didn't switch :))))))

This commit is contained in:
DorfDork 2020-09-04 12:57:20 -05:00
parent 6fc4bfd573
commit a8c423e217
641 changed files with 55501 additions and 54195 deletions

View file

@ -1,19 +1,18 @@
---
IndentWidth: 4
Language: Cpp
BasedOnStyle: Google
BinPackArguments: false
BinPackParameters: false
IncludeBlocks: Regroup
IncludeCategories:
- Regex: 'pch.h'
Priority: 0
- Regex: '^<'
Priority: 1
- Regex: '^".*/'
Priority: 2
- Regex: '(^((?!/).)*$)'
Priority: 3
SortIncludes: true
AlignAfterOpenBracket: Align
SortIncludes: false
ColumnLimit: 104
PointerAlignment: Right
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
BinPackArguments: true
BinPackParameters: true
SpaceAfterCStyleCast: true
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakBeforeBinaryOperators: NonAssignment
Cpp11BracedListStyle: false
IndentCaseLabels: true
AlignTrailingComments: true
UseTab: Never

17
.gitignore vendored
View file

@ -7,11 +7,16 @@
*.ilk
*.exp
# Patch and wiggle related residdue
*.rej
*.porig
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
@ -40,15 +45,16 @@
# Text editor remnants
*.swp
.vscode/*
.idea/*
# General project-specific ignores
__pycache__/*
doxygen/doxygen/*
build/*
*.dump
*.mio0
*.z64
*.map
*.sav
.assets-local.txt
sm64_save_file.bin
sm64config.txt
@ -72,12 +78,3 @@ sm64config.txt
!/sound/**/*custom*/**/*.aiff
!/assets/**/*custom*.bin
!/assets/**/*custom*/**/*.bin
# Visual Studio.
/.vs/**/*
/x64/**/*
/tst/x64/**/*
/packages/**/*
*.cache
*.log
*.tlog

Binary file not shown.

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros">
<NON_MATCHING>1</NON_MATCHING>
<AVOID_UB>1</AVOID_UB>
</PropertyGroup>
<PropertyGroup />
<ItemDefinitionGroup />
<ItemGroup>
<BuildMacro Include="NON_MATCHING">
<Value>$(NON_MATCHING)</Value>
<EnvironmentVariable>true</EnvironmentVariable>
</BuildMacro>
<BuildMacro Include="AVOID_UB">
<Value>$(AVOID_UB)</Value>
</BuildMacro>
</ItemGroup>
</Project>

900
Makefile

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@
# obtain a list of segments from the *.c files in bin directory
SEGMENTS := $(notdir $(basename $(wildcard bin/*.c))) $(addprefix $(VERSION)/,$(notdir $(basename $(wildcard bin/$(VERSION)/*.c)))) $(addsuffix _skybox,$(notdir $(basename $(wildcard textures/skyboxes/*.png))))
ACTORS := $(filter %/,$(wildcard actors/*/))
TEXTURE_DIRS := $(addprefix textures/,$(SEGMENTS)) $(ACTORS) textures/crash_screen textures/intro_raw textures/ipl3_raw
TEXTURE_DIRS := $(addprefix textures/,$(SEGMENTS)) $(ACTORS) textures/crash_screen textures/intro_raw textures/ipl3_raw textures/skybox_tiles
# NOTE: textures assume naming convention "texture.<encoding>.png" generates "texture.<encoding>"
@ -165,9 +165,9 @@ $(eval $(call level_rules,menu,generic)) # Menu (File Select)
# Ending cake textures are generated in a special way
$(BUILD_DIR)/levels/ending/cake_eu.inc.c: levels/ending/cake_eu.png
$(SKYCONV) --type cake-eu --split $^ $(BUILD_DIR)/levels/ending
$(SKYCONV) $(SKYCONV_ARGS) --type cake-eu --split $^ $(BUILD_DIR)/levels/ending
$(BUILD_DIR)/levels/ending/cake.inc.c: levels/ending/cake.png
$(SKYCONV) --type cake --split $^ $(BUILD_DIR)/levels/ending
$(SKYCONV) $(SKYCONV_ARGS) --type cake --split $^ $(BUILD_DIR)/levels/ending
# --------------------------------------
# Texture Bin Rules
@ -235,7 +235,7 @@ $(BUILD_DIR)/bin/eu/translation_fr.elf: SEGMENT_ADDRESS := 0x19000000
# --------------------------------------
$(BUILD_DIR)/bin/%_skybox.c: textures/skyboxes/%.png
$(SKYCONV) --type sky --split $^ $(BUILD_DIR)/bin
$(SKYCONV) $(SKYCONV_ARGS) --type sky --split $^ $(BUILD_DIR)/bin
$(BUILD_DIR)/bin/%_skybox.elf: SEGMENT_ADDRESS := 0x0A000000

View file

@ -1,90 +1,6 @@
# Super Mario 64 Port
# Render96ex
Fork of [sm64ex](https://github.com/sm64pc/sm64ex)
- This repo contains a full decompilation of Super Mario 64 (J), (U), and (E) with minor exceptions in the audio subsystem.
- Naming and documentation of the source code and data structures are in progress.
- Efforts to decompile the Shindou ROM steadily advance toward a matching build.
- Beyond Nintendo 64, it can also target Linux and Windows natively.
This repo does not include all assets necessary for compiling the game.
A prior copy of the game is required to extract the assets.
## Building native executables
### Linux
1. Install prerequisites (Ubuntu): `sudo apt install -y git build-essential pkg-config libusb-1.0-0-dev libsdl2-dev`.
2. Clone the repo: `git clone https://github.com/sm64-port/sm64-port.git`, which will create a directory `sm64-port` and then **enter** it `cd sm64-port`.
3. Place a Super Mario 64 ROM called `baserom.<VERSION>.z64` into the repository's root directory for asset extraction, where `VERSION` can be `us`, `jp`, or `eu`.
4. Run `make` to build. Qualify the version through `make VERSION=<VERSION>`. Add `-j4` to improve build speed (hardware dependent based on the amount of CPU cores available).
5. The executable binary will be located at `build/<VERSION>_pc/sm64.<VERSION>.f3dex2e`.
### Windows
1. Install and update MSYS2, following all the directions listed on https://www.msys2.org/.
2. From the start menu, launch MSYS2 MinGW and install required packages depending on your machine (do **NOT** launch "MSYS2 MSYS"):
* 64-bit: Launch "MSYS2 MinGW 64-bit" and install: `pacman -S git make python3 mingw-w64-x86_64-gcc`
* 32-bit (will also work on 64-bit machines): Launch "MSYS2 MinGW 32-bit" and install: `pacman -S git make python3 mingw-w64-i686-gcc`
* Do **NOT** by mistake install the package called simply `gcc`.
3. The MSYS2 terminal has a _current working directory_ that initially is `C:\msys64\home\<username>` (home directory). At the prompt, you will see the current working directory in yellow. `~` is an alias for the home directory. You can change the current working directory to `My Documents` by entering `cd /c/Users/<username>/Documents`.
4. Clone the repo: `git clone https://github.com/sm64-port/sm64-port.git`, which will create a directory `sm64-port` and then **enter** it `cd sm64-port`.
5. Place a *Super Mario 64* ROM called `baserom.<VERSION>.z64` into the repository's root directory for asset extraction, where `VERSION` can be `us`, `jp`, or `eu`.
6. Run `make` to build. Qualify the version through `make VERSION=<VERSION>`. Add `-j4` to improve build speed (hardware dependent based on the amount of CPU cores available).
7. The executable binary will be located at `build/<VERSION>_pc/sm64.<VERSION>.f3dex2e.exe` inside the repository.
#### Troubleshooting
1. If you get `make: gcc: command not found` or `make: gcc: No such file or directory` although the packages did successfully install, you probably launched the wrong MSYS2. Read the instructions again. The terminal prompt should contain "MINGW32" or "MINGW64" in purple text, and **NOT** "MSYS".
2. If you get `Failed to open baserom.us.z64!` you failed to place the baserom in the repository. You can write `ls` to list the files in the current working directory. If you are in the `sm64-port` directory, make sure you see it here.
3. If you get `make: *** No targets specified and no makefile found. Stop.`, you are not in the correct directory. Make sure the yellow text in the terminal ends with `sm64-port`. Use `cd <dir>` to enter the correct directory. If you write `ls` you should see all the project files, including `Makefile` if everything is correct.
4. If you get any error, be sure MSYS2 packages are up to date by executing `pacman -Syu` and `pacman -Su`. If the MSYS2 window closes immediately after opening it, restart your computer.
5. When you execute `gcc -v`, be sure you see `Target: i686-w64-mingw32` or `Target: x86_64-w64-mingw32`. If you see `Target: x86_64-pc-msys`, you either opened the wrong MSYS start menu entry or installed the incorrect gcc package.
### Debugging
The code can be debugged using `gdb`. On Linux install the `gdb` package and execute `gdb <executable>`. On MSYS2 install by executing `pacman -S winpty gdb` and execute `winpty gdb <executable>`. The `winpty` program makes sure the keyboard works correctly in the terminal. Also consider changing the `-mwindows` compile flag to `-mconsole` to be able to see stdout/stderr as well as be able to press Ctrl+C to interrupt the program. In the Makefile, make sure you compile the sources using `-g` rather than `-O2` to include debugging symbols. See any online tutorial for how to use gdb.
## ROM building
It is possible to build N64 ROMs as well with this repository. See https://github.com/n64decomp/sm64 for instructions.
## Project Structure
```
sm64
├── actors: object behaviors, geo layout, and display lists
├── asm: handwritten assembly code, rom header
│ └── non_matchings: asm for non-matching sections
├── assets: animation and demo data
│ ├── anims: animation data
│ └── demos: demo data
├── bin: C files for ordering display lists and textures
├── build: output directory
├── data: behavior scripts, misc. data
├── doxygen: documentation infrastructure
├── enhancements: example source modifications
├── include: header files
├── levels: level scripts, geo layout, and display lists
├── lib: SDK library code
├── rsp: audio and Fast3D RSP assembly code
├── sound: sequences, sound samples, and sound banks
├── src: C source code for game
│ ├── audio: audio code
│ ├── buffers: stacks, heaps, and task buffers
│ ├── engine: script processing engines and utils
│ ├── game: behaviors and rest of game source
│ ├── goddard: Mario intro screen
│ ├── menu: title screen and file, act, and debug level selection menus
│ └── pc: port code, audio and video renderer
├── text: dialog, level names, act names
├── textures: skybox and generic texture data
└── tools: build tools
```
## Contributing
Pull requests are welcome. For major changes, please open an issue first to
discuss what you would like to change.
Run `clang-format` on your code to ensure it meets the project's coding standards.
Official Discord: https://discord.gg/7bcNTPK
This is meant to be a fork where the team can upload their code.
If you want to help sm64ex then go to their repo.
If you want to help us out then message me on discord DorfDork#4516

205
README_es_ES.md Normal file
View file

@ -0,0 +1,205 @@
# sm64pc
Adaptación a OpenGL de [n64decomp/sm64](https://github.com/n64decomp/sm64).
No dudes en contribuir o reportar bugs, pero recuerda: **no se debe subir nada con copyright**.
Ejecuta `./extract_assets.py --clean && make clean` o `make distclean` para borrar todo el contenido proveniente de la ROM. Este port es posible gracias a [n64-fast32-engine](https://github.com/Emill/n64-fast3d-engine/) creado por [Emill](https://github.com/Emill).
## Funcionalidades
* Renderizado nativo. Podrás jugar a Super Mario 64 sin necesidad de un emulador.
* Resolución y relación de aspecto variables. Puedes jugar a Super Mario 64 a básicamente cualquier resolución o tamaño de ventana.
* Soporte nativo para mandos XInput. En Linux, se ha confirmado que el DualShock 4 funciona sin más.
* Cámara analógica y cámara controlada con el ratón. (Se activa con `make BETTERCAMERA=1`.)
* Opción para desactivar el límite de distancia de renderizado. (Se activa con `make NODRAWINGDISTANCE=1`.)
* Configurar los controles desde el juego.
* Posibilidad de saltarte la intro con la opción de línea de comandos `--skip-intro`
* Menú de trucos (_cheats_) en _options_. (Se activa con la opción de línea de comandos `--cheats`) Ten en cuenta que si un cheat te pide pulsar el botón "L", se refiere al botón de N64, el cual tendrá que estar asignado a un botón de tu mando. Ve a los ajustes de control y asegúrate de que tienes "L" mapeado a un botón de tu mando.
## Compilar en Windows
**No intentes compilar ejecutables para Windows bajo Linux usando `WINDOWS_BUILD=1`. No va a funcionar. Sigue la guía.**
#### 1. Instalación y configuración de MSYS2.
1. Descarga [msys2-x86_64-latest.exe](http://repo.msys2.org/distrib/msys2-x86_64-latest.exe) y ejecútalo. Si tu sistema operativo es de 32 bits (¿por qué?) descarga [msys2-i686-latest.exe](http://repo.msys2.org/distrib/msys2-i686-latest.exe) en su lugar. Asegúrate de que lo instalas en `C:\dev\msys64` (o `C:\dev\msys32` para 32 bits...). Ejecuta MSYS2.
2. En la ventana de comandos de MSYS2, ejecuta el siguiente comando:
```
pacman -Syuu
```
3. Abre "MSYS2 MinGW 64-Bit". Ejecuta este comando __repetidamente__ hasta que MSYS diga que ya no hay más actualizaciones. Es posible que tengas que volver a cerrar y abrir MSYS2.
```
pacman -Syuu
```
5. Ejecuta este comando y cuando te pida confirmación pulsa intro:
```
pacman -S --needed base-devel mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain \
git subversion mercurial \
mingw-w64-i686-cmake mingw-w64-x86_64-cmake
```
6. Listo.
#### Instala las dependencias
```
pacman -S mingw-w64-i686-glew mingw-w64-x86_64-glew mingw-w64-i686-SDL2 mingw-w64-x86_64-SDL2 python3
```
### Crea el directorio en el que preparar todo
Desde el explorador de Windows, navega a `C:\msys64\home\(nombre de usuario)\` y crea una carpeta con el nombre que te apetezca. Aquí es donde vamos a preparar todo.
### Clona el repositorio
En MSYS2, introduce el siguiente comando:
```
git clone https://github.com/sm64pc/sm64pc/
```
(Si no funciona, prueba a escribirlo manualmente, en lugar de copiar y pegar)
#### Copia la ROM base al directorio correspondiente
El paso anterior tiene que haber creado una carpeta llamada sm64pc. Dentro de esa carpeta, y para cada version de la ROM (jp/us/eu) de la cual quieras compilar un ejecutable, coloca la ROM con el nombre `baserom.<version>.z64` para extraer sus assets. Por ejemplo, `baserom.us.z64` para la versión americana, o `baserom.eu.z64` para la versión europea.
#### En MSYS2, vamos a navegar a la carpeta `./tools/audiofile-0.3.6/` y ejecutar el `autoreconf-i`. Introduce los siguientes comandos, en orden, uno a uno:
```
cd sm64pc/tools/audiofile-0.3.6/
autoreconf -i
```
No te vayas de este directorio hasta el paso 9.
#### Ejecuta el script `configure`
```
PATH=/mingw64/bin:/mingw32/bin:$PATH LIBS=-lstdc++ ./configure --disable-docs
```
#### Ejecuta el script `make`
```
PATH=/mingw64/bin:/mingw32/bin:$PATH make
```
#### Crea un directorio `lib` en `tools/`
```
mkdir ../lib
```
#### Acabas de compilar `libaudiofile`. Ahora cópialo a `tools/lib/`
```
cp libaudiofile/.libs/libaudiofile.a ../lib/
cp libaudiofile/.libs/libaudiofile.la ../lib/
```
#### Ahora toca hacer algo desde Windows.
En el explorador de Windows, ve a sm64pc\tools y edita el archivo Makefile desde un editor de texto (es recomendable usar un editor decente como Notepad++ o Sublime Text, en lugar del bloc de notas, para asegurarte de que no rompes el formato del texto) Busca la línea que contiene esto:
```tabledesign_CFLAGS := -Wno-uninitialized -laudiofile```
Y añade ` -lstdc++` al final, de manera que quede así (¡no olvides el espacio!)
```tabledesign_CFLAGS := -Wno-uninitialized -laudiofile -lstdc++```
Guarda el archivo.
#### Vuelve a la carpeta tools y ejecuta `make` con los siguientes comandos.
```
cd ..
PATH=/mingw64/bin:/mingw32/bin:$PATH make
```
#### Vuelve al directorio sm64pc
```
cd ..
```
#### Finalmente, ejecuta ```make``` de nuevo.
(Ten en cuenta que mingw32 y mingw64 han sido intercambiados. Esto es para que puedas compilar la versión de 32 bits si quieres.)
Aquí pones las opciones que quieras según la versión que quieras compilar. Por ejemplo, si quieres activar la cámara analógica, añade al final BETTERCAMERA=1. Si quieres la opción de distancia de renderizado ilimitada, añade NODRAWINGDISTANCE=1.
Por ejemplo:
```
PATH=/mingw32/bin:/mingw64/bin:$PATH make BETTERCAMERA=1 NODRAWINGDISTANCE=1
```
Listo. El .exe estará en sm64pc\build\. Disfruta.
## Compilar en Linux
### Nota para usuarios de Windows
No intentes compilar un ejecutable para Windows desde Linux o WSL. No funciona. Sigue la guía para Windows.
#### Copia la(s) ROM(s) base para la extracción de assets.
Por cada versión de la cual quieras compilar un ejecutable, copia la ROM en `./baserom.<versión>.z64` para extraer los assets.
#### Instala las dependencias.
Para compilar necesitas las sigueintes dependencias.
* python3 >= 3.6
* libsdl2-dev
* [audiofile](https://audiofile.68k.org/)
* libglew-dev
* git
Puedes instalarlas con este comando:
##### Debian / Ubuntu - (compilando para 32 bits)
```
sudo apt install build-essential git python3 libaudiofile-dev libglew-dev:i386 libsdl2-dev:i386
```
##### Debian / Ubuntu - (compilando para 64 bits)
```
sudo apt install build-essential git python3 libaudiofile-dev libglew-dev libsdl2-dev
```
##### Arch Linux
Hay un paquete AUR (cortesía de @narukeh) disponible bajo el nombre [sm64pc-git](https://aur.archlinux.org/packages/sm64pc-git/). Instálalo con tu gestor de AURs preferido.
Si quieres compilarlo por tu cuenta:
```
sudo pacman -S base-devel python audiofile sdl2 glew
```
##### Void Linux - (compilando para 64 bits)
```
sudo xbps-install -S base-devel python3 audiofile-devel SDL2-devel glew-devel
```
##### Void Linux - (compilando para 32 bits)
```
sudo xbps-install -S base-devel python3 audiofile-devel-32bit SDL2-devel-32bit glew-devel-32bit
```
#### Compila el ejecutable.
Ejecuta `make` para compilar (por defecto `VERSION=us`)
```
make VERSION=jp -j6 # Compila la versión (J) usando 6 hilos
make VERSION=us MARCH=i686 TARGET_BITS=32 # Compila un ejecutable de la versión (U) de 32 bits
make TARGET_RPI=1 # Compila un ejecutable para Raspberry Pi
```
## Compilar para la web
Puedes compilar el juego para navegadores que admitan WebGL usando [Emscripten](https://github.com/emscripten-core). Para hacerlo, instala [emsdk](https://github.com/emscripten-core/emsdk) y ejecuta `make TARGET_WEB=1`.
## Script para compilar para Raspberry Pi
[Hyenadae](https://github.com/Hyenadae/) ha creado un script que ayuda a compilar el juego para Raspberry Pi. Estos son los pasos que hace el script:
* Instala las dependencias;
* Cambia VC4_DRM en la RPi de 0 a 3;
* Cambia ajustes en la memoria de las RPis 0 y 1 para que se pueda completar la compilación;
* Permite la instalación de un SDL2 con KMS, lo que elimina la necesidad de usar X11 y garantiza el máximo rendimiento de cualquier RPi que ejecute VC4;
* Clona sm64pc si no encuentra los archivos necesarios;
* Comprueba si existen los assets y la ROM base necesaria (baserom.*.z64);
* Compila sm64pc.
El script está incluído en la rama master, pero también puede descargarse [aquí](https://raw.githubusercontent.com/sm64pc/sm64pc/master/pisetup.sh).
# Problemas conocidos
### Problemas ya conocidos:
* La versión EU tiene bugs en los textos y no tiene audio.
* El movimiento analógico horizontal de la cámara vuelve al estilo antiguo en el nivel Bowser in the Dark World (#72)
* La cámara con el ratón falla cuando disparas a Mario hacia un árbol o un tubo. (#71)
* "make: Nothing to be done for 'default'" al compilar para web. (#67)
### Estos problemas están marcados como solucionados. Por favor, contacta si sigues teniendo estos problemas.
* El juego se llena de flags aleatorias en las builds de 64 bits para Windows
* Hazy Maze Cave se cuelga en pantalla completa (#57)
* La pantalla de título no tiene el cursor para manipular a Mario en pantalla completa. (#28)
## Parches
En la carpeta `./enhancements` hay varios archivos `patch`, que pueden aplicarse de la siguiente manera:
```
git apply fps.patch --ignore-whitespace --reject
```
Si ocurre un rechazo, puedes buscarlo con el comando `find | grep .rej`.
Intenta resolver los rechazos a través de [wiggle](https://github.com/neilbrown/wiggle).
```
wiggle rejection.rej --replace
```

33
README_pt_BR.md Normal file
View file

@ -0,0 +1,33 @@
# sm64pc
Adaptação em OpenGL de [n64decomp/sm64](https://github.com/n64decomp/sm64).
Sinta-se livre para reportar bugs [aqui](https://github.com/sm64pc/sm64pc/issues) e contribuir, mas tenha em mente que não
aceitamos compartilhamento de conteúdo protegido com direitos autorais.
Se necessário, rode `./extract_assets.py --clean && make clean` ou `make distclean` para remover conteúdos advindos da ROM do jogo.
Este port é possível graças à [Emill](https://github.com/Emill), [n64-fast32-engine](https://github.com/Emill/n64-fast3d-engine/), e, é claro, ao
time do [n64decomp](https://github.com/n64decomp).
Em caso de contribuições, crie _pull requests_ apenas para a [branch nightly](https://github.com/sm64pc/sm64pc/tree/nightly/).
Novas funcionalidades serão adicionadas à branch master quando forem consideradas bem testadas.
*Leia isso em outras linguas: [English](README.md) [简体中文](README_zh_CN.md).*
## Recursos
* Renderização nativa. Você agora pode jogar SM64 no PC sem precisar de emulador.
* Proporção de tela e resolução variáveis. O jogo renderiza corretamente em basicamente qualquer tamanho de janela.
* Suporte a entradas de controle através de `xinput`. Tal como usando DualShock 4 em distribuições Linux.
* Controle de câmera com analógico ou mouse. (Ative com `make BETTERCAMERA=1`.)
* Uma opção para desativar distância de renderização. (Ative com `make NODRAWINGDISTANCE=1`.)
* Remapeamento de controles _in-game_.
* Pule as cenas introdutórias da Peach e Lakitu com usando a opção `--skip-intro` ao executar o jogo na linha de comando.
* Menu de cheats nas opções. (Ative com `--cheats`)
** Note que se algum cheat pedir pelo botão "L", o botão em questão é o "L" do N64. Certifique-se de que este está mapeado, caso necessário.
## Compilação
Para instruções de compilaçao, consulte a [wiki](https://github.com/sm64pc/sm64pc/wiki).
## Para usuários de Windows
**Certifique-se de que você tem o [MXE](mxe.cc) antes de tentar compilar em Windows. Siga o guia na Wiki.**

21
README_zh_CN.md Normal file
View file

@ -0,0 +1,21 @@
# sm64pc
本项目是 [n64decomp/sm64](https://github.com/n64decomp/sm64) 的 OpenGL 移植版本。
我们欢迎贡献代码与 bug 报告,但请切记,**不得上传任何被版权保护(来自 ROM 文件)的资源**。
提交前请运行 `./extract_assets.py --clean && make clean``make distclean` 来清除所有从 ROM 文件中提取的内容。
本移植是基于 [Emill](https://github.com/Emill) 的工作 [n64-fast32-engine](https://github.com/Emill/n64-fast3d-engine/) 才得以实现的。
## 主要功能
* 原生渲染。现在不用任何模拟器就可以运行 马力欧64 了。
* 长宽比和分辨率可以自由改变。本游戏目前可以在几乎任何窗口尺寸下正确渲染。
* 原生 xinput 手柄支持。在 Linux 下,已经确认 PS4 手柄可以即插即用。
* 支持模拟量视点控制、鼠标控制视点。(请使用 `make BETTERCAMERA=1` 编译)
* 可取消可视距离限制。(请使用 `make NODRAWINGDISTANCE=1` 编译)
* 游戏内操作设定功能,目前在 `testing` 分支下可用。
* 使用 `--skip-intro` 命令行选项跳过碧奇公主与 Lakitu 的片头剧情。目前在 `testing``skip-intro` 分支下可用。
## 编译方法
关于如何编译,请参考 [wiki](https://github.com/sm64pc/sm64pc/wiki)。
**请勿在 Linux 或者 WSL 下使用 `WINDOWS_BUILD=1` 参数尝试编译 Windows 版本,这样无法编译成功。请参考 Wiki。

158
SAVE_FORMAT.MD Normal file
View file

@ -0,0 +1,158 @@
# Text-based savefile format
This small document describes a new, TOML-like text format for game saves. This format allows the user to use a simple text editor to change the data necessary for the game (for example, special saves for speedrun training).
All data is stored in pairs (*key = value*). Pairs can be placed arbitrarily within a single section. The format of values may differ for each section.
Each savefile (4 total) must be named `save_file_X.sav`, where X - save slot (0, 1, 2 or 3).
> **Note**: The game creates the savefile only when you are saved in the game after completing a course!
___
## Header
The header is automatically generated by the game when saving progress. It mainly contains information about the value of the 0 and 1 flags, the character that the comment starts with, and the time when the file content changed.
Example:
```
# Super Mario 64 save file
# Comment starts with #
# True = 1, False = 0
# 2020-05-18 17:37:07
```
___
## Commenting
All comment lines starts with `#` character. Comments can be located on a separate line or as part of another line. When the game reads the save, comments are ignored.
Example:
```
# This is a comment
coin_score_age = ?? # This is a comment too!
```
___
## Menu Section - [menu]
This section contains two flags for menu.
| Flag | Value | Description |
|---|---|---|
| coin_score_age | 0, 1, 2, 3 | Each save file has a 2 bit "age" for each course. The higher this value, the older the high score is. This is used for tie-breaking when displaying on the high score screen
| sound_mode | stereo, mono, headset | Sound mode for the game
Example:
```
[menu]
coin_score_age = 0
sound_mode = stereo
```
___
## Flags Section - [flags]
This section contains all main game flags (walkthought milestones).
> **Note**: The value can be only 0 (False) or 1 (True).
| Flag | Description |
|---|---|
| wing_cap | **Red Switch** is pressed
| metal_cap | **Green Switch** is pressed
| vanish_cap | **Blue Switch** is pressed.
| key_1 | Key is found in **Bowser in the Dark World**
| key_2 | Key is found in **Bowser in the Fire Sea**
| basement_door | Mario unlocked castle's basement door
| upstairs_door | Mario unlocked castle's upper floors
| ddd_moved_back | **Dire Dire Docks** painting is moved back
| moat_drained | Water is drained in the moat of the castle
| pps_door | **Princess's Secret Slide** window is unlocked
| wf_door | **Whomp's Fortress door** is unlocked
| ccm_door | **Cool, Cool Mountain door** is unlocked
| jrb_door | **Jolly Roger Bay door** is unlocked
| bitdw_door | **Bowser in the Dark World door** door is unlocked
| bitfs_door | **Bowser in the Fire Sea** door is unlocked
| 50star_door | **Endless Staircase** is not endless anymore
Example:
```
[flags]
wing_cap = 1
metal_cap = 1
vanish_cap = 0
key_1 = 1
key_2 = 1
```
___
## Main Courses Section - [courses]
This section contains all stars and coins that Mario collected in each main course.
The first value stores the number of coins collected.
> **Warning!**: Make sure that coins count will not exceed 255!
The second value stores the stars (or completed missions). Each mission (6 main + 1 bonus) is must be marked `0` (not completed) and `1` (completed).
> **Warning!**: The sequence of stars' missions goes from **RIGHT** to **LEFT**!
> **Note**: Last star flag is **100 coins star**
| Flag | Short for |
|---|---|
| bob | Bob-omb Battlefield |
| wf | Whomp's Fortress
| jrb | Jolly Roger Bay
| ccm | Cool, Cool Mountain
| bbh | Big Boo's Haunt
| hmc | Hazy Maze Cave
| lll | Lethal Lava Land
| ssl | Shifting Sand Land
| ddd | Dire, Dire Docks
| sl | Snowman's Land
| wdw | Wet-Dry World
| ttm | Tall, Tall Mountain
| thi | Tiny-Huge Island
| ttc | Tick Tock Clock
| rr | Rainbow Ride
Example:
```
[courses]
bob = "3, 0000011"
wf = "3, 0000101"
jrb = "0, 1000000"
ccm = "1, 1111111"
```
___
## Bonus Section - [bonus]
This section contains all bonus stars that Mario collected in the castle and all bonus courses.
> **Note**: The game takes into account only the number of bonus stars collected, the order of stars flags can be arbitrary
| Flag | Stars | Description |
|---|---|---|
| hub | 5 | MIPS' stars and Toads' stars
| bitdw | 1 | Bowser in the Dark World
| bitfs | 1 | Bowser in the Fire Sea
| bits | 1 | Bowser in the Sky
| pss | 2 | The Princess's Secret Slide
| cotmc | 1 | Cavern of the Metal Cap
| totwc | 1 | Tower of the Wing Cap
| vcutm | 1 | Vanish Cap Under the Moat
| wmotr | 1 | Wing Mario Over the Rainbow
| sa | 1 | The Secret Aquarium
Example:
```
[bonus]
hub = 11101
bitdw = 1
bitfs = 0
bits = 1
pss = 10
```
___
## Cap Section - [cap]
This section contains information about where Mario lost his cap and who take it.
| Flag | Value | Description |
|---|---|---|
| type | ground, klepto, ukiki, mrblizzard | The one who or what took the cap from Mario. Default flag is **"ground"**
| level | ssl, sl, ttm, none | Specifies the course where the cap is located. Default flag is **"none"**.
| area | 1, 2 | Specifies the area in the course.
Example:
```
[cap]
type = ground
level = ssl
area = 1
```

View file

@ -1,5 +1,3 @@
#include "actors/common0.h"
// Amp
// 0x08000F18

View file

@ -1,5 +1,3 @@
#include "actors/group10.h"
// Birds
// 0x05000000

View file

@ -1,5 +1,3 @@
#include "actors/common0.h"
// Blue Coin Switch
// 0x08000E98 - 0x08000F10

View file

@ -1,5 +1,3 @@
#include "actors/common0.h"
// Blue Coin Switch
// 0x08000000

View file

@ -1,5 +1,3 @@
#include "actors/group9.h"
// Boo
// 0x05009B28

View file

@ -1,5 +1,3 @@
#include "actors/group9.h"
// Bookend
// Unreferenced light group

View file

@ -1,5 +1,3 @@
#include "actors/group12.h"
// Bowser (King Koopa)
// 0x0601F438

View file

@ -1,5 +1,3 @@
#include "actors/group12.h"
// Bowser Flame
// TODO: Are these seperate textures or unified 64x64 ones?
@ -80,10 +78,10 @@ static const Vtx flame_seg6_vertex_0601C000[] = {
{{{ 150, 150, 0}, 0, { 2016, 992}, {0xff, 0xff, 0xff, 0xff}}},
{{{ 150, 300, 0}, 0, { 2016, 0}, {0xff, 0xff, 0xff, 0xff}}},
{{{ -150, 300, 0}, 0, { 0, 0}, {0xff, 0xff, 0xff, 0xff}}},
{{{ -150, 0, 0}, 0, { 0, 992}, {0xff, 0xff, 0xff, 0xff}}},
{{{ 150, 0, 0}, 0, { 2016, 992}, {0xff, 0xff, 0xff, 0xff}}},
{{{ 150, 150, 0}, 0, { 2016, 0}, {0xff, 0xff, 0xff, 0xff}}},
{{{ -150, 150, 0}, 0, { 0, 0}, {0xff, 0xff, 0xff, 0xff}}},
{{{ -150, 0, 0}, 0, { 0, 2016}, {0xff, 0xff, 0xff, 0xff}}},
{{{ 150, 0, 0}, 0, { 2016, 2016}, {0xff, 0xff, 0xff, 0xff}}},
{{{ 150, 150, 0}, 0, { 2016, 992}, {0xff, 0xff, 0xff, 0xff}}},
{{{ -150, 150, 0}, 0, { 0, 992}, {0xff, 0xff, 0xff, 0xff}}},
};
// 0x0601C080 - 0x0601C0B0
@ -119,10 +117,9 @@ const Gfx flame_seg6_dl_0601C0E0[] = {
// 0x0601C108 - 0x0601C1A8
const Gfx flame_seg6_dl_0601C108[] = {
gsSPDisplayList(flame_seg6_dl_0601C080),
gsDPLoadTextureBlock(flame_seg6_texture_06000000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(flame_seg6_texture_06000000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(flame_seg6_vertex_0601C000, 8, 0),
gsSPDisplayList(flame_seg6_dl_0601C0B0),
gsDPLoadTextureBlock(flame_seg6_texture_06000000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(flame_seg6_dl_0601C0C8),
gsSPDisplayList(flame_seg6_dl_0601C0E0),
gsSPEndDisplayList(),
@ -131,10 +128,9 @@ const Gfx flame_seg6_dl_0601C108[] = {
// 0x0601C1A8 - 0x0601C248
const Gfx flame_seg6_dl_0601C1A8[] = {
gsSPDisplayList(flame_seg6_dl_0601C080),
gsDPLoadTextureBlock(flame_seg6_texture_06002000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(flame_seg6_texture_06002000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(flame_seg6_vertex_0601C000, 8, 0),
gsSPDisplayList(flame_seg6_dl_0601C0B0),
gsDPLoadTextureBlock(flame_seg6_texture_06002000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(flame_seg6_dl_0601C0C8),
gsSPDisplayList(flame_seg6_dl_0601C0E0),
gsSPEndDisplayList(),
@ -143,10 +139,9 @@ const Gfx flame_seg6_dl_0601C1A8[] = {
// 0x0601C248 - 0x0601C2E8
const Gfx flame_seg6_dl_0601C248[] = {
gsSPDisplayList(flame_seg6_dl_0601C080),
gsDPLoadTextureBlock(flame_seg6_texture_06004000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(flame_seg6_texture_06004000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(flame_seg6_vertex_0601C000, 8, 0),
gsSPDisplayList(flame_seg6_dl_0601C0B0),
gsDPLoadTextureBlock(flame_seg6_texture_06004000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(flame_seg6_dl_0601C0C8),
gsSPDisplayList(flame_seg6_dl_0601C0E0),
gsSPEndDisplayList(),
@ -155,10 +150,9 @@ const Gfx flame_seg6_dl_0601C248[] = {
// 0x0601C2E8 - 0x0601C388
const Gfx flame_seg6_dl_0601C2E8[] = {
gsSPDisplayList(flame_seg6_dl_0601C080),
gsDPLoadTextureBlock(flame_seg6_texture_06006000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(flame_seg6_texture_06006000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(flame_seg6_vertex_0601C000, 8, 0),
gsSPDisplayList(flame_seg6_dl_0601C0B0),
gsDPLoadTextureBlock(flame_seg6_texture_06006000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(flame_seg6_dl_0601C0C8),
gsSPDisplayList(flame_seg6_dl_0601C0E0),
gsSPEndDisplayList(),
@ -167,10 +161,9 @@ const Gfx flame_seg6_dl_0601C2E8[] = {
// 0x0601C388 - 0x0601C428
const Gfx flame_seg6_dl_0601C388[] = {
gsSPDisplayList(flame_seg6_dl_0601C080),
gsDPLoadTextureBlock(flame_seg6_texture_06008000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(flame_seg6_texture_06008000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(flame_seg6_vertex_0601C000, 8, 0),
gsSPDisplayList(flame_seg6_dl_0601C0B0),
gsDPLoadTextureBlock(flame_seg6_texture_06008000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(flame_seg6_dl_0601C0C8),
gsSPDisplayList(flame_seg6_dl_0601C0E0),
gsSPEndDisplayList(),
@ -179,10 +172,9 @@ const Gfx flame_seg6_dl_0601C388[] = {
// 0x0601C428 - 0x0601C4C8
const Gfx flame_seg6_dl_0601C428[] = {
gsSPDisplayList(flame_seg6_dl_0601C080),
gsDPLoadTextureBlock(flame_seg6_texture_0600A000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(flame_seg6_texture_0600A000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(flame_seg6_vertex_0601C000, 8, 0),
gsSPDisplayList(flame_seg6_dl_0601C0B0),
gsDPLoadTextureBlock(flame_seg6_texture_0600A000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(flame_seg6_dl_0601C0C8),
gsSPDisplayList(flame_seg6_dl_0601C0E0),
gsSPEndDisplayList(),
@ -191,10 +183,8 @@ const Gfx flame_seg6_dl_0601C428[] = {
// 0x0601C4C8 - 0x0601C568
const Gfx flame_seg6_dl_0601C4C8[] = {
gsSPDisplayList(flame_seg6_dl_0601C080),
gsDPLoadTextureBlock(flame_seg6_texture_0600C000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(flame_seg6_texture_0600C000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(flame_seg6_vertex_0601C000, 8, 0),
gsSPDisplayList(flame_seg6_dl_0601C0B0),
gsDPLoadTextureBlock(flame_seg6_texture_0600C000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(flame_seg6_dl_0601C0C8),
gsSPDisplayList(flame_seg6_dl_0601C0E0),
gsSPEndDisplayList(),
@ -203,10 +193,9 @@ const Gfx flame_seg6_dl_0601C4C8[] = {
// 0x0601C568 - 0x0601C608
const Gfx flame_seg6_dl_0601C568[] = {
gsSPDisplayList(flame_seg6_dl_0601C080),
gsDPLoadTextureBlock(flame_seg6_texture_0600E000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(flame_seg6_texture_0600E000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(flame_seg6_vertex_0601C000, 8, 0),
gsSPDisplayList(flame_seg6_dl_0601C0B0),
gsDPLoadTextureBlock(flame_seg6_texture_0600E000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(flame_seg6_dl_0601C0C8),
gsSPDisplayList(flame_seg6_dl_0601C0E0),
gsSPEndDisplayList(),
@ -215,10 +204,9 @@ const Gfx flame_seg6_dl_0601C568[] = {
// 0x0601C608 - 0x0601C6A8
const Gfx flame_seg6_dl_0601C608[] = {
gsSPDisplayList(flame_seg6_dl_0601C080),
gsDPLoadTextureBlock(flame_seg6_texture_06010000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(flame_seg6_texture_06010000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(flame_seg6_vertex_0601C000, 8, 0),
gsSPDisplayList(flame_seg6_dl_0601C0B0),
gsDPLoadTextureBlock(flame_seg6_texture_06010000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(flame_seg6_dl_0601C0C8),
gsSPDisplayList(flame_seg6_dl_0601C0E0),
gsSPEndDisplayList(),
@ -227,10 +215,9 @@ const Gfx flame_seg6_dl_0601C608[] = {
// 0x0601C6A8 - 0x0601C748
const Gfx flame_seg6_dl_0601C6A8[] = {
gsSPDisplayList(flame_seg6_dl_0601C080),
gsDPLoadTextureBlock(flame_seg6_texture_06012000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(flame_seg6_texture_06012000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(flame_seg6_vertex_0601C000, 8, 0),
gsSPDisplayList(flame_seg6_dl_0601C0B0),
gsDPLoadTextureBlock(flame_seg6_texture_06012000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(flame_seg6_dl_0601C0C8),
gsSPDisplayList(flame_seg6_dl_0601C0E0),
gsSPEndDisplayList(),
@ -239,10 +226,9 @@ const Gfx flame_seg6_dl_0601C6A8[] = {
// 0x0601C748 - 0x0601C7E8
const Gfx flame_seg6_dl_0601C748[] = {
gsSPDisplayList(flame_seg6_dl_0601C080),
gsDPLoadTextureBlock(flame_seg6_texture_06014000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(flame_seg6_texture_06014000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(flame_seg6_vertex_0601C000, 8, 0),
gsSPDisplayList(flame_seg6_dl_0601C0B0),
gsDPLoadTextureBlock(flame_seg6_texture_06014000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(flame_seg6_dl_0601C0C8),
gsSPDisplayList(flame_seg6_dl_0601C0E0),
gsSPEndDisplayList(),
@ -251,10 +237,9 @@ const Gfx flame_seg6_dl_0601C748[] = {
// 0x0601C7E8 - 0x0601C888
const Gfx flame_seg6_dl_0601C7E8[] = {
gsSPDisplayList(flame_seg6_dl_0601C080),
gsDPLoadTextureBlock(flame_seg6_texture_06016000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(flame_seg6_texture_06016000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(flame_seg6_vertex_0601C000, 8, 0),
gsSPDisplayList(flame_seg6_dl_0601C0B0),
gsDPLoadTextureBlock(flame_seg6_texture_06016000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(flame_seg6_dl_0601C0C8),
gsSPDisplayList(flame_seg6_dl_0601C0E0),
gsSPEndDisplayList(),
@ -263,10 +248,9 @@ const Gfx flame_seg6_dl_0601C7E8[] = {
// 0x0601C888 - 0x0601C928
const Gfx flame_seg6_dl_0601C888[] = {
gsSPDisplayList(flame_seg6_dl_0601C080),
gsDPLoadTextureBlock(flame_seg6_texture_06018000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(flame_seg6_texture_06018000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(flame_seg6_vertex_0601C000, 8, 0),
gsSPDisplayList(flame_seg6_dl_0601C0B0),
gsDPLoadTextureBlock(flame_seg6_texture_06018000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(flame_seg6_dl_0601C0C8),
gsSPDisplayList(flame_seg6_dl_0601C0E0),
gsSPEndDisplayList(),
@ -275,10 +259,9 @@ const Gfx flame_seg6_dl_0601C888[] = {
// 0x0601C928 - 0x0601C9C8
const Gfx flame_seg6_dl_0601C928[] = {
gsSPDisplayList(flame_seg6_dl_0601C080),
gsDPLoadTextureBlock(flame_seg6_texture_0601A000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(flame_seg6_texture_0601A000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(flame_seg6_vertex_0601C000, 8, 0),
gsSPDisplayList(flame_seg6_dl_0601C0B0),
gsDPLoadTextureBlock(flame_seg6_texture_0601A000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(flame_seg6_dl_0601C0C8),
gsSPDisplayList(flame_seg6_dl_0601C0E0),
gsSPEndDisplayList(),

View file

@ -1,5 +1,3 @@
#include "actors/common1.h"
// Bowser Key
// 0x030156E0, ambient color brown - light color orange

View file

@ -1,5 +1,3 @@
#include "actors/group11.h"
// Possible Removed Actor File
// It's possible that bubba and bub used to be 2 "actors" in
// one actor file.

View file

@ -1,5 +1,3 @@
#include "actors/group2.h"
// Bully
// 0x05000000

View file

@ -11,6 +11,9 @@ static const Vtx burn_smoke_seg4_vertex_040217C0[] = {
// //! Wrong texture format. Called as rgba16, which makes the burn smoke appear
// as a transparent black burn smoke. Probably meant to show up as white-ish
// burn smoke, but mistakened for being intended as black smoke.
// Due to debate in the Koopa shorts PR surrounding the fix to a similar bug,
// said fix is on a compile-time variable. Use TEXTURE_FIX=1 at compile time
// to fix this.
// 0x04021800
ALIGNED8 static const u8 burn_smoke_seg4_texture_04021800[] = {
#include "actors/burn_smoke/burn_smoke.ia16.inc.c"
@ -44,7 +47,11 @@ const Gfx burn_smoke_seg4_dl_04022048[] = {
// 0x04022070 - 0x040220C8
const Gfx burn_smoke_seg4_dl_04022070[] = {
gsSPDisplayList(burn_smoke_seg4_dl_04022000),
#ifdef TEXTURE_FIX
gsDPLoadTextureBlock(burn_smoke_seg4_texture_04021800, G_IM_FMT_IA, G_IM_SIZ_16b, 32, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 5, 5, G_TX_NOLOD, G_TX_NOLOD),
#else
gsDPLoadTextureBlock(burn_smoke_seg4_texture_04021800, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 5, 5, G_TX_NOLOD, G_TX_NOLOD),
#endif
gsSPDisplayList(burn_smoke_seg4_dl_04022028),
gsSPDisplayList(burn_smoke_seg4_dl_04022048),
gsSPEndDisplayList(),

View file

@ -1,5 +1,3 @@
#include "actors/group8.h"
// Capswitch
// 0x05001BB8

View file

@ -1,5 +1,3 @@
#include "actors/group14.h"
// Chain Chomp
// 0x06021388

View file

@ -1,5 +1,3 @@
#include "actors/group9.h"
// Chair
// Unreferenced light group

View file

@ -1,5 +1,3 @@
#include "actors/group16.h"
// 0x06003994
const struct Animation *const chilly_chief_seg6_anims_06003994[] = {
&chilly_chief_seg6_anim_060035E0,

View file

@ -1,5 +1,3 @@
#include "actors/group16.h"
// Why are these scripts compressed unlike the other ones?
// 0x06003754
const GeoLayout chilly_chief_geo[] = {

View file

@ -1,5 +1,3 @@
#include "actors/common0.h"
// Chuckya
// Unreferenced light group
@ -359,7 +357,7 @@ static const Vtx chuckya_seg8_vertex_0800A680[] = {
const Gfx chuckya_seg8_dl_0800A700[] = {
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, chuckya_seg8_texture_08006778),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 64 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPLight(&chuckya_seg8_lights_0800A668.l, 1),
gsSPLight(&chuckya_seg8_lights_0800A668.a, 2),
gsSPVertex(chuckya_seg8_vertex_0800A680, 8, 0),
@ -377,7 +375,7 @@ const Gfx chuckya_seg8_dl_0800A758[] = {
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
gsDPTileSync(),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP, 5, G_TX_NOLOD, G_TX_CLAMP, 5, G_TX_NOLOD),
gsDPSetTileSize(0, 0, 0, (32 - 1) << G_TEXTURE_IMAGE_FRAC, (32 - 1) << G_TEXTURE_IMAGE_FRAC),
gsDPSetTileSize(0, 0, 0, (32 - 1) << G_TEXTURE_IMAGE_FRAC, (64 - 1) << G_TEXTURE_IMAGE_FRAC),
gsSPDisplayList(chuckya_seg8_dl_0800A700),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),
gsDPPipeSync(),

View file

@ -1,5 +1,3 @@
#include "actors/group4.h"
// Clam Shell
// Unreferenced light group

View file

@ -1,5 +1,3 @@
#include "actors/common1.h"
// Coin
// 0x030056C0

View file

@ -1,5 +1,3 @@
#include "actors/common1.h"
// Door
// 0x03009CE0

View file

@ -1,5 +1,3 @@
#include "actors/group17.h"
// Dorrie
// 0x06009BA0

View file

@ -1,5 +1,3 @@
#include "actors/common1.h"
// Explosion
// 0x030009C8

View file

@ -1,5 +1,3 @@
#include "actors/common0.h"
// Flyguy
// ???

View file

@ -1,5 +1,3 @@
#include "actors/common0.h"
// Goomba
// Unreferenced light group

View file

@ -1,5 +1,3 @@
#include "actors/group9.h"
// Haunted Cage
// 0x0500C258

View file

@ -1,5 +1,3 @@
#include "actors/group1.h"
// Hoot
// 0x05000900

View file

@ -28,10 +28,10 @@ static const Vtx impact_smoke_seg6_vertex_06062A28[] = {
{{{ 150, 150, 0}, 0, { 2016, 992}, {0x28, 0x19, 0x14, 0xff}}},
{{{ 150, 300, 0}, 0, { 2016, 0}, {0x28, 0x19, 0x14, 0xff}}},
{{{ -150, 300, 0}, 0, { 0, 0}, {0x28, 0x19, 0x14, 0xff}}},
{{{ -150, 0, 0}, 0, { 0, 992}, {0x28, 0x19, 0x14, 0xff}}},
{{{ 150, 0, 0}, 0, { 2016, 992}, {0x28, 0x19, 0x14, 0xff}}},
{{{ 150, 150, 0}, 0, { 2016, 0}, {0x28, 0x19, 0x14, 0xff}}},
{{{ -150, 150, 0}, 0, { 0, 0}, {0x28, 0x19, 0x14, 0xff}}},
{{{ -150, 0, 0}, 0, { 0, 2016}, {0x28, 0x19, 0x14, 0xff}}},
{{{ 150, 0, 0}, 0, { 2016, 2016}, {0x28, 0x19, 0x14, 0xff}}},
{{{ 150, 150, 0}, 0, { 2016, 992}, {0x28, 0x19, 0x14, 0xff}}},
{{{ -150, 150, 0}, 0, { 0, 992}, {0x28, 0x19, 0x14, 0xff}}},
};
// 0x06062AA8 - 0x06062AD8
@ -68,10 +68,9 @@ const Gfx impact_smoke_seg6_dl_06062B08[] = {
// 0x06062B38 - 0x06062BD8
const Gfx impact_smoke_seg6_dl_06062B38[] = {
gsSPDisplayList(impact_smoke_seg6_dl_06062AA8),
gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605AA28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605AA28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(impact_smoke_seg6_vertex_06062A28, 8, 0),
gsSPDisplayList(impact_smoke_seg6_dl_06062AD8),
gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605AA28 + 0x1000, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(impact_smoke_seg6_dl_06062AF0),
gsSPDisplayList(impact_smoke_seg6_dl_06062B08),
gsSPEndDisplayList(),
@ -80,10 +79,9 @@ const Gfx impact_smoke_seg6_dl_06062B38[] = {
// 0x06062BD8 - 0x06062C78
const Gfx impact_smoke_seg6_dl_06062BD8[] = {
gsSPDisplayList(impact_smoke_seg6_dl_06062AA8),
gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605CA28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605CA28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(impact_smoke_seg6_vertex_06062A28, 8, 0),
gsSPDisplayList(impact_smoke_seg6_dl_06062AD8),
gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605CA28 + 0x1000, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(impact_smoke_seg6_dl_06062AF0),
gsSPDisplayList(impact_smoke_seg6_dl_06062B08),
gsSPEndDisplayList(),
@ -92,10 +90,9 @@ const Gfx impact_smoke_seg6_dl_06062BD8[] = {
// 0x06062C78 - 0x06062D18
const Gfx impact_smoke_seg6_dl_06062C78[] = {
gsSPDisplayList(impact_smoke_seg6_dl_06062AA8),
gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605EA28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605EA28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(impact_smoke_seg6_vertex_06062A28, 8, 0),
gsSPDisplayList(impact_smoke_seg6_dl_06062AD8),
gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605EA28 + 0x1000, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(impact_smoke_seg6_dl_06062AF0),
gsSPDisplayList(impact_smoke_seg6_dl_06062B08),
gsSPEndDisplayList(),
@ -104,10 +101,9 @@ const Gfx impact_smoke_seg6_dl_06062C78[] = {
// 0x06062D18 - 0x06062DB8
const Gfx impact_smoke_seg6_dl_06062D18[] = {
gsSPDisplayList(impact_smoke_seg6_dl_06062AA8),
gsDPLoadTextureBlock(impact_smoke_seg6_texture_06060A28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPLoadTextureBlock(impact_smoke_seg6_texture_06060A28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPVertex(impact_smoke_seg6_vertex_06062A28, 8, 0),
gsSPDisplayList(impact_smoke_seg6_dl_06062AD8),
gsDPLoadTextureBlock(impact_smoke_seg6_texture_06060A28 + 0x1000, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD),
gsSPDisplayList(impact_smoke_seg6_dl_06062AF0),
gsSPDisplayList(impact_smoke_seg6_dl_06062B08),
gsSPEndDisplayList(),

View file

@ -1,5 +1,3 @@
#include "actors/group3.h"
// King Bobomb
// Unreferenced light group
@ -533,7 +531,7 @@ static const Vtx king_bobomb_seg5_vertex_0500B218[] = {
const Gfx king_bobomb_seg5_dl_0500B278[] = {
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, king_bobomb_seg5_texture_05004878),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 64 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPLight(&king_bobomb_seg5_lights_0500B200.l, 1),
gsSPLight(&king_bobomb_seg5_lights_0500B200.a, 2),
gsSPVertex(king_bobomb_seg5_vertex_0500B218, 6, 0),
@ -550,7 +548,7 @@ const Gfx king_bobomb_seg5_dl_0500B2D0[] = {
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
gsDPTileSync(),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP, 5, G_TX_NOLOD, G_TX_CLAMP, 5, G_TX_NOLOD),
gsDPSetTileSize(0, 0, 0, (32 - 1) << G_TEXTURE_IMAGE_FRAC, (32 - 1) << G_TEXTURE_IMAGE_FRAC),
gsDPSetTileSize(0, 0, 0, (32 - 1) << G_TEXTURE_IMAGE_FRAC, (64 - 1) << G_TEXTURE_IMAGE_FRAC),
gsSPDisplayList(king_bobomb_seg5_dl_0500B278),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),
gsDPPipeSync(),

View file

@ -1,5 +1,3 @@
#include "actors/group5.h"
// Possible Removed Actor File
// Bin ID? What is this?

View file

@ -1,5 +1,3 @@
#include "actors/group14.h"
// Koopa (Small Koopa, Big Koopa [Koopa the Quick])
@ -56,6 +54,8 @@ static const Lights1 koopa_seg6_lights_06002630 = gdSPDefLights1(
// beneath its shell, despite the fact it was intended to be white like
// the rest of its body. This is evident because once the mistake is corrected
// it turns back to being white like the other polygons.
// Due to debate in the PR surrounding the fix to this, said fix is on
// a compile-time variable. Use TEXTURE_FIX=1 at compile time to fix this.
// 0x06002648
ALIGNED8 static const u8 koopa_seg6_texture_06002648[] = {
#include "actors/koopa/koopa_shell_front.rgba16.inc.c"
@ -2079,8 +2079,13 @@ const Gfx koopa_seg6_dl_0600C498[] = {
gsSPVertex(koopa_seg6_vertex_0600B560, 9, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP1Triangle( 6, 7, 8, 0x0),
#ifdef TEXTURE_FIX
gsSPLight(&koopa_seg6_lights_06002630.l, 1),
gsSPLight(&koopa_seg6_lights_06002630.a, 2),
#else
gsSPLight(koopa_seg6_texture_06002648 + 0x20, 1), // this malformed light results in a
gsSPLight(koopa_seg6_texture_06002648 + 0x18, 2), // koopa appearing to wear pink shorts.
#endif
gsSPVertex(koopa_seg6_vertex_0600B5F0, 15, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 6, 7, 0, 0x0, 8, 5, 9, 0x0),

View file

@ -1,5 +1,3 @@
#include "actors/group14.h"
// Koopa Flag
// 0x06000000

View file

@ -1,5 +1,3 @@
#include "actors/group15.h"
// Lakitu (Cameraman)
// 0x06000000

View file

@ -1,5 +1,3 @@
#include "actors/group11.h"
// Lakitu Enemy
// Unreferenced light group

View file

@ -1,5 +1,3 @@
#include "actors/group9.h"
// Mad Piano
// Unreferenced light group

View file

@ -1,5 +1,3 @@
#include "actors/group0.h"
// Mario
// 0x04000000 # solid color blue - butt, left thigh, right thigh - all poly types

View file

@ -1,5 +1,3 @@
#include "actors/common1.h"
// Mist
// 0x03000000

View file

@ -1,5 +1,3 @@
#include "actors/group16.h"
// Moneybag
// 0x060039B0

View file

@ -1,5 +1,3 @@
#include "actors/group6.h"
// Monty Mole
// Unreferenced light group

View file

@ -1,5 +1,3 @@
#include "actors/group6.h"
// Monty Mole Hole
// 0x05000000

View file

@ -1,5 +1,3 @@
#include "actors/group17.h"
// Mr I (white eyeball)
// 0x06000000

View file

@ -1,5 +1,3 @@
#include "actors/group17.h"
// Mr I (Iris)
// 0x06002130

View file

@ -1,5 +1,3 @@
#include "actors/group10.h"
// Peach
// 0x050009F8

View file

@ -1,5 +1,3 @@
#include "actors/group7.h"
// Penguin
// 0x05002D80

View file

@ -1,5 +1,3 @@
#include "actors/group14.h"
// Piranha Plant
// 0x060113B0

View file

@ -1,5 +1,3 @@
#include "actors/group17.h"
// Scuttlebug
// Unreferenced light group

View file

@ -1,5 +1,3 @@
#include "actors/group13.h"
// Seaweed
// 0x06007DF8

View file

@ -1,5 +1,3 @@
#include "actors/group13.h"
// Skeeter
// Unreferenced light group

View file

@ -1,5 +1,3 @@
#include "actors/group9.h"
// Small Key (unused)
// ???

View file

@ -1,5 +1,3 @@
#include "actors/group7.h"
// Snowman
// ???

View file

@ -1,5 +1,3 @@
#include "actors/group17.h"
// Snufit
// 0x060070E0

View file

@ -1,5 +1,3 @@
#include "actors/group7.h"
// Spindrift
// Unreferenced light group

View file

@ -1,5 +1,3 @@
#include "actors/group11.h"
// Spiny
// 0x050157F8

View file

@ -1,5 +1,3 @@
#include "actors/group8.h"
// Springboard (unused)
// 0x05000000

View file

@ -56,7 +56,7 @@ const Gfx star_seg3_dl_0302B870[] = {
gsSPSetGeometryMode(G_TEXTURE_GEN),
gsDPSetEnvColor(255, 255, 255, 255),
gsDPSetCombineMode(G_CC_DECALFADE, G_CC_DECALFADE),
gsDPLoadTextureBlock(star_seg3_texture_0302A6F0, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 64, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_WRAP | G_TX_NOMIRROR, 5, 6, G_TX_NOLOD, G_TX_NOLOD), //! Dimensions loaded as 32x64 despite this texture having only 32x32 dimensions, harmless due to environment mapping (G_TEXTURE_GEN & gsSPTexture values)
gsDPLoadTextureBlock(star_seg3_texture_0302A6F0, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_WRAP | G_TX_NOMIRROR, 5, 6, G_TX_NOLOD, G_TX_NOLOD),
gsSPTexture(0x07C0, 0x07C0, 0, G_TX_RENDERTILE, G_ON),
gsSPDisplayList(star_seg3_dl_0302B7B0),
gsDPPipeSync(),

View file

@ -1,5 +1,3 @@
#include "actors/group4.h"
// Sushi (Shark)
// Could be a duplicate binid of the previous actor, but i'm putting it here for

View file

@ -1,5 +1,3 @@
#include "actors/group17.h"
// Swoop
// Unreferenced light group

View file

@ -1,5 +1,3 @@
#include "actors/group15.h"
// Toad
// 0x06005908

View file

@ -1,5 +1,3 @@
#include "actors/group13.h"
// Treasure Chest
// 0x06013F90

View file

@ -1,5 +1,3 @@
#include "actors/group6.h"
// Ukiki
// Unreferenced light group

View file

@ -1,5 +1,3 @@
#include "actors/group4.h"
// Unagi (Eel)
// Unreferenced light group

View file

@ -1,5 +1,3 @@
#include "actors/group14.h"
// Whomp
// ???

View file

@ -1,5 +1,3 @@
#include "actors/group11.h"
// Wiggler Body
// 0x05005A30

View file

@ -1,5 +1,3 @@
#include "actors/group1.h"
// Yellow Sphere (used in a lot of things)
// 0x05000000

7
asmdiff.jp.sh Normal file
View file

@ -0,0 +1,7 @@
#!/bin/bash
OBJDUMP="mips-linux-gnu-objdump -D -z -bbinary -mmips -EB"
OPTIONS="--start-address=$(($1)) --stop-address=$(($2))"
$OBJDUMP $OPTIONS baserom.jp.z64 > baserom.jp.dump
$OBJDUMP $OPTIONS build/jp/sm64.jp.z64 > sm64.jp.dump
diff baserom.jp.dump sm64.jp.dump | colordiff

View file

@ -1,7 +1,5 @@
#include "sm64.h"
#include "textures.h"
#include "make_const_nonconst.h"
// 0x09000000

View file

@ -1,9 +1,6 @@
#include <ultra64.h>
#include "sm64.h"
#include "src/menu/debug_level_select.h"
#include "textures.h"
#include "make_const_nonconst.h"
// 0x07000000 - 0x07000018

View file

@ -1,8 +1,6 @@
#include <ultra64.h>
#include "sm64.h"
#include "textures.h"
#include "make_const_nonconst.h"
UNUSED static const u64 effect_unused_0 = 0;

View file

@ -1,7 +1,5 @@
#include "sm64.h"
#include "textures.h"
#include "make_const_nonconst.h"
// 0x09000000

View file

@ -1,7 +1,5 @@
#include "sm64.h"
#include "textures.h"
#include "make_const_nonconst.h"
// 0x09000000

View file

@ -1,7 +1,5 @@
#include "sm64.h"
#include "textures.h"
#include "make_const_nonconst.h"
// 0x09000000

View file

@ -1,7 +1,5 @@
#include "sm64.h"
#include "textures.h"
#include "make_const_nonconst.h"
// 0x09000000

View file

@ -1,7 +1,5 @@
#include "sm64.h"
#include "textures.h"
#include "make_const_nonconst.h"
// 0x09000000

View file

@ -1,7 +1,5 @@
#include "sm64.h"
#include "textures.h"
#include "make_const_nonconst.h"
// 0x09000000

View file

@ -1,7 +1,5 @@
#include "sm64.h"
#include "textures.h"
#include "make_const_nonconst.h"
// 0x09000000

View file

@ -1,5 +1,3 @@
#include "game/segment2.h"
#include <ultra64.h>
#include "sm64.h"
#include "game/ingame_menu.h"
@ -1803,7 +1801,7 @@ ALIGNED8 static const u8 texture_hud_char_arrow_down[] = {
};
// Main HUD print table 0x02008250-0x02008337
const u8* const main_hud_lut[] = {
const u8 *const main_hud_lut[] = {
#ifdef VERSION_EU
texture_hud_char_0, texture_hud_char_1, texture_hud_char_2, texture_hud_char_3,
texture_hud_char_4, texture_hud_char_5, texture_hud_char_6, texture_hud_char_7,
@ -2109,7 +2107,7 @@ const Gfx dl_hud_img_load_tex_block[] = {
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, 4, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, 4, G_TX_NOLOD),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 16 * 16 - 1, CALC_DXT(16, G_IM_SIZ_16b_BYTES)),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 4, 0, G_TX_RENDERTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, 4, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, 4, G_TX_NOLOD),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 4, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP, 4, G_TX_NOLOD, G_TX_CLAMP, 4, G_TX_NOLOD),
gsDPSetTileSize(0, 0, 0, (16 - 1) << G_TEXTURE_IMAGE_FRAC, (16 - 1) << G_TEXTURE_IMAGE_FRAC),
gsSPEndDisplayList(),
};
@ -2146,7 +2144,7 @@ const Gfx dl_rgba16_load_tex_block[] = {
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, 4, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, 4, G_TX_NOLOD),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 16 * 16 - 1, CALC_DXT(16, G_IM_SIZ_16b_BYTES)),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 4, 0, G_TX_RENDERTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, 4, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, 4, G_TX_NOLOD),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 4, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP, 4, G_TX_NOLOD, G_TX_CLAMP, 4, G_TX_NOLOD),
gsDPSetTileSize(0, 0, 0, (16 - 1) << G_TEXTURE_IMAGE_FRAC, (16 - 1) << G_TEXTURE_IMAGE_FRAC),
gsSPEndDisplayList(),
};
@ -2457,39 +2455,39 @@ ALIGNED8 static const u8 texture_shadow_quarter_square[] = {
#include "textures/segment2/shadow_quarter_square.ia8.inc.c"
};
ALIGNED8 u8 texture_transition_star_half[] = {
ALIGNED8 const u8 texture_transition_star_half[] = {
#include "textures/segment2/segment2.0F458.ia8.inc.c"
};
ALIGNED8 u8 texture_transition_circle_half[] = {
ALIGNED8 const u8 texture_transition_circle_half[] = {
#include "textures/segment2/segment2.0FC58.ia8.inc.c"
};
ALIGNED8 u8 texture_transition_mario[] = {
ALIGNED8 const u8 texture_transition_mario[] = {
#include "textures/segment2/segment2.10458.ia8.inc.c"
};
ALIGNED8 u8 texture_transition_bowser_half[] = {
ALIGNED8 const u8 texture_transition_bowser_half[] = {
#include "textures/segment2/segment2.11458.ia8.inc.c"
};
ALIGNED8 u8 texture_waterbox_water[] = {
ALIGNED8 const u8 texture_waterbox_water[] = {
#include "textures/segment2/segment2.11C58.rgba16.inc.c"
};
ALIGNED8 u8 texture_waterbox_jrb_water[] = {
ALIGNED8 const u8 texture_waterbox_jrb_water[] = {
#include "textures/segment2/segment2.12458.rgba16.inc.c"
};
ALIGNED8 u8 texture_waterbox_unknown_water[] = {
ALIGNED8 const u8 texture_waterbox_unknown_water[] = {
#include "textures/segment2/segment2.12C58.rgba16.inc.c"
};
ALIGNED8 u8 texture_waterbox_mist[] = {
ALIGNED8 const u8 texture_waterbox_mist[] = {
#include "textures/segment2/segment2.13458.ia16.inc.c"
};
ALIGNED8 u8 texture_waterbox_lava[] = {
ALIGNED8 const u8 texture_waterbox_lava[] = {
#include "textures/segment2/segment2.13C58.rgba16.inc.c"
};
@ -2501,41 +2499,19 @@ static const Lights1 segment2_lights_unused = gdSPDefLights1(
// 0x02014470 - 0x020144B0
static const Mtx matrix_identity = {
#ifndef GBI_FLOATS
{{0x00010000, 0x00000000,
0x00000001, 0x00000000},
{0x00000000, 0x00010000,
0x00000000, 0x00000001},
{0x00000000, 0x00000000,
0x00000000, 0x00000000},
{0x00000000, 0x00000000,
0x00000000, 0x00000000}}
#else
{{1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}}
#endif
};
// 0x020144B0 - 0x020144F0
static const Mtx matrix_fullscreen = {
#ifndef GBI_FLOATS
{{0x00000000, 0x00000000,
0x00000000, 0x00000000},
{0x00000000, 0xffff0000,
0xffffffff, 0xffff0001},
{((65536 * 2 / SCREEN_WIDTH) << 16) | 0, 0x00000000,
(0 << 16) | (65536 * 2 / SCREEN_HEIGHT), 0x00000000},
{0x00000000, 0x00000000,
0x00000000, 0x00000000}}
#else
{{2.0f / SCREEN_WIDTH, 0.0f, 0.0f, 0.0f},
{0.0f, 2.0f / SCREEN_HEIGHT, 0.0f, 0.0f},
{0.0f, 0.0f, -1.0f, 0.0f},
{-1.0f, -1.0f, -1.0f, 1.0f}}
#endif
};
@ -2654,7 +2630,7 @@ const Gfx dl_skybox_end[] = {
};
// 0x02014790 - 0x020147D0
Gfx dl_waterbox_rgba16_begin[] = {
const Gfx dl_waterbox_rgba16_begin[] = {
gsDPPipeSync(),
gsDPSetCombineMode(G_CC_MODULATERGBA, G_CC_MODULATERGBA),
gsSPClearGeometryMode(G_LIGHTING | G_CULL_BACK),
@ -2678,7 +2654,7 @@ const Gfx dl_waterbox_ia16_begin[] = {
};
// 0x02014810 - 0x02014838
Gfx dl_waterbox_end[] = {
const Gfx dl_waterbox_end[] = {
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),
gsDPPipeSync(),
gsSPSetGeometryMode(G_LIGHTING | G_CULL_BACK),

View file

@ -1,7 +1,5 @@
#include "sm64.h"
#include "textures.h"
#include "make_const_nonconst.h"
// 0x09000000

View file

@ -1,7 +1,5 @@
#include "sm64.h"
#include "textures.h"
#include "make_const_nonconst.h"
// 0x09000000

View file

@ -1,7 +1,5 @@
#include "sm64.h"
#include "textures.h"
#include "make_const_nonconst.h"
// 0x09000000

View file

@ -1,8 +1,6 @@
#include <ultra64.h>
#include "sm64.h"
#include "textures.h"
#include "make_const_nonconst.h"
// 0x0A000000 - 0x0A000100

View file

@ -1,7 +1,5 @@
#include "sm64.h"
#include "textures.h"
#include "make_const_nonconst.h"
// 0x09000000

141
c2obj.py Normal file
View file

@ -0,0 +1,141 @@
"""
This module attempts to parse the ``model.inc.c`` files and extract the
3D models within as standard Wavefront OBJ files.
Example:
Specify the path to the ``.inc.c`` file and a directory where to save
the extracted ``.obj`` files.
$ python c2obj.py ./actors/mario/model.inc.c ./actors/mario/obj/
This is a work in progress and it currently has some serious limitations:
* It only extracts geometry information, so no textures or any other info
* It makes assumptions about the layout of the code in the C source
* It hasn't been properly tested.
"""
def parse(filename, output_directory):
from os import path, mkdir
if not path.isdir(output_directory):
try:
mkdir(output_directory)
except OSError:
print(f'Could not use output directory {output_directory}.')
vtx_def = 'static const Vtx '
vtx_data = {}
reading_vtx = False
current_vtx_name = ''
current_vtx_data = []
current_vtx_vertices = 0
gfx_def = 'const Gfx '
reading_gfx = False
current_gfx_vertices = 0
current_gfx_faces = 0
insert_vert_call = 'gsSPVertex('
insert_1tri_call = 'gsSP1Triangle('
insert_2tri_call = 'gsSP2Triangles('
gfx_count = 0
end_of_block = '};'
with open(filename, 'r') as f:
for line in f:
line = line.strip()
if line.startswith(vtx_def):
vtx_name = line.split(' ')[3][:-2]
current_vtx_name = vtx_name
current_vtx_data = []
reading_vtx = True
continue
if line.startswith(gfx_def):
from datetime import datetime
current_gfx_name = line.split(' ')[2][:-2]
current_gfx_file = open(path.join(output_directory, current_gfx_name + '.obj'), 'w')
current_gfx_file.write("# Armando Arredondo's SM64 Wavefront OBJ Geometry Converter\n")
current_gfx_file.write('# File Created: {}\n\n'.format(datetime.now()))
reading_gfx = True
continue
if line == end_of_block:
if reading_vtx:
vtx_data[current_vtx_name] = current_vtx_data
reading_vtx = False
elif reading_gfx:
current_gfx_file.write(f'# {current_gfx_faces} faces\n\n')
current_gfx_file.close()
current_gfx_vertices = 0
reading_gfx = False
gfx_count += 1
continue
if reading_vtx:
line = line.replace('{', '[').replace('}', ']')
tri = eval(line[:-1])[0]
current_vtx_data.append(tri)
continue
if reading_gfx:
if line.startswith(insert_vert_call):
args = line[len(insert_vert_call):].split(',')
current_vtx_name = args[0]
if current_gfx_vertices > 0:
current_gfx_file.write(f'# {current_gfx_faces} faces\n\n')
current_gfx_faces = 0
current_vtx_vertices = len(vtx_data[current_vtx_name])
current_gfx_vertices += current_vtx_vertices
current_gfx_file.write(f'#\n# object {current_vtx_name}\n#\n\n')
current_vtx_data = vtx_data[current_vtx_name]
for tri in current_vtx_data:
v = tri[0]
current_gfx_file.write('v {:.3f} {:.3f} {:.3f}\n'.format(*v))
current_gfx_file.write(f'# {current_vtx_vertices} vertices\n\n')
for tri in current_vtx_data:
n = [_decode_normal(u) for u in tri[3][:3]]
current_gfx_file.write('vn {:.3f} {:.3f} {:.3f}\n'.format(*n))
current_gfx_file.write(f'# {current_vtx_vertices} vertex normals\n\n')
current_gfx_file.write(f'g {current_vtx_name}\n\n')
elif line.startswith(insert_2tri_call):
args = line[len(insert_2tri_call):].split(',')
correction = current_gfx_vertices - current_vtx_vertices + 1
indexes = [eval(args[i]) + correction for i in [0, 1, 2, 4, 5, 6]]
current_gfx_file.write('f {0}//{0} {1}//{1} {2}//{2}\n'.format(*indexes[:3]))
current_gfx_file.write('f {0}//{0} {1}//{1} {2}//{2}\n'.format(*indexes[3:]))
current_gfx_faces += 2
elif line.startswith(insert_1tri_call):
args = line[len(insert_1tri_call):].split(',')
correction = current_gfx_vertices - current_vtx_vertices + 1
indexes = [eval(args[i]) + correction for i in [0, 1, 2]]
current_gfx_file.write('f {0}//{0} {1}//{1} {2}//{2}\n'.format(*indexes))
current_gfx_faces += 1
continue
print(f'{gfx_count} models extracted.')
def _decode_normal(x):
y = x if x <= 127 else x - 255
return y / 127
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('filename', help = 'filename of the .inc.c source file')
parser.add_argument('output_directory', help = 'directory where to put the extracted .obj files')
args = parser.parse_args()
parse(args.filename, args.output_directory)

View file

@ -6,12 +6,11 @@
#include "game/object_list_processor.h"
#include "game/interaction.h"
#include "game/behavior_actions.h"
#include "game/behaviors/thwomp/thwomp.hpp"
#include "game/mario_actions_cutscene.h"
#include "game/mario_misc.h"
#include "game/object_helpers.h"
#include "game/debug.h"
#include "menu/file_select.hpp"
#include "menu/file_select.h"
#include "engine/surface_load.h"
#include "actors/common0.h"
@ -56,7 +55,282 @@
#include "make_const_nonconst.h"
#include "behavior_data.h"
#include "include/behavior_macros.h"
#define BC_B(a) _SHIFTL(a, 24, 8)
#define BC_BB(a, b) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8))
#define BC_BBBB(a, b, c, d) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 8, 8) | _SHIFTL(d, 0, 8))
#define BC_BBH(a, b, c) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 0, 16))
#define BC_B0H(a, b) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 0, 16))
#define BC_H(a) _SHIFTL(a, 16, 16)
#define BC_HH(a, b) (_SHIFTL(a, 16, 16) | _SHIFTL(b, 0, 16))
#define BC_W(a) ((uintptr_t)(u32)(a))
#define BC_PTR(a) ((uintptr_t)(a))
// Defines the start of the behavior script as well as the object list the object belongs to.
// Has some special behavior for certain objects.
#define BEGIN(objList) \
BC_BB(0x00, objList)
// Delays the behavior script for a certain number of frames.
#define DELAY(num) \
BC_B0H(0x01, num)
// Jumps to a new behavior command and stores the return address in the object's stack.
#define CALL(addr) \
BC_B(0x02), \
BC_PTR(addr)
// Jumps back to the behavior command stored in the object's stack.
#define RETURN() \
BC_B(0x03)
// Jumps to a new behavior script without saving anything.
#define GOTO(addr) \
BC_B(0x04), \
BC_PTR(addr)
// Marks the start of a loop that will repeat a certain number of times.
#define BEGIN_REPEAT(count) \
BC_B0H(0x05, count)
// Marks the end of a repeating loop.
#define END_REPEAT() \
BC_B(0x06)
// Also marks the end of a repeating loop, but continues executing commands following the loop on the same frame.
#define END_REPEAT_CONTINUE() \
BC_B(0x07)
// Marks the beginning of an infinite loop.
#define BEGIN_LOOP() \
BC_B(0x08)
// Marks the end of an infinite loop.
#define END_LOOP() \
BC_B(0x09)
// Exits the behavior script.
// Often used to end behavior scripts that do not contain an infinite loop.
#define BREAK() \
BC_B(0x0A)
// Exits the behavior script, unused.
#define BREAK_UNUSED() \
BC_B(0x0B)
// Executes a native game function.
#define CALL_NATIVE(func) \
BC_B(0x0C), \
BC_PTR(func)
// Adds a float to the specified field.
#define ADD_FLOAT(field, value) \
BC_BBH(0x0D, field, value)
// Sets the specified field to a float.
#define SET_FLOAT(field, value) \
BC_BBH(0x0E, field, value)
// Adds an integer to the specified field.
#define ADD_INT(field, value) \
BC_BBH(0x0F, field, value)
// Sets the specified field to an integer.
#define SET_INT(field, value) \
BC_BBH(0x10, field, value)
// Performs a bitwise OR with the specified field and the given integer.
// Usually used to set an object's flags.
#define OR_INT(field, value) \
BC_BBH(0x11, field, value)
// Performs a bit clear with the specified short. Unused in favor of the 32-bit version.
#define BIT_CLEAR(field, value) \
BC_BBH(0x12, field, value)
// TODO: this one needs a better name / labelling
// Gets a random short, right shifts it the specified amount and adds min to it, then sets the specified field to that value.
#define SET_INT_RAND_RSHIFT(field, min, rshift) \
BC_BBH(0x13, field, min), \
BC_H(rshift)
// Sets the specified field to a random float in the given range.
#define SET_RANDOM_FLOAT(field, min, range) \
BC_BBH(0x14, field, min), \
BC_H(range)
// Sets the specified field to a random integer in the given range.
#define SET_RANDOM_INT(field, min, range) \
BC_BBH(0x15, field, min), \
BC_H(range)
// Adds a random float in the given range to the specified field.
#define ADD_RANDOM_FLOAT(field, min, range) \
BC_BBH(0x16, field, min), \
BC_H(range)
// TODO: better name (unused anyway)
// Gets a random short, right shifts it the specified amount and adds min to it, then adds the value to the specified field. Unused.
#define ADD_INT_RAND_RSHIFT(field, min, rshift) \
BC_BBH(0x17, field, min), \
BC_H(rshift)
// No operation. Unused.
#define CMD_NOP_1(field) \
BC_BB(0x18, field)
// No operation. Unused.
#define CMD_NOP_2(field) \
BC_BB(0x19, field)
// No operation. Unused.
#define CMD_NOP_3(field) \
BC_BB(0x1A, field)
// Sets the current model ID of the object.
#define SET_MODEL(modelID) \
BC_B0H(0x1B, modelID)
// Spawns a child object with the specified model and behavior.
#define SPAWN_CHILD(modelID, behavior) \
BC_B(0x1C), \
BC_W(modelID), \
BC_PTR(behavior)
// Exits the behavior script and despawns the object.
// Often used to end behavior scripts that do not contain an infinite loop.
#define DEACTIVATE() \
BC_B(0x1D)
// Finds the floor triangle directly under the object and moves the object down to it.
#define DROP_TO_FLOOR() \
BC_B(0x1E)
// Sets the destination float field to the sum of the values of the given float fields.
#define SUM_FLOAT(fieldDst, fieldSrc1, fieldSrc2) \
BC_BBBB(0x1F, fieldDst, fieldSrc1, fieldSrc2)
// Sets the destination integer field to the sum of the values of the given integer fields. Unused.
#define SUM_INT(fieldDst, fieldSrc1, fieldSrc2) \
BC_BBBB(0x20, fieldDst, fieldSrc1, fieldSrc2)
// Billboards the current object, making it always face the camera.
#define BILLBOARD() \
BC_B(0x21)
#define CYLBOARD() \
BC_B(0x38)
// Hides the current object.
#define HIDE() \
BC_B(0x22)
// Sets the size of the object's cylindrical hitbox.
#define SET_HITBOX(radius, height) \
BC_B(0x23), \
BC_HH(radius, height)
// No operation. Unused.
#define CMD_NOP_4(field, value) \
BC_BBH(0x24, field, value)
// Delays the behavior script for the number of frames given by the value of the specified field.
#define DELAY_VAR(field) \
BC_BB(0x25, field)
// Unused. Marks the start of a loop that will repeat a certain number of times.
// Uses a u8 as the argument, instead of a s16 like the other version does.
#define BEGIN_REPEAT_UNUSED(count) \
BC_BB(0x26, count)
// Loads the animations for the object. <field> is always set to oAnimations.
#define LOAD_ANIMATIONS(field, anims) \
BC_BB(0x27, field), \
BC_PTR(anims)
// Begins animation and sets the object's current animation index to the specified value.
#define ANIMATE(animIndex) \
BC_BB(0x28, animIndex)
// Spawns a child object with the specified model and behavior, plus a behavior param.
#define SPAWN_CHILD_WITH_PARAM(bhvParam, modelID, behavior) \
BC_B0H(0x29, bhvParam), \
BC_W(modelID), \
BC_PTR(behavior)
// Loads collision data for the object.
#define LOAD_COLLISION_DATA(collisionData) \
BC_B(0x2A), \
BC_PTR(collisionData)
// Sets the size of the object's cylindrical hitbox, and applies a downwards offset.
#define SET_HITBOX_WITH_OFFSET(radius, height, downOffset) \
BC_B(0x2B), \
BC_HH(radius, height), \
BC_H(downOffset)
// Spawns a new object with the specified model and behavior.
#define SPAWN_OBJ(modelID, behavior) \
BC_B(0x2C), \
BC_W(modelID), \
BC_PTR(behavior)
// Sets the home position of the object to its current position.
#define SET_HOME() \
BC_B(0x2D)
// Sets the size of the object's cylindrical hurtbox.
#define SET_HURTBOX(radius, height) \
BC_B(0x2E), \
BC_HH(radius, height)
// Sets the object's interaction type.
#define SET_INTERACT_TYPE(type) \
BC_B(0x2F), \
BC_W(type)
// Sets various parameters that the object uses for calculating physics.
#define SET_OBJ_PHYSICS(wallHitboxRadius, gravity, bounciness, dragStrength, friction, buoyancy, unused1, unused2) \
BC_B(0x30), \
BC_HH(wallHitboxRadius, gravity), \
BC_HH(bounciness, dragStrength), \
BC_HH(friction, buoyancy), \
BC_HH(unused1, unused2)
// Sets the object's interaction subtype. Unused.
#define SET_INTERACT_SUBTYPE(subtype) \
BC_B(0x31), \
BC_W(subtype)
// Sets the object's size to the specified percentage.
#define SCALE(unusedField, percent) \
BC_BBH(0x32, unusedField, percent)
// Performs a bit clear on the object's parent's field with the specified value.
// Used for clearing active particle flags fron Mario's object.
#define PARENT_BIT_CLEAR(field, flags) \
BC_BB(0x33, field), \
BC_W(flags)
// Animates an object using texture animation. <field> is always set to oAnimState.
#define ANIMATE_TEXTURE(field, rate) \
BC_BBH(0x34, field, rate)
// Disables rendering for the object.
#define DISABLE_RENDERING() \
BC_B(0x35)
// Unused. Sets the specified field to an integer. Wastes 4 bytes of space for no reason at all.
#define SET_INT_UNUSED(field, value) \
BC_BB(0x36, field), \
BC_HH(0, value)
// Spawns a water droplet with the given parameters.
#define SPAWN_WATER_DROPLET(dropletParams) \
BC_B(0x37), \
BC_PTR(dropletParams)
const BehaviorScript bhvStarDoor[] = {
BEGIN(OBJ_LIST_SURFACE),
@ -2909,7 +3183,11 @@ const BehaviorScript bhvFloorTrapInCastle[] = {
const BehaviorScript bhvTree[] = {
BEGIN(OBJ_LIST_POLELIKE),
#ifdef BETTERCAMERA
CYLBOARD(),
#else
BILLBOARD(),
#endif
OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE),
SET_INT(oInteractType, INTERACT_POLE),
SET_HITBOX(/*Radius*/ 80, /*Height*/ 500),
@ -5834,5 +6112,3 @@ const BehaviorScript bhvIntroScene[] = {
CALL_NATIVE(bhv_intro_scene_loop),
END_LOOP(),
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 417 B

View file

@ -1,5 +1,5 @@
diff --git a/include/types.h b/include/types.h
index a33dc721..18887a45 100644
index b3dc27e..c46bdf0 100644
--- a/include/types.h
+++ b/include/types.h
@@ -118,6 +118,10 @@ struct GraphNodeObject_sub
@ -48,10 +48,10 @@ index a33dc721..18887a45 100644
struct MarioBodyState
diff --git a/src/engine/graph_node.h b/src/engine/graph_node.h
index a680f70e..a31bb8ae 100644
index 802d97a..1b0d677 100644
--- a/src/engine/graph_node.h
+++ b/src/engine/graph_node.h
@@ -109,6 +109,8 @@ struct GraphNodePerspective
@@ -110,6 +110,8 @@ struct GraphNodePerspective
/*0x1C*/ f32 fov; // horizontal field of view in degrees
/*0x20*/ s16 near; // near clipping plane
/*0x22*/ s16 far; // far clipping plane
@ -60,7 +60,7 @@ index a680f70e..a31bb8ae 100644
};
/** An entry in the master list. It is a linked list of display lists
@@ -117,7 +119,9 @@ struct GraphNodePerspective
@@ -118,7 +120,9 @@ struct GraphNodePerspective
struct DisplayListNode
{
Mtx *transform;
@ -70,7 +70,7 @@ index a680f70e..a31bb8ae 100644
struct DisplayListNode *next;
};
@@ -184,7 +188,11 @@ struct GraphNodeCamera
@@ -185,7 +189,11 @@ struct GraphNodeCamera
} config;
/*0x1C*/ Vec3f pos;
/*0x28*/ Vec3f focus;
@ -82,7 +82,7 @@ index a680f70e..a31bb8ae 100644
/*0x38*/ s16 roll; // roll in look at matrix. Doesn't account for light direction unlike rollScreen.
/*0x3A*/ s16 rollScreen; // rolls screen while keeping the light direction consistent
};
@@ -225,7 +233,8 @@ struct GraphNodeRotation
@@ -226,7 +234,8 @@ struct GraphNodeRotation
/*0x00*/ struct GraphNode node;
/*0x14*/ void *displayList;
/*0x18*/ Vec3s rotation;
@ -92,7 +92,7 @@ index a680f70e..a31bb8ae 100644
};
/** GraphNode part that transforms itself and its children based on animation
@@ -322,6 +331,9 @@ struct GraphNodeBackground
@@ -323,6 +332,9 @@ struct GraphNodeBackground
/*0x00*/ struct FnGraphNode fnNode;
/*0x18*/ s32 unused;
/*0x1C*/ s32 background; // background ID, or rgba5551 color if fnNode.func is null
@ -102,7 +102,7 @@ index a680f70e..a31bb8ae 100644
};
/** Renders the object that Mario is holding.
@@ -332,6 +344,8 @@ struct GraphNodeHeldObject
@@ -333,6 +345,8 @@ struct GraphNodeHeldObject
/*0x18*/ s32 playerIndex;
/*0x1C*/ struct Object *objNode;
/*0x20*/ Vec3s translation;
@ -112,18 +112,18 @@ index a680f70e..a31bb8ae 100644
/** A node that allows an object to specify a different culling radius than the
diff --git a/src/engine/surface_collision.c b/src/engine/surface_collision.c
index 9aff62f9..9c062cf4 100644
index 5b6775f..2c11e25 100644
--- a/src/engine/surface_collision.c
+++ b/src/engine/surface_collision.c
@@ -7,6 +7,7 @@
#include "game/object_list_processor.h"
@@ -8,6 +8,7 @@
#include "surface_collision.h"
#include "surface_load.h"
#include "math_util.h"
+#include "game/game_init.h"
/**************************************************
* WALLS *
@@ -393,26 +394,44 @@ f32 find_floor_height_and_data(f32 xPos, f32 yPos, f32 zPos, struct FloorGeometr
@@ -394,26 +395,44 @@ f32 find_floor_height_and_data(f32 xPos, f32 yPos, f32 zPos, struct FloorGeometr
return floorHeight;
}
@ -169,7 +169,7 @@ index 9aff62f9..9c062cf4 100644
// Check that the point is within the triangle bounds.
if ((z1 - z) * (x2 - x1) - (x1 - x) * (z2 - z1) < 0) {
@@ -422,6 +441,10 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
@@ -423,6 +442,10 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
// To slightly save on computation time, set this later.
x3 = surf->vertex3[0];
z3 = surf->vertex3[2];
@ -180,7 +180,7 @@ index 9aff62f9..9c062cf4 100644
if ((z2 - z) * (x3 - x2) - (x2 - x) * (z3 - z2) < 0) {
continue;
@@ -441,10 +464,30 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
@@ -442,10 +465,30 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
continue;
}
@ -215,7 +215,7 @@ index 9aff62f9..9c062cf4 100644
// If a wall, ignore it. Likely a remnant, should never occur.
if (ny == 0.0f) {
@@ -459,6 +502,15 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
@@ -460,6 +503,15 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
}
*pheight = height;
@ -232,7 +232,7 @@ index 9aff62f9..9c062cf4 100644
break;
}
diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c
index 6936d8a1..b2b7b37a 100644
index ac2ee50..323b7d0 100644
--- a/src/engine/surface_load.c
+++ b/src/engine/surface_load.c
@@ -14,6 +14,7 @@
@ -256,10 +256,10 @@ index 6936d8a1..b2b7b37a 100644
surface->vertex2[0] = x2;
surface->vertex3[0] = x3;
diff --git a/src/game/camera.c b/src/game/camera.c
index 60bfb865..fd910268 100644
index bde0662..9351dea 100644
--- a/src/game/camera.c
+++ b/src/game/camera.c
@@ -483,6 +483,10 @@ CameraTransition sModeTransitions[] = {
@@ -484,6 +484,10 @@ CameraTransition sModeTransitions[] = {
extern u8 sDanceCutsceneIndexTable[][4];
extern u8 sZoomOutAreaMasks[];
@ -270,7 +270,7 @@ index 60bfb865..fd910268 100644
/**
* Starts a camera shake triggered by an interaction
*/
@@ -5502,6 +5506,7 @@ s32 set_camera_mode_fixed(struct Camera *c, s16 x, s16 y, s16 z) {
@@ -5552,6 +5556,7 @@ s32 set_camera_mode_fixed(struct Camera *c, s16 x, s16 y, s16 z) {
c->mode = CAMERA_MODE_FIXED;
vec3f_set(c->pos, sFixedModeBasePosition[0], sMarioCamState->pos[1],
sFixedModeBasePosition[2]);
@ -278,7 +278,7 @@ index 60bfb865..fd910268 100644
}
return basePosSet;
}
@@ -5652,6 +5657,7 @@ BAD_RETURN(s32) cam_rr_enter_building_side(struct Camera *c) {
@@ -5714,6 +5719,7 @@ BAD_RETURN(s32) cam_rr_enter_building_side(struct Camera *c) {
if (c->mode != CAMERA_MODE_FIXED) {
sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT;
c->mode = CAMERA_MODE_FIXED;
@ -286,7 +286,7 @@ index 60bfb865..fd910268 100644
}
}
@@ -5847,6 +5853,7 @@ BAD_RETURN(s32) cam_castle_enter_lobby(struct Camera *c) {
@@ -5909,6 +5915,7 @@ BAD_RETURN(s32) cam_castle_enter_lobby(struct Camera *c) {
sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT;
set_fixed_cam_axis_sa_lobby(c->mode);
c->mode = CAMERA_MODE_FIXED;
@ -294,7 +294,7 @@ index 60bfb865..fd910268 100644
}
}
@@ -7214,6 +7221,7 @@ BAD_RETURN(s32) cutscene_unused_loop(UNUSED struct Camera *c) {
@@ -7279,6 +7286,7 @@ BAD_RETURN(s32) cutscene_unused_loop(UNUSED struct Camera *c) {
BAD_RETURN(s32) cutscene_ending_mario_fall_start(struct Camera *c) {
vec3f_set(c->focus, -26.f, 0.f, -137.f);
vec3f_set(c->pos, 165.f, 4725.f, 324.f);
@ -302,7 +302,7 @@ index 60bfb865..fd910268 100644
}
/**
@@ -7246,6 +7254,7 @@ BAD_RETURN(s32) cutscene_ending_mario_fall(struct Camera *c) {
@@ -7311,6 +7319,7 @@ BAD_RETURN(s32) cutscene_ending_mario_fall(struct Camera *c) {
BAD_RETURN(s32) cutscene_ending_mario_land_closeup(struct Camera *c) {
vec3f_set(c->focus, 85.f, 826.f, 250.f);
vec3f_set(c->pos, -51.f, 988.f, -202.f);
@ -310,7 +310,7 @@ index 60bfb865..fd910268 100644
player2_rotate_cam(c, -0x2000, 0x2000, -0x2000, 0x2000);
}
@@ -7255,6 +7264,7 @@ BAD_RETURN(s32) cutscene_ending_mario_land_closeup(struct Camera *c) {
@@ -7320,6 +7329,7 @@ BAD_RETURN(s32) cutscene_ending_mario_land_closeup(struct Camera *c) {
BAD_RETURN(s32) cutscene_ending_reset_spline(UNUSED struct Camera *c) {
sCutsceneVars[9].point[0] = 0.f;
cutscene_reset_spline();
@ -318,7 +318,7 @@ index 60bfb865..fd910268 100644
}
/**
@@ -7290,6 +7300,7 @@ BAD_RETURN(s32) cutscene_ending_peach_appear_closeup(struct Camera *c) {
@@ -7355,6 +7365,7 @@ BAD_RETURN(s32) cutscene_ending_peach_appear_closeup(struct Camera *c) {
vec3f_set(c->pos, 179.f, 2463.f, -1216.f);
c->pos[1] = gCutsceneFocus->oPosY + 35.f;
vec3f_set(c->focus, gCutsceneFocus->oPosX, gCutsceneFocus->oPosY + 125.f, gCutsceneFocus->oPosZ);
@ -326,7 +326,7 @@ index 60bfb865..fd910268 100644
}
/**
@@ -7308,6 +7319,7 @@ BAD_RETURN(s32) cutscene_ending_peach_appears(struct Camera *c) {
@@ -7373,6 +7384,7 @@ BAD_RETURN(s32) cutscene_ending_peach_appears(struct Camera *c) {
BAD_RETURN(s32) cutscene_ending_peach_descends_start(UNUSED struct Camera *c) {
cutscene_reset_spline();
sCutsceneVars[2].point[1] = 150.f;
@ -334,7 +334,7 @@ index 60bfb865..fd910268 100644
}
/**
@@ -7394,6 +7406,7 @@ BAD_RETURN(s32) cutscene_ending_peach_wakeup(struct Camera *c) {
@@ -7459,6 +7471,7 @@ BAD_RETURN(s32) cutscene_ending_peach_wakeup(struct Camera *c) {
BAD_RETURN(s32) cutscene_ending_dialog(struct Camera *c) {
vec3f_set(c->focus, 11.f, 983.f, -1273.f);
vec3f_set(c->pos, -473.f, 970.f, -1152.f);
@ -342,7 +342,7 @@ index 60bfb865..fd910268 100644
player2_rotate_cam(c, -0x800, 0x2000, -0x2000, 0x2000);
}
@@ -7404,6 +7417,7 @@ BAD_RETURN(s32) cutscene_ending_kiss_closeup(struct Camera *c) {
@@ -7469,6 +7482,7 @@ BAD_RETURN(s32) cutscene_ending_kiss_closeup(struct Camera *c) {
set_fov_function(CAM_FOV_SET_29);
vec3f_set(c->focus, 350.f, 1034.f, -1216.f);
vec3f_set(c->pos, -149.f, 1021.f, -1216.f);
@ -350,7 +350,7 @@ index 60bfb865..fd910268 100644
}
/**
@@ -7439,6 +7453,7 @@ BAD_RETURN(s32) cutscene_ending_kiss(struct Camera *c) {
@@ -7504,6 +7518,7 @@ BAD_RETURN(s32) cutscene_ending_kiss(struct Camera *c) {
BAD_RETURN(s32) cutscene_ending_look_at_sky(struct Camera *c) {
move_point_along_spline(c->focus, sEndingLookAtSkyFocus, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress);
vec3f_set(c->pos, 699.f, 1680.f, -703.f);
@ -358,7 +358,7 @@ index 60bfb865..fd910268 100644
}
/**
@@ -10260,6 +10275,7 @@ BAD_RETURN(s32) cutscene_door_start(struct Camera *c) {
@@ -10340,6 +10355,7 @@ BAD_RETURN(s32) cutscene_door_start(struct Camera *c) {
BAD_RETURN(s32) cutscene_door_fix_cam(struct Camera *c) {
vec3f_copy(c->pos, sCutsceneVars[0].point);
vec3f_copy(c->focus, sCutsceneVars[1].point);
@ -366,7 +366,7 @@ index 60bfb865..fd910268 100644
}
/**
@@ -10293,6 +10309,7 @@ BAD_RETURN(s32) cutscene_door_move_behind_mario(struct Camera *c) {
@@ -10373,6 +10389,7 @@ BAD_RETURN(s32) cutscene_door_move_behind_mario(struct Camera *c) {
}
offset_rotated(c->pos, sMarioCamState->pos, camOffset, sCutsceneVars[0].angle);
@ -375,10 +375,10 @@ index 60bfb865..fd910268 100644
/**
diff --git a/src/game/camera.h b/src/game/camera.h
index f56ed027..2b682ed0 100644
index 173ab8a..b1abdc4 100644
--- a/src/game/camera.h
+++ b/src/game/camera.h
@@ -654,6 +654,8 @@ struct LakituState
@@ -657,6 +657,8 @@ struct LakituState
/// Mario's action from the previous frame. Only used to determine if Mario just finished a dive.
/*0xB8*/ u32 lastFrameAction;
/*0xBC*/ s16 unused;
@ -388,7 +388,7 @@ index f56ed027..2b682ed0 100644
// bss order hack to not affect BSS order. if possible, remove me, but it will be hard to match otherwise
diff --git a/src/game/envfx_bubbles.c b/src/game/envfx_bubbles.c
index 16a92720..ee1b029d 100644
index 16a9272..ee1b029 100644
--- a/src/game/envfx_bubbles.c
+++ b/src/game/envfx_bubbles.c
@@ -35,6 +35,20 @@ Vtx_t gBubbleTempVtx[3] = {
@ -496,7 +496,7 @@ index 16a92720..ee1b029d 100644
gSPDisplayList(sGfxCursor++, &tiny_bubble_dl_0B006AB0);
gSPEndDisplayList(sGfxCursor++);
diff --git a/src/game/envfx_snow.c b/src/game/envfx_snow.c
index c3c14a5c..d2212ef6 100644
index c3c14a5..d2212ef 100644
--- a/src/game/envfx_snow.c
+++ b/src/game/envfx_snow.c
@@ -54,6 +54,26 @@ extern void *tiny_bubble_dl_0B006AB0;
@ -594,7 +594,7 @@ index c3c14a5c..d2212ef6 100644
gSPDisplayList(gfx++, &tiny_bubble_dl_0B006AB0) gSPEndDisplayList(gfx++);
diff --git a/src/game/envfx_snow.h b/src/game/envfx_snow.h
index 7a83b536..f4acc2de 100644
index 7a83b53..f4acc2d 100644
--- a/src/game/envfx_snow.h
+++ b/src/game/envfx_snow.h
@@ -25,7 +25,8 @@ struct EnvFxParticle {
@ -608,10 +608,10 @@ index 7a83b536..f4acc2de 100644
extern s8 gEnvFxMode;
diff --git a/src/game/hud.c b/src/game/hud.c
index 8d4daa54..7ce2b222 100644
index 1540b67..0de6e0b 100644
--- a/src/game/hud.c
+++ b/src/game/hud.c
@@ -57,6 +57,20 @@ static struct UnusedHUDStruct sUnusedHUDValues = { 0x00, 0x0A, 0x00 };
@@ -59,6 +59,20 @@ static struct UnusedHUDStruct sUnusedHUDValues = { 0x00, 0x0A, 0x00 };
static struct CameraHUD sCameraHUD = { CAM_STATUS_NONE };
@ -632,7 +632,7 @@ index 8d4daa54..7ce2b222 100644
/**
* Renders a rgba16 16x16 glyph texture from a table list.
*/
@@ -109,6 +123,7 @@ void render_power_meter_health_segment(s16 numHealthWedges) {
@@ -111,6 +125,7 @@ void render_power_meter_health_segment(s16 numHealthWedges) {
*/
void render_dl_power_meter(s16 numHealthWedges) {
Mtx *mtx;
@ -640,7 +640,7 @@ index 8d4daa54..7ce2b222 100644
mtx = alloc_display_list(sizeof(Mtx));
@@ -116,7 +131,15 @@ void render_dl_power_meter(s16 numHealthWedges) {
@@ -118,7 +133,15 @@ void render_dl_power_meter(s16 numHealthWedges) {
return;
}
@ -658,12 +658,12 @@ index 8d4daa54..7ce2b222 100644
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(mtx++),
G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c
index b9a43df2..281e0f3f 100644
index 7ae9f1e..1c23c96 100644
--- a/src/game/ingame_menu.c
+++ b/src/game/ingame_menu.c
@@ -111,6 +111,41 @@ u8 gMenuHoldKeyIndex = 0;
u8 gMenuHoldKeyTimer = 0;
s32 gDialogResponse = 0;
@@ -130,6 +130,42 @@ s32 gDialogResponse = 0;
static struct CachedChar { u8 used; u8 data[CHCACHE_BUFLEN]; } charCache[256];
#endif // VERSION
+static Gfx *sInterpolatedDialogOffsetPos;
+static f32 sInterpolatedDialogOffset;
@ -700,10 +700,11 @@ index b9a43df2..281e0f3f 100644
+ sInterpolatedDialogZoomPos = NULL;
+ }
+}
+
void create_dl_identity_matrix(void) {
Mtx *matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
@@ -947,6 +982,14 @@ void render_dialog_box_type(struct DialogEntry *dialog, s8 linesPerBox) {
@@ -969,6 +1005,14 @@ void render_dialog_box_type(struct DialogEntry *dialog, s8 linesPerBox) {
switch (gDialogBoxType) {
case DIALOG_TYPE_ROTATE: // Renders a dialog black box with zoom and rotation
if (gDialogBoxState == DIALOG_STATE_OPENING || gDialogBoxState == DIALOG_STATE_CLOSING) {
@ -718,7 +719,7 @@ index b9a43df2..281e0f3f 100644
create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.0 / gDialogBoxScale, 1.0 / gDialogBoxScale, 1.0f);
// convert the speed into angle
create_dl_rotation_matrix(MENU_MTX_NOPUSH, gDialogBoxOpenTimer * 4.0f, 0, 0, 1.0f);
@@ -955,6 +998,12 @@ void render_dialog_box_type(struct DialogEntry *dialog, s8 linesPerBox) {
@@ -977,6 +1021,12 @@ void render_dialog_box_type(struct DialogEntry *dialog, s8 linesPerBox) {
break;
case DIALOG_TYPE_ZOOM: // Renders a dialog white box with zoom
if (gDialogBoxState == DIALOG_STATE_OPENING || gDialogBoxState == DIALOG_STATE_CLOSING) {
@ -731,7 +732,7 @@ index b9a43df2..281e0f3f 100644
create_dl_translation_matrix(MENU_MTX_NOPUSH, 65.0 - (65.0 / gDialogBoxScale),
(40.0 / gDialogBoxScale) - 40, 0);
create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.0 / gDialogBoxScale, 1.0 / gDialogBoxScale, 1.0f);
@@ -1237,6 +1286,8 @@ void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 l
@@ -1259,6 +1309,8 @@ void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 l
#ifdef VERSION_EU
gDialogY -= gDialogScrollOffsetY;
#else
@ -741,7 +742,7 @@ index b9a43df2..281e0f3f 100644
#endif
}
diff --git a/src/game/level_geo.c b/src/game/level_geo.c
index 4c98e705..abc51213 100644
index 4c98e70..abc5121 100644
--- a/src/game/level_geo.c
+++ b/src/game/level_geo.c
@@ -34,12 +34,16 @@ Gfx *geo_envfx_main(s32 callContext, struct GraphNode *node, Mat4 mtxf) {
@ -762,7 +763,7 @@ index 4c98e705..abc51213 100644
}
SET_HIGH_U16_OF_32(*params, gAreaUpdateCounter);
diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c
index 2cc02248..41a26bfc 100644
index 22b45b3..109d7f7 100644
--- a/src/game/object_helpers.c
+++ b/src/game/object_helpers.c
@@ -1554,6 +1554,7 @@ void cur_obj_set_pos_to_home(void) {
@ -774,7 +775,7 @@ index 2cc02248..41a26bfc 100644
void cur_obj_set_pos_to_home_and_stop(void) {
diff --git a/src/game/paintings.c b/src/game/paintings.c
index 205a9eac..9583c64e 100644
index 6cae19c..a304d4a 100644
--- a/src/game/paintings.c
+++ b/src/game/paintings.c
@@ -189,6 +189,32 @@ struct Painting **sPaintingGroups[] = {
@ -851,7 +852,7 @@ index 205a9eac..9583c64e 100644
// Update the ripple, may automatically reset the painting's state.
painting_update_ripple_state(painting);
diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c
index 80dbfca4..b083717f 100644
index d5bf577..71656b4 100644
--- a/src/game/rendering_graph_node.c
+++ b/src/game/rendering_graph_node.c
@@ -39,6 +39,8 @@
@ -1009,7 +1010,7 @@ index 80dbfca4..b083717f 100644
gCurGraphNodeCamFrustum = node;
geo_process_node_and_siblings(node->fnNode.node.children);
@@ -309,6 +380,39 @@ static void geo_process_switch(struct GraphNodeSwitchCase *node) {
@@ -297,6 +368,39 @@ static void geo_process_switch(struct GraphNodeSwitchCase *node) {
}
}
@ -1049,7 +1050,7 @@ index 80dbfca4..b083717f 100644
/**
* Process a camera node.
*/
@@ -316,6 +420,9 @@ static void geo_process_camera(struct GraphNodeCamera *node) {
@@ -304,6 +408,9 @@ static void geo_process_camera(struct GraphNodeCamera *node) {
Mat4 cameraTransform;
Mtx *rollMtx = alloc_display_list(sizeof(*rollMtx));
Mtx *mtx = alloc_display_list(sizeof(*mtx));
@ -1059,7 +1060,7 @@ index 80dbfca4..b083717f 100644
if (node->fnNode.func != NULL) {
node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, gMatStack[gMatStackIndex]);
@@ -326,12 +433,40 @@ static void geo_process_camera(struct GraphNodeCamera *node) {
@@ -314,12 +421,40 @@ static void geo_process_camera(struct GraphNodeCamera *node) {
mtxf_lookat(cameraTransform, node->pos, node->focus, node->roll);
mtxf_mul(gMatStack[gMatStackIndex + 1], cameraTransform, gMatStack[gMatStackIndex]);
@ -1100,7 +1101,7 @@ index 80dbfca4..b083717f 100644
geo_process_node_and_siblings(node->fnNode.node.children);
gCurGraphNodeCamera = NULL;
}
@@ -348,13 +483,17 @@ static void geo_process_translation_rotation(struct GraphNodeTranslationRotation
@@ -336,13 +471,17 @@ static void geo_process_translation_rotation(struct GraphNodeTranslationRotation
Mat4 mtxf;
Vec3f translation;
Mtx *mtx = alloc_display_list(sizeof(*mtx));
@ -1118,7 +1119,7 @@ index 80dbfca4..b083717f 100644
if (node->displayList != NULL) {
geo_append_display_list(node->displayList, node->node.flags >> 8);
}
@@ -373,13 +512,17 @@ static void geo_process_translation(struct GraphNodeTranslation *node) {
@@ -361,13 +500,17 @@ static void geo_process_translation(struct GraphNodeTranslation *node) {
Mat4 mtxf;
Vec3f translation;
Mtx *mtx = alloc_display_list(sizeof(*mtx));
@ -1136,7 +1137,7 @@ index 80dbfca4..b083717f 100644
if (node->displayList != NULL) {
geo_append_display_list(node->displayList, node->node.flags >> 8);
}
@@ -397,12 +540,23 @@ static void geo_process_translation(struct GraphNodeTranslation *node) {
@@ -385,12 +528,23 @@ static void geo_process_translation(struct GraphNodeTranslation *node) {
static void geo_process_rotation(struct GraphNodeRotation *node) {
Mat4 mtxf;
Mtx *mtx = alloc_display_list(sizeof(*mtx));
@ -1160,7 +1161,7 @@ index 80dbfca4..b083717f 100644
if (node->displayList != NULL) {
geo_append_display_list(node->displayList, node->node.flags >> 8);
}
@@ -421,12 +575,16 @@ static void geo_process_scale(struct GraphNodeScale *node) {
@@ -409,12 +563,16 @@ static void geo_process_scale(struct GraphNodeScale *node) {
UNUSED Mat4 transform;
Vec3f scaleVec;
Mtx *mtx = alloc_display_list(sizeof(*mtx));
@ -1177,7 +1178,7 @@ index 80dbfca4..b083717f 100644
if (node->displayList != NULL) {
geo_append_display_list(node->displayList, node->node.flags >> 8);
}
@@ -445,21 +603,30 @@ static void geo_process_scale(struct GraphNodeScale *node) {
@@ -433,21 +591,30 @@ static void geo_process_scale(struct GraphNodeScale *node) {
static void geo_process_billboard(struct GraphNodeBillboard *node) {
Vec3f translation;
Mtx *mtx = alloc_display_list(sizeof(*mtx));
@ -1208,7 +1209,7 @@ index 80dbfca4..b083717f 100644
if (node->displayList != NULL) {
geo_append_display_list(node->displayList, node->node.flags >> 8);
}
@@ -508,13 +675,39 @@ static void geo_process_generated_list(struct GraphNodeGenerated *node) {
@@ -496,13 +663,39 @@ static void geo_process_generated_list(struct GraphNodeGenerated *node) {
*/
static void geo_process_background(struct GraphNodeBackground *node) {
Gfx *list = NULL;
@ -1249,7 +1250,7 @@ index 80dbfca4..b083717f 100644
} else if (gCurGraphNodeMasterList != NULL) {
#ifndef F3DEX_GBI_2E
Gfx *gfxStart = alloc_display_list(sizeof(Gfx) * 7);
@@ -539,61 +732,81 @@ static void geo_process_background(struct GraphNodeBackground *node) {
@@ -527,61 +720,81 @@ static void geo_process_background(struct GraphNodeBackground *node) {
}
}
@ -1365,7 +1366,7 @@ index 80dbfca4..b083717f 100644
if (node->displayList != NULL) {
geo_append_display_list(node->displayList, node->node.flags >> 8);
}
@@ -625,6 +838,17 @@ void geo_set_animation_globals(struct GraphNodeObject_sub *node, s32 hasAnimatio
@@ -613,6 +826,17 @@ void geo_set_animation_globals(struct GraphNodeObject_sub *node, s32 hasAnimatio
}
gCurrAnimFrame = node->animFrame;
@ -1383,7 +1384,7 @@ index 80dbfca4..b083717f 100644
gCurAnimEnabled = (anim->flags & ANIM_FLAG_5) == 0;
gCurrAnimAttribute = segmented_to_virtual((void *) anim->index);
gCurAnimData = segmented_to_virtual((void *) anim->values);
@@ -643,8 +867,10 @@ void geo_set_animation_globals(struct GraphNodeObject_sub *node, s32 hasAnimatio
@@ -631,8 +855,10 @@ void geo_set_animation_globals(struct GraphNodeObject_sub *node, s32 hasAnimatio
*/
static void geo_process_shadow(struct GraphNodeShadow *node) {
Gfx *shadowList;
@ -1394,7 +1395,7 @@ index 80dbfca4..b083717f 100644
Vec3f animOffset;
f32 objScale;
f32 shadowScale;
@@ -652,6 +878,7 @@ static void geo_process_shadow(struct GraphNodeShadow *node) {
@@ -640,6 +866,7 @@ static void geo_process_shadow(struct GraphNodeShadow *node) {
f32 cosAng;
struct GraphNode *geo;
Mtx *mtx;
@ -1402,7 +1403,7 @@ index 80dbfca4..b083717f 100644
if (gCurGraphNodeCamera != NULL && gCurGraphNodeObject != NULL) {
if (gCurGraphNodeHeldObject != NULL) {
@@ -690,21 +917,57 @@ static void geo_process_shadow(struct GraphNodeShadow *node) {
@@ -678,21 +905,57 @@ static void geo_process_shadow(struct GraphNodeShadow *node) {
}
}
@ -1464,7 +1465,7 @@ index 80dbfca4..b083717f 100644
}
gMatStackIndex--;
}
@@ -803,28 +1066,87 @@ static int obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) {
@@ -789,31 +1052,101 @@ static int obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) {
return TRUE;
}
@ -1500,6 +1501,20 @@ index 80dbfca4..b083717f 100644
+ }
+ mtxf_copy(node->header.gfx.prevThrowMatrix, *node->header.gfx.throwMatrix);
+ node->header.gfx.prevThrowMatrixTimestamp = gGlobalTimer;
} else if (node->header.gfx.node.flags & GRAPH_RENDER_CYLBOARD) {
+ Vec3f posInterpolated;
+ if (gGlobalTimer == node->header.gfx.prevTimestamp + 1 &&
+ gGlobalTimer != node->header.gfx.skipInterpolationTimestamp) {
+ interpolate_vectors(posInterpolated, node->header.gfx.prevPos, node->header.gfx.pos);
+ } else {
+ vec3f_copy(posInterpolated, node->header.gfx.pos);
+ }
+ vec3f_copy(node->header.gfx.prevPos, node->header.gfx.pos);
+ node->header.gfx.prevTimestamp = gGlobalTimer;
mtxf_cylboard(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex],
node->header.gfx.pos, gCurGraphNodeCamera->roll);
+ mtxf_cylboard(gMatStackInterpolated[gMatStackIndex + 1], gMatStackInterpolated[gMatStackIndex],
+ posInterpolated, gCurGraphNodeCamera->roll);
} else if (node->header.gfx.node.flags & GRAPH_RENDER_BILLBOARD) {
+ Vec3f posInterpolated;
+ if (gGlobalTimer == node->header.gfx.prevTimestamp + 1 &&
@ -1552,7 +1567,7 @@ index 80dbfca4..b083717f 100644
node->header.gfx.cameraToObject[0] = gMatStack[gMatStackIndex][3][0];
node->header.gfx.cameraToObject[1] = gMatStack[gMatStackIndex][3][1];
node->header.gfx.cameraToObject[2] = gMatStack[gMatStackIndex][3][2];
@@ -835,9 +1157,12 @@ static void geo_process_object(struct Object *node) {
@@ -824,9 +1157,12 @@ static void geo_process_object(struct Object *node) {
}
if (obj_is_in_view(&node->header.gfx, gMatStack[gMatStackIndex])) {
Mtx *mtx = alloc_display_list(sizeof(*mtx));
@ -1565,7 +1580,7 @@ index 80dbfca4..b083717f 100644
if (node->header.gfx.sharedChild != NULL) {
gCurGraphNodeObject = (struct GraphNodeObject *) node;
node->header.gfx.sharedChild->parent = &node->header.gfx.node;
@@ -848,11 +1173,16 @@ static void geo_process_object(struct Object *node) {
@@ -837,11 +1173,16 @@ static void geo_process_object(struct Object *node) {
if (node->header.gfx.node.children != NULL) {
geo_process_node_and_siblings(node->header.gfx.node.children);
}
@ -1582,7 +1597,7 @@ index 80dbfca4..b083717f 100644
}
}
@@ -879,6 +1209,8 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
@@ -868,6 +1209,8 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
Mat4 mat;
Vec3f translation;
Mtx *mtx = alloc_display_list(sizeof(*mtx));
@ -1591,7 +1606,7 @@ index 80dbfca4..b083717f 100644
#ifdef F3DEX_GBI_2
gSPLookAt(gDisplayListHead++, &lookAt);
@@ -894,6 +1226,14 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
@@ -883,6 +1226,14 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
translation[1] = node->translation[1] / 4.0f;
translation[2] = node->translation[2] / 4.0f;
@ -1606,7 +1621,7 @@ index 80dbfca4..b083717f 100644
mtxf_translate(mat, translation);
mtxf_copy(gMatStack[gMatStackIndex + 1], *gCurGraphNodeObject->throwMatrix);
gMatStack[gMatStackIndex + 1][3][0] = gMatStack[gMatStackIndex][3][0];
@@ -902,6 +1242,13 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
@@ -891,6 +1242,13 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
mtxf_mul(gMatStack[gMatStackIndex + 1], mat, gMatStack[gMatStackIndex + 1]);
mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex + 1],
node->objNode->header.gfx.scale);
@ -1620,7 +1635,7 @@ index 80dbfca4..b083717f 100644
if (node->fnNode.func != NULL) {
node->fnNode.func(GEO_CONTEXT_HELD_OBJ, &node->fnNode.node,
(struct AllocOnlyPool *) gMatStack[gMatStackIndex + 1]);
@@ -909,12 +1256,15 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
@@ -898,12 +1256,15 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
gMatStackIndex++;
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
gMatStackFixed[gMatStackIndex] = mtx;
@ -1636,7 +1651,7 @@ index 80dbfca4..b083717f 100644
gCurAnimType = 0;
gCurGraphNodeHeldObject = (void *) node;
if (node->objNode->header.gfx.unk38.curAnim != NULL) {
@@ -929,6 +1279,7 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
@@ -918,6 +1279,7 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
gCurAnimTranslationMultiplier = gGeoTempState.translationMultiplier;
gCurrAnimAttribute = gGeoTempState.attribute;
gCurAnimData = gGeoTempState.data;
@ -1644,7 +1659,7 @@ index 80dbfca4..b083717f 100644
gMatStackIndex--;
}
@@ -1050,6 +1401,7 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
@@ -1039,6 +1401,7 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
if (node->node.flags & GRAPH_RENDER_ACTIVE) {
Mtx *initialMatrix;
Vp *viewport = alloc_display_list(sizeof(*viewport));
@ -1652,7 +1667,7 @@ index 80dbfca4..b083717f 100644
gDisplayListHeap = alloc_only_pool_init(main_pool_available() - sizeof(struct AllocOnlyPool),
MEMORY_POOL_LEFT);
@@ -1060,7 +1412,12 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
@@ -1049,7 +1412,12 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
vec3s_set(viewport->vp.vscale, node->width * 4, node->height * 4, 511);
if (b != NULL) {
clear_frame_buffer(clearColor);
@ -1666,7 +1681,7 @@ index 80dbfca4..b083717f 100644
*viewport = *b;
}
@@ -1068,11 +1425,16 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
@@ -1057,11 +1425,16 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
clear_frame_buffer(clearColor);
make_viewport_clip_rect(c);
}
@ -1685,7 +1700,7 @@ index 80dbfca4..b083717f 100644
G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
gCurGraphNodeRoot = node;
diff --git a/src/game/screen_transition.c b/src/game/screen_transition.c
index 3673a1a8..e65c3bde 100644
index b49ddaf..d6656af 100644
--- a/src/game/screen_transition.c
+++ b/src/game/screen_transition.c
@@ -16,6 +16,19 @@
@ -1721,8 +1736,8 @@ index 3673a1a8..e65c3bde 100644
- return (s16)(result + 0.5);;
+ return (s16)(result + 0.5);
+}
+
}
+#else
+
+s16 calc_tex_transition_radius(s8 fadeTimer, f32 interpolationFraction, s8 transTime, struct WarpTransitionData *transData) {
@ -1732,8 +1747,8 @@ index 3673a1a8..e65c3bde 100644
+ f32 result = transData->startTexRadius + radiusTime;
+
+ return (s16)(result + 0.5);
}
+}
+
+#endif
+
f32 calc_tex_transition_time(s8 fadeTimer, s8 transTime, struct WarpTransitionData *transData) {
@ -1806,7 +1821,7 @@ index 3673a1a8..e65c3bde 100644
switch (transType) {
case WARP_TRANSITION_FADE_FROM_COLOR:
diff --git a/src/menu/intro_geo.c b/src/menu/intro_geo.c
index 2d49d062..31cb72fe 100644
index 37c6752..d823d40 100644
--- a/src/menu/intro_geo.c
+++ b/src/menu/intro_geo.c
@@ -1,5 +1,6 @@
@ -1816,7 +1831,7 @@ index 2d49d062..31cb72fe 100644
#include "game/memory.h"
#include "game/segment2.h"
#include "game/segment7.h"
@@ -68,6 +69,18 @@ s8 gameOverBackgroundTable[] = {
@@ -70,6 +71,18 @@ s8 gameOverBackgroundTable[] = {
s8 gameOverBackgroundFlipOrder[] = { 0x00, 0x01, 0x02, 0x03, 0x07, 0x0B,
0x0a, 0x09, 0x08, 0x04, 0x05, 0x06 };
@ -1835,7 +1850,7 @@ index 2d49d062..31cb72fe 100644
Gfx *geo_title_screen(s32 sp50, struct GraphNode *sp54, UNUSED void *context) {
struct GraphNode *graphNode; // sp4c
Gfx *displayList; // sp48
@@ -78,6 +91,8 @@ Gfx *geo_title_screen(s32 sp50, struct GraphNode *sp54, UNUSED void *context) {
@@ -80,6 +93,8 @@ Gfx *geo_title_screen(s32 sp50, struct GraphNode *sp54, UNUSED void *context) {
f32 scaleX; // sp34
f32 scaleY; // sp30
f32 scaleZ; // sp2c
@ -1844,7 +1859,7 @@ index 2d49d062..31cb72fe 100644
graphNode = sp54;
displayList = NULL;
displayListIter = NULL;
@@ -108,7 +123,11 @@ Gfx *geo_title_screen(s32 sp50, struct GraphNode *sp54, UNUSED void *context) {
@@ -110,7 +125,11 @@ Gfx *geo_title_screen(s32 sp50, struct GraphNode *sp54, UNUSED void *context) {
scaleY = 0.0f;
scaleZ = 0.0f;
}
@ -1858,10 +1873,10 @@ index 2d49d062..31cb72fe 100644
gSPDisplayList(displayListIter++, &intro_seg7_dl_0700B3A0);
gSPPopMatrix(displayListIter++, G_MTX_MODELVIEW);
diff --git a/src/pc/gfx/gfx_dxgi.cpp b/src/pc/gfx/gfx_dxgi.cpp
index 02cdd811..c036e0b7 100644
index 0467495..fa4eb33 100644
--- a/src/pc/gfx/gfx_dxgi.cpp
+++ b/src/pc/gfx/gfx_dxgi.cpp
@@ -34,10 +34,10 @@
@@ -36,10 +36,10 @@
#ifdef VERSION_EU
#define FRAME_INTERVAL_US_NUMERATOR 40000
@ -1874,70 +1889,41 @@ index 02cdd811..c036e0b7 100644
#endif
using namespace Microsoft::WRL; // For ComPtr
diff --git a/src/pc/gfx/gfx_glx.c b/src/pc/gfx/gfx_glx.c
index 97fe4a8b..cd2fa8ff 100644
--- a/src/pc/gfx/gfx_glx.c
+++ b/src/pc/gfx/gfx_glx.c
@@ -19,10 +19,10 @@
#ifdef VERSION_EU
#define FRAME_INTERVAL_US_NUMERATOR 40000
-#define FRAME_INTERVAL_US_DENOMINATOR 1
+#define FRAME_INTERVAL_US_DENOMINATOR 2
#else
#define FRAME_INTERVAL_US_NUMERATOR 100000
-#define FRAME_INTERVAL_US_DENOMINATOR 3
+#define FRAME_INTERVAL_US_DENOMINATOR 6
#endif
const struct {
diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c
index 05f1a5ad..bb8ea052 100644
index 25c9f06..a6461ae 100644
--- a/src/pc/gfx/gfx_sdl2.c
+++ b/src/pc/gfx/gfx_sdl2.c
@@ -137,7 +137,7 @@ int test_vsync(void) {
float average = 4.0 * 1000.0 / (end - start);
@@ -53,7 +53,7 @@ static void (*kb_all_keys_up)(void) = NULL;
// whether to use timer for frame control
static bool use_timer = true;
// time between consequtive game frames
-static const int frame_time = 1000 / FRAMERATE;
+static const int frame_time = 1000 / (2 * FRAMERATE);
vsync_enabled = 1;
- if (average > 27 && average < 33) {
+ /*if (average > 27 && average < 33) {
const SDL_Scancode windows_scancode_table[] = {
/* 0 1 2 3 4 5 6 7 */
@@ -142,7 +142,11 @@ static inline void gfx_sdl_set_vsync(const bool enabled) {
if (enabled) {
// try to detect refresh rate
SDL_GL_SetSwapInterval(1);
} else if (average > 57 && average < 63) {
SDL_GL_SetSwapInterval(2);
@@ -147,6 +147,13 @@ int test_vsync(void) {
SDL_GL_SetSwapInterval(4);
} else {
vsync_enabled = 0;
+ }*/
+ if (average > 57 && average < 63) {
+ SDL_GL_SetSwapInterval(1);
+ } else if (average > 115 && average < 125) {
+ SDL_GL_SetSwapInterval(2);
+ } else {
+ vsync_enabled = 0;
}
}
@@ -271,8 +278,8 @@ static bool gfx_sdl_start_frame(void) {
}
static void sync_framerate_with_timer(void) {
- // Number of milliseconds a frame should take (30 fps)
- const Uint32 FRAME_TIME = 1000 / 30;
+ // Number of milliseconds a frame should take (60 fps)
+ const Uint32 FRAME_TIME = 1000 / 60;
static Uint32 last_time;
Uint32 elapsed = SDL_GetTicks() - last_time;
- const int vblanks = test_vsync();
+ int vblanks = test_vsync();
+ if (vblanks & 1)
+ vblanks = 0; // not divisible by 60, fuck that
+ else
+ vblanks /= 2;
if (vblanks) {
printf("determined swap interval: %d\n", vblanks);
SDL_GL_SetSwapInterval(vblanks);
diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c
index 4fb25fa2..46cf6653 100644
index ed6ee74..63679ad 100644
--- a/src/pc/pc_main.c
+++ b/src/pc/pc_main.c
@@ -75,6 +75,25 @@ void send_display_list(struct SPTask *spTask) {
@@ -83,6 +83,25 @@ void send_display_list(struct SPTask *spTask) {
#define SAMPLES_LOW 528
#endif
+static void patch_interpolations(void) {
+static inline void patch_interpolations(void) {
+ extern void mtx_patch_interpolated(void);
+ extern void patch_screen_transition_interpolated(void);
+ extern void patch_title_screen_scales(void);
@ -1958,16 +1944,16 @@ index 4fb25fa2..46cf6653 100644
+
void produce_one_frame(void) {
gfx_start_frame();
game_loop_one_iteration();
@@ -94,6 +113,11 @@ void produce_one_frame(void) {
@@ -110,6 +129,11 @@ void produce_one_frame(void) {
audio_api->play((u8 *)audio_buffer, 2 * num_audio_samples * 4);
gfx_end_frame();
+
+
+ gfx_start_frame();
+ patch_interpolations();
+ send_display_list(gGfxSPTask);
+ gfx_end_frame();
}
#ifdef TARGET_WEB
void audio_shutdown(void) {

View file

@ -10,52 +10,16 @@ to the source code.
Likewise, to undo the changes from a patch you applied, run
`tools/revert_patch.sh` with the name of the .patch file you wish to undo.
To create your own enhancement patch, switch to the `master` Git
branch, make your changes to the code (but do not commit), then run `tools/create_patch.sh`. Your changes will be stored in the .patch file you specify.
To create your own enhancement patch, switch to the `nightly` Git
branch, make your changes to the code (but do not commit), then run `tools/create_patch.sh`.
Your changes will be stored in the .patch file you specify.
The following enhancements are included in this directory:
## 60 FPS - `60fps.patch`
## 60 FPS - `60fps_ex.patch`
This patch is only supported when not targeting N64. It also currently requires a 64-bit platform. If compiled for a 32-bit platform, the game will run out of memory and crash.
This allows the game to be rendered at 60 FPS instead of 30 FPS by interpolation.
This allows the game to be rendered at 60 FPS instead of 30 FPS by interpolation (game logic still runs at 30 FPS).
The Mario head intro is the only exception which is still rendered at 30 FPS.
## Crash Screen - `crash.patch`
This enhancement provides a crash screen that is displayed when the code throws a hardware exception. This may be useful for diagnosing crashes in game code.
## Debug Box - `debug_box.patch`
This allows you to draw 3D boxes for debugging purposes.
Call the `debug_box` function whenever you want to draw one. `debug_box` by default takes two arguments: a center and bounds vec3f. This will draw a box starting from the point (center - bounds) to (center + bounds).
Use `debug_box_rot` to draw a box rotated in the xz-plane. If you want to draw a box by specifying min and max points, use `debug_box_pos` instead.
## FPS Counter - `fps.patch`
This patch provides an in-game FPS counter to measure the frame rate.
## iQue Player Support - `ique_support.patch`
This enhancement allows the same ROM to work on both the Nintendo 64 and the iQue Player.
## Memory Expansion Pak Error Screen - `mem_error_screen.patch`
Use this patch if your game requires over 4 MB of memory and requires the
Expansion Pak. If the Expansion Pak is not present, an error message will be
shown on startup.
## Demo Input Recorder - `record_demo.patch`
This patch allows you to record gameplay demos for the attract screen. It requires the latest nightly versions of Project64, and uses the Project64 JavaScript API to dump the demo input data from RAM and write it to a file.
Place the `enhancements/RecordDemo.js` file in the `/Scripts/` folder in the Project64 directory.
In the Scripts window, double click on "RecordDemo" on the list on the left side.
When this is done, it should turn green which lets you know that it has started.
When your demo has been recorded, it will be dumped to the newly created `/SM64_DEMOS/` folder within the Project64 directory.
This is the 60fps patch from [sm64-port](https://github.com/sm64-port/sm64-port/tree/master/enhancements) adapted for sm64ex.

View file

@ -1,184 +0,0 @@
/*
* This is a companion file for the record_demo.inc.c enhancement.
*
* You will need the PJ64 javascript API to get this to work, so
* you should download a nightly build from here (Windows only atm):
* https://www.pj64-emu.com/nightly-builds
*
* Place this .js file into the /Scripts/ folder in the PJ64 directory.
*
* In the Scripts window, double click on "RecordDemo" on the list on the left side.
* When this is done, it should turn green which lets you know that it has started.
*
* When your demo has been recorded, it will be dumped to the newly created
* /SM64_DEMOS/ folder within the PJ64 directory.
*/
var RAM_SIZE = 4 * 1048576 // 4 MB
// Get a copy of the first 4MB of memory.
var RAM = mem.getblock(0x80000000, RAM_SIZE)
// Create SM64_DEMOS Directory if it already doesn't exist.
fs.mkdir("SM64_DEMOS/");
// string "DEMORECVARS"
var pattern = [0x44, 0x45, 0x4D, 0x4F, 0x52, 0x45, 0x43, 0x56, 0x41, 0x52, 0x53, 0x00]
var matches = find_matches_fast(pattern)
if(matches.length > 1) {
console.log('Error: More than 1 instance of "DEMORECVARS" was found. Abort!')
} else if(matches.length < 1) {
console.log('Error: No instance of "DEMORECVARS" was found. Abort!')
} else {
console.clear()
var demoRecVarsLocation = 0x80000000 + matches[0] + 12
// Control variables addresses
var gRecordingStatus_vaddr = demoRecVarsLocation + 0
var gDoneDelay_vaddr = demoRecVarsLocation + 4
var gNumOfRecordedInputs_vaddr = demoRecVarsLocation + 8
var gRecordedInputsPtr_vaddr = demoRecVarsLocation + 12
console.log('Recording variables were found at address 0x' + demoRecVarsLocation.toString(16))
console.log('Initialization successful! Press L in-game to ready the demo recording before entering in a level.')
// This runs every frame that is drawn.
events.ondraw(function() {
var gRecordingStatus = mem.u32[gRecordingStatus_vaddr]
if(gRecordingStatus == 3) { // gRecordingStatus == DEMOREC_STATUS_STOPPING
var gNumOfRecordedInputs = mem.u32[gNumOfRecordedInputs_vaddr]
if(gNumOfRecordedInputs < 1) {
console.log('Error: No inputs could be recorded!')
} else {
var gRecordedInputsPtr = mem.u32[gRecordedInputsPtr_vaddr]
console.log('Recorded ' + gNumOfRecordedInputs + ' demo inputs.')
// Grab demo data from RAM.
var demo_data = mem.getblock(gRecordedInputsPtr, (gNumOfRecordedInputs + 1) * 4)
// Create filename with random id added onto it.
var filename = 'SM64_DEMOS/demo_' + get_random_int(0, 0xFFFFFFFF).toString(16) + '.bin'
// Dump demo data to file.
var file = fs.open(filename, 'wb');
fs.write(file, demo_data);
fs.close(file);
console.log('Dumped data to file ' + filename)
}
// Set status to DEMOREC_STATUS_DONE
mem.u32[gRecordingStatus_vaddr] = 4;
// Decomp memes
console.log('OK');
}
})
}
function get_random_int(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
/*
* Finds a byte pattern that is 4-byte aligned.
*
* The javascript api is pretty slow when reading memory directly,
* so I made this to search a copy of RAM to make things a little faster.
*/
function find_matches_fast(pattern) {
var targetLength = pattern.length
var targetLengthMinusOne = targetLength - 1
var matches = []
var matching = 0
// Increments by 8 to speed things up.
for(var i = 0; i < RAM_SIZE; i += 8) {
if(RAM[i] == pattern[matching])
matching++
else
matching = 0
if(matching == targetLength) {
matches.push(i - targetLengthMinusOne)
matching = 0
}
if(matching > 0) {
if(RAM[i + 1] == pattern[matching])
matching++
else
matching = 0
if(matching == targetLength) {
matches.push(i + 1 - targetLengthMinusOne)
matching = 0
}
if(matching > 1) {
if(RAM[i + 2] == pattern[matching])
matching++
else
matching = 0
if(matching == targetLength) {
matches.push(i + 2 - targetLengthMinusOne)
matching = 0
}
if(matching > 2) {
if(RAM[i + 3] == pattern[matching])
matching++
else
matching = 0
if(matching == targetLength) {
matches.push(i + 3 - targetLengthMinusOne)
matching = 0
}
}
}
}
if(RAM[i + 4] == pattern[matching])
matching++
else
matching = 0
if(matching == targetLength) {
matches.push(i + 4 - targetLengthMinusOne)
matching = 0
}
if(matching > 0) {
if(RAM[i + 5] == pattern[matching])
matching++
else
matching = 0
if(matching == targetLength) {
matches.push(i + 5 - targetLengthMinusOne)
matching = 0
}
if(matching > 1) {
if(RAM[i + 6] == pattern[matching])
matching++
else
matching = 0
if(matching == targetLength) {
matches.push(i + 6 - targetLengthMinusOne)
matching = 0
}
if(matching > 2) {
if(RAM[i + 7] == pattern[matching])
matching++
else
matching = 0
if(matching == targetLength) {
matches.push(i + 7 - targetLengthMinusOne)
matching = 0
}
}
}
}
}
return matches
}

View file

@ -1,486 +0,0 @@
diff --git a/asm/crash.s b/asm/crash.s
new file mode 100644
index 00000000..7c272050
--- /dev/null
+++ b/asm/crash.s
@@ -0,0 +1,153 @@
+# SM64 Crash Handler
+# See Readme below.
+
+.include "macros.inc"
+
+/* ---------------------------------------------------------------
+ * IMPORTANT README:
+ * ---------------------------------------------------------------
+ * Frame buffer emulation is required. To enable it in GlideN64,
+ * check "Emulate frame buffer" and "Render frame buffer to output"
+ * in the "Frame buffer" tab.
+ *
+ * Your emulator's CPU core style should be set to interpreter for best results.
+ *
+ * See the DEBUG_ASSERT macro on how to call the crash screen for
+ * detected exceptions.
+ *
+ */
+
+.set noat
+.set noreorder
+.set gp=64
+
+.set COP0_CAUSE, $13
+.set COP0_EPC, $14
+.set COP0_BADVADDR, $8
+
+glabel crashFont
+ .incbin "enhancements/crash_font.bin"
+ .align 4
+
+glabel exceptionRegContext
+ .fill 0x108
+
+glabel pAssertFile
+ .dword 0
+glabel nAssertLine
+ .dword 0
+glabel pAssertExpression
+ .dword 0
+glabel nAssertStopProgram
+ .dword 0
+
+glabel _n64_assert
+ lui $at, %hi(pAssertFile)
+ sw $a0, %lo(pAssertFile)($at)
+ lui $at, %hi(nAssertLine)
+ sw $a1, %lo(nAssertLine)($at)
+ lui $at, %hi(pAssertExpression)
+ sw $a2, %lo(pAssertExpression)($at)
+ lui $at, %hi(nAssertStopProgram)
+ sw $a3, %lo(nAssertStopProgram)($at)
+ beqz $a3, .end_2
+ nop
+ syscall # trigger crash screen
+.end_2:
+ jr $ra
+ nop
+
+glabel cop0_get_cause
+ jr $ra
+ mfc0 $v0, COP0_CAUSE
+
+glabel cop0_get_epc
+ jr $ra
+ mfc0 $v0, COP0_EPC
+
+glabel cop0_get_badvaddr
+ jr $ra
+ mfc0 $v0, COP0_BADVADDR
+
+# If the error code field of cop0's cause register is non-zero,
+# draw crash details to the screen and hang
+#
+# If there wasn't an error, continue to the original handler
+
+glabel __crash_handler_entry
+ mfc0 $k1, COP0_CAUSE
+ andi $k1, $k1, (0x1F << 2)
+ beqzl $k1, .end2 # exit if ExCode is 0
+ lui $k0, %hi(__osException)
+ la $k0, exceptionRegContext
+ sd $zero, 0x018 ($k0)
+ sd $at, 0x020 ($k0)
+ sd $v0, 0x028 ($k0)
+ sd $v1, 0x030 ($k0)
+ sd $a0, 0x038 ($k0)
+ sd $a1, 0x040 ($k0)
+ sd $a2, 0x048 ($k0)
+ sd $a3, 0x050 ($k0)
+ sd $t0, 0x058 ($k0)
+ sd $t1, 0x060 ($k0)
+ sd $t2, 0x068 ($k0)
+ sd $t3, 0x070 ($k0)
+ sd $t4, 0x078 ($k0)
+ sd $t5, 0x080 ($k0)
+ sd $t6, 0x088 ($k0)
+ sd $t7, 0x090 ($k0)
+ sd $s0, 0x098 ($k0)
+ sd $s1, 0x0A0 ($k0)
+ sd $s2, 0x0A8 ($k0)
+ sd $s3, 0x0B0 ($k0)
+ sd $s4, 0x0B8 ($k0)
+ sd $s5, 0x0C0 ($k0)
+ sd $s6, 0x0C8 ($k0)
+ sd $s7, 0x0D0 ($k0)
+ sd $t8, 0x0D8 ($k0)
+ sd $t9, 0x0E0 ($k0)
+ sd $gp, 0x0E8 ($k0)
+ sd $sp, 0x0F0 ($k0)
+ sd $fp, 0x0F8 ($k0)
+ sd $ra, 0x100 ($k0)
+ # cop unusable exception fired twice on startup so we'll ignore it for now
+ li $t0, (0x0B << 2)
+ beq $k1, $t0, .end
+ nop
+ jal show_crash_screen_and_hang
+ nop
+ .end:
+ ld $at, 0x020 ($k0)
+ ld $v0, 0x028 ($k0)
+ ld $v1, 0x030 ($k0)
+ ld $a0, 0x038 ($k0)
+ ld $a1, 0x040 ($k0)
+ ld $a2, 0x048 ($k0)
+ ld $a3, 0x050 ($k0)
+ ld $t0, 0x058 ($k0)
+ ld $t1, 0x060 ($k0)
+ ld $t2, 0x068 ($k0)
+ ld $t3, 0x070 ($k0)
+ ld $t4, 0x078 ($k0)
+ ld $t5, 0x080 ($k0)
+ ld $t6, 0x088 ($k0)
+ ld $t7, 0x090 ($k0)
+ ld $s0, 0x098 ($k0)
+ ld $s1, 0x0A0 ($k0)
+ ld $s2, 0x0A8 ($k0)
+ ld $s3, 0x0B0 ($k0)
+ ld $s4, 0x0B8 ($k0)
+ ld $s5, 0x0C0 ($k0)
+ ld $s6, 0x0C8 ($k0)
+ ld $s7, 0x0D0 ($k0)
+ ld $t8, 0x0D8 ($k0)
+ ld $t9, 0x0E0 ($k0)
+ ld $gp, 0x0E8 ($k0)
+ ld $sp, 0x0F0 ($k0)
+ ld $fp, 0x0F8 ($k0)
+ ld $ra, 0x100 ($k0)
+ lui $k0, %hi(__osException)
+ .end2:
+ addiu $k0, $k0, %lo(__osException)
+ jr $k0 # run the original handler
+ nop
diff --git a/lib/asm/__osExceptionPreamble.s b/lib/asm/__osExceptionPreamble.s
index 865273d9..f9ce7596 100644
--- a/lib/asm/__osExceptionPreamble.s
+++ b/lib/asm/__osExceptionPreamble.s
@@ -15,8 +15,8 @@
.endif
glabel __osExceptionPreamble
- lui $k0, %hi(__osException)
- addiu $k0, %lo(__osException)
+ lui $k0, %hi(__crash_handler_entry)
+ addiu $k0, %lo(__crash_handler_entry)
jr $k0
nop
diff --git a/sm64.ld b/sm64.ld
index e6f5c942..c0feb343
--- a/sm64.ld
+++ b/sm64.ld
@@ -116,6 +116,7 @@ SECTIONS
BUILD_DIR/src/game/rendering_graph_node.o(.text);
BUILD_DIR/src/game/profiler.o(.text);
BUILD_DIR/asm/decompress.o(.text);
+ BUILD_DIR/asm/crash.o(.text);
BUILD_DIR/src/game/camera.o(.text);
BUILD_DIR/src/game/debug_course.o(.text);
BUILD_DIR/src/game/object_list_processor.o(.text);
diff --git a/src/game/crash.c b/src/game/crash.c
new file mode 100644
index 00000000..716adfbd
--- /dev/null
+++ b/src/game/crash.c
@@ -0,0 +1,260 @@
+/* SM64 Crash Handler */
+
+#include <sm64.h>
+
+#include "crash.h"
+
+extern u32 exceptionRegContext[];
+
+extern char *pAssertFile;
+extern int nAssertLine;
+extern char *pAssertExpression;
+extern int nAssertStopProgram;
+
+u16 fbFillColor = 0xFFFF;
+u16 fbShadeColor = 0x0000;
+u16 *fbAddress = NULL;
+
+extern u8 crashFont[];
+
+const char *szErrCodes[] = {
+ "INTERRUPT",
+ "TLB MOD",
+ "UNMAPPED LOAD ADDR",
+ "UNMAPPED STORE ADDR",
+ "BAD LOAD ADDR",
+ "BAD STORE ADDR",
+ "BUS ERR ON INSTR FETCH",
+ "BUS ERR ON LOADSTORE",
+ "SYSCALL",
+ "BREAKPOINT",
+ "UNKNOWN INSTR",
+ "COP UNUSABLE",
+ "ARITHMETIC OVERFLOW",
+ "TRAP EXC",
+ "VIRTUAL COHERENCY INSTR",
+ "FLOAT EXC",
+};
+
+const char *szGPRegisters1[] = { "R0", "AT", "V0", "V1", "A0", "A1", "A2", "A3",
+ "T0", "T1", "T2", "T3", "T4", "T5", "T6", NULL };
+
+const char *szGPRegisters2[] = { "T7", "S0", "S1", "S2", "S3", "S4",
+ "S5", "S6", "S7", "T8", "T9", /*"K0", "K1",*/
+ "GP", "SP", "FP", "RA", NULL };
+
+int crash_strlen(char *str) {
+ int len = 0;
+ while (*str++) {
+ len++;
+ }
+ return len;
+}
+
+void show_crash_screen_and_hang(void) {
+ u32 cause;
+ u32 epc;
+ u8 errno;
+
+ fb_set_address((void *) (*(u32 *) 0xA4400004 | 0x80000000)); // replace me
+
+ cause = cop0_get_cause();
+ epc = cop0_get_epc();
+
+ errno = (cause >> 2) & 0x1F;
+
+ if (nAssertStopProgram == 0) {
+ fbFillColor = 0x6253;
+ fb_fill(10, 10, 300, 220);
+
+ fb_print_str(80, 20, "AN ERROR HAS OCCURRED!");
+ fb_print_int_hex(80, 30, errno, 8);
+ fb_print_str(95, 30, szErrCodes[errno]);
+
+ if (errno >= 2 && errno <= 5) {
+ /*
+ 2 UNMAPPED LOAD ADDR
+ 3 UNMAPPED STORE ADDR
+ 4 BAD LOAD ADDR
+ 5 BAD STORE ADDR
+ */
+ u32 badvaddr = cop0_get_badvaddr();
+
+ fb_print_str(145, 50, "VA");
+ fb_print_int_hex(160, 50, badvaddr, 32);
+ }
+ } else {
+ int afterFileX;
+ int exprBoxWidth;
+ fbFillColor = 0x5263;
+ fb_fill(10, 10, 300, 220);
+
+ fb_print_str(80, 20, "ASSERTION FAILED!");
+
+ afterFileX = fb_print_str(80, 30, pAssertFile);
+ fb_print_str(afterFileX, 30, ":");
+ fb_print_uint(afterFileX + 5, 30, nAssertLine);
+
+ exprBoxWidth = (crash_strlen(pAssertExpression) * 5) + 2;
+ fbFillColor = 0x0001;
+ fb_fill(80 - 1, 40 - 1, exprBoxWidth, 10);
+ fb_print_str(80, 40, pAssertExpression);
+ }
+
+ fb_print_str(80, 50, "PC");
+ fb_print_int_hex(95, 50, epc, 32);
+
+ fb_print_gpr_states(80, 70, szGPRegisters1, &exceptionRegContext[6 + 0]);
+ fb_print_gpr_states(145, 70, szGPRegisters2, &exceptionRegContext[6 + 15 * 2]);
+
+ fb_swap();
+ osWritebackDCacheAll();
+
+ while (1) // hang forever
+ {
+ UNUSED volatile int t = 0; // keep pj64 happy
+ }
+}
+
+u8 ascii_to_idx(char c) {
+ return c - 0x20;
+}
+
+void fb_set_address(void *address) {
+ fbAddress = (u16 *) address;
+}
+
+void fb_swap() {
+ // update VI frame buffer register
+ // todo other registers
+ *(u32 *) (0xA4400004) = (u32) fbAddress & 0x00FFFFFF;
+}
+
+void fb_fill(int baseX, int baseY, int width, int height) {
+ int y, x;
+
+ for (y = baseY; y < baseY + height; y++) {
+ for (x = baseX; x < baseX + width; x++) {
+ fbAddress[y * 320 + x] = fbFillColor;
+ }
+ }
+}
+
+void fb_draw_char(int x, int y, u8 idx) {
+ u16 *out = &fbAddress[y * 320 + x];
+ const u8 *in = &crashFont[idx * 3];
+ int nbyte;
+ int nrow;
+ int ncol;
+
+ for (nbyte = 0; nbyte < 3; nbyte++) {
+ u8 curbyte = in[nbyte];
+ for (nrow = 0; nrow < 2; nrow++) {
+ for (ncol = 0; ncol < 4; ncol++) {
+ u8 px = curbyte & (1 << (7 - (nrow * 4 + ncol)));
+ if (px != 0) {
+ out[ncol] = fbFillColor;
+ }
+ }
+ out += 320;
+ }
+ }
+}
+
+void fb_draw_char_shaded(int x, int y, u8 idx) {
+ fbFillColor = 0x0001;
+ fb_draw_char(x - 1, y + 1, idx);
+
+ fbFillColor = 0xFFFF;
+ fb_draw_char(x, y, idx);
+}
+
+int fb_print_str(int x, int y, const char *str) {
+ while (1) {
+ int yoffs = 0;
+ u8 idx;
+ char c = *str++;
+
+ if (c == '\0') {
+ break;
+ }
+
+ if (c == ' ') {
+ x += 5;
+ continue;
+ }
+
+ switch (c) {
+ case 'j':
+ case 'g':
+ case 'p':
+ case 'q':
+ case 'y':
+ case 'Q':
+ yoffs = 1;
+ break;
+ case ',':
+ yoffs = 2;
+ break;
+ }
+
+ idx = ascii_to_idx(c);
+ fb_draw_char_shaded(x, y + yoffs, idx);
+ x += 5;
+ }
+
+ return x;
+}
+
+void fb_print_int_hex(int x, int y, u32 value, int nbits) {
+ nbits -= 4;
+
+ while (nbits >= 0) {
+ int nib = ((value >> nbits) & 0xF);
+ u8 idx;
+
+ if (nib > 9) {
+ idx = ('A' - 0x20) + (nib - 0xa);
+ } else {
+ idx = ('0' - 0x20) + nib;
+ }
+
+ fb_draw_char_shaded(x, y, idx);
+ x += 5;
+
+ nbits -= 4;
+ }
+}
+
+int fb_print_uint(int x, int y, u32 value) {
+ int nchars = 0;
+
+ int v = value;
+ int i;
+ while (v /= 10) {
+ nchars++;
+ }
+
+ x += nchars * 5;
+
+ for (i = nchars; i >= 0; i--) {
+ fb_draw_char_shaded(x, y, ('0' - 0x20) + (value % 10));
+ value /= 10;
+ x -= 5;
+ }
+
+ return (x + nchars * 5);
+}
+
+void fb_print_gpr_states(int x, int y, const char *regNames[], u32 *regContext) {
+ int i;
+ for (i = 0;; i++) {
+ if (regNames[i] == NULL) {
+ break;
+ }
+
+ fb_print_str(x, y, regNames[i]);
+ fb_print_int_hex(x + 15, y, regContext[i * 2 + 1], 32);
+ y += 10;
+ }
+}
diff --git a/src/game/crash.h b/src/game/crash.h
new file mode 100644
index 00000000..1386930d
--- /dev/null
+++ b/src/game/crash.h
@@ -0,0 +1,28 @@
+#ifndef _CRASH_H_
+#define _CRASH_H_
+
+#include <types.h>
+
+#define CRASH_SCREEN_INCLUDED 1
+
+extern u32 cop0_get_cause(void);
+extern u32 cop0_get_epc(void);
+extern u32 cop0_get_badvaddr(void);
+
+extern void _n64_assert(const char* pFile, int nLine, const char *pExpression, int nStopProgram);
+
+extern u8 __crash_handler_entry[];
+
+void show_crash_screen_and_hang(void);
+u8 ascii_to_idx(char c);
+void fb_set_address(void *address);
+void fb_swap(void);
+void fb_fill(int baseX, int baseY, int width, int height);
+void fb_draw_char(int x, int y, u8 idx);
+void fb_draw_char_shaded(int x, int y, u8 idx);
+int fb_print_str(int x, int y, const char *str);
+int fb_print_uint(int x, int y, u32 value);
+void fb_print_int_hex(int x, int y, u32 value, int nbits);
+void fb_print_gpr_states(int x, int y, const char* regStrs[], u32 *regContext);
+
+#endif /* _CRASH_H_ */

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more