Implement FakeObjects (Just poles for now)
This commit is contained in:
Generated
+1
-1
@@ -279,6 +279,7 @@
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_EXISTING_ENUM_ARRANGEMENT/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_USER_LINEBREAKS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LABELED_STATEMENT_STYLE/@EntryValue" value="ON_SINGLE_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_COLON_IN_MEMBER_INITIALIZER_LISTS/@EntryValue" value="ON_SINGLE_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_DEREF_IN_TRAILING_RETURN_TYPES/@EntryValue" value="ON_SINGLE_LINE" type="string" />
|
||||
@@ -330,7 +331,6 @@
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_ENUMERATION_STYLE/@EntryValue" value="CHOP_ALWAYS" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_LINES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||
<option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=05D45346A5B5B54F93A9F94C46B14079/@EntryIndexRemoved" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=05D45346A5B5B54F93A9F94C46B14079/@EntryIndexedValue" value="" type="string" />
|
||||
|
||||
Generated
-1
@@ -2,6 +2,5 @@
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/test/imgui" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,170 @@
|
||||
//
|
||||
// Created by nepushiro on 5/29/26.
|
||||
//
|
||||
|
||||
#include "FakeObject.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "decomp/global_state.h"
|
||||
#include "decomp/engine/math_util.h"
|
||||
#include "decomp/game/interaction.h"
|
||||
#include "decomp/game/object_stuff.h"
|
||||
#include "decomp/include/object_fields.h"
|
||||
#include "libsm64.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void fake_object_init(struct FakeObject *fake, float x, float y, float z)
|
||||
{
|
||||
memset(fake, 0, sizeof(*fake));
|
||||
|
||||
struct Object *obj = &fake->object;
|
||||
obj->activeFlags = ACTIVE_FLAG_ACTIVE | ACTIVE_FLAG_UNK8;
|
||||
obj->parentObj = NULL;
|
||||
obj->prevObj = NULL;
|
||||
obj->collidedObjInteractTypes = 0;
|
||||
obj->numCollidedObjs = 0;
|
||||
|
||||
for (s32 i = 0; i < 0x50; i++)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
obj->rawData.asS32[i] = 0;
|
||||
#endif
|
||||
#ifdef _WIN64
|
||||
obj->ptrData.asVoidPtr[i] = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
obj->unused1 = 0;
|
||||
obj->bhvStackIndex = 0;
|
||||
obj->bhvDelayTimer = 0;
|
||||
|
||||
obj->hitboxRadius = 50.0f;
|
||||
obj->hitboxHeight = 100.0f;
|
||||
obj->hurtboxRadius = 0.0f;
|
||||
obj->hurtboxHeight = 0.0f;
|
||||
obj->hitboxDownOffset = 0.0f;
|
||||
obj->unused2 = 0;
|
||||
|
||||
obj->platform = NULL;
|
||||
obj->collisionData = NULL;
|
||||
obj->oIntangibleTimer = -1;
|
||||
obj->oDamageOrCoinValue = 0;
|
||||
obj->oHealth = 2048;
|
||||
|
||||
obj->oCollisionDistance = 1000.0f;
|
||||
obj->oDrawingDistance = 4000.0f;
|
||||
|
||||
mtxf_identity(obj->transform);
|
||||
|
||||
obj->respawnInfoType = RESPAWN_INFO_TYPE_NULL;
|
||||
obj->respawnInfo = NULL;
|
||||
|
||||
obj->oDistanceToMario = 19000.0f;
|
||||
obj->oRoom = -1;
|
||||
obj->oInteractType = 0;
|
||||
obj->oInteractionSubtype = 0;
|
||||
obj->oHeldState = 0;
|
||||
obj->oAction = 0;
|
||||
|
||||
obj->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
|
||||
obj->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
|
||||
obj->header.gfx.node.flags &= ~GRAPH_RENDER_BILLBOARD;
|
||||
obj->header.gfx.pos[0] = x;
|
||||
obj->header.gfx.pos[1] = y;
|
||||
obj->header.gfx.pos[2] = z;
|
||||
obj->header.gfx.angle[0] = 0;
|
||||
obj->header.gfx.angle[1] = 0;
|
||||
obj->header.gfx.angle[2] = 0;
|
||||
obj->header.gfx.throwMatrix = NULL;
|
||||
obj->header.gfx.sharedChild = NULL;
|
||||
obj->header.gfx.animInfo.curAnim = NULL;
|
||||
obj->header.gfx.animInfo.animID = 0;
|
||||
obj->header.gfx.animInfo.animFrame = 0;
|
||||
obj->header.gfx.animInfo.animTimer = 0;
|
||||
|
||||
obj->oPosX = x;
|
||||
obj->oPosY = y;
|
||||
obj->oPosZ = z;
|
||||
obj->oMoveAnglePitch = 0;
|
||||
obj->oMoveAngleYaw = 0;
|
||||
obj->oMoveAngleRoll = 0;
|
||||
obj->oFaceAnglePitch = 0;
|
||||
obj->oFaceAngleYaw = 0;
|
||||
obj->oFaceAngleRoll = 0;
|
||||
}
|
||||
|
||||
void fake_object_sync_position(struct FakeObject *fake)
|
||||
{
|
||||
struct Object *obj = &fake->object;
|
||||
obj->header.gfx.pos[0] = obj->oPosX;
|
||||
obj->header.gfx.pos[1] = obj->oPosY;
|
||||
obj->header.gfx.pos[2] = obj->oPosZ;
|
||||
}
|
||||
|
||||
bool fake_object_overlaps_mario(struct FakeObject *fake, struct MarioState *m)
|
||||
{
|
||||
struct Object *obj = &fake->object;
|
||||
float dx = obj->oPosX - m->pos[0];
|
||||
float dz = obj->oPosZ - m->pos[2];
|
||||
float radius = obj->hitboxRadius;
|
||||
float top = obj->oPosY + obj->hitboxHeight;
|
||||
float bottom = obj->oPosY - obj->hitboxDownOffset;
|
||||
|
||||
if ((dx * dx) + (dz * dz) > radius * radius)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m->pos[1] < bottom || m->pos[1] > top)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void fake_object_add_collision(struct FakeObject *fake, struct MarioState *m)
|
||||
{
|
||||
struct Object *obj = &fake->object;
|
||||
|
||||
if (obj->oHeldState != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m->marioObj->collidedObjInteractTypes |= obj->oInteractType;
|
||||
if (m->marioObj->numCollidedObjs < 4)
|
||||
{
|
||||
m->marioObj->collidedObjs[m->marioObj->numCollidedObjs++] = obj;
|
||||
}
|
||||
}
|
||||
|
||||
void fake_object_apply_pole(struct FakeObject *fake)
|
||||
{
|
||||
(void)fake;
|
||||
}
|
||||
|
||||
void fake_object_set_preset(struct FakeObject *fake, uint32_t preset)
|
||||
{
|
||||
struct Object *obj = &fake->object;
|
||||
|
||||
switch (preset)
|
||||
{
|
||||
case 1:
|
||||
obj->oInteractType = INTERACT_POLE;
|
||||
obj->oInteractionSubtype = 0;
|
||||
obj->hitboxRadius = 60.0f;
|
||||
obj->hitboxHeight = 1000.0f;
|
||||
obj->hitboxDownOffset = 0.0f;
|
||||
break;
|
||||
case 0: default:
|
||||
obj->oInteractType = 0;
|
||||
obj->oInteractionSubtype = 0;
|
||||
obj->hitboxRadius = 50.0f;
|
||||
obj->hitboxHeight = 100.0f;
|
||||
obj->hitboxDownOffset = 0.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// Created by nepushiro on 5/29/26.
|
||||
//
|
||||
|
||||
#ifndef LIBSM64_FAKEOBJECT_H
|
||||
#define LIBSM64_FAKEOBJECT_H
|
||||
|
||||
#endif //LIBSM64_FAKEOBJECT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <types.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct FakeObject
|
||||
{
|
||||
struct Object object;
|
||||
};
|
||||
|
||||
void fake_object_init(struct FakeObject *fake, float x, float y, float z);
|
||||
void fake_object_sync_position(struct FakeObject *fake);
|
||||
|
||||
bool fake_object_overlaps_mario(struct FakeObject *fake, struct MarioState *m);
|
||||
void fake_object_add_collision(struct FakeObject *fake, struct MarioState *m);
|
||||
void fake_object_apply_pole(struct FakeObject *fake);
|
||||
void fake_object_set_preset(struct FakeObject *fake, uint32_t preset);
|
||||
@@ -71,6 +71,62 @@ static u32 interact_noop(struct MarioState *m, u32 interactType, struct Object *
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void push_mario_out_of_object(struct MarioState *m, struct Object *o, f32 padding);
|
||||
void reset_mario_pitch(struct MarioState *m);
|
||||
|
||||
static u32 interact_pole(struct MarioState *m, u32 interactType, struct Object *o)
|
||||
{
|
||||
s32 actionId = m->action & ACT_ID_MASK;
|
||||
|
||||
if (actionId >= 0x080 && actionId < 0x0A0)
|
||||
{
|
||||
#if defined(VERSION_SH) || defined(VERSION_CN)
|
||||
f32 velConv = m->forwardVel; // conserve the velocity.
|
||||
struct Object *marioObj = m->marioObj;
|
||||
u32 lowSpeed;
|
||||
#else
|
||||
u32 lowSpeed = (m->forwardVel <= 10.0f);
|
||||
struct Object *marioObj = m->marioObj;
|
||||
#endif
|
||||
|
||||
if (!(m->prevAction & ACT_FLAG_ON_POLE) || m->usedObj != o)
|
||||
{
|
||||
#if defined(VERSION_SH) || defined(VERSION_CN)
|
||||
lowSpeed = (velConv <= 10.0f);
|
||||
#endif
|
||||
|
||||
mario_stop_riding_and_holding(m);
|
||||
|
||||
m->interactObj = o;
|
||||
m->usedObj = o;
|
||||
m->vel[1] = 0.0f;
|
||||
m->forwardVel = 0.0f;
|
||||
|
||||
marioObj->oMarioPoleUnk108 = 0;
|
||||
marioObj->oMarioPoleYawVel = 0;
|
||||
marioObj->oMarioPolePos = m->pos[1] - o->oPosY;
|
||||
|
||||
if (lowSpeed)
|
||||
{
|
||||
return set_mario_action(m, ACT_GRAB_POLE_SLOW, 0);
|
||||
}
|
||||
|
||||
#if defined(VERSION_SH) || defined(VERSION_CN)
|
||||
marioObj->oMarioPoleYawVel = (s32)(velConv * 0x100 + 0x1000);
|
||||
#else
|
||||
marioObj->oMarioPoleYawVel = (s32)(m->forwardVel * 0x100 + 0x1000);
|
||||
#endif
|
||||
reset_mario_pitch(m);
|
||||
#if ENABLE_RUMBLE
|
||||
queue_rumble_data(5, 80);
|
||||
#endif
|
||||
return set_mario_action(m, ACT_GRAB_POLE_FAST, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static struct InteractionHandler sInteractionHandlers[] = {
|
||||
{INTERACT_COIN, interact_noop},
|
||||
{INTERACT_WATER_RING, interact_noop},
|
||||
@@ -94,7 +150,7 @@ static struct InteractionHandler sInteractionHandlers[] = {
|
||||
{INTERACT_HIT_FROM_BELOW, interact_noop},
|
||||
{INTERACT_BOUNCE_TOP, interact_noop},
|
||||
{INTERACT_DAMAGE, interact_noop},
|
||||
{INTERACT_POLE, interact_noop},
|
||||
{INTERACT_POLE, interact_pole},
|
||||
{INTERACT_HOOT, interact_noop},
|
||||
{INTERACT_BREAKABLE, interact_noop},
|
||||
{INTERACT_KOOPA, interact_noop},
|
||||
|
||||
@@ -123,8 +123,7 @@ s32 set_pole_position(struct MarioState *m, f32 offsetY)
|
||||
}
|
||||
|
||||
vec3f_copy(m->marioObj->header.gfx.pos, m->pos);
|
||||
vec3s_set(m->marioObj->header.gfx.angle, m->usedObj->oMoveAnglePitch, m->faceAngle[1],
|
||||
m->usedObj->oMoveAngleRoll);
|
||||
vec3s_set(m->marioObj->header.gfx.angle, m->usedObj->oMoveAnglePitch, m->faceAngle[1], m->usedObj->oMoveAngleRoll);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -132,6 +131,7 @@ s32 set_pole_position(struct MarioState *m, f32 offsetY)
|
||||
s32 act_holding_pole(struct MarioState *m)
|
||||
{
|
||||
struct Object *marioObj = m->marioObj;
|
||||
f32 poleStickY = -m->controller->stickY;
|
||||
|
||||
#ifdef VERSION_JP
|
||||
if (m->input & INPUT_A_PRESSED)
|
||||
@@ -163,7 +163,7 @@ s32 act_holding_pole(struct MarioState *m)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m->controller->stickY > 16.0f)
|
||||
if (poleStickY > 16.0f)
|
||||
{
|
||||
f32 poleTop = m->usedObj->hitboxHeight - 100.0f;
|
||||
// const BehaviorScript *poleBehavior = virtual_to_segmented(0x13, m->usedObj->behavior);
|
||||
@@ -174,15 +174,15 @@ s32 act_holding_pole(struct MarioState *m)
|
||||
}
|
||||
|
||||
// if (poleBehavior != bhvGiantPole && m->controller->stickY > 50.0f) {
|
||||
if (m->controller->stickY > 50.0f)
|
||||
if (poleStickY > 50.0f)
|
||||
{
|
||||
return set_mario_action(m, ACT_TOP_OF_POLE_TRANSITION, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (m->controller->stickY < -16.0f)
|
||||
if (poleStickY < -16.0f)
|
||||
{
|
||||
marioObj->oMarioPoleYawVel -= m->controller->stickY * 2;
|
||||
marioObj->oMarioPoleYawVel -= poleStickY * 2;
|
||||
if (marioObj->oMarioPoleYawVel > 0x1000)
|
||||
{
|
||||
marioObj->oMarioPoleYawVel = 0x1000;
|
||||
@@ -223,6 +223,7 @@ s32 act_climbing_pole(struct MarioState *m)
|
||||
s32 sp24;
|
||||
struct Object *marioObj = m->marioObj;
|
||||
s16 cameraAngle = m->area->camera->yaw;
|
||||
f32 poleStickY = -m->controller->stickY;
|
||||
|
||||
#ifndef VERSION_JP
|
||||
if (m->health < 0x100)
|
||||
@@ -240,18 +241,18 @@ s32 act_climbing_pole(struct MarioState *m)
|
||||
return set_mario_action(m, ACT_WALL_KICK_AIR, 0);
|
||||
}
|
||||
|
||||
if (m->controller->stickY < 8.0f)
|
||||
if (poleStickY < 8.0f)
|
||||
{
|
||||
return set_mario_action(m, ACT_HOLDING_POLE, 0);
|
||||
}
|
||||
|
||||
marioObj->oMarioPolePos += m->controller->stickY / 8.0f;
|
||||
marioObj->oMarioPolePos += poleStickY / 8.0f;
|
||||
marioObj->oMarioPoleYawVel = 0;
|
||||
m->faceAngle[1] = cameraAngle - approach_s32((s16)(cameraAngle - m->faceAngle[1]), 0, 0x400, 0x400);
|
||||
|
||||
if (set_pole_position(m, 0.0f) == POLE_NONE)
|
||||
{
|
||||
sp24 = m->controller->stickY / 4.0f * 0x10000;
|
||||
sp24 = poleStickY / 4.0f * 0x10000;
|
||||
set_mario_anim_with_accel(m, MARIO_ANIM_CLIMB_UP_POLE, sp24);
|
||||
add_tree_leaf_particles(m);
|
||||
play_climbing_sounds(m, 1);
|
||||
@@ -336,12 +337,13 @@ s32 act_top_of_pole(struct MarioState *m)
|
||||
{
|
||||
UNUSED
|
||||
struct Object *marioObj = m->marioObj;
|
||||
f32 poleStickY = -m->controller->stickY;
|
||||
|
||||
if (m->input & INPUT_A_PRESSED)
|
||||
{
|
||||
return set_mario_action(m, ACT_TOP_OF_POLE_JUMP, 0);
|
||||
}
|
||||
if (m->controller->stickY < -16.0f)
|
||||
if (poleStickY < -16.0f)
|
||||
{
|
||||
return set_mario_action(m, ACT_TOP_OF_POLE_TRANSITION, 1);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../obj_pool.h"
|
||||
|
||||
struct GlobalState *g_state = 0;
|
||||
|
||||
struct GlobalState *global_state_create(void)
|
||||
@@ -21,5 +23,6 @@ void global_state_bind(struct GlobalState *state)
|
||||
|
||||
void global_state_delete(struct GlobalState *state)
|
||||
{
|
||||
obj_pool_free_all(&state->mgFakeObjects);
|
||||
free(state);
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "include/types.h"
|
||||
#include "game/area.h"
|
||||
#include "../obj_pool.h"
|
||||
|
||||
struct GlobalState
|
||||
{
|
||||
@@ -41,6 +42,7 @@ struct GlobalState
|
||||
struct Area *mgCurrentArea;
|
||||
struct Object *mgCurrentObject;
|
||||
struct Object *mgMarioObject;
|
||||
struct ObjPool mgFakeObjects;
|
||||
struct MarioAnimation mD_80339D10;
|
||||
struct MarioState mgMarioStateVal;
|
||||
};
|
||||
|
||||
+125
-9
@@ -38,6 +38,8 @@
|
||||
#include "load_tex_data.h"
|
||||
#include "obj_pool.h"
|
||||
#include "fake_interaction.h"
|
||||
#include "object_fields.h"
|
||||
#include "FakeObject.h"
|
||||
|
||||
static struct AllocOnlyPool *s_mario_geo_pool = NULL;
|
||||
static struct GraphNode *s_mario_graph_node = NULL;
|
||||
@@ -51,6 +53,7 @@ struct MarioInstance
|
||||
};
|
||||
|
||||
struct ObjPool s_mario_instance_pool = {0, 0};
|
||||
struct ObjPool s_fakeobj_instance_pool = {0, 0};
|
||||
|
||||
static void update_button(bool on, u16 button)
|
||||
{
|
||||
@@ -109,8 +112,7 @@ SM64_LIB_FN void sm64_register_play_sound_function(SM64PlaySoundFunctionPtr play
|
||||
|
||||
SM64_LIB_FN void sm64_global_init(const uint8_t *rom, uint8_t *outTexture)
|
||||
{
|
||||
if (s_init_global)
|
||||
sm64_global_terminate();
|
||||
if (s_init_global) sm64_global_terminate();
|
||||
|
||||
s_init_global = true;
|
||||
|
||||
@@ -128,9 +130,8 @@ SM64_LIB_FN void sm64_global_terminate(void)
|
||||
|
||||
if (s_init_one_mario)
|
||||
{
|
||||
for (int i = 0; i < s_mario_instance_pool.size; ++i)
|
||||
if (s_mario_instance_pool.objects[i] != NULL)
|
||||
sm64_mario_delete(i);
|
||||
for (int i = 0; i < s_mario_instance_pool.size; ++i) if (s_mario_instance_pool.objects[i] != NULL) sm64_mario_delete(i);
|
||||
for (int i = 0; i < s_fakeobj_instance_pool.size; ++i) if (s_fakeobj_instance_pool.objects[i] != NULL) sm64_fake_object_delete(i);
|
||||
|
||||
obj_pool_free_all(&s_mario_instance_pool);
|
||||
}
|
||||
@@ -257,6 +258,10 @@ SM64_LIB_FN void sm64_mario_tick(int32_t marioId, const struct SM64MarioInputs *
|
||||
|
||||
apply_mario_platform_displacement();
|
||||
bhv_mario_update();
|
||||
|
||||
gMarioState->marioObj->collidedObjInteractTypes = 0;
|
||||
gMarioState->marioObj->numCollidedObjs = 0;
|
||||
|
||||
update_mario_platform(); // TODO platform grabbed here and used next tick could be a use-after-free
|
||||
|
||||
gfx_adapter_bind_output_buffers(outBuffers);
|
||||
@@ -623,6 +628,119 @@ SM64_LIB_FN void sm64_mario_extend_cap(int32_t marioId, uint16_t capTime)
|
||||
gMarioState->capTimer += capTime;
|
||||
}
|
||||
|
||||
SM64_LIB_FN int32_t sm64_fake_object_create(float x, float y, float z, int32_t preset)
|
||||
{
|
||||
struct GlobalState *state = g_state;
|
||||
if (state == NULL)
|
||||
{
|
||||
DEBUG_PRINT("Tried to create fake object without an active Mario state.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t objectIndex = obj_pool_alloc_index(&s_fakeobj_instance_pool, sizeof(struct FakeObject));
|
||||
struct FakeObject *fake = (struct FakeObject *)s_fakeobj_instance_pool.objects[objectIndex];
|
||||
|
||||
fake_object_init(fake, x, y, z);
|
||||
fake_object_set_preset(fake, preset);
|
||||
return objectIndex;
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_fake_object_delete(int32_t objectId)
|
||||
{
|
||||
if (objectId >= s_fakeobj_instance_pool.size || s_fakeobj_instance_pool.objects[objectId] == NULL)
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Object with ID: %d", objectId);
|
||||
return;
|
||||
}
|
||||
struct FakeObject *fake = s_fakeobj_instance_pool.objects[objectId];
|
||||
|
||||
struct MarioState *m = &g_state->mgMarioStateVal;
|
||||
uint32_t action = m->action;
|
||||
|
||||
if (m->interactObj == &fake->object || m->usedObj == &fake->object || m->heldObj == &fake->object)
|
||||
{
|
||||
m->interactObj = NULL;
|
||||
m->usedObj = NULL;
|
||||
m->heldObj = NULL;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case ACT_HOLDING_POLE:
|
||||
case ACT_CLIMBING_POLE:
|
||||
case ACT_TOP_OF_POLE:
|
||||
m->action = ACT_FREEFALL;
|
||||
break;
|
||||
|
||||
default:
|
||||
m->action = ACT_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
m->actionState = 0;
|
||||
}
|
||||
if (m->marioBodyState != NULL && m->heldObj == NULL)
|
||||
{
|
||||
vec3f_set(m->marioBodyState->heldObjLastPosition, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
obj_pool_free_index(&s_fakeobj_instance_pool, (uint32_t)objectId);
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_fake_object_set_position(int32_t objectId, float x, float y, float z)
|
||||
{
|
||||
if (objectId >= s_fakeobj_instance_pool.size || s_fakeobj_instance_pool.objects[objectId] == NULL)
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Object with ID: %d", objectId);
|
||||
return;
|
||||
}
|
||||
struct FakeObject *fake = s_fakeobj_instance_pool.objects[objectId];
|
||||
|
||||
fake->object.oPosX = x;
|
||||
fake->object.oPosY = y;
|
||||
fake->object.oPosZ = z;
|
||||
fake_object_sync_position(fake);
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_fake_object_set_hitbox(int32_t objectId, float radius, float height, float downOffset)
|
||||
{
|
||||
if (objectId >= s_fakeobj_instance_pool.size || s_fakeobj_instance_pool.objects[objectId] == NULL)
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Object with ID: %d", objectId);
|
||||
return;
|
||||
}
|
||||
struct FakeObject *fake = s_fakeobj_instance_pool.objects[objectId];
|
||||
|
||||
fake->object.hitboxRadius = radius;
|
||||
fake->object.hitboxHeight = height;
|
||||
fake->object.hitboxDownOffset = downOffset;
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_fake_object_tick(int32_t objectId)
|
||||
{
|
||||
if (objectId >= s_fakeobj_instance_pool.size || s_fakeobj_instance_pool.objects[objectId] == NULL)
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Object with ID: %d", objectId);
|
||||
return;
|
||||
}
|
||||
struct FakeObject *fake = s_fakeobj_instance_pool.objects[objectId];
|
||||
|
||||
struct GlobalState *state = g_state;
|
||||
struct MarioState *m = state != NULL ? &state->mgMarioStateVal : NULL;
|
||||
struct Object *obj = &fake->object;
|
||||
|
||||
obj->oInteractStatus = 0;
|
||||
|
||||
if (m == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (fake_object_overlaps_mario(fake, m))
|
||||
{
|
||||
fake_object_add_collision(fake, m);
|
||||
}
|
||||
}
|
||||
|
||||
SM64_LIB_FN bool sm64_mario_attack(int32_t marioId, float x, float y, float z, float hitboxHeight)
|
||||
{
|
||||
if (marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL)
|
||||
@@ -653,12 +771,10 @@ SM64_LIB_FN void sm64_surface_object_delete(uint32_t objectId)
|
||||
// A mario standing on the platform that is being destroyed will have a pointer to freed memory if we don't clear it.
|
||||
for (int i = 0; i < s_mario_instance_pool.size; ++i)
|
||||
{
|
||||
if (s_mario_instance_pool.objects[i] == NULL)
|
||||
continue;
|
||||
if (s_mario_instance_pool.objects[i] == NULL) continue;
|
||||
|
||||
struct GlobalState *state = ((struct MarioInstance *)s_mario_instance_pool.objects[i])->globalState;
|
||||
if (state->mgMarioObject->platform == surfaces_object_get_transform_ptr(objectId))
|
||||
state->mgMarioObject->platform = NULL;
|
||||
if (state->mgMarioObject->platform == surfaces_object_get_transform_ptr(objectId)) state->mgMarioObject->platform = NULL;
|
||||
}
|
||||
|
||||
surfaces_unload_object(objectId);
|
||||
|
||||
+17
-2
@@ -1,9 +1,12 @@
|
||||
#ifndef LIB_SM64_H
|
||||
#define LIB_SM64_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifdef SM64_LIB_EXPORT
|
||||
@@ -146,7 +149,9 @@ struct SM64SurfaceCollisionData
|
||||
|
||||
enum
|
||||
{
|
||||
SM64_TEXTURE_WIDTH = 64 * 11, SM64_TEXTURE_HEIGHT = 64, SM64_GEO_MAX_TRIANGLES = 1024,
|
||||
SM64_TEXTURE_WIDTH = 64 * 11,
|
||||
SM64_TEXTURE_HEIGHT = 64,
|
||||
SM64_GEO_MAX_TRIANGLES = 1024,
|
||||
};
|
||||
|
||||
typedef void (*SM64RumbleCallbackFunctionPtr)(int32_t marioId, int16_t level, int16_t time);
|
||||
@@ -259,6 +264,16 @@ extern SM64_LIB_FN uint16_t sm64_get_current_background_music();
|
||||
|
||||
extern SM64_LIB_FN void sm64_play_sound(int32_t soundBits, float *pos);
|
||||
|
||||
extern SM64_LIB_FN int32_t sm64_fake_object_create(float x, float y, float z, int32_t preset);
|
||||
|
||||
extern SM64_LIB_FN void sm64_fake_object_delete(int32_t objectId);
|
||||
|
||||
extern SM64_LIB_FN void sm64_fake_object_set_position(int32_t objectId, float x, float y, float z);
|
||||
|
||||
extern SM64_LIB_FN void sm64_fake_object_set_hitbox(int32_t objectId, float radius, float height, float downOffset);
|
||||
|
||||
extern SM64_LIB_FN void sm64_fake_object_tick(int32_t objectId);
|
||||
|
||||
extern SM64_LIB_FN void sm64_play_sound_global(int32_t soundBits);
|
||||
|
||||
extern SM64_LIB_FN void sm64_set_sound_volume(float vol);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "decomp/include/types.h"
|
||||
#include "decomp/include/surface_terrains.h"
|
||||
|
||||
@@ -800,6 +800,9 @@ int main(void)
|
||||
sm64_static_surfaces_load(surfaces, surfaces_count);
|
||||
int32_t marioId = sm64_mario_create(-6558, 0, 6464);
|
||||
|
||||
int thing = sm64_fake_object_create(-6558.0f, 0.0f, 6200.0f, 1);
|
||||
sm64_fake_object_set_hitbox(thing, 32.0f, 800.0f * 2, 800);
|
||||
|
||||
printf("MarioID: %i\n", marioId);
|
||||
free(rom);
|
||||
|
||||
@@ -958,6 +961,7 @@ int main(void)
|
||||
|
||||
tick -= 1.f / 30;
|
||||
sm64_mario_tick(marioId, &marioInputs, &marioState, &marioGeometry);
|
||||
sm64_fake_object_tick(thing);
|
||||
|
||||
memcpy(currPos, marioState.position, sizeof(currPos));
|
||||
memcpy(currGeoPos, marioGeometry.position, sizeof(currGeoPos));
|
||||
|
||||
Reference in New Issue
Block a user