From 90e16791f1e0e84a76cbe631629749f43f2ad725 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sun, 4 Mar 2007 03:04:55 +0100 Subject: [PATCH] rnd-20070304-1-src --- src/conftime.h | 2 +- src/editor.c | 326 +++++++++++++++++++++++++++++++++++++-------- src/game.c | 211 ++++++++++++++++++++++++++++- src/libgame/misc.c | 41 +++++- src/main.h | 17 ++- 5 files changed, 532 insertions(+), 65 deletions(-) diff --git a/src/conftime.h b/src/conftime.h index f1b3d9f6..23891440 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "2007-03-02 00:13" +#define COMPILE_DATE_STRING "2007-03-04 02:56" diff --git a/src/editor.c b/src/editor.c index 23b2dfdc..4c639397 100644 --- a/src/editor.c +++ b/src/editor.c @@ -8522,6 +8522,82 @@ static int getPillarFromOpenDirectionNotEmpty(int direction, int element_old) return (element_new != EL_EMPTY ? element_new : element_old); } +static int getOpenDirectionFromSteel2(int element) +{ + switch (element) + { + case EL_DC_STEELWALL_2_LEFT: return (MV_RIGHT); + case EL_DC_STEELWALL_2_RIGHT: return (MV_LEFT); + case EL_DC_STEELWALL_2_TOP: return (MV_DOWN); + case EL_DC_STEELWALL_2_BOTTOM: return (MV_UP); + case EL_DC_STEELWALL_2_HORIZONTAL: return (MV_HORIZONTAL); + case EL_DC_STEELWALL_2_VERTICAL: return (MV_VERTICAL); + case EL_DC_STEELWALL_2_MIDDLE: return (MV_ANY_DIRECTION); + case EL_DC_STEELWALL_2_SINGLE: return (MV_NONE); + } + + return MV_NONE; +} + +static int getSteel2FromOpenDirection(int direction) +{ + switch (direction) + { + case (MV_RIGHT): return EL_DC_STEELWALL_2_LEFT; + case (MV_LEFT): return EL_DC_STEELWALL_2_RIGHT; + case (MV_DOWN): return EL_DC_STEELWALL_2_TOP; + case (MV_UP): return EL_DC_STEELWALL_2_BOTTOM; + case (MV_HORIZONTAL): return EL_DC_STEELWALL_2_HORIZONTAL; + case (MV_VERTICAL): return EL_DC_STEELWALL_2_VERTICAL; + case (MV_ANY_DIRECTION): return EL_DC_STEELWALL_2_MIDDLE; + case (MV_NONE): return EL_DC_STEELWALL_2_SINGLE; + } + + return EL_EMPTY; +} + +static int getSteel2FromOpenDirectionNotEmpty(int direction, int element_old) +{ + int element_new = getSteel2FromOpenDirection(direction); + + return (element_new != EL_EMPTY ? element_new : element_old); +} + +static int getOpenDirectionFromChip(int element) +{ + switch (element) + { + case EL_SP_CHIP_SINGLE: return (MV_NONE); + case EL_SP_CHIP_LEFT: return (MV_RIGHT); + case EL_SP_CHIP_RIGHT: return (MV_LEFT); + case EL_SP_CHIP_TOP: return (MV_DOWN); + case EL_SP_CHIP_BOTTOM: return (MV_UP); + } + + return MV_NONE; +} + +static int getChipFromOpenDirection(int direction) +{ + switch (direction) + { + case (MV_NONE): return EL_SP_CHIP_SINGLE; + case (MV_LEFT): return EL_SP_CHIP_RIGHT; + case (MV_RIGHT): return EL_SP_CHIP_LEFT; + case (MV_UP): return EL_SP_CHIP_BOTTOM; + case (MV_DOWN): return EL_SP_CHIP_TOP; + } + + return EL_EMPTY; +} + +static int getChipFromOpenDirectionNotEmpty(int direction, int element_old) +{ + int element_new = getChipFromOpenDirection(direction); + + return (element_new != EL_EMPTY ? element_new : element_old); +} + static int getClosedTube(int x, int y) { static int xy[4][2] = @@ -8532,8 +8608,8 @@ static int getClosedTube(int x, int y) { 0, +1 } }; int element_old = IntelliDrawBuffer[x][y]; - int tube_direction_old = getOpenDirectionFromTube(element_old); - int tube_direction_new = MV_NONE; + int direction_old = getOpenDirectionFromTube(element_old); + int direction_new = MV_NONE; int i; for (i = 0; i < NUM_DIRECTIONS; i++) @@ -8544,12 +8620,12 @@ static int getClosedTube(int x, int y) int dir_opposite = MV_DIR_OPPOSITE(dir); if (IN_LEV_FIELD(xx, yy) && IS_TUBE(IntelliDrawBuffer[xx][yy]) && - (tube_direction_old & dir) && + (direction_old & dir) && (getOpenDirectionFromTube(IntelliDrawBuffer[xx][yy]) & dir_opposite)) - tube_direction_new |= dir; + direction_new |= dir; } - return getTubeFromOpenDirectionNotEmpty(tube_direction_new, element_old); + return getTubeFromOpenDirectionNotEmpty(direction_new, element_old); } static int getClosedBelt(int x, int y) @@ -8562,9 +8638,9 @@ static int getClosedBelt(int x, int y) { 0, +1 } }; int element_old = IntelliDrawBuffer[x][y]; - int belt_nr = getBeltNrFromBeltElement(element_old); - int belt_direction_old = getOpenDirectionFromBelt(element_old); - int belt_direction_new = MV_NONE; + int nr = getBeltNrFromBeltElement(element_old); + int direction_old = getOpenDirectionFromBelt(element_old); + int direction_new = MV_NONE; int i; for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; i++) @@ -8575,12 +8651,12 @@ static int getClosedBelt(int x, int y) int dir_opposite = MV_DIR_OPPOSITE(dir); if (IN_LEV_FIELD(xx, yy) && IS_BELT(IntelliDrawBuffer[xx][yy]) && - (belt_direction_old & dir) && + (direction_old & dir) && (getOpenDirectionFromBelt(IntelliDrawBuffer[xx][yy]) & dir_opposite)) - belt_direction_new |= dir; + direction_new |= dir; } - return getBeltFromNrAndOpenDirection(belt_nr, belt_direction_new); + return getBeltFromNrAndOpenDirection(nr, direction_new); } static int getClosedPool(int x, int y) @@ -8593,8 +8669,8 @@ static int getClosedPool(int x, int y) { 0, +1 } }; int element_old = IntelliDrawBuffer[x][y]; - int pool_direction_old = getOpenDirectionFromPool(element_old); - int pool_direction_new = MV_NONE; + int direction_old = getOpenDirectionFromPool(element_old); + int direction_new = MV_NONE; int i; for (i = 0; i < NUM_DIRECTIONS; i++) @@ -8606,12 +8682,12 @@ static int getClosedPool(int x, int y) if (IN_LEV_FIELD(xx, yy) && IS_ACID_POOL_OR_ACID(IntelliDrawBuffer[xx][yy]) && - (pool_direction_old & dir) && + (direction_old & dir) && (getOpenDirectionFromPool(IntelliDrawBuffer[xx][yy]) & dir_opposite)) - pool_direction_new |= dir; + direction_new |= dir; } - return getPoolFromOpenDirectionNotEmpty(pool_direction_new, element_old); + return getPoolFromOpenDirectionNotEmpty(direction_new, element_old); } static int getClosedPillar(int x, int y) @@ -8624,8 +8700,8 @@ static int getClosedPillar(int x, int y) { 0, +1 } }; int element_old = IntelliDrawBuffer[x][y]; - int pillar_direction_old = getOpenDirectionFromPillar(element_old); - int pillar_direction_new = MV_NONE; + int direction_old = getOpenDirectionFromPillar(element_old); + int direction_new = MV_NONE; int i; for (i = MV_BIT_UP; i <= MV_BIT_DOWN; i++) @@ -8636,12 +8712,72 @@ static int getClosedPillar(int x, int y) int dir_opposite = MV_DIR_OPPOSITE(dir); if (IN_LEV_FIELD(xx, yy) && IS_EMC_PILLAR(IntelliDrawBuffer[xx][yy]) && - (pillar_direction_old & dir) && + (direction_old & dir) && (getOpenDirectionFromPillar(IntelliDrawBuffer[xx][yy]) & dir_opposite)) - pillar_direction_new |= dir; + direction_new |= dir; } - return getPillarFromOpenDirectionNotEmpty(pillar_direction_new, element_old); + return getPillarFromOpenDirectionNotEmpty(direction_new, element_old); +} + +static int getClosedSteel2(int x, int y) +{ + static int xy[4][2] = + { + { -1, 0 }, + { +1, 0 }, + { 0, -1 }, + { 0, +1 } + }; + int element_old = IntelliDrawBuffer[x][y]; + int direction_old = getOpenDirectionFromSteel2(element_old); + int direction_new = MV_NONE; + int i; + + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + + if (IN_LEV_FIELD(xx, yy) && IS_DC_STEELWALL_2(IntelliDrawBuffer[xx][yy]) && + (direction_old & dir) && + (getOpenDirectionFromSteel2(IntelliDrawBuffer[xx][yy]) & dir_opposite)) + direction_new |= dir; + } + + return getSteel2FromOpenDirectionNotEmpty(direction_new, element_old); +} + +static int getClosedChip(int x, int y) +{ + static int xy[4][2] = + { + { -1, 0 }, + { +1, 0 }, + { 0, -1 }, + { 0, +1 } + }; + int element_old = IntelliDrawBuffer[x][y]; + int direction_old = getOpenDirectionFromChip(element_old); + int direction_new = MV_NONE; + int i; + + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + + if (IN_LEV_FIELD(xx, yy) && IS_SP_CHIP(IntelliDrawBuffer[xx][yy]) && + (direction_old & dir) && + (getOpenDirectionFromChip(IntelliDrawBuffer[xx][yy]) & dir_opposite)) + direction_new |= dir; + } + + return getChipFromOpenDirectionNotEmpty(direction_new, element_old); } static void SetElementSimple(int x, int y, int element, boolean change_level) @@ -8704,7 +8840,7 @@ static void SetElementIntelliDraw(int x, int y, int new_element, int direction = MV_NONE; int i; - /* if existing element is tube, keep all existing tube directions */ + /* if old element is of same kind, keep all existing directions */ if (IS_TUBE(old_element)) direction |= getOpenDirectionFromTube(old_element); @@ -8742,7 +8878,7 @@ static void SetElementIntelliDraw(int x, int y, int new_element, int direction = MV_NONE; int i; - /* if existing element is belt, keep all existing belt directions */ + /* if old element is of same kind, keep all existing directions */ if (IS_BELT(old_element)) direction |= getOpenDirectionFromBelt(old_element); @@ -8780,7 +8916,7 @@ static void SetElementIntelliDraw(int x, int y, int new_element, int direction = MV_NONE; int i; - /* if existing element is pool, keep all existing pool directions */ + /* if old element is of same kind, keep all existing directions */ if (IS_ACID_POOL_OR_ACID(old_element)) direction |= getOpenDirectionFromPool(old_element); @@ -8804,42 +8940,13 @@ static void SetElementIntelliDraw(int x, int y, int new_element, } } -#if 1 - int foo = last_element_new; - - if (foo == EL_EMPTY) - foo = EL_ACID; - - if (last_element_new == EL_EMPTY) - last_element_new = old_element; - - if (last_element_new != EL_UNDEFINED) - new_element = getPoolFromOpenDirectionNotEmpty(direction, - foo); - else - new_element = getPoolFromOpenDirectionNotEmpty(direction, new_element); - -#else - -#if 0 + /* special corrections needed for intuitively correct acid pool drawing */ if (last_element_new == EL_EMPTY) last_element_new = new_element; -#else - if (last_element_new == EL_EMPTY) - last_element_new = EL_ACID; -#endif + else if (last_element_new != EL_UNDEFINED) + new_element = last_element_new; -#if 1 - if (last_element_new != EL_UNDEFINED) - new_element = getPoolFromOpenDirectionNotEmpty(direction, - last_element_new); - else - new_element = getPoolFromOpenDirectionNotEmpty(direction, new_element); -#else new_element = getPoolFromOpenDirectionNotEmpty(direction, new_element); -#endif - -#endif if (last_element_new != EL_UNDEFINED) MergeAndCloseNeighbourElements(x, y, &new_element, @@ -8852,7 +8959,7 @@ static void SetElementIntelliDraw(int x, int y, int new_element, int direction = MV_NONE; int i; - /* if existing element is pillar, keep all existing pillar directions */ + /* if old element is of same kind, keep all existing directions */ if (IS_EMC_PILLAR(old_element)) direction |= getOpenDirectionFromPillar(old_element); @@ -8883,6 +8990,107 @@ static void SetElementIntelliDraw(int x, int y, int new_element, last_x, last_y, &last_element_new, getClosedPillar, change_level); } + else if (IS_DC_STEELWALL_2(new_element)) + { + int last_element_new = EL_UNDEFINED; + int direction = MV_NONE; + int i; + + /* if old element is of same kind, keep all existing directions */ + if (IS_DC_STEELWALL_2(old_element)) + direction |= getOpenDirectionFromSteel2(old_element); + + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + + if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && + IS_DC_STEELWALL_2(IntelliDrawBuffer[last_x][last_y])) + { + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + int last_element_old = IntelliDrawBuffer[last_x][last_y]; + int last_direction_old = getOpenDirectionFromSteel2(last_element_old); + int last_direction_new = last_direction_old | dir_opposite; + + last_element_new = getSteel2FromOpenDirection(last_direction_new); + + direction |= dir; + } + } + + new_element = getSteel2FromOpenDirectionNotEmpty(direction, new_element); + + if (last_element_new != EL_UNDEFINED) + MergeAndCloseNeighbourElements(x, y, &new_element, + last_x, last_y, &last_element_new, + getClosedSteel2, change_level); + } + else if (IS_SP_CHIP(new_element)) + { + int last_element_new = EL_UNDEFINED; + int direction = MV_NONE; + int i; + + /* (do not keep existing directions, regardless of kind of old element) */ + + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + + if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && + IS_SP_CHIP(IntelliDrawBuffer[last_x][last_y])) + { + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + int last_element_old = IntelliDrawBuffer[last_x][last_y]; + int last_direction_old = getOpenDirectionFromChip(last_element_old); + int last_direction_new = last_direction_old | dir_opposite; + + if (last_direction_old == MV_NONE) + { + last_element_new = getChipFromOpenDirection(last_direction_new); + direction |= dir; + } + else if (last_direction_old & (dir | dir_opposite)) + { + direction |= MV_DIR_OPPOSITE(last_direction_old); + } + else + { + direction |= MV_DIR_OPPOSITE(dir); + } + } + } + + new_element = getChipFromOpenDirectionNotEmpty(direction, new_element); + + if (last_element_new != EL_UNDEFINED) + MergeAndCloseNeighbourElements(x, y, &new_element, + last_x, last_y, &last_element_new, + getClosedChip, change_level); + } + else if (IS_SP_HARDWARE_BASE(new_element)) + { + int nr = GetSimpleRandom(6); + + new_element = (nr == 0 ? EL_SP_HARDWARE_BASE_1 : + nr == 1 ? EL_SP_HARDWARE_BASE_2 : + nr == 2 ? EL_SP_HARDWARE_BASE_3 : + nr == 3 ? EL_SP_HARDWARE_BASE_4 : + nr == 4 ? EL_SP_HARDWARE_BASE_5 : EL_SP_HARDWARE_BASE_6); + } + else if (new_element == EL_SP_HARDWARE_GREEN || + new_element == EL_SP_HARDWARE_BLUE || + new_element == EL_SP_HARDWARE_RED) + { + int nr = GetSimpleRandom(3); + + new_element = (nr == 0 ? EL_SP_HARDWARE_GREEN : + nr == 1 ? EL_SP_HARDWARE_BLUE : EL_SP_HARDWARE_RED); + } else if (IS_BELT_SWITCH(old_element)) { int belt_nr = getBeltNrFromBeltSwitchElement(old_element); @@ -9563,8 +9771,8 @@ static void RandomPlacement(int new_element) { while (num_elements > 0) { - x = RND(lev_fieldx); - y = RND(lev_fieldy); + x = GetSimpleRandom(lev_fieldx); + y = GetSimpleRandom(lev_fieldy); /* don't place element at the same position twice */ if (free_position[x][y]) diff --git a/src/game.c b/src/game.c index afa0f24f..a52780cb 100644 --- a/src/game.c +++ b/src/game.c @@ -10107,13 +10107,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 +10190,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 +10290,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 +10509,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 +10536,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 +10723,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); diff --git a/src/libgame/misc.c b/src/libgame/misc.c index 41b68190..e0e8a0ff 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -2805,10 +2805,46 @@ void NotifyUserAboutErrorFile() #if DEBUG -#define DEBUG_NUM_TIMESTAMPS 3 +#define DEBUG_NUM_TIMESTAMPS 3 +#define DEBUG_TIME_IN_MICROSECONDS 1 + +#if DEBUG_TIME_IN_MICROSECONDS +static double Counter_Microseconds() +{ + static struct timeval base_time = { 0, 0 }; + struct timeval current_time; + double counter; + + gettimeofday(¤t_time, NULL); + + /* reset base time in case of wrap-around */ + if (current_time.tv_sec < base_time.tv_sec) + base_time = current_time; + + counter = + ((double)(current_time.tv_sec - base_time.tv_sec)) * 1000000 + + ((double)(current_time.tv_usec - base_time.tv_usec)); + + return counter; /* return microseconds since last init */ +} +#endif void debug_print_timestamp(int counter_nr, char *message) { +#if DEBUG_TIME_IN_MICROSECONDS + static double counter[DEBUG_NUM_TIMESTAMPS][2]; + + if (counter_nr >= DEBUG_NUM_TIMESTAMPS) + Error(ERR_EXIT, "debugging: increase DEBUG_NUM_TIMESTAMPS in misc.c"); + + counter[counter_nr][0] = Counter_Microseconds(); + + if (message) + printf("%s %.3f ms\n", message, + (counter[counter_nr][0] - counter[counter_nr][1]) / 1000); + + counter[counter_nr][1] = counter[counter_nr][0]; +#else static long counter[DEBUG_NUM_TIMESTAMPS][2]; if (counter_nr >= DEBUG_NUM_TIMESTAMPS) @@ -2817,10 +2853,11 @@ void debug_print_timestamp(int counter_nr, char *message) counter[counter_nr][0] = Counter(); if (message) - printf("%s %.3f seconds\n", message, + printf("%s %.3f s\n", message, (float)(counter[counter_nr][0] - counter[counter_nr][1]) / 1000); counter[counter_nr][1] = counter[counter_nr][0]; +#endif } void debug_print_parent_only(char *format, ...) diff --git a/src/main.h b/src/main.h index 2be92c6b..3137db79 100644 --- a/src/main.h +++ b/src/main.h @@ -698,7 +698,22 @@ #define IS_ACID_POOL_OR_ACID(e) (IS_ACID_POOL(e) || (e) == EL_ACID) -#define IS_EMC_PILLAR(e) ((e) >= EL_EMC_WALL_1 && (e) <= EL_EMC_WALL_3) +#define IS_EMC_PILLAR(e) ((e) >= EL_EMC_WALL_1 && \ + (e) <= EL_EMC_WALL_3) +#define IS_SP_CHIP(e) ((e) == EL_SP_CHIP_SINGLE || \ + (e) == EL_SP_CHIP_LEFT || \ + (e) == EL_SP_CHIP_RIGHT || \ + (e) == EL_SP_CHIP_TOP || \ + (e) == EL_SP_CHIP_BOTTOM) +#define IS_SP_HARDWARE_BASE(e) ((e) == EL_SP_HARDWARE_BASE_1 || \ + (e) == EL_SP_HARDWARE_BASE_2 || \ + (e) == EL_SP_HARDWARE_BASE_3 || \ + (e) == EL_SP_HARDWARE_BASE_4 || \ + (e) == EL_SP_HARDWARE_BASE_5 || \ + (e) == EL_SP_HARDWARE_BASE_6) + +#define IS_DC_STEELWALL_2(e) ((e) >= EL_DC_STEELWALL_2_LEFT && \ + (e) <= EL_DC_STEELWALL_2_SINGLE) #define GFX_ELEMENT(e) (element_info[e].use_gfx_element ? \ element_info[e].gfx_element : e) -- 2.34.1