# HG changeset patch # User Paul Boddie # Date 1541872386 -3600 # Node ID 56b5497336325b89da4405aac3affc5ac2240a48 # Parent 005f2f8e6a61464615bc3577e3ae74307ac8ef1f Introduced a sprite abstraction, bundling an image with stored display regions. diff -r 005f2f8e6a61 -r 56b549733632 examples/vga/main.c --- a/examples/vga/main.c Sat Nov 10 17:58:49 2018 +0100 +++ b/examples/vga/main.c Sat Nov 10 18:53:06 2018 +0100 @@ -116,21 +116,21 @@ /* Copy to the store from the display, then blit the image. */ -static void plot_sprite(stored_regions_t *r, int x, int y, int key) +static void plot_sprite(sprite_t *s, int x, int y, int key) { int frame = display_config.frame; - position_t *p = image_get_stored_position(r, frame); + position_t *p = image_get_stored_position(s->regions, frame); /* Copy to the stored region. */ - display_copy(&display_config, image_get_stored_region(r, frame), - sprite.width, sprite.height / SOURCE_YSTEP, 1, + display_copy(&display_config, image_get_stored_region(s->regions, frame), + s->image->width, s->image->height / s->yscale, 1, x, y, -1, 0); /* Plot to the screen. */ - display_copy(&display_config, sprite.image, - sprite.width, sprite.height, SOURCE_YSTEP, + display_copy(&display_config, s->image->image, + s->image->width, s->image->height, s->yscale, x, y, key, 1); /* Record the stored background details. */ @@ -138,20 +138,20 @@ p->x = x; p->y = y; - if (frame >= r->stored) - r->stored = frame + 1; + if (frame >= s->regions->stored) + s->regions->stored = frame + 1; } /* Copy to the display from the store, restoring the original background. */ -static void unplot_sprite(stored_regions_t *r) +static void unplot_sprite(sprite_t *s) { int frame = display_config.frame; - position_t *p = image_get_stored_position(r, frame); + position_t *p = image_get_stored_position(s->regions, frame); - if (r->stored > frame) - display_copy(&display_config, image_get_stored_region(r, frame), - sprite.width, sprite.height / SOURCE_YSTEP, 1, + if (s->regions->stored > frame) + display_copy(&display_config, image_get_stored_region(s->regions, frame), + s->image->width, s->image->height / s->yscale, 1, p->x, p->y, -1, 1); } @@ -232,7 +232,7 @@ { /* Stores of background details, replotted when moving the sprite. */ - Stored_Regions(regions, FRAME_COUNT, (sprite.width * sprite.height) / SOURCE_YSTEP); + Sprite(s, &sprite, FRAME_COUNT, SOURCE_YSTEP); /* Sprite position. */ @@ -260,11 +260,11 @@ while (1) { - for (y = 0; y < display_config.line_count - sprite.height; y++) + for (y = 0; y < display_config.line_count - s.image->height; y++) { - for (x = 0; x < display_config.line_length - sprite.width; x++) + for (x = 0; x < display_config.line_length - s.image->width; x++) { - plot_sprite(®ions, x, y, 0x8c); + plot_sprite(&s, x, y, 0x8c); /* Update the display with the frame details. */ @@ -277,7 +277,7 @@ /* Prepare the frame for updates. */ - unplot_sprite(®ions); + unplot_sprite(&s); /* Scroll in the indicated direction. */ diff -r 005f2f8e6a61 -r 56b549733632 include/image.h --- a/include/image.h Sat Nov 10 17:58:49 2018 +0100 +++ b/include/image.h Sat Nov 10 18:53:06 2018 +0100 @@ -69,15 +69,39 @@ -/* Initialise stored regions, allocating memory and a structure to access it. */ +/* A simple sprite abstraction. */ + +typedef struct +{ + /* The sprite image. */ + + image_t *image; + + /* The stored regions to be used to unplot the sprite. */ + + stored_regions_t *regions; + + /* The vertical scaling factor translating display rows to image + coordinates. */ + + int yscale; -#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, \ +} sprite_t; + + + +/* Initialise stored regions, allocating memory and a structure to access it. + + Stored_Regions(, int, int) +*/ + +#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. */ @@ -86,4 +110,20 @@ uint8_t *image_get_stored_region(stored_regions_t *r, int frame); + + +/* Initialise a sprite object using an existing image, creating stored regions + for the animation of the sprite. + + Sprite(, image_t *, int, int) +*/ + +#define Sprite(NAME, IMAGE, FRAMES, YSCALE) \ + Stored_Regions(__##NAME##_regions, FRAMES, \ + (IMAGE)->width * (IMAGE)->height * (YSCALE)); \ + sprite_t NAME = { \ + .image=IMAGE, \ + .regions=&(__##NAME##_regions), \ + .yscale=YSCALE}; + #endif /* __IMAGE_H__ */