mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-07-11 15:29:22 -04:00
Hookify text speed options (#6881)
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "z64.h"
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
#define CVAR_BETTER_OWL_NAME CVAR_ENHANCEMENT("BetterOwl")
|
||||
#define CVAR_BETTER_OWL_VALUE CVarGetInteger(CVAR_BETTER_OWL_NAME, 0)
|
||||
|
||||
static void RegisterBetterOwl() {
|
||||
COND_VB_SHOULD(VB_OWL_CHOOSE_BETTER, CVAR_BETTER_OWL_VALUE, {
|
||||
MessageContext* msgCtx = &gPlayState->msgCtx;
|
||||
if ((msgCtx->textId == 0x2066 || msgCtx->textId == 0x607B || msgCtx->textId == 0x10C2 ||
|
||||
msgCtx->textId == 0x10C6 || msgCtx->textId == 0x206A)) {
|
||||
msgCtx->choiceIndex = 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc(RegisterBetterOwl, { CVAR_BETTER_OWL_NAME });
|
||||
@@ -0,0 +1,90 @@
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "z64.h"
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
// Text Speed which fills whole box in one frame
|
||||
static constexpr int32_t TEXT_SPEED_INSTANT = 6;
|
||||
|
||||
#define CVAR_TEXT_SPEED_NAME CVAR_ENHANCEMENT("TextSpeed")
|
||||
#define CVAR_SLOW_TEXT_SPEED_NAME CVAR_ENHANCEMENT("SlowTextSpeed")
|
||||
|
||||
#define TEXT_SPEED CVarGetInteger(CVAR_TEXT_SPEED_NAME, 1)
|
||||
#define SLOW_TEXT_SPEED CVarGetInteger(CVAR_SLOW_TEXT_SPEED_NAME, TEXT_SPEED)
|
||||
|
||||
static bool ShouldAdvanceQuickText(u16 textPos) {
|
||||
MessageContext* msgCtx = &gPlayState->msgCtx;
|
||||
|
||||
if (textPos + TEXT_SPEED < msgCtx->textDrawPos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING ||
|
||||
(msgCtx->msgMode >= MSGMODE_OCARINA_STARTING && msgCtx->msgMode < MSGMODE_SCARECROW_LONG_RECORDING_START)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void FastTextCrawl(u16 textPos, bool* should) {
|
||||
MessageContext* msgCtx = &gPlayState->msgCtx;
|
||||
if (msgCtx->textDelay == 0) {
|
||||
msgCtx->textDrawPos = textPos + TEXT_SPEED;
|
||||
if (msgCtx->textDrawPos > msgCtx->decodedTextLen) {
|
||||
msgCtx->textDrawPos = msgCtx->decodedTextLen + 1;
|
||||
}
|
||||
*should = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void SlowTextCrawl(bool* should) {
|
||||
MessageContext* msgCtx = &gPlayState->msgCtx;
|
||||
if (msgCtx->textDelayTimer <= 0) {
|
||||
return;
|
||||
}
|
||||
*should = true;
|
||||
if (msgCtx->textDelayTimer > SLOW_TEXT_SPEED) {
|
||||
msgCtx->textDelayTimer -= SLOW_TEXT_SPEED;
|
||||
} else {
|
||||
msgCtx->textDelayTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void RegisterTextSpeedModifiers() {
|
||||
COND_VB_SHOULD(VB_ENABLE_QUICKTEXT, TEXT_SPEED > 1, {
|
||||
u16 textPos = va_arg(args, int);
|
||||
if (!*should && ShouldAdvanceQuickText(textPos)) {
|
||||
*should = true;
|
||||
}
|
||||
});
|
||||
|
||||
COND_VB_SHOULD(VB_FIX_TEXT_SPEED_SOFTLOCK, TEXT_SPEED > 1, {
|
||||
MessageContext* msgCtx = &gPlayState->msgCtx;
|
||||
u16 nextTextPos = va_arg(args, int);
|
||||
|
||||
*should = !*should || (nextTextPos > msgCtx->textDrawPos);
|
||||
if (*should) {
|
||||
msgCtx->textDrawPos = nextTextPos;
|
||||
}
|
||||
});
|
||||
|
||||
COND_VB_SHOULD(VB_TEXT_CRAWL_FASTER, TEXT_SPEED >= TEXT_SPEED_INSTANT, {
|
||||
MessageContext* msgCtx = &gPlayState->msgCtx;
|
||||
msgCtx->textDrawPos = msgCtx->decodedTextLen + 1;
|
||||
*should = true;
|
||||
});
|
||||
|
||||
COND_VB_SHOULD(VB_TEXT_CRAWL_FASTER, TEXT_SPEED > 1 && TEXT_SPEED < TEXT_SPEED_INSTANT, {
|
||||
u16 textPos = va_arg(args, int);
|
||||
FastTextCrawl(textPos, should);
|
||||
});
|
||||
|
||||
COND_VB_SHOULD(VB_TEXT_CRAWL_FASTER, SLOW_TEXT_SPEED > 1 && TEXT_SPEED < TEXT_SPEED_INSTANT,
|
||||
{ SlowTextCrawl(should); });
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc(RegisterTextSpeedModifiers, { CVAR_TEXT_SPEED_NAME, CVAR_SLOW_TEXT_SPEED_NAME });
|
||||
@@ -660,14 +660,6 @@ typedef enum {
|
||||
// - `int32_t` (item - promoted from `u8`)
|
||||
VB_EMPTY_BOTTLE_TO_HALF_MILK,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// (Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)
|
||||
// ```
|
||||
// #### `args`
|
||||
// - None
|
||||
VB_END_GERUDO_MEMBERSHIP_TALK,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
@@ -676,6 +668,25 @@ typedef enum {
|
||||
// - `*EnArrow`
|
||||
VB_EN_ARROW_MAGIC_CONSUMPTION,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// i + 1 == msgCtx->textDrawPos &&
|
||||
// (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING ||
|
||||
// (msgCtx->msgMode >= MSGMODE_OCARINA_STARTING &&
|
||||
// msgCtx->msgMode < MSGMODE_SCARECROW_LONG_RECORDING_START))
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `u16` (text position)
|
||||
VB_ENABLE_QUICKTEXT,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// (Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)
|
||||
// ```
|
||||
// #### `args`
|
||||
// - None
|
||||
VB_END_GERUDO_MEMBERSHIP_TALK,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// !(this->stateFlags3 & PLAYER_STATE3_PAUSE_ACTION_FUNC)
|
||||
@@ -717,6 +728,12 @@ typedef enum {
|
||||
// - `*EnElf`
|
||||
VB_FAIRY_HEAL,
|
||||
|
||||
// #### `result`
|
||||
// True if the next text position must be beyond the current position; false otherwise
|
||||
// #### `args`
|
||||
// - `u16` (next text position)
|
||||
VB_FIX_TEXT_SPEED_SOFTLOCK,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// false
|
||||
@@ -1658,6 +1675,14 @@ typedef enum {
|
||||
// - `*uint16_t` (overrideTextId)
|
||||
VB_OVERRIDE_LINK_THE_GORON_DIALOGUE,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// false
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `None`
|
||||
VB_OWL_CHOOSE_BETTER,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// this->actor.xzDistToPlayer < targetDist
|
||||
@@ -2640,6 +2665,14 @@ typedef enum {
|
||||
// - s32 - background id`
|
||||
VB_TARGETABLE_HOOKSHOT_RETICLE,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// false
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `u16` (text position)
|
||||
VB_TEXT_CRAWL_FASTER,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// (this->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR) && (this->heldActor != NULL) &&
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
#include "soh/SaveManager.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
|
||||
// SOH [Enhancement] Text Speed which fills whole box in one frame
|
||||
#define TEXT_SPEED_INSTANT 6
|
||||
|
||||
// #region SOH [NTSC] - Allows custom messages to work on japanese
|
||||
static bool sDisplayNextMessageAsEnglish = false;
|
||||
static u8 sLastLanguage = LANGUAGE_ENG;
|
||||
@@ -956,7 +953,6 @@ void Message_DrawTextJPN(PlayState* play, Gfx** gfxP) {
|
||||
u16 i;
|
||||
u16 charTexIdx;
|
||||
Gfx* gfx = *gfxP;
|
||||
int gTextSpeed, gSlowTextSpeed;
|
||||
|
||||
play->msgCtx.textPosX = R_TEXT_INIT_XPOS;
|
||||
play->msgCtx.textPosY = R_TEXT_INIT_YPOS;
|
||||
@@ -970,9 +966,6 @@ void Message_DrawTextJPN(PlayState* play, Gfx** gfxP) {
|
||||
msgCtx->unk_E3D0 = 0;
|
||||
charTexIdx = 0;
|
||||
|
||||
gTextSpeed = CVarGetInteger(CVAR_ENHANCEMENT("TextSpeed"), 1);
|
||||
gSlowTextSpeed = CVarGetInteger(CVAR_ENHANCEMENT("SlowTextSpeed"), gTextSpeed);
|
||||
|
||||
for (i = 0; i < msgCtx->textDrawPos; i++) {
|
||||
character = msgCtx->msgBufDecodedWide[i];
|
||||
|
||||
@@ -1012,11 +1005,7 @@ void Message_DrawTextJPN(PlayState* play, Gfx** gfxP) {
|
||||
msgCtx->textPosX += msgCtx->msgBufDecodedWide[++i];
|
||||
break;
|
||||
case MESSAGE_TEXTID_JPN:
|
||||
// #region SOH [General] Fixes softlock for higher text speeds
|
||||
if (gTextSpeed > 1) {
|
||||
msgCtx->textDrawPos = i + 1;
|
||||
}
|
||||
// #endregion
|
||||
GameInteractor_Should(VB_FIX_TEXT_SPEED_SOFTLOCK, false, i + 1);
|
||||
msgCtx->textboxEndType = TEXTBOX_ENDTYPE_HAS_NEXT;
|
||||
if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) {
|
||||
Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
@@ -1027,10 +1016,12 @@ void Message_DrawTextJPN(PlayState* play, Gfx** gfxP) {
|
||||
*gfxP = gfx;
|
||||
return;
|
||||
case MESSAGE_QUICKTEXT_ENABLE_JPN:
|
||||
if ((i + 1 == msgCtx->textDrawPos || (gTextSpeed > 1 && i + gTextSpeed >= msgCtx->textDrawPos)) &&
|
||||
(msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING ||
|
||||
(msgCtx->msgMode >= MSGMODE_OCARINA_STARTING &&
|
||||
msgCtx->msgMode < MSGMODE_SCARECROW_LONG_RECORDING_START))) {
|
||||
if (GameInteractor_Should(VB_ENABLE_QUICKTEXT,
|
||||
i + 1 == msgCtx->textDrawPos &&
|
||||
(msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING ||
|
||||
(msgCtx->msgMode >= MSGMODE_OCARINA_STARTING &&
|
||||
msgCtx->msgMode < MSGMODE_SCARECROW_LONG_RECORDING_START)),
|
||||
i)) {
|
||||
j = i;
|
||||
while (true) {
|
||||
character = msgCtx->msgBufDecodedWide[j];
|
||||
@@ -1043,7 +1034,8 @@ void Message_DrawTextJPN(PlayState* play, Gfx** gfxP) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j > msgCtx->textDrawPos) {
|
||||
|
||||
if (GameInteractor_Should(VB_FIX_TEXT_SPEED_SOFTLOCK, true, j)) {
|
||||
i = j - 1;
|
||||
msgCtx->textDrawPos = j;
|
||||
}
|
||||
@@ -1151,12 +1143,7 @@ void Message_DrawTextJPN(PlayState* play, Gfx** gfxP) {
|
||||
msgCtx->choiceTextId = msgCtx->textId;
|
||||
msgCtx->stateTimer = 4;
|
||||
msgCtx->choiceIndex = 0;
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("BetterOwl"), 0)) {
|
||||
if ((msgCtx->textId == 0x2066 || msgCtx->textId == 0x607B || msgCtx->textId == 0x10C2 ||
|
||||
msgCtx->textId == 0x10C6 || msgCtx->textId == 0x206A)) {
|
||||
msgCtx->choiceIndex = 1;
|
||||
}
|
||||
}
|
||||
GameInteractor_Should(VB_OWL_CHOOSE_BETTER, false);
|
||||
Font_LoadMessageBoxIcon(font, TEXTBOX_ICON_ARROW);
|
||||
}
|
||||
break;
|
||||
@@ -1184,11 +1171,7 @@ void Message_DrawTextJPN(PlayState* play, Gfx** gfxP) {
|
||||
*gfxP = gfx;
|
||||
return;
|
||||
case MESSAGE_OCARINA_JPN:
|
||||
// #region SOH [General] Fixes softlock for higher text speeds
|
||||
if (gTextSpeed > 1) {
|
||||
msgCtx->textDrawPos = i + 1;
|
||||
}
|
||||
// #endregion
|
||||
GameInteractor_Should(VB_FIX_TEXT_SPEED_SOFTLOCK, false, i + 1);
|
||||
if (i + 1 == msgCtx->textDrawPos) {
|
||||
Message_HandleOcarina(play);
|
||||
*gfxP = gfx;
|
||||
@@ -1279,20 +1262,13 @@ void Message_DrawTextJPN(PlayState* play, Gfx** gfxP) {
|
||||
}
|
||||
}
|
||||
|
||||
if (gTextSpeed >= TEXT_SPEED_INSTANT) {
|
||||
msgCtx->textDrawPos = msgCtx->decodedTextLen + 1;
|
||||
} else if (msgCtx->textDelay == 0) {
|
||||
msgCtx->textDrawPos = i + gTextSpeed;
|
||||
if (msgCtx->textDrawPos > msgCtx->decodedTextLen) {
|
||||
msgCtx->textDrawPos = msgCtx->decodedTextLen + 1;
|
||||
}
|
||||
if (GameInteractor_Should(VB_TEXT_CRAWL_FASTER, false, i)) {
|
||||
// Logic handled within hooks
|
||||
} else if (msgCtx->textDelayTimer == 0) {
|
||||
msgCtx->textDrawPos = i + 1;
|
||||
msgCtx->textDelayTimer = msgCtx->textDelay;
|
||||
} else if (msgCtx->textDelayTimer <= gSlowTextSpeed) {
|
||||
msgCtx->textDelayTimer = 0;
|
||||
} else {
|
||||
msgCtx->textDelayTimer -= gSlowTextSpeed;
|
||||
msgCtx->textDelayTimer--;
|
||||
}
|
||||
*gfxP = gfx;
|
||||
}
|
||||
@@ -1309,13 +1285,12 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
|
||||
u16 i;
|
||||
u16 sfxHi;
|
||||
u16 charTexIdx;
|
||||
int gTextSpeed, gSlowTextSpeed;
|
||||
Font* font = &play->msgCtx.font;
|
||||
Gfx* gfx = *gfxP;
|
||||
|
||||
play->msgCtx.textPosX = R_TEXT_INIT_XPOS;
|
||||
|
||||
if (sTextIsCredits == false) {
|
||||
if (!sTextIsCredits) {
|
||||
msgCtx->textPosY = R_TEXT_INIT_YPOS;
|
||||
} else {
|
||||
msgCtx->textPosY = YREG(1);
|
||||
@@ -1332,9 +1307,6 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
|
||||
msgCtx->unk_E3D0 = 0;
|
||||
charTexIdx = 0;
|
||||
|
||||
gTextSpeed = CVarGetInteger(CVAR_ENHANCEMENT("TextSpeed"), 1);
|
||||
gSlowTextSpeed = CVarGetInteger(CVAR_ENHANCEMENT("SlowTextSpeed"), gTextSpeed);
|
||||
|
||||
for (i = 0; i < msgCtx->textDrawPos; i++) {
|
||||
character = msgCtx->msgBufDecoded[i];
|
||||
|
||||
@@ -1384,10 +1356,12 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
|
||||
*gfxP = gfx;
|
||||
return;
|
||||
case MESSAGE_QUICKTEXT_ENABLE:
|
||||
if ((i + 1 == msgCtx->textDrawPos || (gTextSpeed > 1 && i + gTextSpeed >= msgCtx->textDrawPos)) &&
|
||||
(msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING ||
|
||||
(msgCtx->msgMode >= MSGMODE_OCARINA_STARTING &&
|
||||
msgCtx->msgMode < MSGMODE_SCARECROW_LONG_RECORDING_START))) {
|
||||
if (GameInteractor_Should(VB_ENABLE_QUICKTEXT,
|
||||
i + 1 == msgCtx->textDrawPos &&
|
||||
(msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING ||
|
||||
(msgCtx->msgMode >= MSGMODE_OCARINA_STARTING &&
|
||||
msgCtx->msgMode < MSGMODE_SCARECROW_LONG_RECORDING_START)),
|
||||
i)) {
|
||||
j = i;
|
||||
while (true) {
|
||||
lookAheadCharacter = msgCtx->msgBufDecoded[j];
|
||||
@@ -1404,12 +1378,11 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j > msgCtx->textDrawPos) {
|
||||
|
||||
if (GameInteractor_Should(VB_FIX_TEXT_SPEED_SOFTLOCK, true, j)) {
|
||||
i = j - 1;
|
||||
msgCtx->textDrawPos = j;
|
||||
}
|
||||
|
||||
if (character) {}
|
||||
}
|
||||
case MESSAGE_QUICKTEXT_DISABLE:
|
||||
break;
|
||||
@@ -1526,12 +1499,7 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
|
||||
msgCtx->choiceTextId = msgCtx->textId;
|
||||
msgCtx->stateTimer = 4;
|
||||
msgCtx->choiceIndex = 0;
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("BetterOwl"), 0)) {
|
||||
if ((msgCtx->textId == 0x2066 || msgCtx->textId == 0x607B || msgCtx->textId == 0x10C2 ||
|
||||
msgCtx->textId == 0x10C6 || msgCtx->textId == 0x206A)) {
|
||||
msgCtx->choiceIndex = 1;
|
||||
}
|
||||
}
|
||||
GameInteractor_Should(VB_OWL_CHOOSE_BETTER, false);
|
||||
Font_LoadMessageBoxIcon(font, TEXTBOX_ICON_ARROW);
|
||||
}
|
||||
break;
|
||||
@@ -1559,11 +1527,7 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
|
||||
*gfxP = gfx;
|
||||
return;
|
||||
case MESSAGE_OCARINA:
|
||||
// #region SOH [General] Fixes softlock for higher text speeds
|
||||
if (gTextSpeed > 1) {
|
||||
msgCtx->textDrawPos = i + 1;
|
||||
}
|
||||
// #endregion
|
||||
GameInteractor_Should(VB_FIX_TEXT_SPEED_SOFTLOCK, false, i + 1);
|
||||
if (i + 1 == msgCtx->textDrawPos) {
|
||||
Message_HandleOcarina(play);
|
||||
*gfxP = gfx;
|
||||
@@ -1631,17 +1595,13 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gTextSpeed >= TEXT_SPEED_INSTANT) {
|
||||
msgCtx->textDrawPos = msgCtx->decodedTextLen + 1;
|
||||
} else if (msgCtx->textDelay == 0) {
|
||||
msgCtx->textDrawPos = i + gTextSpeed;
|
||||
if (GameInteractor_Should(VB_TEXT_CRAWL_FASTER, false, i)) {
|
||||
// Logic handled within hooks
|
||||
} else if (msgCtx->textDelayTimer == 0) {
|
||||
msgCtx->textDrawPos = i + 1;
|
||||
msgCtx->textDelayTimer = msgCtx->textDelay;
|
||||
} else if (msgCtx->textDelayTimer <= gSlowTextSpeed) {
|
||||
msgCtx->textDelayTimer = 0;
|
||||
} else {
|
||||
msgCtx->textDelayTimer -= gSlowTextSpeed;
|
||||
msgCtx->textDelayTimer--;
|
||||
}
|
||||
*gfxP = gfx;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user