ROM Hack Maybe some kind of compression?

Smariter

Active Member
OP
Newcomer
Joined
Dec 23, 2014
Messages
29
Trophies
0
Age
55
XP
111
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,

FAST6191

Techromancer
Editorial Team
Joined
Nov 21, 2005
Messages
36,798
Trophies
3
XP
28,321
Country
United Kingdom
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.
 

SciresM

Developer
Developer
Joined
Mar 21, 2014
Messages
973
Trophies
3
Age
33
XP
8,294
Country
United States

...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.
 

Gericom

Well-Known Member
Member
Joined
Jun 30, 2011
Messages
1,382
Trophies
2
Age
25
XP
4,690
Country
Netherlands
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.
 

Falo

Well-Known Member
Member
Joined
Jul 22, 2012
Messages
680
Trophies
2
XP
2,627
Country
Germany
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.
 

Falo

Well-Known Member
Member
Joined
Jul 22, 2012
Messages
680
Trophies
2
XP
2,627
Country
Germany
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;
        }
 

Smariter

Active Member
OP
Newcomer
Joined
Dec 23, 2014
Messages
29
Trophies
0
Age
55
XP
111
Country
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

General chit-chat
Help Users
    Veho @ Veho: Cool.