⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r_glide.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 3 页
字号:
// 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 + -