3aa8361d4b600888d025b27791889a6f74e270da
[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 #include <signal.h>
9
10
11 Bitmap *objBitmap;
12 Bitmap *sprBitmap;
13
14 Bitmap *screenBitmap;
15
16 #if 0
17 Pixmap spriteBitmap;
18 #endif
19
20 Pixmap objPixmap;
21 Pixmap sprPixmap;
22
23 #if 0
24 Pixmap objmaskBitmap;
25 Pixmap sprmaskBitmap;
26
27 GC spriteGC;
28 #endif
29
30 char play[SAMPLE_MAX];
31 int play_x[SAMPLE_MAX];
32 int play_y[SAMPLE_MAX];
33 int play_element[SAMPLE_MAX];
34
35 static boolean use_native_em_sound = 0;
36
37 struct GlobalInfo_EM global_em_info;
38 struct GameInfo_EM game_em;
39
40 #if defined(AUDIO_UNIX_NATIVE)
41 static int sound_pid = -1;
42 int sound_pipe[2] = { -1, -1 };         /* for communication */
43 short *sound_data[SAMPLE_MAX];          /* pointer to sound data */
44 int sound_length[SAMPLE_MAX];           /* length of sound data */
45
46 static const char *sound_names[SAMPLE_MAX] =
47 {
48   "00.blank.au",
49   "01.roll.au",
50   "02.stone.au",
51   "03.nut.au",
52   "04.crack.au",
53   "05.bug.au",
54   "06.tank.au",
55   "07.android.au",
56   "06.tank.au",         /* android moving */
57   "08.spring.au",
58   "09.slurp.au",
59   "10.eater.au",
60   "10.eater.au",        /* eater eating */
61   "11.alien.au",
62   "12.collect.au",
63   "13.diamond.au",
64   "14.squash.au",
65   "14.squash.au",
66   "15.drip.au",
67   "16.push.au",
68   "17.dirt.au",
69   "18.acid.au",
70   "19.ball.au",
71   "20.grow.au",
72   "21.wonder.au",
73   "22.door.au",
74   "23.exit.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   20,
95   100,
96   100,
97   50,
98   50,
99   100,
100   100,
101   100,
102   100,
103   100,
104   100,
105   100,
106   100,
107   100,
108   100,
109   100,
110   20,
111   100,
112   100,
113   100,
114   100,
115   100,
116   100,
117   20,
118   100,
119   100,
120   100
121 };
122 #endif
123
124 char *progname;
125 char *arg_basedir;
126
127 extern void tab_generate();
128 extern void tab_generate_graphics_info_em();
129 extern void ulaw_generate();
130
131 int open_all(void)
132 {
133   Bitmap *emc_bitmaps[2];
134 #if 0
135   XGCValues gcValues;
136 #endif
137
138 #if 1
139   SetBitmaps_EM(emc_bitmaps);
140
141   objBitmap = emc_bitmaps[0];
142   sprBitmap = emc_bitmaps[1];
143
144 #if 0
145   objPixmap = emc_bitmaps[0]->drawable;
146   sprPixmap = emc_bitmaps[1]->drawable;
147
148   objmaskBitmap = emc_bitmaps[0]->clip_mask;
149   sprmaskBitmap = emc_bitmaps[1]->clip_mask;
150 #endif
151
152 #if 0
153   printf("::: CreateBitmap: %d, %d => %d\n",
154          MAX_BUF_XSIZE, TILEX, MAX_BUF_XSIZE * TILEX);
155
156   screenBitmap = CreateBitmap(MAX_BUF_XSIZE * TILEX, MAX_BUF_YSIZE * TILEY,
157                               DEFAULT_DEPTH);
158
159   global_em_info.screenbuffer = screenBitmap;
160 #endif
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 InitGfxBuffers_EM()
249 {
250
251 #if 1
252
253 #if 0
254   printf("::: InitGfxBuffers_EM: %d, %d => %d\n",
255          MAX_BUF_XSIZE, TILEX, MAX_BUF_XSIZE * TILEX);
256 #endif
257
258   ReCreateBitmap(&screenBitmap, MAX_BUF_XSIZE * TILEX, MAX_BUF_YSIZE * TILEY,
259                  DEFAULT_DEPTH);
260
261   global_em_info.screenbuffer = screenBitmap;
262
263 #else
264
265   printf("::: CreateBitmap: %d, %d => %d\n",
266          MAX_BUF_XSIZE, TILEX, MAX_BUF_XSIZE * TILEX);
267
268   screenBitmap = CreateBitmap(MAX_BUF_XSIZE * TILEX, MAX_BUF_YSIZE * TILEY,
269                               DEFAULT_DEPTH);
270
271   global_em_info.screenbuffer = screenBitmap;
272 #endif
273 }
274
275 void em_open_all()
276 {
277   /* pre-calculate some data */
278   tab_generate();
279 #if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
280   ulaw_generate();
281 #endif
282
283   progname = "emerald mine";
284
285   if (open_all() != 0)
286     Error(ERR_EXIT, "em_open_all(): open_all() failed");
287
288   /* after "open_all()", because we need the graphic bitmaps to be defined */
289   tab_generate_graphics_info_em();
290
291   game_init_vars();
292 }
293
294 void em_close_all(void)
295 {
296 #if defined(AUDIO_UNIX_NATIVE)
297   int i;
298
299   if (sound_pid != -1)
300   {
301     kill(sound_pid, SIGTERM);
302     waitpid(sound_pid, 0, 0);
303   }
304
305   if (sound_pipe[0] != -1)
306     close(sound_pipe[0]);
307   if (sound_pipe[1] != -1)
308     close(sound_pipe[1]);
309
310   for (i = 0; i < SAMPLE_MAX; i++)
311     if (sound_data[i])
312       free(sound_data[i]);
313 #endif
314
315 #if 0
316   if (spriteGC)
317     XFreeGC(display, spriteGC);
318
319   if (spriteBitmap)
320     XFreePixmap(display, spriteBitmap);
321 #endif
322 }
323
324 /* ---------------------------------------------------------------------- */
325
326 extern int screen_x;
327 extern int screen_y;
328
329 void play_element_sound(int x, int y, int sample, int element)
330 {
331 #if 0
332   int left = screen_x / TILEX;
333   int top  = screen_y / TILEY;
334
335   if ((x == -1 && y == -1) ||   /* play sound in the middle of the screen */
336       ((int)(y - top)  <= SCR_FIELDY &&
337        (int)(x - left) <= SCR_FIELDX))
338 #endif
339   {
340 #if 1
341     PlayLevelSound_EM(x, y, element, sample);
342 #else
343     play[sample] = 1;
344     play_x[sample] = x;
345     play_y[sample] = y;
346     play_element[sample] = element;
347 #endif
348   }
349 }
350
351 void play_sound(int x, int y, int sample)
352 {
353   play_element_sound(x, y, sample, -1);
354 }
355
356 void sound_play(void)
357 {
358   if (!use_native_em_sound)
359   {
360     int i;
361
362 #if 0
363     UpdateEngineValues(screen_x / TILEX, screen_y / TILEY);
364 #endif
365
366     return;
367
368     for (i = 0; i < SAMPLE_MAX; i++)
369       if (play[i])
370         PlayLevelSound_EM(play_x[i], play_y[i], play_element[i], i);
371   }
372
373 #if defined(AUDIO_UNIX_NATIVE)
374   if (use_native_em_sound && sound_pipe[1] != -1)
375   {
376     if (write(sound_pipe[1], &play, sizeof(play)) == -1)
377     {
378       Error(ERR_WARN, "cannot write into pipe to child process -- no sounds");
379
380       if (sound_pipe[0] != -1)
381       {
382         close(sound_pipe[0]);
383         sound_pipe[0] = -1;
384       }
385
386       if (sound_pipe[1] != -1)
387       {
388         close(sound_pipe[1]);
389         sound_pipe[1] = -1;
390       }
391     }
392   }
393
394 #endif
395
396   clear_mem(play, sizeof(play));
397 }
398
399 unsigned int InitEngineRandom_EM(int seed)
400 {
401   if (seed == NEW_RANDOMIZE)
402   {
403     int simple_rnd = GetSimpleRandom(1000);
404     int i;
405
406     for (i = 0; i < simple_rnd || RandomEM == NEW_RANDOMIZE; i++)
407       RandomEM = RandomEM * 129 + 1;
408
409     seed = RandomEM;
410   }
411
412   RandomEM = seed;
413
414   return (unsigned int) seed;
415 }