#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
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)
{
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,
{
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;
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 },
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)
screentiles[sy][sx] = obj;
crumbled_state[sy][sx] = crm;
+
+ redraw[sx][sy] = TRUE;
+ redraw_tiles++;
}
}
}
static void blitplayer(struct PLAYER *ply)
{
- unsigned int x1, y1, x2, y2;
+ int x1, y1, x2, y2;
if (!ply->alive)
return;
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;
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++)
{
}
#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);
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();
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);