mirror of
https://github.com/Azimer/Apollo64.git
synced 2025-04-02 10:31:54 -04:00
367 lines
7.4 KiB
C++
367 lines
7.4 KiB
C++
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
#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<bytes;i++)
|
|
{
|
|
x=mem_read32(addr+i*4);
|
|
d[i]=x;
|
|
}
|
|
}
|
|
|
|
void readshort(int *q,DWORD addr,int bytes)
|
|
{
|
|
int x,i;
|
|
bytes>>=1;
|
|
for(i=0;i<bytes;i+=2)
|
|
{
|
|
x=mem_read32(addr+i*2);
|
|
q[i+0]=(short)(x>>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<bytes;i+=2)
|
|
{
|
|
a=q[i+0]&0xffff;
|
|
b=q[i+1]&0xffff;
|
|
x=(a<<16)+b;
|
|
mem_write32(addr+i*2,x);
|
|
}
|
|
}
|
|
|
|
void readq(int *q,DWORD addr)
|
|
{
|
|
int i;
|
|
readshort(q,addr,64*2);
|
|
// for(i=0;i<64;i++) q[i]=8;
|
|
for(i=1;i<64;i++) q[i]*=2;
|
|
}
|
|
|
|
int zigzag[64]={
|
|
0, 1, 5, 6, 14, 15, 27, 28,
|
|
2, 4, 7, 13, 16, 26, 29, 42,
|
|
3, 8, 12, 17, 25, 30, 41, 43,
|
|
9, 11, 18, 24, 31, 40, 44, 53,
|
|
10, 19, 23, 32, 39, 45, 52, 54,
|
|
20, 22, 33, 38, 46, 51, 55, 60,
|
|
21, 34, 37, 47, 50, 56, 59, 61,
|
|
35, 36, 48, 49, 57, 58, 62, 63};
|
|
|
|
int curve[8][8]={ // old values, overwritten by dctinit()
|
|
{ 16, 16, 16, 16, 16, 16, 16, 16},
|
|
{ 15, 13, 8, 3, -3, -8,-13,-15},
|
|
{ 14, 6, -6,-14,-14, -6, 6, 14},
|
|
{ 13, -3,-15, -8, 8, 15, 3,-13},
|
|
{ 11,-11,-11, 11, 11,-11,-11, 11},
|
|
{ 8,-15, 3, 13,-13, -3, 15, -8},
|
|
{ 6,-14, 14, -6, -6, 14,-14, 6},
|
|
{ 3, -8, 13,-15, 15,-13, 8, -3}
|
|
};
|
|
|
|
void dctdump(int *in,char *text)
|
|
{
|
|
static FILE *f1;
|
|
int x,y;
|
|
|
|
if(!f1) f1=fopen("dct.log","wt");
|
|
fprintf(f1,"%s\n",text);
|
|
for(y=0;y<8;y++)
|
|
{
|
|
for(x=0;x<8;x++)
|
|
{
|
|
fprintf(f1,"%4i ",in[x+y*8]);
|
|
}
|
|
fprintf(f1,"\n");
|
|
}
|
|
}
|
|
|
|
static void dctinit(void)
|
|
{
|
|
int x,y;
|
|
float f,fx,fy;
|
|
if(1)
|
|
{ // more accurate
|
|
for(y=0;y<8;y++)
|
|
{
|
|
for(x=0;x<8;x++)
|
|
{
|
|
fx=(float)x;
|
|
fy=(float)y;
|
|
f=(float)((2*fx+0)*fy*3.1415926535/16.0);
|
|
f=(float)(cos(f)*256.0);
|
|
curve[x][y]=(int)f;
|
|
//print("curve %i,%i: %3i float %.3f\n",x,y,curve[y][x],f/32.0);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(y=0;y<8;y++)
|
|
{
|
|
for(x=0;x<8;x++)
|
|
{
|
|
curve[x][y]*=16;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void dct(int *d,int *s,int *quant,int dump)
|
|
{
|
|
int tmp[8];
|
|
int in[8][8];
|
|
int x,y,a,i;
|
|
static int initdone=0;
|
|
|
|
if(!initdone)
|
|
{
|
|
dctinit();
|
|
initdone=1;
|
|
}
|
|
|
|
for(y=0;y<8;y++) for(x=0;x<8;x++)
|
|
{
|
|
i=zigzag[x+y*8];
|
|
in[y][x]=s[i]*quant[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++;
|
|
}
|
|
|