I used the non optimised leap year function a few years ago for a calendar.
Code: Select all
'CALENDAR
#include "fbgfx.bi"
Dim Shared As Integer xres,yres
Screen 19,32,1,FB.GFX_ALPHA_PRIMITIVES
Screeninfo xres,yres
Windowtitle "FreeBASIC CALENDAR"
#macro incircle(cx,cy,radius,x,y)
(cx-x)*(cx-x) +(cy-y)*(cy-y)<= radius*radius
#endmacro
Type box
As String text
As Ulong colour
As long value,tx,ty,bx,by
End Type
Type Calendar_Month
Number As long
Month_name As String
End Type
declare sub digits(t As String,x As long,y As long,clr As Ulong,sz As long,img As Any Pointer=0)
Declare Function IsLeapYear(N As long) As long
Declare Sub PrintCalendar (_year As long, _month As long)
Declare Sub ComputeMonth (_year As long, _month As long, Byref StartDay As long, Byref TotalDays As long)
declare sub inspect(mx as long,my as long,mw as long)
Dim Shared MonthData(1 To 12) As Calendar_Month
Declare Sub initdata
Declare Sub initmonth
Declare Sub inityear
Declare Sub initdigits
Declare Sub dropmonth
Declare Sub dropyear
Declare Sub dropdigit1
Declare Sub dropdigit2
Declare Sub monthheader()
Declare Sub yearheader
Declare Function inbox(colour As Ulong,x As long,y As long) As long
Declare Sub paintscreen
Declare Sub mouseloop()
Declare Sub checkevents(mx As long,my As long)
Declare Function allflags() As long
Declare Function checktext() As long
Dim Shared As Single m1,m2,y1,y2,BOXWIDTH,d11,d12,d21,d22,digitboxwidth
Dim Shared As long monthflag,yearflag,digit1flag,digit2flag,printflag,endflag,nowflag
Dim Shared As fb.event e
Dim Shared As long _month,_year
Dim Shared As String monthtext,yeartext,digit1text,digit2text,mday,_yr,mn,verse
boxwidth=.07
m1=.1:m2=m1+.07'.2
y1=m2:y2=y1+.07
digitboxwidth=.04
d11=y2:d12=y2+digitboxwidth
d21=d12:d22=d21+digitboxwidth
Dim Shared As box mon(1 To 13),montxt(1 To 13)
Dim Shared As box yr(1 To 4),yrtxt(1 To 4)
Dim Shared As box digit1(9),digit1txt(9)
Dim Shared As box digit2(9),digit2txt(9)
Dim Shared As Ulong offwhite=Rgb(250,251,252)
'_ MAIN ___________
initdata
initmonth
inityear
initdigits
mouseloop
'___________________
'PROCEDURES __________________
Sub initdata
Restore dat2
For I As long = 1 To 12
Read MonthData(I).Month_name, MonthData(I).Number
Next
End Sub
Sub initmonth
Dim s As String
Dim count As long
Restore dat1
For x As long=1 To 13
Read s
mon(x).text=s
mon(x).value=x-1
mon(x).colour=Rgb(0,200,x)
montxt(x).colour=Rgb(255,255,200+x)
Next x
mon(1).colour=Rgb(200,200,1)
Restore
End Sub
Sub inityear
yr(1).text="Year"
yr(2).text="18"
yr(3).text="19"
yr(4).text="20"
For x As long=1 To 4
yr(x).colour=Rgb(200,0,x)
yrtxt(x).colour=Rgb(254,254,200+x)
Next x
yr(1).colour=Rgb(0,0,200)
End Sub
Sub initdigits
For x As long=0 To 9
digit1(x).text=Str(x)
digit2(x).text=Str(x)
digit1(x).colour=Rgb(101,101,101+x)
digit2(x).colour=Rgb(102,102,102+x)
digit1txt(x).colour=Rgb(253,253,200+x)
digit2txt(x).colour=Rgb(252,252,200+x)
Next x
End Sub
Sub dropmonth
Dim k As long:Dim sz As long=30
For x As long=1 To 13
Line(m1*xres,.1*yres+k)-(m2*xres,.1*yres+sz+k),mon(x).colour,BF
Line(m1*xres,.1*yres+k)-(m2*xres,.1*yres+sz+k),Rgb(0,0,0),B
mon(x).tx=m1*xres:mon(x).ty=.1*yres+k
mon(x).bx=m2*xres:mon(x).by=.1*yres+sz+k
Draw String((m1+.01)*xres,.11*yres+k),mon(x).text,montxt(x).colour
k=k+sz
Next x
End Sub
Sub dropyear
Dim k As long:Dim sz As long=30
For x As long=1 To 4
Line(y1*xres,.1*yres+k)-(y2*xres,.1*yres+sz+k),yr(x).colour,BF
Line(y1*xres,.1*yres+k)-(y2*xres,.1*yres+sz+k),Rgb(0,0,0),B
yr(x).tx=y1*xres:yr(x).ty=.1*yres+k
yr(x).bx=y2*xres:yr(x).by=.1*yres+sz+k
Draw String((y1+.01)*xres,.11*yres+k),yr(x).text,yrtxt(x).colour
k=k+sz
Next x
End Sub
Sub dropdigit1
Dim k As long:Dim sz As long=30
For x As long=0 To 9
Line(d11*xres,.1*yres+k)-(d12*xres,.1*yres+sz+k),digit1(x).colour,BF
Line(d11*xres,.1*yres+k)-(d12*xres,.1*yres+sz+k),Rgb(0,0,0),B
digit1(x).tx=d11*xres:digit1(x).ty=.1*yres+k
digit1(x).bx=d12*xres:digit1(x).by=.1*yres+sz+k
Draw String((d11+.01)*xres,.11*yres+k),digit1(x).text,digit1txt(x).colour
k=k+sz
Next x
End Sub
Sub dropdigit2
Dim k As long:Dim sz As long=30
For x As long=0 To 9
Line(d21*xres,.1*yres+k)-(d22*xres,.1*yres+sz+k),digit2(x).colour,BF
Line(d21*xres,.1*yres+k)-(d22*xres,.1*yres+sz+k),Rgb(0,0,0),B
digit2(x).tx=d21*xres:digit2(x).ty=.1*yres+k
digit2(x).bx=d22*xres:digit2(x).by=.1*yres+sz+k
Draw String((d21+.01)*xres,.11*yres+k),digit2(x).text,digit2txt(x).colour
k=k+sz
Next x
End Sub
Sub monthheader()
Dim k As long
Dim sz As long=30
Dim count As long=1
Line(m1*xres,.1*yres+k)-(m2*xres,.1*yres+sz+k),mon(1).colour,BF
Line(m1*xres,.1*yres+k)-(m2*xres,.1*yres+sz+k),Rgb(0,0,0),B
Draw String((m1+.01)*xres,.11*yres+k),mon(1).text,montxt(1).colour
End Sub
Sub yearheader
Dim k As long
Dim sz As long=30
Dim count As long
Line(y1*xres,.1*yres+k)-(y2*xres,.1*yres+sz+k),yr(1).colour,BF
Line(y1*xres,.1*yres+k)-(y2*xres,.1*yres+sz+k),Rgb(0,0,0),B
Draw String((y1+.01)*xres,.11*yres+k),yr(1).text,yrtxt(1).colour
End Sub
Function inbox(colour As Ulong,x As long,y As long) As long
If Point(x,y)=colour Then
Return -1
Else
Return 0
Endif
End Function
Sub paintscreen
Line(.1*xres,.1*yres)-(.9*xres,.9*yres),Rgb(2,2,2),B
Paint (0,0),Rgb(236,233,216),Rgb(2,2,2)
Paint(xres/2,yres/2),Rgb(255,255,255),Rgb(2,2,2)
Line(.4*xres,.2*yres)-(.89*xres,.7*yres),Rgb(0,0,0),BF 'black box
For k As long=-3 To 3 'blue frame
Line(.4*xres+k,.2*yres-k)-(.89*xres-k,.7*yres+k),Rgb(0,150+30*k,236),B
Next k
End Sub
Sub checkevents(mx As long,my As long)
'highlight month
For x As long = 2 To 13
If inbox(mon(x).colour,mx,my) Or inbox(montxt(x).colour,mx,my) Then
line(mon(x).tx,mon(x).ty)-(mon(x).bx,mon(x).by),rgb(255,255,255),b
end if
next x
'highlight year
For x As long = 2 To 4
If inbox(yr(x).colour,mx,my) Or inbox(yrtxt(x).colour,mx,my)Then
line(yr(x).tx,yr(x).ty)-(yr(x).bx,yr(x).by),rgb(255,255,255),b
end if
next x
'highlight digits
For x As long = 0 To 9
If inbox(digit1(x).colour,mx,my) Or inbox(digit1txt(x).colour,mx,my)Then
line(digit1(x).tx,digit1(x).ty)-(digit1(x).bx,digit1(x).by),rgb(255,255,255),b
end if
next x
For x As long = 0 To 9
If inbox(digit2(x).colour,mx,my) Or inbox(digit2txt(x).colour,mx,my)Then
line(digit2(x).tx,digit2(x).ty)-(digit2(x).bx,digit2(x).by),rgb(255,255,255),b
end if
next x
'HEADERS
If (ScreenEvent(@e)) Then
If e.type=13 Then end
If e.type=fb.EVENT_MOUSE_BUTTON_PRESS Then
If inbox(mon(1).colour,mx,my) Or inbox(montxt(1).colour,mx,my)Then
monthflag=1
nowflag=0
Exit Sub
End If
If inbox(yr(1).colour,mx,my) Or inbox(yrtxt(1).colour,mx,my)Then
yearflag=1
nowflag=0
Exit Sub
End If
'OTHERS (drop menus)
For x As long = 2 To 13
If inbox(mon(x).colour,mx,my) Or inbox(montxt(x).colour,mx,my) Then
_month=mon(x).value
monthtext=mon(x).text
line(mon(x).tx,mon(x).ty)-(mon(x).bx,mon(x).by),rgb(255,255,255),bf
Exit Sub
End If
Next x
For x As long = 2 To 4
If inbox(yr(x).colour,mx,my) Or inbox(yrtxt(x).colour,mx,my)Then
yeartext=yr(x).text
'_year=yr(x).value
line(yr(x).tx,yr(x).ty)-(yr(x).bx,yr(x).by),rgb(255,255,255),bf
Exit Sub
End If
Next x
For x As long = 0 To 9
If inbox(digit1(x).colour,mx,my) Or inbox(digit1txt(x).colour,mx,my)Then
digit1text=digit1(x).text
digit1flag=1
line(digit1(x).tx,digit1(x).ty)-(digit1(x).bx,digit1(x).by),rgb(255,255,255),bf
Exit Sub
End If
Next x
For x As long = 0 To 9
If inbox(digit2(x).colour,mx,my) Or inbox(digit2txt(x).colour,mx,my)Then
digit2text=digit2(x).text
digit2flag=1
line(digit2(x).tx,digit2(x).ty)-(digit2(x).bx,digit2(x).by),rgb(255,255,255),bf
Exit Sub
End If
Next x
if incircle(.5*xres,.8*yres,35,mx,my) then
_year=valint(_yr): _month= valint(mn )
nowflag=1
yearflag=0
monthflag=0
monthtext=""
yeartext=""
digit1text=""
digit2text=""
exit sub
end if
'LAST EVENT REACHED (date filled)
If incircle(.5*xres,.05*yres,xres/30,mx,my) Then
printflag=1
Exit Sub
End If
End If 'e.type
End If 'screvent
End Sub
Function allflags() As long
Dim sum As long=monthflag+yearflag+digit1flag+digit2flag
If sum=4 Then
Return -1
Else
Return 0
End If
End Function
Function checktext() As long
If monthtext="" Then Return 0
If yeartext="" Then Return 0
If digit1text="" Then Return 0
If digit2text="" Then Return 0
Return -1
End Function
Sub mouseloop()
Dim As long mx,my
Do
Getmouse mx,my
mday=mid(date,4,2)
_yr=mid(date,7,4)
mn=mid(date,1,2)
Screenlock
Cls
paintscreen
if allflags and printflag then
for z as single=35 to 30 step -.1
circle(.5*xres,.8*yres),z,Rgb(0,150+30*z,236)
next z
circle(.5*xres,.8*yres),30,rgb(0,0,0),,,,f
draw string(.485*xres,.79*yres),"Now"
end if
if nowflag=1 then
digits(time,.52*xres,.13*yres,rgb(100,0,0),10)
draw string(.215*xres,.37*yres),"Now",rgb(0,0,0)
#define pt(n) draw string(.2*xres-n,.8*yres),verse,rgb(0,00,0)
' dim as long temp3=12 (for testing rymes)
select case _month
case 1
verse="January brings the snow, Makes our feet and fingers glow."
draw string(.2*xres,.8*yres),verse,rgb(0,00,0)
case 2
verse="February brings the rain, Thaws the frozen lake again."
pt(len(verse))
case 3
verse="March brings breezes loud and shrill, Stirs the golden daffodil."
pt(len(verse))
case 4
verse="April brings the primrose sweet, Scatters daisies at our feet."
pt(len(verse))
case 5
verse="May brings flocks of pretty lambs, Skipping by their fleecy dams."
pt(len(verse))
case 6
verse="June brings tulips, lillies, roses, Fills the children's hands with posies."
pt(len(verse))
case 7
verse="Hot July brings cooling showers, Apricots and gillyflowers."
pt(len(verse))
case 8
verse="August brings the sheaves of corn, Then the harvest home is borne."
pt(len(verse))
case 9
verse="Warm September brings the fruit, Sportsmen then begin to shoot."
pt(len(verse))
case 10
verse="Fresh October brings the pheasant, Then to gather nuts is pleasant."
pt(len(verse))
case 11
verse="Dull November brings the blast, Then the leaves are falling past."
pt(len(verse))
case 12
verse="Chill December brings the sleet, Blazing fire and Christmas treat."
pt(len(verse))
end select
inspect(185,230,2.5)
end if
monthheader
yearheader
If printflag=1 Then PrintCalendar _year, _month
If monthflag=1 Then dropmonth:Draw String (.1*xres,.05*yres),monthtext,Rgb(0,0,0)
If yearflag=1 Then
dropyear:Draw String (.15*xres,.05*yres),yeartext,Rgb(0,0,0)
dropdigit1:Draw String (.17*xres,.05*yres),digit1text,Rgb(0,0,0)
dropdigit2:Draw String (.18*xres,.05*yres),digit2text,Rgb(0,0,0)
end if
If (allflags And checktext) Then
If printflag=0 Then
Circle(.5*xres,.05*yres),xres/30,Rgb(100,100,100),,,,f
Draw String(.475*xres,.04*yres),"Start",offwhite
end if
if nowflag=0 then _year=Valint(yeartext+digit1text+digit2text)
End If
If _year<1899 Then
printflag=0
Draw String(10,10),"NOT BEFORE 1899 PLEASE",Rgb(255,0,0)
End If
checkevents(mx,my)
Screenunlock
Sleep 1,1
Loop Until Inkey=Chr(27) or endflag=1
End Sub
Sub ComputeMonth (_year As long, _month As long, Byref StartDay As long,Byref TotalDays As long)
Const LEAP = 366 Mod 7
Const NORMAL = 365 Mod 7
Dim As long NumDays,I
For I = 1899 To _year- 1
If IsLeapYear(I) Then
NumDays = NumDays + LEAP
Else
NumDays = NumDays + NORMAL
End If
Next
For I = 1 To _month - 1
NumDays = NumDays + MonthData(I).Number
Next
TotalDays = MonthData(_month).Number
If IsLeapYear(_year) Then
If _month > 2 Then
NumDays = NumDays + 1
Elseif _month = 2 Then
TotalDays = TotalDays + 1
End If
End If
StartDay = NumDays Mod 7
End Sub
Function IsLeapYear (N As long) As long
IsLeapYear = (N Mod 4 = 0 And N Mod 100 <> 0) Or (N Mod 400 = 0)
End Function
sub inspect(mx as long,my as long,mw as long)
if mw=0 then mw=1
mw=abs(mw)
for z as long=0 to 16
line(mx-40+z,my-40+z)-(mx+40-z,my+40-z),rgb(50*z/40,50*z/4,50*z/3.2),B
next z
dim as ulong array(1 to 6561)
dim as long count
for x as long=mx-40 to mx+40
for y as long=my-40 to my+40
count=count+1
array(count)=point(x,y)
next y
next x
count=0
for x as long=mx-40 to mx+40
for y as long=my-40 to my+40
count=count+1
var NewX=mw*(x-mx)+mx
var NewY=mw*(y-my)+my
line(NewX-mw/2,NewY-mw/2)-(NewX+mw/2,NewY+mw/2),array(count),BF
next y
next x
end sub
Sub PrintCalendar (_year As long, _month As long) 'STATIC
Dim As String header
Dim As long totaldays,_pos,_csrlin
Dim As long startday,leftmargin
ComputeMonth _year, _month, StartDay, TotalDays
Header = Rtrim(MonthData(_month).Month_name) + ", " + Str(_year)
LeftMargin = (35 - Len(Header)) \ 2
Locate 15
Print Tab(LeftMargin+50); Header
Print
Print Tab(50);"Su M Tu W Th F Sa"
Print
LeftMargin = 5 * StartDay + 1
Print Tab(LeftMargin+49);
For I As long = 1 To TotalDays
Print Using "##_ "; I;
if I=valint(mday) then
_pos=pos
_csrlin=csrlin
if nowflag=1 then circle( (xres*(_pos)/100)-38,yres*_csrlin/37-15),13,rgba(200,0,0,150),,,,f
end if
If Pos(0) > 82 Then Print Tab(50);
Next
End Sub
dat1: 'for boxes
Data "Month","JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"
dat2:'for calendar
Data "January", 31, "February", 28, "March", 31
Data "April", 30, "May", 31, "June", 30, "July", 31, "August", 31
Data "September", 30, "October", 31, "November", 30, "December", 31
Sub digits(t As String,x As long,y As long,clr As Ulong,sz As long,img As Any Pointer=0)
x=x-2*sz
dim as single s=any,c=any
#macro thickline(x1,y1,x2,y2)
s=(y1-y2)/10
c=(x2-x1)/10
Line img,(x1-s,y1-c)-(x2+s,y2+c),clr,bf
#endmacro
#macro display(_a,_b,_c,_d,_e,_f,_g)
x=x+2*sz
If _a=1 Then :thickline(x,y,(x+sz),y):End If
If _b=1 Then :thickline((x+sz),y,(x+sz),(y+sz)):End If
If _c=1 Then :thickline((x+sz),(y+sz),(x+sz),(y+2*sz)):End If
If _d=1 Then :thickline((x+sz),(y+2*sz),x,(y+2*sz)):End If
If _e=1 Then :thickline(x,(y+2*sz),x,(y+sz)):End If
If _f=1 Then :thickline(x,(y+sz),x,y):End If
If _g=1 Then :thickline(x,(y+sz),(x+sz),(y+sz)):End If
#endmacro
For z As long=0 To Len(t)-1
Select Case As Const t[z]
Case 48 :display(1,1,1,1,1,1,0) '"0"
Case 49 :display(0,1,1,0,0,0,0) '"1"
Case 50 :display(1,1,0,1,1,0,1) '"2"
Case 51 :display(1,1,1,1,0,0,1) '"3"
Case 52 :display(0,1,1,0,0,1,1) '"4"
Case 53 :display(1,0,1,1,0,1,1) '"5"
Case 54 :display(1,0,1,1,1,1,1) '"6"
Case 55 :display(1,1,1,0,0,0,0) '"7"
Case 56 :display(1,1,1,1,1,1,1) '"8"
Case 57 :display(1,1,1,1,0,1,1) '"9"
Case 58 '":"
Circle((x+2*sz),(y+sz/2)),(sz/5),clr,,,,f
Circle((x+2*sz),(y+1.5*sz)),(sz/5),clr,,,,f
x=x+sz
Case 45 :display(0,0,0,0,0,0,1) '"-"
Case 46 '"."
Circle((x+2*sz),(y+1.9*sz)),(sz/5),clr,,,,f
x=x+sz
Case 32 '" "
x=x+sz
End Select
Next z
End Sub