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