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