doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DialogSound.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 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.
23 
24 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.
25 
26 ===========================================================================
27 */
28 
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "../../game/game.h"
33 #include "../../sys/win32/win_local.h"
34 #include "../../sys/win32/rc/common_resource.h"
35 #include "../../sys/win32/rc/SoundEditor_resource.h"
36 #include "../comafx/DialogName.h"
37 #include "../../sys/win32/rc/DeclEditor_resource.h"
38 #include "../decl/DialogDeclEditor.h"
39 
40 #include "DialogSound.h"
41 #include "DialogSoundGroup.h"
42 
43 #ifdef ID_DEBUG_MEMORY
44 #undef new
45 #undef DEBUG_NEW
46 #define DEBUG_NEW new
47 #endif
48 
49 extern HTREEITEM FindTreeItem(CTreeCtrl *tree, HTREEITEM root, const char *text, HTREEITEM forceParent);
50 
51 
53 // CDialogSound dialog
55 
56 
57 CDialogSound::CDialogSound(CWnd* pParent /*=NULL*/)
58  : CDialog(CDialogSound::IDD, pParent)
59 {
60  //{{AFX_DATA_INIT(CDialogSound)
61  strName = _T("");
62  fVolume = 0.0f;
63  fMax = 0.0f;
64  fMin = 0.0f;
65  strShader = _T("");
66  bPlay = TRUE;
67  bTriggered = FALSE;
68  bOmni = FALSE;
69  strGroup = _T("");
70  bGroupOnly = FALSE;
71  bOcclusion = FALSE;
72  leadThrough = 0.0f;
73  plain = FALSE;
74  inUseTree = NULL;
75  random = 0.0f;
76  wait = 0.0f;
77  shakes = 0.0f;
78  looping = TRUE;
79  unclamped = FALSE;
80  //}}AFX_DATA_INIT
81 }
82 
83 
84 void CDialogSound::DoDataExchange(CDataExchange* pDX)
85 {
86  CDialog::DoDataExchange(pDX);
87  //{{AFX_DATA_MAP(CDialogSound)
88  DDX_Control(pDX, IDC_COMBO_SPEAKERS, comboSpeakers);
89  DDX_Control(pDX, IDC_COMBO_GROUPS, comboGroups);
90  DDX_Control(pDX, IDC_EDIT_VOLUME, editVolume);
91  DDX_Control(pDX, IDC_TREE_SOUNDS, treeSounds);
92  DDX_Text(pDX, IDC_EDIT_SOUND_NAME, strName);
93  DDX_Text(pDX, IDC_EDIT_VOLUME, fVolume);
94  DDX_Text(pDX, IDC_EDIT_RANDOM, random);
95  DDX_Text(pDX, IDC_EDIT_WAIT, wait);
96  DDX_Text(pDX, IDC_EDIT_MAXDIST, fMax);
97  DDX_Text(pDX, IDC_EDIT_MINDIST, fMin);
98  DDX_Text(pDX, IDC_EDIT_SHADER, strShader);
99  DDX_Check(pDX, IDC_CHECK_PLAY, bPlay);
100  DDX_Check(pDX, IDC_CHECKP_TRIGGERED, bTriggered);
101  DDX_Check(pDX, IDC_CHECK_OMNI, bOmni);
102  DDX_Text(pDX, IDC_EDIT_GROUP, strGroup);
103  DDX_Check(pDX, IDC_CHECK_GROUPONLY, bGroupOnly);
104  DDX_Check(pDX, IDC_CHECK_OCCLUSION, bOcclusion);
105  DDX_Text(pDX, IDC_EDIT_LEADTHROUGH, leadThrough);
106  DDX_Check(pDX, IDC_CHECK_PLAIN, plain);
107  DDX_Check(pDX, IDC_CHECK_LOOPING, looping);
108  DDX_Check(pDX, IDC_CHECK_UNCLAMPED, unclamped);
109  DDX_Text(pDX, IDC_EDIT_SHAKES, shakes);
110  //}}AFX_DATA_MAP
111 }
112 
113 
114 BEGIN_MESSAGE_MAP(CDialogSound, CDialog)
115  //{{AFX_MSG_MAP(CDialogSound)
116  ON_BN_CLICKED(IDC_BTN_SAVEMAP, OnBtnSavemap)
117  ON_BN_CLICKED(IDC_BTN_SWITCHTOGAME, OnBtnSwitchtogame)
118  ON_BN_CLICKED(IDC_BTN_APPLY_SOUND, OnBtnApply)
119  ON_EN_CHANGE(IDC_EDIT_VOLUME, OnChangeEditVolume)
120  ON_BN_CLICKED(IDC_BTN_REFRESH, OnBtnRefresh)
121  ON_BN_CLICKED(IDC_BTN_PLAYSOUND, OnBtnPlaysound)
122  ON_NOTIFY(NM_DBLCLK, IDC_TREE_SOUNDS, OnDblclkTreeSounds)
123  ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_SOUNDS, OnSelchangedTreeSounds)
124  ON_BN_CLICKED(IDC_CHECK_PLAY, OnCheckPlay)
125  ON_BN_CLICKED(IDC_BTN_EDIT_SOUND, OnBtnEdit)
126  ON_BN_CLICKED(IDC_BTN_DROP, OnBtnDrop)
127  ON_BN_CLICKED(IDC_BTN_GROUP, OnBtnGroup)
128  ON_BN_CLICKED(IDC_BTN_SAVEMAPAS, OnBtnSavemapas)
129  ON_BN_CLICKED(IDC_BTN_YUP, OnBtnYup)
130  ON_BN_CLICKED(IDC_BTN_YDN, OnBtnYdn)
131  ON_BN_CLICKED(IDC_BTN_XDN, OnBtnXdn)
132  ON_BN_CLICKED(IDC_BTN_XUP, OnBtnXup)
133  ON_BN_CLICKED(IDC_BTN_ZUP, OnBtnZup)
134  ON_BN_CLICKED(IDC_BTN_ZDN, OnBtnZdn)
135  ON_BN_CLICKED(IDC_BTN_TRIGGER, OnBtnTrigger)
136  ON_WM_HSCROLL()
137  ON_BN_CLICKED(IDC_CHECK_GROUPONLY, OnCheckGrouponly)
138  ON_CBN_SELCHANGE(IDC_COMBO_GROUPS, OnSelchangeComboGroups)
139  ON_CBN_SELCHANGE(IDC_COMBO_SPEAKERS, OnSelchangeComboSpeakers)
140  ON_BN_CLICKED(IDC_BTN_DOWN, OnBtnDown)
141  ON_BN_CLICKED(IDC_BTN_UP, OnBtnUp)
142  ON_BN_CLICKED(IDC_BTN_REFRESHSPEAKERS, OnBtnRefreshspeakers)
143  ON_BN_CLICKED(IDC_BTN_REFRESHWAVE, OnBtnRefreshwave)
144  //}}AFX_MSG_MAP
145 END_MESSAGE_MAP()
146 
148 // CDialogSound message handlers
149 
150 void SoundEditorInit( const idDict *spawnArgs ) {
151 
152  if ( renderSystem->IsFullScreen() ) {
153  common->Printf( "Cannot run the sound editor in fullscreen mode.\n"
154  "Set r_fullscreen to 0 and vid_restart.\n" );
155  return;
156  }
157 
158  if ( g_SoundDialog == NULL ) {
159  InitAfx();
160  g_SoundDialog = new CDialogSound();
161  }
162 
163  if ( g_SoundDialog->GetSafeHwnd() == NULL ) {
164  g_SoundDialog->Create(IDD_DIALOG_SOUND);
165 /*
166  // FIXME: restore position
167  CRect rct;
168  g_SoundDialog->SetWindowPos( NULL, rct.left, rct.top, 0,0, SWP_NOSIZE );
169 */
170  }
171 
173 
174  g_SoundDialog->ShowWindow( SW_SHOW );
175  g_SoundDialog->SetFocus();
176 
177  if ( spawnArgs ) {
178  const char *name = spawnArgs->GetString( "name" );
179  const idDict *dict = gameEdit->MapGetEntityDict( name );
180  g_SoundDialog->Set( dict );
181  }
182 }
183 
184 void SoundEditorRun( void ) {
185 #if _MSC_VER >= 1300
186  MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!!
187 #else
188  MSG *msg = &m_msgCur;
189 #endif
190 
191  while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) {
192  // pump message
193  if ( !AfxGetApp()->PumpMessage() ) {
194  }
195  }
196 }
197 
198 void SoundEditorShutdown( void ) {
199  delete g_SoundDialog;
200  g_SoundDialog = NULL;
201 }
202 
203 void CDialogSound::OnActivate( UINT nState, CWnd *pWndOther, BOOL bMinimized ) {
204  CDialog::OnActivate( nState, pWndOther, bMinimized );
205  if ( nState != WA_INACTIVE ) {
206  }
207 }
208 
209 void CDialogSound::OnMove( int x, int y ) {
210  if ( GetSafeHwnd() ) {
211  CRect rct;
212  GetWindowRect( rct );
213  // FIXME: save position
214  }
215  CDialog::OnMove( x, y );
216 }
217 
219 
221 
222  return CDialog::OnDestroy();
223 }
224 
226 
227  if ( source == NULL ) {
228  return;
229  }
230 
231  fVolume = source->GetFloat( "s_volume", "0" );
232  fMin = source->GetFloat( "s_mindistance", "1" );
233  fMax = source->GetFloat( "s_maxdistance", "10" );
234  leadThrough = source->GetFloat( "s_leadthrough", "0.1" );
235  plain = source->GetBool( "s_plain" );
236  strShader = source->GetString( "s_shader" );
237  strGroup = source->GetString( "soundgroup" );
238  bOmni = source->GetInt( "s_omni", "-1" );
239  bOcclusion = source->GetBool( "s_occlusion", "0" );
240  bTriggered = source->GetInt( "s_waitfortrigger", "-1" );
241  random = source->GetFloat( "random" );
242  wait = source->GetFloat( "wait" );
243  strName = source->GetString("name");
244  looping = source->GetBool( "s_looping" );
245  unclamped = source->GetBool( "s_unclamped" );
246  shakes = source->GetFloat( "s_shakes" );
247  if (comboSpeakers.SelectString(-1, strName) == CB_ERR) {
248  comboSpeakers.SetCurSel(-1);
249  }
250  if (comboGroups.SelectString(-1, strGroup) == CB_ERR) {
251  comboGroups.SetCurSel(-1);
252  }
253  UpdateData(FALSE);
254 }
255 
257 
258  if ( source == NULL ) {
259  return;
260  }
261  UpdateData( TRUE );
262  float f = source->GetFloat( "s_volume" );
263  source->SetFloat( "s_volume", f );
264  source->SetFloat( "s_mindistance", fMin );
265  source->SetFloat( "s_maxdistance", fMax );
266  source->Set( "s_shader", strShader );
267  source->SetInt( "s_omni", bOmni );
268  source->SetBool( "s_occlusion", ( bOcclusion != FALSE ) );
269  source->SetInt("s_waitfortrigger", bTriggered );
270  source->Set( "soundgroup", strGroup );
271  source->Set( "name", strName );
272  source->SetFloat( "s_leadthrough", leadThrough );
273  source->SetBool( "s_plain", ( plain != FALSE ) );
274  source->SetFloat( "wait", wait );
275  source->SetFloat( "random", random );
276  source->SetBool( "s_looping", looping == TRUE );
277  source->SetBool( "s_unclamped", unclamped == TRUE );
278  source->SetFloat( "s_shakes", shakes );
279 }
280 
282 {
283  OnBtnApply();
284  gameEdit->MapSave();
285 }
286 
288 {
289  ::SetFocus(win32.hWnd);
290 }
291 
292 void CDialogSound::SetVolume( float vol ) {
293  idList<idEntity*> list;
294  list.SetNum( 128 );
295  int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() );
296  list.SetNum( count );
297 
298  if ( count ) {
299  // we might be in either the game or the editor
301  if ( sw ) {
302  sw->PlayShaderDirectly( "" );
303  }
304 
305  for (int i = 0; i < count; i++) {
306  const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] );
307  if ( dict == NULL ) {
308  continue;
309  }
310  const char *name = dict->GetString( "name" );
311  const idDict *dict2 = gameEdit->MapGetEntityDict( name );
312  if ( dict2 ) {
313  gameEdit->MapSetEntityKeyVal( name, "s_volume", va( "%f", vol ) );
314  gameEdit->MapSetEntityKeyVal( name, "s_justVolume", "1" );
315  gameEdit->EntityUpdateChangeableSpawnArgs( list[i], dict2 );
316  fVolume = vol;
317  UpdateData( FALSE );
318  }
319  }
320  }
321 }
322 
323 void CDialogSound::ApplyChanges( bool volumeOnly, bool updateInUseTree ) {
324  idList<idEntity*> list;
325  float vol;
326 
327  vol = fVolume;
328 
329  list.SetNum( 128 );
330  int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() );
331  list.SetNum( count );
332 
333  if ( count ) {
334  // we might be in either the game or the editor
336  if ( sw ) {
337  sw->PlayShaderDirectly( "" );
338  }
339 
340  for (int i = 0; i < count; i++) {
341  const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] );
342  if ( dict == NULL ) {
343  continue;
344  }
345  const char *name = dict->GetString( "name" );
346  const idDict *dict2 = gameEdit->MapGetEntityDict( name );
347  if ( dict2 ) {
348  if ( volumeOnly ) {
349  float f = dict2->GetFloat( "s_volume" );
350  f += vol;
351  gameEdit->MapSetEntityKeyVal( name, "s_volume", va( "%f", f ) );
352  gameEdit->MapSetEntityKeyVal( name, "s_justVolume", "1" );
353  gameEdit->EntityUpdateChangeableSpawnArgs( list[i], dict2 );
354  fVolume = f;
355  UpdateData( FALSE );
356  } else {
357  idDict src;
358  src.SetFloat( "s_volume", dict2->GetFloat( "s_volume" ));
359  Get( &src );
360  src.SetBool( "s_justVolume", true );
361  gameEdit->MapCopyDictToEntity( name, &src );
362  gameEdit->EntityUpdateChangeableSpawnArgs( list[i], dict2 );
363  Set( dict2 );
364  }
365  }
366  }
367  }
368 
369  AddGroups();
370  AddSpeakers();
371  if ( updateInUseTree ) {
372  AddInUseSounds();
373  }
374 }
375 
377 {
378  ApplyChanges();
379 }
380 
382 {
383  // TODO: If this is a RICHEDIT control, the control will not
384  // send this notification unless you override the CDialog::OnInitDialog()
385  // function and call CRichEditCtrl().SetEventMask()
386  // with the ENM_CHANGE flag ORed into the mask.
387 
388  // TODO: Add your control notification handler code here
389 
390 }
391 
392 HTREEITEM CDialogSound::AddStrList(const char *root, const idStrList &list, int id) {
393  idStr out;
394 
395  HTREEITEM base = treeSounds.InsertItem(root);
396  HTREEITEM item = base;
397  HTREEITEM add;
398 
399  int count = list.Num();
400 
401  idStr last, path, path2;
402  for (int i = 0; i < count; i++) {
403  idStr name = list[i];
404 
405  // now break the name down convert to slashes
406  name.BackSlashesToSlashes();
407  name.Strip(' ');
408 
409  int index;
410  int len = last.Length();
411  if (len == 0) {
412  index = name.Last('/');
413  if (index >= 0) {
414  name.Left(index, last);
415  }
416  }
417  else if (idStr::Icmpn(last, name, len) == 0 && name.Last('/') <= len) {
418  name.Right(name.Length() - len - 1, out);
419  add = treeSounds.InsertItem(out, item);
420  quickTree.Set(name, add);
421  treeSounds.SetItemData(add, id);
422  treeSounds.SetItemImage(add, 2, 2);
423  continue;
424  }
425  else {
426  last.Empty();
427  }
428 
429  index = 0;
430  item = base;
431  path = "";
432  path2 = "";
433  while (index >= 0) {
434  index = name.Find('/');
435  if (index >= 0) {
436  HTREEITEM newItem = NULL;
437  HTREEITEM *check = NULL;
438  name.Left( index, out );
439  path += out;
440  if (quickTree.Get(path, &check)) {
441  newItem = *check;
442  }
443 
444  //HTREEITEM newItem = FindTreeItem(&treeSounds, item, name.Left(index, out), item);
445  if (newItem == NULL) {
446  newItem = treeSounds.InsertItem(out, item);
447  quickTree.Set(path, newItem);
448  treeSounds.SetItemData(newItem, WAVEDIR);
449  treeSounds.SetItemImage(newItem, 0, 1);
450  }
451 
452  assert(newItem);
453  item = newItem;
454  name.Right( name.Length() - index - 1, out );
455  name = out;
456  path += "/";
457  }
458  else {
459  add = treeSounds.InsertItem(name, item);
460  treeSounds.SetItemData(add, id);
461  treeSounds.SetItemImage(add, 2, 2);
462  path = "";
463  }
464  }
465  }
466  return base;
467 }
468 
469 void CDialogSound::AddSounds(bool rootItems) {
470  int i, j;
471  idStrList list(1024);
472  idStrList list2(1024);
473  HTREEITEM base = treeSounds.InsertItem("Sound Shaders");
474 
475  for( i = 0; i < declManager->GetNumDecls( DECL_SOUND ) ; i++ ) {
476  const idSoundShader *poo = declManager->SoundByIndex(i, false);
477  list.AddUnique( poo->GetFileName() );
478  }
479  list.Sort();
480 
481  for ( i = 0; i < list.Num(); i++ ) {
482  HTREEITEM child = treeSounds.InsertItem(list[i], base);
483  treeSounds.SetItemData(child, SOUNDPARENT);
484  treeSounds.SetItemImage(child, 0, 1);
485  list2.Clear();
486  for (j = 0; j < declManager->GetNumDecls( DECL_SOUND ); j++) {
487  const idSoundShader *poo = declManager->SoundByIndex(j, false);
488  if ( idStr::Icmp( list[i], poo->GetFileName() ) == 0 ) {
489  list2.Append( poo->GetName() );
490  }
491  }
492  list2.Sort();
493  for (j = 0; j < list2.Num(); j++) {
494  HTREEITEM child2 = treeSounds.InsertItem( list2[j], child );
495  treeSounds.SetItemData(child2, SOUNDS);
496  treeSounds.SetItemImage(child2, 2, 2);
497  }
498  }
499 
500  idFileList *files;
501  files = fileSystem->ListFilesTree( "sound", ".wav|.ogg", true );
502  AddStrList( "Wave files", files->GetList(), WAVES );
503  fileSystem->FreeFileList( files );
504 }
505 
507  comboGroups.ResetContent();
508  idStr work;
509  CWaitCursor cursor;
510 
511  idList<const char*> list;
512  list.SetNum( 1024 );
513  int count = gameEdit->MapGetUniqueMatchingKeyVals( "soundgroup", list.Ptr(), list.Num() );
514  for ( int i = 0; i < count; i++ ) {
515  comboGroups.AddString( list[i] );
516  }
517 }
518 
520  if ( inUseTree ) {
521  treeSounds.DeleteItem( inUseTree );
522  inUseTree = NULL;
523  }
524  inUseTree = treeSounds.InsertItem("Sounds in use");
526  list.SetNum( 512 );
527  int i, count = gameEdit->MapGetEntitiesMatchingClassWithString( "speaker", "", list.Ptr(), list.Num() );
528  idStrList list2;
529  for ( i = 0; i < count; i++ ) {
530  const idDict *dict = gameEdit->MapGetEntityDict( list[i] );
531  if ( dict ) {
532  const char *p = dict->GetString( "s_shader" );
533  if ( p && *p ) {
534  list2.AddUnique( p );
535  }
536  }
537  }
538  list2.Sort();
539  count = list2.Num();
540  for ( i = 0; i < count; i++ ) {
541  HTREEITEM child = treeSounds.InsertItem( list2[i], inUseTree );
542  treeSounds.SetItemData( child, INUSESOUNDS );
543  treeSounds.SetItemImage( child, 2, 2 );
544  }
545 }
546 
548  UpdateData( TRUE );
549  comboSpeakers.ResetContent();
550 
551  CWaitCursor cursor;
553  list.SetNum( 512 );
554 
555  CString group( "" );
556  if (bGroupOnly && comboGroups.GetCurSel() >= 0) {
557  comboGroups.GetLBText( comboGroups.GetCurSel(), group );
558  }
559  int count = gameEdit->MapGetEntitiesMatchingClassWithString( "speaker", group, list.Ptr(), list.Num() );
560 
561  for ( int i = 0; i < count; i++ ) {
562  comboSpeakers.AddString(list[i]);
563  }
564 }
565 
567 {
568  CDialog::OnInitDialog();
569 
570  // Indicate the sound dialog is opened
572 
573  inUseTree = NULL;
574  AddSounds(true);
575  AddGroups();
576  AddSpeakers();
577  AddInUseSounds();
578  SetWaveSize();
579 
580  return TRUE; // return TRUE unless you set the focus to a control
581  // EXCEPTION: OCX Property Pages should return FALSE
582 }
583 
585 {
586  CWaitCursor cursor;
587  treeSounds.DeleteAllItems();
588  quickTree.Clear();
589  declManager->Reload( false );
590  AddSounds(true);
591 }
592 
594 {
595  if (playSound.GetLength()) {
596  // we might be in either the game or the editor
598  if ( sw ) {
600  }
601  }
602 
603 }
604 
605 void CDialogSound::OnDblclkTreeSounds(NMHDR* pNMHDR, LRESULT* pResult)
606 {
607  *pResult = 0;
608  CPoint pt;
609  GetCursorPos( &pt );
610  treeSounds.ScreenToClient( &pt );
611  HTREEITEM item = treeSounds.HitTest( pt );
612 
613  if (item) {
614  DWORD dw = treeSounds.GetItemData( item );
615  if ( dw == SOUNDS || dw == INUSESOUNDS ) {
616  if ( !treeSounds.ItemHasChildren( item ) ) {
617  strShader = treeSounds.GetItemText( item );
618  UpdateData( FALSE );
619  ApplyChanges( false, ( dw == SOUNDS ) );
620  }
621  } else if ( dw == WAVES ) {
622  strShader = RebuildItemName( "Wave Files", item );
623  UpdateData( FALSE );
624  OnBtnApply();
625  }
626  }
627  *pResult = 0;
628 }
629 
630 void CDialogSound::SetWaveSize( const char *p ) {
631  CWnd *wnd = GetDlgItem( IDC_STATIC_WAVESIZE );
632  if ( wnd ) {
633  wnd->SetWindowText( ( p && *p ) ? p : "unknown" );
634  }
635 }
636 
637 void CDialogSound::OnSelchangedTreeSounds(NMHDR* pNMHDR, LRESULT* pResult)
638 {
639  NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
640  HTREEITEM item = treeSounds.GetSelectedItem();
641  SetWaveSize();
642  if (item) {
643  DWORD dw = treeSounds.GetItemData(item);
644  if ( dw == SOUNDS || dw == INUSESOUNDS ) {
645  playSound = treeSounds.GetItemText(item);
646  if (bPlay){
647  OnBtnPlaysound();
648  }
649  } else if (dw == WAVES) {
650  playSound = RebuildItemName("Wave Files", item);
651  float size = fileSystem->ReadFile( playSound, NULL );
652  SetWaveSize( va( "%0.2f mb", size / ( 1024 * 1024) ) );
653  if (bPlay){
654  OnBtnPlaysound();
655  }
656  }
657  }
658 
659  *pResult = 0;
660 }
661 
663 {
664  UpdateData(TRUE);
665 }
666 
668 {
670 
671  if ( decl ) {
672  DialogDeclEditor *declEditor;
673 
674  declEditor = new DialogDeclEditor;
675  declEditor->Create( IDD_DIALOG_DECLEDITOR, GetParent() );
676  declEditor->LoadDecl( const_cast<idDecl *>( decl ) );
677  declEditor->ShowWindow( SW_SHOW );
678  declEditor->SetFocus();
679  }
680 }
681 
683 {
684  idStr classname;
685  idStr key;
686  idStr value;
687  idVec3 org;
688  idDict args;
689  idAngles viewAngles;
690 
691 
692  gameEdit->PlayerGetViewAngles( viewAngles );
694  org += idAngles( 0, viewAngles.yaw, 0 ).ToForward() * 80 + idVec3( 0, 0, 1 );
695  args.Set("origin", org.ToString());
696  args.Set("classname", "speaker");
697  args.Set("angle", va( "%f", viewAngles.yaw + 180 ));
698  args.Set("s_shader", strShader);
699  args.Set("s_looping", "1" );
700  args.Set("s_shakes", "0" );
701 
702 
703  idStr name = gameEdit->GetUniqueEntityName( "speaker" );
704  bool nameValid = false;
705  while (!nameValid) {
706  DialogName dlg("Name Speaker", this);
707  dlg.m_strName = name;
708  if (dlg.DoModal() == IDOK) {
709  idEntity *gameEnt = gameEdit->FindEntity(dlg.m_strName);
710  if (gameEnt) {
711  if (MessageBox("Please choose another name", "Duplicate Entity Name!", MB_OKCANCEL) == IDCANCEL) {
712  return;
713  }
714  } else {
715  nameValid = true;
716  name = dlg.m_strName;
717  }
718  }
719  }
720 
721  args.Set("name", name.c_str());
722 
723  idEntity *ent = NULL;
724  gameEdit->SpawnEntityDef( args, &ent );
725  if (ent) {
728  gameEdit->AddSelectedEntity( ent );
729  }
730 
731  gameEdit->MapAddEntity( &args );
732  const idDict *dict = gameEdit->MapGetEntityDict( args.GetString( "name" ) );
733  Set( dict );
734  AddGroups();
735  AddSpeakers();
736 }
737 
739 {
740  idList<idEntity*> list;
741 
742  list.SetNum( 128 );
743  int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() );
744  list.SetNum( count );
745 
746  bool removed = false;
747  if (count) {
748  for (int i = 0; i < count; i++) {
749  const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] );
750  if ( dict == NULL ) {
751  continue;
752  }
753  const char *name = dict->GetString("name");
754  dict = gameEdit->MapGetEntityDict( name );
755  if ( dict ) {
756  if (MessageBox("Are you Sure?", "Delete Selected Speakers", MB_YESNO) == IDYES) {
757  gameEdit->MapRemoveEntity( name );
758  idEntity *gameEnt = gameEdit->FindEntity( name );
759  if ( gameEnt ) {
760  gameEdit->EntityStopSound( gameEnt );
761  gameEdit->EntityDelete( gameEnt );
762  removed = true;
763  }
764  }
765  }
766  }
767  }
768 
769  if (removed) {
770  AddGroups();
771  AddSpeakers();
772  }
773 
774 }
775 
777 {
778  CFileDialog dlgSave(FALSE,"map",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"Map Files (*.map)|*.map||",AfxGetMainWnd());
779  if (dlgSave.DoModal() == IDOK) {
780  OnBtnApply();
781  idStr work;
782  work = fileSystem->OSPathToRelativePath( dlgSave.m_ofn.lpstrFile );
783  gameEdit->MapSave( work );
784  }
785 }
786 
787 idStr CDialogSound::RebuildItemName(const char *root, HTREEITEM item) {
788  // have to build the name back up
789  idStr strParent;
790  HTREEITEM parent = treeSounds.GetParentItem(item);
791  idStr name = treeSounds.GetItemText(item);
792  while (true && parent) {
793  idStr test = treeSounds.GetItemText(parent);
794  if ( idStr::Icmp(test, root) == 0 ) {
795  break;
796  }
797  strParent = test;
798  strParent += "/";
799  strParent += name;
800  name = strParent;
801  parent = treeSounds.GetParentItem(parent);
802  if (parent == NULL) {
803  break;
804  }
805  }
806  return strParent;
807 }
808 
809 
810 void CDialogSound::UpdateSelectedOrigin( float x, float y, float z ) {
811  idList<idEntity*> list;
812  idVec3 origin;
813  idVec3 vec(x, y, z);
814 
815  list.SetNum( 128 );
816  int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() );
817  list.SetNum( count );
818 
819  if ( count ) {
820  for ( int i = 0; i < count; i++ ) {
821  const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] );
822  if ( dict == NULL ) {
823  continue;
824  }
825  const char *name = dict->GetString( "name" );
826  gameEdit->EntityTranslate( list[i], vec );
827  gameEdit->EntityUpdateVisuals( list[i] );
828  gameEdit->MapEntityTranslate( name, vec );
829  }
830  }
831 }
832 
834 {
835  UpdateSelectedOrigin(0, 8, 0);
836 }
837 
839 {
840  UpdateSelectedOrigin(0, -8, 0);
841 }
842 
844 {
845  UpdateSelectedOrigin(-8, 0, 0);
846 }
847 
849 {
850  UpdateSelectedOrigin(8, 0, 0);
851 }
852 
854 {
855  UpdateSelectedOrigin(0, 0, 8);
856 }
857 
859 {
860  UpdateSelectedOrigin(0, 0, -8);
861 }
862 
865 }
866 
867 void CDialogSound::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {
868 }
869 
870 
872 {
873  AddSpeakers();
874 }
875 
877  CWaitCursor cursor;
879  if ( comboGroups.GetCurSel() >= 0 ) {
880  CString group;
881  comboGroups.GetLBText( comboGroups.GetCurSel(), group );
882 
884  list.SetNum( 512 );
885  int count = gameEdit->MapGetEntitiesMatchingClassWithString( "speaker", group, list.Ptr(), list.Num() );
886  for ( int i = 0; i < count; i++ ) {
887  idEntity *gameEnt = gameEdit->FindEntity( list[i] );
888  if (gameEnt) {
889  gameEdit->AddSelectedEntity( gameEnt );
890  Set( gameEdit->EntityGetSpawnArgs( gameEnt ) );
891  }
892  }
893  }
894  AddSpeakers();
895 }
896 
898  CWaitCursor cursor;
900  if ( comboSpeakers.GetCurSel() >= 0 ) {
901  CString speaker;
902  comboSpeakers.GetLBText( comboSpeakers.GetCurSel(), speaker );
904  list.SetNum( 512 );
905  int count = gameEdit->MapGetEntitiesMatchingClassWithString( "speaker", speaker, list.Ptr(), list.Num() );
906  for ( int i = 0; i < count; i++ ) {
907  idEntity *gameEnt = gameEdit->FindEntity( list[i] );
908  if (gameEnt) {
909  gameEdit->AddSelectedEntity( gameEnt );
910  Set( gameEdit->EntityGetSpawnArgs( gameEnt ) );
911  }
912  }
913  }
914 }
915 
917  fVolume = -1.0;
918  UpdateData( FALSE );
919  ApplyChanges( true, false );
920 }
921 
923  fVolume = 1.0;
924  UpdateData( FALSE );
925  ApplyChanges( true, false );
926 }
927 
929 {
930  AddGroups();
931  AddSpeakers();
932 }
933 
935 {
936  HTREEITEM item = treeSounds.GetSelectedItem();
937  if (item && treeSounds.GetItemData( item ) == WAVEDIR) {
938  idStr path = "sound/";
939  path += RebuildItemName("sound", item);
940  idFileList *files;
941  files = fileSystem->ListFilesTree( path, ".wav" );
942  HTREEITEM child = treeSounds.GetChildItem(item);
943  while (child) {
944  HTREEITEM next = treeSounds.GetNextSiblingItem(child);
945  if (treeSounds.GetItemData(child) == WAVES) {
946  treeSounds.DeleteItem(child);
947  }
948  child = next;
949  }
950  int c = files->GetNumFiles();
951  for (int i = 0; i < c; i++) {
952  idStr work = files->GetFile( i );
953  work.StripPath();
954  child = treeSounds.InsertItem(work, item);
955  treeSounds.SetItemData( child, WAVES );
956  treeSounds.SetItemImage( child, 2, 2 );
957  }
958  fileSystem->FreeFileList( files );
959  }
960 }
961 
963 {
964  CWnd *wnd = GetDlgItem( IDC_EDIT_VOLUME );
965  if ( wnd && pMsg->hwnd == wnd->GetSafeHwnd() ) {
966  if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) {
967  CString str;
968  wnd->GetWindowText( str );
969  SetVolume( atof( str ) );
970  return TRUE;
971  }
972  }
973  return CDialog::PreTranslateMessage(pMsg);
974 }
virtual void EntityUpdateChangeableSpawnArgs(idEntity *ent, const idDict *dict)
Definition: GameEdit.cpp:864
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar)
#define IDC_BTN_EDIT_SOUND
float GetFloat(const char *key, const char *defaultString="0") const
Definition: Dict.h:248
GLsizei const GLfloat * value
Definition: glext.h:3614
int GetInt(const char *key, const char *defaultString="0") const
Definition: Dict.h:252
void Set(const idDict *source)
HTREEITEM AddStrList(const char *root, const idStrList &list, int id)
virtual void DoDataExchange(CDataExchange *pDX)
Definition: DialogSound.cpp:84
virtual void MapAddEntity(const idDict *dict) const
Definition: GameEdit.cpp:1070
assert(prefInfo.fullscreenBtn)
#define IDC_BTN_REFRESHSPEAKERS
afx_msg void OnDestroy()
const char * GetFileName(void) const
Definition: DeclManager.h:171
afx_msg void OnSelchangedTreeSounds(NMHDR *pNMHDR, LRESULT *pResult)
afx_msg void OnActivate(UINT nState, CWnd *pWndOther, BOOL bMinimized)
#define IDC_BTN_YDN
afx_msg void OnBtnXup()
virtual void MapRemoveEntity(const char *name) const
Definition: GameEdit.cpp:1084
#define IDC_CHECK_OCCLUSION
#define IDC_COMBO_GROUPS
CONST PIXELFORMATDESCRIPTOR UINT
Definition: win_qgl.cpp:47
virtual void EntityTranslate(idEntity *ent, const idVec3 &org)
Definition: GameEdit.cpp:841
#define IDC_CHECK_UNCLAMPED
#define IDC_BTN_TRIGGER
void SetNum(int newnum, bool resize=true)
Definition: List.h:289
#define IDC_EDIT_MAXDIST
afx_msg void OnBtnSwitchtogame()
void SetVolume(float f)
#define const
Definition: getdate.c:251
virtual int ReadFile(const char *relativePath, void **buffer, ID_TIME_T *timestamp=NULL)=0
void UpdateSelectedOrigin(float x, float y, float z)
int Length(void) const
Definition: Str.h:702
#define IDC_EDIT_RANDOM
int GetNumFiles(void) const
Definition: FileSystem.h:126
const idStrList & GetList(void) const
Definition: FileSystem.h:128
#define IDC_BTN_APPLY_SOUND
static void ClearStates(void)
Definition: KeyInput.cpp:746
DWORD
Definition: win_qgl.cpp:61
virtual void PlayShaderDirectly(const char *name, int channel=-1)=0
GLenum GLint GLint y
Definition: glext.h:2849
#define IDC_BTN_SWITCHTOGAME
virtual BOOL OnInitDialog()
virtual const char * GetUniqueEntityName(const char *classname) const
Definition: GameEdit.cpp:764
idRenderSystem * renderSystem
CString m_strName
Definition: DialogName.h:51
idFileSystem * fileSystem
Definition: FileSystem.cpp:500
void Strip(const char c)
Definition: Str.h:915
virtual void EntityStopSound(idEntity *ent)
Definition: GameEdit.cpp:917
virtual void TriggerSelected()
Definition: GameEdit.cpp:696
afx_msg void OnCheckPlay()
afx_msg void OnBtnYup()
const char * GetName(void) const
Definition: DeclManager.h:140
Definition: Vector.h:316
type * Ptr(void)
Definition: List.h:596
#define IDC_BTN_SAVEMAP
afx_msg void OnBtnRefreshwave()
void Get(idDict *dest)
const char * Left(int len, idStr &result) const
Definition: Str.h:892
afx_msg void OnBtnSavemap()
#define IDC_CHECK_PLAIN
idStr RebuildItemName(const char *root, HTREEITEM item)
#define IDC_EDIT_SOUND_NAME
GLuint src
Definition: glext.h:5390
GLenum GLsizei len
Definition: glext.h:3472
void Set(const char *key, const char *value)
Definition: Dict.cpp:275
#define IDC_BTN_REFRESHWAVE
CDialogSound * g_SoundDialog
Definition: DialogSound.cpp:54
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
afx_msg void OnCheckGrouponly()
#define BOOL
Definition: mprintf.c:71
#define IDC_EDIT_WAIT
afx_msg void OnBtnSavemapas()
void SetFloat(const char *key, float val)
Definition: Dict.h:188
int test(char *url)
Definition: lib500.c:3
void SoundEditorInit(const idDict *spawnArgs)
int Icmp(const char *text) const
Definition: Str.h:667
#define IDC_CHECK_PLAY
idStr & BackSlashesToSlashes(void)
Definition: Str.cpp:727
#define IDC_BTN_GROUP
idGameEdit * gameEdit
Definition: GameEdit.cpp:668
idStr & StripPath(void)
Definition: Str.cpp:885
void InitAfx(void)
Definition: StdAfx.cpp:53
afx_msg void OnBtnUp()
int com_editors
Definition: Common.cpp:97
int Icmpn(const char *text, int n) const
Definition: Str.h:672
#define IDC_BTN_DROP
virtual idSoundWorld * GetPlayingSoundWorld(void)=0
GLsizei GLsizei GLcharARB * source
Definition: glext.h:3633
virtual void MapCopyDictToEntity(const char *name, const idDict *dict) const
Definition: GameEdit.cpp:1026
virtual void MapSetEntityKeyVal(const char *name, const char *key, const char *val) const
Definition: GameEdit.cpp:1011
void Set(const char *key, Type &value)
Definition: HashTable.h:186
#define IDC_BTN_ZUP
#define IDC_TREE_SOUNDS
void Sort(cmp_t *compare=(cmp_t *)&idListSortCompare< type >)
Definition: List.h:898
virtual void PlayerGetEyePosition(idVec3 &org) const
Definition: GameEdit.cpp:973
afx_msg void OnBtnRefresh()
CEdit editVolume
Definition: DialogSound.h:95
#define IDC_CHECKP_TRIGGERED
GLuint GLuint GLsizei count
Definition: glext.h:2845
void SoundEditorRun(void)
#define IDC_BTN_YUP
void AddGroups()
virtual bool IsFullScreen(void) const =0
GLuint index
Definition: glext.h:3476
const GLubyte * c
Definition: glext.h:4677
const char * GetString(const char *key, const char *defaultString="") const
Definition: Dict.h:240
idVec3 ToForward(void) const
Definition: Angles.cpp:117
void Empty(void)
Definition: Str.h:714
#define IDC_BTN_UP
idHashTable< HTREEITEM > quickTree
Definition: DialogSound.h:118
idCommon * common
Definition: Common.cpp:206
#define IDC_COMBO_SPEAKERS
virtual void MapSave(const char *path=NULL) const
Definition: GameEdit.cpp:999
afx_msg void OnSelchangeComboGroups()
virtual void PlayerGetViewAngles(idAngles &angles) const
Definition: GameEdit.cpp:964
bool GetBool(const char *key, const char *defaultString="0") const
Definition: Dict.h:256
Definition: Dict.h:65
#define IDC_EDIT_SHADER
#define NULL
Definition: Lib.h:88
virtual void EntityDelete(idEntity *ent)
Definition: GameEdit.cpp:928
#define IDC_BTN_REFRESH
afx_msg void OnBtnZup()
virtual void AddSelectedEntity(idEntity *ent)
Definition: GameEdit.cpp:724
afx_msg void OnBtnPlaysound()
afx_msg void OnBtnEdit()
#define IDC_CHECK_LOOPING
const char * GetFile(int index) const
Definition: FileSystem.h:127
float fVolume
Definition: DialogSound.h:98
#define IDC_EDIT_SHAKES
const char * path
Definition: sws.c:117
virtual void Reload(bool force)=0
void AddInUseSounds()
CString playSound
Definition: DialogSound.h:117
const char * Right(int len, idStr &result) const
Definition: Str.h:896
CString strShader
Definition: DialogSound.h:101
int Find(const char c, int start=0, int end=-1) const
Definition: Str.h:874
void ApplyChanges(bool volumeOnly=false, bool updateInUseTree=true)
virtual void FreeFileList(idFileList *fileList)=0
HTREEITEM inUseTree
Definition: DialogSound.h:119
void SetBool(const char *key, bool val)
Definition: Dict.h:196
afx_msg void OnBtnRefreshspeakers()
virtual const idSoundShader * SoundByIndex(int index, bool forceParse=true)=0
virtual void Printf(const char *fmt,...) id_attribute((format(printf
void Clear(void)
Definition: HashTable.h:310
afx_msg void OnBtnYdn()
void LoadDecl(idDecl *decl)
void AddSpeakers()
const char * ToString(int precision=2) const
Definition: Vector.cpp:221
virtual int GetSelectedEntities(idEntity *list[], int max)
Definition: GameEdit.cpp:676
afx_msg void OnBtnApply()
CDialogSound(CWnd *pParent=NULL)
Definition: DialogSound.cpp:57
idDeclManager * declManager
#define IDC_EDIT_VOLUME
#define IDC_BTN_PLAYSOUND
afx_msg void OnBtnXdn()
virtual int GetNumDecls(declType_t type)=0
#define IDC_BTN_XUP
CComboBox comboSpeakers
Definition: DialogSound.h:93
bool Get(const char *key, Type **value=NULL) const
Definition: HashTable.h:214
#define IDC_BTN_XDN
afx_msg void OnBtnTrigger()
int Append(const type &obj)
Definition: List.h:646
void SetInt(const char *key, int val)
Definition: Dict.h:192
void SetWaveSize(const char *p=NULL)
virtual const idDecl * FindDeclWithoutParsing(declType_t type, const char *name, bool makeDefault=true)=0
afx_msg void OnBtnZdn()
float yaw
Definition: Angles.h:54
#define IDC_EDIT_GROUP
int AddUnique(const type &obj)
Definition: List.h:742
tuple f
Definition: idal.py:89
#define IDC_BTN_ZDN
CComboBox comboGroups
Definition: DialogSound.h:94
#define IDC_CHECK_OMNI
virtual idFileList * ListFilesTree(const char *relativePath, const char *extension, bool sort=false, const char *gamedir=NULL)=0
int Num(void) const
Definition: List.h:265
void SoundEditorShutdown(void)
#define IDC_BTN_DOWN
MFnDagNode * GetParent(MFnDagNode *joint)
Definition: maya_main.cpp:350
int Last(const char c) const
Definition: Str.cpp:452
const GLcharARB * name
Definition: glext.h:3629
#define IDC_STATIC_WAVESIZE
GLsizeiptr size
Definition: glext.h:3112
idSoundSystem * soundSystem
Definition: snd_system.cpp:92
Definition: Str.h:116
virtual int MapGetEntitiesMatchingClassWithString(const char *classname, const char *match, const char *list[], const int max) const
Definition: GameEdit.cpp:1100
void AddSounds(bool rootItem)
afx_msg void OnDblclkTreeSounds(NMHDR *pNMHDR, LRESULT *pResult)
const char * c_str(void) const
Definition: Str.h:487
#define FALSE
Definition: mprintf.c:70
afx_msg void OnBtnGroup()
virtual const idDict * MapGetEntityDict(const char *name) const
Definition: GameEdit.cpp:983
virtual void ClearEntitySelection(void)
Definition: GameEdit.cpp:710
HTREEITEM FindTreeItem(CTreeCtrl *tree, HTREEITEM root, const char *text, HTREEITEM forceParent)
virtual void SpawnEntityDef(const idDict &args, idEntity **ent)
Definition: GameEdit.cpp:744
#define TRUE
Definition: mprintf.c:69
virtual const idDict * EntityGetSpawnArgs(idEntity *ent) const
Definition: GameEdit.cpp:852
GLint j
Definition: qgl.h:264
afx_msg void OnMove(int x, int y)
afx_msg void OnChangeEditVolume()
#define IDC_EDIT_MINDIST
char * va(const char *fmt,...)
Definition: Str.cpp:1568
Win32Vars_t win32
Definition: win_main.cpp:65
virtual const char * OSPathToRelativePath(const char *OSPath)=0
GLfloat GLfloat p
Definition: glext.h:4674
virtual BOOL PreTranslateMessage(MSG *pMsg)
GLdouble GLdouble z
Definition: glext.h:3067
afx_msg void OnBtnDrop()
CString strName
Definition: DialogSound.h:97
virtual idEntity * FindEntity(const char *name) const
Definition: GameEdit.cpp:753
#define IDD_DIALOG_DECLEDITOR
CTreeCtrl treeSounds
Definition: DialogSound.h:96
#define IDD_DIALOG_SOUND
float leadThrough
Definition: DialogSound.h:108
CString strGroup
Definition: DialogSound.h:105
virtual void MapEntityTranslate(const char *name, const idVec3 &v) const
Definition: GameEdit.cpp:1131
afx_msg void OnBtnDown()
afx_msg void OnSelchangeComboSpeakers()
virtual int MapGetUniqueMatchingKeyVals(const char *key, const char *list[], const int max) const
Definition: GameEdit.cpp:1048
virtual void EntityUpdateVisuals(idEntity *ent)
Definition: GameEdit.cpp:894
#define IDC_EDIT_LEADTHROUGH
void Clear(void)
Definition: List.h:184
#define IDC_BTN_SAVEMAPAS
#define IDC_CHECK_GROUPONLY