mirror of https://github.com/PCSX2/pcsx2.git
Merge pull request #545 from PCSX2/gsdx-half-screen-snow-engine
Gsdx half screen (most of) snow engine games
This commit is contained in:
commit
f81cf360bc
|
@ -699,7 +699,7 @@ void GSDeviceOGL::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r
|
||||||
gl_CopyImageSubData( sid, GL_TEXTURE_2D,
|
gl_CopyImageSubData( sid, GL_TEXTURE_2D,
|
||||||
0, r.x, r.y, 0,
|
0, r.x, r.y, 0,
|
||||||
did, GL_TEXTURE_2D,
|
did, GL_TEXTURE_2D,
|
||||||
0, r.x, r.y, 0,
|
0, 0, 0, 0,
|
||||||
r.width(), r.height(), 1);
|
r.width(), r.height(), 1);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
|
@ -34,22 +34,36 @@ GSRendererHW::GSRendererHW(GSTextureCache* tc)
|
||||||
m_userhacks_skipdraw = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_SkipDraw", 0) : 0;
|
m_userhacks_skipdraw = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_SkipDraw", 0) : 0;
|
||||||
m_userhacks_align_sprite_X = !!theApp.GetConfig("UserHacks_align_sprite_X", 0) && !!theApp.GetConfig("UserHacks", 0);
|
m_userhacks_align_sprite_X = !!theApp.GetConfig("UserHacks_align_sprite_X", 0) && !!theApp.GetConfig("UserHacks", 0);
|
||||||
m_userhacks_round_sprite_offset = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_round_sprite_offset", 0) : 0;
|
m_userhacks_round_sprite_offset = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_round_sprite_offset", 0) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(!m_nativeres)
|
void GSRendererHW::SetScaling(){
|
||||||
|
int env = IsEnabled(1) ? 1 : 0;
|
||||||
|
|
||||||
|
m_buffer_size = max(m_context->FRAME.FBW, m_regs->DISP[env].DISPFB.FBW);
|
||||||
|
|
||||||
|
if (m_upscale_multiplier < 6 && (m_width / m_upscale_multiplier) != (m_buffer_size * 64)){
|
||||||
|
printf("Frame buffer width on vsync %d m_width %d\n", m_buffer_size, (m_width / m_upscale_multiplier));
|
||||||
|
m_tc->RemovePartial();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_nativeres)
|
||||||
{
|
{
|
||||||
m_width = theApp.GetConfig("resx", m_width);
|
m_width = theApp.GetConfig("resx", m_width);
|
||||||
m_height = theApp.GetConfig("resy", m_height);
|
m_height = theApp.GetConfig("resy", m_height);
|
||||||
|
|
||||||
m_upscale_multiplier = theApp.GetConfig("upscale_multiplier", m_upscale_multiplier);
|
m_upscale_multiplier = theApp.GetConfig("upscale_multiplier", m_upscale_multiplier);
|
||||||
|
|
||||||
if(m_upscale_multiplier > 6)
|
if (m_upscale_multiplier > 6)
|
||||||
{
|
{
|
||||||
m_upscale_multiplier = 1; // use the normal upscale math
|
m_upscale_multiplier = 1; // use the normal upscale math
|
||||||
}
|
}
|
||||||
else if(m_upscale_multiplier > 1)
|
else if (m_upscale_multiplier > 1)
|
||||||
{
|
{
|
||||||
m_width = 640 * m_upscale_multiplier; // 512 is also common, but this is not always detected right.
|
m_width = (m_buffer_size * 64) * m_upscale_multiplier;
|
||||||
m_height = 512 * m_upscale_multiplier; // 448 is also common, but this is not always detected right.
|
m_height = m_width; //Keep it square
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -59,9 +73,15 @@ GSRendererHW::GSRendererHW(GSTextureCache* tc)
|
||||||
|
|
||||||
if (m_upscale_multiplier == 1) {
|
if (m_upscale_multiplier == 1) {
|
||||||
// No upscaling hack at native resolution
|
// No upscaling hack at native resolution
|
||||||
|
if (m_nativeres) {
|
||||||
|
m_width = (m_buffer_size * 64) * m_upscale_multiplier;
|
||||||
|
m_height = m_width; //Keep it square
|
||||||
|
}
|
||||||
|
|
||||||
m_userhacks_round_sprite_offset = 0;
|
m_userhacks_round_sprite_offset = 0;
|
||||||
m_userhacks_align_sprite_X = 0;
|
m_userhacks_align_sprite_X = 0;
|
||||||
}
|
}
|
||||||
|
printf("Frame buffer width %d m_width set to %d multiplier %d", m_buffer_size, m_width, m_upscale_multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
GSRendererHW::~GSRendererHW()
|
GSRendererHW::~GSRendererHW()
|
||||||
|
@ -74,11 +94,6 @@ void GSRendererHW::SetGameCRC(uint32 crc, int options)
|
||||||
GSRenderer::SetGameCRC(crc, options);
|
GSRenderer::SetGameCRC(crc, options);
|
||||||
|
|
||||||
m_hacks.SetGameCRC(m_game);
|
m_hacks.SetGameCRC(m_game);
|
||||||
|
|
||||||
if(m_game.title == CRC::JackieChanAdv)
|
|
||||||
{
|
|
||||||
m_width = 1280; // TODO: uses a 1280px wide 16 bit render target, but this only fixes half of the problem
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GSRendererHW::CanUpscale()
|
bool GSRendererHW::CanUpscale()
|
||||||
|
@ -108,6 +123,9 @@ void GSRendererHW::Reset()
|
||||||
|
|
||||||
void GSRendererHW::VSync(int field)
|
void GSRendererHW::VSync(int field)
|
||||||
{
|
{
|
||||||
|
//Check if the frame buffer width or display width has changed
|
||||||
|
SetScaling();
|
||||||
|
|
||||||
if(m_reset)
|
if(m_reset)
|
||||||
{
|
{
|
||||||
m_tc->RemoveAll();
|
m_tc->RemoveAll();
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "GSTextureCache.h"
|
#include "GSTextureCache.h"
|
||||||
#include "GSCrc.h"
|
#include "GSCrc.h"
|
||||||
#include "GSFunctionMap.h"
|
#include "GSFunctionMap.h"
|
||||||
|
#include "GSState.h"
|
||||||
|
|
||||||
class GSRendererHW : public GSRenderer
|
class GSRendererHW : public GSRenderer
|
||||||
{
|
{
|
||||||
|
@ -34,6 +35,7 @@ private:
|
||||||
int m_skip;
|
int m_skip;
|
||||||
bool m_reset;
|
bool m_reset;
|
||||||
int m_upscale_multiplier;
|
int m_upscale_multiplier;
|
||||||
|
int m_buffer_size;
|
||||||
int m_userhacks_skipdraw;
|
int m_userhacks_skipdraw;
|
||||||
|
|
||||||
bool m_userhacks_align_sprite_X;
|
bool m_userhacks_align_sprite_X;
|
||||||
|
@ -151,6 +153,7 @@ public:
|
||||||
void SetGameCRC(uint32 crc, int options);
|
void SetGameCRC(uint32 crc, int options);
|
||||||
bool CanUpscale();
|
bool CanUpscale();
|
||||||
int GetUpscaleMultiplier();
|
int GetUpscaleMultiplier();
|
||||||
|
void SetScaling();
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
void VSync(int field);
|
void VSync(int field);
|
||||||
|
|
|
@ -40,6 +40,18 @@ GSTextureCache::~GSTextureCache()
|
||||||
_aligned_free(m_temp);
|
_aligned_free(m_temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSTextureCache::RemovePartial()
|
||||||
|
{
|
||||||
|
//m_src.RemoveAll();
|
||||||
|
|
||||||
|
for (int type = 0; type < 2; type++)
|
||||||
|
{
|
||||||
|
for_each(m_dst[type].begin(), m_dst[type].end(), delete_object());
|
||||||
|
|
||||||
|
m_dst[type].clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GSTextureCache::RemoveAll()
|
void GSTextureCache::RemoveAll()
|
||||||
{
|
{
|
||||||
m_src.RemoveAll();
|
m_src.RemoveAll();
|
||||||
|
@ -92,6 +104,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
||||||
}
|
}
|
||||||
|
|
||||||
Target* dst = NULL;
|
Target* dst = NULL;
|
||||||
|
bool half_right = false;
|
||||||
|
|
||||||
#ifdef DISABLE_HW_TEXTURE_CACHE
|
#ifdef DISABLE_HW_TEXTURE_CACHE
|
||||||
if( 0 )
|
if( 0 )
|
||||||
|
@ -115,11 +128,23 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
||||||
{
|
{
|
||||||
Target* t = *i;
|
Target* t = *i;
|
||||||
|
|
||||||
if(t->m_used && t->m_dirty.empty() && GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0, t->m_TEX0.PSM))
|
if(t->m_used && t->m_dirty.empty()) {
|
||||||
{
|
if (GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0, t->m_TEX0.PSM)) {
|
||||||
dst = t;
|
dst = t;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
} else if ((t->m_TEX0.TBW == 20) && (t->m_TEX0.PSM == 2) && GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0 + 0x140, t->m_TEX0.PSM)) {
|
||||||
|
// try to detect render target bigger than 1024 Texels
|
||||||
|
// 0x140: In 16 bits format, pages are 64 pixels and 8KB
|
||||||
|
// Half of 1280 is 640 so 10 pages
|
||||||
|
// TBP0 unit is block of 256B => (10 pages * 8 KB) / (1 block * 256B) = 320 = 0x140
|
||||||
|
|
||||||
|
half_right = true;
|
||||||
|
dst = t;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,7 +161,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
||||||
GL_CACHE("TC: src miss (0x%x)", TEX0.TBP0);
|
GL_CACHE("TC: src miss (0x%x)", TEX0.TBP0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
src = CreateSource(TEX0, TEXA, dst);
|
src = CreateSource(TEX0, TEXA, dst, half_right);
|
||||||
|
|
||||||
if(src == NULL)
|
if(src == NULL)
|
||||||
{
|
{
|
||||||
|
@ -338,6 +363,28 @@ void GSTextureCache::InvalidateVideoMem(GSOffset* off, const GSVector4i& rect, b
|
||||||
m_src.RemoveAt(s);
|
m_src.RemoveAt(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((bw == 20) && (psm == 2)) {
|
||||||
|
// try to detect render target bigger than 1024 Texels
|
||||||
|
// 0x140: In 16 bits format, pages are 64 pixels and 8KB
|
||||||
|
// Half of 1280 is 640 so 10 pages
|
||||||
|
// TBP0 unit is block of 256B => (10 pages * 8 KB) / (1 block * 256B) = 320 = 0x140
|
||||||
|
uint32 bbp = bp + 0x140;
|
||||||
|
|
||||||
|
const list<Source*>& m = m_src.m_map[bbp >> 5];
|
||||||
|
|
||||||
|
for(list<Source*>::const_iterator i = m.begin(); i != m.end(); )
|
||||||
|
{
|
||||||
|
list<Source*>::const_iterator j = i++;
|
||||||
|
|
||||||
|
Source* s = *j;
|
||||||
|
|
||||||
|
if(GSUtil::HasSharedBits(bbp, psm, s->m_TEX0.TBP0, s->m_TEX0.PSM))
|
||||||
|
{
|
||||||
|
m_src.RemoveAt(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GSVector4i r;
|
GSVector4i r;
|
||||||
|
@ -612,7 +659,7 @@ void GSTextureCache::IncAge()
|
||||||
}
|
}
|
||||||
|
|
||||||
//Fixme: Several issues in here. Not handling depth stencil, pitch conversion doesnt work.
|
//Fixme: Several issues in here. Not handling depth stencil, pitch conversion doesnt work.
|
||||||
GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* dst)
|
GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* dst, bool half_right)
|
||||||
{
|
{
|
||||||
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM];
|
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM];
|
||||||
Source* src = new Source(m_renderer, TEX0, TEXA, m_temp);
|
Source* src = new Source(m_renderer, TEX0, TEXA, m_temp);
|
||||||
|
@ -770,13 +817,22 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
||||||
|
|
||||||
if((sRect == dRect).alltrue())
|
if((sRect == dRect).alltrue())
|
||||||
{
|
{
|
||||||
m_renderer->m_dev->CopyRect(sTex, dTex, GSVector4i(0, 0, w, h));
|
// Note: use dstsize.x instead of w because w is limited to 1024 whereas dstsize.x could
|
||||||
|
// be bigger (1280 for snow engine games)
|
||||||
|
if (half_right)
|
||||||
|
m_renderer->m_dev->CopyRect(sTex, dTex, GSVector4i(dstsize.x/2, 0, dstsize.x, h));
|
||||||
|
else
|
||||||
|
m_renderer->m_dev->CopyRect(sTex, dTex, GSVector4i(0, 0, w, h)); // <= likely wrong dstsize.x could be bigger than w
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sRect.z /= sTex->GetWidth();
|
sRect.z /= sTex->GetWidth();
|
||||||
sRect.w /= sTex->GetHeight();
|
sRect.w /= sTex->GetHeight();
|
||||||
|
|
||||||
|
if (half_right) {
|
||||||
|
sRect.x = sRect.z/2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
m_renderer->m_dev->StretchRect(sTex, sRect, dTex, dRect, 0, linear);
|
m_renderer->m_dev->StretchRect(sTex, sRect, dTex, dRect, 0, linear);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ public:
|
||||||
|
|
||||||
void Add(Source* s, const GIFRegTEX0& TEX0, const GSOffset* off);
|
void Add(Source* s, const GIFRegTEX0& TEX0, const GSOffset* off);
|
||||||
void RemoveAll();
|
void RemoveAll();
|
||||||
|
void RemovePartial();
|
||||||
void RemoveAt(Source* s);
|
void RemoveAt(Source* s);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -111,7 +112,7 @@ protected:
|
||||||
int m_spritehack;
|
int m_spritehack;
|
||||||
uint8* m_temp;
|
uint8* m_temp;
|
||||||
|
|
||||||
virtual Source* CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* t = NULL);
|
virtual Source* CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* t = NULL, bool half_right = false);
|
||||||
virtual Target* CreateTarget(const GIFRegTEX0& TEX0, int w, int h, int type);
|
virtual Target* CreateTarget(const GIFRegTEX0& TEX0, int w, int h, int type);
|
||||||
|
|
||||||
virtual int Get8bitFormat() = 0;
|
virtual int Get8bitFormat() = 0;
|
||||||
|
@ -129,6 +130,7 @@ public:
|
||||||
virtual void Read(Target* t, const GSVector4i& r) = 0;
|
virtual void Read(Target* t, const GSVector4i& r) = 0;
|
||||||
#endif
|
#endif
|
||||||
void RemoveAll();
|
void RemoveAll();
|
||||||
|
void RemovePartial();
|
||||||
|
|
||||||
Source* LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r);
|
Source* LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r);
|
||||||
Target* LookupTarget(const GIFRegTEX0& TEX0, int w, int h, int type, bool used);
|
Target* LookupTarget(const GIFRegTEX0& TEX0, int w, int h, int type, bool used);
|
||||||
|
|
Loading…
Reference in New Issue