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

📄 fabdxlib.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 2 页
字号:
        
        
        //TODO: get the desktop bit depth, and build a lookup table
        // for quick conversions of 8bit color indexes 0-255 to desktop colors
        // eg: 256 entries of equivalent of palette colors 0-255 in 15,16,24,32 bit format
        // when blit virtual to real, convert pixels through lookup table..
        
        
        // Use a clipper object for clipping when in windowed mode
        // (make sure our drawing doesn't affect other windows)
        
        ddrval = DDr2->lpVtbl->CreateClipper (DDr2, 0, &windclip, 0);
        if (ddrval != DD_OK)
            I_Error ("CreateClipper FAILED");
        
        // Associate the clipper with the window.
        ddrval = windclip->lpVtbl->SetHWnd (windclip,0, appWin);
        if (ddrval != DD_OK)
            I_Error ("Clipper -> SetHWnd  FAILED");
        
        // Attach the clipper to the surface.
        ddrval = ScreenReal->lpVtbl->SetClipper (ScreenReal,windclip);
        if (ddrval != DD_OK)
            I_Error ("PrimaryScreen -> SetClipperClipper  FAILED");
    }
    
    return TRUE;    
}


//
// Free all memory
//
void    CloseDirectDraw (void)
{
    if (DDr2 != NULL)
    {
        SAFE_RELEASE (windclip);
        SAFE_RELEASE (DDPalette);
        
        // If the app is fullscreen, the back buffer is attached to the
        // primary. Releasing the primary buffer will also release any
        // attached buffers, so explicitly releasing the back buffer is not
        // necessary.
        
        if (!bAppFullScreen)
            SAFE_RELEASE (ScreenVirtual);   // release hidden surface
        SAFE_RELEASE (ScreenReal);                      // and attached backbuffers for bAppFullScreen mode
        DDr2->lpVtbl->Release(DDr2);
        DDr2 = NULL;
    }
}


//
// Release DirectDraw stuff before display mode change
//
void    ReleaseChtuff (void)
{
    if (DDr2 != NULL)
    {
        SAFE_RELEASE (windclip);
        SAFE_RELEASE (DDPalette);
        
        // If the app is fullscreen, the back buffer is attached to the
        // primary. Releasing the primary buffer will also release any
        // attached buffers, so explicitly releasing the back buffer is not
        // necessary.
        
        if (!bAppFullScreen)
            SAFE_RELEASE (ScreenVirtual);   // release hidden surface
        SAFE_RELEASE (ScreenReal);                      // and attached backbuffers for bAppFullScreen mode
    }
}


