// Jet3d - JMiniApp
// Filename: utils.c
// Non-class based helper funcs.
/***************************************************************
Copyright (C) 2000 Novasoft Consulting

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*****************************************************************/






// DirectX stuff.
#include <ddraw.h>
#include <d3d.h>
#include <d3dtypes.h> 
#include <dinput.h>


/****************************************************************************
 *
 *      GetDXVersion
 *
 *  This function returns two arguments:
 *	dwDXVersion:
 *	    0	    No DirectX installed or a corrupted install.
 *	    0x100   DirectX version 1 installed
 *	    0x200   DirectX 2 installed
 *	    0x300   DirectX 3 installed
 *	    0x500   At least DirectX 5 installed
 *	    0x600   At least DirectX 6 installed
 *		0x700   At least DirectX 7 installed
 ****************************************************************************/

typedef HRESULT (WINAPI *DIRECTDRAWCREATE)(GUID *, LPDIRECTDRAW *, IUnknown *);
typedef HRESULT (WINAPI *DIRECTINPUTCREATE)(HINSTANCE, DWORD, LPDIRECTINPUT *, IUnknown *);
typedef HRESULT (WINAPI *DIRECTDRAWCREATEEX)(GUID FAR *lpGUID, LPVOID *lplpDD, REFIID iid,              
                                             IUnknown FAR *pUnkOuter);

