home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 2
/
goldfish_vol2_cd1.bin
/
files
/
comm
/
misc
/
timer
/
timer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-12
|
10KB
|
378 lines
/***********************************************************************
Timer.c (c) HooverSoft 1993. Freely distributable for non-commercial
purposes.
It started as another test program, now it's actually turned into
something useful. :-)
Before I say anything else: The timer.device routines were completely
ripped off from Mike Meyer's "mclk.c". Mike, I'm definitely not going
to make money out of this, but thanks very much for mclk.c :-)
Contact me at hoover@mathematik.uni-bielefeld.de if you have questions
or suggestions for improvements.
***********************************************************************/
/* Includes that we need */
#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <devices/timer.h>
#include <stdio.h>
char *_procname = "Timer";
#define WINX 253 /* STD window size */
#define WINY 27
#define STARTGAD 10 /* Gadget ID's */
#define STOPGAD 11
#define BLACK 1 /* Color definitions */
#define WHITE 2
#define GREY 0
#define PURPLE 3
#define GADWIDTH 45 /* Gadget Dims */
#define GADHEIGHT 10
#define LOGNAME "S:Timer.log" /* Log file name */
static struct timerequest Time_Req;
static struct MsgPort *Timer_Port = NULL, *CreatePort ();
/******************************************************************
Command line Options and their respective default values
autostart: NO
interval: 8 mins
activescreen: NO
logging: NO
x = 10
y = 10
******************************************************************/
ULONG AUTOSTART = 0, INTERVAL = 8, ACTIVE_SCREEN = 0, LOGGING = 0;
UWORD x = 10, y = 10;
ULONG seconds = 0; /* total time elapsed */
struct NewWindow nw =
{00, 11,
/* start LeftEdge, TopEdge */
WINX, WINY, /* start Width, Height */
AUTOFRONTPEN, AUTOBACKPEN, /* DetailPen, BlockPen */
GADGETUP | CLOSEWINDOW, /* IDCMP FLAGS */
WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE,
/* Flags (can be NULL) */
NULL, /* Pointer to FirstGadget */
NULL, /* no pointer to first CheckMark */
(UBYTE *) "Timer V1.04 © HooverSoft", /* Title (can be NULL) */
NULL, /* no Pointer to Screen */
NULL, /* no Pointer to BitMap */
-1, -1,
-1, -1,
WBENCHSCREEN /* Type of screen window appears in */
};
/* Signal masks for our ports */
#define WINMASK 1L << window -> UserPort -> mp_SigBit
#define TMASK 1L << Timer_Port -> mp_SigBit
/* Global variables */
struct Window *window = NULL;
struct IntuitionBase *IntuitionBase = NULL;
SHORT WHITEvecs[] =
{0, 0, GADWIDTH, 0, 0, 0, 0, GADHEIGHT, 0, 0};
SHORT BLACKvecs[] =
{1, GADHEIGHT, GADWIDTH, GADHEIGHT,
GADWIDTH, 1, GADWIDTH, GADHEIGHT, 1, GADHEIGHT};
/*
Borders to achieve 3d lighting effect
I know this can be done with Gadtools.library, but I still haven't
got the RKM's
downside to this method: Font independency becomes a bit harder to
implement (when it will be done :).
*/
struct Border wb =
{-1, -1, WHITE, BLACK, JAM1, 5, WHITEvecs, NULL};
struct Border bb =
{-1, -1, BLACK, BLACK, JAM1, 5, BLACKvecs, &wb};
struct IntuiText start_t =
{BLACK, WHITE, JAM1, 1, 1, NULL, "Start", NULL};
struct IntuiText stop_t =
{BLACK, WHITE, JAM1, 6, 1, NULL, "Stop", NULL};
struct IntuiText total_t =
{BLACK, GREY, JAM2, 0, 0, NULL, NULL, NULL};
/* Gadgets */
struct Gadget startg =
{NULL, 6, WINY - 14, GADWIDTH - 1,
GADHEIGHT, GADGHCOMP, RELVERIFY, BOOLGADGET, (APTR) & bb, NULL, &start_t,
NULL, NULL, STARTGAD, 0};
struct Gadget stopg =
{(struct Gadget *) &startg, WINX - GADWIDTH - 6,
WINY - 14, GADWIDTH - 1, GADHEIGHT, GADGHCOMP, RELVERIFY, BOOLGADGET, (APTR)
& bb, NULL, (struct IntuiText *) &stop_t, NULL, NULL, STOPGAD, NULL};
/***********************************************************************
close everything and exit
***********************************************************************/
void
clean_exit (int status)
{
FILE *logfp; /* Log file pointer */
if (LOGGING)
{
if (!(logfp = fopen (LOGNAME, "a+")))
{
puts ("could not open log file!\n");
goto error;
}
else
{
static long date = 0, store;
date = time (&store);
if (seconds > 0)
fprintf (logfp, "%4ld mins = %ld unit(s) on %s", (seconds / 60) ? (seconds / 60) : 1, 1 + ((seconds / 60) / INTERVAL), ctime (&date));
}
fclose (logfp);
} /* end if(LOGGING) */
error:
/*
Killing the timer device might be done in a more system friendly
way, but this code is courtesy of Mike Meyer, not me. 8-P
Main thing is we get "Total used: 0" on "mem -r" in Csh.
*/
AbortIO ((char *) &Time_Req.tr_node);
if (Time_Req.tr_node.io_Message.mn_ReplyPort)
CloseDevice (&Time_Req);
if (Timer_Port)
DeletePort (Timer_Port);
if (window)
CloseWindow (window);
if (IntuitionBase)
CloseLibrary (IntuitionBase);
exit (status);
}
/***********************************************************************
Parse command line arguments
***********************************************************************/
void
parse_options (int count, char *args[])
{
register int i;
for (i = 1; i < count; i++)
{
if (*args[i] == '-') /* check for option introducer */
{
args[i]++;
if (!(strcmp (args[i], "autostart")))
{
AUTOSTART = 1;
total_t.FrontPen = PURPLE;
continue;
}
if (!(strcmp (args[i], "firstscreen")))
{
ACTIVE_SCREEN = 1;
continue;
}
if (!(strcmp (args[i], "interval")))
{
INTERVAL = atoi (args[i + 1]);
INTERVAL = (INTERVAL == 0) ? 12L : INTERVAL;
i++;
continue;
}
if (!(strcmp (args[i], "log")))
{
LOGGING = 1;
continue;
}
if (!(strcmp (args[i], "x")))
{
x = atoi (args[i + 1]);
i++;
continue;
}
if (!(strcmp (args[i], "y")))
{
y = atoi (args[i + 1]);
i++;
continue;
}
exit (RETURN_WARN);
} /* end if(option_introducer) */
} /* end for */
return;
}
/***********************************************************************
Print current data
**********************************************************************/
void
show_data (long time) /* Passed: seconds */
{
static char string[80]; /* Time string */
register char secs[3], mins[3], hours[3]; /* place to hold components */
register ULONG s, m, h;
/* Calculate current time */
s = time % 60;
m = (time / 60) % 60;
h = time / 3600;
/* convert to string */
sprintf (secs, (s < 10) ? "0%1ld" : "%2ld", s);
sprintf (mins, (m < 10) ? "0%1ld" : "%2ld", m);
sprintf (hours, (h < 10) ? "0%1ld" : "%2ld", h);
sprintf (string, "%2ld/%2ld %2s:%2s:%2s", INTERVAL,
1 + ((time / 60) / INTERVAL), hours, mins, secs);
total_t.IText = string;
PrintIText (window->RPort, &total_t, 6 + GADWIDTH + 12, 14);
return;
}
/***********************************************************************
Init timerequest structure
***********************************************************************/
void
start_timer ()
{
if ((Timer_Port = CreatePort ("Timer Port", 0)) == NULL)
{
puts ("Can't create timer port\n");
clean_exit (50);
}
if (OpenDevice (TIMERNAME, UNIT_VBLANK, (char *) &Time_Req, 0) != NULL)
{
puts ("Can't open timer device!");
clean_exit (20);
}
Time_Req.tr_node.io_Message.mn_ReplyPort = Timer_Port;
Time_Req.tr_node.io_Command = TR_ADDREQUEST;
Time_Req.tr_node.io_Flags = 0;
Time_Req.tr_node.io_Error = 0;
return;
}
/***********************************************************************
Set up a new timer request
***********************************************************************/
void
restart_timer ()
{
Time_Req.tr_time.tv_secs = 1;
Time_Req.tr_time.tv_micro = 0;
SendIO ((char *) &Time_Req.tr_node);
return;
}
/***********************************************************************
main program
***********************************************************************/
void
main (int argc, char **argv)
{
int class;
struct IntuiMessage *msg, *GetMsg (struct MsgPort *);
long RUNNING = 0;
if (argc > 1) /* did we get additional parameters? */
parse_options (argc, argv);
/* Open libs */
if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 0L)))
{
puts ("Can't open intuition.library!\n");
clean_exit (10);
}
if (ACTIVE_SCREEN)
{
seconds = LockIBase (0); /* Lock out all access to IntuitionBase */
nw.Screen = IntuitionBase->FirstScreen;
UnlockIBase (seconds); /* and unlock again */
seconds = 0; /* set seconds back to zero */
nw.Type = CUSTOMSCREEN;
}
if (AUTOSTART)
RUNNING = 1;
/* init gadgets */
nw.FirstGadget = &stopg;
nw.LeftEdge = x;
nw.TopEdge = y;
start_timer ();
if (!(window = (struct Window *) OpenWindow ((struct NewWindow *) &nw)))
{
puts ("Can't open window!\n");
clean_exit (20);
}
for (;;)
{
long signals;
static struct Gadget *gad = NULL;
if (RUNNING)
restart_timer ();
signals = Wait (WINMASK | TMASK);
if (signals & WINMASK)
{
while ((msg = GetMsg (window->UserPort)))
{
class = msg->Class;
gad = (struct Gadget *) (msg->IAddress);
ReplyMsg (msg);
switch (class)
{
case CLOSEWINDOW:
clean_exit (0);
break;
case GADGETUP:
if (gad->GadgetID == STARTGAD && RUNNING)
break;
if (gad->GadgetID == STOPGAD && !RUNNING)
{
seconds = 0;
show_data (seconds);
}
if (gad->GadgetID == STOPGAD && !RUNNING)
{
seconds = 0;
show_data (seconds);
}
if (gad->GadgetID == STARTGAD)
{
RUNNING = 1;
total_t.FrontPen = PURPLE;
}
if (gad->GadgetID == STOPGAD)
{
RUNNING = 0;
total_t.FrontPen = BLACK;
}
default:
break;
} /* end switch */
}
}
else if (signals & TMASK) /* We got a message from timer.device */
{
GetMsg (Timer_Port);
seconds++;
show_data (seconds);
}
} /* end for(;;) */
} /* end main() */