diff options
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/z_camera.c | 1 | ||||
| -rw-r--r-- | src/code/z_parameter.c | 1025 |
2 files changed, 979 insertions, 47 deletions
diff --git a/src/code/z_camera.c b/src/code/z_camera.c index 3a5cde395..f54fc93da 100644 --- a/src/code/z_camera.c +++ b/src/code/z_camera.c @@ -1,4 +1,3 @@ -//#include "prevent_bss_reordering.h" #include "global.h" #include "z64quake.h" #include "z64shrink_window.h" diff --git a/src/code/z_parameter.c b/src/code/z_parameter.c index 79c50e921..4e61639fb 100644 --- a/src/code/z_parameter.c +++ b/src/code/z_parameter.c @@ -506,26 +506,324 @@ Gfx* Gfx_DrawTexQuad4b(Gfx* gfx, TexturePtr texture, s32 fmt, s16 textureWidth, return gfx; } -s16 D_801BFA04[] = { - -14, -14, -24, -8, -12, -12, -7, -8, -7, -8, -12, 0, +// Total number of non-minigame-perfect action quads +#define ACTION_QUAD_BASE_COUNT 11 + +s16 sActionVtxPosX[ACTION_QUAD_BASE_COUNT] = { + -14, // A Button + -14, // A Button Background + -24, // A Button Do-Action + -8, // Three-Day Clock's Star (for the Minute Tracker) + -12, // Three-Day Clock's Sun (for the Day-Time Hours Tracker) + -12, // Three-Day Clock's Moon (for the Night-Time Hours Tracker) + -7, // Three-Day Clock's Hour Digit Above the Sun + -8, // Three-Day Clock's Hour Digit Above the Sun + -7, // Three-Day Clock's Hour Digit Above the Moon + -8, // Three-Day Clock's Hour Digit Above the Moon + -12, // Minigame Countdown Textures }; -s16 D_801BFA1C[] = { - 0x1C, 0x1C, 0x30, 0x10, 0x18, 0x18, 0x10, 0x10, 0x10, 0x10, 0x18, 0, + +s16 sActionVtxWidths[ACTION_QUAD_BASE_COUNT] = { + 28, // A Button + 28, // A Button Background + 48, // A Button Do-Action + 16, // Three-Day Clock's Star (for the Minute Tracker) + 24, // Three-Day Clock's Sun (for the Day-Time Hours Tracker) + 24, // Three-Day Clock's Moon (for the Night-Time Hours Tracker) + 16, // Three-Day Clock's Hour Digit Above the Sun + 16, // Three-Day Clock's Hour Digit Above the Sun + 16, // Three-Day Clock's Hour Digit Above the Moon + 16, // Three-Day Clock's Hour Digit Above the Moon + 24, // Minigame Countdown Textures }; -s16 D_801BFA34[] = { - 14, 14, 8, 24, -82, -82, 58, 59, 58, 59, 32, 0, + +s16 sActionVtxPosY[ACTION_QUAD_BASE_COUNT] = { + 14, // A Button + 14, // A Button Background + 8, // A Button Do-Action + 24, // Three-Day Clock's Star (for the Minute Tracker) + -82, // Three-Day Clock's Sun (for the Day-Time Hours Tracker) + -82, // Three-Day Clock's Moon (for the Night-Time Hours Tracker) + 58, // Three-Day Clock's Hour Digit Above the Sun + 59, // Three-Day Clock's Hour Digit Above the Sun + 58, // Three-Day Clock's Hour Digit Above the Moon + 59, // Three-Day Clock's Hour Digit Above the Moon + 32, // Minigame Countdown Textures }; -s16 D_801BFA4C[] = { - 0x1C, 0x1C, 0x10, 0x10, 0x18, 0x18, 0xB, 0xB, 0xB, 0xB, 0x20, 0, + +s16 sActionVtxHeights[ACTION_QUAD_BASE_COUNT] = { + 28, // A Button + 28, // A Button Background + 16, // A Button Do-Action + 16, // Three-Day Clock's Star (for the Minute Tracker) + 24, // Three-Day Clock's Sun (for the Day-Time Hours Tracker) + 24, // Three-Day Clock's Moon (for the Night-Time Hours Tracker) + 11, // Three-Day Clock's Hour Digit Above the Sun + 11, // Three-Day Clock's Hour Digit Above the Sun + 11, // Three-Day Clock's Hour Digit Above the Moon + 11, // Three-Day Clock's Hour Digit Above the Moon + 32, // Minigame Countdown Textures }; -s16 D_801BFA64[] = { - -61, -45, 29, 104, -117, -42, 32, 55, + +#define PERFECT_LETTERS_VTX_WIDTH 32 +#define PERFECT_LETTERS_VTX_HEIGHT 33 + +// Used for PERFECT_LETTERS_TYPE_1 and only part of PERFECT_LETTERS_TYPE_3 +// Both PERFECT_LETTERS_TYPE_2 and PERFECT_LETTERS_TYPE_2 have (0, 0) as the center for all letters +s16 sPerfectLettersCenterX[PERFECT_LETTERS_NUM_LETTERS] = { + -61, // P + -45, // E + 29, // R + 104, // F + -117, // E + -42, // C + 32, // T + 55, // ! }; -s16 D_801BFA74[] = { - 1, -70, -99, -70, 71, 101, 72, 1, + +s16 sPerfectLettersCenterY[PERFECT_LETTERS_NUM_LETTERS] = { + 1, // P + -70, // E + -99, // R + -70, // F + 71, // E + 101, // C + 72, // T + 1, // ! }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8010E028.s") +/** + * interfaceCtx->actionVtx[0] -> A Button + * interfaceCtx->actionVtx[4] -> A Button Shadow + * interfaceCtx->actionVtx[8] -> A Button Do-Action + * interfaceCtx->actionVtx[12] -> Three-Day Clock's Star (for the Minute Tracker) + * interfaceCtx->actionVtx[16] -> Three-Day Clock's Sun (for the Day Hours Tracker) + * interfaceCtx->actionVtx[20] -> Three-Day Clock's Moon (for the Night Hours Tracker) + * interfaceCtx->actionVtx[24] -> Three-Day Clock's Hour Digit Above the Sun (uses 8 vertices) + * interfaceCtx->actionVtx[32] -> Three-Day Clock's Hour Digit Above the Moon (uses 8 vertices) + * interfaceCtx->actionVtx[40] -> Minigame Countdown Textures + * interfaceCtx->actionVtx[44] -> Minigame Perfect Letter P Shadow + * interfaceCtx->actionVtx[48] -> Minigame Perfect Letter E Shadow + * interfaceCtx->actionVtx[52] -> Minigame Perfect Letter R Shadow + * interfaceCtx->actionVtx[56] -> Minigame Perfect Letter F Shadow + * interfaceCtx->actionVtx[60] -> Minigame Perfect Letter E Shadow + * interfaceCtx->actionVtx[64] -> Minigame Perfect Letter C Shadow + * interfaceCtx->actionVtx[68] -> Minigame Perfect Letter T Shadow + * interfaceCtx->actionVtx[72] -> Minigame Perfect Letter ! Shadow + * interfaceCtx->actionVtx[76] -> Minigame Perfect Letter P Colored + * interfaceCtx->actionVtx[80] -> Minigame Perfect Letter E Colored + * interfaceCtx->actionVtx[84] -> Minigame Perfect Letter R Colored + * interfaceCtx->actionVtx[88] -> Minigame Perfect Letter F Colored + * interfaceCtx->actionVtx[92] -> Minigame Perfect Letter E Colored + * interfaceCtx->actionVtx[96] -> Minigame Perfect Letter C Colored + * interfaceCtx->actionVtx[100] -> Minigame Perfect Letter T Colored + * interfaceCtx->actionVtx[104] -> Minigame Perfect Letter ! Colored + */ + +#define BEATING_HEART_VTX_X -8 +#define BEATING_HEART_VTX_Y -8 +#define BEATING_HEART_VTX_WIDTH 16 + +void Interface_SetVertices(PlayState* play) { + InterfaceContext* interfaceCtx = &play->interfaceCtx; + s16 i; + s16 j; + s16 k; + s16 shadowOffset; + + play->interfaceCtx.actionVtx = + GRAPH_ALLOC(play->state.gfxCtx, (ACTION_QUAD_BASE_COUNT + (2 * PERFECT_LETTERS_NUM_LETTERS)) * 4 * sizeof(Vtx)); + + // Loop over all non-minigame perfect vertices + // where (i) is the actionVtx index, (k) is the iterator + for (k = 0, i = 0; i < (ACTION_QUAD_BASE_COUNT * 4); i += 4, k++) { + // Left vertices x Pos + interfaceCtx->actionVtx[i + 0].v.ob[0] = interfaceCtx->actionVtx[i + 2].v.ob[0] = sActionVtxPosX[k]; + + // Right vertices x Pos + interfaceCtx->actionVtx[i + 1].v.ob[0] = interfaceCtx->actionVtx[i + 3].v.ob[0] = + interfaceCtx->actionVtx[i + 0].v.ob[0] + sActionVtxWidths[k]; + + // Top vertices y Pos + interfaceCtx->actionVtx[i + 0].v.ob[1] = interfaceCtx->actionVtx[i + 1].v.ob[1] = sActionVtxPosY[k]; + + // Bottom vertices y Pos + interfaceCtx->actionVtx[i + 2].v.ob[1] = interfaceCtx->actionVtx[i + 3].v.ob[1] = + interfaceCtx->actionVtx[i + 0].v.ob[1] - sActionVtxHeights[k]; + + // All vertices z Pos + interfaceCtx->actionVtx[i + 0].v.ob[2] = interfaceCtx->actionVtx[i + 1].v.ob[2] = + interfaceCtx->actionVtx[i + 2].v.ob[2] = interfaceCtx->actionVtx[i + 3].v.ob[2] = 0; + + // Unused flag + interfaceCtx->actionVtx[i + 0].v.flag = interfaceCtx->actionVtx[i + 1].v.flag = + interfaceCtx->actionVtx[i + 2].v.flag = interfaceCtx->actionVtx[i + 3].v.flag = 0; + + // Left and Top texture coordinates + interfaceCtx->actionVtx[i + 0].v.tc[0] = interfaceCtx->actionVtx[i + 0].v.tc[1] = + interfaceCtx->actionVtx[i + 1].v.tc[1] = interfaceCtx->actionVtx[i + 2].v.tc[0] = 0; + + // Right vertices texture coordinates + interfaceCtx->actionVtx[i + 1].v.tc[0] = interfaceCtx->actionVtx[i + 3].v.tc[0] = sActionVtxWidths[k] << 5; + + // Bottom vertices texture coordinates + interfaceCtx->actionVtx[i + 2].v.tc[1] = interfaceCtx->actionVtx[i + 3].v.tc[1] = sActionVtxHeights[k] << 5; + + // Set color + interfaceCtx->actionVtx[i + 0].v.cn[0] = interfaceCtx->actionVtx[i + 1].v.cn[0] = + interfaceCtx->actionVtx[i + 2].v.cn[0] = interfaceCtx->actionVtx[i + 3].v.cn[0] = + interfaceCtx->actionVtx[i + 0].v.cn[1] = interfaceCtx->actionVtx[i + 1].v.cn[1] = + interfaceCtx->actionVtx[i + 2].v.cn[1] = interfaceCtx->actionVtx[i + 3].v.cn[1] = + interfaceCtx->actionVtx[i + 0].v.cn[2] = interfaceCtx->actionVtx[i + 1].v.cn[2] = + interfaceCtx->actionVtx[i + 2].v.cn[2] = interfaceCtx->actionVtx[i + 3].v.cn[2] = 255; + + // Set alpha + interfaceCtx->actionVtx[i + 0].v.cn[3] = interfaceCtx->actionVtx[i + 1].v.cn[3] = + interfaceCtx->actionVtx[i + 2].v.cn[3] = interfaceCtx->actionVtx[i + 3].v.cn[3] = 255; + } + + // A button right and top texture coordinates + interfaceCtx->actionVtx[1].v.tc[0] = interfaceCtx->actionVtx[3].v.tc[0] = interfaceCtx->actionVtx[2].v.tc[1] = + interfaceCtx->actionVtx[3].v.tc[1] = 32 << 5; + + // A button background right and top texture coordinates + interfaceCtx->actionVtx[5].v.tc[0] = interfaceCtx->actionVtx[7].v.tc[0] = interfaceCtx->actionVtx[6].v.tc[1] = + interfaceCtx->actionVtx[7].v.tc[1] = 32 << 5; + + // Loop over vertices for the minigame-perfect letters + // Outer loop is to loop over 2 sets of letters: shadowed letters (j = 0) and colored letters (j = 1) + for (j = 0, shadowOffset = 2; j < 2; j++, shadowOffset -= 2) { + // Inner loop is to loop over letters (k) and actionVtx index (i) + for (k = 0; k < PERFECT_LETTERS_NUM_LETTERS; k++, i += 4) { + if ((interfaceCtx->perfectLettersType == PERFECT_LETTERS_TYPE_1) || + ((interfaceCtx->perfectLettersType == PERFECT_LETTERS_TYPE_3) && + (interfaceCtx->perfectLettersState[0] == PERFECT_LETTERS_STATE_EXIT))) { + // Left vertices x Pos + interfaceCtx->actionVtx[i + 0].v.ob[0] = interfaceCtx->actionVtx[i + 2].v.ob[0] = + -((sPerfectLettersCenterX[k] - shadowOffset) + 16); + + // Right vertices x Pos + interfaceCtx->actionVtx[i + 1].v.ob[0] = interfaceCtx->actionVtx[i + 3].v.ob[0] = + interfaceCtx->actionVtx[i + 0].v.ob[0] + PERFECT_LETTERS_VTX_WIDTH; + + // Top vertices y Pos + interfaceCtx->actionVtx[i + 0].v.ob[1] = interfaceCtx->actionVtx[i + 1].v.ob[1] = + (sPerfectLettersCenterY[k] - shadowOffset) + 16; + + // Bottom vertices y Pos + interfaceCtx->actionVtx[i + 2].v.ob[1] = interfaceCtx->actionVtx[i + 3].v.ob[1] = + interfaceCtx->actionVtx[i + 0].v.ob[1] - PERFECT_LETTERS_VTX_HEIGHT; + + } else if ((interfaceCtx->perfectLettersType == PERFECT_LETTERS_TYPE_2) || + (interfaceCtx->perfectLettersType == PERFECT_LETTERS_TYPE_3)) { + // Left vertices x Pos + interfaceCtx->actionVtx[i + 0].v.ob[0] = interfaceCtx->actionVtx[i + 2].v.ob[0] = + -(interfaceCtx->perfectLettersOffsetX[k] - shadowOffset + 16); + + // Right vertices x Pos + interfaceCtx->actionVtx[i + 1].v.ob[0] = interfaceCtx->actionVtx[i + 3].v.ob[0] = + interfaceCtx->actionVtx[i + 0].v.ob[0] + PERFECT_LETTERS_VTX_WIDTH; + + // Top vertices y Pos + interfaceCtx->actionVtx[i + 0].v.ob[1] = interfaceCtx->actionVtx[i + 1].v.ob[1] = 16 - shadowOffset; + + // Bottom vertices y Pos + interfaceCtx->actionVtx[i + 2].v.ob[1] = interfaceCtx->actionVtx[i + 3].v.ob[1] = + interfaceCtx->actionVtx[i + 0].v.ob[1] - PERFECT_LETTERS_VTX_HEIGHT; + + } else { + // Left vertices x Pos + interfaceCtx->actionVtx[i + 0].v.ob[0] = interfaceCtx->actionVtx[i + 2].v.ob[0] = -(216 - shadowOffset); + + // Right vertices x Pos + interfaceCtx->actionVtx[i + 1].v.ob[0] = interfaceCtx->actionVtx[i + 3].v.ob[0] = + interfaceCtx->actionVtx[i + 0].v.ob[0] + PERFECT_LETTERS_VTX_WIDTH; + + // Top vertices y Pos + interfaceCtx->actionVtx[i + 0].v.ob[1] = interfaceCtx->actionVtx[i + 1].v.ob[1] = 24 - shadowOffset; + + // Bottom vertices y Pos + interfaceCtx->actionVtx[i + 2].v.ob[1] = interfaceCtx->actionVtx[i + 3].v.ob[1] = + interfaceCtx->actionVtx[i + 0].v.ob[1] - PERFECT_LETTERS_VTX_HEIGHT; + } + + // All vertices z Pos + interfaceCtx->actionVtx[i + 0].v.ob[2] = interfaceCtx->actionVtx[i + 1].v.ob[2] = + interfaceCtx->actionVtx[i + 2].v.ob[2] = interfaceCtx->actionVtx[i + 3].v.ob[2] = 0; + + // Unused flag + interfaceCtx->actionVtx[i + 0].v.flag = interfaceCtx->actionVtx[i + 1].v.flag = + interfaceCtx->actionVtx[i + 2].v.flag = interfaceCtx->actionVtx[i + 3].v.flag = 0; + + // Left and Top texture coordinates + interfaceCtx->actionVtx[i + 0].v.tc[0] = interfaceCtx->actionVtx[i + 0].v.tc[1] = + interfaceCtx->actionVtx[i + 1].v.tc[1] = interfaceCtx->actionVtx[i + 2].v.tc[0] = 0; + + // Right vertices texture coordinates + interfaceCtx->actionVtx[i + 1].v.tc[0] = interfaceCtx->actionVtx[i + 3].v.tc[0] = PERFECT_LETTERS_VTX_WIDTH + << 5; + + // Bottom vertices texture coordinates + interfaceCtx->actionVtx[i + 2].v.tc[1] = interfaceCtx->actionVtx[i + 3].v.tc[1] = PERFECT_LETTERS_VTX_HEIGHT + << 5; + + // Set color + interfaceCtx->actionVtx[i + 0].v.cn[0] = interfaceCtx->actionVtx[i + 1].v.cn[0] = + interfaceCtx->actionVtx[i + 2].v.cn[0] = interfaceCtx->actionVtx[i + 3].v.cn[0] = + interfaceCtx->actionVtx[i + 0].v.cn[1] = interfaceCtx->actionVtx[i + 1].v.cn[1] = + interfaceCtx->actionVtx[i + 2].v.cn[1] = interfaceCtx->actionVtx[i + 3].v.cn[1] = + interfaceCtx->actionVtx[i + 0].v.cn[2] = interfaceCtx->actionVtx[i + 1].v.cn[2] = + interfaceCtx->actionVtx[i + 2].v.cn[2] = interfaceCtx->actionVtx[i + 3].v.cn[2] = 255; + + // Set alpha + interfaceCtx->actionVtx[i + 0].v.cn[3] = interfaceCtx->actionVtx[i + 1].v.cn[3] = + interfaceCtx->actionVtx[i + 2].v.cn[3] = interfaceCtx->actionVtx[i + 3].v.cn[3] = 255; + } + } + + // Beating Hearts Vertices + interfaceCtx->beatingHeartVtx = GRAPH_ALLOC(play->state.gfxCtx, 4 * sizeof(Vtx)); + + // Left vertices x Pos + interfaceCtx->beatingHeartVtx[0].v.ob[0] = interfaceCtx->beatingHeartVtx[2].v.ob[0] = BEATING_HEART_VTX_X; + + // Right vertices x Pos + interfaceCtx->beatingHeartVtx[1].v.ob[0] = interfaceCtx->beatingHeartVtx[3].v.ob[0] = + BEATING_HEART_VTX_X + BEATING_HEART_VTX_WIDTH; + + // Top vertices y Pos + interfaceCtx->beatingHeartVtx[0].v.ob[1] = interfaceCtx->beatingHeartVtx[1].v.ob[1] = + BEATING_HEART_VTX_Y + BEATING_HEART_VTX_WIDTH; + + // Bottom vertices y Pos + interfaceCtx->beatingHeartVtx[2].v.ob[1] = interfaceCtx->beatingHeartVtx[3].v.ob[1] = BEATING_HEART_VTX_Y; + + // All vertices z Pos + interfaceCtx->beatingHeartVtx[0].v.ob[2] = interfaceCtx->beatingHeartVtx[1].v.ob[2] = + interfaceCtx->beatingHeartVtx[2].v.ob[2] = interfaceCtx->beatingHeartVtx[3].v.ob[2] = 0; + + // unused flag + interfaceCtx->beatingHeartVtx[0].v.flag = interfaceCtx->beatingHeartVtx[1].v.flag = + interfaceCtx->beatingHeartVtx[2].v.flag = interfaceCtx->beatingHeartVtx[3].v.flag = 0; + + // Texture Coordinates + interfaceCtx->beatingHeartVtx[0].v.tc[0] = interfaceCtx->beatingHeartVtx[0].v.tc[1] = + interfaceCtx->beatingHeartVtx[1].v.tc[1] = interfaceCtx->beatingHeartVtx[2].v.tc[0] = 0; + interfaceCtx->beatingHeartVtx[1].v.tc[0] = interfaceCtx->beatingHeartVtx[2].v.tc[1] = + interfaceCtx->beatingHeartVtx[3].v.tc[0] = interfaceCtx->beatingHeartVtx[3].v.tc[1] = + BEATING_HEART_VTX_WIDTH << 5; + + // Set color + interfaceCtx->beatingHeartVtx[0].v.cn[0] = interfaceCtx->beatingHeartVtx[1].v.cn[0] = + interfaceCtx->beatingHeartVtx[2].v.cn[0] = interfaceCtx->beatingHeartVtx[3].v.cn[0] = + interfaceCtx->beatingHeartVtx[0].v.cn[1] = interfaceCtx->beatingHeartVtx[1].v.cn[1] = + interfaceCtx->beatingHeartVtx[2].v.cn[1] = interfaceCtx->beatingHeartVtx[3].v.cn[1] = + interfaceCtx->beatingHeartVtx[0].v.cn[2] = interfaceCtx->beatingHeartVtx[1].v.cn[2] = + interfaceCtx->beatingHeartVtx[2].v.cn[2] = interfaceCtx->beatingHeartVtx[3].v.cn[2] = + interfaceCtx->beatingHeartVtx[0].v.cn[3] = interfaceCtx->beatingHeartVtx[1].v.cn[3] = + interfaceCtx->beatingHeartVtx[2].v.cn[3] = interfaceCtx->beatingHeartVtx[3].v.cn[3] = + 255; +} s32 sPostmanTimerInputBtnAPressed = false; @@ -1409,7 +1707,18 @@ void Interface_UpdateHudAlphas(PlayState* play, s16 dimmingAlpha) { #pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80112AF4.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80112AFC.s") +void Interface_InitMinigame(PlayState* play) { + InterfaceContext* interfaceCtx = &play->interfaceCtx; + + gSaveContext.minigameStatus = MINIGAME_STATUS_ACTIVE; + gSaveContext.minigameScore = 0; + gSaveContext.minigameHiddenScore = 0; + + sHBAScoreTier = 0; + interfaceCtx->minigamePoints = interfaceCtx->minigameHiddenPoints = interfaceCtx->minigameUnusedPoints = 0; + + interfaceCtx->minigameAmmo = 20; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/Interface_LoadItemIconImpl.s") @@ -2826,49 +3135,556 @@ s16 D_801BFC40[] = { #pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80119610.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8011B4E0.s") +void Interface_SetPerfectLetters(PlayState* play, s16 perfectLettersType) { + InterfaceContext* interfaceCtx = &play->interfaceCtx; + s16 i; -u16 D_801BFC50[] = { - 0xC000, 0xE000, 0x0000, 0x2000, 0xA000, 0x8000, 0x6000, 0x4000, + interfaceCtx->perfectLettersOn = true; + interfaceCtx->perfectLettersType = perfectLettersType; + + interfaceCtx->perfectLettersPrimColor[0] = 255; + interfaceCtx->perfectLettersPrimColor[1] = 165; + interfaceCtx->perfectLettersPrimColor[2] = 55; + interfaceCtx->perfectLettersPrimColor[3] = 255; + interfaceCtx->perfectLettersColorTimer = 20; + + interfaceCtx->perfectLettersColorIndex = 0; + interfaceCtx->perfectLettersCount = 1; + interfaceCtx->perfectLettersTimer = 0; + + for (i = 0; i < PERFECT_LETTERS_NUM_LETTERS; i++) { + interfaceCtx->perfectLettersAngles[i] = 0; + interfaceCtx->perfectLettersState[i] = interfaceCtx->perfectLettersOffsetX[i] = 0; + if (interfaceCtx->perfectLettersType == PERFECT_LETTERS_TYPE_1) { + interfaceCtx->perfectLettersSemiAxisX[i] = 140.0f; + interfaceCtx->perfectLettersSemiAxisY[i] = 100.0f; + } else { + interfaceCtx->perfectLettersSemiAxisY[i] = 200.0f; + interfaceCtx->perfectLettersSemiAxisX[i] = 200.0f; + } + } + interfaceCtx->perfectLettersState[0] = PERFECT_LETTERS_STATE_INIT; +} + +u16 sPerfectLettersType1OffScreenAngles[PERFECT_LETTERS_NUM_LETTERS] = { + 6 * PERFECT_LETTERS_ANGLE_PER_LETTER, // P + 7 * PERFECT_LETTERS_ANGLE_PER_LETTER, // E + 0 * PERFECT_LETTERS_ANGLE_PER_LETTER, // R + 1 * PERFECT_LETTERS_ANGLE_PER_LETTER, // F + 5 * PERFECT_LETTERS_ANGLE_PER_LETTER, // E + 4 * PERFECT_LETTERS_ANGLE_PER_LETTER, // C + 3 * PERFECT_LETTERS_ANGLE_PER_LETTER, // T + 2 * PERFECT_LETTERS_ANGLE_PER_LETTER, // ! }; -s16 D_801BFC60[][3] = { - 255, 255, 255, 255, 165, 55, + +s16 sPerfectLettersType1PrimColorTargets[2][3] = { + { 255, 255, 255 }, + { 255, 165, 55 }, }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8011B5C0.s") +void Interface_UpdatePerfectLettersType1(PlayState* play) { + InterfaceContext* interfaceCtx = &play->interfaceCtx; + s16 i; + s16 count; + s16 colorStepR; + s16 colorStepG; + s16 colorStepB; + + // Update letter positions + for (count = 0, i = 0; i < interfaceCtx->perfectLettersCount; i++, count += 4) { + if (interfaceCtx->perfectLettersState[i] == PERFECT_LETTERS_STATE_INIT) { + // Initialize letter positions along the elliptical spirals + interfaceCtx->perfectLettersAngles[i] = sPerfectLettersType1OffScreenAngles[i] + 0xA000; + interfaceCtx->perfectLettersState[i] = PERFECT_LETTERS_STATE_ENTER; + } else if (interfaceCtx->perfectLettersState[i] == PERFECT_LETTERS_STATE_ENTER) { + // Swirl inwards along elliptical spirals to form the spelt-out word + interfaceCtx->perfectLettersAngles[i] -= 0x800; + if (interfaceCtx->perfectLettersAngles[i] == sPerfectLettersType1OffScreenAngles[i]) { + interfaceCtx->perfectLettersState[i] = PERFECT_LETTERS_STATE_STATIONARY; + } + } else if (interfaceCtx->perfectLettersState[i] == PERFECT_LETTERS_STATE_SPREAD) { + // Swirl outwards along elliptical spirals offscreen + interfaceCtx->perfectLettersAngles[i] -= 0x800; + if (interfaceCtx->perfectLettersAngles[i] == (u16)(sPerfectLettersType1OffScreenAngles[i] - 0x8000)) { + interfaceCtx->perfectLettersState[i] = PERFECT_LETTERS_STATE_OFF; + } + } + } -s16 D_801BFC6C[] = { - 78, 54, 29, 5, -18, -42, -67, -85, + // Initialize the next letter in the list + // if `perfectLettersCount == PERFECT_LETTERS_NUM_LETTERS`, + // then perfectLettersState[] is accessed + if ((interfaceCtx->perfectLettersState[interfaceCtx->perfectLettersCount] == PERFECT_LETTERS_STATE_OFF) && + (interfaceCtx->perfectLettersCount < PERFECT_LETTERS_NUM_LETTERS)) { + interfaceCtx->perfectLettersState[interfaceCtx->perfectLettersCount] = PERFECT_LETTERS_STATE_INIT; + + interfaceCtx->perfectLettersSemiAxisX[interfaceCtx->perfectLettersCount] = 140.0f; + interfaceCtx->perfectLettersSemiAxisY[interfaceCtx->perfectLettersCount] = 100.0f; + interfaceCtx->perfectLettersAngles[interfaceCtx->perfectLettersCount] = + sPerfectLettersType1OffScreenAngles[interfaceCtx->perfectLettersCount] + 0xA000; + + interfaceCtx->perfectLettersCount++; + } + + // Update letter colors + if ((interfaceCtx->perfectLettersCount == PERFECT_LETTERS_NUM_LETTERS) && + (interfaceCtx->perfectLettersState[PERFECT_LETTERS_NUM_LETTERS - 1] == PERFECT_LETTERS_STATE_STATIONARY)) { + + colorStepR = ABS_ALT(interfaceCtx->perfectLettersPrimColor[0] - + sPerfectLettersType1PrimColorTargets[interfaceCtx->perfectLettersColorIndex][0]) / + interfaceCtx->perfectLettersColorTimer; + colorStepG = ABS_ALT(interfaceCtx->perfectLettersPrimColor[1] - + sPerfectLettersType1PrimColorTargets[interfaceCtx->perfectLettersColorIndex][1]) / + interfaceCtx->perfectLettersColorTimer; + colorStepB = ABS_ALT(interfaceCtx->perfectLettersPrimColor[2] - + sPerfectLettersType1PrimColorTargets[interfaceCtx->perfectLettersColorIndex][2]) / + interfaceCtx->perfectLettersColorTimer; + + if (interfaceCtx->perfectLettersPrimColor[0] >= + sPerfectLettersType1PrimColorTargets[interfaceCtx->perfectLettersColorIndex][0]) { + interfaceCtx->perfectLettersPrimColor[0] -= colorStepR; + } else { + interfaceCtx->perfectLettersPrimColor[0] += colorStepR; + } + + if (interfaceCtx->perfectLettersPrimColor[1] >= + sPerfectLettersType1PrimColorTargets[interfaceCtx->perfectLettersColorIndex][1]) { + interfaceCtx->perfectLettersPrimColor[1] -= colorStepG; + } else { + interfaceCtx->perfectLettersPrimColor[1] += colorStepG; + } + + if (interfaceCtx->perfectLettersPrimColor[2] >= + sPerfectLettersType1PrimColorTargets[interfaceCtx->perfectLettersColorIndex][2]) { + interfaceCtx->perfectLettersPrimColor[2] -= colorStepB; + } else { + interfaceCtx->perfectLettersPrimColor[2] += colorStepB; + } + + interfaceCtx->perfectLettersColorTimer--; + + if (interfaceCtx->perfectLettersColorTimer == 0) { + interfaceCtx->perfectLettersColorTimer = 20; + interfaceCtx->perfectLettersColorIndex ^= 1; + interfaceCtx->perfectLettersTimer++; + + if (interfaceCtx->perfectLettersTimer == 6) { + for (i = 0; i < PERFECT_LETTERS_NUM_LETTERS; i++) { + interfaceCtx->perfectLettersState[i] = PERFECT_LETTERS_STATE_SPREAD; + } + } + } + } + + for (count = 0, i = 0; i < PERFECT_LETTERS_NUM_LETTERS; i++) { + if (interfaceCtx->perfectLettersState[i] == PERFECT_LETTERS_STATE_OFF) { + count++; + } + } + + if (count == PERFECT_LETTERS_NUM_LETTERS) { + interfaceCtx->perfectLettersOn = false; + } +} + +// Targets to offset each letter to properly spell "PERFECT!" +s16 sPerfectLettersType2SpellingOffsetsX[PERFECT_LETTERS_NUM_LETTERS] = { + 78, // P + 54, // E + 29, // R + 5, // F + -18, // E + -42, // C + -67, // T + -85, // ! }; -s16 D_801BFC7C[] = { - 180, 180, 180, 180, -180, -180, -180, -180, + +// Targets to offset each letter to sweep horizontally offscreen +s16 sPerfectLettersType2OffScreenOffsetsX[PERFECT_LETTERS_NUM_LETTERS] = { + 180, // P (offscreen left) + 180, // E (offscreen left) + 180, // R (offscreen left) + 180, // F (offscreen left) + -180, // E (offscreen right) + -180, // C (offscreen right) + -180, // T (offscreen right) + -180, // ! (offscreen right) }; -s16 D_801BFC8C[2][3] = { + +s16 sPerfectLettersType2PrimColorTargets[2][3] = { { 255, 255, 255 }, { 255, 165, 55 }, }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8011B9E0.s") +void Interface_UpdatePerfectLettersType2(PlayState* play) { + s16 i; + InterfaceContext* interfaceCtx = &play->interfaceCtx; + s16 colorStepR; + s16 colorStepG; + s16 colorStepB; + s16 colorStepA; + s16 j = 0; // unused incrementer + + // Update letter positions + for (i = 0; i < interfaceCtx->perfectLettersCount; i++, j += 4) { + if (interfaceCtx->perfectLettersState[i] == PERFECT_LETTERS_STATE_INIT) { + // Initialize letter positions along the elliptical spirals + interfaceCtx->perfectLettersAngles[i] = i * (0x10000 / PERFECT_LETTERS_NUM_LETTERS); + interfaceCtx->perfectLettersSemiAxisX[i] = 200.0f; + interfaceCtx->perfectLettersSemiAxisY[i] = 200.0f; + + interfaceCtx->perfectLettersOffsetX[i] = 0; + interfaceCtx->perfectLettersState[i] = PERFECT_LETTERS_STATE_ENTER; + } else if (interfaceCtx->perfectLettersState[i] == PERFECT_LETTERS_STATE_ENTER) { + // Swirl inwards along elliptical spirals to the center of the screen + interfaceCtx->perfectLettersAngles[i] -= 0x800; + interfaceCtx->perfectLettersSemiAxisX[i] -= 8.0f; + interfaceCtx->perfectLettersSemiAxisY[i] -= 8.0f; + + if (interfaceCtx->perfectLettersSemiAxisX[i] <= 0.0f) { + // The letter has reached the center of the screen + interfaceCtx->perfectLettersSemiAxisY[i] = 0.0f; + interfaceCtx->perfectLettersSemiAxisX[i] = 0.0f; + interfaceCtx->perfectLettersState[i] = PERFECT_LETTERS_STATE_STATIONARY; + + if (i == (PERFECT_LETTERS_NUM_LETTERS - 1)) { + // The last letter has reached the center of the screen + interfaceCtx->perfectLettersColorTimer = 5; + interfaceCtx->perfectLettersState[0] = interfaceCtx->perfectLettersState[1] = + interfaceCtx->perfectLettersState[2] = interfaceCtx->perfectLettersState[3] = + interfaceCtx->perfectLettersState[4] = interfaceCtx->perfectLettersState[5] = + interfaceCtx->perfectLettersState[6] = interfaceCtx->perfectLettersState[7] = + PERFECT_LETTERS_STATE_SPREAD; + } + } + } else if (interfaceCtx->perfectLettersState[i] == PERFECT_LETTERS_STATE_SPREAD) { + // Spread out the letters horizontally from the center to the spelt-out word + colorStepR = ABS_ALT(interfaceCtx->perfectLettersOffsetX[i] - sPerfectLettersType2SpellingOffsetsX[i]) / + interfaceCtx->perfectLettersColorTimer; + if (interfaceCtx->perfectLettersOffsetX[i] >= sPerfectLettersType2SpellingOffsetsX[i]) { + interfaceCtx->perfectLettersOffsetX[i] -= colorStepR; + } else { + interfaceCtx->perfectLettersOffsetX[i] += colorStepR; + } + } else if (interfaceCtx->perfectLettersState[i] == PERFECT_LETTERS_STATE_EXIT) { + // Spread out the letters horizontally from the spelt-out world to offscreen + colorStepR = ABS_ALT(interfaceCtx->perfectLettersOffsetX[i] - sPerfectLettersType2OffScreenOffsetsX[i]) / + interfaceCtx->perfectLettersColorTimer; + if (interfaceCtx->perfectLettersOffsetX[i] >= sPerfectLettersType2OffScreenOffsetsX[i]) { + interfaceCtx->perfectLettersOffsetX[i] -= colorStepR; + } else { + interfaceCtx->perfectLettersOffsetX[i] += colorStepR; + } + } + } + + if ((interfaceCtx->perfectLettersState[0] == PERFECT_LETTERS_STATE_SPREAD) || + (interfaceCtx->perfectLettersState[0] == PERFECT_LETTERS_STATE_EXIT)) { + if (interfaceCtx->perfectLettersState[0] == PERFECT_LETTERS_STATE_EXIT) { + colorStepA = interfaceCtx->perfectLettersPrimColor[3] / interfaceCtx->perfectLettersColorTimer; + interfaceCtx->perfectLettersPrimColor[3] -= colorStepA; + } + interfaceCtx->perfectLettersColorTimer--; + if (interfaceCtx->perfectLettersColorTimer == 0) { + + if (interfaceCtx->perfectLettersState[0] == PERFECT_LETTERS_STATE_SPREAD) { + for (i = 0; i < PERFECT_LETTERS_NUM_LETTERS; i++) { + interfaceCtx->perfectLettersState[i] = PERFECT_LETTERS_STATE_DISPLAY; + } + interfaceCtx->perfectLettersColorTimer = 20; + } else { + for (i = 0; i < PERFECT_LETTERS_NUM_LETTERS; i++) { + interfaceCtx->perfectLettersState[i] = PERFECT_LETTERS_STATE_OFF; + } + interfaceCtx->perfectLettersOn = false; + } + } + } -s16 D_801BFC98[] = { - 78, 54, 29, 5, -18, -42, -67, -85, + // Initialize the next letter in the list + if (interfaceCtx->perfectLettersState[interfaceCtx->perfectLettersCount] == PERFECT_LETTERS_STATE_OFF) { + if (interfaceCtx->perfectLettersCount < PERFECT_LETTERS_NUM_LETTERS) { + interfaceCtx->perfectLettersState[interfaceCtx->perfectLettersCount] = PERFECT_LETTERS_STATE_INIT; + interfaceCtx->perfectLettersCount++; + } + } + + // Update letter colors + if (interfaceCtx->perfectLettersCount == PERFECT_LETTERS_NUM_LETTERS) { + if (interfaceCtx->perfectLettersState[PERFECT_LETTERS_NUM_LETTERS - 1] == PERFECT_LETTERS_STATE_DISPLAY) { + + colorStepR = ABS_ALT(interfaceCtx->perfectLettersPrimColor[0] - + sPerfectLettersType2PrimColorTargets[interfaceCtx->perfectLettersColorIndex][0]) / + interfaceCtx->perfectLettersColorTimer; + colorStepG = ABS_ALT(interfaceCtx->perfectLettersPrimColor[1] - + sPerfectLettersType2PrimColorTargets[interfaceCtx->perfectLettersColorIndex][1]) / + interfaceCtx->perfectLettersColorTimer; + colorStepB = ABS_ALT(interfaceCtx->perfectLettersPrimColor[2] - + sPerfectLettersType2PrimColorTargets[interfaceCtx->perfectLettersColorIndex][2]) / + interfaceCtx->perfectLettersColorTimer; + + if (interfaceCtx->perfectLettersPrimColor[0] >= + sPerfectLettersType2PrimColorTargets[interfaceCtx->perfectLettersColorIndex][0]) { + interfaceCtx->perfectLettersPrimColor[0] -= colorStepR; + } else { + interfaceCtx->perfectLettersPrimColor[0] += colorStepR; + } + + if (interfaceCtx->perfectLettersPrimColor[1] >= + sPerfectLettersType2PrimColorTargets[interfaceCtx->perfectLettersColorIndex][1]) { + interfaceCtx->perfectLettersPrimColor[1] -= colorStepG; + } else { + interfaceCtx->perfectLettersPrimColor[1] += colorStepG; + } + + if (interfaceCtx->perfectLettersPrimColor[2] >= + sPerfectLettersType2PrimColorTargets[interfaceCtx->perfectLettersColorIndex][2]) { + interfaceCtx->perfectLettersPrimColor[2] -= colorStepB; + } else { + interfaceCtx->perfectLettersPrimColor[2] += colorStepB; + } + + interfaceCtx->perfectLettersColorTimer--; + if (interfaceCtx->perfectLettersColorTimer == 0) { + interfaceCtx->perfectLettersColorTimer = 20; + interfaceCtx->perfectLettersColorIndex ^= 1; + interfaceCtx->perfectLettersTimer++; + if (interfaceCtx->perfectLettersTimer == 6) { + for (i = 0; i < PERFECT_LETTERS_NUM_LETTERS; i++) { + interfaceCtx->perfectLettersState[i] = PERFECT_LETTERS_STATE_EXIT; + } + interfaceCtx->perfectLettersColorTimer = 5; + } + } + } + } +} + +// Targets to offset each letter to properly spell "PERFECT!" +s16 sPerfectLettersType3SpellingOffsetsX[PERFECT_LETTERS_NUM_LETTERS] = { + 78, // P + 54, // E + 29, // R + 5, // F + -18, // E + -42, // C + -67, // T + -85, // ! }; -u16 D_801BFCA8[] = { - 0xC000, 0xE000, 0x0000, 0x2000, 0xA000, 0x8000, 0x6000, 0x4000, + +// Targets to sweep each letter's angle along an elliptical spiral offscreen +u16 sPerfectLettersType3OffScreenAngles[PERFECT_LETTERS_NUM_LETTERS] = { + 6 * PERFECT_LETTERS_ANGLE_PER_LETTER, // P + 7 * PERFECT_LETTERS_ANGLE_PER_LETTER, // E + 0 * PERFECT_LETTERS_ANGLE_PER_LETTER, // R + 1 * PERFECT_LETTERS_ANGLE_PER_LETTER, // F + 5 * PERFECT_LETTERS_ANGLE_PER_LETTER, // E + 4 * PERFECT_LETTERS_ANGLE_PER_LETTER, // C + 3 * PERFECT_LETTERS_ANGLE_PER_LETTER, // T + 2 * PERFECT_LETTERS_ANGLE_PER_LETTER, // ! }; -s16 D_801BFCB8[2][3] = { + +s16 sPerfectLettersType3PrimColorTargets[2][3] = { { 255, 255, 255 }, { 255, 165, 55 }, }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8011BF70.s") +void Interface_UpdatePerfectLettersType3(PlayState* play) { + s16 i; + InterfaceContext* interfaceCtx = &play->interfaceCtx; + s16 colorStepR; + s16 colorStepG; + s16 colorStepB; + s16 j = 0; + + // Update letter positions + for (i = 0; i < interfaceCtx->perfectLettersCount; i++, j += 4) { + if (interfaceCtx->perfectLettersState[i] == PERFECT_LETTERS_STATE_INIT) { + // Initialize letter positions along the elliptical spirals + interfaceCtx->perfectLettersAngles[i] = i * (0x10000 / PERFECT_LETTERS_NUM_LETTERS); + interfaceCtx->perfectLettersSemiAxisX[i] = 200.0f; + interfaceCtx->perfectLettersSemiAxisY[i] = 200.0f; + + interfaceCtx->perfectLettersOffsetX[i] = 0; + interfaceCtx->perfectLettersState[i] = PERFECT_LETTERS_STATE_ENTER; + } else if (interfaceCtx->perfectLettersState[i] == PERFECT_LETTERS_STATE_ENTER) { + // Swirl inwards along elliptical spirals to the center of the screen + interfaceCtx->perfectLettersAngles[i] -= 0x800; + interfaceCtx->perfectLettersSemiAxisX[i] -= 8.0f; + interfaceCtx->perfectLettersSemiAxisY[i] -= 8.0f; + + if (interfaceCtx->perfectLettersSemiAxisX[i] <= 0.0f) { + // The letter has reached the center of the screen + interfaceCtx->perfectLettersSemiAxisY[i] = 0.0f; + interfaceCtx->perfectLettersSemiAxisX[i] = 0.0f; + interfaceCtx->perfectLettersState[i] = PERFECT_LETTERS_STATE_STATIONARY; + + if (i == (PERFECT_LETTERS_NUM_LETTERS - 1)) { + // The last letter has reached the center of the screen + interfaceCtx->perfectLettersColorTimer = 5; + interfaceCtx->perfectLettersState[0] = interfaceCtx->perfectLettersState[1] = + interfaceCtx->perfectLettersState[2] = interfaceCtx->perfectLettersState[3] = + interfaceCtx->perfectLettersState[4] = interfaceCtx->perfectLettersState[5] = + interfaceCtx->perfectLettersState[6] = interfaceCtx->perfectLettersState[7] = + PERFECT_LETTERS_STATE_SPREAD; + } + } + } else if (interfaceCtx->perfectLettersState[i] == PERFECT_LETTERS_STATE_SPREAD) { + // Spread out the letters horizontally from the center to the spelt-out word + colorStepR = ABS_ALT(interfaceCtx->perfectLettersOffsetX[i] - sPerfectLettersType3SpellingOffsetsX[i]) / + interfaceCtx->perfectLettersColorTimer; + if (interfaceCtx->perfectLettersOffsetX[i] >= sPerfectLettersType3SpellingOffsetsX[i]) { + interfaceCtx->perfectLettersOffsetX[i] -= colorStepR; + } else { + interfaceCtx->perfectLettersOffsetX[i] += colorStepR; + } + } else if (interfaceCtx->perfectLettersState[i] == PERFECT_LETTERS_STATE_EXIT) { + // Swirl outwards along elliptical spirals offscreen + interfaceCtx->perfectLettersAngles[i] -= 0x800; + if (interfaceCtx->perfectLettersAngles[i] == (u16)(sPerfectLettersType3OffScreenAngles[i] - 0x8000)) { + interfaceCtx->perfectLettersState[i] = PERFECT_LETTERS_STATE_OFF; + } + } + } -TexturePtr D_801BFCC4[] = { - gMinigameLetterPTex, gMinigameLetterETex, gMinigameLetterRTex, gMinigameLetterFTex, - gMinigameLetterETex, gMinigameLetterCTex, gMinigameLetterTTex, gMinigameExclamationTex, + if (interfaceCtx->perfectLettersState[0] == PERFECT_LETTERS_STATE_SPREAD) { + interfaceCtx->perfectLettersColorTimer--; + if (interfaceCtx->perfectLettersColorTimer == 0) { + for (i = 0; i < PERFECT_LETTERS_NUM_LETTERS; i++) { + interfaceCtx->perfectLettersState[i] = PERFECT_LETTERS_STATE_DISPLAY; + } + interfaceCtx->perfectLettersColorTimer = 20; + } + } + + // Initialize the next letter in the list + if ((interfaceCtx->perfectLettersState[interfaceCtx->perfectLettersCount] == PERFECT_LETTERS_STATE_OFF) && + (interfaceCtx->perfectLettersCount < PERFECT_LETTERS_NUM_LETTERS)) { + interfaceCtx->perfectLettersState[interfaceCtx->perfectLettersCount] = PERFECT_LETTERS_STATE_INIT; + interfaceCtx->perfectLettersCount++; + } + + // Update letter colors + if ((interfaceCtx->perfectLettersCount == PERFECT_LETTERS_NUM_LETTERS) && + (interfaceCtx->perfectLettersState[PERFECT_LETTERS_NUM_LETTERS - 1] == PERFECT_LETTERS_STATE_DISPLAY)) { + + colorStepR = ABS_ALT(interfaceCtx->perfectLettersPrimColor[0] - + sPerfectLettersType3PrimColorTargets[interfaceCtx->perfectLettersColorIndex][0]) / + interfaceCtx->perfectLettersColorTimer; + colorStepG = ABS_ALT(interfaceCtx->perfectLettersPrimColor[1] - + sPerfectLettersType3PrimColorTargets[interfaceCtx->perfectLettersColorIndex][1]) / + interfaceCtx->perfectLettersColorTimer; + colorStepB = ABS_ALT(interfaceCtx->perfectLettersPrimColor[2] - + sPerfectLettersType3PrimColorTargets[interfaceCtx->perfectLettersColorIndex][2]) / + interfaceCtx->perfectLettersColorTimer; + + if (interfaceCtx->perfectLettersPrimColor[0] >= + sPerfectLettersType3PrimColorTargets[interfaceCtx->perfectLettersColorIndex][0]) { + interfaceCtx->perfectLettersPrimColor[0] -= colorStepR; + } else { + interfaceCtx->perfectLettersPrimColor[0] += colorStepR; + } + + if (interfaceCtx->perfectLettersPrimColor[1] >= + sPerfectLettersType3PrimColorTargets[interfaceCtx->perfectLettersColorIndex][1]) { + interfaceCtx->perfectLettersPrimColor[1] -= colorStepG; + } else { + interfaceCtx->perfectLettersPrimColor[1] += colorStepG; + } + + if (interfaceCtx->perfectLettersPrimColor[2] >= + sPerfectLettersType3PrimColorTargets[interfaceCtx->perfectLettersColorIndex][2]) { + interfaceCtx->perfectLettersPrimColor[2] -= colorStepB; + } else { + interfaceCtx->perfectLettersPrimColor[2] += colorStepB; + } + + interfaceCtx->perfectLettersColorTimer--; + if (interfaceCtx->perfectLettersColorTimer == 0) { + interfaceCtx->perfectLettersColorTimer = 20; + interfaceCtx->perfectLettersColorIndex ^= 1; + interfaceCtx->perfectLettersTimer++; + if (interfaceCtx->perfectLettersTimer == 6) { + for (i = 0; i < PERFECT_LETTERS_NUM_LETTERS; i++) { + interfaceCtx->perfectLettersSemiAxisX[i] = 140.0f; + interfaceCtx->perfectLettersSemiAxisY[i] = 100.0f; + interfaceCtx->perfectLettersAngles[i] = sPerfectLettersType3OffScreenAngles[i]; + interfaceCtx->perfectLettersState[i] = PERFECT_LETTERS_STATE_EXIT; + } + interfaceCtx->perfectLettersColorTimer = 5; + } + } + } + + j = 0; + for (i = 0; i < PERFECT_LETTERS_NUM_LETTERS; i++) { + if (interfaceCtx->perfectLettersState[i] == PERFECT_LETTERS_STATE_OFF) { + j++; + } + } + + if (j == PERFECT_LETTERS_NUM_LETTERS) { + interfaceCtx->perfectLettersOn = false; + } +} + +TexturePtr sPerfectLettersTextures[] = { + gPerfectLetterPTex, gPerfectLetterETex, gPerfectLetterRTex, gPerfectLetterFTex, + gPerfectLetterETex, gPerfectLetterCTex, gPerfectLetterTTex, gPerfectLetterExclamationTex, }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8011C4C4.s") +void Interface_DrawPerfectLetters(PlayState* play) { + InterfaceContext* interfaceCtx = &play->interfaceCtx; + f32 letterX; + f32 letterY; + s16 i; + s16 vtxOffset; + + OPEN_DISPS(play->state.gfxCtx); + + func_8012C8D4(play->state.gfxCtx); + + gSPMatrix(OVERLAY_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetCombineLERP(OVERLAY_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, + PRIMITIVE, 0); + + for (vtxOffset = 0, i = 0; i < PERFECT_LETTERS_NUM_LETTERS; vtxOffset += 4, i++) { + if (interfaceCtx->perfectLettersState[i] != PERFECT_LETTERS_STATE_OFF) { + + // The positions follow the path of an elliptical spiral + letterX = Math_SinS(interfaceCtx->perfectLettersAngles[i]) * interfaceCtx->perfectLettersSemiAxisX[i]; + letterY = Math_CosS(interfaceCtx->perfectLettersAngles[i]) * interfaceCtx->perfectLettersSemiAxisY[i]; + + // Draw Minigame Perfect Shadows + gDPPipeSync(OVERLAY_DISP++); + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 0, interfaceCtx->perfectLettersPrimColor[3]); + + Matrix_Translate(letterX, letterY, 0.0f, MTXMODE_NEW); + Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + + gSPMatrix(OVERLAY_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPVertex(OVERLAY_DISP++, &interfaceCtx->actionVtx[44 + vtxOffset], 4, 0); + + OVERLAY_DISP = Gfx_DrawTexQuad4b(OVERLAY_DISP, sPerfectLettersTextures[i], 4, 32, 33, 0); + + // Draw Minigame Perfect Colored Letters + gDPPipeSync(OVERLAY_DISP++); + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, interfaceCtx->perfectLettersPrimColor[0], + interfaceCtx->perfectLettersPrimColor[1], interfaceCtx->perfectLettersPrimColor[2], + interfaceCtx->perfectLettersPrimColor[3]); + + Matrix_Translate(letterX, letterY, 0.0f, MTXMODE_NEW); + Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + + gSPMatrix(OVERLAY_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPVertex(OVERLAY_DISP++, &interfaceCtx->actionVtx[76 + vtxOffset], 4, 0); + + OVERLAY_DISP = Gfx_DrawTexQuad4b(OVERLAY_DISP, sPerfectLettersTextures[i], 4, 32, 33, 0); + } + } + + CLOSE_DISPS(play->state.gfxCtx); +} void Interface_StartMoonCrash(PlayState* play) { if (play->actorCtx.flags & ACTORCTX_FLAG_1) { @@ -3005,7 +3821,7 @@ void Interface_DrawTimers(PlayState* play) { case TIMER_STATE_START: case TIMER_STATE_ALT_START: sTimerStateTimer = 20; - if (interfaceCtx->unk_280 != 0) { + if (interfaceCtx->minigameState != MINIGAME_STATE_NONE) { // Set the timer position gSaveContext.timerX[sTimerId] = 26; @@ -3018,7 +3834,8 @@ void Interface_DrawTimers(PlayState* play) { gSaveContext.timerY[sTimerId] = 46; } - if ((interfaceCtx->unk_280 == 8) || (interfaceCtx->unk_280 == 30)) { + if ((interfaceCtx->minigameState == MINIGAME_STATE_COUNTDOWN_GO) || + (interfaceCtx->minigameState == MINIGAME_STATE_PLAYING)) { if (gSaveContext.timerStates[sTimerId] == TIMER_STATE_START) { gSaveContext.timerStates[sTimerId] = TIMER_STATE_COUNTING; } else { @@ -3150,7 +3967,7 @@ void Interface_DrawTimers(PlayState* play) { OSTIME_TO_TIMER(osTime - ((void)0, gSaveContext.timerStartOsTimes[sTimerId]) - ((void)0, gSaveContext.timerPausedOsTimes[sTimerId])); - if ((gSaveContext.minigameState == 1) && + if ((gSaveContext.minigameStatus == MINIGAME_STATUS_ACTIVE) && (gSaveContext.save.entrance == ENTRANCE(ROMANI_RANCH, 0))) { if (gSaveContext.timerStopTimes[sTimerId] >= SECONDS_TO_TIMER(120)) { gSaveContext.timerStopTimes[sTimerId] = SECONDS_TO_TIMER(120); @@ -3261,7 +4078,8 @@ void Interface_DrawTimers(PlayState* play) { osTime = SECONDS_TO_TIMER(0); } - if ((gSaveContext.minigameState == 1) && (gSaveContext.save.entrance == ENTRANCE(ROMANI_RANCH, 0))) { + if ((gSaveContext.minigameStatus == MINIGAME_STATUS_ACTIVE) && + (gSaveContext.save.entrance == ENTRANCE(ROMANI_RANCH, 0))) { if (osTime >= SECONDS_TO_TIMER(120)) { osTime = SECONDS_TO_TIMER(120); } @@ -3276,7 +4094,8 @@ void Interface_DrawTimers(PlayState* play) { Interface_GetTimerDigits(osTime, sTimerDigits); // Use seconds to determine when to beep - if ((gSaveContext.minigameState == 1) && (gSaveContext.save.entrance == ENTRANCE(ROMANI_RANCH, 0))) { + if ((gSaveContext.minigameStatus == MINIGAME_STATUS_ACTIVE) && + (gSaveContext.save.entrance == ENTRANCE(ROMANI_RANCH, 0))) { if ((gSaveContext.timerCurTimes[sTimerId] > SECONDS_TO_TIMER(110)) && (sTimerBeepSfxSeconds != sTimerDigits[4])) { play_sound(NA_SE_SY_WARNING_COUNT_E); @@ -3313,7 +4132,7 @@ void Interface_DrawTimers(PlayState* play) { } else { gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, 255); } - } else if ((gSaveContext.minigameState == 1) && + } else if ((gSaveContext.minigameStatus == 1) && (gSaveContext.save.entrance == ENTRANCE(ROMANI_RANCH, 0))) { if (gSaveContext.timerCurTimes[sTimerId] >= SECONDS_TO_TIMER(110)) { gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 50, 0, 255); @@ -3447,7 +4266,121 @@ void Interface_UpdateBottleTimers(PlayState* play) { } } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8011E730.s") +void Interface_DrawMinigameIcons(PlayState* play) { + InterfaceContext* interfaceCtx = &play->interfaceCtx; + s16 i; + s16 numDigitsDrawn; + s16 rectX; + s16 rectY; + s16 width; + s16 height; + + OPEN_DISPS(play->state.gfxCtx); + + func_8012C654(play->state.gfxCtx); + + if ((play->pauseCtx.state == 0) && (play->pauseCtx.debugEditor == DEBUG_EDITOR_NONE)) { + // Carrots rendering if the action corresponds to riding a horse + if (interfaceCtx->unk_212 == 8) { + // Load Carrot Icon + gDPLoadTextureBlock(OVERLAY_DISP++, gCarrotIconTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 16, 16, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + + rectX = 110; + rectY = (interfaceCtx->minigameState != MINIGAME_STATE_NONE) ? 200 : 56; + + // Draw 6 carrots + for (i = 1; i < 7; i++, rectX += 16) { + // Carrot Color (based on availability) + if ((interfaceCtx->numHorseBoosts == 0) || (interfaceCtx->numHorseBoosts < i)) { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 150, 255, interfaceCtx->aAlpha); + } else { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->aAlpha); + } + + gSPTextureRectangle(OVERLAY_DISP++, rectX << 2, rectY << 2, (rectX + 16) << 2, (rectY + 16) << 2, + G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + } + } + + if (gSaveContext.minigameStatus == MINIGAME_STATUS_ACTIVE) { + gDPPipeSync(OVERLAY_DISP++); + gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, + PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0); + width = 24; + height = 16; + rectX = 20; + if (gSaveContext.save.playerData.healthCapacity > 0xA0) { + rectY = 75; // two rows of hearts + } else { + rectY = 67; // one row of hearts + } + + if (gSaveContext.save.entrance == ENTRANCE(WATERFALL_RAPIDS, 1)) { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->bAlpha); + gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255); + gDPLoadTextureBlock(OVERLAY_DISP++, gBeaverRingIconTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 24, 16, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + } else if (play->sceneId == SCENE_DOUJOU) { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 140, 50, interfaceCtx->bAlpha); + gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255); + gDPLoadTextureBlock(OVERLAY_DISP++, gSwordTrainingLogIconTex, G_IM_FMT_IA, G_IM_SIZ_8b, 24, 16, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + } else if (play->sceneId == SCENE_30GYOSON) { + width = 16; + height = 30; + rectX = 24; + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 100, 75, interfaceCtx->bAlpha); + gDPSetEnvColor(OVERLAY_DISP++, 55, 55, 0, 255); + gDPLoadTextureBlock(OVERLAY_DISP++, gFishermanMinigameTorchIconTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 30, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + } else { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->bAlpha); + gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255); + gDPLoadTextureBlock(OVERLAY_DISP++, gArcheryScoreIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 24, 16, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + } + + gSPTextureRectangle(OVERLAY_DISP++, (rectX << 2), (rectY << 2), ((rectX + width) << 2), + ((rectY + height) << 2), G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + gDPPipeSync(OVERLAY_DISP++); + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->bAlpha); + gDPSetCombineLERP(OVERLAY_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, + 0, PRIMITIVE, 0); + + if (play->sceneId == SCENE_30GYOSON) { + rectX += 20; + if (gSaveContext.save.playerData.healthCapacity > 0xA0) { + rectY = 87; // two rows of hearts + } else { + rectY = 79; // one row of hearts + } + } else { + rectX += 26; + } + + for (i = 0, numDigitsDrawn = 0; i < 4; i++) { + if ((sMinigameScoreDigits[i] != 0) || (numDigitsDrawn != 0) || (i >= 3)) { + OVERLAY_DISP = + Gfx_DrawTexRectI8(OVERLAY_DISP, ((u8*)gCounterDigit0Tex + (8 * 16 * sMinigameScoreDigits[i])), + 8, 0x10, rectX, rectY - 2, 9, 0xFA, 0x370, 0x370); + rectX += 9; + numDigitsDrawn++; + } + } + + gDPPipeSync(OVERLAY_DISP++); + gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + } + } + + CLOSE_DISPS(play->state.gfxCtx); +} // rupeeDigitsFirst s16 D_801BFD1C[] = { 1, 0, 0, 0 }; @@ -3492,7 +4425,7 @@ TexturePtr D_801BFD8C[] = { gStoryGiantsLeavingTLUT, }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8011F0E0.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/Interface_Draw.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80120F90.s") @@ -3502,11 +4435,11 @@ u8 D_801BFD94 = 0; s16 D_801BFD98 = 0; s16 D_801BFD9C = 0; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_801210E0.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/Interface_Update.s") void Interface_Destroy(PlayState* play) { Map_Destroy(play); func_80174F9C(Interface_PostmanTimerCallback, NULL); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80121FC4.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/Interface_Init.s") |
