1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1995-2002 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
18 /* values for toon animation */
20 #define ANIM_CONTINUE 1
24 static struct ToonScreenInfo screen_info;
26 void InitToonScreen(Bitmap **toon_bitmap_array,
28 void (*update_function)(void),
29 void (*prepare_backbuffer_function)(void),
30 boolean (*redraw_needed_function)(void),
31 struct ToonInfo *toons, int num_toons,
32 int startx, int starty,
33 int width, int height)
35 screen_info.toon_bitmap_array = toon_bitmap_array;
36 screen_info.save_buffer = save_buffer;
37 screen_info.update_function = update_function;
38 screen_info.prepare_backbuffer_function = prepare_backbuffer_function;
39 screen_info.redraw_needed_function = redraw_needed_function;
40 screen_info.toons = toons;
41 screen_info.num_toons = num_toons;
42 screen_info.startx = startx;
43 screen_info.starty = starty;
44 screen_info.width = width;
45 screen_info.height = height;
48 void DrawAnim(Bitmap *toon_bitmap, GC toon_clip_gc,
49 int src_x, int src_y, int width, int height,
50 int dest_x, int dest_y, int pad_x, int pad_y)
52 int buf_x = DOOR_GFX_PAGEX3, buf_y = DOOR_GFX_PAGEY1;
55 /* special method to avoid flickering interference with BackToFront() */
56 BlitBitmap(backbuffer, screen_info.save_buffer, dest_x-pad_x, dest_y-pad_y,
57 width+2*pad_x, height+2*pad_y, buf_x, buf_y);
58 SetClipOrigin(toon_bitmap, toon_clip_gc, dest_x-src_x, dest_y-src_y);
59 BlitBitmapMasked(toon_bitmap, backbuffer,
60 src_x, src_y, width, height, dest_x, dest_y);
61 BlitBitmap(backbuffer, window, dest_x-pad_x, dest_y-pad_y,
62 width+2*pad_x, height+2*pad_y, dest_x-pad_x, dest_y-pad_y);
64 screen_info.update_function();
66 BlitBitmap(screen_info.save_buffer, backbuffer, buf_x, buf_y,
67 width+2*pad_x, height+2*pad_y, dest_x-pad_x, dest_y-pad_y);
69 /* normal method, causing flickering interference with BackToFront() */
70 BlitBitmap(backbuffer, screen_info.save_buffer, dest_x-pad_x, dest_y-pad_y,
71 width+2*pad_x, height+2*pad_y, buf_x, buf_y);
72 SetClipOrigin(toon_bitmap,toon_clip_gc, buf_x-src_x+pad_x,buf_y-src_y+pad_y);
73 BlitBitmapMasked(toon_bitmap, screen_info.save_buffer,
74 src_x, src_y, width, height, buf_x+pad_x, buf_y+pad_y);
75 BlitBitmap(screen_info.save_buffer, window, buf_x, buf_y,
76 width+2*pad_x, height+2*pad_y, dest_x-pad_x, dest_y-pad_y);
82 boolean AnimateToon(int toon_nr, boolean restart)
84 static int pos_x = 0, pos_y = 0;
85 static int delta_x = 0, delta_y = 0;
86 static int frame = 0, frame_step = 1;
87 static boolean horiz_move, vert_move;
88 static unsigned long anim_delay = 0;
89 static unsigned long anim_delay_value = 0;
90 static int width,height;
91 static int pad_x,pad_y;
92 static int cut_x,cut_y;
93 static int src_x, src_y;
94 static int dest_x, dest_y;
96 struct ToonInfo *anim = &screen_info.toons[toon_nr];
97 int bitmap_nr = screen_info.toons[toon_nr].bitmap_nr;
98 Bitmap *anim_bitmap = screen_info.toon_bitmap_array[bitmap_nr];
99 GC anim_clip_gc = anim_bitmap->stored_clip_gc;
103 horiz_move = (anim->direction & (ANIMDIR_LEFT | ANIMDIR_RIGHT));
104 vert_move = (anim->direction & (ANIMDIR_UP | ANIMDIR_DOWN));
105 anim_delay_value = 1000/anim->frames_per_second;
110 if (anim->position == ANIMPOS_UP)
112 else if (anim->position == ANIMPOS_DOWN)
113 pos_y = screen_info.height - anim->height;
114 else if (anim->position == ANIMPOS_UPPER)
115 pos_y = SimpleRND((screen_info.height - anim->height) / 2);
117 pos_y = SimpleRND(screen_info.height - anim->height);
119 if (anim->direction == ANIMDIR_RIGHT)
121 delta_x = anim->stepsize;
122 pos_x = -anim->width + delta_x;
126 delta_x = -anim->stepsize;
127 pos_x = screen_info.width + delta_x;
133 if (anim->position == ANIMPOS_LEFT)
135 else if (anim->position == ANIMPOS_RIGHT)
136 pos_x = screen_info.width - anim->width;
138 pos_x = SimpleRND(screen_info.width - anim->width);
140 if (anim->direction == ANIMDIR_DOWN)
142 delta_y = anim->stepsize;
143 pos_y = -anim->height + delta_y;
147 delta_y = -anim->stepsize;
148 pos_y = screen_info.width + delta_y;
154 if (pos_x <= -anim->width - anim->stepsize ||
155 pos_x >= screen_info.width + anim->stepsize ||
156 pos_y <= -anim->height - anim->stepsize ||
157 pos_y >= screen_info.height + anim->stepsize)
160 if (!DelayReached(&anim_delay, anim_delay_value))
162 if (screen_info.redraw_needed_function() && !restart)
163 DrawAnim(anim_bitmap, anim_clip_gc,
164 src_x + cut_x, src_y + cut_y,
166 screen_info.startx + dest_x,
167 screen_info.starty + dest_y,
173 if (pos_x < -anim->width)
174 pos_x = -anim->width;
175 else if (pos_x > screen_info.width)
176 pos_x = screen_info.width;
177 if (pos_y < -anim->height)
178 pos_y = -anim->height;
179 else if (pos_y > screen_info.height)
180 pos_y = screen_info.height;
182 pad_x = (horiz_move ? anim->stepsize : 0);
183 pad_y = (vert_move ? anim->stepsize : 0);
184 src_x = anim->src_x + frame * anim->width;
190 height = anim->height;
198 else if (pos_x > screen_info.width - anim->width)
199 width -= (pos_x - (screen_info.width - anim->width));
207 else if (pos_y > screen_info.height - anim->height)
208 height -= (pos_y - (screen_info.height - anim->height));
210 DrawAnim(anim_bitmap, anim_clip_gc,
211 src_x + cut_x, src_y + cut_y,
213 screen_info.startx + dest_x,
214 screen_info.starty + dest_y,
221 if (frame<0 || frame>=anim->frames)
226 frame = (frame<0 ? 1 : anim->frames-2);
229 frame = (frame<0 ? anim->frames-1 : 0);
235 void HandleAnimation(int mode)
237 static unsigned long animstart_delay = -1;
238 static unsigned long animstart_delay_value = 0;
239 static boolean anim_restart = TRUE;
240 static boolean reset_delay = TRUE;
241 static int toon_nr = 0;
250 screen_info.prepare_backbuffer_function();
260 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
262 /* Redraw background even when in direct drawing mode */
263 draw_mode = setup.direct_draw;
264 setup.direct_draw = FALSE;
265 screen_info.update_function();
266 setup.direct_draw = draw_mode;
276 animstart_delay = Counter();
277 animstart_delay_value = SimpleRND(3000);
283 if (!DelayReached(&animstart_delay, animstart_delay_value))
286 toon_nr = SimpleRND(screen_info.num_toons);
289 anim_restart = reset_delay = AnimateToon(toon_nr,anim_restart);
294 HandleAnimation(ANIM_START);
299 HandleAnimation(ANIM_STOP);
304 HandleAnimation(ANIM_CONTINUE);