#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
{
int width;
int height;
+ int depth;
uae_u8 data[CL450_VIDEO_BUFFER_SIZE];
};
static struct cl450_videoram *videoram;
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;
}
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;
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++;
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--;
#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)
// 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)
// 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;
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) {
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);
}