293 lines
6.3 KiB
C
293 lines
6.3 KiB
C
// "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;
|
|
}
|