X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame_em%2Fgraphics.c;h=cc746c0c399fd44da79edc8d44e5bc458ce7b453;hb=88c9b68c44a16e7df62557b63cc7e86731e028c9;hp=bc8092e4524c4f0b666ab8828115cbee57a4e3fa;hpb=a268c893d49b178fdcc80956484b567952868fd4;p=rocksndiamonds.git diff --git a/src/game_em/graphics.c b/src/game_em/graphics.c index bc8092e4..cc746c0c 100644 --- a/src/game_em/graphics.c +++ b/src/game_em/graphics.c @@ -16,57 +16,111 @@ unsigned int screen_y; static unsigned int screentiles[MAX_BUF_YSIZE][MAX_BUF_XSIZE]; static unsigned 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 * * perhaps use mit-shm to speed this up */ -void blitscreen(void) +void BlitScreenToBitmap_EM(Bitmap *target_bitmap) { unsigned int x = screen_x % (MAX_BUF_XSIZE * TILEX); unsigned int y = screen_y % (MAX_BUF_YSIZE * TILEY); if (x < 2 * TILEX && y < 2 * TILEY) { - BlitBitmap(screenBitmap, window, x, y, + BlitBitmap(screenBitmap, target_bitmap, x, y, SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY); } else if (x < 2 * TILEX && y >= 2 * TILEY) { - BlitBitmap(screenBitmap, window, x, y, + BlitBitmap(screenBitmap, target_bitmap, x, y, SCR_FIELDX * TILEX, MAX_BUF_YSIZE * TILEY - y, SX, SY); - BlitBitmap(screenBitmap, window, x, 0, + BlitBitmap(screenBitmap, target_bitmap, x, 0, SCR_FIELDX * TILEX, y - 2 * TILEY, SX, SY + MAX_BUF_YSIZE * TILEY - y); } else if (x >= 2 * TILEX && y < 2 * TILEY) { - BlitBitmap(screenBitmap, window, x, y, + BlitBitmap(screenBitmap, target_bitmap, x, y, MAX_BUF_XSIZE * TILEX - x, SCR_FIELDY * TILEY, SX, SY); - BlitBitmap(screenBitmap, window, 0, y, + BlitBitmap(screenBitmap, target_bitmap, 0, y, x - 2 * TILEX, SCR_FIELDY * TILEY, SX + MAX_BUF_XSIZE * TILEX - x, SY); } else { - BlitBitmap(screenBitmap, window, x, y, + BlitBitmap(screenBitmap, target_bitmap, x, y, MAX_BUF_XSIZE * TILEX - x, MAX_BUF_YSIZE * TILEY - y, SX, SY); - BlitBitmap(screenBitmap, window, 0, y, + BlitBitmap(screenBitmap, target_bitmap, 0, y, x - 2 * TILEX, MAX_BUF_YSIZE * TILEY - y, SX + MAX_BUF_XSIZE * TILEX - x, SY); - BlitBitmap(screenBitmap, window, x, 0, + BlitBitmap(screenBitmap, target_bitmap, x, 0, MAX_BUF_XSIZE * TILEX - x, y - 2 * TILEY, SX, SY + MAX_BUF_YSIZE * TILEY - y); - BlitBitmap(screenBitmap, window, 0, 0, + BlitBitmap(screenBitmap, target_bitmap, 0, 0, x - 2 * TILEX, y - 2 * TILEY, SX + MAX_BUF_XSIZE * TILEX - x, SY + MAX_BUF_YSIZE * TILEY - y); } } +void blitscreen(void) +{ +#if 1 + + static boolean scrolling_last = FALSE; + unsigned int left = screen_x / TILEX; + unsigned 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, boolean draw_masked) { @@ -76,25 +130,27 @@ static void DrawLevelField_EM(int x, int y, int sx, int sy, int src_y = g->src_y + g->src_offset_y; int dst_x = sx * TILEX + g->dst_offset_x; int dst_y = sy * TILEY + g->dst_offset_y; + int width = g->width; + int height = g->height; if (draw_masked) { - if (g->width > 0 && g->height > 0) + if (width > 0 && height > 0) { SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc, dst_x - src_x, dst_y - src_y); BlitBitmapMasked(g->bitmap, screenBitmap, - src_x, src_y, g->width, g->height, dst_x, dst_y); + src_x, src_y, width, height, dst_x, dst_y); } } else { - if (g->width != TILEX || g->height != TILEY) + if ((width != TILEX || height != TILEY) && !g->preserve_background) ClearRectangle(screenBitmap, sx * TILEX, sy * TILEY, TILEX, TILEY); - if (g->width > 0 && g->height > 0) + if (width > 0 && height > 0) BlitBitmap(g->bitmap, screenBitmap, - src_x, src_y, g->width, g->height, dst_x, dst_y); + src_x, src_y, width, height, dst_x, dst_y); } } @@ -218,7 +274,7 @@ static void animscreen(void) { unsigned int x, y, i; unsigned int left = screen_x / TILEX; - unsigned int top = screen_y / TILEY; + unsigned int top = screen_y / TILEY; static int xy[4][2] = { { 0, -1 }, @@ -258,6 +314,7 @@ static void animscreen(void) } } + /* only redraw screen tiles if they (or their crumbled state) changed */ if (screentiles[sy][sx] != obj || crumbled_state[sy][sx] != crm) { DrawLevelField_EM(x, y, sx, sy, FALSE); @@ -265,6 +322,9 @@ static void animscreen(void) screentiles[sy][sx] = obj; crumbled_state[sy][sx] = crm; + + redraw[sx][sy] = TRUE; + redraw_tiles++; } } } @@ -303,11 +363,13 @@ static void blitplayer(struct PLAYER *ply) int old_sy = old_y % MAX_BUF_XSIZE; int new_sx = new_x % MAX_BUF_XSIZE; int new_sy = new_y % MAX_BUF_XSIZE; +#if 0 int old_crm = crumbled_state[old_sy][old_sx]; +#endif int new_crm = crumbled_state[new_sy][new_sx]; /* only diggable elements can be crumbled in the classic EM engine */ - boolean player_is_digging = (crumbled_state[new_sy][new_sx] != 0); + boolean player_is_digging = (new_crm != 0); x1 %= MAX_BUF_XSIZE * TILEX; y1 %= MAX_BUF_YSIZE * TILEY; @@ -316,9 +378,11 @@ static void blitplayer(struct PLAYER *ply) if (player_is_digging) { +#if 0 /* draw the field the player is moving from (under the player) */ DrawLevelField_EM(old_x, old_y, old_sx, old_sy, FALSE); DrawLevelFieldCrumbled_EM(old_x, old_y, old_sx, old_sy, old_crm, FALSE); +#endif /* draw the field the player is moving to (under the player) */ DrawLevelField_EM(new_x, new_y, new_sx, new_sy, FALSE); @@ -326,6 +390,11 @@ static void blitplayer(struct PLAYER *ply) /* draw the player (masked) over the element he is just digging away */ DrawLevelPlayer_EM(x1, y1, ply->num, ply->anim, TRUE); + +#if 1 + /* draw the field the player is moving from (masked over the player) */ + DrawLevelField_EM(old_x, old_y, old_sx, old_sy, TRUE); +#endif } else { @@ -348,6 +417,8 @@ static void blitplayer(struct PLAYER *ply) void game_initscreen(void) { unsigned 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; frame = 6; screen_x = 0; @@ -362,17 +433,23 @@ void game_initscreen(void) } } - DrawGameDoorValues_EM(lev.required, ply1.dynamite, lev.score, - DISPLAY_TIME(lev.time + 4)); +#if 1 + 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); +#endif } -void game_animscreen(void) +void RedrawPlayfield_EM() { - unsigned int x,y; + unsigned int i, x, y; - x = (frame * ply1.oldx + (8 - frame) * ply1.x) * TILEX / 8 + /* !!! FIX THIS (CENTERED TO PLAYER 1) !!! */ + x = (frame * ply[0].oldx + (8 - frame) * ply[0].x) * TILEX / 8 + ((SCR_FIELDX - 1) * TILEX) / 2; - y = (frame * ply1.oldy + (8 - frame) * ply1.y) * TILEY / 8 + y = (frame * ply[0].oldy + (8 - frame) * ply[0].y) * TILEY / 8 + ((SCR_FIELDY - 1) * TILEY) / 2; if (x > lev.width * TILEX) @@ -389,9 +466,30 @@ void game_animscreen(void) screen_y = y - (SCR_FIELDY - 1) * TILEY; animscreen(); - blitplayer(&ply1); - blitplayer(&ply2); + + for (i = 0; i < MAX_PLAYERS; i++) + blitplayer(&ply[i]); + blitscreen(); FlushDisplay(); } + +void game_animscreen(void) +{ + RedrawPlayfield_EM(); +} + +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, 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); +#endif +}