#ifndef mysidtune_h #define mysidtune_h class mySidTune : public sidTune { public: // --------------------------------------------------------- public // Only derive the simple constructor. mySidTune(const char* fileName) : sidTune(fileName) { }; bool writeToSidTune(char newInfoString[][maxSidInfoLen+1], mode_type mode) { // PSID-format can only handle up to 31 characters plus a terminating zero. // // The infoStrings are kept without any special order in a two-dimensional // array of the size [infoStringNum][infoStringLen]. // // To make available publically readable copies for each infoString, // extra pointers are assigned: info.nameString, info.authorString, // info.copyrightString, and for compatibility to MUS files and a future // file format: info.infoString[0], ..., info.infoString[infoStringNum]. // A copy of the private instance of the sidTuneInfo structure can be read // out using ::returnInfo(). int infoStringIndex = 0; // Used for FLAGS case. switch(mode) { case TITLE: case AUTHOR: case RELEASED: { // Copy string to private array. strcpy(&infoString[(int) mode][0], newInfoString[(int) mode]); info.infoString[(int) mode] = &infoString[(int) mode][0]; if (TITLE == mode) // Assign pointer: First infoString usually is NAME. info.nameString = &infoString[(int) mode][0]; else if (AUTHOR == mode) // Assign pointer: Second infoString usually is AUTHOR. info.authorString = &infoString[(int) mode][0]; else // Assign pointer: Third infoString usually is RELEASED // (original release information). info.copyrightString = &infoString[(int) mode][0]; break; } case CREDITS: { if ('*' != newInfoString[0][0]) { strcpy(&infoString[0][0], newInfoString[0]); info.nameString = &infoString[0][0]; info.infoString[0] = &infoString[0][0]; } if ('*' != newInfoString[1][0]) { strcpy(&infoString[1][0], newInfoString[1]); info.authorString = &infoString[1][0]; info.infoString[1] = &infoString[1][0]; } if ('*' != newInfoString[2][0]) { strcpy(&infoString[2][0], newInfoString[2]); info.copyrightString = &infoString[2][0]; info.infoString[2] = &infoString[2][0]; } break; } case SPEED: { unsigned long ulSpeed; // Only 32 song speed can be set with the below code assuming // an unsigned long stores 32 bits. if (sizeof(ulSpeed) >= 4) { // Not modifiable! if (info.compatibility == SIDTUNE_COMPATIBILITY_R64) return false; // SPEED string is in hex. ulSpeed = strtoul(newInfoString[0], NULL, 16); convertOldStyleSpeedToTables((udword) ulSpeed); break; } else return false; } case SONGS: //SONGS string must have a comma! { int string_len = strlen(newInfoString[0]); // Terminate string at the comma // example, with SONGS=3,2 the string is "3" int index; for (index = 0; newInfoString[0][index]; index++) { if (',' == newInfoString[0][index]) { newInfoString[0][index] = '\0'; break; } } // If a comma found, continue...else fail if (string_len >= index-1) { info.songs = atoi(newInfoString[0]); info.startSong = atoi(newInfoString[0]+index+1); break; } else return false; } case INITPLAY: // INITPLAY string must have a comma! { int string_len = strlen(newInfoString[0]); // Terminate string at the comma // example, with INITPLAY=1000,1003 the string is "1000" int index; for (index = 0; newInfoString[0][index]; index++) { if (',' == newInfoString[0][index]) { newInfoString[0][index] = '\0'; break; } } // If a comma found, continue...else fail if (string_len >= index-1) { // The strings are in hex. Note that in RSID mode certain // values of init are illegal. This is not checked here info.initAddr = strtoul(newInfoString[0], NULL, 16); info.playAddr = strtoul(newInfoString[0]+index+1, NULL, 16); // Not modifiable! if (info.compatibility == SIDTUNE_COMPATIBILITY_R64) { if (checkRealC64Init() == false) return false; if (info.playAddr != 0) return false; } break; } else return false; } case FREEPAGES: //FREEPAGES string must have a comma! { int string_len = strlen(newInfoString[0]); // Terminate string at the comma // example, with FREEPAGES=20,03 the string is "20" int index; for (index = 0; newInfoString[0][index]; index++) { if (',' == newInfoString[0][index]) { newInfoString[0][index] = '\0'; break; } } // If a comma found, continue...else fail if (string_len >= index-1) { info.relocStartPage = strtoul(newInfoString[0], NULL, 16); info.relocPages = strtoul(newInfoString[0]+index+1, NULL, 16); if (checkRelocInfo() == false) return false; break; } else return false; } case FLAGS: // We'll fall thru the next 4 cases for this one. case MUSPLAYER: { if ((mode == FLAGS) && (newInfoString[infoStringIndex][0] == '*')) { ; // Do nothing - this field is not to be changed. } else if (atoi(newInfoString[infoStringIndex]) == 0) { info.musPlayer = false; } else if (atoi(newInfoString[infoStringIndex]) == 1) { info.musPlayer = true; } else { return false; } if (mode != FLAGS) { break; } else { // Fall through. infoStringIndex++; } } case PLAYSID: { if ((mode == FLAGS) && (newInfoString[infoStringIndex][0] == '*')) { ; // Do nothing - this field is not to be changed. } else if (atoi(newInfoString[infoStringIndex]) == 0) { // Not supported by RSID files if (info.compatibility == SIDTUNE_COMPATIBILITY_R64) return false; info.compatibility = SIDTUNE_COMPATIBILITY_C64; } else if (atoi(newInfoString[infoStringIndex]) == 1) { // Not supported by RSID files if (info.compatibility == SIDTUNE_COMPATIBILITY_R64) return false; info.compatibility = SIDTUNE_COMPATIBILITY_PSID; } else { return false; } if (mode != FLAGS) { break; } else { // Fall through. infoStringIndex++; } } case CLOCK: { if ((mode == FLAGS) && (newInfoString[infoStringIndex][0] == '*')) { ; // Do nothing - this field is not to be changed. } else if (!strcmp(newInfoString[infoStringIndex], "UNKNOWN")) { info.clockSpeed = SIDTUNE_CLOCK_UNKNOWN; } else if (!strcmp(newInfoString[infoStringIndex], "PAL")) { info.clockSpeed = SIDTUNE_CLOCK_PAL; } else if (!strcmp(newInfoString[infoStringIndex], "NTSC")) { info.clockSpeed = SIDTUNE_CLOCK_NTSC; } else if (!strcmp(newInfoString[infoStringIndex], "ANY") || !strcmp(newInfoString[infoStringIndex], "EITHER")) { info.clockSpeed = SIDTUNE_CLOCK_ANY; } else { return false; } if (mode != FLAGS) { break; } else { // Fall through. infoStringIndex++; } } case SIDMODEL: { if ((mode == FLAGS) && (newInfoString[infoStringIndex][0] == '*')) { ; // Do nothing - this field is not to be changed. } else if (!strcmp(newInfoString[infoStringIndex], "UNKNOWN")) { info.sidModel = SIDTUNE_SIDMODEL_UNKNOWN; } else if (!strcmp(newInfoString[infoStringIndex], "6581")) { info.sidModel = SIDTUNE_SIDMODEL_6581; } else if (!strcmp(newInfoString[infoStringIndex], "8580")) { info.sidModel = SIDTUNE_SIDMODEL_8580; } else if (!strcmp(newInfoString[infoStringIndex], "ANY") || !strcmp(newInfoString[infoStringIndex], "EITHER")) { info.sidModel = SIDTUNE_SIDMODEL_ANY; } else { return false; } break; // The FLAGS directive stops here, too. } case FIXLOAD: { // Increase load address by 2 without verification. fixLoadAddress(true,info.initAddr,info.playAddr); break; } default: { return false; } } // switch return true; }; // writeToSidTune }; // mySidTune #endif // mysidtune_h