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