public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);
            if (magic != 0x434F4E44 && // COND
                magic.Swap() != 0x434F4E44)
            {
                throw new FormatException();
            }
            var endian = magic == 0x434F4E44 ? Endian.Little : Endian.Big;

            var version = input.ReadValueU32(endian);
            if (version != 1)
            {
                throw new FormatException();
            }
            this.Version = version;

            var unknown08 = input.ReadValueU16(endian);
            var count = input.ReadValueU16(endian);

            var ids = new int[count];
            var offsets = new uint[count];
            for (ushort i = 0; i < count; i++)
            {
                ids[i] = input.ReadValueS32(endian);
                offsets[i] = input.ReadValueU32(endian);
            }

            for (ushort i = 0; i < count; i++)
            {
                var id = ids[i];
                var offset = offsets[i];

                input.Seek(offset, SeekOrigin.Begin);

                var flags = input.ReadValueU8();

                var valueType = (Conditionals.ValueType)((flags & 0x0F) >> 0);
                var opType = (Conditionals.OpType)((flags & 0xF0) >> 4);

                if (valueType == Conditionals.ValueType.Bool)
                {
                    switch (opType)
                    {
                        default:
                        {
                            throw new NotSupportedException();
                        }
                    }
                }
            }

            //throw new NotImplementedException();

            this.Endian = endian;
        }
Example #2
0
        public static object Deserialize(Stream input, FieldType type, bool littleEndian)
        {
            switch (type)
            {
                case FieldType.UInt8: return input.ReadValueU8();
                case FieldType.Int8: return input.ReadValueS8();
                case FieldType.UInt16: return input.ReadValueU16(littleEndian);
                case FieldType.Int16: return input.ReadValueS16(littleEndian);
                case FieldType.UInt32: return input.ReadValueU32(littleEndian);
                case FieldType.Int32: return input.ReadValueS32(littleEndian);
                case FieldType.UInt64: return input.ReadValueU64(littleEndian);
                case FieldType.Int64: return input.ReadValueS64(littleEndian);
                case FieldType.Single: return input.ReadValueF32(littleEndian);
                case FieldType.Double: return input.ReadValueF64(littleEndian);
                case FieldType.Vector3:
                {
                    var value = new Builtins.Vector3();
                    value.Deserialize(input, littleEndian);
                    return value;
                }
                case FieldType.Vector4:
                {
                    var value = new Builtins.Vector4();
                    value.Deserialize(input, littleEndian);
                    return value;
                }
                case FieldType.Quaternion:
                {
                    var value = new Builtins.Quaternion();
                    value.Deserialize(input, littleEndian);
                    return value;
                }
                case FieldType.String:
                {
                    throw new NotSupportedException("cannot deserialize strings via Builtin");
                }
                case FieldType.Color:
                {
                    var value = new Builtins.Color();
                    value.Deserialize(input, littleEndian);
                    return value;
                }
                case FieldType.Matrix4x4:
                {
                    var value = new Builtins.Matrix4x4();
                    value.Deserialize(input, littleEndian);
                    return value;
                }
            }

            throw new NotSupportedException("unsupported builtin type");
        }
