#include "pch.hpp"
//===========================================================================//
// File:	 Direct3D.cpp													 //
// Project:  GameOS					                                         //
// Contents: Interface to Direct3D										     //
//---------------------------------------------------------------------------//
// Date      Who    Modification                                             //
// 01/21/98  AG     Created													 //
//---------------------------------------------------------------------------//
// Copyright (C) 1999 Microsoft Corp.						                 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//
#include "ErrorHandler.hpp"
#include "DirectXDebugging.hpp"

extern DWORD TotalRenderStateChanges;

//
// IDirect3DVertexBuffer7
//
HRESULT wLock( IDirect3DVertexBuffer7* D3Dvb7, DWORD dwFlags, LPVOID* lplpData, LPDWORD lpdwSize )
{
	LOG_BLOCK("D3D::Lock");
	SPEW(( GROUP_DIRECT3D, "Lock(0x%x)",(int)D3Dvb7 ));

	HRESULT result=D3Dvb7->Lock( dwFlags, lplpData, lpdwSize );

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - Lock(0x%x)",result,ErrorNumberToMessage(result),(int)D3Dvb7 ));

	return result;
}

HRESULT wUnlock( IDirect3DVertexBuffer7* D3Dvb7 )
{
	LOG_BLOCK("D3D::Unlock");
	SPEW(( GROUP_DIRECT3D, "Unlock(0x%x)",(int)D3Dvb7 ));

	HRESULT result=D3Dvb7->Unlock();

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - Unlock(0x%x)",result,ErrorNumberToMessage(result),(int)D3Dvb7 ));

	return result;
}

HRESULT wOptimize( IDirect3DVertexBuffer7* D3Dvb7, LPDIRECT3DDEVICE7 lpD3DDevice, DWORD dwFlags )
{
	LOG_BLOCK("D3D::Optimize");
	SPEW(( GROUP_DIRECT3D, "Optimize(0x%x)",(int)D3Dvb7 ));

	HRESULT result=D3Dvb7->Optimize(lpD3DDevice,dwFlags);

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - Optimize(0x%x)",result,ErrorNumberToMessage(result),(int)D3Dvb7 ));

	return result;
}

HRESULT wProcessVertices( IDirect3DVertexBuffer7* D3Dvb7, DWORD dwVertexOp, DWORD dwDestIndex, DWORD dwCount, LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer, DWORD dwSrcIndex, LPDIRECT3DDEVICE7 lpD3DDevice, DWORD dwFlags )
{
	LOG_BLOCK("D3D::ProcessVertices");
	SPEW(( GROUP_DIRECT3D, "ProcessVertices(Dest=0x%x, Src=0x%x, Vertices=%d)",(int)D3Dvb7, (int)lpSrcBuffer, dwCount ));

	HRESULT result=D3Dvb7->ProcessVertices(dwVertexOp,dwDestIndex,dwCount,/*pGetDXVB(lpSrcBuffer,lpD3DDevice)*/lpSrcBuffer,dwSrcIndex,lpD3DDevice,dwFlags);

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - ProcessVertices(Dest=0x%x, Src=0x%x, Vertices=%d)",result,ErrorNumberToMessage(result),(int)D3Dvb7, (int)lpSrcBuffer, dwCount ));

	return result;
}


//
// IID_IDirect3D7
//
HRESULT wCreateDevice( IDirect3D7* d3d7, REFCLSID rclsid, IDirectDrawSurface7* lpDDS, IDirect3DDevice7** lplpD3DDevice7 )
{
	LOG_BLOCK("D3D::CreateDevice");
	SPEW(( GROUP_DIRECT3D, "CreateDevice(%s from 0x%x)+",Get3DDevice(rclsid),(int)lpDDS));

	HRESULT result=d3d7->CreateDevice( rclsid, lpDDS, lplpD3DDevice7 );

	SPEW(( GROUP_DIRECT3D, " -0x%x",(int)*lplpD3DDevice7));
	
	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - CreateDevice(%s from 0x%x)",result,ErrorNumberToMessage(result),Get3DDevice(rclsid),(int)lpDDS));

	return result;
}

HRESULT wEnumDevices( IDirect3D7* d3d7, LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback, LPVOID lpUserArg )
{
	LOG_BLOCK("D3D::EnumDevices");
	SPEW(( GROUP_DIRECT3D, "EnumDevices()" ));

	HRESULT result=d3d7->EnumDevices( lpEnumDevicesCallback, lpUserArg );

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - EnumDevices()",result,ErrorNumberToMessage(result) ));

	return result;
}

HRESULT wEnumZBufferFormats( IDirect3D7* d3d7, REFCLSID riidDevice, LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback, void* lpContext )
{
	LOG_BLOCK("D3D::EnumZBufferFormats");
	SPEW(( GROUP_DIRECT3D, "EnumZBufferFormats(%s)",Get3DDevice(riidDevice) ));

	HRESULT result=d3d7->EnumZBufferFormats(riidDevice,lpEnumCallback,lpContext);

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - EnumZBufferFormats(%s)",result,ErrorNumberToMessage(result),Get3DDevice(riidDevice) ));

	return result;
}

HRESULT wCreateVertexBuffer( IDirect3D7* d3d7, LPD3DVERTEXBUFFERDESC lpVBDesc, LPDIRECT3DVERTEXBUFFER7* lplpD3DVertexBuffer, DWORD dwFlags )
{
	LOG_BLOCK("D3D::CreateVertexBuffer");
	SPEW(( GROUP_DIRECT3D, "CreateVertexBuffer(%d Vertices)+",lpVBDesc->dwNumVertices ));

	HRESULT result=d3d7->CreateVertexBuffer(lpVBDesc,lplpD3DVertexBuffer,dwFlags);

	SPEW(( GROUP_DIRECT3D, " -0x%x",(int)*lplpD3DVertexBuffer));

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - CreateVertexBuffer(%d Vertices)",result,ErrorNumberToMessage(result),lpVBDesc->dwNumVertices ));

	return result;
}






//
// IDirect3DDevice7
//
HRESULT wBeginScene( IDirect3DDevice7* d3dDevice7 )
{
	LOG_BLOCK("D3D::BeginScene");
	SPEW(( GROUP_DIRECT3D, "BeginScene()" ));

	HRESULT result=d3dDevice7->BeginScene();

	if( FAILED(result) && result!=DDERR_SURFACELOST )
		PAUSE(( "FAILED (0x%x - %s) - BeginScene()",result,ErrorNumberToMessage(result)));

	return result;
}

HRESULT wEndScene( IDirect3DDevice7* d3dDevice7 )
{
	LOG_BLOCK("D3D::EndScene");
	SPEW(( GROUP_DIRECT3D, "EndScene()" ));

	HRESULT result=d3dDevice7->EndScene();

	//Original
	//if( FAILED(result)  )
	//sanghoon
	if( FAILED(result)  && result!=DDERR_SURFACELOST)
		PAUSE(( "FAILED (0x%x - %s) - EndScene()",result,ErrorNumberToMessage(result)));

	return result;
}

HRESULT wSetTransform( IDirect3DDevice7* d3dDevice7, D3DTRANSFORMSTATETYPE dtstTransformStateType, LPD3DMATRIX lpD3DMatrix )
{
	LOG_BLOCK("D3D::SetTransform");
	SPEW(( GROUP_DIRECT3D, "SetTransform(%s)",GetTransformType(dtstTransformStateType) ));

	HRESULT result=d3dDevice7->SetTransform(dtstTransformStateType,lpD3DMatrix);

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - SetTransform(%s)",result,ErrorNumberToMessage(result),GetTransformType(dtstTransformStateType) ));

	return result;
}

HRESULT wMultiplyTransform( IDirect3DDevice7* d3dDevice7, D3DTRANSFORMSTATETYPE dtstTransformStateType, LPD3DMATRIX lpD3DMatrix )
{
	LOG_BLOCK("D3D::MultiplyTransform");
	SPEW(( GROUP_DIRECT3D, "MultiplyTransform(%s)",GetTransformType(dtstTransformStateType) ));

	HRESULT result=d3dDevice7->MultiplyTransform(dtstTransformStateType,lpD3DMatrix);

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - MultiplyTransform()",result,ErrorNumberToMessage(result),GetTransformType(dtstTransformStateType) ));

	return result;
}

HRESULT wSetLight( IDirect3DDevice7* d3dDevice7, DWORD dwLightIndex, LPD3DLIGHT7 lpLight )
{
	LOG_BLOCK("D3D::SetLight");
	SPEW(( GROUP_DIRECT3D, "SetLight(%d, %s)",dwLightIndex,GetLightInfo(lpLight) ));

	HRESULT result=d3dDevice7->SetLight(dwLightIndex,lpLight);

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - SetLight(%d, %s)",result,ErrorNumberToMessage(result),dwLightIndex,GetLightInfo(lpLight) ));

	return result;
}

HRESULT wLightEnable( IDirect3DDevice7* d3dDevice7, DWORD dwLightIndex, bool Enable )
{
	LOG_BLOCK("D3D::LightEnable");
	SPEW(( GROUP_DIRECT3D, "LightEnable(%d, %s)",dwLightIndex,(Enable ? "enable" : "disable") ));

	HRESULT result=d3dDevice7->LightEnable(dwLightIndex,Enable);

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - LightEnable(%d, %s)",result,ErrorNumberToMessage(result),dwLightIndex,(Enable ? "enable" : "disable") ));

	return result;
}

HRESULT wSetMaterial( IDirect3DDevice7* d3dDevice7, LPD3DMATERIAL7 lpMaterial )
{
	LOG_BLOCK("D3D::SetMaterial");
	SPEW(( GROUP_DIRECT3D, "SetMaterial(%s)",GetMaterialInfo(lpMaterial) ));

	HRESULT result=d3dDevice7->SetMaterial(lpMaterial);

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - SetMaterial(%s)",result,ErrorNumberToMessage(result),GetMaterialInfo(lpMaterial) ));

	return result;
}

HRESULT wSetViewport( IDirect3DDevice7* d3dDevice7, LPD3DVIEWPORT7 lpViewport )
{
	LOG_BLOCK("D3D::SetViewport");
	SPEW(( GROUP_DIRECT3D, "SetViewport()" ));

	HRESULT result=d3dDevice7->SetViewport(lpViewport);

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - SetViewport()",result,ErrorNumberToMessage(result) ));

	return result;
}

HRESULT wClear( IDirect3DDevice7* d3dDevice7, DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags, DWORD dwColor, D3DVALUE dvZ, DWORD dwStencil )
{
	LOG_BLOCK("D3D::Clear");
	SPEW(( GROUP_DIRECT3D, "Clear(%s)",GetClearArea(dwCount,lpRects,dwFlags)));

	HRESULT result=d3dDevice7->Clear( dwCount,lpRects,dwFlags,dwColor,dvZ,dwStencil );

	if( FAILED(result) && result!=DDERR_SURFACELOST )
		PAUSE(( "FAILED (0x%x - %s) - Clear(%s)",result,ErrorNumberToMessage(result),GetClearArea(dwCount,lpRects,dwFlags)));

	return result;
}

HRESULT wGetCaps( IDirect3DDevice7* d3dDevice7, LPD3DDEVICEDESC7 lpD3DHWDevDesc )
{
	LOG_BLOCK("D3D::GetCaps");
	SPEW(( GROUP_DIRECT3D, "GetCaps(0x%x)",(int)d3dDevice7 ));

	HRESULT result=d3dDevice7->GetCaps(lpD3DHWDevDesc);

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - GetCaps(0x%x)",result,ErrorNumberToMessage(result),(int)d3dDevice7));

	return result;
}

HRESULT wSetRenderState( IDirect3DDevice7* d3dDevice7, D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState )
{
	LOG_BLOCK("D3D::SetRenderState");
	#ifdef LAB_ONLY
	TotalRenderStateChanges++;
	#endif

	SPEW(( GROUP_DIRECT3D, "SetRenderState(%s)",GetRenderState(dwRenderStateType,dwRenderState)));

	HRESULT result=d3dDevice7->SetRenderState(dwRenderStateType,dwRenderState);

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - SetRenderState(%s)",result,ErrorNumberToMessage(result),GetRenderState(dwRenderStateType,dwRenderState)));

	return result;
}

HRESULT wEnumTextureFormats( IDirect3DDevice7* d3dDevice7, LPD3DENUMPIXELFORMATSCALLBACK lpd3dEnumPixelProc, void* lpArg )
{
	LOG_BLOCK("D3D::EnumTextureFormats");
	SPEW(( GROUP_DIRECT3D, "EnumTextureFormats()" ));

	HRESULT result=d3dDevice7->EnumTextureFormats(lpd3dEnumPixelProc,lpArg);

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - EnumTextureFormats()",result,ErrorNumberToMessage(result) ));

	return result;
}

