+void InitElementInfo()
+{
+
+ int i, act, dir;
+
+ /* set values to -1 to identify later as "uninitialized" values */
+ for (i=0; i<MAX_ELEMENTS; i++)
+ {
+ for (act=0; act<NUM_GFX_ACTIONS_MAPPED; act++)
+ {
+ element_info[i].graphic[act] = -1;
+
+ for (dir=0; dir<NUM_MV_DIRECTIONS; dir++)
+ element_info[i].direction_graphic[act][dir] = -1;
+ }
+ }
+
+ for (i=EL_CHAR_START; i<=EL_CHAR_END; i++)
+ element_info[i].graphic[GFX_ACTION_DEFAULT] =
+ IMG_CHAR_START + (i - EL_CHAR_START);
+
+ for (i=EL_GENERIC_START; i<=EL_GENERIC_END; i++)
+ element_info[i].graphic[GFX_ACTION_DEFAULT] =
+ IMG_GENERIC_START + (i - EL_GENERIC_START);
+
+ i = 0;
+ while (element_to_graphic[i].element > -1)
+ {
+ int element = element_to_graphic[i].element;
+ int direction = element_to_graphic[i].direction;
+ int action = element_to_graphic[i].action;
+ int graphic = element_to_graphic[i].graphic;
+
+ if (action > -1)
+ action = graphics_action_mapping[action];
+ else
+ action = GFX_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;
+
+ i++;
+ }
+
+ /* now set all '-1' values to element specific default values */
+ for (i=0; i<MAX_ELEMENTS; i++)
+ {
+ int default_action_graphic = element_info[i].graphic[GFX_ACTION_DEFAULT];
+ int default_action_direction_graphic[NUM_MV_DIRECTIONS];
+
+ if (default_action_graphic == -1)
+ default_action_graphic = IMG_CHAR_QUESTION;
+
+ for (dir=0; dir<NUM_MV_DIRECTIONS; dir++)
+ {
+ default_action_direction_graphic[dir] =
+ element_info[i].direction_graphic[GFX_ACTION_DEFAULT][dir];
+
+ if (default_action_direction_graphic[dir] == -1)
+ default_action_direction_graphic[dir] = default_action_graphic;
+ }
+
+ for (act=0; act<NUM_GFX_ACTIONS_MAPPED; act++)
+ {
+ for (dir=0; dir<NUM_MV_DIRECTIONS; dir++)
+ {
+ int default_direction_graphic = element_info[i].graphic[act];
+
+ /* no graphic for current action -- use default direction graphic */
+ if (default_direction_graphic == -1)
+ default_direction_graphic = default_action_direction_graphic[dir];
+
+ if (element_info[i].direction_graphic[act][dir] == -1)
+ element_info[i].direction_graphic[act][dir] =
+ default_direction_graphic;
+ }
+
+ /* no graphic for this specific action -- use default action graphic */
+ if (element_info[i].graphic[act] == -1)
+ element_info[i].graphic[act] = default_action_graphic;
+ }
+ }
+}
+
+static void InitGraphicInfo()
+{
+ static int gfx_action[NUM_IMAGE_FILES];
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int first_frame, last_frame;
+ int i;
+
+ image_files = getCurrentImageList();
+
+ /* set temporary graphics action field to default value */
+ for (i=0; i<NUM_IMAGE_FILES; i++)
+ gfx_action[i] = GFX_ACTION_DEFAULT;
+
+ /* set temporary graphics action field from element_to_graphic list */
+ i = 0;
+ while (element_to_graphic[i].element > -1)
+ {
+ int action = element_to_graphic[i].action;
+ int graphic = element_to_graphic[i].graphic;
+
+ if (action == -1)
+ action = GFX_ACTION_DEFAULT;
+
+ gfx_action[graphic] = action;
+
+ i++;
+ }
+
+ for (i=0; i<NUM_IMAGE_FILES; i++)
+ {
+ int *parameter = image_files[i].parameter;
+
+ new_graphic_info[i].bitmap = getBitmapFromImageID(i);
+
+ new_graphic_info[i].src_x = parameter[GFX_ARG_XPOS] * TILEX;
+ new_graphic_info[i].src_y = parameter[GFX_ARG_YPOS] * TILEY;
+ new_graphic_info[i].offset_x = parameter[GFX_ARG_OFFSET];
+ new_graphic_info[i].offset_y = 0;
+
+ /* animation frames are ordered vertically instead of horizontally */
+ if (parameter[GFX_ARG_VERTICAL])
+ {
+ new_graphic_info[i].offset_x = 0;
+ new_graphic_info[i].offset_y = parameter[GFX_ARG_OFFSET];
+ }
+
+ /* 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;
+ else
+ new_graphic_info[i].anim_mode = ANIM_NONE;
+
+ /* set additional flag to play animation frames in reverse order */
+ if (parameter[GFX_ARG_MODE_REVERSE])
+ new_graphic_info[i].anim_mode |= ANIM_REVERSE;
+
+ /* set first frame of animation after determining animation mode */
+ new_graphic_info[i].anim_start_frame = parameter[GFX_ARG_START_FRAME];
+
+ /* 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;
+
+ /* animation synchronized with global frame counter, not move position */
+ new_graphic_info[i].anim_global_sync = parameter[GFX_ARG_GLOBAL_SYNC];
+
+ /* set global_sync for all animations with undefined "animation action" */
+ if (parameter[GFX_ARG_GLOBAL_SYNC] == GFX_ARG_UNDEFINED_VALUE)
+ new_graphic_info[i].anim_global_sync =
+ (gfx_action[i] == GFX_ACTION_DEFAULT ? TRUE : FALSE);
+
+ /* "linear" animations are never globally synchronized */
+ if (parameter[GFX_ARG_MODE_LINEAR])
+ new_graphic_info[i].anim_global_sync = FALSE;
+
+ /* now check if no animation frames are outside of the loaded image */
+
+ 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);
+
+ last_frame = new_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);
+ }
+}
+
+static void InitSoundInfo()
+{
+ sound_files = getCurrentSoundList();
+
+ /* initialize sound effect lookup table for element actions */
+ InitGameSound();
+}
+