 /***************************************************************************************
 *This program is free software; you can redistribute it and/or modify					*
 * it under the terms of the GNU General Public License as published by					*
 * the Free Software Foundation; either version 2 of the License, or					*
 * (at your option) any later version.													*
 *																						*
 * The GPL can be found at: http://www.gnu.org/copyleft/gpl.html						*
 *																						*
 *																						*	
 ****************************************************************************************
 * Authors:																			  *
 *          Marc Dukette                                                              *
 **************************************************************************************/



#include "stdafx.h"
#include "pocketmvp.h"
#include <commctrl.h>
#include "decore.h"
#include "avidecaps.h"
#include "portab.h"
#include "yuv2rgb.h"
#include "skin.h"
#include "utilities.h"
#include "SipApi.h"
#include "imgdecmp.h"
#include "audiothread.h"

//ATI Specific
#ifdef ATI
extern "C"
{

#include <w100api.h>
U32 VRAMoffset,VRAMoffset2;
U16 VH1,VH2;
ATI_STRETCH stretchOptions;
bool Cleared=false;
ATI_OVERLAYPROP OvlWinProp;
U16 OverlayHandle = 0;
int xStart=0;
int yStart=0;
bool ForceFit=false;

}
#endif



/************************************************************************************************/
//Function prototypes
/************************************************************************************************/

#if (_WIN32_WCE >= 300 && !defined(HPC))
	
	typedef BOOL (CALLBACK* paygshell_SHFullScreen)( HWND hwnd, DWORD st );
	paygshell_SHFullScreen SHFullScreen;

	#define SHCMBM_GETMENU      (WM_USER + 402)
	#define SHGetMenu( hWndMB )  ( HMENU )SendMessage( ( hWndMB ), SHCMBM_GETMENU, ( WPARAM )0, ( LPARAM )0 )
	#define CommandBar_GetMenu( hWndMB, x )		( HMENU )SendMessage( ( hWndMB ), SHCMBM_GETMENU, ( WPARAM )0, ( LPARAM )0 )
#endif

void ResetDisplay(HWND hWnd);
#ifdef MIPS
int MyGetTickCount();
#else
#define MyGetTickCount() GetTickCount()
#endif
void SeekPos(int nPos,bool isChapter, int isFrame);
double GetPos();

//#ifdef _USEVIDBUFF
extern "C" BOOL SetKMode (BOOL);
//#endif


DWORD WINAPI PlayThread(LPVOID lpParameter);
extern int fnGetFileName(HWND Parent,LPTSTR Filter,LPTSTR initialDir,  LPTSTR OutFileName, int MaxFilName,LPTSTR* szMultiBuff,unsigned int vkctrl, int webview);

typedef void (CALLBACK* pInitializeReader)(reader* rd);
pInitializeReader READER_InitializeReader=InitializeReader;

HWND ExternalInit(HINSTANCE hDll, HINSTANCE hInstance, int nCmdShow,UserOptions* PlayerOptions, HWND* hwndcb,WNDPROC WndProc, LPTSTR* ToolTips);

void Configure(HINSTANCE hDll, HINSTANCE hInstance, HWND Parent,UserOptions* PlayerOptions);

int JumpTo(HWND Parent,int position);

void Equalizer(HINSTANCE hDll, HINSTANCE hInstance, HWND Parent,UserOptions* PlayerOptions);

void SaveOptions(UserOptions* PlayerOptions);
void LoadOptions(UserOptions* PlayerOptions);
void GetDisplayName();

//typedef BOOL (CALLBACK* VirtualCopy)(LPVOID lpvDest, LPVOID lpvSrc, DWORD cbSize, DWORD fdwProtect );
typedef int (CALLBACK* pdecode_frame)(unsigned char *stream, int length, unsigned char *bmp,int flag);
typedef int (CALLBACK*  pdecode_msg)(
			unsigned long handle,
			unsigned long dec_opt,
			void *param1,
			void *param2);

pdecode_frame DecodeFrame=NULL; 
pdecode_msg DecodeMessage=NULL; 



ATOM				MyRegisterClass	(HINSTANCE, LPTSTR);
BOOL				InitInstance	(HINSTANCE, int);
LRESULT CALLBACK	WndProc			(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ListWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void PauseEvent();
void Pause();
void NextFile(int dir);

DWORD WINAPI AudioThread(LPVOID lpParameter);
pInit Init;
pExit Exit;
pSeekStart SeekStart;
pSeekEnd SeekEnd;
pDecompressAudio DecompressAudio;
pGetHeaderInfo GetHeaderInfo;

#ifdef ARM
static int __inline Decode(unsigned char *stream, int length, unsigned char *bmp, int render_flag, int Extra, int refresh);
#else
static int __inline Decode(unsigned char *stream, int length, unsigned char *bmp, int render_flag, int Extra);
#endif


/************************************************************************************************/
//Buffers
/************************************************************************************************/

char* toBuff;
unsigned char temp[VIDEO_BUFFER_SIZE];

char* outputBuffer =0;
TCHAR		FileName[200] = TEXT(".avi\0");
TCHAR		DisplayName[200];
unsigned char* vbuffStart=(unsigned char*)outputBuffer;
short *vbuff; 
TCHAR		szFile[MAX_PATH] = TEXT("");
videoinfo* vidinfo=NULL;
TCHAR PDLFile[200];


/************************************************************************************************/
//Global Flags
/************************************************************************************************/
int DropTwo=1;
int twelve_bit=0;
int e740=0;
int amigo=0;
int FadeMax;
extern int FirstChunk;

bool bPaused=false;
bool bEnd=false;
bool bStopRead=false;
bool NeedHide=false;
bool FastForward=false;
bool Closing=false;
bool bPlayNow=false;
bool EndReached=false;
bool NoIndex=false;
bool RawAudio=false;
bool NeedShuffle=false;
__int8 lastshow;
#ifdef ARM
	bool g_bInvert=false;
#endif

/************************************************************************************************/
//Global Data and Objects
/************************************************************************************************/

#ifdef GAPI
	#include "gx.h"
#endif

HANDLE ha;
HBITMAP  m_hBitmap=NULL;          // Handle to DIBSECTION
HBITMAP  m_hBitBack=NULL;          // Handle to DIBSECTION
HBITMAP  m_hBitButton=NULL;          // Handle to DIBSECTION
reader rd;
bool Chapters=false;
short sY=0;
short sX=0;
LPTSTR ToolTips[8]={_T(""),_T("Play"),_T("Stop"),_T("Fast Forward"),_T("Equalizer"),_T("Full Screen"),_T("PlayerOptions.Rotate"),_T("Next Item")};
int br;
int nDrop=0;
HINSTANCE			hInst;			// The current instance
HWND				hwndCB;			// The command bar handle
HDC compat=NULL;
HBITMAP hb=NULL;

DWORD ht=0;
DWORD hTimerSlider=0;
DWORD hTimerFade=0;
HANDLE hdivx=NULL;
int Display=2;
bool Stream=false;
bool bSkipChunk=false;
DWORD tid;
long oldproc,oldprocid3;
DWORD rtid=NULL;
DWORD ptid=NULL;
HANDLE hPlayThread=NULL;
HANDLE eventStopped;
HANDLE eventAudioStopped;
HANDLE eventAudio;
HANDLE eventNextFrame;
CRITICAL_SECTION cs;
HWND hWndMain=NULL;
UserOptions PlayerOptions;
Skin PlayerSkin;
HWAVEOUT m_hwo;
int totMsTime;
__int64 totAudio;
int nShouldbe;
int baseTick=0;
int tot=0;
int nCurrentFrame;
int DrawWidth;
int DrawHeight;
int g_nHeight;
int g_nWidth;
int nExtra;
int StartPos=0;
_Files* Files=0;
int Dir=1;
int MaxFile;
int CurrentFile;
int StartFile;
COLORREF backColor;
TCHAR lpTempSkin[255];

extern Written;

extern TCHAR ID3_Title[200];
extern TCHAR ID3_Artist[200];
extern TCHAR ID3_Album[200];

/*****************************************************************************************/
//Skin Functions
/*****************************************************************************************/
HWND hwndList,hwndID3;

void AddEntry(LPTSTR FileName, int pos)
{
	LVITEM lv;
	lv.mask=LVIF_TEXT;
	lv.pszText=_T("");
	lv.cchTextMax=1;
	lv.iSubItem=0;
	LPTSTR temp=FileName+wcslen(FileName);
	if (pos<0) lv.iItem=ListView_GetItemCount(hwndList);	
	else lv.iItem=pos;
	ListView_InsertItem(hwndList,&lv);
	while (temp[0]!='.')
	{
		temp--;
	}
	temp++;
	while (temp[0]!='\\'&&(temp[0]!='/'))
	{
		temp--;
	}
	temp++;
	ListView_SetItemText(hwndList,lv.iItem,0,temp);
}

void AddTextEntry(LPTSTR FileName, int pos)
{
	LVITEM lv;
	lv.mask=LVIF_TEXT;
	lv.pszText=_T("");
	lv.cchTextMax=1;
	lv.iSubItem=0;
	if (pos<0) lv.iItem=ListView_GetItemCount(hwndID3);	
	else lv.iItem=pos;
	ListView_InsertItem(hwndID3,&lv);
	ListView_SetItemText(hwndID3,lv.iItem,0,FileName);
}

void FadeIn()
{
	unsigned long pos;
	if (vidinfo->video_frames) return;
	waveOutGetVolume( 0, &pos);				
	int vol=(LOWORD(pos))*100/0xffff;
	if (vol>100) vol=100;
	if (vol<0) vol=0;
	FadeMax=vol;
	vol=0;
	if (!PlayerOptions.Mute)
	{
		waveOutSetVolume( 0, (unsigned long)(0xffff*vol)/100+(0xffff*vol)/100*0x10000  );				
		hTimerFade=SetTimer(hWndMain,444,50,NULL);
		if (!hTimerFade) waveOutSetVolume( 0, (unsigned long)(0xffff*FadeMax)/100+(0xffff*FadeMax)/100*0x10000  );				
	}
}
void LoadSkin(LPTSTR FileName,HWND hWnd)
{
	unsigned long nPos;
	LVCOLUMN lv;
	LoadSkinFile(FileName,hWnd);
	wcscpy(PlayerOptions.Skin,FileName);
	if (hTimerSlider) KillTimer(hWnd,hTimerSlider);
	if (PlayerSkin.SeekButton.width)
		hTimerSlider=SetTimer(hWnd,11,1000,NULL);
	else
		hTimerSlider=NULL;
	if (PlayerSkin.VolButton.width)
	{
		waveOutGetVolume(0,&nPos);
		nPos=(LOWORD(nPos))*100/0xffff;
		if (PlayerSkin.VolSlider.rotated)
			PlayerSkin.VolButton.top = PlayerSkin.VolSlider.top+((nPos*PlayerSkin.VolSlider.height*PlayerSkin.VolButton.step)/100); 
		else
			PlayerSkin.VolButton.left = PlayerSkin.VolSlider.left+((nPos*(PlayerSkin.VolSlider.width-PlayerSkin.VolButton.width)*PlayerSkin.VolButton.step)/100); 
	}
	if (hwndList) DestroyWindow(hwndList);
	if (hwndID3) DestroyWindow(hwndID3);
	hwndList=NULL;
	hwndList=CreateWindowEx(WS_EX_CLIENTEDGE,_T("SysListView32"), _T(""), WS_CHILD|WS_VSCROLL|LVS_SINGLESEL|LVS_REPORT|LVS_SHOWSELALWAYS|LVS_NOCOLUMNHEADER,
		PlayerSkin.ViewPort.left , PlayerSkin.ViewPort.top, PlayerSkin.ViewPort.width, PlayerSkin.ViewPort.height, hWnd, NULL, hInst, NULL);

	LOGFONT lf;
	memset(&lf,0,sizeof(LOGFONT));

	lf.lfWeight=FW_NORMAL;
	HDC hdc=GetDC(hwndList);
	if (PlayerSkin.PlaylistView.point)
	{
		wcscpy(lf.lfFaceName,PlayerSkin.PlaylistView.font);
		__int64 t=(__int64)GetDeviceCaps(hdc, LOGPIXELSY)*(__int64)PlayerSkin.PlaylistView.point/(__int64)72;
		lf.lfHeight = (long)t;
	}
	else
	{
		wcscpy(lf.lfFaceName,_T("Tahoma"));
		__int64 t=(__int64)GetDeviceCaps(hdc, LOGPIXELSY)*(__int64)9/(__int64)72;
		lf.lfHeight = (long)t;
	}
	ReleaseDC(hwndList,hdc);
	HFONT hf=CreateFontIndirect(&lf);
	SendMessage(hwndList,WM_SETFONT,(WPARAM)hf,MAKELPARAM(TRUE,0));
	
	oldproc=SetWindowLong(hwndList,GWL_WNDPROC,(long)ListWndProc);
	if (PlayerSkin.PlaylistView.BackRed!=0||(PlayerSkin.PlaylistView.BackBlue!=0)||(PlayerSkin.PlaylistView.BackGreen!=0)) 
	{
		ListView_SetBkColor(hwndList,RGB(PlayerSkin.PlaylistView.BackRed,PlayerSkin.PlaylistView.BackGreen,PlayerSkin.PlaylistView.BackBlue));
		ListView_SetTextBkColor(hwndList,RGB(PlayerSkin.PlaylistView.BackRed,PlayerSkin.PlaylistView.BackGreen,PlayerSkin.PlaylistView.BackBlue));
	}
	if (PlayerSkin.PlaylistView.FontRed!=0||(PlayerSkin.PlaylistView.FontBlue!=0)||(PlayerSkin.PlaylistView.FontGreen!=0)) 
	{
		ListView_SetTextColor(hwndList,RGB(PlayerSkin.PlaylistView.FontRed,PlayerSkin.PlaylistView.FontGreen,PlayerSkin.PlaylistView.FontBlue));
	}
	ListView_SetExtendedListViewStyle(hwndList,LVS_EX_FULLROWSELECT);
	lv.mask=LVCF_TEXT | LVCF_WIDTH ;
	lv.fmt=LVCFMT_LEFT ;
	lv.cx=PlayerSkin.ViewPort.width-19;
	lv.pszText=_T("File");
	lv.cchTextMax=5;
	ListView_InsertColumn(hwndList,0,&lv);

	hwndID3=CreateWindowEx(WS_EX_CLIENTEDGE,_T("SysListView32"), _T(""), WS_CHILD|WS_VSCROLL|LVS_SINGLESEL|LVS_REPORT|LVS_SHOWSELALWAYS|LVS_NOCOLUMNHEADER,
		PlayerSkin.ViewPort.left , PlayerSkin.ViewPort.top, PlayerSkin.ViewPort.width, PlayerSkin.ViewPort.height, hWnd, NULL, hInst, NULL);

	memset(&lf,0,sizeof(LOGFONT));

	lf.lfWeight=FW_NORMAL;
	hdc=GetDC(hwndID3);
	if (PlayerSkin.MediaView.point)
	{
		wcscpy(lf.lfFaceName,PlayerSkin.MediaView.font);
		__int64 t=(__int64)GetDeviceCaps(hdc, LOGPIXELSY)*(__int64)PlayerSkin.MediaView.point/(__int64)72;
		lf.lfHeight = (long)t;
	}
	else
	{
		wcscpy(lf.lfFaceName,_T("Tahoma"));
		__int64 t=(__int64)GetDeviceCaps(hdc, LOGPIXELSY)*(__int64)9/(__int64)72;
		lf.lfHeight = (long)t;
	}
	ReleaseDC(hwndID3,hdc);
	hf=CreateFontIndirect(&lf);
	SendMessage(hwndID3,WM_SETFONT,(WPARAM)hf,MAKELPARAM(TRUE,0));
	
	oldprocid3=SetWindowLong(hwndID3,GWL_WNDPROC,(long)ListWndProc);
	if (PlayerSkin.MediaView.BackRed!=0||(PlayerSkin.MediaView.BackBlue!=0)||(PlayerSkin.MediaView.BackGreen!=0)) 
	{
		ListView_SetBkColor(hwndID3,RGB(PlayerSkin.MediaView.BackRed,PlayerSkin.MediaView.BackGreen,PlayerSkin.MediaView.BackBlue));
		ListView_SetTextBkColor(hwndID3,RGB(PlayerSkin.MediaView.BackRed,PlayerSkin.MediaView.BackGreen,PlayerSkin.MediaView.BackBlue));
	}
	if (PlayerSkin.MediaView.FontRed!=0||(PlayerSkin.MediaView.FontBlue!=0)||(PlayerSkin.MediaView.FontGreen!=0)) 
	{
		ListView_SetTextColor(hwndID3,RGB(PlayerSkin.MediaView.FontRed,PlayerSkin.MediaView.FontGreen,PlayerSkin.MediaView.FontBlue));
	}
	ListView_SetExtendedListViewStyle(hwndID3,LVS_EX_FULLROWSELECT);
	lv.mask=LVCF_TEXT | LVCF_WIDTH ;
	lv.fmt=LVCFMT_LEFT ;
	lv.cx=PlayerSkin.ViewPort.width-19;
	lv.pszText=_T("File");
	lv.cchTextMax=5;
	ListView_InsertColumn(hwndID3,0,&lv);
	PostMessage(hWndMain,WM_USER+401,0,0);
	if (wcscmp(FileName,_T(""))) GetDisplayName();
}


void DrawButtonDown(SkinItem* location)
{
	if (!NeedHide||(bPaused))
	{
		HDC hdc=GetDC(hWndMain);
		HBITMAP old;
		old=(HBITMAP)SelectObject(compat,m_hBitButton);
		BitBlt(hdc,location->left,location->top,location->width,location->height,compat,location->pushedleft,location->pushedtop,SRCCOPY);
		SelectObject(compat,old);
		ReleaseDC(hWndMain,hdc);
	}
	location->status=1;

}


void DrawButtonUp(SkinItem* location)
{
	if (!NeedHide||(bPaused))
	{
		HDC hdc=GetDC(hWndMain);
		HBITMAP old;
		old=(HBITMAP)SelectObject(compat,m_hBitBack);
		BitBlt(hdc,location->left,location->top,location->width,location->height,compat,location->left,location->top-Y_ADJUST,SRCCOPY);
		SelectObject(compat,old);
		ReleaseDC(hWndMain,hdc);
	}
	location->status=0;

}

void ProcessRelease(int x,int y)
{
	if (!NeedHide||(bPaused))
	{
		if (PlayerSkin.SeekButton.status)
		{
			int nPos;
			PlayerSkin.SeekButton.status=0;
			if (PlayerSkin.SeekSlider.rotated)
				nPos=(((PlayerSkin.SeekButton.top-PlayerSkin.SeekSlider.top)*PlayerSkin.SeekButton.step*100)/(PlayerSkin.SeekSlider.height-PlayerSkin.SeekButton.height));
			else
				nPos=(((PlayerSkin.SeekButton.left-PlayerSkin.SeekSlider.left)*PlayerSkin.SeekButton.step*100)/(PlayerSkin.SeekSlider.width-PlayerSkin.SeekButton.width));
			if (nPos<0) nPos=0;
			if (nPos>100) nPos=100;
			SeekPos(nPos,0,0);
		}
		else if (PlayerSkin.VolButton.status)
		{
			int nPos;
			PlayerSkin.VolButton.status=0;
			if (PlayerSkin.VolSlider.rotated)
			{
				nPos=((PlayerSkin.VolButton.top-PlayerSkin.VolSlider.top)*PlayerSkin.VolButton.step*100)/(PlayerSkin.VolSlider.height-PlayerSkin.VolButton.height);
			}
			else
			{
				nPos=((PlayerSkin.VolButton.left-PlayerSkin.VolSlider.left)*PlayerSkin.VolButton.step*100)/(PlayerSkin.VolSlider.width-PlayerSkin.VolButton.width);
			}
			if (nPos<0) nPos=0;
			if (nPos>100) nPos=100;
			if (!PlayerOptions.Mute) waveOutSetVolume( 0, (0xffff*nPos)/100+(0xffff*nPos)/100*0x10000  );
		}
		else if (CheckRect(x,y,&PlayerSkin.StopButton))
		{
			DrawButtonUp(&PlayerSkin.StopButton);
			SendMessage(hWndMain,WM_COMMAND,IDM_STOP,NULL);
		}
		else if (CheckRect(x,y,&PlayerSkin.EditorButton))
		{
			DrawButtonUp(&PlayerSkin.EditorButton);
			SendMessage(hWndMain,WM_COMMAND,IDM_PLAYLIST,NULL);
		}
		else if (CheckRect(x,y,&PlayerSkin.OpenButton))
		{
			DrawButtonUp(&PlayerSkin.OpenButton);
			SendMessage(hWndMain,WM_COMMAND,IDM_OPEN,NULL);
		}
		else if (CheckRect(x,y,&PlayerSkin.NextButton))
		{
			DrawButtonUp(&PlayerSkin.NextButton);
			SendMessage(hWndMain,WM_COMMAND,IDM_NEXT,NULL);
		}
		else if (CheckRect(x,y,&PlayerSkin.PrevButton))
		{
			DrawButtonUp(&PlayerSkin.PrevButton);
			SendMessage(hWndMain,WM_COMMAND,IDM_PREV,NULL);
		}
		else if (CheckRect(x,y,&PlayerSkin.SeekSlider))
		{
			if (PlayerSkin.SeekSlider.rotated)
			{
				if (y>PlayerSkin.SeekButton.top+PlayerSkin.SeekButton.height)
				{
					PlayerSkin.SeekButton.top+=PlayerSkin.SeekButton.bigstep;//-PlayerSkin.SeekButton.height;
				}
				else if (y<PlayerSkin.SeekButton.top)
				{
					PlayerSkin.SeekButton.top-=PlayerSkin.SeekButton.bigstep;//-PlayerSkin.SeekButton.height;
				}
				SeekPos(((PlayerSkin.SeekButton.top-PlayerSkin.SeekSlider.top)*PlayerSkin.SeekButton.step*100)/PlayerSkin.SeekSlider.height,0,0);
			}
			else
			{
				if (x>PlayerSkin.SeekButton.left+PlayerSkin.SeekButton.width)
				{
					PlayerSkin.SeekButton.left+=PlayerSkin.SeekButton.bigstep;//-PlayerSkin.SeekButton.height;
					if (PlayerSkin.SeekButton.left+PlayerSkin.SeekButton.width>(PlayerSkin.SeekSlider.left+PlayerSkin.SeekSlider.width))
						PlayerSkin.SeekButton.left=(PlayerSkin.SeekSlider.left+PlayerSkin.SeekSlider.width)-PlayerSkin.SeekButton.width;
				}
				else if (x<PlayerSkin.SeekButton.left)
				{
					PlayerSkin.SeekButton.left-=PlayerSkin.SeekButton.bigstep;//-PlayerSkin.SeekButton.height;
					if (PlayerSkin.SeekButton.left<(PlayerSkin.SeekSlider.left))
						PlayerSkin.SeekButton.left=PlayerSkin.SeekSlider.left;
				}
				SeekPos(((PlayerSkin.SeekButton.left-PlayerSkin.SeekSlider.left)*PlayerSkin.SeekButton.step*100)/PlayerSkin.SeekSlider.width,0,0);
			}
			DrawButtonUp(&PlayerSkin.SeekSlider);
			DrawButtonDown(&PlayerSkin.SeekButton);
			PlayerSkin.SeekButton.status=0;
		}
		else if (CheckRect(x,y,&PlayerSkin.VolSlider))
		{
			if (PlayerSkin.VolSlider.rotated)
			{
				if (y>PlayerSkin.VolButton.top+PlayerSkin.VolButton.height)
				{
					PlayerSkin.VolButton.top+=PlayerSkin.VolButton.bigstep;//-PlayerSkin.SeekButton.height;
				}
				else if (y<PlayerSkin.VolButton.top)
				{
					PlayerSkin.VolButton.top-=PlayerSkin.VolButton.bigstep;//-PlayerSkin.SeekButton.height;
				}
				int nPos=((PlayerSkin.VolButton.top-PlayerSkin.VolSlider.top)*PlayerSkin.VolButton.step*100)/PlayerSkin.VolSlider.height;
				if (!PlayerOptions.Mute) waveOutSetVolume( 0, (0xffff*nPos)/100+(0xffff*nPos)/100*0x10000  );
			}
			else
			{
				if (x>PlayerSkin.VolButton.left+PlayerSkin.VolButton.width)
				{
					PlayerSkin.VolButton.left+=PlayerSkin.VolButton.bigstep;//-PlayerSkin.SeekButton.height;
					if (PlayerSkin.VolButton.left+PlayerSkin.VolButton.width>(PlayerSkin.VolSlider.left+PlayerSkin.VolSlider.width))
						PlayerSkin.VolButton.left=(PlayerSkin.VolSlider.left+PlayerSkin.VolSlider.width)-PlayerSkin.VolButton.width;
				}
				else if (x<PlayerSkin.VolButton.left)
				{
					PlayerSkin.VolButton.left-=PlayerSkin.VolButton.bigstep;//-PlayerSkin.SeekButton.height;
					if (PlayerSkin.VolButton.left<(PlayerSkin.VolSlider.left))
						PlayerSkin.VolButton.left=PlayerSkin.VolSlider.left;
				}
				int nPos=((PlayerSkin.VolButton.left-PlayerSkin.VolSlider.left)*PlayerSkin.VolButton.step*100)/PlayerSkin.VolSlider.width;
				if (!PlayerOptions.Mute) waveOutSetVolume( 0, (0xffff*nPos)/100+(0xffff*nPos)/100*0x10000  );
			}
			DrawButtonUp(&PlayerSkin.VolSlider);
			DrawButtonDown(&PlayerSkin.VolButton);
			PlayerSkin.VolButton.status=0;
		}
	}

}

void ProcessPush(int x,int y)
{
	if (!NeedHide||(bPaused))
	{
		if (CheckRect(x,y,&PlayerSkin.ViewPort))
		{
			PauseEvent();
		}
		else if (CheckRect(x,y,&PlayerSkin.StopButton))
		{
			DrawButtonDown(&PlayerSkin.StopButton);
		}
		else if (CheckRect(x,y,&PlayerSkin.EditorButton))
		{
			DrawButtonDown(&PlayerSkin.EditorButton);
		}
		else if (CheckRect(x,y,&PlayerSkin.OpenButton))
		{
			DrawButtonDown(&PlayerSkin.OpenButton);
		}
		else if (CheckRect(x,y,&PlayerSkin.PrevButton))
		{
			DrawButtonDown(&PlayerSkin.PrevButton);
		}
		else if (CheckRect(x,y,&PlayerSkin.NextButton))
		{
			DrawButtonDown(&PlayerSkin.NextButton);
		}
		else if (CheckRect(x,y,&PlayerSkin.PlayButton))
		{
			PauseEvent();

		}
		else if (CheckRect(x,y,&PlayerSkin.FFWDButton))
		{
			SendMessage(hWndMain,WM_COMMAND,IDM_FASTFWD,NULL);

		}
		else if (CheckRect(x,y,&PlayerSkin.RotateButton))
		{
			SendMessage(hWndMain,WM_COMMAND,IDM_ROTATE,NULL);

		}
		else if (CheckRect(x,y,&PlayerSkin.MuteButton))
		{
			SendMessage(hWndMain,WM_COMMAND,IDM_MUTE,NULL);

		}
		else if (CheckRect(x,y,&PlayerSkin.FullScreenButton))
		{
			SendMessage(hWndMain,WM_COMMAND,IDM_DOUBLE,NULL);

		}
		else if (CheckRect(x,y,&PlayerSkin.EQButton))
		{
			SendMessage(hWndMain,WM_COMMAND,IDM_EQON,NULL);

		}
		else if (CheckRect(x,y,&PlayerSkin.RepeatButton))
		{
			SendMessage(hWndMain,WM_COMMAND,IDM_REPEAT,NULL);

		}
		else if (CheckRect(x,y,&PlayerSkin.SeekButton))
		{
			DrawButtonDown(&PlayerSkin.SeekButton);
		}
		else if (CheckRect(x,y,&PlayerSkin.VolButton))
		{
			DrawButtonDown(&PlayerSkin.VolButton);
		}
		else if (CheckRect(x,y,&PlayerSkin.InfoView))
		{
			PlayerSkin.InfoView.scrolltext=!PlayerSkin.InfoView.scrolltext;
		}


	}
	else
	{
		PauseEvent();
	}


}
void ProcessTrack(int x,int y)
{
	if (!NeedHide||(bPaused))
	{
		if (PlayerSkin.SeekButton.status)
		{
			if (PlayerSkin.SeekSlider.rotated)
			{
				if (y>PlayerSkin.SeekSlider.top&&(y<PlayerSkin.SeekSlider.top+PlayerSkin.SeekSlider.height))
				{
					PlayerSkin.SeekButton.top=y;//-PlayerSkin.SeekButton.height;
					if (PlayerSkin.SeekButton.top+PlayerSkin.SeekButton.height>PlayerSkin.SeekSlider.top+PlayerSkin.SeekSlider.height) 
						PlayerSkin.SeekButton.top=PlayerSkin.SeekSlider.top+PlayerSkin.SeekSlider.height-PlayerSkin.SeekButton.height;
					DrawButtonUp(&PlayerSkin.SeekSlider);
					DrawButtonDown(&PlayerSkin.SeekButton);
				}
			}
			else
			{
				x-=PlayerSkin.SeekButton.width/2;
				if (x<PlayerSkin.SeekSlider.left) x=PlayerSkin.SeekSlider.left;
				PlayerSkin.SeekButton.left=x;//-PlayerSkin.SeekButton.width;
				if (PlayerSkin.SeekButton.left+PlayerSkin.SeekButton.width>PlayerSkin.SeekSlider.left+PlayerSkin.SeekSlider.width) 
					PlayerSkin.SeekButton.left=PlayerSkin.SeekSlider.left+PlayerSkin.SeekSlider.width-PlayerSkin.SeekButton.width;
				DrawButtonUp(&PlayerSkin.SeekSlider);
				DrawButtonDown(&PlayerSkin.SeekButton);

			}
		}
		else if (PlayerSkin.VolButton.status)
		{
			if (PlayerSkin.VolSlider.rotated)
			{
				if (y>PlayerSkin.VolSlider.top&&(y<PlayerSkin.VolSlider.top+PlayerSkin.VolSlider.height))
				{
					PlayerSkin.VolButton.top=y;//-PlayerSkin.SeekButton.height;
					if (PlayerSkin.VolButton.top+PlayerSkin.VolButton.height>PlayerSkin.VolSlider.top+PlayerSkin.VolSlider.height) 
						PlayerSkin.VolButton.top=PlayerSkin.VolSlider.top+PlayerSkin.VolSlider.height-PlayerSkin.VolButton.height;
					DrawButtonUp(&PlayerSkin.VolSlider);
					DrawButtonDown(&PlayerSkin.VolButton);
				}
			}
			else
			{
				x-=PlayerSkin.VolButton.width/2;
				if (x<PlayerSkin.VolSlider.left) x=PlayerSkin.VolSlider.left;
				PlayerSkin.VolButton.left=x;//-PlayerSkin.SeekButton.width;
				if (PlayerSkin.VolButton.left+PlayerSkin.VolButton.width>PlayerSkin.VolSlider.left+PlayerSkin.VolSlider.width) 
					PlayerSkin.VolButton.left=PlayerSkin.VolSlider.left+PlayerSkin.VolSlider.width-PlayerSkin.VolButton.width;
				DrawButtonUp(&PlayerSkin.VolSlider);
				DrawButtonDown(&PlayerSkin.VolButton);

			}
		}
		else if (PlayerSkin.StopButton.status)
		{
			if (!CheckRect(x,y,&PlayerSkin.StopButton))
				DrawButtonUp(&PlayerSkin.StopButton);
		}
		else if (PlayerSkin.OpenButton.status)
		{
			if (!CheckRect(x,y,&PlayerSkin.OpenButton))
				DrawButtonUp(&PlayerSkin.OpenButton);
		}
		else if (PlayerSkin.EditorButton.status)
		{
			if (!CheckRect(x,y,&PlayerSkin.EditorButton))
				DrawButtonUp(&PlayerSkin.EditorButton);
		}
		else if (PlayerSkin.NextButton.status)
		{
			if (!CheckRect(x,y,&PlayerSkin.NextButton))
				DrawButtonUp(&PlayerSkin.NextButton);
		}
		else if (PlayerSkin.PrevButton.status)
		{
			if (!CheckRect(x,y,&PlayerSkin.PrevButton))
				DrawButtonUp(&PlayerSkin.PrevButton);
		}
	}
}


/*****************************************************************************************/
//Input Functions
/*****************************************************************************************/

unsigned char* GetNextBuffer(int* refresh, int* frame,int drop)
{
	int size=rd.READER_NextVideoFrame((char*) temp, drop);
	if (size<=0)
	{
		if (size<0) bEnd=1;
		return 0;
	}
	*frame=size;
#ifdef ARM
	*refresh=size>vidinfo->threshhold||(rd.READER_isKeyFrame(vidinfo->video_pos-1));
#endif
	return temp;
}



/*****************************************************************************************/
//Video Decode Functions
/*****************************************************************************************/
int dummy_decore(unsigned long handle, unsigned long dec_opt,	void *param1, void *param2)
{
	return 0;
}
/***/
int dummy_decore_frame(unsigned char *stream, int length, unsigned char *bmp, int render_flag)
{
	memcpy((void*)bmp,(void*)stream,sizeof(AVPicture));
	return 1;
}

int decore_setoutput(unsigned long color_depth, int output_format)
{

	switch (output_format)
	{
		case RGB565:
#ifdef ATI
			if (color_depth!=2)
				convert_yuv = yuv2rgb_420; 
			else
#endif
				convert_yuv = yuv2rgb_565;
			break;
		case RGB565R:
			convert_yuv = yuv2rgb_565R;
#ifdef ATI
			if (color_depth!=2)
				convert_yuv = yuv2rgb_420R; 
#else
#if (defined(ARM)&&(!defined(IPAQ))&&(defined(GAPI)))
			if (e740) convert_yuv = yuv2rgb_565R_e740; 
#endif
#endif
			break;
#ifndef ATI
		case RGB565RZ:
			convert_yuv = yuv2rgb_565RZ;
			break;
		case RGB565Z:
			convert_yuv = yuv2rgb_565Z;
			break;
#endif
		#ifdef MIPS
		case RGB565ZPP:
			convert_yuv = yuv2rgb_565ZPP;
			break;
		#endif
	}
	return 1;
}


long decBegin(int First)
{
	DEC_PARAM dec_param;
	dec_param.x_dim = g_nWidth;
	dec_param.y_dim = g_nHeight;
	dec_param.color_depth = 0;
	dec_param.dither=PlayerOptions.Clean;
	lastshow=0;
#ifdef IPAQ
	if (First<=0)
		dec_param.output_format=RGB565;
	else
		dec_param.output_format=RGB565R;
#else
	dec_param.output_format=RGB565;
#endif

	if (PlayerOptions.Double)
	{
		if (First<=0)
		{
#ifdef ATI
			dec_param.output_format=RGB565;
#else
			dec_param.output_format=RGB565Z;
#endif
#ifdef MIPS
			if (PlayerOptions.Clean)
				dec_param.output_format=RGB565ZPP;
#endif
		}
		else
		{
#ifdef IPAQ
			dec_param.output_format=RGB565R;
#else
			dec_param.output_format=RGB565;
#endif
		}
	}


	if (PlayerOptions.Rotate) 
	{
#ifdef IPAQ
		if (First<=0)
		{
			dec_param.output_format=RGB565R;
		}
		else
		{
			dec_param.output_format=RGB565;
		}
#else
		dec_param.output_format=RGB565R;
#endif
	}

	if (PlayerOptions.Double&&(PlayerOptions.Rotate)) 
	{
		if (First<=0)
		{
#ifndef ATI
			dec_param.output_format=RGB565RZ;
#endif
		}
	}
	if (First==0)
	{
		DecodeMessage((long) NULL, DEC_OPT_INIT, &dec_param, 0);
	}

	decore_setoutput((long) First, dec_param.output_format);

	return 0;
}

#ifdef ATI

static int __inline Decode(unsigned char *stream, int length, unsigned char *bmp, int render_flag, int Extra, int refresh)
{
	AVPicture avpict;
	EnterCriticalSection(&cs);
	int d=DecodeFrame(stream,length,(unsigned char*) &avpict,render_flag);
	//render_flag&=d+1;
	bool Rotate=PlayerOptions.Rotate;
	if (!d)
	{
		nDrop++;
		render_flag=0;
	}
	if (render_flag) 
	{

		if (Extra==-1) //||(PlayerOptions.Double))
		{
			if (Extra==-1) Extra=0;
			convert_yuv(avpict.data[0], avpict.linesize[0],
				avpict.data[1], avpict.data[2], avpict.linesize[1],
				(unsigned char*) bmp, g_nWidth,g_nHeight,Extra,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],lastshow&&(!refresh)&&(avpict.last_picture[0]!=avpict.data[0]), g_bInvert);
			while(AtiCore_SetOverlayOnOff(OverlayHandle,0)!=SUCCESS);
		}
		else
		{
			U32 regdata;
			int xStart;
			int yStart;
		//	ATI_STRETCH stretchOptions;

			while ( AtiCore_WaitComplete( 100 ) != SUCCESS );
			if (PlayerOptions.Double||(ForceFit)) //&&(!Cleared))
			{
					if (!Cleared)
					{
						Cleared=true;
						AtiCore_SetOverlayOnOff(OverlayHandle,1);
						AtiCore_SetupMemoryTransfer((U32)OvlWinProp.lpSrcBitmap,&regdata);
						memset((void*)regdata,16,OvlWinProp.SrcPitch*OvlWinProp.SrcHeight);
						memset((void*)(regdata+(OvlWinProp.SrcPitch*OvlWinProp.SrcHeight)),128,OvlWinProp.SrcPitch*OvlWinProp.SrcHeight*3/2);
						AtiCore_TerminateMemoryTransfer();
						if (PlayerOptions.FitToViewPort)
						{
							RECT rcView;
							HDC hdc=GetDC(hWndMain);
							rcView.left=PlayerSkin.ViewPort.left;
							rcView.top=PlayerSkin.ViewPort.top;
							rcView.right=PlayerSkin.ViewPort.width+PlayerSkin.ViewPort.left;
							rcView.bottom=PlayerSkin.ViewPort.height+PlayerSkin.ViewPort.top;

							HBRUSH hbr=CreateSolidBrush(RGB(0,0,0));
							FillRect(hdc,&rcView,hbr); //(HBRUSH)GetStockObject(BLACK_BRUSH));
							DeleteObject(hbr);
							ReleaseDC(hWndMain,hdc);
						}
					}
					int nWidth;
					int nHeight;
					nWidth=Rotate?g_nHeight:g_nWidth;
					nHeight=Rotate?g_nWidth:g_nHeight;
					if (Rotate&&(nWidth%16)) nWidth-=nWidth%16;
					if (!ForceFit)
					{
						xStart=(OvlWinProp.SrcPitch-(((float)((float)16/(float)stretchOptions.ScaleXFactor))*(nWidth<OvlWinProp.SrcPitch?nWidth:OvlWinProp.SrcPitch)))/2;
						yStart=(OvlWinProp.SrcHeight-(((float)((float)16/(float)stretchOptions.ScaleYFactor))*(nHeight<OvlWinProp.SrcHeight?nHeight:OvlWinProp.SrcHeight)))/2;
					}
					else
					{
						xStart=(OvlWinProp.SrcPitch-(((float)((float)16/(float)stretchOptions.ScaleXFactor))*(nWidth)))/2; 
						yStart=(OvlWinProp.SrcHeight-(((float)((float)16/(float)stretchOptions.ScaleYFactor))*(nHeight)))/2; 
						if (yStart<0) yStart=(OvlWinProp.SrcHeight-(((float)((float)16/(float)stretchOptions.ScaleYFactor))*(nHeight)));
						if (xStart<0) xStart=(OvlWinProp.SrcPitch-(((float)((float)16/(float)stretchOptions.ScaleXFactor))*(nWidth)));
					}


			}
			if (!Rotate)
			{
				

				if (ForceFit)
				{
					ATI_RECT srcRect;
					ATI_CLIPRECT clipRect;
					ATI_POINT dpPoint;
					U32 y=(U32)VRAMoffset2;
					U32 VRAMTemp=VRAMoffset+(320*120);
					int nWidth;
					int nHeight;
					int row;
					int stepwidth=g_nWidth;
					//if (Rotate) stepwidth=g_nHeight;
					if (stepwidth%16) stepwidth+=16-(stepwidth%16);
					clipRect.X_Top_Left = 0;
					clipRect.Y_Top_Left = 0;
					clipRect.X_Bottom_Right = (S16)g_nWidth;
					clipRect.Y_Bottom_Right = (S16)64;
					AtiCore_SetSrcClippingRect( &clipRect );
					clipRect.X_Bottom_Right = (S16)OvlWinProp.SrcPitch;
					clipRect.Y_Bottom_Right = (S16)OvlWinProp.SrcHeight;
					AtiCore_SetDstClippingRect( &clipRect );
					srcRect.XCoord=0;
					srcRect.YCoord=0;
					for (row=0;row<=(g_nHeight/64);row++)
					{
						int size=64;
						if (row==g_nHeight/64)
						{
							size=g_nHeight%64;
							size-=size%16;
							if (!size)
								continue;
						}
						srcRect.Width=g_nWidth;
						srcRect.Height=size;
						AtiCore_SetupMemoryTransfer(VRAMoffset,&regdata);
						convert_yuv(avpict.data[0]+(avpict.linesize[0]*64*row), avpict.linesize[0],
						avpict.data[1], avpict.data[2], avpict.linesize[1],
						(unsigned char*) regdata, g_nWidth,size,stepwidth,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],0, 1);

						AtiCore_TerminateMemoryTransfer();


						srcRect.Width = stepwidth;
						srcRect.Height = size;

						dpPoint.XCoord =xStart;

						dpPoint.YCoord=((yStart-1)+((16*64*(row))/stretchOptions.ScaleXFactor));
						AtiCore_SetSrcPitchOffset( srcRect.Width, (U32)VRAMoffset );
						AtiCore_SetDstPitchOffset( OvlWinProp.SrcPitch, y);
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );

						srcRect.Width=stepwidth;
						srcRect.Height=size>>1;

						AtiCore_SetupMemoryTransfer(VRAMoffset,&regdata);
						convert_yuv(avpict.data[0], avpict.linesize[0],
							avpict.data[1]+(avpict.linesize[1]*32*row), avpict.data[2]+(avpict.linesize[1]*32*row), avpict.linesize[1],
							(unsigned char*) regdata, g_nWidth,size,stepwidth,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],0, 2);

						AtiCore_TerminateMemoryTransfer();

						srcRect.Width = stepwidth>>1;
						srcRect.Height = size>>1;

						dpPoint.YCoord >>=1;
        
						dpPoint.XCoord >>=1;

						AtiCore_SetSrcPitchOffset( srcRect.Width, (U32)VRAMoffset);
						AtiCore_SetDstPitchOffset( OvlWinProp.SrcPitch>>1, (U32)y + OvlWinProp.SrcPitch * OvlWinProp.SrcHeight );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );

						AtiCore_SetSrcPitchOffset( srcRect.Width, (U32)VRAMoffset + srcRect.Width * (size>>1));
						AtiCore_SetDstPitchOffset( OvlWinProp.SrcPitch>>1, (U32)y + OvlWinProp.SrcPitch * OvlWinProp.SrcHeight * 5 / 4 );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );
					}
				}
				else
				{
					int stepwidth=g_nWidth;
					if (Rotate) stepwidth=g_nHeight;
					if (stepwidth%16) stepwidth+=16-(stepwidth%16);
					AtiCore_SetupMemoryTransfer(VRAMoffset2,&regdata);
					convert_yuv(avpict.data[0], avpict.linesize[0],
						avpict.data[1], avpict.data[2], avpict.linesize[1],
						(unsigned char*) regdata, g_nWidth,g_nHeight,stepwidth,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],0, 0);

					AtiCore_TerminateMemoryTransfer();
					while ( AtiCore_WaitComplete( 100 ) != SUCCESS );
					if (PlayerOptions.Double)
					{
						//ATI_STRETCH stretchOptions;
						ATI_POINT dpPoint;
						ATI_RECT srcRect;
						int nWidth=(stepwidth<DisplayWidth?stepwidth:DisplayWidth);
						int nHeight=(g_nHeight<DisplayHeight?g_nHeight:DisplayHeight);
						 dpPoint.XCoord = dpPoint.YCoord = 0;

						//AtiCore_SetOverlayPos(OverlayHandle,0,0); 
						srcRect.XCoord = srcRect.YCoord = 0;
						srcRect.Width = nWidth;
						srcRect.Height = nHeight;
						AtiCore_SetRopOperation( ROP3_SRCCOPY );
						AtiCore_SetDstType( DSTTYPE_8BPP );
						AtiCore_SetSrcType( SRCTYPE_EQU_DST );


						// Setting clipping rectangle for stretching.  Note that Src and Dst will have different sizes
						ATI_CLIPRECT clipRect;
						clipRect.X_Top_Left = 0;
						clipRect.Y_Top_Left = 0;
						clipRect.X_Bottom_Right = (S16)(g_nWidth<DisplayWidth?g_nWidth:DisplayWidth);
						clipRect.Y_Bottom_Right = (S16)nHeight;
						AtiCore_SetSrcClippingRect( &clipRect );
						clipRect.X_Bottom_Right = (S16)DisplayWidth;
						clipRect.Y_Bottom_Right = (S16)DisplayHeight;
						AtiCore_SetDstClippingRect( &clipRect );

						U32 y=(U32)OvlWinProp.lpSrcBitmap; 
						dpPoint.XCoord = xStart;
						dpPoint.YCoord =yStart;

						AtiCore_SetSrcPitchOffset( nWidth, (U32)VRAMoffset2 );
						AtiCore_SetDstPitchOffset( DisplayWidth, y);
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );
        
						dpPoint.XCoord >>=1;
						dpPoint.YCoord >>=1;

						srcRect.Width >>=1;
						srcRect.Height>>=1;
						// U & V
						AtiCore_SetSrcPitchOffset( nWidth/2, (U32)VRAMoffset2 + nWidth * nHeight );
						AtiCore_SetDstPitchOffset( DisplayWidth/2, (U32)y + DisplayWidth * DisplayHeight );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );

						AtiCore_SetSrcPitchOffset( nWidth/2, (U32)VRAMoffset2 + nWidth * nHeight * 5 / 4 );
						AtiCore_SetDstPitchOffset( DisplayWidth/2, (U32)y + DisplayWidth * DisplayHeight * 5 / 4 );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );


					}
				}
			}
			else
			{
				if (ForceFit)
				{
					ATI_RECT srcRect;
					ATI_RECT dstRect;
					ATI_CLIPRECT clipRect;
					ATI_POINT dpPoint;
					U32 y=(U32)VRAMoffset2;
					U32 VRAMTemp=VRAMoffset+(320*120);
					int nWidth;
					int nHeight;
					int row;
					int step=g_nWidth<320?320:g_nWidth;
					clipRect.X_Top_Left = 0;
					clipRect.Y_Top_Left = 0;
					clipRect.X_Bottom_Right = (S16)step<DisplayHeight?DisplayHeight:step;
					clipRect.Y_Bottom_Right = (S16)DisplayWidth;
					AtiCore_SetSrcClippingRect( &clipRect );
					clipRect.X_Bottom_Right = (S16)DisplayWidth;
					clipRect.Y_Bottom_Right = (S16)step<DisplayHeight?DisplayHeight:step;
					AtiCore_SetDstClippingRect( &clipRect );
					srcRect.XCoord=0;
					srcRect.YCoord=0;
					dstRect.XCoord=0;
					dstRect.YCoord=0;
					for (row=0;row<=(g_nHeight/64);row++)
					{
						int size=64;
						if (row==g_nHeight/64)
						{
							size=g_nHeight%64;
							size-=size%16;
							if (!size)
								continue;
						}
						srcRect.Width=step;
						srcRect.Height=size;
						dstRect.Width=size;
						dstRect.Height=step;
						AtiCore_SetupMemoryTransfer(VRAMoffset,&regdata);
						convert_yuv(avpict.data[0]+(avpict.linesize[0]*64*row), avpict.linesize[0],
						avpict.data[1], avpict.data[2], avpict.linesize[1],
						(unsigned char*) regdata, g_nWidth,size,step,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],0, 2);

						AtiCore_TerminateMemoryTransfer();


						AtiCore_SetDstPitchOffset(dstRect.Width,VRAMTemp);
						AtiCore_SetSrcPitchOffset(step,VRAMoffset);
						AtiCore_BitBltFilpRotate( blt090Rotate, &dstRect, &srcRect );


						srcRect.Width = size;
						srcRect.Height = g_nWidth;

						dpPoint.YCoord =yStart;

						dpPoint.XCoord=DisplayWidth-((xStart-1)+((16*64*(row)+(16*size))/stretchOptions.ScaleXFactor));
						AtiCore_SetSrcPitchOffset( srcRect.Width, (U32)VRAMTemp );
						AtiCore_SetDstPitchOffset( OvlWinProp.SrcPitch, y);
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );

						srcRect.Width=step;
						dstRect.Height=step;
						srcRect.Height=size>>1;
						dstRect.Width=size>>1;

						AtiCore_SetupMemoryTransfer(VRAMoffset,&regdata);
						convert_yuv(avpict.data[0], avpict.linesize[0],
							avpict.data[1]+(avpict.linesize[1]*32*row), avpict.data[2]+(avpict.linesize[1]*32*row), avpict.linesize[1],
							(unsigned char*) regdata, g_nWidth,size,step,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],0, 3);

						AtiCore_TerminateMemoryTransfer();

						AtiCore_SetDstPitchOffset(dstRect.Width,VRAMTemp);
						AtiCore_SetSrcPitchOffset(step,VRAMoffset);
						AtiCore_BitBltFilpRotate( blt090Rotate, &dstRect, &srcRect );


						srcRect.Width = size>>1;
						srcRect.Height = g_nWidth>>1;

						dpPoint.YCoord =yStart>>1;
        
						dpPoint.XCoord >>=1;

						AtiCore_SetSrcPitchOffset( srcRect.Width, (U32)VRAMTemp);
						AtiCore_SetDstPitchOffset( OvlWinProp.SrcPitch>>1, (U32)y + OvlWinProp.SrcPitch * OvlWinProp.SrcHeight );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );

						AtiCore_SetSrcPitchOffset( srcRect.Width, (U32)VRAMTemp + srcRect.Width * (step>>1));
						AtiCore_SetDstPitchOffset( OvlWinProp.SrcPitch>>1, (U32)y + OvlWinProp.SrcPitch * OvlWinProp.SrcHeight * 5 / 4 );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );
					}


				}
				else
				{
					ATI_RECT srcRect;
					ATI_RECT dstRect;
					srcRect.XCoord=0;
					srcRect.YCoord=0;
					dstRect.XCoord=0;
					dstRect.YCoord=0;
					srcRect.Width=320;
					srcRect.Height=g_nHeight<240?g_nHeight:240;
					dstRect.Width=g_nHeight<240?g_nHeight:240;
					if (dstRect.Width%16) dstRect.Width-=(dstRect.Width%16);
					srcRect.Height=dstRect.Width;
					dstRect.Height=320;
					AtiCore_SetupMemoryTransfer(VRAMoffset,&regdata);
					convert_yuv(avpict.data[0], avpict.linesize[0],
					avpict.data[1], avpict.data[2], avpict.linesize[1],
					(unsigned char*) regdata, g_nWidth,g_nHeight,320,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],0, 0);

					AtiCore_TerminateMemoryTransfer();

					ATI_CLIPRECT clipRect;
					clipRect.X_Top_Left = 0;
					clipRect.Y_Top_Left = 0;
					clipRect.X_Bottom_Right = (S16)DisplayHeight;//nHeight;
					clipRect.Y_Bottom_Right = (S16)DisplayWidth;
					AtiCore_SetSrcClippingRect( &clipRect );
					clipRect.X_Bottom_Right = (S16)DisplayWidth;
					clipRect.Y_Bottom_Right = (S16)DisplayHeight;
					AtiCore_SetDstClippingRect( &clipRect );

					AtiCore_SetDstPitchOffset(dstRect.Width,VRAMoffset2);
					AtiCore_SetSrcPitchOffset(320,VRAMoffset);
					AtiCore_BitBltFilpRotate( blt090Rotate, &dstRect, &srcRect );

					srcRect.Height>>=1;
					dstRect.Width>>=1;

					AtiCore_SetupMemoryTransfer(VRAMoffset,&regdata);
					convert_yuv(avpict.data[0], avpict.linesize[0],
						avpict.data[1], avpict.data[2], avpict.linesize[1],
						(unsigned char*) regdata, g_nWidth,g_nHeight,320,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],0, 1);

					AtiCore_TerminateMemoryTransfer();

					AtiCore_SetDstPitchOffset(dstRect.Width,VRAMoffset2+ 320 * (dstRect.Width<<1));
					AtiCore_SetSrcPitchOffset(320,VRAMoffset);
					AtiCore_BitBltFilpRotate( blt090Rotate, &dstRect, &srcRect );

					if (PlayerOptions.Double)
					{
						ATI_POINT dpPoint;
						ATI_RECT srcRect;
						int nWidth=(g_nHeight<DisplayWidth?g_nHeight:DisplayWidth);
						int nHeight=(g_nWidth<DisplayHeight?g_nWidth:DisplayHeight);
						 dpPoint.XCoord = dpPoint.YCoord = 0;
						//AtiCore_SetOverlayPos(OverlayHandle,0,0); 
						if (nWidth%16) nWidth-=(nWidth%16);


						srcRect.XCoord = srcRect.YCoord = 0;
						srcRect.Width = nWidth;
						srcRect.Height = nHeight;
						AtiCore_SetRopOperation( ROP3_SRCCOPY );
						AtiCore_SetDstType( DSTTYPE_8BPP );
						AtiCore_SetSrcType( SRCTYPE_EQU_DST );

						// Setting clipping rectangle for stretching.  Note that Src and Dst will have different sizes

						U32 y=(U32)OvlWinProp.lpSrcBitmap; // + (xStart + DisplayWidth*yStart);
						dpPoint.XCoord = xStart;
						dpPoint.YCoord =yStart;

						AtiCore_SetSrcPitchOffset( nWidth, (U32)VRAMoffset2 );
						AtiCore_SetDstPitchOffset( DisplayWidth, y);
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );
        
						dpPoint.XCoord >>=1;
						dpPoint.YCoord >>=1;

						srcRect.Width >>=1;
						srcRect.Height >>=1;
						// U & V
						AtiCore_SetSrcPitchOffset( nWidth/2, (U32)VRAMoffset2 + nWidth * 320 );
						AtiCore_SetDstPitchOffset( DisplayWidth/2, (U32)y + DisplayWidth * DisplayHeight );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );

						AtiCore_SetSrcPitchOffset( nWidth/2, (U32)VRAMoffset2 + nWidth * 320 * 5 / 4 );
						AtiCore_SetDstPitchOffset( DisplayWidth/2, (U32)y + DisplayWidth * DisplayHeight * 5 / 4 );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );

					}
				}
				
			}
			AtiCore_SetOverlayOnOff(OverlayHandle,1);

		}
	}

	else if (Extra==-1)
	{
			while(AtiCore_SetOverlayOnOff(OverlayHandle,0)!=SUCCESS);
	}
	LeaveCriticalSection(&cs);
	return render_flag;
}
#else

#ifdef ARM
static int __inline Decode(unsigned char *stream, int length, unsigned char *bmp, int render_flag, int Extra, int refresh)
#else
static int __inline Decode(unsigned char *stream, int length, unsigned char *bmp, int render_flag, int Extra)
#endif
{
	AVPicture avpict;
	EnterCriticalSection(&cs);
//#ifdef _USEVIDBUFF
	SetKMode(true);
//#endif
	int d=DecodeFrame(stream,length,(unsigned char*) &avpict,render_flag);
	if (!d&&(render_flag))
	{
		nDrop++;
		render_flag=0;
	}

	if (render_flag) 
	{
/*		int FrameDiff;
		while((FrameDiff=nShouldbe-nCurrentFrame)<-1&&(nShouldbe>=0)&&(!bPaused)&&(!bEnd))
		{
			if (PlayerOptions.Audio&&(vidinfo->audio_bytes))
			{
				WaitForSingleObject(eventNextFrame,500);
				ResetEvent(eventNextFrame);
			}
			else
			{
				Sleep(0);
			}
		}
*/
#ifdef ARM
#ifndef IPAQ
			if (Extra==-1) Extra=0;
#endif
			convert_yuv(avpict.data[0], avpict.linesize[0],
				avpict.data[1], avpict.data[2], avpict.linesize[1],
				(unsigned char*) bmp, g_nWidth,g_nHeight,Extra,PlayerOptions.Clean*(twelve_bit+1),PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],lastshow&&(!refresh)&&(avpict.last_picture[0]!=avpict.data[0]), g_bInvert);
#else

		convert_yuv(avpict.data[0], avpict.linesize[0],
			avpict.data[1], avpict.data[2], avpict.linesize[1],
			bmp, g_nWidth,g_nHeight,Extra,PlayerOptions.Clean);
#endif
	}


#ifdef ARM
	lastshow=render_flag;
#endif


//#ifdef _USEVIDBUFF
	SetKMode(false);
//#endif
	LeaveCriticalSection(&cs);
	return render_flag;
}
#endif

long decEnd()
{
	DecodeMessage((long) NULL, DEC_OPT_RELEASE, NULL, NULL);

	return 0;
}

static void DropFrames()
{	
	int size;
	int refresh;
	unsigned char* rb=GetNextBuffer(&refresh,&size,1);
	if (rb<=0)
	{
		if (!rb) nDrop++	;
		nCurrentFrame--;
		return;
	}
#ifdef ARM
	Decode(rb,size,0,0,0,1);
#else
	Decode(rb,size,0,0,0);
#endif
	nDrop++;
	if (DropTwo)
	{
		rb=GetNextBuffer(&refresh,&size,1);
		if (!rb) return;
#ifdef ARM
		Decode(rb,size,0,0,0,1);
#else
		Decode(rb,size,0,0,0);
#endif
		nDrop++;
	}
	else
	{
		nCurrentFrame--;
	}

}



/*****************************************************************************************/
//Screen Functions
/*****************************************************************************************/

void  RefreshDisplay(bool Full)
{
	RECT rc;
	if (Full)
	{
		GetClientRect(hWndMain,&rc);
		InvalidateRect(hWndMain,&rc,true);
		UpdateWindow(hWndMain);
	}
	else
		SendMessage(hWndMain,WM_PAINT,(WPARAM)NULL,(LPARAM)1);

}

void ShowControls(bool bShow)
{
	EnableWindow(hwndCB,bShow);
	if (bShow)
	{
		ShowWindow(hwndCB,SW_SHOWNORMAL);
		HWND hWndTB=FindWindow(TEXT("HHTaskbar"),NULL);
		ShowWindow(hWndTB,SW_SHOWNORMAL);
#if (_WIN32_WCE >= 300 && !defined(HPC))
		RECT rc;
		GetWindowRect(hWndMain,&rc);
		rc.top=26;
		rc.bottom=294;
		SHFullScreen(hWndMain,2);
		MoveWindow(hWndMain, 
		  rc.left, 
		  rc.top, 
		  rc.right, 
		  rc.bottom, 
		  false);
#endif
//#if (defined(MIPS)&&(defined(GAPI)))
//		if (1)
//#else
		if (NeedHide)
//#endif
			RefreshDisplay(true);
	}
	else
	{
		HWND hWndTB=FindWindow(TEXT("HHTaskbar"),NULL);
		ShowWindow(hWndTB,SW_HIDE);
#if (_WIN32_WCE >= 300 && !defined(HPC))
		RECT rc;
		GetWindowRect(hWndMain,&rc);
		rc.top=0;
		rc.bottom=320;
		SHFullScreen(hWndMain,1);
		MoveWindow(hWndMain,
		  rc.left, 
		  rc.top, 
		  rc.right, 
		  rc.bottom, 
		  false);
#else
#if (defined(MIPS)&&(defined(GAPI)))
		GXCloseDisplay();
		GXOpenDisplay(hWndMain, GX_FULLSCREEN);
#endif
		RefreshDisplay(true);
#endif
		ShowWindow(hwndCB,SW_HIDE);

	}
}

#ifdef ATI

