Files
2007-11-11 02:55:00 +00:00

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;
}