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

📄 r_glide.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 3 页
字号:
    SetWindowLong (lvid->WndParent, GWL_STYLE, WS_POPUP | WS_VISIBLE);
    SetWindowPos(lvid->WndParent, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE |
                 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);


    //cleanup previous mode
    if (grPreviousContext) {
        // close the current graphics subsystem
        DBG_Printf ("grSstWinClose()\n");
        grSstWinClose (grPreviousContext);
    }

    // create Glide window
    grPreviousContext = grSstWinOpen( (FxU32)lvid->WndParent,
                        iResolution,
                        GR_REFRESH_60Hz,      //note: we could always use the higher refresh?
                        GR_COLORFORMAT_ABGR,
                        GR_ORIGIN_UPPER_LEFT,
                        2, 1 );

    if ( !grPreviousContext ) {
        DBG_Printf ("grSstWinOpen() FAILED\n");
        return 0;
    }

    // for glide debug console
    //tlSetScreen (pcurrentmode->width, pcurrentmode->height);
    glide_initialized = true;
    GR_ResetStates (lvid);

    // force reload of patches because the memory is trashed while we change the screen
    GR_InitMipmapCache();

    lvid->buffer = NULL;    //unless we use the software view
    lvid->direct = NULL;    //direct access to video memory, old DOS crap

    currentmode_width = pcurrentmode->width;
    currentmode_height = pcurrentmode->height;

    // remember lvid here, to free the software buffer if we used it (software view)
    viddef = lvid;

    return 1;
}


// --------------------------------------------------------------------------
// Swap front and back buffers
// --------------------------------------------------------------------------
static int glide_console = 1;
EXPORT void HWRAPI( FinishUpdate ) ( int waitvbl )
{
    if (!grPreviousContext) {
        DBG_Printf ("HWRAPI FinishUpdate() : display not set\n");
        return;
    }

    /*
static int frame=0;
static int lasttic=0;
    int tic,fps;

    // draw silly stuff here
    if (glide_console & 1)
        tlPrintNumber (frame++);

    if (glide_console & 1)
    {
        tic = dl.I_GetTime();
        fps = TICRATE - (tic - lasttic) + 1;
        lasttic = tic;
        tlPrintNumber (fps);
    }
*/

    //DBG_Printf ("HWRAPI FinishUpdate()\n");

    // flip screen
    grBufferSwap( waitvbl );      
}


// --------------------------------------------------------------------------
//
// --------------------------------------------------------------------------
static unsigned long myPaletteData[256];  // 256 ARGB entries
//TODO: do the chroma key stuff out of here
EXPORT void HWRAPI( SetPalette ) (RGBA_t* pal, RGBA_t *gamma)
{
    int i;

    if (!grPreviousContext) {
        DBG_Printf ("HWRAPI SetPalette() : display not set\n");
        return;
    }

    // create the palette in the format used for downloading to 3Dfx card
    for (i=0; i<256; i++)
        myPaletteData[i] = (pal[i].s.alpha << 24) |          
                           (pal[i].s.red<<16)     |
                           (pal[i].s.green<<8)    |
                            pal[i].s.blue;

    // make sure the chromakey color is always the same value
    myPaletteData[HWR_PATCHES_CHROMAKEY_COLORINDEX] = HWR_PATCHES_CHROMAKEY_COLORVALUE;

    grTexDownloadTable (GR_TEXTABLE_PALETTE, (void*)myPaletteData);
    guGammaCorrectionRGB(gamma->s.red/127.0f,gamma->s.green/127.0f,gamma->s.blue/127.0f);
}


// **************************************************************************
//
// **************************************************************************

// store min/max w depth buffer values here, used to clear buffer
static  FxU32  gr_wrange[2];


