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