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);
        }