Add menu audio controls and menu music

This commit is contained in:
2026-05-07 20:35:15 +02:00
parent a908b50019
commit 2367f4fb1c
10 changed files with 348 additions and 25 deletions
+2
View File
@@ -279,6 +279,8 @@ class KeyBindings:
def toggle_audio(self):
self.render_engine.audio = not self.render_engine.audio
self.audio = self.render_engine.audio
if hasattr(self, "profile_integration") and self.profile_integration:
self.profile_integration.set_setting("sound_enabled", self.audio)
if not self.render_engine.audio:
self.render_engine.stop_sound()
+30 -2
View File
@@ -128,6 +128,7 @@ class GameWindow:
self.audio_devs["base"] = sdl2.SDL_OpenAudioDevice(None, 0, audio_spec, None, 0)
self.audio_devs["effects"] = sdl2.SDL_OpenAudioDevice(None, 0, audio_spec, None, 0)
self.audio_devs["music"] = sdl2.SDL_OpenAudioDevice(None, 0, audio_spec, None, 0)
self.sound_volume = sdl2.SDL_MIX_MAXVOLUME
self.music_enabled = False
self.music_volume = 128
self.music_track = None
@@ -149,12 +150,20 @@ class GameWindow:
self.music_enabled = True
sdlmixer.Mix_VolumeMusic(self.music_volume)
def set_volume(self, volume_percent):
def set_sound_volume(self, volume_percent):
clamped = max(0, min(int(volume_percent), 100))
self.sound_volume = int(round(clamped * sdl2.SDL_MIX_MAXVOLUME / 100))
def set_music_volume(self, volume_percent):
clamped = max(0, min(int(volume_percent), 100))
self.music_volume = int(round(clamped * 128 / 100))
if self.music_enabled and sdlmixer is not None:
sdlmixer.Mix_VolumeMusic(self.music_volume)
def set_volume(self, volume_percent):
self.set_sound_volume(volume_percent)
self.set_music_volume(volume_percent)
def play_music(self, music_file, loop=True):
if not self.audio or not self.music_enabled or sdlmixer is None:
return False
@@ -498,12 +507,31 @@ class GameWindow:
spec = SDL_AudioSpec(freq=22050, aformat=sdl2.AUDIO_U8, channels=1, samples=2048)
if sdl2.SDL_LoadWAV_RW(rw, 1, byref(spec), byref(_buf), byref(_length)) == None:
raise RuntimeError("Failed to load WAV")
if self.sound_volume <= 0:
sdl2.SDL_FreeWAV(_buf)
return
devid = self.audio_devs[tag]
# Clear any queued audio
sdl2.SDL_ClearQueuedAudio(devid)
buffer_length = int(_length.value)
if self.sound_volume < sdl2.SDL_MIX_MAXVOLUME:
scaled_buffer = create_string_buffer(buffer_length)
sdl2.SDL_MixAudioFormat(
cast(scaled_buffer, POINTER(sdl2.Uint8)),
_buf,
spec.format,
buffer_length,
self.sound_volume,
)
sdl2.SDL_QueueAudio(devid, cast(scaled_buffer, POINTER(sdl2.Uint8)), buffer_length)
else:
sdl2.SDL_QueueAudio(devid, _buf, buffer_length)
sdl2.SDL_FreeWAV(_buf)
# Start playing audio
sdl2.SDL_QueueAudio(devid, _buf, _length)
sdl2.SDL_PauseAudioDevice(devid, 0)
def stop_sound(self):
+26
View File
@@ -72,6 +72,32 @@ class UserProfileIntegration:
if self.current_profile and 'settings' in self.current_profile:
return self.current_profile['settings'].get(setting_name, default_value)
return default_value
def set_setting(self, setting_name, value):
"""Persist a setting on the active local profile."""
if not self.current_profile:
return False
try:
with self.profiles_file.open('r', encoding='utf-8') as f:
data = json.load(f)
profile_name = self.current_profile['name']
if profile_name not in data.get('profiles', {}):
return False
profile = data['profiles'][profile_name]
profile.setdefault('settings', {})
profile['settings'][setting_name] = value
self.current_profile = profile
with self.profiles_file.open('w', encoding='utf-8') as f:
json.dump(data, f, indent=2)
return True
except Exception as e:
print(f"Error updating setting {setting_name}: {e}")
return False
def register_new_user(self, user_id):
"""Registration is handled locally via the profile manager."""