Creating a Wwise source control plug-in DLL requires the following steps:
|
Note: A DLL can contain more than one plug-in. For more information, refer to Establishing Exported Functions. |
When you begin a new project, you must create the project and establish the exported functions to be used in the project.
You should also familiarize yourself with the source control interfaces you will be using in your project.
To create a project using Visual Studio, do the following:
The project is now created and configured to use the Wwise Source Control SDK. The next thing to do is to create the functions that Wwise will use to manage your plug-in DLL.
|
Tip: Strictly speaking, you do not have to create an MFC DLL project. However, this does facilitate certain string and dialog manipulations. If you choose not to use an MFC DLL, make sure to include the oleauto.h header in the stdafx.h file to be able to use the SysAllocString function. |
Each plug-in DLL must export three functions:
Prototypes of these exported functions can be found in the following type definitions:
Here is an example of the exported functions for a plug-in DLL containing two plug-ins:
#include "AK/Wwise/SourceControl/ISourceControl.h" #include "SamplePlugin.h" namespace { // FirstSamplePlugin ID = {BD47DF98-1700-4542-A33F-E44705C25AF0} static const GUID s_guidFirstSamplePluginID = { 0xbd47df98, 0x1700, 0x4542, { 0xa3, 0x3f, 0xe4, 0x47, 0x5, 0xc2, 0x5a, 0xf0 } }; // SecondSamplePlugin ID = {57168691-2354-4166-82BF-DD07A36C16C6} static const GUID s_guidSecondSamplePluginID = { 0x57168691, 0x2354, 0x4166, { 0x82, 0xbf, 0xdd, 0x7, 0xa3, 0x6c, 0x16, 0xc6 } }; } void __stdcall AkSourceControlGetPluginIDList ( AK::Wwise::ISourceControl::PluginIDList& out_rPluginIDList ) { out_rPluginIDList.AddTail( s_guidFirstSamplePluginID ); out_rPluginIDList.AddTail( s_guidSecondSamplePluginID ); } void __stdcall AkSourceControlGetPluginInfo ( const GUID& in_rguidPluginID, AK::Wwise::ISourceControl::PluginInfo& out_rPluginInfo ) { if ( in_rguidPluginID == s_guidFirstSamplePluginID ) { FirstSamplePlugin::GetPluginInfo( out_rPluginInfo ); } else if ( in_rguidPluginID == s_guidSecondSamplePluginID ) { SecondSamplePlugin::GetPluginInfo( out_rPluginInfo ); } } AK::Wwise::ISourceControl* __stdcall AkSourceControlCreatePlugin ( const GUID& in_rguidPluginID ) { AK::Wwise::ISourceControl* pSourceControl = NULL; if ( in_rguidPluginID == s_guidFirstSamplePluginID ) { pSourceControl = new FirstSamplePlugin(); } else if ( in_rguidPluginID == s_guidSecondSamplePluginID ) { pSourceControl = new SecondSamplePlugin(); } return pSourceControl; }
|
Warning: You must change the plug-in GUID value to avoid ID conflicts with other plug-ins. |
When you create a project with Visual Studio, you need to export these functions by adding the function names to the .def file of the project. If no module definition file exists, you must create one.
To create a module definition file, follow these steps:
A typical module definition file looks like this:
LIBRARY "SamplePlugin"
EXPORTS
AkSourceControlGetPluginIDList
AkSourceControlGetPluginInfo
AkSourceControlCreatePlugin
Each Wwise source control plug-in must contain certain interfaces so that it may be integrated properly. These are summarized below, and described in detail later in this documentation.
Your plug-in must implement this interface to perform source control operations.
For more information about this interface, refer to Building the Source Control Plug-in Interface.
This interface is implemented by Wwise and is given to the plug-in at its creation. It exposes some useful utility functions to the plug-in.
For more information about this interface, refer to Using the Source Control Utilities Interface.
This interface is implemented by Wwise and is given to the plug-in via the ISourceControlUtilities class. It exposes functions to manage a simple progress dialog.
For more information about this interface, refer to Implementing the Source Control Operation Progress Interface.
This is the interface that the plug-in must implement to create dialogs that have the Wwise UI look and feel.
For more information about this interface, refer to Defining the Source Control Plug-in Dialog.
When you implement the methods of AK::Wwise::ISourceControl, you define the behavior of your plug-in in response to various situations in Wwise. The methods allow the plug-in to react to the following situations:
Some of these situations are covered in the following sections, but you can refer directly to the AK::Wwise::ISourceControl reference for a complete description of the interface and the functions you need to implement.
|
Tip: Many methods in this interface have the AK::Wwise::ISourceControl::OperationResult enumeration as return type. It is important to note that the OperationResult_Failed result must be used only when the operation fails globally; that is, when you don't want Wwise to consider data that is returned by the plug-in. Such failures include the following:
|
You must create a class derived from AK::Wwise::ISourceControl to implement all methods of this interface. This class manages everything related to UI and source control operations for your plug-in. The context in which these methods are called is indicated in the comments.
#include <AK/Wwise/ISourceControl.h> class SamplePlugin : public AK::Wwise::ISourceControl { public: SamplePlugin(); virtual ~SamplePlugin(); // ISourceControl implementation virtual void Init(AK::Wwise::ISourceControlUtilities* in_pUtilities ); // Initializing and Terminating the // Plug-in Instance virtual void Term(); // Initializing and Terminating the Plug-in Instance virtual void Destroy(); // Destroying the Plug-in Instance virtual bool ShowConfigDlg(); // Plug-in configuration virtual void GetOperationList( OperationMenuType in_menuType, const StringList& in_rFilenameList, OperationList& out_rOperationList ); // Contextual Menu virtual DWORD GetOperationEffect( DWORD in_dwOperationID ); // Wwise needs to know the effect of an operation virtual LPCWSTR GetOperationName( DWORD in_dwOperationID ); // Get operation name virtual AK::Wwise::ISourceControlUtilities::OperationResult GetFileStatus( const StringList& in_rFilenameList, FilenameToStatusMap& out_rFileStatusMap ); // File Manager Dialog virtual AK::Wwise::ISourceControlUtilities::OperationResult GetFileStatusIcons( const StringList& in_rFilenameList, FilenameToIconMap& out_rFileIconsMap ); // Project Explorer Icons Refresh virtual AK::Wwise::ISourceControlUtilities::OperationResult GetMissingFilesInDirectories( const StringList& in_rDirectoryList, StringList& out_rFilenameList ); // File Manager Dialog virtual void DoOperation( DWORD in_dwOperationID, const StringList& in_rFilenameList ); // Execution of a // Source Control Operation virtual AK::Wwise::ISourceControlUtilities::OperationResult PreCreateOrModify( const StringList& in_rFilenameList, bool& out_rContinue ); // Creation or Modification of Files in Wwise virtual AK::Wwise::ISourceControlUtilities::OperationResult PostCreateOrModify( const StringList& in_rFilenameList, bool& out_rContinue ); // Creation or Modification of Files in Wwise // A static method to get the plug-in information class, refer to Source Control Plug-in Information Class // for more information about this method. static void GetPluginInfo( PluginInfo& out_rPluginInfo ); private: // Members AK::Wwise::ISourceControlUtilities* m_pSourceControlUtilities; };
|
Caution: The string parameters and results exchanged between Wwise and the source control plug-in must be in unicode. |
When Wwise requires information about your plug-in, it calls the AkSourceControlGetPluginInfo function exported from your DLL. (For more information, refer to Establishing Exported Functions. ) The AK::Wwise::ISourceControl::PluginInfo class is composed of the following data:
|
Tip: A simple way to obtain the plug-in information is to make the AkSourceControlGetPluginInfo (Establishing Exported Functions) call a static method created inside your implementation of the AK::Wwise::ISourceControl interface. A simple implementation of this static method is: void SamplePlugin::GetPluginInfo( PluginInfo& out_rPluginInfo ) { // Plug-in name and version out_rPluginInfo.m_bstrName = ::SysAllocString( L"Sample Source Control Plug-in" ); out_rPluginInfo.m_uiVersion = 1; // Function availability out_rPluginInfo.m_bShowConfigDlgAvailable = false; out_rPluginInfo.m_dwUpdateCommandID = AK::Wwise::SourceControlConstant::s_dwInvalidOperationID;// Replace with your ID out_rPluginInfo.m_dwCommitCommandID = AK::Wwise::SourceControlConstant::s_dwInvalidOperationID;// Replace with your ID out_rPluginInfo.m_bStatusIconAvailable = false; } |
|
Warning: The plug-in name and the Update All operation name must be allocated using the SysAllocString function, because Wwise is responsible for deleting this memory. |
When the plug-in instance is created, Wwise calls the AK::Wwise::ISourceControl::Init( ISourceControlUtilities* in_pUtilities ) method. The parameter of this function is a pointer to Wwise's implementation of the AK::Wwise::ISourceControlUtilities interface. You might want to copy this pointer to a member of your plug-in class to be able to create dialogs, show a progress dialog, display message boxes, or load and save plug-in configuration. For more information on this topic, refer to Using the Source Control Utilities Interface.
A typical implementation of AK::Wwise::ISourceControl::Init() is:
void SamplePlugin::Init( ISourceControlUtilities* in_pUtilities ) { m_pSourceControlUtilities = in_pUtilities; // Load the plug-in configuration from the registry }
Just before the plug-in instance is destroyed, Wwise calls the AK::Wwise::ISourceControl::Term() method.
A typical implementation of AK::Wwise::ISourceControl::Term() is:
void SamplePlugin::Term() { // Save the plug-in configuration to the registry m_pSourceControlUtilities = NULL; }
For more information about loading/saving plug-in configuration to the registry, refer to Source Control Plug-in Sample Code.
For more information about when these functions are called, refer to Destroying the Plug-in Instance.
When Wwise needs to create an instance of your source control plug-in, it calls the AkSourceControlCreatePlugin() function in your DLL (Establishing Exported Functions) to create the new instance. This function returns an interface to your source control plug-in. When the plug-in instance is no longer needed, Wwise calls the AK::Wwise::ISourceControl::Destroy() method on that particular instance. This method releases any memory or other resources the object consumes, and then deletes the object itself.
If the instance was created with the operator New, a typical implementation of AK::Wwise::ISourceControl::Destroy() would be:
void SamplePlugin::Destroy() { delete this; }
An instance of the plug-in is created in the following situations:
The instance of the plug-in is destroyed in the following situations:
This interface is given to the plug-in when the plug-in instance is initialized (see Initializing and Terminating the Plug-in Instance). Its functions help the plug-in create dialogs, display message boxes, show a progress dialog, and load and save the configuration, all with the Wwise UI look and feel.
This interface exposes the following methods:
When performing source control operations, it can be useful to display a progress dialog with progress feedback messages. This can be done by calling the AK::Wwise::ISourceControlUtilities::GetProgressDialog() method. This method returns an AK::Wwise::ISourceControlOperationProgress interface. For more information on this interface, refer to Implementing the Source Control Operation Progress Interface.
A simple way to display message boxes with the Wwise UI look and feel is to call the AK::Wwise::ISourceControlUtilities::MessageBox() method. Use it the same way as a standard MessageBox Windows function call. You should use this method rather than the standard MessageBox calls to give your plug-in the Wwise UI look and feel.
To create dialogs that have the Wwise UI look and feel, you have to call the AK::Wwise::ISourceControlUtilities::CreateModalCustomDialog( ISourceControlDialogBase* in_pDialog ) method. This method works in the same way as the CDialog::DoModal() method except that it accepts an AK::Wwise::ISourceControlDialogBase interface as input. For more information on this, refer to Defining the Source Control Plug-in Dialog.
AK::Wwise::ISourceControlUtilities offers a simple way to save or load the plug-in configuration in the registry. By calling the AK::Wwise::ISourceControlUtilities::GetRegistryPath() method, you obtain the path of a registry folder that is different for each project and each plug-in. To load or save the configuration, you should create a subfolder for the current version of the plug-in and create all plug-in keys there. You might want to load the configuration in the AK::Wwise::ISourceControl::Init() method and save the configuration in the AK::Wwise::ISourceControl::Term() method.
|
Warning: You must use the HKEY_CURRENT_USER registry key to access this path. The project registry folder is created using this key and the source control plug-in configuration must be user-independent. |
The AK::Wwise::ISourceControlOperationProgress interface's implementation can be accessed via the AK::Wwise::ISourceControlUtilities interface given to the plug-in upon initialization. The former interface exposes these methods:
To create and display the progress dialog, use the AK::Wwise::ISourceControlOperationProgress::ShowProgress() non-blocking method. To add a message to the log message list, use the AK::Wwise::ISourceControlOperationProgress::AddLogMessage() method.
|
Warning: The progress dialog doesn't consider escape characters (such as '\n' or '\t'). The text must be added line by line and tabulation must be replaced with blank spaces. |
To enable the OK button, call the AK::Wwise::ISourceControlOperationProgress::OperationCompleted() method. The method will not return until the user presses the OK button. When the user does so, the dialog is closed and destroyed.
To know if the user has pressed the Cancel button, call the AK::Wwise::ISourceControlOperationProgress::IsCanceled() method. You can also cancel the operation by calling the AK::Wwise::ISourceControlOperationProgress::Cancel() method.
|
Note: Even if you programmatically cancel the dialog by calling the AK::Wwise::ISourceControlOperationProgress::Cancel() method, you still have to call AK::Wwise::ISourceControlOperationProgress::OperationCompleted() to close and destroy the dialog. |
To integrate your source control plug-in into Wwise users' workflows, you must implement certain functionality as follows.
In the Project Settings dialog, the Wwise user can configure the plug-in by clicking the Config… button. This button is enabled only if the AK::Wwise::ISourceControl::PluginInfo::m_bShowConfigDlgAvailable has been set to True. When you click on this button, Wwise calls the AK::Wwise::ISourceControl::ShowConfigDlg() method. The return value of this function is a Boolean value. The meaning of the value is as follows:
A typical implementation of this method is:
bool SamplePlugin::ShowConfigDlg() { DlgConfiguration configurationDialog(); // return True if the user presses 'OK' return m_pSourceControlUtilities->CreateModalCustomDialog( &configurationDialog ) == IDOK; }
In this code sample, the DlgConfiguration class is an implementation of the AK::Wwise::ISourceControlDialogBase interface. For more information, refer to the Defining the Source Control Plug-in Dialog.
When the File Manager is refreshed, two methods are called:
When the file list is populated, Wwise searches for files that are on the disk. On some source control systems, however, files are removed from the disk when they are deleted. Despite this, these files must still be identified to confirm the delete operation on the server. To retrieve the list of files that are in this state, Wwise calls the AK::Wwise::ISourceControl::GetMissingFilesInDirectories() method. The first parameter is the list of directories in which Wwise will look for such missing files, while the second parameter is a list of strings that will be overwritten with the names of the missing files.
|
Warning: The plug-in must not include files located in subdirectories of the given directories. |
After Wwise has obtained the complete file list, the Status and Owner(s) columns must be refreshed. To do this, Wwise calls the AK::Wwise::ISourceControl::GetFileStatus() method. For each file, the plug-in needs to display the corresponding status and owner of the file. Wwise obtains the status of the files listed in the function's first parameter. The second parameter is the resulting map containing the text to be displayed in the Status and Owner(s) columns.
|
Warning: The memory of the string members of AK::Wwise::ISourceControl::FilenameToStatusMapItem must be allocated using the SysAllocString function because Wwise is responsible for deleting this memory. Two strings must not share the same memory space because Wwise will try to destroy these two strings separately. |
When Wwise displays a contextual menu that includes source control operations, it needs the list of all operations that are available in a specific context. To get this list, Wwise calls the AK::Wwise::ISourceControl::GetOperationList( OperationMenuType in_menuType, const StringList& in_rFilenameList, OperationList& out_rOperationList ) method. The first parameter is the context in which the operation list will be displayed. Depending on this context, some plug-ins could restrict the user to specific operations. The second parameter is the list of file names that the user has selected. This can be used to enable or disable some operations depending on the status of the files. The third parameter is the list of operations available in the current context. This list of operations must be filled by the plug-in. The information about the operations contained in this list is used to fill the contextual menu and to call back the plug-in with the ID of the operation. There are no restrictions on either IDs.
Wwise calls the virtual LPCWSTR GetOperationName( DWORD in_dwOperationID ) method to obtain the operation name for displaying in menus and dialogs.
|
Warning: Wwise will not delete the memory occupied by the operation name's string. We therefore recommend you create static strings that are created and destroyed at the same time as the plug-in instance. |
When Wwise users choose an operation from a contextual menu, Wwise first calls the AK::Wwise::ISourceControl::GetOperationEffect( DWORD in_dwOperationID ) method. The parameter is the operation ID corresponding to the operation. The implementation of this method returns a mask made of one or many values of the AK::Wwise::ISourceControl::OperationEffect enumeration. Wwise uses the return value to learn if it must ask users to save their projects before continuing with the source control operation. Operations such as update, rename, revert, and delete modify the contents of the local files. Operations such as commit and check-in modify the contents of the file on the server.
|
Warning: Not returning information about the effect of an operation on a file may lead to frustration for Wwise users. When a file changes on the hard drive during a source control operation, Wwise detects the change and asks the user to reload the project. If users had pending changes (that is, the project is dirty) and are asked to reload, their changes are lost. If users revert the changes to a file that is dirty, choose not to reload the project, and then save the changes, they may overwrite the newly-updated file. AK::Wwise::ISourceControl::GetOperationEffect uses the information returned to avoid such situations by forcing users to save. |
After successfully calling the first method, Wwise calls the AK::Wwise::ISourceControl::DoOperation( DWORD in_dwOperationID, const StringList& in_rFilenameList ) method. The first parameter is the operation ID corresponding to the operation. The second parameter is the list of selected files. The implementation of this method uses the AK::Wwise::ISourceControlOperationProgress interface to display a progress dialog. For more information, refer to Implementing the Source Control Operation Progress Interface.
Wwise needs to refresh icons in the following situations:
Using a pattern similar to that of the AK::Wwise::ISourceControl::GetFileStatus() method, AK::Wwise::ISourceControl::GetFileStatusIcons( const StringList& in_rFilenameList, FilenameToIconMap& out_rFileIconsMap ) must return a map containing icons and tool tip texts for files in the list. The first parameter is the list of names of the file for which Wwise needs to have icon maps. The second parameter is the resulting map containing the following components:
|
Warning: The memory of the string members of AK::Wwise::ISourceControl::FilenameToIconMapItem must be allocated using the SysAllocString function because Wwise is responsible for deleting this memory. Two strings must not share the same memory space because Wwise will try to destroy these two strings separately. |
The icons contained in the map can be any size, but they will be resized to a format of 15x15 pixels. Functions related to icons are only called if AK::Wwise::ISourceControl::PluginInfo::m_bStatusIconAvailable is set to True.
|
Tip: A set of icons you can use is installed with this SDK. |
File creation and modification happens when a Wwise user does the following:
When any of these situations arises, Wwise calls the AK::Wwise::ISourceControl::PreCreateOrModify( const StringList& in_rFilenameList, CreateOrModifyOperation in_eOperation, bool& out_rContinue ) and AK::Wwise::ISourceControl::PostCreateOrModify( const StringList& in_rFilenameList, CreateOrModifyOperation in_eOperation, bool& out_rContinue ) methods. The first parameter is the list of names of the files that are to be created or modified. The second parameter is a flag defining the operation that will be performed. Since you can perform either operation on any of the files listed, you must use the bitwise AND operator to compare the second parameter with a predefined flag. For example, to know if some files were created, do the following:
if ( in_eOperation & CreateOrModifyOperation_Create ) { // Do operations }
The third parameter of the AK::Wwise::ISourceControl::PreCreateOrModify() and AK::Wwise::ISourceControl::PostCreateOrModify() functions is set by the plug-in to inform Wwise to continue or stop the current operation. This parameter is mostly used by calls to the AK::Wwise::ISourceControl::PreCreateOrModify() method.
|
Tip: We recommend that these two methods be used to perform operations that are specific to your source control system. For example, you could use the AK::Wwise::ISourceControl::PreCreateOrModify() method to perform Perforce's checkout operation, or the AK::Wwise::ISourceControl::PostCreateOrModify() method to add files which are not on the server yet. The first method is always called before file creation or modification, and the second one is always called after such an operation. This feature can be used to implement a layer of security in your plug-in. |
If your DLL contains dialogs, you'll want them to have the Wwise UI look and feel. To do that, you need to follow the following steps:
You can create both standard Windows controls and controls specific to Wwise.
You can add regular controls such as static controls, edit controls, check boxes, push buttons, radio buttons, and group controls directly in the Microsoft Development Environment Dialog Editor using the corresponding tools in the Dialog Editor section of the Toolbox. These controls will be automatically subclassed by Wwise so they have the same look as similar controls elsewhere in the application.
|
Note: The dropdown/combobox control is not automatically subclassed. If you need a dropdown control in your dialog, use the Combo custom control instead. Refer to Wwise Controls for more information. |
To integrate Wwise dialog controls (such as Captions and ComboBox) into your dialog, use static text control placeholders with a specially-coded caption text. This text needs to have the following form:
Class=[Classname];
where Classname can be one of the following:
|
Tip: To make it easier to view the layout of the dialog controls, set Border to True in the properties of the static placeholders in the Microsoft Development Environment Dialog Editor. |
Before Wwise can display your dialog, you must implement the AK::Wwise::ISourceControlDialogBase interface. This interface exposes the following methods:
Wwise needs to know in which context the resources can be found. Before creating the dialog, Wwise calls the AK::Wwise::ISourceControlDialogBase::GetResourceHandle() method. A typical implementation for this method is:
HINSTANCE DlgSimple::GetResourceHandle() const
{
AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
return ::AfxGetResourceHandle();
}
Wwise also needs the ID of the dialog in the resource to create the dialog. To retrieve it, Wwise calls the AK::Wwise::ISourceControlDialogBase::GetDialog() method. A typical implementation of this method is:
void DlgSimple::GetDialog( UINT & out_uiDialogID ) const { out_uiDialogID = IDD_SIMPLEDIALOGID; }
To know if the "?" should be shown on the dialog title bar, Wwise calls AK::Wwise::ISourceControlDialogBase::HasHelp(). The plug-in must return True if there is a Help section associated with the dialog. If so, the "?" icon appears.
bool DlgSimple::HasHelp() const { return true; }
When the Wwise user clicks the "?" button of the dialog, Wwise calls the AK::Wwise::ISourceControlDialogBase::Help() method. The plug-in must return True when it manages the Help request and false when nothing is done. An implementation example of this method is:
bool DlgSimple::Help( HWND in_hWnd ) const { AFX_MANAGE_STATE( ::AfxGetStaticModuleState() ) ; // Note: Do NOT call AfxGetApp()->HtmlHelp() as it will launch the Help // window from the wrong parent window which will make floating views // behave unexpectedly. ::HtmlHelp( NULL, AfxGetApp()->m_pszHelpFilePath, HH_HELP_CONTEXT, ONLINEHELP::Simple_Dialog ); return true; }
|
Caution: The Help() method should NOT call AfxGetApp()->HtmlHelp(). It will launch the Help window from the wrong parent window which will make floating views behave unexpectedly. Instead, use HtmlHelp() with a NULL window handle, as shown in the example above. |
The dialog cannot use the MFC methods to manage Windows messages. Instead, each time the dialog receives a Windows message, the AK::Wwise::ISourceControlDialogBase::WindowProc() is called. An implementation example of this method is:
bool DlgConfiguration::WindowProc( HWND in_hWnd, UINT in_message, WPARAM in_wParam, LPARAM in_lParam, LRESULT & out_lResult ) { if ( in_message == WM_INITDIALOG ) { // Initialize the dialog } // For example: Catch window command actions (only for the main dialog) to enable/disable controls else if ( in_message == WM_COMMAND ) { // Notification code switch ( HIWORD( in_wParam ) ) { case BN_CLICKED: // Check which button was clicked switch ( LOWORD( in_wParam ) ) { case IDOK: // The user pressed the 'Ok' button break; } } // End switch hi word (notification code) } // End command window event // Return False to let the parent window deal with the message. Return True // for messages you don't want the parent window to handle. return false; }
The meaning of this method's return value is as follows:
To manually close the dialog, you need to use the Windows PostMessage() function. A typical call to this function looks like this:
PostMessage( in_hWnd, WM_CLOSE, 0, 0 );
To display the dialog, an instance of the corresponding AK::Wwise::ISourceControlDialogBase implementation must be created. Using the AK::Wwise::ISourceControlUtilities::CreateModalCustomDialog() method, the dialog will be displayed like a modal dialog. Here is an example that shows how to create and display the dialog:
bool SamplePlugin::ShowConfigDlg() { DlgConfiguration configurationDialog( m_pSourceControlUtilities ); // return true if the user presses 'OK' return m_pSourceControlUtilities->CreateModalCustomDialog( &configurationDialog ) == IDOK; }
Questions? Problems? Need more info? Contact us, and we can help!
Visit our Support pageRegister your project and we'll help you get started with no strings attached!
Get started with Wwise