#ifndef __FRAMEWORKTYPES_H__
#define __FRAMEWORKTYPES_H__

// --------------------------------------------------------------------------------------
// Framework types declaration
//
// Copyright Microsoft Corp. 2000
//
// --------------------------------------------------------------------------------------

#include <windows.h>
#include <tchar.h>
#include <LIMITS.H>
#include "CD3DDef.h"

// --------------------------------------------------------------------------------------
// Forward declarations

class	CDebugOut;


// --------------------------------------------------------------------------------------
// Defines / Types / Externs

const float pi = 3.141592654f;
const int	MAX_D3D_STRING = 1024;
enum GRAPHICSBUSTYPES { BADBUS, UNKNOWNBUS, PCIBUS, AGPBUS };
enum DRIVERMODEL { DRIVERMODEL_XPDM = 1, DRIVERMODEL_LDDM = 2};
extern CDebugOut	DebugOut; // instantiated in CDebugOut.cpp

#define E_UNSUPPORTED                        _HRESULT_TYPEDEF_(0x8000000BL)

 // Supported APIs list
typedef enum _RENDERPRMITIVEAPI
{
    RP_BE               = 0,    // (Begin/Vertex/End)
    RP_BIE              = 1,    // (BeginIndexed/Index/End)
    RP_DP               = 2,    // DrawPrimitiveUP (DrawPrimitive)
    RP_DIP              = 3,    // DrawIndexedPrimitiveUP (DrawIndexedPrimitive)
    RP_DPS              = 4,    // DrawPrimitive multiple streams (DrawPrimitiveStrided)
    RP_DIPS             = 5,    // DrawIndexedPrimitive multiple streams (DrawIndexedPrimitiveStrided)
    RP_DPVB             = 6,    // DrawPrimitive single stream (DrawPrimitiveVB)
    RP_DIPVB            = 7,    // DrawIndexedPrimitive single stream (DrawIndexedPrimitiveVB)
    RP_DPVB_PV          = 8,    // (DrawPrimitiveVB after ProcessVertices)
    RP_DIPVB_PV         = 9,    // (DrawIndexedPrimitiveVB after ProcessVertices)
    RP_DPVB_OPT         = 10,   // (DrawPrimitiveVB with optimized vertex buffer)
    RP_DIPVB_OPT        = 11,   // (DrawIndexedPrimitiveVB with optimized vertex buffer)
    RP_DPVB_OPT_PV      = 12,   // (DrawPrimitiveVB after ProcessVertices with optimized vertex buffer)
    RP_DIPVB_OPT_PV     = 13,   // (DrawIndexedPrimitiveVB after ProcessVertices with optimized vertex buffer)
    RP_DPVB_PVS         = 14,   // (DrawPrimitiveVB after ProcessVerticesStrided)
    RP_DIPVB_PVS        = 15,   // (DrawIndexedPrimitiveVB after ProcessVerticesStrided)
    RP_FORCE_DWORD      = 0x7fffffff
} RENDERPRIMITIVEAPI, *PRENDERPRIMITIVEAPI;


typedef struct _RPOPTIONS
{
	DWORD		Pool;
	DWORD		Usage;
	UINT		uIBBitCount;
	DWORD		Flags;
} RPOPTIONS, *LPRPOPTIONS;

//enum TESTTYPE
//{
//	TESTTYPE_API=2,
//    TESTTYPE_STRESS=3,
//	TESTTYPE_CONF=4,
//	TESTTYPE_FUNC=5,
//	TESTTYPE_PERF=6,
//	TESTTYPE_APP=7,
//	TESTTYPE_SAMP=8,
//	TESTTYPE_PSGP=9
//};

const DWORD		PSGPREGCHANGE_NONE		= 0x00;
const DWORD		PSGPREGCHANGE_ENABLE	= 0x01;
const DWORD		PSGPREGCHANGE_DISABLE	= 0x02;

const DWORD		VPEMUREGCHANGE_NONE		= 0x00;
const DWORD		VPEMUREGCHANGE_ENABLE	= 0x01;
const DWORD		VPEMUREGCHANGE_DISABLE	= 0x02;

const DWORD		PPEMUREGCHANGE_NONE		= 0x00;
const DWORD		PPEMUREGCHANGE_ENABLE	= 0x01;
const DWORD		PPEMUREGCHANGE_DISABLE	= 0x02;


