Example #1
0
        // From a file
        public BBPRecord(string path)
        {
            FullPath = path;
            if (Path.GetExtension(path).ToLower() == ".bin")
            {
                BIN2BBP.Convert(path, out mgrItem, out bbp, out vocaloid);
            }
            else if (Path.GetExtension(path).ToLower() == ".bdx")
            {
                var bytes = File.ReadAllBytes(path);
                if (bytes.Length != 32768)
                {
                    throw new InvalidDataException($"{path} has an incorrect filesize!");
                }
                var bdx = bytes.ToStruct<BDXFormat>();
                bbp = BDX2BBP.Convert(bdx, out mgrItem);
                //mgrItem = new JbMgrFormat.JbMgrItem() { Author = bdx.contributor.ToString() };
            }
            else
            {
                var buffer = File.ReadAllBytes(path);
                mgrItem = buffer.Take(312).ToArray().ToStruct<JbMgrFormat.JbMgrItem>();
                var bytes = buffer.Skip(312).ToArray();
                var nums = Enumerable.Range(0, 17).Select(i => BitConverter.ToInt32(bytes, i * 4)).ToList();

                var unc1 = Decompress(bytes, nums[3], nums[4]);
                bbp = unc1.ToStruct<BBPFormat>();
                if (nums[5] == 1) vocaloid = Decompress(bytes, nums[7], nums[8]);
            }
        }
Example #2
0
 public Karaoke(BBPFormat bbp)
 {
     if (IsEnabled = bbp.karaokeTimer[0] != 0x3FFF)
     {
         Lyrics = bbp.karaokeLyrics.ArrayToString();
         timer = bbp.karaokeTimer.Select(t => t & 0x3FFF).ToList();
         maxTicks = (bbp.linesPlus6 - 6) * 48;
     }
     else
     {
         Lyrics = "(no karaoke)";
     }
 }
Example #3
0
        public byte[] vocaloid; // uncompressed

        // From known item and packpath
        public BBPRecord(JbMgrFormat.JbMgrItem item, string path, int slot)
        {
            Slot = slot;
            FullPath = path;
            mgrItem = item;
            if (item.Flags.OnSD)
            {
                var buffer = File.ReadAllBytes(path);
                var bytes = buffer;
                var nums = Enumerable.Range(0, 17).Select(i => BitConverter.ToInt32(bytes, i * 4)).ToList();

                var unc1 = Decompress(bytes, nums[3], nums[4]);
                bbp = unc1.ToStruct<BBPFormat>();
                if (nums[5] == 1) vocaloid = Decompress(bytes, nums[7], nums[8]);
            }
            else
            {
                bbp = new BBPFormat
                {
                    title = item.Title.StringToArray(250),
                    channelInfo = new BBPFormat.ChannelInfo[0]
                };
            }
        }
Example #4
0
        public static void Convert(string path, out JbMgrFormat.JbMgrItem mgrItem, out BBPFormat bbp, out byte[] vocaloid)
        {
            mgrItem = JbMgrFormat.JbMgrItem.Empty;
            vocaloid = null;

            using (var br = new BinReader(path))
            {
                // Obtain ID2 and go look for all records in memory
                br.Goto(0xC16C68);
                mgrItem.OtherID = br.ReadUInt32();
                br.Goto(0xC16E90);
                br.Goto(br.ReadUInt32() + 4);
                br.Goto(br.ReadUInt32());
                br.Goto(br.ReadUInt32() + 56);
                br.Goto(br.ReadUInt32() + 24);
                br.Goto(br.ReadUInt32() + 12);

                // Go through records in memory to find the matching one
                uint recordCount = br.ReadUInt32();
                br.BaseStream.Position += 4;
                uint recordAddr = br.ReadUInt32();
                if (recordCount == 100)
                {
                    br.BaseStream.Position += 8;
                    recordCount = br.ReadUInt32();
                }
                br.Goto(recordAddr);
                while (br.ReadUInt32() != mgrItem.OtherID)
                {
                    if (--recordCount == 0) throw new InvalidDataException($"{path} has incorrect data -- could not find matching record");
                    br.BaseStream.Position += 48;
                }

                // Read mgrItem metadata from memory
                mgrItem.ID = br.ReadUInt32();
                mgrItem.Title = br.ReadStringPointer();
                if (mgrItem.Title.Length == 50 && mgrItem.Title[49] == '…')
                {
                    mgrItem.Title = mgrItem.Title.Substring(0, 49);
                }
                mgrItem.TitleSimple = br.ReadStringPointer().Simplify();
                br.BaseStream.Position += 8;
                mgrItem.Author = br.ReadStringPointer();
                br.BaseStream.Position += 12;
                var code = br.ReadStringPointer();

                // Finally, obtain pack data
                br.Goto(0xC16CF4);
                var packaddr = br.ReadUInt32();
                var packsize = br.ReadInt32();
                if (packsize >= 16777216) throw new InvalidDataException($"{path} has incorrect header error #5 {mgrItem.Title}:{mgrItem.Author}");
                br.Goto(packaddr);
                var bytes = br.ReadBytes(packsize);

                if (!gzipHeaderBytes.SequenceEqual(bytes.Take(16)))
                    throw new InvalidDataException($"{path} has incorrect data error #7 {mgrItem.Title}:{mgrItem.Author}");

                var nums = Enumerable.Range(0, 17).Select(i => BitConverter.ToInt32(bytes, i * 4)).ToList();

                //overwrite bbp's ID and title
                bbp = Decompress(bytes, nums[3], nums[4]).ToStruct<BBPFormat>();
                bbp.titleID = (int)mgrItem.ID;
                bbp.title = mgrItem.Title.StringToArray(bbp.title.Length);
                bbp.test0 = 1;
                bbp.test2 = (byte)(char.IsNumber(code[1]) ? 0 : 1);

                vocaloid = null;
                if (nums[5] == 1) vocaloid = Decompress(bytes, nums[7], nums[8]);
                //File.WriteAllBytes($"{path}.dat", bbp.StructToArray());
                //if (vocaloid != null) File.WriteAllBytes($"{path}.voc", vocaloid);

                // metadata stuff temporarily here
                var instrTypes = bbp.channelInfo.Select(c => c.playType);
                var hasPiano = instrTypes.Contains(PlayType.Piano);
                var hasGuitar = instrTypes.Contains(PlayType.Guitar);
                var hasDrum = instrTypes.Contains(PlayType.Drum);

                //mgr.Flags
                var instrx = bbp.timeSignature == 3;
                var lyrics = bbp.karaokeTimer[0] != 0x3FFF;
                var melody = bbp.test3 != -1;
                var isclassic = bbp.test2 == 1;

                mgrItem.Flags = new JbMgrFormat.JbMgrItem.JbFlags
                {
                    HasDrum = hasDrum,
                    HasGuitar = hasGuitar,
                    HasPiano = hasPiano,
                    HasLyrics = lyrics,
                    HasMelody = melody,
                    IsValid = true,
                    OnSD = true,
                    HasVocals = vocaloid != null,
                    IsSingable = vocaloid != null,
                    Parts = bbp.channelInfo.Count(c => c.instrument != 0),
                    IsReceived = true,
                    HasInstrX = instrx,
                    IsClassic = isclassic
                };
            }
        }