added worldarea -> will be responsible for world map rendering
[dboe.git] / exlsound.c
blob05377c68fbc8c30564d9185e23e606f8ce7fce05
1 #include "math.h"
2 #include <windows.h>
3 #include <mmsystem.h>
5 #include "stdio.h"
7 #include "global.h"
8 #include "exlsound.h"
9 #include "text.h"
10 #include "fields.h"
12 #define NUM_SOUNDS 100
14 HGLOBAL sound_handles[NUM_SOUNDS];
15 char far *snds[NUM_SOUNDS];
17 extern HANDLE store_hInstance;
18 extern scenario_data_type far scenario;
20 extern Boolean play_sounds,in_startup_mode;
21 extern HWND mainPtr;
22 extern Boolean gInBackground;
23 extern party_record_type far party;
24 extern Boolean cat,cow,chicken,dog,sheep,monsters_going;
25 extern short num_chirps_played,overall_mode;
27 short last_played = 10000;
28 short error_beeps = 0;
29 short store_last_sound_played = 0;
31 Boolean far always_asynch[100] = {FALSE,FALSE,FALSE,FALSE,FALSE,
32 TRUE,TRUE,FALSE,FALSE,FALSE,
33 TRUE,FALSE,FALSE,FALSE,FALSE, // 10
34 FALSE,FALSE,FALSE,FALSE,FALSE,
35 FALSE,FALSE,TRUE,FALSE,TRUE, // 20
36 TRUE,FALSE,FALSE,FALSE,FALSE,
37 FALSE,FALSE,FALSE,FALSE,TRUE, // 30
38 FALSE,FALSE,TRUE,FALSE,TRUE,
39 FALSE,TRUE,TRUE,TRUE,TRUE, // 40
40 TRUE,TRUE,TRUE,TRUE,TRUE,
41 TRUE,FALSE,FALSE,TRUE,FALSE, // 50
42 TRUE,FALSE,FALSE,FALSE,FALSE,
43 FALSE,TRUE,FALSE,FALSE,FALSE, // 60
44 FALSE,FALSE,FALSE,FALSE,FALSE,
45 FALSE,FALSE,FALSE,FALSE,FALSE, // 70
46 FALSE,TRUE,TRUE,TRUE,TRUE,
47 TRUE,TRUE,TRUE,TRUE,FALSE, // 80
48 TRUE,FALSE,FALSE,FALSE,FALSE,
49 FALSE,TRUE,FALSE,FALSE,FALSE, // 90
50 FALSE,FALSE,FALSE,FALSE,FALSE};
51 Boolean far load_when_play[100] = {
52 0,0,1,1,1,0,0,1,1,1,
53 0,0,0,1,0,1,1,1,1,1,
54 1,1,0,1,1,1,1,0,1,1,
55 1,1,1,1,0,1,1,0,1,1,
56 1,1,1,1,1,1,1,0,0,0,
57 0,1,1,0,1,0,1,1,1,1, // 50
58 1,0,1,1,1,1,1,1,1,0,
59 0,0,0,0,0,0,0,0,0,0, // 70
60 1,1,1,1,1,0,0,0,0,0,
61 1,0,1,1,1,1,1,1,1,0
64 short far can_ignore[100] = {
65 0,0,0,0,0,5,3,0,0,0,
66 5,5,5,0,5,0,0,0,0,0,
67 0,0,5,0,0,0,0,0,0,2,
68 2,2,0,0,0,0,0,0,0,0,
69 0,0,0,0,0,0,0,1,1,1,
70 1,0,0,5,0,1,0,0,0,0, // 50
71 0,0,0,0,5,0,0,0,0,0,
72 0,0,0,0,0, 0,5,5,5,5, // 70
73 4,4,4,4,0,0,0,0,0,0,
74 0,5,5,0,0,0,0,0,0,0};
75 // 1 - polite asych, 1 or 2 or 3- lose easily when pref is set for fewer snds
76 // 3 can be async
77 // 4 - nostop asynch ... when 4, this sound is NOSTOP, i.e. when played, is played
78 // asynch, and refuses all other sounds. Sounds that come in are ignored, and
79 // disappear into the ether
80 // 5 - finally, bold asynch ... when 5, this sound is NOSTOP, i.e. when played, is played
81 // asynch, and refuses all other sounds. When a sound is played on top of this, game
82 // hangs on until sound is done, and then and only then plays later sound.
85 short num_devs;
86 Boolean sounds_fucked = FALSE;
87 long intro_music_start_time = -1;
89 void load_sounds ()
91 short i,t,err;
92 HRSRC h;
93 char snd_name[20],str[60];
94 WAVEOUTCAPS wavecaps;
96 t = waveOutGetNumDevs();
97 if (t == 0) {
98 sounds_fucked = TRUE;
99 return;
101 err = waveOutGetDevCaps(0,&wavecaps,sizeof(WAVEOUTCAPS));
102 if (err != 0) {
103 sounds_fucked = TRUE;
104 switch (err) {
105 case MMSYSERR_BADDEVICEID:
106 MessageBox(mainPtr,"Cannot initialize sounds - No sound device detected. Game can still be played, but quietly.",
107 "Sound Error",MB_OK | MB_ICONEXCLAMATION);
108 return;
109 case MMSYSERR_NODRIVER:
110 MessageBox(mainPtr,"Cannot initialize sounds - No driver installed. Game can still be played, but quietly.",
111 "Sound Error",MB_OK | MB_ICONEXCLAMATION);
112 return;
113 case MMSYSERR_NOMEM :
114 MessageBox(mainPtr,"Cannot initialize sounds - can't find enough memory. Game can still be played, but quietly.",
115 "Sound Error",MB_OK | MB_ICONEXCLAMATION);
116 return;
117 case MMSYSERR_ALLOCATED:
118 MessageBox(mainPtr,"Cannot initialize sounds - sound card already allocated. Game can still be played, but quietly.",
119 "Sound Error",MB_OK | MB_ICONEXCLAMATION);
120 return;
121 case MMSYSERR_ERROR:
122 MessageBox(mainPtr,"Cannot initialize sounds - internal error. Game can still be played, but quietly.",
123 "Sound Error",MB_OK | MB_ICONEXCLAMATION);
124 return;
125 default:
126 MessageBox(mainPtr,"Cannot initialize sounds - unidentified error. Game can still be played, but quietly.",
127 "Sound Error",MB_OK | MB_ICONEXCLAMATION);
128 return;
134 for (i = 0; i < NUM_SOUNDS; i++) {
135 sound_handles[i] = NULL;
136 if (load_when_play[i] == FALSE) {
137 sprintf((char *)snd_name,"#%d",i + 1);
138 h = FindResource(store_hInstance,snd_name,"#100");
140 sound_handles[i] = LoadResource(store_hInstance,h);
141 snds[i] = LockResource(sound_handles[i]);
147 void play_sound(short which) // if < 0, play asynch
149 if (PSD[304][9] > 0)
150 return;
151 if (in_startup_mode == TRUE) {
152 // put some in foreground check here
154 if (play_sounds == TRUE)
155 force_play_sound(which);
159 void force_play_sound(short which)
161 short i,err,num_fails = 0;
162 char snd_name[30],str[60];
163 Boolean asyn = FALSE,a_sound_did_get_played = FALSE,sound_played_nostop = FALSE;
164 Boolean not_asyn = FALSE,check_sound;
165 long dummy;
166 HRSRC h;
167 char far *snd;
168 DWORD size;
170 if ((sounds_fucked == TRUE) || (play_sounds == FALSE))
171 return;
172 if (which < 0) {
173 asyn = TRUE;
174 which = which * -1;
176 if (which >= 1000) {
177 which -= 1000;
178 not_asyn = TRUE;
181 if ((which != 22) && (intro_music_start_time > 0) && (GetCurrentTime() - intro_music_start_time < 8000))
182 return;
183 else if ((intro_music_start_time > 0) && (sound_handles[22] != NULL)) {
184 UnlockResource(sound_handles[22]);
185 FreeResource(sound_handles[22]);
186 sound_handles[22] = NULL;
188 if (which == 22)
189 intro_music_start_time = GetCurrentTime();
191 if (which >= 100)
192 return;
194 if ((always_asynch[which] == TRUE) &&
195 ((can_ignore[which] == 1) || (can_ignore[which] >= 3)))
196 asyn = TRUE;
197 if ((can_ignore[which] > 0) && (can_ignore[which] < 5) && (party.stuff_done[305][5] == 1))
198 return;
199 if ((can_ignore[which] != 1) && (can_ignore[which] < 3))
200 asyn = FALSE;
201 if ((party.stuff_done[305][5] == 1) && (can_ignore[which] < 5))
202 asyn = FALSE;
203 if (not_asyn == TRUE)
204 asyn = FALSE;
206 //print_nums(1000 + can_ignore[which],which,(short) asyn);
208 if ((load_when_play[which] == TRUE) && (sound_handles[which] == NULL)) {
209 // if (can_ignore[which] != 4)
210 asyn = FALSE;
211 sprintf((char *)snd_name,"#%d",which + 1);
212 h = FindResource(store_hInstance,snd_name,"#100");
214 sound_handles[which] = LoadResource(store_hInstance,h);
215 snds[which] = LockResource(sound_handles[which]);
217 // ASB("Loaded sound:");
218 // print_nums(0,0,which);
221 if (store_last_sound_played == 6) {
222 //ASB("Interrupted snd.");
223 sndPlaySound(NULL,0);
226 if (asyn == TRUE) {
227 if (can_ignore[which] >= 4)
228 check_sound = sndPlaySound(snds[which],SND_ASYNC | SND_MEMORY | SND_NOSTOP);
229 else check_sound = sndPlaySound(snds[which],SND_ASYNC | SND_MEMORY);
231 while (check_sound == FALSE) {
233 if (can_ignore[store_last_sound_played] == 4) {// then sound goes away
234 //ASB("Sound overruled by asynch sound.");
235 return;
239 num_fails++;
240 if (num_fails < 40)
241 sound_pause(25);
242 else {
243 MessageBox(mainPtr,"Cannot play sounds - Sounds stuck error a. Game can still be played, but quietly. Check to make sure your sound drivers are up to date and not corrupted.",
244 "Sound Error",MB_OK | MB_ICONEXCLAMATION);
245 print_nums(111,which,num_fails);
246 sounds_fucked = TRUE;
247 return;
249 //ASB ("Asynch clearing buffer!!!");
250 //check_sound = sndPlaySound(snds[99],SND_SYNC | SND_MEMORY);
251 sndPlaySound(NULL,0);
253 if (can_ignore[which] >= 4)
254 check_sound = sndPlaySound(snds[which],SND_ASYNC | SND_MEMORY | SND_NOSTOP);
255 else check_sound = sndPlaySound(snds[which],SND_ASYNC | SND_MEMORY);
257 a_sound_did_get_played = TRUE;
259 else {
260 if (can_ignore[which] >= 4)
261 check_sound = sndPlaySound(snds[which],SND_SYNC | SND_MEMORY | SND_NOSTOP);
262 else check_sound = sndPlaySound(snds[which],SND_SYNC | SND_MEMORY);
263 while (check_sound == FALSE) {
264 if (can_ignore[store_last_sound_played] == 4) {// then sound goes away
265 //ASB("Sound overruled by asynch sound.");
266 return;
270 num_fails++;
271 if (num_fails < 40)
272 sound_pause(25);
273 else {
274 MessageBox(mainPtr,"Cannot play sounds - Sounds stuck error b. Game can still be played, but quietly. Check to make sure your sound drivers are up to date and not corrupted.",
275 "Sound Error",MB_OK | MB_ICONEXCLAMATION);
276 print_nums(222,which,num_fails);
277 sounds_fucked = TRUE;
278 return;
280 //ASB ("Asynch clearing buffer!!!");
281 //check_sound = sndPlaySound(snds[99],SND_SYNC | SND_MEMORY);
282 sndPlaySound(NULL,0);
284 if (can_ignore[which] >= 4)
285 check_sound = sndPlaySound(snds[which],SND_SYNC | SND_MEMORY | SND_NOSTOP);
286 else check_sound = sndPlaySound(snds[which],SND_SYNC | SND_MEMORY);
288 a_sound_did_get_played = TRUE;
291 store_last_sound_played = which;
293 if ((load_when_play[which] == TRUE) && (asyn == FALSE)) {
294 // deleted a seemingly extraneous LoadResource here
295 //ASB("Dumped a sound.");
296 UnlockResource(sound_handles[which]);
297 FreeResource(sound_handles[which]);
298 sound_handles[which] = NULL;
300 //else if (load_when_play[which] == TRUE) ASB("Kept a temp. sound.");
301 for (i = 0; i < NUM_SOUNDS; i++)
302 if ((load_when_play[which] == TRUE) && (sound_handles[which] != NULL)
303 && (a_sound_did_get_played == TRUE) && (i != which)){
304 // deleted a seemingly extraneous LoadResource here
305 UnlockResource(sound_handles[i]);
306 FreeResource(sound_handles[i]);
307 sound_handles[i] = NULL;
308 //ASB("Kept sound dumped:");
309 //print_nums(0,0,i);
314 void kill_sound()
316 sndPlaySound(NULL,0);
318 void one_sound(short which)
320 if (which == last_played)
321 return;
322 play_sound(which);
323 last_played = which;
326 void clear_sound_memory()
328 last_played = 100;
331 void flip_sound()
333 play_sounds = (play_sounds == TRUE) ? FALSE : TRUE;
336 void sound_pause(long len) {
337 long t1,t2;
339 t1 = (long) GetCurrentTime();
340 t2 = t1;
341 while (t2 - t1 < len) {
342 t2 = (long)GetCurrentTime();
345 void move_sound(unsigned char ter,short step)
347 short pic,spec;
349 pic = scenario.ter_types[ter].picture;
350 spec = scenario.ter_types[ter].special;
352 if ((monsters_going == FALSE) && (overall_mode < 10) && (party.in_boat >= 0)) {
353 if (spec == 21)
354 return;
355 play_sound(48);
357 else if ((monsters_going == FALSE) && (overall_mode < 10) && (party.in_horse >= 0)) {////
358 play_sound(85);
360 else if ((ter >= 84) && (ter <= 89))
361 play_sound(47);
362 else if ((pic == 80) || (pic == 76)) // already played in special terrain check
364 else if (pic == 180)
365 play_sound(55);
366 else if (step % 2 == 0)
367 play_sound(49);
368 else play_sound(50);
371 void incidental_noises()