const DWORD		TESTSCENARIO_RAST		= 0x0001;		// Hardware rasterization test
const DWORD		TESTSCENARIO_TNL		= 0x0002;		// Hardware TnL test
const DWORD		TESTSCENARIO_PURE		= 0x0002;		// Pure HAL test
const DWORD		TESTSCENARIO_PSGP		= 0x0008;		// Processor-specific pipeline
const DWORD		TESTSCENARIO_MSGP		= 0x0010;		// MS pipeline
const DWORD		TESTSCENARIO_REF		= 0x0100;		// Reference rasterization test
const DWORD		TESTSCENARIO_TNLREF		= 0x0200;		// Reference pipeline test
const DWORD		TESTSCENARIO_PUREREF	= 0x0400;		// Pure Reference


// --------------------------------------------------------------------------------------
// DISPLAYMODE struct - maintains info for each possible display mode

typedef struct
{
    DWORD   dwWidth;
    DWORD   dwHeight;
    DWORD   dwBPP;
    DWORD   dwRefreshRate;
    FORMAT  Format;
} DISPLAYMODE, *PDISPLAYMODE;

// --------------------------------------------------------------------------------------
// TESTMODE - modes generated by CD3DTest

typedef struct  _TESTMODE
{
	DISPLAYMODE *pDisplay;
	UINT		nBackBufferWidth, nBackBufferHeight;
	bool   		bWindowed;
	int     	nTextureFormat;
    int     	nCubeFormat;
    int     	nVolumeFormat;
	int     	nZBufferFormat;
	int			nMultisample;
	int			nMltsmpQuality;
	int			nBackBufferFormat;
	PVOID		pExtraData;
	
	_TESTMODE*	pNext;
	_TESTMODE*	pPrevious;
} TESTMODE, *PTESTMODE;

// --------------------------------------------------------------------------------------
// DEVICEMODE - modes generated by CD3DWindowFramework

typedef struct _DEVICEMODE
{
	DISPLAYMODE *pDispMode;
	int   nAdapter;
	float fVersion;
	DWORD dwDevType;
	DWORD dwBehaviors;
	DWORD dwPSGPRegChange;

	_DEVICEMODE *pNext;
}DEVICEMODE, *PDEVICEMODE;

// --------------------------------------------------------------------------------------
// Adapter struct - maintains info for each adapter on a system

typedef struct _ADAPTER
{
	TCHAR*		sAdapterName;					// Adapter string
	TCHAR*		sChipName;						// Graphics chip name
	TCHAR*		sDescription;					// Description string
	TCHAR*		sDevicePath;					// Path to device
	TCHAR*		sChipDAC;						
	TCHAR*		sDriver;						// Driver string
	TCHAR*		sVersion;						// Driver version
	TCHAR*		sPnPID;							// PnP ID
    DISPLAYMODE	DesktopMode;					// Desktop mode
	DWORD       dwChipID;						// Graphics chip ID
	DWORD       dwVendorID;						// Chip vendor ID
	UINT		nAdapterOrdinal;				// Display enum ordinal, since it may not match d3d
    
	GRAPHICSBUSTYPES    eBusType;				// AGP, PCI, etc.
	bool				bTextureAGP;			// Can it texture to AGP?
    bool				bHardwareVP;			// Does adapter support HW VP
	bool				bPure;					// Adapter supports pure
	RECT        		rMonitorRect;           // Desktop coordinates for this monitor
    PDISPLAYMODE 		pModes;       			// List of display modes
	int					nModes;					// Number of modes in list
	UINT				m_nDisplyModesAlloc;	// Number of display modes allocated
	 	
	// Legacy vars
    GUID        Guid;                           // Adapter GUID 
    HMONITOR    hMonitor;                       // Monitor handle

} ADAPTER, *PADAPTER;

// --------------------------------------------------------------------------------------
// LOCK_LIST - CnTexture, etc classes use this to persist lock info across Lock/Unlock

typedef struct _LOCK_LIST
{
	_LOCK_LIST*	pNext;
	UINT		uFirstFound;
	union {
	RECT*		pRects;
	UINT*		nSizes;			// deferenced as an array, doesn't look "right" as pSizes[i].cx
	};
	union {
	LOCKED_RECT* pLockedRects;
	BYTE**		 pLockedData;		// ""
	};
	union {
	BOX*		pBoxs;
	UINT*		nBoxSizes;			// deferenced as an array, doesn't look "right" as pSizes[i].cx
	};
	union {
	LOCKED_BOX*  pLockedBoxs;
	BYTE**		 pLockedBoxData;		// ""
	};
	BOOL*		bNullRect;			// ""
	BOOL*		bNullBox;			// ""
	BOOL*		bReadOnly;
} LOCK_LIST, *LPLOCK_LIST;

#ifndef MAKEFOURCC
    #define MAKEFOURCC(ch0, ch1, ch2, ch3)                              \
                ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) |       \
                ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
#endif /* defined(MAKEFOURCC) */

#ifndef RGBTOYUV
#define RGBTOYUV(r,g,b,y,u,v) \
 (y) = (BYTE)(16.0 + \
              (0.257 * (double)(r)) + \
              (0.504 * (double)(g)) + \
              (0.098 * (double)(b))); \
 (u) = (BYTE)(128.0 - \
              (0.148 * (double)(r)) - \
              (0.291 * (double)(g)) + \
              (0.439 * (double)(b))); \
 (v) = (BYTE)(128.0 + \
              (0.439 * (double)(r)) - \
              (0.386 * (double)(g)) - \
              (0.071 * (double)(b)));

#define YUVTORGB(fY0,fY1,fU,fV,c1,c2) \
        c1->R = 0.00456621f * fY0                    + 0.00625893f * fV;\
        c1->G = 0.00456621f * fY0 - 0.00153632f * fU - 0.00318811f * fV;\
        c1->B = 0.00456621f * fY0 + 0.00791071f * fU;\
        c1->A = 1.0f;\
        c1->R = (c1->R < 0.0f) ? 0.0f : ((c1->R > 1.0f) ? 1.0f : c1->R);\
        c1->G = (c1->G < 0.0f) ? 0.0f : ((c1->G > 1.0f) ? 1.0f : c1->G);\
        c1->B = (c1->B < 0.0f) ? 0.0f : ((c1->B > 1.0f) ? 1.0f : c1->B);\
        c2->R = 0.00456621f * fY1                    + 0.00625893f * fV;\
        c2->G = 0.00456621f * fY1 - 0.00153632f * fU - 0.00318811f * fV;\
        c2->B = 0.00456621f * fY1 + 0.00791071f * fU;\
        c2->A = 1.0f;\
        c2->R = (c2->R < 0.0f) ? 0.0f : ((c2->R > 1.0f) ? 1.0f : c2->R);\
        c2->G = (c2->G < 0.0f) ? 0.0f : ((c2->G > 1.0f) ? 1.0f : c2->G);\
        c2->B = (c2->B < 0.0f) ? 0.0f : ((c2->B > 1.0f) ? 1.0f : c2->B);

    // The following conversion factors were used above to pack the YUV pixels.
    // They were shamelessly stolen from overfly.
    // fYOffsetConstant=16.0; fYRFactor=0.257; fYGFactor=0.504; fYBFactor=0.098;
    // fUOffsetConstant=128.0; fURFactor=0.148; fUGFactor=0.291; fUBFactor=0.439;
    // fVOffsetConstant=128.0; fVRFactor=0.439; fVGFactor=0.386; fVBFactor=0.071;

#define PACKYUY2(dw, y0, y1, u0, v0) \
 (dw) = (DWORD)( (((DWORD)(v0) << 24) & 0xff000000) | \
                 (((DWORD)(y1) << 16) & 0x00ff0000) | \
                 (((DWORD)(u0) << 8 ) & 0x0000ff00) | \
                 (((DWORD)(y0)      ) & 0x000000ff) )

#define UNPACKYUY2(dw, y0, y1, u0, v0) \
	v0 = (float)((dw & 0xff000000) >> 24) - 128.f;\
	y1 = (float)((dw & 0x00ff0000) >> 16) - 16.f;\
	u0 = (float)((dw & 0x0000ff00) >> 8) - 128.f;\
	y0 = (float)((dw & 0x000000ff) >> 0) - 16.f;

#define PACKUYVY(dw, y0, y1, u0, v0) \
 (dw) = (DWORD)( (((DWORD)(y1) << 24) & 0xff000000) | \
                 (((DWORD)(v0) << 16) & 0x00ff0000) | \
                 (((DWORD)(y0) << 8 ) & 0x0000ff00) | \
                 (((DWORD)(u0)      ) & 0x000000ff) )

#define UNPACKUYVY(dw, y0, y1, u0, v0) \
	y1 = (float)((dw & 0xff000000) >> 24) - 16.f;\
	v0 = (float)((dw & 0x00ff0000) >> 16) - 128.f;\
	y0 = (float)((dw & 0x0000ff00) >> 8) - 16.f;\
	u0 = (float)((dw & 0x000000ff) >> 0) - 128.f;

#endif

#endif

