/* forward declaration for internal use */
static void UnmapToolButtons();
static void HandleToolButtons(struct GadgetInfo *);
+static int el_act_dir2crm(int, int, int);
+static int el_act2crm(int, int);
static struct GadgetInfo *tool_gadget[NUM_TOOL_BUTTONS];
static int request_gadget_id = -1;
void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height)
{
- if (game_status == GAME_MODE_PLAYING)
+ if (game_status == GAME_MODE_PLAYING && !game.envelope_active)
{
if (force_redraw)
{
return;
DrawGraphicAnimation(sx, sy, graphic);
+
+ if (GFX_CRUMBLED(Feld[x][y]))
+ DrawLevelFieldCrumbledSand(x, y);
}
void DrawLevelElementAnimationIfNeeded(int x, int y, int element)
return;
DrawGraphicAnimation(sx, sy, graphic);
+
+ if (GFX_CRUMBLED(element))
+ DrawLevelFieldCrumbledSand(x, y);
}
void DrawAllPlayers()
player->is_moving ? ACTION_MOVING :
player->snapped ? ACTION_SNAPPING : ACTION_DEFAULT);
+#if 0
+ printf("::: '%s'\n", element_action_info[action].suffix);
+#endif
+
InitPlayerGfxAnimation(player, action, move_dir);
/* ----------------------------------------------------------------------- */
{
if (player_is_moving && GfxElement[jx][jy] != EL_UNDEFINED)
{
+#if 1
+ if (GFX_CRUMBLED(GfxElement[jx][jy]))
+ DrawLevelFieldCrumbledSandDigging(jx, jy, move_dir, player->StepFrame);
+#else
if (GfxElement[jx][jy] == EL_SAND)
DrawLevelFieldCrumbledSandDigging(jx, jy, move_dir, player->StepFrame);
+#endif
else
{
int old_element = GfxElement[jx][jy];
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;
- element = (GfxElement[x][y] != EL_UNDEFINED ? GfxElement[x][y] : Feld[x][y]);
+ element = (GfxElement[x][y] != EL_UNDEFINED && Feld[x][y] != EL_EXPLOSION ?
+ GfxElement[x][y] : Feld[x][y]);
/* crumble field itself */
- if (CAN_BE_CRUMBLED(element) && !IS_MOVING(x, y))
+ if (GFX_CRUMBLED(element) && !IS_MOVING(x, y))
{
if (!IN_SCR_FIELD(sx, sy))
return;
element = (IN_LEV_FIELD(xx, yy) ? Feld[xx][yy] : BorderElement);
/* check if neighbour field is of same type */
- if (CAN_BE_CRUMBLED(element) && !IS_MOVING(xx, yy))
+ 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 = snip;
+ width = crumbled_border_size;
height = TILEY;
- cx = (i == 2 ? TILEX - snip : 0);
+ cx = (i == 2 ? TILEX - crumbled_border_size : 0);
cy = 0;
}
else
{
width = TILEX;
- height = snip;
+ height = crumbled_border_size;
cx = 0;
- cy = (i == 3 ? TILEY - snip : 0);
+ cy = (i == 3 ? TILEY - crumbled_border_size : 0);
}
BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
}
else /* crumble neighbour fields */
{
+#if 0
getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
+#endif
for(i=0; i<4; i++)
{
if (!IN_LEV_FIELD(xx, yy) ||
!IN_SCR_FIELD(sxx, syy) ||
- !CAN_BE_CRUMBLED(Feld[xx][yy]) ||
+ !GFX_CRUMBLED(Feld[xx][yy]) ||
IS_MOVING(xx, yy))
continue;
+#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)
{
- width = snip;
+ width = crumbled_border_size;
height = TILEY;
- cx = (i == 1 ? TILEX - snip : 0);
+ cx = (i == 1 ? TILEX - crumbled_border_size : 0);
cy = 0;
}
else
{
width = TILEX;
- height = snip;
+ height = crumbled_border_size;
cx = 0;
- cy = (i==0 ? TILEY-snip : 0);
+ cy = (i == 0 ? TILEY - crumbled_border_size : 0);
}
BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
void DrawLevelFieldCrumbledSand(int x, int y)
{
+#if 1
+ int graphic;
+
+ if (!IN_LEV_FIELD(x, y))
+ return;
+
+ 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);
if (!IN_LEV_FIELD(xx, yy) ||
!IN_SCR_FIELD(sxx, syy) ||
- !CAN_BE_CRUMBLED(Feld[xx][yy]) ||
+ !GFX_CRUMBLED(Feld[xx][yy]) ||
IS_MOVING(xx, yy))
continue;
{ EL_STEELWALL, EL_INVISIBLE_STEELWALL }
};
int steel_type = (BorderElement == EL_STEELWALL ? 0 : 1);
- int steel_position = (x == -1 && y == -1 ? 0 :
- x == lev_fieldx && y == -1 ? 1 :
- x == -1 && y == lev_fieldy ? 2 :
- x == lev_fieldx && y == lev_fieldy ? 3 :
- x == -1 || x == lev_fieldx ? 4 :
- y == -1 || y == lev_fieldy ? 5 : 6);
+ int steel_position = (x == -1 && y == -1 ? 0 :
+ x == lev_fieldx && y == -1 ? 1 :
+ x == -1 && y == lev_fieldy ? 2 :
+ x == lev_fieldx && y == lev_fieldy ? 3 :
+ x == -1 || x == lev_fieldx ? 4 :
+ y == -1 || y == lev_fieldy ? 5 : 6);
return border[steel_position][steel_type];
}
DrawMiniGraphic(sx, sy, el2edimg(getBorderElement(x, y)));
}
+void DrawEnvelopeBackground(int envelope_nr, 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);
+ int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr;
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int dst_x = SX + startx + x * font_width;
+ int dst_y = SY + starty + y * font_height;
+ int width = graphic_info[graphic].width;
+ int height = graphic_info[graphic].height;
+ int inner_width = MAX(width - 2 * font_width, font_width);
+ int inner_height = MAX(height - 2 * font_height, font_height);
+ int inner_sx = (width >= 3 * font_width ? font_width : 0);
+ int inner_sy = (height >= 3 * font_height ? font_height : 0);
+ boolean draw_masked = graphic_info[graphic].draw_masked;
+
+ getGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y);
+
+ if (src_bitmap == NULL || width < font_width || height < font_height)
+ {
+ ClearRectangle(drawto, dst_x, dst_y, font_width, font_height);
+ return;
+ }
+
+ src_x += (x == 0 ? 0 : x == xsize - 1 ? width - font_width :
+ inner_sx + (x - 1) * font_width % inner_width);
+ src_y += (y == 0 ? 0 : y == ysize - 1 ? height - font_height :
+ inner_sy + (y - 1) * font_height % inner_height);
+
+ if (draw_masked)
+ {
+ SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, font_width, font_height,
+ dst_x, dst_y);
+ }
+ else
+ BlitBitmap(src_bitmap, drawto, src_x, src_y, font_width, font_height,
+ dst_x, dst_y);
+}
+
+void AnimateEnvelope(int envelope_nr, int anim_mode, int action)
+{
+ int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr;
+ boolean draw_masked = graphic_info[graphic].draw_masked;
+ int mask_mode = (draw_masked ? BLIT_MASKED : BLIT_ON_BACKGROUND);
+ boolean ffwd_delay = (tape.playing && tape.fast_forward);
+ unsigned long anim_delay = 0;
+ int anim_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay);
+ int font_nr = FONT_ENVELOPE_1 + envelope_nr;
+ int font_width = getFontWidth(font_nr);
+ int font_height = getFontHeight(font_nr);
+ int max_xsize = level.envelope_xsize[envelope_nr];
+ int max_ysize = level.envelope_ysize[envelope_nr];
+ int xstart = (anim_mode & ANIM_VERTICAL ? max_xsize : 0);
+ int ystart = (anim_mode & ANIM_HORIZONTAL ? max_ysize : 0);
+ int xend = max_xsize;
+ int yend = (anim_mode != ANIM_DEFAULT ? max_ysize : 0);
+ int xstep = (xstart < xend ? 1 : 0);
+ int ystep = (ystart < yend || xstep == 0 ? 1 : 0);
+ int x, y;
+
+ for (x=xstart, y=ystart; x <= xend && y <= yend; x += xstep, y += ystep)
+ {
+ int xsize = (action == ACTION_CLOSING ? xend - (x - xstart) : x) + 2;
+ int ysize = (action == ACTION_CLOSING ? yend - (y - ystart) : y) + 2;
+ int sx = (SXSIZE - xsize * font_width) / 2;
+ int sy = (SYSIZE - ysize * font_height) / 2;
+ int xx, yy;
+
+ SetDrawtoField(DRAW_BUFFERED);
+
+ BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY);
+
+ SetDrawtoField(DRAW_BACKBUFFER);
+
+ for (yy=0; yy < ysize; yy++) for (xx=0; xx < xsize; xx++)
+ DrawEnvelopeBackground(envelope_nr, sx,sy, xx,yy, xsize, ysize, font_nr);
+
+ DrawTextToTextArea(SX + sx + font_width, SY + sy + font_height,
+ level.envelope_text[envelope_nr], font_nr, max_xsize,
+ xsize - 2, ysize - 2, mask_mode);
+
+ redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER;
+ BackToFront();
+
+ WaitUntilDelayReached(&anim_delay, anim_delay_value / 2);
+ }
+}
+
+void ShowEnvelope(int envelope_nr)
+{
+ int element = EL_ENVELOPE_1 + envelope_nr;
+ int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr;
+ int sound_opening = element_info[element].sound[ACTION_OPENING];
+ int sound_closing = element_info[element].sound[ACTION_CLOSING];
+ boolean ffwd_delay = (tape.playing && tape.fast_forward);
+ int wait_delay_value = (ffwd_delay ? 500 : 1000);
+ 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);
+
+ game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */
+
+ PlaySoundStereo(sound_opening, SOUND_MIDDLE);
+
+ if (anim_mode == ANIM_DEFAULT)
+ AnimateEnvelope(envelope_nr, ANIM_DEFAULT, ACTION_OPENING);
+
+ AnimateEnvelope(envelope_nr, main_anim_mode, ACTION_OPENING);
+
+ if (tape.playing)
+ Delay(wait_delay_value);
+ else
+ WaitForEventToContinue();
+
+ PlaySoundStereo(sound_closing, SOUND_MIDDLE);
+
+ if (anim_mode != ANIM_NONE)
+ AnimateEnvelope(envelope_nr, main_anim_mode, ACTION_CLOSING);
+
+ if (anim_mode == ANIM_DEFAULT)
+ AnimateEnvelope(envelope_nr, ANIM_DEFAULT, ACTION_CLOSING);
+
+ game.envelope_active = FALSE;
+
+ SetDrawtoField(DRAW_BUFFERED);
+
+ redraw_mask |= REDRAW_FIELD;
+ BackToFront();
+}
+
void getMicroGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
{
Bitmap *src_bitmap = graphic_info[graphic].bitmap;
if (strlen(label_text) > 0)
{
- int text_width = strlen(label_text) * getFontWidth(font_nr);
- int lxpos = SX + (SXSIZE - text_width) / 2;
+ int lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
int lypos = MICROLABEL_YPOS;
DrawText(lxpos, lypos, label_text, font_nr);
if (leveldir_current->name)
{
- int len = strlen(leveldir_current->name);
- int lxpos = SX + (SXSIZE - len * getFontWidth(FONT_TEXT_1)) / 2;
+ int text_width = getTextWidth(leveldir_current->name, FONT_TEXT_1);
+ int lxpos = SX + (SXSIZE - text_width) / 2;
int lypos = SY + 352;
DrawText(lxpos, lypos, leveldir_current->name, FONT_TEXT_1);
game_status = last_game_status; /* restore current game status */
}
-int REQ_in_range(int x, int y)
+void WaitForEventToContinue()
{
- if (y > DY+249 && y < DY+278)
+ boolean still_wait = TRUE;
+
+ /* simulate releasing mouse button over last gadget, if still pressed */
+ if (button_status)
+ HandleGadgets(-1, -1, 0);
+
+ button_status = MB_RELEASED;
+
+ while (still_wait)
{
- if (x > DX+1 && x < DX+48)
- return 1;
- else if (x > DX+51 && x < DX+98)
- return 2;
+ if (PendingEvent())
+ {
+ Event event;
+
+ NextEvent(&event);
+
+ switch (event.type)
+ {
+ case EVENT_BUTTONPRESS:
+ case EVENT_KEYPRESS:
+ still_wait = FALSE;
+ break;
+
+ case EVENT_KEYRELEASE:
+ ClearPlayerAction();
+ break;
+
+ default:
+ HandleOtherEvents(&event);
+ break;
+ }
+ }
+ else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
+ {
+ still_wait = FALSE;
+ }
+
+ DoAnimation();
+
+ /* don't eat all CPU time */
+ Delay(10);
}
- return 0;
}
#define MAX_REQUEST_LINES 13
unsigned int old_door_state;
int last_game_status = game_status; /* save current game status */
+#if 1
+ SetMouseCursor(CURSOR_DEFAULT);
+#endif
+
#if defined(PLATFORM_UNIX)
/* pause network game while waiting for request to answer */
if (options.network &&
SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
+#if 0
+ SetMouseCursor(CURSOR_DEFAULT);
+#endif
+
while(result < 0)
{
if (PendingEvent())
{
static int door1 = DOOR_OPEN_1;
static int door2 = DOOR_CLOSE_2;
- static unsigned long door_delay = 0;
- int x, start, stepsize = door.step_offset;
- unsigned long door_delay_value = door.step_delay;
+ unsigned long door_delay = 0;
+ unsigned long door_delay_value;
+ int stepsize = 1;
if (door_state == DOOR_GET_STATE)
return(door1 | door2);
else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
door_state &= ~DOOR_CLOSE_2;
+ door_delay_value = (door_state & DOOR_ACTION_1 ? door_1.step_delay :
+ door_2.step_delay);
+
if (setup.quick_doors)
{
- stepsize = 20;
+ stepsize = 20; /* must be choosen to always draw last frame */
door_delay_value = 0;
StopSound(SND_DOOR_OPENING);
if (door_state & DOOR_ACTION)
{
+ boolean door_1_done = !(door_state & DOOR_ACTION_1);
+ boolean door_2_done = !(door_state & DOOR_ACTION_2);
+ int start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
+ int end = (door_state & DOOR_ACTION_1 &&
+ door_1.anim_mode == ANIM_VERTICAL ? DYSIZE : DXSIZE);
+ int x;
+
if (!(door_state & DOOR_NO_DELAY))
{
/* opening door sound has priority over simultaneously closing door */
PlaySoundStereo(SND_DOOR_CLOSING, SOUND_MIDDLE);
}
- start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
-
- for(x=start; x<=DXSIZE; x+=stepsize)
+ for(x = start; x <= end && !(door_1_done && door_2_done); x += stepsize)
{
Bitmap *bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
GC gc = bitmap->stored_clip_gc;
- if (!(door_state & DOOR_NO_DELAY))
- WaitUntilDelayReached(&door_delay, door_delay_value);
-
if (door_state & DOOR_ACTION_1)
{
- int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
- int j = (DXSIZE - i) / 3;
-
- BlitBitmap(bitmap_db_door, drawto,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
- DXSIZE,DYSIZE - i/2, DX, DY);
-
- ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
-
- SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
- BlitBitmapMasked(bitmap, drawto,
- DXSIZE, DOOR_GFX_PAGEY1, i, 77,
- DX + DXSIZE - i, DY + j);
- BlitBitmapMasked(bitmap, drawto,
- DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
- DX + DXSIZE - i, DY + 140 + j);
- SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
- BlitBitmapMasked(bitmap, drawto,
- DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
- DX, DY);
- BlitBitmapMasked(bitmap, drawto,
- DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
- DX, DY + 140 - j);
-
- BlitBitmapMasked(bitmap, drawto,
- DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
- DX, DY + 77 - j);
- BlitBitmapMasked(bitmap, drawto,
- DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
- DX, DY + 203 - j);
- SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
- BlitBitmapMasked(bitmap, drawto,
- DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
- DX + DXSIZE - i, DY + 77 + j);
- BlitBitmapMasked(bitmap, drawto,
- DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
- DX + DXSIZE - i, DY + 203 + j);
+ int a = MIN(x * door_1.step_offset, end);
+ int i = (door_state & DOOR_OPEN_1 ? end - a : a);
+
+ if (x <= a)
+ {
+ BlitBitmap(bitmap_db_door, drawto,
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i / 2,
+ DXSIZE,DYSIZE - i / 2, DX, DY);
+
+ ClearRectangle(drawto, DX, DY + DYSIZE - i / 2, DXSIZE, i / 2);
+ }
+
+ if (door_1.anim_mode == ANIM_HORIZONTAL && x <= DXSIZE)
+ {
+ int src1_x = DXSIZE, src1_y = DOOR_GFX_PAGEY1;
+ int dst1_x = DX + DXSIZE - i, dst1_y = DY;
+ int src2_x = DXSIZE - i, src2_y = DOOR_GFX_PAGEY1;
+ int dst2_x = DX, dst2_y = DY;
+ int width = i, height = DYSIZE;
+
+ SetClipOrigin(bitmap, gc, dst1_x - src1_x, dst1_y - src1_y);
+ BlitBitmapMasked(bitmap, drawto, src1_x, src1_y, width, height,
+ dst1_x, dst1_y);
+
+ SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src2_y);
+ BlitBitmapMasked(bitmap, drawto, src2_x, src2_y, width, height,
+ dst2_x, dst2_y);
+ }
+ else if (door_1.anim_mode == ANIM_VERTICAL && x <= DYSIZE)
+ {
+ int src1_x = DXSIZE, src1_y = DOOR_GFX_PAGEY1;
+ int dst1_x = DX, dst1_y = DY + DYSIZE - i;
+ int src2_x = 0, src2_y = DOOR_GFX_PAGEY1 + DYSIZE - i;
+ int dst2_x = DX, dst2_y = DY;
+ int width = DXSIZE, height = i;
+
+ SetClipOrigin(bitmap, gc, dst1_x - src1_x, dst1_y - src1_y);
+ BlitBitmapMasked(bitmap, drawto, src1_x, src1_y, width, height,
+ dst1_x, dst1_y);
+
+ SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src2_y);
+ BlitBitmapMasked(bitmap, drawto, src2_x, src2_y, width, height,
+ dst2_x, dst2_y);
+ }
+ else if (x <= DXSIZE) /* ANIM_DEFAULT */
+ {
+ int j = (door_1.anim_mode == ANIM_DEFAULT ? (DXSIZE - i) / 3 : 0);
+
+ SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE, DOOR_GFX_PAGEY1, i, 77,
+ DX + DXSIZE - i, DY + j);
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
+ DX + DXSIZE - i, DY + 140 + j);
+ SetClipOrigin(bitmap, gc, DX - DXSIZE + i,
+ DY - (DOOR_GFX_PAGEY1 + j));
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
+ DX, DY);
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
+ DX, DY + 140 - j);
+
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
+ DX, DY + 77 - j);
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
+ DX, DY + 203 - j);
+ SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
+ DX + DXSIZE - i, DY + 77 + j);
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
+ DX + DXSIZE - i, DY + 203 + j);
+ }
redraw_mask |= REDRAW_DOOR_1;
+ door_1_done = (a == end);
}
if (door_state & DOOR_ACTION_2)
{
- int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
- int j = (VXSIZE - i) / 3;
-
- BlitBitmap(bitmap_db_door, drawto,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
- VXSIZE, VYSIZE - i/2, VX, VY);
-
- ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
-
- SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
- BlitBitmapMasked(bitmap, drawto,
- VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
- VX + VXSIZE-i, VY+j);
- SetClipOrigin(bitmap, gc,
- VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
- BlitBitmapMasked(bitmap, drawto,
- VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
- VX, VY);
-
- BlitBitmapMasked(bitmap, drawto,
- VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
- i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
- SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
- BlitBitmapMasked(bitmap, drawto,
- VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
- i, VYSIZE / 2 - j,
- VX + VXSIZE - i, VY + VYSIZE / 2 + j);
+ int a = MIN(x * door_2.step_offset, VXSIZE);
+ int i = (door_state & DOOR_OPEN_2 ? VXSIZE - a : a);
+
+ if (x <= VYSIZE)
+ {
+ BlitBitmap(bitmap_db_door, drawto,
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i / 2,
+ VXSIZE, VYSIZE - i / 2, VX, VY);
+
+ ClearRectangle(drawto, VX, VY + VYSIZE - i / 2, VXSIZE, i / 2);
+ }
+
+ if (door_2.anim_mode == ANIM_HORIZONTAL && x <= VXSIZE)
+ {
+ int src1_x = VXSIZE, src1_y = DOOR_GFX_PAGEY2;
+ int dst1_x = VX + VXSIZE - i, dst1_y = VY;
+ int src2_x = VXSIZE - i, src2_y = DOOR_GFX_PAGEY2;
+ int dst2_x = VX, dst2_y = VY;
+ int width = i, height = VYSIZE;
+
+ SetClipOrigin(bitmap, gc, dst1_x - src1_x, dst1_y - src1_y);
+ BlitBitmapMasked(bitmap, drawto, src1_x, src1_y, width, height,
+ dst1_x, dst1_y);
+
+ SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src2_y);
+ BlitBitmapMasked(bitmap, drawto, src2_x, src2_y, width, height,
+ dst2_x, dst2_y);
+ }
+ else if (door_2.anim_mode == ANIM_VERTICAL && x <= VYSIZE)
+ {
+ int src1_x = VXSIZE, src1_y = DOOR_GFX_PAGEY2;
+ int dst1_x = VX, dst1_y = VY + VYSIZE - i;
+ int src2_x = 0, src2_y = DOOR_GFX_PAGEY2 + VYSIZE - i;
+ int dst2_x = VX, dst2_y = VY;
+ int width = VXSIZE, height = i;
+
+ SetClipOrigin(bitmap, gc, dst1_x - src1_x, dst1_y - src1_y);
+ BlitBitmapMasked(bitmap, drawto, src1_x, src1_y, width, height,
+ dst1_x, dst1_y);
+
+ SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src2_y);
+ BlitBitmapMasked(bitmap, drawto, src2_x, src2_y, width, height,
+ dst2_x, dst2_y);
+ }
+ else if (x <= VXSIZE) /* ANIM_DEFAULT */
+ {
+ int j = (door_2.anim_mode == ANIM_DEFAULT ? (VXSIZE - i) / 3 : 0);
+
+ SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
+ BlitBitmapMasked(bitmap, drawto,
+ VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
+ VX + VXSIZE - i, VY + j);
+ SetClipOrigin(bitmap, gc,
+ VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
+ BlitBitmapMasked(bitmap, drawto,
+ VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
+ VX, VY);
+
+ BlitBitmapMasked(bitmap, drawto,
+ VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
+ i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
+ SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
+ BlitBitmapMasked(bitmap, drawto,
+ VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
+ i, VYSIZE / 2 - j,
+ VX + VXSIZE - i, VY + VYSIZE / 2 + j);
+ }
redraw_mask |= REDRAW_DOOR_2;
+ door_2_done = (a == VXSIZE);
}
BackToFront();
if (game_status == GAME_MODE_MAIN)
DoAnimation();
+
+ if (!(door_state & DOOR_NO_DELAY))
+ WaitUntilDelayReached(&door_delay, door_delay_value);
}
}
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_BIT(direction);
+
+ return element_info[element].direction_crumbled[action][direction];
+}
+
int el_act2img(int element, int action)
{
element = GFX_ELEMENT(element);
return element_info[element].graphic[action];
}
+int el_act2crm(int element, int action)
+{
+ element = GFX_ELEMENT(element);
+
+ return element_info[element].crumbled[action];
+}
+
int el_dir2img(int element, int direction)
{
element = GFX_ELEMENT(element);