HRESULT wSetTexture( IDirect3DDevice7* d3dDevice7, DWORD dwStage, IDirectDrawSurface7* lpTexture )
{
	LOG_BLOCK("D3D::SetTexture");
	SPEW(( GROUP_DIRECT3D, "SetTexture(%d,0x%x)",dwStage,lpTexture ));

	HRESULT result=d3dDevice7->SetTexture(dwStage,lpTexture);

	if( FAILED(result) && result!=DDERR_SURFACELOST )
		PAUSE(( "FAILED (0x%x - %s) - SetTexture(%d,0x%x)",result,ErrorNumberToMessage(result),dwStage,lpTexture ));

	return result;
}

HRESULT wSetTextureStageState( IDirect3DDevice7* d3dDevice7, DWORD dwStage, D3DTEXTURESTAGESTATETYPE dwState, DWORD dwValue )
{
	LOG_BLOCK("D3D::SetTextureStageState");
	#ifdef LAB_ONLY
	TotalRenderStateChanges++;
	#endif

	SPEW(( GROUP_DIRECT3D, "SetTextureStageState(%d,%s)",dwStage,GetStageSet(dwState,dwValue) ));

	HRESULT result=d3dDevice7->SetTextureStageState(dwStage,dwState,dwValue);

	if( FAILED(result) && result!=DDERR_SURFACELOST )
		PAUSE(( "FAILED (0x%x - %s) - SetTextureStageState(%d,%s)",result,ErrorNumberToMessage(result),dwStage,GetStageSet(dwState,dwValue) ));

	return result;
}

HRESULT wValidateDevice( IDirect3DDevice7* d3dDevice7, DWORD* ExtraPasses )
{
	LOG_BLOCK("D3D::ValidateDevice");
	SPEW(( GROUP_DIRECT3D, "ValidateDevice()+" ));

	HRESULT result=d3dDevice7->ValidateDevice(ExtraPasses);

	SPEW(( GROUP_DIRECT3D, " -0x%x",(int)*ExtraPasses ));

	if( FAILED(result) )
		PAUSE(( "FAILED (0x%x - %s) - ValidateDevice()",result,ErrorNumberToMessage(result) ));

	return result;
}

HRESULT wLoad( IDirect3DDevice7* d3dDevice7, IDirectDrawSurface7* lpDestTex, LPPOINT lpDestPoint, IDirectDrawSurface7* lpSrcTex, LPRECT lprcSrcRect, DWORD dwFlags )
{
	LOG_BLOCK("D3D::Load");
	SPEW(( GROUP_DIRECT3D, "Load(0x%x with 0x%x)",(int)lpDestTex, (int)lpSrcTex ));

	HRESULT result=d3dDevice7->Load( lpDestTex, lpDestPoint, lpSrcTex, lprcSrcRect, dwFlags );

	if( FAILED(result) && result!=DDERR_SURFACELOST )
		PAUSE(( "FAILED (0x%x - %s) - Load(0x%x with 0x%x)",result,ErrorNumberToMessage(result),(int)lpDestTex, (int)lpSrcTex ));

	return result;
}

#ifdef LAB_ONLY
HRESULT wDrawPrimitive( IDirect3DDevice7* d3dDevice7, D3DPRIMITIVETYPE dptPrimitiveType, DWORD dvtVertexType, LPVOID lpvVertices, DWORD dwVertexCount, DWORD dwFlags )
{
	LOG_BLOCK("D3D::DrawPrimitive");
	SPEW(( GROUP_DIRECT3D, "DrawPrimitive( %s)",GetDrawPrimitiveData(dptPrimitiveType,dvtVertexType,lpvVertices,dwVertexCount,dwFlags)));

	HRESULT result=d3dDevice7->DrawPrimitive( dptPrimitiveType,dvtVertexType,lpvVertices,dwVertexCount,dwFlags );

	if( FAILED(result) && result!=DDERR_SURFACELOST )
		PAUSE(( "FAILED (0x%x - %s) - DrawPrimitive( %s)",result,ErrorNumberToMessage(result),GetDrawPrimitiveData(dptPrimitiveType,dvtVertexType,lpvVertices,dwVertexCount,dwFlags)));

	return result;
}
#endif

#ifdef LAB_ONLY
HRESULT wDrawIndexedPrimitive( IDirect3DDevice7* d3dDevice7, D3DPRIMITIVETYPE d3dptPrimitiveType, DWORD dwVertexTypeDesc, LPVOID lpvVertices, DWORD dwVertexCount, LPWORD lpwIndices, DWORD dwIndexCount, DWORD dwFlags )
{
	LOG_BLOCK("D3D::DrawIndexedPrimitive");
	SPEW(( GROUP_DIRECT3D, "DrawIndexedPrimitive( %s)",GetDrawIndexedPrimitiveData(d3dptPrimitiveType,dwVertexTypeDesc,lpvVertices,dwVertexCount,lpwIndices,dwIndexCount,dwFlags) ));

	HRESULT result=d3dDevice7->DrawIndexedPrimitive( d3dptPrimitiveType,dwVertexTypeDesc,lpvVertices,dwVertexCount,lpwIndices,dwIndexCount,dwFlags );

	if( FAILED(result) && result!=DDERR_SURFACELOST )
		PAUSE(( "FAILED (0x%x - %s) - DrawIndexedPrimitive( %s)",result,ErrorNumberToMessage(result),GetDrawIndexedPrimitiveData(d3dptPrimitiveType,dwVertexTypeDesc,lpvVertices,dwVertexCount,lpwIndices,dwIndexCount,dwFlags) ));

	return result;
}
#endif

HRESULT wDrawIndexedPrimitiveVB( IDirect3DDevice7* d3dDevice7, D3DPRIMITIVETYPE d3dptPrimitiveType, LPDIRECT3DVERTEXBUFFER7 lpd3dVertexBuffer, DWORD dwStartVertex, DWORD dwNumVertices, LPWORD lpwIndices, DWORD dwIndexCount, DWORD dwFlags )
{
	LOG_BLOCK("D3D::DrawIndexedPrimitiveVB");
	SPEW(( GROUP_DIRECT3D, "DrawIndexedPrimitiveVB(0x%x)",(int)lpd3dVertexBuffer ));


	HRESULT result = S_OK;

	//If we are not using Blade, this should be a NULL ptr
	if(g_pGetDXVB)
	{
		result=d3dDevice7->DrawIndexedPrimitiveVB( d3dptPrimitiveType,g_pGetDXVB(lpd3dVertexBuffer,d3dDevice7),dwStartVertex,dwNumVertices,lpwIndices,dwIndexCount,dwFlags );

		if( FAILED(result) && result!=DDERR_SURFACELOST )
			PAUSE(( "FAILED (0x%x - %s) - DrawIndexedPrimitiveVB(0x%x)",result,ErrorNumberToMessage(result),(int)lpd3dVertexBuffer ));

		//return result;
	}else{
		result=d3dDevice7->DrawIndexedPrimitiveVB( d3dptPrimitiveType,lpd3dVertexBuffer,dwStartVertex,dwNumVertices,lpwIndices,dwIndexCount,dwFlags );

		if( FAILED(result) && result!=DDERR_SURFACELOST )
			PAUSE(( "FAILED (0x%x - %s) - DrawIndexedPrimitiveVB(0x%x)",result,ErrorNumberToMessage(result),(int)lpd3dVertexBuffer ));
	}

	return result;		
}

HRESULT wDrawPrimitiveVB( IDirect3DDevice7* d3dDevice7, D3DPRIMITIVETYPE d3dptPrimitiveType, LPDIRECT3DVERTEXBUFFER7 lpd3dVertexBuffer, DWORD dwStartVertex, DWORD dwNumVertices, DWORD dwFlags )
{
	LOG_BLOCK("D3D::DrawPrimitiveVB");
	SPEW(( GROUP_DIRECT3D, "DrawPrimitiveVB(0x%x)",(int)lpd3dVertexBuffer ));

	HRESULT result = S_OK;

	//If we are not using Blade, this should be a NULL ptr
	if(g_pGetDXVB)
	{
		result=d3dDevice7->DrawPrimitiveVB( d3dptPrimitiveType,g_pGetDXVB(lpd3dVertexBuffer,d3dDevice7),dwStartVertex,dwNumVertices,dwFlags );

		if( FAILED(result) && result!=DDERR_SURFACELOST )
			PAUSE(( "FAILED (0x%x - %s) - DrawPrimitiveVB(0x%x)",result,ErrorNumberToMessage(result),(int)lpd3dVertexBuffer ));
	}else{
		result=d3dDevice7->DrawPrimitiveVB( d3dptPrimitiveType,lpd3dVertexBuffer,dwStartVertex,dwNumVertices,dwFlags );

		if( FAILED(result) && result!=DDERR_SURFACELOST )
			PAUSE(( "FAILED (0x%x - %s) - DrawPrimitiveVB(0x%x)",result,ErrorNumberToMessage(result),(int)lpd3dVertexBuffer ));
	}

	return result;
}










