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