From 49e5cc70747062c45172e6106b8bec41d2e859ad Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 7 Nov 2016 20:39:53 +0100 Subject: [PATCH] added functions to get level position (tile) from screen position (pixel) --- src/game_em/export.h | 3 + src/game_em/graphics.c | 10 ++ src/game_sp/DDScrollBuffer.c | 47 ++++--- src/game_sp/export.h | 3 + src/tools.c | 254 ++++++++++++++++++++++++++++------- src/tools.h | 4 + 6 files changed, 254 insertions(+), 67 deletions(-) diff --git a/src/game_em/export.h b/src/game_em/export.h index efc02cc5..0968f1d6 100644 --- a/src/game_em/export.h +++ b/src/game_em/export.h @@ -739,6 +739,9 @@ extern unsigned int InitEngineRandom_EM(int); extern void setLevelInfoToDefaults_EM(); extern boolean LoadNativeLevel_EM(char *, boolean); +extern int getFieldbufferOffsetX_EM(); +extern int getFieldbufferOffsetY_EM(); + extern void BackToFront_EM(void); extern void BlitScreenToBitmap_EM(Bitmap *); extern void RedrawPlayfield_EM(boolean); diff --git a/src/game_em/graphics.c b/src/game_em/graphics.c index 54711e95..3c68eb03 100644 --- a/src/game_em/graphics.c +++ b/src/game_em/graphics.c @@ -37,6 +37,16 @@ int screen_x, screen_y; /* current scroll position */ static int screentiles[MAX_PLAYFIELD_HEIGHT + 2][MAX_PLAYFIELD_WIDTH + 2]; static int crumbled_state[MAX_PLAYFIELD_HEIGHT + 2][MAX_PLAYFIELD_WIDTH + 2]; +int getFieldbufferOffsetX_EM() +{ + return screen_x % TILEX; +} + +int getFieldbufferOffsetY_EM() +{ + return screen_y % TILEY; +} + void BlitScreenToBitmap_EM(Bitmap *target_bitmap) { /* blit all (up to four) parts of the scroll buffer to the target bitmap */ diff --git a/src/game_sp/DDScrollBuffer.c b/src/game_sp/DDScrollBuffer.c index d90835b3..026b80dd 100644 --- a/src/game_sp/DDScrollBuffer.c +++ b/src/game_sp/DDScrollBuffer.c @@ -13,6 +13,36 @@ int mScrollX_last, mScrollY_last; int ScreenBuffer[2 + MAX_PLAYFIELD_WIDTH + 2][2 + MAX_PLAYFIELD_HEIGHT + 2]; +int getFieldbufferOffsetX_SP() +{ + int px = 2 * TILEX + (mScrollX - mScrollX_last) % TILEX; + + /* scroll correction for even number of visible tiles (half tile shifted) */ + px += game_sp.scroll_xoffset; + + if (ExplosionShakeMurphy != 0) + px += TILEX / 2 - GetSimpleRandom(TILEX + 1); + + px = px * TILESIZE_VAR / TILESIZE; + + return px; +} + +int getFieldbufferOffsetY_SP() +{ + int py = 2 * TILEY + (mScrollY - mScrollY_last) % TILEY; + + /* scroll correction for even number of visible tiles (half tile shifted) */ + py += game_sp.scroll_yoffset; + + if (ExplosionShakeMurphy != 0) + py += TILEY / 2 - GetSimpleRandom(TILEX + 1); + + py = py * TILESIZE_VAR / TILESIZE; + + return py; +} + void RestorePlayfield() { int x1 = mScrollX / TILEX - 2; @@ -201,8 +231,8 @@ void BlitScreenToBitmap_SP(Bitmap *target_bitmap) { /* copy playfield buffer to target bitmap at scroll position */ - int px = 2 * TILEX + (mScrollX - mScrollX_last) % TILEX; - int py = 2 * TILEY + (mScrollY - mScrollY_last) % TILEY; + int px = getFieldbufferOffsetX_SP(); + int py = getFieldbufferOffsetY_SP(); int sx, sy, sxsize, sysize; int xsize = SXSIZE; int ysize = SYSIZE; @@ -214,19 +244,6 @@ void BlitScreenToBitmap_SP(Bitmap *target_bitmap) sx = SX + (full_xsize < xsize ? (xsize - full_xsize) / 2 : 0); sy = SY + (full_ysize < ysize ? (ysize - full_ysize) / 2 : 0); - /* scroll correction for even number of visible tiles (half tile shifted) */ - px += game_sp.scroll_xoffset; - py += game_sp.scroll_yoffset; - - if (ExplosionShakeMurphy != 0) - { - px += TILEX / 2 - GetSimpleRandom(TILEX + 1); - py += TILEY / 2 - GetSimpleRandom(TILEX + 1); - } - - px = px * TILESIZE_VAR / TILESIZE; - py = py * TILESIZE_VAR / TILESIZE; - BlitBitmap(bitmap_db_field_sp, target_bitmap, px, py, sxsize, sysize, sx, sy); } diff --git a/src/game_sp/export.h b/src/game_sp/export.h index 72bffa2b..4edac476 100644 --- a/src/game_sp/export.h +++ b/src/game_sp/export.h @@ -187,6 +187,9 @@ extern void copyInternalEngineVars_SP(); extern boolean LoadNativeLevel_SP(char *, int, boolean); extern void SaveNativeLevel_SP(char *); +extern int getFieldbufferOffsetX_SP(); +extern int getFieldbufferOffsetY_SP(); + extern void BlitScreenToBitmap_SP(Bitmap *); extern void RedrawPlayfield_SP(boolean); diff --git a/src/tools.c b/src/tools.c index 7888dca7..6ae0780f 100644 --- a/src/tools.c +++ b/src/tools.c @@ -192,16 +192,208 @@ static char *print_if_not_empty(int element) return s; } +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)) + { + 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; +} + +int getFieldbufferOffsetX() +{ + if (level.game_engine_type == GAME_ENGINE_TYPE_EM) + return getFieldbufferOffsetX_EM(); + if (level.game_engine_type == GAME_ENGINE_TYPE_SP) + return getFieldbufferOffsetX_SP(); + else + return getFieldbufferOffsetX_RND(); +} + +int getFieldbufferOffsetY() +{ + if (level.game_engine_type == GAME_ENGINE_TYPE_EM) + return getFieldbufferOffsetY_EM(); + if (level.game_engine_type == GAME_ENGINE_TYPE_SP) + return getFieldbufferOffsetY_SP(); + else + return getFieldbufferOffsetY_RND(); +} + +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; +} + +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) - 1; + + lx -= (BorderElement != EL_EMPTY ? 1 : 0); + + return lx; +} + +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) - 1; + + ly -= (BorderElement != EL_EMPTY ? 1 : 0); + + return ly; +} + +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; +} + +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); +#if 0 if (level.game_engine_type == GAME_ENGINE_TYPE_EM) { x--; y--; } +#endif printf_line("-", 79); printf("Field Info: SCREEN(%d, %d), LEVEL(%d, %d)\n", sx, sy, x, y); @@ -232,6 +424,14 @@ void DumpTile(int x, int y) 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) @@ -410,58 +610,8 @@ void DrawMaskedBorderToTarget(int draw_target) 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); } diff --git a/src/tools.h b/src/tools.h index 7ed5f1b1..8c8ac9c6 100644 --- a/src/tools.h +++ b/src/tools.h @@ -65,7 +65,11 @@ #define REQUEST_WAIT_FOR_INPUT (REQ_ASK | REQ_CONFIRM | REQ_PLAYER) +int getLevelFromScreenX(int); +int getLevelFromScreenY(int); + void DumpTile(int, int); +void DumpTileFromScreen(int, int); void DrawMaskedBorder_FIELD(); void DrawMaskedBorder_DOOR_1(); -- 2.34.1