1.1 --- a/examples/vga/main.c Sun Nov 04 18:13:06 2018 +0100
1.2 +++ b/examples/vga/main.c Sun Nov 04 20:45:02 2018 +0100
1.3 @@ -225,7 +225,16 @@
1.4 {
1.5 /* Stored region behind the sprite. */
1.6
1.7 - uint8_t background[(sprite_width * sprite_height) / SOURCE_YSTEP];
1.8 + uint8_t background[FRAME_COUNT][(sprite_width * sprite_height) / SOURCE_YSTEP];
1.9 +
1.10 + /* Positions of the stored regions for each frame. */
1.11 +
1.12 + int background_x[FRAME_COUNT], background_y[FRAME_COUNT];
1.13 + int background_stored[FRAME_COUNT];
1.14 +
1.15 + /* Screen start values for each frame. */
1.16 +
1.17 + uint32_t frame_offset[FRAME_COUNT];
1.18
1.19 /* Sprite position. */
1.20
1.21 @@ -240,58 +249,107 @@
1.22
1.23 int xorigin = 0, yorigin = 0;
1.24
1.25 + /* Scrolling positions for each frame. */
1.26 +
1.27 + int xorigins[FRAME_COUNT], yorigins[FRAME_COUNT];
1.28 +
1.29 /* Scroll increments and replotted column details. */
1.30
1.31 - int xdir, ydir, xstep;
1.32 + int xdir, ydir, xstep, ystep;
1.33 +
1.34 + /* Current frame being accessed. */
1.35 +
1.36 + int frame;
1.37 +
1.38 + for (frame = 0; frame < display_config.frames; frame++)
1.39 + {
1.40 + background_stored[frame] = 0;
1.41 + frame_offset[frame] = 0;
1.42 + xorigins[frame] = xorigin;
1.43 + yorigins[frame] = yorigin;
1.44 + }
1.45 +
1.46 + frame = display_config.frame;
1.47 +
1.48 + /* Animation loop. */
1.49
1.50 while (1)
1.51 {
1.52 - for (y = 0; y < screendata_height - sprite_height; y++)
1.53 + for (y = 0; y < display_config.line_count - sprite_height; y++)
1.54 {
1.55 - for (x = 0; x < screendata_width - sprite_width; x++)
1.56 + for (x = 0; x < display_config.line_length - sprite_width; x++)
1.57 {
1.58 - plot_sprite(background, x, y);
1.59 + plot_sprite(background[frame], x, y);
1.60 +
1.61 + /* Record the stored background. */
1.62 +
1.63 + background_x[frame] = x;
1.64 + background_y[frame] = y;
1.65 + background_stored[frame] = 1;
1.66
1.67 /* Update the display with the frame details. */
1.68
1.69 vga_set_frame(&display_config);
1.70 wait(delay);
1.71
1.72 - unplot_sprite(background, x, y);
1.73 + /* Select the next frame to plot to. */
1.74 +
1.75 + frame = wrap_value(frame + 1, display_config.frames);
1.76 + select_frame(&display_config, frame, frame_offset[frame]);
1.77 +
1.78 + /* Prepare the frame for updates. */
1.79 +
1.80 + if (background_stored[frame])
1.81 + unplot_sprite(background[frame], background_x[frame], background_y[frame]);
1.82
1.83 /* Scroll in the indicated direction. */
1.84
1.85 xdir = dir[dirindex];
1.86 ydir = dir[dirindex + 1];
1.87
1.88 - scroll_display(&display_config, xdir, ydir);
1.89 + /* Update the origin if appropriate. */
1.90
1.91 - /* Update the vertical origin if appropriate. */
1.92 + /* Due to the effect of a simple screen start increment in the
1.93 + dual channel configuration, horizontal scrolling involves two
1.94 + pixel increments and thus requires a two-pixel column to be
1.95 + plotted. */
1.96 +
1.97 + if (xdir)
1.98 + xorigin += xdir * SCROLL_XSTEP;
1.99
1.100 if (ydir)
1.101 - yorigin = wrap_value(yorigin + ydir * SOURCE_YSTEP,
1.102 - screendata_height);
1.103 + yorigin += ydir * SOURCE_YSTEP;
1.104 +
1.105 + /* Determine the magnitude of the scrolling required from this
1.106 + frame to the current origin. */
1.107 +
1.108 + xstep = xorigin - xorigins[frame];
1.109 + ystep = yorigin - yorigins[frame];
1.110 +
1.111 + /* Scroll the frame. */
1.112 +
1.113 + scroll_display(&display_config, xstep / SCROLL_XSTEP,
1.114 + ystep / SOURCE_YSTEP);
1.115 +
1.116 + /* Record the new screen start offset. */
1.117 +
1.118 + frame_offset[frame] = get_start_offset(&display_config);
1.119 +
1.120 + /* Update the current origin. */
1.121 +
1.122 + xorigin = wrap_value(xorigin, screendata_width);
1.123 + yorigin = wrap_value(yorigin, screendata_height);
1.124
1.125 /* For horizontal scrolling, plot the exposed column at the left
1.126 (if scrolling left) or at the right (if scrolling right). */
1.127
1.128 - if (xdir)
1.129 - {
1.130 - /* Due to the effect of a simple screen start increment in
1.131 - the dual channel configuration, horizontal scrolling
1.132 - involves two pixel increments and thus requires a two-
1.133 - pixel column to be plotted. */
1.134 -
1.135 - xstep = xdir * SCROLL_XSTEP;
1.136 + if (xstep)
1.137 + plot_screen_edge(xorigin, yorigin, xstep);
1.138
1.139 - /* Determine the location of the column to be plotted. */
1.140 -
1.141 - xorigin = wrap_value(xorigin + xstep, screendata_width);
1.142 + /* Record the origin for this frame. */
1.143
1.144 - /* Plot either at the left or right edge. */
1.145 -
1.146 - plot_screen_edge(xorigin, yorigin, xstep);
1.147 - }
1.148 + xorigins[frame] = xorigin;
1.149 + yorigins[frame] = yorigin;
1.150 }
1.151
1.152 /* Switch direction periodically. */