home *** CD-ROM | disk | FTP | other *** search
- #include <afxwin.h>
- #include <math.h>
- #include "main.h"
- /*
- This is a screen saver which uses colormap animation, a simple technique
- to achieve seemingly complicated motion. The entire source of this
- program is provided for your convenience. If you find it useful, I'll
- appreciate if you'll send me $10. Send the check to:
-
- CMAP registration
- c/o: Sin-Yaw Wang
- 5878 W. Walbrook Dr.
- San Jose, CA 95129
-
- You can also contact me at sinyaw@netcom.com.
-
- */
-
- /////////////////////////////////////////////////////////////////////////////
-
- // theApp:
- // Just creating this application object runs the whole application.
- //
- CTheApp theApp;
-
- /////////////////////////////////////////////////////////////////////////////
-
- // CMainWindow constructor:
- // Create the window with the appropriate style, size, menu, etc.
- //
- CMainWindow::CMainWindow():
- timerid(7), // randomly chosen id for timer
- speed(15), // how fast the animation is
- cmap(NULL), entry(0), animate(0), cmap_size(0),
- PI(acos(0)*2.0), INIT_PHASE(0)
- {
- // create a rect which covers the whole screen
- CRect rect(0, 0,
- GetSystemMetrics(SM_CXSCREEN),
- GetSystemMetrics(SM_CYSCREEN));
- Create( NULL, NULL, WS_POPUP | WS_VISIBLE, rect);
- }
-
- CMainWindow::~CMainWindow()
- {
- delete cmap;
- delete animate;
- delete (char *)entry;
- KillTimer(timerid);
- }
-
- BOOL CMainWindow::OnEraseBkgnd(CDC *dc)
- {
- CRect rect;
- GetClientRect(&rect);
- CBrush br;
- int i = 0;
-
- // paint 256 rects with decreasing sizes with different colors
- int dec = -1 * rect.Height() / 256;
- CPalette *oldPal = dc->SelectPalette(cmap, FALSE);
- dc->RealizePalette();
- while (rect.Height() > 4) {
- br.CreateSolidBrush(PALETTEINDEX(i++));
- dc->FillRect(&rect, &br);
- br.DeleteObject();
- rect.InflateRect(dec, dec);
- i %= 256;
- }
- dc->SelectPalette(oldPal, FALSE);
- return TRUE;
- }
-
- int CMainWindow::OnCreate(LPCREATESTRUCT lpCreate)
- {
- CWindowDC dc(this);
- cmap_size = dc.GetDeviceCaps(SIZEPALETTE);
- cmap = new CPalette;
- void *data = new char[sizeof(LOGPALETTE) +
- cmap_size * sizeof(PALETTEENTRY)];
- LOGPALETTE *entry = (LOGPALETTE *) data;
- animate = new PALETTEENTRY[cmap_size];
- ASSERT(cmap != NULL && data != NULL && animate != NULL);
-
- // smooth the color with cosine value with different phase angle
- // this part is magic, you can experiment for different effects
-
- int r = 0, g = 0, b = 0;
- double ang = 4.0 * PI / (double) cmap_size;
- double rphase = INIT_PHASE;
- double gphase = rphase + PI / 2.0;
- double bphase = gphase + PI / 2.0;
- entry->palVersion = 0x300;
- entry->palNumEntries = cmap_size;
- for (int i = 0; i < cmap_size; i++) {
- entry->palPalEntry[i].peRed = LOBYTE(127 + (int) (cos(rphase) * 127.0));
- entry->palPalEntry[i].peGreen = LOBYTE(127 + (int) (cos(gphase) * 127.0));
- entry->palPalEntry[i].peBlue = LOBYTE(127 + (int) (cos(bphase) * 127.0));
- entry->palPalEntry[i].peFlags = PC_RESERVED;
- rphase += ang;
- gphase += ang;
- bphase += ang;
- }
-
- // duplicate the colomap to seed the animation
- for (i = 0; i < cmap_size; i++) {
- animate[i].peRed = entry->palPalEntry[i].peRed;
- animate[i].peGreen = entry->palPalEntry[i].peGreen;
- animate[i].peBlue = entry->palPalEntry[i].peBlue;
- animate[i].peFlags = PC_RESERVED;
- }
-
- VERIFY(cmap->CreatePalette(entry));
- VERIFY(SetTimer(timerid, speed, NULL));
- return CWnd::OnCreate(lpCreate);
- }
-
- void CMainWindow::OnTimer(UINT)
- {
- // synthesize the next animation colormap and install it
- PALETTEENTRY tmp;
- int i = 0;
- int last = cmap_size - 1;
- tmp.peRed = animate[0].peRed;
- tmp.peGreen = animate[0].peGreen;
- tmp.peBlue = animate[0].peBlue;
- for (i = 0; i < last; i++) {
- animate[i].peRed = animate[i+1].peRed;
- animate[i].peGreen = animate[i+1].peGreen;
- animate[i].peBlue = animate[i+1].peBlue;
- animate[i].peFlags = PC_RESERVED;
- }
- animate[i].peRed = tmp.peRed;
- animate[i].peGreen = tmp.peGreen;
- animate[i].peBlue = tmp.peBlue;
- animate[i].peFlags = PC_RESERVED;
- CWindowDC dc(this);
- CPalette *oldPal = dc.SelectPalette(cmap, FALSE);
- dc.RealizePalette();
- cmap->AnimatePalette(0, cmap_size, animate);
- dc.SelectPalette(oldPal, FALSE);
- }
-
-
- BEGIN_MESSAGE_MAP( CMainWindow, CScreenSaverWindow )
- ON_WM_CREATE()
- ON_WM_ERASEBKGND()
- ON_WM_TIMER()
- END_MESSAGE_MAP()
-
- BOOL CTheApp::InitInstance()
- {
- if (m_hPrevInstance)
- return FALSE;
-
- if (*m_lpCmdLine && *m_lpCmdLine == '-' || *m_lpCmdLine =='/') {
- m_lpCmdLine++;
- if (*m_lpCmdLine == 'c' || *m_lpCmdLine == 'C')
- return FALSE;
- }
-
- m_pMainWnd = new CMainWindow();
- m_pMainWnd->ShowWindow( m_nCmdShow );
- m_pMainWnd->UpdateWindow();
-
- return TRUE;
- }
-
-