// (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 */
+// tool button identifiers
#define TOOL_CTRL_ID_YES 0
#define TOOL_CTRL_ID_NO 1
#define TOOL_CTRL_ID_CONFIRM 2
#define TOOL_CTRL_ID_PLAYER_2 4
#define TOOL_CTRL_ID_PLAYER_3 5
#define TOOL_CTRL_ID_PLAYER_4 6
+#define TOOL_CTRL_ID_TOUCH_YES 7
+#define TOOL_CTRL_ID_TOUCH_NO 8
+#define TOOL_CTRL_ID_TOUCH_CONFIRM 9
-#define NUM_TOOL_BUTTONS 7
+#define NUM_TOOL_BUTTONS 10
-/* constants for number of doors and door parts */
+// constants for number of doors and door parts
#define NUM_DOORS 2
#define NUM_PANELS NUM_DOORS
// #define NUM_PANELS 0
};
-/* forward declaration for internal use */
-static void UnmapToolButtons();
+// forward declaration for internal use
+static void UnmapToolButtons(void);
static void HandleToolButtons(struct GadgetInfo *);
static int el_act_dir2crm(int, int, int);
static int el_act2crm(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()
+int getFieldbufferOffsetX_RND(int dir, int pos)
{
int full_lev_fieldx = lev_fieldx + (BorderElement != EL_EMPTY ? 2 : 0);
- int dx = (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
+ int dx = (dir & MV_HORIZONTAL ? pos : 0);
int dx_var = dx * TILESIZE_VAR / TILESIZE;
int fx = FX;
if (EVEN(SCR_FIELDX))
{
- int ffx = (scroll_x - SBX_Left) * TILEX_VAR + dx_var;
+ int sbx_right = SBX_Right + (BorderElement != EL_EMPTY ? 1 : 0);
+ int ffx = (scroll_x - SBX_Left) * TILEX_VAR + dx_var;
- if (ffx < SBX_Right * TILEX_VAR + TILEX_VAR / 2 + TILEX_VAR)
+ if (ffx < sbx_right * TILEX_VAR + TILEX_VAR / 2)
fx += dx_var - MIN(ffx, TILEX_VAR / 2) + TILEX_VAR;
else
fx += (dx_var > 0 ? TILEX_VAR : 0);
return fx;
}
-static int getFieldbufferOffsetY_RND()
+int getFieldbufferOffsetY_RND(int dir, int pos)
{
int full_lev_fieldy = lev_fieldy + (BorderElement != EL_EMPTY ? 2 : 0);
- int dy = (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0);
+ int dy = (dir & MV_VERTICAL ? pos : 0);
int dy_var = dy * TILESIZE_VAR / TILESIZE;
int fy = FY;
if (EVEN(SCR_FIELDY))
{
+ int sby_lower = SBY_Lower + (BorderElement != EL_EMPTY ? 1 : 0);
int ffy = (scroll_y - SBY_Upper) * TILEY_VAR + dy_var;
- if (ffy < SBY_Lower * TILEY_VAR + TILEY_VAR / 2 + TILEY_VAR)
+ if (ffy < sby_lower * TILEY_VAR + TILEY_VAR / 2)
fy += dy_var - MIN(ffy, TILEY_VAR / 2) + TILEY_VAR;
else
fy += (dy_var > 0 ? TILEY_VAR : 0);
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;
}
static int getLevelFromScreenX_MM(int sx)
{
-#if 0
int level_xsize = level.native_mm_level->fieldx;
int full_xsize = level_xsize * TILESIZE_VAR;
sx -= (full_xsize < SXSIZE ? (SXSIZE - full_xsize) / 2 : 0);
-#endif
int px = sx - SX;
- int lx = px / TILESIZE_VAR;
+ int lx = (px + TILESIZE_VAR) / TILESIZE_VAR - 1;
return lx;
}
static int getLevelFromScreenY_MM(int sy)
{
-#if 0
int level_ysize = level.native_mm_level->fieldy;
int full_ysize = level_ysize * TILESIZE_VAR;
sy -= (full_ysize < SYSIZE ? (SYSIZE - full_ysize) / 2 : 0);
-#endif
int py = sy - SY;
- int ly = py / TILESIZE_VAR;
+ int ly = (py + TILESIZE_VAR) / TILESIZE_VAR - 1;
return ly;
}
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)
drawto_field = fieldbuffer;
}
- else /* DRAW_TO_BACKBUFFER */
+ else // DRAW_TO_BACKBUFFER
{
FX = SX;
FY = SY;
}
}
-static void RedrawPlayfield_RND()
+int GetDrawtoField(void)
+{
+ return (drawto_field == fieldbuffer ? DRAW_TO_FIELDBUFFER : DRAW_TO_BACKBUFFER);
+}
+
+static void RedrawPlayfield_RND(void)
{
if (game.envelope_active)
return;
DrawAllPlayers();
}
-void RedrawPlayfield()
+void RedrawPlayfield(void)
{
if (game_status != GAME_MODE_PLAYING)
return;
static void DrawMaskedBorderExt_DOOR_3(int draw_target)
{
- /* currently not available */
+ // currently not available
}
static void DrawMaskedBorderExt_ALL(int draw_target)
static void DrawMaskedBorderExt(int redraw_mask, int draw_target)
{
- /* never draw masked screen borders on borderless screens */
+ // never draw masked screen borders on borderless screens
if (global.border_status == GAME_MODE_LOADING ||
global.border_status == GAME_MODE_TITLE)
return;
}
}
-void DrawMaskedBorder_FIELD()
+void DrawMaskedBorder_FIELD(void)
{
DrawMaskedBorderExt_FIELD(DRAW_TO_BACKBUFFER);
}
}
}
-void BlitScreenToBitmap_RND(Bitmap *target_bitmap)
+void DrawTileCursor(int draw_target)
{
- int fx = getFieldbufferOffsetX_RND();
- int fy = getFieldbufferOffsetY_RND();
+ DrawTileCursor_MM(draw_target, game_status == GAME_MODE_PLAYING);
+}
+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(ScreenMovDir, ScreenGfxPos);
+ int fy = getFieldbufferOffsetY_RND(ScreenMovDir, ScreenGfxPos);
+
+ BlitScreenToBitmapExt_RND(target_bitmap, fx, fy);
+}
+
void BlitScreenToBitmap(Bitmap *target_bitmap)
{
if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
redraw_mask |= REDRAW_FIELD;
}
-void DrawFramesPerSecond()
+static void DrawFramesPerSecond(void)
{
char text[100];
int font_nr = FONT_TEXT_2;
int draw_deactivation_mask = GetDrawDeactivationMask();
boolean draw_masked = (draw_deactivation_mask == REDRAW_NONE);
- /* draw FPS with leading space (needed if field buffer deactivated) */
+ // draw FPS with leading space (needed if field buffer deactivated)
sprintf(text, " %04.1f fps", global.frames_per_second);
- /* override draw deactivation mask (required for invisible warp mode) */
+ // override draw deactivation mask (required for invisible warp mode)
SetDrawDeactivationMask(REDRAW_NONE);
- /* draw opaque FPS if field buffer deactivated, else draw masked FPS */
+ // draw opaque FPS if field buffer deactivated, else draw masked FPS
DrawTextExt(backbuffer, SX + SXSIZE - font_width * strlen(text), SY, text,
font_nr, (draw_masked ? BLIT_MASKED : BLIT_OPAQUE));
- /* set draw deactivation mask to previous value */
+ // set draw deactivation mask to previous value
SetDrawDeactivationMask(draw_deactivation_mask);
- /* force full-screen redraw in this frame */
+ // force full-screen redraw in this frame
redraw_mask = REDRAW_ALL;
}
#if DEBUG_FRAME_TIME
-static void PrintFrameTimeDebugging()
+static void PrintFrameTimeDebugging(void)
{
static unsigned int last_counter = 0;
unsigned int counter = Counter();
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),
return unifiedRedrawMask(mask_1) == unifiedRedrawMask(mask_2);
}
-void BackToFront()
+void BackToFront(void)
{
static int last_redraw_mask = REDRAW_NONE;
{
if (fade_type_skip != FADE_TYPE_NONE)
{
- /* skip all fade operations until specified fade operation */
+ // skip all fade operations until specified fade operation
if (fade_type & fade_type_skip)
fade_type_skip = FADE_TYPE_NONE;
if (fade_type_skip != FADE_TYPE_NONE)
{
- /* skip all fade operations until specified fade operation */
+ // skip all fade operations until specified fade operation
if (fade_type & fade_type_skip)
fade_type_skip = FADE_TYPE_NONE;
height = FADE_SYSIZE;
if (border.draw_masked_when_fading)
- draw_border_function = DrawMaskedBorder_FIELD; /* update when fading */
+ draw_border_function = DrawMaskedBorder_FIELD; // update when fading
else
- DrawMaskedBorder_FIELD(); /* draw once */
+ DrawMaskedBorder_FIELD(); // draw once
}
- else /* REDRAW_ALL */
+ else // REDRAW_ALL
{
x = 0;
y = 0;
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);
redraw_mask &= ~fade_mask;
+
+ ClearAutoRepeatKeyEvents();
}
-static void SetScreenStates_BeforeFadingIn()
+static void SetScreenStates_BeforeFadingIn(void)
{
// temporarily set screen mode for animations to screen after fading in
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;
}
-static void SetScreenStates_AfterFadingIn()
+static void SetScreenStates_AfterFadingIn(void)
{
// store new source screen (to use correct masked border for fading)
gfx.fade_border_source_status = global.border_status;
global.anim_status = global.anim_status_next;
}
-static void SetScreenStates_BeforeFadingOut()
+static void SetScreenStates_BeforeFadingOut(void)
{
// store new target screen (to use correct masked border for fading)
gfx.fade_border_target_status = game_status;
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()
+static void SetScreenStates_AfterFadingOut(void)
{
global.border_status = game_status;
}
FADE_SXSIZE = FULL_SXSIZE;
FADE_SYSIZE = FULL_SYSIZE;
- if (game_status == GAME_MODE_PLAYING &&
- strEqual(setup.touch.control_type, TOUCH_CONTROL_VIRTUAL_BUTTONS))
+ // activate virtual buttons depending on upcoming game status
+ if (strEqual(setup.touch.control_type, TOUCH_CONTROL_VIRTUAL_BUTTONS) &&
+ game_status == GAME_MODE_PLAYING && !tape.playing)
SetOverlayActive(TRUE);
SetScreenStates_AfterFadingIn();
void FadeOut(int fade_mask)
{
// update screen if areas covered by "fade_mask" and "redraw_mask" differ
- if (!equalRedrawMasks(fade_mask, redraw_mask))
+ if (!equalRedrawMasks(fade_mask, redraw_mask) &&
+ fade_type_skip != FADE_MODE_SKIP_FADE_OUT)
BackToFront();
SetScreenStates_BeforeFadingOut();
+ SetTileCursorActive(FALSE);
SetOverlayActive(FALSE);
#if 0
fading = fading_leave_stored;
}
-void FadeSetEnterMenu()
+void FadeSetEnterMenu(void)
{
fading = menu.enter_menu;
- FadeSetLeaveNext(fading, TRUE); /* (keep same fade mode) */
+ FadeSetLeaveNext(fading, TRUE); // (keep same fade mode)
}
-void FadeSetLeaveMenu()
+void FadeSetLeaveMenu(void)
{
fading = menu.leave_menu;
- FadeSetLeaveNext(fading, TRUE); /* (keep same fade mode) */
+ FadeSetLeaveNext(fading, TRUE); // (keep same fade mode)
}
-void FadeSetEnterScreen()
+void FadeSetEnterScreen(void)
{
fading = menu.enter_screen[game_status];
- FadeSetLeaveNext(menu.leave_screen[game_status], TRUE); /* store */
+ FadeSetLeaveNext(menu.leave_screen[game_status], TRUE); // store
}
-void FadeSetNextScreen()
+void FadeSetNextScreen(void)
{
fading = menu.next_screen[game_status];
// (do not overwrite fade mode set by FadeSetEnterScreen)
- // FadeSetLeaveNext(fading, TRUE); /* (keep same fade mode) */
+ // FadeSetLeaveNext(fading, TRUE); // (keep same fade mode)
}
-void FadeSetLeaveScreen()
+void FadeSetLeaveScreen(void)
{
- FadeSetLeaveNext(menu.leave_screen[game_status], FALSE); /* recall */
+ FadeSetLeaveNext(menu.leave_screen[game_status], FALSE); // recall
}
void FadeSetFromType(int type)
FadeSetLeaveMenu();
}
-void FadeSetDisabled()
+void FadeSetDisabled(void)
{
static struct TitleFadingInfo fading_none = { FADE_MODE_NONE, -1, -1, -1 };
fading = fading_none;
}
-void FadeSkipNextFadeIn()
+void FadeSkipNextFadeIn(void)
{
FadeExt(0, FADE_MODE_SKIP_FADE_IN, FADE_TYPE_SKIP);
}
-void FadeSkipNextFadeOut()
+void FadeSkipNextFadeOut(void)
{
FadeExt(0, FADE_MODE_SKIP_FADE_OUT, FADE_TYPE_SKIP);
}
-Bitmap *getBitmapFromGraphicOrDefault(int graphic, int default_graphic)
+static Bitmap *getBitmapFromGraphicOrDefault(int graphic, int default_graphic)
{
+ if (graphic == IMG_UNDEFINED)
+ return NULL;
+
boolean redefined = getImageListEntryFromImageID(graphic)->redefined;
- return (graphic == IMG_UNDEFINED ? NULL :
- graphic_info[graphic].bitmap != NULL || redefined ?
+ return (graphic_info[graphic].bitmap != NULL || redefined ?
graphic_info[graphic].bitmap :
graphic_info[default_graphic].bitmap);
}
-Bitmap *getBackgroundBitmap(int graphic)
+static Bitmap *getBackgroundBitmap(int graphic)
{
return getBitmapFromGraphicOrDefault(graphic, IMG_BACKGROUND);
}
-Bitmap *getGlobalBorderBitmap(int graphic)
+static Bitmap *getGlobalBorderBitmap(int graphic)
{
return getBitmapFromGraphicOrDefault(graphic, IMG_GLOBAL_BORDER);
}
SetDoorBackgroundBitmap(getBackgroundBitmap(graphic));
}
-void SetPanelBackground()
+void SetPanelBackground(void)
{
struct GraphicInfo *gfx = &graphic_info[IMG_BACKGROUND_PANEL];
void DrawBackground(int x, int y, int width, int height)
{
- /* "drawto" might still point to playfield buffer here (hall of fame) */
+ // "drawto" might still point to playfield buffer here (hall of fame)
ClearRectangleOnBackground(backbuffer, x, y, width, height);
if (IN_GFX_FIELD_FULL(x, y))
static int dxsize_last = -1, dysize_last = -1;
static int vx_last = -1, vy_last = -1;
static int vxsize_last = -1, vysize_last = -1;
+static int ex_last = -1, ey_last = -1;
+static int exsize_last = -1, eysize_last = -1;
-boolean CheckIfGlobalBorderHasChanged()
+boolean CheckIfGlobalBorderHasChanged(void)
{
// if game status has not changed, global border has not changed either
if (game_status == game_status_last)
return (global_border_bitmap_last != global_border_bitmap);
}
-boolean CheckIfGlobalBorderRedrawIsNeeded()
+#define ONLY_REDRAW_GLOBAL_BORDER_IF_NEEDED 0
+
+#if ONLY_REDRAW_GLOBAL_BORDER_IF_NEEDED
+static boolean CheckIfGlobalBorderRedrawIsNeeded(void)
{
// if game status has not changed, nothing has to be redrawn
if (game_status == game_status_last)
vxsize_last != VXSIZE || vysize_last != VYSIZE)
return TRUE;
+ // redraw if position or size of editor area has changed
+ if (ex_last != EX || ey_last != EY ||
+ exsize_last != EXSIZE || eysize_last != EYSIZE)
+ return TRUE;
+
return FALSE;
}
+#endif
-void RedrawGlobalBorderFromBitmap(Bitmap *bitmap)
+static void RedrawGlobalBorderFromBitmap(Bitmap *bitmap)
{
if (bitmap)
BlitBitmap(bitmap, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
ClearRectangle(backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE);
}
-void RedrawGlobalBorder()
+void RedrawGlobalBorder(void)
{
Bitmap *bitmap = getGlobalBorderBitmapFromStatus(game_status);
redraw_mask = REDRAW_ALL;
}
-static void RedrawGlobalBorderIfNeeded()
+static void RedrawGlobalBorderIfNeeded(void)
{
+#if ONLY_REDRAW_GLOBAL_BORDER_IF_NEEDED
if (game_status == game_status_last)
return;
+#endif
// copy current draw buffer to later copy back areas that have not changed
if (game_status_last != GAME_MODE_TITLE)
BlitBitmap(backbuffer, bitmap_db_store_1, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+#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)
RedrawGlobalBorderFromBitmap(global_border_bitmap);
+ if (game_status == GAME_MODE_EDITOR)
+ DrawSpecialEditorDoor();
+
// copy previous playfield and door areas, if they are defined on both
// previous and current screen and if they still have the same size
BlitBitmap(bitmap_db_store_1, backbuffer,
dx_last, dy_last, DXSIZE, DYSIZE, DX, DY);
- if (vx_last != -1 && vy_last != -1 &&
- VX != -1 && VY != -1 &&
- vxsize_last == VXSIZE && vysize_last == VYSIZE)
- BlitBitmap(bitmap_db_store_1, backbuffer,
- vx_last, vy_last, VXSIZE, VYSIZE, VX, VY);
+ if (game_status != GAME_MODE_EDITOR)
+ {
+ if (vx_last != -1 && vy_last != -1 &&
+ VX != -1 && VY != -1 &&
+ vxsize_last == VXSIZE && vysize_last == VYSIZE)
+ BlitBitmap(bitmap_db_store_1, backbuffer,
+ vx_last, vy_last, VXSIZE, VYSIZE, VX, VY);
+ }
+ else
+ {
+ if (ex_last != -1 && ey_last != -1 &&
+ EX != -1 && EY != -1 &&
+ exsize_last == EXSIZE && eysize_last == EYSIZE)
+ BlitBitmap(bitmap_db_store_1, backbuffer,
+ ex_last, ey_last, EXSIZE, EYSIZE, EX, EY);
+ }
redraw_mask = REDRAW_ALL;
}
vy_last = VY;
vxsize_last = VXSIZE;
vysize_last = VYSIZE;
+ ex_last = EX;
+ ey_last = EY;
+ exsize_last = EXSIZE;
+ eysize_last = EYSIZE;
}
-void ClearField()
+void ClearField(void)
{
RedrawGlobalBorderIfNeeded();
- /* !!! "drawto" might still point to playfield buffer here (see above) !!! */
- /* (when entering hall of fame after playing) */
+ // !!! "drawto" might still point to playfield buffer here (see above) !!!
+ // (when entering hall of fame after playing)
DrawBackground(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
- /* !!! maybe this should be done before clearing the background !!! */
+ // !!! maybe this should be done before clearing the background !!!
if (game_status == GAME_MODE_PLAYING)
{
ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE);
redraw_mask |= REDRAW_FIELD;
}
-void SetBorderElement()
+void SetBorderElement(void)
{
int x, y;
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)
static int check[4][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } };
static int safety = 0;
- /* check if starting field still has the desired content */
+ // check if starting field still has the desired content
if (field[from_x][from_y] == fill_element)
return;
safety++;
if (safety > max_fieldx * max_fieldy)
- Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug.");
+ Fail("Something went wrong in 'FloodFill()'. Please debug.");
old_element = field[from_x][from_y];
field[from_x][from_y] = fill_element;
int getGraphicAnimationFrame(int graphic, int sync_frame)
{
- /* animation synchronized with global frame counter, not move position */
+ // animation synchronized with global frame counter, not move position
if (graphic_info[graphic].anim_global_sync || sync_frame < 0)
sync_frame = FrameCounter;
int src_x = g->src_x + (get_backside ? g->offset2_x : 0);
int src_y = g->src_y + (get_backside ? g->offset2_y : 0);
- if (g->offset_y == 0) /* frames are ordered horizontally */
+ if (g->offset_y == 0) // frames are ordered horizontally
{
int max_width = g->anim_frames_per_line * g->width;
int pos = (src_y / g->height) * max_width + src_x + frame * g->offset_x;
*x = pos % max_width;
*y = src_y % g->height + pos / max_width * g->height;
}
- else if (g->offset_x == 0) /* frames are ordered vertically */
+ else if (g->offset_x == 0) // frames are ordered vertically
{
int max_height = g->anim_frames_per_line * g->height;
int pos = (src_x / g->width) * max_height + src_y + frame * g->offset_y;
*x = src_x % g->width + pos / max_height * g->width;
*y = pos % max_height;
}
- else /* frames are ordered diagonally */
+ else // frames are ordered diagonally
{
*x = src_x + frame * g->offset_x;
*y = src_y + frame * g->offset_y;
{
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];
+
// if no in-game graphics defined, always use standard graphic size
if (g->bitmaps[IMG_BITMAP_GAME] == NULL)
tilesize = TILESIZE;
getSizedGraphicSource(graphic, 0, MINI_TILESIZE, bitmap, x, y);
}
-inline static void getGraphicSourceExt(int graphic, int frame, Bitmap **bitmap,
- int *x, int *y, boolean get_backside)
+static void getGraphicSourceExt(int graphic, int frame, Bitmap **bitmap,
+ int *x, int *y, boolean get_backside)
{
getSizedGraphicSourceExt(graphic, frame, TILESIZE_VAR, bitmap, x, y,
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
BlitBitmap(src_bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
}
-inline static void DrawGraphicShiftedNormal(int x, int y, int dx, int dy,
- int graphic, int frame,
- int cut_mode, int mask_mode)
+static void DrawGraphicShiftedNormal(int x, int y, int dx, int dy,
+ int graphic, int frame,
+ int cut_mode, int mask_mode)
{
Bitmap *src_bitmap;
int src_x, src_y;
int width = TILEX, height = TILEY;
int cx = 0, cy = 0;
- if (dx || dy) /* shifted graphic */
+ if (dx || dy) // shifted graphic
{
- if (x < BX1) /* object enters playfield from the left */
+ if (x < BX1) // object enters playfield from the left
{
x = BX1;
width = dx;
cx = TILEX - dx;
dx = 0;
}
- else if (x > BX2) /* object enters playfield from the right */
+ else if (x > BX2) // object enters playfield from the right
{
x = BX2;
width = -dx;
dx = TILEX + dx;
}
- else if (x == BX1 && dx < 0) /* object leaves playfield to the left */
+ else if (x == BX1 && dx < 0) // object leaves playfield to the left
{
width += dx;
cx = -dx;
dx = 0;
}
- else if (x == BX2 && dx > 0) /* object leaves playfield to the right */
+ else if (x == BX2 && dx > 0) // object leaves playfield to the right
width -= dx;
- else if (dx) /* general horizontal movement */
+ else if (dx) // general horizontal movement
MarkTileDirty(x + SIGN(dx), y);
- if (y < BY1) /* object enters playfield from the top */
+ if (y < BY1) // object enters playfield from the top
{
- if (cut_mode == CUT_BELOW) /* object completely above top border */
+ if (cut_mode == CUT_BELOW) // object completely above top border
return;
y = BY1;
cy = TILEY - dy;
dy = 0;
}
- else if (y > BY2) /* object enters playfield from the bottom */
+ else if (y > BY2) // object enters playfield from the bottom
{
y = BY2;
height = -dy;
dy = TILEY + dy;
}
- else if (y == BY1 && dy < 0) /* object leaves playfield to the top */
+ else if (y == BY1 && dy < 0) // object leaves playfield to the top
{
height += dy;
cy = -dy;
}
else if (dy > 0 && cut_mode == CUT_ABOVE)
{
- if (y == BY2) /* object completely above bottom border */
+ if (y == BY2) // object completely above bottom border
return;
height = dy;
cy = TILEY - dy;
dy = TILEY;
MarkTileDirty(x, y + 1);
- } /* object leaves playfield to the bottom */
+ } // object leaves playfield to the bottom
else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
height -= dy;
- else if (dy) /* general vertical movement */
+ else if (dy) // general vertical movement
MarkTileDirty(x, y + SIGN(dy));
}
#if DEBUG
if (!IN_SCR_FIELD(x, y))
{
- printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
- printf("DrawGraphicShifted(): This should never happen!\n");
+ Debug("draw:DrawGraphicShiftedNormal", "x = %d, y = %d, graphic = %d",
+ x, y, graphic);
+ Debug("draw:DrawGraphicShiftedNormal", "This should never happen!");
+
return;
}
#endif
}
}
-inline static void DrawGraphicShiftedDouble(int x, int y, int dx, int dy,
- int graphic, int frame,
- int cut_mode, int mask_mode)
+static void DrawGraphicShiftedDouble(int x, int y, int dx, int dy,
+ int graphic, int frame,
+ int cut_mode, int mask_mode)
{
Bitmap *src_bitmap;
int src_x, src_y;
int x2 = x + SIGN(dx);
int y2 = y + SIGN(dy);
- /* movement with two-tile animations must be sync'ed with movement position,
- not with current GfxFrame (which can be higher when using slow movement) */
+ // movement with two-tile animations must be sync'ed with movement position,
+ // not with current GfxFrame (which can be higher when using slow movement)
int anim_pos = (dx ? ABS(dx) : ABS(dy));
int anim_frames = graphic_info[graphic].anim_frames;
- /* (we also need anim_delay here for movement animations with less frames) */
+ // (we also need anim_delay here for movement animations with less frames)
int anim_delay = graphic_info[graphic].anim_delay;
int sync_frame = anim_pos * anim_frames * anim_delay / TILESIZE;
- boolean draw_start_tile = (cut_mode != CUT_ABOVE); /* only for falling! */
- boolean draw_end_tile = (cut_mode != CUT_BELOW); /* only for falling! */
+ boolean draw_start_tile = (cut_mode != CUT_ABOVE); // only for falling!
+ boolean draw_end_tile = (cut_mode != CUT_BELOW); // only for falling!
- /* re-calculate animation frame for two-tile movement animation */
+ // re-calculate animation frame for two-tile movement animation
frame = getGraphicAnimationFrame(graphic, sync_frame);
- /* check if movement start graphic inside screen area and should be drawn */
+ // check if movement start graphic inside screen area and should be drawn
if (draw_start_tile && IN_SCR_FIELD(x1, y1))
{
getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y, TRUE);
MarkTileDirty(x1, y1);
}
- /* check if movement end graphic inside screen area and should be drawn */
+ // check if movement end graphic inside screen area and should be drawn
if (draw_end_tile && IN_SCR_FIELD(x2, y2))
{
getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y, FALSE);
return;
}
- if (graphic_info[graphic].double_movement) /* EM style movement images */
+ if (graphic_info[graphic].double_movement) // EM style movement images
DrawGraphicShiftedDouble(x, y, dx, dy, graphic, frame, cut_mode,mask_mode);
else
DrawGraphicShiftedNormal(x, y, dx, dy, graphic, frame, cut_mode,mask_mode);
}
-void DrawGraphicShiftedThruMask(int x, int y, int dx, int dy, int graphic,
- int frame, int cut_mode)
+static void DrawGraphicShiftedThruMask(int x, int y, int dx, int dy,
+ int graphic, int frame, int cut_mode)
{
DrawGraphicShifted(x, y, dx, dy, graphic, frame, cut_mode, USE_MASKING);
}
graphic = el_act_dir2img(element, GfxAction[lx][ly], GfxDir[lx][ly]);
frame = getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]);
- /* do not use double (EM style) movement graphic when not moving */
+ // do not use double (EM style) movement graphic when not moving
if (graphic_info[graphic].double_movement && !dx && !dy)
{
graphic = el_act_dir2img(element, ACTION_DEFAULT, GfxDir[lx][ly]);
frame = getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]);
}
}
- else /* border element */
+ else // border element
{
graphic = el2img(element);
frame = getGraphicAnimationFrame(graphic, -1);
{
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 !!! */
+// !!! implementation of quicksand is totally broken !!!
#define IS_CRUMBLED_TILE(x, y, e) \
(GFX_CRUMBLED(e) && (!IN_LEV_FIELD(x, y) || \
!IS_MOVING(x, y) || \
int element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) :
BorderElement);
- /* check if neighbour field is of same crumble type */
+ // check if neighbour field is of same crumble type
boolean same = (IS_CRUMBLED_TILE(xx, yy, element) &&
graphic_info[graphic].class ==
graphic_info[el_act2crm(element, ACTION_DEFAULT)].class);
- /* return if check prevents inner corner */
+ // return if check prevents inner corner
if (same == (dxx == dx && dyy == dy))
return;
}
- /* if we reach this point, we have an inner corner */
+ // if we reach this point, we have an inner corner
getGraphicSource(graphic, 1, &src_bitmap, &src_x, &src_y);
getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
- /* draw simple, sloppy, non-corner-accurate crumbled border */
+ // draw simple, sloppy, non-corner-accurate crumbled border
width = (dir == 1 || dir == 2 ? crumbled_border_size_var : TILESIZE_VAR);
height = (dir == 0 || dir == 3 ? crumbled_border_size_var : TILESIZE_VAR);
FX + sx * TILEX_VAR + cx,
FY + sy * TILEY_VAR + cy);
- /* (remaining middle border part must be at least as big as corner part) */
+ // (remaining middle border part must be at least as big as corner part)
if (!(graphic_info[graphic].style & STYLE_ACCURATE_BORDERS) ||
crumbled_border_size_var >= TILESIZE_VAR / 3)
return;
- /* correct corners of crumbled border, if needed */
+ // correct corners of crumbled border, if needed
for (i = -1; i <= 1; i += 2)
{
int element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) :
BorderElement);
- /* check if neighbour field is of same crumble type */
+ // check if neighbour field is of same crumble type
if (IS_CRUMBLED_TILE(xx, yy, element) &&
graphic_info[graphic].class ==
graphic_info[el_act2crm(element, ACTION_DEFAULT)].class)
{
- /* no crumbled corner, but continued crumbled border */
+ // no crumbled corner, but continued crumbled border
int c1 = (dir == 2 || dir == 3 ? crumbled_border_pos_var : 0);
int c2 = (i == 1 ? crumbled_border_pos_var : 0);
element = TILE_GFX_ELEMENT(x, y);
- if (IS_CRUMBLED_TILE(x, y, element)) /* crumble field itself */
+ if (IS_CRUMBLED_TILE(x, y, element)) // crumble field itself
{
if (!IN_SCR_FIELD(sx, sy))
return;
- /* crumble field borders towards direct neighbour fields */
+ // crumble field borders towards direct neighbour fields
for (i = 0; i < 4; i++)
{
int xx = x + xy[i][0];
element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) :
BorderElement);
- /* check if neighbour field is of same crumble type */
+ // check if neighbour field is of same crumble type
if (IS_CRUMBLED_TILE(xx, yy, element) &&
graphic_info[graphic].class ==
graphic_info[el_act2crm(element, ACTION_DEFAULT)].class)
DrawLevelFieldCrumbledBorders(x, y, graphic, frame, i);
}
- /* crumble inner field corners towards corner neighbour fields */
+ // crumble inner field corners towards corner neighbour fields
if ((graphic_info[graphic].style & STYLE_INNER_CORNERS) &&
graphic_info[graphic].anim_frames == 2)
{
MarkTileDirty(sx, sy);
}
- else /* center field is not crumbled -- crumble neighbour fields */
+ else // center field is not crumbled -- crumble neighbour fields
{
- /* crumble field borders of direct neighbour fields */
+ // crumble field borders of direct neighbour fields
for (i = 0; i < 4; i++)
{
int xx = x + xy[i][0];
!IN_SCR_FIELD(sxx, syy))
continue;
- if (Feld[xx][yy] == EL_ELEMENT_SNAPPING)
+ // do not crumble fields that are being digged or snapped
+ if (Tile[xx][yy] == EL_EMPTY ||
+ Tile[xx][yy] == EL_ELEMENT_SNAPPING)
continue;
element = TILE_GFX_ELEMENT(xx, yy);
MarkTileDirty(sxx, syy);
}
- /* crumble inner field corners of corner neighbour fields */
+ // crumble inner field corners of corner neighbour fields
for (i = 0; i < 4; i++)
{
int dx = (i & 1 ? +1 : -1);
!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 i;
- /* crumble direct neighbour fields (required for field borders) */
+ // crumble direct neighbour fields (required for field borders)
for (i = 0; i < 4; i++)
{
int xx = x + xy[i][0];
if (!IN_LEV_FIELD(xx, yy) ||
!IN_SCR_FIELD(sxx, syy) ||
- !GFX_CRUMBLED(Feld[xx][yy]) ||
+ !GFX_CRUMBLED(Tile[xx][yy]) ||
IS_MOVING(xx, yy))
continue;
DrawLevelField(xx, yy);
}
- /* crumble corner neighbour fields (required for inner field corners) */
+ // crumble corner neighbour fields (required for inner field corners)
for (i = 0; i < 4; i++)
{
int dx = (i & 1 ? +1 : -1);
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;
}
- element = Feld[lx][ly];
+ element = Tile[lx][ly];
content = Store[lx][ly];
if (IS_MOVING(lx, ly))
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 ||
element, tilesize, el2edimg, masked, element_bits_draw);
}
-void DrawSizedWall_MM(int dst_x, int dst_y, int element, int tilesize,
- int (*el2img_function)(int))
+static void DrawSizedWall_MM(int dst_x, int dst_y, int element, int tilesize,
+ int (*el2img_function)(int))
{
DrawSizedWallExt_MM(dst_x, dst_y, element, tilesize, el2img_function, FALSE,
0x000f);
}
-void DrawSizedElementExt(int x, int y, int element, int tilesize,
- boolean masked)
+static void DrawSizedElementExt(int x, int y, int element, int tilesize,
+ boolean masked)
{
if (IS_MM_WALL(element))
{
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)));
}
-void DrawEnvelopeBackgroundTiles(int graphic, int startx, int starty,
- int x, int y, int xsize, int ysize,
- int tile_width, int tile_height)
+static void DrawEnvelopeBackgroundTiles(int graphic, int startx, int starty,
+ int x, int y, int xsize, int ysize,
+ int tile_width, int tile_height)
{
Bitmap *src_bitmap;
int src_x, src_y;
dst_x, dst_y);
}
-void DrawEnvelopeBackground(int graphic, int startx, int starty,
- int x, int y, int xsize, int ysize, int font_nr)
+static void DrawEnvelopeBackground(int graphic, int startx, int starty,
+ int x, int y, int xsize, int ysize,
+ int font_nr)
{
int font_width = getFontWidth(font_nr);
int font_height = getFontHeight(font_nr);
font_width, font_height);
}
-void AnimateEnvelope(int envelope_nr, int anim_mode, int action)
+static void AnimateEnvelope(int envelope_nr, int anim_mode, int action)
{
int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr;
Bitmap *src_bitmap = graphic_info[graphic].bitmap;
SkipUntilDelayReached(&anim_delay, anim_delay_value, &i, last_frame);
}
+
+ ClearAutoRepeatKeyEvents();
}
void ShowEnvelope(int envelope_nr)
int anim_mode = graphic_info[graphic].anim_mode;
int main_anim_mode = (anim_mode == ANIM_NONE ? ANIM_VERTICAL|ANIM_HORIZONTAL:
anim_mode == ANIM_DEFAULT ? ANIM_VERTICAL : anim_mode);
+ boolean overlay_enabled = GetOverlayEnabled();
+
+ game.envelope_active = TRUE; // needed for RedrawPlayfield() events
- game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */
+ SetOverlayEnabled(FALSE);
+ UnmapAllGadgets();
PlayMenuSoundStereo(sound_opening, SOUND_MIDDLE);
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)
setRequestPositionExt(x, y, request.width, request.height, add_border_size);
}
-void DrawEnvelopeRequest(char *text)
+static void DrawEnvelopeRequest(char *text)
{
char *text_final = text;
char *text_door_style = NULL;
x, y, x_steps, y_steps,
tile_size, tile_size);
- /* force DOOR font inside door area */
+ // force DOOR font inside door area
SetFontStatus(GAME_MODE_PSEUDO_DOOR);
DrawTextBuffer(sx + sx_offset, sy + sy_offset, text_final, font_nr,
free(text_door_style);
}
-void AnimateEnvelopeRequest(int anim_mode, int action)
+static void AnimateEnvelopeRequest(int anim_mode, int action)
{
int graphic = IMG_BACKGROUND_REQUEST;
boolean draw_masked = graphic_info[graphic].draw_masked;
SkipUntilDelayReached(&anim_delay, anim_delay_value, &i, last_frame);
}
+
+ ClearAutoRepeatKeyEvents();
}
-void ShowEnvelopeRequest(char *text, unsigned int req_state, int action)
+static void ShowEnvelopeRequest(char *text, unsigned int req_state, int action)
{
int graphic = IMG_BACKGROUND_REQUEST;
int sound_opening = SND_REQUEST_OPENING;
int sound_closing = SND_REQUEST_CLOSING;
- int anim_mode_1 = request.anim_mode; /* (higher priority) */
- int anim_mode_2 = graphic_info[graphic].anim_mode; /* (lower priority) */
+ int anim_mode_1 = request.anim_mode; // (higher priority)
+ int anim_mode_2 = graphic_info[graphic].anim_mode; // (lower priority)
int anim_mode = (anim_mode_1 != ANIM_DEFAULT ? anim_mode_1 : anim_mode_2);
int main_anim_mode = (anim_mode == ANIM_NONE ? ANIM_VERTICAL|ANIM_HORIZONTAL:
anim_mode == ANIM_DEFAULT ? ANIM_VERTICAL : anim_mode);
{
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)
{
DrawEnvelopeRequest(text);
}
- game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */
+ game.envelope_active = TRUE; // needed for RedrawPlayfield() events
if (action == ACTION_OPENING)
{
SetDrawtoField(DRAW_TO_FIELDBUFFER);
}
-void DrawPreviewElement(int dst_x, int dst_y, int element, int tilesize)
+static void DrawPreviewElement(int dst_x, int dst_y, int element, int tilesize)
{
if (IS_MM_WALL(element))
{
DrawPreviewLevelInfo(MICROLABEL_LEVEL_NAME);
DrawPreviewLevelInfo(MICROLABEL_LEVEL_AUTHOR);
- /* initialize delay counters */
+ // initialize delay counters
DelayReached(&scroll_delay, 0);
DelayReached(&label_delay, 0);
return;
}
- /* scroll preview level, if needed */
+ // scroll preview level, if needed
if (preview.anim_mode != ANIM_NONE &&
(level_xsize > preview.xsize || level_ysize > preview.ysize) &&
DelayReached(&scroll_delay, scroll_delay_value))
DrawPreviewLevelPlayfield(from_x, from_y);
}
- /* !!! THIS ALL SUCKS -- SHOULD BE CLEANLY REWRITTEN !!! */
- /* redraw micro level label, if needed */
+ // !!! THIS ALL SUCKS -- SHOULD BE CLEANLY REWRITTEN !!!
+ // redraw micro level label, if needed
if (!strEqual(level.name, NAMELESS_LEVEL_NAME) &&
!strEqual(level.author, ANONYMOUS_NAME) &&
!strEqual(level.author, leveldir_current->name) &&
}
}
-void DrawPreviewLevelInitial()
+void DrawPreviewPlayers(void)
+{
+ if (game_status != GAME_MODE_MAIN)
+ return;
+
+ // do not draw preview players if level preview redefined, but players aren't
+ if (preview.redefined && !menu.main.preview_players.redefined)
+ return;
+
+ boolean player_found[MAX_PLAYERS];
+ int num_players = 0;
+ int i, x, y;
+
+ for (i = 0; i < MAX_PLAYERS; i++)
+ player_found[i] = FALSE;
+
+ // check which players can be found in the level (simple approach)
+ for (x = 0; x < lev_fieldx; x++)
+ {
+ for (y = 0; y < lev_fieldy; y++)
+ {
+ int element = level.field[x][y];
+
+ if (ELEM_IS_PLAYER(element))
+ {
+ int player_nr = GET_PLAYER_NR(element);
+
+ player_nr = MIN(MAX(0, player_nr), MAX_PLAYERS - 1);
+
+ if (!player_found[player_nr])
+ num_players++;
+
+ player_found[player_nr] = TRUE;
+ }
+ }
+ }
+
+ struct TextPosInfo *pos = &menu.main.preview_players;
+ int tile_size = pos->tile_size;
+ int border_size = pos->border_size;
+ int player_xoffset_raw = (pos->vertical ? 0 : tile_size + border_size);
+ int player_yoffset_raw = (pos->vertical ? tile_size + border_size : 0);
+ int player_xoffset = (pos->xoffset != -1 ? pos->xoffset : player_xoffset_raw);
+ int player_yoffset = (pos->yoffset != -1 ? pos->yoffset : player_yoffset_raw);
+ int max_players_width = (MAX_PLAYERS - 1) * player_xoffset + tile_size;
+ int max_players_height = (MAX_PLAYERS - 1) * player_yoffset + tile_size;
+ int all_players_width = (num_players - 1) * player_xoffset + tile_size;
+ int all_players_height = (num_players - 1) * player_yoffset + tile_size;
+ int max_xpos = SX + ALIGNED_XPOS(pos->x, max_players_width, pos->align);
+ int max_ypos = SY + ALIGNED_YPOS(pos->y, max_players_height, pos->valign);
+ int xpos = SX + ALIGNED_XPOS(pos->x, all_players_width, pos->align);
+ int ypos = SY + ALIGNED_YPOS(pos->y, all_players_height, pos->valign);
+
+ // clear area in which the players will be drawn
+ ClearRectangleOnBackground(drawto, max_xpos, max_ypos,
+ max_players_width, max_players_height);
+
+ if (!network.enabled && !setup.team_mode)
+ return;
+
+ // only draw players if level is suited for team mode
+ if (num_players < 2)
+ return;
+
+ // draw all players that were found in the level
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ if (player_found[i])
+ {
+ int graphic = el2img(EL_PLAYER_1 + i);
+
+ DrawSizedGraphicThruMaskExt(drawto, xpos, ypos, graphic, 0, tile_size);
+
+ xpos += player_xoffset;
+ ypos += player_yoffset;
+ }
+ }
+}
+
+void DrawPreviewLevelInitial(void)
{
DrawPreviewLevelExt(TRUE);
+ DrawPreviewPlayers();
}
-void DrawPreviewLevelAnimation()
+void DrawPreviewLevelAnimation(void)
{
DrawPreviewLevelExt(FALSE);
}
-inline static void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y,
- int graphic, int sync_frame,
- int mask_mode)
+static void DrawNetworkPlayer(int x, int y, int player_nr, int tile_size,
+ int border_size, int font_nr)
+{
+ int graphic = el2img(EL_PLAYER_1 + player_nr);
+ int font_height = getFontHeight(font_nr);
+ int player_height = MAX(tile_size, font_height);
+ int xoffset_text = tile_size + border_size;
+ int yoffset_text = (player_height - font_height) / 2;
+ int yoffset_graphic = (player_height - tile_size) / 2;
+ char *player_name = getNetworkPlayerName(player_nr + 1);
+
+ DrawSizedGraphicThruMaskExt(drawto, x, y + yoffset_graphic, graphic, 0,
+ tile_size);
+ DrawText(x + xoffset_text, y + yoffset_text, player_name, font_nr);
+}
+
+static void DrawNetworkPlayersExt(boolean force)
+{
+ if (game_status != GAME_MODE_MAIN)
+ return;
+
+ if (!network.connected && !force)
+ return;
+
+ // do not draw network players if level preview redefined, but players aren't
+ if (preview.redefined && !menu.main.network_players.redefined)
+ return;
+
+ int num_players = 0;
+ int i;
+
+ for (i = 0; i < MAX_PLAYERS; i++)
+ if (stored_player[i].connected_network)
+ num_players++;
+
+ struct TextPosInfo *pos = &menu.main.network_players;
+ int tile_size = pos->tile_size;
+ int border_size = pos->border_size;
+ int xoffset_text = tile_size + border_size;
+ int font_nr = pos->font;
+ int font_width = getFontWidth(font_nr);
+ int font_height = getFontHeight(font_nr);
+ int player_height = MAX(tile_size, font_height);
+ int player_yoffset = player_height + border_size;
+ int max_players_width = xoffset_text + MAX_PLAYER_NAME_LEN * font_width;
+ int max_players_height = MAX_PLAYERS * player_yoffset - border_size;
+ int all_players_height = num_players * player_yoffset - border_size;
+ int max_xpos = SX + ALIGNED_XPOS(pos->x, max_players_width, pos->align);
+ int max_ypos = SY + ALIGNED_YPOS(pos->y, max_players_height, pos->valign);
+ int ypos = SY + ALIGNED_YPOS(pos->y, all_players_height, pos->valign);
+
+ ClearRectangleOnBackground(drawto, max_xpos, max_ypos,
+ max_players_width, max_players_height);
+
+ // first draw local network player ...
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ if (stored_player[i].connected_network &&
+ stored_player[i].connected_locally)
+ {
+ char *player_name = getNetworkPlayerName(i + 1);
+ int player_width = xoffset_text + getTextWidth(player_name, font_nr);
+ int xpos = SX + ALIGNED_XPOS(pos->x, player_width, pos->align);
+
+ DrawNetworkPlayer(xpos, ypos, i, tile_size, border_size, font_nr);
+
+ ypos += player_yoffset;
+ }
+ }
+
+ // ... then draw all other network players
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ if (stored_player[i].connected_network &&
+ !stored_player[i].connected_locally)
+ {
+ char *player_name = getNetworkPlayerName(i + 1);
+ int player_width = xoffset_text + getTextWidth(player_name, font_nr);
+ int xpos = SX + ALIGNED_XPOS(pos->x, player_width, pos->align);
+
+ DrawNetworkPlayer(xpos, ypos, i, tile_size, border_size, font_nr);
+
+ ypos += player_yoffset;
+ }
+ }
+}
+
+void DrawNetworkPlayers(void)
+{
+ DrawNetworkPlayersExt(FALSE);
+}
+
+void ClearNetworkPlayers(void)
+{
+ DrawNetworkPlayersExt(TRUE);
+}
+
+static void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y,
+ int graphic, int sync_frame,
+ int mask_mode)
{
int frame = getGraphicAnimationFrame(graphic, sync_frame);
DrawFixedGraphicExt(dst_bitmap, x, y, graphic, frame);
}
-inline static void DrawGraphicAnimation(int x, int y, int graphic)
+static void DrawGraphicAnimation(int x, int y, int graphic)
{
int lx = LEVELX(x), ly = LEVELY(y);
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
}
{
if (player->use_murphy)
{
- /* this works only because currently only one player can be "murphy" ... */
+ // this works only because currently only one player can be "murphy" ...
static int last_horizontal_dir = MV_LEFT;
int graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, move_dir);
if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
last_horizontal_dir = move_dir;
- if (graphic == IMG_SP_MURPHY) /* undefined => use special graphic */
+ if (graphic == IMG_SP_MURPHY) // undefined => use special graphic
{
int direction = (player->is_snapping ? move_dir : last_horizontal_dir);
g1->anim_mode == g2->anim_mode);
}
-void DrawAllPlayers()
+#define DRAW_PLAYER_OVER_PUSHED_ELEMENT 1
+
+enum
{
- int i;
+ DRAW_PLAYER_STAGE_INIT = 0,
+ DRAW_PLAYER_STAGE_LAST_FIELD,
+ DRAW_PLAYER_STAGE_FIELD_UNDER_PLAYER,
+#if DRAW_PLAYER_OVER_PUSHED_ELEMENT
+ DRAW_PLAYER_STAGE_ELEMENT_PUSHED,
+ DRAW_PLAYER_STAGE_PLAYER,
+#else
+ DRAW_PLAYER_STAGE_PLAYER,
+ DRAW_PLAYER_STAGE_ELEMENT_PUSHED,
+#endif
+ DRAW_PLAYER_STAGE_ELEMENT_OVER_PLAYER,
+ DRAW_PLAYER_STAGE_FIELD_OVER_PLAYER,
- for (i = 0; i < MAX_PLAYERS; i++)
- if (stored_player[i].active)
- DrawPlayer(&stored_player[i]);
-}
+ NUM_DRAW_PLAYER_STAGES
+};
-void DrawPlayerField(int x, int y)
+static void DrawPlayerExt(struct PlayerInfo *player, int drawing_stage)
{
- if (!IS_PLAYER(x, y))
+ static int static_last_player_graphic[MAX_PLAYERS];
+ static int static_last_player_frame[MAX_PLAYERS];
+ static boolean static_player_is_opaque[MAX_PLAYERS];
+ static boolean draw_player[MAX_PLAYERS];
+ int pnr = player->index_nr;
+
+ if (drawing_stage == DRAW_PLAYER_STAGE_INIT)
+ {
+ static_last_player_graphic[pnr] = getPlayerGraphic(player, player->MovDir);
+ static_last_player_frame[pnr] = player->Frame;
+ static_player_is_opaque[pnr] = FALSE;
+
+ draw_player[pnr] = TRUE;
+ }
+
+ if (!draw_player[pnr])
return;
- DrawPlayer(PLAYERINFO(x, y));
-}
+#if DEBUG
+ if (!IN_LEV_FIELD(player->jx, player->jy))
+ {
+ Debug("draw:DrawPlayerExt", "x = %d, y = %d", player->jx, player->jy);
+ Debug("draw:DrawPlayerExt", "This should never happen!");
-#define DRAW_PLAYER_OVER_PUSHED_ELEMENT 1
+ draw_player[pnr] = FALSE;
+
+ return;
+ }
+#endif
+
+ int last_player_graphic = static_last_player_graphic[pnr];
+ int last_player_frame = static_last_player_frame[pnr];
+ boolean player_is_opaque = static_player_is_opaque[pnr];
-void DrawPlayer(struct PlayerInfo *player)
-{
int jx = player->jx;
int jy = player->jy;
- int move_dir = player->MovDir;
+ int move_dir = (player->is_waiting ? player->dir_waiting : player->MovDir);
int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? +1 : 0);
int dy = (move_dir == MV_UP ? -1 : move_dir == MV_DOWN ? +1 : 0);
int last_jx = (player->is_moving ? jx - dx : jx);
int last_jy = (player->is_moving ? jy - dy : jy);
int next_jx = jx + dx;
int next_jy = jy + dy;
- boolean player_is_moving = (player->MovPos ? TRUE : FALSE);
- boolean player_is_opaque = FALSE;
- int sx = SCREENX(jx), sy = SCREENY(jy);
- int sxx = 0, syy = 0;
- int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
- int graphic;
- int action = ACTION_DEFAULT;
- int last_player_graphic = getPlayerGraphic(player, move_dir);
- int last_player_frame = player->Frame;
- int frame = 0;
+ boolean player_is_moving = (player->MovPos != 0 ? TRUE : FALSE);
+ int sx = SCREENX(jx);
+ int sy = SCREENY(jy);
+ int sxx = (move_dir == MV_LEFT || move_dir == MV_RIGHT ? player->GfxPos : 0);
+ int syy = (move_dir == MV_UP || move_dir == MV_DOWN ? player->GfxPos : 0);
+ int element = Tile[jx][jy];
+ int last_element = Tile[last_jx][last_jy];
+ int action = (player->is_pushing ? ACTION_PUSHING :
+ player->is_digging ? ACTION_DIGGING :
+ player->is_collecting ? ACTION_COLLECTING :
+ player->is_moving ? ACTION_MOVING :
+ player->is_snapping ? ACTION_SNAPPING :
+ player->is_dropping ? ACTION_DROPPING :
+ player->is_waiting ? player->action_waiting :
+ ACTION_DEFAULT);
+
+ if (drawing_stage == DRAW_PLAYER_STAGE_INIT)
+ {
+ // ------------------------------------------------------------------------
+ // initialize drawing the player
+ // ------------------------------------------------------------------------
- /* GfxElement[][] is set to the element the player is digging or collecting;
- remove also for off-screen player if the player is not moving anymore */
- if (IN_LEV_FIELD(jx, jy) && !player_is_moving)
- GfxElement[jx][jy] = EL_UNDEFINED;
+ draw_player[pnr] = FALSE;
- if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
- return;
+ // GfxElement[][] is set to the element the player is digging or collecting;
+ // remove also for off-screen player if the player is not moving anymore
+ if (IN_LEV_FIELD(jx, jy) && !player_is_moving)
+ GfxElement[jx][jy] = EL_UNDEFINED;
-#if DEBUG
- if (!IN_LEV_FIELD(jx, jy))
- {
- printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
- printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
- printf("DrawPlayerField(): This should never happen!\n");
- return;
- }
-#endif
+ if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
+ return;
- if (element == EL_EXPLOSION)
- return;
+ if (element == EL_EXPLOSION)
+ return;
- action = (player->is_pushing ? ACTION_PUSHING :
- player->is_digging ? ACTION_DIGGING :
- player->is_collecting ? ACTION_COLLECTING :
- player->is_moving ? ACTION_MOVING :
- player->is_snapping ? ACTION_SNAPPING :
- player->is_dropping ? ACTION_DROPPING :
- player->is_waiting ? player->action_waiting : ACTION_DEFAULT);
+ InitPlayerGfxAnimation(player, action, move_dir);
- if (player->is_waiting)
- move_dir = player->dir_waiting;
+ draw_player[pnr] = TRUE;
+ }
+ else if (drawing_stage == DRAW_PLAYER_STAGE_LAST_FIELD)
+ {
+ // ------------------------------------------------------------------------
+ // draw things in the field the player is leaving, if needed
+ // ------------------------------------------------------------------------
- InitPlayerGfxAnimation(player, action, move_dir);
+ if (!IN_SCR_FIELD(sx, sy))
+ draw_player[pnr] = FALSE;
- /* ----------------------------------------------------------------------- */
- /* draw things in the field the player is leaving, if needed */
- /* ----------------------------------------------------------------------- */
+ if (!player->is_moving)
+ return;
- if (player->is_moving)
- {
if (Back[last_jx][last_jy] && IS_DRAWABLE(last_element))
{
DrawLevelElement(last_jx, last_jy, Back[last_jx][last_jy]);
last_element == EL_EM_DYNAMITE_ACTIVE ||
last_element == EL_SP_DISK_RED_ACTIVE)
DrawDynamite(last_jx, last_jy);
-#if 0
- /* !!! this is not enough to prevent flickering of players which are
- moving next to each others without a free tile between them -- this
- can only be solved by drawing all players layer by layer (first the
- background, then the foreground etc.) !!! => TODO */
- else if (!IS_PLAYER(last_jx, last_jy))
- DrawLevelField(last_jx, last_jy);
-#else
else
DrawLevelField(last_jx, last_jy);
-#endif
if (player->is_pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
DrawLevelElement(next_jx, next_jy, EL_EMPTY);
}
+ else if (drawing_stage == DRAW_PLAYER_STAGE_FIELD_UNDER_PLAYER)
+ {
+ // ------------------------------------------------------------------------
+ // draw things behind the player, if needed
+ // ------------------------------------------------------------------------
- if (!IN_SCR_FIELD(sx, sy))
- return;
+ if (Back[jx][jy])
+ {
+ DrawLevelElement(jx, jy, Back[jx][jy]);
- /* ----------------------------------------------------------------------- */
- /* draw things behind the player, if needed */
- /* ----------------------------------------------------------------------- */
+ return;
+ }
+
+ if (IS_ACTIVE_BOMB(element))
+ {
+ DrawLevelElement(jx, jy, EL_EMPTY);
+
+ return;
+ }
- if (Back[jx][jy])
- DrawLevelElement(jx, jy, Back[jx][jy]);
- else if (IS_ACTIVE_BOMB(element))
- DrawLevelElement(jx, jy, EL_EMPTY);
- else
- {
if (player_is_moving && GfxElement[jx][jy] != EL_UNDEFINED)
{
int old_element = GfxElement[jx][jy];
DrawGraphic(sx, sy, old_graphic, frame);
if (graphic_info[old_graphic].anim_mode & ANIM_OPAQUE_PLAYER)
- player_is_opaque = TRUE;
+ static_player_is_opaque[pnr] = TRUE;
}
else
{
GfxElement[jx][jy] = EL_UNDEFINED;
- /* make sure that pushed elements are drawn with correct frame rate */
- graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir);
+ // make sure that pushed elements are drawn with correct frame rate
+ int graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir);
if (player->is_pushing && player->is_moving && !IS_ANIM_MODE_CE(graphic))
GfxFrame[jx][jy] = player->StepFrame;
DrawLevelField(jx, jy);
}
}
-
-#if !DRAW_PLAYER_OVER_PUSHED_ELEMENT
- /* ----------------------------------------------------------------------- */
- /* draw player himself */
- /* ----------------------------------------------------------------------- */
-
- graphic = getPlayerGraphic(player, move_dir);
-
- /* in the case of changed player action or direction, prevent the current
- animation frame from being restarted for identical animations */
- if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic))
- player->Frame = last_player_frame;
-
- frame = getGraphicAnimationFrame(graphic, player->Frame);
-
- if (player->GfxPos)
- {
- if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
- sxx = player->GfxPos;
- else
- syy = player->GfxPos;
- }
-
- if (player_is_opaque)
- DrawGraphicShifted(sx, sy, sxx, syy, graphic, frame,NO_CUTTING,NO_MASKING);
- else
- DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
-
- if (SHIELD_ON(player))
- {
- int graphic = (player->shield_deadly_time_left ? IMG_SHIELD_DEADLY_ACTIVE :
- IMG_SHIELD_NORMAL_ACTIVE);
- int frame = getGraphicAnimationFrame(graphic, -1);
-
- DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
- }
-#endif
-
-#if DRAW_PLAYER_OVER_PUSHED_ELEMENT
- if (player->GfxPos)
+ else if (drawing_stage == DRAW_PLAYER_STAGE_ELEMENT_PUSHED)
{
- if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
- sxx = player->GfxPos;
- else
- syy = player->GfxPos;
- }
-#endif
+ // ------------------------------------------------------------------------
+ // draw things the player is pushing, if needed
+ // ------------------------------------------------------------------------
- /* ----------------------------------------------------------------------- */
- /* draw things the player is pushing, if needed */
- /* ----------------------------------------------------------------------- */
+ if (!player->is_pushing || !player->is_moving)
+ return;
- if (player->is_pushing && player->is_moving)
- {
- int px = SCREENX(jx), py = SCREENY(jy);
- int pxx = (TILEX - ABS(sxx)) * dx;
- int pyy = (TILEY - ABS(syy)) * dy;
int gfx_frame = GfxFrame[jx][jy];
- int graphic;
- int sync_frame;
- int frame;
-
- if (!IS_MOVING(jx, jy)) /* push movement already finished */
+ if (!IS_MOVING(jx, jy)) // push movement already finished
{
- element = Feld[next_jx][next_jy];
+ element = Tile[next_jx][next_jy];
gfx_frame = GfxFrame[next_jx][next_jy];
}
- graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir);
+ int graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir);
+ int sync_frame = (IS_ANIM_MODE_CE(graphic) ? gfx_frame : player->StepFrame);
+ int frame = getGraphicAnimationFrame(graphic, sync_frame);
- sync_frame = (IS_ANIM_MODE_CE(graphic) ? gfx_frame : player->StepFrame);
- frame = getGraphicAnimationFrame(graphic, sync_frame);
-
- /* draw background element under pushed element (like the Sokoban field) */
+ // draw background element under pushed element (like the Sokoban field)
if (game.use_masked_pushing && IS_MOVING(jx, jy))
{
- /* this allows transparent pushing animation over non-black background */
+ // this allows transparent pushing animation over non-black background
if (Back[jx][jy])
DrawLevelElement(jx, jy, Back[jx][jy]);
else if (Back[next_jx][next_jy])
DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
+ int px = SCREENX(jx), py = SCREENY(jy);
+ int pxx = (TILEX - ABS(sxx)) * dx;
+ int pyy = (TILEY - ABS(syy)) * dy;
+
#if 1
- /* do not draw (EM style) pushing animation when pushing is finished */
- /* (two-tile animations usually do not contain start and end frame) */
+ // do not draw (EM style) pushing animation when pushing is finished
+ // (two-tile animations usually do not contain start and end frame)
if (graphic_info[graphic].double_movement && !IS_MOVING(jx, jy))
- DrawLevelElement(next_jx, next_jy, Feld[next_jx][next_jy]);
+ DrawLevelElement(next_jx, next_jy, Tile[next_jx][next_jy]);
else
DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame, NO_CUTTING);
#else
- /* masked drawing is needed for EMC style (double) movement graphics */
- /* !!! (ONLY WHEN DRAWING PUSHED ELEMENT OVER THE PLAYER) !!! */
+ // masked drawing is needed for EMC style (double) movement graphics
+ // !!! (ONLY WHEN DRAWING PUSHED ELEMENT OVER THE PLAYER) !!!
DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame, NO_CUTTING);
#endif
}
+ else if (drawing_stage == DRAW_PLAYER_STAGE_PLAYER)
+ {
+ // ------------------------------------------------------------------------
+ // draw player himself
+ // ------------------------------------------------------------------------
-#if DRAW_PLAYER_OVER_PUSHED_ELEMENT
- /* ----------------------------------------------------------------------- */
- /* draw player himself */
- /* ----------------------------------------------------------------------- */
-
- graphic = getPlayerGraphic(player, move_dir);
+ int graphic = getPlayerGraphic(player, move_dir);
- /* in the case of changed player action or direction, prevent the current
- animation frame from being restarted for identical animations */
- if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic))
- player->Frame = last_player_frame;
+ // in the case of changed player action or direction, prevent the current
+ // animation frame from being restarted for identical animations
+ if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic))
+ player->Frame = last_player_frame;
- frame = getGraphicAnimationFrame(graphic, player->Frame);
+ int frame = getGraphicAnimationFrame(graphic, player->Frame);
- if (player->GfxPos)
- {
- if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
- sxx = player->GfxPos;
+ if (player_is_opaque)
+ DrawGraphicShifted(sx,sy, sxx,syy, graphic, frame, NO_CUTTING,NO_MASKING);
else
- syy = player->GfxPos;
- }
+ DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
- if (player_is_opaque)
- DrawGraphicShifted(sx, sy, sxx, syy, graphic, frame,NO_CUTTING,NO_MASKING);
- else
- DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
+ if (SHIELD_ON(player))
+ {
+ graphic = (player->shield_deadly_time_left ? IMG_SHIELD_DEADLY_ACTIVE :
+ IMG_SHIELD_NORMAL_ACTIVE);
+ frame = getGraphicAnimationFrame(graphic, -1);
- if (SHIELD_ON(player))
+ DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
+ }
+ }
+ else if (drawing_stage == DRAW_PLAYER_STAGE_ELEMENT_OVER_PLAYER)
{
- int graphic = (player->shield_deadly_time_left ? IMG_SHIELD_DEADLY_ACTIVE :
- IMG_SHIELD_NORMAL_ACTIVE);
- int frame = getGraphicAnimationFrame(graphic, -1);
+ // ------------------------------------------------------------------------
+ // draw things in front of player (active dynamite or dynabombs)
+ // ------------------------------------------------------------------------
- DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
- }
-#endif
+ if (IS_ACTIVE_BOMB(element))
+ {
+ int graphic = el2img(element);
+ int frame = getGraphicAnimationFrame(graphic, GfxFrame[jx][jy]);
- /* ----------------------------------------------------------------------- */
- /* draw things in front of player (active dynamite or dynabombs) */
- /* ----------------------------------------------------------------------- */
+ if (game.emulation == EMU_SUPAPLEX)
+ DrawGraphic(sx, sy, IMG_SP_DISK_RED, frame);
+ else
+ DrawGraphicThruMask(sx, sy, graphic, frame);
+ }
- if (IS_ACTIVE_BOMB(element))
+ if (player_is_moving && last_element == EL_EXPLOSION)
+ {
+ int element = (GfxElement[last_jx][last_jy] != EL_UNDEFINED ?
+ GfxElement[last_jx][last_jy] : EL_EMPTY);
+ int graphic = el_act2img(element, ACTION_EXPLODING);
+ int delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2);
+ int phase = ExplodePhase[last_jx][last_jy] - 1;
+ int frame = getGraphicAnimationFrame(graphic, phase - delay);
+
+ if (phase >= delay)
+ DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy), graphic, frame);
+ }
+ }
+ else if (drawing_stage == DRAW_PLAYER_STAGE_FIELD_OVER_PLAYER)
{
- graphic = el2img(element);
- frame = getGraphicAnimationFrame(graphic, GfxFrame[jx][jy]);
+ // ------------------------------------------------------------------------
+ // draw elements the player is just walking/passing through/under
+ // ------------------------------------------------------------------------
- if (game.emulation == EMU_SUPAPLEX)
- DrawGraphic(sx, sy, IMG_SP_DISK_RED, frame);
- else
- DrawGraphicThruMask(sx, sy, graphic, frame);
- }
+ if (player_is_moving)
+ {
+ // handle the field the player is leaving ...
+ if (IS_ACCESSIBLE_INSIDE(last_element))
+ DrawLevelField(last_jx, last_jy);
+ else if (IS_ACCESSIBLE_UNDER(last_element))
+ DrawLevelFieldThruMask(last_jx, last_jy);
+ }
- if (player_is_moving && last_element == EL_EXPLOSION)
- {
- int element = (GfxElement[last_jx][last_jy] != EL_UNDEFINED ?
- GfxElement[last_jx][last_jy] : EL_EMPTY);
- int graphic = el_act2img(element, ACTION_EXPLODING);
- int delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2);
- int phase = ExplodePhase[last_jx][last_jy] - 1;
- int frame = getGraphicAnimationFrame(graphic, phase - delay);
+ // do not redraw accessible elements if the player is just pushing them
+ if (!player_is_moving || !player->is_pushing)
+ {
+ // ... and the field the player is entering
+ if (IS_ACCESSIBLE_INSIDE(element))
+ DrawLevelField(jx, jy);
+ else if (IS_ACCESSIBLE_UNDER(element))
+ DrawLevelFieldThruMask(jx, jy);
+ }
- if (phase >= delay)
- DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy), graphic, frame);
+ MarkTileDirty(sx, sy);
}
+}
- /* ----------------------------------------------------------------------- */
- /* draw elements the player is just walking/passing through/under */
- /* ----------------------------------------------------------------------- */
+void DrawPlayer(struct PlayerInfo *player)
+{
+ int i;
- if (player_is_moving)
- {
- /* handle the field the player is leaving ... */
- if (IS_ACCESSIBLE_INSIDE(last_element))
- DrawLevelField(last_jx, last_jy);
- else if (IS_ACCESSIBLE_UNDER(last_element))
- DrawLevelFieldThruMask(last_jx, last_jy);
- }
+ for (i = 0; i < NUM_DRAW_PLAYER_STAGES; i++)
+ DrawPlayerExt(player, i);
+}
- /* do not redraw accessible elements if the player is just pushing them */
- if (!player_is_moving || !player->is_pushing)
- {
- /* ... and the field the player is entering */
- if (IS_ACCESSIBLE_INSIDE(element))
- DrawLevelField(jx, jy);
- else if (IS_ACCESSIBLE_UNDER(element))
- DrawLevelFieldThruMask(jx, jy);
- }
+void DrawAllPlayers(void)
+{
+ int i, j;
- MarkTileDirty(sx, sy);
+ for (i = 0; i < NUM_DRAW_PLAYER_STAGES; i++)
+ for (j = 0; j < MAX_PLAYERS; j++)
+ if (stored_player[j].active)
+ DrawPlayerExt(&stored_player[j], i);
}
-/* ------------------------------------------------------------------------- */
+void DrawPlayerField(int x, int y)
+{
+ if (!IS_PLAYER(x, y))
+ return;
+
+ DrawPlayer(PLAYERINFO(x, y));
+}
+
+// ----------------------------------------------------------------------------
-void WaitForEventToContinue()
+void WaitForEventToContinue(void)
{
+ boolean first_wait = TRUE;
boolean still_wait = TRUE;
if (program.headless)
return;
- /* simulate releasing mouse button over last gadget, if still pressed */
+ // simulate releasing mouse button over last gadget, if still pressed
if (button_status)
HandleGadgets(-1, -1, 0);
button_status = MB_RELEASED;
ClearEventQueue();
+ ClearPlayerAction();
while (still_wait)
{
switch (event.type)
{
case EVENT_BUTTONPRESS:
+ case EVENT_FINGERPRESS:
+ first_wait = FALSE;
+ break;
+
+ case EVENT_BUTTONRELEASE:
+ case EVENT_FINGERRELEASE:
+ still_wait = first_wait;
+ break;
+
case EVENT_KEYPRESS:
-#if defined(TARGET_SDL2)
case SDL_CONTROLLERBUTTONDOWN:
-#endif
case SDL_JOYBUTTONDOWN:
still_wait = FALSE;
break;
- case EVENT_KEYRELEASE:
- ClearPlayerAction();
- break;
-
default:
HandleOtherEvents(&event);
break;
still_wait = FALSE;
}
- BackToFront();
+ if (!PendingEvent())
+ BackToFront();
}
}
static int RequestHandleEvents(unsigned int req_state)
{
- boolean level_solved = (game_status == GAME_MODE_PLAYING &&
- local_player->LevelSolved_GameEnd);
+ boolean game_just_ended = (game_status == GAME_MODE_PLAYING &&
+ checkGameEnded());
+ int draw_buffer_last = GetDrawtoField();
int width = request.width;
int height = request.height;
int sx, sy;
int result;
+ // when showing request dialog after game ended, deactivate game panel
+ if (game_just_ended)
+ game.panel.active = FALSE;
+
+ game.request_active = TRUE;
+
setRequestPosition(&sx, &sy, FALSE);
button_status = MB_RELEASED;
while (result < 0)
{
- if (level_solved)
+ if (game_just_ended)
{
- /* the MM game engine does not use a special (scrollable) field buffer */
- if (level.game_engine_type != GAME_ENGINE_TYPE_MM)
- SetDrawtoField(DRAW_TO_FIELDBUFFER);
+ SetDrawtoField(draw_buffer_last);
HandleGameActions();
if (global.use_envelope_request)
{
- /* copy current state of request area to middle of playfield area */
+ // copy current state of request area to middle of playfield area
BlitBitmap(bitmap_db_store_2, drawto, sx, sy, width, height, sx, sy);
}
}
button_status = MB_RELEASED;
}
- /* this sets 'request_gadget_id' */
+ // this sets 'request_gadget_id'
HandleGadgets(mx, my, button_status);
switch (request_gadget_id)
{
case TOOL_CTRL_ID_YES:
+ case TOOL_CTRL_ID_TOUCH_YES:
result = TRUE;
break;
case TOOL_CTRL_ID_NO:
+ case TOOL_CTRL_ID_TOUCH_NO:
result = FALSE;
break;
case TOOL_CTRL_ID_CONFIRM:
+ case TOOL_CTRL_ID_TOUCH_CONFIRM:
result = TRUE | FALSE;
break;
break;
default:
+ // only check clickable animations if no request gadget clicked
+ HandleGlobalAnimClicks(mx, my, button_status, FALSE);
break;
}
break;
}
-#if defined(TARGET_SDL2)
case SDL_WINDOWEVENT:
HandleWindowEvent((WindowEvent *) &event);
break;
case SDL_APP_DIDENTERFOREGROUND:
HandlePauseResumeEvent((PauseResumeEvent *) &event);
break;
-#endif
case EVENT_KEYPRESS:
{
break;
case KSYM_Return:
-#if defined(TARGET_SDL2)
+ case KSYM_y:
+ case KSYM_Y:
case KSYM_Select:
case KSYM_Menu:
#if defined(KSYM_Rewind)
- case KSYM_Rewind: /* for Amazon Fire TV remote */
-#endif
+ case KSYM_Rewind: // for Amazon Fire TV remote
#endif
result = 1;
break;
case KSYM_Escape:
-#if defined(TARGET_SDL2)
+ case KSYM_n:
+ case KSYM_N:
case KSYM_Back:
#if defined(KSYM_FastForward)
- case KSYM_FastForward: /* for Amazon Fire TV remote */
-#endif
+ case KSYM_FastForward: // for Amazon Fire TV remote
#endif
result = 0;
break;
default:
- HandleKeysDebug(key);
+ HandleKeysDebug(key, KEY_PRESSED);
break;
}
if (req_state & REQ_PLAYER)
- result = 0;
+ {
+ int old_player_nr = setup.network_player_nr;
+
+ if (result != -1)
+ result = old_player_nr + 1;
+
+ switch (key)
+ {
+ case KSYM_space:
+ result = old_player_nr + 1;
+ break;
+
+ case KSYM_Up:
+ case KSYM_1:
+ result = 1;
+ break;
+
+ case KSYM_Right:
+ case KSYM_2:
+ result = 2;
+ break;
+
+ case KSYM_Down:
+ case KSYM_3:
+ result = 3;
+ break;
+
+ case KSYM_Left:
+ case KSYM_4:
+ result = 4;
+ break;
+
+ default:
+ break;
+ }
+ }
break;
}
+ case EVENT_FINGERRELEASE:
case EVENT_KEYRELEASE:
ClearPlayerAction();
break;
-#if defined(TARGET_SDL2)
case SDL_CONTROLLERBUTTONDOWN:
switch (event.cbutton.button)
{
case SDL_CONTROLLER_BUTTON_A:
case SDL_CONTROLLER_BUTTON_X:
case SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
+ case SDL_CONTROLLER_BUTTON_LEFTSTICK:
result = 1;
break;
case SDL_CONTROLLER_BUTTON_B:
case SDL_CONTROLLER_BUTTON_Y:
case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER:
+ case SDL_CONTROLLER_BUTTON_RIGHTSTICK:
case SDL_CONTROLLER_BUTTON_BACK:
result = 0;
break;
}
if (req_state & REQ_PLAYER)
- result = 0;
+ {
+ int old_player_nr = setup.network_player_nr;
+
+ if (result != -1)
+ result = old_player_nr + 1;
+
+ switch (event.cbutton.button)
+ {
+ case SDL_CONTROLLER_BUTTON_DPAD_UP:
+ case SDL_CONTROLLER_BUTTON_Y:
+ result = 1;
+ break;
+
+ case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
+ case SDL_CONTROLLER_BUTTON_B:
+ result = 2;
+ break;
+
+ case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
+ case SDL_CONTROLLER_BUTTON_A:
+ result = 3;
+ break;
+
+ case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
+ case SDL_CONTROLLER_BUTTON_X:
+ result = 4;
+ break;
+
+ default:
+ break;
+ }
+ }
break;
HandleJoystickEvent(&event);
ClearPlayerAction();
break;
-#endif
default:
HandleOtherEvents(&event);
else if (joy & JOY_BUTTON_2)
result = 0;
}
+ else if (AnyJoystick())
+ {
+ int joy = AnyJoystick();
+
+ if (req_state & REQ_PLAYER)
+ {
+ if (joy & JOY_UP)
+ result = 1;
+ else if (joy & JOY_RIGHT)
+ result = 2;
+ else if (joy & JOY_DOWN)
+ result = 3;
+ else if (joy & JOY_LEFT)
+ result = 4;
+ }
+ }
- if (level_solved)
+ if (game_just_ended)
{
if (global.use_envelope_request)
{
- /* copy back current state of pressed buttons inside request area */
+ // copy back current state of pressed buttons inside request area
BlitBitmap(drawto, bitmap_db_store_2, sx, sy, width, height, sx, sy);
}
}
BackToFront();
}
+ SetDrawtoField(draw_buffer_last);
+
+ game.request_active = FALSE;
+
return result;
}
int result;
int ty;
- if (maxWordLengthInString(text) > MAX_REQUEST_LINE_FONT1_LEN)
+ if (maxWordLengthInRequestString(text) > MAX_REQUEST_LINE_FONT1_LEN)
{
max_request_line_len = MAX_REQUEST_LINE_FONT2_LEN;
font_nr = FONT_TEXT_1;
if (game_status == GAME_MODE_PLAYING)
BlitScreenToBitmap(backbuffer);
- /* disable deactivated drawing when quick-loading level tape recording */
+ // disable deactivated drawing when quick-loading level tape recording
if (tape.playing && tape.deactivate_display)
TapeDeactivateDisplayOff(TRUE);
SetMouseCursor(CURSOR_DEFAULT);
-#if defined(NETWORK_AVALIABLE)
- /* pause network game while waiting for request to answer */
- if (options.network &&
+ // 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();
-#endif
old_door_state = GetDoorState();
- /* simulate releasing mouse button over last gadget, if still pressed */
+ // simulate releasing mouse button over last gadget, if still pressed
if (button_status)
HandleGadgets(-1, -1, 0);
UnmapAllGadgets();
- /* draw released gadget before proceeding */
+ // draw released gadget before proceeding
// BackToFront();
if (old_door_state & DOOR_OPEN_1)
{
CloseDoor(DOOR_CLOSE_1);
- /* save old door content */
+ // save old door content
BlitBitmap(bitmap_db_door_1, bitmap_db_door_1,
0 * DXSIZE, 0, DXSIZE, DYSIZE, 1 * DXSIZE, 0);
}
SetDoorBackgroundImage(IMG_BACKGROUND_DOOR);
SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
- /* clear door drawing field */
+ // clear door drawing field
DrawBackground(DX, DY, DXSIZE, DYSIZE);
- /* force DOOR font inside door area */
+ // force DOOR font inside door area
SetFontStatus(GAME_MODE_PSEUDO_DOOR);
- /* write text for request */
+ // write text for request
for (text_ptr = text, ty = 0; ty < MAX_REQUEST_LINES; ty++)
{
char text_line[max_request_line_len + 1];
{
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_4]);
}
- /* copy request gadgets to door backbuffer */
+ // copy request gadgets to door backbuffer
BlitBitmap(drawto, bitmap_db_door_1, DX, DY, DXSIZE, DYSIZE, 0, 0);
OpenDoor(DOOR_OPEN_1);
SetDrawBackgroundMask(REDRAW_FIELD);
}
-#if defined(NETWORK_AVALIABLE)
- /* continue network game after request */
- if (options.network &&
+ // 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();
-#endif
- /* restore deactivated drawing when quick-loading level tape recording */
+ // restore deactivated drawing when quick-loading level tape recording
if (tape.playing && tape.deactivate_display)
TapeDeactivateDisplayOn();
if (game_status == GAME_MODE_PLAYING)
BlitScreenToBitmap(backbuffer);
- /* disable deactivated drawing when quick-loading level tape recording */
+ // disable deactivated drawing when quick-loading level tape recording
if (tape.playing && tape.deactivate_display)
TapeDeactivateDisplayOff(TRUE);
SetMouseCursor(CURSOR_DEFAULT);
-#if defined(NETWORK_AVALIABLE)
- /* pause network game while waiting for request to answer */
- if (options.network &&
+ // 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();
-#endif
- /* simulate releasing mouse button over last gadget, if still pressed */
+ // simulate releasing mouse button over last gadget, if still pressed
if (button_status)
HandleGadgets(-1, -1, 0);
// SetDoorBackgroundImage(IMG_BACKGROUND_DOOR);
// SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
- /* clear door drawing field */
+ // clear door drawing field
// DrawBackground(DX, DY, DXSIZE, DYSIZE);
ShowEnvelopeRequest(text, req_state, ACTION_OPENING);
SetDrawBackgroundMask(REDRAW_FIELD);
}
-#if defined(NETWORK_AVALIABLE)
- /* continue network game after request */
- if (options.network &&
+ // 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();
-#endif
- /* restore deactivated drawing when quick-loading level tape recording */
+ // restore deactivated drawing when quick-loading level tape recording
if (tape.playing && tape.deactivate_display)
TapeDeactivateDisplayOn();
boolean Request(char *text, unsigned int req_state)
{
- boolean overlay_active = GetOverlayActive();
+ boolean overlay_enabled = GetOverlayEnabled();
boolean result;
- SetOverlayActive(FALSE);
+ SetOverlayEnabled(FALSE);
if (global.use_envelope_request)
result = RequestEnvelope(text, req_state);
else
result = RequestDoor(text, req_state);
- SetOverlayActive(overlay_active);
+ SetOverlayEnabled(overlay_enabled);
return result;
}
return compare_result;
}
-void InitGraphicCompatibilityInfo_Doors()
+void InitGraphicCompatibilityInfo_Doors(void)
{
struct
{
struct Rect *door_rect = &door_rect_list[door_index];
boolean door_gfx_redefined = FALSE;
- /* check if any door part graphic definitions have been redefined */
+ // check if any door part graphic definitions have been redefined
for (j = 0; door_part_controls[j].door_token != -1; j++)
{
door_gfx_redefined = TRUE;
}
- /* check for old-style door graphic/animation modifications */
+ // check for old-style door graphic/animation modifications
if (!door_gfx_redefined)
{
struct GraphicInfo *g_part_2 = &graphic_info[part_2];
int num_door_steps, num_panel_steps;
- /* remove door part graphics other than the two default wings */
+ // remove door part graphics other than the two default wings
for (j = 0; door_part_controls[j].door_token != -1; j++)
{
g->bitmap = NULL;
}
- /* set graphics and screen positions of the default wings */
+ // set graphics and screen positions of the default wings
g_part_1->width = door_rect->width;
g_part_1->height = door_rect->height;
door->part_2.y += door_rect->height - door->height;
}
- /* set animation delays for the default wings and panels */
+ // set animation delays for the default wings and panels
door->part_1.step_delay = door->step_delay;
door->part_2.step_delay = door->step_delay;
door->panel.step_delay = door->step_delay;
- /* set animation draw order for the default wings */
+ // set animation draw order for the default wings
- door->part_1.sort_priority = 2; /* draw left wing over ... */
- door->part_2.sort_priority = 1; /* ... right wing */
+ door->part_1.sort_priority = 2; // draw left wing over ...
+ door->part_2.sort_priority = 1; // ... right wing
- /* set animation draw offset for the default wings */
+ // set animation draw offset for the default wings
if (door->anim_mode & ANIM_HORIZONTAL)
{
num_door_steps = g_part_1->height / door->step_offset;
}
- /* set animation draw offset for the default panels */
+ // set animation draw offset for the default panels
if (door->step_offset > 1)
{
}
}
-void InitDoors()
+void InitDoors(void)
{
int i;
struct DoorPartControlInfo *dpc = &door_part_controls[i];
struct DoorPartOrderInfo *dpo = &door_part_order[i];
- /* initialize "start_step_opening" and "start_step_closing", if needed */
+ // initialize "start_step_opening" and "start_step_closing", if needed
if (dpc->pos->start_step_opening == 0 &&
dpc->pos->start_step_closing == 0)
{
dpc->pos->start_step_closing = dpc->pos->start_step;
}
- /* fill structure for door part draw order (sorted below) */
+ // fill structure for door part draw order (sorted below)
dpo->nr = i;
dpo->sort_priority = dpc->pos->sort_priority;
}
- /* sort door part controls according to sort_priority and graphic number */
+ // sort door part controls according to sort_priority and graphic number
qsort(door_part_order, MAX_DOOR_PARTS,
sizeof(struct DoorPartOrderInfo), compareDoorPartOrderInfo);
}
return MoveDoor(door_state);
}
-unsigned int GetDoorState()
+unsigned int GetDoorState(void)
{
return MoveDoor(DOOR_GET_STATE);
}
return MoveDoor(door_state | DOOR_SET_STATE);
}
-int euclid(int a, int b)
+static int euclid(int a, int b)
{
return (b ? euclid(b, a % b) : a);
}
door_state &= ~DOOR_CLOSE_ALL;
}
- if (game_status == GAME_MODE_EDITOR)
+ if (game_status == GAME_MODE_EDITOR && !(door_state & DOOR_FORCE_ANIM))
door_state |= DOOR_NO_DELAY;
if (door_state & DOOR_ACTION)
}
else
{
- /* opening door sound has priority over simultaneously closing door */
+ // opening door sound has priority over simultaneously closing door
if (door_state & (DOOR_OPEN_1 | DOOR_OPEN_2))
{
PlayMenuSoundStereo(SND_DOOR_OPENING, SOUND_MIDDLE);
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
current_move_delay += max_step_delay;
- /* prevent OS (Windows) from complaining about program not responding */
+ // prevent OS (Windows) from complaining about program not responding
CheckQuitEvent();
}
if (door_part_done_all)
break;
}
+
+ if (!(door_state & DOOR_NO_DELAY))
+ {
+ // wait for specified door action post delay
+ if (door_state & DOOR_ACTION_1 && door_state & DOOR_ACTION_2)
+ door_delay_value = MAX(door_1.post_delay, door_2.post_delay);
+ else if (door_state & DOOR_ACTION_1)
+ door_delay_value = door_1.post_delay;
+ else if (door_state & DOOR_ACTION_2)
+ door_delay_value = door_2.post_delay;
+
+ while (!DelayReached(&door_delay, door_delay_value))
+ BackToFront();
+ }
}
if (door_state & DOOR_ACTION_1)
DrawMaskedBorder(REDRAW_DOOR_1);
DrawMaskedBorder(REDRAW_DOOR_2);
+ ClearAutoRepeatKeyEvents();
+
return (door1 | door2);
}
-static boolean useSpecialEditorDoor()
+static boolean useSpecialEditorDoor(void)
{
int graphic = IMG_GLOBAL_BORDER_EDITOR;
boolean redefined = getImageListEntryFromImageID(graphic)->redefined;
return TRUE;
}
-void DrawSpecialEditorDoor()
+void DrawSpecialEditorDoor(void)
{
struct GraphicInfo *gfx1 = &graphic_info[IMG_DOOR_2_TOP_BORDER_CORRECTION];
int top_border_width = gfx1->width;
if (!useSpecialEditorDoor())
return;
- /* draw bigger level editor toolbox window */
+ // draw bigger level editor toolbox window
BlitBitmap(gfx1->bitmap, drawto, gfx1->src_x, gfx1->src_y,
top_border_width, top_border_height, ex, ey - top_border_height);
BlitBitmap(graphic_info[IMG_GLOBAL_BORDER].bitmap, drawto, ex, vy,
redraw_mask |= REDRAW_ALL;
}
-void UndrawSpecialEditorDoor()
+void UndrawSpecialEditorDoor(void)
{
struct GraphicInfo *gfx1 = &graphic_info[IMG_DOOR_2_TOP_BORDER_CORRECTION];
int top_border_width = gfx1->width;
if (!useSpecialEditorDoor())
return;
- /* draw normal tape recorder window */
+ // draw normal tape recorder window
if (graphic_info[IMG_GLOBAL_BORDER].bitmap)
{
BlitBitmap(graphic_info[IMG_GLOBAL_BORDER].bitmap, drawto,
}
-/* ---------- new tool button stuff ---------------------------------------- */
+// ---------- new tool button stuff -------------------------------------------
static struct
{
int graphic;
struct TextPosInfo *pos;
int gadget_id;
+ boolean is_touch_button;
char *infotext;
} toolbutton_info[NUM_TOOL_BUTTONS] =
{
{
IMG_GFX_REQUEST_BUTTON_YES, &request.button.yes,
- TOOL_CTRL_ID_YES, "yes"
+ TOOL_CTRL_ID_YES, FALSE, "yes"
},
{
IMG_GFX_REQUEST_BUTTON_NO, &request.button.no,
- TOOL_CTRL_ID_NO, "no"
+ TOOL_CTRL_ID_NO, FALSE, "no"
},
{
IMG_GFX_REQUEST_BUTTON_CONFIRM, &request.button.confirm,
- TOOL_CTRL_ID_CONFIRM, "confirm"
+ TOOL_CTRL_ID_CONFIRM, FALSE, "confirm"
},
{
IMG_GFX_REQUEST_BUTTON_PLAYER_1, &request.button.player_1,
- TOOL_CTRL_ID_PLAYER_1, "player 1"
+ TOOL_CTRL_ID_PLAYER_1, FALSE, "player 1"
},
{
IMG_GFX_REQUEST_BUTTON_PLAYER_2, &request.button.player_2,
- TOOL_CTRL_ID_PLAYER_2, "player 2"
+ TOOL_CTRL_ID_PLAYER_2, FALSE, "player 2"
},
{
IMG_GFX_REQUEST_BUTTON_PLAYER_3, &request.button.player_3,
- TOOL_CTRL_ID_PLAYER_3, "player 3"
+ TOOL_CTRL_ID_PLAYER_3, FALSE, "player 3"
},
{
IMG_GFX_REQUEST_BUTTON_PLAYER_4, &request.button.player_4,
- TOOL_CTRL_ID_PLAYER_4, "player 4"
+ TOOL_CTRL_ID_PLAYER_4, FALSE, "player 4"
+ },
+ {
+ IMG_GFX_REQUEST_BUTTON_TOUCH_YES, &request.button.touch_yes,
+ TOOL_CTRL_ID_TOUCH_YES, TRUE, "yes"
+ },
+ {
+ IMG_GFX_REQUEST_BUTTON_TOUCH_NO, &request.button.touch_no,
+ TOOL_CTRL_ID_TOUCH_NO, TRUE, "no"
+ },
+ {
+ IMG_GFX_REQUEST_BUTTON_TOUCH_CONFIRM, &request.button.touch_confirm,
+ TOOL_CTRL_ID_TOUCH_CONFIRM, TRUE, "confirm"
}
};
-void CreateToolButtons()
+void CreateToolButtons(void)
{
int i;
for (i = 0; i < NUM_TOOL_BUTTONS; i++)
{
- struct GraphicInfo *gfx = &graphic_info[toolbutton_info[i].graphic];
+ int graphic = toolbutton_info[i].graphic;
+ struct GraphicInfo *gfx = &graphic_info[graphic];
struct TextPosInfo *pos = toolbutton_info[i].pos;
struct GadgetInfo *gi;
Bitmap *deco_bitmap = None;
int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
unsigned int event_mask = GD_EVENT_RELEASED;
- int dx = DX;
- int dy = DY;
+ 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 gd_yp = gfx->src_y + gfx->pressed_yoffset;
+ int x = pos->x;
+ int y = pos->y;
int id = i;
- if (global.use_envelope_request)
- setRequestPosition(&dx, &dy, TRUE);
+ if (global.use_envelope_request && !is_touch_button)
+ {
+ 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 ||
+ y < 0 || y + gfx->height > request.height)
+ {
+ if (id == TOOL_CTRL_ID_YES)
+ {
+ x = 0;
+ y = request.height - 2 * request.border_size - gfx->height;
+ }
+ else if (id == TOOL_CTRL_ID_NO)
+ {
+ x = request.width - 2 * request.border_size - gfx->width;
+ y = request.height - 2 * request.border_size - gfx->height;
+ }
+ else if (id == TOOL_CTRL_ID_CONFIRM)
+ {
+ x = (request.width - 2 * request.border_size - gfx->width) / 2;
+ y = request.height - 2 * request.border_size - gfx->height;
+ }
+ else if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
+ {
+ int player_nr = id - TOOL_CTRL_ID_PLAYER_1;
+
+ x = (request.width - 2 * request.border_size - gfx->width) / 2;
+ y = request.height - 2 * request.border_size - gfx->height * 2;
+
+ x += (player_nr == 3 ? -1 : player_nr == 1 ? +1 : 0) * gfx->width;
+ y += (player_nr == 0 ? -1 : player_nr == 2 ? +1 : 0) * gfx->height;
+ }
+ }
+ }
if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
{
}
gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_IMAGE_ID, graphic,
GDI_INFO_TEXT, toolbutton_info[i].infotext,
- GDI_X, dx + GDI_ACTIVE_POS(pos->x),
- GDI_Y, dy + GDI_ACTIVE_POS(pos->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;
}
}
-void FreeToolButtons()
+void FreeToolButtons(void)
{
int i;
FreeGadget(tool_gadget[i]);
}
-static void UnmapToolButtons()
+static void UnmapToolButtons(void)
{
int i;
static struct Mapping_EM_to_RND_object
{
int element_em;
- boolean is_rnd_to_em_mapping; /* unique mapping EM <-> RND */
- boolean is_backside; /* backside of moving element */
+ boolean is_rnd_to_em_mapping; // unique mapping EM <-> RND
+ boolean is_backside; // backside of moving element
int element_rnd;
int action;
int direction;
}
-em_object_mapping_list[] =
+em_object_mapping_list[GAME_TILE_MAX + 1] =
{
{
- Xblank, TRUE, FALSE,
+ Zborder, FALSE, FALSE,
EL_EMPTY, -1, -1
},
{
- Yacid_splash_eB, FALSE, FALSE,
- EL_ACID_SPLASH_RIGHT, -1, -1
- },
- {
- Yacid_splash_wB, FALSE, FALSE,
- EL_ACID_SPLASH_LEFT, -1, -1
+ Zplayer, FALSE, FALSE,
+ EL_EMPTY, -1, -1
},
-#ifdef EM_ENGINE_BAD_ROLL
{
- Xstone_force_e, FALSE, FALSE,
- EL_ROCK, -1, MV_BIT_RIGHT
+ Zbug, FALSE, FALSE,
+ EL_EMPTY, -1, -1
},
{
- Xstone_force_w, FALSE, FALSE,
- EL_ROCK, -1, MV_BIT_LEFT
+ Ztank, FALSE, FALSE,
+ EL_EMPTY, -1, -1
},
{
- Xnut_force_e, FALSE, FALSE,
- EL_NUT, -1, MV_BIT_RIGHT
+ Zeater, FALSE, FALSE,
+ EL_EMPTY, -1, -1
},
{
- Xnut_force_w, FALSE, FALSE,
- EL_NUT, -1, MV_BIT_LEFT
+ Zdynamite, FALSE, FALSE,
+ EL_EMPTY, -1, -1
},
{
- Xspring_force_e, FALSE, FALSE,
- EL_SPRING, -1, MV_BIT_RIGHT
+ Zboom, FALSE, FALSE,
+ EL_EMPTY, -1, -1
},
+
{
- Xspring_force_w, FALSE, FALSE,
- EL_SPRING, -1, MV_BIT_LEFT
+ Xchain, FALSE, FALSE,
+ EL_DEFAULT, ACTION_EXPLODING, -1
},
{
- Xemerald_force_e, FALSE, FALSE,
- EL_EMERALD, -1, MV_BIT_RIGHT
+ Xboom_bug, FALSE, FALSE,
+ EL_BUG, ACTION_EXPLODING, -1
},
{
- Xemerald_force_w, FALSE, FALSE,
- EL_EMERALD, -1, MV_BIT_LEFT
+ Xboom_tank, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_EXPLODING, -1
},
{
- Xdiamond_force_e, FALSE, FALSE,
- EL_DIAMOND, -1, MV_BIT_RIGHT
+ Xboom_android, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_OTHER, -1
},
{
- Xdiamond_force_w, FALSE, FALSE,
- EL_DIAMOND, -1, MV_BIT_LEFT
+ Xboom_1, FALSE, FALSE,
+ EL_DEFAULT, ACTION_EXPLODING, -1
},
{
- Xbomb_force_e, FALSE, FALSE,
- EL_BOMB, -1, MV_BIT_RIGHT
+ Xboom_2, FALSE, FALSE,
+ EL_DEFAULT, ACTION_EXPLODING, -1
},
+
{
- Xbomb_force_w, FALSE, FALSE,
- EL_BOMB, -1, MV_BIT_LEFT
+ Xblank, TRUE, FALSE,
+ EL_EMPTY, -1, -1
},
-#endif /* EM_ENGINE_BAD_ROLL */
{
- Xstone, TRUE, FALSE,
- EL_ROCK, -1, -1
+ Xsplash_e, FALSE, FALSE,
+ EL_ACID_SPLASH_RIGHT, -1, -1
},
{
- Xstone_pause, FALSE, FALSE,
- EL_ROCK, -1, -1
+ Xsplash_w, FALSE, FALSE,
+ EL_ACID_SPLASH_LEFT, -1, -1
},
+
{
- Xstone_fall, FALSE, FALSE,
- EL_ROCK, -1, -1
+ Xplant, TRUE, FALSE,
+ EL_EMC_PLANT, -1, -1
},
{
- Ystone_s, FALSE, FALSE,
- EL_ROCK, ACTION_FALLING, -1
+ Yplant, FALSE, FALSE,
+ EL_EMC_PLANT, -1, -1
},
+
{
- Ystone_sB, FALSE, TRUE,
- EL_ROCK, ACTION_FALLING, -1
+ Xacid_1, TRUE, FALSE,
+ EL_ACID, -1, -1
},
{
- Ystone_e, FALSE, FALSE,
- EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT
+ Xacid_2, FALSE, FALSE,
+ EL_ACID, -1, -1
},
{
- Ystone_eB, FALSE, TRUE,
- EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT
+ Xacid_3, FALSE, FALSE,
+ EL_ACID, -1, -1
},
{
- Ystone_w, FALSE, FALSE,
- EL_ROCK, ACTION_MOVING, MV_BIT_LEFT
+ Xacid_4, FALSE, FALSE,
+ EL_ACID, -1, -1
},
{
- Ystone_wB, FALSE, TRUE,
- EL_ROCK, ACTION_MOVING, MV_BIT_LEFT
+ Xacid_5, FALSE, FALSE,
+ EL_ACID, -1, -1
},
{
- Xnut, TRUE, FALSE,
- EL_NUT, -1, -1
+ Xacid_6, FALSE, FALSE,
+ EL_ACID, -1, -1
},
{
- Xnut_pause, FALSE, FALSE,
- EL_NUT, -1, -1
+ Xacid_7, FALSE, FALSE,
+ EL_ACID, -1, -1
},
{
- Xnut_fall, FALSE, FALSE,
- EL_NUT, -1, -1
+ Xacid_8, FALSE, FALSE,
+ EL_ACID, -1, -1
},
+
{
- Ynut_s, FALSE, FALSE,
- EL_NUT, ACTION_FALLING, -1
+ Xfake_acid_1, TRUE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
- Ynut_sB, FALSE, TRUE,
- EL_NUT, ACTION_FALLING, -1
+ Xfake_acid_2, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
- Ynut_e, FALSE, FALSE,
- EL_NUT, ACTION_MOVING, MV_BIT_RIGHT
+ Xfake_acid_3, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
- Ynut_eB, FALSE, TRUE,
- EL_NUT, ACTION_MOVING, MV_BIT_RIGHT
+ Xfake_acid_4, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
- Ynut_w, FALSE, FALSE,
- EL_NUT, ACTION_MOVING, MV_BIT_LEFT
+ Xfake_acid_5, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
- Ynut_wB, FALSE, TRUE,
- EL_NUT, ACTION_MOVING, MV_BIT_LEFT
+ Xfake_acid_6, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
- Xbug_n, TRUE, FALSE,
- EL_BUG_UP, -1, -1
+ Xfake_acid_7, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
- Xbug_e, TRUE, FALSE,
- EL_BUG_RIGHT, -1, -1
+ Xfake_acid_8, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
+
{
- Xbug_s, TRUE, FALSE,
- EL_BUG_DOWN, -1, -1
+ Xfake_acid_1_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
- Xbug_w, TRUE, FALSE,
- EL_BUG_LEFT, -1, -1
+ Xfake_acid_2_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
- Xbug_gon, FALSE, FALSE,
- EL_BUG_UP, -1, -1
+ Xfake_acid_3_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
- Xbug_goe, FALSE, FALSE,
- EL_BUG_RIGHT, -1, -1
+ Xfake_acid_4_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
- Xbug_gos, FALSE, FALSE,
- EL_BUG_DOWN, -1, -1
+ Xfake_acid_5_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
- Xbug_gow, FALSE, FALSE,
- EL_BUG_LEFT, -1, -1
+ Xfake_acid_6_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
- Ybug_n, FALSE, FALSE,
- EL_BUG, ACTION_MOVING, MV_BIT_UP
+ Xfake_acid_7_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
- Ybug_nB, FALSE, TRUE,
- EL_BUG, ACTION_MOVING, MV_BIT_UP
+ Xfake_acid_8_player, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
+
{
- Ybug_e, FALSE, FALSE,
- EL_BUG, ACTION_MOVING, MV_BIT_RIGHT
+ Xgrass, TRUE, FALSE,
+ EL_EMC_GRASS, -1, -1
},
{
- Ybug_eB, FALSE, TRUE,
- EL_BUG, ACTION_MOVING, MV_BIT_RIGHT
+ Ygrass_nB, FALSE, FALSE,
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_UP
},
{
- Ybug_s, FALSE, FALSE,
- EL_BUG, ACTION_MOVING, MV_BIT_DOWN
+ Ygrass_eB, FALSE, FALSE,
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_RIGHT
},
{
- Ybug_sB, FALSE, TRUE,
- EL_BUG, ACTION_MOVING, MV_BIT_DOWN
+ Ygrass_sB, FALSE, FALSE,
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_DOWN
},
{
- Ybug_w, FALSE, FALSE,
- EL_BUG, ACTION_MOVING, MV_BIT_LEFT
- },
- {
- 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_n, TRUE, FALSE,
- EL_SPACESHIP_UP, -1, -1
- },
- {
- Xtank_e, TRUE, FALSE,
- EL_SPACESHIP_RIGHT, -1, -1
- },
- {
- Xtank_s, TRUE, FALSE,
- EL_SPACESHIP_DOWN, -1, -1
- },
- {
- Xtank_w, TRUE, FALSE,
- EL_SPACESHIP_LEFT, -1, -1
- },
- {
- Xtank_gon, FALSE, FALSE,
- EL_SPACESHIP_UP, -1, -1
- },
- {
- Xtank_goe, FALSE, FALSE,
- EL_SPACESHIP_RIGHT, -1, -1
- },
- {
- Xtank_gos, FALSE, FALSE,
- EL_SPACESHIP_DOWN, -1, -1
- },
- {
- Xtank_gow, FALSE, FALSE,
- EL_SPACESHIP_LEFT, -1, -1
- },
- {
- Ytank_n, FALSE, FALSE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_UP
- },
- {
- Ytank_nB, FALSE, TRUE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_UP
- },
- {
- Ytank_e, FALSE, FALSE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_RIGHT
- },
- {
- Ytank_eB, FALSE, TRUE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_RIGHT
- },
- {
- Ytank_s, FALSE, FALSE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_DOWN
- },
- {
- Ytank_sB, FALSE, TRUE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_DOWN
- },
- {
- Ytank_w, FALSE, FALSE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_LEFT
- },
- {
- Ytank_wB, FALSE, TRUE,
- EL_SPACESHIP, ACTION_MOVING, MV_BIT_LEFT
- },
- {
- Ytank_w_n, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_LEFT, MV_BIT_UP
- },
- {
- Ytank_n_e, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_UP, MV_BIT_RIGHT
- },
- {
- Ytank_e_s, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_RIGHT, MV_BIT_DOWN
- },
- {
- Ytank_s_w, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_DOWN, MV_BIT_LEFT
- },
- {
- Ytank_e_n, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_RIGHT, MV_BIT_UP
+ Ygrass_wB, FALSE, FALSE,
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_LEFT
},
+
{
- Ytank_s_e, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_DOWN, MV_BIT_RIGHT
+ Xdirt, TRUE, FALSE,
+ EL_SAND, -1, -1
},
{
- Ytank_w_s, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_LEFT, MV_BIT_DOWN
+ Ydirt_nB, FALSE, FALSE,
+ EL_SAND, ACTION_DIGGING, MV_BIT_UP
},
{
- Ytank_n_w, FALSE, FALSE,
- EL_SPACESHIP, ACTION_TURNING_FROM_UP, MV_BIT_LEFT
+ Ydirt_eB, FALSE, FALSE,
+ EL_SAND, ACTION_DIGGING, MV_BIT_RIGHT
},
{
- Ytank_stone, FALSE, FALSE,
- EL_SPACESHIP, ACTION_SMASHED_BY_ROCK, -1
+ Ydirt_sB, FALSE, FALSE,
+ EL_SAND, ACTION_DIGGING, MV_BIT_DOWN
},
{
- Ytank_spring, FALSE, FALSE,
- EL_SPACESHIP, ACTION_SMASHED_BY_SPRING, -1
+ Ydirt_wB, FALSE, FALSE,
+ EL_SAND, ACTION_DIGGING, MV_BIT_LEFT
},
+
{
Xandroid, TRUE, FALSE,
EL_EMC_ANDROID, ACTION_ACTIVE, -1
Yandroid_nwB, FALSE, TRUE,
EL_EMC_ANDROID, ACTION_SHRINKING, MV_BIT_UPLEFT
},
- {
- Xspring, TRUE, FALSE,
- EL_SPRING, -1, -1
- },
- {
- Xspring_pause, FALSE, FALSE,
- EL_SPRING, -1, -1
- },
- {
- Xspring_e, FALSE, FALSE,
- EL_SPRING, -1, -1
- },
- {
- Xspring_w, FALSE, FALSE,
- EL_SPRING, -1, -1
- },
- {
- Xspring_fall, FALSE, FALSE,
- EL_SPRING, -1, -1
- },
- {
- Yspring_s, FALSE, FALSE,
- EL_SPRING, ACTION_FALLING, -1
- },
- {
- Yspring_sB, FALSE, TRUE,
- EL_SPRING, ACTION_FALLING, -1
- },
- {
- Yspring_e, FALSE, FALSE,
- EL_SPRING, ACTION_MOVING, MV_BIT_RIGHT
- },
- {
- Yspring_eB, FALSE, TRUE,
- EL_SPRING, ACTION_MOVING, MV_BIT_RIGHT
- },
- {
- Yspring_w, FALSE, FALSE,
- EL_SPRING, ACTION_MOVING, MV_BIT_LEFT
- },
- {
- Yspring_wB, FALSE, TRUE,
- EL_SPRING, ACTION_MOVING, MV_BIT_LEFT
- },
- {
- Yspring_kill_e, FALSE, FALSE,
- EL_SPRING, ACTION_EATING, MV_BIT_RIGHT
- },
- {
- Yspring_kill_eB, FALSE, TRUE,
- EL_SPRING, ACTION_EATING, MV_BIT_RIGHT
- },
- {
- Yspring_kill_w, FALSE, FALSE,
- EL_SPRING, ACTION_EATING, MV_BIT_LEFT
- },
- {
- Yspring_kill_wB, FALSE, TRUE,
- EL_SPRING, ACTION_EATING, MV_BIT_LEFT
- },
+
{
Xeater_n, TRUE, FALSE,
EL_YAMYAM_UP, -1, -1
Yeater_spring, FALSE, FALSE,
EL_YAMYAM, ACTION_SMASHED_BY_SPRING, -1
},
+
{
Xalien, TRUE, FALSE,
EL_ROBOT, -1, -1
Yalien_spring, FALSE, FALSE,
EL_ROBOT, ACTION_SMASHED_BY_SPRING, -1
},
+
{
- Xemerald, TRUE, FALSE,
- EL_EMERALD, -1, -1
+ Xbug_1_n, TRUE, FALSE,
+ EL_BUG_UP, -1, -1
},
{
- Xemerald_pause, FALSE, FALSE,
- EL_EMERALD, -1, -1
+ Xbug_1_e, TRUE, FALSE,
+ EL_BUG_RIGHT, -1, -1
},
{
- Xemerald_fall, FALSE, FALSE,
- EL_EMERALD, -1, -1
+ Xbug_1_s, TRUE, FALSE,
+ EL_BUG_DOWN, -1, -1
},
{
- Xemerald_shine, FALSE, FALSE,
- EL_EMERALD, ACTION_TWINKLING, -1
+ Xbug_1_w, TRUE, FALSE,
+ EL_BUG_LEFT, -1, -1
},
{
- Yemerald_s, FALSE, FALSE,
- EL_EMERALD, ACTION_FALLING, -1
+ Xbug_2_n, FALSE, FALSE,
+ EL_BUG_UP, -1, -1
},
{
- Yemerald_sB, FALSE, TRUE,
- EL_EMERALD, ACTION_FALLING, -1
+ Xbug_2_e, FALSE, FALSE,
+ EL_BUG_RIGHT, -1, -1
},
{
- Yemerald_e, FALSE, FALSE,
- EL_EMERALD, ACTION_MOVING, MV_BIT_RIGHT
+ Xbug_2_s, FALSE, FALSE,
+ EL_BUG_DOWN, -1, -1
},
{
- Yemerald_eB, FALSE, TRUE,
- EL_EMERALD, ACTION_MOVING, MV_BIT_RIGHT
+ Xbug_2_w, FALSE, FALSE,
+ EL_BUG_LEFT, -1, -1
},
{
- Yemerald_w, FALSE, FALSE,
- EL_EMERALD, ACTION_MOVING, MV_BIT_LEFT
+ Ybug_n, FALSE, FALSE,
+ EL_BUG, ACTION_MOVING, MV_BIT_UP
},
{
- Yemerald_wB, FALSE, TRUE,
- EL_EMERALD, ACTION_MOVING, MV_BIT_LEFT
+ Ybug_nB, FALSE, TRUE,
+ EL_BUG, ACTION_MOVING, MV_BIT_UP
},
{
- Yemerald_eat, FALSE, FALSE,
- EL_EMERALD, ACTION_COLLECTING, -1
+ Ybug_e, FALSE, FALSE,
+ EL_BUG, ACTION_MOVING, MV_BIT_RIGHT
},
{
- Yemerald_stone, FALSE, FALSE,
- EL_NUT, ACTION_BREAKING, -1
+ Ybug_eB, FALSE, TRUE,
+ EL_BUG, ACTION_MOVING, MV_BIT_RIGHT
},
{
- Xdiamond, TRUE, FALSE,
- EL_DIAMOND, -1, -1
+ Ybug_s, FALSE, FALSE,
+ EL_BUG, ACTION_MOVING, MV_BIT_DOWN
},
{
- Xdiamond_pause, FALSE, FALSE,
- EL_DIAMOND, -1, -1
+ Ybug_sB, FALSE, TRUE,
+ EL_BUG, ACTION_MOVING, MV_BIT_DOWN
},
{
- Xdiamond_fall, FALSE, FALSE,
- EL_DIAMOND, -1, -1
+ Ybug_w, FALSE, FALSE,
+ EL_BUG, ACTION_MOVING, MV_BIT_LEFT
},
{
- Xdiamond_shine, FALSE, FALSE,
- EL_DIAMOND, ACTION_TWINKLING, -1
- },
+ Ybug_wB, FALSE, TRUE,
+ EL_BUG, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ 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
EL_DIAMOND, ACTION_MOVING, MV_BIT_LEFT
},
{
- Ydiamond_eat, FALSE, FALSE,
+ Ydiamond_blank, FALSE, FALSE,
EL_DIAMOND, ACTION_COLLECTING, -1
},
{
Ydiamond_stone, FALSE, FALSE,
EL_DIAMOND, ACTION_SMASHED_BY_ROCK, -1
},
+
{
- Xdrip_fall, TRUE, FALSE,
- EL_AMOEBA_DROP, -1, -1
+ Xstone, TRUE, FALSE,
+ EL_ROCK, -1, -1
},
{
- Xdrip_stretch, FALSE, FALSE,
- EL_AMOEBA_DROP, ACTION_FALLING, -1
+ Xstone_pause, FALSE, FALSE,
+ EL_ROCK, -1, -1
},
{
- Xdrip_stretchB, FALSE, TRUE,
- EL_AMOEBA_DROP, ACTION_FALLING, -1
+ Xstone_fall, FALSE, FALSE,
+ EL_ROCK, -1, -1
},
{
- Xdrip_eat, FALSE, FALSE,
- EL_AMOEBA_DROP, ACTION_GROWING, -1
+ Ystone_s, FALSE, FALSE,
+ EL_ROCK, ACTION_FALLING, -1
},
{
- Ydrip_s1, FALSE, FALSE,
- EL_AMOEBA_DROP, ACTION_FALLING, -1
+ Ystone_sB, FALSE, TRUE,
+ EL_ROCK, ACTION_FALLING, -1
},
{
- Ydrip_s1B, FALSE, TRUE,
- EL_AMOEBA_DROP, ACTION_FALLING, -1
+ Ystone_e, FALSE, FALSE,
+ EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT
},
{
- Ydrip_s2, FALSE, FALSE,
- EL_AMOEBA_DROP, ACTION_FALLING, -1
+ Ystone_eB, FALSE, TRUE,
+ EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT
},
{
- Ydrip_s2B, FALSE, TRUE,
- EL_AMOEBA_DROP, ACTION_FALLING, -1
+ Ystone_w, FALSE, FALSE,
+ EL_ROCK, ACTION_MOVING, MV_BIT_LEFT
},
+ {
+ Ystone_wB, FALSE, TRUE,
+ EL_ROCK, ACTION_MOVING, MV_BIT_LEFT
+ },
+
{
Xbomb, TRUE, FALSE,
EL_BOMB, -1, -1
EL_BOMB, ACTION_MOVING, MV_BIT_LEFT
},
{
- Ybomb_eat, FALSE, FALSE,
+ Ybomb_blank, FALSE, FALSE,
EL_BOMB, ACTION_ACTIVATING, -1
},
+
{
- Xballoon, TRUE, FALSE,
- EL_BALLOON, -1, -1
+ Xnut, TRUE, FALSE,
+ EL_NUT, -1, -1
},
{
- Yballoon_n, FALSE, FALSE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_UP
+ Xnut_pause, FALSE, FALSE,
+ EL_NUT, -1, -1
},
{
- Yballoon_nB, FALSE, TRUE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_UP
+ Xnut_fall, FALSE, FALSE,
+ EL_NUT, -1, -1
},
{
- Yballoon_e, FALSE, FALSE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_RIGHT
+ Ynut_s, FALSE, FALSE,
+ EL_NUT, ACTION_FALLING, -1
},
{
- Yballoon_eB, FALSE, TRUE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_RIGHT
+ Ynut_sB, FALSE, TRUE,
+ EL_NUT, ACTION_FALLING, -1
},
{
- Yballoon_s, FALSE, FALSE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_DOWN
+ Ynut_e, FALSE, FALSE,
+ EL_NUT, ACTION_MOVING, MV_BIT_RIGHT
},
{
- Yballoon_sB, FALSE, TRUE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_DOWN
+ Ynut_eB, FALSE, TRUE,
+ EL_NUT, ACTION_MOVING, MV_BIT_RIGHT
},
{
- Yballoon_w, FALSE, FALSE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_LEFT
+ Ynut_w, FALSE, FALSE,
+ EL_NUT, ACTION_MOVING, MV_BIT_LEFT
},
{
- Yballoon_wB, FALSE, TRUE,
- EL_BALLOON, ACTION_MOVING, MV_BIT_LEFT
+ Ynut_wB, FALSE, TRUE,
+ EL_NUT, ACTION_MOVING, MV_BIT_LEFT
},
{
- Xgrass, TRUE, FALSE,
- EL_EMC_GRASS, -1, -1
+ Ynut_stone, FALSE, FALSE,
+ EL_NUT, ACTION_BREAKING, -1
},
+
{
- Ygrass_nB, FALSE, FALSE,
- EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_UP
+ Xspring, TRUE, FALSE,
+ EL_SPRING, -1, -1
},
{
- Ygrass_eB, FALSE, FALSE,
- EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_RIGHT
+ Xspring_pause, FALSE, FALSE,
+ EL_SPRING, -1, -1
},
{
- Ygrass_sB, FALSE, FALSE,
- EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_DOWN
+ Xspring_e, TRUE, FALSE,
+ EL_SPRING_RIGHT, -1, -1
},
{
- Ygrass_wB, FALSE, FALSE,
- EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_LEFT
+ Xspring_w, TRUE, FALSE,
+ EL_SPRING_LEFT, -1, -1
},
{
- Xdirt, TRUE, FALSE,
- EL_SAND, -1, -1
+ Xspring_fall, FALSE, FALSE,
+ EL_SPRING, -1, -1
},
{
- Ydirt_nB, FALSE, FALSE,
- EL_SAND, ACTION_DIGGING, MV_BIT_UP
+ Yspring_s, FALSE, FALSE,
+ EL_SPRING, ACTION_FALLING, -1
},
{
- Ydirt_eB, FALSE, FALSE,
- EL_SAND, ACTION_DIGGING, MV_BIT_RIGHT
+ Yspring_sB, FALSE, TRUE,
+ EL_SPRING, ACTION_FALLING, -1
},
{
- Ydirt_sB, FALSE, FALSE,
- EL_SAND, ACTION_DIGGING, MV_BIT_DOWN
+ Yspring_e, FALSE, FALSE,
+ EL_SPRING, ACTION_MOVING, MV_BIT_RIGHT
},
{
- Ydirt_wB, FALSE, FALSE,
- EL_SAND, ACTION_DIGGING, MV_BIT_LEFT
+ Yspring_eB, FALSE, TRUE,
+ EL_SPRING, ACTION_MOVING, MV_BIT_RIGHT
},
{
- Xacid_ne, TRUE, FALSE,
- EL_ACID_POOL_TOPRIGHT, -1, -1
+ Yspring_w, FALSE, FALSE,
+ EL_SPRING, ACTION_MOVING, MV_BIT_LEFT
},
{
- Xacid_se, TRUE, FALSE,
- EL_ACID_POOL_BOTTOMRIGHT, -1, -1
+ Yspring_wB, FALSE, TRUE,
+ EL_SPRING, ACTION_MOVING, MV_BIT_LEFT
},
{
- Xacid_s, TRUE, FALSE,
- EL_ACID_POOL_BOTTOM, -1, -1
+ Yspring_alien_e, FALSE, FALSE,
+ EL_SPRING, ACTION_EATING, MV_BIT_RIGHT
},
{
- Xacid_sw, TRUE, FALSE,
- EL_ACID_POOL_BOTTOMLEFT, -1, -1
+ Yspring_alien_eB, FALSE, TRUE,
+ EL_SPRING, ACTION_EATING, MV_BIT_RIGHT
},
{
- Xacid_nw, TRUE, FALSE,
- EL_ACID_POOL_TOPLEFT, -1, -1
+ Yspring_alien_w, FALSE, FALSE,
+ EL_SPRING, ACTION_EATING, MV_BIT_LEFT
},
{
- Xacid_1, TRUE, FALSE,
- EL_ACID, -1, -1
+ Yspring_alien_wB, FALSE, TRUE,
+ EL_SPRING, ACTION_EATING, MV_BIT_LEFT
},
+
{
- Xacid_2, FALSE, FALSE,
- EL_ACID, -1, -1
+ Xpush_emerald_e, FALSE, FALSE,
+ EL_EMERALD, -1, MV_BIT_RIGHT
},
{
- Xacid_3, FALSE, FALSE,
- EL_ACID, -1, -1
+ Xpush_emerald_w, FALSE, FALSE,
+ EL_EMERALD, -1, MV_BIT_LEFT
},
{
- Xacid_4, FALSE, FALSE,
- EL_ACID, -1, -1
+ Xpush_diamond_e, FALSE, FALSE,
+ EL_DIAMOND, -1, MV_BIT_RIGHT
},
{
- Xacid_5, FALSE, FALSE,
- EL_ACID, -1, -1
+ Xpush_diamond_w, FALSE, FALSE,
+ EL_DIAMOND, -1, MV_BIT_LEFT
},
{
- Xacid_6, FALSE, FALSE,
- EL_ACID, -1, -1
+ Xpush_stone_e, FALSE, FALSE,
+ EL_ROCK, -1, MV_BIT_RIGHT
},
{
- Xacid_7, FALSE, FALSE,
- EL_ACID, -1, -1
+ Xpush_stone_w, FALSE, FALSE,
+ EL_ROCK, -1, MV_BIT_LEFT
},
{
- Xacid_8, FALSE, FALSE,
- EL_ACID, -1, -1
+ Xpush_bomb_e, FALSE, FALSE,
+ EL_BOMB, -1, MV_BIT_RIGHT
},
{
- Xball_1, TRUE, FALSE,
- EL_EMC_MAGIC_BALL, -1, -1
+ Xpush_bomb_w, FALSE, FALSE,
+ EL_BOMB, -1, MV_BIT_LEFT
},
{
- Xball_1B, FALSE, FALSE,
- EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
+ Xpush_nut_e, FALSE, FALSE,
+ EL_NUT, -1, MV_BIT_RIGHT
},
{
- Xball_2, FALSE, FALSE,
- EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
+ Xpush_nut_w, FALSE, FALSE,
+ EL_NUT, -1, MV_BIT_LEFT
},
{
- Xball_2B, FALSE, FALSE,
- EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
+ Xpush_spring_e, FALSE, FALSE,
+ EL_SPRING_RIGHT, -1, MV_BIT_RIGHT
},
{
- Yball_eat, FALSE, FALSE,
- EL_EMC_MAGIC_BALL, ACTION_DROPPING, -1
+ Xpush_spring_w, FALSE, FALSE,
+ EL_SPRING_LEFT, -1, MV_BIT_LEFT
},
+
{
- Ykey_1_eat, FALSE, FALSE,
- EL_EM_KEY_1, ACTION_COLLECTING, -1
+ Xdynamite, TRUE, FALSE,
+ EL_EM_DYNAMITE, -1, -1
},
{
- Ykey_2_eat, FALSE, FALSE,
- EL_EM_KEY_2, ACTION_COLLECTING, -1
+ Ydynamite_blank, FALSE, FALSE,
+ EL_EM_DYNAMITE, ACTION_COLLECTING, -1
},
{
- Ykey_3_eat, FALSE, FALSE,
- EL_EM_KEY_3, ACTION_COLLECTING, -1
+ Xdynamite_1, TRUE, FALSE,
+ EL_EM_DYNAMITE_ACTIVE, -1, -1
},
{
- Ykey_4_eat, FALSE, FALSE,
- EL_EM_KEY_4, ACTION_COLLECTING, -1
+ Xdynamite_2, FALSE, FALSE,
+ EL_EM_DYNAMITE_ACTIVE, -1, -1
},
{
- Ykey_5_eat, FALSE, FALSE,
- EL_EMC_KEY_5, ACTION_COLLECTING, -1
+ Xdynamite_3, FALSE, FALSE,
+ EL_EM_DYNAMITE_ACTIVE, -1, -1
},
{
- Ykey_6_eat, FALSE, FALSE,
- EL_EMC_KEY_6, ACTION_COLLECTING, -1
+ Xdynamite_4, FALSE, FALSE,
+ EL_EM_DYNAMITE_ACTIVE, -1, -1
},
+
{
- Ykey_7_eat, FALSE, FALSE,
- EL_EMC_KEY_7, ACTION_COLLECTING, -1
+ Xkey_1, TRUE, FALSE,
+ EL_EM_KEY_1, -1, -1
},
{
- Ykey_8_eat, FALSE, FALSE,
- EL_EMC_KEY_8, ACTION_COLLECTING, -1
+ Xkey_2, TRUE, FALSE,
+ EL_EM_KEY_2, -1, -1
},
{
- Ylenses_eat, FALSE, FALSE,
- EL_EMC_LENSES, ACTION_COLLECTING, -1
+ Xkey_3, TRUE, FALSE,
+ EL_EM_KEY_3, -1, -1
},
{
- Ymagnify_eat, FALSE, FALSE,
- EL_EMC_MAGNIFIER, ACTION_COLLECTING, -1
+ Xkey_4, TRUE, FALSE,
+ EL_EM_KEY_4, -1, -1
},
{
- Ygrass_eat, FALSE, FALSE,
- EL_EMC_GRASS, ACTION_SNAPPING, -1
+ Xkey_5, TRUE, FALSE,
+ EL_EMC_KEY_5, -1, -1
},
{
- Ydirt_eat, FALSE, FALSE,
- EL_SAND, ACTION_SNAPPING, -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
},
{
- Xgrow_ns, TRUE, FALSE,
- EL_EXPANDABLE_WALL_VERTICAL, -1, -1
+ Yballoon_wB, FALSE, TRUE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_LEFT
},
+
{
- Ygrow_ns_eat, FALSE, FALSE,
- EL_EXPANDABLE_WALL_VERTICAL, ACTION_GROWING, -1
+ Xball_1, TRUE, FALSE,
+ EL_EMC_MAGIC_BALL, -1, -1
},
{
- Xgrow_ew, TRUE, FALSE,
- EL_EXPANDABLE_WALL_HORIZONTAL, -1, -1
+ Yball_1, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
},
{
- Ygrow_ew_eat, FALSE, FALSE,
- EL_EXPANDABLE_WALL_HORIZONTAL, ACTION_GROWING, -1
+ Xball_2, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
},
{
- Xwonderwall, TRUE, FALSE,
- EL_MAGIC_WALL, -1, -1
+ Yball_2, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
},
{
- XwonderwallB, FALSE, FALSE,
- EL_MAGIC_WALL, ACTION_ACTIVE, -1
+ Yball_blank, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL, ACTION_DROPPING, -1
},
+
{
Xamoeba_1, TRUE, FALSE,
EL_AMOEBA_DRY, ACTION_OTHER, -1
Xamoeba_8, FALSE, FALSE,
EL_AMOEBA_WET, ACTION_OTHER, -1
},
+
{
- Xdoor_1, TRUE, FALSE,
- EL_EM_GATE_1, -1, -1
- },
- {
- Xdoor_2, TRUE, FALSE,
- EL_EM_GATE_2, -1, -1
- },
- {
- Xdoor_3, TRUE, FALSE,
- EL_EM_GATE_3, -1, -1
- },
- {
- Xdoor_4, TRUE, FALSE,
- EL_EM_GATE_4, -1, -1
- },
- {
- Xdoor_5, TRUE, FALSE,
- EL_EMC_GATE_5, -1, -1
- },
- {
- Xdoor_6, TRUE, FALSE,
- EL_EMC_GATE_6, -1, -1
- },
- {
- Xdoor_7, TRUE, FALSE,
- EL_EMC_GATE_7, -1, -1
- },
- {
- Xdoor_8, TRUE, FALSE,
- EL_EMC_GATE_8, -1, -1
- },
- {
- Xkey_1, TRUE, FALSE,
- EL_EM_KEY_1, -1, -1
- },
- {
- Xkey_2, TRUE, FALSE,
- EL_EM_KEY_2, -1, -1
+ Xdrip, TRUE, FALSE,
+ EL_AMOEBA_DROP, ACTION_GROWING, -1
},
{
- Xkey_3, TRUE, FALSE,
- EL_EM_KEY_3, -1, -1
+ Xdrip_fall, FALSE, FALSE,
+ EL_AMOEBA_DROP, -1, -1
},
{
- Xkey_4, TRUE, FALSE,
- EL_EM_KEY_4, -1, -1
+ Xdrip_stretch, FALSE, FALSE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
},
{
- Xkey_5, TRUE, FALSE,
- EL_EMC_KEY_5, -1, -1
+ Xdrip_stretchB, FALSE, TRUE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
},
{
- Xkey_6, TRUE, FALSE,
- EL_EMC_KEY_6, -1, -1
+ Ydrip_1_s, FALSE, FALSE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
},
{
- Xkey_7, TRUE, FALSE,
- EL_EMC_KEY_7, -1, -1
+ Ydrip_1_sB, FALSE, TRUE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
},
{
- Xkey_8, TRUE, FALSE,
- EL_EMC_KEY_8, -1, -1
+ Ydrip_2_s, FALSE, FALSE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
},
{
- Xwind_n, TRUE, FALSE,
- EL_BALLOON_SWITCH_UP, -1, -1
+ Ydrip_2_sB, FALSE, TRUE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
},
+
{
- Xwind_e, TRUE, FALSE,
- EL_BALLOON_SWITCH_RIGHT, -1, -1
+ Xwonderwall, TRUE, FALSE,
+ EL_MAGIC_WALL, -1, -1
},
{
- Xwind_s, TRUE, FALSE,
- EL_BALLOON_SWITCH_DOWN, -1, -1
+ Ywonderwall, FALSE, FALSE,
+ EL_MAGIC_WALL, ACTION_ACTIVE, -1
},
+
{
- Xwind_w, TRUE, FALSE,
- EL_BALLOON_SWITCH_LEFT, -1, -1
+ Xwheel, TRUE, FALSE,
+ EL_ROBOT_WHEEL, -1, -1
},
{
- Xwind_nesw, TRUE, FALSE,
- EL_BALLOON_SWITCH_ANY, -1, -1
+ Ywheel, FALSE, FALSE,
+ EL_ROBOT_WHEEL, ACTION_ACTIVE, -1
},
+
{
- Xwind_stop, TRUE, FALSE,
- EL_BALLOON_SWITCH_NONE, -1, -1
+ Xswitch, TRUE, FALSE,
+ EL_EMC_MAGIC_BALL_SWITCH, -1, -1
},
{
- Xexit, TRUE, FALSE,
- EL_EM_EXIT_CLOSED, -1, -1
+ Yswitch, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL_SWITCH, ACTION_ACTIVE, -1
},
+
{
- Xexit_1, TRUE, FALSE,
- EL_EM_EXIT_OPEN, -1, -1
+ Xbumper, TRUE, FALSE,
+ EL_EMC_SPRING_BUMPER, -1, -1
},
{
- Xexit_2, FALSE, FALSE,
- EL_EM_EXIT_OPEN, -1, -1
+ Ybumper, FALSE, FALSE,
+ EL_EMC_SPRING_BUMPER, ACTION_ACTIVE, -1
},
+
{
- Xexit_3, FALSE, FALSE,
- EL_EM_EXIT_OPEN, -1, -1
+ Xacid_nw, TRUE, FALSE,
+ EL_ACID_POOL_TOPLEFT, -1, -1
},
{
- Xdynamite, TRUE, FALSE,
- EL_EM_DYNAMITE, -1, -1
+ Xacid_ne, TRUE, FALSE,
+ EL_ACID_POOL_TOPRIGHT, -1, -1
},
{
- Ydynamite_eat, FALSE, FALSE,
- EL_EM_DYNAMITE, ACTION_COLLECTING, -1
+ Xacid_sw, TRUE, FALSE,
+ EL_ACID_POOL_BOTTOMLEFT, -1, -1
},
{
- Xdynamite_1, TRUE, FALSE,
- EL_EM_DYNAMITE_ACTIVE, -1, -1
+ Xacid_s, TRUE, FALSE,
+ EL_ACID_POOL_BOTTOM, -1, -1
},
{
- Xdynamite_2, FALSE, FALSE,
- EL_EM_DYNAMITE_ACTIVE, -1, -1
+ Xacid_se, TRUE, FALSE,
+ EL_ACID_POOL_BOTTOMRIGHT, -1, -1
},
+
{
- Xdynamite_3, FALSE, FALSE,
- EL_EM_DYNAMITE_ACTIVE, -1, -1
+ Xfake_blank, TRUE, FALSE,
+ EL_INVISIBLE_WALL, -1, -1
},
{
- Xdynamite_4, FALSE, FALSE,
- EL_EM_DYNAMITE_ACTIVE, -1, -1
+ Yfake_blank, FALSE, FALSE,
+ EL_INVISIBLE_WALL, ACTION_ACTIVE, -1
},
+
{
- Xbumper, TRUE, FALSE,
- EL_EMC_SPRING_BUMPER, -1, -1
+ Xfake_grass, TRUE, FALSE,
+ EL_EMC_FAKE_GRASS, -1, -1
},
{
- XbumperB, FALSE, FALSE,
- EL_EMC_SPRING_BUMPER, ACTION_ACTIVE, -1
+ Yfake_grass, FALSE, FALSE,
+ EL_EMC_FAKE_GRASS, ACTION_ACTIVE, -1
},
+
{
- Xwheel, TRUE, FALSE,
- EL_ROBOT_WHEEL, -1, -1
+ Xfake_amoeba, TRUE, FALSE,
+ EL_EMC_DRIPPER, -1, -1
},
{
- XwheelB, FALSE, FALSE,
- EL_ROBOT_WHEEL, ACTION_ACTIVE, -1
+ Yfake_amoeba, FALSE, FALSE,
+ EL_EMC_DRIPPER, ACTION_ACTIVE, -1
},
+
{
- Xswitch, TRUE, FALSE,
- EL_EMC_MAGIC_BALL_SWITCH, -1, -1
+ Xlenses, TRUE, FALSE,
+ EL_EMC_LENSES, -1, -1
},
+
{
- XswitchB, FALSE, FALSE,
- EL_EMC_MAGIC_BALL_SWITCH, ACTION_ACTIVE, -1
+ Xmagnify, TRUE, FALSE,
+ EL_EMC_MAGNIFIER, -1, -1
},
+
{
Xsand, TRUE, FALSE,
EL_QUICKSAND_EMPTY, -1, -1
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;
{
int i;
- /* return "Xalpha_quest" for all undefined elements in mapping array */
+ // return "Xalpha_quest" for all undefined elements in mapping array
for (i = 0; i < NUM_FILE_ELEMENTS; i++)
mapping_RND_to_EM[i] = Xalpha_quest;
mapping_initialized = TRUE;
}
- if (element_rnd >= 0 && element_rnd < NUM_FILE_ELEMENTS)
- return mapping_RND_to_EM[element_rnd];
+ if (element_rnd < 0 || element_rnd >= NUM_FILE_ELEMENTS)
+ {
+ Warn("invalid RND level element %d", element_rnd);
+
+ return EL_UNKNOWN;
+ }
+
+ return map_em_element_X_to_C(mapping_RND_to_EM[element_rnd]);
+}
+
+int map_element_EM_to_RND_cave(int element_em_cave)
+{
+ static unsigned short mapping_EM_to_RND[GAME_TILE_MAX];
+ static boolean mapping_initialized = FALSE;
+
+ if (!mapping_initialized)
+ {
+ int i;
+
+ // return "EL_UNKNOWN" for all undefined elements in mapping array
+ for (i = 0; i < GAME_TILE_MAX; i++)
+ mapping_EM_to_RND[i] = EL_UNKNOWN;
+
+ for (i = 0; em_object_mapping_list[i].element_em != -1; i++)
+ mapping_EM_to_RND[em_object_mapping_list[i].element_em] =
+ em_object_mapping_list[i].element_rnd;
+
+ mapping_initialized = TRUE;
+ }
+
+ if (element_em_cave < 0 || element_em_cave >= CAVE_TILE_MAX)
+ {
+ Warn("invalid EM cave element %d", element_em_cave);
- Error(ERR_WARN, "invalid RND level element %d", element_rnd);
+ return EL_UNKNOWN;
+ }
- return EL_UNKNOWN;
+ return mapping_EM_to_RND[map_em_element_C_to_X(element_em_cave)];
}
-int map_element_EM_to_RND(int element_em)
+int map_element_EM_to_RND_game(int element_em_game)
{
- static unsigned short mapping_EM_to_RND[TILE_MAX];
+ static unsigned short mapping_EM_to_RND[GAME_TILE_MAX];
static boolean mapping_initialized = FALSE;
if (!mapping_initialized)
{
int i;
- /* return "EL_UNKNOWN" for all undefined elements in mapping array */
- for (i = 0; i < TILE_MAX; i++)
+ // return "EL_UNKNOWN" for all undefined elements in mapping array
+ for (i = 0; i < GAME_TILE_MAX; i++)
mapping_EM_to_RND[i] = EL_UNKNOWN;
for (i = 0; em_object_mapping_list[i].element_em != -1; i++)
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)
int map_element_RND_to_SP(int element_rnd)
{
- int element_sp = 0x20; /* map unknown elements to yellow "hardware" */
+ int element_sp = 0x20; // map unknown elements to yellow "hardware"
if (element_rnd >= EL_SP_START &&
element_rnd <= EL_SP_END)
int map_action_MM_to_RND(int action_mm)
{
- /* all MM actions are defined to exactly match their RND counterparts */
+ // all MM actions are defined to exactly match their RND counterparts
return action_mm;
}
int el_act_dir2img(int element, int action, int direction)
{
element = GFX_ELEMENT(element);
- direction = MV_DIR_TO_BIT(direction); /* default: MV_NONE => MV_DOWN */
+ direction = MV_DIR_TO_BIT(direction); // default: MV_NONE => MV_DOWN
- /* direction_graphic[][] == graphic[] for undefined direction graphics */
+ // direction_graphic[][] == graphic[] for undefined direction graphics
return element_info[element].direction_graphic[action][direction];
}
static int el_act_dir2crm(int element, int action, int direction)
{
element = GFX_ELEMENT(element);
- direction = MV_DIR_TO_BIT(direction); /* default: MV_NONE => MV_DOWN */
+ direction = MV_DIR_TO_BIT(direction); // default: MV_NONE => MV_DOWN
- /* direction_graphic[][] == graphic[] for undefined direction graphics */
+ // direction_graphic[][] == graphic[] for undefined direction graphics
return element_info[element].direction_crumbled[action][direction];
}
return getBeltSwitchElementFromBeltNrAndBeltDirNr(belt_nr, belt_dir_nr);
}
-boolean getTeamMode_EM()
+boolean swapTiles_EM(boolean is_pre_emc_cave)
{
- return game.team_mode;
+ return is_pre_emc_cave && leveldir_current->use_emc_tiles;
}
-int getGameFrameDelay_EM(int native_em_game_frame_delay)
+boolean getTeamMode_EM(void)
{
- 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.team_mode || network_playing;
+}
- return game_frame_delay_value;
+boolean isActivePlayer_EM(int player_nr)
+{
+ return stored_player[player_nr].active;
}
unsigned int InitRND(int seed)
return InitEngineRandom_RND(seed);
}
-static struct Mapping_EM_to_RND_object object_mapping[TILE_MAX];
-static struct Mapping_EM_to_RND_player player_mapping[MAX_PLAYERS][SPR_MAX];
+static struct Mapping_EM_to_RND_object object_mapping[GAME_TILE_MAX];
+static struct Mapping_EM_to_RND_player player_mapping[MAX_PLAYERS][PLY_MAX];
-inline static int get_effective_element_EM(int tile, int frame_em)
+static int get_effective_element_EM(int tile, int frame_em)
{
int element = object_mapping[tile].element_rnd;
int action = object_mapping[tile].action;
{
switch (tile)
{
- case Yacid_splash_eB:
- case Yacid_splash_wB:
+ case Xsplash_e:
+ case Xsplash_w:
return (frame_em > 5 ? EL_EMPTY : element);
default:
return element;
}
}
- else /* frame_em == 7 */
+ else // frame_em == 7
{
switch (tile)
{
- case Yacid_splash_eB:
- case Yacid_splash_wB:
+ case Xsplash_e:
+ case Xsplash_w:
return EL_EMPTY;
- case Yemerald_stone:
+ case Ynut_stone:
return EL_EMERALD;
case Ydiamond_stone:
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:
}
}
-inline static boolean check_linear_animation_EM(int tile)
+static boolean check_linear_animation_EM(int tile)
{
switch (tile)
{
case Ytank_s_e:
case Ytank_w_s:
case Ytank_n_w:
- case Yacid_splash_eB:
- case Yacid_splash_wB:
- case Yemerald_stone:
+ case Xsplash_e:
+ case Xsplash_w:
+ case Ynut_stone:
return TRUE;
}
return FALSE;
}
-inline static void set_crumbled_graphics_EM(struct GraphicInfo_EM *g_em,
- boolean has_crumbled_graphics,
- int crumbled, int sync_frame)
+static void set_crumbled_graphics_EM(struct GraphicInfo_EM *g_em,
+ boolean has_crumbled_graphics,
+ int crumbled, int sync_frame)
{
- /* if element can be crumbled, but certain action graphics are just empty
- space (like instantly snapping sand to empty space in 1 frame), do not
- treat these empty space graphics as crumbled graphics in EMC engine */
+ // if element can be crumbled, but certain action graphics are just empty
+ // space (like instantly snapping sand to empty space in 1 frame), do not
+ // treat these empty space graphics as crumbled graphics in EMC engine
if (crumbled == IMG_EMPTY_SPACE)
has_crumbled_graphics = FALSE;
}
}
+#if 0
void ResetGfxAnimation_EM(int x, int y, int tile)
{
GfxFrame[x][y] = 0;
}
+#endif
void SetGfxAnimation_EM(struct GraphicInfo_EM *g_em,
int tile, int frame_em, int x, int y)
action == ACTION_FILLING ||
action == ACTION_EMPTYING);
- /* special case: graphic uses "2nd movement tile" and has defined
- 7 frames for movement animation (or less) => use default graphic
- for last (8th) frame which ends the movement animation */
+ // special case: graphic uses "2nd movement tile" and has defined
+ // 7 frames for movement animation (or less) => use default graphic
+ // for last (8th) frame which ends the movement animation
if (g->double_movement && g->anim_frames < 8 && frame_em == 7)
{
- action = ACTION_DEFAULT; /* (keep action_* unchanged for now) */
+ action = ACTION_DEFAULT; // (keep action_* unchanged for now)
graphic = (direction == MV_NONE ?
el_act2img(effective_element, action) :
el_act_dir2img(effective_element, action, direction));
GfxFrame[x][y]++;
#if 1
- /* !!! TEST !!! NEW !!! DOES NOT WORK RIGHT YET !!! */
+ // !!! TEST !!! NEW !!! DOES NOT WORK RIGHT YET !!!
if (g->double_movement && frame_em == 0)
GfxFrame[x][y] = 0;
#endif
{
GfxFrame[x][y]++;
- /* special case: animation for Xsand_stonesand_quickout_1/2 twice as fast */
+ // special case: animation for Xsand_stonesand_quickout_1/2 twice as fast
if (tile == Xsand_stonesand_quickout_1 ||
tile == Xsand_stonesand_quickout_2)
GfxFrame[x][y]++;
else if (IN_FIELD(x, y, MAX_LEV_FIELDX, MAX_LEV_FIELDY))
sync_frame = GfxFrame[x][y];
else
- sync_frame = 0; /* playfield border (pseudo steel) */
+ sync_frame = 0; // playfield border (pseudo steel)
SetRandomAnimationValue(x, y);
struct GraphicInfo *g = &graphic_info[graphic];
int sync_frame;
- /* special case: graphic uses "2nd movement tile" and has defined
- 7 frames for movement animation (or less) => use default graphic
- for last (8th) frame which ends the movement animation */
+ // special case: graphic uses "2nd movement tile" and has defined
+ // 7 frames for movement animation (or less) => use default graphic
+ // for last (8th) frame which ends the movement animation
if (g->double_movement && g->anim_frames < 8 && frame_em == 7)
{
effective_action = ACTION_DEFAULT;
else if (IN_FIELD(x, y, MAX_LEV_FIELDX, MAX_LEV_FIELDY))
sync_frame = GfxFrame[x][y];
else
- sync_frame = 0; /* playfield border (pseudo steel) */
+ sync_frame = 0; // playfield border (pseudo steel)
SetRandomAnimationValue(x, y);
getGraphicSourceExt(graphic, frame, &g_em->bitmap, &g_em->src_x, &g_em->src_y,
g->double_movement && is_backside);
- /* (updating the "crumbled" graphic definitions is probably not really needed,
- as animations for crumbled graphics can't be longer than one EMC cycle) */
+ // (updating the "crumbled" graphic definitions is probably not really needed,
+ // as animations for crumbled graphics can't be longer than one EMC cycle)
set_crumbled_graphics_EM(g_em, has_crumbled_graphics, crumbled,
sync_frame);
}
{
int i, j, p;
-#if DEBUG_EM_GFX
- int num_em_gfx_errors = 0;
-
- if (graphic_info_em_object[0][0].bitmap == NULL)
- {
- /* EM graphics not yet initialized in em_open_all() */
-
- return;
- }
-
- printf("::: [4 errors can be ignored (1 x 'bomb', 3 x 'em_dynamite']\n");
-#endif
-
- /* always start with reliable default values */
- for (i = 0; i < TILE_MAX; i++)
+ // always start with reliable default values
+ for (i = 0; i < GAME_TILE_MAX; i++)
{
object_mapping[i].element_rnd = EL_UNKNOWN;
object_mapping[i].is_backside = FALSE;
object_mapping[i].direction = MV_NONE;
}
- /* always start with reliable default values */
+ // always start with reliable default values
for (p = 0; p < MAX_PLAYERS; p++)
{
- for (i = 0; i < SPR_MAX; i++)
+ for (i = 0; i < PLY_MAX; i++)
{
player_mapping[p][i].element_rnd = EL_UNKNOWN;
player_mapping[p][i].action = ACTION_DEFAULT;
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 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 */
+ // ensure to get symmetric 3-frame, 2-delay animations as used in EM
boolean special_animation = (action != ACTION_DEFAULT &&
g->anim_frames == 3 &&
g->anim_delay == 2 &&
g->anim_mode & ANIM_LINEAR);
int sync_frame = (i == Xdrip_stretch ? 7 :
i == Xdrip_stretchB ? 7 :
- i == Ydrip_s2 ? j + 8 :
- i == Ydrip_s2B ? j + 8 :
+ i == Ydrip_2_s ? j + 8 :
+ i == Ydrip_2_sB ? j + 8 :
i == Xacid_1 ? 0 :
i == Xacid_2 ? 10 :
i == Xacid_3 ? 20 :
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 :
i == Xsand_stoneout_2 ? j + 8 : j) + 1;
int step = (is_backside ? step_frame : num_steps - step_frame);
- if (is_backside) /* tile where movement starts */
+ if (is_backside) // tile where movement starts
{
if (dx < 0 || dy < 0)
{
g_em->dst_offset_y = cy * step;
}
}
- else /* tile where movement ends */
+ else // tile where movement ends
{
if (dx < 0 || dy < 0)
{
g_em->height = TILEY - cy * step;
}
- /* create unique graphic identifier to decide if tile must be redrawn */
+ // create unique graphic identifier to decide if tile must be redrawn
/* bit 31 - 16 (16 bit): EM style graphic
bit 15 - 12 ( 4 bit): EM style frame
bit 11 - 6 ( 6 bit): graphic width
bit 5 - 0 ( 6 bit): graphic height */
g_em->unique_identifier =
(graphic << 16) | (frame << 12) | (g_em->width << 6) | g_em->height;
-
-#if DEBUG_EM_GFX
-
- /* skip check for EMC elements not contained in original EMC artwork */
- if (element == EL_EMC_FAKE_ACID)
- continue;
-
- if (g_em->bitmap != debug_bitmap ||
- g_em->src_x != debug_src_x ||
- g_em->src_y != debug_src_y ||
- g_em->src_offset_x != 0 ||
- g_em->src_offset_y != 0 ||
- g_em->dst_offset_x != 0 ||
- g_em->dst_offset_y != 0 ||
- g_em->width != TILEX ||
- g_em->height != TILEY)
- {
- static int last_i = -1;
-
- if (i != last_i)
- {
- printf("\n");
- last_i = i;
- }
-
- printf("::: EMC GFX ERROR for element %d -> %d ('%s', '%s', %d)",
- i, element, element_info[element].token_name,
- element_action_info[effective_action].suffix, direction);
-
- if (element != effective_element)
- printf(" [%d ('%s')]",
- effective_element,
- element_info[effective_element].token_name);
-
- printf("\n");
-
- if (g_em->bitmap != debug_bitmap)
- printf(" %d (%d): different bitmap! (0x%08x != 0x%08x)\n",
- j, is_backside, (int)(g_em->bitmap), (int)(debug_bitmap));
-
- if (g_em->src_x != debug_src_x ||
- g_em->src_y != debug_src_y)
- printf(" frame %d (%c): %d,%d (%d,%d) should be %d,%d (%d,%d)\n",
- j, (is_backside ? 'B' : 'F'),
- g_em->src_x, g_em->src_y,
- g_em->src_x / 32, g_em->src_y / 32,
- debug_src_x, debug_src_y,
- debug_src_x / 32, debug_src_y / 32);
-
- if (g_em->src_offset_x != 0 ||
- g_em->src_offset_y != 0 ||
- g_em->dst_offset_x != 0 ||
- g_em->dst_offset_y != 0)
- printf(" %d (%d): offsets %d,%d and %d,%d should be all 0\n",
- j, is_backside,
- g_em->src_offset_x, g_em->src_offset_y,
- g_em->dst_offset_x, g_em->dst_offset_y);
-
- if (g_em->width != TILEX ||
- g_em->height != TILEY)
- printf(" %d (%d): size %d,%d should be %d,%d\n",
- j, is_backside,
- g_em->width, g_em->height, TILEX, TILEY);
-
- num_em_gfx_errors++;
- }
-#endif
-
}
}
- for (i = 0; i < TILE_MAX; i++)
+ for (i = 0; i < GAME_TILE_MAX; i++)
{
for (j = 0; j < 8; j++)
{
direction == MV_RIGHT ? (is_backside? Yspring_eB: Yspring_e) :
Xspring);
- /* no separate animation for "smashed by rock" -- use rock instead */
- struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][7 - j];
- struct GraphicInfo_EM *g_xx = &graphic_info_em_object[e][7 - j];
+ // no separate animation for "smashed by rock" -- use rock instead
+ struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][j];
+ struct GraphicInfo_EM *g_xx = &graphic_info_em_object[e][j];
g_em->bitmap = g_xx->bitmap;
g_em->src_x = g_xx->src_x;
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;
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
}
-void CheckSaveEngineSnapshot_EM(byte action[MAX_PLAYERS], int frame,
- boolean any_player_moving,
- boolean any_player_snapping,
- boolean any_player_dropping)
+static void CheckSaveEngineSnapshot_EM(byte action[MAX_PLAYERS], 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 CheckSaveEngineSnapshot_SP(boolean murphy_is_waiting,
- boolean murphy_is_dropping)
+static void CheckSaveEngineSnapshot_SP(boolean murphy_is_waiting,
+ boolean murphy_is_dropping)
{
if (murphy_is_waiting)
{
}
}
-void CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame,
- boolean any_player_moving,
- boolean any_player_snapping,
- boolean any_player_dropping)
+static void CheckSaveEngineSnapshot_MM(boolean element_clicked,
+ boolean button_released)
+{
+ if (button_released)
+ {
+ if (game.snapshot.mode == SNAPSHOT_MODE_EVERY_MOVE)
+ CheckSaveEngineSnapshotToList();
+ }
+ else if (element_clicked)
+ {
+ if (game.snapshot.mode != SNAPSHOT_MODE_EVERY_MOVE)
+ CheckSaveEngineSnapshotToList();
+
+ game.snapshot.changed_action = TRUE;
+ }
+}
+
+boolean CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame,
+ boolean any_player_moving,
+ boolean any_player_snapping,
+ boolean any_player_dropping)
{
if (tape.single_step && tape.recording && !tape.pausing)
- if (frame == 0 && !any_player_dropping)
+ if (frame == 7 && !any_player_dropping)
TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
CheckSaveEngineSnapshot_EM(action, frame, any_player_moving,
any_player_snapping, any_player_dropping);
+
+ return tape.pausing;
}
void CheckSingleStepMode_SP(boolean murphy_is_waiting,
CheckSaveEngineSnapshot_SP(murphy_is_waiting, murphy_is_dropping);
}
+void CheckSingleStepMode_MM(boolean element_clicked,
+ boolean button_released)
+{
+ if (tape.single_step && tape.recording && !tape.pausing)
+ if (button_released)
+ TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
+
+ CheckSaveEngineSnapshot_MM(element_clicked, button_released);
+}
+
void getGraphicSource_SP(struct GraphicInfo_SP *g_sp,
int graphic, int sync_frame, int x, int y)
{
PlaySound(sound);
}
-void PlayMenuSound()
+void PlayMenuSound(void)
{
PlayMenuSoundExt(menu.sound[game_status]);
}
PlaySoundLoop(sound);
}
-void PlayMenuSoundIfLoop()
+void PlayMenuSoundIfLoop(void)
{
PlayMenuSoundIfLoopExt(menu.sound[game_status]);
}
if (!setup.sound_music)
return;
- PlayMusic(music);
+ if (IS_LOOP_MUSIC(music))
+ PlayMusicLoop(music);
+ else
+ PlayMusic(music);
}
-void PlayMenuMusic()
+void PlayMenuMusic(void)
{
char *curr_music = getCurrentlyPlayingMusicFilename();
char *next_music = getMusicInfoEntryFilename(menu.music[game_status]);
PlayMenuMusicExt(menu.music[game_status]);
}
-void PlayMenuSoundsAndMusic()
+void PlayMenuSoundsAndMusic(void)
{
PlayMenuSound();
PlayMenuMusic();
}
-static void FadeMenuSounds()
+static void FadeMenuSounds(void)
{
FadeSounds();
}
-static void FadeMenuMusic()
+static void FadeMenuMusic(void)
{
char *curr_music = getCurrentlyPlayingMusicFilename();
char *next_music = getMusicInfoEntryFilename(menu.music[game_status]);
FadeMusic();
}
-void FadeMenuSoundsAndMusic()
+void FadeMenuSoundsAndMusic(void)
{
FadeMenuSounds();
FadeMenuMusic();
}
-void PlaySoundActivating()
+void PlaySoundActivating(void)
{
#if 0
PlaySound(SND_MENU_ITEM_ACTIVATING);
#endif
}
-void PlaySoundSelecting()
+void PlaySoundSelecting(void)
{
#if 0
PlaySound(SND_MENU_ITEM_SELECTING);
#endif
}
-void ToggleFullscreenOrChangeWindowScalingIfNeeded()
+void ToggleFullscreenIfNeeded(void)
{
- boolean change_fullscreen = (setup.fullscreen !=
- video.fullscreen_enabled);
- boolean change_window_scaling_percent = (!video.fullscreen_enabled &&
- setup.window_scaling_percent !=
- video.window_scaling_percent);
-
- if (change_window_scaling_percent && video.fullscreen_enabled)
+ // if setup and video fullscreen state are already matching, nothing do do
+ if (setup.fullscreen == video.fullscreen_enabled ||
+ !video.fullscreen_available)
return;
- if (!change_window_scaling_percent && !video.fullscreen_available)
- return;
+ SDLSetWindowFullscreen(setup.fullscreen);
-#if defined(TARGET_SDL2)
- if (change_window_scaling_percent)
- {
- SDLSetWindowScaling(setup.window_scaling_percent);
+ // set setup value according to successfully changed fullscreen mode
+ setup.fullscreen = video.fullscreen_enabled;
+}
+void ChangeWindowScalingIfNeeded(void)
+{
+ // if setup and video window scaling are already matching, nothing do do
+ if (setup.window_scaling_percent == video.window_scaling_percent ||
+ video.fullscreen_enabled)
return;
- }
- else if (change_fullscreen)
- {
- SDLSetWindowFullscreen(setup.fullscreen);
- /* set setup value according to successfully changed fullscreen mode */
- setup.fullscreen = video.fullscreen_enabled;
+ SDLSetWindowScaling(setup.window_scaling_percent);
+
+ // set setup value according to successfully changed window scaling
+ setup.window_scaling_percent = video.window_scaling_percent;
+}
+
+void ChangeVsyncModeIfNeeded(void)
+{
+ int setup_vsync_mode = VSYNC_MODE_STR_TO_INT(setup.vsync_mode);
+ int video_vsync_mode = video.vsync_mode;
+ // if setup and video vsync mode are already matching, nothing do do
+ if (setup_vsync_mode == video_vsync_mode)
return;
- }
-#endif
- if (change_fullscreen ||
- change_window_scaling_percent)
+ // if renderer is using OpenGL, vsync mode can directly be changed
+ SDLSetScreenVsyncMode(setup.vsync_mode);
+
+ // if vsync mode unchanged, try re-creating renderer to set vsync mode
+ if (video.vsync_mode == video_vsync_mode)
{
Bitmap *tmp_backbuffer = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
- /* save backbuffer content which gets lost when toggling fullscreen mode */
+ // save backbuffer content which gets lost when re-creating screen
BlitBitmap(backbuffer, tmp_backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
- if (change_window_scaling_percent)
- {
- /* keep window mode, but change window scaling */
- video.fullscreen_enabled = TRUE; /* force new window scaling */
- }
+ // force re-creating screen and renderer to set new vsync mode
+ video.fullscreen_enabled = !setup.fullscreen;
- /* toggle fullscreen */
+ // when creating new renderer, destroy textures linked to old renderer
+ FreeAllImageTextures(); // needs old renderer to free the textures
+
+ // re-create screen and renderer (including change of vsync mode)
ChangeVideoModeIfNeeded(setup.fullscreen);
- /* set setup value according to successfully changed fullscreen mode */
+ // set setup value according to successfully changed fullscreen mode
setup.fullscreen = video.fullscreen_enabled;
- /* restore backbuffer content from temporary backbuffer backup bitmap */
+ // restore backbuffer content from temporary backbuffer backup bitmap
BlitBitmap(tmp_backbuffer, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
-
FreeBitmap(tmp_backbuffer);
- /* update visible window/screen */
+ // update visible window/screen
BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+
+ // when changing vsync mode, re-create textures for new renderer
+ InitImageTextures();
}
+
+ // set setup value according to successfully changed vsync mode
+ setup.vsync_mode = VSYNC_MODE_INT_TO_STR(video.vsync_mode);
}
-void JoinRectangles(int *x, int *y, int *width, int *height,
- int x2, int y2, int width2, int height2)
+static void JoinRectangles(int *x, int *y, int *width, int *height,
+ int x2, int y2, int width2, int height2)
{
// do not join with "off-screen" rectangle
if (x2 == -1 || y2 == -1)
{
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;
}
}
}
-void ResetFontStatus()
+void ResetFontStatus(void)
{
SetFontStatus(-1);
}
-void ChangeViewportPropertiesIfNeeded()
+void SetLevelSetInfo(char *identifier, int level_nr)
+{
+ setString(&levelset.identifier, identifier);
+
+ levelset.level_nr = level_nr;
+}
+
+boolean CheckIfAllViewportsHaveChanged(void)
+{
+ // if game status has not changed, viewports have not changed either
+ if (game_status == game_status_last)
+ return FALSE;
+
+ // check if all viewports have changed with current game status
+
+ struct RectWithBorder *vp_playfield = &viewport.playfield[game_status];
+ struct RectWithBorder *vp_door_1 = &viewport.door_1[game_status];
+ struct RectWithBorder *vp_door_2 = &viewport.door_2[game_status];
+ int new_real_sx = vp_playfield->x;
+ int new_real_sy = vp_playfield->y;
+ int new_full_sxsize = vp_playfield->width;
+ int new_full_sysize = vp_playfield->height;
+ int new_dx = vp_door_1->x;
+ int new_dy = vp_door_1->y;
+ int new_dxsize = vp_door_1->width;
+ int new_dysize = vp_door_1->height;
+ int new_vx = vp_door_2->x;
+ int new_vy = vp_door_2->y;
+ int new_vxsize = vp_door_2->width;
+ int new_vysize = vp_door_2->height;
+
+ boolean playfield_viewport_has_changed =
+ (new_real_sx != REAL_SX ||
+ new_real_sy != REAL_SY ||
+ new_full_sxsize != FULL_SXSIZE ||
+ new_full_sysize != FULL_SYSIZE);
+
+ boolean door_1_viewport_has_changed =
+ (new_dx != DX ||
+ new_dy != DY ||
+ new_dxsize != DXSIZE ||
+ new_dysize != DYSIZE);
+
+ boolean door_2_viewport_has_changed =
+ (new_vx != VX ||
+ new_vy != VY ||
+ new_vxsize != VXSIZE ||
+ new_vysize != VYSIZE ||
+ game_status_last == GAME_MODE_EDITOR);
+
+ return (playfield_viewport_has_changed &&
+ door_1_viewport_has_changed &&
+ door_2_viewport_has_changed);
+}
+
+boolean CheckFadeAll(void)
+{
+ return (CheckIfGlobalBorderHasChanged() ||
+ CheckIfAllViewportsHaveChanged());
+}
+
+void ChangeViewportPropertiesIfNeeded(void)
{
boolean use_mini_tilesize = (level.game_engine_type == GAME_ENGINE_TYPE_MM ?
FALSE : setup.small_game_graphics);
struct RectWithBorder *vp_door_3 = &viewport.door_2[GAME_MODE_EDITOR];
int new_win_xsize = vp_window->width;
int new_win_ysize = vp_window->height;
- int border_size = vp_playfield->border_size;
- int new_sx = vp_playfield->x + border_size;
- int new_sy = vp_playfield->y + border_size;
- int new_sxsize = vp_playfield->width - 2 * border_size;
- int new_sysize = vp_playfield->height - 2 * border_size;
+ int border_left = vp_playfield->border_left;
+ int border_right = vp_playfield->border_right;
+ int border_top = vp_playfield->border_top;
+ int border_bottom = vp_playfield->border_bottom;
+ int new_sx = vp_playfield->x + border_left;
+ int new_sy = vp_playfield->y + border_top;
+ int new_sxsize = vp_playfield->width - border_left - border_right;
+ int new_sysize = vp_playfield->height - border_top - border_bottom;
int new_real_sx = vp_playfield->x;
int new_real_sy = vp_playfield->y;
int new_full_sxsize = vp_playfield->width;
init_gfx_buffers = TRUE;
init_gadgets_and_anims = TRUE;
- // printf("::: video: init_video_buffer, init_gfx_buffers\n");
+ // Debug("tools:viewport", "video: init_video_buffer, init_gfx_buffers");
}
if (new_scr_fieldx != SCR_FIELDX ||
new_scr_fieldy != SCR_FIELDY)
{
- /* this always toggles between MAIN and GAME when using small tile size */
+ // this always toggles between MAIN and GAME when using small tile size
SCR_FIELDX = new_scr_fieldx;
SCR_FIELDY = new_scr_fieldy;
- // printf("::: new_scr_fieldx != SCR_FIELDX ...\n");
+ // Debug("tools:viewport", "new_scr_fieldx != SCR_FIELDX ...");
}
if (new_sx != SX ||
}
// add current and new door 2 area if position or size has changed
- if (new_dx != VX || new_dy != VY ||
- new_dxsize != VXSIZE || new_dysize != VYSIZE)
+ if (new_vx != VX || new_vy != VY ||
+ new_vxsize != VXSIZE || new_vysize != VYSIZE)
{
JoinRectangles(&FADE_SX, &FADE_SY, &FADE_SXSIZE, &FADE_SYSIZE,
VX, VY, VXSIZE, VYSIZE);
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();
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
InitVideoBuffer(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, setup.fullscreen);
InitImageTextures();
if (init_gadgets_and_anims)
{
- // printf("::: init_gadgets_and_anims\n");
+ // Debug("tools:viewport", "init_gadgets_and_anims");
InitGadgets();
InitGlobalAnimations();
if (init_em_graphics)
{
- InitGraphicInfo_EM();
+ InitGraphicInfo_EM();
}
}