Posts: 8.597
Threads: 105
Joined: May 2014
Reputation:
169
Location: 127.0.0.1
12-21-2016, 01:45 PM
(This post was last modified: 12-21-2016, 01:45 PM by ssakash.)
I just took a look into the dump, definitely a PCRTC issue. Monitoring the scissor registers, the draw limit on height seems to be from 0-240 but the DISP register seems to be alternating between 464 and 480 repeatedly, on double scan mode they're 232 and 240 which causes the screen to shake.
Hardware tests ought to be done to validate PS2 behavior when DISP registers are alternating back and forth without stabilizing on a single output circuit dimension, IIRC FBW also had a similar case with some Tennis games and Resident Evil games.
We're supposed to be working as a team, if we aren't helping and suggesting things to each other, we aren't working as a team.
- Refraction
Posts: 8.597
Threads: 105
Joined: May 2014
Reputation:
169
Location: 127.0.0.1
12-21-2016, 06:34 PM
(This post was last modified: 12-21-2016, 06:40 PM by ssakash.
Edit Reason: Oops. fix a mistake in the patch.
)
Well, I tried something hacky and the game seems to be fine on the GS dump replayer. Could you check if the issue doesn't occur when playing the game from the emulator? Checking for regression on places other than FMV would also be nice.
GSdx plugin download link for testing:
https://www.dropbox.com/s/o4xb7n2z1fo6a1...2.dll?dl=0
My applied patch for reference
Code:
diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp
index 74b7110..b0f8a9f 100644
--- a/plugins/GSdx/GSState.cpp
+++ b/plugins/GSdx/GSState.cpp
@@ -443,25 +443,39 @@ GSVector4i GSState::GetFrameRect(int i)
{
if (i < 0) i = IsEnabled(1) ? 1 : 0;
+ const bool double_scan_mode = isinterlaced() && m_regs->SMODE2.FFMD;
+ const int scissor_height = static_cast<int>(m_context->SCISSOR.SCAY1 + 1);
+ static int previous_frame_height;
GSVector4i rectangle = GetDisplayRect(i);
int w = rectangle.width();
int h = rectangle.height();
- if (isinterlaced() && m_regs->SMODE2.FFMD && h > 1)
- h >>= 1;
+ if (double_scan_mode)
+ h /= 2;
rectangle.left = m_regs->DISP[i].DISPFB.DBX;
rectangle.top = m_regs->DISP[i].DISPFB.DBY;
rectangle.right = rectangle.left + w;
rectangle.bottom = rectangle.top + h;
+ // The game Mizuiro or whatever it's name was seems to constantly alter it's DH value in DISP register
+ // when an FMV is running, the constant altering of the value causes the screen to shake vertically
+ // To prevent such constant change to the output circuit height, let's prevent the modification to height
+ // when the scissor is equivalent to the previous stabilized height value and most importantly, only at cases
+ // where the scissor has a height value lower than the base display circuit height. (probably not needed but
+ // doesn't hurt to be in the safe side, I guess?)
+ if (double_scan_mode && rectangle.height() != scissor_height && scissor_height < GetDisplayRect(i).height() &&+ scissor_height == previous_frame_height)
+ rectangle.bottom = rectangle.top + scissor_height;
+
/*static GSVector4i old_r = (GSVector4i) 0;
if ((old_r.left != r.left) || (old_r.right != r.right) || (old_r.top != r.top) || (old_r.right != r.right)){
printf("w %d h %d left %d top %d right %d bottom %d\n",w,h,r.left,r.top,r.right,r.bottom);
}
old_r = r;*/
+ previous_frame_height = rectangle.height();
However I don't think the above patch is ideal for detecting such cases on PS2 games using alternating DH values, potentially there's a much better and less hacky way.
We're supposed to be working as a team, if we aren't helping and suggesting things to each other, we aren't working as a team.
- Refraction
Posts: 3
Threads: 1
Joined: Dec 2016
Reputation:
0
Wow!!
Works fine like a charm!
Both FMV part and other part works excellent.
Thank you very very much, detective Conan :-) !
Posts: 1.516
Threads: 26
Joined: Jan 2016
Reputation:
42
Thank you for your report.
This bug report has now been marked as Resolved since it has been fixed on our code base.
This thread will now be closed and moved to the resolved bug reports subforum.