void WriteWave(Wave wave) { mWriter.WriteS32(wave.WaveId); mWriter.Write8(0xFF); // unknown mWriter.Write8((byte)wave.Format); mWriter.Write8((byte)wave.RootKey); mWriter.WritePadding(4, 0); mWriter.WriteF32(wave.SampleRate); mWriter.WriteS32(wave.WaveStart); mWriter.WriteS32(wave.WaveSize); if (wave.Loop) { mWriter.WriteS32(-1); mWriter.WriteS32(wave.LoopStart); mWriter.WriteS32(wave.LoopEnd); } else { mWriter.WriteS32(0); mWriter.WriteS32(0); mWriter.WriteS32(0); } mWriter.WriteS32(wave.SampleCount); if (wave.Loop) { mWriter.WriteS16((short)wave.HistoryLast); mWriter.WriteS16((short)wave.HistoryPenult); } else { mWriter.WriteS16(0); mWriter.WriteS16(0); } mWriter.Write32(0); // runtime (load-flag pointer) mWriter.Write32(0x1D8); // unknown }
public void save(aBinaryWriter writer) { if (writer == null) { throw new ArgumentNullException("writer"); } // calculate entry shit var entryOffset = calculateEntryOffset(FieldCount); var entrySize = calculateEntrySize(mFields); // write header writer.WriteS32(EntryCount); writer.WriteS32(FieldCount); writer.Write32(entryOffset); writer.WriteS32(entrySize); // write field LUT foreach (var field in mFields) { writer.Write32(field.hash); writer.Write32(field.bitmask); writer.Write16(field.start); writer.Write8(field.shift); writer.Write8((byte)field.type); } // since the stream is write-only, we must write packed integer fields to an intermediate, R/W buffer var buffer = new Dictionary <ushort, uint>(FieldCount); for (var entry = 0; entry < EntryCount; ++entry) { buffer.Clear(); for (var field = 0; field < FieldCount; ++field) { writer.Goto(entryOffset + (entrySize * entry) + mFields[field].start); switch (mFields[field].type) { case jmpValueType.INTEGER: { if (mFields[field].bitmask == 0xFFFFFFFFu) { // field is unpacked; write directly to stream writer.WriteS32(mEntries[entry, field]); } else { // field is packed; write to intermediate buffer if (!buffer.ContainsKey(mFields[field].start)) { buffer[mFields[field].start] = 0u; // if there's no key yet, create one } buffer[mFields[field].start] |= ((uint)mEntries[entry, field] << mFields[field].shift) & mFields[field].bitmask; } break; } case jmpValueType.FLOAT: { writer.WriteF32(mEntries[entry, field]); break; } case jmpValueType.STRING: { writer.WriteString <aCSTR>(mEntries[entry, field], 0x20); break; } } } // flush intermediate buffer foreach (var point in buffer) { writer.Goto(entryOffset + (entrySize * entry) + point.Key); writer.Write32(point.Value); } } }