예제 #1
0
            public Header(byte[] bytes)
            {
                magic = EndianBytesOperator.readString(bytes, 0, 4);
                if (magic != "PrOD")
                {
                    throw new InvalidDataException();
                }

                constNum1 = EndianBytesOperator.readUInt(bytes, 0x04);
                if (constNum1 != 0x01000000)
                {
                    throw new InvalidDataException();
                }

                constNum2 = EndianBytesOperator.readUInt(bytes, 0x08);
                if (constNum2 != 0x00000001)
                {
                    throw new InvalidDataException();
                }

                lstUSOffset = EndianBytesOperator.readUInt(bytes, 0x0C);
                fileSize    = EndianBytesOperator.readUInt(bytes, 0x10);
                meshCount   = EndianBytesOperator.readUInt(bytes, 0x14);
                STOffset    = EndianBytesOperator.readUInt(bytes, 0x18);

                NullPadding = EndianBytesOperator.readUInt(bytes, 0x1C);
                if (NullPadding != 0x00000000)
                {
                    throw new InvalidDataException();
                }
            }
예제 #2
0
        public byte[] getBytes()
        {
            if (m_bytes != null)
            {
                return(m_bytes);
            }
            m_bytes = new byte[m_header.fileSize];
            m_header.writeToBytes(m_bytes);

            uint offset = Header.size;

            foreach (var mesh in m_meshes)
            {
                mesh.writeToBytes(m_bytes, offset);
                offset += mesh.size;
            }

            offset = m_header.STOffset;
            EndianBytesOperator.writeUInt(m_bytes, (int)offset + 0x00, (uint)names.Count);
            EndianBytesOperator.writeUInt(m_bytes, (int)offset + 0x04, m_namesSize - 0x08);
            offset += 0x08;

            foreach (var str in names)
            {
                offset += (uint)EndianBytesOperator.writeString_PrOD(m_bytes, (int)offset, str);
            }

            return(m_bytes);
        }
예제 #3
0
 public void writeToBytes(byte[] bytes)
 {
     EndianBytesOperator.writeString(bytes, 0x0, magic, 4);
     EndianBytesOperator.writeUInt(bytes, 0x04, constNum1);
     EndianBytesOperator.writeUInt(bytes, 0x08, constNum2);
     EndianBytesOperator.writeUInt(bytes, 0x0C, lstUSOffset);
     EndianBytesOperator.writeUInt(bytes, 0x10, fileSize);
     EndianBytesOperator.writeUInt(bytes, 0x14, meshCount);
     EndianBytesOperator.writeUInt(bytes, 0x18, STOffset);
     EndianBytesOperator.writeUInt(bytes, 0x1C, NullPadding);
 }
예제 #4
0
                public MeshInstance(byte[] bytes, uint offset)
                {
                    position    = new float[3];
                    position[0] = EndianBytesOperator.readFloat(bytes, (int)offset + 0x0);
                    position[1] = EndianBytesOperator.readFloat(bytes, (int)offset + 0x04);
                    position[2] = EndianBytesOperator.readFloat(bytes, (int)offset + 0x08);

                    rotation    = new float[3];
                    rotation[0] = EndianBytesOperator.readFloat(bytes, (int)offset + 0x0C);
                    rotation[1] = EndianBytesOperator.readFloat(bytes, (int)offset + 0x10);
                    rotation[2] = EndianBytesOperator.readFloat(bytes, (int)offset + 0x14);

                    uniformScale = EndianBytesOperator.readFloat(bytes, (int)offset + 0x18);
                }
예제 #5
0
                public void writeToBytes(byte[] bytes, uint offset)
                {
                    EndianBytesOperator.writeFloat(bytes, (int)offset + 0x00, position[0]);
                    EndianBytesOperator.writeFloat(bytes, (int)offset + 0x04, position[1]);
                    EndianBytesOperator.writeFloat(bytes, (int)offset + 0x08, position[2]);

                    EndianBytesOperator.writeFloat(bytes, (int)offset + 0x0C, rotation[0]);
                    EndianBytesOperator.writeFloat(bytes, (int)offset + 0x10, rotation[1]);
                    EndianBytesOperator.writeFloat(bytes, (int)offset + 0x14, rotation[2]);

                    EndianBytesOperator.writeFloat(bytes, (int)offset + 0x18, uniformScale);

                    EndianBytesOperator.writeUInt(bytes, (int)offset + 0x1C, NullPadding);
                }
예제 #6
0
            public void writeToBytes(byte[] bytes, uint offset)
            {
                EndianBytesOperator.writeUInt(bytes, (int)offset + 0x00, instancesSize);
                EndianBytesOperator.writeUInt(bytes, (int)offset + 0x04, instancesCount);
                EndianBytesOperator.writeUInt(bytes, (int)offset + 0x08, nameOffset);
                EndianBytesOperator.writeUInt(bytes, (int)offset + 0x0C, NullPadding);

                uint t_offset = offset + 0x10;

                foreach (MeshInstance meshIns in instances)
                {
                    meshIns.writeToBytes(bytes, t_offset);
                    t_offset += MeshInstance.size;
                }
            }
예제 #7
0
            public Mesh(byte[] bytes, uint offset, List <string> names, uint stOffset)
            {
                instancesSize = EndianBytesOperator.readUInt(bytes, (int)offset + 0x0);
                size          = 0x10 + instancesSize;

                instancesCount = EndianBytesOperator.readUInt(bytes, (int)offset + 0x04);
                nameOffset     = EndianBytesOperator.readUInt(bytes, (int)offset + 0x08);
                name           = EndianBytesOperator.readString(bytes, (int)(stOffset + nameOffset));
                names.Add(name);

                instances = new List <MeshInstance>();
                for (int i = 0; i < instancesCount; i++)
                {
                    instances.Add(new MeshInstance(bytes, (uint)(offset + 0x10 + MeshInstance.size * i)));
                }
            }
