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(); } }
Formats::Chiptune::Container::Ptr Parse(const Binary::Container& rawData, Builder& target) { if (!FastCheck(rawData)) { return Formats::Chiptune::Container::Ptr(); } const Binary::TypedContainer& data(rawData); const Header& header = *data.GetField<Header>(0); //workaround for some emulators const std::size_t offset = (header.Version == INT_BEGIN) ? offsetof(Header, Version) : sizeof(header); std::size_t restSize = rawData.Size() - offset; const uint8_t* bdata = data.GetField<uint8_t>(offset); //detect as much chunks as possible, in despite of real format issues while (restSize) { const uint_t reg = *bdata; ++bdata; --restSize; if (INT_BEGIN == reg) { target.AddChunks(1); } else if (INT_SKIP == reg) { if (restSize < 1) { ++restSize;//put byte back break; } target.AddChunks(4 * *bdata); ++bdata; --restSize; } else if (MUS_END == reg) { break; } else if (reg <= 15) //register { if (restSize < 1) { ++restSize;//put byte back break; } target.SetRegister(reg, *bdata); ++bdata; --restSize; } else { ++restSize;//put byte back break; } } const std::size_t usedSize = rawData.Size() - restSize; const Binary::Container::Ptr subData = rawData.GetSubcontainer(0, usedSize); return CreateCalculatingCrcContainer(subData, offset, usedSize - offset); }
Formats::Chiptune::Container::Ptr Decode(const Binary::Container& rawData) const override { if (!Format->Match(rawData)) { return Formats::Chiptune::Container::Ptr(); } const std::size_t realSize = std::min(rawData.Size(), MAX_SIZE); const Binary::Container::Ptr data = rawData.GetSubcontainer(0, realSize); return CreateCalculatingCrcContainer(data, 0, realSize); }
virtual Formats::Chiptune::Container::Ptr Parse(const Binary::Container& rawData, Builder& target) const { const ModuleTraits& traits = Format->GetTraits(rawData); if (!traits.Matched()) { return Formats::Chiptune::Container::Ptr(); } target.SetFirstSubmoduleLocation(0, traits.GetFirstModuleSize()); target.SetSecondSubmoduleLocation(traits.GetFirstModuleSize(), traits.GetSecondModuleSize()); const std::size_t usedSize = traits.GetTotalSize(); const Binary::Container::Ptr subData = rawData.GetSubcontainer(0, usedSize); //use whole container as a fixed data return CreateCalculatingCrcContainer(subData, 0, usedSize); }
Formats::Chiptune::Container::Ptr Parse(const Binary::Container& data, Builder& target) { if (data.Size() < sizeof(RawHeader)) { return Formats::Chiptune::Container::Ptr(); } try { Format format(data); format.ParseMainPart(target); format.ParseExtendedPart(target); const Binary::Container::Ptr subData = format.GetUsedData(); const std::size_t fixedStart = offsetof(RawHeader, RAM); const std::size_t fixedEnd = sizeof(RawHeader); return CreateCalculatingCrcContainer(subData, fixedStart, fixedEnd - fixedStart); } catch (const std::exception&) { return Formats::Chiptune::Container::Ptr(); } }
Formats::Chiptune::Container::Ptr Parse(const Binary::Container& rawData, Builder& target) { const Binary::TypedContainer data = CreateContainer(rawData); if (!FastCheck(data)) { return Formats::Chiptune::Container::Ptr(); } try { const Format format(data); StatisticCollectingBuilder statistic(target); format.ParseCommonProperties(statistic); format.ParsePositions(statistic); Indices usedPatterns = statistic.GetUsedPatterns(); const uint_t mode = statistic.GetMode(); if (mode != SINGLE_AY_MODE && !AddTSPatterns(mode, usedPatterns)) { target.SetMode(SINGLE_AY_MODE); } format.ParsePatterns(usedPatterns, statistic); const Indices& usedSamples = statistic.GetUsedSamples(); format.ParseSamples(usedSamples, target); const Indices& usedOrnaments = statistic.GetUsedOrnaments(); format.ParseOrnaments(usedOrnaments, target); Require(format.GetSize() >= MIN_SIZE); const Binary::Container::Ptr subData = rawData.GetSubcontainer(0, format.GetSize()); const RangeChecker::Range fixedRange = format.GetFixedArea(); return CreateCalculatingCrcContainer(subData, fixedRange.first, fixedRange.second - fixedRange.first); } catch (const std::exception&) { Dbg("Failed to create"); return Formats::Chiptune::Container::Ptr(); } }
Formats::Chiptune::Container::Ptr Parse(const Binary::Container& rawData, Builder& target) { if (!FastCheck(rawData)) { return Formats::Chiptune::Container::Ptr(); } try { const std::size_t size = rawData.Size(); const uint8_t* const begin = static_cast<const uint8_t*>(rawData.Start()); const uint8_t* const end = begin + size; const Header& header = *safe_ptr_cast<const Header*>(begin); const uint_t frames = fromLE(header.Duration); target.SetFrames(frames); std::size_t usedBegin = size; std::size_t usedEnd = 0; for (uint_t reg = 0; reg != header.Buffers.size(); ++reg) { target.StartChannel(reg); const BufferDescription& buf = header.Buffers[reg]; const std::size_t offset = buf.GetAbsoluteOffset(reg); Require(offset < size); Stream stream(buf.SizeHi, begin + offset, end); ParseBuffer(frames, stream, target); usedBegin = std::min(usedBegin, offset); usedEnd = std::max<std::size_t>(usedEnd, stream.GetCursor() - begin); } const Binary::Container::Ptr subData = rawData.GetSubcontainer(0, usedEnd); return CreateCalculatingCrcContainer(subData, usedBegin, usedEnd - usedBegin); } catch (const std::exception&) { return Formats::Chiptune::Container::Ptr(); } }