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