' ************************************************************************* ' Program Title: Clock ' Copyright: Virtual Simulations 1995 ' Author: AA v Zoelen ' Last Modified: 21-02-1996 ' Version: 1.1 ' ************************************************************************* ' Description: Just a little clock demo ' ************************************************************************* ' Notes: Public Domain. For personal use only. ' ************************************************************************* ' History: First issue 08-02-1996 ' Rev. 1.1 21-02-1996 Alarm, Commandline switches, ' sound and two circles added. ' ************************************************************************* $CPU 8086 ' program works on any CPU $OPTIMIZE SPEED ' make fastest possible executable $COMPILE EXE ' compile to an EXE $DEBUG MAP OFF ' turn off map file generation $DEBUG PBDEBUG OFF ' don't include pbdebug support in our executable $LIB COM OFF ' turn off PowerBASIC's communications library. $LIB CGA OFF ' turn off PowerBASIC's CGA graphics library. $LIB EGA OFF ' turn off PowerBASIC's EGA graphics library. $LIB VGA ON ' turn off PowerBASIC's VGA graphics library. $LIB HERC OFF ' turn off PowerBASIC's hercules graphics library. $LIB LPT OFF ' turn off PowerBASIC's printer support library. $LIB IPRINT OFF ' turn off PowerBASIC's interpreted print library. $LIB FULLFLOAT OFF ' turn off PowerBASIC's floating point support. $ERROR BOUNDS ON ' turn off bounds checking $ERROR NUMERIC ON ' turn off numeric checking $ERROR OVERFLOW ON ' turn off overflow checking $ERROR STACK ON ' turn off stack checking $FLOAT PROCEDURE ' use procedural floating point to optimize for ' machines without a co-processor $COM 0 ' set communications buffer to nothing $STRING 2 ' set largest string size at 1024-18 CHAR. $STACK 2048 ' let's use a 2k stack $SOUND 1 ' smallest music buffer possible $DIM ARRAY ' force arrays to be pre-dimensioned before they ' can be used $DYNAMIC ' all arrays will be dynamic by default $OPTION CNTLBREAK OFF ' don't allow Ctrl-Break to exit program ' ************************************************************************* DIM X AS INTEGER DIM Y AS INTEGER DIM Radian AS SINGLE DIM Radius AS BYTE DIM Count AS BYTE DIM Seconds AS BYTE DIM Minutes AS BYTE DIM Hours AS BYTE DIM ColErase AS BYTE DIM ColPlate AS BYTE DIM ColBox AS BYTE DIM ColSec AS BYTE DIM ColMin AS BYTE DIM ColHour AS BYTE DIM PlateDotsX(62) AS SINGLE DIM PlateDotsY(62) AS SINGLE DIM Digital AS STRING * 1 DIM CMDLine AS STRING * 20 DIM Alarm AS STRING * 5 CMDLine = COMMAND$ ' Screen 12 will be activated further on. ' Screen 12 have a size of 640 x 480 so the ' values for X, Y and Radius should stay ' between these limits. You only need to ' change this few values below for adjusting ' the whole clock. X = 100 ' X - Center location of the clock Y = 50 ' Y - Center location of the clock Radius = 75 ' The size of the clock ColErase = 1 ' Color for erase ColPlate = 9 ' Color for the plate of the clock ColBox = 1 ' The color of the box around the clock ColSec = 15 ' Color of the seconds hand ColMin = 4 ' Color of the minutes hand ColHour = 12 ' Color of the hours hand Digital = "Y" ' Place also a digital clock on the screen if ' the clock's radius is larger then 75. ' If there is a radius value on the commandline then ' use that one instead. Count = 0 IF CMDLine <> "" THEN CMDLine = UCASE$(CMDLine) Count = INSTR(CMDLine, "/A") IF Count <> 0 THEN Alarm = MID$(CMDLine, Count + 2, 5) Count = INSTR(CMDLine, "/S") IF Count <> 0 THEN Radius = VAL(MID$(CMDLine, Count + 2, 3)) IF INSTR(CMDLine, "/ND") THEN Digital = "N" IF INSTR(CMDLine, "?") THEN CLS PRINT "CLOCK for DOS v1.0" PRINT PRINT "Auteur : AA v Zoelen" PRINT "Date : 21 Feb. 1996 PRINT "Copyright Virtual Simulations 1996" PRINT PRINT "USAGE :" PRINT "CLOCK [/sSIZE] [/aALARM] [nd] PRINT " Size in pixels" PRINT " Alarm in HH:MM format PRINT" /nd Don't activate the digital clock when PRINT " the size is larger then 75 PRINT PRINT "EXAMPLE : CLOCK s120 a11:50 nd PRINT END END IF END IF SCREEN 12 Radius = MAX(Radius, 13) ' The radius can't be smaller then 10 X = MAX(X, Radius) ' Let the clock not go beyond the X<0 and Y<0 Y = MAX(Y, Radius) ' The other sides is your responsibility. :-) DECR Radius, 3 ' Make the clock fit into the box. GOSUB Plate ' Setup and draw the plate of the clock ' Loop until a key is presses DO IF Seconds <> VAL(RIGHT$(TIME$, 2)) THEN GOSUB UpdateHands IF LEFT$(Time$, 5) = Alarm THEN SOUND (Seconds + 1) * 100, 0.1 LOOP UNTIL INKEY$ <> "" END ' ************************************************************************* ' SUB ROUTINES ' ' Update this hands of the clock every second. ' Redraw all the hands just incase there was a pass ' over it by the seconds hand. UpdateHands: IF Radius > 72 AND UCASE$(Digital) = "Y" THEN ' Replace damaged text. LOCATE INT(Y/12) , INT(X/8) - 2 ' Place also the digital time PRINT TIME$ ' on screen, but only if the END IF ' clock is large enough. ' Erase all hands first LINE (X, Y) - (X + PlateDotsX(Seconds + 1), Y + PlateDotsY(Seconds + 1)), ColErase LINE (X, Y) - (X + PlateDotsX(Minutes), Y + PlateDotsY(Minutes)), ColErase LINE (X, Y) - (X + (PlateDotsX(Hours)/1.2), Y + (PlateDotsY(Hours)/1.2)), ColErase CIRCLE (X + (PlateDotsX(Seconds + 1)/1.2), Y + (PlateDotsY(Seconds + 1)/1.2)), Dot * 3, ColErase ' Update the Minute hand Minutes = 1 + VAL(MID$(TIME$,4, 2)) LINE (X, Y) - (X + PlateDotsX(Minutes), Y + PlateDotsY(Minutes)), ColMin locate 1,1 ' If the minute hand point at a half hour the give a signal. IF Minutes = 31 AND Seconds = 59 THEN SOUND 400, 2 SOUND 250, 3 END IF ' Update the Hours hand Hours = VAL(LEFT$(TIME$, 2)) IF Hours => 12 THEN DECR Hours, 12 ' Adjust from a 24h to a 12h clock Hours = (Hours * 5) + 1 + INT(Minutes/12) LINE (X, Y) - (X + (PlateDotsX(Hours)/1.2), Y + (PlateDotsY(Hours)/1.2)), ColHour ' If it is a full hour then signal the right time. IF Seconds = 59 AND Minutes = 1 THEN FOR Count = 1 TO (Hours / 5) SOUND 250, 1 SOUND 450, 0.5 DELAY 1 ' Still keep on moving the seconds hand LINE (X, Y) - (X + PlateDotsX(Seconds + 1), Y + PlateDotsY(Seconds + 1)), ColErase CIRCLE (X + (PlateDotsX(Seconds + 1)/1.2), Y + (PlateDotsY(Seconds + 1)/1.2)), Dot * 3, ColErase GOSUB MoveSec NEXT END IF ' Do seconds at the last moment to get the most actual time. SOUND 200, 0.05 GOSUB MoveSec RETURN ' ************************************************************************* Plate: ' Start at 30 to get the clock in the right position ' Translate degrees to radians and at the and swap ' the order of the coordinates otherwise the clock ' is running backwards. LINE (X - (Radius + 3), Y - (Radius + 3)) - (X + Radius + 3, Y + Radius + 3), ColBox, bf LINE (X - (Radius + 3), Y - (Radius + 3)) - (X + Radius + 3, Y + Radius + 3), ColPlate, b FOR Count = 30 TO 91 Radian = Count * 6 * (3.14159 / 180) PlateDotsX(91 - Count) = SIN(Radian) * Radius PlateDotsY(91 - Count) = COS(Radian) * Radius IF Count / 5 = INT( Count / 5 ) THEN ' Place every 5 min. a dot. Dot = MIN(Radius / 10, 2) ' and also for every minute. IF Radius < 32 THEN Dot = 1 ELSE Dot = 1 IF Radius < 32 THEN Dot = 0 ' But if the clock is to small END IF ' then forget the minute dots. ' Place the minute dots and if the 5 minute dots are ' larger then 1 then also fill the 5 minute dots IF Dot <> 0 THEN CIRCLE (X + PlateDotsX(91 - Count), Y + PlateDotsY(91 - Count)), Dot, ColPlate IF Dot > 1 THEN PAINT (X + PlateDotsX(91 - Count), Y + PlateDotsY(91 - Count)), ColPlate NEXT ' Get the time to start with Minutes = VAL(MID$(TIME$, 4, 2)) ' Get the minutes Hours = VAL(LEFT$(TIME$, 2)) ' Get the Hours IF Hours => 12 THEN DECR Hours, 12 ' Adjust from 24h to a 12h clock. Hours = (Hours * 5) + 1 + INT(Minutes/12) END IF Seconds = VAL(RIGHT$(TIME$, 2)) ' Get the seconds RETURN ' ************************************************************************* ' Move the seconds hand to its next position MoveSec: IF Radius > 40 THEN CIRCLE (X, Y), 3, ColSec Seconds = VAL(RIGHT$(TIME$, 2)) LINE (X, Y) - (X + PlateDotsX(Seconds + 1), Y + PlateDotsY(Seconds + 1)), ColSec CIRCLE (X + (PlateDotsX(Seconds + 1)/1.2), Y + (PlateDotsY(Seconds + 1)/1.2)), Dot * 3, ColSec RETURN