psx - continue fiddling with framebuffer cropping mode
This commit is contained in:
parent
eb59470ed8
commit
4e673df06f
|
@ -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.
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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++)
|
||||||
|
|
Loading…
Reference in New Issue