bool APModuleLoader::LoadModule(PString fileName, bool changeType, PString &errorStr) { APAgent_DecrunchFile decrunchInfo; APAgent_ConvertModule convInfo; APMRSWList<AddOnInfo *> *infoList; bool modConverted = false; bool foundType = false; bool result = false; ap_result apResult; // Allocate the file object file = new PCacheFile(); if (file == NULL) throw PMemoryException(); try { // Initialize the converter structure convInfo.moduleFile = NULL; convInfo.newModuleFile = NULL; // Initialize the decruncher structure decrunchInfo.file = file; decrunchInfo.decrunchedFile = NULL; // Open the module decrunchInfo.file->Open(fileName, PFile::pModeReadWrite | PFile::pModeShareRead | PFile::pModeNoTruncate); // Get the original length of the file fileLength = decrunchInfo.file->GetLength(); // Decrunch the file DecrunchFile(&decrunchInfo); // Copy the file used for decrunching into the converter structure convInfo.moduleFile = decrunchInfo.file; // Well, lock the player list infoList = &GetApp()->playerInfo; infoList->WaitToRead(); try { // Check to see if we can find a player via // the file type if (!FindPlayerViaFileType(convInfo.moduleFile)) { // No player could be found via the file type. // Now try to convert the module modConverted = ConvertModule(&convInfo); // Try all the players to see if we can find // one that understand the file format if (FindPlayer(convInfo.moduleFile)) result = true; } else { foundType = true; result = true; } // Did we found a player? if (result) { PString typeString; PString playerError; // Yap, change the file type if (changeType && !foundType) { try { // Change the module type on the file if (modConverted) { if (convInfo.fileType.IsEmpty()) typeString = player->GetModTypeString(playerInfo->index); else typeString = convInfo.fileType; } else typeString = player->GetModTypeString(playerInfo->index); if (!typeString.IsEmpty()) file->SetFileType(typeString); } catch(PFileException e) { // If we can't set the file type, we ignore the error. // An error will occure on e.g. CD-ROM disks ; } } // Yap, load the module convInfo.moduleFile->SeekToBegin(); apResult = player->LoadModule(playerInfo->index, convInfo.moduleFile, playerError); if (apResult != AP_OK) { // Well, something went wrong when loading the file // // Build the error string errorStr.Format_S3(GetApp()->resource, IDS_CMDERR_LOAD_MODULE, fileName, playerInfo->addOnName, playerError); // Delete the player playerInfo->loader->DeleteInstance(player); player = NULL; playerInfo = NULL; result = false; } else { // Get module information playerName = playerInfo->addOnName; if (modConverted) { moduleFormat = convInfo.modKind; if (moduleFormat.IsEmpty()) moduleFormat = playerInfo->addOnName; } else moduleFormat = playerInfo->addOnName; // Should the file still be open? if (player->GetSupportFlags(playerInfo->index) & appDontCloseFile) { // Yes, remember the file pointer if (modConverted) { usingFile = convInfo.newModuleFile; convInfo.newModuleFile = NULL; } else { usingFile = file; file = NULL; } } } } else { // Nup, send an error back errorStr.Format_S1(GetApp()->resource, IDS_CMDERR_UNKNOWN_MODULE, fileName); } } catch(...) { infoList->DoneReading(); throw; } // Done with the list infoList->DoneReading(); } catch(PFileException e) { PString err; char *fileStr, *errStr; // Build error message err = PSystem::GetErrorString(e.errorNum); errorStr.Format(GetApp()->resource, IDS_CMDERR_FILE, (fileStr = fileName.GetString()), e.errorNum, (errStr = err.GetString())); err.FreeBuffer(errStr); fileName.FreeBuffer(fileStr); result = false; } catch(...) { ; } // Close the files again delete convInfo.newModuleFile; delete file; file = NULL; return (result); }
bool SIDStil::GetField(PString &result, PString buffer, int32 tuneNo, STILField field) { int32 start, firstTuneNo, temp, temp2 = -1; // Clean out the result buffer first result.MakeEmpty(); // Position pointer to the first char beyond the file designation start = buffer.Find('\n'); start++; // Check whether this is a NULL entry or not if (start == 0) return (false); // Is this a multitune entry? firstTuneNo = buffer.Find("(#", start); // This is a tune designation only if the previous char was // a newline (ie. if the "(#" is on the beginning of a line). if ((firstTuneNo >= 1) && (buffer.GetAt(firstTuneNo - 1) != '\n')) firstTuneNo = -1; if (firstTuneNo == -1) { //-------------------// // SINGLE TUNE ENTRY // //-------------------// // // Is the first thing in this STIL entry the COMMENT? temp = buffer.Find(_COMMENT_STR, start); // Search for other potential fields beyond the COMMENT if (temp == start) { temp2 = buffer.Find(_NAME_STR, start); if (temp2 == -1) { temp2 = buffer.Find(_AUTHOR_STR, start); if (temp2 == -1) { temp2 = buffer.Find(_TITLE_STR, start); if (temp2 == -1) temp2 = buffer.Find(_ARTIST_STR, start); } } } if (temp == start) { // Yes. So it's assumed to be a file-global comment if ((tuneNo == 0) && ((field == all) || ((field == comment) && (temp2 == -1)))) { // Simply copy the stuff in result = buffer.Mid(start); return (true); } else if ((tuneNo == 0) && (field == comment)) { // Just copy the comment result = buffer.Mid(start, temp2 - start); return (true); } else if ((tuneNo == 1) && (temp2 != -1)) { // A specific field was asked for return (GetOneField(result, buffer.Mid(temp2), field)); } else { // Anything else is invalid as of v2.00 return (false); } } else { // No. Handle it as a regular entry if ((field == all) && ((tuneNo == 0) || (tuneNo == 1))) { // The complete entry was asked for. Simply copy the stuff in result = buffer.Mid(start); return (true); } else if (tuneNo == 1) { // A specific field was asked for return (GetOneField(result, buffer.Mid(start), field)); } else { // Anything else is invalid as of v2.00 return (false); } } } else { //-----------------// // MULTITUNE ENTRY // //-----------------// int32 myTuneNo, nextTuneNo; PString tuneNoStr; // Was the complete entry asked for? if (tuneNo == 0) { switch (field) { case all: { // Yes. Simply copy the stuff in result = buffer.Mid(start); return (true); } case comment: { // Only the file-global comment field was asked for if (firstTuneNo != start) return (GetOneField(result, buffer.Mid(start, firstTuneNo - start), comment)); else return (false); } default: { // If a specific field other than a comment is // asked for tuneNo=0, this is illegal return (false); } } } // Search for the requested tune number tuneNoStr.Format("(#%d)", tuneNo); myTuneNo = buffer.Find(tuneNoStr, start); if (myTuneNo != -1) { // We found the requested tune number. // Set the pointer beyond it myTuneNo = buffer.Find('\n', myTuneNo) + 1; // Where is the next one? nextTuneNo = buffer.Find("\n(#", myTuneNo); if (nextTuneNo == -1) { // There is no next one - set pointer to the end of entry nextTuneNo = buffer.GetLength(); } else { // The search included the \n - go beyond it nextTuneNo++; } // Put the desired fields into the result (which may be 'all') PString tempResult; bool retVal; retVal = GetOneField(tempResult, buffer.Mid(myTuneNo, nextTuneNo - myTuneNo), field); result += tempResult; return (retVal); } else return (false); } }