diff --git a/libpcsxcore/gpu.c b/libpcsxcore/gpu.c index 61a7b3dc..4ab01166 100755 --- a/libpcsxcore/gpu.c +++ b/libpcsxcore/gpu.c @@ -143,7 +143,7 @@ void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU #endif break; } - GPU_pgxpMemory(madr, PGXP_GetMem()); + GPU_pgxpMemory(PGXP_ConvertAddress(madr), PGXP_GetMem()); GPU_writeDataMem(ptr, size); #if 0 diff --git a/libpcsxcore/gte.c b/libpcsxcore/gte.c index 04a3968c..2d02032a 100755 --- a/libpcsxcore/gte.c +++ b/libpcsxcore/gte.c @@ -499,7 +499,9 @@ int docop2(int op) { PGXP_pushSXYZ2s(Lm_G1_ia((s64)OFX + (s64)(IR1 * h_over_sz3) * (Config.Widescreen ? 0.75 : 1)), Lm_G2_ia((s64)OFY + (s64)(IR2 * h_over_sz3)), - SZ3); + SZ3, SXY2); + + //PGXP_RTPS(0, SXY2); MAC0 = F((s64) DQB + ((s64) DQA * h_over_sz3)); IR0 = Lm_H(m_mac0, 1); @@ -889,7 +891,9 @@ int docop2(int op) { PGXP_pushSXYZ2s(Lm_G1_ia((s64)OFX + (s64)(IR1 * h_over_sz3) * (Config.Widescreen ? 0.75 : 1)), Lm_G2_ia((s64)OFY + (s64)(IR2 * h_over_sz3)), - SZ3); + SZ3, SXY2); + + //PGXP_RTPS(v, SXY2); } MAC0 = F((s64) DQB + ((s64) DQA * h_over_sz3)); diff --git a/libpcsxcore/pgxp_gte.c b/libpcsxcore/pgxp_gte.c index de3797d6..d5341dc6 100644 --- a/libpcsxcore/pgxp_gte.c +++ b/libpcsxcore/pgxp_gte.c @@ -27,6 +27,7 @@ #include "pgxp_gte.h" #include "psxmem.h" +#include "r3000a.h" typedef struct { @@ -35,6 +36,7 @@ typedef struct float z; unsigned int valid; unsigned int count; + unsigned int value; } precise_value; typedef union @@ -52,8 +54,14 @@ typedef union precise_value GTE_reg[32]; precise_value CPU_reg[32]; -precise_value Mem[2048 * 1024 / 4]; // mirror 2MB in 32-bit words -precise_value Scratch[2048 * 1024 / 4]; // mirror 2MB in 32-bit words +precise_value Mem[3 * 2048 * 1024 / 4]; // mirror 2MB in 32-bit words * 3 +const u32 UserMemOffset = 0; +const u32 ScratchOffset = 2048 * 1024 / 4; +const u32 RegisterOffset = 2 * 2048 * 1024 / 4; +const u32 InvalidAddress = 3 * 2048 * 1024 / 4; + +//precise_value Scratch[2048 * 1024 / 4]; // mirror 2MB in 32-bit words +//precise_value Registers[2048 * 1024 / 4]; // mirror 2MB in 32-bit words void PGXP_Init() { @@ -65,94 +73,112 @@ char* PGXP_GetMem() return (char*)(Mem); } -#define VRAM 0 -#define SCRATCH 1 +/* Playstation Memory Map (from Playstation doc by Joshua Walker) +0x0000_0000-0x0000_ffff Kernel (64K) +0x0001_0000-0x001f_ffff User Memory (1.9 Meg) -precise_value* ReadMem(u32 addr) -{ - u32 memType; - uint32_t paddr = addr; - int* ip = NULL; +0x1f00_0000-0x1f00_ffff Parallel Port (64K) - switch (paddr >> 24) - { - case 0x80: - case 0xa0: - case 0x00: - memType = VRAM; - break; - default: - if ((paddr >> 20) == 0x1f8) - { - memType = SCRATCH; - break; - } - // if (value.valid) //FAILED @ 0x807FFEE8 - // *ip = 5; - return NULL; - } - -#ifdef GTE_LOG - //GTE_LOG("PGXP_Read %x [%x] |", addr, paddr); -#endif - if (memType == VRAM) - { - // RAM furher mirrored over 8MB - //paddr = (paddr & 0x1FFFFF) >> 2; - paddr = ((paddr & 0x7FFFFF) % 0x200000) >> 2; - return &Mem[paddr]; - } - else if (memType == SCRATCH) +0x1f80_0000-0x1f80_03ff Scratch Pad (1024 bytes) + +0x1f80_1000-0x1f80_2fff Hardware Registers (8K) + +0x1fc0_0000-0x1fc7_ffff BIOS (512K) + +0x8000_0000-0x801f_ffff Kernel and User Memory Mirror (2 Meg) Cached +0x9fc0_0000-0x9fc7_ffff BIOS Mirror (512K) Cached + +0xa000_0000-0xa01f_ffff Kernel and User Memory Mirror (2 Meg) Uncached +0xbfc0_0000-0xbfc7_ffff BIOS Mirror (512K) Uncached +*/ +void ValidateAddress(u32 addr) +{ + int* pi = NULL; + + if ((addr >= 0x00000000) && (addr <= 0x007fffff)) {} // Kernel + User Memory x 8 + else if ((addr >= 0x1f000000) && (addr <= 0x1f00ffff)) {} // Parallel Port + else if ((addr >= 0x1f800000) && (addr <= 0x1f8003ff)) {} // Scratch Pad + else if ((addr >= 0x1f801000) && (addr <= 0x1f802fff)) {} // Hardware Registers + else if ((addr >= 0x1fc00000) && (addr <= 0x1fc7ffff)) {} // Bios + else if ((addr >= 0x80000000) && (addr <= 0x807fffff)) {} // Kernel + User Memory x 8 Cached mirror + else if ((addr >= 0x9fc00000) && (addr <= 0x9fc7ffff)) {} // Bios Cached Mirror + else if ((addr >= 0xa0000000) && (addr <= 0xa07fffff)) {} // Kernel + User Memory x 8 Uncached mirror + else if ((addr >= 0xbfc00000) && (addr <= 0xbfc7ffff)) {} // Bios Uncached Mirror + else if (addr == 0xfffe0130) {} // Used for cache flushing + else { - paddr = (paddr & 0x1FFFFF) >> 2;// (paddr & 0x3FFF) >> 2; - return &Scratch[paddr]; + // *pi = 5; } - return NULL; } -void WriteMem(precise_value value, u32 addr) +u32 PGXP_ConvertAddress(u32 addr) { - u32 memType; - uint32_t paddr = addr; - int* ip = NULL; + u32 memOffs = 0; + u32 paddr = addr; + + ValidateAddress(addr); switch (paddr >> 24) { case 0x80: case 0xa0: case 0x00: - memType = VRAM; + // RAM further mirrored over 8MB + paddr = ((paddr & 0x7FFFFF) % 0x200000) >> 2; + paddr = UserMemOffset + paddr; break; default: if ((paddr >> 20) == 0x1f8) { - memType = SCRATCH; - break; + if (paddr >= 0x1f801000) + { + // paddr = ((paddr & 0xFFFF) - 0x1000); + // paddr = (paddr % 0x2000) >> 2; + paddr = ((paddr & 0xFFFF) - 0x1000) >> 2; + paddr = RegisterOffset + paddr; + break; + } + else + { + //paddr = ((paddr & 0xFFF) % 0x400) >> 2; + paddr = (paddr & 0x3FF) >> 2; + paddr = ScratchOffset + paddr; + break; + } } - else - if (value.valid) //FAILED @ 0x807FFEE8 - *ip = 5; - return; + + paddr = InvalidAddress; + break; } #ifdef GTE_LOG - GTE_LOG("PGXP_Write %x [%x] |", addr, paddr); + //GTE_LOG("PGXP_Read %x [%x] |", addr, paddr); #endif - // Store to RAM - if (memType == VRAM) - { - // RAM furher mirrored over 8MB - //paddr = (paddr & 0x1FFFFF) >> 2; - paddr = ((paddr & 0x7FFFFF) % 0x200000) >> 2;// (paddr & 0x3FFF) >> 2; - Mem[paddr] = value; - } - else if (memType == SCRATCH) - { - paddr = (paddr & 0x1FFFFF) >> 2;// (paddr & 0x3FFF) >> 2; - Scratch[paddr] = value; - } + return paddr; +} + +precise_value* GetPtr(u32 addr) +{ + addr = PGXP_ConvertAddress(addr); + + if (addr != InvalidAddress) + return &Mem[addr]; + return NULL; +} + +precise_value* ReadMem(u32 addr) +{ + return GetPtr(addr); +} + +void WriteMem(precise_value value, u32 addr) +{ + precise_value* pMem = GetPtr(addr); + + if (pMem) + *pMem = value; } #define SX0 (GTE_reg[ 12 ].x) @@ -186,7 +212,7 @@ precise_value PGXP_validateXY(precise_value *high, u32 low) if (!high) return ret; - high->valid = (high->valid && PGXP_validate(high->x, temp.x) && PGXP_validate(high->y, temp.y)); + high->valid = (high->valid) && (high->value == low);//(high->valid && PGXP_validate(high->x, temp.x) && PGXP_validate(high->y, temp.y)); // Cheat //if (!high->valid) @@ -225,7 +251,7 @@ precise_value PGXP_copyXY(u32 low) return ret; } -void PGXP_pushSXYZ2f(float _x, float _y, float _z) +void PGXP_pushSXYZ2f(float _x, float _y, float _z, unsigned int _v) { static unsigned int uCount = 0; // push values down FIFO @@ -235,6 +261,7 @@ void PGXP_pushSXYZ2f(float _x, float _y, float _z) SXY2.x = _x; SXY2.y = _y; SXY2.z = _z; + SXY2.value = _v; SXY2.valid = 1; SXY2.count = uCount++; @@ -243,13 +270,58 @@ void PGXP_pushSXYZ2f(float _x, float _y, float _z) #endif } -void PGXP_pushSXYZ2s(s64 _x, s64 _y, s64 _z) +void PGXP_pushSXYZ2s(s64 _x, s64 _y, s64 _z, u32 v) { float fx = (float)(_x) / (float)(1 << 16); float fy = (float)(_y) / (float)(1 << 16); float fz = (float)(_z); - PGXP_pushSXYZ2f(fx, fy, fz); + PGXP_pushSXYZ2f(fx, fy, fz, v); +} + +#define VX(n) (psxRegs.CP2D.p[ n << 1 ].sw.l) +#define VY(n) (psxRegs.CP2D.p[ n << 1 ].sw.h) +#define VZ(n) (psxRegs.CP2D.p[ (n << 1) + 1 ].sw.l) + +void PGXP_RTPS(u32 _n, u32 _v) +{ + // Transform + float TRX = (s64)psxRegs.CP2C.p[5].sd; + float TRY = (s64)psxRegs.CP2C.p[6].sd; + float TRZ = (s64)psxRegs.CP2C.p[7].sd; + + // Rotation with 12-bit shift + float R11 = (float)psxRegs.CP2C.p[ 0 ].sw.l / (float)(1 << 12); + float R12 = (float)psxRegs.CP2C.p[ 0 ].sw.h / (float)(1 << 12); + float R13 = (float)psxRegs.CP2C.p[ 1 ].sw.l / (float)(1 << 12); + float R21 = (float)psxRegs.CP2C.p[ 1 ].sw.h / (float)(1 << 12); + float R22 = (float)psxRegs.CP2C.p[ 2 ].sw.l / (float)(1 << 12); + float R23 = (float)psxRegs.CP2C.p[ 2 ].sw.h / (float)(1 << 12); + float R31 = (float)psxRegs.CP2C.p[ 3 ].sw.l / (float)(1 << 12); + float R32 = (float)psxRegs.CP2C.p[ 3 ].sw.h / (float)(1 << 12); + float R33 = (float)psxRegs.CP2C.p[ 4 ].sw.l / (float)(1 << 12); + + // Bring vertex into view space + float MAC1 = TRX + (R11 * VX(_n)) + (R12 * VY(_n)) + (R13 * VZ(_n)); + float MAC2 = TRY + (R21 * VX(_n)) + (R22 * VY(_n)) + (R23 * VZ(_n)); + float MAC3 = TRZ + (R31 * VX(_n)) + (R32 * VY(_n)) + (R33 * VZ(_n)); + + float SZ3 = MAC3; + float H = psxRegs.CP2C.p[26].sw.l; + float h_over_sz3 = H / SZ3; + + // Offsets with 16-bit shift + float OFX = (float)psxRegs.CP2C.p[ 24 ].sd / (float)(1 << 16); + float OFY = (float)psxRegs.CP2C.p[ 25 ].sd / (float)(1 << 16); + + // PSX Screen space X,Y,W components + float sx = OFX + (MAC1 * h_over_sz3) * (Config.Widescreen ? 0.75 : 1); + float sy = OFY + (MAC2 * h_over_sz3); + float sw = SZ3; + + PGXP_pushSXYZ2f(sx , sy , sw, _v); + + return; } int PGXP_NLCIP_valid() @@ -261,13 +333,26 @@ int PGXP_NLCIP_valid() float PGXP_NCLIP() { - float nclip = ((SX0 * SY1) + (SX1 * SY2) + (SX2 * SY0) - (SX0 * SY2) - (SX1 * SY0) - (SX2 * SY1)); +// float nclip = ((SX0 * SY1) + (SX1 * SY2) + (SX2 * SY0) - (SX0 * SY2) - (SX1 * SY0) - (SX2 * SY1)); // ensure fractional values are not incorrectly rounded to 0 - if (fabs(nclip) < 1.0f) - nclip += (nclip < 0.f ? -1 : 1); + //if ((fabs(nclip) < 1.0f) && (nclip != 0)) + // nclip += (nclip < 0.f ? -1 : 1); + + float AX = SX1 - SX0; + float AY = SY1 - SY0; + + float BX = SX2 - SX0; + float BY = SY2 - SY0; + + // normalise A and B + float mA = sqrt((AX*AX) + (AY*AY)); + float mB = sqrt((BX*BX) + (BY*BY)); - return nclip; + // calculate AxB to get Z component of C + float CZ = ((AX * BY) - (AY * BX)) * (1 << 12); + + return CZ;// nclip; } static precise_value PGXP_MFC2_int(u32 reg) @@ -307,7 +392,7 @@ void PGXP_MFC2(u32 gpr, u32 gtr, u32 value) { if (!gpr) return; #ifdef GTE_LOG - GTE_LOG("PGXP_MFC2 [%x] [%x] %x (%u %u)|", gpr, gtr, value, GTE_reg[gtr].valid, GTE_reg[gtr].count); + GTE_LOG("PGXP_MFC2 [%x]<-[%x] %x (%u %u)|", gpr, gtr, value, GTE_reg[gtr].valid, GTE_reg[gtr].count); #endif CPU_reg[gpr] = PGXP_validateXY(>E_reg[gtr], value); @@ -317,7 +402,7 @@ void PGXP_MFC2(u32 gpr, u32 gtr, u32 value) void PGXP_MTC2(u32 gpr, u32 gtr, u32 value) { #ifdef GTE_LOG - GTE_LOG("PGXP_MTC2 [%x] [%x] %x (%u %u)|", gpr, gtr, value, CPU_reg[gtr].valid, CPU_reg[gtr].count); + GTE_LOG("PGXP_MTC2 [%x]->[%x] %x (%u %u)|", gpr, gtr, value, CPU_reg[gpr].valid, CPU_reg[gpr].count); #endif PGXP_MTC2_int(PGXP_validateXY(&CPU_reg[gpr], value), gtr); } @@ -391,7 +476,7 @@ void PGPR_L32(u32 addr, u32 code, u32 value) #endif } -// store 16bit word +// store 32bit word void PGPR_S32(u32 addr, u32 code, u32 value) { u32 reg = ((code >> 16) & 0x1F); // The rt part of the instruction register @@ -429,24 +514,50 @@ void PGPR_S32(u32 addr, u32 code, u32 value) } // invalidate register (invalid 8/16 bit read) -void PGPR_InvalidLoad(u32 addr, u32 code) +void PGPR_InvalidLoad(u32 addr, u32 code, u32 value) { u32 reg = ((code >> 16) & 0x1F); // The rt part of the instruction register + precise_value* pD = NULL; precise_value p; - p.x = p.y = p.valid = p.count = 0; + p.x = p.y = -1337; // default values + + //p.valid = 0; + //p.count = value; + pD = ReadMem(addr); + + if (pD) + { + p.count = addr; + p = *pD; + } + else + { + p.count = value; + } + + p.valid = 0; // invalidate register CPU_reg[reg] = p; } // invalidate memory address (invalid 8/16 bit write) -void PGPR_InvalidStore(u32 addr, u32 code) +void PGPR_InvalidStore(u32 addr, u32 code, u32 value) { u32 reg = ((code >> 16) & 0x1F); // The rt part of the instruction register + precise_value* pD = NULL; precise_value p; - p.x = p.y = p.valid = p.count = 0; + pD = ReadMem(addr); + + p.x = p.y = -2337; + + if (pD) + p = *pD; + + p.valid = 0; + p.count = (reg * 1000) + value; // invalidate memory WriteMem(p, addr); @@ -468,25 +579,25 @@ void PGXP_psxMemWrite32Trace(u32 mem, u32 value, u32 code) u16 PGXP_psxMemRead16Trace(u32 mem, u32 code) { u16 value = psxMemRead16(mem); - PGPR_InvalidLoad(mem, code); + PGPR_InvalidLoad(mem, code, 116); return value; } void PGXP_psxMemWrite16Trace(u32 mem, u16 value, u32 code) { - PGPR_InvalidStore(mem, code); + PGPR_InvalidStore(mem, code, 216); psxMemWrite16(mem, value); } u8 PGXP_psxMemRead8Trace(u32 mem, u32 code) { u8 value = psxMemRead8(mem); - PGPR_InvalidLoad(mem, code); + PGPR_InvalidLoad(mem, code, 18); return value; } void PGXP_psxMemWrite8Trace(u32 mem, u8 value, u32 code) { - PGPR_InvalidStore(mem, code); + PGPR_InvalidStore(mem, code, 28); psxMemWrite8(mem, value); } \ No newline at end of file diff --git a/libpcsxcore/pgxp_gte.h b/libpcsxcore/pgxp_gte.h index 50c8859b..d10021c0 100644 --- a/libpcsxcore/pgxp_gte.h +++ b/libpcsxcore/pgxp_gte.h @@ -32,11 +32,15 @@ void PGXP_Init(); // initialise memory char* PGXP_GetMem(); // return pointer to precision memory +u32 PGXP_ConvertAddress(u32 addr); // -- GTE functions // Transforms -void PGXP_pushSXYZ2f(float _x, float _y, float _z); -void PGXP_pushSXYZ2s(s64 _x, s64 _y, s64 _z); +void PGXP_pushSXYZ2f(float _x, float _y, float _z, unsigned int _v); +void PGXP_pushSXYZ2s(s64 _x, s64 _y, s64 _z, u32 v); + +void PGXP_RTPS(u32 _n, u32 _v); + int PGXP_NLCIP_valid(); float PGXP_NCLIP(); diff --git a/plugins/peopsxgl/draw.c b/plugins/peopsxgl/draw.c index 922145f0..0e2e440a 100755 --- a/plugins/peopsxgl/draw.c +++ b/plugins/peopsxgl/draw.c @@ -599,8 +599,10 @@ int GLinitialize() glMatrixMode(GL_PROJECTION); // init projection with psx resolution glLoadIdentity(); - glOrtho(0,PSXDisplay.DisplayMode.x, - PSXDisplay.DisplayMode.y, 0, -1, 1); + //glOrtho(0,PSXDisplay.DisplayMode.x, + // PSXDisplay.DisplayMode.y, 0, -1, 1); + + PGXP_SetMatrix(0, PSXDisplay.DisplayMode.x, PSXDisplay.DisplayMode.y, 0, -1, 1); if(iZBufferDepth) // zbuffer? { @@ -1019,8 +1021,6 @@ BOOL offsetline(unsigned int* addr) vertex[2].y=(short)((float)y1+py); - PGXP_GetVertices(addr, vertex); - if(vertex[0].x==vertex[3].x && // ortho rect? done vertex[1].x==vertex[2].x && vertex[0].y==vertex[1].y && @@ -1039,6 +1039,8 @@ BOOL offsetline(unsigned int* addr) vertex[3].x-=VERTEX_OFFX; vertex[3].y-=VERTEX_OFFY; + PGXP_GetVertices(addr, vertex, -VERTEX_OFFX, -VERTEX_OFFY); + return FALSE; } @@ -1070,13 +1072,13 @@ BOOL offset2(unsigned int* addr) vertex[1].y=ly1; } - PGXP_GetVertices(addr, vertex); - vertex[0].x+=PSXDisplay.CumulOffset.x; vertex[1].x+=PSXDisplay.CumulOffset.x; vertex[0].y+=PSXDisplay.CumulOffset.y; vertex[1].y+=PSXDisplay.CumulOffset.y; + PGXP_GetVertices(addr, vertex, PSXDisplay.CumulOffset.x, PSXDisplay.CumulOffset.y); + return FALSE; } @@ -1115,8 +1117,6 @@ BOOL offset3(unsigned int* addr) vertex[2].y=ly2; } - PGXP_GetVertices(addr, vertex); - vertex[0].x+=PSXDisplay.CumulOffset.x; vertex[1].x+=PSXDisplay.CumulOffset.x; vertex[2].x+=PSXDisplay.CumulOffset.x; @@ -1124,6 +1124,8 @@ BOOL offset3(unsigned int* addr) vertex[1].y+=PSXDisplay.CumulOffset.y; vertex[2].y+=PSXDisplay.CumulOffset.y; + PGXP_GetVertices(addr, vertex, PSXDisplay.CumulOffset.x, PSXDisplay.CumulOffset.y); + return FALSE; } @@ -1168,8 +1170,6 @@ BOOL offset4(unsigned int* addr) vertex[3].x=lx3; vertex[3].y=ly3; } - - PGXP_GetVertices(addr, vertex); vertex[0].x+=PSXDisplay.CumulOffset.x; vertex[1].x+=PSXDisplay.CumulOffset.x; @@ -1180,12 +1180,14 @@ BOOL offset4(unsigned int* addr) vertex[2].y+=PSXDisplay.CumulOffset.y; vertex[3].y+=PSXDisplay.CumulOffset.y; + PGXP_GetVertices(addr, vertex, PSXDisplay.CumulOffset.x, PSXDisplay.CumulOffset.y); + return FALSE; } ///////////////////////////////////////////////////////// -void offsetST(void) +void offsetST(unsigned int* addr) { if(bDisplayNotSet) SetOGLDisplaySettings(1); @@ -1215,6 +1217,8 @@ void offsetST(void) vertex[1].y=ly1+PSXDisplay.CumulOffset.y; vertex[2].y=ly2+PSXDisplay.CumulOffset.y; vertex[3].y=ly3+PSXDisplay.CumulOffset.y; + + PGXP_GetVertices(addr, vertex, PSXDisplay.CumulOffset.x, PSXDisplay.CumulOffset.y); } ///////////////////////////////////////////////////////// @@ -1282,7 +1286,7 @@ void offsetScreenUpload(int Position) ///////////////////////////////////////////////////////// -void offsetBlk(void) +void offsetBlk(unsigned int* addr) { if(bDisplayNotSet) SetOGLDisplaySettings(1); @@ -1296,6 +1300,8 @@ void offsetBlk(void) vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0; vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0; + PGXP_GetVertices(addr, vertex, PreviousPSXDisplay.Range.x0, PreviousPSXDisplay.Range.y0); + if(iUseMask) { vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z; diff --git a/plugins/peopsxgl/draw.h b/plugins/peopsxgl/draw.h index 2f524904..f50504da 100755 --- a/plugins/peopsxgl/draw.h +++ b/plugins/peopsxgl/draw.h @@ -39,8 +39,8 @@ BOOL offset2(unsigned int* addr); BOOL offset3(unsigned int* addr); BOOL offset4(unsigned int* addr); BOOL offsetline(unsigned int* addr); -void offsetST(void); -void offsetBlk(void); +void offsetST(unsigned int* addr); +void offsetBlk(unsigned int* addr); void offsetScreenUpload(int Position); void assignTexture3(void); void assignTexture4(void); diff --git a/plugins/peopsxgl/gpu.c b/plugins/peopsxgl/gpu.c index 65e074d5..e38ac48b 100755 --- a/plugins/peopsxgl/gpu.c +++ b/plugins/peopsxgl/gpu.c @@ -1314,8 +1314,11 @@ void SetScanLines(void) } glLoadIdentity(); - glOrtho(0,PSXDisplay.DisplayMode.x, - PSXDisplay.DisplayMode.y, 0, -1, 1); + //glOrtho(0,PSXDisplay.DisplayMode.x, + // PSXDisplay.DisplayMode.y, 0, -1, 1); + + PGXP_SetMatrix(0, PSXDisplay.DisplayMode.x, PSXDisplay.DisplayMode.y, 0, -1, 1); + if(bKeepRatio) glViewport(rRatioRect.left, @@ -1889,8 +1892,12 @@ void updateDisplayIfChanged(void) else // some res change? { glLoadIdentity(); - glOrtho(0,PSXDisplay.DisplayModeNew.x, // -> new psx resolution - PSXDisplay.DisplayModeNew.y, 0, -1, 1); + //glOrtho(0,PSXDisplay.DisplayModeNew.x, // -> new psx resolution + // PSXDisplay.DisplayModeNew.y, 0, -1, 1); + + PGXP_SetMatrix(0, PSXDisplay.DisplayModeNew.x, PSXDisplay.DisplayModeNew.y, 0, -1, 1); + + if(bKeepRatio) SetAspectRatio(); } @@ -2985,6 +2992,11 @@ void CALLBACK GPUwriteDataMem(uint32_t *pMem, int iSize) if(gpuDataP == gpuDataC) { gpuDataC=gpuDataP=0; + for (unsigned int i = 0; i < 4; i++) //iCB: remove stale vertex data + { + vertex[i].x = vertex[i].y = 0.f; + vertex[i].z = 1.f; + } primFunc[gpuCommand]((unsigned char *)gpuDataM); if(dwEmuFixes&0x0001 || dwActFixes&0x20000) // hack for emulating "gpu busy" in some games diff --git a/plugins/peopsxgl/pgxp_gpu.c b/plugins/peopsxgl/pgxp_gpu.c index 1ce67bf8..eedf7b8d 100644 --- a/plugins/peopsxgl/pgxp_gpu.c +++ b/plugins/peopsxgl/pgxp_gpu.c @@ -38,6 +38,7 @@ typedef struct float z; unsigned int valid; unsigned int count; + unsigned int value; } PGXP_vertex; const unsigned int primStrideTable[] = { 1, 2, 1, 2, 2, 3, 2, 3, 0 }; @@ -60,15 +61,55 @@ void PGXP_SetAddress(unsigned int addr) currentAddr = addr; } +void PGXP_SetMatrix(float left, float right, float bottom, float top, float zNear, float zFar) +{ + GLfloat m[16]; + for (unsigned int i = 0; i < 16; ++i) + m[i] = 0.f; + + //if ((right-left) != 0) + //{ + // m[0] = 2 / (right - left); + // m[12] = -((right + left) / (right - left)); + //} + //if ((top-bottom) != 0) + //{ + // m[5] = 2 / (top - bottom); + // m[13] = -((top + bottom) / (top - bottom)); + //} + //m[10] = -2 / (zFar - zNear); + //m[14] = -((zFar + zNear) / (zFar - zNear)); + //m[15] = 1; + + if ((right-left) != 0) + { + m[0] = 2 / (right - left); + m[8] = -((right + left) / (right - left)); + } + if ((top-bottom) != 0) + { + m[5] = 2 / (top - bottom); + m[9] = -((top + bottom) / (top - bottom)); + } + m[10] = -2 / (zFar - zNear); + m[14] = -((zFar + zNear) / (zFar - zNear)); + m[11] = 1; + + glLoadMatrixf(m); + //glOrtho(left, right, bottom, top, zNear, zFar); +} + // Get parallel vertex values -int PGXP_GetVertices(unsigned int* addr, void* pOutput) +int PGXP_GetVertices(unsigned int* addr, void* pOutput, int xOffs, int yOffs) { - unsigned int primCmd = ((*addr >> 24) & 0xff); // primitive command - unsigned int primIdx = min((primCmd - 0x20) >> 2, 8); // index to primitive lookup - OGLVertex* pVertex = (OGLVertex*)pOutput; // pointer to output vertices - unsigned int stride = primStrideTable[primIdx]; // stride between vertices - unsigned int count = primCountTable[primIdx]; // number of vertices - PGXP_vertex* primStart = NULL; // pointer to first vertex + unsigned int primCmd = ((*addr >> 24) & 0xff); // primitive command + unsigned int primIdx = min((primCmd - 0x20) >> 2, 8); // index to primitive lookup + OGLVertex* pVertex = (OGLVertex*)pOutput; // pointer to output vertices + unsigned int stride = primStrideTable[primIdx]; // stride between vertices + unsigned int count = primCountTable[primIdx]; // number of vertices + PGXP_vertex* primStart = NULL; // pointer to first vertex + char invalidVert = 0; // Number of vertices without valid PGXP values + float w = 0; // W coordinate of transformed vertex if (PGXP_Mem == NULL) return 0; @@ -76,12 +117,27 @@ int PGXP_GetVertices(unsigned int* addr, void* pOutput) // Offset to start of primitive primStart = &PGXP_Mem[currentAddr + 1]; + // Find any invalid vertices for (unsigned i = 0; i < count; ++i) { + if(!primStart[stride * i].valid) + invalidVert++; + } + + for (unsigned i = 0; i < count; ++i) + { + w = primStart[stride * i].z; + // If there are any invalid vertices set all w values to 1 + // iCB: Could use plane equation to find w for single invalid vertex in a quad + if (invalidVert > 0) + w = 1; + if (primStart[stride * i].valid) { - pVertex[i].x = primStart[stride * i].x; - pVertex[i].y = primStart[stride * i].y; + // Premultiply x,y coorindates by w because they've already been divided by w + pVertex[i].x = (primStart[stride * i].x + xOffs) * w; + pVertex[i].y = (primStart[stride * i].y + yOffs) * w; + pVertex[i].z = w; } } diff --git a/plugins/peopsxgl/pgxp_gpu.h b/plugins/peopsxgl/pgxp_gpu.h index 3c60cd87..35fb5698 100644 --- a/plugins/peopsxgl/pgxp_gpu.h +++ b/plugins/peopsxgl/pgxp_gpu.h @@ -28,7 +28,8 @@ #ifndef _PGXP_GPU_H_ #define _PGXP_GPU_H_ +void PGXP_SetMatrix(float left, float right, float bottom, float top, float zNear, float zFar); void PGXP_SetAddress(unsigned int addr); -int PGXP_GetVertices(unsigned int* addr, void* pOutput); +int PGXP_GetVertices(unsigned int* addr, void* pOutput, int xOffs, int yOffs); #endif // _PGXP_GPU_H_ diff --git a/plugins/peopsxgl/prim.c b/plugins/peopsxgl/prim.c index 0c78145d..adf6380e 100755 --- a/plugins/peopsxgl/prim.c +++ b/plugins/peopsxgl/prim.c @@ -1936,7 +1936,7 @@ void primBlkFill(unsigned char * baseAddr) lx0 = lx3 = sprtX; lx1 = lx2 = (sprtX+sprtW); - offsetBlk(); + offsetBlk(baseAddr); if(ClipVertexListScreen()) { @@ -2283,7 +2283,7 @@ void primTileS(unsigned char * baseAddr) lx0 = sprtX; ly0 = sprtY; - offsetST(); + offsetST(baseAddr); if((dwActFixes&1) && // FF7 special game gix (battle cursor) sprtX==0 && sprtY==0 && sprtW==24 && sprtH==16) @@ -2346,7 +2346,7 @@ void primTile1(unsigned char * baseAddr) lx0 = sprtX; ly0 = sprtY; - offsetST(); + offsetST(baseAddr); bDrawTextured = FALSE; bDrawSmoothShaded = FALSE; @@ -2393,7 +2393,7 @@ void primTile8(unsigned char * baseAddr) lx0 = sprtX; ly0 = sprtY; - offsetST(); + offsetST(baseAddr); bDrawTextured = FALSE; bDrawSmoothShaded = FALSE; @@ -2440,7 +2440,7 @@ void primTile16(unsigned char * baseAddr) lx0 = sprtX; ly0 = sprtY; - offsetST(); + offsetST(baseAddr); bDrawTextured = FALSE; bDrawSmoothShaded = FALSE; @@ -2555,7 +2555,7 @@ void primSprt8(unsigned char * baseAddr) lx0 = sprtX; ly0 = sprtY; - offsetST(); + offsetST(baseAddr); // do texture stuff gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff; @@ -2676,7 +2676,7 @@ void primSprt16(unsigned char * baseAddr) lx0 = sprtX; ly0 = sprtY; - offsetST(); + offsetST(baseAddr); // do texture stuff gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff; @@ -2878,7 +2878,7 @@ void primSprtSRest(unsigned char * baseAddr,unsigned short type) lx0 = sprtX; ly0 = sprtY; - offsetST(); + offsetST(baseAddr); ulClutID=(gpuData[2]>>16); @@ -3008,7 +3008,7 @@ void primSprtS(unsigned char * baseAddr) lx0 = sprtX; ly0 = sprtY; - offsetST(); + offsetST(baseAddr); ulClutID=(gpuData[2]>>16);