(*
** Copyright (c) 1995, 3Dfx Interactive, Inc.
** All Rights Reserved.
**
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.;
** the contents of this file may not be disclosed to third parties, copied or
** duplicated in any form, in whole or in part, without the prior written
** permission of 3Dfx Interactive, Inc.
**
** RESTRICTED RIGHTS LEGEND:
** Use, duplication or disclosure by the Government is subject to restrictions
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
** rights reserved under the Copyright Laws of the United States.
*)

(***************************************************************************
 *
 *  Glide 2.43 Delphi adaptation by Erik Unger and Eric Nowinski
 *
 *  The Headers 3Dfx, Sst1vid, GlideSys, GlideUtl and Glide
 *  are included in this Glide.pas unit.
 *
 *  28.2.98
 *
 *  E-Mail:
 *         Erik Unger <h_unger@magnet.at>
 *         Eric Nowinski <Eric.Nowinski@capway.com>
 *
 ***************************************************************************)

(***************************************************************************
 *
 * Glide 2.43 Free Pascal Compiler adaptation by Ivan Montes. 14-NOV-98
 *
 * e-mail : imv@SoftHome.net
 *
 **************************************************************************)

(**************************************************************************
 *
 * Glide 2.43 Virtual Pascal Compiler adaptation by Kenn ;) 13-SEPT-2000
 *
 * (Not much work involved - total respect to all of the above.
 *
 **************************************************************************)


unit Glide2x;


interface

// A global variable to say if the DLL is loaded.
// Check before use Glide functions, or use the older version.
var
  GlideUnitIsInitalised : Boolean;

{$DEFINE GLIDE2}

const
  GlideDLL = 'Glide2x.dll';


////////////////////////////////////////////////////////////////////////////////
// 3Dfx.h
////////////////////////////////////////////////////////////////////////////////

// basic data types
type
  TFxU8      = Byte;
  TFxI8      = Shortint;
  TFxU16     = Word;
  TFxI16     = Smallint;
  TFxU32     = LongInt;
  TFxI32     = LongInt;
  TFxBool    = LongBool;
  TFxFloat   = Single;
  TFxDouble  = Double;

// color types
type
  TFxColor = LongInt;
  TFxColor4  = packed record
    r,g,b,a : TFxFloat;
  end;

// fundamental types
const
  FXTRUE = True;
  FXFALSE = False;

(*
** helper macros
*)

function FXBIT(i  :longint) : longint;
function FXUNUSED( a :longint) : boolean;

////////////////////////////////////////////////////////////////////////////////
// Sst1vid.h
////////////////////////////////////////////////////////////////////////////////

// Video defines
type
  TGrScreenRefresh = TFxI32;
const
  GR_REFRESH_60Hz = $0;
  GR_REFRESH_70Hz = $1;
  GR_REFRESH_72Hz = $2;
  GR_REFRESH_75Hz = $3;
  GR_REFRESH_80Hz = $4;
  GR_REFRESH_90Hz = $5;
  GR_REFRESH_100Hz = $6;
  GR_REFRESH_85Hz = $7;
  GR_REFRESH_120Hz = $8;
  GR_REFRESH_NONE = $ff;

type
  TGrScreenResolution = TFxI32;
const
  GR_RESOLUTION_320x200 = $0;
  GR_RESOLUTION_320x240 = $1;
  GR_RESOLUTION_400x256 = $2;
  GR_RESOLUTION_512x384 = $3;
  GR_RESOLUTION_640x200 = $4;
  GR_RESOLUTION_640x350 = $5;
  GR_RESOLUTION_640x400 = $6;
  GR_RESOLUTION_640x480 = $7;
  GR_RESOLUTION_800x600 = $8;
  GR_RESOLUTION_960x720 = $9;
  GR_RESOLUTION_856x480 = $a;
  GR_RESOLUTION_512x256 = $b;
  GR_RESOLUTION_1024x768  = $C;
  GR_RESOLUTION_1280x1024 = $D;
  GR_RESOLUTION_1600x1200 = $E;
  GR_RESOLUTION_400x300   = $F;
  GR_RESOLUTION_NONE      = $ff;
  GR_RESOLUTION_MIN       = GR_RESOLUTION_320x200;
  GR_RESOLUTION_MAX       = GR_RESOLUTION_1600x1200;

////////////////////////////////////////////////////////////////////////////////
// GlideSys.h
////////////////////////////////////////////////////////////////////////////////

// Endianness is stored in bits [30:31]
const
  GLIDE_ENDIAN_SHIFT  = 30;
  GLIDE_ENDIAN_LITTLE = $1 shl GLIDE_ENDIAN_SHIFT;
  GLIDE_ENDIAN_BIG    = $2 shl GLIDE_ENDIAN_SHIFT;

// OS is stored in bits [0:6]

  GLIDE_OS_SHIFT   = $0;
  GLIDE_OS_UNIX    = $1;
  GLIDE_OS_DOS32   = $2;
  GLIDE_OS_WIN32   = $4;
  GLIDE_OS_SYSTEM7 = $8;
  GLIDE_OS_OS2     = $10;
  GLIDE_OS_OTHER   = $20; // For Proprietary Arcade HW

// Sim vs. Hardware is stored in bits [7:8]

  GLIDE_SST_SHIFT  = $7;
  GLIDE_SST_SIM    = $1 shl GLIDE_SST_SHIFT;
  GLIDE_SST_HW     = $2 shl GLIDE_SST_SHIFT;

// Hardware type is stored in bits [9:12]

  GLIDE_HW_SHIFT   = $9;
  GLIDE_HW_SST1    = $1 shl GLIDE_HW_SHIFT;
  GLIDE_HW_SST96   = $2 shl GLIDE_HW_SHIFT;
  GLIDE_HW_SSTH3   = $4 shl GLIDE_HW_SHIFT;
  GLIDE_HW_SST2    = $8 shl GLIDE_HW_SHIFT;


  GLIDE_ENDIAN = GLIDE_ENDIAN_LITTLE;
  GLIDE_OS = GLIDE_OS_WIN32;
  GLIDE_SST = GLIDE_SST_HW;
  GLIDE_HW = GLIDE_HW_SST1;

  GLIDE_PLATFORM = GLIDE_ENDIAN or GLIDE_OS or GLIDE_SST or GLIDE_HW;
  GLIDE_NUM_TMU  = 2;

////////////////////////////////////////////////////////////////////////////////
// Glide.h
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------
// type DEFINITIONS
// -----------------------------------------------------------------------
type
  TGrColor = TFxU32;
  TGrAlpha = TFxU8;
  TGrMipMapId = TFxU32;
  TGrFog   = TFxU8;

// -----------------------------------------------------------------------
// CONSTANTS AND TYPES
// -----------------------------------------------------------------------
const
  MAX_NUM_SST            = 4;
  MAX_MIPMAPS_PER_SST    = 1024;
  GR_FOG_TABLE_SIZE      = 64;
  GR_NULL_MIPMAP_HANDLE  = -1;
  GR_ZDEPTHVALUE_NEAREST = $FFFF;
  GR_ZDEPTHVALUE_FARTHEST = $0000;
  GR_WDEPTHVALUE_NEAREST = $0000;
  GR_WDEPTHVALUE_FARTHEST = $FFFF;

  GR_MIPMAPLEVELMASK_EVEN = (1 shl 0);
  GR_MIPMAPLEVELMASK_ODD  = (1 shl 1);
  GR_MIPMAPLEVELMASK_BOTH = GR_MIPMAPLEVELMASK_EVEN or GR_MIPMAPLEVELMASK_ODD;

  GR_LODBIAS_BILINEAR  = 0.5;
  GR_LODBIAS_TRILINEAR = 0.0;

type
  TGrChipID = TFxI32;
const
  GR_TMU0 = $0;
  GR_TMU1 = $1;
  GR_TMU2 = $2;
  GR_FBI  = $3;

type
  TGrCombineFunction = TFxI32;
