diff --git a/plugins/GSdx/GSCrc.cpp b/plugins/GSdx/GSCrc.cpp index 34307df48b..aec9656c20 100644 --- a/plugins/GSdx/GSCrc.cpp +++ b/plugins/GSdx/GSCrc.cpp @@ -128,6 +128,7 @@ CRC::Game CRC::m_games[] = {0x14FE77F7, TalesOfAbyss, US}, {0x045D77E9, TalesOfAbyss, US}, // undub {0xAA5EC3A3, TalesOfAbyss, JP}, + {0xFB236A46, SonicUnleashed, US}, }; CAtlMap CRC::m_map; diff --git a/plugins/GSdx/GSCrc.h b/plugins/GSdx/GSCrc.h index 12f41bd93f..083b69df1a 100644 --- a/plugins/GSdx/GSCrc.h +++ b/plugins/GSdx/GSCrc.h @@ -63,7 +63,8 @@ public: Onimusha3, MajokkoALaMode2, TalesOfAbyss, - TitleCount + SonicUnleashed, + TitleCount, }; enum Region diff --git a/plugins/GSdx/GSDrawScanline.cpp b/plugins/GSdx/GSDrawScanline.cpp index ccdd34f4b7..4813bc0440 100644 --- a/plugins/GSdx/GSDrawScanline.cpp +++ b/plugins/GSdx/GSDrawScanline.cpp @@ -189,6 +189,7 @@ void GSDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f) sel.iip = m_sel.iip; sel.tfx = m_sel.tfx; + sel.tcc = m_sel.tcc; sel.fst = m_sel.fst; sel.fge = m_sel.fge; sel.sprite = m_sel.sprite; diff --git a/plugins/GSdx/GSDrawScanlineCodeGenerator.cpp b/plugins/GSdx/GSDrawScanlineCodeGenerator.cpp index 5b0c12411c..a6eb172b3e 100644 --- a/plugins/GSdx/GSDrawScanlineCodeGenerator.cpp +++ b/plugins/GSdx/GSDrawScanlineCodeGenerator.cpp @@ -35,6 +35,11 @@ GSDrawScanlineCodeGenerator::GSDrawScanlineCodeGenerator(GSScanlineEnvironment& m_sel.key = key; + if(m_sel.tfx == TFX_DECAL && m_sel.tcc == 0) + { + printf("*** TFX_DECAL && !TCC *** \n"); + } + Generate(); } @@ -449,7 +454,7 @@ void GSDrawScanlineCodeGenerator::Init(int params) } } - if(m_sel.tfx != TFX_DECAL) + if(!(m_sel.tfx == TFX_DECAL && m_sel.tcc)) { if(m_sel.iip) { @@ -582,7 +587,7 @@ void GSDrawScanlineCodeGenerator::Step() } } - if(m_sel.tfx != TFX_DECAL) + if(!(m_sel.tfx == TFX_DECAL && m_sel.tcc)) { if(m_sel.iip) { @@ -1202,6 +1207,19 @@ void GSDrawScanlineCodeGenerator::AlphaTFX() case TFX_DECAL: + // if(!tcc) gat = gat.mix16(ga.srl16(7)); + + if(!m_sel.tcc) + { + // GSVector4i ga = iip ? gaf : m_env.c.ga; + + movdqa(xmm4, xmmword[m_sel.iip ? &m_env.temp.ga : &m_env.c.ga]); + + psrlw(xmm4, 7); + + mix16(xmm6, xmm4, xmm3); + } + break; case TFX_HIGHLIGHT: diff --git a/plugins/GSdx/GSRendererSW.h b/plugins/GSdx/GSRendererSW.h index 3189f49a44..c0d2cb0889 100644 --- a/plugins/GSdx/GSRendererSW.h +++ b/plugins/GSdx/GSRendererSW.h @@ -134,7 +134,7 @@ protected: int amin, amax; - if(PRIM->TME && (context->TEX0.TCC || context->TEX0.TFX == TFX_DECAL)) + if(PRIM->TME && context->TEX0.TCC) { DWORD bpp = GSLocalMemory::m_psm[context->TEX0.PSM].trbpp; DWORD cbpp = GSLocalMemory::m_psm[context->TEX0.CPSM].trbpp; @@ -325,11 +325,6 @@ protected: } } - if(p.sel.tfx == TFX_DECAL) - { - p.sel.tcc = 1; - } - if(p.sel.fst == 0) { // skip per pixel division if q is constant @@ -500,7 +495,7 @@ protected: { GS_PRIM_CLASS primclass = GSUtil::GetPrimClass(PRIM->PRIM); - m_vtrace.Update(m_vertices, m_count, primclass, PRIM->IIP, PRIM->TME, m_context->TEX0.TFX); + m_vtrace.Update(m_vertices, m_count, primclass, PRIM->IIP, PRIM->TME, m_context->TEX0.TFX, m_context->TEX0.TCC); if(m_dump) { @@ -522,9 +517,9 @@ protected: str.Format(_T("c:\\temp1\\_%05d_f%I64d_tex_%05x_%d.bmp"), s_n++, m_perfmon.GetFrame(), (int)m_context->TEX0.TBP0, (int)m_context->TEX0.PSM); if(PRIM->TME) if(s_save) {m_mem.SaveBMP(str, m_context->TEX0.TBP0, m_context->TEX0.TBW, m_context->TEX0.PSM, 1 << m_context->TEX0.TW, 1 << m_context->TEX0.TH);} str.Format(_T("c:\\temp1\\_%05d_f%I64d_rt0_%05x_%d.bmp"), s_n++, m_perfmon.GetFrame(), m_context->FRAME.Block(), m_context->FRAME.PSM); - if(s_save) {m_mem.SaveBMP(str, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameSize(1).cx, 512);}//GetFrameSize(1).cy); + if(s_save) {m_mem.SaveBMP(str, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameSize().cx, 512);}//GetFrameSize(1).cy); str.Format(_T("c:\\temp1\\_%05d_f%I64d_rz0_%05x_%d.bmp"), s_n-1, m_perfmon.GetFrame(), m_context->ZBUF.Block(), m_context->ZBUF.PSM); - if(s_savez) {m_mem.SaveBMP(str, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameSize(1).cx, 512);} + if(s_savez) {m_mem.SaveBMP(str, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameSize().cx, 512);} } GSRasterizerData data; @@ -581,9 +576,9 @@ protected: { CString str; str.Format(_T("c:\\temp1\\_%05d_f%I64d_rt1_%05x_%d.bmp"), s_n++, m_perfmon.GetFrame(), m_context->FRAME.Block(), m_context->FRAME.PSM); - if(s_save) {m_mem.SaveBMP(str, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameSize(1).cx, 512);}//GetFrameSize(1).cy); + if(s_save) {m_mem.SaveBMP(str, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameSize().cx, 512);}//GetFrameSize(1).cy); str.Format(_T("c:\\temp1\\_%05d_f%I64d_rz1_%05x_%d.bmp"), s_n-1, m_perfmon.GetFrame(), m_context->ZBUF.Block(), m_context->ZBUF.PSM); - if(s_savez) {m_mem.SaveBMP(str, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameSize(1).cx, 512);} + if(s_savez) {m_mem.SaveBMP(str, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameSize().cx, 512);} } if(0)//stats.ticks > 1000000) diff --git a/plugins/GSdx/GSSetupPrimCodeGenerator.cpp b/plugins/GSdx/GSSetupPrimCodeGenerator.cpp index d44768d68f..4fa97f8ab6 100644 --- a/plugins/GSdx/GSSetupPrimCodeGenerator.cpp +++ b/plugins/GSdx/GSSetupPrimCodeGenerator.cpp @@ -33,7 +33,7 @@ GSSetupPrimCodeGenerator::GSSetupPrimCodeGenerator(GSScanlineEnvironment& env, U m_en.z = m_sel.zb ? 1 : 0; m_en.f = m_sel.fb && m_sel.fge ? 1 : 0; m_en.t = m_sel.fb && m_sel.tfx != TFX_NONE ? 1 : 0; - m_en.c = m_sel.fb && m_sel.tfx != TFX_DECAL ? 1 : 0; + m_en.c = m_sel.fb && !(m_sel.tfx == TFX_DECAL && m_sel.tcc) ? 1 : 0; #if _M_AMD64 #error TODO diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index 11d681a337..d6a9a07a30 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -2130,6 +2130,25 @@ bool GSC_TalesOfAbyss(const GSFrameInfo& fi, int& skip) return true; } +bool GSC_SonicUnleashed(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x02200 && fi.FPSM == PSM_PSMCT16S && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT16) + { + skip = 1000; // shadow + } + } + else + { + if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x02200 && fi.TPSM == PSM_PSMCT16S) + { + skip = 2; + } + } + + return true; +} bool GSState::IsBadFrame(int& skip) { GSFrameInfo fi; @@ -2175,6 +2194,7 @@ bool GSState::IsBadFrame(int& skip) map[CRC::GiTS] = GSC_GiTS; map[CRC::Onimusha3] = GSC_Onimusha3; map[CRC::TalesOfAbyss] = GSC_TalesOfAbyss; + map[CRC::SonicUnleashed] = GSC_SonicUnleashed; } // TODO: just set gsc in SetGameCRC once diff --git a/plugins/GSdx/GSTextureCacheSW.cpp b/plugins/GSdx/GSTextureCacheSW.cpp index e22bfb0e06..0344e0c2a7 100644 --- a/plugins/GSdx/GSTextureCacheSW.cpp +++ b/plugins/GSdx/GSTextureCacheSW.cpp @@ -54,7 +54,7 @@ const GSTextureCacheSW::GSTexture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TE continue; } - if((psm.trbpp == 16 || psm.trbpp == 24) && (t2->m_TEX0.TCC != TEX0.TCC || TEX0.TCC == 1 && !(t2->m_TEXA == (GSVector4i)TEXA).alltrue())) + if((psm.trbpp == 16 || psm.trbpp == 24) && (t2->m_TEX0.TCC != TEX0.TCC || TEX0.TCC && !(t2->m_TEXA == (GSVector4i)TEXA).alltrue())) { continue; } @@ -306,6 +306,8 @@ bool GSTextureCacheSW::GSTexture::Update(const GIFRegTEX0& TEX0, const GIFRegTEX // unfortunatelly a block may be part of the same texture multiple times at different places (when (1 << tw) > (tbw << 6), ex. 1024 > 640), // so just can't set the block's bit to valid in one pass, even if 99.9% of the games don't address the repeated part at the right side + + // TODO: still bogus if those repeated parts aren't fetched together // m_valid[row] |= col; diff --git a/plugins/GSdx/GSVertexSW.cpp b/plugins/GSdx/GSVertexSW.cpp index a8fbefd0c5..d037c1611f 100644 --- a/plugins/GSdx/GSVertexSW.cpp +++ b/plugins/GSdx/GSVertexSW.cpp @@ -38,8 +38,7 @@ GSVertexTrace::GSVertexTraceCodeGenerator::GSVertexTraceCodeGenerator(DWORD key, DWORD primclass = (key >> 0) & 3; DWORD iip = (key >> 2) & 1; DWORD tme = (key >> 3) & 1; - DWORD tfx = (key >> 4) & 3; - DWORD color = !(tme && tfx == TFX_DECAL); + DWORD color = (key >> 4) & 1; int n = 1; diff --git a/plugins/GSdx/GSVertexSW.h b/plugins/GSdx/GSVertexSW.h index 44e0d0ca25..ac21c0bd6d 100644 --- a/plugins/GSdx/GSVertexSW.h +++ b/plugins/GSdx/GSVertexSW.h @@ -244,11 +244,14 @@ public: struct {DWORD xyzf:4, stq:4, rgba:4;}; } m_eq; - void Update(const GSVertexSW* v, int count, GS_PRIM_CLASS primclass, DWORD iip, DWORD tme, DWORD tfx) + void Update(const GSVertexSW* v, int count, GS_PRIM_CLASS primclass, DWORD iip, DWORD tme, DWORD tfx, DWORD tcc) { - if(!tme) tfx = 0; + DWORD key = primclass | (iip << 2) | (tme << 3); - DWORD key = primclass | (iip << 2) | (tme << 3) | (tfx << 4); + if(!(tme && tfx == TFX_DECAL && tcc)) + { + key |= 1 << 4; + } m_map.Lookup(key)(v, count, m_min, m_max); diff --git a/plugins/GSdx/res/tfx10.fx b/plugins/GSdx/res/tfx10.fx index fe101d1674..8f0fe77a9b 100644 --- a/plugins/GSdx/res/tfx10.fx +++ b/plugins/GSdx/res/tfx10.fx @@ -423,7 +423,14 @@ PS_OUTPUT ps_main(PS_INPUT input) } else if(TFX == 1) { - c = t; + if(TCC == 0) + { + c.rgb = t.rgb; + } + else + { + c = t; + } } else if(TFX == 2) { diff --git a/plugins/GSdx/res/tfx9.fx b/plugins/GSdx/res/tfx9.fx index d3c9d05d85..d825cf187b 100644 --- a/plugins/GSdx/res/tfx9.fx +++ b/plugins/GSdx/res/tfx9.fx @@ -250,7 +250,14 @@ float4 ps_main(PS_INPUT input) : COLOR } else if(TFX == 1) { - c = t; + if(TCC == 0) + { + c.rgb = t.rgb; + } + else + { + c = t; + } } else if(TFX == 2) {