void GetDXVersion(LPDWORD pdwDXVersion)
{
    HRESULT					lhr_result;
    HINSTANCE				DDHinst = 0;
    HINSTANCE				DIHinst = 0;
    LPDIRECTDRAW			pDDraw = 0;
    LPDIRECTDRAW2			pDDraw2 = 0;
    LPDIRECTDRAW7			pDDraw7 = 0;
    DIRECTDRAWCREATE	    DirectDrawCreate = 0;
	DIRECTDRAWCREATEEX		DirectDrawCreateEx = 0;
    DIRECTINPUTCREATE	    DirectInputCreate = 0;
    LPDIRECTDRAWSURFACE	    pSurf = 0;
    LPDIRECTDRAWSURFACE3    pSurf3 = 0;
	LPDIRECTDRAWSURFACE4    pSurf4 = 0;
	DDSURFACEDESC			desc;
    
	// Initilize, set to unknown.
	*pdwDXVersion = 0;
	


    // First see if DDRAW.DLL even exists.
    DDHinst = LoadLibrary("DDRAW.DLL");
    if(DDHinst == NULL) 
    {
	 OutputDebugString("Couldn't LoadLibrary DDraw\r\n");
	 return;
    }
   	

    //  See if we can create the DirectDraw object.
    DirectDrawCreate = (DIRECTDRAWCREATE)GetProcAddress(DDHinst, "DirectDrawCreate");
    
	// We've finished with this now.
	FreeLibrary(DDHinst);

	if(DirectDrawCreate == 0) 
    {
	 OutputDebugString("Couldn't GetProcAddress DDrawCreate\r\n");
	 return;
    }

  
    lhr_result = DirectDrawCreate(NULL, &pDDraw, NULL);
    if(FAILED(lhr_result)) 
    {
	 OutputDebugString("Couldn't create DDraw\r\n");
	 return;
    }

    //  So DirectDraw exists.  We are at least DX1.
    *pdwDXVersion = 0x100;

    // Let's see if IID_IDirectDraw2 exists.
    lhr_result = pDDraw->QueryInterface(IID_IDirectDraw2, (LPVOID *)&pDDraw2);
    if(FAILED(lhr_result)) 
    {
	 pDDraw->Release();
	 OutputDebugString("Couldn't QI DDraw2\r\n");
	 return;
    }
    
	// We've finished with this.
	pDDraw2->Release();
	
	/*
    * IDirectDraw2 exists. We must be at least DX2
    */
    *pdwDXVersion = 0x200;

    /*
    *  See if we can create the DirectInput object.
    */
    DIHinst = LoadLibrary("DINPUT.DLL");
    if(DIHinst == NULL) 
    {
     OutputDebugString("Couldn't LoadLibrary DInput\r\n");
	 pDDraw->Release();
	 return;
    }

    DirectInputCreate = (DIRECTINPUTCREATE)GetProcAddress(DIHinst, "DirectInputCreateA");
    FreeLibrary(DIHinst);

    if(DirectInputCreate == 0) 
    {
     pDDraw->Release();
     OutputDebugString("Couldn't GetProcAddress DInputCreate\r\n");
	 return;
    }

    
    // DirectInputCreate exists. That's enough to tell us that we are at least DX3
    *pdwDXVersion = 0x300;

    // Checks for 3a vs 3b?
     

    
    // We can tell if DX5 is present by checking for the existence of IDirectDrawSurface3.
    // First we need a surface to QI off of.
    ZeroMemory(&desc, sizeof(desc));
    desc.dwSize = sizeof(desc);
    desc.dwFlags = DDSD_CAPS;
    desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

    lhr_result = pDDraw->SetCooperativeLevel(NULL, DDSCL_NORMAL);
    if(FAILED(lhr_result)) 
    {
	 // Failure. This means DDraw isn't properly installed.
	pDDraw->Release();
	*pdwDXVersion = 0; // Error.
    OutputDebugString("Couldn't set coop level\r\n");
	return;
    }

    lhr_result = pDDraw->CreateSurface(&desc, &pSurf, NULL);
    if(FAILED(lhr_result)) 
    {
	// Failure. This means DDraw isn't properly installed.
	pDDraw->Release();
	*pdwDXVersion = 0; // Error.
    OutputDebugString("Couldn't CreateSurface\r\n");
	return;
    }

    
    // Try for the IDirectDrawSurface3 interface. 
    if(FAILED(pSurf->QueryInterface(IID_IDirectDrawSurface3,(LPVOID*)&pSurf3)))
    {
     pSurf->Release();
     pDDraw->Release();
     return;
    }

    // QI for IDirectDrawSurface3 succeeded. We must be at least DX5
    *pdwDXVersion = 0x500;

	// Don't need this anymore.
	pSurf3->Release();


    // Try for the IDirectDrawSurface4 interface. 
    if(FAILED(pSurf->QueryInterface(IID_IDirectDrawSurface4,(LPVOID*)&pSurf4)))
    {
     pSurf->Release();
     pDDraw->Release();
     return;
    }

	 // QI for IDirectDrawSurface4 succeeded. We must be at least DX6.
    *pdwDXVersion = 0x600;

	// Don't need this anymore.
	pSurf4->Release();
    pSurf->Release();
    pDDraw->Release();


    // See if we can create a DX7 Direct Draw object.
	DDHinst = LoadLibrary("DDRAW.DLL");
    if(DDHinst == NULL) 
    {
	 OutputDebugString("Couldn't LoadLibrary DDraw\r\n");
	 return;
    }
   	
    //  See if we can create the DirectDraw 7 object.
    DirectDrawCreateEx = (DIRECTDRAWCREATEEX)GetProcAddress(DDHinst, "DirectDrawCreateEx");
    
	// We've finished with this now.
	FreeLibrary(DDHinst);

	if(DirectDrawCreateEx == 0) 
    {
	 OutputDebugString("Couldn't GetProcAddress DDrawCreateEx\r\n");
	 return;
    }

    // Create the DX7 Direct Draw object.
    lhr_result = DirectDrawCreateEx(NULL, (void**)&pDDraw7, IID_IDirectDraw7, NULL);
    if(FAILED(lhr_result)) 
    {
	 OutputDebugString("Couldn't create DDraw\r\n");
	 return;
    }    

    // We must be at least DX7.
    *pdwDXVersion = 0x700;

    pDDraw7->Release();

}









/*----------------------------------------------------------------------------
  Name:		GetAppPath(char  *ac_pathBuf, int ai_buffSize)
  Purpose:
  Notes:      

  1.  
----------------------------------------------------------------------------*/
bool GetAppPath(char  *ac_pathBuf, int ai_buffSize)
{
 int i;

	// get the exe's path and name
	if(GetModuleFileName(NULL, ac_pathBuf, ai_buffSize - 1) == 0)
	{
		return false;
	}

	// strip off exe name to leave path
	for (i=strlen(ac_pathBuf)-1; i>0; i--)
		{
			if (ac_pathBuf[i]=='\\')
				{
					ac_pathBuf[i]=0;
					break;
				}
		}

 if (i==0)
  return false;
 else
  return true;

}
