option: port sound settings dialog to ui

This commit is contained in:
Marcin Kurczewski 2025-04-23 23:35:19 +02:00
parent c590824944
commit ebc6bd1e97
No known key found for this signature in database
GPG key ID: CC65E6FD28CAE42A
22 changed files with 311 additions and 308 deletions

View file

@ -531,7 +531,9 @@
"PHOTO_MODE_ROTATE_PROMPT": "Rotate camera",
"PHOTO_MODE_SNAP_PROMPT": "Take picture",
"PHOTO_MODE_TITLE": "Photo Mode",
"SOUND_SET_VOLUMES": "Set Volumes",
"SOUND_DIALOG_MUSIC": "\\{icon sound} Sound",
"SOUND_DIALOG_SOUND": "\\{icon music} Music",
"SOUND_DIALOG_TITLE": "Set Volumes",
"STATS_AMMO": "AMMO HITS/USED",
"STATS_BASIC_FMT": "%d",
"STATS_BONUS_STATISTICS": "Bonus Statistics",

View file

@ -655,7 +655,9 @@
"PHOTO_MODE_ROTATE_PROMPT": "Rotate camera",
"PHOTO_MODE_SNAP_PROMPT": "Take picture",
"PHOTO_MODE_TITLE": "Photo Mode",
"SOUND_SET_VOLUMES": "Set Volumes",
"SOUND_DIALOG_MUSIC": "\\{icon sound} Sound",
"SOUND_DIALOG_SOUND": "\\{icon music} Music",
"SOUND_DIALOG_TITLE": "Set Volumes",
"STATS_AMMO_HITS": "Hits",
"STATS_AMMO_USED": "Ammo Used",
"STATS_ASSAULT_FINISH": "Finish",

View file

@ -11,6 +11,7 @@
- changed the "enable EIDOS logo" option to disable the Core Design and Bink Video Codec FMVs as well; renamed to "enable legal" (#2741)
- changed sprite pickups to respect the water tint if placed underwater (#2673)
- changed save to take priority over load when both inputs are held on the same frame, in line with OG (#2833)
- changed the sound dialog appearance (repositioned and added text labels)
- fixed the bilinear filter to not readjust the UVs (#2258)
- fixed disabling the cutscenes causing the game to exit (#2743, regression from 4.8)
- fixed anisotropy filter causing black lines on certain GPUs (#902)

View file

@ -1,6 +1,7 @@
## [Unreleased](https://github.com/LostArtefacts/TRX/compare/tr2-1.0...develop) - ××××-××-××
- added an option to wraparound when scrolling UI dialogs, such as save/load (#2834)
- changed save to take priority over load when both inputs are held on the same frame, in line with OG (#2833)
- changed the sound dialog appearance (repositioned, added text labels and arrows)
- fixed the selected keyboard/controller layout not being saved (#2830, regression from 1.0)
- fixed toggling the PSX FOV option not having an immediate effect (#2831, regression from 1.0)
- fixed changing the aspect ratio not updating the current background image (#2832, regression from 1.0)

View file

@ -2,6 +2,16 @@
static uint16_t m_MusicTrackFlags[MAX_MUSIC_TRACKS] = {};
int32_t Music_GetMinVolume(void)
{
return 0;
}
int32_t Music_GetMaxVolume(void)
{
return 10;
}
void Music_ResetTrackFlags(void)
{
for (int32_t i = 0; i < MAX_MUSIC_TRACKS; i++) {

View file

@ -0,0 +1,176 @@
#include "game/ui/dialogs/sound_settings.h"
#include "config.h"
#include "game/game_string.h"
#include "game/input.h"
#include "game/music.h"
#include "game/sound.h"
#include "game/ui/elements/anchor.h"
#include "game/ui/elements/hide.h"
#include "game/ui/elements/label.h"
#include "game/ui/elements/modal.h"
#include "game/ui/elements/requester.h"
#include "game/ui/elements/resize.h"
#include "game/ui/elements/spacer.h"
#include "game/ui/elements/stack.h"
#include "memory.h"
#include "strings.h"
#include "utils.h"
typedef struct UI_SOUND_SETTINGS_STATE {
UI_REQUESTER_STATE req;
} UI_SOUND_SETTINGS_STATE;
typedef enum {
M_ROW_MUSIC = 0,
M_ROW_SOUND = 1,
M_ROW_COUNT = 2,
} M_ROW;
static const GAME_STRING_ID m_Labels[M_ROW_COUNT] = {
GS_ID(SOUND_DIALOG_SOUND),
GS_ID(SOUND_DIALOG_MUSIC),
};
static char *M_FormatRowValue(int32_t row);
static bool M_CanChange(int32_t row, int32_t dir);
static bool M_RequestChange(int32_t row, int32_t dir);
static char *M_FormatRowValue(const int32_t row)
{
switch (row) {
case M_ROW_MUSIC:
return String_Format("%2d", g_Config.audio.music_volume);
case M_ROW_SOUND:
return String_Format("%2d", g_Config.audio.sound_volume);
default:
return nullptr;
}
}
static bool M_CanChange(const int32_t row, const int32_t dir)
{
switch (row) {
case M_ROW_MUSIC:
if (dir < 0) {
return g_Config.audio.music_volume > Music_GetMinVolume();
} else if (dir > 0) {
return g_Config.audio.music_volume < Music_GetMaxVolume();
}
break;
case M_ROW_SOUND:
if (dir < 0) {
return g_Config.audio.sound_volume > Sound_GetMinVolume();
} else if (dir > 0) {
return g_Config.audio.sound_volume < Sound_GetMaxVolume();
}
break;
}
return false;
}
static bool M_RequestChange(const int32_t row, const int32_t dir)
{
if (!M_CanChange(row, dir)) {
return false;
}
switch (row) {
case M_ROW_MUSIC:
g_Config.audio.music_volume += dir;
Music_SetVolume(g_Config.audio.music_volume);
break;
case M_ROW_SOUND:
g_Config.audio.sound_volume += dir;
Sound_SetMasterVolume(g_Config.audio.sound_volume);
break;
default:
return false;
}
Config_Write();
Sound_Effect(SFX_MENU_PASSPORT, nullptr, SPM_ALWAYS);
return true;
}
UI_SOUND_SETTINGS_STATE *UI_SoundSettings_Init(void)
{
UI_SOUND_SETTINGS_STATE *s = Memory_Alloc(sizeof(UI_SOUND_SETTINGS_STATE));
UI_Requester_Init(&s->req, M_ROW_COUNT, M_ROW_COUNT, true);
s->req.row_pad = 2.0f;
return s;
}
void UI_SoundSettings_Free(UI_SOUND_SETTINGS_STATE *const s)
{
UI_Requester_Free(&s->req);
Memory_Free(s);
}
bool UI_SoundSettings_Control(UI_SOUND_SETTINGS_STATE *const s)
{
const int32_t choice = UI_Requester_Control(&s->req);
if (choice == UI_REQUESTER_CANCEL) {
return true;
}
const int32_t sel = UI_Requester_GetCurrentRow(&s->req);
if (g_InputDB.menu_left && sel >= 0) {
M_RequestChange(sel, -1);
} else if (g_InputDB.menu_right && sel >= 0) {
M_RequestChange(sel, +1);
}
return false;
}
void UI_SoundSettings(UI_SOUND_SETTINGS_STATE *const s)
{
const int32_t sel = UI_Requester_GetCurrentRow(&s->req);
UI_BeginModal(0.5f, 0.6f);
UI_BeginRequester(&s->req, GS(SOUND_DIALOG_TITLE));
// Measure the maximum width of the value label to prevent the entire
// dialog from changing its size as the player changes the sound levels.
float value_w = -1.0f;
UI_Label_Measure("10", &value_w, nullptr);
for (int32_t i = 0; i < s->req.max_rows; ++i) {
if (!UI_Requester_IsRowVisible(&s->req, i)) {
UI_BeginResize(-1.0f, 0.0f);
} else {
UI_BeginResize(-1.0f, -1.0f);
}
UI_BeginRequesterRow(&s->req, i);
UI_BeginStackEx((UI_STACK_SETTINGS) {
.orientation = UI_STACK_HORIZONTAL,
.align = { .h = UI_STACK_H_ALIGN_DISTRIBUTE },
});
UI_Label(GameString_Get(m_Labels[i]));
UI_Spacer(20.0f, 0.0f);
UI_BeginStackEx((UI_STACK_SETTINGS) {
.orientation = UI_STACK_HORIZONTAL,
.align = { .h = UI_STACK_H_ALIGN_DISTRIBUTE },
.spacing = { .h = 5.0f },
});
UI_BeginHide(i != sel || !M_CanChange(i, -1));
UI_Label("\\{button left}");
UI_EndHide();
UI_BeginResize(value_w, -1.0f);
UI_BeginAnchor(0.5f, 0.5f);
UI_Label(M_FormatRowValue(i));
UI_EndAnchor();
UI_EndResize();
UI_BeginHide(i != sel || !M_CanChange(i, +1));
UI_Label("\\{button right}");
UI_EndHide();
UI_EndStack();
UI_EndStack();
UI_EndRequesterRow(&s->req, i);
UI_EndResize();
}
UI_EndRequester(&s->req);
UI_EndModal();
}

View file

@ -114,7 +114,7 @@ static void M_Layout(
int32_t child_count = 0;
float total_child_main_size = 0.0f;
UI_NODE *child = node->first_child;
while (child != NULL) {
while (child != nullptr) {
switch (data->settings.orientation) {
case UI_STACK_HORIZONTAL:
total_child_main_size += child->measure_w;

View file

@ -132,7 +132,9 @@ GS_DEFINE(PASSPORT_MODE_NEW_GAME_JP_PLUS, "Japanese NG+")
GS_DEFINE(PASSPORT_STORY_SO_FAR, "Story so far...")
GS_DEFINE(PASSPORT_LEGACY_SELECT_LEVEL_1, "Legacy saves do not")
GS_DEFINE(PASSPORT_LEGACY_SELECT_LEVEL_2, "support this feature.")
GS_DEFINE(SOUND_SET_VOLUMES, "Set Volumes")
GS_DEFINE(SOUND_DIALOG_TITLE, "Set Volumes")
GS_DEFINE(SOUND_DIALOG_SOUND, "\\{icon music} Music")
GS_DEFINE(SOUND_DIALOG_MUSIC, "\\{icon sound} Sound")
GS_DEFINE(OSD_TRAPEZOID_FILTER_ON, "Trapezoid filter enabled")
GS_DEFINE(OSD_TRAPEZOID_FILTER_OFF, "Trapezoid filter disabled")
GS_DEFINE(DETAIL_INTEGER_FMT, "%d")

View file

@ -31,3 +31,15 @@ extern void Music_Unpause(void);
void Music_ResetTrackFlags(void);
uint16_t Music_GetTrackFlags(int32_t track_idx);
void Music_SetTrackFlags(int32_t track, uint16_t flags);
// Gets the minimum possible game volume.
extern int32_t Music_GetMinVolume(void);
// Gets the maximum possible game volume.
extern int32_t Music_GetMaxVolume(void);
// Gets the game volume.
extern int32_t Music_GetVolume(void);
// Sets the game volume.
extern void Music_SetVolume(int32_t volume);

View file

@ -14,6 +14,11 @@ int16_t *Sound_GetSampleLUT(void);
SAMPLE_INFO *Sound_GetSampleInfo(SOUND_EFFECT_ID sfx_num);
SAMPLE_INFO *Sound_GetSampleInfoByIdx(int32_t info_idx);
extern int32_t Sound_GetMinVolume(void);
extern int32_t Sound_GetMaxVolume(void);
extern int32_t Sound_GetMasterVolume(void);
extern void Sound_SetMasterVolume(int32_t volume);
void Sound_ResetSources(void);
void Sound_PauseAll(void);
void Sound_UnpauseAll(void);

View file

@ -10,6 +10,7 @@
#include "./ui/dialogs/play_any_level.h"
#include "./ui/dialogs/save_slot.h"
#include "./ui/dialogs/select_level.h"
#include "./ui/dialogs/sound_settings.h"
#include "./ui/dialogs/stats.h"
#include "./ui/elements/anchor.h"
#include "./ui/elements/fade.h"

View file

@ -0,0 +1,21 @@
// UI dialog for adjusting music and sound volumes
#pragma once
#include "../common.h"
typedef struct UI_SOUND_SETTINGS_STATE UI_SOUND_SETTINGS_STATE;
// state functions
// Initialize the sound settings dialog state
UI_SOUND_SETTINGS_STATE *UI_SoundSettings_Init(void);
// Free resources used by the sound settings dialog
void UI_SoundSettings_Free(UI_SOUND_SETTINGS_STATE *s);
// Handle input/control for the sound settings dialog
// Returns true if the dialog should be closed
bool UI_SoundSettings_Control(UI_SOUND_SETTINGS_STATE *s);
// draw functions
// Render the sound settings dialog
void UI_SoundSettings(UI_SOUND_SETTINGS_STATE *s);

View file

@ -216,6 +216,7 @@ sources = [
'game/ui/dialogs/play_any_level.c',
'game/ui/dialogs/save_slot.c',
'game/ui/dialogs/select_level.c',
'game/ui/dialogs/sound_settings.c',
'game/ui/dialogs/stats.c',
'game/ui/elements/anchor.c',
'game/ui/elements/fade.c',

View file

@ -182,12 +182,12 @@ void Music_Unmute(void)
M_SyncVolume(m_AudioStreamID);
}
int16_t Music_GetVolume(void)
int32_t Music_GetVolume(void)
{
return m_Volume;
}
void Music_SetVolume(int16_t volume)
void Music_SetVolume(int32_t volume)
{
if (volume != m_Volume) {
m_Volume = volume;
@ -195,16 +195,6 @@ void Music_SetVolume(int16_t volume)
}
}
int16_t Music_GetMinVolume(void)
{
return 0;
}
int16_t Music_GetMaxVolume(void)
{
return 10;
}
void Music_Pause(void)
{
if (m_AudioStreamID < 0) {

View file

@ -19,18 +19,6 @@ void Music_Mute(void);
// Unmutes the game music. Doesn't change the music volume.
void Music_Unmute(void);
// Gets the game volume.
int16_t Music_GetVolume(void);
// Sets the game volume. Value can be 0-10.
void Music_SetVolume(int16_t volume);
// Gets the minimum possible game volume.
int16_t Music_GetMinVolume(void);
// Gets the maximum possible game volume.
int16_t Music_GetMaxVolume(void);
// Returns the currently playing track. Includes looped music.
MUSIC_TRACK_ID Music_GetCurrentPlayingTrack(void);

View file

@ -168,6 +168,9 @@ void Option_Draw(INVENTORY_ITEM *const inv_item)
case O_COMPASS_OPTION:
Option_Compass_Draw();
break;
case O_SOUND_OPTION:
Option_Sound_Draw(inv_item);
break;
case O_PICKUP_OPTION_1:
case O_PICKUP_OPTION_2:

View file

@ -1,170 +1,48 @@
#include "game/option/option_sound.h"
#include "game/game_string.h"
#include "game/input.h"
#include "game/music.h"
#include "game/sound.h"
#include "game/text.h"
#include "global/vars.h"
#include <libtrx/config.h>
#include <libtrx/game/ui.h>
#include <stdio.h>
typedef struct {
UI_SOUND_SETTINGS_STATE *ui;
} M_PRIV;
typedef enum {
TEXT_MUSIC_VOLUME = 0,
TEXT_SOUND_VOLUME = 1,
TEXT_TITLE = 2,
TEXT_TITLE_BORDER = 3,
TEXT_LEFT_ARROW = 4,
TEXT_RIGHT_ARROW = 5,
TEXT_NUMBER_OF = 6,
TEXT_OPTION_MIN = TEXT_MUSIC_VOLUME,
TEXT_OPTION_MAX = TEXT_SOUND_VOLUME,
} SOUND_TEXT;
static M_PRIV m_Priv = {};
static TEXTSTRING *m_Text[TEXT_NUMBER_OF] = {};
static void M_InitText(void);
static void M_InitText(void)
static void M_Init(M_PRIV *const p)
{
char buf[20];
p->ui = UI_SoundSettings_Init();
}
m_Text[TEXT_LEFT_ARROW] = Text_Create(-45, 0, "\\{button left}");
m_Text[TEXT_RIGHT_ARROW] = Text_Create(40, 0, "\\{button right}");
m_Text[TEXT_TITLE_BORDER] = Text_Create(0, -32, " ");
m_Text[TEXT_TITLE] = Text_Create(0, -30, GS(SOUND_SET_VOLUMES));
if (g_Config.audio.music_volume > 10) {
g_Config.audio.music_volume = 10;
}
sprintf(buf, "\\{icon music} %2d", g_Config.audio.music_volume);
m_Text[TEXT_MUSIC_VOLUME] = Text_Create(0, 0, buf);
if (g_Config.audio.sound_volume > 10) {
g_Config.audio.sound_volume = 10;
}
sprintf(buf, "\\{icon sound} %2d", g_Config.audio.sound_volume);
m_Text[TEXT_SOUND_VOLUME] = Text_Create(0, 25, buf);
Text_AddBackground(m_Text[g_OptionSelected], 128, 0, 0, 0, TS_REQUESTED);
Text_AddOutline(m_Text[g_OptionSelected], TS_REQUESTED);
Text_AddBackground(m_Text[TEXT_TITLE], 136, 0, 0, 0, TS_HEADING);
Text_AddOutline(m_Text[TEXT_TITLE], TS_HEADING);
Text_AddBackground(m_Text[TEXT_TITLE_BORDER], 140, 85, 0, 0, TS_BACKGROUND);
Text_AddOutline(m_Text[TEXT_TITLE_BORDER], TS_BACKGROUND);
for (int i = 0; i < TEXT_NUMBER_OF; i++) {
Text_CentreH(m_Text[i], 1);
Text_CentreV(m_Text[i], 1);
static void M_Shutdown(M_PRIV *const p)
{
if (p->ui != nullptr) {
UI_SoundSettings_Free(p->ui);
p->ui = nullptr;
}
}
void Option_Sound_Control(INVENTORY_ITEM *inv_item, const bool is_busy)
void Option_Sound_Control(INVENTORY_ITEM *const inv_item, const bool is_busy)
{
M_PRIV *const p = &m_Priv;
if (is_busy) {
return;
}
char buf[20];
if (!m_Text[TEXT_MUSIC_VOLUME]) {
M_InitText();
if (p->ui == nullptr) {
M_Init(p);
}
UI_SoundSettings_Control(p->ui);
}
if (g_InputDB.menu_up && g_OptionSelected > TEXT_OPTION_MIN) {
Text_RemoveOutline(m_Text[g_OptionSelected]);
Text_RemoveBackground(m_Text[g_OptionSelected]);
--g_OptionSelected;
Text_AddBackground(
m_Text[g_OptionSelected], 128, 0, 0, 0, TS_REQUESTED);
Text_AddOutline(m_Text[g_OptionSelected], TS_REQUESTED);
Text_SetPos(m_Text[TEXT_LEFT_ARROW], -45, 0);
Text_SetPos(m_Text[TEXT_RIGHT_ARROW], 40, 0);
}
if (g_InputDB.menu_down && g_OptionSelected < TEXT_OPTION_MAX) {
Text_RemoveOutline(m_Text[g_OptionSelected]);
Text_RemoveBackground(m_Text[g_OptionSelected]);
++g_OptionSelected;
Text_AddBackground(
m_Text[g_OptionSelected], 128, 0, 0, 0, TS_REQUESTED);
Text_AddOutline(m_Text[g_OptionSelected], TS_REQUESTED);
Text_SetPos(m_Text[TEXT_LEFT_ARROW], -45, 25);
Text_SetPos(m_Text[TEXT_RIGHT_ARROW], 40, 25);
}
switch (g_OptionSelected) {
case TEXT_MUSIC_VOLUME:
if (g_InputDB.menu_left
&& g_Config.audio.music_volume > Music_GetMinVolume()) {
g_Config.audio.music_volume--;
Config_Write();
Music_SetVolume(g_Config.audio.music_volume);
Sound_Effect(SFX_MENU_PASSPORT, nullptr, SPM_ALWAYS);
sprintf(buf, "\\{icon music} %2d", g_Config.audio.music_volume);
Text_ChangeText(m_Text[TEXT_MUSIC_VOLUME], buf);
} else if (
g_InputDB.menu_right
&& g_Config.audio.music_volume < Music_GetMaxVolume()) {
g_Config.audio.music_volume++;
Config_Write();
Music_SetVolume(g_Config.audio.music_volume);
Sound_Effect(SFX_MENU_PASSPORT, nullptr, SPM_ALWAYS);
sprintf(buf, "\\{icon music} %2d", g_Config.audio.music_volume);
Text_ChangeText(m_Text[TEXT_MUSIC_VOLUME], buf);
}
Text_Hide(
m_Text[TEXT_LEFT_ARROW],
g_Config.audio.music_volume == Music_GetMinVolume());
Text_Hide(
m_Text[TEXT_RIGHT_ARROW],
g_Config.audio.music_volume == Music_GetMaxVolume());
break;
case TEXT_SOUND_VOLUME:
if (g_InputDB.menu_left
&& g_Config.audio.sound_volume > Sound_GetMinVolume()) {
g_Config.audio.sound_volume--;
Config_Write();
Sound_SetMasterVolume(g_Config.audio.sound_volume);
Sound_Effect(SFX_MENU_PASSPORT, nullptr, SPM_ALWAYS);
sprintf(buf, "\\{icon sound} %2d", g_Config.audio.sound_volume);
Text_ChangeText(m_Text[TEXT_SOUND_VOLUME], buf);
} else if (
g_InputDB.menu_right
&& g_Config.audio.sound_volume < Sound_GetMaxVolume()) {
g_Config.audio.sound_volume++;
Config_Write();
Sound_SetMasterVolume(g_Config.audio.sound_volume);
Sound_Effect(SFX_MENU_PASSPORT, nullptr, SPM_ALWAYS);
sprintf(buf, "\\{icon sound} %2d", g_Config.audio.sound_volume);
Text_ChangeText(m_Text[TEXT_SOUND_VOLUME], buf);
}
Text_Hide(
m_Text[TEXT_LEFT_ARROW],
g_Config.audio.sound_volume == Sound_GetMinVolume());
Text_Hide(
m_Text[TEXT_RIGHT_ARROW],
g_Config.audio.sound_volume == Sound_GetMaxVolume());
break;
}
if (g_InputDB.menu_confirm || g_InputDB.menu_back) {
Option_Sound_Shutdown();
void Option_Sound_Draw(INVENTORY_ITEM *const inv_item)
{
M_PRIV *const p = &m_Priv;
if (p->ui != nullptr) {
UI_SoundSettings(p->ui);
}
}
void Option_Sound_Shutdown(void)
{
for (int i = 0; i < TEXT_NUMBER_OF; i++) {
Text_Remove(m_Text[i]);
m_Text[i] = nullptr;
}
M_Shutdown(&m_Priv);
}

View file

@ -3,4 +3,5 @@
#include <libtrx/game/inventory_ring/types.h>
void Option_Sound_Control(INVENTORY_ITEM *inv_item, bool is_busy);
void Option_Sound_Draw(INVENTORY_ITEM *inv_item);
void Option_Sound_Shutdown(void);

View file

@ -528,18 +528,6 @@ void Sound_StopAll(void)
Audio_Sample_CloseAll();
}
void Sound_SetMasterVolume(int8_t volume)
{
int8_t raw_volume = volume ? 6 * volume + 3 : 0;
m_MasterVolumeDefault = raw_volume & 0x3F;
m_MasterVolume = raw_volume & 0x3F;
}
int8_t Sound_GetMasterVolume(void)
{
return (m_MasterVolume - 3) / 6;
}
int32_t Sound_GetMinVolume(void)
{
return 0;
@ -550,6 +538,18 @@ int32_t Sound_GetMaxVolume(void)
return 10;
}
void Sound_SetMasterVolume(int32_t volume)
{
int8_t raw_volume = volume ? 6 * volume + 3 : 0;
m_MasterVolumeDefault = raw_volume & 0x3F;
m_MasterVolume = raw_volume & 0x3F;
}
int32_t Sound_GetMasterVolume(void)
{
return (m_MasterVolume - 3) / 6;
}
void Sound_ResetAmbient(void)
{
M_ResetAmbientLoudness();

View file

@ -13,10 +13,6 @@ bool Sound_StopEffect(SOUND_EFFECT_ID sfx_num, const XYZ_32 *pos);
void Sound_UpdateEffects(void);
void Sound_ResetEffects(void);
void Sound_StopAmbientSounds(void);
int8_t Sound_GetMasterVolume(void);
void Sound_SetMasterVolume(int8_t volume);
int32_t Sound_GetMinVolume(void);
int32_t Sound_GetMaxVolume(void);
void Sound_LoadSamples(
size_t num_samples, const char **sample_pointers, size_t *sizes);
int32_t Sound_GetMaxSamples(void);

View file

@ -1,132 +1,48 @@
#include "game/game_string.h"
#include "game/input.h"
#include "game/inventory_ring.h"
#include "game/music.h"
#include "game/option/option.h"
#include "game/sound.h"
#include "game/text.h"
#include "global/vars.h"
#include <libtrx/config.h>
#include <libtrx/utils.h>
#include <libtrx/game/ui.h>
#include <stdio.h>
typedef struct {
UI_SOUND_SETTINGS_STATE *ui;
} M_PRIV;
static TEXTSTRING *m_SoundText[4];
static M_PRIV m_Priv = {};
static void M_InitText(void);
static void M_ShutdownText(void);
static void M_InitText(void)
static void M_Init(M_PRIV *const p)
{
CLAMPG(g_Config.audio.music_volume, 10);
CLAMPG(g_Config.audio.sound_volume, 10);
p->ui = UI_SoundSettings_Init();
}
char text[32];
sprintf(text, "\\{icon music} %2d", g_Config.audio.music_volume);
m_SoundText[0] = Text_Create(0, 0, text);
Text_AddBackground(m_SoundText[0], 128, 0, 0, 0, TS_REQUESTED);
Text_AddOutline(m_SoundText[0], TS_REQUESTED);
sprintf(text, "\\{icon sound} %2d", g_Config.audio.sound_volume);
m_SoundText[1] = Text_Create(0, 25, text);
m_SoundText[2] = Text_Create(0, -32, " ");
Text_AddBackground(m_SoundText[2], 140, 85, 0, 0, TS_BACKGROUND);
Text_AddOutline(m_SoundText[2], TS_BACKGROUND);
m_SoundText[3] = Text_Create(0, -30, GS(SOUND_SET_VOLUMES));
Text_AddBackground(m_SoundText[3], 136, 0, 0, 0, TS_HEADING);
Text_AddOutline(m_SoundText[3], TS_HEADING);
for (int32_t i = 0; i < 4; i++) {
Text_CentreH(m_SoundText[i], true);
Text_CentreV(m_SoundText[i], true);
static void M_Shutdown(M_PRIV *const p)
{
if (p->ui != nullptr) {
UI_SoundSettings_Free(p->ui);
p->ui = nullptr;
}
}
static void M_ShutdownText(void)
void Option_Sound_Control(INVENTORY_ITEM *const inv_item, const bool is_busy)
{
for (int32_t i = 0; i < 4; i++) {
Text_Remove(m_SoundText[i]);
m_SoundText[i] = nullptr;
M_PRIV *const p = &m_Priv;
if (is_busy) {
return;
}
if (p->ui == nullptr) {
M_Init(p);
}
UI_SoundSettings_Control(p->ui);
}
void Option_Sound_Draw(INVENTORY_ITEM *const inv_item)
{
M_PRIV *const p = &m_Priv;
if (p->ui != nullptr) {
UI_SoundSettings(p->ui);
}
}
void Option_Sound_Shutdown(void)
{
M_ShutdownText();
}
void Option_Sound_Control(INVENTORY_ITEM *const item, const bool is_busy)
{
if (is_busy) {
return;
}
char text[32];
if (m_SoundText[0] == nullptr) {
M_InitText();
}
if (g_InputDB.menu_up && g_SoundOptionLine > 0) {
Text_RemoveOutline(m_SoundText[g_SoundOptionLine]);
Text_RemoveBackground(m_SoundText[g_SoundOptionLine]);
g_SoundOptionLine--;
Text_AddBackground(
m_SoundText[g_SoundOptionLine], 128, 0, 0, 0, TS_REQUESTED);
Text_AddOutline(m_SoundText[g_SoundOptionLine], TS_REQUESTED);
}
if (g_InputDB.menu_down && g_SoundOptionLine < 1) {
Text_RemoveOutline(m_SoundText[g_SoundOptionLine]);
Text_RemoveBackground(m_SoundText[g_SoundOptionLine]);
g_SoundOptionLine++;
Text_AddBackground(
m_SoundText[g_SoundOptionLine], 128, 0, 0, 0, TS_REQUESTED);
Text_AddOutline(m_SoundText[g_SoundOptionLine], TS_REQUESTED);
}
if (g_SoundOptionLine) {
bool changed = false;
if (g_InputDB.menu_left && g_Config.audio.sound_volume > 0) {
g_Config.audio.sound_volume--;
changed = true;
} else if (g_InputDB.menu_right && g_Config.audio.sound_volume < 10) {
g_Config.audio.sound_volume++;
changed = true;
}
if (changed) {
sprintf(text, "\\{icon sound} %2d", g_Config.audio.sound_volume);
Text_ChangeText(m_SoundText[1], text);
Sound_SetMasterVolume(g_Config.audio.sound_volume);
Sound_Effect(SFX_MENU_PASSPORT, nullptr, SPM_ALWAYS);
}
} else {
bool changed = false;
if (g_InputDB.menu_left && g_Config.audio.music_volume > 0) {
g_Config.audio.music_volume--;
changed = true;
} else if (g_InputDB.menu_right && g_Config.audio.music_volume < 10) {
g_Config.audio.music_volume++;
changed = true;
}
if (changed) {
sprintf(text, "\\{icon music} %2d", g_Config.audio.music_volume);
Text_ChangeText(m_SoundText[0], text);
Music_SetVolume(g_Config.audio.music_volume);
Sound_Effect(SFX_MENU_PASSPORT, nullptr, SPM_ALWAYS);
}
}
if (g_InputDB.menu_confirm || g_InputDB.menu_back) {
Option_Sound_Shutdown();
}
}
void Option_Sound_Draw(INVENTORY_ITEM *const item)
{
M_Shutdown(&m_Priv);
}

View file

@ -9,9 +9,6 @@
void Sound_Init(void);
void Sound_Shutdown(void);
void Sound_SetMasterVolume(int32_t volume);
void Sound_UpdateEffects(void);
void Sound_StopEffect(SOUND_EFFECT_ID sample_id);
void Sound_EndScene(void);
int32_t Sound_GetMinVolume(void);
int32_t Sound_GetMaxVolume(void);