+void ShowEnvelope(int envelope_nr)
+{
+ int element = EL_ENVELOPE_1 + envelope_nr;
+ int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr;
+ int sound_opening = element_info[element].sound[ACTION_OPENING];
+ int sound_closing = element_info[element].sound[ACTION_CLOSING];
+ boolean ffwd_delay = (tape.playing && tape.fast_forward);
+ boolean no_delay = (tape.warp_forward);
+ int normal_delay_value = ONE_SECOND_DELAY / (ffwd_delay ? 2 : 1);
+ int wait_delay_value = (no_delay ? 0 : normal_delay_value);
+ int anim_mode = graphic_info[graphic].anim_mode;
+ int main_anim_mode = (anim_mode == ANIM_NONE ? ANIM_VERTICAL|ANIM_HORIZONTAL:
+ anim_mode == ANIM_DEFAULT ? ANIM_VERTICAL : anim_mode);
+
+ game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */
+
+ PlayMenuSoundStereo(sound_opening, SOUND_MIDDLE);
+
+ if (anim_mode == ANIM_DEFAULT)
+ AnimateEnvelope(envelope_nr, ANIM_DEFAULT, ACTION_OPENING);
+
+ AnimateEnvelope(envelope_nr, main_anim_mode, ACTION_OPENING);
+
+ if (tape.playing)
+ Delay(wait_delay_value);
+ else
+ WaitForEventToContinue();
+
+ PlayMenuSoundStereo(sound_closing, SOUND_MIDDLE);
+
+ if (anim_mode != ANIM_NONE)
+ AnimateEnvelope(envelope_nr, main_anim_mode, ACTION_CLOSING);
+
+ if (anim_mode == ANIM_DEFAULT)
+ AnimateEnvelope(envelope_nr, ANIM_DEFAULT, ACTION_CLOSING);
+
+ game.envelope_active = FALSE;
+
+ SetDrawtoField(DRAW_BUFFERED);
+
+ redraw_mask |= REDRAW_FIELD;
+ BackToFront();
+}
+
+static void setRequestPosition(int *x, int *y, boolean add_border_size)
+{
+ int border_size = request.border_size;
+ int sx_center = (request.x != -1 ? request.x : SX + SXSIZE / 2);
+ int sy_center = (request.y != -1 ? request.y : SY + SYSIZE / 2);
+ int sx = sx_center - request.width / 2;
+ int sy = sy_center - request.height / 2;
+
+ if (add_border_size)
+ {
+ sx += border_size;
+ sy += border_size;
+ }
+
+ *x = sx;
+ *y = sy;
+}
+
+void DrawEnvelopeRequest(char *text)
+{
+ char *text_final = text;
+ char *text_door_style = NULL;
+ int graphic = IMG_BACKGROUND_REQUEST;
+ Bitmap *src_bitmap = graphic_info[graphic].bitmap;
+ int mask_mode = (src_bitmap != NULL ? BLIT_MASKED : BLIT_ON_BACKGROUND);
+ int font_nr = FONT_REQUEST;
+ int font_width = getFontWidth(font_nr);
+ int font_height = getFontHeight(font_nr);
+ int border_size = request.border_size;
+ int line_spacing = request.line_spacing;
+ int line_height = font_height + line_spacing;
+ int text_width = request.width - 2 * border_size;
+ int text_height = request.height - 2 * border_size;
+ int line_length = text_width / font_width;
+ int max_lines = text_height / line_height;
+ int width = request.width;
+ int height = request.height;
+ int tile_size = request.step_offset;
+ int x_steps = width / tile_size;
+ int y_steps = height / tile_size;
+ int sx, sy;
+ int i, x, y;
+
+ if (request.wrap_single_words)
+ {
+ char *src_text_ptr, *dst_text_ptr;
+
+ text_door_style = checked_malloc(2 * strlen(text) + 1);
+
+ src_text_ptr = text;
+ dst_text_ptr = text_door_style;
+
+ while (*src_text_ptr)
+ {
+ if (*src_text_ptr == ' ' ||
+ *src_text_ptr == '?' ||
+ *src_text_ptr == '!')
+ *dst_text_ptr++ = '\n';
+
+ if (*src_text_ptr != ' ')
+ *dst_text_ptr++ = *src_text_ptr;
+
+ src_text_ptr++;
+ }
+
+ *dst_text_ptr = '\0';
+
+ text_final = text_door_style;
+ }
+
+ setRequestPosition(&sx, &sy, FALSE);
+
+ ClearRectangle(backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE);
+
+ for (y = 0; y < y_steps; y++)
+ for (x = 0; x < x_steps; x++)
+ DrawEnvelopeBackgroundTiles(graphic, sx, sy,
+ x, y, x_steps, y_steps,
+ tile_size, tile_size);
+
+ DrawTextBuffer(sx + border_size, sy + border_size, text_final, font_nr,
+ line_length, -1, max_lines, line_spacing, mask_mode,
+ request.autowrap, request.centered, FALSE);
+
+ for (i = 0; i < NUM_TOOL_BUTTONS; i++)
+ RedrawGadget(tool_gadget[i]);
+
+ // store readily prepared envelope request for later use when animating
+ BlitBitmap(backbuffer, bitmap_db_cross, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+
+#if 0
+ // !!! TEST !!!
+ BlitBitmap(bitmap_db_store, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+ BlitBitmap(bitmap_db_cross, backbuffer, sx, sy, width, height, sx, sy);
+
+ redraw_mask = REDRAW_FIELD | REDRAW_FROM_BACKBUFFER;
+ BackToFront();
+
+ Delay(3000);
+
+ BlitBitmap(bitmap_db_store, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+
+ redraw_mask = REDRAW_FIELD | REDRAW_FROM_BACKBUFFER;
+ BackToFront();
+
+ Delay(1000);
+#endif
+
+ if (text_door_style)
+ free(text_door_style);
+}
+
+#if 1
+
+void AnimateEnvelopeRequest(int anim_mode, int action)
+{
+ int graphic = IMG_BACKGROUND_REQUEST;
+ boolean draw_masked = graphic_info[graphic].draw_masked;
+#if 1
+ int delay_value_normal = request.step_delay;
+ int delay_value_fast = delay_value_normal / 2;
+#else
+ int delay_value_normal = GameFrameDelay;
+ int delay_value_fast = FfwdFrameDelay;
+#endif
+ boolean ffwd_delay = (tape.playing && tape.fast_forward);
+ boolean no_delay = (tape.warp_forward);
+ int delay_value = (ffwd_delay ? delay_value_fast : delay_value_normal);
+ int anim_delay_value = (no_delay ? 0 : delay_value + 500 * 0);
+ unsigned int anim_delay = 0;
+
+ int width = request.width;
+ int height = request.height;
+ int tile_size = request.step_offset;
+ int max_xsize = width / tile_size;
+ int max_ysize = height / tile_size;
+ int max_xsize_inner = max_xsize - 2;
+ int max_ysize_inner = max_ysize - 2;
+
+ int xstart = (anim_mode & ANIM_VERTICAL ? max_xsize_inner : 0);
+ int ystart = (anim_mode & ANIM_HORIZONTAL ? max_ysize_inner : 0);
+ int xend = max_xsize_inner;
+ int yend = (anim_mode != ANIM_DEFAULT ? max_ysize_inner : 0);
+ int xstep = (xstart < xend ? 1 : 0);
+ int ystep = (ystart < yend || xstep == 0 ? 1 : 0);
+ int x, y;
+
+ for (x = xstart, y = ystart; x <= xend && y <= yend; x += xstep, y += ystep)
+ {
+ int xsize = (action == ACTION_CLOSING ? xend - (x - xstart) : x) + 2;
+ int ysize = (action == ACTION_CLOSING ? yend - (y - ystart) : y) + 2;
+ int sx_center = (request.x != -1 ? request.x : SX + SXSIZE / 2);
+ int sy_center = (request.y != -1 ? request.y : SY + SYSIZE / 2);
+ int src_x = sx_center - width / 2;
+ int src_y = sy_center - height / 2;
+ int dst_x = sx_center - xsize * tile_size / 2;
+ int dst_y = sy_center - ysize * tile_size / 2;
+ int xsize_size_left = (xsize - 1) * tile_size;
+ int ysize_size_top = (ysize - 1) * tile_size;
+ int max_xsize_pos = (max_xsize - 1) * tile_size;
+ int max_ysize_pos = (max_ysize - 1) * tile_size;
+ int xx, yy;
+
+ BlitBitmap(bitmap_db_store, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+
+#if 1
+ for (yy = 0; yy < 2; yy++)
+ {
+ for (xx = 0; xx < 2; xx++)
+ {
+ int src_xx = src_x + xx * max_xsize_pos;
+ int src_yy = src_y + yy * max_ysize_pos;
+ int dst_xx = dst_x + xx * xsize_size_left;
+ int dst_yy = dst_y + yy * ysize_size_top;
+ int xx_size = (xx ? tile_size : xsize_size_left);
+ int yy_size = (yy ? tile_size : ysize_size_top);
+
+ if (draw_masked)
+ BlitBitmapMasked(bitmap_db_cross, backbuffer,
+ src_xx, src_yy, xx_size, yy_size, dst_xx, dst_yy);
+ else
+ BlitBitmap(bitmap_db_cross, backbuffer,
+ src_xx, src_yy, xx_size, yy_size, dst_xx, dst_yy);
+ }
+ }
+#else
+ BlitBitmap(bitmap_db_cross, backbuffer,
+ src_x, src_y,
+ xsize_size_left, ysize_size_top,
+ dst_x, dst_y);
+ BlitBitmap(bitmap_db_cross, backbuffer,
+ src_x + max_xsize_pos, src_y,
+ tile_size, ysize_size_top,
+ dst_x + xsize_size_left, dst_y);
+ BlitBitmap(bitmap_db_cross, backbuffer,
+ src_x, src_y + max_ysize_pos,
+ xsize_size_left, tile_size,
+ dst_x, dst_y + ysize_size_top);
+ BlitBitmap(bitmap_db_cross, backbuffer,
+ src_x + max_xsize_pos, src_y + max_ysize_pos,
+ tile_size, tile_size,
+ dst_x + xsize_size_left, dst_y + ysize_size_top);
+#endif
+
+#if 1
+ redraw_mask = REDRAW_FIELD | REDRAW_FROM_BACKBUFFER;
+ // redraw_mask |= REDRAW_ALL | REDRAW_FROM_BACKBUFFER;
+#else
+ redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER;
+#endif
+
+#if 1
+ DoAnimation();
+ BackToFront();
+#else
+ BackToFront();
+#endif
+
+ WaitUntilDelayReached(&anim_delay, anim_delay_value / 2);
+ }
+}
+
+#else
+