diff options
| author | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2010-01-31 12:56:08 +0000 |
|---|---|---|
| committer | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2010-01-31 12:56:08 +0000 |
| commit | 9dfc93a3ee0b0b6b17a240bc24046063fbcc1476 (patch) | |
| tree | 4043294f246fe187a08718096a484d6d187c45aa /libpcsxcore/mdec.c | |
| parent | 94f70c33acbf341df5f00fa02a1d9af497d79e3a (diff) | |
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@40990 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'libpcsxcore/mdec.c')
| -rw-r--r-- | libpcsxcore/mdec.c | 721 |
1 files changed, 347 insertions, 374 deletions
diff --git a/libpcsxcore/mdec.c b/libpcsxcore/mdec.c index 8ab8f4bf..0f9701c8 100644 --- a/libpcsxcore/mdec.c +++ b/libpcsxcore/mdec.c @@ -34,162 +34,341 @@ #define FIX_1_847759065 (473) #define FIX_2_613125930 (669) -#define MULTIPLY(var,const) (DESCALE((var) * (const), CONST_BITS)) +#define MULTIPLY(var, const) (DESCALE((var) * (const), CONST_BITS)) -#define DEQUANTIZE(coef,quantval) (coef) +#define DEQUANTIZE(coef, quantval) (coef) -#define DESCALE(x,n) ((x)>>(n)) -#define RANGE(n) (n) +#define DESCALE(x, n) ((x) >> (n)) +#define RANGE(n) (n) -#define DCTSIZE 8 -#define DCTSIZE2 64 +#define DCTSIZE 8 +#define DCTSIZE2 64 -static void idct1(int *block) -{ - int val = RANGE(DESCALE(block[0], PASS1_BITS+3)); +static struct { + u32 command; + u32 status; + u16 *rl; + int rlsize; +} mdec; + +static int iq_y[DCTSIZE2], iq_uv[DCTSIZE2]; + +static void idct1(int *block) { + int i, val = RANGE(DESCALE(block[0], PASS1_BITS + 3)); + for (i = 0; i < DCTSIZE2; i++) block[i] = val; +} + +static void idct(int *block, int k) { + int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + int z5, z10, z11, z12, z13; + int *ptr; int i; - for(i=0;i<DCTSIZE2;i++) block[i]=val; + + if (!k) { idct1(block); return; } + + ptr = block; + for (i = 0; i< DCTSIZE; i++, ptr++) { + if ((ptr[DCTSIZE * 1] | ptr[DCTSIZE * 2] | ptr[DCTSIZE * 3] | + ptr[DCTSIZE * 4] | ptr[DCTSIZE * 5] | ptr[DCTSIZE * 6] | + ptr[DCTSIZE * 7]) == 0) { + ptr[DCTSIZE * 0] = + ptr[DCTSIZE * 1] = + ptr[DCTSIZE * 2] = + ptr[DCTSIZE * 3] = + ptr[DCTSIZE * 4] = + ptr[DCTSIZE * 5] = + ptr[DCTSIZE * 6] = + ptr[DCTSIZE * 7] = + ptr[DCTSIZE * 0]; + continue; + } + + z10 = ptr[DCTSIZE * 0] + ptr[DCTSIZE * 4]; + z11 = ptr[DCTSIZE * 0] - ptr[DCTSIZE * 4]; + z13 = ptr[DCTSIZE * 2] + ptr[DCTSIZE * 6]; + z12 = MULTIPLY(ptr[DCTSIZE * 2] - ptr[DCTSIZE * 6], FIX_1_414213562) - z13; + + tmp0 = z10 + z13; + tmp3 = z10 - z13; + tmp1 = z11 + z12; + tmp2 = z11 - z12; + + z13 = ptr[DCTSIZE * 3] + ptr[DCTSIZE * 5]; + z10 = ptr[DCTSIZE * 3] - ptr[DCTSIZE * 5]; + z11 = ptr[DCTSIZE * 1] + ptr[DCTSIZE * 7]; + z12 = ptr[DCTSIZE * 1] - ptr[DCTSIZE * 7]; + + z5 = MULTIPLY(z12 - z10, FIX_1_847759065); + tmp7 = z11 + z13; + tmp6 = MULTIPLY(z10, FIX_2_613125930) + z5 - tmp7; + tmp5 = MULTIPLY(z11 - z13, FIX_1_414213562) - tmp6; + tmp4 = MULTIPLY(z12, FIX_1_082392200) - z5 + tmp5; + + ptr[DCTSIZE * 0] = (tmp0 + tmp7); + ptr[DCTSIZE * 7] = (tmp0 - tmp7); + ptr[DCTSIZE * 1] = (tmp1 + tmp6); + ptr[DCTSIZE * 6] = (tmp1 - tmp6); + ptr[DCTSIZE * 2] = (tmp2 + tmp5); + ptr[DCTSIZE * 5] = (tmp2 - tmp5); + ptr[DCTSIZE * 4] = (tmp3 + tmp4); + ptr[DCTSIZE * 3] = (tmp3 - tmp4); + } + + ptr = block; + for (i = 0; i < DCTSIZE; i++, ptr += DCTSIZE) { + if ((ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5] | ptr[6] | ptr[7]) == 0) { + ptr[0] = ptr[1] = ptr[2] = ptr[3] = ptr[4] = ptr[5] = ptr[6] = ptr[7] = + RANGE(DESCALE(ptr[0], PASS1_BITS + 3)); + continue; + } + + z10 = ptr[0] + ptr[4]; + z11 = ptr[0] - ptr[4]; + z13 = ptr[2] + ptr[6]; + z12 = MULTIPLY(ptr[2] - ptr[6], FIX_1_414213562) - z13; + + tmp0 = z10 + z13; + tmp3 = z10 - z13; + tmp1 = z11 + z12; + tmp2 = z11 - z12; + + z13 = ptr[3] + ptr[5]; + z10 = ptr[3] - ptr[5]; + z11 = ptr[1] + ptr[7]; + z12 = ptr[1] - ptr[7]; + + z5 = MULTIPLY(z12 - z10, FIX_1_847759065); + tmp7 = z11 + z13; + tmp6 = MULTIPLY(z10, FIX_2_613125930) + z5 - tmp7; + tmp5 = MULTIPLY(z11 - z13, FIX_1_414213562) - tmp6; + tmp4 = MULTIPLY(z12, FIX_1_082392200) - z5 + tmp5; + + ptr[0] = RANGE(DESCALE(tmp0 + tmp7, PASS1_BITS+3));; + ptr[7] = RANGE(DESCALE(tmp0 - tmp7, PASS1_BITS+3));; + ptr[1] = RANGE(DESCALE(tmp1 + tmp6, PASS1_BITS+3));; + ptr[6] = RANGE(DESCALE(tmp1 - tmp6, PASS1_BITS+3));; + ptr[2] = RANGE(DESCALE(tmp2 + tmp5, PASS1_BITS+3));; + ptr[5] = RANGE(DESCALE(tmp2 - tmp5, PASS1_BITS+3));; + ptr[4] = RANGE(DESCALE(tmp3 + tmp4, PASS1_BITS+3));; + ptr[3] = RANGE(DESCALE(tmp3 - tmp4, PASS1_BITS+3));; + } } -void idct(int *block,int k) -{ - int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int z5, z10, z11, z12, z13; - int *ptr; - int i; - - if (!k) { idct1(block); return; } - - ptr = block; - for (i = 0; i< DCTSIZE; i++,ptr++) { - - if ((ptr[DCTSIZE*1] | ptr[DCTSIZE*2] | ptr[DCTSIZE*3] | - ptr[DCTSIZE*4] | ptr[DCTSIZE*5] | ptr[DCTSIZE*6] | - ptr[DCTSIZE*7]) == 0) { - ptr[DCTSIZE*0] = - ptr[DCTSIZE*1] = - ptr[DCTSIZE*2] = - ptr[DCTSIZE*3] = - ptr[DCTSIZE*4] = - ptr[DCTSIZE*5] = - ptr[DCTSIZE*6] = - ptr[DCTSIZE*7] = - ptr[DCTSIZE*0]; - - continue; - } - - z10 = ptr[DCTSIZE*0] + ptr[DCTSIZE*4]; - z11 = ptr[DCTSIZE*0] - ptr[DCTSIZE*4]; - z13 = ptr[DCTSIZE*2] + ptr[DCTSIZE*6]; - z12 = MULTIPLY(ptr[DCTSIZE*2] - ptr[DCTSIZE*6], FIX_1_414213562) - z13; - - tmp0 = z10 + z13; - tmp3 = z10 - z13; - tmp1 = z11 + z12; - tmp2 = z11 - z12; - - z13 = ptr[DCTSIZE*3] + ptr[DCTSIZE*5]; - z10 = ptr[DCTSIZE*3] - ptr[DCTSIZE*5]; - z11 = ptr[DCTSIZE*1] + ptr[DCTSIZE*7]; - z12 = ptr[DCTSIZE*1] - ptr[DCTSIZE*7]; - - z5 = MULTIPLY(z12 - z10, FIX_1_847759065); - tmp7 = z11 + z13; - tmp6 = MULTIPLY(z10, FIX_2_613125930) + z5 - tmp7; - tmp5 = MULTIPLY(z11 - z13, FIX_1_414213562) - tmp6; - tmp4 = MULTIPLY(z12, FIX_1_082392200) - z5 + tmp5; - - ptr[DCTSIZE*0] = (tmp0 + tmp7); - ptr[DCTSIZE*7] = (tmp0 - tmp7); - ptr[DCTSIZE*1] = (tmp1 + tmp6); - ptr[DCTSIZE*6] = (tmp1 - tmp6); - ptr[DCTSIZE*2] = (tmp2 + tmp5); - ptr[DCTSIZE*5] = (tmp2 - tmp5); - ptr[DCTSIZE*4] = (tmp3 + tmp4); - ptr[DCTSIZE*3] = (tmp3 - tmp4); - - } - - ptr = block; - for (i = 0; i < DCTSIZE; i++ ,ptr+=DCTSIZE) { - - if ((ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5] | ptr[6] | - ptr[7]) == 0) { - ptr[0] = - ptr[1] = - ptr[2] = - ptr[3] = - ptr[4] = - ptr[5] = - ptr[6] = - ptr[7] = - RANGE(DESCALE(ptr[0], PASS1_BITS+3));; - - continue; - } - - z10 = ptr[0] + ptr[4]; - z11 = ptr[0] - ptr[4]; - z13 = ptr[2] + ptr[6]; - z12 = MULTIPLY(ptr[2] - ptr[6], FIX_1_414213562) - z13; - - tmp0 = z10 + z13; - tmp3 = z10 - z13; - tmp1 = z11 + z12; - tmp2 = z11 - z12; - - z13 = ptr[3] + ptr[5]; - z10 = ptr[3] - ptr[5]; - z11 = ptr[1] + ptr[7]; - z12 = ptr[1] - ptr[7]; - - z5 = MULTIPLY(z12 - z10, FIX_1_847759065); - tmp7 = z11 + z13; - tmp6 = MULTIPLY(z10, FIX_2_613125930) + z5 - tmp7; - tmp5 = MULTIPLY(z11 - z13, FIX_1_414213562) - tmp6; - tmp4 = MULTIPLY(z12, FIX_1_082392200) - z5 + tmp5; - - ptr[0] = RANGE(DESCALE(tmp0 + tmp7, PASS1_BITS+3));; - ptr[7] = RANGE(DESCALE(tmp0 - tmp7, PASS1_BITS+3));; - ptr[1] = RANGE(DESCALE(tmp1 + tmp6, PASS1_BITS+3));; - ptr[6] = RANGE(DESCALE(tmp1 - tmp6, PASS1_BITS+3));; - ptr[2] = RANGE(DESCALE(tmp2 + tmp5, PASS1_BITS+3));; - ptr[5] = RANGE(DESCALE(tmp2 - tmp5, PASS1_BITS+3));; - ptr[4] = RANGE(DESCALE(tmp3 + tmp4, PASS1_BITS+3));; - ptr[3] = RANGE(DESCALE(tmp3 - tmp4, PASS1_BITS+3));; - - } +#define RUNOF(a) ((a) >> 10) +#define VALOF(a) (((int)(a) << (32 - 10)) >> (32 - 10)) + +static int zscan[DCTSIZE2] = { + 0 , 1 , 8 , 16, 9 , 2 , 3 , 10, + 17, 24, 32, 25, 18, 11, 4 , 5 , + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6 , 7 , 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 +}; + +static int aanscales[DCTSIZE2] = { + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 +}; + +static void iqtab_init(int *iqtab, unsigned char *iq_y) { +#define CONST_BITS14 14 +#define IFAST_SCALE_BITS 2 + int i; + + for(i = 0; i < DCTSIZE2; i++) { + iqtab[i] = iq_y[i] * aanscales[zscan[i]] >> (CONST_BITS14 - IFAST_SCALE_BITS); + } } -unsigned short* rl2blk(int *blk,unsigned short *mdec_rl); -void iqtab_init(int *iqtab,unsigned char *iq_y); -void yuv2rgb24(int *blk,unsigned char *image); -void yuv2rgb15(int *blk,unsigned short *image); +#define NOP 0xfe00 +static unsigned short *rl2blk(int *blk, unsigned short *mdec_rl) { + int i, k, q_scale, rl; + int *iqtab; -struct { - u32 command; - u32 status; - unsigned short *rl; - int rlsize; -} mdec; + memset(blk, 0, 6 * DCTSIZE2 * 4); + iqtab = iq_uv; + for (i = 0; i < 6; i++) { // decode blocks (Cr,Cb,Y1,Y2,Y3,Y4) + if (i > 1) iqtab = iq_y; -int iq_y[DCTSIZE2],iq_uv[DCTSIZE2]; + // zigzag transformation + rl = SWAP16(*mdec_rl); mdec_rl++; + q_scale = RUNOF(rl); + blk[0] = iqtab[0] * VALOF(rl); + for (k = 0;;) { + rl = SWAP16(*mdec_rl); mdec_rl++; + if (rl == NOP) break; + k += RUNOF(rl) + 1; // skip level zero-coefficients + if (k > 63) break; + blk[zscan[k]] = (VALOF(rl) * iqtab[k] * q_scale) / 8; // / 16; + } +// blk[0] = (blk[0] * iq_t[0] * 8) / 16; +// for(int j = 1; j<64; j++) +// blk[j] = blk[j] * iq_t[j] * q_scale; + + idct(blk, k + 1); + + blk += DCTSIZE2; + } + return mdec_rl; +} + +#ifdef FIXED +#define MULR(a) ((((int)0x0000059B) * (a)) >> 10) +#define MULG(a) ((((int)0xFFFFFEA1) * (a)) >> 10) +#define MULG2(a) ((((int)0xFFFFFD25) * (a)) >> 10) +#define MULB(a) ((((int)0x00000716) * (a)) >> 10) +#else +#define MULR(a) ((int)((float)1.40200 * (a))) +#define MULG(a) ((int)((float)-0.3437 * (a))) +#define MULG2(a) ((int)((float)-0.7143 * (a))) +#define MULB(a) ((int)((float)1.77200 * (a))) +#endif + +#define MAKERGB15(r, g, b) ( SWAP16((((r) >> 3) << 10)|(((g) >> 3) << 5)|((b) >> 3)) ) +#define ROUND(c) ( ((c) < -128) ? 0 : (((c) > (255 - 128)) ? 255 : ((c) + 128)) ) + +#define RGB15(n, Y) \ + image[n] = MAKERGB15(ROUND(Y + R), ROUND(Y + G), ROUND(Y + B)); + +#define RGB15BW(n, Y) \ + image[n] = MAKERGB15(ROUND(Y), ROUND(Y), ROUND(Y)); + +#define RGB24(n, Y) \ + image[n + 2] = ROUND(Y + R); \ + image[n + 1] = ROUND(Y + G); \ + image[n + 0] = ROUND(Y + B); + +#define RGB24BW(n, Y) \ + image[n + 2] = ROUND(Y); \ + image[n + 1] = ROUND(Y); \ + image[n + 0] = ROUND(Y); + +static void yuv2rgb15(int *blk, unsigned short *image) { + int x, y; + int *Yblk = blk + DCTSIZE2 * 2; + int Cb, Cr, R, G, B; + int *Cbblk = blk; + int *Crblk = blk + DCTSIZE2; + + if (!Config.Mdec) { + for (y = 0; y < 16; y += 2, Crblk += 4, Cbblk += 4, Yblk += 8, image += 24) { + if (y == 8) Yblk += DCTSIZE2; + for (x = 0; x < 4; x++, image += 2, Crblk++, Cbblk++, Yblk += 2) { + Cr = *Crblk; + Cb = *Cbblk; + R = MULR(Cr); + G = MULG(Cb) + MULG2(Cr); + B = MULB(Cb); + + RGB15(0, Yblk[0]); + RGB15(1, Yblk[1]); + RGB15(16, Yblk[8]); + RGB15(17, Yblk[9]); + + Cr = *(Crblk + 4); + Cb = *(Cbblk + 4); + R = MULR(Cr); + G = MULG(Cb) + MULG2(Cr); + B = MULB(Cb); + + RGB15(8, Yblk[DCTSIZE2 + 0]); + RGB15(9, Yblk[DCTSIZE2 + 1]); + RGB15(24, Yblk[DCTSIZE2 + 8]); + RGB15(25, Yblk[DCTSIZE2 + 9]); + } + } + } else { + for (y = 0; y < 16; y += 2, Yblk += 8, image += 24) { + if (y == 8) Yblk += DCTSIZE2; + for (x = 0; x < 4; x++, image += 2, Yblk += 2) { + RGB15BW(0, Yblk[0]); + RGB15BW(1, Yblk[1]); + RGB15BW(16, Yblk[8]); + RGB15BW(17, Yblk[9]); + + RGB15BW(8, Yblk[DCTSIZE2 + 0]); + RGB15BW(9, Yblk[DCTSIZE2 + 1]); + RGB15BW(24, Yblk[DCTSIZE2 + 8]); + RGB15BW(25, Yblk[DCTSIZE2 + 9]); + } + } + } +} + +static void yuv2rgb24(int *blk, unsigned char *image) { + int x,y; + int *Yblk = blk + DCTSIZE2 * 2; + int Cb, Cr, R, G, B; + int *Cbblk = blk; + int *Crblk = blk + DCTSIZE2; + + if (!Config.Mdec) { + for (y = 0; y < 16; y += 2, Crblk += 4, Cbblk += 4, Yblk += 8, image += 24 * 3) { + if (y == 8) Yblk += DCTSIZE2; + for (x = 0; x < 4; x++, image += 6, Crblk++, Cbblk++, Yblk += 2) { + Cr = *Crblk; + Cb = *Cbblk; + R = MULR(Cr); + G = MULG(Cb) + MULG2(Cr); + B = MULB(Cb); + + RGB24(0, Yblk[0]); + RGB24(1 * 3, Yblk[1]); + RGB24(16 * 3, Yblk[8]); + RGB24(17 * 3, Yblk[9]); + + Cr = *(Crblk + 4); + Cb = *(Cbblk + 4); + R = MULR(Cr); + G = MULG(Cb) + MULG2(Cr); + B = MULB(Cb); + + RGB24(8 * 3, Yblk[DCTSIZE2 + 0]); + RGB24(9 * 3, Yblk[DCTSIZE2 + 1]); + RGB24(24 * 3, Yblk[DCTSIZE2 + 8]); + RGB24(25 * 3, Yblk[DCTSIZE2 + 9]); + } + } + } else { + for (y = 0; y < 16; y += 2, Yblk += 8, image += 24 * 3) { + if (y == 8) Yblk += DCTSIZE2; + for (x = 0; x < 4; x++, image += 6, Yblk += 2) { + RGB24BW(0, Yblk[0]); + RGB24BW(1 * 3, Yblk[1]); + RGB24BW(16 * 3, Yblk[8]); + RGB24BW(17 * 3, Yblk[9]); + + RGB24BW(8 * 3, Yblk[DCTSIZE2 + 0]); + RGB24BW(9 * 3, Yblk[DCTSIZE2 + 1]); + RGB24BW(24 * 3, Yblk[DCTSIZE2 + 8]); + RGB24BW(25 * 3, Yblk[DCTSIZE2 + 9]); + } + } + } +} void mdecInit(void) { - mdec.rl = (u16*)&psxM[0x100000]; + mdec.rl = (u16 *)&psxM[0x100000]; mdec.command = 0; mdec.status = 0; } - void mdecWrite0(u32 data) { #ifdef CDR_LOG CDR_LOG("mdec0 write %lx\n", data); #endif mdec.command = data; - if ((data&0xf5ff0000)==0x30000000) { - mdec.rlsize = data&0xffff; + if ((data & 0xf5ff0000) == 0x30000000) { + mdec.rlsize = data & 0xffff; } } @@ -197,7 +376,7 @@ void mdecWrite1(u32 data) { #ifdef CDR_LOG CDR_LOG("mdec1 write %lx\n", data); #endif - if (data&0x80000000) { // mdec reset + if (data & 0x80000000) { // mdec reset mdec.command = 0; mdec.status = 0; } @@ -232,21 +411,18 @@ void psxDma0(u32 adr, u32 bcr, u32 chcr) { CDR_LOG("DMA0 %lx %lx %lx\n", adr, bcr, chcr); #endif - if (chcr!=0x01000201) return; + if (chcr != 0x01000201) return; - size = (bcr>>16)*(bcr&0xffff); + size = (bcr >> 16) * (bcr & 0xffff); - if (cmd==0x60000000) { - } else - if (cmd==0x40000001) { - u8 *p = (u8*)PSXM(adr); - iqtab_init(iq_y,p); - iqtab_init(iq_uv,p+64); - } else - if ((cmd&0xf5ff0000)==0x30000000) { - mdec.rl = (u16*)PSXM(adr); - } - else { + if (cmd == 0x60000000) { + } else if (cmd == 0x40000001) { + u8 *p = (u8 *)PSXM(adr); + iqtab_init(iq_y, p); + iqtab_init(iq_uv, p + 64); + } else if ((cmd & 0xf5ff0000) == 0x30000000) { + mdec.rl = (u16 *)PSXM(adr); + } else { } HW_DMA0_CHCR &= SWAP32(~0x01000000); @@ -254,7 +430,7 @@ void psxDma0(u32 adr, u32 bcr, u32 chcr) { } void psxDma1(u32 adr, u32 bcr, u32 chcr) { - int blk[DCTSIZE2*6]; + int blk[DCTSIZE2 * 6]; unsigned short *image; int size; @@ -262,29 +438,29 @@ void psxDma1(u32 adr, u32 bcr, u32 chcr) { CDR_LOG("DMA1 %lx %lx %lx (cmd = %lx)\n", adr, bcr, chcr, mdec.command); #endif - if (chcr!=0x01000200) return; + if (chcr != 0x01000200) return; - size = (bcr>>16)*(bcr&0xffff); + size = (bcr >> 16) * (bcr & 0xffff); - image = (u16*)PSXM(adr); - if (mdec.command&0x08000000) { + image = (u16 *)PSXM(adr); + if (mdec.command & 0x08000000) { // MDECOUTDMA_INT(((size * (1000000 / 9000)) / 4) /** 4*/ / BIAS); MDECOUTDMA_INT((size / 4) / BIAS); - size = size / ((16*16)/2); - for (;size>0;size--,image+=(16*16)) { - mdec.rl = rl2blk(blk,mdec.rl); - yuv2rgb15(blk,image); + size = size / ((16 * 16)/2); + for (; size > 0; size--, image += (16 * 16)) { + mdec.rl = rl2blk(blk, mdec.rl); + yuv2rgb15(blk, image); } } else { // MDECOUTDMA_INT(((size * (1000000 / 9000)) / 4) /** 4*/ / BIAS); MDECOUTDMA_INT((size / 4) / BIAS); - size = size / ((24*16)/2); - for (;size>0;size--,image+=(24*16)) { - mdec.rl = rl2blk(blk,mdec.rl); - yuv2rgb24(blk,(u8 *)image); + size = size / ((24 * 16) / 2); + for (; size > 0; size--, image += (24 * 16)) { + mdec.rl = rl2blk(blk, mdec.rl); + yuv2rgb24(blk, (u8 *)image); } } - mdec.status|= MDEC_BUSY; + mdec.status |= MDEC_BUSY; } void mdec1Interrupt() { @@ -292,220 +468,18 @@ void mdec1Interrupt() { CDR_LOG("mdec1Interrupt\n"); #endif if (HW_DMA1_CHCR & SWAP32(0x01000000)) { - // Set a fixed value totaly arbitrarie - // another sound value is PSXCLK / 60 or - // PSXCLK / 50 since the bug happend - // at end of frame. PSXCLK / 1000 seems - // good for FF9. - // (for FF9 need < ~28000) - // CAUTION: commented interrupt-handling may lead to problems, keep an eye ;-) + // Set a fixed value totaly arbitrarie another sound value is PSXCLK / 60 + // or PSXCLK / 50 since the bug happend at end of frame. PSXCLK / 1000 seems + // good for FF9. (for FF9 need < ~28000) + // CAUTION: commented interrupt-handling may lead to problems, keep an eye ;) MDECOUTDMA_INT(PSXCLK / 1000); - //psxRegs.interrupt|= 0x02000000; - //psxRegs.intCycle[5+24+1] *= 8; - //psxRegs.intCycle[5+24] = psxRegs.cycle; - HW_DMA1_CHCR&= SWAP32(~0x01000000); + //psxRegs.interrupt |= 0x02000000; + //psxRegs.intCycle[5 + 24 + 1] *= 8; + //psxRegs.intCycle[5 + 24] = psxRegs.cycle; + HW_DMA1_CHCR &= SWAP32(~0x01000000); DMA_INTERRUPT(1); } else { - mdec.status&= ~MDEC_BUSY; - } -} - -#define RUNOF(a) ((a)>>10) -#define VALOF(a) (((int)(a)<<(32-10))>>(32-10)) - -static int zscan[DCTSIZE2] = { - 0 ,1 ,8 ,16,9 ,2 ,3 ,10, - 17,24,32,25,18,11,4 ,5 , - 12,19,26,33,40,48,41,34, - 27,20,13,6 ,7 ,14,21,28, - 35,42,49,56,57,50,43,36, - 29,22,15,23,30,37,44,51, - 58,59,52,45,38,31,39,46, - 53,60,61,54,47,55,62,63 -}; - -static int aanscales[DCTSIZE2] = { - 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, - 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, - 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, - 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, - 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, - 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, - 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, - 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 -}; - -void iqtab_init(int *iqtab,unsigned char *iq_y) { -#define CONST_BITS14 14 -#define IFAST_SCALE_BITS 2 - int i; - - for(i=0;i<DCTSIZE2;i++) { - iqtab[i] =iq_y[i] *aanscales[zscan[i]]>>(CONST_BITS14-IFAST_SCALE_BITS); - } -} - -#define NOP 0xfe00 -unsigned short* rl2blk(int *blk,unsigned short *mdec_rl) { - int i,k,q_scale,rl; - int *iqtab; - - memset (blk, 0, 6*DCTSIZE2*4); - iqtab = iq_uv; - for(i=0;i<6;i++) { // decode blocks (Cr,Cb,Y1,Y2,Y3,Y4) - if (i>1) iqtab = iq_y; - - // zigzag transformation - rl = SWAP16(*mdec_rl); mdec_rl++; - q_scale = RUNOF(rl); - blk[0] = iqtab[0]*VALOF(rl); - for(k = 0;;) { - rl = SWAP16(*mdec_rl); mdec_rl++; - if (rl==NOP) break; - k += RUNOF(rl)+1; // skip level zero-coefficients - if (k > 63) break; - blk[zscan[k]] = (VALOF(rl) * iqtab[k] * q_scale) / 8; // / 16; - } -// blk[0] = (blk[0] * iq_t[0] * 8) / 16; -// for(int j=1;j<64;j++) -// blk[j] = blk[j] * iq_t[j] * q_scale; - - // idct - idct(blk,k+1); - - blk+=DCTSIZE2; - } - return mdec_rl; -} - -#ifdef FIXED -#define MULR(a) ((((int)0x0000059B) * (a)) >> 10) -#define MULG(a) ((((int)0xFFFFFEA1) * (a)) >> 10) -#define MULG2(a) ((((int)0xFFFFFD25) * (a)) >> 10) -#define MULB(a) ((((int)0x00000716) * (a)) >> 10) -#else -#define MULR(a) ((int)((float)1.40200 * (a))) -#define MULG(a) ((int)((float)-0.3437 * (a))) -#define MULG2(a) ((int)((float)-0.7143 * (a))) -#define MULB(a) ((int)((float)1.77200 * (a))) -#endif - -#define MAKERGB15(r, g, b) ( SWAP16((((r) >> 3) << 10)|(((g) >> 3) << 5)|((b) >> 3)) ) -#define ROUND(c) ( ((c) < -128) ? 0 : (((c) > (255 - 128)) ? 255 : ((c) + 128)) ) - -#define RGB15(n, Y) \ - image[n] = MAKERGB15(ROUND(Y + R),ROUND(Y + G),ROUND(Y + B)); - -#define RGB15BW(n, Y) \ - image[n] = MAKERGB15(ROUND(Y),ROUND(Y),ROUND(Y)); - -#define RGB24(n, Y) \ - image[n+2] = ROUND(Y + R); \ - image[n+1] = ROUND(Y + G); \ - image[n+0] = ROUND(Y + B); - -#define RGB24BW(n, Y) \ - image[n+2] = ROUND(Y); \ - image[n+1] = ROUND(Y); \ - image[n+0] = ROUND(Y); - -void yuv2rgb15(int *blk,unsigned short *image) { - int x,y; - int *Yblk = blk+DCTSIZE2*2; - int Cb,Cr,R,G,B; - int *Cbblk = blk; - int *Crblk = blk+DCTSIZE2; - - if (!Config.Mdec) - for (y=0;y<16;y+=2,Crblk+=4,Cbblk+=4,Yblk+=8,image+=24) { - if (y==8) Yblk+=DCTSIZE2; - for (x=0;x<4;x++,image+=2,Crblk++,Cbblk++,Yblk+=2) { - Cr = *Crblk; - Cb = *Cbblk; - R = MULR(Cr); - G = MULG(Cb) + MULG2(Cr); - B = MULB(Cb); - - RGB15(0, Yblk[0]); - RGB15(1, Yblk[1]); - RGB15(16, Yblk[8]); - RGB15(17, Yblk[9]); - - Cr = *(Crblk+4); - Cb = *(Cbblk+4); - R = MULR(Cr); - G = MULG(Cb) + MULG2(Cr); - B = MULB(Cb); - - RGB15(8, Yblk[DCTSIZE2+0]); - RGB15(9, Yblk[DCTSIZE2+1]); - RGB15(24, Yblk[DCTSIZE2+8]); - RGB15(25, Yblk[DCTSIZE2+9]); - } - } else - for (y=0;y<16;y+=2,Yblk+=8,image+=24) { - if (y==8) Yblk+=DCTSIZE2; - for (x=0;x<4;x++,image+=2,Yblk+=2) { - RGB15BW(0, Yblk[0]); - RGB15BW(1, Yblk[1]); - RGB15BW(16, Yblk[8]); - RGB15BW(17, Yblk[9]); - - RGB15BW(8, Yblk[DCTSIZE2+0]); - RGB15BW(9, Yblk[DCTSIZE2+1]); - RGB15BW(24, Yblk[DCTSIZE2+8]); - RGB15BW(25, Yblk[DCTSIZE2+9]); - } - } -} - -void yuv2rgb24(int *blk,unsigned char *image) { - int x,y; - int *Yblk = blk+DCTSIZE2*2; - int Cb,Cr,R,G,B; - int *Cbblk = blk; - int *Crblk = blk+DCTSIZE2; - - if (!Config.Mdec) - for (y=0;y<16;y+=2,Crblk+=4,Cbblk+=4,Yblk+=8,image+=24*3) { - if (y==8) Yblk+=DCTSIZE2; - for (x=0;x<4;x++,image+=6,Crblk++,Cbblk++,Yblk+=2) { - Cr = *Crblk; - Cb = *Cbblk; - R = MULR(Cr); - G = MULG(Cb) + MULG2(Cr); - B = MULB(Cb); - - RGB24(0, Yblk[0]); - RGB24(1*3, Yblk[1]); - RGB24(16*3, Yblk[8]); - RGB24(17*3, Yblk[9]); - - Cr = *(Crblk+4); - Cb = *(Cbblk+4); - R = MULR(Cr); - G = MULG(Cb) + MULG2(Cr); - B = MULB(Cb); - - RGB24(8*3, Yblk[DCTSIZE2+0]); - RGB24(9*3, Yblk[DCTSIZE2+1]); - RGB24(24*3, Yblk[DCTSIZE2+8]); - RGB24(25*3, Yblk[DCTSIZE2+9]); - } - } else - for (y=0;y<16;y+=2,Yblk+=8,image+=24*3) { - if (y==8) Yblk+=DCTSIZE2; - for (x=0;x<4;x++,image+=6,Yblk+=2) { - RGB24BW(0, Yblk[0]); - RGB24BW(1*3, Yblk[1]); - RGB24BW(16*3, Yblk[8]); - RGB24BW(17*3, Yblk[9]); - - RGB24BW(8*3, Yblk[DCTSIZE2+0]); - RGB24BW(9*3, Yblk[DCTSIZE2+1]); - RGB24BW(24*3, Yblk[DCTSIZE2+8]); - RGB24BW(25*3, Yblk[DCTSIZE2+9]); - } + mdec.status &= ~MDEC_BUSY; } } @@ -519,4 +493,3 @@ int mdecFreeze(gzFile f, int Mode) { return 0; } - |
