Beispiel #1
0
        public void save()
        {
            recalcTable();
            uint       entryCount = (uint)entries.Count;
            FileOutput f          = new FileOutput();

            f.Endian = System.IO.Endianness.Little;
            f.writeUInt(header);
            f.writeUInt(header2);
            f.writeUInt(entryCount);
            f.writeUInt(offsetStart - 0x10);
            foreach (uint i in offsetTable)
            {
                f.writeUInt(i);
            }
            foreach (object[] i in entries)
            {
                string      name            = (string)i[0];
                uint        defaultInternal = (uint)i[1];
                ushort      nusType         = (ushort)i[2];
                ushort      nusCount        = (ushort)i[3];
                List <uint> internalIds     = (List <uint>)i[4];
                f.writeString(name);
                f.writeBytes(new byte[0x10 - name.Length]);
                f.writeUInt(defaultInternal);
                f.writeUShort(nusType);
                f.writeUShort(nusCount);
                foreach (uint j in internalIds)
                {
                    f.writeUInt(j);
                }
                f.writeUShort(0);
            }
            f.save(filename);
        }
Beispiel #2
0
        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);
        }
        private void getNusbankIdInfo(string fname)
        {
            FileData nus3 = new FileData(fname);

            nus3.Endian = Endianness.Little;
            if (nus3.Magic() != "NUS3")  //NUS3
            {
                nus3.seek(0);
                byte[]     data       = nus3.read(nus3.eof());
                byte[]     nus3_decom = ZLibCompressor.DeCompress(data);
                FileOutput newf       = new FileOutput();
                newf.writeBytes(nus3_decom);
                newf.save(fname);
                data        = null;
                nus3_decom  = null;
                nus3        = new FileData(fname);
                nus3.Endian = Endianness.Little;
            }
            else
            {
                nus3.seek(0);
            }

            nus3.seek(4);
            uint size = nus3.readUInt();

            nus3.skip(8);
            uint tocSize = nus3.readUInt();
            uint contentCount = nus3.readUInt();
            uint offset = 0x14 + tocSize;
            uint propOffset = 0, propSize = 0, binfOffset = 0, binfSize = 0, grpOffset = 0, grpSize = 0,
                 dtonOffset = 0, dtonSize = 0, toneOffset = 0, toneSize = 0, junkOffset = 0, junkSize = 0,
                 markOffset = 0, markSize = 0, packOffset = 0, packSize = 0;

            for (int i = 0; i < contentCount; ++i)
            {
                string content = nus3.readString(nus3.pos(), 4);
                nus3.skip(4);
                uint contentSize = nus3.readUInt();
                if (content.Equals("PROP"))
                {
                    propOffset = offset;
                    propSize   = contentSize;
                }
                else if (content.Equals("BINF"))
                {
                    binfOffset = offset;
                    binfSize   = contentSize;
                }
                else if (content.Equals("GRP "))
                {
                    grpOffset = offset;
                    grpSize   = contentSize;
                }
                else if (content.Equals("DTON"))
                {
                    dtonOffset = offset;
                    dtonSize   = contentSize;
                }
                else if (content.Equals("TONE"))
                {
                    toneOffset = offset;
                    toneSize   = contentSize;
                }
                else if (content.Equals("JUNK"))
                {
                    junkOffset = offset;
                    junkSize   = contentSize;
                }
                else if (content.Equals("MARK"))
                {
                    markOffset = offset;
                    markSize   = contentSize;
                }
                else if (content.Equals("PACK"))
                {
                    packOffset = offset;
                    packSize   = contentSize;
                }
                offset += 8 + contentSize;
            }

            nus3.seek((int)binfOffset + 16);
            byte   binfStringSize = nus3.readByte();
            string binfString     = nus3.readString(nus3.pos(), binfStringSize - 1);

            nus3.skip(binfStringSize);
            int padding = (binfStringSize + 1) % 4;

            if (padding != 0)
            {
                nus3.skip(Math.Abs(padding - 4));
            }
            nusIdPos = (uint)nus3.pos();
            nusId    = nus3.readUInt();
            nus3     = null;
        }
Beispiel #4
0
        public 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)Textures.Count);
            o.writeInt(0);
            o.writeInt(0);

            //calculate total header size
            uint headerLength = 0;

            foreach (NutTexture texture in Textures)
            {
                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 Textures)
            {
                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());
        }
