/*  ECSTool.c
 *  (C) Copyright 1991 by O. Bausch
 *  All Rights Reserved.
 *
 *
 *  Release Notes:
 *  - Creation          : Feb 16, 1991
 *  - Last Modification : Jul 09, 1991
 *
 *  Version Notes:
 *  - 0.00 - Feb 16, 1991
 *
 *  Change History:
 *  - Feb 16, 1991 (/ob):
 *     - File creation
 *
 *  Bugs and Limitations: (see TBC)
 *  - none.
 *
 ************************************************************************
 *  Compile options with LatticeC v5.10: lc -Lmn -O -cfist -v ECSTool.c
*************************************************************************/
/* Include Files
 */
#include <env.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <keycodes.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <hardware/custom.h>
#include <graphics/gfxbase.h>
#include <graphics/display.h>
#include <graphics/monitor.h>
#include <devices/inputevent.h>
#include <intuition/intuitionbase.h>

#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/exec.h>
int CXBRK(void) { return(0); }		 /* Disable Lattice CTRL/C handling */

/************************************************************************/
/* Local Constants
 */
#define WindowWidth 				362
#define WindowHeight				105
#define DefaultYOffset			  0
#define DefaultXOffset			  0
#define DefaultNrOfPlanes		  2
#define DefaultPALScanLines	STANDARD_PAL_ROWS		/* 312 */
#define DefaultNTSCScanLines	STANDARD_NTSC_ROWS	/* 262 */

/************************************************************************/
/* Useful abbreviations
 */
#define FAScreen				(IntuitionBase->FirstScreen)
#define UseableScanLines	(ScanLines - 22 - (YOffset > -24 ? (YOffset + 23) : -(YOffset + 23)))
#define Displayed				(UseableScanLines * (IsTrue(InterLace) ? 2 : 1))
#define LastHeighSet			(FAScreen->Height)

/************************************************************************/
/* Global Structures
 */
struct IntuitionBase			*IntuitionBase	= NULL;
struct GfxBase					*GfxBase			= NULL;
extern struct ExecBase		*SysBase;
extern struct Custom			far custom;

/************************************************************************/
/* Local Structures
 */
static struct Preferences	*Prefs			= NULL;
static struct Window			*window			= NULL;
static struct Window			*Hwindow			= NULL;
static struct IntuiText		IText;

typedef struct {
	Word LeftEdge;
	Word TopEdge;
	char *Text;
	Word InfoStart;
} TextDef;

typedef enum { CustomSet = 1<<0, PrefsSet = 1<<1 } SetType;

/************************************************************************/
/* Text Attribute Structure
 */
static struct TextAttr MyFont = {
	"topaz.font",
	TOPAZ_EIGHTY,
	FS_NORMAL,
	FPF_ROMFONT
};

/************************************************************************/
/* NewWindow Structure
 */
static struct NewWindow NewWindow = {
	0,											/* LeftEdge		*/
	0,											/* TopEdge		*/
	WindowWidth,							/* Width			*/
	WindowHeight,							/* Height		*/
	-1,										/* DetailPen	*/
	-1,										/* BlockPen		*/
	CLOSEWINDOW | RAWKEY | NEWPREFS,	/* IDCMP			*/
	WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | ACTIVATE | SMART_REFRESH | RMBTRAP,
	NULL,										/* Pointer to first gadget	*/
	NULL,										/* No checkmark.				*/
	"ECSAgnusTool v1.35g -- NTSC",	/* Window title.				*/
	NULL,										/* Attach a screen later. 	*/
	NULL,										/* No bitmap.					*/
	0,											/* Minimum width.				*/
	0,											/* Minimum height.			*/
	0xFFFF,									/* Maximum width.				*/
	0xFFFF,									/* Maximum height.			*/
	WBENCHSCREEN							/* The Wb Screen				*/
};

/************************************************************************/
/* Local Variables
 */
