mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-12-23 16:32:31 +00:00
Synchronized seesaw, started moving toward a MAX_PLAYERS define
This commit is contained in:
parent
e86efb9e85
commit
5ec9ab9ec0
17 changed files with 126 additions and 65 deletions
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue