- Fixed many flickering scene change transitions (FF12, Gust games, etc).
- Found more info on how games do some special effects. Preliminary code included, but disabled.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2101 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
ramapcsx2 2009-10-31 10:56:10 +00:00
parent 4cb8e21f94
commit 655038be45
2 changed files with 249 additions and 2 deletions

View File

@ -466,7 +466,9 @@ protected:
{ {
__super::VSync(field); __super::VSync(field);
m_tc->IncAge(); // IncAge() gets rid of "old" textures, but it's not really needed.
// Doing it causes flickering on many game scene transitions.
//m_tc->IncAge();
m_skip = 0; m_skip = 0;

View File

@ -451,7 +451,7 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset* o, const GSVector4i& r)
// TODO: ds // TODO: ds
*/ */
} }
//Currently unused
void GSTextureCache::IncAge() void GSTextureCache::IncAge()
{ {
int maxage = m_src.m_used ? 3 : 30; int maxage = m_src.m_used ? 3 : 30;
@ -724,6 +724,251 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
return src; return src;
} }
//WIP fog / blur / depth of field handling.
//GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* dst)
//{
// Source* src = new Source(m_renderer);
//
// src->m_TEX0 = TEX0;
// src->m_TEXA = TEXA;
//
// int tw = 1 << TEX0.TW;
// int th = 1 << TEX0.TH;
// int tp = (int)TEX0.TW << 6;
//
// if(dst == NULL)
// {
// if(m_paltex && GSLocalMemory::m_psm[TEX0.PSM].pal > 0)
// {
// src->m_fmt = FMT_8;
//
// src->m_texture = m_renderer->m_dev->CreateTexture(tw, th, Get8bitFormat());
// src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
// }
// else
// {
// src->m_fmt = FMT_32;
//
// src->m_texture = m_renderer->m_dev->CreateTexture(tw, th);
// }
// }
// else
// {
// // TODO: clean up this mess
//
// src->m_target = true;
//
// if(dst->m_type != RenderTarget)
// {
// // TODO
//
// delete src;
//
// return NULL;
// }
//
// dst->Update();
//
// GSTexture* tmp = NULL;
//
// if(dst->m_texture->IsMSAA())
// {
// tmp = dst->m_texture;
//
// dst->m_texture = m_renderer->m_dev->Resolve(dst->m_texture);
// }
//
// // do not round here!!! if edge becomes a black pixel and addressing mode is clamp => everything outside the clamped area turns into black (kh2 shadows)
//
// int w = (int)(dst->m_texture->GetScale().x * tw);
// int h = (int)(dst->m_texture->GetScale().y * th);
//
// GSVector2i dstsize = dst->m_texture->GetSize();
//
// //Hacked up to figure out how fog / depth / blur effects are done. Works in Xenosaga 3.
// if ((tw == 1024 && th == 1024) && dst->m_TEX0.TBW != TEX0.TBW){
//
// src->m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y, false);
// GSVector4 size = GSVector4(dstsize).xyxy() * 2; // * 2 to force the effect overlay into the right position
// GSVector4 scale = GSVector4(dst->m_texture->GetScale()).xyxy(); //Not needed right now, but good for testing
//
// GSVector4 br (0.0f, 0.0f, 1024.0f, 1024.0f); // entire RT
// GSVector4 sr = br * scale / size;
// GSVector4 dr = br * scale;
//
// m_renderer->m_dev->StretchRect(dst->m_texture, sr, src->m_texture, dr);
// }
// // pitch conversion //total mess right now, don't touch :p
// else if(dst->m_TEX0.TBW != TEX0.TBW) // && dst->m_TEX0.PSM == TEX0.PSM
// {
// // sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left)
//
// // ASSERT(dst->m_TEX0.TBW > TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO)
//
// src->m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y, false);
//
// GSVector4 size = GSVector4(dstsize).xyxy();
// GSVector4 scale = GSVector4(dst->m_texture->GetScale()).xyxy();
//
// if (dst->m_TEX0.TBW < TEX0.TBW) // otherwise scale.x need to be reduced to make the larger texture fit
// {
// // scale.x = ((float)dst->m_TEX0.TBW / (float)TEX0.TBW) ;
// // printf("scale.x = %f \n", scale.x);
// }
//
// int blockWidth = 64;
// int blockHeight = TEX0.PSM == PSM_PSMCT32 || TEX0.PSM == PSM_PSMCT24 ? 32 : 64;
//
// GSVector4i br(0, 0, blockWidth, blockHeight);
//
// int sw = (int)dst->m_TEX0.TBW << 6;
//
// int dw = (int)TEX0.TBW << 6;
// int dh = 1 << TEX0.TH;
//
// if(sw != 0)
// for(int dy = 0; dy < dh; dy += blockHeight)
// {
// for(int dx = 0; dx < dw; dx += blockWidth)
// {
// int o = dy * dw / blockHeight + dx;
//
// int sx = o % sw;
// int sy = o / sw;
// //printf("sx = %d ,sy = %d ,sw = %d ,o = %d \n",sx,sy,sw,o);
// GSVector4 sr = GSVector4(GSVector4i(sx, sy).xyxy() + br) * scale / size;
// GSVector4 dr = GSVector4(GSVector4i(dx, dy).xyxy() + br) * scale;
//
// m_renderer->m_dev->StretchRect(dst->m_texture, sr, src->m_texture, dr);
//
// // TODO: this is quite a lot of StretchRect, do it with one Draw
// }
// }
// }
// else if(tw < tp)
// {
// // FIXME: timesplitters blurs the render target by blending itself over a couple of times
//
// if(tw == 256 && th == 128 && tp == 512 && (TEX0.TBP0 == 0 || TEX0.TBP0 == 0x00e00))
// {
// delete src;
// return false;
// }
// }
// // width/height conversion
//
// GSVector2 scale = dst->m_texture->GetScale();
//
// GSVector4 dr(0, 0, w, h);
//
// if(w > dstsize.x)
// {
// scale.x = (float)dstsize.x / tw;
// dr.z = (float)dstsize.x * scale.x / dst->m_texture->GetScale().x;
// w = dstsize.x;
// }
//
// if(h > dstsize.y)
// {
// scale.y = (float)dstsize.y / th;
// dr.w = (float)dstsize.y * scale.y / dst->m_texture->GetScale().y;
// h = dstsize.y;
// }
//
// GSVector4 sr(0, 0, w, h);
//
// GSTexture* st = src->m_texture ? src->m_texture : dst->m_texture;
// GSTexture* dt = m_renderer->m_dev->CreateRenderTarget(w, h, false);
//
// if(!src->m_texture)
// {
// src->m_texture = dt;
// }
//
// if((sr == dr).alltrue())
// {
// m_renderer->m_dev->CopyRect(st, dt, GSVector4i(0, 0, w, h));
// }
// else
// {
// sr.z /= st->GetWidth();
// sr.w /= st->GetHeight();
//
// m_renderer->m_dev->StretchRect(st, sr, dt, dr);
// }
//
// if(dt != src->m_texture)
// {
// m_renderer->m_dev->Recycle(src->m_texture);
//
// src->m_texture = dt;
// }
//
// src->m_texture->SetScale(scale);
//
// switch(TEX0.PSM)
// {
// default:
// // Note: this assertion triggers in Xenosaga2 after the first intro scenes, when
// // gameplay first begins (in the city).
// ASSERT(0);
// case PSM_PSMCT32:
// src->m_fmt = FMT_32;
// break;
// case PSM_PSMCT24:
// src->m_fmt = FMT_24;
// break;
// case PSM_PSMCT16:
// case PSM_PSMCT16S:
// src->m_fmt = FMT_16;
// break;
// case PSM_PSMT8H:
// src->m_fmt = FMT_8H;
// src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
// break;
// case PSM_PSMT8:
// //Not sure, this wasn't handled at all.
// //Xenosaga 2 and 3 use it, Tales of Legendia as well.
// //It's always used for fog like effects.
// src->m_fmt = FMT_8;
// src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
// break;
// case PSM_PSMT4HL:
// src->m_fmt = FMT_4HL;
// src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
// break;
// case PSM_PSMT4HH:
// src->m_fmt = FMT_4HH;
// src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
// break;
// }
//
// if(tmp != NULL)
// {
// m_renderer->m_dev->Recycle(dst->m_texture);
//
// dst->m_texture = tmp;
// }
// }
//
// if(src->m_texture == NULL)
// {
// ASSERT(0);
//
// return NULL;
// }
//
// const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM];
//
// if(psm.pal > 0)
// {
// memcpy(src->m_clut, (const uint32*)m_renderer->m_mem.m_clut, psm.pal * sizeof(uint32));
// }
//
// m_src.Add(src, TEX0, m_renderer->m_context->offset.tex);
//
// return src;
//}
GSTextureCache::Target* GSTextureCache::CreateTarget(const GIFRegTEX0& TEX0, int w, int h, int type) GSTextureCache::Target* GSTextureCache::CreateTarget(const GIFRegTEX0& TEX0, int w, int h, int type)
{ {