Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions

74
Src/xspf/XSPFHandler.cpp Normal file
View File

@ -0,0 +1,74 @@
#include "XSPFHandler.h"
#include "XSPFLoader.h"
#include "api__xspf.h"
#include "resource.h"
const wchar_t *XSPFHandler::EnumerateExtensions(size_t n)
{
switch(n)
{
case 0:
return L"xspf";
default:
return 0;
}
}
const char *XSPFHandler::EnumerateMIMETypes(size_t n)
{
switch(n)
{
case 0:
return "application/xspf+xml";
default:
return 0;
}
}
const wchar_t *XSPFHandler::GetName()
{
static wchar_t xspfpl[64];
// no point re-loading this all of the time since it won't change once we've been loaded
return (!xspfpl[0]?WASABI_API_LNGSTRINGW_BUF(IDS_XSPF_PLAYLIST,xspfpl,64):xspfpl);
}
// returns SUCCESS and FAILED, so be careful ...
int XSPFHandler::SupportedFilename(const wchar_t *filename)
{
size_t filenameLength = wcslen(filename);
size_t extensionLength = wcslen(L".xspf");
if (filenameLength < extensionLength) return SVC_PLAYLISTHANDLER_FAILED; // too short
if (!_wcsicmp(filename + filenameLength - extensionLength, L".xspf"))
return SVC_PLAYLISTHANDLER_SUCCESS;
else
return SVC_PLAYLISTHANDLER_FAILED;
}
int XSPFHandler::SupportedMIMEType(const char *type)
{
if (!strcmp(type, "application/xspf+xml"))
return SVC_PLAYLISTHANDLER_SUCCESS;
else
return SVC_PLAYLISTHANDLER_FAILED;
}
ifc_playlistloader *XSPFHandler::CreateLoader(const wchar_t *filename)
{
return new XSPFLoader;
}
void XSPFHandler::ReleaseLoader(ifc_playlistloader *loader)
{
delete static_cast<XSPFLoader *>(loader);
}
// Define the dispatch table
#define CBCLASS XSPFHandler
START_DISPATCH;
CB(SVC_PLAYLISTHANDLER_ENUMEXTENSIONS, EnumerateExtensions)
CB(SVC_PLAYLISTHANDLER_ENUMMIMETYPES, EnumerateMIMETypes)
CB(SVC_PLAYLISTHANDLER_SUPPORTFILENAME, SupportedFilename)
CB(SVC_PLAYLISTHANDLER_CREATELOADER, CreateLoader)
VCB(SVC_PLAYLISTHANDLER_RELEASELOADER, ReleaseLoader)
CB(SVC_PLAYLISTHANDLER_GETNAME, GetName)
END_DISPATCH;

23
Src/xspf/XSPFHandler.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef NULLSOFT_XSPF_XSPFHANDLER_H
#define NULLSOFT_XSPF_XSPFHANDLER_H
#include "../playlist/svc_playlisthandler.h"
// the "Playlist Handler" is responsible for describing all the capabilities of the playlist format to Winamp
// It is a singleton class (for each playlist type)
// besides informational functions, it contains factory methods for creating playlist loaders and writers
class XSPFHandler : public svc_playlisthandler
{
public:
const wchar_t *EnumerateExtensions(size_t n); // returns 0 when it's done
const char *EnumerateMIMETypes(size_t n); // returns 0 when it's done, returns char * to match HTTP specs
const wchar_t *GetName(); // returns a name suitable for display to user of this playlist form (e.g. PLS Playlist)
int SupportedFilename(const wchar_t *filename); // returns SUCCESS and FAILED, so be careful ...
int SupportedMIMEType(const char *filename); // returns SUCCESS and FAILED, so be careful ...
ifc_playlistloader *CreateLoader(const wchar_t *filename);
void ReleaseLoader(ifc_playlistloader *loader);
protected:
RECVS_DISPATCH; // boiler-plate code for the dispatch-table
};
#endif

