Files
mk64/src/staff_ghosts.c
T
MegaMech 19410f2825 Code Segments Shiftable (#566)
his PR cleans up segment related code in main.c.
Also cleans up the linker a bit.

    Add memory pool to linker as .bss to validate that it exists properly.

    Move framebuffers, gfx, and audio buffers out of racing segment and make its own segment.

    Rename framebuffers.c to buffers.c as it contains more than just framebuffers.

    Import asserts from sm64 to validate that code segments are not overlapping

    Rename segNoload to segmentNoload

    Rename 802BA370 segment to trigTables

    Rename gMenuSelectionFromEndingSequence to gGotoMenu

    Rename gMenuSelectionFromQuit to gGotoMode

    Rename SEG_ENDING_SEQUENCES to SEG_ENDING

    Rename data_821D10 to ceremonyData

    Rename data_825800 to startupLogo
2024-02-05 17:08:29 -07:00

569 lines
15 KiB
C

#include <ultra64.h>
#include <macros.h>
#include <types.h>
#include <common_structs.h>
#include <defines.h>
#include <decode.h>
#include "main.h"
#include "code_800029B0.h"
#include "buffers.h"
#include "save.h"
#include "staff_ghosts.h"
#include "code_8006E9C0.h"
#include "code_80091750.h"
#include "code_80057C60.h"
extern s32 mio0encode(s32 input, s32, s32);
extern s32 func_80040174(void *, s32, s32);
u8 *D_80162D80;
s16 D_80162D84;
s16 D_80162D86;
u16 D_80162D88;
u32 D_80162D8C;
s16 D_80162D90;
u32 *D_80162D94;
u16 D_80162D98;
u32 D_80162D9C;
s16 D_80162DA0;
u32 *D_80162DA4;
u16 D_80162DA8;
s32 D_80162DAC;
s16 D_80162DB0;
u32 *D_80162DB4;
s16 D_80162DB8;
u32 *D_80162DBC;
u16 D_80162DC0;
u32 D_80162DC4;
s32 D_80162DC8;
s32 D_80162DCC;
s32 D_80162DD0;
u16 D_80162DD4;
u16 D_80162DD6;
u16 D_80162DD8;
s32 D_80162DDC;
s32 D_80162DE0; // ghost kart id?
s32 D_80162DE4;
s32 D_80162DE8;
s32 D_80162DEC;
s32 D_80162DF0;
s32 D_80162DF4;
s32 D_80162DF8;
s32 D_80162DFC;
s32 D_80162E00;
u32 *D_800DC710 = (u32 *) &D_802BFB80[0][2][3];
u32 *D_800DC714 = (u32 *) &D_802BFB80[1][1][3];
extern u8 _kart_texturesSegmentRomStart;
extern s32 gLapCountByPlayerId[];
extern StaffGhost *d_mario_raceway_staff_ghost;
extern StaffGhost *d_royal_raceway_staff_ghost;
extern StaffGhost *d_luigi_raceway_staff_ghost;
void func_80004EF0(void) {
D_80162DA4 = (u32 *) &D_802BFB80[0][2][3];
osInvalDCache(&D_80162DA4[0], 0x4000);
osPiStartDma(&gDmaIoMesg, 0, 0, (uintptr_t) ((D_80162DC4 & 0xFFFFFF) + &_kart_texturesSegmentRomStart), D_80162DA4, 0x4000, &gDmaMesgQueue);
osRecvMesg(&gDmaMesgQueue, &gMainReceivedMesg, OS_MESG_BLOCK);
D_80162D9C = (*D_80162DA4 & 0xFF0000);
D_80162DA0 = 0;
}
void func_80004FB0(void) {
D_80162DB4 = (u32 *) &D_802BFB80[0][D_80162DD0][3];
D_80162DAC = *D_80162DB4 & 0xFF0000;
D_80162DB0 = 0;
}
void func_80004FF8(void) {
D_80162D94 = (u32 *) &D_802BFB80[0][D_80162DC8][3];
D_80162D8C = (s32) *D_80162D94 & 0xFF0000;
D_80162D90 = 0;
}
/**
* Activates staff ghost if time trial lap time is lower enough
*
*/
#ifdef VERSION_EU
#define BLAH 10700
#define BLAH2 19300
#define BLAH3 13300
#else
#define BLAH 9000
#define BLAH2 16000
#define BLAH3 11200
#endif
void set_staff_ghost(void) {
u32 temp_v0; // Appears to be player total lap time.
switch(gCurrentCourseId) {
case COURSE_MARIO_RACEWAY:
temp_v0 = func_800B4E24(0) & 0xfffff;
if (temp_v0 <= BLAH) {
D_80162DD6 = 0;
D_80162DF4 = 0;
} else {
D_80162DD6 = 1;
D_80162DF4 = 1;
}
D_80162DC4 = (u32) &d_mario_raceway_staff_ghost;
D_80162DE4 = 0;
break;
case COURSE_ROYAL_RACEWAY:
temp_v0 = func_800B4E24(0) & 0xfffff;
if (temp_v0 <= BLAH2) {
D_80162DD6 = 0;
D_80162DF4 = 0;
} else {
D_80162DD6 = 1;
D_80162DF4 = 1;
}
D_80162DC4 = (u32) &d_royal_raceway_staff_ghost;
D_80162DE4 = 6;
break;
case COURSE_LUIGI_RACEWAY:
temp_v0 = func_800B4E24(0) & 0xfffff;
if (temp_v0 <= BLAH3) {
D_80162DD6 = 0;
D_80162DF4 = 0;
} else {
D_80162DD6 = 1;
D_80162DF4 = 1;
}
D_80162DC4 = (u32) &d_luigi_raceway_staff_ghost;
D_80162DE4 = 1;
break;
default:
D_80162DD6 = 1;
D_80162DF4 = 1;
}
}
s32 func_800051C4(void) {
s32 phi_v0;
if (D_80162D84 != 0) {
// func_80040174 in mio0_decode.s
func_80040174((void *) D_80162D80, (D_80162D84 * 4) + 0x20, (s32) D_800DC710);
phi_v0 = mio0encode((s32) D_800DC710, (D_80162D84 * 4) + 0x20, (s32) D_800DC714);
return phi_v0 + 0x1e;
}
}
void func_8000522C(void) {
D_80162D94 = (u32 *) &D_802BFB80[0][D_80162DC8][3];
mio0decode((u8 *) D_800DC714, (u8 *) D_80162D94);
D_80162D8C = (s32) (*D_80162D94 & 0xFF0000);
D_80162D90 = 0;
D_80162E00 = 1;
}
void func_800052A4(void) {
s16 temp_v0;
if (D_80162DC8 == 1) {
D_80162DC8 = 0;
D_80162DCC = 1;
} else {
D_80162DC8 = 1;
D_80162DCC = 0;
}
temp_v0 = D_80162DB8;
D_80162D80 = (void *) &D_802BFB80[0][D_80162DC8][3];
D_80162D84 = temp_v0;
D_80162D86 = temp_v0;
}
void func_80005310(void) {
if (gModeSelection == TIME_TRIALS) {
set_staff_ghost();
if (D_80162DC0 != gCurrentCourseId) {
D_80162DD4 = 1;
}
D_80162DC0 = (u16) gCurrentCourseId;
D_80162DF0 = 0;
D_80162DEC = 0;
D_80162DF8 = 0;
if (gModeSelection == TIME_TRIALS && gActiveScreenMode == SCREEN_MODE_1P) {
if (D_8015F890 == 1) {
func_80004FB0();
if (D_80162DD8 == 0) {
func_80004FF8();
}
if (D_80162DD6 == 0) {
func_80004EF0();
}
} else {
D_80162DD8 = 1U;
D_80162DBC = (u32 *) &D_802BFB80[0][D_80162DCC][3];
D_80162DBC[0] = -1;
D_80162DB8 = 0;
D_80162DDC = 0;
func_80091EE4();
if (D_80162DD4 == 0) {
func_80004FF8();
}
if (D_80162DD6 == 0) {
func_80004EF0();
}
}
}
}
}
void func_8000546C(void) {
u32 temp_a0;
u32 temp_a1;
UNUSED u16 unk;
u16 temp_v1;
s16 phi_v1;
s16 phi_v0 = 0;
if (D_80162DB0 >= 0x1000) {
gPlayerOne->type = PLAYER_CINEMATIC_MODE | PLAYER_START_SEQUENCE | PLAYER_CPU;
return;
}
temp_a0 = D_80162DB4[D_80162DB0];
temp_a1 = temp_a0 & 0xFF;
if (temp_a1 < 0x80U) {
phi_v1 = (s16) (temp_a1 & 0xFF);
} else {
phi_v1 = (s16) (temp_a1 | (~0xFF));
}
temp_a1 = (u32) (temp_a0 & 0xFF00) >> 8;
gControllerEight->rawStickX = phi_v1;
if (temp_a1 < 0x80U) {
phi_v1 = (s16) (temp_a1 & 0xFF);
} else {
phi_v1 = (s16) (temp_a1 | (~0xFF));
}
gControllerEight->rawStickY = phi_v1;
if (temp_a0 & 0x80000000) {
phi_v0 |= A_BUTTON;
}
if (temp_a0 & 0x40000000) {
phi_v0 |= B_BUTTON;
}
if (temp_a0 & 0x20000000) {
phi_v0 |= Z_TRIG;
}
if (temp_a0 & 0x10000000) {
phi_v0 |= R_TRIG;
}
temp_v1 = gControllerEight->buttonPressed & 0x1F0F;
gControllerEight->buttonPressed = (phi_v0 & (phi_v0 ^ D_80162DA8)) | temp_v1;
temp_v1 = gControllerEight->buttonDepressed & 0x1F0F;
gControllerEight->buttonDepressed = (D_80162DA8 & (phi_v0 ^ D_80162DA8)) | temp_v1;
D_80162DA8 = phi_v0;
gControllerEight->button = phi_v0;
if (D_80162DAC == 0) {
D_80162DB0++;
D_80162DAC = (s32) (D_80162DB4[D_80162DB0] & 0xFF0000);
} else {
D_80162DAC += 0xFFFF0000;
}
}
void func_8000561C(void) {
u32 temp_a0;
u32 temp_v0;
UNUSED u16 unk;
u16 temp_v1;
s16 phi_v1;
s16 phi_a2 = 0;
if (D_80162DA0 >= 0x1000) {
func_80005AE8(gPlayerThree);
return;
}
temp_a0 = D_80162DA4[D_80162DA0];
temp_v0 = temp_a0 & 0xFF;
if (temp_v0 < 0x80U) {
phi_v1 = (s16) (temp_v0 & 0xFF);
} else {
phi_v1 = (s16) (temp_v0 | (~0xFF));
}
temp_v0 = (u32) (temp_a0 & 0xFF00) >> 8;
gControllerSeven->rawStickX = phi_v1;
if (temp_v0 < 0x80U) {
phi_v1 = (s16) (temp_v0 & 0xFF);
} else {
phi_v1 = (s16) (temp_v0 | (~0xFF));
}
gControllerSeven->rawStickY = phi_v1;
if (temp_a0 & 0x80000000) {
phi_a2 = A_BUTTON;
}
if (temp_a0 & 0x40000000) {
phi_a2 |= B_BUTTON;
}
if (temp_a0 & 0x20000000) {
phi_a2 |= Z_TRIG;
}
if (temp_a0 & 0x10000000) {
phi_a2 |= R_TRIG;
}
temp_v1 = gControllerSeven->buttonPressed & 0x1F0F;
gControllerSeven->buttonPressed = (phi_a2 & (phi_a2 ^ D_80162D98)) | temp_v1;
temp_v1 = gControllerSeven->buttonDepressed & 0x1F0F;
gControllerSeven->buttonDepressed = (D_80162D98 & (phi_a2 ^ D_80162D98)) | temp_v1;
D_80162D98 = phi_a2;
gControllerSeven->button = phi_a2;
if (D_80162D9C == 0) {
D_80162DA0++;
D_80162D9C = (s32) (D_80162DA4[D_80162DA0] & 0xFF0000);
} else {
D_80162D9C += (s32) 0xFFFF0000;
}
}
void func_800057DC(void) {
u32 temp_a0;
u32 temp_v0;
UNUSED u16 unk;
u16 temp_v1;
s16 phi_v1;
s16 phi_a2 = 0;
if (D_80162D90 >= 0x1000) {
func_80005AE8(gPlayerTwo);
return;
}
temp_a0 = D_80162D94[D_80162D90];
temp_v0 = temp_a0 & 0xFF;
if (temp_v0 < 0x80U) {
phi_v1 = (s16) (temp_v0 & 0xFF);
} else {
phi_v1 = (s16) (temp_v0 | ~0xFF);
}
temp_v0 = (u32) (temp_a0 & 0xFF00) >> 8;
gControllerSix->rawStickX = phi_v1;
if (temp_v0 < 0x80U) {
phi_v1 = (s16) (temp_v0 & 0xFF);
} else {
phi_v1 = (s16) (temp_v0 | (~0xFF));
}
gControllerSix->rawStickY = phi_v1;
if (temp_a0 & 0x80000000) {
phi_a2 |= A_BUTTON;
}
if (temp_a0 & 0x40000000) {
phi_a2 |= B_BUTTON;
}
if (temp_a0 & 0x20000000) {
phi_a2 |= Z_TRIG;
}
if (temp_a0 & 0x10000000) {
phi_a2 |= R_TRIG;
}
temp_v1 = gControllerSix->buttonPressed & 0x1F0F;
gControllerSix->buttonPressed = (phi_a2 & (phi_a2 ^ D_80162D88)) | temp_v1;
temp_v1 = gControllerSix->buttonDepressed & 0x1F0F;
gControllerSix->buttonDepressed = (D_80162D88 & (phi_a2 ^ D_80162D88)) | temp_v1;
D_80162D88 = phi_a2;
gControllerSix->button = phi_a2;
if (D_80162D8C == 0) {
D_80162D90++;
D_80162D8C = (s32) (D_80162D94[D_80162D90] & 0xFF0000);
} else {
D_80162D8C += (s32) 0xFFFF0000;
}
}
void func_8000599C(void) {
s16 temp_a2;
u32 phi_a3;
u32 temp_v1;
u32 temp_v2;
u32 temp_v0;
u32 temp_t0;
u32 temp_a0_2;
if (((D_80162DB8 >= 0x1000) ||
((gPlayerOne->unk_0CA & 2) != 0)) ||
((gPlayerOne->unk_0CA & 8) != 0)) {
D_80162DF8 = 1;
return;
}
temp_v1 = gControllerOne->rawStickX;
temp_v1 &= 0xFF;
temp_v2 = gControllerOne->rawStickY;
temp_v2 = (temp_v2 & 0xFF) << 8;
temp_a2 = gControllerOne->button;
phi_a3 = 0;
if (temp_a2 & 0x8000) {
phi_a3 |= 0x80000000;
} if (temp_a2 & 0x4000) {
phi_a3 |= 0x40000000;
}
if (temp_a2 & 0x2000) {
phi_a3 |= 0x20000000;
}
if (temp_a2 & 0x0010) {
phi_a3 |= 0x10000000;
}
phi_a3 |= temp_v1;
phi_a3 |= temp_v2;
temp_t0 = D_80162DBC[D_80162DB8];
temp_a0_2 = temp_t0 & 0xFF00FFFF;
if ((*D_80162DBC) == 0xFFFFFFFF) {
D_80162DBC[D_80162DB8] = phi_a3;
} else if (temp_a0_2 == phi_a3) {
temp_v0 = temp_t0 & 0xFF0000;
if (temp_v0 == 0xFF0000) {
D_80162DB8++;
D_80162DBC[D_80162DB8] = phi_a3;
} else {
temp_t0 += 0x10000;
D_80162DBC[D_80162DB8] = temp_t0;
}
} else {
D_80162DB8++; D_80162DBC[D_80162DB8] = phi_a3;
}
}
// sets player to AI? (unconfirmed)
void func_80005AE8(Player *ply) {
if (((ply->type & PLAYER_INVISIBLE_OR_BOMB) != 0) && (ply != gPlayerOne)) {
ply->type = PLAYER_CINEMATIC_MODE | PLAYER_START_SEQUENCE | PLAYER_CPU;
}
}
void func_80005B18(void) {
if (gModeSelection == TIME_TRIALS) {
if ((gLapCountByPlayerId[0] == 3) && (D_80162DDC == 0) && (D_80162DF8 != 1)) {
if (D_80162DD4 == 1) {
D_80162DD0 = D_80162DCC;
func_800052A4();
D_80162DD4 = 0;
D_80162DDC = 1;
D_80162DE0 = gPlayerOne->characterId;
D_80162DE8 = gPlayerOne->characterId;
D_80162E00 = 0;
D_80162DFC = playerHUD[PLAYER_ONE].someTimer;
func_80005AE8(gPlayerTwo);
func_80005AE8(gPlayerThree);
} else if (gLapCountByPlayerId[1] != 3) {
D_80162DD0 = D_80162DCC;
func_800052A4();
D_80162DDC = 1;
D_80162DE0 = gPlayerOne->characterId;
D_80162DFC = playerHUD[PLAYER_ONE].someTimer;
D_80162E00 = 0;
D_80162DE8 = gPlayerOne->characterId;
func_80005AE8(gPlayerTwo);
func_80005AE8(gPlayerThree);
} else {
D_80162D80 = D_802BFB80[0][D_80162DC8][3].pixel_index_array;
D_80162D84 = D_80162D86;
D_80162DD0 = D_80162DCC;
D_80162DE8 = gPlayerOne->characterId;
D_80162DD8 = 0;
D_80162DD4 = 0;
D_80162DDC = 1;
func_80005AE8(gPlayerTwo);
func_80005AE8(gPlayerThree);
}
} else {
if ((gLapCountByPlayerId[0] == 3) && (D_80162DDC == 0) && (D_80162DF8 == 1)) {
D_80162D80 = D_802BFB80[0][D_80162DC8][3].pixel_index_array;
D_80162D84 = D_80162D86;
D_80162DDC = 1;
}
if ((gPlayerOne->type & 0x800) == 0x800) {
func_80005AE8(gPlayerTwo);
func_80005AE8(gPlayerThree);
} else {
D_80162DEC += 1;
if (D_80162DEC >= 0x65) {
D_80162DEC = 0x00000064;
}
if ((gModeSelection == TIME_TRIALS) && (gActiveScreenMode == SCREEN_MODE_1P)) {
if ((D_80162DD4 == 0) && (gLapCountByPlayerId[1] != 3)) {
func_800057DC();
}
if ((D_80162DD6 == 0) && (gLapCountByPlayerId[2] != 3)) {
func_8000561C();
}
if (!(gPlayerOne->type & 0x800)) {
func_8000599C();
}
}
}
}
}
}
void func_80005E6C(void) {
if ((gModeSelection == TIME_TRIALS) && (gModeSelection == TIME_TRIALS) && (gActiveScreenMode == SCREEN_MODE_1P)) {
if ((D_80162DD8 == 0) && (gLapCountByPlayerId[1] != 3)) {
func_800057DC(); //3
}
if ((D_80162DD6 == 0) && (gLapCountByPlayerId[2] != 3)) {
func_8000561C(); //2
}
if ((gPlayerOne->type & PLAYER_CINEMATIC_MODE) != PLAYER_CINEMATIC_MODE) {
func_8000546C(); //1
return;
}
func_80005AE8(gPlayerTwo);
func_80005AE8(gPlayerThree);
}
}
void staff_ghosts_loop(void) {
if (D_8015F890 == 1) {
func_80005E6C();
return;
}
if (!D_80162DF0) {
func_80005B18();
return;
}
D_80162DF8 = 1;
}