X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Ftools.c;h=79cf0885135681310694fdc4dc562fd40dfa5cf0;hp=5fb84526d33c99386810b2fb5ebe1cfee6006b19;hb=HEAD;hpb=c90edfea149e0b1b8df5db7dca0c2a9e3963879b diff --git a/src/tools.c b/src/tools.c index 5fb84526..4083e77e 100644 --- a/src/tools.c +++ b/src/tools.c @@ -175,6 +175,7 @@ static struct XY xy_topdown[] = // forward declaration for internal use +static void MapToolButtons(unsigned int); static void UnmapToolButtons(void); static void HandleToolButtons(struct GadgetInfo *); static int el_act_dir2crm(int, int, int); @@ -634,6 +635,10 @@ void DrawMaskedBorderToTarget(int draw_target) gfx.masked_border_bitmap_ptr = gfx.fade_bitmap_target; } + // always use global border for PLAYING when restarting the game + if (global.border_status == GAME_MODE_PSEUDO_RESTARTING) + global.border_status = GAME_MODE_PLAYING; + DrawMaskedBorderExt(REDRAW_ALL, draw_target); global.border_status = last_border_status; @@ -641,9 +646,11 @@ void DrawMaskedBorderToTarget(int draw_target) } } -void DrawTileCursor(int draw_target) +void DrawTileCursor(int draw_target, int drawing_stage) { - DrawTileCursor_MM(draw_target, game_status == GAME_MODE_PLAYING); + int tile_cursor_active = (game_status == GAME_MODE_PLAYING); + + DrawTileCursor_MM(draw_target, drawing_stage, tile_cursor_active); } void BlitScreenToBitmapExt_RND(Bitmap *target_bitmap, int fx, int fy) @@ -976,6 +983,10 @@ static void SetScreenStates_BeforeFadingOut(void) static void SetScreenStates_AfterFadingOut(void) { global.border_status = game_status; + + // always use global border for PLAYING when restarting the game + if (global.border_status == GAME_MODE_PSEUDO_RESTARTING) + global.border_status = GAME_MODE_PLAYING; } void FadeIn(int fade_mask) @@ -1110,26 +1121,25 @@ static int getGlobalGameStatus(int status) status); } -Bitmap *getBitmapFromGraphicOrDefault(int graphic, int default_graphic) +int getImageFromGraphicOrDefault(int graphic, int default_graphic) { if (graphic == IMG_UNDEFINED) - return NULL; + return IMG_UNDEFINED; boolean redefined = getImageListEntryFromImageID(graphic)->redefined; return (graphic_info[graphic].bitmap != NULL || redefined ? - graphic_info[graphic].bitmap : - graphic_info[default_graphic].bitmap); + graphic : default_graphic); } -static Bitmap *getBackgroundBitmap(int graphic) +static int getBackgroundImage(int graphic) { - return getBitmapFromGraphicOrDefault(graphic, IMG_BACKGROUND); + return getImageFromGraphicOrDefault(graphic, IMG_BACKGROUND); } -static Bitmap *getGlobalBorderBitmap(int graphic) +static int getGlobalBorderImage(int graphic) { - return getBitmapFromGraphicOrDefault(graphic, IMG_GLOBAL_BORDER); + return getImageFromGraphicOrDefault(graphic, IMG_GLOBAL_BORDER); } Bitmap *getGlobalBorderBitmapFromStatus(int status_raw) @@ -1141,51 +1151,71 @@ Bitmap *getGlobalBorderBitmapFromStatus(int status_raw) status == GAME_MODE_EDITOR ? IMG_GLOBAL_BORDER_EDITOR : status == GAME_MODE_PLAYING ? IMG_GLOBAL_BORDER_PLAYING : IMG_GLOBAL_BORDER); + int graphic_final = getGlobalBorderImage(graphic); + + return graphic_info[graphic_final].bitmap; +} + +void SetBackgroundImage(int graphic, int redraw_mask) +{ + struct GraphicInfo *g = &graphic_info[graphic]; + struct GraphicInfo g_undefined = { 0 }; + + if (graphic == IMG_UNDEFINED) + g = &g_undefined; + + // always use original size bitmap for backgrounds, if existing + Bitmap *bitmap = (g->bitmaps != NULL && + g->bitmaps[IMG_BITMAP_PTR_ORIGINAL] != NULL ? + g->bitmaps[IMG_BITMAP_PTR_ORIGINAL] : g->bitmap); + + // remove every mask before setting mask for window, and + // remove window area mask before setting mask for main or door area + int remove_mask = (redraw_mask == REDRAW_ALL ? 0xffff : REDRAW_ALL); - return getGlobalBorderBitmap(graphic); + // (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) + SetBackgroundBitmap(NULL, remove_mask, 0, 0, 0, 0); // !!! FIX THIS !!! + SetBackgroundBitmap(bitmap, redraw_mask, + g->src_x, g->src_y, + g->width, g->height); } void SetWindowBackgroundImageIfDefined(int graphic) { if (graphic_info[graphic].bitmap) - SetWindowBackgroundBitmap(graphic_info[graphic].bitmap); + SetBackgroundImage(graphic, REDRAW_ALL); } void SetMainBackgroundImageIfDefined(int graphic) { if (graphic_info[graphic].bitmap) - SetMainBackgroundBitmap(graphic_info[graphic].bitmap); + SetBackgroundImage(graphic, REDRAW_FIELD); } void SetDoorBackgroundImageIfDefined(int graphic) { if (graphic_info[graphic].bitmap) - SetDoorBackgroundBitmap(graphic_info[graphic].bitmap); + SetBackgroundImage(graphic, REDRAW_DOOR_1); } void SetWindowBackgroundImage(int graphic) { - SetWindowBackgroundBitmap(getBackgroundBitmap(graphic)); + SetBackgroundImage(getBackgroundImage(graphic), REDRAW_ALL); } void SetMainBackgroundImage(int graphic) { - SetMainBackgroundBitmap(getBackgroundBitmap(graphic)); + SetBackgroundImage(getBackgroundImage(graphic), REDRAW_FIELD); } void SetDoorBackgroundImage(int graphic) { - SetDoorBackgroundBitmap(getBackgroundBitmap(graphic)); + SetBackgroundImage(getBackgroundImage(graphic), REDRAW_DOOR_1); } void SetPanelBackground(void) { - struct GraphicInfo *gfx = &graphic_info[IMG_BACKGROUND_PANEL]; - - BlitBitmapTiled(gfx->bitmap, bitmap_db_panel, gfx->src_x, gfx->src_y, - gfx->width, gfx->height, 0, 0, DXSIZE, DYSIZE); - - SetDoorBackgroundBitmap(bitmap_db_panel); + SetDoorBackgroundImage(IMG_BACKGROUND_PANEL); } void DrawBackground(int x, int y, int width, int height) @@ -1487,6 +1517,11 @@ void SetRandomAnimationValue(int x, int y) gfx.anim_random_frame = GfxRandom[x][y]; } +void SetAnimationFirstLevel(int first_level) +{ + gfx.anim_first_level = first_level; +} + int getGraphicAnimationFrame(int graphic, int sync_frame) { // animation synchronized with global frame counter, not move position @@ -1709,7 +1744,7 @@ void DrawGraphicThruMask(int x, int y, int graphic, int frame) #if DEBUG if (!IN_SCR_FIELD(x, y)) { - Debug("draw:DrawGraphicThruMask", "x = %d,y = %d, graphic = %d", + Debug("draw:DrawGraphicThruMask", "x = %d, y = %d, graphic = %d", x, y, graphic); Debug("draw:DrawGraphicThruMask", "This should never happen!"); @@ -1728,7 +1763,7 @@ void DrawFixedGraphicThruMask(int x, int y, int graphic, int frame) #if DEBUG if (!IN_SCR_FIELD(x, y)) { - Debug("draw:DrawFixedGraphicThruMask", "x = %d,y = %d, graphic = %d", + Debug("draw:DrawFixedGraphicThruMask", "x = %d, y = %d, graphic = %d", x, y, graphic); Debug("draw:DrawFixedGraphicThruMask", "This should never happen!"); @@ -1802,7 +1837,7 @@ void DrawSizedGraphicThruMaskExt(DrawBuffer *d, int x, int y, int graphic, void DrawMiniGraphic(int x, int y, int graphic) { - DrawMiniGraphicExt(drawto, SX + x * MINI_TILEX,SY + y * MINI_TILEY, graphic); + DrawMiniGraphicExt(drawto, SX + x * MINI_TILEX, SY + y * MINI_TILEY, graphic); MarkTileDirty(x / 2, y / 2); } @@ -2005,9 +2040,9 @@ static void DrawGraphicShifted(int x, int y, int dx, int dy, } if (graphic_info[graphic].double_movement) // EM style movement images - DrawGraphicShiftedDouble(x, y, dx, dy, graphic, frame, cut_mode,mask_mode); + DrawGraphicShiftedDouble(x, y, dx, dy, graphic, frame, cut_mode, mask_mode); else - DrawGraphicShiftedNormal(x, y, dx, dy, graphic, frame, cut_mode,mask_mode); + DrawGraphicShiftedNormal(x, y, dx, dy, graphic, frame, cut_mode, mask_mode); } static void DrawGraphicShiftedThruMask(int x, int y, int dx, int dy, @@ -2692,7 +2727,7 @@ void DrawLevelField(int x, int y) DrawScreenField(SCREENX(x), SCREENY(y)); else if (IS_MOVING(x, y)) { - int newx,newy; + int newx, newy; Moving2Blocked(x, y, &newx, &newy); if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy))) @@ -2992,8 +3027,7 @@ void ShowEnvelope(int envelope_nr) static void PrepareEnvelopeRequestToScreen(Bitmap *bitmap, int sx, int sy, int xsize, int ysize) { - if (!global.use_envelope_request || - request.sort_priority <= 0) + if (!global.use_envelope_request) return; if (request.bitmap == NULL || @@ -3013,9 +3047,22 @@ static void PrepareEnvelopeRequestToScreen(Bitmap *bitmap, int sx, int sy, BlitBitmap(bitmap, request.bitmap, sx, sy, xsize, ysize, 0, 0); + // create masked surface for request bitmap, if needed + if (graphic_info[IMG_BACKGROUND_REQUEST].draw_masked) + { + SDL_Surface *surface = request.bitmap->surface; + SDL_Surface *surface_masked = request.bitmap->surface_masked; + + SDLBlitSurface(surface, surface_masked, 0, 0, xsize, ysize, 0, 0); + SDL_SetColorKey(surface_masked, SET_TRANSPARENT_PIXEL, + SDL_MapRGB(surface_masked->format, 0x00, 0x00, 0x00)); + } + SDLFreeBitmapTextures(request.bitmap); SDLCreateBitmapTextures(request.bitmap); + ResetBitmapAlpha(request.bitmap); + // set envelope request run-time values request.sx = sx; request.sy = sy; @@ -3023,16 +3070,22 @@ static void PrepareEnvelopeRequestToScreen(Bitmap *bitmap, int sx, int sy, request.ysize = ysize; } -void DrawEnvelopeRequestToScreen(int drawing_target, int drawing_stage) +void DrawEnvelopeRequestToScreen(int drawing_target) { if (global.use_envelope_request && - game.request_active_or_moving && - request.sort_priority > 0 && - drawing_target == DRAW_TO_SCREEN && - drawing_stage == DRAW_GLOBAL_ANIM_STAGE_2) + game.request_active && + drawing_target == DRAW_TO_SCREEN) { - BlitToScreen(request.bitmap, 0, 0, request.xsize, request.ysize, - request.sx, request.sy); + struct GraphicInfo *g = &graphic_info[IMG_BACKGROUND_REQUEST]; + + SetBitmapAlphaNextBlit(request.bitmap, g->alpha); + + if (g->draw_masked) + BlitToScreenMasked(request.bitmap, 0, 0, request.xsize, request.ysize, + request.sx, request.sy); + else + BlitToScreen(request.bitmap, 0, 0, request.xsize, request.ysize, + request.sx, request.sy); } } @@ -3103,7 +3156,7 @@ static void setRequestPosition(int *x, int *y, boolean add_border_size) setRequestPositionExt(x, y, request.width, request.height, add_border_size); } -static void DrawEnvelopeRequest(char *text) +static void DrawEnvelopeRequestText(int sx, int sy, char *text) { char *text_final = text; char *text_door_style = NULL; @@ -3121,15 +3174,11 @@ static void DrawEnvelopeRequest(char *text) int line_length = max_text_width / font_width; int max_lines = max_text_height / line_height; int text_width = line_length * font_width; - int width = request.width; - int height = request.height; - int tile_size = MAX(request.step_offset, 1); - int x_steps = width / tile_size; - int y_steps = height / tile_size; int sx_offset = border_size; int sy_offset = border_size; - int sx, sy; - int i, x, y; + + // force DOOR font inside door area + SetFontStatus(GAME_MODE_PSEUDO_DOOR); if (request.centered) sx_offset = (request.width - text_width) / 2; @@ -3138,6 +3187,13 @@ static void DrawEnvelopeRequest(char *text) { char *src_text_ptr, *dst_text_ptr; + if (maxWordLengthInRequestString(text) > line_length) + { + font_nr = FONT_REQUEST_NARROW; + font_width = getFontWidth(font_nr); + line_length = max_text_width / font_width; + } + text_door_style = checked_malloc(2 * strlen(text) + 1); src_text_ptr = text; @@ -3161,9 +3217,34 @@ static void DrawEnvelopeRequest(char *text) text_final = text_door_style; } + DrawTextBuffer(sx + sx_offset, sy + sy_offset, text_final, font_nr, + line_length, -1, max_lines, line_spacing, mask_mode, + request.autowrap, request.centered, FALSE); + + if (text_door_style) + free(text_door_style); + + ResetFontStatus(); +} + +static void DrawEnvelopeRequest(char *text, unsigned int req_state) +{ + DrawBuffer *drawto_last = drawto; + int graphic = IMG_BACKGROUND_REQUEST; + int width = request.width; + int height = request.height; + int tile_size = MAX(request.step_offset, 1); + int x_steps = width / tile_size; + int y_steps = height / tile_size; + int sx, sy; + int x, y; + setRequestPosition(&sx, &sy, FALSE); - ClearRectangle(backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE); + // draw complete envelope request to temporary bitmap + drawto = bitmap_db_store_1; + + ClearRectangle(drawto, sx, sy, width, height); for (y = 0; y < y_steps; y++) for (x = 0; x < x_steps; x++) @@ -3171,37 +3252,27 @@ static void DrawEnvelopeRequest(char *text) x, y, x_steps, y_steps, tile_size, tile_size); - // force DOOR font inside door area - SetFontStatus(GAME_MODE_PSEUDO_DOOR); - - DrawTextBuffer(sx + sx_offset, sy + sy_offset, text_final, font_nr, - line_length, -1, max_lines, line_spacing, mask_mode, - request.autowrap, request.centered, FALSE); - - ResetFontStatus(); - - for (i = 0; i < NUM_TOOL_BUTTONS; i++) - RedrawGadget(tool_gadget[i]); + // write text for request + DrawEnvelopeRequestText(sx, sy, text); - // store readily prepared envelope request for later use when animating - BlitBitmap(backbuffer, bitmap_db_store_2, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); + MapToolButtons(req_state); - PrepareEnvelopeRequestToScreen(bitmap_db_store_2, sx, sy, width, height); + // restore pointer to drawing buffer + drawto = drawto_last; - if (text_door_style) - free(text_door_style); + // prepare complete envelope request from temporary bitmap + PrepareEnvelopeRequestToScreen(bitmap_db_store_1, sx, sy, width, height); } static void AnimateEnvelopeRequest(int anim_mode, int action) { - int graphic = IMG_BACKGROUND_REQUEST; - boolean draw_masked = graphic_info[graphic].draw_masked; + boolean game_ended = (game_status == GAME_MODE_PLAYING && checkGameEnded()); int delay_value_normal = request.step_delay; int delay_value_fast = delay_value_normal / 2; 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 = MAX(1, (no_delay ? 0 : delay_value + 500 * 0) / 2); + int anim_delay_value = MAX(1, (no_delay ? 0 : delay_value) / 2); DelayCounter anim_delay = { anim_delay_value }; int tile_size = MAX(request.step_offset, 1); @@ -3244,11 +3315,12 @@ static void AnimateEnvelopeRequest(int anim_mode, int action) int dst_x, dst_y; int xx, yy; + if (game_ended) + HandleGameActions(); + setRequestPosition(&src_x, &src_y, FALSE); setRequestPositionExt(&dst_x, &dst_y, width, height, FALSE); - BlitBitmap(bitmap_db_store_1, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); - for (yy = 0; yy < 2; yy++) { for (xx = 0; xx < 2; xx++) @@ -3260,16 +3332,15 @@ static void AnimateEnvelopeRequest(int anim_mode, int action) int xx_size = (xx ? tile_size : xsize_size_left); int yy_size = (yy ? tile_size : ysize_size_top); - if (draw_masked) - BlitBitmapMasked(bitmap_db_store_2, backbuffer, - src_xx, src_yy, xx_size, yy_size, dst_xx, dst_yy); - else - BlitBitmap(bitmap_db_store_2, backbuffer, - src_xx, src_yy, xx_size, yy_size, dst_xx, dst_yy); + // draw partial (animated) envelope request to temporary bitmap + BlitBitmap(bitmap_db_store_1, bitmap_db_store_2, + src_xx, src_yy, xx_size, yy_size, dst_xx, dst_yy); } } - PrepareEnvelopeRequestToScreen(backbuffer, dst_x, dst_y, width, height); + // prepare partial (animated) envelope request from temporary bitmap + PrepareEnvelopeRequestToScreen(bitmap_db_store_2, dst_x, dst_y, + width, height); redraw_mask |= REDRAW_FIELD; @@ -3292,40 +3363,6 @@ static void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) int main_anim_mode = (anim_mode == ANIM_NONE ? ANIM_VERTICAL|ANIM_HORIZONTAL: anim_mode == ANIM_DEFAULT ? ANIM_VERTICAL : anim_mode); - if (game_status == GAME_MODE_PLAYING) - BlitScreenToBitmap(backbuffer); - - SetDrawtoField(DRAW_TO_BACKBUFFER); - - // SetDrawBackgroundMask(REDRAW_NONE); - - if (action == ACTION_OPENING) - { - BlitBitmap(backbuffer, bitmap_db_store_1, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); - - if (req_state & REQ_ASK) - { - MapGadget(tool_gadget[TOOL_CTRL_ID_YES]); - MapGadget(tool_gadget[TOOL_CTRL_ID_NO]); - MapGadget(tool_gadget[TOOL_CTRL_ID_TOUCH_YES]); - MapGadget(tool_gadget[TOOL_CTRL_ID_TOUCH_NO]); - } - else if (req_state & REQ_CONFIRM) - { - MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]); - MapGadget(tool_gadget[TOOL_CTRL_ID_TOUCH_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]); - } - - DrawEnvelopeRequest(text); - } - game.envelope_active = TRUE; // needed for RedrawPlayfield() events if (action == ACTION_OPENING) @@ -3349,20 +3386,6 @@ static void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) } game.envelope_active = FALSE; - - if (action == ACTION_CLOSING) - BlitBitmap(bitmap_db_store_1, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); - - // SetDrawBackgroundMask(last_draw_background_mask); - - redraw_mask |= REDRAW_FIELD; - - BackToFront(); - - if (action == ACTION_CLOSING && - game_status == GAME_MODE_PLAYING && - level.game_engine_type == GAME_ENGINE_TYPE_RND) - SetDrawtoField(DRAW_TO_FIELDBUFFER); } static void DrawPreviewElement(int dst_x, int dst_y, int element, int tilesize) @@ -3385,7 +3408,7 @@ static void DrawPreviewElement(int dst_x, int dst_y, int element, int tilesize) void DrawLevel(int draw_background_mask) { - int x,y; + int x, y; SetMainBackgroundImage(IMG_BACKGROUND_PLAYING); SetDrawBackgroundMask(draw_background_mask); @@ -3402,7 +3425,7 @@ void DrawLevel(int draw_background_mask) void DrawSizedLevel(int size_x, int size_y, int scroll_x, int scroll_y, int tilesize) { - int x,y; + int x, y; for (x = 0; x < size_x; x++) for (y = 0; y < size_y; y++) @@ -3413,7 +3436,7 @@ void DrawSizedLevel(int size_x, int size_y, int scroll_x, int scroll_y, void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y) { - int x,y; + int x, y; for (x = 0; x < size_x; x++) for (y = 0; y < size_y; y++) @@ -3915,6 +3938,18 @@ void DrawFixedGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y, DrawFixedGraphicExt(dst_bitmap, x, y, graphic, frame); } +void DrawSizedGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y, + int graphic, int sync_frame, int tilesize, + int mask_mode) +{ + int frame = getGraphicAnimationFrame(graphic, sync_frame); + + if (mask_mode == USE_MASKING) + DrawSizedGraphicThruMaskExt(dst_bitmap, x, y, graphic, frame, tilesize); + else + DrawSizedGraphicExt(dst_bitmap, x, y, graphic, frame, tilesize); +} + static void DrawGraphicAnimation(int x, int y, int graphic) { int lx = LEVELX(x), ly = LEVELY(y); @@ -4042,7 +4077,7 @@ static int getPlayerGraphic(struct PlayerInfo *player, int move_dir) return graphic; } else - return el_act_dir2img(player->artwork_element, player->GfxAction,move_dir); + return el_act_dir2img(player->artwork_element, player->GfxAction, move_dir); } static boolean equalGraphics(int graphic1, int graphic2) @@ -4191,9 +4226,6 @@ static void DrawPlayerExt(struct PlayerInfo *player, int drawing_stage) DrawDynamite(last_jx, last_jy); else DrawLevelField(last_jx, last_jy); - - if (player->is_pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy))) - DrawLevelElement(next_jx, next_jy, EL_EMPTY); } else if (drawing_stage == DRAW_PLAYER_STAGE_FIELD_UNDER_PLAYER) { @@ -4251,6 +4283,9 @@ static void DrawPlayerExt(struct PlayerInfo *player, int drawing_stage) if (!player->is_pushing || !player->is_moving) return; + if (Tile[next_jx][next_jy] == EL_EXPLOSION) + return; + int gfx_frame = GfxFrame[jx][jy]; if (!IS_MOVING(jx, jy)) // push movement already finished @@ -4272,14 +4307,12 @@ static void DrawPlayerExt(struct PlayerInfo *player, int drawing_stage) DrawLevelElement(jx, jy, Back[jx][jy]); else DrawLevelElement(jx, jy, EL_EMPTY); - - if (Back[next_jx][next_jy]) - DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]); - else - DrawLevelElement(next_jx, next_jy, EL_EMPTY); } - else if (Back[next_jx][next_jy]) + + if (Back[next_jx][next_jy]) DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]); + else + DrawLevelElement(next_jx, next_jy, EL_EMPTY); int px = SCREENX(jx), py = SCREENY(jy); int pxx = (TILEX - ABS(sxx)) * dx; @@ -4470,26 +4503,15 @@ void WaitForEventToContinue(void) } } -#define MAX_REQUEST_LINES 13 -#define MAX_REQUEST_LINE_FONT1_LEN 7 -#define MAX_REQUEST_LINE_FONT2_LEN 10 - static int RequestHandleEvents(unsigned int req_state, int draw_buffer_game) { - boolean game_just_ended = (game_status == GAME_MODE_PLAYING && - checkGameEnded()); + boolean game_ended = (game_status == GAME_MODE_PLAYING && checkGameEnded()); int draw_buffer_last = GetDrawtoField(); int width = request.width; int height = request.height; int sx, sy; int result; - // when showing request dialog after game ended, deactivate game panel - if (game_just_ended) - game.panel.active = FALSE; - - game.request_active = TRUE; - setRequestPosition(&sx, &sy, FALSE); button_status = MB_RELEASED; @@ -4499,21 +4521,13 @@ static int RequestHandleEvents(unsigned int req_state, int draw_buffer_game) while (result < 0) { - boolean event_handled = FALSE; - - if (game_just_ended) + if (game_ended) { SetDrawtoField(draw_buffer_game); HandleGameActions(); SetDrawtoField(DRAW_TO_BACKBUFFER); - - if (global.use_envelope_request) - { - // copy current state of request area to middle of playfield area - BlitBitmap(bitmap_db_store_2, drawto, sx, sy, width, height, sx, sy); - } } if (PendingEvent()) @@ -4522,14 +4536,13 @@ static int RequestHandleEvents(unsigned int req_state, int draw_buffer_game) while (NextValidEvent(&event)) { - event_handled = TRUE; - switch (event.type) { case EVENT_BUTTONPRESS: case EVENT_BUTTONRELEASE: case EVENT_MOTIONNOTIFY: { + DrawBuffer *drawto_last = drawto; int mx, my; if (event.type == EVENT_MOTIONNOTIFY) @@ -4552,9 +4565,25 @@ static int RequestHandleEvents(unsigned int req_state, int draw_buffer_game) button_status = MB_RELEASED; } + if (global.use_envelope_request) + { + // draw changed button states to temporary bitmap + drawto = bitmap_db_store_1; + } + // this sets 'request_gadget_id' HandleGadgets(mx, my, button_status); + if (global.use_envelope_request) + { + // restore pointer to drawing buffer + drawto = drawto_last; + + // prepare complete envelope request from temporary bitmap + PrepareEnvelopeRequestToScreen(bitmap_db_store_1, sx, sy, + width, height); + } + switch (request_gadget_id) { case TOOL_CTRL_ID_YES: @@ -4584,11 +4613,12 @@ static int RequestHandleEvents(unsigned int req_state, int draw_buffer_game) break; default: - // only check clickable animations if no request gadget clicked - HandleGlobalAnimClicks(mx, my, button_status, FALSE); break; } + // only needed to handle clickable pointer animations here + HandleGlobalAnimClicks(mx, my, button_status, FALSE); + break; } @@ -4778,45 +4808,21 @@ static int RequestHandleEvents(unsigned int req_state, int draw_buffer_game) } } - if (event_handled) - { - if (game_just_ended) - { - if (global.use_envelope_request) - { - // copy back current state of pressed buttons inside request area - BlitBitmap(drawto, bitmap_db_store_2, sx, sy, width, height, sx, sy); - } - } - - PrepareEnvelopeRequestToScreen(drawto, sx, sy, width, height); - } - BackToFront(); } SetDrawtoField(draw_buffer_last); - game.request_active = FALSE; - return result; } -static boolean RequestDoor(char *text, unsigned int req_state) +static void DoRequestBefore(void) { - int draw_buffer_last = GetDrawtoField(); - unsigned int old_door_state; - int max_request_line_len = MAX_REQUEST_LINE_FONT1_LEN; - int font_nr = FONT_TEXT_2; - char *text_ptr; - int result; - int ty; + boolean game_ended = (game_status == GAME_MODE_PLAYING && checkGameEnded()); - if (maxWordLengthInRequestString(text) > MAX_REQUEST_LINE_FONT1_LEN) - { - max_request_line_len = MAX_REQUEST_LINE_FONT2_LEN; - font_nr = FONT_TEXT_1; - } + // when showing request dialog after game ended, deactivate game panel + if (game_ended) + game.panel.active = FALSE; if (game_status == GAME_MODE_PLAYING) BlitScreenToBitmap(backbuffer); @@ -4830,41 +4836,89 @@ static boolean RequestDoor(char *text, unsigned int req_state) // pause network game while waiting for request to answer if (network.enabled && game_status == GAME_MODE_PLAYING && - !game.all_players_gone && - req_state & REQUEST_WAIT_FOR_INPUT) + !game.all_players_gone) SendToServer_PausePlaying(); - 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(); +static void DoRequestAfter(void) +{ + RemapAllGadgets(); - if (old_door_state & DOOR_OPEN_1) + if (game_status == GAME_MODE_PLAYING) { - CloseDoor(DOOR_CLOSE_1); + SetPanelBackground(); + SetDrawBackgroundMask(REDRAW_DOOR_1); + } + else + { + SetDrawBackgroundMask(REDRAW_FIELD); + } - // save old door content - BlitBitmap(bitmap_db_door_1, bitmap_db_door_1, - 0 * DXSIZE, 0, DXSIZE, DYSIZE, 1 * DXSIZE, 0); + // continue network game after request + if (network.enabled && + game_status == GAME_MODE_PLAYING && + !game.all_players_gone) + SendToServer_ContinuePlaying(); + + // restore deactivated drawing when quick-loading level tape recording + if (tape.playing && tape.deactivate_display) + TapeDeactivateDisplayOn(); +} + +static void setRequestDoorTextProperties(char *text, + int text_spacing, + int line_spacing, + int *set_font_nr, + int *set_max_lines, + int *set_max_line_length) +{ + struct RectWithBorder *vp_door_1 = &viewport.door_1[game_status]; + struct TextPosInfo *pos = &request.button.confirm; + int button_ypos = pos->y; + int font_nr = FONT_TEXT_2; + int font_width = getFontWidth(font_nr); + int font_height = getFontHeight(font_nr); + int line_height = font_height + line_spacing; + int max_text_width = vp_door_1->width; + int max_text_height = button_ypos - 2 * text_spacing; + int max_line_length = max_text_width / font_width; + int max_lines = max_text_height / line_height; + + if (maxWordLengthInRequestString(text) > max_line_length) + { + font_nr = FONT_TEXT_1; + font_width = getFontWidth(font_nr); + max_line_length = max_text_width / font_width; } - SetDoorBackgroundImage(IMG_BACKGROUND_DOOR); - SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); + *set_font_nr = font_nr; + *set_max_lines = max_lines; + *set_max_line_length = max_line_length; +} - // clear door drawing field - DrawBackground(DX, DY, DXSIZE, DYSIZE); +static void DrawRequestDoorText(char *text) +{ + char *text_ptr = text; + int text_spacing = 8; + int line_spacing = 2; + int max_request_lines; + int max_request_line_len; + int font_nr; + int ty; // force DOOR font inside door area SetFontStatus(GAME_MODE_PSEUDO_DOOR); - // write text for request - for (text_ptr = text, ty = 0; ty < MAX_REQUEST_LINES; ty++) + setRequestDoorTextProperties(text, text_spacing, line_spacing, &font_nr, + &max_request_lines, &max_request_line_len); + + for (text_ptr = text, ty = 0; ty < max_request_lines; ty++) { char text_line[max_request_line_len + 1]; int tx, tl, tc = 0; @@ -4875,7 +4929,6 @@ static boolean RequestDoor(char *text, unsigned int req_state) for (tl = 0, tx = 0; tx < max_request_line_len; tl++, tx++) { tc = *(text_ptr + tx); - // if (!tc || tc == ' ') if (!tc || tc == ' ' || tc == '?' || tc == '!') break; } @@ -4894,56 +4947,45 @@ static boolean RequestDoor(char *text, unsigned int req_state) text_line[tl] = 0; DrawText(DX + (DXSIZE - tl * getFontWidth(font_nr)) / 2, - DY + 8 + ty * (getFontHeight(font_nr) + 2), + DY + text_spacing + ty * (getFontHeight(font_nr) + line_spacing), text_line, font_nr); text_ptr += tl + (tc == ' ' ? 1 : 0); - // text_ptr += tl + (tc == ' ' || tc == '?' || tc == '!' ? 1 : 0); } ResetFontStatus(); +} - if (req_state & REQ_ASK) - { - MapGadget(tool_gadget[TOOL_CTRL_ID_YES]); - MapGadget(tool_gadget[TOOL_CTRL_ID_NO]); - MapGadget(tool_gadget[TOOL_CTRL_ID_TOUCH_YES]); - MapGadget(tool_gadget[TOOL_CTRL_ID_TOUCH_NO]); - } - else if (req_state & REQ_CONFIRM) - { - MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]); - MapGadget(tool_gadget[TOOL_CTRL_ID_TOUCH_CONFIRM]); - } - else if (req_state & REQ_PLAYER) +static int RequestDoor(char *text, unsigned int req_state) +{ + unsigned int old_door_state = GetDoorState(); + int draw_buffer_last = GetDrawtoField(); + int result; + + if (old_door_state & DOOR_OPEN_1) { - 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]); + CloseDoor(DOOR_CLOSE_1); + + // save old door content + BlitBitmap(bitmap_db_door_1, bitmap_db_door_1, + 0, 0, DXSIZE, DYSIZE, DXSIZE, 0); } - // copy request gadgets to door backbuffer - BlitBitmap(drawto, bitmap_db_door_1, DX, DY, DXSIZE, DYSIZE, 0, 0); + SetDoorBackgroundImage(IMG_BACKGROUND_DOOR); + SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); - OpenDoor(DOOR_OPEN_1); + // clear door drawing field + DrawBackground(DX, DY, DXSIZE, DYSIZE); - if (!(req_state & REQUEST_WAIT_FOR_INPUT)) - { - if (game_status == GAME_MODE_PLAYING) - { - SetPanelBackground(); - SetDrawBackgroundMask(REDRAW_DOOR_1); - } - else - { - SetDrawBackgroundMask(REDRAW_FIELD); - } + // write text for request + DrawRequestDoorText(text); - return FALSE; - } + MapToolButtons(req_state); - SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); + // copy request gadgets to door backbuffer + BlitBitmap(drawto, bitmap_db_door_1, DX, DY, DXSIZE, DYSIZE, 0, 0); + + OpenDoor(DOOR_OPEN_1); // ---------- handle request buttons ---------- result = RequestHandleEvents(req_state, draw_buffer_last); @@ -4959,85 +5001,17 @@ static boolean RequestDoor(char *text, unsigned int req_state) OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK); } - RemapAllGadgets(); - - if (game_status == GAME_MODE_PLAYING) - { - SetPanelBackground(); - SetDrawBackgroundMask(REDRAW_DOOR_1); - } - else - { - SetDrawBackgroundMask(REDRAW_FIELD); - } - - // continue network game after request - if (network.enabled && - game_status == GAME_MODE_PLAYING && - !game.all_players_gone && - req_state & REQUEST_WAIT_FOR_INPUT) - SendToServer_ContinuePlaying(); - - // 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) +static int RequestEnvelope(char *text, unsigned int req_state) { int draw_buffer_last = GetDrawtoField(); int result; - if (game_status == GAME_MODE_PLAYING) - BlitScreenToBitmap(backbuffer); - - // disable deactivated drawing when quick-loading level tape recording - if (tape.playing && tape.deactivate_display) - TapeDeactivateDisplayOff(TRUE); - - SetMouseCursor(CURSOR_DEFAULT); - - // pause network game while waiting for request to answer - if (network.enabled && - game_status == GAME_MODE_PLAYING && - !game.all_players_gone && - req_state & REQUEST_WAIT_FOR_INPUT) - SendToServer_PausePlaying(); - - // 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); - + DrawEnvelopeRequest(text, req_state); ShowEnvelopeRequest(text, req_state, ACTION_OPENING); - if (!(req_state & REQUEST_WAIT_FOR_INPUT)) - { - if (game_status == GAME_MODE_PLAYING) - { - SetPanelBackground(); - SetDrawBackgroundMask(REDRAW_DOOR_1); - } - else - { - SetDrawBackgroundMask(REDRAW_FIELD); - } - - return FALSE; - } - - SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); - // ---------- handle request buttons ---------- result = RequestHandleEvents(req_state, draw_buffer_last); @@ -5045,49 +5019,30 @@ static boolean RequestEnvelope(char *text, unsigned int req_state) ShowEnvelopeRequest(text, req_state, ACTION_CLOSING); - RemapAllGadgets(); - - if (game_status == GAME_MODE_PLAYING) - { - SetPanelBackground(); - SetDrawBackgroundMask(REDRAW_DOOR_1); - } - else - { - SetDrawBackgroundMask(REDRAW_FIELD); - } - - // continue network game after request - if (network.enabled && - game_status == GAME_MODE_PLAYING && - !game.all_players_gone && - req_state & REQUEST_WAIT_FOR_INPUT) - SendToServer_ContinuePlaying(); - - // restore deactivated drawing when quick-loading level tape recording - if (tape.playing && tape.deactivate_display) - TapeDeactivateDisplayOn(); - return result; } -boolean Request(char *text, unsigned int req_state) +int Request(char *text, unsigned int req_state) { boolean overlay_enabled = GetOverlayEnabled(); - boolean result; + int result; - game.request_active_or_moving = TRUE; + game.request_active = TRUE; SetOverlayEnabled(FALSE); + DoRequestBefore(); + if (global.use_envelope_request) result = RequestEnvelope(text, req_state); else result = RequestDoor(text, req_state); + DoRequestAfter(); + SetOverlayEnabled(overlay_enabled); - game.request_active_or_moving = FALSE; + game.request_active = FALSE; return result; } @@ -5391,6 +5346,7 @@ unsigned int MoveDoor(unsigned int door_state) if (door_state & DOOR_ACTION) { + boolean game_ended = (game_status == GAME_MODE_PLAYING && checkGameEnded()); boolean door_panel_drawn[NUM_DOORS]; boolean panel_has_doors[NUM_DOORS]; boolean door_part_skip[MAX_DOOR_PARTS]; @@ -5657,6 +5613,9 @@ unsigned int MoveDoor(unsigned int door_state) if (!(door_state & DOOR_NO_DELAY)) { + if (game_ended) + HandleGameActions(); + BackToFront(); SkipUntilDelayReached(&door_delay, &k, last_frame); @@ -5680,7 +5639,12 @@ unsigned int MoveDoor(unsigned int door_state) door_delay.value = door_2.post_delay; while (!DelayReached(&door_delay)) + { + if (game_ended) + HandleGameActions(); + BackToFront(); + } } } @@ -5943,6 +5907,29 @@ void FreeToolButtons(void) FreeGadget(tool_gadget[i]); } +static void MapToolButtons(unsigned int req_state) +{ + if (req_state & REQ_ASK) + { + MapGadget(tool_gadget[TOOL_CTRL_ID_YES]); + MapGadget(tool_gadget[TOOL_CTRL_ID_NO]); + MapGadget(tool_gadget[TOOL_CTRL_ID_TOUCH_YES]); + MapGadget(tool_gadget[TOOL_CTRL_ID_TOUCH_NO]); + } + else if (req_state & REQ_CONFIRM) + { + MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]); + MapGadget(tool_gadget[TOOL_CTRL_ID_TOUCH_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]); + } +} + static void UnmapToolButtons(void) { int i; @@ -8198,6 +8185,10 @@ int map_element_RND_to_MM(int element_rnd) element_rnd <= EL_MM_END_2 ? EL_MM_START_2_NATIVE + element_rnd - EL_MM_START_2 : + element_rnd >= EL_MM_START_3 && + element_rnd <= EL_MM_END_3 ? + EL_MM_START_3_NATIVE + element_rnd - EL_MM_START_3 : + element_rnd >= EL_CHAR_START && element_rnd <= EL_CHAR_END ? EL_MM_CHAR_START_NATIVE + element_rnd - EL_CHAR_START : @@ -8223,6 +8214,10 @@ int map_element_MM_to_RND(int element_mm) element_mm <= EL_MM_END_2_NATIVE ? EL_MM_START_2 + element_mm - EL_MM_START_2_NATIVE : + element_mm >= EL_MM_START_3_NATIVE && + element_mm <= EL_MM_END_3_NATIVE ? + EL_MM_START_3 + element_mm - EL_MM_START_3_NATIVE : + element_mm >= EL_MM_CHAR_START_NATIVE && element_mm <= EL_MM_CHAR_END_NATIVE ? EL_CHAR_START + element_mm - EL_MM_CHAR_START_NATIVE : @@ -9429,6 +9424,17 @@ int getGraphicInfo_Delay(int graphic) return graphic_info[graphic].anim_delay; } +boolean getGraphicInfo_NewFrame(int x, int y, int graphic) +{ + if (!IS_NEW_FRAME(GfxFrame[x][y], graphic)) + return FALSE; + + if (ANIM_MODE(graphic) & (ANIM_TILED | ANIM_RANDOM_STATIC)) + return FALSE; + + return TRUE; +} + void PlayMenuSoundExt(int sound) { if (sound == SND_UNDEFINED)