bool SidTuneWrite::setInfo (const SidTuneInfo &tuneInfo) { SidTuneInfo info = tuneInfo; // Lets verify some of the data if ((info.currentSong > info.songs) || (info.currentSong == 0) || (info.songs > SIDTUNE_MAX_SONGS) || (info.startSong == 0)) { m_info.statusString = txt_songNumberExceed; return false; } if (info.loadAddr == 0) { m_info.statusString = txt_badAddr; return false; } if (info.sidModel1 > SIDTUNE_COMPATIBILITY_BASIC) { m_info.statusString = txt_invalidCompatibility; return false; } if (info.clockSpeed > SIDTUNE_CLOCK_ANY) { m_info.statusString = txt_invalidClockSpeed; return false; } if (info.sidModel1 > SIDTUNE_SIDMODEL_ANY) { m_info.statusString = txt_invalidSidModel; return false; } if (info.sidModel2 > SIDTUNE_SIDMODEL_ANY) { m_info.statusString = txt_invalidSidModel; return false; } switch (info.songSpeed) { case SIDTUNE_SPEED_CIA_1A: switch (info.compatibility) { case SIDTUNE_COMPATIBILITY_R64: case SIDTUNE_COMPATIBILITY_BASIC: m_info.statusString = txt_vbiClockSpeed; return false; } break; case SIDTUNE_SPEED_VBI: break; default: m_info.statusString = txt_invalidSongSpeed; return false; } if (!resolveAddrs(info, 0)) { m_info.statusString = info.statusString; return false; } if (!checkRelocInfo(info)) { m_info.statusString = info.statusString; return false; } if (!checkCompatibility(info)) { m_info.statusString = info.statusString; return false; } m_info = info; for ( uint_least16_t sNum = 0; sNum < m_info.numberOfInfoStrings; sNum++ ) { m_info.infoString[sNum] = infoString[sNum]; for ( uint_least16_t sPos = 0; sPos < SIDTUNE_MAX_CREDIT_STRLEN; sPos++ ) infoString[sNum][sPos] = info.infoString[sNum][sPos]; } for ( uint_least16_t sNum = m_info.numberOfInfoStrings; sNum < SIDTUNE_MAX_CREDIT_STRINGS; sNum++ ) { m_info.infoString[sNum] = infoString[sNum]; for ( uint_least16_t sPos = 0; sPos < SIDTUNE_MAX_CREDIT_STRLEN; sPos++ ) infoString[sNum][sPos] = '\0'; } songSpeed[m_info.currentSong-1] = m_info.songSpeed; return true; }
void SidTuneBase::acceptSidTune(const char* dataFileName, const char* infoFileName, buffer_t& buf, bool isSlashedFileName) { // Make a copy of the data file name and path, if available. if (dataFileName != nullptr) { const size_t fileNamePos = isSlashedFileName ? SidTuneTools::slashedFileNameWithoutPath(dataFileName) : SidTuneTools::fileNameWithoutPath(dataFileName); info->m_path = std::string(dataFileName, fileNamePos); info->m_dataFileName = std::string(dataFileName + fileNamePos); } // Make a copy of the info file name, if available. if (infoFileName != nullptr) { const size_t fileNamePos = isSlashedFileName ? SidTuneTools::slashedFileNameWithoutPath(infoFileName) : SidTuneTools::fileNameWithoutPath(infoFileName); info->m_infoFileName = std::string(infoFileName + fileNamePos); } // Fix bad sidtune set up. if (info->m_songs > MAX_SONGS) { info->m_songs = MAX_SONGS; } else if (info->m_songs == 0) { info->m_songs = 1; } if (info->m_startSong == 0 || info->m_startSong > info->m_songs) { info->m_startSong = 1; } info->m_dataFileLen = buf.size(); info->m_c64dataLen = buf.size() - fileOffset; // Calculate any remaining addresses and then // confirm all the file details are correct resolveAddrs(&buf[fileOffset]); if (checkRelocInfo() == false) { throw loadError(ERR_BAD_RELOC); } if (checkCompatibility() == false) { throw loadError(ERR_BAD_ADDR); } if (info->m_dataFileLen >= 2) { // We only detect an offset of two. Some position independent // sidtunes contain a load address of 0xE000, but are loaded // to 0x0FFE and call player at 0x1000. info->m_fixLoad = (endian_little16(&buf[fileOffset])==(info->m_loadAddr+2)); } // Check the size of the data. if (info->m_c64dataLen > MAX_MEMORY) { throw loadError(ERR_DATA_TOO_LONG); } else if (info->m_c64dataLen == 0) { throw loadError(ERR_EMPTY); } cache.swap(buf); }