public override byte[] Rebuild() { FileOutput f = new FileOutput(); f.Endian = Endian; f.writeUInt(0x0000FEFF); f.Endian = Endianness.Big; f.writeUInt(Magic); f.Endian = Endian; f.writeInt(0); // Always 0 f.writeInt(Frames.Count); for (int i = 0; i < Frames.Count; i++) { f.writeFloat(Frames[i].qx); f.writeFloat(Frames[i].qy); f.writeFloat(Frames[i].qz); f.writeFloat(Frames[i].qw); f.writeFloat(Frames[i].x); f.writeFloat(Frames[i].y); f.writeFloat(Frames[i].z); } return(f.getBytes()); }
public void Save(string filename) { FileOutput f = new FileOutput(); f.Endian = System.IO.Endianness.Big; f.writeChars("ATKD".ToCharArray()); f.writeInt(entries.Count); f.writeUInt(commonSubactions); f.writeUInt(uniqueSubactions); foreach (Entry e in entries) { f.writeUShort(e.subaction); f.writeUShort(0); f.writeUShort(e.startFrame); f.writeUShort(e.lastFrame); f.writeFloat(e.xmin); f.writeFloat(e.xmax); f.writeFloat(e.ymin); f.writeFloat(e.ymax); } f.save(filename); }
public override byte[] Rebuild() { FileOutput o = new FileOutput(); FileOutput data = new FileOutput(); o.writeUInt(0x4E545033); // "NTP3" o.writeUShort(Version); o.writeUShort((ushort)Nodes.Count); o.writeInt(0); o.writeInt(0); //calculate total header size uint headerLength = 0; foreach (NutTexture texture in Nodes) { byte surfaceCount = (byte)texture.surfaces.Count; bool isCubemap = surfaceCount == 6; if (surfaceCount < 1 || surfaceCount > 6) { throw new NotImplementedException($"Unsupported surface amount {surfaceCount} for texture with hash 0x{texture.HashId:X}. 1 to 6 faces are required."); } else if (surfaceCount > 1 && surfaceCount < 6) { throw new NotImplementedException($"Unsupported cubemap face amount for texture with hash 0x{texture.HashId:X}. Six faces are required."); } byte mipmapCount = (byte)texture.surfaces[0].mipmaps.Count; ushort headerSize = 0x50; if (isCubemap) { headerSize += 0x10; } if (mipmapCount > 1) { headerSize += (ushort)(mipmapCount * 4); while (headerSize % 0x10 != 0) { headerSize += 1; } } headerLength += headerSize; } // write headers+data foreach (NutTexture texture in Nodes) { byte surfaceCount = (byte)texture.surfaces.Count; bool isCubemap = surfaceCount == 6; byte mipmapCount = (byte)texture.surfaces[0].mipmaps.Count; uint dataSize = 0; foreach (var mip in texture.GetAllMipmaps()) { dataSize += (uint)mip.Length; while (dataSize % 0x10 != 0) { dataSize += 1; } } ushort headerSize = 0x50; if (isCubemap) { headerSize += 0x10; } if (mipmapCount > 1) { headerSize += (ushort)(mipmapCount * 4); while (headerSize % 0x10 != 0) { headerSize += 1; } } o.writeUInt(dataSize + headerSize); o.writeUInt(0); o.writeUInt(dataSize); o.writeUShort(headerSize); o.writeUShort(0); o.writeByte(0); o.writeByte(mipmapCount); o.writeByte(0); o.writeByte(texture.getNutFormat()); o.writeShort(texture.Width); o.writeShort(texture.Height); o.writeInt(0); o.writeUInt(texture.DdsCaps2); o.writeUInt((uint)(headerLength + data.size())); headerLength -= headerSize; o.writeInt(0); o.writeInt(0); o.writeInt(0); if (isCubemap) { o.writeInt(texture.surfaces[0].mipmaps[0].Length); o.writeInt(texture.surfaces[0].mipmaps[0].Length); o.writeInt(0); o.writeInt(0); } if (texture.getNutFormat() == 14 || texture.getNutFormat() == 17) { texture.SwapChannelOrderDown(); } for (byte surfaceLevel = 0; surfaceLevel < surfaceCount; ++surfaceLevel) { for (byte mipLevel = 0; mipLevel < mipmapCount; ++mipLevel) { int ds = data.size(); data.writeBytes(texture.surfaces[surfaceLevel].mipmaps[mipLevel]); data.align(0x10); if (mipmapCount > 1 && surfaceLevel == 0) { o.writeInt(data.size() - ds); } } } o.align(0x10); if (texture.getNutFormat() == 14 || texture.getNutFormat() == 17) { texture.SwapChannelOrderUp(); } o.writeUInt(0x65587400); // "eXt\0" o.writeInt(0x20); o.writeInt(0x10); o.writeInt(0x00); o.writeUInt(0x47494458); // "GIDX" o.writeInt(0x10); o.writeInt(texture.HashId); o.writeInt(0); } o.writeOutput(data); return(o.getBytes()); }
public void Save(string fname) { FileOutput f = new FileOutput(); f.Endian = System.IO.Endianness.Little; f.writeUInt(magic); f.writeUInt(header.size); f.writeUInt(header.flags); f.writeUInt(header.height); f.writeUInt(header.width); f.writeUInt(header.pitchOrLinearSize); f.writeUInt(header.depth); f.writeUInt(header.mipmapCount); for (int i = 0; i < 11; ++i) { f.writeUInt(header.reserved1[i]); } f.writeUInt(header.ddspf.size); f.writeUInt(header.ddspf.flags); f.writeUInt(header.ddspf.fourCC); f.writeUInt(header.ddspf.RGBBitCount); f.writeUInt(header.ddspf.RBitMask); f.writeUInt(header.ddspf.GBitMask); f.writeUInt(header.ddspf.BBitMask); f.writeUInt(header.ddspf.ABitMask); f.writeUInt(header.caps); f.writeUInt(header.caps2); f.writeUInt(header.caps3); f.writeUInt(header.caps4); f.writeUInt(header.reserved2); f.writeBytes(bdata); f.save(fname); }
public override byte[] Rebuild() { FileOutput o = new FileOutput(); FileOutput data = new FileOutput(); //We always want BE for the first six bytes o.Endian = Endianness.Big; data.Endian = Endianness.Big; if (Endian == Endianness.Big) { o.writeUInt(0x4E545033); //NTP3 } else if (Endian == Endianness.Little) { o.writeUInt(0x4E545744); //NTWD } //Most NTWU NUTs are 0x020E, which isn't valid for NTP3/NTWD if (Version > 0x0200) { Version = 0x0200; } o.writeUShort(Version); //After that, endian is used appropriately o.Endian = Endian; data.Endian = Endian; o.writeUShort((ushort)Nodes.Count); o.writeInt(0); o.writeInt(0); //calculate total header size uint headerLength = 0; foreach (NutTexture texture in Nodes) { byte surfaceCount = (byte)texture.surfaces.Count; bool isCubemap = surfaceCount == 6; if (surfaceCount < 1 || surfaceCount > 6) { throw new NotImplementedException($"Unsupported surface amount {surfaceCount} for texture with hash 0x{texture.HashId:X}. 1 to 6 faces are required."); } else if (surfaceCount > 1 && surfaceCount < 6) { throw new NotImplementedException($"Unsupported cubemap face amount for texture with hash 0x{texture.HashId:X}. Six faces are required."); } byte mipmapCount = (byte)texture.surfaces[0].mipmaps.Count; ushort headerSize = 0x50; if (isCubemap) { headerSize += 0x10; } if (mipmapCount > 1) { headerSize += (ushort)(mipmapCount * 4); while (headerSize % 0x10 != 0) { headerSize += 1; } } headerLength += headerSize; } // write headers+data foreach (NutTexture texture in Nodes) { byte surfaceCount = (byte)texture.surfaces.Count; bool isCubemap = surfaceCount == 6; byte mipmapCount = (byte)texture.surfaces[0].mipmaps.Count; uint dataSize = 0; foreach (var mip in texture.GetAllMipmaps()) { dataSize += (uint)mip.Length; while (dataSize % 0x10 != 0) { dataSize += 1; } } ushort headerSize = 0x50; if (isCubemap) { headerSize += 0x10; } if (mipmapCount > 1) { headerSize += (ushort)(mipmapCount * 4); while (headerSize % 0x10 != 0) { headerSize += 1; } } o.writeUInt(dataSize + headerSize); o.writeUInt(0); o.writeUInt(dataSize); o.writeUShort(headerSize); o.writeUShort(0); o.writeByte(0); o.writeByte(mipmapCount); o.writeByte(0); o.writeByte(texture.getNutFormat()); o.writeShort(texture.Width); o.writeShort(texture.Height); o.writeInt(0); o.writeUInt(texture.DdsCaps2); if (Version < 0x0200) { o.writeUInt(0); } else if (Version >= 0x0200) { o.writeUInt((uint)(headerLength + data.size())); } headerLength -= headerSize; o.writeInt(0); o.writeInt(0); o.writeInt(0); if (isCubemap) { o.writeInt(texture.surfaces[0].mipmaps[0].Length); o.writeInt(texture.surfaces[0].mipmaps[0].Length); o.writeInt(0); o.writeInt(0); } if (texture.getNutFormat() == 14 || texture.getNutFormat() == 17) { texture.SwapChannelOrderDown(); } for (byte surfaceLevel = 0; surfaceLevel < surfaceCount; ++surfaceLevel) { for (byte mipLevel = 0; mipLevel < mipmapCount; ++mipLevel) { int ds = data.size(); data.writeBytes(texture.surfaces[surfaceLevel].mipmaps[mipLevel]); data.align(0x10); if (mipmapCount > 1 && surfaceLevel == 0) { o.writeInt(data.size() - ds); } } } o.align(0x10); if (texture.getNutFormat() == 14 || texture.getNutFormat() == 17) { texture.SwapChannelOrderUp(); } o.writeBytes(new byte[] { 0x65, 0x58, 0x74, 0x00 }); // "eXt\0" o.writeInt(0x20); o.writeInt(0x10); o.writeInt(0x00); o.writeBytes(new byte[] { 0x47, 0x49, 0x44, 0x58 }); // "GIDX" o.writeInt(0x10); o.writeInt(texture.HashId); o.writeInt(0); if (Version < 0x0200) { o.writeOutput(data); data = new FileOutput(); } } if (Version >= 0x0200) { o.writeOutput(data); } return(o.getBytes()); }
public override byte[] Rebuild() { FileOutput f = new FileOutput(); f.Endian = Endianness.Big; f.writeString("MTA4"); f.writeUInt(unknown); f.writeUInt(frameCount); f.writeUInt(startFrame); f.writeUInt(endFrame); f.writeUInt(frameRate); f.writeInt(matEntries.Count); if (matEntries.Count > 0) { f.writeInt(0x38); } else { f.writeInt(0); } f.writeInt(visEntries.Count); if (visEntries.Count > 0) { f.writeInt(0x38 + 4 * matEntries.Count); } else { f.writeInt(0); } for (int i = 0; i < 0x10; i++) { f.writeByte(0); } List <byte[]> matEntriesBuilt = new List <byte[]>(); List <byte[]> visEntriesBuilt = new List <byte[]>(); int position = 0x38 + matEntries.Count + visEntries.Count; while (position % 0x10 != 0) { position++; } foreach (MatEntry m in matEntries) { byte[] b = m.Rebuild(position); matEntriesBuilt.Add(b); f.writeInt(position); position += b.Length; while (position % 0x10 != 0) { position++; } } foreach (VisEntry v in visEntries) { byte[] b = v.Rebuild(position); matEntriesBuilt.Add(b); f.writeInt(position); position += b.Length; while (position % 0x10 != 0) { position++; } } while (f.pos() % 0x10 != 0) { f.writeByte(0); } foreach (byte[] b in matEntriesBuilt) { f.writeBytes(b); while (f.pos() % 0x10 != 0) { f.writeByte(0); } } foreach (byte[] b in visEntriesBuilt) { f.writeBytes(b); while (f.pos() % 0x10 != 0) { f.writeByte(0); } } return(f.getBytes()); }