#include #include #include #include "common.h" #include "winmain.h" #include "emumain.h" extern u8 *rdram; typedef struct { DWORD m_pic; int wid; int hig; DWORD m_q1; DWORD m_q2; DWORD m_q3; DWORD zero1; DWORD zero2; } ZData; ZData zdata; u32 mem_read32 (u32 addr) { // Very safe memory read return (*(u32 *)(rdram+addr)); if (addr & 0x3) __asm int 3; u32 x; x = rdram[addr^3]; x <<= 8; x += rdram[(addr+1)^3]; x <<= 8; x += rdram[(addr+2)^3]; x <<= 8; x += rdram[(addr+3)^3]; return x; } void mem_write32 (u32 addr, u32 data) { // Very safe memory write *(u32 *)(rdram+addr) = data; return; if (addr & 0x3) __asm int 3; u32 x = data; rdram[(addr+3)^3] = (u8)(x & 0xff); x >>= 8; rdram[(addr+2)^3] = (u8)(x & 0xff); x >>= 8; rdram[(addr+1)^3] = (u8)(x & 0xff); x >>= 8; rdram[(addr)^3] = (u8)(x & 0xff); } static int in[6][64]; static int rgb[256][4]; static int out[16*16]; static int q1[64]; static int q2[64]; static int q3[64]; void readdata(void *dst,DWORD addr,int bytes) { DWORD *d=(DWORD *)dst; int i,x; bytes>>=2; for(i=0;i>=1; for(i=0;i>16); q[i+1]=(short)(x&65535); } } void writeshort(int *q,DWORD addr,int bytes) { int x,a,b,i; bytes>>=1; for(i=0;i>3; } // if(dump) dctdump((int *)in,"\nInput:"); for(x=0;x<8;x++) { for(a=0;a<8;a++) tmp[a]=in[0][x]<<8; for(y=1;y<8;y++) { for(a=0;a<8;a++) { tmp[a]+=in[y][x]*curve[y][a]; } } for(a=0;a<8;a++) in[a][x]=tmp[a]>>8; } for(y=0;y<8;y++) { for(a=0;a<8;a++) tmp[a]=in[y][0]<<8; for(x=1;x<8;x++) { for(a=0;a<8;a++) { tmp[a]+=in[y][x]*curve[x][a]; } } for(a=0;a<8;a++) in[y][a]=tmp[a]>>8; } // if(dump) dctdump((int *)in,"Output:"); for(y=0;y<8;y++) for(x=0;x<8;x++) { d[x+y*8]=in[y][x]; } } static void uncompress(void) { int x2,y2,x,y,a,b; int i1,u1,v1; int ci[64]; int cu[64]; int cv[64]; dct(cu,in[4],q2,0); dct(cv,in[5],q3,0); for(y=0;y<16;y++) for(x=0;x<16;x++) { u1=cu[(x>>1)+(y>>1)*8]; v1=cv[(x>>1)+(y>>1)*8]; rgb[x+y*16][0]=( 291*v1 ) >> 8; rgb[x+y*16][1]=( -101*u1-148*v1 ) >> 8; rgb[x+y*16][2]=( 564*u1 ) >> 8; } for(y2=0;y2<=8;y2+=8) for(x2=0;x2<=8;x2+=8) { dct(ci,in[(x2/8)+(y2/8)*2],q1,1); for(y=0;y<8;y++) for(x=0;x<8;x++) { i1=ci[x+y*8]; rgb[(x+x2)+(y+y2)*16][0]+=i1+128; rgb[(x+x2)+(y+y2)*16][1]+=i1+128; rgb[(x+x2)+(y+y2)*16][2]+=i1+128; } } // convert to short for(y=0;y<16;y++) for(x=0;x<16;x++) { b=1; a=rgb[x+y*16][0]; a=(a>>3); if(a<0) a=0; if(a>31) a=31; b+=(a<<11); a=rgb[x+y*16][1]; a=(a>>3); if(a<0) a=0; if(a>31) a=31; b+=(a<<6); a=rgb[x+y*16][2]; a=(a>>3); if(a<0) a=0; if(a>31) a=31; b+=(a<<1); out[x+y*16]=b; } } void zlist_uncompress() { u32 dataptr = ((u32*)idmem)[0xFF0/4]; int z; static int cnt=1; static int lastframe=-1; static int firsttime=1; //readdata(&zdata,task->m_data_ptr,sizeof(ZData)); memcpy (&zdata, dataptr+rdram, sizeof(ZData)); if((zdata.m_pic&0x7f000000)!=0 || (zdata.m_q1 &0x7f000000)!=0 || (zdata.m_q2 &0x7f000000)!=0 || (zdata.m_q3 &0x7f000000)!=0 || !zdata.m_pic || !zdata.m_q1 || !zdata.m_q2 || !zdata.m_q3) { /*Debug (0, "zelda: JPEG-DCT (buffer %08X, quant %08X) INVALID, ignored.\n", zdata.m_pic,zdata.m_q1,zdata.m_q2,zdata.m_q3);*/ return; } readq(q1,zdata.m_q1); readq(q2,zdata.m_q2); readq(q3,zdata.m_q3); if(firsttime) { firsttime=0; /*disasm_dumpucode("rspzlist.log", task->m_ucode ,task->ucode_size, task->m_ucode_data,task->ucode_data_size,0x80); logd("RSP microcode/data dumped to RSPZLIST.LOG\n");*/ } /* if(st.frames!=lastframe) { print("zelda: JPEG-DCT (buffer %08X, quant %08X %08X %08X)\n", zdata.m_pic,zdata.m_q1,zdata.m_q2,zdata.m_q3); lastframe=st.frames; }*/ for(z=0;z<4;z++) { readshort ((int *)in ,zdata.m_pic+z*768,8*8*2*6); uncompress(); writeshort((int *)out,zdata.m_pic+z*768,16*16*2); } /* if(cnt==1) { FILE *f1; f1=fopen("bgin.dat","wb"); for(z=0;z<3072*2;z+=4) { d=mem_read32(zdata.m_pic+z); d=FLIP32(d); fwrite(&d,1,4,f1); } fclose(f1); } d1=(cnt)+(cnt<<8)+(cnt<<16)+(cnt<<24); d2=d1^-1; for(z=0;z<4;z++) { for(y=0;y<16;y++) for(x=0;x<16;x++) { if(x==0 || y==0 || x==15 || y==15) { mem_write16(zdata.m_pic+z*768+x*2+y*2*16,d1); } } } */ cnt++; }