home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windoware
/
WINDOWARE_1_6.iso
/
source
/
winfern
/
winfern.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-22
|
20KB
|
684 lines
/*
╔════════════════════════════════════════════════════════════════════════════╗
║ ║
║ Product: Fractal Fern Generator ║
║ Version: 1.0 ║
║ ║
║ Source: WINFERN.C ║
║ Revison: 1.0 ║
║ Description: Fractal Fern Generator based on code from the "Fractal ║
║ Programming in C" book by a very qualified author ║
║ (who's name I don't remember since I wrote this a year ago ║
║ and have since packed the book away somewhere) ║
║ Group: Generator code ║
║ ║
║ Author: René Schuchter, TouchGo(tm) Studios ║
║ ║
║ Date: April 22, 1991 (BBS version) ║
║ ║
║ This code is placed in the public domain. Any issues of copyright related ║
║ to using these examples from "Fractals Prograamming in C" for commercial ║
║ or other purposes is the sole responsibility of the person using this ║
║ code. ║
║ ║
║ This notice MUST remain with any versions of this code ditributed on a ║
║ BBS. ║
║ ║
║ The folowing files should be included with any distributed version: ║
║ ║
║ WINFERN.EXE ║
║ WINFERN.C ║
║ WINFERN.H ║
║ WINFERN.RC ║
║ WINFERN.DEF ║
║ WINFERN.ICO ║
║ WFABOUT.BMP ║
║ WFABOUT.RL4 (4 bpp RLE of original BMP ) ║
║ WINFERN ║
║ ║
║ For any questions or comments I can be reached at (916) 739-0100. ║
║ ║
╚════════════════════════════════════════════════════════════════════════════╝
*/
#include <windows.h>
#include <stdlib.h>
#include <math.h>
#include "winfern.h"
char szAppName[] = "Fractal Fern Generator v1.0",
szMsg[ 256 ];
DWORD dwFernColors[ 4 ] = { RGB( 255, 0, 0 ),
RGB( 0, 255, 0 ),
RGB( 0, 0, 255 ),
RGB( 255, 255, 0 ) };
HANDLE hInst;
HWND hWndAbout;
int PASCAL WinMain(
HANDLE hInstance,
HANDLE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow )
{
HWND hWnd;
MSG msg;
WNDCLASS wndclass;
if ( hPrevInstance )
return FALSE;
hInst = hInstance;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInst;
wndclass.hIcon = LoadIcon( hInst, "WFIcon" );
wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndclass.hbrBackground = GetStockObject( WHITE_BRUSH );
wndclass.lpszMenuName = (LPSTR)"WFMenu";
wndclass.lpszClassName = szAppName;
if ( !RegisterClass( &wndclass ) )
return FALSE;
wndclass.lpfnWndProc = AboutWndProc;
wndclass.hIcon = NULL;
wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndclass.hbrBackground = GetStockObject( WHITE_BRUSH );
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = "ABOUTCLASS";
if ( !RegisterClass( &wndclass ) )
return FALSE;
hWnd = CreateWindow( szAppName, /* Class */
szAppName, /* Title */
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
hInst,
NULL );
ShowWindow( hWnd, nCmdShow );
UpdateWindow( hWnd );
while ( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return msg.wParam;
}
long FAR PASCAL WndProc(
HWND hWnd,
WORD wMessage,
WORD wParam,
LONG lParam )
{
HDC hDC;
PAINTSTRUCT ps;
switch ( wMessage )
{
case WM_COMMAND:
switch ( wParam )
{
case IDM_DRAW:
InvalidateRect( hWnd, NULL, TRUE );
UpdateWindow( hWnd );
DrawFern( hWnd, RGB( 255, 0, 0 ) );
break;
case IDM_DRAW3D:
InvalidateRect( hWnd, NULL, TRUE );
UpdateWindow( hWnd );
Draw3DFern( hWnd, 4, dwFernColors );
break;
case IDM_ABOUT:
About( hWnd );
break;
}
break;
case WM_PAINT:
hDC = BeginPaint( hWnd, &ps );
EndPaint( hWnd, &ps );
break;
case WM_DESTROY:
PostQuitMessage( 0 );
break;
default:
return DefWindowProc( hWnd, wMessage, wParam, lParam );
}
return 0L;
}
void NEAR PASCAL DrawFern(
HWND hWnd,
DWORD dwColor )
{
double a[ 4 ],
b[ 4 ],
c[ 4 ],
d[ 4 ],
e[ 4 ],
f[ 4 ],
newx,
dXScreenVGARatio,
dYScreenVGARatio,
x,
y;
HCURSOR hCursor;
HDC hDC;
int i,
j,
k,
nClientWidth,
nClientHeight,
nXScreenSize,
nYScreenSize,
p[ 4 ],
px,
py,
xoffset,
xscale,
yoffset,
yscale;
RECT rRect;
/* constants optimized for VGA
*/
#define convert(x,y) {x = (x + 319); y = (175 - ((93*y) >> 7));}
hCursor = SetCursor( LoadCursor( NULL, IDC_WAIT ) );
a[0] = (double)0.0; a[1] = (double) 0.2; a[2] = (double)-0.15; a[3] = (double) 0.85;
b[0] = (double)0.0; b[1] = (double)-0.26; b[2] = (double) 0.28; b[3] = (double) 0.04;
c[0] = (double)0.0; c[1] = (double) 0.23; c[2] = (double) 0.26; c[3] = (double)-0.04;
d[0] = (double)0.16; d[1] = (double) 0.22; d[2] = (double) 0.24; d[3] = (double) 0.85;
e[0] = (double)0.0; e[1] = (double) 0.0; e[2] = (double) 0.0; e[3] = (double) 0.0;
f[0] = (double)0.0; f[1] = (double) 0.2; f[2] = (double) 0.2; f[3] = (double) 0.2;
p[0] = 328; p[1] = 2621; p[2] = 4915;
GetClientRect( hWnd, &rRect );
nClientWidth = rRect.right - rRect.left + 1;
nClientHeight = rRect.bottom - rRect.top + 1;
nXScreenSize = GetSystemMetrics( SM_CXSCREEN );
nYScreenSize = GetSystemMetrics( SM_CYSCREEN );
dXScreenVGARatio = (double)nXScreenSize / (double)640;
dYScreenVGARatio = (double)nYScreenSize / (double)480;
xscale = (int)( (double)300 * dXScreenVGARatio );
yscale = (int)( (double)300 * dYScreenVGARatio );
xoffset = (int)( (double) -50 * dXScreenVGARatio );
yoffset = (int)( (double)-180 * dYScreenVGARatio );
x = (double)0.0;
y = (double)0.0;
/* image offset for centering optimzed manually for VGA
so adjust offset constants ( 16 and 6 ) for screen size
*/
hDC = GetDC( hWnd );
SetMapMode( hDC, MM_ANISOTROPIC );
SetWindowOrg( hDC, -(int)( (double)( nXScreenSize / 16 ) *
pow( (double)dXScreenVGARatio, (double)2.0 ) ),
-(int)( (double)( nYScreenSize / 6 ) *
pow( (double)dYScreenVGARatio, (double)2.0 ) ) );
SetWindowExt( hDC, nXScreenSize, nYScreenSize );
SetViewportExt( hDC, nClientWidth, nClientHeight );
for ( i = 1; i <= 10000; i++ )
{
j = rand();
k = ( j < p[0] ) ? 0 : ( ( j < p[1] ) ? 1 : ( ( j < p[2] ) ? 2 : 3 ) );
newx = ( ( a[k] * x ) + ( b[k] * y ) + e[k] );
y = ( ( c[k] * x ) + ( d[k] * y ) + f[k] );
x = newx;
px = (int)( x * (double)xscale ) + xoffset;
py = (int)( y * (double)yscale ) + yoffset;
if ( ( px >= -( nXScreenSize / 2 ) ) &&
( px < ( nXScreenSize / 2 ) ) &&
( py >= -( nYScreenSize / 2 ) ) &&
( py < ( nYScreenSize / 2 ) ) )
{
convert( px, py);
SetPixel( hDC, px, py, dwColor );
}
}
ReleaseDC( hWnd, hDC );
SetCursor( hCursor );
}
void NEAR PASCAL Draw3DFern(
HWND hWnd,
int nFernCount,
DWORD *dwColor )
{
#define MAX_FERN_COUNT 4
static double alpha[ MAX_FERN_COUNT ] = { (double)30.0,
(double)45.0,
(double)15.0,
(double)95.0 },
beta[ MAX_FERN_COUNT ] = { (double)115.0,
(double)105.0,
(double)70.0,
(double)40.0 },
gamma[ MAX_FERN_COUNT ] = { (double)25.0,
(double)70.0,
(double)20.0,
(double)-30.0 };
double a[ 4 ],
b[ 4 ],
c[ 4 ],
d[ 4 ],
e[ 4 ],
f[ 4 ],
g[ 4 ],
h[ 4 ],
m[ 4 ],
n[ 4 ],
q[ 4 ],
r[ 4 ],
ca,
cb,
cg,
sa,
sb,
sg,
x,
y,
z,
dXScreenVGARatio,
dYScreenVGARatio,
newx,
newy,
vx,
vy;
HCURSOR hCursor;
HDC hDC;
int i,
j,
k,
index,
nClientWidth,
nClientHeight,
nXScreenSize,
nYScreenSize,
xscale,
yscale,
xoffset,
yoffset,
p[ 4 ],
px,
py;
RECT rRect;
/* constants optimized for VGA
*/
#define convert(x,y) {x = (x + 319); y = (175 - ((93*y) >> 7));}
hCursor = SetCursor( LoadCursor( NULL, IDC_WAIT ) );
a[0] = (double)0.0; a[1] = (double) 0.83; a[2] = (double) 0.22; a[3] = (double)-0.22;
b[0] = (double)0.0; b[1] = (double) 0.0; b[2] = (double)-0.023; b[3] = (double) 0.23;
c[0] = (double)0.0; c[1] = (double) 0.0; c[2] = (double) 0.0; c[3] = (double) 0.0;
d[0] = (double)0.0; d[1] = (double) 0.0; d[2] = (double) 0.24; d[3] = (double) 0.24;
e[0] = (double)0.18; e[1] = (double) 0.86; e[2] = (double) 0.22; e[3] = (double) 0.22;
f[0] = (double)0.0; f[1] = (double) 0.1; f[2] = (double) 0.0; f[3] = (double) 0.0;
g[0] = (double)0.0; g[1] = (double) 0.0; g[2] = (double) 0.0; g[3] = (double) 0.0;
h[0] = (double)0.0; h[1] = (double)-0.12; h[2] = (double) 0.0; h[3] = (double) 0.0;
m[0] = (double)0.0; m[1] = (double) 0.84; m[2] = (double) 0.32; m[3] = (double) 0.32;
n[0] = (double)0.0; n[1] = (double) 0.0; n[2] = (double) 0.0; n[3] = (double) 0.0;
q[0] = (double)0.0; q[1] = (double) 1.62; q[2] = (double) 0.82; q[3] = (double) 0.82;
r[0] = (double)0.0; r[1] = (double) 0.0; r[2] = (double) 0.0; r[3] = (double) 0.0;
p[0] = 328; p[1] = 27879 ; p[2] = 30173;
GetClientRect( hWnd, &rRect );
nClientWidth = rRect.right - rRect.left + 1;
nClientHeight = rRect.bottom - rRect.top + 1;
nXScreenSize = GetSystemMetrics( SM_CXSCREEN );
nYScreenSize = GetSystemMetrics( SM_CYSCREEN );
dXScreenVGARatio = (double)nXScreenSize / (double)640;
dYScreenVGARatio = (double)nYScreenSize / (double)480;
xscale = (int)( (double)40 * dXScreenVGARatio );
yscale = (int)( (double)50 * dYScreenVGARatio );
xoffset = (int)( (double) 60 * dXScreenVGARatio );
yoffset = (int)( (double)-180 * dYScreenVGARatio );
/* image offset for centering optimzed manually for VGA
so adjust offset constants ( 16 and 6 ) for screen size
*/
hDC = GetDC( hWnd );
SetMapMode( hDC, MM_ANISOTROPIC );
SetWindowOrg( hDC, -(int)( (double)( nXScreenSize / 16 ) *
pow( (double)dXScreenVGARatio, (double)2.0 ) ),
-(int)( (double)( nYScreenSize / 6 ) *
pow( (double)dYScreenVGARatio, (double)2.0 ) ) );
SetWindowExt( hDC, nXScreenSize, nYScreenSize );
SetViewportExt( hDC, nClientWidth, nClientHeight );
for ( index = 0; index < nFernCount && index < MAX_FERN_COUNT; index++ )
{
ca = cos( alpha[ index ] * (double)0.0174533 );
cb = cos( beta[ index ] * (double)0.0174533 );
cg = cos( gamma[ index ] * (double)0.0174533 );
sa = sin( alpha[ index ] * (double)0.0174533 );
sb = sin( beta[ index ] * (double)0.0174533 );
sg = sin( gamma[ index ] * (double)0.0174533 );
x = (double)0.0;
y = (double)0.0;
z = (double)0.0;
for ( i = 1; i <= 10000; i++ )
{
j = rand();
k = ( j < p[0] ) ? 0 : ( ( j < p[1] ) ? 1 : ( ( j < p[2] ) ? 2 : 3 ) );
newx = ( a[k] * x ) + ( b[k] * y ) + ( c[k] * z ) + n[k];
newy = ( d[k] * x ) + ( e[k] * y ) + ( f[k] * z ) + q[k];
z = g[k] * x + h[k] * y + m[k] * z + r[k];
x = newx;
y = newy;
vx = ( x * ca ) + ( y * cb ) + ( z * cg );
px = (int)( ( vx * (double)xscale ) + (double)xoffset );
vy = ( x * sa ) + ( y * sb ) + ( z * sg );
py = (int)( ( vy * (double)yscale ) + (double)yoffset );
if ( ( px >= -( nXScreenSize / 2 ) ) &&
( px < ( nXScreenSize / 2 ) ) &&
( py >= -( nYScreenSize / 2 ) ) &&
( py < ( nYScreenSize / 2 ) ) )
{
convert( px, py );
SetPixel( hDC, px, py, dwColor[ index ] );
}
}
}
ReleaseDC( hWnd, hDC );
SetCursor( hCursor );
}
BOOL NEAR PASCAL About(
HWND hWndParent )
{
BITMAP Bitmap;
char szAboutName[ MAXIMAGENAMELEN + 1 ];
HBITMAP hbmAboutImage;
int nAboutHeight,
nAboutWidth;
POINT ptAbout;
RECT rRectClient;
if ( hWndAbout )
return TRUE;
lstrcpy( szAboutName, "ABOUT" );
if ( NULL == ( hbmAboutImage = LoadBitmap( hInst, szAboutName ) ) )
{
MessageBox( hWndParent, "Could not load about image", szAppName, MB_OK );
return FALSE;
}
GetObject( hbmAboutImage, 16, (LPSTR)&Bitmap);
DeleteObject( hbmAboutImage );
nAboutWidth = Bitmap.bmWidth + 2;
nAboutHeight = Bitmap.bmHeight + 2 + GetSystemMetrics( SM_CYCAPTION );
GetClientRect( hWndParent, &rRectClient );
ptAbout.x = ( ( rRectClient.right - rRectClient.left + 1 ) / 2 ) -
( nAboutWidth / 2 );
ptAbout.y = ( ( rRectClient.bottom - rRectClient.top + 1 ) / 2 ) -
( nAboutHeight / 2 );
ptAbout.x = max( ptAbout.x, 0 );
ptAbout.y = max( ptAbout.y, 0 );
nAboutWidth = max( nAboutWidth, 0 );
nAboutHeight = max( nAboutHeight, 0 );
hWndAbout = CreateWindow( "ABOUTCLASS",
"About Fractal Fern Generator",
WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN | WS_VISIBLE,
ptAbout.x,
ptAbout.y,
nAboutWidth,
nAboutHeight,
hWndParent,
NULL,
hInst,
NULL );
if ( !hWndAbout )
{
MessageBox( hWndParent, "Could not create about window", szAppName, MB_OK );
return FALSE;
}
return TRUE;
}
long FAR PASCAL AboutWndProc(
HWND hWnd,
WORD wMessage,
WORD wParam,
LONG lParam )
{
static BOOL bOkButtonShowing = FALSE;
static char szAboutName[ MAXIMAGENAMELEN + 1 ],
szOKText[ 4 ] = "&OK";
static HWND hBtnAbout;
BITMAP Bitmap;
BOOL bShowImage;
HBITMAP hbmAboutImage,
hbmOld;
HDC hDC,
hDCMem;
PAINTSTRUCT ps;
switch ( wMessage )
{
case WM_CREATE:
lstrcpy( szAboutName, "ABOUT" );
bOkButtonShowing = FALSE;
break;
case WM_PAINT:
hDC = BeginPaint( hWnd, &ps );
if ( NULL == ( hbmAboutImage = LoadBitmap( hInst, szAboutName ) ) )
{
bShowImage = FALSE;
MessageBox( hWnd, "Could not load about image", szAppName, MB_OK );
}
else
{
bShowImage = TRUE;
hDCMem = CreateCompatibleDC( hDC );
hbmOld = SelectObject( hDCMem, hbmAboutImage );
GetObject( hbmAboutImage, 16, (LPSTR)&Bitmap);
BitBlt( hDC,
0,
0,
Bitmap.bmWidth,
Bitmap.bmHeight,
hDCMem,
0,
0,
SRCCOPY );
SelectObject( hDCMem, hbmOld );
DeleteDC( hDCMem );
DeleteObject( hbmAboutImage );
if ( !bOkButtonShowing )
{
hBtnAbout = CreateWindow( "button",
szOKText,
WS_CHILD | WS_VISIBLE,
309,
284,
100,
34,
hWnd,
IDC_ABOUTOK,
hInst,
NULL );
SetFocus( hBtnAbout );
bOkButtonShowing = TRUE;
}
else
SetFocus( hBtnAbout );
}
EndPaint( hWnd, &ps );
break;
case WM_COMMAND:
switch ( wParam )
{
case IDC_ABOUTOK:
PostMessage( hWnd, WM_SYSCOMMAND, SC_CLOSE, 0L );
break;
}
if ( hBtnAbout )
SetFocus( hBtnAbout );
break;
case WM_DESTROY:
if ( hBtnAbout )
{
DestroyWindow( hBtnAbout );
hBtnAbout = 0;
bOkButtonShowing = FALSE;
}
hWndAbout = 0;
break;
default:
return DefWindowProc( hWnd, wMessage, wParam, lParam );
}
return 0L;
}