X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=15841b17a993c0c85060d5d0ab64fd5203bb3801;hb=d8e3568accbc475855027f7199e55543dc4d1ddf;hp=e83389da479bb24df3fb4b120dd54470c6388e7b;hpb=d4758d12db28cd36edca33c9c7ab05476a8f85e7;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index e83389da..15841b17 100644 --- a/src/tools.c +++ b/src/tools.c @@ -123,7 +123,12 @@ void SetDrawtoField(int mode) void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height) { - if (game_status == GAME_MODE_PLAYING && !game.envelope_active) + if (game_status == GAME_MODE_PLAYING && + level.game_engine_type == GAME_ENGINE_TYPE_EM) + { + BlitScreenToBitmap_EM(backbuffer); + } + else if (game_status == GAME_MODE_PLAYING && !game.envelope_active) { if (force_redraw) { @@ -721,26 +726,29 @@ inline static void DrawGraphicShiftedNormal(int x, int y, int dx, int dy, } #endif - getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y); + if (width > 0 && height > 0) + { + getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y); - src_x += cx; - src_y += cy; + src_x += cx; + src_y += cy; - dst_x = FX + x * TILEX + dx; - dst_y = FY + y * TILEY + dy; + dst_x = FX + x * TILEX + dx; + dst_y = FY + y * TILEY + dy; - if (mask_mode == USE_MASKING) - { - SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc, - dst_x - src_x, dst_y - src_y); - BlitBitmapMasked(src_bitmap, drawto_field, src_x, src_y, width, height, - dst_x, dst_y); - } - else - BlitBitmap(src_bitmap, drawto_field, src_x, src_y, width, height, - dst_x, dst_y); + if (mask_mode == USE_MASKING) + { + SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc, + dst_x - src_x, dst_y - src_y); + BlitBitmapMasked(src_bitmap, drawto_field, src_x, src_y, width, height, + dst_x, dst_y); + } + else + BlitBitmap(src_bitmap, drawto_field, src_x, src_y, width, height, + dst_x, dst_y); - MarkTileDirty(x, y); + MarkTileDirty(x, y); + } } inline static void DrawGraphicShiftedDouble(int x, int y, int dx, int dy, @@ -802,6 +810,12 @@ inline static void DrawGraphicShiftedDouble(int x, int y, int dx, int dy, MarkTileDirty(x2, y2); } + +#if 0 + printf("::: DONE DrawGraphicShiftedDouble"); + BackToFront(); + Delay(1000); +#endif } static void DrawGraphicShifted(int x, int y, int dx, int dy, @@ -1998,13 +2012,39 @@ void DrawPlayer(struct PlayerInfo *player) if (player->is_pushing && player_is_moving) #endif { +#if 1 + int px = SCREENX(jx), py = SCREENY(jy); + int pxx = (TILEX - ABS(sxx)) * dx; + int pyy = (TILEY - ABS(syy)) * dy; +#else int px = SCREENX(next_jx), py = SCREENY(next_jy); + int pxx = sxx; + int pyy = syy; +#endif + +#if 1 + int graphic; + int frame; + + if (!IS_MOVING(jx, jy)) /* push movement already finished */ + element = Feld[next_jx][next_jy]; + + graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir); + frame = getGraphicAnimationFrame(graphic, player->StepFrame); + /* draw background element under pushed element (like the Sokoban field) */ if (Back[next_jx][next_jy]) DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]); - if ((sxx || syy) && element == EL_SOKOBAN_OBJECT) - DrawGraphicShiftedThruMask(px, py, sxx, syy, IMG_SOKOBAN_OBJECT, 0, + /* masked drawing is needed for EMC style (double) movement graphics */ + DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame, NO_CUTTING); + +#else + if (Back[next_jx][next_jy]) + DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]); + + if ((pxx || pyy) && element == EL_SOKOBAN_OBJECT) + DrawGraphicShiftedThruMask(px, py, pxx, pyy, IMG_SOKOBAN_OBJECT, 0, NO_CUTTING); else { @@ -2016,9 +2056,16 @@ void DrawPlayer(struct PlayerInfo *player) int frame = getGraphicAnimationFrame(graphic, player->Frame); #endif - DrawGraphicShifted(px, py, sxx, syy, graphic, frame, +#if 1 + /* masked drawing is needed for EMC style (double) movement graphics */ + DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame, + NO_CUTTING); +#else + DrawGraphicShifted(px, py, pxx, pyy, graphic, frame, NO_CUTTING, NO_MASKING); +#endif } +#endif } /* ----------------------------------------------------------------------- */ @@ -2177,6 +2224,12 @@ boolean Request(char *text, unsigned int req_state) } } +#if 1 + if (game_status == GAME_MODE_PLAYING && + level.game_engine_type == GAME_ENGINE_TYPE_EM) + BlitScreenToBitmap_EM(backbuffer); +#endif + #if 1 /* disable deactivated drawing when quick-loading level tape recording */ if (tape.playing && tape.deactivate_display) @@ -2968,7 +3021,7 @@ static void HandleToolButtons(struct GadgetInfo *gi) #if 1 -static struct +static struct Mapping_EM_to_RND_object { int element_em; boolean is_rnd_to_em_mapping; /* unique mapping EM <-> RND */ @@ -2978,18 +3031,18 @@ static struct int action; int direction; } -mapping_EM_to_RND_list[] = +em_object_mapping_list[] = { { Xblank, TRUE, FALSE, EL_EMPTY, -1, -1 }, { - Yacid_splash_eB, FALSE, TRUE, + Yacid_splash_eB, FALSE, FALSE, EL_ACID_SPLASH_RIGHT, -1, -1 }, { - Yacid_splash_wB, FALSE, TRUE, + Yacid_splash_wB, FALSE, FALSE, EL_ACID_SPLASH_LEFT, -1, -1 }, @@ -3797,19 +3850,19 @@ mapping_EM_to_RND_list[] = EL_EMC_GRASS, -1, -1 }, { - Ygrass_nB, FALSE, TRUE, + Ygrass_nB, FALSE, FALSE, EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_UP }, { - Ygrass_eB, FALSE, TRUE, + Ygrass_eB, FALSE, FALSE, EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_RIGHT }, { - Ygrass_sB, FALSE, TRUE, + Ygrass_sB, FALSE, FALSE, EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_DOWN }, { - Ygrass_wB, FALSE, TRUE, + Ygrass_wB, FALSE, FALSE, EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_LEFT }, { @@ -3817,19 +3870,19 @@ mapping_EM_to_RND_list[] = EL_SAND, -1, -1 }, { - Ydirt_nB, FALSE, TRUE, + Ydirt_nB, FALSE, FALSE, EL_SAND, ACTION_DIGGING, MV_BIT_UP }, { - Ydirt_eB, FALSE, TRUE, + Ydirt_eB, FALSE, FALSE, EL_SAND, ACTION_DIGGING, MV_BIT_RIGHT }, { - Ydirt_sB, FALSE, TRUE, + Ydirt_sB, FALSE, FALSE, EL_SAND, ACTION_DIGGING, MV_BIT_DOWN }, { - Ydirt_wB, FALSE, TRUE, + Ydirt_wB, FALSE, FALSE, EL_SAND, ACTION_DIGGING, MV_BIT_LEFT }, { @@ -3889,7 +3942,7 @@ mapping_EM_to_RND_list[] = EL_EMC_MAGIC_BALL, -1, -1 }, { - Xball_1B, FALSE, TRUE, + Xball_1B, FALSE, FALSE, EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1 }, { @@ -3897,13 +3950,61 @@ mapping_EM_to_RND_list[] = EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1 }, { - Xball_2B, FALSE, TRUE, + Xball_2B, FALSE, FALSE, EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1 }, { Yball_eat, FALSE, FALSE, EL_EMC_MAGIC_BALL, ACTION_DROPPING, -1 }, + { + Ykey_1_eat, FALSE, FALSE, + EL_EM_KEY_1, ACTION_COLLECTING, -1 + }, + { + Ykey_2_eat, FALSE, FALSE, + EL_EM_KEY_2, ACTION_COLLECTING, -1 + }, + { + Ykey_3_eat, FALSE, FALSE, + EL_EM_KEY_3, ACTION_COLLECTING, -1 + }, + { + Ykey_4_eat, FALSE, FALSE, + EL_EM_KEY_4, ACTION_COLLECTING, -1 + }, + { + Ykey_5_eat, FALSE, FALSE, + EL_EM_KEY_5, ACTION_COLLECTING, -1 + }, + { + Ykey_6_eat, FALSE, FALSE, + EL_EM_KEY_6, ACTION_COLLECTING, -1 + }, + { + Ykey_7_eat, FALSE, FALSE, + EL_EM_KEY_7, ACTION_COLLECTING, -1 + }, + { + Ykey_8_eat, FALSE, FALSE, + EL_EM_KEY_8, ACTION_COLLECTING, -1 + }, + { + Ylenses_eat, FALSE, FALSE, + EL_EMC_LENSES, ACTION_COLLECTING, -1 + }, + { + Ymagnify_eat, FALSE, FALSE, + EL_EMC_MAGNIFIER, ACTION_COLLECTING, -1 + }, + { + Ygrass_eat, FALSE, FALSE, + EL_EMC_GRASS, ACTION_SNAPPING, -1 + }, + { + Ydirt_eat, FALSE, FALSE, + EL_SAND, ACTION_SNAPPING, -1 + }, { Xgrow_ns, TRUE, FALSE, EL_EXPANDABLE_WALL_VERTICAL, -1, -1 @@ -3945,7 +4046,7 @@ mapping_EM_to_RND_list[] = EL_AMOEBA_DRY, ACTION_OTHER, -1 }, { - Xamoeba_5, FALSE, FALSE, + Xamoeba_5, TRUE, FALSE, EL_AMOEBA_WET, ACTION_OTHER, -1 }, { @@ -4576,6 +4677,128 @@ mapping_EM_to_RND_list[] = } }; +static struct Mapping_EM_to_RND_player +{ + int action_em; + int player_nr; + + int element_rnd; + int action; + int direction; +} +em_player_mapping_list[] = +{ + { + SPR_walk + 0, 0, + EL_PLAYER_1, ACTION_MOVING, MV_BIT_UP, + }, + { + SPR_walk + 1, 0, + EL_PLAYER_1, ACTION_MOVING, MV_BIT_RIGHT, + }, + { + SPR_walk + 2, 0, + EL_PLAYER_1, ACTION_MOVING, MV_BIT_DOWN, + }, + { + SPR_walk + 3, 0, + EL_PLAYER_1, ACTION_MOVING, MV_BIT_LEFT, + }, + { + SPR_push + 0, 0, + EL_PLAYER_1, ACTION_PUSHING, MV_BIT_UP, + }, + { + SPR_push + 1, 0, + EL_PLAYER_1, ACTION_PUSHING, MV_BIT_RIGHT, + }, + { + SPR_push + 2, 0, + EL_PLAYER_1, ACTION_PUSHING, MV_BIT_DOWN, + }, + { + SPR_push + 3, 0, + EL_PLAYER_1, ACTION_PUSHING, MV_BIT_LEFT, + }, + { + SPR_spray + 0, 0, + EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_UP, + }, + { + SPR_spray + 1, 0, + EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_RIGHT, + }, + { + SPR_spray + 2, 0, + EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_DOWN, + }, + { + SPR_spray + 3, 0, + EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_LEFT, + }, + { + SPR_walk + 0, 1, + EL_PLAYER_2, ACTION_MOVING, MV_BIT_UP, + }, + { + SPR_walk + 1, 1, + EL_PLAYER_2, ACTION_MOVING, MV_BIT_RIGHT, + }, + { + SPR_walk + 2, 1, + EL_PLAYER_2, ACTION_MOVING, MV_BIT_DOWN, + }, + { + SPR_walk + 3, 1, + EL_PLAYER_2, ACTION_MOVING, MV_BIT_LEFT, + }, + { + SPR_push + 0, 1, + EL_PLAYER_2, ACTION_PUSHING, MV_BIT_UP, + }, + { + SPR_push + 1, 1, + EL_PLAYER_2, ACTION_PUSHING, MV_BIT_RIGHT, + }, + { + SPR_push + 2, 1, + EL_PLAYER_2, ACTION_PUSHING, MV_BIT_DOWN, + }, + { + SPR_push + 3, 1, + EL_PLAYER_2, ACTION_PUSHING, MV_BIT_LEFT, + }, + { + SPR_spray + 0, 1, + EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_UP, + }, + { + SPR_spray + 1, 1, + EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_RIGHT, + }, + { + SPR_spray + 2, 1, + EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_DOWN, + }, + { + SPR_spray + 3, 1, + EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_LEFT, + }, + { + SPR_still, 0, + EL_PLAYER_1, ACTION_DEFAULT, -1, + }, + { + SPR_still, 1, + EL_PLAYER_2, ACTION_DEFAULT, -1, + }, + + { + -1, -1, + -1, -1, -1 + } +}; + int map_element_RND_to_EM(int element_rnd) { static unsigned short mapping_RND_to_EM[NUM_FILE_ELEMENTS]; @@ -4589,10 +4812,10 @@ int map_element_RND_to_EM(int element_rnd) for (i = 0; i < NUM_FILE_ELEMENTS; i++) mapping_RND_to_EM[i] = Xalpha_quest; - for (i = 0; mapping_EM_to_RND_list[i].element_em != -1; i++) - if (mapping_EM_to_RND_list[i].is_rnd_to_em_mapping) - mapping_RND_to_EM[mapping_EM_to_RND_list[i].element_rnd] = - mapping_EM_to_RND_list[i].element_em; + for (i = 0; em_object_mapping_list[i].element_em != -1; i++) + if (em_object_mapping_list[i].is_rnd_to_em_mapping) + mapping_RND_to_EM[em_object_mapping_list[i].element_rnd] = + em_object_mapping_list[i].element_em; mapping_initialized = TRUE; } @@ -4618,9 +4841,9 @@ int map_element_EM_to_RND(int element_em) for (i = 0; i < TILE_MAX; i++) mapping_EM_to_RND[i] = EL_UNKNOWN; - for (i = 0; mapping_EM_to_RND_list[i].element_em != -1; i++) - mapping_EM_to_RND[mapping_EM_to_RND_list[i].element_em] = - mapping_EM_to_RND_list[i].element_rnd; + for (i = 0; em_object_mapping_list[i].element_em != -1; i++) + mapping_EM_to_RND[em_object_mapping_list[i].element_em] = + em_object_mapping_list[i].element_rnd; mapping_initialized = TRUE; } @@ -4842,7 +5065,7 @@ int map_element_EM_to_RND(int element_em) int element_em; int element_rnd; } - mapping_EM_to_RND_list[] = + em_object_mapping_list[] = { { Xblank, EL_EMPTY }, { Yacid_splash_eB, EL_EMPTY }, @@ -5250,9 +5473,9 @@ int map_element_EM_to_RND(int element_em) for (i = 0; i < TILE_MAX; i++) mapping_EM_to_RND[i] = EL_UNKNOWN; - for (i = 0; mapping_EM_to_RND_list[i].element_em != -1; i++) - mapping_EM_to_RND[mapping_EM_to_RND_list[i].element_em] = - mapping_EM_to_RND_list[i].element_rnd; + for (i = 0; em_object_mapping_list[i].element_em != -1; i++) + mapping_EM_to_RND[em_object_mapping_list[i].element_em] = + em_object_mapping_list[i].element_rnd; mapping_initialized = TRUE; } @@ -5283,21 +5506,51 @@ int get_next_element(int element) } } +#if 0 +int el_act_dir2img(int element, int action, int direction) +{ + element = GFX_ELEMENT(element); + + if (direction == MV_NO_MOVING) + return element_info[element].graphic[action]; + + direction = MV_DIR_BIT(direction); + + return element_info[element].direction_graphic[action][direction]; +} +#else int el_act_dir2img(int element, int action, int direction) { element = GFX_ELEMENT(element); direction = MV_DIR_BIT(direction); /* default: MV_NO_MOVING => MV_DOWN */ + /* direction_graphic[][] == graphic[] for undefined direction graphics */ return element_info[element].direction_graphic[action][direction]; } +#endif + +#if 0 +static int el_act_dir2crm(int element, int action, int direction) +{ + element = GFX_ELEMENT(element); + + if (direction == MV_NO_MOVING) + return element_info[element].crumbled[action]; + + direction = MV_DIR_BIT(direction); + return element_info[element].direction_crumbled[action][direction]; +} +#else static int el_act_dir2crm(int element, int action, int direction) { element = GFX_ELEMENT(element); direction = MV_DIR_BIT(direction); /* default: MV_NO_MOVING => MV_DOWN */ + /* direction_graphic[][] == graphic[] for undefined direction graphics */ return element_info[element].direction_crumbled[action][direction]; } +#endif int el_act2img(int element, int action) { @@ -5348,8 +5601,17 @@ int el2preimg(int element) int getGameFrameDelay_EM(int native_em_game_frame_delay) { - return (GameFrameDelay == GAME_FRAME_DELAY ? native_em_game_frame_delay : - GameFrameDelay); + int game_frame_delay_value; + + game_frame_delay_value = + (tape.playing && tape.fast_forward ? FfwdFrameDelay : + GameFrameDelay == GAME_FRAME_DELAY ? native_em_game_frame_delay : + GameFrameDelay); + + if (tape.playing && tape.warp_forward && !tape.pausing) + game_frame_delay_value = 0; + + return game_frame_delay_value; } unsigned int InitRND(long seed) @@ -5360,43 +5622,78 @@ unsigned int InitRND(long seed) return InitEngineRND(seed); } +#define DEBUG_EM_GFX 0 + void InitGraphicInfo_EM(void) { - int mapping_EM_to_RND_element[TILE_MAX]; - int mapping_EM_to_RND_action[TILE_MAX]; - int mapping_EM_to_RND_direction[TILE_MAX]; - boolean mapping_EM_to_RND_backside[TILE_MAX]; - int i, j; + struct Mapping_EM_to_RND_object object_mapping[TILE_MAX]; + struct Mapping_EM_to_RND_player player_mapping[2][SPR_MAX]; + int i, j, p; + +#if DEBUG_EM_GFX + if (graphic_info_em_object[0][0].bitmap == NULL) + { + /* EM graphics not yet initialized in em_open_all() */ + + return; + } +#endif - /* return "EL_UNKNOWN" for all undefined elements in mapping array */ + /* always start with reliable default values */ for (i = 0; i < TILE_MAX; i++) { - mapping_EM_to_RND_element[i] = EL_UNKNOWN; - mapping_EM_to_RND_backside[i] = FALSE; - mapping_EM_to_RND_action[i] = ACTION_DEFAULT; - mapping_EM_to_RND_direction[i] = MV_NO_MOVING; + object_mapping[i].element_rnd = EL_UNKNOWN; + object_mapping[i].is_backside = FALSE; + object_mapping[i].action = ACTION_DEFAULT; + object_mapping[i].direction = MV_NO_MOVING; } - for (i = 0; mapping_EM_to_RND_list[i].element_em != -1; i++) + /* always start with reliable default values */ + for (p = 0; p < 2; p++) { - int e = mapping_EM_to_RND_list[i].element_em; + for (i = 0; i < SPR_MAX; i++) + { + player_mapping[p][i].element_rnd = EL_UNKNOWN; + player_mapping[p][i].action = ACTION_DEFAULT; + player_mapping[p][i].direction = MV_NO_MOVING; + } + } + + for (i = 0; em_object_mapping_list[i].element_em != -1; i++) + { + int e = em_object_mapping_list[i].element_em; + + object_mapping[e].element_rnd = em_object_mapping_list[i].element_rnd; + object_mapping[e].is_backside = em_object_mapping_list[i].is_backside; + + if (em_object_mapping_list[i].action != -1) + object_mapping[e].action = em_object_mapping_list[i].action; - mapping_EM_to_RND_element[e] = mapping_EM_to_RND_list[i].element_rnd; - mapping_EM_to_RND_backside[e] = mapping_EM_to_RND_list[i].is_backside; + if (em_object_mapping_list[i].direction != -1) + object_mapping[e].direction = (1 << em_object_mapping_list[i].direction); + } + + for (i = 0; em_player_mapping_list[i].action_em != -1; i++) + { + int a = em_player_mapping_list[i].action_em; + int p = em_player_mapping_list[i].player_nr; + + player_mapping[p][a].element_rnd = em_player_mapping_list[i].element_rnd; - if (mapping_EM_to_RND_list[i].action != -1) - mapping_EM_to_RND_action[e] = mapping_EM_to_RND_list[i].action; + if (em_player_mapping_list[i].action != -1) + player_mapping[p][a].action = em_player_mapping_list[i].action; - if (mapping_EM_to_RND_list[i].direction != -1) - mapping_EM_to_RND_direction[e] = 1<< mapping_EM_to_RND_list[i].direction; + if (em_player_mapping_list[i].direction != -1) + player_mapping[p][a].direction = + (1 << em_player_mapping_list[i].direction); } for (i = 0; i < TILE_MAX; i++) { - int element = mapping_EM_to_RND_element[i]; - int action = mapping_EM_to_RND_action[i]; - int direction = mapping_EM_to_RND_direction[i]; - int backside = mapping_EM_to_RND_backside[i]; + int element = object_mapping[i].element_rnd; + int action = object_mapping[i].action; + int direction = object_mapping[i].direction; + boolean is_backside = object_mapping[i].is_backside; boolean action_removing = (action == ACTION_DIGGING || action == ACTION_SNAPPING || action == ACTION_COLLECTING); @@ -5409,8 +5706,9 @@ void InitGraphicInfo_EM(void) for (j = 0; j < 8; j++) { - int effective_element = (j < 7 ? element : - i == Ynut_sB ? element : + int effective_element = (j > 5 && i == Yacid_splash_eB ? EL_EMPTY : + j > 5 && i == Yacid_splash_wB ? EL_EMPTY : + j < 7 ? element : i == Xdrip_stretch ? element : i == Xdrip_stretchB ? element : i == Ydrip_s1 ? element : @@ -5419,15 +5717,28 @@ void InitGraphicInfo_EM(void) i == Xball_2 ? element : i == Xball_2B ? element : i == Yball_eat ? element : + i == Ykey_1_eat ? element : + i == Ykey_2_eat ? element : + i == Ykey_3_eat ? element : + i == Ykey_4_eat ? element : + i == Ykey_5_eat ? element : + i == Ykey_6_eat ? element : + i == Ykey_7_eat ? element : + i == Ykey_8_eat ? element : + i == Ylenses_eat ? element : + i == Ymagnify_eat ? element : + i == Ygrass_eat ? element : + i == Ydirt_eat ? element : i == Yspring_kill_e ? EL_SPRING : i == Yspring_kill_w ? EL_SPRING : i == Yemerald_stone ? EL_EMERALD : i == Ydiamond_stone ? EL_ROCK : - backside ? EL_EMPTY : + i == Xsand_stonein_4 ? EL_EMPTY : + i == Xsand_stoneout_2 ? EL_ROCK : + is_backside ? EL_EMPTY : action_removing ? EL_EMPTY : element); int effective_action = (j < 7 ? action : - i == Ynut_sB ? action : i == Xdrip_stretch ? action : i == Xdrip_stretchB ? action : i == Ydrip_s1 ? action : @@ -5436,6 +5747,18 @@ void InitGraphicInfo_EM(void) i == Xball_2 ? action : i == Xball_2B ? action : i == Yball_eat ? action : + i == Ykey_1_eat ? action : + i == Ykey_2_eat ? action : + i == Ykey_3_eat ? action : + i == Ykey_4_eat ? action : + i == Ykey_5_eat ? action : + i == Ykey_6_eat ? action : + i == Ykey_7_eat ? action : + i == Ykey_8_eat ? action : + i == Ylenses_eat ? action : + i == Ymagnify_eat ? action : + i == Ygrass_eat ? action : + i == Ydirt_eat ? action : i == Xsand_stonein_1 ? action : i == Xsand_stonein_2 ? action : i == Xsand_stonein_3 ? action : @@ -5447,29 +5770,49 @@ void InitGraphicInfo_EM(void) action_active ? action : action_other ? action : ACTION_DEFAULT); - int graphic = (direction == MV_NO_MOVING ? - el_act2img(effective_element, effective_action) : - el_act_dir2img(effective_element, effective_action, + int graphic = (el_act_dir2img(effective_element, effective_action, direction)); + int crumbled = (el_act_dir2crm(effective_element, effective_action, + direction)); + int base_graphic = el_act2img(effective_element, ACTION_DEFAULT); + int base_crumbled = el_act2crm(effective_element, ACTION_DEFAULT); + boolean has_crumbled_graphics = (base_crumbled != base_graphic); struct GraphicInfo *g = &graphic_info[graphic]; - struct GraphicInfo_EM *g_em = &graphic_info_em[i][7 - j]; + struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][7 - j]; Bitmap *src_bitmap; int src_x, src_y; + /* ensure to get symmetric 3-frame, 2-delay animations as used in EM */ + boolean special_animation = (action != ACTION_DEFAULT && + g->anim_frames == 3 && + g->anim_delay == 2 && + g->anim_mode & ANIM_LINEAR); int sync_frame = (i == Xdrip_stretch ? 7 : i == Xdrip_stretchB ? 7 : i == Ydrip_s2 ? j + 8 : i == Ydrip_s2B ? j + 8 : i == Xacid_1 ? 0 : - i == Xacid_2 ? 1 : - i == Xacid_3 ? 2 : - i == Xacid_4 ? 3 : - i == Xacid_5 ? 4 : - i == Xacid_6 ? 5 : - i == Xacid_7 ? 6 : - i == Xacid_8 ? 7 : + i == Xacid_2 ? 10 : + i == Xacid_3 ? 20 : + i == Xacid_4 ? 30 : + i == Xacid_5 ? 40 : + i == Xacid_6 ? 50 : + i == Xacid_7 ? 60 : + i == Xacid_8 ? 70 : i == Xball_2 ? 7 : i == Xball_2B ? j + 8 : i == Yball_eat ? j + 1 : + i == Ykey_1_eat ? j + 1 : + i == Ykey_2_eat ? j + 1 : + i == Ykey_3_eat ? j + 1 : + i == Ykey_4_eat ? j + 1 : + i == Ykey_5_eat ? j + 1 : + i == Ykey_6_eat ? j + 1 : + i == Ykey_7_eat ? j + 1 : + i == Ykey_8_eat ? j + 1 : + i == Ylenses_eat ? j + 1 : + i == Ymagnify_eat ? j + 1 : + i == Ygrass_eat ? j + 1 : + i == Ydirt_eat ? j + 1 : i == Xamoeba_1 ? 0 : i == Xamoeba_2 ? 1 : i == Xamoeba_3 ? 2 : @@ -5481,57 +5824,64 @@ void InitGraphicInfo_EM(void) i == Xexit_2 ? j + 8 : i == Xexit_3 ? j + 16 : i == Xdynamite_1 ? 0 : - i == Xdynamite_2 ? 2 : - i == Xdynamite_3 ? 4 : - i == Xdynamite_4 ? 6 : + i == Xdynamite_2 ? 20 : + i == Xdynamite_3 ? 40 : + i == Xdynamite_4 ? 60 : i == Xsand_stonein_1 ? j + 1 : i == Xsand_stonein_2 ? j + 9 : i == Xsand_stonein_3 ? j + 17 : i == Xsand_stonein_4 ? j + 25 : - i == Xsand_stoneout_1 && j == 0 ? 1 : - i == Xsand_stoneout_1 && j == 1 ? 1 : - i == Xsand_stoneout_1 && j == 2 ? 2 : - i == Xsand_stoneout_1 && j == 3 ? 4 : - i == Xsand_stoneout_1 && j == 4 ? 4 : - i == Xsand_stoneout_1 && j == 5 ? 6 : - i == Xsand_stoneout_1 && j == 6 ? 8 : - i == Xsand_stoneout_1 && j == 7 ? 8 : - i == Xsand_stoneout_2 && j == 0 ? 10 : - i == Xsand_stoneout_2 && j == 1 ? 12 : - i == Xsand_stoneout_2 && j == 2 ? 14 : - i == Xsand_stoneout_2 && j == 3 ? 16 : - i == Xsand_stoneout_2 && j == 4 ? 18 : - i == Xsand_stoneout_2 && j == 5 ? 22 : - i == Xsand_stoneout_2 && j == 6 ? 26 : - i == Xsand_stoneout_2 && j == 7 ? 30 : - i == Xboom_bug && j == 2 ? 1 : - i == Xboom_bug && j == 3 ? 2 : - i == Xboom_bug && j == 4 ? 2 : - i == Xboom_bug && j == 5 ? 1 : - i == Xboom_bug && j == 6 ? 1 : + i == Xsand_stoneout_1 && j == 0 ? 0 : + i == Xsand_stoneout_1 && j == 1 ? 0 : + i == Xsand_stoneout_1 && j == 2 ? 1 : + i == Xsand_stoneout_1 && j == 3 ? 2 : + i == Xsand_stoneout_1 && j == 4 ? 2 : + i == Xsand_stoneout_1 && j == 5 ? 3 : + i == Xsand_stoneout_1 && j == 6 ? 4 : + i == Xsand_stoneout_1 && j == 7 ? 4 : + i == Xsand_stoneout_2 && j == 0 ? 5 : + i == Xsand_stoneout_2 && j == 1 ? 6 : + i == Xsand_stoneout_2 && j == 2 ? 7 : + i == Xsand_stoneout_2 && j == 3 ? 8 : + i == Xsand_stoneout_2 && j == 4 ? 9 : + i == Xsand_stoneout_2 && j == 5 ? 11 : + i == Xsand_stoneout_2 && j == 6 ? 13 : + i == Xsand_stoneout_2 && j == 7 ? 15 : + i == Xboom_bug && j == 1 ? 2 : + i == Xboom_bug && j == 2 ? 2 : + i == Xboom_bug && j == 3 ? 4 : + i == Xboom_bug && j == 4 ? 4 : + i == Xboom_bug && j == 5 ? 2 : + i == Xboom_bug && j == 6 ? 2 : i == Xboom_bug && j == 7 ? 0 : - i == Xboom_bomb && j == 2 ? 1 : - i == Xboom_bomb && j == 3 ? 2 : - i == Xboom_bomb && j == 4 ? 2 : - i == Xboom_bomb && j == 5 ? 1 : - i == Xboom_bomb && j == 6 ? 1 : + i == Xboom_bomb && j == 1 ? 2 : + i == Xboom_bomb && j == 2 ? 2 : + i == Xboom_bomb && j == 3 ? 4 : + i == Xboom_bomb && j == 4 ? 4 : + i == Xboom_bomb && j == 5 ? 2 : + i == Xboom_bomb && j == 6 ? 2 : i == Xboom_bomb && j == 7 ? 0 : - i == Xboom_android && j == 7 ? 3 : - i == Xboom_1 && j == 2 ? 1 : - i == Xboom_1 && j == 3 ? 2 : - i == Xboom_1 && j == 4 ? 2 : - i == Xboom_1 && j == 5 ? 3 : - i == Xboom_1 && j == 6 ? 3 : - i == Xboom_1 && j == 7 ? 4 : - i == Xboom_2 && j == 0 ? 4 : - i == Xboom_2 && j == 1 ? 4 : - i == Xboom_2 && j == 2 ? 5 : - i == Xboom_2 && j == 3 ? 5 : - i == Xboom_2 && j == 4 ? 5 : - i == Xboom_2 && j == 5 ? 6 : + i == Xboom_android && j == 7 ? 6 : + i == Xboom_1 && j == 1 ? 2 : + i == Xboom_1 && j == 2 ? 2 : + i == Xboom_1 && j == 3 ? 4 : + i == Xboom_1 && j == 4 ? 4 : + i == Xboom_1 && j == 5 ? 6 : + i == Xboom_1 && j == 6 ? 6 : + i == Xboom_1 && j == 7 ? 8 : + i == Xboom_2 && j == 0 ? 8 : + i == Xboom_2 && j == 1 ? 8 : + i == Xboom_2 && j == 2 ? 10 : + i == Xboom_2 && j == 3 ? 10 : + i == Xboom_2 && j == 4 ? 10 : + i == Xboom_2 && j == 5 ? 12 : + i == Xboom_2 && j == 6 ? 12 : + i == Xboom_2 && j == 7 ? 12 : + special_animation && j == 4 ? 3 : effective_action != action ? 0 : j); -#if 0 + +#if DEBUG_EM_GFX Bitmap *debug_bitmap = g_em->bitmap; int debug_src_x = g_em->src_x; int debug_src_y = g_em->src_y; @@ -5544,7 +5894,7 @@ void InitGraphicInfo_EM(void) sync_frame); getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y, - g->double_movement && backside); + g->double_movement && is_backside); #if 1 g_em->bitmap = src_bitmap; @@ -5556,8 +5906,41 @@ void InitGraphicInfo_EM(void) g_em->dst_offset_y = 0; g_em->width = TILEX; g_em->height = TILEY; + + g_em->has_crumbled_graphics = FALSE; + g_em->crumbled_bitmap = NULL; + g_em->crumbled_src_x = 0; + g_em->crumbled_src_y = 0; + g_em->crumbled_border_size = 0; #endif +#if 0 + if (effective_element == EL_EMC_GRASS && + effective_action == ACTION_DIGGING) + printf("::: %d\n", crumbled); +#endif + +#if 0 + if (has_crumbled_graphics && crumbled == IMG_EMPTY_SPACE) + printf("::: empty crumbled: %d [%s], %d, %d\n", + effective_element, element_info[effective_element].token_name, + effective_action, direction); +#endif + + /* if element can be crumbled, but certain action graphics are just empty + space (like snapping sand with the original R'n'D graphics), do not + treat these empty space graphics as crumbled graphics in EMC engine */ + if (has_crumbled_graphics && crumbled != IMG_EMPTY_SPACE) + { + getGraphicSource(crumbled, frame, &src_bitmap, &src_x, &src_y); + + g_em->has_crumbled_graphics = TRUE; + g_em->crumbled_bitmap = src_bitmap; + g_em->crumbled_src_x = src_x; + g_em->crumbled_src_y = src_y; + g_em->crumbled_border_size = graphic_info[crumbled].border_size; + } + #if 1 if (!g->double_movement && (effective_action == ACTION_FALLING || effective_action == ACTION_MOVING || @@ -5570,7 +5953,7 @@ void InitGraphicInfo_EM(void) int cx = ABS(dx) * TILEX / 8; int cy = ABS(dy) * TILEY / 8; - if (backside) /* tile where movement starts */ + if (is_backside) /* tile where movement starts */ { if (dx < 0 || dy < 0) { @@ -5605,7 +5988,15 @@ void InitGraphicInfo_EM(void) } #endif -#if 0 + /* create unique graphic identifier to decide if tile must be redrawn */ + /* bit 31 - 16 (16 bit): EM style element + bit 15 - 12 ( 4 bit): EM style frame + bit 11 - 6 ( 6 bit): graphic width + bit 5 - 0 ( 6 bit): graphic height */ + g_em->unique_identifier = + (i << 16) | (j << 12) | (g_em->width << 6) | g_em->height; + +#if DEBUG_EM_GFX if (g_em->bitmap != debug_bitmap || g_em->src_x != debug_src_x || g_em->src_y != debug_src_y || @@ -5621,27 +6012,28 @@ void InitGraphicInfo_EM(void) if (i != last_i) { printf("\n"); - last_i = i; } - printf("::: EMC GFX ERROR for element %d -> %d ('%s')", - i, element, element_info[element].token_name); + printf("::: EMC GFX ERROR for element %d -> %d ('%s', '%s', %d)", + i, element, element_info[element].token_name, + element_action_info[effective_action].suffix, direction); if (element != effective_element) printf(" [%d ('%s')]", - effective_element,element_info[effective_element].token_name); + effective_element, + element_info[effective_element].token_name); printf("\n"); if (g_em->bitmap != debug_bitmap) - printf(" %d(%d): different bitmap!\n", - j, backside); + printf(" %d (%d): different bitmap! (0x%08x != 0x%08x)\n", + j, is_backside, (int)(g_em->bitmap), (int)(debug_bitmap)); if (g_em->src_x != debug_src_x || g_em->src_y != debug_src_y) printf(" frame %d (%c): %d,%d (%d,%d) should be %d,%d (%d,%d)\n", - j, (backside ? 'B' : 'F'), + j, (is_backside ? 'B' : 'F'), g_em->src_x, g_em->src_y, g_em->src_x / 32, g_em->src_y / 32, debug_src_x, debug_src_y, @@ -5651,15 +6043,15 @@ void InitGraphicInfo_EM(void) g_em->src_offset_y != 0 || g_em->dst_offset_x != 0 || g_em->dst_offset_y != 0) - printf(" %d(%d): offsets %d,%d and %d,%d should be all 0\n", - j, backside, + printf(" %d (%d): offsets %d,%d and %d,%d should be all 0\n", + j, is_backside, g_em->src_offset_x, g_em->src_offset_y, g_em->dst_offset_x, g_em->dst_offset_y); if (g_em->width != TILEX || g_em->height != TILEY) - printf(" %d(%d): size %d,%d should be %d,%d\n", - j, backside, + printf(" %d (%d): size %d,%d should be %d,%d\n", + j, is_backside, g_em->width, g_em->height, TILEX, TILEY); } #endif @@ -5667,7 +6059,98 @@ void InitGraphicInfo_EM(void) } } -#if 0 + for (p = 0; p < 2; p++) + { + for (i = 0; i < SPR_MAX; i++) + { + int element = player_mapping[p][i].element_rnd; + int action = player_mapping[p][i].action; + int direction = player_mapping[p][i].direction; + + for (j = 0; j < 8; j++) + { + int effective_element = element; + int effective_action = action; + int graphic = (direction == MV_NO_MOVING ? + el_act2img(effective_element, effective_action) : + el_act_dir2img(effective_element, effective_action, + direction)); + struct GraphicInfo *g = &graphic_info[graphic]; + struct GraphicInfo_EM *g_em = &graphic_info_em_player[p][i][7 - j]; + Bitmap *src_bitmap; + int src_x, src_y; + int sync_frame = j; + +#if DEBUG_EM_GFX + Bitmap *debug_bitmap = g_em->bitmap; + int debug_src_x = g_em->src_x; + int debug_src_y = g_em->src_y; +#endif + + int frame = getAnimationFrame(g->anim_frames, + g->anim_delay, + g->anim_mode, + g->anim_start_frame, + sync_frame); + + getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x,&src_y, FALSE); + +#if 1 + g_em->bitmap = src_bitmap; + g_em->src_x = src_x; + g_em->src_y = src_y; + g_em->src_offset_x = 0; + g_em->src_offset_y = 0; + g_em->dst_offset_x = 0; + g_em->dst_offset_y = 0; + g_em->width = TILEX; + g_em->height = TILEY; +#endif + +#if DEBUG_EM_GFX + if (g_em->bitmap != debug_bitmap || + g_em->src_x != debug_src_x || + g_em->src_y != debug_src_y) + { + static int last_i = -1; + + if (i != last_i) + { + printf("\n"); + last_i = i; + } + + printf("::: EMC GFX ERROR for p/a %d/%d -> %d ('%s', '%s', %d)", + p, i, element, element_info[element].token_name, + element_action_info[effective_action].suffix, direction); + + if (element != effective_element) + printf(" [%d ('%s')]", + effective_element, + element_info[effective_element].token_name); + + printf("\n"); + + if (g_em->bitmap != debug_bitmap) + printf(" %d: different bitmap! (0x%08x != 0x%08x)\n", + j, (int)(g_em->bitmap), (int)(debug_bitmap)); + + if (g_em->src_x != debug_src_x || + g_em->src_y != debug_src_y) + printf(" frame %d: %d,%d (%d,%d) should be %d,%d (%d,%d)\n", + j, + g_em->src_x, g_em->src_y, + g_em->src_x / 32, g_em->src_y / 32, + debug_src_x, debug_src_y, + debug_src_x / 32, debug_src_y / 32); + } +#endif + + } + } + } + +#if DEBUG_EM_GFX exit(0); #endif }