Beispiel #5
0
        public void SaveAs(object sender, EventArgs args)
        {
            using (var sfd = new SaveFileDialog())
            {
                sfd.Filter = "HAL DAT|*.dat|" +
                             "All Files (*.*)|*.*";

                sfd.DefaultExt = "dat";
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    if (DatFile.Roots.Length > 0)
                    {
                        if (DatFile.Roots[0].FighterData.Count > 0)
                        {
                            //MessageBox.Show("Cannot save this dat type yet");
                            // gonna have to inject this one for now
                            FileData d = new FileData(fileName);
                            d.Endian = Endianness.Big;
                            FileOutput o = new FileOutput();

                            if (DatFile.Roots.Length > 1)
                            {
                                foreach (DatAnimation a in DatFile.Roots[1].Animations)
                                {
                                    DatFighterScript script = null;
                                    foreach (DatFighterScript s in DatFile.Roots[0].FighterData[0].Scripts)
                                    {
                                        if (s.Text.Equals(a.Text))
                                        {
                                            script = s;
                                            break;
                                        }
                                    }
                                    // Create Animation
                                    MeleeJointAnimationNode n = new MeleeJointAnimationNode(a);
                                    Compiler.Compile(n.GetAsDATFile(), "temp.dat");
                                    if (script != null)
                                    {
                                        script.AnimationOffset = o.size();
                                    }
                                    o.writeBytes(File.ReadAllBytes("temp.dat"));
                                    if (script != null)
                                    {
                                        script.AnimationSize = o.size() - script.AnimationOffset;
                                    }
                                    o.align(0x20, 0xFF);
                                }
                            }
                            if (File.Exists("temp.dat"))
                            {
                                File.Delete("temp.dat");
                            }
                            bool CanExpand = false;
                            foreach (DatFighterScript s in DatFile.Roots[0].FighterData[0].Scripts)
                            {
                                if (DatFile.Roots.Length > 1)
                                {
                                    d.writeInt(s.Offset + 4, s.AnimationOffset);
                                    d.writeInt(s.Offset + 8, s.AnimationSize);
                                }
                                List <byte> newSection = new List <byte>();
                                foreach (SubAction sub in s.SubActions)
                                {
                                    newSection.AddRange(sub.Data);
                                    if (MeleeCMD.GetActionName((byte)(sub.Data[0] >> 2)).Equals("Subroutine") ||
                                        MeleeCMD.GetActionName((byte)(sub.Data[0] >> 2)).Equals("Goto"))
                                    {
                                        newSection[newSection.Count - 1] -= 0x20;
                                    }
                                }
                                newSection.AddRange(new byte[] { 0, 0, 0, 0 });

                                if (newSection.Count > s.SubActionSize && !CanExpand)
                                {
                                    DialogResult dialogResult = MessageBox.Show("Expand the file?\n(Warning incomplete)", "Error: Not enough space", MessageBoxButtons.YesNo);
                                    if (dialogResult != DialogResult.Yes)
                                    {
                                        CanExpand = true;
                                    }
                                    else
                                    {
                                        MessageBox.Show("Failed saving the file");
                                        return;
                                    }
                                }
                                else if (newSection.Count > s.SubActionSize && CanExpand)
                                {
                                    d.writeInt(s.Offset + 12, d.size() - 0x20);
                                    d.writeBytesAt(d.size(), newSection.ToArray());
                                }
                                else
                                {
                                    d.writeInt(s.Offset + 12, s.SubActionOffset - 0x20);
                                    d.writeBytesAt(s.SubActionOffset, newSection.ToArray());
                                }
                                Console.WriteLine(s.SubActionOffset.ToString("x") + " " + s.SubActionSize.ToString("x") + " " + newSection.Count.ToString("x"));
                            }
                            if (DatFile.Roots.Length > 1)
                            {
                                o.save(sfd.FileName.Replace(".dat", "AJ.dat"));
                            }
                            d.writeInt(0, d.size());
                            File.WriteAllBytes(sfd.FileName, d.getSection(0, d.eof()));
                            return;
                        }
                    }
                    Compiler.Compile(DatFile, sfd.FileName);
                }
            }
        }