XeNTaX
http://forum.xentax.com/

PS2 texture unswizzling (4-bit textures)
http://forum.xentax.com/viewtopic.php?f=18&t=3516
Page 1 of 1

Author:  Nick W [ Sat May 30, 2009 3:38 am ]
Post subject:  PS2 texture unswizzling (4-bit textures)

To make a long story short, I'm working on the SVR image format and I'm having trouble unswizzling 4-bit textures. I've already got 8-bit texture unswizzling working fine.

The image on the left is what it should look like, the image on the right is how it currently works with my unswizzle code.

Image Image

I'm currently using Sparky's Swizzle Code for this, obviously modified so it unswizzles rather than swizzles again.

Here is the code I'm currently using (C#):
Code:
        // Unswizzle a 4-bit PS2 texture
        public static void UnSwizzle4(byte[] Buf, int Width, int Height, int Where)
        {
            // Don't swizzle if size if width or height is less than 128
            if (Width < 128 || Height < 128)
                return;

            // Make a copy of the swizzled input and clear buffer
            byte[] Swizzled = new byte[Buf.Length - Where];
            Array.Copy(Buf, Where, Swizzled, 0, Swizzled.Length);

            for (int y = 0; y < Height; y++)
            {
                for (int x = 0; x < Width; x++)
                {
                    // get the pen
                    int index = y * Width + x;
                    //byte uPen = (byte)(Swizzled[index >> 1] >> ((index & 1) * 4) & 0xF);

                    // swizzle
                    int pageX = x & (~0x7f);
                    int pageY = y & (~0x7f);

                    int pages_horz = (Width + 127) / 128;
                    int pages_vert = (Height + 127) / 128;

                    int page_number = (pageY / 128) * pages_horz + (pageX / 128);

                    int page32Y = (page_number / pages_vert) * 32;
                    int page32X = (page_number % pages_vert) * 64;

                    int page_location = page32Y * Height * 2 + page32X * 4;

                    int locX = x & 0x7f;
                    int locY = y & 0x7f;

                    int block_location = ((locX & (~0x1f)) >> 1) * Height + (locY & (~0xf)) * 2;
                    int swap_selector = (((y + 2) >> 2) & 0x1) * 4;
                    int posY = (((y & (~3)) >> 1) + (y & 1)) & 0x7;

                    int column_location = posY * Height * 2 + ((x + swap_selector) & 0x7) * 4;

                    int byte_num = (x >> 3) & 3;     // 0,1,2,3
                    int bits_set = (y >> 1) & 1;     // 0,1            (lower/upper 4 bits)

                    byte uPen = (byte)(Swizzled[page_location + block_location + column_location + byte_num] >> ((index & 1) * 4) & 0xF);
                    Buf[Where + (index >> 1)] = (byte)((Buf[Where + (index >> 1)] & -bits_set) | (uPen << (bits_set * 4)));
                }
            }
        }


Here's the SVR of that file, if it helps at all (CLUT starts at 0x20 and is ARGB8888, image data at 0x60):
http://www.puyonexus.net/files/misc/accord_dress.svr

Author:  brienj [ Thu Mar 21, 2013 4:36 am ]
Post subject:  Re: PS2 texture unswizzling (4-bit textures)

I'm in the same exact boat, and every bit of source code I've found doesn't work, although the source code from Puyo Tools and Sparky's Swizzle Code (they are the same thing and not sure who is the original publisher of the code) has been the closest one so far.

Author:  ameneko [ Mon Nov 11, 2013 6:05 am ]
Post subject:  Re: PS2 texture unswizzling (4-bit textures)

Check this. It's sort of a mess but it for sure works. It's based on Puyo Tools. https://github.com/neko68k/rtftool/blob ... p6t_v2.cpp

Author:  CarLuver69 [ Tue Nov 07, 2017 9:28 am ]
Post subject:  Re: PS2 texture unswizzling (4-bit textures)

After 8 years of this originally being posted, I can finally provide a concrete answer to 4-bit PS2 texture unswizzling. I wrote it in C# and is based on Delphi code originally by Dageron. Full credit goes to him for being smart enough to know how this stuff works!

A permanent link to the code can be found here. If you use this in an open-source project, a link back to the gist would be appreciated. But do make sure you give full credit to Dageron, as he's the one who made this possible in the first place!

Happy unswizzling!

Author:  Sir Kane [ Mon Nov 13, 2017 12:11 am ]
Post subject:  Re: PS2 texture unswizzling (4-bit textures)

The
Quote:
//if ((mw % 32) > 0)
// mw = ((mw / 32) * 32) + 32;

part is for alignment to multiples of 32.

Though the typical implementation would be:
Code:
(value + align-1)/align*align

instead of having the remainder check.

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/