'=========================================================================== ' Subject: ANALOG/DIGITAL CLOCK DISPLAY Date: 04-01-97 (12:00) ' Author: Gary N. Wilkerson, Jr. Code: QB, QBasic, PDS ' Origin: comp.lang.basic.misc Packet: DATETIME.ABC '=========================================================================== ' Analog/Digital Clock ' by Gary N. Wilkerson Jr. ' Constants CONST ClockH = 130 CONST ClockV = 120 CONST Left = 1 CONST Right = 3 CONST TRUE = -1 CONST FALSE = NOT TRUE CONST TwoPI# = 2 * 3.141592654# ' Sub and Function modules DECLARE SUB OnOff (cond) DECLARE SUB Box (cond) DECLARE SUB Center (row, text$) DECLARE SUB KeyPause () DECLARE SUB FuncKeyOn () DECLARE SUB FuncKeyOff () DECLARE SUB RunClock () DECLARE SUB DrawScreen () DECLARE SUB ClockBells () DECLARE SUB TimeDate (row) DECLARE SUB GetCurrTime (Hour, Min, Sec, a$) DECLARE SUB ScreenSaver () DECLARE SUB DisplayAlarmStatus () DECLARE SUB DisplayChimeStatus () DECLARE SUB DisplayClockStatus () DECLARE FUNCTION Hplot (Length, ClockPos) DECLARE FUNCTION Vplot (Length, ClockPos) ' Converts clock face position into Radiens DEF FnRad (x) = -(x - 30) * TwoPI# / 60 ' Set up the Function Key traps KEY OFF ON KEY(1) GOSUB SetTime ON KEY(2) GOSUB SetDate ON KEY(3) GOSUB SetAlarm ON KEY(4) GOSUB ToggleAlarm ON KEY(5) GOSUB ToggleChime ON KEY(6) GOSUB Switch12or24 ' Global variables DIM SHARED Military, Chime, Alarm, Alarm$, AlarmOn, ScreenSave Military = FALSE: Chime = TRUE: Alarm = FALSE: Alarm$ = "12:00:00" AlarmOn = FALSE: ScreenSave = FALSE ' The main routine DrawScreen FuncKeyOn RunClock SYSTEM ' Function Key traps SetTime: FuncKeyOff RESTORE TimeSet Box Left LOCATE 13, 26 LINE INPUT a$ ' Get new time a$ = LTRIM$(a$): a$ = RTRIM$(a$) ' Remove excess spaces IF a$ <> "" THEN ON ERROR GOTO TimeError TIME$ = a$ ' Reset system time ON ERROR GOTO 0 END IF DrawScreen FuncKeyOn RETURN TimeSet: DATA Enter new time,"In 24 hour [##:##:##] format"," ",ZZ TimeError: Center 19, " Invalid Time " KeyPause RESUME NEXT SetDate: FuncKeyOff RESTORE DateSet Box Left LOCATE 13, 30 LINE INPUT a$ a$ = LTRIM$(a$): a$ = RTRIM$(a$) IF a$ <> "" THEN ON ERROR GOTO DateError DATE$ = a$ ' Reset System Date ON ERROR GOTO 0 END IF DrawScreen FuncKeyOn RETURN DateSet: DATA Enter new date,"In ##-##-#### format"," ",ZZ DateError: Center 19, " Invalid Date " KeyPause RESUME NEXT SetAlarm: FuncKeyOff RESTORE AlarmSet Box Left LOCATE 13, 26 LINE INPUT a$ a$ = LTRIM$(a$): a$ = RTRIM$(a$) IF a$ <> "" THEN ' Sets the alarm ON ERROR GOTO AlarmError b$ = TIME$ Alarm$ = a$ TIME$ = a$ TIME$ = b$ ON ERROR GOTO 0 END IF ' Set alarm to system format a$ = TIME$ TIME$ = Alarm$ Alarm$ = TIME$ TIME$ = a$ DrawScreen FuncKeyOn RETURN AlarmSet: DATA Enter time for alarm,"In 24 hour [##:##:##] format"," ",ZZ AlarmError: Center 20, " Invalid Time " KeyPause Alarm$ = "12:00:00" RESUME NEXT ToggleAlarm: IF AlarmOn THEN AlarmOn = FALSE: RETURN ' If alarm is active, shut it off Alarm = NOT Alarm IF NOT ScreenSave THEN DisplayAlarmStatus RETURN ToggleChime: Chime = NOT Chime IF NOT ScreenSave THEN DisplayChimeStatus RETURN Switch12or24: Military = NOT Military IF NOT ScreenSave THEN DisplayClockStatus RETURN ClockMenu: DATA [F1] -- Sets Time,[F2] -- Sets Date,[F3] -- Sets Alarm DATA [F4] -- Toggles Alarm,[F5] -- Toggles Chime,[F6] -- Switch 12/24 hour ' Box ' Draws a box around the DATA for the READ statements until it reaches ZZ SUB Box (cond) DIM temp$(5) u = 0 ' Variable will equal length of longest string in BOX ' Variable will equal the number of strings in BOX FOR t = 0 TO 15 READ temp$(t) IF temp$(t) = "ZZ" THEN EXIT FOR IF LEN(temp$(t)) > u THEN u = LEN(temp$(t)) NEXT t: IF t = 0 THEN EXIT SUB y = 39 - u / 2: LOCATE 11 - t / 2, y ' Center the BOX on screen COLOR 14, 0 PRINT "É"; STRING$(u, 205); "»" ' Top border of BOX FOR x = 0 TO t - 1 a = cond ' Set variable to current condition LOCATE CSRLIN, y COLOR 14, 0 IF temp$(x) = "Í" THEN PRINT "Ì"; STRING$(u, 205); "¹" ' BOX concecrator ELSE PRINT "º"; SPACE$(u); "º"; ' BOX side borders ' First character of string may override condition SELECT CASE LEFT$(temp$(x), 1) CASE "®" a = Left: temp$(x) = MID$(temp$(x), 2) CASE "" a = 2: temp$(x) = MID$(temp$(x), 2) CASE "¯" a = Right: temp$(x) = MID$(temp$(x), 2) END SELECT ' Justify according to condition SELECT CASE a CASE Left ' Left justify LOCATE CSRLIN, y + 1 CASE 2 ' Center LOCATE CSRLIN, 40 - LEN(temp$(x)) / 2 CASE Right ' Right justify LOCATE CSRLIN, y + u + 1 - LEN(temp$(x)) END SELECT COLOR 15, 0 PRINT temp$(x); LOCATE CSRLIN + 1, y END IF NEXT x COLOR 14, 0 PRINT "È"; STRING$(u, 205); "¼" ' BOX bottom border COLOR 15, 0 END SUB ' Center ' Centers the text$ at a given row SUB Center (row, text$) LOCATE row, 40 - LEN(text$) / 2 PRINT text$ END SUB 'ClockBells ' Sounds the Alarm and Chime at the correct time SUB ClockBells ' Hourly Chime IF Chime THEN IF RIGHT$(TIME$, 5) = "00:00" THEN PLAY "MBo3L8ED+ED+Eo2Bo3DCL2o2A" END IF END IF IF Alarm THEN IF TIME$ = Alarm$ THEN AlarmOn = 16 ' Clock's Alarm IF AlarmOn THEN AlarmOn = AlarmOn - 1 PLAY "MBo4L16BBBB" END IF END SUB SUB DisplayAlarmStatus COLOR 14 LOCATE 14, 40: PRINT "Alarm"; : OnOff Alarm END SUB SUB DisplayChimeStatus COLOR 11 LOCATE 11, 40: IF Chime THEN PRINT "{Hourly Chime}" ELSE PRINT SPACE$(14) END SUB SUB DisplayClockStatus COLOR 9 LOCATE 16, 40: PRINT "Time reads at "; IF Military THEN PRINT "24"; ELSE PRINT ; "12"; PRINT " hour mode" END SUB ' DrawScreen ' Draws the screen with the clock on it SUB DrawScreen 'Initialize Screen IF ScreenSave THEN CLS : EXIT SUB SCREEN 9 COLOR 15, 0 CLS ' Draw Border PRINT "É"; STRING$(78, 205); "»" FOR Count = 1 TO 22 PRINT "º"; TAB(80); "º"; NEXT Count PRINT "È"; STRING$(78, 205); "¼"; 'Draw clock face CIRCLE (130, 120), 110, 15, , , .87 CIRCLE STEP(0, 0), 115, 15, , , .87 FOR Count = 0 TO 59 LINE (Hplot(105, Count), Vplot(90, Count))-(Hplot(110, Count), Vplot(95, Count)), 15 IF Count MOD 5 = 0 THEN LINE -(Hplot(100, Count), Vplot(85, Count)), 11 END IF NEXT Count COLOR 4 RESTORE ClockMenu FOR Count = 4 TO 9 LOCATE Count, 40 READ a$: PRINT a$ NEXT Count DisplayChimeStatus COLOR 14 LOCATE 13, 40: PRINT "Alarm Set At "; Alarm$ DisplayAlarmStatus DisplayClockStatus COLOR 13 Center 20, "Analog / Digital Clock" Center 21, "1994 by Gary N. Wilkerson Jr." Center 22, "Press [ESC] to quit" END SUB ' FuncKeyOff ' Turns all the Function Key traps OFF SUB FuncKeyOff FOR Count = 1 TO 6 KEY(Count) OFF NEXT Count END SUB 'FuncKeyOn ' Turns all Function Key traps ON SUB FuncKeyOn FOR Count = 1 TO 6 KEY(Count) ON NEXT Count END SUB ' GetCurrTime ' Gets the current TIME from the system TIME SUB GetCurrTime (Hour, Min, Sec, a$) a$ = TIME$ Min = VAL(MID$(a$, 4, 2)): Sec = VAL(RIGHT$(a$, 2)) Hour = (VAL(LEFT$(a$, 2)) MOD 12) * 5 + (Min / 12) END SUB ' Hplot ' Converts the hand length and clock face position ' into an X coordinate FUNCTION Hplot (Length, ClockPos) Hplot = Length * SIN(FnRad(ClockPos)) + ClockH END FUNCTION ' KeyPause ' Suspends program activity until key is pressed SUB KeyPause Center CSRLIN, " -->Press any key to continue<-- " WHILE INKEY$ <> "": WEND ' Clear keyboard SLEEP END SUB ' OnOff ' PRINTs ON if cond is TRUE, OFF is cond is FALSE SUB OnOff (cond) PRINT " -- "; IF cond THEN PRINT " [ON]" ELSE PRINT "[OFF]" END IF END SUB ' This is the main routine for the ' graphics style analog / digital clock SUB RunClock DO UNTIL INKEY$ = CHR$(27) GetCurrTime Hour, Min, Sec, a$ ' Second Hand LINE (Hplot(90, Sec), Vplot(75, Sec))-(ClockH, ClockV), 4 ' Minute Hand LINE -(Hplot(80, Min), Vplot(65, Min)), 14 ' Hour Hand LINE (ClockH, ClockV)-(Hplot(50, Hour), Vplot(35, Hour)), 3 TimeDate 18 ClockBells ' At a 5 minute interval, activate ScreenSaver IF Min MOD 5 = 0 AND Sec = 0 THEN ScreenSaver ' Pause for a second to pass WHILE a$ = TIME$: WEND ' Erase the hands LINE (Hplot(90, Sec), Vplot(75, Sec))-(ClockH, ClockV), 0 LINE -(Hplot(80, Min), Vplot(65, Min)), 0 LINE (ClockH, ClockV)-(Hplot(50, Hour), Vplot(35, Hour)), 0 LOOP END SUB ' ScreenSaver ' Deletes the graphics clock and display a small ' moving text clock to save the screen SUB ScreenSaver ScreenSave = TRUE RowPos = 1 'Beginning clock position SCREEN 0: COLOR 15, 0: CLS DO UNTIL INKEY$ = " " GetCurrTime Hour, Min, Sec, a$ ' At every 2 minute interval, move the text clock IF Min MOD 2 = 0 AND Sec = 0 THEN RowPos = (RowPos + 4) MOD 16: CLS Center RowPos, "Clock has been erased to preserve screen" Center RowPos + 1, "Press to restore clock" TimeDate RowPos + 3 ClockBells WHILE a$ = TIME$: WEND LOOP ScreenSave = FALSE DrawScreen END SUB ' TimeDate ' Writes the digital Date and Time for the regular and Screen Saver screens SUB TimeDate (row) COLOR 15 ' Display the system date LOCATE row, 10: PRINT DATE$; ' Get and display the system time according to display mode a$ = TIME$ LOCATE row, 60 IF Military THEN ' 24 hour display mode PRINT a$ ELSE ' 12 hour display mode y = VAL(LEFT$(a$, 2)) ' Let's determine the hour IF y >= 12 THEN ' The hour is noon or later b$ = " pm" IF y > 12 THEN y = y - 12 ELSE ' Hour is morning b$ = " am" IF y = 0 THEN y = 12 'Burning the midnight oil! END IF PRINT STR$(y); RIGHT$(a$, 6); b$; END IF END SUB ' Vplot ' Converts the hand length and clock face ' position into a Y coordinate FUNCTION Vplot (Length, ClockPos) Vplot = Length * COS(FnRad(ClockPos)) + ClockV END FUNCTION