From 68273e7dca051815c16eef096cf1cc68873b1c6f Mon Sep 17 00:00:00 2001 From: dexyfex Date: Thu, 8 Mar 2018 12:15:28 +1100 Subject: [PATCH] Refactored loading resource files from raw byte array code --- .../GameFiles/FileTypes/YmapFile.cs | 49 +----------- .../GameFiles/FileTypes/YmtFile.cs | 54 +------------ .../GameFiles/FileTypes/YndFile.cs | 50 +----------- .../GameFiles/FileTypes/YtypFile.cs | 77 +++++-------------- CodeWalker.Core/GameFiles/RpfFile.cs | 55 ++++++++++--- Project/ProjectForm.cs | 2 +- Project/ProjectFormOLD.cs | 2 +- 7 files changed, 69 insertions(+), 220 deletions(-) diff --git a/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs index 67c7720..7e61049 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs @@ -71,54 +71,7 @@ namespace CodeWalker.GameFiles { //direct load from a raw, compressed ymap file (openIV-compatible format) - RpfResourceFileEntry resentry = new RpfResourceFileEntry(); - - //hopefully this format has an RSC7 header... - uint rsc7 = BitConverter.ToUInt32(data, 0); - if (rsc7 == 0x37435352) //RSC7 header present! - { - int version = BitConverter.ToInt32(data, 4); - resentry.SystemFlags = BitConverter.ToUInt32(data, 8); - resentry.GraphicsFlags = BitConverter.ToUInt32(data, 12); - if (data.Length > 16) - { - int newlen = data.Length - 16; //trim the header from the data passed to the next step. - byte[] newdata = new byte[newlen]; - Buffer.BlockCopy(data, 16, newdata, 0, newlen); - data = newdata; - } - else - { - data = null; //shouldn't happen... empty.. - } - } - else - { - //direct load from file without the rpf header.. - //assume it's in resource meta format - resentry.SystemFlags = RpfResourceFileEntry.GetFlagsFromSize(data.Length, 0); - resentry.GraphicsFlags = RpfResourceFileEntry.GetFlagsFromSize(0, 2); //graphics type 2 for ymap - } - - var oldresentry = RpfFileEntry as RpfResourceFileEntry; - if (oldresentry != null) //update the existing entry with the new one - { - oldresentry.SystemFlags = resentry.SystemFlags; - oldresentry.GraphicsFlags = resentry.GraphicsFlags; - resentry.Name = oldresentry.Name; - resentry.NameHash = oldresentry.NameHash; - resentry.NameLower = oldresentry.NameLower; - resentry.ShortNameHash = oldresentry.ShortNameHash; - } - else - { - RpfFileEntry = resentry; //just stick it in there for later... - } - - data = ResourceBuilder.Decompress(data); - - - Load(data, resentry); + RpfFile.LoadResourceFile(this, data, 2); Loaded = true; } diff --git a/CodeWalker.Core/GameFiles/FileTypes/YmtFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YmtFile.cs index 20e51c0..0e52c51 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YmtFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YmtFile.cs @@ -43,63 +43,15 @@ namespace CodeWalker.GameFiles - public void LoadRSC(byte[] data) + public void Load(byte[] data) { //direct load from a raw, compressed ymt resource file (openIV-compatible format) - RpfResourceFileEntry resentry = new RpfResourceFileEntry(); + RpfFile.LoadResourceFile(this, data, 2); - //hopefully this format has an RSC7 header... - uint rsc7 = BitConverter.ToUInt32(data, 0); - if (rsc7 == 0x37435352) //RSC7 header present! - { - int version = BitConverter.ToInt32(data, 4); - resentry.SystemFlags = BitConverter.ToUInt32(data, 8); - resentry.GraphicsFlags = BitConverter.ToUInt32(data, 12); - if (data.Length > 16) - { - int newlen = data.Length - 16; //trim the header from the data passed to the next step. - byte[] newdata = new byte[newlen]; - Buffer.BlockCopy(data, 16, newdata, 0, newlen); - data = newdata; - } - else - { - data = null; //shouldn't happen... empty.. - } - } - else - { - //direct load from file without the rpf header.. - //assume it's in resource meta format - resentry.SystemFlags = RpfResourceFileEntry.GetFlagsFromSize(data.Length, 0); - resentry.GraphicsFlags = RpfResourceFileEntry.GetFlagsFromSize(0, 2); //graphics type 2 for ymt/meta - } - - var oldresentry = RpfFileEntry as RpfResourceFileEntry; - if (oldresentry != null) //update the existing entry with the new one - { - oldresentry.SystemFlags = resentry.SystemFlags; - oldresentry.GraphicsFlags = resentry.GraphicsFlags; - resentry.Name = oldresentry.Name; - resentry.NameHash = oldresentry.NameHash; - resentry.NameLower = oldresentry.NameLower; - resentry.ShortNameHash = oldresentry.ShortNameHash; - } - else - { - RpfFileEntry = resentry; //just stick it in there for later... - } - - data = ResourceBuilder.Decompress(data); - - - Load(data, resentry); - - //Loaded = true; + Loaded = true; } - public void Load(byte[] data, RpfFileEntry entry) { RpfFileEntry = entry; diff --git a/CodeWalker.Core/GameFiles/FileTypes/YndFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YndFile.cs index 03cc426..e50366f 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YndFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YndFile.cs @@ -63,60 +63,12 @@ namespace CodeWalker.GameFiles { //direct load from a raw, compressed ynd file (openIV-compatible format) - RpfResourceFileEntry resentry = new RpfResourceFileEntry(); - - //hopefully this format has an RSC7 header... - uint rsc7 = BitConverter.ToUInt32(data, 0); - if (rsc7 == 0x37435352) //RSC7 header present! - { - int version = BitConverter.ToInt32(data, 4); - resentry.SystemFlags = BitConverter.ToUInt32(data, 8); - resentry.GraphicsFlags = BitConverter.ToUInt32(data, 12); - if (data.Length > 16) - { - int newlen = data.Length - 16; //trim the header from the data passed to the next step. - byte[] newdata = new byte[newlen]; - Buffer.BlockCopy(data, 16, newdata, 0, newlen); - data = newdata; - } - else - { - data = null; //shouldn't happen... empty.. - } - } - else - { - //direct load from file without the rpf header.. - //assume it's in resource meta format - resentry.SystemFlags = RpfResourceFileEntry.GetFlagsFromSize(data.Length, 0); - resentry.GraphicsFlags = RpfResourceFileEntry.GetFlagsFromSize(0, 2); //graphics type 2 for ymap - } - - var oldresentry = RpfFileEntry as RpfResourceFileEntry; - if (oldresentry != null) //update the existing entry with the new one - { - oldresentry.SystemFlags = resentry.SystemFlags; - oldresentry.GraphicsFlags = resentry.GraphicsFlags; - resentry.Name = oldresentry.Name; - resentry.NameHash = oldresentry.NameHash; - resentry.NameLower = oldresentry.NameLower; - resentry.ShortNameHash = oldresentry.ShortNameHash; - } - else - { - RpfFileEntry = resentry; //just stick it in there for later... - } - - data = ResourceBuilder.Decompress(data); - - - Load(data, resentry); + RpfFile.LoadResourceFile(this, data, 2); Loaded = true; LoadQueued = true; } - public void Load(byte[] data, RpfFileEntry entry) { Name = entry.Name; diff --git a/CodeWalker.Core/GameFiles/FileTypes/YtypFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YtypFile.cs index b101123..f9d548e 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YtypFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YtypFile.cs @@ -9,12 +9,9 @@ using System.Threading.Tasks; namespace CodeWalker.GameFiles { [TypeConverter(typeof(ExpandableObjectConverter))] - public class YtypFile : PackedFile + public class YtypFile : GameFile, PackedFile { - public RpfFileEntry RpfFileEntry { get; set; } - public string FilePath { get; set; } - public string Name { get; set; } public Meta Meta { get; set; } public PsoFile Pso { get; set; } @@ -40,11 +37,29 @@ namespace CodeWalker.GameFiles + public YtypFile() : base(null, GameFileType.Ytyp) + { + } + public YtypFile(RpfFileEntry entry) : base(entry, GameFileType.Ytyp) + { + } + + public override string ToString() { return (RpfFileEntry != null) ? RpfFileEntry.Name : string.Empty; } + + public void Load(byte[] data) + { + //direct load from a raw, compressed ytyp file (openIV-compatible format) + + RpfFile.LoadResourceFile(this, data, 2); + + Loaded = true; + } + public void Load(byte[] data, RpfFileEntry entry) { Name = entry.Name; @@ -226,61 +241,7 @@ namespace CodeWalker.GameFiles } - public void Load(byte[] data) //REFACTOR THIS WITH YMAP!! - { - //direct load from a raw, compressed ymap file (openIV-compatible format) - RpfResourceFileEntry resentry = new RpfResourceFileEntry(); - - //hopefully this format has an RSC7 header... - uint rsc7 = BitConverter.ToUInt32(data, 0); - if (rsc7 == 0x37435352) //RSC7 header present! - { - int version = BitConverter.ToInt32(data, 4); - resentry.SystemFlags = BitConverter.ToUInt32(data, 8); - resentry.GraphicsFlags = BitConverter.ToUInt32(data, 12); - if (data.Length > 16) - { - int newlen = data.Length - 16; //trim the header from the data passed to the next step. - byte[] newdata = new byte[newlen]; - Buffer.BlockCopy(data, 16, newdata, 0, newlen); - data = newdata; - } - else - { - data = null; //shouldn't happen... empty.. - } - } - else - { - //direct load from file without the rpf header.. - //assume it's in resource meta format - resentry.SystemFlags = RpfResourceFileEntry.GetFlagsFromSize(data.Length, 0); - resentry.GraphicsFlags = RpfResourceFileEntry.GetFlagsFromSize(0, 2); //graphics type 2 for ymap - } - - var oldresentry = RpfFileEntry as RpfResourceFileEntry; - if (oldresentry != null) //update the existing entry with the new one - { - oldresentry.SystemFlags = resentry.SystemFlags; - oldresentry.GraphicsFlags = resentry.GraphicsFlags; - resentry.Name = oldresentry.Name; - resentry.NameHash = oldresentry.NameHash; - resentry.NameLower = oldresentry.NameLower; - resentry.ShortNameHash = oldresentry.ShortNameHash; - } - else - { - RpfFileEntry = resentry; //just stick it in there for later... - } - - data = ResourceBuilder.Decompress(data); - - - Load(data, resentry); - - //Loaded = true; - } } diff --git a/CodeWalker.Core/GameFiles/RpfFile.cs b/CodeWalker.Core/GameFiles/RpfFile.cs index 3373759..f4c1e21 100644 --- a/CodeWalker.Core/GameFiles/RpfFile.cs +++ b/CodeWalker.Core/GameFiles/RpfFile.cs @@ -610,17 +610,20 @@ namespace CodeWalker.GameFiles { if (entry == null) { - entry = CreateResourceFileEntry(data, 0); + entry = CreateResourceFileEntry(ref data, 0); } file = new T(); file.Load(data, entry); } return file; } + + + public static T GetResourceFile(byte[] data) where T : class, PackedFile, new() { T file = null; - RpfFileEntry entry = CreateResourceFileEntry(data, 0); + RpfFileEntry entry = CreateResourceFileEntry(ref data, 0); if ((data != null) && (entry != null)) { file = new T(); @@ -628,27 +631,55 @@ namespace CodeWalker.GameFiles } return file; } + public static void LoadResourceFile(T file, byte[] data, uint ver) where T : class, PackedFile + { + //direct load from a raw, compressed resource file (openIV-compatible format) + RpfResourceFileEntry resentry = CreateResourceFileEntry(ref data, ver); + if (file is GameFile) + { + GameFile gfile = file as GameFile; - public static RpfResourceFileEntry CreateResourceFileEntry(byte[] data, uint ver) + var oldresentry = gfile.RpfFileEntry as RpfResourceFileEntry; + if (oldresentry != null) //update the existing entry with the new one + { + oldresentry.SystemFlags = resentry.SystemFlags; + oldresentry.GraphicsFlags = resentry.GraphicsFlags; + resentry.Name = oldresentry.Name; + resentry.NameHash = oldresentry.NameHash; + resentry.NameLower = oldresentry.NameLower; + resentry.ShortNameHash = oldresentry.ShortNameHash; + } + else + { + gfile.RpfFileEntry = resentry; //just stick it in there for later... + } + } + + data = ResourceBuilder.Decompress(data); + + file.Load(data, resentry); + + } + public static RpfResourceFileEntry CreateResourceFileEntry(ref byte[] data, uint ver) { var resentry = new RpfResourceFileEntry(); - //hopefully this format has an RSC7 header... + //hopefully this data has an RSC7 header... uint rsc7 = BitConverter.ToUInt32(data, 0); if (rsc7 == 0x37435352) //RSC7 header present! { int version = BitConverter.ToInt32(data, 4);//use this instead of what was given... resentry.SystemFlags = BitConverter.ToUInt32(data, 8); resentry.GraphicsFlags = BitConverter.ToUInt32(data, 12); - //if (data.Length > 16) - //{ - // int newlen = data.Length - 16; //trim the header from the data passed to the next step. - // byte[] newdata = new byte[newlen]; - // Buffer.BlockCopy(data, 16, newdata, 0, newlen); - // data = newdata; - //} + if (data.Length > 16) + { + int newlen = data.Length - 16; //trim the header from the data passed to the next step. + byte[] newdata = new byte[newlen]; + Buffer.BlockCopy(data, 16, newdata, 0, newlen); + data = newdata; + } //else //{ // data = null; //shouldn't happen... empty.. @@ -659,7 +690,7 @@ namespace CodeWalker.GameFiles //direct load from file without the rpf header.. //assume it's in resource meta format resentry.SystemFlags = RpfResourceFileEntry.GetFlagsFromSize(data.Length, 0); - resentry.GraphicsFlags = RpfResourceFileEntry.GetFlagsFromSize(0, ver); //graphics type 2 for ymap + resentry.GraphicsFlags = RpfResourceFileEntry.GetFlagsFromSize(0, ver); } resentry.Name = ""; diff --git a/Project/ProjectForm.cs b/Project/ProjectForm.cs index 62b8aa0..f52ad4f 100644 --- a/Project/ProjectForm.cs +++ b/Project/ProjectForm.cs @@ -4220,7 +4220,7 @@ namespace CodeWalker.Project { byte[] data = File.ReadAllBytes(filename); - ymt.LoadRSC(data); + ymt.Load(data); } diff --git a/Project/ProjectFormOLD.cs b/Project/ProjectFormOLD.cs index 62300fb..f244a99 100644 --- a/Project/ProjectFormOLD.cs +++ b/Project/ProjectFormOLD.cs @@ -3775,7 +3775,7 @@ namespace CodeWalker { byte[] data = File.ReadAllBytes(filename); - ymt.LoadRSC(data); + ymt.Load(data); } private void LoadScenarioTreeNodes(YmtFile ymt, TreeNode node)