Synchronized seesaw, started moving toward a MAX_PLAYERS define

This commit is contained in:
MysterD 2020-08-06 22:52:32 -07:00
parent e86efb9e85
commit 5ec9ab9ec0
17 changed files with 126 additions and 65 deletions

View file

@ -372,4 +372,9 @@ struct MarioState
#define PLAY_MODE_FRAME_ADVANCE 5
#define PLAY_MODE_SYNC_LEVEL 6
// NOTE: this defines the maximum number of players...
// HOWEVER, simply increasing this to 3 will not magically work
// many things will have to be overhauled!
#define MAX_PLAYERS 2
#endif // _SM64_TYPES_H_

View file

@ -666,7 +666,7 @@ static void level_cmd_unload_area(void) {
}
static void level_cmd_set_mario_start_pos(void) {
for (int i = 0; i < 2; i++) {
for (int i = 0; i < MAX_PLAYERS; i++) {
gPlayerSpawnInfos[i].areaIndex = CMD_GET(u8, 2);
#if IS_64_BIT

View file

@ -24,7 +24,7 @@
#include "gfx_dimensions.h"
struct SpawnInfo gPlayerSpawnInfos[2];
struct SpawnInfo gPlayerSpawnInfos[MAX_PLAYERS];
struct GraphNode *D_8033A160[0x100];
struct Area gAreaData[8];

View file

@ -1033,7 +1033,7 @@ void bowser_free_update(void) {
struct Object *platform;
UNUSED f32 floorHeight;
if ((platform = o->platform) != NULL)
apply_platform_displacement(0, platform);
apply_platform_displacement((u32)-1, platform);
o->oBowserUnk10E = 0;
cur_obj_update_floor_and_walls();
cur_obj_call_action_function(sBowserActions);

View file

@ -23,6 +23,10 @@ void bhv_seesaw_platform_init(void) {
if (o->oBehParams2ndByte == 2) {
o->oCollisionDistance = 2000.0f;
}
network_init_object(o, 1000.0f);
network_init_object_field(o, &o->oSeesawPlatformPitchVel);
network_init_object_field(o, &o->oFaceAnglePitch);
}
/**
@ -36,9 +40,29 @@ void bhv_seesaw_platform_update(void) {
cur_obj_play_sound_1(SOUND_ENV_BOAT_ROCKING1);
}
if (gMarioObject->platform == o) {
f32 x = 0;
f32 y = 0;
f32 z = 0;
u8 playersTouched = 0;
for (int i = 0; i < MAX_PLAYERS; i++) {
if (gMarioStates[i].marioObj->platform == o) {
x += gMarioStates[i].marioObj->oPosX;
y += gMarioStates[i].marioObj->oPosY;
z += gMarioStates[i].marioObj->oPosZ;
playersTouched++;
}
}
if (playersTouched > 0) {
x /= (f32)playersTouched;
y /= (f32)playersTouched;
z /= (f32)playersTouched;
int distanceToPlayer = dist_between_object_and_point(o, x, y, z);
int angleToPlayer = obj_angle_to_point(o, x, y, z);
// Rotate toward mario
f32 rotation = o->oDistanceToMario * coss(o->oAngleToMario - o->oMoveAngleYaw);
f32 rotation = distanceToPlayer * coss(angleToPlayer - o->oMoveAngleYaw);
UNUSED s32 unused;
// Deceleration is faster than acceleration

View file

@ -89,7 +89,7 @@ Vec3f sOldFocus;
* Global array of PlayerCameraState.
* L is real.
*/
struct PlayerCameraState gPlayerCameraState[2];
struct PlayerCameraState gPlayerCameraState[MAX_PLAYERS];
/**
* Direction controlled by player 2, moves the focus during the credits.
*/

View file

@ -667,7 +667,7 @@ struct LakituState
extern s16 sSelectionFlags;
extern s16 sCameraSoundFlags;
extern u16 sCButtonsPressed;
extern struct PlayerCameraState gPlayerCameraState[2];
extern struct PlayerCameraState gPlayerCameraState[MAX_PLAYERS];
extern struct LakituState gLakituState;
extern s16 gCameraMovementFlags;
extern s32 gObjCutsceneDone;

View file

@ -43,9 +43,9 @@ OSMesg D_80339CD4;
struct VblankHandler gGameVblankHandler;
uintptr_t gPhysicalFrameBuffers[3];
uintptr_t gPhysicalZBuffer;
void *D_80339CF0[2];
void *D_80339CF0[MAX_PLAYERS];
void *D_80339CF4;
struct MarioAnimation D_80339D10[2];
struct MarioAnimation D_80339D10[MAX_PLAYERS];
struct MarioAnimation gDemo;
UNUSED u8 filler80339D30[0x90];
@ -547,7 +547,7 @@ void setup_game_memory(void) {
gPhysicalFrameBuffers[0] = VIRTUAL_TO_PHYSICAL(gFrameBuffer0);
gPhysicalFrameBuffers[1] = VIRTUAL_TO_PHYSICAL(gFrameBuffer1);
gPhysicalFrameBuffers[2] = VIRTUAL_TO_PHYSICAL(gFrameBuffer2);
for (int i = 0; i < 2; i++) {
for (int i = 0; i < MAX_PLAYERS; i++) {
D_80339CF0[i] = main_pool_alloc(0x4000, MEMORY_POOL_LEFT);
set_segment_base_addr(17, (void *)D_80339CF0[i]);
func_80278A78(&D_80339D10[i], gMarioAnims, D_80339CF0[i]);

View file

@ -820,7 +820,7 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O
save_file_collect_star_or_key(m->numCoins, starIndex);
s32 numStars = save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1);
for (int i = 0; i < 2; i++) {
for (int i = 0; i < MAX_PLAYERS; i++) {
gMarioStates[i].numStars = numStars;
}

View file

@ -150,7 +150,7 @@ struct CreditsEntry sCreditsSequence[] = {
{ LEVEL_NONE, 0, 1, 0, { 0, 0, 0 }, NULL },
};
struct MarioState gMarioStates[2];
struct MarioState gMarioStates[MAX_PLAYERS];
struct HudDisplay gHudDisplay;
s16 sCurrPlayMode;
u16 D_80339ECA;
@ -371,7 +371,7 @@ void init_mario_after_warp(void) {
u32 marioSpawnType = get_mario_spawn_type(spawnNode->object);
if (gMarioState->action != ACT_UNINITIALIZED) {
for (int i = 0; i < 2; i++) {
for (int i = 0; i < MAX_PLAYERS; i++) {
gPlayerSpawnInfos[i].startPos[0] = (s16) spawnNode->object->oPosX;
gPlayerSpawnInfos[i].startPos[1] = (s16) spawnNode->object->oPosY;
gPlayerSpawnInfos[i].startPos[2] = (s16) spawnNode->object->oPosZ;
@ -506,7 +506,7 @@ void warp_credits(void) {
load_area(sWarpDest.areaIdx);
for (int i = 0; i < 2; i++) {
for (int i = 0; i < MAX_PLAYERS; i++) {
vec3s_set(gPlayerSpawnInfos[i].startPos, gCurrCreditsEntry->marioPos[0],
gCurrCreditsEntry->marioPos[1], gCurrCreditsEntry->marioPos[2]);

View file

@ -69,7 +69,7 @@ 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
struct MarioBodyState gBodyStates[MAX_PLAYERS]; // 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

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

View file

@ -301,6 +301,14 @@ f32 dist_between_objects(struct Object *obj1, struct Object *obj2) {
return sqrtf(dx * dx + dy * dy + dz * dz);
}
f32 dist_between_object_and_point(struct Object *obj, f32 pointX, f32 pointY, f32 pointZ) {
f32 dx = (f32)obj->oPosX - pointX;
f32 dy = (f32)obj->oPosY - pointY;
f32 dz = (f32)obj->oPosZ - pointZ;
return sqrtf(dx * dx + dy * dy + dz * dz);
}
void cur_obj_forward_vel_approach_upward(f32 target, f32 increment) {
if (o->oForwardVel >= target) {
o->oForwardVel = target;
@ -393,6 +401,17 @@ s16 obj_angle_to_object(struct Object *obj1, struct Object *obj2) {
return angle;
}
s16 obj_angle_to_point(struct Object *obj, f32 pointX, f32 pointY, f32 pointZ) {
f32 z1, x1, z2, x2;
s16 angle;
z1 = obj->oPosZ; z2 = pointZ; //ordering of instructions..
x1 = obj->oPosX; x2 = pointX;
angle = atan2s(z2 - z1, x2 - x1);
return angle;
}
s16 obj_turn_toward_object(struct Object *obj, struct Object *target, s16 angleIndex, s16 turnAmount) {
f32 a, b, c, d;
UNUSED s32 unused;

View file

@ -82,12 +82,14 @@ void create_transformation_from_matrices(Mat4 a0, Mat4 a1, Mat4 a2);
void obj_set_held_state(struct Object *obj, const BehaviorScript *heldBehavior);
f32 lateral_dist_between_objects(struct Object *obj1, struct Object *obj2);
f32 dist_between_objects(struct Object *obj1, struct Object *obj2);
f32 dist_between_object_and_point(struct Object *obj, f32 pointX, f32 pointY, f32 pointZ);
void cur_obj_forward_vel_approach_upward(f32 target, f32 increment);
s32 approach_f32_signed(f32 *value, f32 target, f32 increment);
f32 approach_f32_symmetric(f32 value, f32 target, f32 increment);
s16 approach_s16_symmetric(s16 value, s16 target, s16 increment);
s32 cur_obj_rotate_yaw_toward(s16 target, s16 increment);
s16 obj_angle_to_object(struct Object *obj1, struct Object *obj2);
s16 obj_angle_to_point(struct Object *obj, f32 pointX, f32 pointY, f32 pointZ);
s16 obj_turn_toward_object(struct Object *obj, struct Object *target, s16 angleIndex, s16 turnAmount);
void obj_set_parent_relative_pos(struct Object *obj, s16 relX, s16 relY, s16 relZ);
void obj_set_pos(struct Object *obj, s16 x, s16 y, s16 z);

View file

@ -20,49 +20,53 @@ struct Object *gMarioPlatform = NULL;
* within 4 units of the floor. Set his referenced platform object accordingly.
*/
void update_mario_platform(void) {
struct Surface *floor;
UNUSED u32 unused;
f32 marioX;
f32 marioY;
f32 marioZ;
f32 floorHeight;
u32 awayFromFloor;
for (int i = 0; i < MAX_PLAYERS; i++) {
struct Surface *floor;
UNUSED u32 unused;
f32 marioX;
f32 marioY;
f32 marioZ;
f32 floorHeight;
u32 awayFromFloor;
if (gMarioObject == NULL) {
return;
}
struct Object* player = gMarioStates[i].marioObj;
//! If Mario moves onto a rotating platform in a PU, the find_floor call
// will detect the platform and he will end up receiving a large amount
// of displacement since he is considered to be far from the platform's
// axis of rotation.
if (player == NULL) {
return;
}
marioX = gMarioObject->oPosX;
marioY = gMarioObject->oPosY;
marioZ = gMarioObject->oPosZ;
floorHeight = find_floor(marioX, marioY, marioZ, &floor);
//! If Mario moves onto a rotating platform in a PU, the find_floor call
// will detect the platform and he will end up receiving a large amount
// of displacement since he is considered to be far from the platform's
// axis of rotation.
if (absf(marioY - floorHeight) < 4.0f) {
awayFromFloor = 0;
} else {
awayFromFloor = 1;
}
marioX = player->oPosX;
marioY = player->oPosY;
marioZ = player->oPosZ;
floorHeight = find_floor(marioX, marioY, marioZ, &floor);
switch (awayFromFloor) {
case 1:
gMarioPlatform = NULL;
gMarioObject->platform = NULL;
break;
if (absf(marioY - floorHeight) < 4.0f) {
awayFromFloor = 0;
} else {
awayFromFloor = 1;
}
case 0:
if (floor != NULL && floor->object != NULL) {
gMarioPlatform = floor->object;
gMarioObject->platform = floor->object;
} else {
switch (awayFromFloor) {
case 1:
gMarioPlatform = NULL;
gMarioObject->platform = NULL;
}
break;
player->platform = NULL;
break;
case 0:
if (floor != NULL && floor->object != NULL) {
gMarioPlatform = floor->object;
player->platform = floor->object;
} else {
gMarioPlatform = NULL;
player->platform = NULL;
}
break;
}
}
}
@ -88,7 +92,7 @@ void set_mario_pos(f32 x, f32 y, f32 z) {
* Apply one frame of platform rotation to Mario or an object using the given
* platform. If isMario is 0, use gCurrentObject.
*/
void apply_platform_displacement(u32 isMario, struct Object *platform) {
void apply_platform_displacement(u32 playerIndex, struct Object *platform) {
f32 x;
f32 y;
f32 z;
@ -108,9 +112,11 @@ void apply_platform_displacement(u32 isMario, struct Object *platform) {
rotation[1] = platform->oAngleVelYaw;
rotation[2] = platform->oAngleVelRoll;
if (isMario) {
if (playerIndex != (u32)-1) {
D_8032FEC0 = 0;
get_mario_pos(&x, &y, &z);
x = gMarioStates[playerIndex].pos[0];
y = gMarioStates[playerIndex].pos[1];
z = gMarioStates[playerIndex].pos[2];
} else {
x = gCurrentObject->oPosX;
y = gCurrentObject->oPosY;
@ -125,8 +131,8 @@ void apply_platform_displacement(u32 isMario, struct Object *platform) {
unused2 = rotation[2];
unused3 = platform->oFaceAngleYaw;
if (isMario) {
gMarioStates[0].faceAngle[1] += rotation[1];
if (playerIndex != (u32)-1) {
gMarioStates[playerIndex].faceAngle[1] += rotation[1];
}
platformPosX = platform->oPosX;
@ -156,8 +162,10 @@ void apply_platform_displacement(u32 isMario, struct Object *platform) {
z = platformPosZ + newObjectOffset[2];
}
if (isMario) {
set_mario_pos(x, y, z);
if (playerIndex != (u32)-1) {
gMarioStates[playerIndex].pos[0] = x;
gMarioStates[playerIndex].pos[1] = y;
gMarioStates[playerIndex].pos[2] = z;
} else {
gCurrentObject->oPosX = x;
gCurrentObject->oPosY = y;
@ -169,11 +177,14 @@ void apply_platform_displacement(u32 isMario, struct Object *platform) {
* If Mario's platform is not null, apply platform displacement.
*/
void apply_mario_platform_displacement(void) {
struct Object *platform;
for (int i = 0; i < MAX_PLAYERS; i++) {
struct Object* player = gMarioStates[i].marioObj;
if (player == NULL) { continue; }
platform = gMarioPlatform;
if (!(gTimeStopState & TIME_STOP_ACTIVE) && gMarioObject != NULL && platform != NULL) {
apply_platform_displacement(1, platform);
struct Object *platform = player->platform;
if (!(gTimeStopState & TIME_STOP_ACTIVE) && player != NULL && platform != NULL) {
apply_platform_displacement(i, platform);
}
}
}

View file

@ -8,7 +8,7 @@
void update_mario_platform(void);
void get_mario_pos(f32 *x, f32 *y, f32 *z);
void set_mario_pos(f32 x, f32 y, f32 z);
void apply_platform_displacement(u32 isMario, struct Object *platform);
void apply_platform_displacement(u32 playerIndex, struct Object *platform);
void apply_mario_platform_displacement(void);
#ifndef VERSION_JP
void clear_mario_platform(void);

View file

@ -30,7 +30,7 @@ void network_receive_collect_star(struct Packet* p) {
save_file_collect_star_or_key(coinScore, starIndex);
s32 numStars = save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1);
for (int i = 0; i < 2; i++) {
for (int i = 0; i < MAX_PLAYERS; i++) {
gMarioStates[i].numStars = numStars;
}