Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

sid_.cpp

Go to the documentation of this file.
00001 //
00002 // /home/ms/sidplay/libsidplay/fformat/RCS/sid_.cpp,v
00003 // 
00004 
00005 #include "sid_.h"
00006 
00007 
00008 const char text_format[] = "Raw plus SIDPLAY ASCII text file (SID)";
00009 
00010 //const char text_chunkError[] = "ERROR: Invalid chunk in description file";
00011 const char text_truncatedError[] = "ERROR: SID file is truncated";
00012 const char text_noMemError[] = "ERROR: Not enough free memory";
00013 
00014 const char keyword_id[] = "SIDPLAY INFOFILE";
00015 
00016 const char keyword_name[] = "NAME=";            // No white-space characters 
00017 const char keyword_author[] = "AUTHOR=";        // in these keywords, because
00018 const char keyword_copyright[] = "COPYRIGHT=";  // we want to use a white-space
00019 const char keyword_address[] = "ADDRESS=";      // eating string stream to
00020 const char keyword_songs[] = "SONGS=";          // parse most of the header.
00021 const char keyword_speed[] = "SPEED=";
00022 const char keyword_musPlayer[] = "SIDSONG=YES";
00023 
00024 const int sidMinFileSize = 1+sizeof(keyword_id);  // Just to avoid a first segm.fault.
00025 const int parseChunkLen = 80;                     // Enough for all keywords incl. their values.
00026 const int MaxInfoStringLen = (80-1);
00027 
00028 
00029 bool sidTune::SID_fileSupport( void* /*dataBuffer*/, udword /*dataBufLen*/,
00030                                                            void* /*sidBuffer*/, udword /*sidBufLen*/ )
00031 {
00032 #if 0 //ALFRED - TODO
00033         // Remove any format description or error string.
00034         info.formatString = 0;
00035         
00036         // Make sure SID buffer pointer is not zero.
00037         // Check for a minimum file size. If it is smaller, we will not proceed.
00038         if ((sidBuffer==0) || (sidBufLen<sidMinFileSize))
00039         {
00040                 return false;
00041         }
00042 
00043         char* pParseBuf = (char*)sidBuffer;
00044         // First line has to contain the exact identification string.
00045         if ( myStrNcaseCmp( pParseBuf, keyword_id ) != 0 )
00046         {
00047                 return false;
00048         }
00049         else
00050         {
00051                 // At least the ID was found, so set a default error message.
00052                 info.formatString = text_truncatedError;
00053                 
00054                 // Defaults.
00055                 fileOffset = 0;                // no header in separate data file
00056                 info.musPlayer = false;
00057                 info.numberOfInfoStrings = 0;
00058                 udword oldStyleSpeed = 0;
00059 
00060                 // Flags for required entries.
00061                 bool hasAddress = false,
00062                     hasName = false,
00063                     hasAuthor = false,
00064                     hasCopyright = false,
00065                     hasSongs = false,
00066                     hasSpeed = false;
00067         
00068                 // Using a temporary instance of an input string chunk.
00069                 char* pParseChunk = new char[parseChunkLen];
00070                 if ( pParseChunk == 0 )
00071                 {
00072                         info.formatString = text_noMemError;
00073                         return false;
00074                 }
00075                 
00076                 // Parse as long we have not collected all ``required'' entries.
00077                 while ( !hasAddress || !hasName || !hasAuthor || !hasCopyright
00078                             || !hasSongs || !hasSpeed )
00079                 {
00080                         // Skip to next line. Leave loop, if none.
00081                         if (( pParseBuf = returnNextLine( pParseBuf )) == 0 )
00082                         {
00083                                 break;
00084                         }
00085                         // And get a second pointer to the following line.
00086                         char* pNextLine = returnNextLine( pParseBuf );
00087                         udword restLen;
00088                         if ( pNextLine != 0 )
00089                         {
00090                                 // Calculate number of chars between current pos and next line.
00091                                 restLen = (udword)(pNextLine - pParseBuf);
00092                         }
00093                         else
00094                         {
00095                                 // Calculate number of chars between current pos and end of buf.
00096                                 restLen = sidBufLen - (udword)(pParseBuf - (char*)sidBuffer);
00097                         }
00098                         // Create whitespace eating (!) input string stream.
00099                         istrstream parseStream( pParseBuf, restLen );
00100                         // A second one just for copying.
00101                         istrstream parseCopyStream( pParseBuf, restLen );
00102                         if ( !parseStream || !parseCopyStream )
00103                         {
00104                                 break;
00105                         }
00106                         // Now copy the next X characters except white-spaces.
00107                         for ( int i = 0; i < parseChunkLen; i++ )
00108                         {
00109                                 char c;
00110                                 parseCopyStream >> c;
00111                                 pParseChunk[i] = c;
00112                         }
00113                         // Now check for the possible keywords.
00114                         // ADDRESS
00115                         if ( myStrNcaseCmp( pParseChunk, keyword_address ) == 0 )
00116                         {
00117                                 skipToEqu( parseStream );
00118                                 info.loadAddr = (uword)readHex( parseStream );
00119                                 if ( !parseStream )
00120                                     break;
00121                                 info.initAddr = (uword)readHex( parseStream );
00122                                 if ( !parseStream )
00123                                     break;
00124                                 info.playAddr = (uword)readHex( parseStream );
00125                                 hasAddress = true;
00126                         }
00127                         // NAME
00128                         else if ( myStrNcaseCmp( pParseChunk, keyword_name ) == 0 )
00129                         {
00130                                 copyStringValueToEOL( pParseBuf, &infoString[0][0], MaxInfoStringLen );
00131                                 info.nameString = &infoString[0][0];
00132                                 info.infoString[0] = &infoString[0][0];
00133                                 hasName = true;
00134                         }
00135                         // AUTHOR
00136                         else if ( myStrNcaseCmp( pParseChunk, keyword_author ) == 0 )
00137                         {
00138                                 copyStringValueToEOL( pParseBuf, &infoString[1][0], MaxInfoStringLen );
00139                                 info.authorString = &infoString[1][0];
00140                                 info.infoString[1] = &infoString[1][0];
00141                                 hasAuthor = true;
00142                         }
00143                         // COPYRIGHT
00144                         else if ( myStrNcaseCmp( pParseChunk, keyword_copyright ) == 0 )
00145                         {
00146                                 copyStringValueToEOL( pParseBuf, &infoString[2][0], MaxInfoStringLen );
00147                                 info.copyrightString = &infoString[2][0];
00148                                 info.infoString[2] = &infoString[2][0];
00149                                 hasCopyright = true;
00150                         }
00151                         // SONGS
00152                         else if ( myStrNcaseCmp( pParseChunk, keyword_songs ) == 0 )
00153                         {
00154                                 skipToEqu( parseStream );
00155                                 info.songs = (uword)readDec( parseStream );
00156                                 info.startSong = (uword)readDec( parseStream );
00157                                 if ( info.startSong == 0 )
00158                                     info.startSong++;
00159                                 hasSongs = true;
00160                         }
00161                         // SPEED
00162                         else if ( myStrNcaseCmp( pParseChunk, keyword_speed ) == 0 )
00163                         {
00164                                 skipToEqu( parseStream );
00165                                 oldStyleSpeed = readHex(parseStream);
00166                                 hasSpeed = true;
00167                         }
00168                         // SIDSONG
00169                         else if ( myStrNcaseCmp( pParseChunk, keyword_musPlayer ) == 0 )
00170                         {
00171                                 info.musPlayer = true;
00172                         }
00173         };
00174                 
00175         delete[] pParseChunk;
00176                 
00177                 if (info.songs > classMaxSongs)
00178                 {
00179                         info.songs = classMaxSongs;
00180                 }
00181 
00182                 // Again check for the ``required'' values.
00183                 if ( hasAddress || hasName || hasAuthor || hasCopyright || hasSongs || hasSpeed )
00184                 {
00185                         // Create the speed/clock setting table.
00186                         convertOldStyleSpeedToTables(oldStyleSpeed);
00187                         // loadAddr = 0 means, the address is stored in front of the C64 data.
00188                         // We cannot verify whether the dataBuffer contains valid data.
00189                     // All we want to know is whether the SID buffer is valid.
00190                         // If data is present, we access it (here to get the C64 load address).
00191                         if (info.loadAddr==0 && (dataBufLen>=(fileOffset+2)) && dataBuffer!=0)
00192                         {
00193                                 ubyte* pDataBufCp = (ubyte*)dataBuffer + fileOffset;
00194                                 info.loadAddr = readEndian( *(pDataBufCp + 1), *pDataBufCp );
00195                                 fileOffset += 2;  // begin of data
00196                         }
00197                         // Keep compatibility to PSID/SID.
00198                         if ( info.initAddr == 0 )
00199                         {
00200                                 info.initAddr = info.loadAddr;
00201                         }
00202                         // Now adjust MUS songs.
00203                         if ( info.musPlayer )
00204                         {
00205                                 info.loadAddr = 0x1000;
00206                                 info.initAddr = 0xc7b0;
00207                                 info.playAddr = 0;
00208                         }
00209                         info.numberOfInfoStrings = 3;
00210                         // We finally accept the input data.
00211                         info.formatString = text_format;
00212                         return true;
00213                 }
00214                 else
00215                 {
00216                         // Something is missing (or damaged ?).
00217                         // Error string set above.
00218                         return false;
00219                 }
00220         }
00221 #endif //ALFRED - TODO
00222         return false; //ALFRED - TODO: REMOVE
00223 }
00224 
00225 
00226 #if 0 //ALFRED - TODO
00227 bool sidTune::SID_fileSupportSave( ofstream& fMyOut )
00228 {
00229         fMyOut << keyword_id << endl
00230                 << keyword_address << hex << setw(4) << setfill('0') << 0 << ','
00231                 << hex << setw(4) << info.initAddr << ","
00232                 << hex << setw(4) << info.playAddr << endl
00233                 << keyword_songs << dec << (int)info.songs << "," << (int)info.startSong << endl;
00234 
00235         udword oldStyleSpeed = 0;
00236         int maxBugSongs = ((info.songs <= 32) ? info.songs : 32);
00237         for (int s = 0; s < maxBugSongs; s++)
00238         {
00239                 if (songSpeed[s] == SIDTUNE_SPEED_CIA_1A)
00240                 {
00241                         oldStyleSpeed |= (1<<s);
00242                 }
00243         }
00244 
00245         fMyOut
00246                 << keyword_speed << hex << setw(8) << oldStyleSpeed << endl
00247                 << keyword_name << info.nameString << endl
00248                 << keyword_author << info.authorString << endl
00249                 << keyword_copyright << info.copyrightString << endl;
00250         if ( info.musPlayer )
00251         {
00252                 fMyOut << keyword_musPlayer << endl;
00253         }
00254         if ( !fMyOut )
00255         {
00256                 return false;
00257         }
00258         else
00259         {
00260                 return true;
00261         }
00262 }
00263 #endif //ALFRED - TODO
00264 

Generated on Tue Feb 8 04:14:05 2005 for Esidplay by doxygen 1.3.3