home *** CD-ROM | disk | FTP | other *** search
- /*==========================================================================
- *
- * Copyright (C) 1995-1996 Microsoft Corporation. All Rights Reserved.
- *
- * File: duel.c
- * Content: Multi-player duel
- *
- *
- ***************************************************************************/
- #include "duel.h"
-
- // Duel 09438c20-e06a-11ce-8681-00aa006c5d58
- DEFINE_GUID(DUEL_GUID,0x09438c20,0xe06a,0x11CE,0x86,0x81,0x00,0xaa,0x00,0x6c,0x5d,0x58);
-
- LPDIRECTPLAY lpIDC=NULL; // DirectPlay Object
- DPID dcoID=0; // our DirectPlay ID
- LPGUID g_lpGuid;
- HANDLE dphEvent = NULL;
-
- LPDIRECTDRAWSURFACE lpFrontBuffer;
- LPDIRECTDRAWSURFACE lpBackBuffer;
- LPDIRECTDRAWSURFACE lpShip0;
- LPDIRECTDRAWSURFACE lpShip1;
- LPDIRECTDRAWSURFACE lpShip2;
- LPDIRECTDRAWSURFACE lpShip3;
- LPDIRECTDRAWSURFACE lpNum;
- LPDIRECTDRAW lpDD;
- LPDIRECTDRAWPALETTE lpArtPalette;
- LPDIRECTDRAWPALETTE lpSplashPalette;
- int showDelay = 0;
- HWND hWndMain;
- BOOL bShowFrameCount=TRUE;
- BOOL bIsActive;
- DWORD dwFrameCount;
- DWORD dwFrameTime;
- DWORD dwFrames;
- DWORD dwFramesLast;
- BOOL bUseEmulation;
- RGBQUAD SPalette[256];
- int ProgramState;
- int level;
- int restCount;
- DWORD dwFillColor;
- BOOL IsHost;
- BOOL HaveHostInit;
- BYTE WhoIAm;
- #ifdef DEBUG
- char DebugBuf[256];
- BOOL bHELBlt = FALSE;
- #endif
-
- BLOCKS Blocks;
- GLOBALSHIP Ships[16];
- DWORD Keys;
- BYTE CommBuff[256];
- int CountDown=0;
- FRAG Frags[64];
-
- /*
- * MainWndproc
- *
- * Callback for all Windows messages
- */
- long FAR PASCAL MainWndproc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
- {
- PAINTSTRUCT ps;
- HDC hdc;
-
- switch( message )
- {
- case WM_ACTIVATEAPP:
- bIsActive = (BOOL) wParam;
- break;
-
- case WM_CREATE:
- break;
-
- case WM_SETCURSOR:
- SetCursor(NULL);
- return TRUE;
-
- case WM_KEYDOWN:
- switch( wParam )
- {
- case VK_NUMPAD5:
- Keys |= KEY_STOP;
- break;
- case VK_DOWN:
- case VK_NUMPAD2:
- Keys |= KEY_DOWN;
- break;
- case VK_LEFT:
- case VK_NUMPAD4:
- Keys |= KEY_LEFT;
- break;
- case VK_RIGHT:
- case VK_NUMPAD6:
- Keys |= KEY_RIGHT;
- break;
- case VK_UP:
- case VK_NUMPAD8:
- Keys |= KEY_UP;
- break;
- case VK_SPACE:
- Keys |= KEY_FIRE;
- break;
- case VK_F5:
- bShowFrameCount = !bShowFrameCount;
- if( bShowFrameCount )
- {
- dwFrameCount = 0;
- dwFrameTime = timeGetTime();
- }
- break;
- case VK_RETURN:
- if( ProgramState == PS_SPLASH )
- {
- lpDD->lpVtbl->FlipToGDISurface( lpDD );
- if ( RemoteCreate(DUEL_GUID, "Duel", "Ship") )
- {
- ProgramState = PS_REST;
- // set the palette
- if( !IsHost )
- {
- SendGameMessage(MSG_HEREIAM, 0, 0, 0, 0);
- HaveHostInit = FALSE;
- }
- else
- {
- HaveHostInit = TRUE;
- WhoIAm = 0;
- InitGame();
- }
- }
- }
- break;
- case VK_ESCAPE:
- case VK_F12:
- PostMessage( hWnd, WM_CLOSE, 0, 0 );
- return 0;
- }
- break;
-
- case WM_KEYUP:
- switch( wParam )
- {
- case VK_NUMPAD5:
- Keys &= ~KEY_STOP;
- break;
- case VK_DOWN:
- case VK_NUMPAD2:
- Keys &= ~KEY_DOWN;
- break;
- case VK_LEFT:
- case VK_NUMPAD4:
- Keys &= ~KEY_LEFT;
- break;
- case VK_RIGHT:
- case VK_NUMPAD6:
- Keys &= ~KEY_RIGHT;
- break;
- case VK_UP:
- case VK_NUMPAD8:
- Keys &= ~KEY_UP;
- break;
- case VK_SPACE:
- Keys &= ~KEY_FIRE;
- break;
- }
- break;
-
- case WM_ERASEBKGND:
- return 1;
-
- case WM_PAINT:
- hdc = BeginPaint( hWnd, &ps );
- EndPaint( hWnd, &ps );
- return 1;
-
- case WM_DESTROY:
- DestroyGame();
- PostQuitMessage( 0 );
- break;
-
- default:
- break;
- }
- return DefWindowProc(hWnd, message, wParam, lParam);
-
- } /* MainWndproc */
-
- /*
- * initApplication
- *
- * Do that Windows initialization stuff...
- */
- static BOOL initApplication( HINSTANCE 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, "DUEL_ICON");
- wc.hCursor = LoadCursor( NULL, IDC_ARROW );
- wc.hbrBackground = GetStockObject( BLACK_BRUSH );
- wc.lpszMenuName = NULL;
- wc.lpszClassName = "DuelClass";
- rc = RegisterClass( &wc );
- if( !rc )
- {
- return FALSE;
- }
-
- hWndMain = CreateWindowEx(0, // WS_EX_TOPMOST,
- "DuelClass",
- "Duel",
- WS_VISIBLE | // so we don't have to call ShowWindow
- WS_POPUP | // non-app window POPUP
- WS_SYSMENU, // so we get an icon in the tray
- 0,
- 0,
- GetSystemMetrics(SM_CXSCREEN),
- GetSystemMetrics(SM_CYSCREEN),
- NULL,
- NULL,
- hInstance,
- NULL );
-
- if( !hWndMain )
- {
- return FALSE;
- }
-
- UpdateWindow( hWndMain );
-
- return TRUE;
-
- } /* initApplication */
-
- /*
- * WinMain
- */
- int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
- int nCmdShow )
- {
- MSG msg;
-
- if( lpCmdLine[0] == '-' )
- {
- bUseEmulation = TRUE;
- }
-
- if( !initApplication(hInstance, nCmdShow) )
- {
- return FALSE;
- }
-
- if( !InitializeGame() )
- {
- DestroyWindow( hWndMain );
- return FALSE;
- }
-
- dwFrameTime = timeGetTime();
-
- while( 1 )
- {
- if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
- {
- if( !GetMessage( &msg, NULL, 0, 0 ) )
- {
- return msg.wParam;
- }
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- else
- {
- ReceiveGameMessages();
- if( bIsActive )
- {
- UpdateFrame();
- }
- }
- }
- } /* WinMain */
-
-
- void DestroyGame( void )
- {
- if( dcoID != 0 )
- {
- lpIDC->lpVtbl->DestroyPlayer(lpIDC, dcoID);
- }
- }
-
- BOOL InitializeGame( void )
- {
- DDCAPS ddcaps;
- HRESULT ddrval;
- DDSURFACEDESC ddsd;
- DDSCAPS ddscaps;
-
- if( bUseEmulation )
- ddrval = DirectDrawCreate( (LPVOID) DDCREATE_EMULATIONONLY, &lpDD, NULL );
- else
- ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
-
- if( ddrval != DD_OK )
- return CleanupAndExit(1);
-
- ddrval = lpDD->lpVtbl->SetCooperativeLevel( lpDD, hWndMain,
- DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
- if( ddrval != DD_OK )
- return CleanupAndExit(2);
-
- // set the mode to 640 by 480 by 8
- #ifdef DEBUG
- if( GetProfileInt( "Duel", "force_16_bit", 0) )
- {
- ddrval = lpDD->lpVtbl->SetDisplayMode( lpDD, 640, 480, 16 );
- }
- else
- #endif
- {
- ddrval = lpDD->lpVtbl->SetDisplayMode( lpDD, 640, 480, 8 );
- }
- if( ddrval != DD_OK )
- return CleanupAndExit(3);
-
- // check the color key hardware capabilities
- ddcaps.dwSize = sizeof( ddcaps );
-
- #ifdef DEBUG
- bHELBlt = GetProfileInt( "Duel", "force_HEL_blt", bHELBlt );
- #endif
-
- // Create surfaces
- memset( &ddsd, 0, sizeof( ddsd ) );
- ddsd.dwSize = sizeof( ddsd );
- ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
- DDSCAPS_FLIP |
- DDSCAPS_COMPLEX;
- ddsd.dwBackBufferCount = 1;
- ddrval = lpDD->lpVtbl->CreateSurface( lpDD, &ddsd, &lpFrontBuffer, NULL );
- if( ddrval != DD_OK )
- return CleanupAndExit(4);
-
- // get a pointer to the back buffer
- ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
- ddrval = lpFrontBuffer->lpVtbl->GetAttachedSurface(
- lpFrontBuffer,
- &ddscaps,
- &lpBackBuffer );
- if( ddrval != DD_OK )
- return CleanupAndExit(5);
-
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- #ifdef DEBUG
- if( bHELBlt )
- ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
- #endif
-
- ddsd.dwWidth = 320;
- ddsd.dwHeight = 128;
- ddrval = lpDD->lpVtbl->CreateSurface( lpDD, &ddsd, &lpShip0, NULL );
- if( ddrval != DD_OK )
- return CleanupAndExit(6);
-
- ddsd.dwWidth = 320;
- ddsd.dwHeight = 128;
- ddrval = lpDD->lpVtbl->CreateSurface( lpDD, &ddsd, &lpShip1, NULL );
- if( ddrval != DD_OK )
- return CleanupAndExit(7);
-
- ddsd.dwWidth = 320;
- ddsd.dwHeight = 128;
- ddrval = lpDD->lpVtbl->CreateSurface( lpDD, &ddsd, &lpShip2, NULL );
- if( ddrval != DD_OK )
- return CleanupAndExit(8);
-
- ddsd.dwWidth = 320;
- ddsd.dwHeight = 128;
- ddrval = lpDD->lpVtbl->CreateSurface( lpDD, &ddsd, &lpShip3, NULL );
- if( ddrval != DD_OK )
- return CleanupAndExit(9);
-
- ddsd.dwHeight = 16;
- ddrval = lpDD->lpVtbl->CreateSurface( lpDD, &ddsd, &lpNum, NULL );
- if( ddrval != DD_OK )
- return CleanupAndExit(10);
-
- if( !RestoreSurfaces() )
- return CleanupAndExit(11);
-
- Keys = 0;
- ProgramState = PS_SPLASH;
- return TRUE;
- }
-
- BOOL CleanupAndExit( int err)
- {
- char buf[256];
-
- #ifdef DEBUG
- wsprintf(DebugBuf, "___CleanupAndExit err = %d\n", err );
- OutputDebugString( DebugBuf );
- #endif
-
- if( lpShip0 != NULL )
- lpShip0->lpVtbl->Release( lpShip0 );
-
- if( lpShip1 != NULL )
- lpShip1->lpVtbl->Release( lpShip1 );
-
- if( lpShip2 != NULL )
- lpShip2->lpVtbl->Release( lpShip2 );
-
- if( lpShip3 != NULL )
- lpShip3->lpVtbl->Release( lpShip3 );
-
- if( lpNum != NULL )
- lpNum->lpVtbl->Release( lpNum );
-
- if( lpFrontBuffer != NULL )
- lpFrontBuffer->lpVtbl->Release( lpFrontBuffer );
-
- if( lpArtPalette != NULL )
- lpArtPalette->lpVtbl->Release( lpArtPalette );
-
- if( lpSplashPalette != NULL )
- lpSplashPalette->lpVtbl->Release( lpSplashPalette );
-
- if( lpDD != NULL )
- lpDD->lpVtbl->Release( lpDD );
-
- wsprintf(buf, "Game could not start (%d)", err);
- MessageBox( hWndMain, buf, "ERROR", MB_OK );
- return FALSE;
- }
-
- void bltSplash( LPRECT rc)
- {
- HRESULT ddrval;
- HBITMAP hbm;
-
- if( ( lpFrontBuffer == NULL ) ||
- ( lpSplashPalette == NULL ) ||
- ( lpBackBuffer == NULL ) )
- {
- return;
- }
-
- // set the palette before loading the splash screen
- lpFrontBuffer->lpVtbl->SetPalette( lpFrontBuffer, lpSplashPalette );
-
- hbm = (HBITMAP)LoadImage( GetModuleHandle( NULL ), "SPLASH", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
- if ( NULL == hbm )
- return;
-
- // if the surface is lost, DDCopyBitmap will fail and the surface will
- // be restored below.
- ddrval = DDCopyBitmap( lpBackBuffer, hbm, 0, 0, 0, 0 );
-
- DeleteObject( hbm );
-
- while( 1 )
- {
- if( rc != NULL )
- {
- ddrval = lpFrontBuffer->lpVtbl->BltFast( lpFrontBuffer,
- rc->left, rc->top, lpBackBuffer, rc, 0);
- }
- else
- {
- ddrval = lpFrontBuffer->lpVtbl->BltFast( lpFrontBuffer,
- 0, 0, lpBackBuffer, NULL, 0);
- }
- if( ddrval == DD_OK )
- return;
- if( ddrval == DDERR_SURFACELOST )
- if( !RestoreSurfaces() )
- return;
- if( ddrval != DDERR_WASSTILLDRAWING )
- return;
- }
- }
-
- void UpdateFrame( void )
- {
- int i;
-
- switch( ProgramState )
- {
- case PS_SPLASH:
- // display the splash screen
- bltSplash(NULL);
- return;
- case PS_ACTIVE:
- ReadKey();
- for(i=0; i<16; i++)
- UpdatePosition(&Ships[i]);
- for(i=0; i<64; i++)
- UpdateFragment(i);
- SendGameMessage(MSG_UPDATE, 0, 0, 0, 0);
- DrawScreen();
- return;
- case PS_REST:
- if( HaveHostInit )
- {
- lpFrontBuffer->lpVtbl->SetPalette( lpFrontBuffer, lpArtPalette );
- ProgramState = PS_ACTIVE;
- }
- break;
- }
- }
-
- void ReadKey( void )
- {
- if( Keys & KEY_LEFT )
- {
- Ships[WhoIAm].frame -= 0.5;
- if( Ships[WhoIAm].frame < 0.0 )
- Ships[WhoIAm].frame += MAX_SHIP_FRAME;
- }
- if( Keys & KEY_RIGHT )
- {
- Ships[WhoIAm].frame += 0.5;
- if( Ships[WhoIAm].frame >= MAX_SHIP_FRAME )
- Ships[WhoIAm].frame -= MAX_SHIP_FRAME;
- }
- if( Keys & KEY_UP )
- {
- Ships[WhoIAm].velx += Dirx[(int)Ships[WhoIAm].frame] * 10.0 / 1000.0;
- Ships[WhoIAm].vely += Diry[(int)Ships[WhoIAm].frame] * 10.0 / 1000.0;
- }
- if( Keys & KEY_DOWN )
- {
- Ships[WhoIAm].velx -= Dirx[(int)Ships[WhoIAm].frame] * 10.0 / 1000.0;
- Ships[WhoIAm].vely -= Diry[(int)Ships[WhoIAm].frame] * 10.0 / 1000.0;
- }
- if( Keys & KEY_STOP )
- {
- Ships[WhoIAm].velx = 0.0;
- Ships[WhoIAm].vely = 0.0;
- }
- if( !Ships[WhoIAm].benable && Ships[WhoIAm].enable )
- {
- if( Keys & KEY_FIRE )
- {
- // launch a new bullet
- Ships[WhoIAm].bposx = Dirx[(int)Ships[WhoIAm].frame]*6.0 + 16.0 + Ships[WhoIAm].posx;
- Ships[WhoIAm].bposy = Diry[(int)Ships[WhoIAm].frame]*6.0 + 16.0 + Ships[WhoIAm].posy;
- Ships[WhoIAm].bvelx = Dirx[(int)Ships[WhoIAm].frame]*500.0/1000.0;
- Ships[WhoIAm].bvely = Diry[(int)Ships[WhoIAm].frame]*500.0/1000.0;
- Ships[WhoIAm].benable = TRUE;
- Ships[WhoIAm].bframe = 0;
- }
- }
- }
-
- void UpdatePosition( LPGLOBALSHIP ship )
- {
- int x,y,j;
- BYTE mask, col, row, oldxCell, oldyCell, newxCell, newyCell;
- double thisTick, totalTick, xtick, ytick;
- DWORD TickCnt;
- DWORD tickDiff;
- LPGLOBALSHIP target;
-
- TickCnt = GetTickCount();
- tickDiff = TickCnt - ship->lastTick;
- ship->lastTick = TickCnt;
-
- if( ship == &(Ships[WhoIAm]) && !ship->enable)
- {
- CountDown -= tickDiff;
- if( CountDown < 0 )
- {
- Ships[WhoIAm].enable = TRUE;
- }
- }
-
- if( !ship->enable )
- return;
-
- if( ( (TickCnt - ship->timeStamp ) > 2000 ) &&
- ( ship != &(Ships[WhoIAm]) ) )
- {
- ship->enable = FALSE;
- return;
- }
-
-
- // incrementally update the position of the ship
- // find out the number of ticks needed to move 8 pixels
- if( ship->velx != 0.0 )
- xtick = 8.0/ship->velx;
- else
- xtick = 999999.0;
-
- if( ship->vely != 0.0 )
- ytick = 8.0/ship->vely;
- else
- ytick = 999999.0;
-
- if( xtick < 0.0 )
- xtick = -xtick;
- if( ytick < 0.0 )
- ytick = -ytick;
-
- if( xtick < ytick )
- thisTick = xtick;
- else
- thisTick = ytick;
-
- if( thisTick > tickDiff )
- thisTick = tickDiff;
-
- for( totalTick = 0.0; totalTick < tickDiff; )
- {
- totalTick += tickDiff;
- oldxCell = (int)(ship->posx+16.0) >> 4;
- oldyCell = (int)(ship->posy+16.0) >> 4;
- ship->posx += ship->velx * thisTick;
- ship->posy += ship->vely * thisTick;
- newxCell = (int)(ship->posx+16.0) >> 4;
- newyCell = (int)(ship->posy+16.0) >> 4;
- if(oldxCell != newxCell)
- {
- if( IsHit( newxCell, newyCell ) )
- {
- if( ship->velx > 0.0 )
- ship->posx = (oldxCell << 4) + 15 - 16;
- else
- ship->posx = (oldxCell << 4) - 16;
- ship->velx = -ship->velx*0.9;
- newxCell = oldxCell;
- }
- }
- if(oldyCell != newyCell)
- {
- if( IsHit( newxCell, newyCell ) )
- {
- if( ship->vely > 0.0 )
- ship->posy = (oldyCell << 4) + 15 - 16;
- else
- ship->posy = (oldyCell << 4) - 16;
- ship->vely = -ship->vely*0.9;
- }
- }
- if( ship->posx > MAX_SHIP_X )
- {
- ship->posx = MAX_SHIP_X;
- ship->velx = -ship->velx*0.9;
- }
- else if ( ship->posx < 0 )
- {
- ship->posx =0;
- ship->velx = -ship->velx*0.9;
- }
- if( ship->posy > MAX_SHIP_Y )
- {
- ship->posy = MAX_SHIP_Y;
- ship->vely = -ship->vely*0.9;
- }
- else if ( ship->posy < 0 )
- {
- ship->posy =0;
- ship->vely = -ship->vely*0.9;
- }
- }
-
- if( !ship->benable )
- return;
-
- // update the active bullet
- ship->bframe += tickDiff;
- if( ship->bframe >= MAX_BULLET_FRAME )
- {
- ship->benable = FALSE;
- return;
- }
-
- if( ship->bvelx != 0.0 )
- xtick = 8.0/ship->bvelx;
- else
- xtick = 999999.0;
-
- if( ship->bvely != 0.0 )
- ytick = 8.0/ship->bvely;
- else
- ytick = 999999.0;
-
- if( xtick < 0.0 )
- xtick = -xtick;
- if( ytick < 0.0 )
- ytick = -ytick;
-
- if( xtick < ytick )
- thisTick = xtick;
- else
- thisTick = ytick;
-
- if( thisTick > tickDiff )
- thisTick = tickDiff;
-
- for( totalTick = 0.0; totalTick < tickDiff; )
- {
- totalTick += thisTick;
-
- ship->bposx += ship->bvelx * thisTick;
- ship->bposy += ship->bvely * thisTick;
-
- // see if it hit a ship
- for(j=0; j<16; j++)
- {
- target = &(Ships[j]);
- if( ( target == ship ) || !target->enable )
- continue;
- if( (ship->bposx > target->posx) &&
- (ship->bposx < (target->posx + 32.0) ) &&
- (ship->bposy > target->posy) &&
- (ship->bposy < (target->posy + 32.0) ) )
- {
- SendGameMessage(MSG_SHIPHIT, 0, (BYTE)j, 0, 0);
- DestroyShip( j );
- target->enable = FALSE;
- ship->benable = FALSE;
- ship->score += 1000;
- return;
- }
- }
-
- if( ship->bposx > MAX_BULLET_X )
- {
- ship->bposx = MAX_BULLET_X;
- ship->bvelx = -ship->bvelx*0.9;
- }
- else if ( ship->bposx < 0 )
- {
- ship->bposx =0;
- ship->bvelx = -ship->bvelx*0.9;
- }
- if( ship->bposy > MAX_BULLET_Y )
- {
- ship->bposy = MAX_BULLET_Y;
- ship->bvely = -ship->bvely*0.9;
- }
- else if ( ship->bposy < 0 )
- {
- ship->bposy =0;
- ship->bvely = -ship->bvely*0.9;
- }
-
- // check to see if it hit anything
- x = (int)(ship->bposx + 0.5) + 1;
- y = (int)(ship->bposy + 0.5) + 1;
-
- row = y >> 4;
- col = x >> 4;
- mask = 1 << (col & 0x7);
- col = col >> 3;
- if( Blocks.bits[row][col] & mask )
- {
- // scored a block hit
- SendGameMessage(MSG_BLOCKHIT, 0, row, col, mask);
- Blocks.bits[row][col] &= ~mask;
- ship->score += 10;
- ship->benable = FALSE;
- return;
- }
- }
- }
-
- BOOL IsHit( int x, int y )
- {
- int col, mask;
-
- // outside screen boundaries?
- if( (x < 0) || (y < 0) || (x >= 40) || (y >= 30) )
- return TRUE;
-
- // look at the block bits
- mask = 1 << (x & 0x7);
- col = x >> 3;
- if( Blocks.bits[y][col] & mask )
- return TRUE;
- else
- return FALSE;
- }
-
- void DrawScreen( void )
- {
- int i;
- BYTE mask, col;
- int x, y;
-
- EraseScreen();
-
- for(i=0; i<16; i++)
- {
- if( Ships[i].benable )
- {
- DrawBullet( i );
- }
- }
-
- for(i=0; i<16; i++)
- {
- if( Ships[i].enable )
- {
- DrawShip( i );
- }
- }
-
- for( y=0; y<30; y++)
- {
- for( x=0; x<40; x++)
- {
- mask = 1 << (x & 0x7);
- col = x >> 3;
- if( Blocks.bits[y][col] & mask )
- DrawBlock( x, y );
- }
- }
-
- DrawScore();
-
- DrawFragments();
- if( bShowFrameCount )
- DisplayFrameRate();
-
- FlipScreen();
- }
-
- void DrawScore( void )
- {
- char scorebuf[11];
- int rem;
-
- // blt everything in reverse order if we are doing destination transparency
- // calculate score string
- scorebuf[0] = Ships[WhoIAm].score/100000 + '0';
- rem = Ships[WhoIAm].score % 100000;
- scorebuf[1] = rem/10000 + '0';
- rem = Ships[WhoIAm].score % 10000;
- scorebuf[2] = rem/1000 + '0';
- rem = Ships[WhoIAm].score % 1000;
- scorebuf[3] = rem/100 + '0';
- rem = Ships[WhoIAm].score % 100;
- scorebuf[4] = rem/10 + '0';
- rem = Ships[WhoIAm].score % 10;
- scorebuf[5] = rem + '0';
- scorebuf[6] = '\0';
-
- bltScore(scorebuf, 8, 8);
- }
-
- 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, lpNum, &src, DDBLTFAST_SRCCOLORKEY );
- }
-
- void DrawShip( int i )
- {
- RECT src;
- LPDIRECTDRAWSURFACE surf;
-
- src.top = 32 * ( (int)Ships[i].frame / 10 );
- src.left = 32 * ( (int)Ships[i].frame % 10 );
- src.right = src.left + 32;
- src.bottom = src.top + 32;
- switch( i % 4 )
- {
- case 0: surf = lpShip0; break;
- case 1: surf = lpShip1; break;
- case 2: surf = lpShip2; break;
- case 3: surf = lpShip3; break;
- }
- bltObject( (int)Ships[i].posx, (int)Ships[i].posy, surf, &src, DDBLTFAST_SRCCOLORKEY );
- }
-
- void DrawBullet( int i )
- {
- RECT src;
-
- src.top = BULLET_Y;
- src.left = BULLET_X + (i%4)*4;
- src.right = src.left + 3;
- src.bottom = src.top + 3;
- bltObject( (int)Ships[i].bposx, (int)Ships[i].bposy, lpNum, &src, DDBLTFAST_SRCCOLORKEY );
- }
-
- void bltScore( char *num, int x, int y )
- {
- char *c;
- RECT src;
- int i;
-
- for(c=num; *c != '\0'; c++)
- {
- i = *c - '0';
- src.left = i*16;
- src.top = 0;
- src.right = src.left + 16;
- src.bottom = src.top + 16;
- bltObject( x, y, lpNum, &src, DDBLTFAST_SRCCOLORKEY );
- x += 16;
- }
- }
-
- void bltObject( int x, int y, LPDIRECTDRAWSURFACE surf, LPRECT src, DWORD flags )
- {
- HRESULT ddrval;
-
- while( 1 )
- {
- ddrval = lpBackBuffer->lpVtbl->BltFast( lpBackBuffer, x, y, surf, src, flags );
- if( ddrval == DD_OK )
- return;
- if( ddrval == DDERR_SURFACELOST )
- if( !RestoreSurfaces() )
- return;
- if( ddrval != DDERR_WASSTILLDRAWING )
- return;
- }
- }
-
- void EraseScreen( void )
- {
- DDBLTFX ddbltfx;
- HRESULT ddrval;
-
- // Erase the background
- ddbltfx.dwSize = sizeof( ddbltfx );
- ddbltfx.dwFillColor = dwFillColor;
- while( 1 )
- {
- ddrval = lpBackBuffer->lpVtbl->Blt( lpBackBuffer, NULL, NULL,
- NULL, DDBLT_COLORFILL, &ddbltfx );
-
- if( ddrval == DD_OK )
- {
- break;
- }
- if( ddrval == DDERR_SURFACELOST )
- {
- if( !RestoreSurfaces() )
- return;
- }
- if( ddrval != DDERR_WASSTILLDRAWING )
- {
- return;
- }
- }
- }
-
- void FlipScreen( void )
- {
- HRESULT ddrval;
-
- // Flip the surfaces
- while( 1 )
- {
- ddrval = lpFrontBuffer->lpVtbl->Flip( lpFrontBuffer, NULL, 0 );
- if( ddrval == DD_OK )
- {
- break;
- }
- if( ddrval == DDERR_SURFACELOST )
- {
- if( !RestoreSurfaces() )
- {
- return;
- }
- }
- if( ddrval != DDERR_WASSTILLDRAWING )
- {
- break;
- }
- }
- }
-
- void DisplayFrameRate( void )
- {
- DWORD time2;
- char buff[256];
-
- dwFrameCount++;
- time2 = timeGetTime() - dwFrameTime;
- if( time2 > 1000 )
- {
- dwFrames = (dwFrameCount*1000)/time2;
- dwFrameTime = timeGetTime();
- dwFrameCount = 0;
- }
- if( dwFrames == 0 )
- {
- return;
- }
-
- if (dwFrames != dwFramesLast)
- {
- dwFramesLast = dwFrames;
- }
-
- if( dwFrames > 99 )
- {
- dwFrames = 99;
- }
- buff[0] = (char)((dwFrames / 10) + '0');
- buff[1] = (char)((dwFrames % 10) + '0');
- buff[2] = '\0';
- bltScore(buff, 295, 10);
- }
-
- void InitGame(void)
- {
- int i, x, y;
-
- // clear all blocks
- for(x=0; x<5; x++)
- for(y=0; y<30; y++)
- Blocks.bits[y][x] = 0;
-
- // set random blocks
- for(i=0; i<400; i++)
- {
- x = randInt(0, 40);
- y = randInt(0, 30);
- if( !setBlock(x, y) )
- i--;
- }
-
- // initialize the host ship
- initShip(&(Ships[0]));
- }
-
- BOOL setBlock( int x, int y )
- {
- BYTE mask, col;
-
- mask = 1 << (x & 0x7);
- col = x >> 3;
-
- // is Block already set?
- if( Blocks.bits[y][col] & mask )
- return FALSE;
-
- // set the block and return success
- Blocks.bits[y][col] |= mask;
- return TRUE;
- }
-
- void initShip( LPGLOBALSHIP ship )
- {
- int i;
-
- ship->velx = ship->vely = 0.0;
-
- ship->enable = TRUE;
- ship->posx = HomeX[WhoIAm];
- ship->posy = HomeY[WhoIAm];
- ship->frame = HomeFrame[WhoIAm];
- ship->benable = FALSE;
- ship->timeStamp = GetTickCount();
- ship->lastTick = ship->timeStamp;
-
- // no ship fragments
- for(i=0; i<64; i++)
- Frags[i].valid = FALSE;
- }
-
- BOOL RestoreSurfaces( void )
- {
- HRESULT ddrval;
- HBITMAP hbm;
-
- ddrval = lpFrontBuffer->lpVtbl->Restore(lpFrontBuffer);
- if( ddrval != DD_OK )
- return FALSE;
- ddrval = lpShip0->lpVtbl->Restore(lpShip0);
- if( ddrval != DD_OK )
- return FALSE;
- ddrval = lpShip1->lpVtbl->Restore(lpShip1);
- if( ddrval != DD_OK )
- return FALSE;
- ddrval = lpShip2->lpVtbl->Restore(lpShip2);
- if( ddrval != DD_OK )
- return FALSE;
- ddrval = lpShip3->lpVtbl->Restore(lpShip3);
- if( ddrval != DD_OK )
- return FALSE;
- ddrval = lpNum->lpVtbl->Restore(lpNum);
- if( ddrval != DD_OK )
- return FALSE;
-
- // Create and set the palette for the splash bitmap
- lpSplashPalette = DDLoadPalette( lpDD, "SPLASH" );
- if( NULL == lpSplashPalette )
- return FALSE;
-
- // Create and set the palette for the art bitmap
- lpArtPalette = DDLoadPalette( lpDD, "Duel8" );
- if( NULL == lpArtPalette )
- return FALSE;
-
- // set the palette before loading the art
- lpFrontBuffer->lpVtbl->SetPalette( lpFrontBuffer, lpArtPalette );
-
- hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), "Duel8", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
-
- if( NULL == hbm )
- return FALSE;
-
- ddrval = DDCopyBitmap( lpShip0, hbm, 0, 0, 320, 128 );
- if( ddrval != DD_OK )
- {
- DeleteObject( hbm );
- return FALSE;
- }
-
- ddrval = DDCopyBitmap( lpShip1, hbm, 0, 128, 320, 128 );
- if( ddrval != DD_OK )
- {
- DeleteObject( hbm );
- return FALSE;
- }
-
- ddrval = DDCopyBitmap( lpShip2, hbm, 0, 256, 320, 128 );
- if( ddrval != DD_OK )
- {
- DeleteObject( hbm );
- return FALSE;
- }
-
- ddrval = DDCopyBitmap( lpShip3, hbm, 0, 384, 320, 128 );
- if( ddrval != DD_OK )
- {
- DeleteObject( hbm );
- return FALSE;
- }
-
- ddrval = DDCopyBitmap( lpNum, hbm, 0, 512, 320, 16 );
- if( ddrval != DD_OK )
- {
- DeleteObject( hbm );
- return FALSE;
- }
-
- DeleteObject( hbm );
-
- // set colorfill colors and color keys according to bitmap contents
- dwFillColor = DDColorMatch( lpShip0, CLR_INVALID );
-
- DDSetColorKey( lpShip0, CLR_INVALID );
- DDSetColorKey( lpShip1, CLR_INVALID );
- DDSetColorKey( lpShip2, CLR_INVALID );
- DDSetColorKey( lpShip3, CLR_INVALID );
- DDSetColorKey( lpNum, CLR_INVALID );
-
- return TRUE;
- }
-
-
- int randInt( int low, int high )
- {
- int range = high - low;
- int num = rand() % range;
- return( num + low );
- }
-
- double randDouble( double low, double high )
- {
- double range = high - low;
- double num = range * (double)rand()/(double)RAND_MAX;
- return( num + low );
- }
-
-
- BOOL RemoteCreate(GUID pGuid, LPSTR FullName, LPSTR NickName)
- {
- HRESULT hr;
- DPSESSIONDESC dpDesc;
-
- // Be sure we aren't already initialized.
- if (lpIDC != NULL)
- {
- return( FALSE );
- }
-
- GetProvider();
-
- if (lpIDC == NULL)
- return(FALSE);
-
- switch( CreateGame())
- {
- case 1: // Create
- IsHost = TRUE;
- memset(&dpDesc, 0x00, sizeof(DPSESSIONDESC));
- dpDesc.dwSize = sizeof(dpDesc);
- dpDesc.dwMaxPlayers = 16;
- dpDesc.dwFlags = DPOPEN_CREATESESSION;
- dpDesc.guidSession = pGuid;
- strcpy( dpDesc.szSessionName, FullName);
-
- if ((hr = lpIDC->lpVtbl->Open(lpIDC, &dpDesc)) != DP_OK)
- {
- lpIDC->lpVtbl->Release(lpIDC);
- lpIDC = NULL;
- return(FALSE);
- }
-
- break;
-
- case 2: // Connect
- IsHost = FALSE;
- g_lpGuid = (LPGUID) &pGuid;
-
- GetGame();
-
- if (lpIDC == NULL)
- return(FALSE);
-
- break;
-
- default:
- return(FALSE);
- }
-
- if ((hr = lpIDC->lpVtbl->CreatePlayer(lpIDC, &dcoID, NickName,
- "Duel Player", &dphEvent)) != DP_OK)
- {
- lpIDC->lpVtbl->Close(lpIDC);
- lpIDC->lpVtbl->Release(lpIDC);
- lpIDC = NULL;
- return(FALSE);
- }
-
- return(TRUE);
-
- }
-
-
- int GetProvider()
- {
- return(DialogBox (NULL, (LPCTSTR)IDD_CHOOSEPROVIDER, hWndMain,
- (DLGPROC)DlgProcChooseProvider));
- }
-
- int CreateGame()
- {
- return(DialogBox (NULL, (LPCTSTR) IDD_Q_CREATE, hWndMain,
- (DLGPROC) DlgProcQCreate));
- }
-
- int GetGame()
- {
-
- return(DialogBox (NULL, (LPCTSTR) IDD_SELSESSION, hWndMain,
- (DLGPROC) DlgProcSelSession));
- }
-
-
- BOOL CALLBACK DlgProcChooseProvider(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- LPGUID lpGuid;
- static LONG iIndex;
- static HWND hWndCtl;
-
- switch (msg)
- {
- case WM_INITDIALOG:
-
- hWndCtl = GetDlgItem(hDlg, IDC_LIST1);
- if (hWndCtl == NULL)
- {
- EndDialog(hDlg, TRUE);
- return(TRUE);
- }
- DirectPlayEnumerate(EnumSP, (LPVOID) hWndCtl);
- SetFocus(hWndCtl);
- SendMessage(hWndCtl, LB_SETCURSEL, 0, 0);
- return(FALSE);
-
- case WM_COMMAND:
- switch( HIWORD(wParam))
- {
- case LBN_SELCHANGE:
- iIndex = SendMessage((HWND) lParam, LB_GETCURSEL, 0, 0);
- hWndCtl = (HWND) lParam;
- return(FALSE);
-
- case LBN_DBLCLK:
- iIndex = SendMessage((HWND) lParam, LB_GETCURSEL, 0, 0);
- if (iIndex != LB_ERR)
- {
- lpGuid = (LPGUID) SendMessage((HWND) lParam, LB_GETITEMDATA, iIndex, 0);
- DirectPlayCreate(lpGuid, &lpIDC, NULL);
- EndDialog(hDlg, TRUE);
- return(TRUE);
- }
- break;
-
- case 0:
- if (LOWORD(wParam) == IDOK)
- {
- if (iIndex != LB_ERR)
- {
- lpGuid = (LPGUID) SendMessage(hWndCtl, LB_GETITEMDATA, iIndex, 0);
- if (lpGuid)
- {
- DirectPlayCreate(lpGuid, &lpIDC, NULL);
- EndDialog(hDlg, TRUE);
- }
- else
- EndDialog(hDlg, FALSE);
- return(TRUE);
- }
- }
- else if (LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, FALSE);
- return(TRUE);
- }
- break;
-
- }
- }
- return (FALSE);
- }
-
- BOOL FAR PASCAL EnumSession(LPDPSESSIONDESC lpDPGameDesc, LPVOID lpContext,
- LPDWORD lpdwTimeOut, DWORD dwFlags)
- {
- LONG iIndex;
- HWND hWnd = (HWND) lpContext;
-
- if( dwFlags & DPESC_TIMEDOUT )
- {
- return FALSE; // don't try again
- }
-
- iIndex = SendMessage(hWnd, LB_ADDSTRING, 0, (LPARAM) lpDPGameDesc->szSessionName);
- if (iIndex != LB_ERR)
- SendMessage(hWnd, LB_SETITEMDATA, iIndex, (LPARAM) lpDPGameDesc->dwSession);
-
- SetFocus(hWnd);
- SendMessage(hWnd, LB_SETCURSEL, 0, 0);
- return(TRUE);
-
- }
-
- BOOL FAR PASCAL EnumSP(LPGUID lpGuid, LPSTR lpDesc, DWORD dwMajorVersion,
- DWORD dwMinorVersion, LPVOID lpv)
- {
- LONG iIndex;
- HWND hWnd = (HWND) lpv;
-
- iIndex = SendMessage(hWnd, LB_ADDSTRING, 0, (LPARAM) lpDesc);
- if (iIndex != LB_ERR)
- SendMessage(hWnd, LB_SETITEMDATA, iIndex, (LPARAM) lpGuid);
-
- SetFocus(hWnd);
- SendMessage(hWnd, LB_SETCURSEL, 0, 0);
- return(TRUE);
- }
-
-
- BOOL CALLBACK DlgProcQCreate (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch (msg)
- {
- case WM_COMMAND:
- switch(wParam)
- {
- case IDC_CREATE:
- EndDialog(hDlg, 1);
- return(TRUE);
-
- case IDC_CONNECT:
- EndDialog(hDlg, 2);
- return(TRUE);
-
- case IDCANCEL:
- EndDialog(hDlg, -1);
- return(TRUE);
- }
- break;
-
- }
- return(FALSE);
- }
-
- BOOL CALLBACK DlgProcSelSession (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- static LONG iIndex;
- static HWND hWndCtl;
- DPSESSIONDESC dpDesc;
- HRESULT hr = DP_OK + 10;
-
- switch (msg)
- {
- case WM_INITDIALOG:
-
- hWndCtl = GetDlgItem(hDlg, IDC_LB_SESSION);
- if (hWndCtl == NULL)
- {
- EndDialog(hDlg, TRUE);
- return(TRUE);
- }
- memset(&dpDesc, 0x00, sizeof(DPSESSIONDESC));
- dpDesc.dwSize = sizeof(dpDesc);
- dpDesc.guidSession = *g_lpGuid;
- // enum sessions with 5 second timeout
- lpIDC->lpVtbl->EnumSessions(lpIDC, &dpDesc, (DWORD)5000, EnumSession, (LPVOID) hWndCtl, (DWORD)NULL);
-
- SetFocus(hWndCtl);
- return(FALSE);
-
- case WM_COMMAND:
-
- switch( HIWORD(wParam))
- {
- case LBN_SELCHANGE:
- iIndex = SendMessage((HWND) lParam, LB_GETCURSEL, 0, 0);
- hWndCtl = (HWND) lParam;
- return(FALSE);
-
- case 0:
- if (LOWORD(wParam) == IDCANCEL)
- {
- lpIDC->lpVtbl->Close(lpIDC);
- lpIDC->lpVtbl->Release(lpIDC);
- lpIDC = NULL;
- EndDialog(hDlg, FALSE);
- return(TRUE);
- }
- //
- // Fall Through.
- //
- case LBN_DBLCLK:
- if (HIWORD(wParam) == LBN_DBLCLK)
- {
- hWndCtl = (HWND) lParam;
- iIndex = SendMessage(hWndCtl, LB_GETCURSEL, 0, 0);
- }
-
- if (iIndex != LB_ERR)
- {
- memset(&dpDesc, 0x00, sizeof(DPSESSIONDESC));
- dpDesc.dwSize = sizeof(dpDesc);
- dpDesc.guidSession = *g_lpGuid;
- dpDesc.dwFlags = DPOPEN_OPENSESSION;
- dpDesc.dwSession = SendMessage((HWND) hWndCtl, LB_GETITEMDATA, iIndex, 0);
- hr = lpIDC->lpVtbl->Open(lpIDC, &dpDesc);
-
- if (hr != DP_OK)
- {
- lpIDC->lpVtbl->Close(lpIDC);
- lpIDC->lpVtbl->Release(lpIDC);
- lpIDC = NULL;
- EndDialog(hDlg, FALSE);
- }
-
- EndDialog(hDlg, TRUE);
- return(TRUE);
-
- }
- }
- }
- return (FALSE);
- }
-
- void ReceiveGameMessages( void )
- {
- DPID fromID, dcoReceiveID;
- DWORD nBytes;
- int x,y;
-
- if ( lpIDC )
- {
- // maybe add a block?
- if( ( randInt( 0, 100 ) > 98 ) && IsHost && bIsActive)
- {
- x = randInt( 0, 40);
- y = randInt( 0, 30);
- if( setBlock( x, y) )
- {
- SendGameMessage(MSG_ADDBLOCK, 0, (BYTE)x, (BYTE)y, 0);
- }
- }
- // read all messages in queue
- while(1)
- {
- HRESULT status;
- nBytes = MAX_BUFFER_SIZE;
- status = lpIDC->lpVtbl->Receive( lpIDC,
- &fromID,
- &dcoReceiveID,
- DPRECEIVE_ALL,
- CommBuff,
- &nBytes);
- switch( status )
- {
- case DP_OK:
- if ( fromID == 0 )
- {
- // ignore system messages
- }
- else
- {
- EvaluateMessage( nBytes );
- }
- break;
-
- default:
-
- // Error condition of some kind - we just stop
- // checking for now
- return;
- }
- }
- }
- }
-
- void EvaluateMessage( DWORD len )
- {
- LPUPDATEMSG lpUpdate;
- LPHEREIAMMSG lpHereIAm;
- LPINITMSG lpInit;
- LPBLOCKHITMSG lpBlockHit;
- LPSHIPHITMSG lpShipHit;
- LPADDBLOCKMSG lpAddBlock;
-
- char dBuf[256];
-
- switch( CommBuff[0] )
- {
- case MSG_UPDATE:
- lpUpdate = (LPUPDATEMSG)CommBuff;
- Ships[lpUpdate->WhoIAm] = lpUpdate->Ship;
- Ships[lpUpdate->WhoIAm].timeStamp = GetTickCount();
- Ships[lpUpdate->WhoIAm].lastTick = Ships[lpUpdate->WhoIAm].timeStamp;
- break;
-
- case MSG_HEREIAM:
- if( IsHost )
- {
- lpHereIAm = (LPHEREIAMMSG)CommBuff;
- SendGameMessage(MSG_INIT, lpHereIAm->ID, 0, 0, 0);
- }
- break;
- case MSG_INIT:
- if( !IsHost )
- {
- lpInit = (LPINITMSG)CommBuff;
- WhoIAm = lpInit->YouAre;
- initShip(&Ships[lpInit->YouAre]);
- Blocks = lpInit->Blocks;
- HaveHostInit = TRUE;
- }
- break;
-
- case MSG_BLOCKHIT:
- lpBlockHit = (LPBLOCKHITMSG)CommBuff;
- Blocks.bits[lpBlockHit->row][lpBlockHit->col] &= ~lpBlockHit->mask;
- break;
-
- case MSG_ADDBLOCK:
- lpAddBlock = (LPADDBLOCKMSG)CommBuff;
- setBlock( lpAddBlock->x, lpAddBlock->y);
- break;
-
- case MSG_SHIPHIT:
- lpShipHit = (LPSHIPHITMSG)CommBuff;
- Ships[lpShipHit->You].enable = FALSE;
- DestroyShip( lpShipHit->You );
- if( lpShipHit->You == WhoIAm )
- {
- Ships[WhoIAm].posx = HomeX[WhoIAm];
- Ships[WhoIAm].posy = HomeY[WhoIAm];
- Ships[WhoIAm].frame = HomeFrame[WhoIAm];
- CountDown = 5000;
- }
- break;
-
- default:
- wsprintf(dBuf, "Unknown message: %d\n", CommBuff[0]);
- OutputDebugString( dBuf );
- break;
- }
- }
-
- void SendGameMessage( BYTE msg, DWORD to, BYTE row, BYTE col, BYTE mask )
- {
- LPUPDATEMSG lpUpdate;
- LPHEREIAMMSG lpHereIAm;
- LPINITMSG lpInit;
- LPBLOCKHITMSG lpBlockHit;
- LPSHIPHITMSG lpShipHit;
- LPADDBLOCKMSG lpAddBlock;
- int nBytes;
- int i;
- DWORD send_to = 0;
-
- switch( msg )
- {
- case MSG_HEREIAM:
- lpHereIAm = (LPHEREIAMMSG)CommBuff;
- lpHereIAm->MsgCode = msg;
- lpHereIAm->ID = (DWORD)dcoID;
- nBytes = sizeof( HEREIAMMSG );
- break;
-
- case MSG_INIT:
- lpInit = (LPINITMSG)CommBuff;
- lpInit->MsgCode = msg;
- send_to = to;
- for(i=0; i<16; i++)
- {
- if( !Ships[i].enable )
- break;
- }
- if( i == 16 )
- {
- // no room for more players
- return;
- }
- lpInit->YouAre = i;
- lpInit->Blocks = Blocks;
- nBytes = sizeof( INITMSG );
- break;
-
- case MSG_UPDATE:
- lpUpdate = (LPUPDATEMSG)CommBuff;
- lpUpdate->MsgCode = msg;
- lpUpdate->WhoIAm = WhoIAm;
- lpUpdate->Ship = Ships[WhoIAm];
- nBytes = sizeof( UPDATEMSG );
- break;
- case MSG_BLOCKHIT:
- lpBlockHit = (LPBLOCKHITMSG)CommBuff;
- lpBlockHit->MsgCode = msg;
- lpBlockHit->row = row;
- lpBlockHit->col = col;
- lpBlockHit->mask = mask;
- nBytes = sizeof( BLOCKHITMSG );
- break;
- case MSG_SHIPHIT:
- lpShipHit = (LPSHIPHITMSG)CommBuff;
- lpShipHit->MsgCode = msg;
- lpShipHit->You = row;
- nBytes = sizeof( SHIPHITMSG );
- break;
- case MSG_ADDBLOCK:
- lpAddBlock = (LPADDBLOCKMSG)CommBuff;
- lpAddBlock->MsgCode = msg;
- lpAddBlock->x = row;
- lpAddBlock->y = col;
- nBytes = sizeof( ADDBLOCKMSG );
- break;
- }
- // Broadcast it to everyone in the group.
- lpIDC->lpVtbl->Send( lpIDC,
- dcoID, // From
- send_to, // send to everybody
- 0,
- (LPSTR)CommBuff,
- nBytes);
-
- }
-
-
- void AddFrag(int which, int offX, int offY)
- {
- int i;
- for(i=0; i<64; i++) // find available fragment
- {
- if( !Frags[i].valid )
- break;
- }
- if( i == 64 )
- return;
-
-
- Frags[i].posx = (double)offX + Ships[which].posx;
- Frags[i].posy = (double)offY + Ships[which].posy;
- switch( which % 4 )
- {
- case 0: Frags[i].surf = lpShip0; break;
- case 1: Frags[i].surf = lpShip1; break;
- case 2: Frags[i].surf = lpShip2; break;
- case 3: Frags[i].surf = lpShip3; break;
- }
- Frags[i].src.top = 32 * ( (int)Ships[which].frame / 10 ) + offX;
- Frags[i].src.left = 32 * ( (int)Ships[which].frame % 10 ) + offY;
- Frags[i].src.right = Frags[i].src.left + 8;
- Frags[i].src.bottom = Frags[i].src.top + 8;
- Frags[i].velx = ((double)offX - 12.0)/24.0;
- Frags[i].vely = ((double)offY - 12.0)/24.0;
- Frags[i].valid = TRUE;
- }
-
-
- void UpdateFragment(int i)
- {
- DWORD TickCnt;
- static DWORD tickDiff;
- static DWORD lastTick;
-
- if( i == 0)
- {
- TickCnt = GetTickCount();
- tickDiff = TickCnt - lastTick;
- lastTick = TickCnt;
- }
-
- if( !Frags[i].valid )
- return;
-
- Frags[i].posx += Frags[i].velx * tickDiff;
- Frags[i].posy += Frags[i].vely * tickDiff;
- if( (Frags[i].posx < 0.0) || (Frags[i].posx >= 632.0) ||
- (Frags[i].posy < 0.0) || (Frags[i].posy >= 472.0) )
- {
- Frags[i].valid = FALSE;
- }
- }
-
- void DrawFragments( void )
- {
- int i;
-
- for(i=0; i<64; i++)
- {
- if( Frags[i].valid )
- {
- bltObject( (int)Frags[i].posx, (int)Frags[i].posy, Frags[i].surf,
- &(Frags[i].src), DDBLTFAST_SRCCOLORKEY );
- }
- }
- }
-
-
- void DestroyShip( int which )
- {
- // add ship fragments
- AddFrag(which, 0, 0);
- AddFrag(which, 8, 0);
- AddFrag(which, 16, 0);
- AddFrag(which, 24, 0);
- AddFrag(which, 0, 8);
- AddFrag(which, 8, 8);
- AddFrag(which, 16, 8);
- AddFrag(which, 24, 8);
- AddFrag(which, 0, 16);
- AddFrag(which, 8, 16);
- AddFrag(which, 16, 16);
- AddFrag(which, 24, 16);
- AddFrag(which, 0, 24);
- AddFrag(which, 8, 24);
- AddFrag(which, 16, 24);
- AddFrag(which, 24, 24);
- }
-