summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/windows/gldirect/dglwgl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/windows/gldirect/dglwgl.c')
-rw-r--r--src/mesa/drivers/windows/gldirect/dglwgl.c2964
1 files changed, 0 insertions, 2964 deletions
diff --git a/src/mesa/drivers/windows/gldirect/dglwgl.c b/src/mesa/drivers/windows/gldirect/dglwgl.c
deleted file mode 100644
index c46cfe162f9..00000000000
--- a/src/mesa/drivers/windows/gldirect/dglwgl.c
+++ /dev/null
@@ -1,2964 +0,0 @@
-/****************************************************************************
-*
-* Mesa 3-D graphics library
-* Direct3D Driver Interface
-*
-* ========================================================================
-*
-* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved.
-*
-* Permission is hereby granted, free of charge, to any person obtaining a
-* copy of this software and associated documentation files (the "Software"),
-* to deal in the Software without restriction, including without limitation
-* the rights to use, copy, modify, merge, publish, distribute, sublicense,
-* and/or sell copies of the Software, and to permit persons to whom the
-* Software is furnished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be included
-* in all copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
-* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-* SOFTWARE.
-*
-* ======================================================================
-*
-* Language: ANSI C
-* Environment: Windows 9x (Win32)
-*
-* Description: OpenGL window functions (wgl*).
-*
-****************************************************************************/
-
-#include "dglwgl.h"
-#ifdef _USE_GLD3_WGL
-#include "gld_driver.h"
-#endif
-
-#include "gl/glu.h" // MUST USE MICROSOFT'S GLU32!
-
-#ifndef _USE_GLD3_WGL
-extern DGL_mesaFuncs mesaFuncs;
-#endif
-
-// Need to export wgl* functions if using GLD3,
-// otherwise export GLD2 DGL_* functions.
-#ifdef _USE_GLD3_WGL
-#define _GLD_WGL_EXPORT(a) wgl##a
-#else
-#define _GLD_WGL_EXPORT(a) DGL_##a
-#endif
-
-// Calls into Mesa 4.x are different
-#ifdef _USE_GLD3_WGL
-#include "dlist.h"
-#include "drawpix.h"
-#include "get.h"
-#include "matrix.h"
-// NOTE: All the _GLD* macros now call the gl* functions direct.
-// This ensures that the correct internal pathway is taken. KeithH
-#define _GLD_glNewList glNewList
-#define _GLD_glBitmap glBitmap
-#define _GLD_glEndList glEndList
-#define _GLD_glDeleteLists glDeleteLists
-#define _GLD_glGetError glGetError
-#define _GLD_glTranslatef glTranslatef
-#define _GLD_glBegin glBegin
-#define _GLD_glVertex2fv glVertex2fv
-#define _GLD_glEnd glEnd
-#define _GLD_glNormal3f glNormal3f
-#define _GLD_glVertex3f glVertex3f
-#define _GLD_glVertex3fv glVertex3fv
-#else // _USE_GLD3_WGL
-#define _GLD_glNewList (*mesaFuncs.glNewList)
-#define _GLD_glBitmap (*mesaFuncs.glBitmap)
-#define _GLD_glEndList (*mesaFuncs.glEndList)
-#define _GLD_glDeleteLists (*mesaFuncs.glDeleteLists)
-#define _GLD_glGetError (*mesaFuncs.glGetError)
-#define _GLD_glTranslatef (*mesaFuncs.glTranslatef)
-#define _GLD_glBegin (*mesaFuncs.glBegin)
-#define _GLD_glVertex2fv (*mesaFuncs.glVertex2fv)
-#define _GLD_glEnd (*mesaFuncs.glEnd)
-#define _GLD_glNormal3f (*mesaFuncs.glNormal3f)
-#define _GLD_glVertex3f (*mesaFuncs.glVertex3f)
-#define _GLD_glVertex3fv (*mesaFuncs.glVertex3fv)
-#endif // _USE_GLD3_WGL
-
-// ***********************************************************************
-
-// Emulate SGI DDK calls.
-#define __wglMalloc(a) GlobalAlloc(GPTR, (a))
-#define __wglFree(a) GlobalFree((a))
-
-// ***********************************************************************
-
-// Mesa glu.h and MS glu.h call these different things...
-//#define GLUtesselator GLUtriangulatorObj
-//#define GLU_TESS_VERTEX_DATA GLU_VERTEX_DATA
-
-// For wglFontOutlines
-
-typedef GLUtesselator *(APIENTRY *gluNewTessProto)(void);
-typedef void (APIENTRY *gluDeleteTessProto)(GLUtesselator *tess);
-typedef void (APIENTRY *gluTessBeginPolygonProto)(GLUtesselator *tess, void *polygon_data);
-typedef void (APIENTRY *gluTessBeginContourProto)(GLUtesselator *tess);
-typedef void (APIENTRY *gluTessVertexProto)(GLUtesselator *tess, GLdouble coords[3], void *data);
-typedef void (APIENTRY *gluTessEndContourProto)(GLUtesselator *tess);
-typedef void (APIENTRY *gluTessEndPolygonProto)(GLUtesselator *tess);
-typedef void (APIENTRY *gluTessPropertyProto)(GLUtesselator *tess, GLenum which, GLdouble value);
-typedef void (APIENTRY *gluTessNormalProto)(GLUtesselator *tess, GLdouble x, GLdouble y, GLdouble z);
-typedef void (APIENTRY *gluTessCallbackProto)(GLUtesselator *tess, GLenum which, void (CALLBACK *)());
-
-static HINSTANCE gluModuleHandle;
-static gluNewTessProto gluNewTessProc;
-static gluDeleteTessProto gluDeleteTessProc;
-static gluTessBeginPolygonProto gluTessBeginPolygonProc;
-static gluTessBeginContourProto gluTessBeginContourProc;
-static gluTessVertexProto gluTessVertexProc;
-static gluTessEndContourProto gluTessEndContourProc;
-static gluTessEndPolygonProto gluTessEndPolygonProc;
-static gluTessPropertyProto gluTessPropertyProc;
-static gluTessNormalProto gluTessNormalProc;
-static gluTessCallbackProto gluTessCallbackProc;
-
-static HFONT hNewFont, hOldFont;
-static FLOAT ScaleFactor;
-
-#define LINE_BUF_QUANT 4000
-#define VERT_BUF_QUANT 4000
-
-static FLOAT* LineBuf;
-static DWORD LineBufSize;
-static DWORD LineBufIndex;
-static FLOAT* VertBuf;
-static DWORD VertBufSize;
-static DWORD VertBufIndex;
-static GLenum TessErrorOccurred;
-
-static int AppendToLineBuf(
- FLOAT value);
-
-static int AppendToVertBuf(
- FLOAT value);
-
-static int DrawGlyph(
- UCHAR* glyphBuf,
- DWORD glyphSize,
- FLOAT chordalDeviation,
- FLOAT extrusion,
- INT format);
-
-static void FreeLineBuf(void);
-
-static void FreeVertBuf(void);
-
-static long GetWord(
- UCHAR** p);
-
-static long GetDWord(
- UCHAR** p);
-
-static double GetFixed(
- UCHAR** p);
-
-static int InitLineBuf(void);
-
-static int InitVertBuf(void);
-
-static HFONT CreateHighResolutionFont(
- HDC hDC);
-
-static int MakeDisplayListFromGlyph(
- DWORD listName,
- UCHAR* glyphBuf,
- DWORD glyphSize,
- LPGLYPHMETRICSFLOAT glyphMetricsFloat,
- FLOAT chordalDeviation,
- FLOAT extrusion,
- INT format);
-
-static BOOL LoadGLUTesselator(void);
-static BOOL UnloadGLUTesselator(void);
-
-static int MakeLinesFromArc(
- FLOAT x0,
- FLOAT y0,
- FLOAT x1,
- FLOAT y1,
- FLOAT x2,
- FLOAT y2,
- DWORD vertexCountIndex,
- FLOAT chordalDeviationSquared);
-
-static int MakeLinesFromGlyph( UCHAR* glyphBuf,
- DWORD glyphSize,
- FLOAT chordalDeviation);
-
-static int MakeLinesFromTTLine( UCHAR** pp,
- DWORD vertexCountIndex,
- WORD pointCount);
-
-static int MakeLinesFromTTPolycurve( UCHAR** pp,
- DWORD vertexCountIndex,
- FLOAT chordalDeviation);
-
-static int MakeLinesFromTTPolygon( UCHAR** pp,
- FLOAT chordalDeviation);
-
-static int MakeLinesFromTTQSpline( UCHAR** pp,
- DWORD vertexCountIndex,
- WORD pointCount,
- FLOAT chordalDeviation);
-
-static void CALLBACK TessCombine( double coords[3],
- void* vertex_data[4],
- FLOAT weight[4],
- void** outData);
-
-static void CALLBACK TessError( GLenum error);
-
-static void CALLBACK TessVertexOutData( FLOAT p[3],
- GLfloat z);
-
-// ***********************************************************************
-
-#ifdef GLD_THREADS
-#pragma message("compiling DGLWGL.C vars for multi-threaded support")
-extern CRITICAL_SECTION CriticalSection;
-extern DWORD dwTLSPixelFormat; // TLS index for current pixel format
-#endif
-int curPFD = 0; // Current PFD (static)
-
-// ***********************************************************************
-
-int dglGetPixelFormat(void)
-{
-#ifdef GLD_THREADS
- int iPixelFormat;
- // get thread-specific instance
- if (glb.bMultiThreaded) {
- __try {
- iPixelFormat = (int)TlsGetValue(dwTLSPixelFormat);
- }
- __except(EXCEPTION_EXECUTE_HANDLER) {
- iPixelFormat = curPFD;
- }
- }
- // get global static var
- else {
- iPixelFormat = curPFD;
- }
- return iPixelFormat;
-#else
- return curPFD;
-#endif
-}
-
-// ***********************************************************************
-
-void dglSetPixelFormat(int iPixelFormat)
-{
-#ifdef GLD_THREADS
- // set thread-specific instance
- if (glb.bMultiThreaded) {
- __try {
- TlsSetValue(dwTLSPixelFormat, (LPVOID)iPixelFormat);
- }
- __except(EXCEPTION_EXECUTE_HANDLER) {
- curPFD = iPixelFormat;
- }
- }
- // set global static var
- else {
- curPFD = iPixelFormat;
- }
-#else
- curPFD = iPixelFormat;
-#endif
-}
-
-// ***********************************************************************
-
-int APIENTRY _GLD_WGL_EXPORT(ChoosePixelFormat)(
- HDC a,
- CONST PIXELFORMATDESCRIPTOR *ppfd)
-{
- DGL_pixelFormat *lpPF = glb.lpPF;
-
- PIXELFORMATDESCRIPTOR ppfdBest;
- int i;
- int bestIndex = -1;
- int numPixelFormats;
- DWORD dwFlags;
-
- char buf[128];
- char cat[8];
-
- DWORD dwAllFlags =
- PFD_DRAW_TO_WINDOW |
- PFD_DRAW_TO_BITMAP |
- PFD_SUPPORT_GDI |
- PFD_SUPPORT_OPENGL |
- PFD_GENERIC_FORMAT |
- PFD_NEED_PALETTE |
- PFD_NEED_SYSTEM_PALETTE |
- PFD_DOUBLEBUFFER |
- PFD_STEREO |
- /*PFD_SWAP_LAYER_BUFFERS |*/
- PFD_DOUBLEBUFFER_DONTCARE |
- PFD_STEREO_DONTCARE |
- PFD_SWAP_COPY |
- PFD_SWAP_EXCHANGE |
- PFD_GENERIC_ACCELERATED |
- 0;
-
- // Validate license
- if (!dglValidate())
- return 0;
-
- // List may not be built until dglValidate() is called! KeithH
- lpPF = glb.lpPF;
-
- //
- // Lets print the input pixel format to the log
- // ** Based on "wglinfo" by Nate Robins **
- //
- ddlogMessage(DDLOG_SYSTEM, "ChoosePixelFormat:\n");
- ddlogMessage(DDLOG_INFO, "Input pixel format for ChoosePixelFormat:\n");
- ddlogMessage(DDLOG_INFO,
- " visual x bf lv rg d st r g b a ax dp st accum buffs ms\n");
- ddlogMessage(DDLOG_INFO,
- " id dep cl sp sz l ci b ro sz sz sz sz bf th cl r g b a ns b\n");
- ddlogMessage(DDLOG_INFO,
- "-----------------------------------------------------------------\n");
- sprintf(buf, " . ");
-
- sprintf(cat, "%2d ", ppfd->cColorBits);
- strcat(buf, cat);
- if(ppfd->dwFlags & PFD_DRAW_TO_WINDOW) sprintf(cat, "wn ");
- else if(ppfd->dwFlags & PFD_DRAW_TO_BITMAP) sprintf(cat, "bm ");
- else sprintf(cat, ". ");
- strcat(buf, cat);
-
- /* should find transparent pixel from LAYERPLANEDESCRIPTOR */
- sprintf(cat, " . ");
- strcat(buf, cat);
-
- sprintf(cat, "%2d ", ppfd->cColorBits);
- strcat(buf, cat);
-
- /* bReserved field indicates number of over/underlays */
- if(ppfd->bReserved) sprintf(cat, " %d ", ppfd->bReserved);
- else sprintf(cat, " . ");
- strcat(buf, cat);
-
- sprintf(cat, " %c ", ppfd->iPixelType == PFD_TYPE_RGBA ? 'r' : 'c');
- strcat(buf, cat);
-
- sprintf(cat, "%c ", ppfd->dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.');
- strcat(buf, cat);
-
- sprintf(cat, " %c ", ppfd->dwFlags & PFD_STEREO ? 'y' : '.');
- strcat(buf, cat);
-
- if(ppfd->cRedBits && ppfd->iPixelType == PFD_TYPE_RGBA)
- sprintf(cat, "%2d ", ppfd->cRedBits);
- else sprintf(cat, " . ");
- strcat(buf, cat);
-
- if(ppfd->cGreenBits && ppfd->iPixelType == PFD_TYPE_RGBA)
- sprintf(cat, "%2d ", ppfd->cGreenBits);
- else sprintf(cat, " . ");
- strcat(buf, cat);
-
- if(ppfd->cBlueBits && ppfd->iPixelType == PFD_TYPE_RGBA)
- sprintf(cat, "%2d ", ppfd->cBlueBits);
- else sprintf(cat, " . ");
- strcat(buf, cat);
-
- if(ppfd->cAlphaBits && ppfd->iPixelType == PFD_TYPE_RGBA)
- sprintf(cat, "%2d ", ppfd->cAlphaBits);
- else sprintf(cat, " . ");
- strcat(buf, cat);
-
- if(ppfd->cAuxBuffers) sprintf(cat, "%2d ", ppfd->cAuxBuffers);
- else sprintf(cat, " . ");
- strcat(buf, cat);
-
- if(ppfd->cDepthBits) sprintf(cat, "%2d ", ppfd->cDepthBits);
- else sprintf(cat, " . ");
- strcat(buf, cat);
-
- if(ppfd->cStencilBits) sprintf(cat, "%2d ", ppfd->cStencilBits);
- else sprintf(cat, " . ");
- strcat(buf, cat);
-
- if(ppfd->cAccumRedBits) sprintf(cat, "%2d ", ppfd->cAccumRedBits);
- else sprintf(cat, " . ");
- strcat(buf, cat);
-
- if(ppfd->cAccumGreenBits) sprintf(cat, "%2d ", ppfd->cAccumGreenBits);
- else sprintf(cat, " . ");
- strcat(buf, cat);
-
- if(ppfd->cAccumBlueBits) sprintf(cat, "%2d ", ppfd->cAccumBlueBits);
- else sprintf(cat, " . ");
- strcat(buf, cat);
-
- if(ppfd->cAccumAlphaBits) sprintf(cat, "%2d ", ppfd->cAccumAlphaBits);
- else sprintf(cat, " . ");
- strcat(buf, cat);
-
- /* no multisample in Win32 */
- sprintf(cat, " . .\n");
- strcat(buf, cat);
-
- ddlogMessage(DDLOG_INFO, buf);
- ddlogMessage(DDLOG_INFO,
- "-----------------------------------------------------------------\n");
- ddlogMessage(DDLOG_INFO, "\n");
-
- //
- // Examine the flags for correctness
- //
- dwFlags = ppfd->dwFlags;
- if (dwFlags != (dwFlags & dwAllFlags))
- {
- /* error: bad dwFlags */
- ddlogPrintf(DDLOG_WARN,
- "ChoosePixelFormat: bad flags (0x%x)",
- dwFlags & (~dwAllFlags));
- // Mask illegal flags and continue
- dwFlags = dwFlags & dwAllFlags;
- }
-
- switch (ppfd->iPixelType) {
- case PFD_TYPE_RGBA:
- case PFD_TYPE_COLORINDEX:
- break;
- default:
- /* error: bad iPixelType */
- ddlogMessage(DDLOG_WARN, "ChoosePixelFormat: bad pixel type\n");
- return 0;
- }
-
- switch (ppfd->iLayerType) {
- case PFD_MAIN_PLANE:
- case PFD_OVERLAY_PLANE:
- case PFD_UNDERLAY_PLANE:
- break;
- default:
- /* error: bad iLayerType */
- ddlogMessage(DDLOG_WARN, "ChoosePixelFormat: bad layer type\n");
- return 0;
- }
-
- numPixelFormats = glb.nPixelFormatCount;
-
- /* loop through candidate pixel format descriptors */
- for (i=0; i<numPixelFormats; ++i) {
- PIXELFORMATDESCRIPTOR ppfdCandidate;
-
- memcpy(&ppfdCandidate, &lpPF[i].pfd, sizeof(PIXELFORMATDESCRIPTOR));
-
- /*
- ** Check attributes which must match
- */
- if (ppfd->iPixelType != ppfdCandidate.iPixelType) {
- continue;
- }
-
- if (ppfd->iLayerType != ppfdCandidate.iLayerType) {
- continue;
- }
-
- if (((dwFlags ^ ppfdCandidate.dwFlags) & dwFlags) &
- (PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP |
- PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL))
- {
- continue;
- }
-
- if (!(dwFlags & PFD_DOUBLEBUFFER_DONTCARE)) {
- if ((dwFlags & PFD_DOUBLEBUFFER) !=
- (ppfdCandidate.dwFlags & PFD_DOUBLEBUFFER))
- {
- continue;
- }
- }
-
-// if (!(dwFlags & PFD_STEREO_DONTCARE)) {
- if ((dwFlags & PFD_STEREO) !=
- (ppfdCandidate.dwFlags & PFD_STEREO))
- {
- continue;
- }
-// }
-
- if (ppfd->iPixelType==PFD_TYPE_RGBA
- && ppfd->cAlphaBits && !ppfdCandidate.cAlphaBits) {
- continue;
- }
-
- if (ppfd->iPixelType==PFD_TYPE_RGBA
- && ppfd->cAccumBits && !ppfdCandidate.cAccumBits) {
- continue;
- }
-
- if (ppfd->cDepthBits && !ppfdCandidate.cDepthBits) {
- continue;
- }
-
- if (ppfd->cStencilBits && !ppfdCandidate.cStencilBits) {
- continue;
- }
-
- if (ppfd->cAuxBuffers && !ppfdCandidate.cAuxBuffers) {
- continue;
- }
-
- /*
- ** See if candidate is better than the previous best choice
- */
- if (bestIndex == -1) {
- ppfdBest = ppfdCandidate;
- bestIndex = i;
- continue;
- }
-
- if ((ppfd->cColorBits > ppfdBest.cColorBits &&
- ppfdCandidate.cColorBits > ppfdBest.cColorBits) ||
- (ppfd->cColorBits <= ppfdCandidate.cColorBits &&
- ppfdCandidate.cColorBits < ppfdBest.cColorBits))
- {
- ppfdBest = ppfdCandidate;
- bestIndex = i;
- continue;
- }
-
- if (ppfd->iPixelType==PFD_TYPE_RGBA
- && ppfd->cAlphaBits
- && ppfdCandidate.cAlphaBits > ppfdBest.cAlphaBits)
- {
- ppfdBest = ppfdCandidate;
- bestIndex = i;
- continue;
- }
-
- if (ppfd->iPixelType==PFD_TYPE_RGBA
- && ppfd->cAccumBits
- && ppfdCandidate.cAccumBits > ppfdBest.cAccumBits)
- {
- ppfdBest = ppfdCandidate;
- bestIndex = i;
- continue;
- }
-
- if ((ppfd->cDepthBits > ppfdBest.cDepthBits &&
- ppfdCandidate.cDepthBits > ppfdBest.cDepthBits) ||
- (ppfd->cDepthBits <= ppfdCandidate.cDepthBits &&
- ppfdCandidate.cDepthBits < ppfdBest.cDepthBits))
- {
- ppfdBest = ppfdCandidate;
- bestIndex = i;
- continue;
- }
-
- if (ppfd->cStencilBits &&
- ppfdCandidate.cStencilBits > ppfdBest.cStencilBits)
- {
- ppfdBest = ppfdCandidate;
- bestIndex = i;
- continue;
- }
-
- if (ppfd->cAuxBuffers &&
- ppfdCandidate.cAuxBuffers > ppfdBest.cAuxBuffers)
- {
- ppfdBest = ppfdCandidate;
- bestIndex = i;
- continue;
- }
- }
-
- if (bestIndex != -1) {
- ddlogPrintf(DDLOG_SYSTEM, "Pixel Format %d chosen as best match", bestIndex+1);
- return bestIndex + 1;
- }
-
- // Return the pixelformat that has the most capabilities.
- // ** NOTE: This is only possible due to the way the list
- // of pixelformats is built. **
- // Now picks best pixelformat. KeithH
- bestIndex = numPixelFormats; // most capable double buffer format
- ddlogPrintf(DDLOG_SYSTEM, "Pixel Format %d chosen by default", bestIndex);
- return (bestIndex);
-}
-
-// ***********************************************************************
-
-BOOL APIENTRY _GLD_WGL_EXPORT(CopyContext)(
- HGLRC a,
- HGLRC b,
- UINT c)
-{
- // Validate license
- if (!dglValidate())
- return FALSE;
- UNSUPPORTED("wglCopyContext")
- return FALSE; // Failed
-}
-
-// ***********************************************************************
-
-HGLRC APIENTRY _GLD_WGL_EXPORT(CreateContext)(
- HDC a)
-{
- int ipf;
-
- // Validate license
- if (!dglValidate())
- return 0;
-
- // Check that the current PFD is valid
- ipf = dglGetPixelFormat();
- if (!IsValidPFD(ipf))
- return (HGLRC)0;
-
- return dglCreateContext(a, &glb.lpPF[ipf-1]);
-}
-
-// ***********************************************************************
-
-HGLRC APIENTRY _GLD_WGL_EXPORT(CreateLayerContext)(
- HDC a,
- int b)
-{
- // Validate license
- if (!dglValidate())
- return 0;
-
- UNSUPPORTED("wglCreateLayerContext")
- return NULL; // Failed
-}
-
-// ***********************************************************************
-
-BOOL APIENTRY _GLD_WGL_EXPORT(DeleteContext)(
- HGLRC a)
-{
- // Validate license
- if (!dglValidate())
- return FALSE;
-
- return dglDeleteContext(a);
-}
-
-// ***********************************************************************
-
-BOOL APIENTRY _GLD_WGL_EXPORT(DescribeLayerPlane)(
- HDC hDC,
- int iPixelFormat,
- int iLayerPlane,
- UINT nBytes,
- LPLAYERPLANEDESCRIPTOR plpd)
-{
- // Validate license
- if (!dglValidate())
- return FALSE;
-
- UNSUPPORTED("DGL_DescribeLayerPlane")
-
-// gldLogPrintf(GLDLOG_INFO, "DescribeLayerPlane: %d, %d", iPixelFormat, iLayerPlane);
-
- return FALSE;
-}
-
-// ***********************************************************************
-
-int APIENTRY _GLD_WGL_EXPORT(DescribePixelFormat)(
- HDC a,
- int b,
- UINT c,
- LPPIXELFORMATDESCRIPTOR d)
-{
- UINT nSize;
-
- // Validate license
- if (!dglValidate())
- return 0;
-
- if (d == NULL) // Calling app requires max number of PF's
- return glb.nPixelFormatCount;
-
- // The supplied buffer may be larger than the info that we
- // will be copying.
- if (c > sizeof(PIXELFORMATDESCRIPTOR))
- nSize = sizeof(PIXELFORMATDESCRIPTOR);
- else
- nSize = c;
-
- // Setup an empty PFD before doing validation check
- memset(d, 0, nSize);
- d->nSize = nSize;
- d->nVersion = 1;
-
- if (!IsValidPFD(b))
- return 0; // Bail if PFD index is invalid
-
- memcpy(d, &glb.lpPF[b-1].pfd, nSize);
-
- return glb.nPixelFormatCount;
-}
-
-// ***********************************************************************
-
-HGLRC APIENTRY _GLD_WGL_EXPORT(GetCurrentContext)(void)
-{
- // Validate license
- if (!dglValidate())
- return 0;
-
- return dglGetCurrentContext();
-}
-
-// ***********************************************************************
-
-HDC APIENTRY _GLD_WGL_EXPORT(GetCurrentDC)(void)
-{
- // Validate license
- if (!dglValidate())
- return 0;
-
- return dglGetCurrentDC();
-}
-
-// ***********************************************************************
-
-PROC APIENTRY _GLD_WGL_EXPORT(GetDefaultProcAddress)(
- LPCSTR a)
-{
- // Validate license
- if (!dglValidate())
- return NULL;
-
- UNSUPPORTED("DGL_GetDefaultProcAddress")
- return NULL;
-}
-
-// ***********************************************************************
-
-int APIENTRY _GLD_WGL_EXPORT(GetLayerPaletteEntries)(
- HDC a,
- int b,
- int c,
- int d,
- COLORREF *e)
-{
- // Validate license
- if (!dglValidate())
- return 0;
-
- UNSUPPORTED("DGL_GetLayerPaletteEntries")
- return 0;
-}
-
-// ***********************************************************************
-
-int APIENTRY _GLD_WGL_EXPORT(GetPixelFormat)(
- HDC a)
-{
- // Validate license
- if (!dglValidate())
- return 0;
-
- return dglGetPixelFormat();
-}
-
-// ***********************************************************************
-
-PROC APIENTRY _GLD_WGL_EXPORT(GetProcAddress)(
- LPCSTR a)
-{
- PROC dglGetProcAddressD3D(LPCSTR a);
-
- // Validate license
- if (!dglValidate())
- return NULL;
-
-#ifdef _USE_GLD3_WGL
- return _gldDriver.wglGetProcAddress(a);
-#else
- return dglGetProcAddressD3D(a);
-#endif
-}
-
-// ***********************************************************************
-
-BOOL APIENTRY _GLD_WGL_EXPORT(MakeCurrent)(
- HDC a,
- HGLRC b)
-{
- // Validate license
- if (!dglValidate())
- return FALSE;
-
- return dglMakeCurrent(a, b);
-}
-
-// ***********************************************************************
-
-BOOL APIENTRY _GLD_WGL_EXPORT(RealizeLayerPalette)(
- HDC a,
- int b,
- BOOL c)
-{
- // Validate license
- if (!dglValidate())
- return FALSE;
-
- UNSUPPORTED("DGL_RealizeLayerPalette")
- return FALSE;
-}
-
-// ***********************************************************************
-
-int APIENTRY _GLD_WGL_EXPORT(SetLayerPaletteEntries)(
- HDC a,
- int b,
- int c,
- int d,
- CONST COLORREF *e)
-{
- // Validate license
- if (!dglValidate())
- return 0;
-
- UNSUPPORTED("DGL_SetLayerPaletteEntries")
- return 0;
-}
-
-// ***********************************************************************
-
-BOOL APIENTRY _GLD_WGL_EXPORT(SetPixelFormat)(
- HDC a,
- int b,
- CONST PIXELFORMATDESCRIPTOR *c)
-{
- // Validate license
- if (!dglValidate())
- return FALSE;
-
- if (IsValidPFD(b)) {
- ddlogPrintf(DDLOG_SYSTEM, "SetPixelFormat: PixelFormat %d has been set", b);
- dglSetPixelFormat(b);
- return TRUE;
- } else {
- ddlogPrintf(DDLOG_ERROR,
- "SetPixelFormat: PixelFormat %d is invalid and cannot be set", b);
- return FALSE;
- }
-}
-
-// ***********************************************************************
-/*
- * Share lists between two gl_context structures.
- * This was added for WIN32 WGL function support, since wglShareLists()
- * must be called *after* wglCreateContext() with valid GLRCs. (DaveM)
- */
-//
-// Copied from GLD2.x. KeithH
-//
-static GLboolean _gldShareLists(
- struct gl_context *ctx1,
- struct gl_context *ctx2)
-{
- /* Sanity check context pointers */
- if (ctx1 == NULL || ctx2 == NULL)
- return GL_FALSE;
- /* Sanity check shared list pointers */
- if (ctx1->Shared == NULL || ctx2->Shared == NULL)
- return GL_FALSE;
- /* Decrement reference count on sharee to release previous list */
- ctx2->Shared->RefCount--;
-#if 0 /* 3DStudio exits on this memory release */
- if (ctx2->Shared->RefCount == 0)
- free_shared_state(ctx2, ctx2->Shared);
-#endif
- /* Re-assign list from sharer to sharee and increment reference count */
- ctx2->Shared = ctx1->Shared;
- ctx1->Shared->RefCount++;
- return GL_TRUE;
-}
-
-// ***********************************************************************
-
-BOOL APIENTRY _GLD_WGL_EXPORT(ShareLists)(
- HGLRC a,
- HGLRC b)
-{
- DGL_ctx *dgl1, *dgl2;
-
- // Validate license
- if (!dglValidate())
- return FALSE;
-
- // Mesa supports shared lists, but you need to supply the shared
- // GL context info when calling gl_create_context(). An auxiliary
- // function gl_share_lists() has been added to update the shared
- // list info after the GL contexts have been created. (DaveM)
- dgl1 = dglGetContextAddress(a);
- dgl2 = dglGetContextAddress(b);
- if (dgl1->bAllocated && dgl2->bAllocated) {
-#ifdef _USE_GLD3_WGL
- return _gldShareLists(dgl1->glCtx, dgl2->glCtx);
-#else
- return (*mesaFuncs.gl_share_lists)(dgl1->glCtx, dgl2->glCtx);
-#endif
- }
- return FALSE;
-}
-
-// ***********************************************************************
-
-BOOL APIENTRY _GLD_WGL_EXPORT(SwapBuffers)(
- HDC a)
-{
- // Validate license
- if (!dglValidate())
- return FALSE;
-
- return dglSwapBuffers(a);
-}
-
-// ***********************************************************************
-
-BOOL APIENTRY _GLD_WGL_EXPORT(SwapLayerBuffers)(
- HDC a,
- UINT b)
-{
- // Validate license
- if (!dglValidate())
- return FALSE;
-
- return dglSwapBuffers(a);
-}
-
-// ***********************************************************************
-
-// ***********************************************************************
-// Note: This ResizeBuffers() function may be called from
-// either MESA glViewport() or GLD wglMakeCurrent().
-
-BOOL dglWglResizeBuffers(
- struct gl_context *ctx,
- BOOL bDefaultDriver)
-{
- DGL_ctx *dgl = NULL;
- RECT rcScreenRect;
- DWORD dwWidth;
- DWORD dwHeight;
- DDSURFACEDESC2 ddsd2;
- DDSCAPS2 ddscaps2;
- IDirectDrawClipper *lpddClipper = NULL;
- DWORD dwFlags;
- HRESULT hResult;
-
- DWORD dwMemoryType;
-
- int i;
- struct gl_texture_object *tObj;
- struct gl_texture_image *image;
-
- BOOL bWasFullscreen;
- BOOL bSaveDesktop;
- BOOL bFullScrnWin = FALSE;
- DDSURFACEDESC2 ddsd2DisplayMode;
-
- DDBLTFX ddbltfx;
- POINT pt;
- RECT rcDst;
-#ifdef _USE_GLD3_WGL
- GLD_displayMode glddm;
-#endif
-
-#define DDLOG_CRITICAL_OR_WARN (bDefaultDriver ? DDLOG_WARN : DDLOG_CRITICAL)
-
- // Validate license
- if (!dglValidate())
- return FALSE;
-
- // Sanity checks
- if (ctx == NULL)
- return FALSE;
- dgl = ctx->DriverCtx;
- if (dgl == NULL)
- return FALSE;
-
- // Get the window size and calculate its dimensions
- if (dgl->hWnd == NULL) {
- // Check for non-window DC = memory DC ?
- if (GetClipBox(dgl->hDC, &rcScreenRect) == ERROR)
- SetRect(&rcScreenRect, 0, 0, 0, 0);
- }
- else if (!GetClientRect(dgl->hWnd, &rcScreenRect))
- SetRect(&rcScreenRect, 0, 0, 0, 0);
- dwWidth = rcScreenRect.right - rcScreenRect.left;
- dwHeight = rcScreenRect.bottom - rcScreenRect.top;
- CopyRect(&dgl->rcScreenRect, &rcScreenRect);
-
- // This will occur on Alt-Tab
- if ((dwWidth == 0) && (dwHeight == 0)) {
- //dgl->bCanRender = FALSE;
- return TRUE; // No resize possible!
- }
-
- // Some apps zero only 1 dimension for non-visible window... (DaveM)
- if ((dwWidth == 0) || (dwHeight == 0)) {
- dwWidth = 8;
- dwHeight = 8;
- }
-
- // Test to see if a resize is required.
- // Note that the dimensions will be the same if a prior resize attempt failed.
- if ((dwWidth == dgl->dwWidth) && (dwHeight == dgl->dwHeight) && bDefaultDriver) {
- return TRUE; // No resize required
- }
-
- ddlogPrintf(DDLOG_SYSTEM, "dglResize: %dx%d", dwWidth, dwHeight);
-#ifndef _USE_GLD3_WGL
- // Work out where we want our surfaces created
- dwMemoryType = (bDefaultDriver) ? glb.dwMemoryType : DDSCAPS_SYSTEMMEMORY;
-#endif // _USE_GLD3_WGL
-
- // Note previous fullscreen vs window display status
- bWasFullscreen = dgl->bFullscreen;
-
-#ifdef _USE_GLD3_WGL
- if (_gldDriver.GetDisplayMode(dgl, &glddm)) {
- if ( (dwWidth == glddm.Width) &&
- (dwHeight == glddm.Height) ) {
- bFullScrnWin = TRUE;
- }
- if (bFullScrnWin && glb.bPrimary && !glb.bFullscreenBlit && !glb.bDirectDrawPersistant) {
- dgl->bFullscreen = TRUE;
- ddlogMessage(DDLOG_INFO, "Fullscreen window after resize.\n");
- }
- else {
- dgl->bFullscreen = FALSE;
- ddlogMessage(DDLOG_INFO, "Non-Fullscreen window after resize.\n");
- }
- // Cache the display mode dimensions
- dgl->dwModeWidth = glddm.Width;
- dgl->dwModeHeight = glddm.Height;
- }
-
- // Clamp the effective window dimensions to primary surface.
- // We need to do this for D3D viewport dimensions even if wide
- // surfaces are supported. This also is a good idea for handling
- // whacked-out window dimensions passed for non-drawable windows
- // like Solid Edge. (DaveM)
- if (dgl->dwWidth > glddm.Width)
- dgl->dwWidth = glddm.Width;
- if (dgl->dwHeight > glddm.Height)
- dgl->dwHeight = glddm.Height;
-#else // _USE_GLD3_WGL
- // Window resize may have changed to fullscreen
- ZeroMemory(&ddsd2DisplayMode, sizeof(ddsd2DisplayMode));
- ddsd2DisplayMode.dwSize = sizeof(ddsd2DisplayMode);
- hResult = IDirectDraw4_GetDisplayMode(
- dgl->lpDD4,
- &ddsd2DisplayMode);
- if (SUCCEEDED(hResult)) {
- if ( (dwWidth == ddsd2DisplayMode.dwWidth) &&
- (dwHeight == ddsd2DisplayMode.dwHeight) ) {
- bFullScrnWin = TRUE;
- }
- if (bFullScrnWin && glb.bPrimary && !glb.bFullscreenBlit && !glb.bDirectDrawPersistant) {
- dgl->bFullscreen = TRUE;
- ddlogMessage(DDLOG_INFO, "Fullscreen window after resize.\n");
- }
- else {
- dgl->bFullscreen = FALSE;
- ddlogMessage(DDLOG_INFO, "Non-Fullscreen window after resize.\n");
- }
- // Cache the display mode dimensions
- dgl->dwModeWidth = ddsd2DisplayMode.dwWidth;
- dgl->dwModeHeight = ddsd2DisplayMode.dwHeight;
- }
-
- // Clamp the effective window dimensions to primary surface.
- // We need to do this for D3D viewport dimensions even if wide
- // surfaces are supported. This also is a good idea for handling
- // whacked-out window dimensions passed for non-drawable windows
- // like Solid Edge. (DaveM)
- if (dgl->dwWidth > ddsd2DisplayMode.dwWidth)
- dgl->dwWidth = ddsd2DisplayMode.dwWidth;
- if (dgl->dwHeight > ddsd2DisplayMode.dwHeight)
- dgl->dwHeight = ddsd2DisplayMode.dwHeight;
-#endif // _USE_GLD3_WGL
-
- // Note if fullscreen vs window display has changed?
- bSaveDesktop = (!bWasFullscreen && !dgl->bFullscreen) ? TRUE : FALSE;
- // Save the desktop primary surface from being destroyed
- // whenever remaining in windowed mode, since the stereo mode
- // switches are expensive...
-
-#ifndef _USE_GLD3_WGL
- // Don't need to re-allocate persistant buffers. (DaveM)
- // Though we should clear the back buffers to hide artifacts.
- if (glb.bDirectDrawPersistant && glb.bPersistantBuffers) {
- dgl->dwWidth = dwWidth;
- dgl->dwHeight = dwHeight;
- ZeroMemory(&ddbltfx, sizeof(ddbltfx));
- ddbltfx.dwSize = sizeof(ddbltfx);
- ddbltfx.dwFillColor = dgl->dwClearColorPF;
- IDirectDrawSurface4_Blt(dgl->lpBack4, &rcScreenRect, NULL, NULL,
- DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
- return TRUE;
- }
-
- // Ensure all rendering is complete
- if (ctx->Driver.Finish)
- (*ctx->Driver.Finish)(ctx);
- if (dgl->bSceneStarted == TRUE) {
- IDirect3DDevice3_EndScene(dgl->lpDev3);
- dgl->bSceneStarted = FALSE;
- }
-#endif // _USE_GLD3_WGL
- dgl->bCanRender = FALSE;
-
-#ifdef GLD_THREADS
- // Serialize access to DirectDraw and DDS operations
- if (glb.bMultiThreaded)
- EnterCriticalSection(&CriticalSection);
-#endif
-
-#ifndef _USE_GLD3_WGL
- // Release existing surfaces
- RELEASE(dgl->lpDev3);
- RELEASE(dgl->lpDepth4);
- RELEASE(dgl->lpBack4);
- if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary)
- ;
- else
- RELEASE(dgl->lpFront4);
-#endif // _USE_GLD3_WGL
- dgl->dwWidth = dwWidth;
- dgl->dwHeight = dwHeight;
-
- // Set defaults
- dgl->dwModeWidth = dgl->dwWidth;
- dgl->dwModeHeight = dgl->dwHeight;
-
-#ifdef _USE_GLD3_WGL
- if (!_gldDriver.ResizeDrawable(dgl, bDefaultDriver, glb.bDirectDrawPersistant, glb.bPersistantBuffers))
- goto cleanup_and_return_with_error;
-#else // _USE_GLD3_WGL
-
- if (dgl->bFullscreen) {
- //
- // FULLSCREEN
- //
-
- // Disable warning popups when in fullscreen mode
- ddlogWarnOption(FALSE);
-
- // Have to release the persistant DirectDraw primary surface
- // if switching to fullscreen mode. So if application wants
- // persistant display in fullscreen mode, a fullscreen-size
- // window should be used instead via fullscreen-blit option.
- if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) {
- RELEASE(glb.lpPrimary4);
- glb.bDirectDrawPrimary = FALSE;
- }
-
- dwFlags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT;
- if (glb.bFastFPU)
- dwFlags |= DDSCL_FPUSETUP; // optional
- hResult = IDirectDraw4_SetCooperativeLevel(dgl->lpDD4, dgl->hWnd, dwFlags);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Unable to set Exclusive Fullscreen mode", hResult);
- goto cleanup_and_return_with_error;
- }
-
- hResult = IDirectDraw4_SetDisplayMode(dgl->lpDD4,
- dgl->dwModeWidth,
- dgl->dwModeHeight,
- dgl->dwBPP,
- 0,
- 0);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetDisplayMode failed", hResult);
- goto cleanup_and_return_with_error;
- }
-
- // ** The display mode has changed, so dont use MessageBox! **
-
- ZeroMemory(&ddsd2, sizeof(ddsd2));
- ddsd2.dwSize = sizeof(ddsd2);
-
- if (dgl->bDoubleBuffer) {
- // Double buffered
- // Primary surface
- ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
- ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
- DDSCAPS_FLIP |
- DDSCAPS_COMPLEX |
- DDSCAPS_3DDEVICE |
- dwMemoryType;
- ddsd2.dwBackBufferCount = 1;
- hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpFront4, NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (primary) failed", hResult);
- goto cleanup_and_return_with_error;
- }
- // Render target surface
- ZeroMemory(&ddscaps2, sizeof(ddscaps2)); // Clear the entire struct.
- ddscaps2.dwCaps = DDSCAPS_BACKBUFFER;
- hResult = IDirectDrawSurface4_GetAttachedSurface(dgl->lpFront4, &ddscaps2, &dgl->lpBack4);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: GetAttachedSurface failed", hResult);
- goto cleanup_and_return_with_error;
- }
- } else {
- // Single buffered
- // Primary surface
- ddsd2.dwFlags = DDSD_CAPS;
- ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
- //DDSCAPS_3DDEVICE |
- dwMemoryType;
-
- hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpFront4, NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (primary) failed", hResult);
- goto cleanup_and_return_with_error;
- }
-
- dgl->lpBack4 = NULL;
- }
- } else {
- // WINDOWED
-
- // OK to enable warning popups in windowed mode
- ddlogWarnOption(glb.bMessageBoxWarnings);
-
- // Ditto if persistant DirectDraw primary
- if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary)
- goto DoClipperOnly;
-
- // WINDOWED
- dwFlags = DDSCL_NORMAL;
- if (glb.bMultiThreaded)
- dwFlags |= DDSCL_MULTITHREADED;
- if (glb.bFastFPU)
- dwFlags |= DDSCL_FPUSETUP; // optional
- hResult = IDirectDraw4_SetCooperativeLevel(dgl->lpDD4,
- dgl->hWnd,
- dwFlags);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Unable to set Normal coop level", hResult);
- goto cleanup_and_return_with_error;
- }
- // Primary surface
- ZeroMemory(&ddsd2, sizeof(ddsd2));
- ddsd2.dwSize = sizeof(ddsd2);
- ddsd2.dwFlags = DDSD_CAPS;
- ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpFront4, NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (primary) failed", hResult);
- goto cleanup_and_return_with_error;
- }
-
- // Cache the primary surface for persistant DirectDraw state
- if (glb.bDirectDrawPersistant && !glb.bDirectDrawPrimary) {
- glb.lpPrimary4 = dgl->lpFront4;
- IDirectDrawSurface4_AddRef(glb.lpPrimary4);
- glb.bDirectDrawPrimary = TRUE;
- }
-
- // Clipper object
- hResult = DirectDrawCreateClipper(0, &lpddClipper, NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateClipper failed", hResult);
- goto cleanup_and_return_with_error;
- }
- hResult = IDirectDrawClipper_SetHWnd(lpddClipper, 0, dgl->hWnd);
- if (FAILED(hResult)) {
- RELEASE(lpddClipper);
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetHWnd failed", hResult);
- goto cleanup_and_return_with_error;
- }
- hResult = IDirectDrawSurface4_SetClipper(dgl->lpFront4, lpddClipper);
- RELEASE(lpddClipper); // We have finished with it.
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetClipper failed", hResult);
- goto cleanup_and_return_with_error;
- }
-DoClipperOnly:
- // Update the window for the original clipper
- if ((glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) || bSaveDesktop) {
- IDirectDrawSurface4_GetClipper(dgl->lpFront4, &lpddClipper);
- IDirectDrawClipper_SetHWnd(lpddClipper, 0, dgl->hWnd);
- RELEASE(lpddClipper);
- }
-
- if (dgl->bDoubleBuffer) {
- // Render target surface
- ZeroMemory(&ddsd2, sizeof(ddsd2));
- ddsd2.dwSize = sizeof(ddsd2);
- ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd2.dwWidth = dgl->dwWidth;
- ddsd2.dwHeight = dgl->dwHeight;
- ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE |
- DDSCAPS_OFFSCREENPLAIN |
- dwMemoryType;
- hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpBack4, NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Create Backbuffer failed", hResult);
- goto cleanup_and_return_with_error;
- }
-
- } else {
- dgl->lpBack4 = NULL;
- }
- }
-
- //
- // Now create the Zbuffer
- //
- if (dgl->bDepthBuffer) {
- // Get z-buffer dimensions from the render target
- // Setup the surface desc for the z-buffer.
- ZeroMemory(&ddsd2, sizeof(ddsd2));
- ddsd2.dwSize = sizeof(ddsd2);
- ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
- ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | dwMemoryType;
- ddsd2.dwWidth = dgl->dwWidth;
- ddsd2.dwHeight = dgl->dwHeight;
- memcpy(&ddsd2.ddpfPixelFormat,
- &glb.lpZBufferPF[dgl->iZBufferPF],
- sizeof(DDPIXELFORMAT) );
-
- // Create a z-buffer
- hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpDepth4, NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (ZBuffer) failed", hResult);
- goto cleanup_and_return_with_error;
- }
-
- // Attach Zbuffer to render target
- TRY(IDirectDrawSurface4_AddAttachedSurface(
- dgl->bDoubleBuffer ? dgl->lpBack4 : dgl->lpFront4,
- dgl->lpDepth4),
- "dglResize: Attach Zbuffer");
-
- }
-
- // Clear the newly resized back buffers for the window client area.
- ZeroMemory(&ddbltfx, sizeof(ddbltfx));
- ddbltfx.dwSize = sizeof(ddbltfx);
- ddbltfx.dwFillColor = dgl->dwClearColorPF;
- IDirectDrawSurface4_Blt(dgl->lpBack4, &rcScreenRect, NULL, NULL,
- DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
-
- //
- // Now that we have a zbuffer we can create the 3D device
- //
- hResult = IDirect3D3_CreateDevice(dgl->lpD3D3,
- bDefaultDriver ? &glb.d3dGuid : &IID_IDirect3DRGBDevice,
- dgl->bDoubleBuffer ? dgl->lpBack4 : dgl->lpFront4,
- &dgl->lpDev3,
- NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Could not create Direct3D device", hResult);
- goto cleanup_and_return_with_error;
- }
-
- // We must do this as soon as the device is created
- dglInitStateCaches(dgl);
-
- //
- // Viewport
- //
- hResult = IDirect3DDevice3_AddViewport(dgl->lpDev3, dgl->lpViewport3);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: AddViewport failed", hResult);
- goto cleanup_and_return_with_error;
- }
-
- // Initialise the viewport
- dgl->d3dViewport.dwSize = sizeof(dgl->d3dViewport);
- dgl->d3dViewport.dwX = 0;
- dgl->d3dViewport.dwY = 0;
- dgl->d3dViewport.dwWidth = dgl->dwWidth;
- dgl->d3dViewport.dwHeight = dgl->dwHeight;
- dgl->d3dViewport.dvClipX = 0;
- dgl->d3dViewport.dvClipY = 0;
- dgl->d3dViewport.dvClipWidth = dgl->dwWidth;
- dgl->d3dViewport.dvClipHeight = dgl->dwHeight;
-// dgl->d3dViewport.dvMinZ = 0.0f;
-// dgl->d3dViewport.dvMaxZ = 1.0f;
- TRY(IDirect3DViewport3_SetViewport2(dgl->lpViewport3, &dgl->d3dViewport),
- "dglResize: SetViewport2");
-
- hResult = IDirect3DDevice3_SetCurrentViewport(dgl->lpDev3, dgl->lpViewport3);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetCurrentViewport failed", hResult);
- goto cleanup_and_return_with_error;
- }
-
- // (Re)Initialise all the Direct3D renderstates
- dglInitStateD3D(ctx);
-
- // Now we have to recreate all of our textures (+ mipmaps).
- // Walk over all textures in hash table
- // XXX what about the default texture objects (id=0)?
- {
- struct _mesa_HashTable *textures = ctx->Shared->TexObjects;
- GLuint id;
- for (id = _mesa_HashFirstEntry(textures);
- id;
- id = _mesa_HashNextEntry(textures, id)) {
- tObj = (struct gl_texture_object *) _mesa_HashLookup(textures, id);
- if (tObj->DriverData) {
- // We could call our TexImage function directly, but it's
- // safer to use the driver pointer.
- for (i=0; i<MAX_TEXTURE_LEVELS; i++) {
- image = tObj->Image[i];
- if (image) {
- switch (tObj->Dimensions){
- case 1:
- if (ctx->Driver.TexImage)
- (*ctx->Driver.TexImage)(ctx, GL_TEXTURE_1D, tObj, i, image->Format, image);
- break;
- case 2:
- if (ctx->Driver.TexImage)
- (*ctx->Driver.TexImage)(ctx, GL_TEXTURE_2D, tObj, i, image->Format, image);
- break;
- default:
- break;
- }
- }
- }
- }
- }
- }
-
- // Re-Bind each texture Unit
- for (i=0; i<glb.wMaxSimultaneousTextures; i++) {
- tObj = ctx->Texture.Unit[i].Current;
- if (tObj) {
- DGL_texture *lpTex = (DGL_texture *)tObj->DriverData;
- hResult = dglSetTexture(dgl, i, lpTex ? lpTex->lpTexture : NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_ERROR, "dglResize: SetTexture failed", hResult);
- }
- }
- }
-#endif // _USE_GLD3_WGL
-
- dgl->bCanRender = TRUE;
-
-#ifdef GLD_THREADS
- // Release serialized access
- if (glb.bMultiThreaded)
- LeaveCriticalSection(&CriticalSection);
-#endif
-
- // SUCCESS.
- return TRUE;
-
-cleanup_and_return_with_error:
- // Relase all interfaces before returning.
-#ifdef _USE_GLD3_WGL
- _gldDriver.DestroyDrawable(dgl);
-#else // _USE_GLD3_WGL
- RELEASE(dgl->lpDev3);
- RELEASE(dgl->lpDepth4);
- RELEASE(dgl->lpBack4);
- if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary)
- ;
- else
- RELEASE(dgl->lpFront4);
-
-#undef DDLOG_CRITICAL_OR_WARN
-#endif // _USE_GLD3_WGL
-
- // Mark context as not being able to render
- dgl->bCanRender = FALSE;
-
-#ifdef GLD_THREADS
- // Release serialized access
- if (glb.bMultiThreaded)
- LeaveCriticalSection(&CriticalSection);
-#endif
-
- return FALSE;
-}
-
-// ***********************************************************************
-// ***********************************************************************
-// Support for bitmap fonts.
-// ***********************************************************************
-// ***********************************************************************
-
-/*****************************************************************************
-**
-** InvertGlyphBitmap.
-**
-** Invert the bitmap so that it suits OpenGL's representation.
-** Each row starts on a double word boundary.
-**
-*****************************************************************************/
-
-static void InvertGlyphBitmap(
- int w,
- int h,
- DWORD *fptr,
- DWORD *tptr)
-{
- int dWordsInRow = (w+31)/32;
- int i, j;
- DWORD *tmp = tptr;
-
- if (w <= 0 || h <= 0) {
- return;
- }
-
- tptr += ((h-1)*dWordsInRow);
- for (i = 0; i < h; i++) {
- for (j = 0; j < dWordsInRow; j++) {
- *(tptr + j) = *(fptr + j);
- }
- tptr -= dWordsInRow;
- fptr += dWordsInRow;
- }
-}
-
-// ***********************************************************************
-
-/*****************************************************************************
- * wglUseFontBitmaps
- *
- * Converts a subrange of the glyphs in a GDI font to OpenGL display
- * lists.
- *
- * Extended to support any GDI font, not just TrueType fonts. (DaveM)
- *
- *****************************************************************************/
-
-BOOL APIENTRY _GLD_WGL_EXPORT(UseFontBitmapsA)(
- HDC hDC,
- DWORD first,
- DWORD count,
- DWORD listBase)
-{
- int i, ox, oy, ix, iy;
- int w, h;
- int iBufSize, iCurBufSize = 0;
- DWORD *bitmapBuffer = NULL;
- DWORD *invertedBitmapBuffer = NULL;
- BOOL bSuccessOrFail = TRUE;
- BOOL bTrueType = FALSE;
- TEXTMETRIC tm;
- GLYPHMETRICS gm;
- RASTERIZER_STATUS rs;
- MAT2 mat;
- SIZE size;
- RECT rect;
- HDC hDCMem;
- HBITMAP hBitmap;
- BITMAPINFO bmi;
- HFONT hFont;
-
- // Validate SciTech DirectGL license
- if (!dglValidate())
- return FALSE;
-
- // Set up a unity matrix.
- ZeroMemory(&mat, sizeof(mat));
- mat.eM11.value = 1;
- mat.eM22.value = 1;
-
- // Test to see if selected font is TrueType or not
- ZeroMemory(&tm, sizeof(tm));
- if (!GetTextMetrics(hDC, &tm)) {
- ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Font metrics error\n");
- return (FALSE);
- }
- bTrueType = (tm.tmPitchAndFamily & TMPF_TRUETYPE) ? TRUE : FALSE;
-
- // Test to see if TRUE-TYPE capabilities are installed
- // (only necessary if TrueType font selected)
- ZeroMemory(&rs, sizeof(rs));
- if (bTrueType) {
- if (!GetRasterizerCaps (&rs, sizeof (RASTERIZER_STATUS))) {
- ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Raster caps error\n");
- return (FALSE);
- }
- if (!(rs.wFlags & TT_ENABLED)) {
- ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: No TrueType caps\n");
- return (FALSE);
- }
- }
-
- // Trick to get the current font handle
- hFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
- SelectObject(hDC, hFont);
-
- // Have memory device context available for holding bitmaps of font glyphs
- hDCMem = CreateCompatibleDC(hDC);
- SelectObject(hDCMem, hFont);
- SetTextColor(hDCMem, RGB(0xFF, 0xFF, 0xFF));
- SetBkColor(hDCMem, 0);
-
- for (i = first; (DWORD) i < (first + count); i++) {
- // Find out how much space is needed for the bitmap so we can
- // Set the buffer size correctly.
- if (bTrueType) {
- // Use TrueType support to get bitmap size of glyph
- iBufSize = GetGlyphOutline(hDC, i, GGO_BITMAP, &gm,
- 0, NULL, &mat);
- if (iBufSize == GDI_ERROR) {
- bSuccessOrFail = FALSE;
- break;
- }
- }
- else {
- // Use generic GDI support to compute bitmap size of glyph
- w = tm.tmMaxCharWidth;
- h = tm.tmHeight;
- if (GetTextExtentPoint32(hDC, (LPCTSTR)&i, 1, &size)) {
- w = size.cx;
- h = size.cy;
- }
- iBufSize = w * h;
- // Use DWORD multiple for compatibility
- iBufSize += 3;
- iBufSize /= 4;
- iBufSize *= 4;
- }
-
- // If we need to allocate Larger Buffers, then do so - but allocate
- // An extra 50 % so that we don't do too many mallocs !
- if (iBufSize > iCurBufSize) {
- if (bitmapBuffer) {
- __wglFree(bitmapBuffer);
- }
- if (invertedBitmapBuffer) {
- __wglFree(invertedBitmapBuffer);
- }
-
- iCurBufSize = iBufSize * 2;
- bitmapBuffer = (DWORD *) __wglMalloc(iCurBufSize);
- invertedBitmapBuffer = (DWORD *) __wglMalloc(iCurBufSize);
-
- if (bitmapBuffer == NULL || invertedBitmapBuffer == NULL) {
- bSuccessOrFail = FALSE;
- break;
- }
- }
-
- // If we fail to get the Glyph data, delete the display lists
- // Created so far and return FALSE.
- if (bTrueType) {
- // Use TrueType support to get bitmap of glyph
- if (GetGlyphOutline(hDC, i, GGO_BITMAP, &gm,
- iBufSize, bitmapBuffer, &mat) == GDI_ERROR) {
- bSuccessOrFail = FALSE;
- break;
- }
-
- // Setup glBitmap parameters for current font glyph
- w = gm.gmBlackBoxX;
- h = gm.gmBlackBoxY;
- ox = gm.gmptGlyphOrigin.x;
- oy = gm.gmptGlyphOrigin.y;
- ix = gm.gmCellIncX;
- iy = gm.gmCellIncY;
- }
- else {
- // Use generic GDI support to create bitmap of glyph
- ZeroMemory(bitmapBuffer, iBufSize);
-
- if (i >= tm.tmFirstChar && i <= tm.tmLastChar) {
- // Only create bitmaps for actual font glyphs
- hBitmap = CreateBitmap(w, h, 1, 1, NULL);
- SelectObject(hDCMem, hBitmap);
- // Make bitmap of current font glyph
- SetRect(&rect, 0, 0, w, h);
- DrawText(hDCMem, (LPCTSTR)&i, 1, &rect,
- DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_NOCLIP);
- // Make copy of bitmap in our local buffer
- ZeroMemory(&bmi, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = w;
- bmi.bmiHeader.biHeight = -h;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 1;
- bmi.bmiHeader.biCompression = BI_RGB;
- GetDIBits(hDCMem, hBitmap, 0, h, bitmapBuffer, &bmi, 0);
- DeleteObject(hBitmap);
- }
- else {
- // Otherwise use empty display list for non-existing glyph
- iBufSize = 0;
- }
-
- // Setup glBitmap parameters for current font glyph
- ox = 0;
- oy = tm.tmDescent;
- ix = w;
- iy = 0;
- }
-
- // Create an OpenGL display list.
- _GLD_glNewList((listBase + i), GL_COMPILE);
-
- // Some fonts have no data for the space character, yet advertise
- // a non-zero size.
- if (0 == iBufSize) {
- _GLD_glBitmap(0, 0, 0.0f, 0.0f, (GLfloat) ix, (GLfloat) iy, NULL);
- } else {
- // Invert the Glyph data.
- InvertGlyphBitmap(w, h, bitmapBuffer, invertedBitmapBuffer);
-
- // Render an OpenGL bitmap and invert the origin.
- _GLD_glBitmap(w, h,
- (GLfloat) ox, (GLfloat) (h-oy),
- (GLfloat) ix, (GLfloat) iy,
- (GLubyte *) invertedBitmapBuffer);
- }
-
- // Close this display list.
- _GLD_glEndList();
- }
-
- if (bSuccessOrFail == FALSE) {
- ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Get glyph failed\n");
- _GLD_glDeleteLists((i+listBase), (i-first));
- }
-
- // Release resources used
- DeleteObject(hFont);
- DeleteDC(hDCMem);
-
- if (bitmapBuffer)
- __wglFree(bitmapBuffer);
- if (invertedBitmapBuffer)
- __wglFree(invertedBitmapBuffer);
-
- return(bSuccessOrFail);
-}
-
-// ***********************************************************************
-
-BOOL APIENTRY _GLD_WGL_EXPORT(UseFontBitmapsW)(
- HDC a,
- DWORD b,
- DWORD c,
- DWORD d)
-{
- // Validate license
- if (!dglValidate())
- return FALSE;
-
- return _GLD_WGL_EXPORT(UseFontBitmapsA)(a, b, c, d);
-}
-
-// ***********************************************************************
-// ***********************************************************************
-// Support for outline TrueType fonts.
-// ***********************************************************************
-// ***********************************************************************
-
-void * __wglRealloc(
- void *oldPtr,
- size_t newSize)
-{
- void *newPtr = NULL;
-
- if (newSize != 0) {
- newPtr = (void *) GlobalAlloc(GPTR, newSize);
- if (oldPtr && newPtr) {
- DWORD oldSize = GlobalSize(oldPtr);
-
- memcpy(newPtr, oldPtr, (oldSize <= newSize ? oldSize : newSize));
- GlobalFree(oldPtr);
- }
- } else if (oldPtr) {
- GlobalFree(oldPtr);
- }
- if (newPtr == NULL) {
- return NULL; /* XXX out of memory error */
- }
- return newPtr;
-}
-
-// ***********************************************************************
-
-
-/*****************************************************************************
- * wglUseFontOutlinesW
- *
- * Converts a subrange of the glyphs in a TrueType font to OpenGL display
- * lists.
- *****************************************************************************/
-
-BOOL APIENTRY _GLD_WGL_EXPORT(UseFontOutlinesW)(
- IN HDC hDC,
- IN DWORD first,
- IN DWORD count,
- IN DWORD listBase,
- IN FLOAT chordalDeviation,
- IN FLOAT extrusion,
- IN INT format,
- OUT LPGLYPHMETRICSFLOAT lpgmf)
-{
- return _GLD_WGL_EXPORT(UseFontOutlinesA)(hDC, first, count, listBase,
- chordalDeviation, extrusion, format, lpgmf);
-}
-
-/*****************************************************************************
- * wglUseFontOutlinesA
- *
- * Converts a subrange of the glyphs in a TrueType font to OpenGL display
- * lists.
- *****************************************************************************/
-
-BOOL APIENTRY _GLD_WGL_EXPORT(UseFontOutlinesA)(
- IN HDC hDC,
- IN DWORD first,
- IN DWORD count,
- IN DWORD listBase,
- IN FLOAT chordalDeviation,
- IN FLOAT extrusion,
- IN INT format,
- OUT LPGLYPHMETRICSFLOAT glyphMetricsFloatArray)
- {
- DWORD glyphIndex;
- UCHAR* glyphBuf;
- DWORD glyphBufSize;
-
-
- /*
- * Flush any previous OpenGL errors. This allows us to check for
- * new errors so they can be reported via the function return value.
- */
- while (_GLD_glGetError() != GL_NO_ERROR)
- ;
-
- /*
- * Make sure that the current font can be sampled accurately.
- */
- hNewFont = CreateHighResolutionFont(hDC);
- if (!hNewFont)
- return FALSE;
-
- hOldFont = SelectObject(hDC, hNewFont);
- if (!hOldFont)
- return FALSE;
-
- /*
- * Preallocate a buffer for the outline data, and track its size:
- */
- glyphBuf = (UCHAR*) __wglMalloc(glyphBufSize = 10240);
- if (!glyphBuf)
- return FALSE; /*WGL_STATUS_NOT_ENOUGH_MEMORY*/
-
- /*
- * Process each glyph in the given range:
- */
- for (glyphIndex = first; glyphIndex - first < count; ++glyphIndex)
- {
- GLYPHMETRICS glyphMetrics;
- DWORD glyphSize;
- static MAT2 matrix =
- {
- {0, 1}, {0, 0},
- {0, 0}, {0, 1}
- };
- LPGLYPHMETRICSFLOAT glyphMetricsFloat =
- &glyphMetricsFloatArray[glyphIndex - first];
-
-
- /*
- * Determine how much space is needed to store the glyph's
- * outlines. If our glyph buffer isn't large enough,
- * resize it.
- */
- glyphSize = GetGlyphOutline( hDC,
- glyphIndex,
- GGO_NATIVE,
- &glyphMetrics,
- 0,
- NULL,
- &matrix
- );
- if (glyphSize < 0)
- return FALSE; /*WGL_STATUS_FAILURE*/
- if (glyphSize > glyphBufSize)
- {
- __wglFree(glyphBuf);
- glyphBuf = (UCHAR*) __wglMalloc(glyphBufSize = glyphSize);
- if (!glyphBuf)
- return FALSE; /*WGL_STATUS_NOT_ENOUGH_MEMORY*/
- }
-
-
- /*
- * Get the glyph's outlines.
- */
- if (GetGlyphOutline( hDC,
- glyphIndex,
- GGO_NATIVE,
- &glyphMetrics,
- glyphBufSize,
- glyphBuf,
- &matrix
- ) < 0)
- {
- __wglFree(glyphBuf);
- return FALSE; /*WGL_STATUS_FAILURE*/
- }
-
- glyphMetricsFloat->gmfBlackBoxX =
- (FLOAT) glyphMetrics.gmBlackBoxX * ScaleFactor;
- glyphMetricsFloat->gmfBlackBoxY =
- (FLOAT) glyphMetrics.gmBlackBoxY * ScaleFactor;
- glyphMetricsFloat->gmfptGlyphOrigin.x =
- (FLOAT) glyphMetrics.gmptGlyphOrigin.x * ScaleFactor;
- glyphMetricsFloat->gmfptGlyphOrigin.y =
- (FLOAT) glyphMetrics.gmptGlyphOrigin.y * ScaleFactor;
- glyphMetricsFloat->gmfCellIncX =
- (FLOAT) glyphMetrics.gmCellIncX * ScaleFactor;
- glyphMetricsFloat->gmfCellIncY =
- (FLOAT) glyphMetrics.gmCellIncY * ScaleFactor;
-
- /*
- * Turn the glyph into a display list:
- */
- if (!MakeDisplayListFromGlyph( (glyphIndex - first) + listBase,
- glyphBuf,
- glyphSize,
- glyphMetricsFloat,
- chordalDeviation + ScaleFactor,
- extrusion,
- format))
- {
- __wglFree(glyphBuf);
- return FALSE; /*WGL_STATUS_FAILURE*/
- }
- }
-
-
- /*
- * Clean up temporary storage and return. If an error occurred,
- * clear all OpenGL error flags and return FAILURE status;
- * otherwise just return SUCCESS.
- */
- __wglFree(glyphBuf);
-
- SelectObject(hDC, hOldFont);
-
- if (_GLD_glGetError() == GL_NO_ERROR)
- return TRUE; /*WGL_STATUS_SUCCESS*/
- else
- {
- while (_GLD_glGetError() != GL_NO_ERROR)
- ;
- return FALSE; /*WGL_STATUS_FAILURE*/
- }
- }
-
-
-
-/*****************************************************************************
- * CreateHighResolutionFont
- *
- * Gets metrics for the current font and creates an equivalent font
- * scaled to the design units of the font.
- *
- *****************************************************************************/
-
-static HFONT
-CreateHighResolutionFont(HDC hDC)
- {
- UINT otmSize;
- OUTLINETEXTMETRIC *otm;
- LONG fontHeight, fontWidth, fontUnits;
- LOGFONT logFont;
-
- otmSize = GetOutlineTextMetrics(hDC, 0, NULL);
- if (otmSize == 0)
- return NULL;
-
- otm = (OUTLINETEXTMETRIC *) __wglMalloc(otmSize);
- if (otm == NULL)
- return NULL;
-
- otm->otmSize = otmSize;
- if (GetOutlineTextMetrics(hDC, otmSize, otm) == 0)
- return NULL;
-
- fontHeight = otm->otmTextMetrics.tmHeight -
- otm->otmTextMetrics.tmInternalLeading;
- fontWidth = otm->otmTextMetrics.tmAveCharWidth;
- fontUnits = (LONG) otm->otmEMSquare;
-
- ScaleFactor = 1.0F / (FLOAT) fontUnits;
-
- logFont.lfHeight = - ((LONG) fontUnits);
- logFont.lfWidth = (LONG)
- ((FLOAT) (fontWidth * fontUnits) / (FLOAT) fontHeight);
- logFont.lfEscapement = 0;
- logFont.lfOrientation = 0;
- logFont.lfWeight = otm->otmTextMetrics.tmWeight;
- logFont.lfItalic = otm->otmTextMetrics.tmItalic;
- logFont.lfUnderline = otm->otmTextMetrics.tmUnderlined;
- logFont.lfStrikeOut = otm->otmTextMetrics.tmStruckOut;
- logFont.lfCharSet = otm->otmTextMetrics.tmCharSet;
- logFont.lfOutPrecision = OUT_OUTLINE_PRECIS;
- logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
- logFont.lfQuality = DEFAULT_QUALITY;
- logFont.lfPitchAndFamily =
- otm->otmTextMetrics.tmPitchAndFamily & 0xf0;
- strcpy(logFont.lfFaceName,
- (char *)otm + (int)otm->otmpFaceName);
-
- hNewFont = CreateFontIndirect(&logFont);
- if (hNewFont == NULL)
- return NULL;
-
- __wglFree(otm);
-
- return hNewFont;
- }
-
-
-
-/*****************************************************************************
- * MakeDisplayListFromGlyph
- *
- * Converts the outline of a glyph to an OpenGL display list.
- *
- * Return value is nonzero for success, zero for failure.
- *
- * Does not check for OpenGL errors, so if the caller needs to know about them,
- * it should call glGetError().
- *****************************************************************************/
-
-static int
-MakeDisplayListFromGlyph( IN DWORD listName,
- IN UCHAR* glyphBuf,
- IN DWORD glyphSize,
- IN LPGLYPHMETRICSFLOAT glyphMetricsFloat,
- IN FLOAT chordalDeviation,
- IN FLOAT extrusion,
- IN INT format)
- {
- int status;
-
- _GLD_glNewList(listName, GL_COMPILE);
- status = DrawGlyph( glyphBuf,
- glyphSize,
- chordalDeviation,
- extrusion,
- format);
-
- _GLD_glTranslatef(glyphMetricsFloat->gmfCellIncX,
- glyphMetricsFloat->gmfCellIncY,
- 0.0F);
- _GLD_glEndList();
-
- return status;
- }
-
-
-
-/*****************************************************************************
- * DrawGlyph
- *
- * Converts the outline of a glyph to OpenGL drawing primitives, tessellating
- * as needed, and then draws the glyph. Tessellation of the quadratic splines
- * in the outline is controlled by "chordalDeviation", and the drawing
- * primitives (lines or polygons) are selected by "format".
- *
- * Return value is nonzero for success, zero for failure.
- *
- * Does not check for OpenGL errors, so if the caller needs to know about them,
- * it should call glGetError().
- *****************************************************************************/
-
-static int
-DrawGlyph( IN UCHAR* glyphBuf,
- IN DWORD glyphSize,
- IN FLOAT chordalDeviation,
- IN FLOAT extrusion,
- IN INT format)
- {
- INT status = 0;
- FLOAT* p;
- DWORD loop;
- DWORD point;
- GLUtesselator* tess = NULL;
-
-
- /*
- * Initialize the global buffer into which we place the outlines:
- */
- if (!InitLineBuf())
- goto exit;
-
-
- /*
- * Convert the glyph outlines to a set of polyline loops.
- * (See MakeLinesFromGlyph() for the format of the loop data
- * structure.)
- */
- if (!MakeLinesFromGlyph(glyphBuf, glyphSize, chordalDeviation))
- goto exit;
- p = LineBuf;
-
-
- /*
- * Now draw the loops in the appropriate format:
- */
- if (format == WGL_FONT_LINES)
- {
- /*
- * This is the easy case. Just draw the outlines.
- */
- for (loop = (DWORD) *p++; loop; --loop)
- {
- _GLD_glBegin(GL_LINE_LOOP);
- for (point = (DWORD) *p++; point; --point)
- {
- _GLD_glVertex2fv(p);
- p += 2;
- }
- _GLD_glEnd();
- }
- status = 1;
- }
-
- else if (format == WGL_FONT_POLYGONS)
- {
- double v[3];
- FLOAT *save_p = p;
- GLfloat z_value;
-
- /*
- * This is the hard case. We have to set up a tessellator
- * to convert the outlines into a set of polygonal
- * primitives, which the tessellator passes to some
- * auxiliary routines for drawing.
- */
- if (!LoadGLUTesselator())
- goto exit;
- if (!InitVertBuf())
- goto exit;
- if (!(tess = gluNewTessProc()))
- goto exit;
- gluTessCallbackProc(tess, GLU_BEGIN, (void(CALLBACK *)()) _GLD_glBegin);
- gluTessCallbackProc(tess, GLU_TESS_VERTEX_DATA,
- (void(CALLBACK *)()) TessVertexOutData);
- gluTessCallbackProc(tess, GLU_END, (void(CALLBACK *)()) _GLD_glEnd);
- gluTessCallbackProc(tess, GLU_ERROR, (void(CALLBACK *)()) TessError);
- gluTessCallbackProc(tess, GLU_TESS_COMBINE, (void(CALLBACK *)()) TessCombine);
- gluTessNormalProc(tess, 0.0F, 0.0F, 1.0F);
-
- TessErrorOccurred = 0;
- _GLD_glNormal3f(0.0f, 0.0f, 1.0f);
- v[2] = 0.0;
- z_value = 0.0f;
-
- gluTessBeginPolygonProc(tess, (void *)*(int *)&z_value);
- for (loop = (DWORD) *p++; loop; --loop)
- {
- gluTessBeginContourProc(tess);
-
- for (point = (DWORD) *p++; point; --point)
- {
- v[0] = p[0];
- v[1] = p[1];
- gluTessVertexProc(tess, v, p);
- p += 2;
- }
-
- gluTessEndContourProc(tess);
- }
- gluTessEndPolygonProc(tess);
-
- status = !TessErrorOccurred;
-
- /* Extrusion code */
- if (extrusion) {
- DWORD loops;
- GLfloat thickness = (GLfloat) -extrusion;
- FLOAT *vert, *vert2;
- DWORD count;
-
- p = save_p;
- loops = (DWORD) *p++;
-
- for (loop = 0; loop < loops; loop++) {
- GLfloat dx, dy, len;
- DWORD last;
-
- count = (DWORD) *p++;
- _GLD_glBegin(GL_QUAD_STRIP);
-
- /* Check if the first and last vertex are identical
- * so we don't draw the same quad twice.
- */
- vert = p + (count-1)*2;
- last = (p[0] == vert[0] && p[1] == vert[1]) ? count-1 : count;
-
- for (point = 0; point <= last; point++) {
- vert = p + 2 * (point % last);
- vert2 = p + 2 * ((point+1) % last);
-
- dx = vert[0] - vert2[0];
- dy = vert[1] - vert2[1];
- len = (GLfloat)sqrt(dx * dx + dy * dy);
-
- _GLD_glNormal3f(dy / len, -dx / len, 0.0f);
- _GLD_glVertex3f((GLfloat) vert[0],
- (GLfloat) vert[1], thickness);
- _GLD_glVertex3f((GLfloat) vert[0],
- (GLfloat) vert[1], 0.0f);
- }
-
- _GLD_glEnd();
- p += count*2;
- }
-
- /* Draw the back face */
- p = save_p;
- v[2] = thickness;
- _GLD_glNormal3f(0.0f, 0.0f, -1.0f);
- gluTessNormalProc(tess, 0.0F, 0.0F, -1.0F);
-
- gluTessBeginPolygonProc(tess, (void *)*(int *)&thickness);
-
- for (loop = (DWORD) *p++; loop; --loop)
- {
- count = (DWORD) *p++;
-
- gluTessBeginContourProc(tess);
-
- for (point = 0; point < count; point++)
- {
- vert = p + ((count-point-1)<<1);
- v[0] = vert[0];
- v[1] = vert[1];
- gluTessVertexProc(tess, v, vert);
- }
- p += count*2;
-
- gluTessEndContourProc(tess);
- }
- gluTessEndPolygonProc(tess);
- }
-
-#if DEBUG
- if (TessErrorOccurred)
- printf("Tessellation error %s\n",
- gluErrorString(TessErrorOccurred));
-#endif
- }
-
-
-exit:
- FreeLineBuf();
- if (tess)
- gluDeleteTessProc(tess);
- // UnloadGLUTesselator();
- FreeVertBuf();
- return status;
- }
-
-
-
-/*****************************************************************************
- * LoadGLUTesselator
- *
- * Maps the glu32.dll module and gets function pointers for the
- * tesselator functions.
- *****************************************************************************/
-
-static BOOL
-LoadGLUTesselator(void)
- {
- if (gluModuleHandle != NULL)
- return TRUE;
-
- {
- extern HINSTANCE hInstanceOpenGL;
- char *gluName = "GLU32.DLL";
-// char name[256];
-// char *ptr;
-// int len;
-
-/*
- len = GetModuleFileName(hInstanceOpenGL, name, 255);
- if (len != 0)
- {
- ptr = name+len-1;
- while (ptr > name && *ptr != '\\')
- ptr--;
- if (*ptr == '\\')
- ptr++;
- if (!stricmp(ptr, "cosmogl.dll"))
- {
- gluName = "COSMOGLU.DLL";
- }
- else if (!stricmp(ptr, "opengl32.dll"))
- {
- gluName = "GLU32.DLL";
- }
- }
-*/
- if ((gluModuleHandle = LoadLibrary(gluName)) == NULL)
- return FALSE;
- }
-
- if ((gluNewTessProc = (gluNewTessProto)
- GetProcAddress(gluModuleHandle, "gluNewTess")) == NULL)
- return FALSE;
-
- if ((gluDeleteTessProc = (gluDeleteTessProto)
- GetProcAddress(gluModuleHandle, "gluDeleteTess")) == NULL)
- return FALSE;
-
- if ((gluTessBeginPolygonProc = (gluTessBeginPolygonProto)
- GetProcAddress(gluModuleHandle, "gluTessBeginPolygon")) == NULL)
- return FALSE;
-
- if ((gluTessBeginContourProc = (gluTessBeginContourProto)
- GetProcAddress(gluModuleHandle, "gluTessBeginContour")) == NULL)
- return FALSE;
-
- if ((gluTessVertexProc = (gluTessVertexProto)
- GetProcAddress(gluModuleHandle, "gluTessVertex")) == NULL)
- return FALSE;
-
- if ((gluTessEndContourProc = (gluTessEndContourProto)
- GetProcAddress(gluModuleHandle, "gluTessEndContour")) == NULL)
- return FALSE;
-
- if ((gluTessEndPolygonProc = (gluTessEndPolygonProto)
- GetProcAddress(gluModuleHandle, "gluTessEndPolygon")) == NULL)
- return FALSE;
-
- if ((gluTessPropertyProc = (gluTessPropertyProto)
- GetProcAddress(gluModuleHandle, "gluTessProperty")) == NULL)
- return FALSE;
-
- if ((gluTessNormalProc = (gluTessNormalProto)
- GetProcAddress(gluModuleHandle, "gluTessNormal")) == NULL)
- return FALSE;
-
- if ((gluTessCallbackProc = (gluTessCallbackProto)
- GetProcAddress(gluModuleHandle, "gluTessCallback")) == NULL)
- return FALSE;
-
- return TRUE;
- }
-
-
-
-/*****************************************************************************
- * UnloadGLUTesselator
- *
- * Unmaps the glu32.dll module.
- *****************************************************************************/
-
-static BOOL
-UnloadGLUTesselator(void)
- {
- if (gluModuleHandle != NULL)
- if (FreeLibrary(gluModuleHandle) == FALSE)
- return FALSE;
- gluModuleHandle = NULL;
- }
-
-
-
-/*****************************************************************************
- * TessVertexOut
- *
- * Used by tessellator to handle output vertexes.
- *****************************************************************************/
-
-static void CALLBACK
-TessVertexOut(FLOAT p[3])
- {
- GLfloat v[2];
-
- v[0] = p[0] * ScaleFactor;
- v[1] = p[1] * ScaleFactor;
- _GLD_glVertex2fv(v);
- }
-
-static void CALLBACK
-TessVertexOutData(FLOAT p[3], GLfloat z)
-{
- GLfloat v[3];
-
- v[0] = (GLfloat) p[0];
- v[1] = (GLfloat) p[1];
- v[2] = z;
- _GLD_glVertex3fv(v);
-}
-
-
-/*****************************************************************************
- * TessCombine
- *
- * Used by tessellator to handle self-intersecting contours and degenerate
- * geometry.
- *****************************************************************************/
-
-static void CALLBACK
-TessCombine(double coords[3],
- void* vertex_data[4],
- FLOAT weight[4],
- void** outData)
- {
- if (!AppendToVertBuf((FLOAT) coords[0])
- || !AppendToVertBuf((FLOAT) coords[1])
- || !AppendToVertBuf((FLOAT) coords[2]))
- TessErrorOccurred = GL_OUT_OF_MEMORY;
- *outData = VertBuf + (VertBufIndex - 3);
- }
-
-
-
-/*****************************************************************************
- * TessError
- *
- * Saves the last tessellator error code in the global TessErrorOccurred.
- *****************************************************************************/
-
-static void CALLBACK
-TessError(GLenum error)
- {
- TessErrorOccurred = error;
- }
-
-
-
-/*****************************************************************************
- * MakeLinesFromGlyph
- *
- * Converts the outline of a glyph from the TTPOLYGON format to a simple
- * array of floating-point values containing one or more loops.
- *
- * The first element of the output array is a count of the number of loops.
- * The loop data follows this count. Each loop consists of a count of the
- * number of vertices it contains, followed by the vertices. Each vertex
- * is an X and Y coordinate. For example, a single triangle might be
- * described by this array:
- *
- * 1., 3., 0., 0., 1., 0., 0., 1.
- * ^ ^ ^ ^ ^ ^ ^ ^
- * #loops #verts x1 y1 x2 y2 x3 y3
- *
- * A two-loop glyph would look like this:
- *
- * 2., 3., 0.,0., 1.,0., 0.,1., 3., .2,.2, .4,.2, .2,.4
- *
- * Line segments from the TTPOLYGON are transferred to the output array in
- * the obvious way. Quadratic splines in the TTPOLYGON are converted to
- * collections of line segments
- *****************************************************************************/
-
-static int
-MakeLinesFromGlyph(IN UCHAR* glyphBuf,
- IN DWORD glyphSize,
- IN FLOAT chordalDeviation)
- {
- UCHAR* p;
- int status = 0;
-
-
- /*
- * Pick up all the polygons (aka loops) that make up the glyph:
- */
- if (!AppendToLineBuf(0.0F)) /* loop count at LineBuf[0] */
- goto exit;
-
- p = glyphBuf;
- while (p < glyphBuf + glyphSize)
- {
- if (!MakeLinesFromTTPolygon(&p, chordalDeviation))
- goto exit;
- LineBuf[0] += 1.0F; /* increment loop count */
- }
-
- status = 1;
-
-exit:
- return status;
- }
-
-
-
-/*****************************************************************************
- * MakeLinesFromTTPolygon
- *
- * Converts a TTPOLYGONHEADER and its associated curve structures into a
- * single polyline loop in the global LineBuf.
- *****************************************************************************/
-
-static int
-MakeLinesFromTTPolygon( IN OUT UCHAR** pp,
- IN FLOAT chordalDeviation)
- {
- DWORD polySize;
- UCHAR* polyStart;
- DWORD vertexCountIndex;
-
- /*
- * Record where the polygon data begins, and where the loop's
- * vertex count resides:
- */
- polyStart = *pp;
- vertexCountIndex = LineBufIndex;
- if (!AppendToLineBuf(0.0F))
- return 0;
-
- /*
- * Extract relevant data from the TTPOLYGONHEADER:
- */
- polySize = GetDWord(pp);
- if (GetDWord(pp) != TT_POLYGON_TYPE) /* polygon type */
- return 0;
- if (!AppendToLineBuf((FLOAT) GetFixed(pp))) /* first X coord */
- return 0;
- if (!AppendToLineBuf((FLOAT) GetFixed(pp))) /* first Y coord */
- return 0;
- LineBuf[vertexCountIndex] += 1.0F;
-
- /*
- * Process each of the TTPOLYCURVE structures in the polygon:
- */
- while (*pp < polyStart + polySize)
- if (!MakeLinesFromTTPolycurve( pp,
- vertexCountIndex,
- chordalDeviation))
- return 0;
-
- return 1;
- }
-
-
-
-/*****************************************************************************
- * MakeLinesFromTTPolyCurve
- *
- * Converts the lines and splines in a single TTPOLYCURVE structure to points
- * in the global LineBuf.
- *****************************************************************************/
-
-static int
-MakeLinesFromTTPolycurve( IN OUT UCHAR** pp,
- IN DWORD vertexCountIndex,
- IN FLOAT chordalDeviation)
- {
- WORD type;
- WORD pointCount;
-
-
- /*
- * Pick up the relevant fields of the TTPOLYCURVE structure:
- */
- type = (WORD) GetWord(pp);
- pointCount = (WORD) GetWord(pp);
-
- /*
- * Convert the "curve" to line segments:
- */
- if (type == TT_PRIM_LINE)
- return MakeLinesFromTTLine( pp,
- vertexCountIndex,
- pointCount);
- else if (type == TT_PRIM_QSPLINE)
- return MakeLinesFromTTQSpline( pp,
- vertexCountIndex,
- pointCount,
- chordalDeviation);
- else
- return 0;
- }
-
-
-
-/*****************************************************************************
- * MakeLinesFromTTLine
- *
- * Converts points from the polyline in a TT_PRIM_LINE structure to
- * equivalent points in the global LineBuf.
- *****************************************************************************/
-static int
-MakeLinesFromTTLine( IN OUT UCHAR** pp,
- IN DWORD vertexCountIndex,
- IN WORD pointCount)
- {
- /*
- * Just copy the line segments into the line buffer (converting
- * type as we go):
- */
- LineBuf[vertexCountIndex] += pointCount;
- while (pointCount--)
- {
- if (!AppendToLineBuf((FLOAT) GetFixed(pp)) /* X coord */
- || !AppendToLineBuf((FLOAT) GetFixed(pp))) /* Y coord */
- return 0;
- }
-
- return 1;
- }
-
-
-
-/*****************************************************************************
- * MakeLinesFromTTQSpline
- *
- * Converts points from the poly quadratic spline in a TT_PRIM_QSPLINE
- * structure to polyline points in the global LineBuf.
- *****************************************************************************/
-
-static int
-MakeLinesFromTTQSpline( IN OUT UCHAR** pp,
- IN DWORD vertexCountIndex,
- IN WORD pointCount,
- IN FLOAT chordalDeviation)
- {
- FLOAT x0, y0, x1, y1, x2, y2;
- WORD point;
-
- /*
- * Process each of the non-interpolated points in the outline.
- * To do this, we need to generate two interpolated points (the
- * start and end of the arc) for each non-interpolated point.
- * The first interpolated point is always the one most recently
- * stored in LineBuf, so we just extract it from there. The
- * second interpolated point is either the average of the next
- * two points in the QSpline, or the last point in the QSpline
- * if only one remains.
- */
- for (point = 0; point < pointCount - 1; ++point)
- {
- x0 = LineBuf[LineBufIndex - 2];
- y0 = LineBuf[LineBufIndex - 1];
-
- x1 = (FLOAT) GetFixed(pp);
- y1 = (FLOAT) GetFixed(pp);
-
- if (point == pointCount - 2)
- {
- /*
- * This is the last arc in the QSpline. The final
- * point is the end of the arc.
- */
- x2 = (FLOAT) GetFixed(pp);
- y2 = (FLOAT) GetFixed(pp);
- }
- else
- {
- /*
- * Peek at the next point in the input to compute
- * the end of the arc:
- */
- x2 = 0.5F * (x1 + (FLOAT) GetFixed(pp));
- y2 = 0.5F * (y1 + (FLOAT) GetFixed(pp));
- /*
- * Push the point back onto the input so it will
- * be reused as the next off-curve point:
- */
- *pp -= 8;
- }
-
- if (!MakeLinesFromArc( x0, y0,
- x1, y1,
- x2, y2,
- vertexCountIndex,
- chordalDeviation * chordalDeviation))
- return 0;
- }
-
- return 1;
- }
-
-
-
-/*****************************************************************************
- * MakeLinesFromArc
- *
- * Subdivides one arc of a quadratic spline until the chordal deviation
- * tolerance requirement is met, then places the resulting set of line
- * segments in the global LineBuf.
- *****************************************************************************/
-
-static int
-MakeLinesFromArc( IN FLOAT x0,
- IN FLOAT y0,
- IN FLOAT x1,
- IN FLOAT y1,
- IN FLOAT x2,
- IN FLOAT y2,
- IN DWORD vertexCountIndex,
- IN FLOAT chordalDeviationSquared)
- {
- FLOAT x01;
- FLOAT y01;
- FLOAT x12;
- FLOAT y12;
- FLOAT midPointX;
- FLOAT midPointY;
- FLOAT deltaX;
- FLOAT deltaY;
-
- /*
- * Calculate midpoint of the curve by de Casteljau:
- */
- x01 = 0.5F * (x0 + x1);
- y01 = 0.5F * (y0 + y1);
- x12 = 0.5F * (x1 + x2);
- y12 = 0.5F * (y1 + y2);
- midPointX = 0.5F * (x01 + x12);
- midPointY = 0.5F * (y01 + y12);
-
-
- /*
- * Estimate chordal deviation by the distance from the midpoint
- * of the curve to its non-interpolated control point. If this
- * distance is greater than the specified chordal deviation
- * constraint, then subdivide. Otherwise, generate polylines
- * from the three control points.
- */
- deltaX = midPointX - x1;
- deltaY = midPointY - y1;
- if (deltaX * deltaX + deltaY * deltaY > chordalDeviationSquared)
- {
- MakeLinesFromArc( x0, y0,
- x01, y01,
- midPointX, midPointY,
- vertexCountIndex,
- chordalDeviationSquared);
-
- MakeLinesFromArc( midPointX, midPointY,
- x12, y12,
- x2, y2,
- vertexCountIndex,
- chordalDeviationSquared);
- }
- else
- {
- /*
- * The "pen" is already at (x0, y0), so we don't need to
- * add that point to the LineBuf.
- */
- if (!AppendToLineBuf(x1)
- || !AppendToLineBuf(y1)
- || !AppendToLineBuf(x2)
- || !AppendToLineBuf(y2))
- return 0;
- LineBuf[vertexCountIndex] += 2.0F;
- }
-
- return 1;
- }
-
-
-
-/*****************************************************************************
- * InitLineBuf
- *
- * Initializes the global LineBuf and its associated size and current-element
- * counters.
- *****************************************************************************/
-
-static int
-InitLineBuf(void)
- {
- if (!(LineBuf = (FLOAT*)
- __wglMalloc((LineBufSize = LINE_BUF_QUANT) * sizeof(FLOAT))))
- return 0;
- LineBufIndex = 0;
- return 1;
- }
-
-
-
-/*****************************************************************************
- * InitVertBuf
- *
- * Initializes the global VertBuf and its associated size and current-element
- * counters.
- *****************************************************************************/
-
-static int
-InitVertBuf(void)
- {
- if (!(VertBuf = (FLOAT*)
- __wglMalloc((VertBufSize = VERT_BUF_QUANT) * sizeof(FLOAT))))
- return 0;
- VertBufIndex = 0;
- return 1;
- }
-
-
-
-/*****************************************************************************
- * AppendToLineBuf
- *
- * Appends one floating-point value to the global LineBuf array. Return value
- * is non-zero for success, zero for failure.
- *****************************************************************************/
-
-static int
-AppendToLineBuf(FLOAT value)
- {
- if (LineBufIndex >= LineBufSize)
- {
- FLOAT* f;
-
- f = (FLOAT*) __wglRealloc(LineBuf,
- (LineBufSize += LINE_BUF_QUANT) * sizeof(FLOAT));
- if (!f)
- return 0;
- LineBuf = f;
- }
- LineBuf[LineBufIndex++] = value;
- return 1;
- }
-
-
-
-/*****************************************************************************
- * AppendToVertBuf
- *
- * Appends one floating-point value to the global VertBuf array. Return value
- * is non-zero for success, zero for failure.
- *
- * Note that we can't realloc this one, because the tessellator is using
- * pointers into it.
- *****************************************************************************/
-
-static int
-AppendToVertBuf(FLOAT value)
- {
- if (VertBufIndex >= VertBufSize)
- return 0;
- VertBuf[VertBufIndex++] = value;
- return 1;
- }
-
-
-
-/*****************************************************************************
- * FreeLineBuf
- *
- * Cleans up vertex buffer structure.
- *****************************************************************************/
-
-static void
-FreeLineBuf(void)
- {
- if (LineBuf)
- {
- __wglFree(LineBuf);
- LineBuf = NULL;
- }
- }
-
-
-
-/*****************************************************************************
- * FreeVertBuf
- *
- * Cleans up vertex buffer structure.
- *****************************************************************************/
-
-static void
-FreeVertBuf(void)
- {
- if (VertBuf)
- {
- __wglFree(VertBuf);
- VertBuf = NULL;
- }
- }
-
-
-
-/*****************************************************************************
- * GetWord
- *
- * Fetch the next 16-bit word from a little-endian byte stream, and increment
- * the stream pointer to the next unscanned byte.
- *****************************************************************************/
-
-static long GetWord(UCHAR** p)
- {
- long value;
-
- value = ((*p)[1] << 8) + (*p)[0];
- *p += 2;
- return value;
- }
-
-
-
-/*****************************************************************************
- * GetDWord
- *
- * Fetch the next 32-bit word from a little-endian byte stream, and increment
- * the stream pointer to the next unscanned byte.
- *****************************************************************************/
-
-static long GetDWord(UCHAR** p)
- {
- long value;
-
- value = ((*p)[3] << 24) + ((*p)[2] << 16) + ((*p)[1] << 8) + (*p)[0];
- *p += 4;
- return value;
- }
-
-
-
-
-/*****************************************************************************
- * GetFixed
- *
- * Fetch the next 32-bit fixed-point value from a little-endian byte stream,
- * convert it to floating-point, and increment the stream pointer to the next
- * unscanned byte.
- *****************************************************************************/
-
-static double GetFixed(
- UCHAR** p)
-{
- long hiBits, loBits;
- double value;
-
- loBits = GetWord(p);
- hiBits = GetWord(p);
- value = (double) ((hiBits << 16) | loBits) / 65536.0;
-
- return value * ScaleFactor;
-}
-
-// ***********************************************************************
-