View File

@ -0,0 +1,56 @@
#include "XSPFHandlerFactory.h"
#include "XSPFHandler.h"
/*
This is the GUID for our service factory
don't re-use this.
make your own guid with guidgen.exe
lives somewhere like C:\program files\Microsoft Visual Studio .NET 2003\Common7\Tools\Bin
*/
// {51D17273-566F-4fa9-AFE0-1345C65B8B1B}
static const GUID XSPFHandlerGUID =
{ 0x51d17273, 0x566f, 0x4fa9, { 0xaf, 0xe0, 0x13, 0x45, 0xc6, 0x5b, 0x8b, 0x1b } };
// our playlist handler.
static XSPFHandler xspfHandler;
FOURCC XSPFHandlerFactory::GetServiceType()
{
return svc_playlisthandler::getServiceType();
}
const char *XSPFHandlerFactory::GetServiceName()
{
return "XSPF Playlist Loader";
}
GUID XSPFHandlerFactory::GetGuid()
{
return XSPFHandlerGUID;
}
void *XSPFHandlerFactory::GetInterface(int global_lock)
{
// xspfHandler is a singleton object, so we can just return a pointer to it
// depending on what kind of service you are making, you might have to
// 'new' an object and return that instead (and then free it in ReleaseInterface)
return &xspfHandler;
}
int XSPFHandlerFactory::ReleaseInterface(void *ifc)
{
// no-op because we returned a singleton (see above)
return 1;
}
// Define the dispatch table
#define CBCLASS XSPFHandlerFactory
START_DISPATCH;
CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
CB(WASERVICEFACTORY_GETGUID, GetGuid)
CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
END_DISPATCH;
#undef CBCLASS

View File

@ -0,0 +1,19 @@
#ifndef NULLSOFT_XSPF_XSPFHANDLERFACTORY_H
#define NULLSOFT_XSPF_XSPFHANDLERFACTORY_H
#include <api/service/waservicefactory.h>
class XSPFHandlerFactory : public waServiceFactory
{
public:
FOURCC GetServiceType();
const char *GetServiceName();
GUID GetGuid();
void *GetInterface(int global_lock = TRUE);
int ReleaseInterface(void *ifc);
protected:
RECVS_DISPATCH; // all Wasabi objects implementing a Dispatchable interface require this
};
#endif

461
Src/xspf/XSPFLoader.cpp Normal file
View File

