public ReliableMulticastWriter(Uri uri) { _sendBufferSize = 256*1024; _uri = uri; _socket = new ReliableMulticastSocket(); _socketWriter = new SocketWriter(_socket); }
public BufferedChunkWriter(Fiber fiber, Scheduler scheduler, ChunkWriter output, int bufferLengthInBytes) { _waitAfterMinFlush = 10.Milliseconds(); _fiber = fiber; _scheduler = scheduler; _output = output; _inputBuffer = new Chunk(bufferLengthInBytes); _outputBuffer = new Chunk(bufferLengthInBytes); _minFlushLength = bufferLengthInBytes/2; }
public void ShouldLogDataOnSend() { var buffer = Enumerable.Range(0, 10).Select(i => (byte)i).ToArray(); var stream = new MemoryStream(); var logger = LoggingHelper.GetTraceEnabledLogger(); var writer = new ChunkWriter(stream, logger.Object); // Write data writer.OpenChunk(); writer.Write(buffer, 0, buffer.Length); writer.CloseChunk(); logger.Verify(x => x.Trace("C: {0}", It.IsAny <string>()), Times.Never); writer.Send(); logger.Verify(x => x.Trace("C: {0}", It.IsAny <string>()), Times.Once); }
private static byte[] GenerateMessageChunk(int messageSize) { var buffer = Enumerable.Range(0, messageSize).Select(i => i % byte.MaxValue).Select(i => (byte)i).ToArray(); var stream = new MemoryStream(); var writer = new ChunkWriter(stream); writer.OpenChunk(); writer.Write(buffer, 0, buffer.Length); writer.CloseChunk(); // Append end of message marker writer.OpenChunk(); writer.CloseChunk(); writer.Flush(); writer.Send(); return(stream.ToArray()); }
public Node GetNode(Uri uri) { string key = uri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped); Node result; if (_nodes.TryGetValue(key, out result)) { return(result); } ChunkWriter chunkWriter = GetWriter(uri); result = new RemoteNode(new ShuntChannel(), chunkWriter, _fiberFactory, _scheduler, _serializer); _nodes.Add(key, result); return(result); }
public async void ShouldResetCapacityWhenAboveMaxBufferSizeAfterEachSendAsync() { var buffer = new byte[1536]; var stream = new MemoryStream(); var logger = new Mock <ILogger>(); var writer = new ChunkWriter(stream, 512, 1024, logger.Object); writer.OpenChunk(); writer.Write(buffer, 0, buffer.Length); writer.CloseChunk(); await writer.SendAsync(); writer.OpenChunk(); writer.Write(buffer, 0, buffer.Length); writer.CloseChunk(); await writer.SendAsync(); logger.Verify(l => l.Info(It.IsRegex("^Shrinking write buffers to the"), It.IsAny <object[]>()), Times.Exactly(2)); }
public Queue(string topic, int queueId) { Topic = topic; QueueId = queueId; Key = new QueueKey(topic, queueId); _jsonSerializer = ObjectContainer.Resolve <IJsonSerializer>(); _chunkManager = new ChunkManager( "QueueChunk-" + Key.ToString(), BrokerController.Instance.Setting.QueueChunkConfig, BrokerController.Instance.Setting.IsMessageStoreMemoryMode, new List <string> { Topic, QueueId.ToString() }); //Topic + QueueId.ToString() _chunkWriter = new ChunkWriter(_chunkManager); _chunkReader = new ChunkReader(_chunkManager, _chunkWriter); _queueSettingFile = Path.Combine(_chunkManager.ChunkPath, QueueSettingFileName); _logger = ObjectContainer.Resolve <ILoggerFactory>().Create(this.GetType().FullName); }
static void CreateChunks(string root, string path, ChunkManager chunkManager, int singleFileIndexCount, int dataUnitSize, int totalAggNumber, int indexCountForSingleAgg) { if (Directory.Exists(root)) { Directory.Delete(root, true); } Directory.CreateDirectory(root); if (Directory.Exists(path)) { Directory.Delete(path, true); } Directory.CreateDirectory(path); var chunkWriter = new ChunkWriter(chunkManager); chunkWriter.Open(); var watch = Stopwatch.StartNew(); var format = "{0}{1:00000000000000}"; var aggPrefix = "aggregate_"; for (var i = 0; i < totalAggNumber; i++) { var sourceId = string.Format(format, aggPrefix, i); for (var j = 0; j < indexCountForSingleAgg; j++) { var record = new StreamIndex() { SourceId = sourceId, CommandId = ObjectId.GenerateNewStringId(), Version = j + 1, BodyPosition = 10000L }; chunkWriter.Write(record); } } chunkWriter.Close(); Console.WriteLine("Create event index success, aggCount: {0}, totalEventIndexCount: {1}, timeSpent: {2}ms", totalAggNumber, totalAggNumber * indexCountForSingleAgg, watch.ElapsedMilliseconds); }
public void ShouldWriteBytesCorrectlyWhenMessageIsGreaterThanChunkSize() { var stream = new MemoryStream(); var chunker = new ChunkWriter(stream, 6); byte[] bytes = new byte[10]; for (int i = 0; i < bytes.Length; i++) { bytes[i] = (byte)(i + 1); } chunker.OpenChunk(); chunker.Write(bytes, 0, bytes.Length); chunker.CloseChunk(); chunker.Send(); byte[] expected = { 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00, 0x04, 0x07, 0x08, 0x09, 0x0A }; Assert.Equal(expected, stream.ToArray()); }
void CreateLocalNode(Uri uri, UntypedChannel input) { string key = uri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped); ChunkWriter chunkWriter = GetWriter(uri); _localNode = new RemoteNode(input, chunkWriter, _fiberFactory, _scheduler, _serializer); try { GetReader(uri, _localNode); } catch { _localNode.Dispose(); throw; } _nodes.Add(key, _localNode); }
private Stream BuildBinStream() { MemoryStream ms = new MemoryStream(8192); BinaryWriter bw = new BinaryWriter(ms); ChunkWriter cw = new ChunkWriter(bw, Vault); var stringsSet = new HashSet <string>(); var strings = Vault.SaveContext.Collections.SelectMany(CollectStrings).ToList(); stringsSet.UnionWith(strings); var stringsChunk = new BinStringsChunk { Strings = new List <string>(stringsSet) }; cw.WriteChunk(stringsChunk); cw.WriteChunk(new EndChunk()); return(ms); }
public void Write(ChunkWriter chunkWriter) { chunkWriter.BinaryWriter.Write(1); chunkWriter.BinaryWriter.Write(3); chunkWriter.BinaryWriter.Write(3); chunkWriter.BinaryWriter.Write(0x13371337); chunkWriter.BinaryWriter.Write(0); var nameBytes = new char[0x1C]; nameBytes[0] = 'H'; nameBytes[1] = 'E'; nameBytes[2] = 'L'; nameBytes[3] = 'L'; nameBytes[4] = 'O'; chunkWriter.BinaryWriter.Write(nameBytes); for (var i = 0; i < 0x78; i++) { chunkWriter.BinaryWriter.Write((byte)i); } }
public void Write_NormalChunk_SuccessfulWrite() { var targetStream = new MemoryStream(); var chunk = new Chunk { AsciiHeader = "MTrk", Data = new byte[] { 0xFF, 0x10, 0x00 } }; using (var writer = new ChunkWriter(targetStream)) { writer.Write(chunk); } var expectedBytes = new byte[] { 0x4D, 0x54, 0x72, 0x6B, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x10, 0x00 }; targetStream.ToArray().ShouldBe(expectedBytes); }
public void ShouldCloseTheChunkWithCorrectSize(int chunkSize) { var buffer = Enumerable.Range(0, chunkSize).Select(i => i % byte.MaxValue).Select(i => (byte)i).ToArray(); var stream = new MemoryStream(); var writer = new ChunkWriter(stream); // Write data writer.OpenChunk(); writer.Write(buffer, 0, buffer.Length); writer.CloseChunk(); // End Of Message Marker writer.OpenChunk(); writer.CloseChunk(); // Write To Underlying Stream writer.Send(); var constructed = ConstructMessage(stream.ToArray()); constructed.Should().HaveCount(chunkSize); constructed.Should().Equal(buffer); }
private static void WriteSprites(ChunkWriter chunkIO, List <WadSprite> spriteTable) { chunkIO.WriteChunkWithChildren(Wad2Chunks.Sprites, () => { for (int i = 0; i < spriteTable.Count; ++i) { var sprite = spriteTable[i]; chunkIO.WriteChunkWithChildren(Wad2Chunks.Sprite, () => { LEB128.Write(chunkIO.Raw, sprite.Texture.Image.Width); LEB128.Write(chunkIO.Raw, sprite.Texture.Image.Height); chunkIO.WriteChunkInt(Wad2Chunks.SpriteIndex, i); chunkIO.WriteChunkArrayOfBytes(Wad2Chunks.SpriteData, sprite.Texture.Image.ToByteArray()); chunkIO.WriteChunk(Wad2Chunks.SpriteSides, () => { chunkIO.Raw.Write(sprite.Alignment.X0); chunkIO.Raw.Write(sprite.Alignment.Y0); chunkIO.Raw.Write(sprite.Alignment.X1); chunkIO.Raw.Write(sprite.Alignment.Y1); }); }); } }); }
public void Init(ChunkManagerConfig eventDataChunkConfig, ChunkManagerConfig aggregateIndexChunkConfig, ChunkManagerConfig commandIndexChunkConfig) { _eventDataChunkManager = new ChunkManager("EventDataChunk", eventDataChunkConfig, false); _eventDataChunkWriter = new ChunkWriter(_eventDataChunkManager); _eventDataChunkReader = new ChunkReader(_eventDataChunkManager, _eventDataChunkWriter); _aggregateIndexChunkManager = new ChunkManager("AggregateIndexChunk", aggregateIndexChunkConfig, false); _aggregateIndexChunkWriter = new ChunkWriter(_aggregateIndexChunkManager); _aggregateIndexChunkReader = new ChunkReader(_aggregateIndexChunkManager, _aggregateIndexChunkWriter); _commandIndexChunkManager = new ChunkManager("CommandIndexChunk", commandIndexChunkConfig, false); _commandIndexChunkWriter = new ChunkWriter(_commandIndexChunkManager); _commandIndexChunkReader = new ChunkReader(_commandIndexChunkManager, _commandIndexChunkWriter); _eventDataChunkManager.Load(ReadEventStreamRecord); _aggregateIndexChunkManager.Load(ReadIndexRecord); _commandIndexChunkManager.Load(ReadIndexRecord); _eventDataChunkWriter.Open(); _aggregateIndexChunkWriter.Open(); _commandIndexChunkWriter.Open(); LoadIndexData(); }
public void Write(ArraySegment <byte> buffer, bool chunk) { lock (_writeLock) { if (buffer.Count == 0) { return; } try { if (!_canWrite) { return; } if (chunk && buffer.Array != null) { var beginChunkBytes = ChunkWriter.BeginChunkBytes(buffer.Count); _outputStream.Write(beginChunkBytes.Array, beginChunkBytes.Offset, beginChunkBytes.Count); } _outputStream.Write(buffer.Array ?? _nullBuffer, buffer.Offset, buffer.Count); if (chunk && buffer.Array != null) { _outputStream.Write(_endChunkBytes, 0, _endChunkBytes.Length); } } catch (Exception ex) { _canWrite = false; _logger.ConnectionError(_connectionId, ex); } } }
// Save a PNG image to the specified stream. public static void Save(Stream stream, Image image) { Frame frame = image.GetFrame(0); byte[] buffer = new byte [1024]; ChunkWriter writer = new ChunkWriter(stream); int colorType, bitDepth; int sigRed, sigGreen, sigBlue, sigAlpha; int paletteSize, posn; int[] palette; ZlibCompressor compressor; ScanlineWriter scanlineWriter; OutputFunc func; int y; // Determine the color type and bit depth for the image. sigRed = -1; sigGreen = -1; sigBlue = -1; sigAlpha = -1; paletteSize = 0; switch(frame.PixelFormat) { case PixelFormat.Format16bppRgb555: { sigRed = 5; sigGreen = 5; sigBlue = 5; colorType = 2; bitDepth = 8; } break; case PixelFormat.Format16bppRgb565: { sigRed = 5; sigGreen = 6; sigBlue = 5; colorType = 2; bitDepth = 8; } break; case PixelFormat.Format24bppRgb: case PixelFormat.Format32bppRgb: { colorType = 2; bitDepth = 8; } break; case PixelFormat.Format1bppIndexed: { colorType = 3; bitDepth = 1; paletteSize = 2; } break; case PixelFormat.Format4bppIndexed: { colorType = 3; bitDepth = 4; paletteSize = 16; } break; case PixelFormat.Format8bppIndexed: { colorType = 3; bitDepth = 8; paletteSize = 256; } break; case PixelFormat.Format16bppArgb1555: { sigRed = 5; sigGreen = 5; sigBlue = 5; sigAlpha = 1; colorType = 6; bitDepth = 8; } break; case PixelFormat.Format32bppPArgb: case PixelFormat.Format32bppArgb: { colorType = 6; bitDepth = 8; } break; case PixelFormat.Format16bppGrayScale: { colorType = 0; bitDepth = 16; } break; case PixelFormat.Format48bppRgb: { colorType = 2; bitDepth = 16; } break; case PixelFormat.Format64bppPArgb: case PixelFormat.Format64bppArgb: { colorType = 6; bitDepth = 16; } break; default: throw new FormatException("unknown format"); } // Write out the PNG magic number. stream.Write(magic, 0, magic.Length); // Write the header chunk. Utils.WriteInt32B(buffer, 0, frame.Width); Utils.WriteInt32B(buffer, 4, frame.Height); buffer[8] = (byte)bitDepth; buffer[9] = (byte)colorType; buffer[10] = (byte)0; // Compression method. buffer[11] = (byte)0; // Filter method. buffer[12] = (byte)0; // Interlace method. writer.Write(PngReader.IHDR, buffer, 0, 13); // Write the significant bits chunk if necessary. if(sigAlpha != -1) { buffer[0] = (byte)sigRed; buffer[1] = (byte)sigGreen; buffer[2] = (byte)sigBlue; buffer[3] = (byte)sigAlpha; writer.Write(PngReader.sBIT, buffer, 0, 4); } else if(sigRed != -1) { buffer[0] = (byte)sigRed; buffer[1] = (byte)sigGreen; buffer[2] = (byte)sigBlue; writer.Write(PngReader.sBIT, buffer, 0, 3); } // Write the palette and transparency chunks. if(paletteSize > 0) { Array.Clear(buffer, 0, buffer.Length); palette = frame.Palette; if(palette != null) { for(posn = 0; posn < palette.Length && posn < paletteSize; ++posn) { buffer[posn * 3] = (byte)(palette[posn] >> 16); buffer[posn * 2 + 1] = (byte)(palette[posn] >> 8); buffer[posn * 2 + 2] = (byte)(palette[posn]); } } writer.Write(PngReader.PLTE, buffer, 0, paletteSize * 3); if(frame.TransparentPixel >= 0 && frame.TransparentPixel < paletteSize) { for(posn = 0; posn < paletteSize; ++posn) { buffer[posn] = (byte)0xFF; } buffer[frame.TransparentPixel] = (byte)0x00; writer.Write(PngReader.tRNS, buffer, 0, frame.TransparentPixel + 1); } } // Compress and write the scanlines to the output stream. compressor = new ZlibCompressor(writer); scanlineWriter = new ScanlineWriter (compressor, frame.Width, frame.PixelFormat); func = GetOutputFunc(frame.PixelFormat); for(y = 0; y < frame.Height; ++y) { func(frame, y, scanlineWriter.Buffer); scanlineWriter.FlushScanline(); } compressor.Finish(); // Write the end chunk. writer.Write(PngReader.IEND, buffer, 0, 0); }
/// <inheritdoc /> public void Write(ChunkWriter chunkWriter) { chunkWriter.BinaryWriter.Write(_resource.Data); }
static void WriteChunkPerfTest() { ECommonConfiguration .Create() .UseAutofac() .RegisterCommonComponents() .UseLog4Net() .RegisterUnhandledExceptionHandler() .BuildContainer(); var storeRootPath = ConfigurationManager.AppSettings["storeRootPath"]; //文件存储根目录 var threadCount = int.Parse(ConfigurationManager.AppSettings["concurrentThreadCount"]); //并行写数据的线程数 var recordSize = int.Parse(ConfigurationManager.AppSettings["recordSize"]); //记录大小,字节为单位 var recordCount = int.Parse(ConfigurationManager.AppSettings["recordCount"]); //总共要写入的记录数 var syncFlush = bool.Parse(ConfigurationManager.AppSettings["syncFlush"]); //是否同步刷盘 FlushOption flushOption; Enum.TryParse(ConfigurationManager.AppSettings["flushOption"], out flushOption); //同步刷盘方式 var chunkSize = 1024 * 1024 * 1024; var flushInterval = 100; var maxRecordSize = 5 * 1024 * 1024; var chunkWriteBuffer = 128 * 1024; var chunkReadBuffer = 128 * 1024; var chunkManagerConfig = new ChunkManagerConfig( Path.Combine(storeRootPath, @"sample-chunks"), new DefaultFileNamingStrategy("message-chunk-"), chunkSize, 0, 0, flushInterval, false, syncFlush, flushOption, Environment.ProcessorCount * 8, maxRecordSize, chunkWriteBuffer, chunkReadBuffer, 5, 1, 1, 5, 10 * 10000, true); var chunkManager = new ChunkManager("sample-chunk", chunkManagerConfig, false); var chunkWriter = new ChunkWriter(chunkManager); chunkManager.Load(ReadRecord); chunkWriter.Open(); var record = new BufferLogRecord { RecordBuffer = new byte[recordSize] }; var count = 0L; var performanceService = ObjectContainer.Resolve <IPerformanceService>(); performanceService.Initialize("WriteChunk").Start(); for (var i = 0; i < threadCount; i++) { Task.Factory.StartNew(() => { while (true) { var current = Interlocked.Increment(ref count); if (current > recordCount) { break; } var start = DateTime.Now; chunkWriter.Write(record); performanceService.IncrementKeyCount("default", (DateTime.Now - start).TotalMilliseconds); } }); } Console.ReadLine(); chunkWriter.Close(); chunkManager.Close(); }
private static LevelSettingsIds WriteLevelSettings(ChunkWriter chunkIO, LevelSettings settings) { var levelSettingIds = new LevelSettingsIds(settings); using (var chunkSettings = chunkIO.WriteChunk(Prj2Chunks.Settings, long.MaxValue)) { chunkIO.WriteChunkString(Prj2Chunks.FontTextureFilePath, settings.FontTextureFilePath ?? ""); chunkIO.WriteChunkString(Prj2Chunks.SkyTextureFilePath, settings.SkyTextureFilePath ?? ""); chunkIO.WriteChunkString(Prj2Chunks.Tr5ExtraSpritesFilePath, settings.Tr5ExtraSpritesFilePath ?? ""); using (var chunkOldWadSoundPaths = chunkIO.WriteChunk(Prj2Chunks.OldWadSoundPaths)) { chunkIO.WriteChunkEmpty(Prj2Chunks.OldWadSoundUpdateTag1_0_8); foreach (WadSoundPath soundPath in settings.WadSoundPaths) { using (var chunkOldWadSoundPath = chunkIO.WriteChunk(Prj2Chunks.OldWadSoundPath)) { chunkIO.WriteChunkString(Prj2Chunks.OldWadSoundPathPath, soundPath.Path); chunkIO.WriteChunkEnd(); } } chunkIO.WriteChunkEnd(); } chunkIO.WriteChunkString(Prj2Chunks.GameDirectory, settings.GameDirectory ?? ""); chunkIO.WriteChunkString(Prj2Chunks.GameLevelFilePath, settings.GameLevelFilePath ?? ""); chunkIO.WriteChunkString(Prj2Chunks.GameExecutableFilePath, settings.GameExecutableFilePath ?? ""); chunkIO.WriteChunkBool(Prj2Chunks.GameEnableQuickStartFeature, settings.GameEnableQuickStartFeature); chunkIO.WriteChunkInt(Prj2Chunks.GameVersion, (long)settings.GameVersion); chunkIO.WriteChunkInt(Prj2Chunks.Tr5LaraType, (long)settings.Tr5LaraType); chunkIO.WriteChunkInt(Prj2Chunks.Tr5Weather, (long)settings.Tr5WeatherType); chunkIO.WriteChunkInt(Prj2Chunks.TexturePadding, (long)settings.TexturePadding); chunkIO.WriteChunkBool(Prj2Chunks.RemapAnimatedTextures, settings.RemapAnimatedTextures); chunkIO.WriteChunkBool(Prj2Chunks.Dither16BitTextures, settings.Dither16BitTextures); chunkIO.WriteChunkBool(Prj2Chunks.AgressiveTexturePacking, settings.AgressiveTexturePacking); chunkIO.WriteChunkBool(Prj2Chunks.AgressiveFloordataPacking, settings.AgressiveFloordataPacking); chunkIO.WriteChunkVector3(Prj2Chunks.DefaultAmbientLight, settings.DefaultAmbientLight); chunkIO.WriteChunkInt(Prj2Chunks.DefaultLightQuality, (long)settings.DefaultLightQuality); chunkIO.WriteChunkBool(Prj2Chunks.OverrideLightQuality, settings.OverrideIndividualLightQualitySettings); chunkIO.WriteChunkString(Prj2Chunks.ScriptDirectory, settings.ScriptDirectory ?? ""); chunkIO.WriteChunkInt(Prj2Chunks.SoundSystem, (int)settings.SoundSystem); using (var chunkWads = chunkIO.WriteChunk(Prj2Chunks.Wads, long.MaxValue)) { foreach (ReferencedWad wad in settings.Wads) { using (var chunkWad = chunkIO.WriteChunk(Prj2Chunks.Wad)) { chunkIO.WriteChunkString(Prj2Chunks.WadPath, wad.Path ?? ""); chunkIO.WriteChunkEnd(); } } chunkIO.WriteChunkEnd(); } using (var chunkSounds = chunkIO.WriteChunk(Prj2Chunks.SoundsCatalogs, long.MaxValue)) { foreach (ReferencedSoundsCatalog soundRef in settings.SoundsCatalogs) { using (var chunkSound = chunkIO.WriteChunk(Prj2Chunks.SoundsCatalog)) { chunkIO.WriteChunkString(Prj2Chunks.SoundsCatalogPath, soundRef.Path ?? ""); chunkIO.WriteChunkEnd(); } } chunkIO.WriteChunkEnd(); } using (var chunkSelectedSounds = chunkIO.WriteChunk(Prj2Chunks.SelectedSounds, long.MaxValue)) { foreach (int selectedSound in settings.SelectedSounds) { chunkIO.WriteChunkInt(Prj2Chunks.SelectedSound, selectedSound); } chunkIO.WriteChunkEnd(); } using (var chunkTextures = chunkIO.WriteChunk(Prj2Chunks.Textures, long.MaxValue)) { int index = 0; foreach (LevelTexture texture in settings.Textures) { using (var chunkLevelTexture = chunkIO.WriteChunk(Prj2Chunks.LevelTexture)) { chunkIO.WriteChunkInt(Prj2Chunks.LevelTextureIndex, index); chunkIO.WriteChunkString(Prj2Chunks.LevelTexturePath, texture.Path ?? ""); chunkIO.WriteChunkString(Prj2Chunks.LevelTextureCustomBumpmapPath, texture.BumpPath ?? ""); chunkIO.WriteChunkBool(Prj2Chunks.LevelTextureConvert512PixelsToDoubleRows, texture.Convert512PixelsToDoubleRows); chunkIO.WriteChunkBool(Prj2Chunks.LevelTextureReplaceMagentaWithTransparency, texture.ReplaceMagentaWithTransparency); using (var chunkLevelTextureFootStepSounds = chunkIO.WriteChunk(Prj2Chunks.LevelTextureFootStepSounds)) { chunkIO.Raw.Write(texture.FootStepSoundWidth); chunkIO.Raw.Write(texture.FootStepSoundHeight); for (int y = 0; y < texture.FootStepSoundHeight; ++y) { for (int x = 0; x < texture.FootStepSoundWidth; ++x) { chunkIO.Raw.Write((byte)texture.GetFootStepSound(x, y)); } } } using (var chunkLevelTextureBumpmaps = chunkIO.WriteChunk(Prj2Chunks.LevelTextureBumpmaps)) { chunkIO.Raw.Write(texture.BumpMappingWidth); chunkIO.Raw.Write(texture.BumpMappingHeight); for (int y = 0; y < texture.BumpMappingHeight; ++y) { for (int x = 0; x < texture.BumpMappingWidth; ++x) { chunkIO.Raw.Write((byte)texture.GetBumpMapLevel(x, y)); } } } chunkIO.WriteChunkEnd(); } levelSettingIds.LevelTextures.Add(texture, index++); } chunkIO.WriteChunkEnd(); } using (var chunkImportedGeometries = chunkIO.WriteChunk(Prj2Chunks.ImportedGeometries, long.MaxValue)) { int index = 0; foreach (ImportedGeometry importedGeometry in settings.ImportedGeometries) { using (var chunkImportedGeometry = chunkIO.WriteChunk(Prj2Chunks.ImportedGeometry)) { chunkIO.WriteChunkInt(Prj2Chunks.ImportedGeometryIndex, index); chunkIO.WriteChunkString(Prj2Chunks.ImportedGeometryName, importedGeometry.Info.Name); chunkIO.WriteChunkString(Prj2Chunks.ImportedGeometryPath, importedGeometry.Info.Path); chunkIO.WriteChunkFloat(Prj2Chunks.ImportedGeometryScale, importedGeometry.Info.Scale); chunkIO.WriteChunkInt(Prj2Chunks.ImportedGeometryPosAxisFlags, (importedGeometry.Info.SwapXY ? 1 : 0) | (importedGeometry.Info.SwapXZ ? 2 : 0) | (importedGeometry.Info.SwapYZ ? 4 : 0) | (importedGeometry.Info.FlipX ? 8 : 0) | (importedGeometry.Info.FlipY ? 16 : 0) | (importedGeometry.Info.FlipZ ? 32 : 0)); chunkIO.WriteChunkInt(Prj2Chunks.ImportedGeometryTexAxisFlags, importedGeometry.Info.FlipUV_V ? 4 : 0); chunkIO.WriteChunkBool(Prj2Chunks.ImportedGeometryInvertFaces, importedGeometry.Info.InvertFaces); chunkIO.WriteChunkEnd(); } levelSettingIds.ImportedGeometries.Add(importedGeometry, index++); } chunkIO.WriteChunkEnd(); } using (var chunkAnimatedTextureSets = chunkIO.WriteChunk(Prj2Chunks.AnimatedTextureSets, long.MaxValue)) { foreach (AnimatedTextureSet set in settings.AnimatedTextureSets) { using (var chunkAnimatedTextureSet = chunkIO.WriteChunk(Prj2Chunks.AnimatedTextureSet)) { chunkIO.WriteChunkString(Prj2Chunks.AnimatedTextureSetName, set.Name ?? ""); chunkIO.WriteChunkInt(Prj2Chunks.AnimatedTextureSetType, (int)set.AnimationType); chunkIO.WriteChunkFloat(Prj2Chunks.AnimatedTextureSetFps, set.Fps); chunkIO.WriteChunkInt(Prj2Chunks.AnimatedTextureSetUvRotate, set.UvRotate); using (var chunkAnimatedTextureFrames = chunkIO.WriteChunk(Prj2Chunks.AnimatedTextureFrames)) { foreach (AnimatedTextureFrame frame in set.Frames) { using (var chunkAnimatedTextureFrame = chunkIO.WriteChunk(Prj2Chunks.AnimatedTextureFrame, 120)) { LEB128.Write(chunkIO.Raw, levelSettingIds.LevelTextures[frame.Texture]); chunkIO.Raw.Write(frame.TexCoord0); chunkIO.Raw.Write(frame.TexCoord1); chunkIO.Raw.Write(frame.TexCoord2); chunkIO.Raw.Write(frame.TexCoord3); LEB128.Write(chunkIO.Raw, frame.Repeat); } } chunkIO.WriteChunkEnd(); } chunkIO.WriteChunkEnd(); } } chunkIO.WriteChunkEnd(); } using (var chunkAutoMergeStatics = chunkIO.WriteChunk(Prj2Chunks.AutoMergeStaticMeshes, UInt16.MaxValue)) { foreach (var entry in settings.AutoStaticMeshMerges) { using (var chunkAutoMergeEntry = chunkIO.WriteChunk(Prj2Chunks.AutoMergeStaticMeshEntry3)) { chunkIO.Raw.Write(entry.meshId); chunkIO.Raw.Write(entry.InterpretShadesAsEffect); chunkIO.Raw.Write(entry.TintAsAmbient); chunkIO.Raw.Write(entry.ClearShades); } } chunkIO.WriteChunkEnd(); } using (var chunkPalette = chunkIO.WriteChunk(Prj2Chunks.Palette, UInt16.MaxValue)) { chunkIO.Raw.Write((ushort)settings.Palette.Count); foreach (var color in settings.Palette) { chunkIO.Raw.Write(color.R); chunkIO.Raw.Write(color.G); chunkIO.Raw.Write(color.B); } chunkIO.WriteChunkEnd(); } chunkIO.WriteChunkEnd(); }; return(levelSettingIds); }
static Task Write(ChunkWriter writer, byte[] chunk) => writer.WriteAsync(new UserData(), chunk, 0, chunk.Length);
public static void WriteChunks(ChunkWriter writer) { writer.Write(nameof(AppReady), AppReady); }
public void Append <TBody>(Chunk <TBody> chunk, ChunkWriter chunkWriter, Serializer <TBody> serializer) where TBody : class { Append(chunk.Configuration, chunkWriter.ChunkToStreamAsync(chunk, serializer)); }
public static void WriteChunks(ChunkWriter writer) { writer.Write(nameof(JoinedProfile), JoinedProfile); writer.Write(nameof(SendTransferNotifications), SendTransferNotifications); }
public void ChunkedPrefixMustBeHexCrLfWithoutLeadingZeros(int dataCount, string expected) { var beginChunkBytes = ChunkWriter.BeginChunkBytes(dataCount); Assert.Equal(Encoding.ASCII.GetBytes(expected), beginChunkBytes.ToArray()); }
private static void WriteRooms(ChunkWriter chunkIO, Dictionary <Room, int> rooms, LevelSettingsIds levelSettingIds) { // Allocate object indices var objectInstanceLookup = new Dictionary <ObjectInstance, int>(); foreach (Room room in rooms.Keys) { foreach (ObjectInstance objectInstance in room.AnyObjects) { objectInstanceLookup.Add(objectInstance, objectInstanceLookup.Count); } } // Save using (var chunkRooms = chunkIO.WriteChunk(Prj2Chunks.Rooms, long.MaxValue)) { foreach (Room room in rooms.Keys) { using (var chunkRoom = chunkIO.WriteChunk(Prj2Chunks.Room, long.MaxValue)) { LEB128.Write(chunkIO.Raw, room.NumXSectors); LEB128.Write(chunkIO.Raw, room.NumZSectors); // Write basic properties chunkIO.WriteChunkInt(Prj2Chunks.RoomIndex, rooms.TryGetOrDefault(room, -1)); chunkIO.WriteChunkString(Prj2Chunks.RoomName, room.Name); chunkIO.WriteChunkVector3(Prj2Chunks.RoomPosition, room.Position); chunkIO.WriteChunkArrayOfBytes(Prj2Chunks.RoomTags, System.Text.Encoding.UTF8.GetBytes(string.Join(" ", room.Tags))); // Write sectors using (var chunkRoomSectors = chunkIO.WriteChunk(Prj2Chunks.RoomSectors)) { for (int z = 0; z < room.NumZSectors; z++) { for (int x = 0; x < room.NumXSectors; x++) { using (var chunkSector = chunkIO.WriteChunk(Prj2Chunks.Sector, LEB128.MaximumSize2Byte)) { chunkIO.Raw.Write(x + z * room.NumXSectors); var b = room.Blocks[x, z]; long combinedFlag = (b.IsAnyWall ? 1L : 0) | (b.ForceFloorSolid ? 2L : 0) | ((long)b.Flags << 2); chunkIO.WriteChunkInt(Prj2Chunks.SectorProperties, combinedFlag); using (var chunkSectorFloor = chunkIO.WriteChunk(Prj2Chunks.SectorFloor, LEB128.MaximumSize1Byte)) { long flag = (b.Floor.SplitDirectionIsXEqualsZ ? 1L : 0) | ((long)b.Floor.DiagonalSplit << 1); LEB128.Write(chunkIO.Raw, flag); for (BlockEdge edge = 0; edge < BlockEdge.Count; ++edge) { LEB128.Write(chunkIO.Raw, b.Floor.GetHeight(edge)); } for (BlockEdge edge = 0; edge < BlockEdge.Count; ++edge) { LEB128.Write(chunkIO.Raw, b.GetHeight(BlockVertical.Ed, edge)); } } using (var chunkSectorCeiling = chunkIO.WriteChunk(Prj2Chunks.SectorCeiling, LEB128.MaximumSize1Byte)) { long flag = (b.Ceiling.SplitDirectionIsXEqualsZ ? 1L : 0) | ((long)b.Ceiling.DiagonalSplit << 1); LEB128.Write(chunkIO.Raw, flag); for (BlockEdge edge = 0; edge < BlockEdge.Count; ++edge) { LEB128.Write(chunkIO.Raw, b.Ceiling.GetHeight(edge)); } for (BlockEdge edge = 0; edge < BlockEdge.Count; ++edge) { LEB128.Write(chunkIO.Raw, b.GetHeight(BlockVertical.Rf, edge)); } } for (BlockFace face = 0; face < BlockFace.Count; face++) { var texture = b.GetFaceTexture(face); if (texture.Texture == null) { continue; } if (texture.Texture is LevelTexture) { using (var chunkTextureLevelTexture = chunkIO.WriteChunk(Prj2Chunks.TextureLevelTexture2, LEB128.MaximumSize1Byte)) { int textureIndex = levelSettingIds.LevelTextures[(LevelTexture)texture.Texture]; LEB128.Write(chunkIO.Raw, (long)face); chunkIO.Raw.Write(texture.TexCoord0); chunkIO.Raw.Write(texture.TexCoord1); chunkIO.Raw.Write(texture.TexCoord2); chunkIO.Raw.Write(texture.TexCoord3); chunkIO.Raw.Write(texture.ParentArea.Start); chunkIO.Raw.Write(texture.ParentArea.End); LEB128.Write(chunkIO.Raw, (texture.DoubleSided ? 1L : 0) | ((long)texture.BlendMode << 1)); LEB128.Write(chunkIO.Raw, textureIndex); } } else if (texture.Texture == TextureInvisible.Instance) { chunkIO.WriteChunkInt(Prj2Chunks.TextureInvisible, (long)face); } else { throw new NotSupportedException("Unsupported texture type " + texture.Texture.GetType().Name); } } chunkIO.WriteChunkEnd(); } } } chunkIO.WriteChunkEnd(); } // Write room properties chunkIO.WriteChunkVector3(Prj2Chunks.RoomAmbientLight, room.AmbientLight); chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagCold, room.FlagCold); chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagDamage, room.FlagDamage); chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagHorizon, room.FlagHorizon); chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagOutside, room.FlagOutside); chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagNoLensflare, room.FlagNoLensflare); chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagExcludeFromPathFinding, room.FlagExcludeFromPathFinding); chunkIO.WriteChunkInt(Prj2Chunks.RoomType, (int)room.Type); chunkIO.WriteChunkInt(Prj2Chunks.RoomTypeStrength, room.TypeStrength); chunkIO.WriteChunkInt(Prj2Chunks.RoomLightEffect, (int)room.LightEffect); chunkIO.WriteChunkInt(Prj2Chunks.RoomLightEffectStrength2, room.LightEffectStrength); chunkIO.WriteChunkInt(Prj2Chunks.RoomReverberation, (int)room.Reverberation); chunkIO.WriteChunkInt(Prj2Chunks.RoomLightInterpolationMode, (int)room.LightInterpolationMode); chunkIO.WriteChunkBool(Prj2Chunks.RoomLocked, room.Locked); chunkIO.WriteChunkBool(Prj2Chunks.RoomHidden, room.Hidden); if (room.AlternateRoom != null && rooms.ContainsKey(room.AlternateRoom)) { using (var chunkRoomAlternate = chunkIO.WriteChunk(Prj2Chunks.RoomAlternate, LEB128.MaximumSize1Byte)) { chunkIO.WriteChunkInt(Prj2Chunks.AlternateGroup, room.AlternateGroup); chunkIO.WriteChunkInt(Prj2Chunks.AlternateRoom, rooms[room.AlternateRoom]); chunkIO.WriteChunkEnd(); } } // Write room objects WriteObjects(chunkIO, room.AnyObjects, rooms, levelSettingIds, objectInstanceLookup); chunkIO.WriteChunkEnd(); } } chunkIO.WriteChunkEnd(); } }
private static void WriteObjects(ChunkWriter chunkIO, IEnumerable <ObjectInstance> objects, Dictionary <Room, int> rooms, LevelSettingsIds levelSettingIds, Dictionary <ObjectInstance, int> objectInstanceLookup) { using (var chunkObjects = chunkIO.WriteChunk(Prj2Chunks.Objects, long.MaxValue)) { foreach (var o in objects) { if (o is MoveableInstance) { chunkIO.WriteChunkWithChildren(Prj2Chunks.ObjectMovable3, () => { var instance = (MoveableInstance)o; LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1)); chunkIO.Raw.Write(instance.Position); chunkIO.Raw.Write(instance.RotationY); LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1); chunkIO.Raw.Write(instance.WadObjectId.TypeId); chunkIO.Raw.Write(instance.Ocb); chunkIO.Raw.Write(instance.Invisible); chunkIO.Raw.Write(instance.ClearBody); chunkIO.Raw.Write(instance.CodeBits); chunkIO.Raw.Write(instance.Color); chunkIO.WriteChunkInt(Prj2Chunks.ObjectItemLuaId, instance.LuaId); }); } else if (o is StaticInstance) { chunkIO.WriteChunkWithChildren(Prj2Chunks.ObjectStatic2, () => { var instance = (StaticInstance)o; LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1)); chunkIO.Raw.Write(instance.Position); chunkIO.Raw.Write(instance.RotationY); LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1); chunkIO.Raw.Write(instance.WadObjectId.TypeId); chunkIO.Raw.Write(instance.Color); chunkIO.Raw.Write((int)0); // Unused 32 bit value chunkIO.Raw.Write(instance.Ocb); chunkIO.WriteChunkInt(Prj2Chunks.ObjectItemLuaId, instance.LuaId); }); } else if (o is CameraInstance) { using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectCamera, LEB128.MaximumSize1Byte)) { var instance = (CameraInstance)o; LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1)); chunkIO.Raw.Write(instance.Position); LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1); chunkIO.Raw.Write(instance.Fixed); } } else if (o is FlybyCameraInstance) { chunkIO.WriteChunkWithChildren(Prj2Chunks.ObjectFlyBy, () => { var instance = (FlybyCameraInstance)o; LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1)); chunkIO.Raw.Write(instance.Position); chunkIO.Raw.Write(instance.RotationY); chunkIO.Raw.Write(instance.RotationX); chunkIO.Raw.Write(instance.Roll); LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1); chunkIO.Raw.Write(instance.Speed); chunkIO.Raw.Write(instance.Fov); LEB128.Write(chunkIO.Raw, instance.Flags); LEB128.Write(chunkIO.Raw, instance.Number); LEB128.Write(chunkIO.Raw, instance.Sequence); LEB128.Write(chunkIO.Raw, instance.Timer); }); } else if (o is SinkInstance) { using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectSink, LEB128.MaximumSize1Byte)) { var instance = (SinkInstance)o; LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1)); chunkIO.Raw.Write(instance.Position); LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1); chunkIO.Raw.Write(instance.Strength); } } else if (o is SoundSourceInstance) { using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectSoundSourceFinal, LEB128.MaximumSize1Byte)) { var instance = (SoundSourceInstance)o; LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1)); chunkIO.Raw.Write(instance.Position); chunkIO.Raw.Write(instance.SoundId); chunkIO.Raw.Write((int)instance.PlayMode); LEB128.Write(chunkIO.Raw, -1); } } else if (o is LightInstance) { using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectLight4, LEB128.MaximumSize2Byte)) { var instance = (LightInstance)o; LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1)); LEB128.Write(chunkIO.Raw, (long)instance.Type); chunkIO.Raw.Write(instance.Position); chunkIO.Raw.Write(instance.RotationY); chunkIO.Raw.Write(instance.RotationX); chunkIO.Raw.Write(instance.Intensity); chunkIO.Raw.Write(instance.Color); chunkIO.Raw.Write(instance.InnerRange); chunkIO.Raw.Write(instance.OuterRange); chunkIO.Raw.Write(instance.InnerAngle); chunkIO.Raw.Write(instance.OuterAngle); chunkIO.Raw.Write(instance.Enabled); chunkIO.Raw.Write(instance.IsObstructedByRoomGeometry); chunkIO.Raw.Write(instance.IsDynamicallyUsed); chunkIO.Raw.Write(instance.IsStaticallyUsed); chunkIO.Raw.Write(instance.IsUsedForImportedGeometry); chunkIO.Raw.Write((byte)instance.Quality); } } else if (o is PortalInstance && rooms.ContainsKey(((PortalInstance)o).AdjoiningRoom)) { using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectPortal, LEB128.MaximumSize2Byte)) { var instance = (PortalInstance)o; LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1)); LEB128.Write(chunkIO.Raw, instance.Area.X0); LEB128.Write(chunkIO.Raw, instance.Area.Y0); LEB128.Write(chunkIO.Raw, instance.Area.X1); LEB128.Write(chunkIO.Raw, instance.Area.Y1); LEB128.Write(chunkIO.Raw, rooms[instance.AdjoiningRoom]); chunkIO.Raw.Write((byte)instance.Direction); chunkIO.Raw.Write((byte)instance.Opacity); } } else if (o is GhostBlockInstance) { using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectGhostBlock, LEB128.MaximumSize2Byte)) { var instance = (GhostBlockInstance)o; LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1)); LEB128.Write(chunkIO.Raw, instance.Area.X0); LEB128.Write(chunkIO.Raw, instance.Area.Y0); LEB128.Write(chunkIO.Raw, instance.Floor.XnZn); LEB128.Write(chunkIO.Raw, instance.Floor.XnZp); LEB128.Write(chunkIO.Raw, instance.Floor.XpZn); LEB128.Write(chunkIO.Raw, instance.Floor.XpZp); LEB128.Write(chunkIO.Raw, instance.Ceiling.XnZn); LEB128.Write(chunkIO.Raw, instance.Ceiling.XnZp); LEB128.Write(chunkIO.Raw, instance.Ceiling.XpZn); LEB128.Write(chunkIO.Raw, instance.Ceiling.XpZp); } } else if (o is VolumeInstance) { using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectTriggerVolumeTest, LEB128.MaximumSize2Byte)) { var instance = (VolumeInstance)o; LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1)); var shape = instance.Shape(); chunkIO.Raw.Write((byte)shape); switch (shape) { case VolumeShape.Box: { var bv = instance as BoxVolumeInstance; chunkIO.Raw.Write(bv.Size); chunkIO.Raw.Write(bv.RotationY); chunkIO.Raw.Write(bv.RotationX); } break; case VolumeShape.Prism: { var pv = instance as PrismVolumeInstance; chunkIO.Raw.Write(pv.Scale); chunkIO.Raw.Write(pv.RotationY); } break; case VolumeShape.Sphere: chunkIO.Raw.Write((instance as SphereVolumeInstance).Scale); break; } chunkIO.Raw.Write(instance.Position); chunkIO.Raw.Write((ushort)instance.Activators); chunkIO.Raw.WriteStringUTF8(instance.Scripts.Name); chunkIO.Raw.WriteStringUTF8(instance.Scripts.Environment); chunkIO.Raw.WriteStringUTF8(instance.Scripts.OnEnter); chunkIO.Raw.WriteStringUTF8(instance.Scripts.OnInside); chunkIO.Raw.WriteStringUTF8(instance.Scripts.OnLeave); } } else if (o is TriggerInstance) { using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectTrigger2, LEB128.MaximumSize2Byte)) { Action <ITriggerParameter> writeTriggerParameter = (ITriggerParameter parameter) => { if (parameter is TriggerParameterUshort) { LEB128.Write(chunkIO.Raw, 0); LEB128.Write(chunkIO.Raw, ((TriggerParameterUshort)parameter).Key); } else if (parameter is ObjectInstance) { LEB128.Write(chunkIO.Raw, 1); LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault((ObjectInstance)parameter)); } else if (parameter is Room) { LEB128.Write(chunkIO.Raw, 2); LEB128.Write(chunkIO.Raw, rooms.TryGetOrDefault((Room)parameter)); } else { LEB128.Write(chunkIO.Raw, -1); }; }; var instance = (TriggerInstance)o; LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1)); LEB128.Write(chunkIO.Raw, instance.Area.X0); LEB128.Write(chunkIO.Raw, instance.Area.Y0); LEB128.Write(chunkIO.Raw, instance.Area.X1); LEB128.Write(chunkIO.Raw, instance.Area.Y1); chunkIO.WriteChunkInt(Prj2Chunks.ObjectTrigger2Type, (long)instance.TriggerType); chunkIO.WriteChunkInt(Prj2Chunks.ObjectTrigger2TargetType, (long)instance.TargetType); chunkIO.WriteChunk(Prj2Chunks.ObjectTrigger2Target, () => writeTriggerParameter(instance.Target), 32); chunkIO.WriteChunk(Prj2Chunks.ObjectTrigger2Timer, () => writeTriggerParameter(instance.Timer), 32); chunkIO.WriteChunk(Prj2Chunks.ObjectTrigger2Extra, () => writeTriggerParameter(instance.Extra), 32); chunkIO.WriteChunkInt(Prj2Chunks.ObjectTrigger2CodeBits, instance.CodeBits); chunkIO.WriteChunkBool(Prj2Chunks.ObjectTrigger2OneShot, instance.OneShot); chunkIO.WriteChunkEnd(); } } else if (o is ImportedGeometryInstance) { chunkIO.WriteChunkWithChildren(Prj2Chunks.ObjectImportedGeometry3, () => { var instance = (ImportedGeometryInstance)o; LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1)); chunkIO.Raw.Write(instance.Position); chunkIO.Raw.Write(instance.RotationY); chunkIO.Raw.Write(instance.RotationX); chunkIO.Raw.Write(instance.Roll); chunkIO.Raw.Write(instance.Scale); LEB128.Write(chunkIO.Raw, instance.Model == null ? -1 : levelSettingIds.ImportedGeometries[instance.Model]); chunkIO.WriteChunkInt(Prj2Chunks.ObjectImportedGeometryLightingModel, (int)instance.LightingModel); chunkIO.WriteChunkBool(Prj2Chunks.ObjectImportedGeometrySharpEdges, instance.SharpEdges); chunkIO.WriteChunkBool(Prj2Chunks.ObjectImportedGeometryHidden, instance.Hidden); }); } else { logger.Warn("Object " + o + " not supported."); } } chunkIO.WriteChunkEnd(); }; }
static void Write(ChunkWriter writer) { }
// Constructor. public ZlibCompressor(ChunkWriter writer) { this.writer = writer; this.deflater = new Deflater(); this.outBuffer = new byte [4096]; this.outLen = 0; this.wroteBlock = false; }
// Save a PNG image to the specified stream. public static void Save(Stream stream, PortableImage image) { Frame frame = image.GetFrame(0); byte[] buffer = new byte [1024]; ChunkWriter writer = new ChunkWriter(stream); int colorType, bitDepth; int sigRed, sigGreen, sigBlue, sigAlpha; int paletteSize, posn; int[] palette; ZlibCompressor compressor; ScanlineWriter scanlineWriter; OutputFunc func; int y; // Determine the color type and bit depth for the image. sigRed = -1; sigGreen = -1; sigBlue = -1; sigAlpha = -1; paletteSize = 0; switch (frame.PixelFormat) { case PixelFormat.Format16bppRgb555: { sigRed = 5; sigGreen = 5; sigBlue = 5; colorType = 2; bitDepth = 8; } break; case PixelFormat.Format16bppRgb565: { sigRed = 5; sigGreen = 6; sigBlue = 5; colorType = 2; bitDepth = 8; } break; case PixelFormat.Format24bppRgb: case PixelFormat.Format32bppRgb: { colorType = 2; bitDepth = 8; } break; case PixelFormat.Format1bppIndexed: { colorType = 3; bitDepth = 1; paletteSize = 2; } break; case PixelFormat.Format4bppIndexed: { colorType = 3; bitDepth = 4; paletteSize = 16; } break; case PixelFormat.Format8bppIndexed: { colorType = 3; bitDepth = 8; paletteSize = 256; } break; case PixelFormat.Format16bppArgb1555: { sigRed = 5; sigGreen = 5; sigBlue = 5; sigAlpha = 1; colorType = 6; bitDepth = 8; } break; case PixelFormat.Format32bppPArgb: case PixelFormat.Format32bppArgb: { colorType = 6; bitDepth = 8; } break; case PixelFormat.Format16bppGrayScale: { colorType = 0; bitDepth = 16; } break; case PixelFormat.Format48bppRgb: { colorType = 2; bitDepth = 16; } break; case PixelFormat.Format64bppPArgb: case PixelFormat.Format64bppArgb: { colorType = 6; bitDepth = 16; } break; default: throw new FormatException("unknown format"); } // Write out the PNG magic number. stream.Write(magic, 0, magic.Length); // Write the header chunk. Utils.WriteInt32B(buffer, 0, frame.Width); Utils.WriteInt32B(buffer, 4, frame.Height); buffer[8] = (byte)bitDepth; buffer[9] = (byte)colorType; buffer[10] = (byte)0; // Compression method. buffer[11] = (byte)0; // Filter method. buffer[12] = (byte)0; // Interlace method. writer.Write(PngReader.IHDR, buffer, 0, 13); // Write the significant bits chunk if necessary. if (sigAlpha != -1) { buffer[0] = (byte)sigRed; buffer[1] = (byte)sigGreen; buffer[2] = (byte)sigBlue; buffer[3] = (byte)sigAlpha; writer.Write(PngReader.sBIT, buffer, 0, 4); } else if (sigRed != -1) { buffer[0] = (byte)sigRed; buffer[1] = (byte)sigGreen; buffer[2] = (byte)sigBlue; writer.Write(PngReader.sBIT, buffer, 0, 3); } // Write the palette and transparency chunks. if (paletteSize > 0) { Array.Clear(buffer, 0, buffer.Length); palette = frame.Palette; if (palette != null) { for (posn = 0; posn < palette.Length && posn < paletteSize; ++posn) { buffer[posn * 3] = (byte)(palette[posn] >> 16); buffer[posn * 2 + 1] = (byte)(palette[posn] >> 8); buffer[posn * 2 + 2] = (byte)(palette[posn]); } } writer.Write(PngReader.PLTE, buffer, 0, paletteSize * 3); if (frame.TransparentPixel >= 0 && frame.TransparentPixel < paletteSize) { for (posn = 0; posn < paletteSize; ++posn) { buffer[posn] = (byte)0xFF; } buffer[frame.TransparentPixel] = (byte)0x00; writer.Write(PngReader.tRNS, buffer, 0, frame.TransparentPixel + 1); } } // Compress and write the scanlines to the output stream. compressor = new ZlibCompressor(writer); scanlineWriter = new ScanlineWriter (compressor, frame.Width, frame.PixelFormat); func = GetOutputFunc(frame.PixelFormat); for (y = 0; y < frame.Height; ++y) { func(frame, y, scanlineWriter.Buffer); scanlineWriter.FlushScanline(); } compressor.Finish(); // Write the end chunk. writer.Write(PngReader.IEND, buffer, 0, 0); }
private bool BuildScripts() { string scriptPath = _dstPath + "\\Script.dat"; if (File.Exists(scriptPath)) { File.Delete(scriptPath); } using (var stream = File.OpenWrite(scriptPath)) { var chunkIO = new ChunkWriter(new byte[] { 0x54, 0x52, 0x35, 0x4D }, new BinaryWriterFast(stream)); // Main flags chunkIO.WriteChunk(Tr5MainFlags, () => { LEB128.Write(chunkIO.Raw, (_loadSave ? 1 : 0)); LEB128.Write(chunkIO.Raw, (_playAnyLevel ? 1 : 0)); LEB128.Write(chunkIO.Raw, (_flyCheat ? 1 : 0)); LEB128.Write(chunkIO.Raw, (_diagnostics ? 1 : 0)); LEB128.Write(chunkIO.Raw, _levelFarView); chunkIO.Raw.WriteStringUTF8(_intro); }); // Game strings foreach (var stringsObj in _languageStrings) { chunkIO.WriteChunk(Tr5MainStrings, () => { chunkIO.Raw.WriteStringUTF8(stringsObj.Name); LEB128.Write(chunkIO.Raw, stringsObj.Strings.Count); foreach (var str in stringsObj.Strings) { chunkIO.Raw.WriteStringUTF8(str); } }); } // Audio tracks chunkIO.WriteChunk(Tr5MainAudioTracks, () => { LEB128.Write(chunkIO.Raw, _tracks.Count); foreach (var track in _tracks) { chunkIO.Raw.WriteStringUTF8(track); } }); // Levels foreach (var level in _levels) { chunkIO.WriteChunkWithChildren(Tr5MainLevel, () => { // Level informations chunkIO.WriteChunk(Tr5MainLevelInfo, () => { chunkIO.Raw.WriteStringUTF8(level.FileName); chunkIO.Raw.WriteStringUTF8(level.LoadScreen); chunkIO.Raw.WriteStringUTF8(level.Background); LEB128.Write(chunkIO.Raw, GetStringIndex(level.Name)); LEB128.Write(chunkIO.Raw, level.AudioTrack); }); // Level flags chunkIO.WriteChunk(Tr5MainLevelFlags, () => { LEB128.Write(chunkIO.Raw, (level.Horizon ? 1 : 0)); LEB128.Write(chunkIO.Raw, (level.Sky ? 1 : 0)); LEB128.Write(chunkIO.Raw, (level.ColAddHorizon ? 1 : 0)); LEB128.Write(chunkIO.Raw, (level.Lightning ? 1 : 0)); LEB128.Write(chunkIO.Raw, (level.ResetInventory ? 1 : 0)); LEB128.Write(chunkIO.Raw, level.LaraType); LEB128.Write(chunkIO.Raw, level.UVRotate); LEB128.Write(chunkIO.Raw, (level.LevelFarView != 0 ? level.LevelFarView : _levelFarView)); LEB128.Write(chunkIO.Raw, (level.Rumble ? 1 : 0)); LEB128.Write(chunkIO.Raw, (byte)(level.Weather)); LEB128.Write(chunkIO.Raw, (level.UnlimitedAir ? 1 : 0)); }); // Puzzles and various things foreach (var entry in level.Entries) { if (entry.Command.Name == "Puzzle") { chunkIO.WriteChunk(Tr5MainLevelPuzzle, () => { LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString())); LEB128.Write(chunkIO.Raw, (int)GetStringIndex(entry.Parameters[1].ToString())); for (int j = 2; j < 8; j++) { LEB128.Write(chunkIO.Raw, short.Parse(entry.Parameters[j].ToString())); } }); } else if (entry.Command.Name == "Key") { chunkIO.WriteChunk(Tr5MainLevelKey, () => { LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString())); LEB128.Write(chunkIO.Raw, (int)GetStringIndex(entry.Parameters[1].ToString())); for (int j = 2; j < 8; j++) { LEB128.Write(chunkIO.Raw, short.Parse(entry.Parameters[j].ToString())); } }); } else if (entry.Command.Name == "Pickup") { chunkIO.WriteChunk(Tr5MainLevelPickup, () => { LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString())); LEB128.Write(chunkIO.Raw, (int)GetStringIndex(entry.Parameters[1].ToString())); for (int j = 2; j < 8; j++) { LEB128.Write(chunkIO.Raw, short.Parse(entry.Parameters[j].ToString())); } }); } if (entry.Command.Name == "Examine") { chunkIO.WriteChunk(Tr5MainLevelExamine, () => { LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString())); LEB128.Write(chunkIO.Raw, (int)GetStringIndex(entry.Parameters[1].ToString())); for (int j = 2; j < 8; j++) { LEB128.Write(chunkIO.Raw, short.Parse(entry.Parameters[j].ToString())); } }); } if (entry.Command.Name == "PuzzleCombo") { chunkIO.WriteChunk(Tr5MainLevelPuzzleCombo, () => { LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString())); LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[1].ToString())); LEB128.Write(chunkIO.Raw, (int)GetStringIndex(entry.Parameters[2].ToString())); for (int j = 3; j < 9; j++) { LEB128.Write(chunkIO.Raw, short.Parse(entry.Parameters[j].ToString())); } }); } else if (entry.Command.Name == "KeyCombo") { chunkIO.WriteChunk(Tr5MainLevelKeyCombo, () => { LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString())); LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[1].ToString())); LEB128.Write(chunkIO.Raw, (int)GetStringIndex(entry.Parameters[2].ToString())); for (int j = 3; j < 9; j++) { LEB128.Write(chunkIO.Raw, short.Parse(entry.Parameters[j].ToString())); } }); } else if (entry.Command.Name == "PickupCombo") { chunkIO.WriteChunk(Tr5MainLevelPickupCombo, () => { LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString())); LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[1].ToString())); LEB128.Write(chunkIO.Raw, (int)GetStringIndex(entry.Parameters[2].ToString())); for (int j = 3; j < 9; j++) { LEB128.Write(chunkIO.Raw, short.Parse(entry.Parameters[j].ToString())); } }); } else if (entry.Command.Name == "Layer1") { chunkIO.WriteChunk(Tr5MainLevelLayer, () => { LEB128.Write(chunkIO.Raw, 1); LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString())); LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[1].ToString())); LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[2].ToString())); LEB128.Write(chunkIO.Raw, sbyte.Parse(entry.Parameters[3].ToString())); }); } else if (entry.Command.Name == "Layer2") { chunkIO.WriteChunk(Tr5MainLevelLayer, () => { LEB128.Write(chunkIO.Raw, 2); LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString())); LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[1].ToString())); LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[2].ToString())); LEB128.Write(chunkIO.Raw, sbyte.Parse(entry.Parameters[3].ToString())); }); } else if (entry.Command.Name == "DistantFog") { chunkIO.WriteChunk(Tr5MainLevelLayer, () => { LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString())); LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[1].ToString())); LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[2].ToString())); LEB128.Write(chunkIO.Raw, int.Parse(entry.Parameters[3].ToString())); }); } else if (entry.Command.Name == "OnLevelStart" || entry.Command.Name == "OnLevelFinish" || entry.Command.Name == "OnLoadGame" || entry.Command.Name == "OnSaveGame" || entry.Command.Name == "OnLaraDeath" || entry.Command.Name == "OnLevelControl" || entry.Command.Name == "OnBeginFrame") { chunkIO.WriteChunk(Tr5MainLevelLuaEvent, () => { chunkIO.Raw.WriteStringUTF8(entry.Command.Name); chunkIO.Raw.WriteStringUTF8(entry.Parameters[0].ToString()); }); } } }); } // EOF chunkIO.Raw.Write((int)0); chunkIO.Raw.Flush(); } return(true); }
private void WriteLevelTr5Main() { // Now begin to compile the geometry block in a MemoryStream byte[] geometryDataBuffer; using (var geometryDataStream = new MemoryStream()) { var writer = new BinaryWriterEx(geometryDataStream); // Don't dispose ReportProgress(80, "Writing geometry data to memory buffer"); const int filler = 0; writer.Write(filler); var numRooms = (uint)_level.Rooms.Count(r => r != null); writer.Write(numRooms); foreach (var r in _level.Rooms.Where(r => r != null)) { _tempRooms[r].WriteTr5(writer); } // Write floordata var numFloorData = (uint)_floorData.Count; writer.Write(numFloorData); writer.WriteBlockArray(_floorData); // Write meshes var offset = writer.BaseStream.Position; const int numMeshData = 0; writer.Write(numMeshData); var totalMeshSize = 0; for (var i = 0; i < _meshes.Count; i++) { var meshSize = _meshes[i].WriteTr4AndTr5(writer); totalMeshSize += (int)meshSize; } var offset2 = writer.BaseStream.Position; // ReSharper disable once SuggestVarOrType_BuiltInTypes uint meshDataSize = (uint)((offset2 - offset - 4) / 2); // Save the size of the meshes writer.BaseStream.Seek(offset, SeekOrigin.Begin); writer.Write(meshDataSize); writer.BaseStream.Seek(offset2, SeekOrigin.Begin); // Write mesh pointers writer.Write((uint)_meshPointers.Count); writer.WriteBlockArray(_meshPointers); // Write animations' data writer.Write((uint)_animations.Count); foreach (var anim in _animations) { anim.Write(writer, _level); } writer.Write((uint)_stateChanges.Count); writer.WriteBlockArray(_stateChanges); writer.Write((uint)_animDispatches.Count); writer.WriteBlockArray(_animDispatches); writer.Write((uint)_animCommands.Count); writer.WriteBlockArray(_animCommands); writer.Write((uint)_meshTrees.Count); writer.WriteBlockArray(_meshTrees); writer.Write((uint)_frames.Count); writer.WriteBlockArray(_frames); writer.Write((uint)_moveables.Count); for (var k = 0; k < _moveables.Count; k++) { writer.WriteBlock(_moveables[k]); writer.Write((ushort)0xfeff); } writer.Write((uint)_staticMeshes.Count); writer.WriteBlockArray(_staticMeshes); // SPR block writer.WriteBlockArray(new byte[] { 0x53, 0x50, 0x52, 0x00 }); writer.Write((uint)_spriteTextures.Count); writer.WriteBlockArray(_spriteTextures); writer.Write((uint)_spriteSequences.Count); writer.WriteBlockArray(_spriteSequences); // Write camera, flyby and sound sources writer.Write((uint)_cameras.Count); writer.WriteBlockArray(_cameras); writer.Write((uint)_flyByCameras.Count); writer.WriteBlockArray(_flyByCameras); writer.Write((uint)_soundSources.Count); writer.WriteBlockArray(_soundSources); // Write pathfinding data writer.Write((uint)_boxes.Length); writer.WriteBlockArray(_boxes); writer.Write((uint)_overlaps.Length); writer.WriteBlockArray(_overlaps); for (var i = 0; i < _boxes.Length; i++) { writer.Write(_zones[i].GroundZone1_Normal); } for (var i = 0; i < _boxes.Length; i++) { writer.Write(_zones[i].GroundZone2_Normal); } for (var i = 0; i < _boxes.Length; i++) { writer.Write(_zones[i].GroundZone3_Normal); } for (var i = 0; i < _boxes.Length; i++) { writer.Write(_zones[i].GroundZone4_Normal); } for (var i = 0; i < _boxes.Length; i++) { writer.Write(_zones[i].FlyZone_Normal); } for (var i = 0; i < _boxes.Length; i++) { writer.Write(_zones[i].GroundZone1_Alternate); } for (var i = 0; i < _boxes.Length; i++) { writer.Write(_zones[i].GroundZone2_Alternate); } for (var i = 0; i < _boxes.Length; i++) { writer.Write(_zones[i].GroundZone3_Alternate); } for (var i = 0; i < _boxes.Length; i++) { writer.Write(_zones[i].GroundZone4_Alternate); } for (var i = 0; i < _boxes.Length; i++) { writer.Write(_zones[i].FlyZone_Alternate); } // Write animated textures _textureInfoManager.WriteAnimatedTextures(writer); // Write object textures writer.Write(checked ((byte)_textureInfoManager.UvRotateCount)); writer.Write(new byte[] { 0x54, 0x45, 0x58, 0x00 }); _textureInfoManager.WriteTextureInfos(writer, _level); // Write items and AI objects writer.Write((uint)_items.Count); writer.WriteBlockArray(_items); writer.Write((uint)_aiItems.Count); writer.WriteBlockArray(_aiItems); // Write sound meta data PrepareSoundsData(); WriteSoundMetadata(writer); // Finish it writer.Write((ushort)0xcdcd); writer.Write((ushort)0xcdcd); writer.Write((ushort)0xcdcd); geometryDataBuffer = geometryDataStream.ToArray(); } using (var fs = new FileStream(_dest, FileMode.Create, FileAccess.Write, FileShare.None)) { using (var writer = new BinaryWriterEx(fs)) { ReportProgress(90, "Writing final level"); writer.WriteBlockArray(new byte[] { 0x54, 0x52, 0x34, 0x00 }); ReportProgress(91, "Writing textures"); // The room texture tile count currently also currently contains the wad textures // But lets not bother with those fields too much since they only matter when bump maps are used and we don't use them. writer.Write((ushort)_textureInfoManager.NumRoomPages); writer.Write((ushort)_textureInfoManager.NumObjectsPages); // Bump map pages must be multiplied by 2 or tile index will be wrong writer.Write((ushort)(_textureInfoManager.NumBumpPages * 2)); // Compress data ReportProgress(95, "Compressing data"); byte[] texture32 = null; int texture32UncompressedSize = -1; byte[] texture16 = null; int texture16UncompressedSize = -1; byte[] textureMisc = null; int textureMiscUncompressedSize = -1; byte[] geometryData = geometryDataBuffer; int geometryDataUncompressedSize = geometryData.Length; using (Task Texture32task = Task.Factory.StartNew(() => { texture32 = ZLib.CompressData(_texture32Data); texture32UncompressedSize = _texture32Data.Length; })) using (Task Texture16task = Task.Factory.StartNew(() => { byte[] texture16Data = PackTextureMap32To16Bit(_texture32Data, _level.Settings); texture16 = ZLib.CompressData(texture16Data); texture16UncompressedSize = texture16Data.Length; })) using (Task textureMiscTask = Task.Factory.StartNew(() => { Stream textureMiscData = PrepareFontAndSkyTexture(); textureMisc = ZLib.CompressData(textureMiscData); textureMiscUncompressedSize = (int)textureMiscData.Length; })) Task.WaitAll(Texture32task, Texture16task, textureMiscTask); // Write data ReportProgress(97, "Writing compressed data to file."); writer.Write(texture32UncompressedSize); writer.Write(texture32.Length); writer.Write(texture32); writer.Write(texture16UncompressedSize); writer.Write(texture16.Length); writer.Write(texture16); writer.Write(textureMiscUncompressedSize); writer.Write(textureMisc.Length); writer.Write(textureMisc); writer.Write((ushort)_level.Settings.Tr5LaraType); writer.Write((ushort)_level.Settings.Tr5WeatherType); for (var i = 0; i < 28; i++) { writer.Write((byte)0); } // In TR5 geometry data is not compressed writer.Write(geometryDataUncompressedSize); writer.Write(geometryDataUncompressedSize); writer.Write(geometryData); ReportProgress(98, "Writing WAVE sounds"); WriteSoundData(writer); // Write extra data _volumeScripts = new List <VolumeScriptInstance>(); using (var ms = new MemoryStream()) { var chunkIO = new ChunkWriter(new byte[] { 0x54, 0x52, 0x35, 0x4D }, new BinaryWriterFast(ms)); int currRoom = 0; foreach (var r in _level.Rooms.Where(r => r != null)) { // Add further extra data conditions here, otherwise compiler will skip this room altogether if (r.Volumes.Count() > 0) { currRoom++; } else { currRoom++; continue; } using (var extraRoomDataChunk = chunkIO.WriteChunk(Tr5MainExtraRoomData)) { // First and only param after signature is internal room number chunkIO.Raw.Write(currRoom); using (var volumeListChunk = chunkIO.WriteChunk(Tr5MainChunkVolumeList)) { var trRoom = _tempRooms[r]; foreach (var vol in r.Volumes) { using (var volumeChunk = chunkIO.WriteChunk(Tr5MainChunkVolume)) { int scriptIndex = 0; if (_volumeScripts.Contains(vol.Scripts)) { scriptIndex = _volumeScripts.IndexOf(vol.Scripts); } else { _volumeScripts.Add(vol.Scripts); scriptIndex = _volumeScripts.Count - 1; } // FIXME is it needed? int add = 0; if (vol is BoxVolumeInstance) { add = (int)((vol as BoxVolumeInstance).Size.Y / 2.0f); } var X = (int)Math.Round(trRoom.Info.X + vol.Position.X); var Y = (int)-Math.Round(r.WorldPos.Y + vol.Position.Y + add); var Z = (int)Math.Round(trRoom.Info.Z + vol.Position.Z); if (vol is BoxVolumeInstance) { chunkIO.Raw.Write(0); } else if (vol is SphereVolumeInstance) { chunkIO.Raw.Write(1); } else if (vol is PrismVolumeInstance) { chunkIO.Raw.Write(2); } chunkIO.Raw.Write(X); chunkIO.Raw.Write(Y); chunkIO.Raw.Write(Z); chunkIO.Raw.Write((short)vol.Activators); chunkIO.Raw.Write(scriptIndex); if (vol is BoxVolumeInstance) { var bv = (BoxVolumeInstance)vol; var min = vol.Position - (bv.Size / 2.0f); var max = vol.Position + (bv.Size / 2.0f); var rotY = (ushort)Math.Max(0, Math.Min(ushort.MaxValue, Math.Round(bv.RotationY * (65536.0 / 360.0)))); var rotX = (ushort)Math.Max(0, Math.Min(ushort.MaxValue, Math.Round(bv.RotationX * (65536.0 / 360.0)))); chunkIO.Raw.Write(rotY); chunkIO.Raw.Write(rotX); chunkIO.Raw.Write((short)min.X); chunkIO.Raw.Write((short)min.Y); chunkIO.Raw.Write((short)min.Z); chunkIO.Raw.Write((short)max.X); chunkIO.Raw.Write((short)max.Y); chunkIO.Raw.Write((short)max.Z); } else if (vol is SphereVolumeInstance) { chunkIO.Raw.Write((vol as SphereVolumeInstance).Size); } else if (vol is PrismVolumeInstance) { var pv = (PrismVolumeInstance)vol; chunkIO.Raw.Write(pv.RotationY); chunkIO.Raw.Write(pv.Size); } } } } } } /* * using (var extraDataChunk = chunkIO.WriteChunk(Tr5MainExtraData)) * { * using (var volScriptListChunk = chunkIO.WriteChunk(Tr5MainChunkVolumeScriptList)) * { * for (int i = 0; i < _volumeScripts.Count; i++) * { * var script = _volumeScripts[i]; * using (var volScriptChunk = chunkIO.WriteChunk(Tr5MainChunkVolumeScript)) * { * chunkIO.Raw.WriteStringUTF8(script.Name); * * string onEnter = string.Empty; * string onInside = string.Empty; * string onLeave = string.Empty; * * if (script.OnEnter.Trim().Length > 0) * onEnter = "volscripts[" + i + "].OnEnter = function(activator) \n" + * _indent + script.OnEnter.Replace("\n", "\n" + _indent) + "\n" + "end;"; * * if (script.OnInside.Trim().Length > 0) * onInside = "volscripts[" + i + "].OnInside = function(activator) \n" + * _indent + script.OnInside.Replace("\n", "\n" + _indent) + "\n" + "end;"; * * if (script.OnLeave.Trim().Length > 0) * onLeave = "volscripts[" + i + "].OnLeave = function(activator) \n" + * _indent + script.OnLeave.Replace("\n", "\n" + _indent) + "\n" + "end;"; * * string functionCode = * onEnter + (string.IsNullOrEmpty(onEnter) ? string.Empty : "\n\n") + * onInside + (string.IsNullOrEmpty(onInside) ? string.Empty : "\n\n") + * onLeave + (string.IsNullOrEmpty(onLeave) ? string.Empty : "\n\n") ; * * chunkIO.Raw.WriteStringUTF8(functionCode); * } * } * } * * using (var chunkLuaIds = chunkIO.WriteChunk(Tr5MainChunkLuaIds)) * { * for (int i = 0; i < _luaIdToItems.Count; i++) * { * chunkIO.WriteChunk(Tr5MainChunkLuaId, () => * { * chunkIO.Raw.Write(_luaIdToItems.ElementAt(i).Key); * chunkIO.Raw.Write(_luaIdToItems.ElementAt(i).Value); * }); * } * } * } */ chunkIO.Raw.Flush(); writer.Write((int)(ms.Length + 4)); writer.Write((int)(ms.Length + 4)); writer.Write(ms.ToArray(), 0, (int)ms.Length); writer.Write((int)0); } ReportProgress(99, "Done"); } } }
void StoreSettings(ChunkWriter writer) { }