From f5289a1768ca1a30421700c808071f4f0c63fd9a Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Tue, 10 Dec 2024 21:00:50 +0100 Subject: [PATCH] added support for crumbled sand for native BD graphics engine --- src/game_bd/bd_cavedb.c | 5 ++++ src/game_bd/bd_elements.h | 1 + src/game_bd/bd_graphics.c | 55 ++++++++++++++++++++++++++++++++++++++- src/tools.c | 4 +++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/game_bd/bd_cavedb.c b/src/game_bd/bd_cavedb.c index 5798638a..f5940889 100644 --- a/src/game_bd/bd_cavedb.c +++ b/src/game_bd/bd_cavedb.c @@ -129,6 +129,11 @@ GdElementProperty gd_element_properties[] = P_AMOEBA_CONSUMES | P_VISUAL_EFFECT | P_DIRT | P_DIGGABLE, "DIRT", '.', 2, 2, 2 }, + { + O_DIRT_CRUMBLED, O_DIRT_CRUMBLED, N_("Dirt (crumbled)"), + P_AMOEBA_CONSUMES | P_VISUAL_EFFECT | P_DIRT | P_DIGGABLE, + "DIRT_CRUMBLED", 0, 2, 2, 2 + }, { O_DIRT_SLOPED_UP_RIGHT, O_DIRT_SLOPED_UP_RIGHT, N_("Sloped dirt (up & right)"), P_DIRT | P_SLOPED_UP | P_SLOPED_RIGHT | P_AMOEBA_CONSUMES | P_DIGGABLE, diff --git a/src/game_bd/bd_elements.h b/src/game_bd/bd_elements.h index 85d34602..e5bb0dfd 100644 --- a/src/game_bd/bd_elements.h +++ b/src/game_bd/bd_elements.h @@ -26,6 +26,7 @@ typedef enum _element { O_SPACE, O_DIRT, + O_DIRT_CRUMBLED, O_DIRT_SLOPED_UP_RIGHT, O_DIRT_SLOPED_UP_LEFT, O_DIRT_SLOPED_DOWN_LEFT, diff --git a/src/game_bd/bd_graphics.c b/src/game_bd/bd_graphics.c index bf469f80..d7f41e2b 100644 --- a/src/game_bd/bd_graphics.c +++ b/src/game_bd/bd_graphics.c @@ -542,6 +542,55 @@ static inline boolean el_smooth_movable(const int element) el_pushable(element)); } +static void gd_drawcave_crumbled(Bitmap *dest, GdGame *game, int x, int y, boolean draw_masked) +{ + void (*blit_bitmap)(Bitmap *, Bitmap *, int, int, int, int, int, int) = + (draw_masked ? BlitBitmapMasked : BlitBitmap); + GdCave *cave = game->cave; + int sx = x * cell_size - scroll_x; + int sy = y * cell_size - scroll_y; + int frame = game->animcycle; + int border_size = cell_size / 8; + struct GraphicInfo_BD *gfx = &graphic_info_bd_object[O_DIRT][frame]; + struct GraphicInfo_BD *crm = &graphic_info_bd_object[O_DIRT_CRUMBLED][frame]; + int dirs[] = { GD_MV_UP, GD_MV_LEFT, GD_MV_RIGHT, GD_MV_DOWN }; + int i; + + // first draw middle part only (because element might be drawn in masked mode) + blit_bitmap(gfx->bitmap, dest, gfx->src_x + border_size, gfx->src_y + border_size, + cell_size - 2 * border_size, cell_size - 2 * border_size, + sx + border_size, sy + border_size); + + // then draw crumbled sand borders if not next to sand, else draw normal sand borders + for (i = 0; i < ARRAY_SIZE(dirs); i++) + { + int dir = dirs[i]; + int dx = gd_dx[dir]; + int dy = gd_dy[dir]; + int xx = (x + dx + cave->w) % cave->w; + int yy = (y + dy + cave->h) % cave->h; + int tile = game->element_buffer[yy][xx]; + int tile_last = game->last_element_buffer[yy][xx]; + int xoffset = (dx > 0 ? cell_size - border_size : 0); + int yoffset = (dy > 0 ? cell_size - border_size : 0); + int xsize = (dx == 0 ? cell_size : border_size); + int ysize = (dy == 0 ? cell_size : border_size); + int dir_to = game->dir_buffer_to[yy][xx]; + boolean is_moving_to = (dir_to != GD_MV_STILL); + + // do not crumble sand that is just being digged away + if (tile_last == O_DIRT && is_moving_to) + continue; + + if (tile == O_DIRT) + blit_bitmap(gfx->bitmap, dest, gfx->src_x + xoffset, gfx->src_y + yoffset, + xsize, ysize, sx + xoffset, sy + yoffset); + else + blit_bitmap(crm->bitmap, dest, crm->src_x + xoffset, crm->src_y + yoffset, + xsize, ysize, sx + xoffset, sy + yoffset); + } +} + static void gd_drawcave_tile(Bitmap *dest, GdGame *game, int x, int y, boolean draw_masked) { void (*blit_bitmap)(Bitmap *, Bitmap *, int, int, int, int, int, int) = @@ -675,7 +724,10 @@ static void gd_drawcave_tile(Bitmap *dest, GdGame *game, int x, int y, boolean d { struct GraphicInfo_BD *g = &graphic_info_bd_object[draw][frame]; - blit_bitmap(g->bitmap, dest, g->src_x, g->src_y, cell_size, cell_size, sx, sy); + if (draw == O_DIRT) + gd_drawcave_crumbled(dest, game, x, y, draw_masked); + else + blit_bitmap(g->bitmap, dest, g->src_x, g->src_y, cell_size, cell_size, sx, sy); return; } @@ -792,6 +844,7 @@ int gd_drawcave(Bitmap *dest, GdGame *game, boolean force_redraw) for (x = cave->x1; x <= cave->x2; x++) { if (redraw_all || + game->drawing_buffer[y][x] == O_DIRT || game->gfx_buffer[y][x] & GD_REDRAW || game->dir_buffer_from[y][x] != GD_MV_STILL || game->dir_buffer_to[y][x] != GD_MV_STILL) diff --git a/src/tools.c b/src/tools.c index 89d065c8..becf1152 100644 --- a/src/tools.c +++ b/src/tools.c @@ -11151,6 +11151,10 @@ void InitGraphicInfo_BD(void) g->anim_start_frame, sync_frame); + // add special definitions for crumbled sand + if (i == O_DIRT_CRUMBLED) + graphic = el_act2crm(EL_BDX_SAND, ACTION_DEFAULT); + getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y, FALSE); g_bd->bitmap = src_bitmap; -- 2.34.1