mirror of
https://github.com/PCSX2/gsdx-sourceforge.git
synced 2026-02-04 03:11:19 +01:00
This commit is contained in:
@@ -1725,7 +1725,20 @@ void GSLocalMemory::ReadTextureNP(const CRect& r, BYTE* dst, int dstpitch, GIFRe
|
||||
|| (r.right & (bs.cx-1)) || (r.bottom & (bs.cy-1))
|
||||
|| (CLAMP.WMS == 3) || (CLAMP.WMT == 3))
|
||||
{
|
||||
switch(TEX0.PSM)
|
||||
DWORD psm = TEX0.PSM;
|
||||
|
||||
switch(psm)
|
||||
{
|
||||
case PSM_PSMT8:
|
||||
case PSM_PSMT8H:
|
||||
case PSM_PSMT4:
|
||||
case PSM_PSMT4HL:
|
||||
case PSM_PSMT4HH:
|
||||
psm = TEX0.CPSM;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(psm)
|
||||
{
|
||||
default:
|
||||
case PSM_PSMCT32:
|
||||
@@ -1736,23 +1749,47 @@ void GSLocalMemory::ReadTextureNP(const CRect& r, BYTE* dst, int dstpitch, GIFRe
|
||||
case PSM_PSMCT16S:
|
||||
ReadTexture<WORD>(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, st);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(this->*st)(r, dst, dstpitch, TEX0, TEXA);
|
||||
}
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTextureNP2(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP)
|
||||
{
|
||||
unSwizzleTexture st = m_psm[TEX0.PSM].ustNP;
|
||||
readTexel rt = m_psm[TEX0.PSM].rtNP;
|
||||
CSize bs = m_psm[TEX0.PSM].bs;
|
||||
|
||||
if(r.Width() < bs.cx || r.Height() < bs.cy
|
||||
|| (r.left & (bs.cx-1)) || (r.top & (bs.cy-1))
|
||||
|| (r.right & (bs.cx-1)) || (r.bottom & (bs.cy-1)))
|
||||
{
|
||||
DWORD psm = TEX0.PSM;
|
||||
|
||||
switch(psm)
|
||||
{
|
||||
case PSM_PSMT8:
|
||||
case PSM_PSMT8H:
|
||||
case PSM_PSMT4:
|
||||
case PSM_PSMT4HL:
|
||||
case PSM_PSMT4HH:
|
||||
switch(TEX0.CPSM)
|
||||
{
|
||||
default:
|
||||
ASSERT(0);
|
||||
case PSM_PSMCT32:
|
||||
ReadTexture<DWORD>(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, st);
|
||||
break;
|
||||
case PSM_PSMCT16:
|
||||
case PSM_PSMCT16S:
|
||||
ReadTexture<WORD>(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, st);
|
||||
break;
|
||||
}
|
||||
psm = TEX0.CPSM;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(psm)
|
||||
{
|
||||
default:
|
||||
case PSM_PSMCT32:
|
||||
case PSM_PSMCT24:
|
||||
ReadTexture2<DWORD>(r, dst, dstpitch, TEX0, TEXA, rt, st);
|
||||
break;
|
||||
case PSM_PSMCT16:
|
||||
case PSM_PSMCT16S:
|
||||
ReadTexture2<WORD>(r, dst, dstpitch, TEX0, TEXA, rt, st);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2005,6 +2042,56 @@ if(!aligned) printf("unaligned memory pointer passed to ReadTexture\n");
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void GSLocalMemory::ReadTexture2(CRect r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, readTexel rt, unSwizzleTexture st)
|
||||
{
|
||||
CSize bs = m_psm[TEX0.PSM].bs;
|
||||
|
||||
int bsxm = bs.cx - 1;
|
||||
int bsym = bs.cy - 1;
|
||||
|
||||
CRect cr;
|
||||
|
||||
cr.left = (r.left + bsxm) & ~bsxm;
|
||||
cr.top = (r.top + bsym) & ~bsym;
|
||||
cr.right = r.right & ~bsxm;
|
||||
cr.bottom = r.bottom & ~bsym;
|
||||
|
||||
bool aligned = ((DWORD_PTR)(dst + (cr.left - r.left) * sizeof(T)) & 0xf) == 0;
|
||||
|
||||
if(cr.left >= cr.right && cr.top >= cr.bottom || !aligned)
|
||||
{
|
||||
// TODO: expand r to block size, read into temp buffer, copy to r (like above)
|
||||
|
||||
if(!aligned) printf("unaligned memory pointer passed to ReadTexture\n");
|
||||
|
||||
for(int y = r.top; y < r.bottom; y++, dst += dstpitch)
|
||||
for(int x = r.left, i = 0; x < r.right; x++, i++)
|
||||
((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int y = r.top; y < cr.top; y++, dst += dstpitch)
|
||||
for(int x = r.left, i = 0; x < r.right; x++, i++)
|
||||
((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA);
|
||||
|
||||
if(!cr.IsRectEmpty())
|
||||
(this->*st)(cr, dst + (cr.left - r.left)*sizeof(T), dstpitch, TEX0, TEXA);
|
||||
|
||||
for(int y = cr.top; y < cr.bottom; y++, dst += dstpitch)
|
||||
{
|
||||
for(int x = r.left, i = 0; x < cr.left; x++, i++)
|
||||
((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA);
|
||||
for(int x = cr.right, i = x - r.left; x < r.right; x++, i++)
|
||||
((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA);
|
||||
}
|
||||
|
||||
for(int y = cr.bottom; y < r.bottom; y++, dst += dstpitch)
|
||||
for(int x = r.left, i = 0; x < r.right; x++, i++)
|
||||
((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
HRESULT GSLocalMemory::SaveBMP(LPCTSTR fn, DWORD bp, DWORD bw, DWORD psm, int w, int h)
|
||||
|
||||
@@ -907,12 +907,14 @@ public:
|
||||
void unSwizzleTexture4HHNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
|
||||
|
||||
void ReadTextureNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP);
|
||||
void ReadTextureNP2(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP);
|
||||
|
||||
//
|
||||
|
||||
static DWORD m_xtbl[1024], m_ytbl[1024];
|
||||
|
||||
template<typename T> void ReadTexture(CRect r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP, readTexel rt, unSwizzleTexture st);
|
||||
template<typename T> void ReadTexture2(CRect r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, readTexel rt, unSwizzleTexture st);
|
||||
|
||||
HRESULT SaveBMP(LPCTSTR fn, DWORD bp, DWORD bw, DWORD psm, int w, int h);
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
int s_n = 0;
|
||||
bool s_dump = false;
|
||||
bool s_save = false;
|
||||
bool s_save = true;
|
||||
bool s_savez = false;
|
||||
|
||||
GSRendererHW::GSRendererHW(BYTE* base, bool mt, void (*irq)(), bool nloophack)
|
||||
@@ -424,7 +424,8 @@ if(s_dump)
|
||||
GSTextureFX::PSSelector ps_sel;
|
||||
|
||||
ps_sel.fst = PRIM->FST;
|
||||
ps_sel.clamp = 0;
|
||||
ps_sel.wms = m_context->CLAMP.WMS;
|
||||
ps_sel.wmt = m_context->CLAMP.WMT;
|
||||
ps_sel.bpp = 0;
|
||||
ps_sel.aem = m_env.TEXA.AEM;
|
||||
ps_sel.tfx = m_context->TEX0.TFX;
|
||||
@@ -436,6 +437,9 @@ if(s_dump)
|
||||
ps_sel.fba = m_context->FBA.FBA;
|
||||
ps_sel.aout = m_context->FRAME.PSM == PSM_PSMCT16 || m_context->FRAME.PSM == PSM_PSMCT16S || (m_context->FRAME.FBMSK & 0xff000000) == 0x7f000000 ? 1 : 0;
|
||||
|
||||
//if(ps_sel.wms == 3) ps_sel.wms = 0;
|
||||
//if(ps_sel.wmt == 3) ps_sel.wmt = 0;
|
||||
|
||||
GSTextureFX::PSSamplerSelector ps_ssel;
|
||||
|
||||
ps_ssel.min = m_filter == 2 ? (m_context->TEX1.MMIN & 1) : m_filter;
|
||||
@@ -445,9 +449,9 @@ if(s_dump)
|
||||
|
||||
GSTextureFX::PSConstantBuffer ps_cb;
|
||||
|
||||
memset(&ps_cb, 0, sizeof(ps_cb));
|
||||
|
||||
ps_cb.FogColor = D3DXVECTOR4((float)(int)m_env.FOGCOL.FCR / 255, (float)(int)m_env.FOGCOL.FCG / 255, (float)(int)m_env.FOGCOL.FCB / 255, 0);
|
||||
ps_cb.ClampMin = D3DXVECTOR2(-4096, -4096);
|
||||
ps_cb.ClampMax = D3DXVECTOR2(+4096, +4096);
|
||||
ps_cb.TA0 = (float)(int)m_env.TEXA.TA0 / 255;
|
||||
ps_cb.TA1 = (float)(int)m_env.TEXA.TA1 / 255;
|
||||
ps_cb.AREF = (float)(int)m_context->TEST.AREF / 255;
|
||||
@@ -470,30 +474,46 @@ if(s_dump)
|
||||
|
||||
switch(m_context->CLAMP.WMS)
|
||||
{
|
||||
case 0: case 3: ps_ssel.tau = 1; break;
|
||||
case 1: case 2: ps_ssel.tau = 0; break;
|
||||
default: __assume(0);
|
||||
case 0:
|
||||
ps_ssel.tau = 1;
|
||||
break;
|
||||
case 1:
|
||||
ps_ssel.tau = 0;
|
||||
break;
|
||||
case 2:
|
||||
ps_cb.MINU = (float)(int)m_context->CLAMP.MINU / (1 << m_context->TEX0.TW);
|
||||
ps_cb.MAXU = (float)(int)m_context->CLAMP.MAXU / (1 << m_context->TEX0.TW);
|
||||
ps_ssel.tau = 0;
|
||||
break;
|
||||
case 3:
|
||||
ps_cb.UMSK = m_context->CLAMP.MINU;
|
||||
ps_cb.UFIX = m_context->CLAMP.MAXU;
|
||||
ps_ssel.tau = 1;
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
|
||||
switch(m_context->CLAMP.WMT)
|
||||
{
|
||||
case 0: case 3: ps_ssel.tav = 1; break;
|
||||
case 1: case 2: ps_ssel.tav = 0; break;
|
||||
default: __assume(0);
|
||||
}
|
||||
|
||||
if(m_context->CLAMP.WMS == 2)
|
||||
{
|
||||
ps_cb.ClampMin.x = (float)(int)m_context->CLAMP.MINU / (1 << m_context->TEX0.TW);
|
||||
ps_cb.ClampMax.x = (float)(int)m_context->CLAMP.MAXU / (1 << m_context->TEX0.TW);
|
||||
ps_sel.clamp = 1;
|
||||
}
|
||||
|
||||
if(m_context->CLAMP.WMT == 2)
|
||||
{
|
||||
ps_cb.ClampMin.y = (float)(int)m_context->CLAMP.MINV / (1 << m_context->TEX0.TH);
|
||||
ps_cb.ClampMax.y = (float)(int)m_context->CLAMP.MAXV / (1 << m_context->TEX0.TH);
|
||||
ps_sel.clamp = 1;
|
||||
case 0:
|
||||
ps_ssel.tav = 1;
|
||||
break;
|
||||
case 1:
|
||||
ps_ssel.tav = 0;
|
||||
break;
|
||||
case 2:
|
||||
ps_cb.MINV = (float)(int)m_context->CLAMP.MINV / (1 << m_context->TEX0.TH);
|
||||
ps_cb.MAXV = (float)(int)m_context->CLAMP.MAXV / (1 << m_context->TEX0.TH);
|
||||
ps_ssel.tav = 0;
|
||||
break;
|
||||
case 3:
|
||||
ps_cb.VMSK = m_context->CLAMP.MINV;
|
||||
ps_cb.VFIX = m_context->CLAMP.MAXV;
|
||||
ps_ssel.tav = 1;
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
|
||||
float w = (float)(int)tex->m_texture.m_desc.Width;
|
||||
@@ -657,32 +677,25 @@ void GSRendererHW::MinMaxUV(int w, int h, CRect& r)
|
||||
{
|
||||
r.SetRect(0, 0, w, h);
|
||||
|
||||
if(m_count > 100)
|
||||
{
|
||||
return;
|
||||
}
|
||||
uvmm_t uv;
|
||||
|
||||
uv.umin = uv.vmin = 0;
|
||||
uv.umax = uv.vmax = 1;
|
||||
|
||||
if(m_context->CLAMP.WMS < 3 || m_context->CLAMP.WMT < 3)
|
||||
{
|
||||
uvmm_t uv;
|
||||
|
||||
uv.umin = uv.vmin = 0;
|
||||
uv.umax = uv.vmax = 1;
|
||||
|
||||
if(PRIM->FST)
|
||||
if(m_count < 100)
|
||||
{
|
||||
UVMinMax(m_count, (vertex_t*)m_vertices, &uv);
|
||||
if(PRIM->FST)
|
||||
{
|
||||
UVMinMax(m_count, (vertex_t*)m_vertices, &uv);
|
||||
|
||||
uv.umin *= 1.0f / (16 << m_context->TEX0.TW);
|
||||
uv.umax *= 1.0f / (16 << m_context->TEX0.TW);
|
||||
uv.vmin *= 1.0f / (16 << m_context->TEX0.TH);
|
||||
uv.vmax *= 1.0f / (16 << m_context->TEX0.TH);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME
|
||||
|
||||
if(m_count > 0)// && m_count < 100)
|
||||
uv.umin *= 1.0f / (16 << m_context->TEX0.TW);
|
||||
uv.umax *= 1.0f / (16 << m_context->TEX0.TW);
|
||||
uv.vmin *= 1.0f / (16 << m_context->TEX0.TH);
|
||||
uv.vmax *= 1.0f / (16 << m_context->TEX0.TH);
|
||||
}
|
||||
else
|
||||
{
|
||||
uv.umin = uv.vmin = +1e10;
|
||||
uv.umax = uv.vmax = -1e10;
|
||||
@@ -699,86 +712,99 @@ void GSRendererHW::MinMaxUV(int w, int h, CRect& r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CSize bs = GSLocalMemory::m_psm[m_context->TEX0.PSM].bs;
|
||||
|
||||
CSize bsm(bs.cx-1, bs.cy-1);
|
||||
|
||||
if(m_context->CLAMP.WMS < 3)
|
||||
{
|
||||
if(m_context->CLAMP.WMS == 0)
|
||||
{
|
||||
float fmin = floor(uv.umin);
|
||||
float fmax = floor(uv.umax);
|
||||
|
||||
if(fmin != fmax) {uv.umin = 0; uv.umax = 1.0f;}
|
||||
else {uv.umin -= fmin; uv.umax -= fmax;}
|
||||
|
||||
// FIXME:
|
||||
if(uv.umin == 0 && uv.umax != 1.0f) uv.umax = 1.0f;
|
||||
}
|
||||
else if(m_context->CLAMP.WMS == 1)
|
||||
{
|
||||
if(uv.umin < 0) uv.umin = 0;
|
||||
else if(uv.umin > 1.0f) uv.umin = 1.0f;
|
||||
if(uv.umax < 0) uv.umax = 0;
|
||||
else if(uv.umax > 1.0f) uv.umax = 1.0f;
|
||||
if(uv.umin > uv.umax) uv.umin = uv.umax;
|
||||
}
|
||||
else if(m_context->CLAMP.WMS == 2)
|
||||
{
|
||||
float minu = 1.0f * m_context->CLAMP.MINU / w;
|
||||
float maxu = 1.0f * m_context->CLAMP.MAXU / w;
|
||||
if(uv.umin < minu) uv.umin = minu;
|
||||
else if(uv.umin > maxu) uv.umin = maxu;
|
||||
if(uv.umax < minu) uv.umax = minu;
|
||||
else if(uv.umax > maxu) uv.umax = maxu;
|
||||
if(uv.umin > uv.umax) uv.umin = uv.umax;
|
||||
}
|
||||
|
||||
r.left = max((int)(uv.umin * w) & ~bsm.cx, 0);
|
||||
r.right = min(((int)(uv.umax * w) + bsm.cx + 1) & ~bsm.cx, w);
|
||||
}
|
||||
|
||||
if(m_context->CLAMP.WMT < 3)
|
||||
{
|
||||
if(m_context->CLAMP.WMT == 0)
|
||||
{
|
||||
float fmin = floor(uv.vmin);
|
||||
float fmax = floor(uv.vmax);
|
||||
|
||||
if(fmin != fmax) {uv.vmin = 0; uv.vmax = 1.0f;}
|
||||
else {uv.vmin -= fmin; uv.vmax -= fmax;}
|
||||
|
||||
// FIXME:
|
||||
if(uv.vmin == 0 && uv.vmax != 1.0f) uv.vmax = 1.0f;
|
||||
}
|
||||
else if(m_context->CLAMP.WMT == 1)
|
||||
{
|
||||
if(uv.vmin < 0) uv.vmin = 0;
|
||||
else if(uv.vmin > 1.0f) uv.vmin = 1.0f;
|
||||
if(uv.vmax < 0) uv.vmax = 0;
|
||||
else if(uv.vmax > 1.0f) uv.vmax = 1.0f;
|
||||
if(uv.vmin > uv.vmax) uv.vmin = uv.vmax;
|
||||
}
|
||||
else if(m_context->CLAMP.WMT == 2)
|
||||
{
|
||||
float minv = 1.0f * m_context->CLAMP.MINV / h;
|
||||
float maxv = 1.0f * m_context->CLAMP.MAXV / h;
|
||||
if(uv.vmin < minv) uv.vmin = minv;
|
||||
else if(uv.vmin > maxv) uv.vmin = maxv;
|
||||
if(uv.vmax < minv) uv.vmax = minv;
|
||||
else if(uv.vmax > maxv) uv.vmax = maxv;
|
||||
if(uv.vmin > uv.vmax) uv.vmin = uv.vmax;
|
||||
}
|
||||
|
||||
r.top = max((int)(uv.vmin * h) & ~bsm.cy, 0);
|
||||
r.bottom = min(((int)(uv.vmax * h) + bsm.cy + 1) & ~bsm.cy, h);
|
||||
}
|
||||
}
|
||||
|
||||
//ASSERT(r.left <= r.right);
|
||||
//ASSERT(r.top <= r.bottom);
|
||||
CSize bs = GSLocalMemory::m_psm[m_context->TEX0.PSM].bs;
|
||||
|
||||
CSize bsm(bs.cx - 1, bs.cy - 1);
|
||||
|
||||
if(m_context->CLAMP.WMS != 3)
|
||||
{
|
||||
if(m_context->CLAMP.WMS == 0)
|
||||
{
|
||||
float fmin = floor(uv.umin);
|
||||
float fmax = floor(uv.umax);
|
||||
|
||||
if(fmin != fmax) {uv.umin = 0; uv.umax = 1.0f;}
|
||||
else {uv.umin -= fmin; uv.umax -= fmax;}
|
||||
|
||||
// FIXME:
|
||||
if(uv.umin == 0 && uv.umax != 1.0f) uv.umax = 1.0f;
|
||||
}
|
||||
else if(m_context->CLAMP.WMS == 1)
|
||||
{
|
||||
if(uv.umin < 0) uv.umin = 0;
|
||||
else if(uv.umin > 1.0f) uv.umin = 1.0f;
|
||||
if(uv.umax < 0) uv.umax = 0;
|
||||
else if(uv.umax > 1.0f) uv.umax = 1.0f;
|
||||
if(uv.umin > uv.umax) uv.umin = uv.umax;
|
||||
}
|
||||
else if(m_context->CLAMP.WMS == 2)
|
||||
{
|
||||
float minu = 1.0f * m_context->CLAMP.MINU / w;
|
||||
float maxu = 1.0f * m_context->CLAMP.MAXU / w;
|
||||
if(uv.umin < minu) uv.umin = minu;
|
||||
else if(uv.umin > maxu) uv.umin = maxu;
|
||||
if(uv.umax < minu) uv.umax = minu;
|
||||
else if(uv.umax > maxu) uv.umax = maxu;
|
||||
if(uv.umin > uv.umax) uv.umin = uv.umax;
|
||||
}
|
||||
|
||||
r.left = (int)(uv.umin * w);
|
||||
r.right = (int)(uv.umax * w);
|
||||
}
|
||||
else
|
||||
{
|
||||
r.left = m_context->CLAMP.MAXU;
|
||||
r.right = r.left + (m_context->CLAMP.MINU + 1);
|
||||
}
|
||||
|
||||
if(m_context->CLAMP.WMT != 3)
|
||||
{
|
||||
if(m_context->CLAMP.WMT == 0)
|
||||
{
|
||||
float fmin = floor(uv.vmin);
|
||||
float fmax = floor(uv.vmax);
|
||||
|
||||
if(fmin != fmax) {uv.vmin = 0; uv.vmax = 1.0f;}
|
||||
else {uv.vmin -= fmin; uv.vmax -= fmax;}
|
||||
|
||||
// FIXME:
|
||||
if(uv.vmin == 0 && uv.vmax != 1.0f) uv.vmax = 1.0f;
|
||||
}
|
||||
else if(m_context->CLAMP.WMT == 1)
|
||||
{
|
||||
if(uv.vmin < 0) uv.vmin = 0;
|
||||
else if(uv.vmin > 1.0f) uv.vmin = 1.0f;
|
||||
if(uv.vmax < 0) uv.vmax = 0;
|
||||
else if(uv.vmax > 1.0f) uv.vmax = 1.0f;
|
||||
if(uv.vmin > uv.vmax) uv.vmin = uv.vmax;
|
||||
}
|
||||
else if(m_context->CLAMP.WMT == 2)
|
||||
{
|
||||
float minv = 1.0f * m_context->CLAMP.MINV / h;
|
||||
float maxv = 1.0f * m_context->CLAMP.MAXV / h;
|
||||
if(uv.vmin < minv) uv.vmin = minv;
|
||||
else if(uv.vmin > maxv) uv.vmin = maxv;
|
||||
if(uv.vmax < minv) uv.vmax = minv;
|
||||
else if(uv.vmax > maxv) uv.vmax = maxv;
|
||||
if(uv.vmin > uv.vmax) uv.vmin = uv.vmax;
|
||||
}
|
||||
|
||||
r.top = (int)(uv.vmin * h);
|
||||
r.bottom = (int)(uv.vmax * h);
|
||||
}
|
||||
else
|
||||
{
|
||||
r.top = m_context->CLAMP.MAXV;
|
||||
r.bottom = r.top + (m_context->CLAMP.MINV + 1);
|
||||
}
|
||||
|
||||
r.left = max(r.left & ~bsm.cx, 0);
|
||||
r.right = min((r.right + bsm.cx + 1) & ~bsm.cx, w);
|
||||
|
||||
r.top = max(r.top & ~bsm.cy, 0);
|
||||
r.bottom = min((r.bottom + bsm.cy + 1) & ~bsm.cy, h);
|
||||
}
|
||||
|
||||
void GSRendererHW::SetupDATE(GSTextureCache::GSRenderTarget* rt, GSTextureCache::GSDepthStencil* ds)
|
||||
|
||||
@@ -40,7 +40,6 @@ bool GSTextureCache::GSTexture::Create()
|
||||
HRESULT hr;
|
||||
|
||||
m_TEX0 = m_tc->m_renderer->m_context->TEX0;
|
||||
m_CLAMP = m_tc->m_renderer->m_context->CLAMP;
|
||||
|
||||
DWORD psm = m_TEX0.PSM;
|
||||
|
||||
@@ -97,7 +96,6 @@ bool GSTextureCache::GSTexture::Create(GSRenderTarget* rt)
|
||||
|
||||
m_scale = rt->m_scale;
|
||||
m_TEX0 = m_tc->m_renderer->m_context->TEX0;
|
||||
m_CLAMP = m_tc->m_renderer->m_context->CLAMP;
|
||||
m_rendered = true;
|
||||
|
||||
int tw = 1 << m_TEX0.TW;
|
||||
@@ -292,7 +290,7 @@ void GSTextureCache::GSTexture::Update()
|
||||
|
||||
BYTE* bits = buff + pitch * r.top + (r.left * m_bpp >> 3);
|
||||
|
||||
GSLocalMemory::readTexture rt = &GSLocalMemory::ReadTextureNP;
|
||||
GSLocalMemory::readTexture rt = &GSLocalMemory::ReadTextureNP2;
|
||||
|
||||
(m_tc->m_renderer->m_mem.*rt)(r, bits, pitch, m_tc->m_renderer->m_context->TEX0, m_tc->m_renderer->m_env.TEXA, m_tc->m_renderer->m_context->CLAMP);
|
||||
|
||||
|
||||
@@ -201,7 +201,6 @@ GSTextureCache::GSDepthStencil* GSTextureCache::GetDepthStencil(const GIFRegTEX0
|
||||
GSTextureCache::GSTexture* GSTextureCache::GetTexture()
|
||||
{
|
||||
const GIFRegTEX0& TEX0 = m_renderer->m_context->TEX0;
|
||||
const GIFRegCLAMP& CLAMP = m_renderer->m_context->CLAMP;
|
||||
|
||||
DWORD clut[256];
|
||||
|
||||
@@ -271,7 +270,6 @@ GSTextureCache::GSTexture* GSTextureCache::GetTexture()
|
||||
{
|
||||
if(TEX0.PSM == t->m_TEX0.PSM && TEX0.TBW == t->m_TEX0.TBW
|
||||
&& TEX0.TW == t->m_TEX0.TW && TEX0.TH == t->m_TEX0.TH
|
||||
&& (CLAMP.WMS != 3 && t->m_CLAMP.WMS != 3 && CLAMP.WMT != 3 && t->m_CLAMP.WMT != 3 || CLAMP.i64 == t->m_CLAMP.i64)
|
||||
&& (pal == 0 || TEX0.CPSM == t->m_TEX0.CPSM && !memcmp(t->m_clut, clut, pal * sizeof(clut[0]))))
|
||||
{
|
||||
m_tex.MoveToHead(pos);
|
||||
|
||||
@@ -75,7 +75,6 @@ public:
|
||||
bool GetDirtyRect(CRect& r);
|
||||
|
||||
public:
|
||||
GIFRegCLAMP m_CLAMP;
|
||||
DWORD m_clut[256]; // *
|
||||
CRect m_valid;
|
||||
int m_bpp;
|
||||
|
||||
@@ -194,35 +194,37 @@ void GSTextureFX::UpdatePS(PSSelector sel, PSSamplerSelector ssel)
|
||||
|
||||
if(!(ps = m_ps.Lookup(sel)))
|
||||
{
|
||||
CStringA str[12];
|
||||
CStringA str[13];
|
||||
|
||||
str[0].Format("%d", sel.fst);
|
||||
str[1].Format("%d", sel.clamp);
|
||||
str[2].Format("%d", sel.bpp);
|
||||
str[3].Format("%d", sel.aem);
|
||||
str[4].Format("%d", sel.tfx);
|
||||
str[5].Format("%d", sel.tcc);
|
||||
str[6].Format("%d", sel.ate);
|
||||
str[7].Format("%d", sel.atst);
|
||||
str[8].Format("%d", sel.fog);
|
||||
str[9].Format("%d", sel.clr1);
|
||||
str[10].Format("%d", sel.fba);
|
||||
str[11].Format("%d", sel.aout);
|
||||
str[1].Format("%d", sel.wms);
|
||||
str[2].Format("%d", sel.wmt);
|
||||
str[3].Format("%d", sel.bpp);
|
||||
str[4].Format("%d", sel.aem);
|
||||
str[5].Format("%d", sel.tfx);
|
||||
str[6].Format("%d", sel.tcc);
|
||||
str[7].Format("%d", sel.ate);
|
||||
str[8].Format("%d", sel.atst);
|
||||
str[9].Format("%d", sel.fog);
|
||||
str[10].Format("%d", sel.clr1);
|
||||
str[11].Format("%d", sel.fba);
|
||||
str[12].Format("%d", sel.aout);
|
||||
|
||||
D3D10_SHADER_MACRO macro[] =
|
||||
{
|
||||
{"FST", str[0]},
|
||||
{"CLAMP", str[1]},
|
||||
{"BPP", str[2]},
|
||||
{"AEM", str[3]},
|
||||
{"TFX", str[4]},
|
||||
{"TCC", str[5]},
|
||||
{"ATE", str[6]},
|
||||
{"ATST", str[7]},
|
||||
{"FOG", str[8]},
|
||||
{"CLR1", str[9]},
|
||||
{"FBA", str[10]},
|
||||
{"AOUT", str[11]},
|
||||
{"WMS", str[1]},
|
||||
{"WMT", str[2]},
|
||||
{"BPP", str[3]},
|
||||
{"AEM", str[4]},
|
||||
{"TFX", str[5]},
|
||||
{"TCC", str[6]},
|
||||
{"ATE", str[7]},
|
||||
{"ATST", str[8]},
|
||||
{"FOG", str[9]},
|
||||
{"CLR1", str[10]},
|
||||
{"FBA", str[11]},
|
||||
{"AOUT", str[12]},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
|
||||
@@ -40,8 +40,14 @@ public:
|
||||
struct PSConstantBuffer
|
||||
{
|
||||
D3DXVECTOR4 FogColor;
|
||||
D3DXVECTOR2 ClampMin;
|
||||
D3DXVECTOR2 ClampMax;
|
||||
float MINU;
|
||||
float MAXU;
|
||||
float MINV;
|
||||
float MAXV;
|
||||
DWORD UMSK;
|
||||
DWORD UFIX;
|
||||
DWORD VMSK;
|
||||
DWORD VFIX;
|
||||
float TA0;
|
||||
float TA1;
|
||||
float AREF;
|
||||
@@ -57,7 +63,8 @@ public:
|
||||
struct
|
||||
{
|
||||
DWORD fst:1;
|
||||
DWORD clamp:1;
|
||||
DWORD wms:2;
|
||||
DWORD wmt:2;
|
||||
DWORD bpp:3;
|
||||
DWORD aem:1;
|
||||
DWORD tfx:3;
|
||||
@@ -72,7 +79,7 @@ public:
|
||||
|
||||
DWORD dw;
|
||||
|
||||
operator DWORD() {return dw & 0x3ffff;}
|
||||
operator DWORD() {return dw & 0x1fffff;}
|
||||
};
|
||||
|
||||
union GSSelector
|
||||
|
||||
@@ -112,8 +112,14 @@ SamplerState Sampler;
|
||||
cbuffer cb1
|
||||
{
|
||||
float4 FogColor;
|
||||
float2 ClampMin;
|
||||
float2 ClampMax;
|
||||
float MINU;
|
||||
float MAXU;
|
||||
float MINV;
|
||||
float MAXV;
|
||||
uint UMSK;
|
||||
uint UFIX;
|
||||
uint VMSK;
|
||||
uint VFIX;
|
||||
float TA0;
|
||||
float TA1;
|
||||
float AREF;
|
||||
@@ -139,7 +145,8 @@ struct PS_OUTPUT
|
||||
|
||||
#ifndef FST
|
||||
#define FST 0
|
||||
#define CLAMP 0
|
||||
#define WMS 2
|
||||
#define WMT 3
|
||||
#define BPP 0
|
||||
#define AEM 0
|
||||
#define TFX 0
|
||||
@@ -169,6 +176,16 @@ float4 Extract16(uint i)
|
||||
return f;
|
||||
}
|
||||
|
||||
float RegionRepeat(float tc, float size, float rsize, uint msk, uint fix)
|
||||
{
|
||||
tc *= size;
|
||||
float f = frac(tc);
|
||||
tc = (float)(((int)tc & msk) | fix);
|
||||
tc += f;
|
||||
tc *= rsize;
|
||||
return tc;
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_main(PS_INPUT input)
|
||||
{
|
||||
float2 tc = input.t.xy;
|
||||
@@ -177,10 +194,25 @@ PS_OUTPUT ps_main(PS_INPUT input)
|
||||
{
|
||||
tc /= input.t.w;
|
||||
}
|
||||
|
||||
if(CLAMP == 1)
|
||||
|
||||
if(WMS == 2)
|
||||
{
|
||||
tc = clamp(tc, ClampMin, ClampMax);
|
||||
tc.x = clamp(tc.x, MINU, MAXU);
|
||||
}
|
||||
|
||||
if(WMS == 3)
|
||||
{
|
||||
tc.x = RegionRepeat(tc.x, WH.x, rWrH.x, UMSK, UFIX);
|
||||
}
|
||||
|
||||
if(WMT == 2)
|
||||
{
|
||||
tc.y = clamp(tc.y, MINV, MAXV);
|
||||
}
|
||||
|
||||
if(WMT == 3)
|
||||
{
|
||||
tc.y = RegionRepeat(tc.y, WH.y, rWrH.y, VMSK, VFIX);
|
||||
}
|
||||
|
||||
float4 t;
|
||||
|
||||
@@ -530,9 +530,45 @@ void GSTextureCache::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const
|
||||
if(HasSharedBits(BITBLTBUF.SBP, BITBLTBUF.SPSM, rt->m_TEX0.TBP0, rt->m_TEX0.PSM))
|
||||
{
|
||||
rt->Read(r);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
GSRenderTarget* rt2 = NULL;
|
||||
int ymin = INT_MAX;
|
||||
|
||||
pos = m_rt.GetHeadPosition();
|
||||
|
||||
while(pos)
|
||||
{
|
||||
GSRenderTarget* rt = m_rt.GetNext(pos);
|
||||
|
||||
if(HasSharedBits(BITBLTBUF.SPSM, rt->m_TEX0.PSM) && BITBLTBUF.SBP > rt->m_TEX0.TBP0)
|
||||
{
|
||||
// ffx2 pause screen background
|
||||
|
||||
DWORD rowsize = BITBLTBUF.SBW * 8192;
|
||||
DWORD offset = (BITBLTBUF.SBP - rt->m_TEX0.TBP0) * 256;
|
||||
|
||||
if(rowsize > 0 && offset % rowsize == 0)
|
||||
{
|
||||
int y = m_renderer->m_mem.m_psm[BITBLTBUF.SPSM].pgs.cy * offset / rowsize;
|
||||
|
||||
if(y < ymin && y < 512)
|
||||
{
|
||||
rt2 = rt;
|
||||
ymin = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(rt2)
|
||||
{
|
||||
rt2->Read(CRect(r.left, r.top + ymin, r.right, r.bottom + ymin));
|
||||
}
|
||||
|
||||
// TODO: ds
|
||||
}
|
||||
|
||||
void GSTextureCache::IncAge()
|
||||
|
||||
Reference in New Issue
Block a user