Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
RadioVox.cpp
Go to the documentation of this file.
1 /* Project Starshatter 4.5
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: Stars.exe
6  FILE: RadioVox.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  View class for Radio Communications HUD Overlay
13 */
14 
15 #include "MemDebug.h"
16 #include "RadioVox.h"
17 #include "RadioView.h"
18 #include "AudioConfig.h"
19 
20 #include "DataLoader.h"
21 #include "Game.h"
22 #include "Sound.h"
23 #include "ThreadSync.h"
24 
25 // +====================================================================+
26 //
27 // RADIO VOX CONTROLLER:
28 //
29 
30 DWORD WINAPI VoxUpdateProc(LPVOID link);
31 
33 {
34 public:
35  enum { MAX_QUEUE = 5 };
36 
39 
40  bool Add(RadioVox* vox);
41  void Update();
42  DWORD UpdateThread();
43 
44  bool shutdown;
45  HANDLE hthread;
48 };
49 
50 static RadioVoxController* controller = 0;
51 
52 // +--------------------------------------------------------------------+
53 
55 : hthread(0), shutdown(false)
56 {
57  DWORD thread_id = 0;
58  hthread = CreateThread(0, 4096, VoxUpdateProc,
59  (LPVOID) this, 0, &thread_id);
60 }
61 
62 // +--------------------------------------------------------------------+
63 
65 {
66  shutdown = true;
67 
68  WaitForSingleObject(hthread, 500);
69  CloseHandle(hthread);
70  hthread = 0;
71 
72  queue.destroy();
73 }
74 
75 // +--------------------------------------------------------------------+
76 
77 DWORD WINAPI VoxUpdateProc(LPVOID link)
78 {
79  RadioVoxController* controller = (RadioVoxController*) link;
80 
81  if (controller)
82  return controller->UpdateThread();
83 
84  return (DWORD) E_POINTER;
85 }
86 
87 // +--------------------------------------------------------------------+
88 
89 DWORD
91 {
92  while (!shutdown) {
93  Update();
94  Sleep(50);
95  }
96 
97  return 0;
98 }
99 
100 // +--------------------------------------------------------------------+
101 
102 void
104 {
105  AutoThreadSync a(sync);
106 
107  if (queue.size()) {
108  RadioVox* vox = queue.first();
109 
110  if (!vox->Update())
111  delete queue.removeIndex(0);
112  }
113 }
114 
115 bool
117 {
118  if (!vox || vox->sounds.isEmpty())
119  return false;
120 
121  AutoThreadSync a(sync);
122 
123  if (queue.size() < MAX_QUEUE) {
124  queue.append(vox);
125  return true;
126  }
127 
128  return false;
129 }
130 
131 // +====================================================================+
132 //
133 // RADIO VOX MESSAGE:
134 //
135 
136 void
138 {
139  if (!controller) {
140  controller = new(__FILE__,__LINE__) RadioVoxController;
141  }
142 }
143 
144 void
146 {
147  delete controller;
148  controller = 0;
149 }
150 
151 // +--------------------------------------------------------------------+
152 
153 RadioVox::RadioVox(int n, const char* p, const char* m)
154 : path(p), message(m), index(0), channel(n)
155 {
156 }
157 
159 {
160  sounds.destroy();
161 }
162 
163 // +--------------------------------------------------------------------+
164 
165 bool
166 RadioVox::AddPhrase(const char* key)
167 {
169  return false;
170 
171  DataLoader* loader = DataLoader::GetLoader();
172  if (!loader)
173  return false;
174 
175  if (key && *key) {
176  char datapath[256];
177  char filename[256];
178 
179  sprintf_s(datapath, "Vox/%s/", path.data());
180  sprintf_s(filename, "%s.wav", key);
181 
182  bool use_fs = loader->IsFileSystemEnabled();
183  Sound* sound = 0;
184 
185  loader->UseFileSystem(true);
186  loader->SetDataPath(datapath);
187  loader->LoadSound(filename, sound, Sound::LOCALIZED, true); // optional sound
188  loader->SetDataPath(0);
189  loader->UseFileSystem(use_fs);
190 
191  if (sound) {
194  sound->SetFilename(filename);
195  sounds.append(sound);
196 
197  return true;
198  }
199  }
200 
201  return false;
202 }
203 
204 // +--------------------------------------------------------------------+
205 
206 bool
208 {
209  if (controller)
210  return controller->Add(this);
211 
212  return false;
213 }
214 
215 bool
217 {
218  if (message.length()) {
220  message = "";
221  }
222 
223  bool active = false;
224 
225  while (!active && index < sounds.size()) {
226  Sound* s = sounds[index];
227 
228  if (s->IsReady()) {
229  if (channel & 1)
230  s->SetPan(channel * -3000);
231  else
232  s->SetPan(channel * 3000);
233 
234  s->Play();
235  active = true;
236  }
237 
238  else if (s->IsPlaying()) {
239  s->Update();
240  active = true;
241  }
242 
243  else {
244  index++;
245  }
246  }
247 
248  return active;
249 }