/************************************************************************* * * SPUDclock - This program does a nice little talking alarm clock * * This was written by Robert E. Beaty and H. Bret Young and * are Copyright (C) 1987 by R.E.Beaty and H. Bret Young and * The Man From S.P.U.D. * * v1.2 *************************************************************************/ /* Get the necessary include files for this program */ #include #include #include #include #include #include #include #include /* * Here are some necessary defines for processing needs */ #define REVISION 1 #define TASK_PRIORITY 0 /* * Here are some necessary return codes for various routines */ #define NORMAL_EXIT 0 #define NORMAL_START 0 #define QUICK_EXIT -10 #define QUICK_START -20 #define CANT_OPEN_INTUITION -100 #define CANT_OPEN_TRANSLATOR -200 #define CANT_OPEN_NARRATOR -300 #define CANT_OPEN_TIMER -400 #define CREATE_PORT_PROBLEMS -500 #define CREATE_IO_PROBLEMS -600 #define TRANSLATOR_NOT_WORKING -700 /* * Here are the variable values that come in handy */ #define QUARTER_HOUR 1 #define HALF_HOUR 2 #define HOUR 4 #define LITTLE 1 #define BIG 2 #define AM_BIT (1<<0) #define PS_BIT (1<<1) #define SA_BIT (1<<2) #define EA_BIT (1<<3) #define AV_BIT (1<<4) #define S_BIT (1<<5) /* * Here are the global structures */ struct timerequest timeReq; /* this is my conduit to the timer */ struct MsgPort *clockPort = NULL, *writePort = NULL, *replyPort = NULL, *timerPort = NULL; struct narrator_rb *writeNarrator = NULL; struct IntuitionBase *IntuitionBase = NULL; struct Library *TranslatorBase = NULL; struct DateStamp now; struct PacketMessage { struct Message packet_message; /* this is for DOS */ int alarm_mode, /* this will tell us how often to alarm */ prestart, /* this will tell if we prestart the speakers */ start_alarm, /* this is the starting time */ end_alarm, /* this is the ending time */ alarm_volume, /* this is how loud to make it */ quit_flag; /* this will tell when to quit */ char salutation[80]; /* this is a little saying before the time */ int change_flags, changing, listing; }; /* * Here are the global variables */ UBYTE *sampleInput, outputString[500]; /* these are for the translator */ SHORT rtnCode, error; BYTE audChanMasks[4] = { 3, 5, 10, 12 }; /* which channels to use */ int signal, timer_signal, port_signal; /* where the message came from */ int alarm_mode, quit_flag, prestart, alarm_volume; int start_alarm, end_alarm, alarm_time; int hours_24, hours_12, minutes; char *cp, salutation[80], alarm[120]; struct PacketMessage *incoming, *outgoing; /************************************************************************ * * cprintf( why ) - This routine does simple string printing to * the console, and so saves us loading the printf * routines. * * This code section was written by Robert E. Beaty and * are Copyright (C) 1987 by R.E.Beaty and The Man From S.P.U.D. * ************************************************************************/ cprintf( arg ) char *arg; { int length; length = Write( Output(), arg, strlen(arg) ); return( length ); } /* end of cprintf(); */ /************************************************************************ * * itoa( string, value ) - This routine does simple integer to ascii * conversion. NOTE: value < 9999 !! * * This code section was written by Robert E. Beaty and * are Copyright (C) 1987 by R.E.Beaty and The Man From S.P.U.D. * ************************************************************************/ void itoa( carg, varg ) char *carg; int varg; { int place; /* reset where I am putting this stuff */ place = 0; if ( varg > 999 ) { /* do the most thousands digit */ carg[place++] = '0' + (varg/1000); varg = varg - (1000*(varg/1000)); } if ( (varg > 99) || (place != 0) ) { /* do the hundreds digit */ carg[place++] = '0' + (varg/100); varg = varg - (100*(varg/100)); } if ( (varg > 9) || (place != 0) ) { /* do the tens digit */ carg[place++] = '0' + (varg/10); varg = varg - (10*(varg/10)); } /* always do the ones digit */ carg[place++] = '0' + varg; /* null terminate this string */ carg[place] = '\0'; } /* end of itoa(); */ /************************************************************************ * * CloseNarrator( why ) - This routine closes up the narrator and * translator devices nicely. * * This code section was written by Robert E. Beaty and * are Copyright (C) 1987 by R.E.Beaty and The Man From S.P.U.D. * ************************************************************************/ void CloseNarrator( why ) int why; { /* Check to see if this was called by OpenNarrator() */ if ( why != CANT_OPEN_NARRATOR ) { if ( writeNarrator != NULL ) CloseDevice( writeNarrator ); } /* Just start deleting things if they exist */ if ( writeNarrator != NULL ) DeleteExtIO( writeNarrator, sizeof(struct narrator_rb) ); if ( writePort != NULL ) DeletePort( writePort ); if ( TranslatorBase != NULL ) CloseLibrary( TranslatorBase ); } /* end of CloseNarrator(); */ /************************************************************************ * * OpenNarrator() - This routine opens up the narrator and translator * devices nicely. It will return non-FALSE if an error * occured. * * This code section was written by Robert E. Beaty and * are Copyright (C) 1987 by R.E.Beaty and The Man From S.P.U.D. * ************************************************************************/ OpenNarrator( ) { int error; /* Open up the translator first */ TranslatorBase = (struct Library *) OpenLibrary( "translator.library", REVISION ); if ( TranslatorBase == NULL ) return( CANT_OPEN_TRANSLATOR ); /* test it */ sampleInput = "this is a test."; rtnCode = Translate( sampleInput, strlen(sampleInput), outputString, 500 ); if ( rtnCode != 0 ) { CloseLibrary( TranslatorBase ); /* this is open, so close */ return( TRANSLATOR_NOT_WORKING ); } /* end of error checking the translator */ /* Create the port to the Narrator */ writePort = (struct MsgPort *) CreatePort( "SPUDclock.narrator", TASK_PRIORITY ); if ( writePort == NULL ) { CloseLibrary( TranslatorBase ); /* this is open, so close */ return( CREATE_PORT_PROBLEMS ); } /* end of error checking the port creation */ /* Open an I/O channel to the Narrator */ writeNarrator = (struct narrator_rb *) CreateExtIO( writePort, sizeof(struct narrator_rb) ); if ( writeNarrator == NULL ) { DeletePort( writePort ); /* this port is open */ CloseLibrary( TranslatorBase ); /* this is open, so close */ return( CREATE_IO_PROBLEMS ); } /* end of error checking I/O creation */ /* Now set up the defaults for the narrator port */ writeNarrator->ch_masks = audChanMasks; /* ... the channel masks */ writeNarrator->nm_masks = sizeof(audChanMasks); /* ... the size */ writeNarrator->message.io_Data = (APTR)outputString; /* data */ writeNarrator->mouths = 0; /* we don't want shapes computed */ writeNarrator->message.io_Command = CMD_WRITE; /* output command */ /* Finally, open the narrator device */ error = OpenDevice( "narrator.device", 0, writeNarrator, TASK_PRIORITY ); if ( error != 0 ) { CloseNarrator( CANT_OPEN_NARRATOR ); /* close it all up */ return( CANT_OPEN_NARRATOR ); } /* end of checking narrator device opening */ /* no errors so return FALSE */ return( FALSE ); } /* end of OpenNarrator(); */ /************************************************************************ * * init( how ) - This routine opens everything up and returns non-FALSE * if something went wrong. * * This code section was written by Robert E. Beaty and * are Copyright (C) 1987 by R.E.Beaty and The Man From S.P.U.D. * ************************************************************************/ init( how ) int how; { int error; /* Open up Intuition first */ if ( IntuitionBase == NULL ) { IntuitionBase = (struct IntuitionBase *) OpenLibrary( "intuition.library", REVISION ); if ( IntuitionBase == NULL ) return( CANT_OPEN_INTUITION ); } /* end of opening intuition if needed */ /* if this is a quick start, then only open up intuition */ if ( how == QUICK_START ) return( FALSE ); /* Open the communication port to other copies of SPUDclock */ clockPort = (struct MsgPort *) CreatePort( "SPUDclock", TASK_PRIORITY ); if ( clockPort == NULL ) { CloseLibrary( IntuitionBase ); /* this is open, so close */ return( CREATE_PORT_PROBLEMS ); } /* end of error checking the port creation */ /* Now open the narrator */ error = OpenNarrator(); if ( error ) { DeletePort( clockPort ); CloseLibrary( IntuitionBase ); return( error ); } /* end of error checking the narrator opening */ /* Now create the timer */ timerPort = (struct MsgPort *) CreatePort( "SPUDclock.timer", TASK_PRIORITY ); if ( timerPort == NULL ) { CloseNarrator( CANT_OPEN_TIMER ); DeletePort( clockPort ); CloseLibrary( IntuitionBase ); /* this is open, so close */ return( CREATE_PORT_PROBLEMS ); } /* end of error checking the port creation */ error = OpenDevice( TIMERNAME, UNIT_VBLANK, (char *) &timeReq, TASK_PRIORITY ); if ( error != 0 ) { DeletePort( timerPort ); CloseNarrator( CANT_OPEN_TIMER ); DeletePort( clockPort ); CloseLibrary( IntuitionBase ); /* this is open, so close */ return( CANT_OPEN_TIMER ); } /* Everything is open O.K., so get the signal bits */ timer_signal = 1 << timerPort->mp_SigBit; port_signal = 1 << clockPort->mp_SigBit; /* ... and set up the timer request structure */ timeReq.tr_node.io_Message.mn_ReplyPort = timerPort; timeReq.tr_node.io_Command = TR_ADDREQUEST; timeReq.tr_node.io_Flags = 0; timeReq.tr_node.io_Error = 0; /* no errors, so return FALSE */ return( FALSE ); } /* end of init(); */ /************************************************************************ * * clean( why ) - This routine cleans everything up. * * This code section was written by Robert E. Beaty and * are Copyright (C) 1987 by R.E.Beaty and The Man From S.P.U.D. * ************************************************************************/ void clean( why ) int why; { /* Abort the timer request pending */ if ( timeReq.tr_node.io_Message.mn_ReplyPort != NULL ) AbortIO( (char *) &timeReq.tr_node ); /* if we want a quick exit then skip this stuff */ if ( why == QUICK_EXIT ) goto quick; /* just call the clean up routines */ if ( timerPort != NULL ) DeletePort( timerPort ); CloseNarrator( why ); if ( clockPort != NULL ) DeletePort( clockPort ); quick: if ( IntuitionBase != NULL ) CloseLibrary( IntuitionBase ); } /* end of clean(); */ /************************************************************************ * * bed_bye( how_much ) - This routine submits a timer event for us * * This code section was written by Robert E. Beaty and * are Copyright (C) 1987 by R.E.Beaty and The Man From S.P.U.D. * ************************************************************************/ void bed_bye( how_much ) int how_much; { /* See how long the sleep is for */ if ( how_much == LITTLE ) { timeReq.tr_time.tv_secs = 5; /* little is 5 sec. */ timeReq.tr_time.tv_micro = 0; } else { timeReq.tr_time.tv_secs = 885; /* big is 14 min 45 sec. */ timeReq.tr_time.tv_micro = 0; } /* ... and send it out to be done */ SendIO( (char *) &timeReq.tr_node ); } /* end of bed_bye(); */ /************************************************************************ * * speak_time( hrs, mins ) - This routine formats and speaks the time. * * This code section was written by Robert E. Beaty and * are Copyright (C) 1987 by R.E.Beaty and The Man From S.P.U.D. * ************************************************************************/ void speak_time( hrs, mins ) int hrs, mins; { /* * First, see if we need to prestart the speakers */ if ( prestart ) cp = stpcpy( alarm, "t,," ); else cp = alarm; /* * Build up the string to speak */ /* start with the salutation */ cp = stpcpy( cp, salutation ); /* ... add the time is stuff */ cp = stpcpy( cp, ", It is now " ); /* check for quarter till */ if ( (alarm_mode == QUARTER_HOUR) && (mins == 45) ) { cp = stpcpy( cp, "quarter till " ); /* check to see that it makes sense */ if ( (++hrs) == 13 ) hrs = 1; } /* * always add the hour */ switch( hrs ) { case 1 : cp = stpcpy( cp, "1 " ); break; case 2 : cp = stpcpy( cp, "2 " ); break; case 3 : cp = stpcpy( cp, "3 " ); break; case 4 : cp = stpcpy( cp, "4 " ); break; case 5 : cp = stpcpy( cp, "5 " ); break; case 6 : cp = stpcpy( cp, "6 " ); break; case 7 : cp = stpcpy( cp, "7 " ); break; case 8 : cp = stpcpy( cp, "8 " ); break; case 9 : cp = stpcpy( cp, "9 " ); break; case 10 : cp = stpcpy( cp, "ten " ); break; /* the number 11 sounds better spelled 'eelaven' */ case 11 : cp = stpcpy( cp, "eelaven " ); break; case 12 : cp = stpcpy( cp, "twelve " ); break; } /* end of decoding the hours */ /* * decode the different modes */ switch( alarm_mode ) { case QUARTER_HOUR : switch( mins ) { case 0 : cp = stpcpy( cp, "o'clock." ); break; case 15 : cp = stpcpy( cp, "fifteen." ); break; case 30 : cp = stpcpy( cp, "thirty." ); break; case 45 : cp = stpcpy( cp, "." ); break; /* if we aren't where we are supposed to be, NULL it out */ default : cp = NULL; break; } break; case HALF_HOUR : switch( mins ) { case 0 : cp = stpcpy( cp, "o'clock." ); break; case 30 : cp = stpcpy( cp, "thirty." ); break; /* if we aren't where we are supposed to be, NULL it out */ default : cp = NULL; break; } break; case HOUR : if ( mins == 0 ) cp = stpcpy( cp, "o'clock." ); else /* if we aren't where we are supposed to be, NULL it out */ cp = NULL; break; } /* end of alarm_mode selection */ /* * If the time section is not NULL, do the rest */ if ( cp != NULL ) { /* * ... add the "Good morning..." or "Good night..." */ if ( start_alarm != end_alarm ) { if ( alarm_time == start_alarm ) cp = stpcpy( cp, ",, Good Morning!" ); if ( alarm_time == end_alarm ) cp = stpcpy( cp, ",, Good Night." ); } /* end of special salutation */ /* * translate it and speak it */ rtnCode = Translate( alarm, strlen(alarm), outputString, 500 ); writeNarrator->sex = MALE; writeNarrator->pitch = DEFPITCH; writeNarrator->mode = ROBOTICF0; writeNarrator->volume = alarm_volume; writeNarrator->message.io_Data = (APTR)outputString; writeNarrator->message.io_Length = strlen( outputString ); DoIO( writeNarrator ); } /* end of finishing it up and speaking it */ } /* end of speak_time(); */ /************************************************************************ * * usage() - This routine helps the user. * * This code section was written by Robert E. Beaty and * are Copyright (C) 1987 by R.E.Beaty and The Man From S.P.U.D. * * minimal additions by H. Bret Young * ************************************************************************/ usage( how_much ) int how_much; { cprintf( "Usage:\n" ); cprintf( " run SPUDclock [-m greeting message] [-f] [-t] [-h] [-q] [-p] [-s ####] [-e ####] [-v ##]\n" ); if ( how_much == LITTLE ) return( FALSE ); cprintf( "Where:\n" ); cprintf( " -m greeting message - this will be spoken before the time\n" ); cprintf( " -f - this will cause the alarm to sound every quarter hour\n" ); cprintf( " -t - this will cause the alarm to sound every half hour\n" ); cprintf( " -h - this will cause the alarm to sound every hour\n" ); cprintf( " -p - this will make the alarm contain a 't' to start speakers\n" ); cprintf( " -s #### - this will set the starting time to this time (2400 hr.)\n" ); cprintf( " -e #### - this will set the ending time to this time (2400 hr.)\n" ); cprintf( " -v ## - this will set the alarm volume to this (>0 and <=64)\n" ); cprintf( " -q - this will remove all copies of SPUDclock from memory\n" ); cprintf( " -l - this will list the current SPUDclock settings\n"); cprintf( " -d - this will cause the parameters not specified on the\n"); cprintf( " command line to revert to their defaults\n"); return( FALSE ); } /* end of usage(); */ /************************************************************************ * * print_settings() - This routine prints the current SPUDclock settings * * This section was written by H. Bret Young * are Copyright (C) 1987 by H. Bret Young and The Man From S.P.U.D. * ************************************************************************/ void print_settings() { char out[5]; cprintf("SPUDclock settings \n\n"); cprintf(" The alarm will sound "); switch (alarm_mode) { case QUARTER_HOUR : cprintf("every QUARTER HOUR\n"); break; case HALF_HOUR : cprintf("every HALF HOUR\n"); break; case HOUR : cprintf("every HOUR\n"); break; } if (prestart) cprintf(" The speakers WILL be prestarted\n"); else cprintf(" The speakers WILL NOT be prestarted\n"); cprintf(" The clock will begin at "); itoa(out,start_alarm); cprintf(out); cprintf("\n"); cprintf(" The clock will stop at "); itoa(out,end_alarm); cprintf(out); cprintf("\n"); cprintf(" The alarm volume is "); itoa(out,alarm_volume); cprintf(out); cprintf("\n"); cprintf(" The alarm salutation is :\n"); cprintf(" "); cprintf(salutation); cprintf("\n"); } /************************************************************************ * * Main section of SPUDclock... * * This and all code sections were written by Robert E. Beaty and * H. Bret Young are Copyright (C) 1987 by H. Bret Young and R.E.Beaty * and The Man From S.P.U.D. * ************************************************************************/ main( argc, argv ) int argc; char *argv[]; { int i; int change_flags, changing, listing; /* * * Set the defaults * */ alarm_mode = HALF_HOUR; /* do it every 30 minutes */ prestart = FALSE; /* don't prestart the speakers */ start_alarm = 830; /* start at 8:30 am */ end_alarm = 2300; /* end at 11:00 pm */ alarm_volume = 50; /* not too loud */ stpcpy( salutation, " " ); /* no salutation to start off */ cp = salutation; /* this is for the argument processing */ quit_flag = FALSE; /* we aren't stopping yet */ change_flags = 0; changing = FALSE; listing = FALSE; /* * * Decode the arguments * */ for ( i=1; i < argc; i++ ) { /* check the options */ if ( argv[i][0] == '-' ) { /* decode the options */ switch( argv[i][1] ) { case 'f' : change_flags |= AM_BIT; alarm_mode = QUARTER_HOUR; break; case 't' : change_flags |= AM_BIT; alarm_mode = HALF_HOUR; break; case 'h' : change_flags |= AM_BIT; alarm_mode = HOUR; break; case 'q' : quit_flag = TRUE; break; case 'p' : change_flags |= PS_BIT; prestart = TRUE; break; case 's' : change_flags |= SA_BIT; i++; /* move to the next argument, the time */ start_alarm = 0; while((*argv[i] >= '0') && (*argv[i] <= '9')) start_alarm = (start_alarm * 10) + *argv[i]++ - '0'; break; case 'e' : change_flags |= EA_BIT; i++; /* move to the next argument, the time */ end_alarm = 0; while((*argv[i] >= '0') && (*argv[i] <= '9')) end_alarm = (end_alarm * 10) + *argv[i]++ - '0'; break; case 'v' : change_flags |= AV_BIT; i++; /* move to the next argument, the volume */ alarm_volume = 0; while((*argv[i] >= '0') && (*argv[i] <= '9')) alarm_volume = (alarm_volume * 10) + *argv[i]++ - '0'; break; case 'm' : change_flags |= S_BIT; /* read in the salutation a word at a time */ for ( i=i; (argv[i+1][0] != '-') && (i < argc); i++ ) { cp = stpcpy( cp, argv[i+1] ); cp = stpcpy( cp, " "); } break; case 'l' : listing = TRUE; break; case 'd' : changing = TRUE; break; default : usage( LITTLE ); /* show him the small usage */ exit( TRUE ); break; } /* end of decoding the options */ } /* end of checking the options */ else { usage( BIG ); /* he needs lots of help */ exit( TRUE ); } } /* end of decoding the arguments */ /* * * O.K. all arguments are decoded, so let's see if one copy of * SPUDclock already exists * */ /* Assume one does and do just a quick start */ if ( (error=init( QUICK_START )) != FALSE ) { if ( error == CANT_OPEN_INTUITION ) { cprintf( "Sorry, but I cannot open a copy of Intuition!\n" ); cprintf( "Please check your DEVS: directory or reboot.\n" ); } /* end of printing the error message */ exit( error ); } /* end of error checking for the initial start */ clockPort = (struct MsgPort *) FindPort( "SPUDclock" ); if ( clockPort != NULL ) { /* Allocate the memory for the message to the other SPUDclock */ outgoing = (struct PacketMessage *) AllocMem( sizeof(struct PacketMessage), MEMF_PUBLIC ); if ( outgoing == NULL ) { cprintf( "Sorry, There is not enough memory to send the message\n" ); cprintf( "to the running copy of SPUDclock. You will probably\n" ); cprintf( "have to re-boot the machine to change the running copy\n" ); cprintf( "of SPUDclock.\n" ); clean( QUICK_EXIT ); exit( TRUE ); } /* end of error checking the message allocation */ /* Allocate the reply port for this message */ replyPort = (struct MsgPort *) CreatePort( "SPUDclock.reply.port", TASK_PRIORITY ); if ( replyPort == NULL ) { cprintf( "Sorry, There are not enough free resources to send the\n" ); cprintf( "message to the running copy of SPUDclock. You will probably\n" ); cprintf( "have to re-boot the machine to change the running copy\n" ); cprintf( "of SPUDclock.\n" ); /* free everything up */ FreeMem( outgoing, sizeof(struct PacketMessage) ); clean( QUICK_EXIT ); exit( TRUE ); } /* end of error checking for port creation */ /* * Now set this message packet so that it will do the job */ outgoing->packet_message.mn_Node.ln_Type = NT_MESSAGE; outgoing->packet_message.mn_ReplyPort = replyPort; outgoing->packet_message.mn_Length = sizeof( struct PacketMessage ); /* Get the status from the packet */ outgoing->alarm_mode = alarm_mode; outgoing->prestart = prestart; outgoing->start_alarm = start_alarm; outgoing->end_alarm = end_alarm; outgoing->alarm_volume = alarm_volume; stpcpy( outgoing->salutation, salutation ); outgoing->quit_flag = quit_flag; outgoing->change_flags = change_flags; outgoing->changing = changing; outgoing->listing = listing; /* * Send it, wait for a reply, and then dispose of all of it */ PutMsg( clockPort, outgoing ); WaitPort( replyPort ); /* free everything up */ DeletePort( replyPort ); FreeMem( outgoing, sizeof(struct PacketMessage) ); clean( QUICK_EXIT ); exit( TRUE ); } /* end of passing arguments to the running SPUDclock */ /* Print a copyright notice */ cprintf( "SPUDclock v1.2 - Copyright 1987 by The Man From S.P.U.D.\n" ); if (listing) print_settings(); /* If quitting was our only motive, then quit */ if ( quit_flag ) { clean( QUICK_EXIT ); exit( FALSE ); } /* end of quick quit */ /* We need to do a normal start */ if ( (error=init( NORMAL_START )) != FALSE ) { /* decode the error */ switch ( error ) { case CANT_OPEN_INTUITION : cprintf( "Sorry, but I cannot open a copy of Intuition!\n" ); cprintf( "Please check your DEVS: directory or reboot.\n" ); break; case CANT_OPEN_TRANSLATOR : cprintf( "Sorry, but I cannot open a copy of the\n" ); cprintf( "Translator device! Please check your DEVS:\n" ); cprintf( "directory for the narrator.device file\n" ); cprintf( "and/or reboot.\n" ); break; case CANT_OPEN_NARRATOR : cprintf( "Sorry, but I cannot open a copy of the\n" ); cprintf( "Narrator device! Please check your DEVS:\n" ); cprintf( "directory for the narrator.device file\n" ); cprintf( "and/or reboot.\n" ); break; case CANT_OPEN_TIMER : cprintf( "Sorry, but I cannot open a copy of the\n" ); cprintf( "Timer device! Please check your DEVS:\n" ); cprintf( "directory and/or reboot.\n" ); break; case CREATE_PORT_PROBLEMS : cprintf( "Sorry, There are not enough free resources to open the\n" ); cprintf( "message ports required. You will probably have to re-boot\n" ); cprintf( "the machine to run SPUDclock.\n" ); break; case CREATE_IO_PROBLEMS : cprintf( "Sorry, There are not enough free resources to open the\n" ); cprintf( "I/O ports required. You will probably have to re-boot\n" ); cprintf( "the machine to run SPUDclock.\n" ); break; case TRANSLATOR_NOT_WORKING : cprintf( "Sorry, but the Translator device does not seem to be working\n" ); cprintf( "at this time. The only suggestion is to re-boot the machine\n" ); cprintf( "and/or get a fresh copy of narrator.device into DEVS:.\n" ); break; default : cprintf( "Sorry, but SPUDclock has returned an error.\n" ); cprintf( "Please try running it again.\n" ); break; } /* end of decoding the error and printing the error message */ exit( error ); } /* end of error checking the start-up of the original copy */ /* Submit a little sleep */ bed_bye( LITTLE ); while( TRUE ) { /* * Now wait until something wakes us up */ signal = Wait( timer_signal | port_signal ); /* * * ... check the timer * */ if ( signal & timer_signal ) { /* get the message out of the way */ (void) GetMsg( timerPort ); /* Get the time now */ DateStamp( &now ); /* Get the time into hours and minutes */ hours_24 = now.ds_Minute / 60; hours_12 = ( now.ds_Minute / 60 ) % 12; if ( hours_12 == 0 ) hours_12 = 12; /* make it simple 12 hour */ minutes = now.ds_Minute % 60; /* * See if we are synced up yet */ if ( (minutes == 0) || (minutes == 15) || (minutes == 30) || (minutes == 45) ) { /* submit a nice long wake up call */ bed_bye( BIG ); /* * Now see if we need to output this to the speakers */ alarm_time = hours_24 * 100 + minutes; if ( (alarm_time >= start_alarm) && (alarm_time <= end_alarm) ) speak_time( hours_12, minutes ); } /* end of processing for synced up */ else { /* submit another wake up call soon */ bed_bye( LITTLE ); } /* end of processing for not synced up */ } /* end of processing the timer signal */ /* * * ... check the clock port * */ if ( signal & port_signal ) { /* Get the message */ incoming = (struct PacketMessage *) GetMsg( clockPort ); /* Get the status from the packet */ changing = incoming->changing; change_flags = incoming->change_flags; listing = incoming->listing; quit_flag = incoming->quit_flag; switch (changing) { case FALSE : if (change_flags & AM_BIT) alarm_mode = incoming->alarm_mode; if (change_flags & PS_BIT) prestart = incoming->prestart; if (change_flags & SA_BIT) start_alarm = incoming->start_alarm; if (change_flags & EA_BIT) end_alarm = incoming->end_alarm; if (change_flags & AV_BIT) alarm_volume = incoming->alarm_volume; if (change_flags & S_BIT) stpcpy( salutation, incoming->salutation ); break; case TRUE : alarm_mode = incoming->alarm_mode; prestart = incoming->prestart; start_alarm = incoming->start_alarm; end_alarm = incoming->end_alarm; alarm_volume = incoming->alarm_volume; stpcpy( salutation, incoming->salutation ); break; } if (listing) print_settings(); /* since we didn't allocate this message, we must reply */ ReplyMsg( incoming ); /* * If the quit flag is set then we need to leave */ if ( quit_flag ) { clean( NORMAL_EXIT ); /* clean all this up */ exit( FALSE ); } /* end of quitting */ } /* end of processing the port signal */ } /* end of main loop */ /* we need this to keep the compiler happy */ return( FALSE ); } /* end of SPUDclock(); */