From 60159c1b09c73c19f798035a15d4ef3b434f2fa0 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 28 Feb 2008 16:34:32 +0900 Subject: Convert crlf->lf line endings. Windows/DOS users should enable core.autocrlf from now on: git config --global core.autocrlf true --- src/mesa/drivers/d3d/WGL.C | 2524 ++++++++++++++++++++++---------------------- 1 file changed, 1262 insertions(+), 1262 deletions(-) (limited to 'src/mesa/drivers/d3d/WGL.C') diff --git a/src/mesa/drivers/d3d/WGL.C b/src/mesa/drivers/d3d/WGL.C index e3b95e1de7..170d094ed4 100644 --- a/src/mesa/drivers/d3d/WGL.C +++ b/src/mesa/drivers/d3d/WGL.C @@ -1,1262 +1,1262 @@ -/*===========================================================================*/ -/* */ -/* Mesa-3.0 Makefile for DirectX 6 */ -/* */ -/* By Leigh McRae */ -/* */ -/* http://www.altsoftware.com/ */ -/* */ -/* Copyright (c) 1998-1997 alt.software inc. All Rights Reserved */ -/*===========================================================================*/ -#include "D3DMesa.h" -/*===========================================================================*/ -/* Window managment. */ -/*===========================================================================*/ -static BOOL InitOpenGL( HINSTANCE hInst ); -static BOOL TermOpenGL( HINSTANCE hInst ); -static BOOL ResizeContext( GLcontext *ctx ); -static BOOL MakeCurrent( D3DMESACONTEXT *pContext ); -static void DestroyContext( D3DMESACONTEXT *pContext ); -static BOOL UnBindWindow( D3DMESACONTEXT *pContext ); -LONG APIENTRY wglMonitorProc( HWND hwnd, UINT message, UINT wParam, LONG lParam ); -/*===========================================================================*/ -/* Mesa hooks. */ -/*===========================================================================*/ -static void SetupDDPointers( GLcontext *ctx ); -static void SetupSWDDPointers( GLcontext *ctx ); -static void SetupHWDDPointers( GLcontext *ctx ); -static void SetupNULLDDPointers( GLcontext *ctx ); -static const char *RendererString( void ); - -/* State Management hooks. */ -static void SetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ); -static void ClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ); -static GLboolean SetBuffer( GLcontext *ctx, GLenum buffer ); - -/* Window Management hooks. */ -static void GetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height ); -static void SetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ); -static void Flush( GLcontext *ctx ); - -/* Span rendering hooks. */ -void WSpanRGB( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgb[][3], const GLubyte mask[] ); -void WSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] ); -void WSpanRGBAMono( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte mask[] ); -void WPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte rgba[][4], const GLubyte mask[] ); -void WPixelsRGBAMono( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte mask[] ); -void RSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, GLubyte rgba[][4] ); -void RPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4], const GLubyte mask[] ); -GLbitfield ClearBuffers( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height ); - -/* Primitve rendering hooks. */ -GLboolean RenderVertexBuffer( GLcontext *ctx, GLboolean allDone ); -void RenderOneTriangle( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv ); -void RenderOneLine( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ); -GLbitfield ClearBuffersD3D( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height ); - -/* Texture Management hooks. */ -static void TextureBind( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj ); -static void TextureLoad( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image ); -static void TextureSubImage( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint internalFormat, const struct gl_texture_image *image ); -/*===========================================================================*/ -/* Global variables. */ -/*===========================================================================*/ -D3DMESACONTEXT *pD3DCurrent, - *pD3DDefault; /* Thin support context. */ - -struct __extensions__ ext[] = { - - { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" }, - { (PROC)glBlendEquationEXT, "glBlendEquationEXT" }, - { (PROC)glBlendColorEXT, "glBlendColorExt" }, - { (PROC)glVertexPointerEXT, "glVertexPointerEXT" }, - { (PROC)glNormalPointerEXT, "glNormalPointerEXT" }, - { (PROC)glColorPointerEXT, "glColorPointerEXT" }, - { (PROC)glIndexPointerEXT, "glIndexPointerEXT" }, - { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" }, - { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" }, - { (PROC)glGetPointervEXT, "glGetPointervEXT" }, - { (PROC)glArrayElementEXT, "glArrayElementEXT" }, - { (PROC)glDrawArraysEXT, "glDrawArrayEXT" }, - { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" }, - { (PROC)glBindTextureEXT, "glBindTextureEXT" }, - { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" }, - { (PROC)glGenTexturesEXT, "glGenTexturesEXT" }, - { (PROC)glIsTextureEXT, "glIsTextureEXT" }, - { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" }, - { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" }, - { (PROC)glTexImage3DEXT, "glTexImage3DEXT" }, - { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" }, -}; - -int qt_ext = sizeof(ext) / sizeof(ext[0]); -float g_DepthScale, - g_MaxDepth; -/*===========================================================================*/ -/* When a process loads this DLL we will setup the linked list for context */ -/* management and create a default context that will support the API until */ -/* the user creates and binds thier own. This THIN default context is useful*/ -/* to have around. */ -/* When the process terminates we will clean up all resources here. */ -/*===========================================================================*/ -/* RETURN: TRUE, FALSE. */ -/*===========================================================================*/ -BOOL APIENTRY DllMain( HINSTANCE hInst, DWORD reason, LPVOID reserved ) -{ - switch( reason ) - { - case DLL_PROCESS_ATTACH: - return InitOpenGL( hInst ); - - case DLL_PROCESS_DETACH: - return TermOpenGL( hInst ); - } - - return TRUE; -} -/*===========================================================================*/ -/* The first thing we do when this dll is hit is connect to the dll that has*/ -/* handles all the DirectX 6 rendering. I decided to use another dll as DX6 */ -/* is all C++ and Mesa-3.0 is C (thats a good thing). This way I can write */ -/* the DX6 in C++ and Mesa-3.0 in C without having to worry about linkage. */ -/* I feel this is easy and better then using static wrappers as it is likely */ -/* faster and it allows me to just develope the one without compiling the */ -/* other. */ -/* NOTE that at this point we don't have much other than a very thin context*/ -/* that will support the API calls only to the point of not causing the app */ -/* to crash from the API table being empty. */ -/*===========================================================================*/ -/* RETURN: TRUE, FALSE. */ -/*===========================================================================*/ -static BOOL InitOpenGL( HINSTANCE hInst ) -{ - /* Allocate and clear the default context. */ - pD3DDefault = (PD3DMESACONTEXT)ALLOC( sizeof(D3DMESACONTEXT) ); - if ( pD3DDefault == NULL ) - return FALSE; - memset( pD3DDefault, 0, sizeof(D3DMESACONTEXT) ); - - /* Clear the D3D vertex buffer so that values not used will be zero. This */ - /* save me from some redundant work. */ - memset( &D3DTLVertices, 0, sizeof(D3DTLVertices) ); - - /* Update the link. We uses a circular list so that it is easy to */ - /* add and search. This context will also be used for head and tail.*/ - pD3DDefault->next = pD3DDefault; - - /*========================================================================*/ - /* Do all core Mesa stuff. */ - /*========================================================================*/ - pD3DDefault->gl_visual = _mesa_create_visual( TRUE, - FALSE, /* db_flag */ - GL_FALSE, /* stereo */ - 8,8,8,8, /* r, g, b, a bits */ - 0, /* index bits */ - 16, /* depth_bits */ - 8, /* stencil_bits */ - 8,8,8,8, /* accum_bits */ - 1 ); - - if ( pD3DDefault->gl_visual == NULL) - { - FREE( pD3DDefault ); - return FALSE; - } - - /* Allocate a new Mesa context */ - pD3DDefault->gl_ctx = _mesa_create_context( pD3DDefault->gl_visual, NULL, pD3DDefault, GL_TRUE ); - if ( pD3DDefault->gl_ctx == NULL ) - { - _mesa_destroy_visual( pD3DDefault->gl_visual ); - FREE( pD3DDefault ); - return FALSE; - } - - /* Allocate a new Mesa frame buffer */ - pD3DDefault->gl_buffer = _mesa_create_framebuffer( pD3DDefault->gl_visual ); - if ( pD3DDefault->gl_buffer == NULL ) - { - _mesa_destroy_visual( pD3DDefault->gl_visual ); - _mesa_destroy_context( pD3DDefault->gl_ctx ); - FREE( pD3DDefault ); - return FALSE; - } - SetupDDPointers( pD3DDefault->gl_ctx ); - _mesa_make_current( pD3DDefault->gl_ctx, pD3DDefault->gl_buffer ); - - return TRUE; -} -/*===========================================================================*/ -/* This function will create a new D3D context but will not create the D3D */ -/* surfaces or even an instance of D3D (see at GetBufferSize). The only stuff*/ -/* done here is the internal Mesa stuff and some Win32 handles. */ -/*===========================================================================*/ -/* RETURN: casted pointer to the context, NULL. */ -/*===========================================================================*/ -HGLRC APIENTRY wglCreateContext( HDC hdc ) -{ - D3DMESACONTEXT *pNewContext; - DWORD dwCoopFlags = DDSCL_NORMAL; - RECT rectClient; - POINT pt; - - /* ALLOC and clear the new context. */ - pNewContext = (PD3DMESACONTEXT)ALLOC( sizeof(D3DMESACONTEXT) ); - if ( pNewContext == NULL ) - { - SetLastError( 0 ); - return (HGLRC)NULL; - } - memset( pNewContext, 0, sizeof(D3DMESACONTEXT) ); - - /*========================================================================*/ - /* Do all core Mesa stuff. */ - /*========================================================================*/ - - /* TODO: support more then one visual. */ - pNewContext->gl_visual = _mesa_create_visual( TRUE, - TRUE, /* db_flag */ - GL_FALSE, /* stereo */ - 8,8,8,8, /* r, g, b, a bits */ - 0, /* index bits */ - 16, /* depth_bits */ - 8, /* stencil_bits */ - 16,16,16,16,/* accum_bits */ - 1 ); - if ( pNewContext->gl_visual == NULL) - { - FREE( pNewContext ); - SetLastError( 0 ); - return (HGLRC)NULL; - } - - /* Allocate a new Mesa context */ - pNewContext->gl_ctx = _mesa_create_context( pNewContext->gl_visual, NULL, pNewContext, GL_TRUE ); - if ( pNewContext->gl_ctx == NULL ) - { - _mesa_destroy_visual( pNewContext->gl_visual ); - FREE( pNewContext ); - SetLastError( 0 ); - return (HGLRC)NULL; - } - - /* Allocate a new Mesa frame buffer */ - pNewContext->gl_buffer = _mesa_create_framebuffer( pNewContext->gl_visual ); - if ( pNewContext->gl_buffer == NULL ) - { - _mesa_destroy_visual( pNewContext->gl_visual ); - _mesa_destroy_context( pNewContext->gl_ctx ); - FREE( pNewContext ); - SetLastError( 0 ); - return (HGLRC)NULL; - } - - /*========================================================================*/ - /* Do all the driver stuff. */ - /*========================================================================*/ - pNewContext->hdc = hdc; - pNewContext->next = pD3DDefault->next; - pD3DDefault->next = pNewContext; /* Add to circular list. */ - - /* Create the HAL for the new context. */ - pNewContext->pShared = InitHAL( WindowFromDC(hdc) ); - - return (HGLRC)pNewContext; -} -/*===========================================================================*/ -/* This is a wrapper function that is supported by MakeCurrent. */ -/*===========================================================================*/ -/* RETURN: TRUE, FALSE. */ -/*===========================================================================*/ -BOOL APIENTRY wglMakeCurrent( HDC hdc, HGLRC hglrc ) -{ - return MakeCurrent((D3DMESACONTEXT *)hglrc); -} -/*===========================================================================*/ -/* MakeCurrent will unbind whatever context is current (if any) & then bind */ -/* the supplied context. A context that is bound has it's window proc hooked*/ -/* with the wglMonitorProc and the context pointer is saved in pD3DCurrent. */ -/* Once the context is bound we update the Mesa-3.0 hooks (SetDDPointers) and*/ -/* the viewport (Mesa-.30 and DX6). */ -/* */ -/* TODO: this function can't fail. */ -/*===========================================================================*/ -/* RETURN: TRUE */ -/*===========================================================================*/ -static BOOL MakeCurrent( D3DMESACONTEXT *pContext ) -{ - D3DMESACONTEXT *pNext; - - /*====================================================================*/ - /* This is a special case that is a request to have no context bound. */ - /*====================================================================*/ - if ( pContext == NULL ) - { - /* Walk the whole list. We start and end at the Default context. */ - for( pNext = pD3DDefault->next; pNext != pD3DDefault; pNext = pNext->next ) - UnBindWindow( pNext ); - - return TRUE; - } - - /*=================================================*/ - /* Make for a fast redundant use of this function. */ - /*=================================================*/ - if ( pD3DCurrent == pContext ) - return TRUE; - - /*=============================*/ - /* Unbind the current context. */ - /*=============================*/ - UnBindWindow( pD3DCurrent ); - - /*=====================================*/ - /* Let Mesa-3.0 we have a new context. */ - /*=====================================*/ - SetupDDPointers( pContext->gl_ctx ); - _mesa_make_current( pContext->gl_ctx, pContext->gl_buffer ); - - /* We are done so set the internal current context. */ - if ( pContext != pD3DDefault ) - { - ResizeContext( pContext->gl_ctx ); - pContext->hOldProc = (WNDPROC)GetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC ); - SetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC, (LONG)wglMonitorProc ); - } - pD3DCurrent = pContext; - - return TRUE; -} -/*===========================================================================*/ -/* This function will only return the current window size. I have re-done */ -/* this function so that it doesn't check the current size and react to it as*/ -/* I should be able to have all the react code in the WM_SIZE message. The */ -/* old version would check the current window size and create/resize the HAL */ -/* surfaces if they have changed. I needed to delay the creation if the */ -/* surfaces because sometimes I wouldn't have a window size so this is where */ -/* I delayed it. If you are reading this then all went ok! */ -/* The default context will return a zero sized window and I'm not sure if */ -/* this is ok at this point (TODO). */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -static void GetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height ) -{ - D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; - - /* Fall through for the default because that is one of the uses for it. */ - if ( pContext == pD3DDefault ) - { - *width = 0; - *height = 0; - } - else - { - *width = pContext->pShared->dwWidth; - *height = pContext->pShared->dwHeight; - } -} -/*===========================================================================*/ -/* */ -/* */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -static BOOL ResizeContext( GLcontext *ctx ) -{ - D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx, - *pCurrentTemp; - RECT rectClient; - POINT pt; - DWORD dwWidth, - dwHeight; - static BOOL bDDrawLock = FALSE; - - /* Make sure we have some values. */ - if ( (pContext->hdc == NULL ) || - (pContext->pShared->hwnd != WindowFromDC(pContext->hdc)) || - (pContext == pD3DDefault) ) - return FALSE; - - /* Having problems with DDraw sending resize messages before I was done. */ - if( bDDrawLock == TRUE ) - return FALSE; - - // TODO: don't think I need this anymore. - pCurrentTemp = pD3DCurrent; - pD3DCurrent = pD3DDefault; - bDDrawLock = TRUE; - - /* Get the current window dimentions. */ - UpdateScreenPosHAL( pContext->pShared ); - dwWidth = pContext->pShared->rectW.right - pContext->pShared->rectW.left; - dwHeight = pContext->pShared->rectW.bottom - pContext->pShared->rectW.top; - - /* Is the size of the OffScreen Render different? */ - if ( (dwWidth != pContext->pShared->dwWidth) || (dwHeight != pContext->pShared->dwHeight) ) - { - /* Create all the D3D surfaces and device. */ - CreateHAL( pContext->pShared ); - - /* I did this so that software rendering would still work as */ - /* I don't need to scale the z values twice. */ - g_DepthScale = (pContext->pShared->bHardware) ? 1.0 : ((float)0x00FFFFFF); - g_MaxDepth = (pContext->pShared->bHardware) ? 1.0 : ((float)0x00FFFFFF); - gl_DepthRange( pContext->gl_ctx, ctx->Viewport.Near, ctx->Viewport.Far ); - - /* Make sure we have a viewport. */ - gl_Viewport( pContext->gl_ctx, 0, 0, dwWidth, dwHeight ); - - /* Update Mesa as we might have changed from SW <-> HW. */ - SetupDDPointers( pContext->gl_ctx ); - _mesa_make_current( pContext->gl_ctx, pContext->gl_buffer ); - - /* If we are in HW we need to load the current texture if there is one already. */ - // if ( (ctx->Texture.Set[ctx->Texture.CurrentSet].Current != NULL) && - // (pContext->pShared->bHardware == TRUE) ) - // { - // CreateTMgrHAL( pContext->pShared, - // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name, - // 0, - // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Format, - // (RECT *)NULL, - // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Width, - // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Height, - // TM_ACTION_BIND, - // (void *)ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Data ); - // } - } - - // TODO: don't think I need this anymore. - pD3DCurrent = pCurrentTemp; - bDDrawLock = FALSE; - - return TRUE; -} - -/*===========================================================================* -/* This function will Blt the render buffer to the PRIMARY surface. I repeat*/ -/* this code for the other SwapBuffer like functions and the flush (didn't */ -/* want the function calling overhead). Thsi could have been a macro... */ -/* */ -/* TODO: there are some problems with viewport/scissoring. */ -/*===========================================================================*/ -/* RETURN: TRUE, FALSE. */ -/*===========================================================================*/ -BOOL APIENTRY wglSwapBuffers( HDC hdc ) -{ - /* Fall through for the default because that is one of the uses for it. */ - if ( pD3DCurrent == pD3DDefault ) - return FALSE; - - SwapBuffersHAL( pD3DCurrent->pShared ); - - return TRUE; -} -/*===========================================================================*/ -/* Same as wglSwapBuffers. */ -/*===========================================================================*/ -/* RETURN: TRUE, FALSE. */ -/*===========================================================================*/ -BOOL APIENTRY SwapBuffers( HDC hdc ) -{ - /* Fall through for the default because that is one of the uses for it. */ - if ( pD3DCurrent == pD3DDefault ) - return FALSE; - - SwapBuffersHAL( pD3DCurrent->pShared ); - - return TRUE; -} -/*===========================================================================*/ -/* This should be ok as none of the SwapBuffers will cause a redundant Blt */ -/* as none of my Swap functions will call flush. This should also allow */ -/* sinlge buffered applications to work (not really worried though). Some */ -/* applications may flush then swap but then this is there fault IMHO. */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -static void Flush( GLcontext *ctx ) -{ - /* Fall through for the default because that is one of the uses for it. */ - if ( pD3DCurrent == pD3DDefault ) - return; - - SwapBuffersHAL( pD3DCurrent->pShared ); -} -/*===========================================================================*/ -/* For now this function will ignore the supplied PF. If I'm going to allow */ -/* the user to choice the mode and device at startup I'm going to have to do */ -/* something different. */ -/* */ -/* TODO: use the linked list of modes to build a pixel format to be returned */ -/* to the caller. */ -/*===========================================================================*/ -/* RETURN: 1. */ -/*===========================================================================*/ -int APIENTRY wglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd ) -{ - return 1; -} -/*===========================================================================*/ -/* See wglChoosePixelFormat. */ -/*===========================================================================*/ -/* RETURN: 1. */ -/*===========================================================================*/ -int APIENTRY ChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd ) -{ - return wglChoosePixelFormat(hdc,ppfd); -} -/*===========================================================================*/ -/* This function (for now) returns a static PF everytime. This is just to */ -/* allow things to continue. */ -/*===========================================================================*/ -/* RETURN: 1. */ -/*===========================================================================*/ -int APIENTRY wglDescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd ) -{ - static PIXELFORMATDESCRIPTOR pfd = - { - sizeof(PIXELFORMATDESCRIPTOR), /* size */ - 1, /* version */ - PFD_SUPPORT_OPENGL | - PFD_DRAW_TO_WINDOW | - PFD_DOUBLEBUFFER, /* support double-buffering */ - PFD_TYPE_RGBA, /* color type */ - 16, /* prefered color depth */ - 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ - 0, /* no alpha buffer */ - 0, /* alpha bits (ignored) */ - 0, /* no accumulation buffer */ - 0, 0, 0, 0, /* accum bits (ignored) */ - 16, /* depth buffer */ - 0, /* no stencil buffer */ - 0, /* no auxiliary buffers */ - PFD_MAIN_PLANE, /* main layer */ - 0, /* reserved */ - 0, 0, 0, /* no layer, visible, damage masks */ - }; - - /* Return the address of this static PF if one was requested. */ - if ( ppfd != NULL ) - memcpy( ppfd, &pfd, sizeof(PIXELFORMATDESCRIPTOR) ); - - return 1; -} -/*===========================================================================*/ -/* See wglDescribePixelFormat. */ -/*===========================================================================*/ -/* RETURN: 1. */ -/*===========================================================================*/ -int APIENTRY DescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd ) -{ - return wglDescribePixelFormat(hdc,iPixelFormat,nBytes,ppfd); -} -/*===========================================================================*/ -/* This function will always return 1 for now. Just to allow for support. */ -/*===========================================================================*/ -/* RETURN: 1. */ -/*===========================================================================*/ -int APIENTRY wglGetPixelFormat( HDC hdc ) -{ - return 1; -} -/*===========================================================================*/ -/* See wglGetPixelFormat. */ -/*===========================================================================*/ -/* RETURN: 1. */ -/*===========================================================================*/ -int APIENTRY GetPixelFormat( HDC hdc ) -{ - return wglGetPixelFormat(hdc); -} -/*===========================================================================*/ -/* This will aways work for now. */ -/*===========================================================================*/ -/* RETURN: TRUE. */ -/*===========================================================================*/ -BOOL APIENTRY wglSetPixelFormat( HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd ) -{ - return TRUE; -} -/*===========================================================================*/ -/* See wglSetPixelFormat. */ -/*===========================================================================*/ -/* RETURN: TRUE, FALSE. */ -/*===========================================================================*/ -BOOL APIENTRY SetPixelFormat( HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd ) -{ - return wglSetPixelFormat(hdc,iPixelFormat,ppfd); -} -/*===========================================================================*/ -/* This is a wrapper function that is supported by my own internal function.*/ -/* that takes my own D3D Mesa context structure. This so I can reuse the */ -/* function (no need for speed). */ -/*===========================================================================*/ -/* RETURN: TRUE. */ -/*===========================================================================*/ -BOOL APIENTRY wglDeleteContext( HGLRC hglrc ) -{ - DestroyContext( (D3DMESACONTEXT *)hglrc ); - - return TRUE; -} -/*===========================================================================*/ -/* Simple getter function that uses a cast. */ -/*===========================================================================*/ -/* RETURN: casted pointer to the context, NULL. */ -/*===========================================================================*/ -HGLRC APIENTRY wglGetCurrentContext( VOID ) -{ - return (pD3DCurrent) ? (HGLRC)pD3DCurrent : (HGLRC)NULL; -} -/*===========================================================================*/ -/* No support. */ -/*===========================================================================*/ -/* RETURN: FALSE. */ -/*===========================================================================*/ -BOOL APIENTRY wglCopyContext( HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask ) -{ - SetLastError( 0 ); - return FALSE; -} -/*===========================================================================*/ -/* No support. */ -/*===========================================================================*/ -/* RETURN: NULL. */ -/*===========================================================================*/ -HGLRC APIENTRY wglCreateLayerContext( HDC hdc,int iLayerPlane ) -{ - SetLastError( 0 ); - return (HGLRC)NULL; -} -/*===========================================================================*/ -/* Simple getter function. */ -/*===========================================================================*/ -/* RETURN: FALSE. */ -/*===========================================================================*/ -HDC APIENTRY wglGetCurrentDC( VOID ) -{ - return (pD3DCurrent) ? pD3DCurrent->hdc : (HDC)NULL; -} -/*===========================================================================*/ -/* Simply call that searches the supported extensions for a match & returns */ -/* the pointer to the function that lends support. */ -/*===========================================================================*/ -/* RETURN: pointer to API call, NULL. */ -/*===========================================================================*/ -PROC APIENTRY wglGetProcAddress( LPCSTR lpszProc ) -{ - int index; - - for( index = 0; index < qt_ext; index++ ) - if( !strcmp(lpszProc,ext[index].name) ) - return ext[index].proc; - - SetLastError( 0 ); - return NULL; -} -/*===========================================================================*/ -/* No support. */ -/*===========================================================================*/ -/* RETURN: FALSE. */ -/*===========================================================================*/ -BOOL APIENTRY wglShareLists( HGLRC hglrc1, HGLRC hglrc2 ) -{ - SetLastError( 0 ); - return FALSE; -} -/*===========================================================================*/ -/* No support. */ -/*===========================================================================*/ -/* RETURN: FALSE. */ -/*===========================================================================*/ -BOOL APIENTRY wglUseFontBitmaps( HDC fontDevice, DWORD firstChar, DWORD numChars, DWORD listBase ) -{ - SetLastError( 0 ); - return FALSE; -} -/*===========================================================================*/ -/* No support. */ -/*===========================================================================*/ -/* RETURN: FALSE. */ -/*===========================================================================*/ -BOOL APIENTRY wglUseFontBitmapsW( HDC hdc,DWORD first,DWORD count,DWORD listBase ) -{ - SetLastError( 0 ); - return FALSE; -} -/*===========================================================================*/ -/* No support. */ -/*===========================================================================*/ -/* RETURN: FALSE. */ -/*===========================================================================*/ -BOOL APIENTRY wglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf ) -{ - SetLastError( 0 ); - return FALSE; -} -/*===========================================================================*/ -/* No support. */ -/*===========================================================================*/ -/* RETURN: FALSE. */ -/*===========================================================================*/ -BOOL APIENTRY wglUseFontOutlinesW( HDC hdc,DWORD first,DWORD count, DWORD listBase,FLOAT deviation, FLOAT extrusion,int format, LPGLYPHMETRICSFLOAT lpgmf ) -{ - SetLastError( 0 ); - return FALSE ; -} -/*===========================================================================*/ -/* No support. */ -/*===========================================================================*/ -/* RETURN: FALSE. */ -/*===========================================================================*/ -BOOL APIENTRY wglSwapLayerBuffers( HDC hdc, UINT fuPlanes ) -{ - SetLastError( 0 ); - return FALSE; -} -/*===========================================================================*/ -/* This function will be hooked into the window that has been bound. Right */ -/* now it is used to track the window size and position. Also the we clean */ -/* up the currrent context when the window is close/destroyed. */ -/* */ -/* TODO: there might be something wrong here as some games (Heretic II) don't*/ -/* track the window quit right. */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -LONG APIENTRY wglMonitorProc( HWND hwnd, UINT message, UINT wParam, LONG lParam ) -{ - WNDPROC hOldProc; - GLint width, - height; - - switch( message ) - { -// case WM_PAINT: -// break; -// case WM_ACTIVATE: -// break; -// case WM_SHOWWINDOW: -// break; - - case UM_FATALSHUTDOWN: - /* Support the API until we die... */ - MakeCurrent( pD3DDefault ); - break; - - case WM_MOVE: - case WM_DISPLAYCHANGE: - case WM_SIZE: - ResizeContext( pD3DCurrent->gl_ctx ); - break; - - case WM_CLOSE: - case WM_DESTROY: - /* Support the API until we die... */ - hOldProc = pD3DCurrent->hOldProc; - DestroyContext( pD3DCurrent ); - return (hOldProc)(hwnd,message,wParam,lParam); - } - - return (pD3DCurrent->hOldProc)(hwnd,message,wParam,lParam); -} - -/**********************************************************************/ -/***** Miscellaneous device driver funcs *****/ -/**********************************************************************/ - -/*===========================================================================*/ -/* Not reacting to this as I'm only supporting drawing to the back buffer */ -/* right now. */ -/*===========================================================================*/ -/* RETURN: TRUE. */ -/*===========================================================================*/ -static GLboolean SetBuffer( GLcontext *ctx, GLenum buffer ) -{ - if (buffer == GL_BACK_LEFT) - return GL_TRUE; - else - return GL_FALSE; -} -/*===========================================================================*/ -/* This proc will be called by Mesa when the viewport has been set. So if */ -/* we have a context and it isn't the default then we should let D3D know of */ -/* the change. */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -static void SetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) -{ - D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; - RECT rect; - - /* Make sure we can set a viewport. */ - if ( pContext->pShared && (pContext != pD3DDefault) ) - { - // TODO: might be needed. - UpdateScreenPosHAL( pContext->pShared ); - rect.left = x; - rect.right = x + w; - rect.top = y; - rect.bottom = y + h; - - // TODO: shared struct should make this call smaller - SetViewportHAL( pContext->pShared, &rect, 0.0F, 1.0F ); - } -} -/*===========================================================================*/ -/* This function could be better I guess but I decided just to grab the four*/ -/* components and store then seperately. Makes it easier to use IMHO. */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -static void ClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; - - pContext->aClear = a; - pContext->bClear = b; - pContext->gClear = g; - pContext->rClear = r; -} -/*===========================================================================*/ -/* This function could be better I guess but I decided just to grab the four*/ -/* components and store then seperately. Makes it easier to use IMHO. */ -/* (is there an echo in here?) */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -static void SetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; - - pContext->aCurrent = a; - pContext->bCurrent = b; - pContext->gCurrent = g; - pContext->rCurrent = r; -} -/*===========================================================================*/ -/* */ -/* */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -static const char *RendererString( void ) -{ - static char pszRender[64]; - - strcpy( pszRender, "altD3D " ); - - if ( pD3DCurrent->pShared->bHardware ) - strcat( pszRender, "(HW)"); - else - strcat( pszRender, "(SW)"); - - return (const char *)pszRender; -} -/*===========================================================================*/ -/* This function will choose which set of pointers Mesa will use based on */ -/* whether we hard using hardware or software. I have added another set of */ -/* pointers that will do nothing but stop the API from crashing. */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -static void SetupDDPointers( GLcontext *ctx ) -{ - D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; - - // TODO: write a generic NULL support for the span render. - if ( pContext->pShared && pContext->pShared->bHardware ) - { - ctx->Driver.UpdateState = SetupHWDDPointers; - } - else if ( pContext == pD3DDefault ) - { - ctx->Driver.UpdateState = SetupNULLDDPointers; - } - else - { - ctx->Driver.UpdateState = SetupSWDDPointers; - } -} -/*===========================================================================*/ -/* This function will populate all the Mesa driver hooks. This version of */ -/* hooks will do nothing but support the API when we don't have a valid */ -/* context bound. This is mostly for applications that don't behave right */ -/* and also to help exit as clean as possable when we have a FatalError. */ -/*===========================================================================*/ -/* RETURN: pointer to the specific function. */ -/*===========================================================================*/ -static void SetupNULLDDPointers( GLcontext *ctx ) -{ - D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; - - /* Initialize all the pointers in the DD struct. Do this whenever */ - /* a new context is made current or we change buffers via set_buffer! */ - ctx->Driver.UpdateState = SetupNULLDDPointers; - - /* State management hooks. */ - ctx->Driver.Color = NULLSetColor; - ctx->Driver.ClearColor = NULLClearColor; - ctx->Driver.Clear = NULLClearBuffers; - ctx->Driver.SetBuffer = NULLSetBuffer; - - /* Window management hooks. */ - ctx->Driver.GetBufferSize = NULLGetBufferSize; - - /* Primitive rendering hooks. */ - ctx->Driver.TriangleFunc = NULL; - ctx->Driver.RenderVB = NULL; - - /* Pixel/span writing functions: */ - ctx->Driver.WriteRGBASpan = NULLWrSpRGBA; - ctx->Driver.WriteRGBSpan = NULLWrSpRGB; - ctx->Driver.WriteMonoRGBASpan = NULLWrSpRGBAMono; - ctx->Driver.WriteRGBAPixels = NULLWrPiRGBA; - ctx->Driver.WriteMonoRGBAPixels = NULLWrPiRGBAMono; - - /* Pixel/span reading functions: */ - ctx->Driver.ReadRGBASpan = NULLReSpRGBA; - ctx->Driver.ReadRGBAPixels = NULLRePiRGBA; - - /* Misc. hooks. */ - ctx->Driver.RendererString = RendererString; -} -/*===========================================================================*/ -/* This function will populate all the Mesa driver hooks. There are two of */ -/* these functions. One if we have hardware support and one is there is only*/ -/* software. These functions will be called by Mesa and by the wgl.c when we*/ -/* have resized (or created) the buffers. The thing is that if a window gets*/ -/* resized we may loose hardware support or gain it... */ -/*===========================================================================*/ -/* RETURN: pointer to the specific function. */ -/*===========================================================================*/ -static void SetupSWDDPointers( GLcontext *ctx ) -{ - D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; - - /* Initialize all the pointers in the DD struct. Do this whenever */ - /* a new context is made current or we change buffers via set_buffer! */ - ctx->Driver.UpdateState = SetupSWDDPointers; - - /* State management hooks. */ - ctx->Driver.Color = SetColor; - ctx->Driver.ClearColor = ClearColor; - ctx->Driver.Clear = ClearBuffers; - ctx->Driver.SetBuffer = SetBuffer; - - /* Window management hooks. */ - ctx->Driver.GetBufferSize = GetBufferSize; - ctx->Driver.Viewport = SetViewport; - - /* Primitive rendering hooks. */ - ctx->Driver.TriangleFunc = NULL; - ctx->Driver.RenderVB = NULL; - - /* Texture management hooks. */ - - /* Pixel/span writing functions: */ - ctx->Driver.WriteRGBASpan = WSpanRGBA; - ctx->Driver.WriteRGBSpan = WSpanRGB; - ctx->Driver.WriteMonoRGBASpan = WSpanRGBAMono; - ctx->Driver.WriteRGBAPixels = WPixelsRGBA; - ctx->Driver.WriteMonoRGBAPixels = WPixelsRGBAMono; - - /* Pixel/span reading functions: */ - ctx->Driver.ReadRGBASpan = RSpanRGBA; - ctx->Driver.ReadRGBAPixels = RPixelsRGBA; - - /* Misc. hooks. */ - ctx->Driver.Flush = Flush; - ctx->Driver.RendererString = RendererString; -} -/*===========================================================================*/ -/* This function will populate all the Mesa driver hooks. There are two of */ -/* these functions. One if we have hardware support and one is there is only*/ -/* software. These functions will be called by Mesa and by the wgl.c when we*/ -/* have resized (or created) the buffers. The thing is that if a window gets*/ -/* resized we may loose hardware support or gain it... */ -/*===========================================================================*/ -/* RETURN: pointer to the specific function. */ -/*===========================================================================*/ -static void SetupHWDDPointers( GLcontext *ctx ) -{ - D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; - - /* Initialize all the pointers in the DD struct. Do this whenever */ - /* a new context is made current or we change buffers via set_buffer! */ - ctx->Driver.UpdateState = SetupHWDDPointers; - - /* State management hooks. */ - ctx->Driver.Color = SetColor; - ctx->Driver.ClearColor = ClearColor; - ctx->Driver.Clear = ClearBuffersD3D; - ctx->Driver.SetBuffer = SetBuffer; - - /* Window management hooks. */ - ctx->Driver.GetBufferSize = GetBufferSize; - ctx->Driver.Viewport = SetViewport; - - /* Primitive rendering hooks. */ - ctx->Driver.TriangleFunc = RenderOneTriangle; - ctx->Driver.LineFunc = RenderOneLine; - ctx->Driver.RenderVB = RenderVertexBuffer; - - /* Pixel/span writing functions: */ - ctx->Driver.WriteRGBASpan = WSpanRGBA; - ctx->Driver.WriteRGBSpan = WSpanRGB; - ctx->Driver.WriteMonoRGBASpan = WSpanRGBAMono; - ctx->Driver.WriteRGBAPixels = WPixelsRGBA; - ctx->Driver.WriteMonoRGBAPixels = WPixelsRGBAMono; - - /* Pixel/span reading functions: */ - ctx->Driver.ReadRGBASpan = RSpanRGBA; - ctx->Driver.ReadRGBAPixels = RPixelsRGBA; - - /* Texture management hooks. */ - // ctx->Driver.BindTexture = TextureBind; - ctx->Driver.TexImage = TextureLoad; - ctx->Driver.TexSubImage = TextureSubImage; - - /* Misc. hooks. */ - ctx->Driver.Flush = Flush; - ctx->Driver.RendererString = RendererString; -} -/*===========================================================================*/ -/* This function will release all resources used by the DLL. Every context */ -/* will be clobbered by releaseing all driver desources and then freeing the */ -/* context memory. Most all the work is done in DestroyContext. */ -/*===========================================================================*/ -/* RETURN: TRUE. */ -/*===========================================================================*/ -static BOOL TermOpenGL( HINSTANCE hInst ) -{ - D3DMESACONTEXT *pTmp, - *pNext; - - /* Just incase we are still getting paint msg. */ - MakeCurrent( pD3DDefault ); - - /* Walk the list until we get back to the default context. */ - for( pTmp = pD3DDefault->next; pTmp != pD3DDefault; pTmp = pNext ) - { - pNext = pTmp->next; - DestroyContext( pTmp ); - } - DestroyContext( pD3DDefault ); - - return TRUE; -} -/*===========================================================================*/ -/* This function is an internal function that will clean up all the Mesa */ -/* context bound to this D3D context. Also any D3D stuff that this context */ -/* uses will be unloaded. */ -/*===========================================================================*/ -/* RETURN: TRUE, FALSE. */ -/*===========================================================================*/ -static void DestroyContext( D3DMESACONTEXT *pContext ) -{ - D3DMESACONTEXT *pTmp; - - /* Walk the list until we find the context before this one. */ - for( pTmp = pD3DDefault; pTmp && (pTmp->next != pContext); pTmp = pTmp->next ) - if ( pTmp == pTmp->next ) - break; - - /* If we never found it it must already be deleted. */ - if ( pTmp->next != pContext ) - return; - - /* Make sure we are not using this context. */ - if ( pContext == pD3DCurrent ) - MakeCurrent( pD3DDefault ); - - /* Free the Mesa stuff. */ - if ( pContext->gl_visual ) - { - _mesa_destroy_visual( pContext->gl_visual ); - pContext->gl_visual = NULL; - } - if ( pContext->gl_buffer ) - { - _mesa_destroy_framebuffer( pContext->gl_buffer ); - pContext->gl_buffer = NULL; - } - if ( pContext->gl_ctx ) - { - _mesa_destroy_context( pContext->gl_ctx ); - pContext->gl_ctx = NULL; - } - - /* Now dump the D3D. */ - if ( pContext->pShared ) - TermHAL( pContext->pShared ); - - /* Update the previous context's link. */ - pTmp->next = pContext->next; - - /* Gonzo. */ - FREE( pContext ); -} -/*===========================================================================*/ -/* This function will pull the supplied context away from Win32. Basicly it*/ -/* will remove the hook from the window Proc. */ -/* */ -/* TODO: might want to serialize this stuff... */ -/*===========================================================================*/ -/* RETURN: TRUE, FALSE. */ -/*===========================================================================*/ -static BOOL UnBindWindow( D3DMESACONTEXT *pContext ) -{ - if ( pContext == NULL ) - return FALSE; - - if ( pContext == pD3DDefault ) - return TRUE; - - /* Make sure we always have a context bound. */ - if ( pContext == pD3DCurrent ) - pD3DCurrent = pD3DDefault; - - SetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC, (LONG)pContext->hOldProc ); - pContext->hOldProc = NULL; - - return TRUE; -} -/*===========================================================================*/ -/* There are two cases that allow for a faster clear when we know that the */ -/* whole buffer is cleared and that there is no clipping. */ -/*===========================================================================*/ -/* RETURN: the original mask with the bits cleared that represents the buffer* -/* or buffers we just cleared. */ -/*===========================================================================*/ -GLbitfield ClearBuffersD3D( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height ) -{ - D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; - DWORD dwFlags = 0; - - if ( mask & GL_COLOR_BUFFER_BIT ) - { - dwFlags |= D3DCLEAR_TARGET; - mask &= ~GL_COLOR_BUFFER_BIT; - } - if ( mask & GL_DEPTH_BUFFER_BIT ) - { - dwFlags |= D3DCLEAR_ZBUFFER; - mask &= ~GL_DEPTH_BUFFER_BIT; - } - if ( dwFlags == 0 ) - return mask; - - ClearHAL( pContext->pShared, - dwFlags, - all, - x, y, - width, height, - ((pContext->aClear<<24) | (pContext->rClear<<16) | (pContext->gClear<<8) | (pContext->bClear)), - ctx->Depth.Clear, - 0 ); - - return mask; -} - - - -/*===========================================================================*/ -/* TEXTURE MANAGER: ok here is how I did textures. Mesa-3.0 will keep track*/ -/* of all the textures for us. So this means that at anytime we can go to */ -/* the Mesa context and get the current texture. With this in mind this is */ -/* what I did. I really don't care about what textures get or are loaded */ -/* until I actually have to draw a tri that is textured. At this point I */ -/* must have the texture so I demand the texture by destorying all other */ -/* texture surfaces if need be and load the current one. This allows for the*/ -/* best preformance on low memory cards as time is not wasted loading and */ -/* unload textures. */ -/*===========================================================================*/ - - - - - -/*===========================================================================*/ -/* TextureLoad will try and create a D3D surface from the supplied texture */ -/* object if its level 0 (first). The surface will be fully filled with the */ -/* texture. */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -static void TextureLoad( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image ) -{ - D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; - - /* TODO: only doing first LOD. */ - if ( (ctx->DriverCtx == NULL) || (level != 0) ) - return; - - CreateTMgrHAL( pContext->pShared, - tObj->Name, - level, - tObj->Image[level]->Format, - (RECT *)NULL, - tObj->Image[level]->Width, - tObj->Image[level]->Height, - TM_ACTION_LOAD, - (void *)tObj->Image[level]->Data ); -} -/*===========================================================================*/ -/* TextureBind make sure that the texture is on the card. Thats it. */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -static void TextureBind( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj ) -{ - D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; - - /* TODO: only doing first LOD. */ - if ( (tObj->Image[0] == NULL) || (ctx->DriverCtx == NULL) ) - return; - - CreateTMgrHAL( pContext->pShared, - tObj->Name, - 0, - tObj->Image[0]->Format, - (RECT *)NULL, - tObj->Image[0]->Width, - tObj->Image[0]->Height, - TM_ACTION_BIND, - (void *)tObj->Image[0]->Data ); -} -/*===========================================================================*/ -/* TextureSubImage will make sure that the texture being updated is updated */ -/* if its on the card. */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -static void TextureSubImage( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint internalFormat, const struct gl_texture_image *image ) -{ - D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; - RECT rect; - - /* TODO: only doing first LOD. */ - if ( (ctx->DriverCtx == NULL) || (level > 0) ) - return; - - /* Create a dirty rectangle structure. */ - rect.left = xoffset; - rect.right = xoffset + width; - rect.top = yoffset; - rect.bottom = yoffset + height; - - CreateTMgrHAL( pContext->pShared, - tObj->Name, - 0, - tObj->Image[0]->Format, - &rect, - tObj->Image[0]->Width, - tObj->Image[0]->Height, - TM_ACTION_UPDATE, - (void *)tObj->Image[0]->Data ); -} - +/*===========================================================================*/ +/* */ +/* Mesa-3.0 Makefile for DirectX 6 */ +/* */ +/* By Leigh McRae */ +/* */ +/* http://www.altsoftware.com/ */ +/* */ +/* Copyright (c) 1998-1997 alt.software inc. All Rights Reserved */ +/*===========================================================================*/ +#include "D3DMesa.h" +/*===========================================================================*/ +/* Window managment. */ +/*===========================================================================*/ +static BOOL InitOpenGL( HINSTANCE hInst ); +static BOOL TermOpenGL( HINSTANCE hInst ); +static BOOL ResizeContext( GLcontext *ctx ); +static BOOL MakeCurrent( D3DMESACONTEXT *pContext ); +static void DestroyContext( D3DMESACONTEXT *pContext ); +static BOOL UnBindWindow( D3DMESACONTEXT *pContext ); +LONG APIENTRY wglMonitorProc( HWND hwnd, UINT message, UINT wParam, LONG lParam ); +/*===========================================================================*/ +/* Mesa hooks. */ +/*===========================================================================*/ +static void SetupDDPointers( GLcontext *ctx ); +static void SetupSWDDPointers( GLcontext *ctx ); +static void SetupHWDDPointers( GLcontext *ctx ); +static void SetupNULLDDPointers( GLcontext *ctx ); +static const char *RendererString( void ); + +/* State Management hooks. */ +static void SetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ); +static void ClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ); +static GLboolean SetBuffer( GLcontext *ctx, GLenum buffer ); + +/* Window Management hooks. */ +static void GetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height ); +static void SetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ); +static void Flush( GLcontext *ctx ); + +/* Span rendering hooks. */ +void WSpanRGB( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgb[][3], const GLubyte mask[] ); +void WSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] ); +void WSpanRGBAMono( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte mask[] ); +void WPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte rgba[][4], const GLubyte mask[] ); +void WPixelsRGBAMono( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte mask[] ); +void RSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, GLubyte rgba[][4] ); +void RPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4], const GLubyte mask[] ); +GLbitfield ClearBuffers( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height ); + +/* Primitve rendering hooks. */ +GLboolean RenderVertexBuffer( GLcontext *ctx, GLboolean allDone ); +void RenderOneTriangle( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv ); +void RenderOneLine( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ); +GLbitfield ClearBuffersD3D( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height ); + +/* Texture Management hooks. */ +static void TextureBind( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj ); +static void TextureLoad( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image ); +static void TextureSubImage( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint internalFormat, const struct gl_texture_image *image ); +/*===========================================================================*/ +/* Global variables. */ +/*===========================================================================*/ +D3DMESACONTEXT *pD3DCurrent, + *pD3DDefault; /* Thin support context. */ + +struct __extensions__ ext[] = { + + { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" }, + { (PROC)glBlendEquationEXT, "glBlendEquationEXT" }, + { (PROC)glBlendColorEXT, "glBlendColorExt" }, + { (PROC)glVertexPointerEXT, "glVertexPointerEXT" }, + { (PROC)glNormalPointerEXT, "glNormalPointerEXT" }, + { (PROC)glColorPointerEXT, "glColorPointerEXT" }, + { (PROC)glIndexPointerEXT, "glIndexPointerEXT" }, + { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" }, + { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" }, + { (PROC)glGetPointervEXT, "glGetPointervEXT" }, + { (PROC)glArrayElementEXT, "glArrayElementEXT" }, + { (PROC)glDrawArraysEXT, "glDrawArrayEXT" }, + { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" }, + { (PROC)glBindTextureEXT, "glBindTextureEXT" }, + { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" }, + { (PROC)glGenTexturesEXT, "glGenTexturesEXT" }, + { (PROC)glIsTextureEXT, "glIsTextureEXT" }, + { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" }, + { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" }, + { (PROC)glTexImage3DEXT, "glTexImage3DEXT" }, + { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" }, +}; + +int qt_ext = sizeof(ext) / sizeof(ext[0]); +float g_DepthScale, + g_MaxDepth; +/*===========================================================================*/ +/* When a process loads this DLL we will setup the linked list for context */ +/* management and create a default context that will support the API until */ +/* the user creates and binds thier own. This THIN default context is useful*/ +/* to have around. */ +/* When the process terminates we will clean up all resources here. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY DllMain( HINSTANCE hInst, DWORD reason, LPVOID reserved ) +{ + switch( reason ) + { + case DLL_PROCESS_ATTACH: + return InitOpenGL( hInst ); + + case DLL_PROCESS_DETACH: + return TermOpenGL( hInst ); + } + + return TRUE; +} +/*===========================================================================*/ +/* The first thing we do when this dll is hit is connect to the dll that has*/ +/* handles all the DirectX 6 rendering. I decided to use another dll as DX6 */ +/* is all C++ and Mesa-3.0 is C (thats a good thing). This way I can write */ +/* the DX6 in C++ and Mesa-3.0 in C without having to worry about linkage. */ +/* I feel this is easy and better then using static wrappers as it is likely */ +/* faster and it allows me to just develope the one without compiling the */ +/* other. */ +/* NOTE that at this point we don't have much other than a very thin context*/ +/* that will support the API calls only to the point of not causing the app */ +/* to crash from the API table being empty. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +static BOOL InitOpenGL( HINSTANCE hInst ) +{ + /* Allocate and clear the default context. */ + pD3DDefault = (PD3DMESACONTEXT)ALLOC( sizeof(D3DMESACONTEXT) ); + if ( pD3DDefault == NULL ) + return FALSE; + memset( pD3DDefault, 0, sizeof(D3DMESACONTEXT) ); + + /* Clear the D3D vertex buffer so that values not used will be zero. This */ + /* save me from some redundant work. */ + memset( &D3DTLVertices, 0, sizeof(D3DTLVertices) ); + + /* Update the link. We uses a circular list so that it is easy to */ + /* add and search. This context will also be used for head and tail.*/ + pD3DDefault->next = pD3DDefault; + + /*========================================================================*/ + /* Do all core Mesa stuff. */ + /*========================================================================*/ + pD3DDefault->gl_visual = _mesa_create_visual( TRUE, + FALSE, /* db_flag */ + GL_FALSE, /* stereo */ + 8,8,8,8, /* r, g, b, a bits */ + 0, /* index bits */ + 16, /* depth_bits */ + 8, /* stencil_bits */ + 8,8,8,8, /* accum_bits */ + 1 ); + + if ( pD3DDefault->gl_visual == NULL) + { + FREE( pD3DDefault ); + return FALSE; + } + + /* Allocate a new Mesa context */ + pD3DDefault->gl_ctx = _mesa_create_context( pD3DDefault->gl_visual, NULL, pD3DDefault, GL_TRUE ); + if ( pD3DDefault->gl_ctx == NULL ) + { + _mesa_destroy_visual( pD3DDefault->gl_visual ); + FREE( pD3DDefault ); + return FALSE; + } + + /* Allocate a new Mesa frame buffer */ + pD3DDefault->gl_buffer = _mesa_create_framebuffer( pD3DDefault->gl_visual ); + if ( pD3DDefault->gl_buffer == NULL ) + { + _mesa_destroy_visual( pD3DDefault->gl_visual ); + _mesa_destroy_context( pD3DDefault->gl_ctx ); + FREE( pD3DDefault ); + return FALSE; + } + SetupDDPointers( pD3DDefault->gl_ctx ); + _mesa_make_current( pD3DDefault->gl_ctx, pD3DDefault->gl_buffer ); + + return TRUE; +} +/*===========================================================================*/ +/* This function will create a new D3D context but will not create the D3D */ +/* surfaces or even an instance of D3D (see at GetBufferSize). The only stuff*/ +/* done here is the internal Mesa stuff and some Win32 handles. */ +/*===========================================================================*/ +/* RETURN: casted pointer to the context, NULL. */ +/*===========================================================================*/ +HGLRC APIENTRY wglCreateContext( HDC hdc ) +{ + D3DMESACONTEXT *pNewContext; + DWORD dwCoopFlags = DDSCL_NORMAL; + RECT rectClient; + POINT pt; + + /* ALLOC and clear the new context. */ + pNewContext = (PD3DMESACONTEXT)ALLOC( sizeof(D3DMESACONTEXT) ); + if ( pNewContext == NULL ) + { + SetLastError( 0 ); + return (HGLRC)NULL; + } + memset( pNewContext, 0, sizeof(D3DMESACONTEXT) ); + + /*========================================================================*/ + /* Do all core Mesa stuff. */ + /*========================================================================*/ + + /* TODO: support more then one visual. */ + pNewContext->gl_visual = _mesa_create_visual( TRUE, + TRUE, /* db_flag */ + GL_FALSE, /* stereo */ + 8,8,8,8, /* r, g, b, a bits */ + 0, /* index bits */ + 16, /* depth_bits */ + 8, /* stencil_bits */ + 16,16,16,16,/* accum_bits */ + 1 ); + if ( pNewContext->gl_visual == NULL) + { + FREE( pNewContext ); + SetLastError( 0 ); + return (HGLRC)NULL; + } + + /* Allocate a new Mesa context */ + pNewContext->gl_ctx = _mesa_create_context( pNewContext->gl_visual, NULL, pNewContext, GL_TRUE ); + if ( pNewContext->gl_ctx == NULL ) + { + _mesa_destroy_visual( pNewContext->gl_visual ); + FREE( pNewContext ); + SetLastError( 0 ); + return (HGLRC)NULL; + } + + /* Allocate a new Mesa frame buffer */ + pNewContext->gl_buffer = _mesa_create_framebuffer( pNewContext->gl_visual ); + if ( pNewContext->gl_buffer == NULL ) + { + _mesa_destroy_visual( pNewContext->gl_visual ); + _mesa_destroy_context( pNewContext->gl_ctx ); + FREE( pNewContext ); + SetLastError( 0 ); + return (HGLRC)NULL; + } + + /*========================================================================*/ + /* Do all the driver stuff. */ + /*========================================================================*/ + pNewContext->hdc = hdc; + pNewContext->next = pD3DDefault->next; + pD3DDefault->next = pNewContext; /* Add to circular list. */ + + /* Create the HAL for the new context. */ + pNewContext->pShared = InitHAL( WindowFromDC(hdc) ); + + return (HGLRC)pNewContext; +} +/*===========================================================================*/ +/* This is a wrapper function that is supported by MakeCurrent. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglMakeCurrent( HDC hdc, HGLRC hglrc ) +{ + return MakeCurrent((D3DMESACONTEXT *)hglrc); +} +/*===========================================================================*/ +/* MakeCurrent will unbind whatever context is current (if any) & then bind */ +/* the supplied context. A context that is bound has it's window proc hooked*/ +/* with the wglMonitorProc and the context pointer is saved in pD3DCurrent. */ +/* Once the context is bound we update the Mesa-3.0 hooks (SetDDPointers) and*/ +/* the viewport (Mesa-.30 and DX6). */ +/* */ +/* TODO: this function can't fail. */ +/*===========================================================================*/ +/* RETURN: TRUE */ +/*===========================================================================*/ +static BOOL MakeCurrent( D3DMESACONTEXT *pContext ) +{ + D3DMESACONTEXT *pNext; + + /*====================================================================*/ + /* This is a special case that is a request to have no context bound. */ + /*====================================================================*/ + if ( pContext == NULL ) + { + /* Walk the whole list. We start and end at the Default context. */ + for( pNext = pD3DDefault->next; pNext != pD3DDefault; pNext = pNext->next ) + UnBindWindow( pNext ); + + return TRUE; + } + + /*=================================================*/ + /* Make for a fast redundant use of this function. */ + /*=================================================*/ + if ( pD3DCurrent == pContext ) + return TRUE; + + /*=============================*/ + /* Unbind the current context. */ + /*=============================*/ + UnBindWindow( pD3DCurrent ); + + /*=====================================*/ + /* Let Mesa-3.0 we have a new context. */ + /*=====================================*/ + SetupDDPointers( pContext->gl_ctx ); + _mesa_make_current( pContext->gl_ctx, pContext->gl_buffer ); + + /* We are done so set the internal current context. */ + if ( pContext != pD3DDefault ) + { + ResizeContext( pContext->gl_ctx ); + pContext->hOldProc = (WNDPROC)GetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC ); + SetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC, (LONG)wglMonitorProc ); + } + pD3DCurrent = pContext; + + return TRUE; +} +/*===========================================================================*/ +/* This function will only return the current window size. I have re-done */ +/* this function so that it doesn't check the current size and react to it as*/ +/* I should be able to have all the react code in the WM_SIZE message. The */ +/* old version would check the current window size and create/resize the HAL */ +/* surfaces if they have changed. I needed to delay the creation if the */ +/* surfaces because sometimes I wouldn't have a window size so this is where */ +/* I delayed it. If you are reading this then all went ok! */ +/* The default context will return a zero sized window and I'm not sure if */ +/* this is ok at this point (TODO). */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void GetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + /* Fall through for the default because that is one of the uses for it. */ + if ( pContext == pD3DDefault ) + { + *width = 0; + *height = 0; + } + else + { + *width = pContext->pShared->dwWidth; + *height = pContext->pShared->dwHeight; + } +} +/*===========================================================================*/ +/* */ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static BOOL ResizeContext( GLcontext *ctx ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx, + *pCurrentTemp; + RECT rectClient; + POINT pt; + DWORD dwWidth, + dwHeight; + static BOOL bDDrawLock = FALSE; + + /* Make sure we have some values. */ + if ( (pContext->hdc == NULL ) || + (pContext->pShared->hwnd != WindowFromDC(pContext->hdc)) || + (pContext == pD3DDefault) ) + return FALSE; + + /* Having problems with DDraw sending resize messages before I was done. */ + if( bDDrawLock == TRUE ) + return FALSE; + + // TODO: don't think I need this anymore. + pCurrentTemp = pD3DCurrent; + pD3DCurrent = pD3DDefault; + bDDrawLock = TRUE; + + /* Get the current window dimentions. */ + UpdateScreenPosHAL( pContext->pShared ); + dwWidth = pContext->pShared->rectW.right - pContext->pShared->rectW.left; + dwHeight = pContext->pShared->rectW.bottom - pContext->pShared->rectW.top; + + /* Is the size of the OffScreen Render different? */ + if ( (dwWidth != pContext->pShared->dwWidth) || (dwHeight != pContext->pShared->dwHeight) ) + { + /* Create all the D3D surfaces and device. */ + CreateHAL( pContext->pShared ); + + /* I did this so that software rendering would still work as */ + /* I don't need to scale the z values twice. */ + g_DepthScale = (pContext->pShared->bHardware) ? 1.0 : ((float)0x00FFFFFF); + g_MaxDepth = (pContext->pShared->bHardware) ? 1.0 : ((float)0x00FFFFFF); + gl_DepthRange( pContext->gl_ctx, ctx->Viewport.Near, ctx->Viewport.Far ); + + /* Make sure we have a viewport. */ + gl_Viewport( pContext->gl_ctx, 0, 0, dwWidth, dwHeight ); + + /* Update Mesa as we might have changed from SW <-> HW. */ + SetupDDPointers( pContext->gl_ctx ); + _mesa_make_current( pContext->gl_ctx, pContext->gl_buffer ); + + /* If we are in HW we need to load the current texture if there is one already. */ + // if ( (ctx->Texture.Set[ctx->Texture.CurrentSet].Current != NULL) && + // (pContext->pShared->bHardware == TRUE) ) + // { + // CreateTMgrHAL( pContext->pShared, + // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name, + // 0, + // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Format, + // (RECT *)NULL, + // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Width, + // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Height, + // TM_ACTION_BIND, + // (void *)ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Data ); + // } + } + + // TODO: don't think I need this anymore. + pD3DCurrent = pCurrentTemp; + bDDrawLock = FALSE; + + return TRUE; +} + +/*===========================================================================* +/* This function will Blt the render buffer to the PRIMARY surface. I repeat*/ +/* this code for the other SwapBuffer like functions and the flush (didn't */ +/* want the function calling overhead). Thsi could have been a macro... */ +/* */ +/* TODO: there are some problems with viewport/scissoring. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglSwapBuffers( HDC hdc ) +{ + /* Fall through for the default because that is one of the uses for it. */ + if ( pD3DCurrent == pD3DDefault ) + return FALSE; + + SwapBuffersHAL( pD3DCurrent->pShared ); + + return TRUE; +} +/*===========================================================================*/ +/* Same as wglSwapBuffers. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY SwapBuffers( HDC hdc ) +{ + /* Fall through for the default because that is one of the uses for it. */ + if ( pD3DCurrent == pD3DDefault ) + return FALSE; + + SwapBuffersHAL( pD3DCurrent->pShared ); + + return TRUE; +} +/*===========================================================================*/ +/* This should be ok as none of the SwapBuffers will cause a redundant Blt */ +/* as none of my Swap functions will call flush. This should also allow */ +/* sinlge buffered applications to work (not really worried though). Some */ +/* applications may flush then swap but then this is there fault IMHO. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void Flush( GLcontext *ctx ) +{ + /* Fall through for the default because that is one of the uses for it. */ + if ( pD3DCurrent == pD3DDefault ) + return; + + SwapBuffersHAL( pD3DCurrent->pShared ); +} +/*===========================================================================*/ +/* For now this function will ignore the supplied PF. If I'm going to allow */ +/* the user to choice the mode and device at startup I'm going to have to do */ +/* something different. */ +/* */ +/* TODO: use the linked list of modes to build a pixel format to be returned */ +/* to the caller. */ +/*===========================================================================*/ +/* RETURN: 1. */ +/*===========================================================================*/ +int APIENTRY wglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd ) +{ + return 1; +} +/*===========================================================================*/ +/* See wglChoosePixelFormat. */ +/*===========================================================================*/ +/* RETURN: 1. */ +/*===========================================================================*/ +int APIENTRY ChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd ) +{ + return wglChoosePixelFormat(hdc,ppfd); +} +/*===========================================================================*/ +/* This function (for now) returns a static PF everytime. This is just to */ +/* allow things to continue. */ +/*===========================================================================*/ +/* RETURN: 1. */ +/*===========================================================================*/ +int APIENTRY wglDescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd ) +{ + static PIXELFORMATDESCRIPTOR pfd = + { + sizeof(PIXELFORMATDESCRIPTOR), /* size */ + 1, /* version */ + PFD_SUPPORT_OPENGL | + PFD_DRAW_TO_WINDOW | + PFD_DOUBLEBUFFER, /* support double-buffering */ + PFD_TYPE_RGBA, /* color type */ + 16, /* prefered color depth */ + 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ + 0, /* no alpha buffer */ + 0, /* alpha bits (ignored) */ + 0, /* no accumulation buffer */ + 0, 0, 0, 0, /* accum bits (ignored) */ + 16, /* depth buffer */ + 0, /* no stencil buffer */ + 0, /* no auxiliary buffers */ + PFD_MAIN_PLANE, /* main layer */ + 0, /* reserved */ + 0, 0, 0, /* no layer, visible, damage masks */ + }; + + /* Return the address of this static PF if one was requested. */ + if ( ppfd != NULL ) + memcpy( ppfd, &pfd, sizeof(PIXELFORMATDESCRIPTOR) ); + + return 1; +} +/*===========================================================================*/ +/* See wglDescribePixelFormat. */ +/*===========================================================================*/ +/* RETURN: 1. */ +/*===========================================================================*/ +int APIENTRY DescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd ) +{ + return wglDescribePixelFormat(hdc,iPixelFormat,nBytes,ppfd); +} +/*===========================================================================*/ +/* This function will always return 1 for now. Just to allow for support. */ +/*===========================================================================*/ +/* RETURN: 1. */ +/*===========================================================================*/ +int APIENTRY wglGetPixelFormat( HDC hdc ) +{ + return 1; +} +/*===========================================================================*/ +/* See wglGetPixelFormat. */ +/*===========================================================================*/ +/* RETURN: 1. */ +/*===========================================================================*/ +int APIENTRY GetPixelFormat( HDC hdc ) +{ + return wglGetPixelFormat(hdc); +} +/*===========================================================================*/ +/* This will aways work for now. */ +/*===========================================================================*/ +/* RETURN: TRUE. */ +/*===========================================================================*/ +BOOL APIENTRY wglSetPixelFormat( HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd ) +{ + return TRUE; +} +/*===========================================================================*/ +/* See wglSetPixelFormat. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY SetPixelFormat( HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd ) +{ + return wglSetPixelFormat(hdc,iPixelFormat,ppfd); +} +/*===========================================================================*/ +/* This is a wrapper function that is supported by my own internal function.*/ +/* that takes my own D3D Mesa context structure. This so I can reuse the */ +/* function (no need for speed). */ +/*===========================================================================*/ +/* RETURN: TRUE. */ +/*===========================================================================*/ +BOOL APIENTRY wglDeleteContext( HGLRC hglrc ) +{ + DestroyContext( (D3DMESACONTEXT *)hglrc ); + + return TRUE; +} +/*===========================================================================*/ +/* Simple getter function that uses a cast. */ +/*===========================================================================*/ +/* RETURN: casted pointer to the context, NULL. */ +/*===========================================================================*/ +HGLRC APIENTRY wglGetCurrentContext( VOID ) +{ + return (pD3DCurrent) ? (HGLRC)pD3DCurrent : (HGLRC)NULL; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglCopyContext( HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask ) +{ + SetLastError( 0 ); + return FALSE; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: NULL. */ +/*===========================================================================*/ +HGLRC APIENTRY wglCreateLayerContext( HDC hdc,int iLayerPlane ) +{ + SetLastError( 0 ); + return (HGLRC)NULL; +} +/*===========================================================================*/ +/* Simple getter function. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +HDC APIENTRY wglGetCurrentDC( VOID ) +{ + return (pD3DCurrent) ? pD3DCurrent->hdc : (HDC)NULL; +} +/*===========================================================================*/ +/* Simply call that searches the supported extensions for a match & returns */ +/* the pointer to the function that lends support. */ +/*===========================================================================*/ +/* RETURN: pointer to API call, NULL. */ +/*===========================================================================*/ +PROC APIENTRY wglGetProcAddress( LPCSTR lpszProc ) +{ + int index; + + for( index = 0; index < qt_ext; index++ ) + if( !strcmp(lpszProc,ext[index].name) ) + return ext[index].proc; + + SetLastError( 0 ); + return NULL; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglShareLists( HGLRC hglrc1, HGLRC hglrc2 ) +{ + SetLastError( 0 ); + return FALSE; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglUseFontBitmaps( HDC fontDevice, DWORD firstChar, DWORD numChars, DWORD listBase ) +{ + SetLastError( 0 ); + return FALSE; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglUseFontBitmapsW( HDC hdc,DWORD first,DWORD count,DWORD listBase ) +{ + SetLastError( 0 ); + return FALSE; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf ) +{ + SetLastError( 0 ); + return FALSE; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglUseFontOutlinesW( HDC hdc,DWORD first,DWORD count, DWORD listBase,FLOAT deviation, FLOAT extrusion,int format, LPGLYPHMETRICSFLOAT lpgmf ) +{ + SetLastError( 0 ); + return FALSE ; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglSwapLayerBuffers( HDC hdc, UINT fuPlanes ) +{ + SetLastError( 0 ); + return FALSE; +} +/*===========================================================================*/ +/* This function will be hooked into the window that has been bound. Right */ +/* now it is used to track the window size and position. Also the we clean */ +/* up the currrent context when the window is close/destroyed. */ +/* */ +/* TODO: there might be something wrong here as some games (Heretic II) don't*/ +/* track the window quit right. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +LONG APIENTRY wglMonitorProc( HWND hwnd, UINT message, UINT wParam, LONG lParam ) +{ + WNDPROC hOldProc; + GLint width, + height; + + switch( message ) + { +// case WM_PAINT: +// break; +// case WM_ACTIVATE: +// break; +// case WM_SHOWWINDOW: +// break; + + case UM_FATALSHUTDOWN: + /* Support the API until we die... */ + MakeCurrent( pD3DDefault ); + break; + + case WM_MOVE: + case WM_DISPLAYCHANGE: + case WM_SIZE: + ResizeContext( pD3DCurrent->gl_ctx ); + break; + + case WM_CLOSE: + case WM_DESTROY: + /* Support the API until we die... */ + hOldProc = pD3DCurrent->hOldProc; + DestroyContext( pD3DCurrent ); + return (hOldProc)(hwnd,message,wParam,lParam); + } + + return (pD3DCurrent->hOldProc)(hwnd,message,wParam,lParam); +} + +/**********************************************************************/ +/***** Miscellaneous device driver funcs *****/ +/**********************************************************************/ + +/*===========================================================================*/ +/* Not reacting to this as I'm only supporting drawing to the back buffer */ +/* right now. */ +/*===========================================================================*/ +/* RETURN: TRUE. */ +/*===========================================================================*/ +static GLboolean SetBuffer( GLcontext *ctx, GLenum buffer ) +{ + if (buffer == GL_BACK_LEFT) + return GL_TRUE; + else + return GL_FALSE; +} +/*===========================================================================*/ +/* This proc will be called by Mesa when the viewport has been set. So if */ +/* we have a context and it isn't the default then we should let D3D know of */ +/* the change. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void SetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + RECT rect; + + /* Make sure we can set a viewport. */ + if ( pContext->pShared && (pContext != pD3DDefault) ) + { + // TODO: might be needed. + UpdateScreenPosHAL( pContext->pShared ); + rect.left = x; + rect.right = x + w; + rect.top = y; + rect.bottom = y + h; + + // TODO: shared struct should make this call smaller + SetViewportHAL( pContext->pShared, &rect, 0.0F, 1.0F ); + } +} +/*===========================================================================*/ +/* This function could be better I guess but I decided just to grab the four*/ +/* components and store then seperately. Makes it easier to use IMHO. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void ClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + pContext->aClear = a; + pContext->bClear = b; + pContext->gClear = g; + pContext->rClear = r; +} +/*===========================================================================*/ +/* This function could be better I guess but I decided just to grab the four*/ +/* components and store then seperately. Makes it easier to use IMHO. */ +/* (is there an echo in here?) */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void SetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + pContext->aCurrent = a; + pContext->bCurrent = b; + pContext->gCurrent = g; + pContext->rCurrent = r; +} +/*===========================================================================*/ +/* */ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static const char *RendererString( void ) +{ + static char pszRender[64]; + + strcpy( pszRender, "altD3D " ); + + if ( pD3DCurrent->pShared->bHardware ) + strcat( pszRender, "(HW)"); + else + strcat( pszRender, "(SW)"); + + return (const char *)pszRender; +} +/*===========================================================================*/ +/* This function will choose which set of pointers Mesa will use based on */ +/* whether we hard using hardware or software. I have added another set of */ +/* pointers that will do nothing but stop the API from crashing. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void SetupDDPointers( GLcontext *ctx ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + // TODO: write a generic NULL support for the span render. + if ( pContext->pShared && pContext->pShared->bHardware ) + { + ctx->Driver.UpdateState = SetupHWDDPointers; + } + else if ( pContext == pD3DDefault ) + { + ctx->Driver.UpdateState = SetupNULLDDPointers; + } + else + { + ctx->Driver.UpdateState = SetupSWDDPointers; + } +} +/*===========================================================================*/ +/* This function will populate all the Mesa driver hooks. This version of */ +/* hooks will do nothing but support the API when we don't have a valid */ +/* context bound. This is mostly for applications that don't behave right */ +/* and also to help exit as clean as possable when we have a FatalError. */ +/*===========================================================================*/ +/* RETURN: pointer to the specific function. */ +/*===========================================================================*/ +static void SetupNULLDDPointers( GLcontext *ctx ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + /* Initialize all the pointers in the DD struct. Do this whenever */ + /* a new context is made current or we change buffers via set_buffer! */ + ctx->Driver.UpdateState = SetupNULLDDPointers; + + /* State management hooks. */ + ctx->Driver.Color = NULLSetColor; + ctx->Driver.ClearColor = NULLClearColor; + ctx->Driver.Clear = NULLClearBuffers; + ctx->Driver.SetBuffer = NULLSetBuffer; + + /* Window management hooks. */ + ctx->Driver.GetBufferSize = NULLGetBufferSize; + + /* Primitive rendering hooks. */ + ctx->Driver.TriangleFunc = NULL; + ctx->Driver.RenderVB = NULL; + + /* Pixel/span writing functions: */ + ctx->Driver.WriteRGBASpan = NULLWrSpRGBA; + ctx->Driver.WriteRGBSpan = NULLWrSpRGB; + ctx->Driver.WriteMonoRGBASpan = NULLWrSpRGBAMono; + ctx->Driver.WriteRGBAPixels = NULLWrPiRGBA; + ctx->Driver.WriteMonoRGBAPixels = NULLWrPiRGBAMono; + + /* Pixel/span reading functions: */ + ctx->Driver.ReadRGBASpan = NULLReSpRGBA; + ctx->Driver.ReadRGBAPixels = NULLRePiRGBA; + + /* Misc. hooks. */ + ctx->Driver.RendererString = RendererString; +} +/*===========================================================================*/ +/* This function will populate all the Mesa driver hooks. There are two of */ +/* these functions. One if we have hardware support and one is there is only*/ +/* software. These functions will be called by Mesa and by the wgl.c when we*/ +/* have resized (or created) the buffers. The thing is that if a window gets*/ +/* resized we may loose hardware support or gain it... */ +/*===========================================================================*/ +/* RETURN: pointer to the specific function. */ +/*===========================================================================*/ +static void SetupSWDDPointers( GLcontext *ctx ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + /* Initialize all the pointers in the DD struct. Do this whenever */ + /* a new context is made current or we change buffers via set_buffer! */ + ctx->Driver.UpdateState = SetupSWDDPointers; + + /* State management hooks. */ + ctx->Driver.Color = SetColor; + ctx->Driver.ClearColor = ClearColor; + ctx->Driver.Clear = ClearBuffers; + ctx->Driver.SetBuffer = SetBuffer; + + /* Window management hooks. */ + ctx->Driver.GetBufferSize = GetBufferSize; + ctx->Driver.Viewport = SetViewport; + + /* Primitive rendering hooks. */ + ctx->Driver.TriangleFunc = NULL; + ctx->Driver.RenderVB = NULL; + + /* Texture management hooks. */ + + /* Pixel/span writing functions: */ + ctx->Driver.WriteRGBASpan = WSpanRGBA; + ctx->Driver.WriteRGBSpan = WSpanRGB; + ctx->Driver.WriteMonoRGBASpan = WSpanRGBAMono; + ctx->Driver.WriteRGBAPixels = WPixelsRGBA; + ctx->Driver.WriteMonoRGBAPixels = WPixelsRGBAMono; + + /* Pixel/span reading functions: */ + ctx->Driver.ReadRGBASpan = RSpanRGBA; + ctx->Driver.ReadRGBAPixels = RPixelsRGBA; + + /* Misc. hooks. */ + ctx->Driver.Flush = Flush; + ctx->Driver.RendererString = RendererString; +} +/*===========================================================================*/ +/* This function will populate all the Mesa driver hooks. There are two of */ +/* these functions. One if we have hardware support and one is there is only*/ +/* software. These functions will be called by Mesa and by the wgl.c when we*/ +/* have resized (or created) the buffers. The thing is that if a window gets*/ +/* resized we may loose hardware support or gain it... */ +/*===========================================================================*/ +/* RETURN: pointer to the specific function. */ +/*===========================================================================*/ +static void SetupHWDDPointers( GLcontext *ctx ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + /* Initialize all the pointers in the DD struct. Do this whenever */ + /* a new context is made current or we change buffers via set_buffer! */ + ctx->Driver.UpdateState = SetupHWDDPointers; + + /* State management hooks. */ + ctx->Driver.Color = SetColor; + ctx->Driver.ClearColor = ClearColor; + ctx->Driver.Clear = ClearBuffersD3D; + ctx->Driver.SetBuffer = SetBuffer; + + /* Window management hooks. */ + ctx->Driver.GetBufferSize = GetBufferSize; + ctx->Driver.Viewport = SetViewport; + + /* Primitive rendering hooks. */ + ctx->Driver.TriangleFunc = RenderOneTriangle; + ctx->Driver.LineFunc = RenderOneLine; + ctx->Driver.RenderVB = RenderVertexBuffer; + + /* Pixel/span writing functions: */ + ctx->Driver.WriteRGBASpan = WSpanRGBA; + ctx->Driver.WriteRGBSpan = WSpanRGB; + ctx->Driver.WriteMonoRGBASpan = WSpanRGBAMono; + ctx->Driver.WriteRGBAPixels = WPixelsRGBA; + ctx->Driver.WriteMonoRGBAPixels = WPixelsRGBAMono; + + /* Pixel/span reading functions: */ + ctx->Driver.ReadRGBASpan = RSpanRGBA; + ctx->Driver.ReadRGBAPixels = RPixelsRGBA; + + /* Texture management hooks. */ + // ctx->Driver.BindTexture = TextureBind; + ctx->Driver.TexImage = TextureLoad; + ctx->Driver.TexSubImage = TextureSubImage; + + /* Misc. hooks. */ + ctx->Driver.Flush = Flush; + ctx->Driver.RendererString = RendererString; +} +/*===========================================================================*/ +/* This function will release all resources used by the DLL. Every context */ +/* will be clobbered by releaseing all driver desources and then freeing the */ +/* context memory. Most all the work is done in DestroyContext. */ +/*===========================================================================*/ +/* RETURN: TRUE. */ +/*===========================================================================*/ +static BOOL TermOpenGL( HINSTANCE hInst ) +{ + D3DMESACONTEXT *pTmp, + *pNext; + + /* Just incase we are still getting paint msg. */ + MakeCurrent( pD3DDefault ); + + /* Walk the list until we get back to the default context. */ + for( pTmp = pD3DDefault->next; pTmp != pD3DDefault; pTmp = pNext ) + { + pNext = pTmp->next; + DestroyContext( pTmp ); + } + DestroyContext( pD3DDefault ); + + return TRUE; +} +/*===========================================================================*/ +/* This function is an internal function that will clean up all the Mesa */ +/* context bound to this D3D context. Also any D3D stuff that this context */ +/* uses will be unloaded. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +static void DestroyContext( D3DMESACONTEXT *pContext ) +{ + D3DMESACONTEXT *pTmp; + + /* Walk the list until we find the context before this one. */ + for( pTmp = pD3DDefault; pTmp && (pTmp->next != pContext); pTmp = pTmp->next ) + if ( pTmp == pTmp->next ) + break; + + /* If we never found it it must already be deleted. */ + if ( pTmp->next != pContext ) + return; + + /* Make sure we are not using this context. */ + if ( pContext == pD3DCurrent ) + MakeCurrent( pD3DDefault ); + + /* Free the Mesa stuff. */ + if ( pContext->gl_visual ) + { + _mesa_destroy_visual( pContext->gl_visual ); + pContext->gl_visual = NULL; + } + if ( pContext->gl_buffer ) + { + _mesa_destroy_framebuffer( pContext->gl_buffer ); + pContext->gl_buffer = NULL; + } + if ( pContext->gl_ctx ) + { + _mesa_destroy_context( pContext->gl_ctx ); + pContext->gl_ctx = NULL; + } + + /* Now dump the D3D. */ + if ( pContext->pShared ) + TermHAL( pContext->pShared ); + + /* Update the previous context's link. */ + pTmp->next = pContext->next; + + /* Gonzo. */ + FREE( pContext ); +} +/*===========================================================================*/ +/* This function will pull the supplied context away from Win32. Basicly it*/ +/* will remove the hook from the window Proc. */ +/* */ +/* TODO: might want to serialize this stuff... */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +static BOOL UnBindWindow( D3DMESACONTEXT *pContext ) +{ + if ( pContext == NULL ) + return FALSE; + + if ( pContext == pD3DDefault ) + return TRUE; + + /* Make sure we always have a context bound. */ + if ( pContext == pD3DCurrent ) + pD3DCurrent = pD3DDefault; + + SetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC, (LONG)pContext->hOldProc ); + pContext->hOldProc = NULL; + + return TRUE; +} +/*===========================================================================*/ +/* There are two cases that allow for a faster clear when we know that the */ +/* whole buffer is cleared and that there is no clipping. */ +/*===========================================================================*/ +/* RETURN: the original mask with the bits cleared that represents the buffer* +/* or buffers we just cleared. */ +/*===========================================================================*/ +GLbitfield ClearBuffersD3D( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + DWORD dwFlags = 0; + + if ( mask & GL_COLOR_BUFFER_BIT ) + { + dwFlags |= D3DCLEAR_TARGET; + mask &= ~GL_COLOR_BUFFER_BIT; + } + if ( mask & GL_DEPTH_BUFFER_BIT ) + { + dwFlags |= D3DCLEAR_ZBUFFER; + mask &= ~GL_DEPTH_BUFFER_BIT; + } + if ( dwFlags == 0 ) + return mask; + + ClearHAL( pContext->pShared, + dwFlags, + all, + x, y, + width, height, + ((pContext->aClear<<24) | (pContext->rClear<<16) | (pContext->gClear<<8) | (pContext->bClear)), + ctx->Depth.Clear, + 0 ); + + return mask; +} + + + +/*===========================================================================*/ +/* TEXTURE MANAGER: ok here is how I did textures. Mesa-3.0 will keep track*/ +/* of all the textures for us. So this means that at anytime we can go to */ +/* the Mesa context and get the current texture. With this in mind this is */ +/* what I did. I really don't care about what textures get or are loaded */ +/* until I actually have to draw a tri that is textured. At this point I */ +/* must have the texture so I demand the texture by destorying all other */ +/* texture surfaces if need be and load the current one. This allows for the*/ +/* best preformance on low memory cards as time is not wasted loading and */ +/* unload textures. */ +/*===========================================================================*/ + + + + + +/*===========================================================================*/ +/* TextureLoad will try and create a D3D surface from the supplied texture */ +/* object if its level 0 (first). The surface will be fully filled with the */ +/* texture. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void TextureLoad( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + /* TODO: only doing first LOD. */ + if ( (ctx->DriverCtx == NULL) || (level != 0) ) + return; + + CreateTMgrHAL( pContext->pShared, + tObj->Name, + level, + tObj->Image[level]->Format, + (RECT *)NULL, + tObj->Image[level]->Width, + tObj->Image[level]->Height, + TM_ACTION_LOAD, + (void *)tObj->Image[level]->Data ); +} +/*===========================================================================*/ +/* TextureBind make sure that the texture is on the card. Thats it. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void TextureBind( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + /* TODO: only doing first LOD. */ + if ( (tObj->Image[0] == NULL) || (ctx->DriverCtx == NULL) ) + return; + + CreateTMgrHAL( pContext->pShared, + tObj->Name, + 0, + tObj->Image[0]->Format, + (RECT *)NULL, + tObj->Image[0]->Width, + tObj->Image[0]->Height, + TM_ACTION_BIND, + (void *)tObj->Image[0]->Data ); +} +/*===========================================================================*/ +/* TextureSubImage will make sure that the texture being updated is updated */ +/* if its on the card. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void TextureSubImage( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint internalFormat, const struct gl_texture_image *image ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + RECT rect; + + /* TODO: only doing first LOD. */ + if ( (ctx->DriverCtx == NULL) || (level > 0) ) + return; + + /* Create a dirty rectangle structure. */ + rect.left = xoffset; + rect.right = xoffset + width; + rect.top = yoffset; + rect.bottom = yoffset + height; + + CreateTMgrHAL( pContext->pShared, + tObj->Name, + 0, + tObj->Image[0]->Format, + &rect, + tObj->Image[0]->Width, + tObj->Image[0]->Height, + TM_ACTION_UPDATE, + (void *)tObj->Image[0]->Data ); +} + -- cgit v1.2.3