mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-04 10:03:36 +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:
parent
9d735212f0
commit
737338ca20
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
{}
|
||||
|
|
|
@ -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);
|
||||
|
|
23
src/gDP.cpp
23
src/gDP.cpp
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue
Block a user