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

Correct coronas emulation in Perfect Dark.

Fixed issue #563.
This commit is contained in:
Sergey Lipskiy 2015-06-04 22:17:04 +06:00
parent 4b6df9bd10
commit 36fbcd5eac
7 changed files with 90 additions and 15 deletions

View File

@ -9,6 +9,8 @@
#include "FrameBuffer.h"
#include "DepthBuffer.h"
#include "VI.h"
#include "RDP.h"
#include "N64.h"
#include "Config.h"
#include "Debug.h"
@ -352,3 +354,81 @@ void DepthBuffer_Destroy()
{
depthBufferList().destroy();
}
/*------------------------DepthBufferCopyRect---------------------------------*/
class DepthBufferCopyRect
{
public:
void addData(const OGLRender::TexturedRectParams & _params)
{
m_vecData.push_back(DepthBufferCopyRectData(_params));
}
void flush()
{
if (m_vecData.empty())
return;
FrameBuffer_CopyDepthBuffer(gDP.colorImage.address);
for (RectData::iterator it = m_vecData.begin(); it != m_vecData.end(); ++it) {
gDPTile & tile = gDP.tiles[_SHIFTR(it->w1, 24, 3)];
tile.tmem = it->tmem;
tile.size = it->size;
gDP.textureImage.bpl = it->bpl;
gDP.textureImage.size = it->size;
gDP.textureImage.address = it->texAddress;
RDP_LoadBlock(it->w0, it->w1);
const u32 width = (u32)(it->lrx - it->ulx);
const u32 ulx = (u32)it->ulx;
u16 * pSrc = ((u16*)TMEM) + (u32)floorf(it->uls + 0.5f);
u16 *pDst = (u16*)(RDRAM + it->address);
for (u32 x = 0; x < width; ++x)
pDst[(ulx + x) ^ 1] = swapword(pSrc[x]);
}
m_vecData.clear();
}
static DepthBufferCopyRect & get()
{
static DepthBufferCopyRect dbcr;
return dbcr;
}
private:
DepthBufferCopyRect() {}
~DepthBufferCopyRect() {}
struct DepthBufferCopyRectData
{
float ulx, lrx, uls;
u32 w0, w1;
u32 address;
u32 tmem, bpl, size, texAddress;
DepthBufferCopyRectData(const OGLRender::TexturedRectParams & _params)
{
ulx = _params.ulx;
lrx = _params.lrx;
uls = _params.uls;
RDP_GetLastLoadBlockParams(w0, w1);
address = gDP.colorImage.address;
tmem = gDP.tiles[_SHIFTR(w1, 24, 3)].tmem;
bpl = gDP.textureImage.bpl;
size = gDP.textureImage.size;
texAddress = gDP.textureImage.address;
}
};
typedef std::vector<DepthBufferCopyRectData> RectData;
RectData m_vecData;
};
void AddDepthBufferCopyRectData(const OGLRender::TexturedRectParams & _params)
{
DepthBufferCopyRect::get().addData(_params);
}
void FlushDepthBufferCopyRects()
{
DepthBufferCopyRect::get().flush();
}

View File

@ -72,4 +72,7 @@ extern const GLuint depthImageUnit;
void DepthBuffer_Init();
void DepthBuffer_Destroy();
void AddDepthBufferCopyRectData(const OGLRender::TexturedRectParams & _params);
void FlushDepthBufferCopyRects();
#endif

View File

@ -1096,8 +1096,6 @@ void DepthBufferToRDRAM::Destroy() {
bool DepthBufferToRDRAM::CopyToRDRAM( u32 _address) {
if (VI.width == 0) // H width is zero. Don't copy
return false;
if (m_lastDList == RSP.DList) // Already read;
return true;
FrameBuffer *pBuffer = frameBufferList().findBuffer(_address);
if (pBuffer == NULL || pBuffer->m_width < VI.width || pBuffer->m_pDepthBuffer == NULL || !pBuffer->m_pDepthBuffer->m_cleared)
return false;

View File

@ -885,16 +885,7 @@ bool texturedRectDepthBufferCopy(const OGLRender::TexturedRectParams & _params)
pBuffer->m_cleared = true;
if (config.frameBufferEmulation.copyDepthToRDRAM == 0)
return true;
if (FrameBuffer_CopyDepthBuffer(gDP.colorImage.address))
RDP_RepeatLastLoadBlock();
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 *pDst = (u16*)(RDRAM + gDP.colorImage.address);
for (u32 x = 0; x < width; ++x)
pDst[(ulx + x) ^ 1] = swapword(pSrc[x]);
AddDepthBufferCopyRectData(_params);
return true;
}
return false;

View File

@ -137,9 +137,10 @@ void RDP_LoadBlock( u32 w0, u32 w1 )
_SHIFTR( w1, 0, 12 ) ); // dxt
}
void RDP_RepeatLastLoadBlock()
void RDP_GetLastLoadBlockParams(u32 & _w0, u32 & _w1)
{
RDP_LoadBlock(lbw0, lbw1);
_w0 = lbw0;
_w1 = lbw1;
}
void RDP_SetTileSize( u32 w0, u32 w1 )

View File

@ -17,7 +17,8 @@ extern RDPInfo RDP;
void RDP_Init();
void RDP_Half_1(u32 _c);
void RDP_ProcessRDPList();
void RDP_RepeatLastLoadBlock();
void RDP_LoadBlock(u32 w0, u32 w1);
void RDP_GetLastLoadBlockParams(u32 & _w0, u32 & _w1);
void RDP_SetScissor(u32 w0, u32 w1);
#endif

View File

@ -758,6 +758,7 @@ void gDPFillRectangle( s32 ulx, s32 uly, s32 lrx, s32 lry )
// Game may use depth texture as auxilary color texture. Example: Mario Tennis
// If color is not depth clear color, that is most likely the case
if (gDP.fillColor.color == DepthClearColor) {
FlushDepthBufferCopyRects();
gDPFillRDRAM(gDP.colorImage.address, ulx, uly, lrx, lry, gDP.colorImage.width, gDP.colorImage.size, gDP.fillColor.color);
render.clearDepthBuffer(uly, lry);
return;