void SetupATIOverlay(int nWidth, int nHeight)
{
//	if (VH1) AtiCore_DestroySurface(VH1);
//	if (VH2) AtiCore_DestroySurface(VH2);
//	if (!PlayerOptions.Double)
//	{
		ATI_EXTENDEDOVERLAYPROP prop;
		OvlWinProp.SrcPitch =  nWidth<DisplayWidth?nWidth:DisplayWidth; 

		if (PlayerOptions.Rotate)
		{
		//	if (OvlWinProp.SrcPitch%16) OvlWinProp.SrcPitch+=16-(OvlWinProp.SrcPitch%16);
			if (OvlWinProp.SrcPitch%16) OvlWinProp.SrcPitch-=(OvlWinProp.SrcPitch%16);
			prop.x.ExtVideoProp.HInvert=1;
			prop.x.ExtVideoProp.VInvert=1;
			prop.HExpansion=1;
			prop.VExpansion=1;
			prop.RConversion=0;
			OvlWinProp.SrcHeight = 320;
		}
		else
		{
			if (OvlWinProp.SrcPitch%16) OvlWinProp.SrcPitch+=16-(OvlWinProp.SrcPitch%16);
			prop.x.ExtVideoProp.HInvert=0;
			prop.x.ExtVideoProp.VInvert=0;
			prop.HExpansion=1;
			prop.VExpansion=1;
			prop.RConversion=0;
			OvlWinProp.SrcHeight = nHeight;
		}
		OvlWinProp.XCoord = 0;
		OvlWinProp.YCoord = 0;

		OvlWinProp.lpOverlayKey = 0;
		OvlWinProp.OverlayFormat = OVLTYPE_YUV420;

		ForceFit=false;

		if (!PlayerOptions.Double)
		{
			int fitHeight=g_nHeight;
			int fitWidth=g_nWidth;
			if (PlayerOptions.Rotate)
			{
				fitHeight=g_nWidth;
				fitWidth=g_nHeight;
			}
			if (!PlayerOptions.FitToViewPort||(fitHeight<=PlayerSkin.ViewPort.height&&(fitWidth<=PlayerSkin.ViewPort.width)))
			{
				if (PlayerOptions.Rotate) OvlWinProp.OverlayWidth = OvlWinProp.SrcPitch; 
				else  OvlWinProp.OverlayWidth=nWidth<DisplayWidth?nWidth:DisplayWidth; 
			//	OvlWinProp.OverlayWidth = nWidth<DisplayWidth?nWidth:DisplayWidth; 
				OvlWinProp.OverlayHeight = nHeight;
				OvlWinProp.lpSrcBitmap = (U32*)VRAMoffset2;
			}
			else
			{
				U32 pitch;
				U32 offset;
				OvlWinProp.SrcPitch = PlayerSkin.ViewPort.width; 
				OvlWinProp.SrcHeight = PlayerSkin.ViewPort.height;
				if (OvlWinProp.SrcHeight%16) OvlWinProp.SrcHeight-=(OvlWinProp.SrcHeight%16);
				OvlWinProp.OverlayWidth = OvlWinProp.SrcPitch; 
				OvlWinProp.OverlayHeight = OvlWinProp.SrcHeight;
				OvlWinProp.lpSrcBitmap = (U32*)VRAMoffset2; //offset;
				ForceFit=true;
			}
		}
		else
		{
			int fitHeight=g_nHeight;
			int fitWidth=g_nWidth;
			if (PlayerOptions.Rotate)
			{
				fitHeight=g_nWidth;
				fitWidth=g_nHeight;
			}
			if (fitHeight>DisplayHeight||(fitWidth>DisplayWidth))
			{
				U32 pitch;
				U32 offset;
				OvlWinProp.SrcPitch = DisplayWidth; 
				OvlWinProp.SrcHeight = DisplayHeight;
				OvlWinProp.OverlayWidth = OvlWinProp.SrcPitch; 
				OvlWinProp.OverlayHeight = OvlWinProp.SrcHeight;
				OvlWinProp.lpSrcBitmap = (U32*)VRAMoffset2; //offset;
				ForceFit=true;
			}

			else
			{
				U32 pitch;
				U32 offset;
				OvlWinProp.SrcPitch = DisplayWidth; 
				OvlWinProp.SrcHeight =DisplayHeight;
				//if (OvlWinProp.SrcHeight%16) OvlWinProp.SrcHeight-=(OvlWinProp.SrcHeight%16);
				if (OvlWinProp.SrcHeight%16) OvlWinProp.SrcHeight+=16-(OvlWinProp.SrcHeight%16);
				OvlWinProp.OverlayWidth = OvlWinProp.SrcPitch; 
				OvlWinProp.OverlayHeight = OvlWinProp.SrcHeight;
				AtiCore_GetFrontBufferPitchOffset( &pitch, &offset );
				OvlWinProp.lpSrcBitmap = (U32*)offset;
			}
		}
		if ( AtiCore_SetupOverlay( OverlayHandle, &OvlWinProp ) != SUCCESS )
		{
			MessageBox(hWndMain,_T("Failed overlay"),_T(""),MB_OK);
		}
		AtiCore_SetupOverlayExtended(OverlayHandle,&prop);
		if (!PlayerOptions.Double)
		{
			if (!ForceFit)
				AtiCore_SetOverlayPos(OverlayHandle,sX,sY); 
			else
				AtiCore_SetOverlayPos(OverlayHandle,PlayerSkin.ViewPort.left+(PlayerSkin.ViewPort.width-OvlWinProp.SrcPitch)/2,PlayerSkin.ViewPort.top+26+(PlayerSkin.ViewPort.height-OvlWinProp.SrcHeight)/2); 
		}
		else
		{
			AtiCore_SetOverlayPos(OverlayHandle,0,0); 
		}

	//	int nWidth;
	//	int nHeight;
		stretchOptions.Count = 1;
		stretchOptions.BlendOn = PlayerOptions.Clean;
		if (ForceFit) stretchOptions.BlendOn=0;
		nWidth=PlayerOptions.Rotate?g_nHeight:g_nWidth;
		nHeight=PlayerOptions.Rotate?g_nWidth:g_nHeight;
		if (PlayerOptions.Rotate&&(nWidth%16)) nWidth-=nWidth%16;
		if (!ForceFit)
		{
			stretchOptions.ScaleXFactor = 16 * (nWidth<DisplayWidth?nWidth:DisplayWidth) / DisplayWidth;
			stretchOptions.ScaleYFactor = 16 * (nHeight<DisplayHeight?nHeight:DisplayHeight) / DisplayHeight;
		}
		else
		{
			stretchOptions.ScaleXFactor = 16 * (nWidth) / OvlWinProp.SrcPitch +1;
			stretchOptions.ScaleYFactor = 16 * (nHeight) / OvlWinProp.SrcHeight +1;
		}
		if (stretchOptions.ScaleXFactor==16) stretchOptions.ScaleXFactor = stretchOptions.ScaleYFactor;
		else if (stretchOptions.ScaleYFactor==16) stretchOptions.ScaleYFactor=stretchOptions.ScaleXFactor;
		if (stretchOptions.ScaleXFactor>31) 
			stretchOptions.ScaleXFactor=31;
		if (stretchOptions.ScaleYFactor>31)
			stretchOptions.ScaleYFactor=31;

		if ( stretchOptions.ScaleXFactor > stretchOptions.ScaleYFactor )
		{
			stretchOptions.ScaleYFactor = stretchOptions.ScaleXFactor;
		}
		else
		{
			stretchOptions.ScaleXFactor = stretchOptions.ScaleYFactor;
		}

	AtiCore_SetRopOperation( ROP3_SRCCOPY );
	AtiCore_SetDstType( DSTTYPE_8BPP );
	AtiCore_SetSrcType( SRCTYPE_EQU_DST );

}
/*

void SetupATIOverlay(int nWidth, int nHeight)
{
//	if (VH1) AtiCore_DestroySurface(VH1);
//	if (VH2) AtiCore_DestroySurface(VH2);
	if (!PlayerOptions.Double)
	{
		ATI_EXTENDEDOVERLAYPROP prop;
		OvlWinProp.SrcPitch =  nWidth<DisplayWidth?nWidth:DisplayWidth; 
		if (OvlWinProp.SrcPitch%16) OvlWinProp.SrcPitch+=16-(OvlWinProp.SrcPitch%16);

		if (PlayerOptions.Rotate)
		{
			prop.x.ExtVideoProp.HInvert=1;
			prop.x.ExtVideoProp.VInvert=1;
			prop.HExpansion=1;
			prop.VExpansion=1;
			prop.RConversion=0;
			OvlWinProp.SrcHeight = 320;
		}
		else
		{
			prop.x.ExtVideoProp.HInvert=0;
			prop.x.ExtVideoProp.VInvert=0;
			prop.HExpansion=1;
			prop.VExpansion=1;
			prop.RConversion=0;
			OvlWinProp.SrcHeight = nHeight;
		}
		OvlWinProp.XCoord = 0;
		OvlWinProp.YCoord = 0;

		OvlWinProp.lpOverlayKey = 0;
		OvlWinProp.OverlayFormat = OVLTYPE_YUV420;


		OvlWinProp.OverlayWidth = nWidth<DisplayWidth?nWidth:DisplayWidth; 
		OvlWinProp.OverlayHeight = nHeight;
		OvlWinProp.lpSrcBitmap = (U32*)VRAMoffset2;
		if ( AtiCore_SetupOverlay( OverlayHandle, &OvlWinProp ) != SUCCESS )
		{
			MessageBox(hWndMain,_T("Failed overlay"),_T(""),MB_OK);
		}
		AtiCore_SetupOverlayExtended(OverlayHandle,&prop);
		AtiCore_SetOverlayPos(OverlayHandle,sX,sY); 
	}
}
*/
#endif

void RecalculateDimensions(HWND hWnd)
{
#if (defined(MIPS)&&(defined(GAPI)))
		if (vidinfo)
		{
			if (vidinfo->video_frames)
			{
				GXCloseDisplay();
				GXOpenDisplay(hWnd, GX_FULLSCREEN);
			}
		}
#endif

	short nWidth=DrawWidth=g_nWidth;
	short nHeight=DrawHeight=g_nHeight;

	if (PlayerOptions.Rotate)
	{
		DrawWidth=nWidth=g_nHeight;
		DrawHeight=nHeight=g_nWidth;

	}
	bEnd=false;
	NeedHide=PlayerOptions.AlwaysHide;
	if (PlayerOptions.Double)
	{
		if ((nWidth<<1)>VisibleWidth) nWidth=VisibleWidth>>1;
		if ((nHeight<<1)>VisibleHeight) nHeight=VisibleHeight>>1;
		DrawWidth=nWidth<<1;
		DrawHeight=nHeight<<1;
	}
	else
	{

		if (nWidth>VisibleWidth) nWidth=VisibleWidth;
		if (nHeight>VisibleHeight) nHeight=VisibleHeight;		
		DrawWidth=nWidth;
		DrawHeight=nHeight;
	
	}
#ifdef IPAQ
	if (DrawWidth>PlayerSkin.ViewPort.height||((DrawHeight>PlayerSkin.ViewPort.width)&&(PlayerSkin.ViewPort.width<VisibleHeight)))
#else
	if (DrawHeight>PlayerSkin.ViewPort.height||((DrawWidth>PlayerSkin.ViewPort.width)&&(PlayerSkin.ViewPort.width<VisibleWidth)))
#endif
	{
#ifdef ATI
		if (!PlayerOptions.FitToViewPort||(PlayerOptions.Double))
		{
#endif
			sY=(VisibleHeight-DrawHeight)/2;
			sX=(VisibleWidth-DrawWidth)/2;
			if (DrawWidth>=VisibleWidth) sX=0;
			if (DrawHeight>=VisibleHeight) sY=0;
			NeedHide=true;
			if (!bPaused)
			{
				ShowControls(false);
			}
#ifdef ATI
		}
#endif
	}
	else
	{

#ifdef IPAQ
		if (!g_bInvert)
			sX=PlayerSkin.ViewPort.top+PlayerSkin.ViewPort.height-(PlayerSkin.ViewPort.height-DrawWidth)/2;
		else
			sX=PlayerSkin.ViewPort.top+(PlayerSkin.ViewPort.height-DrawWidth)/2;
		sY=PlayerSkin.ViewPort.left+(PlayerSkin.ViewPort.width-DrawHeight)/2;
		if (!g_bInvert) sX=VisibleWidth-sX-26;
		else sX+=26;
#else
		sY=PlayerSkin.ViewPort.top+(PlayerSkin.ViewPort.height-DrawHeight)/2;
		sX=PlayerSkin.ViewPort.left+(PlayerSkin.ViewPort.width-DrawWidth)/2;
#if (_WIN32_WCE >= 300 && !defined(HPC))
		sY+=26;
#endif
#endif
		if (sY<0) sY=0;
		if (sX<0) sX=0;
		if (sX%2) sX++;
		if (sY%2) sY++;
	}
#ifdef ATI
	if (nWidth&&(nHeight)) SetupATIOverlay(nWidth,nHeight);
#endif

#ifdef _USEVIDBUFF
	nExtra=DisplayWidth-nWidth;
	vbuffStart=(unsigned char*)(vbuff+(sY*DisplayWidth)+sX);
#else
#ifdef GAPI
	nExtra=DisplayWidth-nWidth;
#ifdef MIPS
	GXSetViewport( sY, DrawHeight, NULL, NULL );
#endif
#else
	nExtra=0;
	vbuffStart=(unsigned char*)outputBuffer;
#endif
#endif

	StartPos=((sY*DisplayWidth)+sX);

}

void ResetDisplay(HWND hWnd)
{
	if (!tot)
	{
		return;
	}
	short nWidth=g_nWidth;
	short nHeight=g_nHeight;
	int size,frame;
	int decoded=0;
	decBegin(2);
	do
	{
		unsigned char* rb=(unsigned char*)GetNextBuffer(&size,&frame,0);
		if (!rb)
		{
			continue;
		}
#ifdef IPAQ
		decoded=Decode(rb,frame,(unsigned char*) outputBuffer,2,-1,1);
#else
#ifdef ARM
		decoded=Decode(rb,frame,(unsigned char*) outputBuffer,2,-1,1);
#else
		decoded=Decode(rb,frame,(unsigned char*) outputBuffer,2,0);
#endif
#endif
		nCurrentFrame++;
	}while(!decoded);
	if (hb)
	{
		DeleteObject(hb);
		hb=NULL;
	}
#ifndef IPAQ
	if (PlayerOptions.Rotate)
#else
	if (!PlayerOptions.Rotate)
#endif

	{
		nWidth=g_nHeight;
		nHeight=g_nWidth;
	}
#ifndef IPAQ
	if (nWidth>VisibleWidth) nWidth=VisibleWidth;
	if (nHeight>VisibleHeight) nHeight=VisibleHeight;
#else
	if (nHeight>VisibleWidth) nHeight=VisibleWidth;
	if (nWidth>VisibleHeight) nWidth=VisibleHeight;
#endif
	hb=CreateBitmap(nWidth,nHeight,1,COLORDEPTH,outputBuffer);
	decBegin(-1);
	RefreshDisplay(false);
}


void OptionRefresh(HWND hWnd,bool* option)
{
	if (ptid&&(vidinfo->video_frames))
	{
		if (!bPaused)
		{
			Pause();
			if (option) *option=!*option;
			RecalculateDimensions(hWnd);	
			decBegin(2);
			decBegin(-1);
			Pause();
		}
		else
		{
			if (option) *option=!*option;
			RecalculateDimensions(hWnd);	
			ResetDisplay(hWnd);
#ifdef MIPS
			RefreshDisplay(true);
#endif
		}
	}
	else
	{
		if (option) *option=!*option;
	}
}



/*****************************************************************************************/
//Plugin Control Functions
/*****************************************************************************************/

int LoadDecoder()
{
	HKEY hKey = 0;
	DWORD dwSize = 0;
	DWORD dwType = 0;
	DWORD dwTmp;
	TCHAR temp[10];
	TCHAR value[200];
	int n=0;
	if (hdivx) FreeLibrary((HINSTANCE)hdivx);
	if (ha) FreeLibrary((HINSTANCE)ha);
	hdivx=NULL;
	ha=NULL;
	DropTwo=1;
	if (vidinfo->a_fmt>1)
	{
		RawAudio=false;
		if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_BASE_AUDIO, 0, 0, &hKey ) )
		{
			dwTmp = 0;
			wcscpy(temp,_T(""));
			dwSize =sizeof(value);
			TCHAR fmt[10];
			_itow(vidinfo->a_fmt,fmt,10);
			wcscat(temp,fmt);
			if ( ERROR_SUCCESS == RegQueryValueEx( hKey, temp, 0, &dwType, ( LPBYTE )value, &dwSize ) )
			{
				if (wcsicmp(value,_T("")))
				{
					ha=LoadLibrary(value);
					if (!ha)
					{
						return -1;
					}		
				}
				else
				{
					ha=NULL;
				}
			}
			else
			{
				MessageBox(hWndMain,_T("This file contains an incompatible audio format"),_T("Audio Error"),MB_OK);
				vidinfo->audio_bytes = 0;
//				return -1;
			}
			RegCloseKey( hKey );
		}
		else
		{
			MessageBox(hWndMain,_T("This file contains an incompatible audio format"),_T("Audio Error"),MB_OK);
			vidinfo->audio_bytes = 0;
		}
	}	
	else
	{
		RawAudio=true;
	}
	if (strcmp(vidinfo->compressor,""))
	{
		if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_BASE_VIDEO, 0, 0, &hKey ) )
		{
			dwTmp = 0;
			wcscpy(temp,_T(""));
			dwSize =sizeof(value);
			TCHAR hold[5];
			MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,vidinfo->compressor,-1,hold,5);
			wcslwr(hold);
			wcscat(temp,hold);
			if ( ERROR_SUCCESS == RegQueryValueEx( hKey, temp, 0, &dwType, ( LPBYTE )value, &dwSize ) )
			{
				if (wcsicmp(value,_T("")))
				{
					hdivx=LoadLibrary(value);
					if (!hdivx)
					{
						return -1;
					}		
					DecodeMessage=(pdecode_msg)GetProcAddress((HINSTANCE)hdivx,_T("DecodeInit"));
					DecodeFrame=(pdecode_frame)GetProcAddress((HINSTANCE)hdivx,_T("DecodeFrame"));
				}
				else
				{
					hdivx=NULL;
					DropTwo=0;
				}
			}
			else
			{
				MessageBox(hWndMain,_T("This file contains an incompatible video format 1"),_T("Video Error"),MB_OK);
				vidinfo->video_frames = 0;
			}
			RegCloseKey( hKey );
		}
		else
		{
				MessageBox(hWndMain,_T("This file contains an incompatible video format 2"),_T("Video Error"),MB_OK);
				vidinfo->video_frames = 0;
		}
	}	
	if (vidinfo->video_frames==0&&(vidinfo->audio_bytes==0))
		return -1;
	if (hdivx==NULL)
	{
		DecodeMessage=(pdecode_msg)dummy_decore; 
		DecodeFrame=(pdecode_frame)dummy_decore_frame;
	}

	return 0;
}
int LoadReader()
{
	static HANDLE hmp3=NULL;
	HKEY hKey = 0;
	DWORD dwSize = 0;
	DWORD dwType = 0;
	DWORD dwTmp;
	TCHAR temp[10];
	TCHAR value[200];


	NoIndex=0;
	if (hmp3)
	{
		FreeLibrary((HINSTANCE)hmp3);
		hmp3=NULL;
	}
	GetFileExt(FileName,temp);
	if (!wcscmp(FileName,_T("Broadcast")))
	{
		hmp3=LoadLibrary(_T("BroadcastReader.dll"));
	}
	else if (wcsstr(FileName,_T(".avi"))||(wcsstr(FileName,_T(".AVI")))||(wcsstr(FileName,_T(".divx"))||(wcsstr(FileName,_T(".DIVX")))))
	{
		if (Stream||(PlayerOptions.NoIndex))
		{
			hmp3=LoadLibrary(_T("avistream.dll"));
			NoIndex=1;
		}
		else
		{
			READER_InitializeReader=InitializeReader;
			READER_InitializeReader(&rd);
			return 0;
		}
	}
	else if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_BASE_FMT, 0, 0, &hKey ) )
	{
			dwTmp = 0;
			dwSize =sizeof(value);
			wcslwr(temp);
			if ( ERROR_SUCCESS == RegQueryValueEx( hKey, temp, 0, &dwType, ( LPBYTE )value, &dwSize ) )
			{
				if (wcsicmp(value,_T("")))
				{
					hmp3=LoadLibrary(value);
				}
				else
				{
					hmp3=NULL;
					RegCloseKey( hKey );
				}
			}
			else
			{
				MessageBox(hWndMain,_T("This file is of an unknown format"),_T("Video Error"),MB_OK);
				return -1;
			}
			RegCloseKey( hKey );
	}
	else
	{
			MessageBox(hWndMain,_T("This file is of an unknown format"),_T("Video Error"),MB_OK);
			return -1;
	}
	
	
	
	
	
	if (hmp3!=NULL)
	{
		READER_InitializeReader=(pInitializeReader) GetProcAddress((HINSTANCE)hmp3,_T("InitializeReader"));
		READER_InitializeReader(&rd);
		return 0;
	}
	else
	{
		LPVOID lpMsgBuf;
		FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),0,(LPTSTR) &lpMsgBuf, 0, NULL );
		MessageBox( NULL, (LPCTSTR)lpMsgBuf, _T("Error loading file reader"), MB_OK | MB_ICONINFORMATION );
		LocalFree( lpMsgBuf );
		return -1;
	}
}

/*****************************************************************************************/
//Player Control Functions
/*****************************************************************************************/


void StopFastForward()
{
	FastForward=!FastForward;
	tot=vidinfo->video_frames-vidinfo->video_pos;
	nCurrentFrame=0;
	baseTick=0;
	if (!NeedHide) DrawButtonUp(&PlayerSkin.FFWDButton);
	else
		PlayerSkin.FFWDButton.status=0;
	if (PlayerOptions.Audio&&(vidinfo->audio_bytes))
	{
		totAudio=rd.READER_ReSeekAudio();

		Exit();
		Init(PlayerOptions.EnableEQ,0);
#ifndef _X86_
		waveOutReset(m_hwo);
#endif
	}
}



void Pause()
{
	if (!bPaused)
	{
		bPaused=!bPaused;
		if (PlayerOptions.Audio) waveOutPause(m_hwo);
		while((nShouldbe)&&(nCurrentFrame<=nShouldbe+1)) Sleep(1);
		EnterCriticalSection(&cs);
		LeaveCriticalSection(&cs);
		//Sleep(500);
		if (!PlayerSkin.FFWDButton.status)
		{
			ResetDisplay(hWndMain);
			if (NeedHide) ShowControls(true);
		}
#if (_WIN32_WCE >= 300)
		if (PlayerOptions.KeepAlive) RegOptionBLTimeout( false );
#endif
	}
	else
	{
		lastshow=0;
		Display=2;
		if (!PlayerOptions.Audio||(vidinfo->audio_bytes<=0))
		{
			baseTick=MyGetTickCount();
			tot=tot-nCurrentFrame;
			nCurrentFrame=1;
		}
		totMsTime=(int)(((double)(tot*1000))/vidinfo->fps);
		if (PlayerOptions.Audio) waveOutRestart(m_hwo);
		bPaused=!bPaused;
#if (_WIN32_WCE >= 300)
		if (PlayerOptions.KeepAlive) RegOptionBLTimeout( true );

#endif
		if (NeedHide)
		{
			ShowControls(false);
		}

	}

}
void DrawInfoView(HDC hdc, bool scroll);
void ChangeView()
{
	if ((vidinfo)&&(!vidinfo->video_frames))	
	{
		if (MaxFile&&(PlayerOptions.Playlist)&&(PlayerOptions.Media))
		{
			RECT rc;
			ShowWindow(hwndID3,SW_SHOWNORMAL);
			ShowWindow(hwndList,SW_SHOWNORMAL);
			ListView_SetItemState(hwndList,CurrentFile,LVIS_SELECTED|LVIS_FOCUSED,0xFFFF);
			ListView_EnsureVisible( hwndList, CurrentFile, false );
			MoveWindow(hwndList,PlayerSkin.ViewPort.left , PlayerSkin.ViewPort.top, PlayerSkin.ViewPort.width, PlayerSkin.ViewPort.height/3,true);
			GetClientRect(hwndList,&rc);
			MoveWindow(hwndID3,PlayerSkin.ViewPort.left , PlayerSkin.ViewPort.top+rc.bottom+5, PlayerSkin.ViewPort.width, PlayerSkin.ViewPort.height-rc.bottom-5,true);
		}
		else if (MaxFile&&(PlayerOptions.Playlist))
		{
			ShowWindow(hwndID3,SW_HIDE);
			ShowWindow(hwndList,SW_SHOWNORMAL);
			ListView_SetItemState(hwndList,CurrentFile,LVIS_SELECTED|LVIS_FOCUSED,0xFFFF);
			ListView_EnsureVisible( hwndList, CurrentFile, false );
			MoveWindow(hwndList,PlayerSkin.ViewPort.left , PlayerSkin.ViewPort.top, PlayerSkin.ViewPort.width, PlayerSkin.ViewPort.height,true);
		}
		else if (PlayerOptions.Media)
		{
			ShowWindow(hwndList,SW_HIDE);
			ShowWindow(hwndID3,SW_SHOWNORMAL);
			MoveWindow(hwndID3,PlayerSkin.ViewPort.left , PlayerSkin.ViewPort.top, PlayerSkin.ViewPort.width, PlayerSkin.ViewPort.height,true);
		}
		else
		{
			ShowWindow(hwndList,SW_HIDE);
			ShowWindow(hwndID3,SW_HIDE);
			if (tot)
			{
				HBITMAP old;
				RECT rcView;
				HDC hdc=GetDC(hWndMain);
				rcView.left=PlayerSkin.ViewPort.left;
				rcView.top=PlayerSkin.ViewPort.top;
				rcView.right=PlayerSkin.ViewPort.width+PlayerSkin.ViewPort.left;
				rcView.bottom=PlayerSkin.ViewPort.height+PlayerSkin.ViewPort.top;
				old=(HBITMAP)SelectObject(compat,m_hBitBack);
				BitBlt(hdc,rcView.left,rcView.top+Y_ADJUST,rcView.right,rcView.bottom,compat,rcView.left,rcView.top,SRCCOPY);
				SelectObject(compat,old);
				ReleaseDC(hWndMain,hdc);

			}

		}
	}
	else
	{
		ShowWindow(hwndList,SW_HIDE);
		ShowWindow(hwndID3,SW_HIDE);
	}
}
void Reset(HWND hWnd, int StartPos)
{
start:
	HMENU hMenu;
	HDC hdc;
	static int inreset=0;
	if (inreset) return;
	inreset=1;
	int opentype=0;
	FastForward=false;
	DrawButtonUp(&PlayerSkin.PlayButton);
	if (!wcscmp(FileName,_T("")))
	{
		inreset=0;
		return;
	}
	NeedHide=false;
	ShowControls(true);
	EnableWindow(hwndCB,false);
	bStopRead=true;
	bPaused=false;
	while (rtid!=NULL)
	{
		Sleep(10);
	}

	hMenu=CommandBar_GetMenu(hwndCB,0);
	if (Chapters)
	{
		int i;
		for (i=0;i<vidinfo->ChapterCount;i++)
		{
			DeleteMenu(hMenu,IDM_CHAPTER1+i+1,MF_BYCOMMAND);
		//DeleteMenu(hMenu,IDM_CHAPTER1+2,MF_BYCOMMAND);
		}
		//DestroyMenu(Chapters);
		Chapters=false;
	}
	vidinfo=NULL;
	br=0;
	if (rd.READER_Close)
		rd.READER_Close();
	if (outputBuffer)
	{
		free(outputBuffer);
		outputBuffer=0;
	}
	if (Closing) return;
	if (LoadReader())
	{
		EnableWindow(hwndCB,true);
		goto done;
	}

	SendMessage(hWndMain,WM_USER+110,0,1);
	if (Stream)
	{
		opentype=1;
	}
	else
	{
		if (PlayerOptions.Cache)
			opentype=2;
		else
			opentype=0;
	}
	memset(vidinfo,sizeof(videoinfo),0);
	if (!rd.READER_Open(FileName, opentype==1?opentype:0,PlayerOptions.CacheSize,&vidinfo))
	{
		SendMessage(hWndMain,WM_USER+110,0,0);
		EnableWindow(hwndCB,true);
		if (MaxFile)
		{
			wcscat(FileName,_T("!!!"));
			RefreshDisplay(true);
			Sleep(5000);
			NextFile(1);
			goto start;
		}
		else
			MessageBox(hWndMain,_T("Failed to load file, Please check available memory."),_T("Load Error"),MB_OK);

		goto done;
	}
	if (opentype==2)
	{
		rd.READER_Close();
		rd.READER_Open(FileName, opentype,PlayerOptions.CacheSize,&vidinfo);
	}
	SendMessage(hWndMain,WM_USER+110,0,0);
	if (vidinfo->ChapterCount)
	{
		int i;
		int j=IDM_CHAPTER1;
		for (i=vidinfo->ChapterCount-1;i>=0;i--)
		{
			InsertMenu(hMenu,j,MF_BYCOMMAND|MF_STRING|MF_ENABLED,j+1,vidinfo->ChapterDisplay[i]);
			j++;
		}
		DrawMenuBar(hwndCB);
		Chapters=true;
	}
	if (!vidinfo->audio_bytes&&(!vidinfo->video_frames))
	{
		EnableWindow(hwndCB,true);
		return;
	}
	if (vidinfo->width>640||(vidinfo->height>480))
	{
		MessageBox(hWndMain,_T("File resolution is greater than supported by the player."),_T("Load Error"),MB_OK);
		EnableWindow(hwndCB,true);
		return;
	}
	if (hb)
	{
		DeleteObject(hb);
		hb=NULL;
	}
	hdc=GetDC(hWndMain);
	DrawInfoView(hdc,PlayerSkin.InfoView.scrolltext);
	ReleaseDC(hWndMain,hdc);
	if (LoadDecoder())
	{
		rd.READER_Close();
		if (LoadDecoder())
		{
			rd.READER_Close();
			goto done;
		}
		rd.READER_Open(FileName, opentype,PlayerOptions.CacheSize,&vidinfo);
	}
	g_nWidth=vidinfo->width;
	g_nHeight=vidinfo->height;
#if (!defined(_USEVIDBUFF)&&(!defined(GAPI)))
	outputBuffer = (char *) malloc(g_nHeight*g_nWidth*2*5);
	if (!outputBuffer)
	{
		MessageBox(hWndMain,_T("Could not allocate enough memory"),_T(""),MB_OK);
		EnableWindow(hwndCB,true);
		goto done;
	}
	memset(outputBuffer, 0, g_nHeight*g_nWidth*2*5);
	toBuff=outputBuffer+(g_nHeight*g_nWidth*2);
#else
	outputBuffer = (char *) malloc(g_nHeight*g_nWidth*2);
	if (!outputBuffer)
	{
		MessageBox(hWndMain,_T("Could not allocate enough memory"),_T(""),MB_OK);
		EnableWindow(hwndCB,true);
		goto done;
	}
	memset(outputBuffer, 0, g_nHeight*g_nWidth*2);
#endif

	ChangeView();
	tot=vidinfo->video_frames;
	wcscpy(ID3_Title,_T(""));
	wcscpy(ID3_Artist,_T(""));
	wcscpy(ID3_Album,_T(""));
	GetDisplayName();
	EnableWindow(hwndCB,true);
	wcscpy(PlayerOptions.LastFile,FileName);
	RecalculateDimensions(hWnd);
	bEnd=0;
	decBegin(0);
	hPlayThread=CreateThread(NULL,NULL,PlayThread,(void*)hWnd,NULL,&ptid);
#ifndef TESTMODE
	if (!bPlayNow)
	{
		Pause();
	}
	else
	{

#if (_WIN32_WCE >= 300)
		if (PlayerOptions.KeepAlive) RegOptionBLTimeout( true );
#endif
		DrawButtonDown(&PlayerSkin.PlayButton);
	}
	if (StartPos&&(vidinfo->video_frames)) SeekPos(StartPos,false,1);
#endif
done:
	inreset=0;
}


void Stop(HWND hWnd)
{
	if (bEnd) return;
	if (ptid||(rtid))
	{
		BOOL Flush=bPaused;
		bPaused=false;
		bEnd=1;
		ResetEvent(eventStopped);
		if (PlayerOptions.Audio&&(vidinfo->audio_bytes))
		{
#ifndef _X86_
			if (Flush) waveOutReset(m_hwo);
#endif
			SetEvent(eventAudio);
		}
		WaitForSingleObject(eventStopped,INFINITE); 
		ResetEvent(eventStopped);
	}
	else
	{
		Reset(hWnd,0);
	}

}

void SeekPos(int nPos, bool isChapter, int isFrame)
{
	if (!vidinfo) return;
	if (Stream) return;
	int bWasPaused=bPaused;
	if (nPos>=99&&(!isFrame)) nPos=99;
	nShouldbe=-99;
	bSkipChunk=true;
	if (!bPaused)
	{
		if( PlayerOptions.Audio&&(vidinfo->audio_bytes) )
		{
#ifndef _X86_
			waveOutReset(m_hwo);
			while(Written!=0) Sleep(10);
#endif
		}
		Pause();
	}
	
	if( PlayerOptions.Audio&&(vidinfo->audio_bytes) )
	{
		SeekStart();
	}
	if (!isChapter)
	{
		totAudio=rd.READER_Seek(nPos,isFrame);
	}
	else
	{
		totAudio=rd.READER_SeekChapter(nPos);
	}
	tot=vidinfo->video_frames-vidinfo->video_pos;
	nShouldbe=-99;
	nCurrentFrame=0;
	baseTick=0;
	if( PlayerOptions.Audio&&(vidinfo->audio_bytes) )
	{
		SeekEnd();
	}
	else
		baseTick=MyGetTickCount();
	bSkipChunk=true;

	if (!bWasPaused)
	{
		if( PlayerOptions.Audio&&(vidinfo->audio_bytes) )
		{
#ifndef _X86_
			waveOutReset(m_hwo);
			while(Written!=0) Sleep(10);
#endif
		}
		FirstChunk=1;
		Pause();
		FadeIn();
	}
	else
	{
		if( PlayerOptions.Audio&&(vidinfo->audio_bytes) )
		{
#ifndef _X86_
			waveOutReset(m_hwo);
			while(Written!=0) Sleep(10);
#endif
		}
		ResetDisplay(hWndMain);
	}
	Sleep(100);
	bSkipChunk=false;
	nShouldbe=-99;
}



void PlayFastForward(unsigned char* vbuffStart, int nExtra)
{
	int size;
	if (!tot) return;
	baseTick=MyGetTickCount();
	nShouldbe=0;
	size=rd.READER_NextVideoFrame((char*)temp,1);
#ifdef ARM
	Decode((unsigned char*)temp,size,vbuffStart ,0,nExtra,1);
#else
	Decode((unsigned char*)temp,size,vbuffStart ,0,nExtra);
#endif
	rd.READER_NextVideoFrame((char*)temp,1);
#ifdef ARM
	Decode((unsigned char*)temp,size,vbuffStart ,0,nExtra,1);
#else
	Decode((unsigned char*)temp,size,vbuffStart ,0,nExtra);
#endif
#ifdef GAPI
#if (defined (IPAQ))
		if (!amigo)
		{
			vbuff=(short *)0xAC050020;
		}
		else
		{
			vbuff=(short *)GXBeginDraw();
			vbuff++;
		}
#else
#if (defined(HPC)&&(defined(ARM)))
		vbuff = (short *)(0x82200000);
#else
#ifndef ATI
			vbuff=(short *)GXBeginDraw();
#endif
#endif
#endif
		vbuffStart=(unsigned char*)(vbuff+((sY*DisplayWidth)+sX));
#endif

	size=rd.READER_NextVideoFrame((char*)temp,0);
#ifdef ARM
	Decode((unsigned char*)temp,size,vbuffStart ,Display,nExtra,1);
#else
	Decode((unsigned char*)temp,size,vbuffStart ,Display,nExtra);
#endif

#ifdef GAPI		
#if (!defined(IPAQ))
#ifndef ATI
		GXEndDraw();
#endif
#else
	if (amigo)
		GXEndDraw();
#endif
#endif

	nCurrentFrame+=3;
}

void PauseEvent()
{
	if (ptid)
	{
		if (bPaused) DrawButtonDown(&PlayerSkin.PlayButton);
		else DrawButtonUp(&PlayerSkin.PlayButton);

		if (!FastForward)
			Pause();
		else
		{
			StopFastForward();
			Sleep(500);

			ShowControls(true);
			ResetDisplay(hWndMain);
		}
	}
}


double GetPos()
{
	if (vidinfo)
	{
		return rd.READER_GetProgress();
	}
	return 0;
}



/*****************************************************************************************/
//Playlist Functions
/*****************************************************************************************/

void Shuffle()
{
	_Files* temp;

	int NextFile;
	int n=0;
	for (n=0;n<=MaxFile;n++)
	{
		Files[n].PlayCount=0;
	}
	n=0;
	temp=(_Files*) malloc(sizeof(_Files)*(MaxFile+1));
	srand(GetTickCount());
	do{
		do{
			int rnd=rand();
			NextFile=(int)(((double)rnd/(double)RAND_MAX)*(((double)MaxFile+1)));
		}while(NextFile>MaxFile || (Files[NextFile].PlayCount));
		if (StartFile&&(NextFile==StartFile-1)) CurrentFile=n;
		wcscpy(temp[n].FileName,Files[NextFile].FileName);
		Files[NextFile].PlayCount=1;
		n++;
	}while(n<=MaxFile);

	PostMessage(hWndMain,WM_USER+401,0,0);
	for (n=0;n<=MaxFile;n++)
	{
		wcscpy(Files[n].FileName,temp[n].FileName);
	}
	free(temp);
}

void NextFile(int dir)
{
	CurrentFile+=dir;
	if (CurrentFile>(MaxFile)||(NeedShuffle))
	{
		CurrentFile=0;
		if (PlayerOptions.Shuffle)
			Shuffle();
	}
	else if (CurrentFile<0)
	{
		CurrentFile=MaxFile;
	}
	NeedShuffle=false;
	wcscpy(FileName,Files[CurrentFile].FileName);
	Stream=!wcsncmp(FileName,_T("http://"),7);
	bPlayNow=true;
}

void GetFileList(HWND hWnd,bool URL,bool Broadcast, int FileType)
{
	HKEY hKey = 0;
	DWORD dwSize = 0;
	DWORD dwType = 0;
	DWORD dwTmp;
	TCHAR value[200];
	
	TCHAR* temp;
#if (_WIN32_WCE >= 300 && !defined(HPC))
	SHFullScreen(hWndMain,4);
#endif
	if (Broadcast)
	{
		MaxFile=0;
		CurrentFile=0;
		Stream=URL;
		bPlayNow=PlayerOptions.PlayAtOpen;
		wcscpy(FileName,_T("Broadcast"));
		bPlayNow=true;
		Stop(hWnd);
#if (_WIN32_WCE >= 300 && !defined(HPC))
		SHFullScreen(hWndMain,8);
#endif
		return;
	}
	int NumFile=0;
	if (!FileType)
	{
		wcscpy(value,_T("*.divx,*.avi"));
		if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_BASE_FMT, 0, 0, &hKey ) )
		{
			dwTmp = 0;
			dwSize =sizeof(value);
			RegQueryValueEx( hKey, _T("SupportedExtensions"), 0, &dwType, ( LPBYTE )value, &dwSize );
		}
		NumFile=fnGetFileName(hWndMain,value, NULL, szFile, 200,&temp,PlayerOptions.ControlSelectKey,URL);
	}
	else if (FileType==1)
	{
		TCHAR path[200];
		HANDLE h=GetModuleHandle(_T("PocketMVP.exe"));
		GetModuleFileName((HMODULE)h,path,200);
		LPTSTR t=wcsstr(path,_T("PocketMVP."));
		*t=0;
		wcscat(path,_T("Skins\\"));
		wcscpy(value,_T("*.pds"));
		NumFile=fnGetFileName(hWndMain,value, path,szFile, 200,&temp,PlayerOptions.ControlSelectKey,URL);
	}
	else
	{
		//TCHAR path[200];
		//HANDLE h=GetModuleHandle(_T("PocketMVP.exe"));
		//GetModuleFileName((HMODULE)h,path,200);
		//LPTSTR t=wcsstr(path,_T("PocketMVP."));
		//*t=0;
		//wcscat(path,_T("playlists\\"));
		wcscpy(value,_T("*.pdl"));
		NumFile=fnGetFileName(hWndMain,value,  NULL,szFile, 200,&temp,PlayerOptions.ControlSelectKey,URL);
	}
	if (NumFile)
	{
		wcscpy(PDLFile,_T(""));
		if (wcsstr(szFile,_T(".pds")))
		{
			LoadSkin(szFile,hWnd);
			RecalculateDimensions(hWnd);	
			RefreshDisplay(true);
			ChangeView();
			return;
		}
		MaxFile=0;
		CurrentFile=0;
		Stream=URL;
		bPlayNow=PlayerOptions.PlayAtOpen;
		if (Files) free(Files);
		Files=0;
		if (wcsstr(szFile,_T(".pdl"))||(NumFile>1))
		{
			int size=100000;
			if (wcsstr(szFile,_T(".pdl")))
			{
				unsigned long t;
				wcscpy(PDLFile,szFile);
				HANDLE h=CreateFile((LPCTSTR)szFile,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
				size=GetFileSize(h,NULL);
				temp=(TCHAR*)malloc(size);
				ReadFile(h,temp,size,&t,NULL);
				CloseHandle(h);
			}
			TCHAR* EndPos;
			TCHAR* BeginPos=temp;
			Files=(_Files*) malloc(sizeof(_Files)*100);
			if (PlayerOptions.Playlist) ListView_DeleteAllItems(hwndList);
			while(BeginPos<(temp+size) &&((EndPos=wcsstr(BeginPos,_T("\r")))!=NULL))
			{
				*EndPos=0;
				wcscpy(Files[MaxFile].FileName,BeginPos);
				AddEntry(Files[MaxFile].FileName,-1);
				BeginPos=EndPos+2;
				MaxFile++;
				if (MaxFile%100>0) Files=(_Files*) realloc(Files,sizeof(_Files)*(MaxFile+100));
			}
			MaxFile--;
			CurrentFile=MaxFile;
			NextFile(1);
			bPlayNow=PlayerOptions.PlayAtOpen;
			if (wcsstr(szFile,_T(".pdl"))) free(temp);
			wcscpy(FileName,Files[CurrentFile].FileName);
		}
		else
		{
			wcscpy(FileName,szFile);
		}
		Stream=!wcsncmp(FileName,_T("http://"),7);
		Stop(hWnd);
#if (_WIN32_WCE >= 300 && !defined(HPC))
		SHFullScreen(hWndMain,8);
#endif
	}
}



#ifndef _USEVIDBUFF
#ifndef GAPI
static void GDIDrawFrame(HWND hWnd,unsigned char* vbuffStart,int sX, int sY, int nWidth,int nHeight)
{
	HBITMAP old;
	RECT rc;
	HDC hdc=GetDC(hWnd);
	DeleteObject(hb);
		GetWindowRect(hWndMain,&rc);
		hb=CreateBitmap(DrawWidth,DrawHeight,1,COLORDEPTH,vbuffStart);

		old=(HBITMAP)SelectObject(compat,hb);
#if _WIN32_WCE >= 300
#ifdef IPAQ
		BitBlt(hdc,sY,sX-rc.top,DrawWidth,DrawHeight,compat,0,0,SRCCOPY);
#else
		BitBlt(hdc,sX,sY-rc.top,DrawWidth,DrawHeight,compat,0,0,SRCCOPY);
#endif
#else
		BitBlt(hdc,sX,sY,DrawWidth,DrawHeight,compat,0,0,SRCCOPY);
#endif
	SelectObject(compat,old);
	ReleaseDC(hWnd,hdc);
}

#endif
#endif




typedef void(CALLBACK* pSetShouldBe)();
pSetShouldBe SetShouldBe;

void SetShouldBeNoAudio()
{
	if (!bPaused)
	{
		nShouldbe=(int)((((__int64)tot*(__int64)(MyGetTickCount()-baseTick))/totMsTime)+1);
		//nShouldbe=nCurrentFrame;
	}
}

void SetShouldBeAudio()
{
}

void SetShouldBeBroadcast()
{
	if (!bPaused) nShouldbe=nCurrentFrame;
	else nShouldbe=-99;
}

#ifdef TESTMODE

int StartTime;
int EndTime;
int max;
#ifdef DECODE_AUDIO

DWORD WINAPI PlayThread(LPVOID lpParameter)
{
	/*
	 * Init everything
	 */
	int t=MyGetTickCount();
	HWND hWnd=(HWND)lpParameter;
	HANDLE hAudioThread;
	int refresh,frame;
	unsigned char* rb;
	HANDLE eventStopped=CreateEvent(NULL,true,false,_T("eventStopped"));
	HANDLE eventAudioStopped=CreateEvent(NULL,true,false,_T("eventAudioStopped"));
	HANDLE eventAudio=CreateEvent(NULL,true,true,_T("eventAudio"));
	HANDLE eventNextFrame=CreateEvent(NULL,true,false,_T("eventNextFrame"));
	nCurrentFrame=0;
	nShouldbe=-99;

	totMsTime=(int)(((double)(tot*1000))/vidinfo->fps);
	SetShouldBe=SetShouldBeAudio;
	//hAudioThread=CreateThread(NULL,NULL,AudioThread,(void*) bPlayNow,0,&tid);//,THREAD_PRIORITY_ABOVE_NORMAL);
	StartTime=MyGetTickCount();
	max=0;
	AudioThread((void*)1);
	short FrameDiff;
	EndReached=false;
	bPlayNow=false;
	Display=2;


	if (tot)
	{
		if (nCurrentFrame>=tot) EndReached=true;
		bStopRead=1;
		bEnd=1;
		if (PlayerOptions.Audio&&(vidinfo->audio_bytes)) SetEvent(eventAudio);
	}
	WaitForSingleObject(eventAudioStopped,INFINITE);
	ResetEvent(eventAudioStopped);
	if (!Closing)
	{
			EndTime=MyGetTickCount()-StartTime;
			bStopRead=1;
			bEnd=1;
			TCHAR dropped[20],total[20];
			_itow(EndTime,dropped,10);
			wcscat(dropped,_T("/"));
			wcscat(dropped,_itow(vidinfo->video_frames,total,10));

			MessageBox(hWnd,dropped,_T("Dropped frames"),MB_OK);
			wcscpy(FileName,_T(""));
	}
	nDrop=0;

	decEnd();
	ptid=NULL;
	SetEvent(eventStopped);
	Reset(hWnd,0);
	CloseHandle(eventStopped);
	CloseHandle(eventAudioStopped);
	CloseHandle(eventAudio);
	CloseHandle(eventNextFrame);
	ShowControls(true);
	return 0;
}
#else
#if defined(DECODE_VIDEO_DISPLAY)||(defined(DECODE_VIDEO))
DWORD WINAPI PlayThread(LPVOID lpParameter)
{
	/*
	 * Init everything
	 */
	HWND hWnd=(HWND)lpParameter;
	HCURSOR oldcursor;
	int t=MyGetTickCount();
	int refresh,frame;
	unsigned char* rb;
	HANDLE eventStopped=CreateEvent(NULL,true,false,_T("eventStopped"));
	HANDLE eventAudioStopped=CreateEvent(NULL,true,false,_T("eventAudioStopped"));
	HANDLE eventAudio=CreateEvent(NULL,true,true,_T("eventAudio"));
	HANDLE eventNextFrame=CreateEvent(NULL,true,false,_T("eventNextFrame"));
	nCurrentFrame=0;
	nShouldbe=-99;
	EndReached=false;
	bPlayNow=false;
#ifdef DECODE_VIDEO_DISPLAY
	int showvid=2;
#else
	int showvid=0;
	oldcursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
#endif
	StartTime=MyGetTickCount();
	bPaused=false;


	for (nCurrentFrame=1;nCurrentFrame<=tot&&(!bEnd);nCurrentFrame++)
		{

				rb=GetNextBuffer(&refresh,&frame,0);
				if (!rb) continue;

#ifdef GAPI
#if (defined (IPAQ))
				if (!amigo)
				{
					vbuff=(short *)0xAC050020;
				}
				else
				{
					vbuff=(short *)GXBeginDraw();
					vbuff++;
				}

#else
#if (defined(HPC)&&(defined(ARM)))
				vbuff = (short *)(0x82200000);
#else
#ifndef ATI
					vbuff=(short *)GXBeginDraw();
#endif
#endif
#endif
				vbuffStart=(unsigned char*)(vbuff+StartPos);//*2;
#endif

				
#ifdef ARM
				Decode(rb,frame,(unsigned char*)vbuffStart ,showvid,nExtra,refresh);
#else
				Decode(rb,frame,vbuffStart ,showvid,nExtra);
#endif

#ifdef GAPI
#if (!defined(IPAQ))
#ifndef ATI
					GXEndDraw();
#endif
#else
				if (amigo);
					GXEndDraw();
#endif
#endif
				
#ifndef _USEVIDBUFF
#ifndef GAPI
				GDIDrawFrame(hWnd,vbuffStart,sX,sY,g_nWidth,g_nHeight);
#endif
#endif
		}
#ifndef DECODE_VIDEO_DISPLAY
		SetCursor(oldcursor);
#endif

#ifdef ATI
		AtiCore_SetOverlayOnOff(OverlayHandle,0);
#endif
		if (!Closing)
		{
			EndTime=MyGetTickCount()-StartTime;
			bStopRead=1;
			bEnd=1;
			TCHAR dropped[20],total[20];
			_itow(EndTime,dropped,10);
			wcscat(dropped,_T("/"));
			wcscat(dropped,_itow(vidinfo->video_frames,total,10));
			MessageBox(hWnd,dropped,_T("Dropped frames"),MB_OK);
			wcscpy(FileName,_T(""));
		}
	decEnd();
	ptid=NULL;
	SetEvent(eventStopped);
	Reset(hWnd,0);
	CloseHandle(eventStopped);
	CloseHandle(eventAudioStopped);
	CloseHandle(eventAudio);
	CloseHandle(eventNextFrame);
	ShowControls(true);
	return 0;
}
#endif
#endif

#else

DWORD WINAPI PlayThread(LPVOID lpParameter)
{
	/*
	 * Init everything
	 */
	HWND hWnd=(HWND)lpParameter;
	int t=MyGetTickCount();
	HANDLE hAudioThread;
	int refresh,frame;
	unsigned char* rb;
	HANDLE eventStopped=CreateEvent(NULL,true,false,_T("eventStopped"));
	HANDLE eventAudioStopped=CreateEvent(NULL,true,false,_T("eventAudioStopped"));
	HANDLE eventAudio=CreateEvent(NULL,true,true,_T("eventAudio"));
	HANDLE eventNextFrame=CreateEvent(NULL,true,false,_T("eventNextFrame"));
	nCurrentFrame=0;
	nShouldbe=-99;

	totMsTime=(int)(((double)(tot*1000))/vidinfo->fps);
	if (PlayerOptions.Audio&&(vidinfo->audio_bytes>0))
	{ 
		ResetEvent(eventNextFrame);
		SetShouldBe=SetShouldBeAudio;
		hAudioThread=CreateThread(NULL,NULL,AudioThread,(void*) bPlayNow,0,&tid);//,THREAD_PRIORITY_ABOVE_NORMAL);
		WaitForSingleObject(eventNextFrame,INFINITE);
		ResetEvent(eventNextFrame);
	}
	else
	{
		baseTick=MyGetTickCount();
		SetShouldBe=SetShouldBeNoAudio;
	}
	FadeIn();
	if (vidinfo->AFAP)
	{
		SetShouldBe=SetShouldBeBroadcast;
	}
	short FrameDiff;
	EndReached=false;
	bPlayNow=false;
	Display=2;
		for (nCurrentFrame=1;vidinfo->video_pos<vidinfo->video_frames&&(!bEnd);nCurrentFrame++)
		{
			SetShouldBe();
			FrameDiff=nShouldbe-nCurrentFrame;
			//if ((!FastForward)&&(nShouldbe>=0)&&(!bPaused||(FrameDiff>=0))&&(FrameDiff<PlayerOptions.DropTolerance)) 
			if (FrameDiff>-2&&(FrameDiff<PlayerOptions.DropTolerance)) 
			{
				rb=GetNextBuffer(&refresh,&frame,(FrameDiff>0)?2:0);
				if (!rb)
				{
					nDrop++;
					continue;
				}
#ifdef GAPI
#if (defined (IPAQ))
				if (!amigo)
				{
					vbuff=(short *)0xAC050020;
				}
				else
				{
					vbuff=(short *)GXBeginDraw();
					vbuff++;
				}

#else
#if (defined(HPC)&&(defined(ARM)))
				vbuff = (short *)(0x82200000);
#else
#ifndef ATI
				vbuff=(short *)GXBeginDraw();
#endif
#endif
#endif
				vbuffStart=(unsigned char*)(vbuff+StartPos);//*2;
#endif
				if (!bPaused&&(Display))
#ifdef ARM
					Decode(rb,frame,vbuffStart ,(FrameDiff>0)?1:Display,nExtra,refresh);
#else
					Decode(rb,frame,vbuffStart ,(FrameDiff>0)?1:Display,nExtra);
#endif
				
				else
#ifdef ARM
					Decode(rb,frame,vbuffStart ,0,0,refresh);
#else
					Decode(rb,frame,vbuffStart ,0,0);
#endif

#ifdef GAPI
#if (!defined(IPAQ))
#ifndef ATI
				GXEndDraw();
#endif
#else
				if (amigo)
					GXEndDraw();
#endif
#endif
				
#ifndef _USEVIDBUFF
#ifndef GAPI
				GDIDrawFrame(hWnd,vbuffStart,sX,sY,g_nWidth,g_nHeight);
#endif
#endif
			}
			else if (FrameDiff>0)
			{
				DropFrames();
				nCurrentFrame++;

			}
			else //if (nCurrentFrame>nShouldbe)
			{
				if (FastForward)
				{
					PlayFastForward(vbuffStart,nExtra);
					Sleep(0);
				}
				else if (PlayerOptions.Audio&&(vidinfo->audio_bytes))
				{
					WaitForSingleObject(eventNextFrame,500);
					ResetEvent(eventNextFrame);
				}
				else
				{
					Sleep(0);
				}
				nCurrentFrame--;
			}
		}
	if (FastForward)
	{
		FastForward=false;
		ShowControls(true);
	}
	if (tot)
	{
		if (nCurrentFrame>=tot) EndReached=true;
		bStopRead=1;
		bEnd=1;
		if (PlayerOptions.Audio&&(vidinfo->audio_bytes)) SetEvent(eventAudio);
	}
	if (PlayerOptions.Audio&&(vidinfo->audio_bytes))
	{
		WaitForSingleObject(eventAudioStopped,INFINITE);
	}

	if (EndReached)
	{
		if (MaxFile)
		{
			if (MaxFile>CurrentFile||(PlayerOptions.Repeat))
				NextFile(Dir);
			Dir=1;
		}
		else if (PlayerOptions.Repeat)
		{
			bPlayNow=true;
		}
	}
	
	ResetEvent(eventAudioStopped);
#ifdef ATI
	AtiCore_SetOverlayOnOff(OverlayHandle,0);
#endif
	if (PlayerOptions.ShowDropped&&(tot)&&(!Closing))
	{
		TCHAR dropped[200];//,total[20];
		wsprintf(dropped,_T("Dropped: %d\r\nPlayed: %d\r\nTotal: %d\r\nAvg FPS: %.2f"),nDrop,vidinfo->video_pos,vidinfo->video_frames,(float)((float)(vidinfo->video_pos+1-nDrop)/(float)(vidinfo->video_pos+1))*vidinfo->fps);
#ifdef ATI
		if (PlayerOptions.Double)
		{
			U32 regdata;
			AtiCore_SetupMemoryTransfer((U32)OvlWinProp.lpSrcBitmap,&regdata);
			memset((void*)regdata,0,DisplayWidth*DisplayHeight);
			memset((void*)(regdata+(DisplayWidth*DisplayHeight)),0,DisplayWidth*DisplayHeight*3/2);
			AtiCore_TerminateMemoryTransfer();
		}
#endif
		MessageBox(hWnd,dropped,_T("Playback Statistics"),MB_OK);
	}
	nDrop=0;

	decEnd();
	ptid=NULL;
	SetEvent(eventStopped);
	Reset(hWnd,0);
	CloseHandle(eventStopped);
	CloseHandle(eventAudioStopped);
	CloseHandle(eventAudio);
	CloseHandle(eventNextFrame);
	if (wcscmp(lpTempSkin,_T("")))
			SendMessage(hWndMain,WM_COMMAND,IDM_FILE_EXIT,NULL);

	return 0;
}
#endif

/************************************************************************************************/
//Main Windows Interface
/************************************************************************************************/

int WINAPI WinMain(	HINSTANCE hInstance,
					HINSTANCE hPrevInstance,
					LPWSTR    lpCmdLine,
					int       nCmdShow)
{
	MSG msg;
	HANDLE ha=NULL;
  	wcscpy(FileName,_T(""));
	GetDisplayName();
	if (lpCmdLine)
	{
		MaxFile=0;
		CurrentFile=0;
		TCHAR* temp;
		int size=100000;
		StartFile=0;
		if (wcsstr(lpCmdLine,_T("-ts")))
		{
			TCHAR* begin=wcsstr(lpCmdLine,_T("-ts"))+3;
			TCHAR* end=wcsstr(lpCmdLine,_T(".pds"))+4;
			wcsncpy(lpTempSkin,begin,(end-begin));
			lpTempSkin[(end-begin)]=0;
			wcscpy(PDLFile,_T(""));
			if (wcscmp(end,_T("")))
				wcscpy(FileName,end+1);
		}
		else if (wcsstr(lpCmdLine,_T(".pdl")))
		{
			unsigned long t;
			TCHAR file[200];
			wcscpy(file,lpCmdLine);
			wcscpy(PDLFile,lpCmdLine);
			if (wcsstr(lpCmdLine,_T(".pdl"))[4]==_T(' '))
			{
				StartFile=_wtoi(wcsstr(lpCmdLine,_T(".pdl"))+5)+1;
				wcsstr(file,_T(".pdl"))[4]=0;
			}
			HANDLE h=CreateFile((LPCTSTR)file,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
			size=GetFileSize(h,NULL);
			temp=(TCHAR*)malloc(size);
			ReadFile(h,temp,size,&t,NULL);
			CloseHandle(h);
			TCHAR* EndPos;
			TCHAR* BeginPos=temp;
			Files=(_Files*)malloc(sizeof(_Files)*100);
			if (PlayerOptions.Playlist) ListView_DeleteAllItems(hwndList);
			while(BeginPos<(temp+size) &&((EndPos=wcsstr(BeginPos,_T("\r")))!=NULL))
			{
				*EndPos=0;
				wcscpy(Files[MaxFile].FileName,BeginPos);
				BeginPos=EndPos+2;
				MaxFile++;
				if (!(MaxFile%100)) Files=(_Files*) realloc(Files,sizeof(_Files)*(MaxFile+100));
			}
			MaxFile--;
			if (wcsstr(szFile,_T(".pdl"))) free(temp);
			wcscpy(FileName,file);
		}
		else
		{
			wcscpy(PDLFile,_T(""));
			wcscpy(FileName,lpCmdLine);
		}
		Stream=!wcsncmp(FileName,_T("http://"),7);
	}
	// Perform application initialization:
	
	PlayerOptions.Audio=true;
#if (_WIN32_WCE >= 300 && !defined(HPC))
	ha=LoadLibrary(_T("aygshell.dll"));
	if (ha!=NULL)
	{
		SHFullScreen=(paygshell_SHFullScreen)GetProcAddress((HINSTANCE)ha,_T("SHFullScreen"));
	}
	else
	{
		return 1;
	}
#endif
	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}
	
	while (GetMessage(&msg, NULL, 0, 0)) 
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

//
//  FUNCTION: InitInstance(HANDLE, int)
//
//  PURPOSE: Saves instance handle and creates main window
//
//  COMMENTS:
//
//    In this function, we save the instance handle in a global variable and
//    create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	
	hInst = hInstance;
	LoadOptions(&PlayerOptions);
	PlayerOptions.Mute=false;
	hWndMain=ExternalInit(0, hInstance, nCmdShow, &PlayerOptions, &hwndCB,WndProc,ToolTips);
	RefreshDisplay(true);
#ifdef ATI
	{
		HMENU hMenu=CommandBar_GetMenu(hwndCB,0);

		EnableMenuItem(hMenu,IDM_FITTOVIEW,MF_BYCOMMAND|MF_ENABLED);
	}
#endif
	if (hWndMain)
	{
		return TRUE;
	}
	else
		return FALSE;
}

void Config()
{
	int t=0;
	if (!bPaused&&(hPlayThread)&&(tot)) Pause();
	Configure(0,hInst,hWndMain,&PlayerOptions);
}

void Equalizer()
{
	int t=0;
	if (!bPaused&&(hPlayThread)&&(tot)) Pause();
	Equalizer(0,hInst,hWndMain,&PlayerOptions);
	if (Init)
	{
		Init(PlayerOptions.EnableEQ,PlayerOptions.Eq);
	}
}

#ifdef ATI
int InitializeATI()
{
	if (VH1) return 0;
	if (AtiCore_ProcessAttach() != SUCCESS)
	{
		MessageBox(hWndMain,_T("AtiCore attach failed"),_T(""),MB_OK);
		return 1;
	}
	if ( AtiCore_AllocOverlay(&OverlayHandle) != SUCCESS )
	{
		MessageBox(hWndMain,_T("AtiCore AllocOverlay failed"),_T(""),MB_OK);
		return 1;
	}
	int i;
	i=AtiCore_AllocateSurface( &VH2, &VRAMoffset2, ((320) * 240 * 3/2), 0 );
	if (!i) MessageBox(hWndMain,_T("No1"),_T(""),MB_OK);
	i=AtiCore_AllocateSurface( &VH1, &VRAMoffset, (320) * 240, 0 );
	if (!i) MessageBox(hWndMain,_T("No2"),_T(""),MB_OK);
	AtiCore_SetRopOperation( ROP3_SRCCOPY );
	AtiCore_SetDstType( DSTTYPE_8BPP );
	AtiCore_SetSrcType( SRCTYPE_EQU_DST );
	return 0;
}
#endif



void ToggleMute()
{
	if (PlayerOptions.Mute)
	{
		waveOutSetVolume( 0, (unsigned long)0  );				
	}
	else
	{
		int nPos;
		if (PlayerSkin.VolSlider.rotated)
		{
			nPos=((PlayerSkin.VolButton.top-PlayerSkin.VolSlider.top)*PlayerSkin.VolButton.step*100)/(PlayerSkin.VolSlider.height-PlayerSkin.VolButton.height);
		}
		else
		{
			nPos=((PlayerSkin.VolButton.left-PlayerSkin.VolSlider.left)*PlayerSkin.VolButton.step*100)/(PlayerSkin.VolSlider.width-PlayerSkin.VolButton.width);
		}
		if (nPos<0) nPos=0;
		if (nPos>100) nPos=100;
		waveOutSetVolume( 0, (0xffff*nPos)/100+(0xffff*nPos)/100*0x10000  );
	}
}

void ToggleMenu(DWORD wmId,bool* value)
{
	HMENU hMenu=CommandBar_GetMenu(hwndCB,0);
	*value=!(*value);
	if (*value)
	{
		CheckMenuItem(hMenu,wmId,MF_CHECKED);
	}
	else
	{
		CheckMenuItem(hMenu,wmId,MF_UNCHECKED);
	}
}

