Project Alice
Loading...
Searching...
No Matches
sound_win.cpp
Go to the documentation of this file.
1#include "sound.hpp"
2#include "system_state.hpp"
3#include "Dshow.h"
4
5#define WM_GRAPHNOTIFY (WM_APP + 1)
6
7#pragma comment(lib, "Strmiids.lib")
8
9namespace sound {
10
11constexpr int32_t volume_function(float v) {
12 return std::clamp(int32_t((v + -1.0f) * 4'500.0f), -10'000, 0);
13}
14
16 if(audio_interface) {
17 ((IBasicAudio*)audio_interface)->Release();
18 audio_interface = nullptr;
19 }
20 if(control_interface) {
21 ((IMediaControl*)control_interface)->Release();
22 control_interface = nullptr;
23 }
24 if(seek_interface) {
25 ((IMediaSeeking*)seek_interface)->Release();
26 seek_interface = nullptr;
27 }
28 if(event_interface) {
29 ((IMediaEventEx*)event_interface)->SetNotifyWindow(NULL, 0, NULL);
30 ((IMediaEventEx*)event_interface)->Release();
31 event_interface = nullptr;
32 }
33 if(graph_interface) {
34 ((IGraphBuilder*)graph_interface)->Release();
35 graph_interface = nullptr;
36 }
37}
38
39void audio_instance::play(float volume, bool as_music, void* window_handle) {
40 if(volume * volume_multiplier <= 0.0f || filename.size() == 0)
41 return;
42
43 if(!graph_interface) {
44 IGraphBuilder* pGraph = nullptr;
45
46 HRESULT hr = CoCreateInstance(CLSID_FilterGraph, nullptr, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph);
47 if(FAILED(hr)) {
48 window::emit_error_message("failed to create graph builder", false);
49 return;
50 }
51
52 hr = pGraph->RenderFile((wchar_t const*)(filename.c_str()), nullptr);
53 if(FAILED(hr)) {
54 window::emit_error_message("unable to play audio file", false);
55 volume_multiplier = 0.0f;
56 return;
57 }
58 IMediaControl* pControl = nullptr;
59 hr = pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl);
60 if(FAILED(hr)) {
61 window::emit_error_message("failed to get control interface", false);
62 return;
63 }
64 if(as_music) {
65 IMediaEventEx* pEvent = nullptr;
66 hr = pGraph->QueryInterface(IID_IMediaEventEx, (void**)&pEvent);
67 if(FAILED(hr)) {
68 window::emit_error_message("failed to get event interface", false);
69 return;
70 }
71 auto const res_b = pEvent->SetNotifyWindow((OAHWND)window_handle, WM_GRAPHNOTIFY, NULL);
72 if(FAILED(res_b)) {
73 window::emit_error_message("failed to set notification window", false);
74 return;
75 }
76 event_interface = pEvent;
77 }
78 IBasicAudio* pAudio = nullptr;
79 hr = pGraph->QueryInterface(IID_IBasicAudio, (void**)&pAudio);
80 if(FAILED(hr)) {
81 window::emit_error_message("failed to get audio interface", false);
82 return;
83 }
84 IMediaSeeking* pSeek = nullptr;
85 hr = pGraph->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
86 if(FAILED(hr)) {
87 window::emit_error_message("failed to get seeking interface", false);
88 return;
89 }
90 graph_interface = pGraph;
91 control_interface = pControl;
92 audio_interface = pAudio;
93 seek_interface = pSeek;
94 hr = ((IBasicAudio*)pAudio)->put_Volume(volume_function(volume * volume_multiplier));
95 if(FAILED(hr)) {
96 window::emit_error_message("failed to put_Volume", false);
97 }
98 LONGLONG new_position = 0;
99 hr = ((IMediaSeeking*)pSeek)->SetPositions(&new_position, AM_SEEKING_AbsolutePositioning, nullptr, AM_SEEKING_NoPositioning);
100 if(FAILED(hr)) {
101 window::emit_error_message("failed to SetPositions", false);
102 }
103 hr = ((IMediaControl*)pControl)->Run();
104 if(FAILED(hr)) {
105 window::emit_error_message("failed to Run", false);
106 }
107 } else {
108 HRESULT hr;
109 if(audio_interface) {
110 hr = audio_interface->put_Volume(volume_function(volume * volume_multiplier));
111 if(FAILED(hr)) {
112 window::emit_error_message("failed to put_Volume", false);
113 }
114 }
115 if(seek_interface) {
116 LONGLONG new_position = 0;
117 hr = seek_interface->SetPositions(&new_position, AM_SEEKING_AbsolutePositioning, nullptr, AM_SEEKING_NoPositioning);
118 if(FAILED(hr)) {
119 window::emit_error_message("failed to SetPositions", false);
120 }
121 }
122 if(control_interface) {
123 hr = control_interface->Run();
124 if(FAILED(hr)) {
125 window::emit_error_message("failed to Run", false);
126 }
127 }
128 }
129}
130
132 if(control_interface)
133 control_interface->Pause();
134}
136 if(control_interface)
137 control_interface->Run();
138}
140 if(control_interface)
141 control_interface->Pause();
142}
143
145 if(seek_interface && volume_multiplier > 0.0f) {
146 LONGLONG end_position = 0;
147 LONGLONG current_position = 0;
148 auto const result = seek_interface->GetPositions(&current_position, &end_position);
149
150 return !(FAILED(result) || current_position >= end_position);
151 } else {
152 return false;
153 }
154}
155
156void audio_instance::change_volume(float new_volume) const {
157 if(new_volume * volume_multiplier > 0.0f) {
158 if(audio_interface)
159 audio_interface->put_Volume(volume_function(new_volume * volume_multiplier));
160 } else {
161 if(control_interface)
162 control_interface->Pause();
163 }
164}
165
167 if(music_list.size() > 0) {
168 int32_t result = int32_t(rand() % music_list.size()); // well aware that using rand is terrible, thanks
169 for(uint32_t i = 0; i < 16 && result == last_music; i++) {
170 result = int32_t(rand() % music_list.size());
171 }
173 }
174}
176 if(music_list.size() > 0) {
177 int32_t result = int32_t((last_music + 1) % music_list.size());
179 }
180}
182 if(music_list.size() > 0) {
183 int32_t result = int32_t((last_music - 1) % music_list.size());
185 }
186}
187
189 auto const lm = last_music;
190 if(lm == -1)
191 return false;
192
193 long evCode;
194 LONG_PTR param1, param2;
195 auto const event_interface = music_list[lm].event_interface;
196 if(event_interface) {
197 while(SUCCEEDED(event_interface->GetEvent(&evCode, &param1, &param2, 0))) {
198 event_interface->FreeEventParams(evCode, param1, param2);
199 switch(evCode) {
200 case EC_COMPLETE: // Fall through.
201 case EC_USERABORT: // Fall through.
202 return true;
203 default:;
204 // nothing
205 }
206 }
207 return false;
208 } else {
209 return false;
210 }
211}
212
214 if(global_pause)
215 return;
216
217 if(!current_effect || current_effect->is_playing() == false) {
218 current_effect = &s;
219 s.play(volume, false, window_handle);
220 }
221}
222
224 if(global_pause)
225 return;
226
227 if(current_interface_sound)
228 current_interface_sound->stop();
229 current_interface_sound = &s;
230 s.play(volume, false, window_handle);
231}
232
233void sound_impl::play_music(int32_t track, float volume) {
234 if(global_pause)
235 return;
236
237 auto const lm = last_music;
238 if(lm != -1)
239 music_list[lm].stop();
240 last_music = track;
241 if(track != -1)
242 music_list[track].play(volume, true, window_handle);
243}
244
246 if(current_effect)
247 current_effect->change_volume(v);
248}
249
251 if(current_interface_sound)
252 current_interface_sound->change_volume(v);
253}
254
256 auto const lm = last_music;
257 if(lm != -1) {
258 music_list[lm].change_volume(v);
259 }
260}
261
263 if(current_effect)
264 current_effect->pause();
265}
267 if(current_interface_sound)
268 current_interface_sound->pause();
269}
271 auto const lm = last_music;
272 if(lm != -1) {
273 music_list[lm].pause();
274 }
275}
276
278 if(current_effect)
279 current_effect->resume();
280}
282 if(current_interface_sound)
283 current_interface_sound->resume();
284}
286 auto const lm = last_music;
287 if(lm != -1) {
288 music_list[lm].resume();
289 }
290}
291
292// called on startup and shutdown -- initialize should also load the list of available music files and load sound effects
294 state.sound_ptr = std::make_unique<sound_impl>();
295 state.sound_ptr->window_handle = state.win_ptr->hwnd;
296
297 auto root_dir = simple_fs::get_root(state.common_fs);
298 auto const music_dir = simple_fs::open_directory(root_dir, NATIVE("music"));
299 for(auto const& mp3_file : simple_fs::list_files(music_dir, NATIVE(".mp3"))) {
300 auto file_name = simple_fs::get_full_name(mp3_file);
301 state.sound_ptr->music_list.emplace_back(file_name);
302 if(parsers::native_has_fixed_suffix_ci(file_name.c_str(), file_name.c_str() + file_name.length(), NATIVE("thecoronation_titletheme.mp3")))
303 state.sound_ptr->first_music = int32_t(state.sound_ptr->music_list.size()) - 1;
304 }
305 for(auto const& music_subdir : simple_fs::list_subdirectories(music_dir)) {
306 for(auto const& mp3_file : simple_fs::list_files(music_subdir, NATIVE(".mp3"))) {
307 auto file_name = simple_fs::get_full_name(mp3_file);
308 state.sound_ptr->music_list.emplace_back(file_name);
309 }
310 }
311
312 struct {
313 audio_instance* audio;
315 } vanilla_sound_table[] = {
316 //{ &state.sound_ptr->click_sound, NATIVE("GI_ValidClick.wav") },
317 { &state.sound_ptr->technology_finished_sound, NATIVE("UI_TechnologyFinished.wav") },
318 { &state.sound_ptr->army_move_sound, NATIVE("GI_InfantryMove.wav") },
319 { &state.sound_ptr->army_select_sound, NATIVE("GI_InfantrySelected.wav") },
320 { &state.sound_ptr->navy_move_sound, NATIVE("UI_SailMove.wav") },
321 { &state.sound_ptr->navy_select_sound, NATIVE("UI_SailSelected.wav") },
322 { &state.sound_ptr->declaration_of_war_sound, NATIVE("DeclarationofWar.wav") },
323 { &state.sound_ptr->chat_message_sound, NATIVE("GI_ChatMessage.wav") },
324 { &state.sound_ptr->error_sound, NATIVE("GI_ErrorBlip.wav") },
325 { &state.sound_ptr->peace_sound, NATIVE("Misc_Peace.wav") },
326 { &state.sound_ptr->army_built_sound, NATIVE("UI_LandUnitFinished.wav") },
327 { &state.sound_ptr->navy_built_sound, NATIVE("UI_NavalUnitFinished.wav") },
328 { &state.sound_ptr->factory_built_sound, NATIVE("Misc_NewFactory.wav") },
329 { &state.sound_ptr->revolt_sound, NATIVE("Misc_revolt.wav") },
330 { &state.sound_ptr->fort_built_sound, NATIVE("Misc_Fortification.wav") },
331 { &state.sound_ptr->railroad_built_sound, NATIVE("Misc_Infrastructure.wav") },
332 { &state.sound_ptr->naval_base_built_sound, NATIVE("Misc_CoalingStation.wav") },
333 { &state.sound_ptr->minor_event_sound, NATIVE("GI_MinorBlip.wav") },
334 { &state.sound_ptr->major_event_sound, NATIVE("Misc_Attention.wav") },
335 { &state.sound_ptr->decline_sound, NATIVE("GI_FailureBlip.wav") },
336 { &state.sound_ptr->accept_sound, NATIVE("GI_SuccessBlip.wav") },
337 { &state.sound_ptr->diplomatic_request_sound, NATIVE("GI_MessageWindow.wav") },
338 { &state.sound_ptr->election_sound, NATIVE("Misc_ElectionHeld.wav") },
339 { &state.sound_ptr->land_battle_sounds[0], NATIVE("Combat_Cavalry_1.wav") },
340 { &state.sound_ptr->land_battle_sounds[1], NATIVE("Combat_Cavalry_2.wav") },
341 { &state.sound_ptr->land_battle_sounds[2], NATIVE("Combat_Cavalry_3.wav") },
342 { &state.sound_ptr->land_battle_sounds[3], NATIVE("Combat_Infantry_1.wav") },
343 { &state.sound_ptr->land_battle_sounds[4], NATIVE("Combat_Infantry_2.wav") },
344 { &state.sound_ptr->land_battle_sounds[5], NATIVE("Combat_Infantry_3.wav") },
345 { &state.sound_ptr->naval_battle_sounds[0], NATIVE("Combat_MajorShip_1.wav") },
346 { &state.sound_ptr->naval_battle_sounds[1], NATIVE("Combat_MajorShip_2.wav") },
347 { &state.sound_ptr->naval_battle_sounds[2], NATIVE("Combat_MajorShip_3.wav") },
348 { &state.sound_ptr->naval_battle_sounds[3], NATIVE("Combat_MinorShip_1.wav") },
349 { &state.sound_ptr->naval_battle_sounds[4], NATIVE("Combat_MinorShip_2.wav") },
350 { &state.sound_ptr->naval_battle_sounds[5], NATIVE("Combat_MinorShip_3.wav") },
351 };
352 auto const sound_directory = simple_fs::open_directory(root_dir, NATIVE("sound"));
353 for(const auto& e : vanilla_sound_table) {
354 auto file_peek = simple_fs::peek_file(sound_directory, e.name);
355 e.audio->set_file(file_peek ? simple_fs::get_full_name(*file_peek) : native_string());
356 }
357 struct {
358 audio_instance* audio;
360 } new_sound_table[] = {
361 { &state.sound_ptr->click_sound, NATIVE("NU_AltClick.wav") },
362 { &state.sound_ptr->click_left_sound, NATIVE("NU_ClickL.wav") },
363 { &state.sound_ptr->click_right_sound, NATIVE("NU_ClickR.wav") },
364 { &state.sound_ptr->console_open_sound, NATIVE("NU_OpenConsole.wav") },
365 { &state.sound_ptr->console_close_sound, NATIVE("NU_CloseConsole.wav") },
366 { &state.sound_ptr->tab_budget_sound, NATIVE("NU_TabBudget.wav") },
367 { &state.sound_ptr->hover_sound, NATIVE("NU_Hover.wav") },
368 { &state.sound_ptr->checkbox_sound, NATIVE("NU_Checkbox.wav") },
369 { &state.sound_ptr->enact_sound, NATIVE("NU_Enact.wav") },
370 { &state.sound_ptr->subtab_sound, NATIVE("NU_Subtab.wav") },
371 { &state.sound_ptr->delete_sound, NATIVE("NU_Delete.wav") },
372 { &state.sound_ptr->autochoose_sound, NATIVE("NU_Autochoose.wav") },
373 { &state.sound_ptr->tab_politics_sound, NATIVE("NU_TabPolitics.wav") },
374 { &state.sound_ptr->tab_diplomacy_sound, NATIVE("NU_TabDiplomacy.wav") },
375 { &state.sound_ptr->tab_military_sound, NATIVE("NU_TabMilitary.wav") },
376 { &state.sound_ptr->tab_population_sound, NATIVE("NU_TabPopulation.wav") },
377 { &state.sound_ptr->tab_production_sound, NATIVE("NU_TabProduction.wav") },
378 { &state.sound_ptr->tab_technology_sound, NATIVE("NU_TabTechnology.wav") },
379 { &state.sound_ptr->tab_military_sound, NATIVE("NU_TabMilitary.wav") },
380 { &state.sound_ptr->event_sound, NATIVE("NU_Event.wav") },
381 { &state.sound_ptr->decision_sound, NATIVE("NU_Decision.wav") },
382 { &state.sound_ptr->pause_sound, NATIVE("NU_Pause.wav") },
383 { &state.sound_ptr->unpause_sound, NATIVE("NU_Unpause.wav") },
384 { &state.sound_ptr->province_select_sounds[0], NATIVE("NU_ProvSelect1.wav") },
385 { &state.sound_ptr->province_select_sounds[1], NATIVE("NU_ProvSelect2.wav") },
386 { &state.sound_ptr->province_select_sounds[2], NATIVE("NU_ProvSelect3.wav") },
387 { &state.sound_ptr->province_select_sounds[3], NATIVE("NU_ProvSelect4.wav") },
388 };
389 auto const assets_directory = simple_fs::open_directory(root_dir, NATIVE("\\assets"));
390 for(const auto& e : new_sound_table) {
391 auto file_peek = simple_fs::peek_file(assets_directory, e.name);
392 e.audio->set_file(file_peek ? simple_fs::get_full_name(*file_peek) : native_string());
393 }
394}
395
396// these functions are called to change the volume of the currently playing track or effect
397void change_effect_volume(sys::state& state, float v) {
398 state.sound_ptr->change_effect_volume(v);
399}
400void change_interface_volume(sys::state& state, float v) {
401 state.sound_ptr->change_interface_volume(v);
402}
403void change_music_volume(sys::state& state, float v) {
404 state.sound_ptr->change_music_volume(v);
405}
406
407// these start playing an effect or track at the specified volume
408void play_effect(sys::state& state, audio_instance& s, float volume) {
409 if(volume > 0.0f)
410 state.sound_ptr->play_effect(s, volume);
411}
412void play_interface_sound(sys::state& state, audio_instance& s, float volume) {
413 if(volume > 0.0f)
414 state.sound_ptr->play_interface_sound(s, volume);
415}
416
417// controls autoplaying music (start music should start with the main theme)
418void stop_music(sys::state& state) {
419 if(state.sound_ptr->last_music != -1)
420 state.sound_ptr->music_list[state.sound_ptr->last_music].stop();
421 state.sound_ptr->last_music = -1;
422}
423void start_music(sys::state& state, float v) {
424 if(v > 0.0f && state.sound_ptr->music_list.size() != 0) {
425 if(state.sound_ptr->first_music != -1)
426 state.sound_ptr->play_music(state.sound_ptr->first_music, v);
427 else
428 state.sound_ptr->play_music(int32_t(rand() % state.sound_ptr->music_list.size()), v);
429 }
430}
431
432void pause_all(sys::state& state) {
433 if(!state.sound_ptr.get())
434 return;
435
436 state.sound_ptr->global_pause = true;
437 state.sound_ptr->pause_effect();
438 state.sound_ptr->pause_interface_sound();
439 state.sound_ptr->pause_music();
440}
441void resume_all(sys::state& state) {
442 if(!state.sound_ptr.get())
443 return;
444
445 state.sound_ptr->global_pause = false;
446 state.sound_ptr->resume_effect();
447 state.sound_ptr->resume_interface_sound();
448 state.sound_ptr->resume_music();
449}
450
451void update_music_track(sys::state& state) {
452 if(state.sound_ptr->music_finished())
453 state.sound_ptr->play_new_track(state);
454}
455
456// returns the default click sound -- expect this list of functions to expand as
457// we implement more of the fixed sound effects
458audio_instance& get_click_sound(sys::state& state) {
459 return state.sound_ptr->click_sound;
460}
461audio_instance& get_click_left_sound(sys::state& state) {
462 return state.sound_ptr->click_left_sound;
463}
464audio_instance& get_click_right_sound(sys::state& state) {
465 return state.sound_ptr->click_right_sound;
466}
467audio_instance& get_tab_budget_sound(sys::state& state) {
468 return state.sound_ptr->tab_budget_sound;
469}
470audio_instance& get_hover_sound(sys::state& state) {
471 return state.sound_ptr->hover_sound;
472}
473audio_instance& get_checkbox_sound(sys::state& state) {
474 return state.sound_ptr->checkbox_sound;
475}
476audio_instance& get_enact_sound(sys::state& state) {
477 return state.sound_ptr->enact_sound;
478}
479audio_instance& get_subtab_sound(sys::state& state) {
480 return state.sound_ptr->subtab_sound;
481}
482audio_instance& get_delete_sound(sys::state& state) {
483 return state.sound_ptr->delete_sound;
484}
485audio_instance& get_autochoose_sound(sys::state& state) {
486 return state.sound_ptr->autochoose_sound;
487}
488audio_instance& get_tab_politics_sound(sys::state& state) {
489 return state.sound_ptr->tab_politics_sound;
490}
491audio_instance& get_tab_diplomacy_sound(sys::state& state) {
492 return state.sound_ptr->tab_diplomacy_sound;
493}
494audio_instance& get_tab_military_sound(sys::state& state) {
495 return state.sound_ptr->tab_military_sound;
496}
497audio_instance& get_tab_population_sound(sys::state& state) {
498 return state.sound_ptr->tab_population_sound;
499}
500audio_instance& get_tab_production_sound(sys::state& state) {
501 return state.sound_ptr->tab_production_sound;
502}
503audio_instance& get_tab_technology_sound(sys::state& state) {
504 return state.sound_ptr->tab_technology_sound;
505}
506audio_instance& get_army_select_sound(sys::state& state) {
507 return state.sound_ptr->army_select_sound;
508}
509audio_instance& get_army_move_sound(sys::state& state) {
510 return state.sound_ptr->army_move_sound;
511}
512audio_instance& get_navy_select_sound(sys::state& state) {
513 return state.sound_ptr->navy_select_sound;
514}
515audio_instance& get_navy_move_sound(sys::state& state) {
516 return state.sound_ptr->navy_move_sound;
517}
518audio_instance& get_error_sound(sys::state& state) {
519 return state.sound_ptr->error_sound;
520}
521audio_instance& get_peace_sound(sys::state& state) {
522 return state.sound_ptr->peace_sound;
523}
524audio_instance& get_army_built_sound(sys::state& state) {
525 return state.sound_ptr->army_built_sound;
526}
527audio_instance& get_navy_built_sound(sys::state& state) {
528 return state.sound_ptr->navy_built_sound;
529}
530audio_instance& get_declaration_of_war_sound(sys::state& state) {
531 return state.sound_ptr->declaration_of_war_sound;
532}
533audio_instance& get_technology_finished_sound(sys::state& state) {
534 return state.sound_ptr->technology_finished_sound;
535}
536audio_instance& get_factory_built_sound(sys::state& state) {
537 return state.sound_ptr->factory_built_sound;
538}
539audio_instance& get_election_sound(sys::state& state) {
540 return state.sound_ptr->election_sound;
541}
542audio_instance& get_revolt_sound(sys::state& state) {
543 return state.sound_ptr->revolt_sound;
544}
545audio_instance& get_fort_built_sound(sys::state& state) {
546 return state.sound_ptr->fort_built_sound;
547}
548audio_instance& get_railroad_built_sound(sys::state& state) {
549 return state.sound_ptr->railroad_built_sound;
550}
551audio_instance& get_naval_base_built_sound(sys::state& state) {
552 return state.sound_ptr->naval_base_built_sound;
553}
554audio_instance& get_minor_event_sound(sys::state& state) {
555 return state.sound_ptr->minor_event_sound;
556}
557audio_instance& get_major_event_sound(sys::state& state) {
558 return state.sound_ptr->major_event_sound;
559}
560audio_instance& get_decline_sound(sys::state& state) {
561 return state.sound_ptr->decline_sound;
562}
563audio_instance& get_accept_sound(sys::state& state) {
564 return state.sound_ptr->accept_sound;
565}
566audio_instance& get_diplomatic_request_sound(sys::state& state) {
567 return state.sound_ptr->diplomatic_request_sound;
568}
569audio_instance& get_chat_message_sound(sys::state& state) {
570 return state.sound_ptr->chat_message_sound;
571}
572audio_instance& get_console_open_sound(sys::state& state) {
573 return state.sound_ptr->console_open_sound;
574}
575audio_instance& get_console_close_sound(sys::state& state) {
576 return state.sound_ptr->console_close_sound;
577}
578
579audio_instance& get_event_sound(sys::state& state) {
580 return state.sound_ptr->event_sound;
581}
582audio_instance& get_decision_sound(sys::state& state) {
583 return state.sound_ptr->decision_sound;
584}
585audio_instance& get_pause_sound(sys::state& state) {
586 return state.sound_ptr->pause_sound;
587}
588audio_instance& get_unpause_sound(sys::state& state) {
589 return state.sound_ptr->unpause_sound;
590}
591
592audio_instance& get_random_land_battle_sound(sys::state& state) {
593 return state.sound_ptr->land_battle_sounds[int32_t(std::rand() % 6)];
594}
595audio_instance& get_random_naval_battle_sound(sys::state& state) {
596 return state.sound_ptr->naval_battle_sounds[int32_t(std::rand() % 6)];
597}
598audio_instance& get_random_province_select_sound(sys::state& state) {
599 return state.sound_ptr->province_select_sounds[int32_t(std::rand() % 4)];
600}
601
602void play_new_track(sys::state& state) {
603 state.sound_ptr->play_new_track(state);
604}
605void play_next_track(sys::state& state) {
606 state.sound_ptr->play_next_track(state);
607}
608void play_previous_track(sys::state& state) {
609 state.sound_ptr->play_previous_track(state);
610}
611
613 if(state.sound_ptr->last_music == -1)
614 return NATIVE("");
615 auto fname = state.sound_ptr->music_list[state.sound_ptr->last_music].filename;
616 auto f = simple_fs::peek_file(simple_fs::get_root(state.common_fs), fname);
617 if(f) {
618 return simple_fs::get_file_name(*f);
619 }
620 return fname;
621}
622
623} // namespace sound
void resume() const
Definition: sound_win.cpp:135
native_string filename
Definition: sound_nix.hpp:10
void change_volume(float new_volume) const
Definition: sound_win.cpp:156
void play(float volume, bool as_music, void *window_handle)
Definition: sound_win.cpp:39
bool is_playing() const
Definition: sound_win.cpp:144
void pause() const
Definition: sound_win.cpp:131
void resume_interface_sound() const
Definition: sound_win.cpp:281
void pause_music() const
Definition: sound_win.cpp:270
void play_interface_sound(audio_instance &s, float volume)
Definition: sound_win.cpp:223
void play_music(int32_t track, float volume)
Definition: sound_nix.cpp:48
void pause_effect() const
Definition: sound_win.cpp:262
void resume_music() const
Definition: sound_win.cpp:285
std::vector< audio_instance > music_list
Definition: sound_nix.hpp:80
int32_t last_music
Definition: sound_nix.hpp:81
void change_effect_volume(float v) const
Definition: sound_win.cpp:245
void resume_effect() const
Definition: sound_win.cpp:277
void change_interface_volume(float v) const
Definition: sound_win.cpp:250
void play_new_track(sys::state &ws)
Definition: sound_nix.cpp:56
void play_previous_track(sys::state &ws)
Definition: sound_nix.cpp:71
void play_effect(audio_instance &s, float volume)
Definition: sound_win.cpp:213
bool music_finished()
Definition: sound_nix.cpp:78
void pause_interface_sound() const
Definition: sound_win.cpp:266
void play_next_track(sys::state &ws)
Definition: sound_nix.cpp:65
void change_music_volume(float v) const
Definition: sound_win.cpp:255
#define FAILED
Definition: gateway.c:99
bool native_has_fixed_suffix_ci(char const *start, char const *end, char const (&t)[N])
Definition: parsers.hpp:252
std::vector< unopened_file > list_files(directory const &dir, native_char const *extension)
std::vector< directory > list_subdirectories(directory const &dir)
directory open_directory(directory const &dir, native_string_view directory_name)
directory get_root(file_system const &fs)
native_string get_full_name(directory const &f)
std::optional< unopened_file > peek_file(directory const &dir, native_string_view file_name)
native_string get_file_name(unopened_file const &f)
Definition: sound.hpp:15
audio_instance & get_peace_sound(sys::state &state)
Definition: sound_nix.cpp:326
audio_instance & get_minor_event_sound(sys::state &state)
Definition: sound_nix.cpp:359
void pause_all(sys::state &state)
Definition: sound_nix.cpp:226
audio_instance & get_revolt_sound(sys::state &state)
Definition: sound_nix.cpp:347
audio_instance & get_hover_sound(sys::state &state)
Definition: sound_nix.cpp:275
void initialize_sound_system(sys::state &state)
Definition: sound_nix.cpp:84
audio_instance & get_tab_population_sound(sys::state &state)
Definition: sound_nix.cpp:302
void resume_all(sys::state &state)
Definition: sound_nix.cpp:240
audio_instance & get_tab_production_sound(sys::state &state)
Definition: sound_nix.cpp:305
audio_instance & get_army_built_sound(sys::state &state)
Definition: sound_nix.cpp:329
audio_instance & get_event_sound(sys::state &state)
Definition: sound_nix.cpp:384
audio_instance & get_decision_sound(sys::state &state)
Definition: sound_nix.cpp:387
audio_instance & get_tab_budget_sound(sys::state &state)
Definition: sound_nix.cpp:272
audio_instance & get_accept_sound(sys::state &state)
Definition: sound_nix.cpp:368
void play_next_track(sys::state &state)
Definition: sound_nix.cpp:410
void update_music_track(sys::state &state)
Definition: sound_nix.cpp:255
constexpr int32_t volume_function(float v)
Definition: sound_win.cpp:11
audio_instance & get_technology_finished_sound(sys::state &state)
Definition: sound_nix.cpp:338
void change_effect_volume(sys::state &state, float v)
Definition: sound_nix.cpp:188
audio_instance & get_enact_sound(sys::state &state)
Definition: sound_nix.cpp:281
audio_instance & get_declaration_of_war_sound(sys::state &state)
Definition: sound_nix.cpp:335
audio_instance & get_console_open_sound(sys::state &state)
Definition: sound_nix.cpp:377
audio_instance & get_console_close_sound(sys::state &state)
Definition: sound_nix.cpp:380
audio_instance & get_tab_technology_sound(sys::state &state)
Definition: sound_nix.cpp:308
void stop_music(sys::state &state)
Definition: sound_nix.cpp:209
audio_instance & get_delete_sound(sys::state &state)
Definition: sound_nix.cpp:287
audio_instance & get_unpause_sound(sys::state &state)
Definition: sound_nix.cpp:393
audio_instance & get_click_left_sound(sys::state &state)
Definition: sound_nix.cpp:266
void change_interface_volume(sys::state &state, float v)
Definition: sound_nix.cpp:191
audio_instance & get_random_land_battle_sound(sys::state &state)
Definition: sound_nix.cpp:397
audio_instance & get_click_right_sound(sys::state &state)
Definition: sound_nix.cpp:269
audio_instance & get_naval_base_built_sound(sys::state &state)
Definition: sound_nix.cpp:356
audio_instance & get_tab_politics_sound(sys::state &state)
Definition: sound_nix.cpp:293
audio_instance & get_major_event_sound(sys::state &state)
Definition: sound_nix.cpp:362
native_string get_current_track_name(sys::state &state)
Definition: sound_nix.cpp:417
audio_instance & get_random_province_select_sound(sys::state &state)
Definition: sound_nix.cpp:403
audio_instance & get_railroad_built_sound(sys::state &state)
Definition: sound_nix.cpp:353
audio_instance & get_navy_move_sound(sys::state &state)
Definition: sound_nix.cpp:320
void play_effect(sys::state &state, audio_instance &s, float volume)
Definition: sound_nix.cpp:198
audio_instance & get_random_naval_battle_sound(sys::state &state)
Definition: sound_nix.cpp:400
audio_instance & get_pause_sound(sys::state &state)
Definition: sound_nix.cpp:390
void play_previous_track(sys::state &state)
Definition: sound_nix.cpp:413
audio_instance & get_navy_select_sound(sys::state &state)
Definition: sound_nix.cpp:317
audio_instance & get_checkbox_sound(sys::state &state)
Definition: sound_nix.cpp:278
void start_music(sys::state &state, float v)
Definition: sound_nix.cpp:214
audio_instance & get_decline_sound(sys::state &state)
Definition: sound_nix.cpp:365
audio_instance & get_election_sound(sys::state &state)
Definition: sound_nix.cpp:344
audio_instance & get_navy_built_sound(sys::state &state)
Definition: sound_nix.cpp:332
void play_new_track(sys::state &state)
Definition: sound_nix.cpp:407
audio_instance & get_army_select_sound(sys::state &state)
Definition: sound_nix.cpp:311
audio_instance & get_fort_built_sound(sys::state &state)
Definition: sound_nix.cpp:350
void play_interface_sound(sys::state &state, audio_instance &s, float volume)
Definition: sound_nix.cpp:203
audio_instance & get_diplomatic_request_sound(sys::state &state)
Definition: sound_nix.cpp:371
audio_instance & get_chat_message_sound(sys::state &state)
Definition: sound_nix.cpp:374
audio_instance & get_tab_diplomacy_sound(sys::state &state)
Definition: sound_nix.cpp:296
audio_instance & get_click_sound(sys::state &state)
Definition: sound_nix.cpp:263
audio_instance & get_error_sound(sys::state &state)
Definition: sound_nix.cpp:323
audio_instance & get_subtab_sound(sys::state &state)
Definition: sound_nix.cpp:284
void change_music_volume(sys::state &state, float v)
Definition: sound_nix.cpp:194
audio_instance & get_autochoose_sound(sys::state &state)
Definition: sound_nix.cpp:290
audio_instance & get_factory_built_sound(sys::state &state)
Definition: sound_nix.cpp:341
audio_instance & get_army_move_sound(sys::state &state)
Definition: sound_nix.cpp:314
audio_instance & get_tab_military_sound(sys::state &state)
Definition: sound_nix.cpp:299
void emit_error_message(std::string const &content, bool fatal)
Definition: window_nix.cpp:355
#define NATIVE(X)
std::string_view native_string_view
std::string native_string
uint uint32_t
#define WM_GRAPHNOTIFY
Definition: sound_win.cpp:5
user_settings_s user_settings