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

Add hack_ZeldaCamera to fix camera in Zelda MM, #577

The game copies current frame buffer to the area, which initially allocated for depth buffer.
Game read camera data from that area, not from normal frame buffer.
That's why 'copy color buffer to RDRAM' option does not help there.
Special code needed to process that. Looks ugly, but works.
This commit is contained in:
Sergey Lipskiy 2015-09-27 10:10:05 +06:00
parent 1eaa967553
commit 24885907d8
5 changed files with 23 additions and 3 deletions

View File

@ -121,6 +121,7 @@ struct Config
#define hack_ignoreVIHeightChange (1<<9) //Do not reset FBO when VI height is changed. Space Invaders need it.
#define hack_VIUpdateOnCIChange (1<<10) //Update frame if color buffer changed. Needed for Quake II underwater.
#define hack_skipVIChangeCheck (1<<11) //Don't reset FBO when VI parameters changed. Zelda MM
#define hack_ZeldaCamera (1<<12) //Special hack to detect and process Zelda MM camera.
extern Config config;

View File

@ -357,11 +357,13 @@ FrameBufferList & FrameBufferList::get()
void FrameBufferList::init()
{
m_pCurrent = NULL;
m_pCopy = NULL;
}
void FrameBufferList::destroy() {
m_list.clear();
m_pCurrent = NULL;
m_pCopy = NULL;
}
void FrameBufferList::setBufferChanged()
@ -1184,7 +1186,15 @@ bool DepthBufferToRDRAM::CopyToRDRAM( u32 _address) {
bool FrameBuffer_CopyDepthBuffer( u32 address ) {
#ifndef GLES2
return g_dbToRDRAM.CopyToRDRAM(address);
FrameBuffer * pCopyBuffer = frameBufferList().getCopyBuffer();
if (pCopyBuffer != NULL) {
// This code is mainly to emulate Zelda MM camera.
g_fbToRDRAM.CopyToRDRAM(pCopyBuffer->m_startAddress);
pCopyBuffer->m_RdramCopy.resize(0); // To disable validity check by RDRAM content. CPU may change content of the buffer for some unknown reason.
frameBufferList().setCopyBuffer(NULL);
return true;
} else
return g_dbToRDRAM.CopyToRDRAM(address);
#else
return false;
#endif

View File

@ -71,10 +71,13 @@ public:
void correctHeight();
void clearBuffersChanged();
FrameBuffer * getCopyBuffer() const { return m_pCopy; }
void setCopyBuffer(FrameBuffer * _pBuffer) { m_pCopy = _pBuffer; }
static FrameBufferList & get();
private:
FrameBufferList() : m_pCurrent(NULL) {}
FrameBufferList() : m_pCurrent(NULL), m_pCopy(NULL) {}
FrameBufferList(const FrameBufferList &);
FrameBuffer * _findBuffer(u32 _startAddress, u32 _endAddress, u32 _width);
@ -82,6 +85,7 @@ private:
typedef std::list<FrameBuffer> FrameBuffers;
FrameBuffers m_list;
FrameBuffer * m_pCurrent;
FrameBuffer * m_pCopy;
};
struct PBOBinder {

View File

@ -338,7 +338,7 @@ void RSP_Init()
)
config.generalEmulation.hacks |= hack_VIUpdateOnCIChange;
else if (strstr(RSP.romname, (const char *)"MASK") != NULL) // Zelda MM
config.generalEmulation.hacks |= hack_skipVIChangeCheck;
config.generalEmulation.hacks |= hack_skipVIChangeCheck | hack_ZeldaCamera;
api().FindPluginPath(RSP.pluginpath);

View File

@ -2114,6 +2114,11 @@ void _loadBGImage(const uObjScaleBg * _bgInfo, bool _loadScale)
gDP.tiles[0].textureMode = TEXTUREMODE_FRAMEBUFFER_BG;
gDP.tiles[0].loadType = LOADTYPE_TILE;
gDP.changed |= CHANGED_TMEM;
if ((config.generalEmulation.hacks & hack_ZeldaCamera) != 0) {
if (gDP.colorImage.address == gDP.depthImageAddress)
frameBufferList().setCopyBuffer(frameBufferList().getCurrent());
}
}
}
}