home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / PJ8_3.ZIP / WINCEL.C < prev    next >
C/C++ Source or Header  |  1990-02-08  |  7KB  |  295 lines

  1. /* 
  2.  * Resident segment for the Windows cellular automaton demo
  3.  *
  4.  * Written by Bill Hall
  5.  * 3665 Benton Street, #66
  6.  * Santa Clara, CA 95051
  7.  *
  8.  */
  9.  
  10. #define NOCOMM
  11. #define NOKANJI
  12. #define NOATOM
  13. #define NOSOUND
  14. #define NOMINMAX
  15. #include <windows.h>
  16. #include <string.h>
  17. #include <stdlib.h>
  18.  
  19. /* dialog box manifests */
  20. #include "wcldlg.h"
  21.  
  22. /* all global variables are declared in this module */
  23. #define EXTERN
  24. #include "wincel.h"
  25.  
  26. #define MAXPOINTS  50        /* maximum number of points */
  27.  
  28. BYTE new[MAXPOINTS][MAXPOINTS];        /* cells */
  29. BYTE old[MAXPOINTS][MAXPOINTS];
  30.  
  31. static BOOL go;            /* start, stop */
  32. static BOOL start;        /* program has been started */
  33.  
  34. /* local function declarations */
  35. static void NEAR MainWndPaint(HWND hWnd, HDC hDC);
  36. static void NEAR DoPeekMessage(void);
  37. static void NEAR InitializePoints(void);
  38. static void NEAR Neighbor(int pos,register int i,register int j,int *k,int *l);
  39. static void NEAR EatPoints(void);
  40. static void NEAR ShowRect(HDC hDC, int i, int j, int index);
  41. static void NEAR WndCommand(HWND hWnd, WORD id);
  42.  
  43. /* Entry point for program */
  44. int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
  45. HANDLE hInstance, hPrevInstance;
  46. LPSTR lpszCmdLine;
  47. int cmdShow;
  48. {
  49.  
  50.     MSG msg;
  51.  
  52.     // If initialization is not successful then exit.
  53.     if (!InitProgram(hInstance,hPrevInstance, lpszCmdLine, cmdShow))
  54.     return FALSE;
  55.  
  56.     // stay in this loop until window is destroyed.
  57.     while (TRUE) {
  58.         if (PeekMessage((LPMSG)&msg,NULL,0,0,PM_REMOVE)) {
  59.         if (msg.message == WM_QUIT)
  60.         break;
  61.         TranslateMessage((LPMSG)&msg); // translate keydown/up to chars.
  62.         DispatchMessage((LPMSG)&msg);  // call the appropriate window proc.
  63.     }
  64.     else if (go) {
  65.         EatPoints();    // change states of points.
  66.             PostMessage(hWndMain, WM_USER, 0, 0L); // copy and display states.
  67.     }
  68.     }
  69.     return (int)msg.wParam;    // terminate program.
  70. }
  71.  
  72. /* All messages are processed here */
  73. long FAR PASCAL MainWndProc(hWnd,message,wParam,lParam)
  74. HWND hWnd;
  75. unsigned message;
  76. WORD wParam;
  77. LONG lParam;
  78. {
  79.  
  80.     PAINTSTRUCT ps;
  81.  
  82.     switch(message) {
  83.  
  84.     // display points if appropriate and reinitialize the old array.
  85.     case WM_USER:
  86.         if (!IsIconic(hWnd)) {
  87.         if (--update == 0) {
  88.                 InvalidateRect(hWnd, NULL, FALSE);
  89.                 UpdateWindow(hWnd);
  90.             update = maxiterates;
  91.             }
  92.         }
  93.             memcpy(old, new, sizeof(old));
  94.         break;
  95.  
  96.     // start and stop display with the mouse
  97.     case WM_LBUTTONDOWN:
  98.         if (start)
  99.         if (go == TRUE)
  100.             go = FALSE;
  101.         else
  102.             go = TRUE;
  103.         break;
  104.  
  105.     // process menus
  106.     case WM_COMMAND:
  107.         WndCommand(hWnd, wParam);
  108.         break;
  109.  
  110.     // quit
  111.     case WM_DESTROY:
  112.         PostQuitMessage(0);
  113.         break;
  114.  
  115.     // draw
  116.     case WM_PAINT:
  117.         BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
  118.         MainWndPaint(hWnd, ps.hdc);
  119.         EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
  120.         break;
  121.  
  122.     // do some initializations
  123.     case WM_CREATE:
  124.         WndInit(hWnd);
  125.         break;
  126.  
  127.     default:
  128.         return ((long)DefWindowProc(hWnd,message,wParam,lParam));
  129.         break;
  130.     }
  131.     return(0L);
  132. }
  133.  
  134. /* process menu commands */
  135. static void NEAR WndCommand(HWND hWnd, WORD id)
  136. {
  137.     switch (id) {
  138.     // initiate or restart process
  139.     case IDM_START:
  140.         InitializePoints();
  141.         start = TRUE;
  142.         go = TRUE;
  143.             InvalidateRect(hWnd, NULL, TRUE);
  144.         break;
  145.  
  146.     // change parameters
  147.     case IDM_PARAMS:
  148.         if (OpenDlgBox(hWnd, ParamBoxProc, DT_PARAMS)) {
  149.         InitializePoints();
  150.         InvalidateRect(hWnd, NULL, TRUE);
  151.         }
  152.         break;
  153.  
  154.     // display about box
  155.     case IDM_ABOUT:
  156.         OpenDlgBox(hWnd, AboutBoxProc, DT_ABOUT);
  157.         break;
  158.     }
  159. }
  160.  
  161. /* update the screen */
  162. static void NEAR MainWndPaint(HWND hWnd, HDC hDC)
  163. {
  164.  
  165.     register int i,j;
  166.     HCURSOR hcur, holdcur;
  167.     RECT rect;
  168.  
  169.   /* draw the icon */
  170.     if (IsIconic(hWnd)) {
  171.     GetClientRect(hWnd, (LPRECT)&rect);
  172.     Rectangle(hDC, 0,0,rect.right, rect.bottom);
  173.         TextOut(hDC,2,rect.bottom/3,(LPSTR)szIcon,strlen(szIcon));
  174.     }
  175.     else if (start) {
  176.     // put up hourglass cursor
  177.         hcur = LoadCursor(hInst, IDC_WAIT);
  178.         holdcur = SetCursor(hcur);
  179.  
  180.     // how big is the screen
  181.         GetClientRect(hWnd, &rect);
  182.  
  183.     /* Set up a logical screen of MAXPOINTS x MAXPOINTS
  184.        rectangles each of size 5 units. */
  185.         SetMapMode(hDC, MM_ANISOTROPIC);
  186.         SetWindowOrg(hDC, 0, 0);
  187.         SetWindowExt(hDC, 5 * MAXPOINTS, 5 * MAXPOINTS);
  188.         SetViewportOrg(hDC, 0, 0);
  189.         SetViewportExt(hDC, rect.right, rect.bottom);
  190.  
  191.     // show the points
  192.         for (i = 0; i < MAXPOINTS; i++) {
  193.         for (j = 0; j < MAXPOINTS; j++)
  194.             ShowRect(hDC, i, j, (int)new[i][j]);
  195.         Yield();    // let someone else read a message
  196.         }
  197.         SetCursor(holdcur);    // restore the old cursor
  198.     }
  199. }
  200.  
  201. /* draw a rectangle on the screen using the display's color table */
  202. static void NEAR ShowRect(HDC hDC, int i, int j, int index)
  203. {
  204.     HBRUSH hbr, hbrold;
  205.     HPEN hpen, hpenold;
  206.     register short x,y;
  207.     DWORD color;
  208.  
  209.     // get the color for this index.
  210.     // If monochrome, make one up
  211.     if (monochrome)
  212.     color = 0xff0000 * ((index & 4) >> 2) +
  213.         0x00ff00 * ((index & 2) >> 1) +
  214.         0x0000ff * (index & 1);
  215.     // if color, read the color table of the device.
  216.     else 
  217.         Escape(hDC, GETCOLORTABLE, NULL, (LPSTR)&index, (LPSTR)&color);
  218.  
  219.     // create and select a brush for the interior
  220.     hbr = CreateSolidBrush(color);
  221.     hbrold = SelectObject(hDC, hbr);
  222.  
  223.     // we want the same color on the boundary, so create the appropriate pen.
  224.     hpen = CreatePen(0, 0, color);
  225.     hpenold = SelectObject(hDC, hpen);
  226.  
  227.     // draw the rectangle at the given position
  228.     x = 5 * j;
  229.     y = 5 * i;
  230.     Rectangle(hDC, x, y, x + 5, y + 5);
  231.  
  232.     // select out and kill the drawing objects
  233.     SelectObject(hDC, hbrold);
  234.     SelectObject(hDC, hpenold);
  235.     DeleteObject(hbr);
  236.     DeleteObject(hpen);
  237. }
  238.  
  239. // load the points with random values between 0 and numstates - 1
  240. static void NEAR InitializePoints()
  241. {
  242.     register int i, j;
  243.     double val;
  244.  
  245.     srand(LOWORD(GetCurrentTime()));
  246.     for (i = 0; i < MAXPOINTS; i++) {
  247.     for (j = 0; j < MAXPOINTS; j++) {
  248.         val = ((float)rand() / 32768.0) * numstates;
  249.         new[i][j] = old[i][j] = (char)val;
  250.     }
  251.     }
  252. }
  253.  
  254. /* consume neighboring points */
  255. static void NEAR EatPoints()
  256. {
  257.     register int i, j;
  258.     int k, l, n;
  259.  
  260.     for (i = 0; i < MAXPOINTS; i++) {
  261.         for (j = 0; j < MAXPOINTS; j++) {
  262.            for (n = 0; n < 4; n++) {
  263.             Neighbor(n, i, j, &k, &l);
  264.             if (old[k][l] == ((old[i][j] + 1) % numstates)) {
  265.                 new[i][j] = old[k][l];
  266.             break;
  267.             }
  268.         }
  269.     }
  270.     }
  271. }
  272.  
  273. // for a given index i, compute the neighboring indices
  274. static void NEAR Neighbor(int pos,register int i,register int j,int *k,int *l)
  275. {
  276.      switch(pos) {
  277.     case 0:
  278.         *k = (i == 0 ? MAXPOINTS - 1 : i - 1);
  279.         *l = j;
  280.         break;
  281.     case 1:
  282.         *k = (i == MAXPOINTS - 1 ?  0 : i + 1);
  283.         *l = j;
  284.         break;
  285.     case 2:
  286.         *k = i;
  287.         *l = (j == 0 ? MAXPOINTS - 1 : j - 1);
  288.         break;
  289.     case 3:
  290.         *k = i;
  291.         *l = (j == MAXPOINTS - 1 ? 0 : j + 1);
  292.         break;
  293.     }
  294. }
  295.