📄 r_d3d_old.cpp
字号:
// If this is a hardware device, we have found
// what we are looking for.
if (fIsHardware)
return D3DENUMRET_CANCEL;
// Otherwise, keep looking.
return D3DENUMRET_OK;
}
// --------------------------------------------------------------------------
// Get the list of available display modes
// --------------------------------------------------------------------------
EXPORT void HWRAPI( GetModeList ) (void** pvidmodes, int* numvidmodes)
{
BOOL fDeviceFound = FALSE;
HRESULT hr;
DBG_Printf ("GetModeList(): ");
// In this code fragment, the variable lpd3d contains a valid
// pointer to the IDirect3D3 interface that the application obtained
// prior to executing this code.
hr = lpD3D->EnumDevices(GetModeListCallback, &fDeviceFound);
if (FAILED(hr))
{
// Code to handle the error goes here.
DBG_Printf ("EnumDevices FAILED\r\n");
DBG_Printf (DDErr(hr));
*numvidmodes = 0;
return;
}
/*if (!fDeviceFound)
{
// Code to handle the error goes here.
DBG_Printf ("no device found\r\n");
*numvidmodes = 0;
return;
} */
// add first the default mode
d3dvidmodes[NUMD3DVIDMODES-1].pnext = NULL;
*((vmode_t**)pvidmodes) = &d3dvidmodes[0];
*numvidmodes = NUMD3DVIDMODES;
}
// ==========================================================================
// Set video mode routine for GLIDE display modes
// Out: 1 ok,
// 0 hardware could not set mode,
// -1 no mem
// ==========================================================================
// current hack to allow the software view to co-exist for development
static BOOL VID_FreeAndAllocVidbuffer (viddef_t *lvid)
{
int vidbuffersize;
vidbuffersize = (lvid->width * lvid->height * lvid->bpp * 4/*numscreens*/)
+ (lvid->width * 32/*st_height*/ * lvid->bpp); //status bar
// allocate the new screen buffer
if( (lvid->buffer = (byte *) malloc(vidbuffersize))==NULL )
return FALSE;
// initially clear the video buffer
memset (lvid->buffer, 0, vidbuffersize);
return TRUE;
}
// ==========================================================================
// CreateNewSurface
// ==========================================================================
LPDIRECTDRAWSURFACE4 CreateNewSurface(int dwWidth,
int dwHeight,
int dwSurfaceCaps)
{
DDSURFACEDESC2 ddsd;
HRESULT hr;
// DDCOLORKEY ddck;
LPDIRECTDRAWSURFACE4 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 = lpDD4->CreateSurface (&ddsd, &psurf, NULL);
if (FAILED(hr)) {
DBG_Printf (DDErr(hr));
psurf = NULL;
}
else
{
psurf->Restore();
//hr = ScreenReal->lpVtbl->GetColorKey(DDCKEY_SRCBLT, &ddck);
//psurf->SetColorKey(DDCKEY_SRCBLT, &ddck);
}
return psurf;
}
// ==========================================================================
// Set display mode
// ==========================================================================
static boolean d3d_display = false;
static BOOL fullScreen = FALSE;
#define DIMW 640
#define DIMH 480
int D3D_SetMode (viddef_t *lvid, vmode_t *pcurrentmode)
{
DWORD dwStyle;
HRESULT hr;
if (d3d_display)
return 1;
// say we're double-buffering, although this value isn't used..
lvid->numpages = 2;
//TODO: release stuff from previous Glide mode...
if (!VID_FreeAndAllocVidbuffer (lvid))
return -1;
//-------------------------------------------------------------------------
// Change window attributes
//-------------------------------------------------------------------------
HWND appWin = lvid->WndParent; //GetActiveWindow ();
if (appWin == NULL) {
DBG_Printf ("GetActiveWindow FAILED\r\n");
return FALSE;
}
if (fullScreen)
{
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);
}
else
{
RECT rect;
rect.top = 0;
rect.left = 0;
rect.bottom = DIMW - 1;
rect.right = DIMH - 1;
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);
}
// just in case..
ShowWindow(appWin, SW_SHOW);
//-------------------------------------------------------------------------
// Set the Windows cooperative level.
//-------------------------------------------------------------------------
hr = lpDD4->SetCooperativeLevel (appWin,
(fullScreen ? DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT : DDSCL_NORMAL) );
if (FAILED(hr)) {
DBG_Printf ("SetCooperativeLevel FAILED\r\n");
DBG_Printf (DDErr(hr));
return FALSE;
}
//-------------------------------------------------------------------------
// Create DirectDraw surfaces used for rendering
//-------------------------------------------------------------------------
DDSURFACEDESC2 ddsd;
ZeroMemory (&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
// 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.
if (fullScreen) {
ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;
ddsd.ddsCaps.dwCaps |= DDSCAPS_FLIP | DDSCAPS_COMPLEX;
}
hr = lpDD4->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
if (FAILED(hr)) {
DBG_Printf ("CreateSurface Primary Screen FAILED");
DBG_Printf (DDErr(hr));
return FALSE;
}
if (fullScreen)
{
// Get a pointer to the back buffer
DDSCAPS2 ddscaps;
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;// | DDSCAPS_3DDEVICE;
hr = lpDDSPrimary->GetAttachedSurface (&ddscaps, &lpDDSBackBuffer);
if (FAILED(hr)) {
DBG_Printf ("GetAttachedSurface FAILED");
DBG_Printf (DDErr(hr));
return FALSE;
}
}
else
{
GetClientRect( appWin, &rcScreenRect );
GetClientRect( appWin, &rcViewportRect );
ClientToScreen( appWin, (POINT*)&rcScreenRect.left );
ClientToScreen( appWin, (POINT*)&rcScreenRect.right );
// Create a back buffer for offscreen rendering, this will be used to
// blt to the primary
lpDDSBackBuffer = CreateNewSurface(DIMW, DIMH, DDSCAPS_OFFSCREENPLAIN |
DDSCAPS_3DDEVICE);
if (lpDDSBackBuffer == NULL) {
DBG_Printf ("CreateSurface Secondary Screen FAILED");
return FALSE;
}
}
if (!fullScreen)
{
LPDIRECTDRAWCLIPPER pcClipper;
hr = lpDD4->CreateClipper( 0, &pcClipper, NULL );
if (FAILED(hr)) {
DBG_Printf (DDErr(hr));
return FALSE;
}
pcClipper->SetHWnd( 0, appWin );
lpDDSPrimary->SetClipper( pcClipper );
pcClipper->Release();
}
//-------------------------------------------------------------------------
// Create the Direct3D interfaces
//-------------------------------------------------------------------------
// Query DirectDraw for access to Direct3D
// see Init()
// Before creating the device, check that we are NOT in a palettized
// display. That case will cause CreateDevice() to fail, don't bother
// with palettes..
ddsd.dwSize = sizeof(ddsd);
lpDD4->GetDisplayMode( &ddsd );
if( ddsd.ddpfPixelFormat.dwRGBBitCount <= 8 )
{
DBG_Printf ("Screen palettized format not supported\r\n");
return FALSE;
}
// Create the device. The GUID is hardcoded for now, but should come from
// device enumeration, which is the topic of a future tutorial. The device
// is created off of our back buffer, which becomes the render target for
// the newly created device.
hr = lpD3D->CreateDevice( IID_IDirect3DHALDevice, lpDDSBackBuffer,
&lpD3DDevice, NULL );
if( FAILED( hr ) ) {
DBG_Printf ("Create Device FAILED\r\n");
DBG_Printf (DDErr(hr));
return FALSE;
}
//-------------------------------------------------------------------------
// Create the viewport
//-------------------------------------------------------------------------
// Set up the viewport data parameters
D3DVIEWPORT2 vdData;
ZeroMemory( &vdData, sizeof(vdData) );
vdData.dwSize = sizeof(vdData);
vdData.dwWidth = DIMW;
vdData.dwHeight = DIMH;
vdData.dvClipX = -1.0f;
vdData.dvClipWidth = 2.0f;
vdData.dvClipY = 1.0f;
vdData.dvClipHeight = 2.0f;
vdData.dvMaxZ = 1.0f;
// Create the viewport
hr = lpD3D->CreateViewport( &lpD3DViewport, NULL );
if( FAILED( hr ) ) {
DBG_Printf ("lpD3D->CreateViewport FAILED\r\n");
DBG_Printf (DDErr(hr));
return FALSE;
}
// Associate the viewport with the D3DDEVICE object
lpD3DDevice->AddViewport( lpD3DViewport );
// Set the parameters to the new viewport
lpD3DViewport->SetViewport2( &vdData );
// Set the viewport as current for the device
lpD3DDevice->SetCurrentViewport( lpD3DViewport );
//-------------------------------------------------------------------------
// We're done and ready to set up our scene
//-------------------------------------------------------------------------
// set initial state of d3d
D3D_InitStates (lpD3DDevice, lpD3DViewport);
lvid->direct = NULL;
d3d_display = true;
//save lvid to free software vidbuffer on shutdown
viddef = lvid;
DBG_Printf("SetD3DMode() succesfull\r\n");
return 1;
}
// --------------------------------------------------------------------------
// Checks for lost surfaces and restores them if lost.
// --------------------------------------------------------------------------
void RestoreSurfaces()
{
// Check/restore the primary surface
if( lpDDSPrimary )
if( lpDDSPrimary->IsLost() )
lpDDSPrimary->Restore();
// Check/restore the back buffer
if( lpDDSBackBuffer )
if( lpDDSBackBuffer->IsLost() )
lpDDSBackBuffer->Restore();
}
// --------------------------------------------------------------------------
// Swap front and back buffers
// --------------------------------------------------------------------------
EXPORT void HWRAPI( FinishUpdate ) (void)
{
HRESULT hr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -