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

📄 fabdxlib.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 2 页
字号:
// 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 + -