From 3fd958431a0c83edefe8da33653eeef6d4343e35 Mon Sep 17 00:00:00 2001 From: Sergey Lipskiy Date: Sat, 4 Apr 2015 14:27:53 +0600 Subject: [PATCH] Fix tile load via gDPLoadBlock when amount of tile data is over TMEM size. Fixed Tom & Jerry / PPG CHEMICAL X: texture issues #183 --- N64.cpp | 2 +- N64.h | 10 ++++++++-- gDP.cpp | 14 ++++++-------- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/N64.cpp b/N64.cpp index 7efa4f0b..fc21c684 100644 --- a/N64.cpp +++ b/N64.cpp @@ -3,7 +3,7 @@ u8 *HEADER; u8 *DMEM; u8 *IMEM; -u64 TMEM[512]; +u64 TMEM[TMEM_SIZE]; u8 *RDRAM; u32 RDRAMSize; diff --git a/N64.h b/N64.h index 1191d5a1..987ed7e2 100644 --- a/N64.h +++ b/N64.h @@ -3,7 +3,13 @@ #include "Types.h" -#define MI_INTR_DP 0x20 // Bit 5: DP intr +#define MI_INTR_DP 0x20 // Bit 5: DP intr + +// Actual TMEM size is 512 QWORDS. However, some load operations load more data that TMEM can take. +// We can either cut the surplus data, or increase the buffer and load everything. +// The second option is more simple and safe. Actual texture load will use correct TMEM size. +#define TMEM_SIZE 1024 +#define TMEM_SIZE_BYTES 8192 struct N64Regs { @@ -39,7 +45,7 @@ extern u8 *HEADER; extern u8 *DMEM; extern u8 *IMEM; extern u8 *RDRAM; -extern u64 TMEM[512]; +extern u64 TMEM[TMEM_SIZE]; extern u32 RDRAMSize; #endif diff --git a/gDP.cpp b/gDP.cpp index c18a1f44..aebe474c 100644 --- a/gDP.cpp +++ b/gDP.cpp @@ -511,14 +511,14 @@ void gDPLoadTile(u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt) return; const u32 bpl = gDP.loadTile->line << 3; - if (((gDP.loadTile->tmem << 3) + height * bpl) > 4096) // Stay within TMEM + if (((gDP.loadTile->tmem << 3) + height * bpl) > TMEM_SIZE_BYTES) // Stay within TMEM { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_TEXTURE, "// Attempting to load texture tile out of range\n" ); DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadTile( %i, %i, %i, %i, %i );\n", tile, gDP.loadTile->uls, gDP.loadTile->ult, gDP.loadTile->lrs, gDP.loadTile->lrt ); #endif - height = (4096 - (gDP.loadTile->tmem << 3)) / bpl; + height = (TMEM_SIZE_BYTES - (gDP.loadTile->tmem << 3)) / bpl; } u32 bpl2 = bpl; @@ -626,20 +626,18 @@ void gDPLoadBlock(u32 tile, u32 uls, u32 ult, u32 lrs, u32 dxt) info.loadType = LOADTYPE_BLOCK; u32 bytes = (lrs - uls + 1) << gDP.loadTile->size >> 1; + if (((gDP.loadTile->tmem << 3) + bytes) > TMEM_SIZE_BYTES) // Stay within TMEM + bytes = TMEM_SIZE_BYTES - (gDP.loadTile->tmem << 3); if ((bytes & 7) != 0) bytes = (bytes & (~7)) + 8; u32 address = gDP.textureImage.address + ult * gDP.textureImage.bpl + (uls << gDP.textureImage.size >> 1); - if ((bytes == 0) || - ((address + bytes) > RDRAMSize) || - (((gDP.loadTile->tmem << 3) + bytes) > 4096)) - { + if (bytes == 0 || (address + bytes) > RDRAMSize) { #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_TEXTURE, "// Attempting to load texture block out of range\n" ); - DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadBlock( %i, %i, %i, %i, %i );\n", + DebugMsg(DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadBlock( %i, %i, %i, %i, %i );\n", tile, uls, ult, lrs, dxt ); #endif -// bytes = min( bytes, min( RDRAMSize - gDP.textureImage.address, 4096 - (gDP.loadTile->tmem << 3) ) ); return; }