win_vid.c
来自「经典的老游戏digger的源代码.提起digger相信很多人会回忆起曾经为了它挑」· C语言 代码 · 共 1,254 行 · 第 1/3 页
C
1,254 行
{
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
else
{
// if (g_pDDSPrimary && !suspend_game)
// return IDirectDrawSurface_Blt(g_pDDSPrimary, &g_rcScreen, g_pDDSBack, &rc_draw_area, DDBLT_WAIT, NULL);
if (cur_dialog_box)
GetWindowRect(cur_dialog_box,&nodraw);
IDirectDrawSurface_Lock(g_pDDSPrimary,NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
for (x=0;x<640;x++)
for (y=0;y<400;y++)
{
if (cur_dialog_box)
{
pt.x = x;
pt.y = y;
if (PtInRect(&nodraw,pt))
continue;
}
((char*) ddsd.lpSurface)[y*ddsd.lPitch+x]=back_bitmap_bits[y*640+x];
}
IDirectDrawSurface_Unlock(g_pDDSPrimary, ddsd.lpSurface);
}
return DD_OK;
}
/* This is ONLY called when the window receives a WM_PAINT message. */
/* Repaint all or a portion of the window. */
/* (used in both Windowed and Fullscreen mode) */
void blit_to_window_dc(HWND wnd)
{
HDC hDC;
PAINTSTRUCT paintStruct;
hDC = BeginPaint(hWnd, &paintStruct);
if (palettized_desktop)
{
SelectPalette (hDC, desktop_palette, TRUE);
RealizePalette (hDC);
}
if (g_bWindowed)
{
BitBlt(hDC,0,0,640,400,back_dc, 0,0,SRCCOPY);
}
else
BitBlt(hDC,g_rcScreen.left,g_rcScreen.top,640,400,back_dc, 0,0,SRCCOPY);
EndPaint(hWnd, &paintStruct);
}
HRESULT restore_surface()
{
HRESULT hRet;
hRet=IDirectDrawSurface_Restore(g_pDDSPrimary);
if (hRet != DD_OK)
{
fatal_error(hRet, "DirectDraw: restore surfaces (primary) failed");
}
return TRUE;
}
/* Blits the given rectangle to the Window (or marks the given rectangle */
/* as dirty if Async option is on). */
/* In DirectX/Fullscreen mode, there must NOT be a Clipper attached to */
/* the surface (otherwise BltFast will not work). */
void blit_rect_to_window(int x, int y, int w, int h)
{
RECT rect;
DDSURFACEDESC ddsd;
int xi,yi;
ddsd.dwSize=sizeof(ddsd);
// if (!g_bWindowed && !g_bActive)
// return;
if (g_bWindowed || preferred_video_mode.bpp > 8)
{
rect.left=x;
rect.right=x+w;
rect.top=y;
rect.bottom=y+h;
InvalidateRect(hWnd, &rect, FALSE);
if (!use_async_screen_updates)
UpdateWindow(hWnd);
}
else
{
if (g_pDDSPrimary)
{
rect.left=x;
rect.right=x+w;
rect.top=y;
rect.bottom=y+h;
// IDirectDrawSurface_BltFast(g_pDDSPrimary, g_rcScreen.left+x, g_rcScreen.top+y, g_pDDSBack, &rect, DDBLTFAST_NOCOLORKEY /* | DDBLTFAST_WAIT */);
IDirectDrawSurface_Lock(g_pDDSPrimary,&rect, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
for (xi=0;xi<w;xi++)
for (yi=0;yi<h;yi++)
((char*) ddsd.lpSurface)[yi*ddsd.lPitch+xi]=back_bitmap_bits[(yi+y)*640+xi+x];
IDirectDrawSurface_Unlock(g_pDDSPrimary, ddsd.lpSurface);
}
}
}
/* This function creates a back buffer for drawing on. */
/* - on Win32 this is a DIBSection */
bool create_back_buffer(HDC window_dc)
{
HANDLE hloc;
BITMAPINFO *pbmi;
back_dc = CreateCompatibleDC(window_dc);
back_bitmap=0;
hloc = LocalAlloc(LMEM_ZEROINIT | LMEM_MOVEABLE, sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * 16));
pbmi = (BITMAPINFO*) LocalLock(hloc);
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = 640;
pbmi->bmiHeader.biHeight = -400;
pbmi->bmiHeader.biPlanes = 1;
pbmi->bmiHeader.biBitCount = 8;
pbmi->bmiHeader.biClrUsed = 16;
pbmi->bmiHeader.biClrImportant = 16;
pbmi->bmiHeader.biCompression = BI_RGB;
memset(pbmi->bmiColors,0,sizeof(RGBQUAD)*16);
back_bitmap = CreateDIBSection(window_dc, (BITMAPINFO*) pbmi, DIB_RGB_COLORS, (VOID **) &back_bitmap_bits, (HANDLE) NULL, 0);
LocalFree(hloc);
if (!back_bitmap)
return FALSE;
old_bitmap = SelectObject(back_dc, back_bitmap);
return TRUE;
}
void destroy_back_buffer()
{
release_directdraw_objects();
SelectObject(back_dc, old_bitmap);
DeleteObject(back_bitmap);
DeleteDC(back_dc);
DeleteObject(desktop_palette);
}
HRESULT release_directdraw_objects()
{
if (use_direct_draw)
{
if (g_pDD != NULL)
{
IDirectDraw_RestoreDisplayMode(g_pDD);
IDirectDraw_SetCooperativeLevel(g_pDD, hWnd, DDSCL_NORMAL);
// if (g_pDDSBack != NULL)
// {
// IDirectDraw_Release(g_pDDSBack);
// g_pDDSBack = NULL;
// }
if (g_pDDSPrimary != NULL)
{
IDirectDraw_Release(g_pDDSPrimary);
g_pDDSPrimary = NULL;
}
}
}
return DD_OK;
}
HRESULT fatal_error(HRESULT hRet, LPCTSTR szError)
{
windows_finish();
MessageBox(hWnd, szError, "Digger", MB_OK);
DestroyWindow(hWnd);
exit(1);
return hRet;
}
HRESULT init_surfaces()
{
HRESULT hRet;
DDSURFACEDESC ddsd;
DDBLTFX ddbltfx;
int i, palnum;
HDC hDC;
LOGPALETTE* logpalette;
RGBQUAD *wp[] = { vga16_pal1_rgbq,vga16_pal1i_rgbq,vga16_pal2_rgbq,vga16_pal2i_rgbq };
if (!use_direct_draw)
g_bWindowed=TRUE;
if (g_bWindowed)
{
/* Are we running in 256 colors (or less)? */
hDC=GetDC(hWnd);
palettized_desktop=GetDeviceCaps(hDC, RASTERCAPS)&RC_PALETTE;
if (palettized_desktop)
{
logpalette=(LOGPALETTE*) malloc(sizeof(LOGPALETTE) + sizeof(PALETTEENTRY)*64);
if (!logpalette)
fatal_error(0,"init_surfaces: could not allocate memory for 'logpalette'");
logpalette->palNumEntries=64;
logpalette->palVersion=0x300;
for (palnum=0;palnum<4;palnum++)
for (i=0;i<16;i++)
{
logpalette->palPalEntry[palnum*16+i].peRed=wp[palnum][i].rgbRed;
logpalette->palPalEntry[palnum*16+i].peBlue=wp[palnum][i].rgbBlue;
logpalette->palPalEntry[palnum*16+i].peGreen=wp[palnum][i].rgbGreen;
logpalette->palPalEntry[palnum*16+i].peFlags=(BYTE) NULL; //PC_NOCOLLAPSE;
}
desktop_palette=CreatePalette(logpalette);
free (logpalette);
SelectPalette(hDC,desktop_palette,TRUE);
i=RealizePalette(hDC);
}
ReleaseDC(hWnd, hDC);
if (use_direct_draw)
{
IDirectDraw_RestoreDisplayMode(g_pDD);
hRet = IDirectDraw_SetCooperativeLevel(g_pDD, hWnd, DDSCL_NORMAL);
if (hRet != DD_OK)
return fatal_error(hRet, "DirectDraw: SetCooperativeLevel FAILED");
}
GetClientRect(hWnd, &g_rcViewport);
GetClientRect(hWnd, &g_rcScreen);
ClientToScreen(hWnd, (POINT*)&g_rcScreen.left);
ClientToScreen(hWnd, (POINT*)&g_rcScreen.right);
}
else
{
SetWindowLong(hWnd, GWL_STYLE, DIGGER_WS_FULLSCREEN);
if (preferred_video_mode.height<=400)
SetMenu(hWnd,NULL);
hRet = IDirectDraw_SetCooperativeLevel(g_pDD, hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
if (hRet != DD_OK)
return fatal_error(hRet, "DirectDraw: SetCooperativeLevel (fullscreen) FAILED");
SetRect(&g_rcViewport, 0, 0, 640, 400 );
memcpy(&g_rcScreen, &g_rcViewport, sizeof(RECT) );
if (!use_640x480_fullscreen)
hRet = IDirectDraw_SetDisplayMode(g_pDD, preferred_video_mode.width, preferred_video_mode.height, preferred_video_mode.bpp);
if (hRet != DD_OK || use_640x480_fullscreen)
{
hRet = IDirectDraw_SetDisplayMode(g_pDD, 640, 480, 8);
if (hRet != DD_OK)
{
return fatal_error(hRet, "DirectDraw: SetDisplayMode FAILED");
}
SetRect(&g_rcViewport, 0, 40, 640, 440 );
memcpy(&g_rcScreen, &g_rcViewport, sizeof(RECT) );
}
/* Create the primary surface */
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
hRet = IDirectDraw_CreateSurface(g_pDD, &ddsd, &g_pDDSPrimary, NULL);
if (hRet != DD_OK)
return fatal_error(hRet, "DirectDraw: CreateSurface (primary, fullscreen) FAILED");
vgainten(cur_intensity);
/* clear the screen */
ZeroMemory(&ddbltfx,sizeof(DDBLTFX));
ddbltfx.dwFillColor=0;
ddbltfx.dwSize=sizeof(DDBLTFX);
IDirectDrawSurface_Blt(g_pDDSPrimary, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT , &ddbltfx );
}
rc_640x400.left=0;
rc_640x400.top=0;
rc_640x400.right=640;
rc_640x400.bottom=400;
rc_draw_area.left=0;
rc_draw_area.top=0;
rc_draw_area.right=640;
rc_draw_area.bottom=400;
return DD_OK;
}
void destroy_palettes()
{
fullscreen_palette[0]=NULL;
}
void init_palettes()
{
HRESULT hRet;
PALETTEENTRY palentry[256];
int i, palnum;
HDC hDC;
LOGPALETTE* logpalette;
if (!use_direct_draw)
g_bWindowed=TRUE;
if (g_bWindowed)
{
/* Are we running in 256 colors (or less)? */
hDC=GetDC(hWnd);
palettized_desktop=GetDeviceCaps(hDC, RASTERCAPS)&RC_PALETTE;
if (palettized_desktop)
{
logpalette=(LOGPALETTE*) malloc(sizeof(LOGPALETTE) + sizeof(PALETTEENTRY)*64);
if (!logpalette)
fatal_error(0,"init_surfaces: could not allocate memory for 'logpalette'");
logpalette->palNumEntries=64;
logpalette->palVersion=0x300;
for (palnum=0;palnum<4;palnum++)
for (i=0;i<16;i++)
{
logpalette->palPalEntry[palnum*16+i].peRed=windowed_palette[palnum][i].rgbRed;
logpalette->palPalEntry[palnum*16+i].peBlue=windowed_palette[palnum][i].rgbBlue;
logpalette->palPalEntry[palnum*16+i].peGreen=windowed_palette[palnum][i].rgbGreen;
logpalette->palPalEntry[palnum*16+i].peFlags=(BYTE) NULL; //PC_NOCOLLAPSE;
}
desktop_palette=CreatePalette(logpalette);
free (logpalette);
SelectPalette(hDC,desktop_palette,TRUE);
i=RealizePalette(hDC);
}
ReleaseDC(hWnd, hDC);
/*
if (use_direct_draw)
{
hRet = IDirectDraw_SetCooperativeLevel(g_pDD, hWnd, DDSCL_NORMAL);
if (hRet != DD_OK)
fatal_error(hRet, "DirectDraw: SetCooperativeLevel FAILED");
}
*/
GetClientRect(hWnd, &g_rcViewport);
GetClientRect(hWnd, &g_rcScreen);
ClientToScreen(hWnd, (POINT*)&g_rcScreen.left);
ClientToScreen(hWnd, (POINT*)&g_rcScreen.right);
}
else
{
if (fullscreen_palette[0]==NULL)
{
for (palnum=0;palnum<4;palnum++)
{
for (i=0;i<256;i++)
{
if (i<16)
{
palentry[i].peRed=windowed_palette[palnum][i].rgbRed;
palentry[i].peBlue=windowed_palette[palnum][i].rgbBlue;
palentry[i].peGreen=windowed_palette[palnum][i].rgbGreen;
palentry[i].peFlags=(BYTE) NULL;
}
else
{
palentry[i].peRed=0;
palentry[i].peBlue=0;
palentry[i].peGreen=0;
palentry[i].peFlags=(BYTE) NULL;
}
}
IDirectDraw_CreatePalette(g_pDD, DDPCAPS_8BIT, palentry, &fullscreen_palette[palnum], NULL);
}
}
vgainten(cur_intensity);
}
}
/* toggle between windowed and fullscreen mode */
HRESULT ChangeCoopLevel()
{
HRESULT hRet;
if (FAILED(hRet = release_directdraw_objects()))
return fatal_error(hRet, "DirectDraw: release_directdraw_objects FAILED");
if (g_bWindowed)
{
SetWindowLong(hWnd, GWL_STYLE, DIGGER_WS_WINDOWED);
SetWindowPos(hWnd, HWND_NOTOPMOST, g_rcWindow.left, g_rcWindow.top,
(g_rcWindow.right - g_rcWindow.left),
(g_rcWindow.bottom - g_rcWindow.top), SWP_SHOWWINDOW );
InvalidateRect(NULL, NULL, TRUE); // all windows should be repainted
}
hRet = init_surfaces();
init_palettes();
return hRet;
}
void init_directdraw()
{
HRESULT hRet;
DDSURFACEDESC ddsd;
GetWindowRect(hWnd, &g_rcWindow); // what is this doing here???
if (!lpDirectDrawCreate)
{
use_direct_draw=0;
return;
}
hRet = DirectDrawCreate( NULL, &g_pDD, NULL);
if (hRet==DD_OK)
{
use_direct_draw=1;
}
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?