port pr 730 from the decomp (#445)

* port pr 730 from the decomp

Co-Authored-By: Jed Grabman <7600154+jedgrabman@users.noreply.github.com>

* rename file

* small fix

* finish fix time trial

---------

Co-authored-by: Jed Grabman <7600154+jedgrabman@users.noreply.github.com>
Co-authored-by: MegaMech <MegaMech@users.noreply.github.com>
This commit is contained in:
coco875
2025-07-10 23:11:36 +00:00
committed by GitHub
parent 371adbd7b9
commit 6a8baf8936
44 changed files with 744 additions and 690 deletions
+29 -8
View File
@@ -48,6 +48,27 @@
#define HOLD_ALL_DPAD_AND_C_BUTTONS \
(U_JPAD | L_JPAD | R_JPAD | D_JPAD | U_CBUTTONS | L_CBUTTONS | R_CBUTTONS | D_CBUTTONS)
#define ALL_BUTTONS \
(A_BUTTON | B_BUTTON | L_TRIG | R_TRIG | Z_TRIG | START_BUTTON | U_JPAD | L_JPAD | R_JPAD | D_JPAD | U_CBUTTONS | \
L_CBUTTONS | R_CBUTTONS | D_CBUTTONS)
/**
* Replay controller buttons
* Used for time trial replays (including staff and player ghosts)
* Each entry is converted to a u32 value
* This allows access to the button struct member
*/
#define REPLAY_A_BUTTON (1 << 31) // 0x80000000
#define REPLAY_B_BUTTON (1 << 30) // 0x40000000
#define REPLAY_Z_TRIG (1 << 29) // 0x20000000
#define REPLAY_R_TRIG (1 << 28) // 0x10000000
#define REPLAY_FRAME_COUNTER 0xFF0000
#define REPLAY_CLEAR_FRAME_COUNTER (0xFFFFFFFF & ~REPLAY_FRAME_COUNTER)
#define REPLAY_STICK_Y 0xFF00
#define REPLAY_STICK_X 0xFF
#define REPLAY_FRAME_INCREMENT 0x10000
/**
* @brief Jump to demo mode from the debug menu using L and A
*/
@@ -382,15 +403,15 @@ enum PLACE { FIRST_PLACE, SECOND_PLACE, THIRD_PLACE, FOURTH_PLACE };
/**
* @brief durations of effects
*/
#define STAR_EFFECT_DURATION 0xA
#define BOO_EFFECT_DURATION 0x7
#define STAR_EFFECT_DURATION 0xA
#define BOO_EFFECT_DURATION 0x7
/**
* @brief alpha related values
*/
#define ALPHA_MAX 0xFF
#define ALPHA_MIN 0x0
#define ALPHA_BOO_EFFECT 0x60
/**
* @brief alpha related values
*/
#define ALPHA_MAX 0xFF
#define ALPHA_MIN 0x0
#define ALPHA_BOO_EFFECT 0x60
#define ALPHA_CHANGE_LARGE 8
#define ALPHA_CHANGE_MEDIUM 4
+1 -1
View File
@@ -58,7 +58,7 @@ void update_actor_kiwano_fruit(struct KiwanoFruit* fruit) {
player->velocity[2] -= temp_f14 * 0.7f;
func_800C9060(player - gPlayerOne, SOUND_ARG_LOAD(0x19, 0x00, 0x70, 0x18));
if (gModeSelection != GRAND_PRIX) {
D_80162DF8 = 1;
gPostTimeTrialReplayCannotSave = 1;
}
}
}
+1 -1
View File
@@ -22,7 +22,7 @@ typedef struct {
} struct_D_802BFB80_4; // size = 0x1000
/*
* In render_player, spawn_players, and staff_ghosts D_802BFB80 is the arraySize8 entry
* In render_player, spawn_players, and replays D_802BFB80 is the arraySize8 entry
* But in menu_items its the arraySize4 entry
* The only way to unify those 2 things is to use a union
*/
+1 -1
View File
@@ -17,7 +17,7 @@
#include "skybox_and_splitscreen.h"
#include "code_8006E9C0.h"
#include "spawn_players.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "render_courses.h"
#include "main.h"
#include "courses/all_course_data.h"
+1 -1
View File
@@ -46,7 +46,7 @@
#include <render_courses.h>
#include <skybox_and_splitscreen.h>
#include <spawn_players.h>
#include <staff_ghosts.h>
#include <replays.h>
#include <textures.h>
#include <actor_types.h>
+1 -1
View File
@@ -30,7 +30,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+1 -1
View File
@@ -24,7 +24,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+1 -1
View File
@@ -24,7 +24,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+1 -1
View File
@@ -26,7 +26,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "code_8003DC40.h"
+1 -1
View File
@@ -25,7 +25,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "code_8003DC40.h"
+2 -2
View File
@@ -18,7 +18,7 @@ extern "C" {
#include "assets/common_data.h"
#include "render_objects.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "code_800029B0.h"
#include "render_courses.h"
#include "collision.h"
@@ -341,7 +341,7 @@ void Course::WhatDoesThisDoAI(Player* player, int8_t playerId) {
}
void Course::SetStaffGhost() {
D_80162DD6 = 1;
bCourseGhostDisabled = 1;
D_80162DF4 = 1;
}
+1 -1
View File
@@ -29,7 +29,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "code_8003DC40.h"
+1 -1
View File
@@ -24,7 +24,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+1 -1
View File
@@ -28,7 +28,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+1 -1
View File
@@ -46,7 +46,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+1 -1
View File
@@ -28,7 +28,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+1 -1
View File
@@ -27,7 +27,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "code_8003DC40.h"
+3 -3
View File
@@ -27,7 +27,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "code_8003DC40.h"
@@ -246,10 +246,10 @@ void LuigiRaceway::WhatDoesThisDoAI(Player* player, int8_t playerId) {
void LuigiRaceway::SetStaffGhost() {
u32 temp_v0 = func_800B4E24(0) & 0xfffff;
if (temp_v0 <= 11200) {
D_80162DD6 = 0;
bCourseGhostDisabled = 0;
D_80162DF4 = 0;
} else {
D_80162DD6 = 1;
bCourseGhostDisabled = 1;
D_80162DF4 = 1;
}
D_80162DC4 = d_luigi_raceway_staff_ghost;
+3 -3
View File
@@ -26,7 +26,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "mario_raceway_data.h"
#include "collision.h"
@@ -266,10 +266,10 @@ void MarioRaceway::WhatDoesThisDoAI(Player* player, int8_t playerId) {
void MarioRaceway::SetStaffGhost() {
u32 temp_v0 = func_800B4E24(0) & 0xfffff;
if (temp_v0 <= 9000) {
D_80162DD6 = 0;
bCourseGhostDisabled = 0;
D_80162DF4 = 0;
} else {
D_80162DD6 = 1;
bCourseGhostDisabled = 1;
D_80162DF4 = 1;
}
D_80162DC4 = d_mario_raceway_staff_ghost;
+1 -1
View File
@@ -27,7 +27,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+1 -1
View File
@@ -30,7 +30,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+1 -1
View File
@@ -26,7 +26,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+3 -3
View File
@@ -26,7 +26,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
@@ -247,10 +247,10 @@ void RoyalRaceway::WhatDoesThisDoAI(Player* player, int8_t playerId) {
void RoyalRaceway::SetStaffGhost() {
u32 temp_v0 = func_800B4E24(0) & 0xfffff;
if (temp_v0 <= 16000) {
D_80162DD6 = 0;
bCourseGhostDisabled = 0;
D_80162DF4 = 0;
} else {
D_80162DD6 = 1;
bCourseGhostDisabled = 1;
D_80162DF4 = 1;
}
D_80162DC4 = d_royal_raceway_staff_ghost;
+1 -1
View File
@@ -26,7 +26,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+1 -1
View File
@@ -24,7 +24,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+1 -1
View File
@@ -46,7 +46,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+1 -1
View File
@@ -31,7 +31,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+1 -1
View File
@@ -26,7 +26,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "code_8003DC40.h"
+1 -1
View File
@@ -29,7 +29,7 @@ extern "C" {
#include "render_objects.h"
#include "assets/common_data.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "actors.h"
#include "collision.h"
#include "memory.h"
+2 -2
View File
@@ -35,7 +35,7 @@
#include "render_player.h"
#include "render_courses.h"
#include "actors.h"
#include "staff_ghosts.h"
#include "replays.h"
#include <debug.h>
#include "crash_screen.h"
#include "buffers/gfx_output_buffer.h"
@@ -826,7 +826,7 @@ void race_logic_loop(void) {
func_802A4EF4();
if (gModeSelection == TIME_TRIALS) {
staff_ghosts_loop();
replays_loop();
}
// Wait for all racers to load
+57 -57
View File
@@ -22,7 +22,7 @@
#include "memory.h"
#include "audio/external.h"
#include "render_objects.h"
#include "staff_ghosts.h"
#include "replays.h"
#include <assets/common_data.h>
#include "textures.h"
#include "math_util.h"
@@ -805,10 +805,7 @@ MenuTexture* D_800E7DC4[] = {
// trophy textures
MkAnimation* D_800E7E14[] = {
D_020020BC,
D_020020CC,
D_020020DC,
D_020020DC, D_020020EC, D_020020FC, D_0200210C, D_0200210C,
D_020020BC, D_020020CC, D_020020DC, D_020020DC, D_020020EC, D_020020FC, D_0200210C, D_0200210C,
};
MkAnimation* D_800E7E34[] = {
@@ -2306,8 +2303,8 @@ void print_text2_wide(s32 column, s32 row, char* text, s32 tracking, f32 scaleX,
glyphTexture = (MenuTexture*) segmented_to_virtual_dupe((const void*) gGlyphTextureLUT[glyphIndex]);
load_menu_img(glyphTexture);
gDisplayListHead =
print_letter_wide_right(gDisplayListHead, glyphTexture, column - (gGlyphDisplayWidth[glyphIndex] / 2), row,
arg6, scaleX, scaleY);
print_letter_wide_right(gDisplayListHead, glyphTexture,
column - (gGlyphDisplayWidth[glyphIndex] / 2), row, arg6, scaleX, scaleY);
if ((glyphIndex >= 0xD5) && (glyphIndex < 0xE0)) {
characterWidth = 0x20;
} else {
@@ -3029,8 +3026,9 @@ Gfx* func_80095BD0(Gfx* displayListHead, u8* arg1, f32 arg2, f32 arg3, u32 arg4,
displayListHead = AddTextMatrix(displayListHead, mf);
// gSPMatrix(displayListHead++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPLoadTextureTile_4b(displayListHead++, arg1, G_IM_FMT_I, arg4, 0, 0, 0, arg4, arg5+2, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gDPLoadTextureTile_4b(displayListHead++, arg1, G_IM_FMT_I, arg4, 0, 0, 0, arg4, arg5 + 2, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD);
switch (arg4) {
default:
var_a1 = D_02007CD8;
@@ -3071,8 +3069,9 @@ Gfx* func_80095BD0_wide_right(Gfx* displayListHead, u8* arg1, f32 arg2, f32 arg3
displayListHead = AddTextMatrix(displayListHead, mf);
// gSPMatrix(displayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]),
// G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPLoadTextureTile_4b(displayListHead++, arg1, G_IM_FMT_I, arg4, 0, 0, 0, arg4-1, arg5-1, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gDPLoadTextureTile_4b(displayListHead++, arg1, G_IM_FMT_I, arg4, 0, 0, 0, arg4 - 1, arg5 - 1, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD);
switch (arg4) {
default:
var_a1 = D_02007CD8;
@@ -3109,8 +3108,8 @@ Gfx* func_800963F0(Gfx* displayListHead, s8 textureFormat, s32 texScaleS, s32 te
s32 srcX, s32 srcY, s32 srcHeight, s32 srcWidth, s32 screenX, s32 screenY, u8* textureData,
u32 texWidth, u32 texHeight) {
gDPLoadTextureTile(displayListHead++, textureData, textureFormat, G_IM_SIZ_16b, texWidth, texHeight, srcX, srcY,
srcX + texWidth-1, srcY + texHeight-1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0,
G_TX_NOLOD, G_TX_NOLOD);
srcX + texWidth - 1, srcY + texHeight - 1, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, 0, 0, G_TX_NOLOD, G_TX_NOLOD);
f32 percentScaleX = 1.0f / ((f32) texScaleS / 1024.0f);
f32 percentScaleY = 1.0f / ((f32) texScaleT / 1024.0f);
gSPWideTextureRectangle(displayListHead++, screenX << 2, screenY << 2,
@@ -3305,8 +3304,8 @@ Gfx* func_80097A14(Gfx* displayListHead, s8 arg1, s32 arg2, s32 arg3, s32 arg4,
}
Gfx* func_80097AE4(Gfx* displayListHead, s8 textureFormat, s32 destX, s32 destY, u8* textureData, s32 sourceWidth) {
gDPLoadTextureTile(displayListHead++, textureData, textureFormat, G_IM_SIZ_16b, 64, 64, 0, 0, sourceWidth - 1, 32-1, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD);
gDPLoadTextureTile(displayListHead++, textureData, textureFormat, G_IM_SIZ_16b, 64, 64, 0, 0, sourceWidth - 1,
32 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD);
gSPWideTextureRectangle(displayListHead++, destX << 2, destY << 2, (destX + sourceWidth) << 2, (destY + 64) << 2, 0,
0, 0, 1024, 1024);
return displayListHead;
@@ -3320,8 +3319,8 @@ Gfx* func_80097E58(Gfx* displayListHead, s8 textureFormat, u32 uls, u32 ult, u32
}
f32 percent = (f32) (32 - width) / 32.0f;
gDPLoadTextureTile(displayListHead++, textureData, textureFormat, G_IM_SIZ_16b, textureWidth, textureHeight, uls,
ult, textureWidth - 1, textureHeight - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD,
G_TX_NOLOD);
ult, textureWidth - 1, textureHeight - 1, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD);
screenX += (s32) ((f32) (textureWidth / 2) * (1.0f - percent));
gSPWideTextureRectangle(displayListHead++, (screenX) << 2, screenY << 2,
(screenX + (s32) ((f32) textureWidth * percent)) << 2, (screenY + textureHeight) << 2, 0, 0,
@@ -3339,10 +3338,10 @@ Gfx* func_80098558(Gfx* displayListHead, u32 arg1, u32 arg2, u32 arg3, u32 arg4,
for (var_v0 = arg2; var_v0 < arg4; var_v0 += 0x20) {
for (var_a3 = arg1; var_a3 < arg3; var_a3 += 0x20) {
gDPLoadTextureTile(displayListHead++, sMenuTextureList, G_IM_FMT_RGBA, G_IM_SIZ_16b, arg8, 0, var_a3,
var_v0, var_a3 + 32-1, var_v0 + 32-1, 0, G_TX_NOMIRROR | G_TX_WRAP,
var_v0, var_a3 + 32 - 1, var_v0 + 32 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle(displayListHead++, arg5 << 2, arg6 << 2, (arg5 + 32) << 2, (arg6 + 32) << 2, 0, 0,
0, 1024, 1024);
gSPTextureRectangle(displayListHead++, arg5 << 2, arg6 << 2, (arg5 + 32) << 2, (arg6 + 32) << 2, 0, 0, 0,
1024, 1024);
arg5 += 0x20;
}
arg5 = arg5Copy;
@@ -4025,7 +4024,7 @@ void func_80099EC4(void) {
#ifdef TARGET_N64
osInvalDCache((void*) gMenuCompressedBuffer, var_s0);
osPiStartDma(&sp68, 0, 0, (u32) _textures_0aSegmentRomStart + SEGMENT_OFFSET(temp_s2->textureData),
gMenuCompressedBuffer, var_s0, &gDmaMesgQueue);
gMenuCompressedBuffer, var_s0, &gDmaMesgQueue);
#endif
if ((size && size) && size) {}
osRecvMesg(&gDmaMesgQueue, &sp64, 1);
@@ -4672,13 +4671,13 @@ Gfx* print_letter(Gfx* arg0, MenuTexture* glyphTexture, f32 arg2, f32 arg3, s32
switch (mode) {
case 1:
gSPDisplayList(arg0++, D_020077F8);
arg0 = func_80095BD0(arg0, var_s0->textureData, var_s0->dX + arg2, var_s0->dY + arg3, var_s0->width,
var_s0->height, scaleX, scaleY);
arg0 = func_80095BD0(arg0, var_s0->textureData, var_s0->dX + arg2, var_s0->dY + arg3,
var_s0->width, var_s0->height, scaleX, scaleY);
break;
case 2:
gSPDisplayList(arg0++, D_02007818);
arg0 = func_80095BD0(arg0, var_s0->textureData, var_s0->dX + arg2, var_s0->dY + arg3, var_s0->width,
var_s0->height, scaleX, scaleY);
arg0 = func_80095BD0(arg0, var_s0->textureData, var_s0->dX + arg2, var_s0->dY + arg3,
var_s0->width, var_s0->height, scaleX, scaleY);
break;
}
}
@@ -4868,10 +4867,8 @@ Gfx* func_8009C708(Gfx* arg0, struct_8018DEE0_entry* arg1, s32 arg2, s32 arg3, s
break;
}
if (arg5 >= 0) {
arg0 =
func_80097E58(arg0, var_t0, 0, 0U, var_s1->width, var_s1->height, var_s1->dX + arg2, var_s1->dY + arg3,
var_s1->textureData,
var_s1->width, var_s1->height, (u32) arg5);
arg0 = func_80097E58(arg0, var_t0, 0, 0U, var_s1->width, var_s1->height, var_s1->dX + arg2,
var_s1->dY + arg3, var_s1->textureData, var_s1->width, var_s1->height, (u32) arg5);
}
var_s1++;
}
@@ -6032,9 +6029,8 @@ void add_menu_item(s32 type, s32 column, s32 row, s8 priority) {
case MENU_ITEM_TYPE_05A:
case MENU_ITEM_TYPE_05B:
case COURSE_SELECT_BATTLE_NAMES:
load_menu_img_comp_type(
gMenuTexturesTrackSelection[type - COURSE_SELECT_MAP_SELECT],
LOAD_MENU_IMG_TKMK00_ONCE);
load_menu_img_comp_type(gMenuTexturesTrackSelection[type - COURSE_SELECT_MAP_SELECT],
LOAD_MENU_IMG_TKMK00_ONCE);
break;
case MENU_ITEM_TYPE_05F:
case MENU_ITEM_TYPE_060:
@@ -6077,7 +6073,8 @@ void add_menu_item(s32 type, s32 column, s32 row, s8 priority) {
case MENU_ITEM_TYPE_079:
case MENU_ITEM_TYPE_07A:
case MENU_ITEM_TYPE_07B:
load_menu_img_comp_type(segmented_to_virtual_dupe(D_800E82F4[type - MENU_ITEM_TYPE_078]), LOAD_MENU_IMG_TKMK00_ONCE);
load_menu_img_comp_type(segmented_to_virtual_dupe(D_800E82F4[type - MENU_ITEM_TYPE_078]),
LOAD_MENU_IMG_TKMK00_ONCE);
break;
case MENU_ITEM_TYPE_08C:
load_menu_img_comp_type(segmented_to_virtual_dupe(seg2_data_texture), LOAD_MENU_IMG_TKMK00_ONCE);
@@ -6150,9 +6147,9 @@ void add_menu_item(s32 type, s32 column, s32 row, s8 priority) {
case MENU_ITEM_TYPE_0BB:
var_ra->param1 = func_800B5020(playerHUD[0].someTimer, gCharacterSelections[0]);
var_ra->param2 = func_800B5218();
if (D_80162DD4 != 1) {
if (bPlayerGhostDisabled != 1) {
if (func_800051C4() >= 0x3C01) {
D_80162DD4 = 1;
bPlayerGhostDisabled = 1;
}
}
if ((var_ra->param1 == 0) || (var_ra->param2 != 0)) {
@@ -7080,14 +7077,12 @@ void func_800A143C(MenuItem* arg0, s32 arg1) {
case 2:
case 3:
gDisplayListHead =
render_menu_textures(gDisplayListHead, gMenuTexturesTrackSelection[arg1 + 1],
arg0->column, arg0->row);
render_menu_textures(gDisplayListHead, gMenuTexturesTrackSelection[arg1 + 1], arg0->column, arg0->row);
break;
case 1:
case 4:
gDisplayListHead =
func_8009BC9C(gDisplayListHead, gMenuTexturesTrackSelection[arg1 + 1],
arg0->column, arg0->row, 2, arg0->param1);
gDisplayListHead = func_8009BC9C(gDisplayListHead, gMenuTexturesTrackSelection[arg1 + 1], arg0->column,
arg0->row, 2, arg0->param1);
break;
}
}
@@ -7872,12 +7867,12 @@ void func_800A3E60(MenuItem* arg0) {
text_rainbow_effect(arg0->state - 5, var_s1, 1);
switch (var_s1) {
case 4:
if (D_80162DF8 == 1) {
if (gPostTimeTrialReplayCannotSave == 1) {
var_v1 = 1;
}
break;
case 5:
if (D_80162DD4 != 0) {
if (bPlayerGhostDisabled != 0) {
var_v1 = 2;
}
break;
@@ -7918,8 +7913,12 @@ void func_800A3E60(MenuItem* arg0) {
if (D_8018EE10[var_s1].ghostDataSaved == 0) {
print_text_mode_1(0xBB - arg0->column, 0xAA + (0x1E * var_s1), D_800E7A44, 0, 0.45f, 0.45f);
} else {
print_text_mode_1(0xBB - arg0->column, 0xAA + (0x1E * var_s1), CM_GetProps()->Name, 0, 0.45f,
0.45f);
print_text_mode_1(
0xBB - arg0->column, 0xAA + (0x1E * var_s1),
CM_GetPropsCourseId(
gCupCourseOrder[D_8018EE10[var_s1].courseIndex / 4][D_8018EE10[var_s1].courseIndex % 4])
->Name,
0, 0.45f, 0.45f);
}
}
break;
@@ -8204,16 +8203,14 @@ void render_pause_menu_versus(MenuItem* arg0) {
break;
case SCREEN_MODE_3P_4P_SPLITSCREEN:
// Left side players
if ((temp_v0->player == gPlayerOne) ||
(temp_v0->player == gPlayerThree)) {
if ((temp_v0->player == gPlayerOne) || (temp_v0->player == gPlayerThree)) {
leftEdge = OTRGetDimensionFromLeftEdge(0);
gDisplayListHead =
draw_box_wide_pause_background(gDisplayListHead, leftEdge - temp_t3, temp_t0 - temp_t4,
temp_v1 + temp_t3, temp_t0 + temp_t4, 0, 0, 0, 140);
// Right side players
} else if ((temp_v0->player == gPlayerTwo) ||
(temp_v0->player == gPlayerFour)) {
} else if ((temp_v0->player == gPlayerTwo) || (temp_v0->player == gPlayerFour)) {
rightEdge = OTRGetDimensionFromRightEdge(SCREEN_WIDTH);
gDisplayListHead =
draw_box_wide_pause_background(gDisplayListHead, temp_v1 - temp_t3, temp_t0 - temp_t4,
@@ -8493,8 +8490,12 @@ void render_menu_item_end_course_option(MenuItem* arg0) {
if (D_8018EE10[var_s1].ghostDataSaved == 0) {
print_text_mode_1(0x69 - arg0->column, (0x96 + (0x14 * var_s1)), D_800E7A44, 0, 0.75f, 0.75f);
} else {
print_text_mode_1(0x69 - arg0->column, (0x96 + (0x14 * var_s1)), CM_GetProps()->Name, 0, 0.75f,
0.75f);
print_text_mode_1(
0x69 - arg0->column, (0x96 + (0x14 * var_s1)),
CM_GetPropsCourseId(
gCupCourseOrder[D_8018EE10[var_s1].courseIndex / 4][D_8018EE10[var_s1].courseIndex % 4])
->Name,
0, 0.75f, 0.75f);
}
}
break;
@@ -10446,8 +10447,7 @@ void func_800AA69C(MenuItem* arg0) {
case 2:
if ((gCharacterGridIsSelected[temp_v0] == 0) && (var_a0 != 0)) {
arg0->subState = 3;
func_8009A594(arg0->D_8018DEE0_index, 0,
gCharacterDeselectAnimation[temp_a0]);
func_8009A594(arg0->D_8018DEE0_index, 0, gCharacterDeselectAnimation[temp_a0]);
}
break;
case 3:
@@ -11735,7 +11735,7 @@ void func_800AD2E8(MenuItem* arg0) {
arg0->param2 = 0;
arg0->column = 0;
arg0->state = gTimeTrialsResultCursorSelection;
if ((arg0->state == 9) && (D_80162DF8 == 1)) {
if ((arg0->state == 9) && (gPostTimeTrialReplayCannotSave == 1)) {
arg0->state--;
}
D_800DC5EC->screenStartX = 0x00F0;
@@ -11752,7 +11752,7 @@ void func_800AD2E8(MenuItem* arg0) {
if ((gControllerOne->buttonPressed | gControllerOne->stickPressed) & 0x800) {
if (arg0->state >= 6) {
arg0->state--;
if ((D_80162DF8 == 1) && (arg0->state == 9)) {
if ((gPostTimeTrialReplayCannotSave == 1) && (arg0->state == 9)) {
arg0->state--;
}
play_sound2(SOUND_MENU_CURSOR_MOVE);
@@ -11765,10 +11765,10 @@ void func_800AD2E8(MenuItem* arg0) {
if ((gControllerOne->buttonPressed | gControllerOne->stickPressed) & 0x400) {
if (arg0->state < 0xA) {
arg0->state++;
if ((D_80162DF8 == 1) && (arg0->state == 9)) {
if ((gPostTimeTrialReplayCannotSave == 1) && (arg0->state == 9)) {
arg0->state++;
}
if ((arg0->state == 0x0000000A) && (D_80162DD4 != 0)) {
if ((arg0->state == 0x0000000A) && (bPlayerGhostDisabled != 0)) {
arg0->state -= 2;
} else {
play_sound2(SOUND_MENU_CURSOR_MOVE);
@@ -12494,7 +12494,7 @@ void func_800AEF14(MenuItem* arg0) {
void func_800AEF74(MenuItem* arg0) {
switch (arg0->state) {
case 0:
if (D_80162DF8 == 1) {
if (gPostTimeTrialReplayCannotSave == 1) {
arg0->state = 1;
arg0->param1 = 0;
} else if (playerHUD[PLAYER_ONE].raceCompleteBool == (s8) 1) {
+2 -2
View File
@@ -15,7 +15,7 @@
#include "menu_items.h"
#include "code_800AF9B0.h"
#include "save.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "save_data.h"
#include <sounds.h>
#include "spawn_players.h"
@@ -1864,7 +1864,7 @@ void load_menu_states(s32 menuSelection) {
gDebugGotoScene = DEBUG_GOTO_RACING;
gGhostPlayerInit = 0;
D_8016556E = 0;
D_80162DD4 = 1;
bPlayerGhostDisabled = 1;
D_80162DD8 = 1;
D_80162E00 = 0;
D_80162DC8 = 1;
+2 -2
View File
@@ -1632,7 +1632,7 @@ bool collision_yoshi_egg(Player* player, struct YoshiValleyEgg* egg) {
} else {
apply_hit_sound_effect(player, player - gPlayerOne);
if ((gModeSelection == TIME_TRIALS) && ((player->type & PLAYER_CPU) == 0)) {
D_80162DF8 = 1;
gPostTimeTrialReplayCannotSave = 1;
}
}
} else {
@@ -2174,7 +2174,7 @@ void evaluate_collision_between_player_actor(Player* player, struct Actor* actor
if (query_collision_player_vs_actor_item(player, actor) == COLLISION) {
func_800C98B8(actor->pos, actor->velocity, SOUND_ACTION_EXPLOSION);
if ((gModeSelection == TIME_TRIALS) && !(player->type & PLAYER_CPU)) {
D_80162DF8 = 1;
gPostTimeTrialReplayCannotSave = 1;
}
if (player->effects & STAR_EFFECT) {
actor->velocity[1] = 10.0f;
+1 -1
View File
@@ -130,7 +130,7 @@ extern s16 gCurrentCourseId;
extern u16 isCrossingTriggeredByIndex[];
extern Lights1 D_800DC610[];
extern s32 D_80162DF8;
extern s32 gPostTimeTrialReplayCannotSave;
extern s8 D_800DC628[];
extern s8 D_800DC630[];
+3 -3
View File
@@ -7,7 +7,7 @@
#include <sounds.h>
#include "camera.h"
#include "waypoints.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "main.h"
#include "code_800029B0.h"
#include "code_80057C60.h"
@@ -775,7 +775,7 @@ void func_8028F970(void) {
gIsGamePaused = (controller - gControllerOne) + 1;
controller->buttonPressed = 0;
func_800C9F90(1);
D_80162DF0 = 1;
gPauseTriggered = 1;
if (gModeSelection == TIME_TRIALS) {
if (gPlayerOne->type & (PLAYER_EXISTS | PLAYER_INVISIBLE_OR_BOMB)) {
func_80005AE8(gPlayerOne);
@@ -907,7 +907,7 @@ void func_8028FCBC(void) {
D_800DC5B0 = 0;
D_800DC5B8 = 1;
CM_SpawnStarterLakitu(); // func_80078F64();
if ((gModeSelection == TIME_TRIALS) && (D_80162DD6 == 0)) {
if ((gModeSelection == TIME_TRIALS) && (bCourseGhostDisabled == 0)) {
phi_v0_4 = 0x1;
//! @warning this used to be < gCurrentCourseId
// Hopefully this is equivallent.
+1 -1
View File
@@ -39,6 +39,6 @@ void func_80290B14(void);
extern f32 gLapCompletionPercentByPlayerId[];
extern s32 gGPCurrentRaceRankByPlayerId[]; // D_801643B8 (position for each player)
extern u16 D_80162DD6;
extern u16 bCourseGhostDisabled;
#endif
+575
View File
@@ -0,0 +1,575 @@
#include <libultraship.h>
#include <macros.h>
#include <mk64.h>
#include <stubs.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 "replays.h"
#include "code_8006E9C0.h"
#include "menu_items.h"
#include "code_80057C60.h"
#include "kart_dma.h"
#include "port/Game.h"
#include "courses/staff_ghost_data.h"
u8* sReplayGhostBuffer;
size_t sReplayGhostBufferSize;
s16 D_80162D86;
static u16 sPlayerGhostButtonsPrev;
static u32 sPlayerGhostFramesRemaining;
static s16 sPlayerGhostReplayIdx;
u32* sPlayerGhostReplay;
static u16 sButtonsPrevCourseGhost;
static u32 sCourseGhostFramesRemaining;
static s16 sCourseGhostReplayIdx;
static u32* sCourseGhostReplay;
static u16 sPostTTButtonsPrev;
static s32 sPostTTFramesRemaining;
static s16 sPostTTReplayIdx;
static u32* sPostTTReplay;
static s16 sPlayerInputIdx;
static u32* sPlayerInputs;
uintptr_t staff_ghost_track_ptr;
StaffGhost* D_80162DC4;
s32 D_80162DC8;
s32 D_80162DCC;
s32 D_80162DD0;
u16 bPlayerGhostDisabled;
u16 bCourseGhostDisabled;
u16 D_80162DD8;
s32 D_80162DDC;
s32 D_80162DE0; // ghost kart id?
s32 D_80162DE4;
s32 D_80162DE8;
s32 sUnusedReplayCounter;
s32 gPauseTriggered;
s32 D_80162DF4;
s32 gPostTimeTrialReplayCannotSave;
s32 D_80162DFC;
s32 D_80162E00;
u32* sReplayGhostEncoded = (u32*) &D_802BFB80.arraySize8[0][2][3];
u32* gReplayGhostCompressed = (u32*) &D_802BFB80.arraySize8[1][1][3];
extern s32 gLapCountByPlayerId[];
void load_course_ghost(void) {
sCourseGhostReplay = (u32*) &D_802BFB80.arraySize8[0][2][3];
u8* dest = (u8*) sCourseGhostReplay;
osInvalDCache(&sCourseGhostReplay[0], 0x4000);
u8* ghost = (u8*) D_80162DC4;
size_t size = 0;
if (ghost == d_luigi_raceway_staff_ghost) {
size = 1046 * sizeof(StaffGhost);
} else if (ghost == d_mario_raceway_staff_ghost) {
size = 935 * sizeof(StaffGhost);
} else if (ghost == d_royal_raceway_staff_ghost) {
size = 1907 * sizeof(StaffGhost);
}
// Manual memcpy required for byte swap
for (size_t i = 0; i < size; i += sizeof(StaffGhost)) {
dest[i] = ghost[i + 3];
dest[i + 1] = ghost[i + 2];
dest[i + 2] = ghost[i + 1];
dest[i + 3] = ghost[i];
}
// memcpy(dest, ghost, size);
osRecvMesg(&gDmaMesgQueue, &gMainReceivedMesg, OS_MESG_BLOCK);
sCourseGhostFramesRemaining = (*sCourseGhostReplay & REPLAY_FRAME_COUNTER);
sCourseGhostReplayIdx = 0;
}
void load_post_time_trial_replay(void) {
sPostTTReplay = (u32*) &D_802BFB80.arraySize8[0][D_80162DD0][3];
sPostTTFramesRemaining = *sPostTTReplay & REPLAY_FRAME_COUNTER;
sPostTTReplayIdx = 0;
}
void load_player_ghost(void) {
sPlayerGhostReplay = (u32*) &D_802BFB80.arraySize8[0][D_80162DC8][3];
sPlayerGhostFramesRemaining = (s32) *sPlayerGhostReplay & REPLAY_FRAME_COUNTER;
sPlayerGhostReplayIdx = 0;
}
/**
* Activates staff ghost if time trial lap time is low enough
*
*/
#ifdef VERSION_EU
#define GHOST_UNLOCK_MARIO 10700
#define GHOST_UNLOCK_ROYAL 19300
#define GHOST_UNLOCK_LUIGI 13300
#else
#define GHOST_UNLOCK_MARIO 9000
#define GHOST_UNLOCK_ROYAL 16000
#define GHOST_UNLOCK_LUIGI 11200
#endif
void set_staff_ghost(void) {
CM_SetStaffGhost();
}
// Always returns true because mio0encode is stubbed.
s32 func_800051C4(void) {
s32 phi_v0;
if (sReplayGhostBufferSize != 0) {
// func_80040174 in mio0_decode.s
func_80040174((void*) sReplayGhostBuffer, (sReplayGhostBufferSize * 4) + 0x20, (s32) sReplayGhostEncoded);
phi_v0 =
mio0encode((s32) sReplayGhostEncoded, (sReplayGhostBufferSize * 4) + 0x20, (s32) gReplayGhostCompressed);
return phi_v0 + 0x1e;
}
}
void func_8000522C(void) {
sPlayerGhostReplay = (u32*) &D_802BFB80.arraySize8[0][D_80162DC8][3];
mio0decode((u8*) gReplayGhostCompressed, (u8*) sPlayerGhostReplay);
sPlayerGhostFramesRemaining = (s32) (*sPlayerGhostReplay & REPLAY_FRAME_COUNTER);
sPlayerGhostReplayIdx = 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 = sPlayerInputIdx;
sReplayGhostBuffer = (void*) &D_802BFB80.arraySize8[0][D_80162DC8][3];
sReplayGhostBufferSize = temp_v0;
D_80162D86 = temp_v0;
}
void func_80005310(void) {
if (gModeSelection == TIME_TRIALS) {
set_staff_ghost();
if (staff_ghost_track_ptr != (uintptr_t) GetCourse()) {
bPlayerGhostDisabled = 1;
}
staff_ghost_track_ptr = (uintptr_t) GetCourse();
gPauseTriggered = 0;
sUnusedReplayCounter = 0;
gPostTimeTrialReplayCannotSave = 0;
if (gModeSelection == TIME_TRIALS && gActiveScreenMode == SCREEN_MODE_1P) {
if (D_8015F890 == 1) {
load_post_time_trial_replay();
if (D_80162DD8 == 0) {
load_player_ghost();
}
if (bCourseGhostDisabled == 0) {
load_course_ghost();
}
} else {
D_80162DD8 = 1U;
sPlayerInputs = (u32*) &D_802BFB80.arraySize8[0][D_80162DCC][3];
sPlayerInputs[0] = -1;
sPlayerInputIdx = 0;
D_80162DDC = 0;
func_80091EE4();
if (bPlayerGhostDisabled == 0) {
load_player_ghost();
}
if (bCourseGhostDisabled == 0) {
load_course_ghost();
}
}
}
}
}
/* Special handling for buttons saved in replays. The listing of L_TRIG here is odd
* because it is not saved in the replay data structure. Possibly, L was initially deleted
* here to make way for the frame counter, but then the format changed when the stick
* coordinates were added */
#define REPLAY_MASK (ALL_BUTTONS ^ (A_BUTTON | B_BUTTON | Z_TRIG | R_TRIG | L_TRIG))
/* Inputs for replays (including player and course ghosts) are saved in a s32[] where
each entry is a combination of the inputs and how long those inputs were held for.
In essence it's "These buttons were pressed and the joystick was in this position.
This was the case for X frames".
bits 1-8: Stick X
bits 9-16: Stick Y
bits 17-24: Frame counter
bits 25-28: Unused
bit 29: R
bit 30: Z
bit 31: B
bit 32: A
*/
void process_post_time_trial_replay(void) {
u32 inputs;
u32 stickBytes;
UNUSED u16 unk;
u16 buttons_temp;
s16 stickVal;
s16 buttons = 0;
if (sPostTTReplayIdx >= 0x1000) {
gPlayerOne->type = PLAYER_CINEMATIC_MODE | PLAYER_START_SEQUENCE | PLAYER_CPU;
return;
}
inputs = sPostTTReplay[sPostTTReplayIdx];
stickBytes = inputs & REPLAY_STICK_X;
// twos complement trick, converting singned 8-bit value to signed 16 bit
if (stickBytes < 0x80U) {
stickVal = (s16) (stickBytes & 0xFF);
} else {
stickVal = (s16) (stickBytes | (~0xFF));
}
stickBytes = (u32) (inputs & REPLAY_STICK_Y) >> 8;
gControllerEight->rawStickX = stickVal;
if (stickBytes < 0x80U) {
stickVal = (s16) (stickBytes & 0xFF);
} else {
stickVal = (s16) (stickBytes | (~0xFF));
}
gControllerEight->rawStickY = stickVal;
if (inputs & REPLAY_A_BUTTON) {
buttons |= A_BUTTON;
}
if (inputs & REPLAY_B_BUTTON) {
buttons |= B_BUTTON;
}
if (inputs & REPLAY_Z_TRIG) {
buttons |= Z_TRIG;
}
if (inputs & REPLAY_R_TRIG) {
buttons |= R_TRIG;
}
buttons_temp = gControllerEight->buttonPressed & REPLAY_MASK;
gControllerEight->buttonPressed = (buttons & (buttons ^ sPostTTButtonsPrev)) | buttons_temp;
buttons_temp = gControllerEight->buttonDepressed & REPLAY_MASK;
gControllerEight->buttonDepressed = (sPostTTButtonsPrev & (buttons ^ sPostTTButtonsPrev)) | buttons_temp;
sPostTTButtonsPrev = buttons;
gControllerEight->button = buttons;
if (sPostTTFramesRemaining == 0) {
sPostTTReplayIdx++;
sPostTTFramesRemaining = (s32) (sPostTTReplay[sPostTTReplayIdx] & REPLAY_FRAME_COUNTER);
} else {
sPostTTFramesRemaining -= REPLAY_FRAME_INCREMENT;
}
}
// See process_post_time_trial_replay comment
void process_course_ghost_replay(void) {
u32 inputs;
u32 stickBytes;
UNUSED u16 unk;
u16 buttonsTemp;
s16 stickVal;
s16 buttons = 0;
if (sCourseGhostReplayIdx >= 0x1000) {
func_80005AE8(gPlayerThree);
return;
}
inputs = sCourseGhostReplay[sCourseGhostReplayIdx];
stickBytes = inputs & REPLAY_STICK_X;
// converting signed 8-bit values to signed 16-bit values
if (stickBytes < 0x80U) {
stickVal = (s16) (stickBytes & 0xFF);
} else {
stickVal = (s16) (stickBytes | (~0xFF));
}
stickBytes = (u32) (inputs & REPLAY_STICK_Y) >> 8;
gControllerSeven->rawStickX = stickVal;
if (stickBytes < 0x80U) {
stickVal = (s16) (stickBytes & 0xFF);
} else {
stickVal = (s16) (stickBytes | (~0xFF));
}
gControllerSeven->rawStickY = stickVal;
if (inputs & REPLAY_A_BUTTON) {
buttons = A_BUTTON;
}
if (inputs & REPLAY_B_BUTTON) {
buttons |= B_BUTTON;
}
if (inputs & REPLAY_Z_TRIG) {
buttons |= Z_TRIG;
}
if (inputs & REPLAY_R_TRIG) {
buttons |= R_TRIG;
}
// Blanks the A, B, Z, R and L buttons
buttonsTemp = gControllerSeven->buttonPressed & REPLAY_MASK;
gControllerSeven->buttonPressed = (buttons & (buttons ^ sButtonsPrevCourseGhost)) | buttonsTemp;
buttonsTemp = gControllerSeven->buttonDepressed & REPLAY_MASK;
gControllerSeven->buttonDepressed = (sButtonsPrevCourseGhost & (buttons ^ sButtonsPrevCourseGhost)) | buttonsTemp;
sButtonsPrevCourseGhost = buttons;
gControllerSeven->button = buttons;
if (sCourseGhostFramesRemaining == 0) {
sCourseGhostReplayIdx++;
sCourseGhostFramesRemaining = (s32) (sCourseGhostReplay[sCourseGhostReplayIdx] & REPLAY_FRAME_COUNTER);
} else {
sCourseGhostFramesRemaining -= (s32) REPLAY_FRAME_INCREMENT;
}
}
// See process_post_time_trial_replay comment
void process_player_ghost_replay(void) {
u32 inputs;
u32 stickBytes;
UNUSED u16 unk;
u16 buttons_temp;
s16 stickVal;
s16 buttons = 0;
if (sPlayerGhostReplayIdx >= 0x1000) {
func_80005AE8(gPlayerTwo);
return;
}
inputs = sPlayerGhostReplay[sPlayerGhostReplayIdx];
stickBytes = inputs & REPLAY_STICK_X;
if (stickBytes < 0x80U) {
stickVal = (s16) (stickBytes & 0xFF);
} else {
stickVal = (s16) (stickBytes | ~0xFF);
}
stickBytes = (u32) (inputs & REPLAY_STICK_Y) >> 8;
gControllerSix->rawStickX = stickVal;
if (stickBytes < 0x80U) {
stickVal = (s16) (stickBytes & 0xFF);
} else {
stickVal = (s16) (stickBytes | (~0xFF));
}
gControllerSix->rawStickY = stickVal;
if (inputs & REPLAY_A_BUTTON) {
buttons = A_BUTTON;
}
if (inputs & REPLAY_B_BUTTON) {
buttons |= B_BUTTON;
}
if (inputs & REPLAY_Z_TRIG) {
buttons |= Z_TRIG;
}
if (inputs & REPLAY_R_TRIG) {
buttons |= R_TRIG;
}
buttons_temp = gControllerSix->buttonPressed & REPLAY_MASK;
gControllerSix->buttonPressed = (buttons & (buttons ^ sPlayerGhostButtonsPrev)) | buttons_temp;
buttons_temp = gControllerSix->buttonDepressed & REPLAY_MASK;
gControllerSix->buttonDepressed = (sPlayerGhostButtonsPrev & (buttons ^ sPlayerGhostButtonsPrev)) | buttons_temp;
sPlayerGhostButtonsPrev = buttons;
gControllerSix->button = buttons;
if (sPlayerGhostFramesRemaining == 0) {
sPlayerGhostReplayIdx++;
sPlayerGhostFramesRemaining = (s32) (sPlayerGhostReplay[sPlayerGhostReplayIdx] & REPLAY_FRAME_COUNTER);
} else {
sPlayerGhostFramesRemaining -= (s32) REPLAY_FRAME_INCREMENT;
}
}
// See process_post_time_trial_replay comment
void save_player_replay(void) {
s16 buttons;
u32 inputs;
u32 stickX;
u32 stickY;
u32 inputCounter;
u32 prevInputsWCounter;
u32 prevInputs;
/* Input file is too long or picked up by lakitu or Out of bounds
Not sure if there is any way to be considered out of bounds without lakitu getting called */
if (((sPlayerInputIdx >= 0x1000) || ((gPlayerOne->unk_0CA & 2) != 0)) || ((gPlayerOne->unk_0CA & 8) != 0)) {
gPostTimeTrialReplayCannotSave = 1;
return;
}
stickX = gControllerOne->rawStickX;
stickX &= 0xFF;
stickY = gControllerOne->rawStickY;
stickY = (stickY & 0xFF) << 8;
buttons = gControllerOne->button;
inputs = 0;
if (buttons & A_BUTTON) {
inputs |= REPLAY_A_BUTTON;
}
if (buttons & B_BUTTON) {
inputs |= REPLAY_B_BUTTON;
}
if (buttons & Z_TRIG) {
inputs |= REPLAY_Z_TRIG;
}
if (buttons & R_TRIG) {
inputs |= REPLAY_R_TRIG;
}
inputs |= stickX;
inputs |= stickY;
prevInputsWCounter = sPlayerInputs[sPlayerInputIdx];
/* The 5th and 6th bytes from the right are counters. Instead of saving the same inputs over and over,
it says "these inputs were played for __ frames" */
prevInputs = prevInputsWCounter & REPLAY_CLEAR_FRAME_COUNTER;
// first frame of inputs
if ((*sPlayerInputs) == -1) {
sPlayerInputs[sPlayerInputIdx] = inputs;
} else if (prevInputs == inputs) {
inputCounter = prevInputsWCounter & REPLAY_FRAME_COUNTER;
if (inputCounter == REPLAY_FRAME_COUNTER) {
sPlayerInputIdx++;
sPlayerInputs[sPlayerInputIdx] = inputs;
} else {
// increment counter by 1
prevInputsWCounter += REPLAY_FRAME_INCREMENT;
sPlayerInputs[sPlayerInputIdx] = prevInputsWCounter;
}
} else {
sPlayerInputIdx++;
sPlayerInputs[sPlayerInputIdx] = inputs;
}
}
// 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) && (gPostTimeTrialReplayCannotSave != 1)) {
if (bPlayerGhostDisabled == 1) {
D_80162DD0 = D_80162DCC;
func_800052A4();
bPlayerGhostDisabled = 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 {
sReplayGhostBuffer = D_802BFB80.arraySize8[0][D_80162DC8][3].pixel_index_array;
sReplayGhostBufferSize = D_80162D86;
D_80162DD0 = D_80162DCC;
D_80162DE8 = gPlayerOne->characterId;
D_80162DD8 = 0;
bPlayerGhostDisabled = 0;
D_80162DDC = 1;
func_80005AE8(gPlayerTwo);
func_80005AE8(gPlayerThree);
}
} else {
if ((gLapCountByPlayerId[0] == 3) && (D_80162DDC == 0) && (gPostTimeTrialReplayCannotSave == 1)) {
sReplayGhostBuffer = D_802BFB80.arraySize8[0][D_80162DC8][3].pixel_index_array;
sReplayGhostBufferSize = D_80162D86;
D_80162DDC = 1;
}
if ((gPlayerOne->type & 0x800) == 0x800) {
func_80005AE8(gPlayerTwo);
func_80005AE8(gPlayerThree);
} else {
sUnusedReplayCounter += 1;
if (sUnusedReplayCounter > 100) {
sUnusedReplayCounter = 100;
}
if ((gModeSelection == TIME_TRIALS) && (gActiveScreenMode == SCREEN_MODE_1P)) {
if ((bPlayerGhostDisabled == 0) && (gLapCountByPlayerId[1] != 3)) {
process_player_ghost_replay();
}
if ((bCourseGhostDisabled == 0) && (gLapCountByPlayerId[2] != 3)) {
process_course_ghost_replay();
}
if (!(gPlayerOne->type & PLAYER_CINEMATIC_MODE)) {
save_player_replay();
}
}
}
}
}
}
void func_80005E6C(void) {
if ((gModeSelection == TIME_TRIALS) && (gModeSelection == TIME_TRIALS) && (gActiveScreenMode == SCREEN_MODE_1P)) {
if ((D_80162DD8 == 0) && (gLapCountByPlayerId[1] != 3)) {
process_player_ghost_replay(); // 3
}
if ((bCourseGhostDisabled == 0) && (gLapCountByPlayerId[2] != 3)) {
process_course_ghost_replay(); // 2
}
if ((gPlayerOne->type & PLAYER_CINEMATIC_MODE) != PLAYER_CINEMATIC_MODE) {
process_post_time_trial_replay(); // 1
return;
}
func_80005AE8(gPlayerTwo);
func_80005AE8(gPlayerThree);
}
}
void replays_loop(void) {
if (D_8015F890 == 1) {
func_80005E6C();
return;
}
if (!gPauseTriggered) {
func_80005B18();
return;
}
/* This only gets triggered when the previous if-statements are not met
Seems like just for pausing */
gPostTimeTrialReplayCannotSave = 1;
}
+16 -16
View File
@@ -1,25 +1,25 @@
#ifndef STAFF_GHOSTS_H
#define STAFF_GHOSTS_H
#ifndef REPLAYS_H
#define REPLAYS_H
#include <libultraship.h>
#include <common_structs.h>
void func_80005B18(void);
void func_80004EF0(void);
void func_80004FB0(void);
void func_80004FF8(void);
void load_course_ghost(void);
void load_post_time_trial_replay(void);
void load_player_ghost(void);
void set_staff_ghost(void);
s32 func_800051C4(void);
void func_8000522C(void);
void func_800052A4(void);
void func_80005310(void);
void func_8000546C(void);
void func_8000561C(void);
void func_800057DC(void);
void func_8000599C(void);
void process_post_time_trial_replay(void);
void process_course_ghost_replay(void);
void process_player_ghost_replay(void);
void save_player_replay(void);
void func_80005AE8(Player*);
void func_80005E6C(void);
void staff_ghosts_loop(void);
void replays_loop(void);
// mi0decode
@@ -28,19 +28,19 @@ extern s32 mio0encode(s32 input, s32, s32);
extern StaffGhost* D_80162DC4;
extern s32 D_80162DC8;
extern s32 D_80162DCC;
extern u16 D_80162DD4;
extern u16 D_80162DD6;
extern u16 bPlayerGhostDisabled;
extern u16 bCourseGhostDisabled;
extern u16 D_80162DD8;
extern s32 D_80162E00;
extern s32 D_80162DE0;
extern s32 D_80162DE4;
extern s32 D_80162DE8;
extern s32 D_80162DF0;
extern s32 gPauseTriggered;
extern s32 D_80162DF4;
extern s32 D_80162DF8;
extern s32 gPostTimeTrialReplayCannotSave;
extern u8* sReplayGhostBuffer;
extern size_t sReplayGhostBufferSize;
extern u32* sReplayGhostDecompressed;
extern u32* sPlayerGhostReplay;
#endif /* STAFF_GHOSTS_H */
#endif /* REPLAYS_H */
+14 -14
View File
@@ -8,7 +8,7 @@
#include "menu_items.h"
#include "menus.h"
#include "save_data.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "code_80057C60.h"
#include "port/Game.h"
#include "buffers.h"
@@ -249,8 +249,8 @@ u32 func_800B4DF4(u8* arr) {
// Get a time trial record, infer course index
s32 func_800B4E24(s32 recordIndex) {
return func_800B4DF4(gSaveData.allCourseTimeTrialRecords.cupRecords[(((GetCupIndex() * 4) + gCourseIndexInCup) / 4)]
.courseRecords[(((GetCupIndex() * 4) + gCourseIndexInCup) % 4)]
return func_800B4DF4(gSaveData.allCourseTimeTrialRecords.cupRecords[GetCupIndex()]
.courseRecords[GetCupCursorPosition()]
.records[recordIndex]);
}
@@ -263,8 +263,8 @@ u32 func_800B4EB4(s32 recordIndex, s32 courseIndex) {
// Get Best Lap record of the inferred course index
s32 func_800B4F2C(void) {
return func_800B4DF4(gSaveData.allCourseTimeTrialRecords.cupRecords[(((GetCupIndex() * 4) + gCourseIndexInCup) / 4)]
.courseRecords[(((GetCupIndex() * 4) + gCourseIndexInCup) % 4)]
return func_800B4DF4(gSaveData.allCourseTimeTrialRecords.cupRecords[GetCupIndex()]
.courseRecords[GetCupCursorPosition()]
.records[TIME_TRIAL_1LAP_RECORD]);
}
@@ -282,7 +282,7 @@ s32 func_800B5020(u32 time, s32 charId) {
s32 j;
CourseTimeTrialRecords* tt;
course = GetCupIndex() * 4 + gCourseIndexInCup;
course = GetCupIndex() * 4 + GetCupCursorPosition();
tt = &gSaveData.allCourseTimeTrialRecords.cupRecords[course / 4].courseRecords[course % 4];
i = 0;
@@ -329,7 +329,7 @@ s32 func_800B5218(void) {
s32 checkLapIndex;
s32 character;
s32 lapBitmask;
recordIndex = (GetCupIndex() * 4) + gCourseIndexInCup;
recordIndex = (GetCupIndex() * 4) + GetCupCursorPosition();
recordPointer =
&gSaveData.allCourseTimeTrialRecords.cupRecords[recordIndex / 4].courseRecords[recordIndex % 4].records[0][0];
lapBitmask = 1;
@@ -782,7 +782,7 @@ s32 func_800B6178(s32 arg0) {
if (var_v0 == 0) {
temp_s3->ghostDataSaved = 1;
if (gGamestate == 4) {
temp_s3->courseIndex = (GetCupIndex() * 4) + gCourseIndexInCup;
temp_s3->courseIndex = (GetCupIndex() * 4) + GetCupCursorPosition();
}
temp_s3->unk_00 = D_80162DFC;
temp_s3->characterId = (u8) D_80162DE0;
@@ -827,11 +827,11 @@ s32 func_800B63F0(s32 arg0) {
s32 phi_s3;
func_800051C4();
D_80162DD6 = 1;
bCourseGhostDisabled = 1;
func_80005AE8(gPlayerThree);
phi_s3 = 0;
if (((GetCupIndex() * 4) + gCourseIndexInCup) != D_8018EE10[arg0].courseIndex) {
if (((GetCupIndex() * 4) + GetCupCursorPosition()) != D_8018EE10[arg0].courseIndex) {
phi_s3 = 2;
} else if (D_80162DFC != D_8018EE10[arg0].unk_00) {
phi_s3 = 3;
@@ -866,16 +866,16 @@ s32 func_800B64EC(s32 arg0) {
return -1;
}
sReplayGhostDecompressed = (u32*) &D_802BFB80.arraySize8[0][D_80162DC8][3];
sPlayerGhostReplay = (u32*) &D_802BFB80.arraySize8[0][D_80162DC8][3];
temp_v0 =
osPfsReadWriteFile(&gControllerPak1FileHandle, gControllerPak1FileNote, PFS_READ,
(arg0 * (sizeof(u8) * 0x1000)) + 0x100, sizeof(u8) * 0x1000, (u8*) sReplayGhostDecompressed);
(arg0 * (sizeof(u8) * 0x1000)) + 0x100, sizeof(u8) * 0x1000, (u8*) sPlayerGhostReplay);
if (temp_v0 == 0) {
// clang-format off
phi_s1 = (u8 *) &D_8018EE10[arg0]; temp_s0 = 0; while (1) {
// clang-format on
if (phi_s1[7] != func_800B60E8(temp_s0, (u8*) sReplayGhostDecompressed)) {
if (phi_s1[7] != func_800B60E8(temp_s0, (u8*) sPlayerGhostReplay)) {
D_8018EE10[arg0].ghostDataSaved = 0;
return -2;
}
@@ -883,7 +883,7 @@ s32 func_800B64EC(s32 arg0) {
++phi_s1;
if ((++temp_s0) == 0x3C) {
func_8000522C();
D_80162DD4 = 0;
bPlayerGhostDisabled = 0;
D_80162DE0 = (s32) D_8018EE10[arg0].characterId;
D_80162DFC = D_8018EE10[arg0].unk_00;
break;
+1 -1
View File
@@ -98,7 +98,7 @@ extern s8 sControllerPak2State; // Current state of the Controller Pak 2
extern const u8 D_800F2E60[];
extern const u8 gGameName[];
extern const u8 gExtCode[];
extern u16 D_80162DD6;
extern u16 bCourseGhostDisabled;
extern s32 D_80162DE0;
extern s32 D_80162DFC;
extern OSPfs gControllerPak1FileHandle;
+4 -4
View File
@@ -16,7 +16,7 @@
#include "code_80057C60.h"
#include "collision.h"
#include "render_courses.h"
#include "staff_ghosts.h"
#include "replays.h"
#include "code_80005FD0.h"
#include "render_player.h"
#include "podium_ceremony_actors.h"
@@ -596,14 +596,14 @@ void spawn_players_versus_one_player(f32* arg0, f32* arg1, f32 arg2) {
} else if (D_8015F890 != 1) {
spawn_player(gPlayerOne, 0, arg0[0], arg1[0], arg2, 32768.0f, gCharacterSelections[0],
PLAYER_EXISTS | PLAYER_START_SEQUENCE | PLAYER_HUMAN);
if (D_80162DD4 == 0) {
if (bPlayerGhostDisabled == 0) {
spawn_player(gPlayerTwo, 1, arg0[0], arg1[0], arg2, 32768.0f, D_80162DE0,
PLAYER_EXISTS | PLAYER_HUMAN | PLAYER_START_SEQUENCE | PLAYER_INVISIBLE_OR_BOMB);
} else {
spawn_player(gPlayerTwo, 1, arg0[0], arg1[0], arg2, 32768.0f, gCharacterSelections[0],
PLAYER_START_SEQUENCE | PLAYER_CPU);
}
if (D_80162DD6 == 0) {
if (bCourseGhostDisabled == 0) {
spawn_player(gPlayerThree, 2, arg0[0], arg1[0], arg2, 32768.0f, D_80162DE4,
PLAYER_EXISTS | PLAYER_HUMAN | PLAYER_START_SEQUENCE | PLAYER_INVISIBLE_OR_BOMB);
} else {
@@ -620,7 +620,7 @@ void spawn_players_versus_one_player(f32* arg0, f32* arg1, f32 arg2) {
spawn_player(gPlayerTwo, 1, arg0[0], arg1[0], arg2, 32768.0f, gCharacterSelections[0],
PLAYER_START_SEQUENCE | PLAYER_CPU);
}
if (D_80162DD6 == 0) {
if (bCourseGhostDisabled == 0) {
spawn_player(gPlayerThree, 2, arg0[0], arg1[0], arg2, 32768.0f, D_80162DE4,
PLAYER_EXISTS | PLAYER_HUMAN | PLAYER_START_SEQUENCE | PLAYER_INVISIBLE_OR_BOMB);
} else {
-542
View File
@@ -1,542 +0,0 @@
#include <libultraship.h>
#include <macros.h>
#include <mk64.h>
#include <stubs.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 "menu_items.h"
#include "code_80057C60.h"
#include "kart_dma.h"
#include "port/Game.h"
#include "courses/staff_ghost_data.h"
u8* sReplayGhostBuffer;
size_t sReplayGhostBufferSize;
s16 D_80162D86;
u16 D_80162D88;
u32 D_80162D8C;
s16 D_80162D90;
u32* sReplayGhostDecompressed;
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;
uintptr_t staff_ghost_track_ptr;
StaffGhost* 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* sReplayGhostEncoded = (u32*) &D_802BFB80.arraySize8[0][2][3];
u32* gReplayGhostCompressed = (u32*) &D_802BFB80.arraySize8[1][1][3];
extern s32 gLapCountByPlayerId[];
void func_80004EF0(void) {
D_80162DA4 = (u32*) &D_802BFB80.arraySize8[0][2][3];
u8* dest = (u8*) D_80162DA4;
osInvalDCache(&D_80162DA4[0], 0x4000);
u8* ghost = (u8*) D_80162DC4;
size_t size = 0;
if (ghost == d_luigi_raceway_staff_ghost) {
size = 187 * sizeof(StaffGhost);
} else if (ghost == d_mario_raceway_staff_ghost) {
size = 208 * sizeof(StaffGhost);
} else if (ghost == d_royal_raceway_staff_ghost) {
size = 377 * sizeof(StaffGhost);
}
// Manual memcpy required for byte swap
for (size_t i = 0; i < size; i += 4) {
dest[i] = ghost[i + 3];
dest[i + 1] = ghost[i + 2];
dest[i + 2] = ghost[i + 1];
dest[i + 3] = ghost[i];
}
osRecvMesg(&gDmaMesgQueue, &gMainReceivedMesg, OS_MESG_BLOCK);
D_80162D9C = (*D_80162DA4 & 0xFF0000);
D_80162DA0 = 0;
}
void func_80004FB0(void) {
D_80162DB4 = (u32*) &D_802BFB80.arraySize8[0][D_80162DD0][3];
D_80162DAC = *D_80162DB4 & 0xFF0000;
D_80162DB0 = 0;
}
void func_80004FF8(void) {
sReplayGhostDecompressed = (u32*) &D_802BFB80.arraySize8[0][D_80162DC8][3];
D_80162D8C = (s32) *sReplayGhostDecompressed & 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) {
CM_SetStaffGhost();
}
// Always returns true because mio0encode is stubbed.
s32 func_800051C4(void) {
s32 phi_v0;
if (sReplayGhostBufferSize != 0) {
// func_80040174 in mio0_decode.s
func_80040174((void*) sReplayGhostBuffer, (sReplayGhostBufferSize * 4) + 0x20, (s32) sReplayGhostEncoded);
phi_v0 =
mio0encode((s32) sReplayGhostEncoded, (sReplayGhostBufferSize * 4) + 0x20, (s32) gReplayGhostCompressed);
return phi_v0 + 0x1e;
}
}
void func_8000522C(void) {
sReplayGhostDecompressed = (u32*) &D_802BFB80.arraySize8[0][D_80162DC8][3];
mio0decode((u8*) gReplayGhostCompressed, (u8*) sReplayGhostDecompressed);
D_80162D8C = (s32) (*sReplayGhostDecompressed & 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;
sReplayGhostBuffer = (void*) &D_802BFB80.arraySize8[0][D_80162DC8][3];
sReplayGhostBufferSize = temp_v0;
D_80162D86 = temp_v0;
}
void func_80005310(void) {
if (gModeSelection == TIME_TRIALS) {
set_staff_ghost();
if (staff_ghost_track_ptr != (uintptr_t)GetCourse()) {
D_80162DD4 = 1;
}
staff_ghost_track_ptr = (uintptr_t)GetCourse();
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.arraySize8[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 = sReplayGhostDecompressed[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) (sReplayGhostDecompressed[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 {
sReplayGhostBuffer = D_802BFB80.arraySize8[0][D_80162DC8][3].pixel_index_array;
sReplayGhostBufferSize = 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)) {
sReplayGhostBuffer = D_802BFB80.arraySize8[0][D_80162DC8][3].pixel_index_array;
sReplayGhostBufferSize = 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;
}
+1 -1
View File
@@ -205,7 +205,7 @@ void func_80072180(void) {
if (gModeSelection == TIME_TRIALS) {
if (((gPlayerOne->type & PLAYER_EXISTS) != 0) &&
((gPlayerOne->type & (PLAYER_INVISIBLE_OR_BOMB | PLAYER_CPU)) == 0)) {
D_80162DF8 = 1;
gPostTimeTrialReplayCannotSave = 1;
}
}
}
+1 -1
View File
@@ -363,7 +363,7 @@ extern u16* gHudLapTextures[];
extern u16* gPortraitTLUTs[];
extern u8* gPortraitTextures[];
extern s32 D_80162DF8;
extern s32 gPostTimeTrialReplayCannotSave;
extern s16 D_8016347C;
extern s32 D_80165594;
extern s32 D_80165598;