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