From 45507177b559e5f6fe1878012ec27a466ae5a3ce Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Fri, 11 Jul 2014 12:20:30 +0300 Subject: [PATCH] 16-bit display mode support. --- cd32_fmv.cpp | 25 ++++++---- cd32_fmv_genlock.cpp | 112 ++++++++++++++++++++++++++++++------------- include/cd32_fmv.h | 2 +- 3 files changed, 97 insertions(+), 42 deletions(-) diff --git a/cd32_fmv.cpp b/cd32_fmv.cpp index b3813f07..84094e46 100644 --- a/cd32_fmv.cpp +++ b/cd32_fmv.cpp @@ -173,7 +173,7 @@ static int fmv_video_debug = 0; #define CL_INT_GOP (1 << 2) #define CL_INT_PIC_V (1 << 1) #define CL_INT_SEQ_V (1 << 3) -// CL450 DRAM resident variabels (WORD address) +// CL450 DRAM resident variables (WORD address) #define CL_DRAM_SEQ_SEM 0x10 #define CL_DRAM_SEQ_CONTROL 0x11 #define CL_DRAM_H_SIZE 0x12 @@ -227,6 +227,7 @@ struct cl450_videoram { int width; int height; + int depth; uae_u8 data[CL450_VIDEO_BUFFER_SIZE]; }; static struct cl450_videoram *videoram; @@ -245,7 +246,8 @@ static struct cl450_newpacket cl450_newpacket_buffer[CL450_NEWPACKET_BUFFER_SIZE static int cl450_newpacket_offset_write; static int cl450_newpacket_offset_read; -static int cl450_frame_rate; +static int cl450_frame_rate, cl450_frame_pixbytes; +static int cl450_frame_width, cl450_frame_height; static int cl450_video_hsync_wait; static int cl450_videoram_read; static int cl450_videoram_write; @@ -804,12 +806,15 @@ static void cl450_parse_frame(void) } break; case STATE_SEQUENCE: - mpeg2_convert(mpeg_decoder, mpeg2convert_rgb32, NULL); + cl450_frame_pixbytes = currprefs.color_mode != 5 ? 2 : 4; + mpeg2_convert(mpeg_decoder, cl450_frame_pixbytes == 2 ? mpeg2convert_rgb16 : mpeg2convert_rgb32, NULL); cl450_set_status(CL_INT_SEQ_V); cl450_frame_rate = mpeg_info->sequence->frame_period ? 27000000 / mpeg_info->sequence->frame_period : 0; + cl450_frame_width = mpeg_info->sequence->width; + cl450_frame_height = mpeg_info->sequence->height; cl450_write_dram(CL_DRAM_PICTURE_RATE, cl450_frame_rate); - cl450_write_dram(CL_DRAM_H_SIZE, mpeg_info->sequence->width); - cl450_write_dram(CL_DRAM_V_SIZE, mpeg_info->sequence->height); + cl450_write_dram(CL_DRAM_H_SIZE, cl450_frame_width); + cl450_write_dram(CL_DRAM_V_SIZE, cl450_frame_height); break; case STATE_PICTURE: break; @@ -820,9 +825,10 @@ static void cl450_parse_frame(void) case STATE_SLICE: case STATE_END: if (mpeg_info->display_fbuf) { - memcpy(videoram[cl450_videoram_write].data, mpeg_info->display_fbuf->buf[0], CL450_VIDEO_BUFFER_SIZE); - videoram[cl450_videoram_write].width = mpeg_info->sequence->width; - videoram[cl450_videoram_write].height = mpeg_info->sequence->height; + memcpy(videoram[cl450_videoram_write].data, mpeg_info->display_fbuf->buf[0], cl450_frame_width * cl450_frame_height * cl450_frame_pixbytes); + videoram[cl450_videoram_write].width = cl450_frame_width; + videoram[cl450_videoram_write].height = cl450_frame_height; + videoram[cl450_videoram_write].depth = cl450_frame_pixbytes; cl450_videoram_write++; cl450_videoram_write &= CL450_VIDEO_BUFFERS - 1; cl450_videoram_cnt++; @@ -1339,7 +1345,8 @@ void cd32_fmv_hsync_handler(void) if (cl450_video_hsync_wait == 0) { cl450_set_status(CL_INT_PIC_D); if (cl450_videoram_cnt > 0) { - cd32_fmv_new_image(videoram[cl450_videoram_read].width, videoram[cl450_videoram_read].height, cl450_blank ? NULL : videoram[cl450_videoram_read].data); + cd32_fmv_new_image(videoram[cl450_videoram_read].width, videoram[cl450_videoram_read].height, + videoram[cl450_videoram_read].depth, cl450_blank ? NULL : videoram[cl450_videoram_read].data); cl450_videoram_read++; cl450_videoram_read &= CL450_VIDEO_BUFFERS - 1; cl450_videoram_cnt--; diff --git a/cd32_fmv_genlock.cpp b/cd32_fmv_genlock.cpp index c49e4b90..b00979bf 100644 --- a/cd32_fmv_genlock.cpp +++ b/cd32_fmv_genlock.cpp @@ -15,8 +15,9 @@ #include "xwin.h" static uae_u8 *mpeg_out_buffer; -static int mpeg_width, mpeg_height; +static int mpeg_width, mpeg_height, mpeg_depth; static uae_u32 fmv_border_color; +static uae_u16 fmv_border_color_16; int cd32_fmv_active; // According to schematics there is at least 3 (possible more) @@ -24,30 +25,36 @@ int cd32_fmv_active; // mpeg player software never sets any genlock bits. // this is probably not how it actually works. -#define GENLOCK_VAL 0x20 +#define GENLOCK_VAL_32 0x20 +#define GENLOCK_VAL_16 0x03 -#define MPEG_PIXBYTES 4 +#define MPEG_PIXBYTES_32 4 +#define MPEG_PIXBYTES_16 2 #define MAX_MPEG_WIDTH 352 #define MAX_MPEG_HEIGHT 288 void cd32_fmv_new_border_color(uae_u32 bordercolor) { fmv_border_color = bordercolor; + fmv_border_color_16 = (((bordercolor >> (16 + 3)) & 31) << 11); + fmv_border_color_16 |= (((bordercolor >> ( 8 + 2)) & 63) << 5); + fmv_border_color_16 |= (((bordercolor >> ( 0 + 3)) & 31) << 0); } -void cd32_fmv_new_image(int w, int h, uae_u8 *s) +void cd32_fmv_new_image(int w, int h, int d, uae_u8 *s) { if (!mpeg_out_buffer) - mpeg_out_buffer = xmalloc(uae_u8, MAX_MPEG_WIDTH * MAX_MPEG_HEIGHT * MPEG_PIXBYTES); + mpeg_out_buffer = xmalloc(uae_u8, MAX_MPEG_WIDTH * MAX_MPEG_HEIGHT * MPEG_PIXBYTES_32); if (s == NULL || w > MAX_MPEG_WIDTH || h > MAX_MPEG_HEIGHT) { - memset(mpeg_out_buffer, 0, MAX_MPEG_WIDTH * MAX_MPEG_HEIGHT * MPEG_PIXBYTES); + memset(mpeg_out_buffer, 0, MAX_MPEG_WIDTH * MAX_MPEG_HEIGHT * MPEG_PIXBYTES_32); mpeg_width = MAX_MPEG_WIDTH; mpeg_height = MAX_MPEG_HEIGHT; return; } - memcpy(mpeg_out_buffer, s, w * h * MPEG_PIXBYTES); + memcpy(mpeg_out_buffer, s, w * h * d); mpeg_width = w; mpeg_height = h; + mpeg_depth = d; } void cd32_fmv_state(int state) @@ -57,6 +64,65 @@ void cd32_fmv_state(int state) // slow software method but who cares. + +static void genlock_32(struct vidbuffer *vbin, struct vidbuffer *vbout, int w, int h, int d, int hoffset, int voffset, int mult) +{ + for (int hh = 0, sh = -voffset; hh < h; sh++, hh += mult) { + for (int h2 = 0; h2 < mult; h2++) { + uae_u8 *d8 = vbout->bufmem + vbout->rowbytes * (hh + h2 + voffset); + uae_u32 *d32 = (uae_u32*)d8; + uae_u8 *s8 = vbin->bufmem + vbin->rowbytes * (hh + h2 + voffset) ; + uae_u32 *srcp = NULL; + if (sh >= 0 && sh < mpeg_height) + srcp = (uae_u32*)(mpeg_out_buffer + sh * mpeg_width * MPEG_PIXBYTES_32); + for (int ww = 0, sw = -hoffset; ww < w; sw++, ww += mult) { + uae_u32 sv = fmv_border_color; + if (sw >= 0 && sw < mpeg_width && srcp) + sv = srcp[sw]; + for (int w2 = 0; w2 < mult; w2++) { + uae_u32 v; + if (s8[0] >= GENLOCK_VAL_32) { + v = *((uae_u32*)s8); + } else { + v = sv; + } + *d32++ = v; + s8 += d; + } + } + } + } +} + +static void genlock_16(struct vidbuffer *vbin, struct vidbuffer *vbout, int w, int h, int d, int hoffset, int voffset, int mult) +{ + for (int hh = 0, sh = -voffset; hh < h; sh++, hh += mult) { + for (int h2 = 0; h2 < mult; h2++) { + uae_u8 *d8 = vbout->bufmem + vbout->rowbytes * (hh + h2 + voffset); + uae_u16 *d16 = (uae_u16*)d8; + uae_u8 *s8 = vbin->bufmem + vbin->rowbytes * (hh + h2 + voffset) ; + uae_u16 *srcp = NULL; + if (sh >= 0 && sh < mpeg_height) + srcp = (uae_u16*)(mpeg_out_buffer + sh * mpeg_width * MPEG_PIXBYTES_16); + for (int ww = 0, sw = -hoffset; ww < w; sw++, ww += mult) { + uae_u16 sv = fmv_border_color_16; + if (sw >= 0 && sw < mpeg_width && srcp) + sv = srcp[sw]; + for (int w2 = 0; w2 < mult; w2++) { + uae_u32 v; + if ((((uae_u16*)s8)[0] >> 11) >= GENLOCK_VAL_16) { + v = *((uae_u16*)s8); + } else { + v = sv; + } + *d16++ = v; + s8 += d; + } + } + } + } +} + void cd32_fmv_genlock(struct vidbuffer *vbin, struct vidbuffer *vbout) { int hoffset, voffset, mult; @@ -64,6 +130,9 @@ void cd32_fmv_genlock(struct vidbuffer *vbin, struct vidbuffer *vbout) int h = vbin->outheight; int d = vbin->pixbytes; + if (!mpeg_out_buffer) + return; + mult = 1; for (;;) { if (mult < 4 && mpeg_width * (mult << 1) <= w && mpeg_height * (mult << 1) <= h) { @@ -82,29 +151,8 @@ void cd32_fmv_genlock(struct vidbuffer *vbin, struct vidbuffer *vbout) if (voffset < 0) voffset = 0; - for (int hh = 0, sh = -voffset; hh < h; sh++, hh += mult) { - for (int h2 = 0; h2 < mult; h2++) { - uae_u8 *d8 = vbout->bufmem + vbout->rowbytes * (hh + h2 + voffset); - uae_u32 *d32 = (uae_u32*)d8; - uae_u8 *s8 = vbin->bufmem + vbin->rowbytes * (hh + h2 + voffset) ; - uae_u32 *srcp = NULL; - if (sh >= 0 && sh < mpeg_height) - srcp = (uae_u32*)(mpeg_out_buffer + sh * mpeg_width * MPEG_PIXBYTES); - for (int ww = 0, sw = -hoffset; ww < w; sw++, ww += mult) { - uae_u32 sv = fmv_border_color; - if (sw >= 0 && sw < mpeg_width && srcp) - sv = srcp[sw]; - for (int w2 = 0; w2 < mult; w2++) { - uae_u32 v; - if (s8[0] >= GENLOCK_VAL) { - v = *((uae_u32*)s8); - } else { - v = sv; - } - *d32++ = v; - s8 += d; - } - } - } - } + if (mpeg_depth == 2) + genlock_16(vbin, vbout, w, h, d, hoffset, voffset, mult); + else + genlock_32(vbin, vbout, w, h, d, hoffset, voffset, mult); } diff --git a/include/cd32_fmv.h b/include/cd32_fmv.h index 3343ab7f..3f8f542f 100644 --- a/include/cd32_fmv.h +++ b/include/cd32_fmv.h @@ -7,7 +7,7 @@ extern void cd32_fmv_hsync_handler(void); extern void cd32_fmv_vsync_handler(void); extern void cd32_fmv_state(int state); -extern void cd32_fmv_new_image(int, int, uae_u8*); +extern void cd32_fmv_new_image(int, int, int, uae_u8*); extern void cd32_fmv_genlock(struct vidbuffer*, struct vidbuffer*); extern void cd32_fmv_new_border_color(uae_u32); extern void cd32_fmv_set_sync(double svpos); -- 2.47.3