rnd-20040928-1-src
[rocksndiamonds.git] / src / game_em / init.c
1 /* 2000-08-10T18:03:54Z
2  *
3  * open X11 display and sound
4  */
5
6 #include <signal.h>
7 #include <sys/wait.h>
8
9 #include "game_em.h"
10
11 #include "global.h"
12 #include "display.h"
13 #include "sample.h"
14
15
16 Bitmap *objBitmap;
17 Bitmap *sprBitmap;
18
19 Bitmap *screenBitmap;
20
21 #if 0
22 Pixmap spriteBitmap;
23 #endif
24
25 Pixmap objPixmap;
26 Pixmap sprPixmap;
27
28 #if 0
29 Pixmap objmaskBitmap;
30 Pixmap sprmaskBitmap;
31
32 GC spriteGC;
33 #endif
34
35 char play[SAMPLE_MAX];
36 int play_x[SAMPLE_MAX];
37 int play_y[SAMPLE_MAX];
38 int play_element[SAMPLE_MAX];
39
40 #if defined(AUDIO_UNIX_NATIVE)
41 static int sound_pid = -1;
42 int sound_pipe[2] = { -1, -1 };         /* for communication */
43 short *sound_data[SAMPLE_MAX];          /* pointer to sound data */
44 long sound_length[SAMPLE_MAX];          /* length of sound data */
45
46 static boolean use_native_em_sound = 0;
47
48 static const char *sound_names[SAMPLE_MAX] =
49 {
50   "00.blank.au",
51   "01.roll.au",
52   "02.stone.au",
53   "03.nut.au",
54   "04.crack.au",
55   "05.bug.au",
56   "06.tank.au",
57   "07.android.au",
58   "08.spring.au",
59   "09.slurp.au",
60   "10.eater.au",
61   "11.alien.au",
62   "12.collect.au",
63   "13.diamond.au",
64   "14.squash.au",
65   "14.squash.au",
66   "15.drip.au",
67   "16.push.au",
68   "17.dirt.au",
69   "18.acid.au",
70   "19.ball.au",
71   "20.grow.au",
72   "21.wonder.au",
73   "22.door.au",
74   "23.exit.au",
75   "24.dynamite.au",
76   "25.tick.au",
77   "26.press.au",
78   "27.wheel.au",
79   "28.boom.au",
80   "29.time.au",
81   "30.die.au"
82 };
83 static const int sound_volume[SAMPLE_MAX] =
84 {
85   20,
86   100,
87   100,
88   100,
89   100,
90   20,
91   20,
92   100,
93   100,
94   100,
95   50,
96   100,
97   100,
98   100,
99   100,
100   100,
101   100,
102   100,
103   100,
104   100,
105   100,
106   100,
107   20,
108   100,
109   100,
110   100,
111   100,
112   100,
113   20,
114   100,
115   100,
116   100
117 };
118 #endif
119
120 char *progname;
121 char *arg_basedir;
122
123 extern void tab_generate();
124 extern void ulaw_generate();
125
126 int open_all(void)
127 {
128   Bitmap *emc_bitmaps[2];
129 #if 0
130   XGCValues gcValues;
131 #endif
132
133 #if 1
134   SetBitmaps_EM(emc_bitmaps);
135
136   objBitmap = emc_bitmaps[0];
137   sprBitmap = emc_bitmaps[1];
138
139 #if 0
140   objPixmap = emc_bitmaps[0]->drawable;
141   sprPixmap = emc_bitmaps[1]->drawable;
142
143   objmaskBitmap = emc_bitmaps[0]->clip_mask;
144   sprmaskBitmap = emc_bitmaps[1]->clip_mask;
145 #endif
146
147   screenBitmap = CreateBitmap(MAX_BUF_XSIZE * TILEX, MAX_BUF_YSIZE * TILEY,
148                               DEFAULT_DEPTH);
149 #endif
150
151 #if 0
152   spriteBitmap = XCreatePixmap(display, window->drawable, TILEX, TILEY, 1);
153   if (spriteBitmap == 0)
154     Error(ERR_EXIT, "failed to create sprite pixmap for EM engine");
155
156   gcValues.function =
157     objmaskBitmap ? GXcopyInverted : sprmaskBitmap ? GXcopy : GXset;
158   gcValues.graphics_exposures = False;
159   spriteGC = XCreateGC(display, spriteBitmap, GCFunction | GCGraphicsExposures,
160                        &gcValues);
161   if (spriteGC == 0)
162     Error(ERR_EXIT, "failed to create sprite GC for EM engine");
163 #endif
164
165   /* ----------------------------------------------------------------- */
166
167 #if defined(AUDIO_UNIX_NATIVE)
168
169 #if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
170
171   if (use_native_em_sound)
172   {
173     char name[MAXNAME+2];
174     int i;
175
176     for (i = 0; i < SAMPLE_MAX; i++)
177     {
178       name[MAXNAME] = 0;
179
180       if (arg_basedir)
181       {
182         snprintf(name, MAXNAME+2, "%s/%s/%s", arg_basedir, EM_SND_DIR,
183                  sound_names[i]);
184       }
185       else
186       {
187         snprintf(name, MAXNAME+2, "%s/%s", EM_SND_DIR, sound_names[i]);
188       }
189
190       if (name[MAXNAME])
191         Error(ERR_EXIT, "buffer overflow when reading sounds directory");
192
193       if (read_sample(name, &sound_data[i], &sound_length[i]))
194         return(1);
195
196       {
197         short *ptr, *stop;
198         int mult = sound_volume[i] * 65536 / (100 * MIXER_MAX);
199         stop = sound_data[i] + sound_length[i];
200         for (ptr = sound_data[i]; ptr < stop; ptr++)
201           *ptr = (*ptr * mult) / 65536;
202       }
203     }
204
205     if (pipe(sound_pipe) == -1)
206     {
207       Error(ERR_WARN, "unable to create sound pipe for EM engine -- no sound");
208
209       return(1);
210     }
211
212     sound_pid = fork();
213     if (sound_pid == -1)
214     {
215       Error(ERR_WARN, "unable to fork sound thread for EM engine -- no sound");
216
217       return(1);
218     }
219
220     close(sound_pipe[sound_pid == 0]);
221     sound_pipe[sound_pid == 0] = -1;
222     if (sound_pid == 0)
223       _exit(sound_thread());
224
225     signal(SIGPIPE, SIG_IGN); /* dont crash if sound process dies */
226   }
227
228 #endif  /* defined(PLATFORM_LINUX) || defined(PLATFORM_BSD) */
229
230 #endif  /* AUDIO_UNIX_NATIVE */
231
232   return(0);
233 }
234
235 void em_open_all()
236 {
237   /* pre-calculate some data */
238   tab_generate();
239   ulaw_generate();
240
241   progname = "emerald mine";
242
243   if (open_all() != 0)
244     Error(ERR_EXIT, "em_open_all(): open_all() failed");
245
246   game_init_vars();
247 }
248
249 void em_close_all(void)
250 {
251 #if defined(AUDIO_UNIX_NATIVE)
252   int i;
253
254   if (sound_pid != -1)
255   {
256     kill(sound_pid, SIGTERM);
257     waitpid(sound_pid, 0, 0);
258   }
259
260   if (sound_pipe[0] != -1)
261     close(sound_pipe[0]);
262   if (sound_pipe[1] != -1)
263     close(sound_pipe[1]);
264
265   for (i = 0; i < SAMPLE_MAX; i++)
266     if (sound_data[i])
267       free(sound_data[i]);
268 #endif
269
270 #if 0
271   if (spriteGC)
272     XFreeGC(display, spriteGC);
273
274   if (spriteBitmap)
275     XFreePixmap(display, spriteBitmap);
276 #endif
277 }
278
279 /* ---------------------------------------------------------------------- */
280
281 extern unsigned int screen_x;
282 extern unsigned int screen_y;
283
284 void play_element_sound(int x, int y, int sample, int element)
285 {
286 #if 0
287   unsigned int left = screen_x / TILEX;
288   unsigned int top  = screen_y / TILEY;
289
290   if ((x == -1 && y == -1) ||   /* play sound in the middle of the screen */
291       ((unsigned int)(y - top)  <= SCR_FIELDY &&
292        (unsigned int)(x - left) <= SCR_FIELDX))
293 #endif
294   {
295 #if 1
296     PlayLevelSound_EM(x, y, element, sample);
297 #else
298     play[sample] = 1;
299     play_x[sample] = x;
300     play_y[sample] = y;
301     play_element[sample] = element;
302 #endif
303   }
304 }
305
306 void play_sound(int x, int y, int sample)
307 {
308   play_element_sound(x, y, sample, -1);
309 }
310
311 void sound_play(void)
312 {
313   if (!use_native_em_sound)
314   {
315     int i;
316
317 #if 0
318     UpdateEngineValues(screen_x / TILEX, screen_y / TILEY);
319 #endif
320
321     return;
322
323     for (i = 0; i < SAMPLE_MAX; i++)
324       if (play[i])
325         PlayLevelSound_EM(play_x[i], play_y[i], play_element[i], i);
326   }
327
328 #if defined(AUDIO_UNIX_NATIVE)
329   if (use_native_em_sound && sound_pipe[1] != -1)
330   {
331     if (write(sound_pipe[1], &play, sizeof(play)) == -1)
332     {
333       Error(ERR_WARN, "cannot write into pipe to child process -- no sounds");
334
335       if (sound_pipe[0] != -1)
336       {
337         close(sound_pipe[0]);
338         sound_pipe[0] = -1;
339       }
340
341       if (sound_pipe[1] != -1)
342       {
343         close(sound_pipe[1]);
344         sound_pipe[1] = -1;
345       }
346     }
347   }
348
349 #endif
350
351   memset(play, 0, sizeof(play));
352 }