/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see .
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../../game/game.h"
#include "../../sys/win32/win_local.h"
#include "../../sys/win32/rc/common_resource.h"
#include "../../sys/win32/rc/SoundEditor_resource.h"
#include "../comafx/DialogName.h"
#include "../../sys/win32/rc/DeclEditor_resource.h"
#include "../decl/DialogDeclEditor.h"
#include "DialogSound.h"
#include "DialogSoundGroup.h"
#ifdef ID_DEBUG_MEMORY
#undef new
#undef DEBUG_NEW
#define DEBUG_NEW new
#endif
extern HTREEITEM FindTreeItem(CTreeCtrl *tree, HTREEITEM root, const char *text, HTREEITEM forceParent);
/////////////////////////////////////////////////////////////////////////////
// CDialogSound dialog
CDialogSound *g_SoundDialog = NULL;
CDialogSound::CDialogSound(CWnd* pParent /*=NULL*/)
: CDialog(CDialogSound::IDD, pParent)
{
//{{AFX_DATA_INIT(CDialogSound)
strName = _T("");
fVolume = 0.0f;
fMax = 0.0f;
fMin = 0.0f;
strShader = _T("");
bPlay = TRUE;
bTriggered = FALSE;
bOmni = FALSE;
strGroup = _T("");
bGroupOnly = FALSE;
bOcclusion = FALSE;
leadThrough = 0.0f;
plain = FALSE;
inUseTree = NULL;
random = 0.0f;
wait = 0.0f;
shakes = 0.0f;
looping = TRUE;
unclamped = FALSE;
//}}AFX_DATA_INIT
}
void CDialogSound::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDialogSound)
DDX_Control(pDX, IDC_COMBO_SPEAKERS, comboSpeakers);
DDX_Control(pDX, IDC_COMBO_GROUPS, comboGroups);
DDX_Control(pDX, IDC_EDIT_VOLUME, editVolume);
DDX_Control(pDX, IDC_TREE_SOUNDS, treeSounds);
DDX_Text(pDX, IDC_EDIT_SOUND_NAME, strName);
DDX_Text(pDX, IDC_EDIT_VOLUME, fVolume);
DDX_Text(pDX, IDC_EDIT_RANDOM, random);
DDX_Text(pDX, IDC_EDIT_WAIT, wait);
DDX_Text(pDX, IDC_EDIT_MAXDIST, fMax);
DDX_Text(pDX, IDC_EDIT_MINDIST, fMin);
DDX_Text(pDX, IDC_EDIT_SHADER, strShader);
DDX_Check(pDX, IDC_CHECK_PLAY, bPlay);
DDX_Check(pDX, IDC_CHECKP_TRIGGERED, bTriggered);
DDX_Check(pDX, IDC_CHECK_OMNI, bOmni);
DDX_Text(pDX, IDC_EDIT_GROUP, strGroup);
DDX_Check(pDX, IDC_CHECK_GROUPONLY, bGroupOnly);
DDX_Check(pDX, IDC_CHECK_OCCLUSION, bOcclusion);
DDX_Text(pDX, IDC_EDIT_LEADTHROUGH, leadThrough);
DDX_Check(pDX, IDC_CHECK_PLAIN, plain);
DDX_Check(pDX, IDC_CHECK_LOOPING, looping);
DDX_Check(pDX, IDC_CHECK_UNCLAMPED, unclamped);
DDX_Text(pDX, IDC_EDIT_SHAKES, shakes);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDialogSound, CDialog)
//{{AFX_MSG_MAP(CDialogSound)
ON_BN_CLICKED(IDC_BTN_SAVEMAP, OnBtnSavemap)
ON_BN_CLICKED(IDC_BTN_SWITCHTOGAME, OnBtnSwitchtogame)
ON_BN_CLICKED(IDC_BTN_APPLY_SOUND, OnBtnApply)
ON_EN_CHANGE(IDC_EDIT_VOLUME, OnChangeEditVolume)
ON_BN_CLICKED(IDC_BTN_REFRESH, OnBtnRefresh)
ON_BN_CLICKED(IDC_BTN_PLAYSOUND, OnBtnPlaysound)
ON_NOTIFY(NM_DBLCLK, IDC_TREE_SOUNDS, OnDblclkTreeSounds)
ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_SOUNDS, OnSelchangedTreeSounds)
ON_BN_CLICKED(IDC_CHECK_PLAY, OnCheckPlay)
ON_BN_CLICKED(IDC_BTN_EDIT_SOUND, OnBtnEdit)
ON_BN_CLICKED(IDC_BTN_DROP, OnBtnDrop)
ON_BN_CLICKED(IDC_BTN_GROUP, OnBtnGroup)
ON_BN_CLICKED(IDC_BTN_SAVEMAPAS, OnBtnSavemapas)
ON_BN_CLICKED(IDC_BTN_YUP, OnBtnYup)
ON_BN_CLICKED(IDC_BTN_YDN, OnBtnYdn)
ON_BN_CLICKED(IDC_BTN_XDN, OnBtnXdn)
ON_BN_CLICKED(IDC_BTN_XUP, OnBtnXup)
ON_BN_CLICKED(IDC_BTN_ZUP, OnBtnZup)
ON_BN_CLICKED(IDC_BTN_ZDN, OnBtnZdn)
ON_BN_CLICKED(IDC_BTN_TRIGGER, OnBtnTrigger)
ON_WM_HSCROLL()
ON_BN_CLICKED(IDC_CHECK_GROUPONLY, OnCheckGrouponly)
ON_CBN_SELCHANGE(IDC_COMBO_GROUPS, OnSelchangeComboGroups)
ON_CBN_SELCHANGE(IDC_COMBO_SPEAKERS, OnSelchangeComboSpeakers)
ON_BN_CLICKED(IDC_BTN_DOWN, OnBtnDown)
ON_BN_CLICKED(IDC_BTN_UP, OnBtnUp)
ON_BN_CLICKED(IDC_BTN_REFRESHSPEAKERS, OnBtnRefreshspeakers)
ON_BN_CLICKED(IDC_BTN_REFRESHWAVE, OnBtnRefreshwave)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDialogSound message handlers
void SoundEditorInit( const idDict *spawnArgs ) {
if ( renderSystem->IsFullScreen() ) {
common->Printf( "Cannot run the sound editor in fullscreen mode.\n"
"Set r_fullscreen to 0 and vid_restart.\n" );
return;
}
if ( g_SoundDialog == NULL ) {
InitAfx();
g_SoundDialog = new CDialogSound();
}
if ( g_SoundDialog->GetSafeHwnd() == NULL ) {
g_SoundDialog->Create(IDD_DIALOG_SOUND);
/*
// FIXME: restore position
CRect rct;
g_SoundDialog->SetWindowPos( NULL, rct.left, rct.top, 0,0, SWP_NOSIZE );
*/
}
idKeyInput::ClearStates();
g_SoundDialog->ShowWindow( SW_SHOW );
g_SoundDialog->SetFocus();
if ( spawnArgs ) {
const char *name = spawnArgs->GetString( "name" );
const idDict *dict = gameEdit->MapGetEntityDict( name );
g_SoundDialog->Set( dict );
}
}
void SoundEditorRun( void ) {
#if _MSC_VER >= 1300
MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!!
#else
MSG *msg = &m_msgCur;
#endif
while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) {
// pump message
if ( !AfxGetApp()->PumpMessage() ) {
}
}
}
void SoundEditorShutdown( void ) {
delete g_SoundDialog;
g_SoundDialog = NULL;
}
void CDialogSound::OnActivate( UINT nState, CWnd *pWndOther, BOOL bMinimized ) {
CDialog::OnActivate( nState, pWndOther, bMinimized );
if ( nState != WA_INACTIVE ) {
}
}
void CDialogSound::OnMove( int x, int y ) {
if ( GetSafeHwnd() ) {
CRect rct;
GetWindowRect( rct );
// FIXME: save position
}
CDialog::OnMove( x, y );
}
void CDialogSound::OnDestroy() {
com_editors &= ~EDITOR_SOUND;
return CDialog::OnDestroy();
}
void CDialogSound::Set( const idDict *source ) {
if ( source == NULL ) {
return;
}
fVolume = source->GetFloat( "s_volume", "0" );
fMin = source->GetFloat( "s_mindistance", "1" );
fMax = source->GetFloat( "s_maxdistance", "10" );
leadThrough = source->GetFloat( "s_leadthrough", "0.1" );
plain = source->GetBool( "s_plain" );
strShader = source->GetString( "s_shader" );
strGroup = source->GetString( "soundgroup" );
bOmni = source->GetInt( "s_omni", "-1" );
bOcclusion = source->GetBool( "s_occlusion", "0" );
bTriggered = source->GetInt( "s_waitfortrigger", "-1" );
random = source->GetFloat( "random" );
wait = source->GetFloat( "wait" );
strName = source->GetString("name");
looping = source->GetBool( "s_looping" );
unclamped = source->GetBool( "s_unclamped" );
shakes = source->GetFloat( "s_shakes" );
if (comboSpeakers.SelectString(-1, strName) == CB_ERR) {
comboSpeakers.SetCurSel(-1);
}
if (comboGroups.SelectString(-1, strGroup) == CB_ERR) {
comboGroups.SetCurSel(-1);
}
UpdateData(FALSE);
}
void CDialogSound::Get( idDict *source ) {
if ( source == NULL ) {
return;
}
UpdateData( TRUE );
float f = source->GetFloat( "s_volume" );
source->SetFloat( "s_volume", f );
source->SetFloat( "s_mindistance", fMin );
source->SetFloat( "s_maxdistance", fMax );
source->Set( "s_shader", strShader );
source->SetInt( "s_omni", bOmni );
source->SetBool( "s_occlusion", ( bOcclusion != FALSE ) );
source->SetInt("s_waitfortrigger", bTriggered );
source->Set( "soundgroup", strGroup );
source->Set( "name", strName );
source->SetFloat( "s_leadthrough", leadThrough );
source->SetBool( "s_plain", ( plain != FALSE ) );
source->SetFloat( "wait", wait );
source->SetFloat( "random", random );
source->SetBool( "s_looping", looping == TRUE );
source->SetBool( "s_unclamped", unclamped == TRUE );
source->SetFloat( "s_shakes", shakes );
}
void CDialogSound::OnBtnSavemap()
{
OnBtnApply();
gameEdit->MapSave();
}
void CDialogSound::OnBtnSwitchtogame()
{
::SetFocus(win32.hWnd);
}
void CDialogSound::SetVolume( float vol ) {
idList list;
list.SetNum( 128 );
int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() );
list.SetNum( count );
if ( count ) {
// we might be in either the game or the editor
idSoundWorld *sw = soundSystem->GetPlayingSoundWorld();
if ( sw ) {
sw->PlayShaderDirectly( "" );
}
for (int i = 0; i < count; i++) {
const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] );
if ( dict == NULL ) {
continue;
}
const char *name = dict->GetString( "name" );
const idDict *dict2 = gameEdit->MapGetEntityDict( name );
if ( dict2 ) {
gameEdit->MapSetEntityKeyVal( name, "s_volume", va( "%f", vol ) );
gameEdit->MapSetEntityKeyVal( name, "s_justVolume", "1" );
gameEdit->EntityUpdateChangeableSpawnArgs( list[i], dict2 );
fVolume = vol;
UpdateData( FALSE );
}
}
}
}
void CDialogSound::ApplyChanges( bool volumeOnly, bool updateInUseTree ) {
idList list;
float vol;
vol = fVolume;
list.SetNum( 128 );
int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() );
list.SetNum( count );
if ( count ) {
// we might be in either the game or the editor
idSoundWorld *sw = soundSystem->GetPlayingSoundWorld();
if ( sw ) {
sw->PlayShaderDirectly( "" );
}
for (int i = 0; i < count; i++) {
const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] );
if ( dict == NULL ) {
continue;
}
const char *name = dict->GetString( "name" );
const idDict *dict2 = gameEdit->MapGetEntityDict( name );
if ( dict2 ) {
if ( volumeOnly ) {
float f = dict2->GetFloat( "s_volume" );
f += vol;
gameEdit->MapSetEntityKeyVal( name, "s_volume", va( "%f", f ) );
gameEdit->MapSetEntityKeyVal( name, "s_justVolume", "1" );
gameEdit->EntityUpdateChangeableSpawnArgs( list[i], dict2 );
fVolume = f;
UpdateData( FALSE );
} else {
idDict src;
src.SetFloat( "s_volume", dict2->GetFloat( "s_volume" ));
Get( &src );
src.SetBool( "s_justVolume", true );
gameEdit->MapCopyDictToEntity( name, &src );
gameEdit->EntityUpdateChangeableSpawnArgs( list[i], dict2 );
Set( dict2 );
}
}
}
}
AddGroups();
AddSpeakers();
if ( updateInUseTree ) {
AddInUseSounds();
}
}
void CDialogSound::OnBtnApply()
{
ApplyChanges();
}
void CDialogSound::OnChangeEditVolume()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialog::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
// TODO: Add your control notification handler code here
}
HTREEITEM CDialogSound::AddStrList(const char *root, const idStrList &list, int id) {
idStr out;
HTREEITEM base = treeSounds.InsertItem(root);
HTREEITEM item = base;
HTREEITEM add;
int count = list.Num();
idStr last, path, path2;
for (int i = 0; i < count; i++) {
idStr name = list[i];
// now break the name down convert to slashes
name.BackSlashesToSlashes();
name.Strip(' ');
int index;
int len = last.Length();
if (len == 0) {
index = name.Last('/');
if (index >= 0) {
name.Left(index, last);
}
}
else if (idStr::Icmpn(last, name, len) == 0 && name.Last('/') <= len) {
name.Right(name.Length() - len - 1, out);
add = treeSounds.InsertItem(out, item);
quickTree.Set(name, add);
treeSounds.SetItemData(add, id);
treeSounds.SetItemImage(add, 2, 2);
continue;
}
else {
last.Empty();
}
index = 0;
item = base;
path = "";
path2 = "";
while (index >= 0) {
index = name.Find('/');
if (index >= 0) {
HTREEITEM newItem = NULL;
HTREEITEM *check = NULL;
name.Left( index, out );
path += out;
if (quickTree.Get(path, &check)) {
newItem = *check;
}
//HTREEITEM newItem = FindTreeItem(&treeSounds, item, name.Left(index, out), item);
if (newItem == NULL) {
newItem = treeSounds.InsertItem(out, item);
quickTree.Set(path, newItem);
treeSounds.SetItemData(newItem, WAVEDIR);
treeSounds.SetItemImage(newItem, 0, 1);
}
assert(newItem);
item = newItem;
name.Right( name.Length() - index - 1, out );
name = out;
path += "/";
}
else {
add = treeSounds.InsertItem(name, item);
treeSounds.SetItemData(add, id);
treeSounds.SetItemImage(add, 2, 2);
path = "";
}
}
}
return base;
}
void CDialogSound::AddSounds(bool rootItems) {
int i, j;
idStrList list(1024);
idStrList list2(1024);
HTREEITEM base = treeSounds.InsertItem("Sound Shaders");
for( i = 0; i < declManager->GetNumDecls( DECL_SOUND ) ; i++ ) {
const idSoundShader *poo = declManager->SoundByIndex(i, false);
list.AddUnique( poo->GetFileName() );
}
list.Sort();
for ( i = 0; i < list.Num(); i++ ) {
HTREEITEM child = treeSounds.InsertItem(list[i], base);
treeSounds.SetItemData(child, SOUNDPARENT);
treeSounds.SetItemImage(child, 0, 1);
list2.Clear();
for (j = 0; j < declManager->GetNumDecls( DECL_SOUND ); j++) {
const idSoundShader *poo = declManager->SoundByIndex(j, false);
if ( idStr::Icmp( list[i], poo->GetFileName() ) == 0 ) {
list2.Append( poo->GetName() );
}
}
list2.Sort();
for (j = 0; j < list2.Num(); j++) {
HTREEITEM child2 = treeSounds.InsertItem( list2[j], child );
treeSounds.SetItemData(child2, SOUNDS);
treeSounds.SetItemImage(child2, 2, 2);
}
}
idFileList *files;
files = fileSystem->ListFilesTree( "sound", ".wav|.ogg", true );
AddStrList( "Wave files", files->GetList(), WAVES );
fileSystem->FreeFileList( files );
}
void CDialogSound::AddGroups() {
comboGroups.ResetContent();
idStr work;
CWaitCursor cursor;
idList list;
list.SetNum( 1024 );
int count = gameEdit->MapGetUniqueMatchingKeyVals( "soundgroup", list.Ptr(), list.Num() );
for ( int i = 0; i < count; i++ ) {
comboGroups.AddString( list[i] );
}
}
void CDialogSound::AddInUseSounds() {
if ( inUseTree ) {
treeSounds.DeleteItem( inUseTree );
inUseTree = NULL;
}
inUseTree = treeSounds.InsertItem("Sounds in use");
idList< const char *> list;
list.SetNum( 512 );
int i, count = gameEdit->MapGetEntitiesMatchingClassWithString( "speaker", "", list.Ptr(), list.Num() );
idStrList list2;
for ( i = 0; i < count; i++ ) {
const idDict *dict = gameEdit->MapGetEntityDict( list[i] );
if ( dict ) {
const char *p = dict->GetString( "s_shader" );
if ( p && *p ) {
list2.AddUnique( p );
}
}
}
list2.Sort();
count = list2.Num();
for ( i = 0; i < count; i++ ) {
HTREEITEM child = treeSounds.InsertItem( list2[i], inUseTree );
treeSounds.SetItemData( child, INUSESOUNDS );
treeSounds.SetItemImage( child, 2, 2 );
}
}
void CDialogSound::AddSpeakers() {
UpdateData( TRUE );
comboSpeakers.ResetContent();
CWaitCursor cursor;
idList< const char *> list;
list.SetNum( 512 );
CString group( "" );
if (bGroupOnly && comboGroups.GetCurSel() >= 0) {
comboGroups.GetLBText( comboGroups.GetCurSel(), group );
}
int count = gameEdit->MapGetEntitiesMatchingClassWithString( "speaker", group, list.Ptr(), list.Num() );
for ( int i = 0; i < count; i++ ) {
comboSpeakers.AddString(list[i]);
}
}
BOOL CDialogSound::OnInitDialog()
{
CDialog::OnInitDialog();
// Indicate the sound dialog is opened
com_editors |= EDITOR_SOUND;
inUseTree = NULL;
AddSounds(true);
AddGroups();
AddSpeakers();
AddInUseSounds();
SetWaveSize();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CDialogSound::OnBtnRefresh()
{
CWaitCursor cursor;
treeSounds.DeleteAllItems();
quickTree.Clear();
declManager->Reload( false );
AddSounds(true);
}
void CDialogSound::OnBtnPlaysound()
{
if (playSound.GetLength()) {
// we might be in either the game or the editor
idSoundWorld *sw = soundSystem->GetPlayingSoundWorld();
if ( sw ) {
sw->PlayShaderDirectly(playSound);
}
}
}
void CDialogSound::OnDblclkTreeSounds(NMHDR* pNMHDR, LRESULT* pResult)
{
*pResult = 0;
CPoint pt;
GetCursorPos( &pt );
treeSounds.ScreenToClient( &pt );
HTREEITEM item = treeSounds.HitTest( pt );
if (item) {
DWORD dw = treeSounds.GetItemData( item );
if ( dw == SOUNDS || dw == INUSESOUNDS ) {
if ( !treeSounds.ItemHasChildren( item ) ) {
strShader = treeSounds.GetItemText( item );
UpdateData( FALSE );
ApplyChanges( false, ( dw == SOUNDS ) );
}
} else if ( dw == WAVES ) {
strShader = RebuildItemName( "Wave Files", item );
UpdateData( FALSE );
OnBtnApply();
}
}
*pResult = 0;
}
void CDialogSound::SetWaveSize( const char *p ) {
CWnd *wnd = GetDlgItem( IDC_STATIC_WAVESIZE );
if ( wnd ) {
wnd->SetWindowText( ( p && *p ) ? p : "unknown" );
}
}
void CDialogSound::OnSelchangedTreeSounds(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
HTREEITEM item = treeSounds.GetSelectedItem();
SetWaveSize();
if (item) {
DWORD dw = treeSounds.GetItemData(item);
if ( dw == SOUNDS || dw == INUSESOUNDS ) {
playSound = treeSounds.GetItemText(item);
if (bPlay){
OnBtnPlaysound();
}
} else if (dw == WAVES) {
playSound = RebuildItemName("Wave Files", item);
float size = fileSystem->ReadFile( playSound, NULL );
SetWaveSize( va( "%0.2f mb", size / ( 1024 * 1024) ) );
if (bPlay){
OnBtnPlaysound();
}
}
}
*pResult = 0;
}
void CDialogSound::OnCheckPlay()
{
UpdateData(TRUE);
}
void CDialogSound::OnBtnEdit()
{
const idDecl *decl = declManager->FindDeclWithoutParsing( DECL_SOUND, strShader, false );
if ( decl ) {
DialogDeclEditor *declEditor;
declEditor = new DialogDeclEditor;
declEditor->Create( IDD_DIALOG_DECLEDITOR, GetParent() );
declEditor->LoadDecl( const_cast( decl ) );
declEditor->ShowWindow( SW_SHOW );
declEditor->SetFocus();
}
}
void CDialogSound::OnBtnDrop()
{
idStr classname;
idStr key;
idStr value;
idVec3 org;
idDict args;
idAngles viewAngles;
gameEdit->PlayerGetViewAngles( viewAngles );
gameEdit->PlayerGetEyePosition( org );
org += idAngles( 0, viewAngles.yaw, 0 ).ToForward() * 80 + idVec3( 0, 0, 1 );
args.Set("origin", org.ToString());
args.Set("classname", "speaker");
args.Set("angle", va( "%f", viewAngles.yaw + 180 ));
args.Set("s_shader", strShader);
args.Set("s_looping", "1" );
args.Set("s_shakes", "0" );
idStr name = gameEdit->GetUniqueEntityName( "speaker" );
bool nameValid = false;
while (!nameValid) {
DialogName dlg("Name Speaker", this);
dlg.m_strName = name;
if (dlg.DoModal() == IDOK) {
idEntity *gameEnt = gameEdit->FindEntity(dlg.m_strName);
if (gameEnt) {
if (MessageBox("Please choose another name", "Duplicate Entity Name!", MB_OKCANCEL) == IDCANCEL) {
return;
}
} else {
nameValid = true;
name = dlg.m_strName;
}
}
}
args.Set("name", name.c_str());
idEntity *ent = NULL;
gameEdit->SpawnEntityDef( args, &ent );
if (ent) {
gameEdit->EntityUpdateChangeableSpawnArgs( ent, NULL );
gameEdit->ClearEntitySelection();
gameEdit->AddSelectedEntity( ent );
}
gameEdit->MapAddEntity( &args );
const idDict *dict = gameEdit->MapGetEntityDict( args.GetString( "name" ) );
Set( dict );
AddGroups();
AddSpeakers();
}
void CDialogSound::OnBtnGroup()
{
idList list;
list.SetNum( 128 );
int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() );
list.SetNum( count );
bool removed = false;
if (count) {
for (int i = 0; i < count; i++) {
const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] );
if ( dict == NULL ) {
continue;
}
const char *name = dict->GetString("name");
dict = gameEdit->MapGetEntityDict( name );
if ( dict ) {
if (MessageBox("Are you Sure?", "Delete Selected Speakers", MB_YESNO) == IDYES) {
gameEdit->MapRemoveEntity( name );
idEntity *gameEnt = gameEdit->FindEntity( name );
if ( gameEnt ) {
gameEdit->EntityStopSound( gameEnt );
gameEdit->EntityDelete( gameEnt );
removed = true;
}
}
}
}
}
if (removed) {
AddGroups();
AddSpeakers();
}
}
void CDialogSound::OnBtnSavemapas()
{
CFileDialog dlgSave(FALSE,"map",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"Map Files (*.map)|*.map||",AfxGetMainWnd());
if (dlgSave.DoModal() == IDOK) {
OnBtnApply();
idStr work;
work = fileSystem->OSPathToRelativePath( dlgSave.m_ofn.lpstrFile );
gameEdit->MapSave( work );
}
}
idStr CDialogSound::RebuildItemName(const char *root, HTREEITEM item) {
// have to build the name back up
idStr strParent;
HTREEITEM parent = treeSounds.GetParentItem(item);
idStr name = treeSounds.GetItemText(item);
while (true && parent) {
idStr test = treeSounds.GetItemText(parent);
if ( idStr::Icmp(test, root) == 0 ) {
break;
}
strParent = test;
strParent += "/";
strParent += name;
name = strParent;
parent = treeSounds.GetParentItem(parent);
if (parent == NULL) {
break;
}
}
return strParent;
}
void CDialogSound::UpdateSelectedOrigin( float x, float y, float z ) {
idList list;
idVec3 origin;
idVec3 vec(x, y, z);
list.SetNum( 128 );
int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() );
list.SetNum( count );
if ( count ) {
for ( int i = 0; i < count; i++ ) {
const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] );
if ( dict == NULL ) {
continue;
}
const char *name = dict->GetString( "name" );
gameEdit->EntityTranslate( list[i], vec );
gameEdit->EntityUpdateVisuals( list[i] );
gameEdit->MapEntityTranslate( name, vec );
}
}
}
void CDialogSound::OnBtnYup()
{
UpdateSelectedOrigin(0, 8, 0);
}
void CDialogSound::OnBtnYdn()
{
UpdateSelectedOrigin(0, -8, 0);
}
void CDialogSound::OnBtnXdn()
{
UpdateSelectedOrigin(-8, 0, 0);
}
void CDialogSound::OnBtnXup()
{
UpdateSelectedOrigin(8, 0, 0);
}
void CDialogSound::OnBtnZup()
{
UpdateSelectedOrigin(0, 0, 8);
}
void CDialogSound::OnBtnZdn()
{
UpdateSelectedOrigin(0, 0, -8);
}
void CDialogSound::OnBtnTrigger() {
gameEdit->TriggerSelected();
}
void CDialogSound::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {
}
void CDialogSound::OnCheckGrouponly()
{
AddSpeakers();
}
void CDialogSound::OnSelchangeComboGroups() {
CWaitCursor cursor;
gameEdit->ClearEntitySelection();
if ( comboGroups.GetCurSel() >= 0 ) {
CString group;
comboGroups.GetLBText( comboGroups.GetCurSel(), group );
idList< const char *> list;
list.SetNum( 512 );
int count = gameEdit->MapGetEntitiesMatchingClassWithString( "speaker", group, list.Ptr(), list.Num() );
for ( int i = 0; i < count; i++ ) {
idEntity *gameEnt = gameEdit->FindEntity( list[i] );
if (gameEnt) {
gameEdit->AddSelectedEntity( gameEnt );
Set( gameEdit->EntityGetSpawnArgs( gameEnt ) );
}
}
}
AddSpeakers();
}
void CDialogSound::OnSelchangeComboSpeakers() {
CWaitCursor cursor;
gameEdit->ClearEntitySelection();
if ( comboSpeakers.GetCurSel() >= 0 ) {
CString speaker;
comboSpeakers.GetLBText( comboSpeakers.GetCurSel(), speaker );
idList< const char *> list;
list.SetNum( 512 );
int count = gameEdit->MapGetEntitiesMatchingClassWithString( "speaker", speaker, list.Ptr(), list.Num() );
for ( int i = 0; i < count; i++ ) {
idEntity *gameEnt = gameEdit->FindEntity( list[i] );
if (gameEnt) {
gameEdit->AddSelectedEntity( gameEnt );
Set( gameEdit->EntityGetSpawnArgs( gameEnt ) );
}
}
}
}
void CDialogSound::OnBtnDown() {
fVolume = -1.0;
UpdateData( FALSE );
ApplyChanges( true, false );
}
void CDialogSound::OnBtnUp() {
fVolume = 1.0;
UpdateData( FALSE );
ApplyChanges( true, false );
}
void CDialogSound::OnBtnRefreshspeakers()
{
AddGroups();
AddSpeakers();
}
void CDialogSound::OnBtnRefreshwave()
{
HTREEITEM item = treeSounds.GetSelectedItem();
if (item && treeSounds.GetItemData( item ) == WAVEDIR) {
idStr path = "sound/";
path += RebuildItemName("sound", item);
idFileList *files;
files = fileSystem->ListFilesTree( path, ".wav" );
HTREEITEM child = treeSounds.GetChildItem(item);
while (child) {
HTREEITEM next = treeSounds.GetNextSiblingItem(child);
if (treeSounds.GetItemData(child) == WAVES) {
treeSounds.DeleteItem(child);
}
child = next;
}
int c = files->GetNumFiles();
for (int i = 0; i < c; i++) {
idStr work = files->GetFile( i );
work.StripPath();
child = treeSounds.InsertItem(work, item);
treeSounds.SetItemData( child, WAVES );
treeSounds.SetItemImage( child, 2, 2 );
}
fileSystem->FreeFileList( files );
}
}
BOOL CDialogSound::PreTranslateMessage(MSG* pMsg)
{
CWnd *wnd = GetDlgItem( IDC_EDIT_VOLUME );
if ( wnd && pMsg->hwnd == wnd->GetSafeHwnd() ) {
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) {
CString str;
wnd->GetWindowText( str );
SetVolume( atof( str ) );
return TRUE;
}
}
return CDialog::PreTranslateMessage(pMsg);
}