/*
 =======================================================================================
  Name        : DevVpt.c
  Description : Tas de reste d'un fichier pourri atomisé
 =======================================================================================
 */
 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include <windows.h>
#include <windowsx.h>
#include <assert.h>
#include <stdio.h>
#include <objbase.h>
#include <initguid.h>
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
/* CPA Errors management*/
#define __DeclareGlobalVariableErrGLD_h__
#include "GLD/ErrGLD.h"
#undef __DeclareGlobalVariableErrGLD_h__
 
/* CPA Memory management*/
#define __DeclareGlobalVariableMmgGLD_h__
#include "GLD/MmgGLD.h"
#undef __DeclareGlobalVariableMmgGLD_h__
 
#include "GldInc.h"
#include "SCR.h"
#include "ERM.h"
 
#include "DLLInter.h"
#include "DispMode.h"
#include "DLLCaps.h"
#include "vpt3d.h"
#include "Gli_menu.h"
 
#include "camera.h"
#include "acp_driver.h"
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
 
 
/*
 =======================================================================================
    Prototypes for internal functions
 =======================================================================================
 */
static BOOL     fn_bGetDevHandle( GLD_tdhDevice * );
static BOOL     fn_bGetVPHandle( GLD_tdhDevice, GLD_tdhViewport * );
static void     fn_vUpdateViewportSizesInPixels( GLD_tdstDevice *, GLD_tdstViewport * );
GLD_tdstDevice  *GLD_pGetDevice( GLD_tdhDevice );
 
/*
 =======================================================================================
    Globals
 =======================================================================================
 */
long            GLD_RenderingCounter = 0;
 
 
GLD_tdpstDevice g_pstGLDDevices[ C_NB_MAX_DEVICES ];   /* n devices*/
 
BOOL            g_bGLDSwapInProgress    = FALSE;       /* A swap is in progress*/
BOOL			g_bGLDBlockSwaping    = FALSE;
static BOOL     gs_bAdjustInProgress    = FALSE;       /* An adjust operation is in progress*/
 
/*
 * global var use for flip with synchro
 */
unsigned long	GLI_g_ulFrameLength = 0;
static long		GLI_gs_lBackGroundColor = 0;
 
/*
 =======================================================================================
    Misc Functions
 =======================================================================================
 */
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Script error callback
 ----------------------------------------------------------------------------------------
 */
