X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=794de36ea7f860ad80e9e5c06cd3f3767ec9f79b;hb=fda8c9f42aa13663ad6b2f698da787a7280b9965;hp=bd1ded0c740635fdf3400c55eb272d7c32c3418b;hpb=a268c893d49b178fdcc80956484b567952868fd4;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index bd1ded0c..794de36e 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) { @@ -1504,7 +1509,7 @@ static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y) { int x, y; - DrawBackground(xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE); + DrawBackground(xpos, ypos, MICROLEVEL_XSIZE, MICROLEVEL_YSIZE); if (lev_fieldx < STD_LEV_FIELDX) xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX; @@ -1535,10 +1540,12 @@ static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y) #define MICROLABEL_EMPTY 0 #define MICROLABEL_LEVEL_NAME 1 -#define MICROLABEL_CREATED_BY 2 +#define MICROLABEL_LEVEL_AUTHOR_HEAD 2 #define MICROLABEL_LEVEL_AUTHOR 3 -#define MICROLABEL_IMPORTED_FROM 4 -#define MICROLABEL_LEVEL_IMPORT_INFO 5 +#define MICROLABEL_IMPORTED_FROM_HEAD 4 +#define MICROLABEL_IMPORTED_FROM 5 +#define MICROLABEL_IMPORTED_BY_HEAD 6 +#define MICROLABEL_IMPORTED_BY 7 static void DrawMicroLevelLabelExt(int mode) { @@ -1546,26 +1553,30 @@ static void DrawMicroLevelLabelExt(int mode) int max_len_label_text; int font_nr = FONT_TEXT_2; - if (mode == MICROLABEL_CREATED_BY || mode == MICROLABEL_IMPORTED_FROM) + if (mode == MICROLABEL_LEVEL_AUTHOR_HEAD || + mode == MICROLABEL_IMPORTED_FROM_HEAD || + mode == MICROLABEL_IMPORTED_BY_HEAD) font_nr = FONT_TEXT_3; max_len_label_text = SXSIZE / getFontWidth(font_nr); - DrawBackground(SX, MICROLABEL_YPOS, SXSIZE, getFontHeight(font_nr)); + DrawBackground(SX, MICROLABEL2_YPOS, SXSIZE, getFontHeight(font_nr)); - strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name : - mode == MICROLABEL_CREATED_BY ? "created by" : - mode == MICROLABEL_LEVEL_AUTHOR ? level.author : - mode == MICROLABEL_IMPORTED_FROM ? "imported from" : - mode == MICROLABEL_LEVEL_IMPORT_INFO ? - leveldir_current->imported_from : ""), + strncpy(label_text, + (mode == MICROLABEL_LEVEL_NAME ? level.name : + mode == MICROLABEL_LEVEL_AUTHOR_HEAD ? "created by" : + mode == MICROLABEL_LEVEL_AUTHOR ? level.author : + mode == MICROLABEL_IMPORTED_FROM_HEAD ? "imported from" : + mode == MICROLABEL_IMPORTED_FROM ? leveldir_current->imported_from : + mode == MICROLABEL_IMPORTED_BY_HEAD ? "imported by" : + mode == MICROLABEL_IMPORTED_BY ? leveldir_current->imported_by :""), max_len_label_text); label_text[max_len_label_text] = '\0'; if (strlen(label_text) > 0) { int lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2; - int lypos = MICROLABEL_YPOS; + int lypos = MICROLABEL2_YPOS; DrawText(lxpos, lypos, label_text, font_nr); } @@ -1600,11 +1611,18 @@ void DrawMicroLevel(int xpos, int ypos, boolean restart) if (leveldir_current->name) { - int text_width = getTextWidth(leveldir_current->name, FONT_TEXT_1); - int lxpos = SX + (SXSIZE - text_width) / 2; - int lypos = SY + 352; + char label_text[MAX_OUTPUT_LINESIZE + 1]; + int font_nr = FONT_TEXT_1; + int max_len_label_text = SXSIZE / getFontWidth(font_nr); + int lxpos, lypos; + + strncpy(label_text, leveldir_current->name, max_len_label_text); + label_text[max_len_label_text] = '\0'; - DrawText(lxpos, lypos, leveldir_current->name, FONT_TEXT_1); + lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2; + lypos = SY + MICROLABEL1_YPOS; + + DrawText(lxpos, lypos, label_text, font_nr); } game_status = last_game_status; /* restore current game status */ @@ -1653,6 +1671,7 @@ void DrawMicroLevel(int xpos, int ypos, boolean restart) DrawMicroLevelExt(xpos, ypos, from_x, from_y); } + /* !!! THIS ALL SUCKS -- SHOULD BE CLEANLY REWRITTEN !!! */ /* redraw micro level label, if needed */ if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 && strcmp(level.author, ANONYMOUS_NAME) != 0 && @@ -1663,18 +1682,31 @@ void DrawMicroLevel(int xpos, int ypos, boolean restart) if (leveldir_current->imported_from != NULL) max_label_counter += 14; + if (leveldir_current->imported_by != NULL) + max_label_counter += 14; label_counter = (label_counter + 1) % max_label_counter; label_state = (label_counter >= 0 && label_counter <= 7 ? MICROLABEL_LEVEL_NAME : label_counter >= 9 && label_counter <= 12 ? - MICROLABEL_CREATED_BY : + MICROLABEL_LEVEL_AUTHOR_HEAD : label_counter >= 14 && label_counter <= 21 ? MICROLABEL_LEVEL_AUTHOR : label_counter >= 23 && label_counter <= 26 ? - MICROLABEL_IMPORTED_FROM : + MICROLABEL_IMPORTED_FROM_HEAD : label_counter >= 28 && label_counter <= 35 ? - MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY); + MICROLABEL_IMPORTED_FROM : + label_counter >= 37 && label_counter <= 40 ? + MICROLABEL_IMPORTED_BY_HEAD : + label_counter >= 42 && label_counter <= 49 ? + MICROLABEL_IMPORTED_BY : MICROLABEL_EMPTY); + + if (leveldir_current->imported_from == NULL && + (label_state == MICROLABEL_IMPORTED_FROM_HEAD || + label_state == MICROLABEL_IMPORTED_FROM)) + label_state = (label_state == MICROLABEL_IMPORTED_FROM_HEAD ? + MICROLABEL_IMPORTED_BY_HEAD : MICROLABEL_IMPORTED_BY); + DrawMicroLevelLabelExt(label_state); } @@ -2219,6 +2251,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) @@ -3964,19 +4002,19 @@ em_object_mapping_list[] = }, { Ykey_5_eat, FALSE, FALSE, - EL_EM_KEY_5, ACTION_COLLECTING, -1 + EL_EMC_KEY_5, ACTION_COLLECTING, -1 }, { Ykey_6_eat, FALSE, FALSE, - EL_EM_KEY_6, ACTION_COLLECTING, -1 + EL_EMC_KEY_6, ACTION_COLLECTING, -1 }, { Ykey_7_eat, FALSE, FALSE, - EL_EM_KEY_7, ACTION_COLLECTING, -1 + EL_EMC_KEY_7, ACTION_COLLECTING, -1 }, { Ykey_8_eat, FALSE, FALSE, - EL_EM_KEY_8, ACTION_COLLECTING, -1 + EL_EMC_KEY_8, ACTION_COLLECTING, -1 }, { Ylenses_eat, FALSE, FALSE, @@ -4035,7 +4073,7 @@ em_object_mapping_list[] = EL_AMOEBA_DRY, ACTION_OTHER, -1 }, { - Xamoeba_5, FALSE, FALSE, + Xamoeba_5, TRUE, FALSE, EL_AMOEBA_WET, ACTION_OTHER, -1 }, { @@ -4068,19 +4106,19 @@ em_object_mapping_list[] = }, { Xdoor_5, TRUE, FALSE, - EL_EM_GATE_5, -1, -1 + EL_EMC_GATE_5, -1, -1 }, { Xdoor_6, TRUE, FALSE, - EL_EM_GATE_6, -1, -1 + EL_EMC_GATE_6, -1, -1 }, { Xdoor_7, TRUE, FALSE, - EL_EM_GATE_7, -1, -1 + EL_EMC_GATE_7, -1, -1 }, { Xdoor_8, TRUE, FALSE, - EL_EM_GATE_8, -1, -1 + EL_EMC_GATE_8, -1, -1 }, { Xkey_1, TRUE, FALSE, @@ -4100,19 +4138,19 @@ em_object_mapping_list[] = }, { Xkey_5, TRUE, FALSE, - EL_EM_KEY_5, -1, -1 + EL_EMC_KEY_5, -1, -1 }, { Xkey_6, TRUE, FALSE, - EL_EM_KEY_6, -1, -1 + EL_EMC_KEY_6, -1, -1 }, { Xkey_7, TRUE, FALSE, - EL_EM_KEY_7, -1, -1 + EL_EMC_KEY_7, -1, -1 }, { Xkey_8, TRUE, FALSE, - EL_EM_KEY_8, -1, -1 + EL_EMC_KEY_8, -1, -1 }, { Xwind_n, TRUE, FALSE, @@ -4324,19 +4362,51 @@ em_object_mapping_list[] = }, { Xfake_door_5, TRUE, FALSE, - EL_EM_GATE_5_GRAY, -1, -1 + EL_EMC_GATE_5_GRAY, -1, -1 }, { Xfake_door_6, TRUE, FALSE, - EL_EM_GATE_6_GRAY, -1, -1 + EL_EMC_GATE_6_GRAY, -1, -1 }, { Xfake_door_7, TRUE, FALSE, - EL_EM_GATE_7_GRAY, -1, -1 + EL_EMC_GATE_7_GRAY, -1, -1 }, { Xfake_door_8, TRUE, FALSE, - EL_EM_GATE_8_GRAY, -1, -1 + EL_EMC_GATE_8_GRAY, -1, -1 + }, + { + Xfake_acid_1, TRUE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 + }, + { + Xfake_acid_2, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 + }, + { + Xfake_acid_3, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 + }, + { + Xfake_acid_4, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 + }, + { + Xfake_acid_5, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 + }, + { + Xfake_acid_6, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 + }, + { + Xfake_acid_7, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 + }, + { + Xfake_acid_8, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { Xsteel_1, TRUE, FALSE, @@ -5590,8 +5660,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) @@ -5689,7 +5768,6 @@ void InitGraphicInfo_EM(void) int effective_element = (j > 5 && i == Yacid_splash_eB ? EL_EMPTY : j > 5 && i == Yacid_splash_wB ? EL_EMPTY : j < 7 ? element : - i == Ynut_sB ? element : i == Xdrip_stretch ? element : i == Xdrip_stretchB ? element : i == Ydrip_s1 ? element : @@ -5714,11 +5792,12 @@ void InitGraphicInfo_EM(void) i == Yspring_kill_w ? EL_SPRING : i == Yemerald_stone ? EL_EMERALD : i == Ydiamond_stone ? EL_ROCK : + 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 : @@ -5778,6 +5857,14 @@ void InitGraphicInfo_EM(void) i == Xacid_6 ? 50 : i == Xacid_7 ? 60 : i == Xacid_8 ? 70 : + i == Xfake_acid_1 ? 0 : + i == Xfake_acid_2 ? 10 : + i == Xfake_acid_3 ? 20 : + i == Xfake_acid_4 ? 30 : + i == Xfake_acid_5 ? 40 : + i == Xfake_acid_6 ? 50 : + i == Xfake_acid_7 ? 60 : + i == Xfake_acid_8 ? 70 : i == Xball_2 ? 7 : i == Xball_2B ? j + 8 : i == Yball_eat ? j + 1 : @@ -5811,22 +5898,22 @@ void InitGraphicInfo_EM(void) 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 == 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 : @@ -5887,11 +5974,13 @@ void InitGraphicInfo_EM(void) 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; + + g_em->has_crumbled_graphics = FALSE; + g_em->preserve_background = FALSE; #endif #if 0 @@ -5930,47 +6019,125 @@ void InitGraphicInfo_EM(void) (effective_action == ACTION_FALLING ? MV_DOWN : direction); int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? 1 : 0); int dy = (move_dir == MV_UP ? -1 : move_dir == MV_DOWN ? 1 : 0); - int cx = ABS(dx) * TILEX / 8; - int cy = ABS(dy) * TILEY / 8; - - if (is_backside) /* tile where movement starts */ + int num_steps = (i == Ydrip_s1 || + i == Ydrip_s1B || + i == Ydrip_s2 || + i == Ydrip_s2B ? 16 : 8); + int cx = ABS(dx) * (TILEX / num_steps); + int cy = ABS(dy) * (TILEY / num_steps); + int step_frame = (i == Ydrip_s2 || + i == Ydrip_s2B ? j + 8 : j) + 1; + int step = (is_backside ? step_frame : num_steps - step_frame); + + if (is_backside) /* tile where movement starts */ { if (dx < 0 || dy < 0) { - g_em->src_offset_x = cx * (j + 1); - g_em->src_offset_y = cy * (j + 1); + g_em->src_offset_x = cx * step; + g_em->src_offset_y = cy * step; } else { - g_em->dst_offset_x = cx * (j + 1); - g_em->dst_offset_y = cy * (j + 1); + g_em->dst_offset_x = cx * step; + g_em->dst_offset_y = cy * step; } - - g_em->width = TILEX - cx * (j + 1); - g_em->height = TILEY - cy * (j + 1); } else /* tile where movement ends */ { if (dx < 0 || dy < 0) { - g_em->dst_offset_x = cx * (7 - j); - g_em->dst_offset_y = cy * (7 - j); + g_em->dst_offset_x = cx * step; + g_em->dst_offset_y = cy * step; } else { - g_em->src_offset_x = cx * (7 - j); - g_em->src_offset_y = cy * (7 - j); + g_em->src_offset_x = cx * step; + g_em->src_offset_y = cy * step; } + } + + g_em->width = TILEX - cx * step; + g_em->height = TILEY - cy * step; + } + +#if 0 + if (effective_action == ACTION_SMASHED_BY_ROCK && + element_info[effective_element].graphic[effective_action] == + element_info[effective_element].graphic[ACTION_DEFAULT]) + { + int move_dir = MV_DOWN; + int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? 1 : 0); + int dy = (move_dir == MV_UP ? -1 : move_dir == MV_DOWN ? 1 : 0); + int num_steps = 8; + int cx = ABS(dx) * (TILEX / num_steps); + int cy = ABS(dy) * (TILEY / num_steps); + int step_frame = j + 1; + int step = (is_backside ? step_frame : num_steps - step_frame); + + graphic = (el_act_dir2img(EL_ROCK, ACTION_FALLING, MV_DOWN)); + g = &graphic_info[graphic]; + sync_frame = j; + 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, + g->double_movement && is_backside); - g_em->width = TILEX - cx * (7 - j); - g_em->height = TILEY - cy * (7 - j); + 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; + + if (is_backside) /* tile where movement starts */ + { + if (dx < 0 || dy < 0) + { + g_em->src_offset_x = cx * step; + g_em->src_offset_y = cy * step; + } + else + { + g_em->dst_offset_x = cx * step; + g_em->dst_offset_y = cy * step; + } } + else /* tile where movement ends */ + { + if (dx < 0 || dy < 0) + { + g_em->dst_offset_x = cx * step; + g_em->dst_offset_y = cy * step; + } + else + { + g_em->src_offset_x = cx * step; + g_em->src_offset_y = cy * step; + } + } + + g_em->width = TILEX - cx * step; + g_em->height = TILEY - cy * step; + +#if 0 + printf("::: -> '%s'\n", element_info[effective_element].token_name); +#endif } +#endif + #endif /* 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) | (frame << 8) | g_em->width | g_em->height; + (i << 16) | (j << 12) | (g_em->width << 6) | g_em->height; #if DEBUG_EM_GFX if (g_em->bitmap != debug_bitmap || @@ -5991,9 +6158,9 @@ void InitGraphicInfo_EM(void) last_i = i; } - printf("::: EMC GFX ERROR for element %d -> %d ('%s') [%d, %d]", + printf("::: EMC GFX ERROR for element %d -> %d ('%s', '%s', %d)", i, element, element_info[element].token_name, - effective_action, direction); + element_action_info[effective_action].suffix, direction); if (element != effective_element) printf(" [%d ('%s')]", @@ -6035,6 +6202,38 @@ void InitGraphicInfo_EM(void) } } +#if 1 + for (i = 0; i < TILE_MAX; i++) + { + for (j = 0; j < 8; j++) + { + int element = object_mapping[i].element_rnd; + int action = object_mapping[i].action; + + if (action == ACTION_SMASHED_BY_ROCK && + element_info[element].graphic[action] == + element_info[element].graphic[ACTION_DEFAULT]) + { + /* no separate animation for "smashed by rock" -- use rock instead */ + struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][7 - j]; + struct GraphicInfo_EM *g_xx = &graphic_info_em_object[Ystone_s][7 - j]; + + g_em->bitmap = g_xx->bitmap; + g_em->src_x = g_xx->src_x; + g_em->src_y = g_xx->src_y; + g_em->src_offset_x = g_xx->src_offset_x; + g_em->src_offset_y = g_xx->src_offset_y; + g_em->dst_offset_x = g_xx->dst_offset_x; + g_em->dst_offset_y = g_xx->dst_offset_y; + g_em->width = g_xx->width; + g_em->height = g_xx->height; + + g_em->preserve_background = TRUE; + } + } + } +#endif + for (p = 0; p < 2; p++) { for (i = 0; i < SPR_MAX; i++)