X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Finit.c;h=08069f4afa83dd1d9c217157411b20b15ba3c19d;hb=5a5342a6ab48037839b783adc4f3304331834a8c;hp=dbe878cd7063942f299061ba83186f00eb3b10d5;hpb=c4e1a476135ce36417cdd797481feeaaff4301af;p=rocksndiamonds.git diff --git a/src/init.c b/src/init.c index dbe878cd..b24944ee 100644 --- a/src/init.c +++ b/src/init.c @@ -1,7 +1,7 @@ /*********************************************************** * Rocks'n'Diamonds -- McDuffin Strikes Back! * *----------------------------------------------------------* -* (c) 1995-2000 Artsoft Entertainment * +* (c) 1995-2002 Artsoft Entertainment * * Holger Schemel * * Detmolder Strasse 189 * * 33604 Bielefeld * @@ -11,8 +11,6 @@ * init.c * ***********************************************************/ -#include - #include "libgame/libgame.h" #include "init.h" @@ -23,22 +21,51 @@ #include "tape.h" #include "tools.h" #include "files.h" -#include "joystick.h" #include "network.h" #include "netserv.h" - -static void InitPlayerInfo(void); -static void InitLevelInfo(void); -static void InitNetworkServer(void); -static void InitSound(void); -static void InitSoundServer(void); -static void InitGfx(void); -static void InitGfxBackground(void); -static void InitGadgets(void); -static void InitElementProperties(void); - -void OpenAll(void) +#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_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() { + InitGlobal(); /* initialize some global variables */ + + if (options.execute_command) + Execute_Command(options.execute_command); + if (options.serveronly) { #if defined(PLATFORM_UNIX) @@ -50,15 +77,19 @@ void OpenAll(void) } InitProgramInfo(UNIX_USERDATA_DIRECTORY, - PROGRAM_TITLE_STRING, WINDOW_TITLE_STRING, + PROGRAM_TITLE_STRING, getWindowTitleString(), ICON_TITLE_STRING, X11_ICON_FILENAME, X11_ICONMASK_FILENAME, - MSDOS_POINTER_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(); - InitSound(); - InitSoundServer(); + InitJoysticks(); InitRND(NEW_RANDOMIZE); @@ -68,19 +99,47 @@ void OpenAll(void) InitEventFilter(FilterMouseMotionEvents); + InitElementProperties(); + InitGfx(); - InitElementProperties(); /* initializes IS_CHAR() for el2gfx() */ InitLevelInfo(); - InitGadgets(); /* needs to know number of level series */ + 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) + { + AutoPlayTape(); + return; + } + + game_status = MAINMENU; + DrawMainMenu(); InitNetworkServer(); } -void InitPlayerInfo() +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 */ +} + +static void InitPlayerInfo() { int i; @@ -88,23 +147,77 @@ void InitPlayerInfo() local_player = &stored_player[0]; for (i=0; iconnected = TRUE; - - LoadSetup(); /* global setup info */ } -void InitLevelInfo() +static void InitLevelInfo() { LoadLevelInfo(); /* global level info */ LoadLevelSetup_LastSeries(); /* last played series info */ LoadLevelSetup_SeriesInfo(); /* last played level info */ } +static void InitArtworkInfo() +{ + LoadArtworkInfo(); +} + +static void InitArtworkConfig() +{ + static char *image_id_prefix[MAX_NUM_ELEMENTS + NUM_FONTS + 1]; + static char *sound_id_prefix[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", + "menu.main.hide_static_text", + "global.num_toons", + NULL + }; + static char *ignore_sound_tokens[] = + { + "name", + "sort_priority", + NULL + }; + int i; + + for (i=0; iidentifier); + ReinitializeSounds(); +} + +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; + +#if defined(TARGET_X11_NATIVE) + +#if 0 + GC copy_clipmask_gc; + + static struct + { + 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 + +#endif /* TARGET_X11_NATIVE */ +#endif /* TARGET_X11 */ + int i; - OpenAudio(); + /* initialize pixmap array for special X11 tile clipping to Pixmap 'None' */ + for (i=0; idrawable, + clip_gc_valuemask, &clip_gc_values); + +#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 defined(TARGET_X11_NATIVE) + +#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); + + /* create only those clipping Pixmaps we really need */ + for (i=0; tile_needs_clipping[i].start>=0; i++) + { + int j; + + for (j=0; jclip_mask; + + tile_clipmask[tile] = XCreatePixmap(display, window->drawable, + TILEX, TILEY, 1); + + XCopyArea(display, src_pixmap, tile_clipmask[tile], copy_clipmask_gc, + src_x, src_y, TILEX, TILEY, 0, 0); + } + } + + XFreeGC(display, copy_clipmask_gc); +#endif + +#endif /* TARGET_X11_NATIVE */ +#endif /* TARGET_X11 */ +#endif +} + +void FreeTileClipmasks() +{ +#if 0 +#if defined(TARGET_X11) + int i; + + for (i=0; istored_clip_gc) { - audio.sound_available = FALSE; - audio.loops_available = FALSE; - audio.sound_enabled = FALSE; + XFreeGC(display, pix[i]->stored_clip_gc); + pix[i]->stored_clip_gc = None; + } + } +#endif + +#endif /* TARGET_X11 */ +#endif +} - return; +void InitGfx() +{ + char *filename_font_initial = NULL; + Bitmap *bitmap_font_initial = NULL; + int i, j; + + /* determine settings for initial font (for displaying startup messages) */ + for (i=0; image_config[i].token != NULL; i++) + { + for (j=0; j < NUM_INITIAL_FONTS; j++) + { + char font_token[128]; + int len_font_token; + + sprintf(font_token, "%s_%d", CONFIG_TOKEN_FONT_INITIAL, j + 1); + len_font_token = strlen(font_token); + + 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); + } } } - num_bg_loops = LoadMusic(); + 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); + + /* 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); + + 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(); +} + +void InitGfxBackground() +{ + 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); + + for (x=0; xidentifier; + 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; -#if !defined(TARGET_SDL) -#if defined(PLATFORM_UNIX) + /* 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) + { + 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; + } + + /* 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) + { +#if 0 + 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); + + InitImages(); + + FreeTileClipmasks(); + InitTileClipmasks(); + + artwork.gfx_current_identifier = artwork.gfx_current->identifier; + last_override_level_graphics = setup.override_level_graphics; + + redraw_screen = TRUE; + } + + 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); + + InitReloadCustomSounds(snd_new_identifier); + ReinitializeSounds(); + + artwork.snd_current_identifier = artwork.snd_current->identifier; + last_override_level_sounds = setup.override_level_sounds; + + redraw_screen = TRUE; + } + + 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); + + InitReloadCustomMusic(mus_new_identifier); + ReinitializeMusic(); + + artwork.mus_current_identifier = artwork.mus_current->identifier; + last_override_level_music = setup.override_level_music; + + redraw_screen = TRUE; + } + + if (redraw_screen) + { + InitGfxBackground(); + + /* force redraw of (open or closed) door graphics */ + SetDoorState(DOOR_OPEN_ALL); + CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY); + } +} + +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 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++) + if (property_mapping[i].artwork_index < MAX_NUM_ELEMENTS) + CreateImageWithSmallImages(property_mapping[i].artwork_index); +} + +static int getFontBitmapID(int font_nr) +{ + int special = -1; + + 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 (special != -1) + return font_info[font_nr].special_bitmap_id[special]; + else + return font_nr; +} + +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; + + if (graphic_info == NULL) /* still at startup phase */ + { + InitFontInfo(font_initial, NUM_INITIAL_FONTS, getFontBitmapID); + + return; + } + + /* ---------- initialize font graphic definitions ---------- */ + + /* always start with reliable default values (normal font graphics) */ + for (i=0; i < NUM_FONTS; i++) + font_info[i].graphic = FONT_INITIAL_1; + + /* 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; + + if (special != -1) + continue; + + font_info[font_nr].graphic = graphic; + } + + /* 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; + } + } + + /* 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 (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++; + } + } + + /* 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; + + if (font_nr < 0) + 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++; + } + } + + /* ---------- initialize font bitmap array ---------- */ + + if (font_bitmap_info != NULL) + free(font_bitmap_info); + + font_bitmap_info = + checked_calloc(num_font_bitmaps * sizeof(struct FontBitmapInfo)); + + /* ---------- initialize font bitmap definitions ---------- */ + + for (i=0; i < NUM_FONTS; i++) + { + if (i < NUM_INITIAL_FONTS) + { + font_bitmap_info[i] = font_initial[i]; + continue; + } + + 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]; + + /* 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; + } + } + + InitFontInfo(font_bitmap_info, num_font_bitmaps, getFontBitmapID); +} + +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; 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; + + if (action < 0) + action = ACTION_DEFAULT; + + if (direction > -1) + 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; + + if (element >= MAX_NUM_ELEMENTS || 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; i++) { - Error(ERR_WARN, "cannot create pipe - no sounds"); - audio.sound_available = FALSE; - return; - } + 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; - if ((audio.soundserver_pid = fork()) < 0) - { - Error(ERR_WARN, "cannot create sound server process - no sounds"); - audio.sound_available = FALSE; - return; + if (base_redefined && !special_redefined) + continue; + + element_info[element].special_graphic[special] = graphic; } - if (audio.soundserver_pid == 0) /* we are child */ + /* initialize special element/graphic mapping from dynamic configuration */ + for (i=0; i < num_property_mappings; i++) { - SoundServer(); + int element = property_mapping[i].base_index; + int special = property_mapping[i].ext3_index; + int graphic = property_mapping[i].artwork_index; - /* never reached */ - exit(0); + if (element >= MAX_NUM_ELEMENTS) + continue; + + if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS) + element_info[element].special_graphic[special] = graphic; } - else /* we are parent */ - close(audio.soundserver_pipe[0]); /* no reading from pipe needed */ +} -#else /* !PLATFORM_UNIX */ +static void set_graphic_parameters(int graphic, char **parameter_raw) +{ + 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; - SoundServer(); + /* 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); + + 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 + graphic_info[graphic].offset_x = graphic_info[graphic].width; + } -#endif /* !PLATFORM_UNIX */ -#endif /* !TARGET_SDL */ + /* 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]; } -void InitJoysticks() +static void InitGraphicInfo() { -#if defined(TARGET_SDL) - static boolean sdl_joystick_subsystem_initialized = FALSE; -#endif - + 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 (global_joystick_status == JOYSTICK_OFF) - return; +#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 - joystick_status = JOYSTICK_OFF; + if (graphic_info != NULL) + free(graphic_info); -#if defined(TARGET_SDL) + graphic_info = checked_calloc(num_images * sizeof(struct GraphicInfo)); - if (!sdl_joystick_subsystem_initialized) +#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) + if (clipmasks_initialized) { - sdl_joystick_subsystem_initialized = TRUE; - - if (SDL_Init(SDL_INIT_JOYSTICK) < 0) + for (i=0; i= SDL_NumJoysticks()) - joystick_nr = -1; + struct FileInfo *image = getImageListEntry(i); + Bitmap *src_bitmap; + int src_x, src_y; + int first_frame, last_frame; - /* misuse joystick file descriptor variable to store joystick number */ - stored_player[i].joystick_fd = joystick_nr; + set_graphic_parameters(i, image->parameter); - /* this allows subsequent calls to 'InitJoysticks' for re-initialization */ - if (Check_SDL_JoystickOpened(joystick_nr)) - Close_SDL_Joystick(joystick_nr); + /* now check if no animation frames are outside of the loaded image */ - if (!setup.input[i].use_joystick) - continue; + if (graphic_info[i].bitmap == NULL) + continue; /* skip check for optional images that are undefined */ - if (!Open_SDL_Joystick(joystick_nr)) + 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_WARN, "cannot open joystick %d", joystick_nr); - continue; + 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; } - joystick_status = JOYSTICK_AVAILABLE; - } - -#else /* !TARGET_SDL */ - -#if defined(PLATFORM_UNIX) - for (i=0; i src_bitmap->width || + src_y + TILEY > src_bitmap->height) { - close(stored_player[i].joystick_fd); - stored_player[i].joystick_fd = -1; + 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 (!setup.input[i].use_joystick) - continue; - - if (access(device_name, R_OK) != 0) - { - Error(ERR_WARN, "cannot access joystick device '%s'", device_name); - continue; - } +#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 ((stored_player[i].joystick_fd = open(device_name, O_RDONLY)) < 0) + if (copy_clipmask_gc == None) { - Error(ERR_WARN, "cannot open joystick device '%s'", device_name); - continue; + 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); } - joystick_status = JOYSTICK_AVAILABLE; - } - -#else /* !PLATFORM_UNIX */ + graphic_info[i].clip_mask = + XCreatePixmap(display, window->drawable, TILEX, TILEY, 1); - /* try to access two joysticks; if that fails, try to access just one */ - if (install_joystick(JOY_TYPE_2PADS) == 0 || - install_joystick(JOY_TYPE_AUTODETECT) == 0) - joystick_status = JOYSTICK_AVAILABLE; + 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); - /* - load_joystick_data(JOYSTICK_FILENAME); - */ + clip_gc_values.graphics_exposures = False; + clip_gc_values.clip_mask = graphic_info[i].clip_mask; + clip_gc_valuemask = GCGraphicsExposures | GCClipMask; - for (i=0; idrawable, clip_gc_valuemask, &clip_gc_values); +#endif + } - if (joystick_nr >= num_joysticks) - joystick_nr = -1; +#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) + if (copy_clipmask_gc) + XFreeGC(display, copy_clipmask_gc); - /* misuse joystick file descriptor variable to store joystick number */ - stored_player[i].joystick_fd = joystick_nr; - } + clipmasks_initialized = TRUE; #endif +} -#endif /* !TARGET_SDL */ +static void InitElementSoundInfo() +{ + /* !!! soon to come !!! */ } -void InitGfx() +static void set_sound_parameters(int sound, char **parameter_raw) { + int parameter[NUM_SND_ARGS]; int i; -#if defined(TARGET_X11) - GC copy_clipmask_gc; - XGCValues clip_gc_values; - unsigned long clip_gc_valuemask; -#endif + /* get integer values from string parameters */ + for (i=0; i < NUM_SND_ARGS; i++) + parameter[i] = + get_parameter_value(sound_config_suffix[i].token, parameter_raw[i], + sound_config_suffix[i].type); -#if !defined(PLATFORM_MSDOS) - static char *image_filename[NUM_PICTURES] = - { - "RocksScreen.pcx", - "RocksDoor.pcx", - "RocksHeroes.pcx", - "RocksToons.pcx", - "RocksSP.pcx", - "RocksDC.pcx", - "RocksMore.pcx", - "RocksFont.pcx", - "RocksFont2.pcx", - "RocksFont3.pcx" - }; -#else - static char *image_filename[NUM_PICTURES] = - { - "Screen.pcx", - "Door.pcx", - "Heroes.pcx", - "Toons.pcx", - "SP.pcx", - "DC.pcx", - "More.pcx", - "Font.pcx", - "Font2.pcx", - "Font3.pcx" - }; -#endif + /* 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]; +} -#ifdef TARGET_X11 - static struct - { - 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 +static void InitSoundInfo() +{ + struct PropertyMapping *property_mapping = getSoundListPropertyMapping(); + int num_property_mappings = getSoundListPropertyMappingSize(); + int *sound_effect_properties; + int num_sounds = getSoundListSize(); + int i, j; - /* initialize some global variables */ - global.frames_per_second = 0; - global.fps_slowdown = FALSE; - global.fps_slowdown_factor = 1; + if (sound_info != NULL) + free(sound_info); - /* 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); + sound_effect_properties = checked_calloc(num_sounds * sizeof(int)); + sound_info = checked_calloc(num_sounds * sizeof(struct SoundInfo)); - /* create additional image buffers for double-buffering */ - pix[PIX_DB_DOOR] = CreateBitmap(3 * DXSIZE, DYSIZE + VYSIZE, DEFAULT_DEPTH); - pix[PIX_DB_FIELD] = CreateBitmap(FXSIZE, FYSIZE, DEFAULT_DEPTH); + /* initialize sound effect for all elements to "no sound" */ + for (i=0; itoken); - DrawInitText(WINDOW_TITLE_STRING, 20, FC_YELLOW); - DrawInitText(WINDOW_SUBTITLE_STRING, 50, FC_RED); -#if defined(PLATFORM_MSDOS) - DrawInitText(PROGRAM_DOS_PORT_STRING, 210, FC_BLUE); - rest(200); -#endif - DrawInitText("Loading graphics:",120,FC_GREEN); + sound_effect_properties[i] = ACTION_OTHER; + sound_info[i].loop = FALSE; - for(i=0; itoken[len_effect_text - len_action_text], + element_action_info[j].suffix) == 0) + { + sound_effect_properties[i] = element_action_info[j].value; -#if defined(TARGET_X11) - /* 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 (element_action_info[j].is_loop_sound) + sound_info[i].loop = TRUE; + } + } - clip_gc_values.graphics_exposures = False; - clip_gc_valuemask = GCGraphicsExposures; - tile_clip_gc = - XCreateGC(display, window->drawable, clip_gc_valuemask, &clip_gc_values); + /* associate elements and some selected sound actions */ - for(i=0; iclip_mask) + for (j=0; jclip_mask; - clip_gc_valuemask = GCGraphicsExposures | GCClipMask; - pix[i]->stored_clip_gc = XCreateGC(display, window->drawable, - clip_gc_valuemask,&clip_gc_values); + if (element_info[j].sound_class_name) + { + int len_class_text = strlen(element_info[j].sound_class_name); + + if (len_class_text + 1 < len_effect_text && + strncmp(sound->token, + 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); } - /* initialize pixmap array to Pixmap 'None' */ - for(i=0; i=0; i++) + /* initialize element/sound mapping from dynamic configuration */ + for (i=0; i < num_property_mappings; i++) { - int j; + int element = property_mapping[i].base_index; + int action = property_mapping[i].ext1_index; + int sound = property_mapping[i].artwork_index; - for(j=0; jclip_mask; + element_info[element].sound[action] = sound; + } - tile_clipmask[tile] = XCreatePixmap(display, window->drawable, - TILEX, TILEY, 1); +#if 0 + /* TEST ONLY */ + { + int element = EL_CUSTOM_11; + int j = 0; - XCopyArea(display, src_pixmap, tile_clipmask[tile], copy_clipmask_gc, - src_x, src_y, TILEX, TILEY, 0, 0); + 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++; } } -#endif /* TARGET_X11 */ -} - -void InitGfxBackground() -{ - int x, y; - drawto = backbuffer; - fieldbuffer = pix[PIX_DB_FIELD]; - SetDrawtoField(DRAW_BACKBUFFER); - - BlitBitmap(pix[PIX_BACK], backbuffer, 0,0, WIN_XSIZE,WIN_YSIZE, 0,0); - ClearRectangle(backbuffer, REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE); - ClearRectangle(pix[PIX_DB_DOOR], 0,0, 3*DXSIZE,DYSIZE+VYSIZE); + PlaySoundLevelElementAction(0,0, EL_CUSTOM_11, ACTION_PUSHING); +#endif - for(x=0; x