home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
384.lha
/
MyClock
/
MyClock.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-06-02
|
9KB
|
385 lines
/*
* MKSoft Mini Clock Face
*
* The DoClock() routine is 100% reentrant. However, it needs
* GfxBase and IntuitionBase set up for it.
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <devices/timer.h>
#include <graphics/gfx.h>
#include <graphics/rastport.h>
#include <intuition/intuition.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/timer.h>
/* MKS_WINDOW is the special version that puts the clock exactly where I want it... */
/* #define MKS_WINDOW */
/* DETATCH_CLOCK is used to add in the Detatch data structures */
/* #define DETATCH_CLOCK */
/* When testing, I set this to 1 so that I can see the hands move faster */
/* It should be 60 for any real work... */
#define SECONDS_PER_MINUTE (60)
static short SinArray[16]={0,105,208,309,407,500,588,669,743,809,866,914,951,978,995,1000};
void AdjustXY(short Minutes,short *x1,short *y1,short Radius_X,short Radius_Y)
{
register long x;
register long y;
register short tmp;
register short tmp1;
tmp1=(15-(tmp=(Minutes % 15)));
if (Minutes<15)
{
x=SinArray[tmp]; y=-SinArray[tmp1];
}
else if (Minutes<30)
{
x=SinArray[tmp1]; y=SinArray[tmp];
}
else if (Minutes<45)
{
x=-SinArray[tmp]; y=SinArray[tmp1];
}
else
{
x=-SinArray[tmp1]; y=-SinArray[tmp];
}
x*=Radius_X;
y*=Radius_Y;
(*x1)+=(short)((x+((x<0) ? -500 : 500))/1000);
(*y1)+=(short)((y+((y<0) ? -500 : 500))/1000);
}
void DrawArm(struct RastPort *rp,short Minutes,short Radius_X,short Radius_Y,short Center_X,short Center_Y)
{
#ifdef THIN_LINE
Move(rp,Center_X,Center_Y);
AdjustXY(Minutes,&Center_X,&Center_Y,Radius_X,Radius_Y);
Draw(rp,Center_X,Center_Y);
#else /* THIN_LINE */
register short loop;
short x,y;
short x1,y1;
x=Center_X;
y=Center_Y;
AdjustXY(Minutes,&x,&y,Radius_X,Radius_Y);
Move(rp,x,y);
Radius_X=1+(Radius_X >> 4);
Radius_Y=1+(Radius_Y >> 4);
for (loop=0;loop<3;loop++)
{
x1=Center_X;
y1=Center_Y;
Minutes=(Minutes+15)%60;
AdjustXY(Minutes,&x1,&y1,Radius_X,Radius_Y);
Draw(rp,x1,y1);
}
Draw(rp,x,y);
#endif /* THIN_LINE */
}
void DrawHands(struct RastPort *rp,short Hours,short Minutes,short Center_X,short Center_Y)
{
DrawArm(rp,(Hours*5)+(Minutes/12),Center_X-5-(Center_X >> 2),Center_Y-5-(Center_Y >> 2),Center_X,Center_Y);
DrawArm(rp,Minutes,Center_X-4,Center_Y-4,Center_X,Center_Y);
}
void DoClock(short LeftEdge,short TopEdge,short Size_X,short Size_Y,UBYTE Face_Pen,UBYTE Hand_Pen,short DragFlag)
{
register struct MsgPort *myport;
register struct Window *window;
register struct RastPort *rp;
register PLANEPTR raster;
register short ExitFlag=FALSE;
register short loop;
register ULONG winSig;
register ULONG timSig;
register short Minutes=0;
register short Hours=0;
register ULONG tmp;
register short Center_X;
register short Center_Y;
struct timerequest Time_Req;
struct TmpRas tmpras;
struct AreaInfo AreaInfo;
struct NewWindow NewWin;
#ifndef MKS_WINDOW
struct Gadget Gad;
#endif /* MKS_WINDOW */
short AreaBuffer[10];
Center_X=((Size_X - 1) >> 1);
Center_Y=((Size_Y - 1) >> 1);
#ifndef MKS_WINDOW
Gad.NextGadget=NULL;
Gad.LeftEdge=0;
Gad.TopEdge=0;
Gad.Width=Size_X;
Gad.Height=Size_Y;
Gad.Flags=GADGHNONE;
Gad.Activation=RELVERIFY;
Gad.GadgetType=WDRAGGING;
Gad.GadgetRender=NULL;
Gad.SelectRender=NULL;
Gad.GadgetText=NULL;
Gad.MutualExclude=NULL;
Gad.SpecialInfo=NULL;
#endif /* MKS_WINDOW */
NewWin.LeftEdge=LeftEdge;
NewWin.TopEdge=TopEdge;
NewWin.Width=Size_X;
NewWin.Height=Size_Y;
NewWin.IDCMPFlags=VANILLAKEY;
NewWin.Flags=BORDERLESS|NOCAREREFRESH|RMBTRAP;
NewWin.FirstGadget=NULL;
#ifndef MKS_WINDOW
if (DragFlag) NewWin.FirstGadget=&Gad;
#endif /* MKS_WINDOW */
NewWin.CheckMark=NULL;
NewWin.Title=NULL;
NewWin.Screen=NULL;
NewWin.BitMap=NULL;
NewWin.Type=WBENCHSCREEN;
if (myport=CreatePort(NULL,NULL))
{
timSig=(1L << (myport->mp_SigBit));
if (!OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)&Time_Req,NULL))
{
Time_Req.tr_node.io_Message.mn_ReplyPort=myport;
if (raster=AllocRaster(Size_X,Size_Y))
{
InitTmpRas(&tmpras,(APTR)raster,RASSIZE((ULONG)Size_X,(ULONG)Size_Y));
if (window=OpenWindow(&NewWin))
{
winSig=(1L << (window->UserPort->mp_SigBit));
/* Get RastPort and set draw modes... */
rp=window->RPort;
rp->TmpRas=&tmpras;
SetAPen(rp,Face_Pen);
SetDrMd(rp,JAM1);
/* Draw the circle */
for (loop=0;loop<10;AreaBuffer[loop++]=0);
InitArea(rp->AreaInfo=&AreaInfo,(APTR)AreaBuffer,4);
AreaEllipse(rp,Center_X,Center_Y,Center_X,Center_Y);
AreaEnd(rp);
/* Draw the hash marks */
SetAPen(rp,Hand_Pen);
Move(rp,Center_X,1); Draw(rp,Center_X,3);
Move(rp,1,Center_Y); Draw(rp,3,Center_Y);
Move(rp,Center_X,Size_Y-2); Draw(rp,Center_X,Size_Y-4);
Move(rp,Size_X-2,Center_Y); Draw(rp,Size_X-4,Center_Y);
while (!ExitFlag)
{
/* Get current time... */
Time_Req.tr_node.io_Command=TR_GETSYSTIME;
Time_Req.tr_node.io_Flags=IOF_QUICK;
DoIO(&Time_Req.tr_node);
/* Erase old hands... */
SetAPen(rp,Face_Pen);
DrawHands(rp,Hours,Minutes,Center_X,Center_Y);
/* Calculate new time... */
tmp=(Time_Req.tr_time.tv_secs)/SECONDS_PER_MINUTE;
Minutes=tmp % 60;
Hours=(tmp / 60) % 12;
/* Draw hands new...*/
SetAPen(rp,Hand_Pen);
DrawHands(rp,Hours,Minutes,Center_X,Center_Y);
/* Clear possible old timer signal */
if ((FindTask(NULL)->tc_SigRecvd)&timSig) Wait(timSig);
/* Set sleep time... */
Time_Req.tr_node.io_Command=TR_ADDREQUEST;
Time_Req.tr_time.tv_secs=SECONDS_PER_MINUTE;
Time_Req.tr_time.tv_micro=0;
SendIO(&Time_Req.tr_node);
if (Wait(winSig|timSig)&winSig)
{
register struct IntuiMessage *msg;
while (msg=(struct IntuiMessage *)GetMsg(window->UserPort))
{
if ((msg->Class==VANILLAKEY)&&(msg->Code==0x1B)) ExitFlag=TRUE;
ReplyMsg((struct Message *)msg);
}
AbortIO((struct IORequest *)&Time_Req);
}
WaitIO((struct IORequest *)&Time_Req);
}
CloseWindow(window);
}
FreeRaster(raster,Size_X,Size_Y);
}
CloseDevice((struct IORequest *)&Time_Req);
}
DeletePort(myport);
}
}
int CXBRK(VOID) { return(0); }
#ifdef MKS_WINDOW
#define FACE_SIZE_X (55)
#define FACE_SIZE_Y (45)
void main(void)
{
#else /* MKS_WINDOW */
#include <proto/dos.h>
#include <string.h>
#include <stdlib.h>
#define FACE_SIZE_X (45)
#define FACE_SIZE_Y (39)
#define FACE_SIZE_MIN (19)
#define USAGE_SIZE 102
#ifdef DETATCH_CLOCK
/* For CBack.o */
char procname[]="MKSoft Mini-Clock";
long priority=1;
long stack=4000;
#else /* DETATCH_CLOCK */
/* Help line. Only if not DETATCH_CLOCK... */
static char Usage[USAGE_SIZE+1]="Usage: MyClock [LEFT x] [TOP y] [WIDTH x] [HEIGHT y]\n [FACE c] [HANDS c] [DRAG|NODRAG]\n\n";
#endif /* DETATCH_CLOCK */
void main(int argc,char *argv[])
{
register short Drag_Flag=TRUE;
register short loop;
register short error=FALSE;
struct Screen Screen;
short LeftEdge;
short TopEdge;
short Size_X=0;
short Size_Y=0;
short Face_Pen;
short Hand_Pen;
#endif /* MKS_WINDOW */
if (IntuitionBase=OpenLibrary("intuition.library",33L))
{
if (GfxBase=OpenLibrary("graphics.library",33L))
{
#ifdef MKS_WINDOW
DoClock(656-((FACE_SIZE_X-1)>>1),434-FACE_SIZE_Y,FACE_SIZE_X,FACE_SIZE_Y,2,1,FALSE);
#else /* MKS_WINDOW */
GetScreenData((CPTR)&Screen,sizeof(struct Screen),WBENCHSCREEN,NULL);
Size_X=FACE_SIZE_X;
Size_Y=(Screen.Height < 300) ? FACE_SIZE_MIN : FACE_SIZE_Y;
LeftEdge=Screen.Width;
TopEdge=Screen.Height;
Face_Pen=Screen.BlockPen;
Hand_Pen=Screen.DetailPen;
if (argc)
{
register char *c;
register short *change;
for (loop=1;loop<argc;loop++)
{
c=argv[loop];
if (!stricmp(c,"DRAG")) Drag_Flag=TRUE;
else if (!stricmp(c,"NODRAG")) Drag_Flag=FALSE;
else if ((loop+1)<argc)
{
if (!stricmp(c,"LEFT")) change=&LeftEdge;
else if (!stricmp(c,"TOP")) change=&TopEdge;
else if (!stricmp(c,"WIDTH")) change=&Size_X;
else if (!stricmp(c,"HEIGHT")) change=&Size_Y;
else if (!stricmp(c,"FACE")) change=&Face_Pen;
else if (!stricmp(c,"HANDS")) change=&Hand_Pen;
else change=NULL;
if (change)
{
loop++;
*change=(short)atol(argv[loop]);
}
else error=TRUE;
}
else error=TRUE;
}
}
if (error)
{
#ifndef DETATCH_CLOCK
register BPTR out;
if (out=Output()) Write(out,Usage,USAGE_SIZE);
#endif /* DETATCH_CLOCK */
}
else
{
if (Size_X<FACE_SIZE_MIN) Size_X=FACE_SIZE_MIN;
if (Size_Y<FACE_SIZE_MIN) Size_Y=FACE_SIZE_MIN;
if (Size_X>Screen.Width) Size_X=Screen.Width;
if (Size_Y>Screen.Height) Size_Y=Screen.Height;
if (LeftEdge<0) LeftEdge=0;
if ((LeftEdge+Size_X)>Screen.Width) LeftEdge=Screen.Width-Size_X;
if (TopEdge<0) TopEdge=0;
if ((TopEdge+Size_Y)>Screen.Height) TopEdge=Screen.Height-Size_Y;
if (Face_Pen==Hand_Pen)
{
Face_Pen=1;
Hand_Pen=0;
}
DoClock(LeftEdge,TopEdge,Size_X,Size_Y,(UBYTE)Face_Pen,(UBYTE)Hand_Pen,Drag_Flag);
}
#endif /* MKS_WINDOW */
CloseLibrary((struct Library *)GfxBase);
}
CloseLibrary((struct Library *)IntuitionBase);
}
}