📄 dibdisplay.c
字号:
&desktop_G_bitmask,
&desktop_B_bitmask)==false)
{
geErrorLog_Add(GE_ERR_SUBSYSTEM_FAILURE,"DIBDisplay_CreateDIB: unable to determine desktop bit format (continuing).");
geErrorLog_Clear();
//ReleaseDC(hWnd, hdc);
//return false;
desktop_R_bitmask = 0x00f800;
desktop_G_bitmask = 0x0007e0;
desktop_B_bitmask = 0x00001f;
}
//
// If DIB and desktop are both in 15/16-BPP mode, set DIB to desktop
// pixel format for maximum throughput
//
// Otherwise, set DIB to 5-6-5 mode if 16BPP DIB requested, or 8-8-8 mode
// if 24BPP DIB requested
//
// Finally, if 8BPP DIB requested, create GDI palette object based on
// current logical palette
//
switch (display_bpp)
{
case 16:
pbmih->biCompression = BI_BITFIELDS;
if ((desktop_bpp == 15) || (desktop_bpp == 16))
{
DI->DIB_R_bitmask = desktop_R_bitmask;
DI->DIB_G_bitmask = desktop_G_bitmask;
DI->DIB_B_bitmask = desktop_B_bitmask;
}
else
{
DI->DIB_R_bitmask = 0x00f800;
DI->DIB_G_bitmask = 0x0007e0;
DI->DIB_B_bitmask = 0x00001f;
}
break;
case 24:
pbmih->biCompression = BI_BITFIELDS;
DI->DIB_R_bitmask = 0xff0000;
DI->DIB_G_bitmask = 0x00ff00;
DI->DIB_B_bitmask = 0x0000ff;
break;
}
*(uint *) (&(DI->pbmi->bmiColors[0])) = DI->DIB_R_bitmask;
*(uint *) (&(DI->pbmi->bmiColors[1])) = DI->DIB_G_bitmask;
*(uint *) (&(DI->pbmi->bmiColors[2])) = DI->DIB_B_bitmask;
//
// Allocate the DIB section ("back buffer")
//
DI->hDIB = CreateDIBSection(hdc, // Device context
DI->pbmi, // BITMAPINFO structure
DIB_RGB_COLORS, // Color data type
(void **) &(DI->lpDIBBuffer), // Address of image map pointer
NULL, // File
0); // Bitmap file offset
ReleaseDC(hWnd, hdc);
if (DI->hDIB == NULL)
{
geErrorLog_Add(GE_ERR_WINDOWS_API_FAILURE,"DIBDisplay_CreateDIB: CreateDIBSection failed");
return false;
}
return true;
}
//------------------------------------------------
bool DIBDisplay_Blit(DIBDisplay *D)
{
HDC hdc;
assert( DIBDisplay_IsValid(D) != false );
hdc = GetDC(D->hWnd);
if (hdc == NULL)
{
geErrorLog_Add(GE_ERR_WINDOWS_API_FAILURE,"DIBDisplay_Blit: Unable to get HDC for blit");
return false;
}
#if 0
if (desktop_bpp == 8)
{
//
// Select palette if desktop running in 8-bit mode
//
// If palette has changed, realize it
//
//probably want to set up a halftone palette, and dither down into the 8 bbp desktop.
SelectPalette( hdc, hPalette, 0);
if (palette_change_request != false)
{
palette_change_request = false;
RealizePalette(hdc);
}
}
#endif
//
// Disable Boolean operations during stretching
//
if (SetStretchBltMode(hdc, COLORONCOLOR)==0)
{
geErrorLog_Add(GE_ERR_WINDOWS_API_FAILURE,"unable to set stretch blit mode");
return false;
}
StretchDIBits(hdc, // Destination DC
0, // Destination X
0, // Destination Y
D->Size_X, // Destination (client area) width
D->Size_Y, // Destination (client area) height
0, // Source X
0, // Source Y
D->Size_X, // Source (back buffer) width
D->Size_Y, // Source (back buffer) height
D->DIBInfo.lpDIBBuffer, // Pointer to source (back buffer)
D->DIBInfo.pbmi, // Bitmap info for back buffer
DIB_RGB_COLORS, // Bitmap contains index values
SRCCOPY); // Do normal copy with stretching
ReleaseDC(D->hWnd, hdc);
return true;
}
//------------------------------------------------
bool DIBDisplay_Wipe ( DIBDisplay *D,
uint color)
{
assert( DIBDisplay_IsValid(D) != false );
if (!D->Locked)
{
geErrorLog_Add(GE_ERR_BAD_PARAMETER,"DIBDisplay_Wipe: Display must be locked to clear");
return false;
}
if (color==0)
memset(D->DIBInfo.lpDIBBuffer, color, D->Size_Y * D->Pitch);
else
{
int i;
int16 *Ptr = (int16 *)D->DIBInfo.lpDIBBuffer;
int16 C = (int16)color;
for (i=(D->Size_X * D->Size_Y); i>0; i--)
{
*(Ptr++) = C;
}
}
return true;
}
bool DIBDisplay_UpdateWindow( DIBDisplay *D )
{
RECT window_rect;
BOOL result;
HWND hWindow;
assert( D->Locked == false );
assert( D->hWnd != NULL );
hWindow = D->hWnd;
result = GetClientRect(hWindow, &window_rect);
if( !result )
{
geErrorLog_Add(GE_ERR_WINDOWS_API_FAILURE,"DIBDisplay_UpdateWindow: failed to get client rect");
return false;
}
assert ( window_rect.left == 0 );
assert ( window_rect.top == 0 );
D->Size_X = ((window_rect.right - window_rect.left)+3)&~3;
D->Size_Y = (window_rect.bottom - window_rect.top);
if ( D->Size_X <=0 )
{
geErrorLog_AddString(GE_ERR_BAD_PARAMETER,"DIBDisplay_UpdateWindow: bad window client width=",geErrorLog_IntToString(D->Size_X));
return false;
}
if ( D->Size_Y <=0 )
{
geErrorLog_AddString(GE_ERR_BAD_PARAMETER,"DIBDisplay_UpdateWindow: bad window client height=",geErrorLog_IntToString(D->Size_Y));
return false;
}
D->hWnd = hWindow;
DIBDisplay_DestroyDIB(&(D->DIBInfo));
D->DIBInfo.pbmi = NULL;
D->DIBInfo.hDIB = NULL;
D->DIBInfo.lpDIBBuffer = NULL;
D->Locked = false;
D->Pitch = (D->BitsPerPixel / 8 ) * D->Size_X;
if (DIBDisplay_CreateDIB(D->Size_X, D->Size_Y, D->BitsPerPixel,
hWindow,
&(D->DIBInfo)) ==false)
{
geErrorLog_Add(GE_ERR_SUBSYSTEM_FAILURE,"DIBDisplay_UpdateWindow: failed to create Dib section");
DIBDisplay_DestroyDIB(&(D->DIBInfo));
return false;
}
return true;
}
//------------------------------------------------
DIBDisplay *DIBDisplay_Create ( HWND hWindow,
int Width,
int Height,
int display_bpp,
uint Flags )
{
DIBDisplay *D;
Flags; Width; Height; // avoid unused formal parameter warnings
assert( display_bpp > 0);
D= malloc(sizeof(*D));
if (D==NULL)
{
geErrorLog_Add(GE_ERR_MEMORY_RESOURCE,"DIBDisplay_Create: failed to allocate DIBDisplay object");
return NULL;
}
D->Locked = false;
D->BitsPerPixel = display_bpp;
D->DIBInfo.pbmi = NULL;
D->DIBInfo.hDIB = NULL;
D->DIBInfo.lpDIBBuffer = NULL;
D->hWnd = hWindow;
if (DIBDisplay_UpdateWindow(D)==false)
{
geErrorLog_Add(GE_ERR_SUBSYSTEM_FAILURE,"DIBDisplay_Create: failed to update window");
free(D);
return NULL;
}
return D;
}
//------------------------------------------------
void DIBDisplay_Destroy(DIBDisplay **pD)
{
DIBDisplay *D;
assert( *pD != NULL );
assert( pD != NULL );
D = *pD;
assert( DIBDisplay_IsValid(D) != false );
DIBDisplay_DestroyDIB(&(D->DIBInfo));
free( D );
*pD = NULL;
}
//------------------------------------------------
bool DIBDisplay_Lock (DIBDisplay *D,
ubyte **ptr,
int *pitch)
{
assert( DIBDisplay_IsValid(D) != false );
assert( ptr != NULL );
assert( pitch != NULL );
assert( D->Locked == false );
*ptr = D->DIBInfo.lpDIBBuffer;
*pitch = D->Pitch;
D->Locked = true;
return true;
}
bool DIBDisplay_Unlock (DIBDisplay *D)
{
assert( DIBDisplay_IsValid(D) != false );
assert( D->Locked == true );
D->Locked = false;
return true;
}
//------------------------------------------------
bool DIBDisplay_GetPixelFormat( const DIBDisplay *D,
//int *pixel_pitch,
int *bytes_per_pixel,
int *R_shift,
uint *R_mask,
int *R_width,
int *G_shift,
uint *G_mask,
int *G_width,
int *B_shift,
uint *B_mask,
int *B_width)
{
int red_shift=0;
uint red_mask;
int red_width=0;
int grn_shift=0;
uint grn_mask;
int grn_width=0;
int blu_shift=0;
uint blu_mask;
int blu_width=0;
int i;
assert( DIBDisplay_IsValid(D) != false );
//assert( pixel_pitch != NULL );
assert( bytes_per_pixel != NULL );
assert( R_shift != NULL );
assert( R_mask != NULL );
assert( R_width != NULL );
assert( G_shift != NULL );
assert( G_mask != NULL );
assert( G_width != NULL );
assert( B_shift != NULL );
assert( B_mask != NULL );
assert( B_width != NULL );
//*pixel_pitch = (D->BitsPerPixel / 8);
*bytes_per_pixel = (D->BitsPerPixel / 8);
red_mask = D->DIBInfo.DIB_R_bitmask;
grn_mask = D->DIBInfo.DIB_G_bitmask;
blu_mask = D->DIBInfo.DIB_B_bitmask;
//
// Derive shift, width values from masks
//
for (i=31; i >= 0; i--)
{
if (red_mask & (1 << i))
{
red_shift = i;
}
if (grn_mask & (1 << i))
{
grn_shift = i;
}
if (blu_mask & (1 << i))
{
blu_shift = i;
}
}
for (i=0; i <= 31; i++)
{
if (red_mask & (1 << i))
{
red_width = i - red_shift + 1;
}
if (grn_mask & (1 << i))
{
grn_width = i - grn_shift + 1;
}
if (blu_mask & (1 << i))
{
blu_width = i - blu_shift + 1;
}
}
//
// Pass all requested values back to the caller
//
*R_shift = red_shift;
*G_shift = grn_shift;
*B_shift = blu_shift;
*R_mask = red_mask;
*G_mask = grn_mask;
*B_mask = blu_mask;
*R_width = red_width;
*G_width = grn_width;
*B_width = blu_width;
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -