public CPSSGFile(System.IO.Stream fileStream) { using (EndianBinaryReaderEx reader = new EndianBinaryReaderEx(new BigEndianBitConverter(), fileStream)) { magic = reader.ReadPSSGString(4); if (magic != "PSSG") { throw new Exception("This is not a PSSG file!"); } int size = reader.ReadInt32(); int attributeInfoCount = reader.ReadInt32(); int nodeInfoCount = reader.ReadInt32(); attributeInfo = new CAttributeInfo[attributeInfoCount]; nodeInfo = new CNodeInfo[nodeInfoCount]; for (int i = 0; i < nodeInfoCount; i++) { nodeInfo[i] = new CNodeInfo(reader, this); } long positionAfterInfo = reader.BaseStream.Position; rootNode = new CNode(reader, this, null, true); if (reader.BaseStream.Position < reader.BaseStream.Length) { reader.BaseStream.Position = positionAfterInfo; rootNode = new CNode(reader, this, null, false); if (reader.BaseStream.Position < reader.BaseStream.Length) { throw new Exception("This file is improperly saved and not supported by this version of the PSSG editor." + Environment.NewLine + Environment.NewLine + "Get an older version of the program if you wish to take out its contents, but, put it back together using this program and a non-modded version of the pssg file."); } } } }
public CAttribute(int id, object data, CPSSGFile file, CNode ParentNode) { this.id = id; this.data = data; this.file = file; this.ParentNode = ParentNode; }
public void RemoveNodeInfo(int id) { // Remove all attributeInfos from nodeInfo List <int> attrKeys = new List <int>(nodeInfo[id - 1].attributeInfo.Keys); while (nodeInfo[id - 1].attributeInfo.Count > 0) { RemoveAttributeInfo(attrKeys[0]); } attrKeys = null; // Shift all succeeding nodeInfos and change their id for (int i = id - 1; i < nodeInfo.Length - 1; i++) { nodeInfo[i] = nodeInfo[i + 1]; nodeInfo[i].id = i + 1; } Array.Resize(ref nodeInfo, nodeInfo.Length - 1); // Delete from CNode if (rootNode != null) { if (rootNode.id == id) { rootNode = null; } else { rootNode.RemoveNodeInfo(id); } } }
public CAttribute(EndianBinaryReaderEx reader, CPSSGFile file, CNode node) { this.file = file; ParentNode = node; id = reader.ReadInt32(); size = reader.ReadInt32(); if (size == 4) { data = reader.ReadBytes(size); return; } else if (size > 4) { int strlen = reader.ReadInt32(); if (size - 4 == strlen) { data = reader.ReadPSSGString(strlen); return; } else { reader.Seek(-4, System.IO.SeekOrigin.Current); } } data = reader.ReadBytes(size); }
public CNode AddNode(CNode parentNode, int nodeID) { if (rootNode == null) { CNode newRootNode = new CNode(nodeID, this, null, nodeInfo[nodeID - 1].isDataNode); rootNode = newRootNode; return(newRootNode); } if (parentNode.isDataNode == true) { MessageBox.Show("Adding sub nodes to a data node is not allowed!", "Add Node", MessageBoxButtons.OK, MessageBoxIcon.Stop); return(null); } if (parentNode.subNodes != null) { Array.Resize(ref parentNode.subNodes, parentNode.subNodes.Length + 1); } else { parentNode.subNodes = new CNode[1]; } CNode newNode = new CNode(nodeID, this, parentNode, nodeInfo[nodeID - 1].isDataNode); parentNode.subNodes[parentNode.subNodes.Length - 1] = newNode; return(newNode); }
public CAttribute(CAttribute attrToCopy) { this.file = attrToCopy.file; ParentNode = attrToCopy.ParentNode; id = attrToCopy.id; size = attrToCopy.size; data = attrToCopy.data; }
public CNode(int id, CPSSGFile file, CNode node, bool isDataNode) { this.id = id; this.file = file; this.ParentNode = node; this.isDataNode = isDataNode; attributes = new Dictionary <string, CAttribute>(); if (isDataNode == true) { data = new byte[0]; } }
public void RemoveNode(CNode node) { if (node.ParentNode == null) { rootNode = null; } else { List <CNode> subNodes = new List <CNode>(node.ParentNode.subNodes); subNodes.Remove(node); node.ParentNode.subNodes = subNodes.ToArray(); node = null; } }
public TreeNode CreateTreeViewNode(CNode node) { TreeNode treeNode = new TreeNode(); treeNode.Text = node.Name; treeNode.Tag = node; if (node.subNodes != null) { foreach (CNode subNode in node.subNodes) { treeNode.Nodes.Add(CreateTreeViewNode(subNode)); } } node.TreeNode = treeNode; return(treeNode); }
public CAttribute AddAttribute(CNode parentNode, int attributeID, object data) { if (parentNode == null) { return(null); } if (parentNode.attributes == null) { parentNode.attributes = new Dictionary <string, CAttribute>(); } else if (parentNode.HasAttribute(attributeID)) { parentNode[attributeID].data = data; return(parentNode[attributeID]); } else if (parentNode.attributes.ContainsKey(attributeInfo[attributeID - 1].name)) { return(null); } CAttribute newAttr = new CAttribute(attributeID, data, this, parentNode); parentNode.attributes.Add(newAttr.Name, newAttr); return(newAttr); }
public CNode(CNode nodeToCopy) { this.file = nodeToCopy.file; ParentNode = nodeToCopy.ParentNode; id = nodeToCopy.id; size = nodeToCopy.size; attributeSize = nodeToCopy.attributeSize; attributes = new Dictionary <string, CAttribute>(); CAttribute attr; foreach (KeyValuePair <string, CAttribute> attrToCopy in nodeToCopy.attributes) { attr = new CAttribute(attrToCopy.Value); attributes.Add(attr.Name, attr); } isDataNode = nodeToCopy.isDataNode; if (isDataNode) { data = nodeToCopy.data; } else { // Each node at least 12 bytes (id + size + arg size) subNodes = new CNode[nodeToCopy.subNodes.Length]; int nodeCount = 0; foreach (CNode subNodeToCopy in nodeToCopy.subNodes) { subNodes[nodeCount] = new CNode(subNodeToCopy); nodeCount++; } Array.Resize(ref subNodes, nodeCount); } }
public CNode(int id, CPSSGFile file, CNode node, bool isDataNode) { this.id = id; this.file = file; this.ParentNode = node; this.isDataNode = isDataNode; attributes = new Dictionary<string, CAttribute>(); if (isDataNode == true) { data = new byte[0]; } }
public CAttribute AddAttribute(CNode parentNode, int attributeID, object data) { if (parentNode == null) { return null; } if (parentNode.attributes == null) { parentNode.attributes = new Dictionary<string, CAttribute>(); } else if (parentNode.HasAttribute(attributeID)) { parentNode[attributeID].data = data; return parentNode[attributeID]; } else if (parentNode.attributes.ContainsKey(attributeInfo[attributeID - 1].name)) { return null; } CAttribute newAttr = new CAttribute(attributeID, data, this, parentNode); parentNode.attributes.Add(newAttr.Name, newAttr); return newAttr; }
public CNode AddNode(CNode parentNode, int nodeID) { if (rootNode == null) { CNode newRootNode = new CNode(nodeID, this, null, nodeInfo[nodeID - 1].isDataNode); rootNode = newRootNode; return newRootNode; } if (parentNode.isDataNode == true) { MessageBox.Show("Adding sub nodes to a data node is not allowed!", "Add Node", MessageBoxButtons.OK, MessageBoxIcon.Stop); return null; } if (parentNode.subNodes != null) { Array.Resize(ref parentNode.subNodes, parentNode.subNodes.Length + 1); } else { parentNode.subNodes = new CNode[1]; } CNode newNode = new CNode(nodeID, this, parentNode, nodeInfo[nodeID - 1].isDataNode); parentNode.subNodes[parentNode.subNodes.Length - 1] = newNode; return newNode; }
public TreeNode CreateTreeViewNode(CNode node) { TreeNode treeNode = new TreeNode(); treeNode.Text = node.Name; treeNode.Tag = node; if (node.subNodes != null) { foreach (CNode subNode in node.subNodes) { treeNode.Nodes.Add(CreateTreeViewNode(subNode)); } } node.TreeNode = treeNode; return treeNode; }
public void Write(CNode node) { node.attributes["height"].data = MiscUtil.Conversion.EndianBitConverter.Big.GetBytes(header.height); node.attributes["width"].data = MiscUtil.Conversion.EndianBitConverter.Big.GetBytes(header.width); if (node.attributes.ContainsKey("numberMipMapLevels") == true) { if ((int)header.mipMapCount - 1 >= 0) { node.attributes["numberMipMapLevels"].data = MiscUtil.Conversion.EndianBitConverter.Big.GetBytes(header.mipMapCount - 1); } else { node.attributes["numberMipMapLevels"].data = MiscUtil.Conversion.EndianBitConverter.Big.GetBytes(0); } } if (header.ddspf.rGBBitCount == 32) { node.attributes["texelFormat"].data = "ui8x4"; } else if (header.ddspf.rGBBitCount == 8) { node.attributes["texelFormat"].data = "u8"; } else { node.attributes["texelFormat"].data = Encoding.UTF8.GetString(BitConverter.GetBytes(header.ddspf.fourCC)).ToLower(); } List <CNode> textureImageBlocks = node.FindNodes("TEXTUREIMAGEBLOCK"); if (bdata2 != null && bdata2.Count > 0) { for (int i = 0; i < textureImageBlocks.Count; i++) { switch (textureImageBlocks[i].attributes["typename"].ToString()) { case "Raw": if (bdata2.ContainsKey(0) == true) { textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data = bdata2[0]; textureImageBlocks[i].attributes["size"].data = EndianBitConverter.Big.GetBytes(bdata2[0].Length); } else { throw new Exception("Loading cubemap failed because not all blocks were found. (Write)"); } break; case "RawNegativeX": if (bdata2.ContainsKey(1) == true) { textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data = bdata2[1]; textureImageBlocks[i].attributes["size"].data = EndianBitConverter.Big.GetBytes(bdata2[1].Length); } else { throw new Exception("Loading cubemap failed because not all blocks were found. (Write)"); } break; case "RawPositiveY": if (bdata2.ContainsKey(2) == true) { textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data = bdata2[2]; textureImageBlocks[i].attributes["size"].data = EndianBitConverter.Big.GetBytes(bdata2[2].Length); } else { throw new Exception("Loading cubemap failed because not all blocks were found. (Write)"); } break; case "RawNegativeY": if (bdata2.ContainsKey(3) == true) { textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data = bdata2[3]; textureImageBlocks[i].attributes["size"].data = EndianBitConverter.Big.GetBytes(bdata2[3].Length); } else { throw new Exception("Loading cubemap failed because not all blocks were found. (Write)"); } break; case "RawPositiveZ": if (bdata2.ContainsKey(4) == true) { textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data = bdata2[4]; textureImageBlocks[i].attributes["size"].data = EndianBitConverter.Big.GetBytes(bdata2[4].Length); } else { throw new Exception("Loading cubemap failed because not all blocks were found. (Write)"); } break; case "RawNegativeZ": if (bdata2.ContainsKey(5) == true) { textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data = bdata2[5]; textureImageBlocks[i].attributes["size"].data = EndianBitConverter.Big.GetBytes(bdata2[5].Length); } else { throw new Exception("Loading cubemap failed because not all blocks were found. (Write)"); } break; } } } else { if ((uint)node.attributes["imageBlockCount"].Value > 1) { throw new Exception("Loading cubemap failed because not all blocks were found. (Write)"); } textureImageBlocks[0].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data = bdata; textureImageBlocks[0].attributes["size"].data = EndianBitConverter.Big.GetBytes(bdata.Length); } }
public void RemoveAttribute(CNode node, string attributeName) { node.attributes.Remove(attributeName); }
public void RemoveNode(CNode node) { if (node.ParentNode == null) { rootNode = null; } else { List<CNode> subNodes = new List<CNode>(node.ParentNode.subNodes); subNodes.Remove(node); node.ParentNode.subNodes = subNodes.ToArray(); node = null; } }
public CNode(CNode nodeToCopy) { this.file = nodeToCopy.file; ParentNode = nodeToCopy.ParentNode; id = nodeToCopy.id; size = nodeToCopy.size; attributeSize = nodeToCopy.attributeSize; attributes = new Dictionary<string, CAttribute>(); CAttribute attr; foreach (KeyValuePair<string, CAttribute> attrToCopy in nodeToCopy.attributes) { attr = new CAttribute(attrToCopy.Value); attributes.Add(attr.Name, attr); } isDataNode = nodeToCopy.isDataNode; if (isDataNode) { data = nodeToCopy.data; } else { // Each node at least 12 bytes (id + size + arg size) subNodes = new CNode[nodeToCopy.subNodes.Length]; int nodeCount = 0; foreach (CNode subNodeToCopy in nodeToCopy.subNodes) { subNodes[nodeCount] = new CNode(subNodeToCopy); nodeCount++; } Array.Resize(ref subNodes, nodeCount); } }
public CNode(EndianBinaryReaderEx reader, CPSSGFile file, CNode node, bool useDataNodeCheck) { this.file = file; ParentNode = node; id = reader.ReadInt32(); size = reader.ReadInt32(); long end = reader.BaseStream.Position + size; attributeSize = reader.ReadInt32(); long attributeEnd = reader.BaseStream.Position + attributeSize; if (attributeEnd > reader.BaseStream.Length || end > reader.BaseStream.Length) { throw new Exception("This file is improperly saved and not supported by this version of the PSSG editor." + Environment.NewLine + Environment.NewLine + "Get an older version of the program if you wish to take out its contents, but, put it back together using this program and a non-modded version of the pssg file."); } // Each attr is at least 8 bytes (id + size), so take a conservative guess attributes = new Dictionary<string, CAttribute>(); CAttribute attr; while (reader.BaseStream.Position < attributeEnd) { attr = new CAttribute(reader, file, this); attributes.Add(attr.Name, attr); } switch (Name) { case "BOUNDINGBOX": case "DATA": case "DATABLOCKDATA": case "DATABLOCKBUFFERED": case "INDEXSOURCEDATA": case "INVERSEBINDMATRIX": case "MODIFIERNETWORKINSTANCEUNIQUEMODIFIERINPUT": case "NeAnimPacketData_B1": case "NeAnimPacketData_B4": case "RENDERINTERFACEBOUNDBUFFERED": case "SHADERINPUT": case "TEXTUREIMAGEBLOCKDATA": case "TRANSFORM": isDataNode = true; break; } if (isDataNode == false && useDataNodeCheck == true) { long currentPos = reader.BaseStream.Position; // Check if it has subnodes while (reader.BaseStream.Position < end) { int tempID = reader.ReadInt32(); if (tempID > file.nodeInfo.Length || tempID < 0) { isDataNode = true; break; } else { int tempSize = reader.ReadInt32(); if ((reader.BaseStream.Position + tempSize > end) || (tempSize == 0 && tempID == 0) || tempSize < 0) { isDataNode = true; break; } else if (reader.BaseStream.Position + tempSize == end) { break; } else { reader.BaseStream.Position += tempSize; } } } reader.BaseStream.Position = currentPos; } if (isDataNode) { data = reader.ReadBytes((int)(end - reader.BaseStream.Position)); } else { // Each node at least 12 bytes (id + size + arg size) subNodes = new CNode[(end - reader.BaseStream.Position) / 12]; int nodeCount = 0; while (reader.BaseStream.Position < end) { subNodes[nodeCount] = new CNode(reader, file, this, useDataNodeCheck); nodeCount++; } Array.Resize(ref subNodes, nodeCount); } file.nodeInfo[id - 1].isDataNode = isDataNode; }
public DDS(CNode node, bool cubePreview) { magic = 0x20534444; header.size = 124; header.flags |= DDS_HEADER.Flags.DDSD_CAPS | DDS_HEADER.Flags.DDSD_HEIGHT | DDS_HEADER.Flags.DDSD_WIDTH | DDS_HEADER.Flags.DDSD_PIXELFORMAT; header.height = (uint)(node.attributes["height"].Value); header.width = (uint)(node.attributes["width"].Value); switch ((string)node.attributes["texelFormat"].Value) { case "dxt1": header.flags |= DDS_HEADER.Flags.DDSD_LINEARSIZE; header.pitchOrLinearSize = (uint)(Math.Max(1, (((uint)node.attributes["width"].Value) + 3) / 4) * 8); header.ddspf.flags |= DDS_PIXELFORMAT.Flags.DDPF_FOURCC; header.ddspf.fourCC = BitConverter.ToUInt32(Encoding.UTF8.GetBytes(((string)node.attributes["texelFormat"].Value).ToUpper()), 0); break; case "dxt2": case "dxt3": case "dxt4": case "dxt5": header.flags |= DDS_HEADER.Flags.DDSD_LINEARSIZE; header.pitchOrLinearSize = (uint)(Math.Max(1, (((uint)node.attributes["width"].Value) + 3) / 4) * 16); header.ddspf.flags |= DDS_PIXELFORMAT.Flags.DDPF_FOURCC; header.ddspf.fourCC = BitConverter.ToUInt32(Encoding.UTF8.GetBytes(((string)node.attributes["texelFormat"].Value).ToUpper()), 0); break; case "ui8x4": header.flags |= DDS_HEADER.Flags.DDSD_LINEARSIZE; header.pitchOrLinearSize = (uint)(Math.Max(1, (((uint)node.attributes["width"].Value) + 3) / 4) * 16); // is this right? header.ddspf.flags |= DDS_PIXELFORMAT.Flags.DDPF_ALPHAPIXELS | DDS_PIXELFORMAT.Flags.DDPF_RGB; header.ddspf.fourCC = 0; header.ddspf.rGBBitCount = 32; header.ddspf.rBitMask = 0xFF0000; header.ddspf.gBitMask = 0xFF00; header.ddspf.bBitMask = 0xFF; header.ddspf.aBitMask = 0xFF000000; break; case "u8": header.flags |= DDS_HEADER.Flags.DDSD_LINEARSIZE; header.pitchOrLinearSize = (uint)(Math.Max(1, (((uint)node.attributes["width"].Value) + 3) / 4) * 16); // is this right? // Interchanging the commented values will both work, not sure which is better header.ddspf.flags |= DDS_PIXELFORMAT.Flags.DDPF_LUMINANCE; //header.ddspf.flags |= DDS_PIXELFORMAT.Flags.DDPF_ALPHA; header.ddspf.fourCC = 0; header.ddspf.rGBBitCount = 8; header.ddspf.rBitMask = 0xFF; //header.ddspf.aBitMask = 0xFF; break; } if (node.attributes.ContainsKey("automipmap") == true && node.attributes.ContainsKey("numberMipMapLevels") == true) { if ((uint)node.attributes["automipmap"].Value == 0 && (uint)node.attributes["numberMipMapLevels"].Value > 0) { header.flags |= DDS_HEADER.Flags.DDSD_MIPMAPCOUNT; header.mipMapCount = (uint)((uint)node.attributes["numberMipMapLevels"].Value + 1); header.caps |= DDS_HEADER.Caps.DDSCAPS_MIPMAP | DDS_HEADER.Caps.DDSCAPS_COMPLEX; } } header.reserved1 = new uint[11]; header.ddspf.size = 32; header.caps |= DDS_HEADER.Caps.DDSCAPS_TEXTURE; List <CNode> textureImageBlocks = node.FindNodes("TEXTUREIMAGEBLOCK"); if ((uint)node.attributes["imageBlockCount"].Value > 1) { bdata2 = new Dictionary <int, byte[]>(); for (int i = 0; i < textureImageBlocks.Count; i++) { switch (textureImageBlocks[i].attributes["typename"].ToString()) { case "Raw": header.caps2 |= DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_POSITIVEX; bdata2.Add(0, textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data); break; case "RawNegativeX": header.caps2 |= DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_NEGATIVEX; bdata2.Add(1, textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data); break; case "RawPositiveY": header.caps2 |= DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_POSITIVEY; bdata2.Add(2, textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data); break; case "RawNegativeY": header.caps2 |= DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_NEGATIVEY; bdata2.Add(3, textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data); break; case "RawPositiveZ": header.caps2 |= DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_POSITIVEZ; bdata2.Add(4, textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data); break; case "RawNegativeZ": header.caps2 |= DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_NEGATIVEZ; bdata2.Add(5, textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data); break; } } if (cubePreview == true) { header.caps2 = 0; } else if (bdata2.Count == (uint)node.attributes["imageBlockCount"].Value) { header.caps2 |= DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP; header.flags = header.flags ^ DDS_HEADER.Flags.DDSD_LINEARSIZE; header.pitchOrLinearSize = 0; header.caps |= DDS_HEADER.Caps.DDSCAPS_COMPLEX; } else { throw new Exception("Loading cubemap failed because not all blocks were found. (Read)"); } } else { bdata = textureImageBlocks[0].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data; } }
public DDS(CNode node, bool cubePreview) { magic = 0x20534444; header.size = 124; header.flags |= DDS_HEADER.Flags.DDSD_CAPS | DDS_HEADER.Flags.DDSD_HEIGHT | DDS_HEADER.Flags.DDSD_WIDTH | DDS_HEADER.Flags.DDSD_PIXELFORMAT; header.height = (uint)(node.attributes["height"].Value); header.width = (uint)(node.attributes["width"].Value); switch ((string)node.attributes["texelFormat"].Value) { case "dxt1": header.flags |= DDS_HEADER.Flags.DDSD_LINEARSIZE; header.pitchOrLinearSize = (uint)(Math.Max(1, (((uint)node.attributes["width"].Value) + 3) / 4) * 8); header.ddspf.flags |= DDS_PIXELFORMAT.Flags.DDPF_FOURCC; header.ddspf.fourCC = BitConverter.ToUInt32(Encoding.UTF8.GetBytes(((string)node.attributes["texelFormat"].Value).ToUpper()), 0); break; case "dxt2": case "dxt3": case "dxt4": case "dxt5": header.flags |= DDS_HEADER.Flags.DDSD_LINEARSIZE; header.pitchOrLinearSize = (uint)(Math.Max(1, (((uint)node.attributes["width"].Value) + 3) / 4) * 16); header.ddspf.flags |= DDS_PIXELFORMAT.Flags.DDPF_FOURCC; header.ddspf.fourCC = BitConverter.ToUInt32(Encoding.UTF8.GetBytes(((string)node.attributes["texelFormat"].Value).ToUpper()), 0); break; case "ui8x4": header.flags |= DDS_HEADER.Flags.DDSD_LINEARSIZE; header.pitchOrLinearSize = (uint)(Math.Max(1, (((uint)node.attributes["width"].Value) + 3) / 4) * 16); // is this right? header.ddspf.flags |= DDS_PIXELFORMAT.Flags.DDPF_ALPHAPIXELS | DDS_PIXELFORMAT.Flags.DDPF_RGB; header.ddspf.fourCC = 0; header.ddspf.rGBBitCount = 32; header.ddspf.rBitMask = 0xFF0000; header.ddspf.gBitMask = 0xFF00; header.ddspf.bBitMask = 0xFF; header.ddspf.aBitMask = 0xFF000000; break; case "u8": header.flags |= DDS_HEADER.Flags.DDSD_LINEARSIZE; header.pitchOrLinearSize = (uint)(Math.Max(1, (((uint)node.attributes["width"].Value) + 3) / 4) * 16); // is this right? // Interchanging the commented values will both work, not sure which is better header.ddspf.flags |= DDS_PIXELFORMAT.Flags.DDPF_LUMINANCE; //header.ddspf.flags |= DDS_PIXELFORMAT.Flags.DDPF_ALPHA; header.ddspf.fourCC = 0; header.ddspf.rGBBitCount = 8; header.ddspf.rBitMask = 0xFF; //header.ddspf.aBitMask = 0xFF; break; } if (node.attributes.ContainsKey("automipmap") == true && node.attributes.ContainsKey("numberMipMapLevels") == true) { if ((uint)node.attributes["automipmap"].Value == 0 && (uint)node.attributes["numberMipMapLevels"].Value > 0) { header.flags |= DDS_HEADER.Flags.DDSD_MIPMAPCOUNT; header.mipMapCount = (uint)((uint)node.attributes["numberMipMapLevels"].Value + 1); header.caps |= DDS_HEADER.Caps.DDSCAPS_MIPMAP | DDS_HEADER.Caps.DDSCAPS_COMPLEX; } } header.reserved1 = new uint[11]; header.ddspf.size = 32; header.caps |= DDS_HEADER.Caps.DDSCAPS_TEXTURE; List<CNode> textureImageBlocks = node.FindNodes("TEXTUREIMAGEBLOCK"); if ((uint)node.attributes["imageBlockCount"].Value > 1) { bdata2 = new Dictionary<int, byte[]>(); for (int i = 0; i < textureImageBlocks.Count; i++) { switch (textureImageBlocks[i].attributes["typename"].ToString()) { case "Raw": header.caps2 |= DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_POSITIVEX; bdata2.Add(0, textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data); break; case "RawNegativeX": header.caps2 |= DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_NEGATIVEX; bdata2.Add(1, textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data); break; case "RawPositiveY": header.caps2 |= DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_POSITIVEY; bdata2.Add(2, textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data); break; case "RawNegativeY": header.caps2 |= DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_NEGATIVEY; bdata2.Add(3, textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data); break; case "RawPositiveZ": header.caps2 |= DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_POSITIVEZ; bdata2.Add(4, textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data); break; case "RawNegativeZ": header.caps2 |= DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_NEGATIVEZ; bdata2.Add(5, textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data); break; } } if (cubePreview == true) { header.caps2 = 0; } else if (bdata2.Count == (uint)node.attributes["imageBlockCount"].Value) { header.caps2 |= DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP; header.flags = header.flags ^ DDS_HEADER.Flags.DDSD_LINEARSIZE; header.pitchOrLinearSize = 0; header.caps |= DDS_HEADER.Caps.DDSCAPS_COMPLEX; } else { throw new Exception("Loading cubemap failed because not all blocks were found. (Read)"); } } else { bdata = textureImageBlocks[0].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data; } }
public CNode(EndianBinaryReaderEx reader, CPSSGFile file, CNode node, bool useDataNodeCheck) { this.file = file; ParentNode = node; id = reader.ReadInt32(); size = reader.ReadInt32(); long end = reader.BaseStream.Position + size; attributeSize = reader.ReadInt32(); long attributeEnd = reader.BaseStream.Position + attributeSize; if (attributeEnd > reader.BaseStream.Length || end > reader.BaseStream.Length) { throw new Exception("This file is improperly saved and not supported by this version of the PSSG editor." + Environment.NewLine + Environment.NewLine + "Get an older version of the program if you wish to take out its contents, but, put it back together using this program and a non-modded version of the pssg file."); } // Each attr is at least 8 bytes (id + size), so take a conservative guess attributes = new Dictionary <string, CAttribute>(); CAttribute attr; while (reader.BaseStream.Position < attributeEnd) { attr = new CAttribute(reader, file, this); attributes.Add(attr.Name, attr); } switch (Name) { case "BOUNDINGBOX": case "DATA": case "DATABLOCKDATA": case "DATABLOCKBUFFERED": case "INDEXSOURCEDATA": case "INVERSEBINDMATRIX": case "MODIFIERNETWORKINSTANCEUNIQUEMODIFIERINPUT": case "NeAnimPacketData_B1": case "NeAnimPacketData_B4": case "RENDERINTERFACEBOUNDBUFFERED": case "SHADERINPUT": case "TEXTUREIMAGEBLOCKDATA": case "TRANSFORM": isDataNode = true; break; } if (isDataNode == false && useDataNodeCheck == true) { long currentPos = reader.BaseStream.Position; // Check if it has subnodes while (reader.BaseStream.Position < end) { int tempID = reader.ReadInt32(); if (tempID > file.nodeInfo.Length || tempID < 0) { isDataNode = true; break; } else { int tempSize = reader.ReadInt32(); if ((reader.BaseStream.Position + tempSize > end) || (tempSize == 0 && tempID == 0) || tempSize < 0) { isDataNode = true; break; } else if (reader.BaseStream.Position + tempSize == end) { break; } else { reader.BaseStream.Position += tempSize; } } } reader.BaseStream.Position = currentPos; } if (isDataNode) { data = reader.ReadBytes((int)(end - reader.BaseStream.Position)); } else { // Each node at least 12 bytes (id + size + arg size) subNodes = new CNode[(end - reader.BaseStream.Position) / 12]; int nodeCount = 0; while (reader.BaseStream.Position < end) { subNodes[nodeCount] = new CNode(reader, file, this, useDataNodeCheck); nodeCount++; } Array.Resize(ref subNodes, nodeCount); } file.nodeInfo[id - 1].isDataNode = isDataNode; }
public void Write(CNode node) { node.attributes["height"].data = MiscUtil.Conversion.EndianBitConverter.Big.GetBytes(header.height); node.attributes["width"].data = MiscUtil.Conversion.EndianBitConverter.Big.GetBytes(header.width); if (node.attributes.ContainsKey("numberMipMapLevels") == true) { if ((int)header.mipMapCount - 1 >= 0) { node.attributes["numberMipMapLevels"].data = MiscUtil.Conversion.EndianBitConverter.Big.GetBytes(header.mipMapCount - 1); } else { node.attributes["numberMipMapLevels"].data = MiscUtil.Conversion.EndianBitConverter.Big.GetBytes(0); } } if (header.ddspf.rGBBitCount == 32) { node.attributes["texelFormat"].data = "ui8x4"; } else if (header.ddspf.rGBBitCount == 8) { node.attributes["texelFormat"].data = "u8"; } else { node.attributes["texelFormat"].data = Encoding.UTF8.GetString(BitConverter.GetBytes(header.ddspf.fourCC)).ToLower(); } List<CNode> textureImageBlocks = node.FindNodes("TEXTUREIMAGEBLOCK"); if (bdata2 != null && bdata2.Count > 0) { for (int i = 0; i < textureImageBlocks.Count; i++) { switch (textureImageBlocks[i].attributes["typename"].ToString()) { case "Raw": if (bdata2.ContainsKey(0) == true) { textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data = bdata2[0]; textureImageBlocks[i].attributes["size"].data = EndianBitConverter.Big.GetBytes(bdata2[0].Length); } else { throw new Exception("Loading cubemap failed because not all blocks were found. (Write)"); } break; case "RawNegativeX": if (bdata2.ContainsKey(1) == true) { textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data = bdata2[1]; textureImageBlocks[i].attributes["size"].data = EndianBitConverter.Big.GetBytes(bdata2[1].Length); } else { throw new Exception("Loading cubemap failed because not all blocks were found. (Write)"); } break; case "RawPositiveY": if (bdata2.ContainsKey(2) == true) { textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data = bdata2[2]; textureImageBlocks[i].attributes["size"].data = EndianBitConverter.Big.GetBytes(bdata2[2].Length); } else { throw new Exception("Loading cubemap failed because not all blocks were found. (Write)"); } break; case "RawNegativeY": if (bdata2.ContainsKey(3) == true) { textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data = bdata2[3]; textureImageBlocks[i].attributes["size"].data = EndianBitConverter.Big.GetBytes(bdata2[3].Length); } else { throw new Exception("Loading cubemap failed because not all blocks were found. (Write)"); } break; case "RawPositiveZ": if (bdata2.ContainsKey(4) == true) { textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data = bdata2[4]; textureImageBlocks[i].attributes["size"].data = EndianBitConverter.Big.GetBytes(bdata2[4].Length); } else { throw new Exception("Loading cubemap failed because not all blocks were found. (Write)"); } break; case "RawNegativeZ": if (bdata2.ContainsKey(5) == true) { textureImageBlocks[i].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data = bdata2[5]; textureImageBlocks[i].attributes["size"].data = EndianBitConverter.Big.GetBytes(bdata2[5].Length); } else { throw new Exception("Loading cubemap failed because not all blocks were found. (Write)"); } break; } } } else { if ((uint)node.attributes["imageBlockCount"].Value > 1) { throw new Exception("Loading cubemap failed because not all blocks were found. (Write)"); } textureImageBlocks[0].FindNodes("TEXTUREIMAGEBLOCKDATA")[0].data = bdata; textureImageBlocks[0].attributes["size"].data = EndianBitConverter.Big.GetBytes(bdata.Length); } }
public void RemoveNodeInfo(int id) { // Remove all attributeInfos from nodeInfo List<int> attrKeys = new List<int>(nodeInfo[id - 1].attributeInfo.Keys); while (nodeInfo[id - 1].attributeInfo.Count > 0) { RemoveAttributeInfo(attrKeys[0]); } attrKeys = null; // Shift all succeeding nodeInfos and change their id for (int i = id - 1; i < nodeInfo.Length - 1; i++) { nodeInfo[i] = nodeInfo[i + 1]; nodeInfo[i].id = i + 1; } Array.Resize(ref nodeInfo, nodeInfo.Length - 1); // Delete from CNode if (rootNode != null) { if (rootNode.id == id) { rootNode = null; } else { rootNode.RemoveNodeInfo(id); } } }