📄 fabdxlib.c
字号:
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id: fabdxlib.c,v 1.5 2001/03/30 17:12:52 bpereira Exp $
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//
// $Log: fabdxlib.c,v $
// Revision 1.5 2001/03/30 17:12:52 bpereira
// no message
//
// Revision 1.4 2001/03/03 06:17:34 bpereira
// no message
//
// Revision 1.3 2000/09/01 19:34:37 bpereira
// no message
//
// Revision 1.2 2000/02/27 00:42:12 hurdler
// fix CR+LF problem
//
// Revision 1.1.1.1 2000/02/22 20:32:33 hurdler
// Initial import into CVS (v1.29 pr3)
//
//
// DESCRIPTION:
// faB's DirectX library v1.0
// - converted to C for Doom Legacy
//
//-----------------------------------------------------------------------------
#include "../doomdef.h"
#include <windows.h>
#include <windowsx.h>
#include "dx_error.h"
#include <ddraw.h>
#include "fabdxlib.h"
#include "../i_system.h"
#define NT4COMPAT //always defined, always compatible
// globals
IDirectDraw2* DDr2 = NULL;
IDirectDrawSurface* ScreenReal = NULL; // DirectDraw primary surface
IDirectDrawSurface* ScreenVirtual = NULL; // DirectDraw back surface
IDirectDrawPalette* DDPalette = NULL; // The primary surface palette
IDirectDrawClipper* windclip = NULL; // clipper for windowed mode
BOOL bAppFullScreen; // true for fullscreen exclusive mode,
int windowPosX = 0; // current position in windowed mode
int windowPosY = 0;
int ScreenWidth;
int ScreenHeight;
BOOL ScreenLocked; // Screen surface is being locked
int ScreenPitch; // offset from one line to the next
unsigned char* ScreenPtr; // memory of the surface
//
// CreateNewSurface
//
IDirectDrawSurface* CreateNewSurface(int dwWidth,
int dwHeight,
int dwSurfaceCaps)
{
DDSURFACEDESC ddsd;
HRESULT hr;
// DDCOLORKEY ddck;
LPDIRECTDRAWSURFACE psurf;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = dwSurfaceCaps;
ddsd.dwHeight = dwHeight;
ddsd.dwWidth = dwWidth;
hr = DDr2->lpVtbl->CreateSurface (DDr2, &ddsd, &psurf, NULL);
if( hr == DD_OK )
{
psurf->lpVtbl->Restore(psurf);
//hr = ScreenReal->lpVtbl->GetColorKey(DDCKEY_SRCBLT, &ddck);
//psurf->SetColorKey(DDCKEY_SRCBLT, &ddck);
}
else
psurf = NULL;
return psurf;
}
//
// hmm.. I've got just one device 'Pilote d'affichage principal'
//
BOOL WINAPI myEnumDDDevicesCallback (GUID FAR*lpGUID,
LPSTR lpDriverDescription,
LPSTR lpDriverName,
LPVOID lpContext)
{
CONS_Printf ("Driver desc: %s\n"
" name: %s\n", lpDriverDescription, lpDriverName);
return DDENUMRET_OK;
}
//
// wow! from 320x200x8 up to 1600x1200x32 thanks Banshee! :)
//
BOOL WINAPI myEnumModesCallback (LPDDSURFACEDESC surf, LPVOID lpContext)
{
//LONG iIndex;
//char buff[256];
//HWND hWnd = (HWND) lpContext;
//LPVOID lpDesc = NULL;
((APPENUMMODESCALLBACK)lpContext) (surf->dwWidth,
surf->dwHeight,
surf->ddpfPixelFormat.dwRGBBitCount);
/*CONS_Printf ("%dx%dx%d bpp %d refresh\n",
surf->dwWidth,
surf->dwHeight,
surf->ddpfPixelFormat.dwRGBBitCount,
surf->dwRefreshRate );*/
return DDENUMRET_OK;
}
//
// Application call here to enumerate display modes
//
BOOL EnumDirectDrawDisplayModes (APPENUMMODESCALLBACK appFunc)
{
if (DDr2==NULL)
return FALSE;
// enumerate display modes
// Carl: DirectX 3.x apparently does not support VGA modes. Who cares. :)
// faB: removed DDEDM_REFRESHRATES, detects too many modes, plus we don't care of refresh rate.
if( bDX0300 )
DDr2->lpVtbl->EnumDisplayModes (DDr2, 0 /*| DDEDM_REFRESHRATES*/,
NULL, (void*)appFunc, myEnumModesCallback);
else
DDr2->lpVtbl->EnumDisplayModes (DDr2, DDEDM_STANDARDVGAMODES /*| DDEDM_REFRESHRATES*/,
NULL, (void*)appFunc, myEnumModesCallback);
return TRUE;
}
//
// Create the DirectDraw object for later
//
BOOL CreateDirectDrawInstance (void)
{
HRESULT hr;
IDirectDraw* DDr;
//
// create an instance of DirectDraw object
//
if (FAILED(hr = DirectDrawCreate(NULL, &DDr, NULL)))
I_Error ("DirectDrawCreate FAILED: %s", DXErrorToString(hr));
// change interface to IDirectDraw2
if (FAILED(hr = DDr->lpVtbl->QueryInterface (DDr, &IID_IDirectDraw2, (LPVOID*)&DDr2)))
I_Error("Failed to query DirectDraw2 interface: %s", DXErrorToString(hr));
// release the interface we don't need
DDr->lpVtbl->Release (DDr);
return TRUE;
}
//
// - returns true if DirectDraw was initialized properly
//
int InitDirectDrawe (HWND appWin, int width, int height, int bpp, int fullScr)
{
DDSURFACEDESC ddsd; // DirectDraw surface description for allocating
DDSCAPS ddscaps;
HRESULT ddrval;
DWORD dwStyle;
RECT rect;
// enumerate directdraw devices
//if ( FAILED(DirectDrawEnumerate (myEnumDDDevicesCallback, NULL)))
// I_Error ("Error with DirectDrawEnumerate");
if (!DDr2)
CreateDirectDrawInstance();
// remember what screen mode we are in
bAppFullScreen = fullScr;
ScreenHeight = height;
ScreenWidth = width;
if (bAppFullScreen)
{
// Change window attributes
dwStyle = WS_POPUP | WS_VISIBLE;
SetWindowLong (appWin, GWL_STYLE, dwStyle);
SetWindowPos(appWin, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE |
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
// Get exclusive mode
ddrval = DDr2->lpVtbl->SetCooperativeLevel(DDr2, appWin, DDSCL_EXCLUSIVE |
DDSCL_FULLSCREEN |
DDSCL_ALLOWREBOOT);
if (ddrval != DD_OK)
I_Error ("SetCooperativeLevel FAILED: %s\n", DXErrorToString(ddrval));
// Switch from windows desktop to fullscreen
#ifdef NT4COMPAT
ddrval = DDr2->lpVtbl->SetDisplayMode(DDr2, width, height, bpp, 0, 0);
#else
ddrval = DDr2->lpVtbl->SetDisplayMode(DDr2, width, height, bpp, 0, DDSDM_STANDARDVGAMODE);
#endif
if (ddrval != DD_OK)
I_Error ("SetDisplayMode FAILED: %s\n", DXErrorToString(ddrval));
// This is not really needed, except in certain cases. One case
// is while using MFC. When the desktop is initally at 16bpp, a mode
// switch to 8bpp somehow causes the MFC window to not fully initialize
// and a CreateSurface will fail with DDERR_NOEXCLUSIVEMODE. This will
// ensure that the window is initialized properly after a mode switch.
ShowWindow(appWin, SW_SHOW);
// Create the primary surface with 1 back buffer. Always zero the
// DDSURFACEDESC structure and set the dwSize member!
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
// for fullscreen we use page flipping, for windowed mode, we blit the hidden surface to
// the visible surface, in both cases we have a visible (or 'real') surface, and a hidden
// (or 'virtual', or 'backbuffer') surface.
ddsd.dwBackBufferCount = 1;
ddrval = DDr2->lpVtbl->CreateSurface(DDr2,&ddsd, &ScreenReal, NULL);
if (ddrval != DD_OK)
I_Error ("CreateSurface Primary Screen FAILED");
// Get a pointer to the back buffer
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
ddrval = ScreenReal->lpVtbl->GetAttachedSurface(ScreenReal,&ddscaps, &ScreenVirtual);
if (ddrval != DD_OK)
I_Error ("GetAttachedSurface FAILED");
}
else
{
rect.top = 0;
rect.left = 0;
rect.bottom = height-1;
rect.right = width-1;
// Change window attributes
dwStyle = GetWindowStyle(appWin);
dwStyle &= ~WS_POPUP;
dwStyle |= WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION;
SetWindowLong(appWin, GWL_STYLE, dwStyle);
// Resize the window so that the client area is the requested width/height
AdjustWindowRectEx(&rect, GetWindowStyle(appWin), GetMenu(appWin) != NULL,
GetWindowExStyle(appWin));
// Just in case the window was moved off the visible area of the
// screen.
SetWindowPos(appWin, NULL, 0, 0, rect.right-rect.left,
rect.bottom-rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
SetWindowPos(appWin, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
// Exclusive mode is normal since it's in windowed mode and needs
// to cooperate with GDI
ddrval = DDr2->lpVtbl->SetCooperativeLevel(DDr2,appWin, DDSCL_NORMAL );
if (ddrval != DD_OK)
I_Error ("SetCooperativeLevel FAILED");
// Always zero the DDSURFACEDESC structure and set the dwSize member!
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
// Create the primary surface
ddrval = DDr2->lpVtbl->CreateSurface(DDr2,&ddsd, &ScreenReal, NULL);
if (ddrval != DD_OK)
I_Error ("CreateSurface Primary Screen FAILED");
// Create a back buffer for offscreen rendering, this will be used to
// blt to the primary
ScreenVirtual = CreateNewSurface(width, height, DDSCAPS_OFFSCREENPLAIN |
DDSCAPS_SYSTEMMEMORY );
if (ScreenVirtual == NULL)
I_Error ("CreateSurface Secondary Screen FAILED");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -