1.1 --- a/include/display.h Sun Nov 04 15:46:13 2018 +0100
1.2 +++ b/include/display.h Sun Nov 04 16:14:58 2018 +0100
1.3 @@ -115,4 +115,10 @@
1.4
1.5 void scroll_display(display_config_t *cfg, int x, int y);
1.6
1.7 +/* Address-related functions. */
1.8 +
1.9 +uint8_t *wrap_pointer(uint8_t *ptr, uint8_t *lower, uint8_t *upper);
1.10 +
1.11 +uint8_t *wrap_screen_pointer(display_config_t *cfg, uint8_t *ptr);
1.12 +
1.13 #endif /* __DISPLAY_H__ */
2.1 --- a/lib/display.c Sun Nov 04 15:46:13 2018 +0100
2.2 +++ b/lib/display.c Sun Nov 04 16:14:58 2018 +0100
2.3 @@ -147,10 +147,7 @@
2.4 0x00;
2.5 }
2.6
2.7 - linedata += cfg->line_length;
2.8 -
2.9 - if (linedata >= cfg->screen_limit)
2.10 - linedata -= cfg->screen_size;
2.11 + linedata = wrap_screen_pointer(cfg, linedata + cfg->line_length);
2.12 }
2.13 }
2.14
2.15 @@ -172,7 +169,7 @@
2.16 {
2.17 int sx, sy, dx, dy;
2.18 uint8_t *storeline = store + ystart * width,
2.19 - *displayline = cfg->screen_start + y * cfg->line_length,
2.20 + *displayline = wrap_screen_pointer(cfg, cfg->screen_start + y * cfg->line_length),
2.21 pixel;
2.22
2.23 /* Define the limits of the copying in the store. */
2.24 @@ -189,9 +186,6 @@
2.25
2.26 for (sy = ystart, dy = y; (sy < ylimit) && (dy < cfg->line_count); sy++, dy++)
2.27 {
2.28 - if (displayline >= cfg->screen_limit)
2.29 - displayline -= cfg->screen_size;
2.30 -
2.31 for (sx = xstart, dx = x; (sx < xlimit) && (dx < cfg->line_length); sx++, dx++)
2.32 {
2.33 if (to_display)
2.34 @@ -205,7 +199,7 @@
2.35 }
2.36
2.37 storeline += width;
2.38 - displayline += cfg->line_length;
2.39 + displayline = wrap_screen_pointer(cfg, displayline + cfg->line_length);
2.40 }
2.41 }
2.42
2.43 @@ -213,21 +207,30 @@
2.44
2.45 void scroll_display(display_config_t *cfg, int x, int y)
2.46 {
2.47 - uint8_t *start;
2.48 -
2.49 - /* Move the screen start by the given number of bytes and lines. */
2.50 + /* Move the screen start by the given number of bytes and lines, wrapping
2.51 + around the start and end of the framebuffer. */
2.52
2.53 - start = cfg->screen_start + x + y * cfg->line_length;
2.54 + cfg->screen_start = wrap_screen_pointer(cfg, cfg->screen_start + x +
2.55 + y * cfg->line_length);
2.56 +}
2.57
2.58 - /* Wrap around the start of the framebuffer to the end. */
2.59 +/* Wrap a pointer within the given limits. */
2.60 +
2.61 +uint8_t *wrap_pointer(uint8_t *ptr, uint8_t *lower, uint8_t *upper)
2.62 +{
2.63 + uint32_t size = upper - lower;
2.64
2.65 - if (start < cfg->frame_start)
2.66 - start = cfg->screen_limit - (cfg->frame_start - start) % cfg->screen_size;
2.67 -
2.68 - /* Wrap around the end of the framebuffer to the start. */
2.69 + if (ptr < lower)
2.70 + return upper - (lower - ptr) % size;
2.71 + else if (ptr >= upper)
2.72 + return lower + (ptr - upper) % size;
2.73 + else
2.74 + return ptr;
2.75 +}
2.76
2.77 - else if (start >= cfg->screen_limit)
2.78 - start = cfg->frame_start + (start - cfg->screen_limit) % cfg->screen_size;
2.79 +/* Wrap the screen pointer to the current frame. */
2.80
2.81 - cfg->screen_start = start;
2.82 +uint8_t *wrap_screen_pointer(display_config_t *cfg, uint8_t *ptr)
2.83 +{
2.84 + return wrap_pointer(ptr, cfg->frame_start, cfg->screen_limit);
2.85 }