home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
pcmagazi
/
1992
/
17
/
bugs
/
bugsbc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-24
|
19KB
|
622 lines
//========================================================================
// Bugsbc.c - A screen saver that does not need SCRNSAVE.LIB
//
// Douglas Boling
//
// Copyright (c) 1992 Doulgas Boling
//========================================================================
#include <windows.h>
//------------------------------------------------------------------------
//Includes specific to Bugs
//------------------------------------------------------------------------
#include "bugsbc.h"
#include <stdlib.h>
#include <string.h>
//------------------------------------------------------------------------
//Function prototypes used by all screen savers
//------------------------------------------------------------------------
BOOL RegisterDialogClasses (HANDLE hInst);
LONG FAR PASCAL ScreenSaverProc(HWND, WORD, WORD, LONG);
extern BOOL FAR PASCAL ScreenSaverConfigureDialog(HWND hDlg, WORD msg,
WORD wParam, LONG lParam);
LONG FAR PASCAL DefScreenSaverProc(HWND, unsigned, WORD, LONG);
//------------------------------------------------------------------------
//Function prototypes used by Bugs
//------------------------------------------------------------------------
BOOL FAR PASCAL AboutDlgProc(HWND, WORD, WORD, LONG);
void BugSmarts (HWND);
void GetProfile (void);
void SetText (HWND, int, int, char*);
int BugCmp (const BUGSTRUCT *, const BUGSTRUCT *);
//------------------------------------------------------------------------
//Global Data required for SCRNSAVE.LIB
//------------------------------------------------------------------------
HANDLE hMainInstance;
HWND hMainWindow;
//------------------------------------------------------------------------
//Global Data for Bugs
//------------------------------------------------------------------------
char szAppName[] = "Screen Saver.Bugs";
char szIniName[] = "CONTROL.INI";
BUGSTRUCT bsBugArray [MAXBUGS+1];
WORD wRNutrition = 1;
WORD wGNutrition = 1;
WORD wBNutrition = 1;
int sStartBugs = 10;
int sScoutLimit = 10;
int sBabyLevel;
int sSustenance;
int sBugLimit;
BOOL bBColorFlag;
BOOL bDColorFlag;
int sNumBugs = 1;
//========================================================================
//RegisterDialogClasses - Called by the screen saver applet during
// initialzation.
//========================================================================
BOOL RegisterDialogClasses (HANDLE hInst) {
return TRUE;
}
//------------------------------------------------------------------------
//Compare function used for sorting Bug array
//------------------------------------------------------------------------
int BugCmp (const BUGSTRUCT * Bug1, const BUGSTRUCT * Bug2) {
if (Bug1->lFood > Bug2->lFood)
return -1;
else
return 1;
}
//========================================================================
//ScreenSaverProc - The Window procedure
//========================================================================
LONG FAR PASCAL ScreenSaverProc(HWND hwnd, WORD msg, WORD wParam,
LONG lParam) {
static HWND hwndDesktop;
static int sScreenCx, sScreenCy;
static WORD wTimer = 0;
static WORD wTimer1 = 0;
HDC hdc;
int i, j;
switch(msg) {
case WM_CREATE:
hwndDesktop = GetDesktopWindow();
hdc = GetDC (hwndDesktop);
sScreenCx = GetDeviceCaps (hdc, HORZRES);
sScreenCy = GetDeviceCaps (hdc, VERTRES);
ReleaseDC (hwndDesktop, hdc);
GetProfile();
srand (LOWORD (GetCurrentTime()));
sScoutLimit = sBugLimit / 10;
if (sSustenance > 100)
sSustenance += sSustenance/100;
else
sSustenance++;
PostMessage (hwnd, WM_USER, 0, 0);
//----------------------------------------------------------
//Use timer 1 if BugSmarts routine is called from WM_TIMER
//instead of from the message loop.
//----------------------------------------------------------
//wTimer = SetTimer (hwnd, 1, 100, NULL);
//
//Timer 2 used for population ctl
//
wTimer1 = SetTimer (hwnd, 2, 15000, NULL);
break;
case WM_USER:
//
// WM_USER message used to reseed bug population
//
hdc = GetDC (hwnd);
for (i = 0; i < 6; i++)
for (j = 0; j < 6; j++)
SetPixel (hdc, i, j, 0x000000);
if (sSustenance > 100)
sSustenance -= (sSustenance/100);
else
if (sSustenance > 0) sSustenance--;
sNumBugs = 1;
//
//10 trys to find a non black pixel
//
for (i = 0; i < 10; i++) {
bsBugArray[0].PosX = (sScreenCx / 100) * (rand() % 100)+50;
bsBugArray[0].PosY = (sScreenCy / 100) * (rand() % 100)+50;
if (GetPixel (hdc, bsBugArray[0].PosX, bsBugArray[0].PosY))
break;
}
bsBugArray[0].wXVec = rand() % 3;
bsBugArray[0].wYVec = rand() % 3;
bsBugArray[0].lFood = sSustenance * 20;
bsBugArray[0].dwColor = 0x00000000;
ReleaseDC (hwnd, hdc);
break;
case WM_TIMER:
//----------------------------------------------------------
//Use two timers if BugSmarts called from timer routine
//----------------------------------------------------------
if (wParam == 1) {
BugSmarts(hwnd);
} else {
if (sNumBugs > (sBugLimit/5) * 4) {
qsort (bsBugArray, sNumBugs, sizeof(BUGSTRUCT),
(const) BugCmp);
sNumBugs -= (sNumBugs / 5);
}
}
break;
case WM_ERASEBKGND:
//
// We don't want the background erased
//
return 0;
case WM_DESTROY:
//----------------------------------------------------------
//Use timer 1 if BugSmarts routine is called from WM_TIMER
//instead of from the message loop.
//----------------------------------------------------------
if (wTimer) KillTimer(hwnd, 1);
if (wTimer1) KillTimer(hwnd, 2);
break;
}
return DefScreenSaverProc(hwnd, msg, wParam, lParam);
}
//========================================================================
//ScreenSaverConfigureDialog - Dialog procedure for configure dialog box
//========================================================================
BOOL FAR PASCAL ScreenSaverConfigureDialog(HWND hDlg, WORD msg, WORD wParam,
LONG lParam) {
int i, j;
char szTemp[10];
switch (msg) {
case WM_INITDIALOG:
GetProfile();
SetText (hDlg, IDD_REDTEXT, wRNutrition, "Red: ");
SetText (hDlg, IDD_GREENTEXT, wGNutrition, "Green: ");
SetText (hDlg, IDD_BLUETEXT, wBNutrition, "Blue: ");
SetText (hDlg, IDD_MAXBTEXT, sBugLimit, "Max Number of Bugs: ");
SetText (hDlg, IDD_BIRTHTEXT, sBabyLevel, "Reproduction Level: ");
SetText (hDlg, IDD_SUSTEXT, sSustenance, "Sustenance Level: ");
SetScrollRange (GetDlgItem (hDlg, IDD_REDLEVEL),
SB_CTL, 0, 10, FALSE);
SetScrollPos (GetDlgItem (hDlg, IDD_REDLEVEL),
SB_CTL, wRNutrition, TRUE);
SetScrollRange (GetDlgItem (hDlg, IDD_GREENLEVEL),
SB_CTL, 0, 10, FALSE);
SetScrollPos (GetDlgItem (hDlg, IDD_GREENLEVEL),
SB_CTL, wGNutrition, TRUE);
SetScrollRange (GetDlgItem (hDlg, IDD_BLUELEVEL),
SB_CTL, 0, 10, FALSE);
SetScrollPos (GetDlgItem (hDlg, IDD_BLUELEVEL),
SB_CTL, wBNutrition, TRUE);
if (sBugLimit > 100)
i = ((sBugLimit - 100) / 10) + 100;
else
i = sBugLimit;
SetScrollRange (GetDlgItem (hDlg, IDD_MAXBLEVEL),
SB_CTL, 0, (MAXBUGS-100)/10+100, FALSE);
SetScrollPos (GetDlgItem (hDlg, IDD_MAXBLEVEL),
SB_CTL, i, TRUE);
if (sBabyLevel > 100)
i = ((sBabyLevel - 100) / 10) + 100;
else
i = sBabyLevel;
SetScrollRange (GetDlgItem (hDlg, IDD_BIRTHLEVEL),
SB_CTL, 0, 500, FALSE);
SetScrollPos (GetDlgItem (hDlg, IDD_BIRTHLEVEL),
SB_CTL, i, TRUE);
if (sSustenance > 100)
i = ((sSustenance - 100) / 10) + 100;
else
i = sSustenance;
SetScrollRange (GetDlgItem (hDlg, IDD_SUSLEVEL),
SB_CTL, 0, 500, FALSE);
SetScrollPos (GetDlgItem (hDlg, IDD_SUSLEVEL),
SB_CTL, i, TRUE);
SendDlgItemMessage (hDlg, IDD_BIRTHCOLOR, BM_SETCHECK,
bBColorFlag, 0);
SendDlgItemMessage (hDlg, IDD_DEATHCOLOR, BM_SETCHECK,
bDColorFlag, 0);
return TRUE;
case WM_COMMAND:
switch (wParam) {
case IDD_BIRTHCOLOR:
if (HIWORD (lParam) == 0) {
bBColorFlag = !bBColorFlag;
SendDlgItemMessage (hDlg, IDD_BIRTHCOLOR, BM_SETCHECK,
bBColorFlag, 0);
}
break;
case IDD_DEATHCOLOR:
if (HIWORD (lParam) == 0) {
bDColorFlag = !bDColorFlag;
SendDlgItemMessage (hDlg, IDD_DEATHCOLOR, BM_SETCHECK,
bDColorFlag, 0);
}
break;
case IDD_HELP: {
FARPROC lpfnAboutDlgProc;
lpfnAboutDlgProc = MakeProcInstance (AboutDlgProc,
hMainInstance);
DialogBox (hMainInstance, "About", hDlg, lpfnAboutDlgProc);
FreeProcInstance (lpfnAboutDlgProc);
}
break;
case IDOK:
i = GetScrollPos (GetDlgItem (hDlg, IDD_REDLEVEL), SB_CTL);
itoa (i, szTemp, 10);
WritePrivateProfileString (szAppName, "Red", szTemp,
szIniName);
i = GetScrollPos (GetDlgItem (hDlg, IDD_GREENLEVEL), SB_CTL);
itoa (i, szTemp, 10);
WritePrivateProfileString (szAppName, "Green", szTemp,
szIniName);
i = GetScrollPos (GetDlgItem (hDlg, IDD_BLUELEVEL), SB_CTL);
itoa (i, szTemp, 10);
WritePrivateProfileString (szAppName, "Blue", szTemp,
szIniName);
i = GetScrollPos (GetDlgItem (hDlg, IDD_MAXBLEVEL), SB_CTL);
if (i > 100) i = 100 + ((i - 100) * 10);
itoa (i, szTemp, 10);
WritePrivateProfileString (szAppName, "MaxBugs", szTemp,
szIniName);
i = GetScrollPos (GetDlgItem (hDlg, IDD_BIRTHLEVEL), SB_CTL);
if (i > 100) i = 100 + ((i - 100) * 10);
itoa (i, szTemp, 10);
WritePrivateProfileString (szAppName, "BabyLevel", szTemp,
szIniName);
i = GetScrollPos (GetDlgItem (hDlg, IDD_SUSLEVEL), SB_CTL);
if (i > 100) i = 100 + ((i - 100) * 10);
itoa (i, szTemp, 10);
WritePrivateProfileString (szAppName, "Sustenance", szTemp,
szIniName);
i = (int) SendDlgItemMessage (hDlg, IDD_BIRTHCOLOR,
BM_GETCHECK, 0, 0);
itoa (i, szTemp, 10);
WritePrivateProfileString (szAppName, "BirthColor", szTemp,
szIniName);
i = (int) SendDlgItemMessage (hDlg, IDD_DEATHCOLOR,
BM_GETCHECK, 0, 0);
itoa (i, szTemp, 10);
WritePrivateProfileString (szAppName, "DeathColor", szTemp,
szIniName);
EndDialog (hDlg, TRUE);
return TRUE;
case IDCANCEL:
EndDialog (hDlg, FALSE);
return TRUE;
}
break;
case WM_HSCROLL:
i = GetScrollPos (HIWORD (lParam), SB_CTL); // Get Scroll bar Pos
j = GetDlgCtrlID (HIWORD (lParam)); // Get Scroll bar ID
switch (wParam) {
case SB_LINEUP:
i--;
break;
case SB_LINEDOWN:
i++;
break;
case SB_PAGEUP:
if (j == IDD_REDLEVEL ||
j == IDD_GREENLEVEL ||
j == IDD_BLUELEVEL)
i -=2;
else
i -= 10;
break;
case SB_PAGEDOWN:
if (j == IDD_REDLEVEL ||
j == IDD_GREENLEVEL ||
j == IDD_BLUELEVEL)
i += 2;
else
i += 10;
break;
case SB_THUMBTRACK:
case SB_THUMBPOSITION:
i = LOWORD (lParam);
break;
}
SetScrollPos (HIWORD (lParam), SB_CTL, i, TRUE);
switch (j) {
case IDD_REDLEVEL:
SetText (hDlg, IDD_REDTEXT, i, "Red: ");
break;
case IDD_GREENLEVEL:
SetText (hDlg, IDD_GREENTEXT, i, "Green: ");
break;
case IDD_BLUELEVEL:
SetText (hDlg, IDD_BLUETEXT, i, "Blue: ");
break;
case IDD_MAXBLEVEL:
if (i > 100) i = 100 + ((i - 100) * 10);
SetText (hDlg, IDD_MAXBTEXT, i, "Max Number of Bugs: ");
break;
case IDD_SUSLEVEL:
if (i > 100) i = 100 + ((i - 100) * 10);
SetText (hDlg, IDD_SUSTEXT, i, "Sustenance Level: ");
break;
case IDD_BIRTHLEVEL:
if (i > 100) i = 100 + ((i - 100) * 10);
SetText (hDlg, IDD_BIRTHTEXT, i, "Reproduction Level: ");
break;
}
break;
}
return FALSE;
}
//========================================================================
//About Dlg Proc - Processes messages for the About box.
//========================================================================
BOOL FAR PASCAL AboutDlgProc(HWND hDlg, WORD msg, WORD wParam, LONG lParam) {
switch (msg) {
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch (wParam) {
case IDOK:
case IDCANCEL:
EndDialog (hDlg, TRUE);
return TRUE;
}
break;
}
return FALSE;
}
//------------------------------------------------------------------------
//Process dead bugs using C code.
//------------------------------------------------------------------------
void DeadBugs (HDC hdc, int sNumBugs, int sDeadBugs, BUGSTRUCT *bsBugArray) {
BUGSTRUCT * bspCurrBug;
BUGSTRUCT * bspNextBug;
int i, j;
if (sDeadBugs) {
i = 0;
j = 1;
while (i < sNumBugs && j < sNumBugs) {
bspCurrBug = &bsBugArray[i];
bspNextBug = &bsBugArray[j];
if (bspCurrBug->lFood <= 0) {
if (bDColorFlag)
SetPixel (hdc, bspCurrBug->PosX, bspCurrBug->PosY, 0x000040);
bspCurrBug->PosX = bspNextBug->PosX;
bspCurrBug->PosY = bspNextBug->PosY;
bspCurrBug->wXVec = bspNextBug->wXVec;
bspCurrBug->wYVec = bspNextBug->wYVec;
bspCurrBug->lFood = bspNextBug->lFood;
bspCurrBug->dwColor = bspNextBug->dwColor;
j++;
} else {
i++;
if (i <= j) j = i + 1;
}
}
}
}
//-----------------------------------------------------------------------
//BugSmarts - Routine that computes the next move for each of the bugs
//-----------------------------------------------------------------------
void BugSmarts (HWND hwnd) {
HDC hdc;
int i, sNewBugs, sDeadBugs, sRandom;
DWORD dwOldPel;
long lPelFood;
BUGSTRUCT * bspCurrBug;
BUGSTRUCT * bspNextBug;
hdc = GetDC (hwnd);
sNewBugs = 0;
sDeadBugs = 0;
for (i = 0; i < sNumBugs; i++) {
bspCurrBug = &bsBugArray[i];
sRandom = rand();
//
//Compute next move
//
if (i < sScoutLimit) {
bspCurrBug->PosX += bspCurrBug->wXVec + (sRandom % 3) - 2;
bspCurrBug->PosY += bspCurrBug->wYVec + ((sRandom >> 2) % 3) - 2;
} else {
bspCurrBug->PosX += (sRandom % 3) - 1;
bspCurrBug->PosY += ((sRandom >> 2) % 3) - 1;
}
//
//Get pixel
//
dwOldPel = GetPixel (hdc, bspCurrBug->PosX, bspCurrBug->PosY);
//
//Determine the nutritional value of Pel by its color
//
if (dwOldPel == -1) {
bspCurrBug->lFood = 0;
} else {
lPelFood = (BYTE)dwOldPel * wRNutrition +
((WORD)dwOldPel >> 8) * wGNutrition +
(dwOldPel >> 16) * wBNutrition;
bspCurrBug->lFood += lPelFood;
bspCurrBug->lFood -= sSustenance;
}
//
//Check for dead bugs
//
if (bspCurrBug->lFood <= 0)
sDeadBugs++;
else {
//
//If not getting enough food, try a new direction
//
if (lPelFood <= sSustenance) {
bspCurrBug->wXVec = (sRandom >> 4) % 3;
bspCurrBug->wYVec = (sRandom >> 6) % 3;
}
if (dwOldPel != 0)
SetPixel (hdc, bspCurrBug->PosX, bspCurrBug->PosY,
bspCurrBug->dwColor);
}
//
//See if bug can reproduce
//
if (sNumBugs + sNewBugs < sBugLimit)
if (bspCurrBug->lFood > sBabyLevel) {
bspNextBug = &bsBugArray[sNumBugs + sNewBugs];
bspNextBug->wXVec = (sRandom % 3) - 1;
bspNextBug->wYVec = ((sRandom >> 2) % 3) - 1;
bspNextBug->PosX = bspCurrBug->PosX +
bspCurrBug->wXVec +
bspNextBug->wXVec;
bspNextBug->PosY = bspCurrBug->PosY +
bspCurrBug->wYVec +
bspNextBug->wYVec;
bspNextBug->lFood = sSustenance * 2;
bspNextBug->dwColor = 0x000000;
if (bBColorFlag)
SetPixel (hdc, bspCurrBug->PosX, bspCurrBug->PosY, 0x008000);
bspCurrBug->lFood -= sBabyLevel/2;
sNewBugs++;
}
}
sNumBugs += sNewBugs;
//
//If any dead bugs, compress data in array
//
DeadBugs (hdc, sNumBugs, sDeadBugs, bsBugArray);
if (sDeadBugs) {
sNumBugs -= sDeadBugs;
}
if (sNumBugs >= sBugLimit) {
SetPixel (hdc, 0, 0, 0x0000ff);
SetPixel (hdc, 0, 1, 0x0000ff);
SetPixel (hdc, 1, 0, 0x0000ff);
SetPixel (hdc, 1, 1, 0x0000ff);
} else {
SetPixel (hdc, 0, 0, 0x00ff00);
SetPixel (hdc, 0, 1, 0x00ff00);
SetPixel (hdc, 1, 0, 0x00ff00);
SetPixel (hdc, 1, 1, 0x00ff00);
}
ReleaseDC (hwnd, hdc);
if (sNumBugs == 0)
PostMessage (hwnd, WM_USER, 0, 0);
return;
}
//------------------------------------------------------------------------
//Get Profile - Reads the profile info from CONTROL.INI.
//------------------------------------------------------------------------
void GetProfile (void) {
wRNutrition = GetPrivateProfileInt (szAppName, "Red", 1,
szIniName);
wGNutrition = GetPrivateProfileInt (szAppName, "Green", 1,
szIniName);
wBNutrition = GetPrivateProfileInt (szAppName, "Blue", 1,
szIniName);
sBugLimit = GetPrivateProfileInt (szAppName, "MaxBugs", 512,
szIniName);
sSustenance = GetPrivateProfileInt (szAppName, "Sustenance", 512,
szIniName);
sBabyLevel = GetPrivateProfileInt (szAppName, "BabyLevel", 128,
szIniName);
bBColorFlag = GetPrivateProfileInt (szAppName, "BirthColor", TRUE,
szIniName);
bDColorFlag = GetPrivateProfileInt (szAppName, "DeathColor", TRUE,
szIniName);
return;
}
//------------------------------------------------------------------------
//Set Text - Sets the text for a dialog box control
//------------------------------------------------------------------------
void SetText (HWND hwnd, int sCtlID, int sVal, char* szText) {
char szTemp[80], szTemp1[10];
strcpy (szTemp, szText);
itoa (sVal, szTemp1, 10);
strcat (szTemp, szTemp1);
SetDlgItemText (hwnd, sCtlID, szTemp);
return;
}