diff options
author | marha <marha@users.sourceforge.net> | 2009-10-09 06:31:44 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2009-10-09 06:31:44 +0000 |
commit | 06456f5db88b434c3634ede42bdbfdce78fc4249 (patch) | |
tree | 97f5174e2d3da40faee7f2ad8858233da3d0166e /mesalib/src/mesa/drivers/windows/gldirect | |
parent | 7b230a3fe2d6c83488d9eec43067fe8ba8ac081b (diff) | |
parent | a0c4815433ccd57322f4f7703ca35e9ccfa59250 (diff) | |
download | vcxsrv-06456f5db88b434c3634ede42bdbfdce78fc4249.tar.gz vcxsrv-06456f5db88b434c3634ede42bdbfdce78fc4249.tar.bz2 vcxsrv-06456f5db88b434c3634ede42bdbfdce78fc4249.zip |
svn merge ^/branches/released . --username marha
Diffstat (limited to 'mesalib/src/mesa/drivers/windows/gldirect')
22 files changed, 9241 insertions, 0 deletions
diff --git a/mesalib/src/mesa/drivers/windows/gldirect/ddlog.c b/mesalib/src/mesa/drivers/windows/gldirect/ddlog.c new file mode 100644 index 000000000..4ae79e2fd --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/ddlog.c @@ -0,0 +1,192 @@ +/**************************************************************************** +* +* 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: Logging functions. +* +****************************************************************************/ + +#define STRICT +#include <windows.h> + +#include "ddlog.h" +#include "gld_driver.h" + +// *********************************************************************** + +static char ddlogbuf[256]; +static FILE* fpDDLog = NULL; // Log file pointer +static char szDDLogName[_MAX_PATH] = {"gldirect.log"}; // Filename of the log +static DDLOG_loggingMethodType ddlogLoggingMethod = DDLOG_NONE; // Default to No Logging +static DDLOG_severityType ddlogDebugLevel; +static BOOL bUIWarning = FALSE; // MessageBox warning ? + +// *********************************************************************** + +void ddlogOpen( + DDLOG_loggingMethodType LoggingMethod, + DDLOG_severityType Severity) +{ + if (fpDDLog != NULL) { + // Tried to re-open the log + ddlogMessage(DDLOG_WARN, "Tried to re-open the log file\n"); + return; + } + + ddlogLoggingMethod = LoggingMethod; + ddlogDebugLevel = Severity; + + if (ddlogLoggingMethod == DDLOG_NORMAL) { + fpDDLog = fopen(szDDLogName, "wt"); + if (fpDDLog == NULL) + return; + } + + ddlogMessage(DDLOG_SYSTEM, "\n"); + ddlogMessage(DDLOG_SYSTEM, "-> Logging Started\n"); +} + +// *********************************************************************** + +void ddlogClose() +{ + // Determine whether the log is already closed + if (fpDDLog == NULL && ddlogLoggingMethod == DDLOG_NORMAL) + return; // Nothing to do. + + ddlogMessage(DDLOG_SYSTEM, "<- Logging Ended\n"); + + if (ddlogLoggingMethod == DDLOG_NORMAL) { + fclose(fpDDLog); + fpDDLog = NULL; + } +} + +// *********************************************************************** + +void ddlogMessage( + DDLOG_severityType severity, + LPSTR message) +{ + char buf[256]; + + // Bail if logging is disabled + if (ddlogLoggingMethod == DDLOG_NONE) + return; + + if (ddlogLoggingMethod == DDLOG_CRASHPROOF) + fpDDLog = fopen(szDDLogName, "at"); + + if (fpDDLog == NULL) + return; + + if (severity >= ddlogDebugLevel) { + sprintf(buf, "DDLog: (%s) %s", ddlogSeverityMessages[severity], message); + fputs(buf, fpDDLog); // Write string to file + OutputDebugString(buf); // Echo to debugger + } + + if (ddlogLoggingMethod == DDLOG_CRASHPROOF) { + fflush(fpDDLog); // Write info to disk + fclose(fpDDLog); + fpDDLog = NULL; + } + + // Popup message box if critical error + if (bUIWarning && severity == DDLOG_CRITICAL) { + MessageBox(NULL, buf, "GLDirect", MB_OK | MB_ICONWARNING | MB_TASKMODAL); + } +} + +// *********************************************************************** + +// Write a string value to the log file +void ddlogError( + DDLOG_severityType severity, + LPSTR message, + HRESULT hResult) +{ +#ifdef _USE_GLD3_WGL + char dxErrStr[1024]; + _gldDriver.GetDXErrorString(hResult, &dxErrStr[0], sizeof(dxErrStr)); + if (FAILED(hResult)) { + sprintf(ddlogbuf, "DDLog: %s %8x:[ %s ]\n", message, hResult, dxErrStr); + } else + sprintf(ddlogbuf, "DDLog: %s\n", message); +#else + if (FAILED(hResult)) { + sprintf(ddlogbuf, "DDLog: %s %8x:[ %s ]\n", message, hResult, DDErrorToString(hResult)); + } else + sprintf(ddlogbuf, "DDLog: %s\n", message); +#endif + ddlogMessage(severity, ddlogbuf); +} + +// *********************************************************************** + +void ddlogPrintf( + DDLOG_severityType severity, + LPSTR message, + ...) +{ + va_list args; + + va_start(args, message); + vsprintf(ddlogbuf, message, args); + va_end(args); + + lstrcat(ddlogbuf, "\n"); + + ddlogMessage(severity, ddlogbuf); +} + +// *********************************************************************** + +void ddlogWarnOption( + BOOL bWarnOption) +{ + bUIWarning = bWarnOption; +} + +// *********************************************************************** + +void ddlogPathOption( + LPSTR szPath) +{ + char szPathName[_MAX_PATH]; + + strcpy(szPathName, szPath); + strcat(szPathName, "\\"); + strcat(szPathName, szDDLogName); + strcpy(szDDLogName, szPathName); +} + +// *********************************************************************** diff --git a/mesalib/src/mesa/drivers/windows/gldirect/ddlog.h b/mesalib/src/mesa/drivers/windows/gldirect/ddlog.h new file mode 100644 index 000000000..d64067e22 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/ddlog.h @@ -0,0 +1,109 @@ +/**************************************************************************** +* +* 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: Logging functions. +* +****************************************************************************/ + +#ifndef __DDLOG_H +#define __DDLOG_H + +#include <stdio.h> + +#ifndef _USE_GLD3_WGL +#include "dderrstr.h" // ddraw/d3d error string +#endif + +/*---------------------- Macros and type definitions ----------------------*/ + +typedef enum { + DDLOG_NONE = 0, // No log output + DDLOG_NORMAL = 1, // Log is kept open + DDLOG_CRASHPROOF = 2, // Log is closed and flushed + DDLOG_METHOD_FORCE_DWORD = 0x7fffffff, +} DDLOG_loggingMethodType; + +// Denotes type of message sent to the logging functions +typedef enum { + DDLOG_INFO = 0, // Information only + DDLOG_WARN = 1, // Warning only + DDLOG_ERROR = 2, // Notify user of an error + DDLOG_CRITICAL = 3, // Exceptionally severe error + DDLOG_SYSTEM = 4, // System message. Not an error + // but must always be printed. + DDLOG_SEVERITY_FORCE_DWORD = 0x7fffffff, // Make enum dword +} DDLOG_severityType; + +#ifdef _USE_GLD3_WGL +// Synomyms +#define GLDLOG_INFO DDLOG_INFO +#define GLDLOG_WARN DDLOG_WARN +#define GLDLOG_ERROR DDLOG_ERROR +#define GLDLOG_CRITICAL DDLOG_CRITICAL +#define GLDLOG_SYSTEM DDLOG_SYSTEM +#endif + +// The message that will be output to the log +static const char *ddlogSeverityMessages[] = { + "INFO", + "WARN", + "ERROR", + "*CRITICAL*", + "System", +}; + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +void ddlogOpen(DDLOG_loggingMethodType LoggingMethod, DDLOG_severityType Severity); +void ddlogClose(); +void ddlogMessage(DDLOG_severityType severity, LPSTR message); +void ddlogError(DDLOG_severityType severity, LPSTR message, HRESULT hResult); +void ddlogPrintf(DDLOG_severityType severity, LPSTR message, ...); +void ddlogWarnOption(BOOL bWarnOption); +void ddlogPathOption(LPSTR szPath); + +#ifdef _USE_GLD3_WGL +// Synomyms +#define gldLogMessage ddlogMessage +#define gldLogError ddlogError +#define gldLogPrintf ddlogPrintf +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.c b/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.c new file mode 100644 index 000000000..e9c23d1cc --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.c @@ -0,0 +1,2214 @@ +/**************************************************************************** +* +* 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: Context handling. +* +****************************************************************************/ + +#include "dglcontext.h" + +// Get compile errors without this. KeithH +//#include "scitech.h" // ibool, etc. + +#ifdef _USE_GLD3_WGL +#include "gld_driver.h" + +extern void _gld_mesa_warning(GLcontext *, char *); +extern void _gld_mesa_fatal(GLcontext *, char *); +#endif // _USE_GLD3_WGL + +// TODO: Clean out old DX6-specific code from GLD 2.x CAD driver +// if it is no longer being built as part of GLDirect. (DaveM) + +// *********************************************************************** + +#define GLDERR_NONE 0 +#define GLDERR_MEM 1 +#define GLDERR_DDRAW 2 +#define GLDERR_D3D 3 +#define GLDERR_BPP 4 + +char szResourceWarning[] = +"GLDirect does not have enough video memory resources\n" +"to support the requested OpenGL rendering context.\n\n" +"You may have to reduce the current display resolution\n" +"to obtain satisfactory OpenGL performance.\n"; + +char szDDrawWarning[] = +"GLDirect is unable to initialize DirectDraw for the\n" +"requested OpenGL rendering context.\n\n" +"You will have to check the DirectX control panel\n" +"for further information.\n"; + +char szD3DWarning[] = +"GLDirect is unable to initialize Direct3D for the\n" +"requested OpenGL rendering context.\n\n" +"You may have to change the display mode resolution\n" +"color depth or check the DirectX control panel for\n" +"further information.\n"; + +char szBPPWarning[] = +"GLDirect is unable to use the selected color depth for\n" +"the requested OpenGL rendering context.\n\n" +"You will have to change the display mode resolution\n" +"color depth with the Display Settings control panel.\n"; + +int nContextError = GLDERR_NONE; + +// *********************************************************************** + +#define VENDORID_ATI 0x1002 + +static DWORD devATIRagePro[] = { + 0x4742, // 3D RAGE PRO BGA AGP 1X/2X + 0x4744, // 3D RAGE PRO BGA AGP 1X only + 0x4749, // 3D RAGE PRO BGA PCI 33 MHz + 0x4750, // 3D RAGE PRO PQFP PCI 33 MHz + 0x4751, // 3D RAGE PRO PQFP PCI 33 MHz limited 3D + 0x4C42, // 3D RAGE LT PRO BGA-312 AGP 133 MHz + 0x4C44, // 3D RAGE LT PRO BGA-312 AGP 66 MHz + 0x4C49, // 3D RAGE LT PRO BGA-312 PCI 33 MHz + 0x4C50, // 3D RAGE LT PRO BGA-256 PCI 33 MHz + 0x4C51, // 3D RAGE LT PRO BGA-256 PCI 33 MHz limited 3D +}; + +static DWORD devATIRageIIplus[] = { + 0x4755, // 3D RAGE II+ + 0x4756, // 3D RAGE IIC PQFP PCI + 0x4757, // 3D RAGE IIC BGA AGP + 0x475A, // 3D RAGE IIC PQFP AGP + 0x4C47, // 3D RAGE LT-G +}; + +// *********************************************************************** + +#ifndef _USE_GLD3_WGL +extern DGL_mesaFuncs mesaFuncs; +#endif + +extern DWORD dwLogging; + +#ifdef GLD_THREADS +#pragma message("compiling DGLCONTEXT.C vars for multi-threaded support") +CRITICAL_SECTION CriticalSection; // for serialized access +DWORD dwTLSCurrentContext = 0xFFFFFFFF; // TLS index for current context +DWORD dwTLSPixelFormat = 0xFFFFFFFF; // TLS index for current pixel format +#endif +HGLRC iCurrentContext = 0; // Index of current context (static) +BOOL bContextReady = FALSE; // Context state ready ? + +DGL_ctx ctxlist[DGL_MAX_CONTEXTS]; // Context list + +// *********************************************************************** + +static BOOL bHaveWin95 = FALSE; +static BOOL bHaveWinNT = FALSE; +static BOOL bHaveWin2K = FALSE; + +/**************************************************************************** +REMARKS: +Detect the installed OS type. +****************************************************************************/ +static void DetectOS(void) +{ + OSVERSIONINFO VersionInformation; + LPOSVERSIONINFO lpVersionInformation = &VersionInformation; + + VersionInformation.dwOSVersionInfoSize = sizeof(VersionInformation); + + GetVersionEx(lpVersionInformation); + + switch (VersionInformation.dwPlatformId) { + case VER_PLATFORM_WIN32_WINDOWS: + bHaveWin95 = TRUE; + bHaveWinNT = FALSE; + bHaveWin2K = FALSE; + break; + case VER_PLATFORM_WIN32_NT: + bHaveWin95 = FALSE; + if (VersionInformation.dwMajorVersion <= 4) { + bHaveWinNT = TRUE; + bHaveWin2K = FALSE; + } + else { + bHaveWinNT = FALSE; + bHaveWin2K = TRUE; + } + break; + case VER_PLATFORM_WIN32s: + bHaveWin95 = FALSE; + bHaveWinNT = FALSE; + bHaveWin2K = FALSE; + break; + } +} + +// *********************************************************************** + +HWND hWndEvent = NULL; // event monitor window +HWND hWndLastActive = NULL; // last active client window +LONG __stdcall GLD_EventWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam); + +// *********************************************************************** + +// Checks if the HGLRC is valid in range of context list. +BOOL dglIsValidContext( + HGLRC a) +{ + return ((int)a > 0 && (int)a <= DGL_MAX_CONTEXTS); +} + +// *********************************************************************** + +// Convert a HGLRC to a pointer into the context list. +DGL_ctx* dglGetContextAddress( + const HGLRC a) +{ + if (dglIsValidContext(a)) + return &ctxlist[(int)a-1]; + return NULL; +} + +// *********************************************************************** + +// Return the current HGLRC (however it may be stored for multi-threading). +HGLRC dglGetCurrentContext(void) +{ +#ifdef GLD_THREADS + HGLRC hGLRC; + // load from thread-specific instance + if (glb.bMultiThreaded) { + // protect against calls from arbitrary threads + __try { + hGLRC = (HGLRC)TlsGetValue(dwTLSCurrentContext); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + hGLRC = iCurrentContext; + } + } + // load from global static var + else { + hGLRC = iCurrentContext; + } + return hGLRC; +#else + return iCurrentContext; +#endif +} + +// *********************************************************************** + +// Set the current HGLRC (however it may be stored for multi-threading). +void dglSetCurrentContext(HGLRC hGLRC) +{ +#ifdef GLD_THREADS + // store in thread-specific instance + if (glb.bMultiThreaded) { + // protect against calls from arbitrary threads + __try { + TlsSetValue(dwTLSCurrentContext, (LPVOID)hGLRC); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + iCurrentContext = hGLRC; + } + } + // store in global static var + else { + iCurrentContext = hGLRC; + } +#else + iCurrentContext = hGLRC; +#endif +} + +// *********************************************************************** + +// Return the current HDC only for a currently active HGLRC. +HDC dglGetCurrentDC(void) +{ + HGLRC hGLRC; + DGL_ctx* lpCtx; + + hGLRC = dglGetCurrentContext(); + if (hGLRC) { + lpCtx = dglGetContextAddress(hGLRC); + return lpCtx->hDC; + } + return 0; +} + +// *********************************************************************** + +void dglInitContextState() +{ + int i; + WNDCLASS wc; + +#ifdef GLD_THREADS + // Allocate thread local storage indexes for current context and pixel format + dwTLSCurrentContext = TlsAlloc(); + dwTLSPixelFormat = TlsAlloc(); +#endif + + dglSetCurrentContext(NULL); // No current rendering context + + // Clear all context data + ZeroMemory(ctxlist, sizeof(ctxlist[0]) * DGL_MAX_CONTEXTS); + + for (i=0; i<DGL_MAX_CONTEXTS; i++) + ctxlist[i].bAllocated = FALSE; // Flag context as unused + + // This section of code crashes the dll in circumstances where the app + // creates and destroys contexts. +/* + // Register the class for our event monitor window + wc.style = 0; + wc.lpfnWndProc = GLD_EventWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = GetModuleHandle(NULL); + wc.hIcon = LoadIcon(GetModuleHandle(NULL), IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = "GLDIRECT"; + RegisterClass(&wc); + + // Create the non-visible window to monitor all broadcast messages + hWndEvent = CreateWindowEx( + WS_EX_TOOLWINDOW,"GLDIRECT","GLDIRECT",WS_POPUP, + 0,0,0,0, + NULL,NULL,GetModuleHandle(NULL),NULL); +*/ + +#ifdef GLD_THREADS + // Create a critical section object for serializing access to + // DirectDraw and DDStereo create/destroy functions in multiple threads + if (glb.bMultiThreaded) + InitializeCriticalSection(&CriticalSection); +#endif + + // Context state is now initialized and ready + bContextReady = TRUE; +} + +// *********************************************************************** + +void dglDeleteContextState() +{ + int i; + static BOOL bOnceIsEnough = FALSE; + + // Only call once, from either DGL_exitDriver(), or DLL_PROCESS_DETACH + if (bOnceIsEnough) + return; + bOnceIsEnough = TRUE; + + for (i=0; i<DGL_MAX_CONTEXTS; i++) { + if (ctxlist[i].bAllocated == TRUE) { + ddlogPrintf(DDLOG_WARN, "** Context %i not deleted - cleaning up.", (i+1)); + dglDeleteContext((HGLRC)(i+1)); + } + } + + // Context state is no longer ready + bContextReady = FALSE; + + // If executed when DLL unloads, DDraw objects may be invalid. + // So catch any page faults with this exception handler. +__try { + + // Release final DirectDraw interfaces + if (glb.bDirectDrawPersistant) { +// RELEASE(glb.lpGlobalPalette); +// RELEASE(glb.lpDepth4); +// RELEASE(glb.lpBack4); +// RELEASE(glb.lpPrimary4); +// RELEASE(glb.lpDD4); + } +} +__except(EXCEPTION_EXECUTE_HANDLER) { + ddlogPrintf(DDLOG_WARN, "Exception raised in dglDeleteContextState."); +} + + // Destroy our event monitor window + if (hWndEvent) { + DestroyWindow(hWndEvent); + hWndEvent = hWndLastActive = NULL; + } + +#ifdef GLD_THREADS + // Destroy the critical section object + if (glb.bMultiThreaded) + DeleteCriticalSection(&CriticalSection); + + // Release thread local storage indexes for current HGLRC and pixel format + TlsFree(dwTLSPixelFormat); + TlsFree(dwTLSCurrentContext); +#endif +} + +// *********************************************************************** + +// Application Window message handler interception +static LONG __stdcall dglWndProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam) +{ + DGL_ctx* lpCtx = NULL; + LONG lpfnWndProc = 0L; + int i; + HGLRC hGLRC; + RECT rect; + PAINTSTRUCT ps; + BOOL bQuit = FALSE; + BOOL bMain = FALSE; + LONG rc; + + // Get the window's message handler *before* it is unhooked in WM_DESTROY + + // Is this the main window? + if (hwnd == glb.hWndActive) { + bMain = TRUE; + lpfnWndProc = glb.lpfnWndProc; + } + // Search for DGL context matching window handle + for (i=0; i<DGL_MAX_CONTEXTS; i++) { + if (ctxlist[i].hWnd == hwnd) { + lpCtx = &ctxlist[i]; + lpfnWndProc = lpCtx->lpfnWndProc; + break; + } + } + // Not one of ours... + if (!lpfnWndProc) + return DefWindowProc(hwnd, msg, wParam, lParam); + + // Intercept messages amd process *before* passing on to window + switch (msg) { +#ifdef _USE_GLD3_WGL + case WM_DISPLAYCHANGE: + glb.bPixelformatsDirty = TRUE; + break; +#endif + case WM_ACTIVATEAPP: + glb.bAppActive = (BOOL)wParam; + ddlogPrintf(DDLOG_INFO, "Calling app has been %s", glb.bAppActive ? "activated" : "de-activated"); + break; + case WM_ERASEBKGND: + // Eat the GDI erase event for the GL window + if (!lpCtx || !lpCtx->bHasBeenCurrent) + break; + lpCtx->bGDIEraseBkgnd = TRUE; + return TRUE; + case WM_PAINT: + // Eat the invalidated update region if render scene is in progress + if (!lpCtx || !lpCtx->bHasBeenCurrent) + break; + if (lpCtx->bFrameStarted) { + if (GetUpdateRect(hwnd, &rect, FALSE)) { + BeginPaint(hwnd, &ps); + EndPaint(hwnd, &ps); + ValidateRect(hwnd, &rect); + return TRUE; + } + } + break; + } + // Call the appropriate window message handler + rc = CallWindowProc((WNDPROC)lpfnWndProc, hwnd, msg, wParam, lParam); + + // Intercept messages and process *after* passing on to window + switch (msg) { + case WM_QUIT: + case WM_DESTROY: + bQuit = TRUE; + if (lpCtx && lpCtx->bAllocated) { + ddlogPrintf(DDLOG_WARN, "WM_DESTROY detected for HWND=%X, HDC=%X, HGLRC=%d", hwnd, lpCtx->hDC, i+1); + dglDeleteContext((HGLRC)(i+1)); + } + break; +#if 0 + case WM_SIZE: + // Resize surfaces to fit window but not viewport (in case app did not bother) + if (!lpCtx || !lpCtx->bHasBeenCurrent) + break; + w = LOWORD(lParam); + h = HIWORD(lParam); + if (lpCtx->dwWidth < w || lpCtx->dwHeight < h) { + if (!dglWglResizeBuffers(lpCtx->glCtx, TRUE)) + dglWglResizeBuffers(lpCtx->glCtx, FALSE); + } + break; +#endif + } + + // If the main window is quitting, then so should we... + if (bMain && bQuit) { + ddlogPrintf(DDLOG_SYSTEM, "shutting down after WM_DESTROY detected for main HWND=%X", hwnd); + dglDeleteContextState(); + dglExitDriver(); + } + + return rc; +} + +// *********************************************************************** + +// Driver Window message handler +static LONG __stdcall GLD_EventWndProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam) +{ + switch (msg) { + // May be sent by splash screen dialog on exit + case WM_ACTIVATE: + if (LOWORD(wParam) == WA_ACTIVE && glb.hWndActive) { + SetForegroundWindow(glb.hWndActive); + return 0; + } + break; + } + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +// *********************************************************************** + +// Intercepted Keyboard handler for detecting hot keys. +LRESULT CALLBACK dglKeyProc( + int code, + WPARAM wParam, + LPARAM lParam) +{ + HWND hWnd, hWndFrame; + HGLRC hGLRC = NULL; + DGL_ctx* lpCtx = NULL; + int cmd = 0, dx1 = 0, dx2 = 0, i; + static BOOL bAltPressed = FALSE; + static BOOL bCtrlPressed = FALSE; + static BOOL bShiftPressed = FALSE; + RECT r, rf, rc; + POINT pt; + BOOL bForceReshape = FALSE; + + return CallNextHookEx(hKeyHook, code, wParam, lParam); +} + +// *********************************************************************** + +HWND hWndMatch; + +// Window handle enumeration procedure. +BOOL CALLBACK dglEnumChildProc( + HWND hWnd, + LPARAM lParam) +{ + RECT rect; + + // Find window handle with matching client rect. + GetClientRect(hWnd, &rect); + if (EqualRect(&rect, (RECT*)lParam)) { + hWndMatch = hWnd; + return FALSE; + } + // Continue with next child window. + return TRUE; +} + +// *********************************************************************** + +// Find window handle with matching client rect. +HWND dglFindWindowRect( + RECT* pRect) +{ + hWndMatch = NULL; + EnumChildWindows(GetForegroundWindow(), dglEnumChildProc, (LPARAM)pRect); + return hWndMatch; +} + +// *********************************************************************** +#ifndef _USE_GLD3_WGL +void dglChooseDisplayMode( + DGL_ctx *lpCtx) +{ + // Note: Choose an exact match if possible. + + int i; + DWORD area; + DWORD bestarea; + DDSURFACEDESC2 *lpDDSD = NULL; // Mode list pointer + DDSURFACEDESC2 *lpBestDDSD = NULL; // Pointer to best + + lpDDSD = glb.lpDisplayModes; + for (i=0; i<glb.nDisplayModeCount; i++, lpDDSD++) { + if ((lpDDSD->dwWidth == lpCtx->dwWidth) && + (lpDDSD->dwHeight == lpCtx->dwHeight)) + goto matched; // Mode has been exactly matched + // Choose modes that are larger in both dimensions than + // the window, but smaller in area than the current best. + if ( (lpDDSD->dwWidth >= lpCtx->dwWidth) && + (lpDDSD->dwHeight >= lpCtx->dwHeight)) + { + if (lpBestDDSD == NULL) { + lpBestDDSD = lpDDSD; + bestarea = lpDDSD->dwWidth * lpDDSD->dwHeight; + continue; + } + area = lpDDSD->dwWidth * lpDDSD->dwHeight; + if (area < bestarea) { + lpBestDDSD = lpDDSD; + bestarea = area; + } + } + } + + // Safety check + if (lpBestDDSD == NULL) { + ddlogMessage(DDLOG_CRITICAL, "dglChooseDisplayMode"); + return; + } + + lpCtx->dwModeWidth = lpBestDDSD->dwWidth; + lpCtx->dwModeHeight = lpBestDDSD->dwHeight; +matched: + ddlogPrintf(DDLOG_INFO, "Matched (%ldx%ld) to (%ldx%ld)", + lpCtx->dwWidth, lpCtx->dwHeight, lpCtx->dwModeWidth, lpCtx->dwModeHeight); +} +#endif // _USE_GLD3_WGL +// *********************************************************************** + +static BOOL IsDevice( + DWORD *lpDeviceIdList, + DWORD dwDeviceId, + int count) +{ + int i; + + for (i=0; i<count; i++) + if (dwDeviceId == lpDeviceIdList[i]) + return TRUE; + + return FALSE; +} + +// *********************************************************************** + +void dglTestForBrokenCards( + DGL_ctx *lpCtx) +{ +#ifndef _GLD3 + DDDEVICEIDENTIFIER dddi; // DX6 device identifier + + // Sanity check. + if (lpCtx == NULL) { + // Testing for broken cards is sensitive area, so we don't want + // anything saying "broken cards" in the error message. ;) + ddlogMessage(DDLOG_ERROR, "Null context passed to TFBC\n"); + return; + } + + if (lpCtx->lpDD4 == NULL) { + // Testing for broken cards is sensitive area, so we don't want + // anything saying "broken cards" in the error message. ;) + ddlogMessage(DDLOG_ERROR, "Null DD4 passed to TFBC\n"); + return; + } + + // Microsoft really fucked up with the GetDeviceIdentifier function + // on Windows 2000, since it locks up on stock driers on the CD. Updated + // drivers from vendors appear to work, but we can't identify the drivers + // without this function!!! For now we skip these tests on Windows 2000. + if ((GetVersion() & 0x80000000UL) == 0) + return; + + // Obtain device info + if (FAILED(IDirectDraw4_GetDeviceIdentifier(lpCtx->lpDD4, &dddi, 0))) + return; + + // Useful info. Log it. + ddlogPrintf(DDLOG_INFO, "DirectDraw: VendorId=0x%x, DeviceId=0x%x", dddi.dwVendorId, dddi.dwDeviceId); + + // Vendor 1: ATI + if (dddi.dwVendorId == VENDORID_ATI) { + // Test A: ATI Rage PRO + if (IsDevice(devATIRagePro, dddi.dwDeviceId, sizeof(devATIRagePro))) + glb.bUseMipmaps = FALSE; + // Test B: ATI Rage II+ + if (IsDevice(devATIRageIIplus, dddi.dwDeviceId, sizeof(devATIRageIIplus))) + glb.bEmulateAlphaTest = TRUE; + } + + // Vendor 2: Matrox + if (dddi.dwVendorId == 0x102B) { + // Test: Matrox G400 stencil buffer support does not work for AutoCAD + if (dddi.dwDeviceId == 0x0525) { + lpCtx->lpPF->pfd.cStencilBits = 0; + if (lpCtx->lpPF->iZBufferPF != -1) { + glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwStencilBitDepth = 0; + glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwStencilBitMask = 0; + glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwFlags &= ~DDPF_STENCILBUFFER; + } + } + } +#endif // _GLD3 +} + +// *********************************************************************** + +BOOL dglCreateContextBuffers( + HDC a, + DGL_ctx *lpCtx, + BOOL bFallback) +{ + HRESULT hResult; + + int i; +// HGLRC hGLRC; +// DGL_ctx* lpCtx; + +#ifndef _USE_GLD3_WGL + DWORD dwFlags; + DDSURFACEDESC2 ddsd2; + DDSCAPS2 ddscaps2; + LPDIRECTDRAWCLIPPER lpddClipper; + D3DDEVICEDESC D3DHWDevDesc; // Direct3D Hardware description + D3DDEVICEDESC D3DHELDevDesc; // Direct3D Hardware Emulation Layer +#endif // _USE_GLD3_WGL + + float inv_aspect; + + GLenum bDoubleBuffer; // TRUE if double buffer required + GLenum bDepthBuffer; // TRUE if depth buffer required + + const PIXELFORMATDESCRIPTOR *lpPFD = &lpCtx->lpPF->pfd; + + // Vars for Mesa visual + DWORD dwDepthBits = 0; + DWORD dwStencilBits = 0; + DWORD dwAlphaBits = 0; + DWORD bAlphaSW = GL_FALSE; + DWORD bDouble = GL_FALSE; + + DDSURFACEDESC2 ddsd2DisplayMode; + BOOL bFullScrnWin = FALSE; // fullscreen-size window ? + DDBLTFX ddbltfx; + DWORD dwMemoryType = (bFallback) ? DDSCAPS_SYSTEMMEMORY : glb.dwMemoryType; + BOOL bBogusWindow = FALSE; // non-drawable window ? + DWORD dwColorRef = 0; // GDI background color + RECT rcDst; // GDI window rect + POINT pt; // GDI window point + + // Palette used for creating default global palette + PALETTEENTRY ppe[256]; + +#ifndef _USE_GLD3_WGL + // Vertex buffer description. Used for creation of vertex buffers + D3DVERTEXBUFFERDESC vbufdesc; +#endif // _USE_GLD3_WGL + +#define DDLOG_CRITICAL_OR_WARN (bFallback ? DDLOG_CRITICAL : DDLOG_WARN) + + ddlogPrintf(DDLOG_SYSTEM, "dglCreateContextBuffers for HDC=%X", a); + nContextError = GLDERR_NONE; + +#ifdef GLD_THREADS + // Serialize access to DirectDraw object creation or DDS start + if (glb.bMultiThreaded) + EnterCriticalSection(&CriticalSection); +#endif + + // Check for back buffer + bDoubleBuffer = GL_TRUE; //(lpPFD->dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE; + // Since we always do back buffering, check if we emulate front buffering + lpCtx->EmulateSingle = + (lpPFD->dwFlags & PFD_DOUBLEBUFFER) ? FALSE : TRUE; +#if 0 // Don't have to mimic MS OpenGL behavior for front-buffering (DaveM) + lpCtx->EmulateSingle |= + (lpPFD->dwFlags & PFD_SUPPORT_GDI) ? TRUE : FALSE; +#endif + + // Check for depth buffer + bDepthBuffer = (lpPFD->cDepthBits) ? GL_TRUE : GL_FALSE; + + lpCtx->bDoubleBuffer = bDoubleBuffer; + lpCtx->bDepthBuffer = bDepthBuffer; + + // Set the Fullscreen flag for the context. +// lpCtx->bFullscreen = glb.bFullscreen; + + // Obtain the dimensions of the rendering window + lpCtx->hDC = a; // Cache DC + lpCtx->hWnd = WindowFromDC(lpCtx->hDC); + // Check for non-window DC = memory DC ? + if (lpCtx->hWnd == NULL) { + // bitmap memory contexts are always single-buffered + lpCtx->EmulateSingle = TRUE; + bBogusWindow = TRUE; + ddlogPrintf(DDLOG_INFO, "Non-Window Memory Device Context"); + if (GetClipBox(lpCtx->hDC, &lpCtx->rcScreenRect) == ERROR) { + ddlogMessage(DDLOG_WARN, "GetClipBox failed in dglCreateContext\n"); + SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0); + } + } + else if (!GetClientRect(lpCtx->hWnd, &lpCtx->rcScreenRect)) { + bBogusWindow = TRUE; + ddlogMessage(DDLOG_WARN, "GetClientRect failed in dglCreateContext\n"); + SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0); + } + lpCtx->dwWidth = lpCtx->rcScreenRect.right - lpCtx->rcScreenRect.left; + lpCtx->dwHeight = lpCtx->rcScreenRect.bottom - lpCtx->rcScreenRect.top; + + ddlogPrintf(DDLOG_INFO, "Input window %X: w=%i, h=%i", + lpCtx->hWnd, lpCtx->dwWidth, lpCtx->dwHeight); + + // What if app only zeroes one dimension instead of both? (DaveM) + if ( (lpCtx->dwWidth == 0) || (lpCtx->dwHeight == 0) ) { + // Make the buffer size something sensible + lpCtx->dwWidth = 8; + lpCtx->dwHeight = 8; + } + + // Set defaults + lpCtx->dwModeWidth = lpCtx->dwWidth; + lpCtx->dwModeHeight = lpCtx->dwHeight; +/* + // Find best display mode for fullscreen + if (glb.bFullscreen || !glb.bPrimary) { + dglChooseDisplayMode(lpCtx); + } +*/ + // Misc initialisation + lpCtx->bCanRender = FALSE; // No rendering allowed yet + lpCtx->bSceneStarted = FALSE; + lpCtx->bFrameStarted = FALSE; + + // Detect OS (specifically 'Windows 2000' or 'Windows XP') + DetectOS(); + + // NOTE: WinNT not supported + ddlogPrintf(DDLOG_INFO, "OS: %s", bHaveWin95 ? "Win9x" : (bHaveWin2K ? "Win2000/XP" : "Unsupported") ); + + // Test for Fullscreen + if (bHaveWin95) { // Problems with fullscreen on Win2K/XP + if ((GetSystemMetrics(SM_CXSCREEN) == lpCtx->dwWidth) && + (GetSystemMetrics(SM_CYSCREEN) == lpCtx->dwHeight)) + { + // Workaround for some apps that crash when going fullscreen. + //lpCtx->bFullscreen = TRUE; + } + + } + +#ifdef _USE_GLD3_WGL + _gldDriver.CreateDrawable(lpCtx, glb.bDirectDrawPersistant, glb.bPersistantBuffers); +#else + // Check if DirectDraw has already been created by original GLRC (DaveM) + if (glb.bDirectDrawPersistant && glb.bDirectDraw) { + lpCtx->lpDD4 = glb.lpDD4; + IDirectDraw4_AddRef(lpCtx->lpDD4); + goto SkipDirectDrawCreate; + } + + // Create DirectDraw object + if (glb.bPrimary) + hResult = DirectDrawCreate(NULL, &lpCtx->lpDD1, NULL); + else { + // A non-primary device is to be used. + // Force context to be Fullscreen, secondary adaptors can not + // be used in a window. + hResult = DirectDrawCreate(&glb.ddGuid, &lpCtx->lpDD1, NULL); + lpCtx->bFullscreen = TRUE; + } + if (FAILED(hResult)) { + MessageBox(NULL, "Unable to initialize DirectDraw", "GLDirect", MB_OK); + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create DirectDraw interface", hResult); + nContextError = GLDERR_DDRAW; + goto return_with_error; + } + + // Query for DX6 IDirectDraw4. + hResult = IDirectDraw_QueryInterface(lpCtx->lpDD1, + &IID_IDirectDraw4, + (void**)&lpCtx->lpDD4); + if (FAILED(hResult)) { + MessageBox(NULL, "GLDirect requires DirectX 6.0 or above", "GLDirect", MB_OK); + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create DirectDraw4 interface", hResult); + nContextError = GLDERR_DDRAW; + goto return_with_error; + } + + // Cache DirectDraw interface for subsequent GLRCs + if (glb.bDirectDrawPersistant && !glb.bDirectDraw) { + glb.lpDD4 = lpCtx->lpDD4; + IDirectDraw4_AddRef(glb.lpDD4); + glb.bDirectDraw = TRUE; + } +SkipDirectDrawCreate: + + // Now we have a DD4 interface we can check for broken cards + dglTestForBrokenCards(lpCtx); + + // Test if primary device can use flipping instead of blitting + ZeroMemory(&ddsd2DisplayMode, sizeof(ddsd2DisplayMode)); + ddsd2DisplayMode.dwSize = sizeof(ddsd2DisplayMode); + hResult = IDirectDraw4_GetDisplayMode( + lpCtx->lpDD4, + &ddsd2DisplayMode); + if (SUCCEEDED(hResult)) { + if ( (lpCtx->dwWidth == ddsd2DisplayMode.dwWidth) && + (lpCtx->dwHeight == ddsd2DisplayMode.dwHeight) ) { + // We have a fullscreen-size window + bFullScrnWin = TRUE; + // OK to use DirectDraw fullscreen mode ? + if (glb.bPrimary && !glb.bFullscreenBlit && !lpCtx->EmulateSingle && !glb.bDirectDrawPersistant) { + lpCtx->bFullscreen = TRUE; + ddlogMessage(DDLOG_INFO, "Primary upgraded to page flipping.\n"); + } + } + // Cache the display mode dimensions + lpCtx->dwModeWidth = ddsd2DisplayMode.dwWidth; + lpCtx->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 (lpCtx->dwWidth > ddsd2DisplayMode.dwWidth) + lpCtx->dwWidth = ddsd2DisplayMode.dwWidth; + if (lpCtx->dwHeight > ddsd2DisplayMode.dwHeight) + lpCtx->dwHeight = ddsd2DisplayMode.dwHeight; + + // Check for non-RGB desktop resolution + if (!lpCtx->bFullscreen && ddsd2DisplayMode.ddpfPixelFormat.dwRGBBitCount <= 8) { + ddlogPrintf(DDLOG_CRITICAL_OR_WARN, "Desktop color depth %d bpp not supported", + ddsd2DisplayMode.ddpfPixelFormat.dwRGBBitCount); + nContextError = GLDERR_BPP; + goto return_with_error; + } +#endif // _USE_GLD3_WGL + + ddlogPrintf(DDLOG_INFO, "Window: w=%i, h=%i (%s)", + lpCtx->dwWidth, + lpCtx->dwHeight, + lpCtx->bFullscreen ? "fullscreen" : "windowed"); + +#ifndef _USE_GLD3_WGL + // Obtain ddraw caps + ZeroMemory(&lpCtx->ddCaps, sizeof(DDCAPS)); + lpCtx->ddCaps.dwSize = sizeof(DDCAPS); + if (glb.bHardware) { + // Get HAL caps + IDirectDraw4_GetCaps(lpCtx->lpDD4, &lpCtx->ddCaps, NULL); + } else { + // Get HEL caps + IDirectDraw4_GetCaps(lpCtx->lpDD4, NULL, &lpCtx->ddCaps); + } + + // If this flag is present then we can't default to Mesa + // SW rendering between BeginScene() and EndScene(). + if (lpCtx->ddCaps.dwCaps2 & DDCAPS2_NO2DDURING3DSCENE) { + ddlogMessage(DDLOG_INFO, + "Warning : No 2D allowed during 3D scene.\n"); + } + + // Query for DX6 Direct3D3 interface + hResult = IDirectDraw4_QueryInterface(lpCtx->lpDD4, + &IID_IDirect3D3, + (void**)&lpCtx->lpD3D3); + if (FAILED(hResult)) { + MessageBox(NULL, "Unable to initialize Direct3D", "GLDirect", MB_OK); + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create Direct3D interface", hResult); + nContextError = GLDERR_D3D; + goto return_with_error; + } + + // Context creation + if (lpCtx->bFullscreen) { + // FULLSCREEN + + // Disable warning popups when in fullscreen mode + ddlogWarnOption(FALSE); + + // Have to release persistant primary surface if fullscreen mode + if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) { + RELEASE(glb.lpPrimary4); + glb.bDirectDrawPrimary = FALSE; + } + + dwFlags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT; + if (glb.bFastFPU) + dwFlags |= DDSCL_FPUSETUP; // fast FPU setup optional (DaveM) + hResult = IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, lpCtx->hWnd, dwFlags); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to set Exclusive Fullscreen mode", hResult); + goto return_with_error; + } + + hResult = IDirectDraw4_SetDisplayMode(lpCtx->lpDD4, + lpCtx->dwModeWidth, + lpCtx->dwModeHeight, + lpPFD->cColorBits, + 0, + 0); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "SetDisplayMode failed", hResult); + goto return_with_error; + } + + // ** The display mode has changed, so dont use MessageBox! ** + + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + + if (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(lpCtx->lpDD4, &ddsd2, &lpCtx->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (primary) failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + + // Render target surface + ZeroMemory(&ddscaps2, sizeof(ddscaps2)); // Clear the entire struct. + ddscaps2.dwCaps = DDSCAPS_BACKBUFFER; + hResult = IDirectDrawSurface4_GetAttachedSurface(lpCtx->lpFront4, &ddscaps2, &lpCtx->lpBack4); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "GetAttachedSurface failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + } else { + // Single buffered + // Primary surface + ddsd2.dwFlags = DDSD_CAPS; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | + //DDSCAPS_3DDEVICE | + dwMemoryType; + + hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (primary) failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + + lpCtx->lpBack4 = NULL; + } + } else { + // WINDOWED + + // OK to enable warning popups in windowed mode + ddlogWarnOption(glb.bMessageBoxWarnings); + + dwFlags = DDSCL_NORMAL; + if (glb.bMultiThreaded) + dwFlags |= DDSCL_MULTITHREADED; + if (glb.bFastFPU) + dwFlags |= DDSCL_FPUSETUP; // fast FPU setup optional (DaveM) + hResult = IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, + lpCtx->hWnd, + dwFlags); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to set Normal coop level", hResult); + goto return_with_error; + } + // Has Primary surface already been created for original GLRC ? + // Note this can only be applicable for windowed modes + if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) { + lpCtx->lpFront4 = glb.lpPrimary4; + IDirectDrawSurface4_AddRef(lpCtx->lpFront4); + // Update the window on the default clipper + IDirectDrawSurface4_GetClipper(lpCtx->lpFront4, &lpddClipper); + IDirectDrawClipper_SetHWnd(lpddClipper, 0, lpCtx->hWnd); + IDirectDrawClipper_Release(lpddClipper); + goto SkipPrimaryCreate; + } + + // Primary surface + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (primary) failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + + // Cache Primary surface for subsequent GLRCs + // Note this can only be applicable to subsequent windowed modes + if (glb.bDirectDrawPersistant && !glb.bDirectDrawPrimary) { + glb.lpPrimary4 = lpCtx->lpFront4; + IDirectDrawSurface4_AddRef(glb.lpPrimary4); + glb.bDirectDrawPrimary = TRUE; + } + + // Clipper object + hResult = DirectDrawCreateClipper(0, &lpddClipper, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateClipper failed", hResult); + goto return_with_error; + } + hResult = IDirectDrawClipper_SetHWnd(lpddClipper, 0, lpCtx->hWnd); + if (FAILED(hResult)) { + RELEASE(lpddClipper); + ddlogError(DDLOG_CRITICAL_OR_WARN, "SetHWnd failed", hResult); + goto return_with_error; + } + hResult = IDirectDrawSurface4_SetClipper(lpCtx->lpFront4, lpddClipper); + RELEASE(lpddClipper); // We have finished with it. + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "SetClipper failed", hResult); + goto return_with_error; + } +SkipPrimaryCreate: + + if (bDoubleBuffer) { + // Render target surface + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd2.dwWidth = lpCtx->dwWidth; + ddsd2.dwHeight = lpCtx->dwHeight; + ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | + DDSCAPS_OFFSCREENPLAIN | + dwMemoryType; + + // Reserve the entire desktop size for persistant buffers option + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers) { + ddsd2.dwWidth = ddsd2DisplayMode.dwWidth; + ddsd2.dwHeight = ddsd2DisplayMode.dwHeight; + } + // Re-use original back buffer if persistant buffers exist + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpBack4) + hResult = IDirectDrawSurface4_AddRef(lpCtx->lpBack4 = glb.lpBack4); + else + hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpBack4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "Create Backbuffer failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && !glb.lpBack4) + IDirectDrawSurface4_AddRef(glb.lpBack4 = lpCtx->lpBack4); + } else { + lpCtx->lpBack4 = NULL; + } + } + + // + // Now create the Z-buffer + // + lpCtx->bStencil = FALSE; // Default to no stencil buffer + if (bDepthBuffer && (lpCtx->lpPF->iZBufferPF != -1)) { + // 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 = lpCtx->dwWidth; + ddsd2.dwHeight = lpCtx->dwHeight; + memcpy(&ddsd2.ddpfPixelFormat, + &glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF], + sizeof(DDPIXELFORMAT) ); + + // Reserve the entire desktop size for persistant buffers option + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers) { + ddsd2.dwWidth = ddsd2DisplayMode.dwWidth; + ddsd2.dwHeight = ddsd2DisplayMode.dwHeight; + } + + // Create a z-buffer + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpDepth4) + hResult = IDirectDrawSurface4_AddRef(lpCtx->lpDepth4 = glb.lpDepth4); + else + hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpDepth4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (ZBuffer) failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && !glb.lpDepth4) + IDirectDrawSurface4_AddRef(glb.lpDepth4 = lpCtx->lpDepth4); + else if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpDepth4 && glb.lpBack4) + IDirectDrawSurface4_DeleteAttachedSurface(glb.lpBack4, 0, glb.lpDepth4); + + // Attach Zbuffer to render target + TRY(IDirectDrawSurface4_AddAttachedSurface( + bDoubleBuffer ? lpCtx->lpBack4 : lpCtx->lpFront4, + lpCtx->lpDepth4), + "dglCreateContext: Attach Zbuffer"); + if (glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwFlags & DDPF_STENCILBUFFER) { + lpCtx->bStencil = TRUE; + ddlogMessage(DDLOG_INFO, "Depth buffer has stencil\n"); + } + } + + // Clear all back buffers and Z-buffers in case of memory recycling. + ZeroMemory(&ddbltfx, sizeof(ddbltfx)); + ddbltfx.dwSize = sizeof(ddbltfx); + IDirectDrawSurface4_Blt(lpCtx->lpBack4, NULL, NULL, NULL, + DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); + if (lpCtx->lpDepth4) + IDirectDrawSurface4_Blt(lpCtx->lpDepth4, NULL, NULL, NULL, + DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); + + // Now that we have a Z-buffer we can create the 3D device + hResult = IDirect3D3_CreateDevice(lpCtx->lpD3D3, + &glb.d3dGuid, + bDoubleBuffer ? lpCtx->lpBack4 : lpCtx->lpFront4, + &lpCtx->lpDev3, + NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create Direct3D device", hResult); + nContextError = GLDERR_D3D; + goto return_with_error; + } + + // We must do this as soon as the device is created + dglInitStateCaches(lpCtx); + + // Obtain the D3D Device Description + D3DHWDevDesc.dwSize = D3DHELDevDesc.dwSize = sizeof(D3DDEVICEDESC); + TRY(IDirect3DDevice3_GetCaps(lpCtx->lpDev3, + &D3DHWDevDesc, + &D3DHELDevDesc), + "dglCreateContext: GetCaps failed"); + + // Choose the relevant description and cache it in the context. + // We will use this description later for caps checking + memcpy( &lpCtx->D3DDevDesc, + glb.bHardware ? &D3DHWDevDesc : &D3DHELDevDesc, + sizeof(D3DDEVICEDESC)); + + // Now we can examine the texture formats + if (!dglBuildTextureFormatList(lpCtx->lpDev3)) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "dglBuildTextureFormatList failed\n"); + goto return_with_error; + } + + // Get the pixel format of the back buffer + lpCtx->ddpfRender.dwSize = sizeof(lpCtx->ddpfRender); + if (bDoubleBuffer) + hResult = IDirectDrawSurface4_GetPixelFormat( + lpCtx->lpBack4, + &lpCtx->ddpfRender); + else + hResult = IDirectDrawSurface4_GetPixelFormat( + lpCtx->lpFront4, + &lpCtx->ddpfRender); + + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "GetPixelFormat failed", hResult); + goto return_with_error; + } + // Find a pixel packing function suitable for this surface + pxClassifyPixelFormat(&lpCtx->ddpfRender, + &lpCtx->fnPackFunc, + &lpCtx->fnUnpackFunc, + &lpCtx->fnPackSpanFunc); + + // Viewport + hResult = IDirect3D3_CreateViewport(lpCtx->lpD3D3, &lpCtx->lpViewport3, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateViewport failed", hResult); + goto return_with_error; + } + + hResult = IDirect3DDevice3_AddViewport(lpCtx->lpDev3, lpCtx->lpViewport3); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "AddViewport failed", hResult); + goto return_with_error; + } + + // Initialise the viewport + // Note screen coordinates are used for viewport clipping since D3D + // transform operations are not used in the GLD CAD driver. (DaveM) + inv_aspect = (float)lpCtx->dwHeight/(float)lpCtx->dwWidth; + + lpCtx->d3dViewport.dwSize = sizeof(lpCtx->d3dViewport); + lpCtx->d3dViewport.dwX = 0; + lpCtx->d3dViewport.dwY = 0; + lpCtx->d3dViewport.dwWidth = lpCtx->dwWidth; + lpCtx->d3dViewport.dwHeight = lpCtx->dwHeight; + lpCtx->d3dViewport.dvClipX = 0; // -1.0f; + lpCtx->d3dViewport.dvClipY = 0; // inv_aspect; + lpCtx->d3dViewport.dvClipWidth = lpCtx->dwWidth; // 2.0f; + lpCtx->d3dViewport.dvClipHeight = lpCtx->dwHeight; // 2.0f * inv_aspect; + lpCtx->d3dViewport.dvMinZ = 0.0f; + lpCtx->d3dViewport.dvMaxZ = 1.0f; + TRY(IDirect3DViewport3_SetViewport2(lpCtx->lpViewport3, &lpCtx->d3dViewport), "dglCreateContext: SetViewport2"); + + hResult = IDirect3DDevice3_SetCurrentViewport(lpCtx->lpDev3, lpCtx->lpViewport3); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "SetCurrentViewport failed", hResult); + goto return_with_error; + } + + lpCtx->dwBPP = lpPFD->cColorBits; + lpCtx->iZBufferPF = lpCtx->lpPF->iZBufferPF; + + // Set last texture to NULL + for (i=0; i<MAX_TEXTURE_UNITS; i++) { + lpCtx->ColorOp[i] = D3DTOP_DISABLE; + lpCtx->AlphaOp[i] = D3DTOP_DISABLE; + lpCtx->tObj[i] = NULL; + } + + // Default to perspective correct texture mapping + dglSetRenderState(lpCtx, D3DRENDERSTATE_TEXTUREPERSPECTIVE, TRUE, "TexturePersp"); + + // Set the default culling mode + lpCtx->cullmode = D3DCULL_NONE; + dglSetRenderState(lpCtx, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE, "CullMode"); + + // Disable specular + dglSetRenderState(lpCtx, D3DRENDERSTATE_SPECULARENABLE, FALSE, "SpecularEnable"); + // Disable subpixel correction +// dglSetRenderState(lpCtx, D3DRENDERSTATE_SUBPIXEL, FALSE, "SubpixelEnable"); + // Disable dithering + dglSetRenderState(lpCtx, D3DRENDERSTATE_DITHERENABLE, FALSE, "DitherEnable"); + + // Initialise the primitive caches +// lpCtx->dwNextLineVert = 0; +// lpCtx->dwNextTriVert = 0; + + // Init the global texture palette + lpCtx->lpGlobalPalette = NULL; + + // Init the HW/SW usage counters +// lpCtx->dwHWUsageCount = lpCtx->dwSWUsageCount = 0L; + + // + // Create two D3D vertex buffers. + // One will hold the pre-transformed data with the other one + // being used to hold the post-transformed & clipped verts. + // +#if 0 // never used (DaveM) + vbufdesc.dwSize = sizeof(D3DVERTEXBUFFERDESC); + vbufdesc.dwCaps = D3DVBCAPS_WRITEONLY; + if (glb.bHardware == FALSE) + vbufdesc.dwCaps = D3DVBCAPS_SYSTEMMEMORY; + vbufdesc.dwNumVertices = 32768; // For the time being + + // Source vertex buffer + vbufdesc.dwFVF = DGL_LVERTEX; + hResult = IDirect3D3_CreateVertexBuffer(lpCtx->lpD3D3, &vbufdesc, &lpCtx->m_vbuf, 0, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateVertexBuffer(src) failed", hResult); + goto return_with_error; + } + + // Destination vertex buffer + vbufdesc.dwFVF = (glb.bMultitexture == FALSE) ? D3DFVF_TLVERTEX : (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX2); + hResult = IDirect3D3_CreateVertexBuffer(lpCtx->lpD3D3, &vbufdesc, &lpCtx->m_pvbuf, 0, NULL); + if(FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateVertexBuffer(dst) failed", hResult); + goto return_with_error; + } +#endif + +#endif _USE_GLD3_WGL + + // + // Now create the Mesa context + // + + // Create the Mesa visual + if (lpPFD->cDepthBits) + dwDepthBits = 16; + if (lpPFD->cStencilBits) + dwStencilBits = 8; + if (lpPFD->cAlphaBits) { + dwAlphaBits = 8; + bAlphaSW = GL_TRUE; + } + if (lpPFD->dwFlags & PFD_DOUBLEBUFFER) + bDouble = GL_TRUE; +// lpCtx->EmulateSingle = +// (lpPFD->dwFlags & PFD_DOUBLEBUFFER) ? FALSE : TRUE; + +#ifdef _USE_GLD3_WGL + lpCtx->glVis = _mesa_create_visual( + GL_TRUE, // RGB mode + bDouble, /* double buffer */ + GL_FALSE, // stereo + lpPFD->cRedBits, + lpPFD->cGreenBits, + lpPFD->cBlueBits, + dwAlphaBits, + 0, // index bits + dwDepthBits, + dwStencilBits, + lpPFD->cAccumRedBits, // accum bits + lpPFD->cAccumGreenBits, // accum bits + lpPFD->cAccumBlueBits, // accum bits + lpPFD->cAccumAlphaBits, // accum alpha bits + 1 // num samples + ); +#else // _USE_GLD3_WGL + lpCtx->glVis = (*mesaFuncs.gl_create_visual)( + GL_TRUE, // RGB mode + bAlphaSW, // Is an alpha buffer required? + bDouble, // Is an double-buffering required? + GL_FALSE, // stereo + dwDepthBits, // depth_size + dwStencilBits, // stencil_size + lpPFD->cAccumBits, // accum_size + 0, // colour-index bits + lpPFD->cRedBits, // Red bit count + lpPFD->cGreenBits, // Green bit count + lpPFD->cBlueBits, // Blue bit count + dwAlphaBits // Alpha bit count + ); +#endif // _USE_GLD3_WGL + + if (lpCtx->glVis == NULL) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "gl_create_visual failed\n"); + goto return_with_error; + } + +#ifdef _USE_GLD3_WGL + lpCtx->glCtx = _mesa_create_context(lpCtx->glVis, NULL, (void *)lpCtx, GL_TRUE); +#else + // Create the Mesa context + lpCtx->glCtx = (*mesaFuncs.gl_create_context)( + lpCtx->glVis, // Mesa visual + NULL, // share list context + (void *)lpCtx, // Pointer to our driver context + GL_TRUE // Direct context flag + ); +#endif // _USE_GLD3_WGL + + if (lpCtx->glCtx == NULL) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "gl_create_context failed\n"); + goto return_with_error; + } + + // Create the Mesa framebuffer +#ifdef _USE_GLD3_WGL + lpCtx->glBuffer = _mesa_create_framebuffer( + lpCtx->glVis, + lpCtx->glVis->depthBits > 0, + lpCtx->glVis->stencilBits > 0, + lpCtx->glVis->accumRedBits > 0, + GL_FALSE //swalpha + ); +#else + lpCtx->glBuffer = (*mesaFuncs.gl_create_framebuffer)(lpCtx->glVis); +#endif // _USE_GLD3_WGL + + if (lpCtx->glBuffer == NULL) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "gl_create_framebuffer failed\n"); + goto return_with_error; + } + +#ifdef _USE_GLD3_WGL + // Init Mesa internals + _swrast_CreateContext( lpCtx->glCtx ); + _vbo_CreateContext( lpCtx->glCtx ); + _tnl_CreateContext( lpCtx->glCtx ); + _swsetup_CreateContext( lpCtx->glCtx ); + + _gldDriver.InitialiseMesa(lpCtx); + + lpCtx->glCtx->imports.warning = _gld_mesa_warning; + lpCtx->glCtx->imports.fatal = _gld_mesa_fatal; + +#else + // Tell Mesa how many texture stages we have + glb.wMaxSimultaneousTextures = lpCtx->D3DDevDesc.wMaxSimultaneousTextures; + // Only use as many Units as the spec requires + if (glb.wMaxSimultaneousTextures > MAX_TEXTURE_UNITS) + glb.wMaxSimultaneousTextures = MAX_TEXTURE_UNITS; + lpCtx->glCtx->Const.MaxTextureUnits = glb.wMaxSimultaneousTextures; + ddlogPrintf(DDLOG_INFO, "Texture stages : %d", glb.wMaxSimultaneousTextures); + + // Set the max texture size. + // NOTE: clamped to a max of 1024 for extra performance! + lpCtx->dwMaxTextureSize = (lpCtx->D3DDevDesc.dwMaxTextureWidth <= 1024) ? lpCtx->D3DDevDesc.dwMaxTextureWidth : 1024; + +// Texture resize takes place elsewhere. KH +// NOTE: This was added to workaround an issue with the Intel app. +#if 0 + lpCtx->glCtx->Const.MaxTextureSize = lpCtx->dwMaxTextureSize; +#else + lpCtx->glCtx->Const.MaxTextureSize = 1024; +#endif + lpCtx->glCtx->Const.MaxDrawBuffers = 1; + + // Setup the Display Driver pointers + dglSetupDDPointers(lpCtx->glCtx); + + // Initialise all the Direct3D renderstates + dglInitStateD3D(lpCtx->glCtx); + +#if 0 + // Signal a reload of texture state on next glBegin + lpCtx->m_texHandleValid = FALSE; + lpCtx->m_mtex = FALSE; + lpCtx->m_texturing = FALSE; +#else + // Set default texture unit state +// dglSetTexture(lpCtx, 0, NULL); +// dglSetTexture(lpCtx, 1, NULL); +#endif + + // + // Set the global texture palette to default values. + // + + // Clear the entire palette + ZeroMemory(ppe, sizeof(PALETTEENTRY) * 256); + + // Fill the palette with a default colour. + // A garish colour is used to catch bugs. Here Magenta is used. + for (i=0; i < 256; i++) { + ppe[i].peRed = 255; + ppe[i].peGreen = 0; + ppe[i].peBlue = 255; + } + + RELEASE(lpCtx->lpGlobalPalette); + + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpGlobalPalette) + hResult = IDirectDrawPalette_AddRef(lpCtx->lpGlobalPalette = glb.lpGlobalPalette); + else + hResult = IDirectDraw4_CreatePalette( + lpCtx->lpDD4, + DDPCAPS_INITIALIZE | DDPCAPS_8BIT | DDPCAPS_ALLOW256, + ppe, + &(lpCtx->lpGlobalPalette), + NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_ERROR, "Default CreatePalette failed\n", hResult); + lpCtx->lpGlobalPalette = NULL; + goto return_with_error; + } + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && !glb.lpGlobalPalette) + IDirectDrawPalette_AddRef(glb.lpGlobalPalette = lpCtx->lpGlobalPalette); + +#endif // _USE_GLD3_WGL + + // ** If we have made it to here then we can enable rendering ** + lpCtx->bCanRender = TRUE; + +// ddlogMessage(DDLOG_SYSTEM, "dglCreateContextBuffers succeded\n"); + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + return TRUE; + +return_with_error: + // Clean up before returning. + // This is critical for secondary devices. + + lpCtx->bCanRender = FALSE; + +#ifdef _USE_GLD3_WGL + // Destroy the Mesa context + if (lpCtx->glBuffer) + _mesa_destroy_framebuffer(lpCtx->glBuffer); + if (lpCtx->glCtx) + _mesa_destroy_context(lpCtx->glCtx); + if (lpCtx->glVis) + _mesa_destroy_visual(lpCtx->glVis); + + // Destroy driver data + _gldDriver.DestroyDrawable(lpCtx); +#else + // Destroy the Mesa context + if (lpCtx->glBuffer) + (*mesaFuncs.gl_destroy_framebuffer)(lpCtx->glBuffer); + if (lpCtx->glCtx) + (*mesaFuncs.gl_destroy_context)(lpCtx->glCtx); + if (lpCtx->glVis) + (*mesaFuncs.gl_destroy_visual)(lpCtx->glVis); + + RELEASE(lpCtx->m_pvbuf); // Release D3D vertex buffer + RELEASE(lpCtx->m_vbuf); // Release D3D vertex buffer + + if (lpCtx->lpViewport3) { + if (lpCtx->lpDev3) IDirect3DDevice3_DeleteViewport(lpCtx->lpDev3, lpCtx->lpViewport3); + RELEASE(lpCtx->lpViewport3); + lpCtx->lpViewport3 = NULL; + } + + RELEASE(lpCtx->lpDev3); + if (lpCtx->lpDepth4) { + if (lpCtx->lpBack4) + IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpBack4, 0L, lpCtx->lpDepth4); + else + IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpFront4, 0L, lpCtx->lpDepth4); + RELEASE(lpCtx->lpDepth4); + lpCtx->lpDepth4 = NULL; + } + RELEASE(lpCtx->lpBack4); + RELEASE(lpCtx->lpFront4); + else + if (lpCtx->bFullscreen) { + IDirectDraw4_RestoreDisplayMode(lpCtx->lpDD4); + IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, NULL, DDSCL_NORMAL); + } + RELEASE(lpCtx->lpD3D3); + RELEASE(lpCtx->lpDD4); + RELEASE(lpCtx->lpDD1); +#endif // _USE_GLD3_WGL + + lpCtx->bAllocated = FALSE; + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + return FALSE; + +#undef DDLOG_CRITICAL_OR_WARN +} + +// *********************************************************************** + +HGLRC dglCreateContext( + HDC a, + const DGL_pixelFormat *lpPF) +{ + int i; + HGLRC hGLRC; + DGL_ctx* lpCtx; + static BOOL bWarnOnce = TRUE; + DWORD dwThreadId = GetCurrentThreadId(); + char szMsg[256]; + HWND hWnd; + LONG lpfnWndProc; + + // Validate license + if (!dglValidate()) + return NULL; + + // Is context state ready ? + if (!bContextReady) + return NULL; + + ddlogPrintf(DDLOG_SYSTEM, "dglCreateContext for HDC=%X, ThreadId=%X", a, dwThreadId); + + // Find next free context. + // Also ensure that only one Fullscreen context is created at any one time. + hGLRC = 0; // Default to Not Found + for (i=0; i<DGL_MAX_CONTEXTS; i++) { + if (ctxlist[i].bAllocated) { + if (/*glb.bFullscreen && */ctxlist[i].bFullscreen) + break; + } else { + hGLRC = (HGLRC)(i+1); + break; + } + } + + // Bail if no GLRC was found + if (!hGLRC) + return NULL; + + // Set the context pointer + lpCtx = dglGetContextAddress(hGLRC); + // Make sure that context is zeroed before we do anything. + // MFC and C++ apps call wglCreateContext() and wglDeleteContext() multiple times, + // even though only one context is ever used by the app, so keep it clean. (DaveM) + ZeroMemory(lpCtx, sizeof(DGL_ctx)); + lpCtx->bAllocated = TRUE; + // Flag that buffers need creating on next wglMakeCurrent call. + lpCtx->bHasBeenCurrent = FALSE; + lpCtx->lpPF = (DGL_pixelFormat *)lpPF; // cache pixel format + lpCtx->bCanRender = FALSE; + + // Create all the internal resources here, not in dglMakeCurrent(). + // We do a re-size check in dglMakeCurrent in case of re-allocations. (DaveM) + // We now try context allocations twice, first with video memory, + // then again with system memory. This is similar to technique + // used for dglWglResizeBuffers(). (DaveM) + if (lpCtx->bHasBeenCurrent == FALSE) { + if (!dglCreateContextBuffers(a, lpCtx, FALSE)) { + if (glb.bMessageBoxWarnings && bWarnOnce && dwLogging) { + bWarnOnce = FALSE; + switch (nContextError) { + case GLDERR_DDRAW: strcpy(szMsg, szDDrawWarning); break; + case GLDERR_D3D: strcpy(szMsg, szD3DWarning); break; + case GLDERR_MEM: strcpy(szMsg, szResourceWarning); break; + case GLDERR_BPP: strcpy(szMsg, szBPPWarning); break; + default: strcpy(szMsg, ""); + } + if (strlen(szMsg)) + MessageBox(NULL, szMsg, "GLDirect", MB_OK | MB_ICONWARNING); + } + // Only need to try again if memory error + if (nContextError == GLDERR_MEM) { + ddlogPrintf(DDLOG_WARN, "dglCreateContext failed 1st time with video memory"); + } + else { + ddlogPrintf(DDLOG_ERROR, "dglCreateContext failed"); + return NULL; + } + } + } + + // Now that we have a hWnd, we can intercept the WindowProc. + hWnd = lpCtx->hWnd; + if (hWnd) { + // Only hook individual window handler once if not hooked before. + lpfnWndProc = GetWindowLong(hWnd, GWL_WNDPROC); + if (lpfnWndProc != (LONG)dglWndProc) { + lpCtx->lpfnWndProc = lpfnWndProc; + SetWindowLong(hWnd, GWL_WNDPROC, (LONG)dglWndProc); + } + // Find the parent window of the app too. + if (glb.hWndActive == NULL) { + while (hWnd != NULL) { + glb.hWndActive = hWnd; + hWnd = GetParent(hWnd); + } + // Hook the parent window too. + lpfnWndProc = GetWindowLong(glb.hWndActive, GWL_WNDPROC); + if (glb.hWndActive == lpCtx->hWnd) + glb.lpfnWndProc = lpCtx->lpfnWndProc; + else if (lpfnWndProc != (LONG)dglWndProc) + glb.lpfnWndProc = lpfnWndProc; + if (glb.lpfnWndProc) + SetWindowLong(glb.hWndActive, GWL_WNDPROC, (LONG)dglWndProc); + } + } + + ddlogPrintf(DDLOG_SYSTEM, "dglCreateContext succeeded for HGLRC=%d", (int)hGLRC); + + return hGLRC; +} + +// *********************************************************************** +// Make a DirectGL context current +// Used by wgl functions and dgl functions +BOOL dglMakeCurrent( + HDC a, + HGLRC b) +{ + int context; + DGL_ctx* lpCtx; + HWND hWnd; + BOOL bNeedResize = FALSE; + BOOL bWindowChanged, bContextChanged; + LPDIRECTDRAWCLIPPER lpddClipper; + DWORD dwThreadId = GetCurrentThreadId(); + LONG lpfnWndProc; + + // Validate license + if (!dglValidate()) + return FALSE; + + // Is context state ready ? + if (!bContextReady) + return FALSE; + + context = (int)b; // This is as a result of STRICT! + ddlogPrintf(DDLOG_SYSTEM, "dglMakeCurrent: HDC=%X, HGLRC=%d, ThreadId=%X", a, context, dwThreadId); + + // If the HGLRC is NULL then make no context current; + // Ditto if the HDC is NULL either. (DaveM) + if (context == 0 || a == 0) { + // Corresponding Mesa operation +#ifdef _USE_GLD3_WGL + _mesa_make_current(NULL, NULL); +#else + (*mesaFuncs.gl_make_current)(NULL, NULL); +#endif + dglSetCurrentContext(0); + return TRUE; + } + + // Make sure the HGLRC is in range + if ((context > DGL_MAX_CONTEXTS) || (context < 0)) { + ddlogMessage(DDLOG_ERROR, "dglMakeCurrent: HGLRC out of range\n"); + return FALSE; + } + + // Find address of context and make sure that it has been allocated + lpCtx = dglGetContextAddress(b); + if (!lpCtx->bAllocated) { + ddlogMessage(DDLOG_ERROR, "dglMakeCurrent: Context not allocated\n"); +// return FALSE; + return TRUE; // HACK: Shuts up "WebLab Viewer Pro". KeithH + } + +#ifdef GLD_THREADS + // Serialize access to DirectDraw or DDS operations + if (glb.bMultiThreaded) + EnterCriticalSection(&CriticalSection); +#endif + + // Check if window has changed + hWnd = (a != lpCtx->hDC) ? WindowFromDC(a) : lpCtx->hWnd; + bWindowChanged = (hWnd != lpCtx->hWnd) ? TRUE : FALSE; + bContextChanged = (b != dglGetCurrentContext()) ? TRUE : FALSE; + + // If the window has changed, make sure the clipper is updated. (DaveM) + if (glb.bDirectDrawPersistant && !lpCtx->bFullscreen && (bWindowChanged || bContextChanged)) { + lpCtx->hWnd = hWnd; +#ifndef _USE_GLD3_WGL + IDirectDrawSurface4_GetClipper(lpCtx->lpFront4, &lpddClipper); + IDirectDrawClipper_SetHWnd(lpddClipper, 0, lpCtx->hWnd); + IDirectDrawClipper_Release(lpddClipper); +#endif // _USE_GLD3_WGL + } + + // Make sure hDC and hWnd is current. (DaveM) + // Obtain the dimensions of the rendering window + lpCtx->hDC = a; // Cache DC + lpCtx->hWnd = hWnd; + hWndLastActive = hWnd; + + // Check for non-window DC = memory DC ? + if (hWnd == NULL) { + if (GetClipBox(a, &lpCtx->rcScreenRect) == ERROR) { + ddlogMessage(DDLOG_WARN, "GetClipBox failed in dglMakeCurrent\n"); + SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0); + } + } + else if (!GetClientRect(lpCtx->hWnd, &lpCtx->rcScreenRect)) { + ddlogMessage(DDLOG_WARN, "GetClientRect failed in dglMakeCurrent\n"); + SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0); + } + // Check if buffers need to be re-sized; + // If so, wait until Mesa GL stuff is setup before re-sizing; + if (lpCtx->dwWidth != lpCtx->rcScreenRect.right - lpCtx->rcScreenRect.left || + lpCtx->dwHeight != lpCtx->rcScreenRect.bottom - lpCtx->rcScreenRect.top) + bNeedResize = TRUE; + + // Now we can update our globals + dglSetCurrentContext(b); + + // Corresponding Mesa operation +#ifdef _USE_GLD3_WGL + _mesa_make_current(lpCtx->glCtx, lpCtx->glBuffer); + lpCtx->glCtx->Driver.UpdateState(lpCtx->glCtx, _NEW_ALL); + if (bNeedResize) { + // Resize buffers (Note Mesa GL needs to be setup beforehand); + // Resize Mesa internal buffer too via glViewport() command, + // which subsequently calls dglWglResizeBuffers() too. + lpCtx->glCtx->Driver.Viewport(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); + lpCtx->bHasBeenCurrent = TRUE; + } +#else + (*mesaFuncs.gl_make_current)(lpCtx->glCtx, lpCtx->glBuffer); + + dglSetupDDPointers(lpCtx->glCtx); + + // Insure DirectDraw surfaces fit current window DC + if (bNeedResize) { + // Resize buffers (Note Mesa GL needs to be setup beforehand); + // Resize Mesa internal buffer too via glViewport() command, + // which subsequently calls dglWglResizeBuffers() too. + (*mesaFuncs.gl_Viewport)(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); + lpCtx->bHasBeenCurrent = TRUE; + } +#endif // _USE_GLD3_WGL + ddlogPrintf(DDLOG_SYSTEM, "dglMakeCurrent: width = %d, height = %d", lpCtx->dwWidth, lpCtx->dwHeight); + + // We have to clear D3D back buffer and render state if emulated front buffering + // for different window (but not context) like in Solid Edge. + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers + && (bWindowChanged /* || bContextChanged */) && lpCtx->EmulateSingle) { +#ifdef _USE_GLD3_WGL +// IDirect3DDevice8_EndScene(lpCtx->pDev); +// lpCtx->bSceneStarted = FALSE; + lpCtx->glCtx->Driver.Clear(lpCtx->glCtx, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, + GL_TRUE, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); +#else + IDirect3DDevice3_EndScene(lpCtx->lpDev3); + lpCtx->bSceneStarted = FALSE; + dglClearD3D(lpCtx->glCtx, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, + GL_TRUE, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); +#endif // _USE_GLD3_WGL + } + + // The first time we call MakeCurrent we set the initial viewport size + if (lpCtx->bHasBeenCurrent == FALSE) +#ifdef _USE_GLD3_WGL + lpCtx->glCtx->Driver.Viewport(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); +#else + (*mesaFuncs.gl_Viewport)(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); +#endif // _USE_GLD3_WGL + lpCtx->bHasBeenCurrent = TRUE; + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + return TRUE; +} + +// *********************************************************************** + +BOOL dglDeleteContext( + HGLRC a) +{ + DGL_ctx* lpCtx; + DWORD dwThreadId = GetCurrentThreadId(); + char argstr[256]; + +#if 0 // We have enough trouble throwing exceptions as it is... (DaveM) + // Validate license + if (!dglValidate()) + return FALSE; +#endif + + // Is context state ready ? + if (!bContextReady) + return FALSE; + + ddlogPrintf(DDLOG_SYSTEM, "dglDeleteContext: Deleting context HGLRC=%d, ThreadId=%X", (int)a, dwThreadId); + + // Make sure the HGLRC is in range + if (((int) a> DGL_MAX_CONTEXTS) || ((int)a < 0)) { + ddlogMessage(DDLOG_ERROR, "dglDeleteCurrent: HGLRC out of range\n"); + return FALSE; + } + + // Make sure context is valid + lpCtx = dglGetContextAddress(a); + if (!lpCtx->bAllocated) { + ddlogPrintf(DDLOG_WARN, "Tried to delete unallocated context HGLRC=%d", (int)a); +// return FALSE; + return TRUE; // HACK: Shuts up "WebLab Viewer Pro". KeithH + } + + // Make sure context is de-activated + if (a == dglGetCurrentContext()) { + ddlogPrintf(DDLOG_WARN, "dglDeleteContext: context HGLRC=%d still active", (int)a); + dglMakeCurrent(NULL, NULL); + } + +#ifdef GLD_THREADS + // Serialize access to DirectDraw or DDS operations + if (glb.bMultiThreaded) + EnterCriticalSection(&CriticalSection); +#endif + + // We are about to destroy all Direct3D objects. + // Therefore we must disable rendering + lpCtx->bCanRender = FALSE; + + // This exception handler was installed to catch some + // particularly nasty apps. Console apps that call exit() + // fall into this catagory (i.e. Win32 Glut). + + // VC cannot successfully implement multiple exception handlers + // if more than one exception occurs. Therefore reverting back to + // single exception handler as Keith originally had it. (DaveM) + +#define WARN_MESSAGE(p) strcpy(argstr, (#p)); +#define SAFE_RELEASE(p) WARN_MESSAGE(p); RELEASE(p); + +__try { +#ifdef _USE_GLD3_WGL + WARN_MESSAGE(gl_destroy_framebuffer); + if (lpCtx->glBuffer) + _mesa_destroy_framebuffer(lpCtx->glBuffer); + WARN_MESSAGE(gl_destroy_context); + if (lpCtx->glCtx) + _mesa_destroy_context(lpCtx->glCtx); + WARN_MESSAGE(gl_destroy_visual); + if (lpCtx->glVis) + _mesa_destroy_visual(lpCtx->glVis); + + _gldDriver.DestroyDrawable(lpCtx); +#else + // Destroy the Mesa context + WARN_MESSAGE(gl_destroy_framebuffer); + if (lpCtx->glBuffer) + (*mesaFuncs.gl_destroy_framebuffer)(lpCtx->glBuffer); + WARN_MESSAGE(gl_destroy_context); + if (lpCtx->glCtx) + (*mesaFuncs.gl_destroy_context)(lpCtx->glCtx); + WARN_MESSAGE(gl_destroy_visual); + if (lpCtx->glVis) + (*mesaFuncs.gl_destroy_visual)(lpCtx->glVis); + + SAFE_RELEASE(lpCtx->m_pvbuf); // release D3D vertex buffer + SAFE_RELEASE(lpCtx->m_vbuf); // release D3D vertex buffer + + // Delete the global palette + SAFE_RELEASE(lpCtx->lpGlobalPalette); + + // Clean up. + if (lpCtx->lpViewport3) { + if (lpCtx->lpDev3) IDirect3DDevice3_DeleteViewport(lpCtx->lpDev3, lpCtx->lpViewport3); + SAFE_RELEASE(lpCtx->lpViewport3); + lpCtx->lpViewport3 = NULL; + } + + SAFE_RELEASE(lpCtx->lpDev3); + if (lpCtx->lpDepth4) { + if (lpCtx->lpBack4) + IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpBack4, 0L, lpCtx->lpDepth4); + else + IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpFront4, 0L, lpCtx->lpDepth4); + SAFE_RELEASE(lpCtx->lpDepth4); + lpCtx->lpDepth4 = NULL; + } + SAFE_RELEASE(lpCtx->lpBack4); + SAFE_RELEASE(lpCtx->lpFront4); + if (lpCtx->bFullscreen) { + IDirectDraw4_RestoreDisplayMode(lpCtx->lpDD4); + IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, NULL, DDSCL_NORMAL); + } + SAFE_RELEASE(lpCtx->lpD3D3); + SAFE_RELEASE(lpCtx->lpDD4); + SAFE_RELEASE(lpCtx->lpDD1); +#endif // _ULSE_GLD3_WGL + +} +__except(EXCEPTION_EXECUTE_HANDLER) { + ddlogPrintf(DDLOG_WARN, "Exception raised in dglDeleteContext: %s", argstr); +} + + // Restore the window message handler because this context may be used + // again by another window with a *different* message handler. (DaveM) + if (lpCtx->lpfnWndProc) { + SetWindowLong(lpCtx->hWnd, GWL_WNDPROC, (LONG)lpCtx->lpfnWndProc); + lpCtx->lpfnWndProc = (LONG)NULL; + } + + lpCtx->bAllocated = FALSE; // This context is now free for use + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + return TRUE; +} + +// *********************************************************************** + +BOOL dglSwapBuffers( + HDC hDC) +{ + RECT rSrcRect; // Source rectangle + RECT rDstRect; // Destination rectangle + POINT pt; + HRESULT hResult; + + DDBLTFX bltFX; + DWORD dwBlitFlags; + DDBLTFX *lpBltFX; + +// DWORD dwThreadId = GetCurrentThreadId(); + HGLRC hGLRC = dglGetCurrentContext(); + DGL_ctx *lpCtx = dglGetContextAddress(hGLRC); + HWND hWnd; + + HDC hDCAux; // for memory DC + int x,y,w,h; // for memory DC BitBlt + +#if 0 // Perhaps not a good idea. Called too often. KH + // Validate license + if (!dglValidate()) + return FALSE; +#endif + + if (!lpCtx) { + return TRUE; //FALSE; // No current context + } + + if (!lpCtx->bCanRender) { + // Don't return false else some apps will bail. + return TRUE; + } + + hWnd = lpCtx->hWnd; + if (hDC != lpCtx->hDC) { + ddlogPrintf(DDLOG_WARN, "dglSwapBuffers: HDC=%X does not match HDC=%X for HGLRC=%d", hDC, lpCtx->hDC, hGLRC); + hWnd = WindowFromDC(hDC); + } + +#ifndef _USE_GLD3_WGL + // Ensure that the surfaces exist before we tell + // the device to render to them. + IDirectDraw4_RestoreAllSurfaces(lpCtx->lpDD4); + + // Make sure that the vertex caches have been emptied +// dglStateChange(lpCtx); + + // Some OpenGL programs don't issue a glFinish - check for it here. + if (lpCtx->bSceneStarted) { + IDirect3DDevice3_EndScene(lpCtx->lpDev3); + lpCtx->bSceneStarted = FALSE; + } +#endif + +#if 0 + // If the calling app is not active then we don't need to Blit/Flip. + // We can therefore simply return TRUE. + if (!glb.bAppActive) + return TRUE; + // Addendum: This is WRONG! We should bail if the app is *minimized*, + // not merely if the app is just plain 'not active'. + // KeithH, 27/May/2000. +#endif + + // Check for non-window DC = memory DC ? + if (hWnd == NULL) { + if (GetClipBox(hDC, &rSrcRect) == ERROR) + return TRUE; + // Use GDI BitBlt instead from compatible DirectDraw DC + x = rSrcRect.left; + y = rSrcRect.top; + w = rSrcRect.right - rSrcRect.left; + h = rSrcRect.bottom - rSrcRect.top; + + // Ack. DX8 does not have a GetDC() function... + // TODO: Defer to DX7 or DX9 drivers... (DaveM) + return TRUE; + } + + // Bail if window client region is not drawable, like in Solid Edge + if (!IsWindow(hWnd) /* || !IsWindowVisible(hWnd) */ || !GetClientRect(hWnd, &rSrcRect)) + return TRUE; + +#ifdef GLD_THREADS + // Serialize access to DirectDraw or DDS operations + if (glb.bMultiThreaded) + EnterCriticalSection(&CriticalSection); +#endif + +#ifdef _USE_GLD3_WGL + // Notify Mesa of impending swap, so Mesa can flush internal buffers. + _mesa_notifySwapBuffers(lpCtx->glCtx); + // Now perform driver buffer swap + _gldDriver.SwapBuffers(lpCtx, hDC, hWnd); +#else + if (lpCtx->bFullscreen) { + // Sync with retrace if required + if (glb.bWaitForRetrace) { + IDirectDraw4_WaitForVerticalBlank( + lpCtx->lpDD4, + DDWAITVB_BLOCKBEGIN, + 0); + } + + // Perform the fullscreen flip + TRY(IDirectDrawSurface4_Flip( + lpCtx->lpFront4, + NULL, + DDFLIP_WAIT), + "dglSwapBuffers: Flip"); + } else { + // Calculate current window position and size + pt.x = pt.y = 0; + ClientToScreen(hWnd, &pt); + GetClientRect(hWnd, &rDstRect); + if (rDstRect.right > lpCtx->dwModeWidth) + rDstRect.right = lpCtx->dwModeWidth; + if (rDstRect.bottom > lpCtx->dwModeHeight) + rDstRect.bottom = lpCtx->dwModeHeight; + OffsetRect(&rDstRect, pt.x, pt.y); + rSrcRect.left = rSrcRect.top = 0; + rSrcRect.right = lpCtx->dwWidth; + rSrcRect.bottom = lpCtx->dwHeight; + if (rSrcRect.right > lpCtx->dwModeWidth) + rSrcRect.right = lpCtx->dwModeWidth; + if (rSrcRect.bottom > lpCtx->dwModeHeight) + rSrcRect.bottom = lpCtx->dwModeHeight; + + if (glb.bWaitForRetrace) { + // Sync the blit to the vertical retrace + ZeroMemory(&bltFX, sizeof(bltFX)); + bltFX.dwSize = sizeof(bltFX); + bltFX.dwDDFX = DDBLTFX_NOTEARING; + dwBlitFlags = DDBLT_WAIT | DDBLT_DDFX; + lpBltFX = &bltFX; + } else { + dwBlitFlags = DDBLT_WAIT; + lpBltFX = NULL; + } + + // Perform the actual blit + TRY(IDirectDrawSurface4_Blt( + lpCtx->lpFront4, + &rDstRect, + lpCtx->lpBack4, // Blit source + &rSrcRect, + dwBlitFlags, + lpBltFX), + "dglSwapBuffers: Blt"); + } +#endif // _USE_GLD3_WGL + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + // TODO: Re-instate rendering bitmap snapshot feature??? (DaveM) + + // Render frame is completed + ValidateRect(hWnd, NULL); + lpCtx->bFrameStarted = FALSE; + + return TRUE; +} + +// *********************************************************************** diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.h b/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.h new file mode 100644 index 000000000..5c433b857 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.h @@ -0,0 +1,281 @@ +/**************************************************************************** +* +* 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 context handling. +* +****************************************************************************/ + +#ifndef __DGLCONTEXT_H +#define __DGLCONTEXT_H + +// Disable compiler complaints about DLL linkage +#pragma warning (disable:4273) + +// Macros to control compilation +#ifndef STRICT +#define STRICT +#endif // STRICT +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <GL\gl.h> + +#ifdef _USE_GLD3_WGL + #include "dglmacros.h" + #include "dglglobals.h" + #include "pixpack.h" + #include "ddlog.h" + #include "dglpf.h" + #include "context.h" // Mesa context +#else + #include <ddraw.h> + #include <d3d.h> + + #include "dglmacros.h" + #include "dglglobals.h" + #include "pixpack.h" + #include "ddlog.h" + #include "dglpf.h" + #include "d3dvertex.h" + + #include "DirectGL.h" + + #include "context.h" // Mesa context + #include "vb.h" // Mesa vertex buffer +#endif // _USE_GLD3_WGL + +/*---------------------- Macros and type definitions ----------------------*/ + +// TODO: Use a list instead of this constant! +#define DGL_MAX_CONTEXTS 32 + +// Structure for describing an OpenGL context +#ifdef _USE_GLD3_WGL +typedef struct { + BOOL bHasBeenCurrent; + DGL_pixelFormat *lpPF; + + // Pointer to private driver data (this also contains the drawable). + void *glPriv; + + // Mesa vars: + GLcontext *glCtx; // The core Mesa context + GLvisual *glVis; // Describes the color buffer + GLframebuffer *glBuffer; // Ancillary buffers + + GLuint ClearIndex; + GLuint CurrentIndex; + GLubyte ClearColor[4]; + GLubyte CurrentColor[4]; + + BOOL EmulateSingle; // Emulate single-buffering + BOOL bDoubleBuffer; + BOOL bDepthBuffer; + + // Shared driver vars: + BOOL bAllocated; + BOOL bFullscreen; // Is this a fullscreen context? + BOOL bSceneStarted; // Has a lpDev->BeginScene been issued? + BOOL bCanRender; // Flag: states whether rendering is OK + BOOL bFrameStarted; // Has frame update started at all? + BOOL bStencil; // TRUE if this context has stencil + BOOL bGDIEraseBkgnd; // GDI Erase Background command + + // Window information + HWND hWnd; // Window handle + HDC hDC; // Windows' Device Context of the window + DWORD dwWidth; // Window width + DWORD dwHeight; // Window height + DWORD dwBPP; // Window bits-per-pixel; + RECT rcScreenRect; // Screen rectangle + DWORD dwModeWidth; // Display mode width + DWORD dwModeHeight; // Display mode height + float dvClipX; + float dvClipY; + LONG lpfnWndProc; // window message handler function + +} DGL_ctx; + +#define GLD_context DGL_ctx +#define GLD_GET_CONTEXT(c) (GLD_context*)(c)->DriverCtx + +#else // _USE_GLD3_WGL + +typedef struct { + BOOL bHasBeenCurrent; + DGL_pixelFormat *lpPF; + // + // Mesa context vars: + // + GLcontext *glCtx; // The core Mesa context + GLvisual *glVis; // Describes the color buffer + GLframebuffer *glBuffer; // Ancillary buffers + + GLuint ClearIndex; + GLuint CurrentIndex; + GLubyte ClearColor[4]; + GLubyte CurrentColor[4]; + + BOOL EmulateSingle; // Emulate single-buffering + BOOL bDoubleBuffer; + BOOL bDepthBuffer; + int iZBufferPF; // Index of Zbuffer pixel format + + // Vertex buffer: one-to-one correlation with Mesa's vertex buffer. + // This will be filled by our setup function (see d3dvsetup.c) + DGL_TLvertex gWin[VB_SIZE]; // Transformed and lit vertices +// DGL_Lvertex gObj[VB_SIZE]; // Lit vertices in object coordinates. + + // Indices for DrawIndexedPrimitive. + // Clipped quads are drawn seperately, so use VB_SIZE. + // 6 indices are needed to make 2 triangles for each possible quad +// WORD wIndices[(VB_SIZE / 4) * 6]; + WORD wIndices[32768]; + + // + // Device driver vars: + // + BOOL bAllocated; + BOOL bFullscreen; // Is this a fullscreen context? + BOOL bSceneStarted; // Has a lpDev->BeginScene been issued? + BOOL bCanRender; // Flag: states whether rendering is OK + BOOL bFrameStarted; // Has frame update started at all? + + // DirectX COM interfaces, postfixed with the interface number + IDirectDraw *lpDD1; + IDirectDraw4 *lpDD4; + IDirect3D3 *lpD3D3; + IDirect3DDevice3 *lpDev3; + IDirect3DViewport3 *lpViewport3; + IDirectDrawSurface4 *lpFront4; + IDirectDrawSurface4 *lpBack4; + IDirectDrawSurface4 *lpDepth4; + + // Vertex buffers + BOOL bD3DPipeline; // True if using D3D geometry pipeline + IDirect3DVertexBuffer *m_vbuf; // Unprocessed vertices + IDirect3DVertexBuffer *m_pvbuf; // Processed vertices ready to be rendered + + D3DTEXTUREOP ColorOp[MAX_TEXTURE_UNITS]; // Used for re-enabling texturing + D3DTEXTUREOP AlphaOp[MAX_TEXTURE_UNITS]; // Used for re-enabling texturing + struct gl_texture_object *tObj[MAX_TEXTURE_UNITS]; + + DDCAPS ddCaps; // DirectDraw caps + D3DDEVICEDESC D3DDevDesc; // Direct3D Device description + + DDPIXELFORMAT ddpfRender; // Pixel format of the render buffer + DDPIXELFORMAT ddpfDepth; // Pixel format of the depth buffer + + BOOL bStencil; // TRUE is this context has stencil + + PX_packFunc fnPackFunc; // Pixel packing function for SW + PX_unpackFunc fnUnpackFunc; // Pixel unpacking function for SW + PX_packSpanFunc fnPackSpanFunc; // Pixel span packer + + D3DVIEWPORT2 d3dViewport; // D3D Viewport object + + D3DCULL cullmode; // Direct3D cull mode + D3DCOLOR curcolor; // Current color + DWORD dwColorPF; // Current color, in format of target surface + D3DCOLOR d3dClearColor; // Clear color + D3DCOLOR ConstantColor; // For flat shading + DWORD dwClearColorPF; // Clear color, in format of target surface + BOOL bGDIEraseBkgnd; // GDI Erase Background command + + // Primitive caches +// DGL_vertex LineCache[DGL_MAX_LINE_VERTS]; +// DGL_vertex TriCache[DGL_MAX_TRI_VERTS]; +// DWORD dwNextLineVert; +// DWORD dwNextTriVert; + + // Window information + HWND hWnd; // Window handle + HDC hDC; // Windows' Device Context of the window + DWORD dwWidth; // Window width + DWORD dwHeight; // Window height + DWORD dwBPP; // Window bits-per-pixel; + RECT rcScreenRect; // Screen rectangle + DWORD dwModeWidth; // Display mode width + DWORD dwModeHeight; // Display mode height + float dvClipX; + float dvClipY; + LONG lpfnWndProc; // window message handler function + + // Shared texture palette + IDirectDrawPalette *lpGlobalPalette; + + // Usage counters. + // One of these counters will be incremented when we choose + // between hardware and software rendering functions. +// DWORD dwHWUsageCount; // Hardware usage count +// DWORD dwSWUsageCount; // Software usage count + + // Texture state flags. +// BOOL m_texturing; // TRUE is texturing +// BOOL m_mtex; // TRUE if multitexture +// BOOL m_texHandleValid; // TRUE if tex state valid + + // Renderstate caches to ensure no redundant state changes + DWORD dwRS[256]; // Renderstates + DWORD dwTSS[2][24]; // Texture-stage states + LPDIRECT3DTEXTURE2 lpTex[2]; // Texture (1 per stage) + + DWORD dwMaxTextureSize; // Max texture size: + // clamped to 1024. + +} DGL_ctx; +#endif // _USE_GLD3_WGL + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +HHOOK hKeyHook; +LRESULT CALLBACK dglKeyProc(int code,WPARAM wParam,LPARAM lParam); + +void dglInitContextState(); +void dglDeleteContextState(); +BOOL dglIsValidContext(HGLRC a); +DGL_ctx* dglGetContextAddress(const HGLRC a); +HDC dglGetCurrentDC(void); +HGLRC dglGetCurrentContext(void); +HGLRC dglCreateContext(HDC a, const DGL_pixelFormat *lpPF); +BOOL dglMakeCurrent(HDC a, HGLRC b); +BOOL dglDeleteContext(HGLRC a); +BOOL dglSwapBuffers(HDC hDC); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglglobals.c b/mesalib/src/mesa/drivers/windows/gldirect/dglglobals.c new file mode 100644 index 000000000..c633e3bcf --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglglobals.c @@ -0,0 +1,149 @@ +/**************************************************************************** +* +* 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: Global variables. +* +****************************************************************************/ + +#include "dglglobals.h" + +// ======================================================================= +// Global Variables +// ======================================================================= + +char szCopyright[] = "Copyright (c) 1998 SciTech Software, Inc."; +char szDllName[] = "Scitech GLDirect"; +char szErrorTitle[] = "GLDirect Error"; + +DGL_globals glb; + +// Shared result variable +HRESULT hResult; + +// *********************************************************************** + +// Patch function for missing function in Mesa +int finite( + double x) +{ + return _finite(x); +}; + +// *********************************************************************** + +void dglInitGlobals() +{ + // Zero all fields just in case + memset(&glb, 0, sizeof(glb)); + + // Set the global defaults + glb.bPrimary = FALSE; // Not the primary device + glb.bHardware = FALSE; // Not a hardware device +// glb.bFullscreen = FALSE; // Not running fullscreen + glb.bSquareTextures = FALSE; // Device does not need sq + glb.bPAL8 = FALSE; // Device cannot do 8bit + glb.dwMemoryType = DDSCAPS_SYSTEMMEMORY; + glb.dwRendering = DGL_RENDER_D3D; + + glb.bWaitForRetrace = TRUE; // Sync to vertical retrace + glb.bFullscreenBlit = FALSE; + + glb.nPixelFormatCount = 0; + glb.lpPF = NULL; // Pixel format list +#ifndef _USE_GLD3_WGL + glb.nZBufferPFCount = 0; + glb.lpZBufferPF = NULL; + glb.nDisplayModeCount = 0; + glb.lpDisplayModes = NULL; + glb.nTextureFormatCount = 0; + glb.lpTextureFormat = NULL; +#endif // _USE_GLD3_WGL + + glb.wMaxSimultaneousTextures = 1; + + // Enable support for multitexture, if available. + glb.bMultitexture = TRUE; + + // Enable support for mipmapping + glb.bUseMipmaps = TRUE; + + // Alpha emulation via chroma key + glb.bEmulateAlphaTest = FALSE; + + // Use Mesa pipeline always (for compatibility) + glb.bForceMesaPipeline = FALSE; + + // Init support for multiple GLRCs + glb.bDirectDraw = FALSE; + glb.bDirectDrawPrimary = FALSE; + glb.bDirect3D = FALSE; + glb.bDirect3DDevice = FALSE; + glb.bDirectDrawStereo = FALSE; + glb.iDirectDrawStereo = 0; + glb.hWndActive = NULL; + // Init DirectX COM interfaces for multiple GLRCs +// glb.lpDD4 = NULL; +// glb.lpPrimary4 = NULL; +// glb.lpBack4 = NULL; +// glb.lpDepth4 = NULL; +// glb.lpGlobalPalette = NULL; + + // Init special support options + glb.bMessageBoxWarnings = TRUE; + glb.bDirectDrawPersistant = FALSE; + glb.bPersistantBuffers = FALSE; + + // Do not assume single-precision-only FPU (for compatibility) + glb.bFastFPU = FALSE; + + // Allow hot-key support + glb.bHotKeySupport = TRUE; + + // Default to single-threaded support (for simplicity) + glb.bMultiThreaded = FALSE; + + // Use application-specific customizations (for end-user convenience) + glb.bAppCustomizations = TRUE; + +#ifdef _USE_GLD3_WGL + // Registry/ini-file settings for GLDirect 3.x + glb.dwAdapter = 0; // Primary DX8 adapter + glb.dwTnL = 1; // MesaSW TnL + glb.dwMultisample = 0; // Multisample Off + glb.dwDriver = 2; // Direct3D HW + + // Signal a pixelformat list rebuild + glb.bPixelformatsDirty = TRUE; +#endif +} + +// *********************************************************************** diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglglobals.h b/mesalib/src/mesa/drivers/windows/gldirect/dglglobals.h new file mode 100644 index 000000000..995f1cd5e --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglglobals.h @@ -0,0 +1,198 @@ +/**************************************************************************** +* +* 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: Globals. +* +****************************************************************************/ + +#ifndef __DGLGLOBALS_H +#define __DGLGLOBALS_H + +#include "dglcontext.h" +#include "dglpf.h" // Pixel format +#ifndef _USE_GLD3_WGL +#include "d3dtexture.h" +#endif + +/*---------------------- Macros and type definitions ----------------------*/ + +typedef enum { + DGL_RENDER_MESASW = 0, + DGL_RENDER_D3D = 1, + DGL_RENDER_FORCE_DWORD = 0x7ffffff, +} DGL_renderType; + +#ifdef _USE_GLD3_WGL + +// Same as DGL_renderType? KeithH +typedef enum { + GLDS_DRIVER_MESA_SW = 0, // Mesa SW rendering + GLDS_DRIVER_REF = 1, // Direct3D Reference Rasteriser + GLDS_DRIVER_HAL = 2, // Direct3D HW rendering +} GLDS_DRIVER; + +typedef enum { + GLDS_TNL_DEFAULT = 0, // Choose best TnL method + GLDS_TNL_MESA = 1, // Mesa TnL + GLDS_TNL_D3DSW = 2, // D3D Software TnL + GLDS_TNL_D3DHW = 3, // D3D Hardware TnL +} GLDS_TNL; + +typedef enum { + GLDS_MULTISAMPLE_NONE = 0, + GLDS_MULTISAMPLE_FASTEST = 1, + GLDS_MULTISAMPLE_NICEST = 2, +} GLDS_MULTISAMPLE; +#endif + +typedef struct { + // Registry settings + char szDDName[MAX_DDDEVICEID_STRING]; // DirectDraw device name + char szD3DName[MAX_DDDEVICEID_STRING]; // Direct3D driver name + BOOL bPrimary; // Is ddraw device the Primary device? + BOOL bHardware; // Is the d3d driver a Hardware driver? +#ifndef _USE_GLD3_WGL + GUID ddGuid; // GUID of the ddraw device + GUID d3dGuid; // GUID of the direct3d driver +#endif // _USE_GLD3_WGL +// BOOL bFullscreen; // Force fullscreen - only useful for primary adaptors. + BOOL bSquareTextures; // Does this driver require square textures? + DWORD dwRendering; // Type of rendering required + + BOOL bWaitForRetrace; // Sync to vertical retrace + BOOL bFullscreenBlit; // Use Blt instead of Flip in fullscreen modes + + // Multitexture + BOOL bMultitexture; + + BOOL bUseMipmaps; + + DWORD dwMemoryType; // Sysmem or Vidmem + + // Global palette + BOOL bPAL8; + DDPIXELFORMAT ddpfPAL8; + + // Multitexture + WORD wMaxSimultaneousTextures; + + // Win32 internals + BOOL bAppActive; // Keep track of Alt-Tab + LONG lpfnWndProc; // WndProc of calling app + + // Pixel Format Descriptior list. + int nPixelFormatCount; + DGL_pixelFormat *lpPF; +#ifndef _USE_GLD3_WGL + // ZBuffer pixel formats + int nZBufferPFCount; // Count of Zbuffer pixel formats + DDPIXELFORMAT *lpZBufferPF; // ZBuffer pixel formats + + // Display modes (for secondary devices) + int nDisplayModeCount; + DDSURFACEDESC2 *lpDisplayModes; + + // Texture pixel formats + int nTextureFormatCount; + DGL_textureFormat *lpTextureFormat; +#endif // _USE_GLD3_WGL + // Alpha emulation via chroma key + BOOL bEmulateAlphaTest; + + // Geom pipeline override. + // If this is set TRUE then the D3D pipeline will never be used, + // and the Mesa pipline will always be used. + BOOL bForceMesaPipeline; + +#ifdef _USE_GLD3_WGL + BOOL bPixelformatsDirty; // Signal a list rebuild +#endif + + // Additional globals to support multiple GL rendering contexts, GLRCs + BOOL bDirectDraw; // DirectDraw interface exists ? + BOOL bDirectDrawPrimary; // DirectDraw primary surface exists ? + BOOL bDirect3D; // Direct3D interface exists ? + BOOL bDirect3DDevice; // Direct3D device exists ? + + BOOL bDirectDrawStereo; // DirectDraw Stereo driver started ? + int iDirectDrawStereo; // DirectDraw Stereo driver reference count + HWND hWndActive; // copy of active window + + // Copies of DirectX COM interfaces for re-referencing across multiple GLRCs +// IDirectDraw4 *lpDD4; // copy of DirectDraw interface +// IDirectDrawSurface4 *lpPrimary4; // copy of DirectDraw primary surface +// IDirectDrawSurface4 *lpBack4; +// IDirectDrawSurface4 *lpDepth4; +// IDirectDrawPalette *lpGlobalPalette; + + // Aids for heavy-duty MFC-windowed OGL apps, like AutoCAD + BOOL bMessageBoxWarnings; // popup message box warning + BOOL bDirectDrawPersistant; // DirectDraw is persisitant + BOOL bPersistantBuffers; // DirectDraw buffers persisitant + + // FPU setup option for CAD precision (AutoCAD) vs GAME speed (Quake) + BOOL bFastFPU; // single-precision-only FPU ? + + // Hot-Key support, like for real-time stereo parallax adjustments + BOOL bHotKeySupport; // hot-key support ? + + // Multi-threaded support, for apps like 3DStudio + BOOL bMultiThreaded; // multi-threaded ? + + // Detect and use app-specific customizations for apps like 3DStudio + BOOL bAppCustomizations; // app customizations ? + +#ifdef _USE_GLD3_WGL + DWORD dwAdapter; // Primary DX8 adapter + DWORD dwTnL; // MesaSW TnL + DWORD dwMultisample; // Multisample Off + DWORD dwDriver; // Direct3D HW + void *pDrvPrivate; // Driver-specific data +#endif + +} DGL_globals; + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +DGL_globals glb; + +void dglInitGlobals(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglmacros.h b/mesalib/src/mesa/drivers/windows/gldirect/dglmacros.h new file mode 100644 index 000000000..aed0f2110 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglmacros.h @@ -0,0 +1,91 @@ +/**************************************************************************** +* +* 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: Useful generic macros. +* +****************************************************************************/ + +#ifndef __DGLMACROS_H +#define __DGLMACROS_H + +#include <ddraw.h> + +// Define the relevant RELEASE macro depending on C or C++ +#if !defined(__cplusplus) || defined(CINTERFACE) + // Standard C version + #define RELEASE(x) if (x!=NULL) { x->lpVtbl->Release(x); x=NULL; } +#else + // C++ version + #define RELEASE(x) if (x!=NULL) { x->Release(); x=NULL; } +#endif + +// We don't want a message *every* time we call an unsupported function +#define UNSUPPORTED(x) \ + { \ + static BOOL bFirstTime = TRUE; \ + if (bFirstTime) { \ + bFirstTime = FALSE; \ + ddlogError(DDLOG_WARN, (x), DDERR_CURRENTLYNOTAVAIL); \ + } \ + } + +#define DGL_CHECK_CONTEXT \ + if (ctx == NULL) return; + +// Don't render if bCanRender is not TRUE. +#define DGL_CHECK_RENDER \ + if (!dgl->bCanRender) return; + +#if 0 +#define TRY(a,b) (a) +#define TRY_ERR(a,b) (a) +#else +// hResult should be defined in the function +// Return codes should be checked via SUCCEDDED and FAILED macros +#define TRY(a,b) \ + { \ + if (FAILED(hResult=(a))) \ + ddlogError(DDLOG_ERROR, (b), hResult); \ + } + +// hResult is a global +// The label exit_with_error should be defined within the calling scope +#define TRY_ERR(a,b) \ + { \ + if (FAILED(hResult=(a))) { \ + ddlogError(DDLOG_ERROR, (b), hResult); \ + goto exit_with_error; \ + } \ + } +#endif // #if 1 + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglpf.c b/mesalib/src/mesa/drivers/windows/gldirect/dglpf.c new file mode 100644 index 000000000..4cd4d0334 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglpf.c @@ -0,0 +1,620 @@ +/**************************************************************************** +* +* 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: Pixel Formats. +* +****************************************************************************/ + +#include "dglpf.h" + +#ifdef _USE_GLD3_WGL +#include "gld_driver.h" +#endif + +// *********************************************************************** + +char szColorDepthWarning[] = +"GLDirect does not support the current desktop\n\ +color depth.\n\n\ +You may need to change the display resolution to\n\ +16 bits per pixel or higher color depth using\n\ +the Windows Display Settings control panel\n\ +before running this OpenGL application.\n"; + +// *********************************************************************** +// This pixel format will be used as a template when compiling the list +// of pixel formats supported by the hardware. Many fields will be +// filled in at runtime. +// PFD flag defaults are upgraded to match ChoosePixelFormat() -- DaveM +DGL_pixelFormat pfTemplateHW = +{ + { + sizeof(PIXELFORMATDESCRIPTOR), // Size of the data structure + 1, // Structure version - should be 1 + // Flags: + PFD_DRAW_TO_WINDOW | // The buffer can draw to a window or device surface. + PFD_DRAW_TO_BITMAP | // The buffer can draw to a bitmap. (DaveM) + PFD_SUPPORT_GDI | // The buffer supports GDI drawing. (DaveM) + PFD_SUPPORT_OPENGL | // The buffer supports OpenGL drawing. + PFD_DOUBLEBUFFER | // The buffer is double-buffered. + 0, // Placeholder for easy commenting of above flags + PFD_TYPE_RGBA, // Pixel type RGBA. + 16, // Total colour bitplanes (excluding alpha bitplanes) + 5, 0, // Red bits, shift + 5, 5, // Green bits, shift + 5, 10, // Blue bits, shift + 0, 0, // Alpha bits, shift (destination alpha) + 0, // Accumulator bits (total) + 0, 0, 0, 0, // Accumulator bits: Red, Green, Blue, Alpha + 0, // Depth bits + 0, // Stencil bits + 0, // Number of auxiliary buffers + 0, // Layer type + 0, // Specifies the number of overlay and underlay planes. + 0, // Layer mask + 0, // Specifies the transparent color or index of an underlay plane. + 0 // Damage mask + }, + -1, // No depth/stencil buffer +}; + +// *********************************************************************** +// Return the count of the number of bits in a Bit Mask. +int BitCount( + DWORD dw) +{ + int i; + + if (dw == 0) + return 0; // account for non-RGB mode + + for (i=0; dw; dw=dw>>1) + i += (dw & 1); + return i; +} + +// *********************************************************************** + +DWORD BitShift( + DWORD dwMaskIn) +{ + DWORD dwShift, dwMask; + + if (dwMaskIn == 0) + return 0; // account for non-RGB mode + + for (dwShift=0, dwMask=dwMaskIn; !(dwMask&1); dwShift++, dwMask>>=1); + + return dwShift; +} + +// *********************************************************************** + +BOOL IsValidPFD(int iPFD) +{ + DGL_pixelFormat *lpPF; + + // Validate license + if (!dglValidate()) + return FALSE; + + if ((glb.lpPF == NULL) || + (glb.nPixelFormatCount == 0)) + return FALSE; + + // Check PFD range + if ( (iPFD < 1) || (iPFD > glb.nPixelFormatCount) ) { + ddlogMessage(DDLOG_ERROR, "PFD out of range\n"); + return FALSE; // PFD is invalid + } + + // Make a pointer to the pixel format + lpPF = &glb.lpPF[iPFD-1]; + + // Check size + if (lpPF->pfd.nSize != sizeof(PIXELFORMATDESCRIPTOR)) { + ddlogMessage(DDLOG_ERROR, "Bad PFD size\n"); + return FALSE; // PFD is invalid + } + + // Check version + if (lpPF->pfd.nVersion != 1) { + ddlogMessage(DDLOG_ERROR, "PFD is not Version 1\n"); + return FALSE; // PFD is invalid + } + + return TRUE; // PFD is valid +} + +// *********************************************************************** + +#ifndef _USE_GLD3_WGL + +int iEnumCount; // Enumeration count +DWORD dwDisplayBitDepth; // Bit depth of current display mode + +// *********************************************************************** + +HRESULT WINAPI EnumDisplayModesCallback( + DDSURFACEDESC2* pddsd, + void *pvContext) +{ + DWORD dwModeDepth; + DDSURFACEDESC2 *lpDisplayMode; + char buf[32]; + + // Check parameters + if (pddsd == NULL) + return DDENUMRET_CANCEL; + + dwModeDepth = pddsd->ddpfPixelFormat.dwRGBBitCount; + lpDisplayMode = (DDSURFACEDESC2 *)pvContext; + + // Check mode for compatability with device. + if (dwModeDepth != dwDisplayBitDepth) + return DDENUMRET_OK; + + if (lpDisplayMode != NULL) { + memcpy(&lpDisplayMode[iEnumCount], pddsd, sizeof(DDSURFACEDESC2)); + sprintf(buf, TEXT("Mode: %ld x %ld x %ld\n"), + pddsd->dwWidth, pddsd->dwHeight, dwModeDepth); + ddlogMessage(DDLOG_INFO, buf); + } + + iEnumCount++; + + return DDENUMRET_OK; +} + +// *********************************************************************** + +HRESULT CALLBACK d3dEnumZBufferFormatsCallback( + DDPIXELFORMAT* pddpf, + VOID* lpZBufferPF ) +{ + char buf[64]; + + if(pddpf == NULL) + return D3DENUMRET_CANCEL; + + if (pddpf->dwFlags & DDPF_ZBUFFER) { + if (lpZBufferPF == NULL) { + // Pass 1. Merely counting the PF + glb.nZBufferPFCount++; + } else { + // Pass 2. Save the PF + if (pddpf->dwFlags & DDPF_STENCILBUFFER) { + sprintf(buf, " %d: Z=%d S=%d\n", + iEnumCount, + pddpf->dwZBufferBitDepth, + pddpf->dwStencilBitDepth); + } else { + sprintf(buf, " %d: Z=%d S=0\n", + iEnumCount, + pddpf->dwZBufferBitDepth); + } + ddlogMessage(DDLOG_INFO, buf); + + memcpy(&glb.lpZBufferPF[iEnumCount++], + pddpf, + sizeof(DDPIXELFORMAT)); + } + } + + return D3DENUMRET_OK; +} +#endif // _USE_GLD3_WGL + +// *********************************************************************** + +BOOL IsStencilSupportBroken(LPDIRECTDRAW4 lpDD4) +{ + DDDEVICEIDENTIFIER dddi; // DX6 device identifier + BOOL bBroken = FALSE; + + // Microsoft really fucked up with the GetDeviceIdentifier function + // on Windows 2000, since it locks up on stock driers on the CD. Updated + // drivers from vendors appear to work, but we can't identify the drivers + // without this function!!! For now we skip these tests on Windows 2000. + if ((GetVersion() & 0x80000000UL) == 0) + return FALSE; + + // Obtain device info + if (FAILED(IDirectDraw4_GetDeviceIdentifier(lpDD4, &dddi, 0))) + return FALSE; + + // Matrox G400 stencil buffer support does not draw anything in AutoCAD, + // but ordinary Z buffers draw shaded models fine. (DaveM) + if (dddi.dwVendorId == 0x102B) { // Matrox + if (dddi.dwDeviceId == 0x0525) { // G400 + bBroken = TRUE; + } + } + + return bBroken; +} + +// *********************************************************************** + +void dglBuildPixelFormatList() +{ + int i; + char buf[128]; + char cat[8]; + DGL_pixelFormat *lpPF; + +#ifdef _USE_GLD3_WGL + _gldDriver.BuildPixelformatList(); +#else + HRESULT hRes; + IDirectDraw *lpDD1 = NULL; + IDirectDraw4 *lpDD4 = NULL; + IDirect3D3 *lpD3D3 = NULL; + DDSURFACEDESC2 ddsdDisplayMode; + + DWORD dwRb, dwGb, dwBb, dwAb; // Bit counts + DWORD dwRs, dwGs, dwBs, dwAs; // Bit shifts + DWORD dwPixelType; // RGB or color index + + // Set defaults + glb.nPixelFormatCount = 0; + glb.lpPF = NULL; + glb.nZBufferPFCount = 0; + glb.lpZBufferPF = NULL; + glb.nDisplayModeCount = 0; + glb.lpDisplayModes = NULL; + + // + // Examine the hardware for depth and stencil + // + + if (glb.bPrimary) + hRes = DirectDrawCreate(NULL, &lpDD1, NULL); + else + hRes = DirectDrawCreate(&glb.ddGuid, &lpDD1, NULL); + + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: DirectDrawCreate failed", hRes); + return; + } + + // Query for DX6 IDirectDraw4. + hRes = IDirectDraw_QueryInterface( + lpDD1, + &IID_IDirectDraw4, + (void**)&lpDD4); + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: QueryInterface (DD4) failed", hRes); + goto clean_up; + } + + + // Retrieve caps of current display mode + ZeroMemory(&ddsdDisplayMode, sizeof(ddsdDisplayMode)); + ddsdDisplayMode.dwSize = sizeof(ddsdDisplayMode); + hRes = IDirectDraw4_GetDisplayMode(lpDD4, &ddsdDisplayMode); + if (FAILED(hRes)) + goto clean_up; + + dwDisplayBitDepth = ddsdDisplayMode.ddpfPixelFormat.dwRGBBitCount; + dwPixelType = (dwDisplayBitDepth <= 8) ? PFD_TYPE_COLORINDEX : PFD_TYPE_RGBA; + dwRb = BitCount(ddsdDisplayMode.ddpfPixelFormat.dwRBitMask); + dwGb = BitCount(ddsdDisplayMode.ddpfPixelFormat.dwGBitMask); + dwBb = BitCount(ddsdDisplayMode.ddpfPixelFormat.dwBBitMask); + dwRs = BitShift(ddsdDisplayMode.ddpfPixelFormat.dwRBitMask); + dwGs = BitShift(ddsdDisplayMode.ddpfPixelFormat.dwGBitMask); + dwBs = BitShift(ddsdDisplayMode.ddpfPixelFormat.dwBBitMask); + + if (BitCount(ddsdDisplayMode.ddpfPixelFormat.dwRGBAlphaBitMask)) { + dwAb = BitCount(ddsdDisplayMode.ddpfPixelFormat.dwRGBAlphaBitMask); + dwAs = BitShift(ddsdDisplayMode.ddpfPixelFormat.dwRGBAlphaBitMask); + } else { + dwAb = 0; + dwAs = 0; + } + + // Query for available display modes + ddlogMessage(DDLOG_INFO, "\n"); + ddlogMessage(DDLOG_INFO, "Display Modes:\n"); + + // Pass 1: Determine count + iEnumCount = 0; + hRes = IDirectDraw4_EnumDisplayModes( + lpDD4, + 0, + NULL, + NULL, + EnumDisplayModesCallback); + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: EnumDisplayModes failed", hRes); + goto clean_up; + } + if (iEnumCount == 0) { + ddlogMessage(DDLOG_ERROR, "dglBPFL: No display modes found"); + goto clean_up; + } + glb.lpDisplayModes = (DDSURFACEDESC2 *)calloc(iEnumCount, + sizeof(DDSURFACEDESC2)); + if (glb.lpDisplayModes == NULL) { + ddlogMessage(DDLOG_ERROR, "dglBPFL: DDSURFACEDESC2 calloc failed"); + goto clean_up; + } + glb.nDisplayModeCount = iEnumCount; + // Pass 2: Save modes + iEnumCount = 0; + hRes = IDirectDraw4_EnumDisplayModes( + lpDD4, + 0, + NULL, + (void *)glb.lpDisplayModes, + EnumDisplayModesCallback); + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: EnumDisplayModes failed", hRes); + goto clean_up; + } + // Query for IDirect3D3 interface + hRes = IDirectDraw4_QueryInterface( + lpDD4, + &IID_IDirect3D3, + (void**)&lpD3D3); + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: QueryInterface (D3D3) failed", hRes); + goto clean_up; + } + + ddlogMessage(DDLOG_INFO, "\n"); + ddlogMessage(DDLOG_INFO, "ZBuffer formats:\n"); + + // Pass 1. Count the ZBuffer pixel formats + hRes = IDirect3D3_EnumZBufferFormats( + lpD3D3, + &glb.d3dGuid, + d3dEnumZBufferFormatsCallback, + NULL); + + if (FAILED(hRes)) + goto clean_up; + + if (glb.nZBufferPFCount) { + glb.lpZBufferPF = (DDPIXELFORMAT *)calloc(glb.nZBufferPFCount, + sizeof(DDPIXELFORMAT)); + if(glb.lpZBufferPF == NULL) + goto clean_up; + + // Pass 2. Cache the ZBuffer pixel formats + iEnumCount = 0; // (Used by the enum function) + hRes = IDirect3D3_EnumZBufferFormats( + lpD3D3, + &glb.d3dGuid, + d3dEnumZBufferFormatsCallback, + glb.lpZBufferPF); + + if (FAILED(hRes)) + goto clean_up; + } + + // Remove stencil support for boards which don't work for AutoCAD; + // Matrox G400 does not work, but NVidia TNT2 and ATI Rage128 do... (DaveM) + if (IsStencilSupportBroken(lpDD4)) { + for (i=0; i<iEnumCount; i++) + if (glb.lpZBufferPF[i].dwFlags & DDPF_STENCILBUFFER) + glb.nZBufferPFCount--; + } + + // One each for every ZBuffer pixel format (including no depth buffer) + // Times-two because duplicated for single buffering (as opposed to double) + glb.nPixelFormatCount = 2 * (glb.nZBufferPFCount + 1); + glb.lpPF = (DGL_pixelFormat *)calloc(glb.nPixelFormatCount, + sizeof(DGL_pixelFormat)); + if (glb.lpPF == NULL) + goto clean_up; + // + // Fill in the pixel formats + // Note: Depth buffer bits are really (dwZBufferBitDepth-dwStencilBitDepth) + // but this will pass wierd numbers to the OpenGL app. (?) + // + + pfTemplateHW.pfd.iPixelType = dwPixelType; + pfTemplateHW.pfd.cColorBits = dwDisplayBitDepth; + pfTemplateHW.pfd.cRedBits = dwRb; + pfTemplateHW.pfd.cGreenBits = dwGb; + pfTemplateHW.pfd.cBlueBits = dwBb; + pfTemplateHW.pfd.cAlphaBits = dwAb; + pfTemplateHW.pfd.cRedShift = dwRs; + pfTemplateHW.pfd.cGreenShift = dwGs; + pfTemplateHW.pfd.cBlueShift = dwBs; + pfTemplateHW.pfd.cAlphaShift = dwAs; + + lpPF = glb.lpPF; + + // Fill in the double-buffered pixel formats + for (i=0; i<(glb.nZBufferPFCount + 1); i++, lpPF++) { + memcpy(lpPF, &pfTemplateHW, sizeof(DGL_pixelFormat)); + if (i) { + lpPF->iZBufferPF = i-1; + lpPF->pfd.cDepthBits = glb.lpZBufferPF[i-1].dwZBufferBitDepth; + lpPF->pfd.cStencilBits = glb.lpZBufferPF[i-1].dwStencilBitDepth; + } + } + // Fill in the single-buffered pixel formats + for (i=0; i<(glb.nZBufferPFCount + 1); i++, lpPF++) { + memcpy(lpPF, &pfTemplateHW, sizeof(DGL_pixelFormat)); + if (i) { + lpPF->iZBufferPF = i-1; + lpPF->pfd.cDepthBits = glb.lpZBufferPF[i-1].dwZBufferBitDepth; + lpPF->pfd.cStencilBits = glb.lpZBufferPF[i-1].dwStencilBitDepth; + } + // Remove double-buffer flag. Could use XOR instead... + lpPF->pfd.dwFlags &= (~(PFD_DOUBLEBUFFER)); + // Insert GDI flag for single buffered format only. + lpPF->pfd.dwFlags |= PFD_SUPPORT_GDI; + } +#endif // _USE_GLD3_WGL + + // Lets dump the list to the log + // ** Based on "wglinfo" by Nate Robins ** + ddlogMessage(DDLOG_INFO, "\n"); + ddlogMessage(DDLOG_INFO, "Pixel Formats:\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"); + for (i=0, lpPF = glb.lpPF; i<glb.nPixelFormatCount; i++, lpPF++) { + sprintf(buf, "0x%02x ", i+1); + + sprintf(cat, "%2d ", lpPF->pfd.cColorBits); + strcat(buf, cat); + if(lpPF->pfd.dwFlags & PFD_DRAW_TO_WINDOW) sprintf(cat, "wn "); + else if(lpPF->pfd.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 ", lpPF->pfd.cColorBits); + strcat(buf, cat); + + /* bReserved field indicates number of over/underlays */ + if(lpPF->pfd.bReserved) sprintf(cat, " %d ", lpPF->pfd.bReserved); + else sprintf(cat, " . "); + strcat(buf, cat); + + sprintf(cat, " %c ", lpPF->pfd.iPixelType == PFD_TYPE_RGBA ? 'r' : 'c'); + strcat(buf, cat); + + sprintf(cat, "%c ", lpPF->pfd.dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.'); + strcat(buf, cat); + + sprintf(cat, " %c ", lpPF->pfd.dwFlags & PFD_STEREO ? 'y' : '.'); + strcat(buf, cat); + + if(lpPF->pfd.cRedBits && lpPF->pfd.iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", lpPF->pfd.cRedBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cGreenBits && lpPF->pfd.iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", lpPF->pfd.cGreenBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cBlueBits && lpPF->pfd.iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", lpPF->pfd.cBlueBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAlphaBits && lpPF->pfd.iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", lpPF->pfd.cAlphaBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAuxBuffers) sprintf(cat, "%2d ", lpPF->pfd.cAuxBuffers); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cDepthBits) sprintf(cat, "%2d ", lpPF->pfd.cDepthBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cStencilBits) sprintf(cat, "%2d ", lpPF->pfd.cStencilBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAccumRedBits) sprintf(cat, "%2d ", lpPF->pfd.cAccumRedBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAccumGreenBits) sprintf(cat, "%2d ", lpPF->pfd.cAccumGreenBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAccumBlueBits) sprintf(cat, "%2d ", lpPF->pfd.cAccumBlueBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAccumAlphaBits) sprintf(cat, "%2d ", lpPF->pfd.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"); + +#ifndef _USE_GLD3_WGL +clean_up: + // Release COM objects + RELEASE(lpD3D3); + RELEASE(lpDD4); + RELEASE(lpDD1); + + // Popup warning message if non RGB color mode + if (dwDisplayBitDepth <= 8) { + ddlogPrintf(DDLOG_WARN, "Current Color Depth %d bpp is not supported", dwDisplayBitDepth); + MessageBox(NULL, szColorDepthWarning, "GLDirect", MB_OK | MB_ICONWARNING); + } +#endif // _USE_GLD3_WGL +} + +// *********************************************************************** + +void dglReleasePixelFormatList() +{ + glb.nPixelFormatCount = 0; + if (glb.lpPF) { + free(glb.lpPF); + glb.lpPF = NULL; + } +#ifndef _USE_GLD3_WGL + glb.nZBufferPFCount = 0; + if (glb.lpZBufferPF) { + free(glb.lpZBufferPF); + glb.lpZBufferPF = NULL; + } + glb.nDisplayModeCount = 0; + if (glb.lpDisplayModes) { + free(glb.lpDisplayModes); + glb.lpDisplayModes = NULL; + } +#endif // _USE_GLD3_WGL +} + +// *********************************************************************** diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglpf.h b/mesalib/src/mesa/drivers/windows/gldirect/dglpf.h new file mode 100644 index 000000000..8a7e38c4b --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglpf.h @@ -0,0 +1,77 @@ +/**************************************************************************** +* +* 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: Pixel Formats. +* +****************************************************************************/ + +#ifndef __DGLPF_H +#define __DGLPF_H + +#ifndef STRICT +#define STRICT +#endif // STRICT +#define WIN32_LEAN_AND_MEAN + +#include <windows.h> + +/*---------------------- Macros and type definitions ----------------------*/ + +typedef struct { + PIXELFORMATDESCRIPTOR pfd; // Win32 Pixel Format Descriptor +#ifdef _USE_GLD3_WGL + // Driver-specific data. + // Example: The DX8 driver uses this to hold an index into a + // list of depth-stencil descriptions. + DWORD dwDriverData; +#else + int iZBufferPF; // Index of depth buffer pixel format +#endif +} DGL_pixelFormat; + +#include "dglglobals.h" + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +BOOL IsValidPFD(int iPFD); +void dglBuildPixelFormatList(); +void dglReleasePixelFormatList(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglwgl.c b/mesalib/src/mesa/drivers/windows/gldirect/dglwgl.c new file mode 100644 index 000000000..74ecb01a5 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglwgl.c @@ -0,0 +1,2964 @@ +/**************************************************************************** +* +* 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( + GLcontext *ctx1, + GLcontext *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( + GLcontext *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; +} + +// *********************************************************************** + diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglwgl.h b/mesalib/src/mesa/drivers/windows/gldirect/dglwgl.h new file mode 100644 index 000000000..aac041033 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglwgl.h @@ -0,0 +1,127 @@ +/**************************************************************************** +* +* 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*). +* +****************************************************************************/ + +#ifndef __DGLWGL_H +#define __DGLWGL_H + +// Disable compiler complaints about DLL linkage +#pragma warning (disable:4273) + +// Macros to control compilation +#define STRICT +#define WIN32_LEAN_AND_MEAN + +#include <windows.h> +#include <GL\gl.h> + +#include "dglcontext.h" +#include "dglglobals.h" +#include "dglmacros.h" +#include "ddlog.h" +#include "dglpf.h" + +/*---------------------- Macros and type definitions ----------------------*/ + +typedef struct { + PROC proc; + char *name; +} DGL_extension; + +#ifndef __MINGW32__ +/* XXX why is this here? + * It should probaby be somewhere in src/mesa/drivers/windows/ + */ +#if defined(_WIN32) && !defined(_WINGDI_) && !defined(_WINGDI_H) && !defined(_GNU_H_WINDOWS32_DEFINES) && !defined(OPENSTEP) && !defined(BUILD_FOR_SNAP) +# define WGL_FONT_LINES 0 +# define WGL_FONT_POLYGONS 1 +#ifndef _GNU_H_WINDOWS32_FUNCTIONS +# ifdef UNICODE +# define wglUseFontBitmaps wglUseFontBitmapsW +# define wglUseFontOutlines wglUseFontOutlinesW +# else +# define wglUseFontBitmaps wglUseFontBitmapsA +# define wglUseFontOutlines wglUseFontOutlinesA +# endif /* !UNICODE */ +#endif /* _GNU_H_WINDOWS32_FUNCTIONS */ +typedef struct tagLAYERPLANEDESCRIPTOR LAYERPLANEDESCRIPTOR, *PLAYERPLANEDESCRIPTOR, *LPLAYERPLANEDESCRIPTOR; +typedef struct _GLYPHMETRICSFLOAT GLYPHMETRICSFLOAT, *PGLYPHMETRICSFLOAT, *LPGLYPHMETRICSFLOAT; +typedef struct tagPIXELFORMATDESCRIPTOR PIXELFORMATDESCRIPTOR, *PPIXELFORMATDESCRIPTOR, *LPPIXELFORMATDESCRIPTOR; +#if !defined(GLX_USE_MESA) +#include <GL/mesa_wgl.h> +#endif +#endif +#endif /* !__MINGW32__ */ + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _USE_GLD3_WGL +int APIENTRY DGL_ChoosePixelFormat(HDC a, CONST PIXELFORMATDESCRIPTOR *ppfd); +BOOL APIENTRY DGL_CopyContext(HGLRC a, HGLRC b, UINT c); +HGLRC APIENTRY DGL_CreateContext(HDC a); +HGLRC APIENTRY DGL_CreateLayerContext(HDC a, int b); +BOOL APIENTRY DGL_DeleteContext(HGLRC a); +BOOL APIENTRY DGL_DescribeLayerPlane(HDC a, int b, int c, UINT d, LPLAYERPLANEDESCRIPTOR e); +int APIENTRY DGL_DescribePixelFormat(HDC a, int b, UINT c, LPPIXELFORMATDESCRIPTOR d); +HGLRC APIENTRY DGL_GetCurrentContext(void); +HDC APIENTRY DGL_GetCurrentDC(void); +PROC APIENTRY DGL_GetDefaultProcAddress(LPCSTR a); +int APIENTRY DGL_GetLayerPaletteEntries(HDC a, int b, int c, int d, COLORREF *e); +int APIENTRY DGL_GetPixelFormat(HDC a); +PROC APIENTRY DGL_GetProcAddress(LPCSTR a); +BOOL APIENTRY DGL_MakeCurrent(HDC a, HGLRC b); +BOOL APIENTRY DGL_RealizeLayerPalette(HDC a, int b, BOOL c); +int APIENTRY DGL_SetLayerPaletteEntries(HDC a, int b, int c, int d, CONST COLORREF *e); +BOOL APIENTRY DGL_SetPixelFormat(HDC a, int b, CONST PIXELFORMATDESCRIPTOR *c); +BOOL APIENTRY DGL_ShareLists(HGLRC a, HGLRC b); +BOOL APIENTRY DGL_SwapBuffers(HDC a); +BOOL APIENTRY DGL_SwapLayerBuffers(HDC a, UINT b); +BOOL APIENTRY DGL_UseFontBitmapsA(HDC a, DWORD b, DWORD c, DWORD d); +BOOL APIENTRY DGL_UseFontBitmapsW(HDC a, DWORD b, DWORD c, DWORD d); +BOOL APIENTRY DGL_UseFontOutlinesA(HDC a, DWORD b, DWORD c, DWORD d, FLOAT e, FLOAT f, int g, LPGLYPHMETRICSFLOAT h); +BOOL APIENTRY DGL_UseFontOutlinesW(HDC a, DWORD b, DWORD c, DWORD d, FLOAT e, FLOAT f, int g, LPGLYPHMETRICSFLOAT h); +#endif //_USE_GLD3_WGL + +BOOL dglWglResizeBuffers(GLcontext *ctx, BOOL bDefaultDriver); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dll_main.c b/mesalib/src/mesa/drivers/windows/gldirect/dll_main.c new file mode 100644 index 000000000..1d7ac64f4 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dll_main.c @@ -0,0 +1,817 @@ +/**************************************************************************** +* +* 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: Win32 DllMain functions. +* +****************************************************************************/ + +// INITGUID must only be defined once. +// Don't put it in a shared header file! +// GLD3 uses dxguid.lib, so INITGUID must *not* be used! +#ifndef _USE_GLD3_WGL +#define INITGUID +#endif // _USE_GLD3_WGL + +#include "dllmain.h" + +//#include "snap/graphics.h" +//#include "drvlib/os/os.h" + +#ifdef _USE_GLD3_WGL +typedef void (APIENTRY *LPDGLSPLASHSCREEN)(int, int, char*); +#include "gld_driver.h" +#endif + +// *********************************************************************** + +BOOL bInitialized = FALSE; // callback driver initialized? +BOOL bExited = FALSE; // callback driver exited this instance? +HINSTANCE hInstanceDll = NULL; // DLL instance handle + +static BOOL bDriverValidated = FALSE; // prior validation status +static BOOL bSplashScreen = TRUE; // Splash Screen ? +static BOOL bValidINIFound = FALSE; // Have we found a valid INI file? + +HHOOK hKeyHook = NULL; // global keyboard handler hook + +// Multi-threaded support needs to be reflected in Mesa code. (DaveM) +int _gld_bMultiThreaded = FALSE; + +// *********************************************************************** + +DWORD dwLogging = 0; // Logging flag +DWORD dwDebugLevel = 0; // Log debug level + +char szLogPath[_MAX_PATH] = {"\0"}; // Log file path +char szSNAPPath[_MAX_PATH] = {"\0"}; // SNAP driver path + +#ifndef _USE_GLD3_WGL +DGL_wglFuncs wglFuncs = { + sizeof(DGL_wglFuncs), + DGL_ChoosePixelFormat, + DGL_CopyContext, + DGL_CreateContext, + DGL_CreateLayerContext, + DGL_DeleteContext, + DGL_DescribeLayerPlane, + DGL_DescribePixelFormat, + DGL_GetCurrentContext, + DGL_GetCurrentDC, + DGL_GetDefaultProcAddress, + DGL_GetLayerPaletteEntries, + DGL_GetPixelFormat, + DGL_GetProcAddress, + DGL_MakeCurrent, + DGL_RealizeLayerPalette, + DGL_SetLayerPaletteEntries, + DGL_SetPixelFormat, + DGL_ShareLists, + DGL_SwapBuffers, + DGL_SwapLayerBuffers, + DGL_UseFontBitmapsA, + DGL_UseFontBitmapsW, + DGL_UseFontOutlinesA, + DGL_UseFontOutlinesW, +}; + +DGL_mesaFuncs mesaFuncs = { + sizeof(DGL_mesaFuncs), +}; +#endif // _USE_GLD3_WGL + +// *********************************************************************** + +typedef struct { + DWORD dwDriver; // 0=SciTech SW, 1=Direct3D SW, 2=Direct3D HW + BOOL bMipmapping; // 0=off, 1=on + BOOL bMultitexture; // 0=off, 1=on + BOOL bWaitForRetrace; // 0=off, 1=on + BOOL bFullscreenBlit; // 0=off, 1=on + BOOL bFastFPU; // 0=off, 1=on + BOOL bDirectDrawPersistant;// 0=off, 1=on + BOOL bPersistantBuffers; // 0=off, 1=on + DWORD dwLogging; // 0=off, 1=normal, 2=crash-proof + DWORD dwLoggingSeverity; // 0=all, 1=warnings+errors, 2=errors only + BOOL bMessageBoxWarnings;// 0=off, 1=on + BOOL bMultiThreaded; // 0=off, 1=on + BOOL bAppCustomizations; // 0=off, 1=on + BOOL bHotKeySupport; // 0=off, 1=on + BOOL bSplashScreen; // 0=off, 1=on + +#ifdef _USE_GLD3_WGL + // + // New for GLDirect 3.0 + // + DWORD dwAdapter; // DX8 adpater ordinal + DWORD dwTnL; // Transform & Lighting type + DWORD dwMultisample; // DX8 multisample type +#endif // _USE_GLD3_WGL +} INI_settings; + +static INI_settings ini; + +// *********************************************************************** + +BOOL APIENTRY DGL_initDriver( +#ifdef _USE_GLD3_WGL + void) +{ +#else + DGL_wglFuncs *lpWglFuncs, + DGL_mesaFuncs *lpMesaFuncs) +{ + // Check for valid pointers + if ((lpWglFuncs == NULL) || (lpMesaFuncs == NULL)) + return FALSE; + + // Check for valid structs + if (lpWglFuncs->dwSize != sizeof(DGL_wglFuncs)) { + return FALSE; + } + + // Check for valid structs + if (lpMesaFuncs->dwSize != sizeof(DGL_mesaFuncs)) { + return FALSE; + } + + // Copy the Mesa functions + memcpy(&mesaFuncs, lpMesaFuncs, sizeof(DGL_mesaFuncs)); + + // Pass back the wgl functions + memcpy(lpWglFuncs, &wglFuncs, sizeof(DGL_wglFuncs)); +#endif // _USE_GLD3_WGL + + // Finally initialize the callback driver + if (!dglInitDriver()) + return FALSE; + + return TRUE; +}; + +// *********************************************************************** + +BOOL ReadINIFile( + HINSTANCE hInstance) +{ + char szModuleFilename[MAX_PATH]; + char szSystemDirectory[MAX_PATH]; + const char szSectionName[] = "Config"; + char szINIFile[MAX_PATH]; + int pos; + + // Now using the DLL module handle. KeithH, 24/May/2000. + // Addendum: GetModuleFileName(NULL, ... returns process filename, + // GetModuleFileName(hModule, ... returns DLL filename, + + // Get the dll path and filename. + GetModuleFileName(hInstance, &szModuleFilename[0], MAX_PATH); // NULL for current process + // Get the System directory. + GetSystemDirectory(&szSystemDirectory[0], MAX_PATH); + + // Test to see if DLL is in system directory. + if (strnicmp(szModuleFilename, szSystemDirectory, strlen(szSystemDirectory))==0) { + // DLL *is* in system directory. + // Return FALSE to indicate that registry keys should be read. + return FALSE; + } + + // Compose filename of INI file + strcpy(szINIFile, szModuleFilename); + pos = strlen(szINIFile); + while (szINIFile[pos] != '\\') { + pos--; + } + szINIFile[pos+1] = '\0'; + // Use run-time DLL path for log file too + strcpy(szLogPath, szINIFile); + szLogPath[pos] = '\0'; + // Complete full INI file path + strcat(szINIFile, "gldirect.ini"); + + // Read settings from private INI file. + // Note that defaults are contained in the calls. + ini.dwDriver = GetPrivateProfileInt(szSectionName, "dwDriver", 2, szINIFile); + ini.bMipmapping = GetPrivateProfileInt(szSectionName, "bMipmapping", 1, szINIFile); + ini.bMultitexture = GetPrivateProfileInt(szSectionName, "bMultitexture", 1, szINIFile); + ini.bWaitForRetrace = GetPrivateProfileInt(szSectionName, "bWaitForRetrace", 0, szINIFile); + ini.bFullscreenBlit = GetPrivateProfileInt(szSectionName, "bFullscreenBlit", 0, szINIFile); + ini.bFastFPU = GetPrivateProfileInt(szSectionName, "bFastFPU", 1, szINIFile); + ini.bDirectDrawPersistant = GetPrivateProfileInt(szSectionName, "bPersistantDisplay", 0, szINIFile); + ini.bPersistantBuffers = GetPrivateProfileInt(szSectionName, "bPersistantResources", 0, szINIFile); + ini.dwLogging = GetPrivateProfileInt(szSectionName, "dwLogging", 0, szINIFile); + ini.dwLoggingSeverity = GetPrivateProfileInt(szSectionName, "dwLoggingSeverity", 0, szINIFile); + ini.bMessageBoxWarnings = GetPrivateProfileInt(szSectionName, "bMessageBoxWarnings", 0, szINIFile); + ini.bMultiThreaded = GetPrivateProfileInt(szSectionName, "bMultiThreaded", 0, szINIFile); + ini.bAppCustomizations = GetPrivateProfileInt(szSectionName, "bAppCustomizations", 1, szINIFile); + ini.bHotKeySupport = GetPrivateProfileInt(szSectionName, "bHotKeySupport", 0, szINIFile); + ini.bSplashScreen = GetPrivateProfileInt(szSectionName, "bSplashScreen", 1, szINIFile); + +#ifdef _USE_GLD3_WGL + // New for GLDirect 3.x + ini.dwAdapter = GetPrivateProfileInt(szSectionName, "dwAdapter", 0, szINIFile); + // dwTnL now defaults to zero (chooses TnL at runtime). KeithH + ini.dwTnL = GetPrivateProfileInt(szSectionName, "dwTnL", 0, szINIFile); + ini.dwMultisample = GetPrivateProfileInt(szSectionName, "dwMultisample", 0, szINIFile); +#endif + + return TRUE; +} + +// *********************************************************************** + +BOOL dllReadRegistry( + HINSTANCE hInstance) +{ + // Read settings from INI file, if available + bValidINIFound = FALSE; + if (ReadINIFile(hInstance)) { + const char *szRendering[3] = { + "SciTech Software Renderer", + "Direct3D MMX Software Renderer", + "Direct3D Hardware Renderer" + }; + // Set globals + glb.bPrimary = 1; + glb.bHardware = (ini.dwDriver == 2) ? 1 : 0; +#ifndef _USE_GLD3_WGL + memset(&glb.ddGuid, 0, sizeof(glb.ddGuid)); + glb.d3dGuid = (ini.dwDriver == 2) ? IID_IDirect3DHALDevice : IID_IDirect3DRGBDevice; +#endif // _USE_GLD3_WGL + strcpy(glb.szDDName, "Primary"); + strcpy(glb.szD3DName, szRendering[ini.dwDriver]); + glb.dwRendering = ini.dwDriver; + glb.bUseMipmaps = ini.bMipmapping; + glb.bMultitexture = ini.bMultitexture; + glb.bWaitForRetrace = ini.bWaitForRetrace; + glb.bFullscreenBlit = ini.bFullscreenBlit; + glb.bFastFPU = ini.bFastFPU; + glb.bDirectDrawPersistant = ini.bDirectDrawPersistant; + glb.bPersistantBuffers = ini.bPersistantBuffers; + dwLogging = ini.dwLogging; + dwDebugLevel = ini.dwLoggingSeverity; + glb.bMessageBoxWarnings = ini.bMessageBoxWarnings; + glb.bMultiThreaded = ini.bMultiThreaded; + glb.bAppCustomizations = ini.bAppCustomizations; + glb.bHotKeySupport = ini.bHotKeySupport; + bSplashScreen = ini.bSplashScreen; +#ifdef _USE_GLD3_WGL + // New for GLDirect 3.x + glb.dwAdapter = ini.dwAdapter; + glb.dwDriver = ini.dwDriver; + glb.dwTnL = ini.dwTnL; + glb.dwMultisample = ini.dwMultisample; +#endif + bValidINIFound = TRUE; + return TRUE; + } + // Read settings from registry + else { + HKEY hReg; + DWORD cbValSize; + DWORD dwType = REG_SZ; // Registry data type for strings + BOOL bRegistryError; + BOOL bSuccess; + +#define REG_READ_DWORD(a, b) \ + cbValSize = sizeof(b); \ + if (ERROR_SUCCESS != RegQueryValueEx( hReg, (a), \ + NULL, NULL, (LPBYTE)&(b), &cbValSize )) \ + bRegistryError = TRUE; + +#define REG_READ_DEVICEID(a, b) \ + cbValSize = MAX_DDDEVICEID_STRING; \ + if(ERROR_SUCCESS != RegQueryValueEx(hReg, (a), 0, &dwType, \ + (LPBYTE)&(b), &cbValSize)) \ + bRegistryError = TRUE; + +#define REG_READ_STRING(a, b) \ + cbValSize = sizeof((b)); \ + if(ERROR_SUCCESS != RegQueryValueEx(hReg, (a), 0, &dwType, \ + (LPBYTE)&(b), &cbValSize)) \ + bRegistryError = TRUE; + + // Read settings from the registry. + + // Open the registry key for the current user if it exists. + bSuccess = (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, + DIRECTGL_REG_SETTINGS_KEY, + 0, + KEY_READ, + &hReg)); + // Otherwise open the registry key for the local machine. + if (!bSuccess) + bSuccess = (ERROR_SUCCESS == RegOpenKeyEx(DIRECTGL_REG_KEY_ROOT, + DIRECTGL_REG_SETTINGS_KEY, + 0, + KEY_READ, + &hReg)); + if (!bSuccess) + return FALSE; + + bRegistryError = FALSE; + + REG_READ_DWORD(DIRECTGL_REG_SETTING_PRIMARY, glb.bPrimary); + REG_READ_DWORD(DIRECTGL_REG_SETTING_D3D_HW, glb.bHardware); +#ifndef _USE_GLD3_WGL + REG_READ_DWORD(DIRECTGL_REG_SETTING_DD_GUID, glb.ddGuid); + REG_READ_DWORD(DIRECTGL_REG_SETTING_D3D_GUID, glb.d3dGuid); +#endif // _USE_GLD3_WGL + REG_READ_DWORD(DIRECTGL_REG_SETTING_LOGGING, dwLogging); + REG_READ_DWORD(DIRECTGL_REG_SETTING_DEBUGLEVEL, dwDebugLevel); + REG_READ_DWORD(DIRECTGL_REG_SETTING_RENDERING, glb.dwRendering); + REG_READ_DWORD(DIRECTGL_REG_SETTING_MULTITEXTURE, glb.bMultitexture); + REG_READ_DWORD(DIRECTGL_REG_SETTING_WAITFORRETRACE, glb.bWaitForRetrace); + REG_READ_DWORD(DIRECTGL_REG_SETTING_FULLSCREENBLIT, glb.bFullscreenBlit); + REG_READ_DWORD(DIRECTGL_REG_SETTING_USEMIPMAPS, glb.bUseMipmaps); + + REG_READ_DEVICEID(DIRECTGL_REG_SETTING_DD_NAME, glb.szDDName); + REG_READ_DEVICEID(DIRECTGL_REG_SETTING_D3D_NAME, glb.szD3DName); + + REG_READ_DWORD(DIRECTGL_REG_SETTING_MSGBOXWARNINGS, glb.bMessageBoxWarnings); + REG_READ_DWORD(DIRECTGL_REG_SETTING_PERSISTDISPLAY, glb.bDirectDrawPersistant); + REG_READ_DWORD(DIRECTGL_REG_SETTING_PERSISTBUFFERS, glb.bPersistantBuffers); + REG_READ_DWORD(DIRECTGL_REG_SETTING_FASTFPU, glb.bFastFPU); + REG_READ_DWORD(DIRECTGL_REG_SETTING_HOTKEYS, glb.bHotKeySupport); + REG_READ_DWORD(DIRECTGL_REG_SETTING_MULTITHREAD, glb.bMultiThreaded); + REG_READ_DWORD(DIRECTGL_REG_SETTING_APPCUSTOM, glb.bAppCustomizations); + REG_READ_DWORD(DIRECTGL_REG_SETTING_SPLASHSCREEN, bSplashScreen); + +#ifdef _USE_GLD3_WGL + // New for GLDirect 3.x + glb.dwDriver = glb.dwRendering; + REG_READ_DWORD(DIRECTGL_REG_SETTING_ADAPTER, glb.dwAdapter); + REG_READ_DWORD(DIRECTGL_REG_SETTING_TNL, glb.dwTnL); + REG_READ_DWORD(DIRECTGL_REG_SETTING_MULTISAMPLE, glb.dwMultisample); +#endif + + RegCloseKey(hReg); + + // Open the global registry key for GLDirect + bSuccess = (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, + DIRECTGL_REG_SETTINGS_KEY, + 0, + KEY_READ, + &hReg)); + if (bSuccess) { + // Read the installation path for GLDirect + REG_READ_STRING("InstallLocation",szLogPath); + RegCloseKey(hReg); + } + + if (bRegistryError || !bSuccess) + return FALSE; + else + + return TRUE; + +#undef REG_READ_DWORD +#undef REG_READ_DEVICEID +#undef REG_READ_STRING + } +} + +// *********************************************************************** + +BOOL dllWriteRegistry( + void ) +{ + HKEY hReg; + DWORD dwCreateDisposition, cbValSize; + BOOL bRegistryError = FALSE; + +#define REG_WRITE_DWORD(a, b) \ + cbValSize = sizeof(b); \ + if (ERROR_SUCCESS != RegSetValueEx( hReg, (a), \ + 0, REG_DWORD, (LPBYTE)&(b), cbValSize )) \ + bRegistryError = TRUE; + + if (ERROR_SUCCESS == RegCreateKeyEx( DIRECTGL_REG_KEY_ROOT, DIRECTGL_REG_SETTINGS_KEY, + 0, NULL, 0, KEY_WRITE, NULL, &hReg, + &dwCreateDisposition )) { + RegFlushKey(hReg); // Make sure keys are written to disk + RegCloseKey(hReg); + hReg = NULL; + } + + if (bRegistryError) + return FALSE; + else + return TRUE; + +#undef REG_WRITE_DWORD +} + +// *********************************************************************** + +void dglInitHotKeys(HINSTANCE hInstance) +{ + // Hot-Key support at all? + if (!glb.bHotKeySupport) + return; + + // Install global keyboard interceptor + hKeyHook = SetWindowsHookEx(WH_KEYBOARD, dglKeyProc, hInstance, 0); +} + +// *********************************************************************** + +void dglExitHotKeys(void) +{ + // Hot-Key support at all? + if (!glb.bHotKeySupport) + return; + + // Remove global keyboard interceptor + if (hKeyHook) + UnhookWindowsHookEx(hKeyHook); + hKeyHook = NULL; +} + +// *********************************************************************** + +// Note: This app-customization step must be performed in both the main +// OpenGL32 driver and the callback driver DLLs for multithreading option. +void dglSetAppCustomizations(void) +{ + char szModuleFileName[MAX_PATH]; + int iSize = MAX_PATH; + + // Get the currently loaded EXE filename. + GetModuleFileName(NULL, &szModuleFileName[0], MAX_PATH); // NULL for current process + strupr(szModuleFileName); + iSize = strlen(szModuleFileName); + + // Check for specific EXEs and adjust global settings accordingly + + // NOTE: In GLD3.x "bDirectDrawPersistant" corresponds to IDirect3D8 and + // "bPersistantBuffers" corresponds to IDirect3DDevice8. KeithH + + // Case 1: 3DStudio must be multi-threaded + // Added: Discreet GMAX (3DStudio MAX 4 for gamers. KeithH) + if (strstr(szModuleFileName, "3DSMAX.EXE") + || strstr(szModuleFileName, "3DSVIZ.EXE") + || strstr(szModuleFileName, "GMAX.EXE")) { + glb.bMultiThreaded = TRUE; + glb.bDirectDrawPersistant = FALSE; + glb.bPersistantBuffers = FALSE; + return; + } + + // Case 2: Solid Edge must use pre-allocated resources for all GLRCs + if (strstr(szModuleFileName, "PART.EXE") + || strstr(szModuleFileName, "ASSEMBL.EXE") + || strstr(szModuleFileName, "DRAFT.EXE") + || strstr(szModuleFileName, "SMARTVW.EXE") + || strstr(szModuleFileName, "SMETAL.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = FALSE; + return; + } + + // Case 3: Sudden Depth creates and destroys GLRCs on paint commands + if (strstr(szModuleFileName, "SUDDEPTH.EXE") + || strstr(szModuleFileName, "SUDDEMO.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = TRUE; + glb.bFullscreenBlit = TRUE; + return; + } + + // Case 4: StereoGraphics test apps create and destroy GLRCs on paint commands + if (strstr(szModuleFileName, "REDBLUE.EXE") + || strstr(szModuleFileName, "DIAGNOSE.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = TRUE; + return; + } + + // Case 5: Pipes screen savers share multiple GLRCs for same window + if (strstr(szModuleFileName, "PIPES.SCR") + || (strstr(szModuleFileName, "PIPES") && strstr(szModuleFileName, ".SCR"))) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = TRUE; + return; + } + + // Case 6: AutoVue uses sub-viewport ops which are temporarily broken in stereo window + if (strstr(szModuleFileName, "AVWIN.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = TRUE; + return; + } + // Case 7: Quake3 is waiting for DDraw objects to be released at exit + if (strstr(szModuleFileName, "QUAKE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = FALSE; + glb.bPersistantBuffers = FALSE; + glb.bFullscreenBlit = FALSE; + return; + } + // Case 8: Reflection GLX server is unable to switch contexts at run-time + if (strstr(szModuleFileName, "RX.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bMessageBoxWarnings = FALSE; + return; + } + // Case 9: Original AutoCAD 2000 must share DDraw objects across GLRCs + if (strstr(szModuleFileName, "ACAD.EXE")) { + glb.bFastFPU = FALSE; + if (GetModuleHandle("wopengl6.hdi") != NULL) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = FALSE; + } + return; + } +} + +// *********************************************************************** + +BOOL dglInitDriver(void) +{ + UCHAR szExeName[MAX_PATH]; + const char *szRendering[] = { + "Mesa Software", + "Direct3D RGB SW", + "Direct3D HW", + }; + static BOOL bWarnOnce = FALSE; + + // Already initialized? + if (bInitialized) + return TRUE; + + // Moved from DllMain DLL_PROCESS_ATTACH: + + // (Re-)Init defaults + dglInitGlobals(); + + // Read registry or INI file settings + if (!dllReadRegistry(hInstanceDll)) { + if (!bWarnOnce) + MessageBox( NULL, "GLDirect has not been configured.\n\n" + "Please run the configuration program\n" + "before using GLDirect with applications.\n", + "GLDirect", MB_OK | MB_ICONWARNING); + bWarnOnce = TRUE; + return FALSE; + } + +#ifdef _USE_GLD3_WGL + // Must do this as early as possible. + // Need to read regkeys/ini-file first though. + gldInitDriverPointers(glb.dwDriver); + + // Create private driver globals + _gldDriver.CreatePrivateGlobals(); +#endif + // Overide settings with application customizations + if (glb.bAppCustomizations) + dglSetAppCustomizations(); + +//#ifndef _USE_GLD3_WGL + // Set the global memory type to either sysmem or vidmem + glb.dwMemoryType = glb.bHardware ? DDSCAPS_VIDEOMEMORY : DDSCAPS_SYSTEMMEMORY; +//#endif + + // Multi-threaded support overides persistant display support + if (glb.bMultiThreaded) + glb.bDirectDrawPersistant = glb.bPersistantBuffers = FALSE; + + // Multi-threaded support needs to be reflected in Mesa code. (DaveM) + _gld_bMultiThreaded = glb.bMultiThreaded; + + // Start logging + ddlogPathOption(szLogPath); + ddlogWarnOption(glb.bMessageBoxWarnings); + ddlogOpen((DDLOG_loggingMethodType)dwLogging, + (DDLOG_severityType)dwDebugLevel); + + // Obtain the name of the calling app + ddlogMessage(DDLOG_SYSTEM, "Driver : SciTech GLDirect 4.0\n"); + GetModuleFileName(NULL, szExeName, sizeof(szExeName)); + ddlogPrintf(DDLOG_SYSTEM, "Executable : %s", szExeName); + + ddlogPrintf(DDLOG_SYSTEM, "DirectDraw device: %s", glb.szDDName); + ddlogPrintf(DDLOG_SYSTEM, "Direct3D driver : %s", glb.szD3DName); + + ddlogPrintf(DDLOG_SYSTEM, "Rendering type : %s", szRendering[glb.dwRendering]); + + ddlogPrintf(DDLOG_SYSTEM, "Multithreaded : %s", glb.bMultiThreaded ? "Enabled" : "Disabled"); + ddlogPrintf(DDLOG_SYSTEM, "Display resources: %s", glb.bDirectDrawPersistant ? "Persistant" : "Instanced"); + ddlogPrintf(DDLOG_SYSTEM, "Buffer resources : %s", glb.bPersistantBuffers ? "Persistant" : "Instanced"); + + dglInitContextState(); + dglBuildPixelFormatList(); + //dglBuildTextureFormatList(); + + // D3D callback driver is now successfully initialized + bInitialized = TRUE; + // D3D callback driver is now ready to be exited + bExited = FALSE; + + return TRUE; +} + +// *********************************************************************** + +void dglExitDriver(void) +{ + + // Only need to clean up once per instance: + // May be called implicitly from DLL_PROCESS_DETACH, + // or explicitly from DGL_exitDriver(). + if (bExited) + return; + bExited = TRUE; + + // DDraw objects may be invalid when DLL unloads. +__try { + + // Clean-up sequence (moved from DLL_PROCESS_DETACH) +#ifndef _USE_GLD3_WGL + dglReleaseTextureFormatList(); +#endif + dglReleasePixelFormatList(); + dglDeleteContextState(); + +#ifdef _USE_GLD3_WGL + _gldDriver.DestroyPrivateGlobals(); +#endif + +} +__except(EXCEPTION_EXECUTE_HANDLER) { + ddlogPrintf(DDLOG_WARN, "Exception raised in dglExitDriver."); +} + + // Close the log file + ddlogClose(); +} + +// *********************************************************************** + +int WINAPI DllMain( + HINSTANCE hInstance, + DWORD fdwReason, + PVOID pvReserved) +{ + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + // Cache DLL instance handle + hInstanceDll = hInstance; + + // Flag that callback driver has yet to be initialized + bInitialized = bExited = FALSE; + +#ifndef _USE_GLD3_WGL + // Init internal Mesa function pointers + memset(&mesaFuncs, 0, sizeof(DGL_mesaFuncs)); +#endif // _USE_GLD3_WGL + + // Init defaults + dglInitGlobals(); + + // Defer rest of DLL initialization to 1st WGL function call + break; + + case DLL_PROCESS_DETACH: + // Call exit clean-up sequence + dglExitDriver(); + break; + } + + return TRUE; +} + +// *********************************************************************** + +void APIENTRY DGL_exitDriver(void) +{ + // Call exit clean-up sequence + dglExitDriver(); +} + +// *********************************************************************** + +void APIENTRY DGL_reinitDriver(void) +{ + // Force init sequence again + bInitialized = bExited = FALSE; + dglInitDriver(); +} + +// *********************************************************************** + +int WINAPI DllInitialize( + HINSTANCE hInstance, + DWORD fdwReason, + PVOID pvReserved) +{ + // Some Watcom compiled executables require this. + return DllMain(hInstance, fdwReason, pvReserved); +} + +// *********************************************************************** + +void DGL_LoadSplashScreen(int piReg, char* pszUser) +{ + HINSTANCE hSplashDll = NULL; + LPDGLSPLASHSCREEN dglSplashScreen = NULL; + static BOOL bOnce = FALSE; + static int iReg = 0; + static char szUser[255] = {"\0"}; + + // Display splash screen at all? + if (!bSplashScreen) + return; + + // Only display splash screen once + if (bOnce) + return; + bOnce = TRUE; + + // Make local copy of string for passing to DLL + if (pszUser) + strcpy(szUser, pszUser); + iReg = piReg; + + // Load Splash Screen DLL + // (If it fails to load for any reason, we don't care...) + hSplashDll = LoadLibrary("gldsplash.dll"); + if (hSplashDll) { + // Execute the Splash Screen function + dglSplashScreen = (LPDGLSPLASHSCREEN)GetProcAddress(hSplashDll, "GLDSplashScreen"); + if (dglSplashScreen) + (*dglSplashScreen)(1, iReg, szUser); + // Don't unload the DLL since splash screen dialog is modeless now + } +} + +// *********************************************************************** + +BOOL dglValidate() +{ + char *szCaption = "SciTech GLDirect Driver"; + UINT uType = MB_OK | MB_ICONEXCLAMATION; + +#ifdef _USE_GLD3_WGL + // (Re)build pixelformat list + if (glb.bPixelformatsDirty) + _gldDriver.BuildPixelformatList(); +#endif + + // Check to see if we have already validated + if (bDriverValidated && bInitialized) + return TRUE; + + // Since all (most) the WGL functions must be validated at this point, + // this also insure that the callback driver is completely initialized. + if (!bInitialized) + if (!dglInitDriver()) { + MessageBox(NULL, + "The GLDirect driver could not initialize.\n\n" + "Please run the configuration program to\n" + "properly configure the driver, or else\n" + "re-run the installation program.", szCaption, uType); + _exit(1); // Bail + } + + return TRUE; +} + +// *********************************************************************** + diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dllmain.h b/mesalib/src/mesa/drivers/windows/gldirect/dllmain.h new file mode 100644 index 000000000..03343ef7a --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dllmain.h @@ -0,0 +1,64 @@ +/**************************************************************************** +* +* 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: Win32 DllMain functions. +* +****************************************************************************/ + +#ifndef __DLLMAIN_H +#define __DLLMAIN_H + +// Macros to control compilation +#define STRICT +#define WIN32_LEAN_AND_MEAN + +#include <windows.h> + +#ifndef _USE_GLD3_WGL +#include "DirectGL.h" +#endif // _USE_GLD3_WGL + +//#include "gldirect/regkeys.h" +#include "dglglobals.h" +#include "ddlog.h" +#ifndef _USE_GLD3_WGL +#include "d3dtexture.h" +#endif // _USE_GLD3_WGL + +#include "dglwgl.h" + +extern BOOL bInitialized; + +BOOL dglInitDriver(void); +void dglExitDriver(void); + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_clip.c b/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_clip.c new file mode 100644 index 000000000..044d2e66f --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_clip.c @@ -0,0 +1,39 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Gareth Hughes <gareth@valinux.com> + */ + +#ifdef DEBUG /* This code only used for debugging */ + +// Stub to enable Mesa to build. KeithH +#pragma message("NOTE: Using gld_debug_clip.c HACK") + +void _math_test_all_cliptest_functions( char *description ) +{ +} + + +#endif /* DEBUG */ diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_norm.c b/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_norm.c new file mode 100644 index 000000000..c20362bb2 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_norm.c @@ -0,0 +1,39 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Gareth Hughes <gareth@valinux.com> + */ + +#ifdef DEBUG /* This code only used for debugging */ + +// Stub to enable Mesa to build. KeithH +#pragma message("NOTE: Using gld_debug_norm.c HACK") + +void _math_test_all_normal_transform_functions( char *description ) +{ +} + + +#endif /* DEBUG */ diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_xform.c b/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_xform.c new file mode 100644 index 000000000..73439dc3b --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_xform.c @@ -0,0 +1,41 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * Updated for P6 architecture by Gareth Hughes. + */ + + +#ifdef DEBUG /* This code only used for debugging */ + +// Stub to enable Mesa to build. KeithH +#pragma message("NOTE: Using gld_debug_xform.c HACK") + +void _math_test_all_transform_functions( char *description ) +{ +} + + +#endif /* DEBUG */ diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gld_dispatch.c b/mesalib/src/mesa/drivers/windows/gldirect/gld_dispatch.c new file mode 100644 index 000000000..e05d767e3 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gld_dispatch.c @@ -0,0 +1,73 @@ +/**************************************************************************** +* +* 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/2000/XP/XBox (Win32) +* +* Description: Thread-aware dispatch table. +* +****************************************************************************/ + +#include "glheader.h" +#include "glapi.h" +#include "glapitable.h" +#include "mtypes.h" +#include "context.h" + +#define KEYWORD1 +#define KEYWORD2 GLAPIENTRY +#if defined(USE_MGL_NAMESPACE) + #define NAME(func) mgl##func +#else + #define NAME(func) gl##func +#endif + +#if 0 +// Altered these to get the dispatch table from +// the current context of the calling thread. +#define DISPATCH(FUNC, ARGS, MESSAGE) \ + GET_CURRENT_CONTEXT(gc); \ + (gc->CurrentDispatch->FUNC) ARGS +#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ + GET_CURRENT_CONTEXT(gc); \ + return (gc->CurrentDispatch->FUNC) ARGS +#else // #if 0 +#define DISPATCH(FUNC, ARGS, MESSAGE) \ + GET_CURRENT_CONTEXT(gc); \ + (_glapi_Dispatch->FUNC) ARGS +#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ + GET_CURRENT_CONTEXT(gc); \ + return (_glapi_Dispatch->FUNC) ARGS +#endif // #if 0 + +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#include "glapitemp.h" diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gld_driver.c b/mesalib/src/mesa/drivers/windows/gldirect/gld_driver.c new file mode 100644 index 000000000..f7c575614 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gld_driver.c @@ -0,0 +1,279 @@ +/**************************************************************************** +* +* 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/2000/XP/XBox (Win32) +* +* Description: Driver functions and interfaces +* +****************************************************************************/ + +#define STRICT +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +#include "gld_driver.h" +#include "ddlog.h" +#include "glheader.h" + +// For glGetString(). +#include "common_x86_asm.h" + +//--------------------------------------------------------------------------- + +static char *szDriverError = "Driver used before initialisation!"; + +// This holds our dynamically created OpenGL renderer string. +// 256 chars should be plenty - remember that some apps display this. +static char _gldRendererString[256]; + +static char *szVendor = "SciTech Software, Inc."; + +//--------------------------------------------------------------------------- + +extern BOOL gldGetDXErrorString_DX(HRESULT hr, char *buf, int nBufSize); + +extern BOOL gldCreateDrawable_MesaSW(DGL_ctx *ctx, BOOL bPersistantInterface, BOOL bPersistantBuffers); +extern BOOL gldResizeDrawable_MesaSW(DGL_ctx *ctx, BOOL bDefaultDriver, BOOL bPersistantInterface, BOOL bPersistantBuffers); +extern BOOL gldDestroyDrawable_MesaSW(DGL_ctx *ctx); +extern BOOL gldCreatePrivateGlobals_MesaSW(void); +extern BOOL gldDestroyPrivateGlobals_MesaSW(void); +extern BOOL gldBuildPixelformatList_MesaSW(void); +extern BOOL gldInitialiseMesa_MesaSW(DGL_ctx *ctx); +extern BOOL gldSwapBuffers_MesaSW(DGL_ctx *ctx, HDC hDC, HWND hWnd); +extern PROC gldGetProcAddress_MesaSW(LPCSTR a); +extern BOOL gldGetDisplayMode_MesaSW(DGL_ctx *ctx, GLD_displayMode *glddm); + +extern BOOL gldCreateDrawable_DX(DGL_ctx *ctx, BOOL bPersistantInterface, BOOL bPersistantBuffers); +extern BOOL gldResizeDrawable_DX(DGL_ctx *ctx, BOOL bDefaultDriver, BOOL bPersistantInterface, BOOL bPersistantBuffers); +extern BOOL gldDestroyDrawable_DX(DGL_ctx *ctx); +extern BOOL gldCreatePrivateGlobals_DX(void); +extern BOOL gldDestroyPrivateGlobals_DX(void); +extern BOOL gldBuildPixelformatList_DX(void); +extern BOOL gldInitialiseMesa_DX(DGL_ctx *ctx); +extern BOOL gldSwapBuffers_DX(DGL_ctx *ctx, HDC hDC, HWND hWnd); +extern PROC gldGetProcAddress_DX(LPCSTR a); +extern BOOL gldGetDisplayMode_DX(DGL_ctx *ctx, GLD_displayMode *glddm); + +//--------------------------------------------------------------------------- +// NOP functions. Called if proper driver functions are not set. +//--------------------------------------------------------------------------- + +static BOOL _gldDriverError(void) +{ + ddlogMessage(DDLOG_CRITICAL, szDriverError); + return FALSE; +} + +//--------------------------------------------------------------------------- + +static BOOL _GetDXErrorString_ERROR( + HRESULT hr, + char *buf, + int nBufSize) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _CreateDrawable_ERROR( + DGL_ctx *ctx, + BOOL bPersistantInterface, + BOOL bPersistantBuffers) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _ResizeDrawable_ERROR( + DGL_ctx *ctx, + BOOL bDefaultDriver, + BOOL bPersistantInterface, + BOOL bPersistantBuffers) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _DestroyDrawable_ERROR( + DGL_ctx *ctx) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _CreatePrivateGlobals_ERROR(void) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _DestroyPrivateGlobals_ERROR(void) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _BuildPixelformatList_ERROR(void) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + + +static BOOL _InitialiseMesa_ERROR( + DGL_ctx *ctx) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _SwapBuffers_ERROR( + DGL_ctx *ctx, + HDC hDC, + HWND hWnd) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static PROC _GetProcAddress_ERROR( + LPCSTR a) +{ + _gldDriverError(); + return NULL; +} + +//--------------------------------------------------------------------------- + +static BOOL _GetDisplayMode_ERROR( + DGL_ctx *ctx, + GLD_displayMode *glddm) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- +// Functions useful to all drivers +//--------------------------------------------------------------------------- + +const GLubyte* _gldGetStringGeneric( + GLcontext *ctx, + GLenum name) +{ + if (!ctx) + return NULL; + + switch (name) { + case GL_RENDERER: + sprintf(_gldRendererString, "GLDirect 4.0 %s%s%s%s (%s %s)", + _mesa_x86_cpu_features ? "/x86" : "", + cpu_has_mmx ? "/MMX" : "", + cpu_has_3dnow ? "/3DNow!" : "", + cpu_has_xmm ? "/SSE" : "", + __DATE__, __TIME__); + return (const GLubyte *) _gldRendererString; + case GL_VENDOR: + return (const GLubyte *) szVendor; + default: + return NULL; + } +} + +//--------------------------------------------------------------------------- +// Global driver function pointers, initially set to functions that +// will report an error when called. +//--------------------------------------------------------------------------- + +GLD_driver _gldDriver = { + _GetDXErrorString_ERROR, + _CreateDrawable_ERROR, + _ResizeDrawable_ERROR, + _DestroyDrawable_ERROR, + _CreatePrivateGlobals_ERROR, + _DestroyPrivateGlobals_ERROR, + _BuildPixelformatList_ERROR, + _InitialiseMesa_ERROR, + _SwapBuffers_ERROR, + _GetProcAddress_ERROR, + _GetDisplayMode_ERROR +}; + +//--------------------------------------------------------------------------- +// Init function. Should be called as soon as regkeys/ini-settings are read. +//--------------------------------------------------------------------------- + +BOOL gldInitDriverPointers( + DWORD dwDriver) +{ + _gldDriver.GetDXErrorString = gldGetDXErrorString_DX; + + if (dwDriver == GLDS_DRIVER_MESA_SW) { + // Mesa Software driver + _gldDriver.CreateDrawable = gldCreateDrawable_MesaSW; + _gldDriver.ResizeDrawable = gldResizeDrawable_MesaSW; + _gldDriver.DestroyDrawable = gldDestroyDrawable_MesaSW; + _gldDriver.CreatePrivateGlobals = gldCreatePrivateGlobals_MesaSW; + _gldDriver.DestroyPrivateGlobals = gldDestroyPrivateGlobals_MesaSW; + _gldDriver.BuildPixelformatList = gldBuildPixelformatList_MesaSW; + _gldDriver.InitialiseMesa = gldInitialiseMesa_MesaSW; + _gldDriver.SwapBuffers = gldSwapBuffers_MesaSW; + _gldDriver.wglGetProcAddress = gldGetProcAddress_MesaSW; + _gldDriver.GetDisplayMode = gldGetDisplayMode_MesaSW; + return TRUE; + } + + if ((dwDriver == GLDS_DRIVER_REF) || (dwDriver == GLDS_DRIVER_HAL)) { + // Direct3D driver, either HW or SW + _gldDriver.CreateDrawable = gldCreateDrawable_DX; + _gldDriver.ResizeDrawable = gldResizeDrawable_DX; + _gldDriver.DestroyDrawable = gldDestroyDrawable_DX; + _gldDriver.CreatePrivateGlobals = gldCreatePrivateGlobals_DX; + _gldDriver.DestroyPrivateGlobals = gldDestroyPrivateGlobals_DX; + _gldDriver.BuildPixelformatList = gldBuildPixelformatList_DX; + _gldDriver.InitialiseMesa = gldInitialiseMesa_DX; + _gldDriver.SwapBuffers = gldSwapBuffers_DX; + _gldDriver.wglGetProcAddress = gldGetProcAddress_DX; + _gldDriver.GetDisplayMode = gldGetDisplayMode_DX; + return TRUE; + }; + + return FALSE; +} + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gld_driver.h b/mesalib/src/mesa/drivers/windows/gldirect/gld_driver.h new file mode 100644 index 000000000..01a46a832 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gld_driver.h @@ -0,0 +1,90 @@ +/**************************************************************************** +* +* 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/2000/XP/XBox (Win32) +* +* Description: Driver functions and interfaces +* +****************************************************************************/ + +#ifndef _GLD_DRIVER_H +#define _GLD_DRIVER_H + +// This file is only useful is we're using the new GLD3 WGL code. +#ifdef _USE_GLD3_WGL + +#include "dglcontext.h" + +// Same as DX8 D3DDISPLAYMODE +typedef struct { + DWORD Width; + DWORD Height; + DWORD Refresh; + DWORD BPP; +} GLD_displayMode; + +typedef struct { + // Returns a string for a given HRESULT error code. + BOOL (*GetDXErrorString)(HRESULT hr, char *buf, int nBufSize); + + // Driver functions for managing drawables. + // Functions must respect persistant buffers / persistant interface. + // NOTE: Persistant interface is: DirectDraw, pre-DX8; Direct3D, DX8 and above. + BOOL (*CreateDrawable)(DGL_ctx *ctx, BOOL bPersistantInterface, BOOL bPersistantBuffers); + BOOL (*ResizeDrawable)(DGL_ctx *ctx, BOOL bDefaultDriver, BOOL bPersistantInterface, BOOL bPersistantBuffers); + BOOL (*DestroyDrawable)(DGL_ctx *ctx); + + // Create/Destroy private globals belonging to driver + BOOL (*CreatePrivateGlobals)(void); + BOOL (*DestroyPrivateGlobals)(void); + + // Build pixelformat list + BOOL (*BuildPixelformatList)(void); + + // Initialise Mesa's driver pointers + BOOL (*InitialiseMesa)(DGL_ctx *ctx); + + // Swap buffers + BOOL (*SwapBuffers)(DGL_ctx *ctx, HDC hDC, HWND hWnd); + + // wglGetProcAddress() + PROC (*wglGetProcAddress)(LPCSTR a); + + BOOL (*GetDisplayMode)(DGL_ctx *ctx, GLD_displayMode *glddm); +} GLD_driver; + +extern GLD_driver _gldDriver; + +BOOL gldInitDriverPointers(DWORD dwDriver); +const GLubyte* _gldGetStringGeneric(GLcontext *ctx, GLenum name); + +#endif // _USE_GLD3_WGL + +#endif // _GLD_DRIVER_H diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gldlame8.c b/mesalib/src/mesa/drivers/windows/gldirect/gldlame8.c new file mode 100644 index 000000000..5ac519c17 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gldlame8.c @@ -0,0 +1,181 @@ +/**************************************************************************** +* +* 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: GLDirect utility for determining lame boards/drivers. +* +****************************************************************************/ + +#define STRICT +#define WIN32_LEAN_AND_MEAN +#include <d3d8.h> + +/* +Ack. Broken out from gldlame.c because of broken D3D headers. KeithH +*/ + +/**************************************************************************** +REMARKS: +Scans list of DirectDraw devices for specific device IDs. +****************************************************************************/ + +#define VENDORID_ATI 0x1002 + +static DWORD devATIRagePro[] = { + 0x4742, // 3D RAGE PRO BGA AGP 1X/2X + 0x4744, // 3D RAGE PRO BGA AGP 1X only + 0x4749, // 3D RAGE PRO BGA PCI 33 MHz + 0x4750, // 3D RAGE PRO PQFP PCI 33 MHz + 0x4751, // 3D RAGE PRO PQFP PCI 33 MHz limited 3D + 0x4C42, // 3D RAGE LT PRO BGA-312 AGP 133 MHz + 0x4C44, // 3D RAGE LT PRO BGA-312 AGP 66 MHz + 0x4C49, // 3D RAGE LT PRO BGA-312 PCI 33 MHz + 0x4C50, // 3D RAGE LT PRO BGA-256 PCI 33 MHz + 0x4C51, // 3D RAGE LT PRO BGA-256 PCI 33 MHz limited 3D +}; + +static DWORD devATIRageIIplus[] = { + 0x4755, // 3D RAGE II+ + 0x4756, // 3D RAGE IIC PQFP PCI + 0x4757, // 3D RAGE IIC BGA AGP + 0x475A, // 3D RAGE IIC PQFP AGP + 0x4C47, // 3D RAGE LT-G +}; + +static __inline BOOL IsDevice( + DWORD *lpDeviceIdList, + DWORD dwDeviceId, + int count) +{ + int i; + + for (i=0; i<count; i++) + if (dwDeviceId == lpDeviceIdList[i]) + return TRUE; + + return FALSE; +} + +/**************************************************************************** +REMARKS: +Test the Direct3D8 device for "lameness" with respect to GLDirect. +This is done on per-chipset basis, as in GLD CAD driver (DGLCONTEXT.C). +If bTestForWHQL is set then the device is tested to see if it is +certified, and bIsWHQL is set to indicate TRUE or FALSE. Otherwise bIsWHQL +is not set. [WHQL = Windows Hardware Quality Labs] + +NOTE: There is a one- or two-second time penalty incurred in determining + the WHQL certification date. +****************************************************************************/ +BOOL IsThisD3D8Lame( + IDirect3D8 *pD3D, + DWORD dwAdapter, + BOOL bTestForWHQL, + BOOL *bIsWHQL) +{ + DWORD dwFlags = bTestForWHQL ? 0 : D3DENUM_NO_WHQL_LEVEL; + D3DADAPTER_IDENTIFIER8 d3dai; + HRESULT hr; + + hr = IDirect3D8_GetAdapterIdentifier(pD3D, dwAdapter, dwFlags, &d3dai); + if (FAILED(hr)) + return TRUE; // Definitely lame if adapter details can't be obtained! + + if (bTestForWHQL) { + *bIsWHQL = d3dai.WHQLLevel ? TRUE : FALSE; + } + + // Vendor 1: ATI + if (d3dai.VendorId == VENDORID_ATI) { + // Test A: ATI Rage PRO + if (IsDevice(devATIRagePro, d3dai.DeviceId, sizeof(devATIRagePro))) + return TRUE; // bad mipmapping + // Test B: ATI Rage II+ + if (IsDevice(devATIRageIIplus, d3dai.DeviceId, sizeof(devATIRageIIplus))) + return TRUE; // bad HW alpha testing + } + + return FALSE; +} + +/**************************************************************************** +REMARKS: +Test the Direct3DDevice8 device for "lameness" with respect to GLDirect. +This is done by querying for particular caps, as in GLD CPL (CPLMAIN.CPP). +****************************************************************************/ +BOOL IsThisD3D8DeviceLame( + IDirect3DDevice8 *pDev) +{ + D3DCAPS8 d3dCaps; + HRESULT hr; + + hr = IDirect3DDevice8_GetDeviceCaps(pDev, &d3dCaps); + if (FAILED(hr)) + return TRUE; + + // Test 1: Perspective-correct textures + // Any card that cannot do perspective-textures is *exceptionally* lame. + if (!(d3dCaps.TextureCaps & D3DPTEXTURECAPS_PERSPECTIVE)) { + return TRUE; // Lame! + } + + // Test 2: Bilinear filtering + if (!(d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR)) { + return TRUE; // Lame! + } + + // Test 3: Mipmapping + if (!(d3dCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)) { + return TRUE; // Lame! + } + + // Test 4: Depth-test modes (?) + + // Test 5: Blend Modes -- Based on DX7 D3DIM MTEXTURE.CPP caps test + + // Accept devices that can do multipass, alpha blending + if( !((d3dCaps.DestBlendCaps & D3DPBLENDCAPS_INVSRCALPHA) && + (d3dCaps.SrcBlendCaps & D3DPBLENDCAPS_SRCALPHA)) ) + return TRUE; + + // Accept devices that can do multipass, color blending + if( !((d3dCaps.DestBlendCaps & D3DPBLENDCAPS_SRCCOLOR) && + (d3dCaps.SrcBlendCaps & D3DPBLENDCAPS_ZERO)) ) + return TRUE; + + // Accept devices that really support multiple textures. + if( !((d3dCaps.MaxTextureBlendStages > 1 ) && + (d3dCaps.MaxSimultaneousTextures > 1 ) && + (d3dCaps.TextureOpCaps & D3DTEXOPCAPS_MODULATE )) ) + return TRUE; + + return FALSE; // Not lame +} diff --git a/mesalib/src/mesa/drivers/windows/gldirect/opengl32.def b/mesalib/src/mesa/drivers/windows/gldirect/opengl32.def new file mode 100644 index 000000000..b213b6e04 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/opengl32.def @@ -0,0 +1,488 @@ +;**************************************************************************** +;* +;* 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/2000/XP/XBox (Win32) +;* +;* Description: DLL Module definition file +;* +;****************************************************************************/ + +DESCRIPTION 'GLDirect' + +VERSION 3.0 + +EXPORTS + glAccum=glAccum @1 + glAlphaFunc=glAlphaFunc @2 + glAreTexturesResident=glAreTexturesResident @3 + glArrayElement=glArrayElement @4 + glBegin=glBegin @5 + glBindTexture=glBindTexture @6 + glBitmap=glBitmap @7 + glBlendFunc=glBlendFunc @8 + glCallList=glCallList @9 + glCallLists=glCallLists @10 + glClear=glClear @11 + glClearAccum=glClearAccum @12 + glClearIndex=glClearIndex @13 + glClearColor=glClearColor @14 + glClearDepth=glClearDepth @15 + glClearStencil=glClearStencil @16 + glClipPlane=glClipPlane @17 + glColor3b=glColor3b @18 + glColor3d=glColor3d @19 + glColor3f=glColor3f @20 + glColor3i=glColor3i @21 + glColor3s=glColor3s @22 + glColor3ub=glColor3ub @23 + glColor3ui=glColor3ui @24 + glColor3us=glColor3us @25 + glColor4b=glColor4b @26 + glColor4d=glColor4d @27 + glColor4f=glColor4f @28 + glColor4i=glColor4i @29 + glColor4s=glColor4s @30 + glColor4ub=glColor4ub @31 + glColor4ui=glColor4ui @32 + glColor4us=glColor4us @33 + glColor3bv=glColor3bv @34 + glColor3dv=glColor3dv @35 + glColor3fv=glColor3fv @36 + glColor3iv=glColor3iv @37 + glColor3sv=glColor3sv @38 + glColor3ubv=glColor3ubv @39 + glColor3uiv=glColor3uiv @40 + glColor3usv=glColor3usv @41 + glColor4bv=glColor4bv @42 + glColor4dv=glColor4dv @43 + glColor4fv=glColor4fv @44 + glColor4iv=glColor4iv @45 + glColor4sv=glColor4sv @46 + glColor4ubv=glColor4ubv @47 + glColor4uiv=glColor4uiv @48 + glColor4usv=glColor4usv @49 + glColorMask=glColorMask @50 + glColorMaterial=glColorMaterial @51 + glColorPointer=glColorPointer @52 + glColorTableEXT=glColorTableEXT @53 + glColorSubTableEXT=glColorSubTableEXT @54 + glCopyPixels=glCopyPixels @55 + glCopyTexImage1D=glCopyTexImage1D @56 + glCopyTexImage2D=glCopyTexImage2D @57 + glCopyTexSubImage1D=glCopyTexSubImage1D @58 + glCopyTexSubImage2D=glCopyTexSubImage2D @59 + glCullFace=glCullFace @60 + glDepthFunc=glDepthFunc @61 + glDepthMask=glDepthMask @62 + glDepthRange=glDepthRange @63 + glDeleteLists=glDeleteLists @64 + glDeleteTextures=glDeleteTextures @65 + glDisable=glDisable @66 + glDisableClientState=glDisableClientState @67 + glDrawArrays=glDrawArrays @68 + glDrawBuffer=glDrawBuffer @69 + glDrawElements=glDrawElements @70 + glDrawPixels=glDrawPixels @71 + glEnable=glEnable @72 + glEnableClientState=glEnableClientState @73 + glEnd=glEnd @74 + glEndList=glEndList @75 + glEvalCoord1d=glEvalCoord1d @76 + glEvalCoord1f=glEvalCoord1f @77 + glEvalCoord1dv=glEvalCoord1dv @78 + glEvalCoord1fv=glEvalCoord1fv @79 + glEvalCoord2d=glEvalCoord2d @80 + glEvalCoord2f=glEvalCoord2f @81 + glEvalCoord2dv=glEvalCoord2dv @82 + glEvalCoord2fv=glEvalCoord2fv @83 + glEvalPoint1=glEvalPoint1 @84 + glEvalPoint2=glEvalPoint2 @85 + glEvalMesh1=glEvalMesh1 @86 + glEdgeFlag=glEdgeFlag @87 + glEdgeFlagv=glEdgeFlagv @88 + glEdgeFlagPointer=glEdgeFlagPointer @89 + glEvalMesh2=glEvalMesh2 @90 + glFeedbackBuffer=glFeedbackBuffer @91 + glFinish=glFinish @92 + glFlush=glFlush @93 + glFogf=glFogf @94 + glFogi=glFogi @95 + glFogfv=glFogfv @96 + glFogiv=glFogiv @97 + glFrontFace=glFrontFace @98 + glFrustum=glFrustum @99 + glGenLists=glGenLists @100 + glGenTextures=glGenTextures @101 + glGetBooleanv=glGetBooleanv @102 + glGetClipPlane=glGetClipPlane @103 + glGetColorTableEXT=glGetColorTableEXT @104 + glGetColorTableParameterivEXT=glGetColorTableParameterivEXT @105 + glGetColorTableParameterfvEXT=glGetColorTableParameterfvEXT @106 + glGetDoublev=glGetDoublev @107 + glGetError=glGetError @108 + glGetFloatv=glGetFloatv @109 + glGetIntegerv=glGetIntegerv @110 + glGetLightfv=glGetLightfv @111 + glGetLightiv=glGetLightiv @112 + glGetMapdv=glGetMapdv @113 + glGetMapfv=glGetMapfv @114 + glGetMapiv=glGetMapiv @115 + glGetMaterialfv=glGetMaterialfv @116 + glGetMaterialiv=glGetMaterialiv @117 + glGetPixelMapfv=glGetPixelMapfv @118 + glGetPixelMapuiv=glGetPixelMapuiv @119 + glGetPixelMapusv=glGetPixelMapusv @120 + glGetPointerv=glGetPointerv @121 + glGetPolygonStipple=glGetPolygonStipple @122 + glGetString=glGetString @123 + glGetTexEnvfv=glGetTexEnvfv @124 + glGetTexEnviv=glGetTexEnviv @125 + glGetTexGeniv=glGetTexGeniv @126 + glGetTexGendv=glGetTexGendv @127 + glGetTexGenfv=glGetTexGenfv @128 + glGetTexImage=glGetTexImage @129 + glGetTexLevelParameterfv=glGetTexLevelParameterfv @130 + glGetTexLevelParameteriv=glGetTexLevelParameteriv @131 + glGetTexParameterfv=glGetTexParameterfv @132 + glGetTexParameteriv=glGetTexParameteriv @133 + glHint=glHint @134 + glIndexd=glIndexd @135 + glIndexf=glIndexf @136 + glIndexi=glIndexi @137 + glIndexs=glIndexs @138 + glIndexub=glIndexub @139 + glIndexdv=glIndexdv @140 + glIndexfv=glIndexfv @141 + glIndexiv=glIndexiv @142 + glIndexsv=glIndexsv @143 + glIndexubv=glIndexubv @144 + glIndexMask=glIndexMask @145 + glIndexPointer=glIndexPointer @146 + glInterleavedArrays=glInterleavedArrays @147 + glInitNames=glInitNames @148 + glIsList=glIsList @149 + glIsTexture=glIsTexture @150 + glLightf=glLightf @151 + glLighti=glLighti @152 + glLightfv=glLightfv @153 + glLightiv=glLightiv @154 + glLightModelf=glLightModelf @155 + glLightModeli=glLightModeli @156 + glLightModelfv=glLightModelfv @157 + glLightModeliv=glLightModeliv @158 + glLineWidth=glLineWidth @159 + glLineStipple=glLineStipple @160 + glListBase=glListBase @161 + glLoadIdentity=glLoadIdentity @162 + glLoadMatrixd=glLoadMatrixd @163 + glLoadMatrixf=glLoadMatrixf @164 + glLoadName=glLoadName @165 + glLogicOp=glLogicOp @166 + glMap1d=glMap1d @167 + glMap1f=glMap1f @168 + glMap2d=glMap2d @169 + glMap2f=glMap2f @170 + glMapGrid1d=glMapGrid1d @171 + glMapGrid1f=glMapGrid1f @172 + glMapGrid2d=glMapGrid2d @173 + glMapGrid2f=glMapGrid2f @174 + glMaterialf=glMaterialf @175 + glMateriali=glMateriali @176 + glMaterialfv=glMaterialfv @177 + glMaterialiv=glMaterialiv @178 + glMatrixMode=glMatrixMode @179 + glMultMatrixd=glMultMatrixd @180 + glMultMatrixf=glMultMatrixf @181 + glNewList=glNewList @182 + glNormal3b=glNormal3b @183 + glNormal3d=glNormal3d @184 + glNormal3f=glNormal3f @185 + glNormal3i=glNormal3i @186 + glNormal3s=glNormal3s @187 + glNormal3bv=glNormal3bv @188 + glNormal3dv=glNormal3dv @189 + glNormal3fv=glNormal3fv @190 + glNormal3iv=glNormal3iv @191 + glNormal3sv=glNormal3sv @192 + glNormalPointer=glNormalPointer @193 + glOrtho=glOrtho @194 + glPassThrough=glPassThrough @195 + glPixelMapfv=glPixelMapfv @196 + glPixelMapuiv=glPixelMapuiv @197 + glPixelMapusv=glPixelMapusv @198 + glPixelStoref=glPixelStoref @199 + glPixelStorei=glPixelStorei @200 + glPixelTransferf=glPixelTransferf @201 + glPixelTransferi=glPixelTransferi @202 + glPixelZoom=glPixelZoom @203 + glPointSize=glPointSize @204 + glPolygonMode=glPolygonMode @205 + glPolygonOffset=glPolygonOffset @206 + glPolygonOffsetEXT=glPolygonOffsetEXT @207 + glPolygonStipple=glPolygonStipple @208 + glPopAttrib=glPopAttrib @209 + glPopClientAttrib=glPopClientAttrib @210 + glPopMatrix=glPopMatrix @211 + glPopName=glPopName @212 + glPrioritizeTextures=glPrioritizeTextures @213 + glPushMatrix=glPushMatrix @214 + glRasterPos2d=glRasterPos2d @215 + glRasterPos2f=glRasterPos2f @216 + glRasterPos2i=glRasterPos2i @217 + glRasterPos2s=glRasterPos2s @218 + glRasterPos3d=glRasterPos3d @219 + glRasterPos3f=glRasterPos3f @220 + glRasterPos3i=glRasterPos3i @221 + glRasterPos3s=glRasterPos3s @222 + glRasterPos4d=glRasterPos4d @223 + glRasterPos4f=glRasterPos4f @224 + glRasterPos4i=glRasterPos4i @225 + glRasterPos4s=glRasterPos4s @226 + glRasterPos2dv=glRasterPos2dv @227 + glRasterPos2fv=glRasterPos2fv @228 + glRasterPos2iv=glRasterPos2iv @229 + glRasterPos2sv=glRasterPos2sv @230 + glRasterPos3dv=glRasterPos3dv @231 + glRasterPos3fv=glRasterPos3fv @232 + glRasterPos3iv=glRasterPos3iv @233 + glRasterPos3sv=glRasterPos3sv @234 + glRasterPos4dv=glRasterPos4dv @235 + glRasterPos4fv=glRasterPos4fv @236 + glRasterPos4iv=glRasterPos4iv @237 + glRasterPos4sv=glRasterPos4sv @238 + glReadBuffer=glReadBuffer @239 + glReadPixels=glReadPixels @240 + glRectd=glRectd @241 + glRectf=glRectf @242 + glRecti=glRecti @243 + glRects=glRects @244 + glRectdv=glRectdv @245 + glRectfv=glRectfv @246 + glRectiv=glRectiv @247 + glRectsv=glRectsv @248 + glScissor=glScissor @249 + glIsEnabled=glIsEnabled @250 + glPushAttrib=glPushAttrib @251 + glPushClientAttrib=glPushClientAttrib @252 + glPushName=glPushName @253 + glRenderMode=glRenderMode @254 + glRotated=glRotated @255 + glRotatef=glRotatef @256 + glSelectBuffer=glSelectBuffer @257 + glScaled=glScaled @258 + glScalef=glScalef @259 + glShadeModel=glShadeModel @260 + glStencilFunc=glStencilFunc @261 + glStencilMask=glStencilMask @262 + glStencilOp=glStencilOp @263 + glTexCoord1d=glTexCoord1d @264 + glTexCoord1f=glTexCoord1f @265 + glTexCoord1i=glTexCoord1i @266 + glTexCoord1s=glTexCoord1s @267 + glTexCoord2d=glTexCoord2d @268 + glTexCoord2f=glTexCoord2f @269 + glTexCoord2i=glTexCoord2i @270 + glTexCoord2s=glTexCoord2s @271 + glTexCoord3d=glTexCoord3d @272 + glTexCoord3f=glTexCoord3f @273 + glTexCoord3i=glTexCoord3i @274 + glTexCoord3s=glTexCoord3s @275 + glTexCoord4d=glTexCoord4d @276 + glTexCoord4f=glTexCoord4f @277 + glTexCoord4i=glTexCoord4i @278 + glTexCoord4s=glTexCoord4s @279 + glTexCoord1dv=glTexCoord1dv @280 + glTexCoord1fv=glTexCoord1fv @281 + glTexCoord1iv=glTexCoord1iv @282 + glTexCoord1sv=glTexCoord1sv @283 + glTexCoord2dv=glTexCoord2dv @284 + glTexCoord2fv=glTexCoord2fv @285 + glTexCoord2iv=glTexCoord2iv @286 + glTexCoord2sv=glTexCoord2sv @287 + glTexCoord3dv=glTexCoord3dv @288 + glTexCoord3fv=glTexCoord3fv @289 + glTexCoord3iv=glTexCoord3iv @290 + glTexCoord3sv=glTexCoord3sv @291 + glTexCoord4dv=glTexCoord4dv @292 + glTexCoord4fv=glTexCoord4fv @293 + glTexCoord4iv=glTexCoord4iv @294 + glTexCoord4sv=glTexCoord4sv @295 + glTexCoordPointer=glTexCoordPointer @296 + glTexGend=glTexGend @297 + glTexGenf=glTexGenf @298 + glTexGeni=glTexGeni @299 + glTexGendv=glTexGendv @300 + glTexGeniv=glTexGeniv @301 + glTexGenfv=glTexGenfv @302 + glTexEnvf=glTexEnvf @303 + glTexEnvi=glTexEnvi @304 + glTexEnvfv=glTexEnvfv @305 + glTexEnviv=glTexEnviv @306 + glTexImage1D=glTexImage1D @307 + glTexImage2D=glTexImage2D @308 + glTexParameterf=glTexParameterf @309 + glTexParameteri=glTexParameteri @310 + glTexParameterfv=glTexParameterfv @311 + glTexParameteriv=glTexParameteriv @312 + glTexSubImage1D=glTexSubImage1D @313 + glTexSubImage2D=glTexSubImage2D @314 + glTranslated=glTranslated @315 + glTranslatef=glTranslatef @316 + glVertex2d=glVertex2d @317 + glVertex2f=glVertex2f @318 + glVertex2i=glVertex2i @319 + glVertex2s=glVertex2s @320 + glVertex3d=glVertex3d @321 + glVertex3f=glVertex3f @322 + glVertex3i=glVertex3i @323 + glVertex3s=glVertex3s @324 + glVertex4d=glVertex4d @325 + glVertex4f=glVertex4f @326 + glVertex4i=glVertex4i @327 + glVertex4s=glVertex4s @328 + glVertex2dv=glVertex2dv @329 + glVertex2fv=glVertex2fv @330 + glVertex2iv=glVertex2iv @331 + glVertex2sv=glVertex2sv @332 + glVertex3dv=glVertex3dv @333 + glVertex3fv=glVertex3fv @334 + glVertex3iv=glVertex3iv @335 + glVertex3sv=glVertex3sv @336 + glVertex4dv=glVertex4dv @337 + glVertex4fv=glVertex4fv @338 + glVertex4iv=glVertex4iv @339 + glVertex4sv=glVertex4sv @340 + glVertexPointer=glVertexPointer @341 + glViewport=glViewport @342 + glBlendEquationEXT=glBlendEquationEXT @343 + glBlendColorEXT=glBlendColorEXT @344 + glVertexPointerEXT=glVertexPointerEXT @345 + glNormalPointerEXT=glNormalPointerEXT @346 + glColorPointerEXT=glColorPointerEXT @347 + glIndexPointerEXT=glIndexPointerEXT @348 + glTexCoordPointerEXT=glTexCoordPointerEXT @349 + glEdgeFlagPointerEXT=glEdgeFlagPointerEXT @350 + glGetPointervEXT=glGetPointervEXT @351 + glArrayElementEXT=glArrayElementEXT @352 + glDrawArraysEXT=glDrawArraysEXT @353 + glBindTextureEXT=glBindTextureEXT @354 + glDeleteTexturesEXT=glDeleteTexturesEXT @355 + glGenTexturesEXT=glGenTexturesEXT @356 + glPrioritizeTexturesEXT=glPrioritizeTexturesEXT @357 + glCopyTexSubImage3DEXT=glCopyTexSubImage3DEXT @358 + glTexImage3DEXT=glTexImage3DEXT @359 + glTexSubImage3DEXT=glTexSubImage3DEXT @360 + glWindowPos4fMESA=glWindowPos4fMESA @361 + glWindowPos2iMESA=glWindowPos2iMESA @362 + glWindowPos2sMESA=glWindowPos2sMESA @363 + glWindowPos2fMESA=glWindowPos2fMESA @364 + glWindowPos2dMESA=glWindowPos2dMESA @365 + glWindowPos2ivMESA=glWindowPos2ivMESA @366 + glWindowPos2svMESA=glWindowPos2svMESA @367 + glWindowPos2fvMESA=glWindowPos2fvMESA @368 + glWindowPos2dvMESA=glWindowPos2dvMESA @369 + glWindowPos3iMESA=glWindowPos3iMESA @370 + glWindowPos3sMESA=glWindowPos3sMESA @371 + glWindowPos3fMESA=glWindowPos3fMESA @372 + glWindowPos3dMESA=glWindowPos3dMESA @373 + glWindowPos3ivMESA=glWindowPos3ivMESA @374 + glWindowPos3svMESA=glWindowPos3svMESA @375 + glWindowPos3fvMESA=glWindowPos3fvMESA @376 + glWindowPos3dvMESA=glWindowPos3dvMESA @377 + glWindowPos4iMESA=glWindowPos4iMESA @378 + glWindowPos4sMESA=glWindowPos4sMESA @379 + glWindowPos4dMESA=glWindowPos4dMESA @380 + glWindowPos4ivMESA=glWindowPos4ivMESA @381 + glWindowPos4svMESA=glWindowPos4svMESA @382 + glWindowPos4fvMESA=glWindowPos4fvMESA @383 + glWindowPos4dvMESA=glWindowPos4dvMESA @384 + glResizeBuffersMESA=glResizeBuffersMESA @385 + wglCopyContext=wglCopyContext @386 + wglCreateContext=wglCreateContext @387 + wglCreateLayerContext=wglCreateLayerContext @388 + wglDeleteContext=wglDeleteContext @389 + wglDescribeLayerPlane=wglDescribeLayerPlane @390 + wglGetCurrentContext=wglGetCurrentContext @391 + wglGetCurrentDC=wglGetCurrentDC @392 + wglGetLayerPaletteEntries=wglGetLayerPaletteEntries @393 + wglGetProcAddress=wglGetProcAddress @394 + wglMakeCurrent=wglMakeCurrent @395 + wglRealizeLayerPalette=wglRealizeLayerPalette @396 + wglSetLayerPaletteEntries=wglSetLayerPaletteEntries @397 + wglShareLists=wglShareLists @398 + wglSwapLayerBuffers=wglSwapLayerBuffers @399 + wglUseFontBitmapsA=wglUseFontBitmapsA @400 + wglUseFontBitmapsW=wglUseFontBitmapsW @401 + wglUseFontOutlinesA=wglUseFontOutlinesA @402 + wglUseFontOutlinesW=wglUseFontOutlinesW @403 + ChoosePixelFormat=ChoosePixelFormat @404 + DescribePixelFormat=DescribePixelFormat @405 + GetPixelFormat=GetPixelFormat @406 + SetPixelFormat=SetPixelFormat @407 + SwapBuffers=SwapBuffers @408 + wglChoosePixelFormat=wglChoosePixelFormat @409 + wglDescribePixelFormat=wglDescribePixelFormat @410 + wglGetPixelFormat=wglGetPixelFormat @411 + wglSetPixelFormat=wglSetPixelFormat @412 + wglSwapBuffers=wglSwapBuffers @413 + glActiveTextureARB=glActiveTextureARB @414 + glClientActiveTextureARB=glClientActiveTextureARB @415 + glMultiTexCoord1dARB=glMultiTexCoord1dARB @416 + glMultiTexCoord1dvARB=glMultiTexCoord1dvARB @417 + glMultiTexCoord1fARB=glMultiTexCoord1fARB @418 + glMultiTexCoord1fvARB=glMultiTexCoord1fvARB @419 + glMultiTexCoord1iARB=glMultiTexCoord1iARB @420 + glMultiTexCoord1ivARB=glMultiTexCoord1ivARB @421 + glMultiTexCoord1sARB=glMultiTexCoord1sARB @422 + glMultiTexCoord1svARB=glMultiTexCoord1svARB @423 + glMultiTexCoord2dARB=glMultiTexCoord2dARB @424 + glMultiTexCoord2dvARB=glMultiTexCoord2dvARB @425 + glMultiTexCoord2fARB=glMultiTexCoord2fARB @426 + glMultiTexCoord2fvARB=glMultiTexCoord2fvARB @427 + glMultiTexCoord2iARB=glMultiTexCoord2iARB @428 + glMultiTexCoord2ivARB=glMultiTexCoord2ivARB @429 + glMultiTexCoord2sARB=glMultiTexCoord2sARB @430 + glMultiTexCoord2svARB=glMultiTexCoord2svARB @431 + glMultiTexCoord3dARB=glMultiTexCoord3dARB @432 + glMultiTexCoord3dvARB=glMultiTexCoord3dvARB @433 + glMultiTexCoord3fARB=glMultiTexCoord3fARB @434 + glMultiTexCoord3fvARB=glMultiTexCoord3fvARB @435 + glMultiTexCoord3iARB=glMultiTexCoord3iARB @436 + glMultiTexCoord3ivARB=glMultiTexCoord3ivARB @437 + glMultiTexCoord3sARB=glMultiTexCoord3sARB @438 + glMultiTexCoord3svARB=glMultiTexCoord3svARB @439 + glMultiTexCoord4dARB=glMultiTexCoord4dARB @440 + glMultiTexCoord4dvARB=glMultiTexCoord4dvARB @441 + glMultiTexCoord4fARB=glMultiTexCoord4fARB @442 + glMultiTexCoord4fvARB=glMultiTexCoord4fvARB @443 + glMultiTexCoord4iARB=glMultiTexCoord4iARB @444 + glMultiTexCoord4ivARB=glMultiTexCoord4ivARB @445 + glMultiTexCoord4sARB=glMultiTexCoord4sARB @446 + glMultiTexCoord4svARB=glMultiTexCoord4svARB @447 diff --git a/mesalib/src/mesa/drivers/windows/gldirect/pixpack.h b/mesalib/src/mesa/drivers/windows/gldirect/pixpack.h new file mode 100644 index 000000000..ec848d455 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/pixpack.h @@ -0,0 +1,108 @@ +/**************************************************************************** +* +* 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: Pixel packing functions. +* +****************************************************************************/ + +#ifndef __PIXPACK_H +#define __PIXPACK_H + +#include <GL\gl.h> +#include <ddraw.h> + +#include "ddlog.h" + +/*---------------------- Macros and type definitions ----------------------*/ + +#define PXAPI + +// Typedef that can be used for pixel packing function pointers. +#define PX_PACK_FUNC(a) void PXAPI (a)(unsigned char *pixdata, void *dst, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2) +typedef void (PXAPI *PX_packFunc)(unsigned char *pixdata, void *dst, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2); + +// Typedef that can be used for pixel unpacking function pointers. +#define PX_UNPACK_FUNC(a) void PXAPI (a)(unsigned char *pixdata, void *src, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2) +typedef void (PXAPI *PX_unpackFunc)(unsigned char *pixdata, void *src, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2); + +// Typedef that can be used for pixel span packing function pointers. +#define PX_PACK_SPAN_FUNC(a) void PXAPI (a)(GLuint n, unsigned char *pixdata, unsigned char *dst, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2) +typedef void (PXAPI *PX_packSpanFunc)(GLuint n, unsigned char *pixdata, unsigned char *dst, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2); + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +// Function that examines a pixel format and returns the relevent +// pixel-packing function +void PXAPI pxClassifyPixelFormat(const LPDDPIXELFORMAT lpddpf, PX_packFunc *lpPackFn ,PX_unpackFunc *lpUnpackFn, PX_packSpanFunc *lpPackSpanFn); + +// Packing functions +PX_PACK_FUNC(pxPackGeneric); +PX_PACK_FUNC(pxPackRGB555); +PX_PACK_FUNC(pxPackARGB4444); +PX_PACK_FUNC(pxPackARGB1555); +PX_PACK_FUNC(pxPackRGB565); +PX_PACK_FUNC(pxPackRGB332); +PX_PACK_FUNC(pxPackRGB888); +PX_PACK_FUNC(pxPackARGB8888); +PX_PACK_FUNC(pxPackPAL8); + +// Unpacking functions +PX_UNPACK_FUNC(pxUnpackGeneric); +PX_UNPACK_FUNC(pxUnpackRGB555); +PX_UNPACK_FUNC(pxUnpackARGB4444); +PX_UNPACK_FUNC(pxUnpackARGB1555); +PX_UNPACK_FUNC(pxUnpackRGB565); +PX_UNPACK_FUNC(pxUnpackRGB332); +PX_UNPACK_FUNC(pxUnpackRGB888); +PX_UNPACK_FUNC(pxUnpackARGB8888); +PX_UNPACK_FUNC(pxUnpackPAL8); + +// Span Packing functions +PX_PACK_SPAN_FUNC(pxPackSpanGeneric); +PX_PACK_SPAN_FUNC(pxPackSpanRGB555); +PX_PACK_SPAN_FUNC(pxPackSpanARGB4444); +PX_PACK_SPAN_FUNC(pxPackSpanARGB1555); +PX_PACK_SPAN_FUNC(pxPackSpanRGB565); +PX_PACK_SPAN_FUNC(pxPackSpanRGB332); +PX_PACK_SPAN_FUNC(pxPackSpanRGB888); +PX_PACK_SPAN_FUNC(pxPackSpanARGB8888); +PX_PACK_SPAN_FUNC(pxPackSpanPAL8); + +#ifdef __cplusplus +} +#endif + +#endif |