📄 r_glide.c
字号:
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id: r_glide.c,v 1.22 2001/02/24 13:35:22 bpereira Exp $
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//
// $Log: r_glide.c,v $
// Revision 1.22 2001/02/24 13:35:22 bpereira
// no message
//
// Revision 1.21 2001/01/25 18:56:28 bpereira
// no message
//
// Revision 1.20 2001/01/05 18:19:13 hurdler
// add renderer version checking
//
// Revision 1.19 2000/11/04 16:23:45 bpereira
// no message
//
// Revision 1.18 2000/10/08 13:30:02 bpereira
// no message
//
// Revision 1.17 2000/10/04 16:29:57 hurdler
// Implement hardware texture memory stats (TODO in glide mode)
//
// Revision 1.16 2000/09/28 20:57:21 bpereira
// no message
//
// Revision 1.15 2000/08/31 14:30:57 bpereira
// no message
//
// Revision 1.14 2000/08/10 14:17:58 hurdler
// add waitvbl
//
// Revision 1.13 2000/08/03 17:57:42 bpereira
// no message
//
// Revision 1.12 2000/07/01 09:23:50 bpereira
// no message
//
// Revision 1.11 2000/05/09 20:50:57 hurdler
// remove warning
//
// Revision 1.10 2000/05/05 18:00:06 bpereira
// no message
//
// Revision 1.9 2000/04/30 10:30:10 bpereira
// no message
//
// Revision 1.8 2000/04/23 16:19:52 bpereira
// no message
//
// Revision 1.7 2000/04/18 12:50:55 hurdler
// join with Boris' code
//
// Revision 1.5 2000/04/14 16:38:24 hurdler
// some nice changes for coronas
//
// Revision 1.4 2000/03/06 15:26:17 hurdler
// change version number
//
// Revision 1.3 2000/02/27 00:42:11 hurdler
// fix CR+LF problem
//
// Revision 1.2 2000/02/26 00:28:42 hurdler
// Mostly bug fix (see borislog.txt 23-2-2000, 24-2-2000)
//
//
// DESCRIPTION:
// 3Dfx Glide Render driver
//
//-----------------------------------------------------------------------------
#include <windows.h>
#include <glide.h>
#include <math.h>
#define _CREATE_DLL_
#include "../hw_drv.h"
#include "../../screen.h"
#include "3dmath.h"
#undef DEBUG_TO_FILE
#define DEBUG_TO_FILE //output debugging msgs to r_glide.log
// **************************************************************************
// PROTOS
// **************************************************************************
// output all debugging messages to this file
#ifdef DEBUG_TO_FILE
static HANDLE logstream;
#endif
static void GR_ResetStates(viddef_t *lvid);
static void GR_InitMipmapCache(void);
static void GR_ClearMipmapCache(void);
static void MakeFogTable(void);
static void FreeFogTable(void);
static void ReSetSpecialState(void);
// **************************************************************************
// GLOBALS
// **************************************************************************
//0 means glide mode not set yet, this is returned by grSstWinOpen()
static GrContext_t grPreviousContext = 0;
// align boundary for textures in texture cache, set at Init()
static FxU32 gr_alignboundary;
static FBITFIELD CurrentPolyFlags;
static FBITFIELD CurrentTextureFlags;
static FOutVector tmpVerts[MAXCLIPVERTS*2];
static FOutVector tmp2Verts[MAXCLIPVERTS*2];
static I_Error_t I_ErrorGr = NULL;
static glide_initialized = false;
static int glide_state[HWD_NUMSTATE];
// **************************************************************************
// DLL ENTRY POINT
// **************************************************************************
BOOL APIENTRY DllMain( HANDLE hModule, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
#ifdef DEBUG_TO_FILE
logstream = INVALID_HANDLE_VALUE;
logstream = CreateFile ("r_glide.log", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL/*|FILE_FLAG_WRITE_THROUGH*/, NULL);
if (logstream == INVALID_HANDLE_VALUE)
return FALSE;
#endif
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
#ifdef DEBUG_TO_FILE
if ( logstream != INVALID_HANDLE_VALUE ) {
CloseHandle ( logstream );
logstream = INVALID_HANDLE_VALUE;
}
#endif
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
// ----------
// DBG_Printf
// Output error messages to debug log if DEBUG_TO_FILE is defined,
// else do nothing
// ----------
void DBG_Printf (LPCTSTR lpFmt, ...)
{
#ifdef DEBUG_TO_FILE
char str[1999];
va_list arglist;
DWORD bytesWritten;
va_start (arglist, lpFmt);
vsprintf (str, lpFmt, arglist);
va_end (arglist);
if ( logstream != INVALID_HANDLE_VALUE )
WriteFile (logstream, str, lstrlen(str), &bytesWritten, NULL);
#endif
}
// error callback function
void GrErrorCallbackFnc (const char *string, FxBool fatal)
{
DBG_Printf ("Glide error(%d) : %s\n",string,fatal);
if( fatal && I_ErrorGr )
I_ErrorGr ("Glide error : %s",string);
}
// ==========================================================================
// Initialise
// ==========================================================================
EXPORT BOOL HWRAPI( Init ) (I_Error_t FatalErrorFunction)
{
FxU32 numboards;
FxI32 fxret;
I_ErrorGr = FatalErrorFunction;
DBG_Printf ("HWRAPI Init(): 3Dfx Glide Render driver for Doom Legacy v1.31\n");
// check for Voodoo card
// - the ONLY possible call before GlideInit
grGet (GR_NUM_BOARDS,4,&numboards);
DBG_Printf ("Num 3Dfx boards : %d\n", numboards);
if (!numboards) {
I_ErrorGr ("3dfx chipset not detected\n");
return FALSE;
}
// init
grGlideInit();
grErrorSetCallback(GrErrorCallbackFnc);
// select subsystem
grSstSelect( 0 );
DBG_Printf( "GR_VENDOR: %s\n", grGetString(GR_VENDOR) );
DBG_Printf( "GR_EXTENSION: %s\n", grGetString(GR_EXTENSION) );
DBG_Printf( "GR_HARDWARE: %s\n", grGetString(GR_HARDWARE) );
DBG_Printf( "GR_RENDERER: %s\n", grGetString(GR_RENDERER) );
DBG_Printf( "GR_VERSION: %s\n", grGetString(GR_VERSION) );
// info
grGet (GR_MAX_TEXTURE_SIZE, 4, &fxret);
DBG_Printf ( "Max texture size : %d\n", fxret);
grGet (GR_NUM_TMU, 4, &fxret);
DBG_Printf ( "Number of TMU's : %d\n", fxret);
grGet (GR_TEXTURE_ALIGN, 4, &fxret);
DBG_Printf ( "Align boundary for textures : %d\n", fxret);
// save for later!
gr_alignboundary = fxret;
if (fxret==0)
gr_alignboundary = 16; //hack, need to be > 0
glide_state[HWD_SET_FOG_MODE] = 1;
glide_state[HWD_SET_FOG_COLOR] = 0x7f7f7f;
glide_state[HWD_SET_FOG_DENSITY] = 500;
glide_state[HWD_SET_POLYGON_SMOOTH] = false;
glide_state[HWD_SET_TEXTUREFILTERMODE] = HWD_SET_TEXTUREFILTER_BILINEAR;
return TRUE;
}
static viddef_t* viddef;
// ==========================================================================
//
// ==========================================================================
EXPORT void HWRAPI( Shutdown ) (void)
{
DBG_Printf ("HWRAPI Shutdown()\n");
grGlideShutdown();
FreeFogTable();
glide_initialized = false;
}
// **************************************************************************
// 3DFX DISPLAY MODES DRIVER
// **************************************************************************
static int Set3DfxMode (viddef_t *lvid, vmode_t *pcurrentmode) ;
// --------------------------------------------------------------------------
//
// --------------------------------------------------------------------------
#define MAX_VIDEO_MODES 30
static vmode_t video_modes[MAX_VIDEO_MODES] = {{NULL, NULL}};
EXPORT void HWRAPI( GetModeList ) (vmode_t** pvidmodes, int* numvidmodes)
{
GrResolution query;
GrResolution *list;
GrResolution *grRes;
char* resTxt;
int listSize;
int listPos;
int iPrevWidth, iPrevHeight; //skip duplicate modes
int iMode, iWidth, iHeight;
DBG_Printf ("HWRAPI GetModeList()\n");
// find all possible modes that include a z-buffer
query.resolution = GR_QUERY_ANY;
query.refresh = GR_QUERY_ANY;
query.numColorBuffers = 2; //GR_QUERY_ANY;
query.numAuxBuffers = 1;
listSize = grQueryResolutions (&query, NULL);
list = _alloca(listSize);
grQueryResolutions (&query, list);
iMode=0;
grRes = list;
iPrevWidth = 0; iPrevHeight = 0;
for (listPos=0; listPos<listSize; listPos+=sizeof(GrResolution) , grRes++)
{
if (iMode>=MAX_VIDEO_MODES)
{
DBG_Printf ("Too many vidmode\n");
break; // quit the for
}
switch (grRes->resolution)
{
case GR_RESOLUTION_320x200 : resTxt = "320x200"; iWidth = 320; iHeight = 200; break;
case GR_RESOLUTION_320x240 : resTxt = "320x240"; iWidth = 320; iHeight = 240; break;
case GR_RESOLUTION_400x256 : resTxt = "400x256"; iWidth = 400; iHeight = 256; break;
case GR_RESOLUTION_512x384 : resTxt = "512x384"; iWidth = 512; iHeight = 384; break;
case GR_RESOLUTION_640x200 : resTxt = "640x200"; iWidth = 640; iHeight = 200; break;
case GR_RESOLUTION_640x350 : resTxt = "640x350"; iWidth = 640; iHeight = 350; break;
case GR_RESOLUTION_640x400 : resTxt = "640x400"; iWidth = 640; iHeight = 400; break;
case GR_RESOLUTION_640x480 : resTxt = "640x480"; iWidth = 640; iHeight = 480; break;
case GR_RESOLUTION_800x600 : resTxt = "800x600"; iWidth = 800; iHeight = 600; break;
case GR_RESOLUTION_960x720 : resTxt = "960x720"; iWidth = 960; iHeight = 720; break;
case GR_RESOLUTION_856x480 : resTxt = "856x480"; iWidth = 856; iHeight = 480; break;
case GR_RESOLUTION_512x256 : resTxt = "512x256"; iWidth = 512; iHeight = 256; break;
case GR_RESOLUTION_1024x768 : resTxt = "1024x768"; iWidth = 1024; iHeight = 768; break;
case GR_RESOLUTION_1280x1024: resTxt = "1280x1024"; iWidth = 1280; iHeight = 1024; break;
case GR_RESOLUTION_1600x1200: resTxt = "1600x1200"; iWidth = 1600; iHeight = 1200; break;
case GR_RESOLUTION_400x300 : resTxt = "400x300"; iWidth = 400; iHeight = 300; break;
case GR_RESOLUTION_NONE : resTxt = "NONE"; iWidth = 0; iHeight = 0; break;
default:
iWidth = 0; iHeight = 0;
resTxt = "unknown resolution"; break;
}
if( iWidth == 0 || iHeight == 0)
{
DBG_Printf ("Wrong Mode (%s)\n",resTxt);
continue;
}
// skip duplicate resolutions where only the refresh rate changes
if( iWidth==iPrevWidth && iHeight==iPrevHeight)
{
DBG_Printf ("Same mode (%s) %d\n",resTxt,grRes->refresh);
continue;
}
// disable too big modes until we get it fixed
if ( iWidth > MAXVIDWIDTH || iHeight > MAXVIDHEIGHT )
{
DBG_Printf ("Mode too big (%s)\n",resTxt);
continue;
}
// save video mode information for video modes menu
video_modes[iMode].pnext = &video_modes[iMode+1];
video_modes[iMode].windowed = 0;
video_modes[iMode].misc = grRes->resolution;
video_modes[iMode].name = resTxt;
video_modes[iMode].width = iWidth;
video_modes[iMode].height = iHeight;
video_modes[iMode].rowbytes = iWidth * 2; //framebuffer 16bit, but we don't use this anyway..
video_modes[iMode].bytesperpixel = 2;
video_modes[iMode].pextradata = NULL; // for VESA, unused here
video_modes[iMode].setmode = Set3DfxMode;
DBG_Printf ("Mode %d : %s (%dx%d) %dHz ires %d \n",
iMode,resTxt, iWidth, iHeight, grRes->refresh, grRes->resolution);
iMode++;
iPrevWidth = iWidth; iPrevHeight = iHeight;
}
// add video modes to the list
if (iMode>0)
{
video_modes[iMode-1].pnext = NULL;
(*(vmode_t**)pvidmodes) = &video_modes[0];
(*numvidmodes) = iMode;
}
// VGA Init equivalent (add first defautlt mode)
//glidevidmodes[NUMGLIDEVIDMODES-1].pnext = NULL;
//*((vmode_t**)pvidmodes) = &glidevidmodes[0];
//*numvidmodes = NUMGLIDEVIDMODES;
}
static int currentmode_width;
static int currentmode_height;
// Set3DfxMode
// switch to one of the video modes querried at initialization
static int Set3DfxMode (viddef_t *lvid, vmode_t *pcurrentmode)
{
int iResolution;
// we stored the GR_RESOLUTION_XXX number into the 'misc' field
iResolution = pcurrentmode->misc;
DBG_Printf ("Set3DfxMode() iResolution(%d)\n", iResolution);
// this is normally not used (but we are actually double-buffering with glide)
lvid->u.numpages = 2;
// Change window attributes
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -