rnd-20000807-1-src
[rocksndiamonds.git] / src / init.c
1 /***********************************************************
2 *  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
3 *----------------------------------------------------------*
4 *  (c) 1995-98 Artsoft Entertainment                       *
5 *              Holger Schemel                              *
6 *              Oststrasse 11a                              *
7 *              33604 Bielefeld                             *
8 *              phone: ++49 +521 290471                     *
9 *              email: aeglos@valinor.owl.de                *
10 *----------------------------------------------------------*
11 *  init.c                                                  *
12 ***********************************************************/
13
14 #include <signal.h>
15
16 #include "init.h"
17 #include "events.h"
18 #include "misc.h"
19 #include "sound.h"
20 #include "screens.h"
21 #include "editor.h"
22 #include "game.h"
23 #include "tape.h"
24 #include "tools.h"
25 #include "files.h"
26 #include "joystick.h"
27 #include "image.h"
28 #include "pcx.h"
29 #include "network.h"
30 #include "netserv.h"
31
32 struct PictureFileInfo
33 {
34   char *picture_filename;
35   boolean picture_with_mask;
36 };
37
38 struct IconFileInfo
39 {
40   char *picture_filename;
41   char *picturemask_filename;
42 };
43
44 static int sound_process_id = 0;
45
46 static void InitLevelAndPlayerInfo(void);
47 static void InitNetworkServer(void);
48 static void InitDisplay(void);
49 static void InitSound(void);
50 static void InitSoundServer(void);
51 static void InitWindow(int, char **);
52 static void InitGfx(void);
53 static void LoadGfx(int, struct PictureFileInfo *);
54 static void InitGadgets(void);
55 static void InitElementProperties(void);
56
57 void OpenAll(int argc, char *argv[])
58 {
59 #ifdef MSDOS
60   initErrorFile();
61 #endif
62
63   if (options.serveronly)
64   {
65     NetworkServer(options.server_port, options.serveronly);
66
67     /* never reached */
68     exit(0);
69   }
70
71   InitCounter();
72   InitSound();
73   InitSoundServer();
74   InitJoysticks();
75   InitRND(NEW_RANDOMIZE);
76
77   signal(SIGINT, CloseAllAndExit);
78   signal(SIGTERM, CloseAllAndExit);
79
80   InitDisplay();
81   InitWindow(argc, argv);
82
83 #ifndef USE_SDL_LIBRARY
84   XMapWindow(display, window);
85   FlushDisplay();
86 #endif
87
88   InitGfx();
89   InitElementProperties();      /* initializes IS_CHAR() for el2gfx() */
90
91   InitLevelAndPlayerInfo();
92   InitGadgets();                /* needs to know number of level series */
93
94   DrawMainMenu();
95
96   InitNetworkServer();
97 }
98
99 void InitLevelAndPlayerInfo()
100 {
101   int i;
102
103   /* choose default local player */
104   local_player = &stored_player[0];
105
106   for (i=0; i<MAX_PLAYERS; i++)
107   {
108     stored_player[i].joystick_fd = -1;  /* joystick device closed */
109     stored_player[i].connected = FALSE;
110   }
111
112   local_player->connected = TRUE;
113
114   LoadLevelInfo();                              /* global level info */
115   LoadSetup();                                  /* global setup info */
116   LoadLevelSetup_LastSeries();                  /* last played series info */
117   LoadLevelSetup_SeriesInfo();                  /* last played level info */
118 }
119
120 void InitNetworkServer()
121 {
122 #ifndef MSDOS
123   int nr_wanted;
124 #endif
125
126   if (!options.network)
127     return;
128
129 #ifndef MSDOS
130   nr_wanted = Request("Choose player", REQ_PLAYER | REQ_STAY_CLOSED);
131
132   if (!ConnectToServer(options.server_host, options.server_port))
133     Error(ERR_EXIT, "cannot connect to network game server");
134
135   SendToServer_PlayerName(setup.player_name);
136   SendToServer_ProtocolVersion();
137
138   if (nr_wanted)
139     SendToServer_NrWanted(nr_wanted);
140 #endif
141 }
142
143 void InitSound()
144 {
145   int i;
146
147   if (sound_status == SOUND_OFF)
148     return;
149
150 #ifdef USE_SDL_LIBRARY
151   /* initialize SDL audio */
152
153   if (SDL_Init(SDL_INIT_AUDIO) < 0)
154   {
155     Error(ERR_WARN, "SDL_Init() failed: %s\n", SDL_GetError());
156     sound_status = SOUND_OFF;
157     return;
158   }
159
160   if (Mix_OpenAudio(22050, AUDIO_S16, 2, 256) < 0)
161   {
162     Error(ERR_WARN, "Mix_OpenAudio() failed: %s\n", SDL_GetError());
163     sound_status = SOUND_OFF;
164     return;
165   }
166
167   Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4);
168   Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4);
169
170   sound_status = SOUND_AVAILABLE;
171   sound_loops_allowed = TRUE;
172
173 #else /* !USE_SDL_LIBRARY */
174
175 #ifndef MSDOS
176   if (access(sound_device_name, W_OK) != 0)
177   {
178     Error(ERR_WARN, "cannot access sound device - no sounds");
179     sound_status = SOUND_OFF;
180     return;
181   }
182
183   if ((sound_device = open(sound_device_name,O_WRONLY))<0)
184   {
185     Error(ERR_WARN, "cannot open sound device - no sounds");
186     sound_status = SOUND_OFF;
187     return;
188   }
189
190   close(sound_device);
191   sound_status = SOUND_AVAILABLE;
192
193 #ifdef VOXWARE
194   sound_loops_allowed = TRUE;
195
196   /*
197   setup.sound_loops_on = TRUE;
198   */
199
200 #endif
201 #else /* MSDOS */
202   sound_loops_allowed = TRUE;
203
204   /*
205   setup.sound_loops_on = TRUE;
206   */
207
208 #endif /* MSDOS */
209 #endif /* !USE_SDL_LIBRARY */
210
211   for(i=0; i<NUM_SOUNDS; i++)
212   {
213     Sound[i].name = sound_name[i];
214
215     if (!LoadSound(&Sound[i]))
216     {
217       sound_status = SOUND_OFF;
218       return;
219     }
220   }
221
222 #if 0
223   sound_status = SOUND_OFF;
224 #endif
225
226 }
227
228 void InitSoundServer()
229 {
230   if (sound_status == SOUND_OFF)
231     return;
232
233 #ifdef USE_SDL_LIBRARY
234   return;
235 #endif
236
237 #ifndef MSDOS
238
239   if (pipe(sound_pipe)<0)
240   {
241     Error(ERR_WARN, "cannot create pipe - no sounds");
242     sound_status = SOUND_OFF;
243     return;
244   }
245
246   if ((sound_process_id = fork()) < 0)
247   {       
248     Error(ERR_WARN, "cannot create sound server process - no sounds");
249     sound_status = SOUND_OFF;
250     return;
251   }
252
253   if (!sound_process_id)        /* we are child */
254   {
255     SoundServer();
256
257     /* never reached */
258     exit(0);
259   }
260   else                          /* we are parent */
261     close(sound_pipe[0]);       /* no reading from pipe needed */
262
263 #else /* MSDOS */
264
265   SoundServer();
266
267 #endif /* MSDOS */
268 }
269
270 void InitJoysticks()
271 {
272 #ifdef USE_SDL_LIBRARY
273   static boolean sdl_joystick_subsystem_initialized = FALSE;
274 #endif
275
276   int i;
277
278   if (global_joystick_status == JOYSTICK_OFF)
279     return;
280
281   joystick_status = JOYSTICK_OFF;
282
283 #ifdef USE_SDL_LIBRARY
284
285   if (!sdl_joystick_subsystem_initialized)
286   {
287     sdl_joystick_subsystem_initialized = TRUE;
288
289     if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
290     {
291       Error(ERR_EXIT, "SDL_Init() failed: %s\n", SDL_GetError());
292       return;
293     }
294   }
295
296   for (i=0; i<MAX_PLAYERS; i++)
297   {
298     char *device_name = setup.input[i].joy.device_name;
299     int joystick_nr = getJoystickNrFromDeviceName(device_name);
300
301     if (joystick_nr >= SDL_NumJoysticks())
302       joystick_nr = -1;
303
304     /* misuse joystick file descriptor variable to store joystick number */
305     stored_player[i].joystick_fd = joystick_nr;
306
307     /* this allows subsequent calls to 'InitJoysticks' for re-initialization */
308     if (Check_SDL_JoystickOpened(joystick_nr))
309       Close_SDL_Joystick(joystick_nr);
310
311     if (!setup.input[i].use_joystick)
312       continue;
313
314     if (!Open_SDL_Joystick(joystick_nr))
315     {
316       Error(ERR_WARN, "cannot open joystick %d", joystick_nr);
317       continue;
318     }
319
320     joystick_status = JOYSTICK_AVAILABLE;
321   }
322
323 #else /* !USE_SDL_LIBRARY */
324
325 #ifndef MSDOS
326   for (i=0; i<MAX_PLAYERS; i++)
327   {
328     char *device_name = setup.input[i].joy.device_name;
329
330     /* this allows subsequent calls to 'InitJoysticks' for re-initialization */
331     if (stored_player[i].joystick_fd != -1)
332     {
333       close(stored_player[i].joystick_fd);
334       stored_player[i].joystick_fd = -1;
335     }
336
337     if (!setup.input[i].use_joystick)
338       continue;
339
340     if (access(device_name, R_OK) != 0)
341     {
342       Error(ERR_WARN, "cannot access joystick device '%s'", device_name);
343       continue;
344     }
345
346     if ((stored_player[i].joystick_fd = open(device_name, O_RDONLY)) < 0)
347     {
348       Error(ERR_WARN, "cannot open joystick device '%s'", device_name);
349       continue;
350     }
351
352     joystick_status = JOYSTICK_AVAILABLE;
353   }
354
355 #else /* MSDOS */
356
357   /* try to access two joysticks; if that fails, try to access just one */
358   if (install_joystick(JOY_TYPE_2PADS) == 0 ||
359       install_joystick(JOY_TYPE_AUTODETECT) == 0)
360     joystick_status = JOYSTICK_AVAILABLE;
361
362   /*
363   load_joystick_data(JOYSTICK_FILENAME);
364   */
365
366   for (i=0; i<MAX_PLAYERS; i++)
367   {
368     char *device_name = setup.input[i].joy.device_name;
369     int joystick_nr = getJoystickNrFromDeviceName(device_name);
370
371     if (joystick_nr >= num_joysticks)
372       joystick_nr = -1;
373
374     /* misuse joystick file descriptor variable to store joystick number */
375     stored_player[i].joystick_fd = joystick_nr;
376   }
377 #endif
378
379 #endif /* !USE_SDL_LIBRARY */
380 }
381
382 void InitDisplay()
383 {
384 #ifdef USE_SDL_LIBRARY
385   /* initialize SDL video */
386   if (SDL_Init(SDL_INIT_VIDEO) < 0)
387     Error(ERR_EXIT, "SDL_Init() failed: %s\n", SDL_GetError());
388
389   /* automatically cleanup SDL stuff after exit() */
390   atexit(SDL_Quit);
391
392 #else /* !USE_SDL_LIBRARY */
393
394 #ifndef MSDOS
395   XVisualInfo vinfo_template, *vinfo;
396   int num_visuals;
397 #endif
398   unsigned int depth;
399
400   /* connect to X server */
401   if (!(display = XOpenDisplay(options.display_name)))
402     Error(ERR_EXIT, "cannot connect to X server %s",
403           XDisplayName(options.display_name));
404
405   screen = DefaultScreen(display);
406   visual = DefaultVisual(display, screen);
407   depth  = DefaultDepth(display, screen);
408   cmap   = DefaultColormap(display, screen);
409
410 #ifndef MSDOS
411   /* look for good enough visual */
412   vinfo_template.screen = screen;
413   vinfo_template.class = (depth == 8 ? PseudoColor : TrueColor);
414   vinfo_template.depth = depth;
415   if ((vinfo = XGetVisualInfo(display, VisualScreenMask | VisualClassMask |
416                               VisualDepthMask, &vinfo_template, &num_visuals)))
417   {
418     visual = vinfo->visual;
419     XFree((void *)vinfo);
420   }
421
422   /* got appropriate visual? */
423   if (depth < 8)
424   {
425     printf("Sorry, displays with less than 8 bits per pixel not supported.\n");
426     exit(-1);
427   }
428   else if ((depth ==8 && visual->class != PseudoColor) ||
429            (depth > 8 && visual->class != TrueColor &&
430             visual->class != DirectColor))
431   {
432     printf("Sorry, cannot get appropriate visual.\n");
433     exit(-1);
434   }
435 #endif /* !MSDOS */
436 #endif /* !USE_SDL_LIBRARY */
437 }
438
439 void InitWindow(int argc, char *argv[])
440 {
441 #ifdef USE_SDL_LIBRARY
442   /* open SDL video output device (window or fullscreen mode) */
443   if ((window = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, WIN_SDL_DEPTH,
444                                  SDL_HWSURFACE))
445       == NULL)
446     Error(ERR_EXIT, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
447
448   /* set window and icon title */
449   SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING);
450
451   /* set event filter to filter out certain mouse motion events */
452   SDL_SetEventFilter(EventFilter);
453
454 #else /* !USE_SDL_LIBRARY */
455
456   unsigned int border_width = 4;
457   XGCValues gc_values;
458   unsigned long gc_valuemask;
459 #ifndef MSDOS
460   XTextProperty windowName, iconName;
461   Pixmap icon_pixmap, iconmask_pixmap;
462   unsigned int icon_width, icon_height;
463   int icon_hot_x, icon_hot_y;
464   char icon_filename[256];
465   XSizeHints size_hints;
466   XWMHints wm_hints;
467   XClassHint class_hints;
468   char *window_name = WINDOW_TITLE_STRING;
469   char *icon_name = WINDOW_TITLE_STRING;
470   long window_event_mask;
471   Atom proto_atom = None, delete_atom = None;
472 #endif
473   int screen_width, screen_height;
474   int win_xpos = WIN_XPOS, win_ypos = WIN_YPOS;
475   unsigned long pen_fg = WhitePixel(display,screen);
476   unsigned long pen_bg = BlackPixel(display,screen);
477   const int width = WIN_XSIZE, height = WIN_YSIZE;
478
479 #ifndef MSDOS
480   static struct IconFileInfo icon_pic =
481   {
482     "rocks_icon.xbm",
483     "rocks_iconmask.xbm"
484   };
485 #endif
486
487   screen_width = XDisplayWidth(display, screen);
488   screen_height = XDisplayHeight(display, screen);
489
490   win_xpos = (screen_width - width) / 2;
491   win_ypos = (screen_height - height) / 2;
492
493   window = XCreateSimpleWindow(display, RootWindow(display, screen),
494                                win_xpos, win_ypos, width, height, border_width,
495                                pen_fg, pen_bg);
496
497 #ifndef MSDOS
498   proto_atom = XInternAtom(display, "WM_PROTOCOLS", FALSE);
499   delete_atom = XInternAtom(display, "WM_DELETE_WINDOW", FALSE);
500   if ((proto_atom != None) && (delete_atom != None))
501     XChangeProperty(display, window, proto_atom, XA_ATOM, 32,
502                     PropModePrepend, (unsigned char *) &delete_atom, 1);
503
504   sprintf(icon_filename, "%s/%s/%s",
505           options.ro_base_directory, GRAPHICS_DIRECTORY,
506           icon_pic.picture_filename);
507   XReadBitmapFile(display,window,icon_filename,
508                   &icon_width,&icon_height,
509                   &icon_pixmap,&icon_hot_x,&icon_hot_y);
510   if (!icon_pixmap)
511     Error(ERR_EXIT, "cannot read icon bitmap file '%s'", icon_filename);
512
513   sprintf(icon_filename, "%s/%s/%s",
514           options.ro_base_directory, GRAPHICS_DIRECTORY,
515           icon_pic.picturemask_filename);
516   XReadBitmapFile(display,window,icon_filename,
517                   &icon_width,&icon_height,
518                   &iconmask_pixmap,&icon_hot_x,&icon_hot_y);
519   if (!iconmask_pixmap)
520     Error(ERR_EXIT, "cannot read icon bitmap file '%s'", icon_filename);
521
522   size_hints.width  = size_hints.min_width  = size_hints.max_width  = width;
523   size_hints.height = size_hints.min_height = size_hints.max_height = height;
524   size_hints.flags = PSize | PMinSize | PMaxSize;
525
526   if (win_xpos || win_ypos)
527   {
528     size_hints.x = win_xpos;
529     size_hints.y = win_ypos;
530     size_hints.flags |= PPosition;
531   }
532
533   if (!XStringListToTextProperty(&window_name, 1, &windowName))
534     Error(ERR_EXIT, "structure allocation for windowName failed");
535
536   if (!XStringListToTextProperty(&icon_name, 1, &iconName))
537     Error(ERR_EXIT, "structure allocation for iconName failed");
538
539   wm_hints.initial_state = NormalState;
540   wm_hints.input = True;
541   wm_hints.icon_pixmap = icon_pixmap;
542   wm_hints.icon_mask = iconmask_pixmap;
543   wm_hints.flags = StateHint | IconPixmapHint | IconMaskHint | InputHint;
544
545   class_hints.res_name = program_name;
546   class_hints.res_class = "Rocks'n'Diamonds";
547
548   XSetWMProperties(display, window, &windowName, &iconName, 
549                    argv, argc, &size_hints, &wm_hints, 
550                    &class_hints);
551
552   XFree(windowName.value);
553   XFree(iconName.value);
554
555   /* Select event types wanted */
556   window_event_mask =
557     ExposureMask | StructureNotifyMask | FocusChangeMask |
558     ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
559     PointerMotionHintMask | KeyPressMask | KeyReleaseMask;
560
561   XSelectInput(display, window, window_event_mask);
562 #endif
563
564   /* create GC for drawing with window depth and background color (black) */
565   gc_values.graphics_exposures = False;
566   gc_values.foreground = pen_bg;
567   gc_values.background = pen_bg;
568   gc_valuemask = GCGraphicsExposures | GCForeground | GCBackground;
569   gc = XCreateGC(display, window, gc_valuemask, &gc_values);
570 #endif /* !USE_SDL_LIBRARY */
571 }
572
573 void InitGfx()
574 {
575   int i,j;
576
577 #ifdef USE_SDL_LIBRARY
578   SDL_Surface *sdl_image_tmp;
579 #else
580   GC copy_clipmask_gc;
581   XGCValues clip_gc_values;
582   unsigned long clip_gc_valuemask;
583 #endif
584
585 #ifdef MSDOS
586   static struct PictureFileInfo pic[NUM_PICTURES] =
587   {
588     { "Screen", TRUE },
589     { "Door",   TRUE },
590     { "Heroes", TRUE },
591     { "Toons",  TRUE },
592     { "SP",     TRUE },
593     { "DC",     TRUE },
594     { "More",   TRUE },
595     { "Font",   FALSE },
596     { "Font2",  FALSE },
597     { "Font3",  FALSE }
598   }; 
599 #else
600   static struct PictureFileInfo pic[NUM_PICTURES] =
601   {
602     { "RocksScreen",    TRUE },
603     { "RocksDoor",      TRUE },
604     { "RocksHeroes",    TRUE },
605     { "RocksToons",     TRUE },
606     { "RocksSP",        TRUE },
607     { "RocksDC",        TRUE },
608     { "RocksMore",      TRUE },
609     { "RocksFont",      FALSE },
610     { "RocksFont2",     FALSE },
611     { "RocksFont3",     FALSE }
612   }; 
613 #endif
614
615 #ifdef DEBUG
616 #if 0
617   static struct PictureFileInfo test_pic1 =
618   {
619     "RocksFont2",
620     FALSE
621   };
622   static struct PictureFileInfo test_pic2 =
623   {
624     "mouse",
625     FALSE
626   };
627 #endif
628 #endif
629
630   static struct
631   {
632     int start;
633     int count;
634   }
635   tile_needs_clipping[] =
636   {
637     { GFX_SPIELER1_UP, 4 },
638     { GFX_SPIELER1_DOWN, 4 },
639     { GFX_SPIELER1_LEFT, 4 },
640     { GFX_SPIELER1_RIGHT, 4 },
641     { GFX_SPIELER1_PUSH_LEFT, 4 },
642     { GFX_SPIELER1_PUSH_RIGHT, 4 },
643     { GFX_SPIELER2_UP, 4 },
644     { GFX_SPIELER2_DOWN, 4 },
645     { GFX_SPIELER2_LEFT, 4 },
646     { GFX_SPIELER2_RIGHT, 4 },
647     { GFX_SPIELER2_PUSH_LEFT, 4 },
648     { GFX_SPIELER2_PUSH_RIGHT, 4 },
649     { GFX_SPIELER3_UP, 4 },
650     { GFX_SPIELER3_DOWN, 4 },
651     { GFX_SPIELER3_LEFT, 4 },
652     { GFX_SPIELER3_RIGHT, 4 },
653     { GFX_SPIELER3_PUSH_LEFT, 4 },
654     { GFX_SPIELER3_PUSH_RIGHT, 4 },
655     { GFX_SPIELER4_UP, 4 },
656     { GFX_SPIELER4_DOWN, 4 },
657     { GFX_SPIELER4_LEFT, 4 },
658     { GFX_SPIELER4_RIGHT, 4 },
659     { GFX_SPIELER4_PUSH_LEFT, 4 },
660     { GFX_SPIELER4_PUSH_RIGHT, 4 },
661     { GFX_SP_MURPHY, 1 },
662     { GFX_MURPHY_GO_LEFT, 3 },
663     { GFX_MURPHY_GO_RIGHT, 3 },
664     { GFX_MURPHY_SNAP_UP, 1 },
665     { GFX_MURPHY_SNAP_DOWN, 1 },
666     { GFX_MURPHY_SNAP_RIGHT, 1 },
667     { GFX_MURPHY_SNAP_LEFT, 1 },
668     { GFX_MURPHY_PUSH_RIGHT, 1 },
669     { GFX_MURPHY_PUSH_LEFT, 1 },
670     { GFX_GEBLUBBER, 4 },
671     { GFX_DYNAMIT, 7 },
672     { GFX_DYNABOMB, 4 },
673     { GFX_EXPLOSION, 8 },
674     { GFX_SOKOBAN_OBJEKT, 1 },
675     { GFX_FUNKELN_BLAU, 3 },
676     { GFX_FUNKELN_WEISS, 3 },
677     { GFX2_SHIELD_PASSIVE, 3 },
678     { GFX2_SHIELD_ACTIVE, 3 },
679     { -1, 0 }
680   };
681
682 #if DEBUG_TIMING
683   debug_print_timestamp(0, NULL);       /* initialize timestamp function */
684 #endif
685
686 #ifdef DEBUG
687 #if 0
688   printf("Test: Loading RocksFont2.pcx ...\n");
689   LoadGfx(PIX_SMALLFONT,&test_pic1);
690   printf("Test: Done.\n");
691   printf("Test: Loading mouse.pcx ...\n");
692   LoadGfx(PIX_SMALLFONT,&test_pic2);
693   printf("Test: Done.\n");
694 #endif
695 #endif
696
697   LoadGfx(PIX_SMALLFONT,&pic[PIX_SMALLFONT]);
698   DrawInitText(WINDOW_TITLE_STRING,20,FC_YELLOW);
699   DrawInitText(COPYRIGHT_STRING,50,FC_RED);
700 #ifdef MSDOS
701   DrawInitText("MSDOS version done by Guido Schulz",210,FC_BLUE);
702   rest(200);
703 #endif /* MSDOS */
704   DrawInitText("Loading graphics:",120,FC_GREEN);
705
706   for(i=0; i<NUM_PICTURES; i++)
707     if (i != PIX_SMALLFONT)
708       LoadGfx(i,&pic[i]);
709
710 #if DEBUG_TIMING
711   debug_print_timestamp(0, "SUMMARY LOADING ALL GRAPHICS:");
712 #endif
713
714 #ifdef USE_SDL_LIBRARY
715   /* create some native image surfaces for double-buffer purposes */
716
717   /* create double-buffer surface for background image */
718   if ((sdl_image_tmp = SDL_CreateRGBSurface(SDL_SWSURFACE,
719                                             WIN_XSIZE, WIN_YSIZE,
720                                             WIN_SDL_DEPTH, 0, 0, 0, 0))
721       == NULL)
722     Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s\n", SDL_GetError());
723
724   if ((pix[PIX_DB_BACK] = SDL_DisplayFormat(sdl_image_tmp)) == NULL)
725     Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s\n", SDL_GetError());
726
727   SDL_FreeSurface(sdl_image_tmp);
728
729   /* create double-buffer surface for door image */
730   if ((sdl_image_tmp = SDL_CreateRGBSurface(SDL_SWSURFACE,
731                                             3 * DXSIZE, DYSIZE + VYSIZE,
732                                             WIN_SDL_DEPTH, 0, 0, 0, 0))
733       == NULL)
734     Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s\n", SDL_GetError());
735
736   if ((pix[PIX_DB_DOOR] = SDL_DisplayFormat(sdl_image_tmp)) == NULL)
737     Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s\n", SDL_GetError());
738
739   SDL_FreeSurface(sdl_image_tmp);
740
741   /* create double-buffer surface for field image */
742   if ((sdl_image_tmp = SDL_CreateRGBSurface(SDL_SWSURFACE,
743                                             FXSIZE, FYSIZE,
744                                             WIN_SDL_DEPTH, 0, 0, 0, 0))
745       == NULL)
746     Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s\n", SDL_GetError());
747
748   if ((pix[PIX_DB_FIELD] = SDL_DisplayFormat(sdl_image_tmp)) == NULL)
749     Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s\n", SDL_GetError());
750
751   SDL_FreeSurface(sdl_image_tmp);
752
753   /* initialize surface array to 'NULL' */
754   for(i=0; i<NUM_TILES; i++)
755     tile_masked[i] = NULL;
756
757   /* create only those masked surfaces we really need */
758   for(i=0; tile_needs_clipping[i].start>=0; i++)
759   {
760     for(j=0; j<tile_needs_clipping[i].count; j++)
761     {
762       int tile = tile_needs_clipping[i].start + j;
763       int graphic = tile;
764       int src_x, src_y;
765       int bitmap_nr;
766       Bitmap src_bitmap;
767
768       getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
769       src_bitmap = pix_masked[bitmap_nr];
770
771       /* create surface for masked tile graphic */
772       if ((sdl_image_tmp = SDL_CreateRGBSurface(SDL_SWSURFACE, TILEX, TILEY,
773                                                 WIN_SDL_DEPTH, 0, 0, 0, 0))
774           == NULL)
775         Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s\n", SDL_GetError());
776
777       /* create native transparent surface for current image */
778       SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
779                       SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
780       if ((tile_masked[tile] = SDL_DisplayFormat(sdl_image_tmp)) == NULL)
781         Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s\n", SDL_GetError());
782
783       SDL_FreeSurface(sdl_image_tmp);
784
785       BlitBitmap(src_bitmap, tile_masked[tile], src_x,src_y, TILEX,TILEY, 0,0);
786     }
787   }
788
789 #else /* !USE_SDL_LIBRARY */
790
791   pix[PIX_DB_BACK] = XCreatePixmap(display, window,
792                                    WIN_XSIZE,WIN_YSIZE,
793                                    XDefaultDepth(display,screen));
794   pix[PIX_DB_DOOR] = XCreatePixmap(display, window,
795                                    3*DXSIZE,DYSIZE+VYSIZE,
796                                    XDefaultDepth(display,screen));
797   pix[PIX_DB_FIELD] = XCreatePixmap(display, window,
798                                     FXSIZE,FYSIZE,
799                                     XDefaultDepth(display,screen));
800
801   clip_gc_values.graphics_exposures = False;
802   clip_gc_valuemask = GCGraphicsExposures;
803   copy_clipmask_gc =
804     XCreateGC(display,clipmask[PIX_BACK],clip_gc_valuemask,&clip_gc_values);
805
806   clip_gc_values.graphics_exposures = False;
807   clip_gc_valuemask = GCGraphicsExposures;
808   tile_clip_gc =
809     XCreateGC(display,window,clip_gc_valuemask,&clip_gc_values);
810
811   /* initialize pixmap array to Pixmap 'None' */
812   for(i=0; i<NUM_TILES; i++)
813     tile_clipmask[i] = None;
814
815   /* create only those clipping Pixmaps we really need */
816   for(i=0; tile_needs_clipping[i].start>=0; i++)
817   {
818     for(j=0; j<tile_needs_clipping[i].count; j++)
819     {
820       int tile = tile_needs_clipping[i].start + j;
821       int graphic = tile;
822       int src_x, src_y;
823       int pixmap_nr;
824       Pixmap src_pixmap;
825
826       getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
827       src_pixmap = clipmask[pixmap_nr];
828
829       tile_clipmask[tile] = XCreatePixmap(display, window, TILEX,TILEY, 1);
830
831       XCopyArea(display,src_pixmap,tile_clipmask[tile],copy_clipmask_gc,
832                 src_x,src_y, TILEX,TILEY, 0,0);
833     }
834   }
835
836   if (!pix[PIX_DB_BACK] || !pix[PIX_DB_DOOR])
837     Error(ERR_EXIT, "cannot create additional pixmaps");
838
839   for(i=0; i<NUM_BITMAPS; i++)
840   {
841     if (clipmask[i])
842     {
843       clip_gc_values.graphics_exposures = False;
844       clip_gc_values.clip_mask = clipmask[i];
845       clip_gc_valuemask = GCGraphicsExposures | GCClipMask;
846       clip_gc[i] = XCreateGC(display,window,clip_gc_valuemask,&clip_gc_values);
847     }
848   }
849
850 #endif /* !USE_SDL_LIBRARY */
851
852   drawto = backbuffer = pix[PIX_DB_BACK];
853   fieldbuffer = pix[PIX_DB_FIELD];
854   SetDrawtoField(DRAW_BACKBUFFER);
855
856   BlitBitmap(pix[PIX_BACK], backbuffer, 0,0, WIN_XSIZE,WIN_YSIZE, 0,0);
857   ClearRectangle(pix[PIX_DB_BACK], REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
858   ClearRectangle(pix[PIX_DB_DOOR], 0,0, 3*DXSIZE,DYSIZE+VYSIZE);
859
860   for(i=0; i<MAX_BUF_XSIZE; i++)
861     for(j=0; j<MAX_BUF_YSIZE; j++)
862       redraw[i][j] = 0;
863   redraw_tiles = 0;
864   redraw_mask = REDRAW_ALL;
865 }
866
867 void LoadGfx(int pos, struct PictureFileInfo *pic)
868 {
869   char basefilename[256];
870   char filename[256];
871
872 #ifdef USE_XPM_LIBRARY
873   int xpm_err, xbm_err;
874   unsigned int width,height;
875   int hot_x,hot_y;
876   Pixmap shapemask;
877   char *picture_ext = ".xpm";
878   char *picturemask_ext = "Mask.xbm";
879 #else
880
881 #ifdef USE_SDL_LIBRARY
882   SDL_Surface *sdl_image_tmp;
883 #else /* !USE_SDL_LIBRARY */
884   int pcx_err;
885 #endif /* !USE_SDL_LIBRARY */
886   char *picture_ext = ".pcx";
887
888 #endif /* !USE_XPM_LIBRARY */
889
890   /* Grafik laden */
891   if (pic->picture_filename)
892   {
893     sprintf(basefilename, "%s%s", pic->picture_filename, picture_ext);
894     DrawInitText(basefilename, 150, FC_YELLOW);
895     sprintf(filename, "%s/%s/%s",
896             options.ro_base_directory, GRAPHICS_DIRECTORY, basefilename);
897
898 #ifdef MSDOS
899     rest(100);
900 #endif /* MSDOS */
901
902 #if DEBUG_TIMING
903     debug_print_timestamp(1, NULL);     /* initialize timestamp function */
904 #endif
905
906 #ifdef USE_SDL_LIBRARY
907     /* load image to temporary surface */
908     if ((sdl_image_tmp = IMG_Load(filename)) == NULL)
909       Error(ERR_EXIT, "IMG_Load() failed: %s\n", SDL_GetError());
910
911     /* create native non-transparent surface for current image */
912     if ((pix[pos] = SDL_DisplayFormat(sdl_image_tmp)) == NULL)
913       Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s\n", SDL_GetError());
914
915     /* create native transparent surface for current image */
916     SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
917                     SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
918     if ((pix_masked[pos] = SDL_DisplayFormat(sdl_image_tmp)) == NULL)
919       Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s\n", SDL_GetError());
920
921     /* free temporary surface */
922     SDL_FreeSurface(sdl_image_tmp);
923
924 #else /* !USE_SDL_LIBRARY */
925
926 #ifdef USE_XPM_LIBRARY
927
928     xpm_att[pos].valuemask = XpmCloseness;
929     xpm_att[pos].closeness = 20000;
930     xpm_err = XpmReadFileToPixmap(display,window,filename,
931                                   &pix[pos],&shapemask,&xpm_att[pos]);
932     switch(xpm_err)
933     {
934       case XpmOpenFailed:
935         Error(ERR_EXIT, "cannot open XPM file '%s'", filename);
936       case XpmFileInvalid:
937         Error(ERR_EXIT, "invalid XPM file '%s'", filename);
938       case XpmNoMemory:
939         Error(ERR_EXIT, "not enough memory for XPM file '%s'", filename);
940       case XpmColorFailed:
941         Error(ERR_EXIT, "cannot get colors for XPM file '%s'", filename);
942       default:
943         break;
944     }
945
946 #if DEBUG_TIMING
947     printf("LOADING XPM FILE %s:", filename);
948     debug_print_timestamp(1, "");
949 #endif
950
951 #else /* !USE_XPM_LIBRARY */
952
953     pcx_err = Read_PCX_to_Pixmap(display, window, gc, filename,
954                                  &pix[pos], &clipmask[pos]);
955     switch(pcx_err)
956     {
957       case PCX_Success:
958         break;
959       case PCX_OpenFailed:
960         Error(ERR_EXIT, "cannot open PCX file '%s'", filename);
961       case PCX_ReadFailed:
962         Error(ERR_EXIT, "cannot read PCX file '%s'", filename);
963       case PCX_FileInvalid:
964         Error(ERR_EXIT, "invalid PCX file '%s'", filename);
965       case PCX_NoMemory:
966         Error(ERR_EXIT, "not enough memory for PCX file '%s'", filename);
967       case PCX_ColorFailed:
968         Error(ERR_EXIT, "cannot get colors for PCX file '%s'", filename);
969       default:
970         break;
971     }
972
973 #if DEBUG_TIMING
974     printf("SUMMARY LOADING PCX FILE %s:", filename);
975     debug_print_timestamp(1, "");
976 #endif
977
978 #endif /* !USE_XPM_LIBRARY */
979
980     if (!pix[pos])
981       Error(ERR_EXIT, "cannot get graphics for '%s'", pic->picture_filename);
982
983     /* setting pix_masked[] to pix[] allows BlitBitmapMasked() to always
984        use pix_masked[], although they are the same when not using SDL */
985     pix_masked[pos] = pix[pos];
986
987 #endif /* !USE_SDL_LIBRARY */
988   }
989
990 #ifndef USE_SDL_LIBRARY
991   /* zugehörige Maske laden (wenn vorhanden) */
992   if (pic->picture_with_mask)
993   {
994 #ifdef USE_XPM_LIBRARY
995
996     sprintf(basefilename, "%s%s", pic->picture_filename, picturemask_ext);
997     DrawInitText(basefilename, 150, FC_YELLOW);
998     sprintf(filename, "%s/%s/%s",
999             options.ro_base_directory, GRAPHICS_DIRECTORY, basefilename);
1000
1001 #if DEBUG_TIMING
1002     debug_print_timestamp(1, NULL);     /* initialize timestamp function */
1003 #endif
1004
1005     xbm_err = XReadBitmapFile(display,window,filename,
1006                               &width,&height,&clipmask[pos],&hot_x,&hot_y);
1007     switch(xbm_err)
1008     {
1009       case BitmapSuccess:
1010         break;
1011       case BitmapOpenFailed:
1012         Error(ERR_EXIT, "cannot open XBM file '%s'", filename);
1013       case BitmapFileInvalid:
1014         Error(ERR_EXIT, "invalid XBM file '%s'", filename);
1015       case BitmapNoMemory:
1016         Error(ERR_EXIT, "not enough memory for XBM file '%s'", filename);
1017         break;
1018       default:
1019         break;
1020     }
1021
1022 #if DEBUG_TIMING
1023     printf("LOADING XBM FILE %s:", filename);
1024     debug_print_timestamp(1, "");
1025 #endif
1026
1027 #endif /* USE_XPM_LIBRARY */
1028
1029     if (!clipmask[pos])
1030       Error(ERR_EXIT, "cannot get clipmask for '%s'", pic->picture_filename);
1031   }
1032 #endif /* !USE_SDL_LIBRARY */
1033 }
1034
1035 void InitGadgets()
1036 {
1037   CreateLevelEditorGadgets();
1038   CreateGameButtons();
1039   CreateTapeButtons();
1040   CreateToolButtons();
1041   CreateScreenGadgets();
1042 }
1043
1044 void InitElementProperties()
1045 {
1046   int i,j;
1047
1048   static int ep_amoebalive[] =
1049   {
1050     EL_AMOEBE_NASS,
1051     EL_AMOEBE_NORM,
1052     EL_AMOEBE_VOLL,
1053     EL_AMOEBE_BD
1054   };
1055   static int ep_amoebalive_num = sizeof(ep_amoebalive)/sizeof(int);
1056
1057   static int ep_amoeboid[] =
1058   {
1059     EL_AMOEBE_TOT,
1060     EL_AMOEBE_NASS,
1061     EL_AMOEBE_NORM,
1062     EL_AMOEBE_VOLL,
1063     EL_AMOEBE_BD
1064   };
1065   static int ep_amoeboid_num = sizeof(ep_amoeboid)/sizeof(int);
1066
1067   static int ep_schluessel[] =
1068   {
1069     EL_SCHLUESSEL1,
1070     EL_SCHLUESSEL2,
1071     EL_SCHLUESSEL3,
1072     EL_SCHLUESSEL4,
1073     EL_EM_KEY_1,
1074     EL_EM_KEY_2,
1075     EL_EM_KEY_3,
1076     EL_EM_KEY_4
1077   };
1078   static int ep_schluessel_num = sizeof(ep_schluessel)/sizeof(int);
1079
1080   static int ep_pforte[] =
1081   {
1082     EL_PFORTE1,
1083     EL_PFORTE2,
1084     EL_PFORTE3,
1085     EL_PFORTE4,
1086     EL_PFORTE1X,
1087     EL_PFORTE2X,
1088     EL_PFORTE3X,
1089     EL_PFORTE4X,
1090     EL_EM_GATE_1,
1091     EL_EM_GATE_2,
1092     EL_EM_GATE_3,
1093     EL_EM_GATE_4,
1094     EL_EM_GATE_1X,
1095     EL_EM_GATE_2X,
1096     EL_EM_GATE_3X,
1097     EL_EM_GATE_4X,
1098     EL_SWITCHGATE_OPEN,
1099     EL_SWITCHGATE_CLOSED,
1100     EL_TIMEGATE_OPEN,
1101     EL_TIMEGATE_CLOSED,
1102     EL_TUBE_CROSS,
1103     EL_TUBE_VERTICAL,
1104     EL_TUBE_HORIZONTAL,
1105     EL_TUBE_VERT_LEFT,
1106     EL_TUBE_VERT_RIGHT,
1107     EL_TUBE_HORIZ_UP,
1108     EL_TUBE_HORIZ_DOWN,
1109     EL_TUBE_LEFT_UP,
1110     EL_TUBE_LEFT_DOWN,
1111     EL_TUBE_RIGHT_UP,
1112     EL_TUBE_RIGHT_DOWN
1113   };
1114   static int ep_pforte_num = sizeof(ep_pforte)/sizeof(int);
1115
1116   static int ep_solid[] =
1117   {
1118     EL_BETON,
1119     EL_MAUERWERK,
1120     EL_MAUER_LEBT,
1121     EL_MAUER_X,
1122     EL_MAUER_Y,
1123     EL_MAUER_XY,
1124     EL_BD_WALL,
1125     EL_FELSBODEN,
1126     EL_AUSGANG_ZU,
1127     EL_AUSGANG_ACT,
1128     EL_AUSGANG_AUF,
1129     EL_AMOEBE_TOT,
1130     EL_AMOEBE_NASS,
1131     EL_AMOEBE_NORM,
1132     EL_AMOEBE_VOLL,
1133     EL_AMOEBE_BD,
1134     EL_MORAST_VOLL,
1135     EL_MORAST_LEER,
1136     EL_MAGIC_WALL_OFF,
1137     EL_MAGIC_WALL_EMPTY,
1138     EL_MAGIC_WALL_FULL,
1139     EL_MAGIC_WALL_DEAD,
1140     EL_MAGIC_WALL_BD_OFF,
1141     EL_MAGIC_WALL_BD_EMPTY,
1142     EL_MAGIC_WALL_BD_FULL,
1143     EL_MAGIC_WALL_BD_DEAD,
1144     EL_LIFE,
1145     EL_LIFE_ASYNC,
1146     EL_BADEWANNE1,
1147     EL_BADEWANNE2,
1148     EL_BADEWANNE3,
1149     EL_BADEWANNE4,
1150     EL_BADEWANNE5,
1151     EL_SP_CHIP_SINGLE,
1152     EL_SP_CHIP_LEFT,
1153     EL_SP_CHIP_RIGHT,
1154     EL_SP_CHIP_UPPER,
1155     EL_SP_CHIP_LOWER,
1156     EL_SP_HARD_GRAY,
1157     EL_SP_HARD_GREEN,
1158     EL_SP_HARD_BLUE,
1159     EL_SP_HARD_RED,
1160     EL_SP_HARD_YELLOW,
1161     EL_SP_HARD_BASE1,
1162     EL_SP_HARD_BASE2,
1163     EL_SP_HARD_BASE3,
1164     EL_SP_HARD_BASE4,
1165     EL_SP_HARD_BASE5,
1166     EL_SP_HARD_BASE6,
1167     EL_SP_TERMINAL,
1168     EL_SP_EXIT,
1169     EL_INVISIBLE_STEEL,
1170     EL_BELT1_SWITCH_LEFT,
1171     EL_BELT1_SWITCH_MIDDLE,
1172     EL_BELT1_SWITCH_RIGHT,
1173     EL_BELT2_SWITCH_LEFT,
1174     EL_BELT2_SWITCH_MIDDLE,
1175     EL_BELT2_SWITCH_RIGHT,
1176     EL_BELT3_SWITCH_LEFT,
1177     EL_BELT3_SWITCH_MIDDLE,
1178     EL_BELT3_SWITCH_RIGHT,
1179     EL_BELT4_SWITCH_LEFT,
1180     EL_BELT4_SWITCH_MIDDLE,
1181     EL_BELT4_SWITCH_RIGHT,
1182     EL_SWITCHGATE_SWITCH_1,
1183     EL_SWITCHGATE_SWITCH_2,
1184     EL_LIGHT_SWITCH_OFF,
1185     EL_LIGHT_SWITCH_ON,
1186     EL_TIMEGATE_SWITCH_OFF,
1187     EL_TIMEGATE_SWITCH_ON,
1188     EL_SIGN_EXCLAMATION,
1189     EL_SIGN_RADIOACTIVITY,
1190     EL_SIGN_STOP,
1191     EL_SIGN_WHEELCHAIR,
1192     EL_SIGN_PARKING,
1193     EL_SIGN_ONEWAY,
1194     EL_SIGN_HEART,
1195     EL_SIGN_TRIANGLE,
1196     EL_SIGN_ROUND,
1197     EL_SIGN_EXIT,
1198     EL_SIGN_YINYANG,
1199     EL_SIGN_OTHER,
1200     EL_STEEL_SLANTED,
1201     EL_EMC_STEEL_WALL_1,
1202     EL_EMC_STEEL_WALL_2,
1203     EL_EMC_STEEL_WALL_3,
1204     EL_EMC_STEEL_WALL_4,
1205     EL_EMC_WALL_1,
1206     EL_EMC_WALL_2,
1207     EL_EMC_WALL_3,
1208     EL_EMC_WALL_4,
1209     EL_EMC_WALL_5,
1210     EL_EMC_WALL_6,
1211     EL_EMC_WALL_7,
1212     EL_EMC_WALL_8,
1213     EL_CRYSTAL,
1214     EL_WALL_PEARL,
1215     EL_WALL_CRYSTAL,
1216     EL_TUBE_CROSS,
1217     EL_TUBE_VERTICAL,
1218     EL_TUBE_HORIZONTAL,
1219     EL_TUBE_VERT_LEFT,
1220     EL_TUBE_VERT_RIGHT,
1221     EL_TUBE_HORIZ_UP,
1222     EL_TUBE_HORIZ_DOWN,
1223     EL_TUBE_LEFT_UP,
1224     EL_TUBE_LEFT_DOWN,
1225     EL_TUBE_RIGHT_UP,
1226     EL_TUBE_RIGHT_DOWN
1227   };
1228   static int ep_solid_num = sizeof(ep_solid)/sizeof(int);
1229
1230   static int ep_massive[] =
1231   {
1232     EL_BETON,
1233     EL_SALZSAEURE,
1234     EL_BADEWANNE1,
1235     EL_BADEWANNE2,
1236     EL_BADEWANNE3,
1237     EL_BADEWANNE4,
1238     EL_BADEWANNE5,
1239     EL_PFORTE1,
1240     EL_PFORTE2,
1241     EL_PFORTE3,
1242     EL_PFORTE4,
1243     EL_PFORTE1X,
1244     EL_PFORTE2X,
1245     EL_PFORTE3X,
1246     EL_PFORTE4X,
1247     EL_EM_GATE_1,
1248     EL_EM_GATE_2,
1249     EL_EM_GATE_3,
1250     EL_EM_GATE_4,
1251     EL_EM_GATE_1X,
1252     EL_EM_GATE_2X,
1253     EL_EM_GATE_3X,
1254     EL_EM_GATE_4X,
1255     EL_SWITCHGATE_OPEN,
1256     EL_SWITCHGATE_CLOSED,
1257     EL_TIMEGATE_OPEN,
1258     EL_TIMEGATE_CLOSED,
1259     EL_SP_HARD_GRAY,
1260     EL_SP_HARD_GREEN,
1261     EL_SP_HARD_BLUE,
1262     EL_SP_HARD_RED,
1263     EL_SP_HARD_YELLOW,
1264     EL_SP_HARD_BASE1,
1265     EL_SP_HARD_BASE2,
1266     EL_SP_HARD_BASE3,
1267     EL_SP_HARD_BASE4,
1268     EL_SP_HARD_BASE5,
1269     EL_SP_HARD_BASE6,
1270     EL_INVISIBLE_STEEL,
1271     EL_BELT1_SWITCH_LEFT,
1272     EL_BELT1_SWITCH_MIDDLE,
1273     EL_BELT1_SWITCH_RIGHT,
1274     EL_BELT2_SWITCH_LEFT,
1275     EL_BELT2_SWITCH_MIDDLE,
1276     EL_BELT2_SWITCH_RIGHT,
1277     EL_BELT3_SWITCH_LEFT,
1278     EL_BELT3_SWITCH_MIDDLE,
1279     EL_BELT3_SWITCH_RIGHT,
1280     EL_BELT4_SWITCH_LEFT,
1281     EL_BELT4_SWITCH_MIDDLE,
1282     EL_BELT4_SWITCH_RIGHT,
1283     EL_LIGHT_SWITCH_OFF,
1284     EL_LIGHT_SWITCH_ON,
1285     EL_SIGN_EXCLAMATION,
1286     EL_SIGN_RADIOACTIVITY,
1287     EL_SIGN_STOP,
1288     EL_SIGN_WHEELCHAIR,
1289     EL_SIGN_PARKING,
1290     EL_SIGN_ONEWAY,
1291     EL_SIGN_HEART,
1292     EL_SIGN_TRIANGLE,
1293     EL_SIGN_ROUND,
1294     EL_SIGN_EXIT,
1295     EL_SIGN_YINYANG,
1296     EL_SIGN_OTHER,
1297     EL_STEEL_SLANTED,
1298     EL_EMC_STEEL_WALL_1,
1299     EL_EMC_STEEL_WALL_2,
1300     EL_EMC_STEEL_WALL_3,
1301     EL_EMC_STEEL_WALL_4,
1302     EL_CRYSTAL,
1303     EL_TUBE_CROSS,
1304     EL_TUBE_VERTICAL,
1305     EL_TUBE_HORIZONTAL,
1306     EL_TUBE_VERT_LEFT,
1307     EL_TUBE_VERT_RIGHT,
1308     EL_TUBE_HORIZ_UP,
1309     EL_TUBE_HORIZ_DOWN,
1310     EL_TUBE_LEFT_UP,
1311     EL_TUBE_LEFT_DOWN,
1312     EL_TUBE_RIGHT_UP,
1313     EL_TUBE_RIGHT_DOWN
1314   };
1315   static int ep_massive_num = sizeof(ep_massive)/sizeof(int);
1316
1317   static int ep_slippery[] =
1318   {
1319     EL_FELSBODEN,
1320     EL_BD_WALL,
1321     EL_FELSBROCKEN,
1322     EL_BD_ROCK,
1323     EL_EDELSTEIN,
1324     EL_EDELSTEIN_BD,
1325     EL_EDELSTEIN_GELB,
1326     EL_EDELSTEIN_ROT,
1327     EL_EDELSTEIN_LILA,
1328     EL_DIAMANT,
1329     EL_BOMBE,
1330     EL_KOKOSNUSS,
1331     EL_ABLENK_EIN,
1332     EL_ABLENK_AUS,
1333     EL_ZEIT_VOLL,
1334     EL_ZEIT_LEER,
1335     EL_BIRNE_EIN,
1336     EL_BIRNE_AUS,
1337     EL_BADEWANNE1,
1338     EL_BADEWANNE2,
1339     EL_SONDE,
1340     EL_SP_ZONK,
1341     EL_SP_INFOTRON,
1342     EL_SP_CHIP_SINGLE,
1343     EL_SP_CHIP_LEFT,
1344     EL_SP_CHIP_RIGHT,
1345     EL_SP_CHIP_UPPER,
1346     EL_SP_CHIP_LOWER,
1347     EL_SPEED_PILL,
1348     EL_STEEL_SLANTED,
1349     EL_PEARL,
1350     EL_CRYSTAL
1351   };
1352   static int ep_slippery_num = sizeof(ep_slippery)/sizeof(int);
1353
1354   static int ep_enemy[] =
1355   {
1356     EL_KAEFER,
1357     EL_FLIEGER,
1358     EL_BUTTERFLY,
1359     EL_FIREFLY,
1360     EL_MAMPFER,
1361     EL_MAMPFER2,
1362     EL_ROBOT,
1363     EL_PACMAN,
1364     EL_SP_SNIKSNAK,
1365     EL_SP_ELECTRON
1366   };
1367   static int ep_enemy_num = sizeof(ep_enemy)/sizeof(int);
1368
1369   static int ep_mauer[] =
1370   {
1371     EL_BETON,
1372     EL_PFORTE1,
1373     EL_PFORTE2,
1374     EL_PFORTE3,
1375     EL_PFORTE4,
1376     EL_PFORTE1X,
1377     EL_PFORTE2X,
1378     EL_PFORTE3X,
1379     EL_PFORTE4X,
1380     EL_EM_GATE_1,
1381     EL_EM_GATE_2,
1382     EL_EM_GATE_3,
1383     EL_EM_GATE_4,
1384     EL_EM_GATE_1X,
1385     EL_EM_GATE_2X,
1386     EL_EM_GATE_3X,
1387     EL_EM_GATE_4X,
1388     EL_AUSGANG_ZU,
1389     EL_AUSGANG_ACT,
1390     EL_AUSGANG_AUF,
1391     EL_MAUERWERK,
1392     EL_FELSBODEN,
1393     EL_MAUER_LEBT,
1394     EL_MAUER_X,
1395     EL_MAUER_Y,
1396     EL_MAUER_XY,
1397     EL_MAUERND,
1398     EL_BD_WALL,
1399     EL_SP_CHIP_SINGLE,
1400     EL_SP_CHIP_LEFT,
1401     EL_SP_CHIP_RIGHT,
1402     EL_SP_CHIP_UPPER,
1403     EL_SP_CHIP_LOWER,
1404     EL_SP_HARD_GRAY,
1405     EL_SP_HARD_GREEN,
1406     EL_SP_HARD_BLUE,
1407     EL_SP_HARD_RED,
1408     EL_SP_HARD_YELLOW,
1409     EL_SP_HARD_BASE1,
1410     EL_SP_HARD_BASE2,
1411     EL_SP_HARD_BASE3,
1412     EL_SP_HARD_BASE4,
1413     EL_SP_HARD_BASE5,
1414     EL_SP_HARD_BASE6,
1415     EL_SP_TERMINAL,
1416     EL_SP_EXIT,
1417     EL_INVISIBLE_STEEL,
1418     EL_STEEL_SLANTED,
1419     EL_EMC_STEEL_WALL_1,
1420     EL_EMC_STEEL_WALL_2,
1421     EL_EMC_STEEL_WALL_3,
1422     EL_EMC_STEEL_WALL_4,
1423     EL_EMC_WALL_1,
1424     EL_EMC_WALL_2,
1425     EL_EMC_WALL_3,
1426     EL_EMC_WALL_4,
1427     EL_EMC_WALL_5,
1428     EL_EMC_WALL_6,
1429     EL_EMC_WALL_7,
1430     EL_EMC_WALL_8
1431   };
1432   static int ep_mauer_num = sizeof(ep_mauer)/sizeof(int);
1433
1434   static int ep_can_fall[] =
1435   {
1436     EL_FELSBROCKEN,
1437     EL_BD_ROCK,
1438     EL_EDELSTEIN,
1439     EL_EDELSTEIN_BD,
1440     EL_EDELSTEIN_GELB,
1441     EL_EDELSTEIN_ROT,
1442     EL_EDELSTEIN_LILA,
1443     EL_DIAMANT,
1444     EL_BOMBE,
1445     EL_KOKOSNUSS,
1446     EL_TROPFEN,
1447     EL_MORAST_VOLL,
1448     EL_MAGIC_WALL_FULL,
1449     EL_MAGIC_WALL_BD_FULL,
1450     EL_ZEIT_VOLL,
1451     EL_ZEIT_LEER,
1452     EL_SP_ZONK,
1453     EL_SP_INFOTRON,
1454     EL_SP_DISK_ORANGE,
1455     EL_PEARL,
1456     EL_CRYSTAL,
1457     EL_SPRING,
1458     EL_DX_SUPABOMB
1459   };
1460   static int ep_can_fall_num = sizeof(ep_can_fall)/sizeof(int);
1461
1462   static int ep_can_smash[] =
1463   {
1464     EL_FELSBROCKEN,
1465     EL_BD_ROCK,
1466     EL_EDELSTEIN,
1467     EL_EDELSTEIN_BD,
1468     EL_EDELSTEIN_GELB,
1469     EL_EDELSTEIN_ROT,
1470     EL_EDELSTEIN_LILA,
1471     EL_DIAMANT,
1472     EL_SCHLUESSEL1,
1473     EL_SCHLUESSEL2,
1474     EL_SCHLUESSEL3,
1475     EL_SCHLUESSEL4,
1476     EL_EM_KEY_1,
1477     EL_EM_KEY_2,
1478     EL_EM_KEY_3,
1479     EL_EM_KEY_4,
1480     EL_BOMBE,
1481     EL_KOKOSNUSS,
1482     EL_TROPFEN,
1483     EL_ZEIT_VOLL,
1484     EL_ZEIT_LEER,
1485     EL_SP_ZONK,
1486     EL_SP_INFOTRON,
1487     EL_SP_DISK_ORANGE,
1488     EL_PEARL,
1489     EL_CRYSTAL,
1490     EL_SPRING,
1491     EL_DX_SUPABOMB
1492   };
1493   static int ep_can_smash_num = sizeof(ep_can_smash)/sizeof(int);
1494
1495   static int ep_can_change[] =
1496   {
1497     EL_FELSBROCKEN,
1498     EL_BD_ROCK,
1499     EL_EDELSTEIN,
1500     EL_EDELSTEIN_BD,
1501     EL_EDELSTEIN_GELB,
1502     EL_EDELSTEIN_ROT,
1503     EL_EDELSTEIN_LILA,
1504     EL_DIAMANT
1505   };
1506   static int ep_can_change_num = sizeof(ep_can_change)/sizeof(int);
1507
1508   static int ep_can_move[] =
1509   {
1510     EL_KAEFER,
1511     EL_FLIEGER,
1512     EL_BUTTERFLY,
1513     EL_FIREFLY,
1514     EL_MAMPFER,
1515     EL_MAMPFER2,
1516     EL_ROBOT,
1517     EL_PACMAN,
1518     EL_MOLE,
1519     EL_PINGUIN,
1520     EL_SCHWEIN,
1521     EL_DRACHE,
1522     EL_SONDE,
1523     EL_SP_SNIKSNAK,
1524     EL_SP_ELECTRON,
1525     EL_BALLOON,
1526     EL_SPRING_MOVING
1527   };
1528   static int ep_can_move_num = sizeof(ep_can_move)/sizeof(int);
1529
1530   static int ep_could_move[] =
1531   {
1532     EL_KAEFER_RIGHT,
1533     EL_KAEFER_UP,
1534     EL_KAEFER_LEFT,
1535     EL_KAEFER_DOWN,
1536     EL_FLIEGER_RIGHT,
1537     EL_FLIEGER_UP,
1538     EL_FLIEGER_LEFT,
1539     EL_FLIEGER_DOWN,
1540     EL_BUTTERFLY_RIGHT,
1541     EL_BUTTERFLY_UP,
1542     EL_BUTTERFLY_LEFT,
1543     EL_BUTTERFLY_DOWN,
1544     EL_FIREFLY_RIGHT,
1545     EL_FIREFLY_UP,
1546     EL_FIREFLY_LEFT,
1547     EL_FIREFLY_DOWN,
1548     EL_PACMAN_RIGHT,
1549     EL_PACMAN_UP,
1550     EL_PACMAN_LEFT,
1551     EL_PACMAN_DOWN
1552   };
1553   static int ep_could_move_num = sizeof(ep_could_move)/sizeof(int);
1554
1555   static int ep_dont_touch[] =
1556   {
1557     EL_KAEFER,
1558     EL_FLIEGER,
1559     EL_BUTTERFLY,
1560     EL_FIREFLY
1561   };
1562   static int ep_dont_touch_num = sizeof(ep_dont_touch)/sizeof(int);
1563
1564   static int ep_dont_go_to[] =
1565   {
1566     EL_KAEFER,
1567     EL_FLIEGER,
1568     EL_BUTTERFLY,
1569     EL_FIREFLY,
1570     EL_MAMPFER,
1571     EL_MAMPFER2,
1572     EL_ROBOT,
1573     EL_PACMAN,
1574     EL_TROPFEN,
1575     EL_SALZSAEURE,
1576     EL_SP_SNIKSNAK,
1577     EL_SP_ELECTRON,
1578     EL_SP_BUG_ACTIVE,
1579     EL_TRAP_ACTIVE,
1580     EL_LANDMINE
1581   };
1582   static int ep_dont_go_to_num = sizeof(ep_dont_go_to)/sizeof(int);
1583
1584   static int ep_mampf2[] =
1585   {
1586     EL_ERDREICH,
1587     EL_KAEFER,
1588     EL_FLIEGER,
1589     EL_BUTTERFLY,
1590     EL_FIREFLY,
1591     EL_MAMPFER,
1592     EL_ROBOT,
1593     EL_PACMAN,
1594     EL_TROPFEN,
1595     EL_AMOEBE_TOT,
1596     EL_AMOEBE_NASS,
1597     EL_AMOEBE_NORM,
1598     EL_AMOEBE_VOLL,
1599     EL_AMOEBE_BD,
1600     EL_EDELSTEIN,
1601     EL_EDELSTEIN_BD,
1602     EL_EDELSTEIN_GELB,
1603     EL_EDELSTEIN_ROT,
1604     EL_EDELSTEIN_LILA,
1605     EL_DIAMANT,
1606     EL_PEARL,
1607     EL_CRYSTAL
1608   };
1609   static int ep_mampf2_num = sizeof(ep_mampf2)/sizeof(int);
1610
1611   static int ep_bd_element[] =
1612   {
1613     EL_LEERRAUM,
1614     EL_ERDREICH,
1615     EL_FELSBODEN,
1616     EL_BD_WALL,
1617     EL_FELSBROCKEN,
1618     EL_BD_ROCK,
1619     EL_EDELSTEIN_BD,
1620     EL_MAGIC_WALL_BD_OFF,
1621     EL_AUSGANG_ZU,
1622     EL_AUSGANG_AUF,
1623     EL_BETON,
1624     EL_SPIELFIGUR,
1625     EL_FIREFLY,
1626     EL_FIREFLY_1,
1627     EL_FIREFLY_2,
1628     EL_FIREFLY_3,
1629     EL_FIREFLY_4,
1630     EL_BUTTERFLY,
1631     EL_BUTTERFLY_1,
1632     EL_BUTTERFLY_2,
1633     EL_BUTTERFLY_3,
1634     EL_BUTTERFLY_4,
1635     EL_AMOEBE_BD,
1636     EL_CHAR_FRAGE
1637   };
1638   static int ep_bd_element_num = sizeof(ep_bd_element)/sizeof(int);
1639
1640   static int ep_sb_element[] =
1641   {
1642     EL_LEERRAUM,
1643     EL_BETON,
1644     EL_SOKOBAN_OBJEKT,
1645     EL_SOKOBAN_FELD_LEER,
1646     EL_SOKOBAN_FELD_VOLL,
1647     EL_SPIELFIGUR,
1648     EL_INVISIBLE_STEEL
1649   };
1650   static int ep_sb_element_num = sizeof(ep_sb_element)/sizeof(int);
1651
1652   static int ep_gem[] =
1653   {
1654     EL_EDELSTEIN,
1655     EL_EDELSTEIN_BD,
1656     EL_EDELSTEIN_GELB,
1657     EL_EDELSTEIN_ROT,
1658     EL_EDELSTEIN_LILA,
1659     EL_DIAMANT,
1660     EL_SP_INFOTRON
1661   };
1662   static int ep_gem_num = sizeof(ep_gem)/sizeof(int);
1663
1664   static int ep_inactive[] =
1665   {
1666     EL_LEERRAUM,
1667     EL_ERDREICH,
1668     EL_MAUERWERK,
1669     EL_BD_WALL,
1670     EL_FELSBODEN,
1671     EL_SCHLUESSEL,
1672     EL_BETON,
1673     EL_AMOEBE_TOT,
1674     EL_MORAST_LEER,
1675     EL_BADEWANNE,
1676     EL_ABLENK_AUS,
1677     EL_SCHLUESSEL1,
1678     EL_SCHLUESSEL2,
1679     EL_SCHLUESSEL3,
1680     EL_SCHLUESSEL4,
1681     EL_EM_KEY_1,
1682     EL_EM_KEY_2,
1683     EL_EM_KEY_3,
1684     EL_EM_KEY_4,
1685     EL_PFORTE1,
1686     EL_PFORTE2,
1687     EL_PFORTE3,
1688     EL_PFORTE4,
1689     EL_PFORTE1X,
1690     EL_PFORTE2X,
1691     EL_PFORTE3X,
1692     EL_PFORTE4X,
1693     EL_EM_GATE_1,
1694     EL_EM_GATE_2,
1695     EL_EM_GATE_3,
1696     EL_EM_GATE_4,
1697     EL_EM_GATE_1X,
1698     EL_EM_GATE_2X,
1699     EL_EM_GATE_3X,
1700     EL_EM_GATE_4X,
1701     EL_DYNAMITE_INACTIVE,
1702     EL_UNSICHTBAR,
1703     EL_BIRNE_AUS,
1704     EL_BIRNE_EIN,
1705     EL_ERZ_EDEL,
1706     EL_ERZ_DIAM,
1707     EL_ERZ_EDEL_BD,
1708     EL_ERZ_EDEL_GELB,
1709     EL_DYNABOMB_NR,
1710     EL_DYNABOMB_SZ,
1711     EL_DYNABOMB_XL,
1712     EL_SOKOBAN_OBJEKT,
1713     EL_SOKOBAN_FELD_LEER,
1714     EL_SOKOBAN_FELD_VOLL,
1715     EL_ERZ_EDEL_ROT,
1716     EL_ERZ_EDEL_LILA,
1717     EL_BADEWANNE1,
1718     EL_BADEWANNE2,
1719     EL_BADEWANNE3,
1720     EL_BADEWANNE4,
1721     EL_BADEWANNE5,
1722     EL_MAGIC_WALL_OFF,
1723     EL_MAGIC_WALL_DEAD,
1724     EL_MAGIC_WALL_BD_OFF,
1725     EL_MAGIC_WALL_BD_DEAD,
1726     EL_AMOEBA2DIAM,
1727     EL_BLOCKED,
1728     EL_SP_EMPTY,
1729     EL_SP_BASE,
1730     EL_SP_PORT1_RIGHT,
1731     EL_SP_PORT1_DOWN,
1732     EL_SP_PORT1_LEFT,
1733     EL_SP_PORT1_UP,
1734     EL_SP_PORT2_RIGHT,
1735     EL_SP_PORT2_DOWN,
1736     EL_SP_PORT2_LEFT,
1737     EL_SP_PORT2_UP,
1738     EL_SP_PORT_X,
1739     EL_SP_PORT_Y,
1740     EL_SP_PORT_XY,
1741     EL_SP_DISK_RED,
1742     EL_SP_DISK_YELLOW,
1743     EL_SP_CHIP_SINGLE,
1744     EL_SP_CHIP_LEFT,
1745     EL_SP_CHIP_RIGHT,
1746     EL_SP_CHIP_UPPER,
1747     EL_SP_CHIP_LOWER,
1748     EL_SP_HARD_GRAY,
1749     EL_SP_HARD_GREEN,
1750     EL_SP_HARD_BLUE,
1751     EL_SP_HARD_RED,
1752     EL_SP_HARD_YELLOW,
1753     EL_SP_HARD_BASE1,
1754     EL_SP_HARD_BASE2,
1755     EL_SP_HARD_BASE3,
1756     EL_SP_HARD_BASE4,
1757     EL_SP_HARD_BASE5,
1758     EL_SP_HARD_BASE6,
1759     EL_SP_EXIT,
1760     EL_INVISIBLE_STEEL,
1761     EL_BELT1_SWITCH_LEFT,
1762     EL_BELT1_SWITCH_MIDDLE,
1763     EL_BELT1_SWITCH_RIGHT,
1764     EL_BELT2_SWITCH_LEFT,
1765     EL_BELT2_SWITCH_MIDDLE,
1766     EL_BELT2_SWITCH_RIGHT,
1767     EL_BELT3_SWITCH_LEFT,
1768     EL_BELT3_SWITCH_MIDDLE,
1769     EL_BELT3_SWITCH_RIGHT,
1770     EL_BELT4_SWITCH_LEFT,
1771     EL_BELT4_SWITCH_MIDDLE,
1772     EL_BELT4_SWITCH_RIGHT,
1773     EL_SIGN_EXCLAMATION,
1774     EL_SIGN_RADIOACTIVITY,
1775     EL_SIGN_STOP,
1776     EL_SIGN_WHEELCHAIR,
1777     EL_SIGN_PARKING,
1778     EL_SIGN_ONEWAY,
1779     EL_SIGN_HEART,
1780     EL_SIGN_TRIANGLE,
1781     EL_SIGN_ROUND,
1782     EL_SIGN_EXIT,
1783     EL_SIGN_YINYANG,
1784     EL_SIGN_OTHER,
1785     EL_STEEL_SLANTED,
1786     EL_EMC_STEEL_WALL_1,
1787     EL_EMC_STEEL_WALL_2,
1788     EL_EMC_STEEL_WALL_3,
1789     EL_EMC_STEEL_WALL_4,
1790     EL_EMC_WALL_1,
1791     EL_EMC_WALL_2,
1792     EL_EMC_WALL_3,
1793     EL_EMC_WALL_4,
1794     EL_EMC_WALL_5,
1795     EL_EMC_WALL_6,
1796     EL_EMC_WALL_7,
1797     EL_EMC_WALL_8
1798   };
1799   static int ep_inactive_num = sizeof(ep_inactive)/sizeof(int);
1800
1801   static int ep_explosive[] =
1802   {
1803     EL_BOMBE,
1804     EL_DYNAMITE_ACTIVE,
1805     EL_DYNAMITE_INACTIVE,
1806     EL_DYNABOMB_ACTIVE_1,
1807     EL_DYNABOMB_ACTIVE_2,
1808     EL_DYNABOMB_ACTIVE_3,
1809     EL_DYNABOMB_ACTIVE_4,
1810     EL_DYNABOMB_NR,
1811     EL_DYNABOMB_SZ,
1812     EL_DYNABOMB_XL,
1813     EL_KAEFER,
1814     EL_MOLE,
1815     EL_PINGUIN,
1816     EL_SCHWEIN,
1817     EL_DRACHE,
1818     EL_SONDE,
1819     EL_SP_DISK_RED,
1820     EL_SP_DISK_ORANGE,
1821     EL_SP_DISK_YELLOW,
1822     EL_SP_SNIKSNAK,
1823     EL_SP_ELECTRON,
1824     EL_DX_SUPABOMB
1825   };
1826   static int ep_explosive_num = sizeof(ep_explosive)/sizeof(int);
1827
1828   static int ep_mampf3[] =
1829   {
1830     EL_EDELSTEIN,
1831     EL_EDELSTEIN_BD,
1832     EL_EDELSTEIN_GELB,
1833     EL_EDELSTEIN_ROT,
1834     EL_EDELSTEIN_LILA,
1835     EL_DIAMANT,
1836     EL_PEARL,
1837     EL_CRYSTAL
1838   };
1839   static int ep_mampf3_num = sizeof(ep_mampf3)/sizeof(int);
1840
1841   static int ep_pushable[] =
1842   {
1843     EL_FELSBROCKEN,
1844     EL_BD_ROCK,
1845     EL_BOMBE,
1846     EL_KOKOSNUSS,
1847     EL_ZEIT_LEER,
1848     EL_SOKOBAN_FELD_VOLL,
1849     EL_SOKOBAN_OBJEKT,
1850     EL_SONDE,
1851     EL_SP_ZONK,
1852     EL_SP_DISK_ORANGE,
1853     EL_SP_DISK_YELLOW,
1854     EL_BALLOON,
1855     EL_SPRING,
1856     EL_DX_SUPABOMB
1857   };
1858   static int ep_pushable_num = sizeof(ep_pushable)/sizeof(int);
1859
1860   static int ep_player[] =
1861   {
1862     EL_SPIELFIGUR,
1863     EL_SPIELER1,
1864     EL_SPIELER2,
1865     EL_SPIELER3,
1866     EL_SPIELER4
1867   };
1868   static int ep_player_num = sizeof(ep_player)/sizeof(int);
1869
1870   static int ep_has_content[] =
1871   {
1872     EL_MAMPFER,
1873     EL_AMOEBE_NASS,
1874     EL_AMOEBE_NORM,
1875     EL_AMOEBE_VOLL,
1876     EL_AMOEBE_BD
1877   };
1878   static int ep_has_content_num = sizeof(ep_has_content)/sizeof(int);
1879
1880   static int ep_eatable[] =
1881   {
1882     EL_ERDREICH,
1883     EL_SP_BASE,
1884     EL_SP_BUG,
1885     EL_TRAP_INACTIVE,
1886     EL_SAND_INVISIBLE
1887   };
1888   static int ep_eatable_num = sizeof(ep_eatable)/sizeof(int);
1889
1890   static int ep_sp_element[] =
1891   {
1892     EL_SP_EMPTY,
1893     EL_SP_ZONK,
1894     EL_SP_BASE,
1895     EL_SP_MURPHY,
1896     EL_SP_INFOTRON,
1897     EL_SP_CHIP_SINGLE,
1898     EL_SP_HARD_GRAY,
1899     EL_SP_EXIT,
1900     EL_SP_DISK_ORANGE,
1901     EL_SP_PORT1_RIGHT,
1902     EL_SP_PORT1_DOWN,
1903     EL_SP_PORT1_LEFT,
1904     EL_SP_PORT1_UP,
1905     EL_SP_PORT2_RIGHT,
1906     EL_SP_PORT2_DOWN,
1907     EL_SP_PORT2_LEFT,
1908     EL_SP_PORT2_UP,
1909     EL_SP_SNIKSNAK,
1910     EL_SP_DISK_YELLOW,
1911     EL_SP_TERMINAL,
1912     EL_SP_DISK_RED,
1913     EL_SP_PORT_Y,
1914     EL_SP_PORT_X,
1915     EL_SP_PORT_XY,
1916     EL_SP_ELECTRON,
1917     EL_SP_BUG,
1918     EL_SP_CHIP_LEFT,
1919     EL_SP_CHIP_RIGHT,
1920     EL_SP_HARD_BASE1,
1921     EL_SP_HARD_GREEN,
1922     EL_SP_HARD_BLUE,
1923     EL_SP_HARD_RED,
1924     EL_SP_HARD_YELLOW,
1925     EL_SP_HARD_BASE2,
1926     EL_SP_HARD_BASE3,
1927     EL_SP_HARD_BASE4,
1928     EL_SP_HARD_BASE5,
1929     EL_SP_HARD_BASE6,
1930     EL_SP_CHIP_UPPER,
1931     EL_SP_CHIP_LOWER,
1932     /* additional elements that appeared in newer Supaplex levels */
1933     EL_UNSICHTBAR,
1934     /* more than one murphy in a level results in an inactive clone */
1935     EL_SP_MURPHY_CLONE
1936   };
1937   static int ep_sp_element_num = sizeof(ep_sp_element)/sizeof(int);
1938
1939   static int ep_quick_gate[] =
1940   {
1941     EL_EM_GATE_1,
1942     EL_EM_GATE_2,
1943     EL_EM_GATE_3,
1944     EL_EM_GATE_4,
1945     EL_EM_GATE_1X,
1946     EL_EM_GATE_2X,
1947     EL_EM_GATE_3X,
1948     EL_EM_GATE_4X,
1949     EL_SP_PORT1_LEFT,
1950     EL_SP_PORT2_LEFT,
1951     EL_SP_PORT1_RIGHT,
1952     EL_SP_PORT2_RIGHT,
1953     EL_SP_PORT1_UP,
1954     EL_SP_PORT2_UP,
1955     EL_SP_PORT1_DOWN,
1956     EL_SP_PORT2_DOWN,
1957     EL_SP_PORT_X,
1958     EL_SP_PORT_Y,
1959     EL_SP_PORT_XY,
1960     EL_SWITCHGATE_OPEN,
1961     EL_TIMEGATE_OPEN
1962   };
1963   static int ep_quick_gate_num = sizeof(ep_quick_gate)/sizeof(int);
1964
1965   static int ep_over_player[] =
1966   {
1967     EL_SP_PORT1_LEFT,
1968     EL_SP_PORT2_LEFT,
1969     EL_SP_PORT1_RIGHT,
1970     EL_SP_PORT2_RIGHT,
1971     EL_SP_PORT1_UP,
1972     EL_SP_PORT2_UP,
1973     EL_SP_PORT1_DOWN,
1974     EL_SP_PORT2_DOWN,
1975     EL_SP_PORT_X,
1976     EL_SP_PORT_Y,
1977     EL_SP_PORT_XY,
1978     EL_TUBE_CROSS,
1979     EL_TUBE_VERTICAL,
1980     EL_TUBE_HORIZONTAL,
1981     EL_TUBE_VERT_LEFT,
1982     EL_TUBE_VERT_RIGHT,
1983     EL_TUBE_HORIZ_UP,
1984     EL_TUBE_HORIZ_DOWN,
1985     EL_TUBE_LEFT_UP,
1986     EL_TUBE_LEFT_DOWN,
1987     EL_TUBE_RIGHT_UP,
1988     EL_TUBE_RIGHT_DOWN
1989   };
1990   static int ep_over_player_num = sizeof(ep_over_player)/sizeof(int);
1991
1992   static int ep_active_bomb[] =
1993   {
1994     EL_DYNAMITE_ACTIVE,
1995     EL_DYNABOMB_ACTIVE_1,
1996     EL_DYNABOMB_ACTIVE_2,
1997     EL_DYNABOMB_ACTIVE_3,
1998     EL_DYNABOMB_ACTIVE_4
1999   };
2000   static int ep_active_bomb_num = sizeof(ep_active_bomb)/sizeof(int);
2001
2002   static int ep_belt[] =
2003   {
2004     EL_BELT1_LEFT,
2005     EL_BELT1_MIDDLE,
2006     EL_BELT1_RIGHT,
2007     EL_BELT2_LEFT,
2008     EL_BELT2_MIDDLE,
2009     EL_BELT2_RIGHT,
2010     EL_BELT3_LEFT,
2011     EL_BELT3_MIDDLE,
2012     EL_BELT3_RIGHT,
2013     EL_BELT4_LEFT,
2014     EL_BELT4_MIDDLE,
2015     EL_BELT4_RIGHT,
2016   };
2017   static int ep_belt_num = sizeof(ep_belt)/sizeof(int);
2018
2019   static int ep_belt_switch[] =
2020   {
2021     EL_BELT1_SWITCH_LEFT,
2022     EL_BELT1_SWITCH_MIDDLE,
2023     EL_BELT1_SWITCH_RIGHT,
2024     EL_BELT2_SWITCH_LEFT,
2025     EL_BELT2_SWITCH_MIDDLE,
2026     EL_BELT2_SWITCH_RIGHT,
2027     EL_BELT3_SWITCH_LEFT,
2028     EL_BELT3_SWITCH_MIDDLE,
2029     EL_BELT3_SWITCH_RIGHT,
2030     EL_BELT4_SWITCH_LEFT,
2031     EL_BELT4_SWITCH_MIDDLE,
2032     EL_BELT4_SWITCH_RIGHT,
2033   };
2034   static int ep_belt_switch_num = sizeof(ep_belt_switch)/sizeof(int);
2035
2036   static int ep_tube[] =
2037   {
2038     EL_TUBE_CROSS,
2039     EL_TUBE_VERTICAL,
2040     EL_TUBE_HORIZONTAL,
2041     EL_TUBE_VERT_LEFT,
2042     EL_TUBE_VERT_RIGHT,
2043     EL_TUBE_HORIZ_UP,
2044     EL_TUBE_HORIZ_DOWN,
2045     EL_TUBE_LEFT_UP,
2046     EL_TUBE_LEFT_DOWN,
2047     EL_TUBE_RIGHT_UP,
2048     EL_TUBE_RIGHT_DOWN
2049   };
2050   static int ep_tube_num = sizeof(ep_tube)/sizeof(int);
2051
2052   static long ep1_bit[] =
2053   {
2054     EP_BIT_AMOEBALIVE,
2055     EP_BIT_AMOEBOID,
2056     EP_BIT_SCHLUESSEL,
2057     EP_BIT_PFORTE,
2058     EP_BIT_SOLID,
2059     EP_BIT_MASSIVE,
2060     EP_BIT_SLIPPERY,
2061     EP_BIT_ENEMY,
2062     EP_BIT_MAUER,
2063     EP_BIT_CAN_FALL,
2064     EP_BIT_CAN_SMASH,
2065     EP_BIT_CAN_CHANGE,
2066     EP_BIT_CAN_MOVE,
2067     EP_BIT_COULD_MOVE,
2068     EP_BIT_DONT_TOUCH,
2069     EP_BIT_DONT_GO_TO,
2070     EP_BIT_MAMPF2,
2071     EP_BIT_BD_ELEMENT,
2072     EP_BIT_SB_ELEMENT,
2073     EP_BIT_GEM,
2074     EP_BIT_INACTIVE,
2075     EP_BIT_EXPLOSIVE,
2076     EP_BIT_MAMPF3,
2077     EP_BIT_PUSHABLE,
2078     EP_BIT_PLAYER,
2079     EP_BIT_HAS_CONTENT,
2080     EP_BIT_EATABLE,
2081     EP_BIT_SP_ELEMENT,
2082     EP_BIT_QUICK_GATE,
2083     EP_BIT_OVER_PLAYER,
2084     EP_BIT_ACTIVE_BOMB
2085   };
2086   static long ep2_bit[] =
2087   {
2088     EP_BIT_BELT,
2089     EP_BIT_BELT_SWITCH,
2090     EP_BIT_TUBE
2091   };
2092   static int *ep1_array[] =
2093   {
2094     ep_amoebalive,
2095     ep_amoeboid,
2096     ep_schluessel,
2097     ep_pforte,
2098     ep_solid,
2099     ep_massive,
2100     ep_slippery,
2101     ep_enemy,
2102     ep_mauer,
2103     ep_can_fall,
2104     ep_can_smash,
2105     ep_can_change,
2106     ep_can_move,
2107     ep_could_move,
2108     ep_dont_touch,
2109     ep_dont_go_to,
2110     ep_mampf2,
2111     ep_bd_element,
2112     ep_sb_element,
2113     ep_gem,
2114     ep_inactive,
2115     ep_explosive,
2116     ep_mampf3,
2117     ep_pushable,
2118     ep_player,
2119     ep_has_content,
2120     ep_eatable,
2121     ep_sp_element,
2122     ep_quick_gate,
2123     ep_over_player,
2124     ep_active_bomb
2125   };
2126   static int *ep2_array[] =
2127   {
2128     ep_belt,
2129     ep_belt_switch,
2130     ep_tube
2131   };
2132   static int *ep1_num[] =
2133   {
2134     &ep_amoebalive_num,
2135     &ep_amoeboid_num,
2136     &ep_schluessel_num,
2137     &ep_pforte_num,
2138     &ep_solid_num,
2139     &ep_massive_num,
2140     &ep_slippery_num,
2141     &ep_enemy_num,
2142     &ep_mauer_num,
2143     &ep_can_fall_num,
2144     &ep_can_smash_num,
2145     &ep_can_change_num,
2146     &ep_can_move_num,
2147     &ep_could_move_num,
2148     &ep_dont_touch_num,
2149     &ep_dont_go_to_num,
2150     &ep_mampf2_num,
2151     &ep_bd_element_num,
2152     &ep_sb_element_num,
2153     &ep_gem_num,
2154     &ep_inactive_num,
2155     &ep_explosive_num,
2156     &ep_mampf3_num,
2157     &ep_pushable_num,
2158     &ep_player_num,
2159     &ep_has_content_num,
2160     &ep_eatable_num,
2161     &ep_sp_element_num,
2162     &ep_quick_gate_num,
2163     &ep_over_player_num,
2164     &ep_active_bomb_num
2165   };
2166   static int *ep2_num[] =
2167   {
2168     &ep_belt_num,
2169     &ep_belt_switch_num,
2170     &ep_tube_num
2171   };
2172   static int num_properties1 = sizeof(ep1_num)/sizeof(int *);
2173   static int num_properties2 = sizeof(ep2_num)/sizeof(int *);
2174
2175   for(i=0; i<MAX_ELEMENTS; i++)
2176   {
2177     Elementeigenschaften1[i] = 0;
2178     Elementeigenschaften2[i] = 0;
2179   }
2180
2181   for(i=0; i<num_properties1; i++)
2182     for(j=0; j<*(ep1_num[i]); j++)
2183       Elementeigenschaften1[(ep1_array[i])[j]] |= ep1_bit[i];
2184   for(i=0; i<num_properties2; i++)
2185     for(j=0; j<*(ep2_num[i]); j++)
2186       Elementeigenschaften2[(ep2_array[i])[j]] |= ep2_bit[i];
2187
2188   for(i=EL_CHAR_START; i<EL_CHAR_END; i++)
2189     Elementeigenschaften1[i] |= (EP_BIT_CHAR | EP_BIT_INACTIVE);
2190 }
2191
2192 void CloseAllAndExit(int exit_value)
2193 {
2194   int i;
2195
2196   if (sound_process_id)
2197   {
2198     StopSounds();
2199     kill(sound_process_id, SIGTERM);
2200     FreeSounds(NUM_SOUNDS);
2201   }
2202
2203   for(i=0; i<NUM_BITMAPS; i++)
2204   {
2205     if (pix[i])
2206     {
2207 #ifdef USE_XPM_LIBRARY
2208       if (i < NUM_PICTURES)     /* XPM pictures */
2209       {
2210         XFreeColors(display,DefaultColormap(display,screen),
2211                     xpm_att[i].pixels,xpm_att[i].npixels,0);
2212         XpmFreeAttributes(&xpm_att[i]);
2213       }
2214 #endif
2215
2216 #ifdef USE_SDL_LIBRARY
2217       SDL_FreeSurface(pix[i]);
2218 #else
2219       XFreePixmap(display,pix[i]);
2220 #endif
2221     }
2222
2223 #ifdef USE_SDL_LIBRARY
2224       SDL_FreeSurface(pix_masked[i]);
2225 #else
2226     if (clipmask[i])
2227       XFreePixmap(display,clipmask[i]);
2228     if (clip_gc[i])
2229       XFreeGC(display, clip_gc[i]);
2230 #endif
2231   }
2232
2233 #ifdef USE_SDL_LIBRARY
2234   KeyboardAutoRepeatOn();
2235 #else
2236   if (gc)
2237     XFreeGC(display, gc);
2238
2239   if (display)
2240   {
2241     KeyboardAutoRepeatOn();
2242     XCloseDisplay(display);
2243   }
2244 #endif
2245
2246 #ifdef MSDOS
2247   dumpErrorFile();
2248 #endif
2249
2250   exit(exit_value);
2251 }