/// <summary> /// Writes the data element into the given buffer (at its current position). /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized into.</param> public void WriteData(RAMBuffer buffer) { ScenarioDataElementTools.AssertListLength(DisabledTechsPerPlayer, 16); DisabledTechsPerPlayer.ForEach(p => buffer.WriteInteger(p.Count)); DisabledTechsPerPlayer.ForEach(p => { p.ForEach(e => buffer.WriteUInteger(e)); buffer.Write(new byte[4 * (30 - p.Count)]); }); ScenarioDataElementTools.AssertListLength(DisabledUnitsPerPlayer, 16); DisabledUnitsPerPlayer.ForEach(p => buffer.WriteInteger(p.Count)); DisabledUnitsPerPlayer.ForEach(p => { p.ForEach(e => buffer.WriteUInteger(e)); buffer.Write(new byte[4 * (30 - p.Count)]); }); ScenarioDataElementTools.AssertListLength(DisabledBuildingsPerPlayer, 16); DisabledBuildingsPerPlayer.ForEach(p => buffer.WriteInteger(p.Count)); DisabledBuildingsPerPlayer.ForEach(p => { p.ForEach(e => buffer.WriteUInteger(e)); buffer.Write(new byte[4 * (20 - p.Count)]); }); buffer.WriteUInteger(Unused1); buffer.WriteUInteger(Unused2); buffer.WriteUInteger(FullTechMode); ScenarioDataElementTools.AssertListLength(StartingAges, 16); StartingAges.ForEach(a => buffer.WriteInteger(a)); }
/*void func(Sail.SailType type, Civ civ, byte[] data) * { * SLPFile s = new SLPFile(new RAMBuffer(data)); * for(int f = 0; f < 90; ++f) * { * s._frameInformationHeaders[f].AnchorX = Sails[type].SailSlps[civ]._frameInformationHeaders[10 * ((f / 10) / 2) + (f % 10)].AnchorX; * s._frameInformationHeaders[f].AnchorY = Sails[type].SailSlps[civ]._frameInformationHeaders[10 * ((f / 10) / 2) + (f % 10)].AnchorY; * } * Sails[type].SailSlps[civ] = s; * }*/ /// <summary> /// Speichert die Schiffsdaten in der angegebenen Datei. /// </summary> /// <param name="filename">Die Zieldatei.</param> public void Save(string filename) { // Puffer erstellen RAMBuffer buffer = new RAMBuffer(); // Name schreiben buffer.WriteInteger(Name.Length); buffer.WriteString(Name); // Rumpf-SLP schreiben if (BaseSlp != null) { // SLP schreiben buffer.WriteByte(1); BaseSlp.writeData(); buffer.Write((RAMBuffer)BaseSlp.DataBuffer); } else { buffer.WriteByte(0); } // Schatten-SLP schreiben if (ShadowSlp != null) { // SLP schreiben buffer.WriteByte(1); ShadowSlp.writeData(); buffer.Write((RAMBuffer)ShadowSlp.DataBuffer); } else { buffer.WriteByte(0); } // Segel schreiben buffer.WriteByte((byte)Sails.Count); foreach (var currSail in Sails) { // Schreiben buffer.WriteByte((byte)currSail.Key); currSail.Value.WriteData(buffer); } // Invertierte Segel schreiben buffer.WriteByte((byte)InvertedSails.Count); foreach (var invSail in InvertedSails) { buffer.WriteByte((byte)invSail); } // Speichern buffer.Save(filename); }
/// <summary> /// Writes the data element into the given buffer (at its current position). /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized into.</param> public void WriteData(RAMBuffer buffer) { ScenarioDataElementTools.AssertListLength(StancesPerPlayer, 16); StancesPerPlayer.ForEach(s => s.WriteData(buffer)); buffer.Write(new byte[11520]); buffer.WriteUInteger(0xFFFFFF9D); ScenarioDataElementTools.AssertListLength(AlliedVictoryObsolete, 16); AlliedVictoryObsolete.ForEach(av => buffer.WriteUInteger(av)); }
/// <summary> /// Schreibt einen String der gegebenen Länge. Falls der String kürzer ist, wird der Rest mit 0-Bytes aufgefüllt. /// </summary> /// <param name="buffer">Der Puffer, in den der String geschrieben werden soll.</param> /// <param name="value">Der zu schreibende String.</param> /// <param name="length">Die Soll-Länge des zu schreibenden Strings.</param> private void WriteString(RAMBuffer buffer, string value, int length) { // Byte-Array anlegen byte[] val = new byte[length]; // String in Byte-Array kopieren, dabei maximal length Zeichen berücksichtigen Encoding.Default.GetBytes(value.Substring(0, Math.Min(length, value.Length))).CopyTo(val, 0); // Wert in den Puffer schreiben buffer.Write(val); }
/// <summary> /// Serializes the data elements into the internal buffer. /// </summary> /// <remarks></remarks> private void WriteData() { // Initialize buffer if (_buffer == null) { _buffer = new RAMBuffer(); } else if (_buffer.Length != 0) { _buffer.Clear(); } // Write header _buffer.WriteString("1.21", 4); _buffer.WriteUInteger(4 + 4 + 4 + (uint)ScenarioInstructions.Length + 4 + 4); _buffer.WriteInteger(2); _buffer.WriteUInteger(LastSaveTimestamp); _buffer.WriteInteger(ScenarioInstructions.Length); _buffer.WriteString(ScenarioInstructions); _buffer.WriteUInteger(0); _buffer.WriteUInteger(PlayerCount); // Create buffer for compressed data elements RAMBuffer comprBuffer = new RAMBuffer(); Header.WriteData(comprBuffer); MessagesCinematics.WriteData(comprBuffer); PlayerAiResources.WriteData(comprBuffer); GlobalVictory.WriteData(comprBuffer); Diplomacy.WriteData(comprBuffer); Disables.WriteData(comprBuffer); Map.WriteData(comprBuffer); Units.WriteData(comprBuffer); PlayerDiplomacyVarious.WriteData(comprBuffer); Triggers.WriteData(comprBuffer); IncludedFiles.WriteData(comprBuffer); // Compress data and copy to main buffer using (MemoryStream output = new MemoryStream()) using (MemoryStream input = comprBuffer.ToMemoryStream()) { // Create compressor stream using (DeflateStream compressor = new DeflateStream(output, CompressionMode.Compress)) { // Compress input.CopyTo(compressor); input.Close(); } // Save compressed data into main buffer _buffer.Write(output.ToArray()); } }
/// <summary> /// Schreibt alle Farbdaten als Bitmap-Farbtabelle in den angegebenen Puffer. /// </summary> /// <param name="buffer">Der zu verwendende Puffer.</param> public void ToBinary(ref RAMBuffer buffer) { // Einträge einzeln durchgehen for (int i = 0; i < 256; i++) { // 4 Bytes nehmen (d.h. einen Tabelleneintrag) byte[] b = { _colors[i].B, _colors[i].G, _colors[i].R, 0 }; // Bytes schreiben buffer.Write(b); } }
/// <summary> /// Schreibt die Daten in den gegebenen Puffer. /// </summary> /// <param name="buffer">Der Puffer, in den die Daten geschrieben werden sollen.</param> public void WriteData(RAMBuffer buffer) { // Benutzung schreiben buffer.WriteByte(Used ? (byte)1 : (byte)0); // Durch SLPs iterieren und schreiben buffer.WriteByte((byte)SailSlps.Count); foreach (var currSlp in SailSlps) { // Schreiben buffer.WriteByte((byte)currSlp.Key); currSlp.Value.writeData(); buffer.Write((RAMBuffer)currSlp.Value.DataBuffer); } }
/// <summary> /// Wandelt die Struktur in ein exportierbares Binärformat um. /// </summary> /// <returns></returns> public RAMBuffer ToBinary() { // Puffer erstellen RAMBuffer buff = new RAMBuffer(); // DRS-Dateiname buff.WriteUInteger((uint)DRSFile.Length); buff.WriteString(DRSFile); // Datei-ID buff.WriteUInteger(FileID); // Ressourcen-Typ buff.WriteUInteger((uint)ResourceType.Length); buff.WriteString(ResourceType); // Data buff.WriteUInteger((uint)Data.Length); buff.Write(Data); // Fertig return(buff); }
/// <summary> /// Speichert die enthaltene Bitmap in den angegebenen Puffer. /// </summary> /// <param name="buffer">Der Puffer, in den das Bild gespeichert werden soll.</param> /// <param name="writeFileHeader">Optional. Gibt an, ob der Dateiheader geschrieben werden oder direkt mit der BITMAPINFOHEADER-Struktur begonnen werden soll.</param> public void SaveToBuffer(RAMBuffer buffer, bool writeFileHeader = true) { // Bilddatenbreite ggf. auf ein Vielfaches von 4 Bytes erhöhen int width = _header.width; // Hilfsvariable zur Performanceerhöhung (immer gleichwertig mit _header.width) int width2 = width; while (width2 % 4 != 0) { width2++; } // Bilddaten-Binär-Zielarray erstellen _imageDataBin = new byte[width2 * Math.Abs(_header.height)]; // Bilddaten in Zielarray schreiben int height2 = Math.Abs(_header.height); for (int x = 0; x < width2; x++) // Start: Links { for (int y = 0; y < height2; y++) // Start: Oben { if (x >= width) { // Falls x außerhalb der Bildbreite liegt, Füllbyte einsetzen _imageDataBin[y * width2 + x] = 0; } else { // Normaler Pixel: Farbtabellenindex schreiben, dabei Bottom-Up-Richtung beachten _imageDataBin[y * width2 + x] = _imageData[(height2 - y - 1) * width + x]; } } } // Header vorbereiten (einige wurden zwar schon definiert, aber lieber alle beisammen) _header.type = 19778; _header.fileSize = (uint)(44 + 256 * 4 + _imageDataBin.Length); _header.reserved = 0; _header.offsetData = (uint)(44 + 256 * 4); _header.imageHeaderSize = 40; _header.width = width; _header.height = height2; _header.layerCount = 1; _header.bitsPerPixel = 8; _header.compression = Header.COMPR_RGB; _header.size = (uint)(height2 * width); _header.xDPI = 0; _header.yDPI = 0; _header.colorCount = 0; _header.colorImportantCount = 0; // Header schreiben if (writeFileHeader) { buffer.WriteUShort(_header.type); buffer.WriteUInteger(_header.fileSize); buffer.WriteUInteger(_header.reserved); buffer.WriteUInteger(_header.offsetData); } buffer.WriteUInteger(_header.imageHeaderSize); buffer.WriteInteger(_header.width); buffer.WriteInteger(_header.height); buffer.WriteUShort(_header.layerCount); buffer.WriteUShort(_header.bitsPerPixel); buffer.WriteUInteger(_header.compression); buffer.WriteUInteger(_header.size); buffer.WriteInteger(_header.xDPI); buffer.WriteInteger(_header.yDPI); buffer.WriteUInteger(_header.colorCount); buffer.WriteUInteger(_header.colorImportantCount); // Farbtabelle schreiben _colorTable.ToBinary(ref buffer); // Bilddaten schreiben buffer.Write(_imageDataBin); }
/// <summary> /// Schreibt die enthaltenen Daten in das interne RAMBuffer-Objekt. /// </summary> /// <remarks></remarks> public void WriteData() { // Puffer initialisieren _buffer = new RAMBuffer(); // --- HEADER --- WriteString(_buffer, _header.Copyright, 40); WriteString(_buffer, _header.Version, 4); WriteString(_buffer, _header.FileType, 12); _buffer.WriteUInteger(_header.TableCount); // ErsteDateiOffset wird vor den Tabellen berechnet, daher erstmal 0 _buffer.WriteUInteger(0); // Erstes Tabellen-Offset ausrechnen Hilft bei der Geschwindigkeitserhöhung beim TABELLEN-Prozess uint aktTableOffset = (uint)(_buffer.Position + _tableInfos.Count * 12); // --- TABELLENINFORMATIONEN --- TableInfo currTableInfo; for (int i = 0; i < _tableInfos.Count; ++i) { // Tabelleninformationen holen currTableInfo = _tableInfos[i]; // Werte schreiben _buffer.WriteByte(currTableInfo.Unknown1); WriteString(_buffer, currTableInfo.ResourceType, 3); _buffer.WriteUInteger(aktTableOffset); _buffer.WriteUInteger(currTableInfo.FileCount); // Offset erhöhen aktTableOffset += currTableInfo.FileCount * 12; } // Erstes Datei-Offset ausrechnen Hilft bei der Geschwindigkeitserhöhung beim DATEIEN-Prozess uint aktFileOffset = (uint)_buffer.Position; for (int i = 0; i < _tables.Count; ++i) { aktFileOffset += (uint)(_tables[i].Entries.Count * 12); } // Header->ErsteDateiOffset uint aktPos = (uint)_buffer.Position; _buffer.Position = 60; _buffer.WriteUInteger(aktFileOffset); _buffer.Position = (int)aktPos; // --- TABELLEN --- Table currTable; TableEntry currEntry; for (int i = 0; i < _tables.Count; ++i) { // Tabelle abrufen currTable = _tables[i]; // Einträge schreiben for (int j = 0; j < currTable.Entries.Count; ++j) { // Eintrag abrufen currEntry = currTable.Entries[j]; // Werte schreiben _buffer.WriteUInteger(currEntry.FileID); _buffer.WriteUInteger(aktFileOffset); _buffer.WriteUInteger(currEntry.FileSize); // Offset erhöhen aktFileOffset += currEntry.FileSize; } } // --- DATEIEN --- foreach (Table aktT in _tables) { // Alle Einträge durchlaufen foreach (TableEntry currE in aktT.Entries) { // Zum Eintrag gehörige Datei suchen foreach (KeyValuePair <uint, byte[]> currFile in _files) { // Datei gefunden? if (currE.FileID == currFile.Key) { _buffer.Write(currFile.Value); break; } } } } }