printf(" MovDir: %d\n", MovDir[x][y]);
printf(" MovDelay: %d\n", MovDelay[x][y]);
printf(" ChangeDelay: %d\n", ChangeDelay[x][y]);
+ printf(" Count: %d\n", Count[x][y]);
printf(" GfxElement: %d\n", GfxElement[x][y]);
printf(" GfxAction: %d\n", GfxAction[x][y]);
printf(" GfxFrame: %d\n", GfxFrame[x][y]);
void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height)
{
- if (game_status == GAME_MODE_PLAYING && !game.envelope_active)
+ if (game_status == GAME_MODE_PLAYING &&
+ level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ {
+ BlitScreenToBitmap_EM(backbuffer);
+ }
+ else if (game_status == GAME_MODE_PLAYING && !game.envelope_active)
{
if (force_redraw)
{
{
BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
-#ifdef DEBUG
#if 0
+#ifdef DEBUG
printf("redrawing all (ScreenGfxPos == %d) because %s\n",
ScreenGfxPos,
(setup.soft_scrolling ?
BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
if (redraw_mask & REDRAW_DOOR_2)
- {
-#if 0
- if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
-#endif
- BlitBitmap(backbuffer, window, VX, VY, VXSIZE, VYSIZE, VX, VY);
-#if 0
- else
- {
- if (redraw_mask & REDRAW_VIDEO_1)
- BlitBitmap(backbuffer, window,
- VX + VIDEO_DISPLAY1_XPOS, VY + VIDEO_DISPLAY1_YPOS,
- VIDEO_DISPLAY_XSIZE, VIDEO_DISPLAY_YSIZE,
- VX + VIDEO_DISPLAY1_XPOS, VY + VIDEO_DISPLAY1_YPOS);
- if (redraw_mask & REDRAW_VIDEO_2)
- BlitBitmap(backbuffer, window,
- VX + VIDEO_DISPLAY2_XPOS, VY + VIDEO_DISPLAY2_YPOS,
- VIDEO_DISPLAY_XSIZE, VIDEO_DISPLAY_YSIZE,
- VX + VIDEO_DISPLAY2_XPOS, VY + VIDEO_DISPLAY2_YPOS);
- if (redraw_mask & REDRAW_VIDEO_3)
- BlitBitmap(backbuffer, window,
- VX + VIDEO_CONTROL_XPOS, VY + VIDEO_CONTROL_YPOS,
- VIDEO_CONTROL_XSIZE, VIDEO_CONTROL_YSIZE,
- VX + VIDEO_CONTROL_XPOS, VY + VIDEO_CONTROL_YPOS);
- }
-#endif
- }
+ BlitBitmap(backbuffer, window, VX, VY, VXSIZE, VYSIZE, VX, VY);
if (redraw_mask & REDRAW_DOOR_3)
BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
BackToFront();
}
+void SetMainBackgroundImageIfDefined(int graphic)
+{
+ if (graphic_info[graphic].bitmap)
+ SetMainBackgroundImage(graphic);
+}
+
void SetMainBackgroundImage(int graphic)
{
SetMainBackgroundBitmap(graphic == IMG_UNDEFINED ? NULL :
if (g->offset_y == 0) /* frames are ordered horizontally */
{
int max_width = g->anim_frames_per_line * g->width;
-#if 1
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
- *x = (src_x + frame * g->offset_x) % max_width;
- *y = src_y + (src_x + frame * g->offset_x) / max_width * g->height;
-#endif
}
else if (g->offset_x == 0) /* frames are ordered vertically */
{
int max_height = g->anim_frames_per_line * g->height;
-#if 1
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
- *x = src_x + (src_y + frame * g->offset_y) / max_height * g->width;
- *y = (src_y + frame * g->offset_y) % max_height;
-#endif
}
else /* frames are ordered diagonally */
{
}
#endif
- getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
+ if (width > 0 && height > 0)
+ {
+ getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
- src_x += cx;
- src_y += cy;
+ src_x += cx;
+ src_y += cy;
- dst_x = FX + x * TILEX + dx;
- dst_y = FY + y * TILEY + dy;
+ dst_x = FX + x * TILEX + dx;
+ dst_y = FY + y * TILEY + dy;
- if (mask_mode == USE_MASKING)
- {
- SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
- dst_x - src_x, dst_y - src_y);
- BlitBitmapMasked(src_bitmap, drawto_field, src_x, src_y, width, height,
- dst_x, dst_y);
- }
- else
- BlitBitmap(src_bitmap, drawto_field, src_x, src_y, width, height,
- dst_x, dst_y);
+ if (mask_mode == USE_MASKING)
+ {
+ SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(src_bitmap, drawto_field, src_x, src_y, width, height,
+ dst_x, dst_y);
+ }
+ else
+ BlitBitmap(src_bitmap, drawto_field, src_x, src_y, width, height,
+ dst_x, dst_y);
- MarkTileDirty(x, y);
+ MarkTileDirty(x, y);
+ }
}
inline static void DrawGraphicShiftedDouble(int x, int y, int dx, int dy,
int sx = SCREENX(x), sy = SCREENY(y);
int element;
int width, height, cx, cy, i;
-#if 1
int crumbled_border_size = graphic_info[graphic].border_size;
-#else
- int snip = TILEX / 8; /* number of border pixels from "crumbled graphic" */
-#endif
static int xy[4][2] =
{
{ 0, -1 },
{ 0, +1 }
};
-#if 0
- if (x == 0 && y == 7)
- printf("::: %d, %d [%d]\n", GfxElement[x][y], Feld[x][y],
- crumbled_border_size);
-#endif
-
if (!IN_LEV_FIELD(x, y))
return;
int xx = x + xy[i][0];
int yy = y + xy[i][1];
-#if 1
element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) :
BorderElement);
-#else
- element = (IN_LEV_FIELD(xx, yy) ? Feld[xx][yy] : BorderElement);
-#endif
/* check if neighbour field is of same type */
if (GFX_CRUMBLED(element) && !IS_MOVING(xx, yy))
continue;
-#if 0
- if (Feld[x][y] == EL_CUSTOM_START + 123)
- printf("::: crumble [%d] THE CHAOS ENGINE (%d, %d): %d, %d\n",
- i, Feld[x][y], element,
- GFX_CRUMBLED(element), IS_MOVING(x, y));
-#endif
-
if (i == 1 || i == 2)
{
width = crumbled_border_size;
}
else /* crumble neighbour fields */
{
-#if 0
- getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
-#endif
-
for (i = 0; i < 4; i++)
{
int xx = x + xy[i][0];
continue;
#endif
-#if 1
graphic = el_act2crm(Feld[xx][yy], ACTION_DEFAULT);
crumbled_border_size = graphic_info[graphic].border_size;
getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
-#endif
if (i == 1 || i == 2)
{
void DrawLevelFieldCrumbledSand(int x, int y)
{
-#if 1
int graphic;
if (!IN_LEV_FIELD(x, y))
graphic = el_act2crm(Feld[x][y], ACTION_DEFAULT);
DrawLevelFieldCrumbledSandExt(x, y, graphic, 0);
-#else
- DrawLevelFieldCrumbledSandExt(x, y, IMG_SAND_CRUMBLED, 0);
-#endif
}
void DrawLevelFieldCrumbledSandDigging(int x, int y, int direction,
int step_frame)
{
-#if 1
int graphic1 = el_act_dir2img(GfxElement[x][y], ACTION_DIGGING, direction);
int graphic2 = el_act_dir2crm(GfxElement[x][y], ACTION_DIGGING, direction);
-#else
- int graphic1 = el_act_dir2img(EL_SAND, ACTION_DIGGING, direction);
- int graphic2 = el_act_dir2img(EL_SAND_CRUMBLED, ACTION_DIGGING, direction);
-#endif
int frame1 = getGraphicAnimationFrame(graphic1, step_frame);
int frame2 = getGraphicAnimationFrame(graphic2, step_frame);
int sx = SCREENX(x), sy = SCREENY(y);
void AnimateEnvelope(int envelope_nr, int anim_mode, int action)
{
int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr;
-#if 1
Bitmap *src_bitmap = graphic_info[graphic].bitmap;
int mask_mode = (src_bitmap != NULL ? BLIT_MASKED : BLIT_ON_BACKGROUND);
-#else
- boolean draw_masked = graphic_info[graphic].draw_masked;
- int mask_mode = (draw_masked ? BLIT_MASKED : BLIT_ON_BACKGROUND);
-#endif
boolean ffwd_delay = (tape.playing && tape.fast_forward);
boolean no_delay = (tape.warp_forward);
unsigned long anim_delay = 0;
{
int x, y;
- DrawBackground(xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
+ DrawBackground(xpos, ypos, MICROLEVEL_XSIZE, MICROLEVEL_YSIZE);
if (lev_fieldx < STD_LEV_FIELDX)
xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
#define MICROLABEL_EMPTY 0
#define MICROLABEL_LEVEL_NAME 1
-#define MICROLABEL_CREATED_BY 2
+#define MICROLABEL_LEVEL_AUTHOR_HEAD 2
#define MICROLABEL_LEVEL_AUTHOR 3
-#define MICROLABEL_IMPORTED_FROM 4
-#define MICROLABEL_LEVEL_IMPORT_INFO 5
+#define MICROLABEL_IMPORTED_FROM_HEAD 4
+#define MICROLABEL_IMPORTED_FROM 5
+#define MICROLABEL_IMPORTED_BY_HEAD 6
+#define MICROLABEL_IMPORTED_BY 7
static void DrawMicroLevelLabelExt(int mode)
{
char label_text[MAX_OUTPUT_LINESIZE + 1];
int max_len_label_text;
int font_nr = FONT_TEXT_2;
+ int i;
- if (mode == MICROLABEL_CREATED_BY || mode == MICROLABEL_IMPORTED_FROM)
+ if (mode == MICROLABEL_LEVEL_AUTHOR_HEAD ||
+ mode == MICROLABEL_IMPORTED_FROM_HEAD ||
+ mode == MICROLABEL_IMPORTED_BY_HEAD)
font_nr = FONT_TEXT_3;
max_len_label_text = SXSIZE / getFontWidth(font_nr);
- DrawBackground(SX, MICROLABEL_YPOS, SXSIZE, getFontHeight(font_nr));
+ for (i = 0; i < max_len_label_text; i++)
+ label_text[i] = ' ';
+ label_text[max_len_label_text] = '\0';
+
+ if (strlen(label_text) > 0)
+ {
+ int lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
+ int lypos = MICROLABEL2_YPOS;
+
+ DrawText(lxpos, lypos, label_text, font_nr);
+ }
- strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
- mode == MICROLABEL_CREATED_BY ? "created by" :
- mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
- mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
- mode == MICROLABEL_LEVEL_IMPORT_INFO ?
- leveldir_current->imported_from : ""),
+ strncpy(label_text,
+ (mode == MICROLABEL_LEVEL_NAME ? level.name :
+ mode == MICROLABEL_LEVEL_AUTHOR_HEAD ? "created by" :
+ mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
+ mode == MICROLABEL_IMPORTED_FROM_HEAD ? "imported from" :
+ mode == MICROLABEL_IMPORTED_FROM ? leveldir_current->imported_from :
+ mode == MICROLABEL_IMPORTED_BY_HEAD ? "imported by" :
+ mode == MICROLABEL_IMPORTED_BY ? leveldir_current->imported_by :""),
max_len_label_text);
label_text[max_len_label_text] = '\0';
if (strlen(label_text) > 0)
{
int lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
- int lypos = MICROLABEL_YPOS;
+ int lypos = MICROLABEL2_YPOS;
DrawText(lxpos, lypos, label_text, font_nr);
}
if (leveldir_current->name)
{
- int text_width = getTextWidth(leveldir_current->name, FONT_TEXT_1);
- int lxpos = SX + (SXSIZE - text_width) / 2;
- int lypos = SY + 352;
+ char label_text[MAX_OUTPUT_LINESIZE + 1];
+ int font_nr = FONT_TEXT_1;
+ int max_len_label_text = SXSIZE / getFontWidth(font_nr);
+ int lxpos, lypos;
+
+ strncpy(label_text, leveldir_current->name, max_len_label_text);
+ label_text[max_len_label_text] = '\0';
+
+ lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
+ lypos = SY + MICROLABEL1_YPOS;
- DrawText(lxpos, lypos, leveldir_current->name, FONT_TEXT_1);
+ DrawText(lxpos, lypos, label_text, font_nr);
}
game_status = last_game_status; /* restore current game status */
DrawMicroLevelExt(xpos, ypos, from_x, from_y);
}
+ /* !!! THIS ALL SUCKS -- SHOULD BE CLEANLY REWRITTEN !!! */
/* redraw micro level label, if needed */
if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
strcmp(level.author, ANONYMOUS_NAME) != 0 &&
{
int max_label_counter = 23;
- if (leveldir_current->imported_from != NULL)
+ if (leveldir_current->imported_from != NULL &&
+ strlen(leveldir_current->imported_from) > 0)
+ max_label_counter += 14;
+ if (leveldir_current->imported_by != NULL &&
+ strlen(leveldir_current->imported_by) > 0)
max_label_counter += 14;
label_counter = (label_counter + 1) % max_label_counter;
label_state = (label_counter >= 0 && label_counter <= 7 ?
MICROLABEL_LEVEL_NAME :
label_counter >= 9 && label_counter <= 12 ?
- MICROLABEL_CREATED_BY :
+ MICROLABEL_LEVEL_AUTHOR_HEAD :
label_counter >= 14 && label_counter <= 21 ?
MICROLABEL_LEVEL_AUTHOR :
label_counter >= 23 && label_counter <= 26 ?
- MICROLABEL_IMPORTED_FROM :
+ MICROLABEL_IMPORTED_FROM_HEAD :
label_counter >= 28 && label_counter <= 35 ?
- MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
+ MICROLABEL_IMPORTED_FROM :
+ label_counter >= 37 && label_counter <= 40 ?
+ MICROLABEL_IMPORTED_BY_HEAD :
+ label_counter >= 42 && label_counter <= 49 ?
+ MICROLABEL_IMPORTED_BY : MICROLABEL_EMPTY);
+
+ if (leveldir_current->imported_from == NULL &&
+ (label_state == MICROLABEL_IMPORTED_FROM_HEAD ||
+ label_state == MICROLABEL_IMPORTED_FROM))
+ label_state = (label_state == MICROLABEL_IMPORTED_FROM_HEAD ?
+ MICROLABEL_IMPORTED_BY_HEAD : MICROLABEL_IMPORTED_BY);
+
DrawMicroLevelLabelExt(label_state);
}
void DrawLevelElementAnimation(int x, int y, int element)
{
-#if 1
int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
DrawGraphicAnimation(SCREENX(x), SCREENY(y), graphic);
-#else
- DrawGraphicAnimation(SCREENX(x), SCREENY(y), el2img(element));
-#endif
}
inline void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic)
int jx = player->jx;
int jy = player->jy;
int move_dir = player->MovDir;
-#if 0
- int last_jx = player->last_jx;
- int last_jy = player->last_jy;
- int next_jx = jx + (jx - last_jx);
- int next_jy = jy + (jy - last_jy);
- boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
-#else
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 next_jx = jx + dx;
int next_jy = jy + dy;
boolean player_is_moving = (player->MovPos ? TRUE : FALSE);
-#endif
int sx = SCREENX(jx), sy = SCREENY(jy);
int sxx = 0, syy = 0;
int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
/* draw things in the field the player is leaving, if needed */
/* ----------------------------------------------------------------------- */
-#if 1
if (player->is_moving)
-#else
- if (player_is_moving)
-#endif
{
if (Back[last_jx][last_jy] && IS_DRAWABLE(last_element))
{
{
GfxElement[jx][jy] = EL_UNDEFINED;
+ /* make sure that pushed elements are drawn with correct frame rate */
+ if (player->is_pushing && player->is_moving)
+ GfxFrame[jx][jy] = player->StepFrame;
+
DrawLevelField(jx, jy);
}
}
/* draw player himself */
/* ----------------------------------------------------------------------- */
-#if 1
-
graphic = getPlayerGraphic(player, move_dir);
/* in the case of changed player action or direction, prevent the current
if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic))
player->Frame = last_player_frame;
-#else
-
- if (player->use_murphy_graphic)
- {
- static int last_horizontal_dir = MV_LEFT;
-
- if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
- last_horizontal_dir = move_dir;
-
- graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, move_dir);
-
- if (graphic == IMG_SP_MURPHY) /* undefined => use special graphic */
- {
- int direction = (player->is_snapping ? move_dir : last_horizontal_dir);
-
- graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, direction);
- }
- }
- else
- graphic = el_act_dir2img(player->element_nr, player->GfxAction, move_dir);
-
-#endif
-
frame = getGraphicAnimationFrame(graphic, player->Frame);
if (player->GfxPos)
#if 1
if (player->is_pushing && player->is_moving)
-#else
- if (player->is_pushing && player_is_moving)
-#endif
{
- int px = SCREENX(next_jx), py = SCREENY(next_jy);
+ int px = SCREENX(jx), py = SCREENY(jy);
+ int pxx = (TILEX - ABS(sxx)) * dx;
+ int pyy = (TILEY - ABS(syy)) * dy;
+
+ int graphic;
+ int frame;
+ if (!IS_MOVING(jx, jy)) /* push movement already finished */
+ element = Feld[next_jx][next_jy];
+
+ graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir);
+ frame = getGraphicAnimationFrame(graphic, player->StepFrame);
+
+ /* draw background element under pushed element (like the Sokoban field) */
if (Back[next_jx][next_jy])
DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
- if ((sxx || syy) && element == EL_SOKOBAN_OBJECT)
- DrawGraphicShiftedThruMask(px, py, sxx, syy, IMG_SOKOBAN_OBJECT, 0,
- NO_CUTTING);
- else
- {
- int element = MovingOrBlocked2Element(next_jx, next_jy);
- int graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir);
-#if 1
- int frame = getGraphicAnimationFrame(graphic, player->StepFrame);
-#else
- int frame = getGraphicAnimationFrame(graphic, player->Frame);
-#endif
-
- DrawGraphicShifted(px, py, sxx, syy, graphic, frame,
- NO_CUTTING, NO_MASKING);
- }
+ /* masked drawing is needed for EMC style (double) movement graphics */
+ DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame, NO_CUTTING);
}
+#endif
/* ----------------------------------------------------------------------- */
/* draw things in front of player (active dynamite or dynabombs) */
DrawLevelFieldThruMask(last_jx, last_jy);
}
-#if 1
/* do not redraw accessible elements if the player is just pushing them */
if (!player_is_moving || !player->is_pushing)
{
DrawLevelFieldThruMask(jx, jy);
}
-#else
-
-#if 0
- /* !!! I have forgotton what this should be good for !!! */
- /* !!! causes player being visible when pushing from within tubes !!! */
- if (!player->is_pushing)
-#endif
- {
- /* ... and the field the player is entering */
- if (IS_ACCESSIBLE_INSIDE(element))
- DrawLevelField(jx, jy);
- else if (IS_ACCESSIBLE_UNDER(element))
- DrawLevelFieldThruMask(jx, jy);
- }
-#endif
-
if (setup.direct_draw)
{
int dst_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
}
}
-#if 1
+ if (game_status == GAME_MODE_PLAYING &&
+ level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ BlitScreenToBitmap_EM(backbuffer);
+
/* disable deactivated drawing when quick-loading level tape recording */
if (tape.playing && tape.deactivate_display)
TapeDeactivateDisplayOff(TRUE);
-#endif
-#if 1
SetMouseCursor(CURSOR_DEFAULT);
-#endif
#if defined(NETWORK_AVALIABLE)
/* pause network game while waiting for request to answer */
OpenDoor(DOOR_OPEN_1);
-#if 0
- ClearEventQueue();
-#endif
-
if (!(req_state & REQUEST_WAIT_FOR_INPUT))
{
SetDrawBackgroundMask(REDRAW_FIELD);
SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
-#if 0
- SetMouseCursor(CURSOR_DEFAULT);
-#endif
-
while (result < 0)
{
if (PendingEvent())
SendToServer_ContinuePlaying();
#endif
-#if 1
/* restore deactivated drawing when quick-loading level tape recording */
if (tape.playing && tape.deactivate_display)
TapeDeactivateDisplayOn();
-#endif
return result;
}
{
stepsize = 20; /* must be choosen to always draw last frame */
door_delay_value = 0;
-
-#if 0
- StopSound(SND_DOOR_OPENING);
- StopSound(SND_DOOR_CLOSING);
-#endif
}
if (global.autoplay_leveldir)
}
}
-#if 0
- if (setup.quick_doors)
- {
- StopSound(SND_DOOR_OPENING);
- StopSound(SND_DOOR_CLOSING);
- }
-#endif
-
if (door_state & DOOR_ACTION_1)
door1 = door_state & DOOR_ACTION_1;
if (door_state & DOOR_ACTION_2)
request_gadget_id = gi->custom_id;
}
-#if 1
-
-static struct
+static struct Mapping_EM_to_RND_object
{
int element_em;
boolean is_rnd_to_em_mapping; /* unique mapping EM <-> RND */
int action;
int direction;
}
-mapping_EM_to_RND_list[] =
+em_object_mapping_list[] =
{
{
Xblank, TRUE, FALSE,
EL_EMPTY, -1, -1
},
{
- Yacid_splash_eB, FALSE, TRUE,
+ Yacid_splash_eB, FALSE, FALSE,
EL_ACID_SPLASH_RIGHT, -1, -1
},
{
- Yacid_splash_wB, FALSE, TRUE,
+ Yacid_splash_wB, FALSE, FALSE,
EL_ACID_SPLASH_LEFT, -1, -1
},
},
{
Ybomb_eat, FALSE, FALSE,
- EL_BOMB, ACTION_SMASHED_BY_ROCK, -1
+ EL_BOMB, ACTION_ACTIVATING, -1
},
{
Xballoon, TRUE, FALSE,
EL_EMC_GRASS, -1, -1
},
{
- Ygrass_nB, FALSE, TRUE,
+ Ygrass_nB, FALSE, FALSE,
EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_UP
},
{
- Ygrass_eB, FALSE, TRUE,
+ Ygrass_eB, FALSE, FALSE,
EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_RIGHT
},
{
- Ygrass_sB, FALSE, TRUE,
+ Ygrass_sB, FALSE, FALSE,
EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_DOWN
},
{
- Ygrass_wB, FALSE, TRUE,
+ Ygrass_wB, FALSE, FALSE,
EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_LEFT
},
{
EL_SAND, -1, -1
},
{
- Ydirt_nB, FALSE, TRUE,
+ Ydirt_nB, FALSE, FALSE,
EL_SAND, ACTION_DIGGING, MV_BIT_UP
},
{
- Ydirt_eB, FALSE, TRUE,
+ Ydirt_eB, FALSE, FALSE,
EL_SAND, ACTION_DIGGING, MV_BIT_RIGHT
},
{
- Ydirt_sB, FALSE, TRUE,
+ Ydirt_sB, FALSE, FALSE,
EL_SAND, ACTION_DIGGING, MV_BIT_DOWN
},
{
- Ydirt_wB, FALSE, TRUE,
+ Ydirt_wB, FALSE, FALSE,
EL_SAND, ACTION_DIGGING, MV_BIT_LEFT
},
{
EL_EMC_MAGIC_BALL, -1, -1
},
{
- Xball_1B, FALSE, TRUE,
+ Xball_1B, FALSE, FALSE,
EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
},
{
EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
},
{
- Xball_2B, FALSE, TRUE,
+ Xball_2B, FALSE, FALSE,
EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
},
{
Yball_eat, FALSE, FALSE,
EL_EMC_MAGIC_BALL, ACTION_DROPPING, -1
},
+ {
+ Ykey_1_eat, FALSE, FALSE,
+ EL_EM_KEY_1, ACTION_COLLECTING, -1
+ },
+ {
+ Ykey_2_eat, FALSE, FALSE,
+ EL_EM_KEY_2, ACTION_COLLECTING, -1
+ },
+ {
+ Ykey_3_eat, FALSE, FALSE,
+ EL_EM_KEY_3, ACTION_COLLECTING, -1
+ },
+ {
+ Ykey_4_eat, FALSE, FALSE,
+ EL_EM_KEY_4, ACTION_COLLECTING, -1
+ },
+ {
+ Ykey_5_eat, FALSE, FALSE,
+ EL_EMC_KEY_5, ACTION_COLLECTING, -1
+ },
+ {
+ Ykey_6_eat, FALSE, FALSE,
+ EL_EMC_KEY_6, ACTION_COLLECTING, -1
+ },
+ {
+ Ykey_7_eat, FALSE, FALSE,
+ EL_EMC_KEY_7, ACTION_COLLECTING, -1
+ },
+ {
+ Ykey_8_eat, FALSE, FALSE,
+ EL_EMC_KEY_8, ACTION_COLLECTING, -1
+ },
+ {
+ Ylenses_eat, FALSE, FALSE,
+ EL_EMC_LENSES, ACTION_COLLECTING, -1
+ },
+ {
+ Ymagnify_eat, FALSE, FALSE,
+ EL_EMC_MAGNIFIER, ACTION_COLLECTING, -1
+ },
+ {
+ Ygrass_eat, FALSE, FALSE,
+ EL_EMC_GRASS, ACTION_SNAPPING, -1
+ },
+ {
+ Ydirt_eat, FALSE, FALSE,
+ EL_SAND, ACTION_SNAPPING, -1
+ },
{
Xgrow_ns, TRUE, FALSE,
EL_EXPANDABLE_WALL_VERTICAL, -1, -1
EL_AMOEBA_DRY, ACTION_OTHER, -1
},
{
- Xamoeba_5, FALSE, FALSE,
+ Xamoeba_5, TRUE, FALSE,
EL_AMOEBA_WET, ACTION_OTHER, -1
},
{
},
{
Xdoor_5, TRUE, FALSE,
- EL_EM_GATE_5, -1, -1
+ EL_EMC_GATE_5, -1, -1
},
{
Xdoor_6, TRUE, FALSE,
- EL_EM_GATE_6, -1, -1
+ EL_EMC_GATE_6, -1, -1
},
{
Xdoor_7, TRUE, FALSE,
- EL_EM_GATE_7, -1, -1
+ EL_EMC_GATE_7, -1, -1
},
{
Xdoor_8, TRUE, FALSE,
- EL_EM_GATE_8, -1, -1
+ EL_EMC_GATE_8, -1, -1
},
{
Xkey_1, TRUE, FALSE,
},
{
Xkey_5, TRUE, FALSE,
- EL_EM_KEY_5, -1, -1
+ EL_EMC_KEY_5, -1, -1
},
{
Xkey_6, TRUE, FALSE,
- EL_EM_KEY_6, -1, -1
+ EL_EMC_KEY_6, -1, -1
},
{
Xkey_7, TRUE, FALSE,
- EL_EM_KEY_7, -1, -1
+ EL_EMC_KEY_7, -1, -1
},
{
Xkey_8, TRUE, FALSE,
- EL_EM_KEY_8, -1, -1
+ EL_EMC_KEY_8, -1, -1
},
{
Xwind_n, TRUE, FALSE,
},
{
Xfake_door_5, TRUE, FALSE,
- EL_EM_GATE_5_GRAY, -1, -1
+ EL_EMC_GATE_5_GRAY, -1, -1
},
{
Xfake_door_6, TRUE, FALSE,
- EL_EM_GATE_6_GRAY, -1, -1
+ EL_EMC_GATE_6_GRAY, -1, -1
},
{
Xfake_door_7, TRUE, FALSE,
- EL_EM_GATE_7_GRAY, -1, -1
+ EL_EMC_GATE_7_GRAY, -1, -1
},
{
Xfake_door_8, TRUE, FALSE,
- EL_EM_GATE_8_GRAY, -1, -1
+ EL_EMC_GATE_8_GRAY, -1, -1
+ },
+ {
+ Xfake_acid_1, TRUE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_2, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_3, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_4, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_5, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_6, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_7, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_8, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
},
{
Xsteel_1, TRUE, FALSE,
}
};
+static struct Mapping_EM_to_RND_player
+{
+ int action_em;
+ int player_nr;
+
+ int element_rnd;
+ int action;
+ int direction;
+}
+em_player_mapping_list[] =
+{
+ {
+ SPR_walk + 0, 0,
+ EL_PLAYER_1, ACTION_MOVING, MV_BIT_UP,
+ },
+ {
+ SPR_walk + 1, 0,
+ EL_PLAYER_1, ACTION_MOVING, MV_BIT_RIGHT,
+ },
+ {
+ SPR_walk + 2, 0,
+ EL_PLAYER_1, ACTION_MOVING, MV_BIT_DOWN,
+ },
+ {
+ SPR_walk + 3, 0,
+ EL_PLAYER_1, ACTION_MOVING, MV_BIT_LEFT,
+ },
+ {
+ SPR_push + 0, 0,
+ EL_PLAYER_1, ACTION_PUSHING, MV_BIT_UP,
+ },
+ {
+ SPR_push + 1, 0,
+ EL_PLAYER_1, ACTION_PUSHING, MV_BIT_RIGHT,
+ },
+ {
+ SPR_push + 2, 0,
+ EL_PLAYER_1, ACTION_PUSHING, MV_BIT_DOWN,
+ },
+ {
+ SPR_push + 3, 0,
+ EL_PLAYER_1, ACTION_PUSHING, MV_BIT_LEFT,
+ },
+ {
+ SPR_spray + 0, 0,
+ EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_UP,
+ },
+ {
+ SPR_spray + 1, 0,
+ EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_RIGHT,
+ },
+ {
+ SPR_spray + 2, 0,
+ EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_DOWN,
+ },
+ {
+ SPR_spray + 3, 0,
+ EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_LEFT,
+ },
+ {
+ SPR_walk + 0, 1,
+ EL_PLAYER_2, ACTION_MOVING, MV_BIT_UP,
+ },
+ {
+ SPR_walk + 1, 1,
+ EL_PLAYER_2, ACTION_MOVING, MV_BIT_RIGHT,
+ },
+ {
+ SPR_walk + 2, 1,
+ EL_PLAYER_2, ACTION_MOVING, MV_BIT_DOWN,
+ },
+ {
+ SPR_walk + 3, 1,
+ EL_PLAYER_2, ACTION_MOVING, MV_BIT_LEFT,
+ },
+ {
+ SPR_push + 0, 1,
+ EL_PLAYER_2, ACTION_PUSHING, MV_BIT_UP,
+ },
+ {
+ SPR_push + 1, 1,
+ EL_PLAYER_2, ACTION_PUSHING, MV_BIT_RIGHT,
+ },
+ {
+ SPR_push + 2, 1,
+ EL_PLAYER_2, ACTION_PUSHING, MV_BIT_DOWN,
+ },
+ {
+ SPR_push + 3, 1,
+ EL_PLAYER_2, ACTION_PUSHING, MV_BIT_LEFT,
+ },
+ {
+ SPR_spray + 0, 1,
+ EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_UP,
+ },
+ {
+ SPR_spray + 1, 1,
+ EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_RIGHT,
+ },
+ {
+ SPR_spray + 2, 1,
+ EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_DOWN,
+ },
+ {
+ SPR_spray + 3, 1,
+ EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_LEFT,
+ },
+ {
+ SPR_still, 0,
+ EL_PLAYER_1, ACTION_DEFAULT, -1,
+ },
+ {
+ SPR_still, 1,
+ EL_PLAYER_2, ACTION_DEFAULT, -1,
+ },
+
+ {
+ -1, -1,
+ -1, -1, -1
+ }
+};
+
int map_element_RND_to_EM(int element_rnd)
{
static unsigned short mapping_RND_to_EM[NUM_FILE_ELEMENTS];
for (i = 0; i < NUM_FILE_ELEMENTS; i++)
mapping_RND_to_EM[i] = Xalpha_quest;
- for (i = 0; mapping_EM_to_RND_list[i].element_em != -1; i++)
- if (mapping_EM_to_RND_list[i].is_rnd_to_em_mapping)
- mapping_RND_to_EM[mapping_EM_to_RND_list[i].element_rnd] =
- mapping_EM_to_RND_list[i].element_em;
+ for (i = 0; em_object_mapping_list[i].element_em != -1; i++)
+ if (em_object_mapping_list[i].is_rnd_to_em_mapping)
+ mapping_RND_to_EM[em_object_mapping_list[i].element_rnd] =
+ em_object_mapping_list[i].element_em;
mapping_initialized = TRUE;
}
for (i = 0; i < TILE_MAX; i++)
mapping_EM_to_RND[i] = EL_UNKNOWN;
- for (i = 0; mapping_EM_to_RND_list[i].element_em != -1; i++)
- mapping_EM_to_RND[mapping_EM_to_RND_list[i].element_em] =
- mapping_EM_to_RND_list[i].element_rnd;
+ 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;
}
return EL_UNKNOWN;
}
-#else
+#if 0
int map_element_RND_to_EM(int element_rnd)
{
int element_em;
int element_rnd;
}
- mapping_EM_to_RND_list[] =
+ em_object_mapping_list[] =
{
{ Xblank, EL_EMPTY },
{ Yacid_splash_eB, EL_EMPTY },
for (i = 0; i < TILE_MAX; i++)
mapping_EM_to_RND[i] = EL_UNKNOWN;
- for (i = 0; mapping_EM_to_RND_list[i].element_em != -1; i++)
- mapping_EM_to_RND[mapping_EM_to_RND_list[i].element_em] =
- mapping_EM_to_RND_list[i].element_rnd;
+ 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 0
+int el_act_dir2img(int element, int action, int direction)
+{
+ element = GFX_ELEMENT(element);
+
+ if (direction == MV_NO_MOVING)
+ return element_info[element].graphic[action];
+
+ direction = MV_DIR_BIT(direction);
+
+ return element_info[element].direction_graphic[action][direction];
+}
+#else
int el_act_dir2img(int element, int action, int direction)
{
element = GFX_ELEMENT(element);
direction = MV_DIR_BIT(direction); /* default: MV_NO_MOVING => MV_DOWN */
+ /* direction_graphic[][] == graphic[] for undefined direction graphics */
return element_info[element].direction_graphic[action][direction];
}
+#endif
+
+#if 0
+static int el_act_dir2crm(int element, int action, int direction)
+{
+ element = GFX_ELEMENT(element);
+
+ if (direction == MV_NO_MOVING)
+ return element_info[element].crumbled[action];
+ direction = MV_DIR_BIT(direction);
+
+ return element_info[element].direction_crumbled[action][direction];
+}
+#else
static int el_act_dir2crm(int element, int action, int direction)
{
element = GFX_ELEMENT(element);
direction = MV_DIR_BIT(direction); /* default: MV_NO_MOVING => MV_DOWN */
+ /* direction_graphic[][] == graphic[] for undefined direction graphics */
return element_info[element].direction_crumbled[action][direction];
}
+#endif
int el_act2img(int element, int action)
{
return element_info[element].special_graphic[GFX_SPECIAL_ARG_PREVIEW];
}
+int font2baseimg(int font_nr)
+{
+ return font_info[font_nr].special_graphic[GFX_SPECIAL_ARG_DEFAULT];
+}
+
int getGameFrameDelay_EM(int native_em_game_frame_delay)
{
- return (GameFrameDelay == GAME_FRAME_DELAY ? native_em_game_frame_delay :
- GameFrameDelay);
+ int game_frame_delay_value;
+
+ game_frame_delay_value =
+ (tape.playing && tape.fast_forward ? FfwdFrameDelay :
+ GameFrameDelay == GAME_FRAME_DELAY ? native_em_game_frame_delay :
+ GameFrameDelay);
+
+ if (tape.playing && tape.warp_forward && !tape.pausing)
+ game_frame_delay_value = 0;
+
+ return game_frame_delay_value;
}
unsigned int InitRND(long seed)
return InitEngineRND(seed);
}
+#define DEBUG_EM_GFX 0
+
void InitGraphicInfo_EM(void)
{
- int mapping_EM_to_RND_element[TILE_MAX];
- int mapping_EM_to_RND_action[TILE_MAX];
- int mapping_EM_to_RND_direction[TILE_MAX];
- boolean mapping_EM_to_RND_backside[TILE_MAX];
- int i, j;
+ struct Mapping_EM_to_RND_object object_mapping[TILE_MAX];
+ struct Mapping_EM_to_RND_player player_mapping[2][SPR_MAX];
+ int i, j, p;
- /* return "EL_UNKNOWN" for all undefined elements in mapping array */
+#if DEBUG_EM_GFX
+ if (graphic_info_em_object[0][0].bitmap == NULL)
+ {
+ /* EM graphics not yet initialized in em_open_all() */
+
+ return;
+ }
+#endif
+
+ /* always start with reliable default values */
for (i = 0; i < TILE_MAX; i++)
{
- mapping_EM_to_RND_element[i] = EL_UNKNOWN;
- mapping_EM_to_RND_backside[i] = FALSE;
- mapping_EM_to_RND_action[i] = ACTION_DEFAULT;
- mapping_EM_to_RND_direction[i] = MV_NO_MOVING;
+ object_mapping[i].element_rnd = EL_UNKNOWN;
+ object_mapping[i].is_backside = FALSE;
+ object_mapping[i].action = ACTION_DEFAULT;
+ object_mapping[i].direction = MV_NO_MOVING;
+ }
+
+ /* always start with reliable default values */
+ for (p = 0; p < 2; p++)
+ {
+ for (i = 0; i < SPR_MAX; i++)
+ {
+ player_mapping[p][i].element_rnd = EL_UNKNOWN;
+ player_mapping[p][i].action = ACTION_DEFAULT;
+ player_mapping[p][i].direction = MV_NO_MOVING;
+ }
+ }
+
+ for (i = 0; em_object_mapping_list[i].element_em != -1; i++)
+ {
+ int e = em_object_mapping_list[i].element_em;
+
+ object_mapping[e].element_rnd = em_object_mapping_list[i].element_rnd;
+ object_mapping[e].is_backside = em_object_mapping_list[i].is_backside;
+
+ if (em_object_mapping_list[i].action != -1)
+ object_mapping[e].action = em_object_mapping_list[i].action;
+
+ if (em_object_mapping_list[i].direction != -1)
+ object_mapping[e].direction = (1 << em_object_mapping_list[i].direction);
}
- for (i = 0; mapping_EM_to_RND_list[i].element_em != -1; i++)
+ for (i = 0; em_player_mapping_list[i].action_em != -1; i++)
{
- int e = mapping_EM_to_RND_list[i].element_em;
+ int a = em_player_mapping_list[i].action_em;
+ int p = em_player_mapping_list[i].player_nr;
- mapping_EM_to_RND_element[e] = mapping_EM_to_RND_list[i].element_rnd;
- mapping_EM_to_RND_backside[e] = mapping_EM_to_RND_list[i].is_backside;
+ player_mapping[p][a].element_rnd = em_player_mapping_list[i].element_rnd;
- if (mapping_EM_to_RND_list[i].action != -1)
- mapping_EM_to_RND_action[e] = mapping_EM_to_RND_list[i].action;
+ if (em_player_mapping_list[i].action != -1)
+ player_mapping[p][a].action = em_player_mapping_list[i].action;
- if (mapping_EM_to_RND_list[i].direction != -1)
- mapping_EM_to_RND_direction[e] = 1<< mapping_EM_to_RND_list[i].direction;
+ if (em_player_mapping_list[i].direction != -1)
+ player_mapping[p][a].direction =
+ (1 << em_player_mapping_list[i].direction);
}
for (i = 0; i < TILE_MAX; i++)
{
- int element = mapping_EM_to_RND_element[i];
- int action = mapping_EM_to_RND_action[i];
- int direction = mapping_EM_to_RND_direction[i];
- int backside = mapping_EM_to_RND_backside[i];
+ int element = object_mapping[i].element_rnd;
+ int action = object_mapping[i].action;
+ int direction = object_mapping[i].direction;
+ boolean is_backside = object_mapping[i].is_backside;
boolean action_removing = (action == ACTION_DIGGING ||
action == ACTION_SNAPPING ||
action == ACTION_COLLECTING);
for (j = 0; j < 8; j++)
{
- int effective_element = (j < 7 ? element :
- i == Ynut_sB ? element :
+ int effective_element = (j > 5 && i == Yacid_splash_eB ? EL_EMPTY :
+ j > 5 && i == Yacid_splash_wB ? EL_EMPTY :
+ j < 7 ? element :
i == Xdrip_stretch ? element :
i == Xdrip_stretchB ? element :
i == Ydrip_s1 ? element :
i == Xball_2 ? element :
i == Xball_2B ? element :
i == Yball_eat ? element :
+ i == Ykey_1_eat ? element :
+ i == Ykey_2_eat ? element :
+ i == Ykey_3_eat ? element :
+ i == Ykey_4_eat ? element :
+ i == Ykey_5_eat ? element :
+ i == Ykey_6_eat ? element :
+ i == Ykey_7_eat ? element :
+ i == Ykey_8_eat ? element :
+ i == Ylenses_eat ? element :
+ i == Ymagnify_eat ? element :
+ i == Ygrass_eat ? element :
+ i == Ydirt_eat ? element :
i == Yspring_kill_e ? EL_SPRING :
i == Yspring_kill_w ? EL_SPRING :
i == Yemerald_stone ? EL_EMERALD :
i == Ydiamond_stone ? EL_ROCK :
- backside ? EL_EMPTY :
+ i == Xsand_stonein_4 ? EL_EMPTY :
+ i == Xsand_stoneout_2 ? EL_ROCK :
+ is_backside ? EL_EMPTY :
action_removing ? EL_EMPTY :
element);
int effective_action = (j < 7 ? action :
- i == Ynut_sB ? action :
i == Xdrip_stretch ? action :
i == Xdrip_stretchB ? action :
i == Ydrip_s1 ? 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 == Xsand_stonein_1 ? action :
i == Xsand_stonein_2 ? action :
i == Xsand_stonein_3 ? action :
action_active ? action :
action_other ? action :
ACTION_DEFAULT);
- int graphic = (direction == MV_NO_MOVING ?
- el_act2img(effective_element, effective_action) :
- el_act_dir2img(effective_element, effective_action,
+ int graphic = (el_act_dir2img(effective_element, effective_action,
direction));
+ int crumbled = (el_act_dir2crm(effective_element, effective_action,
+ direction));
+ int base_graphic = el_act2img(effective_element, ACTION_DEFAULT);
+ int base_crumbled = el_act2crm(effective_element, ACTION_DEFAULT);
+ boolean has_crumbled_graphics = (base_crumbled != base_graphic);
struct GraphicInfo *g = &graphic_info[graphic];
- struct GraphicInfo_EM *g_em = &graphic_info_em[i][7 - j];
+ struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][7 - j];
Bitmap *src_bitmap;
int src_x, src_y;
+ /* 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 == Xacid_1 ? 0 :
- i == Xacid_2 ? 1 :
- i == Xacid_3 ? 2 :
- i == Xacid_4 ? 3 :
- i == Xacid_5 ? 4 :
- i == Xacid_6 ? 5 :
- i == Xacid_7 ? 6 :
- i == Xacid_8 ? 7 :
+ i == Xacid_2 ? 10 :
+ i == Xacid_3 ? 20 :
+ i == Xacid_4 ? 30 :
+ i == Xacid_5 ? 40 :
+ i == Xacid_6 ? 50 :
+ i == Xacid_7 ? 60 :
+ i == Xacid_8 ? 70 :
+ i == Xfake_acid_1 ? 0 :
+ i == Xfake_acid_2 ? 10 :
+ i == Xfake_acid_3 ? 20 :
+ i == Xfake_acid_4 ? 30 :
+ i == Xfake_acid_5 ? 40 :
+ i == Xfake_acid_6 ? 50 :
+ i == Xfake_acid_7 ? 60 :
+ i == Xfake_acid_8 ? 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 == Xamoeba_1 ? 0 :
i == Xamoeba_2 ? 1 :
i == Xamoeba_3 ? 2 :
i == Xexit_2 ? j + 8 :
i == Xexit_3 ? j + 16 :
i == Xdynamite_1 ? 0 :
- i == Xdynamite_2 ? 2 :
- i == Xdynamite_3 ? 4 :
- i == Xdynamite_4 ? 6 :
+ i == Xdynamite_2 ? 20 :
+ i == Xdynamite_3 ? 40 :
+ i == Xdynamite_4 ? 60 :
i == Xsand_stonein_1 ? j + 1 :
i == Xsand_stonein_2 ? j + 9 :
i == Xsand_stonein_3 ? j + 17 :
i == Xsand_stonein_4 ? j + 25 :
- i == Xsand_stoneout_1 && j == 0 ? 1 :
- i == Xsand_stoneout_1 && j == 1 ? 1 :
- i == Xsand_stoneout_1 && j == 2 ? 2 :
- i == Xsand_stoneout_1 && j == 3 ? 4 :
- i == Xsand_stoneout_1 && j == 4 ? 4 :
- i == Xsand_stoneout_1 && j == 5 ? 6 :
- i == Xsand_stoneout_1 && j == 6 ? 8 :
- i == Xsand_stoneout_1 && j == 7 ? 8 :
- i == Xsand_stoneout_2 && j == 0 ? 10 :
- i == Xsand_stoneout_2 && j == 1 ? 12 :
- i == Xsand_stoneout_2 && j == 2 ? 14 :
- i == Xsand_stoneout_2 && j == 3 ? 16 :
- i == Xsand_stoneout_2 && j == 4 ? 18 :
- i == Xsand_stoneout_2 && j == 5 ? 22 :
- i == Xsand_stoneout_2 && j == 6 ? 26 :
- i == Xsand_stoneout_2 && j == 7 ? 30 :
- i == Xboom_bug && j == 2 ? 1 :
- i == Xboom_bug && j == 3 ? 2 :
- i == Xboom_bug && j == 4 ? 2 :
- i == Xboom_bug && j == 5 ? 1 :
- i == Xboom_bug && j == 6 ? 1 :
+ i == Xsand_stoneout_1 && j == 0 ? 0 :
+ i == Xsand_stoneout_1 && j == 1 ? 0 :
+ i == Xsand_stoneout_1 && j == 2 ? 1 :
+ i == Xsand_stoneout_1 && j == 3 ? 2 :
+ i == Xsand_stoneout_1 && j == 4 ? 2 :
+ i == Xsand_stoneout_1 && j == 5 ? 3 :
+ i == Xsand_stoneout_1 && j == 6 ? 4 :
+ i == Xsand_stoneout_1 && j == 7 ? 4 :
+ i == Xsand_stoneout_2 && j == 0 ? 5 :
+ i == Xsand_stoneout_2 && j == 1 ? 6 :
+ i == Xsand_stoneout_2 && j == 2 ? 7 :
+ i == Xsand_stoneout_2 && j == 3 ? 8 :
+ i == Xsand_stoneout_2 && j == 4 ? 9 :
+ i == Xsand_stoneout_2 && j == 5 ? 11 :
+ i == Xsand_stoneout_2 && j == 6 ? 13 :
+ i == Xsand_stoneout_2 && j == 7 ? 15 :
+ i == Xboom_bug && j == 1 ? 2 :
+ i == Xboom_bug && j == 2 ? 2 :
+ i == Xboom_bug && j == 3 ? 4 :
+ i == Xboom_bug && j == 4 ? 4 :
+ i == Xboom_bug && j == 5 ? 2 :
+ i == Xboom_bug && j == 6 ? 2 :
i == Xboom_bug && j == 7 ? 0 :
- i == Xboom_bomb && j == 2 ? 1 :
- i == Xboom_bomb && j == 3 ? 2 :
- i == Xboom_bomb && j == 4 ? 2 :
- i == Xboom_bomb && j == 5 ? 1 :
- i == Xboom_bomb && j == 6 ? 1 :
+ 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_android && j == 7 ? 3 :
- i == Xboom_1 && j == 2 ? 1 :
- i == Xboom_1 && j == 3 ? 2 :
- i == Xboom_1 && j == 4 ? 2 :
- i == Xboom_1 && j == 5 ? 3 :
- i == Xboom_1 && j == 6 ? 3 :
- i == Xboom_1 && j == 7 ? 4 :
- i == Xboom_2 && j == 0 ? 4 :
- i == Xboom_2 && j == 1 ? 4 :
- i == Xboom_2 && j == 2 ? 5 :
- i == Xboom_2 && j == 3 ? 5 :
- i == Xboom_2 && j == 4 ? 5 :
- i == Xboom_2 && j == 5 ? 6 :
+ i == Xboom_android && j == 7 ? 6 :
+ i == Xboom_1 && j == 1 ? 2 :
+ i == Xboom_1 && j == 2 ? 2 :
+ i == Xboom_1 && j == 3 ? 4 :
+ i == Xboom_1 && j == 4 ? 4 :
+ i == Xboom_1 && j == 5 ? 6 :
+ i == Xboom_1 && j == 6 ? 6 :
+ i == Xboom_1 && j == 7 ? 8 :
+ i == Xboom_2 && j == 0 ? 8 :
+ i == Xboom_2 && j == 1 ? 8 :
+ i == Xboom_2 && j == 2 ? 10 :
+ i == Xboom_2 && j == 3 ? 10 :
+ i == Xboom_2 && j == 4 ? 10 :
+ i == Xboom_2 && j == 5 ? 12 :
+ i == Xboom_2 && j == 6 ? 12 :
+ i == Xboom_2 && j == 7 ? 12 :
+ special_animation && j == 4 ? 3 :
effective_action != action ? 0 :
j);
-#if 0
+
+#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;
sync_frame);
getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y,
- g->double_movement && backside);
+ g->double_movement && is_backside);
-#if 1
g_em->bitmap = src_bitmap;
g_em->src_x = src_x;
g_em->src_y = src_y;
g_em->dst_offset_y = 0;
g_em->width = TILEX;
g_em->height = TILEY;
+
+ g_em->crumbled_bitmap = NULL;
+ g_em->crumbled_src_x = 0;
+ g_em->crumbled_src_y = 0;
+ g_em->crumbled_border_size = 0;
+
+ g_em->has_crumbled_graphics = FALSE;
+ g_em->preserve_background = FALSE;
+
+#if 0
+ if (has_crumbled_graphics && crumbled == IMG_EMPTY_SPACE)
+ printf("::: empty crumbled: %d [%s], %d, %d\n",
+ effective_element, element_info[effective_element].token_name,
+ effective_action, direction);
#endif
-#if 1
+ /* if element can be crumbled, but certain action graphics are just empty
+ space (like snapping sand with the original R'n'D graphics), do not
+ treat these empty space graphics as crumbled graphics in EMC engine */
+ if (has_crumbled_graphics && crumbled != IMG_EMPTY_SPACE)
+ {
+ getGraphicSource(crumbled, frame, &src_bitmap, &src_x, &src_y);
+
+ g_em->has_crumbled_graphics = TRUE;
+ g_em->crumbled_bitmap = src_bitmap;
+ g_em->crumbled_src_x = src_x;
+ g_em->crumbled_src_y = src_y;
+ g_em->crumbled_border_size = graphic_info[crumbled].border_size;
+ }
+
if (!g->double_movement && (effective_action == ACTION_FALLING ||
effective_action == ACTION_MOVING ||
effective_action == ACTION_PUSHING))
(effective_action == ACTION_FALLING ? 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 cx = ABS(dx) * TILEX / 8;
- int cy = ABS(dy) * TILEY / 8;
-
- if (backside) /* tile where movement starts */
+ int num_steps = (i == Ydrip_s1 ||
+ i == Ydrip_s1B ||
+ i == Ydrip_s2 ||
+ i == Ydrip_s2B ? 16 : 8);
+ int cx = ABS(dx) * (TILEX / num_steps);
+ int cy = ABS(dy) * (TILEY / num_steps);
+ int step_frame = (i == Ydrip_s2 ||
+ i == Ydrip_s2B ? j + 8 : j) + 1;
+ int step = (is_backside ? step_frame : num_steps - step_frame);
+
+ if (is_backside) /* tile where movement starts */
{
if (dx < 0 || dy < 0)
{
- g_em->src_offset_x = cx * (j + 1);
- g_em->src_offset_y = cy * (j + 1);
+ g_em->src_offset_x = cx * step;
+ g_em->src_offset_y = cy * step;
}
else
{
- g_em->dst_offset_x = cx * (j + 1);
- g_em->dst_offset_y = cy * (j + 1);
+ g_em->dst_offset_x = cx * step;
+ g_em->dst_offset_y = cy * step;
}
-
- g_em->width = TILEX - cx * (j + 1);
- g_em->height = TILEY - cy * (j + 1);
}
else /* tile where movement ends */
{
if (dx < 0 || dy < 0)
{
- g_em->dst_offset_x = cx * (7 - j);
- g_em->dst_offset_y = cy * (7 - j);
+ g_em->dst_offset_x = cx * step;
+ g_em->dst_offset_y = cy * step;
}
else
{
- g_em->src_offset_x = cx * (7 - j);
- g_em->src_offset_y = cy * (7 - j);
+ g_em->src_offset_x = cx * step;
+ g_em->src_offset_y = cy * step;
}
-
- g_em->width = TILEX - cx * (7 - j);
- g_em->height = TILEY - cy * (7 - j);
}
+
+ g_em->width = TILEX - cx * step;
+ g_em->height = TILEY - cy * step;
}
-#endif
-#if 0
+ /* create unique graphic identifier to decide if tile must be redrawn */
+ /* bit 31 - 16 (16 bit): EM style element
+ 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 =
+ (i << 16) | (j << 12) | (g_em->width << 6) | g_em->height;
+
+#if DEBUG_EM_GFX
if (g_em->bitmap != debug_bitmap ||
g_em->src_x != debug_src_x ||
g_em->src_y != debug_src_y ||
if (i != last_i)
{
printf("\n");
-
last_i = i;
}
- printf("::: EMC GFX ERROR for element %d -> %d ('%s')",
- i, element, element_info[element].token_name);
+ 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);
+ effective_element,
+ element_info[effective_element].token_name);
printf("\n");
if (g_em->bitmap != debug_bitmap)
- printf(" %d(%d): different bitmap!\n",
- j, backside);
+ 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, (backside ? 'B' : 'F'),
+ 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,
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, backside,
+ 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, backside,
+ printf(" %d (%d): size %d,%d should be %d,%d\n",
+ j, is_backside,
g_em->width, g_em->height, TILEX, TILEY);
}
#endif
}
}
-#if 0
+ for (i = 0; i < TILE_MAX; i++)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ int element = object_mapping[i].element_rnd;
+ int action = object_mapping[i].action;
+
+ if (action == ACTION_SMASHED_BY_ROCK &&
+ element_info[element].graphic[action] ==
+ element_info[element].graphic[ACTION_DEFAULT])
+ {
+ /* 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[Ystone_s][7 - j];
+
+ g_em->bitmap = g_xx->bitmap;
+ g_em->src_x = g_xx->src_x;
+ g_em->src_y = g_xx->src_y;
+ g_em->src_offset_x = g_xx->src_offset_x;
+ g_em->src_offset_y = g_xx->src_offset_y;
+ g_em->dst_offset_x = g_xx->dst_offset_x;
+ g_em->dst_offset_y = g_xx->dst_offset_y;
+ g_em->width = g_xx->width;
+ g_em->height = g_xx->height;
+
+ g_em->preserve_background = TRUE;
+ }
+ }
+ }
+
+ for (p = 0; p < 2; p++)
+ {
+ for (i = 0; i < SPR_MAX; i++)
+ {
+ int element = player_mapping[p][i].element_rnd;
+ int action = player_mapping[p][i].action;
+ int direction = player_mapping[p][i].direction;
+
+ for (j = 0; j < 8; j++)
+ {
+ int effective_element = element;
+ int effective_action = action;
+ int graphic = (direction == MV_NO_MOVING ?
+ el_act2img(effective_element, effective_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];
+ 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->anim_start_frame,
+ sync_frame);
+
+ getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x,&src_y, FALSE);
+
+ g_em->bitmap = src_bitmap;
+ g_em->src_x = src_x;
+ g_em->src_y = 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;
+
+#if DEBUG_EM_GFX
+ 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);
+ }
+#endif
+
+ }
+ }
+ }
+
+#if DEBUG_EM_GFX
exit(0);
#endif
}