00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "info_.h"
00016
00017
00018 const char text_format[] = "Raw plus PlaySID icon tooltype file (INFO)";
00019
00020 const char keyword_id[] = "SID:PLAYSID";
00021 const char keyword_address[] = "ADDRESS=";
00022 const char keyword_songs[] = "SONGS=";
00023 const char keyword_speed[] = "SPEED=";
00024 const char keyword_name[] = "NAME=";
00025 const char keyword_author[] = "AUTHOR=";
00026 const char keyword_copyright[] = "COPYRIGHT=";
00027 const char keyword_musPlayer[] = "SIDSONG=YES";
00028
00029 const char text_noMemError[] = "ERROR: Not enough free memory";
00030 const char text_corruptError[] = "ERROR: Info file is incomplete or corrupt";
00031 const char text_noStringsError[] = "ERROR: Info file does not contain required strings";
00032 const char text_dataCorruptError[] = "ERROR: C64 data file is corrupt";
00033
00034
00035 const int safeBufferSize = 64;
00036
00037
00038 bool copyItem(smartPtr<char>& spIn, smartPtr<char>& spCmpBuf, udword itemLen)
00039 {
00040 for ( uword i = 0; i < itemLen; i++ )
00041 {
00042 spCmpBuf[i] = spIn[i];
00043 }
00044 return (spIn && spCmpBuf);
00045 }
00046
00047
00048 bool sidTune::INFO_fileSupport(void* dataBuffer, udword dataLength,
00049 void* infoBuffer, udword infoLength)
00050 {
00051
00052 info.formatString = 0;
00053
00054
00055 ulong minSize = 1+sizeof(struct DiskObject);
00056 if (infoLength < minSize)
00057 return( false );
00058
00059 struct DiskObject *dobject = (struct DiskObject *)infoBuffer;
00060
00061
00062 if ( readEndian(dobject->Magic[0],dobject->Magic[1]) != WB_DISKMAGIC )
00063 return false;
00064
00065
00066 if ( readEndian(dobject->Version[0],dobject->Version[1]) != WB_DISKVERSION )
00067 return false;
00068
00069
00070 if ( dobject->Type != WB_PROJECT )
00071 return false;
00072
00073 int i;
00074
00075
00076 char *icon = (char*)infoBuffer + sizeof(struct DiskObject);
00077
00078 if ( (readEndian(dobject->Gadget.Flags[0],dobject->Gadget.Flags[1]) & GFLG_GADGIMAGE) == 0)
00079 {
00080
00081
00082 if (dobject->Gadget.pGadgetRender[0] |
00083 dobject->Gadget.pGadgetRender[1] |
00084 dobject->Gadget.pGadgetRender[2] |
00085 dobject->Gadget.pGadgetRender[3])
00086 {
00087
00088 minSize += sizeof(struct Border);
00089 if (infoLength < minSize)
00090 return( false );
00091
00092 struct Border *brd = (struct Border *)icon;
00093 icon += sizeof(struct Border);
00094 icon += brd->Count * (2+2);
00095 }
00096
00097 if (dobject->Gadget.pSelectRender[0] |
00098 dobject->Gadget.pSelectRender[1] |
00099 dobject->Gadget.pSelectRender[2] |
00100 dobject->Gadget.pSelectRender[3])
00101 {
00102
00103 minSize += sizeof(struct Border);
00104 if (infoLength < minSize)
00105 return( false );
00106
00107 struct Border *brd = (struct Border *)icon;
00108 icon += sizeof(struct Border);
00109 icon += brd->Count * (2+2);
00110 }
00111 }
00112 else
00113 {
00114
00115
00116 if (dobject->Gadget.pGadgetRender[0] |
00117 dobject->Gadget.pGadgetRender[1] |
00118 dobject->Gadget.pGadgetRender[2] |
00119 dobject->Gadget.pGadgetRender[3])
00120 {
00121
00122 minSize += sizeof(struct Image);
00123 if (infoLength < minSize)
00124 return( false );
00125
00126 struct Image *img = (struct Image *)icon;
00127 icon += sizeof(struct Image);
00128
00129 udword imgsize = 0;
00130 for(i=0;i<readEndian(img->Depth[0],img->Depth[1]);i++)
00131 {
00132 if ( (img->PlanePick & (1<<i)) != 0)
00133 {
00134
00135
00136
00137 imgsize++;
00138 }
00139 }
00140
00141 imgsize *= ((readEndian(img->Width[0],img->Width[1])+15)/16)*2;
00142 imgsize *= readEndian(img->Height[0],img->Height[1]);
00143
00144 icon += imgsize;
00145 }
00146
00147 if (dobject->Gadget.pSelectRender[0] |
00148 dobject->Gadget.pSelectRender[1] |
00149 dobject->Gadget.pSelectRender[2] |
00150 dobject->Gadget.pSelectRender[3])
00151 {
00152
00153 minSize += sizeof(struct Image);
00154 if (infoLength < minSize)
00155 return( false );
00156
00157 struct Image *img = (struct Image *)icon;
00158 icon += sizeof(struct Image);
00159
00160 udword imgsize = 0;
00161 for(i=0;i<readEndian(img->Depth[0],img->Depth[1]);i++)
00162 {
00163 if ( (img->PlanePick & (1<<i)) != 0)
00164 {
00165
00166
00167
00168 imgsize++;
00169 }
00170 }
00171
00172 imgsize *= ((readEndian(img->Width[0],img->Width[1])+15)/16)*2;
00173 imgsize *= readEndian(img->Height[0],img->Height[1]);
00174 icon += imgsize;
00175 }
00176 }
00177
00178
00179 smartPtr<char> spTool((char*)icon,infoLength-(ulong)(icon-(char*)infoBuffer));
00180 if ( !spTool )
00181 {
00182 info.formatString = text_corruptError;
00183 return false;
00184 }
00185
00186
00187 smartPtr<char> spCmpBuf(safeBufferSize);
00188 if ( !spCmpBuf )
00189 {
00190 info.formatString = text_noMemError;
00191 return false;
00192 }
00193 char* cmpBuf = spCmpBuf.tellBegin();
00194
00195
00196 spTool += readEndian(spTool[0],spTool[1],spTool[2],spTool[3]) + 4;
00197
00198
00199 fileOffset = 0;
00200 info.musPlayer = false;
00201 info.numberOfInfoStrings = 0;
00202 udword oldStyleSpeed = 0;
00203
00204
00205 bool hasAddress = false,
00206 hasName = false,
00207 hasAuthor = false,
00208 hasCopyright = false,
00209 hasSongs = false,
00210 hasSpeed = false,
00211 hasUnknownChunk = false;
00212
00213
00214 i = (readEndian(spTool[0],spTool[1],spTool[2],spTool[3])/4) - 1;
00215 spTool += 4;
00216
00217 while( i-- > 0 )
00218 {
00219
00220 udword toolLen = readEndian(spTool[0],spTool[1],spTool[2],spTool[3]);
00221 spTool += 4;
00222
00223 if ( !copyItem(spTool,spCmpBuf,toolLen) )
00224 {
00225 return false;
00226 }
00227
00228
00229 if ( myStrNcaseCmp(cmpBuf,keyword_address) == 0 )
00230 {
00231 #if 0 //ALFRED - TODO
00232 istrstream addrIn( cmpBuf + strlen(keyword_address),
00233 toolLen - strlen(keyword_address) );
00234 info.loadAddr = (uword)readHex( addrIn );
00235 info.initAddr = (uword)readHex( addrIn );
00236 info.playAddr = (uword)readHex( addrIn );
00237 if ( !addrIn )
00238 {
00239 return false;
00240 }
00241 #endif //ALFRED - TODO
00242 hasAddress = true;
00243 }
00244 else if ( myStrNcaseCmp(cmpBuf,keyword_songs) == 0 )
00245 {
00246 #if 0 //ALFRED - TODO
00247 istrstream numIn( cmpBuf + strlen(keyword_songs),
00248 toolLen - strlen(keyword_songs) );
00249 if ( !numIn )
00250 {
00251 return false;
00252 }
00253 info.songs = (uword)readDec( numIn );
00254 info.startSong = (uword)readDec( numIn );
00255 if ( info.startSong == 0 )
00256 {
00257 info.startSong++;
00258 }
00259 #endif //ALFRED - TODO
00260 hasSongs = true;
00261 }
00262 else if ( myStrNcaseCmp(cmpBuf,keyword_speed) == 0 )
00263 {
00264 #if 0 //ALFRED - TODO
00265 istrstream speedIn( cmpBuf + strlen(keyword_speed),
00266 toolLen - strlen(keyword_speed) );
00267 if ( !speedIn )
00268 {
00269 return false;
00270 }
00271 oldStyleSpeed = readHex(speedIn);
00272 #endif //ALFRED - TODO
00273 hasSpeed = true;
00274 }
00275 else if ( myStrNcaseCmp(cmpBuf,keyword_name) == 0 )
00276 {
00277 strncpy( &infoString[0][0], cmpBuf + strlen(keyword_name), 31 );
00278 info.nameString = &infoString[0][0];
00279 info.infoString[0] = &infoString[0][0];
00280 hasName = true;
00281 }
00282 else if ( myStrNcaseCmp(cmpBuf,keyword_author) == 0 )
00283 {
00284 strncpy( &infoString[1][0], cmpBuf + strlen(keyword_author), 31 );
00285 info.authorString = &infoString[1][0];
00286 info.infoString[1] = &infoString[1][0];
00287 hasAuthor = true;
00288 }
00289 else if ( myStrNcaseCmp(cmpBuf,keyword_copyright) == 0 )
00290 {
00291 strncpy( &infoString[2][0], cmpBuf + strlen(keyword_copyright), 31 );
00292 info.copyrightString = &infoString[2][0];
00293 info.infoString[2] = &infoString[2][0];
00294 hasCopyright = true;
00295 }
00296 else if ( myStrNcaseCmp(cmpBuf,keyword_musPlayer) == 0 )
00297 {
00298 info.musPlayer = true;
00299 }
00300 else
00301 {
00302 hasUnknownChunk = true;
00303
00304
00305 }
00306
00307 spTool += toolLen;
00308 }
00309
00310 if (info.songs > classMaxSongs)
00311 {
00312 info.songs = classMaxSongs;
00313 }
00314
00315
00316 if ( hasAddress && hasName && hasAuthor && hasCopyright && hasSongs && hasSpeed )
00317 {
00318
00319 convertOldStyleSpeedToTables(oldStyleSpeed);
00320 if (( info.loadAddr == 0 ) && ( dataLength != 0 ))
00321 {
00322 smartPtr<ubyte> spDataBuf((ubyte*)dataBuffer,dataLength);
00323 spDataBuf += fileOffset;
00324 info.loadAddr = readEndian(spDataBuf[1],spDataBuf[0]);
00325 if ( !spDataBuf )
00326 {
00327 info.formatString = text_dataCorruptError;
00328 return false;
00329 }
00330 fileOffset += 2;
00331 }
00332 if ( info.initAddr == 0 )
00333 {
00334 info.initAddr = info.loadAddr;
00335 }
00336
00337 if ( info.musPlayer )
00338 {
00339 info.loadAddr = 0x1000;
00340 info.initAddr = 0xc7b0;
00341 info.playAddr = 0;
00342 }
00343 info.numberOfInfoStrings = 3;
00344
00345 info.formatString = text_format;
00346 return true;
00347 }
00348 else if ( hasAddress || hasName || hasAuthor || hasCopyright || hasSongs || hasSpeed )
00349 {
00350
00351 info.formatString = text_corruptError;
00352 return false;
00353 }
00354 else
00355 {
00356
00357 info.formatString = text_noStringsError;
00358 return false;
00359 }
00360 }