diff options
| author | aMannus <mannusmenting@gmail.com> | 2023-05-31 00:57:45 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-05-30 18:57:45 -0400 |
| commit | b25e4d4f260735c5b61ad2971d3efd13834ccaa7 (patch) | |
| tree | 65faf6a70df81261b0b878c93a30519cd1564ceb /soh/src/code | |
| parent | e8eaac4d77a3751a463bdc4991d51c931a21698a (diff) | |
[Feature] In-game gameplay stats timer (#2910)
* Implement in-game gameplay stats timer
* Change timer to render on top of everything
Diffstat (limited to 'soh/src/code')
| -rw-r--r-- | soh/src/code/z_parameter.c | 102 | ||||
| -rw-r--r-- | soh/src/code/z_play.c | 2 |
2 files changed, 104 insertions, 0 deletions
diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 5092dc79e..83bc7fc29 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -7,6 +7,7 @@ #include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "libultraship/bridge.h" +#include "soh/Enhancements/gameplaystats.h" #ifdef _MSC_VER #include <stdlib.h> @@ -5979,6 +5980,107 @@ void Interface_Draw(PlayState* play) { CLOSE_DISPS(play->state.gfxCtx); } +void Interface_DrawTotalGameplayTimer(PlayState* play) { + // Draw timer based on the Gameplay Stats total time. + + if (CVarGetInteger("gGameplayStats.ShowIngameTimer", 0) && gSaveContext.fileNum >= 0 && gSaveContext.fileNum <= 2) { + + s32 X_Margins_Timer = 0; + if (CVarGetInteger("gIGTUseMargins", 0) != 0) { + if (CVarGetInteger("gIGTPosType", 0) == 0) { + X_Margins_Timer = Left_HUD_Margin; + }; + } + s32 rectLeftOri = OTRGetRectDimensionFromLeftEdge(24 + X_Margins_Timer); + s32 rectTopOri = 73; + if (CVarGetInteger("gIGTPosType", 0) != 0) { + rectTopOri = (CVarGetInteger("gIGTPosY", 0)); + if (CVarGetInteger("gIGTPosType", 0) == 1) { // Anchor Left + if (CVarGetInteger("gIGTUseMargins", 0) != 0) { + X_Margins_Timer = Left_HUD_Margin; + }; + rectLeftOri = OTRGetRectDimensionFromLeftEdge(CVarGetInteger("gIGTPosX", 0) + X_Margins_Timer); + } else if (CVarGetInteger("gIGTPosType", 0) == 2) { // Anchor Right + if (CVarGetInteger("gIGTUseMargins", 0) != 0) { + X_Margins_Timer = Right_HUD_Margin; + }; + rectLeftOri = OTRGetRectDimensionFromRightEdge(CVarGetInteger("gIGTPosX", 0) + X_Margins_Timer); + } else if (CVarGetInteger("gIGTPosType", 0) == 3) { // Anchor None + rectLeftOri = CVarGetInteger("gIGTPosX", 0) + 204 + X_Margins_Timer; + } else if (CVarGetInteger("gIGTPosType", 0) == 4) { // Hidden + rectLeftOri = -9999; + } + } + + s32 rectLeft; + s32 rectTop; + s32 rectWidth = 8; + s32 rectHeightOri = 16; + s32 rectHeight; + + OPEN_DISPS(play->state.gfxCtx); + + gDPSetCombineLERP(OVERLAY_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, + PRIMITIVE, 0); + + gDPSetOtherMode(OVERLAY_DISP++, + G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_IA16 | G_TL_TILE | + G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + G_AC_NONE | G_ZS_PRIM | G_RM_XLU_SURF | G_RM_XLU_SURF2); + + char* totalTimeText = GameplayStats_GetCurrentTime(); + char* textPointer = &totalTimeText[0]; + uint8_t textLength = strlen(textPointer); + uint16_t textureIndex = 0; + + for (uint16_t i = 0; i < textLength; i++) { + if (totalTimeText[i] == ':' || totalTimeText[i] == '.') { + textureIndex = 10; + } else { + textureIndex = totalTimeText[i] - 48; + } + + rectLeft = rectLeftOri + (i * 8); + rectTop = rectTopOri; + rectHeight = rectHeightOri; + + // Load correct digit (or : symbol) + gDPLoadTextureBlock(OVERLAY_DISP++, ((u8*)digitTextures[textureIndex]), G_IM_FMT_I, G_IM_SIZ_8b, rectWidth, + rectHeight, 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); + + // Create dot image from the colon image. + if (totalTimeText[i] == '.') { + rectHeight = rectHeight / 2; + rectTop += 5; + rectLeft -= 1; + } + + // Draw text shadow + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 0, 255); + gDPSetEnvColor(OVERLAY_DISP++, 255, 255, 255, 255); + gSPWideTextureRectangle(OVERLAY_DISP++, rectLeft << 2, rectTop << 2, (rectLeft + rectWidth) << 2, + (rectTop + rectHeight) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + + // Draw regular text. Change color based on if the timer is paused, running or the game is completed. + if (gSaveContext.sohStats.gameComplete) { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 120, 255, 0, 255); + } else { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, 255); + } + + // Offset text so underlaying shadow is to the bottom right of the text. + rectLeft -= 1; + rectTop -= 1; + + gSPWideTextureRectangle(OVERLAY_DISP++, rectLeft << 2, rectTop << 2, (rectLeft + rectWidth) << 2, + (rectTop + rectHeight) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + } + + CLOSE_DISPS(play->state.gfxCtx); + } +} + void Interface_Update(PlayState* play) { static u8 D_80125B60 = 0; static s16 sPrevTimeIncrement = 0; diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index a3d275390..8c5ebb950 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -1714,6 +1714,8 @@ void Play_Draw(PlayState* play) { } CLOSE_DISPS(gfxCtx); + + Interface_DrawTotalGameplayTimer(play); } time_t Play_GetRealTime() { |
