diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp index d8d658627..694835f8b 100644 --- a/src/CxbxKrnl/EmuD3D8.cpp +++ b/src/CxbxKrnl/EmuD3D8.cpp @@ -1209,7 +1209,7 @@ static void EmuUnswizzleTextureStages() void *pTemp = malloc(dwHeight*dwPitch); - XTL::EmuXGUnswizzleRect + XTL::EmuUnswizzleRect ( LockedRect.pBits, dwWidth, dwHeight, dwDepth, pTemp, dwPitch, iRect, iPoint, dwBPP @@ -4493,14 +4493,14 @@ HRESULT WINAPI XTL::EmuIDirect3DResource8_Register // TODO: check for dimensions // TODO: HACK: Temporary? - if(X_Format == 0x2E) + if(X_Format == X_D3DFMT_LIN_D24S8) { /*CxbxKrnlCleanup*/EmuWarning("D3DFMT_LIN_D24S8 not yet supported!"); X_Format = X_D3DFMT_LIN_A8R8G8B8; Format = D3DFMT_A8R8G8B8; } - if(X_Format == 0x30) + if(X_Format == X_D3DFMT_LIN_D16) { /*CxbxKrnlCleanup*/EmuWarning("D3DFMT_LIN_D16 not yet supported!"); X_Format = X_D3DFMT_LIN_R5G6B5; @@ -4811,9 +4811,8 @@ HRESULT WINAPI XTL::EmuIDirect3DResource8_Register } else { - //__asm int 3; // First we need to unswizzle the texture data - XTL::EmuXGUnswizzleRect + XTL::EmuUnswizzleRect ( pSrc + dwMipOffs, dwMipWidth, dwMipHeight, dwDepth, LockedRect.pBits, LockedRect.Pitch, iRect, iPoint, dwBPP @@ -4822,13 +4821,8 @@ HRESULT WINAPI XTL::EmuIDirect3DResource8_Register if (CacheFormat == D3DFMT_P8) //Palette { EmuWarning("Unsupported texture format D3DFMT_P8,\nexpanding to D3DFMT_A8R8G8B8"); -//#if 0 - // - // create texture resource - // - //__asm int 3; - BYTE *pPixelData = (BYTE*)LockedRect.pBits; + BYTE *pPixelData = (BYTE*)LockedRect.pBits; DWORD dwDataSize = dwMipWidth*dwMipHeight; DWORD* pExpandedTexture = (DWORD*)CxbxMalloc(dwDataSize * sizeof(DWORD)); DWORD* pTexturePalette = (DWORD*)pCurrentPalette; @@ -4858,7 +4852,6 @@ HRESULT WINAPI XTL::EmuIDirect3DResource8_Register // Flush unused data buffers CxbxFree(pExpandedTexture); -//#endif } } } diff --git a/src/CxbxKrnl/EmuD3D8/Convert.cpp b/src/CxbxKrnl/EmuD3D8/Convert.cpp index b91c37733..1fb372fe1 100644 --- a/src/CxbxKrnl/EmuD3D8/Convert.cpp +++ b/src/CxbxKrnl/EmuD3D8/Convert.cpp @@ -544,3 +544,101 @@ CONST DWORD XTL::EmuD3DRenderStateSimpleEncoded[174] = X_D3DRSSE_UNK, 0x00040350, // 170 X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 172 }; + +void XTL::EmuUnswizzleRect +( + PVOID pSrcBuff, + DWORD dwWidth, + DWORD dwHeight, + DWORD dwDepth, + PVOID pDstBuff, + DWORD dwPitch, + RECT rSrc, // Unused + POINT poDst, // Unused + DWORD dwBPP // expressed in Bytes Per Pixel +) // Source : Dxbx +{ + // TODO : The following could be done using a lookup table : + DWORD dwMaskX = 0, dwMaskY = 0, dwMaskZ = 0; + for (uint i=1, j=1; (i <= dwWidth) || (i <= dwHeight) || (i <= dwDepth); i <<= 1) { + if (i < dwWidth) { + dwMaskX = dwMaskX | j; + j <<= 1; + }; + + if (i < dwHeight) { + dwMaskY = dwMaskY | j; + j <<= 1; + } + + if (i < dwDepth) { + dwMaskZ = dwMaskZ | j; + j <<= 1; + } + } + + // get the biggest mask + DWORD dwMaskMax; + if (dwMaskX > dwMaskY) + dwMaskMax = dwMaskX; + else + dwMaskMax = dwMaskY; + + if (dwMaskZ > dwMaskMax) + dwMaskMax = dwMaskZ; + + DWORD dwStartX = 0, dwOffsetX = 0; + DWORD dwStartY = 0, dwOffsetY = 0; + DWORD dwStartZ = 0, dwOffsetW = 0; + /* TODO : Use values from poDst and rSrc to initialize above values, after which the following makes more sense: + for (uint i=1; i <= dwMaskMax; i <<= 1) { + if (i <= dwMaskX) { + if (dwMaskX & i) + dwStartX |= (dwOffsetX & i); + else + dwOffsetX <<= 1; + } + + if (i <= dwMaskY) { + if (dwMaskY & i) + dwStartY |= dwOffsetY & i; + else + dwOffsetY <<= 1; + } + + if (i <= dwMaskZ) { + if (dwMaskZ & i) + dwStartZ |= dwOffsetZ & i; + else + dwOffsetZ <<= 1; + } + }*/ + + DWORD dwZ = dwStartZ; + for (uint z = 0; z < dwDepth; z++) { + DWORD dwY = dwStartY; + // TODO : How could we do one memcpy when lines AND pixels are next to eachother? + for (uint y = 0; y < dwHeight; y++) { + DWORD dwX = dwStartX; + // We use one memcpy for the entire line when pixels are next to eachother : + // TODO : How can we simplify the next check; (dwMaskX & 1) perhaps? + if (dwX + 1 == (dwX - dwMaskX) & dwMaskX) { + memcpy(pDstBuff, (PBYTE)pSrcBuff + (dwX | dwY | dwZ) * dwBPP, dwBPP * dwWidth); // copy one line + pDstBuff = (PBYTE)pDstBuff + dwBPP * dwWidth; // Step to next line in destination + } + else { + for (uint x = 0; x < dwWidth; x++) { + memcpy(pDstBuff, (PBYTE)pSrcBuff + (dwX | dwY | dwZ) * dwBPP, dwBPP); // copy one pixel + pDstBuff = (PBYTE)pDstBuff + dwBPP; // Step to next pixel in destination + dwX = (dwX - dwMaskX) & dwMaskX; // step to next pixel in source + } + } + + pDstBuff = (PBYTE)pDstBuff + dwPitch - (dwWidth * dwBPP); // step to next line in destination + dwY = (dwY - dwMaskY) & dwMaskY; // step to next line in source + } + + // TODO : How to step to next level in destination? Should X and Y be recalculated per level? + dwZ = (dwZ - dwMaskZ) & dwMaskZ; // step to next level in source + } +} // EmuUnswizzleRect NOPATCH diff --git a/src/CxbxKrnl/EmuD3D8/Convert.h b/src/CxbxKrnl/EmuD3D8/Convert.h index 380f1a9b2..caa30516f 100644 --- a/src/CxbxKrnl/EmuD3D8/Convert.h +++ b/src/CxbxKrnl/EmuD3D8/Convert.h @@ -205,4 +205,17 @@ inline D3DPRIMITIVETYPE EmuPrimitiveType(X_D3DPRIMITIVETYPE PrimitiveType) return EmuPrimitiveTypeLookup[PrimitiveType]; } +extern void EmuUnswizzleRect +( + PVOID pSrcBuff, + DWORD dwWidth, + DWORD dwHeight, + DWORD dwDepth, + PVOID pDstBuff, + DWORD dwPitch, + RECT rSrc, // Unused + POINT poDst, // Unused + DWORD dwBPP // expressed in Bytes Per Pixel +); // NOPATCH + #endif \ No newline at end of file diff --git a/src/CxbxKrnl/EmuD3D8/PushBuffer.cpp b/src/CxbxKrnl/EmuD3D8/PushBuffer.cpp index f550f7ada..14468c06e 100644 --- a/src/CxbxKrnl/EmuD3D8/PushBuffer.cpp +++ b/src/CxbxKrnl/EmuD3D8/PushBuffer.cpp @@ -133,7 +133,7 @@ static void EmuUnswizzleActiveTexture() void *pTemp = malloc(dwHeight*dwPitch); - XTL::EmuXGUnswizzleRect + XTL::EmuUnswizzleRect ( LockedRect.pBits, dwWidth, dwHeight, dwDepth, pTemp, dwPitch, iRect, iPoint, dwBPP diff --git a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp index 81d212b99..c4e7748ee 100644 --- a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp @@ -1364,7 +1364,7 @@ VOID XTL::EmuFlushIVB() return; } -VOID XTL::EmuUpdateActiveTexture() +VOID XTL::EmuUpdateActiveTexture() // Never called! { // // DEBUGGING @@ -1513,7 +1513,7 @@ VOID XTL::EmuUpdateActiveTexture() } else { - XTL::EmuXGUnswizzleRect + XTL::EmuUnswizzleRect ( pSrc + dwMipOffs, dwMipWidth, dwMipHeight, dwDepth, LockedRect.pBits, LockedRect.Pitch, iRect, iPoint, dwBPP diff --git a/src/CxbxKrnl/EmuXG.cpp b/src/CxbxKrnl/EmuXG.cpp index 7b3629e16..4310c4670 100644 --- a/src/CxbxKrnl/EmuXG.cpp +++ b/src/CxbxKrnl/EmuXG.cpp @@ -192,113 +192,6 @@ VOID WINAPI XTL::EmuXGSwizzleBox } } -// ****************************************************************** -// * func: EmuXGUnswizzleRect -// ****************************************************************** -VOID WINAPI XTL::EmuXGUnswizzleRect -( - PVOID pSrcBuff, - DWORD dwWidth, - DWORD dwHeight, - DWORD dwDepth, - PVOID pDstBuff, - DWORD dwPitch, - RECT rSrc, - POINT poDst, - DWORD dwBPP -) -{ - DWORD dwOffsetU = 0, dwMaskU = 0; - DWORD dwOffsetV = 0, dwMaskV = 0; - DWORD dwOffsetW = 0, dwMaskW = 0; - - DWORD i = 1; - DWORD j = 1; - -// while( (i >= dwWidth) || (i >= dwHeight) || (i >= dwDepth) ) - while( (i <= dwWidth) || (i <= dwHeight) || (i <= dwDepth) ) - { - if(i < dwWidth) - { - dwMaskU |= j; - j<<=1; - } - - if(i < dwHeight) - { - dwMaskV |= j; - j<<=1; - } - - if(i < dwDepth) - { - dwMaskW |= j; - j<<=1; - } - - i<<=1; - } - - DWORD dwSU = 0; - DWORD dwSV = 0; - DWORD dwSW = 0; - DWORD dwMaskMax=0; - - // get the biggest mask - if(dwMaskU > dwMaskV) - dwMaskMax=dwMaskU; - else - dwMaskMax=dwMaskV; - if(dwMaskW > dwMaskMax) - dwMaskMax=dwMaskW; - - for(i = 1; i <= dwMaskMax; i<<=1) - { - if(i<=dwMaskU) - { - if(dwMaskU & i) dwSU |= (dwOffsetU & i); - else dwOffsetU<<=1; - } - - if(i<=dwMaskV) - { - if(dwMaskV & i) dwSV |= (dwOffsetV & i); - else dwOffsetV<<=1; - } - - if(i<=dwMaskW) - { - if(dwMaskW & i) dwSW |= (dwOffsetW & i); - else dwOffsetW<<=1; - } - } - - DWORD dwW = dwSW; - DWORD dwV = dwSV; - DWORD dwU = dwSU; - - for(DWORD z=0; z