Example #3
0
        public void Deserialize(Stream input, Endian endianness)
        {
            this.DataSize = input.ReadValueU32(endianness);

            var type = input.ReadValueU8();
            if (ValidSectionTypes.ContainsKey(type) == false)
            {
                throw new FormatException("unknown section type");
            }
            this.Type = (SectionType)type;

            this.Unknown05 = input.ReadValueU8();
            this.Unknown06 = input.ReadValueU16(endianness);
            this.Flags = input.ReadValueU32(endianness);
            this.Id = input.ReadValueU32(endianness);
            this.Unknown10 = input.ReadValueU32(endianness);
        }
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);
            if (magic != 0x53464152 && // SFAR
                magic.Swap() != 0x53464152)
            {
                throw new FormatException();
            }
            var endian = magic == 0x53464152 ? Endian.Little : Endian.Big;

            var version = input.ReadValueU32(endian);
            if (version != 0x00010000)
            {
                throw new FormatException();
            }

            var dataOffset = input.ReadValueU32(endian);
            var fileTableOffset = input.ReadValueU32(endian);
            var fileTableCount = input.ReadValueU32(endian);
            var blockSizeTableOffset = input.ReadValueU32(endian);
            this.MaximumBlockSize = input.ReadValueU32(endian);
            this.CompressionScheme = input
                .ReadValueEnum<SFXArchive.CompressionScheme>(endian);

            if (fileTableOffset != 0x20)
            {
                throw new FormatException();
            }

            if (this.MaximumBlockSize != 0x010000)
            {
                throw new FormatException();
            }

            /*
            if (this.CompressionScheme != SFXArchive.CompressionScheme.None &&
                this.CompressionScheme != SFXArchive.CompressionScheme.LZMA &&
                this.CompressionScheme != SFXArchive.CompressionScheme.LZX)
            {
                throw new FormatException();
            }
            */

            input.Seek(blockSizeTableOffset, SeekOrigin.Begin);

            var blockSizeTableSize = dataOffset - fileTableOffset;
            var blockSizeTableCount = blockSizeTableSize / 2;
            this.BlockSizes.Clear();
            for (uint i = 0; i < blockSizeTableCount; i++)
            {
                this.BlockSizes.Add(input.ReadValueU16(endian));
            }

            input.Seek(fileTableOffset, SeekOrigin.Begin);
            for (uint i = 0; i < fileTableCount; i++)
            {
// ReSharper disable UseObjectOrCollectionInitializer
                var entry = new SFXArchive.Entry();
// ReSharper restore UseObjectOrCollectionInitializer
                entry.NameHash = input.ReadFileNameHash();
                entry.BlockSizeIndex = input.ReadValueS32(endian);
                entry.UncompressedSize = input.ReadValueU32(endian);
                entry.UncompressedSize |= ((long)input.ReadValueU8()) << 32;
                entry.Offset = input.ReadValueU32(endian);
                entry.Offset |= ((long)input.ReadValueU8()) << 32;
                this.Entries.Add(entry);
            }
        }
