shootgal.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,120 行 · 第 1/3 页

C
1,120
字号
        SetDlgItemText( window_handle, L_BUTTON_BOX, (LPSTR)textbuffer );
        return( TRUE );
    case WM_RBUTTONDOWN:
        wsprintf(textbuffer, "WM_RBUTTONDOWN: %x, %x, %x", wparam,
                (int)(short)LOWORD(lparam ), (int)(short)HIWORD(lparam ) );
        SetDlgItemText( window_handle, R_BUTTON_BOX, (LPSTR)textbuffer );
        return( TRUE );

    case WM_RBUTTONUP:
        wsprintf(textbuffer, "WM_RBUTTONUP: %x, %x, %x", wparam,
                (int)(short)LOWORD(lparam ), (int)(short)HIWORD(lparam ) );
        SetDlgItemText( window_handle, R_BUTTON_BOX, (LPSTR)textbuffer );
        return( TRUE );

    case WM_RBUTTONDBLCLK:
        wsprintf(textbuffer, "WM_RBUTTONDBLCLK: %x, %x, %x", wparam,
                (int)(short)LOWORD(lparam ), (int)(short)HIWORD(lparam ) );
        SetDlgItemText( window_handle, R_BUTTON_BOX, (LPSTR)textbuffer );
        return( TRUE );

    case WM_KEYDOWN:
        wsprintf(textbuffer, "WM_KEYDOWN: %x, %x, %x", wparam,
                (int)(short)LOWORD(lparam ), (int)(short)HIWORD(lparam ) );
        SetDlgItemText( window_handle, KEY_UP_OR_DOWN_BOX, (LPSTR)textbuffer );
        return( TRUE );

    case WM_KEYUP:
        wsprintf(textbuffer, "WM_KEYUP: %x, %x, %x", wparam,
                (int)(short)LOWORD(lparam ), (int)(short)HIWORD(lparam ) );
        SetDlgItemText( window_handle, KEY_UP_OR_DOWN_BOX, (LPSTR)textbuffer );
        return( TRUE );

    case WM_CHAR:
        wsprintf(textbuffer, "WM_CHAR: %c, %x, %x", wparam , LOWORD(lparam ), HIWORD(lparam ));
        SetDlgItemText( window_handle, CHARACTER_BOX, (LPSTR)textbuffer );
        return( TRUE );

    case WM_TIMER:
        {
            extra_data *edata_ptr;

            edata_ptr = (extra_data *) GetWindowLong(
                GetWindow( window_handle, GW_OWNER ), EXTRA_DATA_OFFSET );

            timercount += edata_ptr->target_speed;
            wsprintf(textbuffer, "WM_TIMER: %d seconds", timercount / 1000 );
            SetDlgItemText( window_handle, TIMER_BOX, (LPSTR)textbuffer );
            return( TRUE );
        }
    case WM_HSCROLL:
    case WM_VSCROLL:
        {
            char        *buff1;
            char        *buff2;
            WORD        code;

            if( msg == WM_HSCROLL ) {
                buff1 = "WM_HSCROLL";
                code = GET_WM_HSCROLL_CODE( wparam, lparam );
            } else {
                buff1 = "WM_VSCROLL";
                code = GET_WM_VSCROLL_CODE( wparam, lparam );
            }
            switch( code ){
            case SB_LINEUP:
                buff2 = "SB_LINEUP";
                break;
            case SB_LINEDOWN:
                buff2 = "SB_LINEDOWN";
                break;
            case SB_PAGEUP:
                buff2 = "SB_PAGEUP";
                break;
            case SB_PAGEDOWN:
                buff2 = "SB_PAGEDOWN";
                break;
            case SB_THUMBPOSITION:
                buff2 = "SB_THUMBPOSITION";
                break;
            case SB_THUMBTRACK:
                buff2 = "SB_THUMBTRACK";
                break;
            case SB_ENDSCROLL:
                buff2 = "SB_ENDSCROLL";
                break;
            default :
                buff2 = "unknown";
                break;
            }
            wsprintf(textbuffer, "%s: %s, %x, %x",
                (LPSTR)buff1, (LPSTR)buff2, (int)(short)LOWORD(lparam ),
                (int)(short)HIWORD(lparam ));
            SetDlgItemText( window_handle, SCROLL_BOX, (LPSTR)textbuffer );
            return( TRUE );
        }
    }
    return ( FALSE );
} /* MessageWindowProc */

/*
 * calculate where on the target the bolt hit
 * this is based on the colours of the target rings
 */
static void CheckHit( HDC hdc, POINT hit_point )
/**********************************************/
{
    DWORD               colour;
    unsigned short      points;
    unsigned short      dialog_item;
    BOOL                translated;

    colour = GetPixel( hdc, hit_point.x, hit_point.y );

    switch( colour ) {
    case RING1:
        dialog_item = YELLOW;
        break;
    case RING2:
        dialog_item = RED;
        break;
    case RING3:
        dialog_item = BLUE;
        break;
    case RING4:
        dialog_item = BLACK;
        break;
    case RING5:
        dialog_item = WHITE;
        break;
    case BACKGROUND:
        dialog_item = MISSED;
        break;
    }

    /*
     * increment # of hits on location
     */
    points = GetDlgItemInt( ScoreWnd, dialog_item, &translated, FALSE );
    points++;
    SetDlgItemInt( ScoreWnd, dialog_item, points, FALSE );

    /*
     * increment # of shots
     */
    points = GetDlgItemInt( ScoreWnd, SHOTS, &translated, FALSE );
    points++;
    SetDlgItemInt( ScoreWnd, SHOTS, points, FALSE );

    return;

} /* CheckHit */

/*
 * display a bitmap on the given DC, at device coordinates x,y
 * make the bitmap the same size as the source bitmap
 */
static void DrawBitmap( HDC hdc, HBITMAP bitmap, int x, int y )
/*****************************************************************/
{
    BITMAP      bitmapbuff;
    HDC         memorydc;
    POINT       origin;
    POINT       size;

    memorydc = CreateCompatibleDC( hdc );
    SelectObject( memorydc, bitmap );
    SetMapMode( memorydc, GetMapMode( hdc ) );
    GetObject( bitmap, sizeof( BITMAP ), (LPSTR) &bitmapbuff );

    origin.x = x;
    origin.y = y;
    size.x = bitmapbuff.bmWidth;
    size.y = bitmapbuff.bmHeight;

    DPtoLP( hdc, &origin, 1 );
    DPtoLP( memorydc, &size, 1 );

    BitBlt( hdc, origin.x, origin.y, size.x, size.y, memorydc, 0, 0, SRCCOPY);
    DeleteDC( memorydc );
} /* DrawBitmap */

/*
 * pick a random point so that a bitmap with width & height specified by
 * the second parameter will fit inside the given rectangle
 */
POINT RandPoint( RECT rect, POINT size )
/**************************************/
{
    POINT random_point;
    short width;    /* width of the area to pick from */
    short height;   /* height of the area to pick from */

    width = rect.right - rect.left - size.x;
    height = rect.bottom - rect.top - size.y;

    random_point.x = rand() % width + rect.left;
    random_point.y = rand() % height + rect.top;

    return( random_point );
} /* RandPoint */

/*
 * Draws an icon at the coordinates x,y, after copying a saved bitmap back
 * onto the screen at the coordinates where the last icon was drawn and
 * saving the area under the icon to a DC in memory
 */
void DoDrawBolt( int x, int y, icon_mover * mover)
/************************************************/
{

    /*
     * to make this look fast, even on slow machines, only redraw the icon
     * when the x coordinate is a multiple of the bolt speed
     * thus if speed = 5, the icon will be redrawn every 5th pixel it moves
     */
    if( x % mover->speed != 0 ) return;

    /* if it is not the first iteration */
    if( mover->last.x != -1 || mover->last.y != -1 ) {
        /* redraw the area that the last icon covered */
        BitBlt( mover->screen_dc, mover->last.x, mover->last.y, mover->size.x,
                mover->size.y, mover->storage_dc, 0, 0, SRCCOPY);
    }

    /* save the area that will be under the icon to a DC in memory */
    BitBlt( mover->storage_dc, 0, 0, mover->size.x, mover->size.y,
            mover->screen_dc, x, y, SRCCOPY);

    DrawIcon( mover->screen_dc, x, y, mover->icon );

    /* save the coordinates for next time */
    mover->last.x = x;
    mover->last.y = y;

} /* DoDrawBolt */

/*
 * called by windows from LineDDA funcion
 */
void _EXPORT FAR PASCAL DrawBolt( int x, int y, LPSTR dataptr )
/*************************************************************/
{

    DoDrawBolt( x, y, (icon_mover *) dataptr );

} /* DrawBolt */

