📄 ddutil.cpp
字号:
//-----------------------------------------------------------------------------
// File: ddutil.cpp
//
// Desc: DirectDraw framewark classes. Feel free to use this class as a
// starting point for adding extra functionality.
//
//
// Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
//Modified by Kylinx
#define STRICT
#include <tchar.h>
#include <windows.h>
#include <windowsx.h>
#include <ddraw.h>
#include "ddutil.h"
#include "dxutil.h"
#include"ijl.h"
#include <stdio.h>
#pragma warning(disable:4018)
#pragma comment(lib,"ddraw")
#pragma comment(lib,"dxguid")
#pragma comment(lib,"ijl15")
//my code
DWORD CDisplay::m_dwAlphaMask;
WORD (*CDisplay::pGray)(WORD)=NULL;
#define RGB555(r, g, b) ((r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10))
#define RGB565(r, g, b) ((r >> 3) | ((g >> 2) << 5) | ((b >> 3) << 11))
#define C24BIT 24
#define C16BIT 16
//end my code
//-----------------------------------------------------------------------------
// Name: CDisplay()
// Desc:
//-----------------------------------------------------------------------------
CDisplay::CDisplay()
{
m_pDD = NULL;
m_pddsFrontBuffer = NULL;
m_pddsBackBuffer = NULL;
m_pddsBackBufferLeft = NULL;
m_bGrayDisplay=false;
}
//-----------------------------------------------------------------------------
// Name: ~CDisplay()
// Desc:
//-----------------------------------------------------------------------------
CDisplay::~CDisplay()
{
DestroyObjects();
}
//-----------------------------------------------------------------------------
// Name: DestroyObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::DestroyObjects()
{
SAFE_RELEASE( m_pddsBackBufferLeft );
SAFE_RELEASE( m_pddsBackBuffer );
SAFE_RELEASE( m_pddsFrontBuffer );
if( m_pDD )
m_pDD->SetCooperativeLevel( m_hWnd, DDSCL_NORMAL );
SAFE_RELEASE( m_pDD );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CreateFullScreenDisplay()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::CreateFullScreenDisplay( HWND hWnd, DWORD dwWidth,
DWORD dwHeight, DWORD dwBPP )
{
HRESULT hr;
// Cleanup anything from a previous call
DestroyObjects();
// DDraw stuff begins here
if( FAILED( hr = DirectDrawCreateEx( NULL, (VOID**)&m_pDD,
IID_IDirectDraw7, NULL ) ) )
return E_FAIL;
// Set cooperative level
hr = m_pDD->SetCooperativeLevel( hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN );
if( FAILED(hr) )
return E_FAIL;
// Set the display mode
if( FAILED( m_pDD->SetDisplayMode( dwWidth, dwHeight, dwBPP, 0, 0 ) ) )
return E_FAIL;
m_nScreenWidth=dwWidth;
m_nScreenHeight=dwHeight;
m_nBit=dwBPP;
// Create primary surface (with backbuffer attached)
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS ;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE|DDSCAPS_SYSTEMMEMORY;
if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer,
NULL ) ) )
return E_FAIL;
// Get a pointer to the back buffer
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = 640;
ddsd.dwHeight = 480;
if(FAILED(hr = m_pDD->CreateSurface(&ddsd, &m_pddsBackBuffer, NULL)))
return E_FAIL;
if(FAILED(m_pddsFrontBuffer->QueryInterface(IID_IDirectDrawGammaControl,(void**)&m_lpDDGammaControl)))
{
MessageBox(GetActiveWindow(),"Query Gamma Control Interface Failed!","error",MB_OK);
return E_FAIL;
}
m_lpDDGammaControl->GetGammaRamp(0,&m_ddGammaStart);
DDPIXELFORMAT DDPixelFormat;
ZeroMemory(&DDPixelFormat,sizeof(DDPixelFormat));
DDPixelFormat.dwSize=sizeof(DDPixelFormat);
m_pddsFrontBuffer->GetPixelFormat(&DDPixelFormat);
if((DDPixelFormat.dwGBitMask>>5)==0x1f)//00000011111
{
m_dwAlphaMask=_ALPHA555RGBMASK;
pGray=Gray555;
}
else if((DDPixelFormat.dwGBitMask>>5)==0x3f)//00000111111
{
m_dwAlphaMask=_ALPHA565RGBMASK;
pGray=Gray565;
}
// m_pddsBackBuffer->AddRef();
m_hWnd = hWnd;
m_bWindowed = FALSE;
UpdateBounds();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CreateWindowedDisplay()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::CreateWindowedDisplay( HWND hWnd, DWORD dwWidth, DWORD dwHeight,DWORD dwExtStyle )
{
HRESULT hr;
// Cleanup anything from a previous call
DestroyObjects();
// DDraw stuff begins here
if( FAILED( hr = DirectDrawCreateEx( NULL, (VOID**)&m_pDD,
IID_IDirectDraw7, NULL ) ) )
return E_FAIL;
// Set cooperative level
hr = m_pDD->SetCooperativeLevel( hWnd, DDSCL_NORMAL );
if( FAILED(hr) )
return E_FAIL;
m_nScreenWidth=dwWidth;
m_nScreenHeight=dwHeight;
RECT rcWork;
RECT rc;
DWORD dwStyle;
// If we are still a WS_POPUP window we should convert to a normal app
// window so we look like a windows app.
dwStyle = GetWindowStyle( hWnd );
dwStyle &= ~WS_POPUP;
dwStyle |=WS_CAPTION |WS_SYSMENU|dwExtStyle;
SetWindowLong( hWnd, GWL_STYLE, dwStyle );
// Aet window size
SetRect( &rc, 0, 0, dwWidth, dwHeight );
AdjustWindowRectEx( &rc, GetWindowStyle(hWnd), GetMenu(hWnd) != NULL,
GetWindowExStyle(hWnd) );
SetWindowPos( hWnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
SetWindowPos( hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
// Make sure our window does not hang outside of the work area
SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWork, 0 );
GetWindowRect( hWnd, &rc );
if( rc.left < rcWork.left ) rc.left = rcWork.left;
if( rc.top < rcWork.top ) rc.top = rcWork.top;
SetWindowPos( hWnd, NULL, rc.left, rc.top, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
//Add By Kylinx
MoveWindow(hWnd,(GetSystemMetrics(SM_CXSCREEN)-640)/2,
(GetSystemMetrics(SM_CYSCREEN)-480)/2,
640,
480,
true);
//end Add By Kylinx
LPDIRECTDRAWCLIPPER pcClipper;
// Create the primary surface
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if( FAILED( m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL ) ) )
return E_FAIL;
if(FAILED(m_pddsFrontBuffer->QueryInterface(IID_IDirectDrawGammaControl,(void**)&m_lpDDGammaControl)))
{
MessageBox(GetActiveWindow(),"Query Gamma Control Interface Failed!","error",MB_OK);
return E_FAIL;
}
m_lpDDGammaControl->GetGammaRamp(0,&m_ddGammaStart);
DDPIXELFORMAT DDPixelFormat;
ZeroMemory(&DDPixelFormat,sizeof(DDPixelFormat));
DDPixelFormat.dwSize=sizeof(DDPixelFormat);
m_pddsFrontBuffer->GetPixelFormat(&DDPixelFormat);
HDC hdc=GetDC(hWnd);
m_nBit=GetDeviceCaps(hdc,BITSPIXEL);
if((DDPixelFormat.dwGBitMask>>5)==0x1f)//00000011111
{
m_dwAlphaMask=_ALPHA555RGBMASK;
pGray=Gray555;
}
else if((DDPixelFormat.dwGBitMask>>5)==0x3f)//00000111111
{
m_dwAlphaMask=_ALPHA565RGBMASK;
pGray=Gray565;
}
// Create the backbuffer surface
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE|DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = dwWidth;
ddsd.dwHeight = dwHeight;
if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsBackBuffer, NULL ) ) )
return E_FAIL;
if( FAILED( hr = m_pDD->CreateClipper( 0, &pcClipper, NULL ) ) )
return E_FAIL;
if( FAILED( hr = pcClipper->SetHWnd( 0, hWnd ) ) )
{
pcClipper->Release();
return E_FAIL;
}
if( FAILED( hr = m_pddsFrontBuffer->SetClipper( pcClipper ) ) )
{
pcClipper->Release();
return E_FAIL;
}
// Done with clipper
pcClipper->Release();
m_hWnd = hWnd;
m_bWindowed = TRUE;
UpdateBounds();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::CreateSurface( CSurface** ppSurface,
DWORD dwWidth, DWORD dwHeight )
{
if( NULL == m_pDD )
return E_POINTER;
if( NULL == ppSurface )
return E_INVALIDARG;
HRESULT hr;
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = dwWidth;
ddsd.dwHeight = dwHeight;
(*ppSurface) = new CSurface();
if( FAILED( hr = (*ppSurface)->Create( m_pDD, &ddsd ) ) )
{
delete (*ppSurface);
return hr;
}
return S_OK;
}
HRESULT CDisplay::CreateSurfaceFromJPEG(CSurface**ppSurface,char*strJPEG)
{
IJLERR jerr;
//Create the JPEG object
JPEG_CORE_PROPERTIES jcprops;
//Initialize the JPEG object
jerr = ijlInit(&jcprops);
if (jerr != IJL_OK)
{
return E_FAIL;
}
//Set the IJL data source as a filename
jcprops.JPGFile = strJPEG;
//Read JPEG parameters from the file
jerr = ijlRead(&jcprops, IJL_JFILE_READPARAMS);
//Make sure Parameter read was successful
if (jerr != IJL_OK)
{
return E_FAIL;
}
//Prepare a 24Bit buffer to receive image data
BYTE *buffer24;
//Determine the required size
long szbuff24 = (jcprops.JPGWidth * C24BIT + 7) / 8
* jcprops.JPGHeight;
//Resize the buffer
buffer24 = new BYTE [szbuff24];
if (buffer24 == NULL)
{
return E_FAIL;
}
//Set up the DIB specification for the JPEG decoder
jcprops.DIBWidth = jcprops.JPGWidth;
jcprops.DIBHeight = jcprops.JPGHeight; //Implies a bottom-up DIB.
jcprops.DIBChannels = 3;
jcprops.DIBColor = IJL_BGR;
jcprops.DIBPadBytes = IJL_DIB_PAD_BYTES(jcprops.JPGWidth,3);
jcprops.DIBBytes = reinterpret_cast<BYTE*>(buffer24);
//Set the JPG color space ... this will always be somewhat of an
//educated guess at best because JPEG is "color blind" (i.e.,
//nothing in the bit stream tells you what color space the data was
//encoded from. However, in this example we assume that we are
//reading JFIF files which means that 3 channel images are in the
//YCbCr color space and 1 channel images are in the Y color space.
switch(jcprops.JPGChannels)
{
case 1: jcprops.JPGColor = IJL_G;
break;
case 3: jcprops.JPGColor = IJL_YCBCR;
break;
default:
//This catches everything else, but no color twist will be
//performed by the IJL.
jcprops.DIBColor = (IJL_COLOR)IJL_OTHER;
jcprops.JPGColor = (IJL_COLOR)IJL_OTHER;
break;
}
//Read JPEG image data into our 24bit buffer
jerr = ijlRead(&jcprops, IJL_JFILE_READWHOLEIMAGE);
//Make sure the read was successful
if (jerr != IJL_OK)
{
return E_FAIL;
}
HBITMAP hbm;
WORD *buffer16;
long szbuff16;
//determine the size of our buffer
szbuff16 = ((jcprops.JPGWidth * C16BIT + 7) / 8)
* jcprops.JPGHeight;
//resize the buffer and make sure resize works
buffer16 = new WORD [szbuff16];
if (buffer16 == NULL)
{
return E_FAIL;
}
//Start at the beginning of the buffer
long j = 0;
//Step through the 24bit buffer
//Retrieve 3 channels at a time and convert their values to 16bit
for (long i = 0; i < szbuff24; i += 3)
{
//Check the pixel format and write the color data
//to the 16bit buffer. After the write, advance the
//16bit buffer by one.
if (!this->Is565())
buffer16[j++] = RGB555(buffer24[i], buffer24[i + 1],
buffer24[i + 2]);
else
buffer16[j++] = RGB565(buffer24[i], buffer24[i + 1],
buffer24[i + 2]);
}
//Create the bitmap using the new 16bit buffer
hbm = CreateBitmap (jcprops.JPGWidth, jcprops.JPGHeight, 1,
C16BIT, buffer16);
if(hbm == NULL)
{
return E_FAIL;
}
//remove the new buffer
delete [] buffer16;
//remove the old buffer
delete [] buffer24;
HRESULT hr;
DDSURFACEDESC2 ddsd;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = jcprops.JPGWidth;
ddsd.dwHeight = jcprops.JPGHeight;
(*ppSurface) = new CSurface();
if( FAILED( hr = (*ppSurface)->Create( m_pDD, &ddsd ) ) )
{
delete (*ppSurface);
return hr;
}
// Draw the bitmap on this surface
if( FAILED( hr = (*ppSurface)->DrawBitmap( hbm, 0, 0, 0, 0 ) ) )
{
DeleteObject( hbm );
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -