ROM Hack Maybe some kind of compression?

  • Thread starter Thread starter Smariter
  • Start date Start date
  • Views Views 3,220
  • Replies Replies 11

Smariter

Active Member
Newcomer
Joined
Dec 23, 2014
Messages
29
Reaction score
4
Trophies
0
Age
57
XP
131
Country
I found some files in game store with this format:
rq5AQvj.jpg

Their magic number always 0x18. The origin file is a CGFX. Anyone know what kind of compression is it?

There is an example
 
Last edited by Smariter,
As a quick test of this sort of thing do a light compression pass with a PC program (even a basic gzip). If it compresses again it is probably not compressed, or at least not compressed in the conventional/generic sense (you might still have tile reuse, dual tile encoding or something similar). If it is something really old like RLE on a SNES then it might be basic LZ as seen on Nintendo handhelds since the GBA does pretty well here. It does drop it a couple of kilobytes but

In this case though if you scroll down then there are some ASCII strings with things like DefaultShader, transform matrix and vertex lighting (all classic 3d and 3d texture related). Many of them have something random in the middle of them, and every 8 bytes, which is pretty indicative of a flag usually seen in LZ compression. I am not particularly familiar with the 3ds implementations of it though.
My only issue is the text even further down does not look like it is being compressed that well, though it might just be it lucked out and did not have any repeats within the window, or it might be an archive of sorts and only compresses on a file by file basis.
 

...The file he posted has literally nothing to do with NVIDIA's CgFX format.

The compressed CGFX in the file he posted is of http://3dbrew.org/wiki/CGFX format, not some proprietary NVIDIA format -- and, moreover, the link you posted has nothing to do with the compression you can clearly see in the OP's picture.

Please actually check that what you're saying is helpful before posting smarmy links.
 
It looks like lz11 or lz77 to me. There is probably a longer uncompressed header first, and then the lz11 or lz77 header and compressed data.
 
To me it looks like Capcom SLZ, it's a flag & buffer-window based compression and there are some different variants used throughout their games in PS2/PS3/PSP/Wii.

the normal header is:
1 byte = version
4 byte = compressed length
4 byte = uncompressed length
and you can clearly identify 0xFF as: 8 byte uncompressed data (flag 1 = uncompressed, flag 0 = compressed)

this header uses:
4 byte = header length
4 byte = ???
4 byte = compressed length (- header length)
4 byte = uncompressed length
8 byte = ???
and here it is 0x00 as 8 byte uncompressed data, so the flags are reversed (flag 0 = uncompressed, flag 1 = compressed)

I would need more files or a ram dump of that file to crack it, but it would help to know from which game it is.
 
Why don't you just say that it's "Azure Striker Gunvolt" ?
Well your ram dump is useless, it's just the exefs and not some decompressed IOBJ file.

Since i own this game, i made a ramdump myself and found file 1026 decompressed in it, here the decompress code in C#:

Code:
        public static void DecompressGunvolt(string infile, string outfile)
        {
            byte[] result = DecompressGunvolt(File.ReadAllBytes(infile));

            if (result != null)
                File.WriteAllBytes(outfile, result);
        }

        public static byte[] DecompressGunvolt(byte[] data)
        {
            byte[] result = null;
            int headersize, csize, usize;

            using (var ms = new MemoryStream(data))
            using (var br = new BinaryReader(ms))
            {
                headersize = br.ReadInt32();
                br.ReadInt32(); // some pointer, only used in runtime
                csize = br.ReadInt32();
                usize = br.ReadInt32();
                br.ReadInt32(); // some pointer, only used in runtime
                br.ReadInt32(); // 0

                csize -= headersize;

                result = Decompress_GunvoltSLZ(br.ReadBytes(csize), usize);
            }

            return result;
        }

        public static byte[] Decompress_GunvoltSLZ(byte[] compData, int uncompressedSize)
        {
            byte[] decompData = new byte[uncompressedSize];
            int inPtr = 0, outPtr = 0;
            ushort dist, count;
            byte flags = 0;

            try
            {
                do
                {
                    flags = compData[inPtr++];

                    for (int cbit = 1; (cbit & 0xFF) > 0; cbit <<= 1)
                    {
                        if ((flags & cbit) == 0) //if bit is not set, uncompressed!
                        {
                            decompData[outPtr++] = compData[inPtr++];
                            if (inPtr > compData.Length) break; //check if we reached the end of file
                        }
                        else //compressed
                        {
                            var dat = BitConverter.ToUInt16(compData, inPtr); inPtr += 2;

                            dist = (ushort)((dat & 0xFFF) + 1);
                            count = (ushort)((dat >> 12) + 2);

                            do
                            {
                                decompData[outPtr] = decompData[(outPtr - dist)];

                                outPtr++;
                                count--;
                            } while (count > 0);
                        }

                        if (inPtr >= compData.Length) break; //check if we reached the end of file
                    }

                } while (inPtr < compData.Length);
            }
            catch //(Exception ex)
            {
            }
            return decompData;
        }
 
Why don't you just say that it's "Azure Striker Gunvolt" ?
Well your ram dump is useless, it's just the exefs and not some decompressed IOBJ file.

Since i own this game, i made a ramdump myself and found file 1026 decompressed in it, here the decompress code in C#:

Code:
        public static void DecompressGunvolt(string infile, string outfile)
        {
            byte[] result = DecompressGunvolt(File.ReadAllBytes(infile));

            if (result != null)
                File.WriteAllBytes(outfile, result);
        }

        public static byte[] DecompressGunvolt(byte[] data)
        {
            byte[] result = null;
            int headersize, csize, usize;

            using (var ms = new MemoryStream(data))
            using (var br = new BinaryReader(ms))
            {
                headersize = br.ReadInt32();
                br.ReadInt32(); // some pointer, only used in runtime
                csize = br.ReadInt32();
                usize = br.ReadInt32();
                br.ReadInt32(); // some pointer, only used in runtime
                br.ReadInt32(); // 0

                csize -= headersize;

                result = Decompress_GunvoltSLZ(br.ReadBytes(csize), usize);
            }

            return result;
        }

        public static byte[] Decompress_GunvoltSLZ(byte[] compData, int uncompressedSize)
        {
            byte[] decompData = new byte[uncompressedSize];
            int inPtr = 0, outPtr = 0;
            ushort dist, count;
            byte flags = 0;

            try
            {
                do
                {
                    flags = compData[inPtr++];

                    for (int cbit = 1; (cbit & 0xFF) > 0; cbit <<= 1)
                    {
                        if ((flags & cbit) == 0) //if bit is not set, uncompressed!
                        {
                            decompData[outPtr++] = compData[inPtr++];
                            if (inPtr > compData.Length) break; //check if we reached the end of file
                        }
                        else //compressed
                        {
                            var dat = BitConverter.ToUInt16(compData, inPtr); inPtr += 2;

                            dist = (ushort)((dat & 0xFFF) + 1);
                            count = (ushort)((dat >> 12) + 2);

                            do
                            {
                                decompData[outPtr] = decompData[(outPtr - dist)];

                                outPtr++;
                                count--;
                            } while (count > 0);
                        }

                        if (inPtr >= compData.Length) break; //check if we reached the end of file
                    }

                } while (inPtr < compData.Length);
            }
            catch //(Exception ex)
            {
            }
            return decompData;
        }
Thank you! This really helpful. thank you very much! Do you have any idea about the IOBJ file?

edit:
I can't find text in any file, then I compare the US version with JPN version, it only show differences in this irarc, so I wonder if text layout in game are textures object
 
Last edited by Smariter,

Site & Scene News

Popular threads in this forum