예제 #1
0
        /// <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));
        }
예제 #2
0
        /*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);
        }
예제 #3
0
        /// <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));
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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());
                }
        }
예제 #6
0
        /// <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);
            }
        }
예제 #7
0
        /// <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);
            }
        }
예제 #8
0
            /// <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);
            }
예제 #9
0
        /// <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);
        }
예제 #10
0
        /// <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;
                        }
                    }
                }
            }
        }