# HG changeset patch # User Paul Boddie # Date 1542130747 -3600 # Node ID 79f53d89a0fd0570f6765cfadaa008f911fcb7b3 # Parent ddb4b7db1d9bb48f32927007d836b30343647b7d Demonstrate multiple sprites moving around at the same time. diff -r ddb4b7db1d9b -r 79f53d89a0fd examples/vga/main.c --- a/examples/vga/main.c Tue Nov 13 17:54:21 2018 +0100 +++ b/examples/vga/main.c Tue Nov 13 18:39:07 2018 +0100 @@ -112,26 +112,47 @@ +/* Update the sprite position. */ + +static void update_sprite_position(sprite_t *s, int *xdir, int *ydir) +{ + position_t *last = image_get_stored_position(s, wrap_value(display_config.frame - 1, display_config.frames)); + position_t *next = image_get_sprite_position(s); + + if (((*xdir > 0) && (last->x < display_config.line_length - s->image->width - *xdir)) || + ((*xdir < 0) && (last->x > -*xdir))) + { + next->x = last->x + *xdir; + } + else + { + next->x = last->x; + if (*xdir) + *xdir = -*xdir; + } + + if (((*ydir > 0) && (last->y < display_config.line_count - s->image->height / s->yscale - *ydir)) || + ((*ydir < 0) && (last->y > -*ydir))) + { + next->y = last->y + *ydir; + } + else + { + next->y = last->y; + if (*ydir) + *ydir = -*ydir; + } +} + /* Move a sprite around on the framebuffer. */ static void animate(uint32_t delay) { /* Stores of background details, replotted when moving the sprite. */ - Sprite(s, &sprite, &display_config, FRAME_COUNT, 0x0c, SOURCE_YSTEP); - - /* Sprite position. */ - - int x, y; - - /* Scrolling directions. */ - - int dir[] = {1, 0, -1, 0, 1}; - int dirindex = 0; - - /* Scroll increments. */ - - int xdir, ydir; + Sprite(s1, &sprite, &display_config, FRAME_COUNT, 0x0c, SOURCE_YSTEP); + Sprite(s2, &sprite, &display_config, FRAME_COUNT, 0x0c, SOURCE_YSTEP); + Sprite(s3, &sprite, &display_config, FRAME_COUNT, 0x0c, SOURCE_YSTEP); /* Scrolling viewport. */ @@ -141,53 +162,57 @@ viewport_set_origin(&v, 0, 0); + /* Sprite and scrolling directions. */ + + int xdir[] = {1, -1, 0}, ydir[] = {1, 0, -1}; + + /* Sprite positions. */ + + image_set_sprite_position(&s1, 0, 0); + image_set_sprite_position(&s2, display_config.line_length - s2.image->width, 0); + image_set_sprite_position(&s3, 0, display_config.line_count - s3.image->height); + /* Animation loop. */ while (1) { - for (y = 0; y < display_config.line_count - s.image->height; y++) - { - for (x = 0; x < display_config.line_length - s.image->width; x++) - { - image_set_sprite_position(&s, x, y); - image_plot_sprite(&s); + image_plot_sprite(&s1); + image_plot_sprite(&s2); + image_plot_sprite(&s3); - /* Update the display with the frame details. */ + /* Update the display with the frame details. */ + + vga_set_frame(&display_config, 1); + wait(delay); - vga_set_frame(&display_config, 1); - wait(delay); + /* Select the next frame to plot to. */ - /* Select the next frame to plot to. */ + display_select_next_frame(&display_config); - display_select_next_frame(&display_config); - - /* Prepare the frame for updates. */ + /* Prepare the frame for updates. */ - viewport_unplot_sprite_from_image(&v, &s, &scr); - - /* Scroll in the indicated direction. */ + viewport_unplot_sprite_from_image(&v, &s1, &scr); + viewport_unplot_sprite_from_image(&v, &s2, &scr); + viewport_unplot_sprite_from_image(&v, &s3, &scr); - xdir = dir[dirindex]; - ydir = dir[dirindex + 1]; - - /* Update the origin if appropriate. */ + /* Update the origin to scroll the screen. */ - /* Due to the effect of a simple screen start increment in the - dual channel configuration, horizontal scrolling involves two - pixel increments and thus requires a two-pixel column to be - plotted per scrolling increment. */ + /* Due to the effect of a simple screen start increment in the + dual channel configuration, horizontal scrolling involves two + pixel increments and thus requires a two-pixel column to be + plotted per scrolling increment. */ - /* For vertically-scaled backgrounds, the full resolution image - is traversed by multiples of the scrolling increment. */ + /* For vertically-scaled backgrounds, the full resolution image + is traversed by multiples of the scrolling increment. */ + + viewport_update_origin(&v, xdir[0] * SCROLL_XSTEP, + ydir[0] * SOURCE_YSTEP); - viewport_update_origin(&v, xdir * SCROLL_XSTEP, - ydir * SOURCE_YSTEP); - } + /* Update the position of the sprite being plotted. */ - /* Switch direction periodically. */ - - dirindex = wrap_value(dirindex + 1, 4); - } + update_sprite_position(&s1, &xdir[0], &ydir[0]); + update_sprite_position(&s2, &xdir[1], &ydir[1]); + update_sprite_position(&s3, &xdir[2], &ydir[2]); } } @@ -292,7 +317,7 @@ /* Move a sprite around on the screen with a delay between each movement. */ setup(); - animate(1 << 18); + animate(1); }