1.1 --- a/examples/vga/main.c Sat Nov 10 17:03:17 2018 +0100
1.2 +++ b/examples/vga/main.c Sat Nov 10 17:58:49 2018 +0100
1.3 @@ -116,30 +116,43 @@
1.4
1.5 /* Copy to the store from the display, then blit the image. */
1.6
1.7 -static void plot_sprite(stored_region_t *r, int x, int y, int key)
1.8 +static void plot_sprite(stored_regions_t *r, int x, int y, int key)
1.9 {
1.10 - display_copy(&display_config, r->image,
1.11 + int frame = display_config.frame;
1.12 + position_t *p = image_get_stored_position(r, frame);
1.13 +
1.14 + /* Copy to the stored region. */
1.15 +
1.16 + display_copy(&display_config, image_get_stored_region(r, frame),
1.17 sprite.width, sprite.height / SOURCE_YSTEP, 1,
1.18 x, y, -1, 0);
1.19 +
1.20 + /* Plot to the screen. */
1.21 +
1.22 display_copy(&display_config, sprite.image,
1.23 sprite.width, sprite.height, SOURCE_YSTEP,
1.24 x, y, key, 1);
1.25
1.26 - /* Record the stored background. */
1.27 + /* Record the stored background details. */
1.28
1.29 - r->x = x;
1.30 - r->y = y;
1.31 - r->stored = 1;
1.32 + p->x = x;
1.33 + p->y = y;
1.34 +
1.35 + if (frame >= r->stored)
1.36 + r->stored = frame + 1;
1.37 }
1.38
1.39 /* Copy to the display from the store, restoring the original background. */
1.40
1.41 -static void unplot_sprite(stored_region_t *r)
1.42 +static void unplot_sprite(stored_regions_t *r)
1.43 {
1.44 - if (r->stored)
1.45 - display_copy(&display_config, r->image,
1.46 + int frame = display_config.frame;
1.47 + position_t *p = image_get_stored_position(r, frame);
1.48 +
1.49 + if (r->stored > frame)
1.50 + display_copy(&display_config, image_get_stored_region(r, frame),
1.51 sprite.width, sprite.height / SOURCE_YSTEP, 1,
1.52 - r->x, r->y, -1, 1);
1.53 + p->x, p->y, -1, 1);
1.54 }
1.55
1.56 /* Plot the revealed region at the edge of the screen after scrolling. */
1.57 @@ -219,8 +232,7 @@
1.58 {
1.59 /* Stores of background details, replotted when moving the sprite. */
1.60
1.61 - uint8_t backgrounds[FRAME_COUNT][(sprite.width * sprite.height) / SOURCE_YSTEP];
1.62 - stored_region_t regions[FRAME_COUNT];
1.63 + Stored_Regions(regions, FRAME_COUNT, (sprite.width * sprite.height) / SOURCE_YSTEP);
1.64
1.65 /* Sprite position. */
1.66
1.67 @@ -244,9 +256,6 @@
1.68 init_viewport(&v, &display_config, xorigins, yorigins,
1.69 SCROLL_XSTEP, SOURCE_YSTEP, plot_screen_edge);
1.70
1.71 - init_stored_regions(regions, display_config.frames, (uint8_t *) backgrounds,
1.72 - (sprite.width * sprite.height) / SOURCE_YSTEP);
1.73 -
1.74 /* Animation loop. */
1.75
1.76 while (1)
1.77 @@ -255,7 +264,7 @@
1.78 {
1.79 for (x = 0; x < display_config.line_length - sprite.width; x++)
1.80 {
1.81 - plot_sprite(®ions[display_config.frame], x, y, 0x8c);
1.82 + plot_sprite(®ions, x, y, 0x8c);
1.83
1.84 /* Update the display with the frame details. */
1.85
1.86 @@ -268,7 +277,7 @@
1.87
1.88 /* Prepare the frame for updates. */
1.89
1.90 - unplot_sprite(®ions[display_config.frame]);
1.91 + unplot_sprite(®ions);
1.92
1.93 /* Scroll in the indicated direction. */
1.94
2.1 --- a/include/image.h Sat Nov 10 17:03:17 2018 +0100
2.2 +++ b/include/image.h Sat Nov 10 17:58:49 2018 +0100
2.3 @@ -38,26 +38,52 @@
2.4
2.5 } image_t;
2.6
2.7 +
2.8 +
2.9 /* Stored display regions. */
2.10
2.11 typedef struct
2.12 {
2.13 + /* Position of the stored region on the screen. */
2.14 +
2.15 + int x, y;
2.16 +
2.17 +} position_t;
2.18 +
2.19 +typedef struct
2.20 +{
2.21 /* Stored region overplotted by the sprite. */
2.22
2.23 uint8_t *image;
2.24 + uint32_t size;
2.25 +
2.26 + /* Number of stored frames. */
2.27 +
2.28 int stored;
2.29
2.30 - /* Position of the stored region. */
2.31 + /* Stored region positions. */
2.32
2.33 - int x, y;
2.34 + position_t *pos;
2.35
2.36 -} stored_region_t;
2.37 +} stored_regions_t;
2.38
2.39
2.40
2.41 -/* Initialise the stored regions. */
2.42 +/* Initialise stored regions, allocating memory and a structure to access it. */
2.43
2.44 -void init_stored_regions(stored_region_t *r, int frames,
2.45 - uint8_t *regions, uint32_t region_size);
2.46 +#define Stored_Regions(NAME, FRAMES, SIZE) \
2.47 + uint8_t __##NAME##_image[FRAMES * SIZE]; \
2.48 + position_t __##NAME##_pos[FRAMES]; \
2.49 + stored_regions_t NAME = { \
2.50 + .image=__##NAME##_image, \
2.51 + .size=SIZE, \
2.52 + .stored=0, \
2.53 + .pos=__##NAME##_pos};
2.54 +
2.55 +/* Access functions. */
2.56 +
2.57 +position_t *image_get_stored_position(stored_regions_t *r, int frame);
2.58 +
2.59 +uint8_t *image_get_stored_region(stored_regions_t *r, int frame);
2.60
2.61 #endif /* __IMAGE_H__ */
3.1 --- a/lib/image.c Sat Nov 10 17:03:17 2018 +0100
3.2 +++ b/lib/image.c Sat Nov 10 17:58:49 2018 +0100
3.3 @@ -21,16 +21,16 @@
3.4
3.5
3.6
3.7 -void init_stored_regions(stored_region_t *r, int frames,
3.8 - uint8_t *regions, uint32_t region_size)
3.9 +/* Obtain the position for the stored region from the given frame. */
3.10 +
3.11 +position_t *image_get_stored_position(stored_regions_t *r, int frame)
3.12 {
3.13 - int frame;
3.14 + return &r->pos[frame];
3.15 +}
3.16
3.17 - for (frame = 0; frame < frames; frame++)
3.18 - {
3.19 - r->stored = 0;
3.20 - r->image = regions;
3.21 - regions += region_size;
3.22 - r++;
3.23 - }
3.24 +/* Obtain the image data for the stored region from the given frame. */
3.25 +
3.26 +uint8_t *image_get_stored_region(stored_regions_t *r, int frame)
3.27 +{
3.28 + return r->image + r->size * frame;
3.29 }