@ -0,0 +1,461 @@
#include "XSPFLoader.h"
#include "../xml/obj_xml.h"
#include "../xml/ifc_xmlreadercallback.h"
#include "api__xspf.h"
#include "../winamp/wa_ipc.h"
#include <api/service/waservicefactory.h>
#include <shlwapi.h>
#include <strsafe.h>
// tries to retrieve the media library API (if it's not already retrieved
bool HasMediaLibraryAPI()
{
// TODO: should critical section this
if (!AGAVE_API_MLDB)
{
waServiceFactory *mldbFactory = WASABI_API_SVC->service_getServiceByGuid(mldbApiGuid);
if (mldbFactory)
AGAVE_API_MLDB = (api_mldb *)mldbFactory->getInterface(); // retrieve a pointer to the API object
}
return !!AGAVE_API_MLDB;
}
static bool HasTagzAPI()
{
// TODO: should critical section this
if (!AGAVE_API_TAGZ)
{
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(tagzGUID);
if (sf)
AGAVE_API_TAGZ = (api_tagz *)sf->getInterface(); // retrieve a pointer to the API object
}
return !!AGAVE_API_TAGZ;
}
const wchar_t* ATFString()
{
// TODO: should critical section this
if (!WASABI_API_APP)
{
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(applicationApiServiceGuid);
if (sf)
WASABI_API_APP = (api_application *)sf->getInterface(); // retrieve a pointer to the API object
}
if (WASABI_API_APP)
{
const wchar_t *atf = WASABI_API_APP->getATFString();
if (atf && *atf) return atf;
}
return L"%artist% - %title%";
}
// go check out XSPFLoader::Load before decyphering this class
class XSPFLoaderCallback : public ifc_xmlreadercallback
{
public:
XSPFLoaderCallback(ifc_playlistloadercallback *_playlist);
~XSPFLoaderCallback();
void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
void xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag);
void xmlReaderOnCharacterDataCallback(const wchar_t *xmlpath, const wchar_t *xmltag, const wchar_t *str);
protected:
RECVS_DISPATCH;
private:
enum
{
ELEMENT_NONE=-1,
ELEMENT_LOCATION=0,
ELEMENT_IDENTIFIER,
ELEMENT_TITLE,
ELEMENT_CREATOR,
ELEMENT_ALBUM,
ELEMENT_TRACKNUM,
NUM_ELEMENTS,
};
wchar_t *elements[NUM_ELEMENTS];
int element;
ifc_playlistloadercallback *playlist;
};
XSPFLoaderCallback::XSPFLoaderCallback(ifc_playlistloadercallback *_playlist)
{
element = ELEMENT_NONE;
for (int i=0;i<NUM_ELEMENTS;i++)
elements[i]=0;
playlist = _playlist;
}
XSPFLoaderCallback::~XSPFLoaderCallback()
{
for (int i=0;i<NUM_ELEMENTS;i++)
{
free(elements[i]);
elements[i]=0;
}
}
// this gets called for every opening tag
// xmlpath is the full XML path up to this point, delimited with \f (form feed)
// xmltag is the actual opening tag
// params is an object which lets you query for the attribtues in the tag
void XSPFLoaderCallback::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
{
if (!wcscmp(xmlpath, L"playlist\ftrackList\ftrack\flocation"))
element=ELEMENT_LOCATION;
else if (!wcscmp(xmlpath, L"playlist\ftrackList\ftrack\fidentifier"))
element=ELEMENT_IDENTIFIER;
else if (!wcscmp(xmlpath, L"playlist\ftrackList\ftrack\ftitle"))
element=ELEMENT_TITLE;
else if (!wcscmp(xmlpath, L"playlist\ftrackList\ftrack\fcreator"))
element=ELEMENT_CREATOR;
else if (!wcscmp(xmlpath, L"playlist\ftrackList\ftrack\falbum"))
element=ELEMENT_ALBUM;
else if (!wcscmp(xmlpath, L"playlist\ftrackList\ftrack\ftracknum"))
element=ELEMENT_TRACKNUM;
else
element=ELEMENT_NONE;
}
static void QueryStringAdd(const wchar_t *value, wchar_t *&query, size_t &query_len)
{
if (!value || !*value) return;
while (value && *value && query_len > 3) {
if (*value == L'%') { *query++ = L'%'; *query++ = L'%'; query_len-=2;}
else if (*value == L'\"') { *query++ = L'%'; *query++ = L'2'; *query++ = L'2'; query_len-=3;}
else if (*value == L'\'') { *query++ = L'%'; *query++ = L'2'; *query++ = L'7'; query_len-=3;}
else if (*value == L'[') { *query++ = L'%'; *query++ = L'5'; *query++ = L'B'; query_len-=3;}
else if (*value == L']') { *query++ = L'%'; *query++ = L'5'; *query++ = L'D'; query_len-=3;}
else if (*value == L'(') { *query++ = L'%'; *query++ = L'2'; *query++ = L'8'; query_len-=3;}
else if (*value == L')') { *query++ = L'%'; *query++ = L'2'; *query++ = L'9'; query_len-=3;}
else if (*value == L'#') { *query++ = L'%'; *query++ = L'2'; *query++ = L'3'; query_len-=3;}
else { *query++ = *value; query_len--; }
value++;
}
*query = 0;
}
class ItemRecordTagProvider : public ifc_tagprovider
{
public:
ItemRecordTagProvider(itemRecordW *item) : t(item) {}
wchar_t *GetTag(const wchar_t *name, ifc_tagparams *parameters);
void FreeTag(wchar_t *Tag);
protected:
RECVS_DISPATCH;
private:
itemRecordW *t;
};
#define CBCLASS ItemRecordTagProvider
START_DISPATCH;
CB(IFC_TAGPROVIDER_GET_TAG, GetTag);
VCB(IFC_TAGPROVIDER_FREE_TAG, FreeTag);
END_DISPATCH;
#undef CBCLASS
wchar_t *ItemRecordTagProvider::GetTag(const wchar_t *tag, ifc_tagparams *parameters)
{
bool copy=false;
wchar_t buf[128]={0};
wchar_t *value = NULL;
if (!_wcsicmp(tag, L"artist")) value = t->artist;
else if (!_wcsicmp(tag, L"album")) value = t->album;
else if (!_wcsicmp(tag, L"filename")) value = t->filename;
else if (!_wcsicmp(tag, L"title")) value = t->title;
else if (!_wcsicmp(tag, L"year"))
{
if (t->year > 0)
{
StringCchPrintfW(buf, 128, L"%04d", t->year);
value = buf;
}
}
else if (!_wcsicmp(tag, L"genre")) value = t->genre;
else if (!_wcsicmp(tag, L"comment")) value = t->comment;
else if (!_wcsicmp(tag, L"tracknumber") || !_wcsicmp(tag, L"track"))
{
if (t->track > 0)
{
if (t->tracks > 0)
StringCchPrintfW(buf, 128, L"%02d/%02d", t->track, t->tracks);
else
StringCchPrintfW(buf, 128, L"%02d", t->track);
value = buf;
}
}
else if (!_wcsicmp(tag, L"disc"))
{
if (t->disc > 0)
{
if (t->discs > 0)
StringCchPrintfW(buf, 128, L"%d/%d", t->disc, t->discs);
else
StringCchPrintfW(buf, 128, L"%d", t->disc);
value = buf;
}
}
else if (!_wcsicmp(tag, L"rating"))
{
if (t->rating > 0)
{
StringCchPrintfW(buf, 128, L"%d", t->rating);
value = buf;
}
}
else if (!_wcsicmp(tag, L"playcount"))
{
if (t->playcount > 0)
{
StringCchPrintfW(buf, 128, L"%d", t->playcount);
value = buf;
}
}
else if (!_wcsicmp(tag, L"bitrate"))
{
if (t->bitrate > 0)
{
StringCchPrintfW(buf, 128, L"%d", t->bitrate);
value = buf;
}
}
else if (!_wcsicmp(tag, L"bpm"))
{
if (t->bpm > 0)
{
StringCchPrintfW(buf, 128, L"%d", t->bpm);
value = buf;
}
}
else if (!_wcsicmp(tag, L"albumartist")) value = t->albumartist;
else if (!_wcsicmp(tag, L"publisher")) value = t->publisher;
else if (!_wcsicmp(tag, L"composer")) value = t->composer;
else if (!_wcsicmp(tag, L"replaygain_album_gain")) value = t->replaygain_album_gain;
else if (!_wcsicmp(tag, L"replaygain_track_gain")) value = t->replaygain_track_gain;
else if (!_wcsicmp(tag, L"GracenoteFileID"))
{
copy=true;
value = getRecordExtendedItem(t, L"GracenoteFileID");
}
else if (!_wcsicmp(tag, L"GracenoteExtData"))
{
copy=true;
value = getRecordExtendedItem(t, L"GracenoteExtData");
}
else
return 0;
if (!value)
return 0;
else
{
if (copy || value == buf)
return AGAVE_API_MLDB->DuplicateString(value);
else
{
AGAVE_API_MLDB->RetainString(value);
return value;
}
}
}
void ItemRecordTagProvider::FreeTag(wchar_t *tag)
{
AGAVE_API_MLDB->ReleaseString(tag);
}
// this gets called for every closing tag
void XSPFLoaderCallback::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag)
{
if (!wcscmp(xmlpath, L"playlist\ftrackList\ftrack"))
{
// end of track info
if (elements[ELEMENT_LOCATION] // if we have a location
&& (PathIsURL(elements[ELEMENT_LOCATION]) // and it's a URL
|| GetFileAttributes(elements[ELEMENT_LOCATION]) != INVALID_FILE_ATTRIBUTES)) // or a file that exists
{
// location field seemed OK so go ahead and add
// TODO try using the length if available...
playlist->OnFile(elements[ELEMENT_LOCATION], 0, -1, 0);
}
else if (HasMediaLibraryAPI()) // we don't have a good location so let's hit the media library
{
// let's build a query out of what we have
bool needs_and=false;
wchar_t query[2048]={0};
wchar_t *query_end=query;
size_t query_size=2048;
struct {
const wchar_t *field_name;
int field_value;
} fields[] =
{
{L"artist", ELEMENT_CREATOR},
{L"title", ELEMENT_TITLE},
};
for(size_t i=0;i!=sizeof(fields)/sizeof(fields[0]);i++)
{
if (elements[fields[i].field_value])
{
if (needs_and)
StringCchCopyEx(query_end, query_size, L" AND ", &query_end, &query_size, 0);
StringCchPrintfEx(query_end, query_size, &query_end, &query_size, 0, L"(%s == \"", fields[i].field_name);
QueryStringAdd(elements[fields[i].field_value], query_end, query_size);
StringCchCopyEx(query_end, query_size, L"\")", &query_end, &query_size, 0);
needs_and=true;
}
}
if (query[0])
{
itemRecordListW *results = AGAVE_API_MLDB->QueryLimit(query, 1);
if (results && results->Size >= 1 && results->Items[0].filename)
{
if (HasTagzAPI())
{
wchar_t title[2048]={0};
ItemRecordTagProvider provider(&results->Items[0]);
AGAVE_API_TAGZ->format(ATFString(), title, 2048, &provider, 0);
int length = -1;
if (results->Items[0].length > 0)
length=results->Items[0].length*1000;
playlist->OnFile(results->Items[0].filename, title, length, 0);
}
else
{
int length = -1;
if (results->Items[0].length > 0)
length=results->Items[0].length*1000;
playlist->OnFile(results->Items[0].filename, 0, length, 0);
}
}
AGAVE_API_MLDB->FreeRecordList(results);
}
}
for (int i=0;i<NUM_ELEMENTS;i++)
{
free(elements[i]);
elements[i]=0;
}
}
else if (!wcscmp(xmlpath, L"playlist\ftrackList\ftrack\flocation"))
element=ELEMENT_NONE;
else if (!wcscmp(xmlpath, L"playlist\ftrackList\ftrack\fidentifier"))
element=ELEMENT_NONE;
else if (!wcscmp(xmlpath, L"playlist\ftrackList\ftrack\ftitle"))
element=ELEMENT_NONE;
else if (!wcscmp(xmlpath, L"playlist\ftrackList\ftrack\fcreator"))
element=ELEMENT_NONE;
else if (!wcscmp(xmlpath, L"playlist\ftrackList\ftrack\falbum"))
element=ELEMENT_NONE;
else if (!wcscmp(xmlpath, L"playlist\ftrackList\ftrack\ftracknum"))
element=ELEMENT_NONE;
}
void XSPFLoaderCallback::xmlReaderOnCharacterDataCallback(const wchar_t *xmlpath, const wchar_t *xmltag, const wchar_t *str)
{
if (element!=ELEMENT_NONE)
{
// this certainly isn't the most memory efficient way to do this but it'll work for now :)
if (elements[element] == 0)
{
elements[element] = wcsdup(str);
}
else
{
size_t elementlen = wcslen(elements[element]);
size_t incominglen = wcslen(str);
wchar_t *&newstr = elements[element], *oldstr = newstr;
newstr = (wchar_t *)realloc(newstr, sizeof(wchar_t)*(elementlen+incominglen+1));
if (newstr != NULL)
{
memcpy(newstr+elementlen, str, incominglen*sizeof(wchar_t));
newstr[elementlen+incominglen] = 0;
}
}
}
}
#define CBCLASS XSPFLoaderCallback
START_DISPATCH;
VCB(ONSTARTELEMENT, xmlReaderOnStartElementCallback)
VCB(ONENDELEMENT, xmlReaderOnEndElementCallback)
VCB(ONCHARDATA, xmlReaderOnCharacterDataCallback)
END_DISPATCH;
#undef CBCLASS
/* ---------------------------- */
static int LoadFile(obj_xml *parser, const wchar_t *filename)
{
HANDLE file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
if (file == INVALID_HANDLE_VALUE)
return IFC_PLAYLISTLOADER_FAILED;
while (true)
{
char data[1024] = {0};
DWORD bytesRead = 0;
if (ReadFile(file, data, 1024, &bytesRead, NULL) && bytesRead)
{
if (parser->xmlreader_feed(data, bytesRead) != API_XML_SUCCESS)
{
CloseHandle(file);
return IFC_PLAYLISTLOADER_FAILED;
}
}
else
break;
}
CloseHandle(file);
if (parser->xmlreader_feed(0, 0) != API_XML_SUCCESS)
return IFC_PLAYLISTLOADER_FAILED;
return IFC_PLAYLISTLOADER_SUCCESS;
}
// this get called by Winamp
// you a method in the passed playlist loader callback object
// for each item in the playlist
int XSPFLoader::Load(const wchar_t *filename, ifc_playlistloadercallback *playlist)
{
// first thing we'll need is an XML parser
// we'll have to do the wasabi dance to get it
// first, get the service factory for creating XML objects
waServiceFactory *xmlFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
if (xmlFactory)
{
obj_xml *parser = (obj_xml *)xmlFactory->getInterface(); // create an XML parser
if (parser)
{
// ok now we can get down to biz'nes
XSPFLoaderCallback xmlCallback(playlist);
parser->xmlreader_registerCallback(L"*", &xmlCallback);
parser->xmlreader_setCaseSensitive();
parser->xmlreader_open();
int ret = LoadFile(parser, filename);
parser->xmlreader_unregisterCallback(&xmlCallback);
parser->xmlreader_close();
xmlFactory->releaseInterface(parser); // destroy the XML parser via the service factory
return ret;
}
}
return IFC_PLAYLISTLOADER_FAILED;
}
// Define the dispatch table
#define CBCLASS XSPFLoader
START_DISPATCH;
CB(IFC_PLAYLISTLOADER_LOAD, Load)
END_DISPATCH;
#undef CBCLASS

16
Src/xspf/XSPFLoader.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef NULLSOFT_XSPF_XSPFLOADER_H
#define NULLSOFT_XSPF_XSPFLOADER_H
#include "../playlist/ifc_playlistloader.h"
// this is the class that actually loads the playlist.
// everything up to this point (component, handler, handler factory) was just administrative
class XSPFLoader : public ifc_playlistloader
{
public:
int Load(const wchar_t *filename, ifc_playlistloadercallback *playlist);
protected:
RECVS_DISPATCH; // boiler-plate code for our dispatch table
};
#endif

21
Src/xspf/api__xspf.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef NULLSOFT_XSPF_API_H
#define NULLSOFT_XSPF_API_H
// Service Manager
#include "api/service/api_service.h"
// Media Library API
#include "../Plugins/Library/ml_local/api_mldb.h"
extern api_mldb *mldbApi;
#define AGAVE_API_MLDB mldbApi
#include "../Agave/Language/api_language.h"
#include "../tagz/api_tagz.h"
extern api_tagz *tagzApi;
#define AGAVE_API_TAGZ tagzApi
#include <api/application/api_application.h>
#define WASABI_API_APP applicationApi
#endif

71
Src/xspf/main.cpp Normal file
View File

@ -0,0 +1,71 @@
#include "../Agave/Component/ifc_wa5component.h"
#include "api__xspf.h" // services we'll used are extern'd here
#include "XSPFHandlerFactory.h"
// declarations for the pointers to services we'll need
// by convention, these follow the format WASABI_API_* or AGAVE_API_*
// you are free to name it however you want, but this provides good consistency
api_service *WASABI_API_SVC = 0; // the wasabi service manager (our gateway to other services)
api_mldb *AGAVE_API_MLDB = 0; // media library API. we'll retrieve this the first time we need it, because it will load after us
api_tagz *AGAVE_API_TAGZ = 0;
api_application *WASABI_API_APP = 0;
// wasabi based services for localisation support
api_language *WASABI_API_LNG = 0;
HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
// our service factories that we're going to register
static XSPFHandlerFactory xspfHandlerFactory;
// here is the implementation of our component
// this class contains the methods called during initialization and shutdown
// to register/deregister our component's services
class XSPFComponent : public ifc_wa5component
{
public:
void RegisterServices(api_service *service); // this is where the party is
void DeregisterServices(api_service *service);
protected:
RECVS_DISPATCH; // some boiler-plate code to implement our dispatch table
};
static HINSTANCE GetMyInstance()
{
MEMORY_BASIC_INFORMATION mbi = {0};
if(VirtualQuery(GetMyInstance, &mbi, sizeof(mbi)))
return (HINSTANCE)mbi.AllocationBase;
return NULL;
}
void XSPFComponent::RegisterServices(api_service *service)
{
WASABI_API_SVC = service; // we get passed the service manager and we need to save the pointer
WASABI_API_SVC->service_register(&xspfHandlerFactory);
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
// need to have this initialised before we try to do anything with localisation features
WASABI_API_START_LANG(GetMyInstance(),playlistLangGUID);
}
void XSPFComponent::DeregisterServices(api_service *service)
{
WASABI_API_SVC->service_deregister(&xspfHandlerFactory);
}
static XSPFComponent xspfComponent;
// Winamp calls this function after it LoadLibrary's your W5S
// you need to turn a pointer to your component.
extern "C" __declspec(dllexport) ifc_wa5component *GetWinamp5SystemComponent()
{
return &xspfComponent;
}
// some boiler-plate code to implement the dispatch table for our component
#define CBCLASS XSPFComponent
START_DISPATCH;
VCB(API_WA5COMPONENT_REGISTERSERVICES, RegisterServices)
VCB(API_WA5COMPONENT_DEREEGISTERSERVICES, DeregisterServices)
END_DISPATCH;
#undef CBCLASS

16
Src/xspf/resource.h Normal file
View File

@ -0,0 +1,16 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by xspf.rc
//
#define IDS_XSPF_PLAYLIST 8
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

39
Src/xspf/version.rc2 Normal file
View File

@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
#include "../Winamp/buildType.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION WINAMP_PRODUCTVER
PRODUCTVERSION WINAMP_PRODUCTVER
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Winamp SA"
VALUE "FileDescription", "Winamp 5.x System Component"
VALUE "FileVersion", STR_WINAMP_PRODUCTVER
VALUE "InternalName", "xspf.w5s"
VALUE "LegalCopyright", "Copyright <20> 2007-2023 Winamp SA"
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
VALUE "OriginalFilename", "xspf.w5s"
VALUE "ProductName", "Winamp XML Shareable Playlist Format Support"
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

86
Src/xspf/xspf.rc Normal file
View File

@ -0,0 +1,86 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_XSPF_PLAYLIST "XML Shareable Playlist Format"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#include ""version.rc2""\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "version.rc2"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

30
Src/xspf/xspf.sln Normal file
View File

@ -0,0 +1,30 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29424.173
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xspf", "xspf.vcxproj", "{3FDDC715-EC20-4FD6-B723-92795736BDD5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3FDDC715-EC20-4FD6-B723-92795736BDD5}.Debug|Win32.ActiveCfg = Debug|Win32
{3FDDC715-EC20-4FD6-B723-92795736BDD5}.Debug|Win32.Build.0 = Debug|Win32
{3FDDC715-EC20-4FD6-B723-92795736BDD5}.Debug|x64.ActiveCfg = Debug|x64
{3FDDC715-EC20-4FD6-B723-92795736BDD5}.Debug|x64.Build.0 = Debug|x64
{3FDDC715-EC20-4FD6-B723-92795736BDD5}.Release|Win32.ActiveCfg = Release|Win32
{3FDDC715-EC20-4FD6-B723-92795736BDD5}.Release|Win32.Build.0 = Release|Win32
{3FDDC715-EC20-4FD6-B723-92795736BDD5}.Release|x64.ActiveCfg = Release|x64
{3FDDC715-EC20-4FD6-B723-92795736BDD5}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F492E8CB-F967-49DF-9CBE-D69862846DD6}
EndGlobalSection
EndGlobal

