X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=c859e633975d4e6819e78a298c16ba0db0d3e134;hb=778c7803f078b162199125a9e6e6baf92d74c409;hp=325f7e1c323f336a0d2de27bd74c5e637a398f1b;hpb=62356d7587434a3822d39f74d8b4c86a9febd123;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index 325f7e1c..c859e633 100644 --- a/src/tools.c +++ b/src/tools.c @@ -1416,39 +1416,42 @@ void SetBorderElement(void) } } -void FloodFillLevelExt(int from_x, int from_y, int fill_element, +void FloodFillLevelExt(int start_x, int start_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; - static int check[4][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } }; - static int safety = 0; + static struct XY stack_buffer[MAX_LEV_FIELDX * MAX_LEV_FIELDY]; + static struct XY check[4] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } }; + int old_element = field[start_x][start_y]; + int stack_pos = 0; - // check if starting field still has the desired content - if (field[from_x][from_y] == fill_element) + // do nothing if start field already has the desired content + if (old_element == fill_element) return; - safety++; + stack_buffer[stack_pos++] = (struct XY){ start_x, start_y }; - if (safety > max_fieldx * max_fieldy) - Fail("Something went wrong in 'FloodFill()'. Please debug."); + while (stack_pos > 0) + { + struct XY current = stack_buffer[--stack_pos]; + int i; - old_element = field[from_x][from_y]; - field[from_x][from_y] = fill_element; + field[current.x][current.y] = fill_element; - for (i = 0; i < 4; i++) - { - x = from_x + check[i][0]; - y = from_y + check[i][1]; + for (i = 0; i < 4; i++) + { + int x = current.x + check[i].x; + int y = current.y + check[i].y; - if (IN_FIELD(x, y, max_fieldx, max_fieldy) && field[x][y] == old_element) - FloodFillLevelExt(x, y, fill_element, max_array_fieldx, max_array_fieldy, - field, max_fieldx, max_fieldy); - } + // check for stack buffer overflow (should not happen) + if (stack_pos >= MAX_LEV_FIELDX * MAX_LEV_FIELDY) + Fail("Stack buffer overflow in 'FloodFillLevelExt()'. Please debug."); - safety--; + if (IN_FIELD(x, y, max_fieldx, max_fieldy) && field[x][y] == old_element) + stack_buffer[stack_pos++] = (struct XY){ x, y }; + } + } } void FloodFillLevel(int from_x, int from_y, int fill_element, @@ -1486,7 +1489,7 @@ void getGraphicSourceBitmap(int graphic, int tilesize, Bitmap **bitmap) if (tilesize == gfx.standard_tile_size) *bitmap = g->bitmaps[IMG_BITMAP_STANDARD]; else if (tilesize == game.tile_size) - *bitmap = g->bitmaps[IMG_BITMAP_GAME]; + *bitmap = g->bitmaps[IMG_BITMAP_PTR_GAME]; else *bitmap = g->bitmaps[IMG_BITMAP_1x1 - log_2(tilesize_capped)]; } @@ -1532,7 +1535,7 @@ void getSizedGraphicSourceExt(int graphic, int frame, int tilesize, *g = graphic_info[IMG_CHAR_EXCLAM]; // if no in-game graphics defined, always use standard graphic size - if (g->bitmaps[IMG_BITMAP_GAME] == NULL) + if (g->bitmaps[IMG_BITMAP_PTR_GAME] == NULL) tilesize = TILESIZE; getGraphicSourceBitmap(graphic, tilesize, bitmap); @@ -1559,6 +1562,24 @@ void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y) getSizedGraphicSource(graphic, 0, MINI_TILESIZE, bitmap, x, y); } +void getGlobalAnimGraphicSource(int graphic, int frame, + Bitmap **bitmap, int *x, int *y) +{ + struct GraphicInfo *g = &graphic_info[graphic]; + + // if no graphics defined at all, use fallback graphics + if (g->bitmaps == NULL) + *g = graphic_info[IMG_CHAR_EXCLAM]; + + // use original size graphics, if existing, else use standard size graphics + if (g->bitmaps[IMG_BITMAP_PTR_ORIGINAL]) + *bitmap = g->bitmaps[IMG_BITMAP_PTR_ORIGINAL]; + else + *bitmap = g->bitmaps[IMG_BITMAP_STANDARD]; + + getGraphicSourceXY(graphic, frame, x, y, FALSE); +} + static void getGraphicSourceExt(int graphic, int frame, Bitmap **bitmap, int *x, int *y, boolean get_backside) { @@ -3510,8 +3531,8 @@ static void DrawPreviewLevelExt(boolean restart) DrawPreviewLevelInfo(MICROLABEL_LEVEL_AUTHOR); // initialize delay counters - DelayReached(&scroll_delay, 0); - DelayReached(&label_delay, 0); + ResetDelayCounter(&scroll_delay); + ResetDelayCounter(&label_delay); if (leveldir_current->name) { @@ -3654,7 +3675,7 @@ void DrawPreviewPlayers(void) { int element = level.field[x][y]; - if (ELEM_IS_PLAYER(element)) + if (IS_PLAYER_ELEMENT(element)) { int player_nr = GET_PLAYER_NR(element);