Allow the volume dialog to work without VolumeValancer

When a game defines no VolumeValancer[], fall back to two generic
channels so BGM and sound effects can be adjusted independently.

Volume controls are now always available, so drop the conditional menu
handling.
This commit is contained in:
kichikuou
2026-06-29 15:52:08 +09:00
parent ff31d03153
commit e3dcadd5dd
10 changed files with 45 additions and 51 deletions
+1
View File
@@ -1 +1,2 @@
./src/menu_sdl.c
./src/volume.c
BIN
View File
Binary file not shown.
+8
View File
@@ -41,6 +41,14 @@ msgstr "ミュート"
msgid "Close"
msgstr "閉じる"
#: src/volume.c:90
msgid "BGM"
msgstr "BGM"
#: src/volume.c:91
msgid "Sound effects"
msgstr "効果音"
#: src/menu_sdl.c:378 src/menu_sdl.c:383 src/menu_sdl.c:529
msgid "OK"
msgstr "OK"
+2 -4
View File
@@ -74,9 +74,7 @@ static bool menu_build(mu_Context *ctx, modal *modal) {
struct popup_state *st = (struct popup_state *)modal;
bool keep_open = true;
bool has_volume = volume_available();
int rows = 3 + (has_volume ? 1 : 0);
int rows = 4;
int row_h = ctx->style->size.y + ctx->style->padding * 2;
int w = 200;
// `rows` rows with (rows - 1) inter-row gaps, plus the window's body padding.
@@ -100,7 +98,7 @@ static bool menu_build(mu_Context *ctx, modal *modal) {
if (mu_checkbox(ctx, _("Mouse Auto Move"), &warp))
nact->ags.mouse_warp_enabled = warp;
if (has_volume && mu_button(ctx, _("Volume"))) {
if (mu_button(ctx, _("Volume"))) {
keep_open = false;
st->action = MENU_ACTION_VOLUME;
}
+4
View File
@@ -36,6 +36,10 @@ enum MixDevice {
MIX_PCM
};
// Volume valancer channels.
#define BGM_VOLVAL_CH 0 // BGM is always mapped to this channel.
#define SE_VOLVAL_CH 1 // Sound-effect channel used when the game defines no VolumeValancer.
/* init and exit */
bool mus_init(int audio_buffer_size);
void mus_exit(void);
+1 -3
View File
@@ -23,6 +23,7 @@
#define __MUSIC_PRIVATE_H__
#include "portab.h"
#include "music.h"
#include "bgm.h"
#include "cdrom.h"
#include "midi.h"
@@ -31,9 +32,6 @@
#include "music_pcm.h"
#include "ald_manager.h"
// The volume valancer channel that BGM is mapped to.
#define BGM_VOLVAL_CH 0
struct _musprvdat {
bool midi_valid;
bool pcm_valid;
+3 -3
View File
@@ -181,7 +181,7 @@ bool muspcm_load_no(int slot, int no) {
int ch = WAIMIXCH(no);
prv.vol_pcm_sub[slot] = ch < 0 ? 0: ch;
} else {
prv.vol_pcm_sub[slot] = 0;
prv.vol_pcm_sub[slot] = SE_VOLVAL_CH;
}
return load_chunk(slot, chunk);
@@ -209,7 +209,7 @@ bool muspcm_load_mixlr(int slot, int noL, int noR) {
if (chunk == NULL) {
return false;
}
prv.vol_pcm_sub[slot] = 0;
prv.vol_pcm_sub[slot] = SE_VOLVAL_CH;
return load_chunk(slot, chunk);
}
@@ -221,7 +221,7 @@ bool muspcm_load_data(int slot, uint8_t *buf, uint32_t len) {
Mix_Chunk *chunk = Mix_LoadWAV_RW(SDL_RWFromConstMem(buf, len), 1);
if (!chunk)
return false;
prv.vol_pcm_sub[slot] = 0;
prv.vol_pcm_sub[slot] = SE_VOLVAL_CH;
return load_chunk(slot, chunk);
}
+23 -32
View File
@@ -45,15 +45,8 @@ struct volume_channel {
static int vval_max; // 最大チャンネル番号
static struct volume_channel vval[MAXVOLCH];
static bool vval_available;
bool volume_available(void) {
return vval_available;
}
static void apply_volume(void) {
if (!vval_available) return;
int vol[MAXVOLCH] = {0};
for (int i = 0; i < MAXVOLCH; i++) {
vol[i] = vval[i].mute ? 0 : vval[i].vol;
@@ -62,28 +55,34 @@ static void apply_volume(void) {
}
// 初期化
bool volume_init(void) {
FILE *fp;
char s[256], s1[256];
void volume_init(void) {
int i, vol[MAXVOLCH] = {0};
char fn[256];
int nvalancer = 0;
if (nact->files.init == NULL) return false;
if (NULL == (fp = fopen(nact->files.init, "r"))) return false;
while (fgets(s, 255, fp) != NULL) {
s1[0] = '\0';
sscanf(s, "VolumeValancer[%d] = \"%s", &i, s1);
if (s1[0] == '\0') continue;
if (i >= MAXVOLCH || i < 0) continue;
s1[strlen(s1)-1] = '\0'; // remove last '"'
vval[i].label = sjis2utf(s1);
vval_max = max(vval_max, i);
//WARNING("VolumeValancer[%d] = %s", i, vval[i].label);
FILE *fp = nact->files.init ? fopen(nact->files.init, "r") : NULL;
if (fp) {
char s[256], s1[256];
while (fgets(s, 255, fp) != NULL) {
s1[0] = '\0';
sscanf(s, "VolumeValancer[%d] = \"%s", &i, s1);
if (s1[0] == '\0') continue;
if (i >= MAXVOLCH || i < 0) continue;
s1[strlen(s1)-1] = '\0'; // remove last '"'
vval[i].label = sjis2utf(s1);
vval_max = max(vval_max, i);
nvalancer++;
}
fclose(fp);
}
if (vval_max <= 0) return false;
if (nvalancer == 0) {
// No VolumeValancer[] is defined (or there is no System39.ini). Fall back
// to two generic channels that control BGM and sound effects separately.
vval[BGM_VOLVAL_CH].label = strdup(_("BGM"));
vval[SE_VOLVAL_CH].label = strdup(_("Sound effects"));
vval_max = SE_VOLVAL_CH;
}
// Volume.sav があればそれを読み込む
snprintf(fn, sizeof(fn) -1, "%s/Volume.sav", nact->files.save_path);
@@ -101,10 +100,6 @@ bool volume_init(void) {
}
// どちらにしても music server に送る
mus_vol_set_valance(vol, MAXVOLCH);
vval_available = vval_max > 0;
return true;
}
// Volume Valance をセーブ
@@ -112,8 +107,6 @@ void volume_save(void) {
int vol[MAXVOLCH] = {0};
char fn[256];
if (!vval_available) return;
for (int i = 0; i < MAXVOLCH; i++) {
vol[i] = vval[i].vol;
}
@@ -203,8 +196,6 @@ static bool volume_build(mu_Context *ctx, modal *modal) {
}
void volume_dialog_open(void) {
if (!vval_available)
return;
struct volume_state st = {
.base = { .build = volume_build, .handler = modal_default_handler },
};
+3 -7
View File
@@ -25,17 +25,13 @@
#include <stdbool.h>
// Reads System39.ini / Volume.sav and applies the volumes. Returns true if the
// game defines any volume channels.
bool volume_init(void);
// Reads System39.ini / Volume.sav and applies the volumes.
void volume_init(void);
// Saves the current volumes to Volume.sav (called at exit).
void volume_save(void);
// True if the loaded game defines any volume channels.
bool volume_available(void);
// Opens the modal volume controller dialog. No-op if no channels are defined.
// Opens the modal volume controller dialog.
void volume_dialog_open(void);
#endif /* __VOLUME_H__ */
-2
View File
@@ -86,8 +86,6 @@ void win_menu_init(void) {
// Let SDL recalc the window size, taking menu height into account.
SDL_SetWindowSize(gfx_window, view_w, view_h);
CheckMenuItem(hmenu, ID_OPTION_MOUSE_MOVE, MF_BYCOMMAND | MFS_CHECKED);
if (!volume_available())
EnableMenuItem(hmenu, ID_OPTION_SOUND, MF_BYCOMMAND | MF_GRAYED);
}
void win_menu_onSysWMEvent(SDL_SysWMmsg* msg) {