- Fix a bunch of graphical corruption regressions on big-endian systems.
- Also fix rotation/scale sprite colors and the 3D clear color on big-endian systems.
This commit is contained in:
rogerman 2015-10-06 01:14:44 +00:00
parent 3308d5b28e
commit ec539cba02
5 changed files with 1514 additions and 1141 deletions

View File

@ -649,6 +649,22 @@ void GPUEngineBase::ParseReg_BGnCNT()
this->_ResortBGLayers();
}
template <GPULayerID LAYERID>
void GPUEngineBase::ParseReg_BGnHOFS()
{
const IOREG_BGnHOFS &BGnHOFS = this->_IORegisterMap->BGnOFS[LAYERID].BGnHOFS;
this->_BGLayer[LAYERID].BGnHOFS = BGnHOFS;
this->_BGLayer[LAYERID].xOffset = LOCAL_TO_LE_16(BGnHOFS.value);
}
template <GPULayerID LAYERID>
void GPUEngineBase::ParseReg_BGnVOFS()
{
const IOREG_BGnVOFS &BGnVOFS = this->_IORegisterMap->BGnOFS[LAYERID].BGnVOFS;
this->_BGLayer[LAYERID].BGnVOFS = BGnVOFS;
this->_BGLayer[LAYERID].yOffset = LOCAL_TO_LE_16(BGnVOFS.value);
}
template<GPULayerID LAYERID>
void GPUEngineBase::ParseReg_BGnX()
{
@ -689,11 +705,11 @@ void GPUEngineBase::_RenderLine_Clear(const u16 clearColor, const u16 l, u16 *ds
{
if (BLDCNT.ColorEffect == ColorEffect_IncreaseBrightness)
{
dstClearColor = LE_TO_LOCAL_16(this->_currentFadeInColors[clearColor]);
dstClearColor = this->_currentFadeInColors[clearColor];
}
else if (BLDCNT.ColorEffect == ColorEffect_DecreaseBrightness)
{
dstClearColor = LE_TO_LOCAL_16(this->_currentFadeOutColors[clearColor]);
dstClearColor = this->_currentFadeOutColors[clearColor];
}
}
@ -1490,9 +1506,7 @@ void GPUEngineBase::_LineText(u16 *dstColorLine, const u16 lineIndex)
}
else
{
const u16 hofs = this->_IORegisterMap->BGnOFS[LAYERID].BGnHOFS.Offset;
const u16 vofs = this->_IORegisterMap->BGnOFS[LAYERID].BGnVOFS.Offset;
this->_RenderLine_TextBG<LAYERID, ISDEBUGRENDER, MOSAIC, ISCUSTOMRENDERINGNEEDED>(dstColorLine, lineIndex, hofs, lineIndex + vofs, 256);
this->_RenderLine_TextBG<LAYERID, ISDEBUGRENDER, MOSAIC, ISCUSTOMRENDERINGNEEDED>(dstColorLine, lineIndex, this->_BGLayer[LAYERID].xOffset, lineIndex + this->_BGLayer[LAYERID].yOffset, 256);
}
}
@ -1776,7 +1790,7 @@ void GPUEngineBase::_SpriteRenderPerform(const u16 lineIndex, u16 *dst, u8 *dst_
for (size_t i = 0; i < 128; i++)
{
const OAMAttributes &spriteInfo = this->_oamList[i];
OAMAttributes spriteInfo = this->_oamList[i];
//for each sprite:
if (cost >= 2130)
@ -1793,6 +1807,10 @@ void GPUEngineBase::_SpriteRenderPerform(const u16 lineIndex, u16 *dst, u8 *dst_
if (spriteInfo.RotScale == 0 && spriteInfo.Disable != 0)
continue;
// Must explicitly convert endianness with attributes 1 and 2.
spriteInfo.attr[1] = LOCAL_TO_LE_16(spriteInfo.attr[1]);
spriteInfo.attr[2] = LOCAL_TO_LE_16(spriteInfo.attr[2]);
const OBJMode objMode = (OBJMode)spriteInfo.Mode;
SpriteSize sprSize;
@ -1802,13 +1820,11 @@ void GPUEngineBase::_SpriteRenderPerform(const u16 lineIndex, u16 *dst, u8 *dst_
s32 y;
s32 lg;
s32 xdir;
u8 prio;
u8 prio = spriteInfo.Priority;
u16 *pal;
u8 *src;
u32 srcadr;
prio = spriteInfo.Priority;
if (spriteInfo.RotScale != 0)
{
s32 fieldX, fieldY, auxX, auxY, realX, realY, offset;
@ -1902,15 +1918,14 @@ void GPUEngineBase::_SpriteRenderPerform(const u16 lineIndex, u16 *dst, u8 *dst_
if (colour && (prio < prioTab[sprX]))
{
dst[sprX] = pal[colour];
dst[sprX] = LE_TO_LOCAL_16(pal[colour]);
dst_alpha[sprX] = 0xFF;
typeTab[sprX] = objMode;
prioTab[sprX] = prio;
}
}
// Add the rotation/scale coeficients, here the rotation/scaling
// is performed
// Add the rotation/scale coefficients, here the rotation/scaling is performed
realX += dx;
realY += dy;
}
@ -1955,8 +1970,7 @@ void GPUEngineBase::_SpriteRenderPerform(const u16 lineIndex, u16 *dst, u8 *dst_
}
}
// Add the rotation/scale coeficients, here the rotation/scaling
// is performed
// Add the rotation/scale coefficients, here the rotation/scaling is performed
realX += dx;
realY += dy;
}
@ -2010,8 +2024,7 @@ void GPUEngineBase::_SpriteRenderPerform(const u16 lineIndex, u16 *dst, u8 *dst_
}
}
// Add the rotation/scale coeficients, here the rotation/scaling
// is performed
// Add the rotation/scale coeficients, here the rotation/scaling is performed
realX += dx;
realY += dy;
}
@ -2538,6 +2551,15 @@ void GPUEngineBase::ParseAllRegisters()
// No need to call ParseReg_BGnCNT<GPUEngineID, GPULayerID>(), since it is
// already called by ParseReg_DISPCNT().
this->ParseReg_BGnHOFS<GPULayerID_BG0>();
this->ParseReg_BGnHOFS<GPULayerID_BG1>();
this->ParseReg_BGnHOFS<GPULayerID_BG2>();
this->ParseReg_BGnHOFS<GPULayerID_BG3>();
this->ParseReg_BGnVOFS<GPULayerID_BG0>();
this->ParseReg_BGnVOFS<GPULayerID_BG1>();
this->ParseReg_BGnVOFS<GPULayerID_BG2>();
this->ParseReg_BGnVOFS<GPULayerID_BG3>();
this->ParseReg_BGnX<GPULayerID_BG2>();
this->ParseReg_BGnY<GPULayerID_BG2>();
this->ParseReg_BGnX<GPULayerID_BG3>();
@ -2825,7 +2847,7 @@ void GPUEngineA::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t
const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo();
const float customWidthScale = (float)dispInfo.customWidth / (float)GPU_FRAMEBUFFER_NATIVE_WIDTH;
const FragmentColor *srcLine = this->_3DFramebufferRGBA6665 + (dstLineIndex * dispInfo.customWidth);
const u16 hofs = (u16)( ((float)this->_IORegisterMap->BGnOFS[GPULayerID_BG0].BGnHOFS.Offset * customWidthScale) + 0.5f );
const u16 hofs = (u16)( ((float)this->_BGLayer[GPULayerID_BG0].xOffset * customWidthScale) + 0.5f );
u16 *dstColorLinePtr = dstColorLine;
u8 *layerIDLine = this->_dstLayerID;
@ -4337,6 +4359,16 @@ template void GPUEngineBase::ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG1>();
template void GPUEngineBase::ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG2>();
template void GPUEngineBase::ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG3>();
template void GPUEngineBase::ParseReg_BGnHOFS<GPULayerID_BG0>();
template void GPUEngineBase::ParseReg_BGnHOFS<GPULayerID_BG1>();
template void GPUEngineBase::ParseReg_BGnHOFS<GPULayerID_BG2>();
template void GPUEngineBase::ParseReg_BGnHOFS<GPULayerID_BG3>();
template void GPUEngineBase::ParseReg_BGnVOFS<GPULayerID_BG0>();
template void GPUEngineBase::ParseReg_BGnVOFS<GPULayerID_BG1>();
template void GPUEngineBase::ParseReg_BGnVOFS<GPULayerID_BG2>();
template void GPUEngineBase::ParseReg_BGnVOFS<GPULayerID_BG3>();
template void GPUEngineBase::ParseReg_WINnH<0>();
template void GPUEngineBase::ParseReg_WINnH<1>();

