Merge branch 'dev' of github.com:sm64ex-coop-dev/sm64ex-coop into dev

This commit is contained in:
MysterD 2023-06-18 12:28:07 -07:00
commit ec09ac67c9
18 changed files with 138 additions and 93 deletions

View file

@ -8100,6 +8100,11 @@ function collision_find_surface_on_ray(startX, startY, startZ, dirX, dirY, dirZ)
-- ... -- ...
end end
--- @return WallCollisionData
function collision_get_temp_wall_collision_data()
-- ...
end
--- @return Surface --- @return Surface
function get_water_surface_pseudo_floor() function get_water_surface_pseudo_floor()
-- ... -- ...

View file

@ -7345,6 +7345,24 @@
<br /> <br />
## [collision_get_temp_wall_collision_data](#collision_get_temp_wall_collision_data)
### Lua Example
`local WallCollisionDataValue = collision_get_temp_wall_collision_data()`
### Parameters
- None
### Returns
[WallCollisionData](structs.md#WallCollisionData)
### C Prototype
`struct WallCollisionData* collision_get_temp_wall_collision_data(void);`
[:arrow_up_small:](#)
<br />
## [get_water_surface_pseudo_floor](#get_water_surface_pseudo_floor) ## [get_water_surface_pseudo_floor](#get_water_surface_pseudo_floor)
### Lua Example ### Lua Example

View file

@ -1503,6 +1503,7 @@
- smlua_collision_utils.h - smlua_collision_utils.h
- [collision_find_surface_on_ray](functions-4.md#collision_find_surface_on_ray) - [collision_find_surface_on_ray](functions-4.md#collision_find_surface_on_ray)
- [collision_get_temp_wall_collision_data](functions-4.md#collision_get_temp_wall_collision_data)
- [get_water_surface_pseudo_floor](functions-4.md#get_water_surface_pseudo_floor) - [get_water_surface_pseudo_floor](functions-4.md#get_water_surface_pseudo_floor)
- [smlua_collision_util_get](functions-4.md#smlua_collision_util_get) - [smlua_collision_util_get](functions-4.md#smlua_collision_util_get)

View file

@ -574,27 +574,40 @@ static void level_cmd_create_warp_node(void) {
} }
static void level_cmd_create_instant_warp(void) { static void level_cmd_create_instant_warp(void) {
s32 i; struct InstantWarp *warp = NULL;
struct InstantWarp *warp;
if (sCurrAreaIndex != -1) { if (sCurrAreaIndex != -1) {
if (gAreas[sCurrAreaIndex].instantWarps == NULL) { if (gAreas[sCurrAreaIndex].instantWarps == NULL) {
gAreas[sCurrAreaIndex].instantWarps = gAreas[sCurrAreaIndex].instantWarps =
dynamic_pool_alloc(gLevelPool, 4 * sizeof(struct InstantWarp)); dynamic_pool_alloc(gLevelPool, 4 * sizeof(struct InstantWarp));
for (i = INSTANT_WARP_INDEX_START; i < INSTANT_WARP_INDEX_STOP; i++) { for (s32 i = INSTANT_WARP_INDEX_START; i < INSTANT_WARP_INDEX_STOP; i++) {
gAreas[sCurrAreaIndex].instantWarps[i].id = 0; gAreas[sCurrAreaIndex].instantWarps[i].id = 0;
} }
} }
warp = gAreas[sCurrAreaIndex].instantWarps + CMD_GET(u8, 2); u8 warpIndex = CMD_GET(u8, 2);
if (warpIndex >= INSTANT_WARP_INDEX_STOP) {
LOG_ERROR("Instant warp index out of bounds: %u", warpIndex);
sCurrentCmd = CMD_NEXT;
return;
}
warp[0].id = 1; u8 areaIndex = CMD_GET(u8, 3);
warp[0].area = CMD_GET(u8, 3); if (areaIndex >= MAX_AREAS) {
LOG_ERROR("Instant warp area index out of bounds: %u", areaIndex);
sCurrentCmd = CMD_NEXT;
return;
}
warp[0].displacement[0] = CMD_GET(s16, 4); warp = &gAreas[sCurrAreaIndex].instantWarps[warpIndex];
warp[0].displacement[1] = CMD_GET(s16, 6);
warp[0].displacement[2] = CMD_GET(s16, 8); warp->id = 1;
warp->area = areaIndex;
warp->displacement[0] = CMD_GET(s16, 4);
warp->displacement[1] = CMD_GET(s16, 6);
warp->displacement[2] = CMD_GET(s16, 8);
} }
sCurrentCmd = CMD_NEXT; sCurrentCmd = CMD_NEXT;

View file

@ -31,34 +31,17 @@ SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS];
/** /**
* Pools of data to contain either surface nodes or surfaces. * Pools of data to contain either surface nodes or surfaces.
*/ */
struct SurfaceNode *sSurfaceNodePool = NULL; struct GrowingPool* sSurfaceNodePool = NULL;
struct Surface *sSurfacePool = NULL; struct GrowingPool* sSurfacePool = NULL;
/**
* The size of the surface pool (2300).
*/
s16 sSurfacePoolSize = 0;
u8 gSurfacePoolError = 0;
/** /**
* Allocate the part of the surface node pool to contain a surface node. * Allocate the part of the surface node pool to contain a surface node.
*/ */
static struct SurfaceNode *alloc_surface_node(void) { static struct SurfaceNode* alloc_surface_node(void) {
struct SurfaceNode *node = &sSurfaceNodePool[gSurfaceNodesAllocated]; struct SurfaceNode* node = (struct SurfaceNode*)growing_pool_alloc(sSurfaceNodePool, sizeof(struct SurfaceNode));
gSurfaceNodesAllocated++;
//! A bounds check! If there's more surface nodes than 7000 allowed,
// we, um...
// Perhaps originally just debug feedback?
if (gSurfaceNodesAllocated >= SURFACE_NODE_POOL_SIZE) {
gSurfacePoolError |= NOT_ENOUGH_ROOM_FOR_NODES;
return NULL;
} else {
gSurfacePoolError &= ~NOT_ENOUGH_ROOM_FOR_NODES;
}
node->next = NULL; node->next = NULL;
gSurfaceNodesAllocated++;
return node; return node;
} }
@ -66,20 +49,8 @@ static struct SurfaceNode *alloc_surface_node(void) {
* Allocate the part of the surface pool to contain a surface and * Allocate the part of the surface pool to contain a surface and
* initialize the surface. * initialize the surface.
*/ */
static struct Surface *alloc_surface(void) { static struct Surface* alloc_surface(void) {
struct Surface* surface = (struct Surface*)growing_pool_alloc(sSurfacePool, sizeof(struct Surface));
struct Surface *surface = &sSurfacePool[gSurfacesAllocated];
gSurfacesAllocated++;
//! A bounds check! If there's more surfaces than the 2300 allowed,
// we, um...
// Perhaps originally just debug feedback?
if (gSurfacesAllocated >= sSurfacePoolSize) {
gSurfacePoolError |= NOT_ENOUGH_ROOM_FOR_SURFACES;
return NULL;
} else {
gSurfacePoolError &= ~NOT_ENOUGH_ROOM_FOR_SURFACES;
}
surface->type = 0; surface->type = 0;
surface->force = 0; surface->force = 0;
@ -87,6 +58,8 @@ static struct Surface *alloc_surface(void) {
surface->room = 0; surface->room = 0;
surface->object = NULL; surface->object = NULL;
gSurfacesAllocated++;
return surface; return surface;
} }
@ -549,9 +522,8 @@ void alloc_surface_pools(void) {
clear_static_surfaces(); clear_static_surfaces();
clear_dynamic_surfaces(); clear_dynamic_surfaces();
sSurfacePoolSize = SURFACE_POOL_SIZE; sSurfaceNodePool = growing_pool_init(sSurfaceNodePool, sizeof(struct SurfaceNode) * 1000);
if (!sSurfaceNodePool) { sSurfaceNodePool = calloc(1, SURFACE_NODE_POOL_SIZE * sizeof(struct SurfaceNode)); } sSurfacePool = growing_pool_init(sSurfacePool, sizeof(struct Surface) * 1000);
if (!sSurfacePool) { sSurfacePool = calloc(1, sSurfacePoolSize * sizeof(struct Surface)); }
gEnvironmentRegions = NULL; gEnvironmentRegions = NULL;
gSurfaceNodesAllocated = 0; gSurfaceNodesAllocated = 0;
@ -784,7 +756,26 @@ void load_object_collision_model(void) {
if (!gCurrentObject) { return; } if (!gCurrentObject) { return; }
if (gCurrentObject->collisionData == NULL) { return; } if (gCurrentObject->collisionData == NULL) { return; }
s16 vertexData[600]; s32 numVertices = 64;
if (gCurrentObject->collisionData[0] == COL_INIT()) {
numVertices = gCurrentObject->collisionData[1];
}
if (numVertices <= 0) {
LOG_ERROR("Object collisions had invalid vertex count");
return;
}
static s32 sVertexDataCount = 0;
static s16* sVertexData = NULL;
// allocate vertex data
if (numVertices > sVertexDataCount || sVertexData == NULL) {
if (sVertexData) { free(sVertexData); }
sVertexDataCount = numVertices;
if (sVertexDataCount < 64) { sVertexDataCount = 64; }
sVertexData = malloc((3 * sVertexDataCount + 1) * sizeof(s16));
LOG_INFO("Reallocating object vertex data: %u", sVertexDataCount);
}
s16* collisionData = gCurrentObject->collisionData; s16* collisionData = gCurrentObject->collisionData;
f32 tangibleDist = gCurrentObject->oCollisionDistance; f32 tangibleDist = gCurrentObject->oCollisionDistance;
@ -806,11 +797,11 @@ void load_object_collision_model(void) {
&& (anyPlayerInTangibleRange) && (anyPlayerInTangibleRange)
&& !(gCurrentObject->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { && !(gCurrentObject->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) {
collisionData++; collisionData++;
transform_object_vertices(&collisionData, vertexData); transform_object_vertices(&collisionData, sVertexData);
// TERRAIN_LOAD_CONTINUE acts as an "end" to the terrain data. // TERRAIN_LOAD_CONTINUE acts as an "end" to the terrain data.
while (*collisionData != TERRAIN_LOAD_CONTINUE) { while (*collisionData != TERRAIN_LOAD_CONTINUE) {
load_object_surfaces(&collisionData, vertexData); load_object_surfaces(&collisionData, sVertexData);
} }
} }

View file

@ -26,7 +26,6 @@ typedef struct SurfaceNode SpatialPartitionCell[3];
extern SpatialPartitionCell gStaticSurfacePartition[NUM_CELLS][NUM_CELLS]; extern SpatialPartitionCell gStaticSurfacePartition[NUM_CELLS][NUM_CELLS];
extern SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS]; extern SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS];
extern u8 gSurfacePoolError;
void alloc_surface_pools(void); void alloc_surface_pools(void);

View file

@ -29,7 +29,7 @@
#include "pc/djui/djui_panel_pause.h" #include "pc/djui/djui_panel_pause.h"
struct SpawnInfo gPlayerSpawnInfos[MAX_PLAYERS]; struct SpawnInfo gPlayerSpawnInfos[MAX_PLAYERS];
struct Area gAreaData[8]; struct Area gAreaData[MAX_AREAS];
struct WarpTransition gWarpTransition; struct WarpTransition gWarpTransition;

View file

@ -26,6 +26,8 @@ struct ObjectWarpNode
#define INSTANT_WARP_INDEX_START 0x00 // Equal and greater than Surface 0x1B #define INSTANT_WARP_INDEX_START 0x00 // Equal and greater than Surface 0x1B
#define INSTANT_WARP_INDEX_STOP 0x04 // Less than Surface 0x1F #define INSTANT_WARP_INDEX_STOP 0x04 // Less than Surface 0x1F
#define MAX_AREAS 8
struct InstantWarp struct InstantWarp
{ {
/*0x00*/ u8 id; // 0 = 0x1B / 1 = 0x1C / 2 = 0x1D / 3 = 0x1E /*0x00*/ u8 id; // 0 = 0x1B / 1 = 0x1C / 2 = 0x1D / 3 = 0x1E

View file

@ -410,6 +410,14 @@ void bhv_monty_mole_update(void) {
o->oDeathSound = SOUND_OBJ_DYING_ENEMY1; o->oDeathSound = SOUND_OBJ_DYING_ENEMY1;
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
// if we can't find our floor, set it to the hole's floor
if (!o->oFloor && o->oMontyMoleCurrentHole) {
struct Object* hole = o->oMontyMoleCurrentHole;
struct Surface* floor = NULL;
o->oFloorHeight = find_floor(hole->oPosX, hole->oPosY, hole->oPosZ, &floor);
o->oFloor = floor;
}
o->oMontyMoleHeightRelativeToFloor = o->oPosY - o->oFloorHeight; o->oMontyMoleHeightRelativeToFloor = o->oPosY - o->oFloorHeight;
switch (o->oAction) { switch (o->oAction) {

View file

@ -11,6 +11,10 @@
* positions. * positions.
*/ */
void bhv_ssl_moving_pyramid_wall_init(void) { void bhv_ssl_moving_pyramid_wall_init(void) {
o->areaTimerType = AREA_TIMER_TYPE_LOOP;
o->areaTimer = 0;
o->areaTimerDuration = 200;
switch (o->oBehParams2ndByte) { switch (o->oBehParams2ndByte) {
case PYRAMID_WALL_BP_POSITION_HIGH: case PYRAMID_WALL_BP_POSITION_HIGH:
break; break;
@ -25,17 +29,6 @@ void bhv_ssl_moving_pyramid_wall_init(void) {
o->oAction = PYRAMID_WALL_ACT_MOVING_UP; o->oAction = PYRAMID_WALL_ACT_MOVING_UP;
break; break;
} }
if (!sync_object_is_initialized(o->oSyncID)) {
struct SyncObject *so = sync_object_init(o, SYNC_DISTANCE_ONLY_EVENTS);
if (so) {
sync_object_init_field(o, &o->oPrevAction);
sync_object_init_field(o, &o->oAction);
sync_object_init_field(o, &o->oTimer);
sync_object_init_field(o, &o->oVelY);
sync_object_init_field(o, &o->oPosY);
}
}
} }
/** /**
@ -48,16 +41,14 @@ void bhv_ssl_moving_pyramid_wall_loop(void) {
o->oVelY = -5.12f; o->oVelY = -5.12f;
if (o->oTimer == 100) { if (o->oTimer == 100) {
o->oAction = PYRAMID_WALL_ACT_MOVING_UP; o->oAction = PYRAMID_WALL_ACT_MOVING_UP;
if (sync_object_is_owned_locally(o->oSyncID)) {
network_send_object(o);
}
} }
break; break;
case PYRAMID_WALL_ACT_MOVING_UP: case PYRAMID_WALL_ACT_MOVING_UP:
o->oVelY = 5.12f; o->oVelY = 5.12f;
if (o->oTimer == 100) if (o->oTimer == 100) {
o->oAction = PYRAMID_WALL_ACT_MOVING_DOWN; o->oAction = PYRAMID_WALL_ACT_MOVING_DOWN;
}
break; break;
} }

View file

@ -555,7 +555,7 @@ f32 get_character_anim_offset(struct MarioState* m) {
switch (sAnimTypes[animID]) { switch (sAnimTypes[animID]) {
case ANIM_TYPE_LOWY: case ANIM_TYPE_LOWY:
if (m->minimumBoneY < c->animOffsetLowYPoint) { if (m->minimumBoneY < c->animOffsetLowYPoint) {
return -(m->minimumBoneY - c->animOffsetLowYPoint); return c->animOffsetLowYPoint - m->minimumBoneY;
} }
break; break;
case ANIM_TYPE_FEET: case ANIM_TYPE_FEET:
@ -584,10 +584,6 @@ void update_character_anim_offset(struct MarioState* m) {
if (m->curAnimOffset > 40) { m->curAnimOffset = 40; } if (m->curAnimOffset > 40) { m->curAnimOffset = 40; }
if (m->curAnimOffset < -40) { m->curAnimOffset = -40; } if (m->curAnimOffset < -40) { m->curAnimOffset = -40; }
if (m->action == ACT_JUMBO_STAR_CUTSCENE) { marioObj->header.gfx.pos[1] = m->pos[1] + m->curAnimOffset;
marioObj->header.gfx.pos[1] = m->pos[1] + m->curAnimOffset;
} else {
marioObj->header.gfx.pos[1] += m->curAnimOffset;
}
marioObj->header.gfx.node.flags |= GRAPH_RENDER_PLAYER; marioObj->header.gfx.node.flags |= GRAPH_RENDER_PLAYER;
} }

View file

@ -678,14 +678,6 @@ void render_hud(void) {
render_hud_timer(); render_hud_timer();
} }
if (gSurfacePoolError & NOT_ENOUGH_ROOM_FOR_SURFACES) {
print_text(10, 40, "SURFACE POOL FULL");
}
if (gSurfacePoolError & NOT_ENOUGH_ROOM_FOR_NODES) {
print_text(10, 60, "SURFACE NODE POOL FULL");
}
#if defined(DEVELOPMENT) #if defined(DEVELOPMENT)
extern bool configLuaProfiler; extern bool configLuaProfiler;
if (configLuaProfiler) { if (configLuaProfiler) {

View file

@ -1414,7 +1414,7 @@ u32 interact_player(struct MarioState* m, UNUSED u32 interactType, struct Object
if (!m || !o) { return FALSE; } if (!m || !o) { return FALSE; }
if (!is_player_active(m)) { return FALSE; } if (!is_player_active(m)) { return FALSE; }
if (gServerSettings.playerInteractions == PLAYER_INTERACTIONS_NONE) { return FALSE; } if (gServerSettings.playerInteractions == PLAYER_INTERACTIONS_NONE) { return FALSE; }
if (m->action == ACT_JUMBO_STAR_CUTSCENE) { return FALSE; } if (m->action & ACT_FLAG_INTANGIBLE) { return FALSE; }
struct MarioState* m2 = NULL; struct MarioState* m2 = NULL;
for (s32 i = 0; i < MAX_PLAYERS; i++) { for (s32 i = 0; i < MAX_PLAYERS; i++) {
@ -1425,7 +1425,7 @@ u32 interact_player(struct MarioState* m, UNUSED u32 interactType, struct Object
} }
} }
if (m2 == NULL) { return FALSE; } if (m2 == NULL) { return FALSE; }
if (m2->action == ACT_JUMBO_STAR_CUTSCENE) { return FALSE; } if (m2->action & ACT_FLAG_INTANGIBLE) { return FALSE; }
// vanish cap players can't interact // vanish cap players can't interact
u32 vanishFlags = (MARIO_VANISH_CAP | MARIO_CAP_ON_HEAD); u32 vanishFlags = (MARIO_VANISH_CAP | MARIO_CAP_ON_HEAD);

View file

@ -1222,7 +1222,7 @@ static void geo_process_object(struct Object *node) {
} }
} }
if (gCurGraphNodeMarioState != NULL) { if (gCurGraphNodeMarioState != NULL) {
gCurGraphNodeMarioState->minimumBoneY = 999; gCurGraphNodeMarioState->minimumBoneY = 9999;
} }
} }

View file

@ -27042,6 +27042,21 @@ int smlua_func_collision_find_surface_on_ray(lua_State* L) {
return 1; return 1;
} }
int smlua_func_collision_get_temp_wall_collision_data(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", "collision_get_temp_wall_collision_data", 0, top);
return 0;
}
smlua_push_object(L, LOT_WALLCOLLISIONDATA, collision_get_temp_wall_collision_data());
return 1;
}
int smlua_func_get_water_surface_pseudo_floor(UNUSED lua_State* L) { int smlua_func_get_water_surface_pseudo_floor(UNUSED lua_State* L) {
if (L == NULL) { return 0; } if (L == NULL) { return 0; }
@ -31516,6 +31531,7 @@ void smlua_bind_functions_autogen(void) {
// smlua_collision_utils.h // smlua_collision_utils.h
smlua_bind_function(L, "collision_find_surface_on_ray", smlua_func_collision_find_surface_on_ray); smlua_bind_function(L, "collision_find_surface_on_ray", smlua_func_collision_find_surface_on_ray);
smlua_bind_function(L, "collision_get_temp_wall_collision_data", smlua_func_collision_get_temp_wall_collision_data);
smlua_bind_function(L, "get_water_surface_pseudo_floor", smlua_func_get_water_surface_pseudo_floor); smlua_bind_function(L, "get_water_surface_pseudo_floor", smlua_func_get_water_surface_pseudo_floor);
smlua_bind_function(L, "smlua_collision_util_get", smlua_func_smlua_collision_util_get); smlua_bind_function(L, "smlua_collision_util_get", smlua_func_smlua_collision_util_get);

View file

@ -171,3 +171,9 @@ struct Surface* get_water_surface_pseudo_floor(void) {
Collision* smlua_collision_util_get(const char* name) { Collision* smlua_collision_util_get(const char* name) {
return dynos_collision_get(name); return dynos_collision_get(name);
} }
struct WallCollisionData* collision_get_temp_wall_collision_data(void) {
static struct WallCollisionData sTmpWcd = { 0 };
memset(&sTmpWcd, 0, sizeof(struct WallCollisionData));
return &sTmpWcd;
}

View file

@ -1,6 +1,8 @@
#ifndef SMLUA_COLLISION_UTILS_H #ifndef SMLUA_COLLISION_UTILS_H
#define SMLUA_COLLISION_UTILS_H #define SMLUA_COLLISION_UTILS_H
#include "engine/surface_collision.h"
struct RayIntersectionInfo { struct RayIntersectionInfo {
struct Surface* surface; struct Surface* surface;
Vec3f hitPos; Vec3f hitPos;
@ -118,4 +120,6 @@ struct Surface* get_water_surface_pseudo_floor(void);
Collision* smlua_collision_util_get(const char* name); Collision* smlua_collision_util_get(const char* name);
struct WallCollisionData* collision_get_temp_wall_collision_data(void);
#endif #endif

View file

@ -416,6 +416,7 @@ void network_update_player(void) {
// figure out if we should send it or not // figure out if we should send it or not
static u8 sTicksSinceSend = 0; static u8 sTicksSinceSend = 0;
static u32 sLastPlayerAction = 0; static u32 sLastPlayerAction = 0;
static u32 sLastPlayerParticles = 0;
static f32 sLastStickX = 0; static f32 sLastStickX = 0;
static f32 sLastStickY = 0; static f32 sLastStickY = 0;
static u32 sLastButtonDown = 0; static u32 sLastButtonDown = 0;
@ -423,18 +424,20 @@ void network_update_player(void) {
f32 stickDist = sqrtf(powf(sLastStickX - m->controller->stickX, 2) + powf(sLastStickY - m->controller->stickY, 2)); f32 stickDist = sqrtf(powf(sLastStickX - m->controller->stickX, 2) + powf(sLastStickY - m->controller->stickY, 2));
bool shouldSend = (sTicksSinceSend > 2) bool shouldSend = (sTicksSinceSend > 2)
|| (sLastPlayerAction != m->action) || (sLastPlayerAction != m->action)
|| (sLastButtonDown != m->controller->buttonDown) || (sLastButtonDown != m->controller->buttonDown)
|| (sLastButtonPressed != m->controller->buttonPressed) || (sLastButtonPressed != m->controller->buttonPressed)
|| (sLastPlayerParticles != m->particleFlags)
|| (stickDist > 5.0f); || (stickDist > 5.0f);
if (!shouldSend) { sTicksSinceSend++; return; } if (!shouldSend) { sTicksSinceSend++; return; }
network_send_player(0); network_send_player(0);
sTicksSinceSend = 0; sTicksSinceSend = 0;
sLastPlayerAction = m->action; sLastPlayerAction = m->action;
sLastStickX = m->controller->stickX; sLastStickX = m->controller->stickX;
sLastStickY = m->controller->stickY; sLastStickY = m->controller->stickY;
sLastButtonDown = m->controller->buttonDown; sLastButtonDown = m->controller->buttonDown;
sLastButtonPressed = m->controller->buttonPressed; sLastButtonPressed = m->controller->buttonPressed;
sLastPlayerParticles = m->particleFlags;
} }