Fixed Magical Truck Adventure by emulating VROM texture ports as a FIFO. Now, VF3 crashes on Akira's stage (and probably the other stages with texture glitches). Other games may be affected, too (not thoroughly tested yet).

This commit is contained in:
Bart Trzynadlowski 2016-04-11 00:19:10 +00:00
parent 775256118d
commit 2524f2e837
2 changed files with 22 additions and 33 deletions

View file

@ -79,8 +79,7 @@ void CReal3D::SaveState(CBlockFile *SaveState)
SaveState->Write(memoryPool, MEM_POOL_SIZE_RW); // Don't write out read-only snapshots or dirty page arrays SaveState->Write(memoryPool, MEM_POOL_SIZE_RW); // Don't write out read-only snapshots or dirty page arrays
SaveState->Write(&fifoIdx, sizeof(fifoIdx)); SaveState->Write(&fifoIdx, sizeof(fifoIdx));
SaveState->Write(&vromTextureAddr, sizeof(vromTextureAddr)); SaveState->Write(m_vromTextureFIFO, sizeof(m_vromTextureFIFO));
SaveState->Write(&vromTextureHeader, sizeof(vromTextureHeader));
SaveState->Write(&dmaSrc, sizeof(dmaSrc)); SaveState->Write(&dmaSrc, sizeof(dmaSrc));
SaveState->Write(&dmaDest, sizeof(dmaDest)); SaveState->Write(&dmaDest, sizeof(dmaDest));
@ -96,6 +95,8 @@ void CReal3D::SaveState(CBlockFile *SaveState)
SaveState->Write(&tapIDSize, sizeof(tapIDSize)); SaveState->Write(&tapIDSize, sizeof(tapIDSize));
SaveState->Write(&tapTDO, sizeof(tapTDO)); SaveState->Write(&tapTDO, sizeof(tapTDO));
SaveState->Write(&tapState, sizeof(tapState)); SaveState->Write(&tapState, sizeof(tapState));
SaveState->Write(&m_vromTextureFIFOIdx, sizeof(m_vromTextureFIFOIdx));
} }
void CReal3D::LoadState(CBlockFile *SaveState) void CReal3D::LoadState(CBlockFile *SaveState)
@ -113,8 +114,7 @@ void CReal3D::LoadState(CBlockFile *SaveState)
UpdateSnapshots(true); UpdateSnapshots(true);
Render3D->UploadTextures(0, 0, 2048, 2048); Render3D->UploadTextures(0, 0, 2048, 2048);
SaveState->Read(&fifoIdx, sizeof(fifoIdx)); SaveState->Read(&fifoIdx, sizeof(fifoIdx));
SaveState->Read(&vromTextureAddr, sizeof(vromTextureAddr)); SaveState->Read(&m_vromTextureFIFO, sizeof(m_vromTextureFIFO));
SaveState->Read(&vromTextureHeader, sizeof(vromTextureHeader));
SaveState->Read(&dmaSrc, sizeof(dmaSrc)); SaveState->Read(&dmaSrc, sizeof(dmaSrc));
SaveState->Read(&dmaDest, sizeof(dmaDest)); SaveState->Read(&dmaDest, sizeof(dmaDest));
@ -130,6 +130,8 @@ void CReal3D::LoadState(CBlockFile *SaveState)
SaveState->Read(&tapIDSize, sizeof(tapIDSize)); SaveState->Read(&tapIDSize, sizeof(tapIDSize));
SaveState->Read(&tapTDO, sizeof(tapTDO)); SaveState->Read(&tapTDO, sizeof(tapTDO));
SaveState->Read(&tapState, sizeof(tapState)); SaveState->Read(&tapState, sizeof(tapState));
SaveState->Read(&m_vromTextureFIFOIdx, sizeof(m_vromTextureFIFOIdx));
} }
@ -610,7 +612,7 @@ static void StoreTexelByte(uint16_t *texel, size_t byteSelect, uint8_t byte)
*texel = (*texel & 0x00FF) | (uint16_t(byte) << 8); *texel = (*texel & 0x00FF) | (uint16_t(byte) << 8);
} }
void CReal3D::StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigned height, uint16_t *texData, uint32_t header) void CReal3D::StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigned height, const uint16_t *texData, uint32_t header)
{ {
if ((header & 0x00800000)) // 16-bit textures if ((header & 0x00800000)) // 16-bit textures
{ {
@ -694,7 +696,7 @@ void CReal3D::StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigne
} }
// Texture data will be in little endian format // Texture data will be in little endian format
void CReal3D::UploadTexture(uint32_t header, uint16_t *texData) void CReal3D::UploadTexture(uint32_t header, const uint16_t *texData)
{ {
// Position: texture RAM is arranged as 2 2048x1024 texel sheets // Position: texture RAM is arranged as 2 2048x1024 texel sheets
size_t x = 32*(header&0x3F); size_t x = 32*(header&0x3F);
@ -830,26 +832,15 @@ void CReal3D::WriteTextureFIFO(uint32_t data)
void CReal3D::WriteTexturePort(unsigned reg, uint32_t data) void CReal3D::WriteTexturePort(unsigned reg, uint32_t data)
{ {
//printf("Texture Port: %X=%08X\n", reg, data); if (m_vromTextureFIFOIdx == 2)
switch (reg)
{ {
case 0x0: // VROM texture address uint32_t addr = m_vromTextureFIFO[0];
case 0xC: uint32_t header = m_vromTextureFIFO[1];
vromTextureAddr = data; UploadTexture(header, (const uint16_t *) &vrom[addr & 0xFFFFFF]);
break; m_vromTextureFIFOIdx = 0;
case 0x4: // VROM texture header
case 0x10:
vromTextureHeader = data;
break;
case 0x8: // VROM texture length (also used to trigger uploads)
case 0x14:
UploadTexture(vromTextureHeader,(uint16_t *)&vrom[vromTextureAddr&0xFFFFFF]);
//printf("texture upload: addr=%08X\n", vromTextureAddr);
break;
default:
DebugLog("Real3D texture port write: %X=%08X\n", reg, data);
break;
} }
else
m_vromTextureFIFO[m_vromTextureFIFOIdx++] = data;
} }
void CReal3D::WriteLowCullingRAM(uint32_t addr, uint32_t data) void CReal3D::WriteLowCullingRAM(uint32_t addr, uint32_t data)
@ -940,8 +931,7 @@ void CReal3D::Reset(void)
queuedUploadTexturesRO.clear(); queuedUploadTexturesRO.clear();
fifoIdx = 0; fifoIdx = 0;
vromTextureAddr = 0; m_vromTextureFIFOIdx = 0;
vromTextureHeader = 0;
tapState = 0; tapState = 0;
tapIDSize = 197; tapIDSize = 197;
dmaStatus = 0; dmaStatus = 0;
@ -949,6 +939,7 @@ void CReal3D::Reset(void)
unsigned memSize = (g_Config.gpuMultiThreaded ? MEMORY_POOL_SIZE : MEM_POOL_SIZE_RW); unsigned memSize = (g_Config.gpuMultiThreaded ? MEMORY_POOL_SIZE : MEM_POOL_SIZE_RW);
memset(memoryPool, 0, memSize); memset(memoryPool, 0, memSize);
memset(m_vromTextureFIFO, 0, sizeof(m_vromTextureFIFO));
DebugLog("Real3D reset\n"); DebugLog("Real3D reset\n");
} }
@ -1049,8 +1040,6 @@ CReal3D::CReal3D(void)
vrom = NULL; vrom = NULL;
error = false; error = false;
fifoIdx = 0; fifoIdx = 0;
vromTextureAddr = 0;
vromTextureHeader = 0;
tapState = 0; tapState = 0;
tapIDSize = 197; tapIDSize = 197;
DebugLog("Built Real3D\n"); DebugLog("Built Real3D\n");

View file

@ -383,8 +383,8 @@ private:
void InsertBit(uint8_t *buf, unsigned bitNum, unsigned bit); void InsertBit(uint8_t *buf, unsigned bitNum, unsigned bit);
void InsertID(uint32_t id, unsigned startBit); void InsertID(uint32_t id, unsigned startBit);
unsigned Shift(uint8_t *data, unsigned numBits); unsigned Shift(uint8_t *data, unsigned numBits);
void StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigned height, uint16_t *texData, uint32_t header); void StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigned height, const uint16_t *texData, uint32_t header);
void UploadTexture(uint32_t header, uint16_t *texData); void UploadTexture(uint32_t header, const uint16_t *texData);
uint32_t UpdateSnapshots(bool copyWhole); uint32_t UpdateSnapshots(bool copyWhole);
uint32_t UpdateSnapshot(bool copyWhole, uint8_t *src, uint8_t *dst, unsigned size, uint8_t *dirty); uint32_t UpdateSnapshot(bool copyWhole, uint8_t *src, uint8_t *dst, unsigned size, uint8_t *dirty);
@ -406,9 +406,9 @@ private:
uint32_t *polyRAM; // 4MB of polygon RAM at 98000000 uint32_t *polyRAM; // 4MB of polygon RAM at 98000000
uint16_t *textureRAM; // 8MB of internal texture RAM uint16_t *textureRAM; // 8MB of internal texture RAM
uint32_t *textureFIFO; // 1MB texture FIFO at 0x94000000 uint32_t *textureFIFO; // 1MB texture FIFO at 0x94000000
size_t fifoIdx; // index into texture FIFO uint32_t fifoIdx; // index into texture FIFO
uint32_t vromTextureAddr; // VROM texture port address data uint32_t m_vromTextureFIFO[2] = { 0, 0 };
uint32_t vromTextureHeader; // VROM texture port header data uint32_t m_vromTextureFIFOIdx = 0;
// Read-only snapshots // Read-only snapshots
uint32_t *cullingRAMLoRO; // 4MB of culling RAM at 8C000000 [read-only snapshot] uint32_t *cullingRAMLoRO; // 4MB of culling RAM at 8C000000 [read-only snapshot]