Exemple #1
0
        public iPck(DuplicatableStream duplicatableStream, EndianUtils.Endianness e = EndianUtils.Endianness.BigEndian)
        {
            using (DuplicatableStream s = duplicatableStream.Duplicate()) {
                uint magic = s.ReadUInt32(EndianUtils.Endianness.LittleEndian);
                if (magic != 0x6b635069)
                {
                    throw new Exception("wrong magic");
                }

                uint count        = s.ReadUInt32(e);
                uint offsetsStart = s.ReadUInt32(e);
                uint dataStart    = s.ReadUInt32(e);

                s.Position = offsetsStart;
                uint[] offsets = s.ReadUInt32Array(count, e);

                s.Position = dataStart;
                long dataEnd = s.Length - dataStart;
                Data = new List <byte[]>((int)count);
                for (uint i = 0; i < count; ++i)
                {
                    long start = offsets[i];
                    if (start == 0xffffffffu)
                    {
                        Data.Add(null);
                    }
                    else
                    {
                        long end = FindFileEnd(offsets, i, dataEnd);
                        long len = end - start;
                        s.Position = dataStart + start;
                        Data.Add(s.ReadUInt8Array(len));
                    }
                }
            }
        }
Exemple #2
0
        public void PrintData()
        {
            // save point flags, one byte each, 0x00 not visted 0x01 visited
            byte[] savePointFlags;
            using (DuplicatableStream stream = Stream.Duplicate()) {
                savePointFlags = stream.ReadUInt8Array(0x59);
            }

            PrintSavePoint(savePointFlags, 0x00, "Fiertia Deck (Docked at Atherum)");
            PrintSavePoint(savePointFlags, 0x01, "Atherum");
            PrintSavePoint(savePointFlags, 0x02, "Fiertia Hold");               // same flag for both opportunities?
            PrintSavePoint(savePointFlags, 0x03, "Keiv Moc (Middle)");
            PrintSavePoint(savePointFlags, 0x04, "Keiv Moc (Boss)");
            PrintSavePoint(savePointFlags, 0x05, "Zaphias (Lower Quarter)");
            PrintSavePoint(savePointFlags, 0x06, "Zaphias (Royal Quarter)");
            PrintSavePoint(savePointFlags, 0x07, "Zaphias Castle (Prison)");
            PrintSavePoint(savePointFlags, 0x08, "Zaphias Castle (Kitchen)");               // 2nd visit only
            PrintSavePoint(savePointFlags, 0x09, "Zaphias Castle (Hallways)");              // before zagi fight
            PrintSavePoint(savePointFlags, 0x0A, "Zaphias Castle (Sword Stair)");
            PrintSavePoint(savePointFlags, 0x0B, "Zaphias Castle (Big Hall)");              // 2nd visit only, that big room that leads to the sword stair
            PrintSavePoint(savePointFlags, 0x0C, "Weasand of Cados (Middle)");
            PrintSavePoint(savePointFlags, 0x0D, "Weasand of Cados (Exit)");
            PrintSavePoint(savePointFlags, 0x0E, "Halure (Inn)");
            PrintSavePoint(savePointFlags, 0x0F, "Ghasfarost (Bottom)");
            PrintSavePoint(savePointFlags, 0x10, "Ghasfarost (Top)");
            PrintSavePoint(savePointFlags, 0x11, "Myorzo (Vacant House)");
            PrintSavePoint(savePointFlags, 0x12, "Mt. Temza (Middle)");
            PrintSavePoint(savePointFlags, 0x13, "Mt. Temza (Boss)");
            PrintSavePoint(savePointFlags, 0x14, "Deidon Hold");
            PrintSavePoint(savePointFlags, 0x15, "Northeastern Hypionia");               // aurnion before it's built
            PrintSavePoint(savePointFlags, 0x16, "Aurnion (Developing)");
            PrintSavePoint(savePointFlags, 0x17, "Aurnion (Developed)");
            PrintSavePoint(savePointFlags, 0x18, "Caer Bocram");
            PrintSavePoint(savePointFlags, 0x19, "Quoi Woods");
            PrintSavePoint(savePointFlags, 0x1A, "Dahngrest (Inn)");
            PrintSavePoint(savePointFlags, 0x1B, "Ehmead Hill");
            PrintSavePoint(savePointFlags, 0x1C, "Erealumen (Middle)");
            PrintSavePoint(savePointFlags, 0x1D, "Erealumen (Boss)");
            PrintSavePoint(savePointFlags, 0x1E, "Heracles (Near Engine Room)");
            PrintSavePoint(savePointFlags, 0x1F, "Heracles (Near Control Room)"); // zagi fight
            PrintSavePoint(savePointFlags, 0x20, "Zopheir (Boss)");               // 1st visit only
            PrintSavePoint(savePointFlags, 0x21, "Zopheir (Near Aer Krene)");     // 2nd visit only
            PrintSavePoint(savePointFlags, 0x22, "Manor of the Wicked");
            PrintSavePoint(savePointFlags, 0x23, "Tarqaron (Middle)");
            PrintSavePoint(savePointFlags, 0x24, "Tarqaron (Top)");
            PrintSavePoint(savePointFlags, 0x25, "Baction B1F");
            PrintSavePoint(savePointFlags, 0x26, "Baction B2F");               // both save points on B2F share this flag...?
            PrintSavePoint(savePointFlags, 0x27, "Mantaic (Inn)");
            PrintSavePoint(savePointFlags, 0x28, "Relewiese (Middle)");
            PrintSavePoint(savePointFlags, 0x29, "Relewiese (Boss)");
            PrintSavePoint(savePointFlags, 0x2A, "Capua Nor (Outside Ragou's Mansion)");
            PrintSavePoint(savePointFlags, 0x2B, "Capua Nor (Inn)");
            PrintSavePoint(savePointFlags, 0x2C, "Capua Torim (Inn)");
            PrintSavePoint(savePointFlags, 0x2D, "Shaikos Ruins");
            PrintSavePoint(savePointFlags, 0x2E, "Zaude (Side Entrance)");
            PrintSavePoint(savePointFlags, 0x2F, "Zaude (Alexei)");
            PrintSavePoint(savePointFlags, 0x30, "Zaude (Yeager)");
            PrintSavePoint(savePointFlags, 0x31, "Aspio (Inn)");
            PrintSavePoint(savePointFlags, 0x32, "Nordopolica (Inn)");
            PrintSavePoint(savePointFlags, 0x33, "Heliord (Inn)");
            PrintSavePoint(savePointFlags, 0x34, "Yormgen (Inn)");
            PrintSavePoint(savePointFlags, 0x35, "Weasand of Kogorh (Oasis)");
            PrintSavePoint(savePointFlags, 0x36, "Weasand of Kogorh (Exit)");
            PrintSavePoint(savePointFlags, 0x37, "Egothor Forest");
            PrintSavePoint(savePointFlags, 0x38, "Dahngrest Underpass (Oath)");
            PrintSavePoint(savePointFlags, 0x39, "Ragou's Mansion");               // basement dungeon midpoint
            PrintSavePoint(savePointFlags, 0x3A, "Dahngrest Underpass (Exit)");
            PrintSavePoint(savePointFlags, 0x3B, "Abysmal Hollow (Aer Krene near Yumanju)");
            PrintSavePoint(savePointFlags, 0x3C, "? Abysmal Hollow (Aer Krene near Zaphias)");
            PrintSavePoint(savePointFlags, 0x3D, "Abysmal Hollow (Aer Krene near Heliord)");
            PrintSavePoint(savePointFlags, 0x3E, "Abysmal Hollow (Aer Krene near Nordopolica)");
            PrintSavePoint(savePointFlags, 0x3F, "? Abysmal Hollow (Center)");
            PrintSavePoint(savePointFlags, 0x40, "City of the Waning Moon");
            PrintSavePoint(savePointFlags, 0x41, "Necropolis of Nostalgia A3");
            PrintSavePoint(savePointFlags, 0x42, "Necropolis of Nostalgia A6");
            PrintSavePoint(savePointFlags, 0x43, "Necropolis of Nostalgia A9");
            PrintSavePoint(savePointFlags, 0x44, "Necropolis of Nostalgia A Bottom");
            PrintSavePoint(savePointFlags, 0x45, "Necropolis of Nostalgia B2");
            PrintSavePoint(savePointFlags, 0x46, "Necropolis of Nostalgia B5");
            PrintSavePoint(savePointFlags, 0x47, "Necropolis of Nostalgia B8");
            PrintSavePoint(savePointFlags, 0x48, "Necropolis of Nostalgia B Bottom");
            PrintSavePoint(savePointFlags, 0x49, "Necropolis of Nostalgia C3");
            PrintSavePoint(savePointFlags, 0x4A, "Necropolis of Nostalgia C6");
            PrintSavePoint(savePointFlags, 0x4B, "Necropolis of Nostalgia C9");
            PrintSavePoint(savePointFlags, 0x4C, "Necropolis of Nostalgia C Bottom");
            PrintSavePoint(savePointFlags, 0x4D, "Necropolis of Nostalgia D3");
            PrintSavePoint(savePointFlags, 0x4E, "Necropolis of Nostalgia D6");
            PrintSavePoint(savePointFlags, 0x4F, "Necropolis of Nostalgia D9");
            PrintSavePoint(savePointFlags, 0x50, "Necropolis of Nostalgia D Bottom");
            PrintSavePoint(savePointFlags, 0x51, "Necropolis of Nostalgia E3");
            PrintSavePoint(savePointFlags, 0x52, "Necropolis of Nostalgia E6");
            PrintSavePoint(savePointFlags, 0x53, "Necropolis of Nostalgia E9");
            PrintSavePoint(savePointFlags, 0x54, "Necropolis of Nostalgia E Bottom");
            PrintSavePoint(savePointFlags, 0x55, "Necropolis of Nostalgia F3");
            PrintSavePoint(savePointFlags, 0x56, "Necropolis of Nostalgia F6");
            PrintSavePoint(savePointFlags, 0x57, "Necropolis of Nostalgia F9");
            PrintSavePoint(savePointFlags, 0x58, "Necropolis of Nostalgia F Bottom");
        }
