diff options
Diffstat (limited to 'plugins/sid/sidplay-libs/libsidplay/include/sidplay/SidTune.h')
-rw-r--r-- | plugins/sid/sidplay-libs/libsidplay/include/sidplay/SidTune.h | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/plugins/sid/sidplay-libs/libsidplay/include/sidplay/SidTune.h b/plugins/sid/sidplay-libs/libsidplay/include/sidplay/SidTune.h new file mode 100644 index 00000000..f544afb6 --- /dev/null +++ b/plugins/sid/sidplay-libs/libsidplay/include/sidplay/SidTune.h @@ -0,0 +1,356 @@ +/* + * /home/ms/files/source/libsidtune/RCS/SidTune.h,v + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef SIDTUNE_H +#define SIDTUNE_H + + +#include "sidtypes.h" +#include "Buffer.h" +#include "SmartPtr.h" + +#include <fstream> + + +const uint_least16_t SIDTUNE_MAX_SONGS = 256; +// Also PSID file format limit. + +const uint_least16_t SIDTUNE_MAX_CREDIT_STRINGS = 10; +const uint_least16_t SIDTUNE_MAX_CREDIT_STRLEN = 80+1; +// 80 characters plus terminating zero. + +const uint_least32_t SIDTUNE_MAX_MEMORY = 65536; +const uint_least32_t SIDTUNE_MAX_FILELEN = 65536+2+0x7C; +// C64KB+LOAD+PSID + +const int SIDTUNE_SPEED_VBI = 0; // Vertical-Blanking-Interrupt +const int SIDTUNE_SPEED_CIA_1A = 60; // CIA 1 Timer A + +const int SIDTUNE_CLOCK_UNKNOWN = 0x00; +const int SIDTUNE_CLOCK_PAL = 0x01; // These are also used in the +const int SIDTUNE_CLOCK_NTSC = 0x02; // emulator engine! +const int SIDTUNE_CLOCK_ANY = (SIDTUNE_CLOCK_PAL | SIDTUNE_CLOCK_NTSC); + +const int SIDTUNE_SIDMODEL_UNKNOWN = 0x00; +const int SIDTUNE_SIDMODEL_6581 = 0x01; // These are also used in the +const int SIDTUNE_SIDMODEL_8580 = 0x02; // emulator engine! +const int SIDTUNE_SIDMODEL_ANY = (SIDTUNE_SIDMODEL_6581 | SIDTUNE_SIDMODEL_8580); + +const int SIDTUNE_COMPATIBILITY_C64 = 0x00; // File is C64 compatible +const int SIDTUNE_COMPATIBILITY_PSID = 0x01; // File is PSID specific +const int SIDTUNE_COMPATIBILITY_R64 = 0x02; // File is Real C64 only + + +// Required to export template +#ifndef _SidTune_cpp_ +extern +#endif +template class SID_EXTERN Buffer_sidtt<const uint_least8_t>; + +struct SidTuneInfo +{ + // An instance of this structure is used to transport values to + // and from SidTune objects. + + // You must read (i.e. activate) sub-song specific information + // via: + // const SidTuneInfo& tuneInfo = SidTune[songNumber]; + // const SidTuneInfo& tuneInfo = SidTune.getInfo(); + // void SidTune.getInfo(tuneInfo&); + + // Consider the following fields as read-only, because the SidTune class + // does not provide an implementation of: bool setInfo(const SidTuneInfo&). + // Currently, the only way to get the class to accept values which + // are written to these fields is by creating a derived class. + + const char* formatString; // the name of the identified file format + const char* statusString; // error/status message of last operation + + const char* speedString; // describing the speed a song is running at + + uint_least16_t loadAddr; + uint_least16_t initAddr; + uint_least16_t playAddr; + + uint_least16_t songs; + uint_least16_t startSong; + + // The SID chip base address(es) used by the sidtune. + uint_least16_t sidChipBase1; // 0xD400 (normal, 1st SID) + uint_least16_t sidChipBase2; // 0xD?00 (2nd SID) or 0 (no 2nd SID) + + // Available after song initialization. + // + uint_least16_t irqAddr; // if (playAddr == 0), interrupt handler has been + // installed and starts calling the C64 player + // at this address + uint_least16_t currentSong; // the one that has been initialized + uint_least8_t songSpeed; // intended speed, see top + uint_least8_t clockSpeed; // -"- + uint_least8_t relocStartPage; // First available page for relocation + uint_least8_t relocPages; // Number of pages available for relocation + bool musPlayer; // whether Sidplayer routine has been installed + int sidModel; // Sid Model required for this sid + int compatibility; // compatibility requirements + bool fixLoad; // whether load address might be duplicate + uint_least16_t songLength; // --- not yet supported --- + // + // Song title, credits, ... + // 0 = Title, 1 = Author, 2 = Copyright/Publisher + // + uint_least8_t numberOfInfoStrings; // the number of available text info lines + char* infoString[SIDTUNE_MAX_CREDIT_STRINGS]; + // + uint_least16_t numberOfCommentStrings; // --- not yet supported --- + char ** commentString; // --- not yet supported --- + // + uint_least32_t dataFileLen; // length of single-file sidtune file + uint_least32_t c64dataLen; // length of raw C64 data without load address + char* path; // path to sidtune files; "", if cwd + char* dataFileName; // a first file: e.g. "foo.c64"; "", if none + char* infoFileName; // a second file: e.g. "foo.sid"; "", if none + // +}; + + +class SID_EXTERN SidTune +{ + + public: // ---------------------------------------------------------------- + + // If your opendir() and readdir()->d_name return path names + // that contain the forward slash (/) as file separator, but + // your operating system uses a different character, there are + // extra functions that can deal with this special case. Set + // separatorIsSlash to true if you like path names to be split + // correctly. + // You do not need these extra functions if your systems file + // separator is the forward slash. + // + // Load a sidtune from a file. + // + // To retrieve data from standard input pass in filename "-". + // If you want to override the default filename extensions use this + // contructor. Please note, that if the specified ``sidTuneFileName'' + // does exist and the loader is able to determine its file format, + // this function does not try to append any file name extension. + // See ``sidtune.cpp'' for the default list of file name extensions. + // You can specific ``sidTuneFileName = 0'', if you do not want to + // load a sidtune. You can later load one with open(). + SidTune(const char* fileName, const char **fileNameExt = 0, + const bool separatorIsSlash = false); + + // Load a single-file sidtune from a memory buffer. + // Currently supported: PSID format + SidTune(const uint_least8_t* oneFileFormatSidtune, const uint_least32_t sidtuneLength); + + virtual ~SidTune(); + + // The sidTune class does not copy the list of file name extensions, + // so make sure you keep it. If the provided pointer is 0, the + // default list will be activated. This is a static list which + // is used by all SidTune objects. + void setFileNameExtensions(const char **fileNameExt); + + // Load a sidtune into an existing object. + // From a file. + bool load(const char* fileName, const bool separatorIsSlash = false); + + // From a buffer. + bool read(const uint_least8_t* sourceBuffer, const uint_least32_t bufferLen); + + // Select sub-song (0 = default starting song) + // and retrieve active song information. + const SidTuneInfo& operator[](const uint_least16_t songNum); + + // Select sub-song (0 = default starting song) + // and return active song number out of [1,2,..,SIDTUNE_MAX_SONGS]. + uint_least16_t selectSong(const uint_least16_t songNum); + + // Retrieve sub-song specific information. + // Beware! Still member-wise copy! + const SidTuneInfo& getInfo(); + + // Get a copy of sub-song specific information. + // Beware! Still member-wise copy! + void getInfo(SidTuneInfo&); + + // Determine current state of object (true = okay, false = error). + // Upon error condition use ``getInfo'' to get a descriptive + // text string in ``SidTuneInfo.statusString''. + operator bool() { return status; } + bool getStatus() { return status; } + + // Whether sidtune uses two SID chips. + bool isStereo() + { + return (info.sidChipBase1!=0 && info.sidChipBase2!=0); + } + + // Copy sidtune into C64 memory (64 KB). + bool placeSidTuneInC64mem(uint_least8_t* c64buf); + + // --- file save & format conversion --- + + // These functions work for any successfully created object. + // overWriteFlag: true = Overwrite existing file. + // false = Default, return error when file already + // exists. + // One could imagine an "Are you sure ?"-checkbox before overwriting + // any file. + // returns: true = Successful, false = Error condition. + bool saveC64dataFile( const char* destFileName, const bool overWriteFlag = false ); + bool saveSIDfile( const char* destFileName, const bool overWriteFlag = false ); + bool savePSIDfile( const char* destFileName, const bool overWriteFlag = false ); + + // This function can be used to remove a duplicate C64 load address in + // the C64 data (example: FE 0F 00 10 4C ...). A duplicate load address + // of offset 0x02 is indicated by the ``fixLoad'' flag in the SidTuneInfo + // structure. + // + // The ``force'' flag here can be used to remove the first load address + // and set new INIT/PLAY addresses regardless of whether a duplicate + // load address has been detected and indicated by ``fixLoad''. + // For instance, some position independent sidtunes contain a load address + // of 0xE000, but are loaded to 0x0FFE and call the player code at 0x1000. + // + // Do not forget to save the sidtune file. + void fixLoadAddress(const bool force = false, uint_least16_t initAddr = 0, + uint_least16_t playAddr = 0); + + // Does not affect status of object, and therefore can be used + // to load files. Error string is put into info.statusString, though. + bool loadFile(const char* fileName, Buffer_sidtt<const uint_least8_t>& bufferRef); + + bool saveToOpenFile( std::ofstream& toFile, const uint_least8_t* buffer, uint_least32_t bufLen ); + + protected: // ------------------------------------------------------------- + + SidTuneInfo info; + bool status; + + uint_least8_t songSpeed[SIDTUNE_MAX_SONGS]; + uint_least8_t clockSpeed[SIDTUNE_MAX_SONGS]; + uint_least16_t songLength[SIDTUNE_MAX_SONGS]; + + // holds text info from the format headers etc. + char infoString[SIDTUNE_MAX_CREDIT_STRINGS][SIDTUNE_MAX_CREDIT_STRLEN]; + + // See instructions at top. + bool isSlashedFileName; + + public: + // For files with header: offset to real data + uint_least32_t fileOffset; + protected: + + // Needed for MUS/STR player installation. + uint_least16_t musDataLen; + + public: + Buffer_sidtt<const uint_least8_t> cache; + + protected: + + // Filename extensions to append for various file types. + static const char** fileNameExtensions; + + // --- protected member functions --- + + // Convert 32-bit PSID-style speed word to internal tables. + void convertOldStyleSpeedToTables(uint_least32_t speed, + int clock = SIDTUNE_CLOCK_PAL); + + // Check SidTuneInfo fields for all real c64 only formats + bool checkRealC64Info(uint_least32_t speed); + // Check the init address is legal for real C64 only tunes + bool checkRealC64Init(void); + // Check for valid relocation information + bool checkRelocInfo(void); + // Common address resolution procedure + bool resolveAddrs(const uint_least8_t* c64data); + + // Support for various file formats. + + virtual bool PSID_fileSupport(const void* buffer, const uint_least32_t bufLen); + virtual bool PSID_fileSupportSave(std::ofstream& toFile, const uint_least8_t* dataBuffer); + + virtual bool SID_fileSupport(const void* dataBuffer, uint_least32_t dataBufLen, + const void* sidBuffer, uint_least32_t sidBufLen); + virtual bool SID_fileSupportSave(std::ofstream& toFile); + + virtual bool MUS_fileSupport(Buffer_sidtt<const uint_least8_t>& musBufRef, + Buffer_sidtt<const uint_least8_t>& strBufRef); + virtual bool MUS_detect(const void* buffer, const uint_least32_t bufLen, + uint_least32_t& voice3Index); + virtual bool MUS_mergeParts(Buffer_sidtt<const uint_least8_t>& musBufRef, + Buffer_sidtt<const uint_least8_t>& strBufRef); + virtual void MUS_setPlayerAddress(); + virtual void MUS_installPlayer(uint_least8_t *c64buf); + virtual int MUS_decodePetLine(SmartPtr_sidtt<const uint_least8_t>&, char*); + + virtual bool INFO_fileSupport(const void* dataBuffer, uint_least32_t dataBufLen, + const void* infoBuffer, uint_least32_t infoBufLen); + + // Error and status message strings. + static const char* txt_songNumberExceed; + static const char* txt_empty; + static const char* txt_unrecognizedFormat; + static const char* txt_noDataFile; + static const char* txt_notEnoughMemory; + static const char* txt_cantLoadFile; + static const char* txt_cantOpenFile; + static const char* txt_fileTooLong; + static const char* txt_dataTooLong; + static const char* txt_cantCreateFile; + static const char* txt_fileIoError; + static const char* txt_VBI; + static const char* txt_CIA; + static const char* txt_noErrors; + static const char* txt_na; + static const char* txt_badAddr; + static const char* txt_badReloc; + + private: // --------------------------------------------------------------- + + void init(); + void cleanup(); +#if !defined(SIDTUNE_NO_STDIN_LOADER) + void getFromStdIn(); +#endif + void getFromFiles(const char* name); + + void deleteFileNameCopies(); + + // Try to retrieve single-file sidtune from specified buffer. + void getFromBuffer(const uint_least8_t* const buffer, const uint_least32_t bufferLen); + + // Cache the data of a single-file or two-file sidtune and its + // corresponding file names. + bool acceptSidTune(const char* dataFileName, const char* infoFileName, + Buffer_sidtt<const uint_least8_t>& buf); + + bool createNewFileName(Buffer_sidtt<char>& destString, + const char* sourceName, const char* sourceExt); + + private: // prevent copying + SidTune(const SidTune&); + SidTune& operator=(SidTune&); +}; + +#endif /* SIDTUNE_H */ |