const
  GR_COMBINE_FUNCTION_ZERO        = $0;
  GR_COMBINE_FUNCTION_NONE        = GR_COMBINE_FUNCTION_ZERO;
  GR_COMBINE_FUNCTION_LOCAL       = $1;
  GR_COMBINE_FUNCTION_LOCAL_ALPHA = $2;
  GR_COMBINE_FUNCTION_SCALE_OTHER = $3;
  GR_COMBINE_FUNCTION_BLEND_OTHER = GR_COMBINE_FUNCTION_SCALE_OTHER;
  GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL = $4;
  GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA = $5;
  GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL = $6;
  GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL = $7;
  GR_COMBINE_FUNCTION_BLEND =
      GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL;
  GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA = $8;
  GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL = $9;
  GR_COMBINE_FUNCTION_BLEND_LOCAL =
      GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL;
  GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA = $10;

type
  TGrCombineFactor = TFxI32;
const
  GR_COMBINE_FACTOR_ZERO          = $0;
  GR_COMBINE_FACTOR_NONE          = GR_COMBINE_FACTOR_ZERO;
  GR_COMBINE_FACTOR_LOCAL         = $1;
  GR_COMBINE_FACTOR_OTHER_ALPHA   = $2;
  GR_COMBINE_FACTOR_LOCAL_ALPHA   = $3;
  GR_COMBINE_FACTOR_TEXTURE_ALPHA = $4;
  GR_COMBINE_FACTOR_DETAIL_FACTOR = GR_COMBINE_FACTOR_TEXTURE_ALPHA;
  GR_COMBINE_FACTOR_LOD_FRACTION  = $5;
  GR_COMBINE_FACTOR_ONE           = $8;
  GR_COMBINE_FACTOR_ONE_MINUS_LOCAL = $9;
  GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA = $a;
  GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA = $b;
  GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA = $c;
  GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR =
      GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA;
  GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION = $d;

type
  TGrCombineLocal = TFxI32;
const
  GR_COMBINE_LOCAL_ITERATED = $0;
  GR_COMBINE_LOCAL_CONSTANT = $1;
  GR_COMBINE_LOCAL_NONE = GR_COMBINE_LOCAL_CONSTANT;
  GR_COMBINE_LOCAL_DEPTH  = $2;

type
  TGrCombineOther = TFxI32;
const
  GR_COMBINE_OTHER_ITERATED = $0;
  GR_COMBINE_OTHER_TEXTURE = $1;
  GR_COMBINE_OTHER_CONSTANT = $2;
  GR_COMBINE_OTHER_NONE = GR_COMBINE_OTHER_CONSTANT;

type
  TGrAlphaSource = TFxI32;
const
  GR_ALPHASOURCE_CC_ALPHA = $0;
  GR_ALPHASOURCE_ITERATED_ALPHA = $1;
  GR_ALPHASOURCE_TEXTURE_ALPHA = $2;
  GR_ALPHASOURCE_TEXTURE_ALPHA_TIMES_ITERATED_ALPHA = $3;

type
  TGrColorCombineFnc = TFxI32;
const
  GR_COLORCOMBINE_ZERO  = $0;
  GR_COLORCOMBINE_CCRGB = $1;
  GR_COLORCOMBINE_ITRGB = $2;
  GR_COLORCOMBINE_ITRGB_DELTA0 = $3;
  GR_COLORCOMBINE_DECAL_TEXTURE = $4;
  GR_COLORCOMBINE_TEXTURE_TIMES_CCRGB = $5;
  GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB = $6;
  GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_DELTA0 = $7;
  GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_ADD_ALPHA = $8;
  GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA = $9;
  GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA_ADD_ITRGB = $a;
  GR_COLORCOMBINE_TEXTURE_ADD_ITRGB = $b;
  GR_COLORCOMBINE_TEXTURE_SUB_ITRGB = $c;
  GR_COLORCOMBINE_CCRGB_BLEND_ITRGB_ON_TEXALPHA = $d;
  GR_COLORCOMBINE_DIFF_SPEC_A = $e;
  GR_COLORCOMBINE_DIFF_SPEC_B = $f;
  GR_COLORCOMBINE_ONE = $10;

type
  TGrAlphaBlendFnc = TFxI32;
const
  GR_BLEND_ZERO = $0;
  GR_BLEND_SRC_ALPHA = $1;
  GR_BLEND_SRC_COLOR = $2;
  GR_BLEND_DST_COLOR = GR_BLEND_SRC_COLOR;
  GR_BLEND_DST_ALPHA = $3;
  GR_BLEND_ONE = $4;
  GR_BLEND_ONE_MINUS_SRC_ALPHA = $5;
  GR_BLEND_ONE_MINUS_SRC_COLOR = $6;
  GR_BLEND_ONE_MINUS_DST_COLOR = GR_BLEND_ONE_MINUS_SRC_COLOR;
  GR_BLEND_ONE_MINUS_DST_ALPHA = $7;
  GR_BLEND_RESERVED_8 = $8;
  GR_BLEND_RESERVED_9 = $9;
  GR_BLEND_RESERVED_A = $a;
  GR_BLEND_RESERVED_B = $b;
  GR_BLEND_RESERVED_C = $c;
  GR_BLEND_RESERVED_D = $d;
  GR_BLEND_RESERVED_E = $e;
  GR_BLEND_ALPHA_SATURATE = $f;
  GR_BLEND_PREFOG_COLOR = GR_BLEND_ALPHA_SATURATE;

type
  TGrAspectRatio = TFxI32;
const
  GR_ASPECT_8x1 = $0;       // 8W x 1H
  GR_ASPECT_4x1 = $1;       // 4W x 1H
  GR_ASPECT_2x1 = $2;       // 2W x 1H
  GR_ASPECT_1x1 = $3;       // 1W x 1H
  GR_ASPECT_1x2 = $4;       // 1W x 2H
  GR_ASPECT_1x4 = $5;       // 1W x 4H
  GR_ASPECT_1x8 = $6;       // 1W x 8H

type
  TGrBuffer = TFxI32;
const
  GR_BUFFER_FRONTBUFFER   = $0;
  GR_BUFFER_BACKBUFFER    = $1;
  GR_BUFFER_AUXBUFFER     = $2;
  GR_BUFFER_DEPTHBUFFER   = $3;
  GR_BUFFER_ALPHABUFFER   = $4;
  GR_BUFFER_TRIPLEBUFFER  = $5;

type
  TGrChromakeyMode = TFxI32;
const
  GR_CHROMAKEY_DISABLE    = $0;
  GR_CHROMAKEY_ENABLE     = $1;

type
  TGrCmpFnc = TFxI32;
const
  GR_CMP_NEVER    = $0;
  GR_CMP_LESS     = $1;
  GR_CMP_EQUAL    = $2;
  GR_CMP_LEQUAL   = $3;
  GR_CMP_GREATER  = $4;
  GR_CMP_NOTEQUAL = $5;
  GR_CMP_GEQUAL   = $6;
  GR_CMP_ALWAYS   = $7;

type
  TGrColorFormat = TFxI32;
const
  GR_COLORFORMAT_ARGB     = $0;
  GR_COLORFORMAT_ABGR     = $1;
  GR_COLORFORMAT_RGBA     = $2;
  GR_COLORFORMAT_BGRA     = $3;

type
  TGrCullMode = TFxI32;
const
  GR_CULL_DISABLE         = $0;
  GR_CULL_NEGATIVE        = $1;
  GR_CULL_POSITIVE        = $2;

type
  TGrDepthBufferMode = TFxI32;
const
  GR_DEPTHBUFFER_DISABLE                 = $0;
  GR_DEPTHBUFFER_ZBUFFER                 = $1;
  GR_DEPTHBUFFER_WBUFFER                 = $2;
  GR_DEPTHBUFFER_ZBUFFER_COMPARE_TO_BIAS = $3;
  GR_DEPTHBUFFER_WBUFFER_COMPARE_TO_BIAS = $4;

type
  TGrDitherMode = TFxI32;
const
  GR_DITHER_DISABLE       = $0;
  GR_DITHER_2x2           = $1;
  GR_DITHER_4x4           = $2;

type
  TGrFogMode = TFxI32;
const
  GR_FOG_DISABLE          = $0;
  GR_FOG_WITH_ITERATED_ALPHA = $1;
  GR_FOG_WITH_TABLE       = $2;
  GR_FOG_MULT2            = $100;
  GR_FOG_ADD2             = $200;

