Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

934 lines
24 KiB

/*********************************************************************
* bounce - bouncing ball program
*********************************************************************
*/
// include files
#include <stdlib.h>
#include <windows.h>
#include <string.h>
#include <time.h>
#include "bounce.h"
/*
* Include the LSAPI header file.
*/
#include "lsapi.h"
// global variables
HANDLE hInst; // Instance handle
char szAppName[] = APPNAME; // application name
char szAppTitle[] = APPTITLE; // application title
char szAppIcon[] = APPICON; // icon name
char szAppLicName[] = APPLICNAME;
char szAppProducer [] = APPPRODUCER;
char szAppVersion [] = APPVERSION;
char szAppLicErrMsg [] = APPLICERRMSG;
char szAppNoLicense [] = APPNOLICENSE;
char szAppNoLicRelease [] = APPNOLICRELEASE;
time_t tAppRelease;
LS_HANDLE hLicense; // bounce grant handle
LS_CHALLENGE hChallenge; // challenge handle
ITEM_STRUCT ball_list[MAX_ITEM];
BOOL button1_pressed = FALSE;
BOOL bTimer = FALSE;
static int save_oldx, save_oldy, save_newx, save_newy;
int item_index = 0; /* Points to next unused item in ball_list */
int max_color = 0; /* Holds number of colors/pixmaps used */
int curr_pixmap; /* Holds next pixmap to use for next ball */
int right_wall = 0; /* Locations of room structures */
int left_wall = 0;
int ceiling = 0;
int floor = 0;
int oldx,oldy; /* Used to save x,y position while calc new x,y */
int x,y;
static HANDLE hPixmaps [MAX_COLORS]; // handle to a bitmap
static HANDLE hBlankMap;
static HCURSOR hHourGlass; // handle for hourglass cursor
/* window size variables */
static short cxClient, cyClient, xCenter, yCenter;
static short cxRadius, cyRadius, cxMove, cyMove;
static short cxTotal, cyTotal;
static short xPixel, yPixel;
// function prototypes
//int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance, LPSTR lppszCmdLine, int nCmdShow);
void InitApp (HANDLE hInstance, HANDLE hPrevInstance, int nCmdShow);
void InitAppFirst (HANDLE hInstance);
void InitAppEvery (HANDLE hInstance, int nCmdShow);
BOOL OpenApp (HANDLE hInstance);
void CloseApp (HANDLE hInstance);
long FAR PASCAL WndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam);
void AppCreate (HWND hWnd);
void AppSize (HWND hWnd, UINT wParam, LONG lParam);
void AppTimer (HWND hWnd, UINT wParam, LONG lParam);
void AppPaint (HWND hWnd);
void AppDestroy (HWND hWnd);
void AppMouseMove (HWND hWnd, UINT wParam, LONG lParam);
void AppLButtonDown (HWND hWnd, UINT wParam, LONG lParam);
void AppLButtonUp (HWND hWnd, UINT wParam, LONG lParam);
void AppChar (HWND hWnd, UINT wParam, LONG lParam);
void create_item(int x, int y, int x_vel, int y_vel);
void get_velocity (int *x_vel_ptr, int *y_vel_ptr);
void rebound_item(ITEM_STRUCT *itema_ptr, ITEM_STRUCT *itemb_ptr);
/*********************************************************************
* Main Window Procedure
*********************************************************************
*/
int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lppszCmdLine, int nCmdShow)
{
MSG msg;
if (!OpenApp (hInstance)) // closing routine
return (FALSE);
InitApp (hInstance, hPrevInstance, nCmdShow);
while (GetMessage (&msg, (HWND) NULL, 0, 0)) // main loop
{ // terminated by quit message
TranslateMessage (&msg); // translate virtual keys
DispatchMessage (&msg); // send message to window proc
}
CloseApp (hInstance); // closing routine
return (msg.wParam); // exit & return
}
/*********************************************************************
* InitApp - program initialization
*********************************************************************
*/
void InitApp (HANDLE hInstance, HANDLE hPrevInstance, int nCmdShow)
{
if (!hPrevInstance)
InitAppFirst (hInstance); // first instance only
InitAppEvery (hInstance, nCmdShow); // every instance
}
/*********************************************************************
* InitAppFirst - first instance initialization
*********************************************************************
*/
void InitAppFirst (HANDLE hInstance)
{
WNDCLASS wcApp;
// setup application window class structure
wcApp.style = CS_HREDRAW | CS_VREDRAW;
wcApp.lpfnWndProc = WndProc;
wcApp.cbClsExtra = 0;
wcApp.cbWndExtra = 0;
wcApp.hInstance = hInstance;
wcApp.hIcon = LoadIcon (hInstance, szAppIcon);
wcApp.hCursor = LoadCursor ((HINSTANCE) NULL, IDC_ARROW);
wcApp.hbrBackground = GetStockObject (WHITE_BRUSH);
wcApp.lpszMenuName = NULL;
wcApp.lpszClassName = szAppName;
RegisterClass (&wcApp); // register the window class
}
/*********************************************************************
* InitAppEvery - every instance initialization
*********************************************************************
*/
void InitAppEvery (HANDLE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // save instance handle
hWnd = CreateWindow (szAppName, // window class
szAppTitle, // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x pos
CW_USEDEFAULT, // initial y pos
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
(HWND) NULL, // parent window
(HMENU) NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters
if (!SetTimer (hWnd, 1, 50, NULL))
{
MessageBox (hWnd,
"Too Many clocks or timers!",
szAppName,
MB_ICONEXCLAMATION | MB_OK);
}
bTimer = TRUE;
ShowWindow (hWnd, nCmdShow);
UpdateWindow (hWnd);
}
/*********************************************************************
* OpenApp - open application
*********************************************************************
*/
BOOL OpenApp (HANDLE hInstance)
{
LS_STATUS_CODE ulGrantStatus = LS_SUCCESS, messageStatus = LS_SUCCESS;
unsigned long unitsGranted = 0;
char szCaption [255];
char szText [255];
LS_STR errorText[255];
HCURSOR hCursor;
/* convert time tm to timer */
tAppRelease = mktime (&tmAppTime);
/* load hourglass cursor, save current cursor, display the hour glass */
hHourGlass = LoadCursor ((HINSTANCE) NULL, IDC_WAIT);
hCursor = SetCursor (hHourGlass);
ShowCursor (TRUE);
/* Try to obtain a license */
ulGrantStatus = LSRequest(
(LS_STR FAR *) LS_ANY,
(LS_STR FAR *) szAppProducer,
(LS_STR FAR *) szAppLicName,
(LS_STR FAR *) szAppVersion,
(LS_ULONG) LS_DEFAULT_UNITS,
(LS_STR FAR *) "Making a request",
&hChallenge,
&unitsGranted,
&hLicense);
/* display the cursor */
ShowCursor (FALSE);
SetCursor (hCursor);
ShowCursor (TRUE);
/* if no license, display an error message */
if ( LS_SUCCESS != ulGrantStatus )
{
lstrcpy( szCaption, szAppName );
lstrcat( szCaption, szAppLicErrMsg );
lstrcpy( szText, szAppNoLicense );
lstrcat( szText, "\n" );
messageStatus = LSGetMessage( hLicense, ulGrantStatus, errorText, 255 );
if ( LS_SUCCESS != messageStatus )
lstrcat( szText, "LSGetMessage Failed!" );
else
lstrcat( szText, (char FAR *) errorText );
MessageBox( (HWND) NULL,
szText,
szCaption,
MB_ICONEXCLAMATION | MB_OK );
LSFreeHandle( hLicense );
return( FALSE );
}
/* successfully obtained a license */
return (TRUE);
}
/*********************************************************************
* CloseApp - close application
*********************************************************************
*/
void CloseApp (HANDLE hInstance)
{
LS_STATUS_CODE ulGrantStatus = LS_SUCCESS, messageStatus = LS_SUCCESS;
char szCaption [255];
char szText [255];
HCURSOR hCursor;
char errorText[50];
/* display the hour glass */
hCursor = SetCursor (hHourGlass);
ShowCursor (TRUE);
/* release the grant */
ulGrantStatus = LSRelease(
hLicense,
LS_DEFAULT_UNITS,
(LS_STR FAR *) "Making a release");
LSFreeHandle( hLicense );
/* display the cursor */
ShowCursor (FALSE);
SetCursor (hCursor);
ShowCursor (TRUE);
/* check the return status from the LSRelease call */
if ( LS_SUCCESS != ulGrantStatus )
{
lstrcpy( szCaption, szAppName );
lstrcat( szCaption, szAppLicErrMsg );
lstrcpy( szText, szAppNoLicense );
lstrcat( szText, "\n" );
messageStatus = LSGetMessage( hLicense, ulGrantStatus, errorText, 50 );
if ( LS_SUCCESS != messageStatus )
lstrcat( szText, "LSGetMessage Failed!" );
else
lstrcat( szText, (char FAR *) errorText );
MessageBox( (HWND) NULL,
szText,
szCaption,
MB_ICONEXCLAMATION | MB_OK );
}
}
/*********************************************************************
* WndProc - Main window message loop
*********************************************************************
*/
long FAR PASCAL WndProc (HWND hWnd, UINT message, UINT wParam, LONG lParam)
{
switch ( message )
{
case WM_CREATE: // create message
AppCreate (hWnd);
break;
case WM_SIZE:
AppSize (hWnd, wParam, lParam);
break;
case WM_MOUSEMOVE:
AppMouseMove (hWnd, wParam, lParam);
break;
case WM_LBUTTONDOWN:
AppLButtonDown (hWnd, wParam, lParam);
break;
case WM_LBUTTONUP:
AppLButtonUp (hWnd, wParam, lParam);
break;
case WM_TIMER:
AppTimer (hWnd, wParam, lParam);
break;
case WM_CHAR:
AppChar (hWnd, wParam, lParam);
break;
case WM_PAINT:
AppPaint (hWnd);
break;
case WM_QUERYENDSESSION:
return (1L);
case WM_ENDSESSION:
if (0 != wParam)
CloseApp (hInst);
break;
case WM_DESTROY: // destroy message
AppDestroy (hWnd);
break;
default: // default
return (DefWindowProc (hWnd, message, wParam, lParam));
}
return (0);
}
/*********************************************************************
* AppCreate - Main window create routine
*********************************************************************
*/
void AppCreate (HWND hWnd)
{
HDC hDC, hDCBall;
HANDLE hOldBitmap; // handle to a bitmap
HBRUSH hBrush, hOldBrush;
HPEN hPen, hOldPen;
short red, green, blue;
int max_color;
hDC = GetDC (hWnd);
xPixel = GetDeviceCaps (hDC, ASPECTX);
yPixel = GetDeviceCaps (hDC, ASPECTY);
hDCBall = CreateCompatibleDC (hDC);
if ((HANDLE) NULL == hBlankMap)
{
hBlankMap = CreateCompatibleBitmap (hDC, ITEM_WIDTH, ITEM_HEIGHT);
hOldBitmap = SelectObject (hDCBall, hBlankMap);
Rectangle (hDCBall,
-1,
-1,
ITEM_WIDTH + 1,
ITEM_HEIGHT +1);
hBlankMap = SelectObject (hDCBall, hOldBitmap);
}
for (max_color = 0; max_color < MAX_COLORS; max_color++)
{
hPixmaps [max_color] = CreateCompatibleBitmap (hDC, ITEM_WIDTH, ITEM_HEIGHT);
hOldBitmap = SelectObject (hDCBall, hPixmaps [max_color]);
Rectangle (hDCBall,
-1,
-1,
ITEM_WIDTH + 1,
ITEM_HEIGHT +1);
red = (short) (rand() % 255);
green = (short) (rand() % 255);
blue = (short) (rand() % 255);
hPen = CreatePen (PS_SOLID, 1, RGB(red, green, blue));
hOldPen = SelectObject (hDCBall, hPen);
hBrush = CreateSolidBrush (RGB(red, green, blue));
hOldBrush = SelectObject (hDCBall, hBrush);
Ellipse (hDCBall,
0,
0,
ITEM_WIDTH,
ITEM_HEIGHT);
hPen = SelectObject (hDCBall, hOldPen);
DeleteObject (hPen);
hBrush = SelectObject (hDCBall, hOldBrush);
DeleteObject (hBrush);
hPixmaps [max_color] = SelectObject (hDCBall, hOldBitmap);
}
DeleteDC (hDCBall);
ReleaseDC (hWnd, hDC);
}
/*********************************************************************
* AppSize - Main window resize routine
*********************************************************************
*/
void AppSize (HWND hWnd, UINT wParam, LONG lParam)
{
cxClient = LOWORD (lParam);
cyClient = HIWORD (lParam);
right_wall = cxClient*INTFAC; /* Locations of room structures */
floor = cyClient*INTFAC;
if ((SIZEICONIC == wParam) || (SIZEZOOMHIDE == wParam))
{
bTimer = FALSE;
KillTimer (hWnd, 1);
}
else
{
if (FALSE == bTimer)
{
if (!SetTimer (hWnd, 1, 50, NULL))
{
MessageBox (hWnd,
"Too Many clocks or timers!",
szAppName,
MB_ICONEXCLAMATION | MB_OK);
SendMessage (hWnd, WM_CLOSE, 0, 0L);
}
bTimer = TRUE;
}
}
return;
}
/*********************************************************************
* AppTimer - Main window timer message routine
*********************************************************************
*/
void AppTimer (HWND hWnd, UINT wParam, LONG lParam)
{
InvalidateRect (hWnd, NULL, FALSE);
return;
}
/*********************************************************************
* AppMouseMove - Main window mouse move routine
*********************************************************************
*/
void AppMouseMove (HWND hWnd, UINT wParam, LONG lParam)
{
HDC hDC, hDCBall;
HANDLE hOldBitMap;
if (button1_pressed)
{
/* When button 1 pressed during movement */
save_oldx = save_newx; /* Save 'speed' */
save_oldy = save_newy;
save_newx = LOWORD (lParam);
save_newy = HIWORD (lParam);
/* Erase old object */
hDC = GetDC (hWnd);
hDCBall = CreateCompatibleDC (hDC);
hOldBitMap = SelectObject (hDCBall, hBlankMap);
BitBlt (hDC,
save_oldx - ITEM_WIDTH/2,
save_oldy - ITEM_HEIGHT/2,
ITEM_WIDTH,
ITEM_HEIGHT,
hDCBall,
0,
0,
SRCCOPY);
hBlankMap = SelectObject (hDCBall, hOldBitMap);
hOldBitMap = SelectObject (hDCBall, hPixmaps[curr_pixmap]);
BitBlt (hDC,
save_newx - ITEM_WIDTH/2,
save_newy - ITEM_HEIGHT/2,
ITEM_WIDTH,
ITEM_HEIGHT,
hDCBall,
0,
0,
SRCCOPY);
hPixmaps[curr_pixmap]= SelectObject (hDCBall, hOldBitMap);
DeleteDC (hDCBall);
ReleaseDC (hWnd, hDC);
}
}
/*********************************************************************
* AppLButtonDown - Main window left mouse button down routine
*********************************************************************
*/
void AppLButtonDown (HWND hWnd, UINT wParam, LONG lParam)
{
HDC hDC, hDCBall;
HANDLE hOldBitMap;
button1_pressed = TRUE;
save_oldx = save_newx = LOWORD (lParam);
save_oldy = save_newy = HIWORD (lParam);
/* Draw an item under the pointer */
hDC = GetDC (hWnd);
hDCBall = CreateCompatibleDC (hDC);
hOldBitMap = SelectObject (hDCBall, hPixmaps[curr_pixmap]);
BitBlt (hDC,
save_newx - ITEM_WIDTH/2,
save_newy - ITEM_HEIGHT/2,
ITEM_WIDTH,
ITEM_HEIGHT,
hDCBall,
0,
0,
SRCCOPY);
hPixmaps[curr_pixmap]= SelectObject (hDCBall, hOldBitMap);
DeleteDC (hDCBall);
ReleaseDC (hWnd, hDC);
}
/*********************************************************************
* AppLButtonUp - Main window left mouse button Up routine
*********************************************************************
*/
void AppLButtonUp (HWND hWnd, UINT wParam, LONG lParam)
{
HDC hDC, hDCBall;
HANDLE hOldBitMap;
int x_vel,y_vel;
if (button1_pressed)
{
button1_pressed = FALSE;
/* Erase button ball */
hDC = GetDC (hWnd);
hDCBall = CreateCompatibleDC (hDC);
hOldBitMap = SelectObject (hDCBall, hBlankMap);
BitBlt (hDC,
save_oldx - ITEM_WIDTH/2,
save_oldy - ITEM_HEIGHT/2,
ITEM_WIDTH,
ITEM_HEIGHT,
hDCBall,
0,
0,
SRCCOPY);
hBlankMap = SelectObject (hDCBall, hOldBitMap);
/* Create new item when button let go */
get_velocity( &x_vel,&y_vel);
create_item( save_newx, save_newy ,x_vel, y_vel);
/* paint new ball */
hOldBitMap = SelectObject (hDCBall, hPixmaps[curr_pixmap]);
BitBlt (hDC,
save_newx - ITEM_WIDTH/2,
save_newy - ITEM_HEIGHT/2,
ITEM_WIDTH,
ITEM_HEIGHT,
hDCBall,
0,
0,
SRCCOPY);
hPixmaps[curr_pixmap]= SelectObject (hDCBall, hOldBitMap);
DeleteDC (hDCBall);
ReleaseDC (hWnd, hDC);
}
}
/*********************************************************************
* AppChar - Main window character input routine
*********************************************************************
*/
void AppChar (HWND hWnd, UINT wParam, LONG lParam)
{
HDC hDC, hDCBall;
HANDLE hOldBitMap;
switch (wParam) // wParam is character read
{
case 'q':
case 'Q':
SendMessage (hWnd, WM_CLOSE, 0, 0L);
break;
case 'c':
case 'C':
InvalidateRect (hWnd, NULL, TRUE);
break;
case 'r':
case 'R':
{
item_index--;
oldy = ball_list[item_index].y/INTFAC;
oldx = ball_list[item_index].x/INTFAC;
/* erase a ball */
hDC = GetDC (hWnd);
hDCBall = CreateCompatibleDC (hDC);
hOldBitMap = SelectObject (hDCBall, hBlankMap);
BitBlt (hDC,
oldx - ITEM_WIDTH/2,
oldy - ITEM_HEIGHT/2,
ITEM_WIDTH,
ITEM_HEIGHT,
hDCBall,
0,
0,
SRCCOPY);
hBlankMap = SelectObject (hDCBall, hOldBitMap);
DeleteDC (hDCBall);
ReleaseDC (hWnd, hDC);
ball_list[item_index].valid = FALSE;
}
break;
default:
MessageBeep (0);
}
}
/*********************************************************************
* AppPaint - main window paint routine
*********************************************************************
*/
void AppPaint (HWND hWnd)
{
PAINTSTRUCT ps;
HDC hDC;
HDC hDCBall, hDCBlank;
HANDLE hOldBitMap1, hOldBitMap2;
short x, y;
hDC = BeginPaint (hWnd, &ps); // get dc to client area
hDCBall = CreateCompatibleDC (hDC);
hDCBlank = CreateCompatibleDC (hDC);
hOldBitMap1 = SelectObject (hDCBlank, hBlankMap);
for (x = 0; x < item_index; x++)
{
/* See if item is valid */
if (!ball_list[x].valid)
{
/* Copy last item in list to here */
item_index--;
if (x != item_index)
ball_list[x] = ball_list[item_index];
else
continue; /* Killed last item */
}
/* Calculate new position of item */
/* Save old position so we can erase it */
oldy = ball_list[x].y/INTFAC;
oldx = ball_list[x].x/INTFAC;
/* Calculate new y position */
ball_list[x].y += ball_list[x].y_velocity; /* Move vert based on vel */
ball_list[x].y_velocity++; /* Gravity adds to velocity */
if (ball_list[x].y > floor)
{
/* item hit floor -- bounce off floor */
ball_list[x].y = 2*floor - ball_list[x].y; /* Bounce back */
ball_list[x].y_velocity = (-ball_list[x].y_velocity) + /* Rev vel */
GRAVITY/4; /* But remove some inertia */
}
else
if (ball_list[x].y < ceiling)
{
/* item hit ceiling */
ball_list[x].y = 2*ceiling - ball_list[x].y; /* Bounce off */
ball_list[x].y_velocity = -ball_list[x].y_velocity; /* Rev dir */
}
/* Calculate new x position */
ball_list[x].x += ball_list[x].x_velocity; /* Move horiz base on vel */
if (ball_list[x].x > right_wall)
{
/* Hit right wall */
ball_list[x].x = 2*right_wall-ball_list[x].x; /* Bounce off */
ball_list[x].x_velocity = -ball_list[x].x_velocity; /* Rev dir */
}
else
if (ball_list[x].x < left_wall)
{
/* Hit left wall */
ball_list[x].x = 2*left_wall - ball_list[x].x; /* Bounce off */
ball_list[x].x_velocity = -ball_list[x].x_velocity; /* Rev dir */
}
/* See if collided with another item */
for (y = 0; y < item_index && ball_list[x].rebounded == FALSE; y++)
if (x != y)
rebound_item( &ball_list[x], &ball_list[y]);
ball_list[x].rebounded = FALSE;
if (oldx == ball_list[x].x/INTFAC &&
oldy == ball_list[x].y/INTFAC)
continue; /* Item hasn't moved */
/* Erase old object */
BitBlt (hDC,
oldx - ITEM_WIDTH/2,
oldy - ITEM_HEIGHT/2,
ITEM_WIDTH,
ITEM_HEIGHT,
hDCBlank,
0,
0,
SRCCOPY);
/* See if item has come to a peaceful rest */
if (ball_list[x].y == floor && /* on floor */
ABS(ball_list[x].y_velocity) <= GRAVITY) /* Not bouncing */
{
if (ABS(ball_list[x].x_velocity) < GRAVITY/10) /* Not rolling */
{
ball_list[x].valid = FALSE;
continue; /* Don't draw item */
}
/* Slow down velocity once rolling */
if (ball_list[x].x_velocity > 0)
ball_list[x].x_velocity -= GRAVITY/10;
else
ball_list[x].x_velocity += GRAVITY/10;
}
/* Draw new item */
hOldBitMap2 = SelectObject (hDCBall, hPixmaps[ball_list[x].p_index] );
BitBlt (hDC,
ball_list[x].x/INTFAC - ITEM_WIDTH/2,
ball_list[x].y/INTFAC - ITEM_HEIGHT/2,
ITEM_WIDTH,
ITEM_HEIGHT,
hDCBall,
0,
0,
SRCCOPY);
hPixmaps[ball_list[x].p_index] = SelectObject (hDCBall, hOldBitMap2);
}
hBlankMap = SelectObject (hDCBlank, hOldBitMap1);
DeleteDC (hDCBlank);
DeleteDC (hDCBall);
EndPaint (hWnd, &ps);
}
/*********************************************************************
* AppDestroy - main window destory routine
*********************************************************************
*/
void AppDestroy (HWND hWnd)
{
KillTimer (hWnd, 1);
for (max_color = 0; max_color < MAX_COLORS; max_color++)
{
if ((HANDLE) NULL != hPixmaps [max_color])
{
DeleteObject (hPixmaps [max_color]);
hPixmaps [max_color] = (HANDLE) NULL;
}
}
DeleteObject (hBlankMap);
PostQuitMessage (0);
}
/*********************************************************************
* create_item
*********************************************************************
*/
void create_item(int x, int y, int x_vel, int y_vel)
{
ball_list[item_index].x = x*INTFAC;
ball_list[item_index].y = y*INTFAC;
ball_list[item_index].x_velocity = x_vel;
ball_list[item_index].y_velocity = y_vel;
ball_list[item_index].valid = TRUE;
ball_list[item_index].p_index = curr_pixmap;
curr_pixmap = (curr_pixmap + 1) % MAX_COLORS;
item_index++;
}
/*********************************************************************
* get_velocity
*********************************************************************
*/
void get_velocity( int *x_vel_ptr, int *y_vel_ptr)
{
/* Velocity is based on how fast the pointer is moving which is based */
/* on the last two motion events received's delta-x and delta-y */
*x_vel_ptr = (save_newx - save_oldx) * INTFAC;
*y_vel_ptr = (save_newy - save_oldy) * INTFAC;
#if 0
/* Other velocity ideas */
*x_vel_ptr = ((rand() & 0x7) - 4) * INTFAC; /* Random x velocity */
*y_vel_ptr = -3/*((rand() & 0x3) - 4)*/ * INTFAC; /* Random y vel */
*y_vel_ptr = 0; /* No y velocity */
#endif
}
/*********************************************************************
* rebount_item
*********************************************************************
*/
void rebound_item(ITEM_STRUCT *itema_ptr, ITEM_STRUCT *itemb_ptr)
{
/* Itema is assumed to have just been moved */
int xdiff,ydiff;
xdiff = (itema_ptr->x - itemb_ptr->x)/INTFAC;
ydiff = (itema_ptr->y - itemb_ptr->y)/INTFAC;
if (ABS(xdiff) <= ITEM_WIDTH && ABS(ydiff)<= ITEM_HEIGHT)
{
#if 1
itema_ptr->rebounded = TRUE; /* Mark as rebound */
itemb_ptr->rebounded = TRUE; /* Mark as rebound */
SWAP( itema_ptr->x_velocity, itemb_ptr->x_velocity, int);
SWAP( itema_ptr->y_velocity, itemb_ptr->y_velocity, int);
/* If on each other and slow velocity, bounce away from each other */
if (itema_ptr->y_velocity <= ITEM_WIDTH &&
itemb_ptr->y_velocity <= ITEM_WIDTH)
{
itema_ptr->y_velocity += ITEM_HEIGHT - ydiff;
itemb_ptr->y_velocity -= ITEM_HEIGHT - ydiff;
}
if (itema_ptr->x_velocity <= ITEM_WIDTH &&
itemb_ptr->x_velocity <= ITEM_WIDTH)
{
itema_ptr->x_velocity += ITEM_WIDTH - xdiff;
itemb_ptr->x_velocity -= ITEM_WIDTH - xdiff;
}
#else
if (xdiff != 0)
itema_ptr->x_velocity =
itema_ptr->x_velocity-(ITEM_WIDTH-xdiff)/2;
itema_ptr->y_velocity =
itema_ptr->y_velocity-(ITEM_WIDTH-ydiff)/2;
#endif
}
}