⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r_d3d_old.cpp

📁 The source code of Doom legacy for windows
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    // 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 + -