# HG changeset patch # User Paul Boddie # Date 1541344498 -3600 # Node ID 6d95b67997e657cdb4473d13ebffa2c4d83ea40c # Parent 9d30c6982e8d975ae4a35da8f59c67745f7ae084 Introduced various pointer address wrapping functions. diff -r 9d30c6982e8d -r 6d95b67997e6 include/display.h --- a/include/display.h Sun Nov 04 15:46:13 2018 +0100 +++ b/include/display.h Sun Nov 04 16:14:58 2018 +0100 @@ -115,4 +115,10 @@ void scroll_display(display_config_t *cfg, int x, int y); +/* Address-related functions. */ + +uint8_t *wrap_pointer(uint8_t *ptr, uint8_t *lower, uint8_t *upper); + +uint8_t *wrap_screen_pointer(display_config_t *cfg, uint8_t *ptr); + #endif /* __DISPLAY_H__ */ diff -r 9d30c6982e8d -r 6d95b67997e6 lib/display.c --- a/lib/display.c Sun Nov 04 15:46:13 2018 +0100 +++ b/lib/display.c Sun Nov 04 16:14:58 2018 +0100 @@ -147,10 +147,7 @@ 0x00; } - linedata += cfg->line_length; - - if (linedata >= cfg->screen_limit) - linedata -= cfg->screen_size; + linedata = wrap_screen_pointer(cfg, linedata + cfg->line_length); } } @@ -172,7 +169,7 @@ { int sx, sy, dx, dy; uint8_t *storeline = store + ystart * width, - *displayline = cfg->screen_start + y * cfg->line_length, + *displayline = wrap_screen_pointer(cfg, cfg->screen_start + y * cfg->line_length), pixel; /* Define the limits of the copying in the store. */ @@ -189,9 +186,6 @@ for (sy = ystart, dy = y; (sy < ylimit) && (dy < cfg->line_count); sy++, dy++) { - if (displayline >= cfg->screen_limit) - displayline -= cfg->screen_size; - for (sx = xstart, dx = x; (sx < xlimit) && (dx < cfg->line_length); sx++, dx++) { if (to_display) @@ -205,7 +199,7 @@ } storeline += width; - displayline += cfg->line_length; + displayline = wrap_screen_pointer(cfg, displayline + cfg->line_length); } } @@ -213,21 +207,30 @@ void scroll_display(display_config_t *cfg, int x, int y) { - uint8_t *start; - - /* Move the screen start by the given number of bytes and lines. */ + /* Move the screen start by the given number of bytes and lines, wrapping + around the start and end of the framebuffer. */ - start = cfg->screen_start + x + y * cfg->line_length; + cfg->screen_start = wrap_screen_pointer(cfg, cfg->screen_start + x + + y * cfg->line_length); +} - /* Wrap around the start of the framebuffer to the end. */ +/* Wrap a pointer within the given limits. */ + +uint8_t *wrap_pointer(uint8_t *ptr, uint8_t *lower, uint8_t *upper) +{ + uint32_t size = upper - lower; - if (start < cfg->frame_start) - start = cfg->screen_limit - (cfg->frame_start - start) % cfg->screen_size; - - /* Wrap around the end of the framebuffer to the start. */ + if (ptr < lower) + return upper - (lower - ptr) % size; + else if (ptr >= upper) + return lower + (ptr - upper) % size; + else + return ptr; +} - else if (start >= cfg->screen_limit) - start = cfg->frame_start + (start - cfg->screen_limit) % cfg->screen_size; +/* Wrap the screen pointer to the current frame. */ - cfg->screen_start = start; +uint8_t *wrap_screen_pointer(display_config_t *cfg, uint8_t *ptr) +{ + return wrap_pointer(ptr, cfg->frame_start, cfg->screen_limit); }