Beispiel #1
0
            internal void Write(BinaryWriterEx bw, PARAMDEF def, int index)
            {
                if (def.Unicode)
                {
                    bw.WriteFixStrW(DisplayName, 0x40, (byte)(def.Version >= 104 ? 0x00 : 0x20));
                }
                else
                {
                    bw.WriteFixStr(DisplayName, 0x40, (byte)(def.Version >= 104 ? 0x00 : 0x20));
                }

                byte padding = (byte)(def.Version >= 201 ? 0x00 : 0x20);

                bw.WriteFixStr(DisplayType.ToString(), 8, padding);
                bw.WriteFixStr(DisplayFormat, 8, padding);
                bw.WriteSingle(Default);
                bw.WriteSingle(Minimum);
                bw.WriteSingle(Maximum);
                bw.WriteSingle(Increment);
                bw.WriteInt32((int)EditFlags);
                bw.WriteInt32(ParamUtil.GetValueSize(DisplayType) * (ParamUtil.IsArrayType(DisplayType) ? ArrayLength : 1));

                if (def.Version >= 201)
                {
                    bw.ReserveInt64($"DescriptionOffset{index}");
                }
                else
                {
                    bw.ReserveInt32($"DescriptionOffset{index}");
                }

                bw.WriteFixStr(InternalType, 0x20, padding);

                if (def.Version >= 102)
                {
                    string internalName = InternalName;
                    // This is accurate except for "hasTarget : 1" in SpEffect
                    if (BitSize != -1)
                    {
                        internalName = $"{internalName}:{BitSize}";
                    }
                    // BB is not consistent about including [1] or not, but PTDE always does
                    else if (ParamUtil.IsArrayType(DisplayType))
                    {
                        internalName = $"{internalName}[{ArrayLength}]";
                    }
                    bw.WriteFixStr(internalName, 0x20, padding);
                }

                if (def.Version >= 104)
                {
                    bw.WriteInt32(SortID);
                }

                if (def.Version >= 201)
                {
                    bw.WritePattern(0x1C, 0x00);
                }
            }
Beispiel #2
0
        /// <summary>
        /// Calculates the size of cell data for each row.
        /// </summary>
        public int GetRowSize()
        {
            int size = 0;

            for (int i = 0; i < Fields.Count; i++)
            {
                Field   field = Fields[i];
                DefType type  = field.DisplayType;
                if (ParamUtil.IsArrayType(type))
                {
                    size += ParamUtil.GetValueSize(type) * field.ArrayLength;
                }
                else
                {
                    size += ParamUtil.GetValueSize(type);
                }

                if (ParamUtil.IsBitType(type) && field.BitSize != -1)
                {
                    int     bitOffset = field.BitSize;
                    DefType bitType   = type == DefType.dummy8 ? DefType.u8 : type;
                    int     bitLimit  = ParamUtil.GetBitLimit(bitType);

                    for (; i < Fields.Count - 1; i++)
                    {
                        Field   nextField = Fields[i + 1];
                        DefType nextType  = nextField.DisplayType;
                        if (!ParamUtil.IsBitType(nextType) || nextField.BitSize == -1 || bitOffset + nextField.BitSize > bitLimit ||
                            (nextType == DefType.dummy8 ? DefType.u8 : nextType) != bitType)
                        {
                            break;
                        }
                        bitOffset += nextField.BitSize;
                    }
                }
            }
            return(size);
        }
