📄 spu_mixer.c
字号:
spu_size = (databuf[0]<<8) | databuf[1]; if(spu_size > bufsize) { // databuf not big enough ERROR("%s", "buffer too small\n"); state = 0; bytes_to_read = 0; return -1; } // already read the first two bytes bytes_to_read = spu_size - 2; state = 1; } // get the rest of the spu while(bytes_to_read > 0) { r = get_q(&databuf[spu_size-bytes_to_read], bytes_to_read, dtime, scr_nr); if(r > 0) { bytes_to_read -= r; } else if(r < 0) { perror("read"); state = 0; bytes_to_read = 0; return -1; } else { /* no more elements in q at this time */ /* DNOTE("q empty, %d of %d bytes read\n", spu_size-bytes_to_read, spu_size); */ return 0; } } bytes_to_read = 0; state = 0; return spu_size;}static uint8_t *byte_pos;static inline void set_byte (uint8_t *byte) { byte_pos = byte; aligned = 1;}#ifdef DEBUGuint32_t getbytes(unsigned int num, char *func)#elsestatic inline uint32_t getbytes(unsigned int num)#endif{#ifdef DEBUG int tmpnum = num;#endif uint32_t result = 0; if(num > 4) ERROR("%s", "spu_mixer: getbytes used with more than 4 bytes\n"); while(num > 0) { result <<= 8; result |= *byte_pos; byte_pos++; num--; } DPRINTF(5, "\n%s getbytes(%u): %i, 0x%0*x, ", func, tmpnum, result, tmpnum*2, result); DPRINTBITS(5, tmpnum*8, result); DPRINTF(5, "\n"); return result;}static inline uint8_t get_nibble (void){ static uint8_t next = 0; if (aligned) { fieldoffset[field]++; next = GETBYTES(1, "get_nibble (aligned)"); aligned = 0; return next >> 4; } else { aligned = 1; return next & 0xf; }}static void decode_dcsqt(spu_handle_t *spu_info){ // init start position set_byte(spu_info->buffer); /* Reset state */ //DNOTE("spu: reset 1\n"); spu_info->display_start = 0; // Maybe some other... spu_info->spu_size = GETBYTES(2, "spu_size"); DPRINTF(3, "SPU size: 0x%04x\n", spu_info->spu_size); spu_info->DCSQT_offset = GETBYTES(2, "DCSQT_offset"); DPRINTF(3, "DCSQT offset: 0x%04x\n", spu_info->DCSQT_offset); DPRINTF(3, "Display Control Sequence Table:\n"); /* parse the DCSQT */ set_byte(spu_info->buffer+spu_info->DCSQT_offset); spu_info->next_DCSQ_offset = spu_info->DCSQT_offset;}static void decode_dcsq(spu_handle_t *spu_info){ uint8_t command; uint32_t dummy; /* DCSQ */ set_byte(spu_info->buffer+spu_info->next_DCSQ_offset); DPRINTF(3, "\tDisplay Control Sequence:\n"); spu_info->start_time = GETBYTES(2, "start_time"); DPRINTF(3, "\t\tStart time: 0x%04x\n", spu_info->start_time); spu_info->last_DCSQ = spu_info->next_DCSQ_offset; spu_info->next_DCSQ_offset = GETBYTES(2, "next_DCSQ_offset"); DPRINTF(3, "\t\tNext DCSQ offset: 0x%04x\n", spu_info->next_DCSQ_offset); DPRINTF(3, "\t\tCommand Sequence Start:\n"); while((command = GETBYTES(1, "command")) != 0xff) { /* Command Sequence */ DPRINTF(3, "\t\t\tDisplay Control Command: 0x%02x\n", command); switch (command) { case 0x00: /* forced display start (often a menu) */ DPRINTF(3, "\t\t\t\tforced display start\n"); spu_info->display_start = 1; // spu_info->menu = 1; break; case 0x01: /* display start */ DPRINTF(3, "\t\t\t\tdisplay start\n"); spu_info->display_start = 1; break; case 0x02: /* display stop */ DPRINTF(3, "\t\t\t\tdisplay stop\n"); spu_info->display_start = 0; break; case 0x03: /* set colors */ DPRINTF(3, "\t\t\t\tset colors"); dummy = GETBYTES(2, "set_colors"); spu_info->color[0] = dummy & 0xf; spu_info->color[1] = (dummy>>4) & 0xf; spu_info->color[2] = (dummy>>8) & 0xf; spu_info->color[3] = (dummy>>12); DPRINTF(4, "0x%x 0x%x 0x%x 0x%x", spu_info->color[0], spu_info->color[1], spu_info->color[2], spu_info->color[3]); DPRINTF(3, "\n"); break; case 0x04: /* set contrast */ DPRINTF(3, "\t\t\t\tset contrast"); dummy = GETBYTES(2, "set_contrast"); spu_info->contrast[0] = dummy & 0xf; spu_info->contrast[1] = (dummy>>4) & 0xf; spu_info->contrast[2] = (dummy>>8) & 0xf; spu_info->contrast[3] = (dummy>>12); DPRINTF(4, "0x%x 0x%x 0x%x 0x%x", spu_info->contrast[0], spu_info->contrast[1], spu_info->contrast[2], spu_info->contrast[3]); DPRINTF(3, "\n"); break; case 0x05: /* set sp screen position */ DPRINTF(3, "\t\t\t\tset sp screen position\n"); dummy = GETBYTES(3, "x coordinates"); spu_info->x_start = dummy>>12; spu_info->x_end = dummy & 0xfff; dummy = GETBYTES(3, "y coordinates"); spu_info->y_start = dummy>>12; spu_info->y_end = dummy & 0xfff; spu_info->width = spu_info->x_end - spu_info->x_start + 1; spu_info->height = spu_info->y_end - spu_info->y_start + 1; DPRINTF(4, "\t\t\t\t\tx_start=%i x_end=%i, y_start=%i, y_end=%i " "width=%i height=%i\n", spu_info->x_start, spu_info->x_end, spu_info->y_start, spu_info->y_end, spu_info->width, spu_info->height); break; case 0x06: /* set start address in PXD */ DPRINTF(3, "\t\t\t\tset start address in PXD\n"); spu_info->fieldoffset[0] = GETBYTES(2, "field 0 start"); spu_info->fieldoffset[1] = GETBYTES(2, "field 1 start"); DPRINTF(4, "\t\t\t\t\tfield_0=%i field_1=%i\n", spu_info->fieldoffset[0], spu_info->fieldoffset[1]); break; case 0x07: /* wipe */ { uint16_t num; uint8_t color_left[4]; uint8_t contrast_left[4]; uint8_t color_right[4]; uint8_t contrast_right[4]; uint16_t y_start; uint16_t y_end; uint16_t x_pos; uint16_t u1, u2, u3; /* x_start, x_end, ? */ int type; DPRINTF(3, "\t\t\t\twipe\n"); num = GETBYTES(2,"cmd 7 length"); y_start = GETBYTES(2, "wipe y_start"); dummy = GETBYTES(2, "wipe y_end"); type = (dummy >> 12) & 0xf; y_end = dummy & 0xfff; u1 = GETBYTES(2, "wipe x_start 1?"); dummy = GETBYTES(2, "wipe color_left"); color_left[0] = dummy & 0xf; color_left[1] = (dummy >> 4) & 0xf; color_left[2] = (dummy >> 8) & 0xf; color_left[3] = (dummy >> 12) & 0xf; dummy = GETBYTES(2, "wipe contrast_left"); contrast_left[0] = dummy & 0xf; contrast_left[1] = (dummy >> 4) & 0xf; contrast_left[2] = (dummy >> 8) & 0xf; contrast_left[3] = (dummy >> 12) & 0xf; if(type == 2) { x_pos = GETBYTES(2, "wipe x_pos"); dummy = GETBYTES(2, "wipe color_right"); color_right[0] = dummy & 0xf; color_right[1] = (dummy >> 4) & 0xf; color_right[2] = (dummy >> 8) & 0xf; color_right[3] = (dummy >> 12) & 0xf; dummy = GETBYTES(2, "wipe contrast_right"); contrast_right[0] = dummy & 0xf; contrast_right[1] = (dummy >> 4) & 0xf; contrast_right[2] = (dummy >> 8) & 0xf; contrast_right[3] = (dummy >> 12) & 0xf; } if(type == 1 || type == 2) { u2 = GETBYTES(2, "wipe x_end 1?"); u3 = GETBYTES(2, "wipe x_end 2?"); } else { FATAL("%s", "unknown cmd 07 type\n"); exit(1); } if((u1 != 0) || (u2 != 0x0fff) || (u3 != 0xffff)) { FATAL("%s", "unknown bits in cmd 7 used\n"); exit(1); } } break; default: ERROR("\t\t\t\t*Unknown Display Control Command: %02x\n", command); //exit(1); break; } } DPRINTF(3, "\t\tEnd of Command Sequence\n"); if(spu_info->last_DCSQ == spu_info->next_DCSQ_offset) { DPRINTF(3, "End of Display Control Sequence Table\n"); }}static void display_mix_function_bgr16(uint32_t color, uint32_t contrast, unsigned int length, uint8_t *data, int notused1, uint8_t *notused2, uint8_t *notused3){ uint32_t invcontrast = 256 - contrast; int n; uint16_t *pixel =(uint16_t*) data; /* if total transparency do nothing */ if(contrast != 0) { unsigned int r, g, b; r = color & 0xff; g = (color >> 8) & 0xff; b = (color >> 16) & 0xff; /* if no transparancy just overwrite */ if(contrast == (0xf<<4)) { uint16_t color2 = ((b << 8) & 0xf800) | ((g << 3) & 0x07e0) | (r >> 3); for(n = 0; n < length; n++, pixel++) { *pixel = color2; } } else { for(n = 0; n < length; n++, pixel++) { unsigned int pr, pg, pb; uint16_t source = *pixel; pr = (source & 0x001f) << 3; pg = (source & 0x07e0) >> 3; // or 0x037 >> 2, 0x076 >> 3 ??? pb = (source & 0xf800) >> 8; // (source >> 8) & 0xf8; pr = (pr * invcontrast + r * contrast) >> 8; pg = (pg * invcontrast + g * contrast) >> 8; pb = (pb * invcontrast + b * contrast) >> 8; *pixel = ((pb << 8) & 0xf800) | ((pg << 3) & 0x07e0) | (pr >> 3); } } }}static void display_mix_function_bgr24(uint32_t color, uint32_t contrast, unsigned int length, uint8_t *data, int notused1, uint8_t *notused2, uint8_t *notused3){ uint32_t invcontrast = 256 - contrast; int n; uint8_t *pixel =(uint8_t*) data; /* if total transparency do nothing */ if(contrast != 0) { unsigned int r, g, b; r = color & 0xff; g = (color >> 8) & 0xff; b = (color >> 16) & 0xff; /* if no transparancy just overwrite */ if(contrast == (0xf<<4)) { for(n = 0; n < length; n++, pixel++) { *pixel++ = b; *pixel++ = g; *pixel = r; } } else { for(n = 0; n < length; n++, pixel++) { unsigned int pr, pg, pb; pb = pixel[0]; pg = pixel[1]; pr = pixel[2]; pr = (pr * invcontrast + r * contrast) >> 8; pg = (pg * invcontrast + g * contrast) >> 8; pb = (pb * invcontrast + b * contrast) >> 8; *pixel++ = pb; *pixel++ = pg; *pixel = pr; } } }}static void display_mix_function_bgr32(uint32_t color, uint32_t contrast, unsigned int length, uint8_t *data, int notused1, uint8_t *notused2, uint8_t *notused3){ uint32_t invcontrast = 256 - contrast; int n; uint32_t *pixel =(uint32_t*) data; /* if total transparency do nothing */ if(contrast != 0) { unsigned int r, g, b; r = color & 0xff; g = (color >> 8) & 0xff; b = (color >> 16) & 0xff; /* if no transparancy just overwrite */ if(contrast == (0xf<<4)) { if(rgbmode & MODE_ALIEN_MASK) { for(n = 0; n < length; n++, pixel++) { *pixel = color<<8; } } else { for(n = 0; n < length; n++, pixel++) { *pixel = color; } } } else { if(rgbmode & MODE_ALIEN_MASK) { for(n = 0; n < length; n++, pixel++) { unsigned int pr, pg, pb; uint32_t source = *pixel; pr = (source >> 8) & 0xff; pg = (source >> 16) & 0xff; pb = (source >> 24) & 0xff; pr = (pr * invcontrast + r * contrast) >> 8; pg = (pg * invcontrast + g * contrast) >> 8; pb = (pb * invcontrast + b * contrast) >> 8; *pixel = (pb << 24) | (pg << 16) | (pr << 8); } } else { for(n = 0; n < length; n++, pixel++) { unsigned int pr, pg, pb; uint32_t source = *pixel; pr = source & 0xff; pg = (source >> 8) & 0xff; pb = (source >> 16) & 0xff; pr = (pr * invcontrast + r * contrast) >> 8; pg = (pg * invcontrast + g * contrast) >> 8; pb = (pb * invcontrast + b * contrast) >> 8; *pixel = (pb << 16) | (pg << 8) | pr; } } } }}/* Mixing function for YV12 mode */static void display_mix_function_yuv(uint32_t color, uint32_t contrast, unsigned int length, uint8_t *y_pixel, int field, uint8_t *u_pixel, uint8_t *v_pixel){ uint32_t invcontrast = 256 - contrast; int n; /* if total transparency do nothing */ if(contrast != 0) { uint8_t y, u, v; y = (color >> 16) & 0xff; u = (color >> 8) & 0xff; v = color & 0xff; /* if no transparancy just overwrite */ if(contrast == (0xf<<4)) { for(n = 0; n < length; n++) { y_pixel[n] = y; } /* only write uv on even columns and rows */ if(!field) { int odd = (int)y_pixel & 1; for(n = odd; n < (length + 1 - odd)/2; n++) { u_pixel[n] = u; v_pixel[n] = v; } } /* (length+even)/2 10 och 1 (s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -