X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Ftools.c;h=099fd59de0c007460883d811c59d2997624745d1;hp=f81ff9d90f210075e712ccb9fde88baba9ae558d;hb=b2c4f6e649f55c838726a81ac0cc913db1e55536;hpb=1f8fd7a79343ce670dc62fcb8be48ba78d0c9199 diff --git a/src/tools.c b/src/tools.c index f81ff9d9..099fd59d 100644 --- a/src/tools.c +++ b/src/tools.c @@ -4,7 +4,7 @@ // (c) 1995-2014 by Artsoft Entertainment // Holger Schemel // info@artsoft.org -// http://www.artsoft.org/ +// https://www.artsoft.org/ // ---------------------------------------------------------------------------- // tools.c // ============================================================================ @@ -23,11 +23,9 @@ #include "screens.h" -/* select level set with EMC X11 graphics before activating EM GFX debugging */ -#define DEBUG_EM_GFX FALSE #define DEBUG_FRAME_TIME FALSE -/* tool button identifiers */ +// tool button identifiers #define TOOL_CTRL_ID_YES 0 #define TOOL_CTRL_ID_NO 1 #define TOOL_CTRL_ID_CONFIRM 2 @@ -35,10 +33,13 @@ #define TOOL_CTRL_ID_PLAYER_2 4 #define TOOL_CTRL_ID_PLAYER_3 5 #define TOOL_CTRL_ID_PLAYER_4 6 +#define TOOL_CTRL_ID_TOUCH_YES 7 +#define TOOL_CTRL_ID_TOUCH_NO 8 +#define TOOL_CTRL_ID_TOUCH_CONFIRM 9 -#define NUM_TOOL_BUTTONS 7 +#define NUM_TOOL_BUTTONS 10 -/* constants for number of doors and door parts */ +// constants for number of doors and door parts #define NUM_DOORS 2 #define NUM_PANELS NUM_DOORS // #define NUM_PANELS 0 @@ -165,7 +166,7 @@ static struct DoorPartControlInfo door_part_controls[] = }; -/* forward declaration for internal use */ +// forward declaration for internal use static void UnmapToolButtons(void); static void HandleToolButtons(struct GadgetInfo *); static int el_act_dir2crm(int, int, int); @@ -192,34 +193,19 @@ static char *print_if_not_empty(int element) return s; } -int correctLevelPosX_EM(int lx) -{ - lx -= 1; - lx -= (BorderElement != EL_EMPTY ? 1 : 0); - - return lx; -} - -int correctLevelPosY_EM(int ly) -{ - ly -= 1; - ly -= (BorderElement != EL_EMPTY ? 1 : 0); - - return ly; -} - -static int getFieldbufferOffsetX_RND(void) +int getFieldbufferOffsetX_RND(int dir, int pos) { int full_lev_fieldx = lev_fieldx + (BorderElement != EL_EMPTY ? 2 : 0); - int dx = (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0); + int dx = (dir & MV_HORIZONTAL ? pos : 0); int dx_var = dx * TILESIZE_VAR / TILESIZE; int fx = FX; if (EVEN(SCR_FIELDX)) { - int ffx = (scroll_x - SBX_Left) * TILEX_VAR + dx_var; + int sbx_right = SBX_Right + (BorderElement != EL_EMPTY ? 1 : 0); + int ffx = (scroll_x - SBX_Left) * TILEX_VAR + dx_var; - if (ffx < SBX_Right * TILEX_VAR + TILEX_VAR / 2 + TILEX_VAR) + if (ffx < sbx_right * TILEX_VAR + TILEX_VAR / 2) fx += dx_var - MIN(ffx, TILEX_VAR / 2) + TILEX_VAR; else fx += (dx_var > 0 ? TILEX_VAR : 0); @@ -240,18 +226,19 @@ static int getFieldbufferOffsetX_RND(void) return fx; } -static int getFieldbufferOffsetY_RND(void) +int getFieldbufferOffsetY_RND(int dir, int pos) { int full_lev_fieldy = lev_fieldy + (BorderElement != EL_EMPTY ? 2 : 0); - int dy = (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0); + int dy = (dir & MV_VERTICAL ? pos : 0); int dy_var = dy * TILESIZE_VAR / TILESIZE; int fy = FY; if (EVEN(SCR_FIELDY)) { + int sby_lower = SBY_Lower + (BorderElement != EL_EMPTY ? 1 : 0); int ffy = (scroll_y - SBY_Upper) * TILEY_VAR + dy_var; - if (ffy < SBY_Lower * TILEY_VAR + TILEY_VAR / 2 + TILEY_VAR) + if (ffy < sby_lower * TILEY_VAR + TILEY_VAR / 2) fy += dy_var - MIN(ffy, TILEY_VAR / 2) + TILEY_VAR; else fy += (dy_var > 0 ? TILEY_VAR : 0); @@ -274,7 +261,7 @@ static int getFieldbufferOffsetY_RND(void) static int getLevelFromScreenX_RND(int sx) { - int fx = getFieldbufferOffsetX_RND(); + int fx = getFieldbufferOffsetX_RND(ScreenMovDir, ScreenGfxPos); int dx = fx - FX; int px = sx - SX; int lx = LEVELX((px + dx) / TILESIZE_VAR); @@ -284,7 +271,7 @@ static int getLevelFromScreenX_RND(int sx) static int getLevelFromScreenY_RND(int sy) { - int fy = getFieldbufferOffsetY_RND(); + int fy = getFieldbufferOffsetY_RND(ScreenMovDir, ScreenGfxPos); int dy = fy - FY; int py = sy - SY; int ly = LEVELY((py + dy) / TILESIZE_VAR); @@ -294,7 +281,7 @@ static int getLevelFromScreenY_RND(int sy) static int getLevelFromScreenX_EM(int sx) { - int level_xsize = level.native_em_level->lev->width; + int level_xsize = level.native_em_level->cav->width; int full_xsize = level_xsize * TILESIZE_VAR; sx -= (full_xsize < SXSIZE ? (SXSIZE - full_xsize) / 2 : 0); @@ -304,14 +291,12 @@ static int getLevelFromScreenX_EM(int sx) int px = sx - SX; int lx = LEVELX((px + dx) / TILESIZE_VAR); - lx = correctLevelPosX_EM(lx); - return lx; } static int getLevelFromScreenY_EM(int sy) { - int level_ysize = level.native_em_level->lev->height; + int level_ysize = level.native_em_level->cav->height; int full_ysize = level_ysize * TILESIZE_VAR; sy -= (full_ysize < SYSIZE ? (SYSIZE - full_ysize) / 2 : 0); @@ -321,8 +306,6 @@ static int getLevelFromScreenY_EM(int sy) int py = sy - SY; int ly = LEVELY((py + dy) / TILESIZE_VAR); - ly = correctLevelPosY_EM(ly); - return ly; } @@ -408,41 +391,51 @@ int getLevelFromScreenY(int y) return getLevelFromScreenY_RND(y); } +int getScreenFieldSizeX(void) +{ + return (tape.playing ? tape.scr_fieldx : SCR_FIELDX); +} + +int getScreenFieldSizeY(void) +{ + return (tape.playing ? tape.scr_fieldy : SCR_FIELDY); +} + void DumpTile(int x, int y) { int sx = SCREENX(x); int sy = SCREENY(y); char *token_name; - printf_line("-", 79); - printf("Field Info: SCREEN(%d, %d), LEVEL(%d, %d)\n", sx, sy, x, y); - printf_line("-", 79); + Info("---"); + Info("Field Info: SCREEN(%d, %d), LEVEL(%d, %d)", sx, sy, x, y); + Info("---"); if (!IN_LEV_FIELD(x, y)) { - printf("(not in level field)\n"); - printf("\n"); + Info("(not in level field)"); + Info(""); return; } - token_name = element_info[Feld[x][y]].token_name; + token_name = element_info[Tile[x][y]].token_name; - printf(" Feld: %d\t['%s']\n", Feld[x][y], token_name); - printf(" Back: %s\n", print_if_not_empty(Back[x][y])); - printf(" Store: %s\n", print_if_not_empty(Store[x][y])); - printf(" Store2: %s\n", print_if_not_empty(Store2[x][y])); - printf(" StorePlayer: %s\n", print_if_not_empty(StorePlayer[x][y])); - printf(" MovPos: %d\n", MovPos[x][y]); - printf(" MovDir: %d\n", MovDir[x][y]); - printf(" MovDelay: %d\n", MovDelay[x][y]); - printf(" ChangeDelay: %d\n", ChangeDelay[x][y]); - printf(" CustomValue: %d\n", CustomValue[x][y]); - printf(" GfxElement: %d\n", GfxElement[x][y]); - printf(" GfxAction: %d\n", GfxAction[x][y]); - printf(" GfxFrame: %d [%d]\n", GfxFrame[x][y], FrameCounter); - printf(" Player x/y: %d, %d\n", local_player->jx, local_player->jy); - printf("\n"); + Info("Tile: %d\t['%s']", Tile[x][y], token_name); + Info("Back: %s", print_if_not_empty(Back[x][y])); + Info("Store: %s", print_if_not_empty(Store[x][y])); + Info("Store2: %s", print_if_not_empty(Store2[x][y])); + Info("StorePlayer: %s", print_if_not_empty(StorePlayer[x][y])); + Info("MovPos: %d", MovPos[x][y]); + Info("MovDir: %d", MovDir[x][y]); + Info("MovDelay: %d", MovDelay[x][y]); + Info("ChangeDelay: %d", ChangeDelay[x][y]); + Info("CustomValue: %d", CustomValue[x][y]); + Info("GfxElement: %d", GfxElement[x][y]); + Info("GfxAction: %d", GfxAction[x][y]); + Info("GfxFrame: %d [%d]", GfxFrame[x][y], FrameCounter); + Info("Player x/y: %d, %d", local_player->jx, local_player->jy); + Info(""); } void DumpTileFromScreen(int sx, int sy) @@ -466,7 +459,7 @@ void SetDrawtoField(int mode) drawto_field = fieldbuffer; } - else /* DRAW_TO_BACKBUFFER */ + else // DRAW_TO_BACKBUFFER { FX = SX; FY = SY; @@ -479,6 +472,11 @@ void SetDrawtoField(int mode) } } +int GetDrawtoField(void) +{ + return (drawto_field == fieldbuffer ? DRAW_TO_FIELDBUFFER : DRAW_TO_BACKBUFFER); +} + static void RedrawPlayfield_RND(void) { if (game.envelope_active) @@ -559,7 +557,7 @@ static void DrawMaskedBorderExt_DOOR_2(int draw_target) static void DrawMaskedBorderExt_DOOR_3(int draw_target) { - /* currently not available */ + // currently not available } static void DrawMaskedBorderExt_ALL(int draw_target) @@ -572,7 +570,7 @@ static void DrawMaskedBorderExt_ALL(int draw_target) static void DrawMaskedBorderExt(int redraw_mask, int draw_target) { - /* never draw masked screen borders on borderless screens */ + // never draw masked screen borders on borderless screens if (global.border_status == GAME_MODE_LOADING || global.border_status == GAME_MODE_TITLE) return; @@ -633,68 +631,20 @@ void DrawMaskedBorderToTarget(int draw_target) void DrawTileCursor(int draw_target) { - Bitmap *fade_bitmap; - Bitmap *src_bitmap; - int src_x, src_y; - int dst_x, dst_y; - int graphic = IMG_GLOBAL_TILE_CURSOR; - int frame = 0; - int tilesize = TILESIZE_VAR; - int width = tilesize; - int height = tilesize; - - if (game_status != GAME_MODE_PLAYING) - return; - - if (!tile_cursor.enabled || - !tile_cursor.active) - return; - - if (tile_cursor.moving) - { - int step = TILESIZE_VAR / 4; - int dx = tile_cursor.target_x - tile_cursor.x; - int dy = tile_cursor.target_y - tile_cursor.y; - - if (ABS(dx) < step) - tile_cursor.x = tile_cursor.target_x; - else - tile_cursor.x += SIGN(dx) * step; - - if (ABS(dy) < step) - tile_cursor.y = tile_cursor.target_y; - else - tile_cursor.y += SIGN(dy) * step; - - if (tile_cursor.x == tile_cursor.target_x && - tile_cursor.y == tile_cursor.target_y) - tile_cursor.moving = FALSE; - } - - dst_x = tile_cursor.x; - dst_y = tile_cursor.y; - - frame = getGraphicAnimationFrame(graphic, -1); - - getSizedGraphicSource(graphic, frame, tilesize, &src_bitmap, &src_x, &src_y); - - fade_bitmap = - (draw_target == DRAW_TO_FADE_SOURCE ? gfx.fade_bitmap_source : - draw_target == DRAW_TO_FADE_TARGET ? gfx.fade_bitmap_target : NULL); + DrawTileCursor_MM(draw_target, game_status == GAME_MODE_PLAYING); +} - if (draw_target == DRAW_TO_SCREEN) - BlitToScreenMasked(src_bitmap, src_x, src_y, width, height, dst_x, dst_y); - else - BlitBitmapMasked(src_bitmap, fade_bitmap, src_x, src_y, width, height, - dst_x, dst_y); +void BlitScreenToBitmapExt_RND(Bitmap *target_bitmap, int fx, int fy) +{ + BlitBitmap(drawto_field, target_bitmap, fx, fy, SXSIZE, SYSIZE, SX, SY); } void BlitScreenToBitmap_RND(Bitmap *target_bitmap) { - int fx = getFieldbufferOffsetX_RND(); - int fy = getFieldbufferOffsetY_RND(); + int fx = getFieldbufferOffsetX_RND(ScreenMovDir, ScreenGfxPos); + int fy = getFieldbufferOffsetY_RND(ScreenMovDir, ScreenGfxPos); - BlitBitmap(drawto_field, target_bitmap, fx, fy, SXSIZE, SYSIZE, SX, SY); + BlitScreenToBitmapExt_RND(target_bitmap, fx, fy); } void BlitScreenToBitmap(Bitmap *target_bitmap) @@ -719,20 +669,20 @@ static void DrawFramesPerSecond(void) int draw_deactivation_mask = GetDrawDeactivationMask(); boolean draw_masked = (draw_deactivation_mask == REDRAW_NONE); - /* draw FPS with leading space (needed if field buffer deactivated) */ + // draw FPS with leading space (needed if field buffer deactivated) sprintf(text, " %04.1f fps", global.frames_per_second); - /* override draw deactivation mask (required for invisible warp mode) */ + // override draw deactivation mask (required for invisible warp mode) SetDrawDeactivationMask(REDRAW_NONE); - /* draw opaque FPS if field buffer deactivated, else draw masked FPS */ + // draw opaque FPS if field buffer deactivated, else draw masked FPS DrawTextExt(backbuffer, SX + SXSIZE - font_width * strlen(text), SY, text, font_nr, (draw_masked ? BLIT_MASKED : BLIT_OPAQUE)); - /* set draw deactivation mask to previous value */ + // set draw deactivation mask to previous value SetDrawDeactivationMask(draw_deactivation_mask); - /* force full-screen redraw in this frame */ + // force full-screen redraw in this frame redraw_mask = REDRAW_ALL; } @@ -764,7 +714,7 @@ static void PrintFrameTimeDebugging(void) diff_bar[pos++] = '\0'; - Error(ERR_INFO, "%06d [%02d] [%c%02d] %s", + Debug("time:frame", "%06d [%02d] [%c%02d] %s", counter, diff_1, (diff_2 < 0 ? '-' : diff_2 > 0 ? '+' : ' '), ABS(diff_2), @@ -906,7 +856,7 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type) { if (fade_type_skip != FADE_TYPE_NONE) { - /* skip all fade operations until specified fade operation */ + // skip all fade operations until specified fade operation if (fade_type & fade_type_skip) fade_type_skip = FADE_TYPE_NONE; @@ -931,7 +881,7 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type) if (fade_type_skip != FADE_TYPE_NONE) { - /* skip all fade operations until specified fade operation */ + // skip all fade operations until specified fade operation if (fade_type & fade_type_skip) fade_type_skip = FADE_TYPE_NONE; @@ -951,11 +901,11 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type) height = FADE_SYSIZE; if (border.draw_masked_when_fading) - draw_border_function = DrawMaskedBorder_FIELD; /* update when fading */ + draw_border_function = DrawMaskedBorder_FIELD; // update when fading else - DrawMaskedBorder_FIELD(); /* draw once */ + DrawMaskedBorder_FIELD(); // draw once } - else /* REDRAW_ALL */ + else // REDRAW_ALL { x = 0; y = 0; @@ -963,19 +913,13 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type) height = WIN_YSIZE; } - if (!setup.fade_screens || - fade_delay == 0 || - fading.fade_mode == FADE_MODE_NONE) - { - if (fade_mode == FADE_MODE_FADE_OUT) - return; - - BlitBitmap(backbuffer, window, x, y, width, height, x, y); - - redraw_mask &= ~fade_mask; + // when switching screens without fading, set fade delay to zero + if (!setup.fade_screens || fading.fade_mode == FADE_MODE_NONE) + fade_delay = 0; + // do not display black frame when fading out without fade delay + if (fade_mode == FADE_MODE_FADE_OUT && fade_delay == 0) return; - } FadeRectangle(x, y, width, height, fade_mode, fade_delay, post_delay, draw_border_function); @@ -991,8 +935,7 @@ static void SetScreenStates_BeforeFadingIn(void) global.anim_status = global.anim_status_next; // store backbuffer with all animations that will be started after fading in - if (fade_type_skip != FADE_MODE_SKIP_FADE_IN) - PrepareFadeBitmap(DRAW_TO_FADE_TARGET); + PrepareFadeBitmap(DRAW_TO_FADE_TARGET); // set screen mode for animations back to fading global.anim_status = GAME_MODE_PSEUDO_FADING; @@ -1015,8 +958,7 @@ static void SetScreenStates_BeforeFadingOut(void) global.anim_status = GAME_MODE_PSEUDO_FADING; // store backbuffer with all animations that will be stopped for fading out - if (fade_type_skip != FADE_MODE_SKIP_FADE_OUT) - PrepareFadeBitmap(DRAW_TO_FADE_SOURCE); + PrepareFadeBitmap(DRAW_TO_FADE_SOURCE); } static void SetScreenStates_AfterFadingOut(void) @@ -1042,8 +984,9 @@ void FadeIn(int fade_mask) FADE_SXSIZE = FULL_SXSIZE; FADE_SYSIZE = FULL_SYSIZE; - if (game_status == GAME_MODE_PLAYING && - strEqual(setup.touch.control_type, TOUCH_CONTROL_VIRTUAL_BUTTONS)) + // activate virtual buttons depending on upcoming game status + if (strEqual(setup.touch.control_type, TOUCH_CONTROL_VIRTUAL_BUTTONS) && + game_status == GAME_MODE_PLAYING && !tape.playing) SetOverlayActive(TRUE); SetScreenStates_AfterFadingIn(); @@ -1056,7 +999,8 @@ void FadeIn(int fade_mask) void FadeOut(int fade_mask) { // update screen if areas covered by "fade_mask" and "redraw_mask" differ - if (!equalRedrawMasks(fade_mask, redraw_mask)) + if (!equalRedrawMasks(fade_mask, redraw_mask) && + fade_type_skip != FADE_MODE_SKIP_FADE_OUT) BackToFront(); SetScreenStates_BeforeFadingOut(); @@ -1090,21 +1034,21 @@ void FadeSetEnterMenu(void) { fading = menu.enter_menu; - FadeSetLeaveNext(fading, TRUE); /* (keep same fade mode) */ + FadeSetLeaveNext(fading, TRUE); // (keep same fade mode) } void FadeSetLeaveMenu(void) { fading = menu.leave_menu; - FadeSetLeaveNext(fading, TRUE); /* (keep same fade mode) */ + FadeSetLeaveNext(fading, TRUE); // (keep same fade mode) } void FadeSetEnterScreen(void) { fading = menu.enter_screen[game_status]; - FadeSetLeaveNext(menu.leave_screen[game_status], TRUE); /* store */ + FadeSetLeaveNext(menu.leave_screen[game_status], TRUE); // store } void FadeSetNextScreen(void) @@ -1112,12 +1056,12 @@ void FadeSetNextScreen(void) fading = menu.next_screen[game_status]; // (do not overwrite fade mode set by FadeSetEnterScreen) - // FadeSetLeaveNext(fading, TRUE); /* (keep same fade mode) */ + // FadeSetLeaveNext(fading, TRUE); // (keep same fade mode) } void FadeSetLeaveScreen(void) { - FadeSetLeaveNext(menu.leave_screen[game_status], FALSE); /* recall */ + FadeSetLeaveNext(menu.leave_screen[game_status], FALSE); // recall } void FadeSetFromType(int type) @@ -1149,10 +1093,12 @@ void FadeSkipNextFadeOut(void) static Bitmap *getBitmapFromGraphicOrDefault(int graphic, int default_graphic) { + if (graphic == IMG_UNDEFINED) + return NULL; + boolean redefined = getImageListEntryFromImageID(graphic)->redefined; - return (graphic == IMG_UNDEFINED ? NULL : - graphic_info[graphic].bitmap != NULL || redefined ? + return (graphic_info[graphic].bitmap != NULL || redefined ? graphic_info[graphic].bitmap : graphic_info[default_graphic].bitmap); } @@ -1225,7 +1171,7 @@ void SetPanelBackground(void) void DrawBackground(int x, int y, int width, int height) { - /* "drawto" might still point to playfield buffer here (hall of fame) */ + // "drawto" might still point to playfield buffer here (hall of fame) ClearRectangleOnBackground(backbuffer, x, y, width, height); if (IN_GFX_FIELD_FULL(x, y)) @@ -1353,6 +1299,9 @@ static void RedrawGlobalBorderIfNeeded(void) #if ONLY_REDRAW_GLOBAL_BORDER_IF_NEEDED if (CheckIfGlobalBorderRedrawIsNeeded()) +#else + // determine and store new global border bitmap for current game status + global_border_bitmap = getGlobalBorderBitmapFromStatus(game_status); #endif { // redraw global screen border (or clear, if defined to be empty) @@ -1423,11 +1372,11 @@ void ClearField(void) { RedrawGlobalBorderIfNeeded(); - /* !!! "drawto" might still point to playfield buffer here (see above) !!! */ - /* (when entering hall of fame after playing) */ + // !!! "drawto" might still point to playfield buffer here (see above) !!! + // (when entering hall of fame after playing) DrawBackground(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); - /* !!! maybe this should be done before clearing the background !!! */ + // !!! maybe this should be done before clearing the background !!! if (game_status == GAME_MODE_PLAYING) { ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE); @@ -1450,15 +1399,15 @@ void SetBorderElement(void) BorderElement = EL_EMPTY; - /* the MM game engine does not use a visible border element */ - if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + // only the R'n'D game engine may use an additional steelwall border + if (level.game_engine_type != GAME_ENGINE_TYPE_RND) return; for (y = 0; y < lev_fieldy && BorderElement == EL_EMPTY; y++) { for (x = 0; x < lev_fieldx; x++) { - if (!IS_INDESTRUCTIBLE(Feld[x][y])) + if (!IS_INDESTRUCTIBLE(Tile[x][y])) BorderElement = EL_STEELWALL; if (y != 0 && y != lev_fieldy - 1 && x != lev_fieldx - 1) @@ -1477,14 +1426,14 @@ void FloodFillLevelExt(int from_x, int from_y, int fill_element, static int check[4][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } }; static int safety = 0; - /* check if starting field still has the desired content */ + // check if starting field still has the desired content if (field[from_x][from_y] == fill_element) return; safety++; if (safety > max_fieldx * max_fieldy) - Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug."); + Fail("Something went wrong in 'FloodFill()'. Please debug."); old_element = field[from_x][from_y]; field[from_x][from_y] = fill_element; @@ -1518,7 +1467,7 @@ void SetRandomAnimationValue(int x, int y) int getGraphicAnimationFrame(int graphic, int sync_frame) { - /* animation synchronized with global frame counter, not move position */ + // animation synchronized with global frame counter, not move position if (graphic_info[graphic].anim_global_sync || sync_frame < 0) sync_frame = FrameCounter; @@ -1549,7 +1498,7 @@ void getGraphicSourceXY(int graphic, int frame, int *x, int *y, int src_x = g->src_x + (get_backside ? g->offset2_x : 0); int src_y = g->src_y + (get_backside ? g->offset2_y : 0); - if (g->offset_y == 0) /* frames are ordered horizontally */ + if (g->offset_y == 0) // frames are ordered horizontally { int max_width = g->anim_frames_per_line * g->width; int pos = (src_y / g->height) * max_width + src_x + frame * g->offset_x; @@ -1557,7 +1506,7 @@ void getGraphicSourceXY(int graphic, int frame, int *x, int *y, *x = pos % max_width; *y = src_y % g->height + pos / max_width * g->height; } - else if (g->offset_x == 0) /* frames are ordered vertically */ + else if (g->offset_x == 0) // frames are ordered vertically { int max_height = g->anim_frames_per_line * g->height; int pos = (src_x / g->width) * max_height + src_y + frame * g->offset_y; @@ -1565,7 +1514,7 @@ void getGraphicSourceXY(int graphic, int frame, int *x, int *y, *x = src_x % g->width + pos / max_height * g->width; *y = pos % max_height; } - else /* frames are ordered diagonally */ + else // frames are ordered diagonally { *x = src_x + frame * g->offset_x; *y = src_y + frame * g->offset_y; @@ -1627,8 +1576,9 @@ void DrawGraphic(int x, int y, int graphic, int frame) #if DEBUG if (!IN_SCR_FIELD(x, y)) { - printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n", x, y, graphic); - printf("DrawGraphic(): This should never happen!\n"); + Debug("draw:DrawGraphic", "x = %d, y = %d, graphic = %d", x, y, graphic); + Debug("draw:DrawGraphic", "This should never happen!"); + return; } #endif @@ -1644,8 +1594,10 @@ void DrawFixedGraphic(int x, int y, int graphic, int frame) #if DEBUG if (!IN_SCR_FIELD(x, y)) { - printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n", x, y, graphic); - printf("DrawGraphic(): This should never happen!\n"); + Debug("draw:DrawFixedGraphic", "x = %d, y = %d, graphic = %d", + x, y, graphic); + Debug("draw:DrawFixedGraphic", "This should never happen!"); + return; } #endif @@ -1681,8 +1633,10 @@ void DrawGraphicThruMask(int x, int y, int graphic, int frame) #if DEBUG if (!IN_SCR_FIELD(x, y)) { - printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic); - printf("DrawGraphicThruMask(): This should never happen!\n"); + Debug("draw:DrawGraphicThruMask", "x = %d,y = %d, graphic = %d", + x, y, graphic); + Debug("draw:DrawGraphicThruMask", "This should never happen!"); + return; } #endif @@ -1698,8 +1652,10 @@ void DrawFixedGraphicThruMask(int x, int y, int graphic, int frame) #if DEBUG if (!IN_SCR_FIELD(x, y)) { - printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic); - printf("DrawGraphicThruMask(): This should never happen!\n"); + Debug("draw:DrawFixedGraphicThruMask", "x = %d,y = %d, graphic = %d", + x, y, graphic); + Debug("draw:DrawFixedGraphicThruMask", "This should never happen!"); + return; } #endif @@ -1793,35 +1749,35 @@ static void DrawGraphicShiftedNormal(int x, int y, int dx, int dy, int width = TILEX, height = TILEY; int cx = 0, cy = 0; - if (dx || dy) /* shifted graphic */ + if (dx || dy) // shifted graphic { - if (x < BX1) /* object enters playfield from the left */ + if (x < BX1) // object enters playfield from the left { x = BX1; width = dx; cx = TILEX - dx; dx = 0; } - else if (x > BX2) /* object enters playfield from the right */ + else if (x > BX2) // object enters playfield from the right { x = BX2; width = -dx; dx = TILEX + dx; } - else if (x == BX1 && dx < 0) /* object leaves playfield to the left */ + else if (x == BX1 && dx < 0) // object leaves playfield to the left { width += dx; cx = -dx; dx = 0; } - else if (x == BX2 && dx > 0) /* object leaves playfield to the right */ + else if (x == BX2 && dx > 0) // object leaves playfield to the right width -= dx; - else if (dx) /* general horizontal movement */ + else if (dx) // general horizontal movement MarkTileDirty(x + SIGN(dx), y); - if (y < BY1) /* object enters playfield from the top */ + if (y < BY1) // object enters playfield from the top { - if (cut_mode == CUT_BELOW) /* object completely above top border */ + if (cut_mode == CUT_BELOW) // object completely above top border return; y = BY1; @@ -1829,13 +1785,13 @@ static void DrawGraphicShiftedNormal(int x, int y, int dx, int dy, cy = TILEY - dy; dy = 0; } - else if (y > BY2) /* object enters playfield from the bottom */ + else if (y > BY2) // object enters playfield from the bottom { y = BY2; height = -dy; dy = TILEY + dy; } - else if (y == BY1 && dy < 0) /* object leaves playfield to the top */ + else if (y == BY1 && dy < 0) // object leaves playfield to the top { height += dy; cy = -dy; @@ -1843,25 +1799,27 @@ static void DrawGraphicShiftedNormal(int x, int y, int dx, int dy, } else if (dy > 0 && cut_mode == CUT_ABOVE) { - if (y == BY2) /* object completely above bottom border */ + if (y == BY2) // object completely above bottom border return; height = dy; cy = TILEY - dy; dy = TILEY; MarkTileDirty(x, y + 1); - } /* object leaves playfield to the bottom */ + } // object leaves playfield to the bottom else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW)) height -= dy; - else if (dy) /* general vertical movement */ + else if (dy) // general vertical movement MarkTileDirty(x, y + SIGN(dy)); } #if DEBUG if (!IN_SCR_FIELD(x, y)) { - printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic); - printf("DrawGraphicShifted(): This should never happen!\n"); + Debug("draw:DrawGraphicShiftedNormal", "x = %d, y = %d, graphic = %d", + x, y, graphic); + Debug("draw:DrawGraphicShiftedNormal", "This should never happen!"); + return; } #endif @@ -1907,22 +1865,22 @@ static void DrawGraphicShiftedDouble(int x, int y, int dx, int dy, int x2 = x + SIGN(dx); int y2 = y + SIGN(dy); - /* movement with two-tile animations must be sync'ed with movement position, - not with current GfxFrame (which can be higher when using slow movement) */ + // movement with two-tile animations must be sync'ed with movement position, + // not with current GfxFrame (which can be higher when using slow movement) int anim_pos = (dx ? ABS(dx) : ABS(dy)); int anim_frames = graphic_info[graphic].anim_frames; - /* (we also need anim_delay here for movement animations with less frames) */ + // (we also need anim_delay here for movement animations with less frames) int anim_delay = graphic_info[graphic].anim_delay; int sync_frame = anim_pos * anim_frames * anim_delay / TILESIZE; - boolean draw_start_tile = (cut_mode != CUT_ABOVE); /* only for falling! */ - boolean draw_end_tile = (cut_mode != CUT_BELOW); /* only for falling! */ + boolean draw_start_tile = (cut_mode != CUT_ABOVE); // only for falling! + boolean draw_end_tile = (cut_mode != CUT_BELOW); // only for falling! - /* re-calculate animation frame for two-tile movement animation */ + // re-calculate animation frame for two-tile movement animation frame = getGraphicAnimationFrame(graphic, sync_frame); - /* check if movement start graphic inside screen area and should be drawn */ + // check if movement start graphic inside screen area and should be drawn if (draw_start_tile && IN_SCR_FIELD(x1, y1)) { getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y, TRUE); @@ -1940,7 +1898,7 @@ static void DrawGraphicShiftedDouble(int x, int y, int dx, int dy, MarkTileDirty(x1, y1); } - /* check if movement end graphic inside screen area and should be drawn */ + // check if movement end graphic inside screen area and should be drawn if (draw_end_tile && IN_SCR_FIELD(x2, y2)) { getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y, FALSE); @@ -1970,7 +1928,7 @@ static void DrawGraphicShifted(int x, int y, int dx, int dy, return; } - if (graphic_info[graphic].double_movement) /* EM style movement images */ + if (graphic_info[graphic].double_movement) // EM style movement images DrawGraphicShiftedDouble(x, y, dx, dy, graphic, frame, cut_mode,mask_mode); else DrawGraphicShiftedNormal(x, y, dx, dy, graphic, frame, cut_mode,mask_mode); @@ -1996,14 +1954,14 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element, graphic = el_act_dir2img(element, GfxAction[lx][ly], GfxDir[lx][ly]); frame = getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]); - /* do not use double (EM style) movement graphic when not moving */ + // do not use double (EM style) movement graphic when not moving if (graphic_info[graphic].double_movement && !dx && !dy) { graphic = el_act_dir2img(element, ACTION_DEFAULT, GfxDir[lx][ly]); frame = getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]); } } - else /* border element */ + else // border element { graphic = el2img(element); frame = getGraphicAnimationFrame(graphic, -1); @@ -2013,9 +1971,9 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element, { boolean left_stopped = FALSE, right_stopped = FALSE; - if (!IN_LEV_FIELD(lx - 1, ly) || IS_WALL(Feld[lx - 1][ly])) + if (!IN_LEV_FIELD(lx - 1, ly) || IS_WALL(Tile[lx - 1][ly])) left_stopped = TRUE; - if (!IN_LEV_FIELD(lx + 1, ly) || IS_WALL(Feld[lx + 1][ly])) + if (!IN_LEV_FIELD(lx + 1, ly) || IS_WALL(Tile[lx + 1][ly])) right_stopped = TRUE; if (left_stopped && right_stopped) @@ -2067,10 +2025,10 @@ void DrawLevelElementThruMask(int x, int y, int element) void DrawLevelFieldThruMask(int x, int y) { - DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING); + DrawLevelElementExt(x, y, 0, 0, Tile[x][y], NO_CUTTING, USE_MASKING); } -/* !!! implementation of quicksand is totally broken !!! */ +// !!! implementation of quicksand is totally broken !!! #define IS_CRUMBLED_TILE(x, y, e) \ (GFX_CRUMBLED(e) && (!IN_LEV_FIELD(x, y) || \ !IS_MOVING(x, y) || \ @@ -2101,17 +2059,17 @@ static void DrawLevelFieldCrumbledInnerCorners(int x, int y, int dx, int dy, int element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) : BorderElement); - /* check if neighbour field is of same crumble type */ + // check if neighbour field is of same crumble type boolean same = (IS_CRUMBLED_TILE(xx, yy, element) && graphic_info[graphic].class == graphic_info[el_act2crm(element, ACTION_DEFAULT)].class); - /* return if check prevents inner corner */ + // return if check prevents inner corner if (same == (dxx == dx && dyy == dy)) return; } - /* if we reach this point, we have an inner corner */ + // if we reach this point, we have an inner corner getGraphicSource(graphic, 1, &src_bitmap, &src_x, &src_y); @@ -2140,7 +2098,7 @@ static void DrawLevelFieldCrumbledBorders(int x, int y, int graphic, int frame, getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y); - /* draw simple, sloppy, non-corner-accurate crumbled border */ + // draw simple, sloppy, non-corner-accurate crumbled border width = (dir == 1 || dir == 2 ? crumbled_border_size_var : TILESIZE_VAR); height = (dir == 0 || dir == 3 ? crumbled_border_size_var : TILESIZE_VAR); @@ -2151,12 +2109,12 @@ static void DrawLevelFieldCrumbledBorders(int x, int y, int graphic, int frame, FX + sx * TILEX_VAR + cx, FY + sy * TILEY_VAR + cy); - /* (remaining middle border part must be at least as big as corner part) */ + // (remaining middle border part must be at least as big as corner part) if (!(graphic_info[graphic].style & STYLE_ACCURATE_BORDERS) || crumbled_border_size_var >= TILESIZE_VAR / 3) return; - /* correct corners of crumbled border, if needed */ + // correct corners of crumbled border, if needed for (i = -1; i <= 1; i += 2) { @@ -2165,12 +2123,12 @@ static void DrawLevelFieldCrumbledBorders(int x, int y, int graphic, int frame, int element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) : BorderElement); - /* check if neighbour field is of same crumble type */ + // check if neighbour field is of same crumble type if (IS_CRUMBLED_TILE(xx, yy, element) && graphic_info[graphic].class == graphic_info[el_act2crm(element, ACTION_DEFAULT)].class) { - /* no crumbled corner, but continued crumbled border */ + // no crumbled corner, but continued crumbled border int c1 = (dir == 2 || dir == 3 ? crumbled_border_pos_var : 0); int c2 = (i == 1 ? crumbled_border_pos_var : 0); @@ -2221,12 +2179,12 @@ static void DrawLevelFieldCrumbledExt(int x, int y, int graphic, int frame) element = TILE_GFX_ELEMENT(x, y); - if (IS_CRUMBLED_TILE(x, y, element)) /* crumble field itself */ + if (IS_CRUMBLED_TILE(x, y, element)) // crumble field itself { if (!IN_SCR_FIELD(sx, sy)) return; - /* crumble field borders towards direct neighbour fields */ + // crumble field borders towards direct neighbour fields for (i = 0; i < 4; i++) { int xx = x + xy[i][0]; @@ -2235,7 +2193,7 @@ static void DrawLevelFieldCrumbledExt(int x, int y, int graphic, int frame) element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) : BorderElement); - /* check if neighbour field is of same crumble type */ + // check if neighbour field is of same crumble type if (IS_CRUMBLED_TILE(xx, yy, element) && graphic_info[graphic].class == graphic_info[el_act2crm(element, ACTION_DEFAULT)].class) @@ -2244,7 +2202,7 @@ static void DrawLevelFieldCrumbledExt(int x, int y, int graphic, int frame) DrawLevelFieldCrumbledBorders(x, y, graphic, frame, i); } - /* crumble inner field corners towards corner neighbour fields */ + // crumble inner field corners towards corner neighbour fields if ((graphic_info[graphic].style & STYLE_INNER_CORNERS) && graphic_info[graphic].anim_frames == 2) { @@ -2259,9 +2217,9 @@ static void DrawLevelFieldCrumbledExt(int x, int y, int graphic, int frame) MarkTileDirty(sx, sy); } - else /* center field is not crumbled -- crumble neighbour fields */ + else // center field is not crumbled -- crumble neighbour fields { - /* crumble field borders of direct neighbour fields */ + // crumble field borders of direct neighbour fields for (i = 0; i < 4; i++) { int xx = x + xy[i][0]; @@ -2273,7 +2231,9 @@ static void DrawLevelFieldCrumbledExt(int x, int y, int graphic, int frame) !IN_SCR_FIELD(sxx, syy)) continue; - if (Feld[xx][yy] == EL_ELEMENT_SNAPPING) + // do not crumble fields that are being digged or snapped + if (Tile[xx][yy] == EL_EMPTY || + Tile[xx][yy] == EL_ELEMENT_SNAPPING) continue; element = TILE_GFX_ELEMENT(xx, yy); @@ -2288,7 +2248,7 @@ static void DrawLevelFieldCrumbledExt(int x, int y, int graphic, int frame) MarkTileDirty(sxx, syy); } - /* crumble inner field corners of corner neighbour fields */ + // crumble inner field corners of corner neighbour fields for (i = 0; i < 4; i++) { int dx = (i & 1 ? +1 : -1); @@ -2302,7 +2262,7 @@ static void DrawLevelFieldCrumbledExt(int x, int y, int graphic, int frame) !IN_SCR_FIELD(sxx, syy)) continue; - if (Feld[xx][yy] == EL_ELEMENT_SNAPPING) + if (Tile[xx][yy] == EL_ELEMENT_SNAPPING) continue; element = TILE_GFX_ELEMENT(xx, yy); @@ -2328,7 +2288,7 @@ void DrawLevelFieldCrumbled(int x, int y) if (!IN_LEV_FIELD(x, y)) return; - if (Feld[x][y] == EL_ELEMENT_SNAPPING && + if (Tile[x][y] == EL_ELEMENT_SNAPPING && GfxElement[x][y] != EL_UNDEFINED && GFX_CRUMBLED(GfxElement[x][y])) { @@ -2367,7 +2327,7 @@ void DrawLevelFieldCrumbledNeighbours(int x, int y) }; int i; - /* crumble direct neighbour fields (required for field borders) */ + // crumble direct neighbour fields (required for field borders) for (i = 0; i < 4; i++) { int xx = x + xy[i][0]; @@ -2377,14 +2337,14 @@ void DrawLevelFieldCrumbledNeighbours(int x, int y) if (!IN_LEV_FIELD(xx, yy) || !IN_SCR_FIELD(sxx, syy) || - !GFX_CRUMBLED(Feld[xx][yy]) || + !GFX_CRUMBLED(Tile[xx][yy]) || IS_MOVING(xx, yy)) continue; DrawLevelField(xx, yy); } - /* crumble corner neighbour fields (required for inner field corners) */ + // crumble corner neighbour fields (required for inner field corners) for (i = 0; i < 4; i++) { int dx = (i & 1 ? +1 : -1); @@ -2396,7 +2356,7 @@ void DrawLevelFieldCrumbledNeighbours(int x, int y) if (!IN_LEV_FIELD(xx, yy) || !IN_SCR_FIELD(sxx, syy) || - !GFX_CRUMBLED(Feld[xx][yy]) || + !GFX_CRUMBLED(Tile[xx][yy]) || IS_MOVING(xx, yy)) continue; @@ -2461,7 +2421,7 @@ void DrawScreenField(int x, int y) return; } - element = Feld[lx][ly]; + element = Tile[lx][ly]; content = Store[lx][ly]; if (IS_MOVING(lx, ly)) @@ -2528,7 +2488,7 @@ void DrawScreenField(int x, int y) horiz_move = (MovDir[oldx][oldy] == MV_LEFT || MovDir[oldx][oldy] == MV_RIGHT); - element_old = Feld[oldx][oldy]; + element_old = Tile[oldx][oldy]; content_old = Store[oldx][oldy]; if (element_old == EL_QUICKSAND_EMPTYING || @@ -2681,7 +2641,7 @@ void DrawSizedElementOrWall(int sx, int sy, int scroll_x, int scroll_y, if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy) DrawSizedElement(sx, sy, EL_EMPTY, tilesize); else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy) - DrawSizedElement(sx, sy, Feld[x][y], tilesize); + DrawSizedElement(sx, sy, Tile[x][y], tilesize); else DrawSizedGraphic(sx, sy, el2edimg(getBorderElement(x, y)), 0, tilesize); } @@ -2693,7 +2653,7 @@ void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y) if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy) DrawMiniElement(sx, sy, EL_EMPTY); else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy) - DrawMiniElement(sx, sy, Feld[x][y]); + DrawMiniElement(sx, sy, Tile[x][y]); else DrawMiniGraphic(sx, sy, el2edimg(getBorderElement(x, y))); } @@ -2822,8 +2782,12 @@ void ShowEnvelope(int envelope_nr) 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); + boolean overlay_enabled = GetOverlayEnabled(); + + game.envelope_active = TRUE; // needed for RedrawPlayfield() events - game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */ + SetOverlayEnabled(FALSE); + UnmapAllGadgets(); PlayMenuSoundStereo(sound_opening, SOUND_MIDDLE); @@ -2833,10 +2797,13 @@ void ShowEnvelope(int envelope_nr) AnimateEnvelope(envelope_nr, main_anim_mode, ACTION_OPENING); if (tape.playing) - Delay(wait_delay_value); + Delay_WithScreenUpdates(wait_delay_value); else WaitForEventToContinue(); + RemapAllGadgets(); + SetOverlayEnabled(overlay_enabled); + PlayMenuSoundStereo(sound_closing, SOUND_MIDDLE); if (anim_mode != ANIM_NONE) @@ -2853,6 +2820,53 @@ void ShowEnvelope(int envelope_nr) BackToFront(); } +static void PrepareEnvelopeRequestToScreen(Bitmap *bitmap, int sx, int sy, + int xsize, int ysize) +{ + if (!global.use_envelope_request || + request.sort_priority <= 0) + return; + + if (request.bitmap == NULL || + xsize > request.xsize || + ysize > request.ysize) + { + if (request.bitmap != NULL) + FreeBitmap(request.bitmap); + + request.bitmap = CreateBitmap(xsize, ysize, DEFAULT_DEPTH); + + SDL_Surface *surface = request.bitmap->surface; + + if ((request.bitmap->surface_masked = SDLGetNativeSurface(surface)) == NULL) + Fail("SDLGetNativeSurface() failed"); + } + + BlitBitmap(bitmap, request.bitmap, sx, sy, xsize, ysize, 0, 0); + + SDLFreeBitmapTextures(request.bitmap); + SDLCreateBitmapTextures(request.bitmap); + + // set envelope request run-time values + request.sx = sx; + request.sy = sy; + request.xsize = xsize; + request.ysize = ysize; +} + +void DrawEnvelopeRequestToScreen(int drawing_target, int drawing_stage) +{ + 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) + { + BlitToScreen(request.bitmap, 0, 0, request.xsize, request.ysize, + request.sx, request.sy); + } +} + static void setRequestBasePosition(int *x, int *y) { int sx_base, sy_base; @@ -2988,7 +3002,7 @@ static void DrawEnvelopeRequest(char *text) x, y, x_steps, y_steps, tile_size, tile_size); - /* force DOOR font inside door area */ + // force DOOR font inside door area SetFontStatus(GAME_MODE_PSEUDO_DOOR); DrawTextBuffer(sx + sx_offset, sy + sy_offset, text_final, font_nr, @@ -3003,6 +3017,8 @@ static void DrawEnvelopeRequest(char *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); + PrepareEnvelopeRequestToScreen(bitmap_db_store_2, sx, sy, width, height); + if (text_door_style) free(text_door_style); } @@ -3084,6 +3100,8 @@ static void AnimateEnvelopeRequest(int anim_mode, int action) } } + PrepareEnvelopeRequestToScreen(backbuffer, dst_x, dst_y, width, height); + redraw_mask |= REDRAW_FIELD; BackToFront(); @@ -3099,8 +3117,8 @@ static void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) int graphic = IMG_BACKGROUND_REQUEST; int sound_opening = SND_REQUEST_OPENING; int sound_closing = SND_REQUEST_CLOSING; - int anim_mode_1 = request.anim_mode; /* (higher priority) */ - int anim_mode_2 = graphic_info[graphic].anim_mode; /* (lower priority) */ + int anim_mode_1 = request.anim_mode; // (higher priority) + int anim_mode_2 = graphic_info[graphic].anim_mode; // (lower priority) int anim_mode = (anim_mode_1 != ANIM_DEFAULT ? anim_mode_1 : anim_mode_2); int main_anim_mode = (anim_mode == ANIM_NONE ? ANIM_VERTICAL|ANIM_HORIZONTAL: anim_mode == ANIM_DEFAULT ? ANIM_VERTICAL : anim_mode); @@ -3120,10 +3138,13 @@ static void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) { 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) { @@ -3136,7 +3157,7 @@ static void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) DrawEnvelopeRequest(text); } - game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */ + game.envelope_active = TRUE; // needed for RedrawPlayfield() events if (action == ACTION_OPENING) { @@ -3391,7 +3412,7 @@ static void DrawPreviewLevelExt(boolean restart) DrawPreviewLevelInfo(MICROLABEL_LEVEL_NAME); DrawPreviewLevelInfo(MICROLABEL_LEVEL_AUTHOR); - /* initialize delay counters */ + // initialize delay counters DelayReached(&scroll_delay, 0); DelayReached(&label_delay, 0); @@ -3415,7 +3436,7 @@ static void DrawPreviewLevelExt(boolean restart) return; } - /* scroll preview level, if needed */ + // scroll preview level, if needed if (preview.anim_mode != ANIM_NONE && (level_xsize > preview.xsize || level_ysize > preview.ysize) && DelayReached(&scroll_delay, scroll_delay_value)) @@ -3471,8 +3492,8 @@ static void DrawPreviewLevelExt(boolean restart) DrawPreviewLevelPlayfield(from_x, from_y); } - /* !!! THIS ALL SUCKS -- SHOULD BE CLEANLY REWRITTEN !!! */ - /* redraw micro level label, if needed */ + // !!! THIS ALL SUCKS -- SHOULD BE CLEANLY REWRITTEN !!! + // redraw micro level label, if needed if (!strEqual(level.name, NAMELESS_LEVEL_NAME) && !strEqual(level.author, ANONYMOUS_NAME) && !strEqual(level.author, leveldir_current->name) && @@ -3513,12 +3534,13 @@ static void DrawPreviewLevelExt(boolean restart) } } -static void DrawPreviewPlayers(void) +void DrawPreviewPlayers(void) { if (game_status != GAME_MODE_MAIN) return; - if (!network.enabled && !setup.team_mode) + // do not draw preview players if level preview redefined, but players aren't + if (preview.redefined && !menu.main.preview_players.redefined) return; boolean player_found[MAX_PLAYERS]; @@ -3528,7 +3550,7 @@ static void DrawPreviewPlayers(void) for (i = 0; i < MAX_PLAYERS; i++) player_found[i] = FALSE; - /* check which players can be found in the level (simple approach) */ + // check which players can be found in the level (simple approach) for (x = 0; x < lev_fieldx; x++) { for (y = 0; y < lev_fieldy; y++) @@ -3565,15 +3587,18 @@ static void DrawPreviewPlayers(void) int xpos = SX + ALIGNED_XPOS(pos->x, all_players_width, pos->align); int ypos = SY + ALIGNED_YPOS(pos->y, all_players_height, pos->valign); - /* clear area in which the players will be drawn */ + // clear area in which the players will be drawn ClearRectangleOnBackground(drawto, max_xpos, max_ypos, max_players_width, max_players_height); - /* only draw players if level is suited for team mode */ + if (!network.enabled && !setup.team_mode) + return; + + // only draw players if level is suited for team mode if (num_players < 2) return; - /* draw all players that were found in the level */ + // draw all players that were found in the level for (i = 0; i < MAX_PLAYERS; i++) { if (player_found[i]) @@ -3623,6 +3648,10 @@ static void DrawNetworkPlayersExt(boolean force) if (!network.connected && !force) return; + // do not draw network players if level preview redefined, but players aren't + if (preview.redefined && !menu.main.network_players.redefined) + return; + int num_players = 0; int i; @@ -3649,7 +3678,7 @@ static void DrawNetworkPlayersExt(boolean force) ClearRectangleOnBackground(drawto, max_xpos, max_ypos, max_players_width, max_players_height); - /* first draw local network player ... */ + // first draw local network player ... for (i = 0; i < MAX_PLAYERS; i++) { if (stored_player[i].connected_network && @@ -3665,7 +3694,7 @@ static void DrawNetworkPlayersExt(boolean force) } } - /* ... then draw all other network players */ + // ... then draw all other network players for (i = 0; i < MAX_PLAYERS; i++) { if (stored_player[i].connected_network && @@ -3768,7 +3797,7 @@ void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic) if (GFX_CRUMBLED(TILE_GFX_ELEMENT(x, y))) DrawLevelFieldCrumbled(x, y); #else - if (GFX_CRUMBLED(Feld[x][y])) + if (GFX_CRUMBLED(Tile[x][y])) DrawLevelFieldCrumbled(x, y); #endif } @@ -3796,14 +3825,14 @@ static int getPlayerGraphic(struct PlayerInfo *player, int move_dir) { if (player->use_murphy) { - /* this works only because currently only one player can be "murphy" ... */ + // this works only because currently only one player can be "murphy" ... static int last_horizontal_dir = MV_LEFT; int graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, move_dir); if (move_dir == MV_LEFT || move_dir == MV_RIGHT) last_horizontal_dir = move_dir; - if (graphic == IMG_SP_MURPHY) /* undefined => use special graphic */ + if (graphic == IMG_SP_MURPHY) // undefined => use special graphic { int direction = (player->is_snapping ? move_dir : last_horizontal_dir); @@ -3829,87 +3858,122 @@ static boolean equalGraphics(int graphic1, int graphic2) g1->anim_mode == g2->anim_mode); } -void DrawAllPlayers(void) +#define DRAW_PLAYER_OVER_PUSHED_ELEMENT 1 + +enum { - int i; + DRAW_PLAYER_STAGE_INIT = 0, + DRAW_PLAYER_STAGE_LAST_FIELD, + DRAW_PLAYER_STAGE_FIELD_UNDER_PLAYER, +#if DRAW_PLAYER_OVER_PUSHED_ELEMENT + DRAW_PLAYER_STAGE_ELEMENT_PUSHED, + DRAW_PLAYER_STAGE_PLAYER, +#else + DRAW_PLAYER_STAGE_PLAYER, + DRAW_PLAYER_STAGE_ELEMENT_PUSHED, +#endif + DRAW_PLAYER_STAGE_ELEMENT_OVER_PLAYER, + DRAW_PLAYER_STAGE_FIELD_OVER_PLAYER, - for (i = 0; i < MAX_PLAYERS; i++) - if (stored_player[i].active) - DrawPlayer(&stored_player[i]); -} + NUM_DRAW_PLAYER_STAGES +}; -void DrawPlayerField(int x, int y) +static void DrawPlayerExt(struct PlayerInfo *player, int drawing_stage) { - if (!IS_PLAYER(x, y)) + static int static_last_player_graphic[MAX_PLAYERS]; + static int static_last_player_frame[MAX_PLAYERS]; + static boolean static_player_is_opaque[MAX_PLAYERS]; + static boolean draw_player[MAX_PLAYERS]; + int pnr = player->index_nr; + + if (drawing_stage == DRAW_PLAYER_STAGE_INIT) + { + static_last_player_graphic[pnr] = getPlayerGraphic(player, player->MovDir); + static_last_player_frame[pnr] = player->Frame; + static_player_is_opaque[pnr] = FALSE; + + draw_player[pnr] = TRUE; + } + + if (!draw_player[pnr]) return; - DrawPlayer(PLAYERINFO(x, y)); -} +#if DEBUG + if (!IN_LEV_FIELD(player->jx, player->jy)) + { + Debug("draw:DrawPlayerExt", "x = %d, y = %d", player->jx, player->jy); + Debug("draw:DrawPlayerExt", "This should never happen!"); -#define DRAW_PLAYER_OVER_PUSHED_ELEMENT 1 + draw_player[pnr] = FALSE; + + return; + } +#endif + + int last_player_graphic = static_last_player_graphic[pnr]; + int last_player_frame = static_last_player_frame[pnr]; + boolean player_is_opaque = static_player_is_opaque[pnr]; -void DrawPlayer(struct PlayerInfo *player) -{ int jx = player->jx; int jy = player->jy; - int move_dir = player->MovDir; + int move_dir = (player->is_waiting ? player->dir_waiting : player->MovDir); int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? +1 : 0); int dy = (move_dir == MV_UP ? -1 : move_dir == MV_DOWN ? +1 : 0); int last_jx = (player->is_moving ? jx - dx : jx); int last_jy = (player->is_moving ? jy - dy : jy); int next_jx = jx + dx; int next_jy = jy + dy; - boolean player_is_moving = (player->MovPos ? TRUE : FALSE); - boolean player_is_opaque = FALSE; - int sx = SCREENX(jx), sy = SCREENY(jy); - int sxx = 0, syy = 0; - int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy]; - int graphic; - int action = ACTION_DEFAULT; - int last_player_graphic = getPlayerGraphic(player, move_dir); - int last_player_frame = player->Frame; - int frame = 0; + boolean player_is_moving = (player->MovPos != 0 ? TRUE : FALSE); + int sx = SCREENX(jx); + int sy = SCREENY(jy); + int sxx = (move_dir == MV_LEFT || move_dir == MV_RIGHT ? player->GfxPos : 0); + int syy = (move_dir == MV_UP || move_dir == MV_DOWN ? player->GfxPos : 0); + int element = Tile[jx][jy]; + int last_element = Tile[last_jx][last_jy]; + int action = (player->is_pushing ? ACTION_PUSHING : + player->is_digging ? ACTION_DIGGING : + player->is_collecting ? ACTION_COLLECTING : + player->is_moving ? ACTION_MOVING : + player->is_snapping ? ACTION_SNAPPING : + player->is_dropping ? ACTION_DROPPING : + player->is_waiting ? player->action_waiting : + ACTION_DEFAULT); + + if (drawing_stage == DRAW_PLAYER_STAGE_INIT) + { + // ------------------------------------------------------------------------ + // initialize drawing the player + // ------------------------------------------------------------------------ - /* GfxElement[][] is set to the element the player is digging or collecting; - remove also for off-screen player if the player is not moving anymore */ - if (IN_LEV_FIELD(jx, jy) && !player_is_moving) - GfxElement[jx][jy] = EL_UNDEFINED; + draw_player[pnr] = FALSE; - if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy))) - return; + // GfxElement[][] is set to the element the player is digging or collecting; + // remove also for off-screen player if the player is not moving anymore + if (IN_LEV_FIELD(jx, jy) && !player_is_moving) + GfxElement[jx][jy] = EL_UNDEFINED; -#if DEBUG - if (!IN_LEV_FIELD(jx, jy)) - { - printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy); - printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy); - printf("DrawPlayerField(): This should never happen!\n"); - return; - } -#endif + if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy))) + return; - if (element == EL_EXPLOSION) - return; + if (element == EL_EXPLOSION) + return; - action = (player->is_pushing ? ACTION_PUSHING : - player->is_digging ? ACTION_DIGGING : - player->is_collecting ? ACTION_COLLECTING : - player->is_moving ? ACTION_MOVING : - player->is_snapping ? ACTION_SNAPPING : - player->is_dropping ? ACTION_DROPPING : - player->is_waiting ? player->action_waiting : ACTION_DEFAULT); + InitPlayerGfxAnimation(player, action, move_dir); - if (player->is_waiting) - move_dir = player->dir_waiting; + draw_player[pnr] = TRUE; + } + else if (drawing_stage == DRAW_PLAYER_STAGE_LAST_FIELD) + { + // ------------------------------------------------------------------------ + // draw things in the field the player is leaving, if needed + // ------------------------------------------------------------------------ - InitPlayerGfxAnimation(player, action, move_dir); + if (!IN_SCR_FIELD(sx, sy)) + draw_player[pnr] = FALSE; - /* ----------------------------------------------------------------------- */ - /* draw things in the field the player is leaving, if needed */ - /* ----------------------------------------------------------------------- */ + if (!player->is_moving) + return; - if (player->is_moving) - { if (Back[last_jx][last_jy] && IS_DRAWABLE(last_element)) { DrawLevelElement(last_jx, last_jy, Back[last_jx][last_jy]); @@ -3925,35 +3989,32 @@ void DrawPlayer(struct PlayerInfo *player) last_element == EL_EM_DYNAMITE_ACTIVE || last_element == EL_SP_DISK_RED_ACTIVE) DrawDynamite(last_jx, last_jy); -#if 0 - /* !!! this is not enough to prevent flickering of players which are - moving next to each others without a free tile between them -- this - can only be solved by drawing all players layer by layer (first the - background, then the foreground etc.) !!! => TODO */ - else if (!IS_PLAYER(last_jx, last_jy)) - DrawLevelField(last_jx, last_jy); -#else else DrawLevelField(last_jx, last_jy); -#endif 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) + { + // ------------------------------------------------------------------------ + // draw things behind the player, if needed + // ------------------------------------------------------------------------ - if (!IN_SCR_FIELD(sx, sy)) - return; + if (Back[jx][jy]) + { + DrawLevelElement(jx, jy, Back[jx][jy]); + + return; + } - /* ----------------------------------------------------------------------- */ - /* draw things behind the player, if needed */ - /* ----------------------------------------------------------------------- */ + if (IS_ACTIVE_BOMB(element)) + { + DrawLevelElement(jx, jy, EL_EMPTY); + + return; + } - if (Back[jx][jy]) - DrawLevelElement(jx, jy, Back[jx][jy]); - else if (IS_ACTIVE_BOMB(element)) - DrawLevelElement(jx, jy, EL_EMPTY); - else - { if (player_is_moving && GfxElement[jx][jy] != EL_UNDEFINED) { int old_element = GfxElement[jx][jy]; @@ -3966,14 +4027,14 @@ void DrawPlayer(struct PlayerInfo *player) DrawGraphic(sx, sy, old_graphic, frame); if (graphic_info[old_graphic].anim_mode & ANIM_OPAQUE_PLAYER) - player_is_opaque = TRUE; + static_player_is_opaque[pnr] = TRUE; } else { GfxElement[jx][jy] = EL_UNDEFINED; - /* make sure that pushed elements are drawn with correct frame rate */ - graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir); + // make sure that pushed elements are drawn with correct frame rate + int graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir); if (player->is_pushing && player->is_moving && !IS_ANIM_MODE_CE(graphic)) GfxFrame[jx][jy] = player->StepFrame; @@ -3981,84 +4042,31 @@ void DrawPlayer(struct PlayerInfo *player) DrawLevelField(jx, jy); } } - -#if !DRAW_PLAYER_OVER_PUSHED_ELEMENT - /* ----------------------------------------------------------------------- */ - /* draw player himself */ - /* ----------------------------------------------------------------------- */ - - graphic = getPlayerGraphic(player, move_dir); - - /* in the case of changed player action or direction, prevent the current - animation frame from being restarted for identical animations */ - if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic)) - player->Frame = last_player_frame; - - frame = getGraphicAnimationFrame(graphic, player->Frame); - - if (player->GfxPos) - { - if (move_dir == MV_LEFT || move_dir == MV_RIGHT) - sxx = player->GfxPos; - else - syy = player->GfxPos; - } - - if (player_is_opaque) - DrawGraphicShifted(sx, sy, sxx, syy, graphic, frame,NO_CUTTING,NO_MASKING); - else - DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING); - - if (SHIELD_ON(player)) - { - int graphic = (player->shield_deadly_time_left ? IMG_SHIELD_DEADLY_ACTIVE : - IMG_SHIELD_NORMAL_ACTIVE); - int frame = getGraphicAnimationFrame(graphic, -1); - - DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING); - } -#endif - -#if DRAW_PLAYER_OVER_PUSHED_ELEMENT - if (player->GfxPos) + else if (drawing_stage == DRAW_PLAYER_STAGE_ELEMENT_PUSHED) { - if (move_dir == MV_LEFT || move_dir == MV_RIGHT) - sxx = player->GfxPos; - else - syy = player->GfxPos; - } -#endif + // ------------------------------------------------------------------------ + // draw things the player is pushing, if needed + // ------------------------------------------------------------------------ - /* ----------------------------------------------------------------------- */ - /* draw things the player is pushing, if needed */ - /* ----------------------------------------------------------------------- */ + if (!player->is_pushing || !player->is_moving) + return; - if (player->is_pushing && player->is_moving) - { - int px = SCREENX(jx), py = SCREENY(jy); - int pxx = (TILEX - ABS(sxx)) * dx; - int pyy = (TILEY - ABS(syy)) * dy; int gfx_frame = GfxFrame[jx][jy]; - int graphic; - int sync_frame; - int frame; - - if (!IS_MOVING(jx, jy)) /* push movement already finished */ + if (!IS_MOVING(jx, jy)) // push movement already finished { - element = Feld[next_jx][next_jy]; + element = Tile[next_jx][next_jy]; gfx_frame = GfxFrame[next_jx][next_jy]; } - graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir); - - sync_frame = (IS_ANIM_MODE_CE(graphic) ? gfx_frame : player->StepFrame); - frame = getGraphicAnimationFrame(graphic, sync_frame); + int graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir); + int sync_frame = (IS_ANIM_MODE_CE(graphic) ? gfx_frame : player->StepFrame); + int frame = getGraphicAnimationFrame(graphic, sync_frame); - /* draw background element under pushed element (like the Sokoban field) */ + // draw background element under pushed element (like the Sokoban field) if (game.use_masked_pushing && IS_MOVING(jx, jy)) { - /* this allows transparent pushing animation over non-black background */ + // this allows transparent pushing animation over non-black background if (Back[jx][jy]) DrawLevelElement(jx, jy, Back[jx][jy]); @@ -4073,127 +4081,155 @@ void DrawPlayer(struct PlayerInfo *player) else if (Back[next_jx][next_jy]) DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]); + int px = SCREENX(jx), py = SCREENY(jy); + int pxx = (TILEX - ABS(sxx)) * dx; + int pyy = (TILEY - ABS(syy)) * dy; + #if 1 - /* do not draw (EM style) pushing animation when pushing is finished */ - /* (two-tile animations usually do not contain start and end frame) */ + // do not draw (EM style) pushing animation when pushing is finished + // (two-tile animations usually do not contain start and end frame) if (graphic_info[graphic].double_movement && !IS_MOVING(jx, jy)) - DrawLevelElement(next_jx, next_jy, Feld[next_jx][next_jy]); + DrawLevelElement(next_jx, next_jy, Tile[next_jx][next_jy]); else DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame, NO_CUTTING); #else - /* masked drawing is needed for EMC style (double) movement graphics */ - /* !!! (ONLY WHEN DRAWING PUSHED ELEMENT OVER THE PLAYER) !!! */ + // masked drawing is needed for EMC style (double) movement graphics + // !!! (ONLY WHEN DRAWING PUSHED ELEMENT OVER THE PLAYER) !!! DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame, NO_CUTTING); #endif } + else if (drawing_stage == DRAW_PLAYER_STAGE_PLAYER) + { + // ------------------------------------------------------------------------ + // draw player himself + // ------------------------------------------------------------------------ -#if DRAW_PLAYER_OVER_PUSHED_ELEMENT - /* ----------------------------------------------------------------------- */ - /* draw player himself */ - /* ----------------------------------------------------------------------- */ - - graphic = getPlayerGraphic(player, move_dir); + int graphic = getPlayerGraphic(player, move_dir); - /* in the case of changed player action or direction, prevent the current - animation frame from being restarted for identical animations */ - if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic)) - player->Frame = last_player_frame; + // in the case of changed player action or direction, prevent the current + // animation frame from being restarted for identical animations + if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic)) + player->Frame = last_player_frame; - frame = getGraphicAnimationFrame(graphic, player->Frame); + int frame = getGraphicAnimationFrame(graphic, player->Frame); - if (player->GfxPos) - { - if (move_dir == MV_LEFT || move_dir == MV_RIGHT) - sxx = player->GfxPos; + if (player_is_opaque) + DrawGraphicShifted(sx,sy, sxx,syy, graphic, frame, NO_CUTTING,NO_MASKING); else - syy = player->GfxPos; - } + DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING); - if (player_is_opaque) - DrawGraphicShifted(sx, sy, sxx, syy, graphic, frame,NO_CUTTING,NO_MASKING); - else - DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING); + if (SHIELD_ON(player)) + { + graphic = (player->shield_deadly_time_left ? IMG_SHIELD_DEADLY_ACTIVE : + IMG_SHIELD_NORMAL_ACTIVE); + frame = getGraphicAnimationFrame(graphic, -1); - if (SHIELD_ON(player)) + DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING); + } + } + else if (drawing_stage == DRAW_PLAYER_STAGE_ELEMENT_OVER_PLAYER) { - int graphic = (player->shield_deadly_time_left ? IMG_SHIELD_DEADLY_ACTIVE : - IMG_SHIELD_NORMAL_ACTIVE); - int frame = getGraphicAnimationFrame(graphic, -1); + // ------------------------------------------------------------------------ + // draw things in front of player (active dynamite or dynabombs) + // ------------------------------------------------------------------------ - DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING); - } -#endif + if (IS_ACTIVE_BOMB(element)) + { + int graphic = el2img(element); + int frame = getGraphicAnimationFrame(graphic, GfxFrame[jx][jy]); - /* ----------------------------------------------------------------------- */ - /* draw things in front of player (active dynamite or dynabombs) */ - /* ----------------------------------------------------------------------- */ + if (game.emulation == EMU_SUPAPLEX) + DrawGraphic(sx, sy, IMG_SP_DISK_RED, frame); + else + DrawGraphicThruMask(sx, sy, graphic, frame); + } - if (IS_ACTIVE_BOMB(element)) + if (player_is_moving && last_element == EL_EXPLOSION) + { + int element = (GfxElement[last_jx][last_jy] != EL_UNDEFINED ? + GfxElement[last_jx][last_jy] : EL_EMPTY); + int graphic = el_act2img(element, ACTION_EXPLODING); + int delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2); + int phase = ExplodePhase[last_jx][last_jy] - 1; + int frame = getGraphicAnimationFrame(graphic, phase - delay); + + if (phase >= delay) + DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy), graphic, frame); + } + } + else if (drawing_stage == DRAW_PLAYER_STAGE_FIELD_OVER_PLAYER) { - graphic = el2img(element); - frame = getGraphicAnimationFrame(graphic, GfxFrame[jx][jy]); + // ------------------------------------------------------------------------ + // draw elements the player is just walking/passing through/under + // ------------------------------------------------------------------------ - if (game.emulation == EMU_SUPAPLEX) - DrawGraphic(sx, sy, IMG_SP_DISK_RED, frame); - else - DrawGraphicThruMask(sx, sy, graphic, frame); - } + 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); + } - if (player_is_moving && last_element == EL_EXPLOSION) - { - int element = (GfxElement[last_jx][last_jy] != EL_UNDEFINED ? - GfxElement[last_jx][last_jy] : EL_EMPTY); - int graphic = el_act2img(element, ACTION_EXPLODING); - int delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2); - int phase = ExplodePhase[last_jx][last_jy] - 1; - int frame = getGraphicAnimationFrame(graphic, phase - delay); + // 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); + } - if (phase >= delay) - DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy), graphic, frame); + MarkTileDirty(sx, sy); } +} - /* ----------------------------------------------------------------------- */ - /* draw elements the player is just walking/passing through/under */ - /* ----------------------------------------------------------------------- */ +void DrawPlayer(struct PlayerInfo *player) +{ + int i; - 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); - } + for (i = 0; i < NUM_DRAW_PLAYER_STAGES; i++) + DrawPlayerExt(player, i); +} - /* 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); - } +void DrawAllPlayers(void) +{ + int i, j; + + for (i = 0; i < NUM_DRAW_PLAYER_STAGES; i++) + for (j = 0; j < MAX_PLAYERS; j++) + if (stored_player[j].active) + DrawPlayerExt(&stored_player[j], i); +} - MarkTileDirty(sx, sy); +void DrawPlayerField(int x, int y) +{ + if (!IS_PLAYER(x, y)) + return; + + DrawPlayer(PLAYERINFO(x, y)); } -/* ------------------------------------------------------------------------- */ +// ---------------------------------------------------------------------------- void WaitForEventToContinue(void) { + boolean first_wait = TRUE; boolean still_wait = TRUE; if (program.headless) return; - /* simulate releasing mouse button over last gadget, if still pressed */ + // simulate releasing mouse button over last gadget, if still pressed if (button_status) HandleGadgets(-1, -1, 0); button_status = MB_RELEASED; ClearEventQueue(); + ClearPlayerAction(); while (still_wait) { @@ -4203,19 +4239,22 @@ void WaitForEventToContinue(void) { switch (event.type) { - case EVENT_BUTTONRELEASE: - case EVENT_KEYPRESS: -#if defined(TARGET_SDL2) + case EVENT_BUTTONPRESS: + case EVENT_FINGERPRESS: + first_wait = FALSE; + break; + + case EVENT_BUTTONRELEASE: + case EVENT_FINGERRELEASE: + still_wait = first_wait; + break; + + case EVENT_KEYPRESS: case SDL_CONTROLLERBUTTONDOWN: -#endif case SDL_JOYBUTTONDOWN: still_wait = FALSE; break; - case EVENT_KEYRELEASE: - ClearPlayerAction(); - break; - default: HandleOtherEvents(&event); break; @@ -4226,7 +4265,8 @@ void WaitForEventToContinue(void) still_wait = FALSE; } - BackToFront(); + if (!PendingEvent()) + BackToFront(); } } @@ -4234,16 +4274,17 @@ void WaitForEventToContinue(void) #define MAX_REQUEST_LINE_FONT1_LEN 7 #define MAX_REQUEST_LINE_FONT2_LEN 10 -static int RequestHandleEvents(unsigned int req_state) +static int RequestHandleEvents(unsigned int req_state, int draw_buffer_game) { boolean game_just_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 */ + // when showing request dialog after game ended, deactivate game panel if (game_just_ended) game.panel.active = FALSE; @@ -4258,11 +4299,11 @@ static int RequestHandleEvents(unsigned int req_state) while (result < 0) { + boolean event_handled = FALSE; + if (game_just_ended) { - /* the MM game engine does not use a special (scrollable) field buffer */ - if (level.game_engine_type != GAME_ENGINE_TYPE_MM) - SetDrawtoField(DRAW_TO_FIELDBUFFER); + SetDrawtoField(draw_buffer_game); HandleGameActions(); @@ -4270,7 +4311,7 @@ static int RequestHandleEvents(unsigned int req_state) if (global.use_envelope_request) { - /* copy current state of request area to middle of playfield area */ + // copy current state of request area to middle of playfield area BlitBitmap(bitmap_db_store_2, drawto, sx, sy, width, height, sx, sy); } } @@ -4281,6 +4322,8 @@ static int RequestHandleEvents(unsigned int req_state) while (NextValidEvent(&event)) { + event_handled = TRUE; + switch (event.type) { case EVENT_BUTTONPRESS: @@ -4309,18 +4352,21 @@ static int RequestHandleEvents(unsigned int req_state) button_status = MB_RELEASED; } - /* this sets 'request_gadget_id' */ + // this sets 'request_gadget_id' HandleGadgets(mx, my, button_status); switch (request_gadget_id) { case TOOL_CTRL_ID_YES: + case TOOL_CTRL_ID_TOUCH_YES: result = TRUE; break; case TOOL_CTRL_ID_NO: + case TOOL_CTRL_ID_TOUCH_NO: result = FALSE; break; case TOOL_CTRL_ID_CONFIRM: + case TOOL_CTRL_ID_TOUCH_CONFIRM: result = TRUE | FALSE; break; @@ -4338,13 +4384,14 @@ static int RequestHandleEvents(unsigned int req_state) break; default: + // only check clickable animations if no request gadget clicked + HandleGlobalAnimClicks(mx, my, button_status, FALSE); break; } break; } -#if defined(TARGET_SDL2) case SDL_WINDOWEVENT: HandleWindowEvent((WindowEvent *) &event); break; @@ -4355,7 +4402,6 @@ static int RequestHandleEvents(unsigned int req_state) case SDL_APP_DIDENTERFOREGROUND: HandlePauseResumeEvent((PauseResumeEvent *) &event); break; -#endif case EVENT_KEYPRESS: { @@ -4370,31 +4416,27 @@ static int RequestHandleEvents(unsigned int req_state) case KSYM_Return: case KSYM_y: -#if defined(TARGET_SDL2) case KSYM_Y: case KSYM_Select: case KSYM_Menu: #if defined(KSYM_Rewind) - case KSYM_Rewind: /* for Amazon Fire TV remote */ -#endif + case KSYM_Rewind: // for Amazon Fire TV remote #endif result = 1; break; case KSYM_Escape: case KSYM_n: -#if defined(TARGET_SDL2) case KSYM_N: case KSYM_Back: #if defined(KSYM_FastForward) - case KSYM_FastForward: /* for Amazon Fire TV remote */ -#endif + case KSYM_FastForward: // for Amazon Fire TV remote #endif result = 0; break; default: - HandleKeysDebug(key); + HandleKeysDebug(key, KEY_PRESSED); break; } @@ -4439,11 +4481,11 @@ static int RequestHandleEvents(unsigned int req_state) break; } + case EVENT_FINGERRELEASE: case EVENT_KEYRELEASE: ClearPlayerAction(); break; -#if defined(TARGET_SDL2) case SDL_CONTROLLERBUTTONDOWN: switch (event.cbutton.button) { @@ -4503,7 +4545,6 @@ static int RequestHandleEvents(unsigned int req_state) HandleJoystickEvent(&event); ClearPlayerAction(); break; -#endif default: HandleOtherEvents(&event); @@ -4537,18 +4578,25 @@ static int RequestHandleEvents(unsigned int req_state) } } - if (game_just_ended) + if (event_handled) { - if (global.use_envelope_request) + if (game_just_ended) { - /* copy back current state of pressed buttons inside request area */ - BlitBitmap(drawto, bitmap_db_store_2, sx, sy, width, height, sx, sy); + 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; @@ -4556,6 +4604,7 @@ static int RequestHandleEvents(unsigned int req_state) static boolean RequestDoor(char *text, unsigned int req_state) { + 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; @@ -4572,35 +4621,35 @@ static boolean RequestDoor(char *text, unsigned int req_state) if (game_status == GAME_MODE_PLAYING) BlitScreenToBitmap(backbuffer); - /* disable deactivated drawing when quick-loading level tape recording */ + // 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 */ + // pause network game while waiting for request to answer if (network.enabled && game_status == GAME_MODE_PLAYING && - !AllPlayersGone && + !game.all_players_gone && req_state & REQUEST_WAIT_FOR_INPUT) SendToServer_PausePlaying(); old_door_state = GetDoorState(); - /* simulate releasing mouse button over last gadget, if still pressed */ + // simulate releasing mouse button over last gadget, if still pressed if (button_status) HandleGadgets(-1, -1, 0); UnmapAllGadgets(); - /* draw released gadget before proceeding */ + // draw released gadget before proceeding // BackToFront(); if (old_door_state & DOOR_OPEN_1) { CloseDoor(DOOR_CLOSE_1); - /* save old door content */ + // save old door content BlitBitmap(bitmap_db_door_1, bitmap_db_door_1, 0 * DXSIZE, 0, DXSIZE, DYSIZE, 1 * DXSIZE, 0); } @@ -4608,13 +4657,13 @@ static boolean RequestDoor(char *text, unsigned int req_state) SetDoorBackgroundImage(IMG_BACKGROUND_DOOR); SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); - /* clear door drawing field */ + // clear door drawing field DrawBackground(DX, DY, DXSIZE, DYSIZE); - /* force DOOR font inside door area */ + // force DOOR font inside door area SetFontStatus(GAME_MODE_PSEUDO_DOOR); - /* write text for request */ + // write text for request for (text_ptr = text, ty = 0; ty < MAX_REQUEST_LINES; ty++) { char text_line[max_request_line_len + 1]; @@ -4658,10 +4707,13 @@ static boolean RequestDoor(char *text, unsigned int req_state) { 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) { @@ -4671,7 +4723,7 @@ static boolean RequestDoor(char *text, unsigned int req_state) MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]); } - /* copy request gadgets to door backbuffer */ + // copy request gadgets to door backbuffer BlitBitmap(drawto, bitmap_db_door_1, DX, DY, DXSIZE, DYSIZE, 0, 0); OpenDoor(DOOR_OPEN_1); @@ -4694,7 +4746,7 @@ static boolean RequestDoor(char *text, unsigned int req_state) SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); // ---------- handle request buttons ---------- - result = RequestHandleEvents(req_state); + result = RequestHandleEvents(req_state, draw_buffer_last); UnmapToolButtons(); @@ -4719,14 +4771,14 @@ static boolean RequestDoor(char *text, unsigned int req_state) SetDrawBackgroundMask(REDRAW_FIELD); } - /* continue network game after request */ + // continue network game after request if (network.enabled && game_status == GAME_MODE_PLAYING && - !AllPlayersGone && + !game.all_players_gone && req_state & REQUEST_WAIT_FOR_INPUT) SendToServer_ContinuePlaying(); - /* restore deactivated drawing when quick-loading level tape recording */ + // restore deactivated drawing when quick-loading level tape recording if (tape.playing && tape.deactivate_display) TapeDeactivateDisplayOn(); @@ -4735,25 +4787,26 @@ static boolean RequestDoor(char *text, unsigned int req_state) static boolean 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 */ + // 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 */ + // pause network game while waiting for request to answer if (network.enabled && game_status == GAME_MODE_PLAYING && - !AllPlayersGone && + !game.all_players_gone && req_state & REQUEST_WAIT_FOR_INPUT) SendToServer_PausePlaying(); - /* simulate releasing mouse button over last gadget, if still pressed */ + // simulate releasing mouse button over last gadget, if still pressed if (button_status) HandleGadgets(-1, -1, 0); @@ -4763,7 +4816,7 @@ static boolean RequestEnvelope(char *text, unsigned int req_state) // SetDoorBackgroundImage(IMG_BACKGROUND_DOOR); // SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); - /* clear door drawing field */ + // clear door drawing field // DrawBackground(DX, DY, DXSIZE, DYSIZE); ShowEnvelopeRequest(text, req_state, ACTION_OPENING); @@ -4786,7 +4839,7 @@ static boolean RequestEnvelope(char *text, unsigned int req_state) SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); // ---------- handle request buttons ---------- - result = RequestHandleEvents(req_state); + result = RequestHandleEvents(req_state, draw_buffer_last); UnmapToolButtons(); @@ -4804,14 +4857,14 @@ static boolean RequestEnvelope(char *text, unsigned int req_state) SetDrawBackgroundMask(REDRAW_FIELD); } - /* continue network game after request */ + // continue network game after request if (network.enabled && game_status == GAME_MODE_PLAYING && - !AllPlayersGone && + !game.all_players_gone && req_state & REQUEST_WAIT_FOR_INPUT) SendToServer_ContinuePlaying(); - /* restore deactivated drawing when quick-loading level tape recording */ + // restore deactivated drawing when quick-loading level tape recording if (tape.playing && tape.deactivate_display) TapeDeactivateDisplayOn(); @@ -4820,17 +4873,21 @@ static boolean RequestEnvelope(char *text, unsigned int req_state) boolean Request(char *text, unsigned int req_state) { - boolean overlay_active = GetOverlayActive(); + boolean overlay_enabled = GetOverlayEnabled(); boolean result; - SetOverlayActive(FALSE); + game.request_active_or_moving = TRUE; + + SetOverlayEnabled(FALSE); if (global.use_envelope_request) result = RequestEnvelope(text, req_state); else result = RequestDoor(text, req_state); - SetOverlayActive(overlay_active); + SetOverlayEnabled(overlay_enabled); + + game.request_active_or_moving = FALSE; return result; } @@ -4883,7 +4940,7 @@ void InitGraphicCompatibilityInfo_Doors(void) struct Rect *door_rect = &door_rect_list[door_index]; boolean door_gfx_redefined = FALSE; - /* check if any door part graphic definitions have been redefined */ + // check if any door part graphic definitions have been redefined for (j = 0; door_part_controls[j].door_token != -1; j++) { @@ -4894,7 +4951,7 @@ void InitGraphicCompatibilityInfo_Doors(void) door_gfx_redefined = TRUE; } - /* check for old-style door graphic/animation modifications */ + // check for old-style door graphic/animation modifications if (!door_gfx_redefined) { @@ -4910,7 +4967,7 @@ void InitGraphicCompatibilityInfo_Doors(void) struct GraphicInfo *g_part_2 = &graphic_info[part_2]; int num_door_steps, num_panel_steps; - /* remove door part graphics other than the two default wings */ + // remove door part graphics other than the two default wings for (j = 0; door_part_controls[j].door_token != -1; j++) { @@ -4922,7 +4979,7 @@ void InitGraphicCompatibilityInfo_Doors(void) g->bitmap = NULL; } - /* set graphics and screen positions of the default wings */ + // set graphics and screen positions of the default wings g_part_1->width = door_rect->width; g_part_1->height = door_rect->height; @@ -4954,18 +5011,18 @@ void InitGraphicCompatibilityInfo_Doors(void) door->part_2.y += door_rect->height - door->height; } - /* set animation delays for the default wings and panels */ + // set animation delays for the default wings and panels door->part_1.step_delay = door->step_delay; door->part_2.step_delay = door->step_delay; door->panel.step_delay = door->step_delay; - /* set animation draw order for the default wings */ + // set animation draw order for the default wings - door->part_1.sort_priority = 2; /* draw left wing over ... */ - door->part_2.sort_priority = 1; /* ... right wing */ + door->part_1.sort_priority = 2; // draw left wing over ... + door->part_2.sort_priority = 1; // ... right wing - /* set animation draw offset for the default wings */ + // set animation draw offset for the default wings if (door->anim_mode & ANIM_HORIZONTAL) { @@ -4986,7 +5043,7 @@ void InitGraphicCompatibilityInfo_Doors(void) num_door_steps = g_part_1->height / door->step_offset; } - /* set animation draw offset for the default panels */ + // set animation draw offset for the default panels if (door->step_offset > 1) { @@ -5015,7 +5072,7 @@ void InitDoors(void) struct DoorPartControlInfo *dpc = &door_part_controls[i]; struct DoorPartOrderInfo *dpo = &door_part_order[i]; - /* initialize "start_step_opening" and "start_step_closing", if needed */ + // initialize "start_step_opening" and "start_step_closing", if needed if (dpc->pos->start_step_opening == 0 && dpc->pos->start_step_closing == 0) { @@ -5023,12 +5080,12 @@ void InitDoors(void) dpc->pos->start_step_closing = dpc->pos->start_step; } - /* fill structure for door part draw order (sorted below) */ + // fill structure for door part draw order (sorted below) dpo->nr = i; dpo->sort_priority = dpc->pos->sort_priority; } - /* sort door part controls according to sort_priority and graphic number */ + // sort door part controls according to sort_priority and graphic number qsort(door_part_order, MAX_DOOR_PARTS, sizeof(struct DoorPartOrderInfo), compareDoorPartOrderInfo); } @@ -5220,7 +5277,7 @@ unsigned int MoveDoor(unsigned int door_state) } else { - /* opening door sound has priority over simultaneously closing door */ + // opening door sound has priority over simultaneously closing door if (door_state & (DOOR_OPEN_1 | DOOR_OPEN_2)) { PlayMenuSoundStereo(SND_DOOR_OPENING, SOUND_MIDDLE); @@ -5339,7 +5396,7 @@ unsigned int MoveDoor(unsigned int door_state) if (width > door_rect->width) width = door_rect->width; - // printf("::: k == %d [%d] \n", k, start_step); + // Debug("tools:MoveDoor", "k == %d [%d]", k, start_step); } if (pos->step_yoffset < 0) // door part on bottom side @@ -5408,7 +5465,7 @@ unsigned int MoveDoor(unsigned int door_state) current_move_delay += max_step_delay; - /* prevent OS (Windows) from complaining about program not responding */ + // prevent OS (Windows) from complaining about program not responding CheckQuitEvent(); } @@ -5418,7 +5475,7 @@ unsigned int MoveDoor(unsigned int door_state) if (!(door_state & DOOR_NO_DELAY)) { - /* wait for specified door action post delay */ + // wait for specified door action post delay if (door_state & DOOR_ACTION_1 && door_state & DOOR_ACTION_2) door_delay_value = MAX(door_1.post_delay, door_2.post_delay); else if (door_state & DOOR_ACTION_1) @@ -5482,7 +5539,7 @@ void DrawSpecialEditorDoor(void) if (!useSpecialEditorDoor()) return; - /* draw bigger level editor toolbox window */ + // draw bigger level editor toolbox window BlitBitmap(gfx1->bitmap, drawto, gfx1->src_x, gfx1->src_y, top_border_width, top_border_height, ex, ey - top_border_height); BlitBitmap(graphic_info[IMG_GLOBAL_BORDER].bitmap, drawto, ex, vy, @@ -5506,7 +5563,7 @@ void UndrawSpecialEditorDoor(void) if (!useSpecialEditorDoor()) return; - /* draw normal tape recorder window */ + // draw normal tape recorder window if (graphic_info[IMG_GLOBAL_BORDER].bitmap) { BlitBitmap(graphic_info[IMG_GLOBAL_BORDER].bitmap, drawto, @@ -5526,43 +5583,56 @@ void UndrawSpecialEditorDoor(void) } -/* ---------- new tool button stuff ---------------------------------------- */ +// ---------- new tool button stuff ------------------------------------------- static struct { int graphic; struct TextPosInfo *pos; int gadget_id; + boolean is_touch_button; char *infotext; } toolbutton_info[NUM_TOOL_BUTTONS] = { { IMG_GFX_REQUEST_BUTTON_YES, &request.button.yes, - TOOL_CTRL_ID_YES, "yes" + TOOL_CTRL_ID_YES, FALSE, "yes" }, { IMG_GFX_REQUEST_BUTTON_NO, &request.button.no, - TOOL_CTRL_ID_NO, "no" + TOOL_CTRL_ID_NO, FALSE, "no" }, { IMG_GFX_REQUEST_BUTTON_CONFIRM, &request.button.confirm, - TOOL_CTRL_ID_CONFIRM, "confirm" + TOOL_CTRL_ID_CONFIRM, FALSE, "confirm" }, { IMG_GFX_REQUEST_BUTTON_PLAYER_1, &request.button.player_1, - TOOL_CTRL_ID_PLAYER_1, "player 1" + TOOL_CTRL_ID_PLAYER_1, FALSE, "player 1" }, { IMG_GFX_REQUEST_BUTTON_PLAYER_2, &request.button.player_2, - TOOL_CTRL_ID_PLAYER_2, "player 2" + TOOL_CTRL_ID_PLAYER_2, FALSE, "player 2" }, { IMG_GFX_REQUEST_BUTTON_PLAYER_3, &request.button.player_3, - TOOL_CTRL_ID_PLAYER_3, "player 3" + TOOL_CTRL_ID_PLAYER_3, FALSE, "player 3" }, { IMG_GFX_REQUEST_BUTTON_PLAYER_4, &request.button.player_4, - TOOL_CTRL_ID_PLAYER_4, "player 4" + TOOL_CTRL_ID_PLAYER_4, FALSE, "player 4" + }, + { + IMG_GFX_REQUEST_BUTTON_TOUCH_YES, &request.button.touch_yes, + TOOL_CTRL_ID_TOUCH_YES, TRUE, "yes" + }, + { + IMG_GFX_REQUEST_BUTTON_TOUCH_NO, &request.button.touch_no, + TOOL_CTRL_ID_TOUCH_NO, TRUE, "no" + }, + { + IMG_GFX_REQUEST_BUTTON_TOUCH_CONFIRM, &request.button.touch_confirm, + TOOL_CTRL_ID_TOUCH_CONFIRM, TRUE, "confirm" } }; @@ -5579,8 +5649,9 @@ void CreateToolButtons(void) 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; + boolean is_touch_button = toolbutton_info[i].is_touch_button; + int base_x = (is_touch_button ? 0 : DX); + int base_y = (is_touch_button ? 0 : DY); int gd_x = gfx->src_x; int gd_y = gfx->src_y; int gd_xp = gfx->src_x + gfx->pressed_xoffset; @@ -5589,9 +5660,9 @@ void CreateToolButtons(void) int y = pos->y; int id = i; - if (global.use_envelope_request) + if (global.use_envelope_request && !is_touch_button) { - setRequestPosition(&dx, &dy, TRUE); + setRequestPosition(&base_x, &base_y, TRUE); // check if request buttons are outside of envelope and fix, if needed if (x < 0 || x + gfx->width > request.width || @@ -5638,8 +5709,8 @@ void CreateToolButtons(void) gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_IMAGE_ID, graphic, GDI_INFO_TEXT, toolbutton_info[i].infotext, - GDI_X, dx + x, - GDI_Y, dy + y, + GDI_X, base_x + x, + GDI_Y, base_y + y, GDI_WIDTH, gfx->width, GDI_HEIGHT, gfx->height, GDI_TYPE, GD_TYPE_NORMAL_BUTTON, @@ -5651,12 +5722,13 @@ void CreateToolButtons(void) GDI_DECORATION_SIZE, pos->size, pos->size, GDI_DECORATION_SHIFTING, 1, 1, GDI_DIRECT_DRAW, FALSE, + GDI_OVERLAY_TOUCH_BUTTON, is_touch_button, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_ACTION, HandleToolButtons, GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); tool_gadget[id] = gi; } @@ -5686,414 +5758,289 @@ static void HandleToolButtons(struct GadgetInfo *gi) static struct Mapping_EM_to_RND_object { int element_em; - boolean is_rnd_to_em_mapping; /* unique mapping EM <-> RND */ - boolean is_backside; /* backside of moving element */ + boolean is_rnd_to_em_mapping; // unique mapping EM <-> RND + boolean is_backside; // backside of moving element int element_rnd; int action; int direction; } -em_object_mapping_list[] = +em_object_mapping_list[GAME_TILE_MAX + 1] = { { - Xblank, TRUE, FALSE, + Zborder, FALSE, FALSE, EL_EMPTY, -1, -1 }, { - Yacid_splash_eB, FALSE, FALSE, - EL_ACID_SPLASH_RIGHT, -1, -1 - }, - { - Yacid_splash_wB, FALSE, FALSE, - EL_ACID_SPLASH_LEFT, -1, -1 + Zplayer, FALSE, FALSE, + EL_EMPTY, -1, -1 }, -#ifdef EM_ENGINE_BAD_ROLL { - Xstone_force_e, FALSE, FALSE, - EL_ROCK, -1, MV_BIT_RIGHT + Zbug, FALSE, FALSE, + EL_EMPTY, -1, -1 }, { - Xstone_force_w, FALSE, FALSE, - EL_ROCK, -1, MV_BIT_LEFT + Ztank, FALSE, FALSE, + EL_EMPTY, -1, -1 }, { - Xnut_force_e, FALSE, FALSE, - EL_NUT, -1, MV_BIT_RIGHT + Zeater, FALSE, FALSE, + EL_EMPTY, -1, -1 }, { - Xnut_force_w, FALSE, FALSE, - EL_NUT, -1, MV_BIT_LEFT + Zdynamite, FALSE, FALSE, + EL_EMPTY, -1, -1 }, { - Xspring_force_e, FALSE, FALSE, - EL_SPRING, -1, MV_BIT_RIGHT + Zboom, FALSE, FALSE, + EL_EMPTY, -1, -1 }, + { - Xspring_force_w, FALSE, FALSE, - EL_SPRING, -1, MV_BIT_LEFT + Xchain, FALSE, FALSE, + EL_DEFAULT, ACTION_EXPLODING, -1 }, { - Xemerald_force_e, FALSE, FALSE, - EL_EMERALD, -1, MV_BIT_RIGHT + Xboom_bug, FALSE, FALSE, + EL_BUG, ACTION_EXPLODING, -1 }, { - Xemerald_force_w, FALSE, FALSE, - EL_EMERALD, -1, MV_BIT_LEFT + Xboom_tank, FALSE, FALSE, + EL_SPACESHIP, ACTION_EXPLODING, -1 }, { - Xdiamond_force_e, FALSE, FALSE, - EL_DIAMOND, -1, MV_BIT_RIGHT + Xboom_android, FALSE, FALSE, + EL_EMC_ANDROID, ACTION_OTHER, -1 }, { - Xdiamond_force_w, FALSE, FALSE, - EL_DIAMOND, -1, MV_BIT_LEFT + Xboom_1, FALSE, FALSE, + EL_DEFAULT, ACTION_EXPLODING, -1 }, { - Xbomb_force_e, FALSE, FALSE, - EL_BOMB, -1, MV_BIT_RIGHT + Xboom_2, FALSE, FALSE, + EL_DEFAULT, ACTION_EXPLODING, -1 }, + { - Xbomb_force_w, FALSE, FALSE, - EL_BOMB, -1, MV_BIT_LEFT + Xblank, TRUE, FALSE, + EL_EMPTY, -1, -1 }, -#endif /* EM_ENGINE_BAD_ROLL */ { - Xstone, TRUE, FALSE, - EL_ROCK, -1, -1 + Xsplash_e, FALSE, FALSE, + EL_ACID_SPLASH_RIGHT, -1, -1 }, { - Xstone_pause, FALSE, FALSE, - EL_ROCK, -1, -1 + Xsplash_w, FALSE, FALSE, + EL_ACID_SPLASH_LEFT, -1, -1 }, + { - Xstone_fall, FALSE, FALSE, - EL_ROCK, -1, -1 + Xplant, TRUE, FALSE, + EL_EMC_PLANT, -1, -1 }, { - Ystone_s, FALSE, FALSE, - EL_ROCK, ACTION_FALLING, -1 + Yplant, FALSE, FALSE, + EL_EMC_PLANT, -1, -1 }, + { - Ystone_sB, FALSE, TRUE, - EL_ROCK, ACTION_FALLING, -1 + Xacid_1, TRUE, FALSE, + EL_ACID, -1, -1 }, { - Ystone_e, FALSE, FALSE, - EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT + Xacid_2, FALSE, FALSE, + EL_ACID, -1, -1 }, { - Ystone_eB, FALSE, TRUE, - EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT + Xacid_3, FALSE, FALSE, + EL_ACID, -1, -1 }, { - Ystone_w, FALSE, FALSE, - EL_ROCK, ACTION_MOVING, MV_BIT_LEFT + Xacid_4, FALSE, FALSE, + EL_ACID, -1, -1 }, { - Ystone_wB, FALSE, TRUE, - EL_ROCK, ACTION_MOVING, MV_BIT_LEFT + Xacid_5, FALSE, FALSE, + EL_ACID, -1, -1 }, { - Xnut, TRUE, FALSE, - EL_NUT, -1, -1 + Xacid_6, FALSE, FALSE, + EL_ACID, -1, -1 }, { - Xnut_pause, FALSE, FALSE, - EL_NUT, -1, -1 + Xacid_7, FALSE, FALSE, + EL_ACID, -1, -1 }, { - Xnut_fall, FALSE, FALSE, - EL_NUT, -1, -1 + Xacid_8, FALSE, FALSE, + EL_ACID, -1, -1 }, + { - Ynut_s, FALSE, FALSE, - EL_NUT, ACTION_FALLING, -1 + Xfake_acid_1, TRUE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { - Ynut_sB, FALSE, TRUE, - EL_NUT, ACTION_FALLING, -1 + Xfake_acid_2, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { - Ynut_e, FALSE, FALSE, - EL_NUT, ACTION_MOVING, MV_BIT_RIGHT + Xfake_acid_3, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { - Ynut_eB, FALSE, TRUE, - EL_NUT, ACTION_MOVING, MV_BIT_RIGHT + Xfake_acid_4, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { - Ynut_w, FALSE, FALSE, - EL_NUT, ACTION_MOVING, MV_BIT_LEFT + Xfake_acid_5, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { - Ynut_wB, FALSE, TRUE, - EL_NUT, ACTION_MOVING, MV_BIT_LEFT + Xfake_acid_6, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { - Xbug_n, TRUE, FALSE, - EL_BUG_UP, -1, -1 + Xfake_acid_7, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { - Xbug_e, TRUE, FALSE, - EL_BUG_RIGHT, -1, -1 + Xfake_acid_8, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, + { - Xbug_s, TRUE, FALSE, - EL_BUG_DOWN, -1, -1 + Xfake_acid_1_player, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { - Xbug_w, TRUE, FALSE, - EL_BUG_LEFT, -1, -1 + Xfake_acid_2_player, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { - Xbug_gon, FALSE, FALSE, - EL_BUG_UP, -1, -1 + Xfake_acid_3_player, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { - Xbug_goe, FALSE, FALSE, - EL_BUG_RIGHT, -1, -1 + Xfake_acid_4_player, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { - Xbug_gos, FALSE, FALSE, - EL_BUG_DOWN, -1, -1 + Xfake_acid_5_player, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { - Xbug_gow, FALSE, FALSE, - EL_BUG_LEFT, -1, -1 + Xfake_acid_6_player, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { - Ybug_n, FALSE, FALSE, - EL_BUG, ACTION_MOVING, MV_BIT_UP + Xfake_acid_7_player, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, { - Ybug_nB, FALSE, TRUE, - EL_BUG, ACTION_MOVING, MV_BIT_UP + Xfake_acid_8_player, FALSE, FALSE, + EL_EMC_FAKE_ACID, -1, -1 }, + { - Ybug_e, FALSE, FALSE, - EL_BUG, ACTION_MOVING, MV_BIT_RIGHT + Xgrass, TRUE, FALSE, + EL_EMC_GRASS, -1, -1 }, { - Ybug_eB, FALSE, TRUE, - EL_BUG, ACTION_MOVING, MV_BIT_RIGHT + Ygrass_nB, FALSE, FALSE, + EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_UP }, { - Ybug_s, FALSE, FALSE, - EL_BUG, ACTION_MOVING, MV_BIT_DOWN + Ygrass_eB, FALSE, FALSE, + EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_RIGHT }, { - Ybug_sB, FALSE, TRUE, - EL_BUG, ACTION_MOVING, MV_BIT_DOWN + Ygrass_sB, FALSE, FALSE, + EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_DOWN }, { - Ybug_w, FALSE, FALSE, - EL_BUG, ACTION_MOVING, MV_BIT_LEFT + Ygrass_wB, FALSE, FALSE, + EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_LEFT }, + { - Ybug_wB, FALSE, TRUE, - EL_BUG, ACTION_MOVING, MV_BIT_LEFT + Xdirt, TRUE, FALSE, + EL_SAND, -1, -1 }, { - Ybug_w_n, FALSE, FALSE, - EL_BUG, ACTION_TURNING_FROM_LEFT, MV_BIT_UP + Ydirt_nB, FALSE, FALSE, + EL_SAND, ACTION_DIGGING, MV_BIT_UP }, { - Ybug_n_e, FALSE, FALSE, - EL_BUG, ACTION_TURNING_FROM_UP, MV_BIT_RIGHT + Ydirt_eB, FALSE, FALSE, + EL_SAND, ACTION_DIGGING, MV_BIT_RIGHT }, { - Ybug_e_s, FALSE, FALSE, - EL_BUG, ACTION_TURNING_FROM_RIGHT, MV_BIT_DOWN + Ydirt_sB, FALSE, FALSE, + EL_SAND, ACTION_DIGGING, MV_BIT_DOWN }, { - Ybug_s_w, FALSE, FALSE, - EL_BUG, ACTION_TURNING_FROM_DOWN, MV_BIT_LEFT + Ydirt_wB, FALSE, FALSE, + EL_SAND, ACTION_DIGGING, MV_BIT_LEFT }, + { - Ybug_e_n, FALSE, FALSE, - EL_BUG, ACTION_TURNING_FROM_RIGHT, MV_BIT_UP + Xandroid, TRUE, FALSE, + EL_EMC_ANDROID, ACTION_ACTIVE, -1 }, { - Ybug_s_e, FALSE, FALSE, - EL_BUG, ACTION_TURNING_FROM_DOWN, MV_BIT_RIGHT + Xandroid_1_n, FALSE, FALSE, + EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_UP }, { - Ybug_w_s, FALSE, FALSE, - EL_BUG, ACTION_TURNING_FROM_LEFT, MV_BIT_DOWN + Xandroid_2_n, FALSE, FALSE, + EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_UP }, { - Ybug_n_w, FALSE, FALSE, - EL_BUG, ACTION_TURNING_FROM_UP, MV_BIT_LEFT + Xandroid_1_e, FALSE, FALSE, + EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_RIGHT }, { - Ybug_stone, FALSE, FALSE, - EL_BUG, ACTION_SMASHED_BY_ROCK, -1 + Xandroid_2_e, FALSE, FALSE, + EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_RIGHT }, { - Ybug_spring, FALSE, FALSE, - EL_BUG, ACTION_SMASHED_BY_SPRING, -1 + Xandroid_1_w, FALSE, FALSE, + EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_LEFT }, { - Xtank_n, TRUE, FALSE, - EL_SPACESHIP_UP, -1, -1 + Xandroid_2_w, FALSE, FALSE, + EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_LEFT }, { - Xtank_e, TRUE, FALSE, - EL_SPACESHIP_RIGHT, -1, -1 + Xandroid_1_s, FALSE, FALSE, + EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_DOWN }, { - Xtank_s, TRUE, FALSE, - EL_SPACESHIP_DOWN, -1, -1 + Xandroid_2_s, FALSE, FALSE, + EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_DOWN }, { - Xtank_w, TRUE, FALSE, - EL_SPACESHIP_LEFT, -1, -1 + Yandroid_n, FALSE, FALSE, + EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_UP }, { - Xtank_gon, FALSE, FALSE, - EL_SPACESHIP_UP, -1, -1 + Yandroid_nB, FALSE, TRUE, + EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_UP }, { - Xtank_goe, FALSE, FALSE, - EL_SPACESHIP_RIGHT, -1, -1 + Yandroid_ne, FALSE, FALSE, + EL_EMC_ANDROID, ACTION_GROWING, MV_BIT_UPRIGHT }, { - Xtank_gos, FALSE, FALSE, - EL_SPACESHIP_DOWN, -1, -1 + Yandroid_neB, FALSE, TRUE, + EL_EMC_ANDROID, ACTION_SHRINKING, MV_BIT_UPRIGHT }, { - Xtank_gow, FALSE, FALSE, - EL_SPACESHIP_LEFT, -1, -1 - }, - { - Ytank_n, FALSE, FALSE, - EL_SPACESHIP, ACTION_MOVING, MV_BIT_UP - }, - { - Ytank_nB, FALSE, TRUE, - EL_SPACESHIP, ACTION_MOVING, MV_BIT_UP - }, - { - Ytank_e, FALSE, FALSE, - EL_SPACESHIP, ACTION_MOVING, MV_BIT_RIGHT - }, - { - Ytank_eB, FALSE, TRUE, - EL_SPACESHIP, ACTION_MOVING, MV_BIT_RIGHT - }, - { - Ytank_s, FALSE, FALSE, - EL_SPACESHIP, ACTION_MOVING, MV_BIT_DOWN - }, - { - Ytank_sB, FALSE, TRUE, - EL_SPACESHIP, ACTION_MOVING, MV_BIT_DOWN - }, - { - Ytank_w, FALSE, FALSE, - EL_SPACESHIP, ACTION_MOVING, MV_BIT_LEFT - }, - { - Ytank_wB, FALSE, TRUE, - EL_SPACESHIP, ACTION_MOVING, MV_BIT_LEFT - }, - { - Ytank_w_n, FALSE, FALSE, - EL_SPACESHIP, ACTION_TURNING_FROM_LEFT, MV_BIT_UP - }, - { - Ytank_n_e, FALSE, FALSE, - EL_SPACESHIP, ACTION_TURNING_FROM_UP, MV_BIT_RIGHT - }, - { - Ytank_e_s, FALSE, FALSE, - EL_SPACESHIP, ACTION_TURNING_FROM_RIGHT, MV_BIT_DOWN - }, - { - Ytank_s_w, FALSE, FALSE, - EL_SPACESHIP, ACTION_TURNING_FROM_DOWN, MV_BIT_LEFT - }, - { - Ytank_e_n, FALSE, FALSE, - EL_SPACESHIP, ACTION_TURNING_FROM_RIGHT, MV_BIT_UP - }, - { - Ytank_s_e, FALSE, FALSE, - EL_SPACESHIP, ACTION_TURNING_FROM_DOWN, MV_BIT_RIGHT - }, - { - Ytank_w_s, FALSE, FALSE, - EL_SPACESHIP, ACTION_TURNING_FROM_LEFT, MV_BIT_DOWN - }, - { - Ytank_n_w, FALSE, FALSE, - EL_SPACESHIP, ACTION_TURNING_FROM_UP, MV_BIT_LEFT - }, - { - Ytank_stone, FALSE, FALSE, - EL_SPACESHIP, ACTION_SMASHED_BY_ROCK, -1 - }, - { - Ytank_spring, FALSE, FALSE, - EL_SPACESHIP, ACTION_SMASHED_BY_SPRING, -1 - }, - { - Xandroid, TRUE, FALSE, - EL_EMC_ANDROID, ACTION_ACTIVE, -1 - }, - { - Xandroid_1_n, FALSE, FALSE, - EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_UP - }, - { - Xandroid_2_n, FALSE, FALSE, - EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_UP - }, - { - Xandroid_1_e, FALSE, FALSE, - EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_RIGHT - }, - { - Xandroid_2_e, FALSE, FALSE, - EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_RIGHT - }, - { - Xandroid_1_w, FALSE, FALSE, - EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_LEFT - }, - { - Xandroid_2_w, FALSE, FALSE, - EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_LEFT - }, - { - Xandroid_1_s, FALSE, FALSE, - EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_DOWN - }, - { - Xandroid_2_s, FALSE, FALSE, - EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_DOWN - }, - { - Yandroid_n, FALSE, FALSE, - EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_UP - }, - { - Yandroid_nB, FALSE, TRUE, - EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_UP - }, - { - Yandroid_ne, FALSE, FALSE, - EL_EMC_ANDROID, ACTION_GROWING, MV_BIT_UPRIGHT - }, - { - Yandroid_neB, FALSE, TRUE, - EL_EMC_ANDROID, ACTION_SHRINKING, MV_BIT_UPRIGHT - }, - { - Yandroid_e, FALSE, FALSE, - EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_RIGHT + Yandroid_e, FALSE, FALSE, + EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_RIGHT }, { Yandroid_eB, FALSE, TRUE, @@ -6139,66 +6086,7 @@ em_object_mapping_list[] = Yandroid_nwB, FALSE, TRUE, EL_EMC_ANDROID, ACTION_SHRINKING, MV_BIT_UPLEFT }, - { - Xspring, TRUE, FALSE, - EL_SPRING, -1, -1 - }, - { - Xspring_pause, FALSE, FALSE, - EL_SPRING, -1, -1 - }, - { - Xspring_e, FALSE, FALSE, - EL_SPRING, -1, -1 - }, - { - Xspring_w, FALSE, FALSE, - EL_SPRING, -1, -1 - }, - { - Xspring_fall, FALSE, FALSE, - EL_SPRING, -1, -1 - }, - { - Yspring_s, FALSE, FALSE, - EL_SPRING, ACTION_FALLING, -1 - }, - { - Yspring_sB, FALSE, TRUE, - EL_SPRING, ACTION_FALLING, -1 - }, - { - Yspring_e, FALSE, FALSE, - EL_SPRING, ACTION_MOVING, MV_BIT_RIGHT - }, - { - Yspring_eB, FALSE, TRUE, - EL_SPRING, ACTION_MOVING, MV_BIT_RIGHT - }, - { - Yspring_w, FALSE, FALSE, - EL_SPRING, ACTION_MOVING, MV_BIT_LEFT - }, - { - Yspring_wB, FALSE, TRUE, - EL_SPRING, ACTION_MOVING, MV_BIT_LEFT - }, - { - Yspring_kill_e, FALSE, FALSE, - EL_SPRING, ACTION_EATING, MV_BIT_RIGHT - }, - { - Yspring_kill_eB, FALSE, TRUE, - EL_SPRING, ACTION_EATING, MV_BIT_RIGHT - }, - { - Yspring_kill_w, FALSE, FALSE, - EL_SPRING, ACTION_EATING, MV_BIT_LEFT - }, - { - Yspring_kill_wB, FALSE, TRUE, - EL_SPRING, ACTION_EATING, MV_BIT_LEFT - }, + { Xeater_n, TRUE, FALSE, EL_YAMYAM_UP, -1, -1 @@ -6255,6 +6143,7 @@ em_object_mapping_list[] = Yeater_spring, FALSE, FALSE, EL_YAMYAM, ACTION_SMASHED_BY_SPRING, -1 }, + { Xalien, TRUE, FALSE, EL_ROBOT, -1, -1 @@ -6303,134 +6192,348 @@ em_object_mapping_list[] = Yalien_spring, FALSE, FALSE, EL_ROBOT, ACTION_SMASHED_BY_SPRING, -1 }, + { - Xemerald, TRUE, FALSE, - EL_EMERALD, -1, -1 + Xbug_1_n, TRUE, FALSE, + EL_BUG_UP, -1, -1 }, { - Xemerald_pause, FALSE, FALSE, - EL_EMERALD, -1, -1 + Xbug_1_e, TRUE, FALSE, + EL_BUG_RIGHT, -1, -1 }, { - Xemerald_fall, FALSE, FALSE, - EL_EMERALD, -1, -1 + Xbug_1_s, TRUE, FALSE, + EL_BUG_DOWN, -1, -1 }, { - Xemerald_shine, FALSE, FALSE, - EL_EMERALD, ACTION_TWINKLING, -1 + Xbug_1_w, TRUE, FALSE, + EL_BUG_LEFT, -1, -1 }, { - Yemerald_s, FALSE, FALSE, - EL_EMERALD, ACTION_FALLING, -1 + Xbug_2_n, FALSE, FALSE, + EL_BUG_UP, -1, -1 }, { - Yemerald_sB, FALSE, TRUE, - EL_EMERALD, ACTION_FALLING, -1 + Xbug_2_e, FALSE, FALSE, + EL_BUG_RIGHT, -1, -1 }, { - Yemerald_e, FALSE, FALSE, - EL_EMERALD, ACTION_MOVING, MV_BIT_RIGHT + Xbug_2_s, FALSE, FALSE, + EL_BUG_DOWN, -1, -1 }, { - Yemerald_eB, FALSE, TRUE, - EL_EMERALD, ACTION_MOVING, MV_BIT_RIGHT + Xbug_2_w, FALSE, FALSE, + EL_BUG_LEFT, -1, -1 }, { - Yemerald_w, FALSE, FALSE, - EL_EMERALD, ACTION_MOVING, MV_BIT_LEFT + Ybug_n, FALSE, FALSE, + EL_BUG, ACTION_MOVING, MV_BIT_UP }, { - Yemerald_wB, FALSE, TRUE, - EL_EMERALD, ACTION_MOVING, MV_BIT_LEFT + Ybug_nB, FALSE, TRUE, + EL_BUG, ACTION_MOVING, MV_BIT_UP }, { - Yemerald_eat, FALSE, FALSE, - EL_EMERALD, ACTION_COLLECTING, -1 + Ybug_e, FALSE, FALSE, + EL_BUG, ACTION_MOVING, MV_BIT_RIGHT }, { - Yemerald_stone, FALSE, FALSE, - EL_NUT, ACTION_BREAKING, -1 + Ybug_eB, FALSE, TRUE, + EL_BUG, ACTION_MOVING, MV_BIT_RIGHT }, { - Xdiamond, TRUE, FALSE, - EL_DIAMOND, -1, -1 + Ybug_s, FALSE, FALSE, + EL_BUG, ACTION_MOVING, MV_BIT_DOWN }, { - Xdiamond_pause, FALSE, FALSE, - EL_DIAMOND, -1, -1 + Ybug_sB, FALSE, TRUE, + EL_BUG, ACTION_MOVING, MV_BIT_DOWN }, { - Xdiamond_fall, FALSE, FALSE, - EL_DIAMOND, -1, -1 + Ybug_w, FALSE, FALSE, + EL_BUG, ACTION_MOVING, MV_BIT_LEFT }, { - Xdiamond_shine, FALSE, FALSE, - EL_DIAMOND, ACTION_TWINKLING, -1 + Ybug_wB, FALSE, TRUE, + EL_BUG, ACTION_MOVING, MV_BIT_LEFT }, { - Ydiamond_s, FALSE, FALSE, - EL_DIAMOND, ACTION_FALLING, -1 + Ybug_w_n, FALSE, FALSE, + EL_BUG, ACTION_TURNING_FROM_LEFT, MV_BIT_UP }, { - Ydiamond_sB, FALSE, TRUE, - EL_DIAMOND, ACTION_FALLING, -1 + Ybug_n_e, FALSE, FALSE, + EL_BUG, ACTION_TURNING_FROM_UP, MV_BIT_RIGHT }, { - Ydiamond_e, FALSE, FALSE, - EL_DIAMOND, ACTION_MOVING, MV_BIT_RIGHT + Ybug_e_s, FALSE, FALSE, + EL_BUG, ACTION_TURNING_FROM_RIGHT, MV_BIT_DOWN }, { - Ydiamond_eB, FALSE, TRUE, - EL_DIAMOND, ACTION_MOVING, MV_BIT_RIGHT + Ybug_s_w, FALSE, FALSE, + EL_BUG, ACTION_TURNING_FROM_DOWN, MV_BIT_LEFT }, { - Ydiamond_w, FALSE, FALSE, - EL_DIAMOND, ACTION_MOVING, MV_BIT_LEFT + Ybug_e_n, FALSE, FALSE, + EL_BUG, ACTION_TURNING_FROM_RIGHT, MV_BIT_UP + }, + { + Ybug_s_e, FALSE, FALSE, + EL_BUG, ACTION_TURNING_FROM_DOWN, MV_BIT_RIGHT + }, + { + Ybug_w_s, FALSE, FALSE, + EL_BUG, ACTION_TURNING_FROM_LEFT, MV_BIT_DOWN + }, + { + Ybug_n_w, FALSE, FALSE, + EL_BUG, ACTION_TURNING_FROM_UP, MV_BIT_LEFT + }, + { + Ybug_stone, FALSE, FALSE, + EL_BUG, ACTION_SMASHED_BY_ROCK, -1 + }, + { + Ybug_spring, FALSE, FALSE, + EL_BUG, ACTION_SMASHED_BY_SPRING, -1 + }, + + { + Xtank_1_n, TRUE, FALSE, + EL_SPACESHIP_UP, -1, -1 + }, + { + Xtank_1_e, TRUE, FALSE, + EL_SPACESHIP_RIGHT, -1, -1 + }, + { + Xtank_1_s, TRUE, FALSE, + EL_SPACESHIP_DOWN, -1, -1 + }, + { + Xtank_1_w, TRUE, FALSE, + EL_SPACESHIP_LEFT, -1, -1 + }, + { + Xtank_2_n, FALSE, FALSE, + EL_SPACESHIP_UP, -1, -1 + }, + { + Xtank_2_e, FALSE, FALSE, + EL_SPACESHIP_RIGHT, -1, -1 + }, + { + Xtank_2_s, FALSE, FALSE, + EL_SPACESHIP_DOWN, -1, -1 + }, + { + Xtank_2_w, FALSE, FALSE, + EL_SPACESHIP_LEFT, -1, -1 + }, + { + Ytank_n, FALSE, FALSE, + EL_SPACESHIP, ACTION_MOVING, MV_BIT_UP + }, + { + Ytank_nB, FALSE, TRUE, + EL_SPACESHIP, ACTION_MOVING, MV_BIT_UP + }, + { + Ytank_e, FALSE, FALSE, + EL_SPACESHIP, ACTION_MOVING, MV_BIT_RIGHT + }, + { + Ytank_eB, FALSE, TRUE, + EL_SPACESHIP, ACTION_MOVING, MV_BIT_RIGHT + }, + { + Ytank_s, FALSE, FALSE, + EL_SPACESHIP, ACTION_MOVING, MV_BIT_DOWN + }, + { + Ytank_sB, FALSE, TRUE, + EL_SPACESHIP, ACTION_MOVING, MV_BIT_DOWN + }, + { + Ytank_w, FALSE, FALSE, + EL_SPACESHIP, ACTION_MOVING, MV_BIT_LEFT + }, + { + Ytank_wB, FALSE, TRUE, + EL_SPACESHIP, ACTION_MOVING, MV_BIT_LEFT + }, + { + Ytank_w_n, FALSE, FALSE, + EL_SPACESHIP, ACTION_TURNING_FROM_LEFT, MV_BIT_UP + }, + { + Ytank_n_e, FALSE, FALSE, + EL_SPACESHIP, ACTION_TURNING_FROM_UP, MV_BIT_RIGHT + }, + { + Ytank_e_s, FALSE, FALSE, + EL_SPACESHIP, ACTION_TURNING_FROM_RIGHT, MV_BIT_DOWN + }, + { + Ytank_s_w, FALSE, FALSE, + EL_SPACESHIP, ACTION_TURNING_FROM_DOWN, MV_BIT_LEFT + }, + { + Ytank_e_n, FALSE, FALSE, + EL_SPACESHIP, ACTION_TURNING_FROM_RIGHT, MV_BIT_UP + }, + { + Ytank_s_e, FALSE, FALSE, + EL_SPACESHIP, ACTION_TURNING_FROM_DOWN, MV_BIT_RIGHT + }, + { + Ytank_w_s, FALSE, FALSE, + EL_SPACESHIP, ACTION_TURNING_FROM_LEFT, MV_BIT_DOWN + }, + { + Ytank_n_w, FALSE, FALSE, + EL_SPACESHIP, ACTION_TURNING_FROM_UP, MV_BIT_LEFT + }, + { + Ytank_stone, FALSE, FALSE, + EL_SPACESHIP, ACTION_SMASHED_BY_ROCK, -1 + }, + { + Ytank_spring, FALSE, FALSE, + EL_SPACESHIP, ACTION_SMASHED_BY_SPRING, -1 + }, + + { + Xemerald, TRUE, FALSE, + EL_EMERALD, -1, -1 + }, + { + Xemerald_pause, FALSE, FALSE, + EL_EMERALD, -1, -1 + }, + { + Xemerald_fall, FALSE, FALSE, + EL_EMERALD, -1, -1 + }, + { + Xemerald_shine, FALSE, FALSE, + EL_EMERALD, ACTION_TWINKLING, -1 + }, + { + Yemerald_s, FALSE, FALSE, + EL_EMERALD, ACTION_FALLING, -1 + }, + { + Yemerald_sB, FALSE, TRUE, + EL_EMERALD, ACTION_FALLING, -1 + }, + { + Yemerald_e, FALSE, FALSE, + EL_EMERALD, ACTION_MOVING, MV_BIT_RIGHT + }, + { + Yemerald_eB, FALSE, TRUE, + EL_EMERALD, ACTION_MOVING, MV_BIT_RIGHT + }, + { + Yemerald_w, FALSE, FALSE, + EL_EMERALD, ACTION_MOVING, MV_BIT_LEFT + }, + { + Yemerald_wB, FALSE, TRUE, + EL_EMERALD, ACTION_MOVING, MV_BIT_LEFT + }, + { + Yemerald_blank, FALSE, FALSE, + EL_EMERALD, ACTION_COLLECTING, -1 + }, + + { + Xdiamond, TRUE, FALSE, + EL_DIAMOND, -1, -1 + }, + { + Xdiamond_pause, FALSE, FALSE, + EL_DIAMOND, -1, -1 + }, + { + Xdiamond_fall, FALSE, FALSE, + EL_DIAMOND, -1, -1 + }, + { + Xdiamond_shine, FALSE, FALSE, + EL_DIAMOND, ACTION_TWINKLING, -1 + }, + { + Ydiamond_s, FALSE, FALSE, + EL_DIAMOND, ACTION_FALLING, -1 + }, + { + Ydiamond_sB, FALSE, TRUE, + EL_DIAMOND, ACTION_FALLING, -1 + }, + { + Ydiamond_e, FALSE, FALSE, + EL_DIAMOND, ACTION_MOVING, MV_BIT_RIGHT + }, + { + Ydiamond_eB, FALSE, TRUE, + EL_DIAMOND, ACTION_MOVING, MV_BIT_RIGHT + }, + { + Ydiamond_w, FALSE, FALSE, + EL_DIAMOND, ACTION_MOVING, MV_BIT_LEFT }, { Ydiamond_wB, FALSE, TRUE, EL_DIAMOND, ACTION_MOVING, MV_BIT_LEFT }, { - Ydiamond_eat, FALSE, FALSE, + Ydiamond_blank, FALSE, FALSE, EL_DIAMOND, ACTION_COLLECTING, -1 }, { Ydiamond_stone, FALSE, FALSE, EL_DIAMOND, ACTION_SMASHED_BY_ROCK, -1 }, + { - Xdrip_fall, TRUE, FALSE, - EL_AMOEBA_DROP, -1, -1 + Xstone, TRUE, FALSE, + EL_ROCK, -1, -1 }, { - Xdrip_stretch, FALSE, FALSE, - EL_AMOEBA_DROP, ACTION_FALLING, -1 + Xstone_pause, FALSE, FALSE, + EL_ROCK, -1, -1 }, { - Xdrip_stretchB, FALSE, TRUE, - EL_AMOEBA_DROP, ACTION_FALLING, -1 + Xstone_fall, FALSE, FALSE, + EL_ROCK, -1, -1 }, { - Xdrip_eat, FALSE, FALSE, - EL_AMOEBA_DROP, ACTION_GROWING, -1 + Ystone_s, FALSE, FALSE, + EL_ROCK, ACTION_FALLING, -1 }, { - Ydrip_s1, FALSE, FALSE, - EL_AMOEBA_DROP, ACTION_FALLING, -1 + Ystone_sB, FALSE, TRUE, + EL_ROCK, ACTION_FALLING, -1 }, { - Ydrip_s1B, FALSE, TRUE, - EL_AMOEBA_DROP, ACTION_FALLING, -1 + Ystone_e, FALSE, FALSE, + EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT }, { - Ydrip_s2, FALSE, FALSE, - EL_AMOEBA_DROP, ACTION_FALLING, -1 + Ystone_eB, FALSE, TRUE, + EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT }, { - Ydrip_s2B, FALSE, TRUE, - EL_AMOEBA_DROP, ACTION_FALLING, -1 + Ystone_w, FALSE, FALSE, + EL_ROCK, ACTION_MOVING, MV_BIT_LEFT }, + { + Ystone_wB, FALSE, TRUE, + EL_ROCK, ACTION_MOVING, MV_BIT_LEFT + }, + { Xbomb, TRUE, FALSE, EL_BOMB, -1, -1 @@ -6468,229 +6571,343 @@ em_object_mapping_list[] = EL_BOMB, ACTION_MOVING, MV_BIT_LEFT }, { - Ybomb_eat, FALSE, FALSE, + Ybomb_blank, FALSE, FALSE, EL_BOMB, ACTION_ACTIVATING, -1 }, + { - Xballoon, TRUE, FALSE, - EL_BALLOON, -1, -1 + Xnut, TRUE, FALSE, + EL_NUT, -1, -1 }, { - Yballoon_n, FALSE, FALSE, - EL_BALLOON, ACTION_MOVING, MV_BIT_UP + Xnut_pause, FALSE, FALSE, + EL_NUT, -1, -1 }, { - Yballoon_nB, FALSE, TRUE, - EL_BALLOON, ACTION_MOVING, MV_BIT_UP + Xnut_fall, FALSE, FALSE, + EL_NUT, -1, -1 }, { - Yballoon_e, FALSE, FALSE, - EL_BALLOON, ACTION_MOVING, MV_BIT_RIGHT + Ynut_s, FALSE, FALSE, + EL_NUT, ACTION_FALLING, -1 }, { - Yballoon_eB, FALSE, TRUE, - EL_BALLOON, ACTION_MOVING, MV_BIT_RIGHT + Ynut_sB, FALSE, TRUE, + EL_NUT, ACTION_FALLING, -1 }, { - Yballoon_s, FALSE, FALSE, - EL_BALLOON, ACTION_MOVING, MV_BIT_DOWN + Ynut_e, FALSE, FALSE, + EL_NUT, ACTION_MOVING, MV_BIT_RIGHT }, { - Yballoon_sB, FALSE, TRUE, - EL_BALLOON, ACTION_MOVING, MV_BIT_DOWN + Ynut_eB, FALSE, TRUE, + EL_NUT, ACTION_MOVING, MV_BIT_RIGHT }, { - Yballoon_w, FALSE, FALSE, - EL_BALLOON, ACTION_MOVING, MV_BIT_LEFT + Ynut_w, FALSE, FALSE, + EL_NUT, ACTION_MOVING, MV_BIT_LEFT }, { - Yballoon_wB, FALSE, TRUE, - EL_BALLOON, ACTION_MOVING, MV_BIT_LEFT + Ynut_wB, FALSE, TRUE, + EL_NUT, ACTION_MOVING, MV_BIT_LEFT }, { - Xgrass, TRUE, FALSE, - EL_EMC_GRASS, -1, -1 + Ynut_stone, FALSE, FALSE, + EL_NUT, ACTION_BREAKING, -1 }, + { - Ygrass_nB, FALSE, FALSE, - EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_UP + Xspring, TRUE, FALSE, + EL_SPRING, -1, -1 }, { - Ygrass_eB, FALSE, FALSE, - EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_RIGHT + Xspring_pause, FALSE, FALSE, + EL_SPRING, -1, -1 }, { - Ygrass_sB, FALSE, FALSE, - EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_DOWN + Xspring_e, TRUE, FALSE, + EL_SPRING_RIGHT, -1, -1 }, { - Ygrass_wB, FALSE, FALSE, - EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_LEFT + Xspring_w, TRUE, FALSE, + EL_SPRING_LEFT, -1, -1 }, { - Xdirt, TRUE, FALSE, - EL_SAND, -1, -1 + Xspring_fall, FALSE, FALSE, + EL_SPRING, -1, -1 }, { - Ydirt_nB, FALSE, FALSE, - EL_SAND, ACTION_DIGGING, MV_BIT_UP + Yspring_s, FALSE, FALSE, + EL_SPRING, ACTION_FALLING, -1 }, { - Ydirt_eB, FALSE, FALSE, - EL_SAND, ACTION_DIGGING, MV_BIT_RIGHT + Yspring_sB, FALSE, TRUE, + EL_SPRING, ACTION_FALLING, -1 }, { - Ydirt_sB, FALSE, FALSE, - EL_SAND, ACTION_DIGGING, MV_BIT_DOWN + Yspring_e, FALSE, FALSE, + EL_SPRING, ACTION_MOVING, MV_BIT_RIGHT }, { - Ydirt_wB, FALSE, FALSE, - EL_SAND, ACTION_DIGGING, MV_BIT_LEFT + Yspring_eB, FALSE, TRUE, + EL_SPRING, ACTION_MOVING, MV_BIT_RIGHT }, { - Xacid_ne, TRUE, FALSE, - EL_ACID_POOL_TOPRIGHT, -1, -1 + Yspring_w, FALSE, FALSE, + EL_SPRING, ACTION_MOVING, MV_BIT_LEFT }, { - Xacid_se, TRUE, FALSE, - EL_ACID_POOL_BOTTOMRIGHT, -1, -1 + Yspring_wB, FALSE, TRUE, + EL_SPRING, ACTION_MOVING, MV_BIT_LEFT }, { - Xacid_s, TRUE, FALSE, - EL_ACID_POOL_BOTTOM, -1, -1 + Yspring_alien_e, FALSE, FALSE, + EL_SPRING, ACTION_EATING, MV_BIT_RIGHT }, { - Xacid_sw, TRUE, FALSE, - EL_ACID_POOL_BOTTOMLEFT, -1, -1 + Yspring_alien_eB, FALSE, TRUE, + EL_SPRING, ACTION_EATING, MV_BIT_RIGHT }, { - Xacid_nw, TRUE, FALSE, - EL_ACID_POOL_TOPLEFT, -1, -1 + Yspring_alien_w, FALSE, FALSE, + EL_SPRING, ACTION_EATING, MV_BIT_LEFT }, { - Xacid_1, TRUE, FALSE, - EL_ACID, -1, -1 + Yspring_alien_wB, FALSE, TRUE, + EL_SPRING, ACTION_EATING, MV_BIT_LEFT }, + { - Xacid_2, FALSE, FALSE, - EL_ACID, -1, -1 + Xpush_emerald_e, FALSE, FALSE, + EL_EMERALD, -1, MV_BIT_RIGHT }, { - Xacid_3, FALSE, FALSE, - EL_ACID, -1, -1 + Xpush_emerald_w, FALSE, FALSE, + EL_EMERALD, -1, MV_BIT_LEFT }, { - Xacid_4, FALSE, FALSE, - EL_ACID, -1, -1 + Xpush_diamond_e, FALSE, FALSE, + EL_DIAMOND, -1, MV_BIT_RIGHT }, { - Xacid_5, FALSE, FALSE, - EL_ACID, -1, -1 + Xpush_diamond_w, FALSE, FALSE, + EL_DIAMOND, -1, MV_BIT_LEFT }, { - Xacid_6, FALSE, FALSE, - EL_ACID, -1, -1 + Xpush_stone_e, FALSE, FALSE, + EL_ROCK, -1, MV_BIT_RIGHT }, { - Xacid_7, FALSE, FALSE, - EL_ACID, -1, -1 + Xpush_stone_w, FALSE, FALSE, + EL_ROCK, -1, MV_BIT_LEFT }, { - Xacid_8, FALSE, FALSE, - EL_ACID, -1, -1 + Xpush_bomb_e, FALSE, FALSE, + EL_BOMB, -1, MV_BIT_RIGHT }, { - Xball_1, TRUE, FALSE, - EL_EMC_MAGIC_BALL, -1, -1 + Xpush_bomb_w, FALSE, FALSE, + EL_BOMB, -1, MV_BIT_LEFT }, { - Xball_1B, FALSE, FALSE, - EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1 + Xpush_nut_e, FALSE, FALSE, + EL_NUT, -1, MV_BIT_RIGHT }, { - Xball_2, FALSE, FALSE, - EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1 + Xpush_nut_w, FALSE, FALSE, + EL_NUT, -1, MV_BIT_LEFT }, { - Xball_2B, FALSE, FALSE, - EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1 + Xpush_spring_e, FALSE, FALSE, + EL_SPRING_RIGHT, -1, MV_BIT_RIGHT }, { - Yball_eat, FALSE, FALSE, - EL_EMC_MAGIC_BALL, ACTION_DROPPING, -1 + Xpush_spring_w, FALSE, FALSE, + EL_SPRING_LEFT, -1, MV_BIT_LEFT }, + { - Ykey_1_eat, FALSE, FALSE, - EL_EM_KEY_1, ACTION_COLLECTING, -1 + Xdynamite, TRUE, FALSE, + EL_EM_DYNAMITE, -1, -1 + }, + { + Ydynamite_blank, FALSE, FALSE, + EL_EM_DYNAMITE, ACTION_COLLECTING, -1 + }, + { + Xdynamite_1, TRUE, FALSE, + EL_EM_DYNAMITE_ACTIVE, -1, -1 + }, + { + Xdynamite_2, FALSE, FALSE, + EL_EM_DYNAMITE_ACTIVE, -1, -1 + }, + { + Xdynamite_3, FALSE, FALSE, + EL_EM_DYNAMITE_ACTIVE, -1, -1 + }, + { + Xdynamite_4, FALSE, FALSE, + EL_EM_DYNAMITE_ACTIVE, -1, -1 + }, + + { + Xkey_1, TRUE, FALSE, + EL_EM_KEY_1, -1, -1 + }, + { + Xkey_2, TRUE, FALSE, + EL_EM_KEY_2, -1, -1 + }, + { + Xkey_3, TRUE, FALSE, + EL_EM_KEY_3, -1, -1 + }, + { + Xkey_4, TRUE, FALSE, + EL_EM_KEY_4, -1, -1 + }, + { + Xkey_5, TRUE, FALSE, + EL_EMC_KEY_5, -1, -1 + }, + { + Xkey_6, TRUE, FALSE, + EL_EMC_KEY_6, -1, -1 + }, + { + Xkey_7, TRUE, FALSE, + EL_EMC_KEY_7, -1, -1 + }, + { + Xkey_8, TRUE, FALSE, + EL_EMC_KEY_8, -1, -1 + }, + + { + Xdoor_1, TRUE, FALSE, + EL_EM_GATE_1, -1, -1 + }, + { + Xdoor_2, TRUE, FALSE, + EL_EM_GATE_2, -1, -1 + }, + { + Xdoor_3, TRUE, FALSE, + EL_EM_GATE_3, -1, -1 + }, + { + Xdoor_4, TRUE, FALSE, + EL_EM_GATE_4, -1, -1 + }, + { + Xdoor_5, TRUE, FALSE, + EL_EMC_GATE_5, -1, -1 + }, + { + Xdoor_6, TRUE, FALSE, + EL_EMC_GATE_6, -1, -1 + }, + { + Xdoor_7, TRUE, FALSE, + EL_EMC_GATE_7, -1, -1 + }, + { + Xdoor_8, TRUE, FALSE, + EL_EMC_GATE_8, -1, -1 + }, + + { + Xfake_door_1, TRUE, FALSE, + EL_EM_GATE_1_GRAY, -1, -1 + }, + { + Xfake_door_2, TRUE, FALSE, + EL_EM_GATE_2_GRAY, -1, -1 + }, + { + Xfake_door_3, TRUE, FALSE, + EL_EM_GATE_3_GRAY, -1, -1 + }, + { + Xfake_door_4, TRUE, FALSE, + EL_EM_GATE_4_GRAY, -1, -1 + }, + { + Xfake_door_5, TRUE, FALSE, + EL_EMC_GATE_5_GRAY, -1, -1 }, { - Ykey_2_eat, FALSE, FALSE, - EL_EM_KEY_2, ACTION_COLLECTING, -1 + Xfake_door_6, TRUE, FALSE, + EL_EMC_GATE_6_GRAY, -1, -1 }, { - Ykey_3_eat, FALSE, FALSE, - EL_EM_KEY_3, ACTION_COLLECTING, -1 + Xfake_door_7, TRUE, FALSE, + EL_EMC_GATE_7_GRAY, -1, -1 }, { - Ykey_4_eat, FALSE, FALSE, - EL_EM_KEY_4, ACTION_COLLECTING, -1 + Xfake_door_8, TRUE, FALSE, + EL_EMC_GATE_8_GRAY, -1, -1 }, + { - Ykey_5_eat, FALSE, FALSE, - EL_EMC_KEY_5, ACTION_COLLECTING, -1 + Xballoon, TRUE, FALSE, + EL_BALLOON, -1, -1 }, { - Ykey_6_eat, FALSE, FALSE, - EL_EMC_KEY_6, ACTION_COLLECTING, -1 + Yballoon_n, FALSE, FALSE, + EL_BALLOON, ACTION_MOVING, MV_BIT_UP }, { - Ykey_7_eat, FALSE, FALSE, - EL_EMC_KEY_7, ACTION_COLLECTING, -1 + Yballoon_nB, FALSE, TRUE, + EL_BALLOON, ACTION_MOVING, MV_BIT_UP }, { - Ykey_8_eat, FALSE, FALSE, - EL_EMC_KEY_8, ACTION_COLLECTING, -1 + Yballoon_e, FALSE, FALSE, + EL_BALLOON, ACTION_MOVING, MV_BIT_RIGHT }, { - Ylenses_eat, FALSE, FALSE, - EL_EMC_LENSES, ACTION_COLLECTING, -1 + Yballoon_eB, FALSE, TRUE, + EL_BALLOON, ACTION_MOVING, MV_BIT_RIGHT }, { - Ymagnify_eat, FALSE, FALSE, - EL_EMC_MAGNIFIER, ACTION_COLLECTING, -1 + Yballoon_s, FALSE, FALSE, + EL_BALLOON, ACTION_MOVING, MV_BIT_DOWN }, { - Ygrass_eat, FALSE, FALSE, - EL_EMC_GRASS, ACTION_SNAPPING, -1 + Yballoon_sB, FALSE, TRUE, + EL_BALLOON, ACTION_MOVING, MV_BIT_DOWN }, { - Ydirt_eat, FALSE, FALSE, - EL_SAND, ACTION_SNAPPING, -1 + Yballoon_w, FALSE, FALSE, + EL_BALLOON, ACTION_MOVING, MV_BIT_LEFT }, { - Xgrow_ns, TRUE, FALSE, - EL_EXPANDABLE_WALL_VERTICAL, -1, -1 + Yballoon_wB, FALSE, TRUE, + EL_BALLOON, ACTION_MOVING, MV_BIT_LEFT }, + { - Ygrow_ns_eat, FALSE, FALSE, - EL_EXPANDABLE_WALL_VERTICAL, ACTION_GROWING, -1 + Xball_1, TRUE, FALSE, + EL_EMC_MAGIC_BALL, -1, -1 }, { - Xgrow_ew, TRUE, FALSE, - EL_EXPANDABLE_WALL_HORIZONTAL, -1, -1 + Yball_1, FALSE, FALSE, + EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1 }, { - Ygrow_ew_eat, FALSE, FALSE, - EL_EXPANDABLE_WALL_HORIZONTAL, ACTION_GROWING, -1 + Xball_2, FALSE, FALSE, + EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1 }, { - Xwonderwall, TRUE, FALSE, - EL_MAGIC_WALL, -1, -1 + Yball_2, FALSE, FALSE, + EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1 }, { - XwonderwallB, FALSE, FALSE, - EL_MAGIC_WALL, ACTION_ACTIVE, -1 + Yball_blank, FALSE, FALSE, + EL_EMC_MAGIC_BALL, ACTION_DROPPING, -1 }, + { Xamoeba_1, TRUE, FALSE, EL_AMOEBA_DRY, ACTION_OTHER, -1 @@ -6723,158 +6940,134 @@ em_object_mapping_list[] = Xamoeba_8, FALSE, FALSE, EL_AMOEBA_WET, ACTION_OTHER, -1 }, + { - Xdoor_1, TRUE, FALSE, - EL_EM_GATE_1, -1, -1 - }, - { - Xdoor_2, TRUE, FALSE, - EL_EM_GATE_2, -1, -1 - }, - { - Xdoor_3, TRUE, FALSE, - EL_EM_GATE_3, -1, -1 - }, - { - Xdoor_4, TRUE, FALSE, - EL_EM_GATE_4, -1, -1 - }, - { - Xdoor_5, TRUE, FALSE, - EL_EMC_GATE_5, -1, -1 - }, - { - Xdoor_6, TRUE, FALSE, - EL_EMC_GATE_6, -1, -1 - }, - { - Xdoor_7, TRUE, FALSE, - EL_EMC_GATE_7, -1, -1 - }, - { - Xdoor_8, TRUE, FALSE, - EL_EMC_GATE_8, -1, -1 - }, - { - Xkey_1, TRUE, FALSE, - EL_EM_KEY_1, -1, -1 - }, - { - Xkey_2, TRUE, FALSE, - EL_EM_KEY_2, -1, -1 + Xdrip, TRUE, FALSE, + EL_AMOEBA_DROP, ACTION_GROWING, -1 }, { - Xkey_3, TRUE, FALSE, - EL_EM_KEY_3, -1, -1 + Xdrip_fall, FALSE, FALSE, + EL_AMOEBA_DROP, -1, -1 }, { - Xkey_4, TRUE, FALSE, - EL_EM_KEY_4, -1, -1 + Xdrip_stretch, FALSE, FALSE, + EL_AMOEBA_DROP, ACTION_FALLING, -1 }, { - Xkey_5, TRUE, FALSE, - EL_EMC_KEY_5, -1, -1 + Xdrip_stretchB, FALSE, TRUE, + EL_AMOEBA_DROP, ACTION_FALLING, -1 }, { - Xkey_6, TRUE, FALSE, - EL_EMC_KEY_6, -1, -1 + Ydrip_1_s, FALSE, FALSE, + EL_AMOEBA_DROP, ACTION_FALLING, -1 }, { - Xkey_7, TRUE, FALSE, - EL_EMC_KEY_7, -1, -1 + Ydrip_1_sB, FALSE, TRUE, + EL_AMOEBA_DROP, ACTION_FALLING, -1 }, { - Xkey_8, TRUE, FALSE, - EL_EMC_KEY_8, -1, -1 + Ydrip_2_s, FALSE, FALSE, + EL_AMOEBA_DROP, ACTION_FALLING, -1 }, { - Xwind_n, TRUE, FALSE, - EL_BALLOON_SWITCH_UP, -1, -1 + Ydrip_2_sB, FALSE, TRUE, + EL_AMOEBA_DROP, ACTION_FALLING, -1 }, + { - Xwind_e, TRUE, FALSE, - EL_BALLOON_SWITCH_RIGHT, -1, -1 + Xwonderwall, TRUE, FALSE, + EL_MAGIC_WALL, -1, -1 }, { - Xwind_s, TRUE, FALSE, - EL_BALLOON_SWITCH_DOWN, -1, -1 + Ywonderwall, FALSE, FALSE, + EL_MAGIC_WALL, ACTION_ACTIVE, -1 }, + { - Xwind_w, TRUE, FALSE, - EL_BALLOON_SWITCH_LEFT, -1, -1 + Xwheel, TRUE, FALSE, + EL_ROBOT_WHEEL, -1, -1 }, { - Xwind_nesw, TRUE, FALSE, - EL_BALLOON_SWITCH_ANY, -1, -1 + Ywheel, FALSE, FALSE, + EL_ROBOT_WHEEL, ACTION_ACTIVE, -1 }, + { - Xwind_stop, TRUE, FALSE, - EL_BALLOON_SWITCH_NONE, -1, -1 + Xswitch, TRUE, FALSE, + EL_EMC_MAGIC_BALL_SWITCH, -1, -1 }, { - Xexit, TRUE, FALSE, - EL_EM_EXIT_CLOSED, -1, -1 + Yswitch, FALSE, FALSE, + EL_EMC_MAGIC_BALL_SWITCH, ACTION_ACTIVE, -1 }, + { - Xexit_1, TRUE, FALSE, - EL_EM_EXIT_OPEN, -1, -1 + Xbumper, TRUE, FALSE, + EL_EMC_SPRING_BUMPER, -1, -1 }, { - Xexit_2, FALSE, FALSE, - EL_EM_EXIT_OPEN, -1, -1 + Ybumper, FALSE, FALSE, + EL_EMC_SPRING_BUMPER, ACTION_ACTIVE, -1 }, + { - Xexit_3, FALSE, FALSE, - EL_EM_EXIT_OPEN, -1, -1 + Xacid_nw, TRUE, FALSE, + EL_ACID_POOL_TOPLEFT, -1, -1 }, { - Xdynamite, TRUE, FALSE, - EL_EM_DYNAMITE, -1, -1 + Xacid_ne, TRUE, FALSE, + EL_ACID_POOL_TOPRIGHT, -1, -1 }, { - Ydynamite_eat, FALSE, FALSE, - EL_EM_DYNAMITE, ACTION_COLLECTING, -1 + Xacid_sw, TRUE, FALSE, + EL_ACID_POOL_BOTTOMLEFT, -1, -1 }, { - Xdynamite_1, TRUE, FALSE, - EL_EM_DYNAMITE_ACTIVE, -1, -1 + Xacid_s, TRUE, FALSE, + EL_ACID_POOL_BOTTOM, -1, -1 }, { - Xdynamite_2, FALSE, FALSE, - EL_EM_DYNAMITE_ACTIVE, -1, -1 + Xacid_se, TRUE, FALSE, + EL_ACID_POOL_BOTTOMRIGHT, -1, -1 }, + { - Xdynamite_3, FALSE, FALSE, - EL_EM_DYNAMITE_ACTIVE, -1, -1 + Xfake_blank, TRUE, FALSE, + EL_INVISIBLE_WALL, -1, -1 }, { - Xdynamite_4, FALSE, FALSE, - EL_EM_DYNAMITE_ACTIVE, -1, -1 + Yfake_blank, FALSE, FALSE, + EL_INVISIBLE_WALL, ACTION_ACTIVE, -1 }, + { - Xbumper, TRUE, FALSE, - EL_EMC_SPRING_BUMPER, -1, -1 + Xfake_grass, TRUE, FALSE, + EL_EMC_FAKE_GRASS, -1, -1 }, { - XbumperB, FALSE, FALSE, - EL_EMC_SPRING_BUMPER, ACTION_ACTIVE, -1 + Yfake_grass, FALSE, FALSE, + EL_EMC_FAKE_GRASS, ACTION_ACTIVE, -1 }, + { - Xwheel, TRUE, FALSE, - EL_ROBOT_WHEEL, -1, -1 + Xfake_amoeba, TRUE, FALSE, + EL_EMC_DRIPPER, -1, -1 }, { - XwheelB, FALSE, FALSE, - EL_ROBOT_WHEEL, ACTION_ACTIVE, -1 + Yfake_amoeba, FALSE, FALSE, + EL_EMC_DRIPPER, ACTION_ACTIVE, -1 }, + { - Xswitch, TRUE, FALSE, - EL_EMC_MAGIC_BALL_SWITCH, -1, -1 + Xlenses, TRUE, FALSE, + EL_EMC_LENSES, -1, -1 }, + { - XswitchB, FALSE, FALSE, - EL_EMC_MAGIC_BALL_SWITCH, ACTION_ACTIVE, -1 + Xmagnify, TRUE, FALSE, + EL_EMC_MAGNIFIER, -1, -1 }, + { Xsand, TRUE, FALSE, EL_QUICKSAND_EMPTY, -1, -1 @@ -6899,38 +7092,6 @@ em_object_mapping_list[] = Xsand_stonein_4, FALSE, TRUE, EL_ROCK, ACTION_FILLING, -1 }, - { - Xsand_stonesand_1, FALSE, FALSE, - EL_QUICKSAND_EMPTYING, -1, -1 - }, - { - Xsand_stonesand_2, FALSE, FALSE, - EL_QUICKSAND_EMPTYING, -1, -1 - }, - { - Xsand_stonesand_3, FALSE, FALSE, - EL_QUICKSAND_EMPTYING, -1, -1 - }, - { - Xsand_stonesand_4, FALSE, FALSE, - EL_QUICKSAND_EMPTYING, -1, -1 - }, - { - Xsand_stonesand_quickout_1, FALSE, FALSE, - EL_QUICKSAND_EMPTYING, -1, -1 - }, - { - Xsand_stonesand_quickout_2, FALSE, FALSE, - EL_QUICKSAND_EMPTYING, -1, -1 - }, - { - Xsand_stoneout_1, FALSE, FALSE, - EL_ROCK, ACTION_EMPTYING, -1 - }, - { - Xsand_stoneout_2, FALSE, FALSE, - EL_ROCK, ACTION_EMPTYING, -1 - }, { Xsand_sandstone_1, FALSE, FALSE, EL_QUICKSAND_FILLING, -1, -1 @@ -6945,128 +7106,105 @@ em_object_mapping_list[] = }, { Xsand_sandstone_4, FALSE, FALSE, - EL_QUICKSAND_FILLING, -1, -1 - }, - { - Xplant, TRUE, FALSE, - EL_EMC_PLANT, -1, -1 - }, - { - Yplant, FALSE, FALSE, - EL_EMC_PLANT, -1, -1 - }, - { - Xlenses, TRUE, FALSE, - EL_EMC_LENSES, -1, -1 - }, - { - Xmagnify, TRUE, FALSE, - EL_EMC_MAGNIFIER, -1, -1 - }, - { - Xdripper, TRUE, FALSE, - EL_EMC_DRIPPER, -1, -1 - }, - { - XdripperB, FALSE, FALSE, - EL_EMC_DRIPPER, ACTION_ACTIVE, -1 - }, - { - Xfake_blank, TRUE, FALSE, - EL_INVISIBLE_WALL, -1, -1 + EL_QUICKSAND_FILLING, -1, -1 }, { - Xfake_blankB, FALSE, FALSE, - EL_INVISIBLE_WALL, ACTION_ACTIVE, -1 + Xsand_stonesand_1, FALSE, FALSE, + EL_QUICKSAND_EMPTYING, -1, -1 }, { - Xfake_grass, TRUE, FALSE, - EL_EMC_FAKE_GRASS, -1, -1 + Xsand_stonesand_2, FALSE, FALSE, + EL_QUICKSAND_EMPTYING, -1, -1 }, { - Xfake_grassB, FALSE, FALSE, - EL_EMC_FAKE_GRASS, ACTION_ACTIVE, -1 + Xsand_stonesand_3, FALSE, FALSE, + EL_QUICKSAND_EMPTYING, -1, -1 }, { - Xfake_door_1, TRUE, FALSE, - EL_EM_GATE_1_GRAY, -1, -1 + Xsand_stonesand_4, FALSE, FALSE, + EL_QUICKSAND_EMPTYING, -1, -1 }, { - Xfake_door_2, TRUE, FALSE, - EL_EM_GATE_2_GRAY, -1, -1 + Xsand_stoneout_1, FALSE, FALSE, + EL_ROCK, ACTION_EMPTYING, -1 }, { - Xfake_door_3, TRUE, FALSE, - EL_EM_GATE_3_GRAY, -1, -1 + Xsand_stoneout_2, FALSE, FALSE, + EL_ROCK, ACTION_EMPTYING, -1 }, { - Xfake_door_4, TRUE, FALSE, - EL_EM_GATE_4_GRAY, -1, -1 + Xsand_stonesand_quickout_1, FALSE, FALSE, + EL_QUICKSAND_EMPTYING, -1, -1 }, { - Xfake_door_5, TRUE, FALSE, - EL_EMC_GATE_5_GRAY, -1, -1 + Xsand_stonesand_quickout_2, FALSE, FALSE, + EL_QUICKSAND_EMPTYING, -1, -1 }, + { - Xfake_door_6, TRUE, FALSE, - EL_EMC_GATE_6_GRAY, -1, -1 + Xslide_ns, TRUE, FALSE, + EL_EXPANDABLE_WALL_VERTICAL, -1, -1 }, { - Xfake_door_7, TRUE, FALSE, - EL_EMC_GATE_7_GRAY, -1, -1 + Yslide_ns_blank, FALSE, FALSE, + EL_EXPANDABLE_WALL_VERTICAL, ACTION_GROWING, -1 }, { - Xfake_door_8, TRUE, FALSE, - EL_EMC_GATE_8_GRAY, -1, -1 + Xslide_ew, TRUE, FALSE, + EL_EXPANDABLE_WALL_HORIZONTAL, -1, -1 }, { - Xfake_acid_1, TRUE, FALSE, - EL_EMC_FAKE_ACID, -1, -1 + Yslide_ew_blank, FALSE, FALSE, + EL_EXPANDABLE_WALL_HORIZONTAL, ACTION_GROWING, -1 }, + { - Xfake_acid_2, FALSE, FALSE, - EL_EMC_FAKE_ACID, -1, -1 + Xwind_n, TRUE, FALSE, + EL_BALLOON_SWITCH_UP, -1, -1 }, { - Xfake_acid_3, FALSE, FALSE, - EL_EMC_FAKE_ACID, -1, -1 + Xwind_e, TRUE, FALSE, + EL_BALLOON_SWITCH_RIGHT, -1, -1 }, { - Xfake_acid_4, FALSE, FALSE, - EL_EMC_FAKE_ACID, -1, -1 + Xwind_s, TRUE, FALSE, + EL_BALLOON_SWITCH_DOWN, -1, -1 }, { - Xfake_acid_5, FALSE, FALSE, - EL_EMC_FAKE_ACID, -1, -1 + Xwind_w, TRUE, FALSE, + EL_BALLOON_SWITCH_LEFT, -1, -1 }, { - Xfake_acid_6, FALSE, FALSE, - EL_EMC_FAKE_ACID, -1, -1 + Xwind_any, TRUE, FALSE, + EL_BALLOON_SWITCH_ANY, -1, -1 }, { - Xfake_acid_7, FALSE, FALSE, - EL_EMC_FAKE_ACID, -1, -1 + Xwind_stop, TRUE, FALSE, + EL_BALLOON_SWITCH_NONE, -1, -1 }, + { - Xfake_acid_8, FALSE, FALSE, - EL_EMC_FAKE_ACID, -1, -1 + Xexit, TRUE, FALSE, + EL_EM_EXIT_CLOSED, -1, -1 }, { - Xsteel_1, TRUE, FALSE, - EL_STEELWALL, -1, -1 + Xexit_1, TRUE, FALSE, + EL_EM_EXIT_OPEN, -1, -1 }, { - Xsteel_2, TRUE, FALSE, - EL_EMC_STEELWALL_2, -1, -1 + Xexit_2, FALSE, FALSE, + EL_EM_EXIT_OPEN, -1, -1 }, { - Xsteel_3, TRUE, FALSE, - EL_EMC_STEELWALL_3, -1, -1 + Xexit_3, FALSE, FALSE, + EL_EM_EXIT_OPEN, -1, -1 }, + { - Xsteel_4, TRUE, FALSE, - EL_EMC_STEELWALL_4, -1, -1 + Xpause, FALSE, FALSE, + EL_EMPTY, -1, -1 }, + { Xwall_1, TRUE, FALSE, EL_WALL, -1, -1 @@ -7083,22 +7221,41 @@ em_object_mapping_list[] = Xwall_4, TRUE, FALSE, EL_EMC_WALL_16, -1, -1 }, + { - Xround_wall_1, TRUE, FALSE, + Xroundwall_1, TRUE, FALSE, EL_WALL_SLIPPERY, -1, -1 }, { - Xround_wall_2, TRUE, FALSE, + Xroundwall_2, TRUE, FALSE, EL_EMC_WALL_SLIPPERY_2, -1, -1 }, { - Xround_wall_3, TRUE, FALSE, + Xroundwall_3, TRUE, FALSE, EL_EMC_WALL_SLIPPERY_3, -1, -1 }, { - Xround_wall_4, TRUE, FALSE, + Xroundwall_4, TRUE, FALSE, EL_EMC_WALL_SLIPPERY_4, -1, -1 }, + + { + Xsteel_1, TRUE, FALSE, + EL_STEELWALL, -1, -1 + }, + { + Xsteel_2, TRUE, FALSE, + EL_EMC_STEELWALL_2, -1, -1 + }, + { + Xsteel_3, TRUE, FALSE, + EL_EMC_STEELWALL_3, -1, -1 + }, + { + Xsteel_4, TRUE, FALSE, + EL_EMC_STEELWALL_4, -1, -1 + }, + { Xdecor_1, TRUE, FALSE, EL_EMC_WALL_8, -1, -1 @@ -7147,6 +7304,7 @@ em_object_mapping_list[] = Xdecor_12, TRUE, FALSE, EL_EMC_WALL_12, -1, -1 }, + { Xalpha_0, TRUE, FALSE, EL_CHAR('0'), -1, -1 @@ -7192,8 +7350,8 @@ em_object_mapping_list[] = EL_CHAR('!'), -1, -1 }, { - Xalpha_quote, TRUE, FALSE, - EL_CHAR('"'), -1, -1 + Xalpha_apost, TRUE, FALSE, + EL_CHAR('\''), -1, -1 }, { Xalpha_comma, TRUE, FALSE, @@ -7333,40 +7491,52 @@ em_object_mapping_list[] = }, { - Xboom_bug, FALSE, FALSE, - EL_BUG, ACTION_EXPLODING, -1 + Ykey_1_blank, FALSE, FALSE, + EL_EM_KEY_1, ACTION_COLLECTING, -1 }, { - Xboom_bomb, FALSE, FALSE, - EL_BOMB, ACTION_EXPLODING, -1 + Ykey_2_blank, FALSE, FALSE, + EL_EM_KEY_2, ACTION_COLLECTING, -1 }, { - Xboom_android, FALSE, FALSE, - EL_EMC_ANDROID, ACTION_OTHER, -1 + Ykey_3_blank, FALSE, FALSE, + EL_EM_KEY_3, ACTION_COLLECTING, -1 }, { - Xboom_1, FALSE, FALSE, - EL_DEFAULT, ACTION_EXPLODING, -1 + Ykey_4_blank, FALSE, FALSE, + EL_EM_KEY_4, ACTION_COLLECTING, -1 }, { - Xboom_2, FALSE, FALSE, - EL_DEFAULT, ACTION_EXPLODING, -1 + Ykey_5_blank, FALSE, FALSE, + EL_EMC_KEY_5, ACTION_COLLECTING, -1 }, { - Znormal, FALSE, FALSE, - EL_EMPTY, -1, -1 + Ykey_6_blank, FALSE, FALSE, + EL_EMC_KEY_6, ACTION_COLLECTING, -1 }, { - Zdynamite, FALSE, FALSE, - EL_EMPTY, -1, -1 + Ykey_7_blank, FALSE, FALSE, + EL_EMC_KEY_7, ACTION_COLLECTING, -1 }, { - Zplayer, FALSE, FALSE, - EL_EMPTY, -1, -1 + Ykey_8_blank, FALSE, FALSE, + EL_EMC_KEY_8, ACTION_COLLECTING, -1 }, { - ZBORDER, FALSE, FALSE, - EL_EMPTY, -1, -1 + Ylenses_blank, FALSE, FALSE, + EL_EMC_LENSES, ACTION_COLLECTING, -1 + }, + { + Ymagnify_blank, FALSE, FALSE, + EL_EMC_MAGNIFIER, ACTION_COLLECTING, -1 + }, + { + Ygrass_blank, FALSE, FALSE, + EL_EMC_GRASS, ACTION_SNAPPING, -1 + }, + { + Ydirt_blank, FALSE, FALSE, + EL_SAND, ACTION_SNAPPING, -1 }, { @@ -7384,214 +7554,214 @@ static struct Mapping_EM_to_RND_player int action; int direction; } -em_player_mapping_list[] = +em_player_mapping_list[MAX_PLAYERS * PLY_MAX + 1] = { { - SPR_walk + 0, 0, + PLY_walk_n, 0, EL_PLAYER_1, ACTION_MOVING, MV_BIT_UP, }, { - SPR_walk + 1, 0, + PLY_walk_e, 0, EL_PLAYER_1, ACTION_MOVING, MV_BIT_RIGHT, }, { - SPR_walk + 2, 0, + PLY_walk_s, 0, EL_PLAYER_1, ACTION_MOVING, MV_BIT_DOWN, }, { - SPR_walk + 3, 0, + PLY_walk_w, 0, EL_PLAYER_1, ACTION_MOVING, MV_BIT_LEFT, }, { - SPR_push + 0, 0, + PLY_push_n, 0, EL_PLAYER_1, ACTION_PUSHING, MV_BIT_UP, }, { - SPR_push + 1, 0, + PLY_push_e, 0, EL_PLAYER_1, ACTION_PUSHING, MV_BIT_RIGHT, }, { - SPR_push + 2, 0, + PLY_push_s, 0, EL_PLAYER_1, ACTION_PUSHING, MV_BIT_DOWN, }, { - SPR_push + 3, 0, + PLY_push_w, 0, EL_PLAYER_1, ACTION_PUSHING, MV_BIT_LEFT, }, { - SPR_spray + 0, 0, + PLY_shoot_n, 0, EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_UP, }, { - SPR_spray + 1, 0, + PLY_shoot_e, 0, EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_RIGHT, }, { - SPR_spray + 2, 0, + PLY_shoot_s, 0, EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_DOWN, }, { - SPR_spray + 3, 0, + PLY_shoot_w, 0, EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_LEFT, }, { - SPR_walk + 0, 1, + PLY_walk_n, 1, EL_PLAYER_2, ACTION_MOVING, MV_BIT_UP, }, { - SPR_walk + 1, 1, + PLY_walk_e, 1, EL_PLAYER_2, ACTION_MOVING, MV_BIT_RIGHT, }, { - SPR_walk + 2, 1, + PLY_walk_s, 1, EL_PLAYER_2, ACTION_MOVING, MV_BIT_DOWN, }, { - SPR_walk + 3, 1, + PLY_walk_w, 1, EL_PLAYER_2, ACTION_MOVING, MV_BIT_LEFT, }, { - SPR_push + 0, 1, + PLY_push_n, 1, EL_PLAYER_2, ACTION_PUSHING, MV_BIT_UP, }, { - SPR_push + 1, 1, + PLY_push_e, 1, EL_PLAYER_2, ACTION_PUSHING, MV_BIT_RIGHT, }, { - SPR_push + 2, 1, + PLY_push_s, 1, EL_PLAYER_2, ACTION_PUSHING, MV_BIT_DOWN, }, { - SPR_push + 3, 1, + PLY_push_w, 1, EL_PLAYER_2, ACTION_PUSHING, MV_BIT_LEFT, }, { - SPR_spray + 0, 1, + PLY_shoot_n, 1, EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_UP, }, { - SPR_spray + 1, 1, + PLY_shoot_e, 1, EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_RIGHT, }, { - SPR_spray + 2, 1, + PLY_shoot_s, 1, EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_DOWN, }, { - SPR_spray + 3, 1, + PLY_shoot_w, 1, EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_LEFT, }, { - SPR_still, 0, + PLY_still, 0, EL_PLAYER_1, ACTION_DEFAULT, -1, }, { - SPR_still, 1, + PLY_still, 1, EL_PLAYER_2, ACTION_DEFAULT, -1, }, { - SPR_walk + 0, 2, + PLY_walk_n, 2, EL_PLAYER_3, ACTION_MOVING, MV_BIT_UP, }, { - SPR_walk + 1, 2, + PLY_walk_e, 2, EL_PLAYER_3, ACTION_MOVING, MV_BIT_RIGHT, }, { - SPR_walk + 2, 2, + PLY_walk_s, 2, EL_PLAYER_3, ACTION_MOVING, MV_BIT_DOWN, }, { - SPR_walk + 3, 2, + PLY_walk_w, 2, EL_PLAYER_3, ACTION_MOVING, MV_BIT_LEFT, }, { - SPR_push + 0, 2, + PLY_push_n, 2, EL_PLAYER_3, ACTION_PUSHING, MV_BIT_UP, }, { - SPR_push + 1, 2, + PLY_push_e, 2, EL_PLAYER_3, ACTION_PUSHING, MV_BIT_RIGHT, }, { - SPR_push + 2, 2, + PLY_push_s, 2, EL_PLAYER_3, ACTION_PUSHING, MV_BIT_DOWN, }, { - SPR_push + 3, 2, + PLY_push_w, 2, EL_PLAYER_3, ACTION_PUSHING, MV_BIT_LEFT, }, { - SPR_spray + 0, 2, + PLY_shoot_n, 2, EL_PLAYER_3, ACTION_SNAPPING, MV_BIT_UP, }, { - SPR_spray + 1, 2, + PLY_shoot_e, 2, EL_PLAYER_3, ACTION_SNAPPING, MV_BIT_RIGHT, }, { - SPR_spray + 2, 2, + PLY_shoot_s, 2, EL_PLAYER_3, ACTION_SNAPPING, MV_BIT_DOWN, }, { - SPR_spray + 3, 2, + PLY_shoot_w, 2, EL_PLAYER_3, ACTION_SNAPPING, MV_BIT_LEFT, }, { - SPR_walk + 0, 3, + PLY_walk_n, 3, EL_PLAYER_4, ACTION_MOVING, MV_BIT_UP, }, { - SPR_walk + 1, 3, + PLY_walk_e, 3, EL_PLAYER_4, ACTION_MOVING, MV_BIT_RIGHT, }, { - SPR_walk + 2, 3, + PLY_walk_s, 3, EL_PLAYER_4, ACTION_MOVING, MV_BIT_DOWN, }, { - SPR_walk + 3, 3, + PLY_walk_w, 3, EL_PLAYER_4, ACTION_MOVING, MV_BIT_LEFT, }, { - SPR_push + 0, 3, + PLY_push_n, 3, EL_PLAYER_4, ACTION_PUSHING, MV_BIT_UP, }, { - SPR_push + 1, 3, + PLY_push_e, 3, EL_PLAYER_4, ACTION_PUSHING, MV_BIT_RIGHT, }, { - SPR_push + 2, 3, + PLY_push_s, 3, EL_PLAYER_4, ACTION_PUSHING, MV_BIT_DOWN, }, { - SPR_push + 3, 3, + PLY_push_w, 3, EL_PLAYER_4, ACTION_PUSHING, MV_BIT_LEFT, }, { - SPR_spray + 0, 3, + PLY_shoot_n, 3, EL_PLAYER_4, ACTION_SNAPPING, MV_BIT_UP, }, { - SPR_spray + 1, 3, + PLY_shoot_e, 3, EL_PLAYER_4, ACTION_SNAPPING, MV_BIT_RIGHT, }, { - SPR_spray + 2, 3, + PLY_shoot_s, 3, EL_PLAYER_4, ACTION_SNAPPING, MV_BIT_DOWN, }, { - SPR_spray + 3, 3, + PLY_shoot_w, 3, EL_PLAYER_4, ACTION_SNAPPING, MV_BIT_LEFT, }, { - SPR_still, 2, + PLY_still, 2, EL_PLAYER_3, ACTION_DEFAULT, -1, }, { - SPR_still, 3, + PLY_still, 3, EL_PLAYER_4, ACTION_DEFAULT, -1, }, @@ -7601,7 +7771,7 @@ em_player_mapping_list[] = } }; -int map_element_RND_to_EM(int element_rnd) +int map_element_RND_to_EM_cave(int element_rnd) { static unsigned short mapping_RND_to_EM[NUM_FILE_ELEMENTS]; static boolean mapping_initialized = FALSE; @@ -7610,7 +7780,7 @@ int map_element_RND_to_EM(int element_rnd) { int i; - /* return "Xalpha_quest" for all undefined elements in mapping array */ + // return "Xalpha_quest" for all undefined elements in mapping array for (i = 0; i < NUM_FILE_ELEMENTS; i++) mapping_RND_to_EM[i] = Xalpha_quest; @@ -7622,25 +7792,57 @@ int map_element_RND_to_EM(int element_rnd) mapping_initialized = TRUE; } - if (element_rnd >= 0 && element_rnd < NUM_FILE_ELEMENTS) - return mapping_RND_to_EM[element_rnd]; + if (element_rnd < 0 || element_rnd >= NUM_FILE_ELEMENTS) + { + Warn("invalid RND level element %d", element_rnd); + + return EL_UNKNOWN; + } + + return map_em_element_X_to_C(mapping_RND_to_EM[element_rnd]); +} + +int map_element_EM_to_RND_cave(int element_em_cave) +{ + static unsigned short mapping_EM_to_RND[GAME_TILE_MAX]; + static boolean mapping_initialized = FALSE; + + if (!mapping_initialized) + { + int i; + + // return "EL_UNKNOWN" for all undefined elements in mapping array + for (i = 0; i < GAME_TILE_MAX; i++) + mapping_EM_to_RND[i] = EL_UNKNOWN; + + for (i = 0; em_object_mapping_list[i].element_em != -1; i++) + mapping_EM_to_RND[em_object_mapping_list[i].element_em] = + em_object_mapping_list[i].element_rnd; + + mapping_initialized = TRUE; + } + + if (element_em_cave < 0 || element_em_cave >= CAVE_TILE_MAX) + { + Warn("invalid EM cave element %d", element_em_cave); - Error(ERR_WARN, "invalid RND level element %d", element_rnd); + return EL_UNKNOWN; + } - return EL_UNKNOWN; + return mapping_EM_to_RND[map_em_element_C_to_X(element_em_cave)]; } -int map_element_EM_to_RND(int element_em) +int map_element_EM_to_RND_game(int element_em_game) { - static unsigned short mapping_EM_to_RND[TILE_MAX]; + static unsigned short mapping_EM_to_RND[GAME_TILE_MAX]; static boolean mapping_initialized = FALSE; if (!mapping_initialized) { int i; - /* return "EL_UNKNOWN" for all undefined elements in mapping array */ - for (i = 0; i < TILE_MAX; i++) + // return "EL_UNKNOWN" for all undefined elements in mapping array + for (i = 0; i < GAME_TILE_MAX; i++) mapping_EM_to_RND[i] = EL_UNKNOWN; for (i = 0; em_object_mapping_list[i].element_em != -1; i++) @@ -7650,52 +7852,55 @@ int map_element_EM_to_RND(int element_em) mapping_initialized = TRUE; } - if (element_em >= 0 && element_em < TILE_MAX) - return mapping_EM_to_RND[element_em]; + if (element_em_game < 0 || element_em_game >= GAME_TILE_MAX) + { + Warn("invalid EM game element %d", element_em_game); - Error(ERR_WARN, "invalid EM level element %d", element_em); + return EL_UNKNOWN; + } - return EL_UNKNOWN; + return mapping_EM_to_RND[element_em_game]; } void map_android_clone_elements_RND_to_EM(struct LevelInfo *level) { struct LevelInfo_EM *level_em = level->native_em_level; - struct LEVEL *lev = level_em->lev; + struct CAVE *cav = level_em->cav; int i, j; - for (i = 0; i < TILE_MAX; i++) - lev->android_array[i] = Xblank; + for (i = 0; i < GAME_TILE_MAX; i++) + cav->android_array[i] = Cblank; for (i = 0; i < level->num_android_clone_elements; i++) { int element_rnd = level->android_clone_element[i]; - int element_em = map_element_RND_to_EM(element_rnd); + int element_em_cave = map_element_RND_to_EM_cave(element_rnd); for (j = 0; em_object_mapping_list[j].element_em != -1; j++) if (em_object_mapping_list[j].element_rnd == element_rnd) - lev->android_array[em_object_mapping_list[j].element_em] = element_em; + cav->android_array[em_object_mapping_list[j].element_em] = + element_em_cave; } } void map_android_clone_elements_EM_to_RND(struct LevelInfo *level) { struct LevelInfo_EM *level_em = level->native_em_level; - struct LEVEL *lev = level_em->lev; + struct CAVE *cav = level_em->cav; int i, j; level->num_android_clone_elements = 0; - for (i = 0; i < TILE_MAX; i++) + for (i = 0; i < GAME_TILE_MAX; i++) { - int element_em = lev->android_array[i]; + int element_em_cave = cav->android_array[i]; int element_rnd; boolean element_found = FALSE; - if (element_em == Xblank) + if (element_em_cave == Cblank) continue; - element_rnd = map_element_EM_to_RND(element_em); + element_rnd = map_element_EM_to_RND_cave(element_em_cave); for (j = 0; j < level->num_android_clone_elements; j++) if (level->android_clone_element[j] == element_rnd) @@ -7738,7 +7943,7 @@ int map_direction_EM_to_RND(int direction) int map_element_RND_to_SP(int element_rnd) { - int element_sp = 0x20; /* map unknown elements to yellow "hardware" */ + int element_sp = 0x20; // map unknown elements to yellow "hardware" if (element_rnd >= EL_SP_START && element_rnd <= EL_SP_END) @@ -7838,7 +8043,7 @@ int map_element_MM_to_RND(int element_mm) int map_action_MM_to_RND(int action_mm) { - /* all MM actions are defined to exactly match their RND counterparts */ + // all MM actions are defined to exactly match their RND counterparts return action_mm; } @@ -7929,18 +8134,18 @@ int el2img_mm(int element_mm) int el_act_dir2img(int element, int action, int direction) { element = GFX_ELEMENT(element); - direction = MV_DIR_TO_BIT(direction); /* default: MV_NONE => MV_DOWN */ + direction = MV_DIR_TO_BIT(direction); // default: MV_NONE => MV_DOWN - /* direction_graphic[][] == graphic[] for undefined direction graphics */ + // direction_graphic[][] == graphic[] for undefined direction graphics return element_info[element].direction_graphic[action][direction]; } static int el_act_dir2crm(int element, int action, int direction) { element = GFX_ELEMENT(element); - direction = MV_DIR_TO_BIT(direction); /* default: MV_NONE => MV_DOWN */ + direction = MV_DIR_TO_BIT(direction); // default: MV_NONE => MV_DOWN - /* direction_graphic[][] == graphic[] for undefined direction graphics */ + // direction_graphic[][] == graphic[] for undefined direction graphics return element_info[element].direction_crumbled[action][direction]; } @@ -8124,24 +8329,19 @@ int getBeltSwitchElementFromBeltNrAndBeltDir(int belt_nr, int belt_dir) return getBeltSwitchElementFromBeltNrAndBeltDirNr(belt_nr, belt_dir_nr); } +boolean swapTiles_EM(boolean is_pre_emc_cave) +{ + return is_pre_emc_cave && leveldir_current->use_emc_tiles; +} + boolean getTeamMode_EM(void) { return game.team_mode || network_playing; } -int getGameFrameDelay_EM(int native_em_game_frame_delay) +boolean isActivePlayer_EM(int player_nr) { - int game_frame_delay_value; - - game_frame_delay_value = - (tape.playing && tape.fast_forward ? FfwdFrameDelay : - GameFrameDelay == GAME_FRAME_DELAY ? native_em_game_frame_delay : - GameFrameDelay); - - if (tape.playing && tape.warp_forward && !tape.pausing) - game_frame_delay_value = 0; - - return game_frame_delay_value; + return stored_player[player_nr].active; } unsigned int InitRND(int seed) @@ -8156,8 +8356,8 @@ unsigned int InitRND(int seed) return InitEngineRandom_RND(seed); } -static struct Mapping_EM_to_RND_object object_mapping[TILE_MAX]; -static struct Mapping_EM_to_RND_player player_mapping[MAX_PLAYERS][SPR_MAX]; +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 int get_effective_element_EM(int tile, int frame_em) { @@ -8172,23 +8372,23 @@ static int get_effective_element_EM(int tile, int frame_em) { switch (tile) { - case Yacid_splash_eB: - case Yacid_splash_wB: + case Xsplash_e: + case Xsplash_w: return (frame_em > 5 ? EL_EMPTY : element); default: return element; } } - else /* frame_em == 7 */ + else // frame_em == 7 { switch (tile) { - case Yacid_splash_eB: - case Yacid_splash_wB: + case Xsplash_e: + case Xsplash_w: return EL_EMPTY; - case Yemerald_stone: + case Ynut_stone: return EL_EMERALD; case Ydiamond_stone: @@ -8196,24 +8396,24 @@ static int get_effective_element_EM(int tile, int frame_em) case Xdrip_stretch: case Xdrip_stretchB: - case Ydrip_s1: - case Ydrip_s1B: - case Xball_1B: + case Ydrip_1_s: + case Ydrip_1_sB: + case Yball_1: case Xball_2: - case Xball_2B: - case Yball_eat: - case Ykey_1_eat: - case Ykey_2_eat: - case Ykey_3_eat: - case Ykey_4_eat: - case Ykey_5_eat: - case Ykey_6_eat: - case Ykey_7_eat: - case Ykey_8_eat: - case Ylenses_eat: - case Ymagnify_eat: - case Ygrass_eat: - case Ydirt_eat: + case Yball_2: + case Yball_blank: + case Ykey_1_blank: + case Ykey_2_blank: + case Ykey_3_blank: + case Ykey_4_blank: + case Ykey_5_blank: + case Ykey_6_blank: + case Ykey_7_blank: + case Ykey_8_blank: + case Ylenses_blank: + case Ymagnify_blank: + case Ygrass_blank: + case Ydirt_blank: case Xsand_stonein_1: case Xsand_stonein_2: case Xsand_stonein_3: @@ -8253,9 +8453,9 @@ static boolean check_linear_animation_EM(int tile) case Ytank_s_e: case Ytank_w_s: case Ytank_n_w: - case Yacid_splash_eB: - case Yacid_splash_wB: - case Yemerald_stone: + case Xsplash_e: + case Xsplash_w: + case Ynut_stone: return TRUE; } @@ -8266,9 +8466,9 @@ static void set_crumbled_graphics_EM(struct GraphicInfo_EM *g_em, boolean has_crumbled_graphics, int crumbled, int sync_frame) { - /* if element can be crumbled, but certain action graphics are just empty - space (like instantly snapping sand to empty space in 1 frame), do not - treat these empty space graphics as crumbled graphics in EMC engine */ + // if element can be crumbled, but certain action graphics are just empty + // space (like instantly snapping sand to empty space in 1 frame), do not + // treat these empty space graphics as crumbled graphics in EMC engine if (crumbled == IMG_EMPTY_SPACE) has_crumbled_graphics = FALSE; @@ -8332,12 +8532,12 @@ void SetGfxAnimation_EM(struct GraphicInfo_EM *g_em, action == ACTION_FILLING || action == ACTION_EMPTYING); - /* special case: graphic uses "2nd movement tile" and has defined - 7 frames for movement animation (or less) => use default graphic - for last (8th) frame which ends the movement animation */ + // special case: graphic uses "2nd movement tile" and has defined + // 7 frames for movement animation (or less) => use default graphic + // for last (8th) frame which ends the movement animation if (g->double_movement && g->anim_frames < 8 && frame_em == 7) { - action = ACTION_DEFAULT; /* (keep action_* unchanged for now) */ + action = ACTION_DEFAULT; // (keep action_* unchanged for now) graphic = (direction == MV_NONE ? el_act2img(effective_element, action) : el_act_dir2img(effective_element, action, direction)); @@ -8361,7 +8561,7 @@ void SetGfxAnimation_EM(struct GraphicInfo_EM *g_em, GfxFrame[x][y]++; #if 1 - /* !!! TEST !!! NEW !!! DOES NOT WORK RIGHT YET !!! */ + // !!! TEST !!! NEW !!! DOES NOT WORK RIGHT YET !!! if (g->double_movement && frame_em == 0) GfxFrame[x][y] = 0; #endif @@ -8380,7 +8580,7 @@ void SetGfxAnimation_EM(struct GraphicInfo_EM *g_em, { GfxFrame[x][y]++; - /* special case: animation for Xsand_stonesand_quickout_1/2 twice as fast */ + // special case: animation for Xsand_stonesand_quickout_1/2 twice as fast if (tile == Xsand_stonesand_quickout_1 || tile == Xsand_stonesand_quickout_2) GfxFrame[x][y]++; @@ -8391,7 +8591,7 @@ void SetGfxAnimation_EM(struct GraphicInfo_EM *g_em, else if (IN_FIELD(x, y, MAX_LEV_FIELDX, MAX_LEV_FIELDY)) sync_frame = GfxFrame[x][y]; else - sync_frame = 0; /* playfield border (pseudo steel) */ + sync_frame = 0; // playfield border (pseudo steel) SetRandomAnimationValue(x, y); @@ -8427,9 +8627,9 @@ void getGraphicSourceObjectExt_EM(struct GraphicInfo_EM *g_em, struct GraphicInfo *g = &graphic_info[graphic]; int sync_frame; - /* special case: graphic uses "2nd movement tile" and has defined - 7 frames for movement animation (or less) => use default graphic - for last (8th) frame which ends the movement animation */ + // special case: graphic uses "2nd movement tile" and has defined + // 7 frames for movement animation (or less) => use default graphic + // for last (8th) frame which ends the movement animation if (g->double_movement && g->anim_frames < 8 && frame_em == 7) { effective_action = ACTION_DEFAULT; @@ -8450,7 +8650,7 @@ void getGraphicSourceObjectExt_EM(struct GraphicInfo_EM *g_em, else if (IN_FIELD(x, y, MAX_LEV_FIELDX, MAX_LEV_FIELDY)) sync_frame = GfxFrame[x][y]; else - sync_frame = 0; /* playfield border (pseudo steel) */ + sync_frame = 0; // playfield border (pseudo steel) SetRandomAnimationValue(x, y); @@ -8463,8 +8663,8 @@ void getGraphicSourceObjectExt_EM(struct GraphicInfo_EM *g_em, getGraphicSourceExt(graphic, frame, &g_em->bitmap, &g_em->src_x, &g_em->src_y, g->double_movement && is_backside); - /* (updating the "crumbled" graphic definitions is probably not really needed, - as animations for crumbled graphics can't be longer than one EMC cycle) */ + // (updating the "crumbled" graphic definitions is probably not really needed, + // as animations for crumbled graphics can't be longer than one EMC cycle) set_crumbled_graphics_EM(g_em, has_crumbled_graphics, crumbled, sync_frame); } @@ -8501,21 +8701,8 @@ void InitGraphicInfo_EM(void) { int i, j, p; -#if DEBUG_EM_GFX - int num_em_gfx_errors = 0; - - if (graphic_info_em_object[0][0].bitmap == NULL) - { - /* EM graphics not yet initialized in em_open_all() */ - - return; - } - - printf("::: [4 errors can be ignored (1 x 'bomb', 3 x 'em_dynamite']\n"); -#endif - - /* always start with reliable default values */ - for (i = 0; i < TILE_MAX; i++) + // 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; @@ -8523,10 +8710,10 @@ void InitGraphicInfo_EM(void) object_mapping[i].direction = MV_NONE; } - /* always start with reliable default values */ + // always start with reliable default values for (p = 0; p < MAX_PLAYERS; p++) { - for (i = 0; i < SPR_MAX; i++) + for (i = 0; i < PLY_MAX; i++) { player_mapping[p][i].element_rnd = EL_UNKNOWN; player_mapping[p][i].action = ACTION_DEFAULT; @@ -8564,7 +8751,7 @@ void InitGraphicInfo_EM(void) MV_DIR_FROM_BIT(em_player_mapping_list[i].direction); } - for (i = 0; i < TILE_MAX; i++) + for (i = 0; i < GAME_TILE_MAX; i++) { int element = object_mapping[i].element_rnd; int action = object_mapping[i].action; @@ -8583,24 +8770,24 @@ void InitGraphicInfo_EM(void) int effective_action = (j < 7 ? action : i == Xdrip_stretch ? action : i == Xdrip_stretchB ? action : - i == Ydrip_s1 ? action : - i == Ydrip_s1B ? action : - i == Xball_1B ? action : + i == Ydrip_1_s ? action : + i == Ydrip_1_sB ? action : + i == Yball_1 ? action : i == Xball_2 ? action : - i == Xball_2B ? action : - i == Yball_eat ? action : - i == Ykey_1_eat ? action : - i == Ykey_2_eat ? action : - i == Ykey_3_eat ? action : - i == Ykey_4_eat ? action : - i == Ykey_5_eat ? action : - i == Ykey_6_eat ? action : - i == Ykey_7_eat ? action : - i == Ykey_8_eat ? action : - i == Ylenses_eat ? action : - i == Ymagnify_eat ? action : - i == Ygrass_eat ? action : - i == Ydirt_eat ? action : + i == Yball_2 ? action : + i == Yball_blank ? action : + i == Ykey_1_blank ? action : + i == Ykey_2_blank ? action : + i == Ykey_3_blank ? action : + i == Ykey_4_blank ? action : + i == Ykey_5_blank ? action : + i == Ykey_6_blank ? action : + i == Ykey_7_blank ? action : + i == Ykey_8_blank ? action : + i == Ylenses_blank ? action : + i == Ymagnify_blank ? action : + i == Ygrass_blank ? action : + i == Ydirt_blank ? action : i == Xsand_stonein_1 ? action : i == Xsand_stonein_2 ? action : i == Xsand_stonein_3 ? action : @@ -8621,18 +8808,18 @@ void InitGraphicInfo_EM(void) boolean has_action_graphics = (graphic != base_graphic); boolean has_crumbled_graphics = (base_crumbled != base_graphic); struct GraphicInfo *g = &graphic_info[graphic]; - struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][7 - j]; + struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][j]; Bitmap *src_bitmap; int src_x, src_y; - /* ensure to get symmetric 3-frame, 2-delay animations as used in EM */ + // ensure to get symmetric 3-frame, 2-delay animations as used in EM boolean special_animation = (action != ACTION_DEFAULT && g->anim_frames == 3 && g->anim_delay == 2 && g->anim_mode & ANIM_LINEAR); int sync_frame = (i == Xdrip_stretch ? 7 : i == Xdrip_stretchB ? 7 : - i == Ydrip_s2 ? j + 8 : - i == Ydrip_s2B ? j + 8 : + i == Ydrip_2_s ? j + 8 : + i == Ydrip_2_sB ? j + 8 : i == Xacid_1 ? 0 : i == Xacid_2 ? 10 : i == Xacid_3 ? 20 : @@ -8649,21 +8836,29 @@ void InitGraphicInfo_EM(void) i == Xfake_acid_6 ? 50 : i == Xfake_acid_7 ? 60 : i == Xfake_acid_8 ? 70 : + i == Xfake_acid_1_player ? 0 : + i == Xfake_acid_2_player ? 10 : + i == Xfake_acid_3_player ? 20 : + i == Xfake_acid_4_player ? 30 : + i == Xfake_acid_5_player ? 40 : + i == Xfake_acid_6_player ? 50 : + i == Xfake_acid_7_player ? 60 : + i == Xfake_acid_8_player ? 70 : i == Xball_2 ? 7 : - i == Xball_2B ? j + 8 : - i == Yball_eat ? j + 1 : - i == Ykey_1_eat ? j + 1 : - i == Ykey_2_eat ? j + 1 : - i == Ykey_3_eat ? j + 1 : - i == Ykey_4_eat ? j + 1 : - i == Ykey_5_eat ? j + 1 : - i == Ykey_6_eat ? j + 1 : - i == Ykey_7_eat ? j + 1 : - i == Ykey_8_eat ? j + 1 : - i == Ylenses_eat ? j + 1 : - i == Ymagnify_eat ? j + 1 : - i == Ygrass_eat ? j + 1 : - i == Ydirt_eat ? j + 1 : + i == Yball_2 ? j + 8 : + i == Yball_blank ? j + 1 : + i == Ykey_1_blank ? j + 1 : + i == Ykey_2_blank ? j + 1 : + i == Ykey_3_blank ? j + 1 : + i == Ykey_4_blank ? j + 1 : + i == Ykey_5_blank ? j + 1 : + i == Ykey_6_blank ? j + 1 : + i == Ykey_7_blank ? j + 1 : + i == Ykey_8_blank ? j + 1 : + i == Ylenses_blank ? j + 1 : + i == Ymagnify_blank ? j + 1 : + i == Ygrass_blank ? j + 1 : + i == Ydirt_blank ? j + 1 : i == Xamoeba_1 ? 0 : i == Xamoeba_2 ? 1 : i == Xamoeba_3 ? 2 : @@ -8705,13 +8900,13 @@ void InitGraphicInfo_EM(void) i == Xboom_bug && j == 5 ? 2 : i == Xboom_bug && j == 6 ? 2 : i == Xboom_bug && j == 7 ? 0 : - i == Xboom_bomb && j == 1 ? 2 : - i == Xboom_bomb && j == 2 ? 2 : - i == Xboom_bomb && j == 3 ? 4 : - i == Xboom_bomb && j == 4 ? 4 : - i == Xboom_bomb && j == 5 ? 2 : - i == Xboom_bomb && j == 6 ? 2 : - i == Xboom_bomb && j == 7 ? 0 : + i == Xboom_tank && j == 1 ? 2 : + i == Xboom_tank && j == 2 ? 2 : + i == Xboom_tank && j == 3 ? 4 : + i == Xboom_tank && j == 4 ? 4 : + i == Xboom_tank && j == 5 ? 2 : + i == Xboom_tank && j == 6 ? 2 : + i == Xboom_tank && j == 7 ? 0 : i == Xboom_android && j == 7 ? 6 : i == Xboom_1 && j == 1 ? 2 : i == Xboom_1 && j == 2 ? 2 : @@ -8731,13 +8926,6 @@ void InitGraphicInfo_EM(void) special_animation && j == 4 ? 3 : effective_action != action ? 0 : j); - -#if DEBUG_EM_GFX - Bitmap *debug_bitmap = g_em->bitmap; - int debug_src_x = g_em->src_x; - int debug_src_y = g_em->src_y; -#endif - int frame = getAnimationFrame(g->anim_frames, g->anim_delay, g->anim_mode, @@ -8775,10 +8963,10 @@ void InitGraphicInfo_EM(void) effective_action == ACTION_EMPTYING ? MV_DOWN : direction); int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? 1 : 0); int dy = (move_dir == MV_UP ? -1 : move_dir == MV_DOWN ? 1 : 0); - int num_steps = (i == Ydrip_s1 ? 16 : - i == Ydrip_s1B ? 16 : - i == Ydrip_s2 ? 16 : - i == Ydrip_s2B ? 16 : + int num_steps = (i == Ydrip_1_s ? 16 : + i == Ydrip_1_sB ? 16 : + i == Ydrip_2_s ? 16 : + i == Ydrip_2_sB ? 16 : i == Xsand_stonein_1 ? 32 : i == Xsand_stonein_2 ? 32 : i == Xsand_stonein_3 ? 32 : @@ -8787,15 +8975,15 @@ void InitGraphicInfo_EM(void) i == Xsand_stoneout_2 ? 16 : 8); int cx = ABS(dx) * (TILEX / num_steps); int cy = ABS(dy) * (TILEY / num_steps); - int step_frame = (i == Ydrip_s2 ? j + 8 : - i == Ydrip_s2B ? j + 8 : + int step_frame = (i == Ydrip_2_s ? j + 8 : + i == Ydrip_2_sB ? j + 8 : i == Xsand_stonein_2 ? j + 8 : i == Xsand_stonein_3 ? j + 16 : i == Xsand_stonein_4 ? j + 24 : i == Xsand_stoneout_2 ? j + 8 : j) + 1; int step = (is_backside ? step_frame : num_steps - step_frame); - if (is_backside) /* tile where movement starts */ + if (is_backside) // tile where movement starts { if (dx < 0 || dy < 0) { @@ -8808,7 +8996,7 @@ void InitGraphicInfo_EM(void) g_em->dst_offset_y = cy * step; } } - else /* tile where movement ends */ + else // tile where movement ends { if (dx < 0 || dy < 0) { @@ -8826,85 +9014,17 @@ void InitGraphicInfo_EM(void) g_em->height = TILEY - cy * step; } - /* create unique graphic identifier to decide if tile must be redrawn */ + // create unique graphic identifier to decide if tile must be redrawn /* bit 31 - 16 (16 bit): EM style graphic bit 15 - 12 ( 4 bit): EM style frame bit 11 - 6 ( 6 bit): graphic width bit 5 - 0 ( 6 bit): graphic height */ g_em->unique_identifier = (graphic << 16) | (frame << 12) | (g_em->width << 6) | g_em->height; - -#if DEBUG_EM_GFX - - /* skip check for EMC elements not contained in original EMC artwork */ - if (element == EL_EMC_FAKE_ACID) - continue; - - if (g_em->bitmap != debug_bitmap || - g_em->src_x != debug_src_x || - g_em->src_y != debug_src_y || - g_em->src_offset_x != 0 || - g_em->src_offset_y != 0 || - g_em->dst_offset_x != 0 || - g_em->dst_offset_y != 0 || - g_em->width != TILEX || - g_em->height != TILEY) - { - static int last_i = -1; - - if (i != last_i) - { - printf("\n"); - last_i = i; - } - - printf("::: EMC GFX ERROR for element %d -> %d ('%s', '%s', %d)", - i, element, element_info[element].token_name, - element_action_info[effective_action].suffix, direction); - - if (element != effective_element) - printf(" [%d ('%s')]", - effective_element, - element_info[effective_element].token_name); - - printf("\n"); - - if (g_em->bitmap != debug_bitmap) - printf(" %d (%d): different bitmap! (0x%08x != 0x%08x)\n", - j, is_backside, (int)(g_em->bitmap), (int)(debug_bitmap)); - - if (g_em->src_x != debug_src_x || - g_em->src_y != debug_src_y) - printf(" frame %d (%c): %d,%d (%d,%d) should be %d,%d (%d,%d)\n", - j, (is_backside ? 'B' : 'F'), - g_em->src_x, g_em->src_y, - g_em->src_x / 32, g_em->src_y / 32, - debug_src_x, debug_src_y, - debug_src_x / 32, debug_src_y / 32); - - if (g_em->src_offset_x != 0 || - g_em->src_offset_y != 0 || - g_em->dst_offset_x != 0 || - g_em->dst_offset_y != 0) - printf(" %d (%d): offsets %d,%d and %d,%d should be all 0\n", - j, is_backside, - g_em->src_offset_x, g_em->src_offset_y, - g_em->dst_offset_x, g_em->dst_offset_y); - - if (g_em->width != TILEX || - g_em->height != TILEY) - printf(" %d (%d): size %d,%d should be %d,%d\n", - j, is_backside, - g_em->width, g_em->height, TILEX, TILEY); - - num_em_gfx_errors++; - } -#endif - } } - for (i = 0; i < TILE_MAX; i++) + for (i = 0; i < GAME_TILE_MAX; i++) { for (j = 0; j < 8; j++) { @@ -8926,9 +9046,9 @@ void InitGraphicInfo_EM(void) direction == MV_RIGHT ? (is_backside? Yspring_eB: Yspring_e) : Xspring); - /* no separate animation for "smashed by rock" -- use rock instead */ - struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][7 - j]; - struct GraphicInfo_EM *g_xx = &graphic_info_em_object[e][7 - j]; + // no separate animation for "smashed by rock" -- use rock instead + struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][j]; + struct GraphicInfo_EM *g_xx = &graphic_info_em_object[e][j]; g_em->bitmap = g_xx->bitmap; g_em->src_x = g_xx->src_x; @@ -8949,7 +9069,7 @@ void InitGraphicInfo_EM(void) for (p = 0; p < MAX_PLAYERS; p++) { - for (i = 0; i < SPR_MAX; i++) + for (i = 0; i < PLY_MAX; i++) { int element = player_mapping[p][i].element_rnd; int action = player_mapping[p][i].action; @@ -8964,17 +9084,10 @@ void InitGraphicInfo_EM(void) el_act_dir2img(effective_element, effective_action, direction)); struct GraphicInfo *g = &graphic_info[graphic]; - struct GraphicInfo_EM *g_em = &graphic_info_em_player[p][i][7 - j]; + struct GraphicInfo_EM *g_em = &graphic_info_em_player[p][i][j]; Bitmap *src_bitmap; int src_x, src_y; int sync_frame = j; - -#if DEBUG_EM_GFX - Bitmap *debug_bitmap = g_em->bitmap; - int debug_src_x = g_em->src_x; - int debug_src_y = g_em->src_y; -#endif - int frame = getAnimationFrame(g->anim_frames, g->anim_delay, g->anim_mode, @@ -8992,64 +9105,9 @@ void InitGraphicInfo_EM(void) g_em->dst_offset_y = 0; g_em->width = TILEX; g_em->height = TILEY; - -#if DEBUG_EM_GFX - - /* skip check for EMC elements not contained in original EMC artwork */ - if (element == EL_PLAYER_3 || - element == EL_PLAYER_4) - continue; - - if (g_em->bitmap != debug_bitmap || - g_em->src_x != debug_src_x || - g_em->src_y != debug_src_y) - { - static int last_i = -1; - - if (i != last_i) - { - printf("\n"); - last_i = i; - } - - printf("::: EMC GFX ERROR for p/a %d/%d -> %d ('%s', '%s', %d)", - p, i, element, element_info[element].token_name, - element_action_info[effective_action].suffix, direction); - - if (element != effective_element) - printf(" [%d ('%s')]", - effective_element, - element_info[effective_element].token_name); - - printf("\n"); - - if (g_em->bitmap != debug_bitmap) - printf(" %d: different bitmap! (0x%08x != 0x%08x)\n", - j, (int)(g_em->bitmap), (int)(debug_bitmap)); - - if (g_em->src_x != debug_src_x || - g_em->src_y != debug_src_y) - printf(" frame %d: %d,%d (%d,%d) should be %d,%d (%d,%d)\n", - j, - g_em->src_x, g_em->src_y, - g_em->src_x / 32, g_em->src_y / 32, - debug_src_x, debug_src_y, - debug_src_x / 32, debug_src_y / 32); - - num_em_gfx_errors++; - } -#endif - } } } - -#if DEBUG_EM_GFX - printf("\n"); - printf("::: [%d errors found]\n", num_em_gfx_errors); - - exit(0); -#endif } static void CheckSaveEngineSnapshot_EM(byte action[MAX_PLAYERS], int frame, @@ -9057,7 +9115,7 @@ static void CheckSaveEngineSnapshot_EM(byte action[MAX_PLAYERS], int frame, boolean any_player_snapping, boolean any_player_dropping) { - if (frame == 0 && !any_player_dropping) + if (frame == 7 && !any_player_dropping) { if (!local_player->was_waiting) { @@ -9109,17 +9167,19 @@ static void CheckSaveEngineSnapshot_MM(boolean element_clicked, } } -void CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame, - boolean any_player_moving, - boolean any_player_snapping, - boolean any_player_dropping) +boolean CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame, + boolean any_player_moving, + boolean any_player_snapping, + boolean any_player_dropping) { if (tape.single_step && tape.recording && !tape.pausing) - if (frame == 0 && !any_player_dropping) + if (frame == 7 && !any_player_dropping && FrameCounter > 6) TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); CheckSaveEngineSnapshot_EM(action, frame, any_player_moving, any_player_snapping, any_player_dropping); + + return tape.pausing; } void CheckSingleStepMode_SP(boolean murphy_is_waiting, @@ -9283,66 +9343,77 @@ void PlaySoundSelecting(void) #endif } -void ToggleFullscreenOrChangeWindowScalingIfNeeded(void) +void ToggleFullscreenIfNeeded(void) { - boolean change_fullscreen = (setup.fullscreen != - video.fullscreen_enabled); - boolean change_window_scaling_percent = (!video.fullscreen_enabled && - setup.window_scaling_percent != - video.window_scaling_percent); - - if (change_window_scaling_percent && video.fullscreen_enabled) + // if setup and video fullscreen state are already matching, nothing do do + if (setup.fullscreen == video.fullscreen_enabled || + !video.fullscreen_available) return; - if (!change_window_scaling_percent && !video.fullscreen_available) - return; + SDLSetWindowFullscreen(setup.fullscreen); -#if defined(TARGET_SDL2) - if (change_window_scaling_percent) - { - SDLSetWindowScaling(setup.window_scaling_percent); + // set setup value according to successfully changed fullscreen mode + setup.fullscreen = video.fullscreen_enabled; +} +void ChangeWindowScalingIfNeeded(void) +{ + // if setup and video window scaling are already matching, nothing do do + if (setup.window_scaling_percent == video.window_scaling_percent || + video.fullscreen_enabled) return; - } - else if (change_fullscreen) - { - SDLSetWindowFullscreen(setup.fullscreen); - /* set setup value according to successfully changed fullscreen mode */ - setup.fullscreen = video.fullscreen_enabled; + SDLSetWindowScaling(setup.window_scaling_percent); + + // set setup value according to successfully changed window scaling + setup.window_scaling_percent = video.window_scaling_percent; +} + +void ChangeVsyncModeIfNeeded(void) +{ + int setup_vsync_mode = VSYNC_MODE_STR_TO_INT(setup.vsync_mode); + int video_vsync_mode = video.vsync_mode; + // if setup and video vsync mode are already matching, nothing do do + if (setup_vsync_mode == video_vsync_mode) return; - } -#endif - if (change_fullscreen || - change_window_scaling_percent) + // if renderer is using OpenGL, vsync mode can directly be changed + SDLSetScreenVsyncMode(setup.vsync_mode); + + // if vsync mode unchanged, try re-creating renderer to set vsync mode + if (video.vsync_mode == video_vsync_mode) { Bitmap *tmp_backbuffer = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH); - /* save backbuffer content which gets lost when toggling fullscreen mode */ + // save backbuffer content which gets lost when re-creating screen BlitBitmap(backbuffer, tmp_backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); - if (change_window_scaling_percent) - { - /* keep window mode, but change window scaling */ - video.fullscreen_enabled = TRUE; /* force new window scaling */ - } + // force re-creating screen and renderer to set new vsync mode + video.fullscreen_enabled = !setup.fullscreen; - /* toggle fullscreen */ + // when creating new renderer, destroy textures linked to old renderer + FreeAllImageTextures(); // needs old renderer to free the textures + + // re-create screen and renderer (including change of vsync mode) ChangeVideoModeIfNeeded(setup.fullscreen); - /* set setup value according to successfully changed fullscreen mode */ + // set setup value according to successfully changed fullscreen mode setup.fullscreen = video.fullscreen_enabled; - /* restore backbuffer content from temporary backbuffer backup bitmap */ + // restore backbuffer content from temporary backbuffer backup bitmap BlitBitmap(tmp_backbuffer, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); - FreeBitmap(tmp_backbuffer); - /* update visible window/screen */ + // update visible window/screen BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); + + // when changing vsync mode, re-create textures for new renderer + InitImageTextures(); } + + // set setup value according to successfully changed vsync mode + setup.vsync_mode = VSYNC_MODE_INT_TO_STR(video.vsync_mode); } static void JoinRectangles(int *x, int *y, int *width, int *height, @@ -9362,6 +9433,8 @@ void SetAnimStatus(int anim_status_new) { if (anim_status_new == GAME_MODE_MAIN) anim_status_new = GAME_MODE_PSEUDO_MAINONLY; + else if (anim_status_new == GAME_MODE_NAMES) + anim_status_new = GAME_MODE_PSEUDO_NAMESONLY; else if (anim_status_new == GAME_MODE_SCORES) anim_status_new = GAME_MODE_PSEUDO_SCORESOLD; @@ -9371,7 +9444,11 @@ void SetAnimStatus(int anim_status_new) if ((global.anim_status == GAME_MODE_PSEUDO_MAINONLY && global.anim_status_next == GAME_MODE_PSEUDO_TYPENAME) || (global.anim_status == GAME_MODE_PSEUDO_TYPENAME && - global.anim_status_next == GAME_MODE_PSEUDO_MAINONLY)) + global.anim_status_next == GAME_MODE_PSEUDO_MAINONLY) || + (global.anim_status == GAME_MODE_PSEUDO_NAMESONLY && + global.anim_status_next == GAME_MODE_PSEUDO_TYPENAMES) || + (global.anim_status == GAME_MODE_PSEUDO_TYPENAMES && + global.anim_status_next == GAME_MODE_PSEUDO_NAMESONLY)) global.anim_status = global.anim_status_next; } @@ -9414,29 +9491,58 @@ void SetLevelSetInfo(char *identifier, int level_nr) levelset.level_nr = level_nr; } -boolean CheckIfPlayfieldViewportHasChanged(void) +boolean CheckIfAllViewportsHaveChanged(void) { - // if game status has not changed, playfield viewport has not changed either + // if game status has not changed, viewports have not changed either if (game_status == game_status_last) return FALSE; - // check if playfield viewport has changed with current game status + // check if all viewports have changed with current game status + struct RectWithBorder *vp_playfield = &viewport.playfield[game_status]; + struct RectWithBorder *vp_door_1 = &viewport.door_1[game_status]; + struct RectWithBorder *vp_door_2 = &viewport.door_2[game_status]; 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; + int new_dx = vp_door_1->x; + int new_dy = vp_door_1->y; + int new_dxsize = vp_door_1->width; + int new_dysize = vp_door_1->height; + int new_vx = vp_door_2->x; + int new_vy = vp_door_2->y; + int new_vxsize = vp_door_2->width; + int new_vysize = vp_door_2->height; - return (new_real_sx != REAL_SX || - new_real_sy != REAL_SY || - new_full_sxsize != FULL_SXSIZE || - new_full_sysize != FULL_SYSIZE); + boolean playfield_viewport_has_changed = + (new_real_sx != REAL_SX || + new_real_sy != REAL_SY || + new_full_sxsize != FULL_SXSIZE || + new_full_sysize != FULL_SYSIZE); + + boolean door_1_viewport_has_changed = + (new_dx != DX || + new_dy != DY || + new_dxsize != DXSIZE || + new_dysize != DYSIZE); + + boolean door_2_viewport_has_changed = + (new_vx != VX || + new_vy != VY || + new_vxsize != VXSIZE || + new_vysize != VYSIZE || + game_status_last == GAME_MODE_EDITOR); + + return (playfield_viewport_has_changed && + door_1_viewport_has_changed && + door_2_viewport_has_changed); } -boolean CheckIfGlobalBorderOrPlayfieldViewportHasChanged(void) +boolean CheckFadeAll(void) { return (CheckIfGlobalBorderHasChanged() || - CheckIfPlayfieldViewportHasChanged()); + CheckIfAllViewportsHaveChanged()); } void ChangeViewportPropertiesIfNeeded(void) @@ -9453,11 +9559,14 @@ void ChangeViewportPropertiesIfNeeded(void) struct RectWithBorder *vp_door_3 = &viewport.door_2[GAME_MODE_EDITOR]; int new_win_xsize = vp_window->width; int new_win_ysize = vp_window->height; - int border_size = vp_playfield->border_size; - int new_sx = vp_playfield->x + border_size; - int new_sy = vp_playfield->y + border_size; - int new_sxsize = vp_playfield->width - 2 * border_size; - int new_sysize = vp_playfield->height - 2 * border_size; + int border_left = vp_playfield->border_left; + int border_right = vp_playfield->border_right; + int border_top = vp_playfield->border_top; + int border_bottom = vp_playfield->border_bottom; + int new_sx = vp_playfield->x + border_left; + int new_sy = vp_playfield->y + border_top; + int new_sxsize = vp_playfield->width - border_left - border_right; + int new_sysize = vp_playfield->height - border_top - border_bottom; int new_real_sx = vp_playfield->x; int new_real_sy = vp_playfield->y; int new_full_sxsize = vp_playfield->width; @@ -9496,18 +9605,18 @@ void ChangeViewportPropertiesIfNeeded(void) init_gfx_buffers = TRUE; init_gadgets_and_anims = TRUE; - // printf("::: video: init_video_buffer, init_gfx_buffers\n"); + // Debug("tools:viewport", "video: init_video_buffer, init_gfx_buffers"); } if (new_scr_fieldx != SCR_FIELDX || new_scr_fieldy != SCR_FIELDY) { - /* this always toggles between MAIN and GAME when using small tile size */ + // 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"); + // Debug("tools:viewport", "new_scr_fieldx != SCR_FIELDX ..."); } if (new_sx != SX || @@ -9562,8 +9671,8 @@ void ChangeViewportPropertiesIfNeeded(void) } // add current and new door 2 area if position or size has changed - if (new_dx != VX || new_dy != VY || - new_dxsize != VXSIZE || new_dysize != VYSIZE) + if (new_vx != VX || new_vy != VY || + new_vxsize != VXSIZE || new_vysize != VYSIZE) { JoinRectangles(&FADE_SX, &FADE_SY, &FADE_SXSIZE, &FADE_SYSIZE, VX, VY, VXSIZE, VYSIZE); @@ -9577,7 +9686,7 @@ void ChangeViewportPropertiesIfNeeded(void) if (new_tilesize_var != TILESIZE_VAR) { - // printf("::: new_tilesize_var != TILESIZE_VAR\n"); + // Debug("tools:viewport", "new_tilesize_var != TILESIZE_VAR"); // changing tile size invalidates scroll values of engine snapshots FreeEngineSnapshotSingle(); @@ -9611,13 +9720,13 @@ void ChangeViewportPropertiesIfNeeded(void) init_gfx_buffers = TRUE; init_gadgets_and_anims = TRUE; - // printf("::: viewports: init_gfx_buffers\n"); - // printf("::: viewports: init_gadgets_and_anims\n"); + // Debug("tools:viewport", "viewports: init_gfx_buffers"); + // Debug("tools:viewport", "viewports: init_gadgets_and_anims"); } if (init_gfx_buffers) { - // printf("::: init_gfx_buffers\n"); + // Debug("tools:viewport", "init_gfx_buffers"); SCR_FIELDX = new_scr_fieldx_buffers; SCR_FIELDY = new_scr_fieldy_buffers; @@ -9633,7 +9742,9 @@ void ChangeViewportPropertiesIfNeeded(void) if (init_video_buffer) { - // printf("::: init_video_buffer\n"); + // Debug("tools:viewport", "init_video_buffer"); + + FreeAllImageTextures(); // needs old renderer to free the textures InitVideoBuffer(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, setup.fullscreen); InitImageTextures(); @@ -9641,7 +9752,7 @@ void ChangeViewportPropertiesIfNeeded(void) if (init_gadgets_and_anims) { - // printf("::: init_gadgets_and_anims\n"); + // Debug("tools:viewport", "init_gadgets_and_anims"); InitGadgets(); InitGlobalAnimations(); @@ -9649,6 +9760,6 @@ void ChangeViewportPropertiesIfNeeded(void) if (init_em_graphics) { - InitGraphicInfo_EM(); + InitGraphicInfo_EM(); } }