Page 1 of 1

Xbox 360 Bitmap Research

Posted: Tue Jun 26, 2007 8:15 pm
by pokecancer
I figured I would release my deswizzle method for A8R8G8B8 so people can do more research on bitmaps. This applies to not only H3 but most game's resources for Xbox 360 and could probably be easily adjusted to deal with different argb formats by changing some of the math in my code. BTW this is using my own modified BinaryReader class so you will have to change that if you want to use this code. also keep in mind the data is in big endian format and need to 32 bit swapped in order to be in a format the pc can understand.

Code: Select all

  public static byte[] Deswizzle(byte[] raw, int width, int height)
        {
            MemoryStream ms = new MemoryStream();
            core.IO.EndianIO.EndianWriter ew = new core.IO.EndianIO.EndianWriter(ms, core.IO.EndianType.LittleEndian);
            ew.BaseStream.Position = 0;

            int realsize = width * height * 4;
            int lines = realsize / 16;

            int templine = 0;
            int rowcount = 0;
            int offsetby = 0;
            int i = 0;
            int sections = width / 32;
            for (int x = 0; x < lines; x++)
            {


                if (rowcount % 32 == 0 && rowcount != 0)
                {

                    templine = (i+1)*((width * 32) /4);

                    i++;

                }



                if (rowcount % 8 == 0 && rowcount != 0)
                {
                    if (offsetby == 0)
                    {
                        offsetby = 8 * 16;
                    }
                    else
                    {
                        offsetby = 0;
                    }
                }


                if (rowcount == height) break;

                ///get row 1 - 224 pixels(one row) = 7 * 32   
                for (int y = 0; y < sections; y++)
                {

                    //get 32 pixels
                    for (int z = 0; z < 8; z++)
                    {
                        if (z < 4)
                        {
                            int offset = (templine * 16) + ((y * 256) * 16) + ((z * 2) * 16) + offsetby;
                            int oi1 = BitConverter.ToInt32(raw, offset + 0);
                            int oi2 = BitConverter.ToInt32(raw, offset + 4);
                            int oi3 = BitConverter.ToInt32(raw, offset + 8);
                            int oi4 = BitConverter.ToInt32(raw, offset + 12);

                            ew.Write(oi1);
                            ew.Write(oi2);
                            ew.Write(oi3);
                            ew.Write(oi4);
                        }
                        else
                        {
                            int offset = (templine * 16) + ((y * 256) * 16) + ((z * 2) * 16) - offsetby;
                            int oi1 = BitConverter.ToInt32(raw, offset + 0);
                            int oi2 = BitConverter.ToInt32(raw, offset + 4);
                            int oi3 = BitConverter.ToInt32(raw, offset + 8);
                            int oi4 = BitConverter.ToInt32(raw, offset + 12);

                            ew.Write(oi1);
                            ew.Write(oi2);
                            ew.Write(oi3);
                            ew.Write(oi4);
                        }
                    }

                }
                rowcount++;

                if (rowcount == height) break;
                ///get row 2 
                for (int y = 0; y < sections; y++)
                {

                    //get 32 pixels
                    for (int z = 0; z < 8; z++)
                    {
                        if (offsetby != 0)
                        {
                        }
                        if (z < 4)
                        {
                            int offset = (templine * 16) + 16 + ((y * 256) * 16) + ((z * 2) * 16) + offsetby;
                            int oi1 = BitConverter.ToInt32(raw, offset + 0);
                            int oi2 = BitConverter.ToInt32(raw, offset + 4);
                            int oi3 = BitConverter.ToInt32(raw, offset + 8);
                            int oi4 = BitConverter.ToInt32(raw, offset + 12);
                            ew.Write(oi1);
                            ew.Write(oi2);
                            ew.Write(oi3);
                            ew.Write(oi4);
                        }
                        else
                        {
                            int offset = (templine * 16) + 16 + ((y * 256) * 16) + ((z * 2) * 16) - offsetby;
                            int oi1 = BitConverter.ToInt32(raw, offset + 0);
                            int oi2 = BitConverter.ToInt32(raw, offset + 4);
                            int oi3 = BitConverter.ToInt32(raw, offset + 8);
                            int oi4 = BitConverter.ToInt32(raw, offset + 12);
                            ew.Write(oi1);
                            ew.Write(oi2);
                            ew.Write(oi3);
                            ew.Write(oi4);
                        }
                    }

                }
                rowcount++;
                templine += 16;
            }
            return ms.ToArray();
        }

Posted: Tue Jun 26, 2007 8:28 pm
by Anthony
good idea poke :)

Posted: Tue Jun 26, 2007 8:30 pm
by Sgt.Peppers
Nice, pokecancer, good to see ya working on this stuff. :)

Posted: Tue Jun 26, 2007 8:59 pm
by Tural
Win.

Well, I've decided I suck and can't use this. I'll let someone else put this into a program.

Scratch that. I realized what I did wrong, now it works.

Posted: Tue Jun 26, 2007 9:05 pm
by Trulife8342
Thanks poke

Posted: Fri Jun 29, 2007 12:24 am
by shade45
Awsome thanks poke :D

Posted: Sun Jul 01, 2007 5:23 am
by plushiefire
how could i put this in entity?

Posted: Sun Jul 01, 2007 5:26 am
by Tural
Why would you want it in Entity?

Posted: Sun Jul 01, 2007 5:56 am
by plushiefire
Tural wrote:Why would you want it in Entity?
halo2 has those bitmap types.

Posted: Sun Jul 01, 2007 6:15 am
by Prey
Nice one poke.
plushiefire wrote:halo2 has those bitmap types.
So? Completely different swizzle.

Posted: Sun Jul 01, 2007 6:23 am
by Tural
Prey wrote:
plushiefire wrote:halo2 has those bitmap types.
So? Completely different swizzle.
Plus, Entity already extracts them properly.

Posted: Sun Jul 01, 2007 7:05 am
by plushiefire
Tural wrote:
Prey wrote:
plushiefire wrote:halo2 has those bitmap types.
So? Completely different swizzle.
Plus, Entity already extracts them properly.
what version?

Posted: Sun Jul 01, 2007 7:09 am
by Tural
All? I don't know of any program that can't extract ARGB8.

The only bitmaps I even know of that are ARGB8s in Halo 2 are the UI bitmaps, and those can be extracted fine. Any others would work as well. I don't even know if they're swizzled, I don't think they are.

Anyways, even if you did need to unswizzle them, this would do you no good, as Prey said.

Posted: Fri Sep 07, 2007 2:56 am
by darvolt
Is there a way to deswizzle DXT 1, 2/3, 4/5 etc. Images?
.. there must be a way, cause you did it.

(sry. I'm a bit late)

Posted: Fri Sep 07, 2007 3:32 am
by -DeToX-
Thats what we don't know yet, next time please read before you bump.

Posted: Fri Sep 07, 2007 3:35 am
by darvolt
I've read..

But there must be a way if Poke, Anthony and MarioKart did it. (Masterchief, ATV...)

Posted: Fri Sep 07, 2007 5:54 am
by Tural
Look forward to more as Halo 3 comes out.

The way it was done originally was completely improper. The image was actually manipulated my moving pixels and such, rather than the core file itself. However, I know there are further methods of doing so now, but they are not public.

So yeah, wait for Halo 3, etc.

Posted: Tue Sep 25, 2007 4:00 am
by turk645
:P so is this just a 360 raw deswizzle? IF so the YAY i can extract dead rising photos.

Posted: Fri Sep 28, 2007 10:32 am
by Tanasoo
This isn't about deswizzling, but it is about 360 bitmaps.

I have done a bunch of research into one of the new formats the 360 uses for normal maps. Mostly because it is being used in Halo 3. I have been teaching myself C#, and in the process I have managed to put together a reader/ converter for sed bumpmaps and I will gladly post all I know and the app. There is one thing, however, and it has been eating my lunch off and on for a while now. The one thing that will allow me to read them perfectly.

The thing IS: much like 3DC compression, this one only stores two color components, and generates the blue channel on the fly. This is exactly my problem... I can't seem to do this. If anyone can help me with it and get it working with me, I will post all I know on about the compression method :D.

OK, that said, here is what I was trying to do to generate the Z component:

Code: Select all

double tempd;
double tempr = (((double)Color1R / 255) * 2) -1;
double tempg = (((double)Color1G / 255) * 2) -1;
tempd = System.Math.Sqrt(1 - ((tempr * tempr) - (tempg * tempg)));
Color1B = (int)(tempd * 255);
Bet that was trowing values greater than 255, so I modified it like this:

Code: Select all

double tempd;
double tempr = (((double)Color1R / 255) * 2) - 1;
double tempg = (((double)Color1G / 255) * 2) - 1;
tempd = ((tempr * tempr) - (tempg * tempg));
if (tempd < 0)
{
tempd = tempd * -1;
}
tempd = System.Math.Sqrt(1 - tempd);
Color1B = (int)(tempd * 255);
But now the blue chanel seems to be too intense. Is this correct, of am I still a little off?

Maybe some of you smart programmer brainspeople can figure out what is wrong :)

Edit: Fixed it =D