Cleaned up surface loading
This commit is contained in:
@@ -3,13 +3,12 @@
|
|||||||
#include "../shim.h"
|
#include "../shim.h"
|
||||||
#include "surface_collision.h"
|
#include "surface_collision.h"
|
||||||
#include "../include/surface_terrains.h"
|
#include "../include/surface_terrains.h"
|
||||||
|
#include "../load_surfaces.h"
|
||||||
struct SurfaceNode *s_surfaceList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterate through the list of ceilings and find the first ceiling over a given point.
|
* Iterate through the list of ceilings and find the first ceiling over a given point.
|
||||||
*/
|
*/
|
||||||
static struct Surface *find_ceil_from_list(struct SurfaceNode *surfaceNode, s32 x, s32 y, s32 z, f32 *pheight) {
|
static struct Surface *find_ceil_from_list( s32 x, s32 y, s32 z, f32 *pheight) {
|
||||||
register struct Surface *surf;
|
register struct Surface *surf;
|
||||||
register s32 x1, z1, x2, z2, x3, z3;
|
register s32 x1, z1, x2, z2, x3, z3;
|
||||||
struct Surface *ceil = NULL;
|
struct Surface *ceil = NULL;
|
||||||
@@ -17,10 +16,9 @@ static struct Surface *find_ceil_from_list(struct SurfaceNode *surfaceNode, s32
|
|||||||
ceil = NULL;
|
ceil = NULL;
|
||||||
|
|
||||||
// Stay in this loop until out of ceilings.
|
// Stay in this loop until out of ceilings.
|
||||||
while (surfaceNode != NULL) {
|
int count = loaded_surface_get_count();
|
||||||
surf = surfaceNode->surface;
|
for( int i = 0; i < count; ++i ) {
|
||||||
surfaceNode = surfaceNode->next;
|
surf = loaded_surface_get_at_index(i);
|
||||||
|
|
||||||
|
|
||||||
// Do the check normally done in add_surface_to_cell
|
// Do the check normally done in add_surface_to_cell
|
||||||
if( surf->normal.y >= -0.01f ) continue;
|
if( surf->normal.y >= -0.01f ) continue;
|
||||||
@@ -96,7 +94,7 @@ static struct Surface *find_ceil_from_list(struct SurfaceNode *surfaceNode, s32
|
|||||||
/**
|
/**
|
||||||
* Iterate through the list of floors and find the first floor under a given point.
|
* Iterate through the list of floors and find the first floor under a given point.
|
||||||
*/
|
*/
|
||||||
static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32 x, s32 y, s32 z, f32 *pheight) {
|
static struct Surface *find_floor_from_list( s32 x, s32 y, s32 z, f32 *pheight) {
|
||||||
register struct Surface *surf;
|
register struct Surface *surf;
|
||||||
register s32 x1, z1, x2, z2, x3, z3;
|
register s32 x1, z1, x2, z2, x3, z3;
|
||||||
f32 nx, ny, nz;
|
f32 nx, ny, nz;
|
||||||
@@ -105,9 +103,9 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
|
|||||||
struct Surface *floor = NULL;
|
struct Surface *floor = NULL;
|
||||||
|
|
||||||
// Iterate through the list of floors until there are no more floors.
|
// Iterate through the list of floors until there are no more floors.
|
||||||
while (surfaceNode != NULL) {
|
int count = loaded_surface_get_count();
|
||||||
surf = surfaceNode->surface;
|
for( int i = 0; i < count; ++i ) {
|
||||||
surfaceNode = surfaceNode->next;
|
surf = loaded_surface_get_at_index(i);
|
||||||
|
|
||||||
|
|
||||||
// Do the check normally done in add_surface_to_cell
|
// Do the check normally done in add_surface_to_cell
|
||||||
@@ -175,8 +173,7 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
|
|||||||
return floor;
|
return floor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode,
|
static s32 find_wall_collisions_from_list( struct WallCollisionData *data) {
|
||||||
struct WallCollisionData *data) {
|
|
||||||
register struct Surface *surf;
|
register struct Surface *surf;
|
||||||
register f32 offset;
|
register f32 offset;
|
||||||
register f32 radius = data->radius;
|
register f32 radius = data->radius;
|
||||||
@@ -194,9 +191,9 @@ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stay in this loop until out of walls.
|
// Stay in this loop until out of walls.
|
||||||
while (surfaceNode != NULL) {
|
int count = loaded_surface_get_count();
|
||||||
surf = surfaceNode->surface;
|
for( int i = 0; i < count; ++i ) {
|
||||||
surfaceNode = surfaceNode->next;
|
surf = loaded_surface_get_at_index(i);
|
||||||
|
|
||||||
|
|
||||||
// Do the check normally done in add_surface_to_cell
|
// Do the check normally done in add_surface_to_cell
|
||||||
@@ -362,14 +359,14 @@ s32 find_wall_collisions(struct WallCollisionData *colData)
|
|||||||
return numCollisions;
|
return numCollisions;
|
||||||
}
|
}
|
||||||
|
|
||||||
numCollisions += find_wall_collisions_from_list(s_surfaceList, colData);
|
numCollisions += find_wall_collisions_from_list(colData);
|
||||||
return numCollisions;
|
return numCollisions;
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil)
|
f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil)
|
||||||
{
|
{
|
||||||
f32 height = CELL_HEIGHT_LIMIT;
|
f32 height = CELL_HEIGHT_LIMIT;
|
||||||
*pceil = find_ceil_from_list( s_surfaceList, posX, posY, posZ, &height );
|
*pceil = find_ceil_from_list( posX, posY, posZ, &height );
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,14 +393,14 @@ f32 find_floor_height_and_data(f32 xPos, f32 yPos, f32 zPos, struct FloorGeometr
|
|||||||
f32 find_floor_height(f32 x, f32 y, f32 z)
|
f32 find_floor_height(f32 x, f32 y, f32 z)
|
||||||
{
|
{
|
||||||
f32 height = FLOOR_LOWER_LIMIT;
|
f32 height = FLOOR_LOWER_LIMIT;
|
||||||
find_floor_from_list( s_surfaceList, x, y, z, &height );
|
find_floor_from_list( x, y, z, &height );
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor)
|
f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor)
|
||||||
{
|
{
|
||||||
f32 height = FLOOR_LOWER_LIMIT;
|
f32 height = FLOOR_LOWER_LIMIT;
|
||||||
*pfloor = find_floor_from_list( s_surfaceList, xPos, yPos, zPos, &height );
|
*pfloor = find_floor_from_list( xPos, yPos, zPos, &height );
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,9 +412,4 @@ f32 find_water_level(f32 x, f32 z)
|
|||||||
f32 find_poison_gas_level(f32 x, f32 z)
|
f32 find_poison_gas_level(f32 x, f32 z)
|
||||||
{
|
{
|
||||||
return -10000.0f;
|
return -10000.0f;
|
||||||
}
|
|
||||||
|
|
||||||
void hack_load_surface_list(struct SurfaceNode *surfaceNode)
|
|
||||||
{
|
|
||||||
s_surfaceList = surfaceNode;
|
|
||||||
}
|
}
|
||||||
@@ -39,6 +39,4 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor);
|
|||||||
f32 find_water_level(f32 x, f32 z);
|
f32 find_water_level(f32 x, f32 z);
|
||||||
f32 find_poison_gas_level(f32 x, f32 z);
|
f32 find_poison_gas_level(f32 x, f32 z);
|
||||||
|
|
||||||
void hack_load_surface_list(struct SurfaceNode *surfaceNode);
|
|
||||||
|
|
||||||
#endif // SURFACE_COLLISION_H
|
#endif // SURFACE_COLLISION_H
|
||||||
|
|||||||
@@ -1,378 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include "../include/surface_terrains.h"
|
|
||||||
#include "../include/surface_terrains.h"
|
|
||||||
#include "../shim.h"
|
|
||||||
#include "surface_load.h"
|
|
||||||
#include "surface_collision.h"
|
|
||||||
|
|
||||||
struct Surface **s_surface_list = NULL;
|
|
||||||
size_t s_surface_list_count = 0;
|
|
||||||
struct SurfaceNode *s_surface_node_list = NULL;
|
|
||||||
|
|
||||||
static void add_surface_ex(struct Surface *surface, s32 dynamic)
|
|
||||||
{
|
|
||||||
s_surface_list_count++;
|
|
||||||
|
|
||||||
if( s_surface_list == NULL )
|
|
||||||
s_surface_list = malloc( s_surface_list_count * sizeof( struct Surface * ));
|
|
||||||
else
|
|
||||||
s_surface_list = realloc( s_surface_list, s_surface_list_count * sizeof( struct Surface * ));
|
|
||||||
|
|
||||||
s_surface_list[s_surface_list_count - 1] = surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct Surface *alloc_surface(void) {
|
|
||||||
struct Surface *surface = malloc(sizeof(struct Surface)); // PATCH - just use malloc instead of pool
|
|
||||||
// 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) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
surface->type = 0;
|
|
||||||
surface->force = 0;
|
|
||||||
surface->flags = 0;
|
|
||||||
surface->room = 0;
|
|
||||||
surface->object = NULL;
|
|
||||||
|
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether a surface has exertion/moves Mario
|
|
||||||
* based on the surface type.
|
|
||||||
*/
|
|
||||||
static s32 surface_has_force(s16 surfaceType) {
|
|
||||||
s32 hasForce = FALSE;
|
|
||||||
|
|
||||||
switch (surfaceType) {
|
|
||||||
case SURFACE_0004: // Unused
|
|
||||||
case SURFACE_FLOWING_WATER:
|
|
||||||
case SURFACE_DEEP_MOVING_QUICKSAND:
|
|
||||||
case SURFACE_SHALLOW_MOVING_QUICKSAND:
|
|
||||||
case SURFACE_MOVING_QUICKSAND:
|
|
||||||
case SURFACE_HORIZONTAL_WIND:
|
|
||||||
case SURFACE_INSTANT_MOVING_QUICKSAND:
|
|
||||||
hasForce = TRUE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return hasForce;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether a surface should have the
|
|
||||||
* SURFACE_FLAG_NO_CAM_COLLISION flag.
|
|
||||||
*/
|
|
||||||
static s32 surf_has_no_cam_collision(s16 surfaceType) {
|
|
||||||
s32 flags = 0;
|
|
||||||
|
|
||||||
switch (surfaceType) {
|
|
||||||
case SURFACE_NO_CAM_COLLISION:
|
|
||||||
case SURFACE_NO_CAM_COLLISION_77: // Unused
|
|
||||||
case SURFACE_NO_CAM_COL_VERY_SLIPPERY:
|
|
||||||
case SURFACE_SWITCH:
|
|
||||||
flags = SURFACE_FLAG_NO_CAM_COLLISION;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct Surface *read_surface_data_ex( s32 x1, s32 y1, s32 z1, s32 x2, s32 y2, s32 z2, s32 x3, s32 y3, s32 z3) {
|
|
||||||
struct Surface *surface;
|
|
||||||
s32 maxY, minY;
|
|
||||||
f32 nx, ny, nz;
|
|
||||||
f32 mag;
|
|
||||||
|
|
||||||
// (v2 - v1) x (v3 - v2)
|
|
||||||
nx = (y2 - y1) * (z3 - z2) - (z2 - z1) * (y3 - y2);
|
|
||||||
ny = (z2 - z1) * (x3 - x2) - (x2 - x1) * (z3 - z2);
|
|
||||||
nz = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2);
|
|
||||||
mag = sqrtf(nx * nx + ny * ny + nz * nz);
|
|
||||||
|
|
||||||
// Could have used min_3 and max_3 for this...
|
|
||||||
minY = y1;
|
|
||||||
if (y2 < minY) {
|
|
||||||
minY = y2;
|
|
||||||
}
|
|
||||||
if (y3 < minY) {
|
|
||||||
minY = y3;
|
|
||||||
}
|
|
||||||
|
|
||||||
maxY = y1;
|
|
||||||
if (y2 > maxY) {
|
|
||||||
maxY = y2;
|
|
||||||
}
|
|
||||||
if (y3 > maxY) {
|
|
||||||
maxY = y3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checking to make sure no DIV/0
|
|
||||||
if (mag < 0.0001) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
mag = (f32)(1.0 / mag);
|
|
||||||
nx *= mag;
|
|
||||||
ny *= mag;
|
|
||||||
nz *= mag;
|
|
||||||
|
|
||||||
surface = alloc_surface();
|
|
||||||
|
|
||||||
surface->vertex1[0] = x1;
|
|
||||||
surface->vertex2[0] = x2;
|
|
||||||
surface->vertex3[0] = x3;
|
|
||||||
|
|
||||||
surface->vertex1[1] = y1;
|
|
||||||
surface->vertex2[1] = y2;
|
|
||||||
surface->vertex3[1] = y3;
|
|
||||||
|
|
||||||
surface->vertex1[2] = z1;
|
|
||||||
surface->vertex2[2] = z2;
|
|
||||||
surface->vertex3[2] = z3;
|
|
||||||
|
|
||||||
surface->normal.x = nx;
|
|
||||||
surface->normal.y = ny;
|
|
||||||
surface->normal.z = nz;
|
|
||||||
|
|
||||||
surface->originOffset = -(nx * x1 + ny * y1 + nz * z1);
|
|
||||||
|
|
||||||
surface->lowerY = minY - 5;
|
|
||||||
surface->upperY = maxY + 5;
|
|
||||||
|
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes a Surface struct using the given vertex data
|
|
||||||
* @param vertexData The raw data containing vertex positions
|
|
||||||
* @param vertexIndices Helper which tells positions in vertexData to start reading vertices
|
|
||||||
*/
|
|
||||||
static struct Surface *read_surface_data(s16 *vertexData, s16 **vertexIndices) {
|
|
||||||
register s32 x1, y1, z1;
|
|
||||||
register s32 x2, y2, z2;
|
|
||||||
register s32 x3, y3, z3;
|
|
||||||
s16 offset1, offset2, offset3;
|
|
||||||
|
|
||||||
offset1 = 3 * (*vertexIndices)[0];
|
|
||||||
offset2 = 3 * (*vertexIndices)[1];
|
|
||||||
offset3 = 3 * (*vertexIndices)[2];
|
|
||||||
|
|
||||||
x1 = *(vertexData + offset1 + 0);
|
|
||||||
y1 = *(vertexData + offset1 + 1);
|
|
||||||
z1 = *(vertexData + offset1 + 2);
|
|
||||||
|
|
||||||
x2 = *(vertexData + offset2 + 0);
|
|
||||||
y2 = *(vertexData + offset2 + 1);
|
|
||||||
z2 = *(vertexData + offset2 + 2);
|
|
||||||
|
|
||||||
x3 = *(vertexData + offset3 + 0);
|
|
||||||
y3 = *(vertexData + offset3 + 1);
|
|
||||||
z3 = *(vertexData + offset3 + 2);
|
|
||||||
|
|
||||||
return read_surface_data_ex( x1, y1, z1, x2, y2, z2, x3, y3, z3 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read the data for vertices for reference by triangles.
|
|
||||||
*/
|
|
||||||
static s16 *read_vertex_data(s16 **data) {
|
|
||||||
s32 numVertices;
|
|
||||||
UNUSED s16 unused1[3];
|
|
||||||
UNUSED s16 unused2[3];
|
|
||||||
s16 *vertexData;
|
|
||||||
|
|
||||||
numVertices = *(*data);
|
|
||||||
(*data)++;
|
|
||||||
|
|
||||||
vertexData = *data;
|
|
||||||
*data += 3 * numVertices;
|
|
||||||
|
|
||||||
return vertexData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load in the surfaces for a given surface type. This includes setting the flags,
|
|
||||||
* exertion, and room.
|
|
||||||
*/
|
|
||||||
static void load_static_surfaces(s16 **data, s16 *vertexData, s16 surfaceType, s8 **surfaceRooms) {
|
|
||||||
s32 i;
|
|
||||||
s32 numSurfaces;
|
|
||||||
struct Surface *surface;
|
|
||||||
s8 room = 0;
|
|
||||||
s16 hasForce = surface_has_force(surfaceType);
|
|
||||||
s16 flags = surf_has_no_cam_collision(surfaceType);
|
|
||||||
|
|
||||||
numSurfaces = *(*data);
|
|
||||||
*data += 1;
|
|
||||||
|
|
||||||
for (i = 0; i < numSurfaces; i++) {
|
|
||||||
if (*surfaceRooms != NULL) {
|
|
||||||
room = *(*surfaceRooms);
|
|
||||||
*surfaceRooms += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface = read_surface_data(vertexData, data);
|
|
||||||
if (surface != NULL) {
|
|
||||||
surface->room = room;
|
|
||||||
surface->type = surfaceType;
|
|
||||||
surface->flags = (s8) flags;
|
|
||||||
|
|
||||||
if (hasForce) {
|
|
||||||
surface->force = *(*data + 3);
|
|
||||||
} else {
|
|
||||||
surface->force = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_surface_ex(surface, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
*data += 3;
|
|
||||||
if (hasForce) {
|
|
||||||
*data += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects) {
|
|
||||||
s16 terrainLoadType;
|
|
||||||
s16 *vertexData;
|
|
||||||
UNUSED s32 unused;
|
|
||||||
|
|
||||||
// Initialize the data for this.
|
|
||||||
// gEnvironmentRegions = NULL;
|
|
||||||
// unused8038BE90 = 0;
|
|
||||||
// gSurfaceNodesAllocated = 0;
|
|
||||||
// gSurfacesAllocated = 0;
|
|
||||||
|
|
||||||
// clear_static_surfaces();
|
|
||||||
|
|
||||||
// A while loop iterating through each section of the level data. Sections of data
|
|
||||||
// are prefixed by a terrain "type." This type is reused for surfaces as the surface
|
|
||||||
// type.
|
|
||||||
while (TRUE) {
|
|
||||||
terrainLoadType = *data;
|
|
||||||
data++;
|
|
||||||
|
|
||||||
if (TERRAIN_LOAD_IS_SURFACE_TYPE_LOW(terrainLoadType)) {
|
|
||||||
load_static_surfaces(&data, vertexData, terrainLoadType, &surfaceRooms);
|
|
||||||
} else if (terrainLoadType == TERRAIN_LOAD_VERTICES) {
|
|
||||||
vertexData = read_vertex_data(&data);
|
|
||||||
// } else if (terrainLoadType == TERRAIN_LOAD_OBJECTS) {
|
|
||||||
// spawn_special_objects(index, &data);
|
|
||||||
// } else if (terrainLoadType == TERRAIN_LOAD_ENVIRONMENT) {
|
|
||||||
// load_environmental_regions(&data);
|
|
||||||
} else if (terrainLoadType == TERRAIN_LOAD_CONTINUE) {
|
|
||||||
// continue;
|
|
||||||
break; // PATCH
|
|
||||||
} else if (terrainLoadType == TERRAIN_LOAD_END) {
|
|
||||||
break;
|
|
||||||
} else if (TERRAIN_LOAD_IS_SURFACE_TYPE_HIGH(terrainLoadType)) {
|
|
||||||
load_static_surfaces(&data, vertexData, terrainLoadType, &surfaceRooms);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (macroObjects != NULL && *macroObjects != -1) {
|
|
||||||
// // If the first macro object presetID is within the range [0, 29].
|
|
||||||
// // Generally an early spawning method, every object is in BBH (the first level).
|
|
||||||
// if (0 <= *macroObjects && *macroObjects < 30) {
|
|
||||||
// spawn_macro_objects_hardcoded(index, macroObjects);
|
|
||||||
// }
|
|
||||||
// // A more general version that can spawn more objects.
|
|
||||||
// else {
|
|
||||||
// spawn_macro_objects(index, macroObjects);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// gNumStaticSurfaceNodes = gSurfaceNodesAllocated;
|
|
||||||
// gNumStaticSurfaces = gSurfacesAllocated;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Unused, loads from raw sm64 collision data
|
|
||||||
// struct Surface **surface_load_from_collision_data( const s16 *data, size_t *numSurfaces )
|
|
||||||
// {
|
|
||||||
// s8 *rooms = NULL;
|
|
||||||
// s16 *macroObjects = NULL;
|
|
||||||
// load_area_terrain( 0, (s16*)data, rooms, macroObjects );
|
|
||||||
// *numSurfaces = s_surface_list_count;
|
|
||||||
// return s_surface_list;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
void surface_load_for_libsm64( const struct SM64Surface *surfaceArray, uint32_t numSurfaces )
|
|
||||||
{
|
|
||||||
while( s_surface_node_list )
|
|
||||||
{
|
|
||||||
struct SurfaceNode *node = s_surface_node_list;
|
|
||||||
s_surface_node_list = node->next;
|
|
||||||
free( node );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( s_surface_list )
|
|
||||||
{
|
|
||||||
for( int i = 0; i < s_surface_list_count; ++i )
|
|
||||||
free( s_surface_list[i] );
|
|
||||||
|
|
||||||
free( s_surface_list );
|
|
||||||
|
|
||||||
s_surface_list = NULL;
|
|
||||||
s_surface_list_count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for( int i = 0; i < numSurfaces; ++i )
|
|
||||||
{
|
|
||||||
struct Surface *surface = read_surface_data_ex(
|
|
||||||
surfaceArray[i].vertices[0][0], surfaceArray[i].vertices[0][1], surfaceArray[i].vertices[0][2],
|
|
||||||
surfaceArray[i].vertices[1][0], surfaceArray[i].vertices[1][1], surfaceArray[i].vertices[1][2],
|
|
||||||
surfaceArray[i].vertices[2][0], surfaceArray[i].vertices[2][1], surfaceArray[i].vertices[2][2]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (surface != NULL) {
|
|
||||||
s16 hasForce = surface_has_force(surfaceArray[i].type);
|
|
||||||
s16 flags = surf_has_no_cam_collision(surfaceArray[i].type);
|
|
||||||
|
|
||||||
surface->room = 0;
|
|
||||||
surface->type = surfaceArray[i].type;
|
|
||||||
surface->flags = (s8) flags;
|
|
||||||
|
|
||||||
if (hasForce) {
|
|
||||||
surface->force = surfaceArray[i].force;
|
|
||||||
} else {
|
|
||||||
surface->force = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_surface_ex(surface, FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Surface **ptr = s_surface_list;
|
|
||||||
struct SurfaceNode *node = malloc( sizeof( struct SurfaceNode ));
|
|
||||||
node->surface = *ptr;
|
|
||||||
s_surface_node_list = node;
|
|
||||||
|
|
||||||
for( int i = 1; i < s_surface_list_count; ++i )
|
|
||||||
{
|
|
||||||
ptr++;
|
|
||||||
struct SurfaceNode *next = malloc( sizeof( struct SurfaceNode ));
|
|
||||||
next->surface = *ptr;
|
|
||||||
next->next = NULL;
|
|
||||||
node->next = next;
|
|
||||||
node = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
hack_load_surface_list( s_surface_node_list );
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "../libsm64.h"
|
|
||||||
#include "../include/types.h"
|
|
||||||
|
|
||||||
struct Surface **surface_load_from_collision_data( const s16 *data, size_t *numSurfaces );
|
|
||||||
|
|
||||||
void surface_load_for_libsm64( const struct SM64Surface *surfaceArray, size_t numSurfaces );
|
|
||||||
+10
-1
@@ -12,7 +12,6 @@
|
|||||||
#include "shim.h"
|
#include "shim.h"
|
||||||
#include "game/mario.h"
|
#include "game/mario.h"
|
||||||
#include "game/object_stuff.h"
|
#include "game/object_stuff.h"
|
||||||
#include "engine/surface_load.h"
|
|
||||||
#include "engine/surface_collision.h"
|
#include "engine/surface_collision.h"
|
||||||
#include "engine/graph_node.h"
|
#include "engine/graph_node.h"
|
||||||
#include "engine/geo_layout.h"
|
#include "engine/geo_layout.h"
|
||||||
@@ -174,6 +173,16 @@ void sm64_global_terminate( void )
|
|||||||
|
|
||||||
uint32_t sm64_load_surface_object( const struct SM64SurfaceObject *surfaceObject )
|
uint32_t sm64_load_surface_object( const struct SM64SurfaceObject *surfaceObject )
|
||||||
{
|
{
|
||||||
|
DEBUG_LOG(
|
||||||
|
"sm64_load_surface_object : %f %f %f : %f %f %f : %d",
|
||||||
|
surfaceObject->transform.position[0],
|
||||||
|
surfaceObject->transform.position[1],
|
||||||
|
surfaceObject->transform.position[2],
|
||||||
|
surfaceObject->transform.eulerRotation[0],
|
||||||
|
surfaceObject->transform.eulerRotation[1],
|
||||||
|
surfaceObject->transform.eulerRotation[2],
|
||||||
|
surfaceObject->surfaceCount
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sm64_move_object( uint32_t id, const struct SM64ObjectTransform *transform )
|
void sm64_move_object( uint32_t id, const struct SM64ObjectTransform *transform )
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ struct SM64SurfaceObject
|
|||||||
{
|
{
|
||||||
struct SM64ObjectTransform transform;
|
struct SM64ObjectTransform transform;
|
||||||
uint32_t surfaceCount;
|
uint32_t surfaceCount;
|
||||||
struct SM64Surface surfaces[];
|
struct SM64Surface *surfaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SM64MarioState
|
struct SM64MarioState
|
||||||
|
|||||||
@@ -0,0 +1,139 @@
|
|||||||
|
#include "load_surfaces.h"
|
||||||
|
|
||||||
|
#include "include/types.h"
|
||||||
|
#include "include/surface_terrains.h"
|
||||||
|
|
||||||
|
|
||||||
|
static struct Surface *s_loaded_static_surface_list = NULL;
|
||||||
|
static size_t s_loaded_static_surface_count = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a surface has exertion/moves Mario
|
||||||
|
* based on the surface type.
|
||||||
|
*/
|
||||||
|
static s32 surface_has_force(s16 surfaceType) {
|
||||||
|
s32 hasForce = FALSE;
|
||||||
|
|
||||||
|
switch (surfaceType) {
|
||||||
|
case SURFACE_0004: // Unused
|
||||||
|
case SURFACE_FLOWING_WATER:
|
||||||
|
case SURFACE_DEEP_MOVING_QUICKSAND:
|
||||||
|
case SURFACE_SHALLOW_MOVING_QUICKSAND:
|
||||||
|
case SURFACE_MOVING_QUICKSAND:
|
||||||
|
case SURFACE_HORIZONTAL_WIND:
|
||||||
|
case SURFACE_INSTANT_MOVING_QUICKSAND:
|
||||||
|
hasForce = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return hasForce;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void read_surface_data( struct Surface *surface, int16_t type, int16_t force, s32 x1, s32 y1, s32 z1, s32 x2, s32 y2, s32 z2, s32 x3, s32 y3, s32 z3)
|
||||||
|
{
|
||||||
|
s32 maxY, minY;
|
||||||
|
f32 nx, ny, nz;
|
||||||
|
f32 mag;
|
||||||
|
|
||||||
|
// (v2 - v1) x (v3 - v2)
|
||||||
|
nx = (y2 - y1) * (z3 - z2) - (z2 - z1) * (y3 - y2);
|
||||||
|
ny = (z2 - z1) * (x3 - x2) - (x2 - x1) * (z3 - z2);
|
||||||
|
nz = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2);
|
||||||
|
mag = sqrtf(nx * nx + ny * ny + nz * nz);
|
||||||
|
|
||||||
|
// Could have used min_3 and max_3 for this...
|
||||||
|
minY = y1;
|
||||||
|
if (y2 < minY) {
|
||||||
|
minY = y2;
|
||||||
|
}
|
||||||
|
if (y3 < minY) {
|
||||||
|
minY = y3;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxY = y1;
|
||||||
|
if (y2 > maxY) {
|
||||||
|
maxY = y2;
|
||||||
|
}
|
||||||
|
if (y3 > maxY) {
|
||||||
|
maxY = y3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mag < 0.0001)
|
||||||
|
DEBUG_LOG("ERROR: normal magnitude is very close to zero");
|
||||||
|
|
||||||
|
mag = (f32)(1.0 / mag);
|
||||||
|
nx *= mag;
|
||||||
|
ny *= mag;
|
||||||
|
nz *= mag;
|
||||||
|
|
||||||
|
surface = malloc(sizeof(struct Surface));
|
||||||
|
|
||||||
|
surface->vertex1[0] = x1;
|
||||||
|
surface->vertex2[0] = x2;
|
||||||
|
surface->vertex3[0] = x3;
|
||||||
|
|
||||||
|
surface->vertex1[1] = y1;
|
||||||
|
surface->vertex2[1] = y2;
|
||||||
|
surface->vertex3[1] = y3;
|
||||||
|
|
||||||
|
surface->vertex1[2] = z1;
|
||||||
|
surface->vertex2[2] = z2;
|
||||||
|
surface->vertex3[2] = z3;
|
||||||
|
|
||||||
|
surface->normal.x = nx;
|
||||||
|
surface->normal.y = ny;
|
||||||
|
surface->normal.z = nz;
|
||||||
|
|
||||||
|
surface->originOffset = -(nx * x1 + ny * y1 + nz * z1);
|
||||||
|
|
||||||
|
surface->lowerY = minY - 5;
|
||||||
|
surface->upperY = maxY + 5;
|
||||||
|
|
||||||
|
s16 hasForce = surface_has_force(type);
|
||||||
|
s16 flags = 0; // surf_has_no_cam_collision(type);
|
||||||
|
|
||||||
|
surface->room = 0;
|
||||||
|
surface->type = type;
|
||||||
|
surface->flags = (s8) flags;
|
||||||
|
|
||||||
|
if (hasForce) {
|
||||||
|
surface->force = force;
|
||||||
|
} else {
|
||||||
|
surface->force = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct Surface *loaded_surface_get_at_index( uint32_t index )
|
||||||
|
{
|
||||||
|
return &s_loaded_static_surface_list[ index ];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t loaded_surface_get_count()
|
||||||
|
{
|
||||||
|
return s_loaded_static_surface_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void surfaces_load_static_libsm64( const struct SM64Surface *surfaceArray, uint32_t numSurfaces )
|
||||||
|
{
|
||||||
|
s_loaded_static_surface_count = numSurfaces;
|
||||||
|
s_loaded_static_surface_list = malloc( sizeof( struct Surface ) * numSurfaces );
|
||||||
|
|
||||||
|
for( int i = 0; i < numSurfaces; ++i )
|
||||||
|
read_surface_data(
|
||||||
|
&s_loaded_static_surface_list[i], surfaceArray[i].type, surfaceArray[i].force,
|
||||||
|
surfaceArray[i].vertices[0][0], surfaceArray[i].vertices[0][1], surfaceArray[i].vertices[0][2],
|
||||||
|
surfaceArray[i].vertices[1][0], surfaceArray[i].vertices[1][1], surfaceArray[i].vertices[1][2],
|
||||||
|
surfaceArray[i].vertices[2][0], surfaceArray[i].vertices[2][1], surfaceArray[i].vertices[2][2]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t surfaces_load_object( const struct SM64SurfaceObject *surfaceObject )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "libsm64.h"
|
||||||
|
|
||||||
|
extern struct Surface *loaded_surface_get_at_index( uint32_t index );
|
||||||
|
extern uint32_t loaded_surface_get_count();
|
||||||
|
|
||||||
|
extern void surfaces_load_static_libsm64( const struct SM64Surface *surfaceArray, uint32_t numSurfaces );
|
||||||
|
extern uint32_t surfaces_load_object( const struct SM64SurfaceObject *surfaceObject );
|
||||||
Reference in New Issue
Block a user