rnd-20060319-2-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 long 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   screenBitmap = CreateBitmap(MAX_BUF_XSIZE * TILEX, MAX_BUF_YSIZE * TILEY,
158                               DEFAULT_DEPTH);
159
160   global_em_info.screenbuffer = screenBitmap;
161
162 #endif
163
164 #if 0
165   spriteBitmap = XCreatePixmap(display, window->drawable, TILEX, TILEY, 1);
166   if (spriteBitmap == 0)
167     Error(ERR_EXIT, "failed to create sprite pixmap for EM engine");
168
169   gcValues.function =
170     objmaskBitmap ? GXcopyInverted : sprmaskBitmap ? GXcopy : GXset;
171   gcValues.graphics_exposures = False;
172   spriteGC = XCreateGC(display, spriteBitmap, GCFunction | GCGraphicsExposures,
173                        &gcValues);
174   if (spriteGC == 0)
175     Error(ERR_EXIT, "failed to create sprite GC for EM engine");
176 #endif
177
178   /* ----------------------------------------------------------------- */
179
180 #if defined(AUDIO_UNIX_NATIVE)
181
182 #if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
183
184   if (use_native_em_sound)
185   {
186     char name[MAXNAME+2];
187     int i;
188
189     for (i = 0; i < SAMPLE_MAX; i++)
190     {
191       name[MAXNAME] = 0;
192
193       if (arg_basedir)
194       {
195         snprintf(name, MAXNAME+2, "%s/%s/%s", arg_basedir, EM_SND_DIR,
196                  sound_names[i]);
197       }
198       else
199       {
200         snprintf(name, MAXNAME+2, "%s/%s", EM_SND_DIR, sound_names[i]);
201       }
202
203       if (name[MAXNAME])
204         Error(ERR_EXIT, "buffer overflow when reading sounds directory");
205
206       if (read_sample(name, &sound_data[i], &sound_length[i]))
207         return(1);
208
209       {
210         short *ptr, *stop;
211         int mult = sound_volume[i] * 65536 / (100 * MIXER_MAX);
212         stop = sound_data[i] + sound_length[i];
213         for (ptr = sound_data[i]; ptr < stop; ptr++)
214           *ptr = (*ptr * mult) / 65536;
215       }
216     }
217
218     if (pipe(sound_pipe) == -1)
219     {
220       Error(ERR_WARN, "unable to create sound pipe for EM engine -- no sound");
221
222       return(1);
223     }
224
225     sound_pid = fork();
226     if (sound_pid == -1)
227     {
228       Error(ERR_WARN, "unable to fork sound thread for EM engine -- no sound");
229
230       return(1);
231     }
232
233     close(sound_pipe[sound_pid == 0]);
234     sound_pipe[sound_pid == 0] = -1;
235     if (sound_pid == 0)
236       _exit(sound_thread());
237
238     signal(SIGPIPE, SIG_IGN); /* dont crash if sound process dies */
239   }
240
241 #endif  /* defined(PLATFORM_LINUX) || defined(PLATFORM_BSD) */
242
243 #endif  /* AUDIO_UNIX_NATIVE */
244
245   return(0);
246 }
247
248 void em_open_all()
249 {
250   /* pre-calculate some data */
251   tab_generate();
252 #if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
253   ulaw_generate();
254 #endif
255
256   progname = "emerald mine";
257
258   if (open_all() != 0)
259     Error(ERR_EXIT, "em_open_all(): open_all() failed");
260
261   /* after "open_all()", because we need the graphic bitmaps to be defined */
262   tab_generate_graphics_info_em();
263
264   game_init_vars();
265 }
266
267 void em_close_all(void)
268 {
269 #if defined(AUDIO_UNIX_NATIVE)
270   int i;
271
272   if (sound_pid != -1)
273   {
274     kill(sound_pid, SIGTERM);
275     waitpid(sound_pid, 0, 0);
276   }
277
278   if (sound_pipe[0] != -1)
279     close(sound_pipe[0]);
280   if (sound_pipe[1] != -1)
281     close(sound_pipe[1]);
282
283   for (i = 0; i < SAMPLE_MAX; i++)
284     if (sound_data[i])
285       free(sound_data[i]);
286 #endif
287
288 #if 0
289   if (spriteGC)
290     XFreeGC(display, spriteGC);
291
292   if (spriteBitmap)
293     XFreePixmap(display, spriteBitmap);
294 #endif
295 }
296
297 /* ---------------------------------------------------------------------- */
298
299 extern int screen_x;
300 extern int screen_y;
301
302 void play_element_sound(int x, int y, int sample, int element)
303 {
304 #if 0
305   int left = screen_x / TILEX;
306   int top  = screen_y / TILEY;
307
308   if ((x == -1 && y == -1) ||   /* play sound in the middle of the screen */
309       ((int)(y - top)  <= SCR_FIELDY &&
310        (int)(x - left) <= SCR_FIELDX))
311 #endif
312   {
313 #if 1
314     PlayLevelSound_EM(x, y, element, sample);
315 #else
316     play[sample] = 1;
317     play_x[sample] = x;
318     play_y[sample] = y;
319     play_element[sample] = element;
320 #endif
321   }
322 }
323
324 void play_sound(int x, int y, int sample)
325 {
326   play_element_sound(x, y, sample, -1);
327 }
328
329 void sound_play(void)
330 {
331   if (!use_native_em_sound)
332   {
333     int i;
334
335 #if 0
336     UpdateEngineValues(screen_x / TILEX, screen_y / TILEY);
337 #endif
338
339     return;
340
341     for (i = 0; i < SAMPLE_MAX; i++)
342       if (play[i])
343         PlayLevelSound_EM(play_x[i], play_y[i], play_element[i], i);
344   }
345
346 #if defined(AUDIO_UNIX_NATIVE)
347   if (use_native_em_sound && sound_pipe[1] != -1)
348   {
349     if (write(sound_pipe[1], &play, sizeof(play)) == -1)
350     {
351       Error(ERR_WARN, "cannot write into pipe to child process -- no sounds");
352
353       if (sound_pipe[0] != -1)
354       {
355         close(sound_pipe[0]);
356         sound_pipe[0] = -1;
357       }
358
359       if (sound_pipe[1] != -1)
360       {
361         close(sound_pipe[1]);
362         sound_pipe[1] = -1;
363       }
364     }
365   }
366
367 #endif
368
369   memset(play, 0, sizeof(play));
370 }
371
372 unsigned int InitEngineRND_EM(long seed)
373 {
374   if (seed == NEW_RANDOMIZE)
375   {
376     int simple_rnd = SimpleRND(1000);
377     int i;
378
379     for (i = 0; i < simple_rnd || RandomEM == NEW_RANDOMIZE; i++)
380       RandomEM = RandomEM * 129 + 1;
381
382     seed = RandomEM;
383   }
384
385   RandomEM = seed;
386
387   return (unsigned int) seed;
388 }