X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=ac20e3c144e5b3567019de53c3ad60344ab517c5;hb=520b554dfeb3a72b6b3af91903642b158169407c;hp=49d429605d35c7ceba89f06d84aecbf637fd1c95;hpb=04822a800bb5479087613b0730fdf7e765ba012c;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index 49d42960..ac20e3c1 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 *); @@ -888,11 +1017,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 +1234,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 +1252,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; @@ -2830,7 +2989,7 @@ 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 @@ -3275,14 +3434,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 +3507,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 +3649,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; @@ -4408,9 +4585,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 +4662,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); @@ -5170,10 +5356,222 @@ boolean Request(char *text, unsigned int req_state) #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, @@ -5183,6 +5581,7 @@ unsigned int OpenDoor(unsigned int door_state) 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; } @@ -5196,6 +5595,15 @@ unsigned int CloseDoor(unsigned int door_state) 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); @@ -5203,6 +5611,7 @@ unsigned int CloseDoor(unsigned int door_state) 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; } @@ -5220,15 +5629,36 @@ 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 stepsize = 1; + int i; -#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) @@ -5264,6 +5694,7 @@ unsigned int MoveDoor(unsigned int door_state) door_state &= ~DOOR_CLOSE_2; } +#if 0 door_delay_value = (door_state & DOOR_ACTION_1 ? door_1.step_delay : door_2.step_delay); @@ -5272,6 +5703,7 @@ unsigned int MoveDoor(unsigned int door_state) stepsize = 20; /* must be chosen to always draw last frame */ door_delay_value = 0; } +#endif if (global.autoplay_leveldir) { @@ -5286,69 +5718,583 @@ unsigned int MoveDoor(unsigned int door_state) if (door_state & DOOR_ACTION) { - 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); - boolean door_2_done = (!handle_door_2); - boolean door_1_vertical = (door_1.anim_mode & ANIM_VERTICAL); - boolean door_2_vertical = (door_2.anim_mode & ANIM_VERTICAL); -#if 1 - int door_size_1 = (door_1_vertical ? DYSIZE : DXSIZE); - int door_size_2 = (door_2_vertical ? VYSIZE : VXSIZE); -#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 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; - int start = ((door_state & DOOR_NO_DELAY) ? end : 0); + 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; - if (!(door_state & DOOR_NO_DELAY) && !setup.quick_doors) + for (i = 0; i < NUM_DOORS; i++) + panel_has_doors[i] = FALSE; + + for (i = 0; i < MAX_DOOR_PARTS; i++) { - /* opening door sound has priority over simultaneously closing door */ - if (door_state & (DOOR_OPEN_1 | DOOR_OPEN_2)) - PlayMenuSoundStereo(SND_DOOR_OPENING, SOUND_MIDDLE); - else if (door_state & (DOOR_CLOSE_1 | DOOR_CLOSE_2)) - PlayMenuSoundStereo(SND_DOOR_CLOSING, SOUND_MIDDLE); + 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); } - for (k = start; k <= end && !(door_1_done && door_2_done); k += stepsize) +#if 0 + for (i = 0; i < MAX_DOOR_PARTS; i++) { - int x = k; - Bitmap *bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; - GC gc = bitmap->stored_clip_gc; + struct DoorPartControlInfo *dpc = &door_part_controls[i]; + struct DoorPartPosInfo *pos = dpc->pos; + int start_step = pos->start_step; - if (door_state & DOOR_ACTION_1) - { - int a = MIN(x * door_1.step_offset, end); - int p = (door_state & DOOR_OPEN_1 ? end - a : a); - int i = p + door_skip; + printf("::: ---> %d: start_step == %d [%d]\n", + i, start_step, door_part_done[i]); + } +#endif - if (door_1.anim_mode & ANIM_STATIC_PANEL) - { - BlitBitmap(bitmap_db_door, drawto, - DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, - DXSIZE, DYSIZE, DX, DY); - } - else if (x <= a) + 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 + + for (k = 0; k < num_move_steps; k++) + { + door_part_done_all = TRUE; + + for (i = 0; i < NUM_DOORS; i++) + door_panel_drawn[i] = FALSE; + + 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 + +#if 0 + if (DOOR_PART_IS_PANEL(nr)) + { + int start_step = pos->start_step; + + k2 = (door_closing ? k1 : num_steps[nr] - k1);// - start_step; + kk = (k2 < 0 ? 0 : k2); + } +#endif + +#if 0 + // !!! TEST !!! + if (nr != 16 && nr != 0) + continue; +#endif + +#if 0 + // !!! TEST !!! + if (!is_panel) + continue; +#endif + +#if 1 + if (door_part_skip[nr]) + continue; +#endif + + if (!(door_state & door_token)) + continue; + + if (!g->bitmap) + continue; + +#if 0 + if (current_move_delay % step_delay) + continue; +#endif + + // draw door panel + + if (!door_panel_drawn[door_index]) + { +#if 1 + 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 + src_x = src_xx; + src_y = src_yy; +#else + src_x = panel_pos->x + src_xx; + src_y = panel_pos->y + src_yy; +#endif + } + else + { + src_x = g->src_x + src_xx; + src_y = g->src_y + src_yy; + } + + dst_x = door_rect->x + dst_xx; + dst_y = door_rect->y + dst_yy; + +#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 (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 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 + + 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 + +#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 0 + if (!door_part_done[nr]) + printf("::: k == %d, nr == %d\n", k, nr); +#endif + } + + if (!(door_state & DOOR_NO_DELAY)) + { + BackToFront(); + + if (game_status == GAME_MODE_MAIN) + DoAnimation(); + + WaitUntilDelayReached(&door_delay, door_delay_value); + + current_move_delay += max_step_delay; + } + +#if 0 + door_part_done_all = TRUE; + + 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 + } + } + + if (door_state & DOOR_ACTION_1) + door1 = door_state & DOOR_ACTION_1; + if (door_state & DOOR_ACTION_2) + door2 = door_state & DOOR_ACTION_2; + +#if 0 + printf("::: DOORS DONE %08x\n", door_state); + Delay(3000); + printf("::: GO!\n"); +#endif + + return (door1 | door2); +} + +#else + +// ========== OLD ============================================================== + +unsigned int MoveDoor(unsigned int door_state) +{ + static int door1 = DOOR_OPEN_1; + static int door2 = DOOR_CLOSE_2; + unsigned int door_delay = 0; + unsigned int door_delay_value; + int stepsize = 1; + +#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; + } + + door_delay_value = (door_state & DOOR_ACTION_1 ? door_1.step_delay : + door_2.step_delay); + + // door_delay_value *= 4; // !!! TEST ONLY !!! + + if (setup.quick_doors) + { + stepsize = 20; /* must be chosen to always draw last frame */ + door_delay_value = 0; + } + + 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) + { +#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); + boolean door_2_done = (!handle_door_2); + 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_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; + int start = ((door_state & DOOR_NO_DELAY) ? end : 0); + int k; + + if (!(door_state & DOOR_NO_DELAY) && !setup.quick_doors) + { + /* opening door sound has priority over simultaneously closing door */ + if (door_state & (DOOR_OPEN_1 | DOOR_OPEN_2)) + PlayMenuSoundStereo(SND_DOOR_OPENING, SOUND_MIDDLE); + else if (door_state & (DOOR_CLOSE_1 | DOOR_CLOSE_2)) + PlayMenuSoundStereo(SND_DOOR_CLOSING, SOUND_MIDDLE); + } + + for (k = start; k <= end && !(door_1_done && door_2_done); k += stepsize) + { + int x = k; +#if 0 + Bitmap *bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; + GC gc = bitmap->stored_clip_gc; +#endif + + 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]; + struct GraphicInfo *g_right = &graphic_info[IMG_DOOR_1_WING_RIGHT]; + Bitmap *bm_left = g_left->bitmap; + Bitmap *bm_right = g_right->bitmap; + GC gc_left = bm_left->stored_clip_gc; + 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, + DXSIZE, DYSIZE, DX, DY); + } + else if (x <= a) { 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) { +#if 1 + int src1_x = g_right->src_x; + int src1_y = g_right->src_y; + int src2_x = g_left->src_x + g_left->width - i; + int src2_y = g_left->src_y; + int dst1_x = DX + DXSIZE - i; + int dst1_y = DY; + int dst2_x = DX; + int dst2_y = DY; + int width = i; + int height = DYSIZE; + + SetClipOrigin(bm_right, gc_right, dst1_x - src1_x, dst1_y - src1_y); + BlitBitmapMasked(bm_right, drawto, src1_x, src1_y, width, height, + dst1_x, dst1_y); + + SetClipOrigin(bm_left, gc_left, dst2_x - src2_x, dst2_y - src2_y); + BlitBitmapMasked(bm_left, drawto, src2_x, src2_y, width, height, + dst2_x, dst2_y); +#else int src1_x = DXSIZE, src1_y = DOOR_GFX_PAGEY1; - int dst1_x = DX + DXSIZE - i, dst1_y = DY; int src2_x = DXSIZE - i, src2_y = DOOR_GFX_PAGEY1; + int dst1_x = DX + DXSIZE - i, dst1_y = DY; int dst2_x = DX, dst2_y = DY; int width = i, height = DYSIZE; @@ -5359,12 +6305,33 @@ unsigned int MoveDoor(unsigned int door_state) SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src2_y); BlitBitmapMasked(bitmap, drawto, src2_x, src2_y, width, height, dst2_x, dst2_y); +#endif } else if (door_1.anim_mode & ANIM_VERTICAL && x <= DYSIZE) { +#if 1 + int src1_x = g_right->src_x; + int src1_y = g_right->src_y; + int src2_x = g_left->src_x; + int src2_y = g_left->src_y + g_left->height - i; + int dst1_x = DX; + int dst1_y = DY + DYSIZE - i; + int dst2_x = DX; + int dst2_y = DY; + int width = DXSIZE; + int height = i; + + SetClipOrigin(bm_right, gc_right, dst1_x - src1_x, dst1_y - src1_y); + BlitBitmapMasked(bm_right, drawto, src1_x, src1_y, width, height, + dst1_x, dst1_y); + + SetClipOrigin(bm_left, gc_left, dst2_x - src2_x, dst2_y - src2_y); + BlitBitmapMasked(bm_left, drawto, src2_x, src2_y, width, height, + dst2_x, dst2_y); +#else int src1_x = DXSIZE, src1_y = DOOR_GFX_PAGEY1; - int dst1_x = DX, dst1_y = DY + DYSIZE - i; int src2_x = 0, src2_y = DOOR_GFX_PAGEY1 + DYSIZE - i; + int dst1_x = DX, dst1_y = DY + DYSIZE - i; int dst2_x = DX, dst2_y = DY; int width = DXSIZE, height = i; @@ -5375,11 +6342,99 @@ unsigned int MoveDoor(unsigned int door_state) SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src2_y); BlitBitmapMasked(bitmap, drawto, src2_x, src2_y, width, height, 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); +#if 1 + int src1_x = g_right->src_x; + int src1_y = g_right->src_y; + int src2_x = g_left->src_x + g_left->width - i; + int src2_y = g_left->src_y; + int dst1_x = DX + DXSIZE - i; + int dst1_y = DY; + int dst2_x = DX; + int dst2_y = DY; + int width = i; + int height1 = 63, height2 = DYSIZE / 2 - height1; + int ypos1 = 0, ypos2 = height2; + int ypos3 = DYSIZE / 2, ypos4 = DYSIZE - height2; + + 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(bm_right, drawto, + src1_x, src1_y + ypos3, width, height1, + dst1_x, dst1_y + ypos3 + j); + 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(bm_left, drawto, + src2_x, src2_y + ypos3, width, height1, + dst2_x, dst2_y + ypos3 - j); + + 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(bm_left, drawto, + src2_x, src2_y + ypos4, width, height2, + dst2_x, dst2_y + ypos4 - j); + 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(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; + int dst1_x = DX + DXSIZE - i, dst1_y = DY; + int dst2_x = DX, dst2_y = DY; + int width = i, height = DYSIZE; + int ypos1 = 63, ypos2 = 77, ypos3 = 140, ypos4 = 203; + + SetClipOrigin(bitmap, gc, dst1_x - src1_x, dst1_y - src1_y + j); + BlitBitmapMasked(bitmap, drawto, + src1_x, src1_y, width, ypos2, + dst1_x, dst1_y + j); + BlitBitmapMasked(bitmap, drawto, + src1_x, src1_y + ypos3, width, ypos1, + dst1_x, dst1_y + ypos3 + j); + SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src2_y - j); + BlitBitmapMasked(bitmap, drawto, + src2_x, src2_y + j, width, ypos2 - j, + dst2_x, dst2_y); + BlitBitmapMasked(bitmap, drawto, + src2_x, src2_y + ypos3, width, ypos1, + dst2_x, dst2_y + ypos3 - j); + + SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src2_y - j); + BlitBitmapMasked(bitmap, drawto, + src2_x, src2_y + ypos2, width, ypos1, + dst2_x, dst2_y + ypos2 - j); + BlitBitmapMasked(bitmap, drawto, + src2_x, src2_y + ypos4, width, ypos2, + dst2_x, dst2_y + ypos4 - j); + SetClipOrigin(bitmap, gc, dst1_x - src1_x, dst1_y - src1_y + j); + BlitBitmapMasked(bitmap, drawto, + src1_x, src1_y + ypos2, width, ypos1, + dst1_x, dst1_y + ypos2 + j); + BlitBitmapMasked(bitmap, drawto, + src1_x, src1_y + ypos4, width, ypos2 - j, + dst1_x, dst1_y + ypos4 + j); + + /* SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1); BlitBitmapMasked(bitmap, drawto, DXSIZE, DOOR_GFX_PAGEY1, i, 77, @@ -5409,18 +6464,35 @@ unsigned int MoveDoor(unsigned int door_state) BlitBitmapMasked(bitmap, drawto, DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j, DX + DXSIZE - i, DY + 203 + j); + */ +#endif } redraw_mask |= REDRAW_DOOR_1; 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); int i = p + door_skip; +#if 1 + struct GraphicInfo *g_left = &graphic_info[IMG_DOOR_2_WING_LEFT]; + struct GraphicInfo *g_right = &graphic_info[IMG_DOOR_2_WING_RIGHT]; + Bitmap *bm_left = g_left->bitmap; + Bitmap *bm_right = g_right->bitmap; + GC gc_left = bm_left->stored_clip_gc; + 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, @@ -5438,9 +6510,29 @@ unsigned int MoveDoor(unsigned int door_state) if (door_2.anim_mode & ANIM_HORIZONTAL && x <= VXSIZE) { +#if 1 + int src1_x = g_right->src_x; + int src1_y = g_right->src_y; + int src2_x = g_left->src_x + g_left->width - i; + int src2_y = g_left->src_y; + int dst1_x = VX + VXSIZE - i; + int dst1_y = VY; + int dst2_x = VX; + int dst2_y = VY; + int width = i; + int height = VYSIZE; + + SetClipOrigin(bm_right, gc_right, dst1_x - src1_x, dst1_y - src1_y); + BlitBitmapMasked(bm_right, drawto, src1_x, src1_y, width, height, + dst1_x, dst1_y); + + SetClipOrigin(bm_left, gc_left, dst2_x - src2_x, dst2_y - src2_y); + BlitBitmapMasked(bm_left, drawto, src2_x, src2_y, width, height, + dst2_x, dst2_y); +#else int src1_x = VXSIZE, src1_y = DOOR_GFX_PAGEY2; - int dst1_x = VX + VXSIZE - i, dst1_y = VY; int src2_x = VXSIZE - i, src2_y = DOOR_GFX_PAGEY2; + int dst1_x = VX + VXSIZE - i, dst1_y = VY; int dst2_x = VX, dst2_y = VY; int width = i, height = VYSIZE; @@ -5451,12 +6543,33 @@ unsigned int MoveDoor(unsigned int door_state) SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src2_y); BlitBitmapMasked(bitmap, drawto, src2_x, src2_y, width, height, dst2_x, dst2_y); +#endif } else if (door_2.anim_mode & ANIM_VERTICAL && x <= VYSIZE) { +#if 1 + int src1_x = g_right->src_x; + int src1_y = g_right->src_y; + int src2_x = g_left->src_x; + int src2_y = g_left->src_y + g_left->height - i; + int dst1_x = VX; + int dst1_y = VY + VYSIZE - i; + int dst2_x = VX; + int dst2_y = VY; + int width = VXSIZE; + int height = i; + + SetClipOrigin(bm_right, gc_right, dst1_x - src1_x, dst1_y - src1_y); + BlitBitmapMasked(bm_right, drawto, src1_x, src1_y, width, height, + dst1_x, dst1_y); + + SetClipOrigin(bm_left, gc_left, dst2_x - src2_x, dst2_y - src2_y); + BlitBitmapMasked(bm_left, drawto, src2_x, src2_y, width, height, + dst2_x, dst2_y); +#else int src1_x = VXSIZE, src1_y = DOOR_GFX_PAGEY2; - int dst1_x = VX, dst1_y = VY + VYSIZE - i; int src2_x = 0, src2_y = DOOR_GFX_PAGEY2 + VYSIZE - i; + int dst1_x = VX, dst1_y = VY + VYSIZE - i; int dst2_x = VX, dst2_y = VY; int width = VXSIZE, height = i; @@ -5467,11 +6580,73 @@ unsigned int MoveDoor(unsigned int door_state) SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src2_y); BlitBitmapMasked(bitmap, drawto, src2_x, src2_y, width, height, 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); +#if 1 + int src1_x = g_right->src_x; + int src1_y = g_right->src_y; + int src2_x = g_left->src_x + g_left->width - i; + int src2_y = g_left->src_y; + int dst1_x = VX + VXSIZE - i; + int dst1_y = VY; + int dst2_x = VX; + int dst2_y = VY; + int width = i; + int height = VYSIZE / 2; + int ypos1 = 0, ypos2 = VYSIZE / 2; + + 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(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(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(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 + int src1_x = VXSIZE, src1_y = DOOR_GFX_PAGEY2; + int src2_x = VXSIZE - i, src2_y = DOOR_GFX_PAGEY2; + int dst1_x = VX + VXSIZE - i, dst1_y = VY; + int dst2_x = VX, dst2_y = VY; + int width = i, height = VYSIZE; + int ypos = VYSIZE / 2; + + SetClipOrigin(bitmap, gc, dst1_x - src1_x, dst1_y - src1_y + j); + BlitBitmapMasked(bitmap, drawto, + src1_x, src1_y, width, ypos, + dst1_x, dst1_y + j); + SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src1_y - j); + BlitBitmapMasked(bitmap, drawto, + src2_x, src2_y + j, width, ypos - j, + dst2_x, dst2_y); + + SetClipOrigin(bitmap, gc, dst2_x - src2_x, dst2_y - src1_y - j); + BlitBitmapMasked(bitmap, drawto, + src2_x, src2_y + ypos, width, ypos, + dst2_x, dst2_y + ypos - j); + SetClipOrigin(bitmap, gc, dst1_x - src1_x, dst1_y - src1_y + j); + BlitBitmapMasked(bitmap, drawto, + src1_x, src1_y + ypos, width, ypos - j, + dst1_x, dst1_y + ypos + j); + + /* SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2); BlitBitmapMasked(bitmap, drawto, VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2, @@ -5490,6 +6665,8 @@ unsigned int MoveDoor(unsigned int door_state) VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2 - j, VX + VXSIZE - i, VY + VYSIZE / 2 + j); + */ +#endif } redraw_mask |= REDRAW_DOOR_2; @@ -5516,6 +6693,8 @@ unsigned int MoveDoor(unsigned int door_state) return (door1 | door2); } +#endif + void DrawSpecialEditorDoor() { #if 1 @@ -5664,8 +6843,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, @@ -5824,8 +7003,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, @@ -8254,11 +9433,33 @@ 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 + int num_players = 0; + int i; + + if (!tape.playing) + return (setup.team_mode ? MAX_PLAYERS : 1); + + for (i = 0; i < MAX_PLAYERS; i++) + if (tape.player_participates[i]) + num_players++; + + return (num_players > 1 ? MAX_PLAYERS : 1); + +#else + int num_players = 0; int i; + /* when recording game, activate all connected players */ if (!tape.playing) return -1; @@ -8267,7 +9468,9 @@ int getNumActivePlayers_EM() num_players++; return num_players; +#endif } +#endif int getGameFrameDelay_EM(int native_em_game_frame_delay) { @@ -10100,9 +11303,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]; @@ -10274,7 +11481,9 @@ void ChangeViewportPropertiesIfNeeded() InitGfxBuffers(); #endif +#if 0 if (gfx_game_mode == GAME_MODE_MAIN) +#endif { #if 1 init_gadgets_and_toons = TRUE;