
/*
** Example blanker module source for Melt Blanker.
**
**	(C) 1993,94 David Swsbrook,
**	All Rights Reserved.
**
*/

#include "usr:dev/source/Sprintf.c"

/*
** Firstly we must include the version strings
** and stuff.
*/
	#include	"Blanker.ver"

	extern UBYTE VersionStr[] = VERSIONSTR;
	extern UBYTE TimeStr[]    = TIMESTR;
	extern UBYTE UserStr[]    = USERSTR;
	extern UBYTE ReleseStr[]  = RELEASESTR;
	extern UBYTE CommentStr[] = COMMENTSTR;
	extern UBYTE NameStr[]    = PROGNAME_NOVER;
	extern UBYTE NameVerStr[] = PROGNAME_VER;
	extern UBYTE Name[]       = "Melt";

/*
** SWAZBLANKER INIT STRUCT
*/
	struct SBInit *SBInit;

/*
** This string allows BlankerServer to identify
** us as a blanker module. If this is not present
** then BlankerServer will not load us.
*/
extern UBYTE ID[] = "\0$BLANKER:Ver 2:";

/*
** *** LOCALE SUPPORT
**
** It is desired that your blanker supports locale. If you are using matrix.library
** then this is easily done. Using the progran "cd2c" you can create a C file which
** includes #defines for the locale ID's and an array of ID Offsets and a string base.
** Matrix.library has a function MX_GetCatalogStr() which can parse these arrays and
** return you the locale string.
*/
	#include  "MeltCat.c"

	#define LOCALE(o) MX_GetCatalogStr(SBInit->Catalog, (ULONG *) &LocArray, o)


	struct BPrefs {
		UBYTE	Pad;
	};

	struct BPrefs BPrefs;

	struct MatrixBase *MatrixBase;
	struct SwazConfigBase *SwazConfigBase;
	struct SwazBlankerBase *SwazBlankerBase;


/******************************************************************
**
**	MISC SUPPORT FUNCTIONS
**
******************************************************************/

	BOOL active;	/* Global, set by Blanker() routine */

BOOL IsActive( void )
{
	if(active) active = !(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C);
	return( active );
}

/**
*** CloneTagItemsTags()
**/
struct TagItem *CloneTagItemsTags( Tag tag1, ... )
{
	return( CloneTagItems( (struct TagItem *) &tag1 ) );
}

/**
*** LongestString()
**/
ULONG LongestString( ULONG ID, ... )
{
	ULONG *z;
	ULONG r = 0, c;

	for( z = &ID; *z; z++ )
	{	c = strlen( LOCALE( *z ) );
		if( c > r ) r = c;
	}
	return( r );
}



/******************************************************************
**
**	BLANKER
**
******************************************************************/

	struct	Screen *sc = NULL;
	struct	Window *wi = NULL;
	struct	DrawInfo *di = NULL;

void DisplayCleanUp( void )
{
	if(di) FreeScreenDrawInfo( sc, di );
	if( wi ) CloseWindow( wi ); wi = NULL;
	if( sc ) CloseScreen( sc ); sc = NULL;
}

BOOL DisplaySetUp( void )
{
	if(!(SB_CloneFrontScreenTagList( &sc, &wi, NULL )) )	return(FALSE);
	if(!(di = GetScreenDrawInfo( sc )))			return(FALSE);

	return(TRUE);
}


void CleanUp(void)
{
	DisplayCleanUp();
}

BOOL SetUp(void)
{
	if(!DisplaySetUp())	return(FALSE);
	return(TRUE);
}





#define	RPORT	wi->RPort

