X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=8461537a9329e91bfa9d0c327380493d9be8af91;hb=c6d59064aa782b8ad71eddac2797fdc50e4858f9;hp=c6cd967aaf11dff43d2dfe7e6d038119a34606ce;hpb=949580a3bafe5c8abd1fac99202411b65900b883;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index c6cd967a..8461537a 100644 --- a/src/tools.c +++ b/src/tools.c @@ -14,6 +14,7 @@ #include "libgame/libgame.h" #include "tools.h" +#include "init.h" #include "game.h" #include "events.h" #include "cartoons.h" @@ -348,6 +349,10 @@ void BackToFront() if (redraw_mask & REDRAW_FIELD) { +#if 0 + printf("::: REDRAW_FIELD\n"); +#endif + if (game_status != GAME_MODE_PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER) { @@ -430,6 +435,10 @@ void BackToFront() if (redraw_mask & REDRAW_TILES) { +#if 0 + printf("::: REDRAW_TILES\n"); +#endif + for (x = 0; x < SCR_FIELDX; x++) for (y = 0 ; y < SCR_FIELDY; y++) if (redraw[redraw_x1 + x][redraw_y1 + y]) @@ -1442,14 +1451,205 @@ void DrawLevelFieldThruMask(int x, int y) (e) == EL_QUICKSAND_EMPTYING || \ (e) == EL_QUICKSAND_FAST_EMPTYING)) -static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) +static void DrawLevelFieldCrumbledInnerCorners(int x, int y, int dx, int dy, + int graphic) { Bitmap *src_bitmap; int src_x, src_y; + int width, height, cx, cy; + int sx = SCREENX(x), sy = SCREENY(y); + int crumbled_border_size = graphic_info[graphic].border_size; + int i; + + getGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y); + + for (i = 1; i < 4; i++) + { + int dxx = (i & 1 ? dx : 0); + int dyy = (i & 2 ? dy : 0); + int xx = x + dxx; + int yy = y + dyy; + int element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) : + BorderElement); + + /* check if neighbour field is of same crumble type */ + boolean same = (IS_CRUMBLED_TILE(xx, yy, element) && + graphic_info[graphic].class == + graphic_info[el_act2crm(element, ACTION_DEFAULT)].class); + + /* return if check prevents inner corner */ + if (same == (dxx == dx && dyy == dy)) + return; + } + + /* if we reach this point, we have an inner corner */ + + getGraphicSource(graphic, 1, &src_bitmap, &src_x, &src_y); + + width = crumbled_border_size; + height = crumbled_border_size; + cx = (dx > 0 ? TILEX - crumbled_border_size : 0); + cy = (dy > 0 ? TILEY - crumbled_border_size : 0); + + BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy, + width, height, FX + sx * TILEX + cx, FY + sy * TILEY + cy); +} + +static void DrawLevelFieldCrumbledBorders(int x, int y, int graphic, int frame, + int dir) +{ + Bitmap *src_bitmap; + int src_x, src_y; + int width, height, bx, by, cx, cy; int sx = SCREENX(x), sy = SCREENY(y); - int element; - int width, height, cx, cy, i; int crumbled_border_size = graphic_info[graphic].border_size; + int i; + + getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y); + + /* draw simple, sloppy, non-corner-accurate crumbled border */ + +#if 1 + width = (dir == 1 || dir == 2 ? crumbled_border_size : TILEX); + height = (dir == 0 || dir == 3 ? crumbled_border_size : TILEY); + cx = (dir == 2 ? TILEX - crumbled_border_size : 0); + cy = (dir == 3 ? TILEY - crumbled_border_size : 0); +#else + if (dir == 1 || dir == 2) /* left or right crumbled border */ + { + width = crumbled_border_size; + height = TILEY; + cx = (dir == 2 ? TILEX - crumbled_border_size : 0); + cy = 0; + } + else /* top or bottom crumbled border */ + { + width = TILEX; + height = crumbled_border_size; + cx = 0; + cy = (dir == 3 ? TILEY - crumbled_border_size : 0); + } +#endif + + BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy, + width, height, FX + sx * TILEX + cx, FY + sy * TILEY + cy); + + /* (remaining middle border part must be at least as big as corner part) */ + if (!(graphic_info[graphic].style & STYLE_ACCURATE_BORDERS) || + crumbled_border_size >= TILESIZE / 3) + return; + + /* correct corners of crumbled border, if needed */ + +#if 1 + for (i = -1; i <= 1; i+=2) + { + int xx = x + (dir == 0 || dir == 3 ? i : 0); + int yy = y + (dir == 1 || dir == 2 ? i : 0); + int element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) : + BorderElement); + + /* check if neighbour field is of same crumble type */ + if (IS_CRUMBLED_TILE(xx, yy, element) && + graphic_info[graphic].class == + graphic_info[el_act2crm(element, ACTION_DEFAULT)].class) + { + /* no crumbled corner, but continued crumbled border */ + + int c1 = (dir == 2 || dir == 3 ? TILESIZE - crumbled_border_size : 0); + int c2 = (i == 1 ? TILESIZE - crumbled_border_size : 0); + int b1 = (i == 1 ? crumbled_border_size : + TILESIZE - 2 * crumbled_border_size); + + width = crumbled_border_size; + height = crumbled_border_size; + + if (dir == 1 || dir == 2) + { + cx = c1; + cy = c2; + bx = cx; + by = b1; + } + else + { + cx = c2; + cy = c1; + bx = b1; + by = cy; + } + + BlitBitmap(src_bitmap, drawto_field, src_x + bx, src_y + by, + width, height, FX + sx * TILEX + cx, FY + sy * TILEY + cy); + } + } +#else + if (dir == 1 || dir == 2) /* left or right crumbled border */ + { + for (i = -1; i <= 1; i+=2) + { + int xx = x; + int yy = y + i; + int element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) : + BorderElement); + + /* check if neighbour field is of same crumble type */ + if (IS_CRUMBLED_TILE(xx, yy, element) && + graphic_info[graphic].class == + graphic_info[el_act2crm(element, ACTION_DEFAULT)].class) + { + /* no crumbled corner, but continued crumbled border */ + + width = crumbled_border_size; + height = crumbled_border_size; + cx = (dir == 2 ? TILEX - crumbled_border_size : 0); + cy = (i == 1 ? TILEY - crumbled_border_size : 0); + bx = cx; + by = (i == 1 ? crumbled_border_size : + TILEY - 2 * crumbled_border_size); + + BlitBitmap(src_bitmap, drawto_field, src_x + bx, src_y + by, + width, height, FX + sx * TILEX + cx, FY + sy * TILEY + cy); + } + } + } + else /* top or bottom crumbled border */ + { + for (i = -1; i <= 1; i+=2) + { + int xx = x + i; + int yy = y; + int element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) : + BorderElement); + + /* check if neighbour field is of same crumble type */ + if (IS_CRUMBLED_TILE(xx, yy, element) && + graphic_info[graphic].class == + graphic_info[el_act2crm(element, ACTION_DEFAULT)].class) + { + /* no crumbled corner, but continued crumbled border */ + + width = crumbled_border_size; + height = crumbled_border_size; + cx = (i == 1 ? TILEX - crumbled_border_size : 0); + cy = (dir == 3 ? TILEY - crumbled_border_size : 0); + bx = (i == 1 ? crumbled_border_size : + TILEX - 2 * crumbled_border_size); + by = cy; + + BlitBitmap(src_bitmap, drawto_field, src_x + bx, src_y + by, + width, height, FX + sx * TILEX + cx, FY + sy * TILEY + cy); + } + } + } +#endif +} + +static void DrawLevelFieldCrumbledExt(int x, int y, int graphic, int frame) +{ + int sx = SCREENX(x), sy = SCREENY(y); + int element; + int i; static int xy[4][2] = { { 0, -1 }, @@ -1464,17 +1664,11 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) element = TILE_GFX_ELEMENT(x, y); /* crumble field itself */ -#if 1 if (IS_CRUMBLED_TILE(x, y, element)) -#else - if (GFX_CRUMBLED(element) && !IS_MOVING(x, y)) -#endif { if (!IN_SCR_FIELD(sx, sy)) return; - getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y); - for (i = 0; i < 4; i++) { int xx = x + xy[i][0]; @@ -1483,37 +1677,35 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) : BorderElement); - /* check if neighbour field is of same type */ + /* check if neighbour field is of same crumble type */ #if 1 - if (IS_CRUMBLED_TILE(xx, yy, element)) + if (IS_CRUMBLED_TILE(xx, yy, element) && + graphic_info[graphic].class == + graphic_info[el_act2crm(element, ACTION_DEFAULT)].class) continue; #else - if (GFX_CRUMBLED(element) && !IS_MOVING(xx, yy)) + if (IS_CRUMBLED_TILE(xx, yy, element)) continue; #endif - if (i == 1 || i == 2) - { - width = crumbled_border_size; - height = TILEY; - cx = (i == 2 ? TILEX - crumbled_border_size : 0); - cy = 0; - } - else + DrawLevelFieldCrumbledBorders(x, y, graphic, frame, i); + } + + if ((graphic_info[graphic].style & STYLE_INNER_CORNERS) && + graphic_info[graphic].anim_frames == 2) + { + for (i = 0; i < 4; i++) { - width = TILEX; - height = crumbled_border_size; - cx = 0; - cy = (i == 3 ? TILEY - crumbled_border_size : 0); - } + int dx = (i & 1 ? +1 : -1); + int dy = (i & 2 ? +1 : -1); - BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy, - width, height, FX + sx * TILEX + cx, FY + sy * TILEY + cy); + DrawLevelFieldCrumbledInnerCorners(x, y, dx, dy, graphic); + } } MarkTileDirty(sx, sy); } - else /* crumble neighbour fields */ + else /* center field not crumbled -- crumble neighbour fields */ { for (i = 0; i < 4; i++) { @@ -1522,59 +1714,28 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) int sxx = sx + xy[i][0]; int syy = sy + xy[i][1]; -#if 1 if (!IN_LEV_FIELD(xx, yy) || !IN_SCR_FIELD(sxx, syy)) continue; -#else - if (!IN_LEV_FIELD(xx, yy) || - !IN_SCR_FIELD(sxx, syy) || - IS_MOVING(xx, yy)) - continue; -#endif if (Feld[xx][yy] == EL_ELEMENT_SNAPPING) continue; element = TILE_GFX_ELEMENT(xx, yy); -#if 1 if (!IS_CRUMBLED_TILE(xx, yy, element)) continue; -#else - if (!GFX_CRUMBLED(element)) - continue; -#endif graphic = el_act2crm(element, ACTION_DEFAULT); - crumbled_border_size = graphic_info[graphic].border_size; - - getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y); - - if (i == 1 || i == 2) - { - width = crumbled_border_size; - height = TILEY; - cx = (i == 1 ? TILEX - crumbled_border_size : 0); - cy = 0; - } - else - { - width = TILEX; - height = crumbled_border_size; - cx = 0; - cy = (i == 0 ? TILEY - crumbled_border_size : 0); - } - BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy, - width, height, FX + sxx * TILEX + cx, FY + syy * TILEY + cy); + DrawLevelFieldCrumbledBorders(xx, yy, graphic, 0, 3 - i); MarkTileDirty(sxx, syy); } } } -void DrawLevelFieldCrumbledSand(int x, int y) +void DrawLevelFieldCrumbled(int x, int y) { int graphic; @@ -1593,7 +1754,7 @@ void DrawLevelFieldCrumbledSand(int x, int y) GfxElement[x][y] != EL_UNDEFINED && GFX_CRUMBLED(GfxElement[x][y])) { - DrawLevelFieldCrumbledSandDigging(x, y, GfxDir[x][y], GfxFrame[x][y]); + DrawLevelFieldCrumbledDigging(x, y, GfxDir[x][y], GfxFrame[x][y]); return; } @@ -1605,11 +1766,11 @@ void DrawLevelFieldCrumbledSand(int x, int y) graphic = el_act2crm(Feld[x][y], ACTION_DEFAULT); #endif - DrawLevelFieldCrumbledSandExt(x, y, graphic, 0); + DrawLevelFieldCrumbledExt(x, y, graphic, 0); } -void DrawLevelFieldCrumbledSandDigging(int x, int y, int direction, - int step_frame) +void DrawLevelFieldCrumbledDigging(int x, int y, int direction, + int step_frame) { int graphic1 = el_act_dir2img(GfxElement[x][y], ACTION_DIGGING, direction); int graphic2 = el_act_dir2crm(GfxElement[x][y], ACTION_DIGGING, direction); @@ -1618,10 +1779,10 @@ void DrawLevelFieldCrumbledSandDigging(int x, int y, int direction, int sx = SCREENX(x), sy = SCREENY(y); DrawGraphic(sx, sy, graphic1, frame1); - DrawLevelFieldCrumbledSandExt(x, y, graphic2, frame2); + DrawLevelFieldCrumbledExt(x, y, graphic2, frame2); } -void DrawLevelFieldCrumbledSandNeighbours(int x, int y) +void DrawLevelFieldCrumbledNeighbours(int x, int y) { int sx = SCREENX(x), sy = SCREENY(y); static int xy[4][2] = @@ -1676,7 +1837,7 @@ static int getBorderElement(int x, int y) void DrawScreenElement(int x, int y, int element) { DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING); - DrawLevelFieldCrumbledSand(LEVELX(x), LEVELY(y)); + DrawLevelFieldCrumbled(LEVELX(x), LEVELY(y)); } void DrawLevelElement(int x, int y, int element) @@ -2410,10 +2571,10 @@ inline void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic) #if 1 if (GFX_CRUMBLED(TILE_GFX_ELEMENT(x, y))) - DrawLevelFieldCrumbledSand(x, y); + DrawLevelFieldCrumbled(x, y); #else if (GFX_CRUMBLED(Feld[x][y])) - DrawLevelFieldCrumbledSand(x, y); + DrawLevelFieldCrumbled(x, y); #endif } @@ -2433,7 +2594,7 @@ void DrawLevelElementAnimationIfNeeded(int x, int y, int element) DrawGraphicAnimation(sx, sy, graphic); if (GFX_CRUMBLED(element)) - DrawLevelFieldCrumbledSand(x, y); + DrawLevelFieldCrumbled(x, y); } static int getPlayerGraphic(struct PlayerInfo *player, int move_dir) @@ -2605,7 +2766,7 @@ void DrawPlayer(struct PlayerInfo *player) int frame = getGraphicAnimationFrame(old_graphic, player->StepFrame); if (GFX_CRUMBLED(old_element)) - DrawLevelFieldCrumbledSandDigging(jx, jy, move_dir, player->StepFrame); + DrawLevelFieldCrumbledDigging(jx, jy, move_dir, player->StepFrame); else DrawGraphic(sx, sy, old_graphic, frame); @@ -7789,11 +7950,6 @@ void getGraphicSource_SP(struct GraphicInfo_SP *g_sp, getGraphicSource(graphic, frame, &g_sp->bitmap, &g_sp->src_x, &g_sp->src_y); } -boolean isRandomAnimation_SP(int graphic) -{ - return (ANIM_MODE(graphic) == ANIM_RANDOM); -} - boolean isNextAnimationFrame_SP(int graphic, int sync_frame) { return (IS_NEXT_FRAME(sync_frame, graphic)); @@ -7898,30 +8054,16 @@ void ToggleFullscreenIfNeeded() if (!video.fullscreen_available) return; -#if 1 if (change_fullscreen || change_fullscreen_mode) -#else - if (setup.fullscreen != video.fullscreen_enabled || - setup.fullscreen_mode != video.fullscreen_mode_current) -#endif { Bitmap *tmp_backbuffer = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH); /* save backbuffer content which gets lost when toggling fullscreen mode */ BlitBitmap(backbuffer, tmp_backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); -#if 1 if (change_fullscreen_mode) -#else - if (setup.fullscreen && video.fullscreen_enabled) -#endif { /* keep fullscreen, but change fullscreen mode (screen resolution) */ -#if 1 - /* (this is now set in sdl.c) */ -#else - video.fullscreen_mode_current = setup.fullscreen_mode; -#endif video.fullscreen_enabled = FALSE; /* force new fullscreen mode */ } @@ -7943,3 +8085,81 @@ void ToggleFullscreenIfNeeded() #endif } } + +void ChangeViewportPropertiesIfNeeded() +{ + int *door_1_x = &DX; + int *door_1_y = &DY; + int *door_2_x = (game_status == GAME_MODE_EDITOR ? &EX : &VX); + int *door_2_y = (game_status == GAME_MODE_EDITOR ? &EY : &VY); + int gfx_game_mode = (game_status == GAME_MODE_PLAYING || + game_status == GAME_MODE_EDITOR ? game_status : + GAME_MODE_MAIN); + struct RectWithBorder *vp_playfield = &viewport.playfield[gfx_game_mode]; + struct RectWithBorder *vp_door_1 = &viewport.door_1[gfx_game_mode]; + struct RectWithBorder *vp_door_2 = &viewport.door_2[gfx_game_mode]; + int border_size = vp_playfield->border_size; + int new_sx = vp_playfield->x + border_size; + int new_sy = vp_playfield->y + border_size; + int new_scr_fieldx = (vp_playfield->width - 2 * border_size) / TILESIZE; + int new_scr_fieldy = (vp_playfield->height - 2 * border_size) / TILESIZE; + +#if 0 + /* !!! TEST ONLY !!! */ + // InitGfxBuffers(); + return; +#endif + + if (viewport.window.width != WIN_XSIZE || + viewport.window.height != WIN_YSIZE) + { + WIN_XSIZE = viewport.window.width; + WIN_YSIZE = viewport.window.height; + + InitVideoBuffer(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, setup.fullscreen); + InitGfxBuffers(); + +#if 1 + SetDrawDeactivationMask(REDRAW_NONE); + SetDrawBackgroundMask(REDRAW_FIELD); + + // RedrawBackground(); +#endif + } + + if (new_scr_fieldx != SCR_FIELDX || + new_scr_fieldy != SCR_FIELDY || + new_sx != SX || + new_sy != SY || + vp_playfield->x != REAL_SX || + vp_playfield->y != REAL_SY || + vp_door_1->x != *door_1_x || + vp_door_1->y != *door_1_y || + vp_door_2->x != *door_2_x || + vp_door_2->y != *door_2_y) + { + SCR_FIELDX = new_scr_fieldx; + SCR_FIELDY = new_scr_fieldy; + SX = new_sx; + SY = new_sy; + REAL_SX = vp_playfield->x; + REAL_SY = vp_playfield->y; + + *door_1_x = vp_door_1->x; + *door_1_y = vp_door_1->y; + *door_2_x = vp_door_2->x; + *door_2_y = vp_door_2->y; + + InitGfxBuffers(); + + if (gfx_game_mode == GAME_MODE_MAIN) + { + InitGadgets(); + InitToons(); + } + } + +#if 0 + printf("::: %d, %d / %d, %d [%d]\n", VX, VY, EX, EY, game_status); +#endif +}