X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Finit.c;h=5a16867bac61e49d7ca9ed0949a60231fe75590c;hb=72e44014938c9042261b67213a6cd37b7a17488f;hp=b689911c61d11ebc893b3d29a5a180cb3edb33e1;hpb=b8ccb648b89e24b27f8a60e2d8e9a4680322bd86;p=rocksndiamonds.git diff --git a/src/init.c b/src/init.c index b689911c..5a16867b 100644 --- a/src/init.c +++ b/src/init.c @@ -24,1695 +24,1742 @@ #include "network.h" #include "netserv.h" #include "cartoons.h" -#include "config.h" #include "conf_e2g.c" /* include auto-generated data structure definitions */ #include "conf_esg.c" /* include auto-generated data structure definitions */ #include "conf_e2s.c" /* include auto-generated data structure definitions */ #include "conf_fnt.c" /* include auto-generated data structure definitions */ + #define CONFIG_TOKEN_FONT_INITIAL "font.initial" + struct FontBitmapInfo font_initial[NUM_INITIAL_FONTS]; -static void InitGlobal(); -static void InitSetup(); -static void InitPlayerInfo(); -static void InitLevelInfo(); -static void InitArtworkInfo(); -static void InitLevelArtworkInfo(); -static void InitNetworkServer(); -static void InitArtworkConfig(); -static void InitImages(); -static void InitMixer(); -static void InitSound(); -static void InitMusic(); -static void InitGfx(); -static void InitGfxBackground(); -static void InitGadgets(); -static void InitFontGraphicInfo(); -static void InitElementSmallImages(); -static void InitElementGraphicInfo(); -static void InitElementSpecialGraphicInfo(); -static void InitElementSoundInfo(); -static void InitElementProperties(); -static void InitGraphicInfo(); -static void InitSoundInfo(); -static void Execute_Command(char *); -void OpenAll() +static void InitTileClipmasks() { - InitGlobal(); /* initialize some global variables */ +#if 0 +#if defined(TARGET_X11) + XGCValues clip_gc_values; + unsigned long clip_gc_valuemask; - if (options.execute_command) - Execute_Command(options.execute_command); +#if defined(TARGET_X11_NATIVE) - if (options.serveronly) +#if 0 + GC copy_clipmask_gc; + + static struct { -#if defined(PLATFORM_UNIX) - NetworkServer(options.server_port, options.serveronly); -#else - Error(ERR_WARN, "networking only supported in Unix version"); -#endif - exit(0); /* never reached */ + int start; + int count; } + tile_needs_clipping[] = + { + { GFX_SPIELER1_UP, 4 }, + { GFX_SPIELER1_DOWN, 4 }, + { GFX_SPIELER1_LEFT, 4 }, + { GFX_SPIELER1_RIGHT, 4 }, + { GFX_SPIELER1_PUSH_LEFT, 4 }, + { GFX_SPIELER1_PUSH_RIGHT, 4 }, + { GFX_SPIELER2_UP, 4 }, + { GFX_SPIELER2_DOWN, 4 }, + { GFX_SPIELER2_LEFT, 4 }, + { GFX_SPIELER2_RIGHT, 4 }, + { GFX_SPIELER2_PUSH_LEFT, 4 }, + { GFX_SPIELER2_PUSH_RIGHT, 4 }, + { GFX_SPIELER3_UP, 4 }, + { GFX_SPIELER3_DOWN, 4 }, + { GFX_SPIELER3_LEFT, 4 }, + { GFX_SPIELER3_RIGHT, 4 }, + { GFX_SPIELER3_PUSH_LEFT, 4 }, + { GFX_SPIELER3_PUSH_RIGHT, 4 }, + { GFX_SPIELER4_UP, 4 }, + { GFX_SPIELER4_DOWN, 4 }, + { GFX_SPIELER4_LEFT, 4 }, + { GFX_SPIELER4_RIGHT, 4 }, + { GFX_SPIELER4_PUSH_LEFT, 4 }, + { GFX_SPIELER4_PUSH_RIGHT, 4 }, + { GFX_SP_MURPHY, 1 }, + { GFX_MURPHY_GO_LEFT, 3 }, + { GFX_MURPHY_GO_RIGHT, 3 }, + { GFX_MURPHY_SNAP_UP, 1 }, + { GFX_MURPHY_SNAP_DOWN, 1 }, + { GFX_MURPHY_SNAP_RIGHT, 1 }, + { GFX_MURPHY_SNAP_LEFT, 1 }, + { GFX_MURPHY_PUSH_RIGHT, 1 }, + { GFX_MURPHY_PUSH_LEFT, 1 }, + { GFX_GEBLUBBER, 4 }, + { GFX_DYNAMIT, 7 }, + { GFX_DYNABOMB, 4 }, + { GFX_EXPLOSION, 8 }, + { GFX_SOKOBAN_OBJEKT, 1 }, + { GFX_FUNKELN_BLAU, 3 }, + { GFX_FUNKELN_WEISS, 3 }, + { GFX2_SHIELD_PASSIVE, 3 }, + { GFX2_SHIELD_ACTIVE, 3 }, + { -1, 0 } + }; +#endif - InitProgramInfo(UNIX_USERDATA_DIRECTORY, - PROGRAM_TITLE_STRING, getWindowTitleString(), - ICON_TITLE_STRING, X11_ICON_FILENAME, X11_ICONMASK_FILENAME, - MSDOS_POINTER_FILENAME, - COOKIE_PREFIX, FILENAME_PREFIX, GAME_VERSION_ACTUAL); - - InitSetup(); - InitPlayerInfo(); - InitArtworkInfo(); /* needed before loading gfx, sound & music */ - InitArtworkConfig(); /* needed before forking sound child process */ - InitMixer(); - - InitCounter(); - - InitJoysticks(); - InitRND(NEW_RANDOMIZE); +#endif /* TARGET_X11_NATIVE */ +#endif /* TARGET_X11 */ - InitVideoDisplay(); - InitVideoBuffer(&backbuffer, &window, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, - setup.fullscreen); + int i; - InitEventFilter(FilterMouseMotionEvents); + /* initialize pixmap array for special X11 tile clipping to Pixmap 'None' */ + for (i=0; idrawable, + clip_gc_valuemask, &clip_gc_values); - InitLevelInfo(); - InitLevelArtworkInfo(); +#if 0 + for (i=0; iclip_mask) + { + clip_gc_values.graphics_exposures = False; + clip_gc_values.clip_mask = pix[i]->clip_mask; + clip_gc_valuemask = GCGraphicsExposures | GCClipMask; + pix[i]->stored_clip_gc = XCreateGC(display, window->drawable, + clip_gc_valuemask, &clip_gc_values); + } + } +#endif - InitImages(); /* needs to know current level directory */ - InitSound(); /* needs to know current level directory */ - InitMusic(); /* needs to know current level directory */ +#if defined(TARGET_X11_NATIVE) - InitGfxBackground(); +#if 0 + /* create graphic context structures needed for clipping */ + clip_gc_values.graphics_exposures = False; + clip_gc_valuemask = GCGraphicsExposures; + copy_clipmask_gc = XCreateGC(display, pix[PIX_BACK]->clip_mask, + clip_gc_valuemask, &clip_gc_values); - if (global.autoplay_leveldir) + /* create only those clipping Pixmaps we really need */ + for (i=0; tile_needs_clipping[i].start>=0; i++) { - AutoPlayTape(); - return; - } + int j; - game_status = MAINMENU; + for (j=0; jclip_mask; - InitNetworkServer(); -} + tile_clipmask[tile] = XCreatePixmap(display, window->drawable, + TILEX, TILEY, 1); -static void InitGlobal() -{ - global.autoplay_leveldir = NULL; + XCopyArea(display, src_pixmap, tile_clipmask[tile], copy_clipmask_gc, + src_x, src_y, TILEX, TILEY, 0, 0); + } + } - global.frames_per_second = 0; - global.fps_slowdown = FALSE; - global.fps_slowdown_factor = 1; -} + XFreeGC(display, copy_clipmask_gc); +#endif -static void InitSetup() -{ - LoadSetup(); /* global setup info */ +#endif /* TARGET_X11_NATIVE */ +#endif /* TARGET_X11 */ +#endif } -static void InitPlayerInfo() +void FreeTileClipmasks() { +#if 0 +#if defined(TARGET_X11) int i; - /* choose default local player */ - local_player = &stored_player[0]; + for (i=0; iconnected = TRUE; +#if 0 + for (i=0; istored_clip_gc) + { + XFreeGC(display, pix[i]->stored_clip_gc); + pix[i]->stored_clip_gc = None; + } + } +#endif + +#endif /* TARGET_X11 */ +#endif } -static void InitLevelInfo() +void FreeGadgets() { - LoadLevelInfo(); /* global level info */ - LoadLevelSetup_LastSeries(); /* last played series info */ - LoadLevelSetup_SeriesInfo(); /* last played level info */ + FreeLevelEditorGadgets(); + FreeGameButtons(); + FreeTapeButtons(); + FreeToolButtons(); + FreeScreenGadgets(); } -static void InitArtworkInfo() +void InitGadgets() { - LoadArtworkInfo(); + static boolean gadgets_initialized = FALSE; + + if (gadgets_initialized) + FreeGadgets(); + + CreateLevelEditorGadgets(); + CreateGameButtons(); + CreateTapeButtons(); + CreateToolButtons(); + CreateScreenGadgets(); + + gadgets_initialized = TRUE; } -static char *get_element_class_token(int element) +void InitElementSmallImages() { - char *element_class_name = element_info[element].class_name; - char *element_class_token = checked_malloc(strlen(element_class_name) + 3); + struct PropertyMapping *property_mapping = getImageListPropertyMapping(); + int num_property_mappings = getImageListPropertyMappingSize(); + int i; - sprintf(element_class_token, "[%s]", element_class_name); + /* initialize normal images from static configuration */ + for (i=0; element_to_graphic[i].element > -1; i++) + CreateImageWithSmallImages(element_to_graphic[i].graphic); - return element_class_token; + /* initialize special images from static configuration */ + for (i=0; element_to_special_graphic[i].element > -1; i++) + CreateImageWithSmallImages(element_to_special_graphic[i].graphic); + + /* initialize images from dynamic configuration */ + for (i=0; i < num_property_mappings; i++) + if (property_mapping[i].artwork_index < MAX_NUM_ELEMENTS) + CreateImageWithSmallImages(property_mapping[i].artwork_index); } -static void InitArtworkConfig() +static int getFontBitmapID(int font_nr) { - static char *image_id_prefix[MAX_NUM_ELEMENTS + NUM_FONTS + 1]; - static char *sound_id_prefix[MAX_NUM_ELEMENTS + MAX_NUM_ELEMENTS + 1]; - static char *action_id_suffix[NUM_ACTIONS + 1]; - static char *direction_id_suffix[NUM_DIRECTIONS + 1]; - static char *special_id_suffix[NUM_SPECIAL_GFX_ARGS + 1]; - static char *dummy[1] = { NULL }; - static char *ignore_image_tokens[] = - { - "name", - "sort_priority", - "global.num_toons", - "menu.draw_xoffset", - "menu.draw_yoffset", - "menu.draw_xoffset.MAIN", - "menu.draw_yoffset.MAIN", - "door.step_offset", - "door.step_delay", - NULL - }; - static char *ignore_sound_tokens[] = - { - "name", - "sort_priority", - NULL - }; - int i; - - for (i=0; i -1; i++) + { + int font_nr = font_to_graphic[i].font_nr; + int special = font_to_graphic[i].special; + int graphic = font_to_graphic[i].graphic; - if (nr_wanted) - SendToServer_NrWanted(nr_wanted); -#endif -} + if (special != -1) + continue; -static void InitMixer() -{ - OpenAudio(); - StartMixer(); -} + font_info[font_nr].graphic = graphic; + } -static void ReinitializeGraphics() -{ - InitElementGraphicInfo(); /* element game graphic mapping */ - InitElementSpecialGraphicInfo(); /* element special graphic mapping */ - InitGraphicInfo(); /* graphic properties mapping */ + /* always start with reliable default values (special font graphics) */ + for (i=0; i < NUM_FONTS; i++) + { + for (j=0; j < NUM_SPECIAL_GFX_ARGS; j++) + { + font_info[i].special_graphic[j] = font_info[i].graphic; + font_info[i].special_bitmap_id[j] = i; + } + } - InitElementSmallImages(); /* create editor and preview images */ - InitFontGraphicInfo(); /* initialize text drawing functions */ + /* initialize special font/graphic mapping from static configuration */ + for (i=0; font_to_graphic[i].font_nr > -1; i++) + { + int font_nr = font_to_graphic[i].font_nr; + int special = font_to_graphic[i].special; + int graphic = font_to_graphic[i].graphic; - SetMainBackgroundImage(IMG_BACKGROUND); - SetDoorBackgroundImage(IMG_BACKGROUND_DOOR); + if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS) + { + font_info[font_nr].special_graphic[special] = graphic; + font_info[font_nr].special_bitmap_id[special] = num_font_bitmaps; + num_font_bitmaps++; + } + } - InitGadgets(); - InitToons(); -} + /* initialize special element/graphic mapping from dynamic configuration */ + for (i=0; i < num_property_mappings; i++) + { + int font_nr = property_mapping[i].base_index - MAX_NUM_ELEMENTS; + int special = property_mapping[i].ext3_index; + int graphic = property_mapping[i].artwork_index; -static void ReinitializeSounds() -{ - InitElementSoundInfo(); /* element game sound mapping */ - InitSoundInfo(); /* sound properties mapping */ + if (font_nr < 0) + continue; -#if 1 - InitElementSoundInfo(); /* element game sound mapping */ -#endif + if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS) + { + font_info[font_nr].special_graphic[special] = graphic; + font_info[font_nr].special_bitmap_id[special] = num_font_bitmaps; + num_font_bitmaps++; + } + } - InitPlaySoundLevel(); /* internal game sound settings */ -} + /* ---------- initialize font bitmap array ---------- */ -static void ReinitializeMusic() -{ - /* currently nothing to do */ -} + if (font_bitmap_info != NULL) + FreeFontInfo(font_bitmap_info); -static void InitImages() -{ - ReloadCustomImages(); + font_bitmap_info = + checked_calloc(num_font_bitmaps * sizeof(struct FontBitmapInfo)); - LoadCustomElementDescriptions(); - LoadSpecialMenuDesignSettings(); + /* ---------- initialize font bitmap definitions ---------- */ - ReinitializeGraphics(); -} + for (i=0; i < NUM_FONTS; i++) + { + if (i < NUM_INITIAL_FONTS) + { + font_bitmap_info[i] = font_initial[i]; + continue; + } -static void InitSound() -{ - InitReloadCustomSounds(artwork.snd_current->identifier); - ReinitializeSounds(); -} + for (j=0; j < NUM_SPECIAL_GFX_ARGS; j++) + { + int font_bitmap_id = font_info[i].special_bitmap_id[j]; + int graphic = font_info[i].special_graphic[j]; -static void InitMusic() -{ - InitReloadCustomMusic(artwork.mus_current->identifier); - ReinitializeMusic(); + /* set 'graphic_info' for font entries, if uninitialized (guessed) */ + if (graphic_info[graphic].anim_frames < MIN_NUM_CHARS_PER_FONT) + { + graphic_info[graphic].anim_frames = DEFAULT_NUM_CHARS_PER_FONT; + graphic_info[graphic].anim_frames_per_line= DEFAULT_NUM_CHARS_PER_LINE; + } + + /* copy font relevant information from graphics information */ + font_bitmap_info[font_bitmap_id].bitmap = graphic_info[graphic].bitmap; + font_bitmap_info[font_bitmap_id].src_x = graphic_info[graphic].src_x; + font_bitmap_info[font_bitmap_id].src_y = graphic_info[graphic].src_y; + font_bitmap_info[font_bitmap_id].width = graphic_info[graphic].width; + font_bitmap_info[font_bitmap_id].height = graphic_info[graphic].height; + font_bitmap_info[font_bitmap_id].draw_x = graphic_info[graphic].draw_x; + font_bitmap_info[font_bitmap_id].draw_y = graphic_info[graphic].draw_y; + + font_bitmap_info[font_bitmap_id].num_chars = + graphic_info[graphic].anim_frames; + font_bitmap_info[font_bitmap_id].num_chars_per_line = + graphic_info[graphic].anim_frames_per_line; + } + } + + InitFontInfo(font_bitmap_info, num_font_bitmaps, getFontBitmapID); } -static void InitTileClipmasks() +void InitElementGraphicInfo() { -#if 0 -#if defined(TARGET_X11) - XGCValues clip_gc_values; - unsigned long clip_gc_valuemask; + struct PropertyMapping *property_mapping = getImageListPropertyMapping(); + int num_property_mappings = getImageListPropertyMappingSize(); + int i, act, dir; -#if defined(TARGET_X11_NATIVE) + /* set values to -1 to identify later as "uninitialized" values */ + for (i=0; i -1; i++) { - int start; - int count; - } - tile_needs_clipping[] = - { - { GFX_SPIELER1_UP, 4 }, - { GFX_SPIELER1_DOWN, 4 }, - { GFX_SPIELER1_LEFT, 4 }, - { GFX_SPIELER1_RIGHT, 4 }, - { GFX_SPIELER1_PUSH_LEFT, 4 }, - { GFX_SPIELER1_PUSH_RIGHT, 4 }, - { GFX_SPIELER2_UP, 4 }, - { GFX_SPIELER2_DOWN, 4 }, - { GFX_SPIELER2_LEFT, 4 }, - { GFX_SPIELER2_RIGHT, 4 }, - { GFX_SPIELER2_PUSH_LEFT, 4 }, - { GFX_SPIELER2_PUSH_RIGHT, 4 }, - { GFX_SPIELER3_UP, 4 }, - { GFX_SPIELER3_DOWN, 4 }, - { GFX_SPIELER3_LEFT, 4 }, - { GFX_SPIELER3_RIGHT, 4 }, - { GFX_SPIELER3_PUSH_LEFT, 4 }, - { GFX_SPIELER3_PUSH_RIGHT, 4 }, - { GFX_SPIELER4_UP, 4 }, - { GFX_SPIELER4_DOWN, 4 }, - { GFX_SPIELER4_LEFT, 4 }, - { GFX_SPIELER4_RIGHT, 4 }, - { GFX_SPIELER4_PUSH_LEFT, 4 }, - { GFX_SPIELER4_PUSH_RIGHT, 4 }, - { GFX_SP_MURPHY, 1 }, - { GFX_MURPHY_GO_LEFT, 3 }, - { GFX_MURPHY_GO_RIGHT, 3 }, - { GFX_MURPHY_SNAP_UP, 1 }, - { GFX_MURPHY_SNAP_DOWN, 1 }, - { GFX_MURPHY_SNAP_RIGHT, 1 }, - { GFX_MURPHY_SNAP_LEFT, 1 }, - { GFX_MURPHY_PUSH_RIGHT, 1 }, - { GFX_MURPHY_PUSH_LEFT, 1 }, - { GFX_GEBLUBBER, 4 }, - { GFX_DYNAMIT, 7 }, - { GFX_DYNABOMB, 4 }, - { GFX_EXPLOSION, 8 }, - { GFX_SOKOBAN_OBJEKT, 1 }, - { GFX_FUNKELN_BLAU, 3 }, - { GFX_FUNKELN_WEISS, 3 }, - { GFX2_SHIELD_PASSIVE, 3 }, - { GFX2_SHIELD_ACTIVE, 3 }, - { -1, 0 } - }; -#endif + int element = element_to_graphic[i].element; + int action = element_to_graphic[i].action; + int direction = element_to_graphic[i].direction; + int graphic = element_to_graphic[i].graphic; -#endif /* TARGET_X11_NATIVE */ -#endif /* TARGET_X11 */ + if (graphic_info[graphic].bitmap == NULL) + continue; - int i; + if (action < 0) + action = ACTION_DEFAULT; - /* initialize pixmap array for special X11 tile clipping to Pixmap 'None' */ - for (i=0; i -1) + element_info[element].direction_graphic[action][direction] = graphic; + else + element_info[element].graphic[action] = graphic; + } -#if defined(TARGET_X11) - /* This stuff is needed because X11 (XSetClipOrigin(), to be precise) is - often very slow when preparing a masked XCopyArea() for big Pixmaps. - To prevent this, create small (tile-sized) mask Pixmaps which will then - be set much faster with XSetClipOrigin() and speed things up a lot. */ + /* initialize normal element/graphic mapping from dynamic configuration */ + for (i=0; i < num_property_mappings; i++) + { + int element = property_mapping[i].base_index; + int action = property_mapping[i].ext1_index; + int direction = property_mapping[i].ext2_index; + int special = property_mapping[i].ext3_index; + int graphic = property_mapping[i].artwork_index; - clip_gc_values.graphics_exposures = False; - clip_gc_valuemask = GCGraphicsExposures; - tile_clip_gc = XCreateGC(display, window->drawable, - clip_gc_valuemask, &clip_gc_values); + if (graphic_info[graphic].bitmap == NULL) + continue; -#if 0 - for (i=0; iclip_mask) - { - clip_gc_values.graphics_exposures = False; - clip_gc_values.clip_mask = pix[i]->clip_mask; - clip_gc_valuemask = GCGraphicsExposures | GCClipMask; - pix[i]->stored_clip_gc = XCreateGC(display, window->drawable, - clip_gc_valuemask, &clip_gc_values); - } - } -#endif + if (element >= MAX_NUM_ELEMENTS || special != -1) + continue; -#if defined(TARGET_X11_NATIVE) + if (action < 0) + action = ACTION_DEFAULT; -#if 0 - /* create graphic context structures needed for clipping */ - clip_gc_values.graphics_exposures = False; - clip_gc_valuemask = GCGraphicsExposures; - copy_clipmask_gc = XCreateGC(display, pix[PIX_BACK]->clip_mask, - clip_gc_valuemask, &clip_gc_values); + if (direction > -1) + element_info[element].direction_graphic[action][direction] = graphic; + else + element_info[element].graphic[action] = graphic; + } - /* create only those clipping Pixmaps we really need */ - for (i=0; tile_needs_clipping[i].start>=0; i++) + /* now set all '-1' values to element specific default values */ + for (i=0; iclip_mask; + if (default_action_graphic == -1) + default_action_graphic = IMG_CHAR_QUESTION; - tile_clipmask[tile] = XCreatePixmap(display, window->drawable, - TILEX, TILEY, 1); + for (dir=0; dirstored_clip_gc) - { - XFreeGC(display, pix[i]->stored_clip_gc); - pix[i]->stored_clip_gc = None; - } + for (i=0; i -1; i++) { - for (j=0; j < NUM_INITIAL_FONTS; j++) - { - char font_token[128]; - int len_font_token; + int element = element_to_special_graphic[i].element; + int special = element_to_special_graphic[i].special; + int graphic = element_to_special_graphic[i].graphic; + boolean base_redefined = getImageListEntry(el2img(element))->redefined; + boolean special_redefined = getImageListEntry(graphic)->redefined; - sprintf(font_token, "%s_%d", CONFIG_TOKEN_FONT_INITIAL, j + 1); - len_font_token = strlen(font_token); + if (base_redefined && !special_redefined) + continue; - if (strcmp(image_config[i].token, font_token) == 0) - filename_font_initial = image_config[i].value; - else if (strlen(image_config[i].token) > len_font_token && - strncmp(image_config[i].token, font_token, len_font_token) == 0) - { - if (strcmp(&image_config[i].token[len_font_token], ".x") == 0) - font_initial[j].src_x = atoi(image_config[i].value); - else if (strcmp(&image_config[i].token[len_font_token], ".y") == 0) - font_initial[j].src_y = atoi(image_config[i].value); - else if (strcmp(&image_config[i].token[len_font_token], ".width") == 0) - font_initial[j].width = atoi(image_config[i].value); - else if (strcmp(&image_config[i].token[len_font_token],".height") == 0) - font_initial[j].height = atoi(image_config[i].value); - } - } + element_info[element].special_graphic[special] = graphic; } - if (filename_font_initial == NULL) /* should not happen */ - Error(ERR_EXIT, "cannot get filename for '%s'", CONFIG_TOKEN_FONT_INITIAL); - - /* initialize screen properties */ - InitGfxFieldInfo(SX, SY, SXSIZE, SYSIZE, - REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); - InitGfxDoor1Info(DX, DY, DXSIZE, DYSIZE); - InitGfxDoor2Info(VX, VY, VXSIZE, VYSIZE); - InitGfxScrollbufferInfo(FXSIZE, FYSIZE); + /* initialize special element/graphic mapping from dynamic configuration */ + for (i=0; i < num_property_mappings; i++) + { + int element = property_mapping[i].base_index; + int special = property_mapping[i].ext3_index; + int graphic = property_mapping[i].artwork_index; - /* create additional image buffers for double-buffering */ - bitmap_db_field = CreateBitmap(FXSIZE, FYSIZE, DEFAULT_DEPTH); - bitmap_db_door = CreateBitmap(3 * DXSIZE, DYSIZE + VYSIZE, DEFAULT_DEPTH); + if (element >= MAX_NUM_ELEMENTS) + continue; - bitmap_font_initial = LoadCustomImage(filename_font_initial); - - for (j=0; j < NUM_INITIAL_FONTS; j++) - font_initial[j].bitmap = bitmap_font_initial; - - InitFontGraphicInfo(); - - DrawInitText(WINDOW_TITLE_STRING, 20, FC_YELLOW); - DrawInitText(WINDOW_SUBTITLE_STRING, 50, FC_RED); - - DrawInitText("Loading graphics:", 120, FC_GREEN); - - InitTileClipmasks(); + if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS) + element_info[element].special_graphic[special] = graphic; + } } -void InitGfxBackground() +static void set_graphic_parameters(int graphic, char **parameter_raw) { - int x, y; - - drawto = backbuffer; - fieldbuffer = bitmap_db_field; - SetDrawtoField(DRAW_BACKBUFFER); - - BlitBitmap(graphic_info[IMG_GLOBAL_BORDER].bitmap, backbuffer, - 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); - ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); - ClearRectangle(bitmap_db_door, 0, 0, 3 * DXSIZE, DYSIZE + VYSIZE); + Bitmap *src_bitmap = getBitmapFromImageID(graphic); + int parameter[NUM_GFX_ARGS]; + int anim_frames_per_row = 1, anim_frames_per_col = 1; + int anim_frames_per_line = 1; + int i; - for (x=0; xidentifier; - char *snd_new_identifier = artwork.snd_current->identifier; - char *mus_new_identifier = artwork.mus_current->identifier; - boolean redraw_screen = FALSE; + graphic_info[graphic].bitmap = src_bitmap; - if (leveldir_current_identifier == NULL) - leveldir_current_identifier = leveldir_current->identifier; + /* start with reliable default values */ + graphic_info[graphic].src_x = 0; + graphic_info[graphic].src_y = 0; + graphic_info[graphic].width = TILEX; + graphic_info[graphic].height = TILEY; + graphic_info[graphic].offset_x = 0; /* one or both of these values ... */ + graphic_info[graphic].offset_y = 0; /* ... will be corrected later */ -#if 0 - printf("CURRENT GFX: '%s' ['%s']\n", artwork.gfx_current->identifier, - leveldir_current->graphics_set); - printf("CURRENT LEV: '%s' / '%s'\n", leveldir_current_identifier, - leveldir_current->identifier); -#endif + /* optional x and y tile position of animation frame sequence */ + if (parameter[GFX_ARG_XPOS] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].src_x = parameter[GFX_ARG_XPOS] * TILEX; + if (parameter[GFX_ARG_YPOS] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].src_y = parameter[GFX_ARG_YPOS] * TILEY; -#if 0 - printf("graphics --> '%s' ('%s')\n", - artwork.gfx_current_identifier, artwork.gfx_current->filename); - printf("sounds --> '%s' ('%s')\n", - artwork.snd_current_identifier, artwork.snd_current->filename); - printf("music --> '%s' ('%s')\n", - artwork.mus_current_identifier, artwork.mus_current->filename); -#endif + /* optional x and y pixel position of animation frame sequence */ + if (parameter[GFX_ARG_X] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].src_x = parameter[GFX_ARG_X]; + if (parameter[GFX_ARG_Y] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].src_y = parameter[GFX_ARG_Y]; - /* leveldir_current may be invalid (level group, parent link) */ - if (!validLevelSeries(leveldir_current)) - return; + /* optional width and height of each animation frame */ + if (parameter[GFX_ARG_WIDTH] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].width = parameter[GFX_ARG_WIDTH]; + if (parameter[GFX_ARG_HEIGHT] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].height = parameter[GFX_ARG_HEIGHT]; - /* when a new level series was selected, check if there was a change - in custom artwork stored in level series directory */ - if (leveldir_current_identifier != leveldir_current->identifier) + if (src_bitmap) { - char *identifier_old = leveldir_current_identifier; - char *identifier_new = leveldir_current->identifier; - - if (getTreeInfoFromIdentifier(artwork.gfx_first, identifier_old) != - getTreeInfoFromIdentifier(artwork.gfx_first, identifier_new)) - gfx_new_identifier = identifier_new; - if (getTreeInfoFromIdentifier(artwork.snd_first, identifier_old) != - getTreeInfoFromIdentifier(artwork.snd_first, identifier_new)) - snd_new_identifier = identifier_new; - if (getTreeInfoFromIdentifier(artwork.mus_first, identifier_new) != - getTreeInfoFromIdentifier(artwork.mus_first, identifier_new)) - mus_new_identifier = identifier_new; - - leveldir_current_identifier = leveldir_current->identifier; + anim_frames_per_row = src_bitmap->width / graphic_info[graphic].width; + anim_frames_per_col = src_bitmap->height / graphic_info[graphic].height; } - /* custom level artwork configured in level series configuration file - always overrides custom level artwork stored in level series directory - and (level independant) custom artwork configured in setup menue */ - if (leveldir_current->graphics_set != NULL) - gfx_new_identifier = leveldir_current->graphics_set; - if (leveldir_current->sounds_set != NULL) - snd_new_identifier = leveldir_current->sounds_set; - if (leveldir_current->music_set != NULL) - mus_new_identifier = leveldir_current->music_set; - - if (strcmp(artwork.gfx_current_identifier, gfx_new_identifier) != 0 || - last_override_level_graphics != setup.override_level_graphics) + /* correct x or y offset dependant of vertical or horizontal frame order */ + if (parameter[GFX_ARG_VERTICAL]) /* frames are ordered vertically */ { -#if 0 - printf("RELOADING GRAPHICS '%s' -> '%s' ('%s')\n", - artwork.gfx_current_identifier, - artwork.gfx_current->identifier, - gfx_new_identifier); -#endif + graphic_info[graphic].offset_y = + (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE ? + parameter[GFX_ARG_OFFSET] : graphic_info[graphic].height); + anim_frames_per_line = anim_frames_per_col; + } + else /* frames are ordered horizontally */ + { + graphic_info[graphic].offset_x = + (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE ? + parameter[GFX_ARG_OFFSET] : graphic_info[graphic].width); + anim_frames_per_line = anim_frames_per_row; + } - setLevelArtworkDir(artwork.gfx_first); + /* optionally, the x and y offset of frames can be specified directly */ + if (parameter[GFX_ARG_XOFFSET] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].offset_x = parameter[GFX_ARG_XOFFSET]; + if (parameter[GFX_ARG_YOFFSET] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].offset_y = parameter[GFX_ARG_YOFFSET]; - ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE); + /* automatically determine correct number of frames, if not defined */ + if (parameter[GFX_ARG_FRAMES] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].anim_frames = parameter[GFX_ARG_FRAMES]; + else if (parameter[GFX_ARG_XPOS] == 0 && !parameter[GFX_ARG_VERTICAL]) + graphic_info[graphic].anim_frames = anim_frames_per_row; + else if (parameter[GFX_ARG_YPOS] == 0 && parameter[GFX_ARG_VERTICAL]) + graphic_info[graphic].anim_frames = anim_frames_per_col; + else + graphic_info[graphic].anim_frames = 1; - InitImages(); + graphic_info[graphic].anim_frames_per_line = + (parameter[GFX_ARG_FRAMES_PER_LINE] != ARG_UNDEFINED_VALUE ? + parameter[GFX_ARG_FRAMES_PER_LINE] : anim_frames_per_line); - FreeTileClipmasks(); - InitTileClipmasks(); + graphic_info[graphic].anim_delay = parameter[GFX_ARG_DELAY]; + if (graphic_info[graphic].anim_delay == 0) /* delay must be at least 1 */ + graphic_info[graphic].anim_delay = 1; - artwork.gfx_current_identifier = artwork.gfx_current->identifier; - last_override_level_graphics = setup.override_level_graphics; + graphic_info[graphic].anim_mode = parameter[GFX_ARG_ANIM_MODE]; + if (graphic_info[graphic].anim_frames == 1) + graphic_info[graphic].anim_mode = ANIM_NONE; - redraw_screen = TRUE; - } + /* automatically determine correct start frame, if not defined */ + if (parameter[GFX_ARG_START_FRAME] == ARG_UNDEFINED_VALUE) + graphic_info[graphic].anim_start_frame = 0; + else if (graphic_info[graphic].anim_mode & ANIM_REVERSE) + graphic_info[graphic].anim_start_frame = + graphic_info[graphic].anim_frames - parameter[GFX_ARG_START_FRAME] - 1; + else + graphic_info[graphic].anim_start_frame = parameter[GFX_ARG_START_FRAME]; - if (strcmp(artwork.snd_current_identifier, snd_new_identifier) != 0 || - last_override_level_sounds != setup.override_level_sounds) - { -#if 0 - printf("RELOADING SOUNDS '%s' -> '%s' ('%s')\n", - artwork.snd_current_identifier, - artwork.snd_current->identifier, - snd_new_identifier); -#endif + /* animation synchronized with global frame counter, not move position */ + graphic_info[graphic].anim_global_sync = parameter[GFX_ARG_GLOBAL_SYNC]; - /* set artwork path to send it to the sound server process */ - setLevelArtworkDir(artwork.snd_first); + /* this is only used for toon animations */ + graphic_info[graphic].step_offset = parameter[GFX_ARG_STEP_OFFSET]; + graphic_info[graphic].step_delay = parameter[GFX_ARG_STEP_DELAY]; - InitReloadCustomSounds(snd_new_identifier); - ReinitializeSounds(); + /* this is only used for drawing font characters */ + graphic_info[graphic].draw_x = parameter[GFX_ARG_DRAW_XOFFSET]; + graphic_info[graphic].draw_y = parameter[GFX_ARG_DRAW_YOFFSET]; +} - artwork.snd_current_identifier = artwork.snd_current->identifier; - last_override_level_sounds = setup.override_level_sounds; +static void InitGraphicInfo() +{ + int fallback_graphic = IMG_CHAR_EXCLAM; + struct FileInfo *fallback_image = getImageListEntry(fallback_graphic); + Bitmap *fallback_bitmap = getBitmapFromImageID(fallback_graphic); + int num_images = getImageListSize(); + int i; - redraw_screen = TRUE; - } +#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) + static boolean clipmasks_initialized = FALSE; + Pixmap src_pixmap; + XGCValues clip_gc_values; + unsigned long clip_gc_valuemask; + GC copy_clipmask_gc = None; +#endif - if (strcmp(artwork.mus_current_identifier, mus_new_identifier) != 0 || - last_override_level_music != setup.override_level_music) - { - /* set artwork path to send it to the sound server process */ - setLevelArtworkDir(artwork.mus_first); + if (graphic_info != NULL) + free(graphic_info); - InitReloadCustomMusic(mus_new_identifier); - ReinitializeMusic(); + graphic_info = checked_calloc(num_images * sizeof(struct GraphicInfo)); - artwork.mus_current_identifier = artwork.mus_current->identifier; - last_override_level_music = setup.override_level_music; +#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) + if (clipmasks_initialized) + { + for (i=0; iparameter); -void FreeGadgets() -{ - FreeLevelEditorGadgets(); - FreeGameButtons(); - FreeTapeButtons(); - FreeToolButtons(); - FreeScreenGadgets(); -} + /* now check if no animation frames are outside of the loaded image */ -void InitGadgets() -{ - static boolean gadgets_initialized = FALSE; + if (graphic_info[i].bitmap == NULL) + continue; /* skip check for optional images that are undefined */ - if (gadgets_initialized) - FreeGadgets(); + first_frame = 0; + getGraphicSource(i, first_frame, &src_bitmap, &src_x, &src_y); + if (src_x < 0 || src_y < 0 || + src_x + TILEX > src_bitmap->width || + src_y + TILEY > src_bitmap->height) + { + Error(ERR_RETURN_LINE, "-"); + Error(ERR_RETURN, "warning: error found in config file:"); + Error(ERR_RETURN, "- config file: '%s'", + getImageConfigFilename()); + Error(ERR_RETURN, "- config token: '%s'", + getTokenFromImageID(i)); + Error(ERR_RETURN, "- image file: '%s'", + src_bitmap->source_filename); + Error(ERR_RETURN, + "error: first animation frame out of bounds (%d, %d)", + src_x, src_y); + Error(ERR_RETURN, "custom graphic rejected for this element/action"); - CreateLevelEditorGadgets(); - CreateGameButtons(); - CreateTapeButtons(); - CreateToolButtons(); - CreateScreenGadgets(); + if (i == fallback_graphic) + Error(ERR_EXIT, "fatal error: no fallback graphic available"); - gadgets_initialized = TRUE; -} + Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic"); + Error(ERR_RETURN_LINE, "-"); -void InitElementSmallImages() -{ - struct PropertyMapping *property_mapping = getImageListPropertyMapping(); - int num_property_mappings = getImageListPropertyMappingSize(); - int i; + set_graphic_parameters(i, fallback_image->default_parameter); + graphic_info[i].bitmap = fallback_bitmap; + } - /* initialize normal images from static configuration */ - for (i=0; element_to_graphic[i].element > -1; i++) - CreateImageWithSmallImages(element_to_graphic[i].graphic); + last_frame = graphic_info[i].anim_frames - 1; + getGraphicSource(i, last_frame, &src_bitmap, &src_x, &src_y); + if (src_x < 0 || src_y < 0 || + src_x + TILEX > src_bitmap->width || + src_y + TILEY > src_bitmap->height) + { + Error(ERR_RETURN_LINE, "-"); + Error(ERR_RETURN, "warning: error found in config file:"); + Error(ERR_RETURN, "- config file: '%s'", + getImageConfigFilename()); + Error(ERR_RETURN, "- config token: '%s'", + getTokenFromImageID(i)); + Error(ERR_RETURN, "- image file: '%s'", + src_bitmap->source_filename); + Error(ERR_RETURN, + "error: last animation frame (%d) out of bounds (%d, %d)", + last_frame, src_x, src_y); + Error(ERR_RETURN, "custom graphic rejected for this element/action"); - /* initialize special images from static configuration */ - for (i=0; element_to_special_graphic[i].element > -1; i++) - CreateImageWithSmallImages(element_to_special_graphic[i].graphic); + if (i == fallback_graphic) + Error(ERR_EXIT, "fatal error: no fallback graphic available"); - /* initialize images from dynamic configuration */ - for (i=0; i < num_property_mappings; i++) - if (property_mapping[i].artwork_index < MAX_NUM_ELEMENTS) - CreateImageWithSmallImages(property_mapping[i].artwork_index); -} + Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic"); + Error(ERR_RETURN_LINE, "-"); -static int getFontBitmapID(int font_nr) -{ - int special = -1; + set_graphic_parameters(i, fallback_image->default_parameter); + graphic_info[i].bitmap = fallback_bitmap; + } - if (game_status == MAINMENU || game_status == TYPENAME) - special = GFX_SPECIAL_ARG_MAIN; - else if (game_status == CHOOSELEVEL) - special = GFX_SPECIAL_ARG_LEVELS; - else if (game_status == HALLOFFAME) - special = GFX_SPECIAL_ARG_SCORES; - else if (game_status == LEVELED) - special = GFX_SPECIAL_ARG_EDITOR; - else if (game_status == HELPSCREEN) - special = GFX_SPECIAL_ARG_INFO; - else if (game_status == SETUP) - special = GFX_SPECIAL_ARG_SETUP; - else if (game_status == PSEUDO_PREVIEW) - special = GFX_SPECIAL_ARG_PREVIEW; - else if (game_status == PLAYING || game_status == PSEUDO_DOOR) - special = GFX_SPECIAL_ARG_DOOR; +#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) + /* currently we need only a tile clip mask from the first frame */ + getGraphicSource(i, first_frame, &src_bitmap, &src_x, &src_y); - if (special != -1) - return font_info[font_nr].special_bitmap_id[special]; - else - return font_nr; -} + if (copy_clipmask_gc == None) + { + clip_gc_values.graphics_exposures = False; + clip_gc_valuemask = GCGraphicsExposures; + copy_clipmask_gc = XCreateGC(display, src_bitmap->clip_mask, + clip_gc_valuemask, &clip_gc_values); + } -void InitFontGraphicInfo() -{ - static struct FontBitmapInfo *font_bitmap_info = NULL; - struct PropertyMapping *property_mapping = getImageListPropertyMapping(); - int num_property_mappings = getImageListPropertyMappingSize(); - int num_font_bitmaps = NUM_FONTS; - int i, j; + graphic_info[i].clip_mask = + XCreatePixmap(display, window->drawable, TILEX, TILEY, 1); - if (graphic_info == NULL) /* still at startup phase */ - { - InitFontInfo(font_initial, NUM_INITIAL_FONTS, getFontBitmapID); + src_pixmap = src_bitmap->clip_mask; + XCopyArea(display, src_pixmap, graphic_info[i].clip_mask, + copy_clipmask_gc, src_x, src_y, TILEX, TILEY, 0, 0); - return; - } + clip_gc_values.graphics_exposures = False; + clip_gc_values.clip_mask = graphic_info[i].clip_mask; + clip_gc_valuemask = GCGraphicsExposures | GCClipMask; - /* ---------- initialize font graphic definitions ---------- */ + graphic_info[i].clip_gc = + XCreateGC(display, window->drawable, clip_gc_valuemask, &clip_gc_values); +#endif + } - /* always start with reliable default values (normal font graphics) */ - for (i=0; i < NUM_FONTS; i++) - font_info[i].graphic = FONT_INITIAL_1; +#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) + if (copy_clipmask_gc) + XFreeGC(display, copy_clipmask_gc); - /* initialize normal font/graphic mapping from static configuration */ - for (i=0; font_to_graphic[i].font_nr > -1; i++) - { - int font_nr = font_to_graphic[i].font_nr; - int special = font_to_graphic[i].special; - int graphic = font_to_graphic[i].graphic; + clipmasks_initialized = TRUE; +#endif +} - if (special != -1) - continue; +static void InitElementSoundInfo() +{ + struct PropertyMapping *property_mapping = getSoundListPropertyMapping(); + int num_property_mappings = getSoundListPropertyMappingSize(); + int i, j, act; - font_info[font_nr].graphic = graphic; - } + /* set values to -1 to identify later as "uninitialized" values */ + for (i=0; i < MAX_NUM_ELEMENTS; i++) + for (act=0; act < NUM_ACTIONS; act++) + element_info[i].sound[act] = -1; - /* always start with reliable default values (special font graphics) */ - for (i=0; i < NUM_FONTS; i++) + /* initialize element/sound mapping from static configuration */ + for (i=0; element_to_sound[i].element > -1; i++) { - for (j=0; j < NUM_SPECIAL_GFX_ARGS; j++) - { - font_info[i].special_graphic[j] = font_info[i].graphic; - font_info[i].special_bitmap_id[j] = i; - } - } + int element = element_to_sound[i].element; + int action = element_to_sound[i].action; + int sound = element_to_sound[i].sound; + boolean is_class = element_to_sound[i].is_class; - /* initialize special font/graphic mapping from static configuration */ - for (i=0; font_to_graphic[i].font_nr > -1; i++) - { - int font_nr = font_to_graphic[i].font_nr; - int special = font_to_graphic[i].special; - int graphic = font_to_graphic[i].graphic; + if (action < 0) + action = ACTION_DEFAULT; - if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS) - { - font_info[font_nr].special_graphic[special] = graphic; - font_info[font_nr].special_bitmap_id[special] = num_font_bitmaps; - num_font_bitmaps++; - } + if (!is_class) + element_info[element].sound[action] = sound; + else + for (j=0; j < MAX_NUM_ELEMENTS; j++) + if (strcmp(element_info[j].class_name, + element_info[element].class_name) == 0) + element_info[j].sound[action] = sound; } - /* initialize special element/graphic mapping from dynamic configuration */ + /* initialize element/sound mapping from dynamic configuration */ for (i=0; i < num_property_mappings; i++) { - int font_nr = property_mapping[i].base_index - MAX_NUM_ELEMENTS; - int special = property_mapping[i].ext3_index; - int graphic = property_mapping[i].artwork_index; + int element = property_mapping[i].base_index; + int action = property_mapping[i].ext1_index; + int sound = property_mapping[i].artwork_index; - if (font_nr < 0) + if (element >= MAX_NUM_ELEMENTS) continue; - if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS) - { - font_info[font_nr].special_graphic[special] = graphic; - font_info[font_nr].special_bitmap_id[special] = num_font_bitmaps; - num_font_bitmaps++; - } + if (action < 0) + action = ACTION_DEFAULT; + + element_info[element].sound[action] = sound; } - /* ---------- initialize font bitmap array ---------- */ + /* initialize element class/sound mapping from dynamic configuration */ + for (i=0; i < num_property_mappings; i++) + { + int element_class = property_mapping[i].base_index - MAX_NUM_ELEMENTS; + int action = property_mapping[i].ext1_index; + int sound = property_mapping[i].artwork_index; - if (font_bitmap_info != NULL) - free(font_bitmap_info); + if (element_class < 0 || element_class >= MAX_NUM_ELEMENTS) + continue; - font_bitmap_info = - checked_calloc(num_font_bitmaps * sizeof(struct FontBitmapInfo)); + if (action < 0) + action = ACTION_DEFAULT; - /* ---------- initialize font bitmap definitions ---------- */ + for (j=0; j < MAX_NUM_ELEMENTS; j++) + if (strcmp(element_info[j].class_name, + element_info[element_class].class_name) == 0) + element_info[j].sound[action] = sound; + } - for (i=0; i < NUM_FONTS; i++) + /* now set all '-1' values to element specific default values */ + for (i=0; itoken); + + sound_effect_properties[i] = ACTION_OTHER; + sound_info[i].loop = FALSE; + + /* determine all loop sounds and identify certain sound classes */ + + for (j=0; element_action_info[j].suffix; j++) { - element_info[i].graphic[act] = -1; + int len_action_text = strlen(element_action_info[j].suffix); - for (dir=0; dirtoken[len_effect_text - len_action_text], + element_action_info[j].suffix) == 0) + { + sound_effect_properties[i] = element_action_info[j].value; + + if (element_action_info[j].is_loop_sound) + sound_info[i].loop = TRUE; + } } - } - /* initialize normal element/graphic mapping from static configuration */ - for (i=0; element_to_graphic[i].element > -1; i++) - { - int element = element_to_graphic[i].element; - int action = element_to_graphic[i].action; - int direction = element_to_graphic[i].direction; - int graphic = element_to_graphic[i].graphic; + /* associate elements and some selected sound actions */ - if (action < 0) - action = ACTION_DEFAULT; + for (j=0; j -1) - element_info[element].direction_graphic[action][direction] = graphic; - else - element_info[element].graphic[action] = graphic; + if (len_class_text + 1 < len_effect_text && + strncmp(sound->token, + element_info[j].class_name, len_class_text) == 0 && + sound->token[len_class_text] == '.') + { + int sound_action_value = sound_effect_properties[i]; + + element_info[j].sound[sound_action_value] = i; + } + } + } + + set_sound_parameters(i, sound->parameter); } - /* initialize normal element/graphic mapping from dynamic configuration */ + free(sound_effect_properties); + + /* initialize element/sound mapping from dynamic configuration */ for (i=0; i < num_property_mappings; i++) { int element = property_mapping[i].base_index; int action = property_mapping[i].ext1_index; - int direction = property_mapping[i].ext2_index; - int special = property_mapping[i].ext3_index; - int graphic = property_mapping[i].artwork_index; - - if (element >= MAX_NUM_ELEMENTS || special != -1) - continue; + int sound = property_mapping[i].artwork_index; if (action < 0) action = ACTION_DEFAULT; - if (direction > -1) - element_info[element].direction_graphic[action][direction] = graphic; - else - element_info[element].graphic[action] = graphic; + element_info[element].sound[action] = sound; } - /* now set all '-1' values to element specific default values */ - for (i=0; i -1; i++) - { - int element = element_to_special_graphic[i].element; - int special = element_to_special_graphic[i].special; - int graphic = element_to_special_graphic[i].graphic; - boolean base_redefined = getImageListEntry(el2img(element))->redefined; - boolean special_redefined = getImageListEntry(graphic)->redefined; + InitElementSmallImages(); /* create editor and preview images */ + InitFontGraphicInfo(); /* initialize text drawing functions */ - if (base_redefined && !special_redefined) - continue; + SetMainBackgroundImage(IMG_BACKGROUND); + SetDoorBackgroundImage(IMG_BACKGROUND_DOOR); - element_info[element].special_graphic[special] = graphic; - } + InitGadgets(); + InitToons(); +} - /* initialize special element/graphic mapping from dynamic configuration */ - for (i=0; i < num_property_mappings; i++) - { - int element = property_mapping[i].base_index; - int special = property_mapping[i].ext3_index; - int graphic = property_mapping[i].artwork_index; +static void ReinitializeSounds() +{ + InitSoundInfo(); /* sound properties mapping */ + InitElementSoundInfo(); /* element game sound mapping */ - if (element >= MAX_NUM_ELEMENTS) - continue; +#if 1 + InitElementSoundInfo(); /* element game sound mapping */ +#endif - if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS) - element_info[element].special_graphic[special] = graphic; - } + InitPlaySoundLevel(); /* internal game sound settings */ } -static void set_graphic_parameters(int graphic, char **parameter_raw) +static void ReinitializeMusic() { - Bitmap *src_bitmap = getBitmapFromImageID(graphic); - int num_xtiles = (src_bitmap ? src_bitmap->width : TILEX) / TILEX; - int num_ytiles = (src_bitmap ? src_bitmap->height * 2 / 3 : TILEY) / TILEY; - int parameter[NUM_GFX_ARGS]; - int i; - - /* get integer values from string parameters */ - for (i=0; i < NUM_GFX_ARGS; i++) - parameter[i] = - get_parameter_value(image_config_suffix[i].token, parameter_raw[i], - image_config_suffix[i].type); + /* currently nothing to do */ +} - graphic_info[graphic].bitmap = src_bitmap; +void InitElementProperties() +{ + int i, j; - /* start with reliable default values */ - graphic_info[graphic].src_x = 0; - graphic_info[graphic].src_y = 0; - graphic_info[graphic].width = TILEX; - graphic_info[graphic].height = TILEY; - graphic_info[graphic].offset_x = 0; /* one or both of these values ... */ - graphic_info[graphic].offset_y = 0; /* ... will be corrected later */ - - /* optional x and y tile position of animation frame sequence */ - if (parameter[GFX_ARG_XPOS] != ARG_UNDEFINED_VALUE) - graphic_info[graphic].src_x = parameter[GFX_ARG_XPOS] * TILEX; - if (parameter[GFX_ARG_YPOS] != ARG_UNDEFINED_VALUE) - graphic_info[graphic].src_y = parameter[GFX_ARG_YPOS] * TILEY; - - /* optional x and y pixel position of animation frame sequence */ - if (parameter[GFX_ARG_X] != ARG_UNDEFINED_VALUE) - graphic_info[graphic].src_x = parameter[GFX_ARG_X]; - if (parameter[GFX_ARG_Y] != ARG_UNDEFINED_VALUE) - graphic_info[graphic].src_y = parameter[GFX_ARG_Y]; - - /* optional width and height of each animation frame */ - if (parameter[GFX_ARG_WIDTH] != ARG_UNDEFINED_VALUE) - graphic_info[graphic].width = parameter[GFX_ARG_WIDTH]; - if (parameter[GFX_ARG_HEIGHT] != ARG_UNDEFINED_VALUE) - graphic_info[graphic].height = parameter[GFX_ARG_HEIGHT]; - - /* correct x or y offset dependant of vertical or horizontal frame order */ - if (parameter[GFX_ARG_VERTICAL]) /* frames are ordered vertically */ - { - if (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE) - graphic_info[graphic].offset_y = parameter[GFX_ARG_OFFSET]; - else - graphic_info[graphic].offset_y = graphic_info[graphic].height; - } - else /* frames are ordered horizontally */ + static int ep_amoebalive[] = { - if (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE) - graphic_info[graphic].offset_x = parameter[GFX_ARG_OFFSET]; - else - graphic_info[graphic].offset_x = graphic_info[graphic].width; - } - - /* optionally, the x and y offset of frames can be specified directly */ - if (parameter[GFX_ARG_XOFFSET] != ARG_UNDEFINED_VALUE) - graphic_info[graphic].offset_x = parameter[GFX_ARG_XOFFSET]; - if (parameter[GFX_ARG_YOFFSET] != ARG_UNDEFINED_VALUE) - graphic_info[graphic].offset_y = parameter[GFX_ARG_YOFFSET]; - - /* automatically determine correct number of frames, if not defined */ - if (parameter[GFX_ARG_FRAMES] != ARG_UNDEFINED_VALUE) - graphic_info[graphic].anim_frames = parameter[GFX_ARG_FRAMES]; - else if (parameter[GFX_ARG_XPOS] == 0 && !parameter[GFX_ARG_VERTICAL]) - graphic_info[graphic].anim_frames = num_xtiles; - else if (parameter[GFX_ARG_YPOS] == 0 && parameter[GFX_ARG_VERTICAL]) - graphic_info[graphic].anim_frames = num_ytiles; - else - graphic_info[graphic].anim_frames = 1; - - graphic_info[graphic].anim_delay = parameter[GFX_ARG_DELAY]; - if (graphic_info[graphic].anim_delay == 0) /* delay must be at least 1 */ - graphic_info[graphic].anim_delay = 1; - - if (parameter[GFX_ARG_ANIM_MODE] != ANIM_NONE) - graphic_info[graphic].anim_mode = parameter[GFX_ARG_ANIM_MODE]; - else if (graphic_info[graphic].anim_frames > 1) - graphic_info[graphic].anim_mode = ANIM_LOOP; - - /* automatically determine correct start frame, if not defined */ - if (parameter[GFX_ARG_START_FRAME] == ARG_UNDEFINED_VALUE) - graphic_info[graphic].anim_start_frame = 0; - else if (graphic_info[graphic].anim_mode & ANIM_REVERSE) - graphic_info[graphic].anim_start_frame = - graphic_info[graphic].anim_frames - parameter[GFX_ARG_START_FRAME] - 1; - else - graphic_info[graphic].anim_start_frame = parameter[GFX_ARG_START_FRAME]; - - /* animation synchronized with global frame counter, not move position */ - graphic_info[graphic].anim_global_sync = parameter[GFX_ARG_GLOBAL_SYNC]; - - /* this is only used for toon animations */ - graphic_info[graphic].step_offset = parameter[GFX_ARG_STEP_OFFSET]; - graphic_info[graphic].step_delay = parameter[GFX_ARG_STEP_DELAY]; - - /* this is only used for drawing font characters */ - graphic_info[graphic].draw_x = parameter[GFX_ARG_DRAW_XOFFSET]; - graphic_info[graphic].draw_y = parameter[GFX_ARG_DRAW_YOFFSET]; -} - -static void InitGraphicInfo() -{ - int fallback_graphic = IMG_CHAR_EXCLAM; - struct FileInfo *fallback_image = getImageListEntry(fallback_graphic); - Bitmap *fallback_bitmap = getBitmapFromImageID(fallback_graphic); - int num_images = getImageListSize(); - int i; - -#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) - static boolean clipmasks_initialized = FALSE; - Pixmap src_pixmap; - XGCValues clip_gc_values; - unsigned long clip_gc_valuemask; - GC copy_clipmask_gc = None; -#endif - - if (graphic_info != NULL) - free(graphic_info); - - graphic_info = checked_calloc(num_images * sizeof(struct GraphicInfo)); + EL_AMOEBA_WET, + EL_AMOEBA_DRY, + EL_AMOEBA_FULL, + EL_BD_AMOEBA, + -1 + }; -#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) - if (clipmasks_initialized) + static int ep_amoeboid[] = { - for (i=0; iparameter); - - /* now check if no animation frames are outside of the loaded image */ - - if (graphic_info[i].bitmap == NULL) - continue; /* skip check for optional images that are undefined */ - - first_frame = 0; - getGraphicSource(i, first_frame, &src_bitmap, &src_x, &src_y); - if (src_x < 0 || src_y < 0 || - src_x + TILEX > src_bitmap->width || - src_y + TILEY > src_bitmap->height) - { - Error(ERR_RETURN_LINE, "-"); - Error(ERR_RETURN, "warning: error found in config file:"); - Error(ERR_RETURN, "- config file: '%s'", - getImageConfigFilename()); - Error(ERR_RETURN, "- config token: '%s'", - getTokenFromImageID(i)); - Error(ERR_RETURN, "- image file: '%s'", - src_bitmap->source_filename); - Error(ERR_RETURN, - "error: first animation frame out of bounds (%d, %d)", - src_x, src_y); - Error(ERR_RETURN, "custom graphic rejected for this element/action"); + EL_SAND, + EL_LANDMINE, + EL_TRAP, + EL_TRAP_ACTIVE, + -1 + }; - if (i == fallback_graphic) - Error(ERR_EXIT, "fatal error: no fallback graphic available"); + static int ep_pforte[] = + { + EL_GATE_1, + EL_GATE_2, + EL_GATE_3, + EL_GATE_4, + EL_GATE_1_GRAY, + EL_GATE_2_GRAY, + EL_GATE_3_GRAY, + EL_GATE_4_GRAY, + EL_EM_GATE_1, + EL_EM_GATE_2, + EL_EM_GATE_3, + EL_EM_GATE_4, + EL_EM_GATE_1_GRAY, + EL_EM_GATE_2_GRAY, + EL_EM_GATE_3_GRAY, + EL_EM_GATE_4_GRAY, + EL_SWITCHGATE_OPEN, + EL_SWITCHGATE_OPENING, + EL_SWITCHGATE_CLOSED, + EL_SWITCHGATE_CLOSING, + EL_TIMEGATE_OPEN, + EL_TIMEGATE_OPENING, + EL_TIMEGATE_CLOSED, + EL_TIMEGATE_CLOSING, + EL_TUBE_ANY, + EL_TUBE_VERTICAL, + EL_TUBE_HORIZONTAL, + EL_TUBE_VERTICAL_LEFT, + EL_TUBE_VERTICAL_RIGHT, + EL_TUBE_HORIZONTAL_UP, + EL_TUBE_HORIZONTAL_DOWN, + EL_TUBE_LEFT_UP, + EL_TUBE_LEFT_DOWN, + EL_TUBE_RIGHT_UP, + EL_TUBE_RIGHT_DOWN, + -1 + }; - Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic"); - Error(ERR_RETURN_LINE, "-"); + static int ep_solid[] = + { + EL_WALL, + EL_EXPANDABLE_WALL, + EL_EXPANDABLE_WALL_HORIZONTAL, + EL_EXPANDABLE_WALL_VERTICAL, + EL_EXPANDABLE_WALL_ANY, + EL_BD_WALL, + EL_WALL_CRUMBLED, + EL_EXIT_CLOSED, + EL_EXIT_OPENING, + EL_EXIT_OPEN, + EL_AMOEBA_DEAD, + EL_AMOEBA_WET, + EL_AMOEBA_DRY, + EL_AMOEBA_FULL, + EL_BD_AMOEBA, + EL_QUICKSAND_EMPTY, + EL_QUICKSAND_FULL, + EL_QUICKSAND_FILLING, + EL_QUICKSAND_EMPTYING, + EL_MAGIC_WALL, + EL_MAGIC_WALL_ACTIVE, + EL_MAGIC_WALL_EMPTYING, + EL_MAGIC_WALL_FILLING, + EL_MAGIC_WALL_FULL, + EL_MAGIC_WALL_DEAD, + EL_BD_MAGIC_WALL, + EL_BD_MAGIC_WALL_ACTIVE, + EL_BD_MAGIC_WALL_EMPTYING, + EL_BD_MAGIC_WALL_FULL, + EL_BD_MAGIC_WALL_FILLING, + EL_BD_MAGIC_WALL_DEAD, + EL_GAME_OF_LIFE, + EL_BIOMAZE, + EL_SP_CHIP_SINGLE, + EL_SP_CHIP_LEFT, + EL_SP_CHIP_RIGHT, + EL_SP_CHIP_TOP, + EL_SP_CHIP_BOTTOM, + EL_SP_TERMINAL, + EL_SP_TERMINAL_ACTIVE, + EL_SP_EXIT_CLOSED, + EL_SP_EXIT_OPEN, + EL_INVISIBLE_WALL, + EL_INVISIBLE_WALL_ACTIVE, + EL_SWITCHGATE_SWITCH_UP, + EL_SWITCHGATE_SWITCH_DOWN, + EL_TIMEGATE_SWITCH, + EL_TIMEGATE_SWITCH_ACTIVE, + EL_EMC_WALL_1, + EL_EMC_WALL_2, + EL_EMC_WALL_3, + EL_EMC_WALL_4, + EL_EMC_WALL_5, + EL_EMC_WALL_6, + EL_EMC_WALL_7, + EL_EMC_WALL_8, + EL_WALL_PEARL, + EL_WALL_CRYSTAL, - set_graphic_parameters(i, fallback_image->default_parameter); - graphic_info[i].bitmap = fallback_bitmap; - } - - last_frame = graphic_info[i].anim_frames - 1; - getGraphicSource(i, last_frame, &src_bitmap, &src_x, &src_y); - if (src_x < 0 || src_y < 0 || - src_x + TILEX > src_bitmap->width || - src_y + TILEY > src_bitmap->height) - { - Error(ERR_RETURN_LINE, "-"); - Error(ERR_RETURN, "warning: error found in config file:"); - Error(ERR_RETURN, "- config file: '%s'", - getImageConfigFilename()); - Error(ERR_RETURN, "- config token: '%s'", - getTokenFromImageID(i)); - Error(ERR_RETURN, "- image file: '%s'", - src_bitmap->source_filename); - Error(ERR_RETURN, - "error: last animation frame (%d) out of bounds (%d, %d)", - last_frame, src_x, src_y); - Error(ERR_RETURN, "custom graphic rejected for this element/action"); - - if (i == fallback_graphic) - Error(ERR_EXIT, "fatal error: no fallback graphic available"); - - Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic"); - Error(ERR_RETURN_LINE, "-"); - - set_graphic_parameters(i, fallback_image->default_parameter); - graphic_info[i].bitmap = fallback_bitmap; - } - -#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) - /* currently we need only a tile clip mask from the first frame */ - getGraphicSource(i, first_frame, &src_bitmap, &src_x, &src_y); - - if (copy_clipmask_gc == None) - { - clip_gc_values.graphics_exposures = False; - clip_gc_valuemask = GCGraphicsExposures; - copy_clipmask_gc = XCreateGC(display, src_bitmap->clip_mask, - clip_gc_valuemask, &clip_gc_values); - } - - graphic_info[i].clip_mask = - XCreatePixmap(display, window->drawable, TILEX, TILEY, 1); - - src_pixmap = src_bitmap->clip_mask; - XCopyArea(display, src_pixmap, graphic_info[i].clip_mask, - copy_clipmask_gc, src_x, src_y, TILEX, TILEY, 0, 0); - - clip_gc_values.graphics_exposures = False; - clip_gc_values.clip_mask = graphic_info[i].clip_mask; - clip_gc_valuemask = GCGraphicsExposures | GCClipMask; - - graphic_info[i].clip_gc = - XCreateGC(display, window->drawable, clip_gc_valuemask, &clip_gc_values); -#endif - } - -#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) - if (copy_clipmask_gc) - XFreeGC(display, copy_clipmask_gc); - - clipmasks_initialized = TRUE; + /* the following elements are a direct copy of "indestructible" elements, + except "EL_ACID", which is "indestructible", but not "solid"! */ +#if 0 + EL_ACID, #endif -} - -static void InitElementSoundInfo() -{ - struct PropertyMapping *property_mapping = getSoundListPropertyMapping(); - int num_property_mappings = getSoundListPropertyMappingSize(); - int i, j, act; - - /* set values to -1 to identify later as "uninitialized" values */ - for (i=0; i < MAX_NUM_ELEMENTS; i++) - for (act=0; act < NUM_ACTIONS; act++) - element_info[i].sound[act] = -1; - - /* initialize element/sound mapping from static configuration */ - for (i=0; element_to_sound[i].element > -1; i++) - { - int element = element_to_sound[i].element; - int action = element_to_sound[i].action; - int sound = element_to_sound[i].sound; - boolean is_class = element_to_sound[i].is_class; - - if (action < 0) - action = ACTION_DEFAULT; - - if (!is_class) - element_info[element].sound[action] = sound; - else - for (j=0; j < MAX_NUM_ELEMENTS; j++) - if (strcmp(element_info[j].class_name, - element_info[element].class_name) == 0) - element_info[j].sound[action] = sound; - } - - /* initialize element/sound mapping from dynamic configuration */ - for (i=0; i < num_property_mappings; i++) - { - int element = property_mapping[i].base_index; - int action = property_mapping[i].ext1_index; - int sound = property_mapping[i].artwork_index; - - if (element >= MAX_NUM_ELEMENTS) - continue; - - if (action < 0) - action = ACTION_DEFAULT; - - element_info[element].sound[action] = sound; - } + EL_STEELWALL, + EL_ACID_POOL_TOPLEFT, + EL_ACID_POOL_TOPRIGHT, + EL_ACID_POOL_BOTTOMLEFT, + EL_ACID_POOL_BOTTOM, + EL_ACID_POOL_BOTTOMRIGHT, + EL_SP_HARDWARE_GRAY, + EL_SP_HARDWARE_GREEN, + EL_SP_HARDWARE_BLUE, + EL_SP_HARDWARE_RED, + EL_SP_HARDWARE_YELLOW, + EL_SP_HARDWARE_BASE_1, + EL_SP_HARDWARE_BASE_2, + EL_SP_HARDWARE_BASE_3, + EL_SP_HARDWARE_BASE_4, + EL_SP_HARDWARE_BASE_5, + EL_SP_HARDWARE_BASE_6, + EL_INVISIBLE_STEELWALL, + EL_INVISIBLE_STEELWALL_ACTIVE, + EL_CONVEYOR_BELT_1_SWITCH_LEFT, + EL_CONVEYOR_BELT_1_SWITCH_MIDDLE, + EL_CONVEYOR_BELT_1_SWITCH_RIGHT, + EL_CONVEYOR_BELT_2_SWITCH_LEFT, + EL_CONVEYOR_BELT_2_SWITCH_MIDDLE, + EL_CONVEYOR_BELT_2_SWITCH_RIGHT, + EL_CONVEYOR_BELT_3_SWITCH_LEFT, + EL_CONVEYOR_BELT_3_SWITCH_MIDDLE, + EL_CONVEYOR_BELT_3_SWITCH_RIGHT, + EL_CONVEYOR_BELT_4_SWITCH_LEFT, + EL_CONVEYOR_BELT_4_SWITCH_MIDDLE, + EL_CONVEYOR_BELT_4_SWITCH_RIGHT, + EL_LIGHT_SWITCH, + EL_LIGHT_SWITCH_ACTIVE, + EL_SIGN_EXCLAMATION, + EL_SIGN_RADIOACTIVITY, + EL_SIGN_STOP, + EL_SIGN_WHEELCHAIR, + EL_SIGN_PARKING, + EL_SIGN_ONEWAY, + EL_SIGN_HEART, + EL_SIGN_TRIANGLE, + EL_SIGN_ROUND, + EL_SIGN_EXIT, + EL_SIGN_YINYANG, + EL_SIGN_OTHER, + EL_STEELWALL_SLANTED, + EL_EMC_STEELWALL_1, + EL_EMC_STEELWALL_2, + EL_EMC_STEELWALL_3, + EL_EMC_STEELWALL_4, + EL_CRYSTAL, + EL_GATE_1, + EL_GATE_2, + EL_GATE_3, + EL_GATE_4, + EL_GATE_1_GRAY, + EL_GATE_2_GRAY, + EL_GATE_3_GRAY, + EL_GATE_4_GRAY, + EL_EM_GATE_1, + EL_EM_GATE_2, + EL_EM_GATE_3, + EL_EM_GATE_4, + EL_EM_GATE_1_GRAY, + EL_EM_GATE_2_GRAY, + EL_EM_GATE_3_GRAY, + EL_EM_GATE_4_GRAY, + EL_SWITCHGATE_OPEN, + EL_SWITCHGATE_OPENING, + EL_SWITCHGATE_CLOSED, + EL_SWITCHGATE_CLOSING, + EL_TIMEGATE_OPEN, + EL_TIMEGATE_OPENING, + EL_TIMEGATE_CLOSED, + EL_TIMEGATE_CLOSING, + EL_TUBE_ANY, + EL_TUBE_VERTICAL, + EL_TUBE_HORIZONTAL, + EL_TUBE_VERTICAL_LEFT, + EL_TUBE_VERTICAL_RIGHT, + EL_TUBE_HORIZONTAL_UP, + EL_TUBE_HORIZONTAL_DOWN, + EL_TUBE_LEFT_UP, + EL_TUBE_LEFT_DOWN, + EL_TUBE_RIGHT_UP, + EL_TUBE_RIGHT_DOWN, + -1 + }; - /* initialize element class/sound mapping from dynamic configuration */ - for (i=0; i < num_property_mappings; i++) + static int ep_indestructible[] = { - int element_class = property_mapping[i].base_index - MAX_NUM_ELEMENTS; - int action = property_mapping[i].ext1_index; - int sound = property_mapping[i].artwork_index; - - if (element_class < 0 || element_class >= MAX_NUM_ELEMENTS) - continue; - - if (action < 0) - action = ACTION_DEFAULT; - - for (j=0; j < MAX_NUM_ELEMENTS; j++) - if (strcmp(element_info[j].class_name, - element_info[element_class].class_name) == 0) - element_info[j].sound[action] = sound; - } + EL_STEELWALL, + EL_ACID, + EL_ACID_POOL_TOPLEFT, + EL_ACID_POOL_TOPRIGHT, + EL_ACID_POOL_BOTTOMLEFT, + EL_ACID_POOL_BOTTOM, + EL_ACID_POOL_BOTTOMRIGHT, + EL_SP_HARDWARE_GRAY, + EL_SP_HARDWARE_GREEN, + EL_SP_HARDWARE_BLUE, + EL_SP_HARDWARE_RED, + EL_SP_HARDWARE_YELLOW, + EL_SP_HARDWARE_BASE_1, + EL_SP_HARDWARE_BASE_2, + EL_SP_HARDWARE_BASE_3, + EL_SP_HARDWARE_BASE_4, + EL_SP_HARDWARE_BASE_5, + EL_SP_HARDWARE_BASE_6, + EL_INVISIBLE_STEELWALL, + EL_INVISIBLE_STEELWALL_ACTIVE, + EL_CONVEYOR_BELT_1_SWITCH_LEFT, + EL_CONVEYOR_BELT_1_SWITCH_MIDDLE, + EL_CONVEYOR_BELT_1_SWITCH_RIGHT, + EL_CONVEYOR_BELT_2_SWITCH_LEFT, + EL_CONVEYOR_BELT_2_SWITCH_MIDDLE, + EL_CONVEYOR_BELT_2_SWITCH_RIGHT, + EL_CONVEYOR_BELT_3_SWITCH_LEFT, + EL_CONVEYOR_BELT_3_SWITCH_MIDDLE, + EL_CONVEYOR_BELT_3_SWITCH_RIGHT, + EL_CONVEYOR_BELT_4_SWITCH_LEFT, + EL_CONVEYOR_BELT_4_SWITCH_MIDDLE, + EL_CONVEYOR_BELT_4_SWITCH_RIGHT, + EL_LIGHT_SWITCH, + EL_LIGHT_SWITCH_ACTIVE, + EL_SIGN_EXCLAMATION, + EL_SIGN_RADIOACTIVITY, + EL_SIGN_STOP, + EL_SIGN_WHEELCHAIR, + EL_SIGN_PARKING, + EL_SIGN_ONEWAY, + EL_SIGN_HEART, + EL_SIGN_TRIANGLE, + EL_SIGN_ROUND, + EL_SIGN_EXIT, + EL_SIGN_YINYANG, + EL_SIGN_OTHER, + EL_STEELWALL_SLANTED, + EL_EMC_STEELWALL_1, + EL_EMC_STEELWALL_2, + EL_EMC_STEELWALL_3, + EL_EMC_STEELWALL_4, + EL_CRYSTAL, + EL_GATE_1, + EL_GATE_2, + EL_GATE_3, + EL_GATE_4, + EL_GATE_1_GRAY, + EL_GATE_2_GRAY, + EL_GATE_3_GRAY, + EL_GATE_4_GRAY, + EL_EM_GATE_1, + EL_EM_GATE_2, + EL_EM_GATE_3, + EL_EM_GATE_4, + EL_EM_GATE_1_GRAY, + EL_EM_GATE_2_GRAY, + EL_EM_GATE_3_GRAY, + EL_EM_GATE_4_GRAY, + EL_SWITCHGATE_OPEN, + EL_SWITCHGATE_OPENING, + EL_SWITCHGATE_CLOSED, + EL_SWITCHGATE_CLOSING, + EL_TIMEGATE_OPEN, + EL_TIMEGATE_OPENING, + EL_TIMEGATE_CLOSED, + EL_TIMEGATE_CLOSING, + EL_TUBE_ANY, + EL_TUBE_VERTICAL, + EL_TUBE_HORIZONTAL, + EL_TUBE_VERTICAL_LEFT, + EL_TUBE_VERTICAL_RIGHT, + EL_TUBE_HORIZONTAL_UP, + EL_TUBE_HORIZONTAL_DOWN, + EL_TUBE_LEFT_UP, + EL_TUBE_LEFT_DOWN, + EL_TUBE_RIGHT_UP, + EL_TUBE_RIGHT_DOWN, + -1 + }; - /* now set all '-1' values to element specific default values */ - for (i=0; itoken); - - sound_effect_properties[i] = ACTION_OTHER; - sound_info[i].loop = FALSE; - - /* determine all loop sounds and identify certain sound classes */ - - for (j=0; element_action_info[j].suffix; j++) - { - int len_action_text = strlen(element_action_info[j].suffix); - - if (len_action_text < len_effect_text && - strcmp(&sound->token[len_effect_text - len_action_text], - element_action_info[j].suffix) == 0) - { - sound_effect_properties[i] = element_action_info[j].value; - - if (element_action_info[j].is_loop_sound) - sound_info[i].loop = TRUE; - } - } - - /* associate elements and some selected sound actions */ - - for (j=0; jtoken, - element_info[j].class_name, len_class_text) == 0 && - sound->token[len_class_text] == '.') - { - int sound_action_value = sound_effect_properties[i]; - - element_info[j].sound[sound_action_value] = i; - } - } - } - - set_sound_parameters(i, sound->parameter); - } - - free(sound_effect_properties); + EL_BUG, + EL_SPACESHIP, + EL_BD_BUTTERFLY, + EL_BD_FIREFLY, + EL_YAMYAM, + EL_DARK_YAMYAM, + EL_ROBOT, + EL_PACMAN, + EL_SP_SNIKSNAK, + EL_SP_ELECTRON, + -1 + }; - /* initialize element/sound mapping from dynamic configuration */ - for (i=0; i < num_property_mappings; i++) + static int ep_mauer[] = { - int element = property_mapping[i].base_index; - int action = property_mapping[i].ext1_index; - int sound = property_mapping[i].artwork_index; - - if (action < 0) - action = ACTION_DEFAULT; + EL_STEELWALL, + EL_GATE_1, + EL_GATE_2, + EL_GATE_3, + EL_GATE_4, + EL_GATE_1_GRAY, + EL_GATE_2_GRAY, + EL_GATE_3_GRAY, + EL_GATE_4_GRAY, + EL_EM_GATE_1, + EL_EM_GATE_2, + EL_EM_GATE_3, + EL_EM_GATE_4, + EL_EM_GATE_1_GRAY, + EL_EM_GATE_2_GRAY, + EL_EM_GATE_3_GRAY, + EL_EM_GATE_4_GRAY, + EL_EXIT_CLOSED, + EL_EXIT_OPENING, + EL_EXIT_OPEN, + EL_WALL, + EL_WALL_CRUMBLED, + EL_EXPANDABLE_WALL, + EL_EXPANDABLE_WALL_HORIZONTAL, + EL_EXPANDABLE_WALL_VERTICAL, + EL_EXPANDABLE_WALL_ANY, + EL_EXPANDABLE_WALL_GROWING, + EL_BD_WALL, + EL_SP_CHIP_SINGLE, + EL_SP_CHIP_LEFT, + EL_SP_CHIP_RIGHT, + EL_SP_CHIP_TOP, + EL_SP_CHIP_BOTTOM, + EL_SP_HARDWARE_GRAY, + EL_SP_HARDWARE_GREEN, + EL_SP_HARDWARE_BLUE, + EL_SP_HARDWARE_RED, + EL_SP_HARDWARE_YELLOW, + EL_SP_HARDWARE_BASE_1, + EL_SP_HARDWARE_BASE_2, + EL_SP_HARDWARE_BASE_3, + EL_SP_HARDWARE_BASE_4, + EL_SP_HARDWARE_BASE_5, + EL_SP_HARDWARE_BASE_6, + EL_SP_TERMINAL, + EL_SP_TERMINAL_ACTIVE, + EL_SP_EXIT_CLOSED, + EL_SP_EXIT_OPEN, + EL_INVISIBLE_STEELWALL, + EL_INVISIBLE_STEELWALL_ACTIVE, + EL_INVISIBLE_WALL, + EL_INVISIBLE_WALL_ACTIVE, + EL_STEELWALL_SLANTED, + EL_EMC_STEELWALL_1, + EL_EMC_STEELWALL_2, + EL_EMC_STEELWALL_3, + EL_EMC_STEELWALL_4, + EL_EMC_WALL_1, + EL_EMC_WALL_2, + EL_EMC_WALL_3, + EL_EMC_WALL_4, + EL_EMC_WALL_5, + EL_EMC_WALL_6, + EL_EMC_WALL_7, + EL_EMC_WALL_8, + -1 + }; - element_info[element].sound[action] = sound; - } + static int ep_can_fall[] = + { + EL_ROCK, + EL_BD_ROCK, + EL_EMERALD, + EL_BD_DIAMOND, + EL_EMERALD_YELLOW, + EL_EMERALD_RED, + EL_EMERALD_PURPLE, + EL_DIAMOND, + EL_BOMB, + EL_NUT, + EL_AMOEBA_DROP, + EL_QUICKSAND_FULL, + EL_MAGIC_WALL_FULL, + EL_BD_MAGIC_WALL_FULL, + EL_TIME_ORB_FULL, + EL_TIME_ORB_EMPTY, + EL_SP_ZONK, + EL_SP_INFOTRON, + EL_SP_DISK_ORANGE, + EL_PEARL, + EL_CRYSTAL, + EL_SPRING, + EL_DX_SUPABOMB, + -1 + }; -#if 0 - /* TEST ONLY */ + static int ep_can_smash[] = { - int element = EL_CUSTOM_11; - int j = 0; + EL_ROCK, + EL_BD_ROCK, + EL_EMERALD, + EL_BD_DIAMOND, + EL_EMERALD_YELLOW, + EL_EMERALD_RED, + EL_EMERALD_PURPLE, + EL_DIAMOND, + EL_BOMB, + EL_NUT, + EL_AMOEBA_DROP, + EL_TIME_ORB_FULL, + EL_TIME_ORB_EMPTY, + EL_SP_ZONK, + EL_SP_INFOTRON, + EL_SP_DISK_ORANGE, + EL_PEARL, + EL_CRYSTAL, + EL_SPRING, + EL_DX_SUPABOMB, + -1 + }; - while (element_action_info[j].suffix) - { - printf("element %d, sound action '%s' == %d\n", - element, element_action_info[j].suffix, - element_info[element].sound[j]); - j++; - } - } + static int ep_can_change[] = + { + EL_ROCK, + EL_BD_ROCK, + EL_EMERALD, + EL_BD_DIAMOND, + EL_EMERALD_YELLOW, + EL_EMERALD_RED, + EL_EMERALD_PURPLE, + EL_DIAMOND, + -1 + }; - PlaySoundLevelElementAction(0,0, EL_CUSTOM_11, ACTION_PUSHING); -#endif + static int ep_can_move[] = + { + EL_BUG, + EL_SPACESHIP, + EL_BD_BUTTERFLY, + EL_BD_FIREFLY, + EL_YAMYAM, + EL_DARK_YAMYAM, + EL_ROBOT, + EL_PACMAN, + EL_MOLE, + EL_PENGUIN, + EL_PIG, + EL_DRAGON, + EL_SATELLITE, + EL_SP_SNIKSNAK, + EL_SP_ELECTRON, + EL_BALLOON, + EL_SPRING, + -1 + }; -#if 0 - /* TEST ONLY */ + static int ep_could_move[] = { - int element = EL_SAND; - int sound_action = ACTION_DIGGING; - int j = 0; + EL_BUG_RIGHT, + EL_BUG_UP, + EL_BUG_LEFT, + EL_BUG_DOWN, + EL_SPACESHIP_RIGHT, + EL_SPACESHIP_UP, + EL_SPACESHIP_LEFT, + EL_SPACESHIP_DOWN, + EL_BD_BUTTERFLY_RIGHT, + EL_BD_BUTTERFLY_UP, + EL_BD_BUTTERFLY_LEFT, + EL_BD_BUTTERFLY_DOWN, + EL_BD_FIREFLY_RIGHT, + EL_BD_FIREFLY_UP, + EL_BD_FIREFLY_LEFT, + EL_BD_FIREFLY_DOWN, + EL_PACMAN_RIGHT, + EL_PACMAN_UP, + EL_PACMAN_LEFT, + EL_PACMAN_DOWN, + -1 + }; - while (element_action_info[j].suffix) - { - if (element_action_info[j].value == sound_action) - printf("element %d, sound action '%s' == %d\n", - element, element_action_info[j].suffix, - element_info[element].sound[sound_action]); - j++; - } - } -#endif -} + static int ep_dont_touch[] = + { + EL_BUG, + EL_SPACESHIP, + EL_BD_BUTTERFLY, + EL_BD_FIREFLY, + -1 + }; -void InitElementProperties() -{ - int i, j; + static int ep_dont_go_to[] = + { + EL_BUG, + EL_SPACESHIP, + EL_BD_BUTTERFLY, + EL_BD_FIREFLY, + EL_YAMYAM, + EL_DARK_YAMYAM, + EL_ROBOT, + EL_PACMAN, + EL_AMOEBA_DROP, + EL_ACID, + EL_SP_SNIKSNAK, + EL_SP_ELECTRON, + EL_SP_BUGGY_BASE_ACTIVE, + EL_TRAP_ACTIVE, + EL_LANDMINE, + -1 + }; - static int ep_amoebalive[] = + static int ep_food_dark_yamyam[] = { + EL_SAND, + EL_BUG, + EL_SPACESHIP, + EL_BD_BUTTERFLY, + EL_BD_FIREFLY, + EL_YAMYAM, + EL_ROBOT, + EL_PACMAN, + EL_AMOEBA_DROP, + EL_AMOEBA_DEAD, EL_AMOEBA_WET, EL_AMOEBA_DRY, EL_AMOEBA_FULL, - EL_BD_AMOEBA + EL_BD_AMOEBA, + EL_EMERALD, + EL_BD_DIAMOND, + EL_EMERALD_YELLOW, + EL_EMERALD_RED, + EL_EMERALD_PURPLE, + EL_DIAMOND, + EL_PEARL, + EL_CRYSTAL, + -1 }; - static int ep_amoebalive_num = SIZEOF_ARRAY_INT(ep_amoebalive); - static int ep_amoeboid[] = + static int ep_bd_element[] = { - EL_AMOEBA_DEAD, - EL_AMOEBA_WET, - EL_AMOEBA_DRY, - EL_AMOEBA_FULL, - EL_BD_AMOEBA + EL_EMPTY, + EL_SAND, + EL_WALL_CRUMBLED, + EL_BD_WALL, + EL_ROCK, + EL_BD_ROCK, + EL_BD_DIAMOND, + EL_BD_MAGIC_WALL, + EL_EXIT_CLOSED, + EL_EXIT_OPEN, + EL_STEELWALL, + EL_PLAYER_1, + EL_BD_FIREFLY, + EL_BD_FIREFLY_1, + EL_BD_FIREFLY_2, + EL_BD_FIREFLY_3, + EL_BD_FIREFLY_4, + EL_BD_BUTTERFLY, + EL_BD_BUTTERFLY_1, + EL_BD_BUTTERFLY_2, + EL_BD_BUTTERFLY_3, + EL_BD_BUTTERFLY_4, + EL_BD_AMOEBA, + EL_CHAR_QUESTION, + -1 }; - static int ep_amoeboid_num = SIZEOF_ARRAY_INT(ep_amoeboid); - static int ep_schluessel[] = + static int ep_sb_element[] = { - EL_KEY_1, - EL_KEY_2, - EL_KEY_3, - EL_KEY_4, - EL_EM_KEY_1, - EL_EM_KEY_2, - EL_EM_KEY_3, - EL_EM_KEY_4 + EL_EMPTY, + EL_STEELWALL, + EL_SOKOBAN_OBJECT, + EL_SOKOBAN_FIELD_EMPTY, + EL_SOKOBAN_FIELD_FULL, + EL_PLAYER_1, + EL_INVISIBLE_STEELWALL, + -1 }; - static int ep_schluessel_num = SIZEOF_ARRAY_INT(ep_schluessel); - static int ep_pforte[] = + static int ep_gem[] = { - EL_GATE_1, - EL_GATE_2, - EL_GATE_3, - EL_GATE_4, - EL_GATE_1_GRAY, - EL_GATE_2_GRAY, - EL_GATE_3_GRAY, - EL_GATE_4_GRAY, - EL_EM_GATE_1, - EL_EM_GATE_2, - EL_EM_GATE_3, - EL_EM_GATE_4, - EL_EM_GATE_1_GRAY, - EL_EM_GATE_2_GRAY, - EL_EM_GATE_3_GRAY, - EL_EM_GATE_4_GRAY, - EL_SWITCHGATE_OPEN, - EL_SWITCHGATE_OPENING, - EL_SWITCHGATE_CLOSED, - EL_SWITCHGATE_CLOSING, - EL_TIMEGATE_OPEN, - EL_TIMEGATE_OPENING, - EL_TIMEGATE_CLOSED, - EL_TIMEGATE_CLOSING, - EL_TUBE_ANY, - EL_TUBE_VERTICAL, - EL_TUBE_HORIZONTAL, - EL_TUBE_VERTICAL_LEFT, - EL_TUBE_VERTICAL_RIGHT, - EL_TUBE_HORIZONTAL_UP, - EL_TUBE_HORIZONTAL_DOWN, - EL_TUBE_LEFT_UP, - EL_TUBE_LEFT_DOWN, - EL_TUBE_RIGHT_UP, - EL_TUBE_RIGHT_DOWN + EL_EMERALD, + EL_BD_DIAMOND, + EL_EMERALD_YELLOW, + EL_EMERALD_RED, + EL_EMERALD_PURPLE, + EL_DIAMOND, + -1 }; - static int ep_pforte_num = SIZEOF_ARRAY_INT(ep_pforte); - static int ep_solid[] = + static int ep_inactive[] = { + EL_EMPTY, + EL_SAND, EL_WALL, - EL_EXPANDABLE_WALL, - EL_EXPANDABLE_WALL_HORIZONTAL, - EL_EXPANDABLE_WALL_VERTICAL, - EL_EXPANDABLE_WALL_ANY, EL_BD_WALL, EL_WALL_CRUMBLED, - EL_EXIT_CLOSED, - EL_EXIT_OPENING, - EL_EXIT_OPEN, + EL_STEELWALL, EL_AMOEBA_DEAD, - EL_AMOEBA_WET, - EL_AMOEBA_DRY, - EL_AMOEBA_FULL, - EL_BD_AMOEBA, EL_QUICKSAND_EMPTY, - EL_QUICKSAND_FULL, - EL_QUICKSAND_FILLING, - EL_QUICKSAND_EMPTYING, - EL_MAGIC_WALL, - EL_MAGIC_WALL_ACTIVE, - EL_MAGIC_WALL_EMPTYING, - EL_MAGIC_WALL_FILLING, - EL_MAGIC_WALL_FULL, - EL_MAGIC_WALL_DEAD, - EL_BD_MAGIC_WALL, - EL_BD_MAGIC_WALL_ACTIVE, - EL_BD_MAGIC_WALL_EMPTYING, - EL_BD_MAGIC_WALL_FULL, - EL_BD_MAGIC_WALL_FILLING, - EL_BD_MAGIC_WALL_DEAD, - EL_GAME_OF_LIFE, - EL_BIOMAZE, - EL_SP_CHIP_SINGLE, - EL_SP_CHIP_LEFT, - EL_SP_CHIP_RIGHT, - EL_SP_CHIP_TOP, - EL_SP_CHIP_BOTTOM, - EL_SP_TERMINAL, - EL_SP_TERMINAL_ACTIVE, - EL_SP_EXIT_CLOSED, - EL_SP_EXIT_OPEN, - EL_INVISIBLE_WALL, - EL_INVISIBLE_WALL_ACTIVE, - EL_SWITCHGATE_SWITCH_UP, - EL_SWITCHGATE_SWITCH_DOWN, - EL_TIMEGATE_SWITCH, - EL_TIMEGATE_SWITCH_ACTIVE, - EL_EMC_WALL_1, - EL_EMC_WALL_2, - EL_EMC_WALL_3, - EL_EMC_WALL_4, - EL_EMC_WALL_5, - EL_EMC_WALL_6, - EL_EMC_WALL_7, - EL_EMC_WALL_8, - EL_WALL_PEARL, - EL_WALL_CRYSTAL, - - /* the following elements are a direct copy of "indestructible" elements, - except "EL_ACID", which is "indestructible", but not "solid"! */ -#if 0 - EL_ACID, -#endif - EL_STEELWALL, - EL_ACID_POOL_TOPLEFT, - EL_ACID_POOL_TOPRIGHT, - EL_ACID_POOL_BOTTOMLEFT, - EL_ACID_POOL_BOTTOM, - EL_ACID_POOL_BOTTOMRIGHT, - EL_SP_HARDWARE_GRAY, - EL_SP_HARDWARE_GREEN, - EL_SP_HARDWARE_BLUE, - EL_SP_HARDWARE_RED, - EL_SP_HARDWARE_YELLOW, - EL_SP_HARDWARE_BASE_1, - EL_SP_HARDWARE_BASE_2, - EL_SP_HARDWARE_BASE_3, - EL_SP_HARDWARE_BASE_4, - EL_SP_HARDWARE_BASE_5, - EL_SP_HARDWARE_BASE_6, - EL_INVISIBLE_STEELWALL, - EL_INVISIBLE_STEELWALL_ACTIVE, - EL_CONVEYOR_BELT_1_SWITCH_LEFT, - EL_CONVEYOR_BELT_1_SWITCH_MIDDLE, - EL_CONVEYOR_BELT_1_SWITCH_RIGHT, - EL_CONVEYOR_BELT_2_SWITCH_LEFT, - EL_CONVEYOR_BELT_2_SWITCH_MIDDLE, - EL_CONVEYOR_BELT_2_SWITCH_RIGHT, - EL_CONVEYOR_BELT_3_SWITCH_LEFT, - EL_CONVEYOR_BELT_3_SWITCH_MIDDLE, - EL_CONVEYOR_BELT_3_SWITCH_RIGHT, - EL_CONVEYOR_BELT_4_SWITCH_LEFT, - EL_CONVEYOR_BELT_4_SWITCH_MIDDLE, - EL_CONVEYOR_BELT_4_SWITCH_RIGHT, - EL_LIGHT_SWITCH, - EL_LIGHT_SWITCH_ACTIVE, - EL_SIGN_EXCLAMATION, - EL_SIGN_RADIOACTIVITY, - EL_SIGN_STOP, - EL_SIGN_WHEELCHAIR, - EL_SIGN_PARKING, - EL_SIGN_ONEWAY, - EL_SIGN_HEART, - EL_SIGN_TRIANGLE, - EL_SIGN_ROUND, - EL_SIGN_EXIT, - EL_SIGN_YINYANG, - EL_SIGN_OTHER, - EL_STEELWALL_SLANTED, - EL_EMC_STEELWALL_1, - EL_EMC_STEELWALL_2, - EL_EMC_STEELWALL_3, - EL_EMC_STEELWALL_4, - EL_CRYSTAL, + EL_STONEBLOCK, + EL_ROBOT_WHEEL, + EL_KEY_1, + EL_KEY_2, + EL_KEY_3, + EL_KEY_4, + EL_EM_KEY_1, + EL_EM_KEY_2, + EL_EM_KEY_3, + EL_EM_KEY_4, EL_GATE_1, EL_GATE_2, EL_GATE_3, @@ -1729,37 +1776,55 @@ void InitElementProperties() EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, - EL_SWITCHGATE_OPEN, - EL_SWITCHGATE_OPENING, - EL_SWITCHGATE_CLOSED, - EL_SWITCHGATE_CLOSING, - EL_TIMEGATE_OPEN, - EL_TIMEGATE_OPENING, - EL_TIMEGATE_CLOSED, - EL_TIMEGATE_CLOSING, - EL_TUBE_ANY, - EL_TUBE_VERTICAL, - EL_TUBE_HORIZONTAL, - EL_TUBE_VERTICAL_LEFT, - EL_TUBE_VERTICAL_RIGHT, - EL_TUBE_HORIZONTAL_UP, - EL_TUBE_HORIZONTAL_DOWN, - EL_TUBE_LEFT_UP, - EL_TUBE_LEFT_DOWN, - EL_TUBE_RIGHT_UP, - EL_TUBE_RIGHT_DOWN - }; - static int ep_solid_num = SIZEOF_ARRAY_INT(ep_solid); - - static int ep_indestructible[] = - { - EL_STEELWALL, - EL_ACID, + EL_DYNAMITE, + EL_INVISIBLE_STEELWALL, + EL_INVISIBLE_WALL, + EL_INVISIBLE_SAND, + EL_LAMP, + EL_LAMP_ACTIVE, + EL_WALL_EMERALD, + EL_WALL_DIAMOND, + EL_WALL_BD_DIAMOND, + EL_WALL_EMERALD_YELLOW, + EL_DYNABOMB_INCREASE_NUMBER, + EL_DYNABOMB_INCREASE_SIZE, + EL_DYNABOMB_INCREASE_POWER, + EL_SOKOBAN_OBJECT, + EL_SOKOBAN_FIELD_EMPTY, + EL_SOKOBAN_FIELD_FULL, + EL_WALL_EMERALD_RED, + EL_WALL_EMERALD_PURPLE, EL_ACID_POOL_TOPLEFT, EL_ACID_POOL_TOPRIGHT, EL_ACID_POOL_BOTTOMLEFT, EL_ACID_POOL_BOTTOM, EL_ACID_POOL_BOTTOMRIGHT, + EL_MAGIC_WALL, + EL_MAGIC_WALL_DEAD, + EL_BD_MAGIC_WALL, + EL_BD_MAGIC_WALL_DEAD, + EL_AMOEBA_TO_DIAMOND, + EL_BLOCKED, + EL_SP_EMPTY, + EL_SP_BASE, + EL_SP_PORT_RIGHT, + EL_SP_PORT_DOWN, + EL_SP_PORT_LEFT, + EL_SP_PORT_UP, + EL_SP_GRAVITY_PORT_RIGHT, + EL_SP_GRAVITY_PORT_DOWN, + EL_SP_GRAVITY_PORT_LEFT, + EL_SP_GRAVITY_PORT_UP, + EL_SP_PORT_HORIZONTAL, + EL_SP_PORT_VERTICAL, + EL_SP_PORT_ANY, + EL_SP_DISK_RED, + EL_SP_DISK_YELLOW, + EL_SP_CHIP_SINGLE, + EL_SP_CHIP_LEFT, + EL_SP_CHIP_RIGHT, + EL_SP_CHIP_TOP, + EL_SP_CHIP_BOTTOM, EL_SP_HARDWARE_GRAY, EL_SP_HARDWARE_GREEN, EL_SP_HARDWARE_BLUE, @@ -1771,8 +1836,6 @@ void InitElementProperties() EL_SP_HARDWARE_BASE_4, EL_SP_HARDWARE_BASE_5, EL_SP_HARDWARE_BASE_6, - EL_INVISIBLE_STEELWALL, - EL_INVISIBLE_STEELWALL_ACTIVE, EL_CONVEYOR_BELT_1_SWITCH_LEFT, EL_CONVEYOR_BELT_1_SWITCH_MIDDLE, EL_CONVEYOR_BELT_1_SWITCH_RIGHT, @@ -1785,8 +1848,6 @@ void InitElementProperties() EL_CONVEYOR_BELT_4_SWITCH_LEFT, EL_CONVEYOR_BELT_4_SWITCH_MIDDLE, EL_CONVEYOR_BELT_4_SWITCH_RIGHT, - EL_LIGHT_SWITCH, - EL_LIGHT_SWITCH_ACTIVE, EL_SIGN_EXCLAMATION, EL_SIGN_RADIOACTIVITY, EL_SIGN_STOP, @@ -1804,7 +1865,95 @@ void InitElementProperties() EL_EMC_STEELWALL_2, EL_EMC_STEELWALL_3, EL_EMC_STEELWALL_4, + EL_EMC_WALL_1, + EL_EMC_WALL_2, + EL_EMC_WALL_3, + EL_EMC_WALL_4, + EL_EMC_WALL_5, + EL_EMC_WALL_6, + EL_EMC_WALL_7, + EL_EMC_WALL_8, + -1 + }; + + static int ep_explosive[] = + { + EL_BOMB, + EL_DYNAMITE_ACTIVE, + EL_DYNAMITE, + EL_DYNABOMB_PLAYER_1_ACTIVE, + EL_DYNABOMB_PLAYER_2_ACTIVE, + EL_DYNABOMB_PLAYER_3_ACTIVE, + EL_DYNABOMB_PLAYER_4_ACTIVE, + EL_DYNABOMB_INCREASE_NUMBER, + EL_DYNABOMB_INCREASE_SIZE, + EL_DYNABOMB_INCREASE_POWER, + EL_SP_DISK_RED_ACTIVE, + EL_BUG, + EL_MOLE, + EL_PENGUIN, + EL_PIG, + EL_DRAGON, + EL_SATELLITE, + EL_SP_DISK_RED, + EL_SP_DISK_ORANGE, + EL_SP_DISK_YELLOW, + EL_SP_SNIKSNAK, + EL_SP_ELECTRON, + EL_DX_SUPABOMB, + -1 + }; + + static int ep_food_penguin[] = + { + EL_EMERALD, + EL_BD_DIAMOND, + EL_EMERALD_YELLOW, + EL_EMERALD_RED, + EL_EMERALD_PURPLE, + EL_DIAMOND, + EL_PEARL, EL_CRYSTAL, + -1 + }; + + static int ep_pushable[] = + { + EL_ROCK, + EL_BD_ROCK, + EL_BOMB, + EL_NUT, + EL_TIME_ORB_EMPTY, + EL_SOKOBAN_FIELD_FULL, + EL_SOKOBAN_OBJECT, + EL_SATELLITE, + EL_SP_ZONK, + EL_SP_DISK_ORANGE, + EL_SP_DISK_YELLOW, + EL_BALLOON, + EL_SPRING, + EL_DX_SUPABOMB, + -1 + }; + + static int ep_player[] = + { + EL_PLAYER_1, + EL_PLAYER_2, + EL_PLAYER_3, + EL_PLAYER_4, + -1 + }; + + static int ep_walkable_over[] = + { + EL_EMPTY_SPACE, + EL_SP_EMPTY_SPACE, + EL_SOKOBAN_FIELD_EMPTY, + EL_EXIT_OPEN, + EL_SP_EXIT_OPEN, +#if 1 + /* !!! CHANGE THIS TO "EL_GATE_1_OPEN" etc. !!! */ EL_GATE_1, EL_GATE_2, EL_GATE_3, @@ -1813,22 +1962,12 @@ void InitElementProperties() EL_GATE_2_GRAY, EL_GATE_3_GRAY, EL_GATE_4_GRAY, - EL_EM_GATE_1, - EL_EM_GATE_2, - EL_EM_GATE_3, - EL_EM_GATE_4, - EL_EM_GATE_1_GRAY, - EL_EM_GATE_2_GRAY, - EL_EM_GATE_3_GRAY, - EL_EM_GATE_4_GRAY, - EL_SWITCHGATE_OPEN, - EL_SWITCHGATE_OPENING, - EL_SWITCHGATE_CLOSED, - EL_SWITCHGATE_CLOSING, - EL_TIMEGATE_OPEN, - EL_TIMEGATE_OPENING, - EL_TIMEGATE_CLOSED, - EL_TIMEGATE_CLOSING, +#endif + -1 + }; + + static int ep_walkable_inside[] = + { EL_TUBE_ANY, EL_TUBE_VERTICAL, EL_TUBE_HORIZONTAL, @@ -1839,996 +1978,959 @@ void InitElementProperties() EL_TUBE_LEFT_UP, EL_TUBE_LEFT_DOWN, EL_TUBE_RIGHT_UP, - EL_TUBE_RIGHT_DOWN + EL_TUBE_RIGHT_DOWN, + -1 }; - static int ep_indestructible_num = SIZEOF_ARRAY_INT(ep_indestructible); - static int ep_slippery[] = + static int ep_walkable_under[] = + { + -1 + }; + + static int ep_passable_over[] = + { + EL_EM_GATE_1, + EL_EM_GATE_2, + EL_EM_GATE_3, + EL_EM_GATE_4, + EL_EM_GATE_1_GRAY, + EL_EM_GATE_2_GRAY, + EL_EM_GATE_3_GRAY, + EL_EM_GATE_4_GRAY, + EL_SWITCHGATE_OPEN, + EL_TIMEGATE_OPEN, + -1 + }; + + static int ep_passable_inside[] = + { + EL_SP_PORT_LEFT, + EL_SP_PORT_RIGHT, + EL_SP_PORT_UP, + EL_SP_PORT_DOWN, + EL_SP_PORT_HORIZONTAL, + EL_SP_PORT_VERTICAL, + EL_SP_PORT_ANY, + EL_SP_GRAVITY_PORT_LEFT, + EL_SP_GRAVITY_PORT_RIGHT, + EL_SP_GRAVITY_PORT_UP, + EL_SP_GRAVITY_PORT_DOWN, + -1 + }; + + static int ep_passable_under[] = + { + -1 + }; + + static int ep_diggable[] = + { + EL_SAND, + EL_SP_BASE, + EL_SP_BUGGY_BASE, + EL_SP_BUGGY_BASE_ACTIVATING, + EL_TRAP, + EL_INVISIBLE_SAND, + EL_INVISIBLE_SAND_ACTIVE, +#if 0 + EL_LANDMINE, + EL_SP_BUGGY_BASE_ACTIVE, +#endif + -1 + }; + + static int ep_collectible[] = { - EL_WALL_CRUMBLED, - EL_BD_WALL, - EL_ROCK, - EL_BD_ROCK, - EL_EMERALD, EL_BD_DIAMOND, + EL_EMERALD, + EL_DIAMOND, EL_EMERALD_YELLOW, EL_EMERALD_RED, EL_EMERALD_PURPLE, - EL_DIAMOND, - EL_BOMB, - EL_NUT, - EL_ROBOT_WHEEL_ACTIVE, - EL_ROBOT_WHEEL, - EL_TIME_ORB_FULL, - EL_TIME_ORB_EMPTY, - EL_LAMP_ACTIVE, - EL_LAMP, - EL_ACID_POOL_TOPLEFT, - EL_ACID_POOL_TOPRIGHT, - EL_SATELLITE, - EL_SP_ZONK, + EL_KEY_1, + EL_KEY_2, + EL_KEY_3, + EL_KEY_4, + EL_EM_KEY_1, + EL_EM_KEY_2, + EL_EM_KEY_3, + EL_EM_KEY_4, + EL_DYNAMITE, + EL_DYNABOMB_INCREASE_NUMBER, + EL_DYNABOMB_INCREASE_SIZE, + EL_DYNABOMB_INCREASE_POWER, EL_SP_INFOTRON, - EL_SP_CHIP_SINGLE, - EL_SP_CHIP_LEFT, - EL_SP_CHIP_RIGHT, - EL_SP_CHIP_TOP, - EL_SP_CHIP_BOTTOM, - EL_SPEED_PILL, - EL_STEELWALL_SLANTED, + EL_SP_DISK_RED, EL_PEARL, - EL_CRYSTAL + EL_CRYSTAL, + EL_KEY_WHITE, + EL_SHIELD_NORMAL, + EL_SHIELD_DEADLY, + EL_EXTRA_TIME, + EL_ENVELOPE, + EL_SPEED_PILL, + -1 }; - static int ep_slippery_num = SIZEOF_ARRAY_INT(ep_slippery); - static int ep_enemy[] = + static int ep_active_bomb[] = + { + EL_DYNAMITE_ACTIVE, + EL_DYNABOMB_PLAYER_1_ACTIVE, + EL_DYNABOMB_PLAYER_2_ACTIVE, + EL_DYNABOMB_PLAYER_3_ACTIVE, + EL_DYNABOMB_PLAYER_4_ACTIVE, + EL_SP_DISK_RED_ACTIVE, + -1 + }; + + static int ep_belt[] = + { + EL_CONVEYOR_BELT_1_LEFT, + EL_CONVEYOR_BELT_1_MIDDLE, + EL_CONVEYOR_BELT_1_RIGHT, + EL_CONVEYOR_BELT_2_LEFT, + EL_CONVEYOR_BELT_2_MIDDLE, + EL_CONVEYOR_BELT_2_RIGHT, + EL_CONVEYOR_BELT_3_LEFT, + EL_CONVEYOR_BELT_3_MIDDLE, + EL_CONVEYOR_BELT_3_RIGHT, + EL_CONVEYOR_BELT_4_LEFT, + EL_CONVEYOR_BELT_4_MIDDLE, + EL_CONVEYOR_BELT_4_RIGHT, + -1 + }; + + static int ep_belt_active[] = + { + EL_CONVEYOR_BELT_1_LEFT_ACTIVE, + EL_CONVEYOR_BELT_1_MIDDLE_ACTIVE, + EL_CONVEYOR_BELT_1_RIGHT_ACTIVE, + EL_CONVEYOR_BELT_2_LEFT_ACTIVE, + EL_CONVEYOR_BELT_2_MIDDLE_ACTIVE, + EL_CONVEYOR_BELT_2_RIGHT_ACTIVE, + EL_CONVEYOR_BELT_3_LEFT_ACTIVE, + EL_CONVEYOR_BELT_3_MIDDLE_ACTIVE, + EL_CONVEYOR_BELT_3_RIGHT_ACTIVE, + EL_CONVEYOR_BELT_4_LEFT_ACTIVE, + EL_CONVEYOR_BELT_4_MIDDLE_ACTIVE, + EL_CONVEYOR_BELT_4_RIGHT_ACTIVE, + -1 + }; + + static int ep_belt_switch[] = { - EL_BUG, - EL_SPACESHIP, - EL_BD_BUTTERFLY, - EL_BD_FIREFLY, - EL_YAMYAM, - EL_DARK_YAMYAM, - EL_ROBOT, - EL_PACMAN, - EL_SP_SNIKSNAK, - EL_SP_ELECTRON + EL_CONVEYOR_BELT_1_SWITCH_LEFT, + EL_CONVEYOR_BELT_1_SWITCH_MIDDLE, + EL_CONVEYOR_BELT_1_SWITCH_RIGHT, + EL_CONVEYOR_BELT_2_SWITCH_LEFT, + EL_CONVEYOR_BELT_2_SWITCH_MIDDLE, + EL_CONVEYOR_BELT_2_SWITCH_RIGHT, + EL_CONVEYOR_BELT_3_SWITCH_LEFT, + EL_CONVEYOR_BELT_3_SWITCH_MIDDLE, + EL_CONVEYOR_BELT_3_SWITCH_RIGHT, + EL_CONVEYOR_BELT_4_SWITCH_LEFT, + EL_CONVEYOR_BELT_4_SWITCH_MIDDLE, + EL_CONVEYOR_BELT_4_SWITCH_RIGHT, + -1 }; - static int ep_enemy_num = SIZEOF_ARRAY_INT(ep_enemy); - static int ep_mauer[] = + static int ep_sp_element[] = { - EL_STEELWALL, - EL_GATE_1, - EL_GATE_2, - EL_GATE_3, - EL_GATE_4, - EL_GATE_1_GRAY, - EL_GATE_2_GRAY, - EL_GATE_3_GRAY, - EL_GATE_4_GRAY, - EL_EM_GATE_1, - EL_EM_GATE_2, - EL_EM_GATE_3, - EL_EM_GATE_4, - EL_EM_GATE_1_GRAY, - EL_EM_GATE_2_GRAY, - EL_EM_GATE_3_GRAY, - EL_EM_GATE_4_GRAY, - EL_EXIT_CLOSED, - EL_EXIT_OPENING, - EL_EXIT_OPEN, - EL_WALL, - EL_WALL_CRUMBLED, - EL_EXPANDABLE_WALL, - EL_EXPANDABLE_WALL_HORIZONTAL, - EL_EXPANDABLE_WALL_VERTICAL, - EL_EXPANDABLE_WALL_ANY, - EL_EXPANDABLE_WALL_GROWING, - EL_BD_WALL, + EL_SP_EMPTY, + EL_SP_ZONK, + EL_SP_BASE, + EL_SP_MURPHY, + EL_SP_INFOTRON, EL_SP_CHIP_SINGLE, + EL_SP_HARDWARE_GRAY, + EL_SP_EXIT_CLOSED, + EL_SP_EXIT_OPEN, + EL_SP_DISK_ORANGE, + EL_SP_PORT_RIGHT, + EL_SP_PORT_DOWN, + EL_SP_PORT_LEFT, + EL_SP_PORT_UP, + EL_SP_GRAVITY_PORT_RIGHT, + EL_SP_GRAVITY_PORT_DOWN, + EL_SP_GRAVITY_PORT_LEFT, + EL_SP_GRAVITY_PORT_UP, + EL_SP_SNIKSNAK, + EL_SP_DISK_YELLOW, + EL_SP_TERMINAL, + EL_SP_DISK_RED, + EL_SP_PORT_VERTICAL, + EL_SP_PORT_HORIZONTAL, + EL_SP_PORT_ANY, + EL_SP_ELECTRON, + EL_SP_BUGGY_BASE, EL_SP_CHIP_LEFT, EL_SP_CHIP_RIGHT, - EL_SP_CHIP_TOP, - EL_SP_CHIP_BOTTOM, - EL_SP_HARDWARE_GRAY, + EL_SP_HARDWARE_BASE_1, EL_SP_HARDWARE_GREEN, EL_SP_HARDWARE_BLUE, EL_SP_HARDWARE_RED, EL_SP_HARDWARE_YELLOW, - EL_SP_HARDWARE_BASE_1, EL_SP_HARDWARE_BASE_2, EL_SP_HARDWARE_BASE_3, EL_SP_HARDWARE_BASE_4, EL_SP_HARDWARE_BASE_5, EL_SP_HARDWARE_BASE_6, - EL_SP_TERMINAL, - EL_SP_TERMINAL_ACTIVE, - EL_SP_EXIT_CLOSED, - EL_SP_EXIT_OPEN, - EL_INVISIBLE_STEELWALL, - EL_INVISIBLE_STEELWALL_ACTIVE, + EL_SP_CHIP_TOP, + EL_SP_CHIP_BOTTOM, + /* additional elements that appeared in newer Supaplex levels */ EL_INVISIBLE_WALL, - EL_INVISIBLE_WALL_ACTIVE, - EL_STEELWALL_SLANTED, - EL_EMC_STEELWALL_1, - EL_EMC_STEELWALL_2, - EL_EMC_STEELWALL_3, - EL_EMC_STEELWALL_4, - EL_EMC_WALL_1, - EL_EMC_WALL_2, - EL_EMC_WALL_3, - EL_EMC_WALL_4, - EL_EMC_WALL_5, - EL_EMC_WALL_6, - EL_EMC_WALL_7, - EL_EMC_WALL_8 + /* more than one murphy in a level results in an inactive clone */ + EL_SP_MURPHY_CLONE, + -1 + }; + + static int ep_has_content[] = + { + EL_YAMYAM, + EL_AMOEBA_WET, + EL_AMOEBA_DRY, + EL_AMOEBA_FULL, + EL_BD_AMOEBA, + -1 + }; + + static int ep_tube[] = + { + EL_TUBE_LEFT_UP, + EL_TUBE_LEFT_DOWN, + EL_TUBE_RIGHT_UP, + EL_TUBE_RIGHT_DOWN, + EL_TUBE_HORIZONTAL, + EL_TUBE_HORIZONTAL_UP, + EL_TUBE_HORIZONTAL_DOWN, + EL_TUBE_VERTICAL, + EL_TUBE_VERTICAL_LEFT, + EL_TUBE_VERTICAL_RIGHT, + EL_TUBE_ANY, + -1 }; - static int ep_mauer_num = SIZEOF_ARRAY_INT(ep_mauer); - static int ep_can_fall[] = + static struct + { + int *elements; + int property; + } element_properties[] = + { + { ep_amoebalive, EP_AMOEBALIVE }, + { ep_amoeboid, EP_AMOEBOID }, + { ep_can_be_crumbled, EP_CAN_BE_CRUMBLED }, + { ep_pforte, EP_PFORTE }, + { ep_solid, EP_SOLID }, + { ep_indestructible, EP_INDESTRUCTIBLE }, + { ep_slippery, EP_SLIPPERY }, + { ep_enemy, EP_ENEMY }, + { ep_mauer, EP_MAUER }, + { ep_can_fall, EP_CAN_FALL }, + { ep_can_smash, EP_CAN_SMASH }, + { ep_can_change, EP_CAN_CHANGE }, + { ep_can_move, EP_CAN_MOVE }, + { ep_could_move, EP_COULD_MOVE }, + { ep_dont_touch, EP_DONT_TOUCH }, + { ep_dont_go_to, EP_DONT_GO_TO }, + { ep_food_dark_yamyam, EP_FOOD_DARK_YAMYAM }, + { ep_bd_element, EP_BD_ELEMENT }, + { ep_sb_element, EP_SB_ELEMENT }, + { ep_gem, EP_GEM }, + { ep_inactive, EP_INACTIVE }, + { ep_explosive, EP_EXPLOSIVE }, + { ep_food_penguin, EP_FOOD_PENGUIN }, + { ep_pushable, EP_PUSHABLE }, + { ep_player, EP_PLAYER }, + { ep_walkable_over, EP_WALKABLE_OVER }, + { ep_walkable_inside, EP_WALKABLE_INSIDE }, + { ep_walkable_under, EP_WALKABLE_UNDER }, + { ep_passable_over, EP_PASSABLE_OVER }, + { ep_passable_inside, EP_PASSABLE_INSIDE }, + { ep_passable_under, EP_PASSABLE_UNDER }, + + { ep_diggable, EP_DIGGABLE }, + { ep_collectible, EP_COLLECTIBLE }, + { ep_active_bomb, EP_ACTIVE_BOMB }, + { ep_belt, EP_BELT }, + { ep_belt_active, EP_BELT_ACTIVE }, + { ep_belt_switch, EP_BELT_SWITCH }, + { ep_sp_element, EP_SP_ELEMENT }, + { ep_has_content, EP_HAS_CONTENT }, + { ep_tube, EP_TUBE }, + { NULL, -1 } + }; + +#if 0 + static int active_properties[] = + { + EP_AMOEBALIVE, + EP_AMOEBOID, + EP_PFORTE, + EP_SOLID, + EP_ENEMY, + EP_MAUER, + EP_CAN_FALL, + EP_CAN_SMASH, + EP_CAN_CHANGE, + EP_CAN_MOVE, + EP_COULD_MOVE, + EP_DONT_TOUCH, + EP_DONT_GO_TO, + EP_GEM, + EP_EXPLOSIVE, + EP_PUSHABLE, + EP_PLAYER, + EP_HAS_CONTENT, + EP_DIGGABLE, + EP_PASSABLE_INSIDE, + EP_OVER_PLAYER, + EP_ACTIVE_BOMB, + + EP_BELT, + EP_BELT_ACTIVE, + EP_BELT_SWITCH, + EP_WALKABLE_UNDER, + EP_EM_SLIPPERY_WALL, + EP_CAN_BE_CRUMBLED, + }; +#endif + + /* always start with reliable default values (no properties) */ + for (i=0; iconnected = TRUE; +} + +static void InitArtworkInfo() +{ + LoadArtworkInfo(); +} + +static char *get_element_class_token(int element) +{ + char *element_class_name = element_info[element].class_name; + char *element_class_token = checked_malloc(strlen(element_class_name) + 3); + + sprintf(element_class_token, "[%s]", element_class_name); + + return element_class_token; +} + +static void InitArtworkConfig() +{ + static char *image_id_prefix[MAX_NUM_ELEMENTS + NUM_FONTS + 1]; + static char *sound_id_prefix[MAX_NUM_ELEMENTS + MAX_NUM_ELEMENTS + 1]; + static char *action_id_suffix[NUM_ACTIONS + 1]; + static char *direction_id_suffix[NUM_DIRECTIONS + 1]; + static char *special_id_suffix[NUM_SPECIAL_GFX_ARGS + 1]; + static char *dummy[1] = { NULL }; + static char *ignore_image_tokens[] = { - EL_ROCK, - EL_BD_ROCK, - EL_EMERALD, - EL_BD_DIAMOND, - EL_EMERALD_YELLOW, - EL_EMERALD_RED, - EL_EMERALD_PURPLE, - EL_DIAMOND, - EL_BOMB, - EL_NUT, - EL_AMOEBA_DROP, - EL_TIME_ORB_FULL, - EL_TIME_ORB_EMPTY, - EL_SP_ZONK, - EL_SP_INFOTRON, - EL_SP_DISK_ORANGE, - EL_PEARL, - EL_CRYSTAL, - EL_SPRING, - EL_DX_SUPABOMB + "name", + "sort_priority", + "global.num_toons", + "menu.draw_xoffset", + "menu.draw_yoffset", + "menu.draw_xoffset.MAIN", + "menu.draw_yoffset.MAIN", + "door.step_offset", + "door.step_delay", + NULL }; - static int ep_can_smash_num = SIZEOF_ARRAY_INT(ep_can_smash); - - static int ep_can_change[] = + static char *ignore_sound_tokens[] = { - EL_ROCK, - EL_BD_ROCK, - EL_EMERALD, - EL_BD_DIAMOND, - EL_EMERALD_YELLOW, - EL_EMERALD_RED, - EL_EMERALD_PURPLE, - EL_DIAMOND + "name", + "sort_priority", + NULL }; - static int ep_can_change_num = SIZEOF_ARRAY_INT(ep_can_change); + int i; - static int ep_can_move[] = + for (i=0; i len_font_token && + strncmp(image_config[i].token, font_token, len_font_token) == 0) + { + if (strcmp(&image_config[i].token[len_font_token], ".x") == 0) + font_initial[j].src_x = atoi(image_config[i].value); + else if (strcmp(&image_config[i].token[len_font_token], ".y") == 0) + font_initial[j].src_y = atoi(image_config[i].value); + else if (strcmp(&image_config[i].token[len_font_token], ".width") == 0) + font_initial[j].width = atoi(image_config[i].value); + else if (strcmp(&image_config[i].token[len_font_token],".height") == 0) + font_initial[j].height = atoi(image_config[i].value); + } + } + } + + for (j=0; j < NUM_INITIAL_FONTS; j++) { - EL_BUG_RIGHT, - EL_BUG_UP, - EL_BUG_LEFT, - EL_BUG_DOWN, - EL_SPACESHIP_RIGHT, - EL_SPACESHIP_UP, - EL_SPACESHIP_LEFT, - EL_SPACESHIP_DOWN, - EL_BD_BUTTERFLY_RIGHT, - EL_BD_BUTTERFLY_UP, - EL_BD_BUTTERFLY_LEFT, - EL_BD_BUTTERFLY_DOWN, - EL_BD_FIREFLY_RIGHT, - EL_BD_FIREFLY_UP, - EL_BD_FIREFLY_LEFT, - EL_BD_FIREFLY_DOWN, - EL_PACMAN_RIGHT, - EL_PACMAN_UP, - EL_PACMAN_LEFT, - EL_PACMAN_DOWN - }; - static int ep_could_move_num = SIZEOF_ARRAY_INT(ep_could_move); + font_initial[j].num_chars = DEFAULT_NUM_CHARS_PER_FONT; + font_initial[j].num_chars_per_line = DEFAULT_NUM_CHARS_PER_LINE; + } + + if (filename_font_initial == NULL) /* should not happen */ + Error(ERR_EXIT, "cannot get filename for '%s'", CONFIG_TOKEN_FONT_INITIAL); + + /* create additional image buffers for double-buffering */ + bitmap_db_field = CreateBitmap(FXSIZE, FYSIZE, DEFAULT_DEPTH); + bitmap_db_door = CreateBitmap(3 * DXSIZE, DYSIZE + VYSIZE, DEFAULT_DEPTH); + + /* initialize screen properties */ + InitGfxFieldInfo(SX, SY, SXSIZE, SYSIZE, + REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, + bitmap_db_field); + InitGfxDoor1Info(DX, DY, DXSIZE, DYSIZE); + InitGfxDoor2Info(VX, VY, VXSIZE, VYSIZE); + InitGfxScrollbufferInfo(FXSIZE, FYSIZE); + + bitmap_font_initial = LoadCustomImage(filename_font_initial); + + for (j=0; j < NUM_INITIAL_FONTS; j++) + font_initial[j].bitmap = bitmap_font_initial; - static int ep_dont_touch[] = - { - EL_BUG, - EL_SPACESHIP, - EL_BD_BUTTERFLY, - EL_BD_FIREFLY - }; - static int ep_dont_touch_num = SIZEOF_ARRAY_INT(ep_dont_touch); + InitFontGraphicInfo(); - static int ep_dont_go_to[] = - { - EL_BUG, - EL_SPACESHIP, - EL_BD_BUTTERFLY, - EL_BD_FIREFLY, - EL_YAMYAM, - EL_DARK_YAMYAM, - EL_ROBOT, - EL_PACMAN, - EL_AMOEBA_DROP, - EL_ACID, - EL_SP_SNIKSNAK, - EL_SP_ELECTRON, - EL_SP_BUGGY_BASE_ACTIVE, - EL_TRAP_ACTIVE, - EL_LANDMINE - }; - static int ep_dont_go_to_num = SIZEOF_ARRAY_INT(ep_dont_go_to); + DrawInitText(WINDOW_TITLE_STRING, 20, FC_YELLOW); + DrawInitText(WINDOW_SUBTITLE_STRING, 50, FC_RED); - static int ep_mampf2[] = - { - EL_SAND, - EL_BUG, - EL_SPACESHIP, - EL_BD_BUTTERFLY, - EL_BD_FIREFLY, - EL_YAMYAM, - EL_ROBOT, - EL_PACMAN, - EL_AMOEBA_DROP, - EL_AMOEBA_DEAD, - EL_AMOEBA_WET, - EL_AMOEBA_DRY, - EL_AMOEBA_FULL, - EL_BD_AMOEBA, - EL_EMERALD, - EL_BD_DIAMOND, - EL_EMERALD_YELLOW, - EL_EMERALD_RED, - EL_EMERALD_PURPLE, - EL_DIAMOND, - EL_PEARL, - EL_CRYSTAL - }; - static int ep_mampf2_num = SIZEOF_ARRAY_INT(ep_mampf2); + DrawInitText("Loading graphics:", 120, FC_GREEN); - static int ep_bd_element[] = - { - EL_EMPTY, - EL_SAND, - EL_WALL_CRUMBLED, - EL_BD_WALL, - EL_ROCK, - EL_BD_ROCK, - EL_BD_DIAMOND, - EL_BD_MAGIC_WALL, - EL_EXIT_CLOSED, - EL_EXIT_OPEN, - EL_STEELWALL, - EL_PLAYER_1, - EL_BD_FIREFLY, - EL_BD_FIREFLY_1, - EL_BD_FIREFLY_2, - EL_BD_FIREFLY_3, - EL_BD_FIREFLY_4, - EL_BD_BUTTERFLY, - EL_BD_BUTTERFLY_1, - EL_BD_BUTTERFLY_2, - EL_BD_BUTTERFLY_3, - EL_BD_BUTTERFLY_4, - EL_BD_AMOEBA, - EL_CHAR_QUESTION - }; - static int ep_bd_element_num = SIZEOF_ARRAY_INT(ep_bd_element); + InitTileClipmasks(); +} - static int ep_sb_element[] = - { - EL_EMPTY, - EL_STEELWALL, - EL_SOKOBAN_OBJECT, - EL_SOKOBAN_FIELD_EMPTY, - EL_SOKOBAN_FIELD_FULL, - EL_PLAYER_1, - EL_INVISIBLE_STEELWALL - }; - static int ep_sb_element_num = SIZEOF_ARRAY_INT(ep_sb_element); +void InitGfxBackground() +{ + int x, y; - static int ep_gem[] = - { - EL_EMERALD, - EL_BD_DIAMOND, - EL_EMERALD_YELLOW, - EL_EMERALD_RED, - EL_EMERALD_PURPLE, - EL_DIAMOND - }; - static int ep_gem_num = SIZEOF_ARRAY_INT(ep_gem); + drawto = backbuffer; + fieldbuffer = bitmap_db_field; + SetDrawtoField(DRAW_BACKBUFFER); - static int ep_inactive[] = - { - EL_EMPTY, - EL_SAND, - EL_WALL, - EL_BD_WALL, - EL_WALL_CRUMBLED, - EL_STEELWALL, - EL_AMOEBA_DEAD, - EL_QUICKSAND_EMPTY, - EL_STONEBLOCK, - EL_ROBOT_WHEEL, - EL_KEY_1, - EL_KEY_2, - EL_KEY_3, - EL_KEY_4, - EL_EM_KEY_1, - EL_EM_KEY_2, - EL_EM_KEY_3, - EL_EM_KEY_4, - EL_GATE_1, - EL_GATE_2, - EL_GATE_3, - EL_GATE_4, - EL_GATE_1_GRAY, - EL_GATE_2_GRAY, - EL_GATE_3_GRAY, - EL_GATE_4_GRAY, - EL_EM_GATE_1, - EL_EM_GATE_2, - EL_EM_GATE_3, - EL_EM_GATE_4, - EL_EM_GATE_1_GRAY, - EL_EM_GATE_2_GRAY, - EL_EM_GATE_3_GRAY, - EL_EM_GATE_4_GRAY, - EL_DYNAMITE, - EL_INVISIBLE_STEELWALL, - EL_INVISIBLE_WALL, - EL_INVISIBLE_SAND, - EL_LAMP, - EL_LAMP_ACTIVE, - EL_WALL_EMERALD, - EL_WALL_DIAMOND, - EL_WALL_BD_DIAMOND, - EL_WALL_EMERALD_YELLOW, - EL_DYNABOMB_INCREASE_NUMBER, - EL_DYNABOMB_INCREASE_SIZE, - EL_DYNABOMB_INCREASE_POWER, - EL_SOKOBAN_OBJECT, - EL_SOKOBAN_FIELD_EMPTY, - EL_SOKOBAN_FIELD_FULL, - EL_WALL_EMERALD_RED, - EL_WALL_EMERALD_PURPLE, - EL_ACID_POOL_TOPLEFT, - EL_ACID_POOL_TOPRIGHT, - EL_ACID_POOL_BOTTOMLEFT, - EL_ACID_POOL_BOTTOM, - EL_ACID_POOL_BOTTOMRIGHT, - EL_MAGIC_WALL, - EL_MAGIC_WALL_DEAD, - EL_BD_MAGIC_WALL, - EL_BD_MAGIC_WALL_DEAD, - EL_AMOEBA_TO_DIAMOND, - EL_BLOCKED, - EL_SP_EMPTY, - EL_SP_BASE, - EL_SP_PORT_RIGHT, - EL_SP_PORT_DOWN, - EL_SP_PORT_LEFT, - EL_SP_PORT_UP, - EL_SP_GRAVITY_PORT_RIGHT, - EL_SP_GRAVITY_PORT_DOWN, - EL_SP_GRAVITY_PORT_LEFT, - EL_SP_GRAVITY_PORT_UP, - EL_SP_PORT_HORIZONTAL, - EL_SP_PORT_VERTICAL, - EL_SP_PORT_ANY, - EL_SP_DISK_RED, - EL_SP_DISK_YELLOW, - EL_SP_CHIP_SINGLE, - EL_SP_CHIP_LEFT, - EL_SP_CHIP_RIGHT, - EL_SP_CHIP_TOP, - EL_SP_CHIP_BOTTOM, - EL_SP_HARDWARE_GRAY, - EL_SP_HARDWARE_GREEN, - EL_SP_HARDWARE_BLUE, - EL_SP_HARDWARE_RED, - EL_SP_HARDWARE_YELLOW, - EL_SP_HARDWARE_BASE_1, - EL_SP_HARDWARE_BASE_2, - EL_SP_HARDWARE_BASE_3, - EL_SP_HARDWARE_BASE_4, - EL_SP_HARDWARE_BASE_5, - EL_SP_HARDWARE_BASE_6, - EL_CONVEYOR_BELT_1_SWITCH_LEFT, - EL_CONVEYOR_BELT_1_SWITCH_MIDDLE, - EL_CONVEYOR_BELT_1_SWITCH_RIGHT, - EL_CONVEYOR_BELT_2_SWITCH_LEFT, - EL_CONVEYOR_BELT_2_SWITCH_MIDDLE, - EL_CONVEYOR_BELT_2_SWITCH_RIGHT, - EL_CONVEYOR_BELT_3_SWITCH_LEFT, - EL_CONVEYOR_BELT_3_SWITCH_MIDDLE, - EL_CONVEYOR_BELT_3_SWITCH_RIGHT, - EL_CONVEYOR_BELT_4_SWITCH_LEFT, - EL_CONVEYOR_BELT_4_SWITCH_MIDDLE, - EL_CONVEYOR_BELT_4_SWITCH_RIGHT, - EL_SIGN_EXCLAMATION, - EL_SIGN_RADIOACTIVITY, - EL_SIGN_STOP, - EL_SIGN_WHEELCHAIR, - EL_SIGN_PARKING, - EL_SIGN_ONEWAY, - EL_SIGN_HEART, - EL_SIGN_TRIANGLE, - EL_SIGN_ROUND, - EL_SIGN_EXIT, - EL_SIGN_YINYANG, - EL_SIGN_OTHER, - EL_STEELWALL_SLANTED, - EL_EMC_STEELWALL_1, - EL_EMC_STEELWALL_2, - EL_EMC_STEELWALL_3, - EL_EMC_STEELWALL_4, - EL_EMC_WALL_1, - EL_EMC_WALL_2, - EL_EMC_WALL_3, - EL_EMC_WALL_4, - EL_EMC_WALL_5, - EL_EMC_WALL_6, - EL_EMC_WALL_7, - EL_EMC_WALL_8 - }; - static int ep_inactive_num = SIZEOF_ARRAY_INT(ep_inactive); + BlitBitmap(graphic_info[IMG_GLOBAL_BORDER].bitmap, backbuffer, + 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); + ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); + ClearRectangle(bitmap_db_door, 0, 0, 3 * DXSIZE, DYSIZE + VYSIZE); + + for (x=0; xidentifier); + ReinitializeSounds(); +} - static int ep_has_content[] = - { - EL_YAMYAM, - EL_AMOEBA_WET, - EL_AMOEBA_DRY, - EL_AMOEBA_FULL, - EL_BD_AMOEBA - }; - static int ep_has_content_num = SIZEOF_ARRAY_INT(ep_has_content); +static void InitMusic() +{ + InitReloadCustomMusic(artwork.mus_current->identifier); + ReinitializeMusic(); +} - static int ep_eatable[] = - { - EL_SAND, - EL_SP_BASE, - EL_SP_BUGGY_BASE, - EL_SP_BUGGY_BASE_ACTIVATING, - EL_TRAP, - EL_INVISIBLE_SAND, - EL_INVISIBLE_SAND_ACTIVE - }; - static int ep_eatable_num = SIZEOF_ARRAY_INT(ep_eatable); +void InitNetworkServer() +{ +#if defined(PLATFORM_UNIX) + int nr_wanted; +#endif - static int ep_sp_element[] = - { - EL_SP_EMPTY, - EL_SP_ZONK, - EL_SP_BASE, - EL_SP_MURPHY, - EL_SP_INFOTRON, - EL_SP_CHIP_SINGLE, - EL_SP_HARDWARE_GRAY, - EL_SP_EXIT_CLOSED, - EL_SP_EXIT_OPEN, - EL_SP_DISK_ORANGE, - EL_SP_PORT_RIGHT, - EL_SP_PORT_DOWN, - EL_SP_PORT_LEFT, - EL_SP_PORT_UP, - EL_SP_GRAVITY_PORT_RIGHT, - EL_SP_GRAVITY_PORT_DOWN, - EL_SP_GRAVITY_PORT_LEFT, - EL_SP_GRAVITY_PORT_UP, - EL_SP_SNIKSNAK, - EL_SP_DISK_YELLOW, - EL_SP_TERMINAL, - EL_SP_DISK_RED, - EL_SP_PORT_VERTICAL, - EL_SP_PORT_HORIZONTAL, - EL_SP_PORT_ANY, - EL_SP_ELECTRON, - EL_SP_BUGGY_BASE, - EL_SP_CHIP_LEFT, - EL_SP_CHIP_RIGHT, - EL_SP_HARDWARE_BASE_1, - EL_SP_HARDWARE_GREEN, - EL_SP_HARDWARE_BLUE, - EL_SP_HARDWARE_RED, - EL_SP_HARDWARE_YELLOW, - EL_SP_HARDWARE_BASE_2, - EL_SP_HARDWARE_BASE_3, - EL_SP_HARDWARE_BASE_4, - EL_SP_HARDWARE_BASE_5, - EL_SP_HARDWARE_BASE_6, - EL_SP_CHIP_TOP, - EL_SP_CHIP_BOTTOM, - /* additional elements that appeared in newer Supaplex levels */ - EL_INVISIBLE_WALL, - /* more than one murphy in a level results in an inactive clone */ - EL_SP_MURPHY_CLONE - }; - static int ep_sp_element_num = SIZEOF_ARRAY_INT(ep_sp_element); + if (!options.network) + return; - static int ep_quick_gate[] = - { - EL_EM_GATE_1, - EL_EM_GATE_2, - EL_EM_GATE_3, - EL_EM_GATE_4, - EL_EM_GATE_1_GRAY, - EL_EM_GATE_2_GRAY, - EL_EM_GATE_3_GRAY, - EL_EM_GATE_4_GRAY, - EL_SP_PORT_LEFT, - EL_SP_PORT_RIGHT, - EL_SP_PORT_UP, - EL_SP_PORT_DOWN, - EL_SP_GRAVITY_PORT_LEFT, - EL_SP_GRAVITY_PORT_RIGHT, - EL_SP_GRAVITY_PORT_UP, - EL_SP_GRAVITY_PORT_DOWN, - EL_SP_PORT_HORIZONTAL, - EL_SP_PORT_VERTICAL, - EL_SP_PORT_ANY, - EL_SWITCHGATE_OPEN, - EL_TIMEGATE_OPEN - }; - static int ep_quick_gate_num = SIZEOF_ARRAY_INT(ep_quick_gate); +#if defined(PLATFORM_UNIX) + nr_wanted = Request("Choose player", REQ_PLAYER | REQ_STAY_CLOSED); - static int ep_over_player[] = - { - EL_SP_PORT_LEFT, - EL_SP_PORT_RIGHT, - EL_SP_PORT_UP, - EL_SP_PORT_DOWN, - EL_SP_GRAVITY_PORT_LEFT, - EL_SP_GRAVITY_PORT_RIGHT, - EL_SP_GRAVITY_PORT_UP, - EL_SP_GRAVITY_PORT_DOWN, - EL_SP_PORT_HORIZONTAL, - EL_SP_PORT_VERTICAL, - EL_SP_PORT_ANY, - EL_TUBE_ANY, - EL_TUBE_VERTICAL, - EL_TUBE_HORIZONTAL, - EL_TUBE_VERTICAL_LEFT, - EL_TUBE_VERTICAL_RIGHT, - EL_TUBE_HORIZONTAL_UP, - EL_TUBE_HORIZONTAL_DOWN, - EL_TUBE_LEFT_UP, - EL_TUBE_LEFT_DOWN, - EL_TUBE_RIGHT_UP, - EL_TUBE_RIGHT_DOWN - }; - static int ep_over_player_num = SIZEOF_ARRAY_INT(ep_over_player); + if (!ConnectToServer(options.server_host, options.server_port)) + Error(ERR_EXIT, "cannot connect to network game server"); - static int ep_active_bomb[] = - { - EL_DYNAMITE_ACTIVE, - EL_DYNABOMB_PLAYER_1_ACTIVE, - EL_DYNABOMB_PLAYER_2_ACTIVE, - EL_DYNABOMB_PLAYER_3_ACTIVE, - EL_DYNABOMB_PLAYER_4_ACTIVE, - EL_SP_DISK_RED_ACTIVE - }; - static int ep_active_bomb_num = SIZEOF_ARRAY_INT(ep_active_bomb); + SendToServer_PlayerName(setup.player_name); + SendToServer_ProtocolVersion(); - static int ep_belt[] = - { - EL_CONVEYOR_BELT_1_LEFT, - EL_CONVEYOR_BELT_1_MIDDLE, - EL_CONVEYOR_BELT_1_RIGHT, - EL_CONVEYOR_BELT_2_LEFT, - EL_CONVEYOR_BELT_2_MIDDLE, - EL_CONVEYOR_BELT_2_RIGHT, - EL_CONVEYOR_BELT_3_LEFT, - EL_CONVEYOR_BELT_3_MIDDLE, - EL_CONVEYOR_BELT_3_RIGHT, - EL_CONVEYOR_BELT_4_LEFT, - EL_CONVEYOR_BELT_4_MIDDLE, - EL_CONVEYOR_BELT_4_RIGHT, - }; - static int ep_belt_num = SIZEOF_ARRAY_INT(ep_belt); + if (nr_wanted) + SendToServer_NrWanted(nr_wanted); +#endif +} + +void ReloadCustomArtwork() +{ + static char *leveldir_current_identifier = NULL; + static boolean last_override_level_graphics = FALSE; + static boolean last_override_level_sounds = FALSE; + static boolean last_override_level_music = FALSE; + /* identifier for new artwork; default: artwork configured in setup */ + char *gfx_new_identifier = artwork.gfx_current->identifier; + char *snd_new_identifier = artwork.snd_current->identifier; + char *mus_new_identifier = artwork.mus_current->identifier; + boolean redraw_screen = FALSE; + + if (leveldir_current_identifier == NULL) + leveldir_current_identifier = leveldir_current->identifier; + +#if 0 + printf("CURRENT GFX: '%s' ['%s']\n", artwork.gfx_current->identifier, + leveldir_current->graphics_set); + printf("CURRENT LEV: '%s' / '%s'\n", leveldir_current_identifier, + leveldir_current->identifier); +#endif + +#if 0 + printf("graphics --> '%s' ('%s')\n", + artwork.gfx_current_identifier, artwork.gfx_current->filename); + printf("sounds --> '%s' ('%s')\n", + artwork.snd_current_identifier, artwork.snd_current->filename); + printf("music --> '%s' ('%s')\n", + artwork.mus_current_identifier, artwork.mus_current->filename); +#endif + + /* leveldir_current may be invalid (level group, parent link) */ + if (!validLevelSeries(leveldir_current)) + return; - static int ep_belt_active[] = + /* when a new level series was selected, check if there was a change + in custom artwork stored in level series directory */ + if (leveldir_current_identifier != leveldir_current->identifier) { - EL_CONVEYOR_BELT_1_LEFT_ACTIVE, - EL_CONVEYOR_BELT_1_MIDDLE_ACTIVE, - EL_CONVEYOR_BELT_1_RIGHT_ACTIVE, - EL_CONVEYOR_BELT_2_LEFT_ACTIVE, - EL_CONVEYOR_BELT_2_MIDDLE_ACTIVE, - EL_CONVEYOR_BELT_2_RIGHT_ACTIVE, - EL_CONVEYOR_BELT_3_LEFT_ACTIVE, - EL_CONVEYOR_BELT_3_MIDDLE_ACTIVE, - EL_CONVEYOR_BELT_3_RIGHT_ACTIVE, - EL_CONVEYOR_BELT_4_LEFT_ACTIVE, - EL_CONVEYOR_BELT_4_MIDDLE_ACTIVE, - EL_CONVEYOR_BELT_4_RIGHT_ACTIVE, - }; - static int ep_belt_active_num = SIZEOF_ARRAY_INT(ep_belt_active); + char *identifier_old = leveldir_current_identifier; + char *identifier_new = leveldir_current->identifier; - static int ep_belt_switch[] = - { - EL_CONVEYOR_BELT_1_SWITCH_LEFT, - EL_CONVEYOR_BELT_1_SWITCH_MIDDLE, - EL_CONVEYOR_BELT_1_SWITCH_RIGHT, - EL_CONVEYOR_BELT_2_SWITCH_LEFT, - EL_CONVEYOR_BELT_2_SWITCH_MIDDLE, - EL_CONVEYOR_BELT_2_SWITCH_RIGHT, - EL_CONVEYOR_BELT_3_SWITCH_LEFT, - EL_CONVEYOR_BELT_3_SWITCH_MIDDLE, - EL_CONVEYOR_BELT_3_SWITCH_RIGHT, - EL_CONVEYOR_BELT_4_SWITCH_LEFT, - EL_CONVEYOR_BELT_4_SWITCH_MIDDLE, - EL_CONVEYOR_BELT_4_SWITCH_RIGHT, - }; - static int ep_belt_switch_num = SIZEOF_ARRAY_INT(ep_belt_switch); + if (getTreeInfoFromIdentifier(artwork.gfx_first, identifier_old) != + getTreeInfoFromIdentifier(artwork.gfx_first, identifier_new)) + gfx_new_identifier = identifier_new; + if (getTreeInfoFromIdentifier(artwork.snd_first, identifier_old) != + getTreeInfoFromIdentifier(artwork.snd_first, identifier_new)) + snd_new_identifier = identifier_new; + if (getTreeInfoFromIdentifier(artwork.mus_first, identifier_new) != + getTreeInfoFromIdentifier(artwork.mus_first, identifier_new)) + mus_new_identifier = identifier_new; - static int ep_tube[] = - { - EL_TUBE_ANY, - EL_TUBE_VERTICAL, - EL_TUBE_HORIZONTAL, - EL_TUBE_VERTICAL_LEFT, - EL_TUBE_VERTICAL_RIGHT, - EL_TUBE_HORIZONTAL_UP, - EL_TUBE_HORIZONTAL_DOWN, - EL_TUBE_LEFT_UP, - EL_TUBE_LEFT_DOWN, - EL_TUBE_RIGHT_UP, - EL_TUBE_RIGHT_DOWN - }; - static int ep_tube_num = SIZEOF_ARRAY_INT(ep_tube); - - static long ep1_bit[] = - { - EP_BIT_AMOEBALIVE, - EP_BIT_AMOEBOID, - EP_BIT_SCHLUESSEL, - EP_BIT_PFORTE, - EP_BIT_SOLID, - EP_BIT_INDESTRUCTIBLE, - EP_BIT_SLIPPERY, - EP_BIT_ENEMY, - EP_BIT_MAUER, - EP_BIT_CAN_FALL, - EP_BIT_CAN_SMASH, - EP_BIT_CAN_CHANGE, - EP_BIT_CAN_MOVE, - EP_BIT_COULD_MOVE, - EP_BIT_DONT_TOUCH, - EP_BIT_DONT_GO_TO, - EP_BIT_MAMPF2, - EP_BIT_BD_ELEMENT, - EP_BIT_SB_ELEMENT, - EP_BIT_GEM, - EP_BIT_INACTIVE, - EP_BIT_EXPLOSIVE, - EP_BIT_MAMPF3, - EP_BIT_PUSHABLE, - EP_BIT_PLAYER, - EP_BIT_HAS_CONTENT, - EP_BIT_EATABLE, - EP_BIT_SP_ELEMENT, - EP_BIT_QUICK_GATE, - EP_BIT_OVER_PLAYER, - EP_BIT_ACTIVE_BOMB - }; - static long ep2_bit[] = - { - EP_BIT_BELT, - EP_BIT_BELT_ACTIVE, - EP_BIT_BELT_SWITCH, - EP_BIT_TUBE - }; - static int *ep1_array[] = - { - ep_amoebalive, - ep_amoeboid, - ep_schluessel, - ep_pforte, - ep_solid, - ep_indestructible, - ep_slippery, - ep_enemy, - ep_mauer, - ep_can_fall, - ep_can_smash, - ep_can_change, - ep_can_move, - ep_could_move, - ep_dont_touch, - ep_dont_go_to, - ep_mampf2, - ep_bd_element, - ep_sb_element, - ep_gem, - ep_inactive, - ep_explosive, - ep_mampf3, - ep_pushable, - ep_player, - ep_has_content, - ep_eatable, - ep_sp_element, - ep_quick_gate, - ep_over_player, - ep_active_bomb - }; - static int *ep2_array[] = - { - ep_belt, - ep_belt_active, - ep_belt_switch, - ep_tube - }; - static int *ep1_num[] = - { - &ep_amoebalive_num, - &ep_amoeboid_num, - &ep_schluessel_num, - &ep_pforte_num, - &ep_solid_num, - &ep_indestructible_num, - &ep_slippery_num, - &ep_enemy_num, - &ep_mauer_num, - &ep_can_fall_num, - &ep_can_smash_num, - &ep_can_change_num, - &ep_can_move_num, - &ep_could_move_num, - &ep_dont_touch_num, - &ep_dont_go_to_num, - &ep_mampf2_num, - &ep_bd_element_num, - &ep_sb_element_num, - &ep_gem_num, - &ep_inactive_num, - &ep_explosive_num, - &ep_mampf3_num, - &ep_pushable_num, - &ep_player_num, - &ep_has_content_num, - &ep_eatable_num, - &ep_sp_element_num, - &ep_quick_gate_num, - &ep_over_player_num, - &ep_active_bomb_num - }; - static int *ep2_num[] = - { - &ep_belt_num, - &ep_belt_active_num, - &ep_belt_switch_num, - &ep_tube_num - }; - static int num_properties1 = SIZEOF_ARRAY(ep1_num, int *); - static int num_properties2 = SIZEOF_ARRAY(ep2_num, int *); + leveldir_current_identifier = leveldir_current->identifier; + } - for (i=0; igraphics_set != NULL) + gfx_new_identifier = leveldir_current->graphics_set; + if (leveldir_current->sounds_set != NULL) + snd_new_identifier = leveldir_current->sounds_set; + if (leveldir_current->music_set != NULL) + mus_new_identifier = leveldir_current->music_set; + + if (strcmp(artwork.gfx_current_identifier, gfx_new_identifier) != 0 || + last_override_level_graphics != setup.override_level_graphics) { - Properties1[i] = 0; - Properties2[i] = 0; - } +#if 0 + printf("RELOADING GRAPHICS '%s' -> '%s' ('%s')\n", + artwork.gfx_current_identifier, + artwork.gfx_current->identifier, + gfx_new_identifier); +#endif - for (i=0; iidentifier; + last_override_level_graphics = setup.override_level_graphics; - exit(0); + redraw_screen = TRUE; } - else if (strcmp(command, "print soundsinfo.conf") == 0) + + if (strcmp(artwork.snd_current_identifier, snd_new_identifier) != 0 || + last_override_level_sounds != setup.override_level_sounds) { - int i; +#if 0 + printf("RELOADING SOUNDS '%s' -> '%s' ('%s')\n", + artwork.snd_current_identifier, + artwork.snd_current->identifier, + snd_new_identifier); +#endif - printf("# You can configure additional/alternative sound files here.\n"); - printf("# (The sounds below are default and therefore commented out.)\n"); - printf("\n"); - printf("%s\n", getFormattedSetupEntry("name", "Classic Sounds")); - printf("\n"); - printf("%s\n", getFormattedSetupEntry("sort_priority", "100")); - printf("\n"); + /* set artwork path to send it to the sound server process */ + setLevelArtworkDir(artwork.snd_first); - for (i=0; sound_config[i].token != NULL; i++) - printf("# %s\n", - getFormattedSetupEntry(sound_config[i].token, - sound_config[i].value)); + InitReloadCustomSounds(snd_new_identifier); + ReinitializeSounds(); - exit(0); - } - else if (strcmp(command, "print musicinfo.conf") == 0) - { - printf("# (Currently only \"name\" and \"sort_priority\" recognized.)\n"); - printf("\n"); - printf("%s\n", getFormattedSetupEntry("name", "Classic Music")); - printf("\n"); - printf("%s\n", getFormattedSetupEntry("sort_priority", "100")); + artwork.snd_current_identifier = artwork.snd_current->identifier; + last_override_level_sounds = setup.override_level_sounds; - exit(0); + redraw_screen = TRUE; } - else if (strncmp(command, "dump level ", 11) == 0) + + if (strcmp(artwork.mus_current_identifier, mus_new_identifier) != 0 || + last_override_level_music != setup.override_level_music) { - char *filename = &command[11]; + /* set artwork path to send it to the sound server process */ + setLevelArtworkDir(artwork.mus_first); - if (access(filename, F_OK) != 0) - Error(ERR_EXIT, "cannot open file '%s'", filename); + InitReloadCustomMusic(mus_new_identifier); + ReinitializeMusic(); - LoadLevelFromFilename(filename); - DumpLevel(&level); + artwork.mus_current_identifier = artwork.mus_current->identifier; + last_override_level_music = setup.override_level_music; - exit(0); + redraw_screen = TRUE; } - else if (strncmp(command, "dump tape ", 10) == 0) + + if (redraw_screen) { - char *filename = &command[10]; + InitGfxBackground(); - if (access(filename, F_OK) != 0) - Error(ERR_EXIT, "cannot open file '%s'", filename); + /* force redraw of (open or closed) door graphics */ + SetDoorState(DOOR_OPEN_ALL); + CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY); + } +} - LoadTapeFromFilename(filename); - DumpTape(&tape); - exit(0); - } - else if (strncmp(command, "autoplay ", 9) == 0) - { - char *str_copy = getStringCopy(&command[9]); - char *str_ptr = strchr(str_copy, ' '); +/* ========================================================================= */ +/* OpenAll() */ +/* ========================================================================= */ - global.autoplay_leveldir = str_copy; - global.autoplay_level_nr = -1; +void OpenAll() +{ + InitGlobal(); /* initialize some global variables */ - if (str_ptr != NULL) - { - *str_ptr++ = '\0'; /* terminate leveldir string */ - global.autoplay_level_nr = atoi(str_ptr); /* get level_nr value */ - } + if (options.execute_command) + Execute_Command(options.execute_command); + + if (options.serveronly) + { +#if defined(PLATFORM_UNIX) + NetworkServer(options.server_port, options.serveronly); +#else + Error(ERR_WARN, "networking only supported in Unix version"); +#endif + exit(0); /* never reached */ } - else + + InitSetup(); + + InitPlayerInfo(); + InitArtworkInfo(); /* needed before loading gfx, sound & music */ + InitArtworkConfig(); /* needed before forking sound child process */ + InitMixer(); + + InitCounter(); + + InitRND(NEW_RANDOMIZE); + InitSimpleRND(NEW_RANDOMIZE); + + InitJoysticks(); + + InitVideoDisplay(); + InitVideoBuffer(&backbuffer, &window, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, + setup.fullscreen); + + InitEventFilter(FilterMouseMotionEvents); + + InitElementProperties(); + + InitGfx(); + + InitLevelInfo(); + InitLevelArtworkInfo(); + + InitImages(); /* needs to know current level directory */ + InitSound(); /* needs to know current level directory */ + InitMusic(); /* needs to know current level directory */ + + InitGfxBackground(); + + if (global.autoplay_leveldir) { - Error(ERR_EXIT_HELP, "unrecognized command '%s'", command); + AutoPlayTape(); + return; } + + game_status = MAINMENU; + + DrawMainMenu(); + + InitNetworkServer(); } void CloseAllAndExit(int exit_value)