public PAKResourcePool(Stream stream) { this.stream = stream; using var reader = new BinaryReader(stream, BinaryIOExtension.Encoding, true); if (reader.ReadUInt32() != 0) { throw new InvalidDataException("Invalid PAKArchive magic"); } var root = new PAKDirectory(this, null, new FilePath("")); Root = root; uint fileCount = reader.ReadUInt32(); var directories = new Dictionary <FilePath, PAKDirectory>(); directories.Add(root.Path, root); for (uint i = 0; i < fileCount; i++) { var entry = PAKArchiveEntry.ReadNew(reader); var dir = GetOrCreateDirectoryFor(entry.path.Parent); var file = new PAKFile(this, dir, entry); dir.FileList.Add(file); } PAKDirectory GetOrCreateDirectoryFor(FilePath?path) { if (path == null || !path.StaysInbound || path == "") { return(root !); } else if (directories !.TryGetValue(path, out var prevDir)) { return(prevDir); } var dirsToCreate = new Stack <string>(); dirsToCreate.Push(path.Parts.Last()); var curParentPath = path.Parent; PAKDirectory?curParent = null; while (curParentPath != null && curParentPath.StaysInbound) { if (directories.TryGetValue(curParentPath, out curParent)) { break; } dirsToCreate.Push(curParentPath.Parts.Last()); curParentPath = curParentPath.Parent; } if (curParent == null) { curParent = root !; } while (dirsToCreate.Any()) { var newPath = curParent.Path.Combine(dirsToCreate.Pop()); var prevParent = curParent; curParent = new PAKDirectory(this, prevParent, newPath); prevParent.DirectoryList.Add(curParent); directories.Add(newPath, curParent); } return(curParent); } baseOffset = stream.Position; }
static void Main(string[] args) { Environment.CurrentDirectory = @"C:\SONICADVENTUREDX\Projects\ECPort"; List <BMPInfo> textures = new List <BMPInfo>(TextureArchive.GetTextures(@"C:\SONICADVENTUREDX\system\BEACH01.PVM")); LandTable landTable = LandTable.LoadFromFile(@"Levels\Emerald Coast\Act 1\LandTable.sa1lvl"); texmap = new Dictionary <int, int>(); BMPInfo[] newtexs = TextureArchive.GetTextures(@"C:\SONICADVENTUREDX\system\BEACH03.PVM"); for (int i = 0; i < newtexs.Length; i++) { BMPInfo found = textures.FirstOrDefault(a => a.Name.Equals(newtexs[i].Name)); if (found == null) { texmap[i] = textures.Count; textures.Add(newtexs[i]); } else { texmap[i] = textures.IndexOf(found); } } foreach (COL col in LandTable.LoadFromFile(@"Levels\Emerald Coast\Act 3\LandTable.sa1lvl").COL) { foreach (NJS_MATERIAL mat in ((BasicAttach)col.Model.Attach).Material) { mat.TextureID = texmap[mat.TextureID]; } landTable.COL.Add(col); } texmap = new Dictionary <int, int>(); newtexs = TextureArchive.GetTextures(@"C:\SONICADVENTUREDX\system\BEACH02.PVM"); for (int i = 0; i < newtexs.Length; i++) { BMPInfo found = textures.FirstOrDefault(a => a.Name.Equals(newtexs[i].Name)); if (found == null) { texmap[i] = textures.Count; textures.Add(newtexs[i]); } else { texmap[i] = textures.IndexOf(found); } } foreach (COL col in LandTable.LoadFromFile(@"Levels\Emerald Coast\Act 2\LandTable.sa1lvl").COL) { col.Bounds.Center.Z -= 2000; col.Model.Position.Z -= 2000; foreach (NJS_MATERIAL mat in ((BasicAttach)col.Model.Attach).Material) { mat.TextureID = texmap[mat.TextureID]; } landTable.COL.Add(col); } texmap = new Dictionary <int, int>(); newtexs = TextureArchive.GetTextures(@"C:\SONICADVENTUREDX\system\OBJ_BEACH.PVM"); for (int i = 0; i < newtexs.Length; i++) { BMPInfo found = textures.FirstOrDefault(a => a.Name.Equals(newtexs[i].Name)); if (found == null) { texmap[i] = textures.Count; textures.Add(newtexs[i]); } else { texmap[i] = textures.IndexOf(found); } } PAKFile pak = new PAKFile(); List <byte> inf = new List <byte>(); string filenoext = "beach01"; string longdir = "..\\..\\..\\sonic2\\resource\\gd_pc\\prs\\" + filenoext; using (System.Windows.Forms.Panel panel = new System.Windows.Forms.Panel()) using (Direct3D d3d = new Direct3D()) using (Device dev = new Device(d3d, 0, DeviceType.Hardware, panel.Handle, CreateFlags.HardwareVertexProcessing, new PresentParameters(640, 480))) { for (int i = 0; i < textures.Count; i++) { using (Texture tex = textures[i].Image.ToTexture(dev)) using (DataStream str = Surface.ToStream(tex.GetSurfaceLevel(0), ImageFileFormat.Dds)) using (MemoryStream ms = new MemoryStream()) { str.CopyTo(ms); pak.Files.Add(new PAKFile.File(filenoext + '\\' + Path.ChangeExtension(textures[i].Name, ".dds"), longdir + '\\' + Path.ChangeExtension(textures[i].Name, ".dds"), ms.ToArray())); } int infsz = inf.Count; inf.AddRange(Encoding.ASCII.GetBytes(Path.ChangeExtension(textures[i].Name, null))); inf.AddRange(new byte[0x1C - (inf.Count - infsz)]); inf.AddRange(BitConverter.GetBytes(i + 200)); inf.AddRange(BitConverter.GetBytes(0)); inf.AddRange(BitConverter.GetBytes(0)); inf.AddRange(BitConverter.GetBytes(0)); inf.AddRange(BitConverter.GetBytes(textures[i].Image.Width)); inf.AddRange(BitConverter.GetBytes(textures[i].Image.Height)); inf.AddRange(BitConverter.GetBytes(0)); inf.AddRange(BitConverter.GetBytes(0x80000000)); } } pak.Files.Insert(0, new PAKFile.File(filenoext + '\\' + filenoext + ".inf", longdir + '\\' + filenoext + ".inf", inf.ToArray())); pak.Save(@"C:\Program Files (x86)\Steam\steamapps\common\Sonic Adventure 2\mods\Emerald Coast\gd_PC\PRS\beach01.pak"); List <COL> newcollist = new List <COL>(); Dictionary <string, Attach> visitedAttaches = new Dictionary <string, Attach>(); foreach (COL col in landTable.COL.Where((col) => col.Model != null && col.Model.Attach != null)) { ConvertCOL(newcollist, visitedAttaches, col); } landTable.COL = newcollist; Console.WriteLine("Loading Object Definitions:"); Console.WriteLine("Parsing..."); LevelData.ObjDefs = new List <ObjectDefinition>(); Dictionary <string, ObjectData> objdefini = IniSerializer.Deserialize <Dictionary <string, ObjectData> >("objdefs.ini"); List <ObjectData> objectErrors = new List <ObjectData>(); ObjectListEntry[] objlstini = ObjectList.Load(@"Levels\Emerald Coast\Object List.ini", false); Directory.CreateDirectory("dllcache").Attributes |= FileAttributes.Hidden; List <KeyValuePair <string, string> > compileErrors = new List <KeyValuePair <string, string> >(); for (int ID = 0; ID < objlstini.Length; ID++) { string codeaddr = objlstini[ID].CodeString; if (!objdefini.ContainsKey(codeaddr)) { codeaddr = "0"; } ObjectData defgroup = objdefini[codeaddr]; ObjectDefinition def; if (!string.IsNullOrEmpty(defgroup.CodeFile)) { Console.WriteLine("Compiling: " + defgroup.CodeFile); def = CompileObjectDefinition(defgroup, out bool errorOccured, out string errorText); if (errorOccured) { KeyValuePair <string, string> errorValue = new KeyValuePair <string, string>( defgroup.CodeFile, errorText); compileErrors.Add(errorValue); } } else { def = new DefaultObjectDefinition(); } LevelData.ObjDefs.Add(def); // The only reason .Model is checked for null is for objects that don't yet have any // models defined for them. It would be annoying seeing that error all the time! if (string.IsNullOrEmpty(defgroup.CodeFile) && !string.IsNullOrEmpty(defgroup.Model)) { Console.WriteLine("Loading: " + defgroup.Model); // Otherwise, if the model file doesn't exist and/or no texture file is defined, // load the "default object" instead ("?"). if (!File.Exists(defgroup.Model)) { ObjectData error = new ObjectData { Name = defgroup.Name, Model = defgroup.Model, Texture = defgroup.Texture }; objectErrors.Add(error); defgroup.Model = null; } } def.Init(defgroup, objlstini[ID].Name); def.SetInternalName(objlstini[ID].Name); } // Checks if there have been any errors added to the error list and does its thing // This thing is a mess. If anyone can think of a cleaner way to do this, be my guest. if (objectErrors.Count > 0) { int count = objectErrors.Count; List <string> errorStrings = new List <string> { "The following objects failed to load:" }; foreach (ObjectData o in objectErrors) { bool texEmpty = string.IsNullOrEmpty(o.Texture); bool texExists = (!string.IsNullOrEmpty(o.Texture) && LevelData.Textures.ContainsKey(o.Texture)); errorStrings.Add(""); errorStrings.Add("Object:\t\t" + o.Name); errorStrings.Add("\tModel:"); errorStrings.Add("\t\tName:\t" + o.Model); errorStrings.Add("\t\tExists:\t" + File.Exists(o.Model)); errorStrings.Add("\tTexture:"); errorStrings.Add("\t\tName:\t" + ((texEmpty) ? "(N/A)" : o.Texture)); errorStrings.Add("\t\tExists:\t" + texExists); } // TODO: Proper logging. Who knows where this file may end up File.WriteAllLines("SADXLVL2.log", errorStrings.ToArray()); } // Loading SET Layout Console.WriteLine("Loading SET items", "Initializing..."); List <SETItem> setlist = new List <SETItem>(); SonicRetro.SAModel.SAEditorCommon.UI.EditorItemSelection selection = new SonicRetro.SAModel.SAEditorCommon.UI.EditorItemSelection(); if (LevelData.ObjDefs.Count > 0) { string setstr = @"C:\SONICADVENTUREDX\Projects\ECPort\system\SET0100S.BIN"; if (File.Exists(setstr)) { Console.WriteLine("SET: " + setstr.Replace(Environment.CurrentDirectory, "")); setlist = SETItem.Load(setstr, selection); } setstr = @"C:\SONICADVENTUREDX\Projects\ECPort\system\SET0102B.BIN"; if (File.Exists(setstr)) { Console.WriteLine("SET: " + setstr.Replace(Environment.CurrentDirectory, "")); setlist.AddRange(SETItem.Load(setstr, selection)); } setstr = @"C:\SONICADVENTUREDX\Projects\ECPort\system\SET0101S.BIN"; if (File.Exists(setstr)) { Console.WriteLine("SET: " + setstr.Replace(Environment.CurrentDirectory, "")); List <SETItem> newlist = SETItem.Load(setstr, selection); foreach (SETItem item in newlist) { item.Position.Z -= 2000; } setlist.AddRange(newlist); } } MatrixStack transform = new MatrixStack(); List <SETItem> add = new List <SETItem>(); List <SETItem> del = new List <SETItem>(); List <PalmtreeData> trees = new List <PalmtreeData>(); foreach (SETItem item in setlist) { switch (item.ID) { case 0xD: // item box item.ID = 0xA; item.Scale.X = itemboxmap[(int)item.Scale.X]; break; case 0x15: // ring group to rings for (int i = 0; i < Math.Min(item.Scale.X + 1, 8); i++) { if (item.Scale.Z == 1) // circle { double v4 = i * 360.0; Vector3 v7 = new Vector3( ObjectHelper.NJSin((int)(v4 / item.Scale.X * 65536.0 * 0.002777777777777778)) * item.Scale.Y, 0, ObjectHelper.NJCos((int)(v4 / item.Scale.X * 65536.0 * 0.002777777777777778)) * item.Scale.Y); transform.Push(); transform.NJTranslate(item.Position); transform.NJRotateObject(item.Rotation); Vector3 pos = Vector3.TransformCoordinate(v7, transform.Top); transform.Pop(); add.Add(new SETItem(0, selection) { Position = pos.ToVertex() }); } else // line { transform.Push(); transform.NJTranslate(item.Position); transform.NJRotateObject(item.Rotation); double v5; if (i % 2 == 1) { v5 = i * item.Scale.Y * -0.5; } else { v5 = Math.Ceiling(i * 0.5) * item.Scale.Y; } Vector3 pos = Vector3.TransformCoordinate(new Vector3(0, 0, (float)v5), transform.Top); transform.Pop(); add.Add(new SETItem(0, selection) { Position = pos.ToVertex() }); } } del.Add(item); break; case 0x1A: // tikal -> omochao item.ID = 0x19; item.Position.Y += 3; break; case 0x1D: // kiki item.ID = 0x5B; item.Rotation = new Rotation(); item.Scale = new Vertex(); break; case 0x1F: // sweep ->beetle item.ID = 0x38; item.Rotation = new Rotation(); item.Scale = new Vertex(1, 0, 0); break; case 0x28: // launch ramp item.ID = 6; item.Scale.X /= 2.75f; item.Scale.Z = 0.799999952316284f; break; case 0x4F: // updraft item.ID = 0x35; item.Scale.X = Math.Max(Math.Min(item.Scale.X, 200), 10) / 2; item.Scale.Y = Math.Max(Math.Min(item.Scale.Y, 200), 10) / 2; item.Scale.Z = Math.Max(Math.Min(item.Scale.Z, 200), 10) / 2; break; case 0x52: // item box air item.ID = 0xB; item.Scale.X = itemboxmap[(int)item.Scale.X]; break; // palm trees case 32: case 33: case 34: case 35: trees.Add(new PalmtreeData((byte)(item.ID - 32), item.Position, item.Rotation)); del.Add(item); break; // nonsolid objects case 47: case 48: case 49: case 50: case 51: case 52: case 59: case 62: case 63: case 64: case 70: ConvertSETItem(newcollist, item, false, setlist.IndexOf(item)); del.Add(item); break; // solid objects case 36: case 37: case 39: case 41: case 42: case 43: case 44: case 45: case 46: case 54: case 58: case 66: case 71: case 72: case 73: case 74: ConvertSETItem(newcollist, item, true, setlist.IndexOf(item)); del.Add(item); break; case 81: // goal item.ID = 0xE; item.Position.Y += 30; break; default: if (idmap.ContainsKey(item.ID)) { item.ID = idmap[item.ID]; } else { del.Add(item); } break; } } setlist.AddRange(add); foreach (SETItem item in del) { setlist.Remove(item); } setlist.Add(new SETItem(0x55, selection) { Position = new Vertex(6158.6f, -88f, 2384.97f), Scale = new Vertex(3, 0, 0) }); { COL col = new COL() { Model = new ModelFile(@"E:\Bridge Model.sa1mdl").Model, SurfaceFlags = SurfaceFlags.Visible }; col.Model.Position = new Vertex(2803, -1, 365); foreach (NJS_MATERIAL mat in ((BasicAttach)col.Model.Attach).Material) { mat.TextureID = texmap[mat.TextureID]; } col.Model.ProcessVertexData(); col.CalculateBounds(); ConvertCOL(newcollist, new Dictionary <string, Attach>(), col); col = new COL() { Model = new ModelFile(@"E:\Bridge Model COL.sa1mdl").Model, SurfaceFlags = SurfaceFlags.Solid }; col.Model.Position = new Vertex(2803, -1, 365); col.Model.ProcessVertexData(); col.CalculateBounds(); newcollist.Add(col); col = new COL() { Model = new ModelFile(@"E:\BridgeSegment0.sa1mdl").Model, SurfaceFlags = SurfaceFlags.Solid }; col.Model.ProcessVertexData(); col.CalculateBounds(); newcollist.Add(col); col = new COL() { Model = new ModelFile(@"E:\BridgeSegment1.sa1mdl").Model, SurfaceFlags = SurfaceFlags.Solid }; col.Model.ProcessVertexData(); col.CalculateBounds(); newcollist.Add(col); col = new COL() { Model = new ModelFile(@"E:\BridgeSegment2.sa1mdl").Model, SurfaceFlags = SurfaceFlags.Solid }; col.Model.ProcessVertexData(); col.CalculateBounds(); newcollist.Add(col); col = new COL() { Model = new ModelFile(@"E:\BridgeSegment3.sa1mdl").Model, SurfaceFlags = SurfaceFlags.Solid }; col.Model.ProcessVertexData(); col.CalculateBounds(); newcollist.Add(col); } landTable.SaveToFile(@"C:\Program Files (x86)\Steam\steamapps\common\Sonic Adventure 2\mods\Emerald Coast\LandTable.sa2lvl", LandTableFormat.SA2); ByteConverter.BigEndian = true; SETItem.Save(setlist, @"C:\Program Files (x86)\Steam\steamapps\common\Sonic Adventure 2\mods\Emerald Coast\gd_PC\set0013_s.bin"); for (int i = 0; i < 4; i++) { ModelFile modelFile = new ModelFile($@"C:\SONICADVENTUREDX\Projects\Test\Objects\Levels\Emerald Coast\YASI{i}.sa1mdl"); foreach (BasicAttach attach in modelFile.Model.GetObjects().Where(a => a.Attach != null).Select(a => a.Attach)) { foreach (NJS_MATERIAL mat in attach.Material) { mat.TextureID = texmap[mat.TextureID]; } } modelFile.SaveToFile($@"C:\Program Files (x86)\Steam\steamapps\common\Sonic Adventure 2\mods\Emerald Coast\YASI{i}.sa1mdl"); } using (StreamWriter sw = File.CreateText(@"E:\Documents\Visual Studio 2017\Projects\LevelTest\LevelTest\pt.c")) sw.WriteLine(string.Join(",\r\n", trees)); }
/// <summary> /// The main entry point for the application. /// </summary> static void Main(string[] args) { if (args.Length == 0) { args = new string[] { "/?" } } ; switch (args[0].ToLowerInvariant()) { case "/t": Main(ParseCommandLine(File.ReadAllText(args[1]))); break; case "/u": try { string fn = Path.Combine(Environment.CurrentDirectory, args[1]); Environment.CurrentDirectory = Path.GetDirectoryName(fn); PAKFile pak = new PAKFile(fn); Dictionary <string, PAKInfo> list = new Dictionary <string, PAKInfo>(pak.Files.Count); foreach (PAKFile.File item in pak.Files) { Directory.CreateDirectory(Path.GetDirectoryName(Path.Combine(Environment.CurrentDirectory, item.Name))); File.WriteAllBytes(item.Name, item.Data); list.Add(item.Name, new PAKInfo(item.LongPath)); } IniFile.Serialize(list, Path.ChangeExtension(fn, "ini")); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } break; case "/p": try { string fn = Path.Combine(Environment.CurrentDirectory, args[1]); Environment.CurrentDirectory = Path.GetDirectoryName(fn); Dictionary <string, PAKInfo> list = IniFile.Deserialize <Dictionary <string, PAKInfo> >(Path.ChangeExtension(fn, "ini")); PAKFile pak = new PAKFile(); foreach (KeyValuePair <string, PAKInfo> item in list) { pak.Files.Add(new PAKFile.File(item.Key, item.Value.LongPath, File.ReadAllBytes(item.Key))); } pak.Save(Path.ChangeExtension(fn, "pak")); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } break; case "/?": Console.WriteLine("Arguments:"); Console.WriteLine(); Console.WriteLine("/?\tShow this help."); Console.WriteLine(); Console.WriteLine("/t filename\tReads text file filename as a commandline."); Console.WriteLine(); Console.WriteLine("/u filename\tExtracts files from an archive."); Console.WriteLine(); Console.WriteLine("/p filename\tPacks files into an archive."); Console.WriteLine(); break; default: if (args.Length == 0) { goto case "/?"; } char arg = '\0'; while (arg != 'u' & arg != 'p') { Console.Write("Type u to unpack or p to pack: "); arg = Console.ReadKey().KeyChar; Console.WriteLine(); } Main(new string[] { "/" + arg, args[0] }); break; } }
/// <summary> /// The main entry point for the application. /// </summary> static void Main(string[] args) { if (args.Length == 0) { args = new string[] { "/?" } } ; switch (args[0].ToLowerInvariant()) { case "/t": Main(ParseCommandLine(File.ReadAllText(args[1]))); break; case "/u": try { string fn = args[1]; Console.WriteLine("Extracting PAK file: {0}", Path.GetFullPath(fn)); string outputPath = Path.Combine(Path.GetDirectoryName(fn), Path.GetFileNameWithoutExtension(fn)); Console.WriteLine("Output folder: {0}", Path.GetFullPath(outputPath)); PAKFile pak = new PAKFile(fn); foreach (PAKFile.PAKEntry entry in pak.Entries) { Console.WriteLine("Extracting file: {0}", entry.Name); File.WriteAllBytes(Path.Combine(outputPath, entry.Name), entry.Data); } pak.CreateIndexFile(outputPath); Console.WriteLine("Archive extracted!"); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } break; case "/p": try { Console.WriteLine("Building PAK from folder: {0}", Path.GetFullPath(args[1])); string outputPath = Path.Combine(Environment.CurrentDirectory, args[1]); Environment.CurrentDirectory = Path.GetDirectoryName(outputPath); Dictionary <string, PAKFile.PAKIniItem> list = IniSerializer.Deserialize <Dictionary <string, PAKFile.PAKIniItem> >(Path.Combine(Path.GetFileNameWithoutExtension(outputPath), Path.GetFileNameWithoutExtension(outputPath) + ".ini")); PAKFile pak = new PAKFile(); foreach (KeyValuePair <string, PAKFile.PAKIniItem> item in list) { Console.WriteLine("Adding file: {0}", item.Key); pak.Entries.Add(new PAKFile.PAKEntry(item.Key, item.Value.LongPath, File.ReadAllBytes(item.Key))); } Console.WriteLine("Output file: {0}", Path.ChangeExtension(outputPath, "pak")); pak.Save(Path.ChangeExtension(outputPath, "pak")); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } break; case "/?": Console.WriteLine("Arguments:"); Console.WriteLine(); Console.WriteLine("/?\tShow this help."); Console.WriteLine(); Console.WriteLine("/t filename\tReads text file filename as a commandline."); Console.WriteLine(); Console.WriteLine("/u filename\tExtracts files from an archive."); Console.WriteLine(); Console.WriteLine("/p filename\tPacks files into an archive."); Console.WriteLine(); break; default: if (args.Length == 0) { goto case "/?"; } char arg = '\0'; while (arg != 'u' & arg != 'p') { Console.Write("Type u to unpack or p to pack: "); arg = Console.ReadKey().KeyChar; Console.WriteLine(); } Main(new string[] { "/" + arg, args[0] }); break; } }
/// <summary> /// Main function for extracting archives. /// </summary> static void ExtractArchive(string[] args) { GenericArchive arc; string arcname = extension.ToUpperInvariant(); Console.WriteLine("Extracting {0} file: {1}", arcname.Substring(1, arcname.Length - 1), filePath); byte[] arcdata = File.ReadAllBytes(filePath); outputPath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)); switch (extension.ToLowerInvariant()) { case (".rel"): outputPath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + "_dec.rel"); Console.WriteLine("Output file: {0}", outputPath); byte[] inputData = File.ReadAllBytes(args[0]); byte[] outputData = SplitTools.HelperFunctions.DecompressREL(inputData); File.WriteAllBytes(outputPath, outputData); Console.WriteLine("File extracted!"); return; case (".pvmx"): arc = new PVMXFile(arcdata); break; case (".arcx"): arc = new ARCXFile(arcdata); break; case (".prs"): arcdata = FraGag.Compression.Prs.Decompress(arcdata); if (ARCXFile.Identify(arcdata)) { arc = new ARCXFile(arcdata); } else if (PuyoFile.Identify(arcdata) == PuyoArchiveType.Unknown) { outputPath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".bin"); Console.WriteLine("Output file: {0}", Path.GetFullPath(outputPath)); File.WriteAllBytes(outputPath, arcdata); Console.WriteLine("Archive extracted!"); return; } else { arc = new PuyoFile(arcdata); } break; case (".pvm"): case (".gvm"): arc = new PuyoFile(arcdata); break; case (".xvm"): arc = new XVM(arcdata); break; case (".pb"): arc = new PBFile(arcdata); break; case (".pak"): arc = new PAKFile(filePath); break; case (".dat"): arc = new DATFile(arcdata); break; case (".mdl"): arc = new MDLArchive(arcdata); break; case (".mdt"): arc = new MDTArchive(arcdata); break; case (".mld"): arc = new MLDArchive(arcdata); break; case (".mlt"): case (".gcaxmlt"): string test = System.Text.Encoding.ASCII.GetString(arcdata, 0, 4); if (test == "gcax") { arc = new gcaxMLTFile(arcdata, Path.GetFileNameWithoutExtension(filePath)); } else { arc = new MLTFile(arcdata, Path.GetFileNameWithoutExtension(filePath)); } break; default: Console.WriteLine("Unknown archive type"); return; } Console.WriteLine("Output folder: {0}", Path.GetFullPath(outputPath)); Directory.CreateDirectory(outputPath); foreach (GenericArchiveEntry entry in arc.Entries) { if (entry.Data == null) { Console.WriteLine("Entry {0} has no data", entry.Name); continue; } Console.WriteLine("Extracting file: {0}", entry.Name); if (arc is ARCXFile) { ARCXFile.ARCXEntry ARCXentry = (ARCXFile.ARCXEntry)entry; Directory.CreateDirectory(Path.Combine(outputPath, ARCXentry.Folder)); File.WriteAllBytes(Path.Combine(outputPath, ARCXentry.Folder, entry.Name), entry.Data); } else { File.WriteAllBytes(Path.Combine(outputPath, entry.Name), entry.Data); } } arc.CreateIndexFile(outputPath); Console.WriteLine("Archive extracted!"); }
public static BMPInfo[] GetTextures(string filename) { if (!File.Exists(filename)) { return(null); } GenericArchive arc; List <BMPInfo> textures = new List <BMPInfo>(); byte[] file = File.ReadAllBytes(filename); string ext = Path.GetExtension(filename).ToLowerInvariant(); switch (ext) { // Folder texture pack case ".txt": string[] files = File.ReadAllLines(filename); List <BMPInfo> txts = new List <BMPInfo>(); for (int s = 0; s < files.Length; s++) { string[] entry = files[s].Split(','); txts.Add(new BMPInfo(Path.GetFileNameWithoutExtension(entry[1]), new System.Drawing.Bitmap(Path.Combine(Path.GetDirectoryName(filename), entry[1])))); } return(txts.ToArray()); case ".pak": arc = new PAKFile(filename); string filenoext = Path.GetFileNameWithoutExtension(filename).ToLowerInvariant(); PAKFile pak = (PAKFile)arc; // Get sorted entires from the INF file if it exists List <PAKFile.PAKEntry> sorted = pak.GetSortedEntries(filenoext); arc.Entries = new List <GenericArchiveEntry>(sorted.Cast <GenericArchiveEntry>()); break; case ".pvmx": arc = new PVMXFile(file); break; case ".pb": arc = new PBFile(file); break; case ".pvr": case ".gvr": arc = new PuyoFile(ext == ".gvr"); PuyoFile parcx = (PuyoFile)arc; if (ext == ".gvr") { arc.Entries.Add(new GVMEntry(filename)); } else { arc.Entries.Add(new PVMEntry(filename)); } if (parcx.PaletteRequired) { parcx.AddPalette(Path.GetDirectoryName(filename)); } break; case ".prs": file = FraGag.Compression.Prs.Decompress(file); goto default; case ".pvm": case ".gvm": default: arc = new PuyoFile(file); PuyoFile parc = (PuyoFile)arc; if (parc.PaletteRequired) { parc.AddPalette(Path.GetDirectoryName(filename)); } break; } foreach (GenericArchiveEntry entry in arc.Entries) { textures.Add(new BMPInfo(Path.GetFileNameWithoutExtension(entry.Name), entry.GetBitmap())); } return(textures.ToArray()); }
static void Main(string[] args) { string directoryName; UInt32 startingGBIX = 0; List <String> textureNames = new List <String>(); if (args.Length == 0) { Console.WriteLine("Error - no texturelist provided. Provide a path to a texturelist as your first command line argument"); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); return; } String filePath = args[0]; directoryName = Path.GetDirectoryName(filePath); string archiveName = Path.GetFileNameWithoutExtension(filePath); if (File.Exists(filePath)) { StreamReader texlistStream = File.OpenText(filePath); startingGBIX = UInt32.Parse(texlistStream.ReadLine()); while (!texlistStream.EndOfStream) { textureNames.Add(texlistStream.ReadLine()); } string filenoext = Path.GetFileNameWithoutExtension(filePath).ToLowerInvariant(); string longdir = "..\\..\\..\\sonic2\\resource\\gd_pc\\prs\\" + filenoext; PAKFile pak = new PAKFile(); List <byte> inf = new List <byte>(); using (System.Windows.Forms.Panel panel1 = new System.Windows.Forms.Panel()) using (Device d3ddevice = new Device(0, DeviceType.Hardware, panel1, CreateFlags.SoftwareVertexProcessing, new PresentParameters[] { new PresentParameters() { Windowed = true, SwapEffect = SwapEffect.Discard, EnableAutoDepthStencil = true, AutoDepthStencilFormat = DepthFormat.D24X8 } })) { // Reading in textures for (uint imgIndx = 0; imgIndx < textureNames.Count; imgIndx++) { Bitmap tempTexture = new Bitmap(8, 8); string texturePath = Path.Combine(directoryName, Path.ChangeExtension(textureNames[(int)imgIndx], ".png")); if (File.Exists(texturePath)) { tempTexture = (Bitmap)Bitmap.FromFile(texturePath); tempTexture = tempTexture.Clone(new Rectangle(Point.Empty, tempTexture.Size), System.Drawing.Imaging.PixelFormat.Format32bppArgb); } else { Console.WriteLine(String.Concat("Texture ", textureNames[(int)imgIndx], " not found. Generating a placeholder. Check your files.")); } Stream tex = TextureLoader.SaveToStream(ImageFileFormat.Dds, Texture.FromBitmap(d3ddevice, tempTexture, Usage.SoftwareProcessing, Pool.Managed)); byte[] tb = new byte[tex.Length]; tex.Read(tb, 0, tb.Length); pak.Files.Add(new PAKFile.File(filenoext + '\\' + Path.ChangeExtension(textureNames[(int)imgIndx], ".dds"), longdir + '\\' + Path.ChangeExtension(textureNames[(int)imgIndx], ".dds"), tb)); int i = inf.Count; inf.AddRange(Encoding.ASCII.GetBytes(Path.ChangeExtension(textureNames[(int)imgIndx], null))); inf.AddRange(new byte[0x1C - (inf.Count - i)]); inf.AddRange(BitConverter.GetBytes(startingGBIX + imgIndx)); inf.AddRange(BitConverter.GetBytes(0)); inf.AddRange(BitConverter.GetBytes(0)); inf.AddRange(BitConverter.GetBytes(0)); inf.AddRange(BitConverter.GetBytes(tempTexture.Width)); inf.AddRange(BitConverter.GetBytes(tempTexture.Height)); inf.AddRange(BitConverter.GetBytes(0)); inf.AddRange(BitConverter.GetBytes(0x80000000)); } } pak.Files.Insert(0, new PAKFile.File(filenoext + '\\' + filenoext + ".inf", longdir + '\\' + filenoext + ".inf", inf.ToArray())); pak.Save(Path.ChangeExtension(filePath, "pak")); Console.WriteLine("PAK was compiled successfully!"); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); return; } else // error, supplied path is invalid { Console.WriteLine("Supplied texturelist does not exist!"); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); return; } }
public static BMPInfo[] GetTextures(string filename) { if (!File.Exists(filename)) { return(null); } string ext = Path.GetExtension(filename).ToLowerInvariant(); switch (ext) { case ".pak": PAKFile pak = new PAKFile(filename); string filenoext = Path.GetFileNameWithoutExtension(filename).ToLowerInvariant(); byte[] inf = pak.Files.Single((file) => file.Name.Equals(filenoext + '\\' + filenoext + ".inf", StringComparison.OrdinalIgnoreCase)).Data; List <BMPInfo> newtextures = new List <BMPInfo>(inf.Length / 0x3C); for (int i = 0; i < inf.Length; i += 0x3C) { System.Text.StringBuilder sb = new System.Text.StringBuilder(0x1C); for (int j = 0; j < 0x1C; j++) { if (inf[i + j] != 0) { sb.Append((char)inf[i + j]); } else { break; } } byte[] dds = pak.Files.First((file) => file.Name.Equals(filenoext + '\\' + sb.ToString() + ".dds", StringComparison.OrdinalIgnoreCase)).Data; using (MemoryStream str = new MemoryStream(dds)) { uint check = BitConverter.ToUInt32(dds, 0); if (check == 0x20534444) // DDS header { PixelFormat pxformat; var image = Pfim.Pfim.FromStream(str, new Pfim.PfimConfig()); switch (image.Format) { case Pfim.ImageFormat.Rgba32: pxformat = PixelFormat.Format32bppArgb; break; default: System.Windows.Forms.MessageBox.Show("Unsupported image format."); throw new NotImplementedException(); } var bitmap = new Bitmap(image.Width, image.Height, pxformat); BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, pxformat); System.Runtime.InteropServices.Marshal.Copy(image.Data, 0, bmpData.Scan0, image.DataLen); bitmap.UnlockBits(bmpData); newtextures.Add(new BMPInfo(sb.ToString(), bitmap)); } else { newtextures.Add(new BMPInfo(sb.ToString(), new Bitmap(str))); } } } return(newtextures.ToArray()); case ".pvmx": PVMXFile pvmx = new PVMXFile(File.ReadAllBytes(filename)); List <BMPInfo> textures = new List <BMPInfo>(); for (int i = 0; i < pvmx.GetCount(); i++) { var bmp = new Bitmap(new MemoryStream(pvmx.GetFile(i))); textures.Add(new BMPInfo(pvmx.GetNameWithoutExtension(i), bmp)); } return(textures.ToArray()); case ".txt": string[] files = File.ReadAllLines(filename); List <BMPInfo> txts = new List <BMPInfo>(); for (int s = 0; s < files.Length; s++) { string[] entry = files[s].Split(','); txts.Add(new BMPInfo(entry[1], new System.Drawing.Bitmap(Path.Combine(Path.GetDirectoryName(filename), entry[1])))); } return(txts.ToArray()); case ".pb": PBFile pbdata = new PBFile(File.ReadAllBytes(filename)); List <BMPInfo> txtsp = new List <BMPInfo>(); for (int i = 0; i < pbdata.GetCount(); i++) { PvrTexture pvr = new PvrTexture(pbdata.GetPVR(i)); txtsp.Add(new BMPInfo(i.ToString("D3"), pvr.ToBitmap())); } return(txtsp.ToArray()); case ".pvm": case ".gvm": default: List <BMPInfo> functionReturnValue = new List <BMPInfo>(); bool gvm = false; ArchiveBase pvmfile = null; byte[] pvmdata = File.ReadAllBytes(filename); if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase)) { pvmdata = FraGag.Compression.Prs.Decompress(pvmdata); } pvmfile = new PvmArchive(); MemoryStream stream = new MemoryStream(pvmdata); if (!PvmArchive.Identify(stream)) { pvmfile = new GvmArchive(); gvm = true; } VrSharp.VpPalette pvp = null; ArchiveEntryCollection pvmentries = pvmfile.Open(pvmdata).Entries; foreach (ArchiveEntry file in pvmentries) { VrTexture vrfile = gvm ? (VrTexture) new GvrTexture(file.Open()) : (VrTexture) new PvrTexture(file.Open()); if (vrfile.NeedsExternalPalette) { using (System.Windows.Forms.OpenFileDialog a = new System.Windows.Forms.OpenFileDialog { DefaultExt = gvm ? "gvp" : "pvp", Filter = gvm ? "GVP Files|*.gvp" : "PVP Files|*.pvp", InitialDirectory = System.IO.Path.GetDirectoryName(filename), Title = "External palette file" }) { if (pvp == null) { if (a.ShowDialog() == System.Windows.Forms.DialogResult.OK) { pvp = gvm ? (VpPalette) new GvpPalette(a.FileName) : (VpPalette) new PvpPalette(a.FileName); } else { return(new BMPInfo[0]); } } } if (gvm) { ((GvrTexture)vrfile).SetPalette((GvpPalette)pvp); } else { ((PvrTexture)vrfile).SetPalette((PvpPalette)pvp); } } try { functionReturnValue.Add(new BMPInfo(Path.GetFileNameWithoutExtension(file.Name), vrfile.ToBitmap())); } catch { functionReturnValue.Add(new BMPInfo(Path.GetFileNameWithoutExtension(file.Name), new Bitmap(1, 1))); } } return(functionReturnValue.ToArray()); } }
static void Main(string[] args) { Queue <string> files = new Queue <string>(args); if (files.Count == 0) { Console.Write("File: "); files.Enqueue(Console.ReadLine()); } while (files.Count > 0) { string filename = files.Dequeue(); PAKFile pak = new PAKFile(); List <byte> inf = new List <byte>(); string filenoext = Path.GetFileNameWithoutExtension(filename).ToLowerInvariant(); string longdir = "..\\..\\..\\sonic2\\resource\\gd_pc\\prs\\" + filenoext; byte[] filedata = File.ReadAllBytes(filename); using (System.Windows.Forms.Panel panel1 = new System.Windows.Forms.Panel()) using (Device d3ddevice = new Device(0, DeviceType.Hardware, panel1, CreateFlags.SoftwareVertexProcessing, new PresentParameters[] { new PresentParameters() { Windowed = true, SwapEffect = SwapEffect.Discard, EnableAutoDepthStencil = true, AutoDepthStencilFormat = DepthFormat.D24X8 } })) { if (PvrTexture.Is(filedata)) { if (!AddTexture(pak, filenoext, longdir, false, inf, d3ddevice, filename.ToLowerInvariant(), new MemoryStream(filedata))) { continue; } goto end; } else if (GvrTexture.Is(filedata)) { if (!AddTexture(pak, filenoext, longdir, true, inf, d3ddevice, filename.ToLowerInvariant(), new MemoryStream(filedata))) { continue; } goto end; } bool gvm = false; ArchiveBase pvmfile = null; byte[] pvmdata = File.ReadAllBytes(filename); if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase)) { pvmdata = FraGag.Compression.Prs.Decompress(pvmdata); } pvmfile = new PvmArchive(); if (!pvmfile.Is(pvmdata, filename)) { pvmfile = new GvmArchive(); gvm = true; if (!pvmfile.Is(pvmdata, filename)) { Console.WriteLine("{0} is not a valid file.", filename); continue; } } ArchiveEntryCollection pvmentries = pvmfile.Open(pvmdata).Entries; bool fail = false; foreach (ArchiveEntry file in pvmentries) { if (!AddTexture(pak, filenoext, longdir, gvm, inf, d3ddevice, file.Name.ToLowerInvariant(), file.Open())) { fail = true; break; } } if (fail) { continue; } } end: pak.Files.Insert(0, new PAKFile.File(filenoext + '\\' + filenoext + ".inf", longdir + '\\' + filenoext + ".inf", inf.ToArray())); pak.Save(Path.ChangeExtension(filename, "pak")); } }
private bool GetTextures(string filename) { byte[] pvmdata = File.ReadAllBytes(filename); if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase)) { pvmdata = FraGag.Compression.Prs.Decompress(pvmdata); } ArchiveBase pvmfile = new PvmArchive(); List <TextureInfo> newtextures; if (PvmxArchive.Is(pvmdata)) { format = TextureFormat.PVMX; newtextures = new List <TextureInfo>(PvmxArchive.GetTextures(pvmdata).Cast <TextureInfo>()); } else if (PAKFile.Is(filename)) { format = TextureFormat.PAK; PAKFile pak = new PAKFile(filename); string filenoext = Path.GetFileNameWithoutExtension(filename).ToLowerInvariant(); byte[] inf = pak.Files.Single((file) => file.Name.Equals(filenoext + '\\' + filenoext + ".inf", StringComparison.OrdinalIgnoreCase)).Data; newtextures = new List <TextureInfo>(inf.Length / 0x3C); for (int i = 0; i < inf.Length; i += 0x3C) { StringBuilder sb = new StringBuilder(0x1C); for (int j = 0; j < 0x1C; j++) { if (inf[i + j] != 0) { sb.Append((char)inf[i + j]); } else { break; } } byte[] dds = pak.Files.First((file) => file.Name.Equals(filenoext + '\\' + sb.ToString() + ".dds", StringComparison.OrdinalIgnoreCase)).Data; using (MemoryStream str = new MemoryStream(dds)) using (Texture tex = TextureLoader.FromStream(d3ddevice, str)) using (Stream bmp = TextureLoader.SaveToStream(ImageFileFormat.Png, tex)) newtextures.Add(new PakTextureInfo(sb.ToString(), BitConverter.ToUInt32(inf, i + 0x1C), new Bitmap(bmp))); } } else { if (pvmfile.Is(pvmdata, filename)) { format = TextureFormat.PVM; } else { pvmfile = new GvmArchive(); if (!pvmfile.Is(pvmdata, filename)) { MessageBox.Show(this, "Could not open file \"" + filename + "\".", Text, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(false); } format = TextureFormat.GVM; } ArchiveEntryCollection pvmentries = pvmfile.Open(pvmdata).Entries; newtextures = new List <TextureInfo>(pvmentries.Count); switch (format) { case TextureFormat.PVM: PvpPalette pvp = null; foreach (ArchiveEntry file in pvmentries) { PvrTexture vrfile = new PvrTexture(file.Open()); if (vrfile.NeedsExternalPalette) { if (pvp == null) { using (OpenFileDialog a = new OpenFileDialog { DefaultExt = "pvp", Filter = "PVP Files|*.pvp", InitialDirectory = Path.GetDirectoryName(filename), Title = "External palette file" }) if (a.ShowDialog(this) == DialogResult.OK) { pvp = new PvpPalette(a.FileName); } else { MessageBox.Show(this, "Could not open file \"" + Program.Arguments[0] + "\".", Text, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(false); } } vrfile.SetPalette(pvp); } newtextures.Add(new PvrTextureInfo(Path.GetFileNameWithoutExtension(file.Name), vrfile)); } break; case TextureFormat.GVM: GvpPalette gvp = null; foreach (ArchiveEntry file in pvmentries) { GvrTexture vrfile = new GvrTexture(file.Open()); if (vrfile.NeedsExternalPalette) { if (gvp == null) { using (OpenFileDialog a = new OpenFileDialog { DefaultExt = "gvp", Filter = "GVP Files|*.gvp", InitialDirectory = Path.GetDirectoryName(filename), Title = "External palette file" }) if (a.ShowDialog(this) == DialogResult.OK) { gvp = new GvpPalette(a.FileName); } else { MessageBox.Show(this, "Could not open file \"" + Program.Arguments[0] + "\".", Text, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(false); } } vrfile.SetPalette(gvp); } newtextures.Add(new GvrTextureInfo(Path.GetFileNameWithoutExtension(file.Name), vrfile)); } break; } } textures.Clear(); textures.AddRange(newtextures); listBox1.Items.Clear(); listBox1.Items.AddRange(textures.Select((item) => item.Name).ToArray()); UpdateTextureCount(); SetFilename(Path.GetFullPath(filename)); return(true); }
private void SaveTextures() { byte[] data; using (MemoryStream str = new MemoryStream()) { ArchiveWriter writer = null; switch (format) { case TextureFormat.PVM: writer = new PvmArchiveWriter(str); foreach (PvrTextureInfo tex in textures) { if (tex.DataFormat != PvrDataFormat.Index4 && tex.DataFormat != PvrDataFormat.Index8) { System.Drawing.Imaging.BitmapData bmpd = tex.Image.LockBits(new Rectangle(Point.Empty, tex.Image.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); int stride = bmpd.Stride; byte[] bits = new byte[Math.Abs(stride) * bmpd.Height]; System.Runtime.InteropServices.Marshal.Copy(bmpd.Scan0, bits, 0, bits.Length); tex.Image.UnlockBits(bmpd); int tlevels = 0; for (int y = 0; y < tex.Image.Height; y++) { int srcaddr = y * Math.Abs(stride); for (int x = 0; x < tex.Image.Width; x++) { Color c = Color.FromArgb(BitConverter.ToInt32(bits, srcaddr + (x * 4))); if (c.A == 0) { tlevels = 1; } else if (c.A < 255) { tlevels = 2; break; } } if (tlevels == 2) { break; } } if (tlevels == 0) { tex.PixelFormat = PvrPixelFormat.Rgb565; } else if (tlevels == 1) { tex.PixelFormat = PvrPixelFormat.Argb1555; } else if (tlevels == 2) { tex.PixelFormat = PvrPixelFormat.Argb4444; } if (tex.Image.Width == tex.Image.Height) { if (tex.Mipmap) { tex.DataFormat = PvrDataFormat.SquareTwiddledMipmaps; } else { tex.DataFormat = PvrDataFormat.SquareTwiddled; } } else { tex.DataFormat = PvrDataFormat.Rectangle; } } PvrTextureEncoder encoder = new PvrTextureEncoder(tex.Image, tex.PixelFormat, tex.DataFormat); encoder.GlobalIndex = tex.GlobalIndex; MemoryStream pvr = new MemoryStream(); encoder.Save(pvr); pvr.Seek(0, SeekOrigin.Begin); writer.CreateEntry(pvr, tex.Name); } break; case TextureFormat.GVM: writer = new GvmArchiveWriter(str); foreach (GvrTextureInfo tex in textures) { if (tex.DataFormat != GvrDataFormat.Index4 && tex.DataFormat != GvrDataFormat.Index8) { System.Drawing.Imaging.BitmapData bmpd = tex.Image.LockBits(new Rectangle(Point.Empty, tex.Image.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); int stride = bmpd.Stride; byte[] bits = new byte[Math.Abs(stride) * bmpd.Height]; System.Runtime.InteropServices.Marshal.Copy(bmpd.Scan0, bits, 0, bits.Length); tex.Image.UnlockBits(bmpd); int tlevels = 0; for (int y = 0; y < tex.Image.Height; y++) { int srcaddr = y * Math.Abs(stride); for (int x = 0; x < tex.Image.Width; x++) { Color c = Color.FromArgb(BitConverter.ToInt32(bits, srcaddr + (x * 4))); if (c.A == 0) { tlevels = 1; } else if (c.A < 255) { tlevels = 2; break; } } if (tlevels == 2) { break; } } if (!tex.Mipmap) { tex.DataFormat = GvrDataFormat.Argb8888; } else if (tlevels == 0) { tex.DataFormat = GvrDataFormat.Rgb565; } else { tex.DataFormat = GvrDataFormat.Rgb5a3; } } GvrTextureEncoder encoder = new GvrTextureEncoder(tex.Image, tex.PixelFormat, tex.DataFormat); encoder.GlobalIndex = tex.GlobalIndex; MemoryStream gvr = new MemoryStream(); encoder.Save(gvr); gvr.Seek(0, SeekOrigin.Begin); writer.CreateEntry(gvr, tex.Name); } break; case TextureFormat.PVMX: PvmxArchive.Save(str, textures.Cast <PvmxTextureInfo>()); break; case TextureFormat.PAK: PAKFile pak = new PAKFile(); string filenoext = Path.GetFileNameWithoutExtension(filename).ToLowerInvariant(); string longdir = "..\\..\\..\\sonic2\\resource\\gd_pc\\prs\\" + filenoext; List <byte> inf = new List <byte>(textures.Count * 0x3C); foreach (TextureInfo item in textures) { Stream tex = TextureLoader.SaveToStream(ImageFileFormat.Dds, Texture.FromBitmap(d3ddevice, item.Image, Usage.SoftwareProcessing, Pool.Managed)); byte[] tb = new byte[tex.Length]; tex.Read(tb, 0, tb.Length); string name = item.Name.ToLowerInvariant(); if (name.Length > 0x1C) { name = name.Substring(0, 0x1C); } pak.Files.Add(new PAKFile.File(filenoext + '\\' + name + ".dds", longdir + '\\' + name + ".dds", tb)); inf.AddRange(Encoding.ASCII.GetBytes(name)); if (name.Length != 0x1C) { inf.AddRange(new byte[0x1C - name.Length]); } inf.AddRange(BitConverter.GetBytes(item.GlobalIndex)); inf.AddRange(new byte[0xC]); inf.AddRange(BitConverter.GetBytes(item.Image.Width)); inf.AddRange(BitConverter.GetBytes(item.Image.Height)); inf.AddRange(new byte[4]); inf.AddRange(BitConverter.GetBytes(0x80000000)); } pak.Files.Insert(0, new PAKFile.File(filenoext + '\\' + filenoext + ".inf", longdir + '\\' + filenoext + ".inf", inf.ToArray())); pak.Save(filename); return; } writer?.Flush(); data = str.ToArray(); str.Close(); } if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase)) { FraGag.Compression.Prs.Compress(data, filename); } else { File.WriteAllBytes(filename, data); } }
void openFile(string projFileString) { if (projFileString != null) { Templates.ProjectTemplate projFile = ProjectFunctions.openProjectFileString(projFileString); if (projFile.GameInfo.GameName == "SA2PC") { string projFolder = projFile.GameInfo.ProjectFolder; string gameFolder = ""; if (projFile.GameInfo.GameDataFolder != null) { gameFolder = Path.Combine(ProjectFunctions.GetGamePath(projFile.GameInfo.GameName), projFile.GameInfo.GameDataFolder); } else { gameFolder = Path.Combine(ProjectFunctions.GetGamePath(projFile.GameInfo.GameName), "resource", "gd_PC"); } if (File.Exists(Path.Combine(projFolder, "ADVERTISE_data.ini"))) { IniData ini = IniSerializer.Deserialize <IniData>(Path.Combine(projFolder, "ADVERTISE_data.ini")); filename = Path.Combine(projFolder, ini.Files.First((item) => item.Value.Type == "stageselectlist").Value.Filename); levels = new List <StageSelectLevel>(StageSelectLevelList.Load(filename)); string socFilePath = ""; string prsFilePath = ""; if (projFile.GameInfo.GameName == "SA2PC") { if (File.Exists(Path.Combine(projFolder, "gd_PC", "SOC", "stageMapBG.pak"))) { socFilePath = Path.Combine(projFolder, "gd_PC", "SOC", "stageMapBG.pak"); } else { socFilePath = Path.Combine(gameFolder, "SOC", "stageMapBG.pak"); } if (File.Exists(Path.Combine(projFolder, "gd_PC", "PRS", "stageMap.pak"))) { prsFilePath = Path.Combine(projFolder, "gd_PC", "PRS", "stageMap.pak"); } else { prsFilePath = Path.Combine(gameFolder, "PRS", "stageMap.pak"); } } else { socFilePath = Path.Combine(gameFolder, "stageMapBG.prs"); prsFilePath = Path.Combine(gameFolder, "stageMap.prs"); } PAKFile socpak = new PAKFile(socFilePath); using (MemoryStream str = new MemoryStream(socpak.Entries.Find((a) => a.Name.Equals("stagemap.dds")).Data)) bgtex = LoadDDS(str); if (File.Exists(prsFilePath)) { PAKFile pakf = new PAKFile(prsFilePath); byte[] inf = pakf.Entries.Find((a) => a.Name.Equals("stagemap.inf")).Data; uitexs = new Bitmap[inf.Length / 0x3C]; for (int i = 0; i < uitexs.Length; i++) { using (MemoryStream str = new MemoryStream(pakf.Entries.Find( (a) => a.Name.Equals(Encoding.ASCII.GetString(inf, i * 0x3C, 0x1c).TrimEnd('\0') + ".dds")).Data)) uitexs[i] = LoadDDS(str); } } else { uitexs = TextureArchive.GetTextures(prsFilePath, out bool hasNames).Select((tex) => tex.Image).ToArray(); } saveToolStripMenuItem.Enabled = panel1.Enabled = panel2.Enabled = true; selected = 0; level.SelectedIndex = (int)levels[selected].Level; character.SelectedIndex = (int)levels[selected].Character; column.Value = levels[selected].Column; row.Value = levels[selected].Row; DrawLevel(); } } else { MessageBox.Show("The opened project file is not ", "Incorrect File", MessageBoxButtons.OK); } } Program.sapFile = ""; }
/// <summary> /// Main function for extracting archives. /// </summary> static void ExtractArchive(string[] args) { GenericArchive arc; string arcname = extension.ToUpperInvariant(); Console.WriteLine("Extracting {0} file: {1}", arcname.Substring(1, arcname.Length - 1), filePath); byte[] arcdata = File.ReadAllBytes(filePath); outputPath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)); switch (extension.ToLowerInvariant()) { case (".rel"): outputPath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + "_dec.rel"); Console.WriteLine("Output file: {0}", outputPath); byte[] inputData = File.ReadAllBytes(args[0]); byte[] outputData = SA_Tools.HelperFunctions.DecompressREL(inputData); File.WriteAllBytes(outputPath, outputData); Console.WriteLine("File extracted!"); return; case (".pvmx"): arc = new PVMXFile(arcdata); break; case (".prs"): arcdata = FraGag.Compression.Prs.Decompress(arcdata); if (PuyoFile.Identify(arcdata) == PuyoArchiveType.Unknown) { outputPath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".bin"); Console.WriteLine("Output file: {0}", Path.GetFullPath(outputPath)); File.WriteAllBytes(outputPath, arcdata); Console.WriteLine("Archive extracted!"); return; } arc = new PuyoFile(arcdata); break; case (".pvm"): case (".gvm"): arc = new PuyoFile(arcdata); break; case (".pb"): arc = new PBFile(arcdata); break; case (".pak"): arc = new PAKFile(filePath); break; case (".dat"): arc = new DATFile(arcdata); break; case (".mdl"): arc = new MDLArchive(arcdata); break; case (".mdt"): arc = new MDTArchive(arcdata); break; case (".mld"): arc = new MLDArchive(arcdata); break; case (".mlt"): arc = new MLTArchive(arcdata); break; default: Console.WriteLine("Unknown archive type"); return; } Console.WriteLine("Output folder: {0}", Path.GetFullPath(outputPath)); Directory.CreateDirectory(outputPath); foreach (GenericArchiveEntry entry in arc.Entries) { Console.WriteLine("Extracting file: {0}", entry.Name); File.WriteAllBytes(Path.Combine(outputPath, entry.Name), entry.Data); } arc.CreateIndexFile(outputPath); Console.WriteLine("Archive extracted!"); }
public static ModelLoadResult LoadModels(IFileAccess access, string name) { var pak = new PAKFile(access.GetContent(name)); return(LoadModels(pak)); }