📄 vid_win.c
字号:
}
else
{
sprintf(pinfo, "%s windowed", pv->modedesc);
}
return pinfo;
}
// KJB: Added this to return the mode driver name in description for console
char *VID_GetExtModeDescription (int mode)
{
static char pinfo[40];
vmode_t *pv;
if ((mode < 0) || (mode >= nummodes))
return NULL;
VID_CheckModedescFixup (mode);
pv = VID_GetModePtr (mode);
if (modelist[mode].type == MS_FULLSCREEN)
{
sprintf(pinfo,"%s fullscreen %s",pv->modedesc,
MGL_modeDriverName(pv->modenum));
}
else if (modelist[mode].type == MS_FULLDIB)
{
sprintf(pinfo,"%s fullscreen DIB", pv->modedesc);
}
else
{
sprintf(pinfo, "%s windowed", pv->modedesc);
}
return pinfo;
}
void DestroyDIBWindow (void)
{
if (modestate == MS_WINDOWED)
{
// destroy the associated MGL DC's; the window gets reused
if (windc)
MGL_destroyDC(windc);
if (dibdc)
MGL_destroyDC(dibdc);
windc = dibdc = NULL;
}
}
void DestroyFullscreenWindow (void)
{
if (modestate == MS_FULLSCREEN)
{
// destroy the existing fullscreen mode and DC's
if (mgldc)
MGL_destroyDC (mgldc);
if (memdc)
MGL_destroyDC (memdc);
mgldc = memdc = NULL;
}
}
void DestroyFullDIBWindow (void)
{
if (modestate == MS_FULLDIB)
{
ChangeDisplaySettings (NULL, CDS_FULLSCREEN);
// Destroy the fullscreen DIB window and associated MGL DC's
if (windc)
MGL_destroyDC(windc);
if (dibdc)
MGL_destroyDC(dibdc);
windc = dibdc = NULL;
}
}
qboolean VID_SetWindowedMode (int modenum)
{
HDC hdc;
pixel_format_t pf;
qboolean stretched;
// int lastmodestate; // 2001-12-10 Reduced compiler warnings by Jeff Ford
LONG wlong;
if (!windowed_mode_set)
{
if (COM_CheckParm ("-resetwinpos"))
{
Cvar_Set (vid_window_x, "0");
Cvar_Set (vid_window_y, "0");
}
// windowed_mode_set; // 2001-12-10 Reduced compiler warnings by Jeff Ford
}
VID_CheckModedescFixup (modenum);
DDActive = 0;
// lastmodestate = modestate; // 2001-12-10 Reduced compiler warnings by Jeff Ford
DestroyFullscreenWindow ();
DestroyFullDIBWindow ();
if (windc)
MGL_destroyDC(windc);
if (dibdc)
MGL_destroyDC(dibdc);
windc = dibdc = NULL;
// KJB: Signal to the MGL that we are going back to windowed mode
if (!MGL_changeDisplayMode(grWINDOWED))
initFatalError();
WindowRect.top = WindowRect.left = 0;
WindowRect.right = modelist[modenum].width;
WindowRect.bottom = modelist[modenum].height;
stretched = modelist[modenum].stretched;
DIBWidth = modelist[modenum].width;
DIBHeight = modelist[modenum].height;
if (stretched)
{
DIBWidth >>= 1;
DIBHeight >>= 1;
}
WindowStyle = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU |
WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CLIPSIBLINGS |
WS_CLIPCHILDREN;
ExWindowStyle = 0;
AdjustWindowRectEx(&WindowRect, WindowStyle, FALSE, 0);
// the first time we're called to set the mode, create the window we'll use
// for the rest of the session
if (!vid_mode_set)
{
mainwindow = CreateWindowEx (
ExWindowStyle,
"WinQuake",
"WinQuake",
WindowStyle,
0, 0,
WindowRect.right - WindowRect.left,
WindowRect.bottom - WindowRect.top,
NULL,
NULL,
global_hInstance,
NULL);
if (!mainwindow)
Sys_Error ("Couldn't create DIB window");
// tell MGL to use this window for fullscreen modes
MGL_registerFullScreenWindow (mainwindow);
vid_mode_set = true;
}
else
{
SetWindowLong(mainwindow, GWL_STYLE, WindowStyle | WS_VISIBLE);
SetWindowLong(mainwindow, GWL_EXSTYLE, ExWindowStyle);
}
if (!SetWindowPos (mainwindow,
NULL,
0, 0,
WindowRect.right - WindowRect.left,
WindowRect.bottom - WindowRect.top,
SWP_NOCOPYBITS | SWP_NOZORDER |
SWP_HIDEWINDOW))
{
Sys_Error ("Couldn't resize DIB window");
}
if (hide_window)
return true;
// position and show the DIB window
VID_CheckWindowXY ();
SetWindowPos (mainwindow, NULL, (int)vid_window_x->value,
(int)vid_window_y->value, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME);
if (force_minimized)
ShowWindow (mainwindow, SW_MINIMIZE);
else
ShowWindow (mainwindow, SW_SHOWDEFAULT);
UpdateWindow (mainwindow);
modestate = MS_WINDOWED;
vid_fulldib_on_focus_mode = 0;
// because we have set the background brush for the window to NULL
// (to avoid flickering when re-sizing the window on the desktop),
// we clear the window to black when created, otherwise it will be
// empty while Quake starts up.
hdc = GetDC(mainwindow);
PatBlt(hdc,0,0,WindowRect.right,WindowRect.bottom,BLACKNESS);
ReleaseDC(mainwindow, hdc);
/* Create the MGL window DC and the MGL memory DC */
if ((windc = MGL_createWindowedDC(mainwindow)) == NULL)
MGL_fatalError("Unable to create Windowed DC!");
if ((dibdc = MGL_createMemoryDC(DIBWidth,DIBHeight,8,&pf)) == NULL)
MGL_fatalError("Unable to create Memory DC!");
MGL_makeCurrentDC(dibdc);
vid.buffer = vid.conbuffer = vid.direct = dibdc->surface;
vid.rowbytes = vid.conrowbytes = dibdc->mi.bytesPerLine;
vid.numpages = 1;
vid.maxwarpwidth = WARP_WIDTH;
vid.maxwarpheight = WARP_HEIGHT;
vid.height = vid.conheight = DIBHeight;
vid.width = vid.conwidth = DIBWidth;
vid.aspect = ((float)vid.height / (float)vid.width) *
(320.0 / 240.0);
vid_stretched = stretched;
SendMessage (mainwindow, WM_SETICON, (WPARAM)TRUE, (LPARAM)hIcon);
SendMessage (mainwindow, WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon);
return true;
}
qboolean VID_SetFullscreenMode (int modenum)
{
DDActive = 1;
DestroyDIBWindow ();
DestroyFullDIBWindow ();
mode = modelist[modenum].modenum;
// Destroy old DC's, resetting back to fullscreen mode
if (mgldc)
MGL_destroyDC (mgldc);
if (memdc)
MGL_destroyDC (memdc);
mgldc = memdc = NULL;
if ((mgldc = createDisplayDC (modelist[modenum].stretched ||
(int)vid_nopageflip->value)) == NULL)
{
return false;
}
modestate = MS_FULLSCREEN;
vid_fulldib_on_focus_mode = 0;
vid.buffer = vid.conbuffer = vid.direct = NULL;
vid.maxwarpwidth = WARP_WIDTH;
vid.maxwarpheight = WARP_HEIGHT;
DIBHeight = vid.height = vid.conheight = modelist[modenum].height;
DIBWidth = vid.width = vid.conwidth = modelist[modenum].width;
vid.aspect = ((float)vid.height / (float)vid.width) *
(320.0 / 240.0);
vid_stretched = modelist[modenum].stretched;
// needed because we're not getting WM_MOVE messages fullscreen on NT
window_x = 0;
window_y = 0;
// set the large icon, so the Quake icon will show up in the taskbar
SendMessage (mainwindow, WM_SETICON, (WPARAM)1, (LPARAM)hIcon);
SendMessage (mainwindow, WM_SETICON, (WPARAM)0, (LPARAM)hIcon);
// shouldn't be needed, but Kendall needs to let us get the activation
// message for this not to be needed on NT
AppActivate (true, false);
return true;
}
qboolean VID_SetFullDIBMode (int modenum)
{
HDC hdc;
pixel_format_t pf;
// int lastmodestate; // 2001-12-10 Reduced compiler warnings by Jeff Ford
DDActive = 0;
DestroyFullscreenWindow ();
DestroyDIBWindow ();
if (windc)
MGL_destroyDC(windc);
if (dibdc)
MGL_destroyDC(dibdc);
windc = dibdc = NULL;
// KJB: Signal to the MGL that we are going back to windowed mode
if (!MGL_changeDisplayMode(grWINDOWED))
initFatalError();
gdevmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
gdevmode.dmBitsPerPel = modelist[modenum].bpp;
gdevmode.dmPelsWidth = modelist[modenum].width << modelist[modenum].stretched <<
modelist[modenum].halfscreen;
gdevmode.dmPelsHeight = modelist[modenum].height << modelist[modenum].stretched;
gdevmode.dmSize = sizeof (gdevmode);
if (ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
Sys_Error ("Couldn't set fullscreen DIB mode");
// lastmodestate = modestate; // 2001-12-10 Reduced compiler warnings by Jeff Ford
modestate = MS_FULLDIB;
vid_fulldib_on_focus_mode = modenum;
WindowRect.top = WindowRect.left = 0;
hdc = GetDC(NULL);
WindowRect.right = modelist[modenum].width << modelist[modenum].stretched;
WindowRect.bottom = modelist[modenum].height << modelist[modenum].stretched;
ReleaseDC(NULL,hdc);
DIBWidth = modelist[modenum].width;
DIBHeight = modelist[modenum].height;
WindowStyle = WS_POPUP | WS_SYSMENU | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
ExWindowStyle = 0;
AdjustWindowRectEx(&WindowRect, WindowStyle, FALSE, 0);
SetWindowLong(mainwindow, GWL_STYLE, WindowStyle | WS_VISIBLE);
SetWindowLong(mainwindow, GWL_EXSTYLE, ExWindowStyle);
if (!SetWindowPos (mainwindow,
NULL,
0, 0,
WindowRect.right - WindowRect.left,
WindowRect.bottom - WindowRect.top,
SWP_NOCOPYBITS | SWP_NOZORDER))
{
Sys_Error ("Couldn't resize DIB window");
}
// position and show the DIB window
SetWindowPos (mainwindow, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_SHOWWINDOW | SWP_DRAWFRAME);
ShowWindow (mainwindow, SW_SHOWDEFAULT);
UpdateWindow (mainwindow);
// Because we have set the background brush for the window to NULL
// (to avoid flickering when re-sizing the window on the desktop), we
// clear the window to black when created, otherwise it will be
// empty while Quake starts up.
hdc = GetDC(mainwindow);
PatBlt(hdc,0,0,WindowRect.right,WindowRect.bottom,BLACKNESS);
ReleaseDC(mainwindow, hdc);
/* Create the MGL window DC and the MGL memory DC */
if ((windc = MGL_createWindowedDC(mainwindow)) == NULL)
MGL_fatalError("Unable to create Fullscreen DIB DC!");
if ((dibdc = MGL_createMemoryDC(DIBWidth,DIBHeight,8,&pf)) == NULL)
MGL_fatalError("Unable to create Memory DC!");
MGL_makeCurrentDC(dibdc);
vid.buffer = vid.conbuffer = vid.direct = dibdc->surface;
vid.rowbytes = vid.conrowbytes = dibdc->mi.bytesPerLine;
vid.numpages = 1;
vid.maxwarpwidth = WARP_WIDTH;
vid.maxwarpheight = WARP_HEIGHT;
vid.height = vid.conheight = DIBHeight;
vid.width = vid.conwidth = DIBWidth;
vid.aspect = ((float)vid.height / (float)vid.width) *
(320.0 / 240.0);
vid_stretched = modelist[modenum].stretched;
// needed because we're not getting WM_MOVE messages fullscreen on NT
window_x = 0;
window_y = 0;
return true;
}
void VID_RestoreOldMode (int original_mode)
{
static qboolean inerror = false;
if (inerror)
return;
in_mode_set = false;
inerror = true;
// make sure mode set happens (video mode changes)
vid_modenum = original_mode - 1;
if (!VID_SetMode (original_mode, vid_curpal))
{
vid_modenum = MODE_WINDOWED - 1;
if (!VID_SetMode (windowed_default, vid_curpal))
Sys_Error ("Can't set any video mode");
}
inerror = false;
}
void VID_SetDefaultMode (void)
{
if (vid_initialized)
VID_SetMode (0, vid_curpal);
IN_DeactivateMouse ();
}
int VID_SetMode (int modenum, unsigned char *palette)
{
int original_mode, temp, dummy;
qboolean stat;
MSG msg;
HDC hdc;
while ((modenum >= nummodes) || (modenum < 0))
{
if (vid_modenum == NO_MODE)
{
if (modenum == vid_default)
{
modenum = windowed_default;
}
else
{
modenum = vid_default;
}
Cvar_SetValue (vid_mode, (float)modenum);
}
else
{
Cvar_SetValue (vid_mode, (float)vid_modenum);
return 0;
}
}
if (!force_mode_set && (modenum == vid_modenum))
return true;
// so Con_Printfs don't mess us up by forcing vid and snd updates
temp = scr_disabled_for_loading;
scr_disabled_for_loading = true;
in_mode_set = true;
CDAudio_Pause ();
S_ClearBuffer ();
if (vid_modenum == NO_MODE)
original_mode = windowed_default;
else
original_mode = vid_modenum;
// Set either the fullscreen or windowed mode
if (modelist[modenum].type == MS_WINDOWED)
{
if (_windowed_mouse->value)
{
stat = VID_SetWindowedMode(modenum);
IN_ActivateMouse ();
IN_HideMouse ();
}
else
{
IN_DeactivateMouse ();
IN_ShowMouse ();
stat = VID_SetWindowedMode(modenum);
}
}
else if (modelist[modenum].type == MS_FULLDIB)
{
stat = VID_SetFullDIBMode(modenum);
IN_ActivateMouse ();
IN_HideMouse ();
}
else
{
stat = VID_SetFullscreenMode(modenum);
IN_ActivateMouse ();
IN_HideMouse ();
}
window_width = vid.width << vid_stretched;
window_height = vid.height << vid_stretched;
VID_UpdateWindowStatus ();
CDAudio_Resume ();
scr_disabled_for_loading = temp;
if (!stat)
{
VID_RestoreOldMode (original_mode);
return false;
}
if (hide_window)
return true;
// now we try to make sure we get the focus on the mode switch, because
// sometimes in some systems we don't. We grab the foreground, then
// finish setting up, pump all our messages, and sleep for a little while
// to let messages finish bouncing around the system, then we put
// ourselves at the top of the z order, then grab the foreground again,
// Who knows if it helps, but it probably doesn't hurt
if (!force_minimized)
SetForegroundWindow (mainwindow);
hdc = GetDC(NULL);
if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
vid_palettized = true;
else
vid_palettized = false;
VID_SetPalette (palette);
ReleaseDC(NULL,hdc);
vid_modenum = modenum;
Cvar_SetValue (vid_mode, (float)vid_modenum);
if (!VID_AllocBuffers (vid.width, vid.height))
{
// couldn't get memory for this mode; try to fall back to previous mode
VID_RestoreOldMode (original_mode);
return false;
}
D_InitCaches (vid_surfcache, vid_surfcachesize);
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -