1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Use fixed point calculation for texrect s and t coordinates.

It is impossible to handle integer overflow when coordinates in float format.

Fixed textures in Major League Baseball #146
This commit is contained in:
Sergey Lipskiy 2017-11-11 23:43:01 +07:00
parent 9d735212f0
commit 737338ca20
7 changed files with 64 additions and 42 deletions

View File

@ -306,7 +306,7 @@ void RDRAMtoColorBuffer::copyFromRDRAM(u32 _address, bool _bCFB)
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, m_pCurBuffer->m_FBO);
GraphicsDrawer::TexturedRectParams texRectParams((float)x0, (float)y0, (float)width, (float)height,
0.0f, 0.0f, width - 1.0f, height - 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0, 0,
false, true, false, m_pCurBuffer);
dwnd().getDrawer().drawTexturedRect(texRectParams);

View File

@ -999,7 +999,7 @@ bool texturedRectDepthBufferCopy(const GraphicsDrawer::TexturedRectParams & _par
const u32 width = (u32)(_params.lrx - _params.ulx);
const u32 ulx = (u32)_params.ulx;
u16 * pSrc = ((u16*)TMEM) + (u32)floorf(_params.uls + 0.5f);
u16 * pSrc = ((u16*)TMEM) + _params.s/32;
u16 *pDst = (u16*)(RDRAM + gDP.colorImage.address);
for (u32 x = 0; x < width; ++x)
pDst[(ulx + x) ^ 1] = swapword(pSrc[x]);
@ -1033,7 +1033,7 @@ bool texturedRectBGCopy(const GraphicsDrawer::TexturedRectParams & _params)
const u32 uly = (u32)_params.uly;
const u32 lry = (u32)flry;
u8 * texaddr = RDRAM + gDP.loadInfo[gSP.textureTile[0]->tmem].texAddress + tex_width*(u32)_params.ult + (u32)_params.uls;
u8 * texaddr = RDRAM + gDP.loadInfo[gSP.textureTile[0]->tmem].texAddress + tex_width*_params.t/32 + _params.s/32;
u8 * fbaddr = RDRAM + gDP.colorImage.address + (u32)_params.ulx;
// LOG(LOG_VERBOSE, "memrect (%d, %d, %d, %d), ci_width: %d texaddr: 0x%08lx fbaddr: 0x%08lx\n", (u32)_params.ulx, uly, (u32)_params.lrx, lry, gDP.colorImage.width, gSP.textureTile[0]->imageAddress + tex_width*(u32)_params.ult + (u32)_params.uls, gDP.colorImage.address + (u32)_params.ulx);
@ -1169,24 +1169,58 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
float s0, t0, s1, t1;
} texST[2] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; //struct for texture coordinates
float offsetX, offsetY;
if (_params.flip) {
offsetX = (_params.lry - _params.uly) * _params.dsdx;
offsetY = (_params.lrx - _params.ulx) * _params.dtdy;
} else {
offsetX = (_params.lrx - _params.ulx) * _params.dsdx;
offsetY = (_params.lry - _params.uly) * _params.dtdy;
}
for (u32 t = 0; t < 2; ++t) {
if (pCurrentCombiner->usesTile(t) && cache.current[t] && gSP.textureTile[t]) {
f32 shiftScaleS = 1.0f;
f32 shiftScaleT = 1.0f;
getTextureShiftScale(t, cache, shiftScaleS, shiftScaleT);
if (_params.uls > _params.lrs) {
texST[t].s0 = (_params.uls + _params.dsdx) * shiftScaleS - gSP.textureTile[t]->fuls;
texST[t].s1 = _params.lrs * shiftScaleS - gSP.textureTile[t]->fuls;
} else {
texST[t].s0 = _params.uls * shiftScaleS - gSP.textureTile[t]->fuls;
texST[t].s1 = (_params.lrs + _params.dsdx) * shiftScaleS - gSP.textureTile[t]->fuls;
s16 S = _params.s;
if (gSP.textureTile[t]->shifts > 10) {
const u32 shifts = 16 - gSP.textureTile[t]->shifts;
S = (s16)(S << shifts);
shiftScaleS = (f32)(1 << shifts);
} else if (gSP.textureTile[t]->shifts > 0) {
const u32 shifts = gSP.textureTile[t]->shifts;
S = (s16)(S >> shifts);
shiftScaleS /= (f32)(1 << shifts);
}
if (_params.ult > _params.lrt) {
texST[t].t0 = (_params.ult + _params.dtdy) * shiftScaleT - gSP.textureTile[t]->fult;
texST[t].t1 = _params.lrt * shiftScaleT - gSP.textureTile[t]->fult;
} else {
texST[t].t0 = _params.ult * shiftScaleT - gSP.textureTile[t]->fult;
texST[t].t1 = (_params.lrt + _params.dtdy) * shiftScaleT - gSP.textureTile[t]->fult;
const f32 uls = _FIXED2FLOAT(S, 5);
const f32 lrs = uls + offsetX * shiftScaleS;
s16 T = _params.t;
if (gSP.textureTile[t]->shiftt > 10) {
const u32 shiftt = 16 - gSP.textureTile[t]->shiftt;
T = (s16)(T << shiftt);
shiftScaleT = (f32)(1 << shiftt);
} else if (gSP.textureTile[t]->shiftt > 0) {
const u32 shiftt = gSP.textureTile[t]->shiftt;
T = (s16)(T >> shiftt);
shiftScaleT /= (f32)(1 << shiftt);
}
const f32 ult = _FIXED2FLOAT(T, 5);
const f32 lrt = ult + offsetY * shiftScaleT;
texST[t].s0 = uls - gSP.textureTile[t]->fuls;
texST[t].s1 = lrs - gSP.textureTile[t]->fuls;
texST[t].t0 = ult - gSP.textureTile[t]->fult;
texST[t].t1 = lrt - gSP.textureTile[t]->fult;
if (uls > lrs) {
texST[t].s0 -= _params.dsdx * shiftScaleS;
texST[t].s1 -= _params.dsdx * shiftScaleS;
}
if (ult > lrt) {
texST[t].t0 -= _params.dtdy * shiftScaleT;
texST[t].t1 -= _params.dtdy * shiftScaleT;
}
if (cache.current[t]->frameBufferTexture != CachedTexture::fbNone) {

View File

@ -55,19 +55,19 @@ public:
struct TexturedRectParams
{
float ulx, uly, lrx, lry;
float uls, ult, lrs, lrt;
float dsdx, dtdy;
s16 s, t;
bool flip, forceAjustScale, texrectCmd;
const FrameBuffer * pBuffer;
TexturedRectParams(float _ulx, float _uly, float _lrx, float _lry,
float _uls, float _ult, float _lrs, float _lrt,
float _dsdx, float _dtdy,
s16 _s, s16 _t,
bool _flip, bool _forceAjustScale, bool _texrectCmd,
const FrameBuffer * _pBuffer
) :
ulx(_ulx), uly(_uly), lrx(_lrx), lry(_lry),
uls(_uls), ult(_ult), lrs(_lrs), lrt(_lrt),
dsdx(_dsdx), dtdy(_dtdy),
s(_s), t(_t),
flip(_flip), forceAjustScale(_forceAjustScale), texrectCmd(_texrectCmd),
pBuffer(_pBuffer)
{}

View File

@ -308,8 +308,8 @@ void _TexRect( u32 w0, u32 w1, bool flip )
_FIXED2FLOAT(lrx, 2),
_FIXED2FLOAT(lry, 2),
_SHIFTR(w1, 24, 3), // tile
_FIXED2FLOAT((s16)_SHIFTR(w2, 16, 16), 5), // s
_FIXED2FLOAT((s16)_SHIFTR(w2, 0, 16), 5), // t
(s16)_SHIFTR(w2, 16, 16), // s
(s16)_SHIFTR(w2, 0, 16), // t
_FIXED2FLOAT((s16)_SHIFTR(w3, 16, 16), 10), // dsdx
_FIXED2FLOAT((s16)_SHIFTR(w3, 0, 16), 10), // dsdy
flip);

View File

@ -799,7 +799,7 @@ void gDPSetKeyGB(u32 cG, u32 sG, u32 wG, u32 cB, u32 sB, u32 wB )
cG, sG, wG, cB, sB, wB );
}
void gDPTextureRectangle(f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f32 t, f32 dsdx, f32 dtdy , bool flip)
void gDPTextureRectangle(f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, s16 s, s16 t, f32 dsdx, f32 dtdy , bool flip)
{
if (gDP.otherMode.cycleType == G_CYC_COPY) {
dsdx = 1.0f;
@ -815,18 +815,9 @@ void gDPTextureRectangle(f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f3
gSP.textureTile[1] = &gDP.tiles[(tile + 1) & 7];
// HACK ALERT!
if ((int(s) == 512) && (gDP.colorImage.width + gSP.textureTile[0]->uls < 512))
if (s == 0x4000 && (gDP.colorImage.width + gSP.textureTile[0]->uls < 512))
s = 0.0f;
f32 lrs, lrt;
if (flip) {
lrs = s + (lry - uly - 1) * dsdx;
lrt = t + (lrx - ulx - 1) * dtdy;
} else {
lrs = s + (lrx - ulx - 1) * dsdx;
lrt = t + (lry - uly - 1) * dtdy;
}
gDP.rectColor = gDPInfo::Color();
if (gDP.otherMode.cycleType < G_CYC_COPY) {
if ((config.generalEmulation.hacks & hack_texrect_shade_alpha) != 0 &&
@ -835,7 +826,7 @@ void gDPTextureRectangle(f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f3
}
GraphicsDrawer & drawer = dwnd().getDrawer();
GraphicsDrawer::TexturedRectParams params(ulx, uly, lrx, lry, s, t, lrs, lrt, fabsf(dsdx), fabsf(dtdy),
GraphicsDrawer::TexturedRectParams params(ulx, uly, lrx, lry, dsdx, dtdy, s, t,
flip, false, true, frameBufferList().getCurrent());
if (config.generalEmulation.enableNativeResTexrects == 0 && config.generalEmulation.correctTexrectCoords != Config::tcDisable)
drawer.correctTexturedRectParams(params);
@ -847,11 +838,11 @@ void gDPTextureRectangle(f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f3
frameBufferList().setBufferChanged(lry);
if (flip)
DebugMsg( DEBUG_NORMAL, "gDPTextureRectangleFlip #%i- #%i ( %f, %f, %f, %f, %i, %f, %f, %f, %f);\n",
gSP.tri_num, gSP.tri_num + 1, ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy );
DebugMsg( DEBUG_NORMAL, "gDPTextureRectangleFlip( %f, %f, %f, %f, %i, %f, %f, %f, %f);\n",
ulx, uly, lrx, lry, tile, s/32.0f, t/32.0f, dsdx, dtdy );
else
DebugMsg( DEBUG_NORMAL, "gDPTextureRectangle #%i- #%i ( %f, %f, %f, %f, %i, %i, %f, %f, %f, %f );\n",
gSP.tri_num, gSP.tri_num+1, ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy );
DebugMsg( DEBUG_NORMAL, "gDPTextureRectangle( %f, %f, %f, %f, %i, %i, %f, %f, %f, %f );\n",
ulx, uly, lrx, lry, tile, s/32.0f, t/32.0f, dsdx, dtdy);
gSP.tri_num += 2;
}

View File

@ -279,7 +279,7 @@ void gDPFillRectangle( s32 ulx, s32 uly, s32 lrx, s32 lry );
void gDPSetConvert( s32 k0, s32 k1, s32 k2, s32 k3, s32 k4, s32 k5 );
void gDPSetKeyR( u32 cR, u32 sR, u32 wR );
void gDPSetKeyGB(u32 cG, u32 sG, u32 wG, u32 cB, u32 sB, u32 wB );
void gDPTextureRectangle( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f32 t, f32 dsdx, f32 dtdy, bool flip );
void gDPTextureRectangle( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, s16 s, s16 t, f32 dsdx, f32 dtdy, bool flip );
void gDPFullSync();
void gDPTileSync();
void gDPPipeSync();

View File

@ -1243,9 +1243,6 @@ void F3DSWRS_TexrectGen(u32 _w0, u32 _w1)
T = ((0 - (dtdy_i << 6) * uly_i) << 3) + F + 0xFFF0;
}
const f32 s = _FIXED2FLOAT((s16)S, 5);
const f32 t = _FIXED2FLOAT((s16)T, 5);
gDP.primDepth.z = v.z/v.w;
gDP.primDepth.deltaZ = 0.0f;
@ -1265,7 +1262,7 @@ void F3DSWRS_TexrectGen(u32 _w0, u32 _w1)
_SHIFTR( fogColor, 0, 8 ) ); // a
}
gDPTextureRectangle(ulx, uly, lrx, lry, gSP.texture.tile, s, t, dsdx, dtdy , flip);
gDPTextureRectangle(ulx, uly, lrx, lry, gSP.texture.tile, (s16)S, (s16)T, dsdx, dtdy, flip);
}
void F3DSWRS_SetOtherMode_H_EX(u32 _w0, u32 _w1)