home *** CD-ROM | disk | FTP | other *** search
/ Windows Shareware GOLD / NuclearComputingVol3No1.cdr / games / f1196 / pool.c < prev    next >
C/C++ Source or Header  |  1990-09-08  |  13KB  |  392 lines

  1. /***************************************************************
  2.  * POOL.C
  3.  * MSL 9/3/90
  4.  * Copyright (c) 1990 Mark Lutton
  5.  * All Rights Reserved
  6.  */
  7.  
  8. #ifdef _lint
  9. #define NOREF(a) a = a
  10. #else
  11. #define NOREF(a) a
  12. #endif
  13.  
  14. #define NOCOMM
  15. #define NOMINMAX
  16.  
  17. #include <windows.h>
  18. #include <stdlib.h>     /* for rand()       */
  19. #include "pool.h"
  20.  
  21.  
  22.  
  23. HANDLE hInst;                       /* Global Instance Handle  */
  24.  
  25. long FAR PASCAL MainFormWndProc(HWND, unsigned, WORD, LONG);
  26.  
  27. WORD wAlertTimerId;     /* ID of Alert Timer. */
  28. WORD wTimerTicks=1;    /* Timer interval, initially 1000 times/second. */
  29. WORD wFactor=50;            /* How many points per interval.   */
  30.  
  31. WORD wTableWidth=345;
  32. WORD wTableHeight=196;
  33. WORD wPoolStartX=0;
  34. WORD wPoolStartY=0;
  35. int nXDir = 1;
  36. int nYDir = 1;
  37. int nX, nY;
  38. RECT mainrect;
  39. RECT winrect;
  40. BOOL fReverse = FALSE;
  41.  
  42. WORD wOptionsWindowHeight;
  43. WORD wOptionsWindowWidth;
  44. WORD wOptionsPoolStartX;
  45. WORD wOptionsPoolStartY;
  46. WORD wOptionsPoolTableWidth;
  47. WORD wOptionsPoolTableHeight;
  48. WORD wOptionsPoolSpeed;
  49.  
  50. BOOL fRun = TRUE;
  51.  
  52. char szAppName [] = "Pool";
  53.  
  54. VOID FAR PASCAL PoolTimerTick(HWND hWnd, WORD wMsg, int nIDEvent, DWORD dwTime);
  55. BOOL FAR PASCAL OptionsDlgProc(HWND hDlg, unsigned iMessage,
  56.         WORD wParam, LONG lParam);
  57. BOOL PoolTimerInit(HWND hWnd);
  58. VOID PoolTimerKill(HWND hWnd);
  59. VOID NewOptions(HWND hWnd);
  60.  
  61.  
  62. /******************************************************************
  63.  * WinMain()
  64.  */
  65. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
  66.     LPSTR CmdLine, int CmdShow)
  67.     {
  68.     HWND hWnd;
  69.     MSG msg;
  70.  
  71.     NOREF(CmdLine);
  72.     NOREF(CmdShow);
  73.  
  74.     hInst = hInstance;
  75.  
  76.     if (!hPrevInstance) {
  77.         WNDCLASS WndClass;
  78.         WndClass.lpszClassName  = szAppName;
  79.         WndClass.hInstance      = hInstance;
  80.         WndClass.lpfnWndProc    = MainFormWndProc;
  81.         WndClass.style          = CS_HREDRAW | CS_VREDRAW;
  82.         WndClass.hbrBackground  = GetStockObject(WHITE_BRUSH);
  83.         WndClass.hIcon          = NULL;
  84.         WndClass.lpszMenuName   = "PoolMenu";
  85.         WndClass.hCursor        = LoadCursor(NULL,IDC_ARROW);
  86.         WndClass.cbClsExtra     = NULL;
  87.         WndClass.cbWndExtra     = NULL;
  88.         if (!RegisterClass(&WndClass))
  89.             return(NULL);
  90.         }
  91.  
  92.     hWnd = CreateWindow(szAppName,             /* Window class name        */
  93.                         szAppName,     /* Window caption           */
  94.                         WS_OVERLAPPEDWINDOW,/* window style             */
  95.                         0,                  /* initial x position       */
  96.                         0,                  /* initial y position       */
  97.                         CW_USEDEFAULT,      /* initial x state          */
  98.                         0,                  /* initial y state          */
  99.                         NULL,               /* parent window handle     */
  100.                         NULL,               /* window menu handle       */
  101.                         hInstance,          /* program instance handle  */
  102.                         NULL);              /* create parameters        */
  103.     if (!hWnd)
  104.         return NULL;
  105.  
  106.         /* Application initialization. */
  107.     nX = (int) wPoolStartX;
  108.     nY = (int) wPoolStartY;
  109.  
  110.        
  111.     while (GetMessage (&msg, NULL, 0, 0)){
  112.         (VOID) TranslateMessage (&msg) ;
  113.         (VOID) DispatchMessage (&msg) ;
  114.         }
  115.     return ((int)msg.wParam);
  116.     }
  117.  
  118.  
  119.  
  120. long FAR PASCAL MainFormWndProc(hWnd, message, wParam, lParam)
  121.   HWND hWnd;
  122.   unsigned message;
  123.   WORD wParam;
  124.   LONG lParam;
  125.   {
  126.   static FARPROC  lpfnPoolOptionsDlg;
  127.   int nRetval;
  128.   
  129.   switch (message){
  130.     case WM_CREATE:
  131.             /* Set up pleasing initial options. */
  132.         wOptionsWindowWidth = 396;
  133.         wOptionsWindowHeight = 245;
  134.         wOptionsPoolTableWidth = 345;
  135.         wOptionsPoolTableHeight = 196;
  136.         wOptionsPoolStartX = 297;
  137.         wOptionsPoolStartY = 158;
  138.         wOptionsPoolSpeed = 50;
  139.         NewOptions(hWnd);
  140.         
  141.         lpfnPoolOptionsDlg = MakeProcInstance(OptionsDlgProc, hInst);
  142.         (VOID)PoolTimerInit(hWnd);
  143.         (VOID)ShowWindow(hWnd,SW_SHOWNORMAL);
  144.         UpdateWindow(hWnd);
  145.         break;
  146.         
  147.     case WM_COMMAND:
  148.         switch (wParam) {
  149.         case IDM_OPTIONS:
  150.             fRun = FALSE;       /* Freeze while we set options. */
  151.             GetClientRect(hWnd, &winrect);
  152.             nRetval = DialogBox(hInst, "OPTIONS", hWnd, lpfnPoolOptionsDlg);
  153.             if (nRetval == 1) {
  154.                 NewOptions(hWnd);
  155.                 }
  156.             fRun = TRUE;
  157.             break;
  158.         case IDM_FREEZE:
  159.             fRun = !fRun;           /* Toggle freeze/unfreeze. */
  160.             break;
  161.         case IDM_REVERSE:
  162.             fRun = FALSE;
  163.             fReverse = TRUE;
  164.             fRun = TRUE;
  165.             break;
  166.         case IDM_EXIT:
  167.             fRun = FALSE;
  168.             if (MessageBox(hWnd, "End the program?",
  169.                     "Pool", MB_OKCANCEL) == IDOK) {
  170.                 (VOID) SendMessage(hWnd, WM_CLOSE, 0, 0L);
  171.                 }
  172.             fRun = TRUE;
  173.             break;
  174.         case IDM_ABOUT:
  175.             fRun = FALSE;
  176.             (VOID) MessageBox(hWnd, "Windows Pool 1.0 by Mark Lutton, 9/3/90\n"
  177.                     "Thanks to Tim Peters and Ken Marks for the ideas.\n"
  178.                     "Copyright (c) 1990 Mark Lutton.\nAll rights reserved.",
  179.                     szAppName, MB_ICONASTERISK | MB_OK);
  180.             fRun = TRUE;
  181.             break;
  182.         default:
  183.             return DefWindowProc(hWnd, message, wParam, lParam);
  184.             }
  185.         break;
  186.         
  187.     case WM_ENDSESSION:
  188.         PoolTimerKill(hWnd);
  189.         (VOID)DestroyWindow(hWnd);
  190.         break;
  191.     case WM_DESTROY:
  192.         PostQuitMessage(0);
  193.         break;
  194.     default:return(DefWindowProc(hWnd,message,wParam,lParam));
  195.     }
  196.   return (NULL);
  197.   }
  198.  
  199.  
  200.         /* Function to start up the timer.        */
  201. BOOL PoolTimerInit(HWND hWnd)
  202. {
  203.     FARPROC lpfnTimerProc;
  204.  
  205.     lpfnTimerProc = MakeProcInstance(PoolTimerTick, hInst);
  206.     wAlertTimerId = SetTimer(hWnd, (short)hWnd, wTimerTicks, lpfnTimerProc);
  207.     return (wAlertTimerId != 0);
  208.  
  209. }
  210.  
  211. VOID PoolTimerKill(HWND hWnd)
  212. {
  213.     (VOID) KillTimer(hWnd, (short)hWnd);
  214. }
  215.  
  216.  
  217.         /* Timer tick -- draw one dot (4-way symmetrical) and then */
  218.         /* set next x/y values.                                    */
  219.         /* Note that this application does not respond to WM_PAINT */
  220.         /* messages; we do not save a picture of the window anywhere. */
  221.         /* (We could clear the screen in response to WM_PAINT.)       */
  222.  
  223. VOID FAR PASCAL PoolTimerTick(HWND hWnd, WORD wMsg, int nIDEvent, DWORD dwTime)
  224. {
  225.     HDC hDC;
  226.     unsigned long ulPixel;
  227.     static unsigned long XOR_VALUE = 0x00FFFFFFUL;
  228.     WORD i;
  229.     static int randcount = 0;
  230.  
  231.  
  232.     NOREF(wMsg);
  233.     NOREF(nIDEvent);
  234.     NOREF(dwTime);
  235.  
  236.     if (!fRun) 
  237.         return;
  238.  
  239.         /* Every 1/10 of a second, advance the random number generator. */
  240.     if (++randcount >= 100) {
  241.         randcount = 0;
  242.         (VOID)rand();
  243.         }
  244.  
  245.         
  246.         /* Draw. */
  247.     hDC = GetDC(hWnd);
  248.  
  249.     GetClientRect(hWnd, &mainrect);
  250.  
  251.     for (i=wFactor; i; i--) {
  252.         ulPixel = GetPixel(hDC, nX, nY) ^ XOR_VALUE;
  253.         (VOID)SetPixel(hDC, nX, nY, ulPixel);
  254.         ulPixel = GetPixel(hDC, nX, mainrect.bottom - nY) ^ XOR_VALUE;
  255.         (VOID)SetPixel(hDC, nX, mainrect.bottom - nY, ulPixel);
  256.         ulPixel = GetPixel(hDC, mainrect.right - nX, nY) ^ XOR_VALUE;
  257.         (VOID)SetPixel(hDC, mainrect.right - nX, nY, ulPixel);
  258.         ulPixel = GetPixel(hDC, mainrect.right - nX, mainrect.bottom - nY) ^ XOR_VALUE;
  259.         (VOID)SetPixel(hDC, mainrect.right - nX, mainrect.bottom - nY, ulPixel);
  260.  
  261.         if (fReverse) {
  262.             nXDir = 0 - nXDir;  /* Next time through, will undo pixel */
  263.             nYDir = 0 - nYDir;  /* it just did and not leave a dropping. */
  264.             fReverse = FALSE;
  265.             }
  266.         else {
  267.             nX += nXDir;
  268.             if (nX > (int)wTableWidth || nX < 0) {
  269.                 nXDir = 0 - nXDir;
  270.                 nX += nXDir;
  271.                 nX += nXDir;
  272.                 }
  273.             nY += nYDir;
  274.             if (nY > (int)wTableHeight || nY < 0) {
  275.                 nYDir = 0 - nYDir;
  276.                 nY += nYDir;
  277.                 nY += nYDir;
  278.                 }
  279.             }
  280.         }
  281.  
  282.     (VOID)ReleaseDC(hWnd, hDC);
  283. }
  284.  
  285.     /* Options dialog.     */
  286. BOOL FAR PASCAL OptionsDlgProc(HWND hDlg, unsigned iMessage,
  287.         WORD wParam, LONG lParam)
  288. {
  289.     WORD wRand, wTemp;
  290.     
  291.     NOREF (lParam);
  292.     
  293.     switch (iMessage) {
  294.     case WM_INITDIALOG:
  295.         SetDlgItemInt(hDlg, OD_EDIT_WINWIDTH,
  296.                      (WORD)(winrect.right-winrect.left), 0);
  297.         SetDlgItemInt(hDlg, OD_EDIT_WINHEIGHT, 
  298.                     (WORD)(winrect.bottom-winrect.top), 0);
  299.         SetDlgItemInt(hDlg, OD_EDIT_STARTX, wPoolStartX, 0);
  300.         SetDlgItemInt(hDlg, OD_EDIT_STARTY, wPoolStartY, 0);
  301.         SetDlgItemInt(hDlg, OD_EDIT_TABLEWIDTH, wTableWidth, 0);
  302.         SetDlgItemInt(hDlg, OD_EDIT_TABLEHEIGHT, wTableHeight, 0);
  303.         SetDlgItemInt(hDlg, OD_EDIT_SPEED, wFactor, 0);
  304.         return TRUE;
  305.  
  306.     case WM_COMMAND:
  307.         switch (wParam) {
  308.         case OD_OK:
  309.             wOptionsWindowHeight = GetDlgItemInt(hDlg, OD_EDIT_WINHEIGHT, NULL, FALSE);
  310.             wOptionsWindowWidth = GetDlgItemInt(hDlg, OD_EDIT_WINWIDTH, NULL, FALSE);
  311.             wOptionsPoolStartX = GetDlgItemInt(hDlg, OD_EDIT_STARTX, NULL, FALSE);
  312.             wOptionsPoolStartY = GetDlgItemInt(hDlg, OD_EDIT_STARTY, NULL, FALSE);
  313.             wOptionsPoolTableWidth = GetDlgItemInt(hDlg, OD_EDIT_TABLEWIDTH, NULL, FALSE);
  314.             wOptionsPoolTableHeight = GetDlgItemInt(hDlg, OD_EDIT_TABLEHEIGHT, NULL, FALSE);
  315.             wOptionsPoolSpeed = GetDlgItemInt(hDlg, OD_EDIT_SPEED, NULL, FALSE);
  316.             EndDialog(hDlg, 1);
  317.             break;
  318.  
  319.         case OD_CANCEL:
  320.             EndDialog(hDlg, 0);
  321.             break;
  322.  
  323.         case OD_RANDOM:
  324.                 /* Put 4 random numbers into 4 parameters. */
  325.             wOptionsWindowHeight = GetDlgItemInt(hDlg, OD_EDIT_WINHEIGHT, NULL, FALSE);
  326.             wOptionsWindowWidth = GetDlgItemInt(hDlg, OD_EDIT_WINWIDTH, NULL, FALSE);
  327.                 /* Pool table dimensions are at least half the window */
  328.                 /* size to force some overlap.                        */
  329.                 /* Start the ball somewhere within the window.        */
  330.             wTemp = wOptionsWindowWidth / 2;
  331.             wRand = ((WORD)rand()) % wTemp + wTemp;
  332.             SetDlgItemInt(hDlg, OD_EDIT_TABLEWIDTH, wRand, 0);
  333.             wRand = ((WORD)rand()) % wRand;
  334.             SetDlgItemInt(hDlg, OD_EDIT_STARTX, wRand, 0);
  335.             wTemp = wOptionsWindowHeight / 2;
  336.             wRand = ((WORD)rand()) % wTemp + wTemp;
  337.             SetDlgItemInt(hDlg, OD_EDIT_TABLEHEIGHT, wRand, 0);
  338.             wRand = ((WORD)rand()) % wRand;
  339.             SetDlgItemInt(hDlg, OD_EDIT_STARTY, wRand, 0);
  340.             break;
  341.  
  342.         default:
  343.             return FALSE;
  344.             }
  345.         break;
  346.         
  347.     default:
  348.         return FALSE;
  349.         }
  350.  
  351.     return TRUE;
  352.  
  353. }
  354.  
  355.         /* OK, set the new options. */
  356. VOID NewOptions(HWND hWnd)
  357. {
  358.     RECT NewRect;
  359.     int  nYCaption, nYMenu, nYFrame, nXFrame;
  360.  
  361.  
  362.     wFactor = wOptionsPoolSpeed;
  363.     wPoolStartX = wOptionsPoolStartX;
  364.     wPoolStartY = wOptionsPoolStartY;
  365.     wTableHeight = wOptionsPoolTableHeight;
  366.     wTableWidth = wOptionsPoolTableWidth;
  367.  
  368.  
  369.         /* Convert client rect to window rect.     */
  370.     nYCaption = GetSystemMetrics(SM_CYCAPTION);
  371.     nYMenu = GetSystemMetrics(SM_CYMENU);
  372.     nYFrame = GetSystemMetrics(SM_CYFRAME);
  373.     nXFrame = GetSystemMetrics(SM_CXFRAME);
  374.     GetWindowRect(hWnd, &NewRect);
  375.  
  376.         /* This will force repaint. */
  377.     MoveWindow(hWnd, NewRect.left, NewRect.top, 
  378.             (int)wOptionsWindowWidth + nXFrame + nXFrame,
  379.             (int)wOptionsWindowHeight + nYFrame + nYCaption +
  380.                                 nYMenu + nYFrame, 
  381.             TRUE);
  382.     nXDir = 1;
  383.     nYDir = 1;
  384.     nX = (int) wPoolStartX;
  385.     nY = (int) wPoolStartY;
  386.     InvalidateRect(hWnd, NULL, TRUE);
  387.  
  388. }
  389.  
  390.  
  391.     /* End of POOL.C        */
  392.