5#define WM_GRAPHNOTIFY (WM_APP + 1)
7#pragma comment(lib, "Strmiids.lib")
12 return std::clamp(int32_t((v + -1.0f) * 4'500.0f), -10'000, 0);
17 ((IBasicAudio*)audio_interface)->Release();
18 audio_interface =
nullptr;
20 if(control_interface) {
21 ((IMediaControl*)control_interface)->Release();
22 control_interface =
nullptr;
25 ((IMediaSeeking*)seek_interface)->Release();
26 seek_interface =
nullptr;
29 ((IMediaEventEx*)event_interface)->SetNotifyWindow(NULL, 0, NULL);
30 ((IMediaEventEx*)event_interface)->Release();
31 event_interface =
nullptr;
34 ((IGraphBuilder*)graph_interface)->Release();
35 graph_interface =
nullptr;
43 if(!graph_interface) {
44 IGraphBuilder* pGraph =
nullptr;
46 HRESULT hr = CoCreateInstance(CLSID_FilterGraph,
nullptr, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (
void**)&pGraph);
52 hr = pGraph->RenderFile((
wchar_t const*)(
filename.c_str()),
nullptr);
58 IMediaControl* pControl =
nullptr;
59 hr = pGraph->QueryInterface(IID_IMediaControl, (
void**)&pControl);
65 IMediaEventEx* pEvent =
nullptr;
66 hr = pGraph->QueryInterface(IID_IMediaEventEx, (
void**)&pEvent);
71 auto const res_b = pEvent->SetNotifyWindow((OAHWND)window_handle,
WM_GRAPHNOTIFY, NULL);
76 event_interface = pEvent;
78 IBasicAudio* pAudio =
nullptr;
79 hr = pGraph->QueryInterface(IID_IBasicAudio, (
void**)&pAudio);
84 IMediaSeeking* pSeek =
nullptr;
85 hr = pGraph->QueryInterface(IID_IMediaSeeking, (
void**)&pSeek);
90 graph_interface = pGraph;
91 control_interface = pControl;
92 audio_interface = pAudio;
93 seek_interface = pSeek;
98 LONGLONG new_position = 0;
99 hr = ((IMediaSeeking*)pSeek)->SetPositions(&new_position, AM_SEEKING_AbsolutePositioning,
nullptr, AM_SEEKING_NoPositioning);
103 hr = ((IMediaControl*)pControl)->Run();
109 if(audio_interface) {
116 LONGLONG new_position = 0;
117 hr = seek_interface->SetPositions(&new_position, AM_SEEKING_AbsolutePositioning,
nullptr, AM_SEEKING_NoPositioning);
122 if(control_interface) {
123 hr = control_interface->Run();
132 if(control_interface)
133 control_interface->Pause();
136 if(control_interface)
137 control_interface->Run();
140 if(control_interface)
141 control_interface->Pause();
146 LONGLONG end_position = 0;
147 LONGLONG current_position = 0;
148 auto const result = seek_interface->GetPositions(¤t_position, &end_position);
150 return !(
FAILED(result) || current_position >= end_position);
161 if(control_interface)
162 control_interface->Pause();
168 int32_t result = int32_t(rand() %
music_list.size());
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, ¶m1, ¶m2, 0))) {
198 event_interface->FreeEventParams(evCode, param1, param2);
217 if(!current_effect || current_effect->
is_playing() ==
false) {
227 if(current_interface_sound)
228 current_interface_sound->
stop();
229 current_interface_sound = &s;
251 if(current_interface_sound)
264 current_effect->
pause();
267 if(current_interface_sound)
268 current_interface_sound->
pause();
282 if(current_interface_sound)
283 current_interface_sound->
resume();
294 state.sound_ptr = std::make_unique<sound_impl>();
295 state.sound_ptr->window_handle = state.win_ptr->hwnd;
301 state.sound_ptr->music_list.emplace_back(file_name);
303 state.sound_ptr->first_music = int32_t(state.sound_ptr->music_list.size()) - 1;
308 state.sound_ptr->music_list.emplace_back(file_name);
313 audio_instance*
audio;
315 } vanilla_sound_table[] = {
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") },
353 for(
const auto& e : vanilla_sound_table) {
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") },
390 for(
const auto& e : new_sound_table) {
398 state.sound_ptr->change_effect_volume(v);
401 state.sound_ptr->change_interface_volume(v);
404 state.sound_ptr->change_music_volume(v);
410 state.sound_ptr->play_effect(s, volume);
414 state.sound_ptr->play_interface_sound(s, volume);
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;
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);
428 state.sound_ptr->play_music(int32_t(rand() %
state.sound_ptr->music_list.size()), v);
433 if(!
state.sound_ptr.get())
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();
442 if(!
state.sound_ptr.get())
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();
452 if(
state.sound_ptr->music_finished())
453 state.sound_ptr->play_new_track(state);
459 return state.sound_ptr->click_sound;
462 return state.sound_ptr->click_left_sound;
465 return state.sound_ptr->click_right_sound;
468 return state.sound_ptr->tab_budget_sound;
471 return state.sound_ptr->hover_sound;
474 return state.sound_ptr->checkbox_sound;
477 return state.sound_ptr->enact_sound;
480 return state.sound_ptr->subtab_sound;
483 return state.sound_ptr->delete_sound;
486 return state.sound_ptr->autochoose_sound;
489 return state.sound_ptr->tab_politics_sound;
492 return state.sound_ptr->tab_diplomacy_sound;
495 return state.sound_ptr->tab_military_sound;
498 return state.sound_ptr->tab_population_sound;
501 return state.sound_ptr->tab_production_sound;
504 return state.sound_ptr->tab_technology_sound;
507 return state.sound_ptr->army_select_sound;
510 return state.sound_ptr->army_move_sound;
513 return state.sound_ptr->navy_select_sound;
516 return state.sound_ptr->navy_move_sound;
519 return state.sound_ptr->error_sound;
522 return state.sound_ptr->peace_sound;
525 return state.sound_ptr->army_built_sound;
528 return state.sound_ptr->navy_built_sound;
531 return state.sound_ptr->declaration_of_war_sound;
534 return state.sound_ptr->technology_finished_sound;
537 return state.sound_ptr->factory_built_sound;
540 return state.sound_ptr->election_sound;
543 return state.sound_ptr->revolt_sound;
546 return state.sound_ptr->fort_built_sound;
549 return state.sound_ptr->railroad_built_sound;
552 return state.sound_ptr->naval_base_built_sound;
555 return state.sound_ptr->minor_event_sound;
558 return state.sound_ptr->major_event_sound;
561 return state.sound_ptr->decline_sound;
564 return state.sound_ptr->accept_sound;
567 return state.sound_ptr->diplomatic_request_sound;
570 return state.sound_ptr->chat_message_sound;
573 return state.sound_ptr->console_open_sound;
576 return state.sound_ptr->console_close_sound;
580 return state.sound_ptr->event_sound;
583 return state.sound_ptr->decision_sound;
586 return state.sound_ptr->pause_sound;
589 return state.sound_ptr->unpause_sound;
593 return state.sound_ptr->land_battle_sounds[int32_t(std::rand() % 6)];
596 return state.sound_ptr->naval_battle_sounds[int32_t(std::rand() % 6)];
599 return state.sound_ptr->province_select_sounds[int32_t(std::rand() % 4)];
603 state.sound_ptr->play_new_track(state);
606 state.sound_ptr->play_next_track(state);
609 state.sound_ptr->play_previous_track(state);
613 if(
state.sound_ptr->last_music == -1)
615 auto fname =
state.sound_ptr->music_list[
state.sound_ptr->last_music].filename;
void change_volume(float new_volume) const
void play(float volume, bool as_music, void *window_handle)
void resume_interface_sound() const
void play_interface_sound(audio_instance &s, float volume)
void play_music(int32_t track, float volume)
void pause_effect() const
void resume_music() const
std::vector< audio_instance > music_list
void change_effect_volume(float v) const
void resume_effect() const
void change_interface_volume(float v) const
void play_new_track(sys::state &ws)
void play_previous_track(sys::state &ws)
void play_effect(audio_instance &s, float volume)
void pause_interface_sound() const
void play_next_track(sys::state &ws)
void change_music_volume(float v) const
bool native_has_fixed_suffix_ci(char const *start, char const *end, char const (&t)[N])
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)
audio_instance & get_peace_sound(sys::state &state)
audio_instance & get_minor_event_sound(sys::state &state)
void pause_all(sys::state &state)
audio_instance & get_revolt_sound(sys::state &state)
audio_instance & get_hover_sound(sys::state &state)
void initialize_sound_system(sys::state &state)
audio_instance & get_tab_population_sound(sys::state &state)
void resume_all(sys::state &state)
audio_instance & get_tab_production_sound(sys::state &state)
audio_instance & get_army_built_sound(sys::state &state)
audio_instance & get_event_sound(sys::state &state)
audio_instance & get_decision_sound(sys::state &state)
audio_instance & get_tab_budget_sound(sys::state &state)
audio_instance & get_accept_sound(sys::state &state)
void play_next_track(sys::state &state)
void update_music_track(sys::state &state)
constexpr int32_t volume_function(float v)
audio_instance & get_technology_finished_sound(sys::state &state)
void change_effect_volume(sys::state &state, float v)
audio_instance & get_enact_sound(sys::state &state)
audio_instance & get_declaration_of_war_sound(sys::state &state)
audio_instance & get_console_open_sound(sys::state &state)
audio_instance & get_console_close_sound(sys::state &state)
audio_instance & get_tab_technology_sound(sys::state &state)
void stop_music(sys::state &state)
audio_instance & get_delete_sound(sys::state &state)
audio_instance & get_unpause_sound(sys::state &state)
audio_instance & get_click_left_sound(sys::state &state)
void change_interface_volume(sys::state &state, float v)
audio_instance & get_random_land_battle_sound(sys::state &state)
audio_instance & get_click_right_sound(sys::state &state)
audio_instance & get_naval_base_built_sound(sys::state &state)
audio_instance & get_tab_politics_sound(sys::state &state)
audio_instance & get_major_event_sound(sys::state &state)
native_string get_current_track_name(sys::state &state)
audio_instance & get_random_province_select_sound(sys::state &state)
audio_instance & get_railroad_built_sound(sys::state &state)
audio_instance & get_navy_move_sound(sys::state &state)
void play_effect(sys::state &state, audio_instance &s, float volume)
audio_instance & get_random_naval_battle_sound(sys::state &state)
audio_instance & get_pause_sound(sys::state &state)
void play_previous_track(sys::state &state)
audio_instance & get_navy_select_sound(sys::state &state)
audio_instance & get_checkbox_sound(sys::state &state)
void start_music(sys::state &state, float v)
audio_instance & get_decline_sound(sys::state &state)
audio_instance & get_election_sound(sys::state &state)
audio_instance & get_navy_built_sound(sys::state &state)
void play_new_track(sys::state &state)
audio_instance & get_army_select_sound(sys::state &state)
audio_instance & get_fort_built_sound(sys::state &state)
void play_interface_sound(sys::state &state, audio_instance &s, float volume)
audio_instance & get_diplomatic_request_sound(sys::state &state)
audio_instance & get_chat_message_sound(sys::state &state)
audio_instance & get_tab_diplomacy_sound(sys::state &state)
audio_instance & get_click_sound(sys::state &state)
audio_instance & get_error_sound(sys::state &state)
audio_instance & get_subtab_sound(sys::state &state)
void change_music_volume(sys::state &state, float v)
audio_instance & get_autochoose_sound(sys::state &state)
audio_instance & get_factory_built_sound(sys::state &state)
audio_instance & get_army_move_sound(sys::state &state)
audio_instance & get_tab_military_sound(sys::state &state)
void emit_error_message(std::string const &content, bool fatal)
std::string_view native_string_view
std::string native_string
user_settings_s user_settings