#include "pch.hpp"
//===========================================================================//
// File:	 DirectXDebugging.cpp											 //
// Project:  GameOS					                                         //
// Contents: Debug Functions for DirectX									 //
//---------------------------------------------------------------------------//
// Date      Who    Modification                                             //
// 01/24/98  AG     Created													 //
//---------------------------------------------------------------------------//
// Copyright (C) 1999 Microsoft Corp.						                 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//
#include "Globals.hpp"
#include "ErrorHandler.hpp"
#include "DirectX.hpp"
#include "Windows.hpp"
#include "Net_Header.hpp"



char* GetLightColor( LPD3DLIGHT7 lpLight )
{
	static char Buffer[256];
	sprintf( Buffer,"Diffuse=%6.2f,%6.2f,%6.2f, Specular=%6.2f,%6.2f,%6.2f, Ambient=%6.2f,%6.2f,%6.2f", (double)lpLight->dcvDiffuse.r, (double)lpLight->dcvDiffuse.g, (double)lpLight->dcvDiffuse.b, (double)lpLight->dcvSpecular.r, (double)lpLight->dcvSpecular.g, (double)lpLight->dcvSpecular.b, (double)lpLight->dcvAmbient.r, (double)lpLight->dcvAmbient.g, (double)lpLight->dcvAmbient.b );
	return Buffer;
}

char* GetLightInfo( LPD3DLIGHT7 lpLight )
{
	static char Buffer[256];
	static char RangeBuffer[16];

	switch( lpLight->dltType )
	{
		case D3DLIGHT_POINT:
		{
			if( lpLight->dvRange>=((float)sqrt(FLT_MAX)) )
				strcpy( RangeBuffer, "MAX" );
			else
				sprintf( RangeBuffer, "%6.2f",(double)lpLight->dvRange );
			sprintf( Buffer, "POINT at (%6.2f,%6.2f,%6.2f) - Range=%s, Attenuation=%6.2f,%6.2f,%6.2f - %s", (double)lpLight->dvPosition.x, (double)lpLight->dvPosition.y, (double)lpLight->dvPosition.z, RangeBuffer, (double)lpLight->dvAttenuation0, (double)lpLight->dvAttenuation1, (double)lpLight->dvAttenuation2, GetLightColor(lpLight) );
			return Buffer;
		}
		case D3DLIGHT_SPOT:
		{
			if( lpLight->dvRange>=((float)sqrt(FLT_MAX)) )
				strcpy( RangeBuffer, "MAX" );
			else
				sprintf( RangeBuffer, "%6.2f",(double)lpLight->dvRange );
			sprintf( Buffer, "SPOT at (%6.2f,%6.2f,%6.2f), Direction (%6.2f,%6.2f,%6.2f) - Range=%s, Attenuation=%6.2f,%6.2f,%6.2f, Falloff=%6.2f, Theta=%6.2f, Phi=%6.2f - %s", (double)lpLight->dvPosition.x, (double)lpLight->dvPosition.y, (double)lpLight->dvPosition.z, (double)lpLight->dvDirection.x, (double)lpLight->dvDirection.y, (double)lpLight->dvDirection.z, RangeBuffer, (double)lpLight->dvAttenuation0, (double)lpLight->dvAttenuation1, (double)lpLight->dvAttenuation2, (double)lpLight->dvFalloff, (double)lpLight->dvTheta, (double)lpLight->dvPhi, GetLightColor(lpLight) );
			return Buffer;
		}
		case D3DLIGHT_DIRECTIONAL:
		{
			sprintf( Buffer, "DIRECTIONAL Direction (%6.2f,%6.2f,%6.2f) - %s", (double)lpLight->dvDirection.x, (double)lpLight->dvDirection.y, (double)lpLight->dvDirection.z, GetLightColor(lpLight) );
			return Buffer;
		}
		default:
			return "Unknown light type";
	}
}

char* GetMaterialInfo( LPD3DMATERIAL7 lpMaterial )
{
	static char Buffer[256];
	sprintf( Buffer, "Diffuse=%6.2f,%6.2f,%6.2f, Specular=%6.2f,%6.2f,%6.2f, Ambient=%6.2f,%6.2f,%6.2f, Emissive=%6.2f,%6.2f,%6.2f, Power=%6.2f", (double)lpMaterial->diffuse.r, (double)lpMaterial->diffuse.g, (double)lpMaterial->diffuse.b, (double)lpMaterial->specular.r, (double)lpMaterial->specular.g, (double)lpMaterial->specular.b, (double)lpMaterial->ambient.r, (double)lpMaterial->ambient.g, (double)lpMaterial->ambient.b, (double)lpMaterial->emissive.r, (double)lpMaterial->emissive.g, (double)lpMaterial->emissive.b, (double)lpMaterial->power );
	return Buffer;
}

char* GetTransformType( D3DTRANSFORMSTATETYPE dtstTransformStateType )
{
	switch( dtstTransformStateType )
	{
		case D3DTRANSFORMSTATE_WORLD:
			return "WORLD";
		case D3DTRANSFORMSTATE_VIEW:
			return "VIEW";
		case D3DTRANSFORMSTATE_PROJECTION:
			return "PROJECTION";
		default:
			return "Unknown";
	}
}

char* GetInputDevice( DWORD Size )
{
	if( Size==sizeof(DIMOUSESTATE) )
		return "Mouse";
	else if( Size==sizeof(DIMOUSESTATE2) )
		return "Mouse2";
	else if( Size==256 )
		return "Keyboard";
	else if( Size==sizeof(DIJOYSTATE) )
		return "Joysick";
	else if( Size==sizeof(DIJOYSTATE2) )
		return "Joystick2";
	else
		return "Unknown";
}

char* GetConnectionInfo( void* ConnectionInfo )
{
	static char Buffer[256];
	char tBuffer[128];

	Buffer[0]=0;
	
	DPCOMPOUNDADDRESSELEMENT* ptr=(DPCOMPOUNDADDRESSELEMENT*)ConnectionInfo;
	if( ptr->guidDataType!=DPAID_TotalSize )
	{
		STOP(( "Compound address does not start with size" ));
	}

	DPCOMPOUNDADDRESSELEMENT* EndPtr=(DPCOMPOUNDADDRESSELEMENT*)((BYTE*)ptr+(DWORD)ptr->lpData);
	ptr=(DPCOMPOUNDADDRESSELEMENT*)((BYTE*)ptr+ptr->dwDataSize+sizeof(DPCOMPOUNDADDRESSELEMENT)-4);

	while( ptr<EndPtr && strlen(Buffer)<224 )
	{
		if( ptr->guidDataType==DPAID_ComPort )
		{
			DPCOMPORTADDRESS* pComPort=(DPCOMPORTADDRESS*)&ptr->lpData;
			char* Parity;
			switch( pComPort->dwParity )
			{
				case NOPARITY:
					Parity="None";
					break;
				case ODDPARITY:
					Parity="Odd";
					break;
				case EVENPARITY:
					Parity="Even";
					break;
				case MARKPARITY:
					Parity="Mark";
					break;
				default:
					Parity="Unknown";
			}
			char* Flow;
			switch( pComPort->dwParity )
			{
				case DPCPA_DTRFLOW:
					Flow="DTR";
					break;
				case DPCPA_NOFLOW:
					Flow="None";
					break;
				case DPCPA_RTSDTRFLOW:
					Flow="RTSDTR";
					break;
				case DPCPA_RTSFLOW:
					Flow="RTS";
					break;
				case DPCPA_XONXOFFFLOW:
					Flow="XON/XOFF";
				default:
					Flow="Unknown";
			}
			sprintf( tBuffer, "ComPort=%d, Baud=%d, StopBits=%d, Parity=%s, FlowControl=%s ", pComPort->dwComPort, pComPort->dwBaudRate, pComPort->dwStopBits, Parity, Flow );
		}
		else if( ptr->guidDataType==DPAID_INet )
		{
			sprintf( tBuffer, "Address=\"%s\" ", (char*)&ptr->lpData );
		}
		else if( ptr->guidDataType==DPAID_INetW )
		{
			sprintf( tBuffer, "INetW " );
		}
		else if( ptr->guidDataType==DPAID_INetPort )
		{
			sprintf( tBuffer, "Port=%d ", *(WORD*)&ptr->lpData );
		}
		else if( ptr->guidDataType==DPAID_LobbyProvider )
		{
			sprintf( tBuffer, "LobbyProvider " );
		}
		else if( ptr->guidDataType==DPAID_Modem )
		{
			sprintf( tBuffer, "Modem=\"%s\" ",(char*)&ptr->lpData );
		}
		else if( ptr->guidDataType==DPAID_ModemW )
		{
			sprintf( tBuffer, "ModemW " );
		}
		else if( ptr->guidDataType==DPAID_Phone )
		{
			sprintf( tBuffer, "Phone number=\"%s\" ",(char*)&ptr->lpData );
		}
		else if( ptr->guidDataType==DPAID_PhoneW )
		{
			sprintf( tBuffer, "PhoneW " );
		}
		else if( ptr->guidDataType==DPAID_ServiceProvider )
		{
			char* Provider;
			Provider="Unknown";
			REFGUID Guid=(REFGUID)ptr->lpData;
			if( IsEqualGUID( Guid, DPSPGUID_TCPIP) )
				Provider="TCPIP";
			if( IsEqualGUID( Guid, DPSPGUID_IPX) )
				Provider="IPX";
			if( IsEqualGUID( Guid, DPSPGUID_MODEM) )
				Provider="MODEM";
			if( IsEqualGUID( Guid, DPSPGUID_SERIAL) )
				Provider="SERIAL";
			sprintf( tBuffer, "Provider=%s ", Provider );
		}
		else
		{
			sprintf( tBuffer, "Uknown GUID" );
		}
		strcat( Buffer, tBuffer );
		ptr=(DPCOMPOUNDADDRESSELEMENT*)((BYTE*)ptr+ptr->dwDataSize+sizeof(DPCOMPOUNDADDRESSELEMENT)-4);
	}
	return Buffer;
}

char* GetMessageInfo( DWORD Type, void* pData )
{
	static char Buffer[64];

	if( Type>240 )
	{
		switch( Type )
		{
			case gosNet_PlayerAdded:
				sprintf( Buffer,"Player Added" );
				break;
			case gosNet_PlayerDeleted:
				sprintf( Buffer,"Player Deleted" );
				break;
			case gosNet_GameEnded:
				sprintf( Buffer,"Game Ended" );
				break;
			case gosNet_Ping:
				sprintf( Buffer,"Ping" );
				break;
			default:
				sprintf( Buffer,"Unknown system message 0x%x",Type );
				break;
		}
	}
	else
	{
		sprintf( Buffer, "User Message" );
	}
	return Buffer;
}

char* GetNetworkMessage( NetPacket* pMessage )
{
	static char Buffer[128];
	sprintf( Buffer, "From=0x%x, To=0x%x, Bytes=%d Type=%s",pMessage->FromID, pMessage->ToID, pMessage->Length, GetMessageInfo(pMessage->Type, pMessage->pData) );
	return Buffer;
}

char* GetSendExTo( DPID idTo )
{
	if( DPID_ALLPLAYERS==idTo )
		return "All";
	if( DPID_SERVERPLAYER==idTo )
		return "Server";
	static char Buffer[128];
	sprintf( Buffer, "0x%x",idTo );
	return Buffer;
}

char* GetSendExInfo( DPID idFrom, DPID idTo, DWORD dwFlags, DWORD dwDataSize, DWORD dwPriority, DWORD dwTimeout, LPVOID lpContext, LPDWORD lpdwMsgID )
{
	static char Buffer[128];
	char Buffer1[64];
	sprintf( Buffer, "From=0x%x, To=%s, Bytes=%d ",idFrom,GetSendExTo(idTo),dwDataSize );

	if( dwPriority )
	{
		sprintf( Buffer1, "Priority=%d ",dwPriority );
		strcat( Buffer, Buffer1 );
	}
	if( dwTimeout )
	{
		sprintf( Buffer1, "Timeout=%d ",dwTimeout );
		strcat( Buffer, Buffer1 );
	}
	if( dwFlags&DPSEND_ASYNC )
		strcat( Buffer, "ASYNC ");
	if( dwFlags&DPSEND_ENCRYPTED )
		strcat( Buffer, "ENCRYPTED ");
	if( dwFlags&DPSEND_GUARANTEED )
		strcat( Buffer, "GUARANTEED ");
	if( dwFlags&DPSEND_NOSENDCOMPLETEMSG )
		strcat( Buffer, "NOSENDCOMPLETEMSG ");
	if( dwFlags&DPSEND_SIGNED )
		strcat( Buffer, "SIGNED ");
	return Buffer;
}

char* GetSendInfo( DPID idFrom, DPID idTo, DWORD dwFlags, DWORD dwDataSize )
{
	static char Buffer[128];
	sprintf( Buffer, "From=0x%x, To=0x%x, Bytes=%d %s",idFrom,idTo,dwDataSize,dwFlags&DPSEND_GUARANTEED ? ", GUARANTEED" : "" );
	return Buffer;
}

char* GetReceivedFrom( DPID Player )
{
	static char Buffer[16];
	if( DPID_SERVERPLAYER==Player )
		return "Server";
	sprintf( Buffer, "Player 0x%x",Player );
	return Buffer;
}
char* GetReceivedTo( DPID Player, DPID Group )
{
	static char Buffer[16];
	if( 0==Player && 0==Group )
		return "Everyone";
	if( Player )
	{
		sprintf( Buffer, "Player 0x%x",Player );
	}
	else
	{
		sprintf( Buffer, "Group 0x%x",Group );
	}
	return Buffer;
}

char* GetReceivedData( LPDPID lpidFrom, LPVOID lpData, LPDWORD lpdwDataSize )
{
	static char Buffer[128];

	if( *lpidFrom==DPID_SYSMSG )
	{
		DPMSG_GENERIC* pMes=(DPMSG_GENERIC*)lpData;	

		switch( pMes->dwType )
		{
			case DPSYS_ADDGROUPTOGROUP:
			{
				DPMSG_ADDGROUPTOGROUP* pM=(DPMSG_ADDGROUPTOGROUP*)lpData;
				sprintf( Buffer, "Add Group 0x%x To parent group 0x%x",pM->dpIdGroup,pM->dpIdParentGroup );
				break;
			}
			case DPSYS_ADDPLAYERTOGROUP:
			{
				DPMSG_ADDPLAYERTOGROUP* pM=(DPMSG_ADDPLAYERTOGROUP*)lpData;
				sprintf( Buffer, "Add player 0x%x To group 0x%x",pM->dpIdPlayer,pM->dpIdGroup );
				break;
			}
			case DPSYS_CHAT:
			{
				DPMSG_CHAT* pM=(DPMSG_CHAT*)lpData;
				sprintf( Buffer, "Chat from %s, to %s '%s'",GetReceivedFrom(pM->idFromPlayer),GetReceivedTo(pM->idToPlayer,pM->idToGroup),pM->lpChat->lpszMessageA );
				break;
			}
			case DPSYS_CREATEPLAYERORGROUP:
			{
				DPMSG_CREATEPLAYERORGROUP* pM=(DPMSG_CREATEPLAYERORGROUP*)lpData;
				if( pM->dwPlayerType==DPPLAYERTYPE_PLAYER )
				{
					sprintf( Buffer, "Create player '%s', ID=0x%x",pM->dpnName.lpszShortNameA, pM->dpId );
					break;
				}
				else
				{
					sprintf( Buffer, "Create group '%s', ID=0x%x",pM->dpnName.lpszShortNameA, pM->dpId );
					break;
				}
				break;
			}
			case DPSYS_DELETEGROUPFROMGROUP:
			{
				DPMSG_ADDGROUPTOGROUP* pM=(DPMSG_ADDGROUPTOGROUP*)lpData;
				sprintf( Buffer, "Delete Group 0x%x To parent group 0x%x",pM->dpIdGroup,pM->dpIdParentGroup );
				break;
			}
			case DPSYS_DELETEPLAYERFROMGROUP:
			{
				DPMSG_ADDPLAYERTOGROUP* pM=(DPMSG_ADDPLAYERTOGROUP*)lpData;
				sprintf( Buffer, "Delete player 0x%x To group 0x%x",pM->dpIdPlayer,pM->dpIdGroup );
				break;
			}
			case DPSYS_DESTROYPLAYERORGROUP:
			{
				DPMSG_DESTROYPLAYERORGROUP* pM=(DPMSG_DESTROYPLAYERORGROUP*)lpData;
				if( pM->dwPlayerType==DPPLAYERTYPE_PLAYER )
				{
					sprintf( Buffer, "Destroy player '%s', ID=0x%x",pM->dpnName.lpszShortNameA, pM->dpId );
					break;
				}
				else
				{
					sprintf( Buffer, "Destroy group '%s', ID=0x%x",pM->dpnName.lpszShortNameA, pM->dpId );
					break;
				}
				break;
			}
			case DPSYS_HOST:
			{
				return "Host exited";
			}
			case DPSYS_SECUREMESSAGE:
			{
				return "Secure Message";
			}
			case DPSYS_SENDCOMPLETE:
			{
				return "Send Complete";
			}
			case DPSYS_SESSIONLOST:
			{
				return "Session lost";
			}
			case DPSYS_SETGROUPOWNER:
			{
				DPMSG_SETGROUPOWNER* pM=(DPMSG_SETGROUPOWNER*)lpData;
				sprintf( Buffer, "Set group 0x%x owner from player 0x%x to player 0x%x",pM->idGroup, pM->idOldOwner, pM->idNewOwner );
				break;
			}
			case DPSYS_SETPLAYERORGROUPDATA:
			{
				return "Set player or group data";
			}
			case DPSYS_SETPLAYERORGROUPNAME:
			{
				return "Set player or group name";
			}
			case DPSYS_SETSESSIONDESC:
			{
				return "Set session description";
			}
			case DPSYS_STARTSESSION:
			{
				return "Start session";
			}
			default:
				return "Unknown";
		}
	}
	else
	{
		sprintf( Buffer, "From 0x%x, User message, Bytes=%d",(int)*lpidFrom,(int)*lpdwDataSize );
	}
	return Buffer;
}

char* GetReceiveFlags( DWORD dwFlags, LPDPID lpidFrom, LPDPID lpidTo )
{
	if( DPRECEIVE_ALL==dwFlags )
		return "ALL";

	static char Buffer[64];
	char Buffer1[64];
	Buffer[0]=0;

	if( dwFlags&DPRECEIVE_PEEK )
		strcat( Buffer, "PEEK " );

	if( DPRECEIVE_TOPLAYER == (dwFlags&(DPRECEIVE_TOPLAYER|DPRECEIVE_FROMPLAYER)) )
	{
		sprintf( Buffer1, "TO 0x%x ", lpidTo );
		strcat( Buffer, Buffer1 );
	}

	if( DPRECEIVE_FROMPLAYER == (dwFlags&(DPRECEIVE_TOPLAYER|DPRECEIVE_FROMPLAYER)) )
	{
		sprintf( Buffer1, "FROM 0x%x ", lpidFrom );
		strcat( Buffer, Buffer1 );
	}

	return Buffer;
}

char* GetPlayerName( LPDPNAME lpPlayerName )
{
	if( 0==lpPlayerName )
		return "Null";

	if( lpPlayerName->dwSize != sizeof(DPNAME) )
		STOP(( "Invalid size" ));

	return lpPlayerName->lpszShortNameA;
}

char* GetCreatePlayerFlags( DWORD dwFlags )
{
	if( 0==dwFlags )
		return "PLAYER";
	if( dwFlags&DPPLAYER_SERVERPLAYER )
		return "SERVER";
	return "UNKNOWN";
}

char* GetEnumPlayersInfo( LPGUID lpguidInstance, DWORD Flags )
{
	static char Buffer[256];
	
	if( lpguidInstance )
	{
		ListOfGames* pThis=GameNames;
		while( pThis )
		{
			if( pThis->SessionDescriptor.guidInstance==*lpguidInstance )
				break;
			pThis=pThis->pNext;
		}
		if( pThis )
			sprintf( Buffer, "Game=%s ",pThis->Name );
		else
			sprintf( Buffer, "Game=Unknown " );
	}
	else
	{
		sprintf( Buffer, "Game=Current " );

	}
	if( DPENUMPLAYERS_ALL&Flags )
		strcat( Buffer, "ALL " );
	if( DPENUMPLAYERS_GROUP &Flags )
		strcat( Buffer, "GROUP " );
	if( DPENUMPLAYERS_LOCAL &Flags )
		strcat( Buffer, "LOCAL " );
	if( DPENUMPLAYERS_REMOTE &Flags )
		strcat( Buffer, "REMOTE " );
	if( DPENUMPLAYERS_SERVERPLAYER &Flags )
		strcat( Buffer, "SERVER " );
	if( DPENUMPLAYERS_SESSION &Flags )
		strcat( Buffer, "SESSION " );
	if( DPENUMPLAYERS_SPECTATOR &Flags )
		strcat( Buffer, "SPECTATOR " );
	return Buffer;
}

char* GetEnumSessionFlags( DWORD Timeout, DWORD dwFlags )
{
	static char Buffer[256];
	Buffer[0]=0;
	
	if( Timeout )
	{
		sprintf( Buffer, "Timeout=%d ",Timeout );
	}

	if( 0==dwFlags )
		strcat( Buffer, "AVAILABLE " );
	if( dwFlags&DPENUMSESSIONS_ALL )
		strcat( Buffer, "ALL " );
	if( dwFlags&DPENUMSESSIONS_ASYNC )
		strcat( Buffer, "ASYNC " );
	if( dwFlags&DPENUMSESSIONS_AVAILABLE )
		strcat( Buffer, "AVAILABLE " );
	if( dwFlags&DPENUMSESSIONS_PASSWORDREQUIRED )
		strcat( Buffer, "PASSWORDREQUIRED " );
	if( dwFlags&DPENUMSESSIONS_RETURNSTATUS )
		strcat( Buffer, "RETURNSTATUS " );
	if( dwFlags&DPENUMSESSIONS_STOPASYNC )
		strcat( Buffer, "STOPASYNC " );

	return Buffer;
}

char* GetDPSessionDesc2( LPDPSESSIONDESC2 desc )
{
	static char Buffer[256];
	char Buffer1[128];
	
	if( desc->dwSize!=sizeof(DPSESSIONDESC2) )
		STOP(( "Size not set" ));
	
	Buffer[0]=0;

	if( desc->dwFlags&DPSESSION_CLIENTSERVER )
		strcat( Buffer, "CLIENTSERVER " );
	if( desc->dwFlags&DPSESSION_DIRECTPLAYPROTOCOL )
		strcat( Buffer, "DIRECTPLAYPROTOCOL " );
	if( desc->dwFlags&DPSESSION_JOINDISABLED )
		strcat( Buffer, "JOINDISABLED " );
	if( desc->dwFlags&DPSESSION_KEEPALIVE )
		strcat( Buffer, "KEEPALIVE " );
	if( desc->dwFlags&DPSESSION_MIGRATEHOST )
		strcat( Buffer, "MIGRATEHOST " );
	if( desc->dwFlags&DPSESSION_MULTICASTSERVER )
		strcat( Buffer, "MULTICASTSERVER " );
	if( desc->dwFlags&DPSESSION_NEWPLAYERSDISABLED )
		strcat( Buffer, "NEWPLAYERSDISABLED " );
	if( desc->dwFlags&DPSESSION_NODATAMESSAGES )
		strcat( Buffer, "NODATAMESSAGES " );
	if( desc->dwFlags&DPSESSION_NOMESSAGEID )
		strcat( Buffer, "NOMESSAGEID " );
	if( desc->dwFlags&DPSESSION_NOPRESERVEORDER )
		strcat( Buffer, "NOPRESERVEORDER " );
	if( desc->dwFlags&DPSESSION_OPTIMIZELATENCY )
		strcat( Buffer, "OPTIMIZELATENCY " );
	if( desc->dwFlags&DPSESSION_PASSWORDREQUIRED )
		strcat( Buffer, "PASSWORDREQUIRED " );
	if( desc->dwFlags&DPSESSION_PRIVATE )
		strcat( Buffer, "PRIVATE " );
	if( desc->dwFlags&DPSESSION_SECURESERVER )
		strcat( Buffer, "SECURESERVER " );

	if( desc->dwMaxPlayers )
	{
		sprintf( Buffer1, "MaxPlayers=%d ",desc->dwMaxPlayers  );
		strcat( Buffer, Buffer1 );
	}

	if( desc->dwCurrentPlayers )
	{
		sprintf( Buffer1, "NumPlayers=%d ",desc->dwCurrentPlayers  );
		strcat( Buffer, Buffer1 );
	}

	if( desc->lpszSessionNameA )
	{
		sprintf( Buffer1, "Name=\"%s\" ",desc->lpszSessionNameA  );
		strcat( Buffer, Buffer1 );
	}

	if( desc->lpszPasswordA && *desc->lpszPasswordA )
	{
		sprintf( Buffer1, "Password=\"%s\" ",desc->lpszPasswordA  );
		strcat( Buffer, Buffer1 );
	}

	strcat( Buffer, "Guid=\"");

	if( desc->guidApplication==GUID_NULL )
		strcat( Buffer, "NULL" );
	else if( 0==memcmp( &desc->guidApplication, &Environment.NetworkGUID, sizeof(GUID)) )
		strcat( Buffer, ApplicationName );
	else
		strcat( Buffer, "Unknown ");
	
	strcat( Buffer, "\"" );

	return Buffer;
}

