mirror of
https://github.com/PCSX2/pcsx2-sourceforge.git
synced 2026-02-13 07:40:54 +01:00
826 lines
20 KiB
C
826 lines
20 KiB
C
/* GSsoft
|
|
* Copyright (C) 2002-2005 GSsoft Team
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include <stdarg.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
#include "GS.h"
|
|
#include "Mem.h"
|
|
#include "Rec.h"
|
|
#include "Page.h"
|
|
#include "Transfer.h"
|
|
#include "Cache.h"
|
|
#include "Regs.h"
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
#include "ix86.h"
|
|
#endif
|
|
|
|
#ifdef __MSCW32__
|
|
#pragma warning(disable:4244)
|
|
#endif
|
|
|
|
char *codeclist[] = { "MPEG1", /*"DIVX", "MPEG2",*/ NULL };
|
|
char *filterslist[] = { "Disabled", "Scale2x", NULL };
|
|
|
|
|
|
const unsigned char version = PS2E_GS_VERSION;
|
|
const unsigned char revision = 1; // revision and build gives plugin version
|
|
const unsigned char build = 0;
|
|
|
|
static char *libraryName = "GSsoft Plugin";
|
|
|
|
u32 CALLBACK PS2EgetLibType() {
|
|
return PS2E_LT_GS;
|
|
}
|
|
|
|
char* CALLBACK PS2EgetLibName() {
|
|
return libraryName;
|
|
}
|
|
|
|
u32 CALLBACK PS2EgetLibVersion2(u32 type) {
|
|
return (version<<16) | (revision<<8) | build;
|
|
}
|
|
|
|
#ifdef __WIN32__
|
|
|
|
void SysMessage(char *fmt, ...) {
|
|
va_list list;
|
|
char tmp[512];
|
|
|
|
va_start(list,fmt);
|
|
vsprintf(tmp,fmt,list);
|
|
va_end(list);
|
|
MessageBox(0, tmp, "GSsoftdx Msg", 0);
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef GS_LOG
|
|
void __Log(char *fmt, ...) {
|
|
va_list list;
|
|
|
|
if (!conf.log || gsLog == NULL) return;
|
|
|
|
va_start(list, fmt);
|
|
vfprintf(gsLog, fmt, list);
|
|
va_end(list);
|
|
}
|
|
#endif
|
|
|
|
void gsSetCtxt(int ctxt) {
|
|
if (gs.ctxt == ctxt) return;
|
|
gs.ctxt = ctxt;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("gsSetCtxt %d\n", ctxt);
|
|
#endif
|
|
offset = &gs._offset[ctxt];
|
|
test = &gs._test[ctxt];
|
|
scissor = &gs._scissor[ctxt];
|
|
tex0 = &gs._tex0[ctxt];
|
|
tex1 = &gs._tex1[ctxt];
|
|
tex2 = &gs._tex2[ctxt];
|
|
clamp = &gs._clamp[ctxt];
|
|
miptbp0 = &gs._miptbp0[ctxt];
|
|
miptbp1 = &gs._miptbp1[ctxt];
|
|
gsfb = &gs._gsfb[ctxt];
|
|
alpha = &gs._alpha[ctxt];
|
|
zbuf = &gs._zbuf[ctxt];
|
|
fba = &gs._fba[ctxt];
|
|
/* fBuf = vRam + gsfb->fbp * 4;
|
|
fBufUS = (u16*)fBuf;
|
|
fBufUL = (u32*)fBuf;
|
|
zBuf = vRam + zbuf->zbp * 4;
|
|
zBufUS = (u16*)zBuf;
|
|
zBufUL = (u32*)zBuf;
|
|
tBuf = vRam + (tex0->tbp0 & ~0x1f) * 256;
|
|
tBufUS = (u16*)tBuf;
|
|
tBufUL = (u32*)tBuf;
|
|
cBuf = vRam + (tex0->cbp & ~0x1f) * 256;
|
|
cBufUS = (u16*)cBuf;
|
|
cBufUL = (u32*)cBuf;*/
|
|
}
|
|
|
|
void GSreset() {
|
|
dBuf = vRam;
|
|
dBufUL = vRamUL;
|
|
|
|
memset(&gs, 0, sizeof(gs));
|
|
|
|
gs.DISPLAY[0].w = 640;
|
|
gs.DISPLAY[0].h = 480;
|
|
gs.DISPLAY[1].w = 640;
|
|
gs.DISPLAY[1].h = 480;
|
|
|
|
gs.DISPFB[0].fbw = 640;
|
|
gs.DISPFB[0].fbh = (1024*1024) / gs.DISPFB[0].fbw;
|
|
gs.DISPFB[1].fbw = 640;
|
|
gs.DISPFB[1].fbh = (1024*1024) / gs.DISPFB[1].fbw;
|
|
|
|
gs._gsfb[0].fbw = 640;
|
|
gs._gsfb[0].fbh = (1024*1024) / gs._gsfb[0].fbw;
|
|
gs._gsfb[1].fbw = 640;
|
|
gs._gsfb[1].fbh = (1024*1024) / gs._gsfb[1].fbw;
|
|
|
|
gs._scissor[0].x1 = 639;
|
|
gs._scissor[0].y1 = 479;
|
|
gs._scissor[1].x1 = 639;
|
|
gs._scissor[1].y1 = 479;
|
|
gs.ctxt = -1;
|
|
|
|
gsSetCtxt(0);
|
|
|
|
gs.prac = 1;
|
|
prim = &gs._prim[0];
|
|
gs.primC = 0;
|
|
|
|
gs._tex0[0].tbw = 64;
|
|
gs._tex0[1].tbw = 64;
|
|
|
|
gs.CSRr = 0x55190000;
|
|
}
|
|
|
|
void *_align16(void *ptr) {
|
|
return (void*)(((uptr)ptr+0x10) & ~0xf);
|
|
}
|
|
|
|
s32 CALLBACK GSinit() {
|
|
#ifdef GS_LOG
|
|
gsLog = fopen("logs/gsLog.txt", "w");
|
|
if (gsLog) setvbuf(gsLog, NULL, _IONBF, 0);
|
|
GS_LOG("GSinit\n");
|
|
#endif
|
|
|
|
_vRam = (u8*)malloc(4*1024*1024); vRam = _align16(_vRam);
|
|
if (vRam == NULL) return -1;
|
|
|
|
vRamUS = (u16*)vRam;
|
|
vRamUL = (u32*)vRam;
|
|
|
|
GSreset();
|
|
norender = 0;
|
|
#ifdef GS_LOG
|
|
GS_LOG("GSinit ok\n");
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CALLBACK GSshutdown() {
|
|
free(_vRam);
|
|
#ifdef GS_LOG
|
|
fclose(gsLog);
|
|
#endif
|
|
}
|
|
|
|
s32 CALLBACK GSopen(void *pDsp, char *Title) {
|
|
s32 dsp;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("GSopen\n");
|
|
#endif
|
|
|
|
LoadConfig();
|
|
|
|
strcpy(GStitle, Title);
|
|
|
|
dsp = DXopen();
|
|
if (dsp == 0) return -1;
|
|
*(s32*)pDsp = dsp;
|
|
|
|
if (conf.record) recOpen();
|
|
if (conf.cache) if (CacheInit() == -1) return -1;
|
|
|
|
DXsetGSmode(640, gs.SYNCV.vfp & 1 ? gs.SYNCV.vdp : gs.SYNCV.vdp/2);
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("GSopen ok\n");
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CALLBACK GSclose() {
|
|
DXclose();
|
|
|
|
if (conf.record) recClose();
|
|
if (conf.cache) CacheShutdown();
|
|
|
|
#ifdef __WIN32__
|
|
DestroyWindow(GShwnd);
|
|
#endif
|
|
}
|
|
|
|
void CALLBACK GSirqCallback(void (*callback)()) {
|
|
GSirq = callback;
|
|
}
|
|
|
|
void CALLBACK GSmakeSnapshot(char *path) {
|
|
FILE *bmpfile;
|
|
char filename[256];
|
|
unsigned char header[0x36];
|
|
long size;
|
|
unsigned char line[1024*3];
|
|
int w,h;
|
|
short i,j;
|
|
unsigned char empty[2]={0,0};
|
|
u32 color;
|
|
u32 snapshotnr = 0;
|
|
|
|
// w = dispfb->fbw;
|
|
// h = dispfb->fbh - 20;
|
|
size = w*h*3 + 0x38;
|
|
|
|
// fill in proper values for BMP
|
|
|
|
// hardcoded BMP header
|
|
memset(header,0,0x36);
|
|
header[0]='B';
|
|
header[1]='M';
|
|
header[2]=size&0xff;
|
|
header[3]=(size>>8)&0xff;
|
|
header[4]=(size>>16)&0xff;
|
|
header[5]=(size>>24)&0xff;
|
|
header[0x0a]=0x36;
|
|
header[0x0e]=0x28;
|
|
header[0x12]=w%256;
|
|
header[0x13]=w/256;
|
|
header[0x16]=h%256;
|
|
header[0x17]=h/256;
|
|
header[0x1a]=0x01;
|
|
header[0x1c]=0x18;
|
|
header[0x26]=0x12;
|
|
header[0x27]=0x0B;
|
|
header[0x2A]=0x12;
|
|
header[0x2B]=0x0B;
|
|
|
|
// increment snapshot value & try to get filename
|
|
for (;;) {
|
|
snapshotnr++;
|
|
|
|
sprintf(filename,"%ssnap%03ld.bmp", path, snapshotnr);
|
|
|
|
bmpfile=fopen(filename,"rb");
|
|
if (bmpfile == NULL) break;
|
|
fclose(bmpfile);
|
|
}
|
|
|
|
// try opening new snapshot file
|
|
if((bmpfile=fopen(filename,"wb"))==NULL)
|
|
return;
|
|
|
|
fwrite(header,0x36,1,bmpfile);
|
|
for(i=h-1;i>=0;i--) {
|
|
for(j=0;j<w;j++) {
|
|
// color = readPixel32(j, i, 0, dispfb->fbw);
|
|
line[j*3+2]=(color )&0xff;
|
|
line[j*3+1]=(color>> 8)&0xff;
|
|
line[j*3+0]=(color>>16)&0xff;
|
|
}
|
|
fwrite(line,w*3,1,bmpfile);
|
|
}
|
|
fwrite(empty,0x2,1,bmpfile);
|
|
fclose(bmpfile);
|
|
}
|
|
|
|
void CALLBACK GSvsync() {
|
|
#ifdef GS_LOG
|
|
GS_LOG("\nGSvsync\n\n");
|
|
#endif
|
|
gs.interlace = 1 - gs.interlace;
|
|
|
|
DXupdate();
|
|
|
|
ppf = 0;
|
|
bpf = 0;
|
|
}
|
|
|
|
#define _FBmoveImage(spsm, dpsm) { \
|
|
int x, y; \
|
|
u32 pixel; \
|
|
if (s->x < d->x) { \
|
|
for(y=0; y<h; y++) { \
|
|
for(x=w-1; x>=0; x--) { \
|
|
pixel = readPixel##spsm(s->x + x, s->y + y, gs.srcbuf.bp, gs.srcbuf.bw); \
|
|
writePixel##dpsm(d->x + x, d->y + y, pixel, gs.dstbuf.bp, gs.dstbuf.bw); \
|
|
} \
|
|
} \
|
|
} else { \
|
|
for(y=0; y<h; y++) { \
|
|
for(x=0; x<w; x++) { \
|
|
pixel = readPixel##spsm(s->x + x, s->y + y, gs.srcbuf.bp, gs.srcbuf.bw); \
|
|
writePixel##dpsm(d->x + x, d->y + y, pixel, gs.dstbuf.bp, gs.dstbuf.bw); \
|
|
} \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
#define __FBmoveImage(bpp) \
|
|
void FBmoveImage##bpp##to32(Point *s, Point *d, int w, int h) { _FBmoveImage(bpp, 32); } \
|
|
void FBmoveImage##bpp##to24(Point *s, Point *d, int w, int h) { _FBmoveImage(bpp, 24); } \
|
|
void FBmoveImage##bpp##to16(Point *s, Point *d, int w, int h) { _FBmoveImage(bpp, 16); } \
|
|
void FBmoveImage##bpp##to16S(Point *s, Point *d, int w, int h) { _FBmoveImage(bpp, 16S); } \
|
|
void FBmoveImage##bpp##to8(Point *s, Point *d, int w, int h) { _FBmoveImage(bpp, 8); } \
|
|
void FBmoveImage##bpp##to4(Point *s, Point *d, int w, int h) { _FBmoveImage(bpp, 4); } \
|
|
void FBmoveImage##bpp##to8H(Point *s, Point *d, int w, int h) { _FBmoveImage(bpp, 8H); } \
|
|
void FBmoveImage##bpp##to4HL(Point *s, Point *d, int w, int h) { _FBmoveImage(bpp, 4HL); } \
|
|
void FBmoveImage##bpp##to4HH(Point *s, Point *d, int w, int h) { _FBmoveImage(bpp, 4HH); }
|
|
|
|
__FBmoveImage(32);
|
|
__FBmoveImage(24);
|
|
__FBmoveImage(16);
|
|
__FBmoveImage(16S);
|
|
__FBmoveImage(8);
|
|
__FBmoveImage(4);
|
|
__FBmoveImage(8H);
|
|
__FBmoveImage(4HL);
|
|
__FBmoveImage(4HH);
|
|
|
|
#define _FBmoveImageTO(bpp) \
|
|
switch (gs.srcbuf.psm) { \
|
|
case 0x0: FBmoveImage32to##bpp(&s, &d, w, h); return; \
|
|
case 0x1: FBmoveImage24to##bpp(&s, &d, w, h); return; \
|
|
case 0x2: FBmoveImage16to##bpp(&s, &d, w, h); return; \
|
|
case 0xA: FBmoveImage16to##bpp(&s, &d, w, h); return; \
|
|
case 0x13: FBmoveImage8to##bpp(&s, &d, w, h); return; \
|
|
case 0x14: FBmoveImage4to##bpp(&s, &d, w, h); return; \
|
|
case 0x1B: FBmoveImage8Hto##bpp(&s, &d, w, h); return; \
|
|
case 0x24: FBmoveImage4HLto##bpp(&s, &d, w, h); return; \
|
|
case 0x2C: FBmoveImage4HHto##bpp(&s, &d, w, h); return; \
|
|
}
|
|
|
|
void FBmoveImage() {
|
|
Point s, d;
|
|
int sw, sh, dw, dh;
|
|
int w, h;
|
|
|
|
s.x = gs.trxpos.sx;
|
|
s.y = gs.trxpos.sy;
|
|
d.x = gs.trxpos.dx;
|
|
d.y = gs.trxpos.dy;
|
|
sw = dw = gs.imageW;
|
|
sh = dh = gs.imageH;
|
|
|
|
if (d.x >= gs.dstbuf.bw || d.y >= gs.dstbuf.bh) return;
|
|
if (s.x >= gs.srcbuf.bw || s.y >= gs.srcbuf.bh) return;
|
|
|
|
if ((d.x + dw) < 0 || (d.y + dh) < 0) return;
|
|
if ((s.x + sw) < 0 || (s.y + sh) < 0) return;
|
|
|
|
if (d.x < 0) { dw-= -d.x; d.x = 0; }
|
|
if (d.y < 0) { dh-= -d.y; d.y = 0; }
|
|
|
|
if (s.x < 0) { sw-= -s.x; s.x = 0; }
|
|
if (s.y < 0) { sh-= -s.y; s.y = 0; }
|
|
|
|
if ((d.x + dw) > gs.dstbuf.bw) dw = gs.dstbuf.bw;
|
|
if ((d.y + dh) > gs.dstbuf.bh) dh = gs.dstbuf.bh;
|
|
|
|
if ((s.x + sw) > gs.srcbuf.bw) sw = gs.srcbuf.bw;
|
|
if ((s.y + sh) > gs.srcbuf.bh) sh = gs.srcbuf.bh;
|
|
|
|
w = min(dw, sw);
|
|
h = min(dh, sh);
|
|
|
|
switch (gs.dstbuf.psm) {
|
|
case 0x0: _FBmoveImageTO(32); break;
|
|
case 0x1: _FBmoveImageTO(24); break;
|
|
case 0x2: _FBmoveImageTO(16); break;
|
|
case 0xA: _FBmoveImageTO(16S); break;
|
|
case 0x13: _FBmoveImageTO(8); break;
|
|
case 0x14: _FBmoveImageTO(4); break;
|
|
case 0x1B: _FBmoveImageTO(8H); break;
|
|
case 0x24: _FBmoveImageTO(4HL); break;
|
|
case 0x2C: _FBmoveImageTO(4HH); break;
|
|
}
|
|
|
|
printf("invalid FBmoveImage psm configuraton: %x to %x\n", gs.dstbuf.psm, gs.srcbuf.psm);
|
|
}
|
|
|
|
u32 primP[2];
|
|
|
|
void GIFtag(pathInfo *path, u32 *data) {
|
|
path->tag.nloop = data[0] & 0x7fff;
|
|
path->tag.eop = (data[0] >> 15) & 0x1;
|
|
path->tag.pre = (data[1] >> 14) & 0x1;
|
|
path->tag.prim = (data[1] >> 15) & 0x7ff;
|
|
path->tag.flg = (data[1] >> 26) & 0x3;
|
|
path->tag.nreg = data[1] >> 28;
|
|
if (path->tag.nreg == 0) path->tag.nreg = 16;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("GIFtag: %8.8lx_%8.8lx_%8.8lx_%8.8lx: EOP=%d, NLOOP=%x, FLG=%x, NREG=%d, PRE=%d\n",
|
|
data[3], data[2], data[1], data[0],
|
|
path->tag.eop, path->tag.nloop, path->tag.flg, path->tag.nreg, path->tag.pre);
|
|
#endif
|
|
|
|
switch (path->tag.flg) {
|
|
case 0x0:
|
|
gs.regs = *(u64 *)(data+2);
|
|
gs.regn = 0;
|
|
path->mode = 1;
|
|
if (path->tag.pre) {
|
|
primP[0] = path->tag.prim;
|
|
primP[1] = 0;
|
|
|
|
GSwrite(primP, 0);
|
|
}
|
|
break;
|
|
|
|
case 0x1:
|
|
gs.regs = *(u64 *)(data+2);
|
|
gs.regn = 0;
|
|
path->mode = 2;
|
|
break;
|
|
|
|
case 0x3:
|
|
case 0x2:
|
|
// if (gs.dstbuf.bw == 0) printf("gs.dstbuf == 0!!!\n");
|
|
if (gs.imageTransfer == 0x2) {
|
|
/*#ifdef GS_LOG
|
|
GS_LOG("moveImage %dx%d %dx%d %dx%d (dir=%d)\n",
|
|
gs.trxpos.sx, gs.trxpos.sy, gs.trxpos.dx, gs.trxpos.dy, gs.imageW, gs.imageH, gs.trxpos.dir);
|
|
#endif
|
|
FBmoveImage();*/
|
|
break;
|
|
}
|
|
path->mode = 3;
|
|
#ifdef GS_LOG
|
|
GS_LOG("imageTransfer size %lx, %dx%d %dx%d (psm=%x, bp=%x)\n",
|
|
path->tag.nloop, gs.trxpos.dx, gs.trxpos.dy, gs.imageW, gs.imageH, gs.dstbuf.psm, gs.dstbuf.bp);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void GIFprocessReg(u32 *data, int reg) {
|
|
u32 out[2];
|
|
// GS_LOG("GIFprocessReg %d %8.8x_%8.8x_%8.8x_%8.8x\n", reg, data[3], data[2], data[1], data[0]);
|
|
|
|
switch (reg) {
|
|
case 0x0: // prim
|
|
out[0] = data[0];
|
|
GSwrite(out, 0x0);
|
|
break;
|
|
|
|
case 0x1: // rgbaq
|
|
out[0] = (data[0] & 0xff) |
|
|
((data[1] & 0xff) << 8) |
|
|
((data[2] & 0xff) << 16) |
|
|
((data[3] & 0xff) << 24);
|
|
out[1] = gs.q;
|
|
GSwrite(out, 0x1);
|
|
break;
|
|
|
|
case 0x2: // st
|
|
GSwrite(data, 0x2);
|
|
out[0] = gs.rgba;
|
|
out[1] = data[2];
|
|
GSwrite(out, 0x1);
|
|
break;
|
|
|
|
case 0x3: // uv
|
|
out[0] = (data[0] & 0x7fff) |
|
|
((data[1] & 0x7fff) << 16);
|
|
GSwrite(out, 0x3);
|
|
break;
|
|
|
|
case 0x4: // xyzf2
|
|
out[0] = (data[0] & 0xffff) |
|
|
((data[1] & 0xffff) << 16);
|
|
out[1] = ((data[2] >> 4) & 0xffffff) |
|
|
((data[3] & 0xff0) << 20);
|
|
if ((data[3] >> 15) & 0x1)
|
|
GSwrite(out, 0xc);
|
|
else GSwrite(out, 0x4);
|
|
break;
|
|
|
|
case 0x5: //xyz2
|
|
out[0] = (data[0] & 0xffff) |
|
|
((data[1] & 0xffff) << 16);
|
|
out[1] = data[2];
|
|
if ((data[3] >> 15) & 0x1)
|
|
GSwrite(out, 0xd);
|
|
else GSwrite(out, 0x5);
|
|
break;
|
|
|
|
case 0xe: // ad
|
|
GSwrite(data, data[2] & 0xff);
|
|
break;
|
|
|
|
case 0xf: // nop
|
|
break;
|
|
|
|
default:
|
|
#ifdef GS_LOG
|
|
GS_LOG("UNHANDLED GIFprocessReg %d %8.8x_%8.8x_%8.8x_%8.8x\n", reg, data[3], data[2], data[1], data[0]);
|
|
// GS_LOG("UNHANDLED %x!!!\n",reg);
|
|
#endif
|
|
// printf("UNHANDLED GIFprocessReg %d %8.8x_%8.8x_%8.8x_%8.8x\n", reg, data[3], data[2], data[1], data[0]);
|
|
GSwrite(data, reg);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void _GSgifPacket(pathInfo *path, u32 *pMem) { // 128bit
|
|
int reg = (int)((gs.regs >> (gs.regn*4)) & 0xf);
|
|
|
|
GIFprocessReg(pMem, reg);
|
|
gs.regn++;
|
|
if (path->tag.nreg == gs.regn) {
|
|
gs.regn = 0;
|
|
path->tag.nloop--;
|
|
}
|
|
}
|
|
|
|
void _GSgifRegList(pathInfo *path, u32 *pMem) { // 64bit
|
|
int reg;
|
|
|
|
reg = (int)((gs.regs >> (gs.regn*4)) & 0xf);
|
|
GSwrite(pMem, reg);
|
|
gs.regn++;
|
|
if (path->tag.nreg == gs.regn) {
|
|
gs.regn = 0;
|
|
path->tag.nloop--;
|
|
}
|
|
}
|
|
|
|
void _GSgifTransfer(pathInfo *path, u32 *pMem, u32 size) {
|
|
|
|
while (size > 0) {
|
|
switch (path->mode) {
|
|
case 0: /* GIF TAG */
|
|
/* if (path->tag.eop == 1) {
|
|
path->tag.eop = 0;
|
|
return;
|
|
}*/
|
|
GIFtag(path, pMem); pMem+= 4; size--;
|
|
break;
|
|
|
|
case 1: /* GIF PACKET */
|
|
while (size > 0 && path->tag.nloop > 0) {
|
|
_GSgifPacket(path, pMem);
|
|
pMem+= 4; size--;
|
|
}
|
|
if (path->tag.nloop == 0 &&
|
|
path->mode == 1) path->mode = 0;
|
|
break;
|
|
|
|
case 2: /* GIF REGLIST */
|
|
size*= 2;
|
|
while (size > 0 && path->tag.nloop > 0) {
|
|
_GSgifRegList(path, pMem);
|
|
pMem+= 2; size--;
|
|
}
|
|
if (size & 0x1) pMem+= 2;
|
|
size/= 2;
|
|
if (path->tag.nloop == 0 &&
|
|
path->mode == 2) path->mode = 0;
|
|
break;
|
|
|
|
case 3: /* GIF IMAGE */
|
|
if (size < path->tag.nloop) {
|
|
FBtransferImage(pMem, size);
|
|
path->tag.nloop-= size;
|
|
return;
|
|
} else {
|
|
FBtransferImage(pMem, path->tag.nloop);
|
|
pMem+= path->tag.nloop*4; size-= path->tag.nloop;
|
|
path->tag.nloop = 0; path->mode = 0;
|
|
}
|
|
break;
|
|
|
|
case 4: /* GIF IMAGE (FROM VRAM) */
|
|
// if (size < path->tag.nloop) {
|
|
FBtransferImageSrc(pMem, size);
|
|
pMem+= size*4; path->tag.nloop-= size;
|
|
size = 0; path->mode = 0;
|
|
/* } else {
|
|
FBtransferImageSrc(pMem, path->tag.nloop);
|
|
pMem+= path->tag.nloop*4; size-= path->tag.nloop;
|
|
path->tag.nloop = 0; path->mode = 0;
|
|
}*/
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CALLBACK GSgifTransfer2(u32 *pMem, u32 size) {
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
u64 tick;
|
|
|
|
tick = GetCPUTick();
|
|
#endif
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("GSgifTransfer2 size = %lx (mode %d, gs.path2.tag.nloop = %d)\n", size, gs.path2.mode, gs.path2.tag.nloop);
|
|
#endif
|
|
|
|
_GSgifTransfer(&gs.path2, pMem, size);
|
|
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
gsticks+= GetCPUTick() - tick;
|
|
#endif
|
|
}
|
|
|
|
void CALLBACK GSgifTransfer3(u32 *pMem, u32 size) {
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
u64 tick;
|
|
|
|
tick = GetCPUTick();
|
|
#endif
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("GSgifTransfer3 size = %lx (mode %d, gs.path3.tag.nloop = %d)\n", size, gs.path3.mode, gs.path3.tag.nloop);
|
|
#endif
|
|
|
|
_GSgifTransfer(&gs.path3, pMem, size);
|
|
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
gsticks+= GetCPUTick() - tick;
|
|
#endif
|
|
}
|
|
|
|
void CALLBACK GSgifTransfer1(u32 *pMem, u32 addr) {
|
|
u32 *data;
|
|
pathInfo *path = &gs.path1;
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
u64 tick;
|
|
|
|
tick = GetCPUTick();
|
|
#endif
|
|
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("GSgifTransfer1 0x%x (mode %d)\n", addr, path->mode);
|
|
#endif
|
|
|
|
path->tag.eop = 0;
|
|
path->mode = 0;
|
|
for (;;) {
|
|
data = ((u8*)pMem)+(addr&0x3fff);
|
|
switch (path->mode) {
|
|
case 0: /* GIF TAG */
|
|
if (path->tag.eop == 1) { /*if (addr > 0x4000) printf("meh %x\n", addr);*/ path->mode = 0; return; }
|
|
GIFtag(&gs.path1, data); addr+= 4*4;
|
|
if (path->tag.nloop == 0) { /*if (addr > 0x4000) printf("meh %x\n", addr);*/ path->mode = 0; return; }
|
|
break;
|
|
|
|
case 1: /* GIF PACKET */
|
|
_GSgifPacket(&gs.path1, data);
|
|
addr+= 4*4;
|
|
if (path->tag.nloop == 0 &&
|
|
path->mode == 1) path->mode = 0;
|
|
break;
|
|
|
|
case 2: /* GIF REGLIST */
|
|
_GSgifRegList(&gs.path1, data);
|
|
addr+= 2*4;
|
|
if (path->tag.nloop == 0 &&
|
|
path->mode == 2) {
|
|
if (addr & 2) addr+= 2*4;
|
|
path->mode = 0;
|
|
}
|
|
break;
|
|
|
|
case 3: /* GIF IMAGE */
|
|
FBtransferImage(pMem, 1);
|
|
addr+= 4*4; path->tag.nloop-= 1;
|
|
if (path->tag.nloop == 0) path->mode = 0;
|
|
break;
|
|
}
|
|
}
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
gsticks+= GetCPUTick() - tick;
|
|
#endif
|
|
}
|
|
|
|
void CALLBACK GSreadFIFO(u64 *pMem) {
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
u64 tick;
|
|
|
|
tick = GetCPUTick();
|
|
#endif
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("GSreadFIFO\n");
|
|
#endif
|
|
|
|
FBtransferImageSrc(pMem, 1);
|
|
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
gsticks+= GetCPUTick() - tick;
|
|
#endif
|
|
}
|
|
|
|
#if 0
|
|
void CALLBACK GSgifTransfer64(u32 *pMem) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("GSgifTransfer64 (mode %d)\n", gs.gifMode);
|
|
#endif
|
|
GS_LOG("GSgifTransfer64 %8.8x+%8.8x\n", pMem[1], pMem[0]);
|
|
|
|
switch (gs.gifMode) {
|
|
case 0: /* GIF TAG */
|
|
printf("GIFTAG over Transfer64!!\n");
|
|
// GIFtag(pMem); pMem+= 4; size--;
|
|
break;
|
|
|
|
case 1: /* GIF PACKET */
|
|
if (gs.buffsize == 1) {
|
|
gs.buffsize = 0;
|
|
memcpy(&gs.buff[1], pMem, 2*4);
|
|
_GSgifPacket((u32*)gs.buff);
|
|
} else {
|
|
gs.buffsize = 1;
|
|
memcpy(&gs.buff[0], pMem, 2*4);
|
|
}
|
|
break;
|
|
|
|
case 2: /* GIF REGLIST */
|
|
_GSgifRegList(pMem);
|
|
break;
|
|
|
|
case 3: /* GIF IMAGE */
|
|
/* if (size < gs.gtag.nloop) {
|
|
FBtransferImage(pMem, size);
|
|
gs.gtag.nloop-= size;
|
|
return;
|
|
} else {
|
|
FBtransferImage(pMem, gs.gtag.nloop);
|
|
pMem+= gs.gtag.nloop*4; size-= gs.gtag.nloop;
|
|
gs.gtag.nloop = 0; gs.gifMode = 0;
|
|
}
|
|
*/ break;
|
|
|
|
case 4: /* GIF IMAGE (FROM VRAM) */
|
|
// if (size < gs.gtag.nloop) {
|
|
/* FBtransferImageSrc(pMem, size);
|
|
pMem+= size*4; gs.gtag.nloop-= size;
|
|
size = 0; gs.gifMode = 0;*/
|
|
/* } else {
|
|
FBtransferImageSrc(pMem, gs.gtag.nloop);
|
|
pMem+= gs.gtag.nloop*4; size-= gs.gtag.nloop;
|
|
gs.gtag.nloop = 0; gs.gifMode = 0;
|
|
}*/
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
typedef struct {
|
|
u8 id[32];
|
|
u8 vRam[4*1024*1024];
|
|
GSinternal gs;
|
|
} GSfreezeData;
|
|
|
|
s32 CALLBACK GSfreeze(int mode, freezeData *data) {
|
|
GSfreezeData *gsd;
|
|
|
|
if (mode == FREEZE_LOAD) {
|
|
gsd = (GSfreezeData*)data->data;
|
|
if (data->size != sizeof(GSfreezeData)) {
|
|
SysMessage("GSsoft: freeze data size incorrect, %d != %d\n", data->size, sizeof(GSfreezeData));
|
|
return 0;
|
|
// return -1;
|
|
}
|
|
if (strcmp(gsd->id, libraryName)) {
|
|
SysMessage("GSsoft: freeze data incorrect plugin\n");
|
|
return -1;
|
|
}
|
|
memcpy(vRam, gsd->vRam, 4*1024*1024);
|
|
memcpy(&gs, &gsd->gs, sizeof(GSinternal));
|
|
} else
|
|
if (mode == FREEZE_SAVE) {
|
|
data->size = sizeof(GSfreezeData);
|
|
gsd = (GSfreezeData*)data->data;
|
|
strcpy(gsd->id, libraryName);
|
|
memcpy(gsd->vRam, vRam, 4*1024*1024);
|
|
memcpy(&gsd->gs, &gs, sizeof(GSinternal));
|
|
}
|
|
if (mode == FREEZE_SIZE) {
|
|
data->size = sizeof(GSfreezeData);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|