2019-08-25 04:46:40 +00:00
|
|
|
#include <ultra64.h>
|
|
|
|
|
|
|
|
#include "sm64.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "types.h"
|
|
|
|
#include "audio/external.h"
|
|
|
|
#include "seq_ids.h"
|
2019-12-02 02:52:53 +00:00
|
|
|
#include "dialog_ids.h"
|
2019-08-25 04:46:40 +00:00
|
|
|
#include "game.h"
|
|
|
|
#include "save_file.h"
|
|
|
|
#include "level_update.h"
|
|
|
|
#include "camera.h"
|
|
|
|
#include "text_strings.h"
|
|
|
|
#include "segment2.h"
|
|
|
|
#include "segment7.h"
|
|
|
|
#include "eu_translation.h"
|
|
|
|
#include "ingame_menu.h"
|
2019-10-05 19:08:05 +00:00
|
|
|
#include "print.h"
|
2019-08-25 04:46:40 +00:00
|
|
|
#include "engine/math_util.h"
|
|
|
|
|
|
|
|
extern Gfx *gDisplayListHead;
|
|
|
|
extern s32 gGlobalTimer;
|
|
|
|
extern s16 gCurrCourseNum;
|
|
|
|
extern s16 gCurrSaveFileNum;
|
|
|
|
|
|
|
|
extern Gfx coin_seg3_dl_03007940[];
|
|
|
|
extern Gfx coin_seg3_dl_03007968[];
|
|
|
|
extern Gfx coin_seg3_dl_03007990[];
|
|
|
|
extern Gfx coin_seg3_dl_030079B8[];
|
|
|
|
|
|
|
|
extern u8 main_menu_seg7_table_0700ABD0[];
|
|
|
|
extern Gfx castle_grounds_seg7_dl_0700EA58[];
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
u16 gDialogColorFadeTimer;
|
2019-08-25 04:46:40 +00:00
|
|
|
s8 gLastDialogLineNum;
|
|
|
|
s32 gDialogVariable;
|
2019-10-05 19:08:05 +00:00
|
|
|
u16 gDialogTextAlpha;
|
2020-03-02 03:42:52 +00:00
|
|
|
#if defined(VERSION_EU)
|
2020-02-03 05:51:26 +00:00
|
|
|
s16 gDialogX; // D_8032F69A
|
|
|
|
s16 gDialogY; // D_8032F69C
|
|
|
|
#endif
|
2019-08-25 04:46:40 +00:00
|
|
|
s16 gCutsceneMsgXOffset;
|
|
|
|
s16 gCutsceneMsgYOffset;
|
2019-10-05 19:08:05 +00:00
|
|
|
s8 gRedCoinsCollected;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
extern u8 gLastCompletedCourseNum;
|
|
|
|
extern u8 gLastCompletedStarNum;
|
|
|
|
|
|
|
|
enum DialogBoxState {
|
|
|
|
DIALOG_STATE_OPENING,
|
2019-10-05 19:08:05 +00:00
|
|
|
DIALOG_STATE_VERTICAL,
|
|
|
|
DIALOG_STATE_HORIZONTAL,
|
2019-08-25 04:46:40 +00:00
|
|
|
DIALOG_STATE_CLOSING
|
|
|
|
};
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
enum DialogBoxPageState {
|
|
|
|
DIALOG_PAGE_STATE_NONE,
|
|
|
|
DIALOG_PAGE_STATE_SCROLL,
|
|
|
|
DIALOG_PAGE_STATE_END
|
|
|
|
};
|
|
|
|
|
2019-08-25 04:46:40 +00:00
|
|
|
enum DialogBoxType {
|
|
|
|
DIALOG_TYPE_ROTATE, // used in NPCs and level messages
|
|
|
|
DIALOG_TYPE_ZOOM // used in signposts and wall signs and etc
|
|
|
|
};
|
|
|
|
|
|
|
|
enum DialogMark { DIALOG_MARK_NONE = 0, DIALOG_MARK_DAKUTEN = 1, DIALOG_MARK_HANDAKUTEN = 2 };
|
|
|
|
|
|
|
|
#define DEFAULT_DIALOG_BOX_ANGLE 90.0f
|
|
|
|
#define DEFAULT_DIALOG_BOX_SCALE 19.0f
|
|
|
|
|
|
|
|
#ifndef VERSION_JP
|
|
|
|
u8 gDialogCharWidths[256] = { // TODO: Is there a way to auto generate this?
|
2019-09-01 19:50:50 +00:00
|
|
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6,
|
|
|
|
6, 6, 5, 6, 6, 5, 8, 8, 6, 6, 6, 6, 6, 5, 6, 6,
|
|
|
|
8, 7, 6, 6, 6, 5, 5, 6, 5, 5, 6, 5, 4, 5, 5, 3,
|
|
|
|
7, 5, 5, 5, 6, 5, 5, 5, 5, 5, 7, 7, 5, 5, 4, 4,
|
|
|
|
8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
8, 8, 8, 8, 7, 7, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
6, 6, 6, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 4,
|
|
|
|
5, 5, 5, 5, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
5, 5, 5, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 5, 5, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 5, 6,
|
|
|
|
0, 4, 4, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
#else
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
#endif
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
7, 5, 10, 5, 9, 8, 4, 0, 0, 0, 0, 5, 5, 6, 5, 0,
|
|
|
|
#else
|
|
|
|
7, 5, 10, 5, 9, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
#endif
|
|
|
|
0, 0, 5, 7, 7, 6, 6, 8, 0, 8, 10, 6, 4, 10, 0, 0
|
2019-08-25 04:46:40 +00:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
s8 gDialogBoxState = DIALOG_STATE_OPENING;
|
|
|
|
f32 gDialogBoxOpenTimer = DEFAULT_DIALOG_BOX_ANGLE;
|
|
|
|
f32 gDialogBoxScale = DEFAULT_DIALOG_BOX_SCALE;
|
|
|
|
s16 gDialogScrollOffsetY = 0;
|
|
|
|
s8 gDialogBoxType = DIALOG_TYPE_ROTATE;
|
|
|
|
s16 gDialogID = -1;
|
|
|
|
s16 gLastDialogPageStrPos = 0;
|
2019-10-05 19:08:05 +00:00
|
|
|
s16 gDialogTextPos = 0; // EU: D_802FD64C
|
2020-02-03 05:51:26 +00:00
|
|
|
#ifdef VERSION_EU
|
|
|
|
s32 gInGameLanguage = 0;
|
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
s8 gDialogLineNum = 1;
|
|
|
|
s8 gLastDialogResponse = 0;
|
|
|
|
u8 gMenuHoldKeyIndex = 0;
|
|
|
|
u8 gMenuHoldKeyTimer = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
s32 gDialogResponse = 0;
|
|
|
|
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void create_dl_identity_matrix(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
Mtx *matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (matrix == NULL) {
|
2019-08-25 04:46:40 +00:00
|
|
|
return;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2020-02-03 05:51:26 +00:00
|
|
|
matrix->m[0][0] = 0x00010000; matrix->m[1][0] = 0x00000000; matrix->m[2][0] = 0x00000000; matrix->m[3][0] = 0x00000000;
|
|
|
|
matrix->m[0][1] = 0x00000000; matrix->m[1][1] = 0x00010000; matrix->m[2][1] = 0x00000000; matrix->m[3][1] = 0x00000000;
|
|
|
|
matrix->m[0][2] = 0x00000001; matrix->m[1][2] = 0x00000000; matrix->m[2][2] = 0x00000000; matrix->m[3][2] = 0x00000000;
|
|
|
|
matrix->m[0][3] = 0x00000000; matrix->m[1][3] = 0x00000001; matrix->m[2][3] = 0x00000000; matrix->m[3][3] = 0x00000000;
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
|
|
|
|
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void create_dl_translation_matrix(s8 pushOp, f32 x, f32 y, f32 z) {
|
2019-08-25 04:46:40 +00:00
|
|
|
Mtx *matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (matrix == NULL) {
|
2019-08-25 04:46:40 +00:00
|
|
|
return;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
guTranslate(matrix, x, y, z);
|
|
|
|
|
|
|
|
if (pushOp == MENU_MTX_PUSH)
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (pushOp == MENU_MTX_NOPUSH)
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void create_dl_rotation_matrix(s8 pushOp, f32 a, f32 x, f32 y, f32 z) {
|
2019-08-25 04:46:40 +00:00
|
|
|
Mtx *matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (matrix == NULL) {
|
2019-08-25 04:46:40 +00:00
|
|
|
return;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
guRotate(matrix, a, x, y, z);
|
|
|
|
|
|
|
|
if (pushOp == MENU_MTX_PUSH)
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (pushOp == MENU_MTX_NOPUSH)
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void create_dl_scale_matrix(s8 pushOp, f32 x, f32 y, f32 z) {
|
2019-08-25 04:46:40 +00:00
|
|
|
Mtx *matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (matrix == NULL) {
|
2019-08-25 04:46:40 +00:00
|
|
|
return;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
guScale(matrix, x, y, z);
|
|
|
|
|
|
|
|
if (pushOp == MENU_MTX_PUSH)
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (pushOp == MENU_MTX_NOPUSH)
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void create_dl_ortho_matrix(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
Mtx *matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (matrix == NULL) {
|
2019-08-25 04:46:40 +00:00
|
|
|
return;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_identity_matrix();
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
guOrtho(matrix, 0.0f, SCREEN_WIDTH, 0.0f, SCREEN_HEIGHT, -10.0f, 10.0f, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
// Should produce G_RDPHALF_1 in Fast3D
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPPerspNormalize((Gfx *) (gDisplayListHead++), 0xFFFF);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_PROJECTION | G_MTX_MUL | G_MTX_NOPUSH)
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
static u8 *alloc_ia8_text_from_i1(u16 *in, s16 width, s16 height) {
|
2019-08-25 04:46:40 +00:00
|
|
|
s32 inPos;
|
|
|
|
u16 bitMask;
|
|
|
|
u8 *out;
|
|
|
|
s16 outPos;
|
|
|
|
|
|
|
|
outPos = 0;
|
|
|
|
out = alloc_display_list(width * height);
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (out == NULL) {
|
2019-08-25 04:46:40 +00:00
|
|
|
return NULL;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
for (inPos = 0; inPos < (width * height) / 16; inPos++) {
|
|
|
|
bitMask = 0x8000;
|
|
|
|
|
|
|
|
while (bitMask != 0) {
|
2019-09-01 19:50:50 +00:00
|
|
|
if (in[inPos] & bitMask) {
|
2019-08-25 04:46:40 +00:00
|
|
|
out[outPos] = 0xFF;
|
2019-09-01 19:50:50 +00:00
|
|
|
} else {
|
2019-08-25 04:46:40 +00:00
|
|
|
out[outPos] = 0x00;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
bitMask /= 2;
|
|
|
|
outPos++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
void render_generic_char(u8 c) {
|
2019-10-05 19:08:05 +00:00
|
|
|
void **fontLUT;
|
2019-08-25 04:46:40 +00:00
|
|
|
void *packedTexture;
|
|
|
|
#ifdef VERSION_JP
|
|
|
|
void *unpackedTexture;
|
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
fontLUT = segmented_to_virtual(main_font_lut);
|
|
|
|
packedTexture = segmented_to_virtual(fontLUT[c]);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
#ifdef VERSION_JP
|
2019-10-05 19:08:05 +00:00
|
|
|
unpackedTexture = alloc_ia8_text_from_i1(packedTexture, 8, 16);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
gDPPipeSync(gDisplayListHead++);
|
2019-09-01 19:50:50 +00:00
|
|
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, VIRTUAL_TO_PHYSICAL(unpackedTexture));
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
|
|
|
#ifdef VERSION_US
|
|
|
|
gDPPipeSync(gDisplayListHead++);
|
|
|
|
#endif
|
2019-09-01 19:50:50 +00:00
|
|
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, VIRTUAL_TO_PHYSICAL(packedTexture));
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings);
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
|
|
|
gSPTextureRectangleFlip(gDisplayListHead++, gDialogX << 2, (gDialogY - 16) << 2,
|
2019-10-05 19:08:05 +00:00
|
|
|
(gDialogX + 8) << 2, gDialogY << 2, G_TX_RENDERTILE, 16 << 5, 8 << 5, 1 << 10, 1 << 10);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
u8 *alloc_ia4_tex_from_i1(u8 *in, s16 width, s16 height) {
|
|
|
|
u32 size = (u32) width * (u32) height;
|
|
|
|
u8 *out;
|
|
|
|
s32 inPos;
|
|
|
|
s16 outPos;
|
|
|
|
u8 bitMask;
|
|
|
|
|
|
|
|
outPos = 0;
|
|
|
|
out = (u8 *) alloc_display_list(size);
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (out == NULL) {
|
2019-08-25 04:46:40 +00:00
|
|
|
return NULL;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
for (inPos = 0; inPos < (width * height) / 4; inPos++) {
|
|
|
|
bitMask = 0x80;
|
|
|
|
while (bitMask != 0) {
|
|
|
|
out[outPos] = (in[inPos] & bitMask) ? 0xF0 : 0x00;
|
|
|
|
bitMask /= 2;
|
|
|
|
out[outPos] = (in[inPos] & bitMask) ? out[outPos] + 0x0F : out[outPos];
|
|
|
|
bitMask /= 2;
|
|
|
|
outPos++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
void render_generic_char_at_pos(s16 xPos, s16 yPos, u8 c) {
|
2019-10-05 19:08:05 +00:00
|
|
|
void **fontLUT;
|
2019-08-25 04:46:40 +00:00
|
|
|
void *packedTexture;
|
|
|
|
void *unpackedTexture;
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
fontLUT = segmented_to_virtual(main_font_lut);
|
|
|
|
packedTexture = segmented_to_virtual(fontLUT[c]);
|
2019-08-25 04:46:40 +00:00
|
|
|
unpackedTexture = alloc_ia4_tex_from_i1(packedTexture, 8, 8);
|
|
|
|
|
|
|
|
gDPPipeSync(gDisplayListHead++);
|
2019-09-01 19:50:50 +00:00
|
|
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, VIRTUAL_TO_PHYSICAL(unpackedTexture));
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPTextureRectangleFlip(gDisplayListHead++, xPos << 2, (yPos - 16) << 2, (xPos + 8) << 2, yPos << 2,
|
2019-10-05 19:08:05 +00:00
|
|
|
G_TX_RENDERTILE, 16 << 5, 8 << 5, 1 << 10, 1 << 10);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void render_lowercase_diacritic(s16 *xPos, s16 *yPos, u8 letter, u8 diacritic) {
|
|
|
|
render_generic_char_at_pos(*xPos, *yPos, letter);
|
|
|
|
render_generic_char_at_pos(*xPos, *yPos, diacritic + 0xE7);
|
|
|
|
*xPos += gDialogCharWidths[letter];
|
|
|
|
}
|
|
|
|
|
|
|
|
void render_uppercase_diacritic(s16 *xPos, s16 *yPos, u8 letter, u8 diacritic) {
|
|
|
|
render_generic_char_at_pos(*xPos, *yPos, letter);
|
|
|
|
render_generic_char_at_pos(*xPos, *yPos - 4, diacritic + 0xE3);
|
|
|
|
*xPos += gDialogCharWidths[letter];
|
|
|
|
}
|
|
|
|
#endif // VERSION_EU
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
#if !defined(VERSION_JP) && !defined(VERSION_SH)
|
2019-08-25 04:46:40 +00:00
|
|
|
struct MultiTextEntry {
|
|
|
|
u8 length;
|
|
|
|
u8 str[4];
|
|
|
|
};
|
|
|
|
|
|
|
|
#define TEXT_THE_RAW ASCII_TO_DIALOG('t'), ASCII_TO_DIALOG('h'), ASCII_TO_DIALOG('e'), 0x00
|
|
|
|
#define TEXT_YOU_RAW ASCII_TO_DIALOG('y'), ASCII_TO_DIALOG('o'), ASCII_TO_DIALOG('u'), 0x00
|
|
|
|
|
2019-12-02 02:52:53 +00:00
|
|
|
enum MultiStringIDs { STRING_THE, STRING_YOU };
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Place the multi-text string according to the ID passed. (US, EU)
|
|
|
|
* 0: 'the'
|
|
|
|
* 1: 'you'
|
|
|
|
*/
|
|
|
|
#ifdef VERSION_US
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_multi_text_string(s8 multiTextID) // US: 802D76C8
|
2019-08-25 04:46:40 +00:00
|
|
|
#elif defined(VERSION_EU)
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_multi_text_string(s16 *xPos, s16 *yPos, s8 multiTextID) // EU: 802AD650
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
{
|
|
|
|
s8 i;
|
|
|
|
struct MultiTextEntry textLengths[2] = {
|
|
|
|
{ 3, { TEXT_THE_RAW } },
|
|
|
|
{ 3, { TEXT_YOU_RAW } },
|
|
|
|
};
|
|
|
|
|
|
|
|
for (i = 0; i < textLengths[multiTextID].length; i++) {
|
|
|
|
#ifdef VERSION_US
|
|
|
|
render_generic_char(textLengths[multiTextID].str[i]);
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, (f32)(gDialogCharWidths[textLengths[multiTextID].str[i]]), 0.0f, 0.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
#elif defined(VERSION_EU)
|
|
|
|
render_generic_char_at_pos(*xPos, *yPos, textLengths[multiTextID].str[i]);
|
|
|
|
*xPos += gDialogCharWidths[textLengths[multiTextID].str[i]];
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
#if defined(VERSION_JP) || defined(VERSION_SH)
|
2019-10-05 19:08:05 +00:00
|
|
|
#define MAX_STRING_WIDTH 18
|
|
|
|
#else
|
|
|
|
#define MAX_STRING_WIDTH 16
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Prints a generic white string.
|
|
|
|
* In JP/EU a IA1 texture is used but in US a IA4 texture is used.
|
|
|
|
*/
|
|
|
|
void print_generic_string(s16 x, s16 y, const u8 *str) {
|
2019-08-25 04:46:40 +00:00
|
|
|
UNUSED s8 mark = DIALOG_MARK_NONE; // unused in EU
|
|
|
|
s32 strPos = 0;
|
|
|
|
u8 lineNum = 1;
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
s16 xCoord = x;
|
|
|
|
s16 yCoord = 240 - y;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, x, y, 0.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
while (str[strPos] != DIALOG_CHAR_TERMINATOR) {
|
|
|
|
switch (str[strPos]) {
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
case DIALOG_CHAR_SPACE:
|
|
|
|
xCoord += 5;
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_NEWLINE:
|
|
|
|
yCoord += 16;
|
|
|
|
xCoord = x;
|
|
|
|
lineNum++;
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_LOWER_A_GRAVE:
|
|
|
|
case DIALOG_CHAR_LOWER_A_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_LOWER_A_UMLAUT:
|
|
|
|
render_lowercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('a'), str[strPos] & 0xF);
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_UPPER_A_UMLAUT: // @bug grave and circumflux (0x64-0x65) are absent here
|
|
|
|
render_uppercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('A'), str[strPos] & 0xF);
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_LOWER_E_GRAVE:
|
|
|
|
case DIALOG_CHAR_LOWER_E_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_LOWER_E_UMLAUT:
|
|
|
|
case DIALOG_CHAR_LOWER_E_ACUTE:
|
|
|
|
render_lowercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('e'), str[strPos] & 0xF);
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_UPPER_E_GRAVE:
|
|
|
|
case DIALOG_CHAR_UPPER_E_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_UPPER_E_UMLAUT:
|
|
|
|
case DIALOG_CHAR_UPPER_E_ACUTE:
|
|
|
|
render_uppercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('E'), str[strPos] & 0xF);
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_LOWER_U_GRAVE:
|
|
|
|
case DIALOG_CHAR_LOWER_U_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_LOWER_U_UMLAUT:
|
|
|
|
render_lowercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('u'), str[strPos] & 0xF);
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_UPPER_U_UMLAUT: // @bug grave and circumflex (0x84-0x85) are absent here
|
|
|
|
render_uppercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('U'), str[strPos] & 0xF);
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_LOWER_O_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_LOWER_O_UMLAUT:
|
|
|
|
render_lowercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('o'), str[strPos] & 0xF);
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_UPPER_O_UMLAUT: // @bug circumflex (0x95) is absent here
|
|
|
|
render_uppercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('O'), str[strPos] & 0xF);
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_LOWER_I_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_LOWER_I_UMLAUT:
|
|
|
|
render_lowercase_diacritic(&xCoord, &yCoord, DIALOG_CHAR_I_NO_DIA, str[strPos] & 0xF);
|
|
|
|
break;
|
|
|
|
#else // i.e. not EU
|
2020-01-03 15:38:57 +00:00
|
|
|
case DIALOG_CHAR_DAKUTEN:
|
2019-08-25 04:46:40 +00:00
|
|
|
mark = DIALOG_MARK_DAKUTEN;
|
|
|
|
break;
|
2020-01-03 15:38:57 +00:00
|
|
|
case DIALOG_CHAR_PERIOD_OR_HANDAKUTEN:
|
2019-08-25 04:46:40 +00:00
|
|
|
mark = DIALOG_MARK_HANDAKUTEN;
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_NEWLINE:
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, x, y - (lineNum * MAX_STRING_WIDTH), 0.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
lineNum++;
|
|
|
|
break;
|
2020-01-03 15:38:57 +00:00
|
|
|
case DIALOG_CHAR_PERIOD:
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, -2.0f, -5.0f, 0.0f);
|
2020-01-03 15:38:57 +00:00
|
|
|
render_generic_char(DIALOG_CHAR_PERIOD_OR_HANDAKUTEN);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
break;
|
|
|
|
#endif
|
2020-03-02 03:42:52 +00:00
|
|
|
#if !defined(VERSION_JP) && !defined(VERSION_SH)
|
2019-10-05 19:08:05 +00:00
|
|
|
case DIALOG_CHAR_SLASH:
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_US
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, (f32)(gDialogCharWidths[DIALOG_CHAR_SPACE] * 2), 0.0f, 0.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
#elif defined(VERSION_EU)
|
|
|
|
xCoord += gDialogCharWidths[DIALOG_CHAR_SPACE] * 2;
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_MULTI_THE:
|
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
render_multi_text_string(&xCoord, &yCoord, STRING_THE);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
render_multi_text_string(STRING_THE);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_MULTI_YOU:
|
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
render_multi_text_string(&xCoord, &yCoord, STRING_YOU);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
render_multi_text_string(STRING_YOU);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#ifndef VERSION_EU
|
|
|
|
case DIALOG_CHAR_SPACE:
|
|
|
|
#ifdef VERSION_JP
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, 5.0f, 0.0f, 0.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, (f32)(gDialogCharWidths[DIALOG_CHAR_SPACE]), 0.0f, 0.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
break; // ? needed to match
|
|
|
|
default:
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
render_generic_char_at_pos(xCoord, yCoord, str[strPos]);
|
|
|
|
xCoord += gDialogCharWidths[str[strPos]];
|
|
|
|
break;
|
|
|
|
#else
|
|
|
|
render_generic_char(str[strPos]);
|
|
|
|
if (mark != DIALOG_MARK_NONE) {
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, 5.0f, 5.0f, 0.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
render_generic_char(mark + 0xEF);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
mark = DIALOG_MARK_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VERSION_JP
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, 10.0f, 0.0f, 0.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, (f32)(gDialogCharWidths[str[strPos]]), 0.0f, 0.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
break; // what an odd difference. US added a useless break here.
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
strPos++;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef VERSION_EU
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
void print_hud_char_umlaut(s16 x, s16 y, u8 chr) {
|
|
|
|
void **fontLUT = segmented_to_virtual(main_hud_lut);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
gDPPipeSync(gDisplayListHead++);
|
|
|
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, fontLUT[chr]);
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_load_tex_block);
|
2019-10-05 19:08:05 +00:00
|
|
|
gSPTextureRectangle(gDisplayListHead++, x << 2, y << 2, (x + 16) << 2, (y + 16) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, fontLUT[GLYPH_UMLAUT]);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_load_tex_block);
|
2019-10-05 19:08:05 +00:00
|
|
|
gSPTextureRectangle(gDisplayListHead++, x << 2, (y - 4) << 2, (x + 16) << 2, (y + 12) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
/**
|
|
|
|
* Prints a hud string depending of the hud table list defined.
|
|
|
|
*/
|
|
|
|
void print_hud_lut_string(s8 hudLUT, s16 x, s16 y, const u8 *str) {
|
2019-08-25 04:46:40 +00:00
|
|
|
s32 strPos = 0;
|
2019-10-05 19:08:05 +00:00
|
|
|
void **hudLUT1 = segmented_to_virtual(menu_hud_lut); // Japanese Menu HUD Color font
|
|
|
|
void **hudLUT2 = segmented_to_virtual(main_hud_lut); // 0-9 A-Z HUD Color Font
|
2019-08-25 04:46:40 +00:00
|
|
|
u32 curX = x;
|
|
|
|
u32 curY = y;
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
u32 xStride; // X separation
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (hudLUT == HUD_LUT_JPMENU) {
|
2019-08-25 04:46:40 +00:00
|
|
|
xStride = 16;
|
2019-10-05 19:08:05 +00:00
|
|
|
} else { // HUD_LUT_GLOBAL
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_JP
|
|
|
|
xStride = 14;
|
|
|
|
#else
|
|
|
|
xStride = 12;
|
|
|
|
#endif
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
while (str[strPos] != GLOBAR_CHAR_TERMINATOR) {
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
|
|
|
switch (str[strPos]) {
|
2019-10-05 19:08:05 +00:00
|
|
|
case GLOBAL_CHAR_SPACE:
|
2019-08-25 04:46:40 +00:00
|
|
|
curX += xStride / 2;
|
|
|
|
break;
|
|
|
|
case HUD_CHAR_A_UMLAUT:
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_char_umlaut(curX, curY, ASCII_TO_DIALOG('A'));
|
2019-08-25 04:46:40 +00:00
|
|
|
curX += xStride;
|
|
|
|
break;
|
|
|
|
case HUD_CHAR_O_UMLAUT:
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_char_umlaut(curX, curY, ASCII_TO_DIALOG('O'));
|
2019-08-25 04:46:40 +00:00
|
|
|
curX += xStride;
|
|
|
|
break;
|
|
|
|
case HUD_CHAR_U_UMLAUT:
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_char_umlaut(curX, curY, ASCII_TO_DIALOG('U'));
|
2019-08-25 04:46:40 +00:00
|
|
|
curX += xStride;
|
|
|
|
break;
|
|
|
|
default:
|
2019-09-01 19:50:50 +00:00
|
|
|
#endif
|
|
|
|
#ifdef VERSION_US
|
2019-10-05 19:08:05 +00:00
|
|
|
if (str[strPos] == GLOBAL_CHAR_SPACE) {
|
2019-08-25 04:46:40 +00:00
|
|
|
if (0) //! dead code
|
|
|
|
{
|
|
|
|
}
|
|
|
|
curX += 8;
|
|
|
|
; //! useless statement
|
|
|
|
} else {
|
|
|
|
#endif
|
2019-09-01 19:50:50 +00:00
|
|
|
gDPPipeSync(gDisplayListHead++);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (hudLUT == HUD_LUT_JPMENU)
|
|
|
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, hudLUT1[str[strPos]]);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (hudLUT == HUD_LUT_GLOBAL)
|
|
|
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, hudLUT2[str[strPos]]);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_load_tex_block);
|
|
|
|
gSPTextureRectangle(gDisplayListHead++, curX << 2, curY << 2, (curX + 16) << 2,
|
2019-10-05 19:08:05 +00:00
|
|
|
(curY + 16) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
curX += xStride;
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef VERSION_US
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
strPos++;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
void print_menu_char_umlaut(s16 x, s16 y, u8 chr) {
|
|
|
|
void **fontLUT = segmented_to_virtual(menu_font_lut);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, fontLUT[chr]);
|
|
|
|
gDPLoadSync(gDisplayListHead++);
|
2019-11-03 19:36:27 +00:00
|
|
|
gDPLoadBlock(gDisplayListHead++, G_TX_LOADTILE, 0, 0, 8 * 8 - 1, CALC_DXT(8, G_IM_SIZ_8b_BYTES));
|
2019-10-05 19:08:05 +00:00
|
|
|
gSPTextureRectangle(gDisplayListHead++, x << 2, y << 2, (x + 8) << 2, (y + 8) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, fontLUT[DIALOG_CHAR_UMLAUT]);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDPLoadSync(gDisplayListHead++);
|
2019-11-03 19:36:27 +00:00
|
|
|
gDPLoadBlock(gDisplayListHead++, G_TX_LOADTILE, 0, 0, 8 * 8 - 1, CALC_DXT(8, G_IM_SIZ_8b_BYTES));
|
2019-10-05 19:08:05 +00:00
|
|
|
gSPTextureRectangle(gDisplayListHead++, x << 2, (y - 4) << 2, (x + 8) << 2, (y + 4) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void print_menu_generic_string(s16 x, s16 y, const u8 *str) {
|
2019-08-25 04:46:40 +00:00
|
|
|
UNUSED s8 mark = DIALOG_MARK_NONE; // unused in EU
|
|
|
|
s32 strPos = 0;
|
|
|
|
s32 curX = x;
|
|
|
|
s32 curY = y;
|
2019-10-05 19:08:05 +00:00
|
|
|
void **fontLUT = segmented_to_virtual(menu_font_lut);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
while (str[strPos] != DIALOG_CHAR_TERMINATOR) {
|
|
|
|
switch (str[strPos]) {
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
case DIALOG_CHAR_UPPER_A_UMLAUT:
|
2019-10-05 19:08:05 +00:00
|
|
|
print_menu_char_umlaut(curX, curY, ASCII_TO_DIALOG('A'));
|
2019-08-25 04:46:40 +00:00
|
|
|
curX += gDialogCharWidths[str[strPos]];
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_UPPER_U_UMLAUT:
|
2019-10-05 19:08:05 +00:00
|
|
|
print_menu_char_umlaut(curX, curY, ASCII_TO_DIALOG('U'));
|
2019-08-25 04:46:40 +00:00
|
|
|
curX += gDialogCharWidths[str[strPos]];
|
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_UPPER_O_UMLAUT:
|
2019-10-05 19:08:05 +00:00
|
|
|
print_menu_char_umlaut(curX, curY, ASCII_TO_DIALOG('O'));
|
2019-08-25 04:46:40 +00:00
|
|
|
curX += gDialogCharWidths[str[strPos]];
|
|
|
|
break;
|
|
|
|
#else
|
2020-01-03 15:38:57 +00:00
|
|
|
case DIALOG_CHAR_DAKUTEN:
|
2019-09-01 19:50:50 +00:00
|
|
|
mark = DIALOG_MARK_DAKUTEN;
|
|
|
|
break;
|
2020-01-03 15:38:57 +00:00
|
|
|
case DIALOG_CHAR_PERIOD_OR_HANDAKUTEN:
|
2019-09-01 19:50:50 +00:00
|
|
|
mark = DIALOG_MARK_HANDAKUTEN;
|
|
|
|
break;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
case DIALOG_CHAR_SPACE:
|
2019-08-25 04:46:40 +00:00
|
|
|
curX += 4;
|
|
|
|
break;
|
|
|
|
default:
|
2019-09-01 19:50:50 +00:00
|
|
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, fontLUT[str[strPos]]);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDPLoadSync(gDisplayListHead++);
|
2019-11-03 19:36:27 +00:00
|
|
|
gDPLoadBlock(gDisplayListHead++, G_TX_LOADTILE, 0, 0, 8 * 8 - 1, CALC_DXT(8, G_IM_SIZ_8b_BYTES));
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPTextureRectangle(gDisplayListHead++, curX << 2, curY << 2, (curX + 8) << 2,
|
2019-10-05 19:08:05 +00:00
|
|
|
(curY + 8) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
#ifndef VERSION_EU
|
|
|
|
if (mark != DIALOG_MARK_NONE) {
|
2019-09-01 19:50:50 +00:00
|
|
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, fontLUT[mark + 0xEF]);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDPLoadSync(gDisplayListHead++);
|
2019-11-03 19:36:27 +00:00
|
|
|
gDPLoadBlock(gDisplayListHead++, G_TX_LOADTILE, 0, 0, 8 * 8 - 1, CALC_DXT(8, G_IM_SIZ_8b_BYTES));
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPTextureRectangle(gDisplayListHead++, (curX + 6) << 2, (curY - 7) << 2,
|
2019-10-05 19:08:05 +00:00
|
|
|
(curX + 14) << 2, (curY + 1) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
mark = DIALOG_MARK_NONE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef VERSION_JP
|
|
|
|
curX += 9;
|
|
|
|
#else
|
2019-09-01 19:50:50 +00:00
|
|
|
curX += gDialogCharWidths[str[strPos]];
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
strPos++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void print_credits_string(s16 x, s16 y, const u8 *str) {
|
2019-08-25 04:46:40 +00:00
|
|
|
s32 strPos = 0;
|
2019-10-05 19:08:05 +00:00
|
|
|
void **fontLUT = segmented_to_virtual(main_credits_font_lut);
|
2019-08-25 04:46:40 +00:00
|
|
|
u32 curX = x;
|
|
|
|
u32 curY = y;
|
|
|
|
|
2019-11-03 19:36:27 +00:00
|
|
|
gDPSetTile(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0,
|
|
|
|
G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD);
|
2019-09-01 19:50:50 +00:00
|
|
|
gDPTileSync(gDisplayListHead++);
|
2019-11-03 19:36:27 +00:00
|
|
|
gDPSetTile(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 2, 0, G_TX_RENDERTILE, 0,
|
|
|
|
G_TX_CLAMP, 3, G_TX_NOLOD, G_TX_CLAMP, 3, G_TX_NOLOD);
|
|
|
|
gDPSetTileSize(gDisplayListHead++, G_TX_RENDERTILE, 0, 0, (8 - 1) << G_TEXTURE_IMAGE_FRAC, (8 - 1) << G_TEXTURE_IMAGE_FRAC);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
while (str[strPos] != GLOBAR_CHAR_TERMINATOR) {
|
2019-08-25 04:46:40 +00:00
|
|
|
switch (str[strPos]) {
|
2019-10-05 19:08:05 +00:00
|
|
|
case GLOBAL_CHAR_SPACE:
|
2019-08-25 04:46:40 +00:00
|
|
|
curX += 4;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
gDPPipeSync(gDisplayListHead++);
|
2019-09-01 19:50:50 +00:00
|
|
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, fontLUT[str[strPos]]);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDPLoadSync(gDisplayListHead++);
|
2019-11-03 19:36:27 +00:00
|
|
|
gDPLoadBlock(gDisplayListHead++, G_TX_LOADTILE, 0, 0, 8 * 8 - 1, CALC_DXT(8, G_IM_SIZ_16b_BYTES));
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPTextureRectangle(gDisplayListHead++, curX << 2, curY << 2, (curX + 8) << 2,
|
2019-10-05 19:08:05 +00:00
|
|
|
(curY + 8) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
2019-08-25 04:46:40 +00:00
|
|
|
curX += 7;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
strPos++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void handle_menu_scrolling(s8 scrollDirection, s8 *currentIndex, s8 minIndex, s8 maxIndex) {
|
|
|
|
u8 index = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (scrollDirection == MENU_SCROLL_VERTICAL) {
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gPlayer3Controller->rawStickY > 60) {
|
2019-10-05 19:08:05 +00:00
|
|
|
index++;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gPlayer3Controller->rawStickY < -60) {
|
2019-10-05 19:08:05 +00:00
|
|
|
index += 2;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
} else if (scrollDirection == MENU_SCROLL_HORIZONTAL) {
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gPlayer3Controller->rawStickX > 60) {
|
2019-10-05 19:08:05 +00:00
|
|
|
index += 2;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gPlayer3Controller->rawStickX < -60) {
|
2019-10-05 19:08:05 +00:00
|
|
|
index++;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (((index ^ gMenuHoldKeyIndex) & index) == 2) {
|
2019-09-01 19:50:50 +00:00
|
|
|
if (currentIndex[0] == maxIndex) {
|
|
|
|
//! Probably originally a >=, but later replaced with an == and an else statement.
|
|
|
|
currentIndex[0] = maxIndex;
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
currentIndex[0]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (((index ^ gMenuHoldKeyIndex) & index) == 1) {
|
2019-09-01 19:50:50 +00:00
|
|
|
if (currentIndex[0] == minIndex) {
|
|
|
|
// Same applies to here as above
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
currentIndex[0]--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gMenuHoldKeyTimer == 10) {
|
|
|
|
gMenuHoldKeyTimer = 8;
|
|
|
|
gMenuHoldKeyIndex = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
gMenuHoldKeyTimer++;
|
|
|
|
gMenuHoldKeyIndex = index;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if ((index & 3) == 0) {
|
|
|
|
gMenuHoldKeyTimer = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// EU has both get_str_x_pos_from_center and get_str_x_pos_from_center_scale
|
2019-09-01 19:50:50 +00:00
|
|
|
// US and JP only implement one or the other
|
2019-08-25 04:46:40 +00:00
|
|
|
#if defined(VERSION_US) || defined(VERSION_EU)
|
|
|
|
s16 get_str_x_pos_from_center(s16 centerPos, u8 *str, UNUSED f32 scale) {
|
|
|
|
s16 strPos = 0;
|
|
|
|
f32 spacesWidth = 0.0f;
|
|
|
|
|
|
|
|
while (str[strPos] != DIALOG_CHAR_TERMINATOR) {
|
|
|
|
spacesWidth += gDialogCharWidths[str[strPos]];
|
|
|
|
strPos++;
|
|
|
|
}
|
|
|
|
// return the x position of where the string starts as half the string's
|
|
|
|
// length from the position of the provided center.
|
|
|
|
return (s16)(centerPos - (s16)(spacesWidth / 2.0));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
#if defined(VERSION_JP) || defined(VERSION_EU) || defined(VERSION_SH)
|
2019-08-25 04:46:40 +00:00
|
|
|
s16 get_str_x_pos_from_center_scale(s16 centerPos, u8 *str, f32 scale) {
|
|
|
|
s16 strPos = 0;
|
|
|
|
f32 charsWidth = 0.0f;
|
|
|
|
f32 spacesWidth = 0.0f;
|
|
|
|
|
|
|
|
while (str[strPos] != DIALOG_CHAR_TERMINATOR) {
|
|
|
|
//! EU checks for dakuten and handakuten despite dialog code unable to handle it
|
2019-09-01 19:50:50 +00:00
|
|
|
if (str[strPos] == DIALOG_CHAR_SPACE) {
|
2019-08-25 04:46:40 +00:00
|
|
|
spacesWidth += 1.0;
|
2020-01-03 15:38:57 +00:00
|
|
|
} else if (str[strPos] != DIALOG_CHAR_DAKUTEN
|
|
|
|
&& str[strPos] != DIALOG_CHAR_PERIOD_OR_HANDAKUTEN) {
|
2019-08-25 04:46:40 +00:00
|
|
|
charsWidth += 1.0;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
strPos++;
|
|
|
|
}
|
|
|
|
// return the x position of where the string starts as half the string's
|
|
|
|
// length from the position of the provided center.
|
|
|
|
return (f32) centerPos - (scale * (charsWidth / 2.0)) - ((scale / 2.0) * (spacesWidth / 2.0));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef VERSION_JP
|
2019-10-05 19:08:05 +00:00
|
|
|
s16 get_string_width(u8 *str) {
|
2019-08-25 04:46:40 +00:00
|
|
|
s16 strPos = 0;
|
|
|
|
s16 width = 0;
|
|
|
|
|
|
|
|
while (str[strPos] != DIALOG_CHAR_TERMINATOR) {
|
|
|
|
width += gDialogCharWidths[str[strPos]];
|
|
|
|
strPos++;
|
|
|
|
}
|
|
|
|
return width;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
u8 gHudSymCoin[] = { GLYPH_COIN, GLYPH_SPACE };
|
|
|
|
u8 gHudSymX[] = { GLYPH_MULTIPLY, GLYPH_SPACE };
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void print_hud_my_score_coins(s32 useCourseCoinScore, s8 fileNum, s8 courseNum, s16 x, s16 y) {
|
2019-08-25 04:46:40 +00:00
|
|
|
u8 strNumCoins[4];
|
|
|
|
s16 numCoins;
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (!useCourseCoinScore) {
|
2019-10-05 19:08:05 +00:00
|
|
|
numCoins = (u16)(save_file_get_max_coin_score(courseNum) & 0xFFFF);
|
2019-09-01 19:50:50 +00:00
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
numCoins = save_file_get_course_coin_score(fileNum, courseNum);
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (numCoins != 0) {
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, x, y, gHudSymCoin);
|
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, x + 16, y, gHudSymX);
|
|
|
|
int_to_str(numCoins, strNumCoins);
|
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, x + 32, y, strNumCoins);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void print_hud_my_score_stars(s8 fileNum, s8 courseNum, s16 x, s16 y) {
|
2019-08-25 04:46:40 +00:00
|
|
|
u8 strStarCount[4];
|
|
|
|
s16 starCount;
|
2019-10-05 19:08:05 +00:00
|
|
|
u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE };
|
2019-08-25 04:46:40 +00:00
|
|
|
UNUSED u16 unused;
|
2019-10-05 19:08:05 +00:00
|
|
|
u8 textSymX[] = { GLYPH_MULTIPLY, GLYPH_SPACE };
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
starCount = save_file_get_course_star_count(fileNum, courseNum);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (starCount != 0) {
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, x, y, textSymStar);
|
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, x + 16, y, textSymX);
|
|
|
|
int_to_str(starCount, strStarCount);
|
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, x + 32, y, strStarCount);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void int_to_str(s32 num, u8 *dst) {
|
2019-08-25 04:46:40 +00:00
|
|
|
s32 digit1;
|
|
|
|
s32 digit2;
|
|
|
|
s32 digit3;
|
|
|
|
|
|
|
|
s8 pos = 0;
|
|
|
|
|
|
|
|
if (num > 999) {
|
2020-02-03 05:51:26 +00:00
|
|
|
dst[0] = 0x00; dst[1] = DIALOG_CHAR_TERMINATOR;
|
2019-08-25 04:46:40 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
digit1 = num / 100;
|
|
|
|
digit2 = (num - digit1 * 100) / 10;
|
|
|
|
digit3 = (num - digit1 * 100) - (digit2 * 10);
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (digit1 != 0) {
|
2019-08-25 04:46:40 +00:00
|
|
|
dst[pos++] = digit1;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (digit2 != 0 || digit1 != 0) {
|
2019-08-25 04:46:40 +00:00
|
|
|
dst[pos++] = digit2;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
dst[pos++] = digit3;
|
|
|
|
dst[pos] = DIALOG_CHAR_TERMINATOR;
|
|
|
|
}
|
|
|
|
|
|
|
|
s16 get_dialog_id(void) {
|
|
|
|
return gDialogID;
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void create_dialog_box(s16 dialog) {
|
2019-08-25 04:46:40 +00:00
|
|
|
if (gDialogID == -1) {
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogID = dialog;
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogBoxType = DIALOG_TYPE_ROTATE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void create_dialog_box_with_var(s16 dialog, s32 dialogVar) {
|
2019-08-25 04:46:40 +00:00
|
|
|
if (gDialogID == -1) {
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogID = dialog;
|
|
|
|
gDialogVariable = dialogVar;
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogBoxType = DIALOG_TYPE_ROTATE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void create_dialog_inverted_box(s16 dialog) {
|
2019-08-25 04:46:40 +00:00
|
|
|
if (gDialogID == -1) {
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogID = dialog;
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogBoxType = DIALOG_TYPE_ZOOM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void create_dialog_box_with_response(s16 dialog) {
|
2019-08-25 04:46:40 +00:00
|
|
|
if (gDialogID == -1) {
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogID = dialog;
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogBoxType = DIALOG_TYPE_ROTATE;
|
2019-10-05 19:08:05 +00:00
|
|
|
gLastDialogResponse = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void reset_dialog_render_state(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
level_set_transition(0, 0);
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gDialogBoxType == DIALOG_TYPE_ZOOM) {
|
2020-01-03 15:38:57 +00:00
|
|
|
trigger_cutscene_dialog(2);
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
gDialogBoxScale = 19.0f;
|
|
|
|
gDialogBoxOpenTimer = 90.0f;
|
|
|
|
gDialogBoxState = DIALOG_STATE_OPENING;
|
|
|
|
gDialogID = -1;
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogTextPos = 0;
|
|
|
|
gLastDialogResponse = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
gLastDialogPageStrPos = 0;
|
|
|
|
gDialogResponse = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VERSION_JP
|
|
|
|
#define X_VAL1 -5.0f
|
|
|
|
#define Y_VAL1 2.0
|
|
|
|
#define Y_VAL2 4.0f
|
|
|
|
#else
|
|
|
|
#define X_VAL1 -7.0f
|
|
|
|
#define Y_VAL1 5.0
|
|
|
|
#define Y_VAL2 5.0f
|
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_dialog_box_type(struct DialogEntry *dialog, s8 linesPerBox) {
|
2019-08-25 04:46:40 +00:00
|
|
|
UNUSED s32 unused;
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, dialog->leftOffset, dialog->width, 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
switch (gDialogBoxType) {
|
2019-10-05 19:08:05 +00:00
|
|
|
case DIALOG_TYPE_ROTATE: // Renders a dialog black box with zoom and rotation
|
2019-08-25 04:46:40 +00:00
|
|
|
if (gDialogBoxState == DIALOG_STATE_OPENING || gDialogBoxState == DIALOG_STATE_CLOSING) {
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.0 / gDialogBoxScale, 1.0 / gDialogBoxScale, 1.0f);
|
|
|
|
// convert the speed into angle
|
|
|
|
create_dl_rotation_matrix(MENU_MTX_NOPUSH, gDialogBoxOpenTimer * 4.0f, 0, 0, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2019-12-02 02:52:53 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 150);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
2019-10-05 19:08:05 +00:00
|
|
|
case DIALOG_TYPE_ZOOM: // Renders a dialog white box with zoom
|
2019-08-25 04:46:40 +00:00
|
|
|
if (gDialogBoxState == DIALOG_STATE_OPENING || gDialogBoxState == DIALOG_STATE_CLOSING) {
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, 65.0 - (65.0 / gDialogBoxScale),
|
2019-08-25 04:46:40 +00:00
|
|
|
(40.0 / gDialogBoxScale) - 40, 0);
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.0 / gDialogBoxScale, 1.0 / gDialogBoxScale, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2019-12-02 02:52:53 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 150);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, X_VAL1, Y_VAL1, 0);
|
|
|
|
create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.1f, ((f32) linesPerBox / Y_VAL2) + 0.1, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_draw_text_bg_box);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void change_and_flash_dialog_text_color_lines(s8 colorMode, s8 lineNum) {
|
|
|
|
u8 colorFade;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (colorMode == 1) {
|
|
|
|
if (lineNum == 1) {
|
2019-08-25 04:46:40 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
if (lineNum == gDialogLineNum) {
|
|
|
|
colorFade = (gSineTable[gDialogColorFadeTimer >> 4] * 50.0f) + 200.0f;
|
|
|
|
gDPSetEnvColor(gDisplayListHead++, colorFade, colorFade, colorFade, 255);
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
|
|
|
gDPSetEnvColor(gDisplayListHead++, 200, 200, 200, 255);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (gDialogBoxType) {
|
|
|
|
case DIALOG_TYPE_ROTATE:
|
|
|
|
break;
|
|
|
|
case DIALOG_TYPE_ZOOM:
|
|
|
|
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_generic_dialog_char_at_pos(struct DialogEntry *dialog, s16 x, s16 y, u8 c) {
|
2019-08-25 04:46:40 +00:00
|
|
|
s16 width; // sp26
|
|
|
|
s16 height; // sp24
|
|
|
|
s16 tmpX;
|
|
|
|
s16 tmpY;
|
|
|
|
s16 xCoord; // sp1E
|
|
|
|
s16 yCoord; // sp1C
|
2019-10-05 19:08:05 +00:00
|
|
|
void **fontLUT;
|
2019-08-25 04:46:40 +00:00
|
|
|
void *packedTexture;
|
|
|
|
void *unpackedTexture;
|
|
|
|
|
|
|
|
width = (8.0 - (gDialogBoxScale * 0.8));
|
|
|
|
height = (16.0 - (gDialogBoxScale * 0.8));
|
|
|
|
tmpX = (dialog->leftOffset + (65.0 - (65.0 / gDialogBoxScale)));
|
|
|
|
tmpY = ((240 - dialog->width) - ((40.0 / gDialogBoxScale) - 40));
|
|
|
|
xCoord = (tmpX + (x / gDialogBoxScale));
|
|
|
|
yCoord = (tmpY + (y / gDialogBoxScale));
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
fontLUT = segmented_to_virtual(main_font_lut);
|
|
|
|
packedTexture = segmented_to_virtual(fontLUT[c]);
|
2019-08-25 04:46:40 +00:00
|
|
|
unpackedTexture = alloc_ia4_tex_from_i1(packedTexture, 8, 8);
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, VIRTUAL_TO_PHYSICAL(unpackedTexture));
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPTextureRectangleFlip(gDisplayListHead++, xCoord << 2, (yCoord - height) << 2,
|
2019-10-05 19:08:05 +00:00
|
|
|
(xCoord + width) << 2, yCoord << 2, G_TX_RENDERTILE, 16 << 5, 8 << 5, 1 << 10, 1 << 10);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef VERSION_JP
|
|
|
|
#define X_VAL3 5.0f
|
|
|
|
#define Y_VAL3 20
|
|
|
|
#else
|
|
|
|
#define X_VAL3 0.0f
|
|
|
|
#define Y_VAL3 16
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
void handle_dialog_scroll_page_state(s8 lineNum, s8 totalLines, s8 *pageState, s8 *xMatrix)
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
void handle_dialog_scroll_page_state(s8 lineNum, s8 totalLines, s8 *pageState, s8 *xMatrix, s16 *linePos)
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
{
|
|
|
|
#ifndef VERSION_EU
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (lineNum == totalLines) {
|
|
|
|
pageState[0] = DIALOG_PAGE_STATE_SCROLL;
|
2019-08-25 04:46:40 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
gDialogY += 16;
|
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, X_VAL3, 2 - (lineNum * Y_VAL3), 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
linePos[0] = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
xMatrix[0] = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
#if defined(VERSION_JP) || defined(VERSION_SH)
|
2020-01-03 15:38:57 +00:00
|
|
|
void adjust_pos_and_print_period_char(s8 *xMatrix, s16 *linePos) {
|
2019-10-05 19:08:05 +00:00
|
|
|
if (linePos[0] != 0) {
|
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, xMatrix[0] * 10, 0, 0);
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, -2.0f, -5.0f, 0);
|
2020-01-03 15:38:57 +00:00
|
|
|
render_generic_char(DIALOG_CHAR_PERIOD_OR_HANDAKUTEN);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
linePos[0]++;
|
|
|
|
xMatrix[0] = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_star_count_dialog_text(struct DialogEntry *dialog, s8 *linePos)
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_star_count_dialog_text(s8 *xMatrix, s16 *linePos)
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
{
|
|
|
|
s8 tensDigit = gDialogVariable / 10;
|
|
|
|
s8 onesDigit = gDialogVariable - (tensDigit * 10); // remainder
|
|
|
|
|
|
|
|
if (tensDigit != 0) {
|
|
|
|
#ifdef VERSION_JP
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, xMatrix[0] * 10, 0, 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
render_generic_char(tensDigit);
|
|
|
|
#elif defined(VERSION_EU)
|
2019-10-05 19:08:05 +00:00
|
|
|
render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY, tensDigit);
|
2019-09-01 19:50:50 +00:00
|
|
|
gDialogX += gDialogCharWidths[tensDigit];
|
2019-10-05 19:08:05 +00:00
|
|
|
linePos[0] = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
if (xMatrix[0] != 1) {
|
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, (f32)(gDialogCharWidths[DIALOG_CHAR_SPACE] * xMatrix[0]), 0, 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
render_generic_char(tensDigit);
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, (f32) gDialogCharWidths[tensDigit], 0, 0);
|
|
|
|
xMatrix[0] = 1;
|
|
|
|
linePos[0]++;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#ifndef VERSION_EU
|
|
|
|
else {
|
|
|
|
#ifdef VERSION_JP
|
2019-10-05 19:08:05 +00:00
|
|
|
xMatrix[0]++;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY, onesDigit);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogX += gDialogCharWidths[onesDigit];
|
2019-10-05 19:08:05 +00:00
|
|
|
linePos[0] = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
|
|
|
|
|
|
|
#ifdef VERSION_JP
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, xMatrix[0] * 10, 0, 0);
|
2019-09-01 19:50:50 +00:00
|
|
|
render_generic_char(onesDigit);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
if (xMatrix[0] != 1) {
|
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, (f32)(gDialogCharWidths[DIALOG_CHAR_SPACE] * (xMatrix[0] - 1)), 0, 0);
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
render_generic_char(onesDigit);
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, (f32) gDialogCharWidths[onesDigit], 0, 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
linePos[0]++;
|
|
|
|
xMatrix[0] = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
#if !defined(VERSION_JP) && !defined(VERSION_SH)
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_multi_text_string_lines(s8 multiTextId, s8 lineNum, s8 linesPerBox, UNUSED s16 linePos, s8 lowerBound, struct DialogEntry *dialog)
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_multi_text_string_lines(s8 multiTextId, s8 lineNum, s16 *linePos, s8 linesPerBox, s8 xMatrix, s8 lowerBound)
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
{
|
|
|
|
s8 i;
|
|
|
|
struct MultiTextEntry textLengths[2] = {
|
|
|
|
{ 3, { TEXT_THE_RAW } },
|
|
|
|
{ 3, { TEXT_YOU_RAW } },
|
|
|
|
};
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (lineNum >= lowerBound && lineNum <= (lowerBound + linesPerBox)) {
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_US
|
2019-10-05 19:08:05 +00:00
|
|
|
if (linePos[0] != 0 || (xMatrix != 1)) {
|
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, (gDialogCharWidths[DIALOG_CHAR_SPACE] * (xMatrix - 1)), 0, 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
for (i = 0; i < textLengths[multiTextId].length; i++) {
|
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY, textLengths[multiTextId].str[i]);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogX += gDialogCharWidths[textLengths[multiTextId].str[i]];
|
|
|
|
#else
|
|
|
|
render_generic_char(textLengths[multiTextId].str[i]);
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, (gDialogCharWidths[textLengths[multiTextId].str[i]]), 0, 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#ifdef VERSION_US
|
2019-10-05 19:08:05 +00:00
|
|
|
linePos += textLengths[multiTextId].length;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_dialog_lowercase_diacritic(struct DialogEntry *dialog, u8 chr, u8 diacritic) {
|
|
|
|
render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY, chr);
|
|
|
|
render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY, diacritic + 0xE7);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogX += gDialogCharWidths[chr];
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_dialog_uppercase_diacritic(struct DialogEntry *dialog, u8 chr, u8 diacritic) {
|
|
|
|
render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY, chr);
|
|
|
|
render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY - 4, diacritic + 0xE3);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogX += gDialogCharWidths[chr];
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
u32 ensure_nonnegative(s16 value) {
|
|
|
|
if (value < 0) {
|
|
|
|
value = 0;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
return value;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
#if defined(VERSION_JP) || defined(VERSION_SH)
|
2019-10-05 19:08:05 +00:00
|
|
|
void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog)
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 lowerBound)
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-09-01 19:50:50 +00:00
|
|
|
{
|
2019-10-05 19:08:05 +00:00
|
|
|
UNUSED s32 pad[2];
|
2020-03-02 03:42:52 +00:00
|
|
|
#ifdef VERSION_EU
|
|
|
|
s16 startY = 14;
|
|
|
|
#endif
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
u8 strChar;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
u8 *str = segmented_to_virtual(dialog->str);
|
|
|
|
s8 lineNum = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
s8 totalLines;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
s8 pageState = DIALOG_PAGE_STATE_NONE;
|
2019-09-01 19:50:50 +00:00
|
|
|
UNUSED s8 mark = DIALOG_MARK_NONE; // unused in US, EU
|
2019-10-05 19:08:05 +00:00
|
|
|
s8 xMatrix = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
s8 linesPerBox = dialog->linesPerBox;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
s16 strIdx;
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifndef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
s16 linePos = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gDialogBoxState == DIALOG_STATE_HORIZONTAL) {
|
|
|
|
// If scrolling, consider the number of lines for both
|
|
|
|
// the current page and the page being scrolled to.
|
|
|
|
totalLines = linesPerBox * 2 + 1;
|
2019-09-01 19:50:50 +00:00
|
|
|
} else {
|
|
|
|
totalLines = linesPerBox + 1;
|
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
2019-10-05 19:08:05 +00:00
|
|
|
strIdx = gDialogTextPos;
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-09-01 19:50:50 +00:00
|
|
|
gDialogX = 0;
|
2020-03-02 03:42:52 +00:00
|
|
|
gDialogY = startY;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gDialogBoxState == DIALOG_STATE_HORIZONTAL) {
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-09-01 19:50:50 +00:00
|
|
|
gDialogY -= gDialogScrollOffsetY;
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, 0, (f32) gDialogScrollOffsetY, 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
#ifndef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, X_VAL3, 2 - lineNum * Y_VAL3, 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
while (pageState == DIALOG_PAGE_STATE_NONE) {
|
|
|
|
change_and_flash_dialog_text_color_lines(colorMode, lineNum);
|
2019-09-01 19:50:50 +00:00
|
|
|
strChar = str[strIdx];
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
switch (strChar) {
|
|
|
|
case DIALOG_CHAR_TERMINATOR:
|
2019-10-05 19:08:05 +00:00
|
|
|
pageState = DIALOG_PAGE_STATE_END;
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifndef VERSION_EU
|
2019-09-01 19:50:50 +00:00
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_NEWLINE:
|
|
|
|
lineNum++;
|
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
handle_dialog_scroll_page_state(lineNum, totalLines, &pageState, &xMatrix);
|
2019-09-01 19:50:50 +00:00
|
|
|
gDialogX = 0;
|
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
handle_dialog_scroll_page_state(lineNum, totalLines, &pageState, &xMatrix, &linePos);
|
2019-09-01 19:50:50 +00:00
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
case DIALOG_CHAR_LOWER_A_GRAVE:
|
|
|
|
case DIALOG_CHAR_LOWER_A_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_LOWER_A_UMLAUT:
|
2019-10-05 19:08:05 +00:00
|
|
|
render_dialog_lowercase_diacritic(dialog, ASCII_TO_DIALOG('a'), strChar & 0xF);
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_UPPER_A_GRAVE:
|
|
|
|
case DIALOG_CHAR_UPPER_A_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_UPPER_A_UMLAUT:
|
2019-10-05 19:08:05 +00:00
|
|
|
render_dialog_uppercase_diacritic(dialog, ASCII_TO_DIALOG('A'), strChar & 0xF);
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_LOWER_E_GRAVE:
|
|
|
|
case DIALOG_CHAR_LOWER_E_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_LOWER_E_UMLAUT:
|
|
|
|
case DIALOG_CHAR_LOWER_E_ACUTE:
|
2019-10-05 19:08:05 +00:00
|
|
|
render_dialog_lowercase_diacritic(dialog, ASCII_TO_DIALOG('e'), strChar & 0xF);
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_UPPER_E_GRAVE:
|
|
|
|
case DIALOG_CHAR_UPPER_E_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_UPPER_E_UMLAUT:
|
|
|
|
case DIALOG_CHAR_UPPER_E_ACUTE:
|
2019-10-05 19:08:05 +00:00
|
|
|
render_dialog_uppercase_diacritic(dialog, ASCII_TO_DIALOG('E'), strChar & 0xF);
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_LOWER_U_GRAVE:
|
|
|
|
case DIALOG_CHAR_LOWER_U_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_LOWER_U_UMLAUT:
|
2019-10-05 19:08:05 +00:00
|
|
|
render_dialog_lowercase_diacritic(dialog, ASCII_TO_DIALOG('u'), strChar & 0xF);
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_UPPER_U_GRAVE:
|
|
|
|
case DIALOG_CHAR_UPPER_U_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_UPPER_U_UMLAUT:
|
2019-10-05 19:08:05 +00:00
|
|
|
render_dialog_uppercase_diacritic(dialog, ASCII_TO_DIALOG('U'), strChar & 0xF);
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_LOWER_O_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_LOWER_O_UMLAUT:
|
2019-10-05 19:08:05 +00:00
|
|
|
render_dialog_lowercase_diacritic(dialog, ASCII_TO_DIALOG('o'), strChar & 0xF);
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_UPPER_O_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_UPPER_O_UMLAUT:
|
2019-10-05 19:08:05 +00:00
|
|
|
render_dialog_uppercase_diacritic(dialog, ASCII_TO_DIALOG('O'), strChar & 0xF);
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_LOWER_I_CIRCUMFLEX:
|
|
|
|
case DIALOG_CHAR_LOWER_I_UMLAUT:
|
2019-10-05 19:08:05 +00:00
|
|
|
render_dialog_lowercase_diacritic(dialog, DIALOG_CHAR_I_NO_DIA, strChar & 0xF);
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
|
|
|
#else
|
2020-01-03 15:38:57 +00:00
|
|
|
case DIALOG_CHAR_DAKUTEN:
|
2019-09-01 19:50:50 +00:00
|
|
|
mark = DIALOG_MARK_DAKUTEN;
|
|
|
|
break;
|
2020-01-03 15:38:57 +00:00
|
|
|
case DIALOG_CHAR_PERIOD_OR_HANDAKUTEN:
|
2019-09-01 19:50:50 +00:00
|
|
|
mark = DIALOG_MARK_HANDAKUTEN;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case DIALOG_CHAR_SPACE:
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
gDialogX += gDialogCharWidths[DIALOG_CHAR_SPACE];
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
|
|
|
#ifdef VERSION_JP
|
2019-09-01 19:50:50 +00:00
|
|
|
if (linePos != 0) {
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
xMatrix++;
|
2019-09-01 19:50:50 +00:00
|
|
|
#ifdef VERSION_JP
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
linePos++;
|
2019-10-05 19:08:05 +00:00
|
|
|
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
2020-03-02 03:42:52 +00:00
|
|
|
#if defined(VERSION_JP) || defined(VERSION_SH)
|
2020-01-03 15:38:57 +00:00
|
|
|
case DIALOG_CHAR_PERIOD:
|
|
|
|
adjust_pos_and_print_period_char(&xMatrix, &linePos);
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
case DIALOG_CHAR_SLASH:
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-09-01 19:50:50 +00:00
|
|
|
gDialogX += gDialogCharWidths[DIALOG_CHAR_SPACE] * 2;
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
xMatrix += 2;
|
2019-09-01 19:50:50 +00:00
|
|
|
linePos += 2;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_MULTI_THE:
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
render_multi_text_string_lines(STRING_THE, lineNum, linesPerBox, xMatrix, lowerBound, dialog);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
render_multi_text_string_lines(STRING_THE, lineNum, &linePos, linesPerBox, xMatrix, lowerBound);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
xMatrix = 1;
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
|
|
|
case DIALOG_CHAR_MULTI_YOU:
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
render_multi_text_string_lines(STRING_YOU, lineNum, linesPerBox, xMatrix, lowerBound, dialog);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
render_multi_text_string_lines(STRING_YOU, lineNum, &linePos, linesPerBox, xMatrix, lowerBound);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
xMatrix = 1;
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-09-01 19:50:50 +00:00
|
|
|
case DIALOG_CHAR_STAR_COUNT:
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
render_star_count_dialog_text(dialog, &xMatrix);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
render_star_count_dialog_text(&xMatrix, &linePos);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-09-01 19:50:50 +00:00
|
|
|
break;
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-09-01 19:50:50 +00:00
|
|
|
case DIALOG_CHAR_DOUBLE_LOW_QUOTE:
|
2019-10-05 19:08:05 +00:00
|
|
|
render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY + 8, 0xF6);
|
2019-09-01 19:50:50 +00:00
|
|
|
gDialogX += gDialogCharWidths[0xF6];
|
|
|
|
break;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-09-01 19:50:50 +00:00
|
|
|
default: // any other character
|
2020-03-02 03:42:52 +00:00
|
|
|
#if defined(VERSION_JP) || defined(VERSION_SH)
|
2019-09-01 19:50:50 +00:00
|
|
|
if (linePos != 0) {
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, xMatrix * 10, 0, 0);
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
render_generic_char(strChar);
|
2019-10-05 19:08:05 +00:00
|
|
|
xMatrix = 1;
|
2019-09-01 19:50:50 +00:00
|
|
|
linePos++;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (mark != 0) {
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, 5.0f, 7.0f, 0);
|
2019-09-01 19:50:50 +00:00
|
|
|
render_generic_char(mark + 0xEF);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
mark = 0;
|
|
|
|
}
|
2019-10-05 19:08:05 +00:00
|
|
|
#elif defined(VERSION_US)
|
|
|
|
if (lineNum >= lowerBound && lineNum <= lowerBound + linesPerBox) {
|
|
|
|
if (linePos || xMatrix != 1) {
|
|
|
|
create_dl_translation_matrix(
|
|
|
|
MENU_MTX_NOPUSH, (f32)(gDialogCharWidths[DIALOG_CHAR_SPACE] * (xMatrix - 1)), 0, 0);
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
render_generic_char(strChar);
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, (f32)(gDialogCharWidths[strChar]), 0, 0);
|
|
|
|
xMatrix = 1;
|
2019-09-01 19:50:50 +00:00
|
|
|
linePos++;
|
|
|
|
}
|
2019-10-05 19:08:05 +00:00
|
|
|
#else // VERSION_EU
|
|
|
|
if (lineNum >= lowerBound && lineNum <= lowerBound + linesPerBox) {
|
|
|
|
render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY, strChar);
|
|
|
|
}
|
|
|
|
gDialogX += gDialogCharWidths[strChar];
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
#ifdef VERSION_JP
|
2019-09-01 19:50:50 +00:00
|
|
|
if (linePos == 12) {
|
2020-01-03 15:38:57 +00:00
|
|
|
if (str[strIdx + 1] == DIALOG_CHAR_PERIOD) {
|
|
|
|
adjust_pos_and_print_period_char(&xMatrix, &linePos);
|
2019-09-01 19:50:50 +00:00
|
|
|
strIdx++;
|
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (str[strIdx + 1] == DIALOG_CHAR_COMMA) {
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, xMatrix * 10, 0, 0);
|
2019-09-01 19:50:50 +00:00
|
|
|
render_generic_char(DIALOG_CHAR_COMMA);
|
|
|
|
strIdx++;
|
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (str[strIdx + 1] == DIALOG_CHAR_NEWLINE) {
|
|
|
|
strIdx++;
|
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (str[strIdx + 1] == DIALOG_CHAR_TERMINATOR) {
|
2019-10-05 19:08:05 +00:00
|
|
|
pageState = DIALOG_PAGE_STATE_END;
|
2019-09-01 19:50:50 +00:00
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
break; // exit loop
|
|
|
|
} else {
|
|
|
|
lineNum++;
|
2019-10-05 19:08:05 +00:00
|
|
|
handle_dialog_scroll_page_state(lineNum, totalLines, &pageState, &xMatrix, &linePos);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
strIdx++;
|
|
|
|
}
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gDialogBoxState == DIALOG_STATE_VERTICAL) {
|
|
|
|
if (pageState == DIALOG_PAGE_STATE_END) {
|
2019-09-01 19:50:50 +00:00
|
|
|
gLastDialogPageStrPos = -1;
|
|
|
|
} else {
|
|
|
|
gLastDialogPageStrPos = strIdx;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
2019-09-01 19:50:50 +00:00
|
|
|
|
|
|
|
gLastDialogLineNum = lineNum;
|
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
#ifdef VERSION_JP
|
|
|
|
#define X_VAL4_1 50
|
|
|
|
#define X_VAL4_2 25
|
|
|
|
#define Y_VAL4_1 1
|
|
|
|
#define Y_VAL4_2 20
|
|
|
|
#else
|
|
|
|
#define X_VAL4_1 56
|
|
|
|
#define X_VAL4_2 47
|
|
|
|
#define Y_VAL4_1 2
|
|
|
|
#define Y_VAL4_2 16
|
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_dialog_triangle_choice(void) {
|
|
|
|
if (gDialogBoxState == DIALOG_STATE_VERTICAL) {
|
|
|
|
handle_menu_scrolling(MENU_SCROLL_HORIZONTAL, &gDialogLineNum, 1, 2);
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_NOPUSH, (gDialogLineNum * X_VAL4_1) - X_VAL4_2, Y_VAL4_1 - (gLastDialogLineNum * Y_VAL4_2), 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (gDialogBoxType == DIALOG_TYPE_ROTATE) {
|
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
|
|
|
} else {
|
|
|
|
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255);
|
|
|
|
}
|
|
|
|
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
#define X_VAL5 122.0f
|
|
|
|
#define Y_VAL5_1 -16
|
|
|
|
#define Y_VAL5_2 3
|
|
|
|
#define X_Y_VAL6 0.5f
|
|
|
|
#elif defined(VERSION_US)
|
|
|
|
#define X_VAL5 118.0f
|
|
|
|
#define Y_VAL5_1 -16
|
|
|
|
#define Y_VAL5_2 5
|
|
|
|
#define X_Y_VAL6 0.8f
|
2020-03-02 03:42:52 +00:00
|
|
|
#elif defined(VERSION_JP) || defined(VERSION_SH)
|
2019-08-25 04:46:40 +00:00
|
|
|
#define X_VAL5 123.0f
|
|
|
|
#define Y_VAL5_1 -20
|
|
|
|
#define Y_VAL5_2 2
|
|
|
|
#define X_Y_VAL6 0.8f
|
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_dialog_string_color(s8 linesPerBox) {
|
|
|
|
s32 timer = gGlobalTimer;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (timer & 0x08) {
|
2019-08-25 04:46:40 +00:00
|
|
|
return;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, X_VAL5, (linesPerBox * Y_VAL5_1) + Y_VAL5_2, 0);
|
|
|
|
create_dl_scale_matrix(MENU_MTX_NOPUSH, X_Y_VAL6, X_Y_VAL6, 1.0f);
|
|
|
|
create_dl_rotation_matrix(MENU_MTX_NOPUSH, -DEFAULT_DIALOG_BOX_ANGLE, 0, 0, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gDialogBoxType == DIALOG_TYPE_ROTATE) { // White Text
|
2019-08-25 04:46:40 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
2019-10-05 19:08:05 +00:00
|
|
|
} else { // Black Text
|
2019-08-25 04:46:40 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255);
|
|
|
|
}
|
|
|
|
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void handle_special_dialog_text(s16 dialogID) { // dialog ID tables, in order
|
|
|
|
// King Bob-omb (Start), Whomp (Start), King Bob-omb (throw him out), Eyerock (Start), Wiggler (Start)
|
|
|
|
s16 dialogBossStart[] = { 17, 114, 128, 117, 150 };
|
|
|
|
// Koopa the Quick (BOB), Koopa the Quick (THI), Penguin Race, Fat Penguin Race (120 stars)
|
|
|
|
s16 dialogRaceSound[] = { 5, 9, 55, 164 };
|
|
|
|
// Red Switch, Green Switch, Blue Switch, 100 coins star, Bowser Red Coin Star
|
|
|
|
s16 dialogStarSound[] = { 10, 11, 12, 13, 14 };
|
|
|
|
// King Bob-omb (Start), Whomp (Defeated), King Bob-omb (Defeated, missing in JP), Eyerock (Defeated), Wiggler (Defeated)
|
|
|
|
#if BUGFIX_KING_BOB_OMB_FADE_MUSIC
|
|
|
|
s16 dialogBossStop[] = { 17, 115, 116, 118, 152 };
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
//! @bug JP misses King Bob-omb defeated dialog "116", meaning that the boss music will still
|
|
|
|
//! play after King Bob-omb is defeated until BOB loads it's music after the star cutscene
|
|
|
|
s16 dialogBossStop[] = { 17, 115, 118, 152 };
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
s16 i;
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
for (i = 0; i < (s16) ARRAY_COUNT(dialogBossStart); i++) {
|
|
|
|
if (dialogBossStart[i] == dialogID) {
|
|
|
|
sequence_player_unlower(0, 60);
|
2019-08-25 04:46:40 +00:00
|
|
|
play_music(0, SEQUENCE_ARGS(4, SEQ_EVENT_BOSS), 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
for (i = 0; i < (s16) ARRAY_COUNT(dialogRaceSound); i++) {
|
|
|
|
if (dialogRaceSound[i] == dialogID && gDialogLineNum == 1) {
|
2019-08-25 04:46:40 +00:00
|
|
|
play_race_fanfare();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
for (i = 0; i < (s16) ARRAY_COUNT(dialogStarSound); i++) {
|
|
|
|
if (dialogStarSound[i] == dialogID && gDialogLineNum == 1) {
|
|
|
|
play_sound(SOUND_MENU_STAR_SOUND, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
for (i = 0; i < (s16) ARRAY_COUNT(dialogBossStop); i++) {
|
|
|
|
if (dialogBossStop[i] == dialogID) {
|
|
|
|
sequence_player_fade_out(0, 1);
|
2019-08-25 04:46:40 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
s16 gMenuMode = -1;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
u8 gEndCutsceneStrEn0[] = { TEXT_FILE_MARIO_EXCLAMATION };
|
|
|
|
u8 gEndCutsceneStrEn1[] = { TEXT_POWER_STARS_RESTORED };
|
|
|
|
u8 gEndCutsceneStrEn2[] = { TEXT_THANKS_TO_YOU };
|
|
|
|
u8 gEndCutsceneStrEn3[] = { TEXT_THANK_YOU_MARIO };
|
|
|
|
u8 gEndCutsceneStrEn4[] = { TEXT_SOMETHING_SPECIAL };
|
2019-10-05 19:08:05 +00:00
|
|
|
u8 gEndCutsceneStrEn5[] = { TEXT_LISTEN_EVERYBODY };
|
2019-08-25 04:46:40 +00:00
|
|
|
u8 gEndCutsceneStrEn6[] = { TEXT_LETS_HAVE_CAKE };
|
|
|
|
u8 gEndCutsceneStrEn7[] = { TEXT_FOR_MARIO };
|
|
|
|
u8 gEndCutsceneStrEn8[] = { TEXT_FILE_MARIO_QUESTION };
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
u8 *gEndCutsceneStringsEn[] = {
|
|
|
|
gEndCutsceneStrEn0,
|
|
|
|
gEndCutsceneStrEn1,
|
|
|
|
gEndCutsceneStrEn2,
|
|
|
|
gEndCutsceneStrEn3,
|
|
|
|
gEndCutsceneStrEn4,
|
|
|
|
gEndCutsceneStrEn5,
|
|
|
|
gEndCutsceneStrEn6,
|
|
|
|
gEndCutsceneStrEn7,
|
|
|
|
// This [8] string is actually unused. In the cutscene handler, the developers do not
|
|
|
|
// set the 8th one, but use the first string again at the very end, so Peach ends up
|
|
|
|
// saying "Mario!" twice. It is likely that she was originally meant to say "Mario?" at
|
|
|
|
// the end but the developers changed their mind, possibly because the line recorded
|
|
|
|
// sounded more like an exclamation than a question.
|
|
|
|
gEndCutsceneStrEn8,
|
|
|
|
NULL
|
|
|
|
};
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
u8 gEndCutsceneStrFr0[] = { TEXT_FILE_MARIO_EXCLAMATION };
|
|
|
|
u8 gEndCutsceneStrFr1[] = { TEXT_POWER_STARS_RESTORED_FR };
|
|
|
|
u8 gEndCutsceneStrFr2[] = { TEXT_THANKS_TO_YOU_FR };
|
|
|
|
u8 gEndCutsceneStrFr3[] = { TEXT_THANK_YOU_MARIO_FR };
|
|
|
|
u8 gEndCutsceneStrFr4[] = { TEXT_SOMETHING_SPECIAL_FR };
|
|
|
|
u8 gEndCutsceneStrFr5[] = { TEXT_COME_ON_EVERYBODY_FR };
|
|
|
|
u8 gEndCutsceneStrFr6[] = { TEXT_LETS_HAVE_CAKE_FR };
|
|
|
|
u8 gEndCutsceneStrFr7[] = { TEXT_FOR_MARIO_FR };
|
|
|
|
u8 gEndCutsceneStrFr8[] = { TEXT_FILE_MARIO_QUESTION };
|
|
|
|
|
|
|
|
u8 *gEndCutsceneStringsFr[] = {
|
2019-09-01 19:50:50 +00:00
|
|
|
gEndCutsceneStrFr0,
|
|
|
|
gEndCutsceneStrFr1,
|
|
|
|
gEndCutsceneStrFr2,
|
|
|
|
gEndCutsceneStrFr3,
|
|
|
|
gEndCutsceneStrFr4,
|
|
|
|
gEndCutsceneStrFr5,
|
|
|
|
gEndCutsceneStrFr6,
|
|
|
|
gEndCutsceneStrFr7,
|
|
|
|
gEndCutsceneStrFr8,
|
|
|
|
NULL
|
2019-08-25 04:46:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
u8 gEndCutsceneStrDe0[] = { TEXT_FILE_MARIO_EXCLAMATION };
|
|
|
|
u8 gEndCutsceneStrDe1[] = { TEXT_POWER_STARS_RESTORED_DE };
|
|
|
|
u8 gEndCutsceneStrDe2[] = { TEXT_THANKS_TO_YOU_DE };
|
|
|
|
u8 gEndCutsceneStrDe3[] = { TEXT_THANK_YOU_MARIO_DE };
|
|
|
|
u8 gEndCutsceneStrDe4[] = { TEXT_SOMETHING_SPECIAL_DE };
|
|
|
|
u8 gEndCutsceneStrDe5[] = { TEXT_COME_ON_EVERYBODY_DE };
|
|
|
|
u8 gEndCutsceneStrDe6[] = { TEXT_LETS_HAVE_CAKE_DE };
|
|
|
|
u8 gEndCutsceneStrDe7[] = { TEXT_FOR_MARIO_DE };
|
|
|
|
u8 gEndCutsceneStrDe8[] = { TEXT_FILE_MARIO_QUESTION };
|
|
|
|
|
|
|
|
u8 *gEndCutsceneStringsDe[] = {
|
2019-09-01 19:50:50 +00:00
|
|
|
gEndCutsceneStrDe0,
|
|
|
|
gEndCutsceneStrDe1,
|
|
|
|
gEndCutsceneStrDe2,
|
|
|
|
gEndCutsceneStrDe3,
|
|
|
|
gEndCutsceneStrDe4,
|
|
|
|
gEndCutsceneStrDe5,
|
|
|
|
gEndCutsceneStrDe6,
|
|
|
|
gEndCutsceneStrDe7,
|
|
|
|
gEndCutsceneStrDe8,
|
|
|
|
NULL
|
2019-08-25 04:46:40 +00:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
u16 gCutsceneMsgFade = 0;
|
|
|
|
s16 gCutsceneMsgIndex = -1;
|
|
|
|
s16 gCutsceneMsgDuration = -1;
|
|
|
|
s16 gCutsceneMsgTimer = 0;
|
2020-01-03 15:38:57 +00:00
|
|
|
s8 gDialogCameraAngleIndex = CAM_SELECTION_MARIO;
|
2019-10-05 19:08:05 +00:00
|
|
|
s8 gDialogCourseActNum = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
#ifdef VERSION_JP
|
|
|
|
#define DIAG_VAL1 20
|
|
|
|
#define DIAG_VAL3 130
|
|
|
|
#define DIAG_VAL4 4
|
|
|
|
#else
|
|
|
|
#define DIAG_VAL1 16
|
|
|
|
#define DIAG_VAL3 132 // US & EU
|
|
|
|
#define DIAG_VAL4 5
|
|
|
|
#endif
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
#define DIAG_VAL2 238
|
|
|
|
#else
|
|
|
|
#define DIAG_VAL2 240 // JP & US
|
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_dialog_entries(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
s8 lowerBound;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
void **dialogTable;
|
|
|
|
struct DialogEntry *dialog;
|
|
|
|
#ifdef VERSION_US
|
2019-10-05 19:08:05 +00:00
|
|
|
s8 lowerBound;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
gInGameLanguage = eu_get_language();
|
|
|
|
switch (gInGameLanguage) {
|
|
|
|
case LANGUAGE_ENGLISH:
|
|
|
|
dialogTable = segmented_to_virtual(dialog_table_eu_en);
|
|
|
|
break;
|
|
|
|
case LANGUAGE_FRENCH:
|
|
|
|
dialogTable = segmented_to_virtual(dialog_table_eu_fr);
|
|
|
|
break;
|
|
|
|
case LANGUAGE_GERMAN:
|
|
|
|
dialogTable = segmented_to_virtual(dialog_table_eu_de);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#else
|
2019-09-01 19:50:50 +00:00
|
|
|
dialogTable = segmented_to_virtual(seg2_dialog_table);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
dialog = segmented_to_virtual(dialogTable[gDialogID]);
|
|
|
|
|
|
|
|
// if the dialog entry is invalid, set the ID to -1.
|
|
|
|
if (segmented_to_virtual(NULL) == dialog) {
|
|
|
|
gDialogID = -1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
gDialogX = 0;
|
|
|
|
gDialogY = 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
switch (gDialogBoxState) {
|
|
|
|
case DIALOG_STATE_OPENING:
|
|
|
|
if (gDialogBoxOpenTimer == DEFAULT_DIALOG_BOX_ANGLE) {
|
|
|
|
play_dialog_sound(gDialogID);
|
2019-10-05 19:08:05 +00:00
|
|
|
play_sound(SOUND_MENU_MESSAGE_APPEAR, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (gDialogBoxType == DIALOG_TYPE_ROTATE) {
|
|
|
|
gDialogBoxOpenTimer -= 7.5;
|
|
|
|
gDialogBoxScale -= 1.5;
|
|
|
|
} else {
|
|
|
|
gDialogBoxOpenTimer -= 10.0;
|
|
|
|
gDialogBoxScale -= 2.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gDialogBoxOpenTimer == 0.0f) {
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogBoxState = DIALOG_STATE_VERTICAL;
|
|
|
|
gDialogLineNum = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2020-03-02 03:42:52 +00:00
|
|
|
#if !defined(VERSION_JP) && !defined(VERSION_SH)
|
2019-10-05 19:08:05 +00:00
|
|
|
lowerBound = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
break;
|
2019-10-05 19:08:05 +00:00
|
|
|
case DIALOG_STATE_VERTICAL:
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogBoxOpenTimer = 0.0f;
|
|
|
|
|
|
|
|
if ((gPlayer3Controller->buttonPressed & A_BUTTON)
|
|
|
|
|| (gPlayer3Controller->buttonPressed & B_BUTTON)) {
|
|
|
|
if (gLastDialogPageStrPos == -1) {
|
2019-10-05 19:08:05 +00:00
|
|
|
handle_special_dialog_text(gDialogID);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogBoxState = DIALOG_STATE_CLOSING;
|
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogBoxState = DIALOG_STATE_HORIZONTAL;
|
|
|
|
play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
2020-03-02 03:42:52 +00:00
|
|
|
#if !defined(VERSION_JP) && !defined(VERSION_SH)
|
2019-10-05 19:08:05 +00:00
|
|
|
lowerBound = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
break;
|
2019-10-05 19:08:05 +00:00
|
|
|
case DIALOG_STATE_HORIZONTAL:
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogScrollOffsetY += dialog->linesPerBox * 2;
|
|
|
|
|
|
|
|
if (gDialogScrollOffsetY >= dialog->linesPerBox * DIAG_VAL1) {
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogTextPos = gLastDialogPageStrPos;
|
|
|
|
gDialogBoxState = DIALOG_STATE_VERTICAL;
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogScrollOffsetY = 0;
|
|
|
|
}
|
2020-03-02 03:42:52 +00:00
|
|
|
#if !defined(VERSION_JP) && !defined(VERSION_SH)
|
2019-10-05 19:08:05 +00:00
|
|
|
lowerBound = (gDialogScrollOffsetY / 16) + 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
case DIALOG_STATE_CLOSING:
|
|
|
|
if (gDialogBoxOpenTimer == 20.0f) {
|
|
|
|
level_set_transition(0, 0);
|
2019-10-05 19:08:05 +00:00
|
|
|
play_sound(SOUND_MENU_MESSAGE_DISAPPEAR, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gDialogBoxType == DIALOG_TYPE_ZOOM) {
|
2020-01-03 15:38:57 +00:00
|
|
|
trigger_cutscene_dialog(2);
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogResponse = gDialogLineNum;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gDialogBoxOpenTimer = gDialogBoxOpenTimer + 10.0f;
|
|
|
|
gDialogBoxScale = gDialogBoxScale + 2.0f;
|
|
|
|
|
|
|
|
if (gDialogBoxOpenTimer == DEFAULT_DIALOG_BOX_ANGLE) {
|
|
|
|
gDialogBoxState = DIALOG_STATE_OPENING;
|
|
|
|
gDialogID = -1;
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogTextPos = 0;
|
|
|
|
gLastDialogResponse = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
gLastDialogPageStrPos = 0;
|
|
|
|
gDialogResponse = 0;
|
|
|
|
}
|
2020-03-02 03:42:52 +00:00
|
|
|
#if !defined(VERSION_JP) && !defined(VERSION_SH)
|
2019-10-05 19:08:05 +00:00
|
|
|
lowerBound = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
render_dialog_box_type(dialog, dialog->linesPerBox);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, ensure_nonnegative(dialog->leftOffset),
|
|
|
|
ensure_nonnegative(DIAG_VAL2 - dialog->width),
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
ensure_nonnegative(dialog->leftOffset + DIAG_VAL3 / gDialogBoxScale),
|
|
|
|
ensure_nonnegative((240 - dialog->width) + ((dialog->linesPerBox * 80) / DIAG_VAL4) / gDialogBoxScale));
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
ensure_nonnegative(DIAG_VAL3 + dialog->leftOffset),
|
|
|
|
ensure_nonnegative(240 + ((dialog->linesPerBox * 80) / DIAG_VAL4) - dialog->width));
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2020-03-02 03:42:52 +00:00
|
|
|
#if defined(VERSION_JP) || defined(VERSION_SH)
|
2019-10-05 19:08:05 +00:00
|
|
|
handle_dialog_text_and_pages(0, dialog);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
handle_dialog_text_and_pages(0, dialog, lowerBound);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gLastDialogPageStrPos == -1 && gLastDialogResponse == 1) {
|
|
|
|
render_dialog_triangle_choice();
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2020-02-03 05:51:26 +00:00
|
|
|
#ifdef VERSION_EU
|
|
|
|
#undef BORDER_HEIGHT
|
|
|
|
#define BORDER_HEIGHT 8
|
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 2, 2, SCREEN_WIDTH - BORDER_HEIGHT/2, SCREEN_HEIGHT - BORDER_HEIGHT/2);
|
2020-02-03 05:51:26 +00:00
|
|
|
#ifdef VERSION_EU
|
|
|
|
#undef BORDER_HEIGHT
|
|
|
|
#define BORDER_HEIGHT 1
|
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gLastDialogPageStrPos != -1 && gDialogBoxState == DIALOG_STATE_VERTICAL) {
|
|
|
|
render_dialog_string_color(dialog->linesPerBox);
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
// Calls a gMenuMode value defined by render_menus_and_dialogs cases
|
|
|
|
void set_menu_mode(s16 mode) {
|
|
|
|
if (gMenuMode == -1) {
|
|
|
|
gMenuMode = mode;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void reset_cutscene_msg_fade(void) {
|
|
|
|
gCutsceneMsgFade = 0;
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void dl_rgba16_begin_cutscene_msg_fade(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
|
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gCutsceneMsgFade);
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void dl_rgba16_stop_cutscene_msg_fade(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gCutsceneMsgFade < 250) {
|
2019-08-25 04:46:40 +00:00
|
|
|
gCutsceneMsgFade += 25;
|
2019-09-01 19:50:50 +00:00
|
|
|
} else {
|
2019-08-25 04:46:40 +00:00
|
|
|
gCutsceneMsgFade = 255;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
u8 ascii_to_credits_char(u8 c) {
|
2019-09-01 19:50:50 +00:00
|
|
|
if (c >= 'A' && c <= 'Z') {
|
2019-08-25 04:46:40 +00:00
|
|
|
return (c - ('A' - 0xA));
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (c >= 'a' && c <= 'z') { // remap lower to upper case
|
2019-08-25 04:46:40 +00:00
|
|
|
return (c - ('a' - 0xA));
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (c == ' ') {
|
2019-10-05 19:08:05 +00:00
|
|
|
return GLOBAL_CHAR_SPACE;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
|
|
|
if (c == '.') {
|
2019-08-25 04:46:40 +00:00
|
|
|
return 0x24;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
|
|
|
if (c == '3') {
|
2019-08-25 04:46:40 +00:00
|
|
|
return ASCII_TO_DIALOG('3');
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
|
|
|
if (c == '4') {
|
2019-08-25 04:46:40 +00:00
|
|
|
return ASCII_TO_DIALOG('4');
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
|
|
|
if (c == '6') {
|
2019-08-25 04:46:40 +00:00
|
|
|
return ASCII_TO_DIALOG('6');
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
return GLOBAL_CHAR_SPACE;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void print_credits_str_ascii(s16 x, s16 y, const char *str) {
|
|
|
|
s32 pos = 0;
|
|
|
|
u8 c = str[pos];
|
|
|
|
u8 creditStr[100];
|
|
|
|
|
|
|
|
while (c != 0) {
|
|
|
|
creditStr[pos++] = ascii_to_credits_char(c);
|
|
|
|
c = str[pos];
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
creditStr[pos] = GLOBAR_CHAR_TERMINATOR;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
print_credits_string(x, y, creditStr);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void set_cutscene_message(s16 xOffset, s16 yOffset, s16 msgIndex, s16 msgDuration) {
|
|
|
|
// is message done printing?
|
|
|
|
if (gCutsceneMsgIndex == -1) {
|
|
|
|
gCutsceneMsgIndex = msgIndex;
|
|
|
|
gCutsceneMsgDuration = msgDuration;
|
|
|
|
gCutsceneMsgTimer = 0;
|
|
|
|
gCutsceneMsgXOffset = xOffset;
|
|
|
|
gCutsceneMsgYOffset = yOffset;
|
|
|
|
gCutsceneMsgFade = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void do_cutscene_handler(void) {
|
|
|
|
s16 x;
|
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
// is a cutscene playing? do not perform this handler's actions if so.
|
|
|
|
if (gCutsceneMsgIndex == -1) {
|
2019-08-25 04:46:40 +00:00
|
|
|
return;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_ortho_matrix();
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gCutsceneMsgFade);
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
switch (eu_get_language()) {
|
|
|
|
case LANGUAGE_ENGLISH:
|
2019-09-01 19:50:50 +00:00
|
|
|
x = get_str_x_pos_from_center(gCutsceneMsgXOffset, gEndCutsceneStringsEn[gCutsceneMsgIndex], 10.0f);
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(x, 240 - gCutsceneMsgYOffset, gEndCutsceneStringsEn[gCutsceneMsgIndex]);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
case LANGUAGE_FRENCH:
|
2019-09-01 19:50:50 +00:00
|
|
|
x = get_str_x_pos_from_center(gCutsceneMsgXOffset, gEndCutsceneStringsFr[gCutsceneMsgIndex], 10.0f);
|
2020-02-03 05:51:26 +00:00
|
|
|
print_generic_string(x, 240 - gCutsceneMsgYOffset, gEndCutsceneStringsFr[gCutsceneMsgIndex]);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
case LANGUAGE_GERMAN:
|
2019-09-01 19:50:50 +00:00
|
|
|
x = get_str_x_pos_from_center(gCutsceneMsgXOffset, gEndCutsceneStringsDe[gCutsceneMsgIndex], 10.0f);
|
2020-02-03 05:51:26 +00:00
|
|
|
print_generic_string(x, 240 - gCutsceneMsgYOffset, gEndCutsceneStringsDe[gCutsceneMsgIndex]);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
}
|
2020-03-02 03:42:52 +00:00
|
|
|
#else
|
|
|
|
#if defined(VERSION_SH)
|
|
|
|
// get the x coordinate of where the cutscene string starts.
|
|
|
|
x = get_str_x_pos_from_center_scale(gCutsceneMsgXOffset, gEndCutsceneStringsEn[gCutsceneMsgIndex], 10.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-09-01 19:50:50 +00:00
|
|
|
// get the x coordinate of where the cutscene string starts.
|
|
|
|
x = get_str_x_pos_from_center(gCutsceneMsgXOffset, gEndCutsceneStringsEn[gCutsceneMsgIndex], 10.0f);
|
2020-03-02 03:42:52 +00:00
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(x, 240 - gCutsceneMsgYOffset, gEndCutsceneStringsEn[gCutsceneMsgIndex]);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
// if the timing variable is less than 5, increment
|
|
|
|
// the fade until we are at full opacity.
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gCutsceneMsgTimer < 5) {
|
2019-08-25 04:46:40 +00:00
|
|
|
gCutsceneMsgFade += 50;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
// if the cutscene frame length + the fade-in counter is
|
|
|
|
// less than the timer, it means we have exceeded the
|
|
|
|
// time that the message is supposed to remain on
|
|
|
|
// screen. if (message_duration = 50) and (msg_timer = 55)
|
|
|
|
// then after the first 5 frames, the message will remain
|
|
|
|
// on screen for another 50 frames until it starts fading.
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gCutsceneMsgDuration + 5 < gCutsceneMsgTimer) {
|
2019-08-25 04:46:40 +00:00
|
|
|
gCutsceneMsgFade -= 50;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
// like the first check, it takes 5 frames to fade out, so
|
|
|
|
// perform a + 10 to account for the earlier check (10-5=5).
|
|
|
|
if (gCutsceneMsgDuration + 10 < gCutsceneMsgTimer) {
|
|
|
|
gCutsceneMsgIndex = -1;
|
|
|
|
gCutsceneMsgFade = 0;
|
|
|
|
gCutsceneMsgTimer = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gCutsceneMsgTimer++;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef VERSION_JP
|
|
|
|
extern Gfx castle_grounds_seg7_us_dl_0700F2E8[];
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef VERSION_JP
|
|
|
|
#define PEACH_MESSAGE_TIMER 170
|
|
|
|
#else
|
|
|
|
#define PEACH_MESSAGE_TIMER 250
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef VERSION_JP
|
|
|
|
#define STR_X 53
|
|
|
|
#define STR_Y 136
|
|
|
|
#else
|
|
|
|
#define STR_X 38
|
|
|
|
#define STR_Y 142
|
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
|
2019-08-25 04:46:40 +00:00
|
|
|
// "Dear Mario" message handler
|
|
|
|
void print_peach_letter_message(void) {
|
|
|
|
void **dialogTable;
|
|
|
|
struct DialogEntry *dialog;
|
|
|
|
u8 *str;
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
gInGameLanguage = eu_get_language();
|
|
|
|
switch (gInGameLanguage) {
|
|
|
|
case LANGUAGE_ENGLISH:
|
|
|
|
dialogTable = segmented_to_virtual(dialog_table_eu_en);
|
|
|
|
break;
|
|
|
|
case LANGUAGE_FRENCH:
|
|
|
|
dialogTable = segmented_to_virtual(dialog_table_eu_fr);
|
|
|
|
break;
|
|
|
|
case LANGUAGE_GERMAN:
|
|
|
|
dialogTable = segmented_to_virtual(dialog_table_eu_de);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#else
|
2019-09-01 19:50:50 +00:00
|
|
|
dialogTable = segmented_to_virtual(seg2_dialog_table);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
dialog = segmented_to_virtual(dialogTable[gDialogID]);
|
|
|
|
|
|
|
|
str = segmented_to_virtual(dialog->str);
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, 97.0f, 118.0f, 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gCutsceneMsgFade);
|
|
|
|
gSPDisplayList(gDisplayListHead++, castle_grounds_seg7_dl_0700EA58);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 20, 20, 20, gCutsceneMsgFade);
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(STR_X, STR_Y, str);
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_JP
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
2019-10-05 19:08:05 +00:00
|
|
|
#endif
|
2019-08-25 04:46:40 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
2019-10-05 19:08:05 +00:00
|
|
|
#ifndef VERSION_JP
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
2019-09-01 19:50:50 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 200, 80, 120, gCutsceneMsgFade);
|
|
|
|
gSPDisplayList(gDisplayListHead++, castle_grounds_seg7_us_dl_0700F2E8);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// at the start/end of message, reset the fade.
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gCutsceneMsgTimer == 0) {
|
2019-08-25 04:46:40 +00:00
|
|
|
gCutsceneMsgFade = 0;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
// we're less than 20 increments, so increase the fade.
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gCutsceneMsgTimer < 20) {
|
2019-08-25 04:46:40 +00:00
|
|
|
gCutsceneMsgFade += 10;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
// we're after PEACH_MESSAGE_TIMER increments, so decrease the fade.
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gCutsceneMsgTimer > PEACH_MESSAGE_TIMER) {
|
2019-08-25 04:46:40 +00:00
|
|
|
gCutsceneMsgFade -= 10;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
// 20 increments after the start of the decrease, we're
|
|
|
|
// back where we are, so reset everything at the end.
|
|
|
|
if (gCutsceneMsgTimer > (PEACH_MESSAGE_TIMER + 20)) {
|
|
|
|
gCutsceneMsgIndex = -1;
|
2019-09-01 19:50:50 +00:00
|
|
|
gCutsceneMsgFade = 0; //! uselessly reset since the next execution will just set it to 0 again.
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogID = -1;
|
|
|
|
gCutsceneMsgTimer = 0;
|
|
|
|
return; // return to avoid incrementing the timer
|
|
|
|
}
|
|
|
|
|
|
|
|
gCutsceneMsgTimer++;
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
/**
|
|
|
|
* Renders the cannon reticle when Mario is inside a cannon.
|
|
|
|
* Formed by four triangles.
|
|
|
|
*/
|
|
|
|
void render_hud_cannon_reticle(void) {
|
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, 160.0f, 120.0f, 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
gDPSetEnvColor(gDisplayListHead++, 50, 50, 50, 180);
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, -20.0f, -8.0f, 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, 20.0f, 8.0f, 0);
|
|
|
|
create_dl_rotation_matrix(MENU_MTX_NOPUSH, 180.0f, 0, 0, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, 8.0f, -20.0f, 0);
|
|
|
|
create_dl_rotation_matrix(MENU_MTX_NOPUSH, DEFAULT_DIALOG_BOX_ANGLE, 0, 0, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, -8.0f, 20.0f, 0);
|
|
|
|
create_dl_rotation_matrix(MENU_MTX_NOPUSH, -DEFAULT_DIALOG_BOX_ANGLE, 0, 0, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void reset_red_coins_collected(void) {
|
|
|
|
gRedCoinsCollected = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void change_dialog_camera_angle(void) {
|
2020-01-03 15:38:57 +00:00
|
|
|
if (cam_select_alt_mode(0) == CAM_SELECTION_MARIO) {
|
|
|
|
gDialogCameraAngleIndex = CAM_SELECTION_MARIO;
|
2019-09-01 19:50:50 +00:00
|
|
|
} else {
|
2020-01-03 15:38:57 +00:00
|
|
|
gDialogCameraAngleIndex = CAM_SELECTION_FIXED;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void shade_screen(void) {
|
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, 0, 240.0f, 0);
|
|
|
|
create_dl_scale_matrix(MENU_MTX_NOPUSH, 2.6f, 3.4f, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 110);
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_draw_text_bg_box);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void print_animated_red_coin(s16 x, s16 y) {
|
2019-08-25 04:46:40 +00:00
|
|
|
s32 timer = gGlobalTimer;
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, x, y, 0);
|
|
|
|
create_dl_scale_matrix(MENU_MTX_NOPUSH, 0.2f, 0.2f, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDPSetRenderMode(gDisplayListHead++, G_RM_TEX_EDGE, G_RM_TEX_EDGE2);
|
|
|
|
|
|
|
|
switch (timer & 6) {
|
|
|
|
case 0:
|
|
|
|
gSPDisplayList(gDisplayListHead++, coin_seg3_dl_03007940);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
gSPDisplayList(gDisplayListHead++, coin_seg3_dl_03007968);
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
gSPDisplayList(gDisplayListHead++, coin_seg3_dl_03007990);
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
gSPDisplayList(gDisplayListHead++, coin_seg3_dl_030079B8);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_pause_red_coins(void) {
|
|
|
|
s8 x;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
for (x = 0; x < gRedCoinsCollected; x++) {
|
|
|
|
print_animated_red_coin(290 - x * 20, 16);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
u8 gTextCourseArr[][7] = { // D_802FDA10
|
|
|
|
{ TEXT_COURSE },
|
|
|
|
{ TEXT_COURSE_FR },
|
|
|
|
{ TEXT_COURSE_DE }
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef VERSION_JP
|
|
|
|
#define CRS_NUM_X1 93
|
|
|
|
#else
|
|
|
|
#define CRS_NUM_X1 100
|
|
|
|
#endif
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
#define TXT_STAR_X 89
|
|
|
|
#define ACT_NAME_X 107
|
|
|
|
#define LVL_NAME_X 108
|
2019-10-05 19:08:05 +00:00
|
|
|
#define MYSCORE_X 48
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
|
|
|
#define TXT_STAR_X 98
|
|
|
|
#define ACT_NAME_X 116
|
|
|
|
#define LVL_NAME_X 117
|
2019-10-05 19:08:05 +00:00
|
|
|
#define MYSCORE_X 62
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
|
|
|
|
void render_pause_my_score_coins(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
u8 textMyScore[][10] = {
|
|
|
|
{ TEXT_MY_SCORE },
|
|
|
|
{ TEXT_MY_SCORE_FR },
|
|
|
|
{ TEXT_MY_SCORE_DE }
|
|
|
|
};
|
|
|
|
#define textMyScore textMyScore[gInGameLanguage]
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-09-01 19:50:50 +00:00
|
|
|
u8 textCourse[] = { TEXT_COURSE };
|
|
|
|
u8 textMyScore[] = { TEXT_MY_SCORE };
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
u8 textStar[] = { TEXT_STAR };
|
|
|
|
u8 textUnfilledStar[] = { TEXT_UNFILLED_STAR };
|
|
|
|
|
|
|
|
u8 strCourseNum[4];
|
2019-12-02 02:52:53 +00:00
|
|
|
void **courseNameTbl;
|
|
|
|
u8 *courseName;
|
2019-08-25 04:46:40 +00:00
|
|
|
void **actNameTbl;
|
|
|
|
u8 *actName;
|
|
|
|
u8 courseIndex;
|
|
|
|
u8 starFlags;
|
|
|
|
|
|
|
|
#ifndef VERSION_EU
|
2019-12-02 02:52:53 +00:00
|
|
|
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
2019-08-25 04:46:40 +00:00
|
|
|
actNameTbl = segmented_to_virtual(seg2_act_name_table);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
courseIndex = gCurrCourseNum - 1;
|
|
|
|
starFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1);
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
switch (gInGameLanguage) {
|
|
|
|
case LANGUAGE_ENGLISH:
|
|
|
|
actNameTbl = segmented_to_virtual(act_name_table_eu_en);
|
2019-12-02 02:52:53 +00:00
|
|
|
courseNameTbl = segmented_to_virtual(course_name_table_eu_en);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
case LANGUAGE_FRENCH:
|
|
|
|
actNameTbl = segmented_to_virtual(act_name_table_eu_fr);
|
2019-12-02 02:52:53 +00:00
|
|
|
courseNameTbl = segmented_to_virtual(course_name_table_eu_fr);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
case LANGUAGE_GERMAN:
|
|
|
|
actNameTbl = segmented_to_virtual(act_name_table_eu_de);
|
2019-12-02 02:52:53 +00:00
|
|
|
courseNameTbl = segmented_to_virtual(course_name_table_eu_de);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (courseIndex < COURSE_STAGES_COUNT) {
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_my_score_coins(1, gCurrSaveFileNum - 1, courseIndex, 178, 103);
|
|
|
|
print_hud_my_score_stars(gCurrSaveFileNum - 1, courseIndex, 118, 103);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (courseIndex < COURSE_STAGES_COUNT && save_file_get_course_star_count(gCurrSaveFileNum - 1, courseIndex) != 0) {
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(MYSCORE_X, 121, textMyScore);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-12-02 02:52:53 +00:00
|
|
|
courseName = segmented_to_virtual(courseNameTbl[courseIndex]);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (courseIndex < COURSE_STAGES_COUNT) {
|
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(48, 157, gTextCourseArr[gInGameLanguage]);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(63, 157, textCourse);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
int_to_str(gCurrCourseNum, strCourseNum);
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(get_string_width(gTextCourseArr[gInGameLanguage]) + 51, 157, strCourseNum);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(CRS_NUM_X1, 157, strCourseNum);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
actName = segmented_to_virtual(actNameTbl[(gCurrCourseNum - 1) * 6 + gDialogCourseActNum - 1]);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (starFlags & (1 << (gDialogCourseActNum - 1))) {
|
|
|
|
print_generic_string(TXT_STAR_X, 140, textStar);
|
2019-09-01 19:50:50 +00:00
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(TXT_STAR_X, 140, textUnfilledStar);
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(ACT_NAME_X, 140, actName);
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifndef VERSION_JP
|
2019-12-02 02:52:53 +00:00
|
|
|
print_generic_string(LVL_NAME_X, 157, &courseName[3]);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#ifndef VERSION_JP
|
|
|
|
else {
|
|
|
|
#ifdef VERSION_US
|
2019-12-02 02:52:53 +00:00
|
|
|
print_generic_string(94, 157, &courseName[3]);
|
2019-08-25 04:46:40 +00:00
|
|
|
#elif defined(VERSION_EU)
|
2019-12-02 02:52:53 +00:00
|
|
|
print_generic_string(get_str_x_pos_from_center(159, &courseName[3], 10.0f), 157, &courseName[3]);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#else
|
2019-12-02 02:52:53 +00:00
|
|
|
print_generic_string(117, 157, &courseName[3]);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VERSION_JP
|
|
|
|
#define TXT1_X 4
|
|
|
|
#define TXT2_X 116
|
|
|
|
#define Y_VAL7 0
|
|
|
|
#else
|
|
|
|
#define TXT1_X 3
|
|
|
|
#define TXT2_X 119
|
|
|
|
#define Y_VAL7 2
|
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_pause_camera_options(s16 x, s16 y, s8 *index, s16 xIndex) {
|
2019-08-25 04:46:40 +00:00
|
|
|
u8 textLakituMario[] = { TEXT_LAKITU_MARIO };
|
|
|
|
u8 textLakituStop[] = { TEXT_LAKITU_STOP };
|
|
|
|
#ifdef VERSION_EU
|
2019-09-01 19:50:50 +00:00
|
|
|
u8 textNormalUpClose[][20] = {
|
|
|
|
{ TEXT_NORMAL_UPCLOSE },
|
|
|
|
{ TEXT_NORMAL_UPCLOSE_FR },
|
|
|
|
{ TEXT_NORMAL_UPCLOSE_DE }
|
|
|
|
};
|
2019-08-25 04:46:40 +00:00
|
|
|
u8 textNormalFixed[][17] = {
|
|
|
|
{ TEXT_NORMAL_FIXED },
|
|
|
|
{ TEXT_NORMAL_FIXED_FR },
|
|
|
|
{ TEXT_NORMAL_FIXED_DE },
|
|
|
|
};
|
2019-10-05 19:08:05 +00:00
|
|
|
#define textNormalUpClose textNormalUpClose[gInGameLanguage]
|
|
|
|
#define textNormalFixed textNormalFixed[gInGameLanguage]
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-09-01 19:50:50 +00:00
|
|
|
u8 textNormalUpClose[] = { TEXT_NORMAL_UPCLOSE };
|
|
|
|
u8 textNormalFixed[] = { TEXT_NORMAL_FIXED };
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
handle_menu_scrolling(MENU_SCROLL_HORIZONTAL, index, 1, 2);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(x + 14, y + 2, textLakituMario);
|
|
|
|
print_generic_string(x + TXT1_X, y - 13, textNormalUpClose);
|
|
|
|
print_generic_string(x + 124, y + 2, textLakituStop);
|
|
|
|
print_generic_string(x + TXT2_X, y - 13, textNormalFixed);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, ((index[0] - 1) * xIndex) + x, y + Y_VAL7, 0);
|
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
switch (index[0]) {
|
2019-08-25 04:46:40 +00:00
|
|
|
case 1:
|
2020-01-03 15:38:57 +00:00
|
|
|
cam_select_alt_mode(1);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2020-01-03 15:38:57 +00:00
|
|
|
cam_select_alt_mode(2);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VERSION_JP
|
|
|
|
#define X_VAL8 0
|
|
|
|
#define Y_VAL8 4
|
|
|
|
#else
|
|
|
|
#define X_VAL8 4
|
|
|
|
#define Y_VAL8 2
|
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_pause_course_options(s16 x, s16 y, s8 *index, s16 yIndex) {
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-09-01 19:50:50 +00:00
|
|
|
u8 textContinue[][10] = {
|
|
|
|
{ TEXT_CONTINUE },
|
|
|
|
{ TEXT_CONTINUE_FR },
|
|
|
|
{ TEXT_CONTINUE_DE }
|
|
|
|
};
|
|
|
|
u8 textExitCourse[][15] = {
|
|
|
|
{ TEXT_EXIT_COURSE },
|
|
|
|
{ TEXT_EXIT_COURSE_FR },
|
|
|
|
{ TEXT_EXIT_COURSE_DE }
|
|
|
|
};
|
|
|
|
u8 textCameraAngleR[][24] = {
|
2019-10-05 19:08:05 +00:00
|
|
|
{ TEXT_CAMERA_ANGLE_R },
|
2019-09-01 19:50:50 +00:00
|
|
|
{ TEXT_CAMERA_ANGLE_R_FR },
|
|
|
|
{ TEXT_CAMERA_ANGLE_R_DE }
|
|
|
|
};
|
2019-10-05 19:08:05 +00:00
|
|
|
#define textContinue textContinue[gInGameLanguage]
|
|
|
|
#define textExitCourse textExitCourse[gInGameLanguage]
|
|
|
|
#define textCameraAngleR textCameraAngleR[gInGameLanguage]
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-09-01 19:50:50 +00:00
|
|
|
u8 textContinue[] = { TEXT_CONTINUE };
|
|
|
|
u8 textExitCourse[] = { TEXT_EXIT_COURSE };
|
|
|
|
u8 textCameraAngleR[] = { TEXT_CAMERA_ANGLE_R };
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
handle_menu_scrolling(MENU_SCROLL_VERTICAL, index, 1, 3);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(x + 10, y - 2, textContinue);
|
|
|
|
print_generic_string(x + 10, y - 17, textExitCourse);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (index[0] != 3) {
|
|
|
|
print_generic_string(x + 10, y - 33, textCameraAngleR);
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, x - X_VAL8, (y - ((index[0] - 1) * yIndex)) - Y_VAL8, 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (index[0] == 3) {
|
|
|
|
render_pause_camera_options(x - 42, y - 42, &gDialogCameraAngleIndex, 110);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_pause_castle_menu_box(s16 x, s16 y) {
|
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, x - 78, y - 32, 0);
|
|
|
|
create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.2f, 0.8f, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 105);
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_draw_text_bg_box);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, x + 6, y - 28, 0);
|
|
|
|
create_dl_rotation_matrix(MENU_MTX_NOPUSH, DEFAULT_DIALOG_BOX_ANGLE, 0, 0, 1.0f);
|
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, x - 9, y - 101, 0);
|
|
|
|
create_dl_rotation_matrix(MENU_MTX_NOPUSH, 270.0f, 0, 0, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void highlight_last_course_complete_stars(void) {
|
|
|
|
u8 courseDone;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (gLastCompletedCourseNum == 0) {
|
2019-10-05 19:08:05 +00:00
|
|
|
courseDone = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
courseDone = gLastCompletedCourseNum - 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (courseDone >= COURSE_STAGES_COUNT) {
|
|
|
|
courseDone = COURSE_STAGES_COUNT;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogLineNum = courseDone;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void print_hud_pause_colorful_str(void) {
|
|
|
|
u8 textPause[] = { TEXT_PAUSE };
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, get_str_x_pos_from_center_scale(160, textPause, 12.0f), 81, textPause);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, 123, 81, textPause);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_pause_castle_course_stars(s16 x, s16 y, s16 fileNum, s16 courseNum) {
|
|
|
|
s16 hasStar = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
u8 str[COURSE_STAGES_COUNT * 2];
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
u8 textStar[] = { TEXT_STAR };
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
u8 starFlags = save_file_get_star_flags(fileNum, courseNum);
|
|
|
|
u16 starCount = save_file_get_course_star_count(fileNum, courseNum);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
u16 nextStar = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (starFlags & 0x40) {
|
|
|
|
starCount--;
|
|
|
|
print_generic_string(x + 89, y - 5, textStar);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
while (hasStar != starCount) {
|
|
|
|
if (starFlags & (1 << nextStar)) {
|
|
|
|
str[nextStar * 2] = DIALOG_CHAR_STAR_FILLED;
|
|
|
|
hasStar++;
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
str[nextStar * 2] = DIALOG_CHAR_STAR_OPEN;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
str[nextStar * 2 + 1] = DIALOG_CHAR_SPACE;
|
|
|
|
nextStar++;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (starCount == nextStar && starCount != 6) {
|
|
|
|
str[nextStar * 2] = DIALOG_CHAR_STAR_OPEN;
|
|
|
|
str[nextStar * 2 + 1] = DIALOG_CHAR_SPACE;
|
|
|
|
nextStar++;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
str[nextStar * 2] = DIALOG_CHAR_TERMINATOR;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(x + 14, y + 13, str);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_pause_castle_main_strings(s16 x, s16 y) {
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-12-02 02:52:53 +00:00
|
|
|
void **courseNameTbl;
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-12-02 02:52:53 +00:00
|
|
|
void **courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
u8 textCoin[] = { TEXT_COIN };
|
|
|
|
u8 textX[] = { TEXT_VARIABLE_X };
|
|
|
|
#else
|
2019-09-01 19:50:50 +00:00
|
|
|
u8 textCoin[] = { TEXT_COIN_X };
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-12-02 02:52:53 +00:00
|
|
|
void *courseName;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
u8 strVal[8];
|
2019-10-05 19:08:05 +00:00
|
|
|
s16 starNum = gDialogLineNum;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
switch (gInGameLanguage) {
|
|
|
|
case LANGUAGE_ENGLISH:
|
2019-12-02 02:52:53 +00:00
|
|
|
courseNameTbl = segmented_to_virtual(course_name_table_eu_en);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
case LANGUAGE_FRENCH:
|
2019-12-02 02:52:53 +00:00
|
|
|
courseNameTbl = segmented_to_virtual(course_name_table_eu_fr);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
case LANGUAGE_GERMAN:
|
2019-12-02 02:52:53 +00:00
|
|
|
courseNameTbl = segmented_to_virtual(course_name_table_eu_de);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
handle_menu_scrolling(MENU_SCROLL_VERTICAL, &gDialogLineNum, -1, COURSE_STAGES_COUNT + 1);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gDialogLineNum == COURSE_STAGES_COUNT + 1) {
|
|
|
|
gDialogLineNum = 0;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gDialogLineNum == -1) {
|
|
|
|
gDialogLineNum = COURSE_STAGES_COUNT;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gDialogLineNum != COURSE_STAGES_COUNT) {
|
|
|
|
while (save_file_get_course_star_count(gCurrSaveFileNum - 1, gDialogLineNum) == 0) {
|
|
|
|
if (gDialogLineNum >= starNum) {
|
|
|
|
gDialogLineNum++;
|
2019-09-01 19:50:50 +00:00
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogLineNum--;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gDialogLineNum == COURSE_STAGES_COUNT || gDialogLineNum == -1) {
|
|
|
|
gDialogLineNum = COURSE_STAGES_COUNT;
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gDialogLineNum < COURSE_STAGES_COUNT) {
|
2019-12-02 02:52:53 +00:00
|
|
|
courseName = segmented_to_virtual(courseNameTbl[gDialogLineNum]);
|
2019-10-05 19:08:05 +00:00
|
|
|
render_pause_castle_course_stars(x, y, gCurrSaveFileNum - 1, gDialogLineNum);
|
|
|
|
print_generic_string(x + 34, y - 5, textCoin);
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(x + 44, y - 5, textX);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
int_to_str(save_file_get_course_coin_score(gCurrSaveFileNum - 1, gDialogLineNum), strVal);
|
|
|
|
print_generic_string(x + 54, y - 5, strVal);
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-12-02 02:52:53 +00:00
|
|
|
print_generic_string(x - 17, y + 30, courseName);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
u8 textStarX[] = { TEXT_STAR_X };
|
2019-12-02 02:52:53 +00:00
|
|
|
courseName = segmented_to_virtual(courseNameTbl[COURSE_MAX]);
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(x + 40, y + 13, textStarX);
|
|
|
|
int_to_str(save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_BONUS_STAGES - 1, COURSE_MAX - 1), strVal);
|
|
|
|
print_generic_string(x + 60, y + 13, strVal);
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-12-02 02:52:53 +00:00
|
|
|
print_generic_string(get_str_x_pos_from_center(x + 51, courseName, 10.0f), y + 30, courseName);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef VERSION_EU
|
2019-12-02 02:52:53 +00:00
|
|
|
print_generic_string(x - 9, y + 30, courseName);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
s8 gCourseCompleteCoinsEqual = 0;
|
|
|
|
s32 gCourseDoneMenuTimer = 0;
|
|
|
|
s32 gCourseCompleteCoins = 0;
|
|
|
|
s8 gHudFlash = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
s16 render_pause_courses_and_castle(void) {
|
|
|
|
s16 num;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
gInGameLanguage = eu_get_language();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
switch (gDialogBoxState) {
|
|
|
|
case DIALOG_STATE_OPENING:
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogLineNum = 1;
|
|
|
|
gDialogTextAlpha = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
level_set_transition(-1, 0);
|
|
|
|
#ifdef VERSION_JP
|
2019-10-05 19:08:05 +00:00
|
|
|
play_sound(SOUND_MENU_PAUSE, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
play_sound(SOUND_MENU_PAUSE_HIGHPRIO, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
if (gCurrCourseNum >= COURSE_MIN && gCurrCourseNum <= COURSE_MAX) {
|
2019-10-05 19:08:05 +00:00
|
|
|
change_dialog_camera_angle();
|
|
|
|
gDialogBoxState = DIALOG_STATE_VERTICAL;
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
highlight_last_course_complete_stars();
|
|
|
|
gDialogBoxState = DIALOG_STATE_HORIZONTAL;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
break;
|
2019-10-05 19:08:05 +00:00
|
|
|
case DIALOG_STATE_VERTICAL:
|
|
|
|
shade_screen();
|
|
|
|
render_pause_my_score_coins();
|
|
|
|
render_pause_red_coins();
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gMarioStates[0].action & ACT_FLAG_PAUSE_EXIT) {
|
2019-10-05 19:08:05 +00:00
|
|
|
render_pause_course_options(99, 93, &gDialogLineNum, 15);
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
if (gPlayer3Controller->buttonPressed & (A_BUTTON | Z_TRIG | START_BUTTON))
|
|
|
|
#else
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gPlayer3Controller->buttonPressed & A_BUTTON
|
|
|
|
|| gPlayer3Controller->buttonPressed & START_BUTTON)
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
{
|
|
|
|
level_set_transition(0, 0);
|
2019-10-05 19:08:05 +00:00
|
|
|
play_sound(SOUND_MENU_PAUSE_2, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogBoxState = DIALOG_STATE_OPENING;
|
2019-10-05 19:08:05 +00:00
|
|
|
gMenuMode = -1;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gDialogLineNum == 2) {
|
|
|
|
num = gDialogLineNum;
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
num = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
return num;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
break;
|
2019-10-05 19:08:05 +00:00
|
|
|
case DIALOG_STATE_HORIZONTAL:
|
|
|
|
shade_screen();
|
|
|
|
print_hud_pause_colorful_str();
|
|
|
|
render_pause_castle_menu_box(160, 143);
|
|
|
|
render_pause_castle_main_strings(104, 60);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
if (gPlayer3Controller->buttonPressed & (A_BUTTON | Z_TRIG | START_BUTTON))
|
|
|
|
#else
|
2019-09-01 19:50:50 +00:00
|
|
|
if (gPlayer3Controller->buttonPressed & A_BUTTON
|
|
|
|
|| gPlayer3Controller->buttonPressed & START_BUTTON)
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
{
|
|
|
|
level_set_transition(0, 0);
|
2019-10-05 19:08:05 +00:00
|
|
|
play_sound(SOUND_MENU_PAUSE_2, gDefaultSoundArgs);
|
|
|
|
gMenuMode = -1;
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogBoxState = DIALOG_STATE_OPENING;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gDialogTextAlpha < 250) {
|
|
|
|
gDialogTextAlpha += 25;
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VERSION_JP
|
|
|
|
#define TXT_HISCORE_X 112
|
|
|
|
#define TXT_HISCORE_Y 48
|
|
|
|
#define TXT_CONGRATS_X 60
|
|
|
|
#else
|
|
|
|
#define TXT_HISCORE_X 109
|
|
|
|
#define TXT_HISCORE_Y 36
|
|
|
|
#define TXT_CONGRATS_X 70
|
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
#define HUD_PRINT_HISCORE 0
|
|
|
|
#define HUD_PRINT_CONGRATULATIONS 1
|
|
|
|
|
|
|
|
void print_hud_course_complete_string(s8 str) {
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-09-01 19:50:50 +00:00
|
|
|
u8 textHiScore[][15] = {
|
2019-10-05 19:08:05 +00:00
|
|
|
{ TEXT_HUD_HI_SCORE },
|
|
|
|
{ TEXT_HUD_HI_SCORE_FR },
|
|
|
|
{ TEXT_HUD_HI_SCORE_DE }
|
2019-09-01 19:50:50 +00:00
|
|
|
};
|
|
|
|
u8 textCongratulations[][16] = {
|
2019-10-05 19:08:05 +00:00
|
|
|
{ TEXT_HUD_CONGRATULATIONS },
|
|
|
|
{ TEXT_HUD_CONGRATULATIONS_FR },
|
|
|
|
{ TEXT_HUD_CONGRATULATIONS_DE }
|
2019-09-01 19:50:50 +00:00
|
|
|
};
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
u8 textHiScore[] = { TEXT_HUD_HI_SCORE };
|
|
|
|
u8 textCongratulations[] = { TEXT_HUD_CONGRATULATIONS };
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
u8 colorFade = sins(gDialogColorFadeTimer) * 50.0f + 200.0f;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, colorFade, colorFade, colorFade, 255);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (str == HUD_PRINT_HISCORE) {
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, get_str_x_pos_from_center_scale(160, textHiScore[gInGameLanguage], 12.0f),
|
2019-09-01 19:50:50 +00:00
|
|
|
36, textHiScore[gInGameLanguage]);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, TXT_HISCORE_X, TXT_HISCORE_Y, textHiScore);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
} else { // HUD_PRINT_CONGRATULATIONS
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, get_str_x_pos_from_center_scale(160, textCongratulations[gInGameLanguage], 12.0f),
|
2019-08-25 04:46:40 +00:00
|
|
|
67, textCongratulations[gInGameLanguage]);
|
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, TXT_CONGRATS_X, 67, textCongratulations);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void print_hud_course_complete_coins(s16 x, s16 y) {
|
|
|
|
u8 courseCompleteCoinsStr[4];
|
|
|
|
u8 hudTextSymCoin[] = { GLYPH_COIN, GLYPH_SPACE };
|
|
|
|
u8 hudTextSymX[] = { GLYPH_MULTIPLY, GLYPH_SPACE };
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
|
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, x, y, hudTextSymCoin);
|
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, x + 16, y, hudTextSymX);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
int_to_str(gCourseCompleteCoins, courseCompleteCoinsStr);
|
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, x + 32, y, courseCompleteCoinsStr);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gCourseCompleteCoins >= gHudDisplay.coins) {
|
|
|
|
gCourseCompleteCoinsEqual = 1;
|
|
|
|
gCourseCompleteCoins = gHudDisplay.coins;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (gGotFileCoinHiScore != 0) {
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_course_complete_string(HUD_PRINT_HISCORE);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
} else {
|
2019-10-05 19:08:05 +00:00
|
|
|
if ((gCourseDoneMenuTimer & 1) || gHudDisplay.coins > 70) {
|
|
|
|
gCourseCompleteCoins++;
|
|
|
|
play_sound(SOUND_MENU_YOSHI_GAIN_LIVES, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gCourseCompleteCoins == 50 || gCourseCompleteCoins == 100 || gCourseCompleteCoins == 150) {
|
|
|
|
play_sound(SOUND_GENERAL_COLLECT_1UP, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
gMarioState[0].numLives++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gHudDisplay.coins == gCourseCompleteCoins && gGotFileCoinHiScore != 0) {
|
|
|
|
play_sound(SOUND_MENU_MARIO_CASTLE_WARP2, gDefaultSoundArgs);
|
2019-09-01 19:50:50 +00:00
|
|
|
}
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void play_star_fanfare_and_flash_hud(s32 arg, u8 starNum) {
|
|
|
|
if (gHudDisplay.coins == gCourseCompleteCoins && (gCurrCourseStarFlags & starNum) == 0 && gHudFlash == 0) {
|
2019-08-25 04:46:40 +00:00
|
|
|
play_star_fanfare();
|
2019-10-05 19:08:05 +00:00
|
|
|
gHudFlash = arg;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
#define TXT_NAME_X1 centerX
|
|
|
|
#define TXT_NAME_X2 centerX - 1
|
|
|
|
#else
|
|
|
|
#define TXT_NAME_X1 71
|
|
|
|
#define TXT_NAME_X2 69
|
|
|
|
#endif
|
|
|
|
#ifdef VERSION_JP
|
|
|
|
#define CRS_NUM_X2 95
|
|
|
|
#define CRS_NUM_X3 93
|
|
|
|
#define TXT_CLEAR_X1 205
|
|
|
|
#define TXT_CLEAR_X2 203
|
|
|
|
#else
|
|
|
|
#define CRS_NUM_X2 104
|
|
|
|
#define CRS_NUM_X3 102
|
2019-10-05 19:08:05 +00:00
|
|
|
#define TXT_CLEAR_X1 get_string_width(name) + 81
|
|
|
|
#define TXT_CLEAR_X2 get_string_width(name) + 79
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_course_complete_lvl_info_and_hud_str(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_JP
|
2019-10-05 19:08:05 +00:00
|
|
|
u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE };
|
2019-08-25 04:46:40 +00:00
|
|
|
u8 textCourse[] = { TEXT_COURSE };
|
|
|
|
u8 textCatch[] = { TEXT_CATCH };
|
|
|
|
u8 textClear[] = { TEXT_CLEAR };
|
|
|
|
#elif defined(VERSION_EU)
|
2020-02-03 05:51:26 +00:00
|
|
|
UNUSED u8 textCatch[] = { TEXT_CATCH }; // unused in EU
|
2019-10-05 19:08:05 +00:00
|
|
|
u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE };
|
2019-08-25 04:46:40 +00:00
|
|
|
#define textCourse gTextCourseArr[gInGameLanguage]
|
|
|
|
#else
|
|
|
|
u8 textCourse[] = { TEXT_COURSE };
|
|
|
|
UNUSED u8 textCatch[] = { TEXT_CATCH }; // unused in US
|
|
|
|
UNUSED u8 textClear[] = { TEXT_CLEAR };
|
2019-10-05 19:08:05 +00:00
|
|
|
u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE };
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
void **actNameTbl;
|
2019-12-02 02:52:53 +00:00
|
|
|
void **courseNameTbl;
|
2019-08-25 04:46:40 +00:00
|
|
|
u8 *name;
|
|
|
|
|
|
|
|
u8 strCourseNum[4];
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
s16 centerX;
|
|
|
|
switch (gInGameLanguage) {
|
|
|
|
case LANGUAGE_ENGLISH:
|
|
|
|
actNameTbl = segmented_to_virtual(act_name_table_eu_en);
|
2019-12-02 02:52:53 +00:00
|
|
|
courseNameTbl = segmented_to_virtual(course_name_table_eu_en);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
case LANGUAGE_FRENCH:
|
|
|
|
actNameTbl = segmented_to_virtual(act_name_table_eu_fr);
|
2019-12-02 02:52:53 +00:00
|
|
|
courseNameTbl = segmented_to_virtual(course_name_table_eu_fr);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
case LANGUAGE_GERMAN:
|
|
|
|
actNameTbl = segmented_to_virtual(act_name_table_eu_de);
|
2019-12-02 02:52:53 +00:00
|
|
|
courseNameTbl = segmented_to_virtual(course_name_table_eu_de);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
#else
|
2019-09-01 19:50:50 +00:00
|
|
|
actNameTbl = segmented_to_virtual(seg2_act_name_table);
|
2019-12-02 02:52:53 +00:00
|
|
|
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
if (gLastCompletedCourseNum <= COURSE_STAGES_MAX) {
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_course_complete_coins(118, 103);
|
|
|
|
play_star_fanfare_and_flash_hud(1, 1 << (gLastCompletedStarNum - 1));
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (gLastCompletedStarNum == 7) {
|
|
|
|
name = segmented_to_virtual(actNameTbl[COURSE_STAGES_MAX * 6 + 1]);
|
|
|
|
} else {
|
2019-09-01 19:50:50 +00:00
|
|
|
name = segmented_to_virtual(actNameTbl[(gLastCompletedCourseNum - 1) * 6 + gLastCompletedStarNum - 1]);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
2019-10-05 19:08:05 +00:00
|
|
|
int_to_str(gLastCompletedCourseNum, strCourseNum);
|
|
|
|
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha);
|
|
|
|
print_generic_string(65, 165, textCourse);
|
|
|
|
print_generic_string(CRS_NUM_X2, 165, strCourseNum);
|
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
|
|
|
print_generic_string(63, 167, textCourse);
|
|
|
|
print_generic_string(CRS_NUM_X3, 167, strCourseNum);
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
2019-08-25 04:46:40 +00:00
|
|
|
} else if (gLastCompletedCourseNum == COURSE_BITDW || gLastCompletedCourseNum == COURSE_BITFS) {
|
2019-12-02 02:52:53 +00:00
|
|
|
name = segmented_to_virtual(courseNameTbl[gLastCompletedCourseNum - 1]);
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha);
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
|
|
|
centerX = get_str_x_pos_from_center(153, name, 12.0f);
|
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(TXT_NAME_X1, 130, name);
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifndef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(TXT_CLEAR_X1, 130, textClear);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
|
|
|
print_generic_string(TXT_NAME_X2, 132, name);
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifndef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(TXT_CLEAR_X2, 132, textClear);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_course_complete_string(HUD_PRINT_CONGRATULATIONS);
|
|
|
|
print_hud_course_complete_coins(118, 111);
|
|
|
|
play_star_fanfare_and_flash_hud(2, 0); //! 2 isn't defined, originally for key hud?
|
2019-08-25 04:46:40 +00:00
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
name = segmented_to_virtual(actNameTbl[COURSE_STAGES_MAX * 6]);
|
2019-10-05 19:08:05 +00:00
|
|
|
print_hud_course_complete_coins(118, 103);
|
|
|
|
play_star_fanfare_and_flash_hud(1, 1 << (gLastCompletedStarNum - 1));
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
|
|
|
print_hud_lut_string(HUD_LUT_GLOBAL, 55, 77, textSymStar);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha);
|
|
|
|
print_generic_string(76, 145, name);
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_JP
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(220, 145, textCatch);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
|
|
|
print_generic_string(74, 147, name);
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_JP
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(218, 147, textCatch);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
#if defined(VERSION_JP) || defined(VERSION_SH)
|
2019-08-25 04:46:40 +00:00
|
|
|
#define TXT_SAVEOPTIONS_X x + 10
|
|
|
|
#elif defined(VERSION_US)
|
|
|
|
#define TXT_SAVEOPTIONS_X x + 12
|
|
|
|
#elif defined(VERSION_EU)
|
|
|
|
#define TXT_SAVEOPTIONS_X xOffset
|
|
|
|
#endif
|
|
|
|
#ifdef VERSION_JP
|
|
|
|
#define TXT_SAVECONT_Y 2
|
|
|
|
#define TXT_SAVEQUIT_Y 18
|
|
|
|
#define TXT_CONTNOSAVE_Y 38
|
|
|
|
#else
|
|
|
|
#define TXT_SAVECONT_Y 0
|
|
|
|
#define TXT_SAVEQUIT_Y 20
|
|
|
|
#define TXT_CONTNOSAVE_Y 40
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef VERSION_EU
|
|
|
|
#define X_VAL9 xOffset - 12
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_save_confirmation(s16 y, s8 *index, s16 sp6e)
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
|
|
|
#define X_VAL9 x
|
2019-10-05 19:08:05 +00:00
|
|
|
void render_save_confirmation(s16 x, s16 y, s8 *index, s16 sp6e)
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
{
|
|
|
|
#ifdef VERSION_EU
|
2019-09-01 19:50:50 +00:00
|
|
|
u8 textSaveAndContinueArr[][24] = {
|
|
|
|
{ TEXT_SAVE_AND_CONTINUE },
|
|
|
|
{ TEXT_SAVE_AND_CONTINUE_FR },
|
|
|
|
{ TEXT_SAVE_AND_CONTINUE_DE }
|
|
|
|
};
|
|
|
|
u8 textSaveAndQuitArr[][22] = {
|
|
|
|
{ TEXT_SAVE_AND_QUIT },
|
|
|
|
{ TEXT_SAVE_AND_QUIT_FR },
|
|
|
|
{ TEXT_SAVE_AND_QUIT_DE }
|
|
|
|
};
|
|
|
|
u8 textContinueWithoutSaveArr[][27] = {
|
|
|
|
{ TEXT_CONTINUE_WITHOUT_SAVING },
|
|
|
|
{ TEXT_CONTINUE_WITHOUT_SAVING_FR },
|
|
|
|
{ TEXT_CONTINUE_WITHOUT_SAVING_DE }
|
|
|
|
};
|
2019-08-25 04:46:40 +00:00
|
|
|
#define textSaveAndContinue textSaveAndContinueArr[gInGameLanguage]
|
|
|
|
#define textSaveAndQuit textSaveAndQuitArr[gInGameLanguage]
|
|
|
|
#define textContinueWithoutSave textContinueWithoutSaveArr[gInGameLanguage]
|
|
|
|
s16 xOffset = get_str_x_pos_from_center(160, textContinueWithoutSaveArr[gInGameLanguage], 12.0f);
|
|
|
|
#else
|
2019-09-01 19:50:50 +00:00
|
|
|
u8 textSaveAndContinue[] = { TEXT_SAVE_AND_CONTINUE };
|
|
|
|
u8 textSaveAndQuit[] = { TEXT_SAVE_AND_QUIT };
|
|
|
|
u8 textContinueWithoutSave[] = { TEXT_CONTINUE_WITHOUT_SAVING };
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
handle_menu_scrolling(MENU_SCROLL_VERTICAL, index, 1, 3);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
print_generic_string(TXT_SAVEOPTIONS_X, y + TXT_SAVECONT_Y, textSaveAndContinue);
|
|
|
|
print_generic_string(TXT_SAVEOPTIONS_X, y - TXT_SAVEQUIT_Y, textSaveAndQuit);
|
|
|
|
print_generic_string(TXT_SAVEOPTIONS_X, y - TXT_CONTNOSAVE_Y, textContinueWithoutSave);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-11-03 19:36:27 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_translation_matrix(MENU_MTX_PUSH, X_VAL9, y - ((index[0] - 1) * sp6e), 0);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
|
|
|
|
|
|
|
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
s16 render_course_complete_screen(void) {
|
|
|
|
s16 num;
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
|
|
|
gInGameLanguage = eu_get_language();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
switch (gDialogBoxState) {
|
|
|
|
case DIALOG_STATE_OPENING:
|
2019-10-05 19:08:05 +00:00
|
|
|
render_course_complete_lvl_info_and_hud_str();
|
|
|
|
if (gCourseDoneMenuTimer > 100 && gCourseCompleteCoinsEqual == 1) {
|
|
|
|
gDialogBoxState = DIALOG_STATE_VERTICAL;
|
2019-08-25 04:46:40 +00:00
|
|
|
level_set_transition(-1, 0);
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogTextAlpha = 0;
|
|
|
|
gDialogLineNum = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
break;
|
2019-10-05 19:08:05 +00:00
|
|
|
case DIALOG_STATE_VERTICAL:
|
|
|
|
shade_screen();
|
|
|
|
render_course_complete_lvl_info_and_hud_str();
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-10-05 19:08:05 +00:00
|
|
|
render_save_confirmation(86, &gDialogLineNum, 20);
|
2019-08-25 04:46:40 +00:00
|
|
|
#else
|
2019-10-05 19:08:05 +00:00
|
|
|
render_save_confirmation(100, 86, &gDialogLineNum, 20);
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gCourseDoneMenuTimer > 110
|
2019-08-25 04:46:40 +00:00
|
|
|
&& (gPlayer3Controller->buttonPressed & A_BUTTON
|
2019-09-01 19:50:50 +00:00
|
|
|
|| gPlayer3Controller->buttonPressed & START_BUTTON
|
2019-08-25 04:46:40 +00:00
|
|
|
#ifdef VERSION_EU
|
2019-09-01 19:50:50 +00:00
|
|
|
|| gPlayer3Controller->buttonPressed & Z_TRIG
|
2019-08-25 04:46:40 +00:00
|
|
|
#endif
|
2019-09-01 19:50:50 +00:00
|
|
|
)) {
|
2019-08-25 04:46:40 +00:00
|
|
|
level_set_transition(0, 0);
|
2019-10-05 19:08:05 +00:00
|
|
|
play_sound(SOUND_MENU_STAR_SOUND, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
gDialogBoxState = DIALOG_STATE_OPENING;
|
2019-10-05 19:08:05 +00:00
|
|
|
gMenuMode = -1;
|
|
|
|
num = gDialogLineNum;
|
|
|
|
gCourseDoneMenuTimer = 0;
|
|
|
|
gCourseCompleteCoins = 0;
|
|
|
|
gCourseCompleteCoinsEqual = 0;
|
|
|
|
gHudFlash = 0;
|
|
|
|
|
|
|
|
return num;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gDialogTextAlpha < 250) {
|
|
|
|
gDialogTextAlpha += 25;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
gCourseDoneMenuTimer++;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
// Only case 1 and 2 are used
|
|
|
|
s16 render_menus_and_dialogs() {
|
|
|
|
s16 mode = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
create_dl_ortho_matrix();
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
if (gMenuMode != -1) {
|
|
|
|
switch (gMenuMode) {
|
2019-08-25 04:46:40 +00:00
|
|
|
case 0:
|
2019-10-05 19:08:05 +00:00
|
|
|
mode = render_pause_courses_and_castle();
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
2019-10-05 19:08:05 +00:00
|
|
|
mode = render_pause_courses_and_castle();
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2019-10-05 19:08:05 +00:00
|
|
|
mode = render_course_complete_screen();
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
2019-10-05 19:08:05 +00:00
|
|
|
mode = render_course_complete_screen();
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
gDialogColorFadeTimer = (s16) gDialogColorFadeTimer + 0x1000;
|
2019-08-25 04:46:40 +00:00
|
|
|
} else if (gDialogID != -1) {
|
2019-10-05 19:08:05 +00:00
|
|
|
// Peach message "Dear Mario" new game dialog
|
2019-08-25 04:46:40 +00:00
|
|
|
if (gDialogID == 20) {
|
|
|
|
print_peach_letter_message(); // the peach message needs to be
|
|
|
|
// repositioned seperately
|
2019-10-05 19:08:05 +00:00
|
|
|
return mode;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-05 19:08:05 +00:00
|
|
|
render_dialog_entries();
|
|
|
|
gDialogColorFadeTimer = (s16) gDialogColorFadeTimer + 0x1000;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2019-10-05 19:08:05 +00:00
|
|
|
return mode;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|