fmod/studio/system/
misc.rs

1// Copyright (c) 2024 Melody Madeline Lyons
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
7use fmod_sys::*;
8use lanyard::Utf8CStr;
9use std::mem::MaybeUninit;
10
11use crate::Guid;
12
13use crate::studio::{AdvancedSettings, Bus, EventDescription, SoundInfo, System, Vca};
14use crate::{FmodResultExt, Result};
15
16impl System {
17    /// Retrieves a loaded [`Bus`].
18    ///
19    /// This function allows you to retrieve a handle for any bus in the global mixer.
20    ///
21    /// `path_or_id` may be a path, such as `bus:/SFX/Ambience`, or an ID string, such as `{d9982c58-a056-4e6c-b8e3-883854b4bffb}`.
22    ///
23    /// Note that path lookups will only succeed if the strings bank has been loaded.
24    pub fn get_bus(&self, path_or_id: &Utf8CStr) -> Result<Bus> {
25        let mut bus = std::ptr::null_mut();
26        unsafe {
27            FMOD_Studio_System_GetBus(self.inner.as_ptr(), path_or_id.as_ptr(), &raw mut bus)
28                .to_result()?;
29            Ok(Bus::from_ffi(bus))
30        }
31    }
32
33    /// Retrieves a loaded [`Bus`].
34    ///
35    /// This function allows you to retrieve a handle for any bus in the global mixer.
36    pub fn get_bus_by_id(&self, id: Guid) -> Result<Bus> {
37        let mut bus = std::ptr::null_mut();
38        unsafe {
39            FMOD_Studio_System_GetBusByID(self.inner.as_ptr(), &id.into(), &raw mut bus)
40                .to_result()?;
41            Ok(Bus::from_ffi(bus))
42        }
43    }
44
45    /// Retrieves an [`EventDescription`].
46    ///
47    /// This function allows you to retrieve a handle to any loaded event description.
48    ///
49    /// `path+or_id` may be a path, such as `event:/UI/Cancel` or `snapshot:/IngamePause`, or an ID string, such as `{2a3e48e6-94fc-4363-9468-33d2dd4d7b00}`.
50    ///
51    /// Note that path lookups will only succeed if the strings bank has been loaded.
52    pub fn get_event(&self, path_or_id: &Utf8CStr) -> Result<EventDescription> {
53        let mut event = std::ptr::null_mut();
54        unsafe {
55            FMOD_Studio_System_GetEvent(self.inner.as_ptr(), path_or_id.as_ptr(), &raw mut event)
56                .to_result()?;
57            Ok(EventDescription::from_ffi(event))
58        }
59    }
60
61    /// Retrieves an [`EventDescription`].
62    ///
63    /// This function allows you to retrieve a handle to any loaded event description.
64    pub fn get_event_by_id(&self, id: Guid) -> Result<EventDescription> {
65        let mut event = std::ptr::null_mut();
66        unsafe {
67            FMOD_Studio_System_GetEventByID(self.inner.as_ptr(), &id.into(), &raw mut event)
68                .to_result()?;
69            Ok(EventDescription::from_ffi(event))
70        }
71    }
72
73    /// Retrieves a loaded VCA.
74    ///
75    /// This function allows you to retrieve a handle for any VCA in the global mixer.
76    ///
77    /// `path_or_id` may be a path, such as `vca:/MyVCA`, or an ID string, such as `{d9982c58-a056-4e6c-b8e3-883854b4bffb`}.
78    ///
79    /// Note that path lookups will only succeed if the strings bank has been loaded.
80    pub fn get_vca(&self, path_or_id: &Utf8CStr) -> Result<Vca> {
81        let mut vca = std::ptr::null_mut();
82        unsafe {
83            FMOD_Studio_System_GetVCA(self.inner.as_ptr(), path_or_id.as_ptr(), &raw mut vca)
84                .to_result()?;
85            Ok(Vca::from_ffi(vca))
86        }
87    }
88
89    /// Retrieves a loaded VCA.
90    ///
91    /// This function allows you to retrieve a handle for any VCA in the global mixer.
92    pub fn get_vca_by_id(&self, id: Guid) -> Result<Vca> {
93        let mut vca = std::ptr::null_mut();
94        unsafe {
95            FMOD_Studio_System_GetVCAByID(self.inner.as_ptr(), &id.into(), &raw mut vca)
96                .to_result()?;
97            Ok(Vca::from_ffi(vca))
98        }
99    }
100
101    /// Retrieves advanced settings.
102    pub fn get_advanced_settings(&self) -> Result<AdvancedSettings> {
103        let mut advanced_settings = MaybeUninit::zeroed();
104
105        unsafe {
106            FMOD_Studio_System_GetAdvancedSettings(
107                self.inner.as_ptr(),
108                advanced_settings.as_mut_ptr(),
109            )
110            .to_result()?;
111
112            let advanced_settings = AdvancedSettings::from_ffi(advanced_settings.assume_init());
113
114            Ok(advanced_settings)
115        }
116    }
117
118    /// Retrieves information for loading a sound from the audio table.
119    ///
120    /// The [`SoundInfo`] structure contains information to be passed to [`crate::System::create_sound`] (which will create a parent sound),
121    /// along with a subsound index to be passed to [`crate::Sound::get_sub_sound`] once the parent sound is loaded.
122    ///
123    /// The user is expected to call [`crate::System::create_sound`] with the given information.
124    /// It is up to the user to combine in any desired loading flags, such as [`FMOD_CREATESTREAM`], [`FMOD_CREATECOMPRESSEDSAMPLE`] or [`FMOD_NONBLOCKING`] with the flags in [`FMOD_STUDIO_SOUND_INFO::mode`].
125    ///
126    /// When the banks have been loaded via [`System::load_bank_memory`], the mode will be returned as [`FMOD_OPENMEMORY_POINT`].
127    /// This won't work with the default [`FMOD_CREATESAMPLE`] mode.
128    /// For memory banks, you should add in the [`FMOD_CREATECOMPRESSEDSAMPLE`] or [`FMOD_CREATESTREAM`] flag, or remove [`FMOD_OPENMEMORY_POINT`] and add [`FMOD_OPENMEMORY`] to decompress the sample into a new allocation.
129    ///
130    /// # Safety
131    ///
132    /// The returned [`SoundInfo`] structure has an unbounded lifetime as it is hard to represent. You MUST constrain its lifetime as quickly as possible.
133    pub unsafe fn get_sound_info<'a>(&self, key: &Utf8CStr) -> Result<SoundInfo<'a>> {
134        let mut sound_info = MaybeUninit::zeroed();
135        unsafe {
136            FMOD_Studio_System_GetSoundInfo(
137                self.inner.as_ptr(),
138                key.as_ptr(),
139                sound_info.as_mut_ptr(),
140            )
141            .to_result()?;
142
143            let sound_info = SoundInfo::from_ffi(sound_info.assume_init());
144            Ok(sound_info)
145        }
146    }
147}