Example #5
0
        private void ReadBytecode(Stream input, FunctionDefinition funcDef)
        {
            funcDef.Instructions = new List<IInstruction>();
            funcDef.InstructionOffsets = new List<int>();
            var unencodedByteCodeLength = input.ReadValueEncodedS32();
            int read;
            for (read = 0; read < unencodedByteCodeLength;)
            {
                funcDef.InstructionOffsets.Add(read);
                var op = input.ReadValueU8();
                var opcode = (Script.Opcode) op;
                
                read++;
                Script.IInstruction instruction = null;

                switch (opcode)
                {
                    case Script.Opcode.OP_Target:
                        {
                            instruction = new Target();
                            break;
                        }

                    case Script.Opcode.OP_ShortConst:
                        {
                            instruction = new ShortConst();
                            break;
                        }

                    case Script.Opcode.OP_IntConst:
                        {
                            instruction = new IntConst();
                            break;
                        }

                    case Script.Opcode.OP_FloatConst:
                        {
                            instruction = new FloatConst();
                            break;
                        }

                    case Script.Opcode.OP_StringConst:
                        {
                            instruction = new StringConst(this);
                            break;
                        }

                    case Script.Opcode.OP_VirtualFunc:
                        {
                            instruction = new VirtualFunc(this);
                            break;
                        }

                    case Script.Opcode.OP_Context:
                    case Script.Opcode.OP_SwitchLabel:
                        {
                            instruction = new U16U16(opcode);
                            break;
                        }

                    case Script.Opcode.OP_Assign:
                    case Script.Opcode.OP_JumpIfFalse:
                    case Script.Opcode.OP_Jump:
                    case Script.Opcode.OP_Skip:
                        {
                            instruction = new U16(opcode);
                            break;
                        }

                    case Script.Opcode.OP_LocalVar:
                    case Script.Opcode.OP_ObjectVar:
                    case Script.Opcode.OP_ParamVar:
                    case Script.Opcode.OP_StructMember:
                        {
                            instruction = new TypeMember(opcode, this);
                            break;
                        }

                    case Script.Opcode.OP_Switch:
                        {
                            instruction = new Switch();
                            break;
                        }

                    case Script.Opcode.OP_Constructor:
                        {
                            instruction = new Constructor(this);
                            break;
                        }

                    case Script.Opcode.OP_TestEqual:
                    case Script.Opcode.OP_EnumToInt:
                    case Script.Opcode.OP_ArrayPushBack:
                    case Script.Opcode.OP_ArraySize:
                    case Script.Opcode.OP_ArrayElement:
                    case Script.Opcode.OP_New:
                    case Script.Opcode.OP_ArrayClear:
                    case Script.Opcode.OP_DynamicCast:
                    case Script.Opcode.OP_ArrayContainsFast:
                    case Script.Opcode.OP_ArrayRemoveFast:
                    case Script.Opcode.OP_TestNotEqual:
                    case Script.Opcode.OP_ArrayErase:
                    case Script.Opcode.OP_EnumToString:
                    case Script.Opcode.OP_ArrayContains:
                    case Script.Opcode.OP_ArrayResize:
                    case Script.Opcode.OP_ArrayInsert:
                    case Script.Opcode.OP_ArrayGrow:
                    case Script.Opcode.OP_ArrayFindFirstFast:
                    case Script.Opcode.OP_ArrayLast:
                    case Script.Opcode.OP_ArrayRemove:
                    case Script.Opcode.OP_SaveValue:
                        {
                            instruction = new TypeRef(opcode, this);
                            break;
                        }

                    case Script.Opcode.OP_NameConst:
                        {
                            instruction = new NameConst(Strings);
                            break;
                        }

                    case Script.Opcode.OP_FinalFunc:
                        {
                            instruction = new FinalFunc(this);
                            break;
                        }

                    case Script.Opcode.OP_EntryFunc:
                    case Script.Opcode.OP_SavePoint:
                        {
                            instruction = new U16S32(opcode, this);
                            break;
                        }

                    case Script.Opcode.OP_Nop:
                    case Script.Opcode.OP_ParamEnd:
                    case Script.Opcode.OP_IntZero:
                    case Script.Opcode.OP_IntOne:
                    case Script.Opcode.OP_BoolFalse:
                    case Script.Opcode.OP_BoolTrue:
                    case Script.Opcode.OP_Return:
                    case Script.Opcode.OP_GetServer:
                    case Script.Opcode.OP_GetCamera:
                    case Script.Opcode.OP_NameToString:
                    case Script.Opcode.OP_GetPlayer:
                    case Script.Opcode.OP_IntToFloat:
                    case Script.Opcode.OP_This:
                    case Script.Opcode.OP_Null:
                    case Script.Opcode.OP_GetGame:
                    case Script.Opcode.OP_ObjectToBool:
                    case Script.Opcode.OP_IntToString:
                    case Script.Opcode.OP_FloatToString:
                    case Script.Opcode.OP_IntToByte:
                    case Script.Opcode.OP_ObjectToString:
                    case Script.Opcode.OP_SwitchDefault:
                    case Script.Opcode.OP_BoolToString:
                    case Script.Opcode.OP_GetHud:
                    case Script.Opcode.OP_FloatToInt:
                    case Script.Opcode.OP_NameToBool:
                    case Script.Opcode.OP_Parent:
                    case Script.Opcode.OP_IntToBool:
                    case Script.Opcode.OP_ByteToInt:
                    case Script.Opcode.OP_FloatToBool:
                    case Script.Opcode.OP_ByteToFloat:
                    case Script.Opcode.OP_StringToBool:
                    case Script.Opcode.OP_SavePointEnd:
                    case Script.Opcode.OP_StringToInt:
                    case Script.Opcode.OP_GetSound:
                        {
                            instruction = new Simple(opcode);
                            break;
                        }

                    default:
                        {
                            throw new NotImplementedException("unhandled " + opcode.ToString());
                        }
                }
                read += instruction.Deserialize(input);
                funcDef.Instructions.Add(instruction);
            }

            if (read != unencodedByteCodeLength)
            {
                throw new InvalidOperationException();
            }
        }
Example #6
0
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);
            if (magic != 0x53464152 && // SFAR
                magic.Swap() != 0x53464152)
            {
                throw new FormatException();
            }
            var endian = magic == 0x53464152 ? Endian.Little : Endian.Big;

            var version = input.ReadValueU32(endian);
            if (version != 0x00010000)
            {
                throw new FormatException();
            }

            var dataOffset = input.ReadValueU32(endian);
            bool firstDataOffset = true;
            uint minDataOffset = dataOffset;
            //Console.WriteLine("Data Offset: {0:X8}",dataOffset);
            var fileTableOffset = input.ReadValueU32(endian);
            //Console.WriteLine("File Table Offset: {0:X8}",fileTableOffset);
            var fileTableCount = input.ReadValueU32(endian);
            //Console.WriteLine("File Table Count: {0:X8}",fileTableCount);
            var blockSizeTableOffset = input.ReadValueU32(endian);
            //Console.WriteLine("Block Size Table Offset: {0:X8}",blockSizeTableOffset);
            this.MaximumBlockSize = input.ReadValueU32(endian);
            this.CompressionScheme = input
                .ReadValueEnum<SFXArchive.CompressionScheme>(endian);

            if (fileTableOffset != 0x20)
            {
                throw new FormatException();
            }

            if (this.MaximumBlockSize != 0x010000)
            {
                throw new FormatException();
            }

            /*
            if (this.CompressionScheme != SFXArchive.CompressionScheme.None &&
                this.CompressionScheme != SFXArchive.CompressionScheme.LZMA &&
                this.CompressionScheme != SFXArchive.CompressionScheme.LZX)
            {
                throw new FormatException();
            }
            */
            input.Seek(fileTableOffset, SeekOrigin.Begin);
            for (uint i = 0; i < fileTableCount; i++)
            {
            // ReSharper disable UseObjectOrCollectionInitializer
                var entry = new SFXArchive.Entry();
                entry.entryOffset = input.Position;
            // ReSharper restore UseObjectOrCollectionInitializer
                entry.nameHash = input.ReadFileNameHash();
                //Console.WriteLine("FileNameHash: {0}",entry.NameHash.ToString());
                entry.blockSizeIndex = input.ReadValueS32(endian);
                //Console.WriteLine("Begin position: {0:X8}",input.Position);
                entry.uncompressedSize = input.ReadValueU32(endian);
                entry.uncompressedSize |= ((long)input.ReadValueU8()) << 32;
                //Console.WriteLine("  End position: {0:X8}",input.Position);
                entry.dataOffset = input.ReadValueU32(endian);
                entry.dataOffset |= ((long)input.ReadValueU8()) << 32;
                if(firstDataOffset)
                {
                    minDataOffset = (uint)entry.dataOffset;
                    firstDataOffset = false;
                }
                else
                {
                    if(minDataOffset > entry.dataOffset)
                        minDataOffset = (uint)entry.dataOffset;
                }
                //if(entry.NameHash.Equals (fileNameListNameHash))Console.WriteLine("Offset: {0:X10}, UncSize {1:X10}",entry.Offset,entry.UncompressedSize);
                this.Entries.Add(entry);
            }
            if(minDataOffset > dataOffset)
                dataOffset = minDataOffset;

            input.Seek(blockSizeTableOffset, SeekOrigin.Begin);

            var blockSizeTableSize = dataOffset - blockSizeTableOffset;
            var blockSizeTableCount = blockSizeTableSize / 2;
            //ushort aux;
            //Console.WriteLine("dataOffset: {0:X8}\nfileTableOffset: {1:X8}\nBlockSizeTableSize: {2:X8}\nblockSizeTableOffset: {3:X8}", dataOffset,fileTableOffset,blockSizeTableSize,blockSizeTableOffset);
            this.BlockSizes.Clear();
            //Console.WriteLine("initial position: {0:X8}",input.Position);
            //Console.WriteLine("blockSizeTableCount: {0}",blockSizeTableCount);
            for (uint i = 0; i < blockSizeTableCount; i++)
            {
                this.BlockSizes.Add(input.ReadValueU16(endian));
            }
            //Console.WriteLine("final position: {0:X8}",input.Position);
            //Console.WriteLine("number of repetitions: {0}",blockSizeTableCount);
            //var fileNameListNameHash = new FileNameHash(
            //        new byte[] { 0xB5, 0x50, 0x19, 0xCB, 0xF9, 0xD3, 0xDA, 0x65, 0xD5, 0x5B, 0x32, 0x1C, 0x00, 0x19, 0x69, 0x7C, });
        }
        public void Deserialize(Stream input)
        {
            this.Instructions.Clear();

            var basePosition = input.Position;

            if (input.ReadString(8, Encoding.ASCII) != "NCS V1.0")
            {
                throw new FormatException();
            }
            else if (input.ReadValueU8() != 0x42)
            {
                throw new FormatException();
            }

            var size = input.ReadValueU32(false);
            if (basePosition + size > input.Length)
            {
                throw new InvalidOperationException();
            }

            var code = new byte[size - 13];
            if (input.Read(code, 0, code.Length) != code.Length)
            {
                throw new FormatException();
            }

            var count = CountInstructions(code);

            var offsets = new int[count];
            int offset;

            offset = 0;
            for (int i = 0; offset >= 0 && offset < code.Length; i++)
            {
                offsets[i] = offset;
                offset += GetInstructionSize(code, offset);
            }

            if (offset != code.Length)
            {
                throw new InvalidOperationException();
            }

            var state = new State(offsets);

            offset = 0;
            var instructions = new List<Script.IInstruction>();
            for (int i = 0; offset >= 0 && offset < code.Length; i++)
            {
                if (code[offset + 0] > 58)
                {
                    throw new InvalidOperationException("invalid opcode");
                }

                var op = (Script.Opcode)code[offset + 0];
                var type = (Script.OperandType)code[offset + 1];

                var instruction = Script.OpcodeHandlerCache
                    .CreateInstruction(op);
                instruction.Decode(code, ref offset, type, state);
                instructions.Add(instruction);
            }

            this.Instructions.AddRange(instructions);
        }
