Ensure correct pixel adjustment to framebuffer (over)-draw

- Ensures correct starting position for all modes
    - Renders the last 4 samples into the right side overdraw of framebuffer for NTSC modes
This commit is contained in:
Aaron Culliney 2018-11-11 12:12:32 -08:00
parent aabc29e924
commit 80f741f225
5 changed files with 35 additions and 24 deletions

View File

@ -28,7 +28,7 @@ typedef struct A2Color_s {
typedef uint8_t (*glyph_getter_fn)(uint8_t idx, unsigned int row_off);
typedef void (*plot_fn)(color_mode_t mode, uint16_t bits14, unsigned int col, uint32_t *colors16, unsigned int fb_off);
typedef void (*flush_fn)(void);
typedef void (*flush_fn)(color_mode_t mode, unsigned int fb_off);
typedef PIXEL_TYPE (*scanline_color_fn)(PIXEL_TYPE color);
static A2Color_s colormap[256] = { { 0 } };
@ -401,7 +401,7 @@ static void _plot_oldschool(color_mode_t mode, uint16_t bits14, unsigned int col
uint16_t mask = ~(0xFF << shift); // 0xFF or 0x3FF
unsigned int off = ((shift & 0x8) >> 1) + (shift & 0x2); // 4 or 6
PIXEL_TYPE *fb_ptr = (&fbFull[0]) + _FB_OFF + fb_off - off;
PIXEL_TYPE *fb_ptr = (&fbFull[0]) + fb_off - off;
extern unsigned int ntsc_signal_bits; // HACK ...
@ -449,16 +449,18 @@ static void _plot_oldschool(color_mode_t mode, uint16_t bits14, unsigned int col
static void _plot_direct(color_mode_t mode, uint16_t bits14, unsigned int col, uint32_t *colors16, unsigned int fb_off) {
(void)col;
(void)colors16;
PIXEL_TYPE *fb_ptr = (&fbFull[0]) + _FB_OFF + fb_off;
PIXEL_TYPE *fb_ptr = (&fbFull[0]) + fb_off;
ntsc_plotBits(mode, bits14, fb_ptr);
}
static void _flush_nop(void) {
// no-op ...
static void _flush_nop(color_mode_t mode, unsigned int fb_off) {
(void)mode;
(void)fb_off;
}
static void _flush_scanline(void) {
ntsc_flushScanline();
static void _flush_scanline(color_mode_t mode, unsigned int fb_off) {
PIXEL_TYPE *fb_ptr = (&fbFull[0]) + fb_off + _SCANWIDTH;
ntsc_flushScanline(mode, fb_ptr);
scan_last_bit = 0x0;
}
@ -518,7 +520,7 @@ static void _plot_char40_scanline(scan_data_t *scandata) {
}
int filter_idx = (scanend >> 3);
flush[filter_idx][COLOR_MODE_MONO](); // filter triggers on scanline completion
flush[filter_idx][COLOR_MODE_MONO](COLOR_MODE_MONO, screen_addresses[fb_base] + fb_row); // flush triggers on scanline completion
}
static void _plot_char80_scanline(scan_data_t *scandata) {
@ -551,7 +553,7 @@ static void _plot_char80_scanline(scan_data_t *scandata) {
}
int filter_idx = (scanend >> 3);
flush[filter_idx][COLOR_MODE_MONO](); // filter triggers on scanline completion
flush[filter_idx][COLOR_MODE_MONO](COLOR_MODE_MONO, screen_addresses[fb_base] + fb_row); // flush triggers on scanline completion
}
static void _plot_lores40_scanline(scan_data_t *scandata) {
@ -583,7 +585,7 @@ static void _plot_lores40_scanline(scan_data_t *scandata) {
}
int filter_idx = (scanend >> 3);
flush[filter_idx][color_mode](); // filter triggers on scanline completion
flush[filter_idx][color_mode](color_mode, screen_addresses[fb_base] + fb_row); // flush triggers on scanline completion
}
static inline uint8_t __shift_block80(uint8_t b) {
@ -650,7 +652,7 @@ static void _plot_lores80_scanline(scan_data_t *scandata) {
}
int filter_idx = (scanend >> 3);
flush[filter_idx][color_mode](); // filter triggers on scanline completion
flush[filter_idx][color_mode](color_mode, screen_addresses[fb_base] + fb_row); // flush triggers on scanline completion
}
static void (*_textpage_plotter(uint32_t currswitches, uint32_t txtflags))(scan_data_t*) {
@ -764,7 +766,7 @@ static void _plot_hires80_scanline(scan_data_t *scandata) {
}
int filter_idx = (scanend >> 3);
flush[filter_idx][color_mode](); // filter triggers on scanline completion
flush[filter_idx][color_mode](color_mode, screen_addresses[fb_base]); // flush triggers on scanline completion
}
// ----------------------------------------------------------------------------
@ -801,7 +803,7 @@ static void _plot_hires40_scanline(scan_data_t *scandata) {
}
int filter_idx = (scanend >> 3);
flush[filter_idx][color_mode](); // filter triggers on scanline completion
flush[filter_idx][color_mode](color_mode, screen_addresses[fb_base]); // flush triggers on scanline completion
}
static void (*_hirespage_plotter(uint32_t currswitches))(scan_data_t*) {

View File

@ -258,12 +258,10 @@ uint8_t *display_waitForNextCompleteFramebuffer(void);
#define _SCANWIDTH (TEXT_COLS * FONT_WIDTH_PIXELS) // 560
#define SCANHEIGHT (TEXT_ROWS * FONT_HEIGHT_PIXELS) // 384
// Extra bytes on each side of internal framebuffers for color interpolation hack
#define _FB_OFF 4
#define _INTERPOLATED_PIXEL_ADJUSTMENT_PRE _FB_OFF
#define _INTERPOLATED_PIXEL_ADJUSTMENT_POST _FB_OFF
#define INTERPOLATED_PIXEL_ADJUSTMENT (_INTERPOLATED_PIXEL_ADJUSTMENT_PRE+_INTERPOLATED_PIXEL_ADJUSTMENT_POST)
#define SCANWIDTH (_SCANWIDTH+INTERPOLATED_PIXEL_ADJUSTMENT) // 568
// Extra bytes on each side of internal framebuffer to allow overdraw for NTSC modes
#define _FB_OFF 4
#define _FB_WIDTH_EXTRA (_FB_OFF<<1)
#define SCANWIDTH (_SCANWIDTH+_FB_WIDTH_EXTRA) // 568
#define FONT_GLYPH_X (7+/*unused*/1) // generated font.c uses a single byte (8bits) per font glyph line
#define FONT_GLYPH_Y (FONT_HEIGHT_PIXELS>>1) // ... 8 bytes total for whole glyph

View File

@ -136,7 +136,7 @@ static void _interface_plotMessageCentered(int fb_cols, int fb_rows, interface_c
_translate_screen_x_y(message, message_cols, message_rows);
int col = (fb_cols - message_cols) >> 1;
int row = (fb_rows - message_rows) >> 1;
int fb_pix_width = (fb_cols*FONT80_WIDTH_PIXELS)+INTERPOLATED_PIXEL_ADJUSTMENT;
int fb_pix_width = (fb_cols*FONT80_WIDTH_PIXELS)+_FB_WIDTH_EXTRA;
assert(fb_pix_width == SCANWIDTH);
int row_max = row + message_rows;
for (int idx=0; row<row_max; row++, idx+=message_cols+1) {

View File

@ -111,8 +111,7 @@ static void updateFBCommon(color_mode_t mode, uint16_t signal, PIXEL_TYPE *fb_pt
*fb_ptr0 = color0;
*fb_ptr1 = color1;
++ntsc_color_phase;
ntsc_color_phase &= 3;
ntsc_color_phase = (ntsc_color_phase + 1) & 0x03;
}
static void updateFBMonoTV(color_mode_t mode, uint16_t signal, PIXEL_TYPE *fb_ptr) {
@ -172,7 +171,13 @@ void ntsc_plotBits(color_mode_t mode, uint16_t bits14, PIXEL_TYPE *fb_ptr) {
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); ++fb_ptr;
}
void ntsc_flushScanline(void) {
void ntsc_flushScanline(color_mode_t mode, PIXEL_TYPE *fb_ptr) {
pixelPlotter[mode](mode, 0, fb_ptr); ++fb_ptr;
pixelPlotter[mode](mode, 0, fb_ptr); ++fb_ptr;
pixelPlotter[mode](mode, 0, fb_ptr); ++fb_ptr;
pixelPlotter[mode](mode, 0, fb_ptr); ++fb_ptr;
ntsc_color_phase = 0;
ntsc_signal_bits = 0;
}
@ -431,12 +436,18 @@ static void _init_ntsc(void) {
initChromaPhaseTables(COLOR_MODE_DEFAULT, MONO_MODE_DEFAULT);
pixelPlotter[COLOR_MODE_MONO] = updateFBMonoMonitor;
pixelPlotter[COLOR_MODE_COLOR] = updateFBMonoMonitor;
pixelPlotter[COLOR_MODE_INTERP] = updateFBMonoMonitor;
pixelPlotter[COLOR_MODE_COLOR_MONITOR] = updateFBColorMonitor;
pixelPlotter[COLOR_MODE_MONO_TV] = updateFBMonoTV;
pixelPlotter[COLOR_MODE_COLOR_TV] = updateFBColorTV;
getHalfColor[COLOR_MODE_MONO][0] = doubleScanlineMonitor;
getHalfColor[COLOR_MODE_MONO][1] = halfScanlineMonitor;
getHalfColor[COLOR_MODE_COLOR][0] = doubleScanlineMonitor;
getHalfColor[COLOR_MODE_COLOR][1] = halfScanlineMonitor;
getHalfColor[COLOR_MODE_INTERP][0] = doubleScanlineMonitor;
getHalfColor[COLOR_MODE_INTERP][1] = halfScanlineMonitor;
getHalfColor[COLOR_MODE_COLOR_MONITOR][0] = doubleScanlineMonitor;
getHalfColor[COLOR_MODE_COLOR_MONITOR][1] = halfScanlineMonitor;
getHalfColor[COLOR_MODE_MONO_TV][0] = doubleScanlineTV;

View File

@ -16,7 +16,7 @@
void ntsc_plotBits(color_mode_t mode, uint16_t bits, PIXEL_TYPE *fb_ptr);
void ntsc_flushScanline(void);
void ntsc_flushScanline(color_mode_t mode, PIXEL_TYPE *fb_ptr);
#endif /* A2_NTSC_H */