void	melt(int	valy)
{
	int	x, y,			/* start positions 		*/
		dx, dy,			/* offsets         		*/
		u, v;			/* size            		*/
	int	TempA[32];		/* temp buffer     		*/
	char	mask;			/* bit-plane mask for blitter	*/

	for(mask=1; mask<+(1<<(RPORT->BitMap->Depth))-1; mask*=2)
	{
	u = MX_Random(wi->Width - 3) +1;
	v = MX_Random(wi->Height - 3) +1;
	x = MX_Random(wi->Width - 2 - u);	// removed +1
	y = MX_Random(wi->Height - 3 - v); 	// removed +1
	dx = MX_Random(3) - 1;
	dy = MX_Random(3) - valy;  /* also try dy = MX_Random(3) - 1;  */

	BltBitMap(RPORT->BitMap, x, y,
		RPORT->BitMap, x+dx, y+dy,
		u, v, 0xC0,
		mask, (APTR) &TempA);
	}
}

void Blanker( void )
{
	active = TRUE;

	SetAPen(RPORT,1);
	Move(RPORT,0,0);
	Draw(RPORT,wi->Width-1,0);
	Draw(RPORT,wi->Width-1,wi->Height-1);
	Draw(RPORT,0,wi->Height-1);
	Draw(RPORT,0,0);

	if( IsActive() )
	{
	 SB_SetBlankerScreen(sc,wi);
	 SB_BlankerReady();
	 while( IsActive() )
	 {
	  melt(-1);
	  WaitTOF();
	 }
	 SB_ClrBlankerScreen(sc,wi);
	}
}


	/****************
	     Blank()
	****************/

void Blank( void )
{
	if( SetUp() )
		Blanker();
	CleanUp();
}

/******************************************************************
**
**	PREFERENCES DATA
**
******************************************************************/


	/*
	** Preferences global data.
	*/

	struct WindowHandler *PrefsWH;
	struct BlankerPrefsNode *bpn;

/******************************************************************
**
**	PREFERENCES HOOKS
**
******************************************************************/

	/*******************
	     SetToDef()
	*******************/

void __saveds SetToDef( void )
{
}

	/******************
	     DoAbout()
	******************/

void __saveds DoAbout( void )
{
	STRPTR versionptr = &VersionStr[6];
	MX_DisplayRequestWin( LOCALE(MSG_LOCALE_ABOUT), LOCALE(MSG_GAD_OK), &versionptr, PrefsWH->wh_Window);
}

	/******************
	     DoHelp()
	******************/

void __saveds DoHelp( void )
{
	SB_HelpTags( &*Name, PrefsWH->wh_Window,
		SBHELP_BlankerPrefs, bpn,
		TAG_DONE);
}


	/****************
	     DoTest()
	****************/

void __saveds DoTest( void )
{
	struct SBMessage *sbm;

	SetSignal( 0, SIGBREAKF_CTRL_C );
	if( sbm = SB_BecomeBlankerTaskTagList( NULL ) )
	{
		Blank();
		SB_BecomeBlankerTaskEnd( sbm );
	}
}

	/*******************
	     DoRawKey()
	*******************/

BOOL __saveds __asm DoRawKey( register __a0 struct WindowHandler *wh, register __a1 struct IntuiMessage *im)
{
	#define  RAWKEY_HELP 0x5F

	switch(im->Code) {
	  case RAWKEY_HELP:
		DoHelp();
		return(TRUE);
	  default:
		return(FALSE);
	}
}
	ULONG PrefsIDCMP[] = {
		RAWKEY, (ULONG) DoRawKey,
		NULL,
	};

/******************************************************************
**
**	PREFERENCES MAIN
**
******************************************************************/

