diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index ee8dd8cf70..c789d5e1b7 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -1287,26 +1287,26 @@ void DrawTriangleSlice( } } - // Through mode, with the specific Darkstalker settings. inline void DrawSinglePixel5551(const DrawingCoords &p, const Vec4 &color_in) { - Vec4 prim_color = color_in; - if (prim_color.a() == 0) + if (color_in.a() == 0) return; - const u32 old_color = GetPixelColor(p.x, p.y); + u16 *pixel = fb.Get16Ptr(p.x, p.y, gstate.FrameBufStride()); + u32 new_color; + if (color_in.a() == 255) { + const u32 old_color = RGBA5551ToRGBA8888(*pixel); + const Vec4 dst = Vec4::FromRGBA(old_color); + Vec3 blended = AlphaBlendingResult(color_in, dst); + // ToRGB() always automatically clamps. + new_color = blended.ToRGB(); + } else { + new_color = color_in.ToRGBA() & 0xFFFFFF; + } - u8 stencil = GetPixelStencil(p.x, p.y); - - const Vec4 dst = Vec4::FromRGBA(old_color); - Vec3 blended = AlphaBlendingResult(prim_color, dst); - - // ToRGB() always automatically clamps. - new_color = blended.ToRGB(); - new_color |= stencil << 24; - new_color = (new_color & ~gstate.getColorMask()) | (old_color & gstate.getColorMask()); - SetPixelColor(p.x, p.y, new_color); + new_color |= (*pixel & 0x8000) ? 0xff000000 : 0x00000000; + *pixel = RGBA8888ToRGBA5551(new_color); } static inline Vec4 ModulateRGBA(const Vec4& prim_color, const Vec4& texcolor) { @@ -1339,7 +1339,6 @@ static inline Vec4 ModulateRGBA(const Vec4& prim_color, const Vec4(255, 255, 255, 255); + if (gstate.isTextureMapEnabled()) { // 1:1 (but with mirror support) texture mapping! int s_start = v0.texturecoords.x; @@ -1399,18 +1400,27 @@ void DrawSprite(const VertexData& v0, const VertexData& v1) { gstate.isAlphaBlendEnabled() && gstate.isTextureAlphaUsed() && gstate.getTextureFunction() == GE_TEXFUNC_MODULATE && + gstate.getColorMask() == 0x000000 && gstate.FrameBufFormat() == GE_FORMAT_5551) { int t = t_start; for (int y = pos0.y; y < pos1.y; y++) { int s = s_start; - // Not really that fast but faster than triangle. - for (int x = pos0.x; x < pos1.x; x++) { - Vec4 prim_color = v0.color0; - Vec4 tex_color = Vec4::FromRGBA(nearestFunc(s, t, texptr, texbufw, 0)); - prim_color = ModulateRGBA(prim_color, tex_color); - DrawingCoords pos(x, y, z); - DrawSinglePixel5551(pos, prim_color); - s += ds; + if (isWhite) { + for (int x = pos0.x; x < pos1.x; x++) { + Vec4 tex_color = Vec4::FromRGBA(nearestFunc(s, t, texptr, texbufw, 0)); + DrawingCoords pos(x, y, z); + DrawSinglePixel5551(pos, tex_color); + s += ds; + } + } else { + for (int x = pos0.x; x < pos1.x; x++) { + Vec4 prim_color = v0.color0; + Vec4 tex_color = Vec4::FromRGBA(nearestFunc(s, t, texptr, texbufw, 0)); + prim_color = ModulateRGBA(prim_color, tex_color); + DrawingCoords pos(x, y, z); + DrawSinglePixel5551(pos, prim_color); + s += ds; + } } t += dt; } @@ -1435,11 +1445,34 @@ void DrawSprite(const VertexData& v0, const VertexData& v1) { 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 prim_color = v0.color0; - DrawingCoords pos(x, y, z); - DrawSinglePixel(pos, (u16)z, fog, prim_color); + if (!gstate.isStencilTestEnabled() && + !gstate.isDepthTestEnabled() && + !gstate.isLogicOpEnabled() && + !gstate.isColorTestEnabled() && + !gstate.isDitherEnabled() && + gstate.isAlphaTestEnabled() && + gstate.getAlphaTestRef() == 0 && + gstate.getAlphaTestMask() == 0xFF && + gstate.isAlphaBlendEnabled() && + gstate.isTextureAlphaUsed() && + gstate.getTextureFunction() == GE_TEXFUNC_MODULATE && + gstate.getColorMask() == 0x000000 && + gstate.FrameBufFormat() == GE_FORMAT_5551) { + + for (int y = pos0.y; y < pos1.y; y++) { + for (int x = pos0.x; x < pos1.x; x++) { + Vec4 prim_color = v0.color0; + DrawingCoords pos(x, y, z); + DrawSinglePixel5551(pos, prim_color); + } + } + } else { + for (int y = pos0.y; y < pos1.y; y++) { + for (int x = pos0.x; x < pos1.x; x++) { + Vec4 prim_color = v0.color0; + DrawingCoords pos(x, y, z); + DrawSinglePixel(pos, (u16)z, fog, prim_color); + } } } } diff --git a/GPU/Software/SoftGpu.h b/GPU/Software/SoftGpu.h index c7d4f9365e..02660b5576 100644 --- a/GPU/Software/SoftGpu.h +++ b/GPU/Software/SoftGpu.h @@ -44,6 +44,10 @@ struct FormatBuffer { inline u32 Get32(int x, int y, int stride) { return as32[x + y * stride]; } + + inline u16 *Get16Ptr(int x, int y, int stride) { + return &as16[x + y * stride]; + } }; class SoftwareDrawEngine;