home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d5xx
/
d535
/
fracblank.lha
/
FracBlank
/
FracBlank.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-26
|
26KB
|
1,298 lines
/* $Revision Header * Header built automatically - do not edit! *************
*
* (C) Copyright 1990 by Olaf Barthel & MXM
*
* Name .....: FracBlank.c
* Created ..: Friday 18-Jun-91 15:28
* Revision .: 3
*
* Date Author Comment
* ========= ======== ====================
* 29-Jun-91 Olsen Added VBlank interrupt server.
* 21-Jun-91 Olsen Optimizations, cleanups.
* 18-Jun-91 Olsen Created this file!
*
* $Revision Header ********************************************************/
/* Include the specific math pragmas/header files here (is there
* any way to figure this out by taking a look at predefined
* compiler symbols?).
*/
#ifdef MATH_FFP
#include <clib/mathtrans_protos.h>
#include <proto/mathtrans.h>
#include <mffp.h>
#else
#include <m68881.h>
#endif /* MATH_FFP */
#include <math.h>
/* sin -45° = cos -45° (saves precious calculation time). */
#define deg45 -0.707106781
/* Hotkey IDs. */
enum { POP_WINDOW,BLANK_SCREEN };
/* Gadget IDs. */
enum { GAD_SCREENTIMEOUT,GAD_PATTERNCHANGE,GAD_HOTKEY,
GAD_BLANKSCREEN,GAD_HIDE,GAD_QUIT };
/* Dimensions of the control panel. */
#define WIDTH 308
#define HEIGHT 87
/* Sprite blanker interface data. */
struct BlankerInfo
{
struct Task *RingBack;
BYTE Signal;
BYTE Enabled;
};
/* Program revision tag. */
STATIC const UBYTE * const VersTag = "\0$VER: FracBlank 1.4 (23.7.91)";
/* Shared library identifiers. */
extern struct ExecBase *SysBase;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *CxBase,
*IconBase,
*GadToolsBase;
/* Blanker data. */
struct Task *BlankTask;
struct Screen *BlankScreen;
/* Commodities interface data. */
struct MsgPort *CxPort;
CxObj *Broker;
/* Gfx and gadtools data. */
struct Screen *DefaultScreen;
APTR VisualInfo;
struct TextFont *Topaz;
struct Gadget *GadgetList;
struct Gadget *GadgetArray[6];
struct Window *Window;
/* Rainbow colour table. */
UWORD Table[75];
/* Key sequence buffers. */
UBYTE HotkeyBuffer[256],BlankScreenBuffer[256];
/* Screen and pattern change timeout. */
ULONG ScreenCount = 0,PatternCount = 0,ScreenTimeout,PatternTimeout;
/* The default font to be used by the control panel. */
struct TextAttr DefaultFont =
{
(UBYTE *)"topaz.font",
8,
FS_NORMAL,
FPF_ROMFONT
};
/* A new broker definition, Commodities needs this. */
struct NewBroker NewBroker =
{
NB_VERSION,
"FracBlanker",
"Fractal Blanker v1.3",
"Screen Blanker",
NBU_NOTIFY | NBU_UNIQUE,
0,0,NULL,0
};
/* Function prototypes. */
extern VOID __asm Plot(register __a0 PLANEPTR Plane,register __d0 UWORD x,register __d1 UWORD y,register __d2 UWORD Modulo,register __d3 UWORD MaxX,register __d4 UWORD MaxY);
LONG __saveds ShowTime(struct Gadget *SomeGadget,WORD Level);
struct Gadget * CreateAllGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge);
VOID ShutdownWindow(VOID);
BYTE SetupWindow(VOID);
LONG __saveds __asm SpriteBlanker(register __a1 struct BlankerInfo *BlankerInfo);
VOID SpriteSwitch(BYTE Enabled);
VOID __saveds BlankerAction(CxMsg *CxMessage,CxObj *CxObject);
VOID ShutdownCx(VOID);
BYTE SetupCx(UBYTE **ToolTypes);
VOID HandleCxMsg(CxMsg *Message);
ULONG Random(ULONG MaxValue);
VOID __saveds Blanker(VOID);
VOID CloseAll(LONG ReturnCode);
VOID OpenAll(int argc,char **argv);
VOID __stdargs main(int argc,char **argv);
/* ShowTime(struct Gadget *SomeGadget,WORD Level):
*
* Gadtools support routine, displays the timeouts.
*/
LONG __saveds
ShowTime(struct Gadget *SomeGadget,WORD Level)
{
STATIC UBYTE Buffer[30];
if(Level)
SPrintf(Buffer,"%2ld.%02ld",Level / 60,Level % 60);
else
SPrintf(Buffer,"-Off-");
return((LONG)Buffer);
}
/* CreateAllGadgets():
*
* Gadtools support routine, creates all the gadgets
* required by the control panel.
*/
struct Gadget *
CreateAllGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge)
{
struct Gadget *Gadget;
struct NewGadget NewGadget;
UWORD Counter = 0;
if(Gadget = CreateContext(GadgetList))
{
NewGadget . ng_Width = 104;
NewGadget . ng_Height = 12;
NewGadget . ng_GadgetText = "_Screen Timeout ";
NewGadget . ng_TextAttr = &DefaultFont;
NewGadget . ng_VisualInfo = VisualInfo;
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_Flags = 0;
NewGadget . ng_LeftEdge = (strlen(NewGadget . ng_GadgetText) + 2 - 1) * 8 + 2;
NewGadget . ng_TopEdge = 1 + TopEdge;
GadgetArray[Counter++] = Gadget = CreateGadget(SLIDER_KIND,Gadget,&NewGadget,
GT_Underscore, '_',
GTSL_Min, 0,
GTSL_Max, 30 * 60,
GTSL_Level, ScreenTimeout,
GTSL_DispFunc, ShowTime,
GTSL_LevelFormat, "%s",
GTSL_MaxLevelLen, 5,
TAG_DONE);
NewGadget . ng_GadgetText = "_Pattern Change ";
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_TopEdge = Gadget -> TopEdge + Gadget -> Height + 3;
GadgetArray[Counter++] = Gadget = CreateGadget(SLIDER_KIND,Gadget,&NewGadget,
GT_Underscore, '_',
GTSL_Min, 0,
GTSL_Max, 30 * 60,
GTSL_Level, PatternTimeout,
GTSL_DispFunc, ShowTime,
GTSL_LevelFormat, "%s",
GTSL_MaxLevelLen, 5,
TAG_DONE);
NewGadget . ng_GadgetText = "Hot _Key";
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_Height = 14;
NewGadget . ng_TopEdge = Gadget -> TopEdge + Gadget -> Height + 3;
GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
GT_Underscore, '_',
GTST_MaxChars, 256,
GTST_String, HotkeyBuffer,
TAG_DONE);
NewGadget . ng_GadgetText = "_Blank Screen";
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_Height = 14;
NewGadget . ng_TopEdge = Gadget -> TopEdge + Gadget -> Height + 4;
GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
GT_Underscore, '_',
GTST_MaxChars, 256,
GTST_String, BlankScreenBuffer,
TAG_DONE);
NewGadget . ng_GadgetText = "_Hide";
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_Flags = 0;
NewGadget . ng_LeftEdge = 10;
NewGadget . ng_TopEdge = HEIGHT - 3 - NewGadget . ng_Height;
GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
GT_Underscore, '_',
TAG_DONE);
NewGadget . ng_GadgetText = "_Quit";
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_LeftEdge = WIDTH - 10 - NewGadget . ng_Width;
GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
GT_Underscore, '_',
TAG_DONE);
}
return(Gadget);
}
/* ShutdownWindow():
*
* Closes the control panel.
*/
VOID
ShutdownWindow()
{
if(Window)
{
CloseWindow(Window);
Window = NULL;
}
if(GadgetList)
{
FreeGadgets(GadgetList);
GadgetList = NULL;
}
if(VisualInfo)
{
FreeVisualInfo(VisualInfo);
VisualInfo = NULL;
}
if(DefaultScreen)
{
UnlockPubScreen(NULL,DefaultScreen);
DefaultScreen = NULL;
}
if(Topaz)
{
CloseFont(Topaz);
Topaz = NULL;
}
}
/* SetupWindow():
*
* Creates the control panel and disables the screen
* blanker.
*/
BYTE
SetupWindow()
{
if(BlankTask)
{
RemTask(BlankTask);
BlankTask = NULL;
}
if(BlankScreen)
{
ScreenToBack(BlankScreen);
CloseScreen(BlankScreen);
BlankScreen = NULL;
SpriteSwitch(TRUE);
}
if(Window)
return(TRUE);
if(Topaz = (struct TextFont *)OpenFont(&DefaultFont))
{
if(DefaultScreen = (struct Screen *)LockPubScreen(NULL))
{
if(VisualInfo = GetVisualInfo(DefaultScreen,TAG_DONE))
{
if(CreateAllGadgets(&GadgetArray[0],&GadgetList,VisualInfo,DefaultScreen -> WBorTop + DefaultScreen -> Font -> ta_YSize + 1))
{
if(Window = OpenWindowTags(NULL,
WA_Width, WIDTH,
WA_Height, HEIGHT + DefaultScreen -> Font -> ta_YSize - 8,
WA_Activate, TRUE,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_RMBTrap, TRUE,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | SLIDERIDCMP | BUTTONIDCMP,
WA_Title, "Fractal Blanker v1.3",
TAG_DONE))
{
SetFont(Window -> RPort,Topaz);
AddGList(Window,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
RefreshGList(GadgetList,Window,NULL,(UWORD)-1);
GT_RefreshWindow(Window,NULL);
return(TRUE);
}
}
}
}
}
ShutdownWindow();
return(FALSE);
}
/* SpriteBlanker():
*
* VBlank interrupt server, turns on/off all sprite channels
* at the top of the frame.
*/
LONG __saveds __asm
SpriteBlanker(register __a1 struct BlankerInfo *BlankerInfo)
{
/* Are we still to run this piece of code? */
if(BlankerInfo -> RingBack)
{
/* Enabled/disable the sprites. */
if(BlankerInfo -> Enabled)
ON_SPRITE
else
{
UWORD i;
OFF_SPRITE
for(i = 0 ; i < 8 ; i++)
{
custom . spr[i] . dataa = 0;
custom . spr[i] . datab = 0;
}
}
/* Signal father task to remove the server. */
Signal(BlankerInfo -> RingBack,1 << BlankerInfo -> Signal);
/* Sprites are to be turned on only once. */
if(BlankerInfo -> Enabled)
BlankerInfo -> RingBack = NULL;
}
return(0);
}
/* SpriteSwitch(BYTE Enabled):
*
* Enable/disable sprite DMA by enabling a VBlank
* interrupt server.
*/
VOID
SpriteSwitch(BYTE Enabled)
{
struct BlankerInfo __aligned BlankerInfo;
struct Interrupt __aligned BlankInterrupt;
/* Fill in the standard data. */
BlankerInfo . RingBack = SysBase -> ThisTask;
BlankerInfo . Signal = AllocSignal(-1);
BlankerInfo . Enabled = Enabled;
/* Did we get the a signal? */
if(BlankerInfo . Signal != -1)
{
/* Enable the interrupt server. */
BlankInterrupt . is_Node . ln_Name = "FracBlank.interrupt";
BlankInterrupt . is_Node . ln_Type = NT_INTERRUPT;
BlankInterrupt . is_Node . ln_Pri = 0;
BlankInterrupt . is_Code = (APTR)SpriteBlanker;
BlankInterrupt . is_Data = (APTR)&BlankerInfo;
WaitTOF();
WaitTOF();
AddIntServer(INTB_VERTB,&BlankInterrupt);
/* Wait for ringback signal. */
Wait(1 << BlankerInfo . Signal);
if(!Enabled)
{
/* Wait for another signal to make sure the
* sprites are really off.
*/
Wait(1 << BlankerInfo . Signal);
}
/* Remove the server. */
RemIntServer(INTB_VERTB,&BlankInterrupt);
/* Free the signal. */
FreeSignal(BlankerInfo . Signal);
}
}
/* BlankerAction(CxMsg *CxMessage,CxObj *CxObject):
*
* Commodities support routine, handles the Commodities
* custom actions (in this case: filter the InputEvents
* coming in and enable/disable the screen blanker).
*/
VOID __saveds
BlankerAction(CxMsg *CxMessage,CxObj *CxObject)
{
STATIC BYTE Count = 1;
struct InputEvent *Event = (struct InputEvent *)CxMsgData(CxMessage);
/* Push the blanker screen to the front if necessary. */
if(BlankScreen)
{
if(BlankScreen -> TopEdge)
MoveScreen(BlankScreen,0,-BlankScreen -> TopEdge);
if(IntuitionBase -> FirstScreen != BlankScreen)
{
ScreenToFront(BlankScreen);
SpriteSwitch(FALSE);
}
}
/* This looks like a timer event. */
if(Event -> ie_Class == IECLASS_TIMER && !Window)
{
/* Screen blanker still inactive? */
if(!BlankTask)
{
/* Is there a timeout to take care of? */
if(ScreenTimeout)
{
/* Are we ready to create the
* screenblanker?
*/
if(ScreenCount++ >= ScreenTimeout * 10)
{
if(BlankTask = (struct Task *)CreateTask("FracBlank.task",-20,Blanker,4000))
PatternCount = 0;
}
}
}
else
{
/* Every 5/60 second we signal the blanker
* task to rotate the palette.
*/
if(Count++ == 2)
{
Signal(BlankTask,SIGBREAKF_CTRL_E);
Count = 0;
}
/* Is it time to change the pattern? */
if(PatternTimeout)
{
if(PatternCount++ >= PatternTimeout * 10)
{
Signal(BlankTask,SIGBREAKF_CTRL_D);
PatternCount = 0;
}
}
}
}
else
{
/* The following line determines whether
* the blanker is to be removed or to
* be left running.
*/
if((Event -> ie_Class == IECLASS_RAWKEY && !(Event -> ie_Code & IECODE_UP_PREFIX)) || Event -> ie_Class == IECLASS_RAWMOUSE)
{
/* Remove the blanker task. */
if(BlankTask)
{
RemTask(BlankTask);
BlankTask = NULL;
}
/* Close the blanker screen. */
if(BlankScreen)
{
ScreenToBack(BlankScreen);
SpriteSwitch(TRUE);
CloseScreen(BlankScreen);
BlankScreen = NULL;
}
}
ScreenCount = 0;
}
}
/* ShutdownCx():
*
* Close the Commodities interface.
*/
VOID
ShutdownCx()
{
if(CxPort)
{
struct Message *Message;
/* Remove the broker. */
if(Broker)
DeleteCxObjAll(Broker);
/* Remove the MsgPort from the public list. */
RemPort(CxPort);
/* Remove all pending messages. */
while(Message = GetMsg(CxPort))
ReplyMsg(Message);
/* Delete the MsgPort. */
DeleteMsgPort(CxPort);
CxPort = NULL;
Broker = NULL;
}
}
/* SetupCx(UBYTE **ToolTypes):
*
* Set up the Commodities interface.
*/
BYTE
SetupCx(UBYTE **ToolTypes)
{
/* Cancel any previously made assignments. */
ShutdownCx();
/* Create a reply port. */
if(CxPort = CreateMsgPort())
{
/* Fill in a unique name. */
CxPort -> mp_Node . ln_Name = NewBroker . nb_Name;
/* Add the reply port to the public list. */
AddPort(CxPort);
/* Set the Commodity priority if possible. */
if(ToolTypes)
{
NewBroker . nb_Pri = ArgInt(ToolTypes,"CX_PRIORITY",0);
NewBroker . nb_Port = CxPort;
}
/* This Commodity features a control panel. */
NewBroker . nb_Flags |= COF_SHOW_HIDE;
/* Create the broker. */
if(Broker = CxBroker(&NewBroker,NULL))
{
CxObj *ObjectList;
UBYTE *String;
/* Set the Commodity popup hotkey if possible. */
if(ToolTypes)
{
String = ArgString(ToolTypes,"CX_POPKEY","shift f1");
strcpy(HotkeyBuffer,String);
}
/* Link the hotkey. */
AttachCxObj(Broker,HotKey(HotkeyBuffer,CxPort,POP_WINDOW));
/* Determine the screen blanker hotkey. */
if(ToolTypes)
{
String = ArgString(ToolTypes,"BLANKSCREEN","shift f2");
strcpy(BlankScreenBuffer,String);
}
/* Link another hotkey. */
AttachCxObj(Broker,HotKey(BlankScreenBuffer,CxPort,BLANK_SCREEN));
/* Adjust the screen timeout if possible. */
if(ToolTypes)
ScreenTimeout = ArgInt(ToolTypes,"SCREENTIMEOUT",60);
/* Adjust the pattern change timeout if possible. */
if(ToolTypes)
PatternTimeout = ArgInt(ToolTypes,"PATTERNTIMEOUT",60);
/* Install the plain InputEvent handler. */
ObjectList = CxCustom(BlankerAction,NULL);
/* Any accumulated errors? */
if(!CxObjError(ObjectList))
{
/* Add the custom object. */
AttachCxObj(Broker,ObjectList);
/* Any errors? */
if(!CxObjError(Broker))
{
/* Activate the broker. */
ActivateCxObj(Broker,TRUE);
return(TRUE);
}
}
}
}
ShutdownCx();
return(FALSE);
}
/* HandleCxMsg(CxMsg *Message):
*
* Handle incoming Commodities messages.
*/
VOID
HandleCxMsg(CxMsg *Message)
{
ULONG MessageType = CxMsgID(Message),MessageID = CxMsgType(Message);
ReplyMsg((struct Message *)Message);
/* Take a look at the message type. */
switch(MessageID)
{
/* It's a hotkey. */
case CXM_IEVENT: switch(MessageType)
{
/* Create the control panel. */
case POP_WINDOW: SetupWindow();
break;
/* Blank the screen. */
case BLANK_SCREEN: if(!BlankTask)
{
/* Blanker task isn't running yet,
* so let's create it.
*/
if(BlankTask = (struct Task *)CreateTask("FracBlank.task",-20,Blanker,4000))
PatternCount = 0;
}
else
{
/* Tell the blanker task to change the pattern. */
Signal(BlankTask,SIGBREAKF_CTRL_D);
PatternCount = 0;
}
break;
}
break;
/* It's an internal Commodities command. */
case CXM_COMMAND: switch(MessageType)
{
/* Disable the Commodity. */
case CXCMD_DISABLE: ActivateCxObj(Broker,FALSE);
break;
/* Enable the Commodity. */
case CXCMD_ENABLE: ActivateCxObj(Broker,TRUE);
break;
/* Create the control panel. */
case CXCMD_APPEAR:
case CXCMD_UNIQUE: SetupWindow();
break;
/* Close the control panel. */
case CXCMD_DISAPPEAR: ShutdownWindow();
break;
/* Remove this Commodity. */
case CXCMD_KILL: CloseAll(RETURN_OK);
break;
}
break;
}
}
/* Random(ULONG MaxValue):
*
* Simple random number generation routine.
*/
ULONG
Random(ULONG MaxValue)
{
STATIC ULONG RandomSeed = 0xDEAD0123;
RandomSeed = RandomSeed * custom . vhposr + 0xE153766F;
return(RandomSeed % MaxValue);
}
/* Blanker():
*
* The screen blanker itself.
*/
VOID __saveds
Blanker()
{
/* Open the screen. */
if(BlankScreen = OpenScreenTags(NULL,
SA_Behind, TRUE,
SA_Quiet, TRUE,
SA_DisplayID, HIRESLACE_KEY,
SA_Overscan, OSCAN_STANDARD,
SA_Depth, 1,
TAG_DONE))
{
STATIC BYTE Wheel = 0;
UWORD Modulo = BlankScreen -> RastPort . BitMap -> BytesPerRow,Colours[2],OffsetX = BlankScreen -> Width >> 1,OffsetY = BlankScreen -> Height >> 1;
PLANEPTR Plane = BlankScreen -> RastPort . BitMap -> Planes[0];
float x = 0,y = 0,yy,a,b,c,sx,sy,mag,save;
/* Provide starting numbers for the fractal
* parameters.
*/
a = (float)Random(300) / 100;
b = (float)Random(100) / 100;
c = (float)Random( 50) / 100;
mag = (float)(1 << (Random(4) + 5)) * deg45;
/* Set up the screen colour table. */
Colours[0] = 0;
Colours[1] = Table[Wheel];
LoadRGB4(&BlankScreen -> ViewPort,Colours,2);
/* Push the screen to the front. */
ScreenToFront(BlankScreen);
/* Turn off all sprite channels. */
SpriteSwitch(FALSE);
/* Go into fractal generation loop. */
FOREVER
{
/* The original formula looks like
* this:
* ½
* x <- y - SIGN(x) * ABS(b * x - c)
* y <- a - x
*
* I have split the calculation into
* several steps to save time and
* variables.
*/
yy = a - x;
if((save = b * x - c) < 0)
save = -save;
if(x < 0)
x = y + sqrt(save);
else
x = y - sqrt(save);
y = yy;
/* The resulting image appears to have
* been rotated by 45°, so we'll
* rotate the pixel coordinates by -45°
*
* x <- x * cos alpha + y * sin alpha
* y <- -x * sin alpha + y * cos alpha
*
* We also magnify the image (i.e. the
* distribution of pixels) in the following
* lines.
*/
sx = mag * ( x + y);
sy = mag * (-x + y);
/* If the pixel happens to reside within
* the boundaries of the screen, draw it.
*/
Plot(Plane,(LONG)(sx) + OffsetX,(LONG)(sy) + OffsetY,Modulo,BlankScreen -> Width,BlankScreen -> Height);
/* ^D tells the blanker to change the pattern. */
if(SetSignal(0,0) & SIGBREAKF_CTRL_D)
{
SetSignal(0,SIGBREAKF_CTRL_D);
SetRast(&BlankScreen -> RastPort,0);
x = y = 0;
a = (float)Random(300) / 100;
b = (float)Random(100) / 100;
c = (float)Random( 50) / 100;
mag = (float)(1 << (Random(4) + 5)) * deg45;
}
/* ^E tells the blanker to rotate the
* colours.
*/
if(SetSignal(0,0) & SIGBREAKF_CTRL_E)
{
SetSignal(0,SIGBREAKF_CTRL_E);
Wheel = (Wheel + 1) % 75;
Colours[1] = Table[Wheel];
LoadRGB4(&BlankScreen -> ViewPort,Colours,2);
}
}
}
/* Quietly remove ourselves. */
Forbid();
BlankTask = NULL;
RemTask(SysBase -> ThisTask);
}
/* CloseAll(LONG ReturnCode):
*
* Free all resources and exit the program.
*/
VOID
CloseAll(LONG ReturnCode)
{
if(CxBase && IconBase)
{
ShutdownCx();
ArgArrayDone();
}
if(BlankTask)
RemTask(BlankTask);
if(BlankScreen)
{
SpriteSwitch(TRUE);
ScreenToBack(BlankScreen);
CloseScreen(BlankScreen);
}
ShutdownWindow();
if(IconBase)
CloseLibrary(IconBase);
if(CxBase)
CloseLibrary(CxBase);
if(GadToolsBase)
CloseLibrary(GadToolsBase);
if(GfxBase)
CloseLibrary(GfxBase);
if(IntuitionBase)
CloseLibrary(IntuitionBase);
exit(ReturnCode);
}
/* OpenAll(int argc,char **argv):
*
* Open all resources, initialize the colour table and
* create the Commodities interface.
*/
VOID
OpenAll(int argc,char **argv)
{
UBYTE **ToolTypes,*String;
SHORT i,c = 0,r = 15,g = 0,b = 0;
/* Create a table of rainbow colours. */
for(i = 0 ; i < 16 ; i++)
Table[c++] = (r << 8) | ((g++) << 4) | b;
g = 15;
r--;
for(i = 0 ; i < 15 ; i++)
Table[c++] = ((r--) << 8) | (g << 4) | b;
r = 0;
g--;
b++;
for(i = 0 ; i < 15 ; i++)
Table[c++] = (r << 8) | ((g--) << 4) | (b++);
g = 0;
b = 15;
r++;
for(i = 0 ; i < 15 ; i++)
Table[c++] = ((r++) << 8) | (g << 4) | b;
r = 15;
b--;
for(i = 0 ; i < 14 ; i++)
Table[c++] = (r << 8) | (g << 4) | (b--);
/* Open the libraries we need. */
if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37)))
CloseAll(RETURN_FAIL + 0);
if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",37)))
CloseAll(RETURN_FAIL + 1);
if(!(GadToolsBase = OpenLibrary("gadtools.library",37)))
CloseAll(RETURN_FAIL + 2);
if(!(CxBase = OpenLibrary("commodities.library",37)))
CloseAll(RETURN_FAIL + 3);
if(!(IconBase = OpenLibrary("icon.library",37)))
CloseAll(RETURN_FAIL + 4);
/* Parse the startup arguments. */
ToolTypes = ArgArrayInit(argc,argv);
/* Provide default values. */
strcpy(HotkeyBuffer, "shift f1");
strcpy(BlankScreenBuffer, "shift f2");
ScreenTimeout = 60;
PatternTimeout = 60;
/* Create the commodities interface. */
if(!SetupCx(ToolTypes))
CloseAll(RETURN_FAIL + 5);
/* Pop up the control panel if necessary. */
if(ToolTypes)
{
String = ArgString(ToolTypes,"CX_POPUP","no");
if(!strcmpi(String,"yes") || !strcmpi(String,"on"))
SetupWindow();
}
}
/* main(int argc,char **argv):
*
* That's where all the trouble starts.
*/
VOID __stdargs
main(int argc,char **argv)
{
ULONG SignalSet;
/* Open everything we need. */
OpenAll(argc,argv);
/* Go into loop waiting for messages. */
FOREVER
{
SignalSet = (1 << CxPort -> mp_SigBit) | SIGBREAKF_CTRL_E;
/* If the window is still open, wait for
* some news.
*/
if(Window)
SignalSet |= (1 << Window -> UserPort -> mp_SigBit);
SignalSet = Wait(SignalSet);
/* There are messages pending at the
* Commodities reply port.
*/
if(SignalSet & (1 << CxPort -> mp_SigBit))
{
CxMsg *Message;
while(Message = (CxMsg *)GetMsg(CxPort))
HandleCxMsg(Message);
}
/* ^E tells the program to quit. */
if(SignalSet & SIGBREAKF_CTRL_E)
CloseAll(RETURN_OK);
/* If the control panel is still open,
* check for new messages.
*/
if(Window)
{
if(SignalSet & (1 << Window -> UserPort -> mp_SigBit))
{
struct IntuiMessage *Massage;
struct Gadget *Gadget;
ULONG Class,Code;
while(Massage = (struct IntuiMessage *)GT_GetIMsg(Window -> UserPort))
{
Class = Massage -> Class;
Code = Massage -> Code;
Gadget = (struct Gadget *)Massage -> IAddress;
GT_ReplyIMsg(Massage);
switch(Class)
{
/* Close the window. */
case IDCMP_CLOSEWINDOW: ShutdownWindow();
break;
/* Set the slider values. */
case IDCMP_MOUSEMOVE: switch(Gadget -> GadgetID)
{
case GAD_SCREENTIMEOUT: ScreenCount = 0;
ScreenTimeout = Code;
break;
case GAD_PATTERNCHANGE: PatternCount = 0;
PatternTimeout = Code;
break;
}
break;
/* Handle the keyboard shortcuts. */
case IDCMP_VANILLAKEY: switch(toupper(Code))
{
case 'S': ScreenCount = 0;
if(Code == 's')
{
if(ScreenTimeout + 1 <= 30 * 60)
ScreenTimeout++;
else
ScreenTimeout = ScreenTimeout + 1 - 30 * 60;
}
else
{
if(ScreenTimeout + 10 <= 30 * 60)
ScreenTimeout += 10;
else
ScreenTimeout = ScreenTimeout + 10 - 30 * 60;
}
GT_SetGadgetAttrs(GadgetArray[GAD_SCREENTIMEOUT],Window,NULL,
GTSL_Level,ScreenTimeout,
TAG_DONE);
break;
case 'P': PatternCount = 0;
if(Code == 'p')
{
if(PatternTimeout + 1 <= 30 * 60)
PatternTimeout++;
else
PatternTimeout = PatternTimeout + 1 - 30 * 60;
}
else
{
if(PatternTimeout + 10 <= 30 * 60)
PatternTimeout += 10;
else
PatternTimeout = PatternTimeout + 10 - 30 * 60;
}
GT_SetGadgetAttrs(GadgetArray[GAD_PATTERNCHANGE],Window,NULL,
GTSL_Level,PatternTimeout,
TAG_DONE);
break;
case 'K': ActivateGadget(GadgetArray[GAD_HOTKEY],Window,NULL);
break;
case 'B': ActivateGadget(GadgetArray[GAD_BLANKSCREEN],Window,NULL);
break;
case 'H': ShutdownWindow();
break;
case 'Q': CloseAll(RETURN_OK);
default: break;
}
break;
/* Handle the gadgets themselves. */
case IDCMP_GADGETUP: switch(Gadget -> GadgetID)
{
case GAD_HOTKEY: strcpy(HotkeyBuffer,((struct StringInfo *)Gadget -> SpecialInfo) -> Buffer);
if(!SetupCx(NULL))
CloseAll(RETURN_FAIL + 5);
break;
case GAD_BLANKSCREEN: strcpy(BlankScreenBuffer,((struct StringInfo *)Gadget -> SpecialInfo) -> Buffer);
if(!SetupCx(NULL))
CloseAll(RETURN_FAIL + 5);
break;
case GAD_HIDE: ShutdownWindow();
break;
case GAD_QUIT: CloseAll(RETURN_OK);
}
break;
}
/* Window has been closed, do not
* continue requesting messages
* from the UserPort.
*/
if(!Window)
break;
}
}
}
}
}