Ejemplo n.º 1
0
        /// <summary>
        /// Write a single entry to stream.
        /// Credits for the 'packing' snippet goes to arookas:
        /// https://github.com/arookas/jmpman/blob/master/jmpman/jmp.cs
        /// </summary>
        /// <param name="bw">Binary Writer to use.</param>
        public void Write(DhBinaryWriter bw, List <JField> fields)
        {
            // Save the current position.
            long currentPosition = bw.Position();

            // Define a buffer to hold packed int values.
            Dictionary <ushort, uint> buffer = new Dictionary <ushort, uint>(fields.Count);

            // Loop through each value in the entry.
            for (int i = 0; i < fields.Count; i++)
            {
                // Seek from the current position to value's offset in the entry.
                bw.Sail(fields[i].Offset);

                // Check which type the current value is.
                switch (fields[i].Type)
                {
                case JFieldType.INTEGER:
                    // Write the value as a integer. TODO: Add pack values.
                    int value = int.Parse(Values[i].ToString());

                    // Check if current field has a bitmask.
                    if (fields[i].Bitmask == 0xFFFFFFFF)
                    {
                        // Value is not packed, write data directly.
                        bw.WriteS32((value));
                    }
                    else
                    {
                        // Value is packed, data will be added to the buffer.
                        if (!buffer.ContainsKey(fields[i].Offset))
                        {
                            // Since no key exists yet, create one.
                            buffer[fields[i].Offset] = 0u;
                        }
                        // Add the packet int value to the buffer.
                        buffer[fields[i].Offset] |= ((uint)(value << fields[i].Shift) & fields[i].Bitmask);
                    }
                    break;

                case JFieldType.STRING:
                    // Write the value as a string.
                    bw.WriteStr32(Values[i].ToString());
                    break;

                case JFieldType.FLOAT:
                    // Write the value as a float32.
                    bw.WriteF32(float.Parse(Values[i].ToString()));
                    break;

                default:
                    // Something went horribly wrong.
                    throw new InvalidDataException();
                }

                // Write out the packed int's buffer.
                foreach (var data in buffer)
                {
                    //
                    bw.Goto(currentPosition + data.Key);
                    // Write the packed int value.
                    bw.WriteU32(data.Value);
                }

                // Seek back to the position we saved earlier.
                bw.Goto(currentPosition);
            }
        }