|
|
1.1 ! root 1: /*---------------------------------------------------------------------------*\ ! 2: | BOUNCING BALL MODULE ! 3: | ! 4: | segment: _TEXT (DOS16) ! 5: | created: 19-Oct-90 ! 6: | history: 19-Oct-90 <chriswil> created. ! 7: | ! 8: \*---------------------------------------------------------------------------*/ ! 9: ! 10: #include <windows.h> ! 11: #include "gdidemo.h" ! 12: #include "bounce.h" ! 13: ! 14: ! 15: VOID XFormClear(PMYXFORM); ! 16: VOID XFormScale(PMYXFORM,int,int); ! 17: VOID XFormTrans(PMYXFORM,int,int); ! 18: VOID XFormPoint(PMYXFORM,LPPOINT); ! 19: ! 20: ! 21: /*---------------------------------------------------------------------------*\ ! 22: | CREATE BOUNCE WINDOW PROCEDURE ! 23: | ! 24: | created: 20-May-91 ! 25: | history: 20-May-91 <chriswil> created. ! 26: | ! 27: \*---------------------------------------------------------------------------*/ ! 28: HWND FAR CreateBounceWindow(HWND hWndClient, int nItem) ! 29: { ! 30: HANDLE hInstance; ! 31: MDICREATESTRUCT mcs; ! 32: ! 33: ! 34: hInstance = GETINSTANCE(hWndClient); ! 35: ! 36: /* ! 37: ** Initialize the MDI create struct for creation of the ! 38: ** test window. ! 39: */ ! 40: mcs.szClass = BOUNCECLASS; ! 41: mcs.szTitle = BOUNCETITLE; ! 42: mcs.hOwner = hInstance; ! 43: mcs.x = CW_USEDEFAULT; ! 44: mcs.y = CW_USEDEFAULT; ! 45: mcs.cx = CW_USEDEFAULT; ! 46: mcs.cy = CW_USEDEFAULT; ! 47: mcs.style = 0l; ! 48: mcs.lParam = (LONG)nItem; ! 49: ! 50: return((HWND)SendMessage(hWndClient,WM_MDICREATE,NULL,(LONG)(LPMDICREATESTRUCT)&mcs)); ! 51: } ! 52: ! 53: ! 54: /*---------------------------------------------------------------------------*\ ! 55: | BOUNCE WINDOW PROCEDURE ! 56: | ! 57: | created: 20-May-91 ! 58: | history: 20-May-91 <chriswil> created. ! 59: | ! 60: \*---------------------------------------------------------------------------*/ ! 61: LONG APIENTRY BounceProc(HWND hWnd, UINT wMsg, WPARAM wParam, LONG lParam) ! 62: { ! 63: switch(wMsg) ! 64: { ! 65: case WM_CREATE: ! 66: BounceCreateProc(hWnd); ! 67: break; ! 68: ! 69: case WM_MOVE: ! 70: BounceRefresh(hWnd); ! 71: break; ! 72: ! 73: case WM_COMMAND: ! 74: BounceCommandProc(hWnd,wParam,lParam); ! 75: break; ! 76: ! 77: case WM_TIMER: ! 78: BounceObjects(hWnd); ! 79: break; ! 80: ! 81: case WM_PAINT: ! 82: BouncePaintProc(hWnd); ! 83: break; ! 84: ! 85: case WM_DESTROY: ! 86: BounceDestroyProc(hWnd); ! 87: break; ! 88: ! 89: ! 90: default: ! 91: return(DefMDIChildProc(hWnd,wMsg,wParam,lParam)); ! 92: } ! 93: return(0l); ! 94: } ! 95: ! 96: ! 97: /*---------------------------------------------------------------------------*\ ! 98: | BOUNCE CREATE PROCEDURE ! 99: | ! 100: | created: 20-May-91 ! 101: | history: 20-May-91 <chriswil> created. ! 102: | ! 103: \*---------------------------------------------------------------------------*/ ! 104: BOOL BounceCreateProc(HWND hWnd) ! 105: { ! 106: PBOUNCEDATA pbd; ! 107: ! 108: ! 109: if(AllocWindowInfo(hWnd,sizeof(BOUNCEDATA))) ! 110: { ! 111: if(pbd = (PBOUNCEDATA)LockWindowInfo(hWnd)) ! 112: { ! 113: pbd->hBall1 = ballCreate(hWnd,20,20,RGB(255,0,0)); ! 114: pbd->hBall2 = ballCreate(hWnd,20,20,RGB(0,0,255)); ! 115: pbd->hBall3 = ballCreate(hWnd,20,20,RGB(0,255,0)); ! 116: pbd->hBall4 = ballCreate(hWnd,20,20,RGB(255,0,255)); ! 117: ! 118: UnlockWindowInfo(hWnd); ! 119: ! 120: SetTimer(hWnd,1,50,NULL); ! 121: return(TRUE); ! 122: } ! 123: FreeWindowInfo(hWnd); ! 124: } ! 125: return(FALSE); ! 126: } ! 127: ! 128: ! 129: /*---------------------------------------------------------------------------*\ ! 130: | BOUNCE COMMAND PROCEDURE ! 131: | ! 132: | created: 20-May-91 ! 133: | history: 20-May-91 <chriswil> created. ! 134: | ! 135: \*---------------------------------------------------------------------------*/ ! 136: BOOL BounceCommandProc(HWND hWnd, WPARAM wParam, LONG lParam) ! 137: { ! 138: hWnd = hWnd; ! 139: wParam = wParam; ! 140: lParam = lParam; ! 141: ! 142: return(TRUE); ! 143: } ! 144: ! 145: ! 146: /*---------------------------------------------------------------------------*\ ! 147: | BOUNCE PAINT PROCEDURE ! 148: | ! 149: | created: 20-May-91 ! 150: | history: 20-May-91 <chriswil> created. ! 151: | ! 152: \*---------------------------------------------------------------------------*/ ! 153: VOID BouncePaintProc(HWND hWnd) ! 154: { ! 155: HDC hDC; ! 156: PAINTSTRUCT ps; ! 157: ! 158: ! 159: if(hDC = BeginPaint(hWnd,&ps)) ! 160: EndPaint(hWnd,&ps); ! 161: ! 162: BounceRefresh(hWnd); ! 163: ! 164: return; ! 165: } ! 166: ! 167: ! 168: /*---------------------------------------------------------------------------*\ ! 169: | BOUNCE DESTROY PROCEDURE ! 170: | ! 171: | created: 20-May-91 ! 172: | history: 20-May-91 <chriswil> created. ! 173: | ! 174: \*---------------------------------------------------------------------------*/ ! 175: VOID BounceDestroyProc(HWND hWnd) ! 176: { ! 177: PBOUNCEDATA pbd; ! 178: ! 179: ! 180: KillTimer(hWnd,1); ! 181: if(pbd = (PBOUNCEDATA)LockWindowInfo(hWnd)) ! 182: { ! 183: ballDestroy(pbd->hBall1); ! 184: ballDestroy(pbd->hBall2); ! 185: ballDestroy(pbd->hBall3); ! 186: ballDestroy(pbd->hBall4); ! 187: ! 188: UnlockWindowInfo(hWnd); ! 189: } ! 190: FreeWindowInfo(hWnd); ! 191: return; ! 192: } ! 193: ! 194: ! 195: /*---------------------------------------------------------------------------*\ ! 196: | BOUNCE REFRESH ! 197: | ! 198: | created: 20-May-91 ! 199: | history: 20-May-91 <chriswil> created. ! 200: | ! 201: \*---------------------------------------------------------------------------*/ ! 202: VOID BounceRefresh(HWND hWnd) ! 203: { ! 204: PBOUNCEDATA pbd; ! 205: RECT rect; ! 206: HDC hDC; ! 207: POINT pDimensions; ! 208: int xDirection,yDirection; ! 209: ! 210: ! 211: if(pbd = (PBOUNCEDATA)LockWindowInfo(hWnd)) ! 212: { ! 213: if(hDC = GetDC(hWnd)) ! 214: { ! 215: GetClientRect(hWnd,&rect); ! 216: FillRect(hDC,&rect,GETCLASSBRUSH(hWnd)); ! 217: ! 218: xDirection = ((lRandom() % 5)+5); ! 219: yDirection = ((lRandom() % 5)+5); ! 220: ballSetPosition(pbd->hBall1,0,0); ! 221: ballSetDirection(pbd->hBall1,xDirection,yDirection); ! 222: ! 223: ! 224: ballGetDimensions(pbd->hBall2,&pDimensions); ! 225: ballSetPosition(pbd->hBall2,rect.right-pDimensions.x,0); ! 226: xDirection = -((lRandom() % 5)+5); ! 227: yDirection = ((lRandom() % 5)+5); ! 228: ballSetDirection(pbd->hBall2,xDirection,yDirection); ! 229: ! 230: ! 231: ballGetDimensions(pbd->hBall3,&pDimensions); ! 232: ballSetPosition(pbd->hBall3,0,rect.bottom-pDimensions.y); ! 233: xDirection = ((lRandom() % 5)+5); ! 234: yDirection = -((lRandom() % 5)+5); ! 235: ballSetDirection(pbd->hBall3,xDirection,yDirection); ! 236: ! 237: ! 238: ballGetDimensions(pbd->hBall4,&pDimensions); ! 239: ballSetPosition(pbd->hBall4,rect.right-pDimensions.x,rect.bottom-pDimensions.y); ! 240: xDirection = -((lRandom() % 5)+5); ! 241: yDirection = -((lRandom() % 5)+5); ! 242: ballSetDirection(pbd->hBall4,xDirection,yDirection); ! 243: ! 244: ! 245: ballBounce(pbd->hBall1); ! 246: ballBounce(pbd->hBall2); ! 247: ballBounce(pbd->hBall3); ! 248: ballBounce(pbd->hBall4); ! 249: ! 250: ReleaseDC(hWnd,hDC); ! 251: } ! 252: UnlockWindowInfo(hWnd); ! 253: } ! 254: return; ! 255: } ! 256: ! 257: ! 258: ! 259: VOID BounceObjects(HWND hWnd) ! 260: { ! 261: PBOUNCEDATA pbd; ! 262: ! 263: ! 264: if(pbd = (PBOUNCEDATA)LockWindowInfo(hWnd)) ! 265: { ! 266: /* ! 267: ** Determine if the balls hit any of the edges of the display. If ! 268: ** they do, then these functions reset their position to something ! 269: ** more desireable and re-do their direction. ! 270: */ ! 271: CheckEdgePosition(hWnd,pbd->hBall1); ! 272: CheckEdgePosition(hWnd,pbd->hBall2); ! 273: CheckEdgePosition(hWnd,pbd->hBall3); ! 274: CheckEdgePosition(hWnd,pbd->hBall4); ! 275: ! 276: ballBounce(pbd->hBall1); ! 277: ballBounce(pbd->hBall2); ! 278: ballBounce(pbd->hBall3); ! 279: ballBounce(pbd->hBall4); ! 280: ! 281: ! 282: UnlockWindowInfo(hWnd); ! 283: } ! 284: return; ! 285: } ! 286: ! 287: ! 288: VOID CheckEdgePosition(HWND hWnd, HANDLE hBall) ! 289: { ! 290: POINT pPos,pDir,pDim; ! 291: int xNewPos,yNewPos,xNewDir,yNewDir; ! 292: RECT rect; ! 293: ! 294: ! 295: ! 296: ballGetPosition(hBall,&pPos); ! 297: ballGetDirection(hBall,&pDir); ! 298: ballGetDimensions(hBall,&pDim); ! 299: ! 300: GetClientRect(hWnd,&rect); ! 301: ! 302: ! 303: /* ! 304: ** Check each edge of the client rectagle. If the ball goes past the ! 305: ** boundries, reset the position and give it a new direction. ! 306: */ ! 307: xNewDir = pDir.x; ! 308: yNewDir = pDir.y; ! 309: xNewPos = pPos.x+pDir.x; ! 310: yNewPos = pPos.y+pDir.y; ! 311: ! 312: if(xNewPos < rect.left) ! 313: { ! 314: xNewDir = ((lRandom() % 5)+5); ! 315: ballSetPosition(hBall,rect.left,pPos.y); ! 316: } ! 317: if((xNewPos+pDim.x) > rect.right) ! 318: { ! 319: xNewDir = -((lRandom() % 5)+5); ! 320: ballSetPosition(hBall,rect.right-pDim.x,pPos.y); ! 321: } ! 322: if(yNewPos < rect.top) ! 323: { ! 324: yNewDir = ((lRandom() % 5)+5); ! 325: ballSetPosition(hBall,pPos.x,rect.top); ! 326: } ! 327: if((yNewPos+pDim.y) > rect.bottom) ! 328: { ! 329: yNewDir = -((lRandom() % 5)+5); ! 330: ballSetPosition(hBall,pPos.x,rect.bottom-pDim.y); ! 331: } ! 332: ballSetDirection(hBall,xNewDir,yNewDir); ! 333: ! 334: return; ! 335: } ! 336: ! 337: ! 338: /*---------------------------------------------------------------------------*\ ! 339: | CLEAR XFORM ! 340: | ! 341: | created: 31-Oct-90 ! 342: | history: 31-Oct-90 <chriswil> created. ! 343: | ! 344: \*---------------------------------------------------------------------------*/ ! 345: VOID XFormClear(PMYXFORM pXForm) ! 346: { ! 347: int Row,Col; ! 348: ! 349: ! 350: for(Row=0; Row < 3; Row++) ! 351: for(Col=0; Col < 3; Col++) ! 352: if(Row == Col) ! 353: pXForm->xForm[Row][Col] = 1; ! 354: else ! 355: pXForm->xForm[Row][Col] = 0; ! 356: return; ! 357: } ! 358: ! 359: ! 360: /*---------------------------------------------------------------------------*\ ! 361: | XFORM SCALE ! 362: | ! 363: | created: 31-Oct-90 ! 364: | history: 31-Oct-90 <chriswil> created. ! 365: | ! 366: \*---------------------------------------------------------------------------*/ ! 367: VOID XFormScale(PMYXFORM pXForm, int xScale, int yScale) ! 368: { ! 369: int idx; ! 370: ! 371: ! 372: for(idx=0; idx < 3; idx++) ! 373: { ! 374: pXForm->xForm[idx][0] = pXForm->xForm[idx][0] * xScale; ! 375: pXForm->xForm[idx][1] = pXForm->xForm[idx][1] * yScale; ! 376: } ! 377: return; ! 378: } ! 379: ! 380: ! 381: ! 382: /*---------------------------------------------------------------------------*\ ! 383: | ! 384: | created: 31-Oct-90 ! 385: | history: 31-Oct-90 <chriswil> created. ! 386: | ! 387: \*---------------------------------------------------------------------------*/ ! 388: VOID XFormTrans(PMYXFORM pXForm, int xTrans, int yTrans) ! 389: { ! 390: pXForm->xForm[2][0] = pXForm->xForm[2][0] + xTrans; ! 391: pXForm->xForm[2][1] = pXForm->xForm[2][1] + yTrans; ! 392: ! 393: return; ! 394: } ! 395: ! 396: ! 397: ! 398: /*---------------------------------------------------------------------------*\ ! 399: | ! 400: | created: 31-Oct-90 ! 401: | history: 31-Oct-90 <chriswil> created. ! 402: | ! 403: \*---------------------------------------------------------------------------*/ ! 404: VOID XFormPoint(PMYXFORM pXForm, LPPOINT pPoint) ! 405: { ! 406: int x,y; ! 407: ! 408: ! 409: x = (pXForm->xForm[0][0] * pPoint->x) + (pXForm->xForm[1][0] * pPoint->y) + pXForm->xForm[2][0]; ! 410: y = (pXForm->xForm[0][1] * pPoint->x) + (pXForm->xForm[1][1] * pPoint->y) + pXForm->xForm[2][1]; ! 411: ! 412: pPoint->x = x; ! 413: pPoint->y = y; ! 414: ! 415: return; ! 416: } ! 417: ! 418: ! 419: /* ! 420: ** ------------------------------- ! 421: ** ------------------------------- ! 422: ** ------------------------------- ! 423: */ ! 424: ! 425: HANDLE ballCreate(HWND hWnd, int nWidth, int nHeight, COLORREF crColor) ! 426: { ! 427: HANDLE hBall; ! 428: PBALLDATA pbd; ! 429: ! 430: if(hBall = LocalAlloc(LHND,sizeof(BALLDATA))) ! 431: { ! 432: if(pbd = (PBALLDATA)LocalLock(hBall)) ! 433: { ! 434: pbd->hWnd = hWnd; ! 435: pbd->nWidth = nWidth; ! 436: pbd->nHeight = nHeight; ! 437: pbd->xDirection = 0; ! 438: pbd->yDirection = 0; ! 439: pbd->bNewPosition = FALSE; ! 440: pbd->xPosition = 0; ! 441: pbd->yPosition = 0; ! 442: pbd->crColor = crColor; ! 443: XFormClear(&pbd->xForm); ! 444: ! 445: LocalUnlock(hBall); ! 446: return(hBall); ! 447: } ! 448: LocalFree(hBall); ! 449: } ! 450: return(NULL); ! 451: } ! 452: ! 453: ! 454: BOOL ballDestroy(HANDLE hBall) ! 455: { ! 456: if(LocalFree(hBall)) ! 457: return(FALSE); ! 458: return(TRUE); ! 459: } ! 460: ! 461: ! 462: VOID ballBounce(HANDLE hBall) ! 463: { ! 464: PBALLDATA pbd; ! 465: HDC hDC; ! 466: HBRUSH hBrush; ! 467: POINT pOrg,pExt; ! 468: HRGN hTmp,hOld,hNew; ! 469: ! 470: ! 471: if(pbd = (PBALLDATA)LocalLock(hBall)) ! 472: { ! 473: /* ! 474: ** Create old ball object. ! 475: */ ! 476: pOrg.x = 0; ! 477: pOrg.y = 0; ! 478: pExt.x = pbd->nWidth; ! 479: pExt.y = pbd->nHeight; ! 480: XFormPoint(&pbd->xForm,&pOrg); ! 481: XFormPoint(&pbd->xForm,&pExt); ! 482: hOld = CreateEllipticRgn(pOrg.x,pOrg.y,pExt.x,pExt.y); ! 483: ! 484: ! 485: /* ! 486: ** Create new ball object. ! 487: */ ! 488: if(pbd->bNewPosition) ! 489: { ! 490: pbd->bNewPosition = FALSE; ! 491: XFormClear(&pbd->xForm); ! 492: XFormTrans(&pbd->xForm,pbd->xPosition,pbd->yPosition); ! 493: } ! 494: else ! 495: XFormTrans(&pbd->xForm,pbd->xDirection,pbd->yDirection); ! 496: pOrg.x = 0; ! 497: pOrg.y = 0; ! 498: pExt.x = pbd->nWidth; ! 499: pExt.y = pbd->nHeight; ! 500: XFormPoint(&pbd->xForm,&pOrg); ! 501: XFormPoint(&pbd->xForm,&pExt); ! 502: hNew = CreateEllipticRgn(pOrg.x,pOrg.y,pExt.x,pExt.y); ! 503: ! 504: ! 505: ! 506: if(hDC = GetDC(pbd->hWnd)) ! 507: { ! 508: hTmp = CreateRectRgn(1,1,2,2); ! 509: CombineRgn(hTmp,hOld,hNew,RGN_DIFF); ! 510: FillRgn(hDC,hTmp,GETCLASSBRUSH(pbd->hWnd)); ! 511: ! 512: hBrush = CreateSolidBrush(pbd->crColor); ! 513: FillRgn(hDC,hNew,hBrush); ! 514: DeleteObject(hBrush); ! 515: ! 516: ReleaseDC(pbd->hWnd,hDC); ! 517: ! 518: DeleteObject(hTmp); ! 519: } ! 520: ! 521: DeleteObject(hOld); ! 522: DeleteObject(hNew); ! 523: ! 524: LocalUnlock(hBall); ! 525: } ! 526: return; ! 527: } ! 528: ! 529: ! 530: BOOL ballGetDimensions(HANDLE hBall, LPPOINT pDimension) ! 531: { ! 532: PBALLDATA pbd; ! 533: BOOL bOK; ! 534: ! 535: ! 536: bOK = FALSE; ! 537: if(pbd = (PBALLDATA)LocalLock(hBall)) ! 538: { ! 539: pDimension->x = pbd->nWidth; ! 540: pDimension->y = pbd->nHeight; ! 541: ! 542: bOK = TRUE; ! 543: LocalUnlock(hBall); ! 544: } ! 545: return(bOK); ! 546: } ! 547: ! 548: ! 549: BOOL ballSetDimensions(HANDLE hBall, int nWidth, int nHeight) ! 550: { ! 551: PBALLDATA pbd; ! 552: BOOL bOK; ! 553: ! 554: ! 555: bOK = FALSE; ! 556: if(pbd = (PBALLDATA)LocalLock(hBall)) ! 557: { ! 558: pbd->nWidth = nWidth; ! 559: pbd->nHeight = nHeight; ! 560: ! 561: bOK = TRUE; ! 562: LocalUnlock(hBall); ! 563: } ! 564: return(bOK); ! 565: } ! 566: ! 567: ! 568: BOOL ballGetDirection(HANDLE hBall, LPPOINT pDirection) ! 569: { ! 570: PBALLDATA pbd; ! 571: BOOL bOK; ! 572: ! 573: ! 574: bOK = FALSE; ! 575: if(pbd = (PBALLDATA)LocalLock(hBall)) ! 576: { ! 577: pDirection->x = pbd->xDirection; ! 578: pDirection->y = pbd->yDirection; ! 579: ! 580: bOK = TRUE; ! 581: LocalUnlock(hBall); ! 582: } ! 583: return(bOK); ! 584: } ! 585: ! 586: ! 587: BOOL ballSetDirection(HANDLE hBall, int xDirection, int yDirection) ! 588: { ! 589: PBALLDATA pbd; ! 590: BOOL bOK; ! 591: ! 592: ! 593: bOK = FALSE; ! 594: if(pbd = (PBALLDATA)LocalLock(hBall)) ! 595: { ! 596: pbd->xDirection = xDirection; ! 597: pbd->yDirection = yDirection; ! 598: ! 599: bOK = TRUE; ! 600: LocalUnlock(hBall); ! 601: } ! 602: return(bOK); ! 603: } ! 604: ! 605: ! 606: BOOL ballGetPosition(HANDLE hBall, LPPOINT pPosition) ! 607: { ! 608: PBALLDATA pbd; ! 609: BOOL bOK; ! 610: POINT pOrg; ! 611: ! 612: ! 613: bOK = FALSE; ! 614: if(pbd = (PBALLDATA)LocalLock(hBall)) ! 615: { ! 616: pOrg.x = 0; ! 617: pOrg.y = 0; ! 618: XFormPoint(&pbd->xForm,&pOrg); ! 619: ! 620: pPosition->x = pOrg.x; ! 621: pPosition->y = pOrg.y; ! 622: ! 623: bOK = TRUE; ! 624: LocalUnlock(hBall); ! 625: } ! 626: return(bOK); ! 627: } ! 628: ! 629: ! 630: BOOL ballSetPosition(HANDLE hBall, int x, int y) ! 631: { ! 632: PBALLDATA pbd; ! 633: BOOL bOK; ! 634: ! 635: ! 636: bOK = FALSE; ! 637: if(pbd = (PBALLDATA)LocalLock(hBall)) ! 638: { ! 639: pbd->bNewPosition = TRUE; ! 640: pbd->xPosition = x; ! 641: pbd->yPosition = y; ! 642: ! 643: bOK = TRUE; ! 644: LocalUnlock(hBall); ! 645: } ! 646: return(bOK); ! 647: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.