type
  TGrLock = TFxU32;
const
  GR_LFB_READ_ONLY  = $00;
  GR_LFB_WRITE_ONLY = $01;
  GR_LFB_IDLE       = $00;
  GR_LFB_NOIDLE     = $10;

type
  TGrLfbBypassMode = TFxI32;
const
  GR_LFBBYPASS_DISABLE    = $0;
  GR_LFBBYPASS_ENABLE     = $1;

type
  TGrLfbWriteMode = TFxI32;
const
  GR_LFBWRITEMODE_565 = $0; // RGB:RGB
  GR_LFBWRITEMODE_555 = $1; // RGB:RGB
  GR_LFBWRITEMODE_1555 = $2; // ARGB:ARGB
  GR_LFBWRITEMODE_RESERVED1 = $3;
  GR_LFBWRITEMODE_888 = $4; // RGB
  GR_LFBWRITEMODE_8888 = $5; // ARGB
  GR_LFBWRITEMODE_RESERVED2 = $6;
  GR_LFBWRITEMODE_RESERVED3 = $7;
  GR_LFBWRITEMODE_RESERVED4 = $8;
  GR_LFBWRITEMODE_RESERVED5 = $9;
  GR_LFBWRITEMODE_RESERVED6 = $a;
  GR_LFBWRITEMODE_RESERVED7 = $b;
  GR_LFBWRITEMODE_565_DEPTH = $c; // RGB:DEPTH
  GR_LFBWRITEMODE_555_DEPTH = $d; // RGB:DEPTH
  GR_LFBWRITEMODE_1555_DEPTH = $e; // ARGB:DEPTH
  GR_LFBWRITEMODE_DEPTH_DEPTH = $f; // DEPTH:DEPTH
  GR_LFBWRITEMODE_ZA16        = $f; // DEPTH:DEPTH
  GR_LFBWRITEMODE_ALPHA_ALPHA = GR_LFBWRITEMODE_DEPTH_DEPTH;
  GR_LFBWRITEMODE_ANY       = $FF;

type
  TGrOriginLocation = TFxI32;
const
  GR_ORIGIN_UPPER_LEFT    = $0;
  GR_ORIGIN_LOWER_LEFT    = $1;
  GR_ORIGIN_ANY           = $FF;

type
  TGrLfbInfo = packed record
    size : Integer;
    lfbPtr : Pointer;
    strideInBytes : TFxU32;
    writeMode : TGrLfbWriteMode;
    origin : TGrOriginLocation;
  end;

type
  TGrLOD = TFxI32;
const
  GR_LOD_256              = $0;
  GR_LOD_128              = $1;
  GR_LOD_64               = $2;
  GR_LOD_32               = $3;
  GR_LOD_16               = $4;
  GR_LOD_8                = $5;
  GR_LOD_4                = $6;
  GR_LOD_2                = $7;
  GR_LOD_1                = $8;

type
  TGrMipMapMode = TFxI32;
const
  GR_MIPMAP_DISABLE               = $0; // no mip mapping
  GR_MIPMAP_NEAREST               = $1; // use nearest mipmap
  GR_MIPMAP_NEAREST_DITHER        = $2; // GR_MIPMAP_NEAREST + LOD dith

type
  TGrSmoothingMode = TFxI32;
const
  GR_SMOOTHING_DISABLE = 0;
  GR_SMOOTHING_ENABLE  = 1;

type
  TGrTextureClampMode = TFxI32;
const
  GR_TEXTURECLAMP_WRAP    = $0;
  GR_TEXTURECLAMP_CLAMP   = $1;

type
  TGrTextureCombineFnc = TFxI32;
const
  GR_TEXTURECOMBINE_ZERO          = $0; // texout = 0 */
  GR_TEXTURECOMBINE_DECAL         = $1; // texout = texthis */
  GR_TEXTURECOMBINE_OTHER         = $2; // this TMU in passthru mode */
  GR_TEXTURECOMBINE_ADD           = $3; // tout = tthis + t(this+1) */
  GR_TEXTURECOMBINE_MULTIPLY      = $4; // texout = tthis * t(this+1) */
  GR_TEXTURECOMBINE_SUBTRACT      = $5; // Sutract from upstream TMU */
  GR_TEXTURECOMBINE_DETAIL        = $6; // detail--detail on tthis */
  GR_TEXTURECOMBINE_DETAIL_OTHER  = $7; // detail--detail on tthis+1 */
  GR_TEXTURECOMBINE_TRILINEAR_ODD = $8; // trilinear--odd levels tthis*/
  GR_TEXTURECOMBINE_TRILINEAR_EVEN = $9; //trilinear--even levels tthis*/
  GR_TEXTURECOMBINE_ONE           = $a; // texout = $FFFFFFFF */

type
  TGrTextureFilterMode= TFxI32;
const
  GR_TEXTUREFILTER_POINT_SAMPLED  = $0;
  GR_TEXTUREFILTER_BILINEAR       = $1;

type
  TGrTextureFormat = TFxI32;
const
  GR_TEXFMT_8BIT                  = $0;
  GR_TEXFMT_RGB_332               = GR_TEXFMT_8BIT;
  GR_TEXFMT_YIQ_422               = $1;
  GR_TEXFMT_ALPHA_8               = $2; // (0..0xFF) alpha     */
  GR_TEXFMT_INTENSITY_8           = $3; // (0..0xFF) intensity */
  GR_TEXFMT_ALPHA_INTENSITY_44    = $4;
  GR_TEXFMT_P_8                   = $5; // 8-bit palette */
  GR_TEXFMT_RSVD0                 = $6;
  GR_TEXFMT_RSVD1                 = $7;
  GR_TEXFMT_16BIT                 = $8;
  GR_TEXFMT_ARGB_8332             = GR_TEXFMT_16BIT;
  GR_TEXFMT_AYIQ_8422             = $9;
  GR_TEXFMT_RGB_565               = $a;
  GR_TEXFMT_ARGB_1555             = $b;
  GR_TEXFMT_ARGB_4444             = $c;
  GR_TEXFMT_ALPHA_INTENSITY_88    = $d;
  GR_TEXFMT_AP_88                 = $e; // 8-bit alpha 8-bit palette */
  GR_TEXFMT_RSVD2                 = $f;

type
  TGrTexTable = TFxU32;
const
  GR_TEXTABLE_NCC0    = $0;
  GR_TEXTABLE_NCC1    = $1;
  GR_TEXTABLE_PALETTE = $2;

type
  TGrNCCTable = TFxU32;
const
  GR_NCCTABLE_NCC0    = $0;
  GR_NCCTABLE_NCC1    = $1;

type
  TGrTexBaseRange = TFxU32;
const
  GR_TEXBASE_256      = $0;
  GR_TEXBASE_128      = $1;
  GR_TEXBASE_64       = $2;
  GR_TEXBASE_32_TO_1  = $3;

const
{$IFDEF GLIDE3}
  GLIDE3_EXTRA_STATE = 68;
{$ELSE}
  GLIDE3_EXTRA_STATE = 0;
{$ENDIF}

  GLIDE_STATE_PAD_SIZE  = 312 + GLIDE3_EXTRA_STATE;
//#ifdef GLIDE_LIB
//typedef struct _TGrState_s TGrState;
//#else
//typedef struct _TGrState_s {
//  char pad[GLIDE_STATE_PAD_SIZE];
//} TGrState;
//#endif

type
  TGrState = packed record
    pad : array [0..GLIDE_STATE_PAD_SIZE-1] of char;
  end;

{$IFDEF GLIDE3}
const
(* Types of data in strips *)
  GR_FLOAT       = 0;
  GR_U8          = 1;

(* Parameters for strips *)
  GR_VERTEX      = 0;
  GR_COLOR       = 1;
  GR_TEXTURE0    = 2;
  GR_TEXTURE1    = 3;

(* Componenets for strips *)
(* vertex *)
  GR_VERTEX_XYZ  = 3;
  GR_VERTEX_XYZW = 4;
