public IList <DdrDatabaseEntry> Decode(ReadOnlySpan <byte> database) { var offset = 0; var length = database.Length; var result = new List <DdrDatabaseEntry>(); var shortNameOffsets = new Dictionary <int, int>(); var longNameOffsets = new Dictionary <int, int>(); var index = 0; // Read database entries while (offset < length) { var raw = database.Slice(offset, 0x80); var id = Encodings.CP437.GetStringWithoutNulls(raw.Slice(0x00, 5)); if (id == string.Empty) { break; } var entry = new DdrDatabaseEntry { Index = index, Id = id, Type = raw[0x06], CdTitle = raw[0x07], InternalId = Bitter.ToInt16(raw, 0x08), MaxBpm = Bitter.ToInt16(raw, 0x10), MinBpm = Bitter.ToInt16(raw, 0x12), Unknown014 = Bitter.ToInt16(raw, 0x14), SonglistOrder = Bitter.ToInt16(raw, 0x16), UnlockNumber = Bitter.ToInt16(raw, 0x18), Difficulties = new[] { raw[0x1C] & 0xF, raw[0x1C] >> 4, raw[0x1D] & 0xF, raw[0x1D] >> 4, raw[0x20] & 0xF, raw[0x20] >> 4, raw[0x21] & 0xF, raw[0x21] >> 4, }, Unknown01E = Bitter.ToInt16(raw, 0x1E), Unknown022 = Bitter.ToInt16(raw, 0x22), Flags = Bitter.ToInt32(raw, 0x24), Radar0 = Bitter.ToInt16Array(raw, 0x28, 8), Radar1 = Bitter.ToInt16Array(raw, 0x38, 8), Radar2 = Bitter.ToInt16Array(raw, 0x48, 8), Radar3 = Bitter.ToInt16Array(raw, 0x58, 8), Radar4 = Bitter.ToInt16Array(raw, 0x68, 8) }; longNameOffsets[index] = Bitter.ToInt32(raw, 0x78); shortNameOffsets[index] = Bitter.ToInt32(raw, 0x7C); result.Add(entry); offset += 0x80; index++; } offset += 0x80; // Read string table var strings = database.Slice(offset); foreach (var kv in longNameOffsets) { result[kv.Key].LongName = Encodings.CP437.GetStringWithoutNulls(strings.Slice(kv.Value)); } foreach (var kv in shortNameOffsets) { result[kv.Key].ShortName = Encodings.CP437.GetStringWithoutNulls(strings.Slice(kv.Value)); } return(result); }
public void Decorate(ChartSet chartSet, DdrDatabaseEntry meta, MetadataDecoratorFileExtensions extensions) { if (meta == null || chartSet == null) { return; } if (chartSet.Metadata == null) { chartSet.Metadata = new Metadata(); } chartSet.Metadata[ChartTag.TitleTag] = meta.LongName ?? meta.ShortName ?? meta.Id; chartSet.Metadata[ChartTag.MusicTag] = $"{meta.Id}.{extensions.Audio}"; chartSet.Metadata[ChartTag.OffsetTag] = $"{(decimal) -chartSet.Charts.First()[NumericData.LinearOffset]}"; chartSet.Metadata[ChartTag.DisplayBpmTag] = $"{meta.MinBpm}:{meta.MaxBpm}"; chartSet.Metadata[ChartTag.BannerTag] = $"{meta.Id}_th.{extensions.Graphics}"; chartSet.Metadata[ChartTag.BackgroundTag] = $"{meta.Id}_bk.{extensions.Graphics}"; foreach (var chart in chartSet.Charts.Where(c => c[NumericData.Id] != null)) { var id = (int)chart[NumericData.Id].Value; if (meta.Difficulties == null || meta.Difficulties.Length == 0) { continue; } if (meta.Difficulties.Length < 8) { switch (id) { case 0x0113: case 0x0114: case 0x0116: chart[NumericData.PlayLevel] = meta.Difficulties[0x0]; break; case 0x0213: case 0x0214: case 0x0216: chart[NumericData.PlayLevel] = meta.Difficulties[0x1]; break; case 0x0313: case 0x0314: case 0x0316: chart[NumericData.PlayLevel] = meta.Difficulties[0x2]; break; case 0x0413: case 0x0414: case 0x0416: chart[NumericData.PlayLevel] = meta.Difficulties[0x4]; break; case 0x0613: case 0x0614: case 0x0616: chart[NumericData.PlayLevel] = meta.Difficulties[0x3]; break; case 0x0118: chart[NumericData.PlayLevel] = meta.Difficulties[0x0]; break; case 0x0218: chart[NumericData.PlayLevel] = meta.Difficulties[0x1]; break; case 0x0318: chart[NumericData.PlayLevel] = meta.Difficulties[0x2]; break; case 0x0418: chart[NumericData.PlayLevel] = meta.Difficulties[0x4]; break; case 0x0618: chart[NumericData.PlayLevel] = meta.Difficulties[0x3]; break; } } else { switch (id) { case 0x0113: case 0x0114: case 0x0116: chart[NumericData.PlayLevel] = meta.Difficulties[0x0]; break; case 0x0213: case 0x0214: case 0x0216: chart[NumericData.PlayLevel] = meta.Difficulties[0x1]; break; case 0x0313: case 0x0314: case 0x0316: chart[NumericData.PlayLevel] = meta.Difficulties[0x2]; break; case 0x0413: case 0x0414: case 0x0416: chart[NumericData.PlayLevel] = meta.Difficulties[0x4]; break; case 0x0613: case 0x0614: case 0x0616: chart[NumericData.PlayLevel] = meta.Difficulties[0x3]; break; case 0x0118: chart[NumericData.PlayLevel] = meta.Difficulties[0x8]; break; case 0x0218: chart[NumericData.PlayLevel] = meta.Difficulties[0x9]; break; case 0x0318: chart[NumericData.PlayLevel] = meta.Difficulties[0xA]; break; case 0x0418: chart[NumericData.PlayLevel] = meta.Difficulties[0xC]; break; case 0x0618: chart[NumericData.PlayLevel] = meta.Difficulties[0xB]; break; } } } }