Пример #1
0
        /// <summary>
        /// Export die enthaltenen SLPs in den gegebenen Ordner.
        /// Reihenfolge der Exports ist wichtig - bei Änderungen im TechTreeEditor-Plugin gegenprüfen!
        /// </summary>
        /// <param name="folder">Der Zielordner.</param>
        /// <param name="baseId">Die erste freie ID, zu der exportiert werden soll.</param>
        /// <param name="broadside">Gibt an, ob die Grafiken zusätzlich im Breitseitenmodus exportiert werden sollen.</param>
        /// <param name="enabledCivSets">Eine Liste mit den zu exportierenden Kultur-Grafiksets.</param>
        public void Export(string folder, int baseId, bool broadside, List <Civ> enabledCivSets)
        {
            // Die aktuell freie ID
            int currId = baseId;

            // Basispfad bauen
            string baseFileName = Path.Combine(folder, Name);

            // Der XML-Projektdatei-Code
            string xmlCode = "";

            // Hilfsfunktion fürs Exportieren
            Action <SLPFile, string> exportSlp = (slp, suffix) =>
            {
                // Exportstruktur anlegen
                DRSLibrary.DRSFile.ExternalFile extFile = new DRSLibrary.DRSFile.ExternalFile();

                // Breitseitenmodus?
                SLPFile slpE = slp;
                if (broadside)
                {
                    // Suffix erweitern
                    suffix += " [B]";

                    // Neue SLP mit umkopierten Frames erzeugen
                    slp.writeData();
                    RAMBuffer tmpBuffer = (RAMBuffer)slp.DataBuffer;
                    tmpBuffer.Position = 0;
                    slpE = new SLPFile(tmpBuffer);
                    slpE._frameInformationHeaders.Clear();
                    slpE._frameInformationData.Clear();

                    // Drehrichtungen vorne bis links (-> links bis hinten)
                    for (int i = 4; i <= 8; ++i)
                    {
                        // Alle Frames der Drehrichtung kopieren
                        for (int f = i * (int)(slp.FrameCount / 9); f < (i + 1) * (int)(slp.FrameCount / 9); ++f)
                        {
                            // Header kopieren
                            SLPFile.FrameInformationHeader fHead = new SLPFile.FrameInformationHeader();
                            fHead.AnchorX    = slp._frameInformationHeaders[f].AnchorX;
                            fHead.AnchorY    = slp._frameInformationHeaders[f].AnchorY;
                            fHead.Width      = slp._frameInformationHeaders[f].Width;
                            fHead.Height     = slp._frameInformationHeaders[f].Height;
                            fHead.Properties = slp._frameInformationHeaders[f].Properties;
                            slpE._frameInformationHeaders.Add(fHead);

                            // Daten kopieren
                            SLPFile.FrameInformationData fData = new SLPFile.FrameInformationData();
                            fData.BinaryCommandTable  = new List <SLPFile.BinaryCommand>(slp._frameInformationData[f].BinaryCommandTable);
                            fData.BinaryRowEdge       = slp._frameInformationData[f].BinaryRowEdge;
                            fData.CommandTable        = slp._frameInformationData[f].CommandTable;
                            fData.CommandTableOffsets = new uint[slp._frameInformationData[f].CommandTableOffsets.Length];
                            fData.RowEdge             = slp._frameInformationData[f].RowEdge;
                            slpE._frameInformationData.Add(fData);
                        }
                    }

                    // Drehrichtungen links links hinten bis hinten (-> hinten hinten rechts bis rechts)
                    for (int i = 7; i >= 4; --i)
                    {
                        // Alle Frames der Drehrichtung spiegeln und kopieren
                        for (int f = i * (int)(slp.FrameCount / 9); f < (i + 1) * (int)(slp.FrameCount / 9); ++f)
                        {
                            // Header kopieren
                            SLPFile.FrameInformationHeader fHead = new SLPFile.FrameInformationHeader();
                            fHead.AnchorX    = (int)slp._frameInformationHeaders[f].Width - slp._frameInformationHeaders[f].AnchorX;
                            fHead.AnchorY    = slp._frameInformationHeaders[f].AnchorY;
                            fHead.Width      = slp._frameInformationHeaders[f].Width;
                            fHead.Height     = slp._frameInformationHeaders[f].Height;
                            fHead.Properties = slp._frameInformationHeaders[f].Properties;
                            slpE._frameInformationHeaders.Add(fHead);

                            // Daten spiegeln und kopieren
                            SLPFile.FrameInformationData fData = new SLPFile.FrameInformationData();
                            fData.BinaryCommandTable = new List <SLPFile.BinaryCommand>();
                            fData.BinaryRowEdge      = new SLPFile.BinaryRowedge[slp._frameInformationData[f].BinaryRowEdge.Length];
                            for (int bre = 0; bre < fData.BinaryRowEdge.Length; ++bre)
                            {
                                fData.BinaryRowEdge[bre] = new SLPFile.BinaryRowedge(slp._frameInformationData[f].BinaryRowEdge[bre]._right, slp._frameInformationData[f].BinaryRowEdge[bre]._left);
                            }
                            fData.RowEdge = new ushort[fHead.Height, 2];
                            for (int re = 0; re < fHead.Height; ++re)
                            {
                                fData.RowEdge[re, 0] = slp._frameInformationData[f].RowEdge[re, 1];
                                fData.RowEdge[re, 1] = slp._frameInformationData[f].RowEdge[re, 0];
                            }
                            fData.CommandTable = new int[fHead.Height, fHead.Width];
                            for (int h = 0; h < fHead.Height; ++h)
                            {
                                for (int w = 0; w < fHead.Width; ++w)
                                {
                                    fData.CommandTable[h, fHead.Width - w - 1] = slp._frameInformationData[f].CommandTable[h, w];
                                }
                            }
                            fData.CommandTableOffsets = new uint[slp._frameInformationData[f].CommandTableOffsets.Length];
                            slpE.CreateBinaryCommandTable(fData, (int)fHead.Width, (int)fHead.Height, slpE._settings);
                            slpE._frameInformationData.Add(fData);
                        }
                    }
                }

                // SLP-Daten lesen und zuweisen
                slpE.writeData();
                RAMBuffer slpBuffer = (RAMBuffer)slpE.DataBuffer;
                slpBuffer.Position = 0;
                extFile.Data       = slpBuffer.ReadByteArray(slpBuffer.Length);

                // Metadaten festlegen
                extFile.DRSFile      = "graphics";
                extFile.FileID       = (uint)(currId++);
                extFile.ResourceType = "slp";

                // Exportdatei speichern
                extFile.ToBinary().Save(Path.Combine(folder, extFile.FileID + ".res"));

                // XML-Code generieren
                xmlCode += "<ResFile>" + extFile.FileID + ".res</ResFile>\r\n";

                // SLP speichern
                if (!string.IsNullOrEmpty(suffix))
                {
                    slpBuffer.Save(baseFileName + " " + suffix + ".slp");
                }
                else
                {
                    slpBuffer.Save(baseFileName + ".slp");
                }
            };

            // Schatten und Rumpf exportieren
            if (ShadowSlp != null)
            {
                exportSlp(ShadowSlp, "(Schatten)");
            }
            if (BaseSlp != null)
            {
                exportSlp(BaseSlp, "");
            }

            // Hilfsfunktion für Segel-Export (Reihenfolge wichtig für ID-Vergabe)
            Action <Civ> exportCivSails = (civ) =>
            {
                // Segel exportieren
                if (Sails[Sail.SailType.MainGo].Used)
                {
                    exportSlp(Sails[Sail.SailType.MainGo].SailSlps[civ], "(" + Sail.SailTypeNames[Sail.SailType.MainGo] + ") [" + CivNames[civ] + "]");
                }
                if (Sails[Sail.SailType.Small1].Used)
                {
                    exportSlp(Sails[Sail.SailType.Small1].SailSlps[civ], "(" + Sail.SailTypeNames[Sail.SailType.Small1] + ") [" + CivNames[civ] + "]");
                }
                if (Sails[Sail.SailType.Mid1].Used)
                {
                    exportSlp(Sails[Sail.SailType.Mid1].SailSlps[civ], "(" + Sail.SailTypeNames[Sail.SailType.Mid1] + ") [" + CivNames[civ] + "]");
                }
                if (Sails[Sail.SailType.Large1].Used)
                {
                    exportSlp(Sails[Sail.SailType.Large1].SailSlps[civ], "(" + Sail.SailTypeNames[Sail.SailType.Large1] + ") [" + CivNames[civ] + "]");
                }
                if (Sails[Sail.SailType.MainStop].Used)
                {
                    exportSlp(Sails[Sail.SailType.MainStop].SailSlps[civ], "(" + Sail.SailTypeNames[Sail.SailType.MainStop] + ") [" + CivNames[civ] + "]");
                }
                if (Sails[Sail.SailType.Large2].Used)
                {
                    exportSlp(Sails[Sail.SailType.Large2].SailSlps[civ], "(" + Sail.SailTypeNames[Sail.SailType.Large2] + ") [" + CivNames[civ] + "]");
                }
                if (Sails[Sail.SailType.Mid2].Used)
                {
                    exportSlp(Sails[Sail.SailType.Mid2].SailSlps[civ], "(" + Sail.SailTypeNames[Sail.SailType.Mid2] + ") [" + CivNames[civ] + "]");
                }
                if (Sails[Sail.SailType.Small2].Used)
                {
                    exportSlp(Sails[Sail.SailType.Small2].SailSlps[civ], "(" + Sail.SailTypeNames[Sail.SailType.Small2] + ") [" + CivNames[civ] + "]");
                }
            };

            // Segel kulturweise exportieren
            foreach (Civ civSet in enabledCivSets)
            {
                exportCivSails(civSet);
            }

            // XML-Code speichern
            File.WriteAllText(Path.Combine(folder, "projectdata" + (broadside ? "_b" : "") + ".xml"), xmlCode);

            // Ggf. noch die Nicht-Breitseiten-Frames exportieren
            if (broadside)
            {
                Export(folder, currId, false, enabledCivSets);
            }
        }