void Prefs_BuildGadgets( APTR gadbase, WORD *width )
{
	#include <clib/mxg_protos.h>	/* We need these includes */

	WORD bw,bg;
	WORD lt;
	WORD s;


	APTR d = gadbase;

	bw = 2+LongestString( MSG_GAD_SAVE, MSG_GAD_USE, MSG_GAD_TEST, MSG_GAD_CANCEL, NULL );

	bg = 2;
	*width = 2+2+(bg*3)+(bw*4);
	lt = 4+LongestString( MSG_NO_CONFIG );

	s = 0;
	while( lt > *width )
	{
	  if( s ) {
	    bg++;
	    s = 1;
	  } else {
	    s = 0;
	    bw++;
	  }
	  *width = 2+2+(bg*3)+(bw*4);
	}
	bg += bw;

	if( lt < *width )
	  lt = *width;


	d = mxg_HorizLine( d, 3, -2 ); 
	d = mxg_Button( d, ID_VBUT, 2,        3, bw, MSG_GAD_SAVE,   0, 2 );
	d = mxg_Button( d, ID_VBUT, 2+(bg),   3, bw, MSG_GAD_USE,    0, 1 );
	d = mxg_Button( d, ID_BUT,  2+(bg*2), 3, bw, MSG_GAD_TEST,   0, (ULONG) DoTest );
	d = mxg_Button( d, ID_VBUT, 2+(bg*3), 3, bw, MSG_GAD_CANCEL, 0, 0 );



	d = mxg_Text( d, 0, 1, *width, MSG_NO_CONFIG, PLACETEXT_IN, NULL);
	mxg_End( d );

	/* Un-comment the following lines to get a requestor displaying the number of bytes that
	   your interface layout uses. I will improve the mxg.lib to track and allocate the
	   gadget data.... but later...

	   We add an extra 2 bytes since mxg_End() does not increment pointer!

	d = ( (ULONG) d - (ULONG) gadbase ) + 2; 
	MX_DisplayRequestWin("Bytes used for interface layout : %ld\n", 0, &d, 0 );

	*/

}











	STRPTR CFT[] = {
		NULL
	     };


void DefaultPrefs( struct BPrefs *p )
{

}

void LoadPrefs( struct BPrefs *p, STRPTR FileName )
{

	APTR cf;
	// struct SC_ConfigVar *cv;

	DefaultPrefs( p );

	if( cf = SC_ReadConfig( FileName, &*Name ) )
	{

	  SC_FreeConfig( cf );
	}
}

void SavePrefs( struct BPrefs *p, STRPTR FileName )
{
	APTR cf;
	UBYTE V[32];

	if( cf = SC_ReadConfig( FileName, &*Name ) )
	{

	  SC_WriteConfig( cf, FileName, &*Name );
	  SC_FreeConfig( cf );
	}
}

ULONG __saveds __asm PrefsCallBack( register __a0 struct Hook *Hook, register __a2 APTR Object, register __a1 ULONG *Msg )
{
	ULONG result;

	result = ~0;

	switch( *Msg ) {
	  case MXPFCB_DEFAULT:
		DefaultPrefs( &BPrefs );
		break;
	  case MXPFCB_LOAD:
		LoadPrefs( &BPrefs, Object );
		result = 0;
		break;

	  case MXPFCB_SAVE:
		SavePrefs( &BPrefs, Object );
		result = 0;
		break;
	}

	return( result );
}






