mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-04 10:03:36 +00:00
Rewrite vertex coordinates calculation for gSPObjRectangle using fixed-point math decoded from S2DEX ucode by olivieryuyu
Code refactoring.
This commit is contained in:
parent
7d75b99705
commit
9192a82905
203
src/gSP.cpp
203
src/gSP.cpp
|
@ -1983,30 +1983,49 @@ void gSPSetSpriteTile(const uObjSprite *_pObjSprite)
|
||||||
gSPTexture( 1.0f, 1.0f, 0, 0, TRUE );
|
gSPTexture( 1.0f, 1.0f, 0, 0, TRUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ObjData
|
struct S2DEXCoordCorrector
|
||||||
{
|
{
|
||||||
f32 scaleW;
|
S2DEXCoordCorrector()
|
||||||
f32 scaleH;
|
|
||||||
u32 imageW;
|
|
||||||
u32 imageH;
|
|
||||||
f32 X0;
|
|
||||||
f32 X1;
|
|
||||||
f32 Y0;
|
|
||||||
f32 Y1;
|
|
||||||
bool flipS, flipT;
|
|
||||||
ObjData(const uObjSprite *_pObjSprite)
|
|
||||||
{
|
{
|
||||||
scaleW = _FIXED2FLOAT(_pObjSprite->scaleW, 10);
|
static const u32 CorrectorsA01[] = {
|
||||||
scaleH = _FIXED2FLOAT(_pObjSprite->scaleH, 10);
|
0x00000000,
|
||||||
imageW = _pObjSprite->imageW >> 5;
|
0x00100020,
|
||||||
imageH = _pObjSprite->imageH >> 5;
|
0x00200040,
|
||||||
X0 = _FIXED2FLOAT(_pObjSprite->objX, 2);
|
0x00300060,
|
||||||
X1 = X0 + imageW / scaleW;
|
0x0000FFF4,
|
||||||
Y0 = _FIXED2FLOAT(_pObjSprite->objY, 2);
|
0x00100014,
|
||||||
Y1 = Y0 + imageH / scaleH;
|
0x00200034,
|
||||||
flipS = (_pObjSprite->imageFlags & 0x01) != 0;
|
0x00300054
|
||||||
flipT = (_pObjSprite->imageFlags & 0x10) != 0;
|
};
|
||||||
|
static const s16 * CorrectorsA01_16 = reinterpret_cast<const s16*>(CorrectorsA01);
|
||||||
|
|
||||||
|
static const u32 CorrectorsA23[] = {
|
||||||
|
0x0001FFFE,
|
||||||
|
0xFFFEFFFE,
|
||||||
|
0x00010000,
|
||||||
|
0x00000000
|
||||||
|
};
|
||||||
|
static const s16 * CorrectorsA23_16 = reinterpret_cast<const s16*>(CorrectorsA23);
|
||||||
|
|
||||||
|
static const u32 CorrectorsB03[] = {
|
||||||
|
0xFFFC0000,
|
||||||
|
0x00000001,
|
||||||
|
0xFFFF0003,
|
||||||
|
0xFFF00000
|
||||||
|
};
|
||||||
|
static const s16 * CorrectorsB03_16 = reinterpret_cast<const s16*>(CorrectorsB03);
|
||||||
|
|
||||||
|
const u32 O1 = (gSP.objRendermode & (G_OBJRM_SHRINKSIZE_1 | G_OBJRM_SHRINKSIZE_2 | G_OBJRM_WIDEN)) >> 3;
|
||||||
|
A1 = CorrectorsA01_16[(1 + O1) ^ 1];
|
||||||
|
const u32 O2 = (gSP.objRendermode & (G_OBJRM_SHRINKSIZE_1 | G_OBJRM_BILERP)) >> 2;
|
||||||
|
A2 = CorrectorsA23_16[(0 + O2) ^ 1];
|
||||||
|
A3 = CorrectorsA23_16[(1 + O2) ^ 1];
|
||||||
|
const u32 O3 = (gSP.objRendermode & G_OBJRM_BILERP) >> 1;
|
||||||
|
B0 = CorrectorsB03_16[(0 + O3) ^ 1];
|
||||||
|
B3 = CorrectorsB03_16[(3 + O3) ^ 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s16 A1, A2, A3, B0, B3;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ObjCoordinates
|
struct ObjCoordinates
|
||||||
|
@ -2017,12 +2036,24 @@ struct ObjCoordinates
|
||||||
|
|
||||||
ObjCoordinates(const uObjSprite *_pObjSprite, bool _useMatrix)
|
ObjCoordinates(const uObjSprite *_pObjSprite, bool _useMatrix)
|
||||||
{
|
{
|
||||||
ObjData data(_pObjSprite);
|
/* Fixed point coordinates calculation. Decoded by olivieryuyu */
|
||||||
ulx = data.X0;
|
//XH = AND(objX + A2) by B0
|
||||||
lrx = data.X1;
|
//XL = AND(objX + A2) by B0 + ((ImageW - A1) * 0x100) / scaleW * 2
|
||||||
uly = data.Y0;
|
//YH = AND(objY + A2) by B0
|
||||||
lry = data.Y1;
|
//YL = AND(objY + A2) by B0 + ((ImageH - A1) * 0x100) / scaleH * 2
|
||||||
|
S2DEXCoordCorrector CC;
|
||||||
|
const s16 xh = (_pObjSprite->objX + CC.A2) & CC.B0;
|
||||||
|
const s16 xl = ((_pObjSprite->imageW - CC.A1) << 8) / (_pObjSprite->scaleW << 1) + xh;
|
||||||
|
const s16 yh = (_pObjSprite->objY + CC.A2) & CC.B0;
|
||||||
|
const s16 yl = ((_pObjSprite->imageH - CC.A1) << 8) / (_pObjSprite->scaleH << 1) + yh;
|
||||||
|
|
||||||
|
ulx = _FIXED2FLOAT(xh, 2);
|
||||||
|
lrx = _FIXED2FLOAT(xl, 2);
|
||||||
|
uly = _FIXED2FLOAT(yh, 2);
|
||||||
|
lry = _FIXED2FLOAT(yl, 2);
|
||||||
|
|
||||||
if (_useMatrix) {
|
if (_useMatrix) {
|
||||||
|
// TODO: use fixed point math
|
||||||
ulx = ulx/gSP.objMatrix.baseScaleX + gSP.objMatrix.X;
|
ulx = ulx/gSP.objMatrix.baseScaleX + gSP.objMatrix.X;
|
||||||
lrx = lrx/gSP.objMatrix.baseScaleX + gSP.objMatrix.X;
|
lrx = lrx/gSP.objMatrix.baseScaleX + gSP.objMatrix.X;
|
||||||
uly = uly/gSP.objMatrix.baseScaleY + gSP.objMatrix.Y;
|
uly = uly/gSP.objMatrix.baseScaleY + gSP.objMatrix.Y;
|
||||||
|
@ -2030,16 +2061,12 @@ struct ObjCoordinates
|
||||||
}
|
}
|
||||||
|
|
||||||
uls = ult = 0;
|
uls = ult = 0;
|
||||||
lrs = (f32)(data.imageW - 1);
|
lrs = _FIXED2FLOAT(_pObjSprite->imageW, 5);
|
||||||
lrt = (f32)(data.imageH - 1);
|
lrt = _FIXED2FLOAT(_pObjSprite->imageH, 5);
|
||||||
if (data.flipS) {
|
if ((_pObjSprite->imageFlags & 0x01) != 0) // flipS
|
||||||
uls = lrs;
|
std::swap(uls, lrs);
|
||||||
lrs = 0;
|
if ((_pObjSprite->imageFlags & 0x10) != 0) // flipT
|
||||||
}
|
std::swap(ult, lrt);
|
||||||
if (data.flipT) {
|
|
||||||
ult = lrt;
|
|
||||||
lrt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz;
|
z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : gSP.viewport.nearz;
|
||||||
w = 1.0f;
|
w = 1.0f;
|
||||||
|
@ -2237,30 +2264,6 @@ void _drawYUVImageToFrameBuffer(const ObjCoordinates & _objCoords)
|
||||||
pBuffer->m_isOBScreen = true;
|
pBuffer->m_isOBScreen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gSPObjRectangle(u32 _sp)
|
|
||||||
{
|
|
||||||
const u32 address = RSP_SegmentToPhysical(_sp);
|
|
||||||
uObjSprite *objSprite = (uObjSprite*)&RDRAM[address];
|
|
||||||
gSPSetSpriteTile(objSprite);
|
|
||||||
ObjCoordinates objCoords(objSprite, false);
|
|
||||||
gSPDrawObjRect(objCoords);
|
|
||||||
DebugMsg(DEBUG_NORMAL, "gSPObjRectangle\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void gSPObjRectangleR(u32 _sp)
|
|
||||||
{
|
|
||||||
const u32 address = RSP_SegmentToPhysical(_sp);
|
|
||||||
const uObjSprite *objSprite = (uObjSprite*)&RDRAM[address];
|
|
||||||
gSPSetSpriteTile(objSprite);
|
|
||||||
ObjCoordinates objCoords(objSprite, true);
|
|
||||||
|
|
||||||
if (objSprite->imageFmt == G_IM_FMT_YUV && (config.generalEmulation.hacks&hack_Ogre64)) //Ogre Battle needs to copy YUV texture to frame buffer
|
|
||||||
_drawYUVImageToFrameBuffer(objCoords);
|
|
||||||
gSPDrawObjRect(objCoords);
|
|
||||||
|
|
||||||
DebugMsg(DEBUG_NORMAL, "gSPObjRectangleR\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void _copyDepthBuffer()
|
void _copyDepthBuffer()
|
||||||
{
|
{
|
||||||
|
@ -2410,6 +2413,31 @@ void gSPBgRectCopy( u32 _bg )
|
||||||
DebugMsg(DEBUG_NORMAL, "gSPBgRectCopy\n");
|
DebugMsg(DEBUG_NORMAL, "gSPBgRectCopy\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gSPObjRectangle(u32 _sp)
|
||||||
|
{
|
||||||
|
const u32 address = RSP_SegmentToPhysical(_sp);
|
||||||
|
uObjSprite *objSprite = (uObjSprite*)&RDRAM[address];
|
||||||
|
gSPSetSpriteTile(objSprite);
|
||||||
|
|
||||||
|
ObjCoordinates objCoords(objSprite, false);
|
||||||
|
gSPDrawObjRect(objCoords);
|
||||||
|
DebugMsg(DEBUG_NORMAL, "gSPObjRectangle\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void gSPObjRectangleR(u32 _sp)
|
||||||
|
{
|
||||||
|
const u32 address = RSP_SegmentToPhysical(_sp);
|
||||||
|
const uObjSprite *objSprite = (uObjSprite*)&RDRAM[address];
|
||||||
|
gSPSetSpriteTile(objSprite);
|
||||||
|
ObjCoordinates objCoords(objSprite, true);
|
||||||
|
|
||||||
|
if (objSprite->imageFmt == G_IM_FMT_YUV && (config.generalEmulation.hacks&hack_Ogre64)) //Ogre Battle needs to copy YUV texture to frame buffer
|
||||||
|
_drawYUVImageToFrameBuffer(objCoords);
|
||||||
|
gSPDrawObjRect(objCoords);
|
||||||
|
|
||||||
|
DebugMsg(DEBUG_NORMAL, "gSPObjRectangleR\n");
|
||||||
|
}
|
||||||
|
|
||||||
void gSPObjSprite(u32 _sp)
|
void gSPObjSprite(u32 _sp)
|
||||||
{
|
{
|
||||||
const u32 address = RSP_SegmentToPhysical( _sp );
|
const u32 address = RSP_SegmentToPhysical( _sp );
|
||||||
|
@ -2417,58 +2445,19 @@ void gSPObjSprite(u32 _sp)
|
||||||
gSPSetSpriteTile(objSprite);
|
gSPSetSpriteTile(objSprite);
|
||||||
|
|
||||||
/* Fixed point coordinates calculation. Decoded by olivieryuyu */
|
/* Fixed point coordinates calculation. Decoded by olivieryuyu */
|
||||||
|
|
||||||
static const u32 MagicValuesA01[] = {
|
|
||||||
0x00000000,
|
|
||||||
0x00100020,
|
|
||||||
0x00200040,
|
|
||||||
0x00300060,
|
|
||||||
0x0000FFF4,
|
|
||||||
0x00100014,
|
|
||||||
0x00200034,
|
|
||||||
0x00300054
|
|
||||||
};
|
|
||||||
static const s16 * MagicValuesA01_16 = reinterpret_cast<const s16*>(MagicValuesA01);
|
|
||||||
|
|
||||||
static const u32 MagicValuesA23[] = {
|
|
||||||
0x0001FFFE,
|
|
||||||
0xFFFEFFFE,
|
|
||||||
0x00010000,
|
|
||||||
0x00000000
|
|
||||||
};
|
|
||||||
static const s16 * MagicValuesA23_16 = reinterpret_cast<const s16*>(MagicValuesA23);
|
|
||||||
|
|
||||||
static const u32 MagicValuesB03[] = {
|
|
||||||
0xFFFC0000,
|
|
||||||
0x00000001,
|
|
||||||
0xFFFF0003,
|
|
||||||
0xFFF00000
|
|
||||||
};
|
|
||||||
static const s16 * MagicValuesB03_16 = reinterpret_cast<const s16*>(MagicValuesB03);
|
|
||||||
|
|
||||||
const u32 O1 = (gSP.objRendermode & (G_OBJRM_SHRINKSIZE_1 | G_OBJRM_SHRINKSIZE_2 | G_OBJRM_WIDEN)) >> 3;
|
|
||||||
// const u32 A0 = MagicValuesA01_16[(0 + O1) ^ 1];
|
|
||||||
const s16 A1 = MagicValuesA01_16[(1 + O1) ^ 1];
|
|
||||||
const u32 O2 = (gSP.objRendermode & (G_OBJRM_SHRINKSIZE_1 | G_OBJRM_BILERP)) >> 2;
|
|
||||||
// const s16 A2 = MagicValuesA23_16[(0 + O2) ^ 1];
|
|
||||||
const s16 A3 = MagicValuesA23_16[(1 + O2) ^ 1];
|
|
||||||
const u32 O3 = (gSP.objRendermode & G_OBJRM_BILERP) >> 1;
|
|
||||||
const s16 B0 = MagicValuesB03_16[(0 + O3) ^ 1];
|
|
||||||
// const s16 B1 = MagicValuesB03_16[(1 + O3) ^ 1];
|
|
||||||
// const s16 B2 = MagicValuesB03_16[(2 + O3) ^ 1];
|
|
||||||
const s16 B3 = MagicValuesB03_16[(3 + O3) ^ 1];
|
|
||||||
|
|
||||||
// X1 = AND (X + B3) by B0 + ((objX + A3) * A) >> 16 + ((objY + A3) * B) >> 16
|
// X1 = AND (X + B3) by B0 + ((objX + A3) * A) >> 16 + ((objY + A3) * B) >> 16
|
||||||
// Y1 = AND (Y + B3) by B0 + ((objX + A3) * C) >> 16 + ((objY + A3) * D) >> 16
|
// Y1 = AND (Y + B3) by B0 + ((objX + A3) * C) >> 16 + ((objY + A3) * D) >> 16
|
||||||
// X2 = AND (X + B3) by B0 + ((((imageW - A1) * 0x0100)/(scaleW * 2) + objX + A3) * A) >> 16 + ((((imageH - A1) * 0x0100)/(scaleH * 2) + objY + A3) * B) >> 16
|
// X2 = AND (X + B3) by B0 + ((((imageW - A1) * 0x0100)/(scaleW * 2) + objX + A3) * A) >> 16 + ((((imageH - A1) * 0x0100)/(scaleH * 2) + objY + A3) * B) >> 16
|
||||||
// Y2 = AND (Y + B3) by B0 + ((((imageW - A1) * 0x0100)/(scaleW * 2) + objX + A3) * C) >> 16 + ((((imageH - A1) * 0x0100)/(scaleH * 2) + objY + A3) * D) >> 16
|
// Y2 = AND (Y + B3) by B0 + ((((imageW - A1) * 0x0100)/(scaleW * 2) + objX + A3) * C) >> 16 + ((((imageH - A1) * 0x0100)/(scaleH * 2) + objY + A3) * D) >> 16
|
||||||
|
|
||||||
|
S2DEXCoordCorrector CC;
|
||||||
const uObjMtx *objMtx = reinterpret_cast<const uObjMtx *>(RDRAM + gSP.objMatrix.address);
|
const uObjMtx *objMtx = reinterpret_cast<const uObjMtx *>(RDRAM + gSP.objMatrix.address);
|
||||||
const s16 x0 = ((objMtx->X + B3) & B0);
|
const s16 x0 = (objMtx->X + CC.B3) & CC.B0;
|
||||||
const s16 y0 = ((objMtx->Y + B3) & B0);
|
const s16 y0 = (objMtx->Y + CC.B3) & CC.B0;
|
||||||
const s16 ulx = objSprite->objX + A3;
|
const s16 ulx = objSprite->objX + CC.A3;
|
||||||
const s16 uly = objSprite->objY + A3;
|
const s16 uly = objSprite->objY + CC.A3;
|
||||||
const s16 lrx = ((objSprite->imageW - A1) << 8) / (objSprite->scaleW << 1) + ulx;
|
const s16 lrx = ((objSprite->imageW - CC.A1) << 8) / (objSprite->scaleW << 1) + ulx;
|
||||||
const s16 lry = ((objSprite->imageH - A1) << 8) / (objSprite->scaleH << 1) + uly;
|
const s16 lry = ((objSprite->imageH - CC.A1) << 8) / (objSprite->scaleH << 1) + uly;
|
||||||
|
|
||||||
auto calcX = [&](s16 _x, s16 _y) -> f32
|
auto calcX = [&](s16 _x, s16 _y) -> f32
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user