Пример #2
0
        /// <summary>
        /// Updates the currently displayed frames when the projectile frame delay is changed.
        /// </summary>
        private void UpdateDisplayedFrames()
        {
            // Are any DRS files loaded? Are there drawable frames?
            if (_drs1 == null && _drs2 == null || _drawnImages.Count == 0)
            {
                return;
            }

            // Ensure frame delay is in range
            int frameDelay = CurrentUnitEntry.Value.ProjectileFrameDelay % _currentUnitGraphic.FrameCount;

            // Generate and assign frames
            for (short a = 0; a < _drawnImages.Count; ++a)
            {
                // Get frame ID
                int frameId = frameDelay + a * _currentUnitGraphic.FrameCount;

                // Calculate combined frame dimensions while setting the anchor point to (0, 0)
                OffsetData frameDimensions = new OffsetData(0, 0, 0, 0);

                // Store considered SLPs for later drawing
                // Tuple: frameId, anchorX, anchorY, slpObject
                // slpObject == null --> redraw main SLP
                var drawnSlpFrames = new List <Tuple <int, int, int, SLPFile> >();

                // Check primary SLP
                SLPFile primarySlp = null;
                SLPFile.FrameInformationHeader primarySlpFrameHeader = null;
                if (_currentUnitGraphic.SLP >= 0 && _slps.ContainsKey((ushort)_currentUnitGraphic.SLP))
                {
                    // Get SLP
                    primarySlp = _slps[(ushort)_currentUnitGraphic.SLP];

                    // Update dimensions
                    primarySlpFrameHeader  = primarySlp._frameInformationHeaders[frameId];
                    frameDimensions.Left   = primarySlpFrameHeader.AnchorX;
                    frameDimensions.Top    = primarySlpFrameHeader.AnchorY;
                    frameDimensions.Right  = (int)primarySlpFrameHeader.Width - primarySlpFrameHeader.AnchorX;
                    frameDimensions.Bottom = (int)primarySlpFrameHeader.Height - primarySlpFrameHeader.AnchorY;

                    // Add SLP to render list
                    // Only if no deltas are present, else the primary graphic should be drawn explicitly
                    if (_renderedDeltas.Count == 0)
                    {
                        drawnSlpFrames.Add(new Tuple <int, int, int, SLPFile>(frameId, primarySlpFrameHeader.AnchorX, primarySlpFrameHeader.AnchorY, primarySlp));
                    }
                }

                // Check deltas
                foreach (var currDelta in _renderedDeltas)
                {
                    // Redrawer?
                    if (currDelta.GraphicID == -1 && primarySlp != null)
                    {
                        drawnSlpFrames.Add(new Tuple <int, int, int, SLPFile>(frameId, primarySlpFrameHeader.AnchorX, primarySlpFrameHeader.AnchorY, primarySlp));
                    }
                    else if (currDelta.GraphicID != -1)
                    {
                        // Get graphic and SLP
                        var     currDeltaGraphic = _genieFile.Graphics[currDelta.GraphicID];
                        SLPFile currDeltaSlp     = _slps[(ushort)currDeltaGraphic.SLP];

                        // Update dimensions
                        int currDeltaFrameId = GetCorrespondingFrameId(frameId, _currentUnitGraphic, currDeltaGraphic);
                        SLPFile.FrameInformationHeader frameHeader = currDeltaSlp._frameInformationHeaders[currDeltaFrameId];
                        frameDimensions.Left   = Math.Max(frameDimensions.Left, frameHeader.AnchorX + currDelta.DirectionX);
                        frameDimensions.Top    = Math.Max(frameDimensions.Top, frameHeader.AnchorY + currDelta.DirectionY);
                        frameDimensions.Right  = Math.Max(frameDimensions.Right, (int)frameHeader.Width - (frameHeader.AnchorX + currDelta.DirectionX));
                        frameDimensions.Bottom = Math.Max(frameDimensions.Bottom, (int)frameHeader.Height - (frameHeader.AnchorY + currDelta.DirectionY));

                        // Add delta SLP to render list
                        drawnSlpFrames.Add(new Tuple <int, int, int, SLPFile>(currDeltaFrameId, frameHeader.AnchorX + currDelta.DirectionX, frameHeader.AnchorY + currDelta.DirectionY, currDeltaSlp));
                    }
                }

                // Render frame if neccessary
                if (!_precomputedUnitFrames.ContainsKey(frameId))
                {
                    // Fall back to empty image if there are no graphics to be drawn
                    if (drawnSlpFrames.Count == 0)
                    {
                        _precomputedUnitFrames[frameId] = new System.Drawing.Bitmap(1, 1).ToImageSource();
                    }
                    else
                    {
                        // Create bitmap
                        // 'using' environment to free memory correctly, avoiding OutOfMemory exceptions
                        using (System.Drawing.Bitmap currFrame = new System.Drawing.Bitmap(frameDimensions.Left + frameDimensions.Right, frameDimensions.Top + frameDimensions.Bottom))
                        {
                            // Draw on bitmap
                            using (System.Drawing.Graphics currFrameG = System.Drawing.Graphics.FromImage(currFrame))
                            {
                                // Get main frame
                                System.Drawing.Bitmap primarySlpFrame =
                                    (primarySlpFrameHeader == null
                                                                        ? null
                                                                        : primarySlp.getFrameAsBitmap((uint)frameId, Pal50500, SLPFile.Masks.Graphic, System.Drawing.Color.FromArgb(0, 0, 0, 0),
                                                                                                      System.Drawing.Color.FromArgb(100, 100, 100, 100))
                                    );

                                // Go through render list and render main image and deltas
                                foreach (Tuple <int, int, int, SLPFile> currRenderEntry in drawnSlpFrames)
                                {
                                    // Draw main frame?
                                    if (currRenderEntry.Item4 == primarySlp)
                                    {
                                        // Ensure that main frame exists
                                        if (primarySlpFrame != null)
                                        {
                                            currFrameG.DrawImage(primarySlpFrame, frameDimensions.Left - primarySlpFrameHeader.AnchorX, frameDimensions.Top - primarySlpFrameHeader.AnchorY);
                                        }
                                    }
                                    else
                                    {
                                        // Draw delta frame
                                        currFrameG.DrawImage(currRenderEntry.Item4.getFrameAsBitmap((uint)currRenderEntry.Item1, Pal50500, SLPFile.Masks.Graphic, System.Drawing.Color.FromArgb(0, 0, 0, 0),
                                                                                                    System.Drawing.Color.FromArgb(100, 100, 100, 100)), frameDimensions.Left - currRenderEntry.Item2, frameDimensions.Top - currRenderEntry.Item3);
                                    }
                                }
                            }
                            _precomputedUnitFrames[frameId] = currFrame.ToImageSource();
                        }
                    }
                }

                // Assign to drawn image objects
                _drawnImages[a].Source = _precomputedUnitFrames[frameId];
                _drawnImages[a].Width  = _precomputedUnitFrames[frameId].Width;
                _drawnImages[a].Height = _precomputedUnitFrames[frameId].Height;
                _anchors[a]            = new Point(frameDimensions.Left, frameDimensions.Top);      // Frame anchor point

                // Calculate bounds including the anchor point
                _maxFrameOffsets.Left   = Math.Max(_maxFrameOffsets.Left, frameDimensions.Left);
                _maxFrameOffsets.Right  = Math.Max(_maxFrameOffsets.Right, frameDimensions.Right);
                _maxFrameOffsets.Top    = Math.Max(_maxFrameOffsets.Top, frameDimensions.Top);
                _maxFrameOffsets.Bottom = Math.Max(_maxFrameOffsets.Bottom, frameDimensions.Bottom);
            }

            // Update positions
            UpdatePositions();
        }