psx - continue fiddling with framebuffer cropping mode

This commit is contained in:
zeromus 2015-08-02 15:37:04 -05:00
parent eb59470ed8
commit 4e673df06f
5 changed files with 56 additions and 4 deletions

View File

@ -151,4 +151,7 @@ fit gracefully in a 800x480 window.
Using this option may result in objectionable levels of black bars, but will fix some rare quirks in games.
</value>
</data>
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

Binary file not shown.

View File

@ -1437,6 +1437,7 @@ pscpu_timestamp_t PS_GPU::Update(const pscpu_timestamp_t sys_timestamp)
//it's unclear what happens to games displaying a peculiar Y range
if (dump_framebuffer)
{
//printf("%d %d %d\n", VertStart, VertEnd, DisplayOff);
//special hack: if the game (or the bios...) is set to display no range here, don't modify it
//also, as you can see just above, this condition is used to represent an 'off' display
//unfortunately, this will usually be taking effect at dest_line==0, and so the
@ -1448,6 +1449,9 @@ pscpu_timestamp_t PS_GPU::Update(const pscpu_timestamp_t sys_timestamp)
{
dx_start = 0;
dx_end = 2560 / DotClockRatios[dmc];
if(FirstLine == -99)
FirstLine = dest_line;
LineWidths[dest_line] = dx_end - dx_start;
}
}
@ -1535,6 +1539,8 @@ void PS_GPU::StartFrame(EmulateSpecStruct *espec_arg)
LineWidths = espec->LineWidths;
skip = espec->skip;
FirstLine = -99;
if(espec->VideoFormatChanged)
{
const auto& f = surface->format;

View File

@ -334,6 +334,11 @@ class PS_GPU
template<uint32 out_Rshift, uint32 out_Gshift, uint32 out_Bshift>
void ReorderRGB(bool bpp24, const uint16 *src, uint32 *dest, const int32 dx_start, const int32 dx_end, int32 fb_x) NO_INLINE;
public:
uint32 GetVertStart() { return VertStart; }
uint32 GetVertEnd() { return VertEnd; }
int FirstLine;
};
}

View File

@ -42,6 +42,8 @@
#define FB_WIDTH 800
#define FB_HEIGHT 576
#define kScanlineWidthHeuristicIndex 64
//extern MDFNGI EmulatedPSX;
namespace MDFN_IEN_PSX
@ -1469,7 +1471,10 @@ void NormalizeFramebuffer()
//however, it will help us avoid stressing the displaymanager (for example, a 700x240 will freak it out kind of. we could send it a much more sensible 700x480)
int width = VTLineWidths[0][0]; //presently, except for contrived test programs, it is safe to assume this is the same for the entire frame (no known use by games)
//presently, except for contrived test programs, it is safe to assume this is the same for the entire frame (no known use by games)
int width = VTLineWidths[0][kScanlineWidthHeuristicIndex];
if(width <= 0) VTLineWidths[0][0];
int height = espec.DisplayRect.h;
int virtual_width = 800;
@ -1531,6 +1536,7 @@ void NormalizeFramebuffer()
espec.DisplayRect.h = height;
s_FramebufferCurrentWidth = width;
VTLineWidths[curr^1][0] = VTLineWidths[curr][0];
VTLineWidths[curr^1][kScanlineWidthHeuristicIndex] = VTLineWidths[curr][kScanlineWidthHeuristicIndex];
curr ^= 1;
}
@ -1574,6 +1580,7 @@ void NormalizeFramebuffer()
espec.DisplayRect.x = 0;
espec.DisplayRect.y = 0;
VTLineWidths[curr^1][0] = width;
VTLineWidths[curr ^ 1][kScanlineWidthHeuristicIndex] = width;
s_FramebufferCurrentWidth = width;
curr ^= 1;
@ -1611,9 +1618,40 @@ EW_EXPORT s32 shock_GetFramebuffer(void* psx, ShockFramebufferInfo* fb)
//always fetch description
//presently, except for contrived test programs, it is safe to assume this is the same for the entire frame (no known use by games)
//however, due to the dump_framebuffer, it may be incorrect at scanline 0. so lets use another one for the heuristic here
//64 is enough to fix the PAL bios screen...
int width = VTLineWidths[fbIndex][64];
//you'd think we could use FirstLine instead of kScanlineWidthHeuristicIndex, but sometimes it hasnt been set (screen off) so it's confusing
int width = VTLineWidths[fbIndex][kScanlineWidthHeuristicIndex];
int height = espec.DisplayRect.h;
int yo = espec.DisplayRect.y;
//fix a common error here from disabled screens (?)
//I think we're lucky in selecting these lines kind of randomly. need a better plan.
if(width <= 0) width = VTLineWidths[fbIndex][0];
if (s_ShockConfig.opts.renderType == eShockRenderType_Framebuffer)
{
//printf("%d %d %d %d | %d | %d\n",yo,height, GPU->GetVertStart(), GPU->GetVertEnd(), espec.DisplayRect.y, GPU->FirstLine);
height = GPU->GetVertEnd() - GPU->GetVertStart();
yo = GPU->FirstLine;
if(espec.DisplayRect.h == 288 || espec.DisplayRect.h == 240)
{}
else
{
height *= 2;
//only return even scanlines to avoid bouncing the interlacing
if(yo&1) yo--;
}
//this can happen when the display turns on mid-frame
//maybe an off by one error here..?
if (yo + height >= espec.DisplayRect.h)
yo = espec.DisplayRect.h - height;
//sometimes when changing modes we have trouble..?
if (yo<0) yo = 0;
}
fb->width = width;
fb->height = height;
@ -1625,7 +1663,7 @@ EW_EXPORT s32 shock_GetFramebuffer(void* psx, ShockFramebufferInfo* fb)
//maybe we need to output the framebuffer
//do a raster loop and copy it to the target
uint32* src = VTBuffer[fbIndex]->pixels + (s_FramebufferCurrentWidth*espec.DisplayRect.y) + espec.DisplayRect.x;
uint32* src = VTBuffer[fbIndex]->pixels + (s_FramebufferCurrentWidth*yo) + espec.DisplayRect.x;
uint32* dst = (u32*)fb->ptr;
int tocopy = width*4;
for(int y=0;y<height;y++)