X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Ftoons.c;h=c067d2d460ee1e9fd1d55308b671216780114bcb;hb=3fd727f8ab7628eaab0be7de31658d7d468d6c8d;hp=5c95800cc72c5f53fa0d126221dbaf9e890ac3ae;hpb=a4eaa7fcd8ca604faeee50f049c441415aa4968c;p=rocksndiamonds.git diff --git a/src/libgame/toons.c b/src/libgame/toons.c index 5c95800c..c067d2d4 100644 --- a/src/libgame/toons.c +++ b/src/libgame/toons.c @@ -23,16 +23,64 @@ static struct ToonScreenInfo screen_info; -void InitToonScreen(Bitmap **toon_bitmap_array, - Bitmap *save_buffer, + +/* ========================================================================= */ +/* generic animation frame calculation */ +/* ========================================================================= */ + +int getAnimationFrame(int num_frames, int delay, int mode, int start_frame, + int sync_frame) +{ + int frame = 0; + + sync_frame += start_frame * delay; + + if (mode & ANIM_LOOP) /* normal, looping animation */ + { + frame = (sync_frame % (delay * num_frames)) / delay; + } + else if (mode & ANIM_LINEAR) /* normal, non-looping animation */ + { + frame = sync_frame / delay; + + if (frame > num_frames - 1) + frame = num_frames - 1; + } + else if (mode & ANIM_PINGPONG) /* use border frames once */ + { + int max_anim_frames = 2 * num_frames - 2; + + frame = (sync_frame % (delay * max_anim_frames)) / delay; + frame = (frame < num_frames ? frame : max_anim_frames - frame); + } + else if (mode & ANIM_PINGPONG2) /* use border frames twice */ + { + int max_anim_frames = 2 * num_frames; + + frame = (sync_frame % (delay * max_anim_frames)) / delay; + frame = (frame < num_frames ? frame : max_anim_frames - frame - 1); + } + + if (mode & ANIM_REVERSE) /* use reverse animation direction */ + frame = num_frames - frame - 1; + + return frame; +} + + +/* ========================================================================= */ +/* toon animation functions */ +/* ========================================================================= */ + +void InitToonScreen(Bitmap *save_buffer, void (*update_function)(void), void (*prepare_backbuffer_function)(void), boolean (*redraw_needed_function)(void), struct ToonInfo *toons, int num_toons, int startx, int starty, - int width, int height) + int width, int height, + int frame_delay_value) { - screen_info.toon_bitmap_array = toon_bitmap_array; screen_info.save_buffer = save_buffer; screen_info.update_function = update_function; screen_info.prepare_backbuffer_function = prepare_backbuffer_function; @@ -43,6 +91,7 @@ void InitToonScreen(Bitmap **toon_bitmap_array, screen_info.starty = starty; screen_info.width = width; screen_info.height = height; + screen_info.frame_delay_value = frame_delay_value; } void DrawAnim(Bitmap *toon_bitmap, GC toon_clip_gc, @@ -81,9 +130,10 @@ void DrawAnim(Bitmap *toon_bitmap, GC toon_clip_gc, boolean AnimateToon(int toon_nr, boolean restart) { + static unsigned long animation_frame_counter = 0; static int pos_x = 0, pos_y = 0; static int delta_x = 0, delta_y = 0; - static int frame = 0, frame_step = 1; + static int frame = 0; static boolean horiz_move, vert_move; static unsigned long anim_delay = 0; static unsigned long anim_delay_value = 0; @@ -92,18 +142,19 @@ boolean AnimateToon(int toon_nr, boolean restart) static int cut_x,cut_y; static int src_x, src_y; static int dest_x, dest_y; - struct ToonInfo *anim = &screen_info.toons[toon_nr]; - int bitmap_nr = screen_info.toons[toon_nr].bitmap_nr; - Bitmap *anim_bitmap = screen_info.toon_bitmap_array[bitmap_nr]; + Bitmap *anim_bitmap = screen_info.toons[toon_nr].bitmap; GC anim_clip_gc = anim_bitmap->stored_clip_gc; if (restart) { horiz_move = (anim->direction & (ANIMDIR_LEFT | ANIMDIR_RIGHT)); vert_move = (anim->direction & (ANIMDIR_UP | ANIMDIR_DOWN)); - anim_delay_value = 1000/anim->frames_per_second; - frame = 0; + anim_delay_value = anim->move_delay * screen_info.frame_delay_value; + + frame = getAnimationFrame(anim->anim_frames, anim->anim_delay, + anim->anim_mode, anim->start_frame, + animation_frame_counter++); if (horiz_move) { @@ -189,7 +240,7 @@ boolean AnimateToon(int toon_nr, boolean restart) width = anim->width; height = anim->height; - if (pos_x<0) + if (pos_x < 0) { dest_x = 0; width += pos_x; @@ -198,7 +249,7 @@ boolean AnimateToon(int toon_nr, boolean restart) else if (pos_x > screen_info.width - anim->width) width -= (pos_x - (screen_info.width - anim->width)); - if (pos_y<0) + if (pos_y < 0) { dest_y = 0; height += pos_y; @@ -216,18 +267,10 @@ boolean AnimateToon(int toon_nr, boolean restart) pos_x += delta_x; pos_y += delta_y; - frame += frame_step; - if (frame<0 || frame>=anim->frames) - { - if (anim->mode == ANIM_PINGPONG) - { - frame_step *= -1; - frame = (frame<0 ? 1 : anim->frames-2); - } - else - frame = (frame<0 ? anim->frames-1 : 0); - } + frame = getAnimationFrame(anim->anim_frames, anim->anim_delay, + anim->anim_mode, anim->start_frame, + animation_frame_counter++); return FALSE; }