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 >
Wrap
C/C++ Source or Header
|
1992-05-06
|
36KB
|
1,386 lines
/*----------------------------------------------------------------------------*\
| triqc.c - Sample code showing DIB usage and 386-specific code |
| |
| |
\*----------------------------------------------------------------------------*/
/*
(C) Copyright Microsoft Corp. 1991. All rights reserved.
You have a royalty-free right to use, modify, reproduce and
distribute the Sample Files (and/or any modified version) in
any way you find useful, provided that you agree that
Microsoft has no warranty obligations or liability for any
Sample Application Files which are modified.
*/
/*
WARNING:
Known Bug:
Don't resize client area too small because the DIB code doesn't check
bounds and if it is asked to draw outside of image, it will GP Fault
*/
/*----------------------------------------------------------------------------*\
| |
| g e n e r a l c o n s t a n t s |
| |
\*----------------------------------------------------------------------------*/
#define MAXSTR 80
#define NUMBALLS 3
/*----------------------------------------------------------------------------*\
| |
| i n c l u d e f i l e s |
| |
\*----------------------------------------------------------------------------*/
#define SWAP(x,y) ((x)^=(y)^=(x)^=(y))
// define if we want to force bitmap to <64K (ie, 320x200)
// note: bitmap include BITMAPINFOHEADER and pal
//#define SMALLBITMAP
//#define FIXEDSIZE
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h> // for rand()
#include <search.h>
#include "triq.h"
#include "4d/4d.h"
#include "view.h"
#include "dib.h"
typedef struct _tagBalls
{
int x; // offsets
int y;
} BALL, *PBALL, far *LPBALL;
BALL balls[NUMBALLS];
static char acText[MAXSTRING];
HDC ghdc;
COLORREF crWindowText;
COLORREF crWindowBk;
COLORREF crHilightText;
COLORREF crHilightBk;
COLORREF crWindowFrame;
int cxIcon;
int cyIcon;
unsigned Zlist[MAXPOLY]; // sorted list of polys
unsigned nZPolys; // number of sorted Z Polys
int wScaleX=3;
int wScaleY=3;
int wScaleZ=3;
int wRotxAmount=5;
int wRotyAmount=3;
int wRotzAmount=4;
WORD fAutoRotX=TRUE;
WORD fAutoRotY=TRUE;
WORD fAutoRotZ=TRUE;
WORD fDrawn=FALSE; // have we drawn it yet?
WORD fFill=FALSE;
WORD fNormal=TRUE;
WORD fShowDF=FALSE;
WORD wxRot=0;
WORD wOxRot=0;
WORD wyRot=0;
WORD wOyRot=0;
WORD wzRot=0;
WORD wOzRot=0;
POINTFX4D FAR *POINTSQ; // original 3d points
POINTFX4D FAR *CPOINTSQ; // converted 3d points
POINT FAR *PNTS; // projected 2d points
EDGE FAR *EDGES; // all edges in the scene
POLY FAR *POLYS; // all polys in the scene
static HPALETTE hpalApp;
static HPALETTE hpalT1;
static HPALETTE hpalT2;
BOOL fActiveApp=TRUE;
short xClient, yClient;
HDC hdcDib1;
HANDLE hdib1 = NULL; // memory DIB
HDC hdcDib2;
HANDLE hdib2 = NULL; // memory DIB
LPSTR lpdib1;
LPSTR lpdib2;
BOOL fDibCur=0;
HPALETTE hpalEx;
HPALETTE hpalSystem;
HPALETTE hpalPalette = NULL; // current real-palette
HPALETTE hpalCurrent = NULL; // current dib-palette
HANDLE hdibCurrent = NULL; // memory DIB
BOOL fUseBlit=FALSE;
BOOL fUseDIB=FALSE;
BOOL fUseCustom=FALSE;
BOOL fUseGDI=TRUE;
BOOL fSolidColors=FALSE;
BOOL fNullPen=TRUE;
BOOL fBoxes=FALSE;
unsigned wUseSkip=MENU_EVERY;
unsigned wskipmask=0xffff;
WORD askipmask[MENU_SKIP_MAX - MENU_SKIP_MIN +1]=
{
0xffff, // MENU_EVERY
0xfffe, // MENU_SKIP2
0xfff7, // MENU_SKIP4
0xfff0, // MENU_SKIP8
0xffe0, // MENU_SKIP16
0x0000 // MENU_SKIPALL
};
LPSTR lpdib;
/*----------------------------------------------------------------------------*\
| |
| g l o b a l v a r i a b l e s |
| |
\*----------------------------------------------------------------------------*/
static char szAppName[]="Ball Sample App";
static HANDLE hInstApp;
static HWND hwndApp;
PSTR szText;
char szString[MAXSTR];
/*----------------------------------------------------------------------------*\
| |
| f u n c t i o n d e f i n i t i o n s |
| |
\*----------------------------------------------------------------------------*/
LONG FAR PASCAL AppWndProc (HWND hwnd, unsigned uiMessage, WORD wParam, LONG lParam);
int ErrMsg (LPSTR sz,...);
BOOL fDialog(int id,HWND hwnd,FARPROC fpfn);
LONG NEAR PASCAL AppCommand(HWND hwnd, unsigned msg, WORD wParam, LONG lParam);
HANDLE FAR PASCAL hread (LPSTR szFile, HANDLE h);
void CopyPoly(LPPOINTFX4D lpDest, LPPOINTFX4D lpSrc, WORD numpoints);
zSort(LPPOLY lpPoly,WORD numpolys);
//////void DumpIt(void);
fNormalTest (LPPOLY pPoly);
BOOL fOverlap (FIXED4D min1,FIXED4D max1,FIXED4D min2,FIXED4D max2);
void redraw(void);
void DrawFrame(void);
VOID FAR PASCAL Triangle(HDC hDC, LPPOINT lpPoints);
VOID FAR PASCAL DIBTriangle(LPSTR lpdib, LPPOINT lpPoints, WORD crCol);
/*----------------------------------------------------------------------------*\
| AppAbout( hDlg, uiMessage, wParam, lParam ) |
| |
| Description: |
| This function handles messages belonging to the "About" dialog box. |
| The only message that it looks for is WM_COMMAND, indicating the use |
| has pressed the "OK" button. When this happens, it takes down |
| the dialog box. |
| |
| Arguments: |
| hDlg window handle of about dialog window |
| uiMessage message number |
| wParam message-dependent |
| lParam message-dependent |
| |
| Returns: |
| TRUE if message has been processed, else FALSE |
| |
\*----------------------------------------------------------------------------*/
BOOL FAR PASCAL AppAbout( hDlg, uiMessage, wParam, lParam )
HWND hDlg;
unsigned uiMessage;
WORD wParam;
long lParam;
{
switch (uiMessage)
{
case WM_COMMAND:
if (wParam == IDOK)
EndDialog(hDlg,TRUE);
break;
case WM_INITDIALOG:
return TRUE;
}
return FALSE;
}
/*----------------------------------------------------------------------------*\
| AppInit( hInst, hPrev) |
| |
| Description: |
| This is called when the application is first loaded into |
| memory. It performs all initialization that doesn't need to be done |
| once per instance. |
| |
| Arguments: |
| hInstance instance handle of current instance |
| hPrev instance handle of previous instance |
| |
| Returns: |
| TRUE if successful, FALSE if not |
| |
\*----------------------------------------------------------------------------*/
BOOL AppInit(HANDLE hInst,HANDLE hPrev,WORD sw,LPSTR szCmdLine)
{
WNDCLASS cls;
int dx,dy;
char ach[80];
HMENU hmenu;
HANDLE h;
LPSTR lpRes;
/* Save instance handle for DialogBoxs */
hInstApp = hInst;
PNTS = (VOID FAR * )GlobalLock(GlobalAlloc(GHND, (LONG)MAXPTS * sizeof(POINT)));
POINTSQ = (VOID FAR * )GlobalLock(GlobalAlloc(GHND, (LONG)MAXPTS * sizeof(PNT) ));
CPOINTSQ = (VOID FAR * )GlobalLock(GlobalAlloc(GHND, (LONG)MAXPTS * sizeof(PNT) ));
EDGES = (VOID FAR * )GlobalLock(GlobalAlloc(GHND, (LONG)MAXEDGE * sizeof(EDGE)));
POLYS = (VOID FAR * )GlobalLock(GlobalAlloc(GHND, (LONG)MAXPOLY * sizeof(POLY)));
if (!hPrev)
{
/*
* Register a class for the main application window
*/
cls.hCursor = LoadCursor(NULL,IDC_ARROW);
cls.hIcon = LoadIcon(hInst,MAKEINTATOM(ID_APP));
cls.lpszMenuName = MAKEINTATOM(ID_APP);
cls.lpszClassName = MAKEINTATOM(ID_APP);
cls.hbrBackground = (HBRUSH)COLOR_WINDOW + 1;
cls.hInstance = hInst;
cls.style = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
cls.lpfnWndProc = AppWndProc;
cls.cbWndExtra = 0;
cls.cbClsExtra = 0;
if (!RegisterClass(&cls))
return FALSE;
}
hpalApp = CreateExplicitPalette();
#ifndef FIXEDSIZE
dx = GetSystemMetrics (SM_CXSCREEN);
dy = GetSystemMetrics (SM_CYSCREEN);
#else
dx=400;
dy=400;
#endif
hwndApp = CreateWindow (MAKEINTATOM(ID_APP), // Class name
szAppName, // Caption
WS_OVERLAPPEDWINDOW, // Style bits
0, 0, // Position
dx,dy, // Size
(HWND)NULL, // Parent window (no parent)
(HMENU)NULL, // use class menu
(HANDLE)hInst, // handle to window instance
(LPSTR)NULL // no params to pass on
);
h=FindResource(hInst,MAKEINTATOM(AUTO),MAKEINTATOM(DATA3D));
if(!h)
return FALSE;
lpRes=LockResource(h = LoadResource(hInst,h));
if(!lpRes)
return FALSE;
ParseFile(lpRes);
UnlockResource(h);
FreeResource(h);
if(IsWindow(hwndApp))
ShowWindow(hwndApp,sw);
return TRUE;
}
/*----------------------------------------------------------------------------*\
| WinMain( hInst, hPrev, lpszCmdLine, cmdShow ) |
| |
| Description: |
| The main procedure for the App. After initializing, it just goes |
| into a message-processing loop until it gets a WM_QUIT message |
| (meaning the app was closed). |
| |
| Arguments: |
| hInst instance handle of this instance of the app |
| hPrev instance handle of previous instance, NULL if first |
| szCmdLine ->null-terminated command line |
| cmdShow specifies how the window is initially displayed |
| |
| Returns: |
| The exit code as specified in the WM_QUIT message. |
| |
\*----------------------------------------------------------------------------*/
int FAR PASCAL WinMain(HANDLE hInst, HANDLE hPrev, LPSTR szCmdLine, WORD sw)
{
MSG msg;
/* Call initialization procedure */
if (!AppInit(hInst,hPrev,sw,szCmdLine))
return FALSE;
hdib1 = CreateDib(8,xClient,yClient);
hdib2 = CreateDib(8,xClient,yClient);
SetDibUsage(hdib1, hpalApp, DIB_RGB_COLORS); // PAL
SetDibUsage(hdib2, hpalApp, DIB_RGB_COLORS); // PAL
lpdib1=GlobalLock(hdib1);
lpdib2=GlobalLock(hdib2);
hdcDib1 = CreateDC("DIB",NULL,NULL,lpdib1);
hdcDib2 = CreateDC("DIB",NULL,NULL,lpdib2);
if (hpalApp)
{
hpalT1 = SelectPalette(hdcDib1,CreateExplicitPalette(),FALSE);
RealizePalette(hdcDib1);
hpalT2 = SelectPalette(hdcDib2,CreateExplicitPalette(),FALSE);
RealizePalette(hdcDib2);
}
/*
* Polling messages from event queue
*/
if(!IsWindow(hwndApp))
goto cleanup;
while (TRUE)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if(fActiveApp)
{
if(fAutoRotX)
{
wOxRot=wxRot;
wxRot+=wRotxAmount;
while(wxRot>=360) // normalize
wxRot-=360;
while(wxRot<0) // ditto
wxRot+=360;
}
if(fAutoRotY)
{
wOyRot=wyRot;
wyRot+=wRotyAmount;
while(wyRot>=360) // normalize
wyRot-=360;
while(wyRot<0) // ditto
wyRot+=360;
}
if(fAutoRotZ)
{
wOzRot=wzRot;
wzRot+=wRotzAmount;
while(wzRot>=360) // normalize
wzRot-=360;
while(wzRot<0) // ditto
wzRot+=360;
}
DrawFrame();
}
else
WaitMessage();
}
}
cleanup:
if (hpalApp)
{
DeleteObject(SelectPalette(hdcDib1,hpalT1,FALSE));
DeleteObject(SelectPalette(hdcDib2,hpalT2,FALSE));
}
DeleteDC(hdcDib1);
DeleteDC(hdcDib2);
GlobalUnlock(hdib1);
GlobalUnlock(hdib2);
GlobalFree(hdib1);
GlobalFree(hdib2);
return msg.wParam;
}
void ScalePoly(LPPOINTFX4D lpSrcPoints, int x, int y, int z, WORD numpoints)
{
LPPOINTFX4D lpPoints;
lpPoints=lpSrcPoints;
for (;numpoints>0;numpoints--)
{
lpPoints->x=fxmul(lpPoints->x,FX(x));
lpPoints->y=fxmul(lpPoints->y,FX(y));
lpPoints->z=fxmul(lpPoints->z,FX(z));
lpPoints++;
}
}
void RotPoly(LPPOINTFX4D lpSrcPoints, WORD numpoints,
FIXED4D xdegrees, FIXED4D ydegrees, FIXED4D zdegrees)
{
FIXED4D tx;
FIXED4D ty;
FIXED4D tz;
FIXED4D tcos;
FIXED4D tsin;
FIXED4D tycos;
FIXED4D tysin;
FIXED4D tzcos;
FIXED4D tzsin;
LPPOINTFX4D lpPoints;
lpPoints=lpSrcPoints;
tcos=fxcos(xdegrees);
tsin=fxsin(xdegrees);
tycos=fxcos(ydegrees);
tysin=fxsin(ydegrees);
tzcos=fxcos(zdegrees);
tzsin=fxsin(zdegrees);
for(;numpoints>0;numpoints--)
{
// x Rotate... (heading)
tx=lpPoints->x;
ty=lpPoints->y;
tz=lpPoints->z;
// These are rotates about the object, not relative to the user view
// z rotate...
lpPoints->x=(fxsub(fxmul(tx,tzcos), fxmul(ty,tzsin)));
lpPoints->y=(fxadd(fxmul(tx,tzsin), fxmul(ty,tzcos)));
// x Rotate...
ty=lpPoints->y;
lpPoints->y=(fxsub(fxmul(ty,tcos), fxmul(tz,tsin)));
lpPoints->z=(fxadd(fxmul(ty,tsin), fxmul(tz,tcos)));
// y Rotate...
tx=lpPoints->x;
tz=lpPoints->z;
lpPoints->x=(fxsub(fxmul(tx,tycos), fxmul(tz,tysin)));
lpPoints->z=(fxsub(fxmul(tx,tysin), fxmul(tz,tycos)));
lpPoints++;
}
}
void xlatPoly(LPPOINTFX4D lpSrcPoints, int x, int y, int z, WORD numpoints)
{
LPPOINTFX4D lpPoints;
lpPoints=lpSrcPoints;
for (;numpoints>0;numpoints--)
{
lpPoints->x=fxadd(lpPoints->x,FX(x));
lpPoints->y=fxadd(lpPoints->y,FX(y));
lpPoints->z=fxadd(lpPoints->z,FX(z));
lpPoints++;
}
}
void viewPoly(LPPOINT lppts, LPPOINTFX4D lpSrcPoints, WORD numpoints)
{
LPPOINTFX4D lpPoints;
lpPoints=lpSrcPoints;
for (;numpoints>0;numpoints--)
{
lppts->x=FXINT(lpPoints->x);
lppts->y=FXINT(lpPoints->y);
lpPoints++;
lppts++;
}
}
void CopyPoly(LPPOINTFX4D lpDest, LPPOINTFX4D lpSrcPoints, WORD numpoints)
{
LPPOINTFX4D lpSrc;
lpSrc=lpSrcPoints;
for (;numpoints>0;numpoints--)
{
lpDest->x=lpSrc->x;
lpDest->y=lpSrc->y;
lpDest->z=lpSrc->z;
lpDest++;
lpSrc++;
}
}
void drawpolys(HDC hdc, LPPOLY lppolyin, WORD numpolys, LPPOINT lppts)
{
HBRUSH hBrush;
LPPOLY lppcur;
HANDLE h;
NPPOINT ppnts;
NPPOINT ppt;
int i,j;
h=LocalAlloc(LPTR,sizeof(POINT)*MAXPTS);
ppnts=(NPPOINT)LocalLock(h);
if(!ppnts)
return;
zSort(lppolyin,numpolys);
for(numpolys=0;numpolys<nZPolys;numpolys++)
{
lppcur=&lppolyin[Zlist[numpolys]];
i=lppcur->len;
for(i=0,ppt=ppnts;i<lppcur->len;i++,ppt++)
{
*ppt=lppts[lppcur->ipt[i]];
}
if(fUseCustom)
{
DIBTriangle(lpdib, ppnts, Zlist[numpolys]+17); //rand() % 255);
if (!fNullPen)
Polyline(hdc, ppnts, lppcur->len);
}
else if (fUseGDI)
{
hBrush = CreateSolidBrush(lppcur->rgb);
hBrush = SelectObject(hdc, hBrush);
Polygon(hdc, ppnts,lppcur->len);
DeleteObject(SelectObject(hdc, hBrush));
}
else // use special pat blit
{
hBrush = CreateSolidBrush(lppcur->rgb);
hBrush = SelectObject(hdc, hBrush);
Triangle(hdc, ppnts);
if (!fNullPen)
Polyline(hdc, ppnts, lppcur->len+1);
DeleteObject(SelectObject(hdc, hBrush));
}
}
LocalUnlock(h);
LocalFree(h);
}
void calcpoly(LPPOINT lppts, LPPOINTFX4D lpSrc, WORD numpoints,
int xcenter, int ycenter, int zcenter,
int xscale, int yscale, int zscale,
FIXED4D xRotate, FIXED4D yRotate, FIXED4D zRotate)
{
WORD vxRot, vyRot, vzRot;
vxRot=0;
vyRot=0;
vzRot=0;
// it would be faster to combine all these transformation
// into matrix, but this is a little easier to understand.
// If you want to do real 3-D, Don't do it this way.
CopyPoly(CPOINTSQ, lpSrc, numpoints);
ScalePoly(CPOINTSQ, xscale, yscale, zscale, numpoints);
RotPoly(CPOINTSQ, numpoints, xRotate, yRotate, zRotate);
viewPoly(lppts, CPOINTSQ, numpoints);
}
/*----------------------------------------------------------------------------*\
| AppPaint(hwnd, hdc) |
| |
| Description: |
| The paint function. Right now this does nothing. |
| |
| Arguments: |
| hwnd window painting into |
| hdc display context to paint to |
| |
| Returns: |
| nothing |
| |
\*----------------------------------------------------------------------------*/
AppPaint (HWND hwnd, HDC hdc)
{
RECT rc;
LPPOINTFX4D lpPIt;
HPEN hPen;
HPEN hPenO;
ghdc=hdc;
GetClientRect(hwnd,&rc);
// DrawFrame(hdc);
fDrawn=FALSE;
ghdc=0;
return TRUE;
}
void xlatCopyPoints(LPPOINT lpptsrc, WORD numpts, LPPOINT lpptdest,
int xoff, int yoff)
{
while(numpts--)
{
*lpptdest=*lpptsrc;
lpptdest->x+=xoff;
lpptdest->y+=yoff;
lpptdest++;
lpptsrc++;
}
}
static drawcount=0;
void DrawFrame(void)
{
WORD i;
POINT pts[MAXPTS];
RECT rc;
HPALETTE hpalT;
HDC hdc;
if(!fUseDIB)
{
hdc = GetDC(hwndApp);
GetClientRect(hwndApp,&rc);
if (hpalApp)
{
hpalT = SelectPalette(hdc,hpalApp,FALSE);
RealizePalette(hdc);
}
}
else
{
if(fDibCur)
{
hdc=hdcDib2;
lpdib=lpdib2;
}
else
{
hdc=hdcDib1;
lpdib=lpdib1;
}
}
ghdc=hdc;
if (fNullPen)
SelectObject(hdc, GetStockObject(NULL_PEN));
calcpoly(PNTS, POINTSQ, macPoint,
0, 0, 0,
wScaleX, wScaleY, wScaleZ,
FX(wxRot), FX(wyRot), FX(wzRot)
);
// set background
// clear to white.
PatBlt(hdc,0,0,xClient,yClient,WHITENESS);
for(i=0;i<NUMBALLS;i++)
{
xlatCopyPoints(PNTS, macPoint, pts, balls[i].x,balls[i].y);
drawpolys(hdc, POLYS, macPoly, pts);
}
ghdc=0;
drawcount++;
if(!fUseDIB)
{
if (hpalApp)
SelectPalette(hdc,hpalT,FALSE);
ReleaseDC(hwndApp,hdc);
}
else
{
if((drawcount & wskipmask) == drawcount)
redraw();
if(!fUseBlit)
{
// switch current dibs if delta-frame
fDibCur=!fDibCur;
// need to copy cur to last...
}
}
}
/*----------------------------------------------------------------------------*\
| |
| w i n d o w p r o c s |
| |
\*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*\
| AppWndProc( hwnd, uiMessage, wParam, lParam ) |
| |
| Description: |
| The window proc for the app's main (tiled) window. This processes all |
| of the parent window's messages. |
| |
| Arguments: |
| hwnd window handle for the window |
| uiMessage message number |
| wParam message-dependent |
| lParam message-dependent |
| |
| Returns: |
| 0 if processed, nonzero if ignored |
| |
\*----------------------------------------------------------------------------*/
LONG FAR PASCAL AppWndProc(hwnd, msg, wParam, lParam)
HWND hwnd;
unsigned msg;
WORD wParam;
long lParam;
{
PAINTSTRUCT ps;
BOOL f;
HDC hdc;
WORD i;
switch (msg)
{
case WM_ACTIVATEAPP:
fActiveApp=wParam;
break;
case WM_INITMENU:
CheckMenuItem((HMENU)wParam,MENU_FILL,
fFill ? MF_CHECKED : MF_UNCHECKED);
if(fUseCustom)
{
CheckMenuItem((HMENU)wParam,MENU_USEGDI, MF_UNCHECKED);
CheckMenuItem((HMENU)wParam,MENU_USEPAT, MF_UNCHECKED);
CheckMenuItem((HMENU)wParam,MENU_USECUSTOM, MF_CHECKED);
}
else
{
CheckMenuItem((HMENU)wParam,MENU_USEGDI,
fUseGDI ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem((HMENU)wParam,MENU_USEPAT,
fUseGDI ? MF_UNCHECKED : MF_CHECKED);
CheckMenuItem((HMENU)wParam,MENU_USECUSTOM, MF_UNCHECKED);
}
for(i=MENU_DIB_MIN;i<=MENU_DIB_MAX;i++)
{
EnableMenuItem((HMENU)wParam, i ,
fUseDIB ? MF_ENABLED : MF_GRAYED);
CheckMenuItem((HMENU)wParam, i, MF_UNCHECKED);
}
// EnableMenuItem((HMENU)wParam, MENU_SHOWDF ,
// fUseBlit ? MF_GRAYED : MF_ENABLED );
// if(!fUseBlit)
// CheckMenuItem((HMENU)wParam,
// MENU_SHOWDF , fShowDF ? MF_CHECKED : MF_UNCHECKED);
//
// CheckMenuItem((HMENU)wParam,
// fUseBlit ? MENU_BLIT : MENU_DF, MF_CHECKED);
CheckMenuItem((HMENU)wParam, wUseSkip, MF_CHECKED);
EnableMenuItem((HMENU)wParam,MENU_DIB,
hdcDib1 ? MF_ENABLED : MF_GRAYED);
EnableMenuItem((HMENU)wParam,MENU_USECUSTOM,
fUseDIB ? MF_ENABLED : MF_GRAYED);
CheckMenuItem((HMENU)wParam,MENU_DIB,
fUseDIB ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem((HMENU)wParam,MENU_SCREEN,
fUseDIB ? MF_UNCHECKED : MF_CHECKED);
CheckMenuItem((HMENU)wParam,MENU_SOLID,
fSolidColors ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem((HMENU)wParam,MENU_NULLPEN,
fNullPen ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem((HMENU)wParam,MENU_BOXES,
fBoxes ? MF_CHECKED : MF_UNCHECKED);
break;
case WM_CREATE:
cxIcon=GetSystemMetrics(SM_CXICON);
cyIcon=GetSystemMetrics(SM_CYICON);
// FALL THROUGH!!!!
case WM_WININICHANGE:
crWindowText=GetSysColor(COLOR_WINDOWTEXT);
crWindowBk=GetSysColor(COLOR_WINDOW);
crHilightText=GetSysColor(COLOR_HIGHLIGHTTEXT);
crHilightBk=GetSysColor(COLOR_HIGHLIGHT);
break;
case WM_ERASEBKGND:
break;
case WM_COMMAND:
return AppCommand(hwnd,msg,wParam,lParam);
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SIZE:
#ifndef FIXEDSIZE
xClient = LOWORD(lParam);
yClient = HIWORD(lParam);
#else
xClient = 400;
yClient = 400;
#endif
for(i=0;i<NUMBALLS;i++)
{
balls[i].x=i*100+xClient/4;
balls[i].y=i*100+xClient/4;
}
break;
case WM_CLOSE:
break;
case WM_PAINT:
BeginPaint(hwnd,&ps);
AppPaint (hwnd,ps.hdc);
EndPaint(hwnd,&ps);
return 0L;
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}
LONG NEAR PASCAL AppCommand (hwnd, msg, wParam, lParam)
HWND hwnd;
unsigned msg;
WORD wParam;
long lParam;
{
LPSTR qch;
int fh;
OFSTRUCT of;
DWORD starttime;
DWORD endtime;
int i;
HCURSOR hcur;
switch(wParam)
{
case MENU_SHOWDF:
fShowDF=!fShowDF;
break;
case MENU_USECUSTOM:
fUseCustom=!fUseCustom;
break;
case MENU_SKIP2:
case MENU_SKIP4:
case MENU_SKIP8:
case MENU_SKIP16:
case MENU_SKIPALL:
case MENU_EVERY:
wskipmask=askipmask[wParam-MENU_SKIP_MIN];
wUseSkip=wParam;
break;
case MENU_REDRAW:
if(!fUseBlit)
{
HANDLE hdib;
HDC hdc;
HPALETTE hpalT;
hdc = GetDC(hwndApp);
if (hpalApp)
{
hpalT = SelectPalette(hdc,hpalApp,FALSE);
RealizePalette(hdc);
}
hdib=fDibCur ? hdib1 : hdib2;
SetDibUsage(hdib,hpalApp,DIB_PAL_COLORS);
DibBlt(hdc,0,0,-1,-1, hdib, 0,0, SRCCOPY, DIB_PAL_COLORS);
SetDibUsage(hdib, hpalApp, DIB_RGB_COLORS); // PAL
if (hpalApp)
SelectPalette(hdc,hpalT,FALSE);
ReleaseDC(hwndApp,hdc);
}
else
redraw();
break;
case MENU_DIB:
case MENU_SCREEN:
fUseDIB=!fUseDIB;
if(!fUseDIB)
fUseCustom=FALSE;
break;
case MENU_USEPAT:
case MENU_USEGDI:
fUseGDI = !fUseGDI;
fUseCustom=FALSE;
break;
case MENU_BOXES:
fBoxes = !fBoxes;
break;
case MENU_SOLID:
fSolidColors = !fSolidColors;
break;
case MENU_NULLPEN:
fNullPen = !fNullPen;
break;
case MENU_TIMEIT:
hcur = SetCursor(LoadCursor(NULL,IDC_WAIT));
starttime=GetCurrentTime();
for(i=0;i<50;i++)
{
if(fAutoRotX)
{
wOxRot=wxRot;
wxRot+=wRotxAmount;
while(wxRot>=360) // normalize
wxRot-=360;
while(wxRot<0) // ditto
wxRot+=360;
}
if(fAutoRotY)
{
wOyRot=wyRot;
wyRot+=wRotyAmount;
while(wyRot>=360) // normalize
wyRot-=360;
while(wyRot<0) // ditto
wyRot+=360;
}
if(fAutoRotZ)
{
wOzRot=wzRot;
wzRot+=wRotzAmount;
while(wzRot>=360) // normalize
wzRot-=360;
while(wzRot<0) // ditto
wzRot+=360;
}
DrawFrame();
}
endtime=GetCurrentTime();
SetCursor(hcur);
wsprintf(acText,"%d iterations took %ld MS",i,endtime-starttime);
MessageBox(hwndApp,acText,"Timing",MB_APPLMODAL | MB_ICONINFORMATION| MB_OK);
break;
case MENU_FILL:
fFill=!fFill;
InvalidateRect(hwnd,NULL,TRUE);
fDrawn=FALSE;
break;
case MENU_ABOUT:
fDialog(ABOUTBOX,hwnd,AppAbout);
break;
case MENU_EXIT:
PostMessage(hwnd,WM_CLOSE,0,0L);
break;
}
return 0L;
}
/*----------------------------------------------------------------------------*\
| ErrMsg - Opens a Message box with a error message in it. The user can |
| select the OK button to continue |
\*----------------------------------------------------------------------------*/
int ErrMsg (LPSTR sz,...)
{
char ach[128];
wsprintf (ach,sz,(LPSTR)(&sz+1)); /* Format the string */
MessageBox(NULL,ach,NULL,MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2|MB_SYSTEMMODAL);
return FALSE;
}
/*----------------------------------------------------------------------------*\
| fDialog(id,hwnd,fpfn) |
| |
| Description: |
| This function displays a dialog box and returns the exit code. |
| the function passed will have a proc instance made for it. |
| |
| Arguments: |
| id resource id of dialog to display |
| hwnd parent window of dialog |
| fpfn dialog message function |
| |
| Returns: |
| exit code of dialog (what was passed to EndDialog) |
| |
\*----------------------------------------------------------------------------*/
BOOL fDialog(int id,HWND hwnd,FARPROC fpfn)
{
BOOL f;
HANDLE hInst;
hInst = GetWindowWord(hwnd,GWW_HINSTANCE);
fpfn = MakeProcInstance(fpfn,hInst);
f = DialogBox(hInst,MAKEINTRESOURCE(id),hwnd,fpfn);
FreeProcInstance (fpfn);
return f;
}
HANDLE FAR PASCAL hread (LPSTR szFile, HANDLE h)
{
int fh;
LPSTR qch;
LONG len;
WORD cb;
OFSTRUCT rOF;
HCURSOR hcur;
fh = OpenFile(szFile,&rOF,OF_READ);
if (fh == -1)
return NULL;
hcur = SetCursor(LoadCursor(NULL,IDC_WAIT));
len = _llseek(fh,0L,SEEK_END);
_llseek(fh,0L,SEEK_SET);
if (h)
h = GlobalReAlloc(h,len+1,0);
else
h = GlobalAlloc(GHND,len+1);
qch = GlobalLock(h);
cb = _lread(fh,qch,(WORD)len);
qch[cb] = 0;
GlobalUnlock(h);
_lclose(fh);
SetCursor(hcur);
return h;
}
zSort(LPPOLY lpPoly, WORD numpolys)
{
LPPOLY pPoly;
// int nPolys;
int i, i2;
RECT rc;
HBRUSH hBrush;
GetClientRect(hwndApp,&rc);
/*
* Calculate the bounding boxes for all the polys.
*/
nZPolys = 0;
for (pPoly = lpPoly,i = 0; i < numpolys; i++,pPoly++)
{
if (!fNormal || fNormalTest(pPoly))
{
Zlist[nZPolys++] = i;
}
}
}
#if 0
void DumpIt(void)
{
int i;
int j;
RECT rc;
ghdc=GetDC(hwndApp);
GetClientRect(hwndApp,&rc);
calcpoly(PNTS, POINTSQ, macPoint,
rc.right/2, rc.bottom/2, 0,
wScaleX, wScaleY, wScaleZ,
FX(wxRot), FX(wyRot), FX(wzRot)
);
WinPrintf("POLYGONS:\n");
for (i = 0; i < macPoly; i++)
{
WinPrintf(" %2d: cnt:%02d RGB(%d,%d,%d) N:",i,POLYS[i].len,
GetRValue(POLYS[i].rgb),
GetGValue(POLYS[i].rgb),
GetBValue(POLYS[i].rgb));
WinPrintf(" Y:");
PrintFx(POLYS[i].ymin);
WinPrintf(" ");
PrintFx(POLYS[i].ymax);
WinPrintf(" Z:");
PrintFx(POLYS[i].zmin);
WinPrintf(" ");
PrintFx(POLYS[i].zmax);
WinPrintf("\n");
// WinPrintf("\n");
for (j = 0; j < POLYS[i].len;)
{
WinPrintf(" %02d E:%2d: P:%2d",j,POLYS[i].ied[j],POLYS[i].ipt[j]);
j++;
if(!j%4)
WinPrintf("\n");
}
WinPrintf("\n");
}
WinPrintf("POINTSQ:\n");
for (i = 0; i < macPoint; i++)
{
WinPrintf(" %2d:",i);
PrintPoint(POINTSQ[i]);
WinPrintf(" ");
PrintPoint(CPOINTSQ[i]);
WinPrintf("\n");
}
// zSort(POLYS, macPoly);
WinPrintf("POLYGONS: (Z Sorted)\n");
for (i = 0; i < nZPolys; i++)
{
WinPrintf(" %2d[%2d]: cnt:%02d RGB(%d,%d,%d) N:",i,Zlist[i],POLYS[Zlist[i]].len,
GetRValue(POLYS[Zlist[i]].rgb),
GetGValue(POLYS[Zlist[i]].rgb),
GetBValue(POLYS[Zlist[i]].rgb));
// PrintVector(POLYS[i].nvec);
// PrintFx(POLYS[i].xmin);
// WinPrintf(" ");
// PrintFx(POLYS[i].xmax);
WinPrintf(" Y:");
PrintFx(POLYS[Zlist[i]].ymin);
WinPrintf(" ");
PrintFx(POLYS[Zlist[i]].ymax);
WinPrintf(" Z:");
PrintFx(POLYS[Zlist[i]].zmin);
WinPrintf(" ");
PrintFx(POLYS[Zlist[i]].zmax);
WinPrintf("\n");
// WinPrintf("\n");
for (j = 0; j < POLYS[i].len;)
{
WinPrintf(" %02d E:%2d: P:%2d",j,POLYS[i].ied[j],POLYS[i].ipt[j]);
j++;
if(!(j%4))
WinPrintf("\n");
}
WinPrintf("\n");
}
ReleaseDC(ghdc,hwndApp);
}
#endif
VECTORFX PolyNormal(LPPOLY pPoly, POINTFX4D FAR *pp)
{
POINTFX4D p1,p2,p3;
VECTORFX n;
/*
* choose three points on the poly
*/
p1 = pp[pPoly->ipt[0]];
p2 = pp[pPoly->ipt[1]];
p3 = pp[pPoly->ipt[2]];
n = Normalize(Cross4D(Pdiff(p2,p1),Pdiff(p3,p2)));
//n = Cross4D(Pdiff(p2,p1),Pdiff(p3,p2));
return n;
}
fNormalTest (LPPOLY pPoly)
{
VECTORFX v1,v2;
POINTFX4D p1,p2,p3;
FIXED4D z;
/*
* Calculate ONLY the Z cordinate of the normal
*/
/*
* choose three points on the poly
*/
p1 = CPOINTSQ[pPoly->ipt[0]];
p2 = CPOINTSQ[pPoly->ipt[1]];
p3 = CPOINTSQ[pPoly->ipt[2]];
/*
* v1 = p2 - p1
*/
v1.x = p2.x - p1.x;
v1.y = p2.y - p1.y;
/*
* v2 = p3 - p2
*/
v2.x = p3.x - p2.x;
v2.y = p3.y - p2.y;
z = FXMUL(v1.x,v2.y) - FXMUL(v1.y,v2.x);
return z >= 0;
}
void redraw(void)
{
HDC hdc;
HPALETTE hpalT;
HANDLE hdib;
HANDLE hdibs;
RECT rc;
hdib=fDibCur ? hdib2 : hdib1;
hdc = GetDC(hwndApp);
if (hpalApp)
{
hpalT = SelectPalette(hdc,hpalApp,FALSE);
RealizePalette(hdc);
}
if(fUseBlit || !fDrawn)
{
SetDibUsage(hdib,hpalApp,DIB_PAL_COLORS);
DibBlt(hdc,0,0,-1,-1, hdib, 0,0, SRCCOPY, DIB_PAL_COLORS);
SetDibUsage(hdib, hpalApp, DIB_RGB_COLORS); // PAL
}
if (hpalApp)
SelectPalette(hdc,hpalT,FALSE);
ReleaseDC(hwndApp,hdc);
fDrawn=TRUE;
}