📄 donuts.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
/*==========================================================================
*
*
* File: donuts.c
* Content: Shoot-em-up game
*
*
***************************************************************************/
#define INITGUID
#include "donuts.h"
#include <strsafe.h>
#include "winuserm.h"
LPDIRECTDRAW lpDD = NULL;
LPDIRECTDRAWSURFACE lpFrontBuffer = NULL;
LPDIRECTDRAWSURFACE lpBackBuffer = NULL;
LPDIRECTDRAWSURFACE lpDonut = NULL;
LPDIRECTDRAWSURFACE lpPyramid = NULL;
LPDIRECTDRAWSURFACE lpCube = NULL;
LPDIRECTDRAWSURFACE lpSphere = NULL;
LPDIRECTDRAWSURFACE lpShip = NULL;
LPDIRECTDRAWSURFACE lpNum = NULL;
LPDIRECTDRAWPALETTE lpArtPalette = NULL;
LPDIRECTDRAWPALETTE lpSplashPalette = NULL;
BOOL bSoundEnabled = FALSE;
BOOL bPlayIdle = FALSE;
BOOL bPlayBuzz = FALSE;
BOOL bPlayRev = FALSE;
BOOL bSingleBuffer = FALSE;
BOOL lastThrust = FALSE;
BOOL lastShield = FALSE;
int showDelay = 0;
HWND hWndMain;
HACCEL hAccel;
HINSTANCE hInst;
BOOL bShowFrameCount=TRUE;
BOOL bIsActive;
BOOL bMouseVisible;
DWORD dwFrameCount;
DWORD dwFrameTime;
DWORD dwFrames;
DWORD dwFramesLast;
BOOL bTest=FALSE;
BOOL bStress=FALSE;
DWORD dwTransType;
RGBQUAD SPalette[256];
DWORD lastTickCount;
int score;
int ProgramState;
int level;
int restCount;
DWORD dwFillColor;
BOOL bSpecialEffects = FALSE;
int iForceErase = 0;
DWORD ShowLevelCount = 3000;
DWORD ScreenX;
DWORD ScreenY;
DWORD ScreenBpp;
BOOL bWantSound = TRUE; //global flag to turn off sound
int getint(char**p, int def);
LPCTSTR cszAppName = TEXT("DONUTS");
TCHAR DebugBuf[256];
DBLNODE DL; // Display List
HSNDDEVICE hSoundDevice;
HSNDOBJ hsoBeginLevel = NULL;
HSNDOBJ hsoEngineIdle = NULL;
HSNDOBJ hsoEngineRev = NULL;
HSNDOBJ hsoSkidToStop = NULL;
HSNDOBJ hsoShieldBuzz = NULL;
HSNDOBJ hsoShipExplode = NULL;
HSNDOBJ hsoFireBullet = NULL;
HSNDOBJ hsoShipBounce = NULL;
HSNDOBJ hsoDonutExplode = NULL;
HSNDOBJ hsoPyramidExplode = NULL;
HSNDOBJ hsoCubeExplode = NULL;
HSNDOBJ hsoSphereExplode = NULL;
// timeGetTime currently not supported on WinCE.
#define timeGetTime GetTickCount
// DirectInput work-around.
DWORD GlobalInput = 0;
void setup_game(void)
{
restCount = GetTickCount();
initLevel( ++level );
// set the palette
if (NULL != lpArtPalette)
lpFrontBuffer->lpVtbl->SetPalette( lpFrontBuffer, lpArtPalette );
}
/*
*
* AppPause
*
*/
void AppPause(void)
{
return;
}
/*
*
* AppUnpause
*
* Reset the various time counters so the donuts don't suddenly
* jump halfways across the screen and so the frame rate remains accurate.
*
*/
void AppUnpause(void)
{
iForceErase = 2;
lastTickCount = dwFrameTime = timeGetTime();
}
//-----------------------------------------------------------------------------
// Name: EnumFunction()
// Desc: Enumeration callback for surfaces in flipping chain. We expect this
// function to be called once with the surface interface pointer of
// our back buffer (we only ask for a single back buffer.)
//-----------------------------------------------------------------------------
static HRESULT PASCAL
EnumFunction(LPDIRECTDRAWSURFACE pSurface,
LPDDSURFACEDESC lpSurfaceDesc,
LPVOID lpContext)
{
static BOOL bCalled = FALSE;
if (!bCalled) {
*((LPDIRECTDRAWSURFACE *)lpContext) = pSurface;
bCalled = TRUE;
return DDENUMRET_OK;
}
else {
OutputDebugString(L"DDEX4: Enumerated more than surface?");
pSurface->lpVtbl->Release( pSurface );
return DDENUMRET_CANCEL;
}
}
/*
* MainWndproc
*
* Callback for all Windows messages
*/
long FAR PASCAL MainWndproc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
UINT cmd;
switch( message )
{
case WM_ACTIVATE:
bIsActive = (BOOL) wParam;
if( bIsActive )
{
bMouseVisible = FALSE;
lastTickCount = GetTickCount();
bSpecialEffects = FALSE;
}
else
{
bMouseVisible = TRUE;
// DirectInput automatically unacquires for us in FOREGROUND mode
}
break;
case WM_SETCURSOR:
// Turn off the cursor since this is a full-screen app
SetCursor(NULL);
return TRUE;
case WM_COMMAND:
cmd = GET_WM_COMMAND_ID(wParam, lParam);
switch (cmd) {
case IDC_FRAMERATE:
bShowFrameCount = !bShowFrameCount;
if( bShowFrameCount )
{
dwFrameCount = 0;
dwFrameTime = timeGetTime();
}
break;
case IDC_STARTGAME:
if( ProgramState == PS_SPLASH )
{
ProgramState = PS_BEGINREST;
setup_game();
}
break;
case IDC_QUIT:
PostMessage( hWnd, WM_CLOSE, 0, 0 );
return 0;
case IDC_AUDIO:
if(bWantSound)
{
if( bSoundEnabled )
{
DestroySound();
}
else
{
InitializeSound();
}
}
break;
case IDC_TRAILS:
bSpecialEffects = !bSpecialEffects;
break;
}
break;
case WM_ERASEBKGND:
return 1;
case WM_PAINT:
BeginPaint( hWnd, &ps );
EndPaint( hWnd, &ps );
return 0;
case WM_CLOSE:
DestroyGame();
DestroyWindow(hWnd);
return 0;
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
// Work-Around the fact that we don't have D-Input.
case WM_KEYDOWN:
switch (wParam) {
case VK_NUMPAD8:
case VK_UP:
GlobalInput |= KEY_UP;
break;
case VK_NUMPAD2:
case VK_DOWN:
GlobalInput |= KEY_DOWN;
break;
case VK_NUMPAD4:
case VK_LEFT:
GlobalInput |= KEY_LEFT;
break;
case VK_NUMPAD6:
case VK_RIGHT:
GlobalInput |= KEY_RIGHT;
break;
case VK_ACTION:
GlobalInput |= KEY_FIRE;
break;
case VK_NUMPAD5:
case VK_CLEAR:
case VK_APP1:
GlobalInput |= KEY_STOP;
break;
case VK_NUMPAD7:
case VK_HOME:
case VK_APP2:
GlobalInput |= KEY_SHIELD;
break;
}
break;
case WM_KEYUP:
switch (wParam) {
case VK_NUMPAD8:
case VK_UP:
GlobalInput &= ~KEY_UP;
break;
case VK_NUMPAD2:
case VK_DOWN:
GlobalInput &= ~KEY_DOWN;
break;
case VK_NUMPAD4:
case VK_LEFT:
GlobalInput &= ~KEY_LEFT;
break;
case VK_NUMPAD6:
case VK_RIGHT:
GlobalInput &= ~KEY_RIGHT;
break;
case VK_ACTION:
GlobalInput &= ~KEY_FIRE;
break;
case VK_NUMPAD5:
case VK_CLEAR:
case VK_APP1:
GlobalInput &= ~KEY_STOP;
break;
case VK_NUMPAD7:
case VK_HOME:
case VK_APP2:
GlobalInput &= ~KEY_SHIELD;
break;
}
break;
default:
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
} /* MainWndproc */
/*
* initApplication
*
* Do that Windows initialization stuff...
*/
static BOOL initApplication( HANDLE hInstance, int nCmdShow )
{
WNDCLASS wc;
BOOL rc;
wc.style = CS_DBLCLKS;
wc.lpfnWndProc = MainWndproc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(DONUTS_ICON));
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = GetStockObject( BLACK_BRUSH );
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("DonutsClass");
rc = RegisterClass( &wc );
if( !rc )
{
return FALSE;
}
hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(DONUTS_ACCEL));
if ( !hAccel )
{
return FALSE;
}
hWndMain = CreateWindowEx(WS_EX_TOPMOST,
wc.lpszClassName,
TEXT("Donuts"),
WS_VISIBLE | // so we don't have to call ShowWindow
WS_POPUP, // non-app window
0,
0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
NULL,
NULL,
hInstance,
NULL );
if( !hWndMain )
{
return FALSE;
}
SetFocus(hWndMain);
return TRUE;
} /* initApplication */
/*
* WinMain
*/
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine,
int nCmdShow )
{
MSG msg;
int retcode = 0;
// save off application instance
hInst = hInstance;
while( lpCmdLine[0] == '-' )
{
lpCmdLine++;
switch (*lpCmdLine++)
{
case 't':
bTest = TRUE;
break;
case 'S':
bWantSound = FALSE;
break;
case 'x':
bStress= TRUE;
bTest = TRUE;
break;
}
while( IS_SPACE(*lpCmdLine) )
{
lpCmdLine++;
}
}
if( !initApplication(hInstance, nCmdShow) )
{
return FALSE;
}
if( !InitializeGame() )
{
DestroyWindow( hWndMain );
return FALSE;
}
dwFrameTime = timeGetTime();
// Turn on unfiltered button message mode.
OpenGapiInput();
while( 1 )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if (msg.message == WM_QUIT)
{
retcode = (int)msg.wParam;
break;
}
if ( !TranslateAccelerator( hWndMain, hAccel, &msg ) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else if ( bIsActive )
{
UpdateFrame();
}
}
//Turn off unfiltered button message mode.
CloseGapiInput();
return retcode;
} /* WinMain */
void DestroyGame( void )
{
// Undo what has been done...
DestroySound();
if( lpDonut != NULL )
lpDonut->lpVtbl->Release( lpDonut );
if( lpPyramid != NULL )
lpPyramid->lpVtbl->Release( lpPyramid );
if( lpCube != NULL )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -