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. Using this option may result in objectionable levels of black bars, but will fix some rare quirks in games.
</value> </value>
</data> </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> </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 //it's unclear what happens to games displaying a peculiar Y range
if (dump_framebuffer) 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 //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 //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 //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_start = 0;
dx_end = 2560 / DotClockRatios[dmc]; dx_end = 2560 / DotClockRatios[dmc];
if(FirstLine == -99)
FirstLine = dest_line;
LineWidths[dest_line] = dx_end - dx_start; LineWidths[dest_line] = dx_end - dx_start;
} }
} }
@ -1535,6 +1539,8 @@ void PS_GPU::StartFrame(EmulateSpecStruct *espec_arg)
LineWidths = espec->LineWidths; LineWidths = espec->LineWidths;
skip = espec->skip; skip = espec->skip;
FirstLine = -99;
if(espec->VideoFormatChanged) if(espec->VideoFormatChanged)
{ {
const auto& f = surface->format; const auto& f = surface->format;

View File

@ -334,6 +334,11 @@ class PS_GPU
template<uint32 out_Rshift, uint32 out_Gshift, uint32 out_Bshift> 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; 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_WIDTH 800
#define FB_HEIGHT 576 #define FB_HEIGHT 576
#define kScanlineWidthHeuristicIndex 64
//extern MDFNGI EmulatedPSX; //extern MDFNGI EmulatedPSX;
namespace MDFN_IEN_PSX 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) //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 height = espec.DisplayRect.h;
int virtual_width = 800; int virtual_width = 800;
@ -1531,6 +1536,7 @@ void NormalizeFramebuffer()
espec.DisplayRect.h = height; espec.DisplayRect.h = height;
s_FramebufferCurrentWidth = width; s_FramebufferCurrentWidth = width;
VTLineWidths[curr^1][0] = VTLineWidths[curr][0]; VTLineWidths[curr^1][0] = VTLineWidths[curr][0];
VTLineWidths[curr^1][kScanlineWidthHeuristicIndex] = VTLineWidths[curr][kScanlineWidthHeuristicIndex];
curr ^= 1; curr ^= 1;
} }
@ -1574,6 +1580,7 @@ void NormalizeFramebuffer()
espec.DisplayRect.x = 0; espec.DisplayRect.x = 0;
espec.DisplayRect.y = 0; espec.DisplayRect.y = 0;
VTLineWidths[curr^1][0] = width; VTLineWidths[curr^1][0] = width;
VTLineWidths[curr ^ 1][kScanlineWidthHeuristicIndex] = width;
s_FramebufferCurrentWidth = width; s_FramebufferCurrentWidth = width;
curr ^= 1; curr ^= 1;
@ -1611,9 +1618,40 @@ EW_EXPORT s32 shock_GetFramebuffer(void* psx, ShockFramebufferInfo* fb)
//always fetch description //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) //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 //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... //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][64]; int width = VTLineWidths[fbIndex][kScanlineWidthHeuristicIndex];
int height = espec.DisplayRect.h; 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->width = width;
fb->height = height; fb->height = height;
@ -1625,7 +1663,7 @@ EW_EXPORT s32 shock_GetFramebuffer(void* psx, ShockFramebufferInfo* fb)
//maybe we need to output the framebuffer //maybe we need to output the framebuffer
//do a raster loop and copy it to the target //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; uint32* dst = (u32*)fb->ptr;
int tocopy = width*4; int tocopy = width*4;
for(int y=0;y<height;y++) for(int y=0;y<height;y++)