251d32d64d6dd4efbb967486b22acd84cecd146a
[rocksndiamonds.git] / src / init.c
1 /***********************************************************
2 *  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
3 *----------------------------------------------------------*
4 *  ©1995 Artsoft Development                               *
5 *        Holger Schemel                                    *
6 *        33659 Bielefeld-Senne                             *
7 *        Telefon: (0521) 493245                            *
8 *        eMail: aeglos@valinor.owl.de                      *
9 *               aeglos@uni-paderborn.de                    *
10 *               q99492@pbhrzx.uni-paderborn.de             *
11 *----------------------------------------------------------*
12 *  init.c                                                  *
13 ***********************************************************/
14
15 #include "init.h"
16 #include "misc.h"
17 #include "sound.h"
18 #include "screens.h"
19 #include "files.h"
20 #include <signal.h>
21
22 static int sound_process_id = 0;
23
24 void OpenAll(int argc, char *argv[])
25 {
26   InitLevelAndPlayerInfo();
27
28   InitCounter();
29   InitSound();
30   InitSoundProcess();
31   InitJoystick();
32   InitRND(NEW_RANDOMIZE);
33
34   signal(SIGINT, CloseAll);
35   signal(SIGTERM, CloseAll);
36
37   InitDisplay(argc, argv);
38   InitWindow(argc, argv);
39   InitGfx();
40   InitElementProperties();
41
42   DrawMainMenu();
43
44   XMapWindow(display, window);
45   XFlush(display);
46 }
47
48 void InitLevelAndPlayerInfo()
49 {
50   if (!LoadLevelInfo())                 /* global level info */
51     CloseAll();
52
53   LoadPlayerInfo(PLAYER_SETUP);         /* global setup info */
54   LoadPlayerInfo(PLAYER_LEVEL);         /* level specific info */
55 }
56
57 void InitSound()
58 {
59   int i;
60
61   if (sound_status==SOUND_OFF)
62     return;
63
64   if (access(sound_device_name,W_OK)<0)
65   {
66     fprintf(stderr,"%s: cannot access sound device - no sounds\n",progname);
67     sound_status=SOUND_OFF;
68     return;
69   }
70
71   if ((sound_device=open(sound_device_name,O_WRONLY))<0)
72   {
73     fprintf(stderr,"%s: cannot open sound device - no sounds\n",progname);
74     sound_status=SOUND_OFF;
75     return;
76   }
77
78   close(sound_device);
79   sound_status=SOUND_AVAILABLE;
80
81 #ifdef VOXWARE
82   sound_loops_allowed = TRUE;
83   sound_loops_on = TRUE;
84 #endif
85
86   for(i=0;i<NUM_SOUNDS;i++)
87   {
88     Sound[i].name = sound_name[i];
89     if (!LoadSound(&Sound[i]))
90     {
91       sound_status=SOUND_OFF;
92       return;
93     }
94   }
95 }
96
97 void InitSoundProcess()
98 {
99   if (sound_status==SOUND_OFF)
100     return;
101
102   if (pipe(sound_pipe)<0)
103   {
104     fprintf(stderr,"%s: cannot create pipe - no sounds\n",progname);
105     sound_status=SOUND_OFF;
106     return;
107   }
108
109   if ((sound_process_id=fork())<0)
110   {       
111     fprintf(stderr,"%s: cannot create child process - no sounds\n",progname);
112     sound_status=SOUND_OFF;
113     return;
114   }
115
116   if (!sound_process_id)        /* we are child */
117     SoundServer();
118   else                          /* we are parent */
119     close(sound_pipe[0]);       /* no reading from pipe needed */
120 }
121
122 void InitJoystick()
123 {
124   if (global_joystick_status==JOYSTICK_OFF)
125     return;
126
127   if (access(joystick_device_name[joystick_nr],R_OK)<0)
128   {
129     fprintf(stderr,"%s: cannot access joystick device '%s'\n",
130             progname,joystick_device_name[joystick_nr]);
131     joystick_status = JOYSTICK_OFF;
132     return;
133   }
134
135   if ((joystick_device=open(joystick_device_name[joystick_nr],O_RDONLY))<0)
136   {
137     fprintf(stderr,"%s: cannot open joystick device '%s'\n",
138             progname,joystick_device_name[joystick_nr]);
139     joystick_status = JOYSTICK_OFF;
140     return;
141   }
142
143   joystick_status = JOYSTICK_AVAILABLE;
144   LoadJoystickData();
145 }
146
147 void InitDisplay(int argc, char *argv[])
148 {
149   char *display_name = NULL;
150   int i;
151
152   /* get X server to connect to, if given as an argument */
153   for (i=1;i<argc-1;i++)
154   {
155     char *dispstr="-display";
156     int len=MAX(strlen(dispstr),strlen(argv[i]));
157
158     if (len<4)
159       continue;
160     else if (!strncmp(argv[i],dispstr,len))
161     {
162       display_name=argv[i+1];
163       break;
164     }
165   }
166
167   /* connect to X server */
168   if (!(display=XOpenDisplay(display_name)))
169   {
170     fprintf(stderr,"%s: cannot connect to X server %s\n", 
171             progname, XDisplayName(display_name));
172     exit(-1);
173   }
174   
175   screen = DefaultScreen(display);
176   cmap   = DefaultColormap(display, screen);
177   pen_fg = WhitePixel(display,screen);
178   pen_bg = BlackPixel(display,screen);
179 }
180
181 void InitWindow(int argc, char *argv[])
182 {
183   unsigned int border_width = 4;
184   Pixmap icon_pixmap, iconmask_pixmap;
185   unsigned int icon_width,icon_height;
186   int icon_hot_x,icon_hot_y;
187   char icon_filename[256];
188   XSizeHints size_hints;
189   XWMHints wm_hints;
190   XClassHint class_hints;
191   XTextProperty windowName, iconName;
192   XGCValues gc_values;
193   unsigned long gc_valuemask;
194   char *window_name = "Rocks'n'Diamonds";
195   char *icon_name = "Rocks'n'Diamonds";
196   long window_event_mask;
197   static struct PictureFile icon_pic =
198   {
199     "rocks_icon.xbm",
200     "rocks_iconmask.xbm"
201   };
202
203   width = WIN_XSIZE;
204   height = WIN_YSIZE;
205
206   window = XCreateSimpleWindow(display, RootWindow(display, screen),
207                             WIN_XPOS, WIN_YPOS, width, height, border_width,
208                             pen_fg, pen_bg);
209
210   sprintf(icon_filename,"%s/%s",GFX_PATH,icon_pic.picture_filename);
211   XReadBitmapFile(display,window,icon_filename,
212                   &icon_width,&icon_height,
213                   &icon_pixmap,&icon_hot_x,&icon_hot_y);
214   if (!icon_pixmap)
215   {
216     fprintf(stderr, "%s: cannot read icon bitmap file '%s'.\n",
217             progname,icon_filename);
218     exit(-1);
219   }
220
221   sprintf(icon_filename,"%s/%s",GFX_PATH,icon_pic.picturemask_filename);
222   XReadBitmapFile(display,window,icon_filename,
223                   &icon_width,&icon_height,
224                   &iconmask_pixmap,&icon_hot_x,&icon_hot_y);
225   if (!iconmask_pixmap)
226   {
227     fprintf(stderr, "%s: cannot read icon bitmap file '%s'.\n",
228             progname,icon_filename);
229     exit(-1);
230   }
231
232   size_hints.flags = PSize | PMinSize | PMaxSize;
233   size_hints.width  = size_hints.min_width  = size_hints.max_width  = width;
234   size_hints.height = size_hints.min_height = size_hints.max_height = height;
235
236   if (!XStringListToTextProperty(&window_name, 1, &windowName))
237   {
238     fprintf(stderr, "%s: structure allocation for windowName failed.\n",
239             progname);
240     exit(-1);
241   }
242
243   if (!XStringListToTextProperty(&icon_name, 1, &iconName))
244   {
245     fprintf(stderr, "%s: structure allocation for iconName failed.\n",
246             progname);
247     exit(-1);
248   }
249
250   wm_hints.initial_state = NormalState;
251   wm_hints.input = True;
252   wm_hints.icon_pixmap = icon_pixmap;
253   wm_hints.icon_mask = iconmask_pixmap;
254   wm_hints.flags = StateHint | IconPixmapHint | IconMaskHint | InputHint;
255
256   class_hints.res_name = progname;
257   class_hints.res_class = "Rocks'n'Diamonds";
258
259   XSetWMProperties(display, window, &windowName, &iconName, 
260                    argv, argc, &size_hints, &wm_hints, 
261                    &class_hints);
262
263   XFree(windowName.value);
264   XFree(iconName.value);
265
266   /* Select event types wanted */
267   window_event_mask = ExposureMask | StructureNotifyMask | FocusChangeMask |
268                       ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
269                       KeyPressMask | KeyReleaseMask;
270   XSelectInput(display, window, window_event_mask);
271
272   /* create GC for drawing with window depth */
273   gc_values.graphics_exposures = False;
274   gc_values.foreground = pen_bg;
275   gc_values.background = pen_bg;
276   gc_valuemask = GCGraphicsExposures | GCForeground | GCBackground;
277   gc = XCreateGC(display, window, gc_valuemask, &gc_values);
278 }
279
280 void InitGfx()
281 {
282   int i,j,x,y;
283   int xpm_err, xbm_err;
284   unsigned int width,height;
285   int hot_x,hot_y;
286   XGCValues gc_values;
287   unsigned long gc_valuemask;
288   XGCValues clip_gc_values;
289   unsigned long clip_gc_valuemask;
290   char filename[256];
291   Pixmap shapemask;
292
293   static struct PictureFile pic[NUM_PICTURES] =
294   {
295     "RocksScreen.xpm",          "RocksScreenMaske.xbm",
296     "RocksDoor.xpm",            "RocksDoorMaske.xbm",
297     "RocksToons.xpm",           "RocksToonsMaske.xbm",
298     "RocksFont.xpm",            NULL,
299     "RocksFont2.xpm",           NULL
300   }; 
301
302   for(i=0;i<NUM_PICTURES;i++)
303   {
304     if (pic[i].picture_filename)
305     {
306       sprintf(filename,"%s/%s",GFX_PATH,pic[i].picture_filename);
307
308       xpm_att[i].valuemask = XpmCloseness;
309       xpm_att[i].closeness = 20000;
310       xpm_err = XpmReadFileToPixmap(display,window,filename,
311                                     &pix[i],&shapemask,&xpm_att[i]);
312       switch(xpm_err)
313       {
314         case XpmOpenFailed:
315           fprintf(stderr,"Xpm file open failed on '%s' !\n",filename);
316           CloseAll();
317           exit(-1);
318         case XpmFileInvalid:
319           fprintf(stderr,"Invalid Xpm file '%s'!\n",filename);
320           CloseAll();
321           exit(-1);
322         case XpmNoMemory:
323           fprintf(stderr,"Not enough memory !\n");      
324           CloseAll();
325           exit(1);
326         case XpmColorFailed:
327           fprintf(stderr,"Can`t get any colors...\n");
328           CloseAll();
329           exit(-1);
330         default:
331           break;
332       }
333       if (!pix[i])
334       {
335         fprintf(stderr, "%s: cannot read Xpm file '%s'.\n",
336                 progname,filename);
337         CloseAll();
338         exit(-1);
339       }
340     }
341
342     if (pic[i].picturemask_filename)
343     {
344       sprintf(filename,"%s/%s",GFX_PATH,pic[i].picturemask_filename);
345
346       xbm_err = XReadBitmapFile(display,window,filename,
347                                 &width,&height,&clipmask[i],&hot_x,&hot_y);
348       switch(xbm_err)
349       {
350         case BitmapSuccess:
351           break;
352         case BitmapOpenFailed:
353           fprintf(stderr,"Bitmap file open failed on '%s' !\n",filename);
354           CloseAll();
355           exit(-1);
356           break;
357         case BitmapFileInvalid:
358           fprintf(stderr,"Bitmap file invalid: '%s' !\n",filename);
359           CloseAll();
360           exit(-1);
361           break;
362         case BitmapNoMemory:
363           fprintf(stderr,"No memory for file '%s' !\n",filename);
364           CloseAll();
365           exit(-1);
366           break;
367         default:
368           break;
369       }
370       if (!clipmask[i])
371       {
372         fprintf(stderr, "%s: cannot read X11 bitmap file '%s'.\n",
373                 progname,filename);
374         CloseAll();
375         exit(-1);
376       }
377     }
378   }
379
380   pix[PIX_DB_BACK] = XCreatePixmap(display, window,
381                                    WIN_XSIZE,WIN_YSIZE,
382                                    XDefaultDepth(display,screen));
383   pix[PIX_DB_DOOR] = XCreatePixmap(display, window,
384                                    3*DXSIZE,DYSIZE+VYSIZE,
385                                    XDefaultDepth(display,screen));
386
387   clipmask[PIX_FADEMASK] = XCreatePixmap(display, window,
388                                          SXSIZE+TILEX,SYSIZE+TILEY,1);
389
390   if (!pix[PIX_DB_BACK] || !pix[PIX_DB_DOOR] || !clipmask[PIX_FADEMASK])
391   {
392     fprintf(stderr, "%s: cannot create additional Pixmaps!\n",progname);
393     CloseAll();
394     exit(-1);
395   }
396
397   /* create GC for drawing with bitplane depth */
398   gc_values.graphics_exposures = False;
399   gc_values.foreground = pen_bg;
400   gc_values.background = pen_bg;
401   gc_valuemask = GCGraphicsExposures | GCForeground | GCBackground;
402   plane_gc = XCreateGC(display, clipmask[PIX_BACK], gc_valuemask, &gc_values);
403
404   for(y=0;y<=SCR_FIELDY;y++) for(x=0;x<=SCR_FIELDX;x++)
405     XCopyArea(display,clipmask[PIX_BACK],clipmask[PIX_FADEMASK],plane_gc,
406               SX+2*TILEX,SY+10*TILEY,TILEX,TILEY,x*TILEX,y*TILEY);
407
408   for(i=0;i<NUM_PIXMAPS;i++)
409   {
410     if (clipmask[i])
411     {
412       clip_gc_values.graphics_exposures = False;
413       clip_gc_values.foreground = pen_fg;
414       clip_gc_values.background = pen_bg;
415       clip_gc_values.clip_mask = clipmask[i];
416       clip_gc_valuemask =
417         GCGraphicsExposures | GCForeground | GCBackground | GCClipMask;
418       clip_gc[i] = XCreateGC(display,window,clip_gc_valuemask,&clip_gc_values);
419     }
420   }
421
422   drawto = drawto_field = backbuffer = pix[PIX_DB_BACK];
423
424   XCopyArea(display,pix[PIX_BACK],backbuffer,gc,
425             0,0, WIN_XSIZE,WIN_YSIZE, 0,0);
426   XFillRectangle(display,backbuffer,gc,
427                  REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
428
429   for(i=0;i<SCR_FIELDX;i++)
430     for(j=0;j<SCR_FIELDY;j++)
431       redraw[i][j]=0;
432   redraw_tiles=0;
433   redraw_mask=REDRAW_ALL;
434 }
435
436 void InitElementProperties()
437 {
438   int i,j;
439
440   static int ep_amoebalive[] =
441   {
442     EL_AMOEBE_NASS,
443     EL_AMOEBE_NORM,
444     EL_AMOEBE_VOLL
445   };
446   static int ep_amoebalive_num = sizeof(ep_amoebalive)/sizeof(int);
447
448   static int ep_amoeboid[] =
449   {
450     EL_AMOEBE_TOT,
451     EL_AMOEBE_NASS,
452     EL_AMOEBE_NORM,
453     EL_AMOEBE_VOLL
454   };
455   static int ep_amoeboid_num = sizeof(ep_amoeboid)/sizeof(int);
456
457   static int ep_badewannoid[] =
458   {
459     EL_BADEWANNE1,
460     EL_BADEWANNE2,
461     EL_BADEWANNE3,
462     EL_BADEWANNE4,
463     EL_BADEWANNE5
464   };
465   static int ep_badewannoid_num = sizeof(ep_badewannoid)/sizeof(int);
466
467   static int ep_schluessel[] =
468   {
469     EL_SCHLUESSEL1,
470     EL_SCHLUESSEL2,
471     EL_SCHLUESSEL3,
472     EL_SCHLUESSEL4
473   };
474   static int ep_schluessel_num = sizeof(ep_schluessel)/sizeof(int);
475
476   static int ep_pforte[] =
477   {
478     EL_PFORTE1,
479     EL_PFORTE2,
480     EL_PFORTE3,
481     EL_PFORTE4,
482     EL_PFORTE1X,
483     EL_PFORTE2X,
484     EL_PFORTE3X,
485     EL_PFORTE4X
486   };
487   static int ep_pforte_num = sizeof(ep_pforte)/sizeof(int);
488
489   static int ep_solid[] =
490   {
491     EL_BETON,
492     EL_MAUERWERK,
493     EL_MAUER_LEBT,
494     EL_FELSBODEN,
495     EL_AUSGANG_ZU,
496     EL_AUSGANG_ACT,
497     EL_AUSGANG_AUF,
498     EL_AMOEBE_TOT,
499     EL_AMOEBE_NASS,
500     EL_AMOEBE_NORM,
501     EL_AMOEBE_VOLL,
502     EL_MORAST_VOLL,
503     EL_MORAST_LEER,
504     EL_SIEB_VOLL,
505     EL_SIEB_LEER,
506     EL_SIEB_TOT,
507     EL_SIEB2_VOLL,
508     EL_SIEB2_LEER,
509     EL_SIEB2_TOT,
510     EL_LIFE,
511     EL_LIFE_ASYNC,
512     EL_BADEWANNE1,
513     EL_BADEWANNE2,
514     EL_BADEWANNE3,
515     EL_BADEWANNE4,
516     EL_BADEWANNE5
517   };
518   static int ep_solid_num = sizeof(ep_solid)/sizeof(int);
519
520   static int ep_massiv[] =
521   {
522     EL_BETON,
523     EL_SALZSAEURE,
524     EL_BADEWANNE1,
525     EL_BADEWANNE2,
526     EL_BADEWANNE3,
527     EL_BADEWANNE4,
528     EL_BADEWANNE5,
529     EL_PFORTE1,
530     EL_PFORTE2,
531     EL_PFORTE3,
532     EL_PFORTE4,
533     EL_PFORTE1X,
534     EL_PFORTE2X,
535     EL_PFORTE3X,
536     EL_PFORTE4X
537   };
538   static int ep_massiv_num = sizeof(ep_massiv)/sizeof(int);
539
540   static int ep_slippery[] =
541   {
542     EL_FELSBODEN,
543     EL_FELSBROCKEN,
544     EL_EDELSTEIN,
545     EL_EDELSTEIN2,
546     EL_EDELSTEIN3,
547     EL_DIAMANT,
548     EL_BOMBE,
549     EL_KOKOSNUSS,
550     EL_ABLENK_EIN,
551     EL_ABLENK_AUS,
552     EL_ZEIT_VOLL,
553     EL_ZEIT_LEER,
554     EL_BIRNE_EIN,
555     EL_BIRNE_AUS,
556     EL_BADEWANNE1,
557     EL_BADEWANNE2
558   };
559   static int ep_slippery_num = sizeof(ep_slippery)/sizeof(int);
560
561   static int ep_enemy[] =
562   {
563     EL_KAEFER,
564     EL_FLIEGER,
565     EL_MAMPFER,
566     EL_MAMPFER2,
567     EL_ZOMBIE,
568     EL_PACMAN
569   };
570   static int ep_enemy_num = sizeof(ep_enemy)/sizeof(int);
571
572   static int ep_mauer[] =
573   {
574     EL_BETON,
575     EL_PFORTE1,
576     EL_PFORTE2,
577     EL_PFORTE3,
578     EL_PFORTE4,
579     EL_PFORTE1X,
580     EL_PFORTE2X,
581     EL_PFORTE3X,
582     EL_PFORTE4X,
583     EL_AUSGANG_ZU,
584     EL_AUSGANG_ACT,
585     EL_AUSGANG_AUF,
586     EL_MAUERWERK,
587     EL_FELSBODEN,
588     EL_MAUER_LEBT,
589     EL_MAUERND
590   };
591   static int ep_mauer_num = sizeof(ep_mauer)/sizeof(int);
592
593   static int ep_can_fall[] =
594   {
595     EL_FELSBROCKEN,
596     EL_EDELSTEIN,
597     EL_EDELSTEIN2,
598     EL_EDELSTEIN3,
599     EL_DIAMANT,
600     EL_BOMBE,
601     EL_KOKOSNUSS,
602     EL_TROPFEN,
603     EL_MORAST_VOLL,
604     EL_SIEB_VOLL,
605     EL_SIEB2_VOLL,
606     EL_ZEIT_VOLL,
607     EL_ZEIT_LEER
608   };
609   static int ep_can_fall_num = sizeof(ep_can_fall)/sizeof(int);
610
611   static int ep_can_smash[] =
612   {
613     EL_FELSBROCKEN,
614     EL_EDELSTEIN,
615     EL_EDELSTEIN2,
616     EL_EDELSTEIN3,
617     EL_DIAMANT,
618     EL_SCHLUESSEL1,
619     EL_SCHLUESSEL2,
620     EL_SCHLUESSEL3,
621     EL_SCHLUESSEL4,
622     EL_BOMBE,
623     EL_KOKOSNUSS,
624     EL_TROPFEN,
625     EL_ZEIT_VOLL,
626     EL_ZEIT_LEER
627   };
628   static int ep_can_smash_num = sizeof(ep_can_smash)/sizeof(int);
629
630   static int ep_can_change[] =
631   {
632     EL_FELSBROCKEN,
633     EL_EDELSTEIN,
634     EL_EDELSTEIN2,
635     EL_EDELSTEIN3,
636     EL_DIAMANT
637   };
638   static int ep_can_change_num = sizeof(ep_can_change)/sizeof(int);
639
640   static int ep_can_move[] =
641   {
642     EL_KAEFER,
643     EL_FLIEGER,
644     EL_MAMPFER,
645     EL_MAMPFER2,
646     EL_ZOMBIE,
647     EL_PACMAN
648   };
649   static int ep_can_move_num = sizeof(ep_can_move)/sizeof(int);
650
651   static int ep_could_move[] =
652   {
653     EL_KAEFER_R,
654     EL_KAEFER_O,
655     EL_KAEFER_L,
656     EL_KAEFER_U,
657     EL_FLIEGER_R,
658     EL_FLIEGER_O,
659     EL_FLIEGER_L,
660     EL_FLIEGER_U,
661     EL_PACMAN_R,
662     EL_PACMAN_O,
663     EL_PACMAN_L,
664     EL_PACMAN_U
665   };
666   static int ep_could_move_num = sizeof(ep_could_move)/sizeof(int);
667
668   static int ep_dont_touch[] =
669   {
670     EL_KAEFER,
671     EL_FLIEGER
672   };
673   static int ep_dont_touch_num = sizeof(ep_dont_touch)/sizeof(int);
674
675   static int ep_dont_go_to[] =
676   {
677     EL_KAEFER,
678     EL_FLIEGER,
679     EL_MAMPFER,
680     EL_MAMPFER2,
681     EL_ZOMBIE,
682     EL_PACMAN,
683     EL_TROPFEN,
684     EL_SALZSAEURE
685   };
686   static int ep_dont_go_to_num = sizeof(ep_dont_go_to)/sizeof(int);
687
688   static int ep_mampf2[] =
689   {
690     EL_ERDREICH,
691     EL_KAEFER,
692     EL_FLIEGER,
693     EL_MAMPFER,
694     EL_ZOMBIE,
695     EL_PACMAN,
696     EL_TROPFEN,
697     EL_AMOEBE_TOT,
698     EL_AMOEBE_NASS,
699     EL_AMOEBE_NORM,
700     EL_AMOEBE_VOLL,
701     EL_EDELSTEIN,
702     EL_EDELSTEIN2,
703     EL_EDELSTEIN3,
704     EL_DIAMANT
705   };
706   static int ep_mampf2_num = sizeof(ep_mampf2)/sizeof(int);
707
708   static long ep_bit[] =
709   {
710     EP_BIT_AMOEBALIVE,
711     EP_BIT_AMOEBOID,
712     EP_BIT_BADEWANNOID,
713     EP_BIT_SCHLUESSEL,
714     EP_BIT_PFORTE,
715     EP_BIT_SOLID,
716     EP_BIT_MASSIV,
717     EP_BIT_SLIPPERY,
718     EP_BIT_ENEMY,
719     EP_BIT_MAUER,
720     EP_BIT_CAN_FALL,
721     EP_BIT_CAN_SMASH,
722     EP_BIT_CAN_CHANGE,
723     EP_BIT_CAN_MOVE,
724     EP_BIT_COULD_MOVE,
725     EP_BIT_DONT_TOUCH,
726     EP_BIT_DONT_GO_TO,
727     EP_BIT_MAMPF2
728   };
729   static int *ep_array[] =
730   {
731     ep_amoebalive,
732     ep_amoeboid,
733     ep_badewannoid,
734     ep_schluessel,
735     ep_pforte,
736     ep_solid,
737     ep_massiv,
738     ep_slippery,
739     ep_enemy,
740     ep_mauer,
741     ep_can_fall,
742     ep_can_smash,
743     ep_can_change,
744     ep_can_move,
745     ep_could_move,
746     ep_dont_touch,
747     ep_dont_go_to,
748     ep_mampf2
749   };
750   static int *ep_num[] =
751   {
752     &ep_amoebalive_num,
753     &ep_amoeboid_num,
754     &ep_badewannoid_num,
755     &ep_schluessel_num,
756     &ep_pforte_num,
757     &ep_solid_num,
758     &ep_massiv_num,
759     &ep_slippery_num,
760     &ep_enemy_num,
761     &ep_mauer_num,
762     &ep_can_fall_num,
763     &ep_can_smash_num,
764     &ep_can_change_num,
765     &ep_can_move_num,
766     &ep_could_move_num,
767     &ep_dont_touch_num,
768     &ep_dont_go_to_num,
769     &ep_mampf2_num
770   };
771   static int num_properties = sizeof(ep_num)/sizeof(int *);
772
773   for(i=0;i<MAX_ELEMENTS;i++)
774     Elementeigenschaften[i] = 0;
775
776   for(i=0;i<num_properties;i++)
777     for(j=0;j<*(ep_num[i]);j++)
778       Elementeigenschaften[(ep_array[i])[j]] |= ep_bit[i];
779   for(i=EL_CHAR_START;i<EL_CHAR_END;i++)
780     Elementeigenschaften[i] |= EP_BIT_CHAR;
781 }
782
783 void CloseAll()
784 {
785   int i;
786
787   if (sound_process_id)
788   {
789     StopSounds();
790     kill(sound_process_id, SIGTERM);
791     FreeSounds(NUM_SOUNDS);
792   }
793
794   for(i=0;i<NUM_PIXMAPS;i++)
795   {
796     if (pix[i])
797     {
798       if (i<NUM_PICTURES)       /* XPM pictures */
799       {
800         XFreeColors(display,DefaultColormap(display,screen),
801                     xpm_att[i].pixels,xpm_att[i].npixels,0);
802         XpmFreeAttributes(&xpm_att[i]);
803       }
804       XFreePixmap(display,pix[i]);
805     }
806     if (clipmask[i])
807       XFreePixmap(display,clipmask[i]);
808     if (clip_gc[i])
809       XFreeGC(display, clip_gc[i]);
810   }
811
812   if (gc)
813     XFreeGC(display, gc);
814   if (plane_gc)
815     XFreeGC(display, plane_gc);
816
817   XCloseDisplay(display);
818
819   exit(0);
820 }