www.gusucode.com > VC++纯Win32生成火焰效果的源代码源码程序 > VC++纯Win32生成火焰效果的源代码源码程序/code/fire.cpp

    /*==========================================================================
 *
 *  Copyright (C) 1995-1996 Microsoft Corporation. All Rights Reserved.
 *  download by http://www.NewXing.com
 *  File:       ddex1.cpp
 *  Content:    Direct Draw example program 1.  Creates a Direct Draw 
 *              object and then a primary surface with a back buffer.
 *              Slowly flips between the primary surface and the back
 *              buffer.  Press F12 to terminate the program.
 *
 ***************************************************************************/

#define NAME "DDExample1"
#define TITLE "Direct Draw Example 1"

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <fstream.h>
#include <ddraw.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <io.h>
#include "gif89a.h"
#include "cfire.h"

#define TIMER_ID        1
#define TIMER_RATE      30

void showAFile();
DWORD WINAPI demo(LPVOID lpparm);

LPDIRECTDRAW            lpDD;           // DirectDraw object
LPDIRECTDRAWSURFACE     lpDDSPrimary;   // DirectDraw primary surface
LPDIRECTDRAWSURFACE     lpDDSBack;      // DirectDraw back surface
DWORD RBitMask,GBitMask,BBitMask;
BOOL                    bActive;        // is application active?
BOOL                    bQuit = false;
HANDLE					thandle;
HWND                hwnd;
CFire fire(640,480);

WORD (*RGBto16bit)(unsigned char r,unsigned char g,unsigned char b);

BOOL initWindow( HINSTANCE hInstance, int nCmdShow );
BOOL initDDraw(void);
BOOL initFire(void);
long FAR PASCAL WindowProc( HWND hWnd, UINT message, 
                            WPARAM wParam, LPARAM lParam );
void finiObjects( void );

time_t tt;
long frames,rate,k;

WORD RGBto16bit565(unsigned char r,unsigned char g,unsigned char b)
{	return (((WORD)r<<8)&0xf800)|(((WORD)g<<3)&0x07e0)|((WORD)b>>3);
}

WORD RGBto16bit555(unsigned char r,unsigned char g,unsigned char b)
{	return (((WORD)r<<7)&0x7c00)|(((WORD)g<<2)&0x03e0)|((WORD)b>>3);
}

