{PS2 unswizzling procedure for 4bit textures www.Dageron.com} //in interface procedure UnSwizzle4X(var Source, Dest; const dwWidth, dwHeight: Integer; bInverted: Boolean = False); //in implementation type TBytes = array[Byte] of Byte; const InterlaceMatrix: array[0..7] of Byte = ($00, $10, $02, $12, $11, $01, $13, $03); Matrix: array[0..3] of Integer = (0, 1, -1, 0); TileMatrix: array[0..1] of Integer = (4, -4); procedure UnSwizzle4X(var Source, Dest; const dwWidth, dwHeight: Integer; bInverted: Boolean = False); var X, Y, XX, YY, I, J, MW: Integer; S, D: ^Byte; Pixels, NewPixels: array of Byte; begin if (dwWidth mod 32 > 0) or (dwHeight mod 16 > 0) then Move(Source, Dest, (dwWidth shr 1) * dwHeight) else begin SetLength(Pixels, dwWidth * dwHeight); SetLength(NewPixels, dwWidth * dwHeight); S := Addr(Source); D := Addr(Pixels[0]); if not bInverted then for Y := 0 to dwHeight - 1 do For X := 0 to dwWidth shr 1 - 1 do begin D^ := S^ and 15; Inc(D); D^ := S^ shr 4; Inc(D); Inc(S); end else for Y := 0 to dwHeight - 1 do For X := 0 to dwWidth shr 1 - 1 do begin D^ := S^ shr 4; Inc(D); D^ := S^ and 15; Inc(D); Inc(S); end; MW := dwWidth; if MW mod 32 > 0 then MW := (MW div 32) * 32 + 32; for Y := 0 to dwHeight - 1 do begin if Odd(Y) then For X := 0 to dwWidth - 1 do begin XX := X + Byte(Odd(Y div 4)) * TileMatrix[Byte(Odd(X div 4))]; YY := Y + Matrix[Y mod 4]; I := InterlaceMatrix[(X div 4) mod 4 + 4] + (X * 4) mod 16 + (X div 16) * 32 + ((Y - 1) * MW); J := YY * dwWidth + XX; NewPixels[J] := Pixels[I]; end else for X := 0 to dwWidth - 1 do begin XX := X + Byte(Odd(Y div 4)) * TileMatrix[Byte(Odd(X div 4))]; YY := Y + Matrix[Y mod 4]; I := InterlaceMatrix[(X div 4) mod 4] + (X * 4) mod 16 + (X div 16) * 32 + (Y * MW); J := YY * dwWidth + XX; NewPixels[J] := Pixels[I]; end; end; S := Addr(NewPixels[0]); D := Addr(Dest); if not bInverted then for Y := 0 to dwHeight - 1 do For X := 0 to dwWidth shr 1 - 1 do begin D^ := S^ and 15; Inc(S); D^ := D^ or (S^ shl 4); Inc(S); Inc(D); end else for Y := 0 to dwHeight - 1 do For X := 0 to dwWidth shr 1 - 1 do begin D^ := S^ shl 4; Inc(S); D^ := D^ or (S^ and 15); Inc(S); Inc(D); end; Finalize(NewPixels); Finalize(Pixels); end; end;