home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / pmattrac / pmattrac.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-14  |  9.0 KB  |  289 lines

  1. /*---------------------------------------------------------------------*
  2. *  PM Attractors                               *
  3. *                                       *
  4. *  Author: Cheyenne Wills                           *
  5. *       BIX: cwills                               *
  6. *                                       *
  7. * -------------------------------------------------------------------- *
  8. * Released to the public.  Oct 1, 1990.                    *
  9. *----------------------------------------------------------------------/
  10. /*
  11.                    History:
  12. Version    Date    Author          Reason
  13. -------  --------  ------  ---------------------------------------------
  14.  0.5     10/01/90   CCW    Initial preliminary release to public
  15. */
  16.  
  17. #include "common.h"             /* Pull in common stuff */
  18.  
  19. threadparms tp;         /* Active thread pointer */
  20. int threadstack[STACKSIZE];    /* Stack for thread */
  21. HAB hab;
  22. HBITMAP hbm;
  23.  
  24. HWND hwndframe, hwndClient, hwndMenu;
  25.  
  26. static void initps(HWND);
  27.  
  28. /*--------------------------------------------------------------------*
  29.  * pmattrac -                                  *
  30.  *  main - handles initialization and main PM message loop          *
  31.  *--------------------------------------------------------------------*/
  32.  
  33. int main(void)
  34. {
  35.     static char ClientClass[] = "PMAttrac";
  36.     static ULONG FrameFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_MENU |
  37.     FCF_SIZEBORDER | FCF_MINMAX |
  38.     FCF_SHELLPOSITION | FCF_TASKLIST;
  39.     HMQ hmq;
  40.     QMSG qmsg;
  41.  
  42.     hab = WinInitialize(0);
  43.     hmq = WinCreateMsgQueue(hab, 0);
  44.     WinRegisterClass(hab, ClientClass, ClientWndProc, CS_SIZEREDRAW, 0);
  45.  
  46.     hwndframe = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE,
  47.     &FrameFlags, ClientClass, "PM Attractors",
  48.     0L, NULL, ID_RESOURCE, &hwndClient);
  49.  
  50.     while (WinGetMsg(hab, &qmsg, NULL, 0, 0))
  51.     WinDispatchMsg(hab, &qmsg);
  52.  
  53.     WinDestroyWindow(hwndframe);
  54.     WinDestroyMsgQueue(hmq);
  55.     WinTerminate(hab);
  56.     return 0;
  57. }
  58. /*--------------------------------------------------------------------*
  59.  *  Handle main client window.                          *
  60.  *                                      *
  61.  *  Establish the presentation space (via initps).  Obtain          *
  62.  *  our parent ID (used by the setstop function.              *
  63.  *                                      *
  64.  *  For command messages, do a look up for a dialog proc          *
  65.  *  if found then dispatch that dialog.                   *
  66.  *                                      *
  67.  *  For resizing, remember the new client max.                  *
  68.  *                                      *
  69.  *  For repainting, refresh the client window area.              *
  70.  *                                      *
  71.  *  For cleanup, signal any thread that happens to be processing and  *
  72.  *  clean up our shadow PS and our main PS.                  *
  73.  *                                      *
  74.  *--------------------------------------------------------------------*/
  75. MRESULT EXPENTRY
  76. ClientWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  77. {
  78.  
  79.     static struct {
  80.     int attrtype;
  81.     int dlgitem;
  82.     PFNWP (EXPENTRY *proc)();
  83.     } attractors[] = {
  84.     {IDM_DUFFING, IDD_DUFFING, DuffingDlgProc},
  85.     {IDM_HENON,   IDD_HENON,   HenonDlgProc},
  86.     {IDM_KAM,     IDD_KAM,       KAMDlgProc},
  87.     {-1,          -1,       NULL}
  88.     };
  89.  
  90.     int i;
  91.  
  92.     switch (msg) {
  93.       case WM_CREATE:
  94.     initps(hwnd);
  95.     hwndMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT,
  96.         FALSE), FID_MENU);
  97.     setstop();
  98.     break;
  99.       case WM_USER + 1:
  100.     setstop();
  101.     break;
  102.       case WM_COMMAND:
  103.     if (COMMANDMSG(&msg)->cmd == IDM_STOP) setstop();
  104.     else
  105.         for(i = 0; attractors[i].attrtype != -1; i++) {
  106.         if( attractors[i].attrtype == COMMANDMSG(&msg)->cmd)
  107.             WinDlgBox(HWND_DESKTOP,hwnd,attractors[i].proc,
  108.               NULL,attractors[i].dlgitem,NULL);
  109.         }
  110.     break;
  111.       case WM_SIZE:
  112.     tp.cxmax = SHORT1FROMMP(mp2);
  113.     tp.cymax = SHORT2FROMMP(mp2);
  114.     return 0;
  115.       case WM_PAINT:
  116.     WinBeginPaint(hwnd,tp.hps,NULL);
  117.     GpiErase(tp.hps);
  118.     refresh(tp.hps, tp.memhps, tp.cxmax, tp.cymax, tp.xmax, tp.ymax);
  119.     WinEndPaint(tp.hps);
  120.     return 0;
  121.       case WM_DESTROY:
  122.     tp.exitflag = 1;
  123.     DosSemClear(&tp.triggerdraw);
  124.     DosSemWait(&tp.doingdraw,SEM_INDEFINITE_WAIT);
  125.     GpiSetBitmap(tp.memhps,NULL);
  126.     GpiDestroyPS(tp.hps);
  127.     GpiDestroyPS(tp.memhps);
  128.     GpiDeleteBitmap(hbm);
  129.     return 0;
  130.     }
  131.     return WinDefWindowProc(hwnd, msg, mp1, mp2);
  132. }
  133. /*--------------------------------------------------------------------*
  134.  *  Initps - Initialize our main presentation space and a "shadow"    *
  135.  *  presentation space.  The shadow presentation space is where we    *
  136.  *  will be doing all of our drawing.  At certain points, the shadow  *
  137.  *  PS will be copied over to the main PS.  This may not be the       *
  138.  *  fastest method, but it does allow us to divorce ourselves from    *
  139.  *  the drawing routines.                          *
  140.  *--------------------------------------------------------------------*/
  141. static void
  142. initps(HWND hwnd)
  143. {
  144.     SIZEL size;
  145.     RECTL rectl;
  146.     HDC hdcinit;
  147.     HDC hdcmemory;
  148.     BITMAPINFOHEADER bmp;
  149.     long bitmapfmts[2];
  150.  
  151.     hdcinit = WinOpenWindowDC(hwnd);
  152.     size.cx = 0;
  153.     size.cy = 0;
  154.     tp.hps = GpiCreatePS(hab, hdcinit, &size, PU_PELS |
  155.     GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC);
  156.  
  157.  
  158.     hdcmemory = DevOpenDC(hab, OD_MEMORY, "*", 0L, NULL, NULL);
  159.     /* Now determine the size of the bitmap to use */
  160.  
  161.     rectl.xLeft = 0;
  162.     rectl.yBottom = 0;
  163.     rectl.xRight = size.cx = tp.xmax =
  164.     WinQuerySysValue(HWND_DESKTOP, SV_CXFULLSCREEN);
  165.     rectl.yTop = size.cy = tp.ymax =
  166.     WinQuerySysValue(HWND_DESKTOP, SV_CYFULLSCREEN);
  167.  
  168.     tp.memhps = GpiCreatePS(hab, hdcmemory, &size, PU_ARBITRARY |
  169.     GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC);
  170.  
  171.     GpiSetPageViewport(tp.memhps, &rectl);
  172.  
  173.     GpiQueryDeviceBitmapFormats(tp.hps, 2L, bitmapfmts);
  174.  
  175.     bmp.cbFix = sizeof(bmp);
  176.     bmp.cx = tp.xmax;
  177.     bmp.cy = tp.ymax;
  178.     bmp.cPlanes = (short) bitmapfmts[0];
  179.     bmp.cBitCount = (short) bitmapfmts[1];
  180.  
  181.     hbm = GpiCreateBitmap(tp.memhps, &bmp, 0L, NULL, NULL);
  182.     GpiSetBitmap(tp.memhps, hbm);
  183.     GpiErase(tp.memhps);
  184.     GpiErase(tp.hps);
  185. }
  186.  
  187. /*--------------------------------------------------------------------*
  188.  *  Disable the selection menu and activate the "stop" menu.          *
  189.  *--------------------------------------------------------------------*/
  190. void
  191. setrunning()
  192. {
  193.     WinSendMsg(hwndMenu, MM_SETITEMATTR,
  194.     MPFROM2SHORT(IDM_TYPES, TRUE),
  195.     MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
  196.     WinSendMsg(hwndMenu, MM_SETITEMATTR,
  197.     MPFROM2SHORT(IDM_RUN, TRUE),
  198.     MPFROM2SHORT(MIA_DISABLED, 0));
  199. }
  200. /*--------------------------------------------------------------------*
  201.  *  Disable the stop menu and activate the selection menu          *
  202.  *--------------------------------------------------------------------*/
  203. void
  204. setstop()
  205. {
  206.     tp.exitflag = 1;
  207.     WinSendMsg(hwndMenu, MM_SETITEMATTR,
  208.     MPFROM2SHORT(IDM_TYPES, TRUE),
  209.     MPFROM2SHORT(MIA_DISABLED, 0));
  210.     WinSendMsg(hwndMenu, MM_SETITEMATTR,
  211.     MPFROM2SHORT(IDM_RUN, TRUE),
  212.     MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
  213.  
  214. }
  215.  
  216. /*--------------------------------------------------------------------*
  217.  *  Copy the shadow HPS over to the primary HPS.  Can you say "SLOW"  *
  218.  *  sure you can.                              *
  219.  *--------------------------------------------------------------------*/
  220. void
  221. refresh(HPS dhps, HPS shps, long dxmax, long dymax, long sxmax, long symax)
  222. {
  223.     POINTL aptl[4];
  224.  
  225.     aptl[0].x = 0;
  226.     aptl[0].y = 0;
  227.     aptl[1].x = dxmax;
  228.     aptl[1].y = dymax;
  229.     aptl[2].x = 0;
  230.     aptl[2].y = 0;
  231.     aptl[3].x = sxmax;
  232.     aptl[3].y = symax;
  233.  
  234.     GpiBitBlt(dhps, shps, 4L, aptl, ROP_SRCCOPY, BBO_IGNORE);
  235. }
  236.  
  237. /*--------------------------------------------------------------------*
  238.  *  Build a transformation matrix to be able to handle the          *
  239.  *  floating point world coords.  The application still must handle   *
  240.  *  scaling the floating point value into an integer.              *
  241.  *                                      *
  242.  *  Example of use:                              *
  243.  *    Establish a world coord that can handle from              *
  244.  *                                      *
  245.  *    (-1,1)        |        (1,1)                      *
  246.  *            |                              *
  247.  *    ------------+-------------                      *
  248.  *            |                              *
  249.  *    (-1,-1)     |        (1,-1)                      *
  250.  *                                      *
  251.  *                                      *
  252.  *    and be able to handle values such as .5 or .2 (tenths only)   *
  253.  *                                      *
  254.  *                                      *
  255.  *  setfloatscale(&mat,-1.,-1.,1.,1.,10,10,devxmax,devymax);          *
  256.  *  GpiSetDefaultViewMatrix(hps,9L,&mat,TRANSFORM_REPLACE);          *
  257.  *                                      *
  258.  *  ptl.x = .5 * 10;                              *
  259.  *  ptl.y = -.2 * 10;                              *
  260.  *                                      *
  261.  *  GpiMove....                               *
  262.  *                                      *
  263.  *--------------------------------------------------------------------*/
  264. void
  265. setfloatscale(MATRIXLF *mat,
  266.     double xmin, double ymin,
  267.     double xmax, double ymax,
  268.     short xscale, short yscale,
  269.     short devxmax, short devymax)
  270. {
  271.     double xfact;
  272.     double yfact;
  273.  
  274.     mat->lM13 = 0L;
  275.     mat->lM23 = 0L;
  276.     mat->lM33 = 1L;
  277.  
  278.     xfact = devxmax / ((xmax - xmin) * xscale);
  279.     yfact = devymax / ((ymax - ymin) * yscale);
  280.  
  281.     mat->fxM11 = (FIXED) (65536L * xfact);
  282.     mat->fxM21 = 0L;
  283.     mat->fxM12 = 0L;
  284.     mat->fxM22 = (FIXED) (65536L * yfact);
  285.  
  286.     mat->lM31 = (long) devxmax - (long) ((double) devxmax * (xmax / (xmax - xmin)));
  287.     mat->lM32 = (long) devymax - (long) ((double) devymax * (ymax / (ymax - ymin)));
  288. }
  289.