void GLD_vCloseScr(SCR_tdst_Err_GlobalError *p_st_Err_GlobalError)
{
    Erm_fn_iMessageBox(p_st_Err_GlobalError->a_szBufferOut,"Script fatal error",MB_OK);
    Erm_fn_v_PrintErrMsg("Script general error : ", p_st_Err_GlobalError->a_szBufferOut);
    GLD_bReleaseViewportAndDevice( 0, 0 );
    exit(-3);
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Error callback
 ----------------------------------------------------------------------------------------
 */
void GLD_vCloseErr()
{
    GLD_bReleaseViewportAndDevice( 0, 0 );
    exit(-4);
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : some initialization (called once in the beginning)
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_fn_bInitGLD( void )
{
    SCR_fnp_fn_RdL0_RegisterErrorCallback(GLD_vCloseScr, SCR_CM_Err_Normal);
    Erm_fn_vSetCallBackForExit(GLD_vCloseErr);
    Erm_M_InitErrMsg(GLD); 
    Mmg_M_InitMmg(GLD);
    Mmg_M_SetModeAlloc4Ch(GLD, E_ucDynamic,C_ucMmgDefaultChannel);
    memset( &g_pstGLDDevices[0], 0, sizeof( g_pstGLDDevices ) );
    
    /* Init the timer library*/
    if ( fn_wTimerInitLibrary() == C_wTimerError )
    {
        Erm_M_UpdateLastError( GLD, C_ucErmDefaultChannel, E_uwGLD_CD_InitTimerLibFailed, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, _szPersonalMsg_ );
        return FALSE; /* can't init timers*/
    }
 
    return TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : dump use of memory
 ----------------------------------------------------------------------------------------
 */
#ifndef RETAIL
void GLD_PrintUsedStaticMemory ()
{
	Mmg_M_PrintUsedStaticMemoryInModule(GLD);
}
#endif /* RETAIL */
 
/*
 =======================================================================================
    Functions
 =======================================================================================
 */
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Update viewport size
 ----------------------------------------------------------------------------------------
 */
static void fn_vUpdateViewportSizesInPixels( GLD_tdstDevice *p_stDev, GLD_tdstViewport *p_stVP )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	int	iLeft, iTop, iRight, iBottom;
    int iClipLeft, iClipRight, iClipTop, iClipBottom;
    int iWidth, iHeight;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
	iWidth = 1 + (p_stVP->stViewAttrib.dwWidthInPercent * (p_stDev->stDevAttrib.dwWidth-1)) / 100;
	iHeight = 1 + (p_stVP->stViewAttrib.dwHeightInPercent * (p_stDev->stDevAttrib.dwHeight-1)) / 100;
	p_stVP->stViewAttrib.dwWidth  = iWidth;
	p_stVP->stViewAttrib.dwHeight = iHeight;
 
	p_stVP->stViewAttrib.dwTopInPixForClip = 0;
	p_stVP->stViewAttrib.dwLeftInPixForClip = 0;
	p_stVP->stViewAttrib.dwBottomInPixForClip = iHeight - 1;
	p_stVP->stViewAttrib.dwRightInPixForClip = iWidth - 1;
 
	/*
	 * Take care of position
	 */
	iLeft = p_stVP->stViewAttrib.dwLeftInPixForClip + p_stVP->stViewAttrib.iOffsetPosX;
	iRight = p_stVP->stViewAttrib.dwRightInPixForClip + p_stVP->stViewAttrib.iOffsetPosX;
	iTop = p_stVP->stViewAttrib.dwTopInPixForClip + p_stVP->stViewAttrib.iOffsetPosY;
	iBottom = p_stVP->stViewAttrib.dwBottomInPixForClip + p_stVP->stViewAttrib.iOffsetPosY;
 
	if((iRight < 0) || (iLeft > (int) (p_stDev->stDevAttrib.dwWidth - 1)))
		p_stVP->stViewAttrib.dwLeftInPixForClip = p_stVP->stViewAttrib.dwRightInPixForClip = 0;
	else if((iBottom < 0) || (iTop > (int) (p_stDev->stDevAttrib.dwHeight-1)))
		p_stVP->stViewAttrib.dwTopInPixForClip = p_stVP->stViewAttrib.dwBottomInPixForClip = 0;
	else
	{
		if(iLeft < 0)
		{
			p_stVP->stViewAttrib.dwLeftInPixForClip = 0;
			p_stVP->stViewAttrib.dwRightInPixForClip = iRight;
		}
		else if(iRight > (int) (p_stDev->stDevAttrib.dwWidth - 1))
		{
			p_stVP->stViewAttrib.dwLeftInPixForClip = iLeft;
			p_stVP->stViewAttrib.dwRightInPixForClip = p_stDev->stDevAttrib.dwWidth - 1;
		}
		else
		{
			p_stVP->stViewAttrib.dwLeftInPixForClip = iLeft;
			p_stVP->stViewAttrib.dwRightInPixForClip = iRight;
		}
		if(iTop < 0)
		{
			p_stVP->stViewAttrib.dwTopInPixForClip = 0;
			p_stVP->stViewAttrib.dwBottomInPixForClip = iBottom;
		}
		else if(iBottom > (int) (p_stDev->stDevAttrib.dwHeight - 1))
		{
			p_stVP->stViewAttrib.dwTopInPixForClip = iTop;
			p_stVP->stViewAttrib.dwBottomInPixForClip = p_stDev->stDevAttrib.dwHeight - 1;
		}
		else
		{
			p_stVP->stViewAttrib.dwTopInPixForClip = iTop;
			p_stVP->stViewAttrib.dwBottomInPixForClip = iBottom;
		}
	}
 
	/*
	 * Clipping.
	 */
	iClipTop = (iHeight * p_stVP->stViewAttrib.dwClipTopInPercent) / 100;
	iClipBottom = (iHeight * p_stVP->stViewAttrib.dwClipBottomInPercent) / 100;
	iClipLeft = (iWidth * p_stVP->stViewAttrib.dwClipLeftInPercent) / 100;
	iClipRight = (iWidth * p_stVP->stViewAttrib.dwClipRightInPercent) / 100;
	iClipTop += iTop;
	iClipBottom += iTop;
	iClipLeft += iLeft;
	iClipRight += iLeft;
 
	if(iClipLeft < 0)
		iClipLeft = 0;
	if(iClipTop < 0)
		iClipTop = 0;
	if(iClipRight > (int) (p_stDev->stDevAttrib.dwWidth))
		iClipRight = (p_stDev->stDevAttrib.dwWidth);
	if(iClipBottom > (int) (p_stDev->stDevAttrib.dwHeight))
		iClipBottom = (p_stDev->stDevAttrib.dwHeight);
 
	p_stVP->stViewAttrib.dwClipTopInPix = iClipTop;
	p_stVP->stViewAttrib.dwClipBottomInPix = iClipBottom;
	p_stVP->stViewAttrib.dwClipLeftInPix = iClipLeft;
	p_stVP->stViewAttrib.dwClipRightInPix = iClipRight;
 
	p_stVP->bIsLocked = FALSE;
 
    p_stVP->stViewAttrib.dwLeftInPix   = p_stVP->stViewAttrib.dwTopInPix = 0;
	p_stVP->stViewAttrib.dwRightInPix  = p_stVP->stViewAttrib.dwWidth;
	p_stVP->stViewAttrib.dwBottomInPix = p_stVP->stViewAttrib.dwHeight;
 
    /*
     * Bidouille pour dessiner deux rectangles noir en bas pour virer couleur du brouillard
     */
    GLI_DRV_vNoBlackPolygon();
	if ( p_stVP->stViewAttrib.dwClipTopInPix > 0 )
        GLI_DRV_vAddBlackPolygon( 0, 0, p_stVP->stViewAttrib.dwWidth, p_stVP->stViewAttrib.dwClipTopInPix );
    if ( p_stVP->stViewAttrib.dwClipBottomInPix < p_stVP->stViewAttrib.dwHeight )
        GLI_DRV_vAddBlackPolygon( 0, p_stVP->stViewAttrib.dwClipBottomInPix, p_stVP->stViewAttrib.dwWidth, p_stVP->stViewAttrib.dwHeight );
    if ( p_stVP->stViewAttrib.dwClipLeftInPix > 0 )
        GLI_DRV_vAddBlackPolygon( 0, 0, p_stVP->stViewAttrib.dwClipLeftInPix, p_stVP->stViewAttrib.dwHeight );
    if ( p_stVP->stViewAttrib.dwClipRightInPix < p_stVP->stViewAttrib.dwWidth )
        GLI_DRV_vAddBlackPolygon( p_stVP->stViewAttrib.dwClipRightInPix, 0, p_stVP->stViewAttrib.dwWidth, p_stVP->stViewAttrib.dwHeight );
};
 
/*
 =======================================================================================
    Handles stuff
 =======================================================================================
 */
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Get a unused device handle
 ----------------------------------------------------------------------------------------
 */
static BOOL fn_bGetDevHandle( GLD_tdhDevice *phDev )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdhDevice hDev;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /* Looking for next handle  */
    for ( hDev=0; hDev < C_NB_MAX_DEVICES; hDev++ )
    {
        if ( !g_pstGLDDevices[ hDev ] ) 
        {
            *phDev = hDev;
            return TRUE;
        }
    }
 
    *phDev = -1;
    return FALSE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Test validity device handle
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bIsDeviceHandleValid( GLD_tdhDevice hDev )
{
    if ( hDev < 0 || hDev >= C_NB_MAX_DEVICES )
        return FALSE;
 
    return ( g_pstGLDDevices[ hDev ] != NULL ); 
}
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Invalidate device handle
 ----------------------------------------------------------------------------------------
 */
void GLD_vInvalidateDeviceHandle( GLD_tdhDevice *p_hDev )
{
    assert( p_hDev );
    *p_hDev = -1;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Get new Viewport handle
 ----------------------------------------------------------------------------------------
 */
static BOOL fn_bGetVPHandle( GLD_tdhDevice hDev, GLD_tdhViewport *phVP )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdhViewport   hOldVP;
    GLD_tdpstDevice   pstDev;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /* Get the pointer*/
    pstDev = GLD_pGetDevice(hDev);
 
    /* Looking for next handle*/
    for ( hOldVP=0; hOldVP < C_NB_MAX_VPT_IN_DEV; hOldVP++ )
    {
        if ( !(pstDev->pstViewports)[ hOldVP ] )
        { 
            *phVP = hOldVP;
            return TRUE;
        }
    }
 
    *phVP = -1; 
    return FALSE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Get Viewport
 ----------------------------------------------------------------------------------------
 */
GLD_tdstViewport *GLD_pGetViewport(GLD_tdhDevice hDev, GLD_tdhViewport hOldVP)
{
    return(g_pstGLDDevices[ hDev ]->pstViewports[ hOldVP ]);
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Get device
 ----------------------------------------------------------------------------------------
 */
GLD_tdstDevice *GLD_pGetDevice(GLD_tdhDevice hDev)
{
    return(g_pstGLDDevices[ hDev ]);
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : test viewport handle validity
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bIsViewportHandleValid( GLD_tdhViewport hVP )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdhDevice   hDev    = -1;
    GLD_tdhViewport hOldVP  = -1;
    GLD_tdstDevice  *pstDev;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /* Get parent device*/
    hDev = M_GLD_ParentDeviceHandle( hVP );
    pstDev = GLD_pGetDevice(hDev);
 
    /* Is viewport handle valid ?*/
    hOldVP = M_GLD_OldViewportHandle( hVP );
    if ( hOldVP < 0 || hOldVP >= C_NB_MAX_VPT_IN_DEV )
        return FALSE;
 
    return ( pstDev->pstViewports[ hOldVP ] != NULL );
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : invalidate viewport
 ----------------------------------------------------------------------------------------
 */
void GLD_vInvalidateViewportHandle( GLD_tdhViewport *p_hVP )
{
    assert( p_hVP );
    *p_hVP = -1;
}
 
/*
 =======================================================================================
    Clear functions 
 =======================================================================================
 */
 
/*
 ----------------------------------------------------------------------------------------
  Description   : This function erases the device (BackBuffer and ZBuffer) whose handle is given
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bClearDevice( GLD_tdhDevice hDev )
{
    return GLD_bClearDeviceWithChoice( hDev, GLD_C_CLEAR_BACKBUF | GLD_C_CLEAR_ZBUF );
}
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : This function erases the device (BackBuffer and eventually ZBuffer) 
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bClearDeviceWithChoice( GLD_tdhDevice hDev, short sChoice )
{
    /* Are we swapping or adjusting ? */
    g_bGLDBlockSwaping = TRUE;
	while (g_bGLDSwapInProgress); /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
 
    assert( !gs_bAdjustInProgress );
    GLI_DRV_vClearDevice(sChoice & GLD_C_CLEAR_ZBUF, sChoice & GLD_C_CLEAR_BACKBUF, 0);
 
    g_bGLDBlockSwaping = FALSE;
    return TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : This function clears (BackBuf & ZBuf) the given viewport in the given device
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bClearViewport( GLD_tdhDevice hNotUsed, GLD_tdhViewport hVP )
{
    return GLD_bClearViewportWithChoice( hNotUsed, hVP, GLD_C_CLEAR_BACKBUF | GLD_C_CLEAR_ZBUF );
}
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : This function clears (BackBuf and/or ZBuf) the given viewport in the given device
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bClearViewportWithChoice( GLD_tdhDevice hNotUsed, GLD_tdhViewport hVP, short sChoice )
{
    GLI_DRV_vClearDevice(sChoice & GLD_C_CLEAR_ZBUF, sChoice & GLD_C_CLEAR_BACKBUF, GLI_gs_lBackGroundColor );
    return TRUE;
}
 
 
/*
 =======================================================================================
    Display mode functions 
 =======================================================================================
 */
 
/*
 ----------------------------------------------------------------------------------------
  Description   : This function allows the user to define the resolution for the swap to full screen mode
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bSetFullScreenModeForDevice( GLD_tdhDevice hDev, DWORD dwFullScreenModeX, DWORD dwFullScreenModeY, DWORD dwFullScreenModeBpp , HWND hFullScreenModeWnd )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdpstDevice pstDev;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /* Get device */
    pstDev = GLD_pGetDevice(hDev);
 
	if (pstDev == NULL)
		return FALSE;
 
    pstDev->stDevAttrib.dwFullScreenModeX   = dwFullScreenModeX;
    pstDev->stDevAttrib.dwFullScreenModeY   = dwFullScreenModeY;
    pstDev->stDevAttrib.dwFullScreenModeBpp = dwFullScreenModeBpp;
    pstDev->stDevAttrib.hFullScreenModeWnd  = hFullScreenModeWnd;
 
    return TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description : This functions creates a device associated with the window whose handle 
                is given in structure.
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bCreateDevice( GLD_tdpstDeviceAttributes pstDevAttrib, GLD_tdhDevice *phDev )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdpstDevice     pstDev;     /* Pointer to device structure being created*/
    GLD_tdhDevice       hDev;       /* Device handle*/
    
    static  BOOL        bFirstTime = TRUE;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
 
    /* There must be a valid handle in hWnd field in this version of CreateDevice */
    assert( pstDevAttrib->hNormalModeWnd != NULL || pstDevAttrib->hFullScreenModeWnd != NULL );    
 
    if ( !pstDevAttrib->hNormalModeWnd )
        pstDevAttrib->hNormalModeWnd = pstDevAttrib->hFullScreenModeWnd;
    if ( !pstDevAttrib->hFullScreenModeWnd )
        pstDevAttrib->hFullScreenModeWnd = pstDevAttrib->hNormalModeWnd;
 
    /* A few initialisations */
    if ( bFirstTime ) 
    {
        if (!GLD_fn_bInitGLD())
            return FALSE;
        bFirstTime = FALSE;
    }
 
    /* Only one device in exclusive mode at a time */
    if ( pstDevAttrib->bFullScreen )
    {
        for ( hDev=0; hDev < C_NB_MAX_DEVICES; hDev++ )
            if ( g_pstGLDDevices[ hDev ] )
                if ( g_pstGLDDevices[ hDev ]->stDevAttrib.bFullScreen ) /* Is the device in full screen mode ?*/
                {
                    pstDevAttrib->bFullScreen = FALSE;  /* one device in exclusive mode has been found...*/
                    break;                              /* swap to windowed mode*/
                }
    }
  
    /* Device structure allocation */
    M_GLDAlloc( pstDev, GLD_tdpstDevice, sizeof( GLD_tdstDevice ), E_uwGLD_CD_NotEnoughMemForDev )
    memset( pstDev, 0, sizeof( GLD_tdstDevice ) );
 
    pstDevAttrib->dwWidth   = pstDevAttrib->dwFullScreenModeX;
    pstDevAttrib->dwHeight  = pstDevAttrib->dwFullScreenModeY;
 
      
    /* Save what has to be saved */
    fn_bGetDevHandle( phDev );
    g_pstGLDDevices[ *phDev ] = pstDev;
    pstDevAttrib->xPixelDimensionX = GLD_M_Div ( GLD_C_xScreenDimInMetersX, GLD_M_LongToValue ( GLD_C_lScreenDimInPixX ) ) ;
    pstDevAttrib->xPixelDimensionY = GLD_M_Div ( GLD_C_xScreenDimInMetersY, GLD_M_LongToValue ( GLD_C_lScreenDimInPixY ) ) ;
    pstDevAttrib->p_cVirtualScreen = NULL;
    pstDevAttrib->lPitch = -1;
      
    /* Save attributes */
    memcpy( &pstDev->stDevAttrib, pstDevAttrib, sizeof( GLD_tdstDeviceAttributes ) );
 
    pstDev->bIsLocked               = FALSE;
    pstDev->dwBackgroundColor       = 0;     /* By default, background is black !*/
      
    return TRUE; /* Device created successfully*/
}  
 
 
/*
 ----------------------------------------------------------------------------------------
  Description : This function is only provided in the Windows version of the library
                This function must be called each time the window associated with the device 
                receive a WM_SIZE message.
                Used only by editors
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bAdjustDeviceToWindow( GLD_tdhDevice hDev )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    RECT                            rcWindow;   /* New Window dimensions*/
    HWND                            hWnd;       /* Handle of window associated with device*/
    GLD_tdhViewport                 hVP;        /* Viewport Handle*/
    GLD_tdpstDevice                 pstDev;     /* Pointer to structure Device*/
    GLD_tdpstViewport               pstView;    /* Viewport*/
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    g_bGLDBlockSwaping = TRUE;
	while (g_bGLDSwapInProgress); /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
 
    /* Get device (it must be in windowed mode )*/
    pstDev = GLD_pGetDevice( hDev );
    assert( !pstDev->stDevAttrib.bFullScreen );
    
    /* Get window */
    hWnd = pstDev->stDevAttrib.bFullScreen ? pstDev->stDevAttrib.hFullScreenModeWnd : pstDev->stDevAttrib.hNormalModeWnd;
    assert( hWnd != NULL );
    gs_bAdjustInProgress = TRUE;
    
    if ( (!pstDev->stDevAttrib.bFullScreen) && (GLI_g_stCaps.ulDriverCaps & GLICAPS_DRV_C_ulReadjustViewport) )
    {
        /* Get new Window dimensions*/
        GetClientRect( hWnd, &rcWindow );
        assert( rcWindow.right > rcWindow.left );
        assert( rcWindow.bottom > rcWindow.top );
        pstDev->stDevAttrib.dwHeight = rcWindow.bottom - rcWindow.top;
        pstDev->stDevAttrib.dwWidth  = rcWindow.right - rcWindow.left;
    }
    else
    {
        /* Update the Device structure*/
        pstDev->stDevAttrib.dwWidth  = pstDev->stDevAttrib.dwFullScreenModeX;
        pstDev->stDevAttrib.dwHeight = pstDev->stDevAttrib.dwFullScreenModeY;
    }
 
    /* Update all the viewports structures*/
#ifndef USE_DIRECTX  //ce code ça marche pas avec DX: il stretch l'afichage avec le changement de la taille de device.  
    for ( hVP=C_NB_MAX_VPT_IN_DEV-1; hVP >= 0; hVP-- )
    {
        pstView = pstDev->pstViewports[ hVP ];
        if ( pstView )
        {
            fn_vUpdateViewportSizesInPixels( pstDev, pstView );
			if ( ((GLI_tdstSpecificAttributesFor3D *) pstView->stViewAttrib.p_vSpecificToXD)->p_stCam != NULL )
				GLI_xAdjustCameraToViewport2( &pstDev->stDevAttrib, &pstView->stViewAttrib, ((GLI_tdstSpecificAttributesFor3D *) pstView->stViewAttrib.p_vSpecificToXD)->p_stCam );
        }
    }
#endif
    /* Adjust is finished */
    gs_bAdjustInProgress = FALSE;
    g_bGLDBlockSwaping = FALSE;
 
    return TRUE; 
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : This function gives informations about a device whose handle is given
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bGetDeviceAttributes( GLD_tdhDevice hDev, GLD_tdpstDeviceAttributes pstDevAttrib )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdpstDevice   pstDev;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    g_bGLDBlockSwaping = TRUE;
	while (g_bGLDSwapInProgress); /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
  
    /* Get device */
    if ( (pstDev = GLD_pGetDevice(hDev)) == NULL)
        return FALSE;
    memcpy( pstDevAttrib, &pstDev->stDevAttrib, sizeof( GLD_tdstDeviceAttributes ) );
  
    g_bGLDBlockSwaping = FALSE;
    return TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : This function creates a viewport in the specified device (handle)
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bCreateViewport( GLD_tdhDevice hDev, GLD_tdpstViewportAttributes pstViewAttrib, GLD_tdhViewport *phVP )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdpstDevice     pstDev;       /* Pointer to device structure */
    GLD_tdpstViewport   pstView;      /* Pointer to viewport structure*/
    GLD_tdhViewport     hOldVP;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  
    /* Get device */
    pstDev = GLD_pGetDevice(hDev);
    
    /* Have we got room to store viewport structure ? */
    if ( !fn_bGetVPHandle( hDev, &hOldVP ) )
    {
        *phVP = -1;
        memset( pstViewAttrib, 0xCC, sizeof( GLD_tdstViewportAttributes ) );
        Erm_M_UpdateLastError( GLD, C_ucErmDefaultChannel, E_uwGLD_CRV_MaxNumberReached, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, _szPersonalMsg_ );
        return FALSE; /* No more room*/
    }   
  
    /* Try to allocate memory for viewport structure */
    M_GLDAlloc( pstView, GLD_tdpstViewport, sizeof( GLD_tdstViewport ), E_uwGLD_CRV_NotEnoughMemForVpt );
    if ( !pstView )
    {
        *phVP = -1;
        memset( pstViewAttrib, 0xCC, sizeof( GLD_tdstViewportAttributes ) );
        return FALSE; /* Out of memory for viewport structure*/
    }
  
    /* Save viewport settings */
    memset( pstView, 0, sizeof( GLD_tdstViewport ) );   
    memcpy( &pstView->stViewAttrib, pstViewAttrib, sizeof( GLD_tdstViewportAttributes ) );
  
    /* Get the sizes in pixels */
    fn_vUpdateViewportSizesInPixels( pstDev, pstView );
    pstView->stViewAttrib.dwInitialHeight  = pstView->stViewAttrib.dwHeight;
    pstView->stViewAttrib.dwInitialWidth   = pstView->stViewAttrib.dwWidth;
    pstView->stViewAttrib.p_vSpecificToXD  = NULL;
    pstView->stViewAttrib.p_cVirtualScreen = NULL;
    pstView->stViewAttrib.lPitch           = -1;
  
    pstView->bIsLocked = FALSE;
  
    /* Copy public datas */
    memcpy( pstViewAttrib, &pstView->stViewAttrib, sizeof( GLD_tdstViewportAttributes ) );
  
    /* Save pointer on viewport */
    g_pstGLDDevices[ hDev ]->pstViewports[ hOldVP ] = pstView;
  
    /* Return new handle*/
    *phVP = M_GLD_NewViewportHandleFromOld( hDev, hOldVP );
    return TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : This function retrieves the attributes of a given viewport in a given device
                CAUTION : The hDev parameter is useless and only kept for compatibility reasons !!!!    
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bGetViewportAttributes( GLD_tdhDevice hNotUsed, GLD_tdhViewport hVP, GLD_tdpstViewportAttributes pstViewAttrib )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdhDevice       hDev    = -1;
    GLD_tdhViewport     hOldVP  = -1;
  
    GLD_tdpstDevice           pstDev;       /* Pointer to device structure*/
    GLD_tdpstViewport         pstView;      /* Pointer to viewport structure*/
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /* Are we swapping or adjusting ? */
     g_bGLDBlockSwaping = TRUE;
	while (g_bGLDSwapInProgress); /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
 
    assert( !gs_bAdjustInProgress );
  
    /* Get device */
    hDev = M_GLD_ParentDeviceHandle( hVP );
    pstDev = GLD_pGetDevice(hDev);
  
    /* Get viewport */
    hOldVP = M_GLD_OldViewportHandle( hVP );
    pstView = GLD_pGetViewport( hDev, hOldVP );
  
    pstView->stViewAttrib.lPitch = -1;
    pstView->stViewAttrib.p_cVirtualScreen = NULL;
  
    /* Copy the information in client structure*/
    memcpy( pstViewAttrib, &pstView->stViewAttrib, sizeof( GLD_tdstViewportAttributes ) );
  
    g_bGLDBlockSwaping = FALSE;
    return TRUE;
}
 
/*
 =======================================================================================
    beginning/end of writing to device.
    Theses functions are there to tell the low level driver that we are going to display
    a scene (or we are finished with it). The driver can then perform some once-per-frame
    stuff, prepare the rendering... Some 3D card need to know when all object are drawn
    and they begin the rendering only at that moment.
 =======================================================================================
 */
/*
 ----------------------------------------------------------------------------------------
  Description   : Indicate that we are going to render the scene
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bBeginWriteToDevice( GLD_tdhDevice hNotUsed )
{
    return GLI_DRV_bBeginScene();
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Indicate that we are going to render the scene
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bEndWriteToDevice( GLD_tdhDevice hNotUsed )
{
    /*
     * We display gli menu if enable
     */
#if !defined(PRESS_DEMO)
    GLI_fnv_ManageMenu();
#endif

    return GLI_DRV_bEndScene();
}
 
/*
 =======================================================================================
    writing request to viewport
 =======================================================================================
 */
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : This function sets the write mode for the given viewport of the given device.
                  The viewport is then locked and access to this one will be denied.
                  The function gives back valid pointers to surface in memory in VPAttributes struct.
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bRequestWriteToViewport( GLD_tdhDevice hNotUsed, GLD_tdhViewport hVP, GLD_tdpstViewportAttributes pstViewAttrib, BOOL *pbCanWrite )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdhDevice       hDev    = -1;
    GLD_tdhViewport     hOldVP  = -1;
    GLD_tdpstDevice     pstDev;     /* Pointer to device structure*/
    GLD_tdpstViewport   pstView;    /* Pointer to viewport structure*/
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /* Are we adjusting or swapping ? */
    assert( !gs_bAdjustInProgress );
    
    g_bGLDBlockSwaping = TRUE;
	while (g_bGLDSwapInProgress); /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
	
    /* Get device */
    hDev = M_GLD_ParentDeviceHandle( hVP );
    pstDev = GLD_pGetDevice( hDev );
 
     /* Get viewport */
    hOldVP = M_GLD_OldViewportHandle( hVP );
    pstView = GLD_pGetViewport( hDev, hOldVP );
  
    /* Is device locked or viewport locked ? */
    *pbCanWrite = 1;
    memcpy( pstViewAttrib, &pstView->stViewAttrib, sizeof( GLD_tdstViewportAttributes ) );
  
    /* Device is locked */
    pstDev->bIsLocked = TRUE;
 
    g_bGLDBlockSwaping = FALSE;
    return TRUE;
} /*GLD_bRequestWriteToViewport*/
 
 
/*
 ----------------------------------------------------------------------------------------
  Description : 
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bWriteToViewportFinished( GLD_tdhDevice hNotUsed, GLD_tdhViewport hVP )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdhDevice       hDev    = -1;
    GLD_tdpstDevice     pstDev;     /* Pointer to device structure*/
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /* Get device */
    hDev = M_GLD_ParentDeviceHandle( hVP );
    pstDev = GLD_pGetDevice( hDev );
    
    /*pstView->bIsLocked = FALSE;*/
    pstDev->bIsLocked = FALSE;
    return TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description : This function sets the write mode for the given viewport of the given device.
                The viewport is then locked and access to this one will be denied.
                The function gives back valid pointers to surface in memory in VPAttributes struct.
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bRequestWriteToViewport2D ( GLD_tdhDevice hNotUsed, GLD_tdhViewport hVP, GLD_tdpstViewportAttributes pstViewAttrib, BOOL *pbCanWrite )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdhDevice       hDev    = -1;
    GLD_tdhViewport     hOldVP  = -1;
    GLD_tdpstDevice     pstDev;     /* Pointer to device structure*/
    GLD_tdpstViewport   pstView;    /* Pointer to viewport structure*/
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
    /* Are we adjusting or swapping ? */
    assert( !gs_bAdjustInProgress );
    
    g_bGLDBlockSwaping = TRUE;
	while (g_bGLDSwapInProgress); /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
 
    /* Get device */
    hDev = M_GLD_ParentDeviceHandle( hVP );
    pstDev = GLD_pGetDevice( hDev );
    
    /* By default, can't write and pointer and lPitch are invalid */
    *pbCanWrite = FALSE;
    memset( pstViewAttrib, 0xCC, sizeof( GLD_tdstViewportAttributes ) );
    
    /* Get viewport */
    hOldVP = M_GLD_OldViewportHandle( hVP );
    pstView = GLD_pGetViewport( hDev, hOldVP );
    
    /* Is device locked or viewport locked ? */
    assert( !pstDev->bIsLocked );
    assert( !pstView->bIsLocked );
    
    /* GetViewportAttributes */
    memcpy( pstViewAttrib, &pstView->stViewAttrib, sizeof( GLD_tdstViewportAttributes ) );
    
    if ( !pstDev->stDevAttrib.bFullScreen ) {
	    g_bGLDBlockSwaping = FALSE;
        return FALSE;
	}
 
    if ( (*pbCanWrite = GLI_DRV_bLockDevice( (void **) &pstView->stViewAttrib.p_cVirtualScreen, &pstView->stViewAttrib.lPitch ) ) == TRUE )
    {
        memcpy( pstViewAttrib, &pstView->stViewAttrib, sizeof( GLD_tdstViewportAttributes ) );
        pstView->bIsLocked = TRUE;
        pstDev->bIsLocked = TRUE;
	    g_bGLDBlockSwaping = FALSE;
        return TRUE;
    }
    
    g_bGLDBlockSwaping = FALSE;
    return FALSE; 
}
 
