diff --git a/Makefile b/Makefile index 7e942ece2..50dd38931 100644 --- a/Makefile +++ b/Makefile @@ -986,6 +986,12 @@ else endif endif +IS_DEV_OR_DEBUG := $(or $(filter 1,$(DEVELOPMENT)),$(filter 1,$(DEBUG))) +ifeq ($(IS_DEV_OR_DEBUG),0) + CFLAGS += -fno-ident -fno-common -fno-asynchronous-unwind-tables -ffile-prefix-map=$(PWD)=. -D__DATE__="\"\"" -D__TIME__="\"\"" -Wno-builtin-macro-redefined + LDFLAGS += -Wl,--build-id=none -Wl,--no-randomize-sections +endif + # Prevent a crash with -sopt export LANG := C diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index 7d1ee3f53..8ca6ce3e9 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -7953,12 +7953,29 @@ function get_water_surface_pseudo_floor() -- ... end +--- @param data Pointer_Collision +function smlua_collision_util_find_surface_types(data) + -- ... +end + --- @param name string --- @return Pointer_Collision function smlua_collision_util_get(name) -- ... end +--- @return Pointer_Collision +function smlua_collision_util_get_current_terrain_collision() + -- ... +end + +--- @param level integer +--- @param area integer +--- @return Pointer_Collision +function smlua_collision_util_get_level_collision(level, area) + -- ... +end + --- @param audio ModAudio --- @return number function audio_stream_get_tempo(audio) diff --git a/data/dynos.c.h b/data/dynos.c.h index ad7c9eca1..5f0314198 100644 --- a/data/dynos.c.h +++ b/data/dynos.c.h @@ -64,6 +64,7 @@ void dynos_level_parse_script(const void *script, s32 (*aPreprocessFunction)(u8, void* dynos_level_get_script(s32 level); s32 dynos_level_get_mod_index(s32 level); bool dynos_level_is_vanilla_level(s32 level); +Collision *dynos_level_get_collision(u32 level, u16 area); // -- behaviors -- // void dynos_add_behavior(s32 modIndex, const char *filePath, const char *behaviorName); diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h index 9e398bf90..147e43a5e 100644 --- a/data/dynos.cpp.h +++ b/data/dynos.cpp.h @@ -819,6 +819,7 @@ void DynOS_Level_Unoverride(); const void *DynOS_Level_GetScript(s32 aLevel); s32 DynOS_Level_GetModIndex(s32 aLevel); bool DynOS_Level_IsVanillaLevel(s32 aLevel); +Collision *DynOS_Level_GetCollision(u32 aLevel, u16 aArea); s16 *DynOS_Level_GetWarp(s32 aLevel, s32 aArea, u8 aWarpId); s16 *DynOS_Level_GetWarpEntry(s32 aLevel, s32 aArea); s16 *DynOS_Level_GetWarpDeath(s32 aLevel, s32 aArea); diff --git a/data/dynos_c.cpp b/data/dynos_c.cpp index a28b1577d..3086d2316 100644 --- a/data/dynos_c.cpp +++ b/data/dynos_c.cpp @@ -210,6 +210,10 @@ bool dynos_level_is_vanilla_level(s32 level) { return DynOS_Level_IsVanillaLevel(level); } +Collision *dynos_level_get_collision(u32 level, u16 area) { + return DynOS_Level_GetCollision(level, area); +} + // -- Behaviors -- // void dynos_add_behavior(s32 modIndex, const char *filePath, const char *behaviorName) { diff --git a/data/dynos_level.cpp b/data/dynos_level.cpp index 08cdce723..7afa9e077 100644 --- a/data/dynos_level.cpp +++ b/data/dynos_level.cpp @@ -4,6 +4,7 @@ extern "C" { #include "game/save_file.h" #include "levels/scripts.h" #include "pc/lua/utils/smlua_level_utils.h" +#include "game/area.h" } // @@ -45,6 +46,7 @@ struct DynosLevelScript { static DynosLevelScript sDynosLevelScripts[LEVEL_COUNT] = { { NULL, DYNOS_LEVEL_MOD_INDEX_VANILLA } }; static Array sDynosLevelWarps[LEVEL_COUNT] = { Array() }; +static Collision *sDynosLevelCollision[LEVEL_COUNT][MAX_AREAS] = { NULL }; u64 DynOS_Level_CmdGet(void *aCmd, u64 aOffset) { u64 _Offset = (((aOffset) & 3llu) | (((aOffset) & ~3llu) << (sizeof(void *) >> 3llu))); @@ -154,6 +156,11 @@ static s32 DynOS_Level_PreprocessScript(u8 aType, void *aCmd) { case 0x03: case 0x04: return 3; + + // TERRAIN + case 0x2E: { + sDynosLevelCollision[sDynosCurrentLevelNum][sDynosAreaIndex] = (Collision*) DynOS_Level_CmdGet(aCmd, 4); + } break; } return 0; @@ -240,6 +247,12 @@ bool DynOS_Level_IsVanillaLevel(s32 aLevel) { return false; } +Collision *DynOS_Level_GetCollision(u32 aLevel, u16 aArea) { + if (aLevel >= LEVEL_COUNT) return NULL; + if (aArea >= MAX_AREAS) return NULL; + return sDynosLevelCollision[aLevel][aArea]; +} + // // Level Script Preprocessing // - Ifs are always true diff --git a/docs/lua/functions-5.md b/docs/lua/functions-5.md index 74826ced0..72295de8f 100644 --- a/docs/lua/functions-5.md +++ b/docs/lua/functions-5.md @@ -1083,6 +1083,26 @@
+## [smlua_collision_util_find_surface_types](#smlua_collision_util_find_surface_types) + +### Lua Example +`smlua_collision_util_find_surface_types(data)` + +### Parameters +| Field | Type | +| ----- | ---- | +| data | `Pointer` <`Collision`> | + +### Returns +- None + +### C Prototype +`void smlua_collision_util_find_surface_types(Collision* data);` + +[:arrow_up_small:](#) + +
+ ## [smlua_collision_util_get](#smlua_collision_util_get) ### Lua Example @@ -1103,6 +1123,45 @@
+## [smlua_collision_util_get_current_terrain_collision](#smlua_collision_util_get_current_terrain_collision) + +### Lua Example +`local PointerValue = smlua_collision_util_get_current_terrain_collision()` + +### Parameters +- None + +### Returns +- `Pointer` <`Collision`> + +### C Prototype +`Collision* smlua_collision_util_get_current_terrain_collision(void);` + +[:arrow_up_small:](#) + +
+ +## [smlua_collision_util_get_level_collision](#smlua_collision_util_get_level_collision) + +### Lua Example +`local PointerValue = smlua_collision_util_get_level_collision(level, area)` + +### Parameters +| Field | Type | +| ----- | ---- | +| level | `integer` | +| area | `integer` | + +### Returns +- `Pointer` <`Collision`> + +### C Prototype +`Collision *smlua_collision_util_get_level_collision(u32 level, u16 area);` + +[:arrow_up_small:](#) + +
+ --- # functions from smlua_deprecated.h diff --git a/docs/lua/functions.md b/docs/lua/functions.md index a762da90f..782bf43c4 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -1670,7 +1670,10 @@ - [collision_get_temp_wall_collision_data](functions-5.md#collision_get_temp_wall_collision_data) - [get_surface_from_wcd_index](functions-5.md#get_surface_from_wcd_index) - [get_water_surface_pseudo_floor](functions-5.md#get_water_surface_pseudo_floor) + - [smlua_collision_util_find_surface_types](functions-5.md#smlua_collision_util_find_surface_types) - [smlua_collision_util_get](functions-5.md#smlua_collision_util_get) + - [smlua_collision_util_get_current_terrain_collision](functions-5.md#smlua_collision_util_get_current_terrain_collision) + - [smlua_collision_util_get_level_collision](functions-5.md#smlua_collision_util_get_level_collision)
diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c index 66b2067d8..13c36571f 100644 --- a/src/engine/surface_load.c +++ b/src/engine/surface_load.c @@ -348,7 +348,7 @@ static struct Surface *read_surface_data(s16 *vertexData, s16 **vertexIndices) { * Returns whether a surface has exertion/moves Mario * based on the surface type. */ -static bool surface_has_force(s16 surfaceType) { +bool surface_has_force(s16 surfaceType) { return surfaceType == SURFACE_0004 || surfaceType == SURFACE_FLOWING_WATER || surfaceType == SURFACE_HORIZONTAL_WIND || diff --git a/src/engine/surface_load.h b/src/engine/surface_load.h index e948c2e99..a4a9461f3 100644 --- a/src/engine/surface_load.h +++ b/src/engine/surface_load.h @@ -35,5 +35,6 @@ void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects void clear_dynamic_surfaces(void); void load_object_collision_model(void); struct Surface *obj_get_surface_from_index(struct Object *o, u32 index); +bool surface_has_force(s16 surfaceType); #endif // SURFACE_LOAD_H diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index dc687984c..ea51eec11 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -29450,6 +29450,23 @@ int smlua_func_get_water_surface_pseudo_floor(UNUSED lua_State* L) { return 1; } +int smlua_func_smlua_collision_util_find_surface_types(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_collision_util_find_surface_types", 1, top); + return 0; + } + + Collision* data = (Collision*)smlua_to_cpointer(L, 1, LVT_COLLISION_P); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_collision_util_find_surface_types"); return 0; } + + smlua_collision_util_find_surface_types(data); + + return 1; +} + int smlua_func_smlua_collision_util_get(lua_State* L) { if (L == NULL) { return 0; } @@ -29467,6 +29484,40 @@ int smlua_func_smlua_collision_util_get(lua_State* L) { return 1; } +int smlua_func_smlua_collision_util_get_current_terrain_collision(UNUSED lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 0) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_collision_util_get_current_terrain_collision", 0, top); + return 0; + } + + + smlua_push_pointer(L, LVT_COLLISION_P, (void*)smlua_collision_util_get_current_terrain_collision()); + + return 1; +} + +int smlua_func_smlua_collision_util_get_level_collision(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 2) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_collision_util_get_level_collision", 2, top); + return 0; + } + + u32 level = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_collision_util_get_level_collision"); return 0; } + u16 area = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "smlua_collision_util_get_level_collision"); return 0; } + + smlua_push_pointer(L, LVT_COLLISION_P, (void*)smlua_collision_util_get_level_collision(level, area)); + + return 1; +} + //////////////////////// // smlua_deprecated.h // //////////////////////// @@ -34875,7 +34926,10 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "collision_get_temp_wall_collision_data", smlua_func_collision_get_temp_wall_collision_data); smlua_bind_function(L, "get_surface_from_wcd_index", smlua_func_get_surface_from_wcd_index); smlua_bind_function(L, "get_water_surface_pseudo_floor", smlua_func_get_water_surface_pseudo_floor); + smlua_bind_function(L, "smlua_collision_util_find_surface_types", smlua_func_smlua_collision_util_find_surface_types); smlua_bind_function(L, "smlua_collision_util_get", smlua_func_smlua_collision_util_get); + smlua_bind_function(L, "smlua_collision_util_get_current_terrain_collision", smlua_func_smlua_collision_util_get_current_terrain_collision); + smlua_bind_function(L, "smlua_collision_util_get_level_collision", smlua_func_smlua_collision_util_get_level_collision); // smlua_deprecated.h smlua_bind_function(L, "audio_stream_get_tempo", smlua_func_audio_stream_get_tempo); diff --git a/src/pc/lua/utils/smlua_collision_utils.c b/src/pc/lua/utils/smlua_collision_utils.c index 8be738c46..7e9bafb0f 100644 --- a/src/pc/lua/utils/smlua_collision_utils.c +++ b/src/pc/lua/utils/smlua_collision_utils.c @@ -3,6 +3,8 @@ #include "engine/surface_collision.h" #include "include/surface_terrains.h" #include "game/mario_step.h" +#include "game/area.h" +#include "engine/surface_load.h" #include "pc/lua/smlua.h" #include "smlua_collision_utils.h" @@ -195,3 +197,43 @@ struct Surface* get_surface_from_wcd_index(struct WallCollisionData* wcd, s8 ind if (index < 0 || index >= 4) { return NULL; } return wcd->walls[index]; } + +Collision *smlua_collision_util_get_current_terrain_collision(void) { + if (gCurrentArea && gCurrentArea->terrainData) { + return (Collision*) gCurrentArea->terrainData; + } + return NULL; +} + +Collision *smlua_collision_util_get_level_collision(u32 level, u16 area) { + return dynos_level_get_collision(level, area); +} + +void smlua_collision_util_find_surface_types(Collision* data) { + lua_State* L = gLuaState; + + if (data && *data++ == COL_INIT()) { + lua_newtable(L); + s32 t = lua_gettop(gLuaState); + + // Skip collision vertices + s32 numVertices = *data++; + data += 3 * numVertices; + + // Process surface types + for (u16 i = 0; true; ++i) { + s16 surfaceType = *data++; + if (surfaceType == COL_TRI_STOP()) { break; } + s32 numTriangles = *data++; + data += (3 + surface_has_force(surfaceType)) * numTriangles; + + lua_pushinteger(L, i); + lua_pushinteger(L, surfaceType); + lua_settable(L, t); + } + return; + } + + // Couldn't find anything + lua_pushnil(L); +} diff --git a/src/pc/lua/utils/smlua_collision_utils.h b/src/pc/lua/utils/smlua_collision_utils.h index fe4af6ad5..7cb00fea9 100644 --- a/src/pc/lua/utils/smlua_collision_utils.h +++ b/src/pc/lua/utils/smlua_collision_utils.h @@ -126,4 +126,10 @@ struct WallCollisionData* collision_get_temp_wall_collision_data(void); struct Surface* get_surface_from_wcd_index(struct WallCollisionData* wcd, s8 index); +Collision* smlua_collision_util_get_current_terrain_collision(void); + +Collision *smlua_collision_util_get_level_collision(u32 level, u16 area); + +void smlua_collision_util_find_surface_types(Collision* data); + #endif