/*
 * "shoot" a bolt from the current bolt location to the "aim" location
 */
static void ShootBolt( HWND window_handle )
/*****************************************/
{
    extra_data  *edata_ptr;
    HDC         hdc;
    HBITMAP     screensavebmp;
    MSG         msg;
    FARPROC     proc;
    HANDLE      inst_handle;
    icon_mover  mover;

    edata_ptr = (extra_data *) GetWindowLong( window_handle,
                                        EXTRA_DATA_OFFSET );

    hdc = GetDC( window_handle );
    inst_handle = GET_HINST( window_handle );

    /* set up an "icon_mover" struct to give all needed data to DrawBolt */
    mover.icon = edata_ptr->bolt_icon;
    mover.size.x = BOLTWIDTH;
    mover.size.y = BOLTHEIGHT;
    mover.last.x = -1;
    mover.last.y = -1;
    mover.screen_dc = hdc;
    mover.storage_dc = CreateCompatibleDC( hdc );
    mover.speed = edata_ptr->bolt_speed;

    screensavebmp = CreateCompatibleBitmap( hdc, mover.size.x, mover.size.y );
    SelectObject( mover.storage_dc, screensavebmp );

    if( edata_ptr->sound_on ) {
        BoltSound();
    }
    /*
     * for each point on the line between the points BOLT and AIM,
     * call DrawBolt
     * use aim - boltheight so that the bottom left corner of the bolt icon
     * stops at the point AIM
     */
    proc = MakeProcInstance( (FARPROC)DrawBolt, inst_handle );
    LineDDA( edata_ptr->bolt.x, edata_ptr->bolt.y, edata_ptr->aim.x,
             edata_ptr->aim.y - BOLTHEIGHT, (LINEDDAPROC)proc, (LPARAM)(LPVOID)&mover );
    FreeProcInstance( proc );

    /*
     * remove all WM_LBUTTONDOWN messages from the application queue which
     * occured while the bolt was "in the air"
     * this prevents the shots from building up - only 1 can happen at a time
     */
    while( PeekMessage( &msg, window_handle, WM_LBUTTONDOWN, WM_LBUTTONDOWN,
                        PM_REMOVE ) );

    /* make sure the bolt is drawn at the final location regardless of speed */
    mover.speed = 1;
    DoDrawBolt( edata_ptr->aim.x, edata_ptr->aim.y - BOLTHEIGHT, &mover );
    if( edata_ptr->sound_on ) {
        BoomSound();
    }
    /* redraw the background behind the icon */
    BitBlt( mover.screen_dc, mover.last.x, mover.last.y, mover.size.x,
            mover.size.y, mover.storage_dc, 0, 0, SRCCOPY);

    CheckHit( hdc, edata_ptr->aim );

    DeleteDC( mover.storage_dc );
    DeleteObject( screensavebmp );
    ReleaseDC(window_handle, hdc);

} /* ShootBolt */

/*
 * make a sound like thunder
 * this function is called after each time BoltSound is called
 * Sound is not implemented for the NT version
 */
static void BoomSound( void )
/***************************/
{
#ifndef __NT__
    short i;
    short low;
    short high;

    StopSound();
    SetVoiceQueueSize( 1, 600 );
    SetVoiceAccent( 1, 120, 50, S_STACCATO, 0 );

    for( i=0; i < 1000; i++ ) {
        /*
         * create a random low-pitched sound
         */
        high = rand() % 200 + 1;
        low = rand() % high + 1;
        SetVoiceSound( 1, MAKELONG( low, high ), 1 );
    }
    StartSound();
    WaitSoundState( S_QUEUEEMPTY ); /* wait for the sound to finish */
    StopSound();
    CloseSound();
#endif
} /* BoomSound */

/*
 * create a tone that goes from high-pitched to low-pitched
 * Sound is not implemented for the NT version
 */
static void BoltSound( void )
/***************************/
{
#ifndef __NT__
    short i;

    OpenSound();
    SetVoiceAccent( 1, 120, 50, S_LEGATO, 0 );
    for( i=84; i > 0; i-- ) {
        SetVoiceNote( 1, i, 128, 1 );
        /* place a 128th note of value i into voice queue 1 */
    }
    StartSound();
#endif
} /* BoltSound */

⌨️ 快捷键说明

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