Beispiel #1
0
    void GetResult(Dump& data) const override
    {
      Dump rawDump;
      Delegate->GetResult(rawDump);
      Require(0 == rawDump.size() % Registers::TOTAL);
      const uint32_t framesCount = rawDump.size() / Registers::TOTAL;
      const uint_t storedRegisters = Registers::TOTAL;

      const String& title = Params->Title();
      const String author = Params->Author();
      const uint32_t headerSize = sizeof(FYMHeader) + (title.size() + 1) + (author.size() + 1);
      const std::size_t contentSize = framesCount * storedRegisters;

      Binary::DataBuilder builder(headerSize + contentSize);
      FYMHeader& header = builder.Add<FYMHeader>();
      header.HeaderSize = fromLE(headerSize);
      header.FramesCount = fromLE(framesCount);
      header.LoopFrame = fromLE(static_cast<uint32_t>(Params->LoopFrame()));
      header.PSGFreq = fromLE(static_cast<uint32_t>(Params->ClockFreq()));
      header.IntFreq = fromLE(static_cast<uint32_t>(Time::GetFrequencyForPeriod(Params->FrameDuration())));
      builder.AddCString(title);
      builder.AddCString(author);

      for (uint_t reg = 0; reg < storedRegisters; ++reg)
      {
        uint8_t* const result = static_cast<uint8_t*>(builder.Allocate(framesCount));
        for (uint_t frm = 0, inOffset = reg; frm < framesCount; ++frm, inOffset += Registers::TOTAL)
        {
          result[frm] = rawDump[inOffset];
        }
      }
      Dump result;
      builder.CaptureResult(result);
      Binary::Compression::Zlib::Compress(result, data);
    }
Beispiel #2
0
 void DecodeBlock(Binary::InputStream& stream, std::size_t srcSize, Dump& dst)
 {
   const std::size_t LOOKUP = 1;
   const uint8_t* const src = stream.ReadData(LOOKUP);
   const std::size_t used = DecodeBlock(src, srcSize, &dst[0], dst.size());
   stream.ReadData(used - LOOKUP);
 }
Beispiel #3
0
 void ApplyInsertions(Dump& result) const
 {
   if (0 == SizeAddon)
   {
     return;
   }
   Dump tmp(result.size() + SizeAddon);
   Dump::const_iterator src = result.begin();
   const Dump::const_iterator srcEnd = result.end();
   auto dst = tmp.begin();
   std::size_t oldOffset = 0;
   for (const auto& ins : Insertions)
   {
     if (const std::size_t toCopy = ins.first - oldOffset)
     {
       const Dump::const_iterator nextEnd = src + toCopy;
       dst = std::copy(src, nextEnd, dst);
       src = nextEnd;
       oldOffset += toCopy;
     }
     dst = std::copy(ins.second.begin(), ins.second.end(), dst);
   }
   std::copy(src, srcEnd, dst);
   result.swap(tmp);
 }
Beispiel #4
0
 bool IsInfoEmpty(const Dump& info)
 {
   assert(info.size() == 53);
   //28 is fixed
   //25 is title
   const Dump::const_iterator titleStart = info.begin() + 28;
   return info.end() == std::find_if(titleStart, info.end(), std::bind2nd(std::greater<Char>(), Char(' ')));
 }
Beispiel #5
0
 void AddData(const Dump& registers) override
 {
   Devices::AYM::Registers& data = Data->Allocate();
   const uint_t availRegs = std::min<uint_t>(registers.size(), Devices::AYM::Registers::ENV + 1);
   for (uint_t reg = 0, mask = 1; reg != availRegs; ++reg, mask <<= 1)
   {
     const uint8_t val = registers[reg];
     if (reg != Devices::AYM::Registers::ENV || val != 0xff)
     {
       data[static_cast<Devices::AYM::Registers::Index>(reg)] = val;
     }
   }
 }
Beispiel #6
0
 void OnSector(const Formats::CHS& loc, const uint8_t* rawData, std::size_t rawSize, SectorDataType type, std::size_t targetSize) override
 {
   Dump result;
   switch (type)
   {
   case RAW_SECTOR:
     result.assign(rawData, rawData + rawSize);
     break;
   case R2P_SECTOR:
     DecodeR2P(rawData, rawSize, result);
     break;
   case RLE_SECTOR:
     DecodeRLE(rawData, rawSize, result);
     break;
   }
   Require(result.size() == targetSize);
   Builder->SetSector(loc, result);
 }
Beispiel #7
0
 Container::Ptr Decode(const Binary::Container& rawData) const override
 {
   using namespace CompiledSTP;
   if (!Player->Match(rawData))
   {
     return Container::Ptr();
   }
   const Binary::TypedContainer typedData(rawData);
   const std::size_t availSize = rawData.Size();
   const typename Version::RawPlayer& rawPlayer = *typedData.GetField<typename Version::RawPlayer>(0);
   const std::size_t playerSize = rawPlayer.GetSize();
   if (playerSize >= std::min(availSize, CompiledSTP::MAX_PLAYER_SIZE))
   {
     Dbg("Invalid player");
     return Container::Ptr();
   }
   Dbg("Detected player in first %1% bytes", playerSize);
   const std::size_t modDataSize = std::min(CompiledSTP::MAX_MODULE_SIZE, availSize - playerSize);
   const Binary::Container::Ptr modData = rawData.GetSubcontainer(playerSize, modDataSize);
   const Dump metainfo = rawPlayer.GetInfo();
   if (CompiledSTP::IsInfoEmpty(metainfo))
   {
     Dbg("Player has empty metainfo");
     if (const Binary::Container::Ptr originalModule = Formats::Chiptune::SoundTrackerPro::ParseCompiled(*modData, Formats::Chiptune::SoundTrackerPro::GetStubBuilder()))
     {
       const std::size_t originalSize = originalModule->Size();
       return CreateContainer(originalModule, playerSize + originalSize);
     }
   }
   else if (const Binary::Container::Ptr fixedModule = Formats::Chiptune::SoundTrackerPro::InsertMetaInformation(*modData, metainfo))
   {
     if (Formats::Chiptune::SoundTrackerPro::ParseCompiled(*fixedModule, Formats::Chiptune::SoundTrackerPro::GetStubBuilder()))
     {
       const std::size_t originalSize = fixedModule->Size() - metainfo.size();
       return CreateContainer(fixedModule, playerSize + originalSize);
     }
     Dbg("Failed to parse fixed module");
   }
   Dbg("Failed to find module after player");
   return Container::Ptr();
 }
Beispiel #8
0
 void OverwriteData(std::size_t offset, const Dump& data) override
 {
   Require(offset + data.size() <= Source.Size());
   Require(Overwrites.insert(BlobsMap::value_type(offset, data)).second);
 }
Beispiel #9
0
 void InsertData(std::size_t offset, const Dump& data) override
 {
   Require(Insertions.insert(BlobsMap::value_type(offset, data)).second);
   SizeAddon += data.size();
 }