1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-2002 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
14 #include "libgame/libgame.h"
29 static char *image_filename[NUM_PICTURES] =
43 static void InitSetup(void);
44 static void InitPlayerInfo(void);
45 static void InitLevelInfo(void);
46 static void InitArtworkInfo(void);
47 static void InitLevelArtworkInfo(void);
48 static void InitNetworkServer(void);
49 static void InitMixer(void);
50 static void InitSound(void);
51 static void InitGfx(void);
52 static void InitGfxBackground(void);
53 static void InitGadgets(void);
54 static void InitElementProperties(void);
55 static void Execute_Debug_Command(char *);
59 if (options.debug_command)
61 Execute_Debug_Command(options.debug_command);
66 if (options.serveronly)
68 #if defined(PLATFORM_UNIX)
69 NetworkServer(options.server_port, options.serveronly);
71 Error(ERR_WARN, "networking only supported in Unix version");
73 exit(0); /* never reached */
76 InitProgramInfo(UNIX_USERDATA_DIRECTORY,
77 PROGRAM_TITLE_STRING, getWindowTitleString(),
78 ICON_TITLE_STRING, X11_ICON_FILENAME, X11_ICONMASK_FILENAME,
79 MSDOS_POINTER_FILENAME,
80 COOKIE_PREFIX, FILENAME_PREFIX, GAME_VERSION_ACTUAL);
84 InitArtworkInfo(); /* needed before loading gfx, sound & music */
89 InitRND(NEW_RANDOMIZE);
92 InitVideoBuffer(&backbuffer, &window, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH,
95 InitEventFilter(FilterMouseMotionEvents);
98 InitElementProperties(); /* initializes IS_CHAR() for el2gfx() */
101 InitLevelArtworkInfo();
102 InitGadgets(); /* needs to know number of level series */
103 InitSound(); /* needs to know current level directory */
115 LoadSetup(); /* global setup info */
118 void InitPlayerInfo()
122 /* choose default local player */
123 local_player = &stored_player[0];
125 for (i=0; i<MAX_PLAYERS; i++)
126 stored_player[i].connected = FALSE;
128 local_player->connected = TRUE;
133 LoadLevelInfo(); /* global level info */
134 LoadLevelSetup_LastSeries(); /* last played series info */
135 LoadLevelSetup_SeriesInfo(); /* last played level info */
138 void InitArtworkInfo()
143 void InitLevelArtworkInfo()
145 LoadLevelArtworkInfo();
148 void InitNetworkServer()
150 #if defined(PLATFORM_UNIX)
154 if (!options.network)
157 #if defined(PLATFORM_UNIX)
158 nr_wanted = Request("Choose player", REQ_PLAYER | REQ_STAY_CLOSED);
160 if (!ConnectToServer(options.server_host, options.server_port))
161 Error(ERR_EXIT, "cannot connect to network game server");
163 SendToServer_PlayerName(setup.player_name);
164 SendToServer_ProtocolVersion();
167 SendToServer_NrWanted(nr_wanted);
171 static void InitMixer()
174 InitSoundList(sound_effects, NUM_SOUND_EFFECTS);
179 static void InitSound()
181 /* load custom sounds and music */
182 InitReloadSounds(artwork.snd_current->identifier);
183 InitReloadMusic(artwork.mus_current->identifier);
185 /* initialize sound effect lookup table for element actions */
189 static void InitTileClipmasks()
191 #if defined(TARGET_X11)
192 XGCValues clip_gc_values;
193 unsigned long clip_gc_valuemask;
195 #if defined(TARGET_X11_NATIVE)
203 tile_needs_clipping[] =
205 { GFX_SPIELER1_UP, 4 },
206 { GFX_SPIELER1_DOWN, 4 },
207 { GFX_SPIELER1_LEFT, 4 },
208 { GFX_SPIELER1_RIGHT, 4 },
209 { GFX_SPIELER1_PUSH_LEFT, 4 },
210 { GFX_SPIELER1_PUSH_RIGHT, 4 },
211 { GFX_SPIELER2_UP, 4 },
212 { GFX_SPIELER2_DOWN, 4 },
213 { GFX_SPIELER2_LEFT, 4 },
214 { GFX_SPIELER2_RIGHT, 4 },
215 { GFX_SPIELER2_PUSH_LEFT, 4 },
216 { GFX_SPIELER2_PUSH_RIGHT, 4 },
217 { GFX_SPIELER3_UP, 4 },
218 { GFX_SPIELER3_DOWN, 4 },
219 { GFX_SPIELER3_LEFT, 4 },
220 { GFX_SPIELER3_RIGHT, 4 },
221 { GFX_SPIELER3_PUSH_LEFT, 4 },
222 { GFX_SPIELER3_PUSH_RIGHT, 4 },
223 { GFX_SPIELER4_UP, 4 },
224 { GFX_SPIELER4_DOWN, 4 },
225 { GFX_SPIELER4_LEFT, 4 },
226 { GFX_SPIELER4_RIGHT, 4 },
227 { GFX_SPIELER4_PUSH_LEFT, 4 },
228 { GFX_SPIELER4_PUSH_RIGHT, 4 },
229 { GFX_SP_MURPHY, 1 },
230 { GFX_MURPHY_GO_LEFT, 3 },
231 { GFX_MURPHY_GO_RIGHT, 3 },
232 { GFX_MURPHY_SNAP_UP, 1 },
233 { GFX_MURPHY_SNAP_DOWN, 1 },
234 { GFX_MURPHY_SNAP_RIGHT, 1 },
235 { GFX_MURPHY_SNAP_LEFT, 1 },
236 { GFX_MURPHY_PUSH_RIGHT, 1 },
237 { GFX_MURPHY_PUSH_LEFT, 1 },
238 { GFX_GEBLUBBER, 4 },
241 { GFX_EXPLOSION, 8 },
242 { GFX_SOKOBAN_OBJEKT, 1 },
243 { GFX_FUNKELN_BLAU, 3 },
244 { GFX_FUNKELN_WEISS, 3 },
245 { GFX2_SHIELD_PASSIVE, 3 },
246 { GFX2_SHIELD_ACTIVE, 3 },
249 #endif /* TARGET_X11_NATIVE */
250 #endif /* TARGET_X11 */
254 /* initialize pixmap array for special X11 tile clipping to Pixmap 'None' */
255 for(i=0; i<NUM_TILES; i++)
256 tile_clipmask[i] = None;
258 #if defined(TARGET_X11)
259 /* This stuff is needed because X11 (XSetClipOrigin(), to be precise) is
260 often very slow when preparing a masked XCopyArea() for big Pixmaps.
261 To prevent this, create small (tile-sized) mask Pixmaps which will then
262 be set much faster with XSetClipOrigin() and speed things up a lot. */
264 clip_gc_values.graphics_exposures = False;
265 clip_gc_valuemask = GCGraphicsExposures;
267 XCreateGC(display, window->drawable, clip_gc_valuemask, &clip_gc_values);
269 for(i=0; i<NUM_BITMAPS; i++)
271 if (pix[i]->clip_mask)
273 clip_gc_values.graphics_exposures = False;
274 clip_gc_values.clip_mask = pix[i]->clip_mask;
275 clip_gc_valuemask = GCGraphicsExposures | GCClipMask;
276 pix[i]->stored_clip_gc = XCreateGC(display, window->drawable,
277 clip_gc_valuemask, &clip_gc_values);
281 #if defined(TARGET_X11_NATIVE)
283 /* create graphic context structures needed for clipping */
284 clip_gc_values.graphics_exposures = False;
285 clip_gc_valuemask = GCGraphicsExposures;
287 XCreateGC(display, pix[PIX_BACK]->clip_mask,
288 clip_gc_valuemask, &clip_gc_values);
290 /* create only those clipping Pixmaps we really need */
291 for(i=0; tile_needs_clipping[i].start>=0; i++)
295 for(j=0; j<tile_needs_clipping[i].count; j++)
297 int tile = tile_needs_clipping[i].start + j;
303 getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
304 src_pixmap = pix[pixmap_nr]->clip_mask;
306 tile_clipmask[tile] = XCreatePixmap(display, window->drawable,
309 XCopyArea(display, src_pixmap, tile_clipmask[tile], copy_clipmask_gc,
310 src_x, src_y, TILEX, TILEY, 0, 0);
314 XFreeGC(display, copy_clipmask_gc);
316 #endif /* TARGET_X11_NATIVE */
317 #endif /* TARGET_X11 */
320 void FreeTileClipmasks()
322 #if defined(TARGET_X11)
325 for(i=0; i<NUM_TILES; i++)
327 if (tile_clipmask[i] != None)
329 XFreePixmap(display, tile_clipmask[i]);
330 tile_clipmask[i] = None;
335 XFreeGC(display, tile_clip_gc);
338 for(i=0; i<NUM_BITMAPS; i++)
340 if (pix[i] != NULL && pix[i]->stored_clip_gc)
342 XFreeGC(display, pix[i]->stored_clip_gc);
343 pix[i]->stored_clip_gc = None;
346 #endif /* TARGET_X11 */
353 /* initialize some global variables */
354 global.frames_per_second = 0;
355 global.fps_slowdown = FALSE;
356 global.fps_slowdown_factor = 1;
358 /* initialize screen properties */
359 InitGfxFieldInfo(SX, SY, SXSIZE, SYSIZE,
360 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
361 InitGfxDoor1Info(DX, DY, DXSIZE, DYSIZE);
362 InitGfxDoor2Info(VX, VY, VXSIZE, VYSIZE);
363 InitGfxScrollbufferInfo(FXSIZE, FYSIZE);
365 /* create additional image buffers for double-buffering */
366 pix[PIX_DB_DOOR] = CreateBitmap(3 * DXSIZE, DYSIZE + VYSIZE, DEFAULT_DEPTH);
367 pix[PIX_DB_FIELD] = CreateBitmap(FXSIZE, FYSIZE, DEFAULT_DEPTH);
369 pix[PIX_SMALLFONT] = LoadCustomImage(image_filename[PIX_SMALLFONT]);
371 InitFontInfo(NULL, NULL, pix[PIX_SMALLFONT]);
373 DrawInitText(WINDOW_TITLE_STRING, 20, FC_YELLOW);
374 DrawInitText(WINDOW_SUBTITLE_STRING, 50, FC_RED);
376 DrawInitText("Loading graphics:", 120, FC_GREEN);
378 for(i=0; i<NUM_PICTURES; i++)
380 if (i != PIX_SMALLFONT)
382 DrawInitText(image_filename[i], 150, FC_YELLOW);
384 pix[i] = LoadCustomImage(image_filename[i]);
388 InitFontInfo(pix[PIX_BIGFONT], pix[PIX_MEDIUMFONT], pix[PIX_SMALLFONT]);
393 void InitGfxBackground()
398 fieldbuffer = pix[PIX_DB_FIELD];
399 SetDrawtoField(DRAW_BACKBUFFER);
401 BlitBitmap(pix[PIX_BACK], backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
402 ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
403 ClearRectangle(pix[PIX_DB_DOOR], 0, 0, 3 * DXSIZE, DYSIZE + VYSIZE);
405 for(x=0; x<MAX_BUF_XSIZE; x++)
406 for(y=0; y<MAX_BUF_YSIZE; y++)
409 redraw_mask = REDRAW_ALL;
412 void ReloadCustomArtwork()
414 static char *leveldir_current_identifier = NULL;
415 static boolean last_override_level_graphics = FALSE;
416 static boolean last_override_level_sounds = FALSE;
417 static boolean last_override_level_music = FALSE;
419 /* identifier for new artwork; default: artwork configured in setup */
420 char *gfx_new_identifier = artwork.gfx_current->identifier;
421 char *snd_new_identifier = artwork.snd_current->identifier;
422 char *mus_new_identifier = artwork.mus_current->identifier;
425 printf("graphics --> '%s' ('%s')\n",
426 artwork.gfx_current_identifier, artwork.gfx_current->filename);
427 printf("sounds --> '%s' ('%s')\n",
428 artwork.snd_current_identifier, artwork.snd_current->filename);
429 printf("music --> '%s' ('%s')\n",
430 artwork.mus_current_identifier, artwork.mus_current->filename);
433 /* leveldir_current may be invalid (level group, parent link) */
434 if (!validLevelSeries(leveldir_current))
438 printf("--> '%s'\n", artwork.gfx_current_identifier);
441 /* when a new level series was selected, check if there was a change
442 in custom artwork stored in level series directory */
443 if (leveldir_current_identifier != leveldir_current->identifier)
445 char *identifier_old = leveldir_current_identifier;
446 char *identifier_new = leveldir_current->identifier;
448 if (getTreeInfoFromIdentifier(artwork.gfx_first, identifier_old) !=
449 getTreeInfoFromIdentifier(artwork.gfx_first, identifier_new))
450 gfx_new_identifier = identifier_new;
451 if (getTreeInfoFromIdentifier(artwork.snd_first, identifier_old) !=
452 getTreeInfoFromIdentifier(artwork.snd_first, identifier_new))
453 snd_new_identifier = identifier_new;
454 if (getTreeInfoFromIdentifier(artwork.mus_first, identifier_new) !=
455 getTreeInfoFromIdentifier(artwork.mus_first, identifier_new))
456 artwork.mus_current_identifier = NULL;
458 leveldir_current_identifier = leveldir_current->identifier;
461 /* custom level artwork configured in level series configuration file
462 always overrides custom level artwork stored in level series directory
463 and (level independant) custom artwork configured in setup menue
464 (the path entry is needed to send it to the sound child process) */
465 if (leveldir_current->graphics_set != NULL)
467 if (leveldir_current->graphics_path)
468 free(leveldir_current->graphics_path);
469 leveldir_current->graphics_path = NULL;
470 leveldir_current->graphics_path =
471 getStringCopy(getLevelArtworkDir(artwork.gfx_first));
472 gfx_new_identifier = leveldir_current->graphics_set;
474 if (leveldir_current->sounds_set != NULL)
476 if (leveldir_current->sounds_path)
477 free(leveldir_current->sounds_path);
478 leveldir_current->sounds_path = NULL;
479 leveldir_current->sounds_path =
480 getStringCopy(getLevelArtworkDir(artwork.snd_first));
481 snd_new_identifier = leveldir_current->sounds_set;
483 if (leveldir_current->music_set != NULL)
485 if (leveldir_current->music_path)
486 free(leveldir_current->music_path);
487 leveldir_current->music_path = NULL;
488 leveldir_current->music_path =
489 getStringCopy(getLevelArtworkDir(artwork.mus_first));
490 mus_new_identifier = leveldir_current->music_set;
493 if (strcmp(artwork.gfx_current_identifier, gfx_new_identifier) != 0 ||
494 last_override_level_graphics != setup.override_level_graphics)
498 ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE);
500 for(i=0; i<NUM_PICTURES; i++)
502 DrawInitText(image_filename[i], 150, FC_YELLOW);
503 ReloadCustomImage(pix[i], image_filename[i]);
510 /* force redraw of (open or closed) door graphics */
511 SetDoorState(DOOR_OPEN_ALL);
512 CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY);
514 artwork.gfx_current_identifier = gfx_new_identifier;
515 last_override_level_graphics = setup.override_level_graphics;
518 if (strcmp(artwork.snd_current_identifier, snd_new_identifier) != 0 ||
519 last_override_level_sounds != setup.override_level_sounds)
521 InitReloadSounds(snd_new_identifier);
523 artwork.snd_current_identifier = snd_new_identifier;
524 last_override_level_sounds = setup.override_level_sounds;
527 if (strcmp(artwork.mus_current_identifier, mus_new_identifier) != 0 ||
528 last_override_level_music != setup.override_level_music)
530 InitReloadMusic(mus_new_identifier);
532 artwork.mus_current_identifier = mus_new_identifier;
533 last_override_level_music = setup.override_level_music;
537 printf("<-- '%s'\n", artwork.gfx_current_identifier);
543 CreateLevelEditorGadgets();
547 CreateScreenGadgets();
550 void InitElementProperties()
554 static int ep_amoebalive[] =
561 static int ep_amoebalive_num = SIZEOF_ARRAY_INT(ep_amoebalive);
563 static int ep_amoeboid[] =
571 static int ep_amoeboid_num = SIZEOF_ARRAY_INT(ep_amoeboid);
573 static int ep_schluessel[] =
584 static int ep_schluessel_num = SIZEOF_ARRAY_INT(ep_schluessel);
586 static int ep_pforte[] =
605 EL_SWITCHGATE_OPENING,
606 EL_SWITCHGATE_CLOSED,
607 EL_SWITCHGATE_CLOSING,
624 static int ep_pforte_num = SIZEOF_ARRAY_INT(ep_pforte);
626 static int ep_solid[] =
646 EL_QUICKSAND_FILLING,
647 EL_QUICKSAND_EMPTYING,
650 EL_MAGIC_WALL_EMPTYING,
651 EL_MAGIC_WALL_FILLING,
654 EL_MAGIC_WALL_BD_OFF,
655 EL_MAGIC_WALL_BD_EMPTY,
656 EL_MAGIC_WALL_BD_EMPTYING,
657 EL_MAGIC_WALL_BD_FULL,
658 EL_MAGIC_WALL_BD_FILLING,
659 EL_MAGIC_WALL_BD_DEAD,
684 EL_SP_TERMINAL_ACTIVE,
687 EL_BELT1_SWITCH_LEFT,
688 EL_BELT1_SWITCH_MIDDLE,
689 EL_BELT1_SWITCH_RIGHT,
690 EL_BELT2_SWITCH_LEFT,
691 EL_BELT2_SWITCH_MIDDLE,
692 EL_BELT2_SWITCH_RIGHT,
693 EL_BELT3_SWITCH_LEFT,
694 EL_BELT3_SWITCH_MIDDLE,
695 EL_BELT3_SWITCH_RIGHT,
696 EL_BELT4_SWITCH_LEFT,
697 EL_BELT4_SWITCH_MIDDLE,
698 EL_BELT4_SWITCH_RIGHT,
699 EL_SWITCHGATE_SWITCH_1,
700 EL_SWITCHGATE_SWITCH_2,
703 EL_TIMEGATE_SWITCH_OFF,
704 EL_TIMEGATE_SWITCH_ON,
706 EL_SIGN_RADIOACTIVITY,
750 EL_SWITCHGATE_OPENING,
751 EL_SWITCHGATE_CLOSED,
752 EL_SWITCHGATE_CLOSING,
769 static int ep_solid_num = SIZEOF_ARRAY_INT(ep_solid);
771 static int ep_massive[] =
792 EL_BELT1_SWITCH_LEFT,
793 EL_BELT1_SWITCH_MIDDLE,
794 EL_BELT1_SWITCH_RIGHT,
795 EL_BELT2_SWITCH_LEFT,
796 EL_BELT2_SWITCH_MIDDLE,
797 EL_BELT2_SWITCH_RIGHT,
798 EL_BELT3_SWITCH_LEFT,
799 EL_BELT3_SWITCH_MIDDLE,
800 EL_BELT3_SWITCH_RIGHT,
801 EL_BELT4_SWITCH_LEFT,
802 EL_BELT4_SWITCH_MIDDLE,
803 EL_BELT4_SWITCH_RIGHT,
807 EL_SIGN_RADIOACTIVITY,
841 EL_SWITCHGATE_OPENING,
842 EL_SWITCHGATE_CLOSED,
843 EL_SWITCHGATE_CLOSING,
860 static int ep_massive_num = SIZEOF_ARRAY_INT(ep_massive);
862 static int ep_slippery[] =
897 static int ep_slippery_num = SIZEOF_ARRAY_INT(ep_slippery);
899 static int ep_enemy[] =
912 static int ep_enemy_num = SIZEOF_ARRAY_INT(ep_enemy);
914 static int ep_mauer[] =
961 EL_SP_TERMINAL_ACTIVE,
978 static int ep_mauer_num = SIZEOF_ARRAY_INT(ep_mauer);
980 static int ep_can_fall[] =
995 EL_MAGIC_WALL_BD_FULL,
1006 static int ep_can_fall_num = SIZEOF_ARRAY_INT(ep_can_fall);
1008 static int ep_can_smash[] =
1039 static int ep_can_smash_num = SIZEOF_ARRAY_INT(ep_can_smash);
1041 static int ep_can_change[] =
1052 static int ep_can_change_num = SIZEOF_ARRAY_INT(ep_can_change);
1054 static int ep_can_move[] =
1074 static int ep_can_move_num = SIZEOF_ARRAY_INT(ep_can_move);
1076 static int ep_could_move[] =
1099 static int ep_could_move_num = SIZEOF_ARRAY_INT(ep_could_move);
1101 static int ep_dont_touch[] =
1108 static int ep_dont_touch_num = SIZEOF_ARRAY_INT(ep_dont_touch);
1110 static int ep_dont_go_to[] =
1128 static int ep_dont_go_to_num = SIZEOF_ARRAY_INT(ep_dont_go_to);
1130 static int ep_mampf2[] =
1155 static int ep_mampf2_num = SIZEOF_ARRAY_INT(ep_mampf2);
1157 static int ep_bd_element[] =
1166 EL_MAGIC_WALL_BD_OFF,
1184 static int ep_bd_element_num = SIZEOF_ARRAY_INT(ep_bd_element);
1186 static int ep_sb_element[] =
1191 EL_SOKOBAN_FELD_LEER,
1192 EL_SOKOBAN_FELD_VOLL,
1196 static int ep_sb_element_num = SIZEOF_ARRAY_INT(ep_sb_element);
1198 static int ep_gem[] =
1207 static int ep_gem_num = SIZEOF_ARRAY_INT(ep_gem);
1209 static int ep_inactive[] =
1246 EL_DYNAMITE_INACTIVE,
1258 EL_SOKOBAN_FELD_LEER,
1259 EL_SOKOBAN_FELD_VOLL,
1269 EL_MAGIC_WALL_BD_OFF,
1270 EL_MAGIC_WALL_BD_DEAD,
1306 EL_BELT1_SWITCH_LEFT,
1307 EL_BELT1_SWITCH_MIDDLE,
1308 EL_BELT1_SWITCH_RIGHT,
1309 EL_BELT2_SWITCH_LEFT,
1310 EL_BELT2_SWITCH_MIDDLE,
1311 EL_BELT2_SWITCH_RIGHT,
1312 EL_BELT3_SWITCH_LEFT,
1313 EL_BELT3_SWITCH_MIDDLE,
1314 EL_BELT3_SWITCH_RIGHT,
1315 EL_BELT4_SWITCH_LEFT,
1316 EL_BELT4_SWITCH_MIDDLE,
1317 EL_BELT4_SWITCH_RIGHT,
1318 EL_SIGN_EXCLAMATION,
1319 EL_SIGN_RADIOACTIVITY,
1331 EL_EMC_STEEL_WALL_1,
1332 EL_EMC_STEEL_WALL_2,
1333 EL_EMC_STEEL_WALL_3,
1334 EL_EMC_STEEL_WALL_4,
1344 static int ep_inactive_num = SIZEOF_ARRAY_INT(ep_inactive);
1346 static int ep_explosive[] =
1350 EL_DYNAMITE_INACTIVE,
1351 EL_DYNABOMB_ACTIVE_1,
1352 EL_DYNABOMB_ACTIVE_2,
1353 EL_DYNABOMB_ACTIVE_3,
1354 EL_DYNABOMB_ACTIVE_4,
1371 static int ep_explosive_num = SIZEOF_ARRAY_INT(ep_explosive);
1373 static int ep_mampf3[] =
1384 static int ep_mampf3_num = SIZEOF_ARRAY_INT(ep_mampf3);
1386 static int ep_pushable[] =
1393 EL_SOKOBAN_FELD_VOLL,
1403 static int ep_pushable_num = SIZEOF_ARRAY_INT(ep_pushable);
1405 static int ep_player[] =
1413 static int ep_player_num = SIZEOF_ARRAY_INT(ep_player);
1415 static int ep_has_content[] =
1423 static int ep_has_content_num = SIZEOF_ARRAY_INT(ep_has_content);
1425 static int ep_eatable[] =
1433 static int ep_eatable_num = SIZEOF_ARRAY_INT(ep_eatable);
1435 static int ep_sp_element[] =
1477 /* additional elements that appeared in newer Supaplex levels */
1479 /* more than one murphy in a level results in an inactive clone */
1482 static int ep_sp_element_num = SIZEOF_ARRAY_INT(ep_sp_element);
1484 static int ep_quick_gate[] =
1508 static int ep_quick_gate_num = SIZEOF_ARRAY_INT(ep_quick_gate);
1510 static int ep_over_player[] =
1535 static int ep_over_player_num = SIZEOF_ARRAY_INT(ep_over_player);
1537 static int ep_active_bomb[] =
1540 EL_DYNABOMB_ACTIVE_1,
1541 EL_DYNABOMB_ACTIVE_2,
1542 EL_DYNABOMB_ACTIVE_3,
1543 EL_DYNABOMB_ACTIVE_4
1545 static int ep_active_bomb_num = SIZEOF_ARRAY_INT(ep_active_bomb);
1547 static int ep_belt[] =
1562 static int ep_belt_num = SIZEOF_ARRAY_INT(ep_belt);
1564 static int ep_belt_switch[] =
1566 EL_BELT1_SWITCH_LEFT,
1567 EL_BELT1_SWITCH_MIDDLE,
1568 EL_BELT1_SWITCH_RIGHT,
1569 EL_BELT2_SWITCH_LEFT,
1570 EL_BELT2_SWITCH_MIDDLE,
1571 EL_BELT2_SWITCH_RIGHT,
1572 EL_BELT3_SWITCH_LEFT,
1573 EL_BELT3_SWITCH_MIDDLE,
1574 EL_BELT3_SWITCH_RIGHT,
1575 EL_BELT4_SWITCH_LEFT,
1576 EL_BELT4_SWITCH_MIDDLE,
1577 EL_BELT4_SWITCH_RIGHT,
1579 static int ep_belt_switch_num = SIZEOF_ARRAY_INT(ep_belt_switch);
1581 static int ep_tube[] =
1595 static int ep_tube_num = SIZEOF_ARRAY_INT(ep_tube);
1597 static long ep1_bit[] =
1631 static long ep2_bit[] =
1637 static int *ep1_array[] =
1671 static int *ep2_array[] =
1677 static int *ep1_num[] =
1704 &ep_has_content_num,
1708 &ep_over_player_num,
1711 static int *ep2_num[] =
1714 &ep_belt_switch_num,
1717 static int num_properties1 = SIZEOF_ARRAY(ep1_num, int *);
1718 static int num_properties2 = SIZEOF_ARRAY(ep2_num, int *);
1720 for(i=0; i<MAX_ELEMENTS; i++)
1722 Elementeigenschaften1[i] = 0;
1723 Elementeigenschaften2[i] = 0;
1726 for(i=0; i<num_properties1; i++)
1727 for(j=0; j<*(ep1_num[i]); j++)
1728 Elementeigenschaften1[(ep1_array[i])[j]] |= ep1_bit[i];
1729 for(i=0; i<num_properties2; i++)
1730 for(j=0; j<*(ep2_num[i]); j++)
1731 Elementeigenschaften2[(ep2_array[i])[j]] |= ep2_bit[i];
1733 for(i=EL_CHAR_START; i<=EL_CHAR_END; i++)
1734 Elementeigenschaften1[i] |= (EP_BIT_CHAR | EP_BIT_INACTIVE);
1737 void Execute_Debug_Command(char *command)
1739 if (strcmp(command, "create graphicsinfo.conf") == 0)
1741 printf("# (Currently only \"name\" and \"sort_priority\" recognized.)\n");
1743 printf("%s\n", getFormattedSetupEntry("name", "Classic Graphics"));
1745 printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
1747 else if (strcmp(command, "create soundsinfo.conf") == 0)
1751 printf("# You can configure additional/alternative sound effects here\n");
1752 printf("# (The sounds below are default and therefore commented out.)\n");
1754 printf("%s\n", getFormattedSetupEntry("name", "Classic Sounds"));
1756 printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
1759 for (i=0; i<NUM_SOUND_EFFECTS; i++)
1761 getFormattedSetupEntry(sound_effects[i].text,
1762 sound_effects[i].default_filename));
1764 else if (strcmp(command, "create musicinfo.conf") == 0)
1766 printf("# (Currently only \"name\" and \"sort_priority\" recognized.)\n");
1768 printf("%s\n", getFormattedSetupEntry("name", "Classic Music"));
1770 printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
1774 void CloseAllAndExit(int exit_value)
1781 CloseAudio(); /* called after freeing sounds (needed for SDL) */
1783 FreeTileClipmasks();
1784 for(i=0; i<NUM_BITMAPS; i++)
1787 CloseVideoDisplay();
1788 ClosePlatformDependantStuff();