/****** Prefs() *************************************************
****************************************************************/
void Prefs(void)
{
	#define GADGET_DATA_SIZE 200		/* Make sure you set this size correctly */
	struct TagItem *WHTags;		/* Window Handler Tags */
	UBYTE fontname[40];			/* Storage for the font name */
	APTR gadget_data;			/* Gadget data base and reference */
	WORD width;


	struct Hook PrefsCallBackHook;

	MX_InitHook( &PrefsCallBackHook, PrefsCallBack, 0 );
	if( bpn = SB_AddPrefsTaskTagList( &*NameStr, NULL ) )
	{
	  if( gadget_data = AllocVec( 200, 0 ) )
	  {
		Prefs_BuildGadgets( gadget_data, &width );
		SB_GetBaseVarTags(
			SBBV_FontInfo, &*fontname,
			TAG_DONE);

		WHTags = CloneTagItemsTags(
			MXWH_CloseWindow,	0,
			MXWH_ESCAddress,	-1,
			MXWH_WindowSize,	(width<<16)|4,
	                    MXWH_CatCompArray,    LocArray,               /* Locale array as created by "cd2c", see MX_GetCatalogStr() for other array types supported */
			MXWH_Catalog,	SBInit->Catalog,
			MXWH_WindowPointer,	(ULONG) &bpn->window,
			MXWH_WindowTitle,	(ULONG) &NameVerStr,
			MXWH_ScreenTitle,	(ULONG) &VersionStr[6],
			MXWH_Gadgets,	(ULONG) gadget_data,
			MXWH_WindowHandlerStore, (ULONG) &PrefsWH,
			MXWH_IDCMPFlags,	RAWKEY,
			MXWH_Events, 	(ULONG) PrefsIDCMP,
			TAG_DONE);


	    if( WHTags ) {
	      MX_NewPrefsWHTags(
	          MXPF_UseFile,         SwazBlankerBase->UseFileName,
	          MXPF_SaveFile,        SwazBlankerBase->SaveFileName,
	          MXPF_CallBack,        &PrefsCallBackHook,
	          MXPF_WHTags,          WHTags,                 /* WindowHandler tags (see MX_WindowHandler()) */
	          MXPF_Title,           NameStr,                /* Preferences name */
	          MXPF_InitialLoad,     TRUE,                   /* Load preferences file */
	          MXPF_AboutMenuHook,   DoAbout,                /* Hook function for About Menu item */
	          MXPF_HelpMenuHook,    DoHelp,                 /* Hook function for Help Menu item */
	          MXPF_Font,            fontname,               /* Name of font to use, "fontname size", eg. "topaz 8" */
	          TAG_DONE);

	      FreeTagItems( WHTags );
	    }
	    FreeVec( gadget_data );
	  }
	  SB_RemPrefsTask( bpn );
	}
}






/*
** Here is a list of the libries we wished to have available.
*/


	#include "usr:dev/source/OpenLibrary.c"

	struct LibArray LibData[] = {
		&*MxLibName,           24, (APTR) &MatrixBase,
		"swazblanker.library", 42, (APTR) &SwazBlankerBase,
		"swazconfig.library",   1, (APTR) &SwazConfigBase,
		"intuition.library",   39, (APTR) &IntuitionBase,
		"graphics.library",    39, (APTR) &GfxBase,
		"gadtools.library",    39, (APTR) &GadToolsBase,
		NULL,NULL
	};

void main (int argc, char **argv)
{
    if( OpenLibs(&*NameStr,39,&*LibData) )
    {
        if( SBInit = SB_InitTags( SBINIT_Name,&*Name, TAG_DONE ) )
        {
            switch( SBInit->Method )
            {
                case SBINIT_METHOD_BLANK:
		if( SwazBlankerBase->UseFileName ) LoadPrefs( &BPrefs, SwazBlankerBase->UseFileName );
		else LoadPrefs( &BPrefs, SwazBlankerBase->SaveFileName );
		Blank();
                    break;
                case SBINIT_METHOD_PREFS:
                    Prefs();
                    break;
                case SBINIT_METHOD_INFO:
		SB_PrintInfoTags( SBInit,
			SBINFO_Author,      ~0,	// "David Swasbrook (Swaz)",
			SBINFO_EMail,       ~0,	// "swaz@iconz.co.nz",
			SBINFO_ShortDesc,   LOCALE( MSG_DESCRIPTION_SHORT ),
			SBINFO_LongDesc,    LOCALE( MSG_DESCRIPTION_LONG ),
			SBINFO_Version,     VERSION,
			SBINFO_Revision,    REVISION,
			SBINFO_Time,        &TimeStr[6],
			SBINFO_CPULoading,  SBINFOLOAD_MEDIUM,
			TAG_DONE );
            }
            SB_FreeInit( SBInit );
        }
    }
    CloseLibs(&*LibData);
}