// --------------------------------------------------------------------------
// Do a full buffer clear including color / alpha / and Z buffers
// --------------------------------------------------------------------------
static void BufferClear (void)
{
    if (!grPreviousContext) {
        DBG_Printf ("BufferClear() : display not set\n");
        return;
    }
    grDepthMask (FXTRUE);
    grColorMask (FXTRUE,FXFALSE);
    grBufferClear(0x00000000, 0, gr_wrange[1]);
}


//
// set initial state of 3d card settings
//
static void GR_ResetStates (viddef_t *lvid)
{
    DBG_Printf ("ResetStates()\n");

    if (!grPreviousContext) {
        DBG_Printf ("ResetStates() : display not set\n");
        return;
    }
    //grSplash( 64, 64, SCREEN_WIDTH-64, SCREEN_HEIGHT-64, 0 ); //splash screen!

    // get min/max w buffer range values
    grGet (GR_WDEPTH_MIN_MAX, 8, gr_wrange);
    grCoordinateSpace(GR_CLIP_COORDS);
    grViewport((FxU32)0, (FxU32)0, (FxU32)lvid->width, (FxU32)lvid->height);

    // don't work ! the only function that support this is drawpoly
    // y=0 is in lower left corner, (not like in vga)
    //grSstOrigin( GR_ORIGIN_LOWER_LEFT );


    // initialize depth buffer type
    grDepthRange( 0.0, 1.0 );
    grDepthBufferMode(GR_DEPTHBUFFER_WBUFFER);
    grDepthBufferFunction( GR_CMP_LEQUAL );
    grDepthMask( FXTRUE );
    grColorMask ( FXTRUE, FXFALSE);

    // my vertex format
    grVertexLayout(GR_PARAM_XY   , FIELD_OFFSET(FOutVector,x)   , GR_PARAM_ENABLE);
    grVertexLayout(GR_PARAM_PARGB, FIELD_OFFSET(FOutVector,argb), GR_PARAM_ENABLE);
    //grVertexLayout(GR_PARAM_Q, 12, GR_PARAM_ENABLE);
    grVertexLayout(GR_PARAM_W    , FIELD_OFFSET(FOutVector,oow) , GR_PARAM_ENABLE);
    grVertexLayout(GR_PARAM_ST0  , FIELD_OFFSET(FOutVector,sow) , GR_PARAM_ENABLE);  //s and t for tmu0

    grTexCombine (GR_TMU0, GR_COMBINE_FUNCTION_LOCAL,
                  GR_COMBINE_FACTOR_NONE,
                  GR_COMBINE_FUNCTION_LOCAL,
                  GR_COMBINE_FACTOR_NONE,
                  FXFALSE, FXFALSE );

    // no mipmaps based on depth
    grTexMipMapMode (GR_TMU0, GR_MIPMAP_DISABLE, FXFALSE );

    grConstantColorValue (0xffffffff);
    
    grChromakeyValue(HWR_PATCHES_CHROMAKEY_COLORVALUE);

    grAlphaTestReferenceValue( 0 );

    // this set CurrentPolyFlags to the acctual configuration
    CurrentPolyFlags = 0xffffffff;
    SetBlend(0);

    BufferClear();
    MakeFogTable();
    ReSetSpecialState();
}


// **************************************************************************
//                                               3DFX MEMORY CACHE MANAGEMENT
// **************************************************************************

#define TEXMEM_2MB_EDGE         (1<<21)

static  FxU32           gr_cachemin;
static  FxU32           gr_cachemax;

static  FxU32           gr_cachepos;
static  GlideMipmap_t*  gr_cachetail = NULL;
static  GlideMipmap_t*  gr_cachehead;
static  GlideMipmap_t*  lastmipmapset;

// --------------------------------------------------------------------------
// This must be done once only for all program execution
// --------------------------------------------------------------------------
GlideMipmap_t fakemipmap;
static void GR_ClearMipmapCache (void)
{
    while (gr_cachetail)
    {
        gr_cachetail->downloaded = false;
        gr_cachehead = gr_cachetail;
        gr_cachetail = gr_cachetail->nextmipmap;
        gr_cachehead->nextmipmap = NULL;
    }

    // make a dummy first just for easy cache handling
    fakemipmap.cachepos = gr_cachemin;
    fakemipmap.mipmapSize = grTexCalcMemRequired(GR_LOD_LOG2_1,GR_LOD_LOG2_1,GR_ASPECT_LOG2_1x1,GR_TEXFMT_P_8);
    fakemipmap.downloaded = true;
    fakemipmap.nextmipmap = NULL;
    lastmipmapset = NULL;

    gr_cachetail = &fakemipmap;
    gr_cachehead = &fakemipmap;
    gr_cachepos = gr_cachetail->cachepos+fakemipmap.mipmapSize;

    DBG_Printf ("Cache cleared\n");
}

EXPORT void HWRAPI( ClearMipMapCache ) (void)
{
    GR_ClearMipmapCache ();
}

static void GR_InitMipmapCache (void)
{
    gr_cachemin = grTexMinAddress(GR_TMU0);
    gr_cachemax = grTexMaxAddress(GR_TMU0);

    //testing..
    // reduise memory so there will use more the legacy heap
    //gr_cachemax = gr_cachemin + (256<<10);

    if( gr_cachemax-gr_cachemin < 64<<10 )
        I_ErrorGr("R_Glide : Only %d memory available for texture !\n",gr_cachemax-gr_cachemin);

    GR_ClearMipmapCache();

    DBG_Printf ("HWR_InitMipmapCache() : %d kb, from %x to %x\n"
                "tmu2 : from %x to %x\n", (gr_cachemax-gr_cachemin)>>10,gr_cachemin,gr_cachemax,grTexMinAddress(GR_TMU1),grTexMaxAddress(GR_TMU1));
}

static boolean possibleproblem=false;

static void GR_FlushMipmap ()
{
    if( !gr_cachetail)
        return;
    if(!gr_cachetail->downloaded)
        DBG_Printf ("flush not dowloaded !!\n");
    gr_cachetail->downloaded = false;
    // should never happen
    if (!gr_cachetail->nextmipmap)
    {
        if( possibleproblem )
            I_ErrorGr ("This just CAN'T HAPPEN!!! So you think you're different eh ?");
        possibleproblem=true;
        DBG_Printf ("Never happen happen !!\n");
        GR_ClearMipmapCache ();
    }
    else
    {
//        DBG_Printf ("fluching mipmap at position %d (%d bytes) tailpos=%d (%d byte)\n",gr_cachetail->cachepos,gr_cachetail->mipmapSize,gr_cachetail->nextmipmap->cachepos,gr_cachetail->nextmipmap->mipmapSize);
        gr_cachetail->cachepos = 0;
        gr_cachetail->mipmapSize = -1;
        gr_cachetail = gr_cachetail->nextmipmap;
    }
}

