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