X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Finit.c;h=5a97a827c04b233c654bc8febe8f56caa9ebd07c;hp=926d429e307dbfb17ba1d54f366b6aa22a7a26b7;hb=601cca5b35649856ff49e1bcb3806592b736662c;hpb=b583d4fa28df35b6974bd075d3de65a841454556 diff --git a/src/init.c b/src/init.c index 926d429e..5a97a827 100644 --- a/src/init.c +++ b/src/init.c @@ -27,62 +27,41 @@ #include "config.h" #include "conf_e2g.c" /* include auto-generated data structure definitions */ +#include "conf_esg.c" /* include auto-generated data structure definitions */ -static char *image_filename[NUM_PICTURES] = -{ -#if 0 - "RocksScreen.pcx", - "RocksDoor.pcx", - "RocksToons.pcx", - "RocksFontBig.pcx", - "RocksFontSmall.pcx", - "RocksFontMedium.pcx", - "RocksFontEM.pcx" -#else - "RocksScreen.pcx", - "RocksElements.pcx", - "RocksDoor.pcx", - "RocksHeroes.pcx", - "RocksToons.pcx", - "RocksSP.pcx", - "RocksDC.pcx", - "RocksMore.pcx", - "RocksFontBig.pcx", - "RocksFontSmall.pcx", - "RocksFontMedium.pcx", - "RocksFontEM.pcx" -#endif -}; - static Bitmap *bitmap_font_initial = NULL; -static void InitSetup(void); -static void InitPlayerInfo(void); -static void InitLevelInfo(void); -static void InitArtworkInfo(void); -static void InitLevelArtworkInfo(void); -static void InitNetworkServer(void); -static void InitImages(void); -static void InitMixer(void); -static void InitSound(void); -static void InitGfx(void); -static void InitGfxBackground(void); -static void InitGadgets(void); -static void InitElementProperties(void); -static void InitElementInfo(void); -static void InitGraphicInfo(void); +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 InitElementSmallImages(); +static void InitElementGraphicInfo(); +static void InitElementSpecialGraphicInfo(); +static void InitElementSoundInfo(); +static void InitElementProperties(); +static void InitGraphicInfo(); static void InitSoundInfo(); -static void Execute_Debug_Command(char *); +static void Execute_Command(char *); -void OpenAll(void) +void OpenAll() { - if (options.debug_command) - { - Execute_Debug_Command(options.debug_command); + InitGlobal(); /* initialize some global variables */ - exit(0); - } + if (options.execute_command) + Execute_Command(options.execute_command); if (options.serveronly) { @@ -103,9 +82,11 @@ void OpenAll(void) InitSetup(); InitPlayerInfo(); InitArtworkInfo(); /* needed before loading gfx, sound & music */ + InitArtworkConfig(); /* needed before forking sound child process */ + InitMixer(); InitCounter(); - InitMixer(); + InitJoysticks(); InitRND(NEW_RANDOMIZE); @@ -115,8 +96,7 @@ void OpenAll(void) InitEventFilter(FilterMouseMotionEvents); - InitElementProperties(); /* initializes IS_CHAR() for el2gfx() */ - InitElementInfo(); + InitElementProperties(); InitGfx(); @@ -125,22 +105,36 @@ void OpenAll(void) InitImages(); /* needs to know current level directory */ InitSound(); /* needs to know current level directory */ - InitGadgets(); /* needs images + number of level series */ + InitMusic(); /* needs to know current level directory */ InitGfxBackground(); - InitToons(); + + if (global.autoplay_leveldir) + { + AutoPlayTape(); + return; + } DrawMainMenu(); InitNetworkServer(); } -void InitSetup() +static void InitGlobal() +{ + global.autoplay_leveldir = NULL; + + global.frames_per_second = 0; + global.fps_slowdown = FALSE; + global.fps_slowdown_factor = 1; +} + +static void InitSetup() { LoadSetup(); /* global setup info */ } -void InitPlayerInfo() +static void InitPlayerInfo() { int i; @@ -153,18 +147,45 @@ void InitPlayerInfo() local_player->connected = TRUE; } -void InitLevelInfo() +static void InitLevelInfo() { LoadLevelInfo(); /* global level info */ LoadLevelSetup_LastSeries(); /* last played series info */ LoadLevelSetup_SeriesInfo(); /* last played level info */ } -void InitArtworkInfo() +static void InitArtworkInfo() { LoadArtworkInfo(); } +static void InitArtworkConfig() +{ + static char *element_prefix[MAX_NUM_ELEMENTS + 1]; + static char *sound_class_prefix[MAX_NUM_ELEMENTS + 1]; + static char *action_suffix[NUM_ACTIONS + 1]; + static char *direction_suffix[NUM_DIRECTIONS + 1]; + static char *special_suffix[NUM_SPECIAL_GFX_ARGS + 1]; + static char *dummy[1] = { NULL }; + int i; + + for (i=0; iidentifier); - InitReloadMusic(artwork.mus_current->identifier); + InitReloadCustomSounds(artwork.snd_current->identifier); + ReinitializeSounds(); +} - InitSoundInfo(); +static void InitMusic() +{ + InitReloadCustomMusic(artwork.mus_current->identifier); + ReinitializeMusic(); } static void InitTileClipmasks() { +#if 0 #if defined(TARGET_X11) XGCValues clip_gc_values; unsigned long clip_gc_valuemask; @@ -367,10 +412,12 @@ static void InitTileClipmasks() #endif /* TARGET_X11_NATIVE */ #endif /* TARGET_X11 */ +#endif } void FreeTileClipmasks() { +#if 0 #if defined(TARGET_X11) int i; @@ -399,18 +446,22 @@ void FreeTileClipmasks() #endif #endif /* TARGET_X11 */ +#endif } void InitGfx() { -#if 0 + char *config_token_font_initial = "font.small"; + char *filename_font_initial = NULL; int i; -#endif - /* initialize some global variables */ - global.frames_per_second = 0; - global.fps_slowdown = FALSE; - global.fps_slowdown_factor = 1; + /* determine filename for initial font (for displaying startup messages) */ + for (i=0; image_config[i].token != NULL; i++) + if (strcmp(image_config[i].token, config_token_font_initial) == 0) + filename_font_initial = image_config[i].value; + + 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, @@ -423,40 +474,15 @@ void InitGfx() bitmap_db_field = CreateBitmap(FXSIZE, FYSIZE, DEFAULT_DEPTH); bitmap_db_door = CreateBitmap(3 * DXSIZE, DYSIZE + VYSIZE, DEFAULT_DEPTH); -#if 0 - pix[PIX_FONT_SMALL] = LoadCustomImage(image_filename[PIX_FONT_SMALL]); - - InitFontInfo(NULL, NULL, pix[PIX_FONT_SMALL], NULL); -#else - bitmap_font_initial = LoadCustomImage(image_filename[PIX_FONT_SMALL]); + bitmap_font_initial = LoadCustomImage(filename_font_initial); InitFontInfo(bitmap_font_initial, NULL, NULL, NULL, NULL); -#endif DrawInitText(WINDOW_TITLE_STRING, 20, FC_YELLOW); DrawInitText(WINDOW_SUBTITLE_STRING, 50, FC_RED); DrawInitText("Loading graphics:", 120, FC_GREEN); -#if 0 - for (i=0; i '%s'\n", artwork.gfx_current_identifier); -#endif - /* 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) @@ -553,44 +575,26 @@ void ReloadCustomArtwork() last_override_level_graphics != setup.override_level_graphics) { #if 0 - printf("CHANGED GFX: '%s' -> '%s'\n", - artwork.gfx_current_identifier, gfx_new_identifier); -#endif - -#if 0 - int i; + printf("RELOADING GRAPHICS '%s' -> '%s' ('%s')\n", + artwork.gfx_current_identifier, + artwork.gfx_current->identifier, + gfx_new_identifier); #endif setLevelArtworkDir(artwork.gfx_first); ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE); -#if 0 - for (i=0; iidentifier; -#endif last_override_level_graphics = setup.override_level_graphics; redraw_screen = TRUE; @@ -599,12 +603,20 @@ void ReloadCustomArtwork() 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 + /* set artwork path to send it to the sound server process */ setLevelArtworkDir(artwork.snd_first); - InitReloadSounds(snd_new_identifier); + InitReloadCustomSounds(snd_new_identifier); + ReinitializeSounds(); - artwork.snd_current_identifier = snd_new_identifier; + artwork.snd_current_identifier = artwork.snd_current->identifier; last_override_level_sounds = setup.override_level_sounds; redraw_screen = TRUE; @@ -616,9 +628,10 @@ void ReloadCustomArtwork() /* set artwork path to send it to the sound server process */ setLevelArtworkDir(artwork.mus_first); - InitReloadMusic(mus_new_identifier); + InitReloadCustomMusic(mus_new_identifier); + ReinitializeMusic(); - artwork.mus_current_identifier = mus_new_identifier; + artwork.mus_current_identifier = artwork.mus_current->identifier; last_override_level_music = setup.override_level_music; redraw_screen = TRUE; @@ -632,92 +645,139 @@ void ReloadCustomArtwork() SetDoorState(DOOR_OPEN_ALL); CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY); } +} -#if 0 - printf("<-- '%s'\n", artwork.gfx_current_identifier); -#endif +void FreeGadgets() +{ + FreeLevelEditorGadgets(); + FreeGameButtons(); + FreeTapeButtons(); + FreeToolButtons(); + FreeScreenGadgets(); } void InitGadgets() { + static boolean gadgets_initialized = FALSE; + + if (gadgets_initialized) + FreeGadgets(); + CreateLevelEditorGadgets(); CreateGameButtons(); CreateTapeButtons(); CreateToolButtons(); CreateScreenGadgets(); + + gadgets_initialized = TRUE; } -void InitElementInfo() +void InitElementSmallImages() { + struct PropertyMapping *property_mapping = getImageListPropertyMapping(); + int num_property_mappings = getImageListPropertyMappingSize(); + int i; + + /* initialize normal images from static configuration */ + for (i=0; element_to_graphic[i].element > -1; i++) + CreateImageWithSmallImages(element_to_graphic[i].graphic); + /* 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++) + CreateImageWithSmallImages(property_mapping[i].artwork_index); +} + +void InitElementGraphicInfo() +{ + struct PropertyMapping *property_mapping = getImageListPropertyMapping(); + int num_property_mappings = getImageListPropertyMappingSize(); int i, act, dir; /* set values to -1 to identify later as "uninitialized" values */ - for (i=0; i -1) + /* 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 direction = element_to_graphic[i].direction; int action = element_to_graphic[i].action; + int direction = element_to_graphic[i].direction; int graphic = element_to_graphic[i].graphic; - if (action > -1) - action = graphics_action_mapping[action]; - else - action = GFX_ACTION_DEFAULT; + if (action < 0) + action = ACTION_DEFAULT; if (direction > -1) - { - direction = MV_DIR_BIT(direction); - element_info[element].direction_graphic[action][direction] = graphic; - } else element_info[element].graphic[action] = graphic; + } + + /* 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; - i++; + if (special != -1) + continue; + + if (action < 0) + action = ACTION_DEFAULT; + + if (direction > -1) + element_info[element].direction_graphic[action][direction] = graphic; + else + element_info[element].graphic[action] = graphic; } /* now set all '-1' values to element specific default values */ - for (i=0; i -1) + /* always start with reliable 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; - gfx_action[graphic] = action; + if (base_redefined && !special_redefined) + continue; - i++; + if (special == GFX_SPECIAL_ARG_EDITOR) + element_info[element].editor_graphic = graphic; + else if (special == GFX_SPECIAL_ARG_PREVIEW) + element_info[element].preview_graphic = graphic; } - for (i=0; iwidth : TILEX) / TILEX; + int num_ytiles = (src_bitmap ? src_bitmap->height * 2 / 3 : TILEY) / TILEY; + int parameter[NUM_GFX_ARGS]; + int i; - /* optionally, the x and y offset of frames can be specified directly */ - if (parameter[GFX_ARG_XOFFSET] != GFX_ARG_UNDEFINED_VALUE) - new_graphic_info[i].offset_x = parameter[GFX_ARG_XOFFSET]; - if (parameter[GFX_ARG_YOFFSET] != GFX_ARG_UNDEFINED_VALUE) - new_graphic_info[i].offset_y = parameter[GFX_ARG_YOFFSET]; - - new_graphic_info[i].anim_frames = parameter[GFX_ARG_FRAMES]; - - new_graphic_info[i].anim_delay = parameter[GFX_ARG_DELAY]; - if (new_graphic_info[i].anim_delay == 0) /* delay must be at least 1 */ - new_graphic_info[i].anim_delay = 1; - - /* set mode for animation frame order */ - if (parameter[GFX_ARG_MODE_LOOP]) - new_graphic_info[i].anim_mode = ANIM_LOOP; - else if (parameter[GFX_ARG_MODE_LINEAR]) - new_graphic_info[i].anim_mode = ANIM_LINEAR; - else if (parameter[GFX_ARG_MODE_PINGPONG]) - new_graphic_info[i].anim_mode = ANIM_PINGPONG; - else if (parameter[GFX_ARG_MODE_PINGPONG2]) - new_graphic_info[i].anim_mode = ANIM_PINGPONG2; - else if (parameter[GFX_ARG_FRAMES] > 1) - new_graphic_info[i].anim_mode = ANIM_LOOP; + /* get integer values from string parameters */ + for (i=0; i < NUM_GFX_ARGS; i++) + parameter[i] = + get_parameter_value(image_config_suffix[i].type, parameter_raw[i]); + + graphic_info[graphic].bitmap = src_bitmap; + + /* 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 */ + { + if (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].offset_x = parameter[GFX_ARG_OFFSET]; else - new_graphic_info[i].anim_mode = ANIM_NONE; + graphic_info[graphic].offset_x = graphic_info[graphic].width; + } - /* set additional flag to play animation frames in reverse order */ - if (parameter[GFX_ARG_MODE_REVERSE]) - new_graphic_info[i].anim_mode |= ANIM_REVERSE; + /* 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; + + /* set mode for animation frame order */ + if (parameter[GFX_ARG_MODE_LOOP]) + graphic_info[graphic].anim_mode = ANIM_LOOP; + else if (parameter[GFX_ARG_MODE_LINEAR]) + graphic_info[graphic].anim_mode = ANIM_LINEAR; + else if (parameter[GFX_ARG_MODE_PINGPONG]) + graphic_info[graphic].anim_mode = ANIM_PINGPONG; + else if (parameter[GFX_ARG_MODE_PINGPONG2]) + graphic_info[graphic].anim_mode = ANIM_PINGPONG2; + else if (parameter[GFX_ARG_MODE_RANDOM]) + graphic_info[graphic].anim_mode = ANIM_RANDOM; + else if (graphic_info[graphic].anim_frames > 1) + graphic_info[graphic].anim_mode = ANIM_LOOP; + else + graphic_info[graphic].anim_mode = ANIM_NONE; + + /* set additional flag to play animation frames in reverse order */ + if (parameter[GFX_ARG_MODE_REVERSE]) + graphic_info[graphic].anim_mode |= ANIM_REVERSE; + + /* 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]; +} - /* set first frame of animation after determining animation mode */ - new_graphic_info[i].anim_start_frame = parameter[GFX_ARG_START_FRAME]; +static void InitGraphicInfo() +{ + static boolean clipmasks_initialized = FALSE; + 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) + 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); - /* automatically determine correct start frame, if not defined */ - if (parameter[GFX_ARG_START_FRAME] == GFX_ARG_UNDEFINED_VALUE) - new_graphic_info[i].anim_start_frame = 0; - else if (new_graphic_info[i].anim_mode & ANIM_REVERSE) - new_graphic_info[i].anim_start_frame = - new_graphic_info[i].anim_frames - parameter[GFX_ARG_START_FRAME] - 1; + graphic_info = checked_calloc(num_images * sizeof(struct GraphicInfo)); + +#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) + if (clipmasks_initialized) + { + 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_EXIT, "InitGraphicInfo: first frame of graphic animation object %d outside of image bitmap file '%s'", i, src_bitmap->source_filename); + { + 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"); + + 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; + } - last_frame = new_graphic_info[i].anim_frames - 1; + 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_EXIT, "InitGraphicInfo: last frame of graphic animation object %d outside of image bitmap file '%s'", i, src_bitmap->source_filename); + { + 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); +#endif + + clipmasks_initialized = TRUE; +} + +static void set_sound_parameters(int sound, char **parameter_raw) +{ + int parameter[NUM_SND_ARGS]; + int i; + + /* get integer values from string parameters */ + for (i=0; i < NUM_SND_ARGS; i++) + parameter[i] = + get_parameter_value(sound_config_suffix[i].type, parameter_raw[i]); + + /* explicit loop mode setting in configuration overrides default value */ + if (parameter[SND_ARG_MODE_LOOP] != ARG_UNDEFINED_VALUE) + sound_info[sound].loop = parameter[SND_ARG_MODE_LOOP]; } static void InitSoundInfo() { - sound_files = getCurrentSoundList(); + int *sound_effect_properties; + int num_sounds = getSoundListSize(); + int i, j; + + if (sound_info != NULL) + free(sound_info); + + sound_effect_properties = checked_calloc(num_sounds * sizeof(int)); + sound_info = checked_calloc(num_sounds * sizeof(struct SoundInfo)); + + /* initialize sound effect for all elements to "no sound" */ + 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].sound_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); - /* initialize sound effect lookup table for element actions */ - InitGameSound(); +#if 0 + /* TEST ONLY */ + { + int element = EL_SAND; + int sound_action = ACTION_DIGGING; + int j = 0; + + 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 } void InitElementProperties() @@ -1749,6 +2105,7 @@ void InitElementProperties() EL_SAND, EL_SP_BASE, EL_SP_BUGGY_BASE, + EL_SP_BUGGY_BASE_ACTIVATING, EL_TRAP, EL_INVISIBLE_SAND, EL_INVISIBLE_SAND_ACTIVE @@ -2061,26 +2418,26 @@ void InitElementProperties() static int num_properties1 = SIZEOF_ARRAY(ep1_num, int *); static int num_properties2 = SIZEOF_ARRAY(ep2_num, int *); - for (i=0; i