remote_plugin.cpp
#include "stdafx.h"
#include "windows.h" 
#include "wa_ipc.h"
#include "gen.h"
#include "winamp.h"
#include <process.h>
#include <iostream>


#include "COMPORT.H"
#include <string.h>
#include <sys/timeb.h>
#include <time.h>

#define SAMPLERATE 0
#define BITRATE 1
#define CHANNELS 2
#define SECONDS 1
#define MSECONDS 0

int init(); 
void config(); 
void quit(); 
static void Reader( void* );
int play(void);
void volumeUp(void);
void volumeDown(void);
void stop(void);
void pause(void);
int getStatus(void);
int getInfo(int);
void nextTrack(void);
void prevTrack(void);
void fforward(void);
void rewind(void);
int stringSize(char *);
int getVersion(void);
int getPlayTime(void);
int getPlaylistIndex(void);
int getPlaylistLength(void);
char* getPlaylist(void);
char * remove_nulls(char[], int);

/*****************************************************************/
/************winamp plugin stuff**********************************/
/*****************************************************************/

winampGeneralPurposePlugin plugin = 
{ 
	GPPHDR_VER, 
	"Winamp Remote v1.0", 
	init, 
	config, 
	quit, 
}; 
//required function
int init() 
{ 
	//spawn new thread for main servicing function
	_beginthread( Reader, 0, NULL );
	return 0; 
} 
//required function
void config() 
{ 
} 
//required function
void quit() 
{ 
} 

extern "C" __declspec( dllexport ) winampGeneralPurposePlugin * winampGetGeneralPurposePlugin() 
{ 
	return &plugin;
}

/*****************************************************************/
/************end winamp plugin stuff******************************/
/*****************************************************************/


//function that Rx, Tx, and communicates with winamp
static void Reader( void* )
{
	HWND mainwinampwin = plugin.hwndParent;
	int status;
	char choice;
	int version;
	char aData = 'h';
	double x = clock();
	CString trackFilename;
	struct _timeb timebuffer;
	char *timeline;
	char *title;
	int pos;
	int current_pos=0, song_pos;
	char buffer[10];
	char plbuffer[100];
	int i;
	char clear_flag=0;

	/**************************************************/
	/******setup com port******************************/
	/**************************************************/
	COMPort aPort ("COM1");				//com1
	aPort.setBitRate (COMPort::br9600); //9600bps
	aPort.setParity (COMPort::None);	//no parity
	aPort.setDataBits (COMPort::db8);	//8 data bits
	aPort.setStopBits (COMPort::sb1);	//1 stop bit
	aPort.setxONxOFF (false);			//no xOnxOff
	aPort.setHandshaking(false);		//no handshaking
	/***************************************************/
	/******end setup com port***************************/
	/***************************************************/

	char *output;

  while(1 )
  {
		//block until remote sends a single byte of data
		choice = aPort.read();
	
		//all data that is transmitted ends with a vertical tab '\v'
		//I figure this is not used in any text so it makes a good terminator
		switch (choice)
		{
		//current time
		case '0':
			//********************************
			//   get time
			_ftime( &timebuffer );
			timeline = ctime( & ( timebuffer.time ) );
			aPort.write(timeline, stringSize(timeline));
			aPort.write("\v",stringSize("\v"));
			//**************************************
			break;
		//play
		case '1':
			play();
			break;
		//stop
		case '2':
			stop();
			break;
		//pause
		case '3':
			pause();
			break;
		//increase volume
		case '4':
			volumeUp();
			break;
		//decrease volume
		case '5':
			volumeDown();
			break;
		//nothing
		case '6':
			break;
		//get status:  play, pause, stop
		case '7':
			status = getStatus();
			if(status == 0)
				aPort.write("stop\v",stringSize("stop\v"));
			else if (status ==1)
				aPort.write("play\v",stringSize("play\v"));
			else if (status == 3) 
				aPort.write("pause\v",stringSize("pause\v"));
			else
				aPort.write("unknown\v",stringSize("unknown\v"));
			break;
		//samplerate
		case '8':
			//format the output
			sprintf(buffer,"%d\v",getInfo(SAMPLERATE));
			aPort.write(buffer,stringSize(buffer));
			break;
		//bitrate
		case '9':
			//format the output
			sprintf(buffer,"%d\v",getInfo(BITRATE));
			aPort.write(buffer,stringSize(buffer));
			break;
		//number of channels
		case 'a':
			//format the output
			sprintf(buffer,"%d\v",getInfo(CHANNELS));
			aPort.write(buffer,stringSize(buffer));
			break;
		//go to next track
		case 'b':
			nextTrack();
			break;
		//go to prev track
		case 'c':
			prevTrack();
			break;
		//fast forward
		case 'd':
			fforward();
			break;
		//rewind
		case 'e':
			rewind();
			break;
		//get version of winamp
		case 'f':
			version = getVersion();
			//format the output
			sprintf(buffer,"WinAmp v%x.%02x\v",version/4096, version&0xFFF);
			aPort.write(buffer,stringSize(buffer));
			break;
		//get current play time
		case 'g':
			//format the output
			sprintf(buffer,"%02d:%02d\v",getPlayTime()/1000/60,(getPlayTime()/1000)%60);
			aPort.write(buffer,stringSize(buffer));
			break;
		//get title of current playing song
		case 'h':
		title=(char*)SendMessage(plugin.hwndParent,WM_WA_IPC,getPlaylistIndex(),IPC_GETPLAYLISTTITLE);
			//format the output
			sprintf(buffer,"%s\v",title);
			aPort.write(buffer,stringSize(buffer));
			break;
		//get entire playlist
		case 'i':
			sprintf(plbuffer,"");
			pos=1;
			while(pos < getPlaylistLength())
			{
			title = (char*)SendMessage(plugin.hwndParent,WM_WA_IPC,pos,IPC_GETPLAYLISTTITLE);
				//format the output
				//put a \r between songs in the playlist
				sprintf(plbuffer,"%s%s\r",plbuffer,title);
				pos ++;
			}
			//add the vertical tab as an end of data character
			sprintf(plbuffer,"%s\v",plbuffer);
			aPort.write(plbuffer,stringSize(plbuffer));
			break;
		//get only two songs to display in playlist(incrementing)
		case 'j':
			if(current_pos+1 < getPlaylistLength())
			{
				current_pos++;
			}
			
		title = (char*)SendMessage(plugin.hwndParent,WM_WA_IPC,current_pos-1,IPC_GETPLAYLISTTITLE);
			
			//fill first 16 characters of buffer with first song
			//add a space to beginning
			plbuffer[0]=' ';
			for(i=1;i<16;i++)
			{
				plbuffer[i]=title[i-1];
			}

			//remove the null terminating character and add blank spaces
			//after the null is found, replace it and all remaining with spaces
			for(i=1;i<16;i++)
			{
				if(plbuffer[i]==0)
				{
					plbuffer[i]=' ';
					clear_flag=1;
				}
				else if(clear_flag==1)
				{
					plbuffer[i]=' ';
				}
			}
			clear_flag=0;
			
			//get second song to send
			if(current_pos < getPlaylistLength())
			{
			title = (char*)SendMessage(plugin.hwndParent,WM_WA_IPC,current_pos,IPC_GETPLAYLISTTITLE);
				//fill first 16 characters of buffer with second song
				//add a star to beginning to signify current selected song in playlist
				plbuffer[16]='*';
				for(i=1;i<16;i++)
				{
					plbuffer[i+16]=title[i-1];
				}
			}

			//remove the null terminating character and add blank spaces
			//after the null is found, replace it and all remaining with spaces
			for(i=17;i<32;i++)
			{
				if(plbuffer[i]==0)
				{
					plbuffer[i]=' ';
					clear_flag=1;
				}
				else if(clear_flag==1)
				{
					plbuffer[i]=' ';	
				}
			}
			clear_flag=0;

			//add a vertical tab and null terminate it
			plbuffer[32]='\v';
			plbuffer[33]=0;

			//write to uart
			aPort.write(plbuffer,stringSize(plbuffer));
			break;
		//get only two songs to display in playlist(decrementing)
		case 'k':
			if(current_pos-1 >= 0)
			{
				current_pos--;
			}
			
			title = (char*)SendMessage(plugin.hwndParent,WM_WA_IPC,current_pos,IPC_GETPLAYLISTTITLE);
			
			//fill first 16 characters of buffer with first song
			//add a star to beginning to signify current playlist selection
			plbuffer[0]='*';
			for(i=1;i<16;i++)
			{
				plbuffer[i]=title[i-1];
			}

			//remove the null terminating character and add blank spaces
			//after the null is found, replace it and all remaining with spaces
			for(i=0;i<16;i++)
			{
				if(plbuffer[i]==0)
				{
					plbuffer[i]=' ';
					clear_flag=1;
				}
				else if(clear_flag==1)
				{
					plbuffer[i]=' ';		
				}
			}
			clear_flag=0;

			title = (char*)SendMessage(plugin.hwndParent,WM_WA_IPC,current_pos+1,IPC_GETPLAYLISTTITLE);
			
			//fill first 16 characters of buffer with second song
			//add a space to beginning
			plbuffer[16]=' ';
			for(i=1;i<16;i++)
			{
				plbuffer[i+16]=title[i-1];
			}

			//remove the null terminating character and add blank spaces
			//after the null is found, replace it and all remaining with spaces
			for(i=17;i<32;i++)
			{
				if(plbuffer[i]==0)
				{
					plbuffer[i]=' ';
					clear_flag=1;
				}
				else if(clear_flag==1)
				{
					plbuffer[i]=' ';
					
				}
				
			}
			clear_flag=0;

			//add a vertical tab and null terminate it
			plbuffer[32]='\v';
			plbuffer[33]=0;
			aPort.write(plbuffer,stringSize(plbuffer));			
			break;
		//get the current two songs in playlist
		case 'l':
			
			if(current_pos==0)
			{
				song_pos=current_pos+1;
			}
			else song_pos=current_pos;
		title = (char*)SendMessage(plugin.hwndParent,WM_WA_IPC,song_pos-1,IPC_GETPLAYLISTTITLE);
			
			//add star to beginning of song to signify current playlist selection
			if(song_pos-1==current_pos)
			{
				plbuffer[0]='*';
			}
			//add space at beginning of song
			else plbuffer[0]=' ';

			//fill buffer with first 16 chars of first song
			for(i=1;i<16;i++)
			{
				plbuffer[i]=title[i-1];
			}
			
			//remove all null chars and fill remaining with spaces
			for(i=1;i<16;i++)
			{
				if(plbuffer[i]==0)
				{
					plbuffer[i]=' ';
					clear_flag=1;
				}
				else if(clear_flag==1)
				{
					plbuffer[i]=' ';
					
				}
				
			}
			clear_flag=0;
			

			if(song_pos < getPlaylistLength())
			{
			title = (char*)SendMessage(plugin.hwndParent,WM_WA_IPC,song_pos,IPC_GETPLAYLISTTITLE);
				if(song_pos==current_pos)
				{
					plbuffer[16]='*';
				}
				else plbuffer[16]=' ';
				for(i=1;i<16;i++)
				{
					plbuffer[i+16]=title[i-1];
				}
			}
			
			//fill with first 16 chars of second song
			for(i=17;i<32;i++)
			{
				if(plbuffer[i]==0)
				{
					plbuffer[i]=' ';
					clear_flag=1;
				}
				else if(clear_flag==1)
				{
					plbuffer[i]=' ';	
				}
			}
			clear_flag=0;
			//add vertical tab and null char
			plbuffer[32]='\v';
			plbuffer[33]=0;
			aPort.write(plbuffer,stringSize(plbuffer));
			break;
		//play current playlist selection
		case 'm':
			//set playlist position
			SendMessage(plugin.hwndParent,WM_WA_IPC,current_pos,IPC_SETPLAYLISTPOS);
			play();
			break;

		}

  } 
}





/****************************************************************/		
/**************basic control functions***************************/
/****************************************************************/
void volumeUp(void)
{
	SendMessage(plugin.hwndParent, WM_COMMAND,WINAMP_VOLUMEUP,0);
}

void volumeDown(void)
{
	SendMessage(plugin.hwndParent, WM_COMMAND,WINAMP_VOLUMEDOWN,0);
}

int play(void)
{
	SendMessage(plugin.hwndParent, WM_COMMAND,WINAMP_PLAY,0);
	return 0;
}

void stop(void)
{
	SendMessage(plugin.hwndParent, WM_COMMAND,WINAMP_STOP,0);
}


void pause(void)
{
	SendMessage(plugin.hwndParent, WM_COMMAND,WINAMP_PAUSE,0);
}

void nextTrack(void)
{
	SendMessage(plugin.hwndParent, WM_COMMAND,WINAMP_NEXT,0);
}

void prevTrack(void)
{
	SendMessage(plugin.hwndParent, WM_COMMAND,WINAMP_PREV,0);
}

void fforward(void)
{
	SendMessage(plugin.hwndParent, WM_COMMAND,WINAMP_FF,0);
}

void rewind(void)
{
	SendMessage(plugin.hwndParent, WM_COMMAND,WINAMP_REW,0);
}
/****************************************************************/		
/**************end basic control functions***********************/
/****************************************************************/

//get play status:  play, pause, stop
int getStatus(void)
{
	return SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_ISPLAYING);
}

//get basic info : bitrate, samplrate, channels
int getInfo(int mode)
{
	return SendMessage(plugin.hwndParent,WM_WA_IPC,mode,IPC_GETINFO);
}

//get winamp version
int getVersion(void)
{
	return SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_GETVERSION);
}

//current time elapsed of song
//time in seconds does not work.  Use MSECONDS.
int getPlayTime(void)
{
	return SendMessage(plugin.hwndParent,WM_WA_IPC,MSECONDS,IPC_GETOUTPUTTIME);
}

//returns the index of the song in the playlist that is currently playing
int getPlaylistIndex(void)
{
	return SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_GETLISTPOS);
}

//returns pointer to entire playlist
char* getPlaylist(void)
{
	char* song;
	int pos = 0;
	char* buffer = "";
	while(pos < getPlaylistLength())
	{
		song = (char*)SendMessage(plugin.hwndParent,WM_WA_IPC,getPlaylistIndex(),IPC_GETPLAYLISTTITLE);
		sprintf(buffer,"%s\r\n%s\r\n",buffer, song);
		pos ++;
	}
	return buffer;

}

//return the number of songs in the playlist
int getPlaylistLength(void)
{
	return SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_GETLISTLENGTH);
}

//calculate the string size so i don't have to
int stringSize(char *inString)
{
	int x=0;
	while(inString[x]!=0)
	{
		x++;
	}
	return x;
}