(* Color *)
  GR_COLOR_RGB   = 3;
  GR_COLOR_RGBA  = 4;
(* Texture *)
  GR_TEX_NONE    = 0;
  GR_TEX_ST      = 2;
  GR_TEX_STW     = 3;

(* Stuf for grDrawArray *)
  GR_POINTS              = 0;
  GR_LINE_STRIP          = 1;
  GR_POLYGON             = 2;
  GR_TRIANGLE_STRIP      = 3;
  GR_TRIANGLE_FAN        = 4;
  GR_TRIANGLES           = 5;

{$ENDIF}


// -----------------------------------------------------------------------
// STRUCTURES
// -----------------------------------------------------------------------

// 3DF texture file structs
type
  Gu3dfHeader = packed record
    width, height : TFxU32;
    small_lod, large_lod : Integer;
    aspect_ratio : TGrAspectRatio;
    format : TGrTextureFormat;
  end;

  GuNccTable = packed record
    yRGB : array [0..15] of TFxU8;
    iRGB : array [0..3, 0..2] of TFxI16;
    qRGB : array [0..3, 0..2] of TFxI16;
    packed_data : array [0..11] of TFxU32;
  end;

  GuTexPalette = packed record
    data : array [0..255] of TFxU32;
  end;

  GuTexTable = packed record
    case byte of
      0: (nccTable : GuNccTable);
      1: (palette  : GuTexPalette);
  end;

  Gu3dfInfo = packed record
    header : Gu3dfHeader;
    table : GuTexTable;
    data : Pointer;
    mem_required : TFxU32;    // memory required for mip map in bytes.
  end;

  TGrTexInfo = packed record
    smallLod : TGrLOD;
    largeLod : TGrLOD;
    aspectRatio : TGrAspectRatio;
    format : TGrTextureFormat;
    data : Pointer;
  end;

  TGrMipMapInfo = packed record
    sst : Integer;                    // SST where this texture map was stored  */
    valid : TFxBool;                  // set when this table entry is allocated*/
    width, height : Integer;
    aspect_ratio : TGrAspectRatio;         // aspect ratio of the mip map.  */
    data : Pointer;                  // actual texture data  */

    format : TGrTextureFormat;                    // format of the texture table */
    mipmap_mode : TGrMipMapMode;               // mip map mode for this texture */
    magfilter_mode : TGrTextureFilterMode;       // filtering to be used when magnified */
    minfilter_mode : TGrTextureFilterMode;       // filtering to be used with minified  */
    s_clamp_mode : TGrTextureClampMode;         // how this texture should be clamped in s */
    t_clamp_mode : TGrTextureClampMode;         // how this texture should be clamped in t */
    tLOD : TFxU32;                   // Register value for tLOD register */
    tTextureMode : TFxU32;           // Register value for tTextureMode not including non-texture specific bits */
    lod_bias : TFxU32;               // LOD bias of the mip map in preshifted 4.2*/
    lod_min, lod_max : TGrLOD;       // largest and smallest levels of detail  */
    tmu : Integer;                    // tmu on which this texture resides */
    odd_even_mask : TFxU32;          // mask specifying levels on this tmu  */
    tmu_base_address : TFxU32;       // base addr (in TMU mem) of this texture */
    trilinear : TFxBool;              // should we blend by lod? */

    nccable : GuNccTable;              // NCC compression table (optional) */
  end;

type
  TGrSstType = Integer;
const
  GR_SSTTYPE_VOODOO    = 0;
  GR_SSTTYPE_SST96     = 1;
  GR_SSTTYPE_AT3D      = 2;
  GR_SSTTYPE_Voodoo2   = 3;

type
  TGrTMUConfig = packed record
    tmuRev : Integer;                // Rev of Texelfx chip */
    tmuRam : Integer;                // 1, 2, or 4 MB */
  end;

  TGrVoodooConfig = packed record
    fbRam : Integer;                         // 1, 2, or 4 MB
    fbiRev : Integer;                        // Rev of Pixelfx chip
    nTexelfx : Integer;                      // How many texelFX chips are there?
    sliDetect : TFxBool;                     // Is it a scan-line interleaved board?
    tmuConfig : array [0..GLIDE_NUM_TMU] of TGrTMUConfig;   // Configuration of the Texelfx chips */
  end;

  TGrSst96Config = packed record
    fbRam : Integer;                  // How much? */
    nTexelfx : Integer;
    tmuConfig : TGrTMUConfig;
  end;

  TGrVoodoo2Config = TGrVoodooConfig;

  TGrAT3DConfig = packed record
    rev : Integer;
  end;

  TsstBoard = packed record
    Ssttype : TGrSstType;             // Which hardware is it? */
    case byte of
      0:(VoodooConfig : TGrVoodooConfig);
      1:(SST96Config : TGrSst96Config);
      2:(AT3DConfig : TGrAT3DConfig);
      3:(Voodoo2Config : TGrVoodoo2Config);
  end;

  TGrHwConfiguration = packed record
    num_sst : Integer;
    SSTs : array [0..MAX_NUM_SST-1] of TsstBoard;
  end;

  TGrSstPerfStats = packed record
    pixelsIn : TFxU32;              // # pixels processed (minus buffer clears) */
    chromaFail : TFxU32;            // # pixels not drawn due to chroma key */
    zFuncFail : TFxU32;             // # pixels not drawn due to Z comparison */
    aFuncFail : TFxU32;             // # pixels not drawn due to alpha comparison */
    pixelsOut : TFxU32;             // # pixels drawn (including buffer clears) */
  end;

  TGrTmuVertex = packed record
    sow : Single;                   // s texture ordinate (s over w) */
    tow : Single;                   // t texture ordinate (t over w) */
    oow : Single;                   // 1/w (used mipmapping - really 0xfff/w) */
  end;


// TGrVertex
// If these are changed the C & assembly language trisetup routines MUST
// be changed, for they will no longer work.
  TGrVertex = packed record
    x, y, z : Single;                // X, Y, and Z of scrn space -- Z is ignored */
    r, g, b : Single;                // R, G, B, ([0..255.0]) */
    ooz : Single;                    // 65535/Z (used for Z-buffering) */
    a : Single;                      // Alpha [0..255.0] */
    oow : Single;                    // 1/W (used for W-buffering, texturing) */
    tmuvtx : array [0..GLIDE_NUM_TMU] of TGrTmuVertex;
  end;

// For indexing TGrVertex as a float *.
//   CHANGE THESE IF THE VERTEX STRUCTURE CHANGES!
const
  GR_VERTEX_X_OFFSET              = 0;
  GR_VERTEX_Y_OFFSET              = 1;
  GR_VERTEX_Z_OFFSET              = 2;
  GR_VERTEX_R_OFFSET              = 3;
  GR_VERTEX_G_OFFSET              = 4;
  GR_VERTEX_B_OFFSET              = 5;
  GR_VERTEX_OOZ_OFFSET            = 6;
  GR_VERTEX_A_OFFSET              = 7;
  GR_VERTEX_OOW_OFFSET            = 8;
  GR_VERTEX_SOW_TMU0_OFFSET       = 9;
  GR_VERTEX_TOW_TMU0_OFFSET       = 10;
  GR_VERTEX_OOW_TMU0_OFFSET       = 11;
  GR_VERTEX_SOW_TMU1_OFFSET       = 12;
  GR_VERTEX_TOW_TMU1_OFFSET       = 13;
  GR_VERTEX_OOW_TMU1_OFFSET       = 14;
  GR_VERTEX_SOW_TMU2_OFFSET       = 15;
  GR_VERTEX_TOW_TMU2_OFFSET       = 16;
  GR_VERTEX_OOW_TMU2_OFFSET       = 17;

type
  TGrLfbSrcFmt = TFxU32;
const
  GR_LFB_SRC_FMT_565          = $00;
  GR_LFB_SRC_FMT_555          = $01;
  GR_LFB_SRC_FMT_1555         = $02;
  GR_LFB_SRC_FMT_888          = $04;
  GR_LFB_SRC_FMT_8888         = $05;
  GR_LFB_SRC_FMT_565_DEPTH    = $0c;
  GR_LFB_SRC_FMT_555_DEPTH    = $0d;
  GR_LFB_SRC_FMT_1555_DEPTH   = $0e;
  GR_LFB_SRC_FMT_ZA16         = $0f;
  GR_LFB_SRC_FMT_RLE16        = $80;

type
   TGrPassthruMode = TFxI32;
const
  GR_PASSTHRU_SHOW_VGA    = $0;
  GR_PASSTHRU_SHOW_SST1   = $1;

type
  TGrHint = TFxU32;
const
  GR_HINTTYPE_MIN                 = 0;
  GR_HINT_STWHINT                 = 0;
  GR_HINT_FIFOCHECKHINT           = 1;
  GR_HINT_FPUPRECISION            = 2;
  GR_HINT_ALLOW_MIPMAP_DITHER     = 3;
  GR_HINTTYPE_MAX                 = 3;

type
  TGrSTWHint = TFxU32;
const
  GR_STWHINT_W_DIFF_FBI   = 1 shl 0;
  GR_STWHINT_W_DIFF_TMU0  = 1 shl 1;
  GR_STWHINT_ST_DIFF_TMU0 = 1 shl 2;
  GR_STWHINT_W_DIFF_TMU1  = 1 shl 3;
  GR_STWHINT_ST_DIFF_TMU1 = 1 shl 4;
  GR_STWHINT_W_DIFF_TMU2  = 1 shl 5;
  GR_STWHINT_ST_DIFF_TMU2 = 1 shl 6;

type
  TGrControl = TFxU32;
const
  GR_CONTROL_ACTIVATE   = $1;
  GR_CONTROL_DEACTIVATE = $2;
  GR_CONTROL_RESIZE     = $3;
  GR_CONTROL_MOVE       = $4;

function GR_GENERATE_FIFOCHECK_HINT_MASK(var swHWM, swLWM) : longint;

// -----------------------------------------------------------------------
// function PROTOTYPES
// -----------------------------------------------------------------------

// rendering functions
var
{&stdcall+}
  grDrawLine : procedure (var v1, v2 : TGrVertex);
  grDrawPlanarPolygon : procedure (nverts : Integer; var ilist : Integer; var vlist : TGrVertex);
  grDrawPlanarPolygonVertexList : procedure (nverts : Integer; var vlist : TGrVertex);
  grDrawPoint : procedure (var pt : TGrVertex);
  grDrawPolygon : procedure (nverts : Integer; var ilist : Integer; var vlist : TGrVertex);
  grDrawPolygonVertexList : procedure (nverts : Integer; var vlist : TGrVertex);
  grDrawTriangle : procedure (var a, b, c : TGrVertex);

// buffer management
var
  grBufferClear : procedure (Color : TGrColor; alpha : TGrAlpha; depth : TFxU16);
  grBufferNumPending : procedure  ;
  grBufferSwap : procedure (swap_interval : Integer);
  grRenderBuffer : procedure (buffer : TGrBuffer);

// error management
type
  TGrErrorCallbackFnc = procedure(str : PChar; fatal : TFxBool);
var
  grErrorSetCallback : procedure (fnc : TGrErrorCallbackFnc);

// SST routines
var
  grSstIdle : procedure ;
  grSstVideoLine : function : TFxU32;
  grSstVRetraceOn : function : TFxBool;
  grSstIsBusy : function : TFxBool;
  grSstWinOpen : function (hWnd : TFxU32;
                           screen_resolution : TGrScreenResolution;
                           refresh_rate : TGrScreenRefresh;
                           color_format : TGrColorFormat;
                           origin_location : TGrOriginLocation;
                           nColBuffers, nAuxBuffers : Integer) : TFxBool;
  grSstWinClose : procedure ;
  grSstControl : function  (code : TFxU32): TFxBool;
  grSstQueryHardware : function (var hwconfig : TGrHwConfiguration) : TFxBool;
  grSstQueryBoards : function (var hwconfig : TGrHwConfiguration) : TFxBool;
  grSstOrigin : procedure (origine : TGrOriginLocation);
  grSstSelect : procedure (which_sst : Integer);
  grSstScreenHeight : function : Integer;
  grSstScreenWidth : function : Integer;
  grSstStatus : function : TFxU32;

//  Drawing Statistics
var
  grSstPerfStats : procedure (var pStats : TGrSstPerfStats);
  grSstResetPerfStats : procedure ;
  grResetTriStats : procedure ;
  grTriStats : procedure (var trisProcessed : TFxU32; trisDrawn : TFxU32);

// Glide configuration and special effect maintenance functions
var
  grAlphaBlendFunction : procedure (rgb_sf, rgb_df, alpha_sf, alpha_df : TGrAlphaBlendFnc);
  grAlphaCombine : procedure (Fnct : TGrCombineFunction; factor : TGrCombineFactor;
                              local : TGrCombineLocal; other : TGrCombineOther;
                              invert : TFxBool);
  grAlphaControlsITRGBLighting : procedure (enable : TFxBool);
  grAlphaTestFunction : procedure (fnct : TGrCmpFnc);
  grAlphaTestReferenceValue : procedure (value : TGrAlpha);
  grChromakeyMode : procedure (mode : TGrChromakeyMode);
  grChromakeyValue : procedure (value : TGrColor);
  grClipWindow : procedure (minx, miny, maxx, maxy : Integer);
  grColorCombine : procedure (Fnct : TGrCombineFunction; factor : TGrCombineFactor;
                              local : TGrCombineLocal; other :TGrCombineOther;
                              invert : TFxBool);
  grColorMask : procedure (rgb, a : TFxBool);
  grCullMode : procedure (mode : TGrCullMode);
  grConstantColorValue : procedure (value : TGrColor);
  grConstantColorValue4 : procedure (a, r, g, b : Single);
  grDepthBiasLevel : procedure (level : TFxI16);
  grDepthBufferFunction : procedure (fnct : TGrCmpFnc);
  grDepthBufferMode : procedure (mode : TGrDepthBufferMode);
  grDepthMask : procedure (mask : TFxBool);
  grDisableAllEffects : procedure ;
  grDitherMode : procedure (mode : TGrDitherMode);
  grFogColorValue : procedure (fogcolor : TGrColor);
  grFogMode : procedure (mode : TGrFogMode);
  grFogTable : procedure (var ft : TGrFog);
  grGammaCorrectionValue : procedure (value : single);
  grSplash : procedure (x, y : Single;width, height : Single; frame : TFxU32);

