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 + -
显示快捷键?