示例#1
0
    public EQArchiveFile AsFormat(string NewFormat, bool ChangeExtension)
    {
        if ((NewFormat == null) || (NewFormat == "") || (this.GetImage() == null))
        {
            return(this);
        }

        NewFormat = NewFormat.ToLower();

        if (NewFormat == "auto")
        {
            switch (GetAlphaBits())
            {
            case 0:
            case 1:
                NewFormat = "16-bit";
                break;

            case 8:
                NewFormat = "32-bit";
                break;

            default:     // ?
                NewFormat = "32-bit";
                break;
            }
        }

        EQArchiveFile _newFile = null;

        if (NewFormat != this.ImageFormat)
        {
            _newFile          = new EQArchiveFile();
            _newFile.Filename = this.Filename;
            _newFile.SetImage(this.GetImage(), NewFormat);
        }

        if (ChangeExtension && !System.IO.Path.GetExtension(this.Filename).Equals((NewFormat[0] == '.' ? NewFormat : ".dds"), StringComparison.CurrentCultureIgnoreCase))
        {
            // Gotta change the extension

            if (_newFile == null)
            {
                _newFile = new EQArchiveFile();
                _newFile.SetContents(this.GetContents());
            }

            _newFile.Filename = System.IO.Path.GetFileNameWithoutExtension(this.Filename) + (NewFormat[0] == '.' ? NewFormat : ".dds");
        }
        else
        {
            if (_newFile == null)
            {
                _newFile = this; // Unchanged from our current contents
            }
            else
            {
                _newFile.Filename = this.Filename;
            }
        }

        return(_newFile);
    }
示例#2
0
    public Result Save()
    {
        if ((this.FilePath == "") || (this.Filename == "(Untitled)") || (this.Filename == ""))
        {
            return(Result.InvalidArgument);
        }

        Result _result = Result.OK;

        try
        {
            using (BinaryWriter _file = new BinaryWriter(File.Create(this.FilePath + @"\" + this.Filename)))
            {
                //
                //    Step 1 - Get an order of files by filename CRC, per standard PFS archive practice.
                //

                SortedList <UInt32, EQArchiveFile> _filesByCRC = new SortedList <UInt32, EQArchiveFile>();

                foreach (EQArchiveFile _entry in this.Files.Values)
                {
                    _filesByCRC.Add(GetFilenameCRC(_entry.Filename), _entry);
                }

                //
                //    Step 2 - Build the directory of filenames and compress it for adding at the end of the archive
                //

                EQArchiveFile _directory = new EQArchiveFile();

                byte[] _directoryBytes = new byte[64 * 1024]; // global_chr.s3d = ~29,000 bytes of filenames!

                using (BinaryWriter _stream = new BinaryWriter(new MemoryStream(_directoryBytes)))
                {
                    UInt32 _directorySize = 0;

                    _stream.Write((UInt32)this.Files.Count);

                    foreach (EQArchiveFile _entry in _filesByCRC.Values)
                    {
                        _stream.Write((UInt32)_entry.Filename.Length + 1);
                        foreach (char _c in _entry.Filename)
                        {
                            _stream.Write(_c);
                        }
                        _stream.Write('\0');
                    }

                    _directorySize = (UInt32)_stream.BaseStream.Position;

                    Array.Resize <byte>(ref _directoryBytes, (int)_directorySize);

                    _directory.SetContents(_directoryBytes);
                }

                //
                //    Step 3 - Build the file header
                //

                Header _header = new Header();
                _header.MagicNumber   = _MagicNumber;
                _header.VersionNumber = 0x00020000;

                // a. Index Pointer must be determined. Start with the size after the header itself
                _header.IndexPointer = 4 + 4 + 4;

                // b. Add in the size of all of the compressed chunks and their two size values
                foreach (EQArchiveFile _entry in this.Files.Values)
                {
                    _header.IndexPointer += (4 + 4) * (_entry.CompressedChunks == null ? 1 : (UInt32)_entry.CompressedChunks.Count);
                    _header.IndexPointer += _entry.Size.Compressed;
                }

                // c. Add in the size of the compressed filename directory and its size values
                _header.IndexPointer += (4 + 4) * (UInt32)_directory.CompressedChunks.Count + _directory.Size.Compressed;

                //
                //    Step 4 - Write the file Header
                //

                _file.Write(_header.IndexPointer);
                _file.Write(_header.MagicNumber);
                _file.Write(_header.VersionNumber);

                //
                //    Step 5 - Compressed File Chunks
                //
                foreach (EQArchiveFile _entry in _filesByCRC.Values)
                {
                    _entry.FilePointer = (UInt32)_file.BaseStream.Position;

                    foreach (EQArchiveFile.Chunk _chunk in _entry.CompressedChunks)
                    {
                        _file.Write(_chunk.Size.Compressed);
                        _file.Write(_chunk.Size.Uncompressed);
                        _file.Write(_chunk.CompressedData, 0, (int)_chunk.Size.Compressed);
                    }
                }

                //
                //    Step 6 - Filename Directory compressed chunks at the end
                //
                _directory.FilePointer = (UInt32)_file.BaseStream.Position;

                foreach (EQArchiveFile.Chunk _chunk in _directory.CompressedChunks)
                {
                    _file.Write(_chunk.Size.Compressed);
                    _file.Write(_chunk.Size.Uncompressed);
                    _file.Write(_chunk.CompressedData, 0, (int)_chunk.Size.Compressed);
                }

                //
                //    Step 7 - Index of File Entries
                //
                _file.Write((UInt32)(this.Files.Count + 1));

                foreach (KeyValuePair <UInt32, EQArchiveFile> _kvp in _filesByCRC)
                {
                    _file.Write(_kvp.Key);
                    _file.Write(_kvp.Value.FilePointer);
                    _file.Write(_kvp.Value.Size.Uncompressed);
                }

                //
                //    Step 8 - Add filename directory to end of index
                //

                _file.Write(0xFFFFFFFFU);
                _file.Write(_directory.FilePointer);
                _file.Write(_directory.Size.Uncompressed);

                //
                //    Step 9 - PFS Footer
                //

                foreach (char _letter in _FooterToken)
                {
                    _file.Write(_letter);
                }

                _file.Write(_header.DateStamp);

                _file.Close();
            }
        }
        catch
        {
            return(Result.FileWriteError);
        }

        if (_result == Result.OK)
        {
            this.IsDirty = false;
        }

        return(_result);
    }