mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-15 02:29:51 +01:00
More darkstalkers work
This commit is contained in:
1 parent
d4563a4a62
commit
7fbfcca2fe
2 files changed
+65
-32
No files matched your search
+16
-26
@@ -49,16 +49,11 @@ static inline int CalcClipMask(const ClipCoords& v)
|
||||
return mask;
|
||||
}
|
||||
|
||||
#define AddInterpolatedVertex(t, out, in, numVertices) \
|
||||
{ \
|
||||
Vertices[numVertices++]->Lerp(t, *Vertices[out], *Vertices[in]); \
|
||||
}
|
||||
|
||||
inline bool DIFFERENT_SIGNS(float x, float y) {
|
||||
inline bool different_signs(float x, float y) {
|
||||
return ((x <= 0 && y > 0) || (x > 0 && y <= 0));
|
||||
}
|
||||
|
||||
inline float CLIP_DOTPROD(const VertexData &vert, float A, float B, float C, float D) {
|
||||
inline float clip_dotprod(const VertexData &vert, float A, float B, float C, float D) {
|
||||
return (vert.clippos.x * A + vert.clippos.y * B + vert.clippos.z * C + vert.clippos.w * D);
|
||||
}
|
||||
|
||||
@@ -66,24 +61,24 @@ inline float CLIP_DOTPROD(const VertexData &vert, float A, float B, float C, flo
|
||||
{ \
|
||||
if (mask & PLANE_BIT) { \
|
||||
int idxPrev = inlist[0]; \
|
||||
float dpPrev = CLIP_DOTPROD(*Vertices[idxPrev], A, B, C, D );\
|
||||
float dpPrev = clip_dotprod(*Vertices[idxPrev], A, B, C, D );\
|
||||
int outcount = 0; \
|
||||
\
|
||||
inlist[n] = inlist[0]; \
|
||||
for (int j = 1; j <= n; j++) { \
|
||||
int idx = inlist[j]; \
|
||||
float dp = CLIP_DOTPROD(*Vertices[idx], A, B, C, D ); \
|
||||
float dp = clip_dotprod(*Vertices[idx], A, B, C, D ); \
|
||||
if (dpPrev >= 0) { \
|
||||
outlist[outcount++] = idxPrev; \
|
||||
} \
|
||||
\
|
||||
if (DIFFERENT_SIGNS(dp, dpPrev)) { \
|
||||
if (different_signs(dp, dpPrev)) { \
|
||||
if (dp < 0) { \
|
||||
float t = dp / (dp - dpPrev); \
|
||||
AddInterpolatedVertex(t, idx, idxPrev, numVertices); \
|
||||
Vertices[numVertices++]->Lerp(t, *Vertices[idx], *Vertices[idxPrev]); \
|
||||
} else { \
|
||||
float t = dpPrev / (dpPrev - dp); \
|
||||
AddInterpolatedVertex(t, idxPrev, idx, numVertices); \
|
||||
Vertices[numVertices++]->Lerp(t, *Vertices[idxPrev], *Vertices[idx]); \
|
||||
} \
|
||||
outlist[outcount++] = numVertices - 1; \
|
||||
} \
|
||||
@@ -107,24 +102,22 @@ inline float CLIP_DOTPROD(const VertexData &vert, float A, float B, float C, flo
|
||||
#define CLIP_LINE(PLANE_BIT, A, B, C, D) \
|
||||
{ \
|
||||
if (mask & PLANE_BIT) { \
|
||||
float dp0 = CLIP_DOTPROD(*Vertices[0], A, B, C, D ); \
|
||||
float dp1 = CLIP_DOTPROD(*Vertices[1], A, B, C, D ); \
|
||||
int i = 0; \
|
||||
float dp0 = clip_dotprod(*Vertices[0], A, B, C, D ); \
|
||||
float dp1 = clip_dotprod(*Vertices[1], A, B, C, D ); \
|
||||
int numVertices = 0; \
|
||||
\
|
||||
if (mask0 & PLANE_BIT) { \
|
||||
if (dp0 < 0) { \
|
||||
float t = dp1 / (dp1 - dp0); \
|
||||
i = 0; \
|
||||
AddInterpolatedVertex(t, 1, 0, i); \
|
||||
Vertices[0]->Lerp(t, *Vertices[1], *Vertices[0]); \
|
||||
} \
|
||||
} \
|
||||
dp0 = CLIP_DOTPROD(*Vertices[0], A, B, C, D ); \
|
||||
dp0 = clip_dotprod(*Vertices[0], A, B, C, D ); \
|
||||
\
|
||||
if (mask1 & PLANE_BIT) { \
|
||||
if (dp1 < 0) { \
|
||||
float t = dp1 / (dp1- dp0); \
|
||||
i = 1; \
|
||||
AddInterpolatedVertex(t, 1, 0, i); \
|
||||
Vertices[1]->Lerp(t, *Vertices[1], *Vertices[0]); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
@@ -185,17 +178,14 @@ void ProcessRect(const VertexData& v0, const VertexData& v1)
|
||||
} else {
|
||||
// through mode handling
|
||||
|
||||
// Check for simple case: No depth, alpha != 0 testing only, no blend, texture mapping 1:1 etc.
|
||||
// Also check for scissor rectangle etc.
|
||||
// That is, state commonly used in PSX games and ports like Darkstalker.
|
||||
// In that case we can call DrawPSXSprite.
|
||||
// Check for 1:1 texture mapping. In that case we can call DrawSprite.
|
||||
int xdiff = v1.screenpos.x - v0.screenpos.x;
|
||||
int ydiff = v1.screenpos.y - v0.screenpos.y;
|
||||
int udiff = (v1.texturecoords.x - v0.texturecoords.x) * 16.0f;
|
||||
int vdiff = (v1.texturecoords.y - v0.texturecoords.y) * 16.0f;
|
||||
bool coord_check =
|
||||
(xdiff == udiff /* || xdiff == -udiff*/) &&
|
||||
(ydiff == vdiff /* || ydiff == -vdiff*/);
|
||||
(xdiff == udiff || xdiff == -udiff) &&
|
||||
(ydiff == vdiff || ydiff == -vdiff);
|
||||
// TODO: The U/V mirror support is off by one somehow. Predecrement?
|
||||
|
||||
/*
|
||||
|
||||
@@ -1287,8 +1287,20 @@ void DrawTriangleSlice(
|
||||
}
|
||||
}
|
||||
|
||||
// Slow but can handle all input.
|
||||
void SafeScanline(int s, int ds, int t, int x1, int x2, int y, int z, const u8 *texptr, int texbufw, Sampler::Funcs &sampler, Vec4<int> v0_color) {
|
||||
for (int x = x1; x < x2; x++) {
|
||||
Vec4<int> prim_color = v0_color;
|
||||
Vec4<int> tex_color = Vec4<int>::FromRGBA(sampler.nearest(s, t, texptr, texbufw, 0));
|
||||
prim_color = GetTextureFunctionOutput(prim_color, tex_color);
|
||||
DrawingCoords pos(x, y, z);
|
||||
DrawSinglePixel<false>(pos, (u16)z, 1.0f, prim_color);
|
||||
s += ds;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawPSXSprite(const VertexData& v0, const VertexData& v1) {
|
||||
u8 *texptr = nullptr;
|
||||
const u8 *texptr = nullptr;
|
||||
|
||||
GETextureFormat texfmt = gstate.getTextureFormat();
|
||||
u32 texaddr = gstate.getTextureAddress(0);
|
||||
@@ -1302,17 +1314,44 @@ void DrawPSXSprite(const VertexData& v0, const VertexData& v1) {
|
||||
DrawingCoords pos0 = TransformUnit::ScreenToDrawing(v0.screenpos);
|
||||
DrawingCoords pos1 = TransformUnit::ScreenToDrawing(v1.screenpos);
|
||||
|
||||
DrawingCoords scissorTL(gstate.getScissorX1(), gstate.getScissorY1(), 0);
|
||||
DrawingCoords scissorBR(gstate.getScissorX2(), gstate.getScissorY2(), 0);
|
||||
|
||||
int z = pos0.z;
|
||||
float fog = 1.0f;
|
||||
|
||||
if (gstate.isTextureMapEnabled()) {
|
||||
// 1:1 (but with mirror support) texture mapping!
|
||||
int s = v0.texturecoords.x;
|
||||
int t = v0.texturecoords.y;
|
||||
int s_start = v0.texturecoords.x;
|
||||
int t_start = v0.texturecoords.y;
|
||||
int ds = v1.texturecoords.x > v0.texturecoords.x ? 1 : -1;
|
||||
int dt = v1.texturecoords.y > v0.texturecoords.y ? 1 : -1;
|
||||
|
||||
if (ds < 0) {
|
||||
s_start += ds;
|
||||
}
|
||||
if (dt < 0) {
|
||||
t_start += dt;
|
||||
}
|
||||
|
||||
// First clip the right and bottom sides, since we don't need to adjust the deltas.
|
||||
if (pos1.x > scissorBR.x) pos1.x = scissorBR.x;
|
||||
if (pos1.y > scissorBR.y) pos1.y = scissorBR.y;
|
||||
// Now clip the other sides.
|
||||
if (pos0.x < scissorTL.x) {
|
||||
s_start += (scissorTL.x - pos0.x) * ds;
|
||||
pos0.x = scissorTL.x;
|
||||
}
|
||||
if (pos0.y < scissorTL.y) {
|
||||
t_start += (scissorTL.y - pos0.y) * dt;
|
||||
pos0.y = scissorTL.y;
|
||||
}
|
||||
|
||||
int t = t_start;
|
||||
for (int y = pos0.y; y < pos1.y; y++) {
|
||||
s = v0.texturecoords.x;
|
||||
int s = s_start;
|
||||
SafeScanline(s, ds, t, pos0.x, pos1.x, y, z, texptr, texbufw, sampler, v0.color0);
|
||||
/*
|
||||
for (int x = pos0.x; x < pos1.x; x++) {
|
||||
Vec4<int> prim_color = v0.color0;
|
||||
Vec4<int> tex_color = Vec4<int>::FromRGBA(sampler.nearest(s, t, texptr, texbufw, 0));
|
||||
@@ -1321,10 +1360,14 @@ void DrawPSXSprite(const VertexData& v0, const VertexData& v1) {
|
||||
DrawSinglePixel<false>(pos, (u16)z, fog, prim_color);
|
||||
s += ds;
|
||||
}
|
||||
*/
|
||||
t += dt;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (pos1.x > scissorBR.x) pos1.x = scissorBR.x;
|
||||
if (pos1.y > scissorBR.y) pos1.y = scissorBR.y;
|
||||
if (pos0.x < scissorTL.x) pos0.x = scissorTL.x;
|
||||
if (pos0.y < scissorTL.y) pos0.y = scissorTL.y;
|
||||
for (int y = pos0.y; y < pos1.y; y++) {
|
||||
for (int x = pos0.x; x < pos1.x; x++) {
|
||||
Vec4<int> prim_color = v0.color0;
|
||||
|
||||
Reference in new issue
Block a user