]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
16-bit display mode support.
authorToni Wilen <twilen@winuae.net>
Fri, 11 Jul 2014 09:20:30 +0000 (12:20 +0300)
committerToni Wilen <twilen@winuae.net>
Fri, 11 Jul 2014 09:20:30 +0000 (12:20 +0300)
cd32_fmv.cpp
cd32_fmv_genlock.cpp
include/cd32_fmv.h

index b3813f077237d5cc222ee99c0b718f66171dde33..84094e46d72f859479f48cdd121c3e5c1f877264 100644 (file)
@@ -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--;
index c49e4b90d9e55eb842b3c18521debcf4eb5169e8..b00979bfda9b140c5bb9f54a7438242778f3f50b 100644 (file)
@@ -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);
 }
index 3343ab7f53dcf19e9e0c6dedc02b304322b4da1e..3f8f542f5d8f51d00a797d6e100265ac5bf9ee84 100644 (file)
@@ -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);