X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=95f12fc1d5ca157f11fbfea1a3f9ee002e725fc0;hb=bdc7198372648cdde60eb28495569700b63592d5;hp=f09c85171a40526f1b8066754969ebd009eb08a4;hpb=1e422c29292f0583391b0ce9e9c872b38f035ac0;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index f09c8517..95f12fc1 100644 --- a/src/tools.c +++ b/src/tools.c @@ -304,6 +304,79 @@ void DrawMaskedBorder(int redraw_mask) } } +void BlitScreenToBitmap(Bitmap *target_bitmap) +{ + DrawBuffer *buffer = (drawto_field == window ? backbuffer : drawto_field); + int fx = FX, fy = FY; + +#if NEW_TILESIZE + 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; + + // fx += dx * TILESIZE_VAR / TILESIZE; + // fy += dy * TILESIZE_VAR / TILESIZE; +#else + fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0); + fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0); +#endif + + 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 0 + printf("::: (%d, %d) [(%d / %d, %d / %d)] => %d, %d\n", + scroll_x, scroll_y, + SBX_Left, SBX_Right, + SBY_Upper, SBY_Lower, + fx, fy); +#endif + + if (border.draw_masked[GAME_MODE_PLAYING]) + { + if (buffer != backbuffer) + { + /* copy playfield buffer to backbuffer to add masked border */ + BlitBitmap(buffer, backbuffer, fx, fy, SXSIZE, SYSIZE, SX, SY); + DrawMaskedBorder(REDRAW_FIELD); + } + + BlitBitmap(backbuffer, target_bitmap, + REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, + REAL_SX, REAL_SY); + } + else + { + BlitBitmap(buffer, target_bitmap, fx, fy, SXSIZE, SYSIZE, SX, SY); + } +} + void BackToFront() { int x, y; @@ -322,12 +395,45 @@ void BackToFront() if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD) redraw_mask |= REDRAW_FIELD; +#if 0 + // never redraw single tiles, always redraw the whole field + // (redrawing single tiles up to a certain threshold was faster on old, + // now legacy graphics, but slows things down on modern graphics now) + // UPDATE: this is now globally defined by value of REDRAWTILES_THRESHOLD + if (redraw_mask & REDRAW_TILES) + redraw_mask |= REDRAW_FIELD; +#endif + +#if 0 + /* !!! TEST ONLY !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + /* (force full redraw) */ + if (game_status == GAME_MODE_PLAYING) + redraw_mask |= REDRAW_FIELD; +#endif + if (redraw_mask & REDRAW_FIELD) redraw_mask &= ~REDRAW_TILES; if (redraw_mask == REDRAW_NONE) return; +#if 0 + printf("::: "); + if (redraw_mask & REDRAW_ALL) + printf("[REDRAW_ALL]"); + if (redraw_mask & REDRAW_FIELD) + printf("[REDRAW_FIELD]"); + if (redraw_mask & REDRAW_TILES) + printf("[REDRAW_TILES]"); + if (redraw_mask & REDRAW_DOOR_1) + printf("[REDRAW_DOOR_1]"); + if (redraw_mask & REDRAW_DOOR_2) + printf("[REDRAW_DOOR_2]"); + if (redraw_mask & REDRAW_FROM_BACKBUFFER) + printf("[REDRAW_FROM_BACKBUFFER]"); + printf(" [%d]\n", FrameCounter); +#endif + if (redraw_mask & REDRAW_TILES && game_status == GAME_MODE_PLAYING && border.draw_masked[GAME_MODE_PLAYING]) @@ -399,71 +505,88 @@ void BackToFront() } else { +#if 1 + BlitScreenToBitmap(window); +#else int fx = FX, fy = FY; - if (setup.soft_scrolling) - { #if NEW_TILESIZE - int dx = (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0); - int dy = (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0); - - fx += dx * TILESIZE_VAR / TILESIZE; - fy += dy * TILESIZE_VAR / TILESIZE; + 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; + + // fx += dx * TILESIZE_VAR / TILESIZE; + // fy += dy * TILESIZE_VAR / TILESIZE; #else - fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0); - fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0); + fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0); + fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0); #endif -#if 0 - printf("::: %d, %d [%d, %d] [%d, %d]\n", - fx, fy, FX, FY, ScreenMovDir, ScreenGfxPos); -#endif + /* !!! THIS WORKS !!! */ -#if 0 -#if NEW_TILESIZE - fx = fx * TILESIZE_VAR / TILESIZE; - fy = fy * TILESIZE_VAR / TILESIZE; -#endif -#endif - } + printf("::: %d, %d\n", scroll_x, scroll_y); - if (setup.soft_scrolling || - ABS(ScreenMovPos) + ScrollStepSize == TILEX || - ABS(ScreenMovPos) == ScrollStepSize || - redraw_tiles > REDRAWTILES_THRESHOLD) + ffx = (scroll_x - SBX_Left) * TILEX_VAR + dx_var; + ffy = (scroll_y - SBY_Upper) * TILEY_VAR + dy_var; + + if (EVEN(SCR_FIELDX)) { - if (border.draw_masked[GAME_MODE_PLAYING]) - { - if (buffer != backbuffer) - { - /* copy playfield buffer to backbuffer to add masked border */ - BlitBitmap(buffer, backbuffer, fx, fy, SXSIZE, SYSIZE, SX, SY); - DrawMaskedBorder(REDRAW_FIELD); - } + if (ffx < SBX_Right * TILEX_VAR + TILEX_VAR / 2 + TILEX_VAR) + fx += dx_var - MIN(ffx, TILEX_VAR / 2) + TILEX_VAR; + else + fx += (dx > 0 ? TILEX_VAR : 0); + } + else + { + fx += dx; + } - BlitBitmap(backbuffer, window, - REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, - REAL_SX, REAL_SY); - } + 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 > 0 ? TILEY_VAR : 0); + } + else + { + fy += dy; + } + + if (border.draw_masked[GAME_MODE_PLAYING]) + { + if (buffer != backbuffer) { - BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY); + /* copy playfield buffer to backbuffer to add masked border */ + BlitBitmap(buffer, backbuffer, fx, fy, SXSIZE, SYSIZE, SX, SY); + DrawMaskedBorder(REDRAW_FIELD); } + BlitBitmap(backbuffer, window, + REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, + REAL_SX, REAL_SY); + } + else + { + BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY); + } +#endif + #if 0 #ifdef DEBUG - printf("redrawing all (ScreenGfxPos == %d) because %s\n", - ScreenGfxPos, - (setup.soft_scrolling ? - "setup.soft_scrolling" : - ABS(ScreenGfxPos) + ScrollStepSize == TILEX ? - "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" : - ABS(ScreenGfxPos) == ScrollStepSize ? - "ABS(ScreenGfxPos) == ScrollStepSize" : - "redraw_tiles > REDRAWTILES_THRESHOLD")); + printf("redrawing all (ScreenGfxPos == %d) because %s\n", + ScreenGfxPos, + (setup.soft_scrolling ? + "setup.soft_scrolling" : + ABS(ScreenGfxPos) + ScrollStepSize == TILEX ? + "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" : + ABS(ScreenGfxPos) == ScrollStepSize ? + "ABS(ScreenGfxPos) == ScrollStepSize" : + "redraw_tiles > REDRAWTILES_THRESHOLD")); #endif #endif - } } redraw_mask &= ~REDRAW_MAIN; @@ -498,6 +621,75 @@ void BackToFront() #endif #if NEW_TILESIZE + +#if 1 + InitGfxClipRegion(TRUE, SX, SY, SXSIZE, SYSIZE); + + { + int sx = SX; // - (EVEN(SCR_FIELDX) ? TILEX_VAR / 2 : 0); + int sy = SY; // + (EVEN(SCR_FIELDY) ? TILEY_VAR / 2 : 0); + + int dx = 0, dy = 0; + int dx_var = dx * TILESIZE_VAR / TILESIZE; + int dy_var = dy * TILESIZE_VAR / TILESIZE; + int ffx, ffy; + int fx = FX, fy = FY; + + int scr_fieldx = SCR_FIELDX + (EVEN(SCR_FIELDX) ? 2 : 0); + int scr_fieldy = SCR_FIELDY + (EVEN(SCR_FIELDY) ? 2 : 0); + + 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; + + if (fx % TILEX_VAR) + sx -= TILEX_VAR / 2; + else + sx -= TILEX_VAR; + } + else + { + fx += (dx_var > 0 ? TILEX_VAR : 0); + } + } + + 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; + + if (fy % TILEY_VAR) + sy -= TILEY_VAR / 2; + else + sy -= TILEY_VAR; + } + else + { + fy += (dy_var > 0 ? TILEY_VAR : 0); + } + } + +#if 0 + printf("::: %d, %d, %d, %d\n", sx, sy, SCR_FIELDX, SCR_FIELDY); +#endif + + for (x = 0; x < scr_fieldx; x++) + for (y = 0 ; y < scr_fieldy; y++) + if (redraw[redraw_x1 + x][redraw_y1 + y]) + BlitBitmap(buffer, window, + FX + x * TILEX_VAR, FY + y * TILEY_VAR, + TILEX_VAR, TILEY_VAR, + sx + x * TILEX_VAR, sy + y * TILEY_VAR); + } + + InitGfxClipRegion(FALSE, -1, -1, -1, -1); +#else for (x = 0; x < SCR_FIELDX; x++) for (y = 0 ; y < SCR_FIELDY; y++) if (redraw[redraw_x1 + x][redraw_y1 + y]) @@ -505,6 +697,8 @@ void BackToFront() FX + x * TILEX_VAR, FY + y * TILEY_VAR, TILEX_VAR, TILEY_VAR, SX + x * TILEX_VAR, SY + y * TILEY_VAR); +#endif + #else for (x = 0; x < SCR_FIELDX; x++) for (y = 0 ; y < SCR_FIELDY; y++) @@ -893,7 +1087,18 @@ void DrawBackground(int x, int y, int width, int height) ClearRectangleOnBackground(backbuffer, x, y, width, height); #endif +#if 1 + /* (this only works for the current arrangement of playfield and panels) */ + if (x < gfx.dx) + redraw_mask |= REDRAW_FIELD; + else if (y < gfx.vy) + redraw_mask |= REDRAW_DOOR_1; + else + redraw_mask |= REDRAW_DOOR_2; +#else + /* (this is just wrong (when drawing to one of the two door panel areas)) */ redraw_mask |= REDRAW_FIELD; +#endif } void DrawBackgroundForFont(int x, int y, int width, int height, int font_nr) @@ -2260,49 +2465,57 @@ void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y) DrawMiniGraphic(sx, sy, el2edimg(getBorderElement(x, y))); } -void DrawEnvelopeBackground(int envelope_nr, int startx, int starty, - int x, int y, int xsize, int ysize, int font_nr) +void DrawEnvelopeBackgroundTiles(int graphic, int startx, int starty, + int x, int y, int xsize, int ysize, + int tile_width, int tile_height) { - int font_width = getFontWidth(font_nr); - int font_height = getFontHeight(font_nr); - int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr; Bitmap *src_bitmap; int src_x, src_y; - int dst_x = SX + startx + x * font_width; - int dst_y = SY + starty + y * font_height; + int dst_x = startx + x * tile_width; + int dst_y = starty + y * tile_height; int width = graphic_info[graphic].width; int height = graphic_info[graphic].height; - int inner_width = MAX(width - 2 * font_width, font_width); - int inner_height = MAX(height - 2 * font_height, font_height); - int inner_sx = (width >= 3 * font_width ? font_width : 0); - int inner_sy = (height >= 3 * font_height ? font_height : 0); + int inner_width = MAX(width - 2 * tile_width, tile_width); + int inner_height = MAX(height - 2 * tile_height, tile_height); + int inner_sx = (width >= 3 * tile_width ? tile_width : 0); + int inner_sy = (height >= 3 * tile_height ? tile_height : 0); boolean draw_masked = graphic_info[graphic].draw_masked; getFixedGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y); - if (src_bitmap == NULL || width < font_width || height < font_height) + if (src_bitmap == NULL || width < tile_width || height < tile_height) { - ClearRectangle(drawto, dst_x, dst_y, font_width, font_height); + ClearRectangle(drawto, dst_x, dst_y, tile_width, tile_height); return; } - src_x += (x == 0 ? 0 : x == xsize - 1 ? width - font_width : - inner_sx + (x - 1) * font_width % inner_width); - src_y += (y == 0 ? 0 : y == ysize - 1 ? height - font_height : - inner_sy + (y - 1) * font_height % inner_height); + src_x += (x == 0 ? 0 : x == xsize - 1 ? width - tile_width : + inner_sx + (x - 1) * tile_width % inner_width); + src_y += (y == 0 ? 0 : y == ysize - 1 ? height - tile_height : + inner_sy + (y - 1) * tile_height % inner_height); if (draw_masked) { SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc, dst_x - src_x, dst_y - src_y); - BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, font_width, font_height, + BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, tile_width, tile_height, dst_x, dst_y); } else - BlitBitmap(src_bitmap, drawto, src_x, src_y, font_width, font_height, + BlitBitmap(src_bitmap, drawto, src_x, src_y, tile_width, tile_height, dst_x, dst_y); } +void DrawEnvelopeBackground(int graphic, int startx, int starty, + int x, int y, int xsize, int ysize, int font_nr) +{ + int font_width = getFontWidth(font_nr); + int font_height = getFontHeight(font_nr); + + DrawEnvelopeBackgroundTiles(graphic, startx, starty, x, y, xsize, ysize, + font_width, font_height); +} + void AnimateEnvelope(int envelope_nr, int anim_mode, int action) { int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr; @@ -2310,7 +2523,7 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action) int mask_mode = (src_bitmap != NULL ? BLIT_MASKED : BLIT_ON_BACKGROUND); boolean ffwd_delay = (tape.playing && tape.fast_forward); boolean no_delay = (tape.warp_forward); - unsigned long anim_delay = 0; + unsigned int anim_delay = 0; int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay); int anim_delay_value = (no_delay ? 0 : frame_delay_value); int font_nr = FONT_ENVELOPE_1 + envelope_nr; @@ -2330,27 +2543,32 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action) { int xsize = (action == ACTION_CLOSING ? xend - (x - xstart) : x) + 2; int ysize = (action == ACTION_CLOSING ? yend - (y - ystart) : y) + 2; - int sx = (SXSIZE - xsize * font_width) / 2; - int sy = (SYSIZE - ysize * font_height) / 2; + int sx = SX + (SXSIZE - xsize * font_width) / 2; + int sy = SY + (SYSIZE - ysize * font_height) / 2; int xx, yy; SetDrawtoField(DRAW_BUFFERED); +#if 1 + BlitScreenToBitmap(backbuffer); +#else BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY); +#endif SetDrawtoField(DRAW_BACKBUFFER); - for (yy = 0; yy < ysize; yy++) for (xx = 0; xx < xsize; xx++) - DrawEnvelopeBackground(envelope_nr, sx,sy, xx,yy, xsize, ysize, font_nr); + for (yy = 0; yy < ysize; yy++) + for (xx = 0; xx < xsize; xx++) + DrawEnvelopeBackground(graphic, sx, sy, xx, yy, xsize, ysize, font_nr); #if 1 - DrawTextBuffer(SX + sx + font_width, SY + sy + font_height, + DrawTextBuffer(sx + font_width, sy + font_height, level.envelope[envelope_nr].text, font_nr, max_xsize, xsize - 2, ysize - 2, 0, mask_mode, level.envelope[envelope_nr].autowrap, level.envelope[envelope_nr].centered, FALSE); #else - DrawTextToTextArea(SX + sx + font_width, SY + sy + font_height, + DrawTextToTextArea(sx + font_width, sy + font_height, level.envelope[envelope_nr].text, font_nr, max_xsize, xsize - 2, ysize - 2, mask_mode); #endif @@ -2362,127 +2580,379 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action) } } -void AnimateEnvelopeDoor(char *text, int anim_mode, int action) +void ShowEnvelope(int envelope_nr) { -#if 1 - int envelope_nr = 0; -#endif + int element = EL_ENVELOPE_1 + envelope_nr; int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr; - Bitmap *src_bitmap = graphic_info[graphic].bitmap; - int mask_mode = (src_bitmap != NULL ? BLIT_MASKED : BLIT_ON_BACKGROUND); + int sound_opening = element_info[element].sound[ACTION_OPENING]; + int sound_closing = element_info[element].sound[ACTION_CLOSING]; boolean ffwd_delay = (tape.playing && tape.fast_forward); boolean no_delay = (tape.warp_forward); - unsigned long anim_delay = 0; - int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay); - int anim_delay_value = (no_delay ? 0 : frame_delay_value); -#if 1 - int max_word_len = maxWordLengthInString(text); - int font_nr = (max_word_len > 7 ? FONT_TEXT_1 : FONT_TEXT_2); -#else - int font_nr = FONT_ENVELOPE_1 + envelope_nr; -#endif - int font_width = getFontWidth(font_nr); - int font_height = getFontHeight(font_nr); -#if 1 + int normal_delay_value = ONE_SECOND_DELAY / (ffwd_delay ? 2 : 1); + int wait_delay_value = (no_delay ? 0 : normal_delay_value); + int anim_mode = graphic_info[graphic].anim_mode; + int main_anim_mode = (anim_mode == ANIM_NONE ? ANIM_VERTICAL|ANIM_HORIZONTAL: + anim_mode == ANIM_DEFAULT ? ANIM_VERTICAL : anim_mode); -#if 1 - int max_xsize = DXSIZE / font_width; - int max_ysize = DYSIZE / font_height; -#else - int max_xsize = 7; /* tools.c: MAX_REQUEST_LINE_FONT1_LEN == 7 */ - int max_ysize = 13; /* tools.c: MAX_REQUEST_LINES == 13 */ -#endif + game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */ -#else - int max_xsize = level.envelope[envelope_nr].xsize; - int max_ysize = level.envelope[envelope_nr].ysize; -#endif - int xstart = (anim_mode & ANIM_VERTICAL ? max_xsize : 0); - int ystart = (anim_mode & ANIM_HORIZONTAL ? max_ysize : 0); - int xend = max_xsize; - int yend = (anim_mode != ANIM_DEFAULT ? max_ysize : 0); - int xstep = (xstart < xend ? 1 : 0); - int ystep = (ystart < yend || xstep == 0 ? 1 : 0); - int x, y; + PlayMenuSoundStereo(sound_opening, SOUND_MIDDLE); -#if 1 - char *text_ptr; - char *text_copy = getStringCopy(text); -#else -#if 1 - font_nr = FONT_TEXT_2; + if (anim_mode == ANIM_DEFAULT) + AnimateEnvelope(envelope_nr, ANIM_DEFAULT, ACTION_OPENING); - if (maxWordLengthInString(text) > 7) /* MAX_REQUEST_LINE_FONT1_LEN == 7 */ - { - max_xsize = 10; /* tools.c: MAX_REQUEST_LINE_FONT2_LEN == 10 */ - font_nr = FONT_TEXT_1; - } -#else - int max_word_len = 0; - char *text_ptr; - char *text_copy = getStringCopy(text); + AnimateEnvelope(envelope_nr, main_anim_mode, ACTION_OPENING); - font_nr = FONT_TEXT_2; + if (tape.playing) + Delay(wait_delay_value); + else + WaitForEventToContinue(); - for (text_ptr = text; *text_ptr; text_ptr++) - { - max_word_len = (*text_ptr != ' ' ? max_word_len + 1 : 0); + PlayMenuSoundStereo(sound_closing, SOUND_MIDDLE); - if (max_word_len > 7) /* tools.c: MAX_REQUEST_LINE_FONT1_LEN == 7 */ - { - max_xsize = 10; /* tools.c: MAX_REQUEST_LINE_FONT2_LEN == 10 */ - font_nr = FONT_TEXT_1; + if (anim_mode != ANIM_NONE) + AnimateEnvelope(envelope_nr, main_anim_mode, ACTION_CLOSING); - break; - } - } -#endif -#endif + if (anim_mode == ANIM_DEFAULT) + AnimateEnvelope(envelope_nr, ANIM_DEFAULT, ACTION_CLOSING); -#if 1 - for (text_ptr = text_copy; *text_ptr; text_ptr++) - if (*text_ptr == ' ') - *text_ptr = '\n'; -#endif + game.envelope_active = FALSE; -#if 1 - dDX = SX + (SXSIZE - DXSIZE) / 2 - DX; - dDY = SY + (SYSIZE - DYSIZE) / 2 - DY; -#else - dDX = SX + SXSIZE / 2 - max_xsize * font_width / 2 - DX; - dDY = SY + SYSIZE / 2 - max_ysize * font_height / 2 - DY; -#endif + SetDrawtoField(DRAW_BUFFERED); - for (x = xstart, y = ystart; x <= xend && y <= yend; x += xstep, y += ystep) - { - int xsize = (action == ACTION_CLOSING ? xend - (x - xstart) : x) + 2; - int ysize = (action == ACTION_CLOSING ? yend - (y - ystart) : y) + 2; - int sx = (SXSIZE - xsize * font_width) / 2; - int sy = (SYSIZE - ysize * font_height) / 2; - int xx, yy; + redraw_mask |= REDRAW_FIELD; + BackToFront(); +} -#if 1 - BlitBitmap(bitmap_db_store, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); -#else - SetDrawtoField(DRAW_BUFFERED); +static void setRequestPosition(int *x, int *y, boolean add_border_size) +{ + int border_size = request.border_size; + int sx_center = (request.x != -1 ? request.x : SX + SXSIZE / 2); + int sy_center = (request.y != -1 ? request.y : SY + SYSIZE / 2); + int sx = sx_center - request.width / 2; + int sy = sy_center - request.height / 2; - BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY); + if (add_border_size) + { + sx += border_size; + sy += border_size; + } + + *x = sx; + *y = sy; +} + +void DrawEnvelopeRequest(char *text) +{ + int graphic = IMG_BACKGROUND_REQUEST; + Bitmap *src_bitmap = graphic_info[graphic].bitmap; + int mask_mode = (src_bitmap != NULL ? BLIT_MASKED : BLIT_ON_BACKGROUND); + int font_nr = FONT_REQUEST; + int font_width = getFontWidth(font_nr); + int font_height = getFontHeight(font_nr); + int border_size = request.border_size; + int line_spacing = request.line_spacing; + int line_height = font_height + line_spacing; + int text_width = request.width - 2 * border_size; + int text_height = request.height - 2 * border_size; + int line_length = text_width / font_width; + int max_lines = text_height / line_height; + boolean autowrap = FALSE; + boolean centered = TRUE; + int width = request.width; + int height = request.height; + int tile_size = request.step_offset; + int x_steps = width / tile_size; + int y_steps = height / tile_size; + int sx, sy; + int i, x, y; + + setRequestPosition(&sx, &sy, FALSE); + + ClearRectangle(backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE); + + for (y = 0; y < y_steps; y++) + for (x = 0; x < x_steps; x++) + DrawEnvelopeBackgroundTiles(graphic, sx, sy, + x, y, x_steps, y_steps, + tile_size, tile_size); + + DrawTextBuffer(sx + border_size, sy + border_size, text, font_nr, + line_length, -1, max_lines, line_spacing, mask_mode, + autowrap, centered, FALSE); + + for (i = 0; i < NUM_TOOL_BUTTONS; i++) + RedrawGadget(tool_gadget[i]); + + // store readily prepared envelope request for later use when animating + BlitBitmap(backbuffer, bitmap_db_cross, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); + +#if 0 + // !!! TEST !!! + BlitBitmap(bitmap_db_store, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); + BlitBitmap(bitmap_db_cross, backbuffer, sx, sy, width, height, sx, sy); + + redraw_mask = REDRAW_FIELD | REDRAW_FROM_BACKBUFFER; + BackToFront(); + + Delay(3000); + + BlitBitmap(bitmap_db_store, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); + + redraw_mask = REDRAW_FIELD | REDRAW_FROM_BACKBUFFER; + BackToFront(); + + Delay(1000); +#endif +} + +#if 1 + +void AnimateEnvelopeRequest(char *text, int anim_mode, int action) +{ + int graphic = IMG_BACKGROUND_REQUEST; + boolean draw_masked = graphic_info[graphic].draw_masked; +#if 1 + int delay_value_normal = request.step_delay; + int delay_value_fast = delay_value_normal / 2; +#else + int delay_value_normal = GameFrameDelay; + int delay_value_fast = FfwdFrameDelay; +#endif + boolean ffwd_delay = (tape.playing && tape.fast_forward); + boolean no_delay = (tape.warp_forward); + int delay_value = (ffwd_delay ? delay_value_fast : delay_value_normal); + int anim_delay_value = (no_delay ? 0 : delay_value + 500 * 0); + unsigned int anim_delay = 0; + + int width = request.width; + int height = request.height; + int tile_size = request.step_offset; + int max_xsize = width / tile_size; + int max_ysize = height / tile_size; + int max_xsize_inner = max_xsize - 2; + int max_ysize_inner = max_ysize - 2; + + int xstart = (anim_mode & ANIM_VERTICAL ? max_xsize_inner : 0); + int ystart = (anim_mode & ANIM_HORIZONTAL ? max_ysize_inner : 0); + int xend = max_xsize_inner; + int yend = (anim_mode != ANIM_DEFAULT ? max_ysize_inner : 0); + int xstep = (xstart < xend ? 1 : 0); + int ystep = (ystart < yend || xstep == 0 ? 1 : 0); + int x, y; + + for (x = xstart, y = ystart; x <= xend && y <= yend; x += xstep, y += ystep) + { + int xsize = (action == ACTION_CLOSING ? xend - (x - xstart) : x) + 2; + int ysize = (action == ACTION_CLOSING ? yend - (y - ystart) : y) + 2; + int sx_center = (request.x != -1 ? request.x : SX + SXSIZE / 2); + int sy_center = (request.y != -1 ? request.y : SY + SYSIZE / 2); + int src_x = sx_center - width / 2; + int src_y = sy_center - height / 2; + int dst_x = sx_center - xsize * tile_size / 2; + int dst_y = sy_center - ysize * tile_size / 2; + int xsize_size_left = (xsize - 1) * tile_size; + int ysize_size_top = (ysize - 1) * tile_size; + int max_xsize_pos = (max_xsize - 1) * tile_size; + int max_ysize_pos = (max_ysize - 1) * tile_size; + int xx, yy; + + BlitBitmap(bitmap_db_store, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); + +#if 1 + for (yy = 0; yy < 2; yy++) + { + for (xx = 0; xx < 2; xx++) + { + int src_xx = src_x + xx * max_xsize_pos; + int src_yy = src_y + yy * max_ysize_pos; + int dst_xx = dst_x + xx * xsize_size_left; + int dst_yy = dst_y + yy * ysize_size_top; + int xx_size = (xx ? tile_size : xsize_size_left); + int yy_size = (yy ? tile_size : ysize_size_top); + + if (draw_masked) + BlitBitmapMasked(bitmap_db_cross, backbuffer, + src_xx, src_yy, xx_size, yy_size, dst_xx, dst_yy); + else + BlitBitmap(bitmap_db_cross, backbuffer, + src_xx, src_yy, xx_size, yy_size, dst_xx, dst_yy); + } + } +#else + BlitBitmap(bitmap_db_cross, backbuffer, + src_x, src_y, + xsize_size_left, ysize_size_top, + dst_x, dst_y); + BlitBitmap(bitmap_db_cross, backbuffer, + src_x + max_xsize_pos, src_y, + tile_size, ysize_size_top, + dst_x + xsize_size_left, dst_y); + BlitBitmap(bitmap_db_cross, backbuffer, + src_x, src_y + max_ysize_pos, + xsize_size_left, tile_size, + dst_x, dst_y + ysize_size_top); + BlitBitmap(bitmap_db_cross, backbuffer, + src_x + max_xsize_pos, src_y + max_ysize_pos, + tile_size, tile_size, + dst_x + xsize_size_left, dst_y + ysize_size_top); +#endif + +#if 1 + redraw_mask = REDRAW_FIELD | REDRAW_FROM_BACKBUFFER; + // redraw_mask |= REDRAW_ALL | REDRAW_FROM_BACKBUFFER; +#else + redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER; +#endif + +#if 1 + DoAnimation(); + BackToFront(); +#else + BackToFront(); +#endif + + WaitUntilDelayReached(&anim_delay, anim_delay_value / 2); + } +} + +#else + +void AnimateEnvelopeRequest(char *text, int anim_mode, int action) +{ +#if 0 + int envelope_nr = 0; +#endif +#if 1 + int graphic = IMG_BACKGROUND_REQUEST; +#else + int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr; +#endif + Bitmap *src_bitmap = graphic_info[graphic].bitmap; + int mask_mode = (src_bitmap != NULL ? BLIT_MASKED : BLIT_ON_BACKGROUND); + boolean ffwd_delay = (tape.playing && tape.fast_forward); + boolean no_delay = (tape.warp_forward); + unsigned int anim_delay = 0; + int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay); + int anim_delay_value = (no_delay ? 0 : frame_delay_value + 500 * 0); +#if 1 + int max_word_len = maxWordLengthInString(text); + int font_nr = (max_word_len > 7 ? FONT_TEXT_1 : FONT_TEXT_2); +#else + int font_nr = FONT_ENVELOPE_1 + envelope_nr; +#endif + int font_width = getFontWidth(font_nr); + int font_height = getFontHeight(font_nr); + int line_spacing = 2 * 1; +#if 1 + +#if 1 + int max_xsize = DXSIZE / font_width; + // int max_ysize = DYSIZE / font_height; + int max_ysize = DYSIZE / (font_height + line_spacing); +#else + int max_xsize = 7; /* tools.c: MAX_REQUEST_LINE_FONT1_LEN == 7 */ + int max_ysize = 13; /* tools.c: MAX_REQUEST_LINES == 13 */ +#endif + +#else + int max_xsize = level.envelope[envelope_nr].xsize; + int max_ysize = level.envelope[envelope_nr].ysize; +#endif + int xstart = (anim_mode & ANIM_VERTICAL ? max_xsize : 0); + int ystart = (anim_mode & ANIM_HORIZONTAL ? max_ysize : 0); + int xend = max_xsize; + int yend = (anim_mode != ANIM_DEFAULT ? max_ysize : 0); + int xstep = (xstart < xend ? 1 : 0); + int ystep = (ystart < yend || xstep == 0 ? 1 : 0); + int x, y; + +#if 1 + char *text_ptr; + char *text_copy = getStringCopy(text); +#else +#if 1 + font_nr = FONT_TEXT_2; + + if (maxWordLengthInString(text) > 7) /* MAX_REQUEST_LINE_FONT1_LEN == 7 */ + { + max_xsize = 10; /* tools.c: MAX_REQUEST_LINE_FONT2_LEN == 10 */ + font_nr = FONT_TEXT_1; + } +#else + int max_word_len = 0; + char *text_ptr; + char *text_copy = getStringCopy(text); + + font_nr = FONT_TEXT_2; + + for (text_ptr = text; *text_ptr; text_ptr++) + { + max_word_len = (*text_ptr != ' ' ? max_word_len + 1 : 0); + + if (max_word_len > 7) /* tools.c: MAX_REQUEST_LINE_FONT1_LEN == 7 */ + { + max_xsize = 10; /* tools.c: MAX_REQUEST_LINE_FONT2_LEN == 10 */ + font_nr = FONT_TEXT_1; + + break; + } + } +#endif +#endif + +#if 1 + for (text_ptr = text_copy; *text_ptr; text_ptr++) + if (*text_ptr == ' ') + *text_ptr = '\n'; +#endif + +#if 1 + dDX = SX + (SXSIZE - DXSIZE) / 2 - DX; + dDY = SY + (SYSIZE - DYSIZE) / 2 - DY; +#else + dDX = SX + SXSIZE / 2 - max_xsize * font_width / 2 - DX; + dDY = SY + SYSIZE / 2 - max_ysize * font_height / 2 - DY; +#endif + + for (x = xstart, y = ystart; x <= xend && y <= yend; x += xstep, y += ystep) + { + int xsize = (action == ACTION_CLOSING ? xend - (x - xstart) : x) + 2; + int ysize = (action == ACTION_CLOSING ? yend - (y - ystart) : y) + 2; + int sx = SX + (SXSIZE - xsize * font_width) / 2; + // int sy = SX + (SYSIZE - ysize * font_height) / 2; + int sy = SY + (SYSIZE - ysize * (font_height + line_spacing)) / 2; + int xx, yy; + +#if 1 + BlitBitmap(bitmap_db_store, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); +#else + SetDrawtoField(DRAW_BUFFERED); + +#if 1 + BlitScreenToBitmap(backbuffer); +#else + BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY); +#endif SetDrawtoField(DRAW_BACKBUFFER); #endif - for (yy = 0; yy < ysize; yy++) for (xx = 0; xx < xsize; xx++) - DrawEnvelopeBackground(envelope_nr, sx,sy, xx,yy, xsize, ysize, font_nr); + for (yy = 0; yy < ysize; yy++) + for (xx = 0; xx < xsize; xx++) + DrawEnvelopeBackgroundTiles(graphic, sx, sy, xx, yy, xsize, ysize, + getFontWidth(font_nr), + getFontHeight(font_nr) + line_spacing); #if 1 #if 1 - DrawTextBuffer(SX + sx + font_width, SY + sy + font_height + 8, + DrawTextBuffer(sx + font_width, sy + font_height + 8, text_copy, font_nr, max_xsize, - xsize - 2, ysize - 2, 2, mask_mode, + xsize - 2, ysize - 2, line_spacing, mask_mode, FALSE, TRUE, FALSE); #else - DrawTextBuffer(SX + sx + font_width, SY + sy + font_height, + DrawTextBuffer(sx + font_width, sy + font_height, level.envelope[envelope_nr].text, font_nr, max_xsize, xsize - 2, ysize - 2, 0, mask_mode, level.envelope[envelope_nr].autowrap, @@ -2490,21 +2960,31 @@ void AnimateEnvelopeDoor(char *text, int anim_mode, int action) #endif #else - DrawTextToTextArea(SX + sx + font_width, SY + sy + font_height, + DrawTextToTextArea(sx + font_width, sy + font_height, level.envelope[envelope_nr].text, font_nr, max_xsize, xsize - 2, ysize - 2, mask_mode); #endif /* copy request gadgets to door backbuffer */ #if 1 + /* if ((ysize - 2) > 13) BlitBitmap(bitmap_db_door, drawto, DOOR_GFX_PAGEX1 + (DXSIZE - (xsize - 2) * font_width) / 2, DOOR_GFX_PAGEY1 + 13 * font_height, (xsize - 2) * font_width, (ysize - 2 - 13) * font_height, - SX + sx + font_width, - SY + sy + font_height * (1 + 13)); + sx + font_width, + sy + font_height * (1 + 13)); + */ + if ((ysize - 2) > 13) + BlitBitmap(bitmap_db_door, drawto, + DOOR_GFX_PAGEX1 + (DXSIZE - (xsize - 2) * font_width) / 2, + DOOR_GFX_PAGEY1 + 11 * (font_height + line_spacing * 0), + (xsize - 2) * font_width, + (ysize - 2 - 13) * (font_height + line_spacing), + sx + font_width, + sy + (font_height + line_spacing) * (1 + 13)); #else if ((ysize - 2) > 13) BlitBitmap(bitmap_db_door, drawto, @@ -2512,8 +2992,8 @@ void AnimateEnvelopeDoor(char *text, int anim_mode, int action) DOOR_GFX_PAGEY1 + 13 * font_height, (xsize - 2) * font_width, (ysize - 2 - 13) * font_height, - SX + sx + font_width, - SY + sy + font_height * (1 + 13)); + sx + font_width, + sy + font_height * (1 + 13)); #endif #if 1 @@ -2538,61 +3018,25 @@ void AnimateEnvelopeDoor(char *text, int anim_mode, int action) #endif } -void ShowEnvelope(int envelope_nr) -{ - int element = EL_ENVELOPE_1 + envelope_nr; - int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr; - int sound_opening = element_info[element].sound[ACTION_OPENING]; - int sound_closing = element_info[element].sound[ACTION_CLOSING]; - boolean ffwd_delay = (tape.playing && tape.fast_forward); - boolean no_delay = (tape.warp_forward); - int normal_delay_value = ONE_SECOND_DELAY / (ffwd_delay ? 2 : 1); - int wait_delay_value = (no_delay ? 0 : normal_delay_value); - int anim_mode = graphic_info[graphic].anim_mode; - int main_anim_mode = (anim_mode == ANIM_NONE ? ANIM_VERTICAL|ANIM_HORIZONTAL: - anim_mode == ANIM_DEFAULT ? ANIM_VERTICAL : anim_mode); - - game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */ - - PlayMenuSoundStereo(sound_opening, SOUND_MIDDLE); - - if (anim_mode == ANIM_DEFAULT) - AnimateEnvelope(envelope_nr, ANIM_DEFAULT, ACTION_OPENING); - - AnimateEnvelope(envelope_nr, main_anim_mode, ACTION_OPENING); - - if (tape.playing) - Delay(wait_delay_value); - else - WaitForEventToContinue(); - - PlayMenuSoundStereo(sound_closing, SOUND_MIDDLE); - - if (anim_mode != ANIM_NONE) - AnimateEnvelope(envelope_nr, main_anim_mode, ACTION_CLOSING); - - if (anim_mode == ANIM_DEFAULT) - AnimateEnvelope(envelope_nr, ANIM_DEFAULT, ACTION_CLOSING); - - game.envelope_active = FALSE; - - SetDrawtoField(DRAW_BUFFERED); - - redraw_mask |= REDRAW_FIELD; - BackToFront(); -} +#endif -void ShowEnvelopeDoor(char *text, int action) +void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) { #if 1 int last_game_status = game_status; /* save current game status */ // int last_draw_background_mask = gfx.draw_background_mask; - int envelope_nr = 0; #endif +#if 1 + int graphic = IMG_BACKGROUND_REQUEST; + int sound_opening = SND_REQUEST_OPENING; + int sound_closing = SND_REQUEST_CLOSING; +#else + int envelope_nr = 0; int element = EL_ENVELOPE_1 + envelope_nr; int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr; int sound_opening = element_info[element].sound[ACTION_OPENING]; int sound_closing = element_info[element].sound[ACTION_CLOSING]; +#endif #if 0 boolean ffwd_delay = (tape.playing && tape.fast_forward); boolean no_delay = (tape.warp_forward); @@ -2602,6 +3046,12 @@ void ShowEnvelopeDoor(char *text, int action) int anim_mode = graphic_info[graphic].anim_mode; int main_anim_mode = (anim_mode == ANIM_NONE ? ANIM_VERTICAL|ANIM_HORIZONTAL: anim_mode == ANIM_DEFAULT ? ANIM_VERTICAL : anim_mode); + char *text_copy = getStringCopy(text); + char *text_ptr; + + for (text_ptr = text_copy; *text_ptr; text_ptr++) + if (*text_ptr == ' ') + *text_ptr = '\n'; #if 1 if (game_status == GAME_MODE_PLAYING) @@ -2624,24 +3074,45 @@ void ShowEnvelopeDoor(char *text, int action) { BlitBitmap(backbuffer, bitmap_db_store, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); - if (game_status != GAME_MODE_MAIN) - InitAnimation(); +#if 1 + if (req_state & REQ_ASK) + { + MapGadget(tool_gadget[TOOL_CTRL_ID_YES]); + MapGadget(tool_gadget[TOOL_CTRL_ID_NO]); } - - /* force DOOR font inside door area */ - game_status = GAME_MODE_PSEUDO_DOOR; -#endif - - game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */ - - if (action == ACTION_OPENING) + else if (req_state & REQ_CONFIRM) { - PlayMenuSoundStereo(sound_opening, SOUND_MIDDLE); + MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]); + } + else if (req_state & REQ_PLAYER) + { + MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]); + MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]); + MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]); + MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]); + } +#endif + + DrawEnvelopeRequest(text_copy); + + if (game_status != GAME_MODE_MAIN) + InitAnimation(); + } + + /* force DOOR font inside door area */ + game_status = GAME_MODE_PSEUDO_DOOR; +#endif + + game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */ + + if (action == ACTION_OPENING) + { + PlayMenuSoundStereo(sound_opening, SOUND_MIDDLE); if (anim_mode == ANIM_DEFAULT) - AnimateEnvelopeDoor(text, ANIM_DEFAULT, ACTION_OPENING); + AnimateEnvelopeRequest(text, ANIM_DEFAULT, ACTION_OPENING); - AnimateEnvelopeDoor(text, main_anim_mode, ACTION_OPENING); + AnimateEnvelopeRequest(text, main_anim_mode, ACTION_OPENING); #if 0 if (tape.playing) @@ -2655,10 +3126,10 @@ void ShowEnvelopeDoor(char *text, int action) PlayMenuSoundStereo(sound_closing, SOUND_MIDDLE); if (anim_mode != ANIM_NONE) - AnimateEnvelopeDoor(text, main_anim_mode, ACTION_CLOSING); + AnimateEnvelopeRequest(text, main_anim_mode, ACTION_CLOSING); if (anim_mode == ANIM_DEFAULT) - AnimateEnvelopeDoor(text, ANIM_DEFAULT, ACTION_CLOSING); + AnimateEnvelopeRequest(text, ANIM_DEFAULT, ACTION_CLOSING); } game.envelope_active = FALSE; @@ -2695,12 +3166,22 @@ void ShowEnvelopeDoor(char *text, int action) /* (important: after "BackToFront()", but before "SetDrawtoField()") */ game_status = last_game_status; /* restore current game status */ +#if 1 + if (action == ACTION_CLOSING && + game_status == GAME_MODE_PLAYING && + level.game_engine_type == GAME_ENGINE_TYPE_RND) + SetDrawtoField(DRAW_BUFFERED); +#else if (game_status == GAME_MODE_PLAYING && level.game_engine_type == GAME_ENGINE_TYPE_RND) SetDrawtoField(DRAW_BUFFERED); +#endif + #else BackToFront(); #endif + + free(text_copy); } void DrawPreviewElement(int dst_x, int dst_y, int element, int tilesize) @@ -2744,7 +3225,7 @@ void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y) redraw_mask |= REDRAW_FIELD; } -static void DrawPreviewLevelExt(int from_x, int from_y) +static void DrawPreviewLevelPlayfieldExt(int from_x, int from_y) { boolean show_level_border = (BorderElement != EL_EMPTY); int level_xsize = lev_fieldx + (show_level_border ? 2 : 0); @@ -2880,13 +3361,13 @@ static void DrawPreviewLevelLabelExt(int mode) redraw_mask |= REDRAW_MICROLEVEL; } -void DrawPreviewLevel(boolean restart) +static void DrawPreviewLevelExt(boolean restart) { - static unsigned long scroll_delay = 0; - static unsigned long label_delay = 0; + static unsigned int scroll_delay = 0; + static unsigned int label_delay = 0; static int from_x, from_y, scroll_direction; static int label_state, label_counter; - unsigned long scroll_delay_value = preview.step_delay; + unsigned int scroll_delay_value = preview.step_delay; boolean show_level_border = (BorderElement != EL_EMPTY); int level_xsize = lev_fieldx + (show_level_border ? 2 : 0); int level_ysize = lev_fieldy + (show_level_border ? 2 : 0); @@ -2917,7 +3398,7 @@ void DrawPreviewLevel(boolean restart) label_state = 1; label_counter = 0; - DrawPreviewLevelExt(from_x, from_y); + DrawPreviewLevelPlayfieldExt(from_x, from_y); DrawPreviewLevelLabelExt(label_state); /* initialize delay counters */ @@ -3019,7 +3500,7 @@ void DrawPreviewLevel(boolean restart) break; } - DrawPreviewLevelExt(from_x, from_y); + DrawPreviewLevelPlayfieldExt(from_x, from_y); } /* !!! THIS ALL SUCKS -- SHOULD BE CLEANLY REWRITTEN !!! */ @@ -3066,6 +3547,16 @@ void DrawPreviewLevel(boolean restart) game_status = last_game_status; /* restore current game status */ } +void DrawPreviewLevelInitial() +{ + DrawPreviewLevelExt(TRUE); +} + +void DrawPreviewLevelAnimation() +{ + DrawPreviewLevelExt(FALSE); +} + inline void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y, int graphic, int sync_frame, int mask_mode) { @@ -3574,81 +4065,624 @@ void DrawPlayer(struct PlayerInfo *player) if (player_is_moving) { - /* handle the field the player is leaving ... */ - if (IS_ACCESSIBLE_INSIDE(last_element)) - DrawLevelField(last_jx, last_jy); - else if (IS_ACCESSIBLE_UNDER(last_element)) - DrawLevelFieldThruMask(last_jx, last_jy); + /* handle the field the player is leaving ... */ + if (IS_ACCESSIBLE_INSIDE(last_element)) + DrawLevelField(last_jx, last_jy); + else if (IS_ACCESSIBLE_UNDER(last_element)) + DrawLevelFieldThruMask(last_jx, last_jy); + } + + /* do not redraw accessible elements if the player is just pushing them */ + if (!player_is_moving || !player->is_pushing) + { + /* ... and the field the player is entering */ + if (IS_ACCESSIBLE_INSIDE(element)) + DrawLevelField(jx, jy); + else if (IS_ACCESSIBLE_UNDER(element)) + DrawLevelFieldThruMask(jx, jy); + } + + MarkTileDirty(sx, sy); +} + +/* ------------------------------------------------------------------------- */ + +void WaitForEventToContinue() +{ + boolean still_wait = TRUE; + + /* simulate releasing mouse button over last gadget, if still pressed */ + if (button_status) + HandleGadgets(-1, -1, 0); + + button_status = MB_RELEASED; + +#if 1 + ClearEventQueue(); +#endif + + while (still_wait) + { + if (PendingEvent()) + { + Event event; + + NextEvent(&event); + + switch (event.type) + { + case EVENT_BUTTONPRESS: + case EVENT_KEYPRESS: + still_wait = FALSE; + break; + + case EVENT_KEYRELEASE: + ClearPlayerAction(); + break; + + default: + HandleOtherEvents(&event); + break; + } + } + else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED) + { + still_wait = FALSE; + } + + DoAnimation(); + + /* don't eat all CPU time */ + Delay(10); + } +} + +#define MAX_REQUEST_LINES 13 +#define MAX_REQUEST_LINE_FONT1_LEN 7 +#define MAX_REQUEST_LINE_FONT2_LEN 10 + +#if 1 + +static int RequestHandleEvents(unsigned int req_state) +{ + int last_game_status = game_status; /* save current game status */ + int result; + int mx, my; + + button_status = MB_RELEASED; + + request_gadget_id = -1; + result = -1; + + while (result < 0) + { + if (PendingEvent()) + { + Event event; + + NextEvent(&event); + + switch (event.type) + { + case EVENT_BUTTONPRESS: + case EVENT_BUTTONRELEASE: + case EVENT_MOTIONNOTIFY: + { + if (event.type == EVENT_MOTIONNOTIFY) + { + if (!PointerInWindow(window)) + continue; /* window and pointer are on different screens */ + + if (!button_status) + continue; + + motion_status = TRUE; + mx = ((MotionEvent *) &event)->x; + my = ((MotionEvent *) &event)->y; + } + else + { + motion_status = FALSE; + mx = ((ButtonEvent *) &event)->x; + my = ((ButtonEvent *) &event)->y; + if (event.type == EVENT_BUTTONPRESS) + button_status = ((ButtonEvent *) &event)->button; + else + button_status = MB_RELEASED; + } + + /* this sets 'request_gadget_id' */ + HandleGadgets(mx, my, button_status); + + switch (request_gadget_id) + { + case TOOL_CTRL_ID_YES: + result = TRUE; + break; + case TOOL_CTRL_ID_NO: + result = FALSE; + break; + case TOOL_CTRL_ID_CONFIRM: + result = TRUE | FALSE; + break; + + case TOOL_CTRL_ID_PLAYER_1: + result = 1; + break; + case TOOL_CTRL_ID_PLAYER_2: + result = 2; + break; + case TOOL_CTRL_ID_PLAYER_3: + result = 3; + break; + case TOOL_CTRL_ID_PLAYER_4: + result = 4; + break; + + default: + break; + } + + break; + } + + case EVENT_KEYPRESS: + switch (GetEventKey((KeyEvent *)&event, TRUE)) + { + case KSYM_space: + if (req_state & REQ_CONFIRM) + result = 1; + break; + + case KSYM_Return: + result = 1; + break; + + case KSYM_Escape: +#if defined(TARGET_SDL2) + case KSYM_Back: +#endif + result = 0; + break; + + default: + break; + } + + if (req_state & REQ_PLAYER) + result = 0; + break; + + case EVENT_KEYRELEASE: + ClearPlayerAction(); + break; + + default: + HandleOtherEvents(&event); + break; + } + } + else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED) + { + int joy = AnyJoystick(); + + if (joy & JOY_BUTTON_1) + result = 1; + else if (joy & JOY_BUTTON_2) + result = 0; + } + +#if 1 + + if (game_status == GAME_MODE_PLAYING && local_player->LevelSolved_GameEnd) + { + HandleGameActions(); + } + else + { + DoAnimation(); + + if (!PendingEvent()) /* delay only if no pending events */ + Delay(10); + } + +#if 1 + game_status = GAME_MODE_PSEUDO_DOOR; +#endif + + BackToFront(); + +#if 1 + game_status = last_game_status; /* restore current game status */ +#endif + +#else + + DoAnimation(); + +#if 1 + if (!PendingEvent()) /* delay only if no pending events */ + Delay(10); +#else + /* don't eat all CPU time */ + Delay(10); +#endif + +#endif + } + + return result; +} + +static boolean RequestDoor(char *text, unsigned int req_state) +{ + unsigned int old_door_state; + int last_game_status = game_status; /* save current game status */ + int max_request_line_len = MAX_REQUEST_LINE_FONT1_LEN; + int font_nr = FONT_TEXT_2; + char *text_ptr; + int result; + int ty; + + if (maxWordLengthInString(text) > MAX_REQUEST_LINE_FONT1_LEN) + { + max_request_line_len = MAX_REQUEST_LINE_FONT2_LEN; + font_nr = FONT_TEXT_1; + } + + if (game_status == GAME_MODE_PLAYING) + { + if (level.game_engine_type == GAME_ENGINE_TYPE_EM) + BlitScreenToBitmap_EM(backbuffer); + else if (level.game_engine_type == GAME_ENGINE_TYPE_SP) + BlitScreenToBitmap_SP(backbuffer); + } + + /* disable deactivated drawing when quick-loading level tape recording */ + if (tape.playing && tape.deactivate_display) + TapeDeactivateDisplayOff(TRUE); + + SetMouseCursor(CURSOR_DEFAULT); + +#if defined(NETWORK_AVALIABLE) + /* pause network game while waiting for request to answer */ + if (options.network && + game_status == GAME_MODE_PLAYING && + req_state & REQUEST_WAIT_FOR_INPUT) + SendToServer_PausePlaying(); +#endif + + old_door_state = GetDoorState(); + + /* simulate releasing mouse button over last gadget, if still pressed */ + if (button_status) + HandleGadgets(-1, -1, 0); + + UnmapAllGadgets(); + + /* draw released gadget before proceeding */ + // BackToFront(); + + if (old_door_state & DOOR_OPEN_1) + { + CloseDoor(DOOR_CLOSE_1); + + /* save old door content */ + BlitBitmap(bitmap_db_door, bitmap_db_door, + DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, + DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1); + } + + SetDoorBackgroundImage(IMG_BACKGROUND_DOOR); + SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); + + /* clear door drawing field */ + DrawBackground(DX, DY, DXSIZE, DYSIZE); + + /* force DOOR font inside door area */ + game_status = GAME_MODE_PSEUDO_DOOR; + + /* write text for request */ + for (text_ptr = text, ty = 0; ty < MAX_REQUEST_LINES; ty++) + { + char text_line[max_request_line_len + 1]; + int tx, tl, tc = 0; + + if (!*text_ptr) + break; + + for (tl = 0, tx = 0; tx < max_request_line_len; tl++, tx++) + { + tc = *(text_ptr + tx); + if (!tc || tc == ' ') + break; + } + + if (!tl) + { + text_ptr++; + ty--; + continue; + } + + strncpy(text_line, text_ptr, tl); + text_line[tl] = 0; + + DrawText(DX + (DXSIZE - tl * getFontWidth(font_nr)) / 2, + DY + 8 + ty * (getFontHeight(font_nr) + 2), + text_line, font_nr); + + text_ptr += tl + (tc == ' ' ? 1 : 0); + } + + game_status = last_game_status; /* restore current game status */ + + if (req_state & REQ_ASK) + { + MapGadget(tool_gadget[TOOL_CTRL_ID_YES]); + MapGadget(tool_gadget[TOOL_CTRL_ID_NO]); + } + else if (req_state & REQ_CONFIRM) + { + MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]); + } + else if (req_state & REQ_PLAYER) + { + MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]); + MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]); + MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]); + MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]); + } + + /* copy request gadgets to door backbuffer */ + BlitBitmap(drawto, bitmap_db_door, + DX, DY, DXSIZE, DYSIZE, + DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1); + + OpenDoor(DOOR_OPEN_1); + + if (!(req_state & REQUEST_WAIT_FOR_INPUT)) + { + if (game_status == GAME_MODE_PLAYING) + { + SetPanelBackground(); + SetDrawBackgroundMask(REDRAW_DOOR_1); + } + else + { + SetDrawBackgroundMask(REDRAW_FIELD); + } + + return FALSE; + } + + if (game_status != GAME_MODE_MAIN) + InitAnimation(); + + SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); + + // ---------- handle request buttons ---------- + result = RequestHandleEvents(req_state); + + if (game_status != GAME_MODE_MAIN) + StopAnimation(); + + UnmapToolButtons(); + + if (!(req_state & REQ_STAY_OPEN)) + { + CloseDoor(DOOR_CLOSE_1); + + if (((old_door_state & DOOR_OPEN_1) && !(req_state & REQ_STAY_CLOSED)) || + (req_state & REQ_REOPEN)) + OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK); + } + + RemapAllGadgets(); + + if (game_status == GAME_MODE_PLAYING) + { + SetPanelBackground(); + SetDrawBackgroundMask(REDRAW_DOOR_1); + } + else + { + SetDrawBackgroundMask(REDRAW_FIELD); + } + +#if defined(NETWORK_AVALIABLE) + /* continue network game after request */ + if (options.network && + game_status == GAME_MODE_PLAYING && + req_state & REQUEST_WAIT_FOR_INPUT) + SendToServer_ContinuePlaying(); +#endif + + /* restore deactivated drawing when quick-loading level tape recording */ + if (tape.playing && tape.deactivate_display) + TapeDeactivateDisplayOn(); + + return result; +} + +static boolean RequestEnvelope(char *text, unsigned int req_state) +{ + int result; +#if 0 + int i; +#endif + + if (game_status == GAME_MODE_PLAYING) + { + if (level.game_engine_type == GAME_ENGINE_TYPE_EM) + BlitScreenToBitmap_EM(backbuffer); + else if (level.game_engine_type == GAME_ENGINE_TYPE_SP) + BlitScreenToBitmap_SP(backbuffer); + } + + /* disable deactivated drawing when quick-loading level tape recording */ + if (tape.playing && tape.deactivate_display) + TapeDeactivateDisplayOff(TRUE); + + SetMouseCursor(CURSOR_DEFAULT); + +#if defined(NETWORK_AVALIABLE) + /* pause network game while waiting for request to answer */ + if (options.network && + game_status == GAME_MODE_PLAYING && + req_state & REQUEST_WAIT_FOR_INPUT) + SendToServer_PausePlaying(); +#endif + + /* simulate releasing mouse button over last gadget, if still pressed */ + if (button_status) + HandleGadgets(-1, -1, 0); + + UnmapAllGadgets(); + + // (replace with setting corresponding request background) + // SetDoorBackgroundImage(IMG_BACKGROUND_DOOR); + // SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); + + /* clear door drawing field */ + // DrawBackground(DX, DY, DXSIZE, DYSIZE); + +#if 0 + if (global.use_envelope_request) + { + /* !!! TMP !!! */ + FreeToolButtons(); + CreateToolButtons(); + } +#endif + +#if 0 +#if 0 + if (req_state & REQ_ASK) + { + MapGadgetExt(tool_gadget[TOOL_CTRL_ID_YES], FALSE); + MapGadgetExt(tool_gadget[TOOL_CTRL_ID_NO], FALSE); + } + else if (req_state & REQ_CONFIRM) + { + MapGadgetExt(tool_gadget[TOOL_CTRL_ID_CONFIRM], FALSE); + } + else if (req_state & REQ_PLAYER) + { + MapGadgetExt(tool_gadget[TOOL_CTRL_ID_PLAYER_1], FALSE); + MapGadgetExt(tool_gadget[TOOL_CTRL_ID_PLAYER_2], FALSE); + MapGadgetExt(tool_gadget[TOOL_CTRL_ID_PLAYER_3], FALSE); + MapGadgetExt(tool_gadget[TOOL_CTRL_ID_PLAYER_4], FALSE); + } +#else + if (req_state & REQ_ASK) + { + MapGadget(tool_gadget[TOOL_CTRL_ID_YES]); + MapGadget(tool_gadget[TOOL_CTRL_ID_NO]); + } + else if (req_state & REQ_CONFIRM) + { + MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]); + } + else if (req_state & REQ_PLAYER) + { + MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]); + MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]); + MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]); + MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]); + } +#endif +#endif + + ShowEnvelopeRequest(text, req_state, ACTION_OPENING); + +#if 0 + for (i = 0; i < NUM_TOOL_BUTTONS; i++) + { + if ((req_state & REQ_ASK && (i == TOOL_CTRL_ID_YES || + i == TOOL_CTRL_ID_NO)) || + (req_state & REQ_CONFIRM && i == TOOL_CTRL_ID_CONFIRM) || + (req_state & REQ_PLAYER && (i == TOOL_CTRL_ID_PLAYER_1 && + i == TOOL_CTRL_ID_PLAYER_2 && + i == TOOL_CTRL_ID_PLAYER_3 && + i == TOOL_CTRL_ID_PLAYER_4))) + { + int x = tool_gadget[i]->x + dDX; + int y = tool_gadget[i]->y + dDY; + + ModifyGadget(tool_gadget[i], GDI_X, x, GDI_Y, y, GDI_END); + } } +#endif - /* do not redraw accessible elements if the player is just pushing them */ - if (!player_is_moving || !player->is_pushing) + if (!(req_state & REQUEST_WAIT_FOR_INPUT)) { - /* ... and the field the player is entering */ - if (IS_ACCESSIBLE_INSIDE(element)) - DrawLevelField(jx, jy); - else if (IS_ACCESSIBLE_UNDER(element)) - DrawLevelFieldThruMask(jx, jy); - } + if (game_status == GAME_MODE_PLAYING) + { + SetPanelBackground(); + SetDrawBackgroundMask(REDRAW_DOOR_1); + } + else + { + SetDrawBackgroundMask(REDRAW_FIELD); + } - MarkTileDirty(sx, sy); -} + return FALSE; + } -/* ------------------------------------------------------------------------- */ +#if 0 + if (game_status != GAME_MODE_MAIN) + InitAnimation(); +#endif -void WaitForEventToContinue() -{ - boolean still_wait = TRUE; + SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); - /* simulate releasing mouse button over last gadget, if still pressed */ - if (button_status) - HandleGadgets(-1, -1, 0); + // ---------- handle request buttons ---------- + result = RequestHandleEvents(req_state); - button_status = MB_RELEASED; + if (game_status != GAME_MODE_MAIN) + StopAnimation(); -#if 1 - ClearEventQueue(); -#endif + UnmapToolButtons(); - while (still_wait) - { - if (PendingEvent()) - { - Event event; + ShowEnvelopeRequest(text, req_state, ACTION_CLOSING); - NextEvent(&event); + RemapAllGadgets(); - switch (event.type) - { - case EVENT_BUTTONPRESS: - case EVENT_KEYPRESS: - still_wait = FALSE; - break; + if (game_status == GAME_MODE_PLAYING) + { + SetPanelBackground(); + SetDrawBackgroundMask(REDRAW_DOOR_1); + } + else + { + SetDrawBackgroundMask(REDRAW_FIELD); + } - case EVENT_KEYRELEASE: - ClearPlayerAction(); - break; +#if defined(NETWORK_AVALIABLE) + /* continue network game after request */ + if (options.network && + game_status == GAME_MODE_PLAYING && + req_state & REQUEST_WAIT_FOR_INPUT) + SendToServer_ContinuePlaying(); +#endif - default: - HandleOtherEvents(&event); - break; - } - } - else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED) - { - still_wait = FALSE; - } + /* restore deactivated drawing when quick-loading level tape recording */ + if (tape.playing && tape.deactivate_display) + TapeDeactivateDisplayOn(); - DoAnimation(); + return result; +} - /* don't eat all CPU time */ - Delay(10); - } +boolean Request(char *text, unsigned int req_state) +{ + if (global.use_envelope_request) + return RequestEnvelope(text, req_state); + else + return RequestDoor(text, req_state); } -#define MAX_REQUEST_LINES 13 -#define MAX_REQUEST_LINE_FONT1_LEN 7 -#define MAX_REQUEST_LINE_FONT2_LEN 10 +#else // ===================================================================== boolean Request(char *text, unsigned int req_state) { @@ -3663,7 +4697,9 @@ boolean Request(char *text, unsigned int req_state) char *text_ptr; int i; - global.use_envelope_request = TRUE * 1; +#if 0 + global.use_envelope_request = 1; +#endif #if 1 if (maxWordLengthInString(text) > MAX_REQUEST_LINE_FONT1_LEN) @@ -3823,7 +4859,7 @@ boolean Request(char *text, unsigned int req_state) #if 1 if (global.use_envelope_request) { - ShowEnvelopeDoor(text, ACTION_OPENING); + ShowEnvelopeRequest(text, ACTION_OPENING); for (i = 0; i < NUM_TOOL_BUTTONS; i++) { @@ -3965,6 +5001,9 @@ boolean Request(char *text, unsigned int req_state) break; case KSYM_Escape: +#if defined(TARGET_SDL2) + case KSYM_Back: +#endif result = 0; break; @@ -4041,7 +5080,7 @@ boolean Request(char *text, unsigned int req_state) #if 1 if (global.use_envelope_request) - ShowEnvelopeDoor(text, ACTION_CLOSING); + ShowEnvelopeRequest(text, ACTION_CLOSING); #endif #if 1 @@ -4084,6 +5123,8 @@ boolean Request(char *text, unsigned int req_state) return result; } +#endif + unsigned int OpenDoor(unsigned int door_state) { if (door_state & DOOR_COPY_BACK) @@ -4138,8 +5179,8 @@ unsigned int MoveDoor(unsigned int door_state) { static int door1 = DOOR_OPEN_1; static int door2 = DOOR_CLOSE_2; - unsigned long door_delay = 0; - unsigned long door_delay_value; + unsigned int door_delay = 0; + unsigned int door_delay_value; int stepsize = 1; if (door_1.width < 0 || door_1.width > DXSIZE) @@ -4449,6 +5490,107 @@ void UndrawSpecialEditorDoor() /* ---------- new tool button stuff ---------------------------------------- */ +#if 1 + +static struct +{ + int graphic; + struct TextPosInfo *pos; + int gadget_id; + char *infotext; +} toolbutton_info[NUM_TOOL_BUTTONS] = +{ + { + IMG_REQUEST_BUTTON_GFX_YES, &request.button.yes, + TOOL_CTRL_ID_YES, "yes" + }, + { + IMG_REQUEST_BUTTON_GFX_NO, &request.button.no, + TOOL_CTRL_ID_NO, "no" + }, + { + IMG_REQUEST_BUTTON_GFX_CONFIRM, &request.button.confirm, + TOOL_CTRL_ID_CONFIRM, "confirm" + }, + { + IMG_REQUEST_BUTTON_GFX_PLAYER_1, &request.button.player_1, + TOOL_CTRL_ID_PLAYER_1, "player 1" + }, + { + IMG_REQUEST_BUTTON_GFX_PLAYER_2, &request.button.player_2, + TOOL_CTRL_ID_PLAYER_2, "player 2" + }, + { + IMG_REQUEST_BUTTON_GFX_PLAYER_3, &request.button.player_3, + TOOL_CTRL_ID_PLAYER_3, "player 3" + }, + { + IMG_REQUEST_BUTTON_GFX_PLAYER_4, &request.button.player_4, + TOOL_CTRL_ID_PLAYER_4, "player 4" + } +}; + +void CreateToolButtons() +{ + int i; + + for (i = 0; i < NUM_TOOL_BUTTONS; i++) + { + struct GraphicInfo *gfx = &graphic_info[toolbutton_info[i].graphic]; + struct TextPosInfo *pos = toolbutton_info[i].pos; + struct GadgetInfo *gi; + Bitmap *deco_bitmap = None; + int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0; + unsigned int event_mask = GD_EVENT_RELEASED; + int dx = DX; + int dy = DY; + int gd_x = gfx->src_x; + int gd_y = gfx->src_y; + int gd_xp = gfx->src_x + gfx->pressed_xoffset; + int gd_yp = gfx->src_y + gfx->pressed_yoffset; + int id = i; + + if (global.use_envelope_request) + setRequestPosition(&dx, &dy, TRUE); + + if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4) + { + int player_nr = id - TOOL_CTRL_ID_PLAYER_1; + + getSizedGraphicSource(PLAYER_NR_GFX(IMG_PLAYER_1, player_nr), 0, + pos->size, &deco_bitmap, &deco_x, &deco_y); + deco_xpos = (gfx->width - pos->size) / 2; + deco_ypos = (gfx->height - pos->size) / 2; + } + + gi = CreateGadget(GDI_CUSTOM_ID, id, + GDI_INFO_TEXT, toolbutton_info[i].infotext, + GDI_X, dx + pos->x, + GDI_Y, dy + pos->y, + GDI_WIDTH, gfx->width, + GDI_HEIGHT, gfx->height, + GDI_TYPE, GD_TYPE_NORMAL_BUTTON, + GDI_STATE, GD_BUTTON_UNPRESSED, + GDI_DESIGN_UNPRESSED, gfx->bitmap, gd_x, gd_y, + GDI_DESIGN_PRESSED, gfx->bitmap, gd_xp, gd_yp, + GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y, + GDI_DECORATION_POSITION, deco_xpos, deco_ypos, + GDI_DECORATION_SIZE, pos->size, pos->size, + GDI_DECORATION_SHIFTING, 1, 1, + GDI_DIRECT_DRAW, FALSE, + GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_ACTION, HandleToolButtons, + GDI_END); + + if (gi == NULL) + Error(ERR_EXIT, "cannot create gadget"); + + tool_gadget[id] = gi; + } +} + +#else + /* graphic position values for tool buttons */ #define TOOL_BUTTON_YES_XPOS 2 #define TOOL_BUTTON_YES_YPOS 250 @@ -4558,7 +5700,7 @@ void CreateToolButtons() Bitmap *deco_bitmap = None; int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0; struct GadgetInfo *gi; - unsigned long event_mask; + unsigned int event_mask; int gd_xoffset, gd_yoffset; int gd_x1, gd_x2, gd_y; int id = i; @@ -4607,6 +5749,8 @@ void CreateToolButtons() } } +#endif + void FreeToolButtons() { int i; @@ -7041,7 +8185,7 @@ int getGameFrameDelay_EM(int native_em_game_frame_delay) return game_frame_delay_value; } -unsigned int InitRND(long seed) +unsigned int InitRND(int seed) { if (level.game_engine_type == GAME_ENGINE_TYPE_EM) return InitEngineRandom_EM(seed); @@ -7074,6 +8218,7 @@ inline static int get_effective_element_EM(int tile, int frame_em) return (frame_em > 5 ? EL_EMPTY : element); #if 0 + /* !!! FIX !!! */ case Ydiamond_stone: // if (!game.use_native_emc_graphics_engine) return EL_ROCK; @@ -8632,15 +9777,16 @@ void CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame, boolean any_player_moving, boolean player_is_dropping) { - int i; - if (tape.single_step && tape.recording && !tape.pausing) { +#if 0 boolean active_players = FALSE; + int i; for (i = 0; i < MAX_PLAYERS; i++) if (action[i] != JOY_NO_ACTION) active_players = TRUE; +#endif // if (frame == 0) if (frame == 0 && !player_is_dropping) @@ -8771,18 +9917,44 @@ void PlaySoundSelecting() #endif } -void ToggleFullscreenIfNeeded() +void ToggleFullscreenOrChangeWindowScalingIfNeeded() { boolean change_fullscreen = (setup.fullscreen != video.fullscreen_enabled); boolean change_fullscreen_mode = (video.fullscreen_enabled && !strEqual(setup.fullscreen_mode, video.fullscreen_mode_current)); + boolean change_window_scaling_percent = (!video.fullscreen_enabled && + setup.window_scaling_percent != + video.window_scaling_percent); + + if (change_window_scaling_percent && video.fullscreen_enabled) + return; + + if (!change_window_scaling_percent && !video.fullscreen_available) + return; + +#if defined(TARGET_SDL2) + if (change_window_scaling_percent) + { + SDLSetWindowScaling(setup.window_scaling_percent); + + return; + } + else if (change_fullscreen) + { + SDLSetWindowFullscreen(setup.fullscreen); + + /* set setup value according to successfully changed fullscreen mode */ + setup.fullscreen = video.fullscreen_enabled; - if (!video.fullscreen_available) return; + } +#endif - if (change_fullscreen || change_fullscreen_mode) + if (change_fullscreen || + change_fullscreen_mode || + change_window_scaling_percent) { Bitmap *tmp_backbuffer = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH); @@ -8795,9 +9967,16 @@ void ToggleFullscreenIfNeeded() video.fullscreen_enabled = FALSE; /* force new fullscreen mode */ } + if (change_window_scaling_percent) + { + /* keep window mode, but change window scaling */ + video.fullscreen_enabled = TRUE; /* force new window scaling */ + } + /* toggle fullscreen */ ChangeVideoModeIfNeeded(setup.fullscreen); + /* set setup value according to successfully changed fullscreen mode */ setup.fullscreen = video.fullscreen_enabled; /* restore backbuffer content from temporary backbuffer backup bitmap */ @@ -8829,17 +10008,27 @@ void ChangeViewportPropertiesIfNeeded() int border_size = vp_playfield->border_size; int new_sx = vp_playfield->x + border_size; int new_sy = vp_playfield->y + border_size; - int tilesize = (gfx_game_mode == GAME_MODE_PLAYING ? TILESIZE_VAR : - gfx_game_mode == GAME_MODE_EDITOR ? MINI_TILESIZE : TILESIZE); int new_sxsize = vp_playfield->width - 2 * border_size; int new_sysize = vp_playfield->height - 2 * border_size; + int new_real_sx = vp_playfield->x; + int new_real_sy = vp_playfield->y; + int new_full_sxsize = vp_playfield->width; + int new_full_sysize = vp_playfield->height; #if NEW_TILESIZE + int new_tilesize_var = TILESIZE / (setup.small_game_graphics ? 2 : 1); + int tilesize = (gfx_game_mode == GAME_MODE_PLAYING ? new_tilesize_var : + gfx_game_mode == GAME_MODE_EDITOR ? MINI_TILESIZE : TILESIZE); int new_scr_fieldx = new_sxsize / tilesize; int new_scr_fieldy = new_sysize / tilesize; + int new_scr_fieldx_buffers = new_sxsize / new_tilesize_var; + int new_scr_fieldy_buffers = new_sysize / new_tilesize_var; #else int new_scr_fieldx = (vp_playfield->width - 2 * border_size) / TILESIZE; int new_scr_fieldy = (vp_playfield->height - 2 * border_size) / TILESIZE; #endif + boolean init_gfx_buffers = FALSE; + boolean init_video_buffer = FALSE; + boolean init_gadgets_and_toons = FALSE; #if 0 /* !!! TEST ONLY !!! */ @@ -8853,6 +10042,10 @@ void ChangeViewportPropertiesIfNeeded() WIN_XSIZE = viewport.window.width; WIN_YSIZE = viewport.window.height; +#if 1 + init_video_buffer = TRUE; + init_gfx_buffers = TRUE; +#else InitVideoBuffer(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, setup.fullscreen); InitGfxBuffers(); @@ -8862,45 +10055,123 @@ void ChangeViewportPropertiesIfNeeded() // RedrawBackground(); #endif +#endif + + // printf("::: video: init_video_buffer, init_gfx_buffers\n"); } if (new_scr_fieldx != SCR_FIELDX || - new_scr_fieldy != SCR_FIELDY || - new_sx != SX || + new_scr_fieldy != SCR_FIELDY) + { + /* this always toggles between MAIN and GAME when using small tile size */ + + SCR_FIELDX = new_scr_fieldx; + SCR_FIELDY = new_scr_fieldy; + + // printf("::: new_scr_fieldx != SCR_FIELDX ...\n"); + } + +#if 0 + if (new_tilesize_var != TILESIZE_VAR && + gfx_game_mode == GAME_MODE_PLAYING) + { + /* doing this outside GAME_MODE_PLAYING would give wrong playfield size */ + + TILESIZE_VAR = new_tilesize_var; + + init_gfx_buffers = TRUE; + + // printf("::: tilesize: init_gfx_buffers\n"); + } +#endif + + if (new_sx != SX || new_sy != SY || - vp_playfield->x != REAL_SX || - vp_playfield->y != REAL_SY || + new_sxsize != SXSIZE || + new_sysize != SYSIZE || + new_real_sx != REAL_SX || + new_real_sy != REAL_SY || + new_full_sxsize != FULL_SXSIZE || + new_full_sysize != FULL_SYSIZE || + new_tilesize_var != TILESIZE_VAR || vp_door_1->x != *door_1_x || vp_door_1->y != *door_1_y || vp_door_2->x != *door_2_x || vp_door_2->y != *door_2_y) { - SCR_FIELDX = new_scr_fieldx; - SCR_FIELDY = new_scr_fieldy; SX = new_sx; SY = new_sy; - REAL_SX = vp_playfield->x; - REAL_SY = vp_playfield->y; - SXSIZE = new_sxsize; SYSIZE = new_sysize; - FULL_SXSIZE = vp_playfield->width; - FULL_SYSIZE = vp_playfield->width; + REAL_SX = new_real_sx; + REAL_SY = new_real_sy; + FULL_SXSIZE = new_full_sxsize; + FULL_SYSIZE = new_full_sysize; + TILESIZE_VAR = new_tilesize_var; + +#if 0 + printf("::: %d, %d, %d [%d]\n", + SCR_FIELDX, SCR_FIELDY, TILESIZE_VAR, + setup.small_game_graphics); +#endif *door_1_x = vp_door_1->x; *door_1_y = vp_door_1->y; *door_2_x = vp_door_2->x; *door_2_y = vp_door_2->y; +#if 1 + init_gfx_buffers = TRUE; + + // printf("::: viewports: init_gfx_buffers\n"); +#else InitGfxBuffers(); +#endif if (gfx_game_mode == GAME_MODE_MAIN) { +#if 1 + init_gadgets_and_toons = TRUE; + + // printf("::: viewports: init_gadgets_and_toons\n"); +#else InitGadgets(); InitToons(); +#endif } } + if (init_gfx_buffers) + { + // printf("::: init_gfx_buffers\n"); + + SCR_FIELDX = new_scr_fieldx_buffers; + SCR_FIELDY = new_scr_fieldy_buffers; + + InitGfxBuffers(); + + SCR_FIELDX = new_scr_fieldx; + SCR_FIELDY = new_scr_fieldy; + } + + if (init_video_buffer) + { + // printf("::: init_video_buffer\n"); + + InitVideoBuffer(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, setup.fullscreen); + + SetDrawDeactivationMask(REDRAW_NONE); + SetDrawBackgroundMask(REDRAW_FIELD); + } + + if (init_gadgets_and_toons) + { + // printf("::: init_gadgets_and_toons\n"); + + InitGadgets(); + InitToons(); + } + #if 0 printf("::: %d, %d / %d, %d [%d]\n", VX, VY, EX, EY, game_status); #endif