diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index 1a9c994701..3eb751436b 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -130,7 +130,7 @@ enum UtilityDialogType { // Only a single dialog is allowed at a time. static UtilityDialogType currentDialogType; -static bool currentDialogActive; +bool currentDialogActive; static PSPSaveDialog saveDialog; static PSPMsgDialog msgDialog; static PSPOskDialog oskDialog; diff --git a/GPU/Software/Clipper.cpp b/GPU/Software/Clipper.cpp index 548d9e3dfd..6d22d2e7ee 100644 --- a/GPU/Software/Clipper.cpp +++ b/GPU/Software/Clipper.cpp @@ -28,6 +28,8 @@ extern bool g_DarkStalkerStretch; +// For Darkstalkers hack. Ugh. +extern bool currentDialogActive; namespace Clipper { @@ -139,8 +141,11 @@ static void RotateUVThrough(const VertexData &tl, const VertexData &br, VertexDa } } +bool needsClear = false; + void ProcessRect(const VertexData& v0, const VertexData& v1) { + g_DarkStalkerStretch = false; if (!gstate.isModeThrough()) { VertexData buf[4]; buf[0].clippos = ClipCoords(v0.clippos.x, v0.clippos.y, v1.clippos.z, v1.clippos.w); @@ -191,23 +196,8 @@ void ProcessRect(const VertexData& v0, const VertexData& v1) bool coord_check = (xdiff == udiff || xdiff == -udiff) && (ydiff == vdiff || ydiff == -vdiff); - // TODO: The U/V mirror support is off by one somehow. Predecrement? - - /* - bool state_check = - !gstate.isModeClear() && - !gstate.isFogEnabled() && - gstate.isTextureMapEnabled() && - !gstate.isDepthTestEnabled() && - !gstate.isStencilTestEnabled(); - bool alpha_check = - gstate.getAlphaTestFunction() == GEComparison::GE_COMP_GREATER && - gstate.getAlphaTestMask() == 0xFF && - gstate.getAlphaTestRef() == 0; - */ - bool state_check = !gstate.isModeClear(); - bool alpha_check = true; - if ((coord_check || !gstate.isTextureMapEnabled()) && state_check && alpha_check) { + bool state_check = !gstate.isModeClear(); // TODO: Add support for clear modes in Rasterizer::DrawSprite. + if ((coord_check || !gstate.isTextureMapEnabled()) && state_check) { Rasterizer::DrawSprite(v0, v1); return; } @@ -215,8 +205,24 @@ void ProcessRect(const VertexData& v0, const VertexData& v1) // Eliminate the stretch blit in DarkStalkers. // We compensate for that when blitting the framebuffer in SoftGpu.cpp. if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && v0.texturecoords.x == 64.0f && v0.texturecoords.y == 16.0f && v1.texturecoords.x == 448.0f && v1.texturecoords.y == 240.0f) { - g_DarkStalkerStretch = true; - return; + if (v0.screenpos.x == 0x7100 && v0.screenpos.y == 0x7780 && v1.screenpos.x == 0x8f00 && v1.screenpos.y == 0x8880) { + // Also check for save/load dialog. + if (!currentDialogActive) { + g_DarkStalkerStretch = true; + if (needsClear) { + needsClear = false; + // Afterwards, we also need to clear the actual destination. Can do a fast rectfill. + gstate.textureMapEnable &= ~1; + VertexData newV0 = v0; + newV0.color0 = Vec4(0, 0, 0, 255); + Rasterizer::DrawSprite(newV0, v1); + gstate.textureMapEnable |= 1; + } + return; + } else { + needsClear = true; + } + } // else, handle the Capcom screen stretch, or the non-wide stretch? Or let's just not bother. } VertexData buf[4]; diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index c789d5e1b7..fce5100af3 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -1288,12 +1288,7 @@ void DrawTriangleSlice( } // Through mode, with the specific Darkstalker settings. -inline void DrawSinglePixel5551(const DrawingCoords &p, const Vec4 &color_in) { - if (color_in.a() == 0) - return; - - u16 *pixel = fb.Get16Ptr(p.x, p.y, gstate.FrameBufStride()); - +inline void DrawSinglePixel5551(u16 *pixel, const Vec4 &color_in) { u32 new_color; if (color_in.a() == 255) { const u32 old_color = RGBA5551ToRGBA8888(*pixel); @@ -1377,8 +1372,8 @@ void DrawSprite(const VertexData& v0, const VertexData& v1) { } // 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; + if (pos1.x > scissorBR.x) pos1.x = scissorBR.x + 1; + if (pos1.y > scissorBR.y) pos1.y = scissorBR.y + 1; // Now clip the other sides. if (pos0.x < scissorTL.x) { s_start += (scissorTL.x - pos0.x) * ds; @@ -1405,21 +1400,26 @@ void DrawSprite(const VertexData& v0, const VertexData& v1) { int t = t_start; for (int y = pos0.y; y < pos1.y; y++) { int s = s_start; + u16 *pixel = fb.Get16Ptr(pos0.x, y, gstate.FrameBufStride()); 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); + u32 tex_color = nearestFunc(s, t, texptr, texbufw, 0); + if (tex_color & 0xFF000000) { + DrawSinglePixel5551(pixel, Vec4::FromRGBA(tex_color)); + } s += ds; + pixel++; } } 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); + if (prim_color.a() > 0) { + DrawSinglePixel5551(pixel, prim_color); + } s += ds; + pixel++; } } t += dt; @@ -1458,12 +1458,15 @@ void DrawSprite(const VertexData& v0, const VertexData& v1) { gstate.getTextureFunction() == GE_TEXFUNC_MODULATE && gstate.getColorMask() == 0x000000 && gstate.FrameBufFormat() == GE_FORMAT_5551) { + if (v0.color0.a() == 0) + return; for (int y = pos0.y; y < pos1.y; y++) { + u16 *pixel = fb.Get16Ptr(pos0.x, y, gstate.FrameBufStride()); for (int x = pos0.x; x < pos1.x; x++) { Vec4 prim_color = v0.color0; - DrawingCoords pos(x, y, z); - DrawSinglePixel5551(pos, prim_color); + DrawSinglePixel5551(pixel, prim_color); + pixel++; } } } else { diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 0b715dd952..7254c2ce11 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -198,8 +198,6 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { // RB swapped, compensate with a shader. desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16; pipeline = texColorRBSwizzle; - } else { - // Shouldn't happen (once I'm done with the backends). } desc.width = displayStride_ == 0 ? srcwidth : displayStride_; desc.height = srcheight; @@ -208,7 +206,6 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { u1 = 447.5f / 512.0f; v1 = 16.0f / 272.0f; v0 = 240.0f / 272.0f; - g_DarkStalkerStretch = false; } else if (!Memory::IsValidAddress(displayFramebuf_) || srcwidth == 0 || srcheight == 0) { hasImage = false; u1 = 1.0f; @@ -218,10 +215,17 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { desc.height = srcheight; desc.initData.push_back(data); desc.format = Draw::DataFormat::R8G8B8A8_UNORM; - } else if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN && displayFormat_ == GE_FORMAT_5551) { + } else if (displayFormat_ == GE_FORMAT_5551) { u8 *data = Memory::GetPointer(displayFramebuf_); - desc.swizzle = Draw::TextureSwizzle::BGRA; desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16; + if (draw_->GetDataFormatSupport(Draw::DataFormat::A1B5G5R5_UNORM_PACK16) & Draw::FMT_TEXTURE) { + // The perfect one. + desc.format = Draw::DataFormat::A1B5G5R5_UNORM_PACK16; + } else if (draw_->GetDataFormatSupport(Draw::DataFormat::A1R5G5B5_UNORM_PACK16) & Draw::FMT_TEXTURE) { + // RB swapped, compensate with a shader. + desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16; + pipeline = texColorRBSwizzle; + } desc.width = displayStride_ == 0 ? srcwidth : displayStride_; desc.height = srcheight; desc.initData.push_back(data); diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index fce59694b9..146ea138c0 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -516,16 +516,9 @@ struct DeviceCaps { std::string deviceName; // The device name to use when creating the thin3d context, to get the same one. }; -// Some predefined swizzle -enum class TextureSwizzle { - NO_SWIZZLE = 0, - BGRA = 1, -}; - struct TextureDesc { TextureType type; DataFormat format; - TextureSwizzle swizzle; int width; int height; int depth; diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index cb2fc0d4e8..3222abf2c0 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -700,19 +700,7 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur usageBits |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; } - VkComponentMapping mapping{}; // Defaults to no swizzle - switch (desc.swizzle) { - case TextureSwizzle::NO_SWIZZLE: - break; - case TextureSwizzle::BGRA: - mapping.r = VK_COMPONENT_SWIZZLE_B; - mapping.g = VK_COMPONENT_SWIZZLE_G; - mapping.b = VK_COMPONENT_SWIZZLE_R; - mapping.a = VK_COMPONENT_SWIZZLE_A; - break; - } - - if (!vkTex_->CreateDirect(cmd, alloc, width_, height_, mipLevels_, vulkanFormat, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, usageBits, &mapping)) { + if (!vkTex_->CreateDirect(cmd, alloc, width_, height_, mipLevels_, vulkanFormat, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, usageBits)) { ELOG("Failed to create VulkanTexture: %dx%dx%d fmt %d, %d levels", width_, height_, depth_, (int)vulkanFormat, mipLevels_); return false; }