X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=968ddc7a226868097e523f327a5ba737d5d18e0b;hb=b7282fd678d6f5c7ebf6a12062eb391129a800a7;hp=603ebdaa9a949e8d6945679265e363bc2419389b;hpb=92a3daab2223b297cdb51fa9763c6acad423b2de;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index 603ebdaa..968ddc7a 100644 --- a/src/tools.c +++ b/src/tools.c @@ -11,6 +11,8 @@ * tools.c * ***********************************************************/ +#include + #include "libgame/libgame.h" #include "tools.h" @@ -37,6 +39,133 @@ #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 *); @@ -167,6 +296,68 @@ void SetDrawtoField(int mode) } } +#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 && @@ -233,6 +424,8 @@ void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height) 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; @@ -304,10 +497,12 @@ void DrawMaskedBorder(int redraw_mask) } } -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); @@ -358,6 +553,28 @@ void BlitScreenToBitmap(Bitmap *target_bitmap) 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) @@ -377,6 +594,16 @@ void BlitScreenToBitmap(Bitmap *target_bitmap) } } +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; @@ -486,15 +713,37 @@ void BackToFront() 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 || @@ -506,7 +755,7 @@ void BackToFront() else { #if 1 - BlitScreenToBitmap(window); + BlitScreenToBitmap_RND(window); #else int fx = FX, fy = FY; @@ -888,11 +1137,28 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type) 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; @@ -1088,6 +1354,17 @@ void DrawBackground(int x, int y, int width, int height) #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; @@ -1095,6 +1372,8 @@ void DrawBackground(int x, int y, int width, int height) 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; @@ -1241,12 +1520,28 @@ void getSizedGraphicSourceExt(int graphic, int frame, int tilesize_raw, 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; @@ -1261,6 +1556,34 @@ void getSizedGraphicSourceExt(int graphic, int frame, int tilesize_raw, 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; @@ -2830,10 +3153,11 @@ void AnimateEnvelopeRequest(int anim_mode, int action) 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 @@ -3090,6 +3414,18 @@ void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) #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) @@ -3098,6 +3434,7 @@ void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) { BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY); } +#endif } SetDrawtoField(DRAW_BACKBUFFER); @@ -3175,6 +3512,11 @@ void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) #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) @@ -3188,10 +3530,11 @@ void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) // 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 @@ -3201,8 +3544,10 @@ void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) 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 && @@ -3234,15 +3579,20 @@ void DrawPreviewElement(int dst_x, int dst_y, int element, int tilesize) 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(); @@ -3275,14 +3625,28 @@ static void DrawPreviewLevelPlayfieldExt(int from_x, int from_y) 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++) { @@ -3334,6 +3698,9 @@ static void DrawPreviewLevelLabelExt(int mode) 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) @@ -3473,7 +3840,8 @@ static void DrawPreviewLevelExt(boolean restart) 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; @@ -4275,6 +4643,9 @@ static int RequestHandleEvents(unsigned int req_state) break; case KSYM_Return: +#if defined(TARGET_SDL2) + case KSYM_Menu: +#endif result = 1; break; @@ -4372,10 +4743,14 @@ static boolean RequestDoor(char *text, unsigned int req_state) 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 */ @@ -4408,9 +4783,14 @@ static boolean RequestDoor(char *text, unsigned int req_state) 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); @@ -4480,9 +4860,13 @@ static boolean RequestDoor(char *text, unsigned int req_state) } /* 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); @@ -4559,10 +4943,23 @@ static boolean RequestEnvelope(char *text, unsigned int req_state) 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 */ @@ -4773,10 +5170,14 @@ boolean Request(char *text, unsigned int req_state) 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 */ @@ -5079,147 +5480,837 @@ boolean Request(char *text, unsigned int req_state) result = 0; } -#if 1 +#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; + + 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; + + door_part_done[i] = FALSE; + door_part_skip[i] = (!(door_state & door_token) || + !g->bitmap); + } + +#if 0 + for (i = 0; i < MAX_DOOR_PARTS; i++) + { + struct DoorPartControlInfo *dpc = &door_part_controls[i]; + struct DoorPartPosInfo *pos = dpc->pos; + int start_step = pos->start_step; + + printf("::: ---> %d: start_step == %d [%d]\n", + i, start_step, door_part_done[i]); + } +#endif + + 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); + 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 + } + + 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 - if (game_status == GAME_MODE_PLAYING && local_player->LevelSolved_GameEnd) - { - HandleGameActions(); - } - else + 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; @@ -5228,7 +6319,7 @@ unsigned int MoveDoor(unsigned int door_state) unsigned int door_delay_value; int stepsize = 1; -#if 0 +#if 1 if (door_1.width < 0 || door_1.width > DXSIZE) door_1.width = DXSIZE; if (door_1.height < 0 || door_1.height > DYSIZE) @@ -5288,6 +6379,24 @@ unsigned int MoveDoor(unsigned int door_state) if (door_state & DOOR_ACTION) { +#if 1 + struct GraphicInfo *g1_left = &graphic_info[IMG_DOOR_1_WING_LEFT]; + struct GraphicInfo *g1_right = &graphic_info[IMG_DOOR_1_WING_RIGHT]; + struct GraphicInfo *g2_left = &graphic_info[IMG_DOOR_2_WING_LEFT]; + struct GraphicInfo *g2_right = &graphic_info[IMG_DOOR_2_WING_RIGHT]; + int door_1_left_width = g1_left->width; + int door_1_left_height = g1_left->height; + int door_1_right_width = g1_right->width; + int door_1_right_height = g1_right->height; + int door_2_left_width = g2_left->width; + int door_2_left_height = g2_left->height; + int door_2_right_width = g2_right->width; + int door_2_right_height = g2_right->height; + int door_1_width = MAX(door_1_left_width, door_1_right_width); + int door_1_height = MAX(door_1_left_height, door_1_right_height); + int door_2_width = MAX(door_2_left_width, door_2_right_width); + int door_2_height = MAX(door_2_left_height, door_2_right_height); +#endif boolean handle_door_1 = (door_state & DOOR_ACTION_1); boolean handle_door_2 = (door_state & DOOR_ACTION_2); boolean door_1_done = (!handle_door_1); @@ -5295,15 +6404,21 @@ unsigned int MoveDoor(unsigned int door_state) boolean door_1_vertical = (door_1.anim_mode & ANIM_VERTICAL); boolean door_2_vertical = (door_2.anim_mode & ANIM_VERTICAL); #if 1 +#if 1 + int door_size_1 = (door_1_vertical ? door_1_height : door_1_width); + int door_size_2 = (door_2_vertical ? door_2_height : door_2_width); +#else int door_size_1 = (door_1_vertical ? DYSIZE : DXSIZE); int door_size_2 = (door_2_vertical ? VYSIZE : VXSIZE); +#endif #else int door_size_1 = (door_1_vertical ? door_1.height : door_1.width); int door_size_2 = (door_2_vertical ? door_2.height : door_2.width); #endif int max_door_size_1 = (door_1_vertical ? DYSIZE : DXSIZE); int max_door_size_2 = (door_2_vertical ? VYSIZE : VXSIZE); - int door_size = (handle_door_1 ? door_size_1 : door_size_2); + // int door_size = (handle_door_1 ? door_size_1 : door_size_2); + int door_size = (handle_door_2 ? door_size_2 : door_size_1); int max_door_size = (handle_door_1 ? max_door_size_1 : max_door_size_2); int door_skip = max_door_size - door_size; int end = door_size; @@ -5322,16 +6437,21 @@ unsigned int MoveDoor(unsigned int door_state) for (k = start; k <= end && !(door_1_done && door_2_done); k += stepsize) { int x = k; -#if 1 +#if 0 Bitmap *bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; GC gc = bitmap->stored_clip_gc; #endif - if (door_state & DOOR_ACTION_1) + if (door_state & DOOR_ACTION_1 && + x * door_1.step_offset <= door_size_1) { int a = MIN(x * door_1.step_offset, end); int p = (door_state & DOOR_OPEN_1 ? end - a : a); +#if 1 + int i = p; +#else int i = p + door_skip; +#endif #if 1 struct GraphicInfo *g_left = &graphic_info[IMG_DOOR_1_WING_LEFT]; @@ -5342,6 +6462,11 @@ unsigned int MoveDoor(unsigned int door_state) 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, @@ -5354,7 +6479,10 @@ unsigned int MoveDoor(unsigned int door_state) 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) @@ -5431,7 +6559,7 @@ unsigned int MoveDoor(unsigned int door_state) 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); @@ -5449,35 +6577,40 @@ unsigned int MoveDoor(unsigned int door_state) int ypos1 = 0, ypos2 = height2; int ypos3 = DYSIZE / 2, ypos4 = DYSIZE - height2; - SetClipOrigin(bitmap, gc, dst1_x - src1_x, dst1_y - src1_y + j); - BlitBitmapMasked(bitmap, drawto, + SetClipOrigin(bm_right, gc_right, + dst1_x - src1_x, dst1_y - src1_y + j); + BlitBitmapMasked(bm_right, drawto, src1_x, src1_y + ypos1, width, height2, dst1_x, dst1_y + ypos1 + j); - BlitBitmapMasked(bitmap, drawto, + BlitBitmapMasked(bm_right, drawto, src1_x, src1_y + ypos3, width, height1, dst1_x, dst1_y + ypos3 + j); - SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src2_y - j); - BlitBitmapMasked(bitmap, drawto, + SetClipOrigin(bm_left, gc_left, + dst2_x - src2_x, dst2_y - src2_y - j); + BlitBitmapMasked(bm_left, drawto, src2_x, src2_y + ypos1 + j, width, height2 - j, dst2_x, dst2_y + ypos1); - BlitBitmapMasked(bitmap, drawto, + BlitBitmapMasked(bm_left, drawto, src2_x, src2_y + ypos3, width, height1, dst2_x, dst2_y + ypos3 - j); - SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src2_y - j); - BlitBitmapMasked(bitmap, drawto, + SetClipOrigin(bm_left, gc_left, + dst2_x - src2_x, dst2_y - src2_y - j); + BlitBitmapMasked(bm_left, drawto, src2_x, src2_y + ypos2, width, height1, dst2_x, dst2_y + ypos2 - j); - BlitBitmapMasked(bitmap, drawto, + BlitBitmapMasked(bm_left, drawto, src2_x, src2_y + ypos4, width, height2, dst2_x, dst2_y + ypos4 - j); - SetClipOrigin(bitmap, gc, dst1_x - src1_x, dst1_y - src1_y + j); - BlitBitmapMasked(bitmap, drawto, + SetClipOrigin(bm_right, gc_right, + dst1_x - src1_x, dst1_y - src1_y + j); + BlitBitmapMasked(bm_right, drawto, src1_x, src1_y + ypos2, width, height1, dst1_x, dst1_y + ypos2 + j); - BlitBitmapMasked(bitmap, drawto, + 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; @@ -5554,7 +6687,8 @@ unsigned int MoveDoor(unsigned int door_state) door_1_done = (a == end); } - if (door_state & DOOR_ACTION_2) + if (door_state & DOOR_ACTION_2 && + x * door_2.step_offset <= door_size_2) { int a = MIN(x * door_2.step_offset, door_size); int p = (door_state & DOOR_OPEN_2 ? door_size - a : a); @@ -5569,6 +6703,11 @@ unsigned int MoveDoor(unsigned int door_state) 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, @@ -5658,7 +6797,7 @@ unsigned int MoveDoor(unsigned int door_state) 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); @@ -5675,21 +6814,25 @@ unsigned int MoveDoor(unsigned int door_state) int height = VYSIZE / 2; int ypos1 = 0, ypos2 = VYSIZE / 2; - SetClipOrigin(bitmap, gc, dst1_x - src1_x, dst1_y - src1_y + j); - BlitBitmapMasked(bitmap, drawto, + SetClipOrigin(bm_right, gc_right, + dst1_x - src1_x, dst1_y - src1_y + j); + BlitBitmapMasked(bm_right, drawto, src1_x, src1_y + ypos1, width, height, dst1_x, dst1_y + ypos1 + j); - SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src2_y - j); - BlitBitmapMasked(bitmap, drawto, + SetClipOrigin(bm_left, gc_left, + dst2_x - src2_x, dst2_y - src2_y - j); + BlitBitmapMasked(bm_left, drawto, src2_x, src2_y + ypos1 + j, width, height - j, dst2_x, dst2_y + ypos1); - SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src2_y - j); - BlitBitmapMasked(bitmap, drawto, + SetClipOrigin(bm_left, gc_left, + dst2_x - src2_x, dst2_y - src2_y - j); + BlitBitmapMasked(bm_left, drawto, src2_x, src2_y + ypos2, width, height, dst2_x, dst2_y + ypos2 - j); - SetClipOrigin(bitmap, gc, dst1_x - src1_x, dst1_y - src1_y + j); - BlitBitmapMasked(bitmap, drawto, + SetClipOrigin(bm_right, gc_right, + dst1_x - src1_x, dst1_y - src1_y + j); + BlitBitmapMasked(bm_right, drawto, src1_x, src1_y + ypos2, width, height - j, dst1_x, dst1_y + ypos2 + j); #else @@ -5765,6 +6908,8 @@ unsigned int MoveDoor(unsigned int door_state) return (door1 | door2); } +#endif + void DrawSpecialEditorDoor() { #if 1 @@ -5913,8 +7058,8 @@ void CreateToolButtons() 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, @@ -6073,8 +7218,8 @@ void CreateToolButtons() 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, @@ -8503,6 +9648,12 @@ int getBeltSwitchElementFromBeltNrAndBeltDir(int belt_nr, int belt_dir) return getBeltSwitchElementFromBeltNrAndBeltDirNr(belt_nr, belt_dir_nr); } +#if 1 +boolean getTeamMode_EM() +{ + return game.team_mode; +} +#else int getNumActivePlayers_EM() { #if 1 @@ -8534,6 +9685,7 @@ int getNumActivePlayers_EM() return num_players; #endif } +#endif int getGameFrameDelay_EM(int native_em_game_frame_delay) { @@ -10366,9 +11518,13 @@ void ChangeViewportPropertiesIfNeeded() 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]; @@ -10397,7 +11553,14 @@ void ChangeViewportPropertiesIfNeeded() 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; @@ -10411,6 +11574,7 @@ void ChangeViewportPropertiesIfNeeded() 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 !!! */ @@ -10497,6 +11661,19 @@ void ChangeViewportPropertiesIfNeeded() #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; @@ -10540,7 +11717,9 @@ void ChangeViewportPropertiesIfNeeded() InitGfxBuffers(); #endif +#if 0 if (gfx_game_mode == GAME_MODE_MAIN) +#endif { #if 1 init_gadgets_and_toons = TRUE; @@ -10584,6 +11763,11 @@ void ChangeViewportPropertiesIfNeeded() InitToons(); } + if (init_em_graphics) + { + InitGraphicInfo_EM(); + } + #if 0 printf("::: %d, %d / %d, %d [%d]\n", VX, VY, EX, EY, game_status); #endif