# HG changeset patch # User Paul Boddie # Date 1541869129 -3600 # Node ID 005f2f8e6a61464615bc3577e3ae74307ac8ef1f # Parent db91935dc4a635a070faf72a6d1580385f8d742e Replaced the individual stored region abstraction with a collection abstraction, permitting more convenient initialisation and introducing functions to obtain image data and region positions. The storage state of regions is now managed by a single counter of stored frames rather than a flag per frame. diff -r db91935dc4a6 -r 005f2f8e6a61 examples/vga/main.c --- a/examples/vga/main.c Sat Nov 10 17:03:17 2018 +0100 +++ b/examples/vga/main.c Sat Nov 10 17:58:49 2018 +0100 @@ -116,30 +116,43 @@ /* Copy to the store from the display, then blit the image. */ -static void plot_sprite(stored_region_t *r, int x, int y, int key) +static void plot_sprite(stored_regions_t *r, int x, int y, int key) { - display_copy(&display_config, r->image, + int frame = display_config.frame; + position_t *p = image_get_stored_position(r, frame); + + /* Copy to the stored region. */ + + display_copy(&display_config, image_get_stored_region(r, frame), sprite.width, sprite.height / SOURCE_YSTEP, 1, x, y, -1, 0); + + /* Plot to the screen. */ + display_copy(&display_config, sprite.image, sprite.width, sprite.height, SOURCE_YSTEP, x, y, key, 1); - /* Record the stored background. */ + /* Record the stored background details. */ - r->x = x; - r->y = y; - r->stored = 1; + p->x = x; + p->y = y; + + if (frame >= r->stored) + r->stored = frame + 1; } /* Copy to the display from the store, restoring the original background. */ -static void unplot_sprite(stored_region_t *r) +static void unplot_sprite(stored_regions_t *r) { - if (r->stored) - display_copy(&display_config, r->image, + int frame = display_config.frame; + position_t *p = image_get_stored_position(r, frame); + + if (r->stored > frame) + display_copy(&display_config, image_get_stored_region(r, frame), sprite.width, sprite.height / SOURCE_YSTEP, 1, - r->x, r->y, -1, 1); + p->x, p->y, -1, 1); } /* Plot the revealed region at the edge of the screen after scrolling. */ @@ -219,8 +232,7 @@ { /* Stores of background details, replotted when moving the sprite. */ - uint8_t backgrounds[FRAME_COUNT][(sprite.width * sprite.height) / SOURCE_YSTEP]; - stored_region_t regions[FRAME_COUNT]; + Stored_Regions(regions, FRAME_COUNT, (sprite.width * sprite.height) / SOURCE_YSTEP); /* Sprite position. */ @@ -244,9 +256,6 @@ init_viewport(&v, &display_config, xorigins, yorigins, SCROLL_XSTEP, SOURCE_YSTEP, plot_screen_edge); - init_stored_regions(regions, display_config.frames, (uint8_t *) backgrounds, - (sprite.width * sprite.height) / SOURCE_YSTEP); - /* Animation loop. */ while (1) @@ -255,7 +264,7 @@ { for (x = 0; x < display_config.line_length - sprite.width; x++) { - plot_sprite(®ions[display_config.frame], x, y, 0x8c); + plot_sprite(®ions, x, y, 0x8c); /* Update the display with the frame details. */ @@ -268,7 +277,7 @@ /* Prepare the frame for updates. */ - unplot_sprite(®ions[display_config.frame]); + unplot_sprite(®ions); /* Scroll in the indicated direction. */ diff -r db91935dc4a6 -r 005f2f8e6a61 include/image.h --- a/include/image.h Sat Nov 10 17:03:17 2018 +0100 +++ b/include/image.h Sat Nov 10 17:58:49 2018 +0100 @@ -38,26 +38,52 @@ } image_t; + + /* Stored display regions. */ typedef struct { + /* Position of the stored region on the screen. */ + + int x, y; + +} position_t; + +typedef struct +{ /* Stored region overplotted by the sprite. */ uint8_t *image; + uint32_t size; + + /* Number of stored frames. */ + int stored; - /* Position of the stored region. */ + /* Stored region positions. */ - int x, y; + position_t *pos; -} stored_region_t; +} stored_regions_t; -/* Initialise the stored regions. */ +/* Initialise stored regions, allocating memory and a structure to access it. */ -void init_stored_regions(stored_region_t *r, int frames, - uint8_t *regions, uint32_t region_size); +#define Stored_Regions(NAME, FRAMES, SIZE) \ + uint8_t __##NAME##_image[FRAMES * SIZE]; \ + position_t __##NAME##_pos[FRAMES]; \ + stored_regions_t NAME = { \ + .image=__##NAME##_image, \ + .size=SIZE, \ + .stored=0, \ + .pos=__##NAME##_pos}; + +/* Access functions. */ + +position_t *image_get_stored_position(stored_regions_t *r, int frame); + +uint8_t *image_get_stored_region(stored_regions_t *r, int frame); #endif /* __IMAGE_H__ */ diff -r db91935dc4a6 -r 005f2f8e6a61 lib/image.c --- a/lib/image.c Sat Nov 10 17:03:17 2018 +0100 +++ b/lib/image.c Sat Nov 10 17:58:49 2018 +0100 @@ -21,16 +21,16 @@ -void init_stored_regions(stored_region_t *r, int frames, - uint8_t *regions, uint32_t region_size) +/* Obtain the position for the stored region from the given frame. */ + +position_t *image_get_stored_position(stored_regions_t *r, int frame) { - int frame; + return &r->pos[frame]; +} - for (frame = 0; frame < frames; frame++) - { - r->stored = 0; - r->image = regions; - regions += region_size; - r++; - } +/* Obtain the image data for the stored region from the given frame. */ + +uint8_t *image_get_stored_region(stored_regions_t *r, int frame) +{ + return r->image + r->size * frame; }