X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fgame.c;h=6b920a51ca2d40b9ca2f097e6d3fa865ff0f2c81;hb=4abc7d07404767933918e25220cab6c2eae683e5;hp=237395e75ee33699d5647763f146b3a39d04323b;hpb=2a54652c5fad8751e08b648111a0534f8c012a32;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 237395e7..6b920a51 100644 --- a/src/game.c +++ b/src/game.c @@ -134,6 +134,458 @@ #define DX_TIME (DX + XX_TIME) #define DY_TIME (DY + YY_TIME) +#if 0 +/* game panel display and control definitions */ + +#define GAME_CONTROL_LEVEL 0 +#define GAME_CONTROL_GEMS 1 +#define GAME_CONTROL_INVENTORY 2 +#define GAME_CONTROL_KEYS 3 +#define GAME_CONTROL_SCORE 4 +#define GAME_CONTROL_TIME 5 +#define GAME_CONTROL_TIME_HH 6 +#define GAME_CONTROL_TIME_MM 7 +#define GAME_CONTROL_TIME_SS 8 +#define GAME_CONTROL_DROP_NEXT_1 9 +#define GAME_CONTROL_DROP_NEXT_2 10 +#define GAME_CONTROL_DROP_NEXT_3 11 +#define GAME_CONTROL_DROP_NEXT_4 12 +#define GAME_CONTROL_DROP_NEXT_5 13 +#define GAME_CONTROL_DROP_NEXT_6 14 +#define GAME_CONTROL_DROP_NEXT_7 15 +#define GAME_CONTROL_DROP_NEXT_8 16 +#define GAME_CONTROL_EMC_KEYS 17 +#define GAME_CONTROL_KEY_1 18 +#define GAME_CONTROL_KEY_2 19 +#define GAME_CONTROL_KEY_3 20 +#define GAME_CONTROL_KEY_4 21 +#define GAME_CONTROL_KEY_5 22 +#define GAME_CONTROL_KEY_6 23 +#define GAME_CONTROL_KEY_7 24 +#define GAME_CONTROL_KEY_8 25 +#define GAME_CONTROL_KEY_WHITE 26 +#define GAME_CONTROL_KEY_WHITE_COUNT 27 +#define GAME_CONTROL_SHIELD_NORMAL 28 +#define GAME_CONTROL_SHIELD_NORMAL_TIME 29 +#define GAME_CONTROL_SHIELD_DEADLY 30 +#define GAME_CONTROL_SHIELD_DEADLY_TIME 31 +#define GAME_CONTROL_EXIT 32 +#define GAME_CONTROL_EM_EXIT 33 +#define GAME_CONTROL_SP_EXIT 34 +#define GAME_CONTROL_STEEL_EXIT 35 +#define GAME_CONTROL_EM_STEEL_EXIT 36 +#define GAME_CONTROL_EMC_MAGIC_BALL 37 +#define GAME_CONTROL_EMC_MAGIC_BALL_TIME 38 +#define GAME_CONTROL_LIGHT_SWITCH 39 +#define GAME_CONTROL_LIGHT_SWITCH_TIME 40 +#define GAME_CONTROL_TIMEGATE_SWITCH 41 +#define GAME_CONTROL_TIMEGATE_SWITCH_TIME 42 +#define GAME_CONTROL_SWITCHGATE_SWITCH 43 +#define GAME_CONTROL_EMC_LENSES 44 +#define GAME_CONTROL_EMC_LENSES_TIME 45 +#define GAME_CONTROL_EMC_MAGNIFIER 46 +#define GAME_CONTROL_EMC_MAGNIFIER_TIME 47 +#define GAME_CONTROL_BALLOON_SWITCH 48 +#define GAME_CONTROL_DYNABOMB_NUMBER 49 +#define GAME_CONTROL_DYNABOMB_SIZE 50 +#define GAME_CONTROL_DYNABOMB_POWER 51 +#define GAME_CONTROL_PENGUINS 52 +#define GAME_CONTROL_SOKOBAN_OBJECTS 53 +#define GAME_CONTROL_SOKOBAN_FIELDS 54 +#define GAME_CONTROL_ROBOT_WHEEL 55 +#define GAME_CONTROL_CONVEYOR_BELT_1 56 +#define GAME_CONTROL_CONVEYOR_BELT_1_SWITCH 57 +#define GAME_CONTROL_CONVEYOR_BELT_2 58 +#define GAME_CONTROL_CONVEYOR_BELT_2_SWITCH 59 +#define GAME_CONTROL_CONVEYOR_BELT_3 60 +#define GAME_CONTROL_CONVEYOR_BELT_3_SWITCH 61 +#define GAME_CONTROL_CONVEYOR_BELT_4 62 +#define GAME_CONTROL_CONVEYOR_BELT_4_SWITCH 63 +#define GAME_CONTROL_MAGIC_WALL 64 +#define GAME_CONTROL_MAGIC_WALL_TIME 65 +#define GAME_CONTROL_BD_MAGIC_WALL 66 +#define GAME_CONTROL_DC_MAGIC_WALL 67 +#define GAME_CONTROL_PLAYER_NAME 68 +#define GAME_CONTROL_LEVEL_NAME 69 +#define GAME_CONTROL_LEVEL_AUTHOR 70 + +struct GameControlInfo +{ + int nr; + + struct TextPosInfo *pos_text; + int type; + void *ptr; +}; + +static struct GameControlInfo game_controls[] = +{ + { + GAME_CONTROL_LEVEL, + &game.panel.level, + TYPE_INTEGER, + }, + { + GAME_CONTROL_GEMS, + &game.panel.gems, + TYPE_INTEGER, + }, + { + GAME_CONTROL_INVENTORY, + &game.panel.inventory, + TYPE_INTEGER, + }, + { + GAME_CONTROL_KEYS, + &game.panel.keys, + TYPE_INTEGER, + }, + { + GAME_CONTROL_SCORE, + &game.panel.score, + TYPE_INTEGER, + }, + { + GAME_CONTROL_TIME, + &game.panel.time, + TYPE_INTEGER, + }, + { + GAME_CONTROL_TIME_HH, + &game.panel.time_hh, + TYPE_INTEGER, + }, + { + GAME_CONTROL_TIME_MM, + &game.panel.time_mm, + TYPE_INTEGER, + }, + { + GAME_CONTROL_TIME_SS, + &game.panel.time_ss, + TYPE_INTEGER, + }, + { + GAME_CONTROL_DROP_NEXT_1, + &game.panel.drop_next_1, + TYPE_INTEGER, + }, + { + GAME_CONTROL_DROP_NEXT_2, + &game.panel.drop_next_2, + TYPE_INTEGER, + }, + { + GAME_CONTROL_DROP_NEXT_3, + &game.panel.drop_next_3, + TYPE_INTEGER, + }, + { + GAME_CONTROL_DROP_NEXT_4, + &game.panel.drop_next_4, + TYPE_INTEGER, + }, + { + GAME_CONTROL_DROP_NEXT_5, + &game.panel.drop_next_5, + TYPE_INTEGER, + }, + { + GAME_CONTROL_DROP_NEXT_6, + &game.panel.drop_next_6, + TYPE_INTEGER, + }, + { + GAME_CONTROL_DROP_NEXT_7, + &game.panel.drop_next_7, + TYPE_INTEGER, + }, + { + GAME_CONTROL_DROP_NEXT_8, + &game.panel.drop_next_8, + TYPE_INTEGER, + }, + { + GAME_CONTROL_EMC_KEYS, + &game.panel.emc_keys, + TYPE_INTEGER, + }, + { + GAME_CONTROL_KEY_1, + &game.panel.key_1, + TYPE_INTEGER, + }, + { + GAME_CONTROL_KEY_2, + &game.panel.key_2, + TYPE_INTEGER, + }, + { + GAME_CONTROL_KEY_3, + &game.panel.key_3, + TYPE_INTEGER, + }, + { + GAME_CONTROL_KEY_4, + &game.panel.key_4, + TYPE_INTEGER, + }, + { + GAME_CONTROL_KEY_5, + &game.panel.key_5, + TYPE_INTEGER, + }, + { + GAME_CONTROL_KEY_6, + &game.panel.key_6, + TYPE_INTEGER, + }, + { + GAME_CONTROL_KEY_7, + &game.panel.key_7, + TYPE_INTEGER, + }, + { + GAME_CONTROL_KEY_8, + &game.panel.key_8, + TYPE_INTEGER, + }, + { + GAME_CONTROL_KEY_WHITE, + &game.panel.key_white, + TYPE_INTEGER, + }, + { + GAME_CONTROL_KEY_WHITE_COUNT, + &game.panel.key_white_count, + TYPE_INTEGER, + }, + { + GAME_CONTROL_SHIELD_NORMAL, + &game.panel.shield_normal, + TYPE_INTEGER, + }, + { + GAME_CONTROL_SHIELD_NORMAL_TIME, + &game.panel.shield_normal_time, + TYPE_INTEGER, + }, + { + GAME_CONTROL_SHIELD_DEADLY, + &game.panel.shield_deadly, + TYPE_INTEGER, + }, + { + GAME_CONTROL_SHIELD_DEADLY_TIME, + &game.panel.shield_deadly_time, + TYPE_INTEGER, + }, + { + GAME_CONTROL_EXIT, + &game.panel.exit, + TYPE_INTEGER, + }, + { + GAME_CONTROL_EM_EXIT, + &game.panel.em_exit, + TYPE_INTEGER, + }, + { + GAME_CONTROL_SP_EXIT, + &game.panel.sp_exit, + TYPE_INTEGER, + }, + { + GAME_CONTROL_STEEL_EXIT, + &game.panel.steel_exit, + TYPE_INTEGER, + }, + { + GAME_CONTROL_EM_STEEL_EXIT, + &game.panel.em_steel_exit, + TYPE_INTEGER, + }, + { + GAME_CONTROL_EMC_MAGIC_BALL, + &game.panel.emc_magic_ball, + TYPE_INTEGER, + }, + { + GAME_CONTROL_EMC_MAGIC_BALL_TIME, + &game.panel.emc_magic_ball_time, + TYPE_INTEGER, + }, + { + GAME_CONTROL_LIGHT_SWITCH, + &game.panel.light_switch, + TYPE_INTEGER, + }, + { + GAME_CONTROL_LIGHT_SWITCH_TIME, + &game.panel.light_switch_time, + TYPE_INTEGER, + }, + { + GAME_CONTROL_TIMEGATE_SWITCH, + &game.panel.timegate_switch, + TYPE_INTEGER, + }, + { + GAME_CONTROL_TIMEGATE_SWITCH_TIME, + &game.panel.timegate_switch_time, + TYPE_INTEGER, + }, + { + GAME_CONTROL_SWITCHGATE_SWITCH, + &game.panel.switchgate_switch, + TYPE_INTEGER, + }, + { + GAME_CONTROL_EMC_LENSES, + &game.panel.emc_lenses, + TYPE_INTEGER, + }, + { + GAME_CONTROL_EMC_LENSES_TIME, + &game.panel.emc_lenses_time, + TYPE_INTEGER, + }, + { + GAME_CONTROL_EMC_MAGNIFIER, + &game.panel.emc_magnifier, + TYPE_INTEGER, + }, + { + GAME_CONTROL_EMC_MAGNIFIER_TIME, + &game.panel.emc_magnifier_time, + TYPE_INTEGER, + }, + { + GAME_CONTROL_BALLOON_SWITCH, + &game.panel.balloon_switch, + TYPE_INTEGER, + }, + { + GAME_CONTROL_DYNABOMB_NUMBER, + &game.panel.dynabomb_number, + TYPE_INTEGER, + }, + { + GAME_CONTROL_DYNABOMB_SIZE, + &game.panel.dynabomb_size, + TYPE_INTEGER, + }, + { + GAME_CONTROL_DYNABOMB_POWER, + &game.panel.dynabomb_power, + TYPE_INTEGER, + }, + { + GAME_CONTROL_PENGUINS, + &game.panel.penguins, + TYPE_INTEGER, + }, + { + GAME_CONTROL_SOKOBAN_OBJECTS, + &game.panel.sokoban_objects, + TYPE_INTEGER, + }, + { + GAME_CONTROL_SOKOBAN_FIELDS, + &game.panel.sokoban_fields, + TYPE_INTEGER, + }, + { + GAME_CONTROL_ROBOT_WHEEL, + &game.panel.robot_wheel, + TYPE_INTEGER, + }, + { + GAME_CONTROL_CONVEYOR_BELT_1, + &game.panel.conveyor_belt_1, + TYPE_INTEGER, + }, + { + GAME_CONTROL_CONVEYOR_BELT_1_SWITCH, + &game.panel.conveyor_belt_1_switch, + TYPE_INTEGER, + }, + { + GAME_CONTROL_CONVEYOR_BELT_2, + &game.panel.conveyor_belt_2, + TYPE_INTEGER, + }, + { + GAME_CONTROL_CONVEYOR_BELT_2_SWITCH, + &game.panel.conveyor_belt_2_switch, + TYPE_INTEGER, + }, + { + GAME_CONTROL_CONVEYOR_BELT_3, + &game.panel.conveyor_belt_3, + TYPE_INTEGER, + }, + { + GAME_CONTROL_CONVEYOR_BELT_3_SWITCH, + &game.panel.conveyor_belt_3_switch, + TYPE_INTEGER, + }, + { + GAME_CONTROL_CONVEYOR_BELT_4, + &game.panel.conveyor_belt_4, + TYPE_INTEGER, + }, + { + GAME_CONTROL_CONVEYOR_BELT_4_SWITCH, + &game.panel.conveyor_belt_4_switch, + TYPE_INTEGER, + }, + { + GAME_CONTROL_MAGIC_WALL, + &game.panel.magic_wall, + TYPE_INTEGER, + }, + { + GAME_CONTROL_MAGIC_WALL_TIME, + &game.panel.magic_wall_time, + TYPE_INTEGER, + }, + { + GAME_CONTROL_BD_MAGIC_WALL, + &game.panel.bd_magic_wall, + TYPE_INTEGER, + }, + { + GAME_CONTROL_DC_MAGIC_WALL, + &game.panel.dc_magic_wall, + TYPE_INTEGER, + }, + { + GAME_CONTROL_PLAYER_NAME, + &game.panel.player_name, + TYPE_INTEGER, + }, + { + GAME_CONTROL_LEVEL_NAME, + &game.panel.level_name, + TYPE_INTEGER, + }, + { + GAME_CONTROL_LEVEL_AUTHOR, + &game.panel.level_author, + TYPE_INTEGER, + }, + + { + -1, + NULL, + -1, + NULL + } +}; +#endif + + /* values for delayed check of falling and moving elements and for collision */ #define CHECK_DELAY_MOVING 3 #define CHECK_DELAY_FALLING CHECK_DELAY_MOVING @@ -843,7 +1295,7 @@ static int playfield_scan_delta_y = 1; (y) += playfield_scan_delta_y) \ for ((x) = playfield_scan_start_x; \ (x) >= 0 && (x) <= lev_fieldx - 1; \ - (x) += playfield_scan_delta_x) \ + (x) += playfield_scan_delta_x) #ifdef DEBUG void DEBUG_SetMaximumDynamite() @@ -942,7 +1394,7 @@ void GetPlayerConfig() InitJoysticks(); } -static int get_element_from_group_element(int element) +int GetElementFromGroupElement(int element) { if (IS_GROUP_ELEMENT(element)) { @@ -1240,7 +1692,7 @@ static void InitField(int x, int y, boolean init_game) } else if (IS_GROUP_ELEMENT(element)) { - Feld[x][y] = get_element_from_group_element(element); + Feld[x][y] = GetElementFromGroupElement(element); InitField(x, y, init_game); } @@ -1288,74 +1740,91 @@ static inline void InitField_WithBug2(int x, int y, boolean init_game) void DrawGameValue_Emeralds(int value) { struct TextPosInfo *pos = &game.panel.gems; +#if 1 + int font_nr = pos->font; +#else int font_nr = FONT_TEXT_2; +#endif int font_width = getFontWidth(font_nr); - int digits = pos->chars; + int chars = pos->chars; if (PANEL_DEACTIVATED(pos)) return; - pos->width = digits * font_width; + pos->width = chars * font_width; - DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr); + DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, chars), font_nr); } void DrawGameValue_Dynamite(int value) { struct TextPosInfo *pos = &game.panel.inventory; +#if 1 + int font_nr = pos->font; +#else int font_nr = FONT_TEXT_2; +#endif int font_width = getFontWidth(font_nr); - int digits = pos->chars; + int chars = pos->chars; if (PANEL_DEACTIVATED(pos)) return; - pos->width = digits * font_width; + pos->width = chars * font_width; - DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr); + DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, chars), font_nr); } void DrawGameValue_Score(int value) { struct TextPosInfo *pos = &game.panel.score; +#if 1 + int font_nr = pos->font; +#else int font_nr = FONT_TEXT_2; +#endif int font_width = getFontWidth(font_nr); - int digits = pos->chars; + int chars = pos->chars; if (PANEL_DEACTIVATED(pos)) return; - pos->width = digits * font_width; + pos->width = chars * font_width; - DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr); + DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, chars), font_nr); } void DrawGameValue_Time(int value) { struct TextPosInfo *pos = &game.panel.time; static int last_value = -1; - int digits1 = 3; - int digits2 = 4; - int digits = pos->chars; + int chars1 = 3; + int chars2 = 4; + int chars = pos->chars; +#if 1 + int font1_nr = pos->font; + int font2_nr = pos->font_alt; +#else int font1_nr = FONT_TEXT_2; int font2_nr = FONT_TEXT_1; +#endif int font_nr = font1_nr; - boolean use_dynamic_digits = (digits == -1 ? TRUE : FALSE); + boolean use_dynamic_chars = (chars == -1 ? TRUE : FALSE); if (PANEL_DEACTIVATED(pos)) return; - if (use_dynamic_digits) /* use dynamic number of digits */ + if (use_dynamic_chars) /* use dynamic number of chars */ { - digits = (value < 1000 ? digits1 : digits2); + chars = (value < 1000 ? chars1 : chars2); font_nr = (value < 1000 ? font1_nr : font2_nr); } - /* clear background if value just changed its size (dynamic digits only) */ - if (use_dynamic_digits && (last_value < 1000) != (value < 1000)) + /* clear background if value just changed its size (dynamic chars only) */ + if (use_dynamic_chars && (last_value < 1000) != (value < 1000)) { - int width1 = digits1 * getFontWidth(font1_nr); - int width2 = digits2 * getFontWidth(font2_nr); + int width1 = chars1 * getFontWidth(font1_nr); + int width2 = chars2 * getFontWidth(font2_nr); int max_width = MAX(width1, width2); int max_height = MAX(getFontHeight(font1_nr), getFontHeight(font2_nr)); @@ -1365,9 +1834,9 @@ void DrawGameValue_Time(int value) max_width, max_height); } - pos->width = digits * getFontWidth(font_nr); + pos->width = chars * getFontWidth(font_nr); - DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr); + DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, chars), font_nr); last_value = value; } @@ -1375,26 +1844,31 @@ void DrawGameValue_Time(int value) void DrawGameValue_Level(int value) { struct TextPosInfo *pos = &game.panel.level; - int digits1 = 2; - int digits2 = 3; - int digits = pos->chars; + int chars1 = 2; + int chars2 = 3; + int chars = pos->chars; +#if 1 + int font1_nr = pos->font; + int font2_nr = pos->font_alt; +#else int font1_nr = FONT_TEXT_2; int font2_nr = FONT_TEXT_1; +#endif int font_nr = font1_nr; - boolean use_dynamic_digits = (digits == -1 ? TRUE : FALSE); + boolean use_dynamic_chars = (chars == -1 ? TRUE : FALSE); if (PANEL_DEACTIVATED(pos)) return; - if (use_dynamic_digits) /* use dynamic number of digits */ + if (use_dynamic_chars) /* use dynamic number of chars */ { - digits = (level_nr < 100 ? digits1 : digits2); + chars = (level_nr < 100 ? chars1 : chars2); font_nr = (level_nr < 100 ? font1_nr : font2_nr); } - pos->width = digits * getFontWidth(font_nr); + pos->width = chars * getFontWidth(font_nr); - DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr); + DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, chars), font_nr); } void DrawGameValue_Keys(int key[MAX_NUM_KEYS]) @@ -1419,11 +1893,34 @@ void DrawGameValue_Keys(int key[MAX_NUM_KEYS]) int dst_x = PANEL_XPOS(pos) + i * MINI_TILEX; int dst_y = PANEL_YPOS(pos); +#if 0 + /* masked blit with tiles from half-size scaled bitmap does not work yet + (no mask bitmap created for these sizes after loading and scaling) -- + solution: load without creating mask, scale, then create final mask */ + + BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, src_x, src_y, + MINI_TILEX, MINI_TILEY, dst_x, dst_y); + + if (key[i]) + { + int graphic = el2edimg(base_key_graphic + i); + Bitmap *src_bitmap; + int src_x, src_y; + + getMiniGraphicSource(graphic, &src_bitmap, &src_x, &src_y); + + SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc, + dst_x - src_x, dst_y - src_y); + BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, MINI_TILEX, MINI_TILEY, + dst_x, dst_y); + } +#else if (key[i]) DrawMiniGraphicExt(drawto, dst_x, dst_y, el2edimg(base_key_graphic + i)); else BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, src_x, src_y, MINI_TILEX, MINI_TILEY, dst_x, dst_y); +#endif } } @@ -8732,7 +9229,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) static void CreateFieldExt(int x, int y, int element, boolean is_change) { int old_element = Feld[x][y]; - int new_element = get_element_from_group_element(element); + int new_element = GetElementFromGroupElement(element); int previous_move_direction = MovDir[x][y]; #if USE_NEW_CUSTOM_VALUE int last_ce_value = CustomValue[x][y]; @@ -9064,12 +9561,13 @@ static void HandleElementChange(int x, int y, int page) if (change->can_change) { -#if 0 +#if 1 /* !!! not clear why graphic animation should be reset at all here !!! */ + /* !!! UPDATE: but is needed for correct Snake Bite tail animation !!! */ #if USE_GFX_RESET_WHEN_NOT_MOVING /* when a custom element is about to change (for example by change delay), do not reset graphic animation when the custom element is moving */ - if (IS_MOVING(x, y)) + if (!IS_MOVING(x, y)) #endif { ResetGfxAnimation(x, y); @@ -10107,13 +10605,15 @@ void GameActions_RND() /* continue moving after pushing (this is actually a bug) */ if (!IS_MOVING(x, y)) - { Stop[x][y] = FALSE; - } } } } +#if 0 + debug_print_timestamp(0, "start main loop profiling"); +#endif + SCAN_PLAYFIELD(x, y) { ChangeCount[x][y] = 0; @@ -10188,6 +10688,63 @@ void GameActions_RND() #endif } +#if 0 + debug_print_timestamp(0, "- time for pre-main loop:"); +#endif + +#if 0 // -------------------- !!! TEST ONLY !!! -------------------- + SCAN_PLAYFIELD(x, y) + { + element = Feld[x][y]; + graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); + +#if 1 + { +#if 1 + int element2 = element; + int graphic2 = graphic; +#else + int element2 = Feld[x][y]; + int graphic2 = el_act_dir2img(element2, GfxAction[x][y], GfxDir[x][y]); +#endif + int last_gfx_frame = GfxFrame[x][y]; + + if (graphic_info[graphic2].anim_global_sync) + GfxFrame[x][y] = FrameCounter; + else if (ANIM_MODE(graphic2) == ANIM_CE_VALUE) + GfxFrame[x][y] = CustomValue[x][y]; + else if (ANIM_MODE(graphic2) == ANIM_CE_SCORE) + GfxFrame[x][y] = element_info[element2].collect_score; + else if (ANIM_MODE(graphic2) == ANIM_CE_DELAY) + GfxFrame[x][y] = ChangeDelay[x][y]; + + if (redraw && GfxFrame[x][y] != last_gfx_frame) + DrawLevelGraphicAnimation(x, y, graphic2); + } +#else + ResetGfxFrame(x, y, TRUE); +#endif + +#if 1 + if (ANIM_MODE(graphic) == ANIM_RANDOM && + IS_NEXT_FRAME(GfxFrame[x][y], graphic)) + ResetRandomAnimationValue(x, y); +#endif + +#if 1 + SetRandomAnimationValue(x, y); +#endif + +#if 1 + PlayLevelSoundActionIfLoop(x, y, GfxAction[x][y]); +#endif + } +#endif // -------------------- !!! TEST ONLY !!! -------------------- + +#if 0 + debug_print_timestamp(0, "- time for TEST loop: -->"); +#endif + SCAN_PLAYFIELD(x, y) { element = Feld[x][y]; @@ -10231,6 +10788,143 @@ void GameActions_RND() graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); } +#if 0 // --------------------------------------------------------------------- + + if (!IS_MOVING(x, y) && (CAN_FALL(element) || CAN_MOVE(element))) + { + StartMoving(x, y); + + element = Feld[x][y]; + graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); + + if (IS_ANIMATED(graphic) && + !IS_MOVING(x, y) && + !Stop[x][y]) + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); + + if (IS_GEM(element) || element == EL_SP_INFOTRON) + DrawTwinkleOnField(x, y); + } + else if (IS_MOVING(x, y)) + ContinueMoving(x, y); + else + { + switch (element) + { + case EL_ACID: + case EL_EXIT_OPEN: + case EL_EM_EXIT_OPEN: + case EL_SP_EXIT_OPEN: + case EL_STEEL_EXIT_OPEN: + case EL_EM_STEEL_EXIT_OPEN: + case EL_SP_TERMINAL: + case EL_SP_TERMINAL_ACTIVE: + case EL_EXTRA_TIME: + case EL_SHIELD_NORMAL: + case EL_SHIELD_DEADLY: + if (IS_ANIMATED(graphic)) + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); + break; + + case EL_DYNAMITE_ACTIVE: + case EL_EM_DYNAMITE_ACTIVE: + case EL_DYNABOMB_PLAYER_1_ACTIVE: + case EL_DYNABOMB_PLAYER_2_ACTIVE: + case EL_DYNABOMB_PLAYER_3_ACTIVE: + case EL_DYNABOMB_PLAYER_4_ACTIVE: + case EL_SP_DISK_RED_ACTIVE: + CheckDynamite(x, y); + break; + + case EL_AMOEBA_GROWING: + AmoebeWaechst(x, y); + break; + + case EL_AMOEBA_SHRINKING: + AmoebaDisappearing(x, y); + break; + +#if !USE_NEW_AMOEBA_CODE + case EL_AMOEBA_WET: + case EL_AMOEBA_DRY: + case EL_AMOEBA_FULL: + case EL_BD_AMOEBA: + case EL_EMC_DRIPPER: + AmoebeAbleger(x, y); + break; +#endif + + case EL_GAME_OF_LIFE: + case EL_BIOMAZE: + Life(x, y); + break; + + case EL_EXIT_CLOSED: + CheckExit(x, y); + break; + + case EL_EM_EXIT_CLOSED: + CheckExitEM(x, y); + break; + + case EL_STEEL_EXIT_CLOSED: + CheckExitSteel(x, y); + break; + + case EL_EM_STEEL_EXIT_CLOSED: + CheckExitSteelEM(x, y); + break; + + case EL_SP_EXIT_CLOSED: + CheckExitSP(x, y); + break; + + case EL_EXPANDABLE_WALL_GROWING: + case EL_EXPANDABLE_STEELWALL_GROWING: + MauerWaechst(x, y); + break; + + case EL_EXPANDABLE_WALL: + case EL_EXPANDABLE_WALL_HORIZONTAL: + case EL_EXPANDABLE_WALL_VERTICAL: + case EL_EXPANDABLE_WALL_ANY: + case EL_BD_EXPANDABLE_WALL: + MauerAbleger(x, y); + break; + + case EL_EXPANDABLE_STEELWALL_HORIZONTAL: + case EL_EXPANDABLE_STEELWALL_VERTICAL: + case EL_EXPANDABLE_STEELWALL_ANY: + MauerAblegerStahl(x, y); + break; + + case EL_FLAMES: + CheckForDragon(x, y); + break; + + case EL_EXPLOSION: + break; + + case EL_ELEMENT_SNAPPING: + case EL_DIAGONAL_SHRINKING: + case EL_DIAGONAL_GROWING: + { + graphic = + el_act_dir2img(GfxElement[x][y], GfxAction[x][y],GfxDir[x][y]); + + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); + break; + } + + default: + if (IS_ANIMATED(graphic) && !IS_CHANGING(x, y)) + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); + break; + } + } + +#else // --------------------------------------------------------------------- + if (!IS_MOVING(x, y) && (CAN_FALL(element) || CAN_MOVE(element))) { StartMoving(x, y); @@ -10313,6 +11007,8 @@ void GameActions_RND() else if (IS_ANIMATED(graphic) && !IS_CHANGING(x, y)) DrawLevelGraphicAnimationIfNeeded(x, y, graphic); +#endif // --------------------------------------------------------------------- + if (IS_BELT_ACTIVE(element)) PlayLevelSoundAction(x, y, ACTION_ACTIVE); @@ -10338,6 +11034,10 @@ void GameActions_RND() } } +#if 0 + debug_print_timestamp(0, "- time for MAIN loop: -->"); +#endif + #if USE_NEW_AMOEBA_CODE /* new experimental amoeba growth stuff */ if (!(FrameCounter % 8)) @@ -10521,6 +11221,11 @@ void GameActions_RND() local_player->show_envelope = 0; } +#if 0 + debug_print_timestamp(0, "stop main loop profiling "); + printf("----------------------------------------------------------\n"); +#endif + /* use random number generator in every frame to make it less predictable */ if (game.engine_version >= VERSION_IDENT(3,1,1,0)) RND(1); @@ -10575,14 +11280,19 @@ void ScrollLevel(int dx, int dy) int i, x, y; #endif +#if 0 + /* !!! THIS IS APPARENTLY WRONG FOR PLAYER RELOCATION !!! */ /* only horizontal XOR vertical scroll direction allowed */ if ((dx == 0 && dy == 0) || (dx != 0 && dy != 0)) return; +#endif #if 1 if (bitmap_db_field2 == NULL) bitmap_db_field2 = CreateBitmap(FXSIZE, FYSIZE, DEFAULT_DEPTH); + /* needed when blitting directly to same bitmap -- should not be needed with + recent SDL libraries, but apparently does not work in 1.2.11 directly */ BlitBitmap(drawto_field, bitmap_db_field2, FX + TILEX * (dx == -1) - softscroll_offset, FY + TILEY * (dy == -1) - softscroll_offset, @@ -10601,6 +11311,7 @@ void ScrollLevel(int dx, int dy) #else #if 1 + /* !!! DOES NOT WORK FOR DIAGONAL PLAYER RELOCATION !!! */ int xsize = (BX2 - BX1 + 1); int ysize = (BY2 - BY1 + 1); int start = (dx != 0 ? (dx == -1 ? BX1 : BX2) : (dy == -1 ? BY1 : BY2)); @@ -13536,9 +14247,9 @@ static void LoadEngineSnapshotValues_RND() if (game.num_random_calls != num_random_calls) { - Error(ERR_RETURN, "number of random calls out of sync"); - Error(ERR_RETURN, "number of random calls should be %d", num_random_calls); - Error(ERR_RETURN, "number of random calls is %d", game.num_random_calls); + Error(ERR_INFO, "number of random calls out of sync"); + Error(ERR_INFO, "number of random calls should be %d", num_random_calls); + Error(ERR_INFO, "number of random calls is %d", game.num_random_calls); Error(ERR_EXIT, "this should not happen -- please debug"); } }