📄 fabdxlib.c
字号:
//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 + -