/*
 ----------------------------------------------------------------------------------------
  Description : 
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bWriteToViewportFinished2D ( GLD_tdhDevice hNotUsed, GLD_tdhViewport hVP )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdhDevice        hDev    = -1;
    GLD_tdhViewport      hOldVP  = -1;
    GLD_tdpstDevice      pstDev;     /* Pointer to device structure*/
    GLD_tdpstViewport    pstView;    /* Pointer to viewport structure*/
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /* Get device */
    hDev = M_GLD_ParentDeviceHandle( hVP );
    pstDev = GLD_pGetDevice( hDev );
 
    /* Get viewport */
    hOldVP = M_GLD_OldViewportHandle( hVP );
    pstView = GLD_pGetViewport( hDev, hOldVP );
 
    GLI_DRV_bUnlockDevice();
 
    pstView->bIsLocked = FALSE;
    pstDev->bIsLocked = FALSE;
    return TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description : 
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bRequestWriteToViewport3D( GLD_tdhDevice hNotUsed, GLD_tdhViewport hVP, GLD_tdpstViewportAttributes pstViewAttrib, BOOL *pbCanWrite )
{
    return GLD_bRequestWriteToViewport( hNotUsed, hVP, pstViewAttrib, pbCanWrite );
}
 
/*
 ----------------------------------------------------------------------------------------
  Description : 
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bWriteToViewportFinished3D( GLD_tdhDevice hNotUsed, GLD_tdhViewport hVP )
{
    return GLD_bWriteToViewportFinished( hNotUsed, hVP );
}
 
/*
 =======================================================================================
    Flip / synchro
 =======================================================================================
 */
