diff options
| author | aMannus <mannusmenting@gmail.com> | 2023-06-02 03:40:10 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-01 21:40:10 -0400 |
| commit | 2957dc61c37bb5f764a44d87951b8001724d2df7 (patch) | |
| tree | efe96966485706222eebb286dbb1552ddd45f580 /soh/src/code | |
| parent | fdf9086b2a900e0539f68952f01cc81fd7c6cd86 (diff) | |
[Feature] Boss Rush (#2923)
* Ganon(dorf) cutscene skips
* Remove leftover code
* Load into chamber of sages
* Fix loading into chamber without fast file select
* Boss warps in chamber done
* Change warps back to chamber
* Initial proof of concept done
* ganon(dorf) cutscene skips
* Code cleanup & auto age equipment
* Gameplay stats timer + tweaks
* Scuffed timer
* Better timer
* remove arena props + fix arena exits
* Fix blue warps
* Attempt to fix build
* Fix build again
* And again..
* Try no. 9001
* Handle dying and saving
* Child link face fire medallion
* Fix build
* Fix warps after reset/death
* Disable doors and move player spawns in boss rooms
* Fix boss rush logo rendering
* Start of ingame options menu
* File Select cleanup
* Fix build
* Render char text PoC
* Move functions to be more generic
* Fix build
* Fix other builds
* Initial text scaling/kerning
* Special characters prep
* All special characters work now
* Attempt to fix build
* Fix build question mark
* Finish all kerning
* Start of ingame options menu with vertical scrolling
* Barebones functional options menu
* More options menu progress
* More visual elements for options menu
* Options menu visual changes, implement all options, tons of cleanup
* Cleanup and comments
* Shorter enums
* More options
* Change default heart count
* Finish French translations
* Implement timer in cosmetics editor
* Uncomment timer requirement
* Variable name change
* German translation & small UI tweaks
* Animated up/down arrows in options UI
* Better arrows in options UI
* Cleaner timer + make it usable for general gameplay
* More cleanup + ganon & ganondorf boss option
* Implement never heal option
* Slight up arrow in options UI tweak
* Add BGS option
* Reintroduce ganondorf cutscene skip
* Change encoding to UTF on bossrush.cpp
* Fix build hopefully
* Fixed static variables leading to options not properly resetting
* Fix BR completed timestamp
* Change timer to render on top of everything
* Offset final BR time by 0.1 second from boss timestamps
* Add missing check for boss rush
* Implement soh_assets.h
* Revert merge mistake
* Fix special characters with UTF-8
* Fix build
* here's the fix you can merge from your phone
* Fix quest select crash with oot.otr only
* Use OoT's kerning
* Fix HD textures on options menu
* Fix special character kerning
* "Heal every boss" fixes
* Seperate headers + bunny hood option
* Remove GetUnixTimestamp() externing
* Clean up extern "C"'s
* Address review comments
* Fix build question mark
* Remove accidental styling change
---------
Co-authored-by: briaguya <briaguya@alice>
Diffstat (limited to 'soh/src/code')
| -rw-r--r-- | soh/src/code/z_kaleido_scope_call.c | 3 | ||||
| -rw-r--r-- | soh/src/code/z_kanfont.c | 4 | ||||
| -rw-r--r-- | soh/src/code/z_message_PAL.c | 4 | ||||
| -rw-r--r-- | soh/src/code/z_parameter.c | 88 | ||||
| -rw-r--r-- | soh/src/code/z_play.c | 3 | ||||
| -rw-r--r-- | soh/src/code/z_sram.c | 4 |
6 files changed, 97 insertions, 9 deletions
diff --git a/soh/src/code/z_kaleido_scope_call.c b/soh/src/code/z_kaleido_scope_call.c index 5d1f6937d..6f0648e08 100644 --- a/soh/src/code/z_kaleido_scope_call.c +++ b/soh/src/code/z_kaleido_scope_call.c @@ -56,7 +56,8 @@ void KaleidoScopeCall_Update(PlayState* play) { KaleidoMgrOverlay* kaleidoScopeOvl = &gKaleidoMgrOverlayTable[KALEIDO_OVL_KALEIDO_SCOPE]; PauseContext* pauseCtx = &play->pauseCtx; - if (!gSaveContext.sohStats.gameComplete) { + if (!gSaveContext.sohStats.gameComplete && + (!gSaveContext.isBossRush || !gSaveContext.isBossRushPaused)) { gSaveContext.sohStats.pauseTimer++; } diff --git a/soh/src/code/z_kanfont.c b/soh/src/code/z_kanfont.c index 2dd9cda80..217ef3c0a 100644 --- a/soh/src/code/z_kanfont.c +++ b/soh/src/code/z_kanfont.c @@ -177,6 +177,10 @@ void Font_LoadChar(Font* font, u8 character, u16 codePointIndex) { memcpy(&font->charTexBuf[codePointIndex], fntTbl[character], strlen(fntTbl[character]) + 1); } +void* Font_FetchCharTexture(u8 character) { + return fntTbl[character]; +} + /** * Loads a message box icon from message_static, such as the ending triangle/square or choice arrow into the * icon buffer. diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 762e06b55..881637d8d 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -709,6 +709,10 @@ f32 sFontWidths[144] = { 14.0f, // ? }; +f32 Message_GetCharacterWidth(unsigned char characterIndex) { + return sFontWidths[characterIndex] * (R_TEXT_CHAR_SCALE / 100.0f); +} + u16 Message_DrawItemIcon(PlayState* play, u16 itemId, Gfx** p, u16 i) { s32 pad; Gfx* gfx = *p; diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 83bc7fc29..83066aff4 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -8,6 +8,8 @@ #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "libultraship/bridge.h" #include "soh/Enhancements/gameplaystats.h" +#include "soh/Enhancements/boss-rush/BossRushTypes.h" +#include "soh/Enhancements/custom-message/CustomMessageInterfaceAddon.h" #ifdef _MSC_VER #include <stdlib.h> @@ -882,7 +884,8 @@ void func_80083108(PlayState* play) { Interface_ChangeAlpha(12); } } - } else if (play->sceneNum == SCENE_KENJYANOMA) { + // Don't hide the HUD in the Chamber of Sages when in Boss Rush. + } else if (play->sceneNum == SCENE_KENJYANOMA && !gSaveContext.isBossRush) { Interface_ChangeAlpha(1); } else if (play->sceneNum == SCENE_TURIBORI) { gSaveContext.unk_13E7 = 2; @@ -4942,7 +4945,10 @@ void Interface_Draw(PlayState* play) { PosX_RC = PosX_RC_ori; } gDPSetPrimColor(OVERLAY_DISP++, 0, 0, rColor.r, rColor.g, rColor.b, interfaceCtx->magicAlpha); - OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, gRupeeCounterIconTex, 16, 16, PosX_RC, PosY_RC, 16, 16, 1 << 10, 1 << 10); + // Draw Rupee icon. Hide in Boss Rush. + if (!gSaveContext.isBossRush) { + OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, gRupeeCounterIconTex, 16, 16, PosX_RC, PosY_RC, 16, 16, 1 << 10, 1 << 10); + } switch (play->sceneNum) { case SCENE_BMORI1: @@ -5057,10 +5063,12 @@ void Interface_Draw(PlayState* play) { svar2 = rupeeDigitsFirst[CUR_UPG_VALUE(UPG_WALLET)]; svar5 = rupeeDigitsCount[CUR_UPG_VALUE(UPG_WALLET)]; - for (svar1 = 0, svar3 = 16; svar1 < svar5; svar1++, svar2++, svar3 += 8) { - OVERLAY_DISP = - Gfx_TextureI8(OVERLAY_DISP, ((u8*)digitTextures[interfaceCtx->counterDigits[svar2]]), 8, 16, - PosX_RC+svar3, PosY_RC, 8, 16, 1 << 10, 1 << 10); + // Draw Rupee Counter. Hide in Boss Rush. + if (!gSaveContext.isBossRush) { + for (svar1 = 0, svar3 = 16; svar1 < svar5; svar1++, svar2++, svar3 += 8) { + OVERLAY_DISP = Gfx_TextureI8(OVERLAY_DISP, ((u8*)digitTextures[interfaceCtx->counterDigits[svar2]]), + 8, 16, PosX_RC + svar3, PosY_RC, 8, 16, 1 << 10, 1 << 10); + } } } else { @@ -5983,7 +5991,8 @@ void Interface_Draw(PlayState* play) { 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) { + if ((gSaveContext.isBossRush && gSaveContext.bossRushOptions[BR_OPTIONS_TIMER] == BR_CHOICE_TIMER_YES) || + (CVarGetInteger("gGameplayStats.ShowIngameTimer", 0) && gSaveContext.fileNum >= 0 && gSaveContext.fileNum <= 2)) { s32 X_Margins_Timer = 0; if (CVarGetInteger("gIGTUseMargins", 0) != 0) { @@ -6065,6 +6074,8 @@ void Interface_DrawTotalGameplayTimer(PlayState* play) { // 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 if (gSaveContext.isBossRushPaused) { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 150, 150, 150, 255); } else { gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, 255); } @@ -6483,3 +6494,66 @@ void Interface_Update(PlayState* play) { } } } + +void Interface_DrawTextCharacter(GraphicsContext* gfx, int16_t x, int16_t y, void* texture, uint16_t colorR, + uint16_t colorG, uint16_t colorB, uint16_t colorA, float textScale, uint8_t textShadow) { + + int32_t scale = R_TEXT_CHAR_SCALE * textScale; + int32_t sCharTexSize = (scale / 100.0f) * 16.0f; + int32_t sCharTexScale = 1024.0f / (scale / 100.0f); + + OPEN_DISPS(gfx); + + gDPPipeSync(POLY_OPA_DISP++); + + gDPLoadTextureBlock_4b(POLY_OPA_DISP++, texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, FONT_CHAR_TEX_HEIGHT, 0, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); + + if (textShadow) { + // Draw drop shadow + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, colorA); + gSPTextureRectangle(POLY_OPA_DISP++, (x + R_TEXT_DROP_SHADOW_OFFSET) << 2, (y + R_TEXT_DROP_SHADOW_OFFSET) << 2, + (x + R_TEXT_DROP_SHADOW_OFFSET + sCharTexSize) << 2, + (y + R_TEXT_DROP_SHADOW_OFFSET + sCharTexSize) << 2, G_TX_RENDERTILE, 0, 0, sCharTexScale, + sCharTexScale); + } + + gDPPipeSync(POLY_OPA_DISP++); + + // Draw normal text + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, colorR, colorG, colorB, colorA); + gSPTextureRectangle(POLY_OPA_DISP++, x << 2, y << 2, (x + sCharTexSize) << 2, (y + sCharTexSize) << 2, + G_TX_RENDERTILE, 0, 0, sCharTexScale, sCharTexScale); + + CLOSE_DISPS(gfx); +} + +uint16_t Interface_DrawTextLine(GraphicsContext* gfx, char text[], int16_t x, int16_t y, uint16_t colorR, + uint16_t colorG, uint16_t colorB, uint16_t colorA, float textScale, uint8_t textShadow) { + + uint16_t textureIndex; + uint16_t kerningOffset = 0; + uint16_t lineOffset = 0; + void* texture; + const char* processedText = Interface_ReplaceSpecialCharacters(text); + uint8_t textLength = strlen(processedText); + + for (uint16_t i = 0; i < textLength; i++) { + if (processedText[i] == '\n') { + lineOffset += 15 * textScale; + kerningOffset = 0; + } else { + textureIndex = processedText[i] - 32; + + if (textureIndex != 0) { + texture = Font_FetchCharTexture(textureIndex); + Interface_DrawTextCharacter(gfx, x + kerningOffset, y + lineOffset, texture, colorR, colorG, colorB, + colorA, textScale, textShadow); + } + kerningOffset += (uint16_t)(Message_GetCharacterWidth(textureIndex) * textScale); + } + } + + return kerningOffset; +} diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index 44e5442db..f4d0cdbe6 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -1170,7 +1170,8 @@ void Play_Update(PlayState* play) { play->gameplayFrames++; // Gameplay stat tracking - if (!gSaveContext.sohStats.gameComplete) { + if (!gSaveContext.sohStats.gameComplete && + (!gSaveContext.isBossRush || (gSaveContext.isBossRush && !gSaveContext.isBossRushPaused))) { gSaveContext.sohStats.playTimer++; gSaveContext.sohStats.sceneTimer++; gSaveContext.sohStats.roomTimer++; diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 1735a2eb9..ce5651539 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -29,6 +29,10 @@ void Sram_InitDebugSave(void) { Save_InitFile(true); } +void Sram_InitBossRushSave(void) { + Save_InitFile(false); +} + /** * Copy save currently on the buffer to Save Context and complete various tasks to open the save. * This includes: |
