Example #1
0
        public static Smap GetSmapFromSdat(string pSdatPath)
        {
            Smap   smap     = new Smap();
            string fullPath = Path.GetFullPath(pSdatPath);

            if (!File.Exists(fullPath))
            {
                throw new FileNotFoundException(String.Format("Cannot find file <{0}>", fullPath));
            }
            else
            {
                using (FileStream fs = File.OpenRead(fullPath))
                {
                    Type dataType = FormatUtil.getObjectType(fs);

                    if (dataType != null && dataType.Name.Equals("Sdat"))
                    {
                        Sdat sdat = new Sdat();
                        sdat.Initialize(fs, fullPath);
                        smap = new Smap(sdat);
                    }
                }
            }

            return(smap);
        }
Example #2
0
        public static string ExtractSdat(string pSdatPath)
        {
            string fullPath   = Path.GetFullPath(pSdatPath);
            string outputPath = null;
            string waveArcOutputPath;

            if (!File.Exists(fullPath))
            {
                throw new FileNotFoundException(String.Format("Cannot find file <{0}>", fullPath));
            }
            else
            {
                Swar   swar = new Swar();
                string swavOutputPath;

                using (FileStream fs = File.OpenRead(fullPath))
                {
                    Type dataType = FormatUtil.getObjectType(fs);

                    if (dataType != null && dataType.Name.Equals("Sdat"))
                    {
                        string filePrefix = Path.GetFileNameWithoutExtension(fullPath);
                        outputPath = Path.Combine(Path.GetDirectoryName(fullPath), filePrefix);

                        Sdat sdat = new Sdat();
                        sdat.Initialize(fs, fullPath);

                        sdat.ExtractBanks(fs, outputPath);
                        sdat.ExtractSseqs(fs, outputPath);
                        sdat.ExtractSeqArc(fs, outputPath);
                        sdat.ExtractStrms(fs, outputPath);
                        waveArcOutputPath = sdat.ExtractWaveArcs(fs, outputPath);

                        // extract SWAVs
                        if (!String.IsNullOrEmpty(waveArcOutputPath))
                        {
                            foreach (string f in Directory.GetFiles(waveArcOutputPath, "*" + Swar.FILE_EXTENSION))
                            {
                                using (FileStream swarFs = File.Open(f, FileMode.Open, FileAccess.Read))
                                {
                                    dataType = FormatUtil.getObjectType(swarFs);

                                    if (dataType != null && dataType.Name.Equals("Swar"))
                                    {
                                        swavOutputPath = Path.Combine(waveArcOutputPath, Path.GetFileNameWithoutExtension(f));
                                        swar.Initialize(swarFs, f);

                                        ExtractAndWriteSwavFromSwar(swarFs, swar, swavOutputPath);
                                    }
                                }
                            }
                        }

                        sdat.BuildSmap(outputPath, filePrefix);
                    }
                }
            }
            return(outputPath);
        }
        protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pSdatOptimizerStruct,
                                              DoWorkEventArgs e)
        {
            SdatOptimizerStruct sdatOptimizerStruct = (SdatOptimizerStruct)pSdatOptimizerStruct;

            string sdatDirectory;
            string sdatOptimizingFileName;
            string sdatOptimizingPath;

            string sdatCompletedFileName;
            string sdatCompletedPath;

            Sdat sdat          = null;
            int  startSequence = Sdat.NO_SEQUENCE_RESTRICTION;
            int  endSequence   = Sdat.NO_SEQUENCE_RESTRICTION;

            sdatDirectory          = Path.GetDirectoryName(pPath);
            sdatOptimizingFileName = String.Format("{0}_OPTIMIZING.sdat",
                                                   Path.GetFileNameWithoutExtension(pPath));
            sdatOptimizingPath = Path.Combine(sdatDirectory, sdatOptimizingFileName);

            sdatCompletedFileName = String.Format("{0}_OPTIMIZED.sdat",
                                                  Path.GetFileNameWithoutExtension(pPath));
            sdatCompletedPath = Path.Combine(sdatDirectory, sdatCompletedFileName);

            File.Copy(pPath, sdatOptimizingPath, true);

            using (FileStream fs = File.Open(sdatOptimizingPath, FileMode.Open, FileAccess.ReadWrite))
            {
                Type dataType = FormatUtil.getObjectType(fs);

                if (dataType != null && dataType.Name.Equals("Sdat"))
                {
                    sdat = new Sdat();
                    sdat.Initialize(fs, sdatOptimizingPath);
                }
            }

            if (sdat != null)
            {
                if (!String.IsNullOrEmpty(sdatOptimizerStruct.startSequence))
                {
                    startSequence = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(sdatOptimizerStruct.startSequence.Trim());
                }

                if (!String.IsNullOrEmpty(sdatOptimizerStruct.endSequence))
                {
                    endSequence = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(sdatOptimizerStruct.endSequence);
                }

                sdat.OptimizeForZlib(startSequence, endSequence);
            }

            File.Copy(sdatOptimizingPath, sdatCompletedPath, true);
            File.Delete(sdatOptimizingPath);
        }
Example #4
0
        private void initializeSseq(Sdat pSdat)
        {
            this.sseqSection = new SmapSeqStruct[pSdat.InfoSection.SdatInfoSseqs.Length];

            for (int i = 0; i < this.sseqSection.Length; i++)
            {
                this.sseqSection[i]        = new SmapSeqStruct();
                this.sseqSection[i].number = i;

                if (pSdat.InfoSection.SdatInfoSseqs[i].fileId != null)
                {
                    int intFileId = BitConverter.ToInt16(pSdat.InfoSection.SdatInfoSseqs[i].fileId, 0);

                    if ((pSdat.SymbSection != null) &&
                        (i < pSdat.SymbSection.SymbSeqFileNames.Length) &&
                        (!String.IsNullOrEmpty(pSdat.SymbSection.SymbSeqFileNames[i])))
                    {
                        this.sseqSection[i].label = pSdat.SymbSection.SymbSeqFileNames[i];
                        this.sseqSection[i].name  =
                            pSdat.SymbSection.SymbSeqFileNames[i] + Sdat.SEQUENCE_FILE_EXTENSION;
                    }
                    else
                    {
                        this.sseqSection[i].label = "SSEQ" + intFileId.ToString("X4");
                        this.sseqSection[i].name  = String.Format("SSEQ{0}{1}", intFileId.ToString("X4"), Sdat.SEQUENCE_FILE_EXTENSION);
                    }

                    this.sseqSection[i].fileID = BitConverter.ToInt16(pSdat.InfoSection.SdatInfoSseqs[i].fileId, 0);
                    this.sseqSection[i].bnk    = BitConverter.ToInt16(pSdat.InfoSection.SdatInfoSseqs[i].bnk, 0);
                    this.sseqSection[i].vol    = pSdat.InfoSection.SdatInfoSseqs[i].vol[0];
                    this.sseqSection[i].cpr    = pSdat.InfoSection.SdatInfoSseqs[i].cpr[0];
                    this.sseqSection[i].ppr    = pSdat.InfoSection.SdatInfoSseqs[i].ppr[0];
                    this.sseqSection[i].ply    = pSdat.InfoSection.SdatInfoSseqs[i].ply[0];
                    // this.sseqSection[i].hsize; @TODO figure this out
                    this.sseqSection[i].size =
                        BitConverter.ToInt32(pSdat.FatSection.SdatFatRecs[BitConverter.ToInt16(pSdat.InfoSection.SdatInfoSseqs[i].fileId, 0)].nSize, 0);
                }
                else
                {
                    this.sseqSection[i].fileID = EMPTY_FILE_ID;
                }
            }
        }
Example #5
0
        public static ArrayList GetDuplicateSseqsList(string pSdatPath)
        {
            string    fullPath = Path.GetFullPath(pSdatPath);
            ArrayList ret      = null;

            if (!File.Exists(fullPath))
            {
                throw new FileNotFoundException(String.Format("Cannot find file <{0}>", fullPath));
            }
            else
            {
                if (Sdat.IsSdat(fullPath))
                {
                    using (FileStream fs = File.OpenRead(fullPath))
                    {
                        Sdat sdat = new Sdat();
                        sdat.Initialize(fs, fullPath);
                        ret = sdat.GetDuplicatesList();
                    }
                }
            }

            return(ret);
        }
Example #6
0
        private void LoadComboBox(string pSourcePath)
        {
            Smap.SmapSeqStruct s;

            this.dataGridSseq.Rows.Clear();

            if (Sdat.IsSdat(pSourcePath))
            {
                Smap            smap = SdatUtil.GetSmapFromSdat(pSourcePath);
                DataGridViewRow row  = new DataGridViewRow();

                if ((smap.SseqSection != null) && (smap.SseqSection.Length > 0))
                {
                    // get duplicates list
                    ArrayList duplicatesList = SdatUtil.GetDuplicateSseqsList(pSourcePath);

                    // setup volume tracking struct
                    this.sseqVolumeList = new Mk2sfWorker.VolumeChangeStruct[smap.SseqSection.Length];

                    // foreach (Smap.SmapSeqStruct s in smap.SseqSection)
                    for (int i = 0; i < smap.SseqSection.Length; i++)
                    {
                        s = smap.SseqSection[i];

                        row = new DataGridViewRow();
                        row.CreateCells(this.dataGridSseq);

                        row.Cells[1].Value = s.number.ToString("x4");

                        if (!String.IsNullOrEmpty(s.name))
                        {
                            row.Cells[0].Value = true;
                            row.Cells[2].Value = s.fileID.ToString();
                            row.Cells[3].Value = s.size.ToString().PadLeft(6, '0');
                            row.Cells[4].Value = s.name.ToString();
                            row.Cells[5].Value = s.bnk.ToString();
                            row.Cells[6].Value = s.vol.ToString();
                            row.Cells[7].Value = s.cpr.ToString();
                            row.Cells[8].Value = s.ppr.ToString();
                            row.Cells[9].Value = s.ply.ToString();

                            // add volume tracking
                            this.sseqVolumeList[i].oldValue = s.vol;
                            this.sseqVolumeList[i].newValue = s.vol;

                            // check for duplicate
                            if (duplicatesList.Contains(i))
                            {
                                row.Cells[0].Value             = false;
                                row.DefaultCellStyle.BackColor = Color.Crimson;
                            }
                        }
                        else
                        {
                            row.Cells[0].Value = false;
                        }

                        this.dataGridSseq.Rows.Add(row);
                    }
                }
            }
        }
Example #7
0
        private void Make2sfFiles(Mk2sfStruct pMk2sfStruct)
        {
            string sdatDestinationPath;
            string TwoSFDestinationPath;
            string sdatPrefix;
            string testpackDestinationPath;
            string unallowedDestinationPath;
            string strmDestinationPath;
            Sdat   sdat;

            // Build Paths
            if (String.IsNullOrEmpty(pMk2sfStruct.GameSerial))
            {
                sdatDestinationPath =
                    Path.Combine(pMk2sfStruct.DestinationFolder, Path.GetFileName(pMk2sfStruct.SourcePath));
            }
            else
            {
                sdatDestinationPath =
                    Path.Combine(pMk2sfStruct.DestinationFolder, pMk2sfStruct.GameSerial + Path.GetExtension(pMk2sfStruct.SourcePath));
            }
            TwoSFDestinationPath =
                Path.Combine(pMk2sfStruct.DestinationFolder, Path.GetFileNameWithoutExtension(sdatDestinationPath));
            sdatPrefix = Path.GetFileNameWithoutExtension(sdatDestinationPath);
            testpackDestinationPath = Path.Combine(pMk2sfStruct.DestinationFolder,
                                                   Path.GetFileName(TESTPACK_FULL_PATH));
            unallowedDestinationPath = Path.Combine(TwoSFDestinationPath, "UnAllowed Sequences");
            strmDestinationPath      = TwoSFDestinationPath;

            // Copy SDAT to destination folder
            try
            {
                File.Copy(pMk2sfStruct.SourcePath, sdatDestinationPath, false);
            }
            catch (Exception sdatException)
            {
                throw new IOException(String.Format("Error: Cannot copy SDAT <{0}> to destination directory: {1}.", sdatDestinationPath, sdatException.Message));
            }

            // Copy STRMs
            this.progressStruct.Clear();
            this.progressStruct.GenericMessage = "Copying STRM files" + Environment.NewLine;
            ReportProgress(Constants.ProgressMessageOnly, progressStruct);

            using (FileStream sdatStream = File.OpenRead(sdatDestinationPath))
            {
                sdat = new Sdat();
                sdat.Initialize(sdatStream, sdatDestinationPath);
                sdat.ExtractStrms(sdatStream, strmDestinationPath);
            }

            // Update Volume
            for (int i = 0; i < pMk2sfStruct.VolumeChangeList.Length; i++)
            {
                if (pMk2sfStruct.VolumeChangeList[i].newValue != pMk2sfStruct.VolumeChangeList[i].oldValue)
                {
                    sdat.UpdateSseqVolume(i, pMk2sfStruct.VolumeChangeList[i].newValue);
                }
            }


            // Optimize SDAT
            this.progressStruct.Clear();
            this.progressStruct.GenericMessage = "Optimizing SDAT" + Environment.NewLine;
            ReportProgress(Constants.ProgressMessageOnly, progressStruct);

            using (FileStream sdatStream = File.OpenRead(sdatDestinationPath))
            {
                sdat = new Sdat();
                sdat.Initialize(sdatStream, sdatDestinationPath);
            }
            sdat.OptimizeForZlib(pMk2sfStruct.AllowedSequences);

            // Copy testpack.nds
            File.Copy(TESTPACK_FULL_PATH, testpackDestinationPath, true);

            // Create 2SF output path
            if (!Directory.Exists(TwoSFDestinationPath))
            {
                Directory.CreateDirectory(TwoSFDestinationPath);
            }

            // Build 2SFs
            this.progressStruct.Clear();
            this.progressStruct.GenericMessage = "Build 2SFs" + Environment.NewLine;
            ReportProgress(Constants.ProgressMessageOnly, progressStruct);

            XsfUtil.Make2sfSet(testpackDestinationPath, sdatDestinationPath,
                               GetMinAllowedSseq(pMk2sfStruct.AllowedSequences),
                               GetMaxAllowedSseq(pMk2sfStruct.AllowedSequences), TwoSFDestinationPath);

            // Move unallowed Sequences
            string unallowedFileName;
            string unallowedFilePath;

            foreach (int unallowedSequenceNumber in pMk2sfStruct.UnAllowedSequences)
            {
                unallowedFileName = String.Format("{0}-{1}.mini2sf", sdatPrefix, unallowedSequenceNumber.ToString("x4"));
                unallowedFilePath = Path.Combine(TwoSFDestinationPath, unallowedFileName);

                if (!Directory.Exists(unallowedDestinationPath))
                {
                    Directory.CreateDirectory(unallowedDestinationPath);
                }

                if (File.Exists(unallowedFilePath))
                {
                    File.Copy(unallowedFilePath, Path.Combine(unallowedDestinationPath, unallowedFileName), true);
                    File.Delete(unallowedFilePath);
                }
            }

            // Add Tags
            this.progressStruct.Clear();
            this.progressStruct.GenericMessage = "Tagging Output" + Environment.NewLine;
            ReportProgress(Constants.ProgressMessageOnly, progressStruct);

            XsfBasicTaggingStruct tagStruct = new XsfBasicTaggingStruct();

            tagStruct.TagArtist        = pMk2sfStruct.TagArtist;
            tagStruct.TagCopyright     = pMk2sfStruct.TagCopyright;
            tagStruct.TagYear          = pMk2sfStruct.TagYear;
            tagStruct.TagGame          = pMk2sfStruct.TagGame;
            tagStruct.TagComment       = "uses Legacy of Ys: Book II driver hacked by Caitsith2";
            tagStruct.TagXsfByTagName  = "-2sfby";
            tagStruct.TagXsfByTagValue = "VGMToolbox";

            string taggingBatchPath = XsfUtil.BuildBasicTaggingBatch(TwoSFDestinationPath, tagStruct, "*.mini2sf");

            XsfUtil.ExecutePsfPointBatchScript(taggingBatchPath, true);

            // Time 2SFs
            this.progressStruct.Clear();
            this.progressStruct.GenericMessage = "Timing Output" + Environment.NewLine;
            ReportProgress(Constants.ProgressMessageOnly, progressStruct);

            string outputTimerMessages;

            Time2sfStruct timerStruct = new Time2sfStruct();

            timerStruct.DoSingleLoop     = false;
            timerStruct.Mini2sfDirectory = TwoSFDestinationPath;
            timerStruct.SdatPath         = pMk2sfStruct.SourcePath;

            XsfUtil.Time2sfFolder(timerStruct, out outputTimerMessages);

            // Delete Files
            this.progressStruct.Clear();
            this.progressStruct.GenericMessage = "Cleaning Up" + Environment.NewLine;
            ReportProgress(Constants.ProgressMessageOnly, progressStruct);

            if (File.Exists(sdatDestinationPath))
            {
                File.Delete(sdatDestinationPath);
            }
            if (File.Exists(testpackDestinationPath))
            {
                File.Delete(testpackDestinationPath);
            }
        }
Example #8
0
        static void Main(string[] args)
        {
            string pathTo2sf;
            string pathToSdat;
            string filePrefix;
            string smapPath       = String.Empty;
            bool   processSuccess = false;
            string emptyFolderFileName;

            if (args.Length != 3)
            {
                usage();
                return;
            }
            else
            {
                pathTo2sf  = args[0];
                pathToSdat = args[1];
                filePrefix = args[2];
            }

            if (!Directory.Exists(pathTo2sf))
            {
                Console.WriteLine(String.Format("Cannot find directory <{0}>", pathTo2sf));
                return;
            }

            if (!File.Exists(pathToSdat))
            {
                Console.WriteLine(String.Format("Cannot find file <{0}>", pathToSdat));
                return;
            }

            if (!String.IsNullOrEmpty(smapPath) && !File.Exists(smapPath))
            {
                Console.WriteLine(String.Format("Cannot find file <{0}>", smapPath));
                return;
            }

            string sseq2MidPath = Path.Combine(Path.Combine(".", "helper"), "sseq2mid.exe");
            string psfpointPath = Path.Combine(Path.Combine(".", "helper"), "psfpoint.exe");

            // delete old .bat file
            string psfpointBatchFilePath = Path.Combine(Path.Combine(pathTo2sf, "text"), PSFPOINT_BATCH_TXT);

            Console.WriteLine();

            if (File.Exists(psfpointBatchFilePath))
            {
                Console.WriteLine("Deleting Old Batch File");
                File.Delete(psfpointBatchFilePath);
            }

            // Extract SDAT
            Console.WriteLine("Extracting SDAT");

            string extractedSdatPath = Path.Combine(Path.GetDirectoryName(pathToSdat), Path.GetFileNameWithoutExtension(pathToSdat));

            if (Directory.Exists(extractedSdatPath))
            {
                extractedSdatPath += String.Format("_temp_{0}", new Random().Next().ToString());
            }

            string extractedSseqPath = Path.Combine(extractedSdatPath, "Seq");

            FileStream fs   = File.Open(pathToSdat, FileMode.Open, FileAccess.Read);
            Sdat       sdat = new Sdat();

            sdat.Initialize(fs, pathToSdat);
            sdat.ExtractSseqs(fs, extractedSdatPath);
            fs.Close();
            fs.Dispose();

            // Make SMAP
            Console.WriteLine("Building Internal SMAP");
            Smap smap = new Smap(sdat);

            // Loop through SMAP and build timing script
            Console.WriteLine("Building Timing Script");
            string emptyFileDir = Path.Combine(pathTo2sf, EMPTY_FILE_DIRECTORY);

            int totalSequences = smap.SseqSection.Length;
            int i = 1;

            // Initialize Bass
            if (smap.SseqSection.Length > 0)
            {
                Console.WriteLine("Going to sleep for 5 seconds to avoid the freeware billboard...");
                Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero, null);
                Thread.Sleep(5000);
                Console.WriteLine("Ok, back to work...");
            }

            foreach (Smap.SmapSeqStruct s in smap.SseqSection)
            {
                Console.Write("\r" + String.Format("Processing [{0}/{1}]",
                                                   i.ToString().PadLeft(4, '0'), totalSequences.ToString().PadLeft(4, '0')));

                string rippedFileName = String.Format("{0}-{1}.mini2sf", filePrefix, s.number.ToString("X4"));
                string rippedFilePath = Path.Combine(pathTo2sf, rippedFileName);

                // check if file is empty or not
                if (s.fileID == Smap.EMPTY_FILE_ID)
                {
                    // move to empty dir
                    if (!Directory.Exists(emptyFileDir))
                    {
                        Directory.CreateDirectory(emptyFileDir);
                    }

                    if (File.Exists(rippedFilePath))
                    {
                        emptyFolderFileName = Path.Combine(emptyFileDir, rippedFileName);
                        File.Copy(rippedFilePath, emptyFolderFileName, true);
                        File.Delete(rippedFilePath);
                    }
                }
                else
                {
                    string sseqFilePath = Path.Combine(extractedSseqPath, s.name);

                    // convert sseq file to midi
                    processSuccess = convertSseqFile(sseq2MidPath, pathTo2sf,
                                                     sseqFilePath);

                    // time file
                    if (processSuccess)
                    {
                        processSuccess = buildFileTimingBatch(pathTo2sf,
                                                              rippedFilePath, sseqFilePath);
                    }
                }
                i++;
            }

            // run timing script
            Console.WriteLine(Environment.NewLine + "Executing Timing Script");
            executeBatchScript(psfpointPath, pathTo2sf);

            // Cleanup
            Console.WriteLine("Cleaning Up");
            doCleanup(extractedSdatPath, pathTo2sf, psfpointPath);
        }
Example #9
0
 public Smap(Sdat pSdat)
 {
     // SSEQ
     this.initializeSseq(pSdat);
     this.setMinMaxSseq();
 }
Example #10
0
        static void Main(string[] args)
        {
            if ((args.Length > 3) || (args.Length < 2))
            {
                Console.WriteLine("usage: sdatopt.exe fileName start_sequence end_sequence");
                Console.WriteLine("       sdatopt.exe fileName ALL");
                Console.WriteLine("       sdatopt.exe fileName PREP");
                Console.WriteLine("       sdatopt.exe fileName MAP smap_file");
                Console.WriteLine("       sdatopt.exe fileName MAP");
                Console.WriteLine();
                Console.WriteLine("fileName: .sdat or .2sflib containing SDAT to optimize");
                Console.WriteLine("start_sequence: starting sequence number to keep");
                Console.WriteLine("end_sequence: endinging sequence number to keep");
                Console.WriteLine("ALL: use this if you wish to keep all sequences");
                Console.WriteLine("PREP: use this to output an SMAP to use for sequence selection.  Delete the entire line of sequences you do not want to include.");
                Console.WriteLine("MAP smap_file: uses smap_file from PREP to select sequences to keep.");
                Console.WriteLine("MAP: looks for an smap file based on the sdat name select sequences to keep.  Must be in proper format.");
            }
            else
            {
                Sdat sdat        = null;
                bool is2sfSource = false;;

                string sdatDirectory;
                string sdatOptimizingFileName;
                string sdatOptimizingPath;

                string sdatCompletedFileName;
                string sdatCompletedPath;

                int startSequence = Sdat.NO_SEQUENCE_RESTRICTION;
                int endSequence   = Sdat.NO_SEQUENCE_RESTRICTION;

                string[] extractedSdats       = null;
                string   decompressedDataPath = null;
                string   extractedToFolder    = null;

                ArrayList cleanupList = new ArrayList();

                string filename     = Path.GetFullPath(args[0]);
                string smapFileName = null;

                if (!File.Exists(filename))
                {
                    Console.WriteLine("Cannot find SDAT: {0}", filename);
                    return;
                }

                if (args[1].Trim().ToUpper().Equals("MAP"))
                {
                    if (args.Length < 3)
                    {
                        smapFileName = Path.ChangeExtension(filename, Smap.FILE_EXTENSION);
                    }
                    else
                    {
                        smapFileName = Path.GetFullPath(args[2]);
                    }

                    if (!File.Exists(smapFileName))
                    {
                        Console.WriteLine("Cannot find SMAP: {0}", smapFileName);
                        return;
                    }
                }

                sdatDirectory          = Path.GetDirectoryName(filename);
                sdatOptimizingFileName = String.Format("{0}_OPTIMIZING{1}",
                                                       Path.GetFileNameWithoutExtension(filename), Path.GetExtension(filename));
                sdatOptimizingPath = Path.Combine(sdatDirectory, sdatOptimizingFileName);

                sdatCompletedFileName = String.Format("{0}_OPTIMIZED{1}",
                                                      Path.GetFileNameWithoutExtension(filename), Path.GetExtension(filename));
                sdatCompletedPath = Path.Combine(sdatDirectory, sdatCompletedFileName);

                try
                {
                    File.Copy(filename, sdatOptimizingPath, true);

                    using (FileStream fs = File.Open(sdatOptimizingPath, FileMode.Open, FileAccess.Read))
                    {
                        Type dataType = FormatUtil.getObjectType(fs);

                        if (dataType != null)
                        {
                            if (dataType.Name.Equals("Sdat"))
                            {
                                Console.WriteLine("Input file is an SDAT.");
                                Console.WriteLine("Building Internal SDAT.");
                                sdat = new Sdat();
                                sdat.Initialize(fs, sdatOptimizingPath);
                            }
                            else if (dataType.Name.Equals("Xsf")) // is an Xsf, confirm it is a 2sf
                            {
                                Xsf libFile = new Xsf();
                                libFile.Initialize(fs, sdatOptimizingPath);

                                if (libFile.GetFormat().Equals(Xsf.FormatName2sf))
                                {
                                    Console.WriteLine("Input file is a 2SF.");

                                    is2sfSource = true;

                                    // close stream, we're gonna need this file
                                    fs.Close();
                                    fs.Dispose();

                                    // unpack compressed section
                                    Console.WriteLine("Decompressing Compressed Data section of 2SF.");

                                    Xsf2ExeStruct xsf2ExeStruct = new Xsf2ExeStruct();
                                    xsf2ExeStruct.IncludeExtension = true;
                                    xsf2ExeStruct.StripGsfHeader   = false;
                                    decompressedDataPath           = XsfUtil.ExtractCompressedDataSection(sdatOptimizingPath, xsf2ExeStruct);

                                    // extract SDAT
                                    Console.WriteLine("Extracting SDAT from Decompressed Compressed Data Section.");

                                    VGMToolbox.util.FindOffsetStruct findOffsetStruct = new VGMToolbox.util.FindOffsetStruct();
                                    findOffsetStruct.SearchString           = Sdat.ASCII_SIGNATURE_STRING;
                                    findOffsetStruct.TreatSearchStringAsHex = true;
                                    findOffsetStruct.CutFile             = true;
                                    findOffsetStruct.SearchStringOffset  = "0";
                                    findOffsetStruct.CutSize             = "8";
                                    findOffsetStruct.CutSizeOffsetSize   = "4";
                                    findOffsetStruct.IsCutSizeAnOffset   = true;
                                    findOffsetStruct.OutputFileExtension = ".sdat";
                                    findOffsetStruct.IsLittleEndian      = true;

                                    findOffsetStruct.UseTerminatorForCutSize    = false;
                                    findOffsetStruct.TerminatorString           = null;
                                    findOffsetStruct.TreatTerminatorStringAsHex = false;
                                    findOffsetStruct.IncludeTerminatorLength    = false;
                                    findOffsetStruct.ExtraCutSizeBytes          = null;

                                    string output;
                                    extractedToFolder = ParseFile.FindOffsetAndCutFile(decompressedDataPath, findOffsetStruct, out output, false, false);

                                    // create SDAT object
                                    Console.WriteLine("Building Internal SDAT.");
                                    extractedSdats = Directory.GetFiles(extractedToFolder, "*.sdat");

                                    if (extractedSdats.Length > 1)
                                    {
                                        Console.WriteLine("Sorry, this 2SF file contains more than 1 SDAT.  sdatopt cannot currently handle this.");
                                        return;
                                    }
                                    else if (extractedSdats.Length == 0)
                                    {
                                        Console.WriteLine("ERROR: Did not find an SDAT in the Decompressed Data Section.");
                                        return;
                                    }
                                    else
                                    {
                                        using (FileStream sdatFs = File.Open(extractedSdats[0], FileMode.Open, FileAccess.Read))
                                        {
                                            sdat = new Sdat();
                                            sdat.Initialize(sdatFs, extractedSdats[0]);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                Console.WriteLine("ERROR: Cannot determine format of the input file.");
                                return;
                            }
                        }
                    }

                    if (sdat != null)
                    {
                        if (args[1].Trim().ToUpper().Equals("PREP"))
                        {
                            sdat.BuildSmapPrep(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename));
                        }
                        else if (args[1].Trim().ToUpper().Equals("MAP"))
                        {
                            ArrayList allowedSequences = buildSequenceList(smapFileName);

                            Console.WriteLine("Optimizing SDAT.");
                            sdat.OptimizeForZlib(allowedSequences);
                        }
                        else
                        {
                            if (!args[1].Trim().ToUpper().Equals("ALL"))
                            {
                                if (!String.IsNullOrEmpty(args[1]))
                                {
                                    startSequence = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(args[1]);
                                }

                                if (!String.IsNullOrEmpty(args[2]))
                                {
                                    endSequence = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(args[2]);
                                }
                            }

                            Console.WriteLine("Optimizing SDAT.");
                            sdat.OptimizeForZlib(startSequence, endSequence);
                        }
                    }

                    if (is2sfSource)
                    {
                        if (!args[1].Trim().ToUpper().Equals("PREP"))
                        {
                            // replace SDAT section
                            Console.WriteLine("Inserting SDAT back into Decompressed Compressed Data Section.");
                            long sdatOffset;
                            using (FileStream dcFs = File.Open(decompressedDataPath, FileMode.Open, FileAccess.ReadWrite))
                            {
                                sdatOffset = ParseFile.GetNextOffset(dcFs, 0, Sdat.ASCII_SIGNATURE);
                            }

                            FileInfo fi = new FileInfo(extractedSdats[0]);
                            FileUtil.ReplaceFileChunk(extractedSdats[0], 0, fi.Length, decompressedDataPath, sdatOffset);

                            // rebuild 2sf
                            Console.WriteLine("Rebuilding 2sf File.");

                            string bin2PsfStdOut = String.Empty;
                            string bin2PsfStdErr = String.Empty;

                            XsfUtil.Bin2Psf(Path.GetExtension(filename).Substring(1), (int)Xsf.Version2sf,
                                            decompressedDataPath, ref bin2PsfStdOut, ref bin2PsfStdErr);

                            Console.WriteLine("Cleaning up intermediate files.");
                            File.Copy(Path.ChangeExtension(decompressedDataPath, Path.GetExtension(filename)), sdatOptimizingPath, true);
                            File.Delete(Path.ChangeExtension(decompressedDataPath, Path.GetExtension(filename)));
                        }

                        File.Delete(decompressedDataPath);
                        Directory.Delete(extractedToFolder, true);
                    }

                    if (!args[1].Trim().ToUpper().Equals("PREP"))
                    {
                        Console.WriteLine("Copying to OPTIMIZED file.");
                        File.Copy(sdatOptimizingPath, sdatCompletedPath, true);
                    }

                    Console.WriteLine("Deleting OPTIMIZING file.");
                    File.Delete(sdatOptimizingPath);

                    Console.WriteLine("Optimization Complete.");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(String.Format("ERROR: {0}", ex.Message));
                }
            }
        }