Exemple #3
0
        public override INode GetChildByIndex(long index)
        {
            if (index >= 0 && index < Entries.LongLength)
            {
                uint entryLoc = Entries[index];
                Stream.Position = entryLoc;
                uint type = Stream.ReadUInt32(Endian);

                switch (type)
                {
                // PC vesperia can't agree with itself whether this is endian-agnostic or not, the JP files have it swapped compared to the EN files...
                case 0x69733134:
                case 0x34317369: {
                    Stream.Position = entryLoc + 0x14;
                    uint length = Stream.ReadUInt32(Endian);
                    uint offset = Stream.ReadUInt32(Endian);
                    Stream.Position = entryLoc + 0xbc;
                    byte[] bnsfheader = Stream.ReadUInt8Array(0x30);

                    Stream.Position = Header.StartOfFiles + offset;
                    using (var ms = new MemoryStream()) {
                        ms.Write(bnsfheader);
                        StreamUtils.CopyStream(Stream, ms, length);
                        return(new NubFile(ms.CopyToByteArrayStreamAndDispose(), "bnsf"));
                    }
                }

                case 0x64737000: {
                    Stream.Position = entryLoc + 0x14;
                    uint length = Stream.ReadUInt32(Endian);
                    uint offset = Stream.ReadUInt32(Endian);
                    Stream.Position = entryLoc + 0xbc;
                    byte[] dspheader = Stream.ReadUInt8Array(0x60);

                    Stream.Position = Header.StartOfFiles + offset;
                    using (var ms = new MemoryStream()) {
                        ms.Write(dspheader);
                        StreamUtils.CopyStream(Stream, ms, length);
                        return(new NubFile(ms.CopyToByteArrayStreamAndDispose(), "dsp"));
                    }
                }

                case 0x61743300: {
                    Stream.Position = entryLoc;
                    byte[] at3header = Stream.ReadUInt8Array(0x100);

                    Stream.Position = entryLoc + 0x14;
                    uint length = Stream.ReadUInt32(Endian);
                    uint offset = Stream.ReadUInt32(Endian);
                    Stream.Position = Header.StartOfFiles + offset;

                    using (var ms = new MemoryStream()) {
                        ms.Write(at3header);
                        StreamUtils.CopyStream(Stream, ms, length);
                        return(new NubFile(ms.CopyToByteArrayStreamAndDispose(), "at3"));
                    }
                }

                case 0x76616700: {
                    Stream.Position = entryLoc;
                    byte[] vagheader = Stream.ReadUInt8Array(0xc0);

                    Stream.Position = entryLoc + 0x14;
                    uint length = Stream.ReadUInt32(Endian);
                    uint offset = Stream.ReadUInt32(Endian);
                    Stream.Position = Header.StartOfFiles + offset;

                    using (var ms = new MemoryStream()) {
                        if (Endian == EndianUtils.Endianness.LittleEndian)
                        {
                            // unclear if this needs to be all swapped or just a subset...
                            for (int i = 0; i < 0xc0; i += 4)
                            {
                                ms.WriteByte(vagheader[i + 3]);
                                ms.WriteByte(vagheader[i + 2]);
                                ms.WriteByte(vagheader[i + 1]);
                                ms.WriteByte(vagheader[i + 0]);
                            }
                        }
                        else
                        {
                            ms.Write(vagheader);
                        }
                        ms.WriteUInt64(0);
                        ms.WriteUInt64(0);
                        StreamUtils.CopyStream(Stream, ms, length);
                        return(new NubFile(ms.CopyToByteArrayStreamAndDispose(), "vag"));
                    }
                }

                default:
                    Console.WriteLine("Unimplemented nub subtype: 0x" + type.ToString("x8"));
                    return(null);
                }
            }
            return(null);
        }