X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame_em%2Fgraphics.c;h=236b8289bfbdff7a8b837e2e338d2ef0613c968d;hb=d14ff3d04c44d90b4dc151fd7774946e20da0152;hp=06f974a2e935777387583b68373e7897e55b2ff6;hpb=1e4a6b46371858fdb85052eec3e7143732ff91b5;p=rocksndiamonds.git diff --git a/src/game_em/graphics.c b/src/game_em/graphics.c index 06f974a2..236b8289 100644 --- a/src/game_em/graphics.c +++ b/src/game_em/graphics.c @@ -7,14 +7,43 @@ #include "display.h" #include "level.h" - -unsigned int frame; /* current screen frame */ -unsigned int screen_x; /* current scroll position */ -unsigned int screen_y; +#define MIN_SCREEN_XPOS 1 +#define MIN_SCREEN_YPOS 1 +#define MAX_SCREEN_XPOS MAX(1, lev.width - (SCR_FIELDX - 1)) +#define MAX_SCREEN_YPOS MAX(1, lev.height - (SCR_FIELDY - 1)) + +#define MIN_SCREEN_X (MIN_SCREEN_XPOS * TILEX) +#define MIN_SCREEN_Y (MIN_SCREEN_YPOS * TILEY) +#define MAX_SCREEN_X (MAX_SCREEN_XPOS * TILEX) +#define MAX_SCREEN_Y (MAX_SCREEN_YPOS * TILEY) + +#define VALID_SCREEN_X(x) ((x) < MIN_SCREEN_X ? MIN_SCREEN_X : \ + (x) > MAX_SCREEN_X ? MAX_SCREEN_X : (x)) +#define VALID_SCREEN_Y(y) ((y) < MIN_SCREEN_Y ? MIN_SCREEN_Y : \ + (y) > MAX_SCREEN_Y ? MAX_SCREEN_Y : (y)) + +#define PLAYER_SCREEN_X(p) ((( frame) * ply[p].oldx + \ + (8 - frame) * ply[p].x) * TILEX / 8 \ + - ((SCR_FIELDX - 1) * TILEX) / 2) +#define PLAYER_SCREEN_Y(p) ((( frame) * ply[p].oldy + \ + (8 - frame) * ply[p].y) * TILEY / 8 \ + - ((SCR_FIELDY - 1) * TILEY) / 2) + + +int frame; /* current screen frame */ +#if 0 +int screen_x; /* current scroll position */ +int screen_y; +#else +int screen_x; /* current scroll position */ +int screen_y; +#endif /* tiles currently on screen */ -static unsigned int screentiles[MAX_BUF_YSIZE][MAX_BUF_XSIZE]; -static unsigned int crumbled_state[MAX_BUF_YSIZE][MAX_BUF_XSIZE]; +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]; /* copy the entire screen to the window at the scroll position @@ -24,8 +53,8 @@ static unsigned int crumbled_state[MAX_BUF_YSIZE][MAX_BUF_XSIZE]; void BlitScreenToBitmap_EM(Bitmap *target_bitmap) { - unsigned int x = screen_x % (MAX_BUF_XSIZE * TILEX); - unsigned int y = screen_y % (MAX_BUF_YSIZE * TILEY); + int x = screen_x % (MAX_BUF_XSIZE * TILEX); + int y = screen_y % (MAX_BUF_YSIZE * TILEY); if (x < 2 * TILEX && y < 2 * TILEY) { @@ -69,7 +98,54 @@ void BlitScreenToBitmap_EM(Bitmap *target_bitmap) void blitscreen(void) { +#if 1 + + static boolean scrolling_last = FALSE; + int left = screen_x / TILEX; + int top = screen_y / TILEY; + boolean scrolling = (screen_x % TILEX != 0 || screen_y % TILEY != 0); + int x, y; + + SyncDisplay(); + + if (redraw_tiles > REDRAWTILES_THRESHOLD || scrolling || scrolling_last) + { + /* blit all (up to four) parts of the scroll buffer to the backbuffer */ + BlitScreenToBitmap_EM(backbuffer); + + /* blit the completely updated backbuffer to the window (in one blit) */ + BlitBitmap(backbuffer, window, SX, SY, SXSIZE, SYSIZE, SX, SY); + } + else + { + for (x = 0; x < SCR_FIELDX; x++) + { + for (y = 0; y < SCR_FIELDY; 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, SY + y * TILEY); + } + } + } + + for (x = 0; x < MAX_BUF_XSIZE; x++) + for (y = 0; y < MAX_BUF_YSIZE; y++) + redraw[x][y] = FALSE; + redraw_tiles = 0; + + scrolling_last = scrolling; + +#else + + /* blit all (up to four) parts of the scroll buffer to the window */ BlitScreenToBitmap_EM(window); + +#endif } static void DrawLevelField_EM(int x, int y, int sx, int sy, @@ -110,7 +186,7 @@ static void DrawLevelFieldCrumbled_EM(int x, int y, int sx, int sy, { int tile = Draw[y][x]; struct GraphicInfo_EM *g = &graphic_info_em_object[tile][frame]; - unsigned int i; + int i; if (crm == 0) /* no crumbled edges for this tile */ return; @@ -223,9 +299,9 @@ static void DrawLevelPlayer_EM(int x1, int y1, int player_nr, int anim, static void animscreen(void) { - unsigned int x, y, i; - unsigned int left = screen_x / TILEX; - unsigned int top = screen_y / TILEY; + int x, y, i; + int left = screen_x / TILEX; + int top = screen_y / TILEY; static int xy[4][2] = { { 0, -1 }, @@ -242,8 +318,8 @@ static void animscreen(void) int sy = y % MAX_BUF_YSIZE; int tile = Draw[y][x]; struct GraphicInfo_EM *g = &graphic_info_em_object[tile][frame]; - unsigned int obj = g->unique_identifier; - unsigned int crm = 0; + int obj = g->unique_identifier; + int crm = 0; /* re-calculate crumbled state of this tile */ if (g->has_crumbled_graphics) @@ -273,6 +349,9 @@ static void animscreen(void) screentiles[sy][sx] = obj; crumbled_state[sy][sx] = crm; + + redraw[sx][sy] = TRUE; + redraw_tiles++; } } } @@ -286,7 +365,7 @@ static void animscreen(void) static void blitplayer(struct PLAYER *ply) { - unsigned int x1, y1, x2, y2; + int x1, y1, x2, y2; if (!ply->alive) return; @@ -297,8 +376,8 @@ static void blitplayer(struct PLAYER *ply) x2 = x1 + TILEX - 1; y2 = y1 + TILEY - 1; - if ((unsigned int)(x2 - screen_x) < ((MAX_BUF_XSIZE - 1) * TILEX - 1) && - (unsigned int)(y2 - screen_y) < ((MAX_BUF_YSIZE - 1) * TILEY - 1)) + if ((int)(x2 - screen_x) < ((MAX_BUF_XSIZE - 1) * TILEX - 1) && + (int)(y2 - screen_y) < ((MAX_BUF_YSIZE - 1) * TILEY - 1)) { /* some casts to "int" are needed because of negative calculation values */ int dx = (int)ply->x - (int)ply->oldx; @@ -364,11 +443,19 @@ static void blitplayer(struct PLAYER *ply) void game_initscreen(void) { - unsigned int x,y; + int x,y; + int dynamite_state = ply[0].dynamite; /* !!! ONLY PLAYER 1 !!! */ + int all_keys_state = ply[0].keys | ply[1].keys | ply[2].keys | ply[3].keys; + int player_nr = 0; /* !!! FIX THIS (CENTERED TO PLAYER 1) !!! */ frame = 6; +#if 1 + screen_x = VALID_SCREEN_X(PLAYER_SCREEN_X(player_nr)); + screen_y = VALID_SCREEN_Y(PLAYER_SCREEN_Y(player_nr)); +#else screen_x = 0; screen_y = 0; +#endif for (y = 0; y < MAX_BUF_YSIZE; y++) { @@ -380,8 +467,8 @@ void game_initscreen(void) } #if 1 - DrawAllGameValues(lev.required, ply1.dynamite, lev.score, - lev.time, ply1.keys | ply2.keys); + DrawAllGameValues(lev.required, dynamite_state, lev.score, + lev.time, all_keys_state); #else DrawAllGameValues(lev.required, ply1.dynamite, lev.score, DISPLAY_TIME(lev.time + 4), ply1.keys | ply2.keys); @@ -390,29 +477,43 @@ void game_initscreen(void) void RedrawPlayfield_EM() { - unsigned int x,y; + int player_nr = 0; /* !!! FIX THIS (CENTERED TO PLAYER 1) !!! */ + int sx = PLAYER_SCREEN_X(player_nr); + int sy = PLAYER_SCREEN_Y(player_nr); + int i; - x = (frame * ply1.oldx + (8 - frame) * ply1.x) * TILEX / 8 - + ((SCR_FIELDX - 1) * TILEX) / 2; - y = (frame * ply1.oldy + (8 - frame) * ply1.y) * TILEY / 8 - + ((SCR_FIELDY - 1) * TILEY) / 2; +#if 1 - if (x > lev.width * TILEX) - x = lev.width * TILEX; - if (y > lev.height * TILEY) - y = lev.height * TILEY; + int offset = (setup.scroll_delay ? 3 : 0) * TILEX; - if (x < SCR_FIELDX * TILEX) - x = SCR_FIELDX * TILEY; - if (y < SCR_FIELDY * TILEY) - y = SCR_FIELDY * TILEY; + /* calculate new screen scrolling position, with regard to scroll delay */ + screen_x = VALID_SCREEN_X(sx + offset < screen_x ? sx + offset : + sx - offset > screen_x ? sx - offset : screen_x); + screen_y = VALID_SCREEN_Y(sy + offset < screen_y ? sy + offset : + sy - offset > screen_y ? sy - offset : screen_y); - screen_x = x - (SCR_FIELDX - 1) * TILEX; - screen_y = y - (SCR_FIELDY - 1) * TILEY; +#else + + if (sx > lev.width * TILEX) + sx = lev.width * TILEX; + if (sy > lev.height * TILEY) + sy = lev.height * TILEY; + + if (sx < SCR_FIELDX * TILEX) + sx = SCR_FIELDX * TILEY; + if (sy < SCR_FIELDY * TILEY) + sy = SCR_FIELDY * TILEY; + + screen_x = sx - (SCR_FIELDX - 1) * TILEX; + screen_y = sy - (SCR_FIELDY - 1) * TILEY; + +#endif animscreen(); - blitplayer(&ply1); - blitplayer(&ply2); + + for (i = 0; i < MAX_PLAYERS; i++) + blitplayer(&ply[i]); + blitscreen(); FlushDisplay(); @@ -425,9 +526,12 @@ void game_animscreen(void) void DrawGameDoorValues_EM() { + int dynamite_state = ply[0].dynamite; /* !!! ONLY PLAYER 1 !!! */ + int all_keys_state = ply[0].keys | ply[1].keys | ply[2].keys | ply[3].keys; + #if 1 - DrawAllGameValues(lev.required, ply1.dynamite, lev.score, - lev.time, ply1.keys | ply2.keys); + DrawAllGameValues(lev.required, dynamite_state, lev.score, + lev.time, all_keys_state); #else DrawAllGameValues(lev.required, ply1.dynamite, lev.score, DISPLAY_TIME(lev.time), ply1.keys | ply2.keys);