Example #8
0
        public void Deserialize(Stream input)
        {
            if (input.ReadValueU32() != 0x39444350)
            {
                throw new FormatException();
            }

            this.Format = input.ReadValueEnum<PCD9.Format>();
            var dataSize = input.ReadValueU32();
            this.Unknown0C = input.ReadValueU32();
            this.Width = input.ReadValueU16();
            this.Height = input.ReadValueU16();
            this.BPP = input.ReadValueU8();
            var mipMapCount = 1 + input.ReadValueU8();
            this.Unknown16 = input.ReadValueU16();
            if ((this.Unknown16 & 0x8000) != 0)
            {
                throw new NotSupportedException();
                this.unknownFlag = true;
            }

            this.Mipmaps.Clear();
            using (var data = input.ReadToMemoryStream(dataSize))
            {
                var mipWidth = this.Width;
                var mipHeight = this.Height;

                for (int i = 0; i < mipMapCount; i++)
                {
                    if (mipWidth == 0)
                    {
                        mipWidth = 1;
                    }

                    if (mipHeight == 0)
                    {
                        mipHeight = 1;
                    }

                    int size;
                    switch (this.Format)
                    {
                        case PCD9.Format.A8R8G8B8:
                        {
                            size = mipWidth * mipHeight * 4;
                            break;
                        }

                        case PCD9.Format.DXT1:
                        case PCD9.Format.DXT3:
                        case PCD9.Format.DXT5:
                        {
                            int blockCount = ((mipWidth + 3) / 4) * ((mipHeight + 3) / 4);
                            int blockSize = this.Format == PCD9.Format.DXT1 ? 8 : 16;
                            size = blockCount * blockSize;
                            break;
                        }

                        default:
                        {
                            throw new NotSupportedException();
                        }
                    }

                    var buffer = new byte[size];
                    if (data.Read(buffer, 0, buffer.Length) != buffer.Length)
                    {
                        throw new EndOfStreamException();
                    }

                    this.Mipmaps.Add(new PCD9.Mipmap()
                        {
                            Width = mipWidth,
                            Height = mipHeight,
                            Data = buffer,
                        });

                    mipWidth >>= 1;
                    mipHeight >>= 1;
                }

                if (data.Position != data.Length)
                {
                    throw new InvalidOperationException();
                }
            }
        }