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

📄 gameproc.c

📁 2D即时战略游戏VC源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*==========================================================================
 *
 *  Copyright (C) 1995-1996 Microsoft Corporation. All Rights Reserved.
 *
 *  File:       gameproc.c
 *  Content:    Game processing code
 *
 *
 ***************************************************************************/
#include "gameproc.h"
#include "util.h"
#include "gfx.h"
#include "comm.h"
#include "input.h"
#include "lobby.h"
#include "wizard.h"
#include "dsound.h"
#include "sfx.h"
#include "stdio.h"

/*
 * Externals
 */
extern DWORD                    gdwKeys;
extern LPDIRECTDRAWSURFACE      glpShip0;
extern LPDIRECTDRAWSURFACE      glpShip1;
extern LPDIRECTDRAWSURFACE      glpShip2;
extern LPDIRECTDRAWSURFACE      glpShip3;
extern BOOL                     gbShowFrameCount;
extern LPDIRECTDRAWSURFACE      glpNum;
extern BOOL                     gbIsHost;
extern BOOL                     gbIsActive;
extern LPDPSESSIONDESC2         glpdpSD;
extern HWND                     ghWndMain;
extern HINSTANCE                ghinst;
extern BOOL                     gbReliable;

/*
 * Globals
 */
FRAG                            gFrags[64];                 // ship framents
BLOCKS                          gBlocks;                    // field layout
LPVOID                          glpvReceiveBuffer = NULL;   // buffer to store received messages
DWORD                           gdwReceiveBufferSize = 0;   // size of buffer
DPID                            gOurID;                     // our player id
BOOL                            gbHaveHostInit;             // do we need to do host initializaton
int                             gnProgramState;             // current state of the game
DWORD                           gdwFrameCount;              // used for fps calc
DWORD                           gdwFramesLast;              // ..
DWORD                           gdwFrameTime;               // ..
BOOL                            gbUpdate;                   // TRUE if player data needs to be updated
BOOL                            gbNoField;                  // display blocks ?
BOOL                            gbSessionLost;              // did we get disconnected ?
HOSTMSG                         gHostMsg;                   // message buffer
BLOCKHITMSG                     gBlockHitMsg;               // ..
SHIPHITMSG                      gShipHitMsg;                // ..
ADDBLOCKMSG                     gAddBlockMsg;               // ..
CONTROLMSG                      gControlMsg;                // .. 
SYNCMSG                         gSyncMsg;                   // ..
TCHAR                           gDebugBuff[MAX_ERRORMSG];   // buffer for debug output

/*
 * Statics
 */

static double      gDirx[40] =                          
{
    0.000000,
    0.156434,
    0.309017,
    0.453991,
    0.587785,
    0.707107,
    0.809017,
    0.891007,
    0.951057,
    0.987688,
    1.000000,
    0.987688,
    0.951057,
    0.891007,
    0.809017,
    0.707107,
    0.587785,
    0.453990,
    0.309017,
    0.156434,
    0.000000,
    -0.156435,
    -0.309017,
    -0.453991,
    -0.587785,
    -0.707107,
    -0.809017,
    -0.891007,
    -0.951057,
    -0.987688,
    -1.000000,
    -0.987688,
    -0.951056,
    -0.891006,
    -0.809017,
    -0.707107,
    -0.587785,
    -0.453990,
    -0.309017,
    -0.156434
};

static double      gDiry[40] =
{
    -1.000000,
    -0.987688,
    -0.951057,
    -0.891007,
    -0.809017,
    -0.707107,
    -0.587785,
    -0.453990,
    -0.309017,
    -0.156434,
    0.000000,
    0.156434,
    0.309017,
    0.453991,
    0.587785,
    0.707107,
    0.809017,
    0.891007,
    0.951057,
    0.987688,
    1.000000,
    0.987688,
    0.951057,
    0.891006,
    0.809017,
    0.707107,
    0.587785,
    0.453990,
    0.309017,
    0.156434,
    0.000000,
    -0.156435,
    -0.309017,
    -0.453991,
    -0.587785,
    -0.707107,
    -0.809017,
    -0.891007,
    -0.951057,
    -0.987688
};

/*
 * InitMessageBuffers
 *
 * Sets up buffes used for sending different types of messages
 */
void InitMessageBuffers(void)
{
    gHostMsg.byType        = MSG_HOST;
    gBlockHitMsg.byType    = MSG_BLOCKHIT;
    gShipHitMsg.byType     = MSG_SHIPHIT;    
    gAddBlockMsg.byType    = MSG_ADDBLOCK;
    gControlMsg.byType     = MSG_CONTROL; 
    gSyncMsg.byType        = MSG_SYNC;
}

/*
 * LaunchGame
 *
 * Sets up the game layout and launches
 */
void LaunchGame(void)
{
    HRESULT hr;

    // initialize global message buffers
    InitMessageBuffers();

    // update window title
    UpdateTitle();

    // get current session description (glpdpSD is initialized in here)
    hr = DPlayGetSessionDesc();
    if (FAILED(hr) || (!glpdpSD))
    {
        ShowError(IDS_DPLAY_ERROR_GSD);
        goto ABORT;
    }

    // initialize random number seed
    srand((int)GetTickCount());

    // clear front buffer before changing palette
    EraseScreen();
    FlipScreen();

    // initialize us
    hr = InitOurShip();
    if (FAILED(hr))
    {
        goto ABORT;
    }

    // get the field layout
    if( gbIsHost )
    {
        // initialize field (done only by host)
        if (!gbNoField)
            InitField();

        // we have host initialization
        gbHaveHostInit = TRUE;

        // start updating screen
        gbIsActive = TRUE;
    }
    else
    {
        // get it from host, if we are joining
        gbHaveHostInit = FALSE;
    }

    // success
    return;

ABORT:
    // something went wrong, terminate game
    ExitGame();
}

/*
 * ExitGame
 *
 * Game termination code
 */
void ExitGame(void)
{
    // shut down app
    PostMessage( ghWndMain, WM_CLOSE, 0, 0 );
}

/*
 * InitOurShip
 *
 * Initializes our ship's initial attributes
 */
HRESULT InitOurShip(void)
{
    int i;
    SHIP ship;
    HRESULT hr;

    // wipe out everything
    ZeroMemory(&ship, sizeof(ship));

    // initialize sound buffers
    InitPlayerLocalSoundData(&ship);

    // calculate ship type based on the number of players in the game
    // we cycle through four ships (Y,R,G,B) for now.

    ship.byType = (BYTE) ((glpdpSD->dwCurrentPlayers-1) % NUM_SHIP_TYPES);
    ship.dPosX  = randInt(0,MAX_SHIP_X);
    ship.dPosY  = randInt(0,MAX_SHIP_Y);
    ship.cFrame = randInt(0, MAX_SHIP_FRAME);
    ship.bEnable = TRUE;

    // set our local data
    hr = DPlaySetPlayerData(gOurID, &ship, sizeof(ship), DPSET_LOCAL);
    if (FAILED(hr))
    {
        ShowError(IDS_DPLAY_ERROR_SPLD);
        goto FAIL;
    }

    // no ship fragments
    for(i=0; i<64; i++)
        gFrags[i].valid = FALSE;

    // success
    return DP_OK;

FAIL:
    // failed
    return hr;
}

/*
 *FUNCTION:   InitPlayerLocalSoundData
 *
 *
 *NOTES:      Takes a ship and initializes ONLY its soundbuffers and sound flags.
 *            It leaves everything else alone.  Good for when going to
 *            full-screen mode, when we need to get rid of the sound buffers
 *            for a bit, but don't want to change the data.
 */
void InitPlayerLocalSoundData(LPSHIP lpShip)
{
int i;
    if (gbSoundInitialized)
    {
        for (i=0; i<MAX_SOUNDS; i++)
        {
            if (FALSE == WaveGetBuffers(gSoundEffect[i],&lpShip->lpDirectSoundBuffer[i], &lpShip->lpDirectSound3DBuffer[i]))
            {//if it didn't work, get rid of all the other sound buffers
                ShowError(IDS_DSOUND_DUPBUF);
                for (--i; i>=0; i--)
                {
                    IDirectSoundBuffer_Release(lpShip->lpDirectSoundBuffer  [i]);
                    IDirectSoundBuffer_Release(lpShip->lpDirectSound3DBuffer[i]);
                    lpShip->lpDirectSoundBuffer  [i] = NULL;
                    lpShip->lpDirectSound3DBuffer[i] = NULL;
                }
                return;
            }
        }

        lpShip->bFiring        = FALSE;
        lpShip->bBounced       = FALSE;
        lpShip->bDeath         = FALSE;
        lpShip->bBlockHit      = FALSE;
        lpShip->bEngineRunning = FALSE;
        lpShip->bMoving        = FALSE;
    }
    else
    {
    //if sound initialization has already failed in InitSfx(), then we want the ships'
    //sound buffers to be NULL so that we don't try to release them later.
        for (i=0; i<MAX_SOUNDS; i++)
        {
            lpShip->lpDirectSoundBuffer  [i] = NULL;
            lpShip->lpDirectSound3DBuffer[i] = NULL;
        }
    }
};

/*
 *FUNCTION:   SetPlayerLocalSoundDataCB (CALLBACK)
 *
 *PURPOSE:    Initializes and registers a player's local SOUND data ONLY.
 */