// texture mapping control functions
var
  grTexCalcMemRequired : function (lodmin, modmax : TGrLOD; aspect : TGrAspectRatio; fmt : TGrTextureFormat) : TFxU32;
  grTexTextureMemRequired : function (evenOdd : TFxU32; var info : TGrTexInfo) : TFxU32;
  grTexMinAddress : function (tmu : TGrChipID) : TFxU32;
  grTexMaxAddress : function (tmu : TGrChipID) : TFxU32;
  grTexNCCTable : procedure (tmu : TGrChipID ; table : TGrNCCTable);
  grTexSource : procedure (tmu : TGrChipID; startAddess, evenOdd : TFxU32; var info : TGrTexInfo);
  grTexClampMode : procedure (tmu : TGrChipID; s_clampmode, t_clampmode: TGrTextureClampMode);
  grTexCombine : procedure (tmu : TGrChipID;
                            rgb_function : TGrCombineFunction;
                            rgb_factor : TGrCombineFactor;
                            alpha_function : TGrCombineFunction;
                            alpha_factor : TGrCombineFactor;
                            rgb_invert, alpha_invert : TFxBool);
  grTexCombineFunction : procedure (tmu : TGrChipID; fnc : TGrTextureCombineFnc);
  grTexDetailControl : procedure (tmu : TGrChipID; lod_bias : Integer; detail_scale : TFxU8; detail_max : Single);
  grTexFilterMode : procedure (tmu : TGrChipID; minfilter_mode,magfilter_mode : TGrTextureFilterMode);
  grTexLodBiasValue : procedure (tmu : TGrChipID; bias : Single);
  grTexDownloadMipMap : procedure (tmu : TGrChipID; startAddress, enenOdd : TFxU32; var info : TGrTexInfo);
  grTexDownloadMipMapLevel : procedure (tmu : TGrChipID;
                                        startAddress : TFxU32;
                                        thisLod, largeLod : TGrLOD;
                                        aspectRatio : TGrAspectRatio;
                                        format : TGrTextureFormat;
                                        evenOdd : TFxU32;
                                        data : Pointer);
  grTexDownloadMipMapLevelPartial : procedure (tmu : TGrChipID;
                                               startAdress : TFxU32;
                                               thisLod, largeLod : TGrLOD;
                                               aspectRatio : TGrAspectRatio;
                                               format : TGrTextureFormat;
                                               evenOdd : TFxU32;
                                               data : Pointer;
                                               _start, _end : Integer);
  ConvertAndDownloadRle : procedure (tmu : TGrChipID;
                                    startAddress : TFxU32;
                                    thisLod, largeLod : TGrLOD;
                                    aspectRatio : TGrAspectRatio;
                                    format : TGrTextureFormat;
                                    evenOdd : TFxU32;
                                    var bm_data : TFxU8;
                                    bm_h : LongInt;
                                    u0, v0 : TFxU32;
                                    width, height : TFxU32;
                                    dest_width, dest_height : TFxU32;
                                    var tlut : TFxU16);
  grCheckForRoom : procedure (n : TFxI32);
  grTexDownloadTable : procedure (tmu : TGrChipID; ype : TGrTexTable; data : Pointer);
  grTexDownloadTablePartial : procedure (tmu : TGrChipID; _Type : TGrTexTable; data : Pointer;
                                         _start, _end : Integer);
  grTexMipMapMode : procedure (tmu : TGrChipID; mode : TGrMipMapMode;lodBlend : TFxBool);
  grTexMultibase : procedure (tmu : TGrChipID; enable : TFxBool);
  grTexMultibaseAddress : procedure (tmu : TGrChipID; range : TGrTexBaseRange;
                                     startAddress, evenodd : TFxU32;
                                     var info : TGrTexInfo);

// utility texture functions
var
  guTexAllocateMemory : function (tmu : TGrChipID;
                                  odd_even_mask : TFxU8;
                                  width, height : Integer;
                                  fmt : TGrTextureFormat;
                                  mm_mode : TGrMipMapMode;
                                  smallest_lod, largest_lod : TGrLOD;
                                  aspect : TGrAspectRatio;
                                  s_clamp_mode, t_clamp_mode : TGrTextureClampMode;
                                  minfilter_mode, magfilter_mode : TGrTextureFilterMode;
                                  lod_bias : Single;
                                  trilinear : TFxBool) : TGrMipMapId;
  guTexChangeAttributes : function (mmid : TGrMipMapId;
                                    width, height : Integer;
                                    fmt : TGrTextureFormat;
                                    mm_mode : TGrMipMapMode;
                                    smallest_lod, largest_lod : TGrLOD;
                                    aspect : TGrAspectRatio;
                                    s_clamp_mode, t_clamp_mode : TGrTextureClampMode;
                                    minfilter_mode, magfilter_mode : TGrTextureFilterMode) : TFxBool;
  guTexCombineFunction : procedure (tmu : TGrChipID; fnc : TGrTextureCombineFnc);
  guTexGetCurrentMipMap : function (tmu : TGrChipID) : TGrMipMapId;
  guTexGetMipMapInfo : function (mmid : TGrMipMapId) : TGrMipMapInfo;
  guTexMemQueryAvail : function (tmu : TGrChipID) : TFxU32;
  guTexMemReset : procedure ;
  guTexDownloadMipMap : procedure (mmid : TGrMipMapId; src : Pointer; var table : GuNccTable);
  guTexDownloadMipMapLevel : procedure (mmid : TGrMipMapId; lod : TGrLOD; var src : Pointer);
  guTexSource : procedure (id : TGrMipMapId);

// linear frame buffer functions
var
  grLfbLock : function (ype : TGrLock; buffer : TGrBuffer; writeMode : TGrLfbWriteMode;
                        origin : TGrOriginLocation; pixelPipeline : TFxBool;
                        var info : TGrLfbInfo) : TFxBool;
  grLfbUnlock : function (ype : TGrLock; buffer : TGrBuffer) : TFxBool;
  grLfbConstantAlpha : procedure (alpha : TGrAlpha);
  grLfbConstantDepth : procedure (depth : TFxU16);
  grLfbWriteColorSwizzle : procedure (swizzleBytes : TFxBool; swapWords : TFxBool);
  grLfbWriteColorFormat : procedure (colorFormat : TGrColorFormat);
  grLfbWriteRegion : function (dst_buffer : TGrBuffer;
                               dst_x, dst_y : TFxU32;
                               src_format : TGrLfbSrcFmt;
                               src_width, src_height : TFxU32;
                               src_stride : TFxI32;
                               src_data : Pointer) : TFxBool;
  grLfbReadRegion : function (src_buffer : TGrBuffer;
                              src_x, src_y : TFxU32;
                              src_width, src_height : TFxU32;
                              dst_stride : TFxU32;
                              dst_data : Pointer) : TFxBool;

//  Antialiasing Functions
var
  grAADrawLine : procedure (var v1 : TGrVertex; var v2 : TGrVertex);
  grAADrawPoint : procedure (var pt : TGrVertex);
  grAADrawPolygon : procedure (nverts : Integer; var ilist : Integer; var vlist : TGrVertex);
  grAADrawPolygonVertexList : procedure (nverts : Integer; var vlist : TGrVertex);
  grAADrawTriangle : procedure (var a, b, c : TGrVertex; ab_antialias, bc_antialias, ca_antialias : TFxBool);

// glide management functions
var
  grGlideInit : procedure ;
  grGlideShutdown : procedure ;
  grGlideGetVersion : procedure (version : PChar);
  grGlideGetState : procedure (var state : TGrState);
  grGlideSetState : procedure (var state : TGrState);
  grGlideShamelessPlug : procedure (_On : TFxBool);
  grHints : procedure (hintType : TGrHint; hintMask : TFxU32);

{$IFDEF GLIDE3}
var
  grParameterData : procedure (param,components,_type: TFxU32; offset: TFxI32);
  grDrawArray : procedure (mode,Count: TFxU32; var pointers);
{$ENDIF}

////////////////////////////////////////////////////////////////////////////////
// Glideutl.h
////////////////////////////////////////////////////////////////////////////////

// rendering functions
var
  guAADrawTriangleWithClip : procedure (var a, b, c: TGrVertex);
  guDrawTriangleWithClip : procedure (var a, b, c: TGrVertex);
  guDrawPolygonVertexListWithClip : procedure (nverts : Integer ;vlist : TGrVertex);

// hi-level rendering utility functions
var
  guAlphaSource : procedure (mode : TGrAlphaSource);
  guColorCombineFunction : procedure (fnc: TGrColorCombineFnc);
  guEncodeRLE16 : function (dst, src: Pointer; width, height : TFxU32) : Integer;
  guTexCreateColorMipMap : function  : Pointer;

// fog stuff
var
  guFogTableIndexToW : function (i: Integer) : Single;
  guFogGenerateExp : procedure (var fogtable: TGrFog; density: Single);
  guFogGenerateExp2 : procedure (var fogtable: TGrFog; density: Single);
  guFogGenerateLinear : procedure (var fogtable: TGrFog; nearZ, farZ: Single);

// endian stuff
var
  guEndianSwapWords : function (value: TFxU32) : TFxU32;
  guEndianSwapBytes : function (value: TFxU16) : TFxU16;

// hi-level texture manipulation tools.
var
  gu3dfGetInfo : function (filename: PChar; var info: Gu3dfInfo): TFxBool;
  gu3dfLoad : function (filename: PChar; var data: Gu3dfInfo): TFxBool;

// movie capture stuff
var
  guMovieStart : procedure ;
  guMovieStop : procedure ;
  guMovieSetName : procedure (name: PChar);

function InitGlideUnit : Boolean;
function CloseGlideUnit : Boolean;

implementation



uses
  Windows,
  SysUtils;


const
  GlideHandle : integer = 0;




function InitGlideUnit : Boolean;
var p:pointer;

begin
  result := False;
  if (GlideHandle = 0) then
  begin
    GlideHandle := LoadLibrary(GlideDLL);
    if (GlideHandle = 0) then exit;

    // rendering functions
    p := GetProcAddress(GlideHandle, '_grDrawLine@8');grdrawline:=p;
    p := GetProcAddress (GlideHandle, '_grDrawPlanarPolygon@12');grDrawPlanarPolygon:=p;
    p := GetProcAddress (GlideHandle, '_grDrawPlanarPolygonVertexList@8');grDrawPlanarPolygonVertexList :=p;
    p := GetProcAddress (GlideHandle, '_grDrawPoint@4');grdrawpoint:=p;
    p := GetProcAddress (GlideHandle, '_grDrawPolygon@12');grDrawPolygon :=p;
    p := GetProcAddress (GlideHandle, '_grDrawPolygonVertexList@8');grDrawPolygonVertexList :=p;
    p := GetProcAddress (GlideHandle, '_grDrawTriangle@12');grdrawtriangle:=p;

    // buffer management
    p := GetProcAddress (GlideHandle, '_grBufferClear@12');grbufferclear:=p;
    p := GetProcAddress (GlideHandle, '_grBufferNumPending@0');grBufferNumPending :=p;
    p := GetProcAddress (GlideHandle, '_grBufferSwap@4');grbufferswap:=p;
    p := GetProcAddress (GlideHandle, '_grRenderBuffer@4');grrenderbuffer:=p;

    // error management
    p := GetProcAddress (GlideHandle, '_grErrorSetCallback@4');grErrorSetCallback :=p;

    // SST routines
    p := GetProcAddress (GlideHandle, '_grSstIdle@0');grSstIdle :=p;
    p := GetProcAddress (GlideHandle, '_grSstVideoLine@0');grSstVideoLine :=p;
    p := GetProcAddress (GlideHandle, '_grSstVRetraceOn@0');grSstVRetraceOn :=p;
    p := GetProcAddress (GlideHandle, '_grSstIsBusy@0');grSstIsBusy :=p;
    p := GetProcAddress (GlideHandle, '_grSstWinOpen@28');grsstwinopen:=p;
    p := GetProcAddress (GlideHandle, '_grSstWinClose@0');grsstwinclose:=p;
    p := GetProcAddress (GlideHandle, '_grSstControl@4');grSstControl :=p;
    p := GetProcAddress (GlideHandle, '_grSstQueryHardware@4');grSstQueryHardware :=p;
    p := GetProcAddress (GlideHandle, '_grSstQueryBoards@4');grSstQueryBoards :=p;
    p := GetProcAddress (GlideHandle, '_grSstOrigin@4');grSstOrigin :=p;
    p := GetProcAddress (GlideHandle, '_grSstSelect@4');grsstselect:=p;
    p := GetProcAddress (GlideHandle, '_grSstScreenHeight@0');grsstscreenheight:=p;
    p := GetProcAddress (GlideHandle, '_grSstScreenWidth@0');grsstscreenwidth:=p;

    p := GetProcAddress (GlideHandle, '_grSstStatus@0');grSstStatus :=p;
    //    grSstPassthruMode := GetProcAddress (GlideHandle, '_grSstPassthruMode@4');

    //  Drawing Statistics
    p := GetProcAddress (GlideHandle, '_grSstPerfStats@4');grSstPerfStats :=p;
    p := GetProcAddress (GlideHandle, '_grSstResetPerfStats@0');grSstResetPerfStats :=p;
    p := GetProcAddress (GlideHandle, '_grResetTriStats@0');grResetTriStats :=p;
    p := GetProcAddress (GlideHandle, '_grTriStats@8');grTriStats :=p;

    // Glide configuration and special effect maintenance functions
    p := GetProcAddress (GlideHandle, '_grAlphaBlendFunction@16');grAlphaBlendFunction :=p;
    p := GetProcAddress (GlideHandle, '_grAlphaCombine@20');grAlphaCombine :=p;
    p := GetProcAddress (GlideHandle, '_grAlphaControlsITRGBLighting@4');grAlphaControlsITRGBLighting :=p;
    p := GetProcAddress (GlideHandle, '_grAlphaTestFunction@4');grAlphaTestFunction :=p;
    p := GetProcAddress (GlideHandle, '_grAlphaTestReferenceValue@4');grAlphaTestReferenceValue :=p;
    p := GetProcAddress (GlideHandle, '_grChromakeyMode@4');grChromakeyMode :=p;
    p := GetProcAddress (GlideHandle, '_grChromakeyValue@4');grChromakeyValue :=p;
    p := GetProcAddress (GlideHandle, '_grClipWindow@16');grClipWindow :=p;
    p := GetProcAddress (GlideHandle, '_grColorCombine@20');grColorCombine :=p;
    p := GetProcAddress (GlideHandle, '_grColorMask@8');grColorMask :=p;
    p := GetProcAddress (GlideHandle, '_grCullMode@4');grCullMode :=p;
    p := GetProcAddress (GlideHandle, '_grConstantColorValue@4');grConstantColorValue :=p;
    p := GetProcAddress (GlideHandle, '_grConstantColorValue4@16');grConstantColorValue4 :=p;
    p := GetProcAddress (GlideHandle, '_grDepthBiasLevel@4');grDepthBiasLevel :=p;
    p := GetProcAddress (GlideHandle, '_grDepthBufferFunction@4');grDepthBufferFunction :=p;
    p := GetProcAddress (GlideHandle, '_grDepthBufferMode@4');grDepthBufferMode :=p;
    p := GetProcAddress (GlideHandle, '_grDepthMask@4');grDepthMask :=p;
    p := GetProcAddress (GlideHandle, '_grDisableAllEffects@0');grDisableAllEffects :=p;
    p := GetProcAddress (GlideHandle, '_grDitherMode@4');grDitherMode :=p;
    p := GetProcAddress (GlideHandle, '_grFogColorValue@4');grFogColorValue :=p;
    p := GetProcAddress (GlideHandle, '_grFogMode@4');grFogMode :=p;
    p := GetProcAddress (GlideHandle, '_grFogTable@4');grFogTable :=p;
    p := GetProcAddress (GlideHandle, '_grGammaCorrectionValue@4');grGammaCorrectionValue :=p;
    p := GetProcAddress (GlideHandle, '_grSplash@20');grSplash :=p;

    // texture mapping control functions
    p := GetProcAddress (GlideHandle, '_grTexCalcMemRequired@16');grTexCalcMemRequired :=p;
    p := GetProcAddress (GlideHandle, '_grTexTextureMemRequired@8');grTexTextureMemRequired :=p;
    p := GetProcAddress (GlideHandle, '_grTexMinAddress@4');grTexMinAddress :=p;
    p := GetProcAddress (GlideHandle, '_grTexMaxAddress@4');grTexMaxAddress :=p;
    p := GetProcAddress (GlideHandle, '_grTexNCCTable@8');grTexNCCTable :=p;
    p := GetProcAddress (GlideHandle, '_grTexSource@16');grTexSource :=p;
    p := GetProcAddress (GlideHandle, '_grTexClampMode@12');grTexClampMode :=p;
    p := GetProcAddress (GlideHandle, '_grTexCombine@28');grTexCombine :=p;
    p := GetProcAddress (GlideHandle, '_grTexCombineFunction@8');grTexCombineFunction :=p;
    p := GetProcAddress (GlideHandle, '_grTexDetailControl@16');grTexDetailControl :=p;
    p := GetProcAddress (GlideHandle, '_grTexFilterMode@12');grTexFilterMode :=p;
    p := GetProcAddress (GlideHandle, '_grTexLodBiasValue@8');grTexLodBiasValue :=p;
    p := GetProcAddress (GlideHandle, '_grTexDownloadMipMap@16');grTexDownloadMipMap :=p;
    p := GetProcAddress (GlideHandle, '_grTexDownloadMipMapLevel@32');grTexDownloadMipMapLevel :=p;
    p := GetProcAddress (GlideHandle, '_grTexDownloadMipMapLevelPartial@40');grTexDownloadMipMapLevelPartial :=p;
    p := GetProcAddress (GlideHandle, '_grTexDownloadTable@12');grTexDownloadTable :=p;
    p := GetProcAddress (GlideHandle, '_grTexDownloadTablePartial@20');grTexDownloadTablePartial :=p;
    p := GetProcAddress (GlideHandle, '_ConvertAndDownloadRle@64');ConvertAndDownloadRle :=p;
    p := GetProcAddress (GlideHandle, '_grCheckForRoom@4');grCheckForRoom :=p;
    p := GetProcAddress (GlideHandle, '_grTexMipMapMode@12');grTexMipMapMode :=p;
    p := GetProcAddress (GlideHandle, '_grTexMultibase@8');grTexMultibase :=p;
    p := GetProcAddress (GlideHandle, '_grTexMultibaseAddress@20');grTexMultibaseAddress :=p;

    // utility texture functions
    p := GetProcAddress (GlideHandle,  '_guTexAllocateMemory@60');guTexAllocateMemory :=p;
    p := GetProcAddress (GlideHandle,  '_guTexChangeAttributes@48');guTexChangeAttributes :=p;
    p := GetProcAddress (GlideHandle,  '_guTexCombineFunction@8');guTexCombineFunction :=p;
    p := GetProcAddress (GlideHandle,  '_guTexGetCurrentMipMap@4');guTexGetCurrentMipMap :=p;
    p := GetProcAddress (GlideHandle,  '_guTexGetMipMapInfo@4');guTexGetMipMapInfo :=p;
    p := GetProcAddress (GlideHandle,  '_guTexMemQueryAvail@4');guTexMemQueryAvail :=p;
    p := GetProcAddress (GlideHandle,  '_guTexMemReset@0');guTexMemReset :=p;
    p := GetProcAddress (GlideHandle,  '_guTexDownloadMipMap@12');guTexDownloadMipMap :=p;
    p := GetProcAddress (GlideHandle,  '_guTexDownloadMipMapLevel@12');guTexDownloadMipMapLevel :=p;
    p := GetProcAddress (GlideHandle,  '_guTexSource@4');guTexSource :=p;

    // linear frame buffer functions
    p := GetProcAddress (GlideHandle,  '_grLfbLock@24');grLfbLock :=p;
    p := GetProcAddress (GlideHandle,  '_grLfbUnlock@8');grLfbUnLock :=p;
    p := GetProcAddress (GlideHandle,  '_grLfbConstantAlpha@4');grLfbConstantAlpha :=p;
    p := GetProcAddress (GlideHandle,  '_grLfbConstantDepth@4');grLfbConstantDepth :=p;
    p := GetProcAddress (GlideHandle,  '_grLfbWriteColorSwizzle@8');grLfbWriteColorSwizzle :=p;
    p := GetProcAddress (GlideHandle,  '_grLfbWriteColorFormat@4');grLfbWriteColorFormat :=p;
    p := GetProcAddress (GlideHandle,  '_grLfbWriteRegion@32');grLfbWriteRegion :=p;
    p := GetProcAddress (GlideHandle,  '_grLfbReadRegion@28');grLfbReadRegion :=p;

    //  Antialiasing Functions
    p := GetProcAddress (GlideHandle,  '_grAADrawLine@8');grAADrawLine :=p;
    p := GetProcAddress (GlideHandle,  '_grAADrawPoint@4');grAADrawPoint :=p;
    p := GetProcAddress (GlideHandle,  '_grAADrawPolygon@12');grAADrawPolygon :=p;
    p := GetProcAddress (GlideHandle,  '_grAADrawPolygonVertexList@8');grAADrawPolygonVertexList :=p;
    p := GetProcAddress (GlideHandle,  '_grAADrawTriangle@24');grAADrawTriangle :=p;

    // glide management functions
    p := GetProcAddress (GlideHandle, '_grGlideInit@0');grglideinit:=p;
    p := GetProcAddress (GlideHandle,  '_grGlideShutdown@0');grglideshutdown:=p;
    p := GetProcAddress (GlideHandle,  '_grGlideGetVersion@4');grglidegetversion:=p;
    p := GetProcAddress (GlideHandle,  '_grGlideGetState@4');grGlideGetState :=p;
    p := GetProcAddress (GlideHandle,  '_grGlideSetState@4');grGlideSetState :=p;
    p := GetProcAddress (GlideHandle,  '_grGlideShamelessPlug@4');grglideshamelessplug:=p;
    p := GetProcAddress (GlideHandle,  '_grHints@8');grHints :=p;

