diff --git a/plugins/GSdx/GSCrc.cpp b/plugins/GSdx/GSCrc.cpp index 35c4829367..d8bed42b80 100644 --- a/plugins/GSdx/GSCrc.cpp +++ b/plugins/GSdx/GSCrc.cpp @@ -176,6 +176,7 @@ CRC::Game CRC::m_games[] = {0xD568B684, SMTDDS2, EU, ZWriteMustNotClear}, // SMT Digital Devil Saga 2 {0xE47C1A9C, SMTDDS2, JP, ZWriteMustNotClear}, // SMT Digital Devil Saga 2 {0x0B8AB37B, RozenMaidenGebetGarden, JP, 0}, + {0x1CC39DBD, SuikodenTactics, US, 0}, }; hash_map CRC::m_map; diff --git a/plugins/GSdx/GSCrc.h b/plugins/GSdx/GSCrc.h index 92995b5a64..2a1b5b7355 100644 --- a/plugins/GSdx/GSCrc.h +++ b/plugins/GSdx/GSCrc.h @@ -81,6 +81,7 @@ public: SMTDDS1, SMTDDS2, RozenMaidenGebetGarden, + SuikodenTactics, TitleCount, }; diff --git a/plugins/GSdx/GSDrawScanlineCodeGenerator.x86.cpp b/plugins/GSdx/GSDrawScanlineCodeGenerator.x86.cpp index 59dd83d242..126fe50c6c 100644 --- a/plugins/GSdx/GSDrawScanlineCodeGenerator.x86.cpp +++ b/plugins/GSdx/GSDrawScanlineCodeGenerator.x86.cpp @@ -2958,7 +2958,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset) { movdqa(ptr[&m_local.temp.test], xmm7); - mov(ebx, ptr[&m_local.temp.lod.i.u32[0]]); + mov(ebx, ptr[&lod_i->u32[0]]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); ReadTexel(xmm6, xmm5, 0); @@ -2966,7 +2966,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset) ReadTexel(xmm4, xmm2, 0); psrldq(xmm2, 4); - mov(ebx, ptr[&m_local.temp.lod.i.u32[1]]); + mov(ebx, ptr[&lod_i->u32[1]]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); ReadTexel(xmm1, xmm5, 0); @@ -2977,7 +2977,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset) punpckldq(xmm6, xmm1); punpckldq(xmm4, xmm7); - mov(ebx, ptr[&m_local.temp.lod.i.u32[2]]); + mov(ebx, ptr[&lod_i->u32[2]]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); ReadTexel(xmm1, xmm5, 0); @@ -2985,7 +2985,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset) ReadTexel(xmm7, xmm2, 0); psrldq(xmm2, 4); - mov(ebx, ptr[&m_local.temp.lod.i.u32[3]]); + mov(ebx, ptr[&lod_i->u32[3]]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); ReadTexel(xmm5, xmm5, 0); @@ -2997,7 +2997,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset) punpcklqdq(xmm6, xmm1); punpcklqdq(xmm4, xmm7); - mov(ebx, ptr[&m_local.temp.lod.i.u32[0]]); + mov(ebx, ptr[&lod_i->u32[0]]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); ReadTexel(xmm1, xmm0, 0); @@ -3005,7 +3005,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset) ReadTexel(xmm5, xmm3, 0); psrldq(xmm3, 4); - mov(ebx, ptr[&m_local.temp.lod.i.u32[1]]); + mov(ebx, ptr[&lod_i->u32[1]]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); ReadTexel(xmm2, xmm0, 0); @@ -3016,7 +3016,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset) punpckldq(xmm1, xmm2); punpckldq(xmm5, xmm7); - mov(ebx, ptr[&m_local.temp.lod.i.u32[2]]); + mov(ebx, ptr[&lod_i->u32[2]]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); ReadTexel(xmm2, xmm0, 0); @@ -3024,7 +3024,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset) ReadTexel(xmm7, xmm3, 0); psrldq(xmm3, 4); - mov(ebx, ptr[&m_local.temp.lod.i.u32[3]]); + mov(ebx, ptr[&lod_i->u32[3]]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); ReadTexel(xmm0, xmm0, 0); @@ -3040,13 +3040,13 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset) } else { - mov(ebx, ptr[&m_local.temp.lod.i.u32[0]]); + mov(ebx, ptr[&lod_i->u32[0]]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); ReadTexel(xmm6, xmm5, 0); psrldq(xmm5, 4); // shuffle instead? (1 2 3 0 ~ rotation) - mov(ebx, ptr[&m_local.temp.lod.i.u32[1]]); + mov(ebx, ptr[&lod_i->u32[1]]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); ReadTexel(xmm1, xmm5, 0); @@ -3054,13 +3054,13 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset) punpckldq(xmm6, xmm1); - mov(ebx, ptr[&m_local.temp.lod.i.u32[2]]); + mov(ebx, ptr[&lod_i->u32[2]]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); ReadTexel(xmm1, xmm5, 0); psrldq(xmm5, 4); - mov(ebx, ptr[&m_local.temp.lod.i.u32[3]]); + mov(ebx, ptr[&lod_i->u32[3]]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); ReadTexel(xmm4, xmm5, 0); diff --git a/plugins/GSdx/GSRendererSW.cpp b/plugins/GSdx/GSRendererSW.cpp index 0b8caf45d3..c603ed0b63 100644 --- a/plugins/GSdx/GSRendererSW.cpp +++ b/plugins/GSdx/GSRendererSW.cpp @@ -129,7 +129,10 @@ void GSRendererSW::Draw() GSScanlineGlobalData gd; - GetScanlineGlobalData(gd); + if(!GetScanlineGlobalData(gd)) + { + return; + } if(!gd.sel.fwrite && !gd.sel.zwrite) { @@ -244,7 +247,7 @@ void GSRendererSW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GS #include "GSTextureSW.h" -void GSRendererSW::GetScanlineGlobalData(GSScanlineGlobalData& gd) +bool GSRendererSW::GetScanlineGlobalData(GSScanlineGlobalData& gd) { const GSDrawingEnvironment& env = m_env; const GSDrawingContext* context = m_context; @@ -346,7 +349,7 @@ void GSRendererSW::GetScanlineGlobalData(GSScanlineGlobalData& gd) const GSTextureCacheSW::Texture* t = m_tc->Lookup(context->TEX0, env.TEXA, r); - if(t == NULL) {ASSERT(0); return;} + if(t == NULL) {ASSERT(0); return false;} gd.tex[0] = t->m_buff; gd.sel.tw = t->m_tw - 3; @@ -469,7 +472,7 @@ void GSRendererSW::GetScanlineGlobalData(GSScanlineGlobalData& gd) const GSTextureCacheSW::Texture* t = m_tc->Lookup(MIP_TEX0, env.TEXA, r, gd.sel.tw + 3); - if(t == NULL) {ASSERT(0); return;} + if(t == NULL) {ASSERT(0); return false;} gd.tex[i] = t->m_buff; @@ -684,6 +687,8 @@ void GSRendererSW::GetScanlineGlobalData(GSScanlineGlobalData& gd) { gd.zm |= GSVector4i::xffff0000(); } + + return true; } template @@ -848,5 +853,7 @@ if(!m_dump) } m_count += count; + + // Flush(); } } diff --git a/plugins/GSdx/GSRendererSW.h b/plugins/GSdx/GSRendererSW.h index 1f6915ed53..3340dcccba 100644 --- a/plugins/GSdx/GSRendererSW.h +++ b/plugins/GSdx/GSRendererSW.h @@ -42,7 +42,7 @@ protected: void Draw(); void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r); - void GetScanlineGlobalData(GSScanlineGlobalData& gd); + bool GetScanlineGlobalData(GSScanlineGlobalData& gd); public: GSRendererSW(int threads); diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index 019a228cd4..de5dcd3ba2 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -2482,6 +2482,19 @@ bool GSC_HauntingGround(const GSFrameInfo& fi, int& skip) return true; } +bool GSC_SuikodenTactics(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(!fi.TME && fi.TPSM == PSM_PSMT8H && fi.FPSM == 0 && fi.FBMSK == 0x0FF000000 && fi.TBP0 == 0 && GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) + { + skip = 4; + } + } + + return true; +} + bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw) { GSFrameInfo fi; @@ -2536,6 +2549,7 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw) map[CRC::ValkyrieProfile2] = GSC_ValkyrieProfile2; map[CRC::RadiataStories] = GSC_RadiataStories; map[CRC::HauntingGround] = GSC_HauntingGround; + map[CRC::SuikodenTactics] = GSC_SuikodenTactics; } // TODO: just set gsc in SetGameCRC once diff --git a/plugins/GSdx/GSTextureCacheSW.cpp b/plugins/GSdx/GSTextureCacheSW.cpp index 0c9edb7791..0b0d3a01a4 100644 --- a/plugins/GSdx/GSTextureCacheSW.cpp +++ b/plugins/GSdx/GSTextureCacheSW.cpp @@ -119,7 +119,7 @@ const GSTextureCacheSW::Texture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TEX0 if(!t->Update(TEX0, TEXA, r)) { - printf("!@#$\n"); // memory allocation may fail if the game is too hungry + printf("!@#$\n"); // memory allocation may fail if the game is too hungry (tales of legendia fight transition/scene) RemoveAt(t); @@ -256,13 +256,15 @@ bool GSTextureCacheSW::Texture::Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& bool repeating = m_TEX0.IsRepeating(); - if(m_TEX0.TBW == 1) // repeating) + if(m_TEX0.TBW == 1 && m_tw != 0) // repeating) { // FIXME: // - marking a block prevents fetching it again to a different part of the texture // - only a real issue for TBW = 1 mipmap levels, where the repeating part is below and often exploited (onimusha 3 intro / sidewalk) - r = GSVector4i(0, 0, tw, th); + // r = GSVector4i(0, 0, tw, th); + r.top = 0; + r.bottom = th; } r = r.ralign(bs);