Jump to content

Unswizzle Tool


Blitz091

Recommended Posts

A group of emembers at my site have created an unswizzle tool for San Andreas on the Xbox. Skinning characers was before impossible, but soon it will be a reality. Members at another board have requested this tool be implemented into TXD workshop to make it more xbox compatible. I will post a link to the downlaod when it is doen, if the author of workshop wants to add it, great, if he gives proper credit and does it fair great, i will link to the source if he is interested.

Link to comment
Share on other sites

hi, i'm the author of txd workshop (gtatools.com), this is great news! now i need some xbox txds and the unswizzle algorythms, contact me by PM or post files / details in this topic about it.

 

Currently working on Top Down City Game, a classics top down game similar to GTA1 & GTA2: 

 

Thread Info: https://gtaforums.com/topic/911312-new-game-top-down-city/

Youtube channel: https://www.youtube.com/channel/UCxGfOh3ld7Xm-ic3KEMB6iA 

Discord: https://discord.gg/UXmDPzS - join #bridge channel 

Link to comment
Share on other sites

Hey Delfi, love TXDWorkshop thanks so much...I see a common problem with users involvng .bmp, most people think it's not possible to use photoshop/.bmp with TXDWorkshop, check my post here

Link to comment
Share on other sites

hi, i'm the author of txd workshop (gtatools.com), this is great news! now i need some xbox txds and the unswizzle algorythms, contact me by PM or post files / details in this topic about it.

www.therockerscabin.com/soulxplorer/

 

go tehre, i will let you into a coding section. You will get all the info there.

Link to comment
Share on other sites

If you need generic XBOX Swizzle/Unswizzle functions, here's something I wrote a while ago. It's in VB, I hope its understandable for you Delphi guys smile.gif UnswizBlock and SwizBlock are just helpers... Swizzle and Unswizzle are the real thing... CTpkTexture is just a custom class to encapsulate a texture object... the properties used from it should be enough to show what information is required.

 

 

Private Function SwizBlock(ByRef OutData() As Byte, ByRef InData() As Byte, ByRef OffsOut As Long, ByVal Offs As Long, ByVal BlWidth As Long, ByVal BlHeight As Long, ByVal Stride As Long)   If (Offs > UBound(InData)) Then Exit Function   If BlWidth < 2 Or BlHeight < 2 Then       ' just copy data here       CopyMemory OutData(Offs), InData(OffsOut), BlWidth * BlHeight       OffsOut = OffsOut + BlWidth * BlHeight   ElseIf BlWidth = 2 And BlHeight = 2 Then       ' swizzle block       OutData(OffsOut) = InData(Offs)       OutData(OffsOut + 1) = InData(Offs + 1)       OutData(OffsOut + 2) = InData(Offs + Stride)       OutData(OffsOut + 3) = InData(Offs + Stride + 1)       OffsOut = OffsOut + 4   Else       ' break into 4 blocks and reprocess       SwizBlock OutData, InData, OffsOut, Offs, BlWidth / 2, BlHeight / 2, Stride       SwizBlock OutData, InData, OffsOut, Offs + (BlWidth / 2), BlWidth / 2, BlHeight / 2, Stride       SwizBlock OutData, InData, OffsOut, Offs + (Stride * (BlHeight / 2)), BlWidth / 2, BlHeight / 2, Stride       SwizBlock OutData, InData, OffsOut, Offs + (Stride * (BlHeight / 2)) + (BlWidth / 2), BlWidth / 2, BlHeight / 2, Stride   End IfEnd FunctionPublic Function Swizzle(InTex As CTpkTexture, Data() As Byte) As Byte()   Dim bytData() As Byte, bytDataOut() As Byte   Dim lOffs As Long, i As Long, Width As Long, Height As Long   Dim MinMax As Long, MipLevels As Long, DataLen As Long   MinMax = IIf(InTex.TexHeight > InTex.TexWidth, InTex.TexHeight, InTex.TexWidth)   MipLevels = Log(MinMax) / Log(2) + 1      lOffs = 0   bytData = Data   ReDim bytDataOut(UBound(bytData))      Width = InTex.TexWidth   Height = InTex.TexHeight      For i = 1 To MipLevels       SwizBlock bytDataOut, bytData, lOffs, lOffs, Width, Height, Width       Width = Width / 2       Height = Height / 2       If lOffs > UBound(bytData) Then Exit For   Next      Swizzle = bytDataOut   End FunctionPrivate Function UnswizBlock(ByRef InData() As Byte, ByRef OutData() As Byte, ByRef Offs As Long, ByVal OffsOut As Long, ByVal BlWidth As Long, ByVal BlHeight As Long, ByVal Stride As Long)   If (Offs > UBound(InData)) Then Exit Function   If BlWidth < 2 Or BlHeight < 2 Then       ' just copy data here       CopyMemory OutData(OffsOut), InData(Offs), BlWidth * BlHeight       OffsOut = OffsOut + BlWidth * BlHeight   ElseIf BlWidth = 2 And BlHeight = 2 Then       ' unswizzle block       OutData(OffsOut) = InData(Offs)       OutData(OffsOut + 1) = InData(Offs + 1)       OutData(OffsOut + Stride) = InData(Offs + 2)       OutData(OffsOut + Stride + 1) = InData(Offs + 3)       Offs = Offs + 4   Else       ' break into 4 blocks and reprocess       UnswizBlock InData, OutData, Offs, OffsOut, BlWidth / 2, BlHeight / 2, Stride       UnswizBlock InData, OutData, Offs, OffsOut + (BlWidth / 2), BlWidth / 2, BlHeight / 2, Stride       UnswizBlock InData, OutData, Offs, OffsOut + (Stride * (BlHeight / 2)), BlWidth / 2, BlHeight / 2, Stride       UnswizBlock InData, OutData, Offs, OffsOut + (Stride * (BlHeight / 2)) + (BlWidth / 2), BlWidth / 2, BlHeight / 2, Stride   End IfEnd FunctionPublic Function Unswizzle(InTex As CTpkTexture) As Byte()   Dim bytData() As Byte, bytDataOut() As Byte   Dim lOffs As Long, i As Long, Width As Long, Height As Long   Dim MinMax As Long, MipLevels As Long   MinMax = IIf(InTex.TexHeight > InTex.TexWidth, InTex.TexHeight, InTex.TexWidth)   MipLevels = Log(MinMax) / Log(2) + 1      lOffs = 0   bytData = InTex.GetData(True)   ReDim bytDataOut(UBound(bytData))      Width = InTex.TexWidth   Height = InTex.TexHeight      For i = 1 To MipLevels       UnswizBlock bytData, bytDataOut, lOffs, lOffs, Width, Height, Width       Width = Width / 2       Height = Height / 2       If lOffs > UBound(bytData) Then Exit For   Next      Unswizzle = bytDataOutEnd Function

 

Link to comment
Share on other sites

Can you please try to explain how the swizzling works, because that vb code looks to me like a bunch of swear words wow.gif

 

Currently working on Top Down City Game, a classics top down game similar to GTA1 & GTA2: 

 

Thread Info: https://gtaforums.com/topic/911312-new-game-top-down-city/

Youtube channel: https://www.youtube.com/channel/UCxGfOh3ld7Xm-ic3KEMB6iA 

Discord: https://discord.gg/UXmDPzS - join #bridge channel 

Link to comment
Share on other sites

 

Can you please try to explain how the swizzling works, because that vb code looks to me like a bunch of swear words wow.gif

lol okay, umm lets see.

 

In simple words, swizzling means to store the data in a form such that the tU and tV coordinates' addressing indices are interleaved.

 

To explain that VB code, first the Swizzle() function:

 

Calculate # of MipMaps:

 

  MinMax = IIf(InTex.TexHeight > InTex.TexWidth, InTex.TexHeight, InTex.TexWidth)  MipLevels = Log(MinMax) / Log(2) + 1

 

 

For each mipmap level, call SwizBlock() and then half the width and height (since the next mipmap level should be half the size of the previous one). If you know exactly know many mipmaps you have and are sure you have enough data, you may remove the "Exit For" line since that just breaks out of the loop incase we overflow the # of mipmaps.

 

  For i = 1 To MipLevels      SwizBlock bytDataOut, bytData, lOffs, lOffs, Width, Height, Width      Width = Width / 2      Height = Height / 2      If lOffs > UBound(bytData) Then Exit For  Next

 

 

Now in SwizBlock, this is just a don't process if we don't have enough data:

 

   If (Offs > UBound(InData)) Then Exit Function

 

 

If the Block Width is less than 2 or the Block Height is less than 2, i.e. we have a 2x1 block, 1x2 block or a 4x1 block, etc, we just copy the pixels. There might be a bug here.. I'm not sure... and I have no idea why I used CopyMemory/RtlMoveMemory.. seems like a waste of an API call.

 

  If BlWidth < 2 Or BlHeight < 2 Then      ' just copy data here      CopyMemory OutData(Offs), InData(OffsOut), BlWidth * BlHeight      OffsOut = OffsOut + BlWidth * BlHeight

 

 

If it is exactly a 2x2 block, then we perform the swizzle. This pretty much takes a 2x2 block of data and converts it to a 4x1 block. The Stride tells the length of one line of pixel data (this is not the block width!):

 

   ElseIf BlWidth = 2 And BlHeight = 2 Then      ' swizzle block      OutData(OffsOut) = InData(Offs)      OutData(OffsOut + 1) = InData(Offs + 1)      OutData(OffsOut + 2) = InData(Offs + Stride)      OutData(OffsOut + 3) = InData(Offs + Stride + 1)      OffsOut = OffsOut + 4

 

 

Otherwise, we need to break up the block into 4 equally sized smaller blocks and perform SwizBlock on them again. The first SwizBlock does the upper-left corner, the second one does the upper-right corner, etc. This is probabbly the most confusing part... draw out the pixels on a peice of paper and figure out the algorithm tounge.gif

 

   Else      ' break into 4 blocks and reprocess      SwizBlock OutData, InData, OffsOut, Offs, BlWidth / 2, BlHeight / 2, Stride      SwizBlock OutData, InData, OffsOut, Offs + (BlWidth / 2), BlWidth / 2, BlHeight / 2, Stride      SwizBlock OutData, InData, OffsOut, Offs + (Stride * (BlHeight / 2)), BlWidth / 2, BlHeight / 2, Stride      SwizBlock OutData, InData, OffsOut, Offs + (Stride * (BlHeight / 2)) + (BlWidth / 2), BlWidth / 2, BlHeight / 2, Stride  End If

 

 

If you notice.. SwizBlock is a recursive function with a O(log2(min(width,height)))... so it's not so bad and won't overflow the call stack. I believe I have only tested this with equal Width/Height sized textures. Not sure how well it works with different sized ones.

 

Unswizzle is similar to the process above.

Edited by aru
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • 1 User Currently Viewing
    0 members, 0 Anonymous, 1 Guest

×
×
  • Create New...

Important Information

By using GTAForums.com, you agree to our Terms of Use and Privacy Policy.