// rendering functions
    p := GetProcAddress (GlideHandle,  '_guAADrawTriangleWithClip@12');guAADrawTriangleWithClip :=p;
    p := GetProcAddress (GlideHandle,  '_guDrawTriangleWithClip@12');guDrawTriangleWithClip :=p;
    p := GetProcAddress (GlideHandle,  '_guDrawPolygonVertexListWithClip@8');guDrawPolygonVertexListWithClip :=p;

    // hi-level rendering utility functions
    p := GetProcAddress (GlideHandle,  '_guAlphaSource@4');guAlphaSource :=p;
    p := GetProcAddress (GlideHandle,  '_guColorCombineFunction@4');guColorCombineFunction :=p;
    p := GetProcAddress (GlideHandle,  '_guEncodeRLE16@16');guEncodeRLE16 :=p;
    p := GetProcAddress (GlideHandle,  '_guTexCreateColorMipMap@0');guTexCreateColorMipMap :=p;

    // fog stuff
    p := GetProcAddress (GlideHandle,  '_guFogTableIndexToW@4');guFogTableIndexToW :=p;
    p := GetProcAddress (GlideHandle,  '_guFogGenerateExp@8');guFogGenerateExp :=p;
    p := GetProcAddress (GlideHandle,  '_guFogGenerateExp2@8');guFogGenerateExp2 :=p;
    p := GetProcAddress (GlideHandle,  '_guFogGenerateLinear@12');guFogGenerateLinear :=p;

    // endian stuff
    p := GetProcAddress (GlideHandle,  '_guEndianSwapWords@4');guEndianSwapWords :=p;
    p := GetProcAddress (GlideHandle,  '_guEndianSwapBytes@4');guEndianSwapBytes :=p;

    // hi-level texture manipulation tools.
    p := GetProcAddress (GlideHandle,  '_gu3dfGetInfo@8');gu3dfGetInfo :=p;
    p := GetProcAddress (GlideHandle,  '_gu3dfLoad@8');gu3dfLoad :=p;

    // movie capture stuff
    p := GetProcAddress (GlideHandle,  '_guMovieStart@0');guMovieStart :=p;
    p := GetProcAddress (GlideHandle,  '_guMovieStop@0');guMovieStop :=p;
    p := GetProcAddress (GlideHandle,  '_guMovieSetName@4');guMovieSetName :=p;

    Result:=True;
  end;
  GlideUnitIsInitalised := Result;
end;

function CloseGlideUnit : Boolean;
begin
  if GlideHandle <> 0 then
    begin
      FreeLibrary(GlideHandle);
      GlideHandle := 0;
    end;
  Result := True;
  GlideUnitIsInitalised := not Result;
end;

function GR_GENERATE_FIFOCHECK_HINT_MASK(var swHWM, swLWM) : longint;
begin
  Result := ((longint(swHWM) and $ffff) shl 16) or (longint(swLWM) and $ffff)
end;

function FXBIT(i :longint) : longint;
begin
  Result := 1 shl i;
end;

function FXUNUSED(a :longint) : boolean;
begin
  Result := a = 0;
end;


procedure SetIntelPrecision;
var
        memvar : LongInt;
begin
        //taken directly from the Glide 2.4 programming Guide
        asm
                finit
                fwait
                fstcw word ptr memvar
                fwait
                mov eax,memvar
                and eax,0fffffcffh
                mov memvar,eax
                fldcw word ptr memvar
                fwait
        end;
end;

initialization
begin
  GlideHandle := 0;
  InitGlideUnit;

  {$IFNDEF NO_SETINTELPRECISION}
  SetIntelPrecision;
  {$ENDIF}
end

finalization
begin
  CloseGlideUnit;
end

end.

