* tools.c *
***********************************************************/
+#include <math.h>
+
#include "libgame/libgame.h"
#include "tools.h"
#define NUM_TOOL_BUTTONS 7
+/* constants for number of doors and door parts */
+#define NUM_DOORS 2
+#define NUM_PANELS NUM_DOORS
+// #define NUM_PANELS 0
+#define MAX_PARTS_PER_DOOR 8
+#define MAX_DOOR_PARTS (NUM_DOORS * MAX_PARTS_PER_DOOR + NUM_PANELS)
+#define DOOR_PART_IS_PANEL(i) ((i) >= NUM_DOORS * MAX_PARTS_PER_DOOR)
+
+
+struct DoorPartOrderInfo
+{
+ int nr;
+ int sort_priority;
+};
+
+static struct DoorPartOrderInfo door_part_order[MAX_DOOR_PARTS];
+
+struct DoorPartControlInfo
+{
+ int door_token;
+ int graphic;
+ struct DoorPartPosInfo *pos;
+};
+
+static struct DoorPartControlInfo door_part_controls[] =
+{
+ {
+ DOOR_1,
+ IMG_DOOR_1_GFX_PART_1,
+ &door_1.part_1
+ },
+ {
+ DOOR_1,
+ IMG_DOOR_1_GFX_PART_2,
+ &door_1.part_2
+ },
+ {
+ DOOR_1,
+ IMG_DOOR_1_GFX_PART_3,
+ &door_1.part_3
+ },
+ {
+ DOOR_1,
+ IMG_DOOR_1_GFX_PART_4,
+ &door_1.part_4
+ },
+ {
+ DOOR_1,
+ IMG_DOOR_1_GFX_PART_5,
+ &door_1.part_5
+ },
+ {
+ DOOR_1,
+ IMG_DOOR_1_GFX_PART_6,
+ &door_1.part_6
+ },
+ {
+ DOOR_1,
+ IMG_DOOR_1_GFX_PART_7,
+ &door_1.part_7
+ },
+ {
+ DOOR_1,
+ IMG_DOOR_1_GFX_PART_8,
+ &door_1.part_8
+ },
+
+ {
+ DOOR_2,
+ IMG_DOOR_2_GFX_PART_1,
+ &door_2.part_1
+ },
+ {
+ DOOR_2,
+ IMG_DOOR_2_GFX_PART_2,
+ &door_2.part_2
+ },
+ {
+ DOOR_2,
+ IMG_DOOR_2_GFX_PART_3,
+ &door_2.part_3
+ },
+ {
+ DOOR_2,
+ IMG_DOOR_2_GFX_PART_4,
+ &door_2.part_4
+ },
+ {
+ DOOR_2,
+ IMG_DOOR_2_GFX_PART_5,
+ &door_2.part_5
+ },
+ {
+ DOOR_2,
+ IMG_DOOR_2_GFX_PART_6,
+ &door_2.part_6
+ },
+ {
+ DOOR_2,
+ IMG_DOOR_2_GFX_PART_7,
+ &door_2.part_7
+ },
+ {
+ DOOR_2,
+ IMG_DOOR_2_GFX_PART_8,
+ &door_2.part_8
+ },
+
+ {
+ DOOR_1,
+ IMG_BACKGROUND_PANEL,
+ &door_1.panel
+ },
+ {
+ DOOR_2,
+ IMG_BACKGROUND_TAPE,
+ &door_2.panel
+ },
+
+ {
+ -1,
+ -1,
+ NULL
+ }
+};
+
+
/* forward declaration for internal use */
static void UnmapToolButtons();
static void HandleToolButtons(struct GadgetInfo *);
}
}
+#if 1
+
+static void RedrawPlayfield_RND()
+{
+ if (game.envelope_active)
+ return;
+
+#if 1
+ DrawLevel(REDRAW_ALL);
+#else
+ int x, y;
+
+ SetMainBackgroundImage(IMG_BACKGROUND_PLAYING);
+ // SetDrawBackgroundMask(REDRAW_FIELD); // !!! CHECK THIS !!!
+ SetDrawBackgroundMask(REDRAW_ALL); // !!! CHECK THIS !!!
+
+ for (x = BX1; x <= BX2; x++)
+ for (y = BY1; y <= BY2; y++)
+ DrawScreenField(x, y);
+
+ redraw_mask |= REDRAW_FIELD;
+#endif
+ DrawAllPlayers();
+
+#if 0
+#if NEW_TILESIZE
+ BlitScreenToBitmap(backbuffer);
+#else
+ /* blit playfield from scroll buffer to normal back buffer */
+ if (setup.soft_scrolling)
+ {
+ int fx = FX, fy = FY;
+
+ fx += (ScreenMovDir & (MV_LEFT|MV_RIGHT) ? ScreenGfxPos : 0);
+ fy += (ScreenMovDir & (MV_UP|MV_DOWN) ? ScreenGfxPos : 0);
+
+ BlitBitmap(fieldbuffer, backbuffer, fx,fy, SXSIZE,SYSIZE, SX,SY);
+ }
+#endif
+#endif
+}
+
+void RedrawPlayfield()
+{
+ if (game_status != GAME_MODE_PLAYING)
+ return;
+
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ RedrawPlayfield_EM(TRUE);
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
+ RedrawPlayfield_SP(TRUE);
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_RND)
+ RedrawPlayfield_RND();
+
+ BlitScreenToBitmap(backbuffer);
+
+ BlitBitmap(drawto, window, gfx.sx, gfx.sy, gfx.sxsize, gfx.sysize,
+ gfx.sx, gfx.sy);
+}
+
+#else
+
void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height)
{
if (game_status == GAME_MODE_PLAYING &&
BlitBitmap(drawto, window, x, y, width, height, x, y);
}
+#endif
+
void DrawMaskedBorder_Rect(int x, int y, int width, int height)
{
Bitmap *bitmap = graphic_info[IMG_GLOBAL_BORDER].bitmap;
}
}
-void BlitScreenToBitmap(Bitmap *target_bitmap)
+static void BlitScreenToBitmap_RND(Bitmap *target_bitmap)
{
DrawBuffer *buffer = (drawto_field == window ? backbuffer : drawto_field);
int fx = FX, fy = FY;
+ int full_lev_fieldx = lev_fieldx + (BorderElement != EL_EMPTY ? 2 : 0);
+ int full_lev_fieldy = lev_fieldy + (BorderElement != EL_EMPTY ? 2 : 0);
#if NEW_TILESIZE
int dx = (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
fx, fy);
#endif
+#if 1
+ if (full_lev_fieldx <= SCR_FIELDX)
+ {
+ // printf(":1: PLAYFIELD FITS TO SCREEN [%d, %d, %d]\n", fx, ffx, dx_var);
+
+ if (EVEN(SCR_FIELDX))
+ fx = 2 * TILEX_VAR - (ODD(lev_fieldx) ? TILEX_VAR / 2 : 0);
+ else
+ fx = 2 * TILEX_VAR - (EVEN(lev_fieldx) ? TILEX_VAR / 2 : 0);
+
+ // printf(":2: PLAYFIELD FITS TO SCREEN [%d, %d, %d]\n", fx, ffx, dx_var);
+ }
+
+ if (full_lev_fieldy <= SCR_FIELDY)
+ {
+ if (EVEN(SCR_FIELDY))
+ fy = 2 * TILEY_VAR - (ODD(lev_fieldy) ? TILEY_VAR / 2 : 0);
+ else
+ fy = 2 * TILEY_VAR - (EVEN(lev_fieldy) ? TILEY_VAR / 2 : 0);
+ }
+#endif
+
if (border.draw_masked[GAME_MODE_PLAYING])
{
if (buffer != backbuffer)
}
}
+void BlitScreenToBitmap(Bitmap *target_bitmap)
+{
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ BlitScreenToBitmap_EM(target_bitmap);
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
+ BlitScreenToBitmap_SP(target_bitmap);
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_RND)
+ BlitScreenToBitmap_RND(target_bitmap);
+}
+
void BackToFront()
{
int x, y;
if (redraw_mask & REDRAW_ALL)
{
+#if 0
+ if (game_status != GAME_MODE_PLAYING ||
+ redraw_mask & REDRAW_FROM_BACKBUFFER)
+ {
+#if 0
+ printf("::: REDRAW_ALL [%d]\n", FrameCounter);
+#endif
+
+ BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+
+ redraw_mask = REDRAW_NONE;
+ }
+ else
+ {
+ redraw_mask &= ~REDRAW_ALL;
+ }
+#else
+#if 0
+ printf("::: REDRAW_ALL [%d]\n", FrameCounter);
+#endif
+
BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
redraw_mask = REDRAW_NONE;
+#endif
}
if (redraw_mask & REDRAW_FIELD)
{
#if 0
- printf("::: REDRAW_FIELD\n");
+ printf("::: REDRAW_FIELD [%d]\n", FrameCounter);
#endif
if (game_status != GAME_MODE_PLAYING ||
else
{
#if 1
- BlitScreenToBitmap(window);
+ BlitScreenToBitmap_RND(window);
#else
int fx = FX, fy = FY;
ClearRectangle(backbuffer, x, y, width, height);
#endif
+#if 1
+
+#if 1
+ BlitBitmap(backbuffer, window, x, y, width, height, x, y);
+
+ redraw_mask &= ~fade_mask;
+#else
+ /* always redraw area that was explicitly marked to fade */
+ redraw_mask |= fade_mask;
+
+ BackToFront();
+#endif
+
+#else
+
#if 1
BlitBitmap(backbuffer, window, x, y, width, height, x, y);
redraw_mask = REDRAW_NONE;
+ // (^^^ WRONG; should be "redraw_mask &= ~fade_mask" if done this way)
#else
BackToFront();
+#endif
#endif
return;
#endif
#if 1
+
+#if 1
+ if (IN_GFX_FIELD_FULL(x, y))
+ redraw_mask |= REDRAW_FIELD;
+ else if (IN_GFX_DOOR_1(x, y))
+ redraw_mask |= REDRAW_DOOR_1;
+ else if (IN_GFX_DOOR_2(x, y))
+ redraw_mask |= REDRAW_DOOR_2;
+ else if (IN_GFX_DOOR_3(x, y))
+ redraw_mask |= REDRAW_DOOR_3;
+#else
/* (this only works for the current arrangement of playfield and panels) */
if (x < gfx.dx)
redraw_mask |= REDRAW_FIELD;
redraw_mask |= REDRAW_DOOR_1;
else
redraw_mask |= REDRAW_DOOR_2;
+#endif
+
#else
/* (this is just wrong (when drawing to one of the two door panel areas)) */
redraw_mask |= REDRAW_FIELD;
Bitmap *src_bitmap = g->bitmap;
int tilesize = MIN(MAX(1, tilesize_raw), TILESIZE);
int offset_calc_pos = log_2(tilesize);
+ int bitmap_width = src_bitmap->width;
+ int bitmap_height = src_bitmap->height;
int width_mult = offset_calc[offset_calc_pos].width_mult;
int width_div = offset_calc[offset_calc_pos].width_div;
int height_mult = offset_calc[offset_calc_pos].height_mult;
int height_div = offset_calc[offset_calc_pos].height_div;
- int startx = src_bitmap->width * width_mult / width_div;
- int starty = src_bitmap->height * height_mult / height_div;
+ int startx = bitmap_width * width_mult / width_div;
+ int starty = bitmap_height * height_mult / height_div;
+
+#if NEW_GAME_TILESIZE
+
+ int src_x = (g->src_x + (get_backside ? g->offset2_x : 0)) *
+ tilesize_raw / TILESIZE;
+ int src_y = (g->src_y + (get_backside ? g->offset2_y : 0)) *
+ tilesize_raw / TILESIZE;
+ int width = g->width * tilesize_raw / TILESIZE;
+ int height = g->height * tilesize_raw / TILESIZE;
+ int offset_x = g->offset_x * tilesize_raw / TILESIZE;
+ int offset_y = g->offset_y * tilesize_raw / TILESIZE;
+
+#else
+
#if NEW_TILESIZE
int src_x = (g->src_x + (get_backside ? g->offset2_x : 0)) *
tilesize / TILESIZE;
int offset_x = g->offset_x * tilesize / TILESIZE;
int offset_y = g->offset_y * tilesize / TILESIZE;
+#endif
+
+#if NEW_GAME_TILESIZE
+ if (game.tile_size != TILESIZE)
+ {
+ int bitmap_width_std =
+ bitmap_width * TILESIZE / (TILESIZE + game.tile_size);
+ int bitmap_height_std =
+ bitmap_height * TILESIZE / game.tile_size * 3 / 2;
+
+ if (tilesize_raw == game.tile_size)
+ {
+ startx = bitmap_width_std;
+ starty = 0;
+ }
+ else
+ {
+ bitmap_width = bitmap_width_std;
+
+ if (game.tile_size > TILESIZE * 3 / 2)
+ bitmap_height = bitmap_height_std;
+
+ startx = bitmap_width * width_mult / width_div;
+ starty = bitmap_height * height_mult / height_div;
+ }
+ }
+#endif
+
if (g->offset_y == 0) /* frames are ordered horizontally */
{
int max_width = g->anim_frames_per_line * width;
#if NEW_TILESIZE
width = crumbled_border_size * TILESIZE_VAR / TILESIZE;
height = crumbled_border_size * TILESIZE_VAR / TILESIZE;
- cx = (dx > 0 ? TILEX - crumbled_border_size : 0) * TILESIZE_VAR / TILESIZE;
- cy = (dy > 0 ? TILEY - crumbled_border_size : 0) * TILESIZE_VAR / TILESIZE;
+ cx = (dx > 0 ? TILESIZE_VAR - width : 0);
+ cy = (dy > 0 ? TILESIZE_VAR - height : 0);
BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
width, height, FX + sx * TILEX_VAR + cx, FY + sy * TILEY_VAR + cy);
int width, height, bx, by, cx, cy;
int sx = SCREENX(x), sy = SCREENY(y);
int crumbled_border_size = graphic_info[graphic].border_size;
+ int crumbled_border_size_var = crumbled_border_size * TILESIZE_VAR / TILESIZE;
+ int crumbled_border_pos_var = TILESIZE_VAR - crumbled_border_size_var;
int i;
getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
/* draw simple, sloppy, non-corner-accurate crumbled border */
#if 1
- width = (dir == 1 || dir == 2 ? crumbled_border_size : TILEX);
- height = (dir == 0 || dir == 3 ? crumbled_border_size : TILEY);
- cx = (dir == 2 ? TILEX - crumbled_border_size : 0);
- cy = (dir == 3 ? TILEY - crumbled_border_size : 0);
+ width = (dir == 1 || dir == 2 ? crumbled_border_size_var : TILESIZE_VAR);
+ height = (dir == 0 || dir == 3 ? crumbled_border_size_var : TILESIZE_VAR);
+ cx = (dir == 2 ? crumbled_border_pos_var : 0);
+ cy = (dir == 3 ? crumbled_border_pos_var : 0);
#else
if (dir == 1 || dir == 2) /* left or right crumbled border */
{
#if NEW_TILESIZE
BlitBitmap(src_bitmap, drawto_field,
- src_x + cx * TILESIZE_VAR / TILESIZE,
- src_y + cy * TILESIZE_VAR / TILESIZE,
- width * TILESIZE_VAR / TILESIZE,
- height * TILESIZE_VAR / TILESIZE,
- FX + sx * TILEX_VAR + cx * TILESIZE_VAR / TILESIZE,
- FY + sy * TILEY_VAR + cy * TILESIZE_VAR / TILESIZE);
+ src_x + cx,
+ src_y + cy,
+ width,
+ height,
+ FX + sx * TILEX_VAR + cx,
+ FY + sy * TILEY_VAR + cy);
#else
BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
width, height, FX + sx * TILEX + cx, FY + sy * TILEY + cy);
/* correct corners of crumbled border, if needed */
#if 1
- for (i = -1; i <= 1; i+=2)
+ for (i = -1; i <= 1; i += 2)
{
int xx = x + (dir == 0 || dir == 3 ? i : 0);
int yy = y + (dir == 1 || dir == 2 ? i : 0);
{
/* no crumbled corner, but continued crumbled border */
- int c1 = (dir == 2 || dir == 3 ? TILESIZE - crumbled_border_size : 0);
- int c2 = (i == 1 ? TILESIZE - crumbled_border_size : 0);
- int b1 = (i == 1 ? crumbled_border_size :
- TILESIZE - 2 * crumbled_border_size);
+ int c1 = (dir == 2 || dir == 3 ? crumbled_border_pos_var : 0);
+ int c2 = (i == 1 ? crumbled_border_pos_var : 0);
+ int b1 = (i == 1 ? crumbled_border_size_var :
+ TILESIZE_VAR - 2 * crumbled_border_size_var);
- width = crumbled_border_size;
- height = crumbled_border_size;
+ width = crumbled_border_size_var;
+ height = crumbled_border_size_var;
if (dir == 1 || dir == 2)
{
#if NEW_TILESIZE
BlitBitmap(src_bitmap, drawto_field,
- src_x + bx * TILESIZE_VAR / TILESIZE,
- src_y + by * TILESIZE_VAR / TILESIZE,
- width * TILESIZE_VAR / TILESIZE,
- height * TILESIZE_VAR / TILESIZE,
- FX + sx * TILEX_VAR + cx * TILESIZE_VAR / TILESIZE,
- FY + sy * TILEY_VAR + cy * TILESIZE_VAR / TILESIZE);
+ src_x + bx,
+ src_y + by,
+ width,
+ height,
+ FX + sx * TILEX_VAR + cx,
+ FY + sy * TILEY_VAR + cy);
#else
BlitBitmap(src_bitmap, drawto_field, src_x + bx, src_y + by,
width, height, FX + sx * TILEX + cx, FY + sy * TILEY + cy);
dst_x + xsize_size_left, dst_y + ysize_size_top);
#endif
-#if 1
+#if 0
redraw_mask = REDRAW_FIELD | REDRAW_FROM_BACKBUFFER;
// redraw_mask |= REDRAW_ALL | REDRAW_FROM_BACKBUFFER;
#else
+ /* CHECK AGAIN (previous code reactivated) */
redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER;
#endif
#if 1
if (game_status == GAME_MODE_PLAYING)
{
+#if 1
+#if 1
+ BlitScreenToBitmap(backbuffer);
+#else
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ BlitScreenToBitmap_EM(backbuffer);
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
+ BlitScreenToBitmap_SP(backbuffer);
+ else
+ BlitScreenToBitmap_RND(backbuffer);
+#endif
+#else
if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
BlitScreenToBitmap_EM(backbuffer);
else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
{
BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY);
}
+#endif
}
SetDrawtoField(DRAW_BACKBUFFER);
#if 1
// game_status = last_game_status; /* restore current game status */
+#if 1
+ /* !!! CHECK AGAIN (SEE BELOW) !!! */
+ game_status = last_game_status; /* restore current game status */
+#endif
+
if (action == ACTION_CLOSING)
{
if (game_status != GAME_MODE_MAIN)
// SetDrawBackgroundMask(last_draw_background_mask);
-#if 1
+#if 0
redraw_mask = REDRAW_FIELD;
// redraw_mask |= REDRAW_ALL;
#else
+ /* CHECK AGAIN (previous code reactivated) */
redraw_mask |= REDRAW_FIELD;
#endif
BackToFront();
+#if 0
/* (important: after "BackToFront()", but before "SetDrawtoField()") */
game_status = last_game_status; /* restore current game status */
+#endif
#if 1
if (action == ACTION_CLOSING &&
BlitBitmap(src_bitmap, drawto, src_x, src_y, tilesize, tilesize, dst_x,dst_y);
}
-void DrawLevel()
+void DrawLevel(int draw_background_mask)
{
int x,y;
+#if 1
+ SetMainBackgroundImage(IMG_BACKGROUND_PLAYING);
+ SetDrawBackgroundMask(draw_background_mask);
+#else
#if 1
SetMainBackgroundImage(IMG_BACKGROUND_PLAYING);
SetDrawBackgroundMask(REDRAW_FIELD);
#else
SetDrawBackgroundMask(REDRAW_NONE);
+#endif
#endif
ClearField();
int preview_height = preview.ysize * tile_size;
int real_preview_xsize = MIN(level_xsize, preview.xsize);
int real_preview_ysize = MIN(level_ysize, preview.ysize);
+ int real_preview_width = real_preview_xsize * tile_size;
+ int real_preview_height = real_preview_ysize * tile_size;
int dst_x = SX + ALIGNED_XPOS(preview.x, preview_width, preview.align);
int dst_y = SY + ALIGNED_YPOS(preview.y, preview_height, preview.valign);
int x, y;
+#if 1
+ if (!IN_GFX_FIELD_FULL(dst_x, dst_y + preview_height - 1))
+ return;
+#endif
+
+#if 0
+ dst_x += (preview_width - real_preview_width) / 2;
+ dst_y += (preview_height - real_preview_height) / 2;
+
+ DrawBackground(dst_x, dst_y, real_preview_width, real_preview_height);
+#else
DrawBackground(dst_x, dst_y, preview_width, preview_height);
- dst_x += (preview_width - real_preview_xsize * tile_size) / 2;
- dst_y += (preview_height - real_preview_ysize * tile_size) / 2;
+ dst_x += (preview_width - real_preview_width) / 2;
+ dst_y += (preview_height - real_preview_height) / 2;
+#endif
for (x = 0; x < real_preview_xsize; x++)
{
int font_nr = pos->font;
int i;
+ if (!IN_GFX_FIELD_FULL(pos->x, pos->y + getFontHeight(pos->font)))
+ return;
+
if (mode == MICROLABEL_LEVEL_AUTHOR_HEAD ||
mode == MICROLABEL_IMPORTED_FROM_HEAD ||
mode == MICROLABEL_IMPORTED_BY_HEAD)
label_text[max_len_label_text] = '\0';
#if 1
- DrawTextSAligned(pos->x, pos->y, label_text, font_nr, pos->align);
+ if (IN_GFX_FIELD_FULL(pos->x, pos->y + getFontHeight(pos->font)))
+ DrawTextSAligned(pos->x, pos->y, label_text, font_nr, pos->align);
#else
lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
lypos = SY + MICROLABEL1_YPOS;
break;
case KSYM_Return:
+#if defined(TARGET_SDL2)
+ case KSYM_Menu:
+#endif
result = 1;
break;
if (game_status == GAME_MODE_PLAYING)
{
+#if 1
+ BlitScreenToBitmap(backbuffer);
+#else
if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
BlitScreenToBitmap_EM(backbuffer);
else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
BlitScreenToBitmap_SP(backbuffer);
+#endif
}
/* disable deactivated drawing when quick-loading level tape recording */
CloseDoor(DOOR_CLOSE_1);
/* save old door content */
+#if 1
+ BlitBitmap(bitmap_db_door_1, bitmap_db_door_1,
+ 0 * DXSIZE, 0, DXSIZE, DYSIZE, 1 * DXSIZE, 0);
+#else
BlitBitmap(bitmap_db_door, bitmap_db_door,
DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
+#endif
}
SetDoorBackgroundImage(IMG_BACKGROUND_DOOR);
}
/* copy request gadgets to door backbuffer */
+#if 1
+ BlitBitmap(drawto, bitmap_db_door_1, DX, DY, DXSIZE, DYSIZE, 0, 0);
+#else
BlitBitmap(drawto, bitmap_db_door,
DX, DY, DXSIZE, DYSIZE,
DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+#endif
OpenDoor(DOOR_OPEN_1);
if (game_status == GAME_MODE_PLAYING)
{
+#if 1
+#if 1
+ BlitScreenToBitmap(backbuffer);
+#else
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ BlitScreenToBitmap_EM(backbuffer);
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
+ BlitScreenToBitmap_SP(backbuffer);
+ else
+ BlitScreenToBitmap_RND(backbuffer);
+#endif
+#else
if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
BlitScreenToBitmap_EM(backbuffer);
else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
BlitScreenToBitmap_SP(backbuffer);
+#endif
}
/* disable deactivated drawing when quick-loading level tape recording */
if (game_status == GAME_MODE_PLAYING)
{
+#if 1
+ BlitScreenToBitmap(backbuffer);
+#else
if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
BlitScreenToBitmap_EM(backbuffer);
else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
BlitScreenToBitmap_SP(backbuffer);
+#endif
}
/* disable deactivated drawing when quick-loading level tape recording */
break;
}
- if (req_state & REQ_PLAYER)
- result = 0;
- break;
+ if (req_state & REQ_PLAYER)
+ result = 0;
+ break;
+
+ case EVENT_KEYRELEASE:
+ ClearPlayerAction();
+ break;
+
+ default:
+ HandleOtherEvents(&event);
+ break;
+ }
+ }
+ else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
+ {
+ int joy = AnyJoystick();
+
+ if (joy & JOY_BUTTON_1)
+ result = 1;
+ else if (joy & JOY_BUTTON_2)
+ result = 0;
+ }
+
+#if 1
+
+ if (game_status == GAME_MODE_PLAYING && local_player->LevelSolved_GameEnd)
+ {
+ HandleGameActions();
+ }
+ else
+ {
+ DoAnimation();
+
+ if (!PendingEvent()) /* delay only if no pending events */
+ Delay(10);
+ }
+
+#if 1
+ game_status = GAME_MODE_PSEUDO_DOOR;
+#endif
+
+ BackToFront();
+
+#if 1
+ game_status = last_game_status; /* restore current game status */
+#endif
+
+#else
+
+ DoAnimation();
+
+#if 1
+ if (!PendingEvent()) /* delay only if no pending events */
+ Delay(10);
+#else
+ /* don't eat all CPU time */
+ Delay(10);
+#endif
+
+#endif
+ }
+
+ if (game_status != GAME_MODE_MAIN)
+ StopAnimation();
+
+ UnmapToolButtons();
+
+#if 1
+ if (global.use_envelope_request)
+ ShowEnvelopeRequest(text, ACTION_CLOSING);
+#endif
+
+#if 1
+ if (!(req_state & REQ_STAY_OPEN) && !global.use_envelope_request)
+#else
+ if (!(req_state & REQ_STAY_OPEN))
+#endif
+ {
+ CloseDoor(DOOR_CLOSE_1);
+
+ if (((old_door_state & DOOR_OPEN_1) && !(req_state & REQ_STAY_CLOSED)) ||
+ (req_state & REQ_REOPEN))
+ OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
+ }
+
+ RemapAllGadgets();
+
+ if (game_status == GAME_MODE_PLAYING)
+ {
+ SetPanelBackground();
+ SetDrawBackgroundMask(REDRAW_DOOR_1);
+ }
+ else
+ {
+ SetDrawBackgroundMask(REDRAW_FIELD);
+ }
+
+#if defined(NETWORK_AVALIABLE)
+ /* continue network game after request */
+ if (options.network &&
+ game_status == GAME_MODE_PLAYING &&
+ req_state & REQUEST_WAIT_FOR_INPUT)
+ SendToServer_ContinuePlaying();
+#endif
+
+ /* restore deactivated drawing when quick-loading level tape recording */
+ if (tape.playing && tape.deactivate_display)
+ TapeDeactivateDisplayOn();
+
+ return result;
+}
+
+#endif
+
+static int compareDoorPartOrderInfo(const void *object1, const void *object2)
+{
+ const struct DoorPartOrderInfo *dpo1 = (struct DoorPartOrderInfo *)object1;
+ const struct DoorPartOrderInfo *dpo2 = (struct DoorPartOrderInfo *)object2;
+ int compare_result;
+
+ if (dpo1->sort_priority != dpo2->sort_priority)
+ compare_result = dpo1->sort_priority - dpo2->sort_priority;
+ else
+ compare_result = dpo1->nr - dpo2->nr;
+
+ return compare_result;
+}
+
+void InitGraphicCompatibilityInfo_Doors()
+{
+ struct
+ {
+ int door_token;
+ int part_1, part_8;
+ struct DoorInfo *door;
+ }
+ doors[] =
+ {
+ { DOOR_1, IMG_DOOR_1_GFX_PART_1, IMG_DOOR_1_GFX_PART_8, &door_1 },
+ { DOOR_2, IMG_DOOR_2_GFX_PART_1, IMG_DOOR_2_GFX_PART_8, &door_2 },
+
+ { -1, -1, -1, NULL }
+ };
+ struct Rect door_rect_list[] =
+ {
+ { DX, DY, DXSIZE, DYSIZE },
+ { VX, VY, VXSIZE, VYSIZE }
+ };
+ int i, j;
+
+ for (i = 0; doors[i].door_token != -1; i++)
+ {
+ int door_token = doors[i].door_token;
+ int door_index = DOOR_INDEX_FROM_TOKEN(door_token);
+ int part_1 = doors[i].part_1;
+ int part_8 = doors[i].part_8;
+ int part_2 = part_1 + 1;
+ int part_3 = part_1 + 2;
+ struct DoorInfo *door = doors[i].door;
+ struct Rect *door_rect = &door_rect_list[door_index];
+ boolean door_gfx_redefined = FALSE;
+
+ /* check if any door part graphic definitions have been redefined */
+
+ for (j = 0; door_part_controls[j].door_token != -1; j++)
+ {
+ struct DoorPartControlInfo *dpc = &door_part_controls[j];
+ struct FileInfo *fi = getImageListEntryFromImageID(dpc->graphic);
+
+ if (dpc->door_token == door_token && fi->redefined)
+ door_gfx_redefined = TRUE;
+ }
+
+ /* check for old-style door graphic/animation modifications */
+
+ if (!door_gfx_redefined)
+ {
+ if (door->anim_mode & ANIM_STATIC_PANEL)
+ {
+ door->panel.step_xoffset = 0;
+ door->panel.step_yoffset = 0;
+ }
+
+ if (door->anim_mode & (ANIM_HORIZONTAL | ANIM_VERTICAL))
+ {
+ struct GraphicInfo *g_part_1 = &graphic_info[part_1];
+ 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 */
+
+ for (j = 0; door_part_controls[j].door_token != -1; j++)
+ {
+ struct DoorPartControlInfo *dpc = &door_part_controls[j];
+ struct GraphicInfo *g = &graphic_info[dpc->graphic];
+
+ if (dpc->graphic >= part_3 &&
+ dpc->graphic <= part_8)
+ g->bitmap = NULL;
+ }
+
+ /* set graphics and screen positions of the default wings */
+
+ g_part_1->width = door_rect->width;
+ g_part_1->height = door_rect->height;
+ g_part_2->width = door_rect->width;
+ g_part_2->height = door_rect->height;
+ g_part_2->src_x = door_rect->width;
+ g_part_2->src_y = g_part_1->src_y;
+
+ door->part_2.x = door->part_1.x;
+ door->part_2.y = door->part_1.y;
+
+ if (door->width != -1)
+ {
+ g_part_1->width = door->width;
+ g_part_2->width = door->width;
+
+ // special treatment for graphics and screen position of right wing
+ g_part_2->src_x += door_rect->width - door->width;
+ door->part_2.x += door_rect->width - door->width;
+ }
+
+ if (door->height != -1)
+ {
+ g_part_1->height = door->height;
+ g_part_2->height = door->height;
+
+ // special treatment for graphics and screen position of bottom wing
+ g_part_2->src_y += door_rect->height - door->height;
+ door->part_2.y += door_rect->height - door->height;
+ }
+
+ /* 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 */
+
+ 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 */
+
+ if (door->anim_mode & ANIM_HORIZONTAL)
+ {
+ door->part_1.step_xoffset = door->step_offset;
+ door->part_1.step_yoffset = 0;
+ door->part_2.step_xoffset = door->step_offset * -1;
+ door->part_2.step_yoffset = 0;
+
+ num_door_steps = g_part_1->width / door->step_offset;
+ }
+ else // ANIM_VERTICAL
+ {
+ door->part_1.step_xoffset = 0;
+ door->part_1.step_yoffset = door->step_offset;
+ door->part_2.step_xoffset = 0;
+ door->part_2.step_yoffset = door->step_offset * -1;
+
+ num_door_steps = g_part_1->height / door->step_offset;
+ }
+
+ /* set animation draw offset for the default panels */
+
+ if (door->step_offset > 1)
+ {
+ num_panel_steps = 2 * door_rect->height / door->step_offset;
+ door->panel.start_step = num_panel_steps - num_door_steps;
+ }
+ else
+ {
+ num_panel_steps = door_rect->height / door->step_offset;
+ door->panel.start_step = num_panel_steps - num_door_steps / 2;
+ door->panel.step_delay *= 2;
+ }
+ }
+ }
+ }
+}
+
+void InitDoors()
+{
+ int i;
+
+ for (i = 0; door_part_controls[i].door_token != -1; 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 */
+ if (dpc->pos->start_step_opening == 0 &&
+ dpc->pos->start_step_closing == 0)
+ {
+ // dpc->pos->start_step_opening = dpc->pos->start_step;
+ dpc->pos->start_step_closing = dpc->pos->start_step;
+ }
+
+ /* fill structure for door part draw order (sorted below) */
+ dpo->nr = i;
+ dpo->sort_priority = dpc->pos->sort_priority;
+
+#if 0
+ struct DoorPartPosInfo *pos = dpc->pos;
+
+ printf(":0: step_xoffset == %d, step_yoffset == %d\n",
+ pos->step_xoffset, pos->step_yoffset);
+#endif
+ }
+
+ /* sort door part controls according to sort_priority and graphic number */
+ qsort(door_part_order, MAX_DOOR_PARTS,
+ sizeof(struct DoorPartOrderInfo), compareDoorPartOrderInfo);
+}
+
+unsigned int OpenDoor(unsigned int door_state)
+{
+ if (door_state & DOOR_COPY_BACK)
+ {
+#if 1
+ if (door_state & DOOR_OPEN_1)
+ BlitBitmap(bitmap_db_door_1, bitmap_db_door_1,
+ 1 * DXSIZE, 0, DXSIZE, DYSIZE, 0 * DXSIZE, 0);
+
+ if (door_state & DOOR_OPEN_2)
+ BlitBitmap(bitmap_db_door_2, bitmap_db_door_2,
+ 1 * VXSIZE, 0, VXSIZE, VYSIZE, 0 * VXSIZE, 0);
+#else
+ if (door_state & DOOR_OPEN_1)
+ BlitBitmap(bitmap_db_door, bitmap_db_door,
+ DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+
+ if (door_state & DOOR_OPEN_2)
+ BlitBitmap(bitmap_db_door, bitmap_db_door,
+ DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY2, VXSIZE, VYSIZE,
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
+#endif
+
+ door_state &= ~DOOR_COPY_BACK;
+ }
+
+ return MoveDoor(door_state);
+}
+
+unsigned int CloseDoor(unsigned int door_state)
+{
+ unsigned int old_door_state = GetDoorState();
+
+ if (!(door_state & DOOR_NO_COPY_BACK))
+ {
+#if 1
+ if (old_door_state & DOOR_OPEN_1)
+ BlitBitmap(backbuffer, bitmap_db_door_1,
+ DX, DY, DXSIZE, DYSIZE, 0, 0);
+
+ if (old_door_state & DOOR_OPEN_2)
+ BlitBitmap(backbuffer, bitmap_db_door_2,
+ VX, VY, VXSIZE, VYSIZE, 0, 0);
+#else
+ if (old_door_state & DOOR_OPEN_1)
+ BlitBitmap(backbuffer, bitmap_db_door,
+ DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+
+ if (old_door_state & DOOR_OPEN_2)
+ BlitBitmap(backbuffer, bitmap_db_door,
+ VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
+#endif
+
+ door_state &= ~DOOR_NO_COPY_BACK;
+ }
+
+ return MoveDoor(door_state);
+}
+
+unsigned int GetDoorState()
+{
+ return MoveDoor(DOOR_GET_STATE);
+}
+
+unsigned int SetDoorState(unsigned int door_state)
+{
+ return MoveDoor(door_state | DOOR_SET_STATE);
+}
+
+#if 1
+
+// ========== TEST 1 ===========================================================
+
+int euclid(int a, int b)
+{
+ return (b ? euclid(b, a % b) : a);
+}
+
+unsigned int MoveDoor(unsigned int door_state)
+{
+#if 0
+ struct XY panel_pos_list[] =
+ {
+ { DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 },
+ { DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 },
+ };
+#endif
+ struct Rect door_rect_list[] =
+ {
+ { DX, DY, DXSIZE, DYSIZE },
+ { VX, VY, VXSIZE, VYSIZE }
+ };
+ static int door1 = DOOR_OPEN_1;
+ static int door2 = DOOR_CLOSE_2;
+ unsigned int door_delay = 0;
+ unsigned int door_delay_value;
+ int i;
+
+#if 1
+ if (door_1.width < 0 || door_1.width > DXSIZE)
+ door_1.width = DXSIZE;
+ if (door_1.height < 0 || door_1.height > DYSIZE)
+ door_1.height = DYSIZE;
+ if (door_2.width < 0 || door_2.width > VXSIZE)
+ door_2.width = VXSIZE;
+ if (door_2.height < 0 || door_2.height > VYSIZE)
+ door_2.height = VYSIZE;
+#endif
+
+ if (door_state == DOOR_GET_STATE)
+ return (door1 | door2);
+
+ if (door_state & DOOR_SET_STATE)
+ {
+ if (door_state & DOOR_ACTION_1)
+ door1 = door_state & DOOR_ACTION_1;
+ if (door_state & DOOR_ACTION_2)
+ door2 = door_state & DOOR_ACTION_2;
+
+ return (door1 | door2);
+ }
+
+ if (!(door_state & DOOR_FORCE_REDRAW))
+ {
+ if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
+ door_state &= ~DOOR_OPEN_1;
+ else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
+ door_state &= ~DOOR_CLOSE_1;
+ if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
+ door_state &= ~DOOR_OPEN_2;
+ else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
+ door_state &= ~DOOR_CLOSE_2;
+ }
+
+#if 0
+ door_delay_value = (door_state & DOOR_ACTION_1 ? door_1.step_delay :
+ door_2.step_delay);
+
+ if (setup.quick_doors)
+ {
+ stepsize = 20; /* must be chosen to always draw last frame */
+ door_delay_value = 0;
+ }
+#endif
+
+ if (global.autoplay_leveldir)
+ {
+ door_state |= DOOR_NO_DELAY;
+ door_state &= ~DOOR_CLOSE_ALL;
+ }
+
+#if 1
+ if (game_status == GAME_MODE_EDITOR)
+ door_state |= DOOR_NO_DELAY;
+#endif
+
+ if (door_state & DOOR_ACTION)
+ {
+ boolean door_panel_drawn[NUM_DOORS];
+ boolean panel_has_doors[NUM_DOORS];
+ boolean door_part_skip[MAX_DOOR_PARTS];
+ boolean door_part_done[MAX_DOOR_PARTS];
+ boolean door_part_done_all;
+ int num_steps[MAX_DOOR_PARTS];
+ int max_move_delay = 0; // delay for complete animations of all doors
+ int max_step_delay = 0; // delay (ms) between two animation frames
+ int num_move_steps = 0; // number of animation steps for all doors
+ int current_move_delay = 0;
+ int k;
+
+ for (i = 0; i < NUM_DOORS; i++)
+ panel_has_doors[i] = FALSE;
- case EVENT_KEYRELEASE:
- ClearPlayerAction();
- break;
+ for (i = 0; i < MAX_DOOR_PARTS; i++)
+ {
+ struct DoorPartControlInfo *dpc = &door_part_controls[i];
+ struct GraphicInfo *g = &graphic_info[dpc->graphic];
+ int door_token = dpc->door_token;
- default:
- HandleOtherEvents(&event);
- break;
- }
+ door_part_done[i] = FALSE;
+ door_part_skip[i] = (!(door_state & door_token) ||
+ !g->bitmap);
}
- else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
+
+#if 0
+ for (i = 0; i < MAX_DOOR_PARTS; i++)
{
- int joy = AnyJoystick();
+ struct DoorPartControlInfo *dpc = &door_part_controls[i];
+ struct DoorPartPosInfo *pos = dpc->pos;
+ int start_step = pos->start_step;
- if (joy & JOY_BUTTON_1)
- result = 1;
- else if (joy & JOY_BUTTON_2)
- result = 0;
+ printf("::: ---> %d: start_step == %d [%d]\n",
+ i, start_step, door_part_done[i]);
}
+#endif
-#if 1
-
- if (game_status == GAME_MODE_PLAYING && local_player->LevelSolved_GameEnd)
+ for (i = 0; i < MAX_DOOR_PARTS; i++)
{
- HandleGameActions();
+ int nr = door_part_order[i].nr;
+ struct DoorPartControlInfo *dpc = &door_part_controls[nr];
+ struct DoorPartPosInfo *pos = dpc->pos;
+ struct GraphicInfo *g = &graphic_info[dpc->graphic];
+ int door_token = dpc->door_token;
+ int door_index = DOOR_INDEX_FROM_TOKEN(door_token);
+ boolean is_panel = DOOR_PART_IS_PANEL(nr);
+ int step_xoffset = ABS(pos->step_xoffset);
+ int step_yoffset = ABS(pos->step_yoffset);
+ int step_delay = pos->step_delay;
+ int current_door_state = door_state & door_token;
+ boolean door_opening = ((current_door_state & DOOR_OPEN) != 0);
+ boolean door_closing = ((current_door_state & DOOR_CLOSE) != 0);
+ boolean part_opening = (is_panel ? door_closing : door_opening);
+ int start_step = (part_opening ? pos->start_step_opening :
+ pos->start_step_closing);
+ float move_xsize = (step_xoffset ? g->width : 0);
+ float move_ysize = (step_yoffset ? g->height : 0);
+ int move_xsteps = (step_xoffset ? ceil(move_xsize / step_xoffset) : 0);
+ int move_ysteps = (step_yoffset ? ceil(move_ysize / step_yoffset) : 0);
+ int move_steps = (move_xsteps && move_ysteps ?
+ MIN(move_xsteps, move_ysteps) :
+ move_xsteps ? move_xsteps : move_ysteps) - start_step;
+ int move_delay = move_steps * step_delay;
+
+ if (door_part_skip[nr])
+ continue;
+
+ if (!is_panel)
+ panel_has_doors[door_index] = TRUE;
+
+ max_move_delay = MAX(max_move_delay, move_delay);
+ max_step_delay = (max_step_delay == 0 ? step_delay :
+ euclid(max_step_delay, step_delay));
+ num_steps[nr] = move_steps;
+
+#if 0
+#if 0
+ printf("::: %d: move_delay == %d, start_step == %d [%d]\n",
+ i, move_delay, start_step, door_part_order[i].nr);
+#else
+ if (DOOR_PART_IS_PANEL(i))
+ printf("::: %d: move_delay == %d, start_step == %d\n",
+ i, move_delay, start_step);
+#endif
+#endif
}
- else
+
+ num_move_steps = max_move_delay / max_step_delay;
+
+ door_delay_value = max_step_delay;
+
+#if 0
+ door_delay_value *= 10;
+#endif
+
+#if 0
+ printf("::: num_move_steps == %d, max_move_delay == %d, max_step_delay == %d\n", num_move_steps, max_move_delay, max_step_delay);
+#endif
+
+ for (k = 0; k < num_move_steps; k++)
{
- DoAnimation();
+ door_part_done_all = TRUE;
- if (!PendingEvent()) /* delay only if no pending events */
- Delay(10);
- }
+ for (i = 0; i < NUM_DOORS; i++)
+ door_panel_drawn[i] = FALSE;
-#if 1
- game_status = GAME_MODE_PSEUDO_DOOR;
+ for (i = 0; i < MAX_DOOR_PARTS; i++)
+ {
+ int nr = door_part_order[i].nr;
+ struct DoorPartControlInfo *dpc = &door_part_controls[nr];
+ struct DoorPartPosInfo *pos = dpc->pos;
+ struct GraphicInfo *g = &graphic_info[dpc->graphic];
+ int door_token = dpc->door_token;
+ int door_index = DOOR_INDEX_FROM_TOKEN(door_token);
+ boolean is_panel = DOOR_PART_IS_PANEL(nr);
+#if 0
+ struct XY *panel_pos = &panel_pos_list[door_index];
+#endif
+ struct Rect *door_rect = &door_rect_list[door_index];
+ Bitmap *bitmap_db_door = (door_token == DOOR_1 ? bitmap_db_door_1 :
+ bitmap_db_door_2);
+ Bitmap *bitmap = (is_panel ? bitmap_db_door : g->bitmap);
+ int current_door_state = door_state & door_token;
+ boolean door_opening = ((current_door_state & DOOR_OPEN) != 0);
+ boolean door_closing = !door_opening;
+ boolean part_opening = (is_panel ? door_closing : door_opening);
+ boolean part_closing = !part_opening;
+ int start_step = (part_opening ? pos->start_step_opening :
+ pos->start_step_closing);
+ int step_delay = pos->step_delay;
+ int step_factor = step_delay / max_step_delay;
+ int k1 = (step_factor ? k / step_factor + 1 : k);
+ int k2 = (part_opening ? k1 + start_step : num_steps[nr] - k1);
+ int kk = (k2 < 0 ? 0 : k2);
+ int src_x, src_y, src_xx, src_yy;
+ int dst_x, dst_y, dst_xx, dst_yy;
+ int width, height;
+
+#if 0
+ if (k == 0 && is_panel && door_token == DOOR_2)
+ printf("::: %d, %d\n", g->width, g->height);
#endif
- BackToFront();
+#if 0
+ if (DOOR_PART_IS_PANEL(nr))
+ {
+ int start_step = pos->start_step;
-#if 1
- game_status = last_game_status; /* restore current game status */
+ k2 = (door_closing ? k1 : num_steps[nr] - k1);// - start_step;
+ kk = (k2 < 0 ? 0 : k2);
+ }
#endif
-#else
+#if 0
+ // !!! TEST !!!
+ if (nr != 16 && nr != 0)
+ continue;
+#endif
- DoAnimation();
+#if 0
+ // !!! TEST !!!
+ if (!is_panel)
+ continue;
+#endif
#if 1
- if (!PendingEvent()) /* delay only if no pending events */
- Delay(10);
-#else
- /* don't eat all CPU time */
- Delay(10);
+ if (door_part_skip[nr])
+ continue;
#endif
-#endif
- }
+ if (!(door_state & door_token))
+ continue;
- if (game_status != GAME_MODE_MAIN)
- StopAnimation();
+ if (!g->bitmap)
+ continue;
- UnmapToolButtons();
+#if 0
+ if (current_move_delay % step_delay)
+ continue;
+#endif
+ // draw door panel
+
+ if (!door_panel_drawn[door_index])
+ {
#if 1
- if (global.use_envelope_request)
- ShowEnvelopeRequest(text, ACTION_CLOSING);
+ ClearRectangle(drawto, door_rect->x, door_rect->y,
+ door_rect->width, door_rect->height);
+#else
+ BlitBitmap(bitmap_db_door, drawto, panel_pos->x, panel_pos->y,
+ door_rect->width, door_rect->height,
+ door_rect->x, door_rect->y);
#endif
+ door_panel_drawn[door_index] = TRUE;
+ }
+
+ // draw opening or closing door parts
+
+ if (pos->step_xoffset < 0) // door part on right side
+ {
+ src_xx = 0;
+ dst_xx = pos->x + ABS(kk * pos->step_xoffset);
+ width = g->width;
+
+ if (dst_xx + width > door_rect->width)
+ width = door_rect->width - dst_xx;
+ }
+ else // door part on left side
+ {
+ src_xx = 0;
+ dst_xx = pos->x - kk * pos->step_xoffset;
+
+ if (dst_xx < 0)
+ {
+ src_xx = ABS(dst_xx);
+ dst_xx = 0;
+ }
+
+ width = g->width - src_xx;
+
+ // printf("::: k == %d [%d] \n", k, start_step);
+ }
+
+ if (pos->step_yoffset < 0) // door part on bottom side
+ {
+ src_yy = 0;
+ dst_yy = pos->y + ABS(kk * pos->step_yoffset);
+ height = g->height;
+
+ if (dst_yy + height > door_rect->height)
+ height = door_rect->height - dst_yy;
+ }
+ else // door part on top side
+ {
+ src_yy = 0;
+ dst_yy = pos->y - kk * pos->step_yoffset;
+
+ if (dst_yy < 0)
+ {
+ src_yy = ABS(dst_yy);
+ dst_yy = 0;
+ }
+
+ height = g->height - src_yy;
+ }
+
+ if (is_panel)
+ {
#if 1
- if (!(req_state & REQ_STAY_OPEN) && !global.use_envelope_request)
+ src_x = src_xx;
+ src_y = src_yy;
#else
- if (!(req_state & REQ_STAY_OPEN))
+ src_x = panel_pos->x + src_xx;
+ src_y = panel_pos->y + src_yy;
#endif
- {
- CloseDoor(DOOR_CLOSE_1);
+ }
+ else
+ {
+ src_x = g->src_x + src_xx;
+ src_y = g->src_y + src_yy;
+ }
- if (((old_door_state & DOOR_OPEN_1) && !(req_state & REQ_STAY_CLOSED)) ||
- (req_state & REQ_REOPEN))
- OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
- }
+ dst_x = door_rect->x + dst_xx;
+ dst_y = door_rect->y + dst_yy;
- RemapAllGadgets();
+#if 0
+ if (DOOR_PART_IS_PANEL(nr))
+ {
+ printf("::: width == %d, height == %d [%d, %d] [%d, %d]\n",
+ width, height, g->width, g->height, src_x, src_y);
+ }
+#endif
- if (game_status == GAME_MODE_PLAYING)
- {
- SetPanelBackground();
- SetDrawBackgroundMask(REDRAW_DOOR_1);
- }
- else
- {
- SetDrawBackgroundMask(REDRAW_FIELD);
- }
+ if (width >= 0 && width <= g->width &&
+ height >= 0 && height <= g->height)
+ {
+ if (is_panel || !pos->draw_masked)
+ BlitBitmap(bitmap, drawto, src_x, src_y, width, height,
+ dst_x, dst_y);
+ else
+ BlitBitmapMasked(bitmap, drawto, src_x, src_y, width, height,
+ dst_x, dst_y);
+ }
-#if defined(NETWORK_AVALIABLE)
- /* continue network game after request */
- if (options.network &&
- game_status == GAME_MODE_PLAYING &&
- req_state & REQUEST_WAIT_FOR_INPUT)
- SendToServer_ContinuePlaying();
+#if 0
+ if (DOOR_PART_IS_PANEL(nr))
+ {
+ bitmap = bitmap_db_door;
+ src_x = panel_pos->x + src_xx;
+ src_y = panel_pos->y + src_yy;
+
+ printf("::: width == %d, height == %d [%d, %d] [%d, %d]\n",
+ width, height, g->width, g->height, src_x, src_y);
+
+ if (width >= 0 && width <= g->width &&
+ height >= 0 && height <= g->height)
+ BlitBitmap(bitmap, drawto, src_x, src_y,
+ width, height,
+ dst_x, dst_y);
+ }
#endif
- /* restore deactivated drawing when quick-loading level tape recording */
- if (tape.playing && tape.deactivate_display)
- TapeDeactivateDisplayOn();
-
- return result;
-}
+ redraw_mask |= REDRAW_DOOR_FROM_TOKEN(door_token);
+#if 1
+ if ((part_opening && (width < 0 || height < 0)) ||
+ (part_closing && (width >= g->width && height >= g->height)))
+ door_part_done[nr] = TRUE;
+#else
+ if ((door_opening && (width < 0 || height < 0)) ||
+ (door_closing && (width >= g->width && height >= g->height)))
+ door_part_done[nr] = TRUE;
#endif
-unsigned int OpenDoor(unsigned int door_state)
-{
- if (door_state & DOOR_COPY_BACK)
- {
- if (door_state & DOOR_OPEN_1)
- BlitBitmap(bitmap_db_door, bitmap_db_door,
- DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+#if 1
+ // continue door part animations, but not panel after door has closed
+ if (!door_part_done[nr] &&
+ !(is_panel && door_closing && panel_has_doors[door_index]))
+ door_part_done_all = FALSE;
+#else
+ // continue door part animations, but not panel after door has closed
+ if (!door_part_done[nr] && !(is_panel && door_closing))
+ door_part_done_all = FALSE;
+#endif
- if (door_state & DOOR_OPEN_2)
- BlitBitmap(bitmap_db_door, bitmap_db_door,
- DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY2, VXSIZE, VYSIZE,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
+#if 0
+ if (!door_part_done[nr])
+ printf("::: k == %d, nr == %d\n", k, nr);
+#endif
+ }
- door_state &= ~DOOR_COPY_BACK;
- }
+ if (!(door_state & DOOR_NO_DELAY))
+ {
+ BackToFront();
- return MoveDoor(door_state);
-}
+ if (game_status == GAME_MODE_MAIN)
+ DoAnimation();
-unsigned int CloseDoor(unsigned int door_state)
-{
- unsigned int old_door_state = GetDoorState();
+ WaitUntilDelayReached(&door_delay, door_delay_value);
- if (!(door_state & DOOR_NO_COPY_BACK))
- {
- if (old_door_state & DOOR_OPEN_1)
- BlitBitmap(backbuffer, bitmap_db_door,
- DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+ current_move_delay += max_step_delay;
+ }
- if (old_door_state & DOOR_OPEN_2)
- BlitBitmap(backbuffer, bitmap_db_door,
- VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
+#if 0
+ door_part_done_all = TRUE;
- door_state &= ~DOOR_NO_COPY_BACK;
+ for (i = 0; i < MAX_DOOR_PARTS; i++)
+ if (!door_part_done[i] &&
+ !(DOOR_PART_IS_PANEL(i) && door_closing))
+ door_part_done_all = FALSE;
+#endif
+#if 1
+ if (door_part_done_all)
+ break;
+#endif
+ }
}
- return MoveDoor(door_state);
-}
+ if (door_state & DOOR_ACTION_1)
+ door1 = door_state & DOOR_ACTION_1;
+ if (door_state & DOOR_ACTION_2)
+ door2 = door_state & DOOR_ACTION_2;
-unsigned int GetDoorState()
-{
- return MoveDoor(DOOR_GET_STATE);
-}
+#if 0
+ printf("::: DOORS DONE %08x\n", door_state);
+ Delay(3000);
+ printf("::: GO!\n");
+#endif
-unsigned int SetDoorState(unsigned int door_state)
-{
- return MoveDoor(door_state | DOOR_SET_STATE);
+ return (door1 | door2);
}
+#else
+
+// ========== OLD ==============================================================
+
unsigned int MoveDoor(unsigned int door_state)
{
static int door1 = DOOR_OPEN_1;
GC gc_right = bm_right->stored_clip_gc;
#endif
+ int classic_dxsize = 100;
+ int classic_dysize = 280;
+ boolean classic_door_1_size = (DXSIZE == classic_dxsize &&
+ DYSIZE == classic_dysize);
+
if (door_1.anim_mode & ANIM_STATIC_PANEL)
{
BlitBitmap(bitmap_db_door, drawto,
DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + p / 2,
DXSIZE, DYSIZE - p / 2, DX, DY);
+#if 1
+ // printf("::: p == %d\n", p);
ClearRectangle(drawto, DX, DY + DYSIZE - p / 2, DXSIZE, p / 2);
+#endif
}
if (door_1.anim_mode & ANIM_HORIZONTAL && x <= DXSIZE)
dst2_x, dst2_y);
#endif
}
- else if (x <= DXSIZE) /* ANIM_DEFAULT */
+ else if (classic_door_1_size && x <= DXSIZE) /* ANIM_DEFAULT */
{
int j = (door_1.anim_mode == ANIM_DEFAULT ? (DXSIZE - i) / 3 : 0);
BlitBitmapMasked(bm_right, drawto,
src1_x, src1_y + ypos4, width, height2 - j,
dst1_x, dst1_y + ypos4 + j);
+
#else
int src1_x = DXSIZE, src1_y = DOOR_GFX_PAGEY1;
int src2_x = DXSIZE - i, src2_y = DOOR_GFX_PAGEY1;
GC gc_right = bm_right->stored_clip_gc;
#endif
+ int classic_vxsize = 100;
+ int classic_vysize = 100;
+ boolean classic_door_2_size = (VXSIZE == classic_vxsize &&
+ VYSIZE == classic_vysize);
+
if (door_2.anim_mode & ANIM_STATIC_PANEL)
{
BlitBitmap(bitmap_db_door, drawto,
dst2_x, dst2_y);
#endif
}
- else if (x <= VXSIZE) /* ANIM_DEFAULT */
+ else if (classic_door_2_size && x <= VXSIZE) /* ANIM_DEFAULT */
{
int j = (door_2.anim_mode == ANIM_DEFAULT ? (VXSIZE - i) / 3 : 0);
return (door1 | door2);
}
+#endif
+
void DrawSpecialEditorDoor()
{
#if 1
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_INFO_TEXT, toolbutton_info[i].infotext,
- GDI_X, dx + pos->x,
- GDI_Y, dy + pos->y,
+ GDI_X, dx + GDI_ACTIVE_POS(pos->x),
+ GDI_Y, dy + GDI_ACTIVE_POS(pos->y),
GDI_WIDTH, gfx->width,
GDI_HEIGHT, gfx->height,
GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_INFO_TEXT, toolbutton_info[i].infotext,
- GDI_X, DX + toolbutton_info[i].x,
- GDI_Y, DY + toolbutton_info[i].y,
+ GDI_X, DX + GDI_ACTIVE_POS(toolbutton_info[i].x),
+ GDI_Y, DY + GDI_ACTIVE_POS(toolbutton_info[i].y),
GDI_WIDTH, toolbutton_info[i].width,
GDI_HEIGHT, toolbutton_info[i].height,
GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
int *door_2_x = (game_status == GAME_MODE_EDITOR ? &EX : &VX);
int *door_2_y = (game_status == GAME_MODE_EDITOR ? &EY : &VY);
#endif
+#if 1
+ int gfx_game_mode = game_status;
+#else
int gfx_game_mode = (game_status == GAME_MODE_PLAYING ||
game_status == GAME_MODE_EDITOR ? game_status :
GAME_MODE_MAIN);
+#endif
int gfx_game_mode2 = (game_status == GAME_MODE_EDITOR ? GAME_MODE_DEFAULT :
game_status);
struct RectWithBorder *vp_playfield = &viewport.playfield[gfx_game_mode];
int new_exsize = vp_door_3->width;
int new_eysize = vp_door_3->height;
#if NEW_TILESIZE
+
+#if NEW_GAME_TILESIZE
+ int new_tilesize_var =
+ (setup.small_game_graphics ? MINI_TILESIZE : game.tile_size);
+#else
int new_tilesize_var = TILESIZE / (setup.small_game_graphics ? 2 : 1);
+#endif
+
int tilesize = (gfx_game_mode == GAME_MODE_PLAYING ? new_tilesize_var :
gfx_game_mode == GAME_MODE_EDITOR ? MINI_TILESIZE : TILESIZE);
int new_scr_fieldx = new_sxsize / tilesize;
boolean init_gfx_buffers = FALSE;
boolean init_video_buffer = FALSE;
boolean init_gadgets_and_toons = FALSE;
+ boolean init_em_graphics = FALSE;
#if 0
/* !!! TEST ONLY !!! */
#endif
)
{
+#if 1
+ if (new_tilesize_var != TILESIZE_VAR)
+ {
+ // printf("::: new_tilesize_var != TILESIZE_VAR\n");
+
+ // changing tile size invalidates scroll values of engine snapshots
+ FreeEngineSnapshot();
+
+ // changing tile size requires update of graphic mapping for EM engine
+ init_em_graphics = TRUE;
+ }
+#endif
+
SX = new_sx;
SY = new_sy;
DX = new_dx;
InitGfxBuffers();
#endif
+#if 0
if (gfx_game_mode == GAME_MODE_MAIN)
+#endif
{
#if 1
init_gadgets_and_toons = TRUE;
InitToons();
}
+ if (init_em_graphics)
+ {
+ InitGraphicInfo_EM();
+ }
+
#if 0
printf("::: %d, %d / %d, %d [%d]\n", VX, VY, EX, EY, game_status);
#endif