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