📄 gameproc.c
字号:
wsprintf(gDebugBuff, TEXT("Get Player local data failed for id %d\n"), gOurID);
DEBUG_OUT(gDebugBuff);
goto FAIL;
}
// blt everything in reverse order if we are doing destination transparency
// calculate dwScore string
dwScorebuf[0] = (BYTE)ship.dwScore/100000 + '0';
rem = ship.dwScore % 100000;
dwScorebuf[1] = rem/10000 + '0';
rem = ship.dwScore % 10000;
dwScorebuf[2] = rem/1000 + '0';
rem = ship.dwScore % 1000;
dwScorebuf[3] = rem/100 + '0';
rem = ship.dwScore % 100;
dwScorebuf[4] = rem/10 + '0';
rem = ship.dwScore % 10;
dwScorebuf[5] = rem + '0';
dwScorebuf[6] = '\0';
bltScore(dwScorebuf, 8, 8);
// save ship data
hr = DPlaySetPlayerData(gOurID, &ship, sizeof(ship), DPSET_LOCAL);
if (FAILED(hr))
{
ShowError(IDS_DPLAY_ERROR_SPLD);
goto FAIL;
}
return TRUE;
FAIL:
// failed
return FALSE;
}
/*
* DrawBlock
*
* Renders a block
*/
void DrawBlock( int x, int y )
{
RECT src;
src.top = 0;
src.left = 224;
src.right = src.left + 16;
src.bottom = src.top + 16;
bltObject( x << 4, y << 4, glpNum, &src, DDBLTFAST_SRCCOLORKEY );
}
/*
* DrawShip
*
* Renders a ship
*/
void DrawShip( LPSHIP lpShip )
{
RECT src;
LPDIRECTDRAWSURFACE surf;
src.top = 32 * (lpShip->cFrame / 10 );
src.left = 32 * (lpShip->cFrame % 10 );
src.right = src.left + 32;
src.bottom = src.top + 32;
switch( lpShip->byType )
{
case 0: surf = glpShip0; break;
case 1: surf = glpShip1; break;
case 2: surf = glpShip2; break;
case 3: surf = glpShip3; break;
default: DEBUG_OUT(TEXT("Ship type not specified\n")); return;
}
bltObject((int)lpShip->dPosX, (int)lpShip->dPosY, surf, &src, DDBLTFAST_SRCCOLORKEY );
}
/*
* DrawBullet
*
* Renders a bullet
*/
void DrawBullet( LPSHIP lpShip )
{
RECT src;
src.top = BULLET_Y;
src.left = BULLET_X + (lpShip->byType)*4;
src.right = src.left + 3;
src.bottom = src.top + 3;
bltObject((int)lpShip->dBulletPosX, (int)lpShip->dBulletPosY, glpNum, &src, DDBLTFAST_SRCCOLORKEY );
}
/*
* DrawFragments
*
* Renders the fragments
*/
void DrawFragments( void )
{
int i;
for(i=0; i<64; i++)
{
if( gFrags[i].valid )
{
bltObject((int)gFrags[i].dPosX, (int)gFrags[i].dPosY, gFrags[i].surf,
&(gFrags[i].src), DDBLTFAST_SRCCOLORKEY );
}
}
}
/*
* ReceiveGameMessages
*
* Checks if there are any messages for us and receives them
*/
HRESULT ReceiveMessages( void )
{
DPID idFrom, idTo;
LPVOID lpvMsgBuffer;
DWORD dwMsgBufferSize;
HRESULT hr;
// read all messages in queue
dwMsgBufferSize = gdwReceiveBufferSize;
lpvMsgBuffer = glpvReceiveBuffer;
while (TRUE)
{
// see what's out there
idFrom = 0;
idTo = 0;
hr = DPlayReceive(&idFrom, &idTo, DPRECEIVE_ALL, lpvMsgBuffer, &dwMsgBufferSize);
if (hr == DPERR_BUFFERTOOSMALL)
{
if (lpvMsgBuffer == NULL)
{
lpvMsgBuffer = GlobalAllocPtr(GHND, dwMsgBufferSize);
if (lpvMsgBuffer == NULL)
return (DPERR_NOMEMORY);
glpvReceiveBuffer = lpvMsgBuffer;
gdwReceiveBufferSize = dwMsgBufferSize;
}
else if (dwMsgBufferSize > gdwReceiveBufferSize)
{
lpvMsgBuffer = GlobalReAllocPtr(lpvMsgBuffer, dwMsgBufferSize, 0);
if (lpvMsgBuffer == NULL)
return (DPERR_NOMEMORY);
glpvReceiveBuffer = lpvMsgBuffer;
gdwReceiveBufferSize = dwMsgBufferSize;
}
}
else if ((hr == DP_OK) &&
((dwMsgBufferSize >= sizeof(GENERICMSG)) ||
(dwMsgBufferSize >= sizeof(DPMSG_GENERIC))))
{
if (idFrom == DPID_SYSMSG)
{
DoSystemMessage((LPDPMSG_GENERIC) lpvMsgBuffer, dwMsgBufferSize, idFrom, idTo);
}
else
{
DoApplicationMessage((LPGENERICMSG) lpvMsgBuffer, dwMsgBufferSize, idFrom, idTo);
}
}
else
break;
};
return hr;
}
/*
* DoSystemMessage
*
* Evaluates system messages and performs appropriate actions
*/
void DoSystemMessage( LPDPMSG_GENERIC lpMsg, DWORD dwMsgSize, DPID idFrom, DPID idTo )
{
switch( lpMsg->dwType)
{
case DPSYS_CREATEPLAYERORGROUP:
{
LPDPMSG_CREATEPLAYERORGROUP lpAddMsg = (LPDPMSG_CREATEPLAYERORGROUP) lpMsg;
if( gbIsHost)
{
gHostMsg.Blocks = gBlocks;
SendGameMessage((LPGENERICMSG) &gHostMsg, lpAddMsg->dpId);
}
}
break;
case DPSYS_DESTROYPLAYERORGROUP:
{
LPSHIP lpShip;
LPDPMSG_DESTROYPLAYERORGROUP lpDestroyMsg = (LPDPMSG_DESTROYPLAYERORGROUP) lpMsg;
if ((sizeof(SHIP) != lpDestroyMsg->dwLocalDataSize) ||
(NULL == lpDestroyMsg->lpLocalData))
break;
lpShip = lpDestroyMsg->lpLocalData;
ReleasePlayerLocalSoundData(lpShip);
}
break;
case DPSYS_HOST:
{
gbIsHost = TRUE;
UpdateTitle();
}
break;
case DPSYS_SESSIONLOST:
// inform user that session was lost
ShowError(IDS_DPLAY_ERROR_SL);
gbSessionLost = TRUE;
break;
}
}
/*
* DoApplicationMessage
*
* Evaluates an application message and performs appropriate actions
*/
void DoApplicationMessage( LPGENERICMSG lpMsg, DWORD dwMsgSize, DPID idFrom, DPID idTo )
{
HRESULT hr;
switch( lpMsg->byType )
{
case MSG_HOST:
{
LPHOSTMSG lpHost;
if( !gbIsHost )
{
lpHost = (LPHOSTMSG) lpMsg;
// receive the field layout
gBlocks = lpHost->Blocks;
// have host initializtion at this point
gbHaveHostInit = TRUE;
// start updating screen
gbIsActive = TRUE;
}
}
break;
case MSG_BLOCKHIT:
{
LPBLOCKHITMSG lpBlockHit;
lpBlockHit = (LPBLOCKHITMSG) lpMsg;
gBlocks.bits[lpBlockHit->byRow][lpBlockHit->byCol] &= ~lpBlockHit->byMask;
}
break;
case MSG_ADDBLOCK:
{
LPADDBLOCKMSG lpAddBlock;
lpAddBlock = (LPADDBLOCKMSG) lpMsg;
setBlock( lpAddBlock->byX, lpAddBlock->byY);
}
break;
case MSG_SHIPHIT:
{
LPSHIPHITMSG lpShipHit = (LPSHIPHITMSG) lpMsg;
SHIP ship;
DWORD dwSize;
dwSize = sizeof(SHIP);
// get player local data
hr = DPlayGetPlayerData(lpShipHit->Id, &ship, &dwSize, DPGET_LOCAL);
if (FAILED(hr))
return;
// no player data yet
if (0 == dwSize)
return;
if (!ship.bIgnore)
{
// explode the ship on our screen
DestroyShip(&ship);
// turn it off
ship.bEnable = FALSE;
ship.bBulletEnable = FALSE;
// if it is us
if (lpShipHit->Id == gOurID)
{
// set our hide time-out
ship.iCountDown = HIDE_TIMEOUT;
ship.dwLastTick = timeGetTime();
// let the world know that we are dead
gShipHitMsg.Id = gOurID;
SendGameMessage((LPGENERICMSG) &gShipHitMsg, DPID_ALLPLAYERS);
}
}
// update player local data
DPlaySetPlayerData(lpShipHit->Id, &ship, sizeof(ship), DPSET_LOCAL);
}
break;
case MSG_CONTROL:
{
LPCONTROLMSG lpControlMsg;
SHIP ship;
DWORD dwSize;
lpControlMsg = (LPCONTROLMSG) lpMsg;
dwSize = sizeof(SHIP);
// get player local data
hr = DPlayGetPlayerData(idFrom, &ship, &dwSize, DPGET_LOCAL);
if (FAILED(hr))
return;
// no player data yet
if (0 == dwSize)
return;
// update its State
UpdateState(&ship, (DWORD)lpControlMsg->byState);
// save it back
DPlaySetPlayerData(idFrom, &ship, dwSize, DPSET_LOCAL);
}
break;
case MSG_SYNC:
{
LPSYNCMSG lpSyncMsg;
SHIP ship;
DWORD dwSize;
lpSyncMsg = (LPSYNCMSG) lpMsg;
dwSize = sizeof(SHIP);
// get player local data
hr = DPlayGetPlayerData(idFrom, &ship, &dwSize, DPGET_LOCAL);
if (FAILED(hr))
return;
// we are seeing this player for the first time
// so do the initialization
if (0 == dwSize)
{
ZeroMemory(&ship, sizeof(ship));
// initialize sound buffers
InitPlayerLocalSoundData(&ship);
ship.byType = lpSyncMsg->byShipType;
ship.dPosX = lpSyncMsg->dPosX;
ship.dPosY = lpSyncMsg->dPosY;
ship.cFrame = lpSyncMsg->cFrame;
ship.dwLastTick = timeGetTime();
ship.bEnable = TRUE;
}
if (ship.bEnable)
{
// head towards rendezvous location (accelerate/decelerate as necessary)
ship.dVelX = (lpSyncMsg->dPosX - ship.dPosX)/1000;
ship.dVelY = (lpSyncMsg->dPosY - ship.dPosY)/1000;
ship.cFrame = lpSyncMsg->cFrame;
}
else if (!ship.bIgnore)
// Ship is alive, but we just don't know it.
// So, display it at the rendezvous location.
{
ship.dPosX = lpSyncMsg->dPosX;
ship.dPosY = lpSyncMsg->dPosY;
ship.cFrame = lpSyncMsg->cFrame;
ship.dwLastTick = timeGetTime();
ship.bEnable = TRUE;
}
// save it back
DPlaySetPlayerData(idFrom, &ship, sizeof(ship), DPSET_LOCAL);
}
break;
default:
{
wsprintf(gDebugBuff, TEXT("Unknown message type %d\n"), lpMsg->byType);
DEBUG_OUT( gDebugBuff );
}
break;
}
}
/*
* SendGameMessage
*
* Sends a message to specified player(s)
*/
void SendGameMessage( LPGENERICMSG lpMsg, DPID idTo )
{
int nBytes;
DWORD dwFlags = 0;
if (gbSessionLost)
{
// no sends when we are not in the session
return;
}
switch( lpMsg->byType )
{
case MSG_HOST:
nBytes = sizeof( HOSTMSG );
dwFlags = DPSEND_GUARANTEED;
break;
case MSG_BLOCKHIT:
nBytes = sizeof( BLOCKHITMSG );
break;
case MSG_SHIPHIT:
nBytes = sizeof( SHIPHITMSG );
break;
case MSG_ADDBLOCK:
nBytes = sizeof( ADDBLOCKMSG );
break;
case MSG_CONTROL:
nBytes = sizeof( CONTROLMSG );
break;
case MSG_SYNC:
nBytes = sizeof( SYNCMSG );
break;
default:
return;
}
if (gbReliable)
{
dwFlags = DPSEND_GUARANTEED;
}
// Send the message to the relevant player(s)
DPlaySend(gOurID, idTo, dwFlags, (LPVOID)lpMsg, nBytes);
}
/*
* CleanupComm
*
* Cleans up communication stuff
*/
void CleanupComm(void)
{
HRESULT hr;
//free up all the local sound buffers
ReleaseLocalData();
// free the receive buffer
if (glpvReceiveBuffer)
{
GlobalFreePtr(glpvReceiveBuffer);
glpvReceiveBuffer = NULL;
}
// delete our player
if( gOurID )
{
hr = DPlayDestroyPlayer(gOurID);
if (FAILED(hr))
{
ShowError(IDS_DPLAY_ERROR_DP);
}
gOurID = 0;
}
// cleanup directplay objects
hr = DPlayClose();
hr = DPlayRelease();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -