diff options
author | Nemrav <> | 2024-04-22 22:30:21 +0200 |
---|---|---|
committer | Nemrav <> | 2024-08-06 01:40:34 +0200 |
commit | 9506f4160f0bd351f0853e6e8263ea927d9ec771 (patch) | |
tree | 0a9bd4f52c01315c3b38ce641a78c33bd8562be2 /game/src | |
parent | fde15e554dc9ed458a838683c69d10262764db12 (diff) |
Music and Sound Effect loading and playing
almost working music loading
music list sent to godot
wav loading not working
mp3 metadata
load wav initial
load and play title theme first
fix errors not related to nodetools
working wav define loading and music playlists
fixup error handling and playlist
load song chances
code style progress
switch mp3 metadata addon to MusicMetadata
add id3v1 mp3 metadata handling to MusicMetadata
remove commented code from id3v1
sounds gd styling
fix dataloader conflicts
clean up commented code
move MusicChance to dataloader
remove reference to old addon
move sfx defines loader
add self to credits
feedback on soundSingleton
include subfolders in sound singleton sfx map
replace space tabs
replace std_view_to_godot_string with std_to_godot_string
revise singleton files
revise gd side sound
final revisions
Diffstat (limited to 'game/src')
-rw-r--r-- | game/src/Game/Autoload/SoundManager.gd | 20 | ||||
-rw-r--r-- | game/src/Game/GameSession/GameSession.gd | 2 | ||||
-rw-r--r-- | game/src/Game/GameStart.gd | 26 | ||||
-rw-r--r-- | game/src/Game/MusicConductor/MusicConductor.gd | 82 | ||||
-rw-r--r-- | game/src/Game/MusicConductor/SongInfo.gd | 11 | ||||
-rw-r--r-- | game/src/Game/Theme/StyleBoxWithSound.gd | 2 |
6 files changed, 130 insertions, 13 deletions
diff --git a/game/src/Game/Autoload/SoundManager.gd b/game/src/Game/Autoload/SoundManager.gd index 35c715c..01562f8 100644 --- a/game/src/Game/Autoload/SoundManager.gd +++ b/game/src/Game/Autoload/SoundManager.gd @@ -18,7 +18,7 @@ func _ready() -> void: "ogg", "wav", "mp3": _loaded_sound[fname.get_basename()] = load(_audio_directory_path.path_join(fname)) # SND-10 -func play_stream(sound : AudioStream, bus_type : String) -> void: +func play_stream(sound : AudioStream, bus_type : String, volume : float = 1.0) -> void: var player : AudioStreamPlayer = _bus_to_stream_player.get(bus_type) if player == null: player = AudioStreamPlayer.new() @@ -28,6 +28,7 @@ func play_stream(sound : AudioStream, bus_type : String) -> void: add_child(player) player.play() var poly_playback : AudioStreamPlaybackPolyphonic = player.get_stream_playback() + player.volume_db = linear_to_db(volume) poly_playback.play_stream(sound) func play(sound : String, bus_type : String) -> void: @@ -35,8 +36,21 @@ func play(sound : String, bus_type : String) -> void: # REQUIREMENTS: # * SND-7 -func play_effect_stream(sound : AudioStream) -> void: - play_stream(sound, "SFX") +func play_effect_stream(sound : AudioStream, volume : float = 1.0) -> void: + play_stream(sound, "SFX", volume) func play_effect(sound : String) -> void: play(sound, "SFX") + +func play_effect_compat(sfx : String, fallback : AudioStream=null) -> void: + var sound:AudioStreamWAV = SoundSingleton.get_sound_stream(sfx) + var volume:float = SoundSingleton.get_sound_base_volume(sfx) + + if sound != null: + play_effect_stream(sound,volume) + elif fallback != null: + push_warning("Failed to find sound %s, playing fallback instead" % sfx) + play_effect_stream(fallback) + else: + push_warning("Failed to find sound %s" % sfx) + diff --git a/game/src/Game/GameSession/GameSession.gd b/game/src/Game/GameSession/GameSession.gd index 0158b3a..30e6c1c 100644 --- a/game/src/Game/GameSession/GameSession.gd +++ b/game/src/Game/GameSession/GameSession.gd @@ -10,6 +10,8 @@ func _ready() -> void: _model_manager.generate_units() _model_manager.generate_buildings() + MusicConductor.generate_playlist() + MusicConductor.select_next_song() func _process(_delta : float) -> void: GameSingleton.try_tick() diff --git a/game/src/Game/GameStart.gd b/game/src/Game/GameStart.gd index 6074df8..3c046a0 100644 --- a/game/src/Game/GameStart.gd +++ b/game/src/Game/GameStart.gd @@ -105,8 +105,32 @@ func _setup_compatibility_mode_paths() -> void: _compatibility_path_list.push_back(actual_base_path + "/mod/" + mod_name) func _load_compatibility_mode() -> void: - if GameSingleton.load_defines_compatibility_mode(_compatibility_path_list) != OK: + if GameSingleton.set_compatibility_mode_roots(_compatibility_path_list) != OK: + push_error("Errors setting game roots!") + + setup_title_theme() + + if GameSingleton.load_defines_compatibility_mode() != OK: push_error("Errors loading game defines!") + + SoundSingleton.load_sounds() + SoundSingleton.load_music() + MusicConductor.add_compat_songs() + +func setup_title_theme() -> void: + SoundSingleton.load_title_theme() + + MusicConductor.setup_compat_song(SoundSingleton.title_theme) + + var song_paths = MusicConductor.get_all_song_paths() + var title_index = song_paths.find(SoundSingleton.title_theme) + if title_index != -1: + MusicConductor.call_deferred("start_song_by_index",title_index) + if len(MusicConductor._available_songs) <= 0: + push_error("No song available to play") + else: + MusicConductor.call_deferred("start_current_song") + # REQUIREMENTS # * FS-333, FS-334, FS-335, FS-341 diff --git a/game/src/Game/MusicConductor/MusicConductor.gd b/game/src/Game/MusicConductor/MusicConductor.gd index b4b660a..7103aff 100644 --- a/game/src/Game/MusicConductor/MusicConductor.gd +++ b/game/src/Game/MusicConductor/MusicConductor.gd @@ -17,6 +17,12 @@ var _selected_track := 0 var _available_songs : Array[SongInfo] = [] var _auto_play_next_song : bool = true +var playlist: Array[int] = [] +var playlist_index:int = 0 +var preferred_playlist_len: int = 7 +var last_played: int = -1 + + ## True if music player should be visible. ## Used to keep keep consistency between scene changes var is_music_player_visible : bool = true @@ -28,6 +34,12 @@ func get_all_song_names() -> PackedStringArray: for si : SongInfo in _available_songs: songNames.append(si.song_name) return songNames + +func get_all_song_paths() -> PackedStringArray: + var songPaths : PackedStringArray = [] + for si : SongInfo in _available_songs: + songPaths.append(si.song_path) + return songPaths func get_current_song_index() -> int: return _selected_track @@ -67,24 +79,82 @@ func start_song_by_index(id: int) -> void: # REQUIREMENTS # * SS-69 func select_next_song() -> void: - _selected_track = (_selected_track + 1) % len(_available_songs) + #_selected_track = (_selected_track + 1) % len(_available_songs) + if playlist_index >= preferred_playlist_len or playlist_index >= len(playlist): + generate_playlist() + playlist_index = 0 + _selected_track = playlist[playlist_index] + playlist_index += 1 + last_played = playlist_index start_current_song() func select_previous_song() -> void: _selected_track = (len(_available_songs) - 1) if (_selected_track == 0) else (_selected_track - 1) start_current_song() -# REQUIREMENTS -# * SND-2, SND-3 -func _ready() -> void: +func setup_compat_song(file_name) -> void: + var song = SongInfo.new() + var stream = SoundSingleton.get_song(file_name) + + var metadata = MusicMetadata.new() + metadata.set_from_stream(stream) + var title = metadata.title + if title == "": + #use the file name without the extension if there's no metadata + title = file_name.split(".")[0] + song.init_stream(file_name,title,stream) + _available_songs.append(song) + +func add_compat_songs() -> void: + for file_name : String in SoundSingleton.song_list: + setup_compat_song(file_name) + +func add_ootb_music() -> void: var dir := DirAccess.open(music_directory) for fname : String in dir.get_files(): if fname.ends_with(".import"): fname = fname.get_basename() if fname.get_basename() == first_song_name: _selected_track = _available_songs.size() - _available_songs.append(SongInfo.new(music_directory, fname)) - start_current_song() + var song = SongInfo.new() + song.init_file_path(music_directory, fname) + _available_songs.append(song) + +func generate_playlist() -> void: + var song_names = MusicConductor.get_all_song_paths() + var possible_indices = range(len(song_names)-1) + + var title_index = song_names.find(SoundSingleton.title_theme) + possible_indices.remove_at(title_index) + + var actual_playlist_len = min(preferred_playlist_len,len(possible_indices)) + + #if the playlist size is too large or small, make it the same size as what we + #need to support + if len(playlist) != actual_playlist_len: + playlist.resize(actual_playlist_len) + playlist.fill(0) + + #The song we just played can be in the playlist, just not the first one + if last_played != -1: + possible_indices.remove_at(last_played) + + #essentially shuffle-bag randomness, picking from a list of song indices + for i in range(actual_playlist_len): + var ind = randi_range(0,len(possible_indices)-1) + #add back the last song we just played as an option + if i==2: + possible_indices.append(last_played) + + playlist[i] = possible_indices[ind] + possible_indices.remove_at(ind) + +# REQUIREMENTS +# * SND-2, SND-3 +func _ready() -> void: + add_ootb_music() + #don't start the current song for compat mode, do that from + #GameStart so we can wait until the music is loaded func set_startup_music(play : bool) -> void: if not _has_startup_happened: diff --git a/game/src/Game/MusicConductor/SongInfo.gd b/game/src/Game/MusicConductor/SongInfo.gd index abcf120..527f618 100644 --- a/game/src/Game/MusicConductor/SongInfo.gd +++ b/game/src/Game/MusicConductor/SongInfo.gd @@ -3,9 +3,16 @@ class_name SongInfo var song_path : String = "" var song_name : String = "" -var song_stream : Resource +var song_stream : AudioStream -func _init(dirname:String, fname:String) -> void: +#Initialize from a file path +func init_file_path(dirname : String, fname : String) -> void: song_path = dirname.path_join(fname) song_name = fname.get_basename().replace("_", " ") song_stream = load(song_path) + +#Initialize from an audio stream +func init_stream(dirpath : String, name : String, stream : AudioStream) -> void: + song_path = dirpath + song_name = name + song_stream = stream diff --git a/game/src/Game/Theme/StyleBoxWithSound.gd b/game/src/Game/Theme/StyleBoxWithSound.gd index 8c29b34..75a181a 100644 --- a/game/src/Game/Theme/StyleBoxWithSound.gd +++ b/game/src/Game/Theme/StyleBoxWithSound.gd @@ -29,6 +29,6 @@ func _draw(to_canvas_item : RID, rect : Rect2) -> void: # Is there any other reason aside from release sounds (might be useful for toggles?) # This should be fast enough to not cause draw issues if sound != null: - SoundManager.play_effect_stream(sound) + SoundManager.play_effect_compat("click",sound) if style_box != null: style_box.draw(to_canvas_item, rect) |