summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAetias <aetias@outlook.com>2024-06-21 11:59:50 +0200
committerAetias <aetias@outlook.com>2024-06-21 11:59:50 +0200
commit4329a6892f959ba97995e36a371c4199fc514d2d (patch)
tree54c49d1bcdd557b80a5371f34b5db9ca8796addd
parent3306a9c7b4c1fe2a0df0549e81ab8ed0f3af5fe2 (diff)
parent925505ed5dc1deb4bd9c3de281233b65dca55016 (diff)
Merge branch 'main' into actor
-rw-r--r--INSTALL.md6
-rw-r--r--Makefile22
-rw-r--r--docs/build_system.md2
-rw-r--r--docs/decompiling.md80
-rw-r--r--docs/images/ghidra_decomp.pngbin0 -> 9695 bytes
-rw-r--r--docs/images/objdiff_function.pngbin0 -> 29981 bytes
-rw-r--r--docs/images/objdiff_match.pngbin0 -> 35154 bytes
-rw-r--r--docs/images/objdiff_objects.pngbin0 -> 11676 bytes
-rw-r--r--docs/images/objdiff_symbols.pngbin0 -> 18567 bytes
-rw-r--r--docs/inline_assembler.md2
-rw-r--r--include/Actor/ActorType.hpp1
-rw-r--r--include/Player/LinkStateRoll.hpp1
-rw-r--r--src/00_Core/Actor/ActorManager.cpp5
-rw-r--r--src/00_Core/Item/Item.cpp4
-rw-r--r--src/00_Core/Map/Course.cpp4
-rw-r--r--src/00_Core/Map/MapBase.cpp4
-rw-r--r--src/00_Core/Map/MapManager.cpp4
-rw-r--r--src/00_Core/Player/LinkStateBase.cpp4
-rw-r--r--src/00_Core/Player/LinkStateDamage.cpp4
-rw-r--r--src/00_Core/Player/LinkStateFollow.cpp4
-rw-r--r--src/00_Core/Player/LinkStateInteract.cpp4
-rw-r--r--src/00_Core/Player/LinkStateItem.cpp4
-rw-r--r--src/00_Core/Player/LinkStateMove.cpp4
-rw-r--r--src/00_Core/Player/LinkStateRoll.cpp4
-rw-r--r--src/00_Core/Player/PlayerBase.cpp4
-rw-r--r--src/00_Core/Player/PlayerControl.cpp4
-rw-r--r--src/00_Core/Player/TouchControl.cpp4
-rw-r--r--src/00_Core/Player/TouchGesture.cpp4
-rw-r--r--src/00_Core/Save/AdventureFlags.cpp4
-rw-r--r--src/14_Land/Actor/ActorRupee.cpp5
-rw-r--r--tools/lcf.py19
-rwxr-xr-xtools/m2ctx.py47
-rw-r--r--tools/mangle.py1
-rw-r--r--tools/objdiff.py19
34 files changed, 118 insertions, 156 deletions
diff --git a/INSTALL.md b/INSTALL.md
index bea8eff4..816f3278 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -12,13 +12,12 @@ Contents:
1. Use one of these platforms:
- Windows (MSYS)
- Linux via WSL
- - Recommended for Windows users
- Linux
2. Install the following:
- Python 3.11+ and pip
- GCC 9+
- Make
- - **On Linux/WSL**: Wine
+ - **On Linux/WSL**: Wine/Wibo
3. Install the Python dependencies:
```shell
python -m pip install -r tools/requirements.txt
@@ -28,6 +27,9 @@ python -m pip install -r tools/requirements.txt
python tools/setup.py
```
+> [!NOTE]
+> For Linux users: If you plan to use Wibo instead of Wine, run make with `make WINE=<path/to/wibo> ...`.
+
## Build the ROM
This repository does not include any of the game's assets, and you will need an original decrypted base ROM.
diff --git a/Makefile b/Makefile
index 0dc3c52a..bf37505a 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@ endif
ifeq ($(OS),Windows_NT)
WINE :=
else
- WINE := wine
+ WINE ?= wine
PYTHON ?= python3.11
endif
@@ -27,11 +27,13 @@ ASSETS_TXT := assets.txt
ASM_FILES := $(shell find asm -name *.s)
CXX_FILES := $(shell find src -name *.cpp) $(shell find libs -name *.cpp)
-C_FILES := $(shell find src -name *.c) $(shell find libs -name *.c)
-ASM_OBJS = $(ASM_FILES:%.s=$(TARGET_DIR)/%.s.o)
-ASM_INCS = $(ASM_FILES:%.s=%.inc)
-CXX_OBJS = $(CXX_FILES:%.cpp=$(TARGET_DIR)/%.cpp.o)
-C_OBJS = $(C_FILES:%.c=$(TARGET_DIR)/%.c.o)
+C_FILES := $(shell find src -name *.c) $(shell find libs -name *.c)
+ASM_OBJS = $(ASM_FILES:%.s=$(TARGET_DIR)/%.s.o)
+ASM_INCS = $(ASM_FILES:%.s=%.inc)
+CXX_OBJS = $(CXX_FILES:%.cpp=$(TARGET_DIR)/%.cpp.o)
+C_OBJS = $(C_FILES:%.c=$(TARGET_DIR)/%.c.o)
+CXX_CTXS = $(CXX_FILES:%.cpp=$(TARGET_DIR)/%.cpp.ctx)
+C_CTXS = $(C_FILES:%.c=$(TARGET_DIR)/%.c.ctx)
OV_BINS := $(wildcard $(TARGET_DIR)/overlays/*.bin)
OV_LZS = $(OV_BINS:%.bin=%.lz)
@@ -124,16 +126,20 @@ $(ASM_OBJS): $(TARGET_DIR)/%.o: %
mkdir -p $(dir $@)
LM_LICENSE_FILE=$(MW_LICENSE) $(WINE) $(MW_ASM) $(ASM_FLAGS) $< -o $@
-$(CXX_OBJS): $(TARGET_DIR)/%.o: %
+$(CXX_OBJS): $(TARGET_DIR)/%.o: % $(TARGET_DIR)/%.ctx
mkdir -p $(dir $@)
LM_LICENSE_FILE=$(MW_LICENSE) $(WINE) $(MW_CC) $(CC_FLAGS) $(CXX_FLAGS) $< -o $@
$(TOOLS_DIR)/elf/elfkill -s $< -e $@
-$(C_OBJS): $(TARGET_DIR)/%.o: %
+$(C_OBJS): $(TARGET_DIR)/%.o: % $(TARGET_DIR)/%.ctx
mkdir -p $(dir $@)
LM_LICENSE_FILE=$(MW_LICENSE) $(WINE) $(MW_CC) $(CC_FLAGS) $(C_FLAGS) $< -o $@
$(TOOLS_DIR)/elf/elfkill -s $< -e $@
+$(CXX_CTXS) $(C_CTXS): $(TARGET_DIR)/%.ctx: %
+ mkdir -p $(dir $@)
+ $(PYTHON) $(TOOLS_DIR)/m2ctx.py -f $@ $<
+
.PHONY: link
link: lcf $(ASM_OBJS) $(CXX_OBJS) $(C_OBJS)
cd $(TARGET_DIR) && LM_LICENSE_FILE=$(MW_LICENSE) $(WINE) $(MW_LD) $(LD_FLAGS) $(LCF_FILE) @$(OBJS_FILE)
diff --git a/docs/build_system.md b/docs/build_system.md
index ee46340f..a81d6e4e 100644
--- a/docs/build_system.md
+++ b/docs/build_system.md
@@ -56,7 +56,7 @@ When the code is linked, all code of the same section will be written adjacent t
## Compiling code
This game was written in C++, so most of the code we decompile will be in this programming language. In C++, we typically don't
have to express which section we want the code to be written to. Instead, the compiler determines the section automatically.
-Here are a few examples of how to
+Here are a few examples of how to generate code for different section types.
- `.text`
- Functions and member functions (aka methods)
diff --git a/docs/decompiling.md b/docs/decompiling.md
index 3ff23f2b..caf723de 100644
--- a/docs/decompiling.md
+++ b/docs/decompiling.md
@@ -20,43 +20,55 @@ again. Remember to make a pull request of any notable progress you made on the s
[non-matching functions](/CONTRIBUTING.md#non-matching-functions).
## Decompiling a source file
-It can be tricky to fully decompile an assembly file into a C/C++ source file, so here's some advice to make it easier:
-- C/C++ code is built before assembly code
- - This means you can take one function from the top of your assembly file, decompile it, and append it to the bottom of
- your C/C++ file.
-- Build the ROM often
- - We recommend building every time you decompile a function.
- - This is because functions can sometimes match in decomp.me, but not when building.
- - If your ROM doesn't match, it's easier to know which function is wrong if it's the only function added since the last
- successful build.
+We use the object diffing tool [`objdiff`](https://github.com/encounter/objdiff) to track differences between C++ and assembly
+code.
+1. [Download the latest release.](https://github.com/encounter/objdiff/releases/latest)
+1. Run `python tools/objdiff.py <EUR|USA>` to generate `objdiff.json` in the project root.
+1. In `objdiff`, set the project directory to the root of this project. This will load `objdiff.json`.
+1. Select your source file in the left sidebar:
+![List of objects in objdiff](images/objdiff_objects.png)
+5. See the list of functions and data to decompile:
+![List of symbols in objdiff](images/objdiff_symbols.png)
+
+> [!NOTE]
+> If a source file is missing in `objdiff`, or `objdiff` fails to build a file, first rerun `objdiff.py` to update
+> `objdiff.json`. If the problem persists, feel free to ask for help.
## Decompiling a function
-Say you've found a function you want to decompile. Here are the steps we recommend for decompiling it:
-1. Visit [decomp.me](https://decomp.me/) and start decomping.
-1. Under the platforms, select "Nintendo DS".
-1. Select compiler preset "Phantom Hourglass".
-1. Copy and paste the target assembly for your function, including the `func_start` and `func_end` macros, and the pool
-constants. For example:
-```arm
- .global func_ov09_0211bf48
- thumb_func_start func_ov09_0211bf48
-func_ov09_0211bf48: ; 0x0211bf48
- ldr r0, _0211bf50 ; =data_ov09_0211f59c
- ldrb r0, [r0]
- bx lr
- nop
- thumb_func_end func_ov09_0211bf48
-_0211bf50: .word data_ov09_0211f59c
+Once you've opened a source file in `objdiff`, you can choose to decompile the functions in any order. We recommend starting
+with a small function if you're unfamiliar with decompilation. Here's an example:
+
+![Function in objdiff](images/objdiff_function.png)
+
+As a starting point, we look at the decompiler output in Ghidra. You can request access to our shared Ghidra project [in this section](#the-ghidra-project).
+
+![Decompiler in Ghidra](images/ghidra_decomp.png)
+
+Looking at this output, we might try writing something like this:
+```cpp
+ARM bool Actor::SetVelocity(Vec3p *vel) {
+ if (mUnk_11b) {
+ mVel = *vel;
+ mUnk_11b = false;
+ return true;
+ }
+ return false;
+}
```
-5. Run `m2ctx.py include/MyHeader.hpp -c` to generate a context and put it in your clipboard.
- - If no suitable header file exists, make a new one and put any structs and types you need in there.
-1. Paste the context into decomp.me, and create the scratch.
-1. Decompile the function and try to get a 100% match.
- - There's no ARM decompiler in decomp.me yet, but Ghidra does the job quite well. See [the Ghidra section](#the-ghidra-project)
- for more info.
- - If you're unable to get a 100% match, share your decomp.me scratch with other contributors and they may assist you.
- - In the worst case, you can also contribute [non-matching functions](/CONTRIBUTING.md#non-matching-functions) to this
- project.
+
+Now we can go back to `objdiff` and look at the result:
+
+![Matching function in objdiff](images/objdiff_match.png)
+
+Success! Note that this was a simple example and that you'll sometimes get stuck on a function. In that case, try the
+following:
+- Decompile a different function and come back later.
+- Export to [decomp.me](https://decomp.me/):
+ 1. Press the `decomp.me` button in `objdiff`.
+ 1. Once you're sent to `decomp.me`, go to "Options" and change the preset to "Phantom Hourglass".
+ 1. Paste your code into the "Source code" tab.
+ 1. Share the link with us!
+- In the worst case, add the function as a [non-matching function](/CONTRIBUTING.md#non-matching-functions).
## Decompiling `.init` functions
> [!NOTE]
diff --git a/docs/images/ghidra_decomp.png b/docs/images/ghidra_decomp.png
new file mode 100644
index 00000000..d54ff6ab
--- /dev/null
+++ b/docs/images/ghidra_decomp.png
Binary files differ
diff --git a/docs/images/objdiff_function.png b/docs/images/objdiff_function.png
new file mode 100644
index 00000000..34e8a164
--- /dev/null
+++ b/docs/images/objdiff_function.png
Binary files differ
diff --git a/docs/images/objdiff_match.png b/docs/images/objdiff_match.png
new file mode 100644
index 00000000..a43726b7
--- /dev/null
+++ b/docs/images/objdiff_match.png
Binary files differ
diff --git a/docs/images/objdiff_objects.png b/docs/images/objdiff_objects.png
new file mode 100644
index 00000000..0bde5aaa
--- /dev/null
+++ b/docs/images/objdiff_objects.png
Binary files differ
diff --git a/docs/images/objdiff_symbols.png b/docs/images/objdiff_symbols.png
new file mode 100644
index 00000000..d1af868b
--- /dev/null
+++ b/docs/images/objdiff_symbols.png
Binary files differ
diff --git a/docs/inline_assembler.md b/docs/inline_assembler.md
index 0ef8d669..72339c4e 100644
--- a/docs/inline_assembler.md
+++ b/docs/inline_assembler.md
@@ -21,7 +21,7 @@ dcd 0x1234
#### `ldconst`: Loads a literal 32-bit value
```asm
-ldconst 0x1234
+ldconst r0, 0x1234
bx lr
```
This code is equivalent to the above example using `dcd`.
diff --git a/include/Actor/ActorType.hpp b/include/Actor/ActorType.hpp
index 7e9e777b..06fd3b59 100644
--- a/include/Actor/ActorType.hpp
+++ b/include/Actor/ActorType.hpp
@@ -140,6 +140,7 @@ struct ActorType {
/* 10 */ ActorType *next;
/* 14 */
+ inline ActorType() {}
ActorType(ActorTypeId id, ActorCreateFunc create, unk32 (*unk_08)());
~ActorType();
unk32 func_0203e7c8();
diff --git a/include/Player/LinkStateRoll.hpp b/include/Player/LinkStateRoll.hpp
index 9ff28899..52b42b43 100644
--- a/include/Player/LinkStateRoll.hpp
+++ b/include/Player/LinkStateRoll.hpp
@@ -42,4 +42,5 @@ public:
void func_ov00_020aee58(s16 param1, u16 param2);
void func_ov00_020aee84();
+ bool func_ov00_020aeeac();
};
diff --git a/src/00_Core/Actor/ActorManager.cpp b/src/00_Core/Actor/ActorManager.cpp
index 613f5f42..472eede2 100644
--- a/src/00_Core/Actor/ActorManager.cpp
+++ b/src/00_Core/Actor/ActorManager.cpp
@@ -1,14 +1,12 @@
#include "Actor/ActorManager.hpp"
-#ifdef STUBS
-
void ActorManager::DeleteActor(u32 index, bool param2) {}
void ActorManager::func_ov00_020c3484(ActorRef *ref, Actor *actor, unk32 param3) {}
void ActorManager::Actor_vfunc_10(u32 param1) {}
Actor* ActorManager::FindActorById(u32 id) {}
Actor* ActorManager::GetActor(ActorRef *ref) {}
bool FilterActor::Filter(Actor *actor) {}
-s32 ActorManager::FilterActors(ActorFilterBase *filter, ActorList *filteredActors) {}
+s32 ActorManager::FilterActors(FilterActorBase *filter, ActorList *filteredActors) {}
void ActorManager::FindActorByType(ActorRef *ref, ActorManager *manager, ActorTypeId type) {}
void ActorManager::FindNearestActorOfType(ActorRef *ref, ActorManager *manager, ActorTypeId type, Vec3p *pos) {}
bool ActorManager::func_ov00_020c398c(u32 index) {}
@@ -20,4 +18,3 @@ void ActorManager::func_ov00_020c3ce8(unk32 param1, unk32 param2) {}
void ActorManager::Actor_vfunc_28() {}
bool ActorManager::ActorTypeIsOneOf(u32 type, ActorTypeId *types) {}
-#endif
diff --git a/src/00_Core/Item/Item.cpp b/src/00_Core/Item/Item.cpp
index 522dd51d..817d86db 100644
--- a/src/00_Core/Item/Item.cpp
+++ b/src/00_Core/Item/Item.cpp
@@ -1,8 +1,4 @@
#include "Item/Item.hpp"
-#ifdef STUBS
-
bool Item::func_ov00_020ad020(ItemId item) {}
bool Item::func_ov00_020ad068(ItemId item) {}
-
-#endif
diff --git a/src/00_Core/Map/Course.cpp b/src/00_Core/Map/Course.cpp
index 560169e8..316b05ee 100644
--- a/src/00_Core/Map/Course.cpp
+++ b/src/00_Core/Map/Course.cpp
@@ -1,7 +1,5 @@
#include "Map/Course.hpp"
-#ifdef STUBS
-
void Course::GetDungeonProgress(CourseProgress *param_2) {}
void Course::func_ov00_0207ca28(s32 param_2, unk32 param_3, unk32 param_4) {}
char* Course::SetCourseName(char *src) {}
@@ -51,5 +49,3 @@ void Course::SetMapDataFlag4(unk32 param_2, unk32 param_3) {}
bool Course::GetMapDataFlag4(unk32 param_2) {}
MapData* Course::FindMapData(u32 map) {}
MapData* Course::FindCurrentMapData() {}
-
-#endif
diff --git a/src/00_Core/Map/MapBase.cpp b/src/00_Core/Map/MapBase.cpp
index 5a5ed636..1afc8c29 100644
--- a/src/00_Core/Map/MapBase.cpp
+++ b/src/00_Core/Map/MapBase.cpp
@@ -1,8 +1,6 @@
#include "Map/MapBase.hpp"
#include "Map/MapManager.hpp"
-#ifdef STUBS
-
MapBase::~MapBase() {}
MapBase_Unk_180::~MapBase_Unk_180() {}
void MapBase::SetBounds(unk32 map, unk32 course) {}
@@ -112,5 +110,3 @@ unk32 TriggerBase::vfunc_10() {}
void MapBase::func_ov00_02080de4() {}
unk8 MapBase::func_ov00_02080de8(unk32 param_2) {}
void MapBase::func_ov00_02080edc() {}
-
-#endif
diff --git a/src/00_Core/Map/MapManager.cpp b/src/00_Core/Map/MapManager.cpp
index 61dd5564..6305418e 100644
--- a/src/00_Core/Map/MapManager.cpp
+++ b/src/00_Core/Map/MapManager.cpp
@@ -1,7 +1,5 @@
#include "Map/MapManager.hpp"
-#ifdef STUBS
-
void MapManager::func_ov00_020820ec(unk32 *param_2) {}
void MapManager::func_ov00_020820fc(s32 param_2, unk32 param_3, unk32 param_4) {}
unk8 MapManager::func_ov00_0208210c(unk32 param_2, unk32 param_3) {}
@@ -200,5 +198,3 @@ unk8 MapManager::func_ov00_02085c60(unk32 param_2, unk32 param_3, unk32 param_4,
unk8 MapManager::func_ov00_02086044(unk32 param_2, unk32 param_3, unk32 param_4) {}
bool MapManager::func_ov00_02086284(s32 *param_2, Vec3p *param_3, Vec3p *param_4, s32 param_5, u16 param_6, Vec3p *param_7, Vec3p *param_8) {}
bool MapManager::func_ov00_02086a84(s32 *param_2, Vec3p *param_3, Vec3p *param_4, s32 param_5, s32 param_6, unk32 param_7, Vec3p *param_8, Vec3p *param_9) {}
-
-#endif
diff --git a/src/00_Core/Player/LinkStateBase.cpp b/src/00_Core/Player/LinkStateBase.cpp
index 482a8371..abe7bd34 100644
--- a/src/00_Core/Player/LinkStateBase.cpp
+++ b/src/00_Core/Player/LinkStateBase.cpp
@@ -1,7 +1,5 @@
#include "Player/LinkStateBase.hpp"
-#ifdef STUBS
-
void LinkStateBase::vfunc_00() {}
void LinkStateBase::OnStateEnter() {}
void LinkStateBase::OnStateLeave(s32 param1) {}
@@ -85,5 +83,3 @@ unk32 LinkStateBase::Get_PlayerControlData_Unk120() {}
s32 LinkStateBase::Get_PlayerLinkBase_Unk38() {}
DebugHierarchy* LinkStateBase::GetDebugHierarchy0() {}
DebugHierarchy* LinkStateBase::GetDebugHierarchy1() {}
-
-#endif
diff --git a/src/00_Core/Player/LinkStateDamage.cpp b/src/00_Core/Player/LinkStateDamage.cpp
index 84674461..c544b154 100644
--- a/src/00_Core/Player/LinkStateDamage.cpp
+++ b/src/00_Core/Player/LinkStateDamage.cpp
@@ -1,7 +1,5 @@
#include "Player/LinkStateDamage.hpp"
-#ifdef STUBS
-
void LinkStateDamage::vfunc_00() {}
void LinkStateDamage::CreateDebugHierarchy() {}
void LinkStateDamage::OnStateEnter() {}
@@ -16,5 +14,3 @@ bool LinkStateDamage::vfunc_24(s32 param1) {}
bool LinkStateDamage::vfunc_20(s32 param1) {}
void LinkStateDamage::func_ov00_020acfe8(bool param1) {}
LinkStateId LinkStateDamage::GetId() {}
-
-#endif
diff --git a/src/00_Core/Player/LinkStateFollow.cpp b/src/00_Core/Player/LinkStateFollow.cpp
index 54e87938..69d173dd 100644
--- a/src/00_Core/Player/LinkStateFollow.cpp
+++ b/src/00_Core/Player/LinkStateFollow.cpp
@@ -1,7 +1,5 @@
#include "Player/LinkStateFollow.hpp"
-#ifdef STUBS
-
void LinkStateFollow::vfunc_00() {}
LinkStateId LinkStateFollow::GetId() {}
void LinkStateFollow::MoveTowardTarget() {}
@@ -12,5 +10,3 @@ LinkStateCutscene* LinkStateFollow::GetLinkStateCutscene() {}
bool LinkStateFollow::vfunc_34(Vec3p *param1) {}
bool LinkStateFollow::func_ov00_020a9180(Vec3p *param1) {}
bool LinkStateFollow::func_ov00_020a9210(Vec3p *param1, Actor *param2) {}
-
-#endif
diff --git a/src/00_Core/Player/LinkStateInteract.cpp b/src/00_Core/Player/LinkStateInteract.cpp
index a3a7ddca..6cbda713 100644
--- a/src/00_Core/Player/LinkStateInteract.cpp
+++ b/src/00_Core/Player/LinkStateInteract.cpp
@@ -1,7 +1,5 @@
#include "Player/LinkStateInteract.hpp"
-#ifdef STUBS
-
void LinkStateInteract::vfunc_00() {}
LinkStateId LinkStateInteract::GetId() {}
void LinkStateInteract::CreateDebugHierarchy() {}
@@ -30,5 +28,3 @@ void LinkStateInteract::func_ov00_020abbdc(ActorRef *ref) {}
void LinkStateInteract::func_ov00_020abc18(ActorRef *ref) {}
bool LinkStateInteract::func_ov00_020abc40() {}
bool LinkStateInteract::func_ov00_020abc78(ActorRef *ref) {}
-
-#endif
diff --git a/src/00_Core/Player/LinkStateItem.cpp b/src/00_Core/Player/LinkStateItem.cpp
index 1faf16ab..eaf3c8b6 100644
--- a/src/00_Core/Player/LinkStateItem.cpp
+++ b/src/00_Core/Player/LinkStateItem.cpp
@@ -1,7 +1,5 @@
#include "Player/LinkStateItem.hpp"
-#ifdef STUBS
-
void LinkStateItem::vfunc_00() {}
LinkStateId LinkStateItem::GetId() {}
s32 LinkStateItem::IsHammerEquipped() {}
@@ -10,5 +8,3 @@ EquipBombchu* LinkStateItem::GetEquipBombchu() {}
LinkStateMove* LinkStateItem::GetLinkStateMove() {}
bool LinkStateItem::func_ov00_020abf70() {}
bool LinkStateItem::vfunc_28() {}
-
-#endif
diff --git a/src/00_Core/Player/LinkStateMove.cpp b/src/00_Core/Player/LinkStateMove.cpp
index 586a331e..918a92fe 100644
--- a/src/00_Core/Player/LinkStateMove.cpp
+++ b/src/00_Core/Player/LinkStateMove.cpp
@@ -1,7 +1,5 @@
#include "Player/LinkStateMove.hpp"
-#ifdef STUBS
-
void LinkStateMove::vfunc_00() {}
LinkStateId LinkStateMove::GetId() {}
void LinkStateMove::CreateDebugHierarchy() {}
@@ -10,5 +8,3 @@ void LinkStateMove::OnStateLeave(s32 param1) {}
bool LinkStateMove::vfunc_24(s32 param1) {}
bool LinkStateMove::func_ov00_020a8f2c() {}
bool LinkStateMove::func_ov00_020a8f4c() {}
-
-#endif
diff --git a/src/00_Core/Player/LinkStateRoll.cpp b/src/00_Core/Player/LinkStateRoll.cpp
index d6a93463..91044e21 100644
--- a/src/00_Core/Player/LinkStateRoll.cpp
+++ b/src/00_Core/Player/LinkStateRoll.cpp
@@ -1,7 +1,5 @@
#include "Player/LinkStateRoll.hpp"
-#ifdef STUBS
-
void LinkStateRoll::vfunc_00() {}
LinkStateId LinkStateRoll::GetId() {}
void LinkStateRoll::CreateDebugHierarchy() {}
@@ -12,5 +10,3 @@ bool LinkStateRoll::vfunc_24(s32 param1) {}
void LinkStateRoll::func_ov00_020aee58(s16 param1, u16 param2) {}
void LinkStateRoll::func_ov00_020aee84() {}
bool LinkStateRoll::func_ov00_020aeeac() {}
-
-#endif
diff --git a/src/00_Core/Player/PlayerBase.cpp b/src/00_Core/Player/PlayerBase.cpp
index dfdb4eb5..fc5c92fb 100644
--- a/src/00_Core/Player/PlayerBase.cpp
+++ b/src/00_Core/Player/PlayerBase.cpp
@@ -1,7 +1,5 @@
#include "Player/PlayerLinkBase.hpp"
-#ifdef STUBS
-
bool PlayerBase::vfunc_04() {}
ItemFlag PlayerBase::GetEquipId() {}
bool PlayerBase::CanMove() {}
@@ -20,5 +18,3 @@ void PlayerBase::AddHealth(s16 amount) {}
bool PlayerBase::Teleport(Vec3p *pos, s16 angle, unk32 param3, bool param4, bool param5) {}
bool PlayerBase::TeleportToEntrance(unk32 entranceId, bool param2) {}
bool PlayerBase::TeleportToLastEntrance(bool param1) {}
-
-#endif
diff --git a/src/00_Core/Player/PlayerControl.cpp b/src/00_Core/Player/PlayerControl.cpp
index 48c52e7a..f51d0a89 100644
--- a/src/00_Core/Player/PlayerControl.cpp
+++ b/src/00_Core/Player/PlayerControl.cpp
@@ -1,7 +1,5 @@
#include "Player/PlayerControl.hpp"
-#ifdef STUBS
-
bool PlayerControl::func_ov00_020aeeac() {}
void PlayerControl::func_ov00_020aeef8() {}
void PlayerControl::func_ov00_020aef30() {}
@@ -52,5 +50,3 @@ bool PlayerControl::IsNotTouching() {}
bool PlayerControl::IsTouchingFast() {}
bool PlayerControl::IsTappedNow() {}
bool PlayerControl::func_ov00_020b13c4() {}
-
-#endif
diff --git a/src/00_Core/Player/TouchControl.cpp b/src/00_Core/Player/TouchControl.cpp
index df8bbfe0..5cae75a5 100644
--- a/src/00_Core/Player/TouchControl.cpp
+++ b/src/00_Core/Player/TouchControl.cpp
@@ -1,7 +1,5 @@
#include "Player/TouchControl.hpp"
-#ifdef STUBS
-
TouchControl::TouchControl() {}
void TouchControl::IncreaseSpeed(s16 increase) {}
void TouchControl::UpdateFlags(u16 speed) {}
@@ -11,5 +9,3 @@ bool TouchControl::func_ov00_0207aeac() {}
void TouchControl::UpdateConditionally(TouchState *state, u16 speed) {}
void TouchControl::func_ov00_0207af38(u16 speed, bool param2) {}
TouchControl::~TouchControl() {}
-
-#endif
diff --git a/src/00_Core/Player/TouchGesture.cpp b/src/00_Core/Player/TouchGesture.cpp
index 83879415..027e3e0a 100644
--- a/src/00_Core/Player/TouchGesture.cpp
+++ b/src/00_Core/Player/TouchGesture.cpp
@@ -1,7 +1,5 @@
#include "Player/TouchGesture.hpp"
-#ifdef STUBS
-
TouchGesture::TouchGesture() {}
void TouchGesture::ResetTouchHistory() {}
void TouchGesture::Update(void *param1) {}
@@ -9,5 +7,3 @@ TouchGesture::~TouchGesture() {}
void TouchGestureBase::ResetTouchHistory() {}
TouchGestureBase::~TouchGestureBase() {}
-
-#endif STUBS
diff --git a/src/00_Core/Save/AdventureFlags.cpp b/src/00_Core/Save/AdventureFlags.cpp
index dd05dff6..14f377c1 100644
--- a/src/00_Core/Save/AdventureFlags.cpp
+++ b/src/00_Core/Save/AdventureFlags.cpp
@@ -1,7 +1,5 @@
#include "Save/AdventureFlags.hpp"
-#ifdef STUBS
-
bool AdventureFlags::Exists() {}
void AdventureFlags::CopyTo(unk32 *flags) {}
void AdventureFlags::func_ov00_02097674() {}
@@ -50,5 +48,3 @@ bool AdventureFlags::func_ov00_0209809c() {}
bool AdventureFlags::func_ov00_020980ac() {}
void AdventureFlags::func_ov00_020980bc(s32 param1) {}
void AdventureFlags::func_ov00_020980d0() {}
-
-#endif
diff --git a/src/14_Land/Actor/ActorRupee.cpp b/src/14_Land/Actor/ActorRupee.cpp
index 20d98de4..5288f3bd 100644
--- a/src/14_Land/Actor/ActorRupee.cpp
+++ b/src/14_Land/Actor/ActorRupee.cpp
@@ -1,8 +1,5 @@
#include "Actor/ActorRupee.hpp"
-#ifdef STUBS
-
-Resource ActorRupee::gResource;
ActorType ActorRupee::gType;
ActorRupee* ActorRupee::Create() {}
@@ -21,5 +18,3 @@ void ActorRupee::func_ov14_0213b5f4(RupeeId id, unk32 param2, Vec3p *param3, boo
void ActorRupee::func_ov14_0213b6a4(RupeeId id, void *param2) {}
bool ActorRupee::func_ov14_0213b70c(RupeeId id) {}
ActorRupee::~ActorRupee() {}
-
-#endif
diff --git a/tools/lcf.py b/tools/lcf.py
index a352fadb..7a37598e 100644
--- a/tools/lcf.py
+++ b/tools/lcf.py
@@ -33,63 +33,45 @@ DTCM_OBJECTS = [
ov00 = Overlay(name='ov00', after='ARM9', objects=[
'asm/ov00/ov00_020773c0.s',
- 'src/00_Core/Player/TouchControl.cpp',
'asm/ov00/Player/TouchControl.s',
'asm/ov00/ov00_0207afa0.s',
'asm/ov00/Map/Course.s',
- 'src/00_Core/Map/Course.cpp',
'asm/ov00/Map/MapBase.s',
- 'src/00_Core/Map/MapBase.cpp',
'asm/ov00/ov00_0207da38.s',
'asm/ov00/Map/MapManager.s',
- 'src/00_Core/Map/MapManager.cpp',
'asm/ov00/ov00_02086cd0.s',
- 'src/00_Core/Save/AdventureFlags.cpp',
'asm/ov00/Save/AdventureFlags.s',
'asm/ov00/ov00_020980f4.s',
- 'src/00_Core/Player/PlayerBase.cpp',
'asm/ov00/Player/PlayerBase.s',
- 'src/00_Core/Player/LinkStateBase.cpp',
'asm/ov00/Player/LinkStateBase.s',
- 'src/00_Core/Player/LinkStateMove.cpp',
'asm/ov00/Player/LinkStateMove.s',
- 'src/00_Core/Player/LinkStateFollow.cpp',
'asm/ov00/Player/LinkStateFollow.s',
- 'src/00_Core/Player/TouchGesture.cpp',
'asm/ov00/Player/TouchGesture.s',
'asm/ov00/ov00_020a8e04.s',
- 'src/00_Core/Player/LinkStateInteract.cpp',
'asm/ov00/Player/LinkStateInteract.s',
- 'src/00_Core/Player/LinkStateItem.cpp',
'asm/ov00/Player/LinkStateItem.s',
- 'src/00_Core/Player/LinkStateDamage.cpp',
'asm/ov00/Player/LinkStateDamage.s',
- 'src/00_Core/Item/Item.cpp',
'asm/ov00/Item/Item.s',
'src/00_Core/Item/ItemManager.cpp',
- 'src/00_Core/Player/LinkStateRoll.cpp',
'asm/ov00/Player/LinkStateRoll.s',
- 'src/00_Core/Player/PlayerControl.cpp',
'asm/ov00/Player/PlayerControl.s',
'asm/ov00/ov00_020b1498.s',
- # 'src/00_Core/Actor/Actor.cpp',
'asm/ov00/Actor/Actor.s',
'asm/ov00/ov00_020c3348.s',
- 'src/00_Core/Actor/ActorManager.cpp',
'asm/ov00/Actor/ActorManager.s',
'asm/ov00/ov00_020c3e54.s',
@@ -136,7 +118,6 @@ ov13 = Overlay(name='ov13', after=[ov04, ov05, ov06, ov07], objects=[
ov14 = Overlay(name='ov14', after=[ov08, ov09, ov10, ov13], objects=[
'asm/ov14/ov14_0211f640.s',
- 'src/14_Land/Actor/ActorRupee.cpp',
'asm/ov14/Actor/ActorRupee.s',
'asm/ov14/ov14_0213b778.s',
diff --git a/tools/m2ctx.py b/tools/m2ctx.py
index 299d1834..24e12d7a 100755
--- a/tools/m2ctx.py
+++ b/tools/m2ctx.py
@@ -6,6 +6,8 @@ import subprocess
import os
from pathlib import Path
import argparse
+import re
+import tempfile
parser = argparse.ArgumentParser(description="Generates a context for decomp.me")
parser.add_argument('file', help="Input file to preprocess")
@@ -28,19 +30,40 @@ root_dir = script_dir / ".."
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
-try:
- ctx: str = subprocess.check_output([
- 'gcc',
- '-E', '-P', '-fworking-directory', '-undef', '-dD',
- *CXX_FLAGS,
- args.file
- ], cwd=root_dir, encoding=args.encoding)
-except subprocess.CalledProcessError as e:
- eprint(f"Failed to preprocess '{args.file}'")
- if args.verbose: eprint(e)
- else: eprint("Use -v for more verbose error output")
- exit(1)
+# Finds all lines starting with #include followed by <...> or "..."
+INCLUDE_REGEX = r'^\s*#\s*include\s*([<"][\S ]+[>"])\s*$'
+# Finds all line comments and multiline comments
+COMMENT_REGEX = r'\/\/.*$|\/\*(?:.|\r|\n)+?\*\/'
+# Finds all lines from #ifndef NONMATCHING to #else
+NONMATCH_REGEX = r'^\s*#\s*ifndef\s*NONMATCHING\s*(?:.|\r|\n)*\n\s*#\s*else\s*$'
+with open(args.file, 'r') as f:
+ contents = f.read()
+contents = re.sub(COMMENT_REGEX, '', contents, 0, re.MULTILINE)
+contents = re.sub(NONMATCH_REGEX, '', contents, 0, re.MULTILINE)
+includes = re.findall(INCLUDE_REGEX, contents, re.MULTILINE)
+
+_, suffix = os.path.splitext(args.file)
+
+with tempfile.NamedTemporaryFile(delete=True, suffix=suffix) as tmp_file:
+ # Write includes
+ for include in includes:
+ tmp_file.write(f'#include {include}\n'.encode())
+ tmp_file.flush()
+
+ # Run preprocessor
+ try:
+ ctx: str = subprocess.check_output([
+ 'gcc',
+ '-E', '-P', '-fworking-directory', '-undef', '-dD',
+ *CXX_FLAGS,
+ tmp_file.name
+ ], cwd=root_dir, encoding=args.encoding)
+ except subprocess.CalledProcessError as e:
+ eprint(f"Failed to preprocess '{args.file}'")
+ if args.verbose: eprint(e)
+ else: eprint("Use -v for more verbose error output")
+ exit(1)
lines = ctx.splitlines(True)
for i in reversed(range(len(lines))):
diff --git a/tools/mangle.py b/tools/mangle.py
index a9bfcadf..d14bec54 100644
--- a/tools/mangle.py
+++ b/tools/mangle.py
@@ -38,7 +38,6 @@ cc.extend([
'-i', include_dir,
'-i', libc_include_dir,
'-i', libcpp_include_dir,
- '-DSTUBS',
args.file
])
diff --git a/tools/objdiff.py b/tools/objdiff.py
index 80f91ca4..16078798 100644
--- a/tools/objdiff.py
+++ b/tools/objdiff.py
@@ -35,16 +35,16 @@ def find_asm_path(src_path: Path) -> Path | None:
return asm_path
-def get_build_path(path: Path) -> Path:
+def get_build_path(path: Path, extension='.o') -> Path:
region = args.region.lower()
- return Path('build') / region / path.parent / (path.name + '.o')
+ return Path('build') / region / path.parent / (path.name + extension)
config = dict()
config["custom_make"] = "make"
config["custom_args"] = [
- f"REGION={args.region}",
- "-B" # Always build target
+ "-B",
+ f"REGION={args.region}"
]
config["build_target"] = True
config["watch_patterns"] = [
@@ -62,6 +62,7 @@ for (root, dirs, files) in os.walk(src_dir):
src_path = Path(f'{root}/{file}')
src_path = src_path.relative_to(src_dir)
asm_path = find_asm_path(src_path)
+ src_path = 'src' / src_path
if asm_path: asm_path = 'asm' / asm_path
@@ -70,9 +71,17 @@ for (root, dirs, files) in os.walk(src_dir):
obj = dict()
obj["name"] = name
if asm_path.exists(): obj["target_path"] = str(get_build_path(asm_path))
- obj["base_path"] = str(get_build_path('src' / src_path))
+ obj["base_path"] = str(get_build_path(src_path))
obj["reverse_fn_order"] = False
+ scratch = dict()
+ scratch["platform"] = "nds_arm9"
+ scratch["compiler"] = "mwcc_30_131"
+ scratch["ctx_path"] = str(get_build_path(src_path, '.ctx'))
+ scratch["build_ctx"] = True
+
+ obj["scratch"] = scratch
+
config["objects"].append(obj)
with open(config_path, 'w') as f: