コード例 #1
0
            internal void ReadCells(BinaryReaderEx br, PARAMDEF paramdef)
            {
                // In case someone decides to add new rows before applying the paramdef (please don't do that)
                if (DataOffset == 0)
                {
                    return;
                }

                Def = paramdef;

                br.Position = DataOffset;
                var cells = new Cell[paramdef.Fields.Count];

                int bitOffset = -1;

                PARAMDEF.DefType bitType  = PARAMDEF.DefType.u8;
                uint             bitValue = 0;

                for (int i = 0; i < paramdef.Fields.Count; i++)
                {
                    PARAMDEF.Field   field = paramdef.Fields[i];
                    object           value = null;
                    PARAMDEF.DefType type  = field.DisplayType;

                    if (type == PARAMDEF.DefType.s8)
                    {
                        value = br.ReadSByte();
                    }
                    else if (type == PARAMDEF.DefType.s16)
                    {
                        value = br.ReadInt16();
                    }
                    else if (type == PARAMDEF.DefType.s32)
                    {
                        value = br.ReadInt32();
                    }
                    else if (type == PARAMDEF.DefType.f32)
                    {
                        value = br.ReadSingle();
                    }
                    else if (type == PARAMDEF.DefType.fixstr)
                    {
                        value = br.ReadFixStr(field.ArrayLength);
                    }
                    else if (type == PARAMDEF.DefType.fixstrW)
                    {
                        value = br.ReadFixStrW(field.ArrayLength * 2);
                    }
                    else if (ParamUtil.IsBitType(type))
                    {
                        if (field.BitSize == -1)
                        {
                            if (type == PARAMDEF.DefType.u8)
                            {
                                value = br.ReadByte();
                            }
                            else if (type == PARAMDEF.DefType.u16)
                            {
                                value = br.ReadUInt16();
                            }
                            else if (type == PARAMDEF.DefType.u32)
                            {
                                value = br.ReadUInt32();
                            }
                            else if (type == PARAMDEF.DefType.dummy8)
                            {
                                value = br.ReadBytes(field.ArrayLength);
                            }
                        }
                    }
                    else
                    {
                        throw new NotImplementedException($"Unsupported field type: {type}");
                    }

                    if (value != null)
                    {
                        bitOffset = -1;
                    }
                    else
                    {
                        PARAMDEF.DefType newBitType = type == PARAMDEF.DefType.dummy8 ? PARAMDEF.DefType.u8 : type;
                        int bitLimit = ParamUtil.GetBitLimit(newBitType);

                        if (field.BitSize == 0)
                        {
                            throw new NotImplementedException($"Bit size 0 is not supported.");
                        }
                        if (field.BitSize > bitLimit)
                        {
                            throw new InvalidDataException($"Bit size {field.BitSize} is too large to fit in type {newBitType}.");
                        }

                        if (bitOffset == -1 || newBitType != bitType || bitOffset + field.BitSize > bitLimit)
                        {
                            bitOffset = 0;
                            bitType   = newBitType;
                            if (bitType == PARAMDEF.DefType.u8)
                            {
                                bitValue = br.ReadByte();
                            }
                            else if (bitType == PARAMDEF.DefType.u16)
                            {
                                bitValue = br.ReadUInt16();
                            }
                            else if (bitType == PARAMDEF.DefType.u32)
                            {
                                bitValue = br.ReadUInt32();
                            }
                        }

                        uint shifted = bitValue << (32 - field.BitSize - bitOffset) >> (32 - field.BitSize);
                        bitOffset += field.BitSize;
                        if (bitType == PARAMDEF.DefType.u8)
                        {
                            value = (byte)shifted;
                        }
                        else if (bitType == PARAMDEF.DefType.u16)
                        {
                            value = (ushort)shifted;
                        }
                        else if (bitType == PARAMDEF.DefType.u32)
                        {
                            value = shifted;
                        }
                    }

                    cells[i] = new Cell(field, value);
                }
                Cells = cells;
            }
コード例 #2
0
            internal void WriteCells(BinaryWriterEx bw, byte format2D, int index)
            {
                if ((format2D & 0x7F) < 4)
                {
                    bw.FillUInt32($"RowOffset{index}", (uint)bw.Position);
                }
                else
                {
                    bw.FillInt64($"RowOffset{index}", bw.Position);
                }

                int bitOffset = -1;

                PARAMDEF.DefType bitType  = PARAMDEF.DefType.u8;
                uint             bitValue = 0;

                for (int i = 0; i < Cells.Count; i++)
                {
                    Cell             cell  = Cells[i];
                    object           value = cell.Value;
                    PARAMDEF.Field   field = cell.Def;
                    PARAMDEF.DefType type  = field.DisplayType;

                    if (type == PARAMDEF.DefType.s8)
                    {
                        bw.WriteSByte((sbyte)value);
                    }
                    else if (type == PARAMDEF.DefType.s16)
                    {
                        bw.WriteInt16((short)value);
                    }
                    else if (type == PARAMDEF.DefType.s32)
                    {
                        bw.WriteInt32((int)value);
                    }
                    else if (type == PARAMDEF.DefType.f32)
                    {
                        bw.WriteSingle((float)value);
                    }
                    else if (type == PARAMDEF.DefType.fixstr)
                    {
                        bw.WriteFixStr((string)value, field.ArrayLength);
                    }
                    else if (type == PARAMDEF.DefType.fixstrW)
                    {
                        bw.WriteFixStrW((string)value, field.ArrayLength * 2);
                    }
                    else if (ParamUtil.IsBitType(type))
                    {
                        if (field.BitSize == -1)
                        {
                            if (type == PARAMDEF.DefType.u8)
                            {
                                bw.WriteByte((byte)value);
                            }
                            else if (type == PARAMDEF.DefType.u16)
                            {
                                bw.WriteUInt16((ushort)value);
                            }
                            else if (type == PARAMDEF.DefType.u32)
                            {
                                bw.WriteUInt32((uint)value);
                            }
                            else if (type == PARAMDEF.DefType.dummy8)
                            {
                                bw.WriteBytes((byte[])value);
                            }
                        }
                        else
                        {
                            if (bitOffset == -1)
                            {
                                bitOffset = 0;
                                bitType   = type == PARAMDEF.DefType.dummy8 ? PARAMDEF.DefType.u8 : type;
                                bitValue  = 0;
                            }

                            uint shifted = 0;
                            if (bitType == PARAMDEF.DefType.u8)
                            {
                                shifted = (byte)value;
                            }
                            else if (bitType == PARAMDEF.DefType.u16)
                            {
                                shifted = (ushort)value;
                            }
                            else if (bitType == PARAMDEF.DefType.u32)
                            {
                                shifted = (uint)value;
                            }
                            // Shift left first to clear any out-of-range bits
                            shifted    = shifted << (32 - field.BitSize) >> (32 - field.BitSize - bitOffset);
                            bitValue  |= shifted;
                            bitOffset += field.BitSize;

                            bool write = false;
                            if (i == Cells.Count - 1)
                            {
                                write = true;
                            }
                            else
                            {
                                PARAMDEF.Field   nextField = Cells[i + 1].Def;
                                PARAMDEF.DefType nextType  = nextField.DisplayType;
                                int bitLimit = ParamUtil.GetBitLimit(bitType);
                                if (!ParamUtil.IsBitType(nextType) || nextField.BitSize == -1 || bitOffset + nextField.BitSize > bitLimit ||
                                    (nextType == PARAMDEF.DefType.dummy8 ? PARAMDEF.DefType.u8 : nextType) != bitType)
                                {
                                    write = true;
                                }
                            }

                            if (write)
                            {
                                bitOffset = -1;
                                if (bitType == PARAMDEF.DefType.u8)
                                {
                                    bw.WriteByte((byte)bitValue);
                                }
                                else if (bitType == PARAMDEF.DefType.u16)
                                {
                                    bw.WriteUInt16((ushort)bitValue);
                                }
                                else if (bitType == PARAMDEF.DefType.u32)
                                {
                                    bw.WriteUInt32(bitValue);
                                }
                            }
                        }
                    }
                    else
                    {
                        throw new NotImplementedException($"Unsupported field type: {type}");
                    }
                }
            }
コード例 #3
0
        private static int WriteMemoryCell(PARAM.Cell cell, IntPtr CellDataPtr, ref int bitFieldPos, ref BitArray bits, SoulsMemoryHandler memoryHandler)
        {
            PARAMDEF.DefType displayType = cell.Def.DisplayType;
            // If this can be simplified, that would be ideal. Currently we have to reconcile DefType, a numerical size in bits, and the Type used for the bitField array
            if (cell.Def.BitSize != -1)
            {
                if (displayType == SoulsFormats.PARAMDEF.DefType.u8)
                {
                    if (bitFieldPos == 0)
                    {
                        bits = new BitArray(8);
                    }
                    bits.Set(bitFieldPos, Convert.ToBoolean(cell.Value));
                    bitFieldPos++;
                    if (bitFieldPos == 8)
                    {
                        byte valueRead = 0;
                        memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead);

                        byte[] bitField = new byte[1];
                        bits.CopyTo(bitField, 0);
                        bitFieldPos = 0;
                        byte bitbuffer = bitField[0];
                        if (valueRead != bitbuffer)
                        {
                            memoryHandler.WriteProcessMemory(CellDataPtr, ref bitbuffer);
                        }
                        return(sizeof(byte));
                    }
                    return(0);
                }
                else if (displayType == SoulsFormats.PARAMDEF.DefType.u16)
                {
                    if (bitFieldPos == 0)
                    {
                        bits = new BitArray(16);
                    }
                    bits.Set(bitFieldPos, Convert.ToBoolean(cell.Value));
                    bitFieldPos++;
                    if (bitFieldPos == 16)
                    {
                        ushort valueRead = 0;
                        memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead);

                        ushort[] bitField = new ushort[1];
                        bits.CopyTo(bitField, 0);
                        bitFieldPos = 0;
                        ushort bitbuffer = bitField[0];
                        if (valueRead != bitbuffer)
                        {
                            memoryHandler.WriteProcessMemory(CellDataPtr, ref bitbuffer);
                        }
                        return(sizeof(UInt16));
                    }
                    return(0);
                }
                else if (displayType == SoulsFormats.PARAMDEF.DefType.u32)
                {
                    if (bitFieldPos == 0)
                    {
                        bits = new BitArray(32);
                    }
                    bits.Set(bitFieldPos, Convert.ToBoolean(cell.Value));
                    bitFieldPos++;
                    if (bitFieldPos == 32)
                    {
                        uint valueRead = 0;
                        memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead);

                        uint[] bitField = new uint[1];
                        bits.CopyTo(bitField, 0);
                        bitFieldPos = 0;
                        uint bitbuffer = bitField[0];
                        if (valueRead != bitbuffer)
                        {
                            memoryHandler.WriteProcessMemory(CellDataPtr, ref bitbuffer);
                        }
                        return(sizeof(UInt32));
                    }
                    return(0);
                }
            }
            if (displayType == SoulsFormats.PARAMDEF.DefType.f32)
            {
                float valueRead = 0f;
                memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead);

                float value = Convert.ToSingle(cell.Value);
                if (valueRead != value)
                {
                    memoryHandler.WriteProcessMemory(CellDataPtr, ref value);
                }
                return(sizeof(float));
            }
            else if (displayType == SoulsFormats.PARAMDEF.DefType.s32)
            {
                int valueRead = 0;
                memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead);

                int value = Convert.ToInt32(cell.Value);
                if (valueRead != value)
                {
                    memoryHandler.WriteProcessMemory(CellDataPtr, ref value);
                }
                return(sizeof(Int32));
            }
            else if (displayType == SoulsFormats.PARAMDEF.DefType.s16)
            {
                short valueRead = 0;
                memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead);

                short value = Convert.ToInt16(cell.Value);
                if (valueRead != value)
                {
                    memoryHandler.WriteProcessMemory(CellDataPtr, ref value);
                }
                return(sizeof(Int16));
            }
            else if (displayType == SoulsFormats.PARAMDEF.DefType.s8)
            {
                sbyte valueRead = 0;
                memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead);

                sbyte value = Convert.ToSByte(cell.Value);
                if (valueRead != value)
                {
                    memoryHandler.WriteProcessMemory(CellDataPtr, ref value);
                }
                return(sizeof(sbyte));
            }
            else if (displayType == SoulsFormats.PARAMDEF.DefType.u32)
            {
                uint valueRead = 0;
                memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead);

                uint value = Convert.ToUInt32(cell.Value);
                if (valueRead != value)
                {
                    memoryHandler.WriteProcessMemory(CellDataPtr, ref value);
                }
                return(sizeof(UInt32));
            }
            else if (displayType == SoulsFormats.PARAMDEF.DefType.u16)
            {
                ushort valueRead = 0;
                memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead);

                ushort value = Convert.ToUInt16(cell.Value);
                if (valueRead != value)
                {
                    memoryHandler.WriteProcessMemory(CellDataPtr, ref value);
                }
                return(sizeof(UInt16));
            }
            else if (displayType == SoulsFormats.PARAMDEF.DefType.u8)
            {
                byte valueRead = 0;
                memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead);

                byte value = Convert.ToByte(cell.Value);
                if (valueRead != value)
                {
                    memoryHandler.WriteProcessMemory(CellDataPtr, ref value);
                }
                return(sizeof(byte));
            }
            else if (displayType == SoulsFormats.PARAMDEF.DefType.dummy8 || displayType == SoulsFormats.PARAMDEF.DefType.fixstr || displayType == SoulsFormats.PARAMDEF.DefType.fixstrW)
            {
                return(cell.Def.ArrayLength);
            }
            else
            {
                throw new Exception("Unexpected Field Type");
            }
        }