//
// Clear the surface to color
//
void ClearSurface (IDirectDrawSurface* surface, int color)
{
    DDBLTFX             ddbltfx;
    
    // Use the blter to do a color fill to clear the back buffer
    ddbltfx.dwSize = sizeof(ddbltfx);
    ddbltfx.dwFillColor = color;
    surface->lpVtbl->Blt(surface,NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
    
}


//
// Flip the real page with virtual page
// - in bAppFullScreen mode, do page flipping
// - in windowed mode, copy the hidden surface to the visible surface
//
// waitflip : if not 0, wait for page flip to end
BOOL ScreenFlip (int waitflip)
{
    HRESULT hr;
    RECT    rect;
    
    if (bAppFullScreen)
    {               
        //hr = ScreenReal->lpVtbl->GetFlipStatus (ScreenReal, DDGFS_);
        
        // In full-screen exclusive mode, do a hardware flip.
        hr = ScreenReal->lpVtbl->Flip(ScreenReal, NULL, DDFLIP_WAIT);   //return immediately
        
        // If the surface was lost, restore it.
        if (hr == DDERR_SURFACELOST)
        {
            ScreenReal->lpVtbl->Restore(ScreenReal);
            
            // The restore worked, so try the flip again.
            hr = ScreenReal->lpVtbl->Flip(ScreenReal, 0, DDFLIP_WAIT);
        }
    }
    else
    {
        rect.left = windowPosX;
        rect.top = windowPosY;
        rect.right = windowPosX + ScreenWidth - 1;
        rect.bottom = windowPosY + ScreenHeight - 1;
        
        // Copy the back buffer to front.
        hr = ScreenReal->lpVtbl->Blt(ScreenReal,&rect, ScreenVirtual, 0, DDBLT_WAIT, 0);
        
        if (hr!=DD_OK)
        {
            // If the surfaces were lost, restore them.
            if (ScreenReal->lpVtbl->IsLost(ScreenReal) == DDERR_SURFACELOST)                        
                ScreenReal->lpVtbl->Restore(ScreenReal);
            
            if (ScreenVirtual->lpVtbl->IsLost(ScreenVirtual) == DDERR_SURFACELOST)
                ScreenVirtual->lpVtbl->Restore(ScreenVirtual);
            
            // Retry the copy.
            hr = ScreenReal->lpVtbl->Blt(ScreenReal,&rect, ScreenVirtual, 0, DDBLT_WAIT, 0);
        }
    }
    
    if (hr != DD_OK)
        I_Error ("ScreenFlip() : couldn't Flip surfaces");
    
    return FALSE;
}


//
// Print a text to the surface
//
void TextPrint (int x, int y, char* message)
{
    HRESULT hr;
    HDC             hdc = NULL;
    
    // Get the device context handle.
    hr = ScreenVirtual->lpVtbl->GetDC(ScreenVirtual,&hdc);
    if (hr != DD_OK)
        return;
    
    // Write the message.
    SetBkMode(hdc, TRANSPARENT);
    SetTextColor(hdc, RGB(255, 255, 255));
    TextOut(hdc, x, y, message, strlen(message));
    
    // Release the device context.
    hr = ScreenVirtual->lpVtbl->ReleaseDC(ScreenVirtual,hdc);
}


//
// Lock surface before multiple drawings by hand, for speed
//
boolean LockScreen(void)
{
    DDSURFACEDESC  ddsd;
    HRESULT        ddrval;
    
    memset( &ddsd, 0, sizeof( ddsd ));
    ddsd.dwSize = sizeof( ddsd );
    
    // attempt to Lock the surface
    ddrval = ScreenVirtual->lpVtbl->Lock(ScreenVirtual, NULL, &ddsd, DDLOCK_WAIT, NULL);
    
    // Always, always check for errors with DirectX!
    
    // If the surface was lost, restore it.
    if (ddrval == DDERR_SURFACELOST)
    {
        ddrval = ScreenReal->lpVtbl->Restore (ScreenReal);
        
        // now retry to get the lock
        ddrval = ScreenVirtual->lpVtbl->Lock(ScreenVirtual, NULL, &ddsd, DDLOCK_WAIT, NULL);
    }
    
    if( ddrval == DD_OK )
    {
        ScreenLocked = TRUE;
        ScreenPtr    = (unsigned char*)ddsd.lpSurface;
        ScreenPitch = ddsd.lPitch;
    }
    else
    {
        ScreenLocked = FALSE;
        ScreenPtr        = NULL;
        ScreenPitch = 0;
        //I_Error ("LockScreen() : couldn't restore the surface.");
        return false;
    }
    return true;
}


//
// Unlock surface
//
void UnlockScreen(void)
{
    if (DD_OK != ScreenVirtual->lpVtbl->Unlock(ScreenVirtual,NULL))
        I_Error ("Couldn't UnLock the renderer!");
    
    ScreenLocked = FALSE;
    ScreenPtr    = NULL;
    ScreenPitch = 0;
}


// Blit virtual screen to real screen
//faB: note: testing 14/03/1999, see if it is faster than memcopy of virtual to 
/*
static    LPDIRECTDRAWSURFACE lpDDS = NULL;
void BlitScreen (void)
{
    HRESULT hr;

    if (!lpDDS)
        I_Error ("lpDDS NULL");

    hr = ScreenVirtual->lpVtbl->BltFast(ScreenVirtual,
                    0, 0,    // Upper left xy of destination
                    lpDDS, // Source surface
                    NULL,        // Source rectangle = entire surface
                    DDBLTFAST_WAIT | DDBLTFAST_NOCOLORKEY );
    if (FAILED(hr))
        I_Error ("BltFast FAILED");
}


void MakeScreen (int width, int height, BYTE* lpSurface)
{
    HRESULT hr;
    DDSURFACEDESC    ddsd;

    // Initialize the surface description.
    ZeroMemory (&ddsd, sizeof(ddsd));
    ZeroMemory (&ddsd.ddpfPixelFormat, sizeof(DDPIXELFORMAT));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | //DDSD_LPSURFACE |
                   DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_CAPS;
    ddsd.dwWidth = width;
    ddsd.dwHeight= height;
    ddsd.lPitch  = width;
    ddsd.lpSurface = lpSurface;
    ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
 
    // Set up the pixel format for 8-bit
    ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
    ddsd.ddpfPixelFormat.dwFlags= DDPF_RGB | DDPF_PALETTEINDEXED8;
    ddsd.ddpfPixelFormat.dwRGBBitCount = 8;

    //
      ddsd.ddpfPixelFormat.dwRGBBitCount = (DWORD)DEPTH*8;
    ddsd.ddpfPixelFormat.dwRBitMask    = 0x00FF0000;
    ddsd.ddpfPixelFormat.dwGBitMask    = 0x0000FF00;
    ddsd.ddpfPixelFormat.dwBBitMask    = 0x000000FF;
 
    // Create the surface
    hr = DDr2->lpVtbl->CreateSurface (DDr2, &ddsd, &lpDDS, NULL);
    if (FAILED(hr))
        I_Error ("MakeScreen FAILED: %s",DDError(hr));
    //ddsd.lpSurface = lpSurface;
}
*/

//
// Create a palette object
// 
void CreateDDPalette (PALETTEENTRY* colorTable)
{
    HRESULT  ddrval;
    ddrval = DDr2->lpVtbl->CreatePalette(DDr2,DDPCAPS_8BIT|DDPCAPS_ALLOW256, colorTable, &DDPalette, NULL);
    if (ddrval != DD_OK)
        I_Error ("couldn't CreatePalette");
};


//
// Free the palette object
//
void DestroyDDPalette (void)
{
    SAFE_RELEASE(DDPalette);
}


//
// Set a a full palette of 256 PALETTEENTRY entries
//
void SetDDPalette (PALETTEENTRY* pal)
{
    // create palette first time
    if (DDPalette==NULL)
        CreateDDPalette (pal);
    else
        DDPalette->lpVtbl->SetEntries(DDPalette,0,0,256,pal);
    // setting the same palette to the same surface again does not increase
    // the reference count
    ScreenReal->lpVtbl->SetPalette (ScreenReal,DDPalette);
}


//
// Wait for vsync, gross
//
void WaitVbl (void)
{
    DDr2->lpVtbl->WaitForVerticalBlank (DDr2,DDWAITVB_BLOCKBEGIN, NULL);
}

⌨️ 快捷键说明

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