#include "DevVp1.c"
 
BOOL GLD_bFlipDeviceWithSynchro(GLD_tdhDevice hDev,enum Synchro eSynchro)
{
	/* long lNbFrameWait; */
 
	int i = 0;
 
	/* lNbFrameWait = GLD_lComputeWaitFrameForSynchro( eSynchro ); */ 
 
	GLD_RenderingCounter ++;
    
	/*bart990126*/
	g_bGLDBlockSwaping = TRUE;
	while (g_bGLDSwapInProgress)
	{
		i++; /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
	}
 
	
  //  GLI_DRV_vFlipDevice( lNbFrameWait );	/* MT990126*/
    GLI_DRV_vFlipDeviceWithSyncro();
 
	/*bart990126*/
    g_bGLDBlockSwaping = FALSE;

	if( gs_wTimerForSmoothSyncro != 0xbeef )
	{
		TMR_fn_wResetTimer(gs_wTimerForSmoothSyncro);
		TMR_fn_wStartTimer(gs_wTimerForSmoothSyncro);
	}

    return TRUE;
}
 
/*
 =======================================================================================
    Other functions
 =======================================================================================
 */
 
unsigned char GLD_fn_bIsAValidResolution(unsigned long _ulWidth,unsigned long _ulHeight)
{
    return(TRUE);
}
 
 
/*
 ----------------------------------------------------------------------------------------
  Description : This function sets a new position and new dimensions for the given viewport 
                of the given device.
                CAUTION : The hDev parameters is useless and only kept for compatibility reasons
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bSetViewportPosition( GLD_tdhDevice hNotUsed, GLD_tdhViewport hVP, GLD_tdpstViewportAttributes pstViewAttrib )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdhDevice   hDev    = -1;
    GLD_tdhViewport hOldVP  = -1;
  
    GLD_tdpstDevice   pstDev;       /* Pointer to device structure*/
    GLD_tdpstViewport pstView;      /* Pointer to viewport structure*/
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /* Are we swapping or adjusting ? */
    g_bGLDBlockSwaping = TRUE;
	while (g_bGLDSwapInProgress); /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
 
    assert( !gs_bAdjustInProgress );
  
    /* Get device */
    hDev = M_GLD_ParentDeviceHandle( hVP );
    pstDev = GLD_pGetDevice( hDev);
  
    /* Get viewport */
    hOldVP = M_GLD_OldViewportHandle( hVP );
    pstView = GLD_pGetViewport( hDev, hOldVP );
  
    /* Get the sizes in pixels  */
    memset( pstView, 0, sizeof( GLD_tdstViewport ) );   
    memcpy( &pstView->stViewAttrib, pstViewAttrib, sizeof( GLD_tdstViewportAttributes ) );
    fn_vUpdateViewportSizesInPixels( pstDev, pstView );
  
    pstView->stViewAttrib.p_cVirtualScreen = NULL;
    pstView->stViewAttrib.lPitch = -1;
  
    /* Copy public datas*/
    memcpy( pstViewAttrib, &pstView->stViewAttrib, sizeof( GLD_tdstViewportAttributes ) );
  
  
    g_bGLDBlockSwaping = FALSE;
    return TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description : This function deletes a given viewport in a given device
                of the given device.
                CAUTION : The hDev parameters is useless and only kept for compatibility reasons
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bDeleteViewport( GLD_tdhDevice hNotUsed, GLD_tdhViewport hVP )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdhDevice   hDev    = -1;
    GLD_tdhViewport hOldVP  = -1;
  
    GLD_tdpstDevice   pstDev;       /* Pointer to device structure*/
    GLD_tdpstViewport pstView;      /* Pointer to viewport structure*/
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  
    /* Are we swapping or adjusting ? */
    
 
	/*assert( !g_bGLDSwapInProgress );*/
    g_bGLDBlockSwaping = TRUE;
	while (g_bGLDSwapInProgress); /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
    
	assert( !gs_bAdjustInProgress );
	/*while( gs_bAdjustInProgress ); // BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
  
    /* Get device */
    hDev = M_GLD_ParentDeviceHandle( hVP );
    pstDev = GLD_pGetDevice( hDev);
  
    /* Get viewport */
    hOldVP = M_GLD_OldViewportHandle( hVP );
    pstView = GLD_pGetViewport( hDev, hOldVP );
  
    /* Is device locked ?*/
    /* Let's smash the current structure*/
    memset( pstView, 0xCC, sizeof( GLD_tdstViewport ) );
  
    /* Free the structure*/
    M_GLDFree( pstView );
  
    /* Zero the pointer in the device*/
    pstDev->pstViewports[ hOldVP ] = NULL;
  
    g_bGLDBlockSwaping = FALSE;
    return TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : This function deletes device whose handle is given
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bDeleteDevice( GLD_tdhDevice hDev )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdpstDevice     pstDev;       /* Pointer to device structure*/
    GLD_tdhViewport     hVP;        /* Handle of viewport   */
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  
    /* Is adjust in progress ?*/
    assert( !gs_bAdjustInProgress );
  
    /* Get device */
    pstDev = GLD_pGetDevice( hDev);
  
    /* Is device locked ?*/
    /* During a swap operation, keep the viewports and the rasters*/
 
    if ( !g_bGLDSwapInProgress )
    {
        /* First : delete all the viewports*/
        for ( hVP=0; hVP < C_NB_MAX_VPT_IN_DEV; hVP++ )
        {
            if ( pstDev->pstViewports[ hVP ] )
            {
                /* Smash the viewport structure*/
                memset( pstDev->pstViewports[ hVP ], 0xCC, sizeof( GLD_tdstViewport ) );
                /* Smash the pointer*/
                pstDev->pstViewports[ hVP ] = NULL;
            }
        }
    }
 
    /* Finally : smash the device structure*/
    memset ( pstDev, 0xCC, sizeof( GLD_tdstDevice ) );
  
    /* Free the device pointer*/
    M_GLDFree( pstDev );
  
    /* Smash the pointer*/
    g_pstGLDDevices[ hDev ] = NULL;
  
    return TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : To know if device can be windowed
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_fn_bCanBeWindowed( void )
{
	return ( ( GLI_g_stCaps.ulDriverCaps & GLICAPS_DRV_C_ulCanBeWindowed ) == 0 ) ? FALSE : TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : This function swaps between Full screen - Exclusive mode and Windowed - Normal mode
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bSwapDeviceMode( GLD_tdhDevice hDev, BOOL _bCanBeWindowed )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdpstDevice             pstDev;       /* Pointer to device structure*/
    GLD_tdpstViewport           pstView;      /* Viewports*/
    GLD_tdstDeviceAttributes    stDevAttrib;    
    /* To save viewports stuff*/
    GLD_tdpstViewport           pstTmpViewports[ C_NB_MAX_VPT_IN_DEV ]; /* Buffer for swapping*/
    /* To save background color*/
    DWORD                       dwBackgroundColor;
    /* Handles*/
    GLD_tdhViewport             hVP;                    /* Viewports*/
    HWND                        hFSMWnd, hNMWnd;
    BOOL                        bReinitDevice;
 
	BOOL bWasInFullScreen;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    while (g_bGLDBlockSwaping); /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
    g_bGLDSwapInProgress = TRUE;
 
    /* Get device */
    pstDev = GLD_pGetDevice( hDev);
	if (pstDev == NULL)	{
	    g_bGLDSwapInProgress = FALSE;
		return FALSE; /* failed !*/
	}
 
	bWasInFullScreen = pstDev->stDevAttrib.bFullScreen;
	pstDev->stDevAttrib.bFullScreen = !pstDev->stDevAttrib.bFullScreen; /*bbart1118*/
 
    /* Window handle must exist*/
    assert( pstDev->stDevAttrib.hNormalModeWnd != NULL && pstDev->stDevAttrib.hFullScreenModeWnd != NULL );
    hFSMWnd = pstDev->stDevAttrib.hFullScreenModeWnd;
    hNMWnd  = pstDev->stDevAttrib.hNormalModeWnd;
 
    if ( !_bCanBeWindowed )
    {
        if (bWasInFullScreen) /*old : if (pstDev->stDevAttrib.bFullScreen)*/
            GLI_DRV_vActivateGli(pstDev->stDevAttrib.hNormalModeWnd, FALSE); /*DEACTIVATE*/
        else
            GLI_DRV_vActivateGli(pstDev->stDevAttrib.hNormalModeWnd, TRUE); /*ACTIVATE*/
        bReinitDevice = FALSE;
    }
    else
    {
        if (bWasInFullScreen) { /*old : if (pstDev->stDevAttrib.bFullScreen) */
            if (!GLI_DRV_bPrepareForGliWindowed(pstDev->stDevAttrib.hNormalModeWnd)) {
	            g_bGLDSwapInProgress = FALSE;
				return FALSE; /* failed !*/
			}
		} else
            GLI_DRV_vPrepareForGliFullScreen(pstDev->stDevAttrib.hFullScreenModeWnd /*NULL*/); /*bart990126 : why was it "NULL" ?*/
        bReinitDevice = TRUE;
    }
 
    /*bbart1118 : pstDev->stDevAttrib.bFullScreen = !pstDev->stDevAttrib.bFullScreen;*/
 
    if (bReinitDevice)
    {
        memcpy( &stDevAttrib, &pstDev->stDevAttrib, sizeof( GLD_tdstDeviceAttributes ) );        
 
        /* Copy viewports of old device in buffer*/
        memcpy( &pstTmpViewports[ 0 ], &pstDev->pstViewports[ 0 ], sizeof( pstTmpViewports ) );
    
        /* Save Background Color*/
        dwBackgroundColor = pstDev->dwBackgroundColor;
 
        /* Delete old device*/
        if ( !GLD_bDeleteDevice( hDev ) )
        {
            g_bGLDSwapInProgress = FALSE;
            Erm_M_UpdateLastError( GLD, C_ucErmDefaultChannel, E_uwGLD_SDM_DeleteDeviceFailed, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, _szPersonalMsg_ );
            Erm_fn_v_PrintErrMsgWithPersonalMsg("GLD - DevVpt", " GLD_bSwapDeviceMode", "GLD_bDeleteDevice failed");  
            return FALSE; /* can't swap*/
        }
  
        /* Create the new device*/
        if ( !GLD_bCreateDevice( &stDevAttrib, &hDev ) )
        {
            g_bGLDSwapInProgress = FALSE;
            Erm_fn_v_PrintErrMsgWithPersonalMsg("GLD - DevVpt", " GLD_bSwapDeviceMode", "GLD_bCreateDevice failed");  
            return FALSE;   /* Couldn't swap*/
        }
        pstDev = GLD_pGetDevice( hDev );
 
        /* Restore viewports in the new device*/
        memcpy( &pstDev->pstViewports[ 0 ], &pstTmpViewports[ 0 ], sizeof( pstTmpViewports ) );
        /* Update all the viewports structures*/
        for ( hVP=C_NB_MAX_VPT_IN_DEV-1; hVP >= 0; hVP-- )
        {
            pstView = pstDev->pstViewports[ hVP ];
            if ( pstView )
                /* New sizes in pixels in my structure*/
                fn_vUpdateViewportSizesInPixels( pstDev, pstView );        
        }
 
        /* Restore background color*/
        pstDev->dwBackgroundColor = dwBackgroundColor;
    }
 
    /* end swap */
    g_bGLDSwapInProgress = FALSE;
    return TRUE;
 
} /*GLD_bSwapDeviceMode*/
 
 
 
 /*
 ----------------------------------------------------------------------------------------
  BART990126 : GLD_bReinitDevice, GLD_bSwapToWindowedMode & GLD_bSwapToFullScreen
 ----------------------------------------------------------------------------------------
 */
 
BOOL GLD_bReinitDevice( GLD_tdhDevice _hCurrentDev, GLD_tdpstDevice _pstCurrentDev)
{
 
    GLD_tdpstViewport           pstViewportsStruct;      /* Viewports*/
    GLD_tdstDeviceAttributes    stCurrentDevAttrib;    
    /* To save viewports stuff*/
    GLD_tdpstViewport           pstTmpViewports[ C_NB_MAX_VPT_IN_DEV ]; /* Buffer for swapping*/
    /* To save background color*/
    DWORD                       dwBackgroundColor;
    /* Handles*/
    GLD_tdhViewport             hVP;                    /* Viewports*/
 
 
 
    memcpy( &stCurrentDevAttrib, &_pstCurrentDev->stDevAttrib, sizeof( GLD_tdstDeviceAttributes ) );        
 
    /* Copy viewports of old device in buffer*/
    memcpy( &pstTmpViewports[ 0 ], &_pstCurrentDev->pstViewports[ 0 ], sizeof( pstTmpViewports ) );
 
    /* Save Background Color*/
    dwBackgroundColor = _pstCurrentDev->dwBackgroundColor;
 
    /* Delete old device*/
    if ( !GLD_bDeleteDevice( _hCurrentDev ) )
    {
        g_bGLDSwapInProgress = FALSE;
        Erm_M_UpdateLastError( GLD, C_ucErmDefaultChannel, E_uwGLD_SDM_DeleteDeviceFailed, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, _szPersonalMsg_ );
        Erm_fn_v_PrintErrMsgWithPersonalMsg("GLD - DevVpt", " GLD_bSwapDeviceMode", "GLD_bDeleteDevice failed");  
        return FALSE; /* can't swap*/
    }
 
    /* Create the new device*/
    if ( !GLD_bCreateDevice( &stCurrentDevAttrib, &_hCurrentDev ) )
    {
        g_bGLDSwapInProgress = FALSE;
        Erm_fn_v_PrintErrMsgWithPersonalMsg("GLD - DevVpt", " GLD_bSwapDeviceMode", "GLD_bCreateDevice failed");  
        return FALSE;   /* Couldn't swap*/
    }
    
	_pstCurrentDev = GLD_pGetDevice( _hCurrentDev);
 
    /* Restore viewports in the new device*/
    memcpy( &_pstCurrentDev->pstViewports[ 0 ], &pstTmpViewports[ 0 ], sizeof( pstTmpViewports ) );
    /* Update all the viewports structures*/
    for ( hVP=C_NB_MAX_VPT_IN_DEV-1; hVP >= 0; hVP-- )
    {
        pstViewportsStruct = _pstCurrentDev->pstViewports[ hVP ];
        if ( pstViewportsStruct )
            /* New sizes in pixels in my structure*/
            fn_vUpdateViewportSizesInPixels( _pstCurrentDev, pstViewportsStruct );        
    }
 
    /* Restore background color*/
    _pstCurrentDev->dwBackgroundColor = dwBackgroundColor;

	GLI_DRV_hChangeMode(FALSE,0,0,0); /*GLI_fn_vReadaptDisplay(); bart990210 => GLI_fn_hRestoreSurfaces*/

	return TRUE;
}
 
 
 
BOOL GLD_bSwapToWindowedMode( GLD_tdhDevice _hCurrentDev, BOOL _bCanBeWindowed )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdpstDevice             pstCurrentDev;       /* Pointer to device structure*/
	BOOL bRet;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    while (g_bGLDBlockSwaping); /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
    g_bGLDSwapInProgress = TRUE;
 
    /* Get device */
    pstCurrentDev = GLD_pGetDevice( _hCurrentDev );
	if (pstCurrentDev == NULL)	{
	    g_bGLDSwapInProgress = FALSE;
		return FALSE; /* failed !*/
	}
 
	assert(pstCurrentDev->stDevAttrib.bFullScreen == TRUE);
	pstCurrentDev->stDevAttrib.bFullScreen = FALSE;
 
    /* Window handle must exist*/
    assert( pstCurrentDev->stDevAttrib.hNormalModeWnd != NULL /*&& pstCurrentDev->stDevAttrib.hFullScreenModeWnd != NULL */);
 
    if ( !_bCanBeWindowed )
    {
        GLI_DRV_vActivateGli(pstCurrentDev->stDevAttrib.hNormalModeWnd, FALSE); /*DEACTIVATE*/
		bRet = TRUE;
    }
    else
    {
		if (!GLI_DRV_bPrepareForGliWindowed(pstCurrentDev->stDevAttrib.hNormalModeWnd)) {
			g_bGLDSwapInProgress = FALSE;
			return FALSE; /* failed !*/
		}
        bRet = GLD_bReinitDevice(_hCurrentDev, pstCurrentDev);
    }
 
    /* end swap */
    g_bGLDSwapInProgress = FALSE;
    return bRet;
 
} /*GLD_bSwapToWindowedMode*/
 
 
 
BOOL GLD_bSwapToFullScreen( GLD_tdhDevice _hCurrentDev, BOOL _bCanBeWindowed )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdpstDevice             pstCurrentDev;       /* Pointer to device structure*/
	BOOL bRet;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    while (g_bGLDBlockSwaping); /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
    g_bGLDSwapInProgress = TRUE;
 
    /* Get device */
    pstCurrentDev = GLD_pGetDevice( _hCurrentDev );
	if (pstCurrentDev == NULL)	{
	    g_bGLDSwapInProgress = FALSE;
		return FALSE; /* failed !*/
	}
 
	assert(pstCurrentDev->stDevAttrib.bFullScreen == FALSE);
	pstCurrentDev->stDevAttrib.bFullScreen = TRUE;
 
    /* Window handle must exist*/
    assert( pstCurrentDev->stDevAttrib.hNormalModeWnd != NULL && pstCurrentDev->stDevAttrib.hFullScreenModeWnd != NULL );
 
    if ( !_bCanBeWindowed )
    {
        GLI_DRV_vActivateGli(pstCurrentDev->stDevAttrib.hNormalModeWnd, TRUE); /*ACTIVATE*/
		bRet = TRUE;
    }
    else
    {
        GLI_DRV_vPrepareForGliFullScreen(pstCurrentDev->stDevAttrib.hFullScreenModeWnd /*NULL*/); /*bart990126 : why was it "NULL" ?*/
        bRet = GLD_bReinitDevice(_hCurrentDev, pstCurrentDev);
    }
 
 
    /* end swap */
    g_bGLDSwapInProgress = FALSE;
    return bRet;
 
} /*GLD_bSwapToFullScreen*/
 
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : change device display mode
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_fn_bChangeDeviceDisplayMode( GLD_tdhDevice hDev )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdpstDevice             pstDev;       /* Pointer to device structure*/
    GLD_tdpstViewport           pstView;      /* Viewports*/
    GLD_tdstDeviceAttributes    stDevAttrib;    
    /* To save viewports stuff*/
    GLD_tdpstViewport           pstTmpViewports[ C_NB_MAX_VPT_IN_DEV ]; /* Buffer for swapping*/
    /* To save window settings*/
    DWORD                       dwStyleBeforeSwap   = 0;
    DWORD                       dwExStyleBeforeSwap = 0;
    RECT                        rcWindowBeforeSwap  = { 0, 0, 0, 0 };
    /* To save background color*/
    DWORD                       dwBackgroundColor;
    /* Handles*/
    GLD_tdhViewport             hVP;                    /* Viewports*/
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /* Get device */
    pstDev = GLD_pGetDevice( hDev);
 
    /* 
     * check if requested mode is the same as previous
     */
    if ( ( !GLI_fn_lIsFullScreenMode() ) && ( !pstDev->stDevAttrib.bFullScreen) )
        return TRUE;
 
    if ( (GLI_fn_lIsFullScreenMode()) && (pstDev->stDevAttrib.bFullScreen) )
    {
        if ( (GLI_fn_lDisplayModeWidth() == (long) pstDev->stDevAttrib.dwFullScreenModeX) && (GLI_fn_lDisplayModeHeight() == (long) pstDev->stDevAttrib.dwFullScreenModeY) )
            return TRUE;
    }
 
    /* Save device data*/
    memcpy( &stDevAttrib, &pstDev->stDevAttrib, sizeof( GLD_tdstDeviceAttributes ) );
    memcpy( pstTmpViewports, pstDev->pstViewports, sizeof( pstTmpViewports ) );
    dwBackgroundColor = pstDev->dwBackgroundColor;
 
    while (g_bGLDBlockSwaping); /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
    g_bGLDSwapInProgress = TRUE;
 
    stDevAttrib.dwFullScreenModeX   = GLI_fn_lDisplayModeWidth();
    stDevAttrib.dwFullScreenModeY   = GLI_fn_lDisplayModeHeight();
  
    /* Delete old device*/
    if ( !GLD_bDeleteDevice( hDev ) )
    {
        g_bGLDSwapInProgress = FALSE;
        Erm_M_UpdateLastError( GLD, C_ucErmDefaultChannel, E_uwGLD_SDM_DeleteDeviceFailed, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, _szPersonalMsg_ );
        Erm_fn_v_PrintErrMsgWithPersonalMsg("GLD - DevVpt", " GLD_fn_bChangeDeviceDisplayMode", "GLD_bDeleteDevice failed");  
        return FALSE; /* can't swap*/
    }
  
    /* Create the new device*/
    if ( !GLD_bCreateDevice( &stDevAttrib, &hDev ) )
    {
        g_bGLDSwapInProgress = FALSE;
        Erm_fn_v_PrintErrMsgWithPersonalMsg("GLD - DevVpt", " GLD_fn_bChangeDeviceDisplayMode", "GLD_bCreateDevice failed");  
        return FALSE;   /* Couldn't swap*/
    }
 
    pstDev = GLD_pGetDevice( hDev );
 
    /* Restore saved parameters*/
    memcpy( pstDev->pstViewports, pstTmpViewports, sizeof( pstTmpViewports ) );
    for ( hVP=C_NB_MAX_VPT_IN_DEV-1; hVP >= 0; hVP-- )
    {
        pstView = pstDev->pstViewports[ hVP ];
        if ( pstView )
            fn_vUpdateViewportSizesInPixels( pstDev, pstView );
    }
    pstDev->dwBackgroundColor = dwBackgroundColor;
 
    /* end swap */
    g_bGLDSwapInProgress = FALSE;
    return TRUE;
}
 
 
/******* BART990111 *************************/
/*
 ----------------------------------------------------------------------------------------
  Description   : reinit device display mode
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_fn_bReinitDeviceDisplayMode( GLD_tdhDevice hDev )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    GLD_tdpstDevice             pstDev;       /* Pointer to device structure*/
    GLD_tdpstViewport           pstView;      /* Viewports*/
    GLD_tdstDeviceAttributes    stDevAttrib;    
    /* To save viewports stuff*/
    GLD_tdpstViewport           pstTmpViewports[ C_NB_MAX_VPT_IN_DEV ]; /* Buffer for swapping*/
    /* To save background color*/
    DWORD                       dwBackgroundColor;
    /* Handles*/
    GLD_tdhViewport             hVP;                    /* Viewports*/
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /* Get device */
    pstDev = GLD_pGetDevice( hDev);
	if (pstDev == NULL)
		return FALSE; /* failed !*/
 
	/*if (!GLI_DRV_bPrepareForGliWindowed(pstDev->stDevAttrib.hNormalModeWnd)) {
		g_bGLDSwapInProgress = FALSE;
		return FALSE; // failed !
	}*/
 
    /* Save device data*/
    memcpy( &stDevAttrib, &pstDev->stDevAttrib, sizeof( GLD_tdstDeviceAttributes ) );
    memcpy( pstTmpViewports, pstDev->pstViewports, sizeof( pstTmpViewports ) );
    dwBackgroundColor = pstDev->dwBackgroundColor;
 
    while (g_bGLDBlockSwaping); /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
    g_bGLDSwapInProgress = TRUE;
 
    /* Delete old device*/
    if ( !GLD_bDeleteDevice( hDev ) )
    {
        g_bGLDSwapInProgress = FALSE;
        Erm_M_UpdateLastError( GLD, C_ucErmDefaultChannel, E_uwGLD_SDM_DeleteDeviceFailed, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, _szPersonalMsg_ );
        Erm_fn_v_PrintErrMsgWithPersonalMsg("GLD - DevVpt", " GLD_fn_bReinitDeviceDisplayMode", "GLD_bDeleteDevice failed");  
        return FALSE; /* can't swap*/
    }
  
    /* Create the new device*/
    if ( !GLD_bCreateDevice( &stDevAttrib, &hDev ) )
    {
        g_bGLDSwapInProgress = FALSE;
        Erm_fn_v_PrintErrMsgWithPersonalMsg("GLD - DevVpt", " GLD_fn_bReinitDeviceDisplayMode", "GLD_bCreateDevice failed");  
        return FALSE;   /* Couldn't swap*/
    }
 
    pstDev = GLD_pGetDevice( hDev );
 
    /* Restore saved parameters*/
    memcpy( pstDev->pstViewports, pstTmpViewports, sizeof( pstTmpViewports ) );
    for ( hVP=C_NB_MAX_VPT_IN_DEV-1; hVP >= 0; hVP-- )
    {
        pstView = pstDev->pstViewports[ hVP ];
        if ( pstView )
            fn_vUpdateViewportSizesInPixels( pstDev, pstView );
    }
    pstDev->dwBackgroundColor = dwBackgroundColor;
 
    /* end swap */
    g_bGLDSwapInProgress = FALSE;
    return TRUE;
}
/********************************************/
 
/*
 ----------------------------------------------------------------------------------------
  Description   : This functions associates a "specific attributes" structure with a viewport
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bGiveSpecificAttributesToViewport( GLD_tdhDevice hNotUsed, GLD_tdhViewport hVP, void *p_vSpecAttrib )
{
    GLD_tdhDevice   hDev    = -1;
    GLD_tdhViewport hOldVP  = -1;
  
    GLD_tdpstDevice   pstDev;       /* Pointer to device structure*/
    GLD_tdpstViewport pstView;      /* Pointer to viewport structure*/
  
    /* Get device */
    hDev = M_GLD_ParentDeviceHandle( hVP );
    pstDev = GLD_pGetDevice( hDev);
 
    /* Get viewport */
    hOldVP = M_GLD_OldViewportHandle( hVP );
    pstView = GLD_pGetViewport( hDev, hOldVP );
  
    pstView->stViewAttrib.p_vSpecificToXD = p_vSpecAttrib;
  
    return TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : This function sets the background color for the specified device
 ----------------------------------------------------------------------------------------
 */
BOOL GLD_bSetBackgroundColorForDevice( GLD_tdhDevice hDev, COLORREF crRGB )
{
	GLI_gs_lBackGroundColor = crRGB;
	return TRUE;
}
 
 
 
BOOL GLD_bReleaseViewportAndDevice(GLD_tdhDevice hDev, GLD_tdhViewport hVP)
{
    GLD_bDeleteViewport( hDev, hVP);
 
    g_bGLDBlockSwaping = TRUE;
	while (g_bGLDSwapInProgress); /* BART : si vous êtes bloqué ici => prévenez moi rapidement ! ! ! */
 
    GLD_bDeleteDevice( hDev);
 
    return (TRUE);
}
 
 
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Set contrast
 ----------------------------------------------------------------------------------------
 */
void GLD_bHardwareSetContrast( float fContrast)
{
};
 
/*
 ----------------------------------------------------------------------------------------
  Description   : set luminosity
 ----------------------------------------------------------------------------------------
 */
void GLD_bHardwareSetLuminosity( float fLuminosity)
{
};
 
 
