From b0ca99f18cbfd9c724020b23d7912443472f2ca9 Mon Sep 17 00:00:00 2001 From: Hoeloe Date: Sun, 18 Aug 2024 22:55:02 +0100 Subject: [PATCH] [Enhancement] MM3D style clock (#713) --- mm/2s2h/BenGui/BenMenuBar.cpp | 1 + mm/2s2h/Enhancements/Enhancements.cpp | 1 + mm/2s2h/Enhancements/Enhancements.h | 2 + mm/2s2h/Enhancements/Graphics/3DSClock.cpp | 350 ++++++++++++++++++ mm/2s2h/Enhancements/Graphics/3DSClock.h | 6 + mm/assets/2s2h_assets.h | 54 +++ .../gThreeDayClock3DSArrowTex.ia8.png | Bin 0 -> 15088 bytes .../gThreeDayClock3DSEdgeTex.ia8.png | Bin 0 -> 15731 bytes .../gThreeDayClock3DSFillTex.ia8.png | Bin 0 -> 15691 bytes ...ThreeDayClock3DSFinalHoursColonTex.ia8.png | Bin 0 -> 185 bytes ...hreeDayClock3DSFinalHoursDigit0Tex.ia8.png | Bin 0 -> 329 bytes ...hreeDayClock3DSFinalHoursDigit1Tex.ia8.png | Bin 0 -> 262 bytes ...hreeDayClock3DSFinalHoursDigit2Tex.ia8.png | Bin 0 -> 345 bytes ...hreeDayClock3DSFinalHoursDigit3Tex.ia8.png | Bin 0 -> 364 bytes ...hreeDayClock3DSFinalHoursDigit4Tex.ia8.png | Bin 0 -> 330 bytes ...hreeDayClock3DSFinalHoursDigit5Tex.ia8.png | Bin 0 -> 376 bytes ...hreeDayClock3DSFinalHoursDigit6Tex.ia8.png | Bin 0 -> 374 bytes ...hreeDayClock3DSFinalHoursDigit7Tex.ia8.png | Bin 0 -> 336 bytes ...hreeDayClock3DSFinalHoursDigit8Tex.ia8.png | Bin 0 -> 366 bytes ...hreeDayClock3DSFinalHoursDigit9Tex.ia8.png | Bin 0 -> 342 bytes ...gThreeDayClock3DSFinalHoursMoonTex.ia8.png | Bin 0 -> 3413 bytes .../gThreeDayClock3DSMiddleTex.ia8.png | Bin 0 -> 15485 bytes .../gThreeDayClock3DSSlowTimeTex.ia8.png | Bin 0 -> 242 bytes .../gThreeDayClock3DSTimeBackdropTex.ia8.png | Bin 0 -> 15159 bytes 24 files changed, 414 insertions(+) create mode 100644 mm/2s2h/Enhancements/Graphics/3DSClock.cpp create mode 100644 mm/2s2h/Enhancements/Graphics/3DSClock.h create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSArrowTex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSEdgeTex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFillTex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursColonTex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit0Tex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit1Tex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit2Tex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit3Tex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit4Tex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit5Tex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit6Tex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit7Tex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit8Tex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit9Tex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursMoonTex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSMiddleTex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSSlowTimeTex.ia8.png create mode 100644 mm/assets/custom/textures/parameter_static/gThreeDayClock3DSTimeBackdropTex.ia8.png diff --git a/mm/2s2h/BenGui/BenMenuBar.cpp b/mm/2s2h/BenGui/BenMenuBar.cpp index 4a1dd56e9..9d5d00378 100644 --- a/mm/2s2h/BenGui/BenMenuBar.cpp +++ b/mm/2s2h/BenGui/BenMenuBar.cpp @@ -48,6 +48,7 @@ static std::unordered_map windowBackendsMap = static const std::unordered_map clockTypeOptions = { { CLOCK_TYPE_ORIGINAL, "Original" }, + { CLOCK_TYPE_3DS, "MM3D style" }, { CLOCK_TYPE_TEXT_BASED, "Text only" }, }; diff --git a/mm/2s2h/Enhancements/Enhancements.cpp b/mm/2s2h/Enhancements/Enhancements.cpp index ae30f2361..99c9a00c5 100644 --- a/mm/2s2h/Enhancements/Enhancements.cpp +++ b/mm/2s2h/Enhancements/Enhancements.cpp @@ -16,6 +16,7 @@ void InitEnhancements() { // Clock RegisterTextBasedClock(); + Register3DSClock(); // Cycle & Saving RegisterEndOfCycleSaveHooks(); diff --git a/mm/2s2h/Enhancements/Enhancements.h b/mm/2s2h/Enhancements/Enhancements.h index 7aa780c7f..7da2ad77a 100644 --- a/mm/2s2h/Enhancements/Enhancements.h +++ b/mm/2s2h/Enhancements/Enhancements.h @@ -8,6 +8,7 @@ #include "Cheats/Infinite.h" #include "Dialogue/Dialogue.h" #include "Graphics/TextBasedClock.h" +#include "Graphics/3DSClock.h" #include "Cheats/Cheats.h" #include "Cheats/UnbreakableRazorSword.h" #include "Cheats/UnrestrictedItems.h" @@ -48,6 +49,7 @@ enum TimeStopOptions { enum ClockTypeOptions { CLOCK_TYPE_ORIGINAL, + CLOCK_TYPE_3DS, CLOCK_TYPE_TEXT_BASED, }; diff --git a/mm/2s2h/Enhancements/Graphics/3DSClock.cpp b/mm/2s2h/Enhancements/Graphics/3DSClock.cpp new file mode 100644 index 000000000..b28db14bc --- /dev/null +++ b/mm/2s2h/Enhancements/Graphics/3DSClock.cpp @@ -0,0 +1,350 @@ +#include +#include "2s2h/BenGui/HudEditor.h" +#include "2s2h/Enhancements/GameInteractor/GameInteractor.h" +#include "2s2h/Enhancements/Enhancements.h" +#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h" +#include "misc/title_static/title_static.h" +#include "2s2h_assets.h" + +extern "C" { +#include +#include +#include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h" +#include "interface/parameter_static/parameter_static.h" + +extern PlayState* gPlayState; +Gfx* Gfx_DrawTexRectIA8(Gfx* gfx, TexturePtr texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, s16 rectTop, + s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy); + +Gfx* Gfx_DrawTexRectIA8_DropShadow(Gfx* gfx, TexturePtr texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, + s16 rectTop, s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy, s16 r, s16 g, s16 b, + s16 a); + +Gfx* Gfx_DrawTexRectIA8_DropShadowOffset(Gfx* gfx, TexturePtr texture, s16 textureWidth, s16 textureHeight, + s16 rectLeft, s16 rectTop, s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy, + s16 r, s16 g, s16 b, s16 a, s32 masks, s32 rects); +} + +#define SECONDS_IN_THREE_DAYS (3 * 24 * 60 * 60) +#define SECONDS_IN_SIX_HOURS (6 * 60 * 60) +#define CLOCK_SECTION_HALFWIDTH 24 +#define CLOCK_SECTION_WIDTH 48 + +static TexturePtr sDigitTextures[] = { + (TexturePtr)gFinalHoursClockDigit0Tex, (TexturePtr)gFinalHoursClockDigit1Tex, (TexturePtr)gFinalHoursClockDigit2Tex, + (TexturePtr)gFinalHoursClockDigit3Tex, (TexturePtr)gFinalHoursClockDigit4Tex, (TexturePtr)gFinalHoursClockDigit5Tex, + (TexturePtr)gFinalHoursClockDigit6Tex, (TexturePtr)gFinalHoursClockDigit7Tex, (TexturePtr)gFinalHoursClockDigit8Tex, + (TexturePtr)gFinalHoursClockDigit9Tex, (TexturePtr)gFinalHoursClockColonTex, +}; + +static TexturePtr sFinalHoursDigitTextures[] = { + (TexturePtr)gThreeDayClock3DSFinalHoursDigit0Tex, (TexturePtr)gThreeDayClock3DSFinalHoursDigit1Tex, + (TexturePtr)gThreeDayClock3DSFinalHoursDigit2Tex, (TexturePtr)gThreeDayClock3DSFinalHoursDigit3Tex, + (TexturePtr)gThreeDayClock3DSFinalHoursDigit4Tex, (TexturePtr)gThreeDayClock3DSFinalHoursDigit5Tex, + (TexturePtr)gThreeDayClock3DSFinalHoursDigit6Tex, (TexturePtr)gThreeDayClock3DSFinalHoursDigit7Tex, + (TexturePtr)gThreeDayClock3DSFinalHoursDigit8Tex, (TexturePtr)gThreeDayClock3DSFinalHoursDigit9Tex, + (TexturePtr)gThreeDayClock3DSFinalHoursColonTex, +}; + +s16 finalHoursClockSlots[8]; + +void Register3DSClock() { + + REGISTER_VB_SHOULD(GI_VB_PREVENT_CLOCK_DISPLAY, { + if (CVarGetInteger("gEnhancements.Graphics.ClockType", CLOCK_TYPE_ORIGINAL) == CLOCK_TYPE_3DS) { + *should = true; + + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + if (HudEditor_IsActiveElementHidden()) { + return; + } + + static s32 sPreviousTimeCheck = -1; + + if ((R_TIME_SPEED != 0) && + ((gPlayState->msgCtx.msgMode == MSGMODE_NONE) || + ((gPlayState->actorCtx.flags & ACTORCTX_FLAG_1) && !Play_InCsMode(gPlayState)) || + (gPlayState->msgCtx.msgMode == MSGMODE_NONE) || + ((gPlayState->msgCtx.currentTextId >= 0x100) && (gPlayState->msgCtx.currentTextId <= 0x200)) || + (gSaveContext.gameMode == GAMEMODE_END_CREDITS)) && + !FrameAdvance_IsEnabled(&gPlayState->state) && !Environment_IsTimeStopped() && + (gSaveContext.save.day <= 3)) { + + if ((gPlayState->pauseCtx.state == PAUSE_STATE_OFF) && + (gPlayState->pauseCtx.debugEditor == DEBUG_EDITOR_NONE)) { + + static s16 sThreeDayClockAlpha = 255; + + static s32 sFinalHoursIntro = 0; + + sThreeDayClockAlpha = gPlayState->interfaceCtx.aAlpha; + + OPEN_DISPS(gPlayState->state.gfxCtx); + s16 posX = 160; + s16 posY = 210; + + // Draw background of 3DS clock + // TODO: Replace this with matrix/vertex handling to avoid gaps when scaled + OVERLAY_DISP = Gfx_DrawTexRectIA8_DropShadow( + OVERLAY_DISP, (TexturePtr)gThreeDayClock3DSEdgeTex, CLOCK_SECTION_HALFWIDTH * 3, 12, + posX - (CLOCK_SECTION_HALFWIDTH * 4), posY, CLOCK_SECTION_HALFWIDTH * 3, 12, 1 << 10, 1 << 10, + 255, 255, 255, sThreeDayClockAlpha); + + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = Gfx_DrawTexRectIA8_DropShadow( + OVERLAY_DISP, (TexturePtr)gThreeDayClock3DSMiddleTex, CLOCK_SECTION_WIDTH, 12, + posX - CLOCK_SECTION_HALFWIDTH, posY, CLOCK_SECTION_WIDTH, 12, 1 << 10, 1 << 10, 255, 255, 255, + sThreeDayClockAlpha); + + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = Gfx_DrawTexRectIA8_DropShadowOffset( + OVERLAY_DISP, (TexturePtr)gThreeDayClock3DSEdgeTex, CLOCK_SECTION_HALFWIDTH * 3, 12, + posX + CLOCK_SECTION_HALFWIDTH, posY, CLOCK_SECTION_HALFWIDTH * 3, 12, 1 << 10, 1 << 10, 255, + 255, 255, sThreeDayClockAlpha, 3, (CLOCK_SECTION_HALFWIDTH * 3) << 5); + + // Coloured day markers, which highlights the current day with its own colour + u16 fillalpha = 64; + if (gSaveContext.save.day <= 1) { + fillalpha = 255; + } + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 128, 255, (fillalpha * sThreeDayClockAlpha) / 255); + + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = + Gfx_DrawTexRectIA8(OVERLAY_DISP, (TexturePtr)gThreeDayClock3DSFillTex, CLOCK_SECTION_WIDTH, 12, + posX - CLOCK_SECTION_WIDTH, posY, CLOCK_SECTION_WIDTH, 12, 1 << 10, 1 << 10); + + fillalpha = 64; + if (gSaveContext.save.day == 2) { + fillalpha = 255; + } + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 192, 0, (fillalpha * sThreeDayClockAlpha) / 255); + + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = Gfx_DrawTexRectIA8(OVERLAY_DISP, (TexturePtr)gThreeDayClock3DSFillTex, + CLOCK_SECTION_WIDTH, 12, posX - CLOCK_SECTION_HALFWIDTH, posY, + CLOCK_SECTION_WIDTH, 12, 1 << 10, 1 << 10); + + fillalpha = 64; + if (gSaveContext.save.day >= 3) { + fillalpha = 255; + } + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 64, 0, (fillalpha * sThreeDayClockAlpha) / 255); + + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = Gfx_DrawTexRectIA8(OVERLAY_DISP, (TexturePtr)gThreeDayClock3DSFillTex, + CLOCK_SECTION_WIDTH, 12, posX + CLOCK_SECTION_HALFWIDTH, posY, + CLOCK_SECTION_WIDTH, 12, 1 << 10, 1 << 10); + + // This next part is for the little arrow that shows what the current time is + + s32 timeUntilCrash = (s32)TIME_TO_SECONDS_F(TIME_UNTIL_MOON_CRASH); + + // This is a safety measure to delay skipping the arrow marker back a day on the frame before the + // day changes by just checking if time went backwards + if (sPreviousTimeCheck != -1 && sPreviousTimeCheck > SECONDS_IN_THREE_DAYS - timeUntilCrash) { + s32 trueTimeUntilCrash = timeUntilCrash; + timeUntilCrash = SECONDS_IN_THREE_DAYS - sPreviousTimeCheck; + sPreviousTimeCheck = SECONDS_IN_THREE_DAYS - trueTimeUntilCrash; + } else { + sPreviousTimeCheck = SECONDS_IN_THREE_DAYS - timeUntilCrash; + } + + // Compute the position of the arrow, and then draw it + s32 timeoffset = + std::max(std::min(3 * CLOCK_SECTION_WIDTH - + (timeUntilCrash * 3 * CLOCK_SECTION_WIDTH) / SECONDS_IN_THREE_DAYS, + 3 * CLOCK_SECTION_WIDTH), + 0); + + u16 counterX = posX - (CLOCK_SECTION_HALFWIDTH * 3) + timeoffset; + u16 counterY = posY - 4; + + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 200, 0, 0, sThreeDayClockAlpha); + + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = Gfx_DrawTexRectIA8(OVERLAY_DISP, (TexturePtr)gThreeDayClock3DSArrowTex, 8, 8, + counterX - 4, posY + 4, 8, 8, 1 << 10, 1 << 10); + + u16 curMinutes = (s32)TIME_TO_MINUTES_F(gSaveContext.save.time) % 60; + u16 curHours = (s32)TIME_TO_MINUTES_F(gSaveContext.save.time) / 60; + + // Final hours timer + if ((CURRENT_DAY >= 4) || + ((CURRENT_DAY == 3) && (((void)0, gSaveContext.save.time) >= (CLOCK_TIME(0, 0) + 5)) && + (((void)0, gSaveContext.save.time) < CLOCK_TIME(6, 0)))) { + + // This all just gets the time to display in each number slot + s32 timeInSeconds = timeUntilCrash % 60; + s32 timeInMinutes = (timeUntilCrash / 60) % 60; + s32 timeInHours = (timeUntilCrash / 60) / 60; + + finalHoursClockSlots[0] = std::min(timeInHours / 10, 9); + finalHoursClockSlots[1] = timeInHours % 10; + finalHoursClockSlots[2] = 10; + finalHoursClockSlots[3] = timeInMinutes / 10; + finalHoursClockSlots[4] = timeInMinutes % 10; + finalHoursClockSlots[5] = 10; + + finalHoursClockSlots[6] = timeInSeconds / 10; + finalHoursClockSlots[7] = timeInSeconds % 10; + + u16 finalTimerSpacing = 8; + + u16 finalTimerPos = posX - finalTimerSpacing * 4 - finalTimerSpacing / 2; + s16 i; + + s32 percentToCrash = std::min(std::max((timeUntilCrash * 255) / SECONDS_IN_SIX_HOURS, 0), 255); + + // This is a lerp between yellow and red based on the remaining time + u16 finalHoursR1 = 255; + u16 finalHoursR2 = 255; + u16 finalHoursG1 = 0; + u16 finalHoursG2 = 255; + u16 finalHoursB1 = 0; + u16 finalHoursB2 = 0; + + u16 finalHoursR = + (((255 - percentToCrash) * finalHoursR1) + (percentToCrash * finalHoursR2)) / 255; + u16 finalHoursG = + (((255 - percentToCrash) * finalHoursG1) + (percentToCrash * finalHoursG2)) / 255; + u16 finalHoursB = + (((255 - percentToCrash) * finalHoursB1) + (percentToCrash * finalHoursB2)) / 255; + + // Controls the distance and speed modifier of the final hours clock intro animation + // finalHoursOffset controls the distance offset for the intro animation + // finalHoursModifier controls the speed of the intro animation - larger is slower + s32 finalHoursOffset = 10; + s32 finalHoursModifier = 2; + if (sFinalHoursIntro < finalHoursOffset * finalHoursModifier) { + sFinalHoursIntro++; + } + + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, finalHoursR, finalHoursG, finalHoursB, + (sThreeDayClockAlpha * sFinalHoursIntro) / + (finalHoursOffset * finalHoursModifier)); + // This just loops through and draws all the numbers + for (i = 0; i < 8; i++) { + + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = Gfx_DrawTexRectIA8( + OVERLAY_DISP, sFinalHoursDigitTextures[finalHoursClockSlots[i]], 16, 16, finalTimerPos, + posY - 14 - finalHoursOffset + (sFinalHoursIntro / finalHoursModifier), 16, 16, 1 << 10, + 1 << 10); + finalTimerPos += finalTimerSpacing; + } + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = Gfx_DrawTexRectIA8( + OVERLAY_DISP, (TexturePtr)gThreeDayClock3DSFinalHoursMoonTex, 16, 16, posX - 8, + posY - 28 - finalHoursOffset + (sFinalHoursIntro / finalHoursModifier), 16, 16, 1 << 10, + 1 << 10); + } else { + + sFinalHoursIntro = 0; + + // Draw the current time in a small box + // TODO: Add scale slider to allow this box to be scaled independently of the main UI element + + // Draw the background box + if (gSaveContext.save.timeSpeedOffset == -2) { + u16 pulseTime = ((s32)TIME_TO_SECONDS_F(gSaveContext.save.time) % 120); + u16 pulse; + if (pulseTime < 60) { + pulse = (pulseTime * 255) / 60; + } else { + pulse = 255 - ((pulseTime - 60) * 255) / 60; + } + + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, pulse, pulse, 0, sThreeDayClockAlpha / 2); + } else { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 0, sThreeDayClockAlpha / 2); + } + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = Gfx_DrawTexRectIA8(OVERLAY_DISP, (TexturePtr)gThreeDayClock3DSTimeBackdropTex, + CLOCK_SECTION_WIDTH, 16, counterX - CLOCK_SECTION_HALFWIDTH, + counterY - 4, CLOCK_SECTION_WIDTH, 16, 1 << 10, 1 << 10); + + counterX -= 8; + + // Draw the sun/moon next to the current time + TexturePtr daynightmarker; + if (curHours < 6 || curHours >= 18) { + daynightmarker = (TexturePtr)gThreeDayClockMoonHourTex; + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 200, 200, 0, sThreeDayClockAlpha); + } else { + daynightmarker = (TexturePtr)gThreeDayClockSunHourTex; + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 200, 64, 0, sThreeDayClockAlpha); + } + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = Gfx_DrawTexRectI8(OVERLAY_DISP, daynightmarker, 24, 24, counterX - 11, + counterY - 2, 12, 12, 1 << 11, 1 << 11); + if (!CVarGetInteger("gEnhancements.Graphics.24HoursClock", 0)) { + curHours %= 12; + if (curHours == 0) { + curHours = 12; + } + } + + u16 curTensHours = curHours / 10; + curHours %= 10; + + u16 curTensMinutes = curMinutes / 10; + curMinutes %= 10; + + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, sThreeDayClockAlpha); + + // Inverted time + if (gSaveContext.save.timeSpeedOffset == -2) { + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = + Gfx_DrawTexRectIA8(OVERLAY_DISP, (TexturePtr)gThreeDayClock3DSSlowTimeTex, 16, 16, + counterX + 8 + 20, counterY - 4, 16, 16, 1 << 10, 1 << 10); + + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 64, 192, 255, sThreeDayClockAlpha); + } + + // Digital time + u16 timerSpacing = 6; + + if (curTensHours > 0 || CVarGetInteger("gEnhancements.Graphics.24HoursClock", 0)) { + timerSpacing = 4; + + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = Gfx_DrawTexRectI8(OVERLAY_DISP, sDigitTextures[curTensHours], 8, 8, counterX, + counterY, 8, 8, 1 << 10, 1 << 10); + counterX += timerSpacing; + } + + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = Gfx_DrawTexRectI8(OVERLAY_DISP, sDigitTextures[curHours], 8, 8, counterX, + counterY, 8, 8, 1 << 10, 1 << 10); + counterX += timerSpacing; + + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = Gfx_DrawTexRectI8(OVERLAY_DISP, sDigitTextures[10], 8, 8, counterX, counterY, 8, + 8, 1 << 10, 1 << 10); + counterX += timerSpacing; + + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = Gfx_DrawTexRectI8(OVERLAY_DISP, sDigitTextures[curTensMinutes], 8, 8, counterX, + counterY, 8, 8, 1 << 10, 1 << 10); + counterX += timerSpacing; + + HudEditor_SetActiveElement(HUD_EDITOR_ELEMENT_CLOCK); + OVERLAY_DISP = Gfx_DrawTexRectI8(OVERLAY_DISP, sDigitTextures[curMinutes], 8, 8, counterX, + counterY, 8, 8, 1 << 10, 1 << 10); + } + gDPPipeSync(OVERLAY_DISP++); + + CLOSE_DISPS(gPlayState->state.gfxCtx); + } else { + sPreviousTimeCheck = SECONDS_IN_THREE_DAYS - (s32)TIME_TO_SECONDS_F(TIME_UNTIL_MOON_CRASH); + } + } else { + sPreviousTimeCheck = SECONDS_IN_THREE_DAYS - (s32)TIME_TO_SECONDS_F(TIME_UNTIL_MOON_CRASH); + } + + hudEditorActiveElement = HUD_EDITOR_ELEMENT_NONE; + } + }); +} diff --git a/mm/2s2h/Enhancements/Graphics/3DSClock.h b/mm/2s2h/Enhancements/Graphics/3DSClock.h new file mode 100644 index 000000000..8a7dc143e --- /dev/null +++ b/mm/2s2h/Enhancements/Graphics/3DSClock.h @@ -0,0 +1,6 @@ +#ifndef MM3D_CLOCK_H +#define MM3D_CLOCK_H + +void Register3DSClock(); + +#endif // TEXT_BASED_CLOCK_H diff --git a/mm/assets/2s2h_assets.h b/mm/assets/2s2h_assets.h index e51647c4e..7a02cbe6e 100644 --- a/mm/assets/2s2h_assets.h +++ b/mm/assets/2s2h_assets.h @@ -59,6 +59,60 @@ static const ALIGN_ASSET(2) char gThreeDayClockHour24Tex[] = dgThreeDayClockHour #define dgEmptyTexture "__OTR__textures/virtual/gEmptyTexture" static const ALIGN_ASSET(2) char gEmptyTexture[] = dgEmptyTexture; +#define dgThreeDayClock3DSEdgeTex "__OTR__textures/parameter_static/gThreeDayClock3DSEdgeTex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSEdgeTex[] = dgThreeDayClock3DSEdgeTex; + +#define dgThreeDayClock3DSMiddleTex "__OTR__textures/parameter_static/gThreeDayClock3DSMiddleTex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSMiddleTex[] = dgThreeDayClock3DSMiddleTex; + +#define dgThreeDayClock3DSFillTex "__OTR__textures/parameter_static/gThreeDayClock3DSFillTex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSFillTex[] = dgThreeDayClock3DSFillTex; + +#define dgThreeDayClock3DSArrowTex "__OTR__textures/parameter_static/gThreeDayClock3DSArrowTex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSArrowTex[] = dgThreeDayClock3DSArrowTex; + +#define dgThreeDayClock3DSTimeBackdropTex "__OTR__textures/parameter_static/gThreeDayClock3DSTimeBackdropTex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSTimeBackdropTex[] = dgThreeDayClock3DSTimeBackdropTex; + +#define dgThreeDayClock3DSSlowTimeTex "__OTR__textures/parameter_static/gThreeDayClock3DSSlowTimeTex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSSlowTimeTex[] = dgThreeDayClock3DSSlowTimeTex; + +#define dgThreeDayClock3DSFinalHoursMoonTex "__OTR__textures/parameter_static/gThreeDayClock3DSFinalHoursMoonTex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSFinalHoursMoonTex[] = dgThreeDayClock3DSFinalHoursMoonTex; + +#define dgThreeDayClock3DSFinalHoursDigit0Tex "__OTR__textures/parameter_static/gThreeDayClock3DSFinalHoursDigit0Tex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSFinalHoursDigit0Tex[] = dgThreeDayClock3DSFinalHoursDigit0Tex; + +#define dgThreeDayClock3DSFinalHoursDigit1Tex "__OTR__textures/parameter_static/gThreeDayClock3DSFinalHoursDigit1Tex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSFinalHoursDigit1Tex[] = dgThreeDayClock3DSFinalHoursDigit1Tex; + +#define dgThreeDayClock3DSFinalHoursDigit2Tex "__OTR__textures/parameter_static/gThreeDayClock3DSFinalHoursDigit2Tex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSFinalHoursDigit2Tex[] = dgThreeDayClock3DSFinalHoursDigit2Tex; + +#define dgThreeDayClock3DSFinalHoursDigit3Tex "__OTR__textures/parameter_static/gThreeDayClock3DSFinalHoursDigit3Tex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSFinalHoursDigit3Tex[] = dgThreeDayClock3DSFinalHoursDigit3Tex; + +#define dgThreeDayClock3DSFinalHoursDigit4Tex "__OTR__textures/parameter_static/gThreeDayClock3DSFinalHoursDigit4Tex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSFinalHoursDigit4Tex[] = dgThreeDayClock3DSFinalHoursDigit4Tex; + +#define dgThreeDayClock3DSFinalHoursDigit5Tex "__OTR__textures/parameter_static/gThreeDayClock3DSFinalHoursDigit5Tex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSFinalHoursDigit5Tex[] = dgThreeDayClock3DSFinalHoursDigit5Tex; + +#define dgThreeDayClock3DSFinalHoursDigit6Tex "__OTR__textures/parameter_static/gThreeDayClock3DSFinalHoursDigit6Tex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSFinalHoursDigit6Tex[] = dgThreeDayClock3DSFinalHoursDigit6Tex; + +#define dgThreeDayClock3DSFinalHoursDigit7Tex "__OTR__textures/parameter_static/gThreeDayClock3DSFinalHoursDigit7Tex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSFinalHoursDigit7Tex[] = dgThreeDayClock3DSFinalHoursDigit7Tex; + +#define dgThreeDayClock3DSFinalHoursDigit8Tex "__OTR__textures/parameter_static/gThreeDayClock3DSFinalHoursDigit8Tex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSFinalHoursDigit8Tex[] = dgThreeDayClock3DSFinalHoursDigit8Tex; + +#define dgThreeDayClock3DSFinalHoursDigit9Tex "__OTR__textures/parameter_static/gThreeDayClock3DSFinalHoursDigit9Tex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSFinalHoursDigit9Tex[] = dgThreeDayClock3DSFinalHoursDigit9Tex; + +#define dgThreeDayClock3DSFinalHoursColonTex "__OTR__textures/parameter_static/gThreeDayClock3DSFinalHoursColonTex" +static const ALIGN_ASSET(2) char gThreeDayClock3DSFinalHoursColonTex[] = dgThreeDayClock3DSFinalHoursColonTex; + #define dgPauseSavePromptENGTex "__OTR__textures/icon_item_static/gPauseSavePromptENGTex" static const ALIGN_ASSET(2) char gPauseSavePromptENGTex[] = dgPauseSavePromptENGTex; diff --git a/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSArrowTex.ia8.png b/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSArrowTex.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..7adecac9920041b50795fedce478678c8f3aa392 GIT binary patch literal 15088 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 literal 0 HcmV?d00001 diff --git a/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFillTex.ia8.png b/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFillTex.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..100afdb6312ccd85f7b37058937f4d57c363a961 GIT binary patch literal 15691 zcmeAS@N?(olHy`uVBq!ia0y~yU@%}{VBq0kV_;xV*<}~Vz`(#+;1OBOz`!jG!i)^F z=14Fw*wki*M3hAM`dB6B=jtV<RP5H8|x+; z8yH!nCL1Q1C8mNsiK-pLXqWutQcybZbg_eE{FMCU%oHnlva&KtF*P+wGBMRPHZnKT zH8f03(@iq9G}BEnG_kNSvoteFu}p?pgk%_oMgB#Z>6v+nIY??ieo4tpu}U&cGfXv4 zG}bjsG_ue&N;R?2O)^VK)=f1`GB!*#u}m|wFojux#TX2$JTi+*@{1~wQW>no2u>|T z6@^LUWP(eOg2bZYR8YpWRf6SAc##81uMpA(oWZRUlR;&VT{0;7rl#2FqlhA$1E<~=_VN(CFz=`nxyI`CK;RR8mFcir6rlAni!j#z@ix` z7SX+kh-z>E<0*w80R~ou+Yr?7B%*+Xn2M?mxADmtiFxU%DR%lWpTPvswG8H%Bd$Dz z1PpmGhgR}Kj2hB02Z>MAG7(nJVwRych&sVJKPSJ)H$NrS&e%pDn=m5fAnAgY{Em6a zsh|S77_|fdHw~Q<(@{l1SqWNRV6UH&lFU=m(o$1(jSZ8a^^=8VqJeIjVTwtTsYQxO ziiIJ>qv%BrL=@FVWbfc}uT4s_Ra$;gZeodDW^Q77s(wLUx{W?U5GepattBh}qRiC1 zl0_fT__ZQSqiaRz49&|du``0& zh9-=p3)G~u0;h)Hg2d!hJ2O*LV^bS_bYXNI0htx4IT0?Ixv6=@nfZBkCKgaV=n_~p zMj|vC8X;>$l7MQ2L@`o70i3uXqCqZhc3d|4;O-5ms{@vTSJkv)KpjRa<00mbS^^0N zBFWLsqfNH`Eljs_Qz0R>Su z8eEWYAd(ynE+PX8qHHv{AmKnHIT~C<1{6fuXmCNofk<*RxQGlWh_cb(f`kK+qqrn9U2O`PQ;36`hAj(FA3la`QlB2;zWI#cbjRqGa9Ec=GgNw+3f+!meE=V{K zNsa~=kpTr!HX2-za3GQ#4K5-B3ZiT@xFF#`Bsm&fLqG_5gAYrWuw6b2?rv{(cmI7pdiXdg9{Q4M3SSyMPxuhl#K=#Bpiq&M}v#V zfPyF+4K7GH5J}<F!Nq_$Tw?7=f=ELJG(^Hjjg?X`@ z#G?jQFY^m0{;);OKJT=CLe$k44ofy`glX=O&z)SNm6YH6<3NTgA5*3Yx!Qn0K4=i$c|7`6}a&swyfq512nV2VPyZ zs&vc#xqJ;`onl4_x=Z)`T+w}5IVH)}xOwJ9-b35&KWA1F%DTy4b?)cRy}{CqoDN?- oCT6HH^R0i+uuYI%{vnePtIWNld&`6v7#J8lUHx3vIVCg!0Be##i2wiq literal 0 HcmV?d00001 diff --git a/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit0Tex.ia8.png b/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit0Tex.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..e72e0ebb46812441d6d9f5809dc5df4e0e402c71 GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s77>k44ofy`glX=O&z{u?B z;uvDld$xC@*Wm<_R(lf#$$tlrI{p_wVQi7|iE-0Y)pfxsia0OGvFx~XKqM8VEsHKbn2>AlZyQs>LgkHr80 literal 0 HcmV?d00001 diff --git a/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit1Tex.ia8.png b/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit1Tex.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..cf6b069e230f250c8ed269f51b77e731afdffa7b GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s77>k44ofy`glX=O&z;M9R z#WBR9_v{2)u0sw2Zt_YkA&qww_ok$NWUy>#|G*<=c000yG4TAPII)||9uAixm)|VX z;W7JZ=q4bqqjUJ3c|O~}nLDrTx)L=#Q9{rDuT8L5tc%N>;z=qex4wS3Wa+k3n{wtq z-^sLM)vE2m$_ibJwi>2A+{>=O(bRv1aa-oBt{|^9TZ2Sg-*a4^cI%jBIdfm3%>K96 zwlOydZ;)PeTa@9!eqITe+k9~m+4HsPCipZnD||If=8-8__x^hzm;FOVW>^3K literal 0 HcmV?d00001 diff --git a/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit2Tex.ia8.png b/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit2Tex.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..490226fa2c2f3d112b75dc2364d703d63f25ca3f GIT binary patch literal 345 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s77>k44ofy`glX=O&z$onL z;uvDldv>C2R!e|LEB_?7M~6>oiEYalE@bxnZ>CVTZR4gBM{IpQnh9Lu-O(x_UB6st zwnLC7Tk{gTOg9O&)@8Gqx9^-@{I2{yvtF1}$J+P57r+0#SRmDZ(0i{q9=MgxlMC7IiS(W00AoqUhWz1l6W82?VTmQ|wugJkPYuV2Dl3B|t#oHd%$+%Bia&6YOT;T)U4Y!Xn zXg}h$YuRj_(+QDcGRGSe zC6+(_Z7MKZ_|4~AIzkLT7y=k~*uDNQlPb944$rjF6*2UngDHf Bl9vDg literal 0 HcmV?d00001 diff --git a/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit3Tex.ia8.png b/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit3Tex.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..75f6e24b207eede355753b673e369b940550e131 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s77>k44ofy`glX=O&z^LZw z;uvDldv=0h_Mrfg*7E@qc-GIj>sTOsk?$Sj|Hj$Q*WJx_ZxyjBKlef*c1~>0_D7d) zo|^12%U)q=;E|=#AB#JKHJ8nnzw_|kY0Ej)OE({tFy?4V5NA1fPQv)d`idP9Iu?)S z9F{QFQCSzZdh*vQUWfJ97vFxn>Hhn|bAc;E)LeNw9?z)T-@nA%^Y+II9*5OeZ;5dx zs^0ag(wOR1zW8DWtAMNEzW3|7<`yoA(W{sFe<8 z+tJTuW}khwJZ$yec_tYqQt=F)lN4ThUdpnX%M`Hwx_!4wL{v88iA_B^rx`X}dsKPv z(~`y|)t;XXcswspG4bU*Ea3UMCcH!2)7bNg>FMk44ofy`glX=O&z{uk1 z;uvDldv&6r_u&8$H~voVZDrg`qqmu?F5&9uo5{7vDa}!^{etHHMbXRrUizk44ofy`glX=O&z-Z*@ z;uvDldvuba_hAQ_qw_nPuV0W>Nw#<3-;_G}fNxn@vAENL30GH^6rEx(c*XwWfkNpQ z?Hei!oToLdYkalf#?q6;1|3JXyn)L-=~>dY{X0{#-e| z>CcR_Y0pnT{gk$PaZuJlUW>lZ_ukyk=URO=D=_rx!wMTWnd1x$nyNad57pS!XPHL0 z&sxS%5WD`Z#?pDS!_RN(xtsUBXu1K1qS5)!T5Cfsui&`Cw-4pKDV0-+$kKKTd?Tdy#_Y zuYLZCN0L`JCQ1Zrsx~Vm%zJ+3^BhM30SBfBYpyPM#&p1T-?IZ%^?TM8UbgRGEMYjY jYaeUD_UvExKXLv^o*Og$`?sqM3=9mOu6{1-oD!M<+M%o` literal 0 HcmV?d00001 diff --git a/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit6Tex.ia8.png b/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit6Tex.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..d1dd11b1fc6d7be8664a7c687dad134f91696324 GIT binary patch literal 374 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s77>k44ofy`glX=O&z-Zv< z;uvDldv>C2_Mrfgw)>YH_8gYA5{+v2K5|fT_k#k({YnpHKIzNsDi?orZR_Oyi(8~i zc9eLuFVdQ&MBb@076uxFaQ7m literal 0 HcmV?d00001 diff --git a/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit7Tex.ia8.png b/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursDigit7Tex.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..0793f0f11dc57d5e6a049e6da6c39e2f5d01f644 GIT binary patch literal 336 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s77>k44ofy`glX=O&z{ut4 z;uvDldvv0r_mKjLWA*R$ZzwKJOid6zxAm!aa)O}Fb>AlM&k=?l2Xnr1#|WuOn5>n^ zIqvW#cz?s&vgA9*vIQRA*m+p=@6q<>mGjx-e&lbvbtu8W;)~7uD9x>VSDE{6KCwwh z=k%w%$FA2)pI>iydGUfokkN$G%b!M)U&>c{4pvyvjkmSwJ5q@nj)&w@FQ rfzi)Qa<|x-#_9tMWxu!m*PZ`qcfNOz-^-&63=9mOu6{1-oD!Mk44ofy`glX=O&z^LKr z;uvDldv@abyygIrWBb=MDXdf2!OOa>k$uGj)d^c$mPa<_INg0?u(`H%=}up*fEi2M z9D;+df0+H!XYY*{^O(Fhi>w-$xo6~we_^}s+#)6XzTC$pExi7 X*kEz-e)Uua1_lOCS3j3^P6k44ofy`glX=O&z$oD9 z;uvDldv=0h)?o($SNkQC5~QbZj1pyQ=2O_9b>AUeU{`DP{e!1CH)+-q<*^()jbzdhO&h-jh^RJev%U-Lu|fDZ}@r=v-pY%^oSf zri9mX7QeQ-WTNUDyldTIOLqa5+l~$*uBHuJ#XLO@MR6aZ@D{G6{C`>ltPGkI!b` zeRtjW2gzqxm+PEnSh1>W)hdP)n|RKD_B+hy;XmnH<-Fi&s;QBao?A}(cKw!yuIk=z y`Z1rM`uFnhXSkov=3m8$Li&42U1@|w@zvcaR$vz~#0fx*+&&t;ucLK6VW7>;BB literal 0 HcmV?d00001 diff --git a/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursMoonTex.ia8.png b/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSFinalHoursMoonTex.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..5c4a60916c2d9df05ad6d9e15780c9457052bb2d GIT binary patch literal 3413 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 literal 0 HcmV?d00001 diff --git a/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSMiddleTex.ia8.png b/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSMiddleTex.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..ca0376fe02966716c028cc329f30f2e26e079c0d GIT binary patch literal 15485 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 literal 0 HcmV?d00001 diff --git a/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSTimeBackdropTex.ia8.png b/mm/assets/custom/textures/parameter_static/gThreeDayClock3DSTimeBackdropTex.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..57d4f97dfbcb5cc4bf115c33a8637bc88b612284 GIT binary patch literal 15159 zcmeAS@N?(olHy`uVBq!ia0y~yU@%}{U=ZM7V_;wiSodcm0|NtRfk$L90|U1(2s1Lw znj^u$VEHC9B%&n3*T*V3KUXg?B|j-uuOhdA0R(L9D+&^mvr|hHl2X$%^K6yg@7}MZ zkeOnu6mIHk;9KCFnvv;IRg@ZBP$9xMK*2e`C{@8!&rCPj(AYx3+)~fb)Y8JpL`T8M zz|c(Jz*67PMAyL3%D~dfz)%4Sl166{V!vDrJtASalYcxR#aR z*I67=S&*t9lv~HM!ZY(y^2>`gZS>K#AmSTgTB=K8NvfTZfsu)>ftjw6 zNr;h=m5G^^p@B9iVHzMA0#S)(hHq*~VoG93A~B|*s6{s?KP5A*k|8(WNxf$XqcL&n`CNf zrki4DVqsxsX=ajQnGCZC$uJCy{EITvGxHL2kko+ul9HKXWtnJXYG7<)p=)N6Vxeo8 zVv?krXkuuhn_^^`oSI~6k(6p?0}T(i4=?IUPMGSIDqk#LJ*_Cs&E^E8lFTHkPuT*wc$2CIU_MIJvGHnAC`b& z0_a+>#~efyHD|$cD`rl#NlCU!%P-1JEV0YXO-xVKFUU)`(MJd(?6g6YLC*O(`9;3@ zDXDhGHu~6vk#vD7CoBJ=%+$P+L~!mjw9&^9LsuUG%I!I&VD;uk1_lNO`i3A9sufup zU27zMt;o{oS`j)!^D;~9jG(rm2_xwO)u2}3zz8l#Oir~kGc`3fwb4fxM%NLLS&^C( z;gXq~npd2epJ!)c0o8*pfmLH9LZhJ>vPL8cs76RqKx&qO^EgB_$i>Z$%SIpEngq2h z!BX&&kyZ?-!)RqZ#N1I!AmKnHIT~C<1{6fuXmCNofk<*RxQGlWh_cb(f`kK+qqrn9U2O`PQ;36`hAj(FA3la`QlB2;zWI#cbjRqGa9Ec=GgNw+3f+!meE=V{K zNsa~=kpTr!HX2-za3GQ#4K5-B3ZiT@xFF#`Bsm&fLqG_5gAYrWuw6b2?rv{(cmI7pdiXdg9{Q4M3SSyMPxuhl#K=#Bpiq&M}v#V zfPyF+4K7GH5J`>(7m)!4Q8pS}kZ>T991Sia0}7&SG`Jw)KqNUDTto&GMA>L?LBfGZ zax}Pz3@C`Q(cprF1Ciuta1j|$5M`sm1qlZtNxZ?uh1kNGnwMg$RIX%iXLmznD+2?A zLb6AYF9SoBDg#49GXulV{|pQbFBuq04Hy_+B``2p&0t^<&z}^3)Qy3G;i#vJV@SoV zH`5Hc4jTxteE-CJSH9=3X6d@8m)2imZ~C9|W=Y`IOc4(Ut`%0ZD<1xm*8rE6Rg>NRQU%V4i;j>c74tp1^?9F3Ywr>4Xwt>rwDIV+>$Q@rtc zW6xt^jb}eS@iuq-6qq#il-QyUnO7Ur{C=+1E#Zvddb6rZ;>4LxIf4;;zPAfX92aDG zr|W9Ar~8a$`Zl|{#q(XwwtQhI`s_N%`t7FlwtdGmujgN}&}U#^`2U}o;klE{u8Y5H SCNeNEFnGH9xvX