static void ParseSubchunk(const SubChunkHeader& hdr, Builder& target) { switch (hdr.ID) { case SubChunkHeader::SongName: target.SetTitle(hdr.GetString()); break; case SubChunkHeader::GameName: target.SetGame(hdr.GetString()); break; case SubChunkHeader::ArtistName: target.SetArtist(hdr.GetString()); break; case SubChunkHeader::DumperName: target.SetDumper(hdr.GetString()); break; case SubChunkHeader::Date: target.SetDumpDate(DateFromInteger(hdr.GetInteger())); break; case SubChunkHeader::Comments: target.SetComment(hdr.GetString()); break; case SubChunkHeader::IntroductionLength: target.SetIntro(hdr.GetTicks()); break; case SubChunkHeader::LoopLength: target.SetLoop(hdr.GetTicks()); break; case SubChunkHeader::FadeLength: target.SetFade(hdr.GetTicks()); break; default: break; } }
Formats::Chiptune::Container::Ptr Parse(const Binary::Container& data, Builder& target) { if (!FastCheck(data)) { return Formats::Chiptune::Container::Ptr(); } try { Binary::InputStream stream(data); stream.ReadField<SignatureType>(); target.SetTitle(DecodeString(stream.ReadCString(MAX_STRING_SIZE))); target.SetAuthor(DecodeString(stream.ReadCString(MAX_STRING_SIZE))); target.SetComment(DecodeString(stream.ReadCString(MAX_COMMENT_SIZE))); const std::size_t fixedOffset = stream.GetPosition(); std::size_t totalFrames = 0; for (;;) { const uint8_t val = stream.ReadField<uint8_t>(); if (val == FINISH) { break; } switch (val) { case BEGIN_FRAME: ++totalFrames; target.BeginFrames(1); break; case SKIP_FRAMES: { const uint_t frames = 3 + stream.ReadField<uint8_t>(); totalFrames += frames; target.BeginFrames(frames); } break; case SELECT_SECOND_CHIP: target.SelectChip(1); break; case SELECT_FIRST_CHIP: target.SelectChip(0); break; case LOOP_MARKER: target.SetLoop(); break; default: target.SetRegister(val, stream.ReadField<uint8_t>()); break; } } Require(totalFrames >= MIN_FRAMES); const std::size_t usedSize = stream.GetPosition(); const auto subData = stream.GetReadData(); return CreateCalculatingCrcContainer(subData, fixedOffset, usedSize - fixedOffset); } catch (const std::exception&) { return Formats::Chiptune::Container::Ptr(); } }