home *** CD-ROM | disk | FTP | other *** search
- /*
- ╔════════════════════════════════════════════════════════════════════════════╗
- ║ ║
- ║ 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;
- }
-
-
-