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