summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authoriCatButler <i.am.catbutler@gmail.com>2016-04-27 12:18:13 +0100
committeriCatButler <i.am.catbutler@gmail.com>2016-04-27 12:18:13 +0100
commit153c8eb4997d21d3b2965cf38d4348f05c29860f (patch)
tree994a8995a888c47eacb6d650f8c28c0c631d3c50 /plugins
parent580df75296286b65812afdac64d82054279fb235 (diff)
Perspective correct texturing
- replace calls to glOrtho with new matrix (z value becomes w) - store w value for each vertex - if any vertex does not have a w value set whole polygon to 1.0 - Reset vertex between draw calls to prevent stale w values persisting - validate PGXP values using stored copy of original (allow greater variance) - properly convert addresses before passing to plugin - rework memory to use a single pool with offsets - Implement floating point RTPS/RTPT transform, currently disabled.
Diffstat (limited to 'plugins')
-rwxr-xr-xplugins/peopsxgl/draw.c30
-rwxr-xr-xplugins/peopsxgl/draw.h4
-rwxr-xr-xplugins/peopsxgl/gpu.c20
-rw-r--r--plugins/peopsxgl/pgxp_gpu.c74
-rw-r--r--plugins/peopsxgl/pgxp_gpu.h3
-rwxr-xr-xplugins/peopsxgl/prim.c18
6 files changed, 112 insertions, 37 deletions
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 @@ ENDVRAM:
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);