// (c) 1995-2014 by Artsoft Entertainment
// Holger Schemel
// info@artsoft.org
-// http://www.artsoft.org/
+// https://www.artsoft.org/
// ----------------------------------------------------------------------------
// tools.c
// ============================================================================
#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
#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
#define NUM_DOORS 2
}
};
+static struct XY xy_topdown[] =
+{
+ { 0, -1 },
+ { -1, 0 },
+ { +1, 0 },
+ { 0, +1 }
+};
+
// forward declaration for internal use
+static void MapToolButtons(unsigned int);
static void UnmapToolButtons(void);
static void HandleToolButtons(struct GadgetInfo *);
static int el_act_dir2crm(int, int, int);
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;
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;
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);
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);
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);
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);
int py = sy - SY;
int ly = LEVELY((py + dy) / TILESIZE_VAR);
- ly = correctLevelPosY_EM(ly);
-
return ly;
}
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)
}
}
+int GetDrawtoField(void)
+{
+ return (drawto_field == fieldbuffer ? DRAW_TO_FIELDBUFFER : DRAW_TO_BACKBUFFER);
+}
+
static void RedrawPlayfield_RND(void)
{
if (game.envelope_active)
if (game_status != GAME_MODE_PLAYING)
return;
- if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ if (level.game_engine_type == GAME_ENGINE_TYPE_BD)
+ RedrawPlayfield_BD(TRUE);
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
RedrawPlayfield_EM(TRUE);
else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
RedrawPlayfield_SP(TRUE);
Bitmap *src_bitmap = getGlobalBorderBitmapFromStatus(global.border_status);
Bitmap *dst_bitmap = gfx.masked_border_bitmap_ptr;
+ // may happen for "border.draw_masked.*" with undefined "global.border.*"
+ if (src_bitmap == NULL)
+ return;
+
if (x == -1 && y == -1)
return;
gfx.masked_border_bitmap_ptr = gfx.fade_bitmap_target;
}
+ // always use global border for PLAYING when restarting the game
+ if (global.border_status == GAME_MODE_PSEUDO_RESTARTING)
+ global.border_status = GAME_MODE_PLAYING;
+
DrawMaskedBorderExt(REDRAW_ALL, draw_target);
global.border_status = last_border_status;
}
}
-void DrawTileCursor(int draw_target)
+void DrawTileCursor(int draw_target, int drawing_stage)
{
- 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);
+ int tile_cursor_active = (game_status == GAME_MODE_PLAYING);
- 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, drawing_stage, tile_cursor_active);
+}
- 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)
{
- if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ if (level.game_engine_type == GAME_ENGINE_TYPE_BD)
+ BlitScreenToBitmap_BD(target_bitmap);
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
BlitScreenToBitmap_EM(target_bitmap);
else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
BlitScreenToBitmap_SP(target_bitmap);
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),
DrawFramesPerSecond();
// remove playfield redraw before potentially merging with doors redraw
- if (DrawingDeactivated(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE))
+ if (DrawingDeactivated(REAL_SX, REAL_SY))
redraw_mask &= ~REDRAW_FIELD;
// redraw complete window if both playfield and (some) doors need redraw
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);
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;
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)
{
global.border_status = game_status;
+
+ // always use global border for PLAYING when restarting the game
+ if (global.border_status == GAME_MODE_PSEUDO_RESTARTING)
+ global.border_status = GAME_MODE_PLAYING;
}
void FadeIn(int fade_mask)
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();
+ // when using BD game engine, cover playfield before fading out after a game
+ if (game_bd.cover_screen)
+ CoverScreen_BD();
+
SetScreenStates_BeforeFadingOut();
SetTileCursorActive(FALSE);
FadeExt(0, FADE_MODE_SKIP_FADE_OUT, FADE_TYPE_SKIP);
}
-static Bitmap *getBitmapFromGraphicOrDefault(int graphic, int default_graphic)
+static int getGlobalGameStatus(int status)
+{
+ return (status == GAME_MODE_PSEUDO_TYPENAME ? GAME_MODE_MAIN :
+ status == GAME_MODE_SCOREINFO ? GAME_MODE_SCORES :
+ status);
+}
+
+int getImageFromGraphicOrDefault(int graphic, int default_graphic)
{
if (graphic == IMG_UNDEFINED)
- return NULL;
+ return IMG_UNDEFINED;
boolean redefined = getImageListEntryFromImageID(graphic)->redefined;
return (graphic_info[graphic].bitmap != NULL || redefined ?
- graphic_info[graphic].bitmap :
- graphic_info[default_graphic].bitmap);
+ graphic : default_graphic);
}
-static Bitmap *getBackgroundBitmap(int graphic)
+static int getBackgroundImage(int graphic)
{
- return getBitmapFromGraphicOrDefault(graphic, IMG_BACKGROUND);
+ return getImageFromGraphicOrDefault(graphic, IMG_BACKGROUND);
}
-static Bitmap *getGlobalBorderBitmap(int graphic)
+static int getGlobalBorderImage(int graphic)
{
- return getBitmapFromGraphicOrDefault(graphic, IMG_GLOBAL_BORDER);
+ return getImageFromGraphicOrDefault(graphic, IMG_GLOBAL_BORDER);
}
-Bitmap *getGlobalBorderBitmapFromStatus(int status)
+Bitmap *getGlobalBorderBitmapFromStatus(int status_raw)
{
+ int status = getGlobalGameStatus(status_raw);
int graphic =
- (status == GAME_MODE_MAIN ||
- status == GAME_MODE_PSEUDO_TYPENAME ? IMG_GLOBAL_BORDER_MAIN :
- status == GAME_MODE_SCORES ? IMG_GLOBAL_BORDER_SCORES :
- status == GAME_MODE_EDITOR ? IMG_GLOBAL_BORDER_EDITOR :
- status == GAME_MODE_PLAYING ? IMG_GLOBAL_BORDER_PLAYING :
+ (status == GAME_MODE_MAIN ? IMG_GLOBAL_BORDER_MAIN :
+ status == GAME_MODE_SCORES ? IMG_GLOBAL_BORDER_SCORES :
+ status == GAME_MODE_EDITOR ? IMG_GLOBAL_BORDER_EDITOR :
+ status == GAME_MODE_PLAYING ? IMG_GLOBAL_BORDER_PLAYING :
IMG_GLOBAL_BORDER);
+ int graphic_final = getGlobalBorderImage(graphic);
+
+ return graphic_info[graphic_final].bitmap;
+}
+
+void SetBackgroundImage(int graphic, int redraw_mask)
+{
+ struct GraphicInfo *g = &graphic_info[graphic];
+ struct GraphicInfo g_undefined = { 0 };
- return getGlobalBorderBitmap(graphic);
+ if (graphic == IMG_UNDEFINED)
+ g = &g_undefined;
+
+ // always use original size bitmap for backgrounds, if existing
+ Bitmap *bitmap = (g->bitmaps != NULL &&
+ g->bitmaps[IMG_BITMAP_PTR_ORIGINAL] != NULL ?
+ g->bitmaps[IMG_BITMAP_PTR_ORIGINAL] : g->bitmap);
+
+ // remove every mask before setting mask for window, and
+ // remove window area mask before setting mask for main or door area
+ int remove_mask = (redraw_mask == REDRAW_ALL ? 0xffff : REDRAW_ALL);
+
+ // (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!)
+ SetBackgroundBitmap(NULL, remove_mask, 0, 0, 0, 0); // !!! FIX THIS !!!
+ SetBackgroundBitmap(bitmap, redraw_mask,
+ g->src_x, g->src_y,
+ g->width, g->height);
}
void SetWindowBackgroundImageIfDefined(int graphic)
{
if (graphic_info[graphic].bitmap)
- SetWindowBackgroundBitmap(graphic_info[graphic].bitmap);
+ SetBackgroundImage(graphic, REDRAW_ALL);
}
void SetMainBackgroundImageIfDefined(int graphic)
{
if (graphic_info[graphic].bitmap)
- SetMainBackgroundBitmap(graphic_info[graphic].bitmap);
+ SetBackgroundImage(graphic, REDRAW_FIELD);
}
void SetDoorBackgroundImageIfDefined(int graphic)
{
if (graphic_info[graphic].bitmap)
- SetDoorBackgroundBitmap(graphic_info[graphic].bitmap);
+ SetBackgroundImage(graphic, REDRAW_DOOR_1);
}
void SetWindowBackgroundImage(int graphic)
{
- SetWindowBackgroundBitmap(getBackgroundBitmap(graphic));
+ SetBackgroundImage(getBackgroundImage(graphic), REDRAW_ALL);
}
void SetMainBackgroundImage(int graphic)
{
- SetMainBackgroundBitmap(getBackgroundBitmap(graphic));
+ SetBackgroundImage(getBackgroundImage(graphic), REDRAW_FIELD);
}
void SetDoorBackgroundImage(int graphic)
{
- SetDoorBackgroundBitmap(getBackgroundBitmap(graphic));
+ SetBackgroundImage(getBackgroundImage(graphic), REDRAW_DOOR_1);
}
void SetPanelBackground(void)
{
- struct GraphicInfo *gfx = &graphic_info[IMG_BACKGROUND_PANEL];
-
- BlitBitmapTiled(gfx->bitmap, bitmap_db_panel, gfx->src_x, gfx->src_y,
- gfx->width, gfx->height, 0, 0, DXSIZE, DYSIZE);
-
- SetDoorBackgroundBitmap(bitmap_db_panel);
+ SetDoorBackgroundImage(IMG_BACKGROUND_PANEL);
}
void DrawBackground(int x, int y, int width, int height)
#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)
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)
}
}
-void FloodFillLevelExt(int from_x, int from_y, int fill_element,
+void FloodFillLevelExt(int start_x, int start_y, int fill_element,
int max_array_fieldx, int max_array_fieldy,
short field[max_array_fieldx][max_array_fieldy],
int max_fieldx, int max_fieldy)
{
- int i,x,y;
- int old_element;
- static int check[4][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } };
- static int safety = 0;
+ static struct XY stack_buffer[MAX_LEV_FIELDX * MAX_LEV_FIELDY];
+ struct XY *check = xy_topdown;
+ int old_element = field[start_x][start_y];
+ int stack_pos = 0;
- // check if starting field still has the desired content
- if (field[from_x][from_y] == fill_element)
+ // do nothing if start field already has the desired content
+ if (old_element == fill_element)
return;
- safety++;
+ stack_buffer[stack_pos++] = (struct XY){ start_x, start_y };
- if (safety > max_fieldx * max_fieldy)
- Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug.");
+ while (stack_pos > 0)
+ {
+ struct XY current = stack_buffer[--stack_pos];
+ int i;
- old_element = field[from_x][from_y];
- field[from_x][from_y] = fill_element;
+ field[current.x][current.y] = fill_element;
- for (i = 0; i < 4; i++)
- {
- x = from_x + check[i][0];
- y = from_y + check[i][1];
+ for (i = 0; i < 4; i++)
+ {
+ int x = current.x + check[i].x;
+ int y = current.y + check[i].y;
- if (IN_FIELD(x, y, max_fieldx, max_fieldy) && field[x][y] == old_element)
- FloodFillLevelExt(x, y, fill_element, max_array_fieldx, max_array_fieldy,
- field, max_fieldx, max_fieldy);
- }
+ // check for stack buffer overflow (should not happen)
+ if (stack_pos >= MAX_LEV_FIELDX * MAX_LEV_FIELDY)
+ Fail("Stack buffer overflow in 'FloodFillLevelExt()'. Please debug.");
- safety--;
+ if (IN_FIELD(x, y, max_fieldx, max_fieldy) && field[x][y] == old_element)
+ stack_buffer[stack_pos++] = (struct XY){ x, y };
+ }
+ }
}
void FloodFillLevel(int from_x, int from_y, int fill_element,
gfx.anim_random_frame = GfxRandom[x][y];
}
+void SetAnimationFirstLevel(int first_level)
+{
+ gfx.anim_first_level = first_level;
+}
+
int getGraphicAnimationFrame(int graphic, int sync_frame)
{
// animation synchronized with global frame counter, not move position
if (graphic_info[graphic].anim_global_sync || sync_frame < 0)
sync_frame = FrameCounter;
+ else if (graphic_info[graphic].anim_global_anim_sync)
+ sync_frame = getGlobalAnimSyncFrame();
return getAnimationFrame(graphic_info[graphic].anim_frames,
graphic_info[graphic].anim_delay,
sync_frame);
}
+int getGraphicAnimationFrameXY(int graphic, int lx, int ly)
+{
+ if (graphic_info[graphic].anim_mode & ANIM_TILED)
+ {
+ struct GraphicInfo *g = &graphic_info[graphic];
+ int xsize = MAX(1, g->anim_frames_per_line);
+ int ysize = MAX(1, g->anim_frames / xsize);
+ int xoffset = g->anim_start_frame % xsize;
+ int yoffset = g->anim_start_frame % ysize;
+ // may be needed if screen field is significantly larger than playfield
+ int x = (lx + xoffset + SCR_FIELDX * xsize) % xsize;
+ int y = (ly + yoffset + SCR_FIELDY * ysize) % ysize;
+ int sync_frame = y * xsize + x;
+
+ return sync_frame % g->anim_frames;
+ }
+ else if (graphic_info[graphic].anim_mode & ANIM_RANDOM_STATIC)
+ {
+ struct GraphicInfo *g = &graphic_info[graphic];
+ // may be needed if screen field is significantly larger than playfield
+ int x = (lx + SCR_FIELDX * lev_fieldx) % lev_fieldx;
+ int y = (ly + SCR_FIELDY * lev_fieldy) % lev_fieldy;
+ int sync_frame = GfxRandomStatic[x][y];
+
+ return sync_frame % g->anim_frames;
+ }
+ else
+ {
+ int sync_frame = (IN_LEV_FIELD(lx, ly) ? GfxFrame[lx][ly] : -1);
+
+ return getGraphicAnimationFrame(graphic, sync_frame);
+ }
+}
+
void getGraphicSourceBitmap(int graphic, int tilesize, Bitmap **bitmap)
{
struct GraphicInfo *g = &graphic_info[graphic];
if (tilesize == gfx.standard_tile_size)
*bitmap = g->bitmaps[IMG_BITMAP_STANDARD];
else if (tilesize == game.tile_size)
- *bitmap = g->bitmaps[IMG_BITMAP_GAME];
+ *bitmap = g->bitmaps[IMG_BITMAP_PTR_GAME];
else
*bitmap = g->bitmaps[IMG_BITMAP_1x1 - log_2(tilesize_capped)];
}
*g = graphic_info[IMG_CHAR_EXCLAM];
// if no in-game graphics defined, always use standard graphic size
- if (g->bitmaps[IMG_BITMAP_GAME] == NULL)
+ if (g->bitmaps[IMG_BITMAP_PTR_GAME] == NULL)
tilesize = TILESIZE;
getGraphicSourceBitmap(graphic, tilesize, bitmap);
getSizedGraphicSource(graphic, 0, MINI_TILESIZE, bitmap, x, y);
}
+void getGlobalAnimGraphicSource(int graphic, int frame,
+ Bitmap **bitmap, int *x, int *y)
+{
+ struct GraphicInfo *g = &graphic_info[graphic];
+
+ // if no graphics defined at all, use fallback graphics
+ if (g->bitmaps == NULL)
+ *g = graphic_info[IMG_CHAR_EXCLAM];
+
+ // use original size graphics, if existing, else use standard size graphics
+ if (g->bitmaps[IMG_BITMAP_PTR_ORIGINAL])
+ *bitmap = g->bitmaps[IMG_BITMAP_PTR_ORIGINAL];
+ else
+ *bitmap = g->bitmaps[IMG_BITMAP_STANDARD];
+
+ getGraphicSourceXY(graphic, frame, x, y, FALSE);
+}
+
static void getGraphicSourceExt(int graphic, int frame, Bitmap **bitmap,
int *x, int *y, boolean get_backside)
{
#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
#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
#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
#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
void DrawMiniGraphic(int x, int y, int graphic)
{
- DrawMiniGraphicExt(drawto, SX + x * MINI_TILEX,SY + y * MINI_TILEY, graphic);
+ DrawMiniGraphicExt(drawto, SX + x * MINI_TILEX, SY + y * MINI_TILEY, graphic);
MarkTileDirty(x / 2, y / 2);
}
#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
}
if (graphic_info[graphic].double_movement) // EM style movement images
- DrawGraphicShiftedDouble(x, y, dx, dy, graphic, frame, cut_mode,mask_mode);
+ DrawGraphicShiftedDouble(x, y, dx, dy, graphic, frame, cut_mode, mask_mode);
else
- DrawGraphicShiftedNormal(x, y, dx, dy, graphic, frame, cut_mode,mask_mode);
+ DrawGraphicShiftedNormal(x, y, dx, dy, graphic, frame, cut_mode, mask_mode);
}
static void DrawGraphicShiftedThruMask(int x, int y, int dx, int dy,
if (IN_LEV_FIELD(lx, ly))
{
+ if (element == EL_EMPTY)
+ element = GfxElementEmpty[lx][ly];
+
SetRandomAnimationValue(lx, ly);
graphic = el_act_dir2img(element, GfxAction[lx][ly], GfxDir[lx][ly]);
- frame = getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]);
+ frame = getGraphicAnimationFrameXY(graphic, lx, ly);
// 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]);
+ frame = getGraphicAnimationFrameXY(graphic, lx, ly);
}
+
+ if (game.use_masked_elements && (dx || dy))
+ mask_mode = USE_MASKING;
}
else // border element
{
graphic = el2img(element);
- frame = getGraphicAnimationFrame(graphic, -1);
+ frame = getGraphicAnimationFrameXY(graphic, lx, ly);
}
if (element == EL_EXPANDABLE_WALL)
{
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)
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 !!!
cx = (dx > 0 ? TILESIZE_VAR - width : 0);
cy = (dy > 0 ? TILESIZE_VAR - height : 0);
- BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
- width, height, FX + sx * TILEX_VAR + cx, FY + sy * TILEY_VAR + cy);
+ if (game.use_masked_elements)
+ {
+ int graphic0 = el2img(EL_EMPTY);
+ int frame0 = getGraphicAnimationFrameXY(graphic0, x, y);
+ Bitmap *src_bitmap0;
+ int src_x0, src_y0;
+
+ getGraphicSource(graphic0, frame0, &src_bitmap0, &src_x0, &src_y0);
+
+ BlitBitmap(src_bitmap0, drawto_field, src_x0 + cx, src_y0 + cy,
+ width, height,
+ FX + sx * TILEX_VAR + cx, FY + sy * TILEY_VAR + cy);
+
+ BlitBitmapMasked(src_bitmap, drawto_field, src_x + cx, src_y + cy,
+ width, height,
+ FX + sx * TILEX_VAR + cx, FY + sy * TILEY_VAR + cy);
+ }
+ else
+ BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
+ width, height,
+ FX + sx * TILEX_VAR + cx, FY + sy * TILEY_VAR + cy);
}
static void DrawLevelFieldCrumbledBorders(int x, int y, int graphic, int frame,
getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
+ // only needed when using masked elements
+ int graphic0 = el2img(EL_EMPTY);
+ int frame0 = getGraphicAnimationFrameXY(graphic0, x, y);
+ Bitmap *src_bitmap0;
+ int src_x0, src_y0;
+
+ if (game.use_masked_elements)
+ getGraphicSource(graphic0, frame0, &src_bitmap0, &src_x0, &src_y0);
+
// draw simple, sloppy, non-corner-accurate crumbled border
width = (dir == 1 || dir == 2 ? crumbled_border_size_var : TILESIZE_VAR);
cx = (dir == 2 ? crumbled_border_pos_var : 0);
cy = (dir == 3 ? crumbled_border_pos_var : 0);
- BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy, width, height,
- FX + sx * TILEX_VAR + cx,
- FY + sy * TILEY_VAR + cy);
+ if (game.use_masked_elements)
+ {
+ BlitBitmap(src_bitmap0, drawto_field, src_x0 + cx, src_y0 + cy,
+ width, height,
+ FX + sx * TILEX_VAR + cx,
+ FY + sy * TILEY_VAR + cy);
+
+ BlitBitmapMasked(src_bitmap, drawto_field, src_x + cx, src_y + cy,
+ width, height,
+ FX + sx * TILEX_VAR + cx,
+ FY + sy * TILEY_VAR + cy);
+ }
+ else
+ BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
+ width, height,
+ FX + sx * TILEX_VAR + cx,
+ FY + sy * TILEY_VAR + cy);
// (remaining middle border part must be at least as big as corner part)
if (!(graphic_info[graphic].style & STYLE_ACCURATE_BORDERS) ||
by = cy;
}
- BlitBitmap(src_bitmap, drawto_field, src_x + bx, src_y + by,
- width, height,
- FX + sx * TILEX_VAR + cx,
- FY + sy * TILEY_VAR + cy);
+ if (game.use_masked_elements)
+ {
+ BlitBitmap(src_bitmap0, drawto_field, src_x0 + bx, src_y0 + by,
+ width, height,
+ FX + sx * TILEX_VAR + cx,
+ FY + sy * TILEY_VAR + cy);
+
+ BlitBitmapMasked(src_bitmap, drawto_field, src_x + bx, src_y + by,
+ width, height,
+ FX + sx * TILEX_VAR + cx,
+ FY + sy * TILEY_VAR + cy);
+ }
+ else
+ BlitBitmap(src_bitmap, drawto_field, src_x + bx, src_y + by,
+ width, height,
+ FX + sx * TILEX_VAR + cx,
+ FY + sy * TILEY_VAR + cy);
}
}
}
int sx = SCREENX(x), sy = SCREENY(y);
int element;
int i;
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
if (!IN_LEV_FIELD(x, y))
return;
// crumble field borders towards direct neighbour fields
for (i = 0; i < 4; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) :
BorderElement);
// crumble field borders of direct neighbour fields
for (i = 0; i < 4; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
- int sxx = sx + xy[i][0];
- int syy = sy + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
+ int sxx = sx + xy[i].x;
+ int syy = sy + xy[i].y;
if (!IN_LEV_FIELD(xx, yy) ||
!IN_SCR_FIELD(sxx, syy))
continue;
// do not crumble fields that are being digged or snapped
- if (Feld[xx][yy] == EL_EMPTY ||
- Feld[xx][yy] == EL_ELEMENT_SNAPPING)
+ if (Tile[xx][yy] == EL_EMPTY ||
+ Tile[xx][yy] == EL_ELEMENT_SNAPPING)
continue;
element = TILE_GFX_ELEMENT(xx, yy);
!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);
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]))
{
int frame2 = getGraphicAnimationFrame(graphic2, step_frame);
int sx = SCREENX(x), sy = SCREENY(y);
- DrawGraphic(sx, sy, graphic1, frame1);
+ DrawScreenGraphic(sx, sy, graphic1, frame1);
DrawLevelFieldCrumbledExt(x, y, graphic2, frame2);
}
void DrawLevelFieldCrumbledNeighbours(int x, int y)
{
int sx = SCREENX(x), sy = SCREENY(y);
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
int i;
// crumble direct neighbour fields (required for field borders)
for (i = 0; i < 4; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
- int sxx = sx + xy[i][0];
- int syy = sy + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
+ int sxx = sx + xy[i].x;
+ int syy = sy + xy[i].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;
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;
return border[steel_position][steel_type];
}
+void DrawScreenGraphic(int x, int y, int graphic, int frame)
+{
+ if (game.use_masked_elements)
+ {
+ if (graphic != el2img(EL_EMPTY))
+ DrawScreenElementExt(x, y, 0, 0, EL_EMPTY, NO_CUTTING, NO_MASKING);
+
+ DrawGraphicThruMask(x, y, graphic, frame);
+ }
+ else
+ {
+ DrawGraphic(x, y, graphic, frame);
+ }
+}
+
+void DrawLevelGraphic(int x, int y, int graphic, int frame)
+{
+ DrawScreenGraphic(SCREENX(x), SCREENY(y), graphic, frame);
+}
+
void DrawScreenElement(int x, int y, int element)
{
- DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
+ int mask_mode = NO_MASKING;
+
+ if (game.use_masked_elements)
+ {
+ int lx = LEVELX(x), ly = LEVELY(y);
+
+ if (IN_LEV_FIELD(lx, ly) && element != EL_EMPTY)
+ {
+ DrawScreenElementExt(x, y, 0, 0, EL_EMPTY, NO_CUTTING, NO_MASKING);
+
+ mask_mode = USE_MASKING;
+ }
+ }
+
+ DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, mask_mode);
DrawLevelFieldCrumbled(LEVELX(x), LEVELY(y));
}
return;
}
- element = Feld[lx][ly];
+ element = Tile[lx][ly];
content = Store[lx][ly];
if (IS_MOVING(lx, ly))
else
DrawScreenElement(x, y, EL_EMPTY);
+ if (cut_mode != CUT_BELOW && game.use_masked_elements)
+ {
+ int dir = MovDir[lx][ly];
+ int newx = x + (dir == MV_LEFT ? -1 : dir == MV_RIGHT ? +1 : 0);
+ int newy = y + (dir == MV_UP ? -1 : dir == MV_DOWN ? +1 : 0);
+
+ if (IN_SCR_FIELD(newx, newy))
+ DrawScreenElement(newx, newy, EL_EMPTY);
+ }
+
if (horiz_move)
DrawScreenElementShifted(x, y, MovPos[lx][ly], 0, element, NO_CUTTING);
else if (cut_mode == NO_CUTTING)
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 ||
DrawScreenField(SCREENX(x), SCREENY(y));
else if (IS_MOVING(x, y))
{
- int newx,newy;
+ int newx, newy;
Moving2Blocked(x, y, &newx, &newy);
if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
}
else
{
- int graphic = el2edimg(element);
+ int graphic, frame;
+
+ el2edimg_with_frame(element, &graphic, &frame);
if (masked)
- DrawSizedGraphicThruMask(x, y, graphic, 0, tilesize);
+ DrawSizedGraphicThruMask(x, y, graphic, frame, tilesize);
else
- DrawSizedGraphic(x, y, graphic, 0, tilesize);
+ DrawSizedGraphic(x, y, graphic, frame, tilesize);
}
}
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);
}
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)));
}
int mask_mode = (src_bitmap != NULL ? BLIT_MASKED : BLIT_ON_BACKGROUND);
boolean ffwd_delay = (tape.playing && tape.fast_forward);
boolean no_delay = (tape.warp_forward);
- unsigned int anim_delay = 0;
int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay);
int anim_delay_value = MAX(1, (no_delay ? 0 : frame_delay_value) / 2);
+ DelayCounter anim_delay = { anim_delay_value };
int font_nr = FONT_ENVELOPE_1 + envelope_nr;
int font_width = getFontWidth(font_nr);
int font_height = getFontHeight(font_nr);
for (xx = 0; xx < xsize; xx++)
DrawEnvelopeBackground(graphic, sx, sy, xx, yy, xsize, ysize, font_nr);
- DrawTextBuffer(sx + font_width, sy + font_height,
- level.envelope[envelope_nr].text, font_nr, max_xsize,
- xsize - 2, ysize - 2, 0, mask_mode,
- level.envelope[envelope_nr].autowrap,
- level.envelope[envelope_nr].centered, FALSE);
+ DrawTextArea(sx + font_width, sy + font_height,
+ level.envelope[envelope_nr].text, font_nr, max_xsize,
+ xsize - 2, ysize - 2, 0, mask_mode,
+ level.envelope[envelope_nr].autowrap,
+ level.envelope[envelope_nr].centered, FALSE);
redraw_mask |= REDRAW_FIELD;
BackToFront();
- SkipUntilDelayReached(&anim_delay, anim_delay_value, &i, last_frame);
+ SkipUntilDelayReached(&anim_delay, &i, last_frame);
}
ClearAutoRepeatKeyEvents();
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
+ SetOverlayEnabled(FALSE);
+ UnmapAllGadgets();
+
PlayMenuSoundStereo(sound_opening, SOUND_MIDDLE);
if (anim_mode == ANIM_DEFAULT)
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)
BackToFront();
}
+static void PrepareEnvelopeRequestToScreen(Bitmap *bitmap, int sx, int sy,
+ int xsize, int ysize)
+{
+ if (!global.use_envelope_request)
+ 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);
+
+ // create masked surface for request bitmap, if needed
+ if (graphic_info[IMG_BACKGROUND_REQUEST].draw_masked)
+ {
+ SDL_Surface *surface = request.bitmap->surface;
+ SDL_Surface *surface_masked = request.bitmap->surface_masked;
+
+ SDLBlitSurface(surface, surface_masked, 0, 0, xsize, ysize, 0, 0);
+ SDL_SetColorKey(surface_masked, SET_TRANSPARENT_PIXEL,
+ SDL_MapRGB(surface_masked->format, 0x00, 0x00, 0x00));
+ }
+
+ SDLFreeBitmapTextures(request.bitmap);
+ SDLCreateBitmapTextures(request.bitmap);
+
+ ResetBitmapAlpha(request.bitmap);
+
+ // set envelope request run-time values
+ request.sx = sx;
+ request.sy = sy;
+ request.xsize = xsize;
+ request.ysize = ysize;
+}
+
+void DrawEnvelopeRequestToScreen(int drawing_target)
+{
+ if (global.use_envelope_request &&
+ game.request_active &&
+ drawing_target == DRAW_TO_SCREEN)
+ {
+ struct GraphicInfo *g = &graphic_info[IMG_BACKGROUND_REQUEST];
+
+ SetBitmapAlphaNextBlit(request.bitmap, g->alpha);
+
+ if (g->draw_masked)
+ BlitToScreenMasked(request.bitmap, 0, 0, request.xsize, request.ysize,
+ request.sx, request.sy);
+ else
+ BlitToScreen(request.bitmap, 0, 0, request.xsize, request.ysize,
+ request.sx, request.sy);
+ }
+}
+
static void setRequestBasePosition(int *x, int *y)
{
int sx_base, sy_base;
setRequestPositionExt(x, y, request.width, request.height, add_border_size);
}
-static void DrawEnvelopeRequest(char *text)
+static void DrawEnvelopeRequestText(int sx, int sy, char *text)
{
char *text_final = text;
char *text_door_style = NULL;
int line_length = max_text_width / font_width;
int max_lines = max_text_height / line_height;
int text_width = line_length * font_width;
- int width = request.width;
- int height = request.height;
- int tile_size = MAX(request.step_offset, 1);
- int x_steps = width / tile_size;
- int y_steps = height / tile_size;
int sx_offset = border_size;
int sy_offset = border_size;
- int sx, sy;
- int i, x, y;
+
+ // force DOOR font inside door area
+ SetFontStatus(GAME_MODE_PSEUDO_DOOR);
if (request.centered)
sx_offset = (request.width - text_width) / 2;
{
char *src_text_ptr, *dst_text_ptr;
+ if (maxWordLengthInRequestString(text) > line_length)
+ {
+ font_nr = FONT_REQUEST_NARROW;
+ font_width = getFontWidth(font_nr);
+ line_length = max_text_width / font_width;
+ }
+
text_door_style = checked_malloc(2 * strlen(text) + 1);
src_text_ptr = text;
text_final = text_door_style;
}
+ DrawTextBuffer(sx + sx_offset, sy + sy_offset, text_final, font_nr,
+ line_length, -1, max_lines, line_spacing, mask_mode,
+ request.autowrap, request.centered, FALSE);
+
+ if (text_door_style)
+ free(text_door_style);
+
+ ResetFontStatus();
+}
+
+static void DrawEnvelopeRequest(char *text, unsigned int req_state)
+{
+ DrawBuffer *drawto_last = drawto;
+ int graphic = IMG_BACKGROUND_REQUEST;
+ int width = request.width;
+ int height = request.height;
+ int tile_size = MAX(request.step_offset, 1);
+ int x_steps = width / tile_size;
+ int y_steps = height / tile_size;
+ int sx, sy;
+ int x, y;
+
setRequestPosition(&sx, &sy, FALSE);
- ClearRectangle(backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE);
+ // draw complete envelope request to temporary bitmap
+ drawto = bitmap_db_store_1;
+
+ ClearRectangle(drawto, sx, sy, width, height);
for (y = 0; y < y_steps; y++)
for (x = 0; x < x_steps; x++)
x, y, x_steps, y_steps,
tile_size, tile_size);
- // force DOOR font inside door area
- SetFontStatus(GAME_MODE_PSEUDO_DOOR);
-
- DrawTextBuffer(sx + sx_offset, sy + sy_offset, text_final, font_nr,
- line_length, -1, max_lines, line_spacing, mask_mode,
- request.autowrap, request.centered, FALSE);
-
- ResetFontStatus();
+ // write text for request
+ DrawEnvelopeRequestText(sx, sy, text);
- for (i = 0; i < NUM_TOOL_BUTTONS; i++)
- RedrawGadget(tool_gadget[i]);
+ MapToolButtons(req_state);
- // store readily prepared envelope request for later use when animating
- BlitBitmap(backbuffer, bitmap_db_store_2, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+ // restore pointer to drawing buffer
+ drawto = drawto_last;
- if (text_door_style)
- free(text_door_style);
+ // prepare complete envelope request from temporary bitmap
+ PrepareEnvelopeRequestToScreen(bitmap_db_store_1, sx, sy, width, height);
}
static void AnimateEnvelopeRequest(int anim_mode, int action)
{
- int graphic = IMG_BACKGROUND_REQUEST;
- boolean draw_masked = graphic_info[graphic].draw_masked;
+ boolean game_ended = (game_status == GAME_MODE_PLAYING && checkGameEnded());
int delay_value_normal = request.step_delay;
int delay_value_fast = delay_value_normal / 2;
boolean ffwd_delay = (tape.playing && tape.fast_forward);
boolean no_delay = (tape.warp_forward);
int delay_value = (ffwd_delay ? delay_value_fast : delay_value_normal);
- int anim_delay_value = MAX(1, (no_delay ? 0 : delay_value + 500 * 0) / 2);
- unsigned int anim_delay = 0;
+ int anim_delay_value = MAX(1, (no_delay ? 0 : delay_value) / 2);
+ DelayCounter anim_delay = { anim_delay_value };
int tile_size = MAX(request.step_offset, 1);
int max_xsize = request.width / tile_size;
int dst_x, dst_y;
int xx, yy;
+ if (game_ended)
+ HandleGameActions();
+
setRequestPosition(&src_x, &src_y, FALSE);
setRequestPositionExt(&dst_x, &dst_y, width, height, FALSE);
- BlitBitmap(bitmap_db_store_1, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
-
for (yy = 0; yy < 2; yy++)
{
for (xx = 0; xx < 2; xx++)
int xx_size = (xx ? tile_size : xsize_size_left);
int yy_size = (yy ? tile_size : ysize_size_top);
- if (draw_masked)
- BlitBitmapMasked(bitmap_db_store_2, backbuffer,
- src_xx, src_yy, xx_size, yy_size, dst_xx, dst_yy);
- else
- BlitBitmap(bitmap_db_store_2, backbuffer,
- src_xx, src_yy, xx_size, yy_size, dst_xx, dst_yy);
+ // draw partial (animated) envelope request to temporary bitmap
+ BlitBitmap(bitmap_db_store_1, bitmap_db_store_2,
+ src_xx, src_yy, xx_size, yy_size, dst_xx, dst_yy);
}
}
+ // prepare partial (animated) envelope request from temporary bitmap
+ PrepareEnvelopeRequestToScreen(bitmap_db_store_2, dst_x, dst_y,
+ width, height);
+
redraw_mask |= REDRAW_FIELD;
BackToFront();
- SkipUntilDelayReached(&anim_delay, anim_delay_value, &i, last_frame);
+ SkipUntilDelayReached(&anim_delay, &i, last_frame);
}
ClearAutoRepeatKeyEvents();
int main_anim_mode = (anim_mode == ANIM_NONE ? ANIM_VERTICAL|ANIM_HORIZONTAL:
anim_mode == ANIM_DEFAULT ? ANIM_VERTICAL : anim_mode);
- if (game_status == GAME_MODE_PLAYING)
- BlitScreenToBitmap(backbuffer);
-
- SetDrawtoField(DRAW_TO_BACKBUFFER);
-
- // SetDrawBackgroundMask(REDRAW_NONE);
-
- if (action == ACTION_OPENING)
- {
- BlitBitmap(backbuffer, bitmap_db_store_1, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
-
- if (req_state & REQ_ASK)
- {
- MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
- MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
- }
- else if (req_state & REQ_CONFIRM)
- {
- MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
- }
- else if (req_state & REQ_PLAYER)
- {
- MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
- MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
- MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
- MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
- }
-
- DrawEnvelopeRequest(text);
- }
-
game.envelope_active = TRUE; // needed for RedrawPlayfield() events
if (action == ACTION_OPENING)
}
game.envelope_active = FALSE;
+}
- if (action == ACTION_CLOSING)
- BlitBitmap(bitmap_db_store_1, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
-
- // SetDrawBackgroundMask(last_draw_background_mask);
-
- redraw_mask |= REDRAW_FIELD;
-
- BackToFront();
+static Bitmap *GetPreviewTileBitmap(Bitmap *bitmap)
+{
+ if (level.game_engine_type == GAME_ENGINE_TYPE_BD)
+ return GetPreviewTileBitmap_BD(bitmap);
- if (action == ACTION_CLOSING &&
- game_status == GAME_MODE_PLAYING &&
- level.game_engine_type == GAME_ENGINE_TYPE_RND)
- SetDrawtoField(DRAW_TO_FIELDBUFFER);
+ return bitmap;
}
static void DrawPreviewElement(int dst_x, int dst_y, int element, int tilesize)
int graphic = el2preimg(element);
getSizedGraphicSource(graphic, 0, tilesize, &src_bitmap, &src_x, &src_y);
+
+ // for BD style levels, maybe use bitmap with level-specific colors
+ src_bitmap = GetPreviewTileBitmap(src_bitmap);
+
BlitBitmap(src_bitmap, drawto, src_x, src_y, tilesize, tilesize,
dst_x, dst_y);
}
void DrawLevel(int draw_background_mask)
{
- int x,y;
+ int x, y;
SetMainBackgroundImage(IMG_BACKGROUND_PLAYING);
SetDrawBackgroundMask(draw_background_mask);
void DrawSizedLevel(int size_x, int size_y, int scroll_x, int scroll_y,
int tilesize)
{
- int x,y;
+ int x, y;
for (x = 0; x < size_x; x++)
for (y = 0; y < size_y; y++)
void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
{
- int x,y;
+ int x, y;
for (x = 0; x < size_x; x++)
for (y = 0; y < size_y; y++)
redraw_mask |= REDRAW_FIELD;
}
+static int getPreviewLevelWidth(void)
+{
+ if (level.game_engine_type == GAME_ENGINE_TYPE_BD)
+ return (level.native_bd_level->cave->x2 - level.native_bd_level->cave->x1 + 1);
+
+ return lev_fieldx;
+}
+
+static int getPreviewLevelHeight(void)
+{
+ if (level.game_engine_type == GAME_ENGINE_TYPE_BD)
+ return (level.native_bd_level->cave->y2 - level.native_bd_level->cave->y1 + 1);
+
+ return lev_fieldy;
+}
+
static void DrawPreviewLevelPlayfield(int from_x, int from_y)
{
boolean show_level_border = (BorderElement != EL_EMPTY);
- int level_xsize = lev_fieldx + (show_level_border ? 2 : 0);
- int level_ysize = lev_fieldy + (show_level_border ? 2 : 0);
+ int level_xsize = getPreviewLevelWidth() + (show_level_border ? 2 : 0);
+ int level_ysize = getPreviewLevelHeight() + (show_level_border ? 2 : 0);
int tile_size = preview.tile_size;
int preview_width = preview.xsize * tile_size;
int preview_height = preview.ysize * tile_size;
static void DrawPreviewLevelExt(boolean restart)
{
- static unsigned int scroll_delay = 0;
- static unsigned int label_delay = 0;
+ static DelayCounter scroll_delay = { 0 };
+ static DelayCounter label_delay = { 0 };
static int from_x, from_y, scroll_direction;
static int label_state, label_counter;
- unsigned int scroll_delay_value = preview.step_delay;
boolean show_level_border = (BorderElement != EL_EMPTY);
int level_xsize = lev_fieldx + (show_level_border ? 2 : 0);
int level_ysize = lev_fieldy + (show_level_border ? 2 : 0);
+ scroll_delay.value = preview.step_delay;
+ label_delay.value = MICROLEVEL_LABEL_DELAY;
+
if (restart)
{
from_x = 0;
DrawPreviewLevelInfo(MICROLABEL_LEVEL_AUTHOR);
// initialize delay counters
- DelayReached(&scroll_delay, 0);
- DelayReached(&label_delay, 0);
+ ResetDelayCounter(&scroll_delay);
+ ResetDelayCounter(&label_delay);
if (leveldir_current->name)
{
// 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))
+ DelayReached(&scroll_delay))
{
switch (scroll_direction)
{
if (!strEqual(level.name, NAMELESS_LEVEL_NAME) &&
!strEqual(level.author, ANONYMOUS_NAME) &&
!strEqual(level.author, leveldir_current->name) &&
- DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
+ DelayReached(&label_delay))
{
int max_label_counter = 23;
{
int element = level.field[x][y];
- if (ELEM_IS_PLAYER(element))
+ if (IS_PLAYER_ELEMENT(element))
{
int player_nr = GET_PLAYER_NR(element);
}
}
+static void PreparePreviewTileBitmap(void)
+{
+ // check if special preview bitmap with level-specific colors should be created
+ if (level.game_engine_type != GAME_ENGINE_TYPE_BD)
+ return;
+
+ // use original sized bitmap (else reduced color palette is lost by downscaling)
+ int original_tilesize = MAX(MINI_TILESIZE, preview.tile_size);
+ int scale_down_factor = original_tilesize / preview.tile_size;
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int element_template = EL_BDX_GAME_GRAPHICS_COLOR_TEMPLATE;
+ int graphic_template = el2preimg(element_template);
+ int element_default = EL_BDX_ROCK;
+ int graphic_default = el2preimg(element_default);
+
+ // create special preview bitmap and scale it down to preview tile size
+ getSizedGraphicSource(graphic_template, 0, original_tilesize, &src_bitmap, &src_x, &src_y);
+ PreparePreviewTileBitmap_BD(src_bitmap, scale_down_factor);
+
+ // force using special preview bitmap to replace original preview bitmap
+ getSizedGraphicSource(graphic_default, 0, preview.tile_size, &src_bitmap, &src_x, &src_y);
+ SetPreviewTileBitmapReference_BD(src_bitmap);
+}
+
void DrawPreviewLevelInitial(void)
{
+ PreparePreviewTileBitmap(); // only needed for native BD style levels
+
DrawPreviewLevelExt(TRUE);
DrawPreviewPlayers();
}
}
static void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y,
- int graphic, int sync_frame,
+ int graphic, int lx, int ly,
int mask_mode)
{
- int frame = getGraphicAnimationFrame(graphic, sync_frame);
+ int frame = getGraphicAnimationFrameXY(graphic, lx, ly);
if (mask_mode == USE_MASKING)
DrawGraphicThruMaskExt(dst_bitmap, x, y, graphic, frame);
DrawFixedGraphicExt(dst_bitmap, x, y, graphic, frame);
}
+void DrawSizedGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y,
+ int graphic, int sync_frame, int tilesize,
+ int mask_mode)
+{
+ int frame = getGraphicAnimationFrame(graphic, sync_frame);
+
+ if (mask_mode == USE_MASKING)
+ DrawSizedGraphicThruMaskExt(dst_bitmap, x, y, graphic, frame, tilesize);
+ else
+ DrawSizedGraphicExt(dst_bitmap, x, y, graphic, frame, tilesize);
+}
+
static void DrawGraphicAnimation(int x, int y, int graphic)
{
int lx = LEVELX(x), ly = LEVELY(y);
+ int mask_mode = NO_MASKING;
if (!IN_SCR_FIELD(x, y))
return;
+ if (game.use_masked_elements)
+ {
+ if (Tile[lx][ly] != EL_EMPTY)
+ {
+ DrawScreenElementExt(x, y, 0, 0, EL_EMPTY, NO_CUTTING, NO_MASKING);
+
+ mask_mode = USE_MASKING;
+ }
+ }
+
DrawGraphicAnimationExt(drawto_field, FX + x * TILEX_VAR, FY + y * TILEY_VAR,
- graphic, GfxFrame[lx][ly], NO_MASKING);
+ graphic, lx, ly, mask_mode);
MarkTileDirty(x, y);
}
void DrawFixedGraphicAnimation(int x, int y, int graphic)
{
int lx = LEVELX(x), ly = LEVELY(y);
+ int mask_mode = NO_MASKING;
if (!IN_SCR_FIELD(x, y))
return;
+ if (game.use_masked_elements)
+ {
+ if (Tile[lx][ly] != EL_EMPTY)
+ {
+ DrawScreenElementExt(x, y, 0, 0, EL_EMPTY, NO_CUTTING, NO_MASKING);
+
+ mask_mode = USE_MASKING;
+ }
+ }
+
DrawGraphicAnimationExt(drawto_field, FX + x * TILEX, FY + y * TILEY,
- graphic, GfxFrame[lx][ly], NO_MASKING);
+ graphic, lx, ly, mask_mode);
+
MarkTileDirty(x, y);
}
if (!IN_LEV_FIELD(x, y) || !IN_SCR_FIELD(sx, sy))
return;
+ if (Tile[x][y] == EL_EMPTY)
+ graphic = el2img(GfxElementEmpty[x][y]);
+
if (!IS_NEW_FRAME(GfxFrame[x][y], graphic))
return;
+ if (ANIM_MODE(graphic) & (ANIM_TILED | ANIM_RANDOM_STATIC))
+ return;
+
DrawGraphicAnimation(sx, sy, graphic);
#if 1
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
}
return graphic;
}
else
- return el_act_dir2img(player->artwork_element, player->GfxAction,move_dir);
+ return el_act_dir2img(player->artwork_element, player->GfxAction, move_dir);
}
static boolean equalGraphics(int graphic1, int graphic2)
#if DEBUG
if (!IN_LEV_FIELD(player->jx, player->jy))
{
- printf("DrawPlayerField(): x = %d, y = %d\n", player->jx, player->jy);
- printf("DrawPlayerField(): This should never happen!\n");
+ Debug("draw:DrawPlayerExt", "x = %d, y = %d", player->jx, player->jy);
+ Debug("draw:DrawPlayerExt", "This should never happen!");
draw_player[pnr] = FALSE;
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 = Feld[jx][jy];
- int last_element = Feld[last_jx][last_jy];
+ 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 :
DrawDynamite(last_jx, last_jy);
else
DrawLevelField(last_jx, last_jy);
-
- if (player->is_pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
- DrawLevelElement(next_jx, next_jy, EL_EMPTY);
}
else if (drawing_stage == DRAW_PLAYER_STAGE_FIELD_UNDER_PLAYER)
{
if (GFX_CRUMBLED(old_element))
DrawLevelFieldCrumbledDigging(jx, jy, move_dir, player->StepFrame);
else
- DrawGraphic(sx, sy, old_graphic, frame);
+ DrawScreenGraphic(sx, sy, old_graphic, frame);
if (graphic_info[old_graphic].anim_mode & ANIM_OPAQUE_PLAYER)
static_player_is_opaque[pnr] = TRUE;
if (!player->is_pushing || !player->is_moving)
return;
+ if (Tile[next_jx][next_jy] == EL_EXPLOSION)
+ return;
+
int gfx_frame = GfxFrame[jx][jy];
if (!IS_MOVING(jx, jy)) // push movement already finished
{
- element = Feld[next_jx][next_jy];
+ element = Tile[next_jx][next_jy];
gfx_frame = GfxFrame[next_jx][next_jy];
}
DrawLevelElement(jx, jy, Back[jx][jy]);
else
DrawLevelElement(jx, jy, EL_EMPTY);
-
- if (Back[next_jx][next_jy])
- DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
- else
- DrawLevelElement(next_jx, next_jy, EL_EMPTY);
}
- else if (Back[next_jx][next_jy])
+
+ if (Back[next_jx][next_jy])
DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
+ else
+ DrawLevelElement(next_jx, next_jy, EL_EMPTY);
int px = SCREENX(jx), py = SCREENY(jy);
int pxx = (TILEX - ABS(sxx)) * dx;
// 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
if (IS_ACTIVE_BOMB(element))
{
int graphic = el2img(element);
- int frame = getGraphicAnimationFrame(graphic, GfxFrame[jx][jy]);
+ int frame = getGraphicAnimationFrameXY(graphic, jx, jy);
if (game.emulation == EMU_SUPAPLEX)
DrawGraphic(sx, sy, IMG_SP_DISK_RED, frame);
void WaitForEventToContinue(void)
{
+ boolean first_wait = TRUE;
boolean still_wait = TRUE;
if (program.headless)
button_status = MB_RELEASED;
ClearEventQueue();
+ ClearPlayerAction();
while (still_wait)
{
{
switch (event.type)
{
- case EVENT_BUTTONRELEASE:
+ 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:
case SDL_JOYBUTTONDOWN:
still_wait = FALSE;
break;
- case EVENT_KEYRELEASE:
- ClearPlayerAction();
- break;
-
default:
HandleOtherEvents(&event);
break;
still_wait = FALSE;
}
- BackToFront();
+ if (!PendingEvent())
+ BackToFront();
}
}
-#define MAX_REQUEST_LINES 13
-#define MAX_REQUEST_LINE_FONT1_LEN 7
-#define MAX_REQUEST_LINE_FONT2_LEN 10
-
-static int RequestHandleEvents(unsigned int req_state)
+static int RequestHandleEvents(unsigned int req_state, int draw_buffer_game)
{
- boolean game_just_ended = (game_status == GAME_MODE_PLAYING &&
- checkGameEnded());
+ boolean game_ended = (game_status == GAME_MODE_PLAYING && checkGameEnded());
+ int draw_buffer_last = GetDrawtoField();
int width = request.width;
int height = request.height;
int sx, sy;
int result;
- // when showing request dialog after game ended, deactivate game panel
- if (game_just_ended)
- game.panel.active = FALSE;
-
- game.request_active = TRUE;
-
setRequestPosition(&sx, &sy, FALSE);
button_status = MB_RELEASED;
while (result < 0)
{
- if (game_just_ended)
+ if (game_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();
SetDrawtoField(DRAW_TO_BACKBUFFER);
-
- if (global.use_envelope_request)
- {
- // copy current state of request area to middle of playfield area
- BlitBitmap(bitmap_db_store_2, drawto, sx, sy, width, height, sx, sy);
- }
}
if (PendingEvent())
case EVENT_BUTTONRELEASE:
case EVENT_MOTIONNOTIFY:
{
+ DrawBuffer *drawto_last = drawto;
int mx, my;
if (event.type == EVENT_MOTIONNOTIFY)
button_status = MB_RELEASED;
}
+ if (global.use_envelope_request)
+ {
+ // draw changed button states to temporary bitmap
+ drawto = bitmap_db_store_1;
+ }
+
// this sets 'request_gadget_id'
HandleGadgets(mx, my, button_status);
+ if (global.use_envelope_request)
+ {
+ // restore pointer to drawing buffer
+ drawto = drawto_last;
+
+ // prepare complete envelope request from temporary bitmap
+ PrepareEnvelopeRequestToScreen(bitmap_db_store_1, sx, sy,
+ width, height);
+ }
+
switch (request_gadget_id)
{
case TOOL_CTRL_ID_YES:
+ 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;
break;
}
+ // only needed to handle clickable pointer animations here
+ HandleGlobalAnimClicks(mx, my, button_status, FALSE);
+
break;
}
case EVENT_KEYPRESS:
{
- Key key = GetEventKey((KeyEvent *)&event, TRUE);
+ Key key = GetEventKey((KeyEvent *)&event);
switch (key)
{
break;
}
+ case EVENT_FINGERRELEASE:
case EVENT_KEYRELEASE:
ClearPlayerAction();
break;
}
}
- if (game_just_ended)
- {
- if (global.use_envelope_request)
- {
- // copy back current state of pressed buttons inside request area
- BlitBitmap(drawto, bitmap_db_store_2, sx, sy, width, height, sx, sy);
- }
- }
-
BackToFront();
}
- game.request_active = FALSE;
+ SetDrawtoField(draw_buffer_last);
return result;
}
-static boolean RequestDoor(char *text, unsigned int req_state)
+static void DoRequestBefore(void)
{
- unsigned int old_door_state;
- int max_request_line_len = MAX_REQUEST_LINE_FONT1_LEN;
- int font_nr = FONT_TEXT_2;
- char *text_ptr;
- int result;
- int ty;
+ boolean game_ended = (game_status == GAME_MODE_PLAYING && checkGameEnded());
- if (maxWordLengthInRequestString(text) > MAX_REQUEST_LINE_FONT1_LEN)
- {
- max_request_line_len = MAX_REQUEST_LINE_FONT2_LEN;
- font_nr = FONT_TEXT_1;
- }
+ // when showing request dialog after game ended, deactivate game panel
+ if (game_ended)
+ game.panel.active = FALSE;
if (game_status == GAME_MODE_PLAYING)
BlitScreenToBitmap(backbuffer);
// pause network game while waiting for request to answer
if (network.enabled &&
game_status == GAME_MODE_PLAYING &&
- !game.all_players_gone &&
- req_state & REQUEST_WAIT_FOR_INPUT)
+ !game.all_players_gone)
SendToServer_PausePlaying();
- old_door_state = GetDoorState();
-
// simulate releasing mouse button over last gadget, if still pressed
if (button_status)
HandleGadgets(-1, -1, 0);
UnmapAllGadgets();
+}
- // draw released gadget before proceeding
- // BackToFront();
+static void DoRequestAfter(void)
+{
+ RemapAllGadgets();
- if (old_door_state & DOOR_OPEN_1)
+ if (game_status == GAME_MODE_PLAYING)
{
- CloseDoor(DOOR_CLOSE_1);
+ SetPanelBackground();
+ SetDrawBackgroundMask(REDRAW_DOOR_1);
+ }
+ else
+ {
+ SetDrawBackgroundMask(REDRAW_FIELD);
+ }
- // save old door content
- BlitBitmap(bitmap_db_door_1, bitmap_db_door_1,
- 0 * DXSIZE, 0, DXSIZE, DYSIZE, 1 * DXSIZE, 0);
+ // continue network game after request
+ if (network.enabled &&
+ game_status == GAME_MODE_PLAYING &&
+ !game.all_players_gone)
+ SendToServer_ContinuePlaying();
+
+ // restore deactivated drawing when quick-loading level tape recording
+ if (tape.playing && tape.deactivate_display)
+ TapeDeactivateDisplayOn();
+}
+
+static void setRequestDoorTextProperties(char *text,
+ int text_spacing,
+ int line_spacing,
+ int *set_font_nr,
+ int *set_max_lines,
+ int *set_max_line_length)
+{
+ struct RectWithBorder *vp_door_1 = &viewport.door_1[game_status];
+ struct TextPosInfo *pos = &request.button.confirm;
+ int button_ypos = pos->y;
+ int font_nr = FONT_TEXT_2;
+ int font_width = getFontWidth(font_nr);
+ int font_height = getFontHeight(font_nr);
+ int line_height = font_height + line_spacing;
+ int max_text_width = vp_door_1->width;
+ int max_text_height = button_ypos - 2 * text_spacing;
+ int max_line_length = max_text_width / font_width;
+ int max_lines = max_text_height / line_height;
+
+ if (maxWordLengthInRequestString(text) > max_line_length)
+ {
+ font_nr = FONT_TEXT_1;
+ font_width = getFontWidth(font_nr);
+ max_line_length = max_text_width / font_width;
}
- SetDoorBackgroundImage(IMG_BACKGROUND_DOOR);
- SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
+ *set_font_nr = font_nr;
+ *set_max_lines = max_lines;
+ *set_max_line_length = max_line_length;
+}
- // clear door drawing field
- DrawBackground(DX, DY, DXSIZE, DYSIZE);
+static void DrawRequestDoorText(char *text)
+{
+ char *text_ptr = text;
+ int text_spacing = 8;
+ int line_spacing = 2;
+ int max_request_lines;
+ int max_request_line_len;
+ int font_nr;
+ int ty;
// force DOOR font inside door area
SetFontStatus(GAME_MODE_PSEUDO_DOOR);
- // write text for request
- for (text_ptr = text, ty = 0; ty < MAX_REQUEST_LINES; ty++)
+ setRequestDoorTextProperties(text, text_spacing, line_spacing, &font_nr,
+ &max_request_lines, &max_request_line_len);
+
+ for (text_ptr = text, ty = 0; ty < max_request_lines; ty++)
{
char text_line[max_request_line_len + 1];
int tx, tl, tc = 0;
for (tl = 0, tx = 0; tx < max_request_line_len; tl++, tx++)
{
tc = *(text_ptr + tx);
- // if (!tc || tc == ' ')
if (!tc || tc == ' ' || tc == '?' || tc == '!')
break;
}
text_line[tl] = 0;
DrawText(DX + (DXSIZE - tl * getFontWidth(font_nr)) / 2,
- DY + 8 + ty * (getFontHeight(font_nr) + 2),
+ DY + text_spacing + ty * (getFontHeight(font_nr) + line_spacing),
text_line, font_nr);
text_ptr += tl + (tc == ' ' ? 1 : 0);
- // text_ptr += tl + (tc == ' ' || tc == '?' || tc == '!' ? 1 : 0);
}
ResetFontStatus();
+}
- if (req_state & REQ_ASK)
- {
- MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
- MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
- }
- else if (req_state & REQ_CONFIRM)
- {
- MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
- }
- else if (req_state & REQ_PLAYER)
+static int RequestDoor(char *text, unsigned int req_state)
+{
+ unsigned int old_door_state = GetDoorState();
+ int draw_buffer_last = GetDrawtoField();
+ int result;
+
+ if (old_door_state & DOOR_OPEN_1)
{
- MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
- MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
- MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
- MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
+ CloseDoor(DOOR_CLOSE_1);
+
+ // save old door content
+ BlitBitmap(bitmap_db_door_1, bitmap_db_door_1,
+ 0, 0, DXSIZE, DYSIZE, DXSIZE, 0);
}
- // copy request gadgets to door backbuffer
- BlitBitmap(drawto, bitmap_db_door_1, DX, DY, DXSIZE, DYSIZE, 0, 0);
+ SetDoorBackgroundImage(IMG_BACKGROUND_DOOR);
+ SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
- OpenDoor(DOOR_OPEN_1);
+ // clear door drawing field
+ DrawBackground(DX, DY, DXSIZE, DYSIZE);
- if (!(req_state & REQUEST_WAIT_FOR_INPUT))
- {
- if (game_status == GAME_MODE_PLAYING)
- {
- SetPanelBackground();
- SetDrawBackgroundMask(REDRAW_DOOR_1);
- }
- else
- {
- SetDrawBackgroundMask(REDRAW_FIELD);
- }
+ // write text for request
+ DrawRequestDoorText(text);
- return FALSE;
- }
+ MapToolButtons(req_state);
- SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
+ // copy request gadgets to door backbuffer
+ BlitBitmap(drawto, bitmap_db_door_1, DX, DY, DXSIZE, DYSIZE, 0, 0);
+
+ OpenDoor(DOOR_OPEN_1);
// ---------- handle request buttons ----------
- result = RequestHandleEvents(req_state);
+ result = RequestHandleEvents(req_state, draw_buffer_last);
UnmapToolButtons();
OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
}
- RemapAllGadgets();
+ return result;
+}
- if (game_status == GAME_MODE_PLAYING)
- {
- SetPanelBackground();
- SetDrawBackgroundMask(REDRAW_DOOR_1);
- }
- else
- {
- SetDrawBackgroundMask(REDRAW_FIELD);
- }
+static int RequestEnvelope(char *text, unsigned int req_state)
+{
+ int draw_buffer_last = GetDrawtoField();
+ int result;
- // continue network game after request
- if (network.enabled &&
- game_status == GAME_MODE_PLAYING &&
- !game.all_players_gone &&
- req_state & REQUEST_WAIT_FOR_INPUT)
- SendToServer_ContinuePlaying();
+ DrawEnvelopeRequest(text, req_state);
+ ShowEnvelopeRequest(text, req_state, ACTION_OPENING);
- // restore deactivated drawing when quick-loading level tape recording
- if (tape.playing && tape.deactivate_display)
- TapeDeactivateDisplayOn();
+ // ---------- handle request buttons ----------
+ result = RequestHandleEvents(req_state, draw_buffer_last);
+
+ UnmapToolButtons();
+
+ ShowEnvelopeRequest(text, req_state, ACTION_CLOSING);
return result;
}
-static boolean RequestEnvelope(char *text, unsigned int req_state)
+int Request(char *text, unsigned int req_state)
{
+ boolean overlay_enabled = GetOverlayEnabled();
int result;
- if (game_status == GAME_MODE_PLAYING)
- BlitScreenToBitmap(backbuffer);
-
- // disable deactivated drawing when quick-loading level tape recording
- if (tape.playing && tape.deactivate_display)
- TapeDeactivateDisplayOff(TRUE);
+ game.request_active = TRUE;
- SetMouseCursor(CURSOR_DEFAULT);
+ SetOverlayEnabled(FALSE);
- // pause network game while waiting for request to answer
- if (network.enabled &&
- game_status == GAME_MODE_PLAYING &&
- !game.all_players_gone &&
- req_state & REQUEST_WAIT_FOR_INPUT)
- SendToServer_PausePlaying();
-
- // simulate releasing mouse button over last gadget, if still pressed
- if (button_status)
- HandleGadgets(-1, -1, 0);
-
- UnmapAllGadgets();
-
- // (replace with setting corresponding request background)
- // SetDoorBackgroundImage(IMG_BACKGROUND_DOOR);
- // SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
-
- // clear door drawing field
- // DrawBackground(DX, DY, DXSIZE, DYSIZE);
-
- ShowEnvelopeRequest(text, req_state, ACTION_OPENING);
-
- if (!(req_state & REQUEST_WAIT_FOR_INPUT))
- {
- if (game_status == GAME_MODE_PLAYING)
- {
- SetPanelBackground();
- SetDrawBackgroundMask(REDRAW_DOOR_1);
- }
- else
- {
- SetDrawBackgroundMask(REDRAW_FIELD);
- }
-
- return FALSE;
- }
-
- SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
-
- // ---------- handle request buttons ----------
- result = RequestHandleEvents(req_state);
-
- UnmapToolButtons();
-
- ShowEnvelopeRequest(text, req_state, ACTION_CLOSING);
-
- RemapAllGadgets();
-
- if (game_status == GAME_MODE_PLAYING)
- {
- SetPanelBackground();
- SetDrawBackgroundMask(REDRAW_DOOR_1);
- }
- else
- {
- SetDrawBackgroundMask(REDRAW_FIELD);
- }
-
- // continue network game after request
- if (network.enabled &&
- game_status == GAME_MODE_PLAYING &&
- !game.all_players_gone &&
- req_state & REQUEST_WAIT_FOR_INPUT)
- SendToServer_ContinuePlaying();
-
- // restore deactivated drawing when quick-loading level tape recording
- if (tape.playing && tape.deactivate_display)
- TapeDeactivateDisplayOn();
-
- return result;
-}
-
-boolean Request(char *text, unsigned int req_state)
-{
- boolean overlay_enabled = GetOverlayEnabled();
- boolean result;
-
- SetOverlayEnabled(FALSE);
+ DoRequestBefore();
if (global.use_envelope_request)
result = RequestEnvelope(text, req_state);
else
result = RequestDoor(text, req_state);
+ DoRequestAfter();
+
SetOverlayEnabled(overlay_enabled);
+ game.request_active = FALSE;
+
return result;
}
};
static int door1 = DOOR_CLOSE_1;
static int door2 = DOOR_CLOSE_2;
- unsigned int door_delay = 0;
- unsigned int door_delay_value;
+ DelayCounter door_delay = { 0 };
int i;
if (door_state == DOOR_GET_STATE)
if (door_state & DOOR_ACTION)
{
+ boolean game_ended = (game_status == GAME_MODE_PLAYING && checkGameEnded());
boolean door_panel_drawn[NUM_DOORS];
boolean panel_has_doors[NUM_DOORS];
boolean door_part_skip[MAX_DOOR_PARTS];
int num_move_steps = 0; // number of animation steps for all doors
int max_move_delay_doors_only = 0; // delay for doors only (no panel)
int num_move_steps_doors_only = 0; // steps for doors only (no panel)
- int current_move_delay = 0;
int start = 0;
int k;
num_move_steps = max_move_delay / max_step_delay;
num_move_steps_doors_only = max_move_delay_doors_only / max_step_delay;
- door_delay_value = max_step_delay;
+ door_delay.value = max_step_delay;
if ((door_state & DOOR_NO_DELAY) || setup.quick_doors)
{
}
}
+ SetDoorBackgroundImage(IMG_BACKGROUND_DOOR);
+
+ game.any_door_active = TRUE;
+
for (k = start; k < num_move_steps; k++)
{
int last_frame = num_move_steps - 1; // last frame of this "for" loop
{
int k2_door = (door_opening ? k : num_move_steps_doors_only - k - 1);
int kk_door = MAX(0, k2_door);
- int sync_frame = kk_door * door_delay_value;
+ int sync_frame = kk_door * door_delay.value;
int frame = getGraphicAnimationFrame(dpc->graphic, sync_frame);
getFixedGraphicSource(dpc->graphic, frame, &bitmap,
if (!door_panel_drawn[door_index])
{
- ClearRectangle(drawto, door_rect->x, door_rect->y,
- door_rect->width, door_rect->height);
+ ClearRectangleOnBackground(drawto, door_rect->x, door_rect->y,
+ door_rect->width, door_rect->height);
door_panel_drawn[door_index] = TRUE;
}
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
if (!(door_state & DOOR_NO_DELAY))
{
- BackToFront();
+ if (game_ended)
+ HandleGameActions();
- SkipUntilDelayReached(&door_delay, door_delay_value, &k, last_frame);
+ BackToFront();
- current_move_delay += max_step_delay;
+ SkipUntilDelayReached(&door_delay, &k, last_frame);
// prevent OS (Windows) from complaining about program not responding
CheckQuitEvent();
{
// 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);
+ door_delay.value = MAX(door_1.post_delay, door_2.post_delay);
else if (door_state & DOOR_ACTION_1)
- door_delay_value = door_1.post_delay;
+ door_delay.value = door_1.post_delay;
else if (door_state & DOOR_ACTION_2)
- door_delay_value = door_2.post_delay;
+ door_delay.value = door_2.post_delay;
+
+ while (!DelayReached(&door_delay))
+ {
+ if (game_ended)
+ HandleGameActions();
- while (!DelayReached(&door_delay, door_delay_value))
BackToFront();
+ }
}
+
+ game.any_door_active = FALSE;
}
if (door_state & DOOR_ACTION_1)
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"
}
};
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;
int y = pos->y;
int id = i;
- if (global.use_envelope_request)
+ // do not use touch buttons if overlay touch buttons are disabled
+ if (is_touch_button && !setup.touch.overlay_buttons)
+ continue;
+
+ 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 ||
}
}
- if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
+ if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4 &&
+ pos->draw_player)
{
int player_nr = id - TOOL_CTRL_ID_PLAYER_1;
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,
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;
}
FreeGadget(tool_gadget[i]);
}
+static void MapToolButtons(unsigned int req_state)
+{
+ if (req_state & REQ_ASK)
+ {
+ MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
+ MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
+ MapGadget(tool_gadget[TOOL_CTRL_ID_TOUCH_YES]);
+ MapGadget(tool_gadget[TOOL_CTRL_ID_TOUCH_NO]);
+ }
+ else if (req_state & REQ_CONFIRM)
+ {
+ MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
+ MapGadget(tool_gadget[TOOL_CTRL_ID_TOUCH_CONFIRM]);
+ }
+ else if (req_state & REQ_PLAYER)
+ {
+ MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
+ MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
+ MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
+ MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
+ }
+}
+
static void UnmapToolButtons(void)
{
int i;
request_gadget_id = gi->custom_id;
}
-static struct Mapping_EM_to_RND_object
+static int getEngineElement_Ext(int element, int game_engine_type, boolean is_drawing_element)
{
- int element_em;
- boolean is_rnd_to_em_mapping; // unique mapping EM <-> RND
- boolean is_backside; // backside of moving element
+ int el_empty;
+ int el_player;
+ int el_sand;
+ int el_wall;
+ int el_steelwall;
+ int el_exit_closed;
+
+ if (game_engine_type == -1)
+ game_engine_type = level.game_engine_type;
+
+ if (level.game_engine_type == GAME_ENGINE_TYPE_BD)
+ {
+ el_empty = EL_EMPTY;
+ el_player = EL_BDX_PLAYER;
+ el_sand = EL_BDX_SAND_1;
+ el_wall = EL_BDX_WALL;
+ el_steelwall = EL_BDX_STEELWALL;
+ el_exit_closed = EL_BDX_EXIT_CLOSED;
+ }
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ {
+ el_empty = EL_EMPTY;
+ el_player = EL_PLAYER_1;
+ el_sand = EL_SAND;
+ el_wall = EL_WALL;
+ el_steelwall = EL_STEELWALL;
+ el_exit_closed = EL_EM_EXIT_CLOSED;
+ }
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
+ {
+ el_empty = EL_EMPTY;
+ el_player = EL_SP_MURPHY;
+ el_sand = EL_SP_BASE;
+ el_wall = EL_SP_CHIP_SINGLE;
+ el_steelwall = EL_SP_HARDWARE_GRAY;
+ el_exit_closed = EL_SP_EXIT_CLOSED;
+ }
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_MM)
+ {
+ el_empty = EL_EMPTY;
+ el_player = EL_MM_MCDUFFIN_DOWN;
+ el_sand = EL_EMPTY;
+ el_wall = EL_MM_WOODEN_WALL;
+ el_steelwall = EL_MM_STEEL_WALL;
+ el_exit_closed = EL_MM_EXIT_CLOSED;
+
+ if (is_drawing_element)
+ {
+ el_wall = EL_MM_MIRROR_START;
+ el_sand = EL_MM_WOODEN_WALL;
+ }
+ }
+ else
+ {
+ el_empty = EL_EMPTY;
+ el_player = EL_PLAYER_1;
+ el_sand = EL_SAND;
+ el_wall = EL_WALL;
+ el_steelwall = EL_STEELWALL;
+ el_exit_closed = EL_EXIT_CLOSED;
+ }
+
+ return (element == EL_EMPTY ? el_empty :
+ element == EL_PLAYER_1 ? el_player :
+ element == EL_SAND ? el_sand :
+ element == EL_WALL ? el_wall :
+ element == EL_STEELWALL ? el_steelwall :
+ element == EL_EXIT_CLOSED ? el_exit_closed : EL_EMPTY);
+}
+
+int getEngineElement(int element)
+{
+ return getEngineElement_Ext(element, -1, FALSE);
+}
+
+int getDrawingElement(int element)
+{
+ return getEngineElement_Ext(element, -1, TRUE);
+}
+
+static struct Mapping_BD_to_RND_object
+{
+ int element_bd;
+ boolean is_rnd_to_bd_mapping; // unique mapping BD <-> RND
int element_rnd;
int action;
int direction;
}
-em_object_mapping_list[] =
+bd_object_mapping_list[] =
{
+ // additional RND style elements mapped to BD style elements (must be listed first)
+
{
- Xblank, TRUE, FALSE,
- EL_EMPTY, -1, -1
+ O_DIRT, TRUE,
+ EL_SAND, -1, -1
},
{
- Yacid_splash_eB, FALSE, FALSE,
- EL_ACID_SPLASH_RIGHT, -1, -1
+ O_STONE, TRUE,
+ EL_BD_ROCK, -1, -1
},
{
- Yacid_splash_wB, FALSE, FALSE,
- EL_ACID_SPLASH_LEFT, -1, -1
+ O_BRICK, TRUE,
+ EL_BD_WALL, -1, -1
},
-
-#ifdef EM_ENGINE_BAD_ROLL
{
- Xstone_force_e, FALSE, FALSE,
- EL_ROCK, -1, MV_BIT_RIGHT
+ O_STEEL, TRUE,
+ EL_STEELWALL, -1, -1
},
{
- Xstone_force_w, FALSE, FALSE,
- EL_ROCK, -1, MV_BIT_LEFT
+ O_DIAMOND, TRUE,
+ EL_BD_DIAMOND, -1, -1
},
{
- Xnut_force_e, FALSE, FALSE,
- EL_NUT, -1, MV_BIT_RIGHT
+ O_INBOX, TRUE,
+ EL_PLAYER_1, -1, -1
},
{
- Xnut_force_w, FALSE, FALSE,
- EL_NUT, -1, MV_BIT_LEFT
+ O_INBOX, TRUE,
+ EL_PLAYER_2, -1, -1
},
{
- Xspring_force_e, FALSE, FALSE,
- EL_SPRING, -1, MV_BIT_RIGHT
+ O_INBOX, TRUE,
+ EL_PLAYER_3, -1, -1
},
{
- Xspring_force_w, FALSE, FALSE,
- EL_SPRING, -1, MV_BIT_LEFT
+ O_INBOX, TRUE,
+ EL_PLAYER_4, -1, -1
},
{
- Xemerald_force_e, FALSE, FALSE,
- EL_EMERALD, -1, MV_BIT_RIGHT
+ O_PRE_OUTBOX, TRUE,
+ EL_EXIT_CLOSED, -1, -1
},
+
+ // BD style elements with their corresponding RND style elements
+
{
- Xemerald_force_w, FALSE, FALSE,
- EL_EMERALD, -1, MV_BIT_LEFT
+ O_SPACE, TRUE,
+ EL_EMPTY, -1, -1
},
{
- Xdiamond_force_e, FALSE, FALSE,
- EL_DIAMOND, -1, MV_BIT_RIGHT
+ O_DIRT, TRUE,
+ EL_BDX_SAND_1, -1, -1
},
{
- Xdiamond_force_w, FALSE, FALSE,
- EL_DIAMOND, -1, MV_BIT_LEFT
+ O_DIRT_SLOPED_UP_RIGHT, TRUE,
+ EL_BDX_SAND_SLOPED_UP_RIGHT, -1, -1
},
{
- Xbomb_force_e, FALSE, FALSE,
- EL_BOMB, -1, MV_BIT_RIGHT
+ O_DIRT_SLOPED_UP_LEFT, TRUE,
+ EL_BDX_SAND_SLOPED_UP_LEFT, -1, -1
},
{
- Xbomb_force_w, FALSE, FALSE,
- EL_BOMB, -1, MV_BIT_LEFT
+ O_DIRT_SLOPED_DOWN_LEFT, TRUE,
+ EL_BDX_SAND_SLOPED_DOWN_LEFT, -1, -1
},
-#endif // EM_ENGINE_BAD_ROLL
-
{
- Xstone, TRUE, FALSE,
- EL_ROCK, -1, -1
+ O_DIRT_SLOPED_DOWN_RIGHT, TRUE,
+ EL_BDX_SAND_SLOPED_DOWN_RIGHT, -1, -1
},
{
- Xstone_pause, FALSE, FALSE,
- EL_ROCK, -1, -1
+ O_DIRT_BALL, TRUE,
+ EL_BDX_SAND_BALL, -1, -1
},
{
- Xstone_fall, FALSE, FALSE,
- EL_ROCK, -1, -1
+ O_DIRT_BALL_F, TRUE,
+ EL_BDX_SAND_BALL_FALLING, -1, -1
},
{
- Ystone_s, FALSE, FALSE,
- EL_ROCK, ACTION_FALLING, -1
+ O_DIRT_BALL_F, FALSE,
+ EL_BDX_SAND_BALL, ACTION_FALLING, -1
},
{
- Ystone_sB, FALSE, TRUE,
- EL_ROCK, ACTION_FALLING, -1
+ O_DIRT_LOOSE, TRUE,
+ EL_BDX_SAND_LOOSE, -1, -1
},
{
- Ystone_e, FALSE, FALSE,
- EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT
+ O_DIRT_LOOSE_F, TRUE,
+ EL_BDX_SAND_LOOSE_FALLING, -1, -1
},
{
- Ystone_eB, FALSE, TRUE,
- EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT
+ O_DIRT_LOOSE_F, FALSE,
+ EL_BDX_SAND_LOOSE, ACTION_FALLING, -1
},
{
- Ystone_w, FALSE, FALSE,
- EL_ROCK, ACTION_MOVING, MV_BIT_LEFT
+ O_DIRT2, TRUE,
+ EL_BDX_SAND_2, -1, -1
},
{
- Ystone_wB, FALSE, TRUE,
- EL_ROCK, ACTION_MOVING, MV_BIT_LEFT
+ O_BRICK, TRUE,
+ EL_BDX_WALL, -1, -1
},
{
- Xnut, TRUE, FALSE,
- EL_NUT, -1, -1
+ O_BRICK_SLOPED_UP_RIGHT, TRUE,
+ EL_BDX_WALL_SLOPED_UP_RIGHT, -1, -1
},
{
- Xnut_pause, FALSE, FALSE,
- EL_NUT, -1, -1
+ O_BRICK_SLOPED_UP_LEFT, TRUE,
+ EL_BDX_WALL_SLOPED_UP_LEFT, -1, -1
},
{
- Xnut_fall, FALSE, FALSE,
- EL_NUT, -1, -1
+ O_BRICK_SLOPED_DOWN_LEFT, TRUE,
+ EL_BDX_WALL_SLOPED_DOWN_LEFT, -1, -1
},
{
- Ynut_s, FALSE, FALSE,
- EL_NUT, ACTION_FALLING, -1
+ O_BRICK_SLOPED_DOWN_RIGHT, TRUE,
+ EL_BDX_WALL_SLOPED_DOWN_RIGHT, -1, -1
},
{
- Ynut_sB, FALSE, TRUE,
- EL_NUT, ACTION_FALLING, -1
+ O_BRICK_NON_SLOPED, TRUE,
+ EL_BDX_WALL_NON_SLOPED, -1, -1
},
{
- Ynut_e, FALSE, FALSE,
- EL_NUT, ACTION_MOVING, MV_BIT_RIGHT
+ O_MAGIC_WALL, TRUE,
+ EL_BDX_MAGIC_WALL, ACTION_ACTIVE, -1
},
{
- Ynut_eB, FALSE, TRUE,
- EL_NUT, ACTION_MOVING, MV_BIT_RIGHT
+ O_PRE_OUTBOX, TRUE,
+ EL_BDX_EXIT_CLOSED, -1, -1
},
{
- Ynut_w, FALSE, FALSE,
- EL_NUT, ACTION_MOVING, MV_BIT_LEFT
+ O_OUTBOX, TRUE,
+ EL_BDX_EXIT_OPEN, -1, -1
},
{
- Ynut_wB, FALSE, TRUE,
- EL_NUT, ACTION_MOVING, MV_BIT_LEFT
+ O_PRE_INVIS_OUTBOX, TRUE,
+ EL_BDX_INVISIBLE_EXIT_CLOSED, -1, -1
},
{
- Xbug_n, TRUE, FALSE,
- EL_BUG_UP, -1, -1
+ O_INVIS_OUTBOX, TRUE,
+ EL_BDX_INVISIBLE_EXIT_OPEN, -1, -1
},
{
- Xbug_e, TRUE, FALSE,
- EL_BUG_RIGHT, -1, -1
+ O_STEEL, TRUE,
+ EL_BDX_STEELWALL, -1, -1
},
{
- Xbug_s, TRUE, FALSE,
- EL_BUG_DOWN, -1, -1
+ O_STEEL_SLOPED_UP_RIGHT, TRUE,
+ EL_BDX_STEELWALL_SLOPED_UP_RIGHT, -1, -1
},
{
- Xbug_w, TRUE, FALSE,
- EL_BUG_LEFT, -1, -1
+ O_STEEL_SLOPED_UP_LEFT, TRUE,
+ EL_BDX_STEELWALL_SLOPED_UP_LEFT, -1, -1
},
{
- Xbug_gon, FALSE, FALSE,
- EL_BUG_UP, -1, -1
+ O_STEEL_SLOPED_DOWN_LEFT, TRUE,
+ EL_BDX_STEELWALL_SLOPED_DOWN_LEFT, -1, -1
},
{
- Xbug_goe, FALSE, FALSE,
- EL_BUG_RIGHT, -1, -1
+ O_STEEL_SLOPED_DOWN_RIGHT, TRUE,
+ EL_BDX_STEELWALL_SLOPED_DOWN_RIGHT, -1, -1
},
{
- Xbug_gos, FALSE, FALSE,
- EL_BUG_DOWN, -1, -1
+ O_STEEL_EXPLODABLE, TRUE,
+ EL_BDX_STEELWALL_EXPLODABLE, -1, -1
},
{
- Xbug_gow, FALSE, FALSE,
- EL_BUG_LEFT, -1, -1
+ O_STEEL_EATABLE, TRUE,
+ EL_BDX_STEELWALL_DIGGABLE, -1, -1
},
{
- Ybug_n, FALSE, FALSE,
- EL_BUG, ACTION_MOVING, MV_BIT_UP
+ O_BRICK_EATABLE, TRUE,
+ EL_BDX_WALL_DIGGABLE, -1, -1
},
{
- Ybug_nB, FALSE, TRUE,
- EL_BUG, ACTION_MOVING, MV_BIT_UP
+ O_STONE, TRUE,
+ EL_BDX_ROCK, -1, -1
},
{
- Ybug_e, FALSE, FALSE,
- EL_BUG, ACTION_MOVING, MV_BIT_RIGHT
+ O_STONE_F, TRUE,
+ EL_BDX_ROCK_FALLING, -1, -1
},
{
- Ybug_eB, FALSE, TRUE,
- EL_BUG, ACTION_MOVING, MV_BIT_RIGHT
+ O_STONE_F, FALSE,
+ EL_BDX_ROCK, ACTION_FALLING, -1
},
{
- Ybug_s, FALSE, FALSE,
- EL_BUG, ACTION_MOVING, MV_BIT_DOWN
+ O_FLYING_STONE, TRUE,
+ EL_BDX_FLYING_ROCK, -1, -1
},
{
- Ybug_sB, FALSE, TRUE,
- EL_BUG, ACTION_MOVING, MV_BIT_DOWN
+ O_FLYING_STONE_F, TRUE,
+ EL_BDX_FLYING_ROCK_FLYING, -1, -1
},
{
- Ybug_w, FALSE, FALSE,
- EL_BUG, ACTION_MOVING, MV_BIT_LEFT
+ O_FLYING_STONE_F, FALSE,
+ EL_BDX_FLYING_ROCK, ACTION_FLYING, -1
},
{
- Ybug_wB, FALSE, TRUE,
- EL_BUG, ACTION_MOVING, MV_BIT_LEFT
+ O_MEGA_STONE, TRUE,
+ EL_BDX_MEGA_ROCK, -1, -1
},
{
- Ybug_w_n, FALSE, FALSE,
- EL_BUG, ACTION_TURNING_FROM_LEFT, MV_BIT_UP
+ O_MEGA_STONE_F, TRUE,
+ EL_BDX_MEGA_ROCK_FALLING, -1, -1
},
{
- Ybug_n_e, FALSE, FALSE,
- EL_BUG, ACTION_TURNING_FROM_UP, MV_BIT_RIGHT
+ O_MEGA_STONE_F, FALSE,
+ EL_BDX_MEGA_ROCK, ACTION_FALLING, -1
},
{
- Ybug_e_s, FALSE, FALSE,
- EL_BUG, ACTION_TURNING_FROM_RIGHT, MV_BIT_DOWN
+ O_DIAMOND, TRUE,
+ EL_BDX_DIAMOND, -1, -1
},
{
- Ybug_s_w, FALSE, FALSE,
- EL_BUG, ACTION_TURNING_FROM_DOWN, MV_BIT_LEFT
+ O_DIAMOND_F, TRUE,
+ EL_BDX_DIAMOND_FALLING, -1, -1
},
{
- Ybug_e_n, FALSE, FALSE,
- EL_BUG, ACTION_TURNING_FROM_RIGHT, MV_BIT_UP
+ O_DIAMOND_F, FALSE,
+ EL_BDX_DIAMOND, ACTION_FALLING, -1
},
{
- Ybug_s_e, FALSE, FALSE,
- EL_BUG, ACTION_TURNING_FROM_DOWN, MV_BIT_RIGHT
+ O_FLYING_DIAMOND, TRUE,
+ EL_BDX_FLYING_DIAMOND, -1, -1
},
{
- Ybug_w_s, FALSE, FALSE,
- EL_BUG, ACTION_TURNING_FROM_LEFT, MV_BIT_DOWN
+ O_FLYING_DIAMOND_F, TRUE,
+ EL_BDX_FLYING_DIAMOND_FLYING, -1, -1
},
{
- Ybug_n_w, FALSE, FALSE,
- EL_BUG, ACTION_TURNING_FROM_UP, MV_BIT_LEFT
+ O_FLYING_DIAMOND_F, FALSE,
+ EL_BDX_FLYING_DIAMOND, ACTION_FLYING, -1
},
{
- Ybug_stone, FALSE, FALSE,
- EL_BUG, ACTION_SMASHED_BY_ROCK, -1
+ O_NUT, TRUE,
+ EL_BDX_NUT, -1, -1
},
{
- Ybug_spring, FALSE, FALSE,
- EL_BUG, ACTION_SMASHED_BY_SPRING, -1
+ O_NUT_F, TRUE,
+ EL_BDX_NUT_FALLING, -1, -1
},
{
- Xtank_n, TRUE, FALSE,
- EL_SPACESHIP_UP, -1, -1
+ O_NUT_F, FALSE,
+ EL_BDX_NUT, ACTION_FALLING, -1
},
{
- Xtank_e, TRUE, FALSE,
- EL_SPACESHIP_RIGHT, -1, -1
+ O_BLADDER_SPENDER, TRUE,
+ EL_BDX_BLADDER_SPENDER, -1, -1
},
{
- Xtank_s, TRUE, FALSE,
- EL_SPACESHIP_DOWN, -1, -1
+ O_INBOX, TRUE,
+ EL_BDX_INBOX, -1, -1
},
{
- Xtank_w, TRUE, FALSE,
- EL_SPACESHIP_LEFT, -1, -1
+ O_H_EXPANDING_WALL, TRUE,
+ EL_BDX_EXPANDABLE_WALL_HORIZONTAL, -1, -1
},
{
- Xtank_gon, FALSE, FALSE,
- EL_SPACESHIP_UP, -1, -1
+ O_V_EXPANDING_WALL, TRUE,
+ EL_BDX_EXPANDABLE_WALL_VERTICAL, -1, -1
},
{
- Xtank_goe, FALSE, FALSE,
- EL_SPACESHIP_RIGHT, -1, -1
+ O_EXPANDING_WALL, TRUE,
+ EL_BDX_EXPANDABLE_WALL_ANY, -1, -1
},
{
- Xtank_gos, FALSE, FALSE,
- EL_SPACESHIP_DOWN, -1, -1
+ O_H_EXPANDING_STEEL_WALL, TRUE,
+ EL_BDX_EXPANDABLE_STEELWALL_HORIZONTAL, -1, -1
},
{
- Xtank_gow, FALSE, FALSE,
- EL_SPACESHIP_LEFT, -1, -1
+ O_V_EXPANDING_STEEL_WALL, TRUE,
+ EL_BDX_EXPANDABLE_STEELWALL_VERTICAL, -1, -1
},
{
- Ytank_n, FALSE, FALSE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_UP
+ O_EXPANDING_STEEL_WALL, TRUE,
+ EL_BDX_EXPANDABLE_STEELWALL_ANY, -1, -1
},
{
- Ytank_nB, FALSE, TRUE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_UP
+ O_EXPANDING_WALL_SWITCH, TRUE,
+ EL_BDX_EXPANDABLE_WALL_SWITCH, -1, -1
},
{
- Ytank_e, FALSE, FALSE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_RIGHT
+ O_CREATURE_SWITCH, TRUE,
+ EL_BDX_CREATURE_SWITCH, -1, -1
},
{
- Ytank_eB, FALSE, TRUE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_RIGHT
+ O_BITER_SWITCH, TRUE,
+ EL_BDX_BITER_SWITCH_1, -1, -1
},
{
- Ytank_s, FALSE, FALSE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_DOWN
+ O_REPLICATOR_SWITCH, TRUE,
+ EL_BDX_REPLICATOR_SWITCH, -1, -1
},
{
- Ytank_sB, FALSE, TRUE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_DOWN
+ O_CONVEYOR_SWITCH, TRUE,
+ EL_BDX_CONVEYOR_SWITCH, -1, -1
},
{
- Ytank_w, FALSE, FALSE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_LEFT
+ O_CONVEYOR_DIR_SWITCH, TRUE,
+ EL_BDX_CONVEYOR_DIR_SWITCH, -1, -1
},
{
- Ytank_wB, FALSE, TRUE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_LEFT
+ O_ACID, TRUE,
+ EL_BDX_ACID, -1, -1
},
{
- Ytank_w_n, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_LEFT, MV_BIT_UP
+ O_FALLING_WALL, TRUE,
+ EL_BDX_FALLING_WALL, -1, -1
},
{
- Ytank_n_e, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_UP, MV_BIT_RIGHT
+ O_FALLING_WALL_F, TRUE,
+ EL_BDX_FALLING_WALL_FALLING, -1, -1
},
{
- Ytank_e_s, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_RIGHT, MV_BIT_DOWN
+ O_FALLING_WALL_F, FALSE,
+ EL_BDX_FALLING_WALL, ACTION_FALLING, -1
},
{
- Ytank_s_w, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_DOWN, MV_BIT_LEFT
+ O_BOX, TRUE,
+ EL_BDX_BOX, -1, -1
},
{
- Ytank_e_n, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_RIGHT, MV_BIT_UP
+ O_TIME_PENALTY, TRUE,
+ EL_BDX_TIME_PENALTY, -1, -1
},
{
- Ytank_s_e, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_DOWN, MV_BIT_RIGHT
+ O_GRAVESTONE, TRUE,
+ EL_BDX_GRAVESTONE, -1, -1
},
{
- Ytank_w_s, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_LEFT, MV_BIT_DOWN
+ O_STONE_GLUED, TRUE,
+ EL_BDX_ROCK_GLUED, -1, -1
},
{
- Ytank_n_w, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_UP, MV_BIT_LEFT
+ O_DIAMOND_GLUED, TRUE,
+ EL_BDX_DIAMOND_GLUED, -1, -1
},
{
- Ytank_stone, FALSE, FALSE,
- EL_SPACESHIP, ACTION_SMASHED_BY_ROCK, -1
+ O_DIAMOND_KEY, TRUE,
+ EL_BDX_DIAMOND_KEY, -1, -1
},
{
- Ytank_spring, FALSE, FALSE,
- EL_SPACESHIP, ACTION_SMASHED_BY_SPRING, -1
+ O_TRAPPED_DIAMOND, TRUE,
+ EL_BDX_TRAPPED_DIAMOND, -1, -1
},
{
- Xandroid, TRUE, FALSE,
- EL_EMC_ANDROID, ACTION_ACTIVE, -1
+ O_CLOCK, TRUE,
+ EL_BDX_CLOCK, -1, -1
},
{
- Xandroid_1_n, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_UP
+ O_DIRT_GLUED, TRUE,
+ EL_BDX_SAND_GLUED, -1, -1
},
{
- Xandroid_2_n, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_UP
+ O_KEY_1, TRUE,
+ EL_BDX_KEY_1, -1, -1
},
{
- Xandroid_1_e, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_RIGHT
+ O_KEY_2, TRUE,
+ EL_BDX_KEY_2, -1, -1
},
{
- Xandroid_2_e, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_RIGHT
+ O_KEY_3, TRUE,
+ EL_BDX_KEY_3, -1, -1
},
{
- Xandroid_1_w, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_LEFT
+ O_DOOR_1, TRUE,
+ EL_BDX_GATE_1, -1, -1
},
{
- Xandroid_2_w, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_LEFT
+ O_DOOR_2, TRUE,
+ EL_BDX_GATE_2, -1, -1
},
{
- Xandroid_1_s, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_DOWN
+ O_DOOR_3, TRUE,
+ EL_BDX_GATE_3, -1, -1
},
{
- Xandroid_2_s, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_DOWN
+ O_POT, TRUE,
+ EL_BDX_POT, -1, -1
},
{
- Yandroid_n, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_UP
+ O_GRAVITY_SWITCH, TRUE,
+ EL_BDX_GRAVITY_SWITCH, -1, -1
},
{
- Yandroid_nB, FALSE, TRUE,
- EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_UP
+ O_PNEUMATIC_HAMMER, TRUE,
+ EL_BDX_PNEUMATIC_HAMMER, -1, -1
},
{
- Yandroid_ne, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_GROWING, MV_BIT_UPRIGHT
+ O_TELEPORTER, TRUE,
+ EL_BDX_TELEPORTER, -1, -1
},
{
- Yandroid_neB, FALSE, TRUE,
- EL_EMC_ANDROID, ACTION_SHRINKING, MV_BIT_UPRIGHT
+ O_SKELETON, TRUE,
+ EL_BDX_SKELETON, -1, -1
},
{
- Yandroid_e, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_RIGHT
+ O_WATER, TRUE,
+ EL_BDX_WATER, -1, -1
},
{
- Yandroid_eB, FALSE, TRUE,
- EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_RIGHT
+ O_WATER_1, TRUE,
+ EL_BDX_WATER_1, -1, -1
},
{
- Yandroid_se, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_GROWING, MV_BIT_DOWNRIGHT
+ O_WATER_1, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Yandroid_seB, FALSE, TRUE,
- EL_EMC_ANDROID, ACTION_SHRINKING, MV_BIT_DOWNRIGHT
+ O_WATER_2, TRUE,
+ EL_BDX_WATER_2, -1, -1
},
{
- Yandroid_s, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_DOWN
+ O_WATER_2, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Yandroid_sB, FALSE, TRUE,
- EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_DOWN
+ O_WATER_3, TRUE,
+ EL_BDX_WATER_3, -1, -1
},
{
- Yandroid_sw, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_GROWING, MV_BIT_DOWNLEFT
+ O_WATER_3, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Yandroid_swB, FALSE, TRUE,
- EL_EMC_ANDROID, ACTION_SHRINKING, MV_BIT_DOWNLEFT
+ O_WATER_4, TRUE,
+ EL_BDX_WATER_4, -1, -1
},
{
- Yandroid_w, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_LEFT
+ O_WATER_4, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Yandroid_wB, FALSE, TRUE,
- EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_LEFT
+ O_WATER_5, TRUE,
+ EL_BDX_WATER_5, -1, -1
},
{
- Yandroid_nw, FALSE, FALSE,
- EL_EMC_ANDROID, ACTION_GROWING, MV_BIT_UPLEFT
+ O_WATER_5, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Yandroid_nwB, FALSE, TRUE,
- EL_EMC_ANDROID, ACTION_SHRINKING, MV_BIT_UPLEFT
+ O_WATER_6, TRUE,
+ EL_BDX_WATER_6, -1, -1
},
{
- Xspring, TRUE, FALSE,
- EL_SPRING, -1, -1
+ O_WATER_6, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Xspring_pause, FALSE, FALSE,
- EL_SPRING, -1, -1
+ O_WATER_7, TRUE,
+ EL_BDX_WATER_7, -1, -1
},
{
- Xspring_e, FALSE, FALSE,
- EL_SPRING, -1, -1
+ O_WATER_7, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Xspring_w, FALSE, FALSE,
- EL_SPRING, -1, -1
+ O_WATER_8, TRUE,
+ EL_BDX_WATER_8, -1, -1
},
{
- Xspring_fall, FALSE, FALSE,
- EL_SPRING, -1, -1
+ O_WATER_8, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Yspring_s, FALSE, FALSE,
- EL_SPRING, ACTION_FALLING, -1
+ O_WATER_9, TRUE,
+ EL_BDX_WATER_9, -1, -1
},
{
- Yspring_sB, FALSE, TRUE,
- EL_SPRING, ACTION_FALLING, -1
+ O_WATER_9, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Yspring_e, FALSE, FALSE,
- EL_SPRING, ACTION_MOVING, MV_BIT_RIGHT
+ O_WATER_10, TRUE,
+ EL_BDX_WATER_10, -1, -1
},
{
- Yspring_eB, FALSE, TRUE,
- EL_SPRING, ACTION_MOVING, MV_BIT_RIGHT
+ O_WATER_10, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Yspring_w, FALSE, FALSE,
- EL_SPRING, ACTION_MOVING, MV_BIT_LEFT
+ O_WATER_11, TRUE,
+ EL_BDX_WATER_11, -1, -1
},
{
- Yspring_wB, FALSE, TRUE,
- EL_SPRING, ACTION_MOVING, MV_BIT_LEFT
+ O_WATER_11, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Yspring_kill_e, FALSE, FALSE,
- EL_SPRING, ACTION_EATING, MV_BIT_RIGHT
+ O_WATER_12, TRUE,
+ EL_BDX_WATER_12, -1, -1
},
{
- Yspring_kill_eB, FALSE, TRUE,
- EL_SPRING, ACTION_EATING, MV_BIT_RIGHT
+ O_WATER_12, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Yspring_kill_w, FALSE, FALSE,
- EL_SPRING, ACTION_EATING, MV_BIT_LEFT
+ O_WATER_13, TRUE,
+ EL_BDX_WATER_13, -1, -1
},
{
- Yspring_kill_wB, FALSE, TRUE,
- EL_SPRING, ACTION_EATING, MV_BIT_LEFT
+ O_WATER_13, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Xeater_n, TRUE, FALSE,
- EL_YAMYAM_UP, -1, -1
+ O_WATER_14, TRUE,
+ EL_BDX_WATER_14, -1, -1
},
{
- Xeater_e, TRUE, FALSE,
- EL_YAMYAM_RIGHT, -1, -1
+ O_WATER_14, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Xeater_w, TRUE, FALSE,
- EL_YAMYAM_LEFT, -1, -1
+ O_WATER_15, TRUE,
+ EL_BDX_WATER_15, -1, -1
},
{
- Xeater_s, TRUE, FALSE,
- EL_YAMYAM_DOWN, -1, -1
+ O_WATER_15, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Yeater_n, FALSE, FALSE,
- EL_YAMYAM, ACTION_MOVING, MV_BIT_UP
+ O_WATER_16, TRUE,
+ EL_BDX_WATER_16, -1, -1
},
{
- Yeater_nB, FALSE, TRUE,
- EL_YAMYAM, ACTION_MOVING, MV_BIT_UP
+ O_WATER_16, FALSE,
+ EL_BDX_WATER, -1, -1
},
{
- Yeater_e, FALSE, FALSE,
- EL_YAMYAM, ACTION_MOVING, MV_BIT_RIGHT
+ O_COW_1, TRUE,
+ EL_BDX_COW_LEFT, -1, -1
},
{
- Yeater_eB, FALSE, TRUE,
- EL_YAMYAM, ACTION_MOVING, MV_BIT_RIGHT
+ O_COW_2, TRUE,
+ EL_BDX_COW_UP, -1, -1
},
{
- Yeater_s, FALSE, FALSE,
- EL_YAMYAM, ACTION_MOVING, MV_BIT_DOWN
+ O_COW_3, TRUE,
+ EL_BDX_COW_RIGHT, -1, -1
},
{
- Yeater_sB, FALSE, TRUE,
- EL_YAMYAM, ACTION_MOVING, MV_BIT_DOWN
+ O_COW_4, TRUE,
+ EL_BDX_COW_DOWN, -1, -1
},
{
- Yeater_w, FALSE, FALSE,
- EL_YAMYAM, ACTION_MOVING, MV_BIT_LEFT
+ O_COW_ENCLOSED_1, TRUE,
+ EL_BDX_COW_ENCLOSED_1, -1, -1
},
{
- Yeater_wB, FALSE, TRUE,
- EL_YAMYAM, ACTION_MOVING, MV_BIT_LEFT
+ O_COW_ENCLOSED_1, FALSE,
+ EL_BDX_COW_DOWN, -1, -1
},
{
- Yeater_stone, FALSE, FALSE,
- EL_YAMYAM, ACTION_SMASHED_BY_ROCK, -1
+ O_COW_ENCLOSED_2, TRUE,
+ EL_BDX_COW_ENCLOSED_2, -1, -1
},
{
- Yeater_spring, FALSE, FALSE,
- EL_YAMYAM, ACTION_SMASHED_BY_SPRING, -1
+ O_COW_ENCLOSED_2, FALSE,
+ EL_BDX_COW_DOWN, -1, -1
},
{
- Xalien, TRUE, FALSE,
- EL_ROBOT, -1, -1
+ O_COW_ENCLOSED_3, TRUE,
+ EL_BDX_COW_ENCLOSED_3, -1, -1
},
{
- Xalien_pause, FALSE, FALSE,
- EL_ROBOT, -1, -1
+ O_COW_ENCLOSED_3, FALSE,
+ EL_BDX_COW_DOWN, -1, -1
},
{
- Yalien_n, FALSE, FALSE,
- EL_ROBOT, ACTION_MOVING, MV_BIT_UP
+ O_COW_ENCLOSED_4, TRUE,
+ EL_BDX_COW_ENCLOSED_4, -1, -1
},
{
- Yalien_nB, FALSE, TRUE,
- EL_ROBOT, ACTION_MOVING, MV_BIT_UP
+ O_COW_ENCLOSED_4, FALSE,
+ EL_BDX_COW_DOWN, -1, -1
},
{
- Yalien_e, FALSE, FALSE,
- EL_ROBOT, ACTION_MOVING, MV_BIT_RIGHT
+ O_COW_ENCLOSED_5, TRUE,
+ EL_BDX_COW_ENCLOSED_5, -1, -1
},
{
- Yalien_eB, FALSE, TRUE,
- EL_ROBOT, ACTION_MOVING, MV_BIT_RIGHT
+ O_COW_ENCLOSED_5, FALSE,
+ EL_BDX_COW_DOWN, -1, -1
},
{
- Yalien_s, FALSE, FALSE,
- EL_ROBOT, ACTION_MOVING, MV_BIT_DOWN
+ O_COW_ENCLOSED_6, TRUE,
+ EL_BDX_COW_ENCLOSED_6, -1, -1
},
{
- Yalien_sB, FALSE, TRUE,
- EL_ROBOT, ACTION_MOVING, MV_BIT_DOWN
+ O_COW_ENCLOSED_6, FALSE,
+ EL_BDX_COW_DOWN, -1, -1
},
{
- Yalien_w, FALSE, FALSE,
- EL_ROBOT, ACTION_MOVING, MV_BIT_LEFT
+ O_COW_ENCLOSED_7, TRUE,
+ EL_BDX_COW_ENCLOSED_7, -1, -1
},
{
- Yalien_wB, FALSE, TRUE,
- EL_ROBOT, ACTION_MOVING, MV_BIT_LEFT
+ O_COW_ENCLOSED_7, FALSE,
+ EL_BDX_COW_DOWN, -1, -1
},
{
- Yalien_stone, FALSE, FALSE,
- EL_ROBOT, ACTION_SMASHED_BY_ROCK, -1
+ O_WALLED_DIAMOND, TRUE,
+ EL_BDX_WALL_DIAMOND, -1, -1
},
{
- Yalien_spring, FALSE, FALSE,
- EL_ROBOT, ACTION_SMASHED_BY_SPRING, -1
+ O_WALLED_KEY_1, TRUE,
+ EL_BDX_WALL_KEY_1, -1, -1
},
{
- Xemerald, TRUE, FALSE,
- EL_EMERALD, -1, -1
+ O_WALLED_KEY_2, TRUE,
+ EL_BDX_WALL_KEY_2, -1, -1
},
{
- Xemerald_pause, FALSE, FALSE,
- EL_EMERALD, -1, -1
+ O_WALLED_KEY_3, TRUE,
+ EL_BDX_WALL_KEY_3, -1, -1
},
{
- Xemerald_fall, FALSE, FALSE,
- EL_EMERALD, -1, -1
+ O_AMOEBA, TRUE,
+ EL_BDX_AMOEBA_1, -1, -1
},
{
- Xemerald_shine, FALSE, FALSE,
- EL_EMERALD, ACTION_TWINKLING, -1
+ O_AMOEBA_2, TRUE,
+ EL_BDX_AMOEBA_2, -1, -1
},
{
- Yemerald_s, FALSE, FALSE,
- EL_EMERALD, ACTION_FALLING, -1
+ O_REPLICATOR, TRUE,
+ EL_BDX_REPLICATOR, -1, -1
},
{
- Yemerald_sB, FALSE, TRUE,
- EL_EMERALD, ACTION_FALLING, -1
+ O_CONVEYOR_LEFT, TRUE,
+ EL_BDX_CONVEYOR_LEFT, -1, -1
},
{
- Yemerald_e, FALSE, FALSE,
- EL_EMERALD, ACTION_MOVING, MV_BIT_RIGHT
+ O_CONVEYOR_RIGHT, TRUE,
+ EL_BDX_CONVEYOR_RIGHT, -1, -1
},
{
- Yemerald_eB, FALSE, TRUE,
- EL_EMERALD, ACTION_MOVING, MV_BIT_RIGHT
+ O_LAVA, TRUE,
+ EL_BDX_LAVA, -1, -1
},
{
- Yemerald_w, FALSE, FALSE,
- EL_EMERALD, ACTION_MOVING, MV_BIT_LEFT
+ O_SWEET, TRUE,
+ EL_BDX_SWEET, -1, -1
},
{
- Yemerald_wB, FALSE, TRUE,
- EL_EMERALD, ACTION_MOVING, MV_BIT_LEFT
+ O_VOODOO, TRUE,
+ EL_BDX_VOODOO_DOLL, -1, -1
},
{
- Yemerald_eat, FALSE, FALSE,
- EL_EMERALD, ACTION_COLLECTING, -1
+ O_SLIME, TRUE,
+ EL_BDX_SLIME, -1, -1
},
{
- Yemerald_stone, FALSE, FALSE,
- EL_NUT, ACTION_BREAKING, -1
+ O_BLADDER, TRUE,
+ EL_BDX_BLADDER, -1, -1
},
{
- Xdiamond, TRUE, FALSE,
- EL_DIAMOND, -1, -1
+ O_BLADDER_1, TRUE,
+ EL_BDX_BLADDER_1, -1, -1
},
{
- Xdiamond_pause, FALSE, FALSE,
- EL_DIAMOND, -1, -1
+ O_BLADDER_1, FALSE,
+ EL_BDX_BLADDER, -1, -1
},
{
- Xdiamond_fall, FALSE, FALSE,
- EL_DIAMOND, -1, -1
+ O_BLADDER_2, TRUE,
+ EL_BDX_BLADDER_2, -1, -1
},
{
- Xdiamond_shine, FALSE, FALSE,
- EL_DIAMOND, ACTION_TWINKLING, -1
+ O_BLADDER_2, FALSE,
+ EL_BDX_BLADDER, -1, -1
},
{
- Ydiamond_s, FALSE, FALSE,
- EL_DIAMOND, ACTION_FALLING, -1
+ O_BLADDER_3, TRUE,
+ EL_BDX_BLADDER_3, -1, -1
},
{
- Ydiamond_sB, FALSE, TRUE,
- EL_DIAMOND, ACTION_FALLING, -1
+ O_BLADDER_3, FALSE,
+ EL_BDX_BLADDER, -1, -1
},
{
- Ydiamond_e, FALSE, FALSE,
- EL_DIAMOND, ACTION_MOVING, MV_BIT_RIGHT
+ O_BLADDER_4, TRUE,
+ EL_BDX_BLADDER_4, -1, -1
},
{
- Ydiamond_eB, FALSE, TRUE,
- EL_DIAMOND, ACTION_MOVING, MV_BIT_RIGHT
+ O_BLADDER_4, FALSE,
+ EL_BDX_BLADDER, -1, -1
},
{
- Ydiamond_w, FALSE, FALSE,
- EL_DIAMOND, ACTION_MOVING, MV_BIT_LEFT
+ O_BLADDER_5, TRUE,
+ EL_BDX_BLADDER_5, -1, -1
},
{
- Ydiamond_wB, FALSE, TRUE,
- EL_DIAMOND, ACTION_MOVING, MV_BIT_LEFT
+ O_BLADDER_5, FALSE,
+ EL_BDX_BLADDER, -1, -1
},
{
- Ydiamond_eat, FALSE, FALSE,
- EL_DIAMOND, ACTION_COLLECTING, -1
+ O_BLADDER_6, TRUE,
+ EL_BDX_BLADDER_6, -1, -1
},
{
- Ydiamond_stone, FALSE, FALSE,
- EL_DIAMOND, ACTION_SMASHED_BY_ROCK, -1
+ O_BLADDER_6, FALSE,
+ EL_BDX_BLADDER, -1, -1
},
{
- Xdrip_fall, TRUE, FALSE,
- EL_AMOEBA_DROP, -1, -1
+ O_BLADDER_7, TRUE,
+ EL_BDX_BLADDER_7, -1, -1
},
{
- Xdrip_stretch, FALSE, FALSE,
- EL_AMOEBA_DROP, ACTION_FALLING, -1
+ O_BLADDER_7, FALSE,
+ EL_BDX_BLADDER, -1, -1
},
{
- Xdrip_stretchB, FALSE, TRUE,
- EL_AMOEBA_DROP, ACTION_FALLING, -1
+ O_BLADDER_8, TRUE,
+ EL_BDX_BLADDER_8, -1, -1
},
{
- Xdrip_eat, FALSE, FALSE,
- EL_AMOEBA_DROP, ACTION_GROWING, -1
+ O_BLADDER_8, FALSE,
+ EL_BDX_BLADDER, -1, -1
},
{
- Ydrip_s1, FALSE, FALSE,
- EL_AMOEBA_DROP, ACTION_FALLING, -1
+ O_WAITING_STONE, TRUE,
+ EL_BDX_WAITING_ROCK, -1, -1
},
{
- Ydrip_s1B, FALSE, TRUE,
- EL_AMOEBA_DROP, ACTION_FALLING, -1
+ O_CHASING_STONE, TRUE,
+ EL_BDX_CHASING_ROCK, -1, -1
},
{
- Ydrip_s2, FALSE, FALSE,
- EL_AMOEBA_DROP, ACTION_FALLING, -1
+ O_GHOST, TRUE,
+ EL_BDX_GHOST, -1, -1
},
{
- Ydrip_s2B, FALSE, TRUE,
- EL_AMOEBA_DROP, ACTION_FALLING, -1
+ O_FIREFLY_1, TRUE,
+ EL_BDX_FIREFLY_1_LEFT, -1, -1
},
{
- Xbomb, TRUE, FALSE,
- EL_BOMB, -1, -1
+ O_FIREFLY_2, TRUE,
+ EL_BDX_FIREFLY_1_UP, -1, -1
},
{
- Xbomb_pause, FALSE, FALSE,
- EL_BOMB, -1, -1
+ O_FIREFLY_3, TRUE,
+ EL_BDX_FIREFLY_1_RIGHT, -1, -1
},
{
- Xbomb_fall, FALSE, FALSE,
- EL_BOMB, -1, -1
+ O_FIREFLY_4, TRUE,
+ EL_BDX_FIREFLY_1_DOWN, -1, -1
},
{
- Ybomb_s, FALSE, FALSE,
- EL_BOMB, ACTION_FALLING, -1
+ O_ALT_FIREFLY_1, TRUE,
+ EL_BDX_FIREFLY_2_LEFT, -1, -1
},
{
- Ybomb_sB, FALSE, TRUE,
- EL_BOMB, ACTION_FALLING, -1
+ O_ALT_FIREFLY_2, TRUE,
+ EL_BDX_FIREFLY_2_UP, -1, -1
},
{
- Ybomb_e, FALSE, FALSE,
- EL_BOMB, ACTION_MOVING, MV_BIT_RIGHT
+ O_ALT_FIREFLY_3, TRUE,
+ EL_BDX_FIREFLY_2_RIGHT, -1, -1
},
{
- Ybomb_eB, FALSE, TRUE,
- EL_BOMB, ACTION_MOVING, MV_BIT_RIGHT
+ O_ALT_FIREFLY_4, TRUE,
+ EL_BDX_FIREFLY_2_DOWN, -1, -1
},
{
- Ybomb_w, FALSE, FALSE,
- EL_BOMB, ACTION_MOVING, MV_BIT_LEFT
+ O_BUTTER_1, TRUE,
+ EL_BDX_BUTTERFLY_1_LEFT, -1, -1
},
{
- Ybomb_wB, FALSE, TRUE,
- EL_BOMB, ACTION_MOVING, MV_BIT_LEFT
+ O_BUTTER_2, TRUE,
+ EL_BDX_BUTTERFLY_1_UP, -1, -1
},
{
- Ybomb_eat, FALSE, FALSE,
- EL_BOMB, ACTION_ACTIVATING, -1
+ O_BUTTER_3, TRUE,
+ EL_BDX_BUTTERFLY_1_RIGHT, -1, -1
},
{
- Xballoon, TRUE, FALSE,
- EL_BALLOON, -1, -1
+ O_BUTTER_4, TRUE,
+ EL_BDX_BUTTERFLY_1_DOWN, -1, -1
},
{
- Yballoon_n, FALSE, FALSE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_UP
+ O_ALT_BUTTER_1, TRUE,
+ EL_BDX_BUTTERFLY_2_LEFT, -1, -1
},
{
- Yballoon_nB, FALSE, TRUE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_UP
+ O_ALT_BUTTER_2, TRUE,
+ EL_BDX_BUTTERFLY_2_UP, -1, -1
},
{
- Yballoon_e, FALSE, FALSE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_RIGHT
+ O_ALT_BUTTER_3, TRUE,
+ EL_BDX_BUTTERFLY_2_RIGHT, -1, -1
},
{
- Yballoon_eB, FALSE, TRUE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_RIGHT
+ O_ALT_BUTTER_4, TRUE,
+ EL_BDX_BUTTERFLY_2_DOWN, -1, -1
},
{
- Yballoon_s, FALSE, FALSE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_DOWN
+ O_STONEFLY_1, TRUE,
+ EL_BDX_STONEFLY_LEFT, -1, -1
},
{
- Yballoon_sB, FALSE, TRUE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_DOWN
+ O_STONEFLY_2, TRUE,
+ EL_BDX_STONEFLY_UP, -1, -1
},
{
- Yballoon_w, FALSE, FALSE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_LEFT
+ O_STONEFLY_3, TRUE,
+ EL_BDX_STONEFLY_RIGHT, -1, -1
},
{
- Yballoon_wB, FALSE, TRUE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_LEFT
+ O_STONEFLY_4, TRUE,
+ EL_BDX_STONEFLY_DOWN, -1, -1
},
{
- Xgrass, TRUE, FALSE,
- EL_EMC_GRASS, -1, -1
+ O_BITER_1, TRUE,
+ EL_BDX_BITER_UP, -1, -1
},
{
- Ygrass_nB, FALSE, FALSE,
- EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_UP
+ O_BITER_2, TRUE,
+ EL_BDX_BITER_RIGHT, -1, -1
},
{
- Ygrass_eB, FALSE, FALSE,
- EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_RIGHT
+ O_BITER_3, TRUE,
+ EL_BDX_BITER_DOWN, -1, -1
},
{
- Ygrass_sB, FALSE, FALSE,
- EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_DOWN
+ O_BITER_4, TRUE,
+ EL_BDX_BITER_LEFT, -1, -1
},
{
- Ygrass_wB, FALSE, FALSE,
- EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_LEFT
+ O_DRAGONFLY_1, TRUE,
+ EL_BDX_DRAGONFLY_LEFT, -1, -1
},
{
- Xdirt, TRUE, FALSE,
- EL_SAND, -1, -1
+ O_DRAGONFLY_2, TRUE,
+ EL_BDX_DRAGONFLY_UP, -1, -1
},
{
- Ydirt_nB, FALSE, FALSE,
- EL_SAND, ACTION_DIGGING, MV_BIT_UP
+ O_DRAGONFLY_3, TRUE,
+ EL_BDX_DRAGONFLY_RIGHT, -1, -1
},
{
- Ydirt_eB, FALSE, FALSE,
- EL_SAND, ACTION_DIGGING, MV_BIT_RIGHT
+ O_DRAGONFLY_4, TRUE,
+ EL_BDX_DRAGONFLY_DOWN, -1, -1
},
{
- Ydirt_sB, FALSE, FALSE,
- EL_SAND, ACTION_DIGGING, MV_BIT_DOWN
+ O_PRE_PL_1, TRUE,
+ EL_BDX_PLAYER_GROWING_1, -1, -1
},
{
- Ydirt_wB, FALSE, FALSE,
- EL_SAND, ACTION_DIGGING, MV_BIT_LEFT
+ O_PRE_PL_1, FALSE,
+ EL_BDX_PLAYER, ACTION_GROWING, -1
},
{
- Xacid_ne, TRUE, FALSE,
- EL_ACID_POOL_TOPRIGHT, -1, -1
+ O_PRE_PL_2, TRUE,
+ EL_BDX_PLAYER_GROWING_2, -1, -1
},
{
- Xacid_se, TRUE, FALSE,
- EL_ACID_POOL_BOTTOMRIGHT, -1, -1
+ O_PRE_PL_2, FALSE,
+ EL_BDX_PLAYER, ACTION_GROWING, -1
},
{
- Xacid_s, TRUE, FALSE,
- EL_ACID_POOL_BOTTOM, -1, -1
+ O_PRE_PL_3, TRUE,
+ EL_BDX_PLAYER_GROWING_3, -1, -1
},
{
- Xacid_sw, TRUE, FALSE,
- EL_ACID_POOL_BOTTOMLEFT, -1, -1
+ O_PRE_PL_3, FALSE,
+ EL_BDX_PLAYER, ACTION_GROWING, -1
},
{
- Xacid_nw, TRUE, FALSE,
- EL_ACID_POOL_TOPLEFT, -1, -1
+ O_PLAYER, TRUE,
+ EL_BDX_PLAYER, -1, -1
},
{
- Xacid_1, TRUE, FALSE,
- EL_ACID, -1, -1
+ O_PLAYER_BOMB, TRUE,
+ EL_BDX_PLAYER_WITH_BOMB, -1, -1
},
{
- Xacid_2, FALSE, FALSE,
- EL_ACID, -1, -1
+ O_PLAYER_ROCKET_LAUNCHER, TRUE,
+ EL_BDX_PLAYER_WITH_ROCKET_LAUNCHER, -1, -1
},
{
- Xacid_3, FALSE, FALSE,
- EL_ACID, -1, -1
+ O_PLAYER_GLUED, TRUE,
+ EL_BDX_PLAYER_GLUED, -1, -1
},
{
- Xacid_4, FALSE, FALSE,
- EL_ACID, -1, -1
+ O_PLAYER_STIRRING, TRUE,
+ EL_BDX_PLAYER_STIRRING, -1, -1
},
{
- Xacid_5, FALSE, FALSE,
- EL_ACID, -1, -1
+ O_ROCKET_LAUNCHER, TRUE,
+ EL_BDX_ROCKET_LAUNCHER, -1, -1
},
{
- Xacid_6, FALSE, FALSE,
- EL_ACID, -1, -1
+ O_ROCKET_1, TRUE,
+ EL_BDX_ROCKET_RIGHT, -1, -1
},
{
- Xacid_7, FALSE, FALSE,
- EL_ACID, -1, -1
+ O_ROCKET_2, TRUE,
+ EL_BDX_ROCKET_UP, -1, -1
},
{
- Xacid_8, FALSE, FALSE,
- EL_ACID, -1, -1
+ O_ROCKET_3, TRUE,
+ EL_BDX_ROCKET_LEFT, -1, -1
},
{
- Xball_1, TRUE, FALSE,
- EL_EMC_MAGIC_BALL, -1, -1
+ O_ROCKET_4, TRUE,
+ EL_BDX_ROCKET_DOWN, -1, -1
},
{
- Xball_1B, FALSE, FALSE,
- EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
+ O_BOMB, TRUE,
+ EL_BDX_BOMB, -1, -1
},
{
- Xball_2, FALSE, FALSE,
- EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
+ O_BOMB_TICK_1, TRUE,
+ EL_BDX_BOMB_TICKING_1, -1, -1
},
{
- Xball_2B, FALSE, FALSE,
- EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
+ O_BOMB_TICK_1, FALSE,
+ EL_BDX_BOMB, ACTION_ACTIVE, -1
},
{
- Yball_eat, FALSE, FALSE,
- EL_EMC_MAGIC_BALL, ACTION_DROPPING, -1
+ O_BOMB_TICK_2, TRUE,
+ EL_BDX_BOMB_TICKING_2, -1, -1
},
{
- Ykey_1_eat, FALSE, FALSE,
- EL_EM_KEY_1, ACTION_COLLECTING, -1
+ O_BOMB_TICK_2, FALSE,
+ EL_BDX_BOMB, ACTION_ACTIVE, -1
},
{
- Ykey_2_eat, FALSE, FALSE,
- EL_EM_KEY_2, ACTION_COLLECTING, -1
+ O_BOMB_TICK_3, TRUE,
+ EL_BDX_BOMB_TICKING_3, -1, -1
},
{
- Ykey_3_eat, FALSE, FALSE,
- EL_EM_KEY_3, ACTION_COLLECTING, -1
+ O_BOMB_TICK_3, FALSE,
+ EL_BDX_BOMB, ACTION_ACTIVE, -1
},
{
- Ykey_4_eat, FALSE, FALSE,
- EL_EM_KEY_4, ACTION_COLLECTING, -1
+ O_BOMB_TICK_4, TRUE,
+ EL_BDX_BOMB_TICKING_4, -1, -1
},
{
- Ykey_5_eat, FALSE, FALSE,
- EL_EMC_KEY_5, ACTION_COLLECTING, -1
+ O_BOMB_TICK_4, FALSE,
+ EL_BDX_BOMB, ACTION_ACTIVE, -1
},
{
- Ykey_6_eat, FALSE, FALSE,
- EL_EMC_KEY_6, ACTION_COLLECTING, -1
+ O_BOMB_TICK_5, TRUE,
+ EL_BDX_BOMB_TICKING_5, -1, -1
},
{
- Ykey_7_eat, FALSE, FALSE,
- EL_EMC_KEY_7, ACTION_COLLECTING, -1
+ O_BOMB_TICK_5, FALSE,
+ EL_BDX_BOMB, ACTION_ACTIVE, -1
},
{
- Ykey_8_eat, FALSE, FALSE,
- EL_EMC_KEY_8, ACTION_COLLECTING, -1
+ O_BOMB_TICK_6, TRUE,
+ EL_BDX_BOMB_TICKING_6, -1, -1
},
{
- Ylenses_eat, FALSE, FALSE,
- EL_EMC_LENSES, ACTION_COLLECTING, -1
+ O_BOMB_TICK_6, FALSE,
+ EL_BDX_BOMB, ACTION_ACTIVE, -1
},
{
- Ymagnify_eat, FALSE, FALSE,
- EL_EMC_MAGNIFIER, ACTION_COLLECTING, -1
+ O_BOMB_TICK_7, TRUE,
+ EL_BDX_BOMB_TICKING_7, -1, -1
},
{
- Ygrass_eat, FALSE, FALSE,
- EL_EMC_GRASS, ACTION_SNAPPING, -1
+ O_BOMB_TICK_7, FALSE,
+ EL_BDX_BOMB, ACTION_ACTIVE, -1
},
{
- Ydirt_eat, FALSE, FALSE,
- EL_SAND, ACTION_SNAPPING, -1
+ O_NITRO_PACK, TRUE,
+ EL_BDX_NITRO_PACK, -1, -1
},
{
- Xgrow_ns, TRUE, FALSE,
- EL_EXPANDABLE_WALL_VERTICAL, -1, -1
+ O_NITRO_PACK_F, TRUE,
+ EL_BDX_NITRO_PACK_FALLING, -1, -1
},
{
- Ygrow_ns_eat, FALSE, FALSE,
- EL_EXPANDABLE_WALL_VERTICAL, ACTION_GROWING, -1
+ O_NITRO_PACK_F, FALSE,
+ EL_BDX_NITRO_PACK, ACTION_FALLING, -1
},
{
- Xgrow_ew, TRUE, FALSE,
- EL_EXPANDABLE_WALL_HORIZONTAL, -1, -1
+ O_PRE_CLOCK_1, TRUE,
+ EL_BDX_CLOCK_GROWING_1, -1, -1
},
{
- Ygrow_ew_eat, FALSE, FALSE,
- EL_EXPANDABLE_WALL_HORIZONTAL, ACTION_GROWING, -1
+ O_PRE_CLOCK_1, FALSE,
+ EL_BDX_CLOCK, ACTION_GROWING, -1
},
{
- Xwonderwall, TRUE, FALSE,
- EL_MAGIC_WALL, -1, -1
+ O_PRE_CLOCK_2, TRUE,
+ EL_BDX_CLOCK_GROWING_2, -1, -1
},
{
- XwonderwallB, FALSE, FALSE,
- EL_MAGIC_WALL, ACTION_ACTIVE, -1
+ O_PRE_CLOCK_2, FALSE,
+ EL_BDX_CLOCK, ACTION_GROWING, -1
},
{
- Xamoeba_1, TRUE, FALSE,
- EL_AMOEBA_DRY, ACTION_OTHER, -1
+ O_PRE_CLOCK_3, TRUE,
+ EL_BDX_CLOCK_GROWING_3, -1, -1
},
{
- Xamoeba_2, FALSE, FALSE,
- EL_AMOEBA_DRY, ACTION_OTHER, -1
+ O_PRE_CLOCK_3, FALSE,
+ EL_BDX_CLOCK, ACTION_GROWING, -1
},
{
- Xamoeba_3, FALSE, FALSE,
- EL_AMOEBA_DRY, ACTION_OTHER, -1
+ O_PRE_CLOCK_4, TRUE,
+ EL_BDX_CLOCK_GROWING_4, -1, -1
},
{
- Xamoeba_4, FALSE, FALSE,
- EL_AMOEBA_DRY, ACTION_OTHER, -1
+ O_PRE_CLOCK_4, FALSE,
+ EL_BDX_CLOCK, ACTION_GROWING, -1
},
{
- Xamoeba_5, TRUE, FALSE,
- EL_AMOEBA_WET, ACTION_OTHER, -1
+ O_PRE_DIA_1, TRUE,
+ EL_BDX_DIAMOND_GROWING_1, -1, -1
},
{
- Xamoeba_6, FALSE, FALSE,
- EL_AMOEBA_WET, ACTION_OTHER, -1
+ O_PRE_DIA_1, FALSE,
+ EL_BDX_DIAMOND, ACTION_GROWING, -1
},
{
- Xamoeba_7, FALSE, FALSE,
- EL_AMOEBA_WET, ACTION_OTHER, -1
+ O_PRE_DIA_2, TRUE,
+ EL_BDX_DIAMOND_GROWING_2, -1, -1
},
{
- Xamoeba_8, FALSE, FALSE,
- EL_AMOEBA_WET, ACTION_OTHER, -1
+ O_PRE_DIA_2, FALSE,
+ EL_BDX_DIAMOND, ACTION_GROWING, -1
},
{
- Xdoor_1, TRUE, FALSE,
- EL_EM_GATE_1, -1, -1
+ O_PRE_DIA_3, TRUE,
+ EL_BDX_DIAMOND_GROWING_3, -1, -1
},
{
- Xdoor_2, TRUE, FALSE,
- EL_EM_GATE_2, -1, -1
+ O_PRE_DIA_3, FALSE,
+ EL_BDX_DIAMOND, ACTION_GROWING, -1
},
{
- Xdoor_3, TRUE, FALSE,
- EL_EM_GATE_3, -1, -1
+ O_PRE_DIA_4, TRUE,
+ EL_BDX_DIAMOND_GROWING_4, -1, -1
},
{
- Xdoor_4, TRUE, FALSE,
- EL_EM_GATE_4, -1, -1
+ O_PRE_DIA_4, FALSE,
+ EL_BDX_DIAMOND, ACTION_GROWING, -1
},
{
- Xdoor_5, TRUE, FALSE,
- EL_EMC_GATE_5, -1, -1
+ O_PRE_DIA_5, TRUE,
+ EL_BDX_DIAMOND_GROWING_5, -1, -1
},
{
- Xdoor_6, TRUE, FALSE,
- EL_EMC_GATE_6, -1, -1
+ O_PRE_DIA_5, FALSE,
+ EL_BDX_DIAMOND, ACTION_GROWING, -1
},
{
- Xdoor_7, TRUE, FALSE,
- EL_EMC_GATE_7, -1, -1
+ O_EXPLODE_1, TRUE,
+ EL_BDX_EXPLODING_1, -1, -1
},
{
- Xdoor_8, TRUE, FALSE,
- EL_EMC_GATE_8, -1, -1
+ O_EXPLODE_1, FALSE,
+ EL_DEFAULT, ACTION_EXPLODING, -1
},
{
- Xkey_1, TRUE, FALSE,
- EL_EM_KEY_1, -1, -1
+ O_EXPLODE_2, TRUE,
+ EL_BDX_EXPLODING_2, -1, -1
},
{
- Xkey_2, TRUE, FALSE,
- EL_EM_KEY_2, -1, -1
+ O_EXPLODE_2, FALSE,
+ EL_DEFAULT, ACTION_EXPLODING, -1
},
{
- Xkey_3, TRUE, FALSE,
- EL_EM_KEY_3, -1, -1
+ O_EXPLODE_3, TRUE,
+ EL_BDX_EXPLODING_3, -1, -1
},
{
- Xkey_4, TRUE, FALSE,
- EL_EM_KEY_4, -1, -1
+ O_EXPLODE_3, FALSE,
+ EL_DEFAULT, ACTION_EXPLODING, -1
},
{
- Xkey_5, TRUE, FALSE,
- EL_EMC_KEY_5, -1, -1
+ O_EXPLODE_4, TRUE,
+ EL_BDX_EXPLODING_4, -1, -1
},
{
- Xkey_6, TRUE, FALSE,
- EL_EMC_KEY_6, -1, -1
+ O_EXPLODE_4, FALSE,
+ EL_DEFAULT, ACTION_EXPLODING, -1
},
{
- Xkey_7, TRUE, FALSE,
- EL_EMC_KEY_7, -1, -1
+ O_EXPLODE_5, TRUE,
+ EL_BDX_EXPLODING_5, -1, -1
},
{
- Xkey_8, TRUE, FALSE,
- EL_EMC_KEY_8, -1, -1
+ O_EXPLODE_5, FALSE,
+ EL_DEFAULT, ACTION_EXPLODING, -1
},
{
- Xwind_n, TRUE, FALSE,
- EL_BALLOON_SWITCH_UP, -1, -1
+ O_PRE_STONE_1, TRUE,
+ EL_BDX_ROCK_GROWING_1, -1, -1
},
{
- Xwind_e, TRUE, FALSE,
- EL_BALLOON_SWITCH_RIGHT, -1, -1
+ O_PRE_STONE_1, FALSE,
+ EL_BDX_ROCK, ACTION_GROWING, -1
},
{
- Xwind_s, TRUE, FALSE,
- EL_BALLOON_SWITCH_DOWN, -1, -1
+ O_PRE_STONE_2, TRUE,
+ EL_BDX_ROCK_GROWING_2, -1, -1
},
{
- Xwind_w, TRUE, FALSE,
- EL_BALLOON_SWITCH_LEFT, -1, -1
+ O_PRE_STONE_2, FALSE,
+ EL_BDX_ROCK, ACTION_GROWING, -1
},
{
- Xwind_nesw, TRUE, FALSE,
- EL_BALLOON_SWITCH_ANY, -1, -1
+ O_PRE_STONE_3, TRUE,
+ EL_BDX_ROCK_GROWING_3, -1, -1
},
{
- Xwind_stop, TRUE, FALSE,
- EL_BALLOON_SWITCH_NONE, -1, -1
+ O_PRE_STONE_3, FALSE,
+ EL_BDX_ROCK, ACTION_GROWING, -1
},
{
- Xexit, TRUE, FALSE,
- EL_EM_EXIT_CLOSED, -1, -1
+ O_PRE_STONE_4, TRUE,
+ EL_BDX_ROCK_GROWING_4, -1, -1
},
{
- Xexit_1, TRUE, FALSE,
- EL_EM_EXIT_OPEN, -1, -1
+ O_PRE_STONE_4, FALSE,
+ EL_BDX_ROCK, ACTION_GROWING, -1
},
{
- Xexit_2, FALSE, FALSE,
- EL_EM_EXIT_OPEN, -1, -1
+ O_PRE_STEEL_1, TRUE,
+ EL_BDX_STEELWALL_GROWING_1, -1, -1
},
{
- Xexit_3, FALSE, FALSE,
- EL_EM_EXIT_OPEN, -1, -1
+ O_PRE_STEEL_1, FALSE,
+ EL_BDX_STEELWALL, ACTION_GROWING, -1
},
{
- Xdynamite, TRUE, FALSE,
- EL_EM_DYNAMITE, -1, -1
+ O_PRE_STEEL_2, TRUE,
+ EL_BDX_STEELWALL_GROWING_2, -1, -1
},
{
- Ydynamite_eat, FALSE, FALSE,
- EL_EM_DYNAMITE, ACTION_COLLECTING, -1
+ O_PRE_STEEL_2, FALSE,
+ EL_BDX_STEELWALL, ACTION_GROWING, -1
},
{
- Xdynamite_1, TRUE, FALSE,
- EL_EM_DYNAMITE_ACTIVE, -1, -1
+ O_PRE_STEEL_3, TRUE,
+ EL_BDX_STEELWALL_GROWING_3, -1, -1
},
{
- Xdynamite_2, FALSE, FALSE,
- EL_EM_DYNAMITE_ACTIVE, -1, -1
+ O_PRE_STEEL_3, FALSE,
+ EL_BDX_STEELWALL, ACTION_GROWING, -1
+ },
+ {
+ O_PRE_STEEL_4, TRUE,
+ EL_BDX_STEELWALL_GROWING_4, -1, -1
+ },
+ {
+ O_PRE_STEEL_4, FALSE,
+ EL_BDX_STEELWALL, ACTION_GROWING, -1
+ },
+ {
+ O_GHOST_EXPL_1, TRUE,
+ EL_BDX_GHOST_EXPLODING_1, -1, -1
+ },
+ {
+ O_GHOST_EXPL_1, FALSE,
+ EL_BDX_GHOST, ACTION_EXPLODING, -1
+ },
+ {
+ O_GHOST_EXPL_2, TRUE,
+ EL_BDX_GHOST_EXPLODING_2, -1, -1
+ },
+ {
+ O_GHOST_EXPL_2, FALSE,
+ EL_BDX_GHOST, ACTION_EXPLODING, -1
+ },
+ {
+ O_GHOST_EXPL_3, TRUE,
+ EL_BDX_GHOST_EXPLODING_3, -1, -1
+ },
+ {
+ O_GHOST_EXPL_3, FALSE,
+ EL_BDX_GHOST, ACTION_EXPLODING, -1
+ },
+ {
+ O_GHOST_EXPL_4, TRUE,
+ EL_BDX_GHOST_EXPLODING_4, -1, -1
+ },
+ {
+ O_GHOST_EXPL_4, FALSE,
+ EL_BDX_GHOST, ACTION_EXPLODING, -1
+ },
+ {
+ O_BOMB_EXPL_1, TRUE,
+ EL_BDX_BOMB_EXPLODING_1, -1, -1
+ },
+ {
+ O_BOMB_EXPL_1, FALSE,
+ EL_BDX_BOMB, ACTION_EXPLODING, -1
+ },
+ {
+ O_BOMB_EXPL_2, TRUE,
+ EL_BDX_BOMB_EXPLODING_2, -1, -1
+ },
+ {
+ O_BOMB_EXPL_2, FALSE,
+ EL_BDX_BOMB, ACTION_EXPLODING, -1
+ },
+ {
+ O_BOMB_EXPL_3, TRUE,
+ EL_BDX_BOMB_EXPLODING_3, -1, -1
+ },
+ {
+ O_BOMB_EXPL_3, FALSE,
+ EL_BDX_BOMB, ACTION_EXPLODING, -1
+ },
+ {
+ O_BOMB_EXPL_4, TRUE,
+ EL_BDX_BOMB_EXPLODING_4, -1, -1
+ },
+ {
+ O_BOMB_EXPL_4, FALSE,
+ EL_BDX_BOMB, ACTION_EXPLODING, -1
+ },
+ {
+ O_NITRO_EXPL_1, TRUE,
+ EL_BDX_NITRO_PACK_EXPLODING_1, -1, -1
+ },
+ {
+ O_NITRO_EXPL_1, FALSE,
+ EL_BDX_NITRO_PACK, ACTION_EXPLODING, -1
+ },
+ {
+ O_NITRO_EXPL_2, TRUE,
+ EL_BDX_NITRO_PACK_EXPLODING_2, -1, -1
+ },
+ {
+ O_NITRO_EXPL_2, FALSE,
+ EL_BDX_NITRO_PACK, ACTION_EXPLODING, -1
+ },
+ {
+ O_NITRO_EXPL_3, TRUE,
+ EL_BDX_NITRO_PACK_EXPLODING_3, -1, -1
+ },
+ {
+ O_NITRO_EXPL_3, FALSE,
+ EL_BDX_NITRO_PACK, ACTION_EXPLODING, -1
+ },
+ {
+ O_NITRO_EXPL_4, TRUE,
+ EL_BDX_NITRO_PACK_EXPLODING_4, -1, -1
+ },
+ {
+ O_NITRO_EXPL_4, FALSE,
+ EL_BDX_NITRO_PACK, ACTION_EXPLODING, -1
+ },
+ {
+ O_NITRO_PACK_EXPLODE, TRUE,
+ EL_BDX_NITRO_PACK_EXPLODING, -1, -1
+ },
+ {
+ O_NITRO_PACK_EXPLODE, FALSE,
+ EL_BDX_NITRO_PACK, ACTION_EXPLODING, -1
+ },
+ {
+ O_AMOEBA_2_EXPL_1, TRUE,
+ EL_BDX_AMOEBA_2_EXPLODING_1, -1, -1
+ },
+ {
+ O_AMOEBA_2_EXPL_1, FALSE,
+ EL_BDX_AMOEBA_2, ACTION_EXPLODING, -1
+ },
+ {
+ O_AMOEBA_2_EXPL_2, TRUE,
+ EL_BDX_AMOEBA_2_EXPLODING_2, -1, -1
+ },
+ {
+ O_AMOEBA_2_EXPL_2, FALSE,
+ EL_BDX_AMOEBA_2, ACTION_EXPLODING, -1
+ },
+ {
+ O_AMOEBA_2_EXPL_3, TRUE,
+ EL_BDX_AMOEBA_2_EXPLODING_3, -1, -1
+ },
+ {
+ O_AMOEBA_2_EXPL_3, FALSE,
+ EL_BDX_AMOEBA_2, ACTION_EXPLODING, -1
+ },
+ {
+ O_AMOEBA_2_EXPL_4, TRUE,
+ EL_BDX_AMOEBA_2_EXPLODING_4, -1, -1
+ },
+ {
+ O_AMOEBA_2_EXPL_4, FALSE,
+ EL_BDX_AMOEBA_2, ACTION_EXPLODING, -1
+ },
+ {
+ O_NUT_EXPL_1, TRUE,
+ EL_BDX_NUT_BREAKING_1, -1, -1
+ },
+ {
+ O_NUT_EXPL_1, FALSE,
+ EL_BDX_NUT, ACTION_BREAKING, -1
+ },
+ {
+ O_NUT_EXPL_2, TRUE,
+ EL_BDX_NUT_BREAKING_2, -1, -1
+ },
+ {
+ O_NUT_EXPL_2, FALSE,
+ EL_BDX_NUT, ACTION_BREAKING, -1
+ },
+ {
+ O_NUT_EXPL_3, TRUE,
+ EL_BDX_NUT_BREAKING_3, -1, -1
+ },
+ {
+ O_NUT_EXPL_3, FALSE,
+ EL_BDX_NUT, ACTION_BREAKING, -1
+ },
+ {
+ O_NUT_EXPL_4, TRUE,
+ EL_BDX_NUT_BREAKING_4, -1, -1
+ },
+ {
+ O_NUT_EXPL_4, FALSE,
+ EL_BDX_NUT, ACTION_BREAKING, -1
+ },
+ {
+ O_PLAYER_PNEUMATIC_LEFT, FALSE,
+ EL_BDX_PLAYER, ACTION_HITTING, MV_BIT_LEFT
+ },
+ {
+ O_PLAYER_PNEUMATIC_RIGHT, FALSE,
+ EL_BDX_PLAYER, ACTION_HITTING, MV_BIT_RIGHT
+ },
+ {
+ O_PNEUMATIC_ACTIVE_LEFT, FALSE,
+ EL_BDX_PNEUMATIC_HAMMER, ACTION_HITTING, MV_BIT_LEFT
+ },
+ {
+ O_PNEUMATIC_ACTIVE_RIGHT, FALSE,
+ EL_BDX_PNEUMATIC_HAMMER, ACTION_HITTING, MV_BIT_RIGHT
+ },
+
+ // helper (runtime) elements
+
+ {
+ O_FAKE_BONUS, FALSE,
+ EL_BDX_FAKE_BONUS, -1, -1
+ },
+ {
+ O_INBOX_CLOSED, FALSE,
+ EL_BDX_INBOX, -1, -1
+ },
+ {
+ O_INBOX_OPEN, FALSE,
+ EL_BDX_INBOX, ACTION_OPENING, -1
+ },
+ {
+ O_OUTBOX_CLOSED, FALSE,
+ EL_BDX_EXIT_CLOSED, -1, -1
+ },
+ {
+ O_OUTBOX_OPEN, FALSE,
+ EL_BDX_EXIT_OPEN, -1, -1
+ },
+ {
+ O_COVERED, FALSE,
+ EL_BDX_COVERED, -1, -1
+ },
+ {
+ O_PLAYER_LEFT, FALSE,
+ EL_BDX_PLAYER, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ O_PLAYER_RIGHT, FALSE,
+ EL_BDX_PLAYER, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ O_PLAYER_UP, FALSE,
+ EL_BDX_PLAYER, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ O_PLAYER_DOWN, FALSE,
+ EL_BDX_PLAYER, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ O_PLAYER_BLINK, FALSE,
+ EL_BDX_PLAYER, ACTION_BORING_1, -1
+ },
+ {
+ O_PLAYER_TAP, FALSE,
+ EL_BDX_PLAYER, ACTION_BORING_2, -1
+ },
+ {
+ O_PLAYER_TAP_BLINK, FALSE,
+ EL_BDX_PLAYER, ACTION_BORING_3, -1
+ },
+ {
+ O_PLAYER_PUSH_LEFT, FALSE,
+ EL_BDX_PLAYER, ACTION_PUSHING, MV_BIT_LEFT
+ },
+ {
+ O_PLAYER_PUSH_RIGHT, FALSE,
+ EL_BDX_PLAYER, ACTION_PUSHING, MV_BIT_RIGHT
+ },
+ {
+ O_CREATURE_SWITCH_ON, FALSE,
+ EL_BDX_CREATURE_SWITCH_ACTIVE, -1, -1
+ },
+ {
+ O_EXPANDING_WALL_SWITCH_HORIZ, FALSE,
+ EL_BDX_EXPANDABLE_WALL_SWITCH, -1, -1
+ },
+ {
+ O_EXPANDING_WALL_SWITCH_VERT, FALSE,
+ EL_BDX_EXPANDABLE_WALL_SWITCH_ACTIVE, -1, -1
+ },
+ {
+ O_GRAVITY_SWITCH_ACTIVE, FALSE,
+ EL_BDX_GRAVITY_SWITCH_ACTIVE, -1, -1
+ },
+ {
+ O_REPLICATOR_SWITCH_OFF, FALSE,
+ EL_BDX_REPLICATOR_SWITCH, -1, -1
+ },
+ {
+ O_REPLICATOR_SWITCH_ON, FALSE,
+ EL_BDX_REPLICATOR_SWITCH_ACTIVE, -1, -1
+ },
+ {
+ O_CONVEYOR_DIR_NORMAL, FALSE,
+ EL_BDX_CONVEYOR_DIR_SWITCH, -1, -1
+ },
+ {
+ O_CONVEYOR_DIR_CHANGED, FALSE,
+ EL_BDX_CONVEYOR_DIR_SWITCH_ACTIVE, -1, -1
+ },
+ {
+ O_CONVEYOR_SWITCH_OFF, FALSE,
+ EL_BDX_CONVEYOR_SWITCH, -1, -1
+ },
+ {
+ O_CONVEYOR_SWITCH_ON, FALSE,
+ EL_BDX_CONVEYOR_SWITCH_ACTIVE, -1, -1
+ },
+ {
+ O_MAGIC_WALL_ACTIVE, FALSE,
+ EL_BDX_MAGIC_WALL_ACTIVE, -1, -1
+ },
+ {
+ O_REPLICATOR_ACTIVE, FALSE,
+ EL_BDX_REPLICATOR_ACTIVE, -1, -1
+ },
+ {
+ O_CONVEYOR_LEFT_ACTIVE, FALSE,
+ EL_BDX_CONVEYOR_LEFT_ACTIVE, -1, -1
+ },
+ {
+ O_CONVEYOR_RIGHT_ACTIVE, FALSE,
+ EL_BDX_CONVEYOR_RIGHT_ACTIVE, -1, -1
+ },
+ {
+ O_BITER_SWITCH_1, FALSE,
+ EL_BDX_BITER_SWITCH_1, -1, -1
+ },
+ {
+ O_BITER_SWITCH_2, FALSE,
+ EL_BDX_BITER_SWITCH_2, -1, -1
+ },
+ {
+ O_BITER_SWITCH_3, FALSE,
+ EL_BDX_BITER_SWITCH_3, -1, -1
+ },
+ {
+ O_BITER_SWITCH_4, FALSE,
+ EL_BDX_BITER_SWITCH_4, -1, -1
+ },
+
+ {
+ -1, FALSE,
+ -1, -1, -1
+ }
+};
+
+int map_element_RND_to_BD_cave(int element_rnd)
+{
+ static unsigned short mapping_RND_to_BD[NUM_FILE_ELEMENTS];
+ static boolean mapping_initialized = FALSE;
+
+ if (!mapping_initialized)
+ {
+ int i;
+
+ // return "O_UNKNOWN" for all undefined elements in mapping array
+ for (i = 0; i < NUM_FILE_ELEMENTS; i++)
+ mapping_RND_to_BD[i] = O_UNKNOWN;
+
+ for (i = 0; bd_object_mapping_list[i].element_bd != -1; i++)
+ if (bd_object_mapping_list[i].is_rnd_to_bd_mapping)
+ mapping_RND_to_BD[bd_object_mapping_list[i].element_rnd] =
+ bd_object_mapping_list[i].element_bd;
+
+ mapping_initialized = TRUE;
+ }
+
+ if (element_rnd < 0 || element_rnd >= NUM_FILE_ELEMENTS)
+ {
+ Warn("invalid RND element %d", element_rnd);
+
+ return O_UNKNOWN;
+ }
+
+ return mapping_RND_to_BD[element_rnd];
+}
+
+int map_element_RND_to_BD_effect(int element_rnd, int action)
+{
+ static unsigned short mapping_RND_to_BD[NUM_FILE_ELEMENTS][NUM_ACTIONS];
+ static boolean mapping_initialized = FALSE;
+
+ if (!mapping_initialized)
+ {
+ int i, j;
+
+ // return "O_UNKNOWN" for all undefined elements in mapping array
+ for (i = 0; i < NUM_FILE_ELEMENTS; i++)
+ for (j = 0; j < NUM_ACTIONS; j++)
+ mapping_RND_to_BD[i][j] = O_UNKNOWN;
+
+ for (i = 0; bd_object_mapping_list[i].element_bd != -1; i++)
+ {
+ int element_rnd = bd_object_mapping_list[i].element_rnd;
+ int element_bd = bd_object_mapping_list[i].element_bd;
+ int action = bd_object_mapping_list[i].action;
+
+ if (action != -1)
+ mapping_RND_to_BD[element_rnd][action] = element_bd;
+ }
+
+ mapping_initialized = TRUE;
+ }
+
+ if (element_rnd < 0 || element_rnd >= NUM_FILE_ELEMENTS)
+ {
+ Warn("invalid RND element %d", element_rnd);
+
+ return O_UNKNOWN;
+ }
+
+ if (action < 0 || action >= NUM_ACTIONS)
+ {
+ Warn("invalid action %d", action);
+
+ return O_UNKNOWN;
+ }
+
+ return mapping_RND_to_BD[element_rnd][action];
+}
+
+int map_element_BD_to_RND_cave(int element_bd)
+{
+ static unsigned short mapping_BD_to_RND[O_MAX_ALL];
+ static boolean mapping_initialized = FALSE;
+
+ if (!mapping_initialized)
+ {
+ int i;
+
+ // return "EL_UNKNOWN" for all undefined elements in mapping array
+ for (i = 0; i < O_MAX_ALL; i++)
+ mapping_BD_to_RND[i] = EL_UNKNOWN;
+
+ for (i = 0; bd_object_mapping_list[i].element_bd != -1; i++)
+ if (bd_object_mapping_list[i].is_rnd_to_bd_mapping)
+ mapping_BD_to_RND[bd_object_mapping_list[i].element_bd] =
+ bd_object_mapping_list[i].element_rnd;
+
+ mapping_initialized = TRUE;
+ }
+
+ if (element_bd < 0 || element_bd >= O_MAX_ALL)
+ {
+ Warn("invalid BD element %d", element_bd);
+
+ return EL_UNKNOWN;
+ }
+
+ return mapping_BD_to_RND[element_bd];
+}
+
+int map_element_BD_to_RND_game(int element_bd)
+{
+ static unsigned short mapping_BD_to_RND[O_MAX_ALL];
+ static boolean mapping_initialized = FALSE;
+
+ if (!mapping_initialized)
+ {
+ int i;
+
+ // return "EL_UNKNOWN" for all undefined elements in mapping array
+ for (i = 0; i < O_MAX_ALL; i++)
+ mapping_BD_to_RND[i] = EL_UNKNOWN;
+
+ for (i = 0; bd_object_mapping_list[i].element_bd != -1; i++)
+ mapping_BD_to_RND[bd_object_mapping_list[i].element_bd] =
+ bd_object_mapping_list[i].element_rnd;
+
+ mapping_initialized = TRUE;
+ }
+
+ if (element_bd < 0 || element_bd >= O_MAX_ALL)
+ {
+ Warn("invalid BD element %d", element_bd);
+
+ return EL_UNKNOWN;
+ }
+
+ return mapping_BD_to_RND[element_bd];
+}
+
+static struct Mapping_EM_to_RND_object
+{
+ int element_em;
+ 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[GAME_TILE_MAX + 1] =
+{
+ {
+ Zborder, FALSE, FALSE,
+ EL_EMPTY, -1, -1
+ },
+ {
+ Zplayer, FALSE, FALSE,
+ EL_EMPTY, -1, -1
+ },
+
+ {
+ Zbug, FALSE, FALSE,
+ EL_EMPTY, -1, -1
+ },
+ {
+ Ztank, FALSE, FALSE,
+ EL_EMPTY, -1, -1
+ },
+ {
+ Zeater, FALSE, FALSE,
+ EL_EMPTY, -1, -1
+ },
+ {
+ Zdynamite, FALSE, FALSE,
+ EL_EMPTY, -1, -1
+ },
+ {
+ Zboom, FALSE, FALSE,
+ EL_EMPTY, -1, -1
+ },
+
+ {
+ Xchain, FALSE, FALSE,
+ EL_DEFAULT, ACTION_EXPLODING, -1
+ },
+ {
+ Xboom_bug, FALSE, FALSE,
+ EL_BUG, ACTION_EXPLODING, -1
+ },
+ {
+ Xboom_tank, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_EXPLODING, -1
+ },
+ {
+ Xboom_android, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_OTHER, -1
+ },
+ {
+ Xboom_1, FALSE, FALSE,
+ EL_DEFAULT, ACTION_EXPLODING, -1
+ },
+ {
+ Xboom_2, FALSE, FALSE,
+ EL_DEFAULT, ACTION_EXPLODING, -1
+ },
+
+ {
+ Xblank, TRUE, FALSE,
+ EL_EMPTY, -1, -1
+ },
+
+ {
+ Xsplash_e, FALSE, FALSE,
+ EL_ACID_SPLASH_RIGHT, -1, -1
+ },
+ {
+ Xsplash_w, FALSE, FALSE,
+ EL_ACID_SPLASH_LEFT, -1, -1
+ },
+
+ {
+ Xplant, TRUE, FALSE,
+ EL_EMC_PLANT, -1, -1
+ },
+ {
+ Yplant, FALSE, FALSE,
+ EL_EMC_PLANT, -1, -1
+ },
+
+ {
+ Xacid_1, TRUE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xacid_2, FALSE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xacid_3, FALSE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xacid_4, FALSE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xacid_5, FALSE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xacid_6, FALSE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xacid_7, FALSE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xacid_8, FALSE, FALSE,
+ EL_ACID, -1, -1
+ },
+
+ {
+ Xfake_acid_1, TRUE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_2, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_3, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_4, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_5, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_6, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_7, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_8, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+
+ {
+ Xfake_acid_1_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_2_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_3_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_4_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_5_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_6_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_7_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_8_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+
+ {
+ Xgrass, TRUE, FALSE,
+ EL_EMC_GRASS, -1, -1
+ },
+ {
+ Ygrass_nB, FALSE, FALSE,
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_UP
+ },
+ {
+ Ygrass_eB, FALSE, FALSE,
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_RIGHT
+ },
+ {
+ Ygrass_sB, FALSE, FALSE,
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_DOWN
+ },
+ {
+ Ygrass_wB, FALSE, FALSE,
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_LEFT
+ },
+
+ {
+ Xdirt, TRUE, FALSE,
+ EL_SAND, -1, -1
+ },
+ {
+ Ydirt_nB, FALSE, FALSE,
+ EL_SAND, ACTION_DIGGING, MV_BIT_UP
+ },
+ {
+ Ydirt_eB, FALSE, FALSE,
+ EL_SAND, ACTION_DIGGING, MV_BIT_RIGHT
+ },
+ {
+ Ydirt_sB, FALSE, FALSE,
+ EL_SAND, ACTION_DIGGING, MV_BIT_DOWN
+ },
+ {
+ Ydirt_wB, FALSE, FALSE,
+ EL_SAND, ACTION_DIGGING, MV_BIT_LEFT
+ },
+
+ {
+ 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_eB, FALSE, TRUE,
+ EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yandroid_se, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_GROWING, MV_BIT_DOWNRIGHT
+ },
+ {
+ Yandroid_seB, FALSE, TRUE,
+ EL_EMC_ANDROID, ACTION_SHRINKING, MV_BIT_DOWNRIGHT
+ },
+ {
+ Yandroid_s, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yandroid_sB, FALSE, TRUE,
+ EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yandroid_sw, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_GROWING, MV_BIT_DOWNLEFT
+ },
+ {
+ Yandroid_swB, FALSE, TRUE,
+ EL_EMC_ANDROID, ACTION_SHRINKING, MV_BIT_DOWNLEFT
+ },
+ {
+ Yandroid_w, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yandroid_wB, FALSE, TRUE,
+ EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yandroid_nw, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_GROWING, MV_BIT_UPLEFT
+ },
+ {
+ Yandroid_nwB, FALSE, TRUE,
+ EL_EMC_ANDROID, ACTION_SHRINKING, MV_BIT_UPLEFT
+ },
+
+ {
+ Xeater_n, TRUE, FALSE,
+ EL_YAMYAM_UP, -1, -1
+ },
+ {
+ Xeater_e, TRUE, FALSE,
+ EL_YAMYAM_RIGHT, -1, -1
+ },
+ {
+ Xeater_w, TRUE, FALSE,
+ EL_YAMYAM_LEFT, -1, -1
+ },
+ {
+ Xeater_s, TRUE, FALSE,
+ EL_YAMYAM_DOWN, -1, -1
+ },
+ {
+ Yeater_n, FALSE, FALSE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Yeater_nB, FALSE, TRUE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Yeater_e, FALSE, FALSE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yeater_eB, FALSE, TRUE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yeater_s, FALSE, FALSE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yeater_sB, FALSE, TRUE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yeater_w, FALSE, FALSE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yeater_wB, FALSE, TRUE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yeater_stone, FALSE, FALSE,
+ EL_YAMYAM, ACTION_SMASHED_BY_ROCK, -1
+ },
+ {
+ Yeater_spring, FALSE, FALSE,
+ EL_YAMYAM, ACTION_SMASHED_BY_SPRING, -1
+ },
+
+ {
+ Xalien, TRUE, FALSE,
+ EL_ROBOT, -1, -1
+ },
+ {
+ Xalien_pause, FALSE, FALSE,
+ EL_ROBOT, -1, -1
+ },
+ {
+ Yalien_n, FALSE, FALSE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Yalien_nB, FALSE, TRUE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Yalien_e, FALSE, FALSE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yalien_eB, FALSE, TRUE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yalien_s, FALSE, FALSE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yalien_sB, FALSE, TRUE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yalien_w, FALSE, FALSE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yalien_wB, FALSE, TRUE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yalien_stone, FALSE, FALSE,
+ EL_ROBOT, ACTION_SMASHED_BY_ROCK, -1
+ },
+ {
+ Yalien_spring, FALSE, FALSE,
+ EL_ROBOT, ACTION_SMASHED_BY_SPRING, -1
+ },
+
+ {
+ Xbug_1_n, TRUE, FALSE,
+ EL_BUG_UP, -1, -1
+ },
+ {
+ Xbug_1_e, TRUE, FALSE,
+ EL_BUG_RIGHT, -1, -1
+ },
+ {
+ Xbug_1_s, TRUE, FALSE,
+ EL_BUG_DOWN, -1, -1
+ },
+ {
+ Xbug_1_w, TRUE, FALSE,
+ EL_BUG_LEFT, -1, -1
+ },
+ {
+ Xbug_2_n, FALSE, FALSE,
+ EL_BUG_UP, -1, -1
+ },
+ {
+ Xbug_2_e, FALSE, FALSE,
+ EL_BUG_RIGHT, -1, -1
+ },
+ {
+ Xbug_2_s, FALSE, FALSE,
+ EL_BUG_DOWN, -1, -1
+ },
+ {
+ Xbug_2_w, FALSE, FALSE,
+ EL_BUG_LEFT, -1, -1
+ },
+ {
+ Ybug_n, FALSE, FALSE,
+ EL_BUG, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Ybug_nB, FALSE, TRUE,
+ EL_BUG, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Ybug_e, FALSE, FALSE,
+ EL_BUG, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ybug_eB, FALSE, TRUE,
+ EL_BUG, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ybug_s, FALSE, FALSE,
+ EL_BUG, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Ybug_sB, FALSE, TRUE,
+ EL_BUG, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Ybug_w, FALSE, FALSE,
+ EL_BUG, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ybug_wB, FALSE, TRUE,
+ EL_BUG, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ybug_w_n, FALSE, FALSE,
+ EL_BUG, ACTION_TURNING_FROM_LEFT, MV_BIT_UP
+ },
+ {
+ Ybug_n_e, FALSE, FALSE,
+ EL_BUG, ACTION_TURNING_FROM_UP, MV_BIT_RIGHT
+ },
+ {
+ Ybug_e_s, FALSE, FALSE,
+ EL_BUG, ACTION_TURNING_FROM_RIGHT, MV_BIT_DOWN
+ },
+ {
+ Ybug_s_w, FALSE, FALSE,
+ EL_BUG, ACTION_TURNING_FROM_DOWN, 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_blank, FALSE, FALSE,
+ EL_DIAMOND, ACTION_COLLECTING, -1
+ },
+ {
+ Ydiamond_stone, FALSE, FALSE,
+ EL_DIAMOND, ACTION_SMASHED_BY_ROCK, -1
+ },
+
+ {
+ Xstone, TRUE, FALSE,
+ EL_ROCK, -1, -1
+ },
+ {
+ Xstone_pause, FALSE, FALSE,
+ EL_ROCK, -1, -1
+ },
+ {
+ Xstone_fall, FALSE, FALSE,
+ EL_ROCK, -1, -1
+ },
+ {
+ Ystone_s, FALSE, FALSE,
+ EL_ROCK, ACTION_FALLING, -1
+ },
+ {
+ Ystone_sB, FALSE, TRUE,
+ EL_ROCK, ACTION_FALLING, -1
+ },
+ {
+ Ystone_e, FALSE, FALSE,
+ EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ystone_eB, FALSE, TRUE,
+ EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ 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
+ },
+ {
+ Xbomb_pause, FALSE, FALSE,
+ EL_BOMB, -1, -1
+ },
+ {
+ Xbomb_fall, FALSE, FALSE,
+ EL_BOMB, -1, -1
+ },
+ {
+ Ybomb_s, FALSE, FALSE,
+ EL_BOMB, ACTION_FALLING, -1
+ },
+ {
+ Ybomb_sB, FALSE, TRUE,
+ EL_BOMB, ACTION_FALLING, -1
+ },
+ {
+ Ybomb_e, FALSE, FALSE,
+ EL_BOMB, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ybomb_eB, FALSE, TRUE,
+ EL_BOMB, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ybomb_w, FALSE, FALSE,
+ EL_BOMB, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ybomb_wB, FALSE, TRUE,
+ EL_BOMB, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ybomb_blank, FALSE, FALSE,
+ EL_BOMB, ACTION_ACTIVATING, -1
+ },
+
+ {
+ Xnut, TRUE, FALSE,
+ EL_NUT, -1, -1
+ },
+ {
+ Xnut_pause, FALSE, FALSE,
+ EL_NUT, -1, -1
+ },
+ {
+ Xnut_fall, FALSE, FALSE,
+ EL_NUT, -1, -1
+ },
+ {
+ Ynut_s, FALSE, FALSE,
+ EL_NUT, ACTION_FALLING, -1
+ },
+ {
+ Ynut_sB, FALSE, TRUE,
+ EL_NUT, ACTION_FALLING, -1
+ },
+ {
+ Ynut_e, FALSE, FALSE,
+ EL_NUT, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ynut_eB, FALSE, TRUE,
+ EL_NUT, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ynut_w, FALSE, FALSE,
+ EL_NUT, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ynut_wB, FALSE, TRUE,
+ EL_NUT, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ynut_stone, FALSE, FALSE,
+ EL_NUT, ACTION_BREAKING, -1
+ },
+
+ {
+ Xspring, TRUE, FALSE,
+ EL_SPRING, -1, -1
+ },
+ {
+ Xspring_pause, FALSE, FALSE,
+ EL_SPRING, -1, -1
+ },
+ {
+ Xspring_e, TRUE, FALSE,
+ EL_SPRING_RIGHT, -1, -1
+ },
+ {
+ Xspring_w, TRUE, FALSE,
+ EL_SPRING_LEFT, -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_alien_e, FALSE, FALSE,
+ EL_SPRING, ACTION_EATING, MV_BIT_RIGHT
+ },
+ {
+ Yspring_alien_eB, FALSE, TRUE,
+ EL_SPRING, ACTION_EATING, MV_BIT_RIGHT
+ },
+ {
+ Yspring_alien_w, FALSE, FALSE,
+ EL_SPRING, ACTION_EATING, MV_BIT_LEFT
+ },
+ {
+ Yspring_alien_wB, FALSE, TRUE,
+ EL_SPRING, ACTION_EATING, MV_BIT_LEFT
+ },
+
+ {
+ Xpush_emerald_e, FALSE, FALSE,
+ EL_EMERALD, -1, MV_BIT_RIGHT
+ },
+ {
+ Xpush_emerald_w, FALSE, FALSE,
+ EL_EMERALD, -1, MV_BIT_LEFT
+ },
+ {
+ Xpush_diamond_e, FALSE, FALSE,
+ EL_DIAMOND, -1, MV_BIT_RIGHT
+ },
+ {
+ Xpush_diamond_w, FALSE, FALSE,
+ EL_DIAMOND, -1, MV_BIT_LEFT
+ },
+ {
+ Xpush_stone_e, FALSE, FALSE,
+ EL_ROCK, -1, MV_BIT_RIGHT
+ },
+ {
+ Xpush_stone_w, FALSE, FALSE,
+ EL_ROCK, -1, MV_BIT_LEFT
+ },
+ {
+ Xpush_bomb_e, FALSE, FALSE,
+ EL_BOMB, -1, MV_BIT_RIGHT
+ },
+ {
+ Xpush_bomb_w, FALSE, FALSE,
+ EL_BOMB, -1, MV_BIT_LEFT
+ },
+ {
+ Xpush_nut_e, FALSE, FALSE,
+ EL_NUT, -1, MV_BIT_RIGHT
+ },
+ {
+ Xpush_nut_w, FALSE, FALSE,
+ EL_NUT, -1, MV_BIT_LEFT
+ },
+ {
+ Xpush_spring_e, FALSE, FALSE,
+ EL_SPRING_RIGHT, -1, MV_BIT_RIGHT
+ },
+ {
+ Xpush_spring_w, FALSE, FALSE,
+ EL_SPRING_LEFT, -1, MV_BIT_LEFT
+ },
+
+ {
+ 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
+ },
+ {
+ Xfake_door_6, TRUE, FALSE,
+ EL_EMC_GATE_6_GRAY, -1, -1
+ },
+ {
+ Xfake_door_7, TRUE, FALSE,
+ EL_EMC_GATE_7_GRAY, -1, -1
+ },
+ {
+ Xfake_door_8, TRUE, FALSE,
+ EL_EMC_GATE_8_GRAY, -1, -1
+ },
+
+ {
+ Xballoon, TRUE, FALSE,
+ EL_BALLOON, -1, -1
+ },
+ {
+ Yballoon_n, FALSE, FALSE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Yballoon_nB, FALSE, TRUE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Yballoon_e, FALSE, FALSE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yballoon_eB, FALSE, TRUE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yballoon_s, FALSE, FALSE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yballoon_sB, FALSE, TRUE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yballoon_w, FALSE, FALSE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yballoon_wB, FALSE, TRUE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_LEFT
+ },
+
+ {
+ Xball_1, TRUE, FALSE,
+ EL_EMC_MAGIC_BALL, -1, -1
+ },
+ {
+ Yball_1, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
+ },
+ {
+ Xball_2, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
+ },
+ {
+ Yball_2, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
+ },
+ {
+ Yball_blank, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL, ACTION_DROPPING, -1
+ },
+
+ {
+ Xamoeba_1, TRUE, FALSE,
+ EL_AMOEBA_DRY, ACTION_OTHER, -1
+ },
+ {
+ Xamoeba_2, FALSE, FALSE,
+ EL_AMOEBA_DRY, ACTION_OTHER, -1
+ },
+ {
+ Xamoeba_3, FALSE, FALSE,
+ EL_AMOEBA_DRY, ACTION_OTHER, -1
+ },
+ {
+ Xamoeba_4, FALSE, FALSE,
+ EL_AMOEBA_DRY, ACTION_OTHER, -1
+ },
+ {
+ Xamoeba_5, TRUE, FALSE,
+ EL_AMOEBA_WET, ACTION_OTHER, -1
+ },
+ {
+ Xamoeba_6, FALSE, FALSE,
+ EL_AMOEBA_WET, ACTION_OTHER, -1
+ },
+ {
+ Xamoeba_7, FALSE, FALSE,
+ EL_AMOEBA_WET, ACTION_OTHER, -1
+ },
+ {
+ Xamoeba_8, FALSE, FALSE,
+ EL_AMOEBA_WET, ACTION_OTHER, -1
+ },
+
+ {
+ Xdrip, TRUE, FALSE,
+ EL_AMOEBA_DROP, ACTION_GROWING, -1
+ },
+ {
+ Xdrip_fall, FALSE, FALSE,
+ EL_AMOEBA_DROP, -1, -1
+ },
+ {
+ Xdrip_stretch, FALSE, FALSE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
+ },
+ {
+ Xdrip_stretchB, FALSE, TRUE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
+ },
+ {
+ Ydrip_1_s, FALSE, FALSE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
+ },
+ {
+ Ydrip_1_sB, FALSE, TRUE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
+ },
+ {
+ Ydrip_2_s, FALSE, FALSE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
+ },
+ {
+ Ydrip_2_sB, FALSE, TRUE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
+ },
+
+ {
+ Xwonderwall, TRUE, FALSE,
+ EL_MAGIC_WALL, -1, -1
+ },
+ {
+ Ywonderwall, FALSE, FALSE,
+ EL_MAGIC_WALL, ACTION_ACTIVE, -1
+ },
+
+ {
+ Xwheel, TRUE, FALSE,
+ EL_ROBOT_WHEEL, -1, -1
+ },
+ {
+ Ywheel, FALSE, FALSE,
+ EL_ROBOT_WHEEL, ACTION_ACTIVE, -1
+ },
+
+ {
+ Xswitch, TRUE, FALSE,
+ EL_EMC_MAGIC_BALL_SWITCH, -1, -1
+ },
+ {
+ Yswitch, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL_SWITCH, ACTION_ACTIVE, -1
+ },
+
+ {
+ Xbumper, TRUE, FALSE,
+ EL_EMC_SPRING_BUMPER, -1, -1
+ },
+ {
+ Ybumper, FALSE, FALSE,
+ EL_EMC_SPRING_BUMPER, ACTION_ACTIVE, -1
+ },
+
+ {
+ Xacid_nw, TRUE, FALSE,
+ EL_ACID_POOL_TOPLEFT, -1, -1
+ },
+ {
+ Xacid_ne, TRUE, FALSE,
+ EL_ACID_POOL_TOPRIGHT, -1, -1
+ },
+ {
+ Xacid_sw, TRUE, FALSE,
+ EL_ACID_POOL_BOTTOMLEFT, -1, -1
+ },
+ {
+ Xacid_s, TRUE, FALSE,
+ EL_ACID_POOL_BOTTOM, -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
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
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
- },
- {
- 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
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
Xdecor_12, TRUE, FALSE,
EL_EMC_WALL_12, -1, -1
},
+
{
Xalpha_0, TRUE, FALSE,
EL_CHAR('0'), -1, -1
EL_CHAR('!'), -1, -1
},
{
- Xalpha_quote, TRUE, FALSE,
- EL_CHAR('"'), -1, -1
+ Xalpha_apost, TRUE, FALSE,
+ EL_CHAR('\''), -1, -1
},
{
Xalpha_comma, TRUE, FALSE,
},
{
- 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
},
{
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,
},
}
};
-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;
+
+ if (!mapping_initialized)
+ {
+ int i;
+
+ // 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;
+
+ for (i = 0; em_object_mapping_list[i].element_em != -1; i++)
+ if (em_object_mapping_list[i].is_rnd_to_em_mapping)
+ mapping_RND_to_EM[em_object_mapping_list[i].element_rnd] =
+ em_object_mapping_list[i].element_em;
+
+ mapping_initialized = TRUE;
+ }
+
+ 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_RND_to_EM[NUM_FILE_ELEMENTS];
+ static unsigned short mapping_EM_to_RND[GAME_TILE_MAX];
static boolean mapping_initialized = FALSE;
if (!mapping_initialized)
{
int i;
- // 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;
+ // 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++)
- if (em_object_mapping_list[i].is_rnd_to_em_mapping)
- mapping_RND_to_EM[em_object_mapping_list[i].element_rnd] =
- em_object_mapping_list[i].element_em;
+ mapping_EM_to_RND[em_object_mapping_list[i].element_em] =
+ em_object_mapping_list[i].element_rnd;
mapping_initialized = TRUE;
}
- if (element_rnd >= 0 && element_rnd < NUM_FILE_ELEMENTS)
- return mapping_RND_to_EM[element_rnd];
+ 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++)
+ 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_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)
element_rnd <= EL_MM_END_2 ?
EL_MM_START_2_NATIVE + element_rnd - EL_MM_START_2 :
+ element_rnd >= EL_MM_START_3 &&
+ element_rnd <= EL_MM_END_3 ?
+ EL_MM_START_3_NATIVE + element_rnd - EL_MM_START_3 :
+
element_rnd >= EL_CHAR_START &&
element_rnd <= EL_CHAR_END ?
EL_MM_CHAR_START_NATIVE + element_rnd - EL_CHAR_START :
element_rnd <= EL_MM_RUNTIME_END ?
EL_MM_RUNTIME_START_NATIVE + element_rnd - EL_MM_RUNTIME_START :
- element_rnd >= EL_MM_DUMMY_START &&
- element_rnd <= EL_MM_DUMMY_END ?
- EL_MM_DUMMY_START_NATIVE + element_rnd - EL_MM_DUMMY_START :
-
EL_MM_EMPTY_NATIVE);
}
element_mm <= EL_MM_END_2_NATIVE ?
EL_MM_START_2 + element_mm - EL_MM_START_2_NATIVE :
+ element_mm >= EL_MM_START_3_NATIVE &&
+ element_mm <= EL_MM_END_3_NATIVE ?
+ EL_MM_START_3 + element_mm - EL_MM_START_3_NATIVE :
+
element_mm >= EL_MM_CHAR_START_NATIVE &&
element_mm <= EL_MM_CHAR_END_NATIVE ?
EL_CHAR_START + element_mm - EL_MM_CHAR_START_NATIVE :
element_mm <= EL_MM_RUNTIME_END_NATIVE ?
EL_MM_RUNTIME_START + element_mm - EL_MM_RUNTIME_START_NATIVE :
- element_mm >= EL_MM_DUMMY_START_NATIVE &&
- element_mm <= EL_MM_DUMMY_END_NATIVE ?
- EL_MM_DUMMY_START + element_mm - EL_MM_DUMMY_START_NATIVE :
-
EL_EMPTY);
}
return el2img(map_element_MM_to_RND(element_mm));
}
+int el_act2img_mm(int element_mm, int action)
+{
+ return el_act2img(map_element_MM_to_RND(element_mm), action);
+}
+
int el_act_dir2img(int element, int action, int direction)
{
element = GFX_ELEMENT(element);
return element_info[element].special_graphic[GFX_SPECIAL_ARG_EDITOR];
}
+int el2edimg_with_frame(int element, int *graphic, int *frame)
+{
+ *graphic = el2edimg(element);
+ *frame = 0;
+
+ if (*graphic == IMG_UNKNOWN)
+ {
+ // no graphic defined -- if BD style, try to get runtime ("effect") element graphics
+ // (normal BD style elements have graphics, but runtime ("effects") elements do not)
+ int element_bd = map_element_RND_to_BD_cave(element);
+
+ if (element_bd != O_UNKNOWN)
+ {
+ struct GraphicInfo_BD *g_bd = &graphic_info_bd_object[element_bd][0];
+
+ *graphic = g_bd->graphic;
+ *frame = g_bd->frame;
+ }
+ }
+
+ return *graphic;
+}
+
int el2preimg(int element)
{
element = GFX_ELEMENT(element);
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)
{
- if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ if (level.game_engine_type == GAME_ENGINE_TYPE_BD)
+ return InitEngineRandom_BD(seed);
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
return InitEngineRandom_EM(seed);
else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
return InitEngineRandom_SP(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_BD_to_RND_object bd_object_mapping[O_MAX_ALL];
+static struct Mapping_EM_to_RND_object em_object_mapping[GAME_TILE_MAX];
+static struct Mapping_EM_to_RND_player em_player_mapping[MAX_PLAYERS][PLY_MAX];
static int get_effective_element_EM(int tile, int frame_em)
{
- int element = object_mapping[tile].element_rnd;
- int action = object_mapping[tile].action;
- boolean is_backside = object_mapping[tile].is_backside;
+ int element = em_object_mapping[tile].element_rnd;
+ int action = em_object_mapping[tile].action;
+ boolean is_backside = em_object_mapping[tile].is_backside;
boolean action_removing = (action == ACTION_DIGGING ||
action == ACTION_SNAPPING ||
action == ACTION_COLLECTING);
{
switch (tile)
{
- case Yacid_splash_eB:
- case Yacid_splash_wB:
+ case Xsplash_e:
+ case Xsplash_w:
return (frame_em > 5 ? EL_EMPTY : element);
default:
{
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:
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:
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;
}
void SetGfxAnimation_EM(struct GraphicInfo_EM *g_em,
int tile, int frame_em, int x, int y)
{
- int action = object_mapping[tile].action;
- int direction = object_mapping[tile].direction;
+ int action = em_object_mapping[tile].action;
+ int direction = em_object_mapping[tile].direction;
int effective_element = get_effective_element_EM(tile, frame_em);
int graphic = (direction == MV_NONE ?
el_act2img(effective_element, action) :
}
else if (action_moving)
{
- boolean is_backside = object_mapping[tile].is_backside;
+ boolean is_backside = em_object_mapping[tile].is_backside;
if (is_backside)
{
- int direction = object_mapping[tile].direction;
+ int direction = em_object_mapping[tile].direction;
int move_dir = (action_falling ? MV_DOWN : direction);
GfxFrame[x][y]++;
if (graphic_info[graphic].anim_global_sync)
sync_frame = FrameCounter;
+ else if (graphic_info[graphic].anim_global_anim_sync)
+ sync_frame = getGlobalAnimSyncFrame();
else if (IN_FIELD(x, y, MAX_LEV_FIELDX, MAX_LEV_FIELDY))
sync_frame = GfxFrame[x][y];
else
void getGraphicSourceObjectExt_EM(struct GraphicInfo_EM *g_em,
int tile, int frame_em, int x, int y)
{
- int action = object_mapping[tile].action;
- int direction = object_mapping[tile].direction;
- boolean is_backside = object_mapping[tile].is_backside;
+ int action = em_object_mapping[tile].action;
+ int direction = em_object_mapping[tile].direction;
+ boolean is_backside = em_object_mapping[tile].is_backside;
int effective_element = get_effective_element_EM(tile, frame_em);
int effective_action = action;
int graphic = (direction == MV_NONE ?
if (graphic_info[graphic].anim_global_sync)
sync_frame = FrameCounter;
+ else if (graphic_info[graphic].anim_global_anim_sync)
+ sync_frame = getGlobalAnimSyncFrame();
else if (IN_FIELD(x, y, MAX_LEV_FIELDX, MAX_LEV_FIELDY))
sync_frame = GfxFrame[x][y];
else
void getGraphicSourcePlayerExt_EM(struct GraphicInfo_EM *g_em,
int player_nr, int anim, int frame_em)
{
- int element = player_mapping[player_nr][anim].element_rnd;
- int action = player_mapping[player_nr][anim].action;
- int direction = player_mapping[player_nr][anim].direction;
+ int element = em_player_mapping[player_nr][anim].element_rnd;
+ int action = em_player_mapping[player_nr][anim].action;
+ int direction = em_player_mapping[player_nr][anim].direction;
int graphic = (direction == MV_NONE ?
el_act2img(element, action) :
el_act_dir2img(element, action, direction));
&g_em->src_x, &g_em->src_y, FALSE);
}
-void InitGraphicInfo_EM(void)
+#define BD_GFX_RANGE(a, n, i) ((i) >= (a) && (i) < (a) + (n))
+#define BD_GFX_FRAME(b, i) (((i) - (b)) * 8)
+
+void InitGraphicInfo_BD(void)
{
- int i, j, p;
+ int i, j;
-#if DEBUG_EM_GFX
- int num_em_gfx_errors = 0;
+ // always start with reliable default values
+ for (i = 0; i < O_MAX_ALL; i++)
+ {
+ bd_object_mapping[i].element_rnd = EL_UNKNOWN;
+ bd_object_mapping[i].action = ACTION_DEFAULT;
+ bd_object_mapping[i].direction = MV_NONE;
+ }
- if (graphic_info_em_object[0][0].bitmap == NULL)
+ for (i = 0; bd_object_mapping_list[i].element_bd != -1; i++)
{
- // EM graphics not yet initialized in em_open_all()
+ int e = bd_object_mapping_list[i].element_bd;
- return;
+ bd_object_mapping[e].element_rnd = bd_object_mapping_list[i].element_rnd;
+
+ if (bd_object_mapping_list[i].action != -1)
+ bd_object_mapping[e].action = bd_object_mapping_list[i].action;
+
+ if (bd_object_mapping_list[i].direction != -1)
+ bd_object_mapping[e].direction =
+ MV_DIR_FROM_BIT(bd_object_mapping_list[i].direction);
}
- printf("::: [4 errors can be ignored (1 x 'bomb', 3 x 'em_dynamite']\n");
-#endif
+ for (i = 0; i < O_MAX_ALL; i++)
+ {
+ int element = bd_object_mapping[i].element_rnd;
+ int action = bd_object_mapping[i].action;
+ int direction = bd_object_mapping[i].direction;
+
+ for (j = 0; j < 8; j++)
+ {
+ int effective_element = element;
+ int effective_action = action;
+ int graphic = (el_act_dir2img(effective_element, effective_action,
+ direction));
+ struct GraphicInfo *g = &graphic_info[graphic];
+ struct GraphicInfo_BD *g_bd = &graphic_info_bd_object[i][j];
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int sync_frame = (BD_GFX_RANGE(O_PRE_PL_1, 3, i) ? BD_GFX_FRAME(O_PRE_PL_1, i) :
+ BD_GFX_RANGE(O_PRE_DIA_1, 5, i) ? BD_GFX_FRAME(O_PRE_DIA_1, i) :
+ BD_GFX_RANGE(O_PRE_STONE_1, 4, i) ? BD_GFX_FRAME(O_PRE_STONE_1, i) :
+ BD_GFX_RANGE(O_PRE_STEEL_1, 4, i) ? BD_GFX_FRAME(O_PRE_STEEL_1, i) :
+ BD_GFX_RANGE(O_BOMB_TICK_1, 7, i) ? BD_GFX_FRAME(O_BOMB_TICK_1, i) :
+ BD_GFX_RANGE(O_BOMB_EXPL_1, 4, i) ? BD_GFX_FRAME(O_BOMB_EXPL_1, i) :
+ BD_GFX_RANGE(O_NUT_EXPL_1, 4, i) ? BD_GFX_FRAME(O_NUT_EXPL_1, i) :
+ BD_GFX_RANGE(O_GHOST_EXPL_1, 4, i) ? BD_GFX_FRAME(O_GHOST_EXPL_1, i) :
+ BD_GFX_RANGE(O_EXPLODE_1, 5, i) ? BD_GFX_FRAME(O_EXPLODE_1, i) :
+ BD_GFX_RANGE(O_PRE_CLOCK_1, 4, i) ? BD_GFX_FRAME(O_PRE_CLOCK_1, i) :
+ BD_GFX_RANGE(O_NITRO_EXPL_1, 4, i) ? BD_GFX_FRAME(O_NITRO_EXPL_1, i) :
+ BD_GFX_RANGE(O_AMOEBA_2_EXPL_1, 4, i) ? BD_GFX_FRAME(O_AMOEBA_2_EXPL_1, i):
+ i == O_INBOX_OPEN || i == O_OUTBOX_OPEN ? j :
+ j * 2);
+ int frame = getAnimationFrame(g->anim_frames,
+ g->anim_delay,
+ g->anim_mode,
+ g->anim_start_frame,
+ sync_frame);
+
+ getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y, FALSE);
+
+ g_bd->bitmap = src_bitmap;
+ g_bd->src_x = src_x;
+ g_bd->src_y = src_y;
+ g_bd->width = TILEX;
+ g_bd->height = TILEY;
+
+ g_bd->graphic = graphic;
+ g_bd->frame = frame;
+ }
+ }
+
+ // game graphics template for level-specific colors for native BD levels
+ int graphic = IMG_BDX_GAME_GRAPHICS_COLOR_TEMPLATE;
+ struct GraphicInfo_BD *g_bd = &graphic_info_bd_color_template;
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+
+ getGraphicSourceExt(graphic, 0, &src_bitmap, &src_x, &src_y, FALSE);
+
+ g_bd->bitmap = src_bitmap;
+ g_bd->src_x = src_x;
+ g_bd->src_y = src_y;
+ g_bd->width = TILEX;
+ g_bd->height = TILEY;
+
+ g_bd->graphic = graphic;
+ g_bd->frame = 0;
+}
+
+void InitGraphicInfo_EM(void)
+{
+ int i, j, p;
// always start with reliable default values
- for (i = 0; i < TILE_MAX; i++)
+ for (i = 0; i < GAME_TILE_MAX; i++)
{
- object_mapping[i].element_rnd = EL_UNKNOWN;
- object_mapping[i].is_backside = FALSE;
- object_mapping[i].action = ACTION_DEFAULT;
- object_mapping[i].direction = MV_NONE;
+ em_object_mapping[i].element_rnd = EL_UNKNOWN;
+ em_object_mapping[i].is_backside = FALSE;
+ em_object_mapping[i].action = ACTION_DEFAULT;
+ em_object_mapping[i].direction = MV_NONE;
}
// always start with reliable default values
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;
- player_mapping[p][i].direction = MV_NONE;
+ em_player_mapping[p][i].element_rnd = EL_UNKNOWN;
+ em_player_mapping[p][i].action = ACTION_DEFAULT;
+ em_player_mapping[p][i].direction = MV_NONE;
}
}
{
int e = em_object_mapping_list[i].element_em;
- object_mapping[e].element_rnd = em_object_mapping_list[i].element_rnd;
- object_mapping[e].is_backside = em_object_mapping_list[i].is_backside;
+ em_object_mapping[e].element_rnd = em_object_mapping_list[i].element_rnd;
+ em_object_mapping[e].is_backside = em_object_mapping_list[i].is_backside;
if (em_object_mapping_list[i].action != -1)
- object_mapping[e].action = em_object_mapping_list[i].action;
+ em_object_mapping[e].action = em_object_mapping_list[i].action;
if (em_object_mapping_list[i].direction != -1)
- object_mapping[e].direction =
+ em_object_mapping[e].direction =
MV_DIR_FROM_BIT(em_object_mapping_list[i].direction);
}
int a = em_player_mapping_list[i].action_em;
int p = em_player_mapping_list[i].player_nr;
- player_mapping[p][a].element_rnd = em_player_mapping_list[i].element_rnd;
+ em_player_mapping[p][a].element_rnd = em_player_mapping_list[i].element_rnd;
if (em_player_mapping_list[i].action != -1)
- player_mapping[p][a].action = em_player_mapping_list[i].action;
+ em_player_mapping[p][a].action = em_player_mapping_list[i].action;
if (em_player_mapping_list[i].direction != -1)
- player_mapping[p][a].direction =
+ em_player_mapping[p][a].direction =
MV_DIR_FROM_BIT(em_player_mapping_list[i].direction);
}
- for (i = 0; i < TILE_MAX; i++)
+ for (i = 0; i < GAME_TILE_MAX; i++)
{
- int element = object_mapping[i].element_rnd;
- int action = object_mapping[i].action;
- int direction = object_mapping[i].direction;
- boolean is_backside = object_mapping[i].is_backside;
+ int element = em_object_mapping[i].element_rnd;
+ int action = em_object_mapping[i].action;
+ int direction = em_object_mapping[i].direction;
+ boolean is_backside = em_object_mapping[i].is_backside;
boolean action_exploding = ((action == ACTION_EXPLODING ||
action == ACTION_SMASHED_BY_ROCK ||
action == ACTION_SMASHED_BY_SPRING) &&
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 :
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
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 :
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 :
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 :
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,
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 :
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 :
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++)
{
- int element = object_mapping[i].element_rnd;
- int action = object_mapping[i].action;
- int direction = object_mapping[i].direction;
- boolean is_backside = object_mapping[i].is_backside;
+ int element = em_object_mapping[i].element_rnd;
+ int action = em_object_mapping[i].action;
+ int direction = em_object_mapping[i].direction;
+ boolean is_backside = em_object_mapping[i].is_backside;
int graphic_action = el_act_dir2img(element, action, direction);
int graphic_default = el_act_dir2img(element, ACTION_DEFAULT, direction);
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];
+ 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;
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;
- int direction = player_mapping[p][i].direction;
+ int element = em_player_mapping[p][i].element_rnd;
+ int action = em_player_mapping[p][i].action;
+ int direction = em_player_mapping[p][i].direction;
for (j = 0; j < 8; j++)
{
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,
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,
+static void CheckSaveEngineSnapshot_EM(int frame,
boolean any_player_moving,
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)
{
}
}
-void CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame,
- boolean any_player_moving,
- boolean any_player_snapping,
- boolean any_player_dropping)
+boolean CheckSingleStepMode_EM(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,
+ CheckSaveEngineSnapshot_EM(frame, any_player_moving,
any_player_snapping, any_player_dropping);
+
+ return tape.pausing;
}
void CheckSingleStepMode_SP(boolean murphy_is_waiting,
}
void getGraphicSource_SP(struct GraphicInfo_SP *g_sp,
- int graphic, int sync_frame, int x, int y)
+ int graphic, int sync_frame)
{
int frame = getGraphicAnimationFrame(graphic, sync_frame);
return graphic_info[graphic].anim_delay;
}
+boolean getGraphicInfo_NewFrame(int x, int y, int graphic)
+{
+ if (!IS_NEW_FRAME(GfxFrame[x][y], graphic))
+ return FALSE;
+
+ if (ANIM_MODE(graphic) & (ANIM_TILED | ANIM_RANDOM_STATIC))
+ return FALSE;
+
+ return TRUE;
+}
+
void PlayMenuSoundExt(int sound)
{
if (sound == SND_UNDEFINED)
#endif
}
-void ToggleFullscreenOrChangeWindowScalingIfNeeded(void)
+void ToggleAudioSampleRateIfNeeded(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);
+ int setup_audio_sample_rate = (setup.audio_sample_rate_44100 ? 44100 : 22050);
- if (change_window_scaling_percent && video.fullscreen_enabled)
+ // if setup and audio sample rate are already matching, nothing do do
+ if ((setup_audio_sample_rate == audio.sample_rate) ||
+ !audio.sound_available)
return;
- if (!change_window_scaling_percent && !video.fullscreen_available)
+#if 1
+ // apparently changing the audio output sample rate does not work at runtime,
+ // so currently the program has to be restarted to apply the new sample rate
+ Request("Please restart the program to change audio sample rate!", REQ_CONFIRM);
+#else
+ SDLReopenAudio();
+
+ // set setup value according to successfully changed audio sample rate
+ setup.audio_sample_rate_44100 = (audio.sample_rate == 44100);
+#endif
+}
+
+void ToggleFullscreenIfNeeded(void)
+{
+ // 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)
- {
- SDLSetWindowScaling(setup.window_scaling_percent);
+ SDLSetWindowFullscreen(setup.fullscreen);
+
+ // 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;
- }
- 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;
+
+ // when creating new renderer, destroy textures linked to old renderer
+ FreeAllImageTextures(); // needs old renderer to free the textures
- // toggle fullscreen
+ // re-create screen and renderer (including change of vsync mode)
ChangeVideoModeIfNeeded(setup.fullscreen);
// set setup value according to successfully changed fullscreen mode
// 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
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,
{
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;
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;
}
{
boolean use_mini_tilesize = (level.game_engine_type == GAME_ENGINE_TYPE_MM ?
FALSE : setup.small_game_graphics);
- int gfx_game_mode = game_status;
- int gfx_game_mode2 = (game_status == GAME_MODE_EDITOR ? GAME_MODE_DEFAULT :
- game_status);
+ int gfx_game_mode = getGlobalGameStatus(game_status);
+ int gfx_game_mode2 = (gfx_game_mode == GAME_MODE_EDITOR ? GAME_MODE_DEFAULT :
+ gfx_game_mode);
struct RectWithBorder *vp_window = &viewport.window[gfx_game_mode];
struct RectWithBorder *vp_playfield = &viewport.playfield[gfx_game_mode];
struct RectWithBorder *vp_door_1 = &viewport.door_1[gfx_game_mode];
boolean init_gfx_buffers = FALSE;
boolean init_video_buffer = FALSE;
boolean init_gadgets_and_anims = FALSE;
+ boolean init_bd_graphics = FALSE;
boolean init_em_graphics = FALSE;
if (new_win_xsize != WIN_XSIZE ||
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 ||
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 ||
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();
- // changing tile size requires update of graphic mapping for EM engine
+ // changing tile size requires update of graphic mapping for BD/EM engine
+ init_bd_graphics = TRUE;
init_em_graphics = TRUE;
}
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;
if (init_video_buffer)
{
- // printf("::: init_video_buffer\n");
+ // Debug("tools:viewport", "init_video_buffer");
FreeAllImageTextures(); // needs old renderer to free the textures
if (init_gadgets_and_anims)
{
- // printf("::: init_gadgets_and_anims\n");
+ // Debug("tools:viewport", "init_gadgets_and_anims");
InitGadgets();
InitGlobalAnimations();
}
+ if (init_bd_graphics)
+ {
+ InitGraphicInfo_BD();
+ }
+
if (init_em_graphics)
{
- InitGraphicInfo_EM();
+ InitGraphicInfo_EM();
+ }
+}
+
+void OpenURL(char *url)
+{
+#if SDL_VERSION_ATLEAST(2,0,14)
+ SDL_OpenURL(url);
+#else
+ Warn("SDL_OpenURL(\"%s\") not supported by SDL %d.%d.%d!",
+ url, SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL);
+ Warn("Please upgrade to at least SDL 2.0.14 for URL support!");
+#endif
+}
+
+void OpenURLFromHash(SetupFileHash *hash, int hash_key)
+{
+ OpenURL(getHashEntry(hash, int2str(hash_key, 0)));
+}
+
+char *getCurrentLevelsetName(void)
+{
+ return leveldir_current->name;
+}
+
+
+// ============================================================================
+// tests
+// ============================================================================
+
+#if defined(PLATFORM_WINDOWS)
+/* FILETIME of Jan 1 1970 00:00:00. */
+static const unsigned __int64 epoch = ((unsigned __int64) 116444736000000000ULL);
+
+/*
+ * timezone information is stored outside the kernel so tzp isn't used anymore.
+ *
+ * Note: this function is not for Win32 high precision timing purpose. See
+ * elapsed_time().
+ */
+static int gettimeofday_windows(struct timeval * tp, struct timezone * tzp)
+{
+ FILETIME file_time;
+ SYSTEMTIME system_time;
+ ULARGE_INTEGER ularge;
+
+ GetSystemTime(&system_time);
+ SystemTimeToFileTime(&system_time, &file_time);
+ ularge.LowPart = file_time.dwLowDateTime;
+ ularge.HighPart = file_time.dwHighDateTime;
+
+ tp->tv_sec = (long) ((ularge.QuadPart - epoch) / 10000000L);
+ tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
+
+ return 0;
+}
+#endif
+
+static char *test_init_uuid_random_function_simple(void)
+{
+ static char seed_text[100];
+ unsigned int seed = InitSimpleRandom(NEW_RANDOMIZE);
+
+ sprintf(seed_text, "%d", seed);
+
+ return seed_text;
+}
+
+static char *test_init_uuid_random_function_better(void)
+{
+ static char seed_text[100];
+ struct timeval current_time;
+
+ gettimeofday(¤t_time, NULL);
+
+ prng_seed_bytes(¤t_time, sizeof(current_time));
+
+ sprintf(seed_text, "%ld.%ld",
+ (long)current_time.tv_sec,
+ (long)current_time.tv_usec);
+
+ return seed_text;
+}
+
+#if defined(PLATFORM_WINDOWS)
+static char *test_init_uuid_random_function_better_windows(void)
+{
+ static char seed_text[100];
+ struct timeval current_time;
+
+ gettimeofday_windows(¤t_time, NULL);
+
+ prng_seed_bytes(¤t_time, sizeof(current_time));
+
+ sprintf(seed_text, "%ld.%ld",
+ (long)current_time.tv_sec,
+ (long)current_time.tv_usec);
+
+ return seed_text;
+}
+#endif
+
+static unsigned int test_uuid_random_function_simple(int max)
+{
+ return GetSimpleRandom(max);
+}
+
+static unsigned int test_uuid_random_function_better(int max)
+{
+ return (max > 0 ? prng_get_uint() % max : 0);
+}
+
+#if defined(PLATFORM_WINDOWS)
+#define NUM_UUID_TESTS 3
+#else
+#define NUM_UUID_TESTS 2
+#endif
+
+static void TestGeneratingUUIDs_RunTest(int nr, int always_seed, int num_uuids)
+{
+ HashTable *hash_seeds =
+ create_hashtable(get_hash_from_string, hash_key_strings_are_equal, free, NULL);
+ HashTable *hash_uuids =
+ create_hashtable(get_hash_from_string, hash_key_strings_are_equal, free, NULL);
+ static char message[100];
+ int i;
+
+ char *random_name = (nr == 0 ? "simple" : "better");
+ char *random_type = (always_seed ? "always" : "only once");
+ char *(*init_random_function)(void) =
+ (nr == 0 ?
+ test_init_uuid_random_function_simple :
+ test_init_uuid_random_function_better);
+ unsigned int (*random_function)(int) =
+ (nr == 0 ?
+ test_uuid_random_function_simple :
+ test_uuid_random_function_better);
+ int xpos = 40;
+
+#if defined(PLATFORM_WINDOWS)
+ if (nr == 2)
+ {
+ random_name = "windows";
+ init_random_function = test_init_uuid_random_function_better_windows;
+ }
+#endif
+
+ ClearField();
+
+ DrawTextF(xpos, 40, FC_GREEN, "Test: Generating UUIDs");
+ DrawTextF(xpos, 80, FC_YELLOW, "Test %d.%d:", nr + 1, always_seed + 1);
+
+ DrawTextF(xpos, 100, FC_YELLOW, "Random Generator Name: %s", random_name);
+ DrawTextF(xpos, 120, FC_YELLOW, "Seeding Random Generator: %s", random_type);
+ DrawTextF(xpos, 140, FC_YELLOW, "Number of UUIDs generated: %d", num_uuids);
+
+ DrawTextF(xpos, 180, FC_GREEN, "Please wait ...");
+
+ BackToFront();
+
+ // always initialize random number generator at least once
+ init_random_function();
+
+ unsigned int time_start = SDL_GetTicks();
+
+ for (i = 0; i < num_uuids; i++)
+ {
+ if (always_seed)
+ {
+ char *seed = getStringCopy(init_random_function());
+
+ hashtable_remove(hash_seeds, seed);
+ hashtable_insert(hash_seeds, seed, "1");
+ }
+
+ char *uuid = getStringCopy(getUUIDExt(random_function));
+
+ hashtable_remove(hash_uuids, uuid);
+ hashtable_insert(hash_uuids, uuid, "1");
}
+
+ int num_unique_seeds = hashtable_count(hash_seeds);
+ int num_unique_uuids = hashtable_count(hash_uuids);
+
+ unsigned int time_needed = SDL_GetTicks() - time_start;
+
+ DrawTextF(xpos, 220, FC_YELLOW, "Time needed: %d ms", time_needed);
+
+ DrawTextF(xpos, 240, FC_YELLOW, "Number of unique UUIDs: %d", num_unique_uuids);
+
+ if (always_seed)
+ DrawTextF(xpos, 260, FC_YELLOW, "Number of unique seeds: %d", num_unique_seeds);
+
+ if (nr == NUM_UUID_TESTS - 1 && always_seed)
+ DrawTextF(xpos, 300, FC_GREEN, "All tests done!");
+ else
+ DrawTextF(xpos, 300, FC_GREEN, "Confirm dialog for next test ...");
+
+ sprintf(message, "Test %d.%d finished!", nr + 1, always_seed + 1);
+
+ Request(message, REQ_CONFIRM);
+
+ hashtable_destroy(hash_seeds);
+ hashtable_destroy(hash_uuids);
+}
+
+void TestGeneratingUUIDs(void)
+{
+ int num_uuids = 1000000;
+ int i, j;
+
+ for (i = 0; i < NUM_UUID_TESTS; i++)
+ for (j = 0; j < 2; j++)
+ TestGeneratingUUIDs_RunTest(i, j, num_uuids);
+
+ CloseAllAndExit(0);
}