CommonPIC32

Changeset

115:bfe765ff97e0
2018-11-09 Paul Boddie raw files shortlog changelog graph Introduced screen start address retention for each frame in the display library.
examples/vga/main.c (file) include/display.h (file) lib/display.c (file)
     1.1 --- a/examples/vga/main.c	Fri Nov 09 21:04:23 2018 +0100
     1.2 +++ b/examples/vga/main.c	Fri Nov 09 21:05:06 2018 +0100
     1.3 @@ -89,6 +89,10 @@
     1.4  
     1.5  static uint8_t framebuffer[FRAME_SIZE * FRAME_COUNT];
     1.6  
     1.7 +/* Screen start values for each frame. */
     1.8 +
     1.9 +uint8_t *screen_starts[FRAME_COUNT];
    1.10 +
    1.11  
    1.12  
    1.13  /* Bundled image and font data. */
    1.14 @@ -210,10 +214,6 @@
    1.15      int background_x[FRAME_COUNT], background_y[FRAME_COUNT];
    1.16      int background_stored[FRAME_COUNT];
    1.17  
    1.18 -    /* Screen start values for each frame. */
    1.19 -
    1.20 -    uint32_t frame_offset[FRAME_COUNT];
    1.21 -
    1.22      /* Sprite position. */
    1.23  
    1.24      int x, y;
    1.25 @@ -242,7 +242,6 @@
    1.26      for (frame = 0; frame < display_config.frames; frame++)
    1.27      {
    1.28          background_stored[frame] = 0;
    1.29 -        frame_offset[frame] = 0;
    1.30          xorigins[frame] = xorigin;
    1.31          yorigins[frame] = yorigin;
    1.32      }
    1.33 @@ -273,7 +272,7 @@
    1.34                  /* Select the next frame to plot to. */
    1.35  
    1.36                  frame = wrap_value(frame + 1, display_config.frames);
    1.37 -                display_select_frame(&display_config, frame, frame_offset[frame]);
    1.38 +                display_select_frame(&display_config, frame);
    1.39  
    1.40                  /* Prepare the frame for updates. */
    1.41  
    1.42 @@ -312,10 +311,6 @@
    1.43                  display_scroll(&display_config, xstep / SCROLL_XSTEP,
    1.44                                                  ystep / SOURCE_YSTEP);
    1.45  
    1.46 -                /* Record the new screen start offset. */
    1.47 -
    1.48 -                frame_offset[frame] = display_get_start_offset(&display_config);
    1.49 -
    1.50                  /* For horizontal scrolling, plot the exposed column at the left
    1.51                     (if scrolling left) or at the right (if scrolling right). */
    1.52  
    1.53 @@ -372,7 +367,7 @@
    1.54      {
    1.55          /* Obtain the frame. */
    1.56  
    1.57 -        display_select_frame(&display_config, frame, 0);
    1.58 +        display_select_frame(&display_config, frame);
    1.59  
    1.60          /* Plot the image centred on the screen. */
    1.61  
    1.62 @@ -388,7 +383,7 @@
    1.63          write_chars();
    1.64      }
    1.65  
    1.66 -    display_select_frame(&display_config, 0, 0);
    1.67 +    display_select_frame(&display_config, 0);
    1.68  }
    1.69  
    1.70  
    1.71 @@ -425,7 +420,8 @@
    1.72  
    1.73      /* Initialise memory for a double-buffered display. */
    1.74  
    1.75 -    init_display(&display_config, framebuffer, LINE_LENGTH, LINE_COUNT, FRAME_COUNT);
    1.76 +    init_display(&display_config, framebuffer, LINE_LENGTH, LINE_COUNT,
    1.77 +                 FRAME_COUNT, screen_starts);
    1.78  
    1.79      /* Initialise VGA output with one or two line channels, configuring a line
    1.80         timer and any transfer timer, with an initiating channel being introduced
     2.1 --- a/include/display.h	Fri Nov 09 21:04:23 2018 +0100
     2.2 +++ b/include/display.h	Fri Nov 09 21:05:06 2018 +0100
     2.3 @@ -54,6 +54,10 @@
     2.4  
     2.5      uint8_t *screen_start;              /* >= frame_start; < screen_limit */
     2.6  
     2.7 +    /* A pointer to a collection of screen start pointers, one per frame. */
     2.8 +
     2.9 +    uint8_t **screen_starts;
    2.10 +
    2.11      /* The fixed end address of the current frame. */
    2.12  
    2.13      uint8_t *screen_limit;              /* = frame_start + screen_size */
    2.14 @@ -93,14 +97,19 @@
    2.15  /* Configuration functions. */
    2.16  
    2.17  void init_display(display_config_t *cfg, uint8_t *framebuffer,
    2.18 -                  uint32_t line_length, uint32_t line_count, int frames);
    2.19 +                  uint32_t line_length, uint32_t line_count,
    2.20 +                  int frames, uint8_t **screen_starts);
    2.21  
    2.22 -void init_display_properties(display_config_t *cfg, uint32_t offset);
    2.23 +void init_display_properties(display_config_t *cfg);
    2.24  
    2.25 -void display_select_frame(display_config_t *cfg, int frame, uint32_t offset);
    2.26 +void init_frames(display_config_t *cfg);
    2.27 +
    2.28 +void display_select_frame(display_config_t *cfg, int frame);
    2.29  
    2.30  void display_set_frames(display_config_t *cfg, int frames);
    2.31  
    2.32 +uint8_t *display_get_frame_start(display_config_t *cfg, int frame);
    2.33 +
    2.34  uint32_t display_get_start_offset(display_config_t *cfg);
    2.35  
    2.36  /* Access functions. */
     3.1 --- a/lib/display.c	Fri Nov 09 21:04:23 2018 +0100
     3.2 +++ b/lib/display.c	Fri Nov 09 21:05:06 2018 +0100
     3.3 @@ -25,7 +25,8 @@
     3.4  /* Initialise a display configuration. */
     3.5  
     3.6  void init_display(display_config_t *cfg, uint8_t *framebuffer,
     3.7 -                  uint32_t line_length, uint32_t line_count, int frames)
     3.8 +                  uint32_t line_length, uint32_t line_count,
     3.9 +                  int frames, uint8_t **screen_starts)
    3.10  {
    3.11      /* Framebuffer address. */
    3.12  
    3.13 @@ -47,21 +48,32 @@
    3.14      cfg->frames = frames;
    3.15      cfg->frame = 0;
    3.16  
    3.17 -    init_display_properties(cfg, 0);
    3.18 +    /* Set the pointer to a collection of screen start pointers, one per
    3.19 +       frame. */
    3.20 +
    3.21 +    cfg->screen_starts = screen_starts;
    3.22 +
    3.23 +    init_frames(cfg);
    3.24 +    init_display_properties(cfg);
    3.25  }
    3.26  
    3.27  /* Initialise the display constraints. */
    3.28  
    3.29 -void init_display_properties(display_config_t *cfg, uint32_t offset)
    3.30 +void init_display_properties(display_config_t *cfg)
    3.31  {
    3.32      /* Fixed address of the frame. */
    3.33  
    3.34 -    cfg->frame_start = cfg->framebuffer +
    3.35 -                       (cfg->screen_size + cfg->line_length) * cfg->frame;
    3.36 +    cfg->frame_start = display_get_frame_start(cfg, cfg->frame);
    3.37  
    3.38      /* Floating address of the screen contents. */
    3.39  
    3.40 -    cfg->screen_start = cfg->frame_start + offset;
    3.41 +    if (cfg->screen_starts)
    3.42 +        cfg->screen_start = cfg->screen_starts[cfg->frame];
    3.43 +
    3.44 +    /* Without any way of recording the address, just reset the start. */
    3.45 +
    3.46 +    else
    3.47 +        cfg->screen_start = cfg->frame_start;
    3.48  
    3.49      /* Fixed limit of the frame. */
    3.50  
    3.51 @@ -72,22 +84,37 @@
    3.52      cfg->line_multiplier = cfg->scanlines / cfg->line_count;
    3.53  }
    3.54  
    3.55 +/* Initialise the screen start addresses for all frames. */
    3.56 +
    3.57 +void init_frames(display_config_t *cfg)
    3.58 +{
    3.59 +    int frame;
    3.60 +
    3.61 +    for (frame = 0; frame < cfg->frames; frame++)
    3.62 +        cfg->screen_starts[frame] = display_get_frame_start(cfg, frame);
    3.63 +}
    3.64 +
    3.65  
    3.66  
    3.67  /* Select a frame in the framebuffer. */
    3.68  
    3.69 -void display_select_frame(display_config_t *cfg, int frame, uint32_t offset)
    3.70 +void display_select_frame(display_config_t *cfg, int frame)
    3.71  {
    3.72      if ((frame < 0) || (frame >= cfg->frames))
    3.73          return;
    3.74  
    3.75 +    /* Store the current frame's screen start, if possible. */
    3.76 +
    3.77 +    if (cfg->screen_starts)
    3.78 +        cfg->screen_starts[cfg->frame] = cfg->screen_start;
    3.79 +
    3.80      /* Update the frame details. */
    3.81  
    3.82      cfg->frame = frame;
    3.83  
    3.84      /* Set the screen start offset when switching frames. */
    3.85  
    3.86 -    init_display_properties(cfg, offset);
    3.87 +    init_display_properties(cfg);
    3.88  }
    3.89  
    3.90  /* Set the number of frames in the framebuffer memory. */
    3.91 @@ -110,11 +137,19 @@
    3.92      cfg->frames = frames;
    3.93      cfg->frame = 0;
    3.94  
    3.95 -    init_display_properties(cfg, 0);
    3.96 +    init_frames(cfg);
    3.97 +    init_display_properties(cfg);
    3.98  }
    3.99  
   3.100  
   3.101  
   3.102 +/* Return the start address of the given frame. */
   3.103 +
   3.104 +uint8_t *display_get_frame_start(display_config_t *cfg, int frame)
   3.105 +{
   3.106 +    return cfg->framebuffer + (cfg->screen_size + cfg->line_length) * frame;
   3.107 +}
   3.108 +
   3.109  /* Return the line data position for the given pixel. */
   3.110  
   3.111  int display_get_position(display_config_t *cfg, int x)