diff --git a/src/Config.cpp b/src/Config.cpp index a2e0b59b..41421d98 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -56,6 +56,7 @@ void Config::resetToDefaults() frameBufferEmulation.detectCFB = 0; frameBufferEmulation.N64DepthCompare = 0; frameBufferEmulation.aspect = 1; + frameBufferEmulation.bufferSwapMode = 0; textureFilter.txCacheSize = 100 * gc_uMegabyte; textureFilter.txDump = 0; diff --git a/src/Config.h b/src/Config.h index 19f893ef..3240e235 100644 --- a/src/Config.h +++ b/src/Config.h @@ -71,6 +71,12 @@ struct Config ctAsync }; + enum BufferSwapMode { + bsOnVIUpdate = 0, + bsOnVIOriginChange, + bsOnColorImageChange + }; + struct { u32 enable; u32 copyAuxToRDRAM; @@ -80,6 +86,7 @@ struct Config u32 detectCFB; u32 N64DepthCompare; u32 aspect; // 0: stretch ; 1: 4/3 ; 2: 16/9; 3: adjust + u32 bufferSwapMode; // 0: on VI update call; 1: on VI origin change; 2: on main frame buffer update } frameBufferEmulation; struct @@ -130,7 +137,6 @@ struct Config #define hack_legoRacers (1<<7) //LEGO racers course map #define hack_blastCorps (1<<8) //Blast Corps black polygons #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. diff --git a/src/RSP.cpp b/src/RSP.cpp index 97d0b2b0..0c6e40dc 100644 --- a/src/RSP.cpp +++ b/src/RSP.cpp @@ -332,13 +332,6 @@ void RSP_Init() config.generalEmulation.hacks |= hack_blastCorps; else if (strstr(RSP.romname, (const char *)"SPACE INVADERS") != NULL) config.generalEmulation.hacks |= hack_ignoreVIHeightChange; - else if (strstr(RSP.romname, (const char *)"QUAKE II") != NULL || - strstr(RSP.romname, (const char *)"Quake") != NULL || - strstr(RSP.romname, (const char *)"Perfect Dark") || - strstr(RSP.romname, (const char *)"PERFECT DARK") || - strstr(RSP.romname, (const char *)"POKEMON SNAP") - ) - config.generalEmulation.hacks |= hack_VIUpdateOnCIChange; else if (strstr(RSP.romname, (const char *)"MASK") != NULL) // Zelda MM config.generalEmulation.hacks |= hack_skipVIChangeCheck | hack_ZeldaCamera; diff --git a/src/VI.cpp b/src/VI.cpp index d7539843..d7d79909 100644 --- a/src/VI.cpp +++ b/src/VI.cpp @@ -117,9 +117,20 @@ void VI_UpdateScreen() } const bool bCFB = (gDP.changed&CHANGED_CPU_FB_WRITE) == CHANGED_CPU_FB_WRITE; - const bool bNeedUpdate = (bCFB ? true : (*REG.VI_ORIGIN != VI.lastOrigin)) || ((config.generalEmulation.hacks & hack_VIUpdateOnCIChange) != 0 && gDP.colorImage.changed != 0); + bool bNeedSwap = false; + switch (config.frameBufferEmulation.bufferSwapMode) { + case Config::bsOnVIUpdate: + bNeedSwap = true; + break; + case Config::bsOnVIOriginChange: + bNeedSwap = bCFB ? true : (*REG.VI_ORIGIN != VI.lastOrigin); + break; + case Config::bsOnColorImageChange: + bNeedSwap = gDP.colorImage.changed != 0; + break; + } - if (bNeedUpdate) { + if (bNeedSwap) { if (bCFB) { if (pBuffer == NULL || pBuffer->m_width != VI.width) { if (!bVIUpdated) { diff --git a/src/mupenplus/Config_mupenplus.cpp b/src/mupenplus/Config_mupenplus.cpp index f0025d6e..3eb4200a 100644 --- a/src/mupenplus/Config_mupenplus.cpp +++ b/src/mupenplus/Config_mupenplus.cpp @@ -49,6 +49,8 @@ bool Config_SetDefault() assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "AspectRatio", config.frameBufferEmulation.aspect, "Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust)"); assert(res == M64ERR_SUCCESS); + res = ConfigSetDefaultInt(g_configVideoGliden64, "BufferSwapMode", config.frameBufferEmulation.bufferSwapMode, "Swap frame buffers (0=On VI update call, 1=On VI origin change, 2=On buffer update)"); + assert(res == M64ERR_SUCCESS); //#Texture Settings res = ConfigSetDefaultBool(g_configVideoGliden64, "bilinearMode", config.texture.bilinearMode, "Bilinear filtering mode (0=N64 3point, 1=standard)"); @@ -177,6 +179,7 @@ void Config_LoadConfig() config.video.multisampling = 0; #endif config.frameBufferEmulation.aspect = ConfigGetParamInt(g_configVideoGliden64, "AspectRatio"); + config.frameBufferEmulation.bufferSwapMode = ConfigGetParamInt(g_configVideoGliden64, "BufferSwapMode"); //#Texture Settings config.texture.bilinearMode = ConfigGetParamBool(g_configVideoGliden64, "bilinearMode");