From 44b31e75162d6e446a9e9b454a079a2da5604fdf Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Wed, 21 Apr 2010 00:41:51 +0200 Subject: [PATCH] rnd-20100421-1-src * changed native Emerald Mine engine to support different viewport sizes * changed native Supaplex engine to support different viewport sizes --- ChangeLog | 6 ++++ src/conftime.h | 2 +- src/game_em/graphics.c | 57 +++++++++++++++++++++++++++++-- src/game_em/main_em.h | 8 +++++ src/init.c | 1 + src/libgame/system.c | 76 ++++++++++++++++++++++++++++++++++++++---- src/libgame/system.h | 5 +++ 7 files changed, 144 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 285539ca..ae08cbe1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-04-20 + * changed native Emerald Mine engine to support different viewport sizes + +2010-04-19 + * changed native Supaplex engine to support different viewport sizes + 2010-04-07 * added initial, experimental support for different viewport properties (with "viewports" being menu/playfield area and doors; currently the diff --git a/src/conftime.h b/src/conftime.h index bd403855..a6bfb390 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "2010-04-20 17:35" +#define COMPILE_DATE_STRING "2010-04-21 00:32" diff --git a/src/game_em/graphics.c b/src/game_em/graphics.c index 29d9e15d..d7640e77 100644 --- a/src/game_em/graphics.c +++ b/src/game_em/graphics.c @@ -29,15 +29,21 @@ #define USE_EXTENDED_GRAPHICS_ENGINE 1 -int frame; /* current screen frame */ -int screen_x; /* current scroll position */ -int screen_y; +int frame; /* current screen frame */ +int screen_x, screen_y; /* current scroll position */ /* tiles currently on screen */ +#if 1 +static int screentiles[MAX_PLAYFIELD_HEIGHT + 2][MAX_PLAYFIELD_WIDTH + 2]; +static int crumbled_state[MAX_PLAYFIELD_HEIGHT + 2][MAX_PLAYFIELD_WIDTH + 2]; + +static boolean redraw[MAX_PLAYFIELD_WIDTH + 2][MAX_PLAYFIELD_HEIGHT + 2]; +#else static int screentiles[MAX_BUF_YSIZE][MAX_BUF_XSIZE]; static int crumbled_state[MAX_BUF_YSIZE][MAX_BUF_XSIZE]; static boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE]; +#endif #if 0 #if 1 @@ -96,12 +102,21 @@ void BlitScreenToBitmap_EM(Bitmap *target_bitmap) void BackToFront_EM(void) { + static int screen_x_last = -1, screen_y_last = -1; static boolean scrolling_last = FALSE; int left = screen_x / TILEX; int top = screen_y / TILEY; +#if 1 + boolean scrolling = (screen_x != screen_x_last || screen_y != screen_y_last); +#else boolean scrolling = (screen_x % TILEX != 0 || screen_y % TILEY != 0); +#endif int x, y; +#if 0 + printf("::: %d, %d\n", screen_x, screen_y); +#endif + SyncDisplay(); if (redraw_tiles > REDRAWTILES_THRESHOLD || scrolling || scrolling_last) @@ -114,6 +129,35 @@ void BackToFront_EM(void) } else { +#if 1 + boolean half_shifted_x = (EVEN(SCR_FIELDX) && screen_x % TILEX); + boolean half_shifted_y = (EVEN(SCR_FIELDY) && screen_y % TILEY); + int x1 = 0, x2 = SCR_FIELDX - (half_shifted_x ? 0 : 1); + int y1 = 0, y2 = SCR_FIELDY - (half_shifted_y ? 0 : 1); + int scroll_xoffset = (half_shifted_x ? TILEX / 2 : 0); + int scroll_yoffset = (half_shifted_y ? TILEY / 2 : 0); + + InitGfxClipRegion(TRUE, SX, SY, SXSIZE, SYSIZE); + + for (x = x1; x <= x2; x++) + { + for (y = y1; y <= y2; y++) + { + int xx = (left + x) % MAX_BUF_XSIZE; + int yy = (top + y) % MAX_BUF_YSIZE; + + if (redraw[xx][yy]) + BlitBitmap(screenBitmap, window, + xx * TILEX, yy * TILEY, TILEX, TILEY, + SX + x * TILEX - scroll_xoffset, + SY + y * TILEY - scroll_yoffset); + } + } + + InitGfxClipRegion(FALSE, -1, -1, -1, -1); + +#else + for (x = 0; x < SCR_FIELDX; x++) { for (y = 0; y < SCR_FIELDY; y++) @@ -127,6 +171,7 @@ void BackToFront_EM(void) SX + x * TILEX, SY + y * TILEY); } } +#endif } FlushDisplay(); @@ -136,6 +181,8 @@ void BackToFront_EM(void) redraw[x][y] = FALSE; redraw_tiles = 0; + screen_x_last = screen_x; + screen_y_last = screen_y; scrolling_last = scrolling; } @@ -433,6 +480,10 @@ static void blitplayer(struct PLAYER *ply) x2 = x1 + TILEX - 1; y2 = y1 + TILEY - 1; +#if 0 + printf("::: %d, %d\n", x1, y1); +#endif + if ((int)(x2 - screen_x) < ((MAX_BUF_XSIZE - 1) * TILEX - 1) && (int)(y2 - screen_y) < ((MAX_BUF_YSIZE - 1) * TILEY - 1)) { diff --git a/src/game_em/main_em.h b/src/game_em/main_em.h index add5ae09..c5efc415 100644 --- a/src/game_em/main_em.h +++ b/src/game_em/main_em.h @@ -69,16 +69,24 @@ #define ORIG_SCR_MENUY 12 #define SCR_MENUX 17 #define SCR_MENUY 12 +#if 1 +extern int SCR_FIELDX, SCR_FIELDY; +#else #define SCR_FIELDX 17 #define SCR_FIELDY 17 +#endif #define MAX_BUF_XSIZE (SCR_FIELDX + 2) #define MAX_BUF_YSIZE (SCR_FIELDY + 2) /* often used screen positions */ #define ORIG_MENU_SX ((ORIG_SCR_MENUX - SCR_MENUX) * TILEX / 2) #define ORIG_MENU_SY 0 +#if 1 +extern int SX, SY; +#else #define SX 8 #define SY 8 +#endif #define SXSIZE (SCR_FIELDX * TILEX) #define SYSIZE (SCR_FIELDY * TILEY) diff --git a/src/init.c b/src/init.c index 3d7b3065..12dfed1a 100644 --- a/src/init.c +++ b/src/init.c @@ -5465,6 +5465,7 @@ void InitGfxBuffers() InitGfxDoor2Info(VX, VY, VXSIZE, VYSIZE); InitGfxWindowInfo(WIN_XSIZE, WIN_YSIZE); InitGfxScrollbufferInfo(FXSIZE, FYSIZE); + InitGfxClipRegion(FALSE, -1, -1, -1, -1); InitGfxBuffers_SP(); } diff --git a/src/libgame/system.c b/src/libgame/system.c index e67cbaeb..4b7a3cad 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -211,6 +211,15 @@ void InitGfxScrollbufferInfo(int scrollbuffer_width, int scrollbuffer_height) gfx.scrollbuffer_height = scrollbuffer_height; } +void InitGfxClipRegion(boolean enabled, int x, int y, int width, int height) +{ + gfx.clipping_enabled = enabled; + gfx.clip_x = x; + gfx.clip_y = y; + gfx.clip_width = width; + gfx.clip_height = height; +} + void InitGfxDrawBusyAnimFunction(void (*draw_busy_anim_function)(void)) { gfx.draw_busy_anim_function = draw_busy_anim_function; @@ -512,9 +521,61 @@ boolean DrawingOnBackground(int x, int y) CheckDrawingArea(x, y, 1, 1, gfx.draw_background_mask)); } -static boolean ValidClippedRectangle(Bitmap *bitmap, int *x, int *y, - int *width, int *height) +static boolean InClippedRectangle(Bitmap *bitmap, int *x, int *y, + int *width, int *height, boolean is_dest) { +#if 1 + int clip_x, clip_y, clip_width, clip_height; + + if (gfx.clipping_enabled && is_dest) /* only clip destination bitmap */ + { + clip_x = MIN(MAX(0, gfx.clip_x), bitmap->width); + clip_y = MIN(MAX(0, gfx.clip_y), bitmap->height); + clip_width = MIN(MAX(0, gfx.clip_width), bitmap->width - clip_x); + clip_height = MIN(MAX(0, gfx.clip_height), bitmap->height - clip_y); + } + else + { + clip_x = 0; + clip_y = 0; + clip_width = bitmap->width; + clip_height = bitmap->height; + } + + /* skip if rectangle completely outside bitmap */ + + if (*x + *width <= clip_x || + *y + *height <= clip_y || + *x >= clip_x + clip_width || + *y >= clip_y + clip_height) + return FALSE; + + /* clip if rectangle overlaps bitmap */ + + if (*x < clip_x) + { + *width -= clip_x - *x; + *x = clip_x; + } + else if (*x + *width > clip_x + clip_width) + { + *width = clip_x + clip_width - *x; + } + + if (*y < clip_y) + { + *height -= clip_y - *y; + *y = clip_y; + } + else if (*y + *height > clip_y + clip_height) + { + *height = clip_y + clip_height - *y; + } + + return TRUE; + +#else + /* skip if rectangle completely outside bitmap */ if (*x + *width <= 0 || @@ -546,6 +607,7 @@ static boolean ValidClippedRectangle(Bitmap *bitmap, int *x, int *y, } return TRUE; +#endif } void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap, @@ -559,8 +621,8 @@ void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap, return; #if 1 - if (!ValidClippedRectangle(src_bitmap, &src_x, &src_y, &width, &height) || - !ValidClippedRectangle(dst_bitmap, &dst_x, &dst_y, &width, &height)) + if (!InClippedRectangle(src_bitmap, &src_x, &src_y, &width, &height, FALSE) || + !InClippedRectangle(dst_bitmap, &dst_x, &dst_y, &width, &height, TRUE)) return; /* source x/y might need adjustment if destination x/y was clipped top/left */ @@ -648,8 +710,8 @@ void FadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, void (*draw_border_function)(void)) { #if 1 - /* (use bitmap "backbuffer" -- "bitmap_cross" may be undefined) */ - if (!ValidClippedRectangle(backbuffer, &x, &y, &width, &height)) + /* (use destination bitmap "backbuffer" -- "bitmap_cross" may be undefined) */ + if (!InClippedRectangle(backbuffer, &x, &y, &width, &height, TRUE)) return; #endif @@ -669,7 +731,7 @@ void FillRectangle(Bitmap *bitmap, int x, int y, int width, int height, return; #if 1 - if (!ValidClippedRectangle(bitmap, &x, &y, &width, &height)) + if (!InClippedRectangle(bitmap, &x, &y, &width, &height, TRUE)) return; #else /* skip if rectangle starts outside bitmap */ diff --git a/src/libgame/system.h b/src/libgame/system.h index 51017fec..cbcf5c86 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -754,6 +754,10 @@ struct GfxInfo Bitmap *background_bitmap; int background_bitmap_mask; + boolean clipping_enabled; + int clip_x, clip_y; + int clip_width, clip_height; + boolean override_level_graphics; boolean override_level_sounds; boolean override_level_music; @@ -1186,6 +1190,7 @@ void InitGfxDoor1Info(int, int, int, int); void InitGfxDoor2Info(int, int, int, int); void InitGfxWindowInfo(int, int); void InitGfxScrollbufferInfo(int, int); +void InitGfxClipRegion(boolean, int, int, int, int); void InitGfxDrawBusyAnimFunction(void (*draw_busy_anim_function)(void)); void InitGfxCustomArtworkInfo(); void SetDrawDeactivationMask(int); -- 2.34.1