static Boolean		keep 				= True;
static Boolean		WonnaWindow 	= True;
static Boolean 	HWindowIsOpen	= False;
static Boolean		InterLace		= False;
static Boolean		ECSAgnus			= False;
static Boolean		PALMode			= False;
static SignedByte XOffset;
static SignedByte YOffset;
static Word			ScanLines;
static char 		Buffer[9];
static double		RefreshRate;
static TextDef		InfoText[] = {
	{ 10, 40, "Planes:", 93},
	{ 10, 50, "XOffset:", 93},
	{ 10, 60, "YOffset:", 93},
	{ 10, 70, "LastSet:", 93},
	{ 10, 80, "MaxHeigth:", 93},
	{ 10, 90, "ScanLines:", 93},
	{200, 80, "FreeCHIP:", 298},
	{200, 90, "Frequency:", 282},
	{334, 80, "KB", 0},
	{334, 90, "Hz", 0},
	{ 40, 20, "(c)Copyright 1991 by Oliver Bausch", 0},
	{148, 54, "No ECS_AGNUS installed !!", 0}
};
static char			HelpText[][] = {
	{"'R' Reset values         "},
	{"'S' Set new WBHeight"},
	{"'T' Toggle InterLaceMode"},
	{"'+' Add another BitPlane"},
	{"'-' Subtract one BitPlane"}
};

/************************************************************************/
/* Function Prototypes
 */
static ErrType FAinit(void);
static ErrType FAendwork(void);
static void		ErrorMessages(ErrType);
static void		ScanKeys(struct IntuiMessage	*);
static void		WindowInfo(void);
static void		SetNewRefresh(SetType);
static void		ResetValues(void);
static Boolean	SetNewHeight(struct Screen *, Word);
static Boolean	SetNrOfPlanes(struct Screen *, Word);
static void 	ToggleLace(struct Screen *);
static void 	EditWindows(struct Screen *, Word);
static void 	SorryUser(void);
static void		HelpUser(void);

void main(int, char **);

/************************************************************************/
/* Function implementation
 */
