1.1 --- a/lib/display.c Sat Nov 03 16:42:17 2018 +0100
1.2 +++ b/lib/display.c Sat Nov 03 21:47:40 2018 +0100
1.3 @@ -21,6 +21,99 @@
1.4
1.5
1.6
1.7 +/* Initialise a display configuration. */
1.8 +
1.9 +void init_display(display_config_t *cfg, uint8_t *framebuffer,
1.10 + uint32_t line_length, uint32_t line_count, int frames)
1.11 +{
1.12 + /* Framebuffer address. */
1.13 +
1.14 + cfg->framebuffer = framebuffer;
1.15 +
1.16 + /* Frame allocation limits. */
1.17 +
1.18 + cfg->total_lines = (line_count + 1) * frames;
1.19 + cfg->max_frames = frames;
1.20 +
1.21 + /* Screen size and dimensions. */
1.22 +
1.23 + cfg->screen_size = line_length * line_count;
1.24 + cfg->line_length = line_length;
1.25 + cfg->line_count = line_count;
1.26 +
1.27 + /* Set the number of frames and the current frame. */
1.28 +
1.29 + cfg->frames = frames;
1.30 + cfg->frame = 0;
1.31 +
1.32 + init_display_properties(cfg, 0);
1.33 +}
1.34 +
1.35 +/* Initialise the display constraints. */
1.36 +
1.37 +void init_display_properties(display_config_t *cfg, uint32_t offset)
1.38 +{
1.39 + /* Fixed address of the frame. */
1.40 +
1.41 + cfg->frame_start = cfg->framebuffer +
1.42 + (cfg->screen_size + cfg->line_length) * cfg->frame;
1.43 +
1.44 + /* Floating address of the screen contents. */
1.45 +
1.46 + cfg->screen_start = cfg->frame_start + offset;
1.47 +
1.48 + /* Fixed limit of the frame. */
1.49 +
1.50 + cfg->screen_limit = cfg->frame_start + cfg->screen_size;
1.51 +
1.52 + /* Recalculate the line multiplier. */
1.53 +
1.54 + cfg->line_multiplier = cfg->scanlines / cfg->line_count;
1.55 +}
1.56 +
1.57 +/* Set the number of frames in the framebuffer memory. */
1.58 +
1.59 +void set_frames(display_config_t *cfg, int frames)
1.60 +{
1.61 + /* Recalculate the number of lines. */
1.62 +
1.63 + cfg->line_count = (cfg->total_lines - cfg->max_frames) / frames;
1.64 +
1.65 + /* Recalculate the screen size. */
1.66 +
1.67 + cfg->screen_size = cfg->line_count * cfg->line_length;
1.68 +
1.69 + /* Set the number of frames and the current frame. */
1.70 +
1.71 + cfg->frames = frames;
1.72 + cfg->frame = 0;
1.73 +
1.74 + init_display_properties(cfg, 0);
1.75 +}
1.76 +
1.77 +/* Select a frame in the framebuffer. */
1.78 +
1.79 +void select_frame(display_config_t *cfg, int frame, uint32_t offset)
1.80 +{
1.81 + if ((frame < 0) || (frame >= cfg->frames))
1.82 + return;
1.83 +
1.84 + /* Update the frame details. */
1.85 +
1.86 + cfg->frame = frame;
1.87 +
1.88 + /* Set the screen start offset when switching frames. */
1.89 +
1.90 + init_display_properties(cfg, offset);
1.91 +}
1.92 +
1.93 +/* Return the screen start offset. */
1.94 +
1.95 +uint32_t get_start_offset(display_config_t *cfg)
1.96 +{
1.97 + return cfg->screen_start - cfg->frame_start;
1.98 +}
1.99 +
1.100 /* Return the line data position for the given pixel. */
1.101
1.102 int get_position(display_config_t *cfg, int x)
1.103 @@ -125,13 +218,13 @@
1.104
1.105 /* Wrap around the start of the framebuffer to the end. */
1.106
1.107 - if (start < cfg->framebuffer)
1.108 - start = cfg->screen_limit - (cfg->screen_limit - start) % cfg->screen_size;
1.109 + if (start < cfg->frame_start)
1.110 + start = cfg->screen_limit - (cfg->frame_start - start) % cfg->screen_size;
1.111
1.112 /* Wrap around the end of the framebuffer to the start. */
1.113
1.114 else if (start >= cfg->screen_limit)
1.115 - start = cfg->framebuffer + (start - cfg->framebuffer) % cfg->screen_size;
1.116 + start = cfg->frame_start + (start - cfg->screen_limit) % cfg->screen_size;
1.117
1.118 cfg->screen_start = start;
1.119 }