X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Ftools.c;h=695a536223c87d07372d8d55be2a62f7b8dd888a;hp=a51f2f690e8909ac8d327b7dda93d2b480b06869;hb=14801844faf14be284c590b66f030c6bf7cea5c2;hpb=7efb5fe320faf4801e52a6b36e91dc9b3a6f73f4 diff --git a/src/tools.c b/src/tools.c index a51f2f69..695a5362 100644 --- a/src/tools.c +++ b/src/tools.c @@ -360,30 +360,26 @@ static int getLevelFromScreenY_SP(int sy) static int getLevelFromScreenX_MM(int sx) { -#if 0 int level_xsize = level.native_mm_level->fieldx; int full_xsize = level_xsize * TILESIZE_VAR; sx -= (full_xsize < SXSIZE ? (SXSIZE - full_xsize) / 2 : 0); -#endif int px = sx - SX; - int lx = px / TILESIZE_VAR; + int lx = (px + TILESIZE_VAR) / TILESIZE_VAR - 1; return lx; } static int getLevelFromScreenY_MM(int sy) { -#if 0 int level_ysize = level.native_mm_level->fieldy; int full_ysize = level_ysize * TILESIZE_VAR; sy -= (full_ysize < SYSIZE ? (SYSIZE - full_ysize) / 2 : 0); -#endif int py = sy - SY; - int ly = py / TILESIZE_VAR; + int ly = (py + TILESIZE_VAR) / TILESIZE_VAR - 1; return ly; } @@ -635,6 +631,64 @@ void DrawMaskedBorderToTarget(int draw_target) } } +void DrawTileCursor(int draw_target) +{ + Bitmap *fade_bitmap; + Bitmap *src_bitmap; + int src_x, src_y; + int dst_x, dst_y; + int graphic = IMG_GLOBAL_TILE_CURSOR; + int frame = 0; + int tilesize = TILESIZE_VAR; + int width = tilesize; + int height = tilesize; + + if (game_status != GAME_MODE_PLAYING) + return; + + if (!tile_cursor.enabled || + !tile_cursor.active) + return; + + if (tile_cursor.moving) + { + int step = TILESIZE_VAR / 4; + int dx = tile_cursor.target_x - tile_cursor.x; + int dy = tile_cursor.target_y - tile_cursor.y; + + if (ABS(dx) < step) + tile_cursor.x = tile_cursor.target_x; + else + tile_cursor.x += SIGN(dx) * step; + + if (ABS(dy) < step) + tile_cursor.y = tile_cursor.target_y; + else + tile_cursor.y += SIGN(dy) * step; + + if (tile_cursor.x == tile_cursor.target_x && + tile_cursor.y == tile_cursor.target_y) + tile_cursor.moving = FALSE; + } + + dst_x = tile_cursor.x; + dst_y = tile_cursor.y; + + frame = getGraphicAnimationFrame(graphic, -1); + + getSizedGraphicSource(graphic, frame, tilesize, &src_bitmap, &src_x, &src_y); + + fade_bitmap = + (draw_target == DRAW_TO_FADE_SOURCE ? gfx.fade_bitmap_source : + draw_target == DRAW_TO_FADE_TARGET ? gfx.fade_bitmap_target : NULL); + + if (draw_target == DRAW_TO_SCREEN) + BlitToScreenMasked(src_bitmap, src_x, src_y, width, height, dst_x, dst_y); + else + BlitBitmapMasked(src_bitmap, fade_bitmap, src_x, src_y, width, height, + dst_x, dst_y); +} + void BlitScreenToBitmap_RND(Bitmap *target_bitmap) { int fx = getFieldbufferOffsetX_RND(); @@ -1005,6 +1059,7 @@ void FadeOut(int fade_mask) SetScreenStates_BeforeFadingOut(); + SetTileCursorActive(FALSE); SetOverlayActive(FALSE); #if 0 @@ -1377,9 +1432,10 @@ 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) +void FloodFillLevelExt(int from_x, int from_y, int fill_element, + int max_array_fieldx, int max_array_fieldy, + short field[max_array_fieldx][max_array_fieldy], + int max_fieldx, int max_fieldy) { int i,x,y; int old_element; @@ -1404,12 +1460,22 @@ void FloodFillLevel(int from_x, int from_y, int fill_element, 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); + FloodFillLevelExt(x, y, fill_element, max_array_fieldx, max_array_fieldy, + field, max_fieldx, max_fieldy); } safety--; } +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) +{ + FloodFillLevelExt(from_x, from_y, fill_element, + MAX_LEV_FIELDX, MAX_LEV_FIELDY, field, + max_fieldx, max_fieldy); +} + void SetRandomAnimationValue(int x, int y) { gfx.anim_random_frame = GfxRandom[x][y]; @@ -1635,6 +1701,14 @@ void DrawSizedGraphic(int x, int y, int graphic, int frame, int tilesize) MarkTileDirty(x / tilesize, y / tilesize); } +void DrawSizedGraphicThruMask(int x, int y, int graphic, int frame, + int tilesize) +{ + DrawSizedGraphicThruMaskExt(drawto, SX + x * tilesize, SY + y * tilesize, + graphic, frame, tilesize); + MarkTileDirty(x / tilesize, y / tilesize); +} + void DrawSizedGraphicExt(DrawBuffer *d, int x, int y, int graphic, int frame, int tilesize) { @@ -1645,6 +1719,16 @@ void DrawSizedGraphicExt(DrawBuffer *d, int x, int y, int graphic, int frame, BlitBitmap(src_bitmap, d, src_x, src_y, tilesize, tilesize, x, y); } +void DrawSizedGraphicThruMaskExt(DrawBuffer *d, int x, int y, int graphic, + int frame, int tilesize) +{ + Bitmap *src_bitmap; + int src_x, src_y; + + getSizedGraphicSource(graphic, frame, tilesize, &src_bitmap, &src_x, &src_y); + BlitBitmapMasked(src_bitmap, d, src_x, src_y, tilesize, tilesize, x, y); +} + void DrawMiniGraphic(int x, int y, int graphic) { DrawMiniGraphicExt(drawto, SX + x * MINI_TILEX,SY + y * MINI_TILEY, graphic); @@ -2456,13 +2540,15 @@ void DrawLevelField(int x, int y) } } -void DrawSizedWall_MM(int dst_x, int dst_y, int element, int tilesize, - int (*el2img_function)(int)) +static void DrawSizedWallExt_MM(int dst_x, int dst_y, int element, int tilesize, + int (*el2img_function)(int), boolean masked, + int element_bits_draw) { int element_base = map_mm_wall_element(element); int element_bits = (IS_DF_WALL(element) ? element - EL_DF_WALL_START : - element - EL_MM_WALL_START) & 0x000f; + IS_MM_WALL(element) ? + element - EL_MM_WALL_START : EL_EMPTY) & 0x000f; int graphic = el2img_function(element_base); int tilesize_draw = tilesize / 2; Bitmap *src_bitmap; @@ -2476,30 +2562,70 @@ void DrawSizedWall_MM(int dst_x, int dst_y, int element, int tilesize, int dst_draw_x = dst_x + (i % 2) * tilesize_draw; int dst_draw_y = dst_y + (i / 2) * tilesize_draw; + if (!(element_bits_draw & (1 << i))) + continue; + if (element_bits & (1 << i)) - BlitBitmap(src_bitmap, drawto, src_x, src_y, tilesize_draw, tilesize_draw, - dst_draw_x, dst_draw_y); + { + if (masked) + BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, + tilesize_draw, tilesize_draw, dst_draw_x, dst_draw_y); + else + BlitBitmap(src_bitmap, drawto, src_x, src_y, + tilesize_draw, tilesize_draw, dst_draw_x, dst_draw_y); + } else - ClearRectangle(drawto, dst_draw_x, dst_draw_y, - tilesize_draw, tilesize_draw); + { + if (!masked) + ClearRectangle(drawto, dst_draw_x, dst_draw_y, + tilesize_draw, tilesize_draw); + } } } -void DrawSizedElement(int x, int y, int element, int tilesize) +void DrawSizedWallParts_MM(int x, int y, int element, int tilesize, + boolean masked, int element_bits_draw) +{ + DrawSizedWallExt_MM(SX + x * tilesize, SY + y * tilesize, + element, tilesize, el2edimg, masked, element_bits_draw); +} + +void DrawSizedWall_MM(int dst_x, int dst_y, int element, int tilesize, + int (*el2img_function)(int)) +{ + DrawSizedWallExt_MM(dst_x, dst_y, element, tilesize, el2img_function, FALSE, + 0x000f); +} + +void DrawSizedElementExt(int x, int y, int element, int tilesize, + boolean masked) { if (IS_MM_WALL(element)) { - DrawSizedWall_MM(SX + x * tilesize, SY + y * tilesize, - element, tilesize, el2edimg); + DrawSizedWallExt_MM(SX + x * tilesize, SY + y * tilesize, + element, tilesize, el2edimg, masked, 0x000f); } else { int graphic = el2edimg(element); - DrawSizedGraphic(x, y, graphic, 0, tilesize); + if (masked) + DrawSizedGraphicThruMask(x, y, graphic, 0, tilesize); + else + DrawSizedGraphic(x, y, graphic, 0, tilesize); } } +void DrawSizedElement(int x, int y, int element, int tilesize) +{ + DrawSizedElementExt(x, y, element, tilesize, FALSE); +} + +void DrawSizedElementThruMask(int x, int y, int element, int tilesize) +{ + DrawSizedElementExt(x, y, element, tilesize, TRUE); +} + void DrawMiniElement(int x, int y, int element) { int graphic; @@ -3915,7 +4041,9 @@ static int RequestHandleEvents(unsigned int req_state) { if (level_solved) { - SetDrawtoField(DRAW_TO_FIELDBUFFER); + /* the MM game engine does not use a special (scrollable) field buffer */ + if (level.game_engine_type != GAME_ENGINE_TYPE_MM) + SetDrawtoField(DRAW_TO_FIELDBUFFER); HandleGameActions(); @@ -4697,7 +4825,7 @@ unsigned int MoveDoor(unsigned int door_state) door_state &= ~DOOR_CLOSE_ALL; } - if (game_status == GAME_MODE_EDITOR) + if (game_status == GAME_MODE_EDITOR && !(door_state & DOOR_FORCE_ANIM)) door_state |= DOOR_NO_DELAY; if (door_state & DOOR_ACTION) @@ -4789,9 +4917,23 @@ unsigned int MoveDoor(unsigned int door_state) { /* opening door sound has priority over simultaneously closing door */ if (door_state & (DOOR_OPEN_1 | DOOR_OPEN_2)) + { PlayMenuSoundStereo(SND_DOOR_OPENING, SOUND_MIDDLE); + + if (door_state & DOOR_OPEN_1) + PlayMenuSoundStereo(SND_DOOR_1_OPENING, SOUND_MIDDLE); + if (door_state & DOOR_OPEN_2) + PlayMenuSoundStereo(SND_DOOR_2_OPENING, SOUND_MIDDLE); + } else if (door_state & (DOOR_CLOSE_1 | DOOR_CLOSE_2)) + { PlayMenuSoundStereo(SND_DOOR_CLOSING, SOUND_MIDDLE); + + if (door_state & DOOR_CLOSE_1) + PlayMenuSoundStereo(SND_DOOR_1_CLOSING, SOUND_MIDDLE); + if (door_state & DOOR_CLOSE_2) + PlayMenuSoundStereo(SND_DOOR_2_CLOSING, SOUND_MIDDLE); + } } for (k = start; k < num_move_steps; k++) @@ -4968,6 +5110,17 @@ unsigned int MoveDoor(unsigned int door_state) if (door_part_done_all) break; } + + if (!(door_state & DOOR_NO_DELAY)) + { + /* wait for specified door action post delay */ + if (door_state & DOOR_ACTION_1 && door_state & DOOR_ACTION_2) + Delay(MAX(door_1.post_delay, door_2.post_delay)); + else if (door_state & DOOR_ACTION_1) + Delay(door_1.post_delay); + else if (door_state & DOOR_ACTION_2) + Delay(door_2.post_delay); + } } if (door_state & DOOR_ACTION_1) @@ -7336,6 +7489,27 @@ int map_element_MM_to_RND(int element_mm) EL_EMPTY); } +int map_action_MM_to_RND(int action_mm) +{ + /* all MM actions are defined to exactly match their RND counterparts */ + return action_mm; +} + +int map_sound_MM_to_RND(int sound_mm) +{ + switch (sound_mm) + { + case SND_MM_GAME_LEVELTIME_CHARGING: + return SND_GAME_LEVELTIME_CHARGING; + + case SND_MM_GAME_HEALTH_CHARGING: + return SND_GAME_HEALTH_CHARGING; + + default: + return SND_UNDEFINED; + } +} + int map_mm_wall_element(int element) { return (element >= EL_MM_STEEL_WALL_START && @@ -8569,6 +8743,23 @@ void CheckSaveEngineSnapshot_SP(boolean murphy_is_waiting, } } +void CheckSaveEngineSnapshot_MM(boolean element_clicked, + boolean button_released) +{ + if (button_released) + { + if (game.snapshot.mode == SNAPSHOT_MODE_EVERY_MOVE) + CheckSaveEngineSnapshotToList(); + } + else if (element_clicked) + { + if (game.snapshot.mode != SNAPSHOT_MODE_EVERY_MOVE) + CheckSaveEngineSnapshotToList(); + + game.snapshot.changed_action = TRUE; + } +} + void CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame, boolean any_player_moving, boolean any_player_snapping, @@ -8599,6 +8790,16 @@ void CheckSingleStepMode_SP(boolean murphy_is_waiting, CheckSaveEngineSnapshot_SP(murphy_is_waiting, murphy_is_dropping); } +void CheckSingleStepMode_MM(boolean element_clicked, + boolean button_released) +{ + if (tape.single_step && tape.recording && !tape.pausing) + if (button_released) + TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); + + CheckSaveEngineSnapshot_MM(element_clicked, button_released); +} + void getGraphicSource_SP(struct GraphicInfo_SP *g_sp, int graphic, int sync_frame, int x, int y) { @@ -8854,8 +9055,35 @@ void ResetFontStatus() SetFontStatus(-1); } +boolean CheckIfPlayfieldViewportHasChanged() +{ + // if game status has not changed, playfield viewport has not changed either + if (game_status == game_status_last) + return FALSE; + + // check if playfield viewport has changed with current game status + struct RectWithBorder *vp_playfield = &viewport.playfield[game_status]; + int new_real_sx = vp_playfield->x; + int new_real_sy = vp_playfield->y; + int new_full_sxsize = vp_playfield->width; + int new_full_sysize = vp_playfield->height; + + return (new_real_sx != REAL_SX || + new_real_sy != REAL_SY || + new_full_sxsize != FULL_SXSIZE || + new_full_sysize != FULL_SYSIZE); +} + +boolean CheckIfGlobalBorderOrPlayfieldViewportHasChanged() +{ + return (CheckIfGlobalBorderHasChanged() || + CheckIfPlayfieldViewportHasChanged()); +} + void ChangeViewportPropertiesIfNeeded() { + boolean use_mini_tilesize = (level.game_engine_type == GAME_ENGINE_TYPE_MM ? + FALSE : setup.small_game_graphics); int gfx_game_mode = game_status; int gfx_game_mode2 = (game_status == GAME_MODE_EDITOR ? GAME_MODE_DEFAULT : game_status); @@ -8887,9 +9115,7 @@ void ChangeViewportPropertiesIfNeeded() int new_ey = vp_door_3->y; int new_exsize = vp_door_3->width; int new_eysize = vp_door_3->height; - int new_tilesize_var = - (setup.small_game_graphics ? MINI_TILESIZE : game.tile_size); - + int new_tilesize_var = (use_mini_tilesize ? MINI_TILESIZE : game.tile_size); int tilesize = (gfx_game_mode == GAME_MODE_PLAYING ? new_tilesize_var : gfx_game_mode == GAME_MODE_EDITOR ? MINI_TILESIZE : TILESIZE); int new_scr_fieldx = new_sxsize / tilesize;