// --------------------------------------------------------------------------
// Download a 'surface' into the graphics card memory
// --------------------------------------------------------------------------
static void GR_DownloadMipmap (GlideMipmap_t* grMipmap)
{
    FxU32   mipmapSize;

    if (!grPreviousContext) {
        DBG_Printf ("HWRAPI DownloadMipmap() : display not set\n");
        return;
    }

    if ( !grMipmap->grInfo.data ) {
        DBG_Printf ("HWRAPI DownloadMipmap() : No DATA !!!\n");
        return;
    }
        
    mipmapSize = grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &grMipmap->grInfo);

    while (1)
    {
        // 3Dfx specs : a mipmap level can not straddle the 2MByte boundary
        if (gr_cachetail->cachepos >= gr_cachepos)
        {
            if (gr_cachetail->cachepos >= gr_cachepos + mipmapSize)
                if((gr_cachepos < TEXMEM_2MB_EDGE) && (gr_cachepos+mipmapSize > TEXMEM_2MB_EDGE))
                {
                    if( gr_cachetail->cachepos >= TEXMEM_2MB_EDGE )
                    {    
                        gr_cachepos = TEXMEM_2MB_EDGE;
                        continue;
                    }
                    // else FlushMipmap
                }
                else
                    break;
            GR_FlushMipmap ();
        }
        else
        {
            if (gr_cachemax >= gr_cachepos + mipmapSize)
            {
                if((gr_cachepos < TEXMEM_2MB_EDGE) && (gr_cachepos+mipmapSize > TEXMEM_2MB_EDGE) && (gr_cachetail->cachepos < TEXMEM_2MB_EDGE))
                    gr_cachepos = TEXMEM_2MB_EDGE;
                else
                    break;
            }
            else
                // not enough space in the end of the buffer
                gr_cachepos = gr_cachemin;
                //dbg_printf ("        cycle over\n");
        }
        //dbg_printf ("        tailpos: %7d pos: %7d size: %7d free: %7d\n",
        //            gr_cachetail->cachepos, gr_cachepos, mipmapsize, freespace);
    }
    gr_cachehead->nextmipmap = grMipmap;
   
    //DBG_Printf ("download %d byte at %d\n",mipmapSize,gr_cachepos);

    grTexDownloadMipMap (GR_TMU0, gr_cachepos, GR_MIPMAPLEVELMASK_BOTH, &grMipmap->grInfo);
    grMipmap->cachepos     = gr_cachepos;
    grMipmap->mipmapSize   = mipmapSize;
    grMipmap->downloaded   = true;
    grMipmap->nextmipmap    = NULL;     // the head don't have next

    gr_cachepos += mipmapSize;

    gr_cachehead = grMipmap;   // the head is the last loaded texture (FIFO)
    possibleproblem=false;
}


// ==========================================================================
// The mipmap becomes the current texture source
// ==========================================================================
EXPORT void HWRAPI( SetTexture ) (GlideMipmap_t* grMipmap)
{
    FBITFIELD xor;
    if (!grPreviousContext) {
        DBG_Printf ("HWRAPI SetTexture() : display not set\n");
        return;
    }

    // don't set exactely the same mipmap 
    if( lastmipmapset == grMipmap )
        return;

    if (!grMipmap->downloaded)
        GR_DownloadMipmap (grMipmap);

    xor = grMipmap->flags ^ CurrentTextureFlags;
    if(xor)
    {
        if(xor&TF_WRAPXY)
        {
            switch(grMipmap->flags & TF_WRAPXY)
        {
            case 0 :
                grTexClampMode (GR_TMU0, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_CLAMP);
                break;
            case TF_WRAPX :
                grTexClampMode (GR_TMU0, GR_TEXTURECLAMP_WRAP , GR_TEXTURECLAMP_CLAMP);
                break;
            case TF_WRAPY :
                grTexClampMode (GR_TMU0, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_WRAP);
                break;
            case TF_WRAPXY :
                grTexClampMode (GR_TMU0, GR_TEXTURECLAMP_WRAP, GR_TEXTURECLAMP_WRAP);
                break;
        }
        }
        if( xor & TF_CHROMAKEYED )
        {
            if(grMipmap->flags & TF_CHROMAKEYED )
                grChromakeyMode (GR_CHROMAKEY_ENABLE);
            else
                grChromakeyMode (GR_CHROMAKEY_DISABLE);
        }
        CurrentTextureFlags = grMipmap->flags;
    }
    grTexSource (GR_TMU0, grMipmap->cachepos, GR_MIPMAPLEVELMASK_BOTH, &grMipmap->grInfo);
    lastmipmapset = grMipmap;
}


// -----------------+
// SetBlend         : Set render mode
// -----------------+
// PF_Masked - we could use an ALPHA_TEST of GL_EQUAL, and alpha ref of 0,
//             is it faster when pixels are discarded ?
EXPORT void HWRAPI(     SetBlend ) ( FBITFIELD PolyFlags )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -