GPU:
- 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:
parent
3308d5b28e
commit
ec539cba02
|
@ -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>();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
2523
desmume/src/MMU.cpp
2523
desmume/src/MMU.cpp
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue