Using floor-based terrain instead of area-based

This commit is contained in:
jaburns 2020-10-27 21:01:44 -06:00
parent 6563afc16d
commit d12a3e2568
18 changed files with 52 additions and 32 deletions

View file

@ -37,7 +37,7 @@ def main():
out_lines = []
for tri in tris:
out_lines.append("{%s,0,{{%s,%s,%s},{%s,%s,%s},{%s,%s,%s}}}"%(tri[3], \
out_lines.append("{%s,0,TERRAIN_SNOW,{{%s,%s,%s},{%s,%s,%s},{%s,%s,%s}}}"%(tri[3], \
verts[tri[0]][0], verts[tri[0]][1], verts[tri[0]][2], \
verts[tri[1]][0], verts[tri[1]][1], verts[tri[1]][2], \
verts[tri[2]][0], verts[tri[2]][1], verts[tri[2]][2]))
@ -45,7 +45,7 @@ def main():
out_str = ",\n".join(out_lines)
out_str = "const struct SM64Surface surfaces[] = {\n" + out_str + "};\n\n"
out_str += "const size_t surfaces_count = sizeof( surfaces ) / sizeof( surfaces[0] );"
out_str = '#include "../src/include/surface_terrains.h"\n' + out_str
out_str = '#include "../src/decomp/include/surface_terrains.h"\n' + out_str
out_str = '#include "level.h"\n' + out_str
with open("test/level.c", "w") as file:

View file

@ -350,7 +350,6 @@ extern struct GraphNodeMasterList *gCurGraphNodeMasterList;
extern struct GraphNodePerspective *gCurGraphNodeCamFrustum;
extern struct GraphNodeCamera *gCurGraphNodeCamera;
extern struct GraphNodeHeldObject *gCurGraphNodeHeldObject;
extern u16 gAreaUpdateCounter;
extern struct GraphNode *gCurRootGraphNode;
extern struct GraphNode *gCurGraphNodeList[];

View file

@ -64,7 +64,7 @@ struct Area
{
/*0x00*/ s8 index;
/*0x01*/ s8 flags; // Only has 1 flag: 0x01 = Is this the active area?
/*0x02*/ u16 terrainType; // default terrain of the level (set from level script cmd 0x31)
// /*0x02*/ u16 terrainType; // default terrain of the level (set from level script cmd 0x31) ; in libsm64 terrain is defined in the Surface struct
/*0x04*/ struct GraphNodeRoot *unk04; // geometry layout data
/*0x08*/ s16 *terrainData; // collision data (set from level script cmd 0x2E)
/*0x0C*/ s8 *surfaceRooms; // (set from level script cmd 0x2F)

View file

@ -396,7 +396,7 @@ s32 mario_get_floor_class(struct MarioState *m) {
// The slide terrain type defaults to slide slipperiness.
// This doesn't matter too much since normally the slide terrain
// is checked for anyways.
if ((m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE) {
if (m->curTerrain == TERRAIN_SLIDE) {
floorClass = SURFACE_CLASS_VERY_SLIPPERY;
} else {
floorClass = SURFACE_CLASS_DEFAULT;
@ -464,12 +464,12 @@ s8 sTerrainSounds[7][6] = {
*/
u32 mario_get_terrain_sound_addend(struct MarioState *m) {
s16 floorSoundType;
s16 terrainType = m->area->terrainType & TERRAIN_MASK;
s32 ret = SOUND_TERRAIN_DEFAULT << 16;
s32 floorType;
if (m->floor != NULL) {
floorType = m->floor->type;
s16 terrainType = m->curTerrain;
if ((gCurrLevelNum != LEVEL_LLL) && (m->floorHeight < (m->waterLevel - 10))) {
// Water terrain sound, excluding LLL since it uses water in the volcano.
@ -579,7 +579,7 @@ s32 mario_facing_downhill(struct MarioState *m, s32 turnYaw) {
u32 mario_floor_is_slippery(struct MarioState *m) {
f32 normY;
if ((m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE
if (m->curTerrain == TERRAIN_SLIDE
&& m->floor->normal.y < 0.9998477f //~cos(1 deg)
) {
return TRUE;
@ -612,7 +612,7 @@ u32 mario_floor_is_slippery(struct MarioState *m) {
s32 mario_floor_is_slope(struct MarioState *m) {
f32 normY;
if ((m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE
if (m->curTerrain == TERRAIN_SLIDE
&& m->floor->normal.y < 0.9998477f) { // ~cos(1 deg)
return TRUE;
}
@ -1326,6 +1326,8 @@ void update_mario_geometry_inputs(struct MarioState *m) {
m->floorHeight = find_floor(m->pos[0], m->pos[1], m->pos[2], &m->floor);
m->curTerrain = m->floor->terrain;
// If Mario is OOB, move his position to his graphical position (which was not updated)
// and check for the floor there.
// This can cause errant behavior when combined with astral projection,
@ -1468,7 +1470,7 @@ void update_mario_health(struct MarioState *m) {
}
} else {
if ((m->action & ACT_FLAG_SWIMMING) && !(m->action & ACT_FLAG_INTANGIBLE)) {
terrainIsSnow = (m->area->terrainType & TERRAIN_MASK) == TERRAIN_SNOW;
terrainIsSnow = m->floor != NULL && m->curTerrain == TERRAIN_SNOW;
// When Mario is near the water surface, recover health (unless in snow),
// when in snow terrains lose 3 health.
@ -1834,6 +1836,8 @@ void init_mario(void) {
gMarioState->floorHeight =
find_floor(gMarioState->pos[0], gMarioState->pos[1], gMarioState->pos[2], &gMarioState->floor);
gMarioState->curTerrain = gMarioState->floor->terrain;
if (gMarioState->pos[1] < gMarioState->floorHeight) {
gMarioState->pos[1] = gMarioState->floorHeight;
}
@ -1879,7 +1883,7 @@ void init_mario_from_save_file(void) {
gMarioState->action = 0;
gMarioState->spawnInfo = gMarioSpawnInfo;
// gMarioState->statusForCamera = &gPlayerCameraState;
gMarioState->marioBodyState = &gBodyStates[0];
gMarioState->marioBodyState = &g_state->mgBodyStates[0];
gMarioState->controller = &gController;
gMarioState->animation = &D_80339D10;

View file

@ -115,12 +115,11 @@ s32 check_kick_or_dive_in_air(struct MarioState *m) {
}
s32 should_get_stuck_in_ground(struct MarioState *m) {
u32 terrainType = m->area->terrainType & TERRAIN_MASK;
struct Surface *floor = m->floor;
s32 flags = floor->flags;
s32 type = floor->type;
if (floor != NULL && (terrainType == TERRAIN_SNOW || terrainType == TERRAIN_SAND)
if (floor != NULL && (m->curTerrain == TERRAIN_SNOW || m->curTerrain == TERRAIN_SAND)
&& type != SURFACE_BURNING && SURFACE_IS_NOT_HARD(type)) {
if (!(flags & 0x01) && m->peakHeight - m->pos[1] > 1000.0f && floor->normal.y >= 0.8660254f) {
return TRUE;
@ -1556,8 +1555,9 @@ s32 act_lava_boost(struct MarioState *m) {
break;
}
set_mario_animation(m, MARIO_ANIM_FIRE_LAVA_BURN);
if ((m->area->terrainType & TERRAIN_MASK) != TERRAIN_SNOW && !(m->flags & MARIO_METAL_CAP)
if (m->curTerrain != TERRAIN_SNOW && !(m->flags & MARIO_METAL_CAP)
&& m->vel[1] > 0.0f) {
m->particleFlags |= PARTICLE_FIRE;
if (m->actionState == 0) {

View file

@ -472,7 +472,7 @@ void update_walking_speed(struct MarioState *m) {
s32 should_begin_sliding(struct MarioState *m) {
if (m->input & INPUT_ABOVE_SLIDE) {
s32 slideLevel = (m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE;
s32 slideLevel = m->curTerrain == TERRAIN_SLIDE;
s32 movingBackward = m->forwardVel <= -1.0f;
if (slideLevel || movingBackward || mario_facing_downhill(m, FALSE)) {

View file

@ -127,7 +127,7 @@ s32 act_idle(struct MarioState *m) {
}
if (m->actionState == 3) {
if ((m->area->terrainType & TERRAIN_MASK) == TERRAIN_SNOW) {
if (m->floor != NULL && m->curTerrain == TERRAIN_SNOW) {
return set_mario_action(m, ACT_SHIVERING, 0);
} else {
return set_mario_action(m, ACT_START_SLEEPING, 0);

View file

@ -78,7 +78,8 @@ static s8 gMarioAttackScaleAnimation[3 * 6] = {
10, 12, 16, 24, 10, 10, 10, 14, 20, 30, 10, 10, 10, 16, 20, 26, 26, 20,
};
struct MarioBodyState gBodyStates[2]; // 2nd is never accessed in practice, most likely Luigi related
#define gBodyStates (g_state->mgBodyStates)
//struct MarioBodyState gBodyStates[2]; // 2nd is never accessed in practice, most likely Luigi related
//struct GraphNodeObject gMirrorMario; // copy of Mario's geo node for drawing mirror Mario
// This whole file is weirdly organized. It has to be the same file due

View file

@ -6,9 +6,6 @@
#include "../include/macros.h"
#include "../include/types.h"
extern struct GraphNodeObject gMirrorMario;
extern struct MarioBodyState gBodyStates[2];
// Gfx *geo_draw_mario_head_goddard(s32 callContext, struct GraphNode *node, Mat4 *c);
void bhv_toad_message_loop(void);
void bhv_toad_message_init(void);

View file

@ -141,7 +141,6 @@ struct GraphNodePerspective *gCurGraphNodeCamFrustum = NULL;
struct GraphNodeCamera *gCurGraphNodeCamera = NULL;
struct GraphNodeObject *gCurGraphNodeObject = NULL;
struct GraphNodeHeldObject *gCurGraphNodeHeldObject = NULL;
u16 gAreaUpdateCounter = 0;
#ifdef F3DEX_GBI_2
LookAt lookAt;

View file

@ -11,7 +11,6 @@ extern struct GraphNodePerspective *gCurGraphNodeCamFrustum;
extern struct GraphNodeCamera *gCurGraphNodeCamera;
extern struct GraphNodeObject *gCurGraphNodeObject;
extern struct GraphNodeHeldObject *gCurGraphNodeHeldObject;
extern u16 gAreaUpdateCounter;
// after processing an object, the type is reset to this
#define ANIM_TYPE_NONE 0

View file

@ -24,6 +24,9 @@ struct GlobalState
// mario_misc.c
struct MarioBodyState mgBodyStates[2];
// rendering_graph_node.c
u16 mgAreaUpdateCounter;
// Implemented and in use:
// platform_displacement.c

View file

@ -242,6 +242,8 @@ struct Surface
} normal;
/*0x28*/ f32 originOffset;
/*0x2C*/ struct Object *object;
u16 terrain;
};
struct MarioBodyState
@ -343,6 +345,8 @@ struct MarioState
/*0xBC*/ f32 peakHeight;
/*0xC0*/ f32 quicksandDepth;
/*0xC4*/ f32 unkC4;
u16 curTerrain;
};
#endif // TYPES_H

View file

@ -58,4 +58,5 @@
#define gCurrentObject (g_state->mgCurrentObject)
#define gMarioObject (g_state->mgMarioObject)
#define D_80339D10 (g_state->mD_80339D10)
#define gMarioState (&g_state->mgMarioStateVal)
#define gMarioState (&g_state->mgMarioStateVal)
#define gAreaUpdateCounter (g_state->mgAreaUpdateCounter)

View file

@ -3,6 +3,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
@ -30,7 +31,7 @@
static struct AllocOnlyPool *s_mario_geo_pool;
static struct GraphNode *s_mario_graph_node;
static uint32_t s_last_colors_hash;
static bool s_is_init = false;
static struct GlobalState *s_global_state;
static void update_button( bool on, u16 button )
@ -70,6 +71,11 @@ static void free_area( struct Area *area )
SM64_LIB_FN void sm64_global_init( uint8_t *rom, uint8_t *outTexture, SM64DebugPrintFunctionPtr debugPrintFunction )
{
if( s_is_init )
sm64_global_terminate();
s_is_init = true;
s_last_colors_hash = 0;
g_debug_print_func = debugPrintFunction;
@ -93,10 +99,9 @@ SM64_LIB_FN void sm64_global_init( uint8_t *rom, uint8_t *outTexture, SM64DebugP
D_80339D10.targetAnim = NULL;
}
SM64_LIB_FN void sm64_load_surfaces( uint16_t terrainType, const struct SM64Surface *surfaceArray, uint32_t numSurfaces )
SM64_LIB_FN void sm64_load_surfaces( const struct SM64Surface *surfaceArray, uint32_t numSurfaces )
{
surfaces_load_static_libsm64( surfaceArray, numSurfaces );
gCurrentArea->terrainType = terrainType;
}
SM64_LIB_FN void sm64_mario_reset( int16_t marioX, int16_t marioY, int16_t marioZ )
@ -134,12 +139,13 @@ static void update_non_terrain_objects( void )
static void update_objects( void )
{
update_mario_platform();
//clear_dynamic_surfaces();
update_terrain_objects();
apply_mario_platform_displacement();
//detect_object_collisions();
update_non_terrain_objects();
update_mario_platform();
}
SM64_LIB_FN void sm64_mario_tick( const struct SM64MarioInputs *inputs, struct SM64MarioState *outState, struct SM64MarioGeometryBuffers *outBuffers )
@ -170,6 +176,11 @@ SM64_LIB_FN void sm64_mario_tick( const struct SM64MarioInputs *inputs, struct S
SM64_LIB_FN void sm64_global_terminate( void )
{
if( !s_is_init )
return;
s_is_init = false;
free( gMarioObject );
free_area( gCurrentArea );

View file

@ -19,6 +19,7 @@ struct SM64Surface
{
int16_t type;
int16_t force;
uint16_t terrain;
int16_t vertices[3][3];
};
@ -69,7 +70,7 @@ enum
};
extern SM64_LIB_FN void sm64_global_init( uint8_t *rom, uint8_t *outTexture, SM64DebugPrintFunctionPtr debugPrintFunction );
extern SM64_LIB_FN void sm64_load_surfaces( uint16_t terrainType, const struct SM64Surface *surfaceArray, uint32_t numSurfaces );
extern SM64_LIB_FN void sm64_load_surfaces( const struct SM64Surface *surfaceArray, uint32_t numSurfaces );
extern SM64_LIB_FN void sm64_mario_reset( int16_t marioX, int16_t marioY, int16_t marioZ );
extern SM64_LIB_FN void sm64_mario_tick( const struct SM64MarioInputs *inputs, struct SM64MarioState *outState, struct SM64MarioGeometryBuffers *outBuffers );
@ -85,12 +86,11 @@ extern void sm64_global_init( uint8_t *rom, uint8_t *outTexture, SM64DebugPrintF
extern uint8_t sm64_global_is_init( void );
extern void sm64_global_terminate( void );
extern void sm64_create_static_surfaces( uint16_t terrainType, const struct SM64Surface *surfaceArray, uint32_t numSurfaces );
extern void sm64_delete_static_surfaces( void );
extern void sm64_load_static_surfaces( const struct SM64Surface *surfaceArray, uint32_t numSurfaces );
extern uint32_t sm64_create_surface_object( const struct SM64SurfaceObject *surfaceObject );
extern void sm64_move_object( uint32_t objectId, const struct SM64ObjectTransform *transform );
extern void sm64_delete_object( uint32_t objectId );
extern void sm64_move_surface_object( uint32_t objectId, const struct SM64ObjectTransform *transform );
extern void sm64_delete_surface_object( uint32_t objectId );
extern uint32_t sm64_create_mario( int16_t x, int16_t y, int16_t z );
extern void sm64_mario_tick( const struct SM64MarioInputs *inputs, struct SM64MarioState *outState, struct SM64MarioGeometryBuffers *outBuffers );

View file

@ -192,6 +192,7 @@ static void engine_surface_from_lib_surface( struct Surface *surface, const stru
surface->room = 0;
surface->type = type;
surface->flags = (s8) flags;
surface->terrain = libSurf->terrain;
if (hasForce) {
surface->force = force;

View file

@ -392,8 +392,9 @@ int main( void )
uint8_t *texture = malloc( 4 * SM64_TEXTURE_WIDTH * SM64_TEXTURE_HEIGHT );
sm64_global_terminate();
sm64_global_init( rom, texture, NULL );
sm64_load_surfaces( 0, surfaces, surfaces_count );
sm64_load_surfaces( surfaces, surfaces_count );
sm64_mario_reset( 0, 1000, 0 );
free( rom );