/[pcsx2_0.9.7]/trunk/pcsx2/Mdec.cpp
ViewVC logotype

Contents of /trunk/pcsx2/Mdec.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 2 months ago) by william
File size: 9721 byte(s)
committing r3113 initial commit again...
1 /* Pcsx2 - Pc Ps2 Emulator
2 * Copyright (C) 2002-2008 Pcsx2 Team
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 /* This code was based on the FPSE v0.08 Mdec decoder*/
20
21 #ifdef 0
22
23 #include <stdio.h>
24 #include <string.h>
25
26 #include "IopCommon.h"
27 #include "Mdec.h"
28
29 int iq_y[DCTSIZE2],iq_uv[DCTSIZE2];
30
31 static void idct1(int *block)
32 {
33 int i, val;
34
35 val = RANGE(DESCALE(block[0], PASS1_BITS+3));
36
37 for(i=0;i<DCTSIZE2;i++)
38 block[i]=val;
39 }
40
41 void idct(int *block,int k)
42 {
43 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
44 int z5, z10, z11, z12, z13;
45 int *ptr;
46 int i;
47
48 if (!k) { idct1(block); return; }
49
50 ptr = block;
51 for (i = 0; i< DCTSIZE; i++,ptr++) {
52
53 if ((ptr[DCTSIZE*1] | ptr[DCTSIZE*2] | ptr[DCTSIZE*3] |
54 ptr[DCTSIZE*4] | ptr[DCTSIZE*5] | ptr[DCTSIZE*6] |
55 ptr[DCTSIZE*7]) == 0) {
56 ptr[DCTSIZE*0] =
57 ptr[DCTSIZE*1] =
58 ptr[DCTSIZE*2] =
59 ptr[DCTSIZE*3] =
60 ptr[DCTSIZE*4] =
61 ptr[DCTSIZE*5] =
62 ptr[DCTSIZE*6] =
63 ptr[DCTSIZE*7] =
64 ptr[DCTSIZE*0];
65
66 continue;
67 }
68
69 z10 = ptr[DCTSIZE*0] + ptr[DCTSIZE*4];
70 z11 = ptr[DCTSIZE*0] - ptr[DCTSIZE*4];
71 z13 = ptr[DCTSIZE*2] + ptr[DCTSIZE*6];
72 z12 = MULTIPLY(ptr[DCTSIZE*2] - ptr[DCTSIZE*6], FIX_1_414213562) - z13;
73
74 tmp0 = z10 + z13;
75 tmp3 = z10 - z13;
76 tmp1 = z11 + z12;
77 tmp2 = z11 - z12;
78
79 z13 = ptr[DCTSIZE*3] + ptr[DCTSIZE*5];
80 z10 = ptr[DCTSIZE*3] - ptr[DCTSIZE*5];
81 z11 = ptr[DCTSIZE*1] + ptr[DCTSIZE*7];
82 z12 = ptr[DCTSIZE*1] - ptr[DCTSIZE*7];
83
84 z5 = MULTIPLY(z12 - z10, FIX_1_847759065);
85 tmp7 = z11 + z13;
86 tmp6 = MULTIPLY(z10, FIX_2_613125930) + z5 - tmp7;
87 tmp5 = MULTIPLY(z11 - z13, FIX_1_414213562) - tmp6;
88 tmp4 = MULTIPLY(z12, FIX_1_082392200) - z5 + tmp5;
89
90 ptr[DCTSIZE*0] = (tmp0 + tmp7);
91 ptr[DCTSIZE*7] = (tmp0 - tmp7);
92 ptr[DCTSIZE*1] = (tmp1 + tmp6);
93 ptr[DCTSIZE*6] = (tmp1 - tmp6);
94 ptr[DCTSIZE*2] = (tmp2 + tmp5);
95 ptr[DCTSIZE*5] = (tmp2 - tmp5);
96 ptr[DCTSIZE*4] = (tmp3 + tmp4);
97 ptr[DCTSIZE*3] = (tmp3 - tmp4);
98
99 }
100
101 ptr = block;
102 for (i = 0; i < DCTSIZE; i++ ,ptr+=DCTSIZE) {
103
104 if ((ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5] | ptr[6] |
105 ptr[7]) == 0) {
106 ptr[0] =
107 ptr[1] =
108 ptr[2] =
109 ptr[3] =
110 ptr[4] =
111 ptr[5] =
112 ptr[6] =
113 ptr[7] =
114 RANGE(DESCALE(ptr[0], PASS1_BITS+3));;
115
116 continue;
117 }
118
119 z10 = ptr[0] + ptr[4];
120 z11 = ptr[0] - ptr[4];
121 z13 = ptr[2] + ptr[6];
122 z12 = MULTIPLY(ptr[2] - ptr[6], FIX_1_414213562) - z13;
123
124 tmp0 = z10 + z13;
125 tmp3 = z10 - z13;
126 tmp1 = z11 + z12;
127 tmp2 = z11 - z12;
128
129 z13 = ptr[3] + ptr[5];
130 z10 = ptr[3] - ptr[5];
131 z11 = ptr[1] + ptr[7];
132 z12 = ptr[1] - ptr[7];
133
134 z5 = MULTIPLY(z12 - z10, FIX_1_847759065);
135 tmp7 = z11 + z13;
136 tmp6 = MULTIPLY(z10, FIX_2_613125930) + z5 - tmp7;
137 tmp5 = MULTIPLY(z11 - z13, FIX_1_414213562) - tmp6;
138 tmp4 = MULTIPLY(z12, FIX_1_082392200) - z5 + tmp5;
139
140 ptr[0] = RANGE(DESCALE(tmp0 + tmp7, PASS1_BITS+3));;
141 ptr[7] = RANGE(DESCALE(tmp0 - tmp7, PASS1_BITS+3));;
142 ptr[1] = RANGE(DESCALE(tmp1 + tmp6, PASS1_BITS+3));;
143 ptr[6] = RANGE(DESCALE(tmp1 - tmp6, PASS1_BITS+3));;
144 ptr[2] = RANGE(DESCALE(tmp2 + tmp5, PASS1_BITS+3));;
145 ptr[5] = RANGE(DESCALE(tmp2 - tmp5, PASS1_BITS+3));;
146 ptr[4] = RANGE(DESCALE(tmp3 + tmp4, PASS1_BITS+3));;
147 ptr[3] = RANGE(DESCALE(tmp3 - tmp4, PASS1_BITS+3));;
148
149 }
150 }
151
152 void mdecInit(void) {
153 mdec.rl = (u16*)&psxM[0x100000];
154 mdec.command = 0;
155 mdec.status = 0;
156 round_init();
157 }
158
159
160 void mdecWrite0(u32 data) {
161 CDR_LOG("mdec0 write %lx", data);
162
163 mdec.command = data;
164 if ((data&0xf5ff0000)==0x30000000) {
165 mdec.rlsize = data&0xffff;
166 }
167 }
168
169 void mdecWrite1(u32 data) {
170 CDR_LOG("mdec1 write %lx", data);
171
172 if (data&0x80000000) { // mdec reset
173 round_init();
174 // mdecInit();
175 }
176 }
177
178 u32 mdecRead0(void) {
179 CDR_LOG("mdec0 read %lx", mdec.command);
180
181 return mdec.command;
182 }
183
184 u32 mdecRead1(void) {
185 #ifdef CDR_LOG
186 CDR_LOG("mdec1 read %lx", mdec.status);
187 #endif
188 return mdec.status;
189 }
190
191 void psxDma0(u32 adr, u32 bcr, u32 chcr) {
192 int cmd = mdec.command;
193 int size;
194
195 CDR_LOG("DMA0 %lx %lx %lx", adr, bcr, chcr);
196
197 if (chcr!=0x01000201) return;
198
199 size = (bcr>>16)*(bcr&0xffff);
200
201 if (cmd==0x40000001) {
202 u8 *p = (u8*)PSXM(adr);
203 iqtab_init(iq_y,p);
204 iqtab_init(iq_uv,p+64);
205 }
206 else if ((cmd&0xf5ff0000)==0x30000000) {
207 mdec.rl = (u16*)PSXM(adr);
208 }
209
210 HW_DMA0_CHCR &= ~0x01000000;
211 psxDmaInterrupt(0);
212 }
213
214 void psxDma1(u32 adr, u32 bcr, u32 chcr) {
215 int blk[DCTSIZE2*6];
216 unsigned short *image;
217 int size;
218
219 CDR_LOG("DMA1 %lx %lx %lx (cmd = %lx)", adr, bcr, chcr, mdec.command);
220
221 if (chcr!=0x01000200) return;
222
223 size = (bcr>>16)*(bcr&0xffff);
224 image = (u16*)PSXM(adr);
225 if (mdec.command&0x08000000) {
226 for (;size>0;size-=(16*16)/2,image+=(16*16)) {
227 mdec.rl = rl2blk(blk,mdec.rl);
228 yuv2rgb15(blk,image);
229 }
230 } else {
231 for (;size>0;size-=(24*16)/2,image+=(24*16)) {
232 mdec.rl = rl2blk(blk,mdec.rl);
233 yuv2rgb24(blk,(u8 *)image);
234 }
235 }
236
237 HW_DMA1_CHCR &= ~0x01000000;
238 psxDmaInterrupt(1);
239 }
240
241 static int zscan[DCTSIZE2] = {
242 0 ,1 ,8 ,16,9 ,2 ,3 ,10,
243 17,24,32,25,18,11,4 ,5 ,
244 12,19,26,33,40,48,41,34,
245 27,20,13,6 ,7 ,14,21,28,
246 35,42,49,56,57,50,43,36,
247 29,22,15,23,30,37,44,51,
248 58,59,52,45,38,31,39,46,
249 53,60,61,54,47,55,62,63
250 };
251
252 static int aanscales[DCTSIZE2] = {
253 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
254 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
255 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
256 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
257 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
258 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
259 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
260 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
261 };
262
263 void iqtab_init(int *iqtab,unsigned char *iq_y)
264 {
265 int i;
266
267 for(i=0;i<DCTSIZE2;i++) {
268 iqtab[i] =iq_y[i] *aanscales[zscan[i]]>>(CONST_BITS14-IFAST_SCALE_BITS);
269 }
270 }
271
272 unsigned short* rl2blk(int *blk,unsigned short *mdec_rl) {
273 int i,k,q_scale,rl;
274 int *iqtab;
275
276 memset (blk, 0, 6*DCTSIZE2*4);
277 iqtab = iq_uv;
278 for(i=0;i<6;i++) { // decode blocks (Cr,Cb,Y1,Y2,Y3,Y4)
279 if (i>1) iqtab = iq_y;
280
281 // zigzag transformation
282 rl = *mdec_rl++;
283 q_scale = RUNOF(rl);
284 blk[0] = iqtab[0]*VALOF(rl);
285 for(k = 0;;) {
286 rl = *mdec_rl++;
287 if (rl==NOP) break;
288 k += RUNOF(rl)+1; // skip level zero-coefficients
289 if (k > 63) break;
290 blk[zscan[k]] = (VALOF(rl) * iqtab[k] * q_scale) / 8; // / 16;
291 }
292
293 idct(blk,k+1);
294 blk+=DCTSIZE2;
295 }
296 return mdec_rl;
297 }
298
299 unsigned char roundtbl[256*3];
300
301 void round_init(void) {
302 int i;
303 for(i=0;i<256;i++) {
304 roundtbl[i]=0;
305 roundtbl[i+256]=i;
306 roundtbl[i+512]=255;
307 }
308 }
309
310 void yuv2rgb15(int *blk,unsigned short *image) {
311 int x,y;
312 int *Yblk = blk+DCTSIZE2*2;
313 int Cb,Cr,R,G,B;
314 int *Cbblk = blk;
315 int *Crblk = blk+DCTSIZE2;
316
317 if (!(Config.Mdec&0x1))
318 for (y=0;y<16;y+=2,Crblk+=4,Cbblk+=4,Yblk+=8,image+=24) {
319 if (y==8) Yblk+=DCTSIZE2;
320 for (x=0;x<4;x++,image+=2,Crblk++,Cbblk++,Yblk+=2) {
321 Cr = *Crblk;
322 Cb = *Cbblk;
323 R = MULR(Cr);
324 G = MULG(Cb) + MULG2(Cr);
325 B = MULB(Cb);
326
327 RGB15(0, Yblk[0]);
328 RGB15(1, Yblk[1]);
329 RGB15(16, Yblk[8]);
330 RGB15(17, Yblk[9]);
331
332 Cr = *(Crblk+4);
333 Cb = *(Cbblk+4);
334 R = MULR(Cr);
335 G = MULG(Cb) + MULG2(Cr);
336 B = MULB(Cb);
337
338 RGB15(8, Yblk[DCTSIZE2+0]);
339 RGB15(9, Yblk[DCTSIZE2+1]);
340 RGB15(24, Yblk[DCTSIZE2+8]);
341 RGB15(25, Yblk[DCTSIZE2+9]);
342 }
343 } else
344 for (y=0;y<16;y+=2,Yblk+=8,image+=24) {
345 if (y==8) Yblk+=DCTSIZE2;
346 for (x=0;x<4;x++,image+=2,Yblk+=2) {
347 RGB15BW(0, Yblk[0]);
348 RGB15BW(1, Yblk[1]);
349 RGB15BW(16, Yblk[8]);
350 RGB15BW(17, Yblk[9]);
351
352 RGB15BW(8, Yblk[DCTSIZE2+0]);
353 RGB15BW(9, Yblk[DCTSIZE2+1]);
354 RGB15BW(24, Yblk[DCTSIZE2+8]);
355 RGB15BW(25, Yblk[DCTSIZE2+9]);
356 }
357 }
358 }
359
360 void yuv2rgb24(int *blk,unsigned char *image) {
361 int x,y;
362 int *Yblk = blk+DCTSIZE2*2;
363 int Cb,Cr,R,G,B;
364 int *Cbblk = blk;
365 int *Crblk = blk+DCTSIZE2;
366
367 if (!(Config.Mdec&0x1))
368 for (y=0;y<16;y+=2,Crblk+=4,Cbblk+=4,Yblk+=8,image+=24*3) {
369 if (y==8) Yblk+=DCTSIZE2;
370 for (x=0;x<4;x++,image+=6,Crblk++,Cbblk++,Yblk+=2) {
371 Cr = *Crblk;
372 Cb = *Cbblk;
373 R = MULR(Cr);
374 G = MULG(Cb) + MULG2(Cr);
375 B = MULB(Cb);
376
377 RGB24(0, Yblk[0]);
378 RGB24(1*3, Yblk[1]);
379 RGB24(16*3, Yblk[8]);
380 RGB24(17*3, Yblk[9]);
381
382 Cr = *(Crblk+4);
383 Cb = *(Cbblk+4);
384 R = MULR(Cr);
385 G = MULG(Cb) + MULG2(Cr);
386 B = MULB(Cb);
387
388 RGB24(8*3, Yblk[DCTSIZE2+0]);
389 RGB24(9*3, Yblk[DCTSIZE2+1]);
390 RGB24(24*3, Yblk[DCTSIZE2+8]);
391 RGB24(25*3, Yblk[DCTSIZE2+9]);
392 }
393 } else
394 for (y=0;y<16;y+=2,Yblk+=8,image+=24*3) {
395 if (y==8) Yblk+=DCTSIZE2;
396 for (x=0;x<4;x++,image+=6,Yblk+=2) {
397 RGB24BW(0, Yblk[0]);
398 RGB24BW(1*3, Yblk[1]);
399 RGB24BW(16*3, Yblk[8]);
400 RGB24BW(17*3, Yblk[9]);
401
402 RGB24BW(8*3, Yblk[DCTSIZE2+0]);
403 RGB24BW(9*3, Yblk[DCTSIZE2+1]);
404 RGB24BW(24*3, Yblk[DCTSIZE2+8]);
405 RGB24BW(25*3, Yblk[DCTSIZE2+9]);
406 }
407 }
408 }
409
410 int SaveState::mdecFreeze() {
411 Freeze(mdec);
412 Freeze(iq_y);
413 Freeze(iq_uv);
414
415 return 0;
416
417 }
418 #endif
419
420
421

  ViewVC Help
Powered by ViewVC 1.1.22