home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------*\
- | Lava.c - A Lava Flow Simulator for Windows application |
- | |
- | |
- \*----------------------------------------------------------------------------*/
- /*
- (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.
- */
-
- #define PUBLIC far pascal
- #define PRIVATE near pascal
- #include <windows.h>
-
- #define WinAssert(x)
-
- #include <math.h>
-
- #include "lava.h"
-
- #define PC_NOCOLLAPSE 0x04 // non-collapsing flag
-
- #define rgbBlack RGB(0,0,0)
- #define rgbWhite RGB(255,255,255)
- //#define rgbRed RGB(255,0,0)
- //#define rgbGreen RGB(0,255,0)
- //#define rgbBlue RGB(0,0,255)
- #define rgbMenu GetSysColor(COLOR_MENU)
- #define rgbMenuText GetSysColor(COLOR_MENUTEXT)
-
- #define MAXCOLORS 256
-
- #define wDibUsage (fPalColors ? DIB_PAL_COLORS : DIB_RGB_COLORS)
-
- typedef struct CHARGE
- {
- POINT pt;
- int value;
- }CHARGE;
-
- /*----------------------------------------------------------------------------*\
- | |
- | g l o b a l v a r i a b l e s |
- | |
- \*----------------------------------------------------------------------------*/
- static char szAppName[]="LavaFlow";
-
- static HANDLE hInstApp;
- static HWND hwndApp;
-
- /*----------------------------------------------------------------------------*\
- | |
- | 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);
-
- HMENU hmenuPopup;
-
- BOOL fSetDIBits = TRUE;
- BOOL fPalColors = TRUE;
- BOOL fPalette;
- BOOL fFastCycle;
- short fSinPalette=FALSE;
- short fCrossFade=FALSE;
- short fColorCycle=TRUE;
- short fNoCollapse=FALSE;
- short paletteval[MAXCOLORS];
-
- //
- // A brush for every color in the palette, for use on non palette devices.
- //
- HBRUSH hbrPalette[MAXCOLORS];
-
- HPALETTE hpalLava;
- LOGPALETTE *pLogPal;
- int nColors = 128;
- int NumCenters = 4;
- int nBandScale = 1;
-
- short nColorPhase = 0;
- RGBQUAD rgbLava = {0,0,255};
-
- //
- // TRUE if a Lava computation is in progress
- //
- BOOL fLavaSem;
-
- //
- // if set to a non zero value will cause lava calculation to abort
- //
- BOOL fStopLava;
- #define F_LAVAOK 0
- #define F_LAVASTOP 1
- #define F_LAVADIE 2
-
- HBITMAP hbmLava;
- BITMAP bmLava;
- BYTE abScanLine[2048];
-
- BITMAPINFOHEADER *pbiLava;
-
- LONG PRIVATE AppOwnerDraw(HWND hwnd, WORD msg, WORD wParam, LONG lParam);
- LONG PRIVATE AppCommand(HWND hwnd, unsigned msg, WORD wParam, LONG lParam);
- HBITMAP CopyBitmap (HBITMAP hbm);
- HPALETTE CopyPalette(HPALETTE hpal);
- HANDLE CreateLogicalDib(HBITMAP hbm, HPALETTE hpal);
-
- extern LONG LavaFlowXY386(int nCenter, CHARGE *aptCenter, int x, int y);
- void LavaFlow(HDC hdc, int nCenter, CHARGE aptCenter[], PRECT prc);
- void CyclePalette(HDC hdc);
- void InitPalette();
- void SetPalette(PALETTEENTRY * pPal, int nPhase, RGBQUAD rgb);
-
- #define MAXI (16*1024)
-
- /*----------------------------------------------------------------------------*\
- | |
- | Random functions |
- | |
- \*----------------------------------------------------------------------------*/
-
- #define RAND(x) (rand() % (x))
-
- DWORD dwRand = 1L;
- void PASCAL srand(DWORD dwSeed)
- {
- dwRand = dwSeed;
- }
-
- WORD PASCAL rand(void)
- {
- dwRand = dwRand * 214013L + 2531011L;
- return (WORD)((dwRand >> 16) & 0xffff);
- }
-
- POINT PASCAL PtRand(int x, int y)
- {
- POINT pt;
-
- pt.x = RAND(x);
- pt.y = RAND(y);
-
- return pt;
- }
-
- VOID WinYield()
- {
- MSG msg;
-
- while(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
-
- /*----------------------------------------------------------------------------*\
- | 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;
- }
-
- VOID SetupPalette()
- {
- int i;
- WORD *pw;
- RGBQUAD *prgb;
- PALETTEENTRY *ppe;
-
- if (hpalLava)
- {
- DeleteObject(hpalLava);
- hpalLava = NULL;
- }
- //hpalLava = CreateWashPalette(rgbBlue,rgbBlack,-nColors);
- if(pLogPal == NULL)
- {
- pLogPal = (VOID *)LocalAlloc(LPTR,sizeof(LOGPALETTE) + MAXCOLORS * sizeof(PALETTEENTRY));
- }
- WinAssert(pLogPal);
-
- pLogPal->palVersion = 0x300;
- pLogPal->palNumEntries = nColors;
-
- SetPalette(pLogPal->palPalEntry,nColorPhase,rgbLava);
-
- if (!fPalette)
- {
- for(i=0,ppe=pLogPal->palPalEntry;i<nColors;i++,ppe++)
- {
- if (hbrPalette[i])
- DeleteObject(hbrPalette[i]);
-
- hbrPalette[i] = CreateSolidBrush(RGB(ppe->peRed,ppe->peGreen,ppe->peBlue));
- }
- }
-
- hpalLava = CreatePalette(pLogPal);
-
- if (pbiLava == NULL)
- {
- pbiLava = (VOID *)LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER) + MAXCOLORS * sizeof(RGBQUAD));
-
- pbiLava->biSize = sizeof(BITMAPINFOHEADER);
- pbiLava->biWidth = 0;
- pbiLava->biHeight = 0;
- pbiLava->biPlanes = 1;
- pbiLava->biBitCount = 8;
-
- pbiLava->biCompression = BI_RGB;
- pbiLava->biSizeImage = 0;
- pbiLava->biXPelsPerMeter = 0;
- pbiLava->biYPelsPerMeter = 0;
- pbiLava->biClrUsed = nColors;
- pbiLava->biClrImportant = 0;
- }
- WinAssert(pbiLava);
-
- if (fPalColors)
- {
- pw = (WORD*)((BYTE*)pbiLava+pbiLava->biSize);
- for (i=0; i<nColors; i++)
- {
- *pw++ = i;
- }
- }
- else
- {
- prgb = (RGBQUAD*)((BYTE*)pbiLava+pbiLava->biSize);
- for (i=0; i<nColors; i++)
- {
- prgb[i].rgbRed = pLogPal->palPalEntry[i].peRed;
- prgb[i].rgbGreen = pLogPal->palPalEntry[i].peGreen;
- prgb[i].rgbBlue = pLogPal->palPalEntry[i].peBlue;
- prgb[i].rgbReserved = 0;
- }
- }
- }
-
- /*----------------------------------------------------------------------------*\
- | AppExit() |
- | |
- | Description: |
- | This is called when the application is removed from memory |
- | It free all global objects and other things |
- | |
- | Returns: |
- | Exit code to be returned to KERNEL |
- | |
- \*----------------------------------------------------------------------------*/
- WORD AppExit()
- {
- int i;
-
- for (i=0; i<nColors; i++)
- {
- if (hbrPalette[i])
- DeleteObject(hbrPalette[i]);
- }
-
- if (hbmLava)
- DeleteObject(hbmLava);
-
- if (hpalLava)
- DeleteObject(hpalLava);
-
- //if (hmenuPopup)
- // DeleteMenu(hmenuPopup);
-
- return 0;
- }
-
- /*----------------------------------------------------------------------------*\
- | 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(hInst,hPrev,sw,szCmd)
- HANDLE hInst;
- HANDLE hPrev;
- WORD sw;
- LPSTR szCmd;
- {
- WNDCLASS rClass;
- int dx,dy;
- char ach[80];
- HMENU hmenu;
- HPALETTE hpal;
- HDC hdc;
-
- if (LOWORD(GetWinFlags()) & (WF_CPU086|WF_CPU186|WF_CPU286))
- {
- MessageBox(NULL,"Lava requires a 386 or better","Lava",MB_OK|MB_ICONEXCLAMATION|MB_TASKMODAL);
- return FALSE;
- }
-
- /* Save instance handle for DialogBoxs */
- hInstApp = hInst;
-
- if (!hPrev) {
- /*
- * Register a class for the main application window
- */
- rClass.hCursor = LoadCursor(NULL,IDC_ARROW);
- rClass.hIcon = LoadIcon(hInst,"AppIcon");
- rClass.lpszMenuName = NULL;
- rClass.lpszClassName = szAppName;
- rClass.hbrBackground = (HBRUSH)COLOR_WINDOW + 1;
- rClass.hInstance = hInst;
- rClass.style = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
- rClass.lpfnWndProc = AppWndProc;
- rClass.cbWndExtra = 0;
- rClass.cbClsExtra = 0;
-
- if (!RegisterClass(&rClass))
- return FALSE;
- }
-
- dx = GetSystemMetrics (SM_CXSCREEN);
- dy = GetSystemMetrics (SM_CYSCREEN);
-
- hwndApp = CreateWindow (szAppName,szAppName,
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, 0,dx/2,dy/2,
- (HWND)NULL, /* no parent */
- (HMENU)NULL, /* use class menu */
- (HANDLE)hInst, /* handle to window instance */
- (LPSTR)NULL /* no params to pass on */
- );
- WinAssert(hwndApp);
- ShowWindow (hwndApp,sw);
-
- hmenu = LoadMenu(hInst,"AppMenu");
- WinAssert(hmenu);
- hmenuPopup = GetSubMenu(hmenu, 0);
- WinAssert(hmenuPopup);
-
- CheckMenuItem(hmenuPopup,MENU_NUMCENTERS+NumCenters,MF_CHECKED);
- CheckMenuItem(hmenuPopup,MENU_NUMCOLORS+nColors,MF_CHECKED);
- CheckMenuItem(hmenuPopup,MENU_BANDSCALE+nBandScale,MF_CHECKED);
-
- InitPalette();
- SetupPalette();
-
- SetTimer(hwndApp,1,10,NULL);
-
- srand(GetCurrentTime());
-
- hdc = GetDC(NULL);
- fPalette = fSetDIBits = (GetDeviceCaps(hdc,RASTERCAPS) & RC_PALETTE);
- ReleaseDC(NULL,hdc);
-
- 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 |
- | lpszCmdLine ->null-terminated command line |
- | cmdShow specifies how the window is initially displayed |
- | |
- | Returns: |
- | The exit code as specified in the WM_QUIT message. |
- | |
- \*----------------------------------------------------------------------------*/
- int PASCAL WinMain( hInst, hPrev, fpcCmdLine, iCmdShow )
- HANDLE hInst, hPrev;
- LPSTR fpcCmdLine;
- int iCmdShow;
- {
- MSG msg;
-
- /* Call initialization procedure */
- if (!AppInit(hInst,hPrev,iCmdShow,fpcCmdLine))
- return FALSE;
-
- for (;;)
- {
- /* Polling messages from event queue */
- while (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
- {
- if (msg.message == WM_QUIT)
- goto exit;
-
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- if (fFastCycle)
- SendMessage(hwndApp,WM_TIMER,0,0L);
- else
- WaitMessage();
- }
- exit:
- return AppExit();
- }
-
- /*----------------------------------------------------------------------------*\
- | 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;
- HBITMAP hbmT;
- HDC hdcBits;
-
- if (hbmLava == NULL)
- return FALSE;
-
- if (hpalLava)
- {
- SelectPalette(hdc,hpalLava,FALSE);
- RealizePalette(hdc);
- }
-
- hdcBits = CreateCompatibleDC(hdc);
-
- GetClientRect(hwnd,&rc);
-
- hbmT = SelectObject(hdcBits,hbmLava);
- BitBlt(hdc,0,0,bmLava.bmWidth,bmLava.bmHeight,hdcBits,0,0,SRCCOPY);
- SelectObject(hdcBits,hbmT);
-
- DeleteDC(hdcBits);
- return TRUE;
- }
-
- /*----------------------------------------------------------------------------*\
- | |
- | 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;
- RECT rc;
-
- switch (msg) {
- case WM_CREATE:
- break;
-
- case WM_QUERYNEWPALETTE:
- if (hpalLava)
- {
- hdc = GetDC(hwnd);
- SelectPalette(hdc,hpalLava,FALSE);
- f = RealizePalette(hdc);
- ReleaseDC(hwnd,hdc);
- return (LONG)f;
- }
- return FALSE;
-
- case WM_PALETTECHANGED:
- if (wParam != hwnd && hpalLava)
- InvalidateRect(hwnd,NULL,TRUE);
- break;
-
- case WM_LBUTTONDOWN:
- ClientToScreen(hwnd, (LPPOINT)&lParam);
- TrackPopupMenu(hmenuPopup, 0, LOWORD(lParam)-30, HIWORD(lParam)+4, 0, hwnd, NULL);
- break;
-
- case WM_DRAWITEM:
- case WM_MEASUREITEM:
- case WM_DELETEITEM:
- return AppOwnerDraw(hwnd,msg,wParam,lParam);
-
- case WM_INITMENU:
- EnableMenuItem(wParam,MENU_GO,
- fLavaSem ? MF_GRAYED : MF_ENABLED);
- EnableMenuItem(wParam,MENU_STOP,
- !fLavaSem ? MF_GRAYED : MF_ENABLED);
- EnableMenuItem(wParam,MENU_PASTE,
- IsClipboardFormatAvailable(CF_BITMAP) ? MF_ENABLED : MF_GRAYED);
- EnableMenuItem(wParam,MENU_COPY,
- hbmLava ? MF_ENABLED : MF_GRAYED);
- EnableMenuItem(wParam,MENU_PALCOLORS,
- fSetDIBits ? MF_ENABLED : MF_GRAYED);
- CheckMenuItem(wParam,MENU_PALETTE,
- fPalette ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(wParam,MENU_SATIN,
- fSinPalette ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(wParam,MENU_CROSSFADE,
- fCrossFade ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(wParam,MENU_SETDIBITS,
- fSetDIBits ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(wParam,MENU_PALCOLORS,
- (fPalColors && fSetDIBits)? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(wParam,MENU_FASTCYCLE,
- fFastCycle ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(wParam,MENU_COLORCYCLE,
- fColorCycle ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(wParam,MENU_NOCOLLAPSE,
- fNoCollapse ? MF_CHECKED : MF_UNCHECKED);
- break;
-
- case WM_COMMAND:
- return AppCommand(hwnd,msg,wParam,lParam);
-
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
-
- case WM_CLOSE:
- //
- // if a lava calculation is under way stop it before closing
- //
- if (fLavaSem)
- {
- fStopLava = F_LAVADIE;
- return 0L;
- }
- break;
-
- case WM_TIMER:
- if (fPalette && hpalLava)
- {
- hdc = GetDC(hwnd);
-
- SelectPalette(hdc,hpalLava,FALSE);
- RealizePalette(hdc);
-
- CyclePalette(hdc);
-
- ReleaseDC(hwnd,hdc);
- }
- break;
-
- case WM_PAINT:
- BeginPaint(hwnd,&ps);
- AppPaint (hwnd,ps.hdc);
- EndPaint(hwnd,&ps);
- return 0L;
- }
- return DefWindowProc(hwnd,msg,wParam,lParam);
- }
-
-
- /*----------------------------------------------------------------------------*\
- | ErrMsg - Opens a Message box with a error message in it. The user can |
- | select the OK button to continue or the CANCEL button to kill |
- | the parent application. |
- \*----------------------------------------------------------------------------*/
- 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;
- }
-
- void PRIVATE WinSetCursor(HWND hwnd, HCURSOR hcur)
- {
- SetCursor(hcur);
- SetClassWord(hwnd,GCW_HCURSOR,(WORD)hcur);
- }
-
- LONG PRIVATE AppCommand (hwnd, msg, wParam, lParam)
- HWND hwnd;
- unsigned msg;
- WORD wParam;
- long lParam;
- {
- switch(wParam)
- {
- case MENU_COPY:
- if (!OpenClipboard(hwnd))
- break;
-
- EmptyClipboard();
-
- rgbLava.rgbRed = rgbLava.rgbGreen = rgbLava.rgbBlue = 255;
- SetPalette(pLogPal->palPalEntry,0,rgbLava);
- SetPaletteEntries(hpalLava,0,nColors,pLogPal->palPalEntry);
-
- if (hbmLava)
- SetClipboardData(CF_BITMAP,CopyBitmap(hbmLava));
-
- if (hpalLava)
- SetClipboardData(CF_PALETTE,CopyPalette(hpalLava));
-
- if (hbmLava)
- SetClipboardData(CF_DIB,CreateLogicalDib(hbmLava,hpalLava));
-
- CloseClipboard();
- break;
-
- case MENU_ABOUT:
- fDialog(ABOUTBOX,hwnd,AppAbout);
- break;
-
- case MENU_EXIT:
- PostMessage(hwnd,WM_CLOSE,0,0L);
- break;
- case MENU_SATIN:
- fSinPalette = !fSinPalette;
- InitPalette();
- SetupPalette();
- break;
- case MENU_CROSSFADE:
- fCrossFade = !fCrossFade;
- break;
- case MENU_SETDIBITS:
- fSetDIBits = !fSetDIBits;
- break;
- case MENU_COLORCYCLE:
- fColorCycle = !fColorCycle;
- break;
- case MENU_PALCOLORS:
- fPalColors = !fPalColors;
- SetupPalette();
- break;
- case MENU_FASTCYCLE:
- fFastCycle = !fFastCycle;
-
- KillTimer(hwndApp,1);
-
- if (!fFastCycle)
- SetTimer(hwndApp,1,10,NULL);
-
- break;
- case MENU_NOCOLLAPSE:
- fNoCollapse = !fNoCollapse;
- SetupPalette();
- break;
- case MENU_PALETTE:
- fPalette = !fPalette;
- SetupPalette();
- break;
- case MENU_STOP:
- if (fLavaSem)
- fStopLava = F_LAVASTOP;
- break;
- case MENU_GO:
- if (!fLavaSem)
- {
- HDC hdc;
- CHARGE apt[40];
- RECT rc;
- int i;
-
- //
- // Change the GO menu item to stop
- //
- ChangeMenu(hmenuPopup,MENU_GO,"Stop!",MENU_STOP,MF_CHANGE|MF_BYCOMMAND);
-
- WinSetCursor(hwnd,LoadCursor(NULL,IDC_WAIT));
-
- fLavaSem++;
- fStopLava = F_LAVAOK;
-
- hdc = GetDC(hwnd);
- SelectPalette(hdc,hpalLava,FALSE);
- RealizePalette(hdc);
-
- //
- // Hack, if the window is maximized generate a SCREEN size
- // bitmap
- //
- if (IsZoomed(hwnd))
- SetRect(&rc,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
- else
- GetClientRect(hwnd,&rc);
-
- //
- // Pick random charge centers and weights
- //
- for (i=0; i<NumCenters; i++)
- {
- apt[i].pt = PtRand(rc.right,rc.bottom);
- do
- apt[i].value = RAND(9)-4;
- while (apt[i].value == 0);
- }
-
- LavaFlow(hdc, NumCenters, apt, &rc);
-
- fLavaSem--;
- ReleaseDC(hwnd,hdc);
-
- WinSetCursor(hwnd,LoadCursor(NULL,IDC_ARROW));
-
- //
- // Change the STOP menu item back to go
- //
- ChangeMenu(hmenuPopup,MENU_STOP,"Go!",MENU_GO,MF_CHANGE|MF_BYCOMMAND);
-
- //
- // If the user tried to close the app while we were working
- // do it now
- //
- if (fStopLava == F_LAVADIE)
- PostMessage(hwnd,WM_CLOSE,0,0L);
- }
- break;
-
- default:
- switch (wParam & 0xFF00)
- {
- int n;
-
- case MENU_NUMCENTERS:
- n = wParam & 0xFF;
- CheckMenuItem(hmenuPopup,MENU_NUMCENTERS+NumCenters,MF_UNCHECKED);
- CheckMenuItem(hmenuPopup,MENU_NUMCENTERS+n,MF_CHECKED);
- NumCenters = n;
- break;
- case MENU_NUMCOLORS:
- n = wParam & 0xFF;
- CheckMenuItem(hmenuPopup,MENU_NUMCOLORS+nColors,MF_UNCHECKED);
- CheckMenuItem(hmenuPopup,MENU_NUMCOLORS+n,MF_CHECKED);
- nColors = n;
- SetupPalette();
- break;
- case MENU_BANDSCALE:
- n = wParam & 0xFF;
- CheckMenuItem(hmenuPopup,MENU_BANDSCALE+nBandScale,MF_UNCHECKED);
- CheckMenuItem(hmenuPopup,MENU_BANDSCALE+n,MF_CHECKED);
- nBandScale = n;
- break;
- }
- break;
- }
- return 0L;
- }
-
- LONG PRIVATE AppOwnerDraw(HWND hwnd, WORD msg, WORD wParam, LONG lParam)
- {
- #define lpMIS ((LPMEASUREITEMSTRUCT)lParam)
- #define lpDIS ((LPDRAWITEMSTRUCT)lParam)
-
- switch (msg)
- {
- case WM_MEASUREITEM:
- lpMIS->itemHeight = 10;
- lpMIS->itemWidth = 10;
- return TRUE;
-
- case WM_DRAWITEM:
- return TRUE;
-
- case WM_DELETEITEM:
- return TRUE;
- }
- return TRUE;
- }
-
- void InitPalette()
- {
- int i;
- int j;
-
- j = 0;
- for(i=0;i<nColors;i++)
- {
- if (fSinPalette)
- paletteval[i] = (int)(MAXI-sin(i*3.14/(nColors-1))*MAXI);
- else
- paletteval[i] = (int)((1-pow(2.0*i/(nColors-1)-1,2.0))*MAXI);
- }
- }
-
- /*
- * llSetPixel(hdc,x,y,n)
- *
- * Sets a pixel in a HDC, will use dither patterns if fPalette not set
- *
- */
- void llSetPixel(HDC hdc, int x, int y, int n)
- {
- HBRUSH hbrT;
-
- if (fPalette)
- {
- SetPixel(hdc,x,y,PALETTEINDEX(n));
- }
- else
- {
- hbrT = SelectObject(hdc,hbrPalette[n]);
- PatBlt(hdc,x,y,1,1,PATCOPY);
- SelectObject(hdc,hbrT);
- }
- }
-
- /*
- * LavaFlow()
- *
- * calulates the "Lava Lamp" equation for each point in the passed
- * rectangle. The Lava equation at any point is defined as the sum
- * of the distance squared from each center point
- *
- */
- void LavaFlow(HDC hdc, int nCenter, CHARGE aptCenter[], PRECT prc)
- {
- int x,y,i,a1;
- static short a = 0;
- int dx,dy;
- HDC hdcBits;
- HBITMAP hbmT;
- HPALETTE hpalT;
-
- hdcBits = CreateCompatibleDC(hdc);
-
- dx = prc->right - prc->left;
- dy = prc->bottom - prc->top;
-
- a1 = a;
-
- if (!hbmLava || bmLava.bmWidth != dx || bmLava.bmHeight != dy)
- {
- if (hbmLava)
- DeleteObject(hbmLava);
-
- hbmLava = CreateCompatibleBitmap(hdc,dx,dy);
-
- if (!hbmLava)
- return;
-
- GetObject(hbmLava,sizeof(bmLava),(LPSTR)&bmLava);
-
- pbiLava->biWidth = dx;
- pbiLava->biHeight = dy;
- pbiLava->biPlanes = 1;
- pbiLava->biBitCount = 8;
-
- pbiLava->biClrUsed = nColors;
- pbiLava->biClrImportant = 0;
-
- hbmT = SelectObject(hdcBits,hbmLava);
- PatBlt(hdcBits,0,0,dx,dy,BLACKNESS);
- SelectObject(hdcBits,hbmT);
- }
-
- for (y=prc->top; y<prc->bottom; y++)
- {
- if (fCrossFade)
- {
- hbmT = SelectObject(hdcBits,hbmLava);
- hpalT = SelectPalette(hdcBits,hpalLava,FALSE);
- RealizePalette(hdcBits);
-
- a = !a;
- for (x=prc->left+a; x<prc->right; x+=2)
- {
- i = LavaFlowXY386(nCenter,aptCenter,x,y) / nBandScale % nColors;
- llSetPixel(hdc,x,y,i);
- llSetPixel(hdcBits,x,y,i);
- }
-
- SelectObject(hdcBits,hbmT);
- SelectPalette(hdcBits,hpalT,FALSE);
- }
- else
- {
- for (x=prc->left; x<prc->right; x++)
- {
- i = LavaFlowXY386(nCenter,aptCenter,x,y) / nBandScale % nColors;
- abScanLine[x] = (BYTE)i;
- }
-
- if (fSetDIBits)
- {
- SetDIBits(hdc,hbmLava,dy-1-y,1,abScanLine,(LPBITMAPINFO)pbiLava,wDibUsage);
-
- hbmT = SelectObject(hdcBits,hbmLava);
- hpalT = SelectPalette(hdcBits,hpalLava,FALSE);
- RealizePalette(hdcBits);
-
- BitBlt(hdc,0,y,dx,1,hdcBits,0,y,SRCCOPY);
-
- SelectObject(hdcBits,hbmT);
- SelectPalette(hdcBits,hpalT,FALSE);
- }
- else
- {
- hbmT = SelectObject(hdcBits,hbmLava);
- hpalT = SelectPalette(hdcBits,hpalLava,FALSE);
- RealizePalette(hdcBits);
-
- for (x=prc->left; x<prc->right; x++)
- {
- i = abScanLine[x];
- llSetPixel(hdc,x,y,i);
- llSetPixel(hdcBits,x,y,i);
- }
-
- SelectObject(hdcBits,hbmT);
- SelectPalette(hdcBits,hpalT,FALSE);
- }
- }
-
- if (fPalette)
- CyclePalette(hdc);
-
- WinYield();
-
- //
- // See if we should abort early
- //
- if (fStopLava != F_LAVAOK)
- break;
- }
-
- a = !a1;
-
- DeleteDC(hdcBits);
- }
-
- void SetPalette(PALETTEENTRY * pPal, int nPhase, RGBQUAD rgb)
- {
- int i,n;
-
- for(i=0;i<nColors;i++)
- {
- n = paletteval[(nPhase + i) % nColors];
-
- pPal[i].peRed = (BYTE)((long)rgb.rgbRed * n / MAXI);
- pPal[i].peGreen = (BYTE)((long)rgb.rgbGreen* n / MAXI);
- pPal[i].peBlue = (BYTE)((long)rgb.rgbBlue * n / MAXI);
-
- if (fNoCollapse)
- pPal[i].peFlags = (BYTE)PC_NOCOLLAPSE;
- else
- pPal[i].peFlags = (BYTE)PC_RESERVED;
- }
- }
-
- void CyclePalette(HDC hdc)
- {
- int i;
- PALETTEENTRY peT;
-
- static short nLenColorCycle = 0;
- static RGBQUAD rgbLavaOrg;
- static short dr,dg,db;
-
- if (fColorCycle)
- {
- if (nColorPhase >= nLenColorCycle)
- {
- nLenColorCycle = (RAND(4) + 1) * nColors;
- nColorPhase = 0;
-
- rgbLavaOrg = rgbLava;
-
- dr = RAND(256) - (int)rgbLava.rgbRed;
- dg = RAND(256) - (int)rgbLava.rgbGreen;
- db = RAND(256) - (int)rgbLava.rgbBlue;
- }
-
- rgbLava.rgbRed = (int)rgbLavaOrg.rgbRed + (long)dr * nColorPhase / nLenColorCycle;
- rgbLava.rgbGreen = (int)rgbLavaOrg.rgbGreen + (long)dg * nColorPhase / nLenColorCycle;
- rgbLava.rgbBlue = (int)rgbLavaOrg.rgbBlue + (long)db * nColorPhase / nLenColorCycle;
-
- nColorPhase++;
-
- SetPalette(pLogPal->palPalEntry,nColorPhase,rgbLava);
- }
- else
- {
- peT = pLogPal->palPalEntry[0];
-
- for (i = 0; i < (pLogPal->palNumEntries - 1); i++)
- pLogPal->palPalEntry[i] = pLogPal->palPalEntry[i+1];
-
- pLogPal->palPalEntry[i] = peT;
- }
-
- if (fNoCollapse)
- {
- SetPaletteEntries(hpalLava, 0, pLogPal->palNumEntries, pLogPal->palPalEntry);
- RealizePalette(hdc);
- }
- else
- {
- AnimatePalette(hpalLava, 0, pLogPal->palNumEntries, pLogPal->palPalEntry);
- }
- }
-
- #define WIDTHBYTES(i) ((i+31)/32*4) /* ULONG aligned ! */
- #define MAKEP(sel,off) ((VOID FAR *)MAKELONG(off,sel))
-
- #define PaletteSize(lpbi) (sizeof(RGBQUAD)*DibNumColors(lpbi))
-
- WORD DibNumColors(LPBITMAPINFOHEADER lpbi)
- {
- if (lpbi->biClrUsed != 0 || lpbi->biBitCount == 24)
- return (WORD)lpbi->biClrUsed;
- else
- return 1<<lpbi->biBitCount;
- }
-
- /*
- * CreateLogicalDib
- *
- * Given a DDB and a HPALETTE create a "logical" DIB
- *
- * if the HBITMAP is NULL create a DIB from the system "stock" bitmap
- * This is used to save a logical palette to a disk file as a DIB
- *
- * if the HPALETTE is NULL use the system "stock" palette (ie the
- * system palette)
- *
- * a "logical" DIB is a DIB where the DIB color table *exactly* matches
- * the passed logical palette. There will be no system colors in the DIB
- * block, and a pixel value of <n> in the DIB will correspond to logical
- * palette index <n>.
- *
- * This is accomplished by doing a GetDIBits() with the DIB_PAL_COLORS
- * option then converting the palindexes returned in the color table
- * from palette indexes to logical RGB values. The entire passed logical
- * palette is always copied to the DIB color table.
- *
- * The DIB color table will have exactly the same number of entries as
- * the logical palette. Normaly GetDIBits() will always set biClrUsed to
- * the maximum colors supported by the device regardless of the number of
- * colors in the logical palette
- *
- * Why would you want to do this? The major reason for a "logical" DIB
- * is so when the DIB is written to a disk file then reloaded the logical
- * palette created from the DIB color table will be the same as one used
- * originaly to create the bitmap. It also will prevent GDI from doing
- * nearest color matching on PC_RESERVED palettes.
- *
- * ** What do we do if the logical palette has more than 256 entries!!!!!
- * ** GetDIBits() may return logical palette index's that are greater than
- * ** 256, we cant represent these colors in the "logical" DIB
- * **
- * ** for now hose the caller?????
- *
- */
-
- HANDLE CreateLogicalDib(HBITMAP hbm, HPALETTE hpal)
- {
- BITMAP bm;
- BITMAPINFOHEADER bi;
- LPBITMAPINFOHEADER lpDib; // pointer to DIB
- LPBITMAPINFOHEADER lpbi; // temp pointer to BITMAPINFO
- DWORD dwLen;
- DWORD dw;
- int n;
- int nColors;
- HANDLE hdib;
- HDC hdc;
- BYTE FAR * lpBits;
- WORD FAR * lpCT;
- RGBQUAD FAR * lpRgb;
- PALETTEENTRY peT;
- HPALETTE hpalT;
- WORD biBits;
-
- if (hpal == NULL)
- hpal = GetStockObject(DEFAULT_PALETTE);
-
- if (hbm == NULL)
- hbm = NULL; // ????GetStockObject(STOCK_BITMAP);
-
- GetObject(hpal,sizeof(nColors),(LPSTR)&nColors);
- GetObject(hbm,sizeof(bm),(LPSTR)&bm);
-
- biBits = nColors > 16 ? 8 : 4;
-
- if (nColors > 256) // ACK!
- ; // How do we handle this????
-
- bi.biSize = sizeof(BITMAPINFOHEADER);
- bi.biWidth = bm.bmWidth;
- bi.biHeight = bm.bmHeight;
- bi.biPlanes = 1;
- bi.biBitCount = biBits;
- bi.biCompression = BI_RGB;
- bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight;
- bi.biXPelsPerMeter = 0;
- bi.biYPelsPerMeter = 0;
- bi.biClrUsed = nColors;
- bi.biClrImportant = 0;
-
- dwLen = bi.biSize + PaletteSize(&bi) + bi.biSizeImage;
-
- hdib = GlobalAlloc(GMEM_MOVEABLE,dwLen);
-
- if (!hdib)
- return NULL;
-
- lpbi = MAKEP(GlobalAlloc(GMEM_FIXED,bi.biSize + 256 * sizeof(RGBQUAD)),0);
-
- if (!lpbi)
- {
- GlobalFree(hdib);
- return NULL;
- }
-
- hdc = GetDC(NULL);
- hpalT = SelectPalette(hdc,hpal,FALSE);
- RealizePalette(hdc); // why is this needed on a MEMORY DC? GDI bug??
-
- lpDib = (VOID FAR *)GlobalLock(hdib);
-
- *lpbi = bi;
- *lpDib = bi;
- lpCT = (WORD FAR *)((LPSTR)lpbi + (WORD)lpbi->biSize);
- lpRgb = (RGBQUAD FAR *)((LPSTR)lpDib + (WORD)lpDib->biSize);
- lpBits = (LPSTR)lpDib + (WORD)lpDib->biSize + PaletteSize(lpDib);
-
- /*
- * call GetDIBits to get the DIB bits and fill the color table with
- * logical palette index's
- */
- GetDIBits(hdc, hbm, 0, (WORD)bi.biHeight,
- lpBits,(LPBITMAPINFO)lpbi, DIB_PAL_COLORS);
-
- /*
- * Now convert the DIB bits into "real" logical palette index's
- *
- * lpCT points to the DIB color table wich is a WORD array of
- * logical palette index's
- *
- * lpBits points to the DIB bits, each DIB pixel is a index into
- * the DIB color table.
- *
- */
-
- if (biBits == 8)
- {
- for (dw = 0; dw < bi.biSizeImage; dw++, ((BYTE huge *)lpBits)++)
- *lpBits = (BYTE)lpCT[*lpBits];
- }
- else // biBits == 4
- {
- for (dw = 0; dw < bi.biSizeImage; dw++, ((BYTE huge *)lpBits)++)
- *lpBits = lpCT[*lpBits & 0x0F] | (lpCT[(*lpBits >> 4) & 0x0F] << 4);
- }
-
- /*
- * Now copy the RGBs in the logical palette to the dib color table
- */
- for (n=0; n<nColors; n++,lpRgb++)
- {
- GetPaletteEntries(hpal,n,1,&peT);
-
- lpRgb->rgbRed = peT.peRed;
- lpRgb->rgbGreen = peT.peGreen;
- lpRgb->rgbBlue = peT.peBlue;
- lpRgb->rgbReserved = (BYTE)0;
- }
-
- GlobalUnlock(hdib);
- GlobalFree(HIWORD((DWORD)lpbi));
-
- SelectPalette(hdc,hpalT,FALSE);
- ReleaseDC(NULL,hdc);
-
- return hdib;
- }
-
- /*----------------------------------------------------------------------------
- CopyBitmap (hbm) - Returns a copy of the passed bitmap
- ----------------------------------------------------------------------------*/
- HBITMAP CopyBitmap (HBITMAP hbm)
- {
- HDC hMemDCsrc;
- HDC hMemDCdst;
- HDC hdc;
- HBITMAP hNewBm;
- BITMAP bm;
-
- if (!hbm)
- return NULL;
-
- hdc = GetDC(NULL);
- hMemDCsrc = CreateCompatibleDC(hdc);
- hMemDCdst = CreateCompatibleDC(hdc);
-
- GetObject(hbm,sizeof(BITMAP),(LPSTR)&bm);
-
- hNewBm = CreateBitmap(bm.bmWidth,bm.bmHeight,bm.bmPlanes,bm.bmBitsPixel,NULL);
-
- if (hNewBm)
- {
- SelectObject (hMemDCsrc,hbm);
- SelectObject (hMemDCdst,hNewBm);
-
- BitBlt (hMemDCdst,0,0,bm.bmWidth,bm.bmHeight,hMemDCsrc,0,0,SRCCOPY);
- }
-
- ReleaseDC(NULL,hdc);
- DeleteDC(hMemDCsrc);
- DeleteDC(hMemDCdst);
- return hNewBm;
- }
-
- /*
- * CopyPalette, makes a copy of a GDI logical palette
- */
- HPALETTE CopyPalette(HPALETTE hpal)
- {
- PLOGPALETTE ppal;
- int nNumEntries;
-
- if (!hpal)
- return NULL;
-
- GetObject(hpal,sizeof(int),(LPSTR)&nNumEntries);
-
- if (nNumEntries == 0)
- return NULL;
-
- ppal = (PLOGPALETTE)LocalAlloc(LPTR,sizeof(LOGPALETTE) +
- nNumEntries * sizeof(PALETTEENTRY));
-
- if (!ppal)
- return NULL;
-
- ppal->palVersion = 0x300;
- ppal->palNumEntries = nNumEntries;
-
- GetPaletteEntries(hpal,0,nNumEntries,ppal->palPalEntry);
-
- hpal = CreatePalette(ppal);
-
- LocalFree((HANDLE)ppal);
- return hpal;
- }
-