278
Src/xspf/xspf.vcxproj Normal file
View File

@ -0,0 +1,278 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3FDDC715-EC20-4FD6-B723-92795736BDD5}</ProjectGuid>
<RootNamespace>xspf</RootNamespace>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<TargetExt>.w5s</TargetExt>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<TargetExt>.w5s</TargetExt>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<TargetExt>.w5s</TargetExt>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<TargetExt>.w5s</TargetExt>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnabled>false</VcpkgEnabled>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../replicant;../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;XSPF_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(ProjectDir)x86_Debug\$(ProjectName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../replicant;../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;XSPF_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(ProjectDir)x64_Debug\$(ProjectName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<ProfileGuidedDatabase>$(ProjectDir)x64_Debug\$(TargetName).pgd</ProfileGuidedDatabase>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>../replicant;../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;XSPF_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(ProjectDir)x86_Release\$(ProjectName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<ProfileGuidedDatabase>$(ProjectDir)x86_Release\$(TargetName).pgd</ProfileGuidedDatabase>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>../replicant;../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;XSPF_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(ProjectDir)x64_Release\$(ProjectName).lib</ImportLibrary>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<ManifestFile>$(ProjectDir)x64_Release\$(TargetName)$(TargetExt).intermediate.manifest</ManifestFile>
<ProfileGuidedDatabase>$(ProjectDir)x64_Release\$(TargetName).pgd</ProfileGuidedDatabase>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\Plugins\General\gen_ml\ml_lib.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="XSPFHandler.cpp" />
<ClCompile Include="XSPFHandlerFactory.cpp" />
<ClCompile Include="XSPFLoader.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="api__xspf.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="XSPFHandler.h" />
<ClInclude Include="XSPFHandlerFactory.h" />
<ClInclude Include="XSPFLoader.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="xspf.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Wasabi\Wasabi.vcxproj">
<Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XSPFHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XSPFHandlerFactory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XSPFLoader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Plugins\General\gen_ml\ml_lib.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="XSPFLoader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="XSPFHandlerFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="XSPFHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="api__xspf.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{85782fd0-d621-46ed-84af-21d7dc5cbb60}</UniqueIdentifier>
</Filter>
<Filter Include="Ressource Files">
<UniqueIdentifier>{4d951680-f48e-4040-9d03-dbafac1e7cb1}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{0a439138-f363-4152-aaaf-5e20c98a37cd}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="xspf.rc">
<Filter>Ressource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>