|
|
// "Shuffle" module for IdleWild.
//
// Blts a pattern over the screen (to "darken" it), then
// divides the screen into blocks and shuffles them around.
//
// By Tony Krueger
#ifdef PM
#define INCL_WIN
#define INCL_GPI
#include <os2.h>
/*int _acrtused = 0;*/ #endif
#ifdef WIN
#include <windows.h>
#include <port1632.h>
#endif
#include "std.h"
#include "scrsave.h"
INT rand();
INT dxScreen, dyScreen; INT xBlock, yBlock; INT xBlockMax, yBlockMax; INT dx, dy, dir, lastOppDirection = 0; INT xBlockSize, yBlockSize;
#define ROP_PANDD (DWORD)0x00A000C9 /* dest = pattern AND dest */
#define ROP_INVPANDD (DWORD)0x000A0329 /* dest = ~pattern AND dest */
typedef WORD BMP[8]; /* Monochrome brush-sized bitmap is 8 words */
#define stdchance 2 /* One in 2 times only pick from standard bmps */
#define ibmpStdMax 5
#define ibmpMax 17
BMP rgbmp[ibmpMax] = { { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 }, /* Dither 1x1 */ { 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xCC }, /* Dither 2x1 */ { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 }, /* Horiz stripe */ { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00 }, /* Vert stripe */ { 0x88, 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44 }, /* Slash */
{ 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC }, /* Dither 2x2 */ { 0xFF, 0x0C, 0x0C, 0x0C, 0xFF, 0xC0, 0xC0, 0xC0 }, /* Brick */ { 0x38, 0x7C, 0xEE, 0xC6, 0xEE, 0x7C, 0x38, 0x00 }, /* Small Hollow Circle */ { 0x38, 0x7C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x00 }, /* Small Circle */ { 0xF8, 0xF1, 0xE3, 0xC7, 0x8F, 0x1F, 0x3E, 0x7C }, /* Thick Slash */
{ 0xF8, 0xF1, 0xE3, 0xC7, 0x8F, 0xC7, 0xE3, 0xF1 }, /* Thick ZigZag */ { 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x3F, 0x7F }, /* Tile edge */ { 0xF8, 0x74, 0x22, 0x47, 0x8F, 0x17, 0x22, 0x71 }, /* Thatch */ { 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xF0 }, /* Waffle */ { 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00 }, /* Small Solid Box */
{ 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00 }, /* Solid Diamond */ { 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0 }, /* Dither 4x1 */ };
/* Pick new direction */ /* Don't move back onto square just vacated */ /* Also don't move off screen */ VOID GetDxDy() { INT xNew, yNew, oppDir;
do { dir = WRand(4); switch(dir) { case 0: /* Left */ dx = -1; dy = 0; oppDir = 1; break; case 1: /* Right */ dx = 1; dy = 0; oppDir = 0; break; case 2: /* Up */ dx = 0; dy = 1; oppDir = 3; break; case 3: /* Down */ dx = 0; dy = -1; oppDir = 2; break; } xNew = xBlock + dx; yNew = yBlock + dy; } while (dir == lastOppDirection || xNew < 0 || xNew >= xBlockMax || yNew < 0 || yNew >= yBlockMax); lastOppDirection = oppDir; }
BOOL EXPENTRY ScrSaveProc(INT ssm, LPVOID l1, LONG_PTR l2, LONG_PTR l3) { static INT csecReblank; CHAR FAR * lpsz; CHAR FAR * lpch; switch (ssm) { default: return fFalse; case SSM_OPEN: lpsz = (PSZ) l1; lpch = "Shuffle"; while ((*lpsz++ = *lpch++) != '\0') ; lpsz = (PSZ) l2; lpch = "Divide and\nShuffle Screen\n\nby Tony Krueger"; while ((*lpsz++ = *lpch++) != '\0') ; #ifdef PM
dxScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN); dyScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN); #endif
#ifdef WIN
dxScreen = GetSystemMetrics(SM_CXSCREEN); dyScreen = GetSystemMetrics(SM_CYSCREEN); #endif
break; case SSM_BLANK: { CVS cvs; HBITMAP hbmp; HBRUSH hbr, hbrOld; HPEN hpenOld; INT x, y; ScrRestoreScreen();
cvs = (CVS) l1;
csecReblank = 60 * 20;
#ifdef DARKEN
/* Darken screen */
hbmp = NULL; hbr = NULL;
/*hbmp = +++CreateBitmap - Not Recommended(use CreateDIBitmap)+++(8, 8, 1, 1, (LPSTR) &(rgbmp[ */ hbmp = CreateBitmap(8, 8, 1, 1, (LPSTR) &(rgbmp[ WRand(stdchance) ? WRand(ibmpMax) : WRand(ibmpStdMax)])); if (hbmp == NULL) goto LFail;
hbr = CreatePatternBrush(hbmp); if (hbr == NULL) goto LFail;
hbrOld = SelectObject(cvs, hbr); PatBlt(cvs, 0, 0, dxScreen, dyScreen, WRand(2) ? ROP_PANDD : ROP_INVPANDD); SelectObject(cvs, hbrOld);
LFail: if (hbmp != NULL) DeleteObject(hbmp); if (hbr != NULL) DeleteObject(hbr); #endif
/* Select and Blacken random block */
xBlockSize = 24 + 8*WRand(10); yBlockSize = xBlockSize * GetDeviceCaps(cvs, ASPECTX) / GetDeviceCaps(cvs, ASPECTY); yBlockSize = ((yBlockSize + 4) / 8) * 8; /* Round to nearest 8 */ if (yBlockSize == 0) /* Assure a minimum */ yBlockSize = 8;
xBlockMax = dxScreen / xBlockSize; yBlockMax = dyScreen / yBlockSize; xBlock = WRand(xBlockMax); yBlock = WRand(yBlockMax);
PatBlt(cvs, xBlock * xBlockSize, yBlock * yBlockSize, xBlockSize, yBlockSize, BLACKNESS);
/* Draw Gridlines */
hpenOld = SelectObject(cvs, GetStockObject(BLACK_PEN)); for (x = 0; x < dxScreen; x += xBlockSize) { (VOID)MMoveTo(cvs, x, 0); LineTo(cvs, x, dyScreen); } for (y = 0; y < dyScreen; y += yBlockSize) { (VOID)MMoveTo(cvs, 0, y); LineTo(cvs, dxScreen, y); } SelectObject(cvs, hpenOld); } break; case SSM_SECOND: if (csecReblank-- == 0) ScrChooseRandomServer(); break; case SSM_ANIMATE: { CVS cvs; INT cd, step; INT xSrc, ySrc; INT xDest, yDest; INT xFill, yFill; INT dxFill, dyFill; static INT iSkip = 0;
if (iSkip++ == 1) { iSkip = 0; break; } cvs = (CVS) l1;
GetDxDy();
xBlock += dx; yBlock += dy;
dx *= 4; step = dx + dy; if (step < 0) step = -step;
/* Source */ xSrc = xBlock * xBlockSize; ySrc = yBlock * yBlockSize;
/* Dest */ xDest = xSrc - dx; yDest = ySrc - dy;
for (cd = 0; cd < (dx == 0 ? yBlockSize : xBlockSize); cd += step) { BitBlt(cvs, xDest, yDest, xBlockSize, yBlockSize, cvs, xSrc, ySrc, SRCCOPY);
xFill = xSrc; yFill = ySrc; dxFill = dx > 0 ? dx : -dx; dyFill = dy > 0 ? dy : -dy;
switch (dir) { case 0: /* Left */ dyFill = yBlockSize; break; case 1: /* Right */ xFill = xDest + xBlockSize; dyFill = yBlockSize; break; case 2: /* Up */ yFill = yDest + yBlockSize; dxFill = xBlockSize; break; case 3: /* Down */ dxFill = xBlockSize; break; } PatBlt(cvs, xFill, yFill, dxFill, dyFill, BLACKNESS); xSrc -= dx; ySrc -= dy; xDest -= dx; yDest -= dy; } break; } } return fTrue; }
|