From df61073c39e3c701a05fa6433b975ca75ac51ec7 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 18 Sep 2018 12:01:16 +0200 Subject: [PATCH] Clip textures that extend past the end of VRAM. Only load the valid portion of it. Fixes Shenmue Space Harrier mini-arcade game. Disable verify on non-square twiddled textures for Quake 3. --- core/rend/gles/gltex.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/core/rend/gles/gltex.cpp b/core/rend/gles/gltex.cpp index 28da0ee05..40d309e77 100644 --- a/core/rend/gles/gltex.cpp +++ b/core/rend/gles/gltex.cpp @@ -337,7 +337,8 @@ struct TextureCacheData } else { - verify(w==h || !tcw.MipMapped); // are non square mipmaps supported ? i can't recall right now *WARN* + // Quake 3 Arena uses one. Not sure if valid but no need to crash + //verify(w==h || !tcw.MipMapped); // are non square mipmaps supported ? i can't recall right now *WARN* if (tcw.VQ_Comp) { @@ -400,10 +401,21 @@ struct TextureCacheData stride=(TEXT_CONTROL&31)*32; //I think this needs +1 ? //PrintTextureName(); + u32 original_h = h; if (sa_tex > VRAM_SIZE || size == 0 || sa + size > VRAM_SIZE) { - printf("Warning: invalid texture. Address %08X %08X size %d\n", sa_tex, sa, size); - return; + if (sa + size > VRAM_SIZE) + { + // Shenmue Space Harrier mini-arcade loads a texture that goes beyond the end of VRAM + // but only uses the top portion of it + h = (VRAM_SIZE - sa) * 8 / stride / tex->bpp; + size = stride * h * tex->bpp/8; + } + else + { + printf("Warning: invalid texture. Address %08X %08X size %d\n", sa_tex, sa, size); + return; + } } void *temp_tex_buffer = NULL; @@ -475,6 +487,8 @@ struct TextureCacheData memset(pb16.data(), 0x80, w * h * 2); temp_tex_buffer = pb16.data(); } + // Restore the original texture height if it was constrained to VRAM limits above + h = original_h; //lock the texture to detect changes in it lock_block = libCore_vramlock_Lock(sa_tex,sa+size-1,this);