PROGRAM time(input,output); USES dos,crt,graph; TYPE options=(clock,alarm,set_time,exit); optrec=RECORD column:byte; option:string[10]; END; CONST nullchar=#0; bell=#7; {key scan codes} enter=#13; escape=#27; leftarrow=#75; rightarrow=#77; optchars='CASE'; opt:array[options] of optrec=((column:2;option:'Clock'), (column:15;option:'Alarm'), (column:30;option:'Settime'), (column:50;option:'Exit')); menuchars:set of char=['C','A','S','E',nullchar,enter]; cursorscancodes:set of char=[leftarrow,rightarrow]; VAR a,b,f,g,k,l,y,z,gd,gm,i,j,p,q,code,errorcode:integer; ha,ma,hs,ms,h,m,s,s1,hund:word; c,d,e,path:string; x:char; angle1,angle2,angle3,angle4:real; done,flag,error:boolean; currentselection:options; PROCEDURE help; {prints the help box} BEGIN window(15,9,65,16); gotoxy(1,1); writeln('For setting the alarm and time : '); write('This is a 24-hour clock.Therefore the valid entriesare from 0 to'); write(' 23 for hours and from 0 to 59 for minutes.If a wrong entry is '); writeln('made,there will be a beep and you can input the time again.'); writeln; write('The shortest hand on the clock dial indicates the time for which'); write(' the alarm is set.'); window(1,1,80,25); gotoxy(14,8); write('É'); gotoxy(14,17); write('È'); gotoxy(66,8); write('»'); gotoxy(66,17); write('¼'); for i:=1 to 8 do begin gotoxy(14,8+i); write('º'); gotoxy(66,8+i); write('º'); end; for i:=1 to 51 do begin gotoxy(14+i,8); write('Í'); gotoxy(14+i,17); write('Í'); end; END; PROCEDURE box(tp:options); {common procedure for the alarm and} BEGIN {time-setting modules} window(14,8,66,17); clrscr; window(1,1,80,25); gotoxy(20,8); write('Ú'); gotoxy(61,8); write('¿'); gotoxy(20,18); write('À'); gotoxy(61,18); write('Ù'); gotoxy(20,13); write('³'); gotoxy(61,13); write('³'); for k:= 1 to 2 do begin for i:=1 to 4 do begin gotoxy(20,i+8+(k-1)*5); write('³'); gotoxy(61,i+8+(k-1)*5); write('³'); for j:=1 to 40 do begin gotoxy(j+20,k*10-2); write('Ä'); gotoxy(j+20,i+8+(k-1)*5); write('²'); end; end; for a:= 1 to 10 do begin gotoxy(a+(k-1)*30+20,13); write('²'); end; end; CASE currentselection OF alarm: begin gotoxy(28,12); write('ALARM TO BE SET FOR(hh:mm):'); end; set_time:begin gotoxy(30,12); write('ENTER NEW TIME(hh:mm):'); end; clock:begin gotoxy(29,12); write('ENTER CORRECT BGI PATH:'); end; END; if currentselection<>clock then begin repeat flag:=false; gotoxy(31,13); x:=' '; c:=''; while (x<>enter) and (x<>escape) do begin x:=readkey; if x=#8 then begin if wherex>31 then begin c:=copy(c,1,length(c)-1); gotoxy(wherex-1,wherey); write(' '); gotoxy(wherex-1,wherey); end; end else begin if (x=':') or (x in ['0'..'9']) then begin if wherex<51 then begin write(x); c:=c+x; end; end; end; end; if x<>escape then begin i:=0; i:=pos(':',c); d:=copy(c,1,i-1); e:=copy(c,i+1,2); val(d,hs,code); val(e,ms,code); if (i=0) or (i=1) or (hs<0) or (hs>23) or (ms<0) or (ms>59) then begin write(bell); flag:=true; gotoxy(31,13); clreol; gotoxy(61,13); write('³'); for i:= 1 to 10 do begin gotoxy(50+i,13); write('²'); end; end; end; until flag=false; if currentselection=set_time then begin if x<>escape then settime(hs,ms,0,0); end else if x<> escape then begin ha:=hs; ma:=ms; hs:=(hs mod 12); ms:=ms+(hs*60); if hs<3 then angle4:=90-(ms*0.5) else angle4:=360-(ms-180)*0.5; angle4:=angle4*pi/180; end; end; END; PROCEDURE setalarm; {sets the alarm} BEGIN box(currentselection); END; PROCEDURE timeset; {sets the time} BEGIN box(currentselection); END; PROCEDURE ringalarm; {rings the alarm} BEGIN sound(450+i*5); if j mod 2 =0 then i:=i+1 else i:=i-1; j:=s; END; PROCEDURE hands; {places the hours,minutes and seconds} BEGIN {hands on the clock face and also erases} setviewport(0,0,639,479,clipon); {the previous hands} setcolor(0); line(289,239,a,b); line(289,239,f,g); line(289,239,k,l); setcolor(15); if s1<15 then angle1:=90-(s1*6) else angle1:=360-(s1-15)*6; s1:=m*60+s1; if m<15 then angle2:=90-(s1*0.1) else angle2:=360-((s1-900)*0.1); s1:=(h mod 12)*3600+s1; if h mod 12<3 then angle3:=90-(s1/120) else angle3:=360-((s1-10800)/120); angle1:=angle1*pi/180; angle2:=angle2*pi/180; angle3:=angle3*pi/180; a:=289+round(95*cos(angle1)); b:=239-round(95*sin(angle1)); f:=289+round(102*cos(angle2)); g:=239-round(102*sin(angle2)); k:=289+round(75*cos(angle3)); l:=239-round(75*sin(angle3)); setlinestyle(0,0,1); line(289,239,a,b); setlinestyle(0,0,3); line(289,239,f,g); line(289,239,k,l); END; PROCEDURE viewclock; {prints the clock as well as the} BEGIN {digital time on the screen;also} gd:=detect; {indicates the time for which the} if error=true then {alarm is set} initgraph(gd,gm,path) else initgraph(gd,gm,'C:\TURBO\bgi'); errorcode:=graphresult; while errorcode<>grok do begin write(bell); error:=true; clrscr; {obtains correct BGI path} box(currentselection); gotoxy(31,13); readln(path); gd:=detect; initgraph(gd,gm,path); errorcode:=graphresult; end; a:=(getmaxx div 2)-30; b:=getmaxy div 2; p:=a; q:=b; setpalette(0,blue); for i:=1 to 5 do circle(a,b,159+i); {draws the clock dial} circle(a,b,4); floodfill(a,b,15); settextstyle(triplexfont,horizdir,5); outtextxy(278,155,'V'); for i:=1 to 12 do begin case i of 4..12:angle1:=330-(i-4)*30; 1..3:angle1:=60-(i-1)*30; end; angle1:=angle1*pi/180; str(i,c); a:=round(130*cos(angle1)); b:=round(130*sin(angle1)); if i<10 then outtextxy(279+a,214-b,c) else {prints the numbers on the clock face} outtextxy(269+a,214-b,c); end; for i:=1 to 60 do begin angle1:=(i*6-6)*pi/180; a:=289+round(155*cos(angle1)); b:=239-round(155*sin(angle1)); putpixel(289+round(155*cos(358*pi/180)),249-round(155*sin(358*pi/180)),15); if (i mod 5)=1 then begin circle(a,b,2); floodfill(a,b,15); end else putpixel(a,b,15); end; i:=0; j:=0; settextstyle(sansseriffont,horizdir,2); outtextxy(410,360,'Alarm set for:'); outtextxy(50,440,'Press Esc key for menu : '); settextstyle(gothicfont,horizdir,5); while not keypressed do begin gettime(h,m,s,hund); {gets the time from DOS} if (h=ha) and (m=ma) then ringalarm else nosound; {checks time for alarm} s1:=s; hands; circle(p,q,4); floodfill(p,q,15); settextstyle(triplexfont,horizdir,5); outtextxy(278,155,'V'); settextstyle(sansseriffont,horizdir,2); str(ha,c); str(ma,d); if ma<10 then d:='0'+d; outtextxy(560,360,c+':'+d); settextstyle(gothicfont,horizdir,5); y:=289+round(60*cos(angle4)); z:=239-round(60*sin(angle4)); setlinestyle(0,0,1); line(289,239,y,z); setlinestyle(0,0,3); setviewport(0,0,639,50,clipon); str(h,c); str(m,d); str(s,e); if s<10 then e:='0'+e; if m<10 then d:='0'+d; if h<10 then c:='0'+c; c:=c+':'+d+':'+e; outtextxy(200,5,c); {outputs digital time} delay(2000); clearviewport; end; nosound; closegraph; END; PROCEDURE reversevideo(status:boolean); {determines colour combination} BEGIN {of output of menu-black on} if status then begin {white or white on black} textcolor(black); textbackground(white); end else begin textcolor(white); textbackground(black); end; END; PROCEDURE highlightselection; {highlights selected option-} BEGIN {makes it black on white instead} reversevideo(true); {of white on black} with opt[currentselection] do begin gotoxy(column,1); writeln(option); gotoxy(column,1); end; reversevideo(false); END; PROCEDURE initialisemenu; {prints the opening menu screen} VAR ch:options; BEGIN clrscr; reversevideo(false); for ch:= clock to exit do with opt[ch] do begin gotoxy(column,1); highvideo; write(copy(option,1,1)); lowvideo; writeln(copy(option,2,length(option)-1)); end; for i:= 1 to 80 do write('Ä'); currentselection:=clock; highlightselection; help; gotoxy(1,25); reversevideo(true); write(chr(26),' , ',chr(27),' or C , A , S , E : Highlight selection Enter:Select Esc:Cancel'); reversevideo(false); gotoxy(2,1); END; PROCEDURE getselection(VAR quit:boolean); {deals with the option} VAR {selection process} inchar:char; PROCEDURE removehighlight; {removes the highlight of the } BEGIN {previously selected option} with opt[currentselection] do begin gotoxy(column,1); highvideo; write(copy(option,1,1)); lowvideo; writeln(copy(option,2,length(option)-1)); end; END; PROCEDURE selectnextoption; {handles the process of choosing the } BEGIN {succeeeding option} removehighlight; if currentselection=exit then currentselection:=clock else currentselection:=succ(currentselection); highlightselection; END; PROCEDURE selectpreviousoption; {handles the process of choosing the } BEGIN {preceding option} removehighlight; if currentselection=clock then currentselection:=exit else currentselection:=pred(currentselection); highlightselection; END; BEGIN {main block of getselection procedure-reads the choice} quit:=false; {input by user and takes corresponding action} repeat inchar:=upcase(readkey); if (not(inchar in menuchars)) and (inchar<>escape) then write(bell); {checks for wrong input} until (inchar in menuchars); CASE inchar OF 'C','A','S','E':begin removehighlight; currentselection:=options(pos(inchar,optchars)-1); highlightselection; end; nullchar:begin {waits for input} inchar:=readkey; if inchar in cursorscancodes then case inchar of leftarrow:selectpreviousoption; rightarrow:selectnextoption; end else write(bell); end; enter:begin {takes action after selection is made} if currentselection=exit then quit:=true else begin case currentselection of clock:viewclock; alarm:setalarm; set_time:timeset; end; clrscr; initialisemenu; end; end; END; END; BEGIN {main block of program} ha:=15; ma:=0; angle4:=0; error:=false; initialisemenu; repeat {checks for exiting condition} getselection(done); until done; clrscr; END.