char* GetDPOpenFLags( DWORD Flags )
{
	static char Buffer[64];
	Buffer[0]=0;

	if( Flags&DPOPEN_CREATE )
		strcat( Buffer, "CREATE" );
	if( Flags&DPOPEN_JOIN )
		strcat( Buffer, "JOIN" );
	if( Flags&DPOPEN_RETURNSTATUS )
		strcat( Buffer, " RETURNSTATUS" );
	return Buffer;
}

char* GetChanProp( DWORD Prop )
{
	static char Buffer[128];

	Buffer[0]=0;
	if(Prop & gosAudio_Common)
		strcat(Buffer, "HARDWARE ");
	if(Prop & gosAudio_Volume)
		strcat(Buffer, "DYNAMIC_VOLUME ");
	if(Prop & gosAudio_Frequency)
		strcat(Buffer, "DYNAMIC_FREQUENCY ");
	if(Prop & gosAudio_Panning)
		strcat(Buffer, "DYNAMIC_PANNING ");
	return Buffer;
}

char* GetSBStatus( DWORD Status )
{
	static char Buffer[128];

	if( 0==Status )
		return "NULL";
	
	Buffer[0]=0;
	if( Status & DSBSTATUS_LOCSOFTWARE )
		strcat(Buffer, "LOCSOFTWARE ");
	if( Status & DSBSTATUS_LOCHARDWARE )
		strcat(Buffer, "LOCHARDWARE ");
	if( Status & DSBSTATUS_TERMINATED )
		strcat(Buffer, "TERMINATED ");
	if( Status & DSBSTATUS_BUFFERLOST )
		strcat(Buffer, "LOST ");
	if( Status & DSBSTATUS_LOOPING )
		strcat(Buffer, "LOOPING ");
	if( Status & DSBSTATUS_PLAYING )
		strcat(Buffer, "PLAYING ");
	if( Buffer[0]==0 )
		sprintf( Buffer, "0x%x",Status );

	return Buffer;
}

char* GetQSupport( ULONG Support )
{
	switch( Support )
	{
		case 0:
			return "None";
		case KSPROPERTY_SUPPORT_GET:
			return "GET";
		case KSPROPERTY_SUPPORT_SET:
			return "SET";
		case (KSPROPERTY_SUPPORT_GET|KSPROPERTY_SUPPORT_SET):
			return "GET/SET";
		default:
			return "Unknown";	
	}
}

char* GetWaveFormat( char* Buffer, LPCWAVEFORMATEX lpcfxFormat )
{
	if (!lpcfxFormat)
		return "NULL";
	if( lpcfxFormat->wFormatTag!=WAVE_FORMAT_PCM )
	{
		char* format="Unknown";

		if( lpcfxFormat->wFormatTag==WAVE_FORMAT_ADPCM )
			format="ADPCM";

		sprintf( Buffer, "(%s %d-bit, %d Channel, %dHz, %dbps, cbSize=%d)",
			format,
			lpcfxFormat->wBitsPerSample,
			lpcfxFormat->nChannels,
			lpcfxFormat->nSamplesPerSec,
			lpcfxFormat->nAvgBytesPerSec,
			lpcfxFormat->cbSize
			);
	}
	else
	{
		sprintf( Buffer, "(PCM %d-bit, %d Channel, %dHz, %dbps)",
			lpcfxFormat->wBitsPerSample,
			lpcfxFormat->nChannels,
			lpcfxFormat->nSamplesPerSec,
			lpcfxFormat->nAvgBytesPerSec
			);
	}
	return Buffer;
}

char* GetDIInputFormat( LPCDIDATAFORMAT Format )
{
	if( Format==&c_dfDIKeyboard )
		return "c_dfDIKeyboard";
	else if( Format==&c_dfDIMouse )
		return "c_dfDIMouse";
	else if( Format==&c_dfDIJoystick )
		return "c_dfDIJoystick";
	else if( Format== &c_dfDIJoystick2 )
		return "c_dfDIJoystick2";
	else
		return "Unknown";
}

char* GetDIDevType( DWORD DevType )
{
#ifdef DI8DEVTYPE_MOUSE
	switch( DevType&255 )
	{
		case DI8DEVTYPE_MOUSE:
			return "MOUSE";
		case DI8DEVTYPE_KEYBOARD:
			return "KEYBOARD";
		case DI8DEVTYPE_JOYSTICK:
			return "JOYSTICK";
		case DI8DEVTYPE_DEVICE:
			return "DEVICE";
		case 0:
			return "ALL";
	}
#else
	switch( DevType&255 )
	{
		case DIDEVTYPE_MOUSE:
			return "MOUSE";
		case DIDEVTYPE_KEYBOARD:
			return "KEYBOARD";
		case DIDEVTYPE_JOYSTICK:
			return "JOYSTICK";
		case DIDEVTYPE_DEVICE:
			return "DEVICE";
		case 0:
			return "ALL";
	}
#endif
	return "Unknown";
}

char* GetDSoundCoopLevel( DWORD Level )
{
	switch( Level )
	{
		case DSSCL_EXCLUSIVE:
			return "EXCLUSIVE";
		case DSSCL_NORMAL:
			return "NORMAL";
		case DSSCL_PRIORITY:
			return "PRIORITY";
		case DSSCL_WRITEPRIMARY:
			return "WRITEPRIMARY";
	}
	return "Unknown";
}

char* GetFlipFlags( DWORD Flags )
{
	static char Buffer[128];

	Buffer[0]=0;
	if(Flags & DDFLIP_WAIT)
		strcat(Buffer, "WAIT ");
	if(Flags & DDFLIP_EVEN)
		strcat(Buffer, "EVEN ");
	if(Flags & DDFLIP_ODD)
		strcat(Buffer, "ODD ");
	return Buffer;
}

char* GetWrappingMode( DWORD Value )
{
	switch( Value )
	{
		case D3DTADDRESS_WRAP:
			return "WRAP";
		case D3DTADDRESS_MIRROR:
			return "MIRROR";
		case D3DTADDRESS_CLAMP:
			return "CLAMP";
		case D3DTADDRESS_BORDER:
			return "BORDER";
	}
	return "Unknown";
}

char* GetTextureMAGFilter( DWORD Value )
{
	switch( Value )
	{
		case D3DTFG_POINT:
			return "POINT";
		case D3DTFG_LINEAR:
			return "LINEAR";
		case D3DTFG_FLATCUBIC:
			return "FLATCUBIC";
		case D3DTFG_GAUSSIANCUBIC:
			return "GAUSSIANCUBIC";
		case D3DTFG_ANISOTROPIC:
			return "ANISOTROPIC";
	}
	return "Unknown";
}

char* GetTextureMINFilter( DWORD Value )
{
	switch( Value )
	{
		case D3DTFN_POINT:
			return "POINT";
		case D3DTFN_LINEAR:
			return "LINEAR";
		case D3DTFN_ANISOTROPIC:
			return "ANISOTROPIC";
	}
	return "Unknown";
}

char* GetTextureMIPFilter( DWORD Value )
{
	switch( Value )
	{
		case D3DTFP_NONE:
			return "NONE";
		case D3DTFP_POINT:
			return "POINT";
		case D3DTFP_LINEAR:
			return "LINEAR";
	}
	return "Unknown";
}

char* GetTextureArgumentFlags( DWORD Value )
{
	static char Buffer[128];	
	switch( Value&(D3DTA_CURRENT|D3DTA_DIFFUSE|D3DTA_TEXTURE|D3DTA_TFACTOR) )
	{
		case D3DTA_CURRENT:
			strcpy( Buffer, "CURRENT" );
			break;
		case D3DTA_DIFFUSE:
			strcpy( Buffer, "DIFFUSE" );
			break;
		case D3DTA_TEXTURE:
			strcpy( Buffer, "TEXTURE" );
			break;
		case D3DTA_TFACTOR:
			strcpy( Buffer, "TFACTOR" );
			break;
		default:
			strcpy( Buffer, "Unknown");
	}
	if( Value&D3DTA_ALPHAREPLICATE )
		strcat( Buffer, "+ALPHAREPLICATE" );
	if( Value&D3DTA_COMPLEMENT )
		strcat( Buffer, "+COMPLEMENT" );
	return Buffer;
}

char* GetTextureOp( DWORD Value )
{
	switch( Value )
	{
		case D3DTOP_DISABLE:
			return "DISABLE";
		case D3DTOP_SELECTARG1:
			return "SELECTARG1";
		case D3DTOP_SELECTARG2:
			return "SELECTARG2";
		case D3DTOP_MODULATE:
			return "MODULATE";
		case D3DTOP_MODULATE2X:
			return "MODULATE2X";
		case D3DTOP_MODULATE4X:
			return "MODULATE4X";
		case D3DTOP_ADD:
			return "ADD";
		case D3DTOP_ADDSIGNED:
			return "ADDSIGNED";
		case D3DTOP_SUBTRACT:
			return "SUBTRACT";
		case D3DTOP_ADDSMOOTH:
			return "ADDSMOOTH";
		case D3DTOP_BLENDDIFFUSEALPHA:
			return "BLENDDIFFUSEALPHA";
		case D3DTOP_BLENDTEXTUREALPHA:
			return "BLENDTEXTUREALPHA";
		case D3DTOP_BLENDFACTORALPHA:
			return "BLENDFACTORALPHA";
		case D3DTOP_BLENDTEXTUREALPHAPM:
			return "BLENDTEXTUREALPHAPM";
		case D3DTOP_BLENDCURRENTALPHA:
			return "BLENDCURRENTALPHA";
		case D3DTOP_PREMODULATE:
			return "PREMODULATE";
		case D3DTOP_MODULATEALPHA_ADDCOLOR:
			return "MODULATEALPHA_ADDCOLOR";
		case D3DTOP_MODULATECOLOR_ADDALPHA:
			return "MODULATECOLOR_ADDALPHA";
		case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
			return "MODULATEINVALPHA_ADDCOLOR";
		case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
			return "MODULATEINVCOLOR_ADDALPHA";
		case D3DTOP_BUMPENVMAP:
			return "BUMPENVMAP";
		case D3DTOP_BUMPENVMAPLUMINANCE:
			return "BUMPENVMAPLUMINANCE";
		case D3DTOP_DOTPRODUCT3:
			return "DOTPRODUCT3";
	}
	return "Unknown";
}

char* GetStageSet( D3DTEXTURESTAGESTATETYPE dwState, DWORD dwValue )
{
	static char Buffer[128];
	float tfloat;
	*(DWORD*)&tfloat=dwValue;
	switch( dwState )
	{
		case D3DTSS_COLOROP:
			wsprintf( Buffer, "COLOROP=%s",GetTextureOp(dwValue) );
			break;
		case D3DTSS_COLORARG1:
			wsprintf( Buffer, "COLORARG1=%s",GetTextureArgumentFlags(dwValue) );
			break;
		case D3DTSS_COLORARG2:
			wsprintf( Buffer, "COLORARG2=%s",GetTextureArgumentFlags(dwValue) );
			break;
		case D3DTSS_ALPHAOP:
			wsprintf( Buffer, "ALPHAOP=%s",GetTextureOp(dwValue) );
			break;
		case D3DTSS_ALPHAARG1:
			wsprintf( Buffer, "ALPHAARG1=%s",GetTextureArgumentFlags(dwValue) );
			break;
		case D3DTSS_ALPHAARG2:
			wsprintf( Buffer, "ALPHAARG2=%s",GetTextureArgumentFlags(dwValue) );
			break;
		case D3DTSS_BUMPENVMAT00:
			sprintf( Buffer, "BUMPENVMAT00=%f",(double)tfloat );
			break;
		case D3DTSS_BUMPENVMAT01:
			sprintf( Buffer, "BUMPENVMAT01=%f",(double)tfloat );
			break;
		case D3DTSS_BUMPENVMAT10:
			sprintf( Buffer, "BUMPENVMAT10=%f",(double)tfloat );
			break;
		case D3DTSS_BUMPENVMAT11:
			sprintf( Buffer, "BUMPENVMAT11=%f",(double)tfloat );
			break;
		case D3DTSS_TEXCOORDINDEX:
			wsprintf( Buffer, "TEXCOORDINDEX=%d",dwValue );
			break;
		case D3DTSS_ADDRESS:
			wsprintf( Buffer, "ADDRESS=%s",GetWrappingMode(dwValue) );
			break;
		case D3DTSS_ADDRESSU:
			wsprintf( Buffer, "ADDRESSU=%s",GetWrappingMode(dwValue) );
			break;
		case D3DTSS_ADDRESSV:
			wsprintf( Buffer, "ADDRESSV=%s",GetWrappingMode(dwValue) );
			break;
		case D3DTSS_BORDERCOLOR:
			wsprintf( Buffer, "BORDERCOLOR=0x%x",dwValue );
			break;
		case D3DTSS_MAGFILTER:
			wsprintf( Buffer, "MAGFILTER=%s",GetTextureMAGFilter(dwValue) );
			break;
		case D3DTSS_MINFILTER:
			wsprintf( Buffer, "MINFILTER=%s",GetTextureMINFilter(dwValue) );
			break;
		case D3DTSS_MIPFILTER:
			wsprintf( Buffer, "MIPFILTER=%s",GetTextureMIPFilter(dwValue) );
			break;
		case D3DTSS_MIPMAPLODBIAS:
			wsprintf( Buffer, "MIPMAPLODBIAS=%f",(double)tfloat );
			break;
		case D3DTSS_MAXMIPLEVEL:
			wsprintf( Buffer, "MAXMIPLEVEL=%d",dwValue );
			break;
		case D3DTSS_MAXANISOTROPY:
			wsprintf( Buffer, "MAXANISOTROPY=%d",dwValue );
			break;
		case D3DTSS_BUMPENVLSCALE:
			wsprintf( Buffer, "BUMPENVLSCALE=%f",(double)tfloat );
			break;
		case D3DTSS_BUMPENVLOFFSET:
			wsprintf( Buffer, "BUMPENVLOFFSET=%f",(double)tfloat );
			break;
		default:
			wsprintf( Buffer, "Unknown" );
	}
	return Buffer;
}

char* GetTextureAddress( DWORD Value )
{
	switch( Value )
	{
		case 0:
			return "NONE";
		case D3DWRAP_U:
			return "WRAPU";
		case D3DWRAP_V:
			return "WRAPV";
		case D3DWRAP_U+D3DWRAP_V:
			return "WRAPU+V";
	}
	return "Unknown";
}

char* GetStencilOp( DWORD Value )
{
	switch( Value )
	{
		case D3DSTENCILOP_KEEP:
			return "KEEP";
		case D3DSTENCILOP_ZERO:
			return "ZERO";
		case D3DSTENCILOP_REPLACE:
			return "REPLACE";
		case D3DSTENCILOP_INCRSAT:
			return "INCRSAT";
		case D3DSTENCILOP_DECRSAT:
			return "DECRSAT";
		case D3DSTENCILOP_INVERT:
			return "INVER";
		case D3DSTENCILOP_INCR:
			return "INCR";
		case D3DSTENCILOP_DECR:
			return "DECR";
	}
	return "Unknown";
}

char* GetVertexType( char* Buffer, DWORD VertexType )
{
	if( VertexType==D3DFVF_TLVERTEX )
		return "D3DTLVERTEX ";	
	if( VertexType==D3DFVF_LVERTEX )
		return "D3DLVERTEX ";	
	if( VertexType==D3DFVF_VERTEX )
		return "D3DVERTEX ";	
	strcpy( Buffer,"fvf( ");
	if( VertexType&D3DFVF_XYZ )
		strcat(Buffer,"XYZ ");
	if( VertexType&D3DFVF_XYZRHW )
		strcat(Buffer,"XYZRHW ");
	if( VertexType&D3DFVF_NORMAL )
		strcat(Buffer,"NORMAL ");
	if( VertexType&D3DFVF_DIFFUSE )
		strcat(Buffer,"DIFFUSE ");
	if( VertexType&D3DFVF_SPECULAR )
		strcat(Buffer,"SPECULAR ");
	if( (VertexType&D3DFVF_TEXCOUNT_MASK)==D3DFVF_TEX1 )
		strcat(Buffer,"TEX1 ");
	if( (VertexType&D3DFVF_TEXCOUNT_MASK)==D3DFVF_TEX2 )
		strcat(Buffer,"TEX2 ");
	if( (VertexType&D3DFVF_TEXCOUNT_MASK)==D3DFVF_TEX3 )
		strcat(Buffer,"TEX3 ");
	if( (VertexType&D3DFVF_TEXCOUNT_MASK)==D3DFVF_TEX4 )
		strcat(Buffer,"TEX4 ");
	if( (VertexType&D3DFVF_TEXCOUNT_MASK)==D3DFVF_TEX5 )
		strcat(Buffer,"TEX5 ");
	if( (VertexType&D3DFVF_TEXCOUNT_MASK)==D3DFVF_TEX6 )
		strcat(Buffer,"TEX6 ");
	if( (VertexType&D3DFVF_TEXCOUNT_MASK)==D3DFVF_TEX7 )
		strcat(Buffer,"TEX7 ");
	if( (VertexType&D3DFVF_TEXCOUNT_MASK)==D3DFVF_TEX8 )
		strcat(Buffer,"TEX8 ");
	strcat( Buffer, ")" );
	return Buffer;
}

char* GetFillMode( DWORD Value )
{
	switch( Value )
	{
		case D3DFILL_POINT:
			return "D3DFILL_POINT";
		case D3DFILL_WIREFRAME:
			return "D3DFILL_WIREFRAME";
		case D3DFILL_SOLID:
			return "D3DFILL_SOLID";
	}
	return "Unknown";
}

char* GetShadeMode( DWORD Value )
{
	switch( Value )
	{
		case D3DSHADE_FLAT:
			return "D3DSHADE_FLAT";
		case D3DSHADE_GOURAUD:
			return "D3DSHADE_GOURAUD";
		case D3DSHADE_PHONG:
			return "D3DSHADE_PHONG";
	}
	return "Unknown";
}

char* GetTextureFilter( DWORD Value )
{
	switch( Value )
	{
		case D3DFILTER_NEAREST:
			return "NEAREST";
		case D3DFILTER_LINEAR:
			return "LINEAR";
		case D3DFILTER_MIPNEAREST:
			return "MIPNEAREST";
		case D3DFILTER_MIPLINEAR:
			return "MIPLINEAR";
		case D3DFILTER_LINEARMIPNEAREST:
			return "LINEARMIPNEAREST";
		case D3DFILTER_LINEARMIPLINEAR:
			return "LINEARMIPLINEAR";
	}
	return "Unknown";
}

char* GetBlendMode( DWORD Value )
{
	switch( Value )
	{
		case D3DBLEND_ZERO:
			return "ZERO";
		case D3DBLEND_ONE:
			return "ONE";
		case D3DBLEND_SRCCOLOR:
			return "SRCCOLOR";
		case D3DBLEND_INVSRCCOLOR:
			return "INVSRCCOLOR";
		case D3DBLEND_SRCALPHA:
			return "SRCALPHA";
		case D3DBLEND_INVSRCALPHA:
			return "INVSRCALPHA";
		case D3DBLEND_DESTALPHA:
			return "DESTALPHA";
		case D3DBLEND_INVDESTALPHA:
			return "INVDESTALPHA";
		case D3DBLEND_DESTCOLOR:
			return "DESTCOLOR";
		case D3DBLEND_INVDESTCOLOR:
			return "INVDESTCOLOR";
		case D3DBLEND_SRCALPHASAT:
			return "SRCALPHASAT";
		case D3DBLEND_BOTHSRCALPHA:
			return "BOTHSRCALPHA";
		case  D3DBLEND_BOTHINVSRCALPHA:
			return " D3DBLEND_BOTHINVSRCALPHA";
	}
	return "Unknown";
}

char* GetTextureBlendMode( DWORD Value )
{
	switch( Value )
	{
		case D3DTBLEND_DECAL:
			return "DECAL";
		case D3DTBLEND_MODULATE:
			return "MODULATE";
		case D3DTBLEND_DECALALPHA:
			return "DECALALPHA";
		case D3DTBLEND_MODULATEALPHA:
			return "MODULATEALPHA";
		case D3DTBLEND_DECALMASK:
			return "DECALMASK";
		case D3DTBLEND_MODULATEMASK:
			return "MODULATEMASK";
		case D3DTBLEND_COPY:
			return "COPY";
	}
	return "Unknown";
}

char* GetCullMode( DWORD Value )
{
	switch( Value )
	{
		case D3DCULL_NONE:
			return "NONE";
		case D3DCULL_CW:
			return "CW";
		case D3DCULL_CCW:
			return "CCW";
	}
	return "Unknown";
}

char* GetCompareMode( DWORD Value )
{
	switch( Value )
	{
		case D3DCMP_NEVER:
			return "NEVER";
		case D3DCMP_LESS:
			return "LESS";
		case D3DCMP_EQUAL:
			return "EQUAL";
		case D3DCMP_LESSEQUAL:
			return "LESSEQUAL";
		case D3DCMP_GREATER:
			return "GREATER";
		case D3DCMP_NOTEQUAL:
			return "NOTEQUAL";
		case D3DCMP_GREATEREQUAL:
			return "GREATEREQUAL";
		case D3DCMP_ALWAYS:
			return "ALWAYS";
	}
	return "Unknown";
}

char* GetFogMode( DWORD Value )
{
	switch( Value )
	{
		case D3DFOG_NONE:
			return "NONE";
		case D3DFOG_EXP:
			return "EXP";
		case D3DFOG_EXP2:
			return "EXP2";
		case D3DFOG_LINEAR:
			return "LINEAR";
	}
	return "Unknown";
}

//
// Describe the render state
//
char* GetRenderState( DWORD RenderState, DWORD Value )
{
	static char Buffer[256];	
	float tfloat;
	*(DWORD*)&tfloat=Value;
	switch( RenderState )
	{
		case D3DRENDERSTATE_TEXTUREHANDLE:
			wsprintf( Buffer, "TEXTUREHANDLE=0x%x", Value);
			break;
		case D3DRENDERSTATE_ANTIALIAS:
			wsprintf( Buffer, "ANTIALIAS=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_TEXTUREADDRESS:
			wsprintf( Buffer, "TEXTUREADDRESS=%s", GetWrappingMode(Value));
			break;
		case D3DRENDERSTATE_TEXTUREPERSPECTIVE:
			wsprintf( Buffer, "TEXTUREPERSPECTIVE=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_WRAPU:
			wsprintf( Buffer, "WRAPU=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_WRAPV:
			wsprintf( Buffer, "WRAPV=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_ZENABLE:
			wsprintf( Buffer, "ZENABLE=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_FILLMODE:
			wsprintf( Buffer, "FILLMODE=%s", GetFillMode(Value));
			break;
		case D3DRENDERSTATE_SHADEMODE:
			wsprintf( Buffer, "SHADEMODE=%s", GetShadeMode(Value));
			break;
		case D3DRENDERSTATE_LINEPATTERN:
			wsprintf( Buffer, "LINEPATTERN=0x%x", Value);
			break;
		case D3DRENDERSTATE_MONOENABLE:
			wsprintf( Buffer, "MONOENABLE=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_ROP2:
			wsprintf( Buffer, "ROP2=%d", Value);
			break;
		case D3DRENDERSTATE_PLANEMASK:
			wsprintf( Buffer, "PLANEMASK=0x%x", Value);
			break;
		case D3DRENDERSTATE_ZWRITEENABLE:
			wsprintf( Buffer, "ZWRITEENABLE=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_ALPHATESTENABLE:
			wsprintf( Buffer, "ALPHATESTENABLE=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_LASTPIXEL:
			wsprintf( Buffer, "LASTPIXEL=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_TEXTUREMAG:
			wsprintf( Buffer, "TEXTUREMAG=%s", GetTextureFilter(Value));
			break;
		case D3DRENDERSTATE_TEXTUREMIN:
			wsprintf( Buffer, "TEXTUREMIN=%s", GetTextureFilter(Value));
			break;
		case D3DRENDERSTATE_SRCBLEND:
			wsprintf( Buffer, "SRCBLEND=%s", GetBlendMode(Value));
			break;
		case D3DRENDERSTATE_DESTBLEND:
			wsprintf( Buffer, "DESTBLEND=%s", GetBlendMode(Value));
			break;
		case D3DRENDERSTATE_TEXTUREMAPBLEND:
			wsprintf( Buffer, "TEXTUREMAPBLEND=%s", GetTextureBlendMode(Value));
			break;
		case D3DRENDERSTATE_CULLMODE:
			wsprintf( Buffer, "CULLMODE=%s", GetCullMode(Value));
			break;
		case D3DRENDERSTATE_ZFUNC:
			wsprintf( Buffer, "ZFUNC=%s", GetCompareMode(Value));
			break;
		case D3DRENDERSTATE_ALPHAREF:
			wsprintf( Buffer, "ALPHAREF=0x%x", Value);
			break;
		case D3DRENDERSTATE_ALPHAFUNC:
			wsprintf( Buffer, "ALPHAFUNC=%s", GetCompareMode(Value));
			break;
		case D3DRENDERSTATE_DITHERENABLE:
			wsprintf( Buffer, "DITHERENABLE=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_ALPHABLENDENABLE:
			wsprintf( Buffer, "ALPHABLENDENABLE=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_FOGENABLE:
			wsprintf( Buffer, "FOGENABLE=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_SPECULARENABLE:
			wsprintf( Buffer, "SPECULARENABLE=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_ZVISIBLE:
			wsprintf( Buffer, "ZVISIBLE=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_SUBPIXEL:
			wsprintf( Buffer, "SUBPIXEL=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_SUBPIXELX:
			wsprintf( Buffer, "SUBPIXELX=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_STIPPLEDALPHA:
			wsprintf( Buffer, "STIPPLEDALPHA=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_FOGCOLOR:
			wsprintf( Buffer, "FOGCOLOR=0x%x", Value);
			break;
		case D3DRENDERSTATE_FOGTABLEMODE:
			wsprintf( Buffer, "FOGTABLEMODE=%s", GetFogMode(Value));
			break;
		case D3DRENDERSTATE_FOGTABLESTART:
			sprintf( Buffer, "FOGTABLESTART=%f", (double)tfloat );
			break;
		case D3DRENDERSTATE_FOGTABLEEND:
			sprintf( Buffer, "FOGTABLEEND=%f", (double)tfloat);
			break;
		case D3DRENDERSTATE_FOGTABLEDENSITY:
			sprintf( Buffer, "FOGTABLEDENSITY=%f", (double)tfloat);
			break;
		case D3DRENDERSTATE_STIPPLEENABLE:
			wsprintf( Buffer, "STIPPLEENABLE=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_EDGEANTIALIAS:
			wsprintf( Buffer, "EDGEANTIALIAS=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_COLORKEYENABLE:
			wsprintf( Buffer, "COLORKEYENABLE=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_BORDERCOLOR:
			wsprintf( Buffer, "BORDERCOLOR=0x%x", Value);
			break;
		case D3DRENDERSTATE_TEXTUREADDRESSU:
			wsprintf( Buffer, "TEXTUREADDRESSU=%s", GetTextureAddress(Value));
			break;
		case D3DRENDERSTATE_TEXTUREADDRESSV:
			wsprintf( Buffer, "TEXTUREADDRESSV=%s", GetTextureAddress(Value));
			break;
		case D3DRENDERSTATE_MIPMAPLODBIAS:
			sprintf( Buffer, "MIPMAPLODBIAS=%f", (double)tfloat);
			break;
		case D3DRENDERSTATE_ZBIAS:
			wsprintf( Buffer, "ZBIAS=%d", Value);
			break;
		case D3DRENDERSTATE_RANGEFOGENABLE:
			wsprintf( Buffer, "RANGEFOGENABLE=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_ANISOTROPY:
			wsprintf( Buffer, "ANISOTROPY=0x%x", Value);
			break;
		case D3DRENDERSTATE_FLUSHBATCH:
			wsprintf( Buffer, "FLUSHBATCH");
			break;
		case D3DRENDERSTATE_TRANSLUCENTSORTINDEPENDENT:
			wsprintf( Buffer, "TRANSLUCENTSORTINDEPENDENT=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_STENCILENABLE:
			wsprintf( Buffer, "STENCILENABLE=%s", Value ? "TRUE" : "FALSE");
			break;
		case D3DRENDERSTATE_STENCILFAIL:
			wsprintf( Buffer, "STENCILFAIL=%s", GetStencilOp(Value) );
			break;
		case D3DRENDERSTATE_STENCILZFAIL:
			wsprintf( Buffer, "STENCILZFAIL=%s", GetStencilOp(Value) );
			break;
		case D3DRENDERSTATE_STENCILPASS:
			wsprintf( Buffer, "RANGEFOGENABLE=%s", GetStencilOp(Value) );
			break;
		case D3DRENDERSTATE_STENCILFUNC:
			wsprintf( Buffer, "STENCILFUNC=%s", GetCompareMode(Value) );
			break;
		case D3DRENDERSTATE_STENCILREF:
			wsprintf( Buffer, "STENCILREF=0x%x", Value );
			break;
		case D3DRENDERSTATE_STENCILMASK:
			wsprintf( Buffer, "STENCILMASK=0x%x", Value );
			break;
		case D3DRENDERSTATE_STENCILWRITEMASK:
			wsprintf( Buffer, "STENCILWRITEMASK=0x%x", Value );
			break;
		case D3DRENDERSTATE_TEXTUREFACTOR:
			wsprintf( Buffer, "TEXTUREFACTOR=0x%x", Value );
			break;
		case D3DRENDERSTATE_LIGHTING:
			wsprintf( Buffer, "LIGHTING=%s", (Value ? "TRUE" : "FALSE") );
			break;
		case D3DRENDERSTATE_LOCALVIEWER:
			wsprintf( Buffer, "LOCALVIEWER=%s", (Value ? "TRUE" : "FALSE") );
			break;
		case D3DRENDERSTATE_EXTENTS:
			wsprintf( Buffer, "EXTENTS=0x%x", Value );
			break;
		case D3DRENDERSTATE_CLIPPING:
			wsprintf( Buffer, "CLIPPING=%s", (Value ? "TRUE" : "FALSE") );
			break;
		case D3DRENDERSTATE_AMBIENT:
			wsprintf( Buffer, "AMBIENT=0x%x", Value );
			break;
		case D3DRENDERSTATE_WRAP0:
			wsprintf( Buffer, "WRAP0=0x%x", Value );
			break;
		case D3DRENDERSTATE_WRAP1:
			wsprintf( Buffer, "WRAP1=0x%x", Value );
			break;
		case D3DRENDERSTATE_NORMALIZENORMALS:
			wsprintf( Buffer, "NORMALIZENORMALS=0x%x", Value );
			break;
		case D3DRENDERSTATE_VERTEXBLEND:
			wsprintf( Buffer, "VERTEXBLEND=0x%x", Value );
			break;
		default:
			wsprintf( Buffer, "Unknown (0x%x)=0x%x", RenderState, Value );
	}
	return Buffer;
}


//
// Describe the DrawIndexePrimitive
//
char* GetDrawIndexedPrimitiveData( D3DPRIMITIVETYPE d3dptPrimitiveType, DWORD dwVertexTypeDesc, LPVOID lpvVertices, DWORD dwVertexCount, LPWORD lpwIndices, DWORD dwIndexCount, DWORD dwFlags )
{
	static char Buffer[128];
	char vBuffer[64];
	char VertexBuffer[64];

	switch( d3dptPrimitiveType )
	{
		case D3DPT_POINTLIST:
			strcpy(Buffer, "POINTLIST");
			break;
		case D3DPT_LINELIST:
			strcpy(Buffer, "LINELIST");
			break;
		case D3DPT_LINESTRIP:
			strcpy(Buffer, "LINESTRIP");
			break;
		case D3DPT_TRIANGLELIST:
			strcpy(Buffer, "TRIANGLELIST");
			break;
		case D3DPT_TRIANGLESTRIP:
			strcpy(Buffer, "TRIANGLESTRIP");
			break;
		case D3DPT_TRIANGLEFAN:
			strcpy(Buffer, "TRIANGLEFAN");
			break;
		default:
			strcpy(Buffer,"UnknownList");
	}

	wsprintf(vBuffer, " of %d %swith %d indices ",dwVertexCount,GetVertexType(VertexBuffer,dwVertexTypeDesc),dwIndexCount );

	strcat( Buffer, vBuffer );
	
	if( dwFlags&D3DDP_WAIT )
		strcat( Buffer, "D3DDP_WAIT ");

	return Buffer;
}

//
// Describe the DrawPrimitive
//
char* GetDrawPrimitiveData( D3DPRIMITIVETYPE dptPrimitiveType, DWORD dvtVertexType, LPVOID lpvVertices, DWORD dwVertexCount, DWORD dwFlags )
{
	static char Buffer[128];
	char vBuffer[64];
	char VertexBuffer[64];

	switch( dptPrimitiveType )
	{
		case D3DPT_POINTLIST:
			strcpy(Buffer, "POINTLIST");
			break;
		case D3DPT_LINELIST:
			strcpy(Buffer, "LINELIST");
			break;
		case D3DPT_LINESTRIP:
			strcpy(Buffer, "LINESTRIP");
			break;
		case D3DPT_TRIANGLELIST:
			strcpy(Buffer, "TRIANGLELIST");
			break;
		case D3DPT_TRIANGLESTRIP:
			strcpy(Buffer, "TRIANGLESTRIP");
			break;
		case D3DPT_TRIANGLEFAN:
			strcpy(Buffer, "TRIANGLEFAN");
			break;
		default:
			strcpy(Buffer,"UnknownList");
	}

	wsprintf(vBuffer, " of %d %s",dwVertexCount,GetVertexType(VertexBuffer,dvtVertexType) );

	strcat( Buffer, vBuffer );
	
	if( dwFlags&D3DDP_WAIT )
		strcat( Buffer, "D3DDP_WAIT ");

	return Buffer;
}

//
// Viewport clear parameters
//
char* GetClearArea( DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags )
{
	static char Buffer[128];

	switch( dwCount )
	{
		case 0:
			strcpy( Buffer, "Whole Vieport");
			break;
		case 1:
			wsprintf( Buffer, "%d,%d to %d,%d",lpRects->x1,lpRects->y1,lpRects->x2,lpRects->y2 );
			break;
		default:
			wsprintf( Buffer, "%d Rectangles",lpRects);
			break;
	}	
	if( dwFlags&D3DCLEAR_TARGET )
		strcat( Buffer, " Background");
	if( dwFlags&D3DCLEAR_ZBUFFER )
		strcat( Buffer, " ZBuffer");
	return Buffer;
}

//
// BltFast flags
//
char* GetBltFastFlags( DWORD dwTrans )
{
	static char Buffer[128];
	Buffer[0]=0;

	if( dwTrans & DDBLTFAST_DESTCOLORKEY )
		strcat( Buffer, "DESTCOLORKEY " );
	if( dwTrans & DDBLTFAST_NOCOLORKEY )
		strcat( Buffer, "NOCOLORKEY " );
	if( dwTrans & DDBLTFAST_SRCCOLORKEY )
		strcat( Buffer, "SRCCOLORKEY " );
	if( dwTrans & DDBLTFAST_WAIT )
		strcat( Buffer, "WAIT " );
	return Buffer;
}

//
// Blt flags
//
char* GetBltFlags( DWORD flags, LPDDBLTFX pfx )
{
	static char Buffer[128];
	Buffer[0]=0;

	if( flags & DDBLT_ALPHADEST )
		strcat( Buffer, "ALPHADEST " );
	if( flags & DDBLT_ALPHADESTCONSTOVERRIDE )
		strcat( Buffer, "ALPHADESTCONSTOVERRIDE " );
	if( flags & DDBLT_ALPHADESTNEG )
		strcat( Buffer, "ALPHADESTNEG " );
	if( flags & DDBLT_ALPHADESTSURFACEOVERRIDE )
		strcat( Buffer, "ALPHADESTSURFACEOVERRIDE " );
	if( flags & DDBLT_ALPHAEDGEBLEND )
		strcat( Buffer, "ALPHAEDGEBLEND " );
	if( flags & DDBLT_ALPHASRC )
		strcat( Buffer, "ALPHASRC " );
	if( flags & DDBLT_ALPHASRCCONSTOVERRIDE )
		strcat( Buffer, "ALPHASRCCONSTOVERRIDE " );
	if( flags & DDBLT_ALPHASRCNEG )
		strcat( Buffer, "ALPHASRCNEG " );
	if( flags & DDBLT_ALPHASRCSURFACEOVERRIDE )
		strcat( Buffer, "ALPHASRCSURFACEOVERRIDE " );
	if( flags & DDBLT_ASYNC )
		strcat( Buffer, "ASYNC " );
	if( flags & DDBLT_COLORFILL )
		sprintf(&Buffer[strlen(Buffer)], "COLORFILL 0x%6.6x ",pfx->dwFillColor);
	if( flags & DDBLT_DDFX  )
		strcat( Buffer, "DDFX " );
	if( flags & DDBLT_DDROPS  )
		strcat( Buffer, "DDROPS " );
	if( flags & DDBLT_DEPTHFILL  )
		strcat( Buffer, "DEPTHFILL " );
	if( flags & DDBLT_KEYDEST  )
		strcat( Buffer, "KEYDEST " );
	if( flags & DDBLT_KEYDESTOVERRIDE  )
		strcat( Buffer, "KEYDESTOVERRIDE " );
	if( flags & DDBLT_KEYSRC  )
		strcat( Buffer, "KEYSRC " );
	if( flags & DDBLT_KEYSRCOVERRIDE  )
		strcat( Buffer, "KEYSRCOVERRIDE " );
	if( flags & DDBLT_ROP  )
		strcat( Buffer, "ROP " );
	if( flags & DDBLT_ROTATIONANGLE  )
		strcat( Buffer, "ROTATIONANGLE " );
	if( flags & DDBLT_WAIT  )
		strcat( Buffer, "WAIT " );
	if( flags & DDBLT_ZBUFFER  )
		strcat( Buffer, "ZBUFFER " );
	if( flags & DDBLT_ZBUFFERDESTCONSTOVERRIDE  )
		strcat( Buffer, "ZBUFFERDESTCONSTOVERRIDE " );
	if( flags & DDBLT_ZBUFFERDESTOVERRIDE  )
		strcat( Buffer, "ZBUFFERDESTOVERRIDE " );
	if( flags & DDBLT_ZBUFFERSRCCONSTOVERRIDE  )
		strcat( Buffer, "ZBUFFERSRCCONSTOVERRIDE " );
	if( flags & DDBLT_ZBUFFERSRCOVERRIDE  )
		strcat( Buffer, "ZBUFFERSRCOVERRIDE " );
	return Buffer;
}

//
// Returns a string decribing the rectangle
//
char* GetRectangle( char* Buffer, LPRECT lp )
{
	if( !lp )
		strcpy( Buffer,"complete" );
	else
		sprintf( Buffer, "%d,%d (%dx%d)",lp->left,lp->top,lp->right-lp->left,lp->bottom-lp->top );
	return Buffer;
}

//
// Returns a string describing the BltFast
//
char* GetBltFastInformation( IDirectDrawSurface7* lpdds4, DWORD dwX, DWORD dwY, IDirectDrawSurface7* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans )
{
	static char Buffer[256];
	char RectBuffer[32];
	sprintf( Buffer,"0x%x at %d,%d, Src=0x%x at %s Flags:%s",(int)lpdds4,(int)dwX,(int)dwY,(int)lpDDSrcSurface,GetRectangle(RectBuffer,lpSrcRect),GetBltFastFlags(dwTrans) );
	return Buffer;
}

//
// Returns a string describing the Blt
//
char* GetBltInformation( IDirectDrawSurface7* lpdds4, LPRECT lpDestRect, IDirectDrawSurface7* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx )
{
	static char Buffer[256];
	char RectBuffer1[32];
	char RectBuffer2[32];
	if( dwFlags & DDBLT_COLORFILL )
		sprintf( Buffer,"Dest=0x%x at %s %s",(int)lpdds4,GetRectangle(RectBuffer1,lpDestRect),GetBltFlags(dwFlags,lpDDBltFx) );
	else
		sprintf( Buffer,"Dest=0x%x at %s, Src=0x%x at %s Flags:%s",(int)lpdds4,GetRectangle(RectBuffer1,lpDestRect),lpDDSrcSurface,GetRectangle(RectBuffer2,lpSrcRect),GetBltFlags(dwFlags,lpDDBltFx) );
	return Buffer;
}

//
// Returns a string in ANSI that passed in UNICODE
//
char* GetANSIfromUNICODE( const LPCWSTR Unicode )
{
	static char Buffer[MAX_PATH];
	WideCharToMultiByte( CP_ACP, 0, Unicode, -1, Buffer, MAX_PATH-1, NULL, NULL );
	return Buffer;
}

//
// Returns a string describing the 3D device ID passed
//
char* Get3DDevice( REFCLSID rclsid )
{
	if( rclsid==IID_IDirect3DHALDevice )
		return "HAL";
	if( rclsid==IID_IDirect3DTnLHalDevice )
		return "T&LHAL";
	if( rclsid==IID_IDirect3DMMXDevice )
		return "MMX";
	if( rclsid==IID_IDirect3DRampDevice )
		return "RAMP";
	if( rclsid==IID_IDirect3DRGBDevice )
		return "RGB";
	if( rclsid==IID_IDirect3DRefDevice )
		return "REFERENCE RASTERIZER";
	if( rclsid==IID_IDirect3DBladeDevice )
		return "BLADE";
	return "Unknown";
}

//
// Returns a string describing a DirectInput Device
//
char* GetDIDevice( REFGUID rguid )
{
	if( &rguid==&GUID_ConstantForce )
		return "GUID_ConstantForce";
	if( &rguid==&GUID_RampForce )
		return "GUID_RampForce";
	if( &rguid==&GUID_Square )
		return "GUID_Square";
	if( &rguid==&GUID_Sine )
		return "GUID_Sine";
	if( &rguid==&GUID_Triangle )
		return "GUID_Triangle";
	if( &rguid==&GUID_SawtoothUp )
		return "GUID_SawtoothUp";
	if( &rguid==&GUID_SawtoothDown )
		return "GUID_SawtoothDown";
	if( &rguid==&GUID_Spring )
		return "GUID_Spring";
	if( &rguid==&GUID_Damper )
		return "GUID_Damper";
	if( &rguid==&GUID_Inertia )
		return "GUID_Inertia";
	if( &rguid==&GUID_Friction )
		return "GUID_Friction";
	if( &rguid==&GUID_CustomForce )
		return "GUID_CustomForce";
	if( &rguid==&DIPROP_AUTOCENTER )
		return "DIPROP_AUTOCENTER";
	if( &rguid==&DIPROP_AXISMODE )
		return "DIPROP_AXISMODE";
	if( &rguid==&DIPROP_BUFFERSIZE )
		return "DIPROP_BUFFERSIZE";
	if( &rguid==&DIPROP_CALIBRATIONMODE )
		return "DIPROP_CALIBRATIONMODE";
	if( &rguid==&DIPROP_DEADZONE )
		return "DIPROP_DEADZONE";
	if( &rguid==&DIPROP_FFGAIN )
		return "DIPROP_FFGAIN";
	if( &rguid==&DIPROP_RANGE )
		return "DIPROP_RANGE";
	if( &rguid==&DIPROP_SATURATION )
		return "DIPROP_SATURATION";
	if( rguid==GUID_SysKeyboard )
		return "GUID_SysKeyboard";
	if( rguid==GUID_SysMouse )
		return "GUID_SysMouse";
	if( rguid==GUID_Joystick )
		return "GUID_Joystick";
	return "Unknown";
}
//
// Returns a string describing a Direct Sound property
//
char* GetPropertySet( REFGUID rguid )
{
	if( &rguid==&DSPROPSETID_EAX_ReverbProperties )
		return "EAX_ReverbProperties";
	return "Unknown";
}
//
// Returns a string describing a Direct Sound property item
//
char* GetPropertyItem( REFGUID rguid, LONG Item )
{
	if( &rguid==&DSPROPSETID_EAX_ReverbProperties )
	{
		switch( Item )
		{
			case DSPROPERTY_EAX_ENVIRONMENT:
				return "EAX_ENVIRONMENT";
			case DSPROPERTY_EAX_DAMPING:
				return "EAX_DAMPING";
			case DSPROPERTY_EAX_DECAYTIME:
				return "EAX_DECAYTIME";
			case DSPROPERTY_EAX_ALL:
				return "EAX_ALL";
		}
	}
	return "Unknown";
}
//
// Returns a string describing the interface passed
//
char* GetReturnInterface( REFIID riid )
{
	if( riid==IID_IDirectDraw )
		return "IDirectDraw";
	if( riid==IID_IDirectDraw2 )
		return "IDirectDraw2";
	if( riid==IID_IDirectDraw4 )
		return "IDirectDraw4";
	if( riid==IID_IDirectDraw7 )
		return "IDirectDraw7";
	if( riid==IID_IDirectDrawSurface )
		return "IDirectDrawSurface";
	if( riid==IID_IDirectDrawSurface2 )
		return "IDirectDrawSurface2";
	if( riid==IID_IDirectDrawSurface3 )
		return "IDirectDrawSurface3";
	if( riid==IID_IDirectDrawSurface4 )
		return "IDirectDrawSurface4";
	if( riid==IID_IDirectDrawSurface7 )
		return "IDirectDrawSurface7";
	if( riid==IID_IDirectDrawPalette )
		return "IDirectDrawPalette";
	if( riid==IID_IDirectDrawClipper )
		return "IDirectDrawClipper";
	if( riid==IID_IDirectDrawColorControl )
		return "IDirectDrawColorControl";
	if( riid==IID_IAMMultiMediaStream )
		return "IAMMultiMediaStream";
	if( riid==IID_IDirectInputDevice )
		return "IDirectInputDevice";
	if( riid==IID_IDirectInputDevice2 )
		return "IDirectInputDevice2";
	if( riid==IID_IDirectInputDevice7 )
		return "IDirectInputDevice7";
	if( riid==IID_IDirectInput )
		return "IDirectInput";
	if( riid==IID_IDirectInput2 )
		return "IDirectInput2";
	if( riid==IID_IDirectInput7 )
		return "IDirectInput7";
	if( riid==IID_IDirectDrawMediaStream )
		return "IDirectDrawMediaStream";
	if( riid==IID_IDirect3D )
		return "IDirect3D";
	if( riid==IID_IDirect3D2 )
		return "IDirect3D2";
	if( riid==IID_IDirect3D3 )
		return "IDirect3D3";
	if( riid==IID_IDirect3D7 )
		return "IDirect3D7";
	if( riid==IID_IDirect3DTexture2 )
		return "IDirect3DTexture2";
	if( riid==IID_IKsPropertySet )
		return "IIKsPropertySet";
	if( riid==IID_IDirectPlayLobby )
		return "IDirectPlayLobby";
	if( riid==IID_IDirectPlayLobby3A )
		return "IDirectPlayLobby3A";
	if( riid==IID_IDirectPlay )
		return "IDirectPlay";
	if( riid==IID_IDirectPlay4A )
		return "IDirectPlay4A";
	if( riid==IID_IDirectSound3DBuffer )
		return "IDirectSound3DBuffer";
	if( riid==IID_IKsPropertySet )
		return "IKsPropertySet";
	if( riid==IID_IDirectSound3DListener )
		return "IDirectSound3DListener";
	if( riid==IID_IDirectDrawGammaControl )
		return "IDirectDrawGammaControl";
	if( riid==IID_IMultiMediaStream )
		return "IID_IMultiMediaStream";
	if( riid==IID_IMediaControl )
		return "IMediaControl";
	if( riid==IID_IBasicAudio )
		return "IBasicAudio";
	return "Unknown";
}

//
// Returns a string describing the Lock flags
//
char* GetLockFlags( DWORD dwFlags )
{
	static char Buffer[128];
	Buffer[0]=0;

	if( dwFlags & DDLOCK_NOSYSLOCK )
		strcat(Buffer, "NOSYSLOCK ");
	if( dwFlags & DDLOCK_READONLY )
		strcat(Buffer, "READONLY ");
	if( dwFlags & DDLOCK_SURFACEMEMORYPTR )
		strcat(Buffer, "SURFACEMEMORYPTR ");
	if( dwFlags & DDLOCK_WAIT )
		strcat(Buffer, "WAIT ");
	if( dwFlags & DDLOCK_WRITEONLY )
		strcat(Buffer, "WRITEONLY ");
	return Buffer;
}

//
// Returns a string describing the SetColorKey flags
//
char* GetSetColorKeyFlags( DWORD dwFlags )
{
	static char Buffer[128];
	Buffer[0]=0;

	if( dwFlags & DDCKEY_COLORSPACE )
		strcat(Buffer, "COLORSPACE ");
	if( dwFlags & DDCKEY_DESTBLT )
		strcat(Buffer, "DESTBLT ");
	if( dwFlags & DDCKEY_DESTOVERLAY )
		strcat(Buffer, "DESTOVERLAY ");
	if( dwFlags & DDCKEY_SRCBLT )
		strcat(Buffer, "SRCBLT ");
	if( dwFlags & DDCKEY_SRCOVERLAY )
		strcat(Buffer, "SRCOVERLAY ");
	return Buffer;
}

//
// Returns a string describing the EnumDisplayMode flags
//
char* GetEnumDisplayModeFlags( DWORD dwFlags )
{
	static char Buffer[64];
	Buffer[0]=0;

	if( dwFlags & DDEDM_REFRESHRATES )
		strcat(Buffer, "REFRESHRATES ");
	if( dwFlags & DDEDM_STANDARDVGAMODES )
		strcat(Buffer, "STANDARDVGAMODES ");
	return Buffer;
}

//
// Returns a string describing the CreatePalette flags
//
char* GetCreatePaletteFlags( DWORD dwFlags )
{
	static char Buffer[128];
	Buffer[0]=0;

	if( dwFlags & DDPCAPS_1BIT )
		strcat(Buffer, "1BIT ");
	if( dwFlags & DDPCAPS_2BIT )
		strcat(Buffer, "2BIT ");
	if( dwFlags & DDPCAPS_4BIT )
		strcat(Buffer, "4BIT ");
	if( dwFlags & DDPCAPS_8BITENTRIES )
		strcat(Buffer, "8BITENTRIES ");
	if( dwFlags & DDPCAPS_8BIT )
		strcat(Buffer, "8BIT ");
	if( dwFlags & DDPCAPS_ALLOW256 )
		strcat(Buffer, "ALLOW256 ");
	return Buffer;
}

//
// Returns a string describing the SetCooperativeLevel flags
//
char* GetSetCooperativeLevelFlags( DWORD dwFlags )
{
	static char Buffer[128];
	Buffer[0]=0;

	if( dwFlags & DDSCL_ALLOWMODEX )
		strcat(Buffer, "ALLOWMODEX ");
	if( dwFlags & DDSCL_ALLOWREBOOT )
		strcat(Buffer, "ALLOWREBOOT ");
	if( dwFlags & DDSCL_EXCLUSIVE )
		strcat(Buffer, "EXCLUSIVE ");
	if( dwFlags & DDSCL_FULLSCREEN )
		strcat(Buffer, "FULLSCREEN ");
	if( dwFlags & DDSCL_NORMAL )
		strcat(Buffer, "NORMAL ");
	if( dwFlags & DDSCL_NOWINDOWCHANGES )
		strcat(Buffer, "NOWINDOWCHANGES ");
	return Buffer;
}

//
// Returns a char describing the number of bits set in an INT
//
char ReturnBits( DWORD Value )
{
	DWORD result=0,mask=1;

	for(int t1=0;t1!=32;t1++)
	{
		if( Value&mask )
			result++;
		mask<<=1;
	}
	return (char)((result > 9) ? result+'A'-10 : result+'0');
}

//
// Returns a string that describes the pixel format passed
//
char* GetGosPixelFormat( LPDDPIXELFORMAT pf )
{
	static char Buffer[128];
	Buffer[0]=0;

	if( pf->dwSize != sizeof(DDPIXELFORMAT) )
		return "Invalid size field! ";

	if(	pf->dwFlags & DDPF_PALETTEINDEXED1 )
		sprintf(Buffer, "1bit " );
	else if(	pf->dwFlags & DDPF_PALETTEINDEXED2 )
		sprintf(Buffer, "2bit " );
	else if(	pf->dwFlags & DDPF_PALETTEINDEXED4 )
		sprintf(Buffer, "4bit " );
	else if(	pf->dwFlags & DDPF_PALETTEINDEXED8 )
		sprintf(Buffer, "8bit " );
	else if(	pf->dwFlags & DDPF_BUMPDUDV )
		sprintf(Buffer, "Bump map DuDv (%c,%c) ",ReturnBits(pf->dwBumpDuBitMask),ReturnBits(pf->dwBumpDvBitMask) );
	else if(	pf->dwFlags & DDPF_PALETTEINDEXEDTO8 )
		sprintf(Buffer, "IndexedTo8 " );
	else if(	pf->dwFlags & DDPF_FOURCC )
		sprintf(Buffer, "FourCC (%c%c%c%c) ",(pf->dwFourCC>>24)&0xff,(pf->dwFourCC>>16)&0xff,(pf->dwFourCC>>8)&0xff,pf->dwFourCC&0xff );
	else if(	pf->dwFlags & DDPF_YUV )
		sprintf(Buffer, "YUV " );
	else if(	pf->dwFlags & DDPF_LUMINANCE )
		sprintf(Buffer, "%d bit Luminance ",pf->dwLuminanceBitCount );
	else if(	pf->dwFlags & DDPF_BUMPLUMINANCE )
		sprintf(Buffer, "%c bit Bump Luminance ",ReturnBits(pf->dwBumpLuminanceBitMask) );
	else if(	pf->dwFlags & DDPF_RGB )
	{
			if( pf->dwFlags & DDPF_ALPHAPIXELS )
				sprintf(&Buffer[strlen(Buffer)], "%c",ReturnBits(pf->dwRGBAlphaBitMask) );
			if( pf->dwRGBBitCount==32 )
			{
				if( (pf->dwFlags & DDPF_ALPHAPIXELS) && ReturnBits(pf->dwRGBAlphaBitMask)=='8' )
					sprintf(&Buffer[strlen(Buffer)], "888 " );
				else
					sprintf(&Buffer[strlen(Buffer)], "0888 " );
			}
			else
				sprintf(&Buffer[strlen(Buffer)], "%c%c%c ",ReturnBits(pf->dwRBitMask),ReturnBits(pf->dwGBitMask),ReturnBits(pf->dwBBitMask) );
	}
	else if( pf->dwFlags & DDPF_ZBUFFER )
	{
		if( pf->dwFlags & DDPF_STENCILBUFFER )
		{
			sprintf(Buffer, "(Z=%d (0x%x) Stencil=%d (0x%x)) ",pf->dwZBufferBitDepth,pf->dwZBitMask,pf->dwStencilBitDepth,pf->dwStencilBitMask );
		}
		else
		{
			sprintf(Buffer, "%d bit Z ",pf->dwZBufferBitDepth );
		}
	}
	else
	{
		sprintf(Buffer, "Unknown " );
	}

	if(pf->dwFlags & DDPF_ALPHA)
		strcat(Buffer, "+ALPHA ");
	if(pf->dwFlags & DDPF_COMPRESSED)
		strcat(Buffer, "+COMPRESSED ");
	if(pf->dwFlags & DDPF_ALPHAPREMULT)
		strcat(Buffer, "+ALPHAPREMULT ");
	if(pf->dwFlags & DDPF_RGBTOYUV)
		strcat(Buffer, "+RGBTOYUV ");
	if(pf->dwFlags & DDPF_ZPIXELS)
		strcat(Buffer, "+ZPIXELS ");

	return Buffer;
}

//
// Returns a string that describes the surface caps passed
//
char *GetSurfaceCaps( LPDDSCAPS2 lpDDSCaps2 )
{
	static char Buffer[128];
	Buffer[0]=0;

	if( lpDDSCaps2->dwCaps & DDSCAPS_3DDEVICE )
		strcat( Buffer, "3D ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_COMPLEX )
		strcat( Buffer, "Complex ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_BACKBUFFER )
		strcat( Buffer, "BackBuffer ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_FRONTBUFFER )
		strcat( Buffer, "FrontBuffer ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_HWCODEC )
		strcat( Buffer, "HWCodec ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_LIVEVIDEO )
		strcat( Buffer, "LiveVideo ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_MIPMAP )
		strcat( Buffer, "Mipmap ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_WRITEONLY )
		strcat( Buffer, "WriteOnly ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_FLIP )
		strcat( Buffer, "Flipping ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_LOCALVIDMEM )
		strcat( Buffer, "LocalVideoMemory ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_NONLOCALVIDMEM )
		strcat( Buffer, "NonLocalVideoMemory ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_VIDEOMEMORY )
		strcat( Buffer, "VideoMemory ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_SYSTEMMEMORY )
		strcat( Buffer, "SystemMemory ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_ALLOCONLOAD )
		strcat( Buffer, "AllocOnLoad ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_PRIMARYSURFACE )
		strcat( Buffer, "Primary ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_TEXTURE )
		strcat( Buffer, "Texture ");

	if( lpDDSCaps2->dwCaps & DDSCAPS_OFFSCREENPLAIN )
		strcat( Buffer, "OffScreenPlain ");

	return Buffer;
}

//
// Returns a string that describes the surface description passed
//
char *GetSurfaceDescription( LPDDSURFACEDESC2 pSD )
{
	static char Buffer[512];

	Buffer[0]=0;

	if( pSD->dwSize != sizeof(DDSURFACEDESC2) )
		return "Invalid size field";

	if( (pSD->dwFlags & (DDSD_HEIGHT+DDSD_WIDTH)) == (DDSD_HEIGHT+DDSD_WIDTH) )
		sprintf(&Buffer[strlen(Buffer)], "%dx%d ",pSD->dwWidth,pSD->dwHeight);

	if( (pSD->dwFlags & DDSD_PIXELFORMAT ) )
		sprintf(&Buffer[strlen(Buffer)], "%s",GetGosPixelFormat(&pSD->ddpfPixelFormat) );

	if( (pSD->dwFlags & DDSD_ALPHABITDEPTH ) )
		sprintf(&Buffer[strlen(Buffer)], "%d bit AlphaBuffer%s ",pSD->dwAlphaBitDepth, pSD->dwAlphaBitDepth==1 ? "" : "s");

	if( (pSD->dwFlags & DDSD_BACKBUFFERCOUNT ) )
		sprintf(&Buffer[strlen(Buffer)], "Backbuffer%s=%d ",pSD->dwBackBufferCount==1 ? "" : "s",pSD->dwBackBufferCount);

	if( (pSD->dwFlags & DDSD_PITCH ) )
		sprintf(&Buffer[strlen(Buffer)], "Pitch=%d ",pSD->lPitch);

	if( (pSD->dwFlags & DDSD_MIPMAPCOUNT ) )
		sprintf(&Buffer[strlen(Buffer)], "MipMap%s=%d ",pSD->dwMipMapCount==1 ? "" : "s",pSD->dwMipMapCount);

	if( (pSD->dwFlags & DDSD_CKDESTBLT ) )
		sprintf(&Buffer[strlen(Buffer)], "Dest ColorKey ");

	if( (pSD->dwFlags & DDSD_CKSRCBLT ) )
		sprintf(&Buffer[strlen(Buffer)], "Source ColorKey ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) )
		sprintf(&Buffer[strlen(Buffer)], "3D ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_COMPLEX) )
		sprintf(&Buffer[strlen(Buffer)], "Complex ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_BACKBUFFER) )
		sprintf(&Buffer[strlen(Buffer)], "BackBuffer ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) )
		sprintf(&Buffer[strlen(Buffer)], "FrontBuffer ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_HWCODEC) )
		sprintf(&Buffer[strlen(Buffer)], "HWCodec ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_LIVEVIDEO) )
		sprintf(&Buffer[strlen(Buffer)], "LiveVideo ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_MIPMAP) )
		sprintf(&Buffer[strlen(Buffer)], "Mipmap ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_WRITEONLY) )
		sprintf(&Buffer[strlen(Buffer)], "WriteOnly ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_FLIP) )
		sprintf(&Buffer[strlen(Buffer)], "Flipping ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM) )
		sprintf(&Buffer[strlen(Buffer)], "LocalVideoMemory ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM) )
		sprintf(&Buffer[strlen(Buffer)], "NonLocalVideoMemory ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) )
		sprintf(&Buffer[strlen(Buffer)], "VideoMemory ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) )
		sprintf(&Buffer[strlen(Buffer)], "SystemMemory ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) )
		sprintf(&Buffer[strlen(Buffer)], "AllocOnLoad ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) )
		sprintf(&Buffer[strlen(Buffer)], "Primary ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE) )
		sprintf(&Buffer[strlen(Buffer)], "Texture ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) )
		sprintf(&Buffer[strlen(Buffer)], "OffScreenPlain ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps2 & DDSCAPS2_HINTANTIALIASING) )
		sprintf(&Buffer[strlen(Buffer)], "Antialiased ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps2 & DDSCAPS2_HINTDYNAMIC) )
		sprintf(&Buffer[strlen(Buffer)], "Dynamic ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps2 & DDSCAPS2_HINTSTATIC) )
		sprintf(&Buffer[strlen(Buffer)], "Static ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL) )
		sprintf(&Buffer[strlen(Buffer)], "MipmapSubLevel ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps2 & DDSCAPS2_OPAQUE) )
		sprintf(&Buffer[strlen(Buffer)], "Opaque ");

	return Buffer;
}

//
// Returns a string that describes the surface description passed
//
char *GetSurfaceDescriptionOld( LPDDSURFACEDESC pSD )
{
	static char Buffer[512];

	Buffer[0]=0;

	if( 0==pSD )
	{
		strcpy( Buffer, "NULL" );
		return Buffer;
	}

	if( pSD->dwSize != sizeof(DDSURFACEDESC) )
		return "Invalid size field";

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) )
		sprintf(&Buffer[strlen(Buffer)], "PRIMARY ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE) )
		sprintf(&Buffer[strlen(Buffer)], "Texture ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) )
		sprintf(&Buffer[strlen(Buffer)], "OffScreenPlain ");

	if( (pSD->dwFlags & (DDSD_HEIGHT+DDSD_WIDTH)) == (DDSD_HEIGHT+DDSD_WIDTH) )
		sprintf(&Buffer[strlen(Buffer)], "%dx%d ",pSD->dwWidth,pSD->dwHeight);

	if( (pSD->dwFlags & DDSD_PIXELFORMAT ) )
		sprintf(&Buffer[strlen(Buffer)], "%s",GetGosPixelFormat(&pSD->ddpfPixelFormat) );

	if( (pSD->dwFlags & DDSD_ALPHABITDEPTH ) )
		sprintf(&Buffer[strlen(Buffer)], "%d bit AlphaBuffer%s ",pSD->dwAlphaBitDepth, pSD->dwAlphaBitDepth==1 ? "" : "s");

	if( (pSD->dwFlags & DDSD_BACKBUFFERCOUNT ) )
		sprintf(&Buffer[strlen(Buffer)], "Backbuffer%s=%d ",pSD->dwBackBufferCount==1 ? "" : "s",pSD->dwBackBufferCount);

	if( (pSD->dwFlags & DDSD_PITCH ) )
		sprintf(&Buffer[strlen(Buffer)], "Pitch=%d ",pSD->lPitch);

	if( (pSD->dwFlags & DDSD_MIPMAPCOUNT ) )
		sprintf(&Buffer[strlen(Buffer)], "MipMap%s=%d ",pSD->dwMipMapCount==1 ? "" : "s",pSD->dwMipMapCount);

	if( (pSD->dwFlags & DDSD_CKDESTBLT ) )
		sprintf(&Buffer[strlen(Buffer)], "Dest ColorKey ");

	if( (pSD->dwFlags & DDSD_CKSRCBLT ) )
		sprintf(&Buffer[strlen(Buffer)], "Source ColorKey ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) )
		sprintf(&Buffer[strlen(Buffer)], "3D ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_COMPLEX) )
		sprintf(&Buffer[strlen(Buffer)], "Complex ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_FLIP) )
		sprintf(&Buffer[strlen(Buffer)], "Flipping ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM) )
		sprintf(&Buffer[strlen(Buffer)], "LocalVideoMemory ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM) )
		sprintf(&Buffer[strlen(Buffer)], "NonLocalVideoMemory ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) )
		sprintf(&Buffer[strlen(Buffer)], "VideoMemory ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) )
		sprintf(&Buffer[strlen(Buffer)], "SystemMemory ");

	if( (pSD->dwFlags & DDSD_CAPS) && (pSD->ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) )
		sprintf(&Buffer[strlen(Buffer)], "AllocOnLoad ");

	return Buffer;
}

char* GetDIEnumFlags(DWORD flags)
{
	static char Buffer[128];
	Buffer[0] = 0;
	if (flags & DIEDFL_ALLDEVICES)
	{
		strcat(Buffer,"DIEDFL_ALLDEVICES ") ;
	}
	if (flags & DIEDFL_ATTACHEDONLY)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEDFL_ATTACHEDONLY ") ;
	}
	if (flags & DIEDFL_FORCEFEEDBACK)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEDFL_FORCEFEEDBACK ") ;
	}
	return Buffer;
}

char* GetDICoopFlags(DWORD flags)
{
	static char Buffer[128];
	Buffer[0] = 0;
	if (flags & DISCL_BACKGROUND)
	{
		strcat(Buffer,"DISCL_BACKGROUND ") ;
	}
	if (flags & DISCL_EXCLUSIVE)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DISCL_EXCLUSIVE ") ;
	}
	if (flags & DISCL_FOREGROUND)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DISCL_FOREGROUND ") ;
	}
	if (flags & DISCL_NONEXCLUSIVE)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DISCL_NONEXCLUSIVE ") ;
	}
	return Buffer;
}

char* GetDIGetDeviceDataFlags(DWORD flags)
{
	static char Buffer[128];
	Buffer[0] = 0;
	if (flags & DIGDD_PEEK)
	{
		strcat(Buffer,"DIGDD_PEEK ") ;
	}
	if (flags == 0)
	{
		strcat(Buffer,"NONE ") ;
	}
	return Buffer;
}

char * DSGetStreamType(STREAM_TYPE StreamType)
{
	switch(StreamType)
	{
	case STREAMTYPE_READ:
		return "STREAMTYPE_READ";
	case STREAMTYPE_WRITE:
		return "STREAMTYPE_WRITE";
	case STREAMTYPE_TRANSFORM:
		return "STREAMTYPE_TRANSFORM";
	}
	return "STREAMTYPE_BAD";
}

char * DSGetInitFlags(DWORD dwFlags)
{
	static char Buffer[128];
	Buffer[0] = 0;
	
	if (dwFlags & AMMSF_ADDDEFAULTRENDERER)
		strcat(Buffer,"AMMSF_ADDDEFAULTRENDERER ");
	if (dwFlags & AMMSF_CREATEPEER)
		strcat(Buffer,"AMMSF_CREATEPEER ");
	if (dwFlags & AMMSF_STOPIFNOSAMPLES)
		strcat(Buffer,"AMMSF_STOPIFNOSAMPLES ");
	if (dwFlags & AMMSF_NOSTALL)
		strcat(Buffer,"AMMSF_NOSTALL ");
	return Buffer;
}

char * DSGetUpdateFlags(DWORD dwFlags)
{
	static char Buffer[128];
	Buffer[0] = 0;
	
	if (dwFlags & SSUPDATE_ASYNC )
		strcat(Buffer,"SSUPDATE_ASYNC ");
	if (dwFlags & SSUPDATE_CONTINUOUS )
		strcat(Buffer,"SSUPDATE_CONTINUOUS ");
	return Buffer;
}

char * GetDSSpeakerConfig(DWORD dsFlags)
{
	static char Buffer[128];
	Buffer[0] = 0;
	
	if (dsFlags & DSSPEAKER_HEADPHONE )
		strcat(Buffer,"DSSPEAKER_HEADPHONE  ");
	if (dsFlags & DSSPEAKER_MONO  )
		strcat(Buffer,"DSSPEAKER_MONO ");
	if (dsFlags & DSSPEAKER_QUAD  )
		strcat(Buffer,"DSSPEAKER_QUAD ");
	if (dsFlags & DSSPEAKER_STEREO  )
		strcat(Buffer,"DSSPEAKER_STEREO ");
	if (dsFlags & DSSPEAKER_SURROUND  )
		strcat(Buffer,"DSSPEAKER_SURROUND ");
	if (dsFlags & DSSPEAKER_GEOMETRY_WIDE  )
		strcat(Buffer,"DSSPEAKER_GEOMETRY_WIDE ");
	if (dsFlags & DSSPEAKER_GEOMETRY_NARROW  )
		strcat(Buffer,"DSSPEAKER_GEOMETRY_NARROW ");
	if (dsFlags & DSSPEAKER_GEOMETRY_MIN  )
		strcat(Buffer,"DSSPEAKER_GEOMETRY_MIN ");
	if (dsFlags & DSSPEAKER_GEOMETRY_MAX  )
		strcat(Buffer,"DSSPEAKER_GEOMETRY_MAX ");
	return Buffer;
}

char* GetApplyFlag( DWORD flag )
{
	if( flag==DS3D_DEFERRED )
		return "DEFERRED";
	if( flag==DS3D_IMMEDIATE )
		return "IMMEDIATE";
	return "Unknown";
}

char* GetDSBDFlags(DWORD dsFlags)
{
	static char Buffer[256];
	Buffer[0] = 0;
	
	if (dsFlags & DSBCAPS_CTRL3D )
		strcat(Buffer,"DSBCAPS_CTRL3D ");
//	if (dsFlags & DSBCAPS_CTRLALL  )
//		strcat(Buffer,"DSBCAPS_CTRLALL ");
	if (dsFlags & DSBCAPS_CTRLFREQUENCY  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DSBCAPS_CTRLFREQUENCY ");
	}
	if (dsFlags & DSBCAPS_CTRLPAN  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DSBCAPS_CTRLPAN ");
	}
	if (dsFlags & DSBCAPS_CTRLPOSITIONNOTIFY  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DSBCAPS_CTRLPOSITIONNOTIFY ");
	}
	if (dsFlags & DSBCAPS_CTRLVOLUME  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DSBCAPS_CTRLVOLUME ");
	}
	if (dsFlags & DSBCAPS_GETCURRENTPOSITION2  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DSBCAPS_GETCURRENTPOSITION2 ");
	}
	if (dsFlags & DSBCAPS_GLOBALFOCUS  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DSBCAPS_GLOBALFOCUS ");
	}
	if (dsFlags & DSBCAPS_LOCDEFER  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DSBCAPS_LOCDEFER ");
	}
	if (dsFlags & DSBCAPS_LOCHARDWARE  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DSBCAPS_LOCHARDWARE ");
	}
	if (dsFlags & DSBCAPS_LOCSOFTWARE  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DSBCAPS_LOCSOFTWARE ");
	}
	if (dsFlags & DSBCAPS_MUTE3DATMAXDISTANCE  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DSBCAPS_MUTE3DATMAXDISTANCE ");
	}
	if (dsFlags & DSBCAPS_PRIMARYBUFFER  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DSBCAPS_PRIMARYBUFFER ");
	}
	if (dsFlags & DSBCAPS_STATIC  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DSBCAPS_STATIC ");
	}
	if (dsFlags & DSBCAPS_STICKYFOCUS  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DSBCAPS_STICKYFOCUS ");
	}
	return Buffer;
}

char * GetDShowSeekType(DWORD dsFlags)
{
	static char Buffer[256];
	Buffer[0] = 0;

	if (dsFlags & AM_SEEKING_NoPositioning  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"AM_SEEKING_NoPositioning ");
	}

	if (dsFlags & AM_SEEKING_AbsolutePositioning  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"AM_SEEKING_AbsolutePositioning ");
	}

	if (dsFlags & AM_SEEKING_RelativePositioning  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"AM_SEEKING_RelativePositioning ");
	}

	if (dsFlags & AM_SEEKING_IncrementalPositioning  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"AM_SEEKING_IncrementalPositioning ");
	}

	if (dsFlags & AM_SEEKING_PositioningBitsMask  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"AM_SEEKING_PositioningBitsMask ");
	}

	if (dsFlags & AM_SEEKING_SeekToKeyFrame  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"AM_SEEKING_SeekToKeyFrame ");
	}

	if (dsFlags & AM_SEEKING_ReturnTime  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"AM_SEEKING_ReturnTime ");
	}

	if (dsFlags & AM_SEEKING_Segment  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"AM_SEEKING_Segment ");
	}

	if (dsFlags & AM_SEEKING_NoFlush  )
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"AM_SEEKING_NoFlush ");
	}

	return Buffer;
}

char* GetEffectFlags(DWORD diFlags)
{
	static char Buffer[256];
	Buffer[0] = 0;

	if (diFlags &DIEP_AXES)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEP_AXES ");
	}
	if (diFlags &DIEP_DIRECTION)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEP_DIRECTION ");
	}
	if (diFlags &DIEP_DURATION)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEP_DURATION ");
	}
	if (diFlags &DIEP_ENVELOPE)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEP_ENVELOPE ");
	}
	if (diFlags &DIEP_GAIN)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEP_GAIN ");
	}
	if (diFlags &DIEP_NODOWNLOAD)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEP_NODOWNLOAD ");
	}
	if (diFlags &DIEP_NORESTART)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEP_RESTART ");
	}
	if (diFlags &DIEP_SAMPLEPERIOD)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEP_SAMPLEPERIOD ");
	}
	if (diFlags &DIEP_START)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEP_START ");
	}
	if (diFlags &DIEP_STARTDELAY)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEP_STARTDELAY ");
	}
	if (diFlags &DIEP_TRIGGERBUTTON)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEP_TRIGGERBUTTON ");
	}
	if (diFlags &DIEP_TRIGGERREPEATINTERVAL)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEP_TRIGGERREPEATINTERVAL ");
	}
	if (diFlags &DIEP_TYPESPECIFICPARAMS)
	{
		if (Buffer[0]) strcat(Buffer, "| ");
		strcat(Buffer,"DIEP_TYPESPECIFICPARAMS ");
	}
	return Buffer;
}