Beispiel #3
0
            internal Field(BinaryReaderEx br, PARAMDEF def)
            {
                Parent = def;
                if (def.Unicode)
                {
                    DisplayName = br.ReadFixStrW(0x40);
                }
                else
                {
                    DisplayName = br.ReadFixStr(0x40);
                }

                DisplayType   = (DefType)Enum.Parse(typeof(DefType), br.ReadFixStr(8));
                DisplayFormat = br.ReadFixStr(8);
                Default       = br.ReadSingle();
                Minimum       = br.ReadSingle();
                Maximum       = br.ReadSingle();
                Increment     = br.ReadSingle();
                EditFlags     = (EditFlags)br.ReadInt32();

                int byteCount = br.ReadInt32();

                if (!ParamUtil.IsArrayType(DisplayType) && byteCount != ParamUtil.GetValueSize(DisplayType) ||
                    ParamUtil.IsArrayType(DisplayType) && byteCount % ParamUtil.GetValueSize(DisplayType) != 0)
                {
                    throw new InvalidDataException($"Unexpected byte count {byteCount} for type {DisplayType}.");
                }
                ArrayLength = byteCount / ParamUtil.GetValueSize(DisplayType);

                long descriptionOffset;

                if (def.Version >= 201)
                {
                    descriptionOffset = br.ReadInt64();
                }
                else
                {
                    descriptionOffset = br.ReadInt32();
                }

                InternalType = br.ReadFixStr(0x20);

                BitSize = -1;
                if (def.Version >= 102)
                {
                    // A few fields in DS1 FaceGenParam have a trailing space in the name
                    InternalName = br.ReadFixStr(0x20).Trim();

                    Match match = bitSizeRx.Match(InternalName);
                    if (match.Success)
                    {
                        InternalName = match.Groups["name"].Value;
                        BitSize      = int.Parse(match.Groups["size"].Value);
                    }

                    if (ParamUtil.IsArrayType(DisplayType))
                    {
                        match = arrayLengthRx.Match(InternalName);
                        int length = match.Success ? int.Parse(match.Groups["length"].Value) : 1;
                        if (length != ArrayLength)
                        {
                            throw new InvalidDataException($"Mismatched array length in {InternalName} with byte count {byteCount}.");
                        }
                        if (match.Success)
                        {
                            InternalName = match.Groups["name"].Value;
                        }
                    }
                }

                if (def.Version >= 104)
                {
                    SortID = br.ReadInt32();
                }

                if (def.Version >= 201)
                {
                    br.AssertPattern(0x1C, 0x00);
                }

                if (descriptionOffset != 0)
                {
                    if (def.Unicode)
                    {
                        Description = br.GetUTF16(descriptionOffset);
                    }
                    else
                    {
                        Description = br.GetShiftJIS(descriptionOffset);
                    }
                }
            }
Beispiel #4
0
            internal void Write(BinaryWriterEx bw, PARAMDEF def, int index)
            {
                if (def.FormatVersion >= 202)
                {
                    bw.ReserveInt64($"DisplayNameOffset{index}");
                }
                else if (def.Unicode)
                {
                    bw.WriteFixStrW(DisplayName, 0x40, (byte)(def.FormatVersion >= 104 ? 0x00 : 0x20));
                }
                else
                {
                    bw.WriteFixStr(DisplayName, 0x40, (byte)(def.FormatVersion >= 104 ? 0x00 : 0x20));
                }

                byte padding = (byte)(def.FormatVersion >= 200 ? 0x00 : 0x20);

                bw.WriteFixStr(DisplayType.ToString(), 8, padding);
                bw.WriteFixStr(DisplayFormat, 8, padding);
                bw.WriteSingle(Default);
                bw.WriteSingle(Minimum);
                bw.WriteSingle(Maximum);
                bw.WriteSingle(Increment);
                bw.WriteInt32((int)EditFlags);
                bw.WriteInt32(ParamUtil.GetValueSize(DisplayType) * (ParamUtil.IsArrayType(DisplayType) ? ArrayLength : 1));

                if (def.FormatVersion >= 200)
                {
                    bw.ReserveInt64($"DescriptionOffset{index}");
                }
                else
                {
                    bw.ReserveInt32($"DescriptionOffset{index}");
                }

                if (def.FormatVersion >= 202)
                {
                    bw.ReserveInt64($"InternalTypeOffset{index}");
                }
                else
                {
                    bw.WriteFixStr(InternalType, 0x20, padding);
                }

                if (def.FormatVersion >= 202)
                {
                    bw.ReserveInt64($"InternalNameOffset{index}");
                }
                else if (def.FormatVersion >= 102)
                {
                    bw.WriteFixStr(MakeInternalName(), 0x20, padding);
                }

                if (def.FormatVersion >= 104)
                {
                    bw.WriteInt32(SortID);
                }

                if (def.FormatVersion >= 200)
                {
                    bw.WriteInt32(0);
                    bw.ReserveInt64($"UnkB8Offset{index}");
                    bw.ReserveInt64($"UnkC0Offset{index}");
                    bw.ReserveInt64($"UnkC8Offset{index}");
                }
            }