예제 #8
0
 public static bool IsYaz0(byte[] bytes)
 {
     return(EndianBytesOperator.readString(bytes, 0, 4) == "Yaz0");
 }
예제 #9
0
        public static byte[] decode(byte[] src)
        {
            if (!IsYaz0(src))
            {
                return(src);
            }

            uint decompressedSize = EndianBytesOperator.readUInt(src, 0x04);

            byte[] dst    = new byte[decompressedSize];
            uint   srcPos = 0x10;
            uint   dstPos = 0;

            byte Opcode = 0x00;
            List <KeyValuePair <int, KeyValuePair <int, int> > > finds = new List <KeyValuePair <int, KeyValuePair <int, int> > >();

            while (true)
            {
                Opcode = src[srcPos];
                srcPos++;
                for (int i = 0; i < 8; i++, Opcode <<= 1)
                {
                    if ((Opcode & 0x80) != 0)
                    {
                        dst[dstPos] = src[srcPos];
                        dstPos++;
                        srcPos++;
                    }
                    else
                    {
                        byte b1 = src[srcPos];
                        byte b2 = src[srcPos + 1];
                        srcPos += 2;

                        uint copyLen = 0;
                        if ((b1 >> 4) == 0)
                        {
                            copyLen = (uint)src[srcPos] + 0x12;
                            srcPos++;
                        }
                        else
                        {
                            copyLen = (uint)(b1 >> 4) + 0x02;
                        }
                        uint dist    = (uint)((b1 & 0x0F) << 8 | b2) + 1;
                        uint copyPos = dstPos - dist;
                        finds.Add(new KeyValuePair <int, KeyValuePair <int, int> >((int)dstPos, new KeyValuePair <int, int>((int)copyPos, (int)copyLen)));
                        for (int j = 0; j < copyLen; j++)
                        {
                            dst[dstPos] = dst[copyPos];
                            dstPos++;
                            copyPos++;
                        }
                    }

                    if (dstPos >= decompressedSize)
                    {
                        return(dst);
                    }
                }
            }
        }
예제 #10
0
        public static byte[] encode(byte[] src)
        {
            //find need compressed position
            uint curPos = 0;
            uint endPos = (uint)src.Length;
            List <KeyValuePair <uint, KeyValuePair <uint, uint> > > finds = new List <KeyValuePair <uint, KeyValuePair <uint, uint> > >();

            while (curPos + 0x03 <= endPos)
            {
                var find = searchNextNCPoses(src, curPos, endPos);
                if (find[0].Value.Value != 0)
                {
                    finds.AddRange(find);
                }
                curPos = find[find.Count - 1].Key + find[find.Count - 1].Value.Value;
            }

            //compress
            byte[] temp      = new byte[src.Length + src.Length / 8];
            uint   writeLen  = 0;
            uint   srcPos    = 0;
            uint   dstPos    = 0x01;
            uint   opcodePos = 0;
            uint   cycle     = 0x00;

            foreach (var find in finds)
            {
                //write data that does not need to be compressed
                while (srcPos < find.Key)
                {
                    if (cycle == 8)
                    {
                        opcodePos = dstPos;
                        dstPos++;
                        cycle = 0x00;
                    }
                    temp[opcodePos] = (byte)(temp[opcodePos] | 0x80 >> (int)cycle);
                    cycle++;

                    temp[dstPos] = src[srcPos];
                    dstPos++;
                    srcPos++;
                }

                //write data that need to compressed
                if (cycle == 8)
                {
                    opcodePos = dstPos;
                    dstPos++;
                    cycle = 0x00;
                }
                cycle++;

                uint findLen = find.Value.Value;
                uint findPos = find.Value.Key;
                uint pos     = find.Key;
                uint dist    = pos - findPos - 1;
                if (findLen < 0x12)
                {
                    byte b1 = (byte)((findLen - 2) << 4 | dist >> 8);
                    byte b2 = (byte)(dist & 0xFF);

                    temp[dstPos]     = b1;
                    temp[dstPos + 1] = b2;
                    dstPos          += 2;
                }
                else
                {
                    byte b1 = (byte)(dist >> 8);
                    byte b2 = (byte)(dist & 0xFF);
                    byte b3 = (byte)(findLen - 0x12);

                    temp[dstPos]     = b1;
                    temp[dstPos + 1] = b2;
                    temp[dstPos + 2] = b3;
                    dstPos          += 3;
                }

                srcPos += findLen;
            }

            //write data that does not need to be compressed
            while (srcPos < src.Length)
            {
                if (cycle == 8)
                {
                    opcodePos = dstPos;
                    dstPos++;
                    cycle = 0x00;
                }
                temp[opcodePos] = (byte)(temp[opcodePos] | 0x80 >> (int)cycle);
                cycle++;

                temp[dstPos] = src[srcPos];
                dstPos++;
                srcPos++;
            }

            writeLen = dstPos;

            byte[] ret = new byte[writeLen + 0x10];
            EndianBytesOperator.writeString(ret, 0, "Yaz0", 4);
            EndianBytesOperator.writeUInt(ret, 0x04, (uint)src.Length);
            for (int i = 0; i < writeLen; i++)
            {
                ret[i + 0x10] = temp[i];
            }

            return(ret);
        }