Beispiel #1
0
    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();
      }
    }
Beispiel #2
0
    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);
    }
Beispiel #3
0
 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);
 }
Beispiel #4
0
      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);
      }
Beispiel #5
0
 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();
      }
    }
Beispiel #7
0
    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();
      }
    }