2019-08-25 04:46:40 +00:00
|
|
|
#include "ultra64.h"
|
|
|
|
#include "sm64.h"
|
2019-11-03 19:36:27 +00:00
|
|
|
#include "prevent_bss_reordering.h"
|
2019-08-25 04:46:40 +00:00
|
|
|
#include "types.h"
|
2019-10-05 19:08:05 +00:00
|
|
|
#include "game/memory.h"
|
|
|
|
#include "game/segment2.h"
|
|
|
|
#include "game/segment7.h"
|
2019-08-25 04:46:40 +00:00
|
|
|
#include "intro_geo.h"
|
|
|
|
|
2020-05-07 18:21:22 +00:00
|
|
|
#include "gfx_dimensions.h"
|
|
|
|
|
2019-08-25 04:46:40 +00:00
|
|
|
// frame counts for the zoom in, hold, and zoom out of title model
|
|
|
|
#define INTRO_STEPS_ZOOM_IN 20
|
|
|
|
#define INTRO_STEPS_HOLD_1 75
|
|
|
|
#define INTRO_STEPS_ZOOM_OUT 91
|
|
|
|
|
|
|
|
// background types
|
|
|
|
#define INTRO_BACKGROUND_SUPER_MARIO 0
|
|
|
|
#define INTRO_BACKGROUND_GAME_OVER 1
|
|
|
|
|
|
|
|
struct GraphNodeMore {
|
|
|
|
/*0x00*/ struct GraphNode node;
|
|
|
|
/*0x14*/ void *todo;
|
|
|
|
/*0x18*/ u32 unk18;
|
|
|
|
};
|
|
|
|
|
|
|
|
// title screen segment A
|
|
|
|
extern Gfx title_screen_bg_dl_0A000118[];
|
|
|
|
extern Gfx title_screen_bg_dl_0A000100[];
|
|
|
|
extern Gfx title_screen_bg_dl_0A000130[];
|
|
|
|
extern Gfx title_screen_bg_dl_0A000148[];
|
|
|
|
extern Gfx title_screen_bg_dl_0A000160[];
|
|
|
|
extern Gfx title_screen_bg_dl_0A000178[];
|
|
|
|
extern Gfx title_screen_bg_dl_0A000190[];
|
2019-11-03 19:36:27 +00:00
|
|
|
extern const u8 *const mario_title_texture_table[];
|
|
|
|
extern const u8 *const game_over_texture_table[];
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
// intro geo bss
|
2020-02-03 05:51:26 +00:00
|
|
|
s32 gGameOverFrameCounter;
|
|
|
|
s32 gGameOverTableIndex;
|
2019-08-25 04:46:40 +00:00
|
|
|
s16 gTitleZoomCounter;
|
|
|
|
s32 gTitleFadeCounter;
|
|
|
|
|
|
|
|
// intro screen background display lists for each of four 80x20 textures
|
|
|
|
Gfx *introBackgroundDlRows[] = { title_screen_bg_dl_0A000130, title_screen_bg_dl_0A000148,
|
|
|
|
title_screen_bg_dl_0A000160, title_screen_bg_dl_0A000178 };
|
|
|
|
|
|
|
|
// intro screen background texture X offsets
|
|
|
|
float introBackgroundOffsetX[] = {
|
|
|
|
0.0, 80.0, 160.0, 240.0, 0.0, 80.0, 160.0, 240.0, 0.0, 80.0, 160.0, 240.0,
|
|
|
|
};
|
|
|
|
|
|
|
|
// intro screen background texture Y offsets
|
|
|
|
float introBackgroundOffsetY[] = {
|
|
|
|
160.0, 160.0, 160.0, 160.0, 80.0, 80.0, 80.0, 80.0, 0.0, 0.0, 0.0, 0.0,
|
|
|
|
};
|
|
|
|
|
|
|
|
// table that points to either the "Super Mario 64" or "Game Over" tables
|
2019-11-03 19:36:27 +00:00
|
|
|
const u8 *const *introBackgroundTextureType[] = { mario_title_texture_table, game_over_texture_table };
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
s8 introBackgroundIndexTable[] = {
|
|
|
|
INTRO_BACKGROUND_SUPER_MARIO, INTRO_BACKGROUND_SUPER_MARIO, INTRO_BACKGROUND_SUPER_MARIO,
|
|
|
|
INTRO_BACKGROUND_SUPER_MARIO, INTRO_BACKGROUND_SUPER_MARIO, INTRO_BACKGROUND_SUPER_MARIO,
|
|
|
|
INTRO_BACKGROUND_SUPER_MARIO, INTRO_BACKGROUND_SUPER_MARIO, INTRO_BACKGROUND_SUPER_MARIO,
|
|
|
|
INTRO_BACKGROUND_SUPER_MARIO, INTRO_BACKGROUND_SUPER_MARIO, INTRO_BACKGROUND_SUPER_MARIO,
|
|
|
|
};
|
|
|
|
|
|
|
|
// only one table of indexes listed
|
|
|
|
s8 *introBackgroundTables[] = { introBackgroundIndexTable };
|
|
|
|
|
|
|
|
s8 gameOverBackgroundTable[] = {
|
|
|
|
INTRO_BACKGROUND_GAME_OVER, INTRO_BACKGROUND_GAME_OVER, INTRO_BACKGROUND_GAME_OVER,
|
|
|
|
INTRO_BACKGROUND_GAME_OVER, INTRO_BACKGROUND_GAME_OVER, INTRO_BACKGROUND_GAME_OVER,
|
|
|
|
INTRO_BACKGROUND_GAME_OVER, INTRO_BACKGROUND_GAME_OVER, INTRO_BACKGROUND_GAME_OVER,
|
|
|
|
INTRO_BACKGROUND_GAME_OVER, INTRO_BACKGROUND_GAME_OVER, INTRO_BACKGROUND_GAME_OVER,
|
|
|
|
};
|
|
|
|
|
|
|
|
// order of tiles that are flipped from "Game Over" to "Super Mario 64"
|
|
|
|
s8 gameOverBackgroundFlipOrder[] = { 0x00, 0x01, 0x02, 0x03, 0x07, 0x0B,
|
|
|
|
0x0a, 0x09, 0x08, 0x04, 0x05, 0x06 };
|
|
|
|
|
2020-04-03 18:57:26 +00:00
|
|
|
Gfx *geo_title_screen(s32 sp50, struct GraphNode *sp54, UNUSED void *context) {
|
2019-08-25 04:46:40 +00:00
|
|
|
struct GraphNode *graphNode; // sp4c
|
|
|
|
Gfx *displayList; // sp48
|
|
|
|
Gfx *displayListIter; // sp44
|
|
|
|
Mtx *scaleMat; // sp40
|
|
|
|
f32 *scaleTable1; // sp3c
|
|
|
|
f32 *scaleTable2; // sp38
|
|
|
|
f32 scaleX; // sp34
|
|
|
|
f32 scaleY; // sp30
|
|
|
|
f32 scaleZ; // sp2c
|
|
|
|
graphNode = sp54;
|
|
|
|
displayList = NULL;
|
|
|
|
displayListIter = NULL;
|
|
|
|
scaleTable1 = segmented_to_virtual(intro_seg7_table_0700C790);
|
|
|
|
scaleTable2 = segmented_to_virtual(intro_seg7_table_0700C880);
|
|
|
|
if (sp50 != 1) {
|
|
|
|
gTitleZoomCounter = 0;
|
|
|
|
} else if (sp50 == 1) {
|
|
|
|
graphNode->flags = (graphNode->flags & 0xFF) | 0x100;
|
|
|
|
scaleMat = alloc_display_list(sizeof(*scaleMat));
|
|
|
|
displayList = alloc_display_list(4 * sizeof(*displayList));
|
|
|
|
displayListIter = displayList;
|
|
|
|
if (gTitleZoomCounter >= 0 && gTitleZoomCounter < INTRO_STEPS_ZOOM_IN) {
|
|
|
|
scaleX = scaleTable1[gTitleZoomCounter * 3];
|
|
|
|
scaleY = scaleTable1[gTitleZoomCounter * 3 + 1];
|
|
|
|
scaleZ = scaleTable1[gTitleZoomCounter * 3 + 2];
|
|
|
|
} else if (gTitleZoomCounter >= INTRO_STEPS_ZOOM_IN && gTitleZoomCounter < INTRO_STEPS_HOLD_1) {
|
|
|
|
scaleX = 1.0f;
|
|
|
|
scaleY = 1.0f;
|
|
|
|
scaleZ = 1.0f;
|
|
|
|
} else if (gTitleZoomCounter >= INTRO_STEPS_HOLD_1
|
|
|
|
&& gTitleZoomCounter < INTRO_STEPS_ZOOM_OUT) {
|
|
|
|
scaleX = scaleTable2[(gTitleZoomCounter - INTRO_STEPS_HOLD_1) * 3];
|
|
|
|
scaleY = scaleTable2[(gTitleZoomCounter - INTRO_STEPS_HOLD_1) * 3 + 1];
|
|
|
|
scaleZ = scaleTable2[(gTitleZoomCounter - INTRO_STEPS_HOLD_1) * 3 + 2];
|
|
|
|
} else {
|
|
|
|
scaleX = 0.0f;
|
|
|
|
scaleY = 0.0f;
|
|
|
|
scaleZ = 0.0f;
|
|
|
|
}
|
|
|
|
guScale(scaleMat, scaleX, scaleY, scaleZ);
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPMatrix(displayListIter++, scaleMat, G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(displayListIter++, &intro_seg7_dl_0700B3A0);
|
|
|
|
gSPPopMatrix(displayListIter++, G_MTX_MODELVIEW);
|
|
|
|
gSPEndDisplayList(displayListIter);
|
|
|
|
gTitleZoomCounter++;
|
|
|
|
}
|
|
|
|
return displayList;
|
|
|
|
}
|
|
|
|
|
2020-04-03 18:57:26 +00:00
|
|
|
Gfx *geo_fade_transition(s32 sp40, struct GraphNode *sp44, UNUSED void *context) {
|
2019-08-25 04:46:40 +00:00
|
|
|
struct GraphNode *graphNode = sp44; // sp3c
|
|
|
|
Gfx *displayList = NULL; // sp38
|
|
|
|
Gfx *displayListIter = NULL; // sp34
|
|
|
|
if (sp40 != 1) {
|
|
|
|
gTitleFadeCounter = 0; // D_801B985C
|
|
|
|
} else if (sp40 == 1) {
|
|
|
|
displayList = alloc_display_list(5 * sizeof(*displayList));
|
|
|
|
displayListIter = displayList;
|
|
|
|
gSPDisplayList(displayListIter++, dl_proj_mtx_fullscreen);
|
2019-12-02 02:52:53 +00:00
|
|
|
gDPSetEnvColor(displayListIter++, 255, 255, 255, gTitleFadeCounter);
|
|
|
|
if (gTitleFadeCounter == 255) {
|
2019-08-25 04:46:40 +00:00
|
|
|
if (0) {
|
|
|
|
}
|
|
|
|
graphNode->flags = (graphNode->flags & 0xFF) | 0x100;
|
|
|
|
gDPSetRenderMode(displayListIter++, G_RM_AA_OPA_SURF, G_RM_AA_OPA_SURF2);
|
|
|
|
} else {
|
|
|
|
graphNode->flags = (graphNode->flags & 0xFF) | 0x500;
|
|
|
|
gDPSetRenderMode(displayListIter++, G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2);
|
|
|
|
if (0) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gSPDisplayList(displayListIter++, &intro_seg7_dl_0700C6A0);
|
|
|
|
gSPEndDisplayList(displayListIter);
|
|
|
|
if (gTitleZoomCounter >= 0x13) {
|
|
|
|
gTitleFadeCounter += 0x1a;
|
|
|
|
if (gTitleFadeCounter >= 0x100) {
|
|
|
|
gTitleFadeCounter = 0xFF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return displayList;
|
|
|
|
}
|
|
|
|
|
2020-02-03 05:51:26 +00:00
|
|
|
Gfx *intro_backdrop_one_image(s32 index, s8 *backgroundTable) {
|
2019-11-03 19:36:27 +00:00
|
|
|
Mtx *mtx; // sp5c
|
|
|
|
Gfx *displayList; // sp58
|
|
|
|
Gfx *displayListIter; // sp54
|
|
|
|
const u8 *const *vIntroBgTable; // sp50
|
|
|
|
s32 i; // sp4c
|
2020-05-07 18:21:22 +00:00
|
|
|
f32 aspect = GFX_DIMENSIONS_ASPECT_RATIO;
|
|
|
|
int num_tiles_h = (((aspect*SCREEN_HEIGHT)+79)/80);
|
|
|
|
float x_ofs = (SCREEN_WIDTH/2)-(aspect*SCREEN_HEIGHT/2);
|
|
|
|
|
2019-08-25 04:46:40 +00:00
|
|
|
mtx = alloc_display_list(sizeof(*mtx));
|
|
|
|
displayList = alloc_display_list(36 * sizeof(*displayList));
|
|
|
|
displayListIter = displayList;
|
2020-05-07 18:21:22 +00:00
|
|
|
vIntroBgTable = segmented_to_virtual(introBackgroundTextureType[backgroundTable[0]]);
|
|
|
|
guTranslate(mtx, ((index%num_tiles_h)*80)+x_ofs, (index/num_tiles_h)*80, 0.0f);
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPMatrix(displayListIter++, mtx, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_PUSH);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(displayListIter++, &title_screen_bg_dl_0A000118);
|
|
|
|
for (i = 0; i < 4; ++i) {
|
2019-11-03 19:36:27 +00:00
|
|
|
gDPLoadTextureBlock(displayListIter++, vIntroBgTable[i], G_IM_FMT_RGBA, G_IM_SIZ_16b, 80, 20, 0,
|
|
|
|
G_TX_CLAMP, G_TX_CLAMP, 7, 6, G_TX_NOLOD, G_TX_NOLOD)
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(displayListIter++, introBackgroundDlRows[i]);
|
|
|
|
}
|
|
|
|
gSPPopMatrix(displayListIter++, G_MTX_MODELVIEW);
|
|
|
|
gSPEndDisplayList(displayListIter);
|
|
|
|
return displayList;
|
|
|
|
}
|
|
|
|
|
2020-04-03 18:57:26 +00:00
|
|
|
Gfx *geo_intro_backdrop(s32 sp48, struct GraphNode *sp4c, UNUSED void *context) {
|
2019-08-25 04:46:40 +00:00
|
|
|
struct GraphNodeMore *graphNode; // sp44
|
|
|
|
s32 index; // sp40
|
|
|
|
s8 *backgroundTable; // sp3c
|
|
|
|
Gfx *displayList; // sp38
|
|
|
|
Gfx *displayListIter; // sp34
|
|
|
|
s32 i; // sp30
|
|
|
|
graphNode = (struct GraphNodeMore *) sp4c;
|
|
|
|
index = graphNode->unk18 & 0xff; // TODO: word at offset 0x18 of struct GraphNode
|
|
|
|
backgroundTable = introBackgroundTables[index];
|
|
|
|
displayList = NULL;
|
|
|
|
displayListIter = NULL;
|
2020-05-07 18:21:22 +00:00
|
|
|
f32 aspect = GFX_DIMENSIONS_ASPECT_RATIO;
|
|
|
|
int num_tiles_h = (((aspect*SCREEN_HEIGHT)+79)/80);
|
|
|
|
|
2019-08-25 04:46:40 +00:00
|
|
|
if (sp48 == 1) {
|
2020-05-07 18:21:22 +00:00
|
|
|
displayList = alloc_display_list(((num_tiles_h*3)+4) * sizeof(*displayList));
|
2019-08-25 04:46:40 +00:00
|
|
|
displayListIter = displayList;
|
|
|
|
graphNode->node.flags = (graphNode->node.flags & 0xFF) | 0x100;
|
|
|
|
gSPDisplayList(displayListIter++, &dl_proj_mtx_fullscreen);
|
|
|
|
gSPDisplayList(displayListIter++, &title_screen_bg_dl_0A000100);
|
2020-05-07 18:21:22 +00:00
|
|
|
for (i = 0; i < num_tiles_h*3; ++i) {
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(displayListIter++, intro_backdrop_one_image(i, backgroundTable));
|
|
|
|
}
|
|
|
|
gSPDisplayList(displayListIter++, &title_screen_bg_dl_0A000190);
|
|
|
|
gSPEndDisplayList(displayListIter);
|
|
|
|
}
|
|
|
|
return displayList;
|
|
|
|
}
|
|
|
|
|
2020-04-03 18:57:26 +00:00
|
|
|
Gfx *geo_game_over_tile(s32 sp40, struct GraphNode *sp44, UNUSED void *context) {
|
2019-08-25 04:46:40 +00:00
|
|
|
struct GraphNode *graphNode; // sp3c
|
|
|
|
Gfx *displayList; // sp38
|
|
|
|
Gfx *displayListIter; // sp34
|
|
|
|
s32 j; // sp30
|
|
|
|
s32 i; // sp2c
|
|
|
|
graphNode = sp44;
|
|
|
|
displayList = NULL;
|
|
|
|
displayListIter = NULL;
|
2020-05-07 18:21:22 +00:00
|
|
|
f32 aspect = GFX_DIMENSIONS_ASPECT_RATIO;
|
|
|
|
int num_tiles_h = (((aspect*SCREEN_HEIGHT)+79)/80);
|
|
|
|
|
2019-08-25 04:46:40 +00:00
|
|
|
if (sp40 != 1) {
|
|
|
|
gGameOverFrameCounter = 0;
|
|
|
|
gGameOverTableIndex = -2;
|
|
|
|
for (i = 0; i < (s32) sizeof(gameOverBackgroundTable); ++i) {
|
|
|
|
gameOverBackgroundTable[i] = INTRO_BACKGROUND_GAME_OVER;
|
|
|
|
}
|
|
|
|
} else {
|
2020-05-07 18:21:22 +00:00
|
|
|
displayList = alloc_display_list(((num_tiles_h*3)+4) * sizeof(*displayList));
|
2019-08-25 04:46:40 +00:00
|
|
|
displayListIter = displayList;
|
|
|
|
if (gGameOverTableIndex == -2) {
|
|
|
|
if (gGameOverFrameCounter == 180) {
|
|
|
|
gGameOverTableIndex++;
|
|
|
|
gGameOverFrameCounter = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// transition tile from "Game Over" to "Super Mario 64"
|
|
|
|
if (gGameOverTableIndex != 11 && !(gGameOverFrameCounter & 0x1)) {
|
|
|
|
gGameOverTableIndex++;
|
|
|
|
gameOverBackgroundTable[gameOverBackgroundFlipOrder[gGameOverTableIndex]] =
|
|
|
|
INTRO_BACKGROUND_SUPER_MARIO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (gGameOverTableIndex != 11) {
|
|
|
|
gGameOverFrameCounter++;
|
|
|
|
}
|
|
|
|
graphNode->flags = (graphNode->flags & 0xFF) | 0x100;
|
|
|
|
gSPDisplayList(displayListIter++, &dl_proj_mtx_fullscreen);
|
|
|
|
gSPDisplayList(displayListIter++, &title_screen_bg_dl_0A000100);
|
2020-05-07 18:21:22 +00:00
|
|
|
for (j = 0; j < (s32) num_tiles_h*3; ++j) {
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(displayListIter++, intro_backdrop_one_image(j, gameOverBackgroundTable));
|
|
|
|
}
|
|
|
|
gSPDisplayList(displayListIter++, &title_screen_bg_dl_0A000190);
|
|
|
|
gSPEndDisplayList(displayListIter);
|
|
|
|
}
|
|
|
|
return displayList;
|
|
|
|
}
|