static ErrType FAinit(void)
{
	Byte i;

	if((GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",33)) == NULL){
		return(ErrLibrary);
	}		
	if((IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",33)) == NULL){
		return(ErrLibrary);
	}		
	if((Prefs = (struct Preferences *)AllocMem(sizeof(struct Preferences), MEMF_PUBLIC)) == NULL){
		return(ErrMemory);
	}
	GetPrefs(Prefs, sizeof(struct Preferences));
	YOffset		= Prefs->ViewYOffset;
	XOffset		= Prefs->ViewXOffset;
	ScanLines	= GfxBase->MaxDisplayRow;

	if(FAScreen->ViewPort.Modes & INTERLACE){
		InterLace = True;
	}
	if(custom.vposr & (1 << 0x0d)){
		ECSAgnus = True;
	}
	if(GfxBase->DisplayFlags & PAL){
		PALMode = True;
		strcpy(&NewWindow.Title[23], "PAL\0");
	}
	if(IsTrue(WonnaWindow)){
		if((window=(struct Window *)OpenWindow(&NewWindow)) == NULL){
			return(ErrWindow);
		}
		IText.FrontPen		= 0x01;
		IText.BackPen		= 0x00;
		IText.DrawMode		= JAM1;
		IText.ITextFont	= &MyFont;
		IText.NextText		= NULL;
		for (i=0;i < (IsTrue(ECSAgnus) ? 11 : 12);i++){
			IText.LeftEdge		= InfoText[i].LeftEdge;
			IText.TopEdge		= InfoText[i].TopEdge;
			IText.IText			= InfoText[i].Text;
			PrintIText(window->RPort, &IText, 0x00, 0x00);
		}
		if(IsFalse(ECSAgnus)) SorryUser();
	}
	SetNewRefresh(PrefsSet | CustomSet);

	return(ErrOK);
}

/*----------------------------------------------------------------------*/
static ErrType FAendwork(void)
{
	if(IsTrue(HWindowIsOpen)){
		Hwindow->UserPort = NULL;
		CloseWindow(Hwindow);
	}
	if(window != NULL){
		CloseWindow(window);
	}
	RethinkDisplay(); RemakeDisplay();

	if(Prefs != NULL){
		FreeMem(Prefs, sizeof(struct Preferences));
	}
	if(GfxBase != NULL){
		CloseLibrary((struct Library *)GfxBase);
	}
	if(IntuitionBase != NULL){
		CloseLibrary((struct Library *)IntuitionBase);
	}
	return(ErrOK);
}

/*----------------------------------------------------------------------*/
static Boolean SetNrOfPlanes(struct Screen *ScreenTT, Word NewNrOfPlanes)
{
	Word ScreenTTWidth, ScreenTTHeight, ActNrOfPlanes, planes;

	ActNrOfPlanes	= ScreenTT->BitMap.Depth;
	ScreenTTWidth	= ScreenTT->Width;
	ScreenTTHeight	= ScreenTT->Height;

	if((NewNrOfPlanes == ActNrOfPlanes) || (NewNrOfPlanes < 1) || (NewNrOfPlanes > 8)){
		return(True);
	}
	if(NewNrOfPlanes > ActNrOfPlanes){
		for(planes=ActNrOfPlanes;planes<NewNrOfPlanes;planes++){
			if((ScreenTT->BitMap.Planes[planes] = 
			AllocMem(RASSIZE(ScreenTTWidth, ScreenTTHeight), MEMF_CHIP|MEMF_CLEAR)) == NULL){
				for(planes=ActNrOfPlanes;planes<NewNrOfPlanes;planes++){
					if(ScreenTT->BitMap.Planes[planes] != NULL){ 
						FreeMem(ScreenTT->BitMap.Planes[planes], RASSIZE(ScreenTTWidth, ScreenTTHeight));
					} 
				}
				return(False);
			} 
		}
	}
	Forbid();
	Disable();
	ScreenTT->BitMap.Depth		= NewNrOfPlanes;
	ScreenTT->RastPort.BitMap	= &ScreenTT->BitMap;

	if(NewNrOfPlanes < ActNrOfPlanes){
		for(planes=NewNrOfPlanes;planes<ActNrOfPlanes;planes++){
			FreeMem(ScreenTT->BitMap.Planes[planes], RASSIZE(ScreenTTWidth, ScreenTTHeight));
		}
	}
/* TBC
	Prefs->wb_Depth = FAScreen->BitMap.Depth;
	SetPrefs(Prefs, sizeof(struct Preferences), True);
 */

	Enable();
	Permit();
	RethinkDisplay(); RemakeDisplay();

	return(True);
}

/*----------------------------------------------------------------------*/
static Boolean SetNewHeight(struct Screen *ScreenTT, Word ScreenTTHeight)
{
	struct BitMap 	*NBitMap;
	Word				ScreenTTWidth, NrOfPlanes, planes;

	EditWindows(ScreenTT, ScreenTTHeight);
	NrOfPlanes		= ScreenTT->BitMap.Depth;
	ScreenTTWidth	= ScreenTT->Width;

	if((NBitMap = (struct BitMap *)AllocMem(sizeof(struct BitMap), MEMF_PUBLIC|MEMF_CLEAR)) == NULL){
		return(False);
	}
	InitBitMap(NBitMap, NrOfPlanes, ScreenTTWidth, ScreenTTHeight);
	for(planes=0;planes<NrOfPlanes;planes++){
		if((NBitMap->Planes[planes] = AllocMem(RASSIZE(ScreenTTWidth, ScreenTTHeight), MEMF_CHIP|MEMF_CLEAR)) == NULL){
			for(planes=0;planes<NrOfPlanes;planes++){
				if(NBitMap->Planes[planes] != NULL){ 
					FreeMem(NBitMap->Planes[planes], RASSIZE(ScreenTTWidth, ScreenTTHeight));
				} 
			}
			FreeMem(NBitMap, sizeof(struct BitMap));
			return(False);
		} 
	}
	Forbid();
	Disable();

	for(planes=0;planes<NrOfPlanes;planes++){
		CopyMem(ScreenTT->BitMap.Planes[planes], NBitMap->Planes[planes], RASSIZE(ScreenTTWidth, min(ScreenTTHeight, ScreenTT->Height)));
		FreeMem(ScreenTT->BitMap.Planes[planes], ScreenTT->BitMap.BytesPerRow * ScreenTT->BitMap.Rows);
	}
	CopyMem(NBitMap, &ScreenTT->BitMap, sizeof(struct BitMap));
 	ScreenTT->Height				= ScreenTTHeight;
	ScreenTT->RastPort.BitMap	= &ScreenTT->BitMap;
	FreeMem(NBitMap, sizeof(struct BitMap));

	IntuitionBase->Flags 		&= ~0x10000;

/* TBC
	Prefs->wb_Height				= FAScreen->Height;
	Prefs->wb_Width				= FAScreen->Width;
	SetPrefs(Prefs, sizeof(struct Preferences), True);
 */

	Enable();
	Permit();

	if(Displayed < 512){
		if(IsTrue(PALMode)){
			GfxBase->DisplayFlags &= ~PAL;
			GfxBase->DisplayFlags |= NTSC;
			PALMode = False;
			if(IsTrue(WonnaWindow)){
				strcpy(&NewWindow.Title[23], "NTSC");
				SetWindowTitles(window, NewWindow.Title, (char *)-1l);
			}
		}
	}else{
		if(IsFalse(PALMode)){
			GfxBase->DisplayFlags &= ~NTSC;
			GfxBase->DisplayFlags |= PAL;
			PALMode = True;
			if(IsTrue(WonnaWindow)){
				strcpy(&NewWindow.Title[23], "PAL\0");
				SetWindowTitles(window, NewWindow.Title, (char *)-1l);
			}
		}
	}
	return(True);
}

/*----------------------------------------------------------------------*/
static void ToggleLace(struct Screen *ScreenTT)
{
	if(ScreenTT->ViewPort.Modes & LACE){
		if(IsTrue(SetNewHeight(ScreenTT, ScreenTT->Height >> 1))){
			ScreenTT->ViewPort.Modes  &= ~LACE;
			InterLace						= False;
		}
	}else{
		if(IsTrue(SetNewHeight(ScreenTT, ScreenTT->Height << 1))){
			ScreenTT->ViewPort.Modes  |= LACE;
			InterLace						= True;
		}
	}
}

/*----------------------------------------------------------------------*/
static void EditWindows(struct Screen *ScreenTT, Word NewHeight)
{
	struct Window *ActWindow;

	ActWindow = ScreenTT->FirstWindow;
	while(ActWindow != NULL){
		if((ActWindow->TopEdge+ActWindow->Height) > NewHeight){
			MoveWindow(ActWindow, 0, -(ActWindow->TopEdge));
			RethinkDisplay();
			if(ActWindow->Height > NewHeight){
				SizeWindow(ActWindow, 0, NewHeight-(ActWindow->Height));
				RethinkDisplay();
			}
		}
		RefreshWindowFrame(ActWindow);
		ActWindow = ActWindow->NextWindow;
	}
	RemakeDisplay();
}

/*----------------------------------------------------------------------*/
static void ScanKeys(struct IntuiMessage	*KeyMessage)
{
#define NO_IEQUALIFIERS		0x00
#define MY_IEQUALIFIERS		(IEQUALIFIER_CONTROL|IEQUALIFIER_LALT)

	SetType	SetSelect;
	Byte 		key  = KeyMessage->Code;		/* if you use Word instead of Byte */
	Byte 		qual = KeyMessage->Qualifier;	/* it won't work. nobody knows why */

	switch(key){
	case CURSORUP:
		switch(qual){
		case MY_IEQUALIFIERS:
			YOffset--;
			SetSelect = PrefsSet;
			break;
		case NO_IEQUALIFIERS:
			if(IsTrue(ECSAgnus)){
				ScanLines++;
				SetSelect = CustomSet;
			}
			break;		
		}
		break;
	case CURSORDOWN:
		switch(qual){
		case MY_IEQUALIFIERS:
			YOffset++;
			SetSelect = PrefsSet;
			break;
		case NO_IEQUALIFIERS:
			if(IsTrue(ECSAgnus)){
				ScanLines--;
				SetSelect = CustomSet;
			}
			break;		
		}
		break;
	case CURSORRIGHT:
		switch(qual){
		case MY_IEQUALIFIERS:
			XOffset++;
			SetSelect = PrefsSet;
			break;
		}
		break;
	case CURSORLEFT:
		switch(qual){
		case MY_IEQUALIFIERS:
			XOffset--;
			SetSelect = PrefsSet;
			break;
		}
		break;
	case 0x5e:	/* NumPad 	+ */
	case 0x1b:	/* KeyBoard + */
		SetNrOfPlanes(FAScreen, FAScreen->BitMap.Depth+1);
		break;
	case 0x4a:	/* NumPad 	- */
	case 0x3a:	/* KeyBoard - */
		SetNrOfPlanes(FAScreen, FAScreen->BitMap.Depth-1);
		break;
	case KEYCODE_R:
		ResetValues();
		SetSelect = CustomSet | PrefsSet;
		break;
	case KEYCODE_S:
		SetNewHeight(FAScreen, Displayed);
		RethinkDisplay(); RemakeDisplay();
		break;
	case KEYCODE_T:
		ToggleLace(FAScreen);
		RethinkDisplay(); RemakeDisplay();
		break;
	case KEYCODE_ENTER:
		keep = False;
		break;
	case KEYCODE_HELP:
		HelpUser();
	default:
		return;
	}
	SetNewRefresh(SetSelect);
}

/*----------------------------------------------------------------------*/
static void SorryUser(void)
{
	struct IntuiText BText, GText;
		
	BText.FrontPen		= 0x00;
	BText.DrawMode		= JAM1;
	BText.ITextFont	= &MyFont;
	BText.NextText		= NULL;
	BText.LeftEdge		= 10;
	BText.TopEdge		= 10;
	BText.IText			= InfoText[11].Text;

	GText.FrontPen		= 0x02;
	GText.DrawMode		= JAM1;
	GText.ITextFont	= &MyFont;
	GText.NextText		= NULL;
	GText.LeftEdge		= 6;
	GText.TopEdge		= 3;
	GText.IText			= "Go On !";

	AutoRequest(window, &BText, &GText, &GText, GADGETUP|VANILLAKEY, GADGETUP, (29*8)+10, 60);
}

/*----------------------------------------------------------------------*/
static void HelpUser(void)
{
	Byte i;

	if(IsFalse(HWindowIsOpen)){
		NewWindow.LeftEdge 	= window->LeftEdge +123;
		NewWindow.TopEdge 	= window->TopEdge  + 36;
		NewWindow.Width	 	= 230;
		NewWindow.Height	 	=  63;
		NewWindow.Title		= "ECSTool HelpWindow";
		NewWindow.IDCMPFlags	= NULL;
		NewWindow.Flags		= WINDOWDRAG | SMART_REFRESH | RMBTRAP;
		if((Hwindow=(struct Window *)OpenWindow(&NewWindow)) == NULL){
			return;
		}
		HWindowIsOpen	 		= True;
		Hwindow->UserPort 	= window->UserPort;
		ModifyIDCMP(Hwindow, RAWKEY);

		IText.LeftEdge			= 10;
		IText.TopEdge			= 13;
		IText.FrontPen			= 0x01;
		IText.BackPen			= 0x00;
		IText.DrawMode			= JAM1;
		IText.ITextFont		= &MyFont;
		IText.NextText			= NULL;
		for (i=0;i<5;i++){
			IText.IText			= HelpText[i];
			PrintIText(Hwindow->RPort, &IText, 0x00, 0x00);
			IText.TopEdge	  += 9;
		}
	}else{
		if(Hwindow != NULL){
			Hwindow->UserPort = NULL;
			CloseWindow(Hwindow);
		}
		HWindowIsOpen = False;
	}
}

/*----------------------------------------------------------------------*/
static void ResetValues(void)
{
	if(IsTrue(PALMode)){
		ScanLines = DefaultPALScanLines;
	}else{
		ScanLines = DefaultNTSCScanLines;
	}
	XOffset = DefaultXOffset;
	YOffset = DefaultYOffset;

	SetNrOfPlanes(FAScreen, DefaultNrOfPlanes);
}

/*----------------------------------------------------------------------*/
static void WindowInfo(void)
{
	Byte i;

	if(IsTrue(WonnaWindow)){
		IText.FrontPen		= 0x03;
		IText.BackPen		= 0x00;
		IText.DrawMode		= JAM2;
		IText.ITextFont	= &MyFont;
		IText.IText			= Buffer;
		IText.NextText		= NULL;
		for(i=0;i<8;i++){
			switch(i){
			case 0:
				sprintf(Buffer, "%#3d", FAScreen->BitMap.Depth);
				break;
			case 1:
				sprintf(Buffer, "%#3d", XOffset);
				break;
			case 2:
				sprintf(Buffer, "%#3d", YOffset);
				break;
			case 3:
				sprintf(Buffer, "%#3d", LastHeighSet);
				break;
			case 4:
				sprintf(Buffer, "%#3d", Displayed);
				break;
			case 5:
				sprintf(Buffer, "%#3d", ScanLines);
				break;
			case 6:
				sprintf(Buffer, "%#4d", (AvailMem(MEMF_CHIP) / 1024));
				break;
			case 7:
				sprintf(Buffer,"%#6.2f", RefreshRate);
				break;
			}
			IText.TopEdge	= InfoText[i].TopEdge;
			IText.LeftEdge	= InfoText[i].InfoStart;
			PrintIText(window->RPort, &IText, 0x00, 0x00);
		}
	}
}

/*----------------------------------------------------------------------*/
static void SetNewRefresh(SetType SetSel)
{
	if(SetSel & CustomSet){
		IntuitionBase->Flags 	  &= ~0x10000;
		GfxBase->MaxDisplayRow		= ScanLines;
		GfxBase->NormalDisplayRows	= UseableScanLines;			/* wb height */
		if(IsTrue(ECSAgnus)){
			custom.beamcon0			= VARBEAM | LOLDIS;
			custom.htotal				= STANDARD_COLORCLOCKS;		/* 226 */
			custom.vtotal 				= ScanLines;
		}	
		RefreshRate = ((DOUBLE)15625 / (DOUBLE)ScanLines);
		SysBase->VBlankFrequency	= (Word)RefreshRate;
	}
	if(SetSel & PrefsSet){
		Prefs->ViewYOffset 			= YOffset;
		Prefs->ViewXOffset 			= XOffset;
		SetPrefs(Prefs, sizeof(struct Preferences), True);
	}
	WindowInfo();
}

/*----------------------------------------------------------------------*/
static void ErrorMessages(ErrType error)
{
	printf("\n%s\n\n", NewWindow.Title);
	printf(" Sorry. I'm unable to ");
	switch(error){
	case ErrLibrary:
		printf("open a vital library.\n");
		break;
	case ErrMemory:
		printf("allocate a few bytes of memory.\n");
		break;
	case ErrWindow:
		printf("open a window. Use me with CommandLine options.\n");
		printf(" For more Information use option <Help>.\n");
		break;
	default:
		printf("continue. A suspicious error occured.\n");
		break;
	}
	printf("\n");
}

/*----------------------------------------------------------------------*/
void main(int argc, char *argv[])
{
	struct IntuiMessage	*msg;
	Byte						i;
	int						dummy;
	ErrType					Ferr;

	if(argc > 1){
		strcpy(&NewWindow.Title[19], "\0");
		WonnaWindow = False;
		keep			= False;
	}
	if((Ferr = FAinit()) != ErrOK){
		ErrorMessages(Ferr);
		FAendwork();
		exit(1);
	}
	for(i=1;i<argc;i++){
		stcd_i(&argv[i][1], &dummy);
		switch(argv[i][0]){
		case 'l':
		case 'L':
			if(IsTrue(ECSAgnus)){
				if(dummy != NULL){
					ScanLines = dummy;
				}
			}
			break;
		case 'p':
		case 'P':
			if((dummy>0) && (dummy<8)){
				SetNrOfPlanes(FAScreen, (Word)dummy);
			}
			break;
		case 'r':
		case 'R':
			ResetValues();
			break;
		case 's':
		case 'S':
			SetNewHeight(FAScreen, Displayed);
			RethinkDisplay(); RemakeDisplay();
			break;
		case 't':
		case 'T':
			ToggleLace(FAScreen);
			RethinkDisplay(); RemakeDisplay();
			break;
		case 'x':
		case 'X':
			XOffset = dummy;
			break;
		case 'y':
		case 'Y':
			YOffset = dummy;
			break;
		default:
			printf("\n%s\n\n", NewWindow.Title);
			printf(" To change one of the two offsets and/or the number of ScanLines\n");
			printf(" Just use <%s Xddd Yddd Lddd S>.\n", argv[0]);
			printf(" For example, you want to set the XOffset to -15, the YOffset to -23 and\n");
			printf(" the LastScanLine to 278 just enter:\n\n");
			printf(" <%s X-15 Y-23 L278 S>   -- That's it !\n\n", argv[0]);
			printf("\nThe %s CommandLine options:\n\n", NewWindow.Title);
			printf(" <%s Xddd> set ScreenXOffset.\n", argv[0]);
			printf(" <%s Yddd> set ScreenYOffset.\n", argv[0]);
			printf(" <%s Lddd> set LastScanLine.\n", argv[0]);
			printf(" <%s Pd>   set NrOfColorPlanes.\n", argv[0]);
			printf(" <%s R>    reset values to defaults.\n", argv[0]);
			printf(" <%s T>    toggle ScreenMode between InterLace and NonInterLace.\n", argv[0]);
			printf(" <%s S>    set new WorkBenchHeight depending on LastScanLine.\n", argv[0]);
			
			printf(" <%s ?>    show actual values like this:\n\n", argv[0]);
		case '?':
			printf("\nYour actual values:\n\n");
			printf(" %s    %#3d\n", InfoText[0].Text, FAScreen->BitMap.Depth);
			printf(" %s   %#3d\n", InfoText[1].Text, XOffset);
			printf(" %s   %#3d\n", InfoText[2].Text, YOffset);
			printf(" %s   %#3d lines.\n", InfoText[3].Text, LastHeighSet);
			printf(" %s %#3d lines.\n", InfoText[4].Text, Displayed);
			printf(" %s %#3d therefore resulting", InfoText[5].Text, ScanLines);
			printf(" %s %#6.2f %s.\n",InfoText[7].Text, RefreshRate, InfoText[9].Text);
			printf("\n%s --> %s\n\n", NewWindow.Title, InfoText[10].Text);
			break;
		}
		SetNewRefresh(PrefsSet | CustomSet);
	}
	while(keep){
		WaitPort(window->UserPort);
		while(msg=(struct IntuiMessage *)GetMsg(window->UserPort)){
			switch(msg->Class){
			case CLOSEWINDOW:
				keep=FALSE;
				break;
			case RAWKEY:
				ScanKeys(msg);
				break;
			case NEWPREFS:
				GetPrefs(Prefs, sizeof(struct Preferences));
				YOffset = Prefs->ViewYOffset;
				XOffset = Prefs->ViewXOffset;
				WindowInfo();
				break;
			}
			ReplyMsg((struct Message *)msg);
		}
	}
	FAendwork();
}