int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        LPSTR lpCmdLine, int nCmdShow)
{   MSG         msg;
    lpCmdLine = lpCmdLine;
    hPrevInstance = hPrevInstance;
	DWORD tID;
    if( !initWindow( hInstance, nCmdShow ) )
    {   return FALSE;
    }
	if(!initDDraw())
	{	 goto error;
	}
	if(!initFire())
	{	 goto error;
	} 
	if((thandle = CreateThread(NULL,0,demo,NULL,0,&tID)) == NULL)
		goto error;
    while (GetMessage(&msg, NULL, 0, 0))
    {	
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
error:
	char buf[40];
	sprintf(buf, "初始化失败!");
    MessageBox( hwnd, buf, "ERROR", MB_OK );
	finiObjects();
    DestroyWindow( hwnd );
	return FALSE;
}

BOOL initWindow( HINSTANCE hInstance, int nCmdShow )
{   WNDCLASS            wc;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
    wc.hbrBackground = NULL;
    wc.lpszMenuName = NAME;
    wc.lpszClassName = NAME;
    RegisterClass( &wc );
    
    hwnd = CreateWindowEx(
        WS_EX_TOPMOST,
        NAME,
        TITLE,
        WS_POPUP,
        0, 0,
        GetSystemMetrics( SM_CXSCREEN ),
        GetSystemMetrics( SM_CYSCREEN ),
        NULL,
        NULL,
        hInstance,
        NULL );

    if( !hwnd )
    {
        return FALSE;
    }

    ShowWindow( hwnd, nCmdShow );
    UpdateWindow( hwnd );
//	MessageBox( hwnd, "Hello!", "", MB_OK); 
	return TRUE;
}

BOOL initFire(void)
{	if(!fire)
		return FALSE;
	if(!fire.loadSeedMap("seed.gif"))
		return FALSE;
	if(!fire.loadCoolMap("cool.gif"))
		return FALSE;
	if(!fire.loadLightMap("light.gif"))
		return FALSE;
	return TRUE;
}

BOOL initDDraw(void)
{   DDSURFACEDESC       ddsd;
	DDSCAPS             ddscaps;
    HRESULT             ddrval;
    char                buf[256];
	ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
    if( ddrval == DD_OK )
    {   // Get exclusive mode
        ddrval = lpDD->SetCooperativeLevel( hwnd,
                                DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
        if(ddrval == DD_OK )
        {   ddrval = lpDD->SetDisplayMode( 640,480, 16 );
            if( ddrval == DD_OK )
            {   // Create the primary surface with 1 back buffer
                ddsd.dwSize = sizeof( ddsd );
				ddsd.dwFlags = DDSD_CAPS | 
							   DDSD_BACKBUFFERCOUNT;
                ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
                                      DDSCAPS_FLIP | 
                                      DDSCAPS_COMPLEX;
                ddsd.dwBackBufferCount = 1;
                ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
                if( ddrval == DD_OK )
                {   ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
                    ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, 
                                                          &lpDDSBack);
					if( ddrval == DD_OK )
					{	DDPIXELFORMAT pixelFormat;
						pixelFormat.dwSize = sizeof(DDPIXELFORMAT);
						lpDDSPrimary->GetPixelFormat(&pixelFormat);
						if((pixelFormat.dwFlags&DDPF_RGB)==0)
							goto error;
						RBitMask = pixelFormat.dwRBitMask;
						GBitMask = pixelFormat.dwGBitMask;
						BBitMask = pixelFormat.dwBBitMask;
						if(((WORD)GBitMask) == 0x07e0)
							RGBto16bit = RGBto16bit565;
						else
							RGBto16bit = RGBto16bit555;
						return TRUE;
					}
                }
			}
        }
    }
error:
    wsprintf(buf, "Direct Draw Init Failed (%08lx)\n", ddrval );
    MessageBox( hwnd, buf, "ERROR", MB_OK );
    return FALSE;
}

long FAR PASCAL WindowProc( HWND hWnd, UINT message, 
                            WPARAM wParam, LPARAM lParam )
{    switch( message )
    {
    case WM_ACTIVATEAPP:
        bActive = wParam;
        break;

    case WM_CREATE:
        break;

    case WM_SETCURSOR:
        SetCursor(NULL);
        return TRUE;
    case WM_KEYDOWN:
        switch( wParam )
        {
        case VK_ESCAPE:
        case VK_F12:
			bQuit = true;
			while(WaitForSingleObject(thandle,200) != WAIT_OBJECT_0)
				;
            PostMessage(hWnd, WM_CLOSE, 0, 0);
            break;
		}
        break;
    case WM_PAINT:
        break;

    case WM_DESTROY:
        finiObjects();
        PostQuitMessage( 0 );
        break;
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}

void finiObjects( void )
{
    if( lpDD != NULL )
    {
        if( lpDDSPrimary != NULL )
        {   lpDDSPrimary->Release();
            lpDDSPrimary = NULL;
        }
		lpDD->Release();
        lpDD = NULL;
    }
}

void showAFile()
{	DDSURFACEDESC       ddsd;
	HRESULT             ddrval;
	ddsd.dwSize = sizeof(ddsd);

	DDBLTFX ddbltfx;
	ddbltfx.dwSize = sizeof(ddbltfx);
	ddbltfx.dwFillColor = 0x0000;
	lpDDSBack->Blt(NULL,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT, &ddbltfx);
	while ((ddrval = lpDDSBack->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
		;
	if( ddrval == DD_OK )
	{	fire.render((WORD*)ddsd.lpSurface);
		lpDDSBack->Unlock(NULL);
	}
	while( 1 )
	{
	    ddrval = lpDDSPrimary->Flip( NULL, 0 );
        if( ddrval == DD_OK )
	    {
		    break;
		}
		if( ddrval == DDERR_SURFACELOST )
		{
			ddrval = lpDDSPrimary->Restore();
			if( ddrval != DD_OK )
			{
				break;
			}
		}
		if( ddrval != DDERR_WASSTILLDRAWING )
		{
			break;
		}
	}
}

DWORD WINAPI demo(LPVOID lpparm)
{	static time_t time1 = 0,time2;
	while(1)
	{	if( bQuit )
			return -1;
		if( bActive )
		{	showAFile();
		}
	}
}