📄 cpi_playlist.c
字号:
for(iCharIDX = 0; _pcFilename[iCharIDX] && iCharIDX < iPlaylist_DirectoryBytes; iCharIDX++)
{
if(tolower(_pcFilename[iCharIDX]) != tolower(pcOutputName[iCharIDX]))
break;
if(_pcFilename[iCharIDX] == '\\')
pcLastCommonSplitPoint = _pcFilename+iCharIDX+1;
}
// - add a .. for every slash left in the playlist's path
cRelPath[0] = '\0';
for(; iCharIDX < iPlaylist_DirectoryBytes; iCharIDX++)
{
if(pcOutputName[iCharIDX] == '\\')
strcat(cRelPath, "..\\");
}
strcat(cRelPath, pcLastCommonSplitPoint);
}
else
strcpy(cRelPath, _pcFilename);
// PLS files have the format FileXXX=pathname - we want to write the stuff up to (and including)
// the equals sign
if(enFileType == pftPLS)
{
char cPlsFileHeader[32];
sprintf(cPlsFileHeader, "File%d=", iFileNumber + 1);
WriteFile_Text(hOutputFile, cPlsFileHeader, FALSE);
}
// Write the filename
WriteFile_Text(hOutputFile, cRelPath, TRUE);
}
}
CloseHandle(hOutputFile);
}
//
//
//
void CPL_AddPrefixedFile( CP_HPLAYLIST hPlaylist,
const char* pcFilename, const char* pcTitle,
const char* pcPlaylistFile,
const unsigned int iPlaylist_VolumeBytes,
const unsigned int iPlaylist_DirBytes)
{
const unsigned int iFile_VolumeBytes = CPL_GetPathVolumeBytes(pcFilename);
// If the file has volume information - add it as it is
if(iFile_VolumeBytes)
CPL_AddSingleFile(hPlaylist, pcFilename, pcTitle);
// If the filename has a leading \ then add it prepended by the playlist's volume
else if(pcFilename[0] == '\\')
{
char cFullPath[MAX_PATH];
memcpy(cFullPath, pcPlaylistFile, iPlaylist_VolumeBytes);
strcpy(cFullPath + iPlaylist_VolumeBytes, pcFilename + 1);
CPL_AddSingleFile(hPlaylist, cFullPath, pcTitle);
}
// Add the filename prepended by the playlist's directory
else
{
char cFullPath[MAX_PATH];
memcpy(cFullPath, pcPlaylistFile, iPlaylist_DirBytes);
strcpy(cFullPath + iPlaylist_DirBytes, pcFilename);
CPL_AddSingleFile(hPlaylist, cFullPath, pcTitle);
}
}
//
//
//
void CPL_AddFile(CP_HPLAYLIST hPlaylist, const char* pcFilename)
{
CPs_Playlist* pPlaylist = (CPs_Playlist*)hPlaylist;
CPe_PlayListFileType enFileType;
unsigned int iPlaylist_VolumeBytes;
unsigned int iPlaylist_DirectoryBytes;
CP_CHECKOBJECT(pPlaylist);
// Check for known file types
enFileType = CPL_GetFileType(pcFilename);
if(enFileType == pftUnknown)
{
// This doesn't seem to be a playlist file - add it as a playlist item
CPL_AddSingleFile(hPlaylist, pcFilename, NULL);
return;
}
// Get playlist file information
iPlaylist_VolumeBytes = CPL_GetPathVolumeBytes(pcFilename);
iPlaylist_DirectoryBytes = CPL_GetPathDirectoryBytes(pcFilename, iPlaylist_VolumeBytes);
// Load the playlist files
CPL_cb_LockWindowUpdates(TRUE);
if(enFileType == pftPLS)
{
int iNumFiles, iFileIDX;
iNumFiles = GetPrivateProfileInt("playlist", "NumberOfEntries", 0, pcFilename);
for(iFileIDX = 0; iFileIDX < iNumFiles; iFileIDX++)
{
DWORD dwNumCharsRead;
char cPlsFileHeader[32];
char cBuffer[MAX_PATH];
char cTitle[1024];
sprintf(cPlsFileHeader, "File%d", iFileIDX + 1);
// Get the path - leave room for a drive
dwNumCharsRead = GetPrivateProfileString("playlist", cPlsFileHeader, NULL, cBuffer, MAX_PATH, pcFilename);
if(dwNumCharsRead == 0)
continue;
sprintf(cPlsFileHeader, "Title%d", iFileIDX + 1);
dwNumCharsRead = GetPrivateProfileString("playlist", cPlsFileHeader, NULL, cTitle, 1024, pcFilename);
if(dwNumCharsRead == 0)
CPL_AddPrefixedFile(hPlaylist, cBuffer, NULL, pcFilename, iPlaylist_VolumeBytes, iPlaylist_DirectoryBytes);
else
CPL_AddPrefixedFile(hPlaylist, cBuffer, cTitle, pcFilename, iPlaylist_VolumeBytes, iPlaylist_DirectoryBytes);
}
}
else
{
// Open file and load it all into memory
HANDLE hFile;
hFile = CreateFile(pcFilename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
const DWORD dwFileSize = GetFileSize(hFile, NULL);
// We will only load playlists that are smaller than 256K
if(dwFileSize < 0x40000)
{
// The plan is to load the entire file into a memblock and then split it into lines
// and scan off the whitepace and add the items to the list
char *pcPlaylistBuffer = (char*)malloc(dwFileSize+1);
DWORD dwBytesRead;
unsigned int iLastLineStartIDX, iCharIDX;
ReadFile(hFile, pcPlaylistBuffer, dwFileSize, &dwBytesRead, NULL);
// Read in the file line by line
iLastLineStartIDX = 0;
for(iCharIDX = 0; iCharIDX < dwFileSize+1; iCharIDX++)
{
if( (pcPlaylistBuffer[iCharIDX] == '\r'
|| pcPlaylistBuffer[iCharIDX] == '\n'
|| iCharIDX == dwFileSize)
&& iLastLineStartIDX < iCharIDX)
{
char cBuffer[512];
// Is there a file on this line (strip whitespace from start)
if(sscanf(pcPlaylistBuffer + iLastLineStartIDX, " %512[^\r\n]", cBuffer) == 1)
{
// Something has been read - ignore lines starting with #
if(cBuffer[0] != '#')
CPL_AddPrefixedFile(hPlaylist, cBuffer, NULL, pcFilename, iPlaylist_VolumeBytes, iPlaylist_DirectoryBytes);
}
// Set the line start for the next line
if(pcPlaylistBuffer[iCharIDX + 1] == '\n')
iCharIDX++;
iLastLineStartIDX = iCharIDX + 1;
}
}
free(pcPlaylistBuffer);
}
CloseHandle(hFile);
}
}
if(options.shuffle_play)
PostThreadMessage(pPlaylist->m_dwWorkerThreadID, CPPLWT_SYNCSHUFFLE, 0, 0);
CPL_cb_LockWindowUpdates(FALSE);
}
//
//
//
int __cdecl cpl_sort_Path(const void *e1, const void *e2)
{
const CPs_PlaylistItem* pElem1 = *(const CPs_PlaylistItem**)e1;
const CPs_PlaylistItem* pElem2 = *(const CPs_PlaylistItem**)e2;
return stricmp(pElem1->m_pcPath, pElem2->m_pcPath);
}
//
//
//
int __cdecl cpl_sort_Filename(const void *e1, const void *e2)
{
const CPs_PlaylistItem* pElem1 = *(const CPs_PlaylistItem**)e1;
const CPs_PlaylistItem* pElem2 = *(const CPs_PlaylistItem**)e2;
return stricmp(pElem1->m_pcPath, pElem2->m_pcPath);
}
//
//
//
int __cdecl cpl_sort_TrackNum(const void *e1, const void *e2)
{
const CPs_PlaylistItem* pElem1 = *(const CPs_PlaylistItem**)e1;
const CPs_PlaylistItem* pElem2 = *(const CPs_PlaylistItem**)e2;
if(pElem1->m_cTrackNum == pElem2->m_cTrackNum)
return cpl_sort_Path(e1, e2);
else if((char)pElem1->m_cTrackNum < (char)pElem2->m_cTrackNum)
return -1;
return 1;
}
//
//
//
int __cdecl cpl_sort_Length(const void *e1, const void *e2)
{
const CPs_PlaylistItem* pElem1 = *(const CPs_PlaylistItem**)e1;
const CPs_PlaylistItem* pElem2 = *(const CPs_PlaylistItem**)e2;
if(pElem1->m_iTrackLength == pElem2->m_iTrackLength)
return 0;
else if(pElem1->m_iTrackLength < pElem2->m_iTrackLength)
return -1;
return 1;
}
//
//
//
int __cdecl cpl_sort_TrackStackPos(const void *e1, const void *e2)
{
const CPs_PlaylistItem* pElem1 = *(const CPs_PlaylistItem**)e1;
const CPs_PlaylistItem* pElem2 = *(const CPs_PlaylistItem**)e2;
if(pElem1->m_iTrackStackPos == pElem2->m_iTrackStackPos)
return 0;
if(pElem1->m_iTrackStackPos == CIC_TRACKSTACK_UNSTACKED)
return 1;
if(pElem2->m_iTrackStackPos == CIC_TRACKSTACK_UNSTACKED)
return -1;
if(pElem1->m_iTrackStackPos > pElem2->m_iTrackStackPos)
return 1;
else
return -1;
}
//
//
//
int __cdecl cpl_sort_TrackName(const void *e1, const void *e2)
{
const CPs_PlaylistItem* pElem1 = *(const CPs_PlaylistItem**)e1;
const CPs_PlaylistItem* pElem2 = *(const CPs_PlaylistItem**)e2;
return stricmp(pElem1->m_pcTrackName, pElem2->m_pcTrackName);
}
//
//
//
int __cdecl cpl_sort_Album(const void *e1, const void *e2)
{
const CPs_PlaylistItem* pElem1 = *(const CPs_PlaylistItem**)e1;
const CPs_PlaylistItem* pElem2 = *(const CPs_PlaylistItem**)e2;
int iStringCompare;
if(pElem1->m_pcAlbum == NULL && pElem2->m_pcAlbum == NULL)
return cpl_sort_TrackNum(e1, e2);
else if(pElem1->m_pcAlbum == NULL)
return -1;
else if(pElem2->m_pcAlbum == NULL)
return 1;
// Sort by artist - but fall back to track name
iStringCompare = stricmp(pElem1->m_pcAlbum, pElem2->m_pcAlbum);
if(iStringCompare != 0)
return iStringCompare;
return cpl_sort_TrackNum(e1, e2);
}
//
//
//
int __cdecl cpl_sort_Artist(const void *e1, const void *e2)
{
const CPs_PlaylistItem* pElem1 = *(const CPs_PlaylistItem**)e1;
const CPs_PlaylistItem* pElem2 = *(const CPs_PlaylistItem**)e2;
int iStringCompare;
if(pElem1->m_pcArtist == NULL && pElem2->m_pcArtist == NULL)
return cpl_sort_Album(e1, e2);
else if(pElem1->m_pcArtist == NULL)
return -1;
else if(pElem2->m_pcArtist == NULL)
return 1;
// Sort by artist - but fall back to track name
iStringCompare = stricmp(pElem1->m_pcArtist, pElem2->m_pcArtist);
if(iStringCompare != 0)
return iStringCompare;
return cpl_sort_Album(e1, e2);
}
//
//
//
int __cdecl cpl_sort_Year(const void *e1, const void *e2)
{
const CPs_PlaylistItem* pElem1 = *(const CPs_PlaylistItem**)e1;
const CPs_PlaylistItem* pElem2 = *(const CPs_PlaylistItem**)e2;
int iStringCompare;
if(pElem1->m_pcYear == NULL && pElem2->m_pcYear == NULL)
return cpl_sort_Artist(e1, e2);
else if(pElem1->m_pcYear == NULL)
return -1;
else if(pElem2->m_pcYear == NULL)
return 1;
// Sort by artist - but fall back to track name
iStringCompare = stricmp(pElem1->m_pcYear, pElem2->m_pcYear);
if(iStringCompare != 0)
return iStringCompare;
return cpl_sort_Artist(e1, e2);
}
//
//
//
int __cdecl cpl_sort_Genre(const void *e1, const void *e2)
{
const CPs_PlaylistItem* pElem1 = *(const CPs_PlaylistItem**)e1;
const CPs_PlaylistItem* pElem2 = *(const CPs_PlaylistItem**)e2;
int iStringCompare;
if(CPLI_GetGenre((CP_HPLAYLISTITEM)pElem1) == NULL && CPLI_GetGenre((CP_HPLAYLISTITEM)pElem2) == NULL)
return cpl_sort_Artist(e1, e2);
else if(CPLI_GetGenre((CP_HPLAYLISTITEM)pElem1) == NULL)
return -1;
else if(CPLI_GetGenre((CP_HPLAYLISTITEM)pElem2) == NULL)
return 1;
// Sort by artist - but fall back to track name
iStringCompare = stricmp(CPLI_GetGenre((CP_HPLAYLISTITEM)pElem1), CPLI_GetGenre((CP_HPLAYLISTITEM)pElem2));
if(iStringCompare != 0)
return iStringCompare;
return cpl_sort_Artist(e1, e2);
}
//
//
//
int __cdecl cpl_sort_Comment(const void *e1, const void *e2)
{
const CPs_PlaylistItem* pElem1 = *(const CPs_PlaylistItem**)e1;
const CPs_PlaylistItem* pElem2 = *(const CPs_PlaylistItem**)e2;
int iStringCompare;
if(pElem1->m_pcComment == NULL && pElem2->m_pcComment == NULL)
return cpl_sort_Artist(e1, e2);
else if(pElem1->m_pcComment == NULL)
return -1;
else if(pElem2->m_pcComment == NULL)
return 1;
// Sort by artist - but fall back to track name
iStringCompare = stricmp(pElem1->m_pcComment, pElem2->m_pcComment);
if(iStringCompare != 0)
return iStringCompare;
return cpl_sort_Artist(e1, e2);
}
//
//
//
int __cdecl cpl_sort_Random(const void *e1, const void *e2)
{
const unsigned short r1 = rand();
const unsigned short r2 = rand();
if(r1 < r2)
return -1;
else if(r1 == r2)
return 0;
else
return 1;
}
//
//
//
void CPL_SortList(CP_HPLAYLIST hPlaylist, const CPe_PlayItemSortElement enElement, const BOOL bDesc)
{
CPs_Playlist* pPlaylist = (CPs_Playlist*)hPlaylist;
CPs_PlaylistItem** pFlatArray;
unsigned int iNumItems;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -