* Adds ability for Notifiations to not make a noise This is probably the only feature that will use it, the noise makes sense for most things we want to use notifications for, but it playing on every scene transition was a bit distracting. * Adds a hook for OnSeqPlayerInit * Uses new hook and displays notification instead of overlay text * Changes names to prevent collisions Will be registering other types of hooks that will need different ShipInitFuncs in this same file later. * Change Icon * Change CVarName and remove now-unused duration slider * Update ConfigMigrator for CVar changes. * clang-format * fix * bring back duration control * config v4 * fix v4 migration --------- Co-authored-by: Christopher Leggett <chris@leggett.dev> Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com>
This commit is contained in:
@@ -842,18 +842,17 @@ void RegisterAudioWidgets() {
|
||||
"the area for the effect to kick in."));
|
||||
SohGui::mSohMenu->AddSearchWidget({ leadingMusic, "Enhancements", "Audio Editor", "Audio Options" });
|
||||
|
||||
displaySeqName = { .name = "Display Sequence Name on Overlay", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
|
||||
displaySeqName.CVar(CVAR_AUDIO("SeqNameOverlay"))
|
||||
displaySeqName = { .name = "Display Sequence Name in Notifications", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
|
||||
displaySeqName.CVar(CVAR_AUDIO("SeqNameNotification"))
|
||||
.Options(CheckboxOptions()
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Displays the name of the current sequence in the corner of the screen whenever a new "
|
||||
"sequence "
|
||||
"is loaded to the main sequence player (does not apply to fanfares or enemy BGM)."));
|
||||
.Tooltip("Emits a notification with the current song name whenever it changes. "
|
||||
"(does not apply to fanfares or enemy BGM)."));
|
||||
SohGui::mSohMenu->AddSearchWidget({ displaySeqName, "Enhancements", "Audio Editor", "Audio Options" });
|
||||
|
||||
ovlDuration = { .name = "Overlay Duration: %d seconds", .type = WidgetType::WIDGET_CVAR_SLIDER_INT };
|
||||
ovlDuration.CVar(CVAR_AUDIO("SeqNameOverlayDuration"))
|
||||
.Options(IntSliderOptions().Color(THEME_COLOR).Min(1).Max(10).DefaultValue(5).Size(ImVec2(300.0f, 0.0f)));
|
||||
ovlDuration = { .name = "Sequence Notification Duration: %d seconds", .type = WidgetType::WIDGET_CVAR_SLIDER_INT };
|
||||
ovlDuration.CVar(CVAR_AUDIO("SeqNameNotificationDuration"))
|
||||
.Options(IntSliderOptions().Color(THEME_COLOR).Min(1).Max(20).DefaultValue(10).Size(ImVec2(300.0f, 0.0f)));
|
||||
SohGui::mSohMenu->AddSearchWidget({ ovlDuration, "Enhancements", "Audio Editor", "Audio Options" });
|
||||
|
||||
voicePitch = { .name = "Link's Voice Pitch Multiplier", .type = WidgetType::WIDGET_CVAR_SLIDER_FLOAT };
|
||||
|
||||
43
soh/soh/Enhancements/audio/AudioHooks.cpp
Normal file
43
soh/soh/Enhancements/audio/AudioHooks.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
#include "AudioCollection.h"
|
||||
#include <soh/Notification/Notification.h>
|
||||
#include <soh/SohGui/ImGuiUtils.h>
|
||||
|
||||
extern "C" {
|
||||
#include "variables.h"
|
||||
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
#define CVAR_SEQOVERLAY_NAME CVAR_AUDIO("SeqNameNotification")
|
||||
#define CVAR_SEQOVERLAY_DEFAULT 0
|
||||
#define CVAR_SEQOVERLAY_VALUE CVarGetInteger(CVAR_SEQOVERLAY_NAME, CVAR_SEQOVERLAY_DEFAULT)
|
||||
|
||||
void NotifySequenceName(int32_t playerIdx, int32_t seqId) {
|
||||
// Keep track of the previous sequence/scene so we don't repeat notifications
|
||||
static uint16_t previousSeqId = UINT16_MAX;
|
||||
static int16_t previousSceneNum = INT16_MAX;
|
||||
if (playerIdx == SEQ_PLAYER_BGM_MAIN &&
|
||||
(seqId != previousSeqId || (gPlayState != NULL && gPlayState->sceneNum != previousSceneNum))) {
|
||||
|
||||
previousSeqId = seqId;
|
||||
if (gPlayState != NULL) {
|
||||
previousSceneNum = gPlayState->sceneNum;
|
||||
}
|
||||
const char* sequenceName = AudioCollection::Instance->GetSequenceName(seqId);
|
||||
if (sequenceName != NULL) {
|
||||
Notification::Emit({
|
||||
.message = ICON_FA_MUSIC " " + std::string(sequenceName),
|
||||
.remainingTime = static_cast<float>(CVarGetInteger(CVAR_AUDIO("SeqNameNotificationDuration"), 10)),
|
||||
.mute = true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterAudioNotificationHooks() {
|
||||
COND_HOOK(OnSeqPlayerInit, CVAR_SEQOVERLAY_VALUE, NotifySequenceName);
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc notifInitFunc(RegisterAudioNotificationHooks, { CVAR_SEQOVERLAY_NAME });
|
||||
@@ -74,3 +74,6 @@ DEFINE_HOOK(OnGenerationCompletion, ());
|
||||
DEFINE_HOOK(OnSetGameLanguage, ());
|
||||
DEFINE_HOOK(OnAssetAltChange, ());
|
||||
DEFINE_HOOK(OnKaleidoUpdate, ());
|
||||
|
||||
// Audio
|
||||
DEFINE_HOOK(OnSeqPlayerInit, (int32_t playerIdx, int32_t seqId));
|
||||
|
||||
@@ -327,3 +327,8 @@ void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void)) {
|
||||
void GameInteractor_ExecuteOnKaleidoUpdate() {
|
||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnKaleidoUpdate>();
|
||||
}
|
||||
|
||||
// Mark: Audio
|
||||
void GameInteractor_ExecuteOnSeqPlayerInit(int32_t playerIdx, int32_t seqId) {
|
||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSeqPlayerInit>(playerIdx, seqId);
|
||||
}
|
||||
|
||||
@@ -86,6 +86,9 @@ void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void));
|
||||
// Mark: - Pause Menu
|
||||
void GameInteractor_ExecuteOnKaleidoUpdate();
|
||||
|
||||
// Mark: - Audio
|
||||
void GameInteractor_ExecuteOnSeqPlayerInit(int32_t playerIdx, int32_t seqId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -131,8 +131,10 @@ void Emit(Options notification) {
|
||||
notification.remainingTime = CVarGetFloat(CVAR_SETTING("Notifications.Duration"), 10.0f);
|
||||
}
|
||||
notifications.push_back(notification);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
if (!notification.mute) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Notification
|
||||
|
||||
@@ -17,6 +17,7 @@ struct Options {
|
||||
std::string suffix = "";
|
||||
ImVec4 suffixColor = ImVec4(1.0f, 0.5f, 0.5f, 1.0f);
|
||||
float remainingTime = 0.0f; // Seconds
|
||||
bool mute = false; // whether notification should make a noise
|
||||
};
|
||||
|
||||
class Window final : public Ship::GuiWindow {
|
||||
|
||||
@@ -1237,6 +1237,7 @@ extern "C" void InitOTR() {
|
||||
conf->RegisterVersionUpdater(std::make_shared<SOH::ConfigVersion1Updater>());
|
||||
conf->RegisterVersionUpdater(std::make_shared<SOH::ConfigVersion2Updater>());
|
||||
conf->RegisterVersionUpdater(std::make_shared<SOH::ConfigVersion3Updater>());
|
||||
conf->RegisterVersionUpdater(std::make_shared<SOH::ConfigVersion4Updater>());
|
||||
conf->RunVersionUpdates();
|
||||
|
||||
SohGui::SetupGuiElements();
|
||||
|
||||
@@ -1520,4 +1520,9 @@ std::vector<Migration> version3Migrations = {
|
||||
{ MigrationAction::Remove, "gPreset0" },
|
||||
{ MigrationAction::Remove, "gPreset1" },
|
||||
};
|
||||
|
||||
std::vector<Migration> version4Migrations = {
|
||||
{ MigrationAction::Rename, "gAudioEditor.SeqNameOverlay", "gAudioEditor.SeqNameNotification" },
|
||||
{ MigrationAction::Rename, "gAudioEditor.SeqNameOverlayDuration", "gAudioEditor.SeqNameNotificationDuration" },
|
||||
};
|
||||
} // namespace SOH
|
||||
|
||||
@@ -9,6 +9,8 @@ ConfigVersion2Updater::ConfigVersion2Updater() : ConfigVersionUpdater(2) {
|
||||
}
|
||||
ConfigVersion3Updater::ConfigVersion3Updater() : ConfigVersionUpdater(3) {
|
||||
}
|
||||
ConfigVersion4Updater::ConfigVersion4Updater() : ConfigVersionUpdater(4) {
|
||||
}
|
||||
|
||||
void ConfigVersion1Updater::Update(Ship::Config* conf) {
|
||||
if (conf->GetInt("Window.Width", 640) == 640) {
|
||||
@@ -111,4 +113,13 @@ void ConfigVersion3Updater::Update(Ship::Config* conf) {
|
||||
CVarClear(migration.from.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigVersion4Updater::Update(Ship::Config* conf) {
|
||||
for (Migration migration : version4Migrations) {
|
||||
if (migration.action == MigrationAction::Rename) {
|
||||
CVarCopy(migration.from.c_str(), migration.to.value().c_str());
|
||||
}
|
||||
CVarClear(migration.from.c_str());
|
||||
}
|
||||
}
|
||||
} // namespace SOH
|
||||
|
||||
@@ -18,4 +18,10 @@ class ConfigVersion3Updater final : public Ship::ConfigVersionUpdater {
|
||||
ConfigVersion3Updater();
|
||||
void Update(Ship::Config* conf);
|
||||
};
|
||||
|
||||
class ConfigVersion4Updater final : public Ship::ConfigVersionUpdater {
|
||||
public:
|
||||
ConfigVersion4Updater();
|
||||
void Update(Ship::Config* conf);
|
||||
};
|
||||
} // namespace SOH
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "soh/Enhancements/audio/AudioCollection.h"
|
||||
#include "soh/Enhancements/audio/AudioEditor.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include <stdio.h>
|
||||
#ifdef _MSC_VER
|
||||
#define strdup _strdup
|
||||
@@ -630,19 +631,7 @@ s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) {
|
||||
AudioSeq_SkipForwardSequence(seqPlayer);
|
||||
//! @bug missing return (but the return value is not used so it's not UB)
|
||||
|
||||
// Keep track of the previous sequence/scene so we don't repeat notifications
|
||||
static uint16_t previousSeqId = UINT16_MAX;
|
||||
static int16_t previousSceneNum = INT16_MAX;
|
||||
if (CVarGetInteger(CVAR_AUDIO("SeqNameOverlay"), 0) && playerIdx == SEQ_PLAYER_BGM_MAIN &&
|
||||
(seqId != previousSeqId || (gPlayState != NULL && gPlayState->sceneNum != previousSceneNum))) {
|
||||
|
||||
previousSeqId = seqId;
|
||||
if (gPlayState != NULL) {
|
||||
previousSceneNum = gPlayState->sceneNum;
|
||||
}
|
||||
|
||||
AudioCollection_EmitSongNameNotification(seqId);
|
||||
}
|
||||
GameInteractor_ExecuteOnSeqPlayerInit(playerIdx, seqId);
|
||||
}
|
||||
|
||||
u8* AudioLoad_SyncLoadSeq(s32 seqId) {
|
||||
|
||||
Reference in New Issue
Block a user