X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=622fa488166603440dd57e3a8afbbcc19a054a2b;hb=b09d5604ce8b27c7fdff1ce3839fccd62f5b4bf6;hp=accded22545e5bb8e1eba390403e551a2c87b4c4;hpb=2276a40b6ceb93c0e54317a6f3aa85c09e535f68;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index accded22..622fa488 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); @@ -645,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) @@ -1514,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 @@ -3053,6 +3061,8 @@ static void PrepareEnvelopeRequestToScreen(Bitmap *bitmap, int sx, int sy, SDLFreeBitmapTextures(request.bitmap); SDLCreateBitmapTextures(request.bitmap); + ResetBitmapAlpha(request.bitmap); + // set envelope request run-time values request.sx = sx; request.sy = sy; @@ -3063,10 +3073,14 @@ static void PrepareEnvelopeRequestToScreen(Bitmap *bitmap, int sx, int sy, void DrawEnvelopeRequestToScreen(int drawing_target) { if (global.use_envelope_request && - game.request_active_or_moving && + game.request_active && drawing_target == DRAW_TO_SCREEN) { - if (graphic_info[IMG_BACKGROUND_REQUEST].draw_masked) + 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 @@ -3142,9 +3156,8 @@ 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, unsigned int req_state) +static void DrawEnvelopeRequestText(int sx, int sy, char *text) { - DrawBuffer *drawto_last = drawto; char *text_final = text; char *text_door_style = NULL; int graphic = IMG_BACKGROUND_REQUEST; @@ -3161,15 +3174,11 @@ static void DrawEnvelopeRequest(char *text, unsigned int req_state) 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 x, y; + + // force DOOR font inside door area + SetFontStatus(GAME_MODE_PSEUDO_DOOR); if (request.centered) sx_offset = (request.width - text_width) / 2; @@ -3178,6 +3187,13 @@ static void DrawEnvelopeRequest(char *text, unsigned int req_state) { 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; @@ -3201,10 +3217,32 @@ static void DrawEnvelopeRequest(char *text, unsigned int req_state) 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); - // draw envelope request to temporary bitmap - drawto = bitmap_db_store_2; + // draw complete envelope request to temporary bitmap + drawto = bitmap_db_store_1; ClearRectangle(drawto, sx, sy, width, height); @@ -3214,52 +3252,27 @@ static void DrawEnvelopeRequest(char *text, unsigned int req_state) 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(); + // write text for request + DrawEnvelopeRequestText(sx, sy, text); - 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]); - } + MapToolButtons(req_state); // restore pointer to drawing buffer drawto = drawto_last; - PrepareEnvelopeRequestToScreen(bitmap_db_store_2, sx, sy, width, height); - - 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) { + 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); @@ -3302,6 +3315,9 @@ 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); @@ -3316,12 +3332,14 @@ 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); - BlitBitmap(bitmap_db_store_2, bitmap_db_store_1, + // 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(bitmap_db_store_1, dst_x, dst_y, + // prepare partial (animated) envelope request from temporary bitmap + PrepareEnvelopeRequestToScreen(bitmap_db_store_2, dst_x, dst_y, width, height); redraw_mask |= REDRAW_FIELD; @@ -3349,8 +3367,6 @@ static void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) if (action == ACTION_OPENING) { - DrawEnvelopeRequest(text, req_state); - PlayMenuSoundStereo(sound_opening, SOUND_MIDDLE); if (anim_mode == ANIM_DEFAULT) @@ -4487,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; @@ -4516,7 +4521,7 @@ static int RequestHandleEvents(unsigned int req_state, int draw_buffer_game) while (result < 0) { - if (game_just_ended) + if (game_ended) { SetDrawtoField(draw_buffer_game); @@ -4563,7 +4568,7 @@ static int RequestHandleEvents(unsigned int req_state, int draw_buffer_game) if (global.use_envelope_request) { // draw changed button states to temporary bitmap - drawto = bitmap_db_store_2; + drawto = bitmap_db_store_1; } // this sets 'request_gadget_id' @@ -4571,10 +4576,12 @@ static int RequestHandleEvents(unsigned int req_state, int draw_buffer_game) if (global.use_envelope_request) { - PrepareEnvelopeRequestToScreen(drawto, sx, sy, width, height); - // 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) @@ -4606,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; } @@ -4805,26 +4813,16 @@ static int RequestHandleEvents(unsigned int req_state, int draw_buffer_game) 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); @@ -4838,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; @@ -4883,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; } @@ -4902,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); @@ -4967,135 +5001,48 @@ 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); + DrawEnvelopeRequest(text, req_state); + ShowEnvelopeRequest(text, req_state, ACTION_OPENING); - // disable deactivated drawing when quick-loading level tape recording - if (tape.playing && tape.deactivate_display) - TapeDeactivateDisplayOff(TRUE); + // ---------- handle request buttons ---------- + result = RequestHandleEvents(req_state, draw_buffer_last); - SetMouseCursor(CURSOR_DEFAULT); + UnmapToolButtons(); - // 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(); + ShowEnvelopeRequest(text, req_state, ACTION_CLOSING); - // simulate releasing mouse button over last gadget, if still pressed - if (button_status) - HandleGadgets(-1, -1, 0); + return result; +} - UnmapAllGadgets(); +int Request(char *text, unsigned int req_state) +{ + boolean overlay_enabled = GetOverlayEnabled(); + int result; - // (replace with setting corresponding request background) - // SetDoorBackgroundImage(IMG_BACKGROUND_DOOR); - // SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); + game.request_active = TRUE; - // clear door drawing field - // DrawBackground(DX, DY, DXSIZE, DYSIZE); + SetOverlayEnabled(FALSE); - ShowEnvelopeRequest(text, req_state, ACTION_OPENING); + DoRequestBefore(); - if (!(req_state & REQUEST_WAIT_FOR_INPUT)) - { - if (game_status == GAME_MODE_PLAYING) - { - SetPanelBackground(); - SetDrawBackgroundMask(REDRAW_DOOR_1); - } - else - { - SetDrawBackgroundMask(REDRAW_FIELD); - } + if (global.use_envelope_request) + result = RequestEnvelope(text, req_state); + else + result = RequestDoor(text, req_state); - return FALSE; - } + DoRequestAfter(); - SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); + SetOverlayEnabled(overlay_enabled); - // ---------- handle request buttons ---------- - result = RequestHandleEvents(req_state, draw_buffer_last); - - UnmapToolButtons(); - - 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) -{ - boolean overlay_enabled = GetOverlayEnabled(); - boolean result; - - game.request_active_or_moving = TRUE; - - SetOverlayEnabled(FALSE); - - if (global.use_envelope_request) - result = RequestEnvelope(text, req_state); - else - result = RequestDoor(text, req_state); - - SetOverlayEnabled(overlay_enabled); - - game.request_active_or_moving = FALSE; + game.request_active = FALSE; return result; } @@ -5399,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]; @@ -5665,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); @@ -5688,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(); + } } } @@ -5951,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; @@ -5964,6 +5943,1145 @@ static void HandleToolButtons(struct GadgetInfo *gi) request_gadget_id = gi->custom_id; } +static struct Mapping_BD_to_RND_object +{ + int element_bd; + boolean is_rnd_to_bd_mapping; // unique mapping BD <-> RND + + int element_rnd; + int action; + int direction; +} +bd_object_mapping_list[] = +{ + // additional RND style elements mapped to BD style elements must be listed first + + { + O_DIRT, TRUE, + EL_SAND, -1, -1 + }, + { + O_STONE, TRUE, + EL_BD_ROCK, -1, -1 + }, + { + O_BRICK, TRUE, + EL_BD_WALL, -1, -1 + }, + { + O_STEEL, TRUE, + EL_STEELWALL, -1, -1 + }, + { + O_DIAMOND, TRUE, + EL_BD_DIAMOND, -1, -1 + }, + { + O_INBOX, TRUE, + EL_PLAYER_1, -1, -1 + }, + { + O_INBOX, TRUE, + EL_PLAYER_2, -1, -1 + }, + { + O_INBOX, TRUE, + EL_PLAYER_3, -1, -1 + }, + { + O_INBOX, TRUE, + EL_PLAYER_4, -1, -1 + }, + { + O_PRE_OUTBOX, TRUE, + EL_EXIT_CLOSED, -1, -1 + }, + + // BD style elements with their corresponding RND style elements + + { + O_SPACE, TRUE, + EL_EMPTY, -1, -1 + }, + { + O_DIRT, TRUE, + EL_BD_SAND, -1, -1 + }, + { + O_DIRT_SLOPED_UP_RIGHT, TRUE, + EL_BD_SAND_SLOPED_UP_RIGHT, -1, -1 + }, + { + O_DIRT_SLOPED_UP_LEFT, TRUE, + EL_BD_SAND_SLOPED_UP_LEFT, -1, -1 + }, + { + O_DIRT_SLOPED_DOWN_LEFT, TRUE, + EL_BD_SAND_SLOPED_DOWN_LEFT, -1, -1 + }, + { + O_DIRT_SLOPED_DOWN_RIGHT, TRUE, + EL_BD_SAND_SLOPED_DOWN_RIGHT, -1, -1 + }, + { + O_DIRT_BALL, TRUE, + EL_BD_SAND_BALL, -1, -1 + }, + { + O_DIRT_BALL_F, FALSE, + EL_BD_SAND_BALL, ACTION_FALLING, -1 + }, + { + O_DIRT_LOOSE, TRUE, + EL_BD_SAND_LOOSE, -1, -1 + }, + { + O_DIRT_LOOSE_F, FALSE, + EL_BD_SAND_LOOSE, ACTION_FALLING, -1 + }, + { + O_DIRT2, TRUE, + EL_BD_SAND_2, -1, -1 + }, + { + O_BRICK, TRUE, + EL_BD_WALL, -1, -1 + }, + { + O_BRICK_SLOPED_UP_RIGHT, TRUE, + EL_BD_WALL_SLOPED_UP_RIGHT, -1, -1 + }, + { + O_BRICK_SLOPED_UP_LEFT, TRUE, + EL_BD_WALL_SLOPED_UP_LEFT, -1, -1 + }, + { + O_BRICK_SLOPED_DOWN_LEFT, TRUE, + EL_BD_WALL_SLOPED_DOWN_LEFT, -1, -1 + }, + { + O_BRICK_SLOPED_DOWN_RIGHT, TRUE, + EL_BD_WALL_SLOPED_DOWN_RIGHT, -1, -1 + }, + { + O_BRICK_NON_SLOPED, TRUE, + EL_BD_WALL_NON_SLOPED, -1, -1 + }, + { + O_MAGIC_WALL, TRUE, + EL_BD_MAGIC_WALL, ACTION_ACTIVE, -1 + }, + { + O_PRE_OUTBOX, TRUE, + EL_BD_EXIT_CLOSED, -1, -1 + }, + { + O_OUTBOX, TRUE, + EL_BD_EXIT_OPEN, -1, -1 + }, + { + O_PRE_INVIS_OUTBOX, TRUE, + EL_BD_INVISIBLE_EXIT_CLOSED, -1, -1 + }, + { + O_INVIS_OUTBOX, TRUE, + EL_BD_INVISIBLE_EXIT_OPEN, -1, -1 + }, + { + O_STEEL, TRUE, + EL_BD_STEELWALL, -1, -1 + }, + { + O_STEEL_SLOPED_UP_RIGHT, TRUE, + EL_BD_STEELWALL_SLOPED_UP_RIGHT, -1, -1 + }, + { + O_STEEL_SLOPED_UP_LEFT, TRUE, + EL_BD_STEELWALL_SLOPED_UP_LEFT, -1, -1 + }, + { + O_STEEL_SLOPED_DOWN_LEFT, TRUE, + EL_BD_STEELWALL_SLOPED_DOWN_LEFT, -1, -1 + }, + { + O_STEEL_SLOPED_DOWN_RIGHT, TRUE, + EL_BD_STEELWALL_SLOPED_DOWN_RIGHT, -1, -1 + }, + { + O_STEEL_EXPLODABLE, TRUE, + EL_BD_STEELWALL_EXPLODABLE, -1, -1 + }, + { + O_STEEL_EATABLE, TRUE, + EL_BD_STEELWALL_DIGGABLE, -1, -1 + }, + { + O_BRICK_EATABLE, TRUE, + EL_BD_WALL_DIGGABLE, -1, -1 + }, + { + O_STONE, TRUE, + EL_BD_ROCK, -1, -1 + }, + { + O_STONE_F, FALSE, + EL_BD_ROCK, ACTION_FALLING, -1 + }, + { + O_FLYING_STONE, TRUE, + EL_BD_FLYING_ROCK, -1, -1 + }, + { + O_FLYING_STONE_F, FALSE, + EL_BD_FLYING_ROCK, ACTION_FALLING, -1 + }, + { + O_MEGA_STONE, TRUE, + EL_BD_MEGA_ROCK, -1, -1 + }, + { + O_MEGA_STONE_F, FALSE, + EL_BD_MEGA_ROCK, ACTION_FALLING, -1 + }, + { + O_DIAMOND, TRUE, + EL_BD_DIAMOND, -1, -1 + }, + { + O_DIAMOND_F, FALSE, + EL_BD_DIAMOND, ACTION_FALLING, -1 + }, + { + O_FLYING_DIAMOND, TRUE, + EL_BD_FLYING_DIAMOND, -1, -1 + }, + { + O_FLYING_DIAMOND_F, FALSE, + EL_BD_FLYING_DIAMOND, ACTION_FALLING, -1 + }, + { + O_NUT, TRUE, + EL_BD_NUT, -1, -1 + }, + { + O_NUT_F, FALSE, + EL_BD_NUT, ACTION_FALLING, -1 + }, + { + O_BLADDER_SPENDER, TRUE, + EL_BD_BLADDER_SPENDER, -1, -1 + }, + { + O_INBOX, TRUE, + EL_BD_INBOX, -1, -1 + }, + { + O_H_EXPANDING_WALL, TRUE, + EL_BD_EXPANDABLE_WALL_HORIZONTAL, -1, -1 + }, + { + O_V_EXPANDING_WALL, TRUE, + EL_BD_EXPANDABLE_WALL_VERTICAL, -1, -1 + }, + { + O_EXPANDING_WALL, TRUE, + EL_BD_EXPANDABLE_WALL_ANY, -1, -1 + }, + { + O_H_EXPANDING_STEEL_WALL, TRUE, + EL_BD_EXPANDABLE_STEELWALL_HORIZONTAL, -1, -1 + }, + { + O_V_EXPANDING_STEEL_WALL, TRUE, + EL_BD_EXPANDABLE_STEELWALL_VERTICAL, -1, -1 + }, + { + O_EXPANDING_STEEL_WALL, TRUE, + EL_BD_EXPANDABLE_STEELWALL_ANY, -1, -1 + }, + { + O_EXPANDING_WALL_SWITCH, TRUE, + EL_BD_EXPANDABLE_WALL_SWITCH_HORIZONTAL, -1, -1 + }, + { + O_CREATURE_SWITCH, TRUE, + EL_BD_CREATURE_SWITCH, -1, -1 + }, + { + O_BITER_SWITCH, TRUE, + EL_BD_BITER_SWITCH_1, -1, -1 + }, + { + O_REPLICATOR_SWITCH, TRUE, + EL_BD_REPLICATOR_SWITCH, -1, -1 + }, + { + O_CONVEYOR_SWITCH, TRUE, + EL_BD_CONVEYOR_SWITCH, -1, -1 + }, + { + O_CONVEYOR_DIR_SWITCH, TRUE, + EL_BD_CONVEYOR_DIR_SWITCH_RIGHT, -1, -1 + }, + { + O_ACID, TRUE, + EL_BD_ACID, -1, -1 + }, + { + O_FALLING_WALL, TRUE, + EL_BD_FALLING_WALL, -1, -1 + }, + { + O_FALLING_WALL_F, FALSE, + EL_BD_FALLING_WALL, ACTION_FALLING, -1 + }, + { + O_BOX, TRUE, + EL_BD_BOX, -1, -1 + }, + { + O_TIME_PENALTY, TRUE, + EL_BD_TIME_PENALTY, -1, -1 + }, + { + O_GRAVESTONE, TRUE, + EL_BD_GRAVESTONE, -1, -1 + }, + { + O_STONE_GLUED, TRUE, + EL_BD_ROCK_GLUED, -1, -1 + }, + { + O_DIAMOND_GLUED, TRUE, + EL_BD_DIAMOND_GLUED, -1, -1 + }, + { + O_DIAMOND_KEY, TRUE, + EL_BD_DIAMOND_KEY, -1, -1 + }, + { + O_TRAPPED_DIAMOND, TRUE, + EL_BD_TRAPPED_DIAMOND, -1, -1 + }, + { + O_CLOCK, TRUE, + EL_BD_CLOCK, -1, -1 + }, + { + O_DIRT_GLUED, TRUE, + EL_BD_SAND_GLUED, -1, -1 + }, + { + O_KEY_1, TRUE, + EL_BD_KEY_1, -1, -1 + }, + { + O_KEY_2, TRUE, + EL_BD_KEY_2, -1, -1 + }, + { + O_KEY_3, TRUE, + EL_BD_KEY_3, -1, -1 + }, + { + O_DOOR_1, TRUE, + EL_BD_GATE_1, -1, -1 + }, + { + O_DOOR_2, TRUE, + EL_BD_GATE_2, -1, -1 + }, + { + O_DOOR_3, TRUE, + EL_BD_GATE_3, -1, -1 + }, + { + O_POT, TRUE, + EL_BD_POT, -1, -1 + }, + { + O_GRAVITY_SWITCH, TRUE, + EL_BD_GRAVITY_SWITCH, -1, -1 + }, + { + O_PNEUMATIC_HAMMER, TRUE, + EL_BD_PNEUMATIC_HAMMER, -1, -1 + }, + { + O_TELEPORTER, TRUE, + EL_BD_TELEPORTER, -1, -1 + }, + { + O_SKELETON, TRUE, + EL_BD_SKELETON, -1, -1 + }, + { + O_WATER, TRUE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_1, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_2, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_3, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_4, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_5, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_6, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_7, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_8, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_9, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_10, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_11, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_12, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_13, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_14, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_15, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_WATER_16, FALSE, + EL_BD_WATER, -1, -1 + }, + { + O_COW_1, TRUE, + EL_BD_COW_LEFT, -1, -1 + }, + { + O_COW_2, TRUE, + EL_BD_COW_UP, -1, -1 + }, + { + O_COW_3, TRUE, + EL_BD_COW_RIGHT, -1, -1 + }, + { + O_COW_4, TRUE, + EL_BD_COW_DOWN, -1, -1 + }, + { + O_COW_ENCLOSED_1, FALSE, + EL_BD_COW_DOWN, -1, -1 + }, + { + O_COW_ENCLOSED_2, FALSE, + EL_BD_COW_DOWN, -1, -1 + }, + { + O_COW_ENCLOSED_3, FALSE, + EL_BD_COW_DOWN, -1, -1 + }, + { + O_COW_ENCLOSED_4, FALSE, + EL_BD_COW_DOWN, -1, -1 + }, + { + O_COW_ENCLOSED_5, FALSE, + EL_BD_COW_DOWN, -1, -1 + }, + { + O_COW_ENCLOSED_6, FALSE, + EL_BD_COW_DOWN, -1, -1 + }, + { + O_COW_ENCLOSED_7, FALSE, + EL_BD_COW_DOWN, -1, -1 + }, + { + O_WALLED_DIAMOND, TRUE, + EL_BD_WALL_DIAMOND, -1, -1 + }, + { + O_WALLED_KEY_1, TRUE, + EL_BD_WALL_KEY_1, -1, -1 + }, + { + O_WALLED_KEY_2, TRUE, + EL_BD_WALL_KEY_2, -1, -1 + }, + { + O_WALLED_KEY_3, TRUE, + EL_BD_WALL_KEY_3, -1, -1 + }, + { + O_AMOEBA, TRUE, + EL_BD_AMOEBA, -1, -1 + }, + { + O_AMOEBA_2, TRUE, + EL_BD_AMOEBA_2, -1, -1 + }, + { + O_REPLICATOR, TRUE, + EL_BD_REPLICATOR, -1, -1 + }, + { + O_CONVEYOR_LEFT, TRUE, + EL_BD_CONVEYOR_LEFT, -1, -1 + }, + { + O_CONVEYOR_RIGHT, TRUE, + EL_BD_CONVEYOR_RIGHT, -1, -1 + }, + { + O_LAVA, TRUE, + EL_BD_LAVA, -1, -1 + }, + { + O_SWEET, TRUE, + EL_BD_SWEET, -1, -1 + }, + { + O_VOODOO, TRUE, + EL_BD_VOODOO_DOLL, -1, -1 + }, + { + O_SLIME, TRUE, + EL_BD_SLIME, -1, -1 + }, + { + O_BLADDER, TRUE, + EL_BD_BLADDER, -1, -1 + }, + { + O_BLADDER_1, FALSE, + EL_BD_BLADDER, -1, -1 + }, + { + O_BLADDER_2, FALSE, + EL_BD_BLADDER, -1, -1 + }, + { + O_BLADDER_3, FALSE, + EL_BD_BLADDER, -1, -1 + }, + { + O_BLADDER_4, FALSE, + EL_BD_BLADDER, -1, -1 + }, + { + O_BLADDER_5, FALSE, + EL_BD_BLADDER, -1, -1 + }, + { + O_BLADDER_6, FALSE, + EL_BD_BLADDER, -1, -1 + }, + { + O_BLADDER_7, FALSE, + EL_BD_BLADDER, -1, -1 + }, + { + O_BLADDER_8, FALSE, + EL_BD_BLADDER, -1, -1 + }, + { + O_WAITING_STONE, TRUE, + EL_BD_WAITING_ROCK, -1, -1 + }, + { + O_CHASING_STONE, TRUE, + EL_BD_CHASING_ROCK, -1, -1 + }, + { + O_GHOST, TRUE, + EL_BD_GHOST, -1, -1 + }, + { + O_FIREFLY_1, TRUE, + EL_BD_FIREFLY_LEFT, -1, -1 + }, + { + O_FIREFLY_2, TRUE, + EL_BD_FIREFLY_UP, -1, -1 + }, + { + O_FIREFLY_3, TRUE, + EL_BD_FIREFLY_RIGHT, -1, -1 + }, + { + O_FIREFLY_4, TRUE, + EL_BD_FIREFLY_DOWN, -1, -1 + }, + { + O_ALT_FIREFLY_1, TRUE, + EL_BD_FIREFLY_2_LEFT, -1, -1 + }, + { + O_ALT_FIREFLY_2, TRUE, + EL_BD_FIREFLY_2_UP, -1, -1 + }, + { + O_ALT_FIREFLY_3, TRUE, + EL_BD_FIREFLY_2_RIGHT, -1, -1 + }, + { + O_ALT_FIREFLY_4, TRUE, + EL_BD_FIREFLY_2_DOWN, -1, -1 + }, + { + O_BUTTER_1, TRUE, + EL_BD_BUTTERFLY_LEFT, -1, -1 + }, + { + O_BUTTER_2, TRUE, + EL_BD_BUTTERFLY_UP, -1, -1 + }, + { + O_BUTTER_3, TRUE, + EL_BD_BUTTERFLY_RIGHT, -1, -1 + }, + { + O_BUTTER_4, TRUE, + EL_BD_BUTTERFLY_DOWN, -1, -1 + }, + { + O_ALT_BUTTER_1, TRUE, + EL_BD_BUTTERFLY_2_LEFT, -1, -1 + }, + { + O_ALT_BUTTER_2, TRUE, + EL_BD_BUTTERFLY_2_UP, -1, -1 + }, + { + O_ALT_BUTTER_3, TRUE, + EL_BD_BUTTERFLY_2_RIGHT, -1, -1 + }, + { + O_ALT_BUTTER_4, TRUE, + EL_BD_BUTTERFLY_2_DOWN, -1, -1 + }, + { + O_STONEFLY_1, TRUE, + EL_BD_STONEFLY_LEFT, -1, -1 + }, + { + O_STONEFLY_2, TRUE, + EL_BD_STONEFLY_UP, -1, -1 + }, + { + O_STONEFLY_3, TRUE, + EL_BD_STONEFLY_RIGHT, -1, -1 + }, + { + O_STONEFLY_4, TRUE, + EL_BD_STONEFLY_DOWN, -1, -1 + }, + { + O_BITER_1, TRUE, + EL_BD_BITER_UP, -1, -1 + }, + { + O_BITER_2, TRUE, + EL_BD_BITER_RIGHT, -1, -1 + }, + { + O_BITER_3, TRUE, + EL_BD_BITER_DOWN, -1, -1 + }, + { + O_BITER_4, TRUE, + EL_BD_BITER_LEFT, -1, -1 + }, + { + O_DRAGONFLY_1, TRUE, + EL_BD_DRAGONFLY_LEFT, -1, -1 + }, + { + O_DRAGONFLY_2, TRUE, + EL_BD_DRAGONFLY_UP, -1, -1 + }, + { + O_DRAGONFLY_3, TRUE, + EL_BD_DRAGONFLY_RIGHT, -1, -1 + }, + { + O_DRAGONFLY_4, TRUE, + EL_BD_DRAGONFLY_DOWN, -1, -1 + }, + { + O_PRE_PL_1, FALSE, + EL_BD_PLAYER, ACTION_GROWING, -1 + }, + { + O_PRE_PL_2, FALSE, + EL_BD_PLAYER, ACTION_GROWING, -1 + }, + { + O_PRE_PL_3, FALSE, + EL_BD_PLAYER, ACTION_GROWING, -1 + }, + { + O_PLAYER, TRUE, + EL_BD_PLAYER, -1, -1 + }, + { + O_PLAYER_BOMB, TRUE, + EL_BD_PLAYER_WITH_BOMB, -1, -1 + }, + { + O_PLAYER_GLUED, TRUE, + EL_BD_PLAYER_GLUED, -1, -1 + }, + { + O_PLAYER_STIRRING, TRUE, + EL_BD_PLAYER_STIRRING, -1, -1 + }, + { + O_BOMB, TRUE, + EL_BD_BOMB, -1, -1 + }, + { + O_BOMB_TICK_1, FALSE, + EL_BD_BOMB, ACTION_ACTIVE, -1 + }, + { + O_BOMB_TICK_2, FALSE, + EL_BD_BOMB, ACTION_ACTIVE, -1 + }, + { + O_BOMB_TICK_3, FALSE, + EL_BD_BOMB, ACTION_ACTIVE, -1 + }, + { + O_BOMB_TICK_4, FALSE, + EL_BD_BOMB, ACTION_ACTIVE, -1 + }, + { + O_BOMB_TICK_5, FALSE, + EL_BD_BOMB, ACTION_ACTIVE, -1 + }, + { + O_BOMB_TICK_6, FALSE, + EL_BD_BOMB, ACTION_ACTIVE, -1 + }, + { + O_BOMB_TICK_7, FALSE, + EL_BD_BOMB, ACTION_ACTIVE, -1 + }, + { + O_NITRO_PACK, TRUE, + EL_BD_NITRO_PACK, -1, -1 + }, + { + O_NITRO_PACK_F, FALSE, + EL_BD_NITRO_PACK, ACTION_FALLING, -1 + }, + { + O_NITRO_PACK_EXPLODE, FALSE, + EL_BD_NITRO_PACK, ACTION_EXPLODING, -1 + }, + { + O_PRE_CLOCK_1, FALSE, + EL_BD_CLOCK, ACTION_GROWING, -1 + }, + { + O_PRE_CLOCK_2, FALSE, + EL_BD_CLOCK, ACTION_GROWING, -1 + }, + { + O_PRE_CLOCK_3, FALSE, + EL_BD_CLOCK, ACTION_GROWING, -1 + }, + { + O_PRE_CLOCK_4, FALSE, + EL_BD_CLOCK, ACTION_GROWING, -1 + }, + { + O_PRE_DIA_1, FALSE, + EL_BD_DIAMOND, ACTION_GROWING, -1 + }, + { + O_PRE_DIA_2, FALSE, + EL_BD_DIAMOND, ACTION_GROWING, -1 + }, + { + O_PRE_DIA_3, FALSE, + EL_BD_DIAMOND, ACTION_GROWING, -1 + }, + { + O_PRE_DIA_4, FALSE, + EL_BD_DIAMOND, ACTION_GROWING, -1 + }, + { + O_PRE_DIA_5, FALSE, + EL_BD_DIAMOND, ACTION_GROWING, -1 + }, + { + O_EXPLODE_1, FALSE, + EL_DEFAULT, ACTION_EXPLODING, -1 + }, + { + O_EXPLODE_2, FALSE, + EL_DEFAULT, ACTION_EXPLODING, -1 + }, + { + O_EXPLODE_3, FALSE, + EL_DEFAULT, ACTION_EXPLODING, -1 + }, + { + O_EXPLODE_4, FALSE, + EL_DEFAULT, ACTION_EXPLODING, -1 + }, + { + O_EXPLODE_5, FALSE, + EL_DEFAULT, ACTION_EXPLODING, -1 + }, + { + O_PRE_STONE_1, FALSE, + EL_BD_ROCK, ACTION_GROWING, -1 + }, + { + O_PRE_STONE_2, FALSE, + EL_BD_ROCK, ACTION_GROWING, -1 + }, + { + O_PRE_STONE_3, FALSE, + EL_BD_ROCK, ACTION_GROWING, -1 + }, + { + O_PRE_STONE_4, FALSE, + EL_BD_ROCK, ACTION_GROWING, -1 + }, + { + O_PRE_STEEL_1, FALSE, + EL_BD_STEELWALL, ACTION_GROWING, -1 + }, + { + O_PRE_STEEL_2, FALSE, + EL_BD_STEELWALL, ACTION_GROWING, -1 + }, + { + O_PRE_STEEL_3, FALSE, + EL_BD_STEELWALL, ACTION_GROWING, -1 + }, + { + O_PRE_STEEL_4, FALSE, + EL_BD_STEELWALL, ACTION_GROWING, -1 + }, + { + O_GHOST_EXPL_1, FALSE, + EL_BD_GHOST, ACTION_EXPLODING, -1 + }, + { + O_GHOST_EXPL_2, FALSE, + EL_BD_GHOST, ACTION_EXPLODING, -1 + }, + { + O_GHOST_EXPL_3, FALSE, + EL_BD_GHOST, ACTION_EXPLODING, -1 + }, + { + O_GHOST_EXPL_4, FALSE, + EL_BD_GHOST, ACTION_EXPLODING, -1 + }, + { + O_BOMB_EXPL_1, FALSE, + EL_BD_BOMB, ACTION_EXPLODING, -1 + }, + { + O_BOMB_EXPL_2, FALSE, + EL_BD_BOMB, ACTION_EXPLODING, -1 + }, + { + O_BOMB_EXPL_3, FALSE, + EL_BD_BOMB, ACTION_EXPLODING, -1 + }, + { + O_BOMB_EXPL_4, FALSE, + EL_BD_BOMB, ACTION_EXPLODING, -1 + }, + { + O_NITRO_EXPL_1, FALSE, + EL_BD_NITRO_PACK, ACTION_EXPLODING, -1 + }, + { + O_NITRO_EXPL_2, FALSE, + EL_BD_NITRO_PACK, ACTION_EXPLODING, -1 + }, + { + O_NITRO_EXPL_3, FALSE, + EL_BD_NITRO_PACK, ACTION_EXPLODING, -1 + }, + { + O_NITRO_EXPL_4, FALSE, + EL_BD_NITRO_PACK, ACTION_EXPLODING, -1 + }, + { + O_AMOEBA_2_EXPL_1, FALSE, + EL_BD_AMOEBA_2, ACTION_EXPLODING, -1 + }, + { + O_AMOEBA_2_EXPL_2, FALSE, + EL_BD_AMOEBA_2, ACTION_EXPLODING, -1 + }, + { + O_AMOEBA_2_EXPL_3, FALSE, + EL_BD_AMOEBA_2, ACTION_EXPLODING, -1 + }, + { + O_AMOEBA_2_EXPL_4, FALSE, + EL_BD_AMOEBA_2, ACTION_EXPLODING, -1 + }, + { + O_NUT_EXPL_1, FALSE, + EL_BD_NUT, ACTION_BREAKING, -1 + }, + { + O_NUT_EXPL_2, FALSE, + EL_BD_NUT, ACTION_BREAKING, -1 + }, + { + O_NUT_EXPL_3, FALSE, + EL_BD_NUT, ACTION_BREAKING, -1 + }, + { + O_NUT_EXPL_4, FALSE, + EL_BD_NUT, ACTION_BREAKING, -1 + }, + { + O_PLAYER_PNEUMATIC_LEFT, FALSE, + EL_BD_PLAYER, ACTION_HITTING, MV_BIT_LEFT + }, + { + O_PLAYER_PNEUMATIC_RIGHT, FALSE, + EL_BD_PLAYER, ACTION_HITTING, MV_BIT_RIGHT + }, + { + O_PNEUMATIC_ACTIVE_LEFT, TRUE, + EL_BD_PNEUMATIC_HAMMER, ACTION_HITTING, MV_BIT_LEFT + }, + { + O_PNEUMATIC_ACTIVE_RIGHT, TRUE, + EL_BD_PNEUMATIC_HAMMER, ACTION_HITTING, MV_BIT_RIGHT + }, + + // helper (runtime) elements + + { + O_FAKE_BONUS, FALSE, + EL_BD_FAKE_BONUS, -1, -1 + }, + { + O_INBOX_CLOSED, FALSE, + EL_BD_INBOX, -1, -1 + }, + { + O_INBOX_OPEN, FALSE, + EL_BD_INBOX, ACTION_OPENING, -1 + }, + { + O_OUTBOX_CLOSED, FALSE, + EL_BD_EXIT_CLOSED, -1, -1 + }, + { + O_OUTBOX_OPEN, FALSE, + EL_BD_EXIT_OPEN, -1, -1 + }, + { + O_COVERED, FALSE, + EL_BD_COVERED, -1, -1 + }, + { + O_PLAYER_LEFT, FALSE, + EL_BD_PLAYER, ACTION_MOVING, MV_BIT_LEFT + }, + { + O_PLAYER_RIGHT, FALSE, + EL_BD_PLAYER, ACTION_MOVING, MV_BIT_RIGHT + }, + { + O_PLAYER_BLINK, FALSE, + EL_BD_PLAYER, ACTION_BORING_1, -1 + }, + { + O_PLAYER_TAP, FALSE, + EL_BD_PLAYER, ACTION_BORING_2, -1 + }, + { + O_PLAYER_TAP_BLINK, FALSE, + EL_BD_PLAYER, ACTION_BORING_3, -1 + }, + { + O_CREATURE_SWITCH_ON, FALSE, + EL_BD_CREATURE_SWITCH_ACTIVE, -1, -1 + }, + { + O_EXPANDING_WALL_SWITCH_HORIZ, FALSE, + EL_BD_EXPANDABLE_WALL_SWITCH_HORIZONTAL, -1, -1 + }, + { + O_EXPANDING_WALL_SWITCH_VERT, FALSE, + EL_BD_EXPANDABLE_WALL_SWITCH_VERTICAL, -1, -1 + }, + { + O_GRAVITY_SWITCH_ACTIVE, FALSE, + EL_BD_GRAVITY_SWITCH_ACTIVE, -1, -1 + }, + { + O_REPLICATOR_SWITCH_OFF, FALSE, + EL_BD_REPLICATOR_SWITCH, -1, -1 + }, + { + O_REPLICATOR_SWITCH_ON, FALSE, + EL_BD_REPLICATOR_SWITCH_ACTIVE, -1, -1 + }, + { + O_CONVEYOR_DIR_NORMAL, FALSE, + EL_BD_CONVEYOR_DIR_SWITCH_RIGHT, -1, -1 + }, + { + O_CONVEYOR_DIR_CHANGED, FALSE, + EL_BD_CONVEYOR_DIR_SWITCH_LEFT, -1, -1 + }, + { + O_CONVEYOR_SWITCH_OFF, FALSE, + EL_BD_CONVEYOR_SWITCH, -1, -1 + }, + { + O_CONVEYOR_SWITCH_ON, FALSE, + EL_BD_CONVEYOR_SWITCH_ACTIVE, -1, -1 + }, + { + O_MAGIC_WALL_ACTIVE, FALSE, + EL_BD_MAGIC_WALL_ACTIVE, -1, -1 + }, + { + O_REPLICATOR_ACTIVE, FALSE, + EL_BD_REPLICATOR_ACTIVE, -1, -1 + }, + { + O_CONVEYOR_LEFT_ACTIVE, FALSE, + EL_BD_CONVEYOR_LEFT_ACTIVE, -1, -1 + }, + { + O_CONVEYOR_RIGHT_ACTIVE, FALSE, + EL_BD_CONVEYOR_RIGHT_ACTIVE, -1, -1 + }, + { + O_BITER_SWITCH_1, FALSE, + EL_BD_BITER_SWITCH_1, -1, -1 + }, + { + O_BITER_SWITCH_2, FALSE, + EL_BD_BITER_SWITCH_2, -1, -1 + }, + { + O_BITER_SWITCH_3, FALSE, + EL_BD_BITER_SWITCH_3, -1, -1 + }, + { + O_BITER_SWITCH_4, FALSE, + EL_BD_BITER_SWITCH_4, -1, -1 + }, + + { + -1, FALSE, + -1, -1, -1 + } +}; + +int map_element_RND_to_BD(int element_rnd) +{ + static unsigned short mapping_RND_to_BD[NUM_FILE_ELEMENTS]; + static boolean mapping_initialized = FALSE; + + if (!mapping_initialized) + { + int i; + + // return "O_UNKNOWN" for all undefined elements in mapping array + for (i = 0; i < NUM_FILE_ELEMENTS; i++) + mapping_RND_to_BD[i] = O_UNKNOWN; + + for (i = 0; bd_object_mapping_list[i].element_bd != -1; i++) + if (bd_object_mapping_list[i].is_rnd_to_bd_mapping) + mapping_RND_to_BD[bd_object_mapping_list[i].element_rnd] = + bd_object_mapping_list[i].element_bd; + + mapping_initialized = TRUE; + } + + if (element_rnd < 0 || element_rnd >= NUM_FILE_ELEMENTS) + { + Warn("invalid RND element %d", element_rnd); + + return O_UNKNOWN; + } + + return mapping_RND_to_BD[element_rnd]; +} + +int map_element_BD_to_RND(int element_bd) +{ + static unsigned short mapping_BD_to_RND[O_MAX_ALL]; + static boolean mapping_initialized = FALSE; + + if (!mapping_initialized) + { + int i; + + // return "EL_UNKNOWN" for all undefined elements in mapping array + for (i = 0; i < O_MAX_ALL; i++) + mapping_BD_to_RND[i] = EL_UNKNOWN; + + for (i = 0; bd_object_mapping_list[i].element_bd != -1; i++) + mapping_BD_to_RND[bd_object_mapping_list[i].element_bd] = + bd_object_mapping_list[i].element_rnd; + + mapping_initialized = TRUE; + } + + if (element_bd < 0 || element_bd >= O_MAX_ALL) + { + Warn("invalid BD element %d", element_bd); + + return EL_UNKNOWN; + } + + return mapping_BD_to_RND[element_bd]; +} + static struct Mapping_EM_to_RND_object { int element_em; @@ -8570,14 +9688,14 @@ unsigned int InitRND(int seed) return InitEngineRandom_RND(seed); } -static struct Mapping_EM_to_RND_object object_mapping[GAME_TILE_MAX]; -static struct Mapping_EM_to_RND_player player_mapping[MAX_PLAYERS][PLY_MAX]; +static struct Mapping_EM_to_RND_object em_object_mapping[GAME_TILE_MAX]; +static struct Mapping_EM_to_RND_player em_player_mapping[MAX_PLAYERS][PLY_MAX]; static int get_effective_element_EM(int tile, int frame_em) { - int element = object_mapping[tile].element_rnd; - int action = object_mapping[tile].action; - boolean is_backside = object_mapping[tile].is_backside; + int element = em_object_mapping[tile].element_rnd; + int action = em_object_mapping[tile].action; + boolean is_backside = em_object_mapping[tile].is_backside; boolean action_removing = (action == ACTION_DIGGING || action == ACTION_SNAPPING || action == ACTION_COLLECTING); @@ -8725,8 +9843,8 @@ void ResetGfxAnimation_EM(int x, int y, int tile) void SetGfxAnimation_EM(struct GraphicInfo_EM *g_em, int tile, int frame_em, int x, int y) { - int action = object_mapping[tile].action; - int direction = object_mapping[tile].direction; + int action = em_object_mapping[tile].action; + int direction = em_object_mapping[tile].direction; int effective_element = get_effective_element_EM(tile, frame_em); int graphic = (direction == MV_NONE ? el_act2img(effective_element, action) : @@ -8765,11 +9883,11 @@ void SetGfxAnimation_EM(struct GraphicInfo_EM *g_em, } else if (action_moving) { - boolean is_backside = object_mapping[tile].is_backside; + boolean is_backside = em_object_mapping[tile].is_backside; if (is_backside) { - int direction = object_mapping[tile].direction; + int direction = em_object_mapping[tile].direction; int move_dir = (action_falling ? MV_DOWN : direction); GfxFrame[x][y]++; @@ -8824,9 +9942,9 @@ void SetGfxAnimation_EM(struct GraphicInfo_EM *g_em, void getGraphicSourceObjectExt_EM(struct GraphicInfo_EM *g_em, int tile, int frame_em, int x, int y) { - int action = object_mapping[tile].action; - int direction = object_mapping[tile].direction; - boolean is_backside = object_mapping[tile].is_backside; + int action = em_object_mapping[tile].action; + int direction = em_object_mapping[tile].direction; + boolean is_backside = em_object_mapping[tile].is_backside; int effective_element = get_effective_element_EM(tile, frame_em); int effective_action = action; int graphic = (direction == MV_NONE ? @@ -8890,9 +10008,9 @@ void getGraphicSourceObjectExt_EM(struct GraphicInfo_EM *g_em, void getGraphicSourcePlayerExt_EM(struct GraphicInfo_EM *g_em, int player_nr, int anim, int frame_em) { - int element = player_mapping[player_nr][anim].element_rnd; - int action = player_mapping[player_nr][anim].action; - int direction = player_mapping[player_nr][anim].direction; + int element = em_player_mapping[player_nr][anim].element_rnd; + int action = em_player_mapping[player_nr][anim].action; + int direction = em_player_mapping[player_nr][anim].direction; int graphic = (direction == MV_NONE ? el_act2img(element, action) : el_act_dir2img(element, action, direction)); @@ -8922,10 +10040,10 @@ void InitGraphicInfo_EM(void) // always start with reliable default values for (i = 0; i < GAME_TILE_MAX; i++) { - object_mapping[i].element_rnd = EL_UNKNOWN; - object_mapping[i].is_backside = FALSE; - object_mapping[i].action = ACTION_DEFAULT; - object_mapping[i].direction = MV_NONE; + em_object_mapping[i].element_rnd = EL_UNKNOWN; + em_object_mapping[i].is_backside = FALSE; + em_object_mapping[i].action = ACTION_DEFAULT; + em_object_mapping[i].direction = MV_NONE; } // always start with reliable default values @@ -8933,9 +10051,9 @@ void InitGraphicInfo_EM(void) { for (i = 0; i < PLY_MAX; i++) { - player_mapping[p][i].element_rnd = EL_UNKNOWN; - player_mapping[p][i].action = ACTION_DEFAULT; - player_mapping[p][i].direction = MV_NONE; + em_player_mapping[p][i].element_rnd = EL_UNKNOWN; + em_player_mapping[p][i].action = ACTION_DEFAULT; + em_player_mapping[p][i].direction = MV_NONE; } } @@ -8943,14 +10061,14 @@ void InitGraphicInfo_EM(void) { int e = em_object_mapping_list[i].element_em; - object_mapping[e].element_rnd = em_object_mapping_list[i].element_rnd; - object_mapping[e].is_backside = em_object_mapping_list[i].is_backside; + em_object_mapping[e].element_rnd = em_object_mapping_list[i].element_rnd; + em_object_mapping[e].is_backside = em_object_mapping_list[i].is_backside; if (em_object_mapping_list[i].action != -1) - object_mapping[e].action = em_object_mapping_list[i].action; + em_object_mapping[e].action = em_object_mapping_list[i].action; if (em_object_mapping_list[i].direction != -1) - object_mapping[e].direction = + em_object_mapping[e].direction = MV_DIR_FROM_BIT(em_object_mapping_list[i].direction); } @@ -8959,22 +10077,22 @@ void InitGraphicInfo_EM(void) int a = em_player_mapping_list[i].action_em; int p = em_player_mapping_list[i].player_nr; - player_mapping[p][a].element_rnd = em_player_mapping_list[i].element_rnd; + em_player_mapping[p][a].element_rnd = em_player_mapping_list[i].element_rnd; if (em_player_mapping_list[i].action != -1) - player_mapping[p][a].action = em_player_mapping_list[i].action; + em_player_mapping[p][a].action = em_player_mapping_list[i].action; if (em_player_mapping_list[i].direction != -1) - player_mapping[p][a].direction = + em_player_mapping[p][a].direction = MV_DIR_FROM_BIT(em_player_mapping_list[i].direction); } for (i = 0; i < GAME_TILE_MAX; i++) { - int element = object_mapping[i].element_rnd; - int action = object_mapping[i].action; - int direction = object_mapping[i].direction; - boolean is_backside = object_mapping[i].is_backside; + int element = em_object_mapping[i].element_rnd; + int action = em_object_mapping[i].action; + int direction = em_object_mapping[i].direction; + boolean is_backside = em_object_mapping[i].is_backside; boolean action_exploding = ((action == ACTION_EXPLODING || action == ACTION_SMASHED_BY_ROCK || action == ACTION_SMASHED_BY_SPRING) && @@ -9246,10 +10364,10 @@ void InitGraphicInfo_EM(void) { for (j = 0; j < 8; j++) { - int element = object_mapping[i].element_rnd; - int action = object_mapping[i].action; - int direction = object_mapping[i].direction; - boolean is_backside = object_mapping[i].is_backside; + int element = em_object_mapping[i].element_rnd; + int action = em_object_mapping[i].action; + int direction = em_object_mapping[i].direction; + boolean is_backside = em_object_mapping[i].is_backside; int graphic_action = el_act_dir2img(element, action, direction); int graphic_default = el_act_dir2img(element, ACTION_DEFAULT, direction); @@ -9289,9 +10407,9 @@ void InitGraphicInfo_EM(void) { for (i = 0; i < PLY_MAX; i++) { - int element = player_mapping[p][i].element_rnd; - int action = player_mapping[p][i].action; - int direction = player_mapping[p][i].direction; + int element = em_player_mapping[p][i].element_rnd; + int action = em_player_mapping[p][i].action; + int direction = em_player_mapping[p][i].direction; for (j = 0; j < 8; j++) {