BOOL WINAPI SetPlayerLocalSoundDataCB(DPID dpId, DWORD dwPlayerType, LPCDPNAME lpName, 
                                      DWORD dwFlags, LPVOID lpContext)
{
    SHIP ship;
    DWORD dwSize = sizeof(ship);
    HRESULT hr;

    DPlayGetPlayerData(dpId, &ship, &dwSize, DPGET_LOCAL); 

    // no player data yet
    if (0 == dwSize)
        return TRUE;

    InitPlayerLocalSoundData(&ship);

    hr = DPlaySetPlayerData(dpId, &ship, dwSize, DPSET_LOCAL);
    return (DP_OK == hr);
};

/*
 *FUNCTION:   InitLocalSoundData
 *
 *PURPOSE:    Initializes and registers all players' sound data ONLY
 */
HRESULT InitLocalSoundData(void)
{
    HRESULT hr;
    hr = DPlayEnumPlayers(&(glpdpSD->guidInstance), SetPlayerLocalSoundDataCB, NULL, 0);
    return hr;
}

/*
 *FUNCTION:   ReleaseLocalSoundData
 *
 *NOTES:      Releases a single ship's local sound buffers.
 */
void ReleasePlayerLocalSoundData(LPSHIP lpShip)
{
int i;

    if (gbSoundInitialized)
    {
        for (i=0; i<MAX_SOUNDS; i++)
        {
            if (lpShip->lpDirectSoundBuffer[i] != NULL)
            {
                IDirectSoundBuffer_Stop     (lpShip->lpDirectSoundBuffer[i]);
                IDirectSoundBuffer_Release  (lpShip->lpDirectSoundBuffer[i]);
                lpShip->lpDirectSoundBuffer[i] = NULL;
            }

            if (lpShip->lpDirectSound3DBuffer[i] != NULL)
            {
                IDirectSound3DBuffer_Release(lpShip->lpDirectSound3DBuffer[i]); 
                lpShip->lpDirectSound3DBuffer[i] = NULL;
            }
        }
    }
};

/*
 *FUNCTION:   ReleasePlayerLocalData  (CALLBACK)
 *
 *PURPOSE:    Retrieves and releases a player's local data from dplay.
 */
BOOL WINAPI ReleasePlayerLocalDataCB(DPID dpId, DWORD dwPlayerType, LPCDPNAME lpName,
                                     DWORD dwFlags, LPVOID lpContext)
{
    SHIP ship;
    DWORD dwSize = sizeof(SHIP);    
    HRESULT hr;
    
    hr = DPlayGetPlayerData(dpId, &ship, &dwSize, DPGET_LOCAL);
    if (FAILED(hr))
    {
        wsprintf(gDebugBuff, TEXT("Get Player local data failed for id %d\n"), dpId);
        DEBUG_OUT(gDebugBuff);
        goto FAIL;
    }

    // no player data yet
    if (0 == dwSize)
        return TRUE;

    ReleasePlayerLocalSoundData(&ship);

    hr = DPlaySetPlayerData(dpId, &ship,  dwSize, DPSET_LOCAL);
    if (FAILED(hr))
    {
        ShowError(IDS_DPLAY_ERROR_SPLD);
        goto FAIL;
    }

    // success
    return TRUE;
FAIL:
    // we failed
    return FALSE;
}

/*
 *FUNCTION:   ReleaseLocalData
 *
 *PURPOSE:    Releases local data of ALL players.
 */
void ReleaseLocalData(void)
{
     HRESULT hr;

     if (gnProgramState == PS_ACTIVE)
     {
         hr = DPlayEnumPlayers(&(glpdpSD->guidInstance), ReleasePlayerLocalDataCB, NULL, 0);
         if (FAILED(hr))
         {
             ShowError(IDS_DPLAY_ERROR_EP);
         }
     }
};

/*
 * ProcessUserInput
 *
 * Processes any input from the user and updates our ship state
 */
void ProcessUserInput(LPSHIP lpShip)
{
    static dwOldKeys = 0;

    gbUpdate = FALSE;

    // DSOUND: check if the engine was turned off
    if (!(gdwKeys    & (KEY_DOWN | KEY_UP)) && 
        (dwOldKeys & (KEY_DOWN | KEY_UP)))
    {
        gdwKeys |= KEY_ENGINEOFF;

        gControlMsg.byState = (BYTE) gdwKeys;
        // let everyone know that we just turned our engine off
        SendGameMessage((LPGENERICMSG) &gControlMsg, DPID_ALLPLAYERS);
    }

    // update our ship state
    UpdateState(lpShip, gdwKeys);

    // remember current keys for next frame
    dwOldKeys = gdwKeys;
}

/*
 * UpdateState
 *
 * Updates the current state of our ship, given user input
 */
void UpdateState(LPSHIP lpShip, DWORD dwControls)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -