return s;
}
-void DumpTile(int x, int y)
+int correctLevelPosX_EM(int lx)
{
- int sx = SCREENX(x);
- int sy = SCREENY(y);
+ lx -= 1;
+ lx -= (BorderElement != EL_EMPTY ? 1 : 0);
- if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ return lx;
+}
+
+int correctLevelPosY_EM(int ly)
+{
+ ly -= 1;
+ ly -= (BorderElement != EL_EMPTY ? 1 : 0);
+
+ return ly;
+}
+
+static int getFieldbufferOffsetX_RND()
+{
+ int full_lev_fieldx = lev_fieldx + (BorderElement != EL_EMPTY ? 2 : 0);
+ int dx = (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
+ int dx_var = dx * TILESIZE_VAR / TILESIZE;
+ int fx = FX;
+
+ if (EVEN(SCR_FIELDX))
{
- x--;
- y--;
+ int ffx = (scroll_x - SBX_Left) * TILEX_VAR + dx_var;
+
+ if (ffx < SBX_Right * TILEX_VAR + TILEX_VAR / 2 + TILEX_VAR)
+ fx += dx_var - MIN(ffx, TILEX_VAR / 2) + TILEX_VAR;
+ else
+ fx += (dx_var > 0 ? TILEX_VAR : 0);
+ }
+ else
+ {
+ fx += dx_var;
}
+ if (full_lev_fieldx <= SCR_FIELDX)
+ {
+ if (EVEN(SCR_FIELDX))
+ fx = 2 * TILEX_VAR - (ODD(lev_fieldx) ? TILEX_VAR / 2 : 0);
+ else
+ fx = 2 * TILEX_VAR - (EVEN(lev_fieldx) ? TILEX_VAR / 2 : 0);
+ }
+
+ return fx;
+}
+
+static int getFieldbufferOffsetY_RND()
+{
+ int full_lev_fieldy = lev_fieldy + (BorderElement != EL_EMPTY ? 2 : 0);
+ int dy = (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0);
+ int dy_var = dy * TILESIZE_VAR / TILESIZE;
+ int fy = FY;
+
+ if (EVEN(SCR_FIELDY))
+ {
+ int ffy = (scroll_y - SBY_Upper) * TILEY_VAR + dy_var;
+
+ if (ffy < SBY_Lower * TILEY_VAR + TILEY_VAR / 2 + TILEY_VAR)
+ fy += dy_var - MIN(ffy, TILEY_VAR / 2) + TILEY_VAR;
+ else
+ fy += (dy_var > 0 ? TILEY_VAR : 0);
+ }
+ else
+ {
+ fy += dy_var;
+ }
+
+ if (full_lev_fieldy <= SCR_FIELDY)
+ {
+ if (EVEN(SCR_FIELDY))
+ fy = 2 * TILEY_VAR - (ODD(lev_fieldy) ? TILEY_VAR / 2 : 0);
+ else
+ fy = 2 * TILEY_VAR - (EVEN(lev_fieldy) ? TILEY_VAR / 2 : 0);
+ }
+
+ return fy;
+}
+
+static int getLevelFromScreenX_RND(int sx)
+{
+ int fx = getFieldbufferOffsetX_RND();
+ int dx = fx - FX;
+ int px = sx - SX;
+ int lx = LEVELX((px + dx) / TILESIZE_VAR);
+
+ return lx;
+}
+
+static int getLevelFromScreenY_RND(int sy)
+{
+ int fy = getFieldbufferOffsetY_RND();
+ int dy = fy - FY;
+ int py = sy - SY;
+ int ly = LEVELY((py + dy) / TILESIZE_VAR);
+
+ return ly;
+}
+
+static int getLevelFromScreenX_EM(int sx)
+{
+ int level_xsize = level.native_em_level->lev->width;
+ int full_xsize = level_xsize * TILESIZE_VAR;
+
+ sx -= (full_xsize < SXSIZE ? (SXSIZE - full_xsize) / 2 : 0);
+
+ int fx = getFieldbufferOffsetX_EM();
+ int dx = fx;
+ int px = sx - SX;
+ int lx = LEVELX((px + dx) / TILESIZE_VAR);
+
+ lx = correctLevelPosX_EM(lx);
+
+ return lx;
+}
+
+static int getLevelFromScreenY_EM(int sy)
+{
+ int level_ysize = level.native_em_level->lev->height;
+ int full_ysize = level_ysize * TILESIZE_VAR;
+
+ sy -= (full_ysize < SYSIZE ? (SYSIZE - full_ysize) / 2 : 0);
+
+ int fy = getFieldbufferOffsetY_EM();
+ int dy = fy;
+ int py = sy - SY;
+ int ly = LEVELY((py + dy) / TILESIZE_VAR);
+
+ ly = correctLevelPosY_EM(ly);
+
+ return ly;
+}
+
+static int getLevelFromScreenX_SP(int sx)
+{
+ int menBorder = setup.sp_show_border_elements;
+ int level_xsize = level.native_sp_level->width;
+ int full_xsize = (level_xsize - (menBorder ? 0 : 1)) * TILESIZE_VAR;
+
+ sx += (full_xsize < SXSIZE ? (SXSIZE - full_xsize) / 2 : 0);
+
+ int fx = getFieldbufferOffsetX_SP();
+ int dx = fx - FX;
+ int px = sx - SX;
+ int lx = LEVELX((px + dx) / TILESIZE_VAR);
+
+ return lx;
+}
+
+static int getLevelFromScreenY_SP(int sy)
+{
+ int menBorder = setup.sp_show_border_elements;
+ int level_ysize = level.native_sp_level->height;
+ int full_ysize = (level_ysize - (menBorder ? 0 : 1)) * TILESIZE_VAR;
+
+ sy += (full_ysize < SYSIZE ? (SYSIZE - full_ysize) / 2 : 0);
+
+ int fy = getFieldbufferOffsetY_SP();
+ int dy = fy - FY;
+ int py = sy - SY;
+ int ly = LEVELY((py + dy) / TILESIZE_VAR);
+
+ return ly;
+}
+
+int getLevelFromScreenX(int x)
+{
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ return getLevelFromScreenX_EM(x);
+ if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
+ return getLevelFromScreenX_SP(x);
+ else
+ return getLevelFromScreenX_RND(x);
+}
+
+int getLevelFromScreenY(int y)
+{
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ return getLevelFromScreenY_EM(y);
+ if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
+ return getLevelFromScreenY_SP(y);
+ else
+ return getLevelFromScreenY_RND(y);
+}
+
+void DumpTile(int x, int y)
+{
+ int sx = SCREENX(x);
+ int sy = SCREENY(y);
+
printf_line("-", 79);
printf("Field Info: SCREEN(%d, %d), LEVEL(%d, %d)\n", sx, sy, x, y);
printf_line("-", 79);
printf(" GfxElement: %d\n", GfxElement[x][y]);
printf(" GfxAction: %d\n", GfxAction[x][y]);
printf(" GfxFrame: %d [%d]\n", GfxFrame[x][y], FrameCounter);
+ printf(" Player x/y: %d, %d\n", local_player->jx, local_player->jy);
printf("\n");
}
+void DumpTileFromScreen(int sx, int sy)
+{
+ int lx = getLevelFromScreenX(sx);
+ int ly = getLevelFromScreenY(sy);
+
+ DumpTile(lx, ly);
+}
+
void SetDrawtoField(int mode)
{
if (mode == DRAW_TO_FIELDBUFFER)
void BlitScreenToBitmap_RND(Bitmap *target_bitmap)
{
- int fx = FX, fy = FY;
- int full_lev_fieldx = lev_fieldx + (BorderElement != EL_EMPTY ? 2 : 0);
- int full_lev_fieldy = lev_fieldy + (BorderElement != EL_EMPTY ? 2 : 0);
-
- int dx = (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
- int dy = (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0);
- int dx_var = dx * TILESIZE_VAR / TILESIZE;
- int dy_var = dy * TILESIZE_VAR / TILESIZE;
- int ffx, ffy;
-
- ffx = (scroll_x - SBX_Left) * TILEX_VAR + dx_var;
- ffy = (scroll_y - SBY_Upper) * TILEY_VAR + dy_var;
-
- if (EVEN(SCR_FIELDX))
- {
- if (ffx < SBX_Right * TILEX_VAR + TILEX_VAR / 2 + TILEX_VAR)
- fx += dx_var - MIN(ffx, TILEX_VAR / 2) + TILEX_VAR;
- else
- fx += (dx_var > 0 ? TILEX_VAR : 0);
- }
- else
- {
- fx += dx_var;
- }
-
- if (EVEN(SCR_FIELDY))
- {
- if (ffy < SBY_Lower * TILEY_VAR + TILEY_VAR / 2 + TILEY_VAR)
- fy += dy_var - MIN(ffy, TILEY_VAR / 2) + TILEY_VAR;
- else
- fy += (dy_var > 0 ? TILEY_VAR : 0);
- }
- else
- {
- fy += dy_var;
- }
-
- if (full_lev_fieldx <= SCR_FIELDX)
- {
- if (EVEN(SCR_FIELDX))
- fx = 2 * TILEX_VAR - (ODD(lev_fieldx) ? TILEX_VAR / 2 : 0);
- else
- fx = 2 * TILEX_VAR - (EVEN(lev_fieldx) ? TILEX_VAR / 2 : 0);
- }
-
- if (full_lev_fieldy <= SCR_FIELDY)
- {
- if (EVEN(SCR_FIELDY))
- fy = 2 * TILEY_VAR - (ODD(lev_fieldy) ? TILEY_VAR / 2 : 0);
- else
- fy = 2 * TILEY_VAR - (EVEN(lev_fieldy) ? TILEY_VAR / 2 : 0);
- }
+ int fx = getFieldbufferOffsetX_RND();
+ int fy = getFieldbufferOffsetY_RND();
BlitBitmap(drawto_field, target_bitmap, fx, fy, SXSIZE, SYSIZE, SX, SY);
}
int width, height, cx, cy;
int sx = SCREENX(x), sy = SCREENY(y);
int crumbled_border_size = graphic_info[graphic].border_size;
+ int crumbled_tile_size = graphic_info[graphic].tile_size;
+ int crumbled_border_size_var =
+ crumbled_border_size * TILESIZE_VAR / crumbled_tile_size;
int i;
getGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y);
getGraphicSource(graphic, 1, &src_bitmap, &src_x, &src_y);
- width = crumbled_border_size * TILESIZE_VAR / TILESIZE;
- height = crumbled_border_size * TILESIZE_VAR / TILESIZE;
+ width = crumbled_border_size_var;
+ height = crumbled_border_size_var;
cx = (dx > 0 ? TILESIZE_VAR - width : 0);
cy = (dy > 0 ? TILESIZE_VAR - height : 0);
int width, height, bx, by, cx, cy;
int sx = SCREENX(x), sy = SCREENY(y);
int crumbled_border_size = graphic_info[graphic].border_size;
- int crumbled_border_size_var = crumbled_border_size * TILESIZE_VAR / TILESIZE;
+ int crumbled_tile_size = graphic_info[graphic].tile_size;
+ int crumbled_border_size_var =
+ crumbled_border_size * TILESIZE_VAR / crumbled_tile_size;
int crumbled_border_pos_var = TILESIZE_VAR - crumbled_border_size_var;
int i;
/* (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)
+ crumbled_border_size_var >= TILESIZE_VAR / 3)
return;
/* correct corners of crumbled border, if needed */
element = TILE_GFX_ELEMENT(x, y);
- /* crumble field itself */
- if (IS_CRUMBLED_TILE(x, y, element))
+ if (IS_CRUMBLED_TILE(x, y, element)) /* crumble field itself */
{
if (!IN_SCR_FIELD(sx, sy))
return;
+ /* crumble field borders towards direct neighbour fields */
for (i = 0; i < 4; i++)
{
int xx = x + xy[i][0];
DrawLevelFieldCrumbledBorders(x, y, graphic, frame, i);
}
+ /* crumble inner field corners towards corner neighbour fields */
if ((graphic_info[graphic].style & STYLE_INNER_CORNERS) &&
graphic_info[graphic].anim_frames == 2)
{
MarkTileDirty(sx, sy);
}
- else /* center field not crumbled -- crumble neighbour fields */
+ else /* center field is not crumbled -- crumble neighbour fields */
{
+ /* crumble field borders of direct neighbour fields */
for (i = 0; i < 4; i++)
{
int xx = x + xy[i][0];
MarkTileDirty(sxx, syy);
}
+
+ /* crumble inner field corners of corner neighbour fields */
+ for (i = 0; i < 4; i++)
+ {
+ int dx = (i & 1 ? +1 : -1);
+ int dy = (i & 2 ? +1 : -1);
+ int xx = x + dx;
+ int yy = y + dy;
+ int sxx = sx + dx;
+ int syy = sy + dy;
+
+ if (!IN_LEV_FIELD(xx, yy) ||
+ !IN_SCR_FIELD(sxx, syy))
+ continue;
+
+ if (Feld[xx][yy] == EL_ELEMENT_SNAPPING)
+ continue;
+
+ element = TILE_GFX_ELEMENT(xx, yy);
+
+ if (!IS_CRUMBLED_TILE(xx, yy, element))
+ continue;
+
+ graphic = el_act2crm(element, ACTION_DEFAULT);
+
+ if ((graphic_info[graphic].style & STYLE_INNER_CORNERS) &&
+ graphic_info[graphic].anim_frames == 2)
+ DrawLevelFieldCrumbledInnerCorners(xx, yy, -dx, -dy, graphic);
+
+ MarkTileDirty(sxx, syy);
+ }
}
}
};
int i;
+ /* crumble direct neighbour fields (required for field borders) */
for (i = 0; i < 4; i++)
{
int xx = x + xy[i][0];
DrawLevelField(xx, yy);
}
+
+ /* crumble corner neighbour fields (required for inner field corners) */
+ for (i = 0; i < 4; i++)
+ {
+ int dx = (i & 1 ? +1 : -1);
+ int dy = (i & 2 ? +1 : -1);
+ int xx = x + dx;
+ int yy = y + dy;
+ int sxx = sx + dx;
+ int syy = sy + dy;
+
+ if (!IN_LEV_FIELD(xx, yy) ||
+ !IN_SCR_FIELD(sxx, syy) ||
+ !GFX_CRUMBLED(Feld[xx][yy]) ||
+ IS_MOVING(xx, yy))
+ continue;
+
+ int element = TILE_GFX_ELEMENT(xx, yy);
+ int graphic = el_act2crm(element, ACTION_DEFAULT);
+
+ if ((graphic_info[graphic].style & STYLE_INNER_CORNERS) &&
+ graphic_info[graphic].anim_frames == 2)
+ DrawLevelField(xx, yy);
+ }
}
static int getBorderElement(int x, int y)
int newly = ly + (dir == MV_UP ? -1 : dir == MV_DOWN ? +1 : 0);
DrawLevelElementThruMask(newlx, newly, EL_ACID);
+
+ // prevent target field from being drawn again (but without masking)
+ // (this would happen if target field is scanned after moving element)
+ Stop[newlx][newly] = TRUE;
}
}
else if (IS_BLOCKED(lx, ly))
&g_em->crumbled_src_x, &g_em->crumbled_src_y);
g_em->crumbled_border_size = graphic_info[crumbled].border_size;
+ g_em->crumbled_tile_size = graphic_info[crumbled].tile_size;
g_em->has_crumbled_graphics = TRUE;
}
g_em->crumbled_src_x = 0;
g_em->crumbled_src_y = 0;
g_em->crumbled_border_size = 0;
+ g_em->crumbled_tile_size = 0;
g_em->has_crumbled_graphics = FALSE;
}
boolean any_player_snapping,
boolean any_player_dropping)
{
- static boolean player_was_waiting = TRUE;
-
if (frame == 0 && !any_player_dropping)
{
- if (!player_was_waiting)
+ if (!local_player->was_waiting)
{
- if (!SaveEngineSnapshotToList())
+ if (!CheckSaveEngineSnapshotToList())
return;
- player_was_waiting = TRUE;
+ local_player->was_waiting = TRUE;
}
}
else if (any_player_moving || any_player_snapping || any_player_dropping)
{
- player_was_waiting = FALSE;
+ local_player->was_waiting = FALSE;
}
}
void CheckSaveEngineSnapshot_SP(boolean murphy_is_waiting,
boolean murphy_is_dropping)
{
- static boolean player_was_waiting = TRUE;
-
if (murphy_is_waiting)
{
- if (!player_was_waiting)
+ if (!local_player->was_waiting)
{
- if (!SaveEngineSnapshotToList())
+ if (!CheckSaveEngineSnapshotToList())
return;
- player_was_waiting = TRUE;
+ local_player->was_waiting = TRUE;
}
}
else
{
- player_was_waiting = FALSE;
+ local_player->was_waiting = FALSE;
}
}