X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=62965af09d2df0e90ce0f15107f6e4c2d9453fe6;hb=e2f44b4cef0a3a0441a8c031181a543751ef9cb3;hp=ddc8353b5c9da4a33b9d0caa3d3911f3690ac87d;hpb=1264abe158bef8419451c95e6db9a738eeec76f8;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index ddc8353b..62965af0 100644 --- a/src/tools.c +++ b/src/tools.c @@ -19,6 +19,7 @@ #include "cartoons.h" #include "network.h" #include "tape.h" +#include "screens.h" /* select level set with EMC X11 graphics before activating EM GFX debugging */ @@ -240,6 +241,11 @@ void DrawMaskedBorder_ALL() void DrawMaskedBorder(int redraw_mask) { + /* do not draw masked screen borders when displaying title screens */ + if (effectiveGameStatus() == GAME_MODE_TITLE || + effectiveGameStatus() == GAME_MODE_MESSAGE) + return; + if (redraw_mask & REDRAW_ALL) DrawMaskedBorder_ALL(); else @@ -274,7 +280,7 @@ void BackToFront() if (redraw_mask & REDRAW_TILES && game_status == GAME_MODE_PLAYING && - border.draw_masked[game_status]) + border.draw_masked[GAME_MODE_PLAYING]) redraw_mask |= REDRAW_FIELD; if (global.fps_slowdown && game_status == GAME_MODE_PLAYING) @@ -314,15 +320,16 @@ void BackToFront() SyncDisplay(); -#if 1 - DrawMaskedBorder(redraw_mask); -#endif + /* prevent drawing masked border to backbuffer when using playfield buffer */ + if (game_status != GAME_MODE_PLAYING || + redraw_mask & REDRAW_FROM_BACKBUFFER || + buffer == backbuffer) + DrawMaskedBorder(redraw_mask); + else + DrawMaskedBorder(redraw_mask & REDRAW_DOORS); if (redraw_mask & REDRAW_ALL) { -#if 0 - DrawMaskedBorder(REDRAW_ALL); -#endif BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); redraw_mask = REDRAW_NONE; @@ -333,9 +340,6 @@ void BackToFront() if (game_status != GAME_MODE_PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER) { -#if 0 - DrawMaskedBorder(REDRAW_FIELD); -#endif BlitBitmap(backbuffer, window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY); } @@ -354,21 +358,23 @@ void BackToFront() ABS(ScreenMovPos) == ScrollStepSize || redraw_tiles > REDRAWTILES_THRESHOLD) { -#if 1 - if (border.draw_masked[GFX_SPECIAL_ARG_MAIN]) + if (border.draw_masked[GAME_MODE_PLAYING]) { - BlitBitmap(buffer, backbuffer, fx, fy, SXSIZE, SYSIZE, SX, SY); + if (buffer != backbuffer) + { + /* copy playfield buffer to backbuffer to add masked border */ + BlitBitmap(buffer, backbuffer, fx, fy, SXSIZE, SYSIZE, SX, SY); + DrawMaskedBorder(REDRAW_FIELD); + } - DrawMaskedBorder(REDRAW_FIELD); BlitBitmap(backbuffer, window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY); } else + { BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY); -#else - BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY); -#endif + } #if 0 #ifdef DEBUG @@ -392,28 +398,13 @@ void BackToFront() if (redraw_mask & REDRAW_DOORS) { if (redraw_mask & REDRAW_DOOR_1) - { -#if 0 - DrawMaskedBorder(REDRAW_DOOR_1); -#endif BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY); - } if (redraw_mask & REDRAW_DOOR_2) - { -#if 0 - DrawMaskedBorder(REDRAW_DOOR_2); -#endif BlitBitmap(backbuffer, window, VX, VY, VXSIZE, VYSIZE, VX, VY); - } if (redraw_mask & REDRAW_DOOR_3) - { -#if 0 - DrawMaskedBorder(REDRAW_DOOR_3); -#endif BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY); - } redraw_mask &= ~REDRAW_DOORS; } @@ -597,10 +588,30 @@ void FadeCrossSaveBackbuffer() BlitBitmap(backbuffer, bitmap_db_cross, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); } +void SetWindowBackgroundImageIfDefined(int graphic) +{ + if (graphic_info[graphic].bitmap) + SetWindowBackgroundBitmap(graphic_info[graphic].bitmap); +} + void SetMainBackgroundImageIfDefined(int graphic) { if (graphic_info[graphic].bitmap) - SetMainBackgroundImage(graphic); + SetMainBackgroundBitmap(graphic_info[graphic].bitmap); +} + +void SetDoorBackgroundImageIfDefined(int graphic) +{ + if (graphic_info[graphic].bitmap) + SetDoorBackgroundBitmap(graphic_info[graphic].bitmap); +} + +void SetWindowBackgroundImage(int graphic) +{ + SetWindowBackgroundBitmap(graphic == IMG_UNDEFINED ? NULL : + graphic_info[graphic].bitmap ? + graphic_info[graphic].bitmap : + graphic_info[IMG_BACKGROUND].bitmap); } void SetMainBackgroundImage(int graphic) @@ -713,6 +724,39 @@ void SetBorderElement() } } +void FloodFillLevel(int from_x, int from_y, int fill_element, + short field[MAX_LEV_FIELDX][MAX_LEV_FIELDY], + int max_fieldx, int max_fieldy) +{ + int i,x,y; + int old_element; + static int check[4][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } }; + static int safety = 0; + + /* check if starting field still has the desired content */ + if (field[from_x][from_y] == fill_element) + return; + + safety++; + + if (safety > max_fieldx * max_fieldy) + Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug."); + + old_element = field[from_x][from_y]; + field[from_x][from_y] = fill_element; + + for (i = 0; i < 4; i++) + { + x = from_x + check[i][0]; + y = from_y + check[i][1]; + + if (IN_FIELD(x, y, max_fieldx, max_fieldy) && field[x][y] == old_element) + FloodFillLevel(x, y, fill_element, field, max_fieldx, max_fieldy); + } + + safety--; +} + void SetRandomAnimationValue(int x, int y) { gfx.anim_random_frame = GfxRandom[x][y]; @@ -1380,13 +1424,17 @@ void DrawScreenField(int x, int y) boolean cut_mode = NO_CUTTING; if (element == EL_QUICKSAND_EMPTYING || + element == EL_QUICKSAND_FAST_EMPTYING || element == EL_MAGIC_WALL_EMPTYING || element == EL_BD_MAGIC_WALL_EMPTYING || + element == EL_DC_MAGIC_WALL_EMPTYING || element == EL_AMOEBA_DROPPING) cut_mode = CUT_ABOVE; else if (element == EL_QUICKSAND_FILLING || + element == EL_QUICKSAND_FAST_FILLING || element == EL_MAGIC_WALL_FILLING || - element == EL_BD_MAGIC_WALL_FILLING) + element == EL_BD_MAGIC_WALL_FILLING || + element == EL_DC_MAGIC_WALL_FILLING) cut_mode = CUT_BELOW; if (cut_mode == CUT_ABOVE) @@ -1428,8 +1476,10 @@ void DrawScreenField(int x, int y) content_old = Store[oldx][oldy]; if (element_old == EL_QUICKSAND_EMPTYING || + element_old == EL_QUICKSAND_FAST_EMPTYING || element_old == EL_MAGIC_WALL_EMPTYING || element_old == EL_BD_MAGIC_WALL_EMPTYING || + element_old == EL_DC_MAGIC_WALL_EMPTYING || element_old == EL_AMOEBA_DROPPING) cut_mode = CUT_ABOVE; @@ -1576,9 +1626,17 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action) for (yy = 0; yy < ysize; yy++) for (xx = 0; xx < xsize; xx++) DrawEnvelopeBackground(envelope_nr, sx,sy, xx,yy, xsize, ysize, font_nr); +#if 1 + DrawTextBuffer(SX + sx + font_width, SY + sy + font_height, + level.envelope[envelope_nr].text, font_nr, max_xsize, + xsize - 2, ysize - 2, mask_mode, + level.envelope[envelope_nr].autowrap, + level.envelope[envelope_nr].centered, FALSE); +#else DrawTextToTextArea(SX + sx + font_width, SY + sy + font_height, level.envelope[envelope_nr].text, font_nr, max_xsize, xsize - 2, ysize - 2, mask_mode); +#endif redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER; BackToFront(); @@ -1742,7 +1800,7 @@ static void DrawPreviewLevelExt(int from_x, int from_y) #define MICROLABEL_IMPORTED_BY_HEAD 6 #define MICROLABEL_IMPORTED_BY 7 -static int getMaxTextLength(struct MenuPosInfo *pos, int font_nr) +static int getMaxTextLength(struct TextPosInfo *pos, int font_nr) { int max_text_width = SXSIZE; int font_width = getFontWidth(font_nr); @@ -1759,7 +1817,7 @@ static int getMaxTextLength(struct MenuPosInfo *pos, int font_nr) static void DrawPreviewLevelLabelExt(int mode) { - struct MenuPosInfo *pos = &menu.main.text.level_info_2; + struct TextPosInfo *pos = &menu.main.text.level_info_2; char label_text[MAX_OUTPUT_LINESIZE + 1]; int max_len_label_text; int font_nr = FONT_TEXT_2; @@ -1776,6 +1834,11 @@ static void DrawPreviewLevelLabelExt(int mode) max_len_label_text = SXSIZE / getFontWidth(font_nr); #endif +#if 1 + if (pos->chars != -1) + max_len_label_text = pos->chars; +#endif + for (i = 0; i < max_len_label_text; i++) label_text[i] = ' '; label_text[max_len_label_text] = '\0'; @@ -1862,7 +1925,7 @@ void DrawPreviewLevel(boolean restart) if (leveldir_current->name) { - struct MenuPosInfo *pos = &menu.main.text.level_info_1; + struct TextPosInfo *pos = &menu.main.text.level_info_1; char label_text[MAX_OUTPUT_LINESIZE + 1]; int font_nr = FONT_TEXT_1; #if 1 @@ -1875,6 +1938,11 @@ void DrawPreviewLevel(boolean restart) int lxpos, lypos; #endif +#if 1 + if (pos->chars != -1) + max_len_label_text = pos->chars; +#endif + strncpy(label_text, leveldir_current->name, max_len_label_text); label_text[max_len_label_text] = '\0'; @@ -2487,7 +2555,11 @@ boolean Request(char *text, unsigned int req_state) if (max_word_len > MAX_REQUEST_LINE_FONT1_LEN) { max_request_line_len = MAX_REQUEST_LINE_FONT2_LEN; +#if 1 + font_nr = FONT_TEXT_1; +#else font_nr = FONT_LEVEL_NUMBER; +#endif break; } @@ -2733,6 +2805,23 @@ boolean Request(char *text, unsigned int req_state) result = 0; } +#if 1 + + if (game_status == GAME_MODE_PLAYING && local_player->LevelSolved_GameEnd) + { + HandleGameActions(); + BackToFront(); + } + else + { + DoAnimation(); + + if (!PendingEvent()) /* delay only if no pending events */ + Delay(10); + } + +#else + DoAnimation(); #if 1 @@ -2741,6 +2830,8 @@ boolean Request(char *text, unsigned int req_state) #else /* don't eat all CPU time */ Delay(10); +#endif + #endif } @@ -4454,19 +4545,19 @@ em_object_mapping_list[] = }, { Xexit, TRUE, FALSE, - EL_EXIT_CLOSED, -1, -1 + EL_EM_EXIT_CLOSED, -1, -1 }, { Xexit_1, TRUE, FALSE, - EL_EXIT_OPEN, -1, -1 + EL_EM_EXIT_OPEN, -1, -1 }, { Xexit_2, FALSE, FALSE, - EL_EXIT_OPEN, -1, -1 + EL_EM_EXIT_OPEN, -1, -1 }, { Xexit_3, FALSE, FALSE, - EL_EXIT_OPEN, -1, -1 + EL_EM_EXIT_OPEN, -1, -1 }, { Xdynamite, TRUE, FALSE, @@ -5375,10 +5466,14 @@ int get_next_element(int element) { case EL_QUICKSAND_FILLING: return EL_QUICKSAND_FULL; case EL_QUICKSAND_EMPTYING: return EL_QUICKSAND_EMPTY; + case EL_QUICKSAND_FAST_FILLING: return EL_QUICKSAND_FAST_FULL; + case EL_QUICKSAND_FAST_EMPTYING: return EL_QUICKSAND_FAST_EMPTY; case EL_MAGIC_WALL_FILLING: return EL_MAGIC_WALL_FULL; case EL_MAGIC_WALL_EMPTYING: return EL_MAGIC_WALL_ACTIVE; case EL_BD_MAGIC_WALL_FILLING: return EL_BD_MAGIC_WALL_FULL; case EL_BD_MAGIC_WALL_EMPTYING: return EL_BD_MAGIC_WALL_ACTIVE; + case EL_DC_MAGIC_WALL_FILLING: return EL_DC_MAGIC_WALL_FULL; + case EL_DC_MAGIC_WALL_EMPTYING: return EL_DC_MAGIC_WALL_ACTIVE; case EL_AMOEBA_DROPPING: return EL_AMOEBA_WET; default: return element; @@ -5483,6 +5578,115 @@ int font2baseimg(int font_nr) return font_info[font_nr].special_graphic[GFX_SPECIAL_ARG_DEFAULT]; } +int getBeltNrFromBeltElement(int element) +{ + return (element < EL_CONVEYOR_BELT_2_LEFT ? 0 : + element < EL_CONVEYOR_BELT_3_LEFT ? 1 : + element < EL_CONVEYOR_BELT_4_LEFT ? 2 : 3); +} + +int getBeltNrFromBeltActiveElement(int element) +{ + return (element < EL_CONVEYOR_BELT_2_LEFT_ACTIVE ? 0 : + element < EL_CONVEYOR_BELT_3_LEFT_ACTIVE ? 1 : + element < EL_CONVEYOR_BELT_4_LEFT_ACTIVE ? 2 : 3); +} + +int getBeltNrFromBeltSwitchElement(int element) +{ + return (element < EL_CONVEYOR_BELT_2_SWITCH_LEFT ? 0 : + element < EL_CONVEYOR_BELT_3_SWITCH_LEFT ? 1 : + element < EL_CONVEYOR_BELT_4_SWITCH_LEFT ? 2 : 3); +} + +int getBeltDirNrFromBeltElement(int element) +{ + static int belt_base_element[4] = + { + EL_CONVEYOR_BELT_1_LEFT, + EL_CONVEYOR_BELT_2_LEFT, + EL_CONVEYOR_BELT_3_LEFT, + EL_CONVEYOR_BELT_4_LEFT + }; + + int belt_nr = getBeltNrFromBeltElement(element); + int belt_dir_nr = element - belt_base_element[belt_nr]; + + return (belt_dir_nr % 3); +} + +int getBeltDirNrFromBeltSwitchElement(int element) +{ + static int belt_base_element[4] = + { + EL_CONVEYOR_BELT_1_SWITCH_LEFT, + EL_CONVEYOR_BELT_2_SWITCH_LEFT, + EL_CONVEYOR_BELT_3_SWITCH_LEFT, + EL_CONVEYOR_BELT_4_SWITCH_LEFT + }; + + int belt_nr = getBeltNrFromBeltSwitchElement(element); + int belt_dir_nr = element - belt_base_element[belt_nr]; + + return (belt_dir_nr % 3); +} + +int getBeltDirFromBeltElement(int element) +{ + static int belt_move_dir[3] = + { + MV_LEFT, + MV_NONE, + MV_RIGHT + }; + + int belt_dir_nr = getBeltDirNrFromBeltElement(element); + + return belt_move_dir[belt_dir_nr]; +} + +int getBeltDirFromBeltSwitchElement(int element) +{ + static int belt_move_dir[3] = + { + MV_LEFT, + MV_NONE, + MV_RIGHT + }; + + int belt_dir_nr = getBeltDirNrFromBeltSwitchElement(element); + + return belt_move_dir[belt_dir_nr]; +} + +int getBeltElementFromBeltNrAndBeltDir(int belt_nr, int belt_dir) +{ + static int belt_base_element[4] = + { + EL_CONVEYOR_BELT_1_LEFT, + EL_CONVEYOR_BELT_2_LEFT, + EL_CONVEYOR_BELT_3_LEFT, + EL_CONVEYOR_BELT_4_LEFT + }; + int belt_dir_nr = (belt_dir == MV_LEFT ? 0 : belt_dir == MV_RIGHT ? 2 : 1); + + return belt_base_element[belt_nr] + belt_dir_nr; +} + +int getBeltSwitchElementFromBeltNrAndBeltDir(int belt_nr, int belt_dir) +{ + static int belt_base_element[4] = + { + EL_CONVEYOR_BELT_1_SWITCH_LEFT, + EL_CONVEYOR_BELT_2_SWITCH_LEFT, + EL_CONVEYOR_BELT_3_SWITCH_LEFT, + EL_CONVEYOR_BELT_4_SWITCH_LEFT + }; + int belt_dir_nr = (belt_dir == MV_LEFT ? 0 : belt_dir == MV_RIGHT ? 2 : 1); + + return belt_base_element[belt_nr] + belt_dir_nr; +} + int getNumActivePlayers_EM() { int num_players = 0; @@ -6196,9 +6400,26 @@ void PlayMenuMusic() if (music == MUS_UNDEFINED) return; + if (!setup.sound_music) + return; + PlayMusic(music); } +void PlaySoundActivating() +{ +#if 0 + PlaySound(SND_MENU_ITEM_ACTIVATING); +#endif +} + +void PlaySoundSelecting() +{ +#if 0 + PlaySound(SND_MENU_ITEM_SELECTING); +#endif +} + void ToggleFullscreenIfNeeded() { boolean change_fullscreen = (setup.fullscreen !=