📄 misc.c
字号:
goto ret_ok;
} else if (mode == D3DAPP_USEWINDOW) {
/*
* Check to see if this driver can use the Windows display depth
*/
if (D3DAppIBPPToDDBD(d3dappi.WindowsDisplay.bpp) &
d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth) {
goto ret_ok;
} else {
/*
* Since it cannot, call this function again to choose any
* display mode which is compatible
*/
mode = D3DAPP_YOUDECIDE;
ATTEMPT(D3DAppIVerifyDriverAndMode(&driver, &mode));
if (driver == D3DAPP_BOGUS)
goto exit_with_error;
goto ret_ok;
}
} else {
/*
* Check to see if this driver can use the specified fullscreen mode
*/
if (D3DAppIBPPToDDBD(d3dappi.Mode[mode].bpp) &
d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth) {
goto ret_ok;
} else {
/*
* Since it cannot, call this function again to choose any
* display mode which is compatible
*/
mode = D3DAPP_YOUDECIDE;
ATTEMPT(D3DAppIVerifyDriverAndMode(&driver, &mode));
if (driver == D3DAPP_BOGUS)
goto exit_with_error;
goto ret_ok;
}
}
ret_ok:
*lpdriver = driver; *lpmode = mode;
return TRUE;
exit_with_error:
return FALSE;
}
/***************************************************************************/
/* Dirty Rectangle Functions */
/***************************************************************************/
/*
* D3DAppIValidateDirtyRects
* Set the dirty rectangles for the front and back buffers to the entire
* client size.
*/
void
D3DAppIValidateDirtyRects(void)
{
NumDirtyClientRects = 1; NumDirtyBackRects = 1; NumDirtyZRects = 1;
SetRect((LPRECT)&DirtyClient[0], 0, 0, d3dappi.szClient.cx,
d3dappi.szClient.cy);
SetRect((LPRECT)&DirtyBack[0], 0, 0, d3dappi.szClient.cx,
d3dappi.szClient.cy);
SetRect((LPRECT)&DirtyZ[0], 0, 0, d3dappi.szClient.cx,
d3dappi.szClient.cy);
}
/*
* D3DAppICopyRectList
* Copy a list of rectangles to another
*/
void
D3DAppICopyRectList(int* dstnum, LPD3DRECT dst, int srcnum, LPD3DRECT src)
{
int i;
for (i = 0; i < srcnum; i++)
dst[i] = src[i];
*dstnum = srcnum;
}
/*
* MERGE macro
* Set first rectangle to be the smallest rectangle containing both rects
*/
#undef MERGE
#define MERGE(rc1, rc2) \
do { \
if (rc2.x1 < rc1.x1) rc1.x1 = rc2.x1; \
if (rc2.y1 < rc1.y1) rc1.y1 = rc2.y1; \
if (rc2.x2 > rc1.x2) rc1.x2 = rc2.x2; \
if (rc2.y2 > rc1.y2) rc1.y2 = rc2.y2; \
} while(0)
/*
* D3DAppIMergeRectLists
* Merge two lists of rectangles to create another list of rectangles. The
* merged list of rectangles covers all the area of the original two with NO
* OVERLAPPING amongst it's rectangles.
*/
void
D3DAppIMergeRectLists(int* dstnum, LPD3DRECT dst, int src1num, LPD3DRECT src1,
int src2num, LPD3DRECT src2)
{
LPD3DRECT rc;
int* isvalid;
int num, i, j, intersect;
rc = (LPD3DRECT)malloc(sizeof(D3DRECT) * D3DAPP_MAXCLEARRECTS * 2);
memset(rc, 0, sizeof(D3DRECT) * D3DAPP_MAXCLEARRECTS * 2);
isvalid = (int*)malloc(sizeof(int) * D3DAPP_MAXCLEARRECTS * 2);
memset(isvalid, 0, sizeof(int) * D3DAPP_MAXCLEARRECTS * 2);
for (i = 0; i < src1num; i++) {
memcpy(&rc[i], &src1[i], sizeof(D3DRECT));
if ((rc[i].x1 == 0 && rc[i].x2 == 0) ||
(rc[i].y1 == 0 && rc[i].y2 == 0))
isvalid[i] = 0;
else if (rc[i].x1 <= rc[i].x2 && rc[i].y1 <= rc[i].y2)
isvalid[i] = 1;
else
isvalid[i] = 0;
}
for (i = 0; i < src2num; i++) {
memcpy(&rc[i + src1num], &src2[i], sizeof(D3DRECT));
if (rc[i + src1num].x1 <= rc[i + src1num].x2 &&
rc[i + src1num].y1 <= rc[i + src1num].y2)
isvalid[i + src1num] = 1;
else
isvalid[i + src1num] = 0;
}
num = src1num + src2num;
for (i = 0; i < num - 1; i++) {
if (!isvalid[i]) continue;
j = i + 1;
do {
intersect = 0;
for (; j < num; j++) {
if (j != i && isvalid[j]) {
if (rc[i].x1 < rc[j].x1) {
if (rc[i].x2 < rc[j].x1)
continue;
} else {
if (rc[j].x2 < rc[i].x1)
continue;
}
if (rc[i].y1 < rc[j].y1) {
if (rc[i].y2 < rc[j].y1)
continue;
} else {
if (rc[j].y2 < rc[i].y1)
continue;
}
MERGE(rc[i], rc[j]);
isvalid[j] = 0;
j = 0; intersect = 1;
break;
}
}
} while(intersect);
}
for (i = 0, j = 0; i < num; i++)
if (isvalid[i]) ++j;
if (j > D3DAPP_MAXCLEARRECTS) {
for (i = 0; i < num; i++)
if (isvalid[i]) break;
if (i < num) {
*dstnum = 1;
dst[0] = rc[i];
for (; i < num; i++) {
if (isvalid[i]) {
MERGE(dst[0], rc[i]);
}
}
} else {
*dstnum = 0;
}
} else {
for (i = 0, j = 0; i < num; i++) {
if (isvalid[i]) {
memcpy(&dst[j], &rc[i], sizeof(D3DRECT));
++j;
}
}
*dstnum = j;
}
free(rc);
free(isvalid);
}
/***************************************************************************/
/* Getting and Setting Window Attribs */
/***************************************************************************/
/*
* D3DAppISetClientSize
* Set the client size of the given window. A WM_SIZE message is generated,
* but ignored.
*/
void
D3DAppISetClientSize(HWND hwnd, int w, int h, BOOL bReturnFromFullscreen)
{
RECT rc;
bIgnoreWM_SIZE = TRUE;
if (bReturnFromFullscreen) {
SetRect(&rc, 0, 0, w, h);
AdjustWindowRectEx(&rc, GetWindowLong(hwnd, GWL_STYLE),
GetMenu(hwnd) != NULL,
GetWindowLong(hwnd, GWL_EXSTYLE));
SetWindowPos(hwnd, NULL, 0, 0, rc.right-rc.left,
rc.bottom-rc.top,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
} else {
/*
* This is the only way to set the client size correctly if the menu
* is stacked, so do it unless we are returning from a fullscreen
* mode.
*/
SendMessage(hwnd, WM_SIZE, SIZE_RESTORED, w + h << 16);
GetWindowRect(hwnd, &rc);
SetWindowPos(hwnd, NULL, 0, 0, rc.right-rc.left,
rc.bottom-rc.top,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
}
bIgnoreWM_SIZE = FALSE;
d3dappi.pClientOnPrimary.x = d3dappi.pClientOnPrimary.y = 0;
ClientToScreen(hwnd, &d3dappi.pClientOnPrimary);
d3dappi.szClient.cx = w; d3dappi.szClient.cy = h;
}
/*
* D3DAppIGetClientWin
* Gets the client window size and sets it in the D3DAppInfo structure
*/
void
D3DAppIGetClientWin(HWND hwnd)
{
RECT rc;
if (!d3dappi.bFullscreen) {
d3dappi.pClientOnPrimary.x = d3dappi.pClientOnPrimary.y = 0;
ClientToScreen(hwnd, &d3dappi.pClientOnPrimary);
GetClientRect(hwnd, &rc);
d3dappi.szClient.cx = rc.right;
d3dappi.szClient.cy = rc.bottom;
} else {
/*
* In the fullscreen case, we must be careful because if the window
* frame has been drawn, the client size has shrunk and this can
* cause problems, so it's best to report the entire screen.
*/
d3dappi.pClientOnPrimary.x = d3dappi.pClientOnPrimary.y = 0;
d3dappi.szClient.cx = d3dappi.ThisMode.w;
d3dappi.szClient.cy = d3dappi.ThisMode.h;
}
}
/***************************************************************************/
/* Error reporting */
/***************************************************************************/
/*
* D3DAppISetErrorString
* Set the global variable which records the last error string.
*/
void
D3DAppISetErrorString( LPSTR fmt, ... )
{
char buff[256];
buff[0] = 0;
wvsprintf(&buff[0], fmt, (char *)(&fmt+1));
lstrcat(buff, "\r\n");
lstrcpy(LastErrorString, buff);
}
/* dpf
* Debug printf. Very useful for fullscreen exclusive mode or when surfaces
* are in video memory.
*/
void __cdecl
dpf( LPSTR fmt, ... )
{
char buff[256];
lstrcpy(buff, "D3DApp: ");
wvsprintf(&buff[lstrlen(buff)], fmt, (char *)(&fmt+1));
lstrcat(buff, "\r\n");
OutputDebugString(buff);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -