Merge pull request #29 from headshot2017/master
add functions to play sound/music and more
This commit is contained in:
@@ -24,7 +24,7 @@ project under the `test` directory as well, demonstrating usage of the library.
|
||||
- Run `make` to build. If you want to link musl libc instead of glibc run `LIBSM64_MUSL=1 make` instead.
|
||||
- To run the test program you'll need a SM64 US ROM in the root of the repository with the name `baserom.us.z64`.
|
||||
|
||||
## Building on Windows (test program not supported)
|
||||
## Building on Windows
|
||||
- [Follow steps 1-4 for setting up MSYS2 MinGW 64 here](https://github.com/sm64-port/sm64-port#windows), but replace the repository URL with `https://github.com/libsm64/libsm64.git`
|
||||
- Run `make` to build
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#define LEVEL_BOUNDARY_MAX 0x2000
|
||||
#define CELL_SIZE 0x400
|
||||
|
||||
#define CELL_HEIGHT_LIMIT 20000.f
|
||||
#define FLOOR_LOWER_LIMIT -11000.f
|
||||
#define CELL_HEIGHT_LIMIT 100000.f
|
||||
#define FLOOR_LOWER_LIMIT -110000.f
|
||||
|
||||
s32 f32_find_wall_collision(f32 *xPtr, f32 *yPtr, f32 *zPtr, f32 offsetY, f32 radius);
|
||||
s32 find_wall_collisions(struct SM64WallCollisionData *colData);
|
||||
|
||||
@@ -1321,7 +1321,7 @@ void update_mario_joystick_inputs(struct MarioState *m) {
|
||||
* Resolves wall collisions, and updates a variety of inputs.
|
||||
*/
|
||||
void update_mario_geometry_inputs(struct MarioState *m) {
|
||||
f32 gasLevel;
|
||||
//f32 gasLevel;
|
||||
f32 ceilToFloorDist;
|
||||
|
||||
f32_find_wall_collision(&m->pos[0], &m->pos[1], &m->pos[2], 60.0f, 50.0f);
|
||||
@@ -1343,8 +1343,8 @@ void update_mario_geometry_inputs(struct MarioState *m) {
|
||||
}
|
||||
|
||||
m->ceilHeight = vec3f_find_ceil(&m->pos[0], m->floorHeight, &m->ceil);
|
||||
gasLevel = find_poison_gas_level(m->pos[0], m->pos[2]);
|
||||
m->waterLevel = find_water_level(m->pos[0], m->pos[2]);
|
||||
//gasLevel = find_poison_gas_level(m->pos[0], m->pos[2]);
|
||||
//m->waterLevel = find_water_level(m->pos[0], m->pos[2]);
|
||||
|
||||
if (m->floor != NULL) {
|
||||
m->floorAngle = atan2s(m->floor->normal.z, m->floor->normal.x);
|
||||
@@ -1371,7 +1371,7 @@ void update_mario_geometry_inputs(struct MarioState *m) {
|
||||
m->input |= INPUT_IN_WATER;
|
||||
}
|
||||
|
||||
if (m->pos[1] < (gasLevel - 100.0f)) {
|
||||
if (m->pos[1] < (m->gasLevel - 100.0f)) {
|
||||
m->input |= INPUT_IN_POISON_GAS;
|
||||
}
|
||||
|
||||
@@ -1831,6 +1831,8 @@ int init_mario(void) {
|
||||
|
||||
gMarioState->waterLevel =
|
||||
find_water_level(gMarioSpawnInfo->startPos[0], gMarioSpawnInfo->startPos[2]);
|
||||
gMarioState->gasLevel =
|
||||
find_poison_gas_level(gMarioSpawnInfo->startPos[0], gMarioSpawnInfo->startPos[2]);
|
||||
|
||||
gMarioState->area = gCurrentArea;
|
||||
gMarioState->marioObj = gMarioObject;
|
||||
|
||||
@@ -612,6 +612,8 @@ s32 act_ledge_climb_slow(struct MarioState *m) {
|
||||
return let_go_of_ledge(m);
|
||||
}
|
||||
|
||||
m->actionTimer++;
|
||||
|
||||
if (m->actionTimer >= 28
|
||||
&& (m->input
|
||||
& (INPUT_NONZERO_ANALOG | INPUT_A_PRESSED | INPUT_OFF_FLOOR | INPUT_ABOVE_SLIDE))) {
|
||||
|
||||
@@ -331,14 +331,14 @@ s32 act_sleeping(struct MarioState *m) {
|
||||
}
|
||||
|
||||
s32 act_waking_up(struct MarioState *m) {
|
||||
// if (!m->actionTimer) {
|
||||
// func_803205E8(SOUND_MARIO_SNORING1, m->marioObj->header.gfx.cameraToObject);
|
||||
// func_803205E8(SOUND_MARIO_SNORING2, m->marioObj->header.gfx.cameraToObject);
|
||||
//#ifndef VERSION_JP
|
||||
// func_803205E8(SOUND_MARIO_SNORING3, m->marioObj->header.gfx.cameraToObject);
|
||||
//#endif
|
||||
// raise_background_noise(2);
|
||||
// }
|
||||
if (!m->actionTimer) {
|
||||
stop_sound(SOUND_MARIO_SNORING1, m->marioObj->header.gfx.cameraToObject);
|
||||
stop_sound(SOUND_MARIO_SNORING2, m->marioObj->header.gfx.cameraToObject);
|
||||
#ifndef VERSION_JP
|
||||
stop_sound(SOUND_MARIO_SNORING3, m->marioObj->header.gfx.cameraToObject);
|
||||
#endif
|
||||
raise_background_noise(2);
|
||||
}
|
||||
|
||||
if (m->input & INPUT_UNKNOWN_10) {
|
||||
return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
|
||||
|
||||
@@ -269,7 +269,8 @@ static s32 perform_ground_quarter_step(struct MarioState *m, Vec3f nextPos) {
|
||||
floorHeight = find_floor(nextPos[0], nextPos[1], nextPos[2], &floor);
|
||||
ceilHeight = vec3f_find_ceil(nextPos, floorHeight, &ceil);
|
||||
|
||||
waterLevel = find_water_level(nextPos[0], nextPos[2]);
|
||||
//waterLevel = find_water_level(nextPos[0], nextPos[2]);
|
||||
waterLevel = m->waterLevel;
|
||||
|
||||
m->wall = upperWall;
|
||||
|
||||
@@ -403,7 +404,8 @@ s32 perform_air_quarter_step(struct MarioState *m, Vec3f intendedPos, u32 stepAr
|
||||
floorHeight = find_floor(nextPos[0], nextPos[1], nextPos[2], &floor);
|
||||
ceilHeight = vec3f_find_ceil(nextPos, floorHeight, &ceil);
|
||||
|
||||
waterLevel = find_water_level(nextPos[0], nextPos[2]);
|
||||
//waterLevel = find_water_level(nextPos[0], nextPos[2]);
|
||||
waterLevel = m->waterLevel;
|
||||
|
||||
m->wall = NULL;
|
||||
|
||||
|
||||
@@ -325,6 +325,7 @@ struct MarioState
|
||||
/*0xC4*/ f32 unkC4;
|
||||
|
||||
u16 curTerrain; // libsm64: added field
|
||||
s32 gasLevel; // libsm64: added field
|
||||
};
|
||||
|
||||
#endif // TYPES_H
|
||||
|
||||
@@ -0,0 +1,301 @@
|
||||
#include "decomp/global_state.h"
|
||||
|
||||
#include "debug_print.h"
|
||||
#include "load_surfaces.h"
|
||||
#include "gfx_adapter.h"
|
||||
#include "load_anim_data.h"
|
||||
#include "load_tex_data.h"
|
||||
#include "obj_pool.h"
|
||||
|
||||
#include "decomp/game/interaction.h"
|
||||
#include "decomp/include/object_fields.h"
|
||||
#include "decomp/include/sm64.h"
|
||||
#include "decomp/shim.h"
|
||||
#include "decomp/game/mario.h"
|
||||
#include "decomp/engine/math_util.h"
|
||||
#include "fake_interaction.h"
|
||||
|
||||
#define INT_GROUND_POUND_OR_TWIRL (1 << 0) // 0x01
|
||||
#define INT_PUNCH (1 << 1) // 0x02
|
||||
#define INT_KICK (1 << 2) // 0x04
|
||||
#define INT_TRIP (1 << 3) // 0x08
|
||||
#define INT_SLIDE_KICK (1 << 4) // 0x10
|
||||
#define INT_FAST_ATTACK_OR_SHELL (1 << 5) // 0x20
|
||||
#define INT_HIT_FROM_ABOVE (1 << 6) // 0x40
|
||||
#define INT_HIT_FROM_BELOW (1 << 7) // 0x80
|
||||
|
||||
#define INT_ATTACK_NOT_FROM_BELOW \
|
||||
(INT_GROUND_POUND_OR_TWIRL | INT_PUNCH | INT_KICK | INT_TRIP | INT_SLIDE_KICK \
|
||||
| INT_FAST_ATTACK_OR_SHELL | INT_HIT_FROM_ABOVE)
|
||||
|
||||
#define INT_ANY_ATTACK \
|
||||
(INT_GROUND_POUND_OR_TWIRL | INT_PUNCH | INT_KICK | INT_TRIP | INT_SLIDE_KICK \
|
||||
| INT_FAST_ATTACK_OR_SHELL | INT_HIT_FROM_ABOVE | INT_HIT_FROM_BELOW)
|
||||
|
||||
#define INT_ATTACK_NOT_WEAK_FROM_ABOVE \
|
||||
(INT_GROUND_POUND_OR_TWIRL | INT_PUNCH | INT_KICK | INT_TRIP | INT_HIT_FROM_BELOW)
|
||||
|
||||
#define sDelayInvincTimer (g_state->msDelayInvincTimer)
|
||||
#define sInvulnerable (g_state->msInvulnerable)
|
||||
|
||||
static u32 sForwardKnockbackActions[][3] = {
|
||||
{ ACT_SOFT_FORWARD_GROUND_KB, ACT_FORWARD_GROUND_KB, ACT_HARD_FORWARD_GROUND_KB },
|
||||
{ ACT_FORWARD_AIR_KB, ACT_FORWARD_AIR_KB, ACT_HARD_FORWARD_AIR_KB },
|
||||
{ ACT_FORWARD_WATER_KB, ACT_FORWARD_WATER_KB, ACT_FORWARD_WATER_KB },
|
||||
};
|
||||
|
||||
static u32 sBackwardKnockbackActions[][3] = {
|
||||
{ ACT_SOFT_BACKWARD_GROUND_KB, ACT_BACKWARD_GROUND_KB, ACT_HARD_BACKWARD_GROUND_KB },
|
||||
{ ACT_BACKWARD_AIR_KB, ACT_BACKWARD_AIR_KB, ACT_HARD_BACKWARD_AIR_KB },
|
||||
{ ACT_BACKWARD_WATER_KB, ACT_BACKWARD_WATER_KB, ACT_BACKWARD_WATER_KB },
|
||||
};
|
||||
|
||||
uint32_t fake_damage_knock_back(struct MarioState *m, uint32_t damage,uint32_t interactionSubtype,float xSrc,float ySrc,float zSrc) {
|
||||
|
||||
if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)
|
||||
&& !(interactionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
||||
//o->oInteractStatus = INT_STATUS_INTERACTED | INT_STATUS_ATTACKED_MARIO;
|
||||
//m->interactObj = o;
|
||||
|
||||
// calculate damage, substitute for take_damage_from_interact_object
|
||||
if (!(m->flags & MARIO_CAP_ON_HEAD)) {
|
||||
damage += (damage + 1) / 2;
|
||||
}
|
||||
|
||||
if (m->flags & MARIO_METAL_CAP) {
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
m->hurtCounter += 4 * damage; // apply hurt counter
|
||||
|
||||
if (interactionSubtype & INT_SUBTYPE_BIG_KNOCKBACK) {
|
||||
m->forwardVel = 40.0f;
|
||||
}
|
||||
|
||||
if (damage > 0) {
|
||||
play_sound(SOUND_MARIO_ATTACKED, m->marioObj->header.gfx.cameraToObject);
|
||||
}
|
||||
|
||||
//update_mario_sound_and_camera(m);
|
||||
return drop_and_set_mario_action(m, fake_determine_knockback_action(m, damage,xSrc,ySrc,zSrc),
|
||||
damage);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
s16 fake_mario_obj_angle_to_object(struct MarioState *m, float xSrc,float zSrc) {
|
||||
f32 dx = xSrc - m->pos[0];
|
||||
f32 dz = zSrc - m->pos[2];
|
||||
|
||||
return atan2s(dz, dx);
|
||||
}
|
||||
|
||||
u32 fake_determine_knockback_action(struct MarioState *m, s32 damage,float xSrc,float ySrc,float zSrc) {
|
||||
u32 bonkAction;
|
||||
|
||||
s16 terrainIndex = 0; // 1 = air, 2 = water, 0 = default
|
||||
s16 strengthIndex = 0;
|
||||
|
||||
s16 angleToObject = fake_mario_obj_angle_to_object(m, xSrc,zSrc);
|
||||
s16 facingDYaw = angleToObject - m->faceAngle[1];
|
||||
s16 remainingHealth = m->health - 0x40 * m->hurtCounter;
|
||||
|
||||
if (m->action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER)) {
|
||||
terrainIndex = 2;
|
||||
} else if (m->action & (ACT_FLAG_AIR | ACT_FLAG_ON_POLE | ACT_FLAG_HANGING)) {
|
||||
terrainIndex = 1;
|
||||
}
|
||||
|
||||
if (remainingHealth < 0x100) {
|
||||
strengthIndex = 2;
|
||||
} else if (damage >= 4) {
|
||||
strengthIndex = 2;
|
||||
} else if (damage >= 2) {
|
||||
strengthIndex = 1;
|
||||
}
|
||||
|
||||
m->faceAngle[1] = angleToObject;
|
||||
|
||||
if (terrainIndex == 2) {
|
||||
if (m->forwardVel < 28.0f) {
|
||||
mario_set_forward_vel(m, 28.0f);
|
||||
}
|
||||
|
||||
if (m->pos[1] >= ySrc) {
|
||||
if (m->vel[1] < 20.0f) {
|
||||
m->vel[1] = 20.0f;
|
||||
}
|
||||
} else {
|
||||
if (m->vel[1] > 0.0f) {
|
||||
m->vel[1] = 0.0f;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (m->forwardVel < 16.0f) {
|
||||
mario_set_forward_vel(m, 16.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (-0x4000 <= facingDYaw && facingDYaw <= 0x4000) {
|
||||
m->forwardVel *= -1.0f;
|
||||
bonkAction = sBackwardKnockbackActions[terrainIndex][strengthIndex];
|
||||
} else {
|
||||
m->faceAngle[1] += 0x8000;
|
||||
bonkAction = sForwardKnockbackActions[terrainIndex][strengthIndex];
|
||||
}
|
||||
|
||||
return bonkAction;
|
||||
}
|
||||
|
||||
s16 fake_mario_obj_angle_to_pos(struct MarioState *m, float x, float z) {
|
||||
f32 dx = x - m->pos[0];
|
||||
f32 dz = z - m->pos[2];
|
||||
|
||||
return atan2s(dz, dx);
|
||||
}
|
||||
|
||||
void fake_bounce_back_from_attack(struct MarioState *m, u32 interaction) {
|
||||
if (interaction & (INT_PUNCH | INT_KICK | INT_TRIP)) {
|
||||
if (m->action == ACT_PUNCHING) {
|
||||
m->action = ACT_MOVE_PUNCHING;
|
||||
}
|
||||
|
||||
if (m->action & ACT_FLAG_AIR) {
|
||||
mario_set_forward_vel(m, -16.0f);
|
||||
} else {
|
||||
mario_set_forward_vel(m, -48.0f);
|
||||
}
|
||||
|
||||
//set_camera_shake_from_hit(SHAKE_ATTACK);
|
||||
m->particleFlags |= PARTICLE_TRIANGLE;
|
||||
}
|
||||
|
||||
if (interaction & (INT_PUNCH | INT_KICK | INT_TRIP | INT_FAST_ATTACK_OR_SHELL)) {
|
||||
play_sound(SOUND_ACTION_HIT_2, m->marioObj->header.gfx.cameraToObject);
|
||||
}
|
||||
}
|
||||
|
||||
u32 fake_determine_interaction(struct MarioState *m, float x, float y, float z) {
|
||||
u32 interaction = 0;
|
||||
u32 action = m->action;
|
||||
|
||||
s16 dYawToObject = fake_mario_obj_angle_to_pos(m, x, z) - m->faceAngle[1];
|
||||
if (action & ACT_FLAG_ATTACKING) {
|
||||
if (action == ACT_PUNCHING || action == ACT_MOVE_PUNCHING || action == ACT_JUMP_KICK) {
|
||||
|
||||
|
||||
if (m->flags & MARIO_PUNCHING) {
|
||||
// 120 degrees total, or 60 each way
|
||||
if (-0x2AAA <= dYawToObject && dYawToObject <= 0x2AAA) {
|
||||
interaction = INT_PUNCH;
|
||||
}
|
||||
}
|
||||
if (m->flags & MARIO_KICKING) {
|
||||
// 120 degrees total, or 60 each way
|
||||
if (-0x2AAA <= dYawToObject && dYawToObject <= 0x2AAA) {
|
||||
interaction = INT_KICK;
|
||||
}
|
||||
}
|
||||
if (m->flags & MARIO_TRIPPING) {
|
||||
// 180 degrees total, or 90 each way
|
||||
if (-0x4000 <= dYawToObject && dYawToObject <= 0x4000) {
|
||||
interaction = INT_TRIP;
|
||||
}
|
||||
}
|
||||
} else if (action == ACT_GROUND_POUND || action == ACT_TWIRLING) {
|
||||
if (m->vel[1] < 0.0f) {
|
||||
interaction = INT_GROUND_POUND_OR_TWIRL;
|
||||
}
|
||||
} else if (action == ACT_GROUND_POUND_LAND || action == ACT_TWIRL_LAND) {
|
||||
// Neither ground pounding nor twirling change Mario's vertical speed on landing.,
|
||||
// so the speed check is nearly always true (perhaps not if you land while going upwards?)
|
||||
// Additionally, actionState it set on each first thing in their action, so this is
|
||||
// only true prior to the very first frame (i.e. active 1 frame prior to it run).
|
||||
if (m->vel[1] < 0.0f && m->actionState == 0) {
|
||||
interaction = INT_GROUND_POUND_OR_TWIRL;
|
||||
}
|
||||
} else if (action == ACT_SLIDE_KICK || action == ACT_SLIDE_KICK_SLIDE) {
|
||||
interaction = INT_SLIDE_KICK;
|
||||
} else if (action & ACT_FLAG_RIDING_SHELL) {
|
||||
interaction = INT_FAST_ATTACK_OR_SHELL;
|
||||
} else if (m->forwardVel <= -26.0f || 26.0f <= m->forwardVel) {
|
||||
interaction = INT_FAST_ATTACK_OR_SHELL;
|
||||
}
|
||||
}
|
||||
|
||||
// Prior to this, the interaction type could be overwritten. This requires, however,
|
||||
// that the interaction not be set prior. This specifically overrides turning a ground
|
||||
// pound into just a bounce.
|
||||
if (interaction == 0 && (action & ACT_FLAG_AIR)) {
|
||||
if (m->vel[1] < 0.0f) {
|
||||
if (m->pos[1] > y) {
|
||||
interaction = INT_HIT_FROM_ABOVE;
|
||||
}
|
||||
} else {
|
||||
if (m->pos[1] < y) {
|
||||
interaction = INT_HIT_FROM_BELOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return interaction;
|
||||
}
|
||||
|
||||
void fake_bounce_off_object(struct MarioState *m, float x, float y, float z, float hitboxHeight, f32 velY) {
|
||||
//m->pos[1] = y + hitboxHeight;
|
||||
m->vel[1] = velY;
|
||||
|
||||
m->flags &= ~MARIO_UNKNOWN_08;
|
||||
|
||||
play_sound(SOUND_ACTION_BOUNCE_OFF_OBJECT, m->marioObj->header.gfx.cameraToObject);
|
||||
}
|
||||
|
||||
u32 fake_interact_hit_from_below(struct MarioState *m, float x, float y, float z, float hitboxHeight) {
|
||||
|
||||
u32 interaction;
|
||||
if (m->flags & MARIO_METAL_CAP) {
|
||||
interaction = INT_FAST_ATTACK_OR_SHELL;
|
||||
} else {
|
||||
interaction = fake_determine_interaction(m, x, y, z);
|
||||
}
|
||||
|
||||
if (interaction & INT_ANY_ATTACK) {
|
||||
fake_bounce_back_from_attack(m, interaction);
|
||||
|
||||
if (interaction & INT_HIT_FROM_BELOW) {
|
||||
m->vel[1] = 0.0f;
|
||||
}
|
||||
|
||||
if (interaction & INT_HIT_FROM_ABOVE) {
|
||||
fake_bounce_off_object(m, x, y, z, hitboxHeight, 30.0f);
|
||||
}
|
||||
return TRUE;
|
||||
} else/* if (fake_damage_knock_back(m, 0, 0, x, y, z))*/ {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u32 fake_interact_bounce_top(struct MarioState *m, float x, float y, float z, float hitboxHeight) {
|
||||
u32 interaction;
|
||||
if (m->flags & MARIO_METAL_CAP) {
|
||||
interaction = INT_FAST_ATTACK_OR_SHELL;
|
||||
} else {
|
||||
interaction = fake_determine_interaction(m, x, y, z);
|
||||
}
|
||||
|
||||
if (interaction & INT_ATTACK_NOT_FROM_BELOW) {
|
||||
fake_bounce_back_from_attack(m, interaction);
|
||||
|
||||
if (interaction & INT_HIT_FROM_ABOVE) {
|
||||
fake_bounce_off_object(m, x, y, z, hitboxHeight, 30.0f);
|
||||
}
|
||||
return TRUE;
|
||||
} else/* if (fake_damage_knock_back(m, 0, 0, x, y, z))*/ {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "decomp/include/types.h"
|
||||
|
||||
u32 fake_determine_knockback_action(struct MarioState *m, s32 damage,float xSrc,float ySrc,float zSrc);
|
||||
s16 fake_mario_obj_angle_to_object(struct MarioState *m, float xSrc,float zSrc);
|
||||
uint32_t fake_damage_knock_back(struct MarioState *m, uint32_t damage,uint32_t interactionSubtype,float xSrc,float ySrc,float zSrc);
|
||||
u32 fake_interact_hit_from_below(struct MarioState *m, float x, float y, float z, float hitboxHeight);
|
||||
u32 fake_interact_bounce_top(struct MarioState *m, float x, float y, float z, float hitboxHeight);
|
||||
+332
@@ -14,6 +14,7 @@
|
||||
#include "decomp/include/PR/os_cont.h"
|
||||
#include "decomp/engine/math_util.h"
|
||||
#include "decomp/include/sm64.h"
|
||||
#include "decomp/include/seq_ids.h"
|
||||
#include "decomp/shim.h"
|
||||
#include "decomp/memory.h"
|
||||
#include "decomp/global_state.h"
|
||||
@@ -33,6 +34,7 @@
|
||||
#include "load_audio_data.h"
|
||||
#include "load_tex_data.h"
|
||||
#include "obj_pool.h"
|
||||
#include "fake_interaction.h"
|
||||
|
||||
static struct AllocOnlyPool *s_mario_geo_pool = NULL;
|
||||
static struct GraphNode *s_mario_graph_node = NULL;
|
||||
@@ -252,6 +254,10 @@ SM64_LIB_FN void sm64_mario_tick( int32_t marioId, const struct SM64MarioInputs
|
||||
vec3f_copy( outState->position, gMarioState->pos );
|
||||
vec3f_copy( outState->velocity, gMarioState->vel );
|
||||
outState->faceAngle = (float)gMarioState->faceAngle[1] / 32768.0f * 3.14159f;
|
||||
outState->action = gMarioState->action;
|
||||
outState->flags = gMarioState->flags;
|
||||
outState->particleFlags = gMarioState->particleFlags;
|
||||
outState->invincTimer = gMarioState->invincTimer;
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_mario_delete( int32_t marioId )
|
||||
@@ -265,6 +271,8 @@ SM64_LIB_FN void sm64_mario_delete( int32_t marioId )
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
stop_sound(SOUND_MARIO_SNORING3, gMarioState->marioObj->header.gfx.cameraToObject);
|
||||
|
||||
free( gMarioObject );
|
||||
free_area( gCurrentArea );
|
||||
|
||||
@@ -272,6 +280,290 @@ SM64_LIB_FN void sm64_mario_delete( int32_t marioId )
|
||||
obj_pool_free_index( &s_mario_instance_pool, marioId );
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_set_mario_action(int32_t marioId, uint32_t action)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
set_mario_action(gMarioState, action, 0);
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_set_mario_action_arg(int32_t marioId, uint32_t action, uint32_t actionArg)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
set_mario_action(gMarioState, action, actionArg);
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_set_mario_animation(int32_t marioId, int32_t animID)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
set_mario_animation(gMarioState, animID);
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_set_mario_anim_frame(int32_t marioId, int16_t animFrame)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
gMarioState->marioObj->header.gfx.animInfo.animFrame = animFrame;
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_set_mario_state(int32_t marioId, uint32_t flags)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
gMarioState->flags = flags;
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_set_mario_position(int32_t marioId, float x, float y, float z)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
gMarioState->pos[0] = x;
|
||||
gMarioState->pos[1] = y;
|
||||
gMarioState->pos[2] = z;
|
||||
vec3f_copy(gMarioState->marioObj->header.gfx.pos, gMarioState->pos);
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_set_mario_angle(int32_t marioId, float x, float y, float z)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
vec3s_set(gMarioState->faceAngle, (int16_t)(x / 3.14159f * 32768.f), (int16_t)(y / 3.14159f * 32768.f), (int16_t)(z / 3.14159f * 32768.f));
|
||||
vec3s_copy(gMarioState->marioObj->header.gfx.angle, gMarioState->faceAngle);
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_set_mario_faceangle(int32_t marioId, float y)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
gMarioState->faceAngle[1] = (int16_t)(y / 3.14159f * 32768.f);
|
||||
vec3s_set(gMarioState->marioObj->header.gfx.angle, 0, gMarioState->faceAngle[1], 0);
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_set_mario_velocity(int32_t marioId, float x, float y, float z)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
gMarioState->vel[0] = x;
|
||||
gMarioState->vel[1] = y;
|
||||
gMarioState->vel[2] = z;
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_set_mario_forward_velocity(int32_t marioId, float vel)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
gMarioState->forwardVel = vel;
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_set_mario_water_level(int32_t marioId, signed int level)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
gMarioState->waterLevel = level;
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_set_mario_gas_level(int32_t marioId, signed int level)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
gMarioState->gasLevel = level;
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_mario_take_damage(int32_t marioId, uint32_t damage, uint32_t subtype, float x, float y, float z)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
fake_damage_knock_back(gMarioState, damage, subtype, x, y, z);
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_mario_heal(int32_t marioId, uint8_t healCounter)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
gMarioState->healCounter += healCounter;
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_mario_kill(int32_t marioId)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
gMarioState->health = 0xff;
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_mario_interact_cap(int32_t marioId, uint32_t capFlag, uint16_t capTime, uint8_t playMusic)
|
||||
{
|
||||
if( marioId >= s_mario_instance_pool.size || s_mario_instance_pool.objects[marioId] == NULL )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
uint16_t capMusic = 0;
|
||||
if(gMarioState->action != ACT_GETTING_BLOWN && capFlag != 0)
|
||||
{
|
||||
gMarioState->flags &= ~MARIO_CAP_ON_HEAD & ~MARIO_CAP_IN_HAND;
|
||||
gMarioState->flags |= capFlag;
|
||||
|
||||
switch(capFlag)
|
||||
{
|
||||
case MARIO_VANISH_CAP:
|
||||
if(capTime == 0) capTime = 600;
|
||||
capMusic = SEQUENCE_ARGS(4, SEQ_EVENT_POWERUP);
|
||||
break;
|
||||
case MARIO_METAL_CAP:
|
||||
if(capTime == 0) capTime = 600;
|
||||
capMusic = SEQUENCE_ARGS(4, SEQ_EVENT_METAL_CAP);
|
||||
break;
|
||||
case MARIO_WING_CAP:
|
||||
if(capTime == 0) capTime = 1800;
|
||||
capMusic = SEQUENCE_ARGS(4, SEQ_EVENT_POWERUP);
|
||||
break;
|
||||
}
|
||||
|
||||
if (capTime > gMarioState->capTimer) {
|
||||
gMarioState->capTimer = capTime;
|
||||
}
|
||||
|
||||
if ((gMarioState->action & ACT_FLAG_IDLE) || gMarioState->action == ACT_WALKING) {
|
||||
gMarioState->flags |= MARIO_CAP_IN_HAND;
|
||||
set_mario_action(gMarioState, ACT_PUTTING_ON_CAP, 0);
|
||||
} else {
|
||||
gMarioState->flags |= MARIO_CAP_ON_HEAD;
|
||||
}
|
||||
|
||||
play_sound(SOUND_MENU_STAR_SOUND, gMarioState->marioObj->header.gfx.cameraToObject);
|
||||
play_sound(SOUND_MARIO_HERE_WE_GO, gMarioState->marioObj->header.gfx.cameraToObject);
|
||||
|
||||
if (playMusic != 0 && capMusic != 0) {
|
||||
play_cap_music(capMusic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
DEBUG_PRINT("Tried to use non-existant Mario with ID: %d", marioId);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct GlobalState *globalState = ((struct MarioInstance *)s_mario_instance_pool.objects[ marioId ])->globalState;
|
||||
global_state_bind( globalState );
|
||||
|
||||
return fake_interact_bounce_top(gMarioState, x, y, z, hitboxHeight);
|
||||
}
|
||||
|
||||
SM64_LIB_FN uint32_t sm64_surface_object_create( const struct SM64SurfaceObject *surfaceObject )
|
||||
{
|
||||
uint32_t id = surfaces_load_object( surfaceObject );
|
||||
@@ -339,3 +631,43 @@ SM64_LIB_FN float sm64_surface_find_poison_gas_level( float x, float z )
|
||||
{
|
||||
return find_poison_gas_level( x, z );
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_seq_player_play_sequence(uint8_t player, uint8_t seqId, uint16_t arg2)
|
||||
{
|
||||
seq_player_play_sequence(player,seqId,arg2);
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_play_music(uint8_t player, uint16_t seqArgs, uint16_t fadeTimer)
|
||||
{
|
||||
play_music(player,seqArgs,fadeTimer);
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_stop_background_music(uint16_t seqId)
|
||||
{
|
||||
stop_background_music(seqId);
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_fadeout_background_music(uint16_t arg0, uint16_t fadeOut)
|
||||
{
|
||||
fadeout_background_music(arg0,fadeOut);
|
||||
}
|
||||
|
||||
SM64_LIB_FN uint16_t sm64_get_current_background_music()
|
||||
{
|
||||
return get_current_background_music();
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_play_sound(int32_t soundBits, float *pos)
|
||||
{
|
||||
play_sound(soundBits,pos);
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_play_sound_global(int32_t soundBits)
|
||||
{
|
||||
play_sound(soundBits,gGlobalSoundSource);
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_set_sound_volume(float vol)
|
||||
{
|
||||
gAudioVolume = vol;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,10 @@ struct SM64MarioState
|
||||
float velocity[3];
|
||||
float faceAngle;
|
||||
int16_t health;
|
||||
uint32_t action;
|
||||
uint32_t flags;
|
||||
uint32_t particleFlags;
|
||||
int16_t invincTimer;
|
||||
};
|
||||
|
||||
struct SM64MarioGeometryBuffers
|
||||
@@ -142,6 +146,24 @@ extern SM64_LIB_FN int32_t sm64_mario_create( float x, float y, float z );
|
||||
extern SM64_LIB_FN void sm64_mario_tick( int32_t marioId, const struct SM64MarioInputs *inputs, struct SM64MarioState *outState, struct SM64MarioGeometryBuffers *outBuffers );
|
||||
extern SM64_LIB_FN void sm64_mario_delete( int32_t marioId );
|
||||
|
||||
extern SM64_LIB_FN void sm64_set_mario_action(int32_t marioId, uint32_t action);
|
||||
extern SM64_LIB_FN void sm64_set_mario_action_arg(int32_t marioId, uint32_t action, uint32_t actionArg);
|
||||
extern SM64_LIB_FN void sm64_set_mario_animation(int32_t marioId, int32_t animID);
|
||||
extern SM64_LIB_FN void sm64_set_mario_anim_frame(int32_t marioId, int16_t animFrame);
|
||||
extern SM64_LIB_FN void sm64_set_mario_state(int32_t marioId, uint32_t flags);
|
||||
extern SM64_LIB_FN void sm64_set_mario_position(int32_t marioId, float x, float y, float z);
|
||||
extern SM64_LIB_FN void sm64_set_mario_angle(int32_t marioId, float x, float y, float z);
|
||||
extern SM64_LIB_FN void sm64_set_mario_faceangle(int32_t marioId, float y);
|
||||
extern SM64_LIB_FN void sm64_set_mario_velocity(int32_t marioId, float x, float y, float z);
|
||||
extern SM64_LIB_FN void sm64_set_mario_forward_velocity(int32_t marioId, float vel);
|
||||
extern SM64_LIB_FN void sm64_set_mario_water_level(int32_t marioId, signed int level);
|
||||
extern SM64_LIB_FN void sm64_set_mario_gas_level(int32_t marioId, signed int level);
|
||||
extern SM64_LIB_FN void sm64_mario_take_damage(int32_t marioId, uint32_t damage, uint32_t subtype, float x, float y, float z);
|
||||
extern SM64_LIB_FN void sm64_mario_heal(int32_t marioId, uint8_t healCounter);
|
||||
extern SM64_LIB_FN void sm64_mario_kill(int32_t marioId);
|
||||
extern SM64_LIB_FN void sm64_mario_interact_cap(int32_t marioId, uint32_t capFlag, uint16_t capTime, uint8_t playMusic);
|
||||
extern SM64_LIB_FN bool sm64_mario_attack(int32_t marioId, float x, float y, float z, float hitboxHeight);
|
||||
|
||||
extern SM64_LIB_FN uint32_t sm64_surface_object_create( const struct SM64SurfaceObject *surfaceObject );
|
||||
extern SM64_LIB_FN void sm64_surface_object_move( uint32_t objectId, const struct SM64ObjectTransform *transform );
|
||||
extern SM64_LIB_FN void sm64_surface_object_delete( uint32_t objectId );
|
||||
@@ -155,4 +177,13 @@ extern SM64_LIB_FN float sm64_surface_find_floor( float xPos, float yPos, float
|
||||
extern SM64_LIB_FN float sm64_surface_find_water_level( float x, float z );
|
||||
extern SM64_LIB_FN float sm64_surface_find_poison_gas_level( float x, float z );
|
||||
|
||||
extern SM64_LIB_FN void sm64_seq_player_play_sequence(uint8_t player, uint8_t seqId, uint16_t arg2);
|
||||
extern SM64_LIB_FN void sm64_play_music(uint8_t player, uint16_t seqArgs, uint16_t fadeTimer);
|
||||
extern SM64_LIB_FN void sm64_stop_background_music(uint16_t seqId);
|
||||
extern SM64_LIB_FN void sm64_fadeout_background_music(uint16_t arg0, uint16_t fadeOut);
|
||||
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 void sm64_play_sound_global(int32_t soundBits);
|
||||
extern SM64_LIB_FN void sm64_set_sound_volume(float vol);
|
||||
|
||||
#endif//LIB_SM64_H
|
||||
|
||||
+4
-1
@@ -73,7 +73,7 @@ int main( void )
|
||||
sm64_global_init( rom, texture );
|
||||
sm64_audio_init(rom);
|
||||
sm64_static_surfaces_load( surfaces, surfaces_count );
|
||||
uint32_t marioId = sm64_mario_create( 0, 1000, 0 );
|
||||
int32_t marioId = sm64_mario_create( 0, 1000, 0 );
|
||||
|
||||
free( rom );
|
||||
|
||||
@@ -115,6 +115,8 @@ int main( void )
|
||||
|
||||
audio_init();
|
||||
|
||||
sm64_play_music(0, 0x05 | 0x80, 0); // from decomp/include/seq_ids.h: SEQ_LEVEL_WATER | SEQ_VARIATION
|
||||
|
||||
do
|
||||
{
|
||||
float dt = (SDL_GetTicks() - lastTicks) / 1000.f;
|
||||
@@ -219,6 +221,7 @@ int main( void )
|
||||
}
|
||||
while( context_flip_frame_poll_events() );
|
||||
|
||||
sm64_stop_background_music(sm64_get_current_background_music());
|
||||
sm64_global_terminate();
|
||||
context_terminate();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user