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