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); }