summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/BPStructs.cpp
diff options
context:
space:
mode:
authorScott Mansell <phiren@gmail.com>2021-09-12 04:44:25 +1200
committerScott Mansell <phiren@gmail.com>2021-09-15 02:31:38 +1200
commit37b80e21707fe9288d3a5f47fe0ab0a9454b744b (patch)
treed3d81cfb4a81a2e99816d6c13b950b969291ca8a /Source/Core/VideoCommon/BPStructs.cpp
parent1b32a61d6a47e748e024a62a6f856b21ec635294 (diff)
BPStructs: fix out-of-range EFB copy clamping
Previous code from #7950 only clamps correctly when the efb copies left and top coordinates are (0, 0) Now we should handle all situations. Spyro: A hero's tail is an example of a game that does an oversized EFB copy with a non-zero origin.
Diffstat (limited to 'Source/Core/VideoCommon/BPStructs.cpp')
-rw-r--r--Source/Core/VideoCommon/BPStructs.cpp28
1 files changed, 11 insertions, 17 deletions
diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp
index 97c78474e1..b00315f9da 100644
--- a/Source/Core/VideoCommon/BPStructs.cpp
+++ b/Source/Core/VideoCommon/BPStructs.cpp
@@ -3,6 +3,7 @@
#include "VideoCommon/BPStructs.h"
+#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
@@ -237,27 +238,20 @@ static void BPWritten(const BPCmd& bp)
// writing the junk data, we don't write anything to RAM at all for over-sized copies, and clamp
// to the EFB borders for over-offset copies. The arcade virtual console games (e.g. 1942) are
// known for configuring these out-of-range copies.
- u32 copy_width = srcRect.GetWidth();
- u32 copy_height = srcRect.GetHeight();
- if (srcRect.right > EFB_WIDTH || srcRect.bottom > EFB_HEIGHT)
+
+ if (u32(srcRect.right) > EFB_WIDTH || u32(srcRect.bottom) > EFB_HEIGHT)
{
- WARN_LOG_FMT(VIDEO, "Oversized EFB copy: {}x{} (offset {},{} stride {})", copy_width,
- copy_height, srcRect.left, srcRect.top, destStride);
+ WARN_LOG_FMT(VIDEO, "Oversized EFB copy: {}x{} (offset {},{} stride {})", srcRect.GetWidth(),
+ srcRect.GetHeight(), srcRect.left, srcRect.top, destStride);
- // Adjust the copy size to fit within the EFB. So that we don't end up with a stretched image,
- // instead of clamping the source rectangle, we reduce it by the over-sized amount.
- if (copy_width > EFB_WIDTH)
- {
- srcRect.right -= copy_width - EFB_WIDTH;
- copy_width = EFB_WIDTH;
- }
- if (copy_height > EFB_HEIGHT)
- {
- srcRect.bottom -= copy_height - EFB_HEIGHT;
- copy_height = EFB_HEIGHT;
- }
+ // Clamp the copy region to fit within EFB. So that we don't end up with a stretched image.
+ srcRect.right = std::clamp<int>(srcRect.right, 0, EFB_WIDTH);
+ srcRect.bottom = std::clamp<int>(srcRect.bottom, 0, EFB_HEIGHT);
}
+ u32 copy_width = srcRect.GetWidth();
+ u32 copy_height = srcRect.GetHeight();
+
// Check if we are to copy from the EFB or draw to the XFB
const UPE_Copy PE_copy = bpmem.triggerEFBCopy;
if (PE_copy.copy_to_xfb == 0)