home *** CD-ROM | disk | FTP | other *** search
- /*---------------------------------------------------------------------*
- * PM Attractors *
- * *
- * Author: Cheyenne Wills *
- * BIX: cwills *
- * *
- * -------------------------------------------------------------------- *
- * Released to the public. Oct 1, 1990. *
- *----------------------------------------------------------------------/
- /*
- History:
- Version Date Author Reason
- ------- -------- ------ ---------------------------------------------
- 0.5 10/01/90 CCW Initial preliminary release to public
- */
-
- #include "common.h" /* Pull in common stuff */
-
- threadparms tp; /* Active thread pointer */
- int threadstack[STACKSIZE]; /* Stack for thread */
- HAB hab;
- HBITMAP hbm;
-
- HWND hwndframe, hwndClient, hwndMenu;
-
- static void initps(HWND);
-
- /*--------------------------------------------------------------------*
- * pmattrac - *
- * main - handles initialization and main PM message loop *
- *--------------------------------------------------------------------*/
-
- int main(void)
- {
- static char ClientClass[] = "PMAttrac";
- static ULONG FrameFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_MENU |
- FCF_SIZEBORDER | FCF_MINMAX |
- FCF_SHELLPOSITION | FCF_TASKLIST;
- HMQ hmq;
- QMSG qmsg;
-
- hab = WinInitialize(0);
- hmq = WinCreateMsgQueue(hab, 0);
- WinRegisterClass(hab, ClientClass, ClientWndProc, CS_SIZEREDRAW, 0);
-
- hwndframe = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE,
- &FrameFlags, ClientClass, "PM Attractors",
- 0L, NULL, ID_RESOURCE, &hwndClient);
-
- while (WinGetMsg(hab, &qmsg, NULL, 0, 0))
- WinDispatchMsg(hab, &qmsg);
-
- WinDestroyWindow(hwndframe);
- WinDestroyMsgQueue(hmq);
- WinTerminate(hab);
- return 0;
- }
- /*--------------------------------------------------------------------*
- * Handle main client window. *
- * *
- * Establish the presentation space (via initps). Obtain *
- * our parent ID (used by the setstop function. *
- * *
- * For command messages, do a look up for a dialog proc *
- * if found then dispatch that dialog. *
- * *
- * For resizing, remember the new client max. *
- * *
- * For repainting, refresh the client window area. *
- * *
- * For cleanup, signal any thread that happens to be processing and *
- * clean up our shadow PS and our main PS. *
- * *
- *--------------------------------------------------------------------*/
- MRESULT EXPENTRY
- ClientWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- {
-
- static struct {
- int attrtype;
- int dlgitem;
- PFNWP (EXPENTRY *proc)();
- } attractors[] = {
- {IDM_DUFFING, IDD_DUFFING, DuffingDlgProc},
- {IDM_HENON, IDD_HENON, HenonDlgProc},
- {IDM_KAM, IDD_KAM, KAMDlgProc},
- {-1, -1, NULL}
- };
-
- int i;
-
- switch (msg) {
- case WM_CREATE:
- initps(hwnd);
- hwndMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT,
- FALSE), FID_MENU);
- setstop();
- break;
- case WM_USER + 1:
- setstop();
- break;
- case WM_COMMAND:
- if (COMMANDMSG(&msg)->cmd == IDM_STOP) setstop();
- else
- for(i = 0; attractors[i].attrtype != -1; i++) {
- if( attractors[i].attrtype == COMMANDMSG(&msg)->cmd)
- WinDlgBox(HWND_DESKTOP,hwnd,attractors[i].proc,
- NULL,attractors[i].dlgitem,NULL);
- }
- break;
- case WM_SIZE:
- tp.cxmax = SHORT1FROMMP(mp2);
- tp.cymax = SHORT2FROMMP(mp2);
- return 0;
- case WM_PAINT:
- WinBeginPaint(hwnd,tp.hps,NULL);
- GpiErase(tp.hps);
- refresh(tp.hps, tp.memhps, tp.cxmax, tp.cymax, tp.xmax, tp.ymax);
- WinEndPaint(tp.hps);
- return 0;
- case WM_DESTROY:
- tp.exitflag = 1;
- DosSemClear(&tp.triggerdraw);
- DosSemWait(&tp.doingdraw,SEM_INDEFINITE_WAIT);
- GpiSetBitmap(tp.memhps,NULL);
- GpiDestroyPS(tp.hps);
- GpiDestroyPS(tp.memhps);
- GpiDeleteBitmap(hbm);
- return 0;
- }
- return WinDefWindowProc(hwnd, msg, mp1, mp2);
- }
- /*--------------------------------------------------------------------*
- * Initps - Initialize our main presentation space and a "shadow" *
- * presentation space. The shadow presentation space is where we *
- * will be doing all of our drawing. At certain points, the shadow *
- * PS will be copied over to the main PS. This may not be the *
- * fastest method, but it does allow us to divorce ourselves from *
- * the drawing routines. *
- *--------------------------------------------------------------------*/
- static void
- initps(HWND hwnd)
- {
- SIZEL size;
- RECTL rectl;
- HDC hdcinit;
- HDC hdcmemory;
- BITMAPINFOHEADER bmp;
- long bitmapfmts[2];
-
- hdcinit = WinOpenWindowDC(hwnd);
- size.cx = 0;
- size.cy = 0;
- tp.hps = GpiCreatePS(hab, hdcinit, &size, PU_PELS |
- GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC);
-
-
- hdcmemory = DevOpenDC(hab, OD_MEMORY, "*", 0L, NULL, NULL);
- /* Now determine the size of the bitmap to use */
-
- rectl.xLeft = 0;
- rectl.yBottom = 0;
- rectl.xRight = size.cx = tp.xmax =
- WinQuerySysValue(HWND_DESKTOP, SV_CXFULLSCREEN);
- rectl.yTop = size.cy = tp.ymax =
- WinQuerySysValue(HWND_DESKTOP, SV_CYFULLSCREEN);
-
- tp.memhps = GpiCreatePS(hab, hdcmemory, &size, PU_ARBITRARY |
- GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC);
-
- GpiSetPageViewport(tp.memhps, &rectl);
-
- GpiQueryDeviceBitmapFormats(tp.hps, 2L, bitmapfmts);
-
- bmp.cbFix = sizeof(bmp);
- bmp.cx = tp.xmax;
- bmp.cy = tp.ymax;
- bmp.cPlanes = (short) bitmapfmts[0];
- bmp.cBitCount = (short) bitmapfmts[1];
-
- hbm = GpiCreateBitmap(tp.memhps, &bmp, 0L, NULL, NULL);
- GpiSetBitmap(tp.memhps, hbm);
- GpiErase(tp.memhps);
- GpiErase(tp.hps);
- }
-
- /*--------------------------------------------------------------------*
- * Disable the selection menu and activate the "stop" menu. *
- *--------------------------------------------------------------------*/
- void
- setrunning()
- {
- WinSendMsg(hwndMenu, MM_SETITEMATTR,
- MPFROM2SHORT(IDM_TYPES, TRUE),
- MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
- WinSendMsg(hwndMenu, MM_SETITEMATTR,
- MPFROM2SHORT(IDM_RUN, TRUE),
- MPFROM2SHORT(MIA_DISABLED, 0));
- }
- /*--------------------------------------------------------------------*
- * Disable the stop menu and activate the selection menu *
- *--------------------------------------------------------------------*/
- void
- setstop()
- {
- tp.exitflag = 1;
- WinSendMsg(hwndMenu, MM_SETITEMATTR,
- MPFROM2SHORT(IDM_TYPES, TRUE),
- MPFROM2SHORT(MIA_DISABLED, 0));
- WinSendMsg(hwndMenu, MM_SETITEMATTR,
- MPFROM2SHORT(IDM_RUN, TRUE),
- MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
-
- }
-
- /*--------------------------------------------------------------------*
- * Copy the shadow HPS over to the primary HPS. Can you say "SLOW" *
- * sure you can. *
- *--------------------------------------------------------------------*/
- void
- refresh(HPS dhps, HPS shps, long dxmax, long dymax, long sxmax, long symax)
- {
- POINTL aptl[4];
-
- aptl[0].x = 0;
- aptl[0].y = 0;
- aptl[1].x = dxmax;
- aptl[1].y = dymax;
- aptl[2].x = 0;
- aptl[2].y = 0;
- aptl[3].x = sxmax;
- aptl[3].y = symax;
-
- GpiBitBlt(dhps, shps, 4L, aptl, ROP_SRCCOPY, BBO_IGNORE);
- }
-
- /*--------------------------------------------------------------------*
- * Build a transformation matrix to be able to handle the *
- * floating point world coords. The application still must handle *
- * scaling the floating point value into an integer. *
- * *
- * Example of use: *
- * Establish a world coord that can handle from *
- * *
- * (-1,1) | (1,1) *
- * | *
- * ------------+------------- *
- * | *
- * (-1,-1) | (1,-1) *
- * *
- * *
- * and be able to handle values such as .5 or .2 (tenths only) *
- * *
- * *
- * setfloatscale(&mat,-1.,-1.,1.,1.,10,10,devxmax,devymax); *
- * GpiSetDefaultViewMatrix(hps,9L,&mat,TRANSFORM_REPLACE); *
- * *
- * ptl.x = .5 * 10; *
- * ptl.y = -.2 * 10; *
- * *
- * GpiMove.... *
- * *
- *--------------------------------------------------------------------*/
- void
- setfloatscale(MATRIXLF *mat,
- double xmin, double ymin,
- double xmax, double ymax,
- short xscale, short yscale,
- short devxmax, short devymax)
- {
- double xfact;
- double yfact;
-
- mat->lM13 = 0L;
- mat->lM23 = 0L;
- mat->lM33 = 1L;
-
- xfact = devxmax / ((xmax - xmin) * xscale);
- yfact = devymax / ((ymax - ymin) * yscale);
-
- mat->fxM11 = (FIXED) (65536L * xfact);
- mat->fxM21 = 0L;
- mat->fxM12 = 0L;
- mat->fxM22 = (FIXED) (65536L * yfact);
-
- mat->lM31 = (long) devxmax - (long) ((double) devxmax * (xmax / (xmax - xmin)));
- mat->lM32 = (long) devymax - (long) ((double) devymax * (ymax / (ymax - ymin)));
- }
-