Xbox 360 Bitmap Research

Modding tutorials for Halo 3.
Post Reply
pokecancer




Socialist Revivalist Construct Wave
Firestorm ONI

Posts: 226
Joined: Wed Mar 10, 2004 10:37 am

Xbox 360 Bitmap Research

Post 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();
        }
Last edited by pokecancer on Tue Jun 26, 2007 8:31 pm, edited 1 time in total.
User avatar
Anthony




Translator Connoisseur New Age ONI

Posts: 1001
Joined: Thu Jul 06, 2006 10:19 pm
Location: Whittier, CA
Contact:

Post by Anthony »

good idea poke :)
User avatar
Sgt.Peppers




Snitch! Connoisseur

Posts: 2277
Joined: Thu Jul 06, 2006 1:25 pm
Location: Texas

Post by Sgt.Peppers »

Nice, pokecancer, good to see ya working on this stuff. :)
User avatar
Tural




Conceptionist Acolyte Bloodhound Recreator
Socialist Connoisseur Droplet Scorched Earth
Grunge

Posts: 15628
Joined: Thu Jun 16, 2005 3:44 pm
Location: Lincoln, NE
Contact:

Post 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.
Last edited by Tural on Thu Jun 28, 2007 5:34 am, edited 2 times in total.
User avatar
Trulife8342




Orb Commentator Firestorm

Posts: 2403
Joined: Sat Sep 03, 2005 7:04 am
Location: Miami, FL -- Name: Mauro Garcia
Contact:

Post by Trulife8342 »

Thanks poke
User avatar
shade45




Translator Artisan Enthraller Logistician
Stylist Wave Firestorm New Age

Posts: 2270
Joined: Fri Apr 01, 2005 1:04 pm

Post by shade45 »

Awsome thanks poke :D
User avatar
plushiefire





Posts: 618
Joined: Thu Nov 23, 2006 12:10 pm
Location: Canada

Post by plushiefire »

how could i put this in entity?
Come check out Team 3volved.
Image
User avatar
Tural




Conceptionist Acolyte Bloodhound Recreator
Socialist Connoisseur Droplet Scorched Earth
Grunge

Posts: 15628
Joined: Thu Jun 16, 2005 3:44 pm
Location: Lincoln, NE
Contact:

Post by Tural »

Why would you want it in Entity?
User avatar
plushiefire





Posts: 618
Joined: Thu Nov 23, 2006 12:10 pm
Location: Canada

Post by plushiefire »

Tural wrote:Why would you want it in Entity?
halo2 has those bitmap types.
Come check out Team 3volved.
Image
User avatar
Prey




Connoisseur Snitch! Pyre Articulatist 500

Posts: 1026
Joined: Wed Dec 27, 2006 6:49 am
Location: UK
Contact:

Post by Prey »

Nice one poke.
plushiefire wrote:halo2 has those bitmap types.
So? Completely different swizzle.
Halo 2 Prophet - Skin with ease with the simple 3D point and click interface.
Halo 3 Research Thread - Contribute to the research into Halo 3.
User avatar
Tural




Conceptionist Acolyte Bloodhound Recreator
Socialist Connoisseur Droplet Scorched Earth
Grunge

Posts: 15628
Joined: Thu Jun 16, 2005 3:44 pm
Location: Lincoln, NE
Contact:

Post by Tural »

Prey wrote:
plushiefire wrote:halo2 has those bitmap types.
So? Completely different swizzle.
Plus, Entity already extracts them properly.
User avatar
plushiefire





Posts: 618
Joined: Thu Nov 23, 2006 12:10 pm
Location: Canada

Post 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?
Come check out Team 3volved.
Image
User avatar
Tural




Conceptionist Acolyte Bloodhound Recreator
Socialist Connoisseur Droplet Scorched Earth
Grunge

Posts: 15628
Joined: Thu Jun 16, 2005 3:44 pm
Location: Lincoln, NE
Contact:

Post 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.
User avatar
darvolt





Posts: 49
Joined: Tue Mar 29, 2005 11:31 am
Location: Munich
Contact:

Post 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)
Attachments
perfect design :lol:
perfect design :lol:
pic.PNG (5.44 KiB) Viewed 7100 times
32bit_raw_to_dds.rar
My app
(10.16 KiB) Downloaded 60 times
-DeToX-




Illusionist Recreator Connoisseur Acolyte
Sigma Decryptor Droplet Pyre
Blacksmith Socialist New Age System Engineer
ONI

Posts: 4589
Joined: Sun Jun 18, 2006 3:58 pm
Location: ...

Post by -DeToX- »

Thats what we don't know yet, next time please read before you bump.
Image
User avatar
darvolt





Posts: 49
Joined: Tue Mar 29, 2005 11:31 am
Location: Munich
Contact:

Post by darvolt »

I've read..

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




Conceptionist Acolyte Bloodhound Recreator
Socialist Connoisseur Droplet Scorched Earth
Grunge

Posts: 15628
Joined: Thu Jun 16, 2005 3:44 pm
Location: Lincoln, NE
Contact:

Post 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.
User avatar
turk645




Artisan Translator Pyre

Posts: 2887
Joined: Wed May 18, 2005 12:32 pm
Location: In my special pillow fort.
Contact:

Post by turk645 »

:P so is this just a 360 raw deswizzle? IF so the YAY i can extract dead rising photos.
Image
ScottyGee wrote:Smokers suck >_< (to avoid someone saying it later, both literally and in the derogatory way)
"Before you criticize someone, walk a mile in their shoes. That way after you make fun of them, you still have their shoes."-Dranciel ಠ_ಠ
Tanasoo




Literarian 250

Posts: 298
Joined: Sat Jan 01, 2005 7:15 pm

Post 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
Post Reply