void GetDisplayName()
{
	TCHAR temp[200];
	TCHAR rt[20];
	TCHAR * token;;
	if (!wcscmp(ID3_Title,_T("")))
	{
		wcscpy(DisplayName,FileName);				
		wcscpy(temp,FileName);				
		token = wcstok( temp,  _T("\\"));
		while( token != NULL )
		{
		  wcscpy(DisplayName,token);
		  token = wcstok( NULL, _T("\\") );

		}
	}
	else
	{
		if (wcscmp(ID3_Artist,_T("")))
		{
			wcscpy(DisplayName, ID3_Artist);
			wcscat(DisplayName,_T(" - "));
			wcscat(DisplayName,ID3_Title);
		}
		else
			wcscpy(DisplayName,ID3_Title);
	}
	if (!wcscmp(DisplayName,_T(""))) wcscpy(DisplayName,_T("(No File)"));
	wcscpy(temp,DisplayName);

	if(vidinfo)
	{
		int h=0,m=0,s=0;
		wcscpy(rt,_T(""));
		wcscat(temp,_T(" ("));
		if (vidinfo->video_frames)
		{
			s=(int) (vidinfo->video_frames/vidinfo->fps);
		}
		else if (vidinfo->audio_bytes&(br))
		{
			s=vidinfo->audio_bytes/(abs(br)/8);
		}
		h=s/3600;
		m=(s-h*3600)/60;
		s=s-(h*3600+m*60);
		if (h)
		{
			_itow(h,rt,10);
			wcscat(rt,_T(":"));
		}
		if (m<10) wcscat(rt,_T("0"));
		_itow(m,rt+wcslen(rt),10);
		wcscat(rt,_T(":"));
		if (s<10) wcscat(rt,_T("0"));
		_itow(s,rt+wcslen(rt),10);
		wcscat(temp,rt);
		wcscat(temp,_T(")"));
		
	}
	wcscpy(DisplayName,_T(" "));
	wcscat(DisplayName,temp);
	wcscat(DisplayName,_T(" "));
	HDC hdc=GetDC(hWndMain);
	DrawInfoView(hdc,0);
	ReleaseDC(hWndMain,hdc);
	if (vidinfo&&(br))
	{
		TCHAR name[200];
		int abr=abs(br);
		ListView_DeleteAllItems(hwndID3);		
		wcscpy(name,_T("TITLE="));
		wcscat(name,ID3_Title);
		AddTextEntry(name,-1);
		wcscpy(name,_T("ARTIST="));
		wcscat(name,ID3_Artist);
		AddTextEntry(name,-1);
		wcscpy(name,_T("ALBUM="));
		wcscat(name,ID3_Album);
		AddTextEntry(name,-1);

		wcscpy(name,_T("RUNNING TIME="));
		wcscat(name,rt);
		AddTextEntry(name,-1);

		wcscpy(name,_T("BITRATE="));
		_itow(abr/1000,name+8,10);
		wcscat(name,_T("Kbps"));
		AddTextEntry(name,-1);
		
		wcscpy(name,_T("SAMPLE RATE="));
		_itow(vidinfo->a_rate/1000,name+12,10);
		wcscat(name,_T("khz"));
		AddTextEntry(name,-1);

		wcscpy(name,_T("MONO"));
		if (vidinfo->a_chans>1)
		{
			wcscpy(name,_T("STEREO"));
		}
		AddTextEntry(name,-1);
	}

}

void DrawTime(HDC hdc)
{
	TCHAR temp[20];
	RECT rc;
	int textsize=0;
	if(vidinfo)
	{
		int h=0,m=0,s=0;
		wcscpy(temp,_T(""));
		if (vidinfo->video_frames)
		{
			s=(int) (vidinfo->video_pos/vidinfo->fps);
		}
		else if (vidinfo->audio_bytes&(br))
		{
			s=(GetPos()*(double)vidinfo->audio_bytes)/100;
			s=s/(abs(br)/8);
			//s=vidinfo->audio_bytes/(abs(br)/8);
		}
		h=s/3600;
		m=(s-h*3600)/60;
		s=s-(h*3600+m*60);
		if (h)
		{
			_itow(h,temp+wcslen(temp),10);
			wcscat(temp,_T(":"));
		}
		if (m<10) wcscat(temp,_T("0"));
		_itow(m,temp+wcslen(temp),10);
		wcscat(temp,_T(":"));
		if (s<10) wcscat(temp,_T("0"));
		_itow(s,temp+wcslen(temp),10);
		

		//if (PlayerSkin.InfoView.scrolltext)
		LOGFONT lf;
		memset(&lf,0,sizeof(LOGFONT));

		lf.lfWeight=FW_NORMAL;
		if (PlayerSkin.Time.point)
		{
			wcscpy(lf.lfFaceName,PlayerSkin.InfoView.font);
			__int64 t=(__int64)GetDeviceCaps(hdc, LOGPIXELSY)*(__int64)PlayerSkin.InfoView.point/(__int64)72;
			lf.lfHeight = (long)t;
		}
		else
		{
			wcscpy(lf.lfFaceName,_T("Tahoma"));
			__int64 t=(__int64)GetDeviceCaps(hdc, LOGPIXELSY)*(__int64)9/(__int64)72;
			lf.lfHeight = (long)t;
		}
		HFONT hf=CreateFontIndirect(&lf);
		if (PlayerSkin.Time.FontRed!=0||(PlayerSkin.Time.FontBlue!=0)||(PlayerSkin.Time.FontGreen!=0))
		{
			SetTextColor(hdc,RGB(PlayerSkin.Time.FontRed,PlayerSkin.Time.FontGreen,PlayerSkin.Time.FontBlue));
		}

		if (PlayerSkin.Time.BackRed!=0||(PlayerSkin.Time.BackBlue!=0)||(PlayerSkin.Time.BackGreen!=0)) 
		{ 
			SetBkMode(hdc, OPAQUE); 
			SetBkColor(hdc,RGB(PlayerSkin.Time.BackRed,PlayerSkin.Time.BackGreen,PlayerSkin.Time.BackBlue)); 
		} 
		else 
		{ 
			SetBkMode(hdc, TRANSPARENT); 
		} 	
		
		HFONT of=(HFONT)SelectObject(hdc,hf);
		rc.left=PlayerSkin.Time.left;
		rc.right=PlayerSkin.Time.width+rc.left;
		rc.top=PlayerSkin.Time.top;
		rc.bottom=PlayerSkin.Time.height+rc.top;
		DrawButtonUp(&PlayerSkin.Time);
		DrawText(hdc,temp,wcslen(temp),&rc,DT_RIGHT|DT_SINGLELINE);
		SelectObject(hdc,of);
		DeleteObject(hf);
	}

}

void DrawInfoView(HDC hdc, bool scroll)
{
	RECT rc;
	SIZE sz;
	static start=0;
	int textsize=0;
	//if (PlayerSkin.InfoView.scrolltext)
	DrawButtonUp(&PlayerSkin.InfoView);
	LOGFONT lf;
	memset(&lf,0,sizeof(LOGFONT));

	lf.lfWeight=FW_NORMAL;
	if (PlayerSkin.InfoView.point)
	{
		wcscpy(lf.lfFaceName,PlayerSkin.InfoView.font);
		__int64 t=(__int64)GetDeviceCaps(hdc, LOGPIXELSY)*(__int64)PlayerSkin.InfoView.point/(__int64)72;
		lf.lfHeight = (long)t;
	}
	else
	{
		wcscpy(lf.lfFaceName,_T("Tahoma"));
		__int64 t=(__int64)GetDeviceCaps(hdc, LOGPIXELSY)*(__int64)9/(__int64)72;
		lf.lfHeight = (long)t;
	}
	HFONT hf=CreateFontIndirect(&lf);
	if (PlayerSkin.InfoView.FontRed!=0||(PlayerSkin.InfoView.FontBlue!=0)||(PlayerSkin.InfoView.FontGreen!=0))
	{
		SetTextColor(hdc,RGB(PlayerSkin.InfoView.FontRed,PlayerSkin.InfoView.FontGreen,PlayerSkin.InfoView.FontBlue));
	}

	if (PlayerSkin.InfoView.BackRed!=0||(PlayerSkin.InfoView.BackBlue!=0)||(PlayerSkin.InfoView.BackGreen!=0)) 
	{ 
		SetBkMode(hdc, OPAQUE); 
		SetBkColor(hdc,RGB(PlayerSkin.InfoView.BackRed,PlayerSkin.InfoView.BackGreen,PlayerSkin.InfoView.BackBlue)); 
	} 
	else 
	{ 
		SetBkMode(hdc, TRANSPARENT); 
	} 	
	
	HFONT of=(HFONT)SelectObject(hdc,hf);
	rc.left=PlayerSkin.InfoView.left;
	rc.right=PlayerSkin.InfoView.width+rc.left;
	rc.top=PlayerSkin.InfoView.top;
	rc.bottom=PlayerSkin.InfoView.height+rc.top;
	if (PlayerSkin.InfoView.scrolltext)
	{
		textsize=GetTextExtentPoint(hdc,DisplayName,wcslen(DisplayName),&sz);
		if (start<sz.cx*-1) 
		{
			if (sz.cx>rc.right-rc.left)
			{
				start+=sz.cx;
			}
			else
			{
				start+=PlayerSkin.InfoView.width+PlayerSkin.InfoView.left;
			}
		}
		ExtTextOut(hdc,start,rc.top,ETO_CLIPPED,&rc,DisplayName,wcslen(DisplayName),NULL);
		if (sz.cx>rc.right-rc.left)
		{
			if (start<0&&(start+sz.cx<rc.right-rc.left))
			{
				ExtTextOut(hdc,sz.cx+start,rc.top,ETO_CLIPPED,&rc,DisplayName,wcslen(DisplayName),NULL);
			}
		}
		else
		{
			if (start<0)
			{
				ExtTextOut(hdc,rc.right+start,rc.top,ETO_CLIPPED,&rc,DisplayName,wcslen(DisplayName),NULL);
			}
		}
	}
	else
		DrawText(hdc,DisplayName,wcslen(DisplayName),&rc,DT_CENTER);
	SelectObject(hdc,of);
	DeleteObject(hf);
	start-=16;
}

LRESULT CALLBACK ListWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message) 
	{
		case WM_KEYUP:
			return 0;
			break;
		case WM_SETFOCUS:
#ifdef ATI
//OutputDebugString(_T("init\r\n"));
			InitializeATI();
			RecalculateDimensions(hWnd);
#endif
			SendMessage(hWndMain,WM_USER+301,wParam,lParam);

			break;
		case WM_KILLFOCUS:
			if (GetActiveWindow()!=hWndMain) 
				SendMessage(hWndMain,WM_USER+302,wParam,lParam);
			break;
		case WM_KEYDOWN:
			SendMessage(hWndMain,message,wParam,lParam);
			return 0;
			break;
		default:
//#if _WIN32_WCE >= 300
#ifdef STRICT
			if (hWnd==hwndList)
				return CallWindowProc((WNDPROC)oldproc,hWnd,message,wParam,lParam);
			else
				return CallWindowProc((WNDPROC)oldprocid3,hWnd,message,wParam,lParam);
#else
			if (hWnd==hwndList)
				return CallWindowProc((int (__cdecl *)(void))oldproc,hWnd,message,wParam,lParam);
			else
				return CallWindowProc((int (__cdecl *)(void))oldprocid3,hWnd,message,wParam,lParam);
#endif
			break;
	}
	return 0;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC hdc;
	int wmId;
	int key;
	static bool FocusPause=false;
	static HCURSOR oldcursor=NULL;
	HBITMAP old;
	switch (message) 
	{
		case WM_USER+110:
			if (lParam)
			{
				oldcursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
			}
			else
			{
				SetCursor(oldcursor);
			}
		break;
		case WM_USER+401:
			{
				int n;
				ListView_DeleteAllItems(hwndList);
				if (MaxFile)
				{
					for (n=0;n<=MaxFile;n++)
					{
						AddEntry(Files[n].FileName,-1);
					}
				}
				else
				{
					AddEntry(FileName,-1);
				}
				ListView_SetItemState(hwndList,CurrentFile,LVIS_SELECTED|LVIS_FOCUSED,0xFFFF);
				ListView_EnsureVisible( hwndList, CurrentFile, false );

			}
			break;
		case WM_USER+301:
			Display=2;
			break;
		case WM_SETFOCUS:
#ifdef ATI
//OutputDebugString(_T("init\r\n"));
			InitializeATI();
			RecalculateDimensions(hWnd);
#endif
			Display=2;
			break;
		case WM_TIMER:
			if (wParam==222||(wParam==223))
			{
				KillTimer(hWnd,wParam);
				SendMessage(hWnd,WM_USER+401,0,0);
				if (StartFile)
				{
					if (PlayerOptions.Shuffle) Shuffle();
					else CurrentFile=StartFile-1;
					wcscpy(FileName,Files[CurrentFile].FileName);
					StartFile=0;
					Stream=!wcsncmp(FileName,_T("http://"),7);
				}
				else if (MaxFile)
				{
					CurrentFile=MaxFile;
					NextFile(1);
				}
				if (wParam==222)
				{
					bPlayNow=true;
					Reset(hWnd,0);
				}
				else
				{
					bPlayNow=PlayerOptions.PlayAtOpen;
					Reset(hWnd,PlayerOptions.LastFilePos);
				}
			}
			else if (wParam==444)
			{
				unsigned long pos;
				waveOutGetVolume( 0, &pos);				
				int vol=(LOWORD(pos))*100/0xffff;
				vol+=10;
				if (vol>100) vol=100;
				if (vol<0) vol=0;
				if (vol>=FadeMax)
				{
					vol=FadeMax;
					KillTimer(hWndMain,hTimerFade);
				}
				if (!PlayerOptions.Mute) waveOutSetVolume( 0, (unsigned long)(0xffff*vol)/100+(0xffff*vol)/100*0x10000  );				
			}
			else if (wParam==10)
			{
				if (ptid&&(!bPaused))
				{
					keybd_event(VK_SHIFT,1,0,0);
					keybd_event(VK_SHIFT,1,KEYEVENTF_KEYUP,0);
				}
			}
			else if ((!NeedHide||((bPaused&&(!FastForward))))&&(!PlayerSkin.SeekButton.status))
			{
				if (PlayerSkin.SeekSlider.rotated)
					PlayerSkin.SeekButton.top = PlayerSkin.SeekSlider.top+((GetPos()*PlayerSkin.SeekSlider.height*PlayerSkin.SeekButton.step)/100); 
				else
					PlayerSkin.SeekButton.left = PlayerSkin.SeekSlider.left+((GetPos()*PlayerSkin.SeekSlider.width*PlayerSkin.SeekButton.step)/100); 
				if (PlayerSkin.SeekButton.top+PlayerSkin.SeekButton.height>PlayerSkin.SeekSlider.top+PlayerSkin.SeekSlider.height)
					PlayerSkin.SeekButton.top=PlayerSkin.SeekSlider.top+PlayerSkin.SeekSlider.height-PlayerSkin.SeekButton.height;
				if (PlayerSkin.SeekButton.left+PlayerSkin.SeekButton.width>PlayerSkin.SeekSlider.left+PlayerSkin.SeekSlider.width)
					PlayerSkin.SeekButton.left=PlayerSkin.SeekSlider.left+PlayerSkin.SeekSlider.width-PlayerSkin.SeekButton.width;
				DrawButtonUp(&PlayerSkin.SeekSlider);
				DrawButtonDown(&PlayerSkin.SeekButton);
				PlayerSkin.SeekButton.status=0;
				if (PlayerSkin.InfoView.scrolltext)
				{
					HDC hdc=GetDC(hWndMain);
					DrawInfoView(hdc,true);
					ReleaseDC(hWndMain,hdc);
				}
				if (PlayerSkin.Time.width)
				{
					HDC hdc=GetDC(hWndMain);
					DrawTime(hdc);
					ReleaseDC(hWndMain,hdc);
				}
			}

			break;

		case WM_KEYDOWN:
			key=(int) wParam;
			if (key == PlayerOptions.PauseKey)
				PauseEvent();
			else if (key==PlayerOptions.ZoomKey)
				SendMessage(hWnd,WM_COMMAND,IDM_DOUBLE,NULL);
			else if (key==PlayerOptions.RotateKey)
				SendMessage(hWnd,WM_COMMAND,IDM_ROTATE,NULL);
			else if (key == PlayerOptions.StopKey)
				SendMessage(hWnd,WM_COMMAND,IDM_STOP,NULL);
			else if (key == PlayerOptions.MuteKey)
				SendMessage(hWnd,WM_COMMAND,IDM_MUTE,NULL);
#if (defined( GAPI)&&((_WIN32_WCE >= 300)))
			else if (key==PlayerOptions.ToggleKey)
				ToggleDisplay();				
#endif
			if (key==PlayerOptions.VolumeDownKey||(key==PlayerOptions.VolumeUpKey))
			{
				unsigned long pos;
				waveOutGetVolume( 0, &pos);				
				int vol=(LOWORD(pos))*100/0xffff;
				vol+=key==PlayerOptions.VolumeUpKey?5:-5;
				if (vol>100) vol=100;
				if (vol<0) vol=0;
				if (!PlayerOptions.Mute) waveOutSetVolume( 0, (unsigned long)(0xffff*vol)/100+(0xffff*vol)/100*0x10000  );				
				if (PlayerSkin.VolButton.width)
				{
					if (PlayerSkin.VolSlider.rotated)
						PlayerSkin.VolButton.top = PlayerSkin.VolSlider.top+((vol*PlayerSkin.VolSlider.height*PlayerSkin.VolButton.step)/100); 
					else
						PlayerSkin.VolButton.left = PlayerSkin.VolSlider.left+((vol*(PlayerSkin.VolSlider.width-PlayerSkin.VolButton.width)*PlayerSkin.VolButton.step)/100); 
					if (!NeedHide||(bPaused))
					{
						DrawButtonUp(&PlayerSkin.VolSlider);
						DrawButtonDown(&PlayerSkin.VolButton);
						PlayerSkin.VolButton.status=0;
					}
				}

			}
			else if (key==PlayerOptions.NextKey)
				SendMessage(hWnd,WM_COMMAND,IDM_NEXT,NULL);
			else if (key==PlayerOptions.PrevKey)
				SendMessage(hWnd,WM_COMMAND,IDM_PREV,NULL);
			else if (key==PlayerOptions.FastKey)
				SendMessage(hWnd,WM_COMMAND,IDM_FASTFWD,NULL);
#ifdef ARM
			else if (key==PlayerOptions.BrightnessUpKey)
			{
				PlayerOptions.Brightness+=10;
				lastshow=0;
			}
			else if (key==PlayerOptions.BrightnessDownKey)
			{
				PlayerOptions.Brightness-=10;
				lastshow=0;
			}
#endif
		break;
	
		case WM_INITMENUPOPUP:
			Display=0;
			break;
		case WM_USER+302:
		case WM_KILLFOCUS:
			Display=0;
			if (!bPaused&&(vidinfo)&&(vidinfo->video_pos)&&(vidinfo->video_pos+1<vidinfo->video_frames)) Pause();
#ifdef ATI
			if (VH1)
			{
				AtiCore_DestroySurface(VH1);
				VH1=NULL;
				if (VH2) AtiCore_DestroySurface(VH2);
				AtiCore_ReleaseOverlay(OverlayHandle);
				AtiCore_ProcessDetach();
//OutputDebugString(_T("release\r\n"));
			}
#endif
			break;
		case WM_LBUTTONUP:
			ProcessRelease(LOWORD(lParam),HIWORD(lParam));
			break;
		case WM_LBUTTONDOWN:
			ProcessPush(LOWORD(lParam),HIWORD(lParam));
			break;
		case WM_HELP:
			CreateProcess(TEXT("PegHelp.exe"),TEXT("PMVP.htm#MAIN_CONTENTS"),NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL); 
			break;
		case WM_MOUSEMOVE:
			ProcessTrack(LOWORD(lParam),HIWORD(lParam));
			break;
		case WM_NOTIFY:
			{
				LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lParam;
				if (lpnmlv->hdr.code==NM_CLICK&&(lpnmlv->hdr.hwndFrom==hwndList))
				{
					if (lpnmlv->iItem>=0)
					{
						CurrentFile=lpnmlv->iItem;
						wcscpy(FileName,Files[CurrentFile].FileName);
						Stream=!wcsncmp(FileName,_T("http://"),7);
						bPlayNow=true;
						Stop(hWnd);
					}
					else
					{
						ListView_SetItemState(hwndList,CurrentFile,LVIS_SELECTED|LVIS_FOCUSED,0xFFFF);
						ListView_EnsureVisible( hwndList, CurrentFile, false );
						SendMessage(hWnd,WM_COMMAND,IDM_PLAY,NULL);
					}
				}

			}
			break;
		case WM_COMMAND:
			wmId    = LOWORD(wParam); 
			if (vidinfo)
			{
				if (wmId>IDM_CHAPTER1&&(wmId<=IDM_CHAPTER1+vidinfo->ChapterCount))
				{
					SeekPos(vidinfo->ChapterCount-(wmId-IDM_CHAPTER1-1)-1,1,0);
				}
			}
			// Parse the menu selections:
			switch (wmId)
			{
				case IDM_HELP:		
					CreateProcess(TEXT("PegHelp.exe"),TEXT("PMVP.htm#MAIN_CONTENTS"),NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL); 
					break;
				case IDM_PLAYLIST:
					{
						TCHAR path[200];
						HANDLE h=GetModuleHandle(_T("PocketMVP.exe"));
						HWND d=FindWindow(NULL,_T("PlaylistEditor"));
						PROCESS_INFORMATION p;
						GetModuleFileName((HMODULE)h,path,200);
						LPTSTR t=wcsstr(path,_T("PocketMVP."));
						*t=0;
						wcscat(path,_T("PlaylistEditor.exe"));
						if (wcscmp(PDLFile,_T("")))
						{
							CreateProcess(path,PDLFile,NULL,NULL,NULL,0,NULL,NULL,NULL,&p);
						}
						else
							CreateProcess(path,NULL,NULL,NULL,NULL,0,NULL,NULL,NULL,&p);
					}
					break;
				case IDM_JUMP:
					{
						int s=0;
						int newpos;
						if (vidinfo->video_frames)
						{
							s=(int) (vidinfo->video_pos/vidinfo->fps);
						}
						else if (vidinfo->audio_bytes&(br))
						{
							s=(GetPos()*(double)vidinfo->audio_bytes)/100;
							s=s/(abs(br)/8);
						}
#if (_WIN32_WCE >= 300 && !defined(HPC))
						SHFullScreen(hWndMain,4);
						SipShowIM(1);
#endif
						newpos=JumpTo(hWnd,s);
#if (_WIN32_WCE >= 300 && !defined(HPC))
						SipShowIM(0);
						SHFullScreen(hWndMain,8);
#endif
						if (newpos>=0)
						{
							if (vidinfo->video_frames)
							{
								SeekPos(newpos*vidinfo->fps,false,true);
							}
							else if (vidinfo->audio_bytes&(br))
							{
								int s=vidinfo->audio_bytes/(abs(br)/8);
								SeekPos((newpos*100/s),false,true);
							}
						}
					}
					break;
				case IDM_MEDIA:
					{
						TCHAR Info[1000];
						TCHAR Time[10];
						if (vidinfo)
						{
							int h,m,s;
							int abr=abs(br);
							TCHAR hold[5];

							if (vidinfo->video_frames)
							{
								s=(int)(vidinfo->video_frames/vidinfo->fps);
							}
							else if (vidinfo->audio_bytes)
							{
								s=vidinfo->audio_bytes/(abr/8);
							}
							h=s/3600;
							m=(s-h*3600)/60;
							s=s-(h*3600+m*60);
							wcscpy(Time,_T(""));
							if (h)
							{
								_itow(h,Time,10);
								wcscat(Time,_T(":"));
							}
							if (m<10) wcscat(Time,_T("0"));
							_itow(m,Time+wcslen(Time),10);
							wcscat(Time,_T(":"));
							if (s<10) wcscat(Time,_T("0"));
							_itow(s,Time+wcslen(Time),10);

							if (vidinfo->video_frames)
							{
								MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,vidinfo->compressor,-1,hold,5);
								swprintf(Info,_T("File Name: %s\r\nResolution: %d X %d\r\nFrames: %d\r\nFPS: %.2f\r\nAudio Bitrate: %dKbps\r\nAudio Rate: %dKhz\r\nChannels: %d\r\nRunning Time: %s\r\nFourCC: %s\r\nAudio Format: %d"),FileName,vidinfo->width,vidinfo->height,vidinfo->video_frames,vidinfo->fps,abr/1000,vidinfo->a_rate/1000,vidinfo->a_chans,Time,hold,vidinfo->a_fmt);
							}
							else
							{
								swprintf(Info,_T("File Name: %s\r\nTitle: %s\r\nArtist: %s\r\nAlbum: %s\r\nAudio Bitrate: %dKbps\r\nAudio Rate: %dKhz\r\nChannels: %d\r\nRunning Time: %s\r\nAudio Format: %d"),FileName,ID3_Title,ID3_Artist,ID3_Album,abr/1000,vidinfo->a_rate/1000,vidinfo->a_chans,Time,vidinfo->a_fmt);
							}

						}
						else
						{
							swprintf(Info,_T("No file loaded"));
						}
						MessageBox(hWnd,Info,_T("Media Info"),MB_OK);
					}
					break;
				case IDM_ABOUT:
					{
						MessageBox(hWnd,VERSION,_T("PocketMVP"),MB_OK);
					}
					break;
				case IDM_NEXT:
					if (EndReached) break;
					Dir=1;
					EndReached=true;
					Stop(hWnd);
					break;
				case IDM_PREV:
					if (EndReached) break;
					Dir=-1;
					EndReached=true;
					Stop(hWnd);
					break;
				case IDM_FASTFWD:
					if (!vidinfo||(!vidinfo->video_frames)) break;
					if (!FastForward&&(!PlayerSkin.FFWDButton.status)) DrawButtonDown(&PlayerSkin.FFWDButton);
					if (ptid)
					{
						if (!FastForward)
						{
							if (!bPaused)
							{
								Pause();
								Sleep(1000);
							}
							if (NeedHide)
							{
								ShowControls(false);
							}
							FastForward=!FastForward;
						}
						else
						{
							StopFastForward();
							Pause();
						}
					}

					break;
				case IDM_EQON:
					if (!PlayerOptions.EnableEQ) DrawButtonDown(&PlayerSkin.EQButton);
					else DrawButtonUp(&PlayerSkin.EQButton);
					PlayerOptions.EnableEQ=!PlayerOptions.EnableEQ;
					if (Init)
					{
						Init(PlayerOptions.EnableEQ,PlayerOptions.Eq);
					}
					break;
				case IDM_PLAY:
					PauseEvent();
					break;
				case IDM_STOP:
					Stop(hWnd);
					break;
				case IDM_ROTATE:
#ifdef IPAQ
					if (PlayerOptions.Rotate) DrawButtonDown(&PlayerSkin.RotateButton);
					else DrawButtonUp(&PlayerSkin.RotateButton);
#else
					if (!PlayerOptions.Rotate) DrawButtonDown(&PlayerSkin.RotateButton);
					else DrawButtonUp(&PlayerSkin.RotateButton);
#endif
					//PlayerOptions.Rotate=!PlayerOptions.Rotate;
					OptionRefresh(hWnd,&PlayerOptions.Rotate);
					break;
				case IDM_MUTE:
					if (!PlayerOptions.Mute) DrawButtonDown(&PlayerSkin.MuteButton);
					else DrawButtonUp(&PlayerSkin.MuteButton);
					PlayerOptions.Mute=!PlayerOptions.Mute;
					ToggleMute();
					break;
				case IDM_FITTOVIEW:
					ToggleMenu(wmId,&PlayerOptions.FitToViewPort);
					OptionRefresh(hWnd,NULL);
					break;
				case IDM_SHUFFLE:
					ToggleMenu(wmId,&PlayerOptions.Shuffle);
					CurrentFile=MaxFile;
					NeedShuffle=PlayerOptions.Shuffle;
					break;
				case IDM_REPEAT:
					if (!PlayerOptions.Repeat) DrawButtonDown(&PlayerSkin.RepeatButton);
					else DrawButtonUp(&PlayerSkin.RepeatButton);
					ToggleMenu(wmId,&PlayerOptions.Repeat);
					break;
				case IDM_DOUBLE:
					if (!PlayerOptions.Double) DrawButtonDown(&PlayerSkin.FullScreenButton);
					else DrawButtonUp(&PlayerSkin.FullScreenButton);
					//PlayerOptions.Double=!PlayerOptions.Double;
					OptionRefresh(hWnd,&PlayerOptions.Double);
					break;

				case IDM_CLEAN:
					ToggleMenu(wmId,&PlayerOptions.Clean);										
					OptionRefresh(hWnd,NULL);
					break;
				case IDM_VIEWPLAYLIST:
					ToggleMenu(wmId,&PlayerOptions.Playlist);	
					ChangeView();
					break;
				case IDM_VIEWMEDIA:
					ToggleMenu(wmId,&PlayerOptions.Media);										
					ChangeView();
					break;
				case IDM_CONFIGURE:
					Config();
					if (PlayerOptions.KeepAlive&&(!ht))
					{
						ht=SetTimer(hWnd,10,60000,NULL);
					}
					else if (!PlayerOptions.KeepAlive&&(ht))
					{
						KillTimer(hWnd,ht);
						ht=0;
					}
#if (_WIN32_WCE >= 300)
					RegOptionBLTimeout( PlayerOptions.KeepAlive );
#endif

					break;
				case IDM_EQ:
					Equalizer();
					break;
				case IDM_OPENURL:
					GetFileList(hWnd,true,false,0);
					break;
				case IDM_OPEN:
					GetFileList(hWnd,false,false,0);
					break;
				case IDM_OPENSKIN:
					GetFileList(hWnd,false,false,1);
					break;
				case IDM_OPENLIST:
					GetFileList(hWnd,false,false,2);
					break;
				case IDM_BROADCAST:
					GetFileList(hWnd,false,true,0);
					break;
				case IDM_FILE_EXIT:
				   DestroyWindow(hWnd);
				   break;
				default:
				   return DefWindowProc(hWnd, message, wParam, lParam);
			}
			break;
		case WM_CREATE:
			if (wcscmp(lpTempSkin,_T("")))
			{
				TCHAR hold[255];
				wcscpy(hold,PlayerOptions.Skin);
				LoadSkin(lpTempSkin,hWnd);
				wcscpy(PlayerOptions.Skin,hold);
			}
			else
				LoadSkin(PlayerOptions.Skin,hWnd);
			hdc=GetDC(hWnd);
			SystemParametersInfo(SPI_GETOEMINFO,200,(void*)temp,0);
#ifdef IPAQ
			amigo=0;
			twelve_bit=1;
			if (wcsstr((LPTSTR)temp,_T("39")))
			{
				twelve_bit=0;
				amigo=1;
			}
			else if (wcsstr((LPTSTR)temp,_T("38")))
			{
				twelve_bit=0;
				g_bInvert=true;
			}
			else if (wcsstr((LPTSTR)temp,_T("iPAQ")))
			{
				g_bInvert=false;
			}
			else
			{
				twelve_bit=0;
				amigo=1;
			}
#else
			if (wcsstr((LPTSTR)temp,_T("740"))||(wcsstr((LPTSTR)temp,_T("750"))))
			{
				e740=1;
			}
			else
			{
				e740=0;
			}

#endif

#ifdef ATI
				VH1=NULL;
//OutputDebugString(_T("init\r\n"));
				if (InitializeATI()) return 1;
#endif

			InitializeCriticalSection(&cs);


			compat=CreateCompatibleDC(hdc);
			if (PlayerOptions.KeepAlive) ht=SetTimer(hWnd,10,60000,NULL);
			eventStopped=CreateEvent(NULL,true,false,_T("eventStopped"));
			eventAudioStopped=CreateEvent(NULL,true,false,_T("eventAudioStopped"));
			eventAudio=CreateEvent(NULL,true,true,_T("eventAudio"));
			eventNextFrame=CreateEvent(NULL,true,false,_T("eventNextFrame"));
			ReleaseDC(hWnd,hdc);

#ifdef _USEVIDBUFF
			vbuff = (short *)PHYSADDR; //lpv; 
#endif


#ifdef GAPI
#ifndef HPC

			
//#ifndef ATI			
	GXOpenDisplay(hWnd, GX_FULLSCREEN);
//#endif
//	GXDisplayProperties x=GXGetDisplayProperties();
//	{
//		TCHAR temp[10];
//		MessageBox(hWnd,_itow(x.cxWidth,temp,10),_T("width"),MB_OK);
//		MessageBox(hWnd,_itow(x.cyHeight,temp,10),_T("height"),MB_OK);
//		MessageBox(hWnd,_itow(x.cbxPitch,temp,10),_T("x pitch"),MB_OK);
//		MessageBox(hWnd,_itow(x.cbyPitch,temp,10),_T("y pitch"),MB_OK);
//	}
#endif
	// Initialize the Hardware Buttons
	GXOpenInput();

#endif
			if (wcscmp(FileName,_T("")))
			{
				SetTimer(hWnd,222,1000,NULL);
			}
			else if (wcscmp(PlayerOptions.LastFile,_T(""))&&(PlayerOptions.KeepLastFile))
			{
				wcscpy(FileName,PlayerOptions.LastFile);
				SetTimer(hWnd,223,1000,NULL);
			}
			break;

		case WM_PAINT:
		{
			RECT rc;
			if (!hwndCB) break;
			lastshow=0;
#ifdef ATI
			Cleared=false;
#endif
			if (!lParam) DefWindowProc(hWnd, message, wParam, lParam);
			hdc = GetDC(hWnd); //BeginPaint(hWnd, &ps);
#ifdef HPC
			if (((bPaused&&(!FastForward))||(!NeedHide))&&(!lParam))
#else
			if (((bPaused&&(!FastForward))||(!NeedHide))&&(IsWindowVisible(hwndCB))&&(!lParam))
#endif
			{
				RECT rcView;
				rcView.left=PlayerSkin.ViewPort.left;
				rcView.top=PlayerSkin.ViewPort.top;
				rcView.right=PlayerSkin.ViewPort.width+PlayerSkin.ViewPort.left;
				rcView.bottom=PlayerSkin.ViewPort.height+PlayerSkin.ViewPort.top;
				GetWindowRect(hWnd,&rc);
				old=(HBITMAP)SelectObject(compat,m_hBitBack);
				BitBlt(hdc,0,Y_ADJUST,rc.right,rc.bottom,compat,0,0,SRCCOPY);
				SelectObject(compat,old);
				backColor=GetPixel(hdc,rcView.left+1,rcView.top+Y_ADJUST+1);
			}
			if (hb&&(bPaused))
			{
				short nWidth=g_nWidth;
				short nHeight=g_nHeight;
				RECT rcView;
				rcView.left=PlayerSkin.ViewPort.left;
				rcView.top=PlayerSkin.ViewPort.top;
				rcView.right=PlayerSkin.ViewPort.width+PlayerSkin.ViewPort.left;
				rcView.bottom=PlayerSkin.ViewPort.height+PlayerSkin.ViewPort.top;

				HBRUSH hbr=CreateSolidBrush(backColor);
				FillRect(hdc,&rcView,hbr); //(HBRUSH)GetStockObject(BLACK_BRUSH));
				DeleteObject(hbr);
#ifdef IPAQ
				if (!PlayerOptions.Rotate)
#else
				if (PlayerOptions.Rotate)
#endif
				{
					nWidth=nHeight;
					nHeight=g_nWidth;
				}
#ifndef IPAQ


				if (nWidth>VisibleWidth) nWidth=VisibleWidth;
				if (nHeight>VisibleHeight) nHeight=VisibleHeight;
#else
				if (nHeight>VisibleWidth) nHeight=VisibleWidth;
				if (nWidth>VisibleHeight) nWidth=VisibleHeight;
#endif	
				old=(HBITMAP)SelectObject(compat,hb);
				if (nWidth>PlayerSkin.ViewPort.width||(nHeight>PlayerSkin.ViewPort.height))
				{
					
					float nStretchX=(((float)((float)PlayerSkin.ViewPort.width/(float)nWidth)));
					float nStretchY=(((float)((float)PlayerSkin.ViewPort.height/(float)nHeight)));
					int StretchX;
					int StretchY;
					if (nStretchX>nStretchY) 
					{
						nStretchX=nStretchY;
					}
					else
					{
						nStretchY=nStretchX;
					}
					StretchX=(int)((float)((float)nStretchX)*((float)nWidth));
					StretchY=(int)((float)((float)nStretchY)*((float)nHeight));
					StretchBlt(hdc,PlayerSkin.ViewPort.left+(PlayerSkin.ViewPort.width-StretchX)/2,PlayerSkin.ViewPort.top+(PlayerSkin.ViewPort.height-StretchY)/2,StretchX,StretchY,compat,0,0,nWidth,nHeight,SRCCOPY);

				}
				else
				{
					if (PlayerOptions.Double&&(nWidth*2<PlayerSkin.ViewPort.width&&(nHeight*2<PlayerSkin.ViewPort.height)))
					{
						StretchBlt(hdc,PlayerSkin.ViewPort.left+((PlayerSkin.ViewPort.width-(nWidth*2))/2),PlayerSkin.ViewPort.top+((PlayerSkin.ViewPort.height-(nHeight*2))/2),nWidth*2,nHeight*2,compat,0,0,nWidth,nHeight,SRCCOPY);
					}
					else
					{
						int tY=PlayerSkin.ViewPort.top+((PlayerSkin.ViewPort.height-(nHeight))/2);
						if (tY%2)
#ifdef IPAQ
							tY--;
#else
							tY++;
#endif
						BitBlt(hdc,PlayerSkin.ViewPort.left+((PlayerSkin.ViewPort.width-(nWidth))/2),tY,nWidth,nHeight,compat,0,0,SRCCOPY);
					}
				}
				SelectObject(compat,old);
			}
			if(	PlayerSkin.InfoView.height>0&&(!NeedHide||((bPaused&&(!FastForward))))&&(IsWindowVisible(hwndCB))&&(!lParam))
			{
				DrawInfoView(hdc,PlayerSkin.InfoView.scrolltext);
			}
			ReleaseDC(hWnd,hdc);
#ifdef HPC
			if (((bPaused&&(!FastForward))||(!NeedHide)))
#else
			if (((bPaused&&(!FastForward))||(!NeedHide))&&(IsWindowVisible(hwndCB))&&(!lParam))
#endif
			{
				if (PlayerSkin.PlayButton.status&&(!bPaused)) DrawButtonDown(&PlayerSkin.PlayButton);
				else DrawButtonUp(&PlayerSkin.PlayButton);
				if (PlayerSkin.StopButton.status) DrawButtonDown(&PlayerSkin.StopButton);
				else DrawButtonUp(&PlayerSkin.StopButton);
				if (PlayerSkin.OpenButton.status) DrawButtonDown(&PlayerSkin.OpenButton);
				else DrawButtonUp(&PlayerSkin.OpenButton);
				if (PlayerSkin.EditorButton.status) DrawButtonDown(&PlayerSkin.EditorButton);
				else DrawButtonUp(&PlayerSkin.EditorButton);
				if (PlayerSkin.NextButton.status) DrawButtonDown(&PlayerSkin.NextButton);
				else DrawButtonUp(&PlayerSkin.NextButton);
				if (PlayerSkin.PrevButton.status) DrawButtonDown(&PlayerSkin.PrevButton);
				else DrawButtonUp(&PlayerSkin.PrevButton);
				if (PlayerSkin.FFWDButton.status&&(FastForward)) DrawButtonDown(&PlayerSkin.FFWDButton);
				else DrawButtonUp(&PlayerSkin.FFWDButton);
				if (PlayerOptions.Mute) DrawButtonDown(&PlayerSkin.MuteButton);
				else DrawButtonUp(&PlayerSkin.MuteButton);
#ifdef IPAQ
				if (!PlayerOptions.Rotate)
#else
				if (PlayerOptions.Rotate)
#endif
					DrawButtonDown(&PlayerSkin.RotateButton);
				else 
					DrawButtonUp(&PlayerSkin.RotateButton);
				if (PlayerOptions.Double) DrawButtonDown(&PlayerSkin.FullScreenButton);
				else DrawButtonUp(&PlayerSkin.FullScreenButton);
				if (PlayerOptions.EnableEQ) DrawButtonDown(&PlayerSkin.EQButton);
				else DrawButtonUp(&PlayerSkin.EQButton);
				if (PlayerOptions.Repeat) DrawButtonDown(&PlayerSkin.RepeatButton);
				else DrawButtonUp(&PlayerSkin.RepeatButton);
				DrawButtonUp(&PlayerSkin.SeekSlider);
				DrawButtonDown(&PlayerSkin.SeekButton);
				PlayerSkin.SeekButton.status=0;
				DrawButtonUp(&PlayerSkin.VolSlider);
				DrawButtonDown(&PlayerSkin.VolButton);
				PlayerSkin.VolButton.status=0;
			}
			Display=2;
		}
		break;
		case WM_DESTROY:
			Closing=true;
			if (PlayerOptions.Playlist) SetWindowLong(hwndList,GWL_WNDPROC,(long)oldproc);
			SetWindowLong(hwndID3,GWL_WNDPROC,(long)oldprocid3);
#ifdef ATI
			if (VH1)
			{
				AtiCore_DestroySurface(VH1);
				if (VH2) AtiCore_DestroySurface(VH2);
				AtiCore_ReleaseOverlay(OverlayHandle);
				AtiCore_ProcessDetach();
				VH1=NULL;
//OutputDebugString(_T("release\r\n"));
			}
#endif
			{
				if (vidinfo)
					PlayerOptions.LastFilePos=vidinfo->video_pos;
				if (PlayerOptions.Mute) ToggleMute();
				SaveOptions(&PlayerOptions);
			}
			Stop(hWnd);
			
#ifdef GAPI


			GXCloseDisplay();
			GXCloseInput();
#endif
			DeleteObject(compat);
			DeleteCriticalSection(&cs);
			CommandBar_Destroy(hwndCB);

			if (Files) free(Files);
			if (ht) KillTimer(hWnd,ht);
			if (hTimerSlider) KillTimer(hWnd,hTimerSlider);
#if (_WIN32_WCE >= 300)
			RegOptionBLTimeout( false );
#endif
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}