View File

@ -399,11 +399,19 @@ typedef union
struct
{
#ifdef LOCAL_LE
u32 BG_MosaicH:4; // 0- 3: Mosaic pixel width for BG layers; 0...15
u32 BG_MosaicV:4; // 4- 7: Mosaic pixel height for BG layers; 0...15
u32 OBJ_MosaicH:4; // 8-11: Mosaic pixel width for OBJ layer; 0...15
u32 OBJ_MosaicV:4; // 12-15: Mosaic pixel height for OBJ layer; 0...15
#else
u32 BG_MosaicV:4; // 4- 7: Mosaic pixel height for BG layers; 0...15
u32 BG_MosaicH:4; // 0- 3: Mosaic pixel width for BG layers; 0...15
u32 OBJ_MosaicV:4; // 12-15: Mosaic pixel height for OBJ layer; 0...15
u32 OBJ_MosaicH:4; // 8-11: Mosaic pixel width for OBJ layer; 0...15
#endif
u32 :16; // 16-31: Unused bits
};
@ -465,11 +473,19 @@ typedef union
struct
{
#ifdef LOCAL_LE
u16 EVA:5; // 0- 4: Blending coefficient for 1st target; 0...31 (clamped to 16)
u16 :3; // 5- 7: Unused bits
u16 EVB:5; // 8-12: Blending coefficient for 2nd target; 0...31 (clamped to 16)
u16 :3; // 13-15: Unused bits
#else
u16 :3; // 5- 7: Unused bits
u16 EVA:5; // 0- 4: Blending coefficient for 1st target; 0...31 (clamped to 16)
u16 :3; // 13-15: Unused bits
u16 EVB:5; // 8-12: Blending coefficient for 2nd target; 0...31 (clamped to 16)
#endif
};
} IOREG_BLDALPHA; // 0x400x052: Color effects selection, interacts with BLDCNT (0x400x050) (Engine A+B)
@ -482,14 +498,11 @@ typedef union
#ifdef LOCAL_LE
u16 EVY:5; // 0- 4: Blending coefficient for increase/decrease brightness; 0...31 (clamped to 16)
u16 :3; // 5- 7: Unused bits
u16 :8; // 8-15: Unused bits
#else
u16 :3; // 5- 7: Unused bits
u16 EVY:5; // 0- 4: Blending coefficient for increase/decrease brightness; 0...31 (clamped to 16)
u16 :8; // 8-15: Unused bits
#endif
u16 :8; // 8-15: Unused bits
};
} IOREG_BLDY; // 0x400x054: Color effects selection, interacts with BLDCNT (0x400x050) (Engine A+B)
@ -852,8 +865,8 @@ typedef union
// 1: 16x16 32x8 8x32
// 2: 32x32 32x16 16x32
// 3: 64x64 64x32 32x64
u16 TileIndex:10; // 32-41: Tile index; 0...1023
u16 Priority:2; // 42-43: Rendering priority; 0...3, where 0 is highest priority and 3 is lowest priority
u16 PaletteIndex:4; // 44-47: Palette index; 0...15
#else
@ -863,24 +876,25 @@ typedef union
struct
{
u16 Y:8; // 0- 7: Sprite Y-coordinate; 0...255
u16 Shape:2; // 14-15: OBJ shape; 0=Square, 1=Horizontal, 2=Vertical, 3=Prohibited
u16 PaletteMode:1; // 13: Color/palette select; 0=16 palettes of 16 colors each, 1=Single palette of 256 colors
u16 Mosaic:1; // 12: Mosaic render: 0=Disable, 1=Enable
u16 Mode:2; // 10-11: OBJ mode; 0=Normal, 1=Transparent, 2=Window, 3=Bitmap
u16 Disable:1; // 9: OBJ disable flag, only if Bit8 is cleared; 0=Perform render, 1=Do not perform render
u16 RotScale:1; // 8: Perform rotation/scaling; 0=Disable, 1=Enable
u16 Y:8; // 0- 7: Sprite Y-coordinate; 0...255
};
struct
{
u16 :8;
u16 :6;
u16 DoubleSize:1; // 9: Perform double-size render, only if Bit8 is set; 0=Disable, 1=Enable
u16 :1;
u16 :8;
};
};
// 16-31: Whenever this is used, you will need to explicitly convert endianness.
u16 Size:2; // 30-31: OBJ size, interacts with Bit 14-15
//
// Size| Square | Horizontal | Vertical
@ -893,6 +907,7 @@ typedef union
u16 RotScaleIndex:3; // 25-27: Rotation/scaling parameter selection; 0...31
s16 X:9; // 16-24: Sprite X-coordinate; 0...511
// 32-47: Whenever this is used, you will need to explicitly convert endianness.
u16 PaletteIndex:4; // 44-47: Palette index; 0...15
u16 Priority:2; // 42-43: Rendering priority; 0...3, where 0 is highest priority and 3 is lowest priority
u16 TileIndex:10; // 32-41: Tile index; 0...1023
@ -1052,6 +1067,8 @@ typedef struct
{
GPULayerID layerID;
IOREG_BGnCNT BGnCNT;
IOREG_BGnHOFS BGnHOFS;
IOREG_BGnVOFS BGnVOFS;
BGLayerSize size;
BGType type;
@ -1068,6 +1085,9 @@ typedef struct
u32 BMPAddress;
u32 tileMapAddress;
u32 tileEntryAddress;
u16 xOffset;
u16 yOffset;
} BGLayerInfo;
class GPUEngineBase
@ -1218,6 +1238,8 @@ public:
template<GPUEngineID ENGINEID> void ParseReg_DISPCNT();
template<GPUEngineID ENGINEID, GPULayerID LAYERID> void ParseReg_BGnCNT();
template<GPULayerID LAYERID> void ParseReg_BGnHOFS();
template<GPULayerID LAYERID> void ParseReg_BGnVOFS();
template<GPULayerID LAYERID> void ParseReg_BGnX();
template<GPULayerID LAYERID> void ParseReg_BGnY();
template<size_t WINNUM> void ParseReg_WINnH();

File diff suppressed because it is too large Load Diff

View File

@ -316,6 +316,7 @@ typedef union
{
u8 value;
#ifdef LOCAL_LE
struct
{
unsigned MST:3;
@ -332,6 +333,24 @@ typedef union
unsigned :2;
unsigned Enable_ABHI:1;
};
#else
struct
{
unsigned Enable:1;
unsigned :2;
unsigned OFS:2;
unsigned MST:3;
};
struct
{
unsigned Enable_ABHI:1;
unsigned :2;
unsigned OFS_ABHI:2;
unsigned :1;
unsigned MST_ABHI:2;
};
#endif
} VRAMCNT;
#define DUP2(x) x, x

View File

@ -314,10 +314,19 @@ Render3DError Render3D::ClearFramebuffer(const GFX3D_State &renderState)
Render3DError error = RENDER3DERROR_NOERR;
FragmentColor clearColor;
#ifdef LOCAL_LE
clearColor.r = renderState.clearColor & 0x1F;
clearColor.g = (renderState.clearColor >> 5) & 0x1F;
clearColor.b = (renderState.clearColor >> 10) & 0x1F;
clearColor.a = (renderState.clearColor >> 16) & 0x1F;
#else
const u32 clearColorSwapped = LE_TO_LOCAL_32(renderState.clearColor);
clearColor.r = clearColorSwapped & 0x1F;
clearColor.g = (clearColorSwapped >> 5) & 0x1F;
clearColor.b = (clearColorSwapped >> 10) & 0x1F;
clearColor.a = (clearColorSwapped >> 16) & 0x1F;
#endif
FragmentAttributes clearFragment;
clearFragment.opaquePolyID = (renderState.clearColor >> 24) & 0x3F;