diff --git a/src/Config.h b/src/Config.h index ffe1b749..c10af4dc 100644 --- a/src/Config.h +++ b/src/Config.h @@ -195,6 +195,7 @@ struct Config #define hack_LoadDepthTextures (1<<16) //Load textures for depth buffer #define hack_Snap (1<<17) //Frame buffer settings for camera detection in Pokemon Snap. Copy aux buffers at fullsync #define hack_MK64 (1<<18) //Hack for load MK64 HD textures properly. +#define hack_RE2 (1<<19) //RE2 hacks. extern Config config; diff --git a/src/FrameBuffer.cpp b/src/FrameBuffer.cpp index b3c3313e..97476bca 100644 --- a/src/FrameBuffer.cpp +++ b/src/FrameBuffer.cpp @@ -547,6 +547,9 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt if (_width > 640) return; + if (_width == 512 && (config.generalEmulation.hacks & hack_RE2) != 0) + _width = *REG.VI_WIDTH; + if (config.frameBufferEmulation.enable == 0) { if (m_list.empty()) _createScreenSizeBuffer(); diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp index d30fe734..4f63d507 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp +++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp @@ -1259,12 +1259,27 @@ public: "} \n" ; } else { - m_part = - "void writeDepth() \n" - "{ \n" - " gl_FragDepth = clamp((gl_FragCoord.z * 2.0 - 1.0) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n" - "} \n" - ; + if (_glinfo.imageTextures && (config.generalEmulation.hacks & hack_RE2) != 0) { + m_part = + "layout(binding = 0, r32ui) highp uniform readonly uimage2D uZlutImage;\n" + "void writeDepth() \n" + "{ \n" + " gl_FragDepth = clamp((gl_FragCoord.z * 2.0 - 1.0) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n" + " highp int iZ = gl_FragDepth > 0.999 ? 262143 : int(floor(gl_FragDepth * 262143.0)); \n" + " mediump int y0 = clamp(iZ/512, 0, 511); \n" + " mediump int x0 = iZ - 512*y0; \n" + " highp uint iN64z = imageLoad(uZlutImage,ivec2(x0,y0)).r; \n" + " gl_FragDepth = clamp(float(iN64z)/65532.0, 0.0, 1.0); \n" + "} \n" + ; + } else { + m_part = + "void writeDepth() \n" + "{ \n" + " gl_FragDepth = clamp((gl_FragCoord.z * 2.0 - 1.0) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n" + "} \n" + ; + } } } } diff --git a/src/GraphicsDrawer.cpp b/src/GraphicsDrawer.cpp index af027198..a84d5b41 100644 --- a/src/GraphicsDrawer.cpp +++ b/src/GraphicsDrawer.cpp @@ -185,6 +185,12 @@ void GraphicsDrawer::updateScissor(FrameBuffer * _pBuffer) const f32 SX1 = gDP.scissor.lrx; f32 SY0 = gDP.scissor.uly; f32 SY1 = gDP.scissor.lry; + + if (u32(SX1) == 512 && (config.generalEmulation.hacks & hack_RE2) != 0) { + SX1 = f32(*REG.VI_WIDTH); + SY1 *= 512.0f / SX1; + } + if (_needAdjustCoordinate(wnd)) _adjustScissorX(SX0, SX1, wnd.getAdjustScale()); diff --git a/src/RSP.cpp b/src/RSP.cpp index 7243ed9a..cd3437bc 100644 --- a/src/RSP.cpp +++ b/src/RSP.cpp @@ -261,6 +261,9 @@ void RSP_Init() config.generalEmulation.hacks |= hack_Snap; else if (strstr(RSP.romname, (const char *)"MARIOKART64") != nullptr) config.generalEmulation.hacks |= hack_MK64; + else if (strstr(RSP.romname, (const char *)"Resident Evil II") || + strstr(RSP.romname, (const char *)"BioHazard II")) + config.generalEmulation.hacks |= hack_RE2 | hack_ModifyVertexXyInShader | hack_LoadDepthTextures; api().FindPluginPath(RSP.pluginpath); diff --git a/src/Textures.cpp b/src/Textures.cpp index dc14ebf3..91dc9e83 100644 --- a/src/Textures.cpp +++ b/src/Textures.cpp @@ -846,6 +846,13 @@ void TextureCache::_loadBackground(CachedTexture *pTexture) } } + if ((config.generalEmulation.hacks&hack_LoadDepthTextures) != 0 && gDP.colorImage.address == gDP.depthImageAddress) { + _loadDepthTexture(pTexture, (u16*)pDest); + free(pDest); + free(pSwapped); + return; + } + bool bLoaded = false; if ((config.textureFilter.txEnhancementMode | config.textureFilter.txFilterMode) != 0 && config.textureFilter.txFilterIgnoreBG == 0 && diff --git a/src/VI.cpp b/src/VI.cpp index 57a73d40..19b0c7b3 100644 --- a/src/VI.cpp +++ b/src/VI.cpp @@ -126,9 +126,11 @@ void VI_UpdateScreen() if (config.frameBufferEmulation.enable) { FrameBuffer * pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN); - if (pBuffer == nullptr) + if (pBuffer == nullptr) { gDP.changed |= CHANGED_CPU_FB_WRITE; - else if (!FBInfo::fbInfo.isSupported() && !pBuffer->isValid(true)) { + } else if (!FBInfo::fbInfo.isSupported() && + (config.generalEmulation.hacks & hack_RE2) == 0 && + !pBuffer->isValid(true)) { gDP.changed |= CHANGED_CPU_FB_WRITE; if (config.frameBufferEmulation.copyToRDRAM == 0 && (config.generalEmulation.hacks & hack_subscreen) == 0) pBuffer->copyRdram(); diff --git a/src/gSP.cpp b/src/gSP.cpp index c6840e20..02da74e6 100644 --- a/src/gSP.cpp +++ b/src/gSP.cpp @@ -1622,6 +1622,10 @@ void gSPModifyVertex( u32 _vtx, u32 _where, u32 _val ) vtx0.y *= vtx0.w; } else { vtx0.modify |= MODIFY_XY; + if (vtx0.w == 0.0f) { + vtx0.w = 1.0f; + vtx0.clip &= ~(CLIP_W); + } } vtx0.clip &= ~(CLIP_POSX | CLIP_NEGX | CLIP_POSY | CLIP_NEGY); break; @@ -1973,17 +1977,27 @@ struct ObjCoordinates { const f32 frameX = _FIXED2FLOAT(_pObjScaleBg->frameX, 2); const f32 frameY = _FIXED2FLOAT(_pObjScaleBg->frameY, 2); - const f32 frameW = _FIXED2FLOAT(_pObjScaleBg->frameW, 2); - const f32 frameH = _FIXED2FLOAT(_pObjScaleBg->frameH, 2); const f32 imageX = gSP.bgImage.imageX; const f32 imageY = gSP.bgImage.imageY; - const f32 imageW = (f32)(_pObjScaleBg->imageW>>2); - const f32 imageH = (f32)(_pObjScaleBg->imageH >> 2); -// const f32 imageW = (f32)gSP.bgImage.width; -// const f32 imageH = (f32)gSP.bgImage.height; const f32 scaleW = gSP.bgImage.scaleW; const f32 scaleH = gSP.bgImage.scaleH; + f32 frameW = _FIXED2FLOAT(_pObjScaleBg->frameW, 2); + f32 frameH = _FIXED2FLOAT(_pObjScaleBg->frameH, 2); + f32 imageW = (f32)(_pObjScaleBg->imageW>>2); + f32 imageH = (f32)(_pObjScaleBg->imageH >> 2); +// const f32 imageW = (f32)gSP.bgImage.width; +// const f32 imageH = (f32)gSP.bgImage.height; + + if (u32(imageW) == 512 && (config.generalEmulation.hacks & hack_RE2) != 0) { + const f32 width = f32(*REG.VI_WIDTH); + const f32 scale = imageW / width; + imageW = width; + frameW = width; + imageH *= scale; + frameH *= scale; + } + ulx = frameX; uly = frameY; lrx = frameX + min(imageW/scaleW, frameW) - 1.0f; @@ -2198,9 +2212,14 @@ void _loadBGImage(const uObjScaleBg * _bgInfo, bool _loadScale) gSP.bgImage.address = RSP_SegmentToPhysical( _bgInfo->imagePtr ); const u32 imageW = _bgInfo->imageW >> 2; - gSP.bgImage.width = imageW - imageW%2; const u32 imageH = _bgInfo->imageH >> 2; - gSP.bgImage.height = imageH - imageH%2; + if (imageW == 512 && (config.generalEmulation.hacks & hack_RE2) != 0) { + gSP.bgImage.width = *REG.VI_WIDTH; + gSP.bgImage.height = (imageH * imageW) / gSP.bgImage.width; + } else { + gSP.bgImage.width = imageW - imageW%2; + gSP.bgImage.height = imageH - imageH%2; + } gSP.bgImage.format = _bgInfo->imageFmt; gSP.bgImage.size = _bgInfo->imageSiz; gSP.bgImage.palette = _bgInfo->imagePal; @@ -2221,7 +2240,7 @@ void _loadBGImage(const uObjScaleBg * _bgInfo, bool _loadScale) return; } - if (!pBuffer->isValid(false)) { + if (pBuffer->m_cfb || !pBuffer->isValid(false)) { frameBufferList().removeBuffer(pBuffer->m_startAddress); return; }