home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-386-Vol-2of3.iso / t / triq.zip / TRIQ.C < prev    next >
C/C++ Source or Header  |  1992-05-06  |  36KB  |  1,386 lines

  1. /*----------------------------------------------------------------------------*\
  2. |   triqc.c - Sample code showing DIB usage and 386-specific code              |
  3. |                                           |
  4. |                                                                              |
  5. \*----------------------------------------------------------------------------*/
  6.  
  7. /*
  8.      (C) Copyright Microsoft Corp. 1991.  All rights reserved.
  9.  
  10.      You have a royalty-free right to use, modify, reproduce and 
  11.      distribute the Sample Files (and/or any modified version) in 
  12.      any way you find useful, provided that you agree that 
  13.      Microsoft has no warranty obligations or liability for any 
  14.      Sample Application Files which are modified. 
  15.  */
  16.  
  17. /*
  18.  
  19. WARNING:
  20.  
  21. Known Bug:
  22.  
  23. Don't resize client area too small because the DIB code doesn't check
  24. bounds and if it is asked to draw outside of image, it will GP Fault
  25.  
  26. */
  27.  
  28. /*----------------------------------------------------------------------------*\
  29. |                                                                              |
  30. |   g e n e r a l   c o n s t a n t s                                          |
  31. |                                                                              |
  32. \*----------------------------------------------------------------------------*/
  33.  
  34. #define MAXSTR   80
  35. #define NUMBALLS 3
  36.  
  37. /*----------------------------------------------------------------------------*\
  38. |                                                                              |
  39. |   i n c l u d e   f i l e s                                                  |
  40. |                                                                              |
  41. \*----------------------------------------------------------------------------*/
  42.  
  43. #define SWAP(x,y)   ((x)^=(y)^=(x)^=(y))
  44.  
  45. // define if we want to force bitmap to <64K (ie, 320x200)
  46. // note: bitmap include BITMAPINFOHEADER and pal 
  47.  
  48. //#define SMALLBITMAP
  49. //#define FIXEDSIZE
  50.  
  51. #include <windows.h>
  52. #include <math.h>
  53. #include <stdio.h>
  54. #include <stdlib.h>    // for rand()
  55. #include <search.h>
  56. #include "triq.h"
  57. #include "4d/4d.h"
  58. #include "view.h"
  59.  
  60. #include "dib.h"
  61.  
  62. typedef struct _tagBalls
  63. {
  64.     int x;        // offsets
  65.     int y;
  66. } BALL, *PBALL, far *LPBALL;
  67.  
  68. BALL balls[NUMBALLS];
  69.  
  70. static    char    acText[MAXSTRING];
  71.  
  72. HDC ghdc;
  73.  
  74. COLORREF    crWindowText;
  75. COLORREF    crWindowBk;
  76. COLORREF    crHilightText;
  77. COLORREF    crHilightBk;
  78. COLORREF    crWindowFrame;
  79.  
  80. int        cxIcon;
  81. int        cyIcon;
  82.  
  83. unsigned Zlist[MAXPOLY];    // sorted list of polys
  84. unsigned nZPolys;        // number of sorted Z Polys
  85.  
  86. int wScaleX=3;
  87. int wScaleY=3;
  88. int wScaleZ=3;
  89.  
  90. int wRotxAmount=5;
  91. int wRotyAmount=3;
  92. int wRotzAmount=4;
  93. WORD fAutoRotX=TRUE;
  94. WORD fAutoRotY=TRUE;
  95. WORD fAutoRotZ=TRUE;
  96.  
  97. WORD fDrawn=FALSE;    // have we drawn it yet?
  98. WORD fFill=FALSE;
  99. WORD fNormal=TRUE;
  100. WORD fShowDF=FALSE;
  101.  
  102. WORD wxRot=0;
  103. WORD wOxRot=0;
  104. WORD wyRot=0;
  105. WORD wOyRot=0;
  106. WORD wzRot=0;
  107. WORD wOzRot=0;
  108.  
  109.  
  110. POINTFX4D FAR *POINTSQ;          // original 3d points
  111. POINTFX4D FAR *CPOINTSQ;         // converted 3d points
  112. POINT FAR *PNTS;            // projected 2d points
  113. EDGE  FAR *EDGES;           // all edges in the scene
  114. POLY  FAR *POLYS;           // all polys in the scene
  115.  
  116.  
  117.         
  118. static  HPALETTE hpalApp;
  119. static  HPALETTE hpalT1;
  120. static  HPALETTE hpalT2;
  121.  
  122. BOOL    fActiveApp=TRUE;
  123.  
  124. short   xClient, yClient;
  125.  
  126.  
  127. HDC     hdcDib1;
  128. HANDLE  hdib1   = NULL;      // memory DIB
  129.  
  130. HDC    hdcDib2;
  131. HANDLE  hdib2   = NULL;      // memory DIB
  132.  
  133. LPSTR    lpdib1;
  134. LPSTR   lpdib2;
  135.  
  136. BOOL    fDibCur=0;
  137.  
  138. HPALETTE hpalEx;
  139. HPALETTE hpalSystem;
  140. HPALETTE hpalPalette   = NULL;      // current real-palette
  141. HPALETTE hpalCurrent   = NULL;      // current dib-palette
  142. HANDLE   hdibCurrent   = NULL;      // memory DIB
  143.  
  144. BOOL    fUseBlit=FALSE;
  145. BOOL    fUseDIB=FALSE;
  146. BOOL    fUseCustom=FALSE;
  147. BOOL    fUseGDI=TRUE;
  148. BOOL    fSolidColors=FALSE;
  149. BOOL    fNullPen=TRUE;
  150. BOOL    fBoxes=FALSE;
  151. unsigned wUseSkip=MENU_EVERY;
  152. unsigned wskipmask=0xffff;
  153.  
  154. WORD askipmask[MENU_SKIP_MAX - MENU_SKIP_MIN +1]=
  155. {
  156.     0xffff,    // MENU_EVERY
  157.     0xfffe,    // MENU_SKIP2
  158.     0xfff7,    // MENU_SKIP4
  159.     0xfff0,     // MENU_SKIP8
  160.     0xffe0,    // MENU_SKIP16
  161.     0x0000    // MENU_SKIPALL
  162. };
  163.  
  164.         
  165. LPSTR lpdib;
  166.  
  167.  
  168.  
  169. /*----------------------------------------------------------------------------*\
  170. |                                                                              |
  171. |   g l o b a l   v a r i a b l e s                                            |
  172. |                                                                              |
  173. \*----------------------------------------------------------------------------*/
  174. static  char    szAppName[]="Ball Sample App";
  175.  
  176. static  HANDLE  hInstApp;
  177. static  HWND    hwndApp;
  178.  
  179. PSTR    szText;
  180. char    szString[MAXSTR];
  181.  
  182. /*----------------------------------------------------------------------------*\
  183. |                                                                              |
  184. |   f u n c t i o n   d e f i n i t i o n s                                    |
  185. |                                                                              |
  186. \*----------------------------------------------------------------------------*/
  187.  
  188. LONG FAR PASCAL AppWndProc (HWND hwnd, unsigned uiMessage, WORD wParam, LONG lParam);
  189. int  ErrMsg (LPSTR sz,...);
  190. BOOL fDialog(int id,HWND hwnd,FARPROC fpfn);
  191.  
  192. LONG  NEAR PASCAL AppCommand(HWND hwnd, unsigned msg, WORD wParam, LONG lParam);
  193.  
  194. HANDLE FAR PASCAL hread (LPSTR szFile, HANDLE h);
  195.  
  196. void CopyPoly(LPPOINTFX4D lpDest, LPPOINTFX4D lpSrc, WORD numpoints);
  197. zSort(LPPOLY lpPoly,WORD numpolys);
  198. //////void DumpIt(void);
  199. fNormalTest (LPPOLY pPoly);
  200. BOOL fOverlap (FIXED4D min1,FIXED4D max1,FIXED4D min2,FIXED4D max2);
  201. void redraw(void);
  202. void DrawFrame(void);
  203.  
  204. VOID FAR PASCAL Triangle(HDC hDC, LPPOINT lpPoints);
  205. VOID FAR PASCAL DIBTriangle(LPSTR lpdib, LPPOINT lpPoints, WORD crCol);
  206.  
  207. /*----------------------------------------------------------------------------*\
  208. |   AppAbout( hDlg, uiMessage, wParam, lParam )                    |
  209. |                                           |
  210. |   Description:                                   |
  211. |    This function handles messages belonging to the "About" dialog box.    |
  212. |    The only message that it looks for is WM_COMMAND, indicating the use   |
  213. |    has pressed the "OK" button.  When this happens, it takes down           |
  214. |    the dialog box.                                |
  215. |                                           |
  216. |   Arguments:                                       |
  217. |    hDlg        window handle of about dialog window               |
  218. |    uiMessage    message number                           |
  219. |    wParam        message-dependent                       |
  220. |    lParam        message-dependent                       |
  221. |                                           |
  222. |   Returns:                                       |
  223. |    TRUE if message has been processed, else FALSE                   |
  224. |                                           |
  225. \*----------------------------------------------------------------------------*/
  226. BOOL FAR PASCAL AppAbout( hDlg, uiMessage, wParam, lParam )
  227.     HWND     hDlg;
  228.     unsigned uiMessage;
  229.     WORD     wParam;
  230.     long     lParam;
  231. {
  232.     switch (uiMessage) 
  233.     {
  234.         case WM_COMMAND:
  235.             if (wParam == IDOK)
  236.                 EndDialog(hDlg,TRUE);
  237.         break;
  238.  
  239.     case WM_INITDIALOG:
  240.         return TRUE;
  241.     }
  242.     return FALSE;
  243. }
  244.  
  245. /*----------------------------------------------------------------------------*\
  246. |   AppInit( hInst, hPrev)                               |
  247. |                                           |
  248. |   Description:                                   |
  249. |    This is called when the application is first loaded into           |
  250. |    memory.  It performs all initialization that doesn't need to be done   |
  251. |    once per instance.                               |
  252. |                                           |
  253. |   Arguments:                                       |
  254. |    hInstance    instance handle of current instance               |
  255. |    hPrev        instance handle of previous instance               |
  256. |                                           |
  257. |   Returns:                                       |
  258. |    TRUE if successful, FALSE if not                       |
  259. |                                           |
  260. \*----------------------------------------------------------------------------*/
  261. BOOL AppInit(HANDLE hInst,HANDLE hPrev,WORD sw,LPSTR szCmdLine)
  262. {
  263.     WNDCLASS cls;
  264.     int      dx,dy;
  265.     char     ach[80];
  266.     HMENU    hmenu;
  267.     HANDLE h;
  268.     LPSTR lpRes;
  269.     
  270.  
  271.     /* Save instance handle for DialogBoxs */
  272.     hInstApp = hInst;
  273.  
  274.     PNTS    = (VOID FAR * )GlobalLock(GlobalAlloc(GHND, (LONG)MAXPTS  * sizeof(POINT)));
  275.     POINTSQ  = (VOID FAR * )GlobalLock(GlobalAlloc(GHND, (LONG)MAXPTS  * sizeof(PNT) ));
  276.     CPOINTSQ = (VOID FAR * )GlobalLock(GlobalAlloc(GHND, (LONG)MAXPTS  * sizeof(PNT) ));
  277.     EDGES   = (VOID FAR * )GlobalLock(GlobalAlloc(GHND, (LONG)MAXEDGE * sizeof(EDGE)));
  278.     POLYS   = (VOID FAR * )GlobalLock(GlobalAlloc(GHND, (LONG)MAXPOLY * sizeof(POLY)));
  279.             
  280.     
  281.     if (!hPrev) 
  282.     {
  283.     /*
  284.      *  Register a class for the main application window
  285.      */
  286.         cls.hCursor        = LoadCursor(NULL,IDC_ARROW);
  287.         cls.hIcon          = LoadIcon(hInst,MAKEINTATOM(ID_APP));
  288.         cls.lpszMenuName   = MAKEINTATOM(ID_APP);
  289.         cls.lpszClassName  = MAKEINTATOM(ID_APP);
  290.         cls.hbrBackground  = (HBRUSH)COLOR_WINDOW + 1;
  291.         cls.hInstance      = hInst;
  292.         cls.style          = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
  293.         cls.lpfnWndProc    = AppWndProc;
  294.         cls.cbWndExtra     = 0;
  295.         cls.cbClsExtra     = 0;
  296.  
  297.         if (!RegisterClass(&cls))
  298.         return FALSE;
  299.     }
  300.  
  301.     hpalApp = CreateExplicitPalette();
  302. #ifndef FIXEDSIZE
  303.     dx = GetSystemMetrics (SM_CXSCREEN);
  304.     dy = GetSystemMetrics (SM_CYSCREEN);
  305. #else
  306.     dx=400;
  307.     dy=400;
  308. #endif
  309.  
  310.     hwndApp = CreateWindow (MAKEINTATOM(ID_APP),    // Class name
  311.                             szAppName,              // Caption
  312.                             WS_OVERLAPPEDWINDOW,    // Style bits
  313.                             0, 0,            // Position
  314.                             dx,dy,                  // Size
  315.                             (HWND)NULL,             // Parent window (no parent)
  316.                             (HMENU)NULL,            // use class menu
  317.                             (HANDLE)hInst,          // handle to window instance
  318.                             (LPSTR)NULL             // no params to pass on
  319.                            );
  320.                
  321.  
  322.     h=FindResource(hInst,MAKEINTATOM(AUTO),MAKEINTATOM(DATA3D));
  323.     if(!h)
  324.     return FALSE;
  325.     
  326.     lpRes=LockResource(h = LoadResource(hInst,h));
  327.     if(!lpRes)
  328.     return FALSE;
  329.     ParseFile(lpRes);
  330.     
  331.     UnlockResource(h);
  332.     FreeResource(h);
  333.     
  334.     if(IsWindow(hwndApp))
  335.     ShowWindow(hwndApp,sw);
  336.  
  337.     return TRUE;
  338. }
  339.  
  340. /*----------------------------------------------------------------------------*\
  341. |   WinMain( hInst, hPrev, lpszCmdLine, cmdShow )                   |
  342. |                                                                              |
  343. |   Description:                                                               |
  344. |       The main procedure for the App.  After initializing, it just goes      |
  345. |       into a message-processing loop until it gets a WM_QUIT message         |
  346. |       (meaning the app was closed).                                          |
  347. |                                                                              |
  348. |   Arguments:                                                                 |
  349. |    hInst        instance handle of this instance of the app           |
  350. |    hPrev        instance handle of previous instance, NULL if first    |
  351. |       szCmdLine       ->null-terminated command line                         |
  352. |       cmdShow         specifies how the window is initially displayed        |
  353. |                                                                              |
  354. |   Returns:                                                                   |
  355. |       The exit code as specified in the WM_QUIT message.                     |
  356. |                                                                              |
  357. \*----------------------------------------------------------------------------*/
  358. int FAR PASCAL WinMain(HANDLE hInst, HANDLE hPrev, LPSTR szCmdLine, WORD sw)
  359. {
  360.     MSG     msg;
  361.  
  362.     /* Call initialization procedure */
  363.     if (!AppInit(hInst,hPrev,sw,szCmdLine))
  364.         return FALSE;
  365.  
  366.     hdib1 = CreateDib(8,xClient,yClient);
  367.     hdib2 = CreateDib(8,xClient,yClient);
  368.     
  369.     SetDibUsage(hdib1, hpalApp, DIB_RGB_COLORS);    // PAL
  370.     SetDibUsage(hdib2, hpalApp, DIB_RGB_COLORS);    // PAL
  371.     
  372.     lpdib1=GlobalLock(hdib1);
  373.     lpdib2=GlobalLock(hdib2);
  374.     
  375.     hdcDib1 = CreateDC("DIB",NULL,NULL,lpdib1);
  376.     hdcDib2 = CreateDC("DIB",NULL,NULL,lpdib2);
  377.  
  378.     if (hpalApp)
  379.     {
  380.     hpalT1 = SelectPalette(hdcDib1,CreateExplicitPalette(),FALSE);
  381.     RealizePalette(hdcDib1);
  382.     hpalT2 = SelectPalette(hdcDib2,CreateExplicitPalette(),FALSE);
  383.     RealizePalette(hdcDib2);
  384.     }
  385.     
  386.     /*
  387.      * Polling messages from event queue
  388.      */
  389.  
  390.     if(!IsWindow(hwndApp))
  391.     goto cleanup;
  392.     
  393.     while (TRUE)
  394.     {
  395.     if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))  
  396.     {
  397.         if(msg.message == WM_QUIT)
  398.         break;
  399.         
  400.         TranslateMessage(&msg);
  401.         DispatchMessage(&msg);
  402.     }
  403.     else
  404.     {
  405.         if(fActiveApp)
  406.         {
  407.         if(fAutoRotX)
  408.         {
  409.             wOxRot=wxRot;
  410.             wxRot+=wRotxAmount;
  411.         
  412.             while(wxRot>=360)    // normalize
  413.             wxRot-=360;
  414.             while(wxRot<0)    // ditto
  415.             wxRot+=360;
  416.         
  417.         }
  418.         if(fAutoRotY)
  419.         {
  420.         
  421.             wOyRot=wyRot;
  422.             wyRot+=wRotyAmount;
  423.         
  424.             while(wyRot>=360)    // normalize
  425.             wyRot-=360;
  426.             while(wyRot<0)    // ditto
  427.             wyRot+=360;
  428.         
  429.         }
  430.         if(fAutoRotZ)
  431.         {
  432.         
  433.             wOzRot=wzRot;
  434.             wzRot+=wRotzAmount;
  435.         
  436.             while(wzRot>=360)    // normalize
  437.             wzRot-=360;
  438.             while(wzRot<0)    // ditto
  439.             wzRot+=360;
  440.         
  441.  
  442.         }
  443.         DrawFrame();
  444.         }
  445.         else
  446.         WaitMessage();
  447.     }
  448.     }
  449.  
  450. cleanup:
  451.  
  452.     if (hpalApp)
  453.     {
  454.     DeleteObject(SelectPalette(hdcDib1,hpalT1,FALSE));
  455.     DeleteObject(SelectPalette(hdcDib2,hpalT2,FALSE));
  456.     }
  457.     
  458.     DeleteDC(hdcDib1);
  459.     DeleteDC(hdcDib2);
  460.     
  461.     GlobalUnlock(hdib1);
  462.     GlobalUnlock(hdib2);
  463.     GlobalFree(hdib1);
  464.     GlobalFree(hdib2);
  465.     
  466.     return msg.wParam;
  467. }
  468.  
  469.  
  470. void ScalePoly(LPPOINTFX4D lpSrcPoints, int x, int y, int z, WORD numpoints)
  471. {
  472.     LPPOINTFX4D     lpPoints;
  473.     
  474.     lpPoints=lpSrcPoints;
  475.     
  476.     for (;numpoints>0;numpoints--)
  477.     {
  478.     lpPoints->x=fxmul(lpPoints->x,FX(x));
  479.     lpPoints->y=fxmul(lpPoints->y,FX(y));
  480.     lpPoints->z=fxmul(lpPoints->z,FX(z));
  481.     lpPoints++;
  482.     }
  483.     
  484. }
  485.  
  486. void RotPoly(LPPOINTFX4D lpSrcPoints, WORD numpoints, 
  487.     FIXED4D xdegrees, FIXED4D ydegrees, FIXED4D zdegrees)
  488. {
  489.     FIXED4D tx;
  490.     FIXED4D ty;
  491.     FIXED4D tz;
  492.     
  493.     FIXED4D tcos;
  494.     FIXED4D tsin;
  495.     FIXED4D tycos;
  496.     FIXED4D tysin;
  497.     FIXED4D tzcos;
  498.     FIXED4D tzsin;
  499.     LPPOINTFX4D     lpPoints;
  500.     
  501.     lpPoints=lpSrcPoints;
  502.     
  503.     tcos=fxcos(xdegrees);
  504.     tsin=fxsin(xdegrees);
  505.     tycos=fxcos(ydegrees);
  506.     tysin=fxsin(ydegrees);
  507.     tzcos=fxcos(zdegrees);
  508.     tzsin=fxsin(zdegrees);
  509.     
  510.     for(;numpoints>0;numpoints--)
  511.     {
  512. // x Rotate...    (heading)
  513.     tx=lpPoints->x;
  514.     ty=lpPoints->y;
  515.     tz=lpPoints->z;
  516.     
  517. // These are rotates about the object, not relative to the user view
  518.  
  519. // z rotate... 
  520.     lpPoints->x=(fxsub(fxmul(tx,tzcos), fxmul(ty,tzsin)));
  521.     lpPoints->y=(fxadd(fxmul(tx,tzsin), fxmul(ty,tzcos)));
  522. // x Rotate... 
  523.  
  524.     ty=lpPoints->y;
  525.     lpPoints->y=(fxsub(fxmul(ty,tcos), fxmul(tz,tsin)));
  526.     lpPoints->z=(fxadd(fxmul(ty,tsin), fxmul(tz,tcos)));
  527.     
  528. // y Rotate...
  529.     tx=lpPoints->x;
  530.     tz=lpPoints->z;
  531.     lpPoints->x=(fxsub(fxmul(tx,tycos), fxmul(tz,tysin)));
  532.     lpPoints->z=(fxsub(fxmul(tx,tysin), fxmul(tz,tycos)));
  533.  
  534.     
  535.     lpPoints++;
  536.     }
  537.     
  538. }
  539.  
  540. void xlatPoly(LPPOINTFX4D lpSrcPoints, int x, int y, int z, WORD numpoints)
  541. {
  542.     LPPOINTFX4D     lpPoints;
  543.     
  544.     lpPoints=lpSrcPoints;
  545.     
  546.     for (;numpoints>0;numpoints--)
  547.     {
  548.     lpPoints->x=fxadd(lpPoints->x,FX(x));
  549.     lpPoints->y=fxadd(lpPoints->y,FX(y));
  550.     lpPoints->z=fxadd(lpPoints->z,FX(z));
  551.     lpPoints++;
  552.     }
  553. }
  554.  
  555. void viewPoly(LPPOINT lppts, LPPOINTFX4D lpSrcPoints, WORD numpoints)
  556. {
  557.     LPPOINTFX4D     lpPoints;
  558.     
  559.     lpPoints=lpSrcPoints;
  560.     
  561.     for (;numpoints>0;numpoints--)
  562.     {
  563.     lppts->x=FXINT(lpPoints->x);
  564.     lppts->y=FXINT(lpPoints->y);
  565.     lpPoints++;
  566.     lppts++;
  567.     }
  568. }
  569.  
  570. void CopyPoly(LPPOINTFX4D lpDest, LPPOINTFX4D lpSrcPoints, WORD numpoints)
  571. {
  572.     LPPOINTFX4D     lpSrc;
  573.     
  574.     lpSrc=lpSrcPoints;
  575.     
  576.     for (;numpoints>0;numpoints--)
  577.     {
  578.     lpDest->x=lpSrc->x;
  579.     lpDest->y=lpSrc->y;
  580.     lpDest->z=lpSrc->z;
  581.     lpDest++;
  582.     lpSrc++;
  583.     }
  584. }
  585.  
  586. void drawpolys(HDC hdc, LPPOLY lppolyin, WORD numpolys, LPPOINT lppts)
  587. {
  588.     HBRUSH  hBrush;
  589.     LPPOLY lppcur;
  590.     HANDLE h;
  591.     NPPOINT ppnts;
  592.     NPPOINT ppt;
  593.     int i,j;
  594.     
  595.     h=LocalAlloc(LPTR,sizeof(POINT)*MAXPTS);
  596.     ppnts=(NPPOINT)LocalLock(h);
  597.     if(!ppnts)
  598.     return;
  599.     
  600.     zSort(lppolyin,numpolys);
  601.     
  602.     for(numpolys=0;numpolys<nZPolys;numpolys++)
  603.     {
  604.     lppcur=&lppolyin[Zlist[numpolys]];
  605.     
  606.     i=lppcur->len;
  607.     for(i=0,ppt=ppnts;i<lppcur->len;i++,ppt++)
  608.     {
  609.         *ppt=lppts[lppcur->ipt[i]];
  610.     }
  611.     
  612.     if(fUseCustom)
  613.     {
  614.         DIBTriangle(lpdib, ppnts, Zlist[numpolys]+17);   //rand() % 255);
  615.         if (!fNullPen)
  616.         Polyline(hdc, ppnts, lppcur->len);
  617.     }
  618.     else if (fUseGDI)
  619.     {
  620.         hBrush = CreateSolidBrush(lppcur->rgb);
  621.     
  622.         hBrush = SelectObject(hdc, hBrush);
  623.         Polygon(hdc, ppnts,lppcur->len);
  624.         DeleteObject(SelectObject(hdc, hBrush));
  625.     }
  626.     else // use special pat blit
  627.     {
  628.         hBrush = CreateSolidBrush(lppcur->rgb);
  629.     
  630.         hBrush = SelectObject(hdc, hBrush);
  631.         Triangle(hdc, ppnts);
  632.         if (!fNullPen)
  633.         Polyline(hdc, ppnts, lppcur->len+1);
  634.         DeleteObject(SelectObject(hdc, hBrush));
  635.     }
  636.    
  637.     }
  638.     
  639.     LocalUnlock(h);
  640.     LocalFree(h);
  641. }
  642.  
  643. void calcpoly(LPPOINT lppts, LPPOINTFX4D lpSrc, WORD numpoints, 
  644.     int xcenter, int ycenter, int zcenter, 
  645.     int xscale, int yscale, int zscale, 
  646.     FIXED4D xRotate, FIXED4D yRotate, FIXED4D zRotate)
  647. {
  648.     WORD vxRot, vyRot, vzRot;
  649.     
  650.     vxRot=0;
  651.     vyRot=0;
  652.     vzRot=0;
  653.  
  654. // it would be faster to combine all these transformation
  655. // into matrix, but this is a little easier to understand.
  656.  
  657. // If you want to do real 3-D, Don't do it this way.
  658.     CopyPoly(CPOINTSQ, lpSrc, numpoints);
  659.     ScalePoly(CPOINTSQ, xscale,  yscale, zscale, numpoints);
  660.     RotPoly(CPOINTSQ, numpoints, xRotate, yRotate, zRotate);
  661.     viewPoly(lppts, CPOINTSQ, numpoints);
  662. }
  663.  
  664. /*----------------------------------------------------------------------------*\
  665. |   AppPaint(hwnd, hdc)                                |
  666. |                                                                              |
  667. |   Description:                                                               |
  668. |       The paint function.  Right now this does nothing.                      |
  669. |                                                                              |
  670. |   Arguments:                                       |
  671. |    hwnd         window painting into                       |
  672. |    hdc         display context to paint to                   |
  673. |                                                                              |
  674. |   Returns:                                                                   |
  675. |       nothing                                                                |
  676. |                                                                              |
  677. \*----------------------------------------------------------------------------*/
  678. AppPaint (HWND hwnd, HDC hdc)
  679. {
  680.     RECT    rc;
  681.     LPPOINTFX4D lpPIt;
  682.     HPEN hPen;
  683.     HPEN hPenO;
  684.  
  685.     ghdc=hdc;
  686.     
  687.     GetClientRect(hwnd,&rc);
  688.     
  689. //    DrawFrame(hdc);
  690.     
  691.     fDrawn=FALSE;
  692.   
  693.     ghdc=0;
  694.     return TRUE;
  695. }
  696.  
  697. void xlatCopyPoints(LPPOINT lpptsrc, WORD numpts, LPPOINT lpptdest, 
  698.     int xoff, int yoff)
  699. {
  700.     while(numpts--)
  701.     {
  702.     *lpptdest=*lpptsrc;
  703.     lpptdest->x+=xoff;
  704.     lpptdest->y+=yoff;
  705.     lpptdest++;
  706.     lpptsrc++;
  707.     }
  708. }
  709.  
  710. static drawcount=0;
  711.  
  712. void DrawFrame(void)
  713. {
  714.     WORD i;
  715.     POINT pts[MAXPTS];
  716.     RECT rc;
  717.  
  718.     HPALETTE hpalT;
  719.     HDC hdc;
  720.  
  721.     if(!fUseDIB)
  722.     {
  723.     hdc = GetDC(hwndApp);
  724.     
  725.     GetClientRect(hwndApp,&rc);
  726.     if (hpalApp)
  727.     {
  728.         hpalT = SelectPalette(hdc,hpalApp,FALSE);
  729.         RealizePalette(hdc);
  730.     }
  731.  
  732.     }
  733.     else
  734.     {
  735.     if(fDibCur)
  736.     {
  737.         hdc=hdcDib2;
  738.         lpdib=lpdib2;
  739.     }
  740.     else
  741.     {
  742.         hdc=hdcDib1;
  743.         lpdib=lpdib1;
  744.     }
  745.     
  746.     }
  747.  
  748.     ghdc=hdc;
  749.     
  750.     if (fNullPen)
  751.     SelectObject(hdc, GetStockObject(NULL_PEN));
  752.  
  753.     calcpoly(PNTS, POINTSQ, macPoint,
  754.         0, 0, 0,
  755.         wScaleX, wScaleY, wScaleZ,
  756.         FX(wxRot), FX(wyRot), FX(wzRot)
  757.         );
  758.  
  759.     // set background
  760.     // clear to white.
  761.     PatBlt(hdc,0,0,xClient,yClient,WHITENESS);
  762.         
  763.     for(i=0;i<NUMBALLS;i++)
  764.     {
  765.     xlatCopyPoints(PNTS, macPoint, pts, balls[i].x,balls[i].y);
  766.     drawpolys(hdc, POLYS, macPoly, pts);
  767.     }
  768.     
  769.     ghdc=0;
  770.     
  771.     drawcount++;
  772.     
  773.     if(!fUseDIB)
  774.     {
  775.     if (hpalApp)
  776.         SelectPalette(hdc,hpalT,FALSE);
  777.     
  778.         
  779.     ReleaseDC(hwndApp,hdc);
  780.     }
  781.     else
  782.     {
  783.     if((drawcount & wskipmask) == drawcount)
  784.         redraw();
  785.     
  786.     if(!fUseBlit)
  787.     {
  788.         // switch current dibs if delta-frame
  789.         fDibCur=!fDibCur;
  790.         // need to copy cur to last...
  791.     }
  792.     }
  793. }
  794.  
  795. /*----------------------------------------------------------------------------*\
  796. |                                                                              |
  797. |   w i n d o w   p r o c s                                                    |
  798. |                                                                              |
  799. \*----------------------------------------------------------------------------*/
  800.  
  801. /*----------------------------------------------------------------------------*\
  802. |   AppWndProc( hwnd, uiMessage, wParam, lParam )                   |
  803. |                                                                              |
  804. |   Description:                                                               |
  805. |       The window proc for the app's main (tiled) window.  This processes all |
  806. |       of the parent window's messages.                                       |
  807. |                                                                              |
  808. |   Arguments:                                                                 |
  809. |    hwnd        window handle for the window                   |
  810. |       uiMessage       message number                                         |
  811. |       wParam          message-dependent                                      |
  812. |       lParam          message-dependent                                      |
  813. |                                                                              |
  814. |   Returns:                                                                   |
  815. |       0 if processed, nonzero if ignored                                     |
  816. |                                                                              |
  817. \*----------------------------------------------------------------------------*/
  818. LONG FAR PASCAL AppWndProc(hwnd, msg, wParam, lParam)
  819.     HWND     hwnd;
  820.     unsigned msg;
  821.     WORD     wParam;
  822.     long     lParam;
  823. {
  824.     PAINTSTRUCT ps;
  825.     BOOL        f;
  826.     HDC         hdc;
  827.     WORD i;
  828.  
  829.     switch (msg) 
  830.     {
  831.     case WM_ACTIVATEAPP:
  832.         fActiveApp=wParam;
  833.         break;
  834.         
  835.     case WM_INITMENU:
  836.         CheckMenuItem((HMENU)wParam,MENU_FILL,
  837.             fFill ? MF_CHECKED : MF_UNCHECKED);
  838.         if(fUseCustom)
  839.         {
  840.         CheckMenuItem((HMENU)wParam,MENU_USEGDI, MF_UNCHECKED);
  841.         CheckMenuItem((HMENU)wParam,MENU_USEPAT, MF_UNCHECKED);
  842.         CheckMenuItem((HMENU)wParam,MENU_USECUSTOM, MF_CHECKED);
  843.         }
  844.         else
  845.         {
  846.         CheckMenuItem((HMENU)wParam,MENU_USEGDI,
  847.             fUseGDI ? MF_CHECKED : MF_UNCHECKED);
  848.         CheckMenuItem((HMENU)wParam,MENU_USEPAT,
  849.             fUseGDI ? MF_UNCHECKED : MF_CHECKED);
  850.         CheckMenuItem((HMENU)wParam,MENU_USECUSTOM, MF_UNCHECKED);
  851.         }
  852.         
  853.         for(i=MENU_DIB_MIN;i<=MENU_DIB_MAX;i++)
  854.         {
  855.         EnableMenuItem((HMENU)wParam, i ,
  856.                 fUseDIB ?  MF_ENABLED : MF_GRAYED);
  857.         CheckMenuItem((HMENU)wParam, i, MF_UNCHECKED);
  858.         }
  859.         
  860. //        EnableMenuItem((HMENU)wParam, MENU_SHOWDF ,
  861. //                fUseBlit ?  MF_GRAYED : MF_ENABLED );
  862. //        if(!fUseBlit)
  863. //        CheckMenuItem((HMENU)wParam, 
  864. //            MENU_SHOWDF , fShowDF ? MF_CHECKED : MF_UNCHECKED);
  865. //            
  866. //        CheckMenuItem((HMENU)wParam, 
  867. //            fUseBlit ? MENU_BLIT : MENU_DF, MF_CHECKED);
  868.             
  869.         CheckMenuItem((HMENU)wParam, wUseSkip, MF_CHECKED);
  870.         
  871.             EnableMenuItem((HMENU)wParam,MENU_DIB,
  872.             hdcDib1 ?  MF_ENABLED : MF_GRAYED);
  873.             
  874.             EnableMenuItem((HMENU)wParam,MENU_USECUSTOM,
  875.             fUseDIB ?  MF_ENABLED : MF_GRAYED);
  876.             
  877.         CheckMenuItem((HMENU)wParam,MENU_DIB,
  878.             fUseDIB ? MF_CHECKED : MF_UNCHECKED);
  879.         CheckMenuItem((HMENU)wParam,MENU_SCREEN,
  880.             fUseDIB ? MF_UNCHECKED : MF_CHECKED);
  881.         
  882.         CheckMenuItem((HMENU)wParam,MENU_SOLID,
  883.             fSolidColors ? MF_CHECKED : MF_UNCHECKED);
  884.         CheckMenuItem((HMENU)wParam,MENU_NULLPEN,
  885.             fNullPen ? MF_CHECKED : MF_UNCHECKED);
  886.         CheckMenuItem((HMENU)wParam,MENU_BOXES,
  887.             fBoxes ? MF_CHECKED : MF_UNCHECKED);
  888.         break;
  889.     case WM_CREATE:
  890.         cxIcon=GetSystemMetrics(SM_CXICON);
  891.         cyIcon=GetSystemMetrics(SM_CYICON);
  892.  
  893.        // FALL THROUGH!!!!
  894.        
  895.        case WM_WININICHANGE:
  896.         crWindowText=GetSysColor(COLOR_WINDOWTEXT);
  897.         crWindowBk=GetSysColor(COLOR_WINDOW);
  898.         crHilightText=GetSysColor(COLOR_HIGHLIGHTTEXT);
  899.         crHilightBk=GetSysColor(COLOR_HIGHLIGHT);
  900.         break;
  901.  
  902.  
  903.         case WM_ERASEBKGND:
  904.             break;
  905.  
  906.         case WM_COMMAND:
  907.             return AppCommand(hwnd,msg,wParam,lParam);
  908.  
  909.     case WM_DESTROY:
  910.         PostQuitMessage(0);
  911.         break;
  912.  
  913.     case WM_SIZE:
  914. #ifndef FIXEDSIZE
  915.         xClient = LOWORD(lParam);
  916.         yClient = HIWORD(lParam);
  917. #else
  918.         xClient = 400;
  919.         yClient = 400;
  920. #endif        
  921.         for(i=0;i<NUMBALLS;i++)
  922.         {
  923.         balls[i].x=i*100+xClient/4;
  924.         balls[i].y=i*100+xClient/4;
  925.         }
  926.         break;
  927.  
  928.     case WM_CLOSE:
  929.         break;
  930.  
  931.         case WM_PAINT:
  932.             BeginPaint(hwnd,&ps);
  933.             AppPaint (hwnd,ps.hdc);
  934.             EndPaint(hwnd,&ps);
  935.         return 0L;
  936.     }
  937.     return DefWindowProc(hwnd,msg,wParam,lParam);
  938. }
  939.  
  940. LONG NEAR PASCAL AppCommand (hwnd, msg, wParam, lParam)
  941.     HWND     hwnd;
  942.     unsigned msg;
  943.     WORD     wParam;
  944.     long     lParam;
  945. {
  946.     LPSTR     qch;
  947.     int     fh;
  948.     OFSTRUCT of;
  949.     DWORD starttime;
  950.     DWORD endtime;
  951.     int i;
  952.     HCURSOR  hcur;
  953.     
  954.     switch(wParam)
  955.     {
  956.     case MENU_SHOWDF:
  957.         fShowDF=!fShowDF;
  958.         break;
  959.         
  960.     case MENU_USECUSTOM:
  961.         fUseCustom=!fUseCustom;
  962.         break;
  963.             
  964.     case MENU_SKIP2:
  965.         case MENU_SKIP4:
  966.     case MENU_SKIP8:
  967.     case MENU_SKIP16:
  968.     case MENU_SKIPALL:
  969.     case MENU_EVERY:
  970.         wskipmask=askipmask[wParam-MENU_SKIP_MIN];
  971.         wUseSkip=wParam;
  972.         break;
  973.             
  974.     case MENU_REDRAW:
  975.         if(!fUseBlit)
  976.         {
  977.         HANDLE hdib;
  978.         HDC hdc;
  979.         HPALETTE hpalT;
  980.  
  981.         
  982.         hdc = GetDC(hwndApp);
  983.  
  984.         if (hpalApp)
  985.         {
  986.             hpalT = SelectPalette(hdc,hpalApp,FALSE);
  987.             RealizePalette(hdc);
  988.         }
  989.     
  990.         hdib=fDibCur ? hdib1 : hdib2;
  991.     
  992.         SetDibUsage(hdib,hpalApp,DIB_PAL_COLORS);
  993.         
  994.         DibBlt(hdc,0,0,-1,-1, hdib, 0,0, SRCCOPY, DIB_PAL_COLORS);
  995.     
  996.         SetDibUsage(hdib, hpalApp, DIB_RGB_COLORS);    // PAL
  997.             
  998.         if (hpalApp)
  999.             SelectPalette(hdc,hpalT,FALSE);
  1000.         
  1001.         ReleaseDC(hwndApp,hdc);
  1002.         }
  1003.         else
  1004.         redraw();
  1005.         break;
  1006.             
  1007.     case MENU_DIB:
  1008.     case MENU_SCREEN:
  1009.         fUseDIB=!fUseDIB;
  1010.         if(!fUseDIB)
  1011.         fUseCustom=FALSE;
  1012.         break;
  1013.             
  1014.     case MENU_USEPAT:
  1015.     case MENU_USEGDI:
  1016.         fUseGDI = !fUseGDI;
  1017.         fUseCustom=FALSE;
  1018.         break;
  1019.             
  1020.     case MENU_BOXES:
  1021.         fBoxes = !fBoxes;
  1022.         break;
  1023.  
  1024.     case MENU_SOLID:
  1025.         fSolidColors = !fSolidColors;
  1026.         break;
  1027.  
  1028.     case MENU_NULLPEN:
  1029.         fNullPen = !fNullPen;
  1030.         break;
  1031.  
  1032.         case MENU_TIMEIT:
  1033.         hcur = SetCursor(LoadCursor(NULL,IDC_WAIT));
  1034.  
  1035.         starttime=GetCurrentTime();
  1036.         for(i=0;i<50;i++)
  1037.         {
  1038.         if(fAutoRotX)
  1039.         {
  1040.             wOxRot=wxRot;
  1041.             wxRot+=wRotxAmount;
  1042.         
  1043.             while(wxRot>=360)    // normalize
  1044.             wxRot-=360;
  1045.             while(wxRot<0)    // ditto
  1046.             wxRot+=360;
  1047.         
  1048.         }
  1049.         if(fAutoRotY)
  1050.         {
  1051.         
  1052.             wOyRot=wyRot;
  1053.             wyRot+=wRotyAmount;
  1054.         
  1055.             while(wyRot>=360)    // normalize
  1056.             wyRot-=360;
  1057.             while(wyRot<0)    // ditto
  1058.             wyRot+=360;
  1059.         
  1060.         }
  1061.         if(fAutoRotZ)
  1062.         {
  1063.         
  1064.             wOzRot=wzRot;
  1065.             wzRot+=wRotzAmount;
  1066.         
  1067.             while(wzRot>=360)    // normalize
  1068.             wzRot-=360;
  1069.             while(wzRot<0)    // ditto
  1070.             wzRot+=360;
  1071.         
  1072.  
  1073.         }
  1074.         DrawFrame();
  1075.         }
  1076.         
  1077.         endtime=GetCurrentTime();
  1078.         SetCursor(hcur);
  1079.         
  1080.         wsprintf(acText,"%d iterations took %ld MS",i,endtime-starttime);
  1081.         MessageBox(hwndApp,acText,"Timing",MB_APPLMODAL | MB_ICONINFORMATION| MB_OK);
  1082.         
  1083.         break;
  1084.         
  1085.     case MENU_FILL:
  1086.         fFill=!fFill;
  1087.         InvalidateRect(hwnd,NULL,TRUE);
  1088.         fDrawn=FALSE;
  1089.         break;
  1090.         
  1091.     case MENU_ABOUT:
  1092.             fDialog(ABOUTBOX,hwnd,AppAbout);
  1093.             break;
  1094.         
  1095.     case MENU_EXIT:
  1096.         PostMessage(hwnd,WM_CLOSE,0,0L);
  1097.             break;
  1098.     }
  1099.     return 0L;
  1100. }
  1101.  
  1102. /*----------------------------------------------------------------------------*\
  1103. |   ErrMsg - Opens a Message box with a error message in it.  The user can     |
  1104. |            select the OK button to continue                                  |
  1105. \*----------------------------------------------------------------------------*/
  1106. int ErrMsg (LPSTR sz,...)
  1107. {
  1108.     char ach[128];
  1109.  
  1110.     wsprintf (ach,sz,(LPSTR)(&sz+1));     /* Format the string */
  1111.     MessageBox(NULL,ach,NULL,MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2|MB_SYSTEMMODAL);
  1112.     return FALSE;
  1113. }
  1114.  
  1115. /*----------------------------------------------------------------------------*\
  1116. |   fDialog(id,hwnd,fpfn)                               |
  1117. |                                           |
  1118. |   Description:                                                               |
  1119. |    This function displays a dialog box and returns the exit code.           |
  1120. |    the function passed will have a proc instance made for it.           |
  1121. |                                           |
  1122. |   Arguments:                                                                 |
  1123. |    id        resource id of dialog to display               |
  1124. |    hwnd        parent window of dialog                    |
  1125. |    fpfn        dialog message function                    |
  1126. |                                                                              |
  1127. |   Returns:                                                                   |
  1128. |    exit code of dialog (what was passed to EndDialog)               |
  1129. |                                                                              |
  1130. \*----------------------------------------------------------------------------*/
  1131. BOOL fDialog(int id,HWND hwnd,FARPROC fpfn)
  1132. {
  1133.     BOOL    f;
  1134.     HANDLE    hInst;
  1135.  
  1136.     hInst = GetWindowWord(hwnd,GWW_HINSTANCE);
  1137.     fpfn  = MakeProcInstance(fpfn,hInst);
  1138.     f = DialogBox(hInst,MAKEINTRESOURCE(id),hwnd,fpfn);
  1139.     FreeProcInstance (fpfn);
  1140.     return f;
  1141. }
  1142.  
  1143.  
  1144. HANDLE FAR PASCAL hread (LPSTR szFile, HANDLE h)
  1145. {
  1146.     int    fh;
  1147.     LPSTR  qch;
  1148.     LONG   len;
  1149.     WORD   cb;
  1150.     OFSTRUCT rOF;
  1151.     HCURSOR  hcur;
  1152.  
  1153.     fh = OpenFile(szFile,&rOF,OF_READ);
  1154.     if (fh == -1)
  1155.     return NULL;
  1156.  
  1157.     hcur = SetCursor(LoadCursor(NULL,IDC_WAIT));
  1158.  
  1159.     len = _llseek(fh,0L,SEEK_END);
  1160.     _llseek(fh,0L,SEEK_SET);
  1161.  
  1162.     if (h)
  1163.     h = GlobalReAlloc(h,len+1,0);
  1164.     else
  1165.     h = GlobalAlloc(GHND,len+1);
  1166.  
  1167.  
  1168.     qch = GlobalLock(h);
  1169.  
  1170.     cb = _lread(fh,qch,(WORD)len);
  1171.     qch[cb] = 0;
  1172.     GlobalUnlock(h);
  1173.  
  1174.     _lclose(fh);
  1175.  
  1176.     SetCursor(hcur);
  1177.     return h;
  1178. }
  1179.  
  1180.  
  1181. zSort(LPPOLY lpPoly, WORD numpolys)
  1182. {
  1183.     LPPOLY     pPoly;
  1184. //    int       nPolys;
  1185.     int       i, i2;
  1186.     RECT rc;
  1187.     HBRUSH    hBrush;
  1188.  
  1189.     GetClientRect(hwndApp,&rc);
  1190.     
  1191.     /*
  1192.      * Calculate the bounding boxes for all the polys.
  1193.      */
  1194.  
  1195.     nZPolys = 0;
  1196.     for (pPoly = lpPoly,i = 0; i < numpolys; i++,pPoly++)
  1197.     {
  1198.     if (!fNormal || fNormalTest(pPoly))
  1199.     {
  1200.         Zlist[nZPolys++] = i;
  1201.     }
  1202.     }
  1203.  
  1204. }
  1205.  
  1206.  
  1207. #if 0
  1208. void DumpIt(void)
  1209. {
  1210.     int i;
  1211.     int j;
  1212.     RECT    rc;
  1213.  
  1214.     ghdc=GetDC(hwndApp);
  1215.     
  1216.     GetClientRect(hwndApp,&rc);
  1217.     calcpoly(PNTS, POINTSQ, macPoint,
  1218.         rc.right/2, rc.bottom/2, 0,
  1219.         wScaleX, wScaleY, wScaleZ,
  1220.         FX(wxRot), FX(wyRot), FX(wzRot)
  1221.             );
  1222.  
  1223.     WinPrintf("POLYGONS:\n");
  1224.     for (i = 0; i < macPoly; i++)
  1225.     {
  1226.     WinPrintf("  %2d: cnt:%02d RGB(%d,%d,%d) N:",i,POLYS[i].len,
  1227.             GetRValue(POLYS[i].rgb),
  1228.             GetGValue(POLYS[i].rgb),
  1229.             GetBValue(POLYS[i].rgb));
  1230.         WinPrintf(" Y:");
  1231.         PrintFx(POLYS[i].ymin);
  1232.         WinPrintf(" ");
  1233.         PrintFx(POLYS[i].ymax);
  1234.         WinPrintf(" Z:");
  1235.         PrintFx(POLYS[i].zmin);
  1236.         WinPrintf(" ");
  1237.         PrintFx(POLYS[i].zmax);
  1238.         WinPrintf("\n");
  1239.  
  1240.  
  1241. //    WinPrintf("\n");
  1242.     for (j = 0; j < POLYS[i].len;)
  1243.     {
  1244.          WinPrintf("    %02d  E:%2d: P:%2d",j,POLYS[i].ied[j],POLYS[i].ipt[j]);
  1245.          j++;
  1246.          if(!j%4)
  1247.          WinPrintf("\n");
  1248.     }
  1249.     WinPrintf("\n");
  1250.     }
  1251.  
  1252.     WinPrintf("POINTSQ:\n");
  1253.     for (i = 0; i < macPoint; i++)
  1254.     {
  1255.     WinPrintf("  %2d:",i);
  1256.     PrintPoint(POINTSQ[i]);
  1257.     WinPrintf(" ");
  1258.     PrintPoint(CPOINTSQ[i]);
  1259.     WinPrintf("\n");
  1260.     }
  1261.  
  1262. //    zSort(POLYS, macPoly);
  1263.  
  1264.     WinPrintf("POLYGONS: (Z Sorted)\n");
  1265.     for (i = 0; i < nZPolys; i++)
  1266.     {
  1267.     WinPrintf("  %2d[%2d]: cnt:%02d RGB(%d,%d,%d) N:",i,Zlist[i],POLYS[Zlist[i]].len,
  1268.             GetRValue(POLYS[Zlist[i]].rgb),
  1269.             GetGValue(POLYS[Zlist[i]].rgb),
  1270.             GetBValue(POLYS[Zlist[i]].rgb));
  1271. //        PrintVector(POLYS[i].nvec);
  1272. //        PrintFx(POLYS[i].xmin);
  1273. //        WinPrintf(" ");
  1274. //        PrintFx(POLYS[i].xmax);
  1275.         WinPrintf(" Y:");
  1276.         PrintFx(POLYS[Zlist[i]].ymin);
  1277.         WinPrintf(" ");
  1278.         PrintFx(POLYS[Zlist[i]].ymax);
  1279.         WinPrintf(" Z:");
  1280.         PrintFx(POLYS[Zlist[i]].zmin);
  1281.         WinPrintf(" ");
  1282.         PrintFx(POLYS[Zlist[i]].zmax);
  1283.         WinPrintf("\n");
  1284.  
  1285.  
  1286. //    WinPrintf("\n");
  1287.     for (j = 0; j < POLYS[i].len;)
  1288.     {
  1289.          WinPrintf("   %02d  E:%2d: P:%2d",j,POLYS[i].ied[j],POLYS[i].ipt[j]);
  1290.          j++;
  1291.          if(!(j%4))
  1292.          WinPrintf("\n");
  1293.     }
  1294.     WinPrintf("\n");
  1295.     }
  1296.  
  1297.     ReleaseDC(ghdc,hwndApp);
  1298. }
  1299. #endif
  1300.  
  1301. VECTORFX PolyNormal(LPPOLY pPoly, POINTFX4D FAR *pp)
  1302. {
  1303.     POINTFX4D  p1,p2,p3;
  1304.     VECTORFX n;
  1305.  
  1306.     /*
  1307.      * choose three points on the poly
  1308.      */
  1309.     p1 = pp[pPoly->ipt[0]];
  1310.     p2 = pp[pPoly->ipt[1]];
  1311.     p3 = pp[pPoly->ipt[2]];
  1312.  
  1313.     n = Normalize(Cross4D(Pdiff(p2,p1),Pdiff(p3,p2)));
  1314.     //n = Cross4D(Pdiff(p2,p1),Pdiff(p3,p2));
  1315.  
  1316.     return n;
  1317. }
  1318.  
  1319. fNormalTest (LPPOLY pPoly)
  1320. {
  1321.     VECTORFX v1,v2;
  1322.     POINTFX4D  p1,p2,p3;
  1323.     FIXED4D    z;
  1324.  
  1325.     /*
  1326.      *    Calculate ONLY the Z cordinate of the normal
  1327.      */
  1328.  
  1329.     /*
  1330.      * choose three points on the poly
  1331.      */
  1332.     p1 = CPOINTSQ[pPoly->ipt[0]];
  1333.     p2 = CPOINTSQ[pPoly->ipt[1]];
  1334.     p3 = CPOINTSQ[pPoly->ipt[2]];
  1335.  
  1336.     /*
  1337.      *    v1 = p2 - p1
  1338.      */
  1339.     v1.x = p2.x - p1.x;
  1340.     v1.y = p2.y - p1.y;
  1341.  
  1342.     /*
  1343.      *    v2 = p3 - p2
  1344.      */
  1345.     v2.x = p3.x - p2.x;
  1346.     v2.y = p3.y - p2.y;
  1347.  
  1348.     z = FXMUL(v1.x,v2.y) - FXMUL(v1.y,v2.x);
  1349.  
  1350.     return z >= 0;
  1351. }
  1352.  
  1353. void redraw(void)
  1354. {
  1355.     HDC hdc;
  1356.     HPALETTE hpalT;
  1357.     HANDLE hdib;
  1358.     HANDLE hdibs;
  1359.     RECT rc;
  1360.     
  1361.     hdib=fDibCur ? hdib2 : hdib1;
  1362.     
  1363.     hdc = GetDC(hwndApp);
  1364.     if (hpalApp)
  1365.     {
  1366.     hpalT = SelectPalette(hdc,hpalApp,FALSE);
  1367.     RealizePalette(hdc);
  1368.     }
  1369.     
  1370.     if(fUseBlit || !fDrawn)
  1371.     {
  1372.     SetDibUsage(hdib,hpalApp,DIB_PAL_COLORS);
  1373.     
  1374.     DibBlt(hdc,0,0,-1,-1, hdib, 0,0, SRCCOPY, DIB_PAL_COLORS);
  1375.     
  1376.     SetDibUsage(hdib, hpalApp, DIB_RGB_COLORS);    // PAL
  1377.     }
  1378.     
  1379.     if (hpalApp)
  1380.     SelectPalette(hdc,hpalT,FALSE);
  1381.     
  1382.     ReleaseDC(hwndApp,hdc);
  1383.     
  1384.     fDrawn=TRUE;
  1385. }
  1386.