From: Holger Schemel Date: Tue, 11 Mar 2003 23:32:19 +0000 (+0100) Subject: rnd-20030312-1-src X-Git-Tag: 3.0.0^2~124 X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=commitdiff_plain;h=3fb68b18f28034e492534fb3b5579fd1da888292 rnd-20030312-1-src --- diff --git a/src/conf_e2s.c b/src/conf_e2s.c index f5caea86..0fef9ca3 100644 --- a/src/conf_e2s.c +++ b/src/conf_e2s.c @@ -356,6 +356,10 @@ element_to_sound[] = EL_EXIT_CLOSED, TRUE, ACTION_PASSING, SND_CLASS_EXIT_PASSING }, + { + EL_PENGUIN, FALSE, ACTION_PASSING, + SND_PENGUIN_PASSING + }, { EL_BALLOON, FALSE, ACTION_MOVING, SND_BALLOON_MOVING diff --git a/src/conf_snd.c b/src/conf_snd.c index 23f2e506..dc002cc7 100644 --- a/src/conf_snd.c +++ b/src/conf_snd.c @@ -113,6 +113,7 @@ struct ConfigInfo sound_config[] = { "[quicksand].emptying", UNDEFINED_FILENAME }, { "[exit].opening", "oeffnen.wav" }, { "[exit].passing", "buing.wav" }, + { "penguin.passing", "buing.wav" }, /* sounds for Emerald Mine Club style elements and actions */ { "balloon.moving", UNDEFINED_FILENAME }, diff --git a/src/conf_snd.h b/src/conf_snd.h index 5e820d48..f869225d 100644 --- a/src/conf_snd.h +++ b/src/conf_snd.h @@ -95,97 +95,98 @@ #define SND_CLASS_QUICKSAND_EMPTYING 74 #define SND_CLASS_EXIT_OPENING 75 #define SND_CLASS_EXIT_PASSING 76 -#define SND_BALLOON_MOVING 77 -#define SND_BALLOON_WAITING 78 -#define SND_BALLOON_PUSHING 79 -#define SND_CLASS_BALLOON_SWITCH_ACTIVATING 80 -#define SND_SPRING_MOVING 81 -#define SND_SPRING_PUSHING 82 -#define SND_SPRING_IMPACT 83 -#define SND_CLASS_WALL_GROWING 84 -#define SND_PEARL_COLLECTING 85 -#define SND_PEARL_BREAKING 86 -#define SND_PEARL_IMPACT 87 -#define SND_CRYSTAL_COLLECTING 88 -#define SND_CRYSTAL_IMPACT 89 -#define SND_ENVELOPE_COLLECTING 90 -#define SND_INVISIBLE_SAND_DIGGING 91 -#define SND_SHIELD_NORMAL_COLLECTING 92 -#define SND_SHIELD_NORMAL_ACTIVE 93 -#define SND_SHIELD_DEADLY_COLLECTING 94 -#define SND_SHIELD_DEADLY_ACTIVE 95 -#define SND_EXTRA_TIME_COLLECTING 96 -#define SND_MOLE_MOVING 97 -#define SND_MOLE_WAITING 98 -#define SND_MOLE_DIGGING 99 -#define SND_CLASS_SWITCHGATE_SWITCH_ACTIVATING 100 -#define SND_CLASS_SWITCHGATE_OPENING 101 -#define SND_CLASS_SWITCHGATE_CLOSING 102 -#define SND_CLASS_SWITCHGATE_PASSING 103 -#define SND_TIMEGATE_SWITCH_ACTIVATING 104 -#define SND_TIMEGATE_SWITCH_ACTIVE 105 -#define SND_TIMEGATE_SWITCH_DEACTIVATING 106 -#define SND_TIMEGATE_OPENING 107 -#define SND_CLASS_TIMEGATE_CLOSING 108 -#define SND_CLASS_TIMEGATE_PASSING 109 -#define SND_CLASS_CONVEYOR_BELT_SWITCH_ACTIVATING 110 -#define SND_CLASS_CONVEYOR_BELT_ACTIVE 111 -#define SND_CLASS_CONVEYOR_BELT_SWITCH_DEACTIVATING 112 -#define SND_LIGHT_SWITCH_ACTIVATING 113 -#define SND_LIGHT_SWITCH_DEACTIVATING 114 -#define SND_DX_SUPABOMB_PUSHING 115 -#define SND_TRAP_DIGGING 116 -#define SND_TRAP_ACTIVATING 117 -#define SND_CLASS_TUBE_PASSING 118 -#define SND_AMOEBA_TURNING_TO_GEM 119 -#define SND_AMOEBA_TURNING_TO_ROCK 120 -#define SND_SPEED_PILL_COLLECTING 121 -#define SND_DYNABOMB_INCREASE_NUMBER_COLLECTING 122 -#define SND_DYNABOMB_INCREASE_SIZE_COLLECTING 123 -#define SND_DYNABOMB_INCREASE_POWER_COLLECTING 124 -#define SND_CLASS_DYNABOMB_DROPPING 125 -#define SND_CLASS_DYNABOMB_ACTIVE 126 -#define SND_SATELLITE_MOVING 127 -#define SND_SATELLITE_WAITING 128 -#define SND_SATELLITE_PUSHING 129 -#define SND_LAMP_ACTIVATING 130 -#define SND_LAMP_DEACTIVATING 131 -#define SND_TIME_ORB_FULL_COLLECTING 132 -#define SND_TIME_ORB_FULL_IMPACT 133 -#define SND_TIME_ORB_EMPTY_PUSHING 134 -#define SND_TIME_ORB_EMPTY_IMPACT 135 -#define SND_GAME_OF_LIFE_WAITING 136 -#define SND_GAME_OF_LIFE_GROWING 137 -#define SND_BIOMAZE_WAITING 138 -#define SND_BIOMAZE_GROWING 139 -#define SND_PACMAN_MOVING 140 -#define SND_PACMAN_WAITING 141 -#define SND_PACMAN_DIGGING 142 -#define SND_DARK_YAMYAM_MOVING 143 -#define SND_DARK_YAMYAM_WAITING 144 -#define SND_DARK_YAMYAM_DIGGING 145 -#define SND_PENGUIN_MOVING 146 -#define SND_PENGUIN_WAITING 147 -#define SND_PIG_MOVING 148 -#define SND_PIG_WAITING 149 -#define SND_PIG_DIGGING 150 -#define SND_DRAGON_MOVING 151 -#define SND_DRAGON_WAITING 152 -#define SND_DRAGON_ATTACKING 153 -#define SND_CLASS_PLAYER_DYING 154 -#define SND_ELEMENT_EXPLODING 155 -#define SND_SP_ELEMENT_EXPLODING 156 -#define SND_GAME_STARTING 157 -#define SND_GAME_RUNNING_OUT_OF_TIME 158 -#define SND_GAME_LEVELTIME_BONUS 159 -#define SND_GAME_LOSING 160 -#define SND_GAME_WINNING 161 -#define SND_GAME_SOKOBAN_SOLVING 162 -#define SND_MENU_DOOR_OPENING 163 -#define SND_MENU_DOOR_CLOSING 164 -#define SND_MENU_HALL_OF_FAME 165 -#define SND_MENU_INFO_SCREEN 166 +#define SND_PENGUIN_PASSING 77 +#define SND_BALLOON_MOVING 78 +#define SND_BALLOON_WAITING 79 +#define SND_BALLOON_PUSHING 80 +#define SND_CLASS_BALLOON_SWITCH_ACTIVATING 81 +#define SND_SPRING_MOVING 82 +#define SND_SPRING_PUSHING 83 +#define SND_SPRING_IMPACT 84 +#define SND_CLASS_WALL_GROWING 85 +#define SND_PEARL_COLLECTING 86 +#define SND_PEARL_BREAKING 87 +#define SND_PEARL_IMPACT 88 +#define SND_CRYSTAL_COLLECTING 89 +#define SND_CRYSTAL_IMPACT 90 +#define SND_ENVELOPE_COLLECTING 91 +#define SND_INVISIBLE_SAND_DIGGING 92 +#define SND_SHIELD_NORMAL_COLLECTING 93 +#define SND_SHIELD_NORMAL_ACTIVE 94 +#define SND_SHIELD_DEADLY_COLLECTING 95 +#define SND_SHIELD_DEADLY_ACTIVE 96 +#define SND_EXTRA_TIME_COLLECTING 97 +#define SND_MOLE_MOVING 98 +#define SND_MOLE_WAITING 99 +#define SND_MOLE_DIGGING 100 +#define SND_CLASS_SWITCHGATE_SWITCH_ACTIVATING 101 +#define SND_CLASS_SWITCHGATE_OPENING 102 +#define SND_CLASS_SWITCHGATE_CLOSING 103 +#define SND_CLASS_SWITCHGATE_PASSING 104 +#define SND_TIMEGATE_SWITCH_ACTIVATING 105 +#define SND_TIMEGATE_SWITCH_ACTIVE 106 +#define SND_TIMEGATE_SWITCH_DEACTIVATING 107 +#define SND_TIMEGATE_OPENING 108 +#define SND_CLASS_TIMEGATE_CLOSING 109 +#define SND_CLASS_TIMEGATE_PASSING 110 +#define SND_CLASS_CONVEYOR_BELT_SWITCH_ACTIVATING 111 +#define SND_CLASS_CONVEYOR_BELT_ACTIVE 112 +#define SND_CLASS_CONVEYOR_BELT_SWITCH_DEACTIVATING 113 +#define SND_LIGHT_SWITCH_ACTIVATING 114 +#define SND_LIGHT_SWITCH_DEACTIVATING 115 +#define SND_DX_SUPABOMB_PUSHING 116 +#define SND_TRAP_DIGGING 117 +#define SND_TRAP_ACTIVATING 118 +#define SND_CLASS_TUBE_PASSING 119 +#define SND_AMOEBA_TURNING_TO_GEM 120 +#define SND_AMOEBA_TURNING_TO_ROCK 121 +#define SND_SPEED_PILL_COLLECTING 122 +#define SND_DYNABOMB_INCREASE_NUMBER_COLLECTING 123 +#define SND_DYNABOMB_INCREASE_SIZE_COLLECTING 124 +#define SND_DYNABOMB_INCREASE_POWER_COLLECTING 125 +#define SND_CLASS_DYNABOMB_DROPPING 126 +#define SND_CLASS_DYNABOMB_ACTIVE 127 +#define SND_SATELLITE_MOVING 128 +#define SND_SATELLITE_WAITING 129 +#define SND_SATELLITE_PUSHING 130 +#define SND_LAMP_ACTIVATING 131 +#define SND_LAMP_DEACTIVATING 132 +#define SND_TIME_ORB_FULL_COLLECTING 133 +#define SND_TIME_ORB_FULL_IMPACT 134 +#define SND_TIME_ORB_EMPTY_PUSHING 135 +#define SND_TIME_ORB_EMPTY_IMPACT 136 +#define SND_GAME_OF_LIFE_WAITING 137 +#define SND_GAME_OF_LIFE_GROWING 138 +#define SND_BIOMAZE_WAITING 139 +#define SND_BIOMAZE_GROWING 140 +#define SND_PACMAN_MOVING 141 +#define SND_PACMAN_WAITING 142 +#define SND_PACMAN_DIGGING 143 +#define SND_DARK_YAMYAM_MOVING 144 +#define SND_DARK_YAMYAM_WAITING 145 +#define SND_DARK_YAMYAM_DIGGING 146 +#define SND_PENGUIN_MOVING 147 +#define SND_PENGUIN_WAITING 148 +#define SND_PIG_MOVING 149 +#define SND_PIG_WAITING 150 +#define SND_PIG_DIGGING 151 +#define SND_DRAGON_MOVING 152 +#define SND_DRAGON_WAITING 153 +#define SND_DRAGON_ATTACKING 154 +#define SND_CLASS_PLAYER_DYING 155 +#define SND_ELEMENT_EXPLODING 156 +#define SND_SP_ELEMENT_EXPLODING 157 +#define SND_GAME_STARTING 158 +#define SND_GAME_RUNNING_OUT_OF_TIME 159 +#define SND_GAME_LEVELTIME_BONUS 160 +#define SND_GAME_LOSING 161 +#define SND_GAME_WINNING 162 +#define SND_GAME_SOKOBAN_SOLVING 163 +#define SND_MENU_DOOR_OPENING 164 +#define SND_MENU_DOOR_CLOSING 165 +#define SND_MENU_HALL_OF_FAME 166 +#define SND_MENU_INFO_SCREEN 167 -#define NUM_SOUND_FILES 167 +#define NUM_SOUND_FILES 168 #endif /* CONF_SND_H */ diff --git a/src/conftime.h b/src/conftime.h index 64cae4a1..2024351e 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2003-03-07 00:59]" +#define COMPILE_DATE_STRING "[2003-03-12 00:07]" diff --git a/src/files.c b/src/files.c index 4eecf9fd..2f031820 100644 --- a/src/files.c +++ b/src/files.c @@ -1379,14 +1379,27 @@ void SaveScore(int level_nr) #define NUM_PLAYER_SETUP_TOKENS 16 +/* system setup */ +#define SETUP_TOKEN_SYSTEM_SDL_AUDIODRIVER 0 +#define SETUP_TOKEN_SYSTEM_AUDIO_FRAGMENT_SIZE 1 + +#define NUM_SYSTEM_SETUP_TOKENS 2 + +/* options setup */ +#define SETUP_TOKEN_OPTIONS_VERBOSE 0 + +#define NUM_OPTIONS_SETUP_TOKENS 1 + + static struct SetupInfo si; static struct SetupEditorInfo sei; static struct SetupShortcutInfo ssi; static struct SetupInputInfo sii; +static struct SetupSystemInfo syi; +static struct OptionInfo soi; static struct TokenInfo global_setup_tokens[] = { - /* global setup */ { TYPE_STRING, &si.player_name, "player_name" }, { TYPE_SWITCH, &si.sound, "sound" }, { TYPE_SWITCH, &si.sound_loops, "repeating_sound_loops" }, @@ -1413,7 +1426,6 @@ static struct TokenInfo global_setup_tokens[] = static struct TokenInfo editor_setup_tokens[] = { - /* shortcut setup */ { TYPE_SWITCH, &sei.el_boulderdash, "editor.el_boulderdash" }, { TYPE_SWITCH, &sei.el_emerald_mine, "editor.el_emerald_mine" }, { TYPE_SWITCH, &sei.el_more, "editor.el_more" }, @@ -1427,7 +1439,6 @@ static struct TokenInfo editor_setup_tokens[] = static struct TokenInfo shortcut_setup_tokens[] = { - /* shortcut setup */ { TYPE_KEY_X11, &ssi.save_game, "shortcut.save_game" }, { TYPE_KEY_X11, &ssi.load_game, "shortcut.load_game" }, { TYPE_KEY_X11, &ssi.toggle_pause, "shortcut.toggle_pause" } @@ -1435,7 +1446,6 @@ static struct TokenInfo shortcut_setup_tokens[] = static struct TokenInfo player_setup_tokens[] = { - /* player setup */ { TYPE_BOOLEAN, &sii.use_joystick, ".use_joystick" }, { TYPE_STRING, &sii.joy.device_name, ".joy.device_name" }, { TYPE_INTEGER, &sii.joy.xleft, ".joy.xleft" }, @@ -1454,6 +1464,17 @@ static struct TokenInfo player_setup_tokens[] = { TYPE_KEY_X11, &sii.key.bomb, ".key.place_bomb" } }; +static struct TokenInfo system_setup_tokens[] = +{ + { TYPE_STRING, &syi.sdl_audiodriver, "system.sdl_audiodriver" }, + { TYPE_INTEGER, &syi.audio_fragment_size,"system.audio_fragment_size" } +}; + +static struct TokenInfo options_setup_tokens[] = +{ + { TYPE_BOOLEAN, &soi.verbose, "options.verbose" } +}; + static void setSetupInfoToDefaults(struct SetupInfo *si) { int i; @@ -1518,6 +1539,11 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->input[i].key.snap = (i == 0 ? DEFAULT_KEY_SNAP : KSYM_UNDEFINED); si->input[i].key.bomb = (i == 0 ? DEFAULT_KEY_BOMB : KSYM_UNDEFINED); } + + si->system.sdl_audiodriver = getStringCopy(ARG_DEFAULT); + si->system.audio_fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE; + + si->options.verbose = FALSE; } static void decodeSetupFileList(struct SetupFileList *setup_file_list) @@ -1566,6 +1592,20 @@ static void decodeSetupFileList(struct SetupFileList *setup_file_list) } setup.input[pnr] = sii; } + + /* system setup */ + syi = setup.system; + for (i=0; iLevelSolved = FALSE; - PlaySoundStereo(SND_GAME_WINNING, SOUND_MAX_RIGHT); + PlaySoundStereo(SND_GAME_WINNING, SOUND_MIDDLE); if (TimeLeft) { if (!tape.playing && setup.sound_loops) - PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT, + PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP); while (TimeLeft > 0) { if (!tape.playing && !setup.sound_loops) - PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_RIGHT); + PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE); if (TimeLeft > 0 && !(TimeLeft % 10)) RaiseScore(level.score[SC_ZEITBONUS]); if (TimeLeft > 100 && !(TimeLeft % 10)) @@ -1128,13 +1128,13 @@ void GameWon() else if (level.time == 0) /* level without time limit */ { if (!tape.playing && setup.sound_loops) - PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT, + PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP); while (TimePlayed < 999) { if (!tape.playing && !setup.sound_loops) - PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_RIGHT); + PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE); if (TimePlayed < 999 && !(TimePlayed % 10)) RaiseScore(level.score[SC_ZEITBONUS]); if (TimePlayed < 900 && !(TimePlayed % 10)) @@ -3141,7 +3141,7 @@ void StartMoving(int x, int y) Feld[x][y] = EL_EMPTY; DrawLevelField(x, y); - PlaySoundLevel(newx, newy, SND_CLASS_EXIT_PASSING); + PlaySoundLevel(newx, newy, SND_PENGUIN_PASSING); if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy))) DrawGraphicThruMask(SCREENX(newx),SCREENY(newy), el2img(element), 0); @@ -4879,7 +4879,7 @@ void GameActions() TimeLeft--; if (TimeLeft <= 10 && setup.time_limit) - PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MAX_RIGHT); + PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE); DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FONT_TEXT_2); @@ -5768,7 +5768,7 @@ int DigField(struct PlayerInfo *player, TimeLeft += 10; DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FONT_TEXT_2); } - PlaySoundStereo(SND_EXTRA_TIME_COLLECTING, SOUND_MAX_RIGHT); + PlaySoundStereo(SND_EXTRA_TIME_COLLECTING, SOUND_MIDDLE); break; case EL_SHIELD_NORMAL: @@ -6202,7 +6202,7 @@ int DigField(struct PlayerInfo *player, TimeLeft += 10; DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FONT_TEXT_2); DrawLevelField(x, y); - PlaySoundStereo(SND_TIME_ORB_FULL_COLLECTING, SOUND_MAX_RIGHT); + PlaySoundStereo(SND_TIME_ORB_FULL_COLLECTING, SOUND_MIDDLE); return MF_ACTION; break; diff --git a/src/init.c b/src/init.c index b689911c..62109f00 100644 --- a/src/init.c +++ b/src/init.c @@ -31,1570 +31,1096 @@ #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) + free(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(); + /* 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); } -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 (action < 0) + action = ACTION_DEFAULT; - int i; + if (direction > -1) + element_info[element].direction_graphic[action][direction] = graphic; + else + element_info[element].graphic[action] = graphic; + } - /* initialize pixmap array for special X11 tile clipping to Pixmap 'None' */ - for (i=0; i= MAX_NUM_ELEMENTS || special != -1) + continue; - clip_gc_values.graphics_exposures = False; - clip_gc_valuemask = GCGraphicsExposures; - tile_clip_gc = XCreateGC(display, window->drawable, - clip_gc_valuemask, &clip_gc_values); + if (action < 0) + action = ACTION_DEFAULT; -#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); - } + if (direction > -1) + element_info[element].direction_graphic[action][direction] = graphic; + else + element_info[element].graphic[action] = graphic; } -#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++) + /* 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 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; - /* 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); + if (element >= MAX_NUM_ELEMENTS) + continue; - /* 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(); + 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 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; - 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) + /* correct x or y offset dependant of vertical or horizontal frame order */ + if (parameter[GFX_ARG_VERTICAL]) /* frames are ordered vertically */ { - 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; + 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; } - /* 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; + /* 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]; - 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 + /* 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; - setLevelArtworkDir(artwork.gfx_first); + 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; - ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE); + 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; - InitImages(); + /* 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]; - FreeTileClipmasks(); - InitTileClipmasks(); + /* animation synchronized with global frame counter, not move position */ + graphic_info[graphic].anim_global_sync = parameter[GFX_ARG_GLOBAL_SYNC]; - artwork.gfx_current_identifier = artwork.gfx_current->identifier; - last_override_level_graphics = setup.override_level_graphics; + /* 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]; - redraw_screen = TRUE; - } + /* 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]; +} - 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); +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 - /* set artwork path to send it to the sound server process */ - setLevelArtworkDir(artwork.snd_first); + if (graphic_info != NULL) + free(graphic_info); - InitReloadCustomSounds(snd_new_identifier); - ReinitializeSounds(); + graphic_info = checked_calloc(num_images * sizeof(struct GraphicInfo)); - artwork.snd_current_identifier = artwork.snd_current->identifier; - last_override_level_sounds = setup.override_level_sounds; +#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) + if (clipmasks_initialized) + { + for (i=0; iparameter); - artwork.mus_current_identifier = artwork.mus_current->identifier; - last_override_level_music = setup.override_level_music; + /* now check if no animation frames are outside of the loaded image */ - redraw_screen = TRUE; - } + if (graphic_info[i].bitmap == NULL) + continue; /* skip check for optional images that are undefined */ - if (redraw_screen) - { - InitGfxBackground(); + 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"); - /* force redraw of (open or closed) door graphics */ - SetDoorState(DOOR_OPEN_ALL); - CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY); - } -} + if (i == fallback_graphic) + Error(ERR_EXIT, "fatal error: no fallback graphic available"); -void FreeGadgets() -{ - FreeLevelEditorGadgets(); - FreeGameButtons(); - FreeTapeButtons(); - FreeToolButtons(); - FreeScreenGadgets(); -} + Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic"); + Error(ERR_RETURN_LINE, "-"); -void InitGadgets() -{ - static boolean gadgets_initialized = FALSE; + set_graphic_parameters(i, fallback_image->default_parameter); + graphic_info[i].bitmap = fallback_bitmap; + } - if (gadgets_initialized) - FreeGadgets(); + 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"); - 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); +#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); - /* 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 (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); + } - /* 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); -} + graphic_info[i].clip_mask = + XCreatePixmap(display, window->drawable, TILEX, TILEY, 1); -static int getFontBitmapID(int font_nr) -{ - int special = -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); - 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; + clip_gc_values.graphics_exposures = False; + clip_gc_values.clip_mask = graphic_info[i].clip_mask; + clip_gc_valuemask = GCGraphicsExposures | GCClipMask; - if (special != -1) - return font_info[font_nr].special_bitmap_id[special]; - else - return font_nr; + 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; +#endif } -void InitFontGraphicInfo() +static void InitElementSoundInfo() { - 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; + struct PropertyMapping *property_mapping = getSoundListPropertyMapping(); + int num_property_mappings = getSoundListPropertyMappingSize(); + int i, j, act; - if (graphic_info == NULL) /* still at startup phase */ - { - InitFontInfo(font_initial, NUM_INITIAL_FONTS, getFontBitmapID); + /* 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; - return; - } + /* 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; - /* ---------- initialize font graphic definitions ---------- */ + if (action < 0) + action = ACTION_DEFAULT; - /* always start with reliable default values (normal font graphics) */ - for (i=0; i < NUM_FONTS; i++) - font_info[i].graphic = FONT_INITIAL_1; + 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 normal font/graphic mapping from static configuration */ - for (i=0; font_to_graphic[i].font_nr > -1; i++) + /* initialize element/sound mapping from dynamic configuration */ + for (i=0; i < num_property_mappings; i++) { - int font_nr = font_to_graphic[i].font_nr; - int special = font_to_graphic[i].special; - int graphic = font_to_graphic[i].graphic; + int element = property_mapping[i].base_index; + int action = property_mapping[i].ext1_index; + int sound = property_mapping[i].artwork_index; - if (special != -1) + if (element >= MAX_NUM_ELEMENTS) continue; - font_info[font_nr].graphic = graphic; + if (action < 0) + action = ACTION_DEFAULT; + + element_info[element].sound[action] = sound; } - /* always start with reliable default values (special font graphics) */ - for (i=0; i < NUM_FONTS; i++) + /* initialize element class/sound mapping from dynamic configuration */ + for (i=0; i < num_property_mappings; 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_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; } - /* initialize special font/graphic mapping from static configuration */ - for (i=0; font_to_graphic[i].font_nr > -1; i++) + /* now set all '-1' values to element specific default values */ + for (i=0; i= 0 && special < NUM_SPECIAL_GFX_ARGS) + for (act=0; act < NUM_ACTIONS; act++) { - font_info[font_nr].special_graphic[special] = graphic; - font_info[font_nr].special_bitmap_id[special] = num_font_bitmaps; - num_font_bitmaps++; + /* no sound for this specific action -- use default action sound */ + if (element_info[i].sound[act] == -1) + element_info[i].sound[act] = default_action_sound; } } +} - /* 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 set_sound_parameters(int sound, char **parameter_raw) +{ + int parameter[NUM_SND_ARGS]; + int i; - if (font_nr < 0) - continue; + /* 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 (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++; - } - } + /* 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]; +} - /* ---------- initialize font bitmap array ---------- */ +static void InitSoundInfo() +{ + struct PropertyMapping *property_mapping = getSoundListPropertyMapping(); + int num_property_mappings = getSoundListPropertyMappingSize(); + int *sound_effect_properties; + int num_sounds = getSoundListSize(); + int i, j; - if (font_bitmap_info != NULL) - free(font_bitmap_info); + if (sound_info != NULL) + free(sound_info); - font_bitmap_info = - checked_calloc(num_font_bitmaps * sizeof(struct FontBitmapInfo)); + sound_effect_properties = checked_calloc(num_sounds * sizeof(int)); + sound_info = checked_calloc(num_sounds * sizeof(struct SoundInfo)); - /* ---------- initialize font bitmap definitions ---------- */ + /* initialize sound effect for all elements to "no sound" */ + for (i=0; itoken); - for (j=0; j < NUM_SPECIAL_GFX_ARGS; j++) + 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 font_bitmap_id = font_info[i].special_bitmap_id[j]; - int graphic = font_info[i].special_graphic[j]; + int len_action_text = strlen(element_action_info[j].suffix); - /* 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; - } - } + 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; - InitFontInfo(font_bitmap_info, num_font_bitmaps, getFontBitmapID); -} + if (element_action_info[j].is_loop_sound) + sound_info[i].loop = TRUE; + } + } -void InitElementGraphicInfo() -{ - struct PropertyMapping *property_mapping = getImageListPropertyMapping(); - int num_property_mappings = getImageListPropertyMappingSize(); - int i, act, dir; + /* associate elements and some selected sound actions */ - /* 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 (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]; - if (action < 0) - action = ACTION_DEFAULT; + element_info[j].sound[sound_action_value] = i; + } + } + } - if (direction > -1) - element_info[element].direction_graphic[action][direction] = graphic; - else - element_info[element].graphic[action] = graphic; + 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; + SetMainBackgroundImage(IMG_BACKGROUND); + SetDoorBackgroundImage(IMG_BACKGROUND_DOOR); - if (base_redefined && !special_redefined) - continue; + InitGadgets(); + InitToons(); +} - element_info[element].special_graphic[special] = graphic; - } +static void ReinitializeSounds() +{ + InitElementSoundInfo(); /* element game sound mapping */ + InitSoundInfo(); /* sound properties mapping */ - /* 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; +#if 1 + InitElementSoundInfo(); /* element game sound mapping */ +#endif - if (element >= MAX_NUM_ELEMENTS) - continue; + InitPlaySoundLevel(); /* internal game sound settings */ +} - if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS) - element_info[element].special_graphic[special] = graphic; - } -} - -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); - - 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; - } - - /* 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]; + /* currently nothing to do */ } -static void InitGraphicInfo() +void InitElementProperties() { - 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)); + int i, j; -#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) - if (clipmasks_initialized) + static int ep_amoebalive[] = { - 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"); - - if (i == fallback_graphic) - Error(ERR_EXIT, "fatal error: no fallback graphic available"); + EL_AMOEBA_DEAD, + EL_AMOEBA_WET, + EL_AMOEBA_DRY, + EL_AMOEBA_FULL, + EL_BD_AMOEBA + }; + static int ep_amoeboid_num = SIZEOF_ARRAY_INT(ep_amoeboid); - Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic"); - Error(ERR_RETURN_LINE, "-"); + static int ep_schluessel[] = + { + 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 + }; + static int ep_schluessel_num = SIZEOF_ARRAY_INT(ep_schluessel); - 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; -#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; - } - - /* 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 (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; - } - - /* 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); - - /* 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 (action < 0) - action = ACTION_DEFAULT; - - element_info[element].sound[action] = sound; - } - -#if 0 - /* TEST ONLY */ - { - int element = EL_CUSTOM_11; - int j = 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++; - } - } - - PlaySoundLevelElementAction(0,0, EL_CUSTOM_11, ACTION_PUSHING); -#endif - -#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() -{ - int i, j; - - static int ep_amoebalive[] = - { - EL_AMOEBA_WET, - EL_AMOEBA_DRY, - EL_AMOEBA_FULL, - EL_BD_AMOEBA - }; - static int ep_amoebalive_num = SIZEOF_ARRAY_INT(ep_amoebalive); - - static int ep_amoeboid[] = - { - EL_AMOEBA_DEAD, - EL_AMOEBA_WET, - EL_AMOEBA_DRY, - EL_AMOEBA_FULL, - EL_BD_AMOEBA - }; - static int ep_amoeboid_num = SIZEOF_ARRAY_INT(ep_amoeboid); - - static int ep_schluessel[] = - { - 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 - }; - static int ep_schluessel_num = SIZEOF_ARRAY_INT(ep_schluessel); - - 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 - }; - static int ep_pforte_num = SIZEOF_ARRAY_INT(ep_pforte); + 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 + }; + static int ep_pforte_num = SIZEOF_ARRAY_INT(ep_pforte); static int ep_solid[] = { @@ -2678,157 +2204,620 @@ void InitElementProperties() }; 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 + &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 *); + + 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[] = + { + "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 *ep2_num[] = + static char *ignore_sound_tokens[] = { - &ep_belt_num, - &ep_belt_active_num, - &ep_belt_switch_num, - &ep_tube_num + "name", + "sort_priority", + NULL }; - static int num_properties1 = SIZEOF_ARRAY(ep1_num, int *); - static int num_properties2 = SIZEOF_ARRAY(ep2_num, int *); + int i; + + 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 (i=0; iidentifier); + ReinitializeSounds(); +} + +static void InitMusic() +{ + InitReloadCustomMusic(artwork.mus_current->identifier); + ReinitializeMusic(); +} + +void InitNetworkServer() +{ +#if defined(PLATFORM_UNIX) + int nr_wanted; +#endif + + if (!options.network) + return; + +#if defined(PLATFORM_UNIX) + nr_wanted = Request("Choose player", REQ_PLAYER | REQ_STAY_CLOSED); + + if (!ConnectToServer(options.server_host, options.server_port)) + Error(ERR_EXIT, "cannot connect to network game server"); + + SendToServer_PlayerName(setup.player_name); + SendToServer_ProtocolVersion(); - for (i=EL_CHAR_START; i<=EL_CHAR_END; i++) - Properties1[i] |= (EP_BIT_CHAR | EP_BIT_INACTIVE); + if (nr_wanted) + SendToServer_NrWanted(nr_wanted); +#endif } -void Execute_Command(char *command) +void ReloadCustomArtwork() { - if (strcmp(command, "print graphicsinfo.conf") == 0) - { - int i; + 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; - printf("# You can configure additional/alternative image files here.\n"); - printf("# (The images below are default and therefore commented out.)\n"); - printf("\n"); - printf("%s\n", getFormattedSetupEntry("name", "Classic Graphics")); - printf("\n"); - printf("%s\n", getFormattedSetupEntry("sort_priority", "100")); - printf("\n"); + if (leveldir_current_identifier == NULL) + leveldir_current_identifier = leveldir_current->identifier; - for (i=0; image_config[i].token != NULL; i++) - printf("# %s\n", - getFormattedSetupEntry(image_config[i].token, - image_config[i].value)); +#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 - exit(0); - } - else if (strcmp(command, "print soundsinfo.conf") == 0) - { - int i; +#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 - 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"); + /* leveldir_current may be invalid (level group, parent link) */ + if (!validLevelSeries(leveldir_current)) + return; - for (i=0; sound_config[i].token != NULL; i++) - printf("# %s\n", - getFormattedSetupEntry(sound_config[i].token, - sound_config[i].value)); + /* 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; - exit(0); + 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; } - else if (strcmp(command, "print musicinfo.conf") == 0) + + /* 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) { - 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")); +#if 0 + printf("RELOADING GRAPHICS '%s' -> '%s' ('%s')\n", + artwork.gfx_current_identifier, + artwork.gfx_current->identifier, + gfx_new_identifier); +#endif - exit(0); + 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; } - else if (strncmp(command, "dump level ", 11) == 0) + + if (strcmp(artwork.snd_current_identifier, snd_new_identifier) != 0 || + last_override_level_sounds != setup.override_level_sounds) { - char *filename = &command[11]; +#if 0 + printf("RELOADING SOUNDS '%s' -> '%s' ('%s')\n", + artwork.snd_current_identifier, + artwork.snd_current->identifier, + snd_new_identifier); +#endif - if (access(filename, F_OK) != 0) - Error(ERR_EXIT, "cannot open file '%s'", filename); + /* set artwork path to send it to the sound server process */ + setLevelArtworkDir(artwork.snd_first); - LoadLevelFromFilename(filename); - DumpLevel(&level); + InitReloadCustomSounds(snd_new_identifier); + ReinitializeSounds(); - exit(0); + artwork.snd_current_identifier = artwork.snd_current->identifier; + last_override_level_sounds = setup.override_level_sounds; + + redraw_screen = TRUE; } - else if (strncmp(command, "dump tape ", 10) == 0) + + if (strcmp(artwork.mus_current_identifier, mus_new_identifier) != 0 || + last_override_level_music != setup.override_level_music) { - char *filename = &command[10]; + /* 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(); - LoadTapeFromFilename(filename); - DumpTape(&tape); + 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, "autoplay ", 9) == 0) + + if (redraw_screen) { - char *str_copy = getStringCopy(&command[9]); - char *str_ptr = strchr(str_copy, ' '); + InitGfxBackground(); - global.autoplay_leveldir = str_copy; - global.autoplay_level_nr = -1; + /* force redraw of (open or closed) door graphics */ + SetDoorState(DOOR_OPEN_ALL); + CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY); + } +} - if (str_ptr != NULL) - { - *str_ptr++ = '\0'; /* terminate leveldir string */ - global.autoplay_level_nr = atoi(str_ptr); /* get level_nr value */ - } + +/* ========================================================================= */ +/* OpenAll() */ +/* ========================================================================= */ + +void OpenAll() +{ + InitGlobal(); /* initialize some global variables */ + + 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 + + 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); + + 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) diff --git a/src/init.h b/src/init.h index 9eb9fb62..95993d45 100644 --- a/src/init.h +++ b/src/init.h @@ -16,8 +16,9 @@ #include "main.h" -void OpenAll(void); void ReloadCustomArtwork(); + +void OpenAll(void); void CloseAllAndExit(int); #endif diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index 5184b088..85dbab94 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -40,6 +40,8 @@ static int video_yoffset; inline void SDLInitVideoDisplay(void) { + putenv("SDL_VIDEO_CENTERED=1"); + /* initialize SDL video */ if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) Error(ERR_EXIT, "SDL_InitSubSystem() failed: %s", SDL_GetError()); @@ -1173,6 +1175,9 @@ Bitmap *SDLLoadImage(char *filename) inline void SDLOpenAudio(void) { + if (strcmp(setup.system.sdl_audiodriver, ARG_DEFAULT) != 0) + putenv(getStringCat2("SDL_AUDIODRIVER=", setup.system.sdl_audiodriver)); + if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { Error(ERR_WARN, "SDL_InitSubSystem() failed: %s", SDL_GetError()); @@ -1181,7 +1186,7 @@ inline void SDLOpenAudio(void) if (Mix_OpenAudio(DEFAULT_AUDIO_SAMPLE_RATE, MIX_DEFAULT_FORMAT, AUDIO_NUM_CHANNELS_STEREO, - DEFAULT_AUDIO_FRAGMENT_SIZE) < 0) + setup.system.audio_fragment_size) < 0) { Error(ERR_WARN, "Mix_OpenAudio() failed: %s", SDL_GetError()); return; diff --git a/src/libgame/system.h b/src/libgame/system.h index 9b914a8a..bba4a305 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -156,6 +156,9 @@ /* default value for undefined filename */ #define UNDEFINED_FILENAME "[NONE]" +/* default value for undefined parameter */ +#define ARG_DEFAULT "[DEFAULT]" + /* default values for undefined configuration file parameters */ #define ARG_UNDEFINED "-1000000" #define ARG_UNDEFINED_VALUE (atoi(ARG_UNDEFINED)) @@ -391,6 +394,12 @@ struct SetupShortcutInfo Key toggle_pause; }; +struct SetupSystemInfo +{ + char *sdl_audiodriver; + int audio_fragment_size; +}; + struct SetupInfo { char *player_name; @@ -423,6 +432,8 @@ struct SetupInfo struct SetupEditorInfo editor; struct SetupShortcutInfo shortcut; struct SetupInputInfo input[MAX_PLAYERS]; + struct SetupSystemInfo system; + struct OptionInfo options; }; #define TREE_TYPE_GENERIC 0