static bool PackFiles(string[] args)
        {
            // Parse parameters, validate.

            if (args[1].Length > 4) {
                Console.WriteLine("Creator id " + args[1] + " must be 4 chars or less.");
                return false;
            }
            string strCreatorId = args[1];
            string strFullPathPdb = Path.GetFullPath(args[2]);
            string strFilePdb = Path.GetFileName(strFullPathPdb);
            string strDirPdb = Path.GetDirectoryName(strFullPathPdb);
            if (strDirPdb == "")
                strDirPdb = ".";
            if (strFilePdb.Length > 31) {
                Console.WriteLine("Pdb filename " + strFilePdb + " must be 31 characters or less.");
                return false;
            }
            string strFileSpec;
            if (args.Length == 3) {
                strFileSpec = ".\\*.*";
            } else {
                strFileSpec = args[3];
            }

            // Get list of files to add

            string strFileFileSpecAdd = Path.GetFileName(strFileSpec);
            string strDirFileSpecAdd = Path.GetDirectoryName(strFileSpec);
            if (strDirFileSpecAdd == "")
                strDirFileSpecAdd = ".";
            string[] astrFilesAdd = Directory.GetFiles(strDirFileSpecAdd, strFileFileSpecAdd);

            // File types not to compress

            ArrayList alsStrFilesNoCompress = new ArrayList();
            if (args.Length > 4) {
                if (args[4] == "-nocompress") {
                    for (int i = 5; i < args.Length; i++) {
                        string[] astrFiles = Directory.GetFiles(strDirFileSpecAdd, args[i]);
                        foreach (string str in astrFiles)
                            alsStrFilesNoCompress.Add(Path.GetFullPath(str));
                    }
                }
            }

            // Print status

            Console.Write("Packing files... ");
            PdbPacker pdbp = new PdbPacker();
            foreach (string strFileAdd in astrFilesAdd) {
                // Don't add the .pdb we're building

                string strFullPathAdd = Path.GetFullPath(strFileAdd);
                if (strFullPathPdb.ToLower() == strFullPathAdd.ToLower())
                    continue;

                // Get filename only, check length

                string strFile = Path.GetFileName(strFullPathAdd).ToLower();
                if (strFile.Length >= s_cbFilenameMax) {
                    Console.WriteLine("The file " + strFile + " is too long. Must be " + (s_cbFilenameMax - 1) + "chars max.");
                    return false;
                }

                // Compress or not?

                bool fCompress = true;
                foreach (string strFileNoCompress in alsStrFilesNoCompress) {
                    if (strFullPathAdd.ToLower() == strFileNoCompress.ToLower()) {
                        fCompress = false;
                        break;
                    }
                }

                // Read the file

                Stream stm = new FileStream(strFullPathAdd, FileMode.Open, FileAccess.Read);
                BinaryReader brdr = new BinaryReader(stm);
                PdbPacker.File file = new PdbPacker.File(strFile, brdr.ReadBytes((int)brdr.BaseStream.Length), fCompress);
                brdr.Close();
                pdbp.Add(file);
            }

            // Save out

            pdbp.Save(strFullPathPdb, strCreatorId);
            return true;
        }
        void SavePdb(string strPdbFile)
        {
            // Make a list of unique sound files

            PdbPacker pdbp = new PdbPacker();
            int cSfx = m_alsNames.Count;
            StringCollection strcUniqueSounds = new StringCollection();
            ArrayList alsPcm = new ArrayList();
            for (int iSfx = 0; iSfx < cSfx; iSfx++) {
                if (!listViewSfx.Items[iSfx].Checked)
                    continue;
                if (!(bool)m_alsSfxEnabled[iSfx])
                    continue;
                string strFile = listViewSfx.Items[iSfx].SubItems[1].Text;
                if (strFile == null)
                    continue;
                strFile.Trim();
                if (strFile.Length == 0)
                    continue;
                int istr = strcUniqueSounds.IndexOf(strFile);
                if (istr == -1)
                    istr = strcUniqueSounds.Add(strFile);
            }

            // Serialize names out

            ArrayList alsStringOffsets = new ArrayList();
            BinaryWriter bwtr = new BinaryWriter(new MemoryStream());
            bwtr.Write(Misc.SwapUShort((ushort)strcUniqueSounds.Count));
            for (int iSound = 0; iSound < strcUniqueSounds.Count; iSound++) {
                alsStringOffsets.Add(bwtr.BaseStream.Position);
                string strFile = Path.ChangeExtension(strcUniqueSounds[iSound], ".snd");
                char[] sz = strFile.ToCharArray();
                bwtr.Write(sz);
                bwtr.Write((byte)0);
            }
            byte[] abSoundFiles = new byte[bwtr.BaseStream.Length];
            bwtr.BaseStream.Seek(0, SeekOrigin.Begin);
            bwtr.BaseStream.Read(abSoundFiles, 0, (int)bwtr.BaseStream.Length);
            bwtr.Close();

            // soundfiles file

            PdbPacker.File fileSounds = new PdbPacker.File("soundfiles", abSoundFiles);
            pdbp.Add(fileSounds);

            // Now serialize the sfx entries in the order of the names

            bwtr = new BinaryWriter(new MemoryStream());
            for (int iName = 0; iName < m_alsNames.Count; iName++) {
                // Need to find the entry in listViewSfx for this name since the persist
                // order needs to match soundeffects.h.

                string strName = ((StringCollection)m_alsNames[iName])[0];
                int iSfx;
                bool fFound = false;
                for (iSfx = 0; iSfx < cSfx; iSfx++) {
                    if (strName == listViewSfx.Items[iSfx].SubItems[0].Text) {
                        fFound = true;
                        break;
                    }
                }
                if (!fFound)
                    throw new Exception("Internal error");

                string strFile = listViewSfx.Items[iSfx].SubItems[1].Text;
                if (!listViewSfx.Items[iSfx].Checked)
                    strFile = null;
                if (!(bool)m_alsSfxEnabled[iSfx])
                    strFile = null;
                if (strFile == null) {
                    bwtr.Write((byte)0xff);
                } else {
                    strFile.Trim();
                    if (strFile.Length == 0) {
                        bwtr.Write((byte)0xff);
                    } else {
                        bwtr.Write((byte)strcUniqueSounds.IndexOf(strFile));
                    }
                }
                bwtr.Write((byte)0); // bwtr.Write(byte.Parse(listViewSfx.Items[iSfx].SubItems[2].Text));
                int nPriority = m_strcPriorities.IndexOf(listViewSfx.Items[iSfx].SubItems[3].Text);
                if (nPriority < 0) {
                    MessageBox.Show("Warning: " + listViewSfx.Items[iSfx].SubItems[0].Text + " has an unfamiliar priority.");
                }
                bwtr.Write((byte)nPriority);
            }
            byte[] abSfxEntries = new byte[bwtr.BaseStream.Length];
            bwtr.BaseStream.Seek(0, SeekOrigin.Begin);
            bwtr.BaseStream.Read(abSfxEntries, 0, (int)bwtr.BaseStream.Length);
            bwtr.Close();

            PdbPacker.File fileSfxEntries = new PdbPacker.File("SfxEntries", abSfxEntries);
            pdbp.Add(fileSfxEntries);

            // Now add in all the sounds

            for (int istrFile = 0; istrFile < strcUniqueSounds.Count; istrFile++) {
                string strFile = Path.GetFullPath(textBoxSoundsDir.Text) + "\\" + strcUniqueSounds[istrFile];
                Pcm pcm = new Pcm(strFile);
                PdbPacker.File fileT = new PdbPacker.File();
                fileT.str = Path.ChangeExtension(strcUniqueSounds[istrFile], ".snd");
                fileT.ab = pcm.GetSndEncoding();
                fileT.fCompress = false;
                pdbp.Add(fileT);
            }

            // Ready to save pdb

            pdbp.Save(strPdbFile, "WARI");
        }