public static void SaveXA(xaParser parser, string destPath, bool keepBackup) { DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(destPath)); string backup = null; if (keepBackup && File.Exists(destPath)) { backup = Utility.GetDestFile(dir, Path.GetFileNameWithoutExtension(destPath) + ".bak", Path.GetExtension(destPath)); File.Move(destPath, backup); } try { using (BufferedStream bufStr = new BufferedStream(File.OpenWrite(destPath))) { parser.WriteTo(bufStr); } } catch { if (File.Exists(backup)) { if (File.Exists(destPath)) { File.Delete(destPath); } File.Move(backup, destPath); } } }
private void Export(DirectoryInfo dir, xxFrame meshFrame) { try { xaMorphSection morphSection = xaParser.MorphSection; xaMorphIndexSet indexSet = xa.FindMorphIndexSet(clip.Name, morphSection); ushort[] meshIndices = indexSet.MeshIndices; ushort[] morphIndices = indexSet.MorphIndices; xxMesh meshList = meshFrame.Mesh; int meshObjIdx = xa.MorphMeshObjIdx(meshIndices, meshList); if (meshObjIdx < 0) { throw new Exception("no valid mesh object was found for the morph"); } xxSubmesh meshObjBase = meshList.SubmeshList[meshObjIdx]; colorVertex = new bool[meshObjBase.VertexList.Count]; for (int i = 0; i < meshIndices.Length; i++) { colorVertex[meshIndices[i]] = true; } string dest = Utility.GetDestFile(dir, meshFrame.Name + "-" + clip.Name + "-", ".morph.mqo"); List <xaMorphKeyframeRef> refList = clip.KeyframeRefList; morphNames = new List <string>(refList.Count); vertLists = new List <List <ImportedVertex> >(refList.Count); for (int i = 0; i < refList.Count; i++) { if (!morphNames.Contains(refList[i].Name)) { List <ImportedVertex> vertList = xx.ImportedVertexList(meshObjBase.VertexList, xx.IsSkinned(meshList)); vertLists.Add(vertList); xaMorphKeyframe keyframe = xa.FindMorphKeyFrame(refList[i].Name, morphSection); for (int j = 0; j < meshIndices.Length; j++) { ImportedVertex vert = vertList[meshIndices[j]]; vert.Position = keyframe.PositionList[morphIndices[j]]; } morphNames.Add(keyframe.Name); } } faceList = xx.ImportedFaceList(meshObjBase.FaceList); Export(dest, meshObjBase.MaterialIndex); foreach (xxTexture tex in usedTextures) { xx.ExportTexture(tex, dir.FullName + @"\" + Path.GetFileName(tex.Name)); } Report.ReportLog("Finished exporting morph to " + dest); } catch (Exception ex) { Report.ReportLog("Error exporting morph: " + ex.Message); } }
public static void Export(string dirPath, xxParser parser, List <xxFrame> meshParents, bool singleMqo, bool worldCoords) { DirectoryInfo dir = new DirectoryInfo(dirPath); List <xxTexture> usedTextures = new List <xxTexture>(parser.TextureList.Count); if (singleMqo) { try { string dest = Utility.GetDestFile(dir, "meshes", ".mqo"); List <xxTexture> texList = Export(dest, parser, meshParents, worldCoords); foreach (xxTexture tex in texList) { if (!usedTextures.Contains(tex)) { usedTextures.Add(tex); } } Report.ReportLog("Finished exporting meshes to " + dest); } catch (Exception ex) { Report.ReportLog("Error exporting meshes: " + ex.Message); } } else { for (int i = 0; i < meshParents.Count; i++) { try { string frameName = meshParents[i].Name; string dest = dir.FullName + @"\" + frameName + ".mqo"; List <xxTexture> texList = Export(dest, parser, new List <xxFrame> { meshParents[i] }, worldCoords); foreach (xxTexture tex in texList) { if (!usedTextures.Contains(tex)) { usedTextures.Add(tex); } } Report.ReportLog("Finished exporting mesh to " + dest); } catch (Exception ex) { Report.ReportLog("Error exporting mesh: " + ex.Message); } } } foreach (xxTexture tex in usedTextures) { xx.ExportTexture(tex, dir.FullName + @"\" + Path.GetFileName(tex.Name)); } }
void writeArchiveWorker_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = (BackgroundWorker)sender; string backup = null; string dirName = Path.GetDirectoryName(destPath); if (dirName == String.Empty) { dirName = @".\"; } DirectoryInfo dir = new DirectoryInfo(dirName); if (!dir.Exists) { dir.Create(); } if (File.Exists(destPath)) { backup = Utility.GetDestFile(dir, Path.GetFileNameWithoutExtension(destPath), ".bak"); File.Move(destPath, backup); if (destPath.Equals(this.FilePath, StringComparison.InvariantCultureIgnoreCase)) { foreach (IWriteFile iw in Subfiles) { if (iw is ppSubfile) { ppSubfile subfile = iw as ppSubfile; if (subfile.ppPath.Equals(this.FilePath, StringComparison.InvariantCultureIgnoreCase)) { subfile.ppPath = backup; } } } } } try { using (BinaryWriter writer = new BinaryWriter(File.Create(destPath))) { writer.BaseStream.Seek(ppHeader.HeaderSize(Subfiles.Count), SeekOrigin.Begin); long offset = writer.BaseStream.Position; var Hashes = new MetaIWriteList(); for (int i = 0; i < Subfiles.Count; i++) { if (worker.CancellationPending) { e.Cancel = true; break; } worker.ReportProgress(i * 100 / Subfiles.Count); System.Diagnostics.Trace.WriteLine(Subfiles[i].Name); if (Subfiles[i] is ppSubfile) { ppSubfile subfile = Subfiles[i] as ppSubfile; using (MD5 md5 = MD5.Create()) using (MemoryStream mem = new MemoryStream()) using (BinaryReader reader = new BinaryReader(File.OpenRead(subfile.ppPath))) { reader.BaseStream.Seek(subfile.offset, SeekOrigin.Begin); int bufsize = Utility.EstBufSize(subfile.size); uint hash = 0; if (bufsize == 0) { Hashes.AddNew(Subfiles[i], hash, 0, subfile.Metadata); continue; } int readSteps = (int)subfile.size / bufsize; byte[] buf; for (int j = 0; j < readSteps; j++) { buf = reader.ReadBytes(bufsize); md5.TransformBlock(buf, 0, bufsize, buf, 0); mem.WriteBytes(buf); } int remaining = (int)(subfile.size % bufsize); buf = reader.ReadBytes(remaining); md5.TransformFinalBlock(buf, 0, remaining); mem.WriteBytes(buf); hash = BitConverter.ToUInt32(md5.Hash, 0); if (!Hashes.Any(x => x.Hash == hash)) { writer.Write(mem.ToArray()); Hashes.AddNew(Subfiles[i], hash, (uint)(writer.BaseStream.Position - offset), subfile.Metadata); } else { var first = Hashes.First(x => x.Hash == hash); Hashes.AddNew(Subfiles[i], hash, first.Size, first.Metadata); } } } else { Stream stream = ppFormat.WriteStream(writer.BaseStream); using (MD5 md5 = MD5.Create()) using (MemoryStream mem = new MemoryStream()) { Subfiles[i].WriteTo(mem); uint hash = BitConverter.ToUInt32(md5.ComputeHash(mem.ToArray()), 0); if (Hashes.Any(x => x.Hash == hash)) { var first = Hashes.First(x => x.Hash == hash); Hashes.AddNew(Subfiles[i], hash, first.Size, first.Metadata); } else { mem.WriteTo(stream); object meta = ppFormat.FinishWriteTo(stream); long ppos = writer.BaseStream.Position; Hashes.AddNew(Subfiles[i], hash, (uint)(ppos - offset), meta); } } } offset = writer.BaseStream.Position; } if (!e.Cancel) { writer.BaseStream.Seek(0, SeekOrigin.Begin); ppHeader.WriteRLEHeader(writer.BaseStream, Hashes); } } if (e.Cancel) { RestoreBackup(destPath, backup); } else if ((backup != null) && !keepBackup) { File.Delete(backup); } foreach (IWriteFile iw in Subfiles) { if (iw is IDisposable) { ((IDisposable)iw).Dispose(); } } //ReloadSubfiles(); } catch (Exception ex) { RestoreBackup(destPath, backup); throw new Exception("PP Parser has encountered an error.", ex); } }
void writeArchiveWorker_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = (BackgroundWorker)sender; string backup = null; string dirName = Path.GetDirectoryName(destPath); if (dirName == String.Empty) { dirName = @".\"; } DirectoryInfo dir = new DirectoryInfo(dirName); if (!dir.Exists) { dir.Create(); } if (File.Exists(destPath)) { backup = Utility.GetDestFile(dir, Path.GetFileNameWithoutExtension(destPath) + ".bak", Path.GetExtension(destPath)); File.Move(destPath, backup); if (destPath.Equals(this.FilePath, StringComparison.InvariantCultureIgnoreCase)) { for (int i = 0; i < Subfiles.Count; i++) { ppSubfile subfile = Subfiles[i] as ppSubfile; if ((subfile != null) && subfile.ppPath.Equals(this.FilePath, StringComparison.InvariantCultureIgnoreCase)) { subfile.ppPath = backup; } } } } try { using (BinaryWriter writer = new BinaryWriter(File.Create(destPath))) { writer.BaseStream.Seek(Format.ppHeader.HeaderSize(Subfiles.Count), SeekOrigin.Begin); int offset = (int)writer.BaseStream.Position; int[] sizes = new int[Subfiles.Count]; object[] metadata = new object[Subfiles.Count]; for (int i = 0; i < Subfiles.Count; i++) { if (worker.CancellationPending) { e.Cancel = true; break; } worker.ReportProgress(i * 100 / Subfiles.Count); ppSubfile subfile = Subfiles[i] as ppSubfile; if ((subfile != null) && (subfile.ppFormat == this.Format)) { using (BinaryReader reader = new BinaryReader(File.OpenRead(subfile.ppPath))) { reader.BaseStream.Seek(subfile.offset, SeekOrigin.Begin); int readSteps = subfile.size / Utility.BufSize; for (int j = 0; j < readSteps; j++) { writer.Write(reader.ReadBytes(Utility.BufSize)); } writer.Write(reader.ReadBytes(subfile.size % Utility.BufSize)); } metadata[i] = subfile.Metadata; } else { Stream stream = Format.WriteStream(writer.BaseStream); Subfiles[i].WriteTo(stream); metadata[i] = Format.FinishWriteTo(stream); } int pos = (int)writer.BaseStream.Position; sizes[i] = pos - offset; offset = pos; } if (!e.Cancel) { writer.BaseStream.Seek(0, SeekOrigin.Begin); Format.ppHeader.WriteHeader(writer.BaseStream, Subfiles, sizes, metadata); offset = (int)writer.BaseStream.Position; for (int i = 0; i < Subfiles.Count; i++) { ppSubfile subfile = Subfiles[i] as ppSubfile; if (subfile != null) { subfile.offset = offset; subfile.size = sizes[i]; } offset += sizes[i]; } } } if (e.Cancel) { RestoreBackup(destPath, backup); } else { if (destPath.Equals(this.FilePath, StringComparison.InvariantCultureIgnoreCase)) { for (int i = 0; i < Subfiles.Count; i++) { ppSubfile subfile = Subfiles[i] as ppSubfile; if ((subfile != null) && subfile.ppPath.Equals(backup, StringComparison.InvariantCultureIgnoreCase)) { subfile.ppPath = this.FilePath; } } } else { this.FilePath = destPath; } if ((backup != null) && !keepBackup) { File.Delete(backup); } } } catch (Exception ex) { RestoreBackup(destPath, backup); Utility.ReportException(ex); } }