1.1 --- a/examples/vga/main.c Sat Nov 10 17:58:49 2018 +0100
1.2 +++ b/examples/vga/main.c Sat Nov 10 18:53:06 2018 +0100
1.3 @@ -116,21 +116,21 @@
1.4
1.5 /* Copy to the store from the display, then blit the image. */
1.6
1.7 -static void plot_sprite(stored_regions_t *r, int x, int y, int key)
1.8 +static void plot_sprite(sprite_t *s, int x, int y, int key)
1.9 {
1.10 int frame = display_config.frame;
1.11 - position_t *p = image_get_stored_position(r, frame);
1.12 + position_t *p = image_get_stored_position(s->regions, 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 + display_copy(&display_config, image_get_stored_region(s->regions, frame),
1.19 + s->image->width, s->image->height / s->yscale, 1,
1.20 x, y, -1, 0);
1.21
1.22 /* Plot to the screen. */
1.23
1.24 - display_copy(&display_config, sprite.image,
1.25 - sprite.width, sprite.height, SOURCE_YSTEP,
1.26 + display_copy(&display_config, s->image->image,
1.27 + s->image->width, s->image->height, s->yscale,
1.28 x, y, key, 1);
1.29
1.30 /* Record the stored background details. */
1.31 @@ -138,20 +138,20 @@
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 + if (frame >= s->regions->stored)
1.38 + s->regions->stored = frame + 1;
1.39 }
1.40
1.41 /* Copy to the display from the store, restoring the original background. */
1.42
1.43 -static void unplot_sprite(stored_regions_t *r)
1.44 +static void unplot_sprite(sprite_t *s)
1.45 {
1.46 int frame = display_config.frame;
1.47 - position_t *p = image_get_stored_position(r, frame);
1.48 + position_t *p = image_get_stored_position(s->regions, frame);
1.49
1.50 - if (r->stored > frame)
1.51 - display_copy(&display_config, image_get_stored_region(r, frame),
1.52 - sprite.width, sprite.height / SOURCE_YSTEP, 1,
1.53 + if (s->regions->stored > frame)
1.54 + display_copy(&display_config, image_get_stored_region(s->regions, frame),
1.55 + s->image->width, s->image->height / s->yscale, 1,
1.56 p->x, p->y, -1, 1);
1.57 }
1.58
1.59 @@ -232,7 +232,7 @@
1.60 {
1.61 /* Stores of background details, replotted when moving the sprite. */
1.62
1.63 - Stored_Regions(regions, FRAME_COUNT, (sprite.width * sprite.height) / SOURCE_YSTEP);
1.64 + Sprite(s, &sprite, FRAME_COUNT, SOURCE_YSTEP);
1.65
1.66 /* Sprite position. */
1.67
1.68 @@ -260,11 +260,11 @@
1.69
1.70 while (1)
1.71 {
1.72 - for (y = 0; y < display_config.line_count - sprite.height; y++)
1.73 + for (y = 0; y < display_config.line_count - s.image->height; y++)
1.74 {
1.75 - for (x = 0; x < display_config.line_length - sprite.width; x++)
1.76 + for (x = 0; x < display_config.line_length - s.image->width; x++)
1.77 {
1.78 - plot_sprite(®ions, x, y, 0x8c);
1.79 + plot_sprite(&s, x, y, 0x8c);
1.80
1.81 /* Update the display with the frame details. */
1.82
1.83 @@ -277,7 +277,7 @@
1.84
1.85 /* Prepare the frame for updates. */
1.86
1.87 - unplot_sprite(®ions);
1.88 + unplot_sprite(&s);
1.89
1.90 /* Scroll in the indicated direction. */
1.91
2.1 --- a/include/image.h Sat Nov 10 17:58:49 2018 +0100
2.2 +++ b/include/image.h Sat Nov 10 18:53:06 2018 +0100
2.3 @@ -69,15 +69,39 @@
2.4
2.5
2.6
2.7 -/* Initialise stored regions, allocating memory and a structure to access it. */
2.8 +/* A simple sprite abstraction. */
2.9 +
2.10 +typedef struct
2.11 +{
2.12 + /* The sprite image. */
2.13 +
2.14 + image_t *image;
2.15 +
2.16 + /* The stored regions to be used to unplot the sprite. */
2.17 +
2.18 + stored_regions_t *regions;
2.19 +
2.20 + /* The vertical scaling factor translating display rows to image
2.21 + coordinates. */
2.22 +
2.23 + int yscale;
2.24
2.25 -#define Stored_Regions(NAME, FRAMES, SIZE) \
2.26 - uint8_t __##NAME##_image[FRAMES * SIZE]; \
2.27 - position_t __##NAME##_pos[FRAMES]; \
2.28 - stored_regions_t NAME = { \
2.29 - .image=__##NAME##_image, \
2.30 - .size=SIZE, \
2.31 - .stored=0, \
2.32 +} sprite_t;
2.33 +
2.34 +
2.35 +
2.36 +/* Initialise stored regions, allocating memory and a structure to access it.
2.37 +
2.38 + Stored_Regions(<name>, int, int)
2.39 +*/
2.40 +
2.41 +#define Stored_Regions(NAME, FRAMES, SIZE) \
2.42 + uint8_t __##NAME##_image[(FRAMES) * (SIZE)]; \
2.43 + position_t __##NAME##_pos[FRAMES]; \
2.44 + stored_regions_t NAME = { \
2.45 + .image=__##NAME##_image, \
2.46 + .size=SIZE, \
2.47 + .stored=0, \
2.48 .pos=__##NAME##_pos};
2.49
2.50 /* Access functions. */
2.51 @@ -86,4 +110,20 @@
2.52
2.53 uint8_t *image_get_stored_region(stored_regions_t *r, int frame);
2.54
2.55 +
2.56 +
2.57 +/* Initialise a sprite object using an existing image, creating stored regions
2.58 + for the animation of the sprite.
2.59 +
2.60 + Sprite(<name>, image_t *, int, int)
2.61 +*/
2.62 +
2.63 +#define Sprite(NAME, IMAGE, FRAMES, YSCALE) \
2.64 + Stored_Regions(__##NAME##_regions, FRAMES, \
2.65 + (IMAGE)->width * (IMAGE)->height * (YSCALE)); \
2.66 + sprite_t NAME = { \
2.67 + .image=IMAGE, \
2.68 + .regions=&(__##NAME##_regions), \
2.69 + .yscale=YSCALE};
2.70 +
2.71 #endif /* __IMAGE_H__ */