Author Topic: Calendar Maker  (Read 13728 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Calendar Maker
« on: August 05, 2019, 01:55:20 am »
Here is the Calendar Maker program I've worked on in the last couple days. I'm 99.9% sure it is finished. I know I could have done it differently and not used LOCATE on my numbers and holidays, but with the math I used and the loops, and all the hard work I did to make things fit in the boxes, I'm just going to leave it like this. If you use it enough, you might come across holiday names that don't look centered at all, but I'm just going to leave it like this. This is the first calendar program I've ever made. Thank you to B+, SMcNeill, and euklides for your help. I added your names to the code at the top. I find it pretty neat how you can use this program to go from the mid-1700's to 9999. You can also make one of the month you were born. You also can save the calendars as JPG pictures, with a different name for every month and year. I say in the welcome screen that you can use Windows Paint or any other graphics program to print it out. I printed out the month I was born. :) You also can use this program to use it as a tool to print them out and write tiny reminders for certain days. I thought about adding that to the program, but I don't know enough about making data files to do that. I would end up making a separate data file for every single reminder and that would be a mess. Plus I feel pretty confident that this is complete for me and I finally made a neat calendar maker. Of course anyone can use the code and expand on it from here if they wish. But please try it out. I suggest putting it in a separate directory so you can find your calendar JPG files easy. For example, the picture file for January 2000 would be made like this: 1-2000.jpg. I did it that way so they would line up in the Windows directory in order. Have fun with it!
P..S. Also, I know there's ways to print out pictures, and probably even rotate them first before you print them, but I haven't looked too much into that and I'm very cautious about printing graphics with my programs because twice so far I've printed 2 of them where it made the entire papers black, which is so much toner wasted in the printer.

(Note: As usual, this first paste isn't the best, so scroll down, thanks.)

Code: QB64: [Select]
  1. 'This is my very first calendar making program!
  2. 'Thanks to the guys from the QB64.org forum for the help, B+, SMcNeill, and euklides!
  3. 'This is a freeware program like all my other programs and games, only free.
  4. 'Feel free to use this code in your own programs.
  5. 'Made on Sunday, August 4, 2019 by Ken G.
  6. '
  7. _TITLE "Calendar Maker"
  8. start:
  9. dd = 0
  10. leap = 0
  11. SCREEN _NEWIMAGE(800, 600, 32)
  12. PRINT "                                     Monthly Calendar Maker"
  13. PRINT "                                           By Ken G."
  14. PRINT "             This program will make a calendar for the year and month you want."
  15. PRINT "             It will also name some holidays on their days."
  16. PRINT "             This uses the Gregorian Calendar which became common practice in"
  17. PRINT "             England in 1753."
  18. PRINT "             First make a calender, then if you want to save it as a .jpg file,"
  19. PRINT "             press the 'S' key and it will save it as the month and year for its name."
  20. PRINT "             For example, if you made a calendar for January 2020 and wish to save it,"
  21. PRINT "             press the 'S' key and it will save it as 1-2020.jpg"
  22. PRINT "             Feel free to use a different program to change the picture as you wish and"
  23. PRINT "             also print it with a printer, with Windows Paint or something else."
  24. PRINT "             The .jpg calendar picture will be saved in the same directory as this program."
  25. PRINT "             To make a new calendar without saving, press the Space Bar."
  26. PRINT "             Keyboard commands will be listed on the title bar of the window."
  27. again1:
  28. INPUT "             Type the year here (1753-9999): ", y
  29. IF y < 1753 OR y > 9999 THEN PRINT "The year can only be between 1753 and 9999, try again.": GOTO again1:
  30. again2:
  31. INPUT "             Type the month here (1-12): ", m
  32. IF m < 1 OR m > 12 THEN PRINT "1-12 only, try again.": GOTO again2:
  33.  
  34. 'Get the month name.
  35. IF m = 1 THEN month$ = " January"
  36. IF m = 2 THEN month$ = "February"
  37. IF m = 3 THEN month$ = "  March"
  38. IF m = 4 THEN month$ = "  April"
  39. IF m = 5 THEN month$ = "  May"
  40. IF m = 6 THEN month$ = "  June"
  41. IF m = 7 THEN month$ = "  July"
  42. IF m = 8 THEN month$ = " August"
  43. IF m = 9 THEN month$ = "September"
  44. IF m = 10 THEN month$ = " October"
  45. IF m = 11 THEN month$ = "November"
  46. IF m = 12 THEN month$ = "December"
  47.  
  48. 'Calculate to see if it's a Leap Year.
  49. IF m <> 2 THEN GOTO nex:
  50. IF y / 400 = INT(y / 400) THEN leap = 1: GOTO more:
  51. IF y / 4 = INT(y / 4) THEN leap = 1
  52. IF y / 100 = INT(y / 100) THEN leap = 0
  53.  
  54. 'Get the number of days for each month.
  55. more:
  56. IF leap = 1 THEN days = 29
  57. IF leap = 0 THEN days = 28
  58. GOTO weekday:
  59. nex:
  60. IF m = 1 THEN days = 31
  61. IF m = 3 THEN days = 31
  62. IF m = 4 THEN days = 30
  63. IF m = 5 THEN days = 31
  64. IF m = 6 THEN days = 30
  65. IF m = 7 THEN days = 31
  66. IF m = 8 THEN days = 31
  67. IF m = 9 THEN days = 30
  68. IF m = 10 THEN days = 31
  69. IF m = 11 THEN days = 30
  70. IF m = 12 THEN days = 31
  71. weekday:
  72.  
  73. 'Set the month, year, and weekday variables to start with.
  74. mm = m
  75. yy = y
  76. GetDay mm, dd, y, weekday
  77.  
  78. 'This section makes the calendar graph.
  79. make:
  80. _TITLE "Press 'S' to Save, Space Bar to make another calendar, or 'Esc' to quit."
  81. LINE (0, 0)-(800, 600), _RGB32(255, 255, 255), BF
  82. COLOR _RGB(0, 0, 0), _RGB(255, 255, 255)
  83. LOCATE 3, 42: PRINT month$; "  "; yy
  84.  
  85. FOR x = 20 TO 780 STEP 108
  86.     LINE (x, 100)-(x, 580), _RGB32(0, 0, 0)
  87. FOR z = 100 TO 580 STEP 80
  88.     LINE (16, z)-(780, z), _RGB32(0, 0, 0)
  89.  
  90. LOCATE 5, 8: PRINT "SUNDAY"
  91. LOCATE 5, 21: PRINT "MONDAY"
  92. LOCATE 5, 34: PRINT "TUESDAY"
  93. LOCATE 5, 47: PRINT "WEDNESDAY"
  94. LOCATE 5, 60: PRINT "THURSDAY"
  95. LOCATE 5, 75: PRINT "FRIDAY"
  96. LOCATE 5, 87: PRINT "SATURDAY"
  97.  
  98. 'Finding Date of Easter
  99. PQA = yy
  100. GOSUB PAQUES
  101. 'month = PQM, day = PQJ, year = PQA
  102.  
  103. 'This section puts the right dates and holidays in the right squares for the calendar.
  104. w = (weekday * 13) + 8
  105. FOR week = 8 TO 59 STEP 5
  106.     FOR day = w TO 91 STEP 13
  107.         dd = dd + 1
  108.         GetDay mm, dd, y, weekday
  109.         IF weekday = 0 THEN LOCATE week, day + 2: PRINT dd
  110.         IF weekday = 1 THEN LOCATE week, day - 2: PRINT dd
  111.         IF weekday = 2 THEN LOCATE week, day - 2: PRINT dd
  112.         IF weekday = 3 THEN LOCATE week, day - 1: PRINT dd
  113.         IF weekday = 4 THEN LOCATE week, day: PRINT dd
  114.         IF weekday > 4 THEN LOCATE week, day + 2: PRINT dd
  115.         IF m = 1 AND dd = 1 THEN LOCATE week + 2, day - 1: PRINT "New Years": LOCATE week + 3, day: PRINT "Day"
  116.         IF m = 1 AND weekday = 2 AND dd > 14 AND dd < 22 THEN LOCATE week + 2, day - 1: PRINT "MLK Jr.": LOCATE week + 3, day: PRINT "Day"
  117.         IF m = 2 AND weekday = 2 AND dd > 14 AND dd < 22 THEN LOCATE week + 2, day + 3: PRINT "Pres.": LOCATE week + 3, day + 3: PRINT "Day"
  118.         IF m = 2 AND dd = 14 THEN LOCATE week + 2, day + 3: PRINT "Val.": LOCATE week + 3, day + 3: PRINT "Day"
  119.         IF m = PQM AND dd = PQJ THEN LOCATE week + 2, day - 1: PRINT "Easter"
  120.         IF m = 5 AND weekday = 2 AND dd > 24 THEN LOCATE week + 2, day - 1: PRINT "Mem.": LOCATE week + 3, day - 1: PRINT "Day"
  121.         IF m = 7 AND dd = 4 THEN LOCATE week + 2, day - 1: PRINT "Independ.": LOCATE week + 3, day + 2: PRINT "Day"
  122.         IF m = 9 AND weekday = 2 AND dd < 8 THEN LOCATE week + 2, day - 2: PRINT "Labor Day"
  123.         IF m = 10 AND dd > 9 AND dd < 16 AND weekday = 2 THEN LOCATE week + 2, day - 1: PRINT "Columbus": LOCATE week + 3, day: PRINT "Day"
  124.         IF m = 10 AND dd = 31 THEN LOCATE week + 2, day: PRINT "Halloween"
  125.         IF m = 11 AND dd = 11 THEN LOCATE week + 2, day: PRINT "Veterans": LOCATE week + 3, day: PRINT "Day"
  126.         IF m = 11 AND dd > 21 AND dd < 29 AND weekday = 5 THEN LOCATE week + 2, day - 1: PRINT "Thanksgiving"
  127.         IF m = 12 AND dd = 25 THEN LOCATE week + 2, day + 1: PRINT "Christmas"
  128.         IF dd = days THEN GOTO more2:
  129.     NEXT day
  130.     w = 7
  131. NEXT week
  132. more2:
  133. a$ = INKEY$
  134. IF a$ = CHR$(27) THEN CLS: PRINT: PRINT: PRINT "Goodbye.": END
  135. IF a$ = "s" OR a$ = "S" THEN GOTO saving:
  136. IF a$ = " " THEN GOTO start:
  137. GOTO more2:
  138.  
  139.  
  140. 'Find the right date for Easter.
  141. PAQUES:
  142. PQM = INT(PQA / 100): PQ1 = PQA - PQM * 100: PQJ = INT(((PQA / 19 - INT(PQA / 19)) + .001) * 19)
  143. PQ2 = INT(PQM / 4): PQ3 = INT(((PQM / 4) - PQ2 + .001) * 4): PQ4 = INT((8 + PQM) / 25)
  144. PQ5 = INT((1 + PQM - PQ4 + .001) / 3): PQ4 = (15 + 19 * PQJ + PQM - PQ2 - PQ5 + .001) / 30: PQ4 = PQ4 - INT(PQ4)
  145. PQ4 = INT(PQ4 * 30): PQ5 = INT(PQ1 / 4): PQ6 = ((PQ1 / 4) - PQ5) * 4
  146. PQ7 = (32 + 2 * PQ3 + 2 * PQ5 - PQ4 - PQ6 + .001) / 7: PQ7 = (PQ7 - INT(PQ7)) * 7: PQ6 = (PQJ + 11 * PQ4 + 22 * PQ7) / 451
  147. PQ6 = INT(PQ6): PQ2 = (114 + PQ4 + PQ7 - 7 * PQ6) / 31: PQM = INT(PQ2): PQJ = INT((PQ2 - PQM + .001) * 31 + 1)
  148.  
  149.  
  150. 'This section saves the calendar to a JPG file along with the SUB at the end of this program.
  151. saving:
  152. mo$ = STR$(m)
  153. mo$ = LTRIM$(RTRIM$(mo$))
  154. year$ = STR$(yy)
  155. year$ = LTRIM$(RTRIM$(year$))
  156. nm$ = mo$ + "-"
  157. nm$ = LTRIM$(RTRIM$(nm$))
  158. nm$ = nm$ + year$
  159. nm$ = LTRIM$(RTRIM$(nm$))
  160. SaveImage 0, nm$ 'saves entire program screen,"
  161. nm2$ = nm$ + ".jpg"
  162. nm2$ = LTRIM$(RTRIM$(nm2$))
  163. PRINT "          "; nm2$; " has been saved to your computer."
  164. INPUT "          Do you wish to make another calendar (Yes/No)"; ag$
  165. IF LEFT$(ag$, 1) = "y" OR LEFT$(ag$, 1) = "Y" THEN GOTO start:
  166. PRINT "          Goodbye."
  167.  
  168. weekdays:
  169.  
  170. 'This section gets the right weekday.
  171. SUB GetDay (mm, dd, y, weekday) 'use 4 digit year
  172.     'From Zeller's congruence: https://en.wikipedia.org/wiki/Zeller%27s_congruence
  173.     IF mm < 3 THEN mm = mm + 12: y = y - 1
  174.     century = y MOD 100
  175.     zerocentury = y \ 100
  176.     weekday = (dd + INT(13 * (mm + 1) / 5) + century + INT(century / 4) + INT(zerocentury / 4) + 5 * zerocentury) MOD 7
  177.  
  178. 'This section saves the .jpg picture file.
  179. SUB SaveImage (image AS LONG, filename AS STRING)
  180.     bytesperpixel& = _PIXELSIZE(image&)
  181.     IF bytesperpixel& = 0 THEN PRINT "Text modes unsupported!": END
  182.     IF bytesperpixel& = 1 THEN bpp& = 8 ELSE bpp& = 24
  183.     x& = _WIDTH(image&)
  184.     y& = _HEIGHT(image&)
  185.     b$ = "BM????QB64????" + MKL$(40) + MKL$(x&) + MKL$(y&) + MKI$(1) + MKI$(bpp&) + MKL$(0) + "????" + STRING$(16, 0) 'partial BMP header info(???? to be filled later)
  186.     IF bytesperpixel& = 1 THEN
  187.         FOR c& = 0 TO 255 ' read BGR color settings from JPG image + 1 byte spacer(CHR$(0))
  188.             cv& = _PALETTECOLOR(c&, image&) ' color attribute to read.
  189.             b$ = b$ + CHR$(_BLUE32(cv&)) + CHR$(_GREEN32(cv&)) + CHR$(_RED32(cv&)) + CHR$(0) 'spacer byte
  190.         NEXT
  191.     END IF
  192.     MID$(b$, 11, 4) = MKL$(LEN(b$)) ' image pixel data offset(BMP header)
  193.     lastsource& = _SOURCE
  194.     _SOURCE image&
  195.     IF ((x& * 3) MOD 4) THEN padder$ = STRING$(4 - ((x& * 3) MOD 4), 0)
  196.     FOR py& = y& - 1 TO 0 STEP -1 ' read JPG image pixel color data
  197.         r$ = ""
  198.         FOR px& = 0 TO x& - 1
  199.             c& = POINT(px&, py&) 'POINT 32 bit values are large LONG values
  200.             IF bytesperpixel& = 1 THEN r$ = r$ + CHR$(c&) ELSE r$ = r$ + LEFT$(MKL$(c&), 3)
  201.         NEXT px&
  202.         d$ = d$ + r$ + padder$
  203.     NEXT py&
  204.     _SOURCE lastsource&
  205.     MID$(b$, 35, 4) = MKL$(LEN(d$)) ' image size(BMP header)
  206.     b$ = b$ + d$ ' total file data bytes to create file
  207.     MID$(b$, 3, 4) = MKL$(LEN(b$)) ' size of data file(BMP header)
  208.     IF LCASE$(RIGHT$(filename$, 4)) <> ".jpg" THEN ext$ = ".jpg"
  209.     f& = FREEFILE
  210.     OPEN filename$ + ext$ FOR OUTPUT AS #f&: CLOSE #f& ' erases an existing file
  211.     OPEN filename$ + ext$ FOR BINARY AS #f&
  212.     PUT #f&, , b$
  213.     CLOSE #f&
  214.  
  215.  
« Last Edit: August 05, 2019, 11:10:30 pm by SierraKen »

Offline euklides

  • Forum Regular
  • Posts: 128
    • View Profile
Re: Calendar Maker
« Reply #1 on: August 05, 2019, 04:13:05 am »
Of course only available in the States for the holidays and national holidays.

Well done, and now the next steps would be :
- moon phase (%  %)
- spring, summer autumn & winter days...
- day number 1... 365 (356)
- week number 1... 52 (53)
- julian date

In fact, when you work with making a calendar, there are a lot of complications !
« Last Edit: August 05, 2019, 05:27:37 am by euklides »
Why not yes ?

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Calendar Maker
« Reply #2 on: August 05, 2019, 10:14:39 am »
Cool. Nicely done!
Logic is the beginning of wisdom.

Offline Jack002

  • Forum Regular
  • Posts: 123
  • Boss, l wanna talk about arrays
    • View Profile
Re: Calendar Maker
« Reply #3 on: August 05, 2019, 10:31:24 am »
Very cool. I once made a program that makes a calendar in HTML with tables. I was lazy and asked the user the number of days and what day the calendar starts on. I never put that in to automate that. This and mine would be an interesting combo.
[I have had a need for an html cal for years, its for a website I'm on]
QB64 is the best!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Calendar Maker
« Reply #4 on: August 05, 2019, 10:48:02 am »
Clippy’s “Calendos” Program from 1988.  I think it still works in QB64, but I haven’t tested it yet to be certain. 

Code: [Select]
CALENDOS.BAS
'
' COMPUTER GENERATED CALENDER
'
' FILE records all holidays and weekends
' for accurate business days in year
'
DEFINT A-Z
'_FULLSCREEN 'QB64
DECLARE SUB GetDay (strday$, daynm%)
DECLARE SUB LeapYear (yr%, Lpy$, fday%)
DECLARE SUB Easter (yrn%, EM%, ED%)
OPTION BASE 1
DIM Day%(7, 6)
DIM Hol%(4)
DIM Rel%(4)
CLS
10
CLS
SCREEN 13
OUT &H3C8, 0 'assign color number 1 TO 15 in Screen 12
OUT &H3C9, 0 'red value
OUT &H3C9, 0 'green value
OUT &H3C9, 15 'blue value

SOUND 300, 4
'SOUND 700, 3 'Opening screen
COLOR 9
LOCATE 5, 13: PRINT "CALENDOS PROGRAM"
LOCATE 20, 3: PRINT "Year number or enter for present year:"
in$ = ""
DO: _LIMIT 100 'Get Input from User QB64
a$ = INKEY$
IF a$ <> "" AND a$ > CHR$(47) AND a$ < CHR$(58) THEN 'filter for numbers only
in$ = in$ + a$
ELSEIF a$ <> "" THEN EXIT DO
END IF
LOCATE 10, 15: PRINT "Year = "; in$
LOOP UNTIL LEN(in$) = 4
SLEEP 1
IF LEN(in$) = 4 THEN
Year$ = in$ 'Get year from user 4 digit
ELSE: Year$ = MID$(DATE$, 7, 4) 'get year from the actual date
END IF

yrn% = VAL(Year$) ' Check for number of year for leap year calculate
yrnum% = yrn% 'yrnum% is for adding year in second January and display
LeapYear yrn%, Lpy$, frstday%
Easter yrn%, EM%, ED%


num% = frstday% ' set first month 1st day position for calendar
37
'_______________READ NUM OF DAYS _____________ INKEY LOOP for months
FOR month% = 1 TO 13 'includes January of next year 13 months
ERASE Day%
fst% = num% 'get first day number(day) from num% for other months

SELECT CASE month% 'DAYS OF MONTH
CASE 2
IF Lpy$ = "N" THEN days% = 28
IF Lpy$ = "Y" THEN days% = 29
CASE 4, 6, 9, 11
days% = 30
CASE ELSE ' all other months have 31 days
days% = 31
END SELECT
week% = 1
FOR d% = 1 TO days% 'ASSIGN NUMBERS TO DAYS ARRAY
Day%(num%, week%) = d%
IF num% = 7 THEN
num% = 0
week% = 1 + week%
END IF
num% = 1 + num% 'SET NUMBER FOR NEXT MONTH
NEXT d%

'>>>>>>>>>>>>>>>>>>>>>>>> SELECT HOLIDAYS

ERASE Hol%, Rel% 'for each month
mond% = 0
tue% = 0
thu% = 0
'ADJUST FOR MONTHS WITHOUT DAY IN 1ST WEEK
IF Day%(2, 1) = 0 THEN mond% = 1
IF Day%(5, 1) = 0 THEN thu% = 1
IF Day%(3, 1) = 0 THEN tue% = 1

SELECT CASE month% 'holiday 2nd monday = Day%(2, 3)
CASE 1
mon$ = "JANUARY"
Hol%(1) = 1
Hol%(2) = Day%(2, 3 + mond%)
CASE 2
mon$ = "FEBRUARY"
Hol%(1) = Day%(2, 3 + mond%)
CASE 3
mon$ = "MARCH"
IF EM% = 3 THEN Rel%(1) = ED%
CASE 4
mon$ = "APRIL"
IF EM% = 4 THEN Rel%(1) = ED%
CASE 5
mon$ = "MAY"
Hol%(1) = Day%(2, 4 + mond%)
IF Day%(2, 5 + mond%) > 0 THEN Hol%(1) = Day%(2, 5 + mond%) 'last monday of month
CASE 6
mon$ = "JUNE"
CASE 7
mon$ = "JULY"
Hol%(1) = 4
CASE 8
mon$ = "AUGUST"
CASE 9
mon$ = "SEPTEMBER"
Hol%(1) = Day%(2, 1 + mond%)
CASE 10
mon$ = "OCTOBER"
Hol%(1) = Day%(2, 2 + mond%)
CASE 11
mon$ = "NOVEMBER"
Hol%(1) = Day%(3, 1 + tue%)
Hol%(2) = 11
Hol%(3) = Day%(5, 4 + thu%)
CASE 12
mon$ = "DECEMBER"
Hol%(1) = 25
CASE 13
mon$ = "JANUARY"
Hol%(1) = 1
Hol%(2) = Day%(2, 3 + mond%)
END SELECT
tomonth$ = MID$(DATE$, 1, 2) 'Get todays month in time line
IF MID$(tomonth$, 1, 1) = "0" THEN tomonth$ = MID$(DATE$, 2, 1)
SELECT CASE tomonth$ 'get month name
CASE "1": moon$ = "Jan."
CASE "2": moon$ = "Feb."
CASE "3": moon$ = "Mar."
CASE "4": moon$ = "Apr."
CASE "5": moon$ = "May "
CASE "6": moon$ = "June"
CASE "7": moon$ = "July"
CASE "8": moon$ = "Aug."
CASE "9": moon$ = "Sep."
CASE "10": moon$ = "Oct."
CASE "11": moon$ = "Nov."
CASE "12": moon$ = "Dec."
END SELECT
today$ = MID$(DATE$, 4, 2) 'Get todays date
yr$ = MID$(DATE$, 7, 4)
'Figure name of the day of week near clock using actual date
IF month% = 1 THEN
datenum% = VAL(today$) 'find date number
monthnum% = VAL(tomonth$) 'find month number
yrno% = VAL(yr$) ' find year number
LeapYear yrno%, Lp$, fstday% 'check if leap Get first day position number
mon1st% = fstday%
FOR i% = 1 TO monthnum% - 1
SELECT CASE i%
CASE 2
IF Lp$ = "N" THEN mon1st% = mon1st% + 28 'Feb
IF Lp$ = "Y" THEN mon1st% = mon1st% + 29
CASE 4, 6, 9, 11
mon1st% = mon1st% + 30 'April, June, Sept, Nov
CASE ELSE
mon1st% = mon1st% + 31 ' all others have 31 days
END SELECT
NEXT i%
IF Lp$ = "N" THEN lpno% = 365
IF Lp$ = "Y" THEN lpno% = 366
dayofyear% = mon1st% + datenum% - fstday%
IF Lp$ = "Y" AND dayofyear% >= 60 THEN dayofyear% = dayofyear% + 1
fstofmo% = mon1st% MOD 7 'finds day value of 1st day of month
daynum% = (datenum% + fstofmo% - 1) MOD 7 'finds value of actual day

SELECT CASE daynum% 'assign week day name
CASE 0: wd$ = "Sat"
CASE 1: wd$ = "Sun"
CASE 2: wd$ = "Mon"
CASE 3: wd$ = "Tue"
CASE 4: wd$ = "Wed"
CASE 5: wd$ = "Thu"
CASE 6: wd$ = "Fri"
END SELECT
END IF
COLOR 8
CLS

'*********************** PRINT CALENDER
COLOR 8
LOCATE 23, 7: PRINT "Any key for next month! "
IF month% = 13 THEN
SOUND 500, 3
'SOUND 700, 4
yrnum% = yrnum% + 1 ' add 1 for next year
LOCATE 23, 7: PRINT " Any key ends program! "
END IF
COLOR 13
LOCATE 2, 8: PRINT mon$
LOCATE 2, 24: PRINT yrnum%
COLOR 1
LOCATE 4, 8: PRINT "S M T W T F S "
COLOR 7
LOCATE 21, 7: PRINT "Day Num"; dayofyear%; " Left"; lpno% - dayofyear%
'LOCATE and PRINT day numbers............. from Day%() Array
FOR r% = 1 TO 6 'week loop r% begin
FOR c% = 1 TO 7 'day loop and colors
COLOR 14 'normal day color
IF c% = 1 OR c% = 7 THEN COLOR 5 'color weekends
FOR i% = 1 TO 3
IF Day%(c%, r%) = Hol%(i%) THEN COLOR 4 ' color holidays
IF Day%(c%, r%) = Rel%(i%) THEN COLOR 3 ' color Easter day
NEXT i%
LOCATE (2 * r%) + 4, (3 * c%) + 4: PRINT Day%(c%, r%)
IF Day%(c%, r%) = 0 THEN LOCATE (2 * r%) + 4, (3 * c%) + 4: PRINT SPACE$(2)
NEXT c%
NEXT r% 'r% week loop end
'**********************BOX around Calendar
COLOR 6
'LOCATE 3, 6: PRINT STRING$(23, CHR$(223))
LINE (48, 16)-(225, 20), 6, BF 'TOP
'LOCATE 17, 6: PRINT STRING$(23, CHR$(220))
LINE (48, 130)-(225, 134), 6, BF 'BOTTOM
LINE (44, 16)-(48, 134), 6, BF 'left side
LINE (225, 16)-(229, 134), 6, BF 'right side
'FOR i% = 3 TO 17
'LOCATE i%, 6: PRINT STRING$(1, CHR$(176)) 'Sides
'LOCATE i%, 29: PRINT STRING$(1, CHR$(176))
' NEXT i%
'*******************************

LOCATE 18, 20: COLOR 4: PRINT "Holidays"
IF month% = EM% THEN COLOR 3: LOCATE 18, 8: PRINT "Easter"
COLOR 9
LOCATE 20, 7: PRINT wd$; ", "; moon$; datenum%

DO: _LIMIT 1 'continuous time loop NEXT MONTH LOOP INKEY
hour$ = LEFT$(TIME$, 2)
SELECT CASE hour$
CASE "00"
hr$ = "12"
CASE "01", "13"
hr$ = " 1"
CASE "02", "14"
hr$ = " 2"
CASE "03", "15"
hr$ = " 3"
CASE "04", "16"
hr$ = " 4"
CASE "05", "17"
hr$ = " 5"
CASE "06", "18"
hr$ = " 6"
CASE "07", "19"
hr$ = " 7"
CASE "08", "20"
hr$ = " 8"
CASE "09", "21"
hr$ = " 9"
CASE "10", "22"
hr$ = "10"
CASE "11", "23"
hr$ = "11"
CASE "12", "24"
hr$ = "12"
END SELECT
IF hour$ < "12" THEN aft$ = " AM" 'set AM PM
IF hour$ >= "12" THEN aft$ = " PM"
minu$ = MID$(TIME$, 3, 3)
sec$ = RIGHT$(TIME$, 3) 'minutes & seconds
COLOR 9
LOCATE 20, 20: PRINT hr$; minu$;
COLOR 2
COLOR 9
PRINT aft$
LOOP UNTIL INKEY$ <> ""
NEXT month%
60 CLOSE #1
100 CLS

LOCATE 4, 4: PRINT " CALENDOS "
LOCATE 7, 4: PRINT " Written by Ted Weissgerber"
LOCATE 10, 4: PRINT " burger2227@Gmail.com"
LOCATE 14, 4: PRINT " 2010"
LOCATE 18, 4: PRINT " Qbasic and DOS Rule!"

SLEEP 3
SYSTEM

SUB Easter (yrn, EM, ED)
c = yrn \ 100 'Century
G = yrn MOD 19
K = (c - 17) \ 25
i = (c - (c \ 4) - (c - K) \ 3 + (19 * G) + 15) MOD 30
i = i - (i \ 28) * (1 - (i \ 28) * (29 \ (i + 1)) * ((21 - G) \ 11))
J = (yrn + yrn \ 4 + i + 2 - c + c \ 4) MOD 7
L = i - J
EM = 3 + (L + 40) \ 44 'Month of Easter.
ED = L + 28 - 31 * (EM \ 4) 'Day of Easter.
END SUB

SUB LeapYear (yrn%, Leap$, firstday%)
'my LEAP YEAR and the First Day of Year routine based on year 2000
LpYear% = 2000
firstday% = 7 ' the first day of 2000 was a saturday, the 7th day
IF yrn% >= 2000 THEN ' ** yrn% INPUT
'FORWARD LOOP 2000 up
yrnm% = 1999 'start in 1999
DO
yrnm% = yrnm% + 1 ' start in 2000 (1999 + 1)
IF yrnm% > 2000 THEN firstday% = firstday% + 1 'add one day every year to first day (52 weeks + 1
IF firstday% > 7 THEN firstday% = firstday% - 7 ' ** firstday% OUTPUT

IF yrnm% = LpYear% THEN Leap$ = "Y" ' ** Lp$ for print only
IF yrnm% MOD 100 = 0 THEN nly% = LpYear% MOD 400 'test century leap 400
IF nly% <> 0 THEN Leap$ = "N" ' if not divisible by 400

IF yrnm% - 1 = LpYear% THEN ' add day AFTER leap year
IF nly% = 0 THEN firstday% = firstday% + 1 ' add a leap day
IF firstday% > 7 THEN firstday% = firstday% - 7
Leap$ = "N"
LpYear% = LpYear% + 4 ' find next leap year by adding 4
END IF
nly% = 0 ' reset MOD value
LOOP UNTIL yrnm% = yrn%
END IF 'end forward loop

IF yrn% < 2000 THEN 'REVERSE LOOP 2000 down
yrnm% = 2001 'start in 2001
DO
yrnm% = yrnm% - 1 ' start in 2000 (2001 - 1)
IF yrnm% < 2000 THEN firstday% = firstday% - 1 'subt one day every year to first day (52 weeks + 1
IF firstday% = 0 THEN firstday% = 7
IF yrnm% MOD 100 = 0 THEN nly% = LpYear% MOD 400 ' test century every 100
Leap$ = "N"

IF yrnm% = LpYear% THEN ' BEFORE leap year
IF nly% = 0 AND LpYear% <> 2000 THEN firstday% = firstday% - 1 ' subt a leap day
IF firstday% = 0 THEN firstday% = 7
LpYear% = LpYear% - 4 ' find next leap year
Leap$ = "Y"
IF nly% <> 0 THEN Leap$ = "N" ' if not divisible by 400
END IF
nly% = 0 ' reset MOD value
LOOP UNTIL yrnm% = yrn%
END IF
END SUB
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Calendar Maker
« Reply #5 on: August 05, 2019, 12:08:04 pm »
Wow SAM never saw OUT before, watch OUT!

Looks like Ted Weissgerber code good for thumbnail sketches on screen, has complex Leap Year Calc and another Easter Calc.
« Last Edit: August 05, 2019, 12:18:32 pm by bplus »

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Calendar Maker
« Reply #6 on: August 05, 2019, 12:20:12 pm »
LOL that's a cute little program. But it's not from 1988, it has a gmail address in the code and it mentions QBasic with the year 2010.


Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Calendar Maker
« Reply #7 on: August 05, 2019, 12:23:57 pm »
LOL that's a cute little program. But it's not from 1988, it has a gmail address in the code and it mentions QBasic with the year 2010.

It’s from 88, but has been translated a few times over the years.  Clippy even has an Android version of it, somewhere, where it was translated to run on it.  ;)

(Here’s a link to where he was talking about it back in 2008, over at the QBASIC forums: https://www.tapatalk.com/groups/qbasic/how-calculate-week-number-t29545-s20.html)

The QBASIC forums go back 30 years, or so, but a lot of the older stuff is archived for historical preservation and disk storage, so it’s not exactly search friendly.  2008 is the oldest non-archived post I can find on his Calendos program, but he mentions it originated back in 88, and I have no real reason to doubt it.  ;)
« Last Edit: August 05, 2019, 12:35:44 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Calendar Maker
« Reply #8 on: August 05, 2019, 07:56:18 pm »
Well, I am (hopefully) minutes away from making this a GREAT calendar program. But I need help from you guys badly.  It could be minutes from being completed, but the problem I ran into is that the program freezes after you print it out using the program (Yes, I added printing to it!). It saves and prints the first one fine. But then it asks you if you want to make another calendar, so it goes back to the first screen to do that and after you add both the year and month, it just sits there... does nothing... And I have no idea why. I've looked through the code and I'm tried testing it in a few places, etc. but can't figure it out. Have you guys ran into problems before where a printer freezes a program? If we can't fix this, I'll just remove the part where it asks if you want to make a new calendar after printing, and just make the program end. I added a lot to it. In order to make it print good calendars, I got code from the Wiki pages where an example shows how to flip a picture certain degrees, it originally says 360 degrees but I changed it to 90 so it would fit good on paper. If you have a printer, please try it out. You can watch the calendar being turned 90 degrees, is really cool. Anyway, any help is appreciated, and I want to thank B+ for telling me about PRINTSTRING, which I also changed to so now the numbers line up perfectly and the holidays fit a lot better. Tell me what you think, thanks. Remember, it makes them, saves them, and prints them fine the first time, but you can't even make one the second time. Oh, I also tried _FREEIMAGE on p& which is the screen the printer prints, but it won't let me do that for some reason, but it will let me do _FREEIMAGE on the picture itself. Could that be a problem? Having a SCREEN _NEWIMAGE(800, 900), p&  overlapping the _SOURCE img& ? It's lines between 205 and 235. It might not be the problem though because it lets you go back to the front screen though to setup a new calendar. Although, could there be a conflict when you press enter and it makes another SCREEN _NEWIMAGE(800,600,32) for the new calendar? Also notice that the printer image doesn't use the last 32 number because it prints black all around the calendar, which looks neat but is too costly for toner. I wonder if that's a conflict though? Sorry for so many questions, this program just means a lot to me.

(Note: This version has an error in it, so please keep scrolling to my next one, thanks.)

Code: QB64: [Select]
  1. 'This is my very first calendar making program!
  2. 'Thanks to the guys from the QB64.org forum for the help, B+, SMcNeill, and euklides!
  3. 'This is a freeware program like all my other programs and games, only free.
  4. 'Feel free to use this code in your own programs.
  5. 'Made on Sunday, August 4, 2019 by Ken G.
  6. '
  7. _TITLE "Calendar Maker"
  8. start:
  9. _LIMIT 1000
  10. dd = 0
  11. leap = 0
  12. m = 0
  13. mm = 0
  14. y = 0
  15. yy = 0
  16. w = 0
  17. weekday = 0
  18. days = 0
  19. SCREEN _NEWIMAGE(800, 600, 32)
  20. PRINT "                                     Monthly Calendar Maker"
  21. PRINT "                                           By Ken G."
  22. PRINT "             This program will make a calendar for the year and month you want."
  23. PRINT "             It will also name some holidays on their days."
  24. PRINT "             This uses the Gregorian Calendar which became common practice in"
  25. PRINT "             England in 1753."
  26. PRINT "             First make a calender, then if you want to save it as a .jpg file,"
  27. PRINT "             press the 'S' key and it will save it as the month and year for its name."
  28. PRINT "             For example, if you made a calendar for January 2020 and wish to save it,"
  29. PRINT "             press the 'S' key and it will save it as 1-2020.jpg"
  30. PRINT "             If you wish to print your calendar on your printer, first press 'S' to save"
  31. PRINT "             it and it will then ask you if you wish to print it on paper."
  32. PRINT "             The .jpg calendar picture will be saved in the same directory as this program."
  33. PRINT "             To make a new calendar without saving, press the Space Bar."
  34. PRINT "             Keyboard commands will be listed on the title bar of the window."
  35. again1:
  36. INPUT "             Type the year here (1753-9999): ", y
  37. IF y <> INT(y) THEN PRINT "Cannot use decimals, try again.": GOTO again1:
  38. IF y < 1753 OR y > 9999 THEN PRINT "The year can only be between 1753 and 9999, try again.": GOTO again1:
  39. again2:
  40. INPUT "             Type the month here (1-12): ", m
  41. IF m <> INT(m) THEN PRINT "Cannot use decimals, try again.": GOTO again2:
  42. IF m < 1 OR m > 12 THEN PRINT "1-12 only, try again.": GOTO again2:
  43.  
  44. 'Get the month name.
  45. IF m = 1 THEN month$ = " January"
  46. IF m = 2 THEN month$ = "February"
  47. IF m = 3 THEN month$ = "  March"
  48. IF m = 4 THEN month$ = "  April"
  49. IF m = 5 THEN month$ = "  May"
  50. IF m = 6 THEN month$ = "  June"
  51. IF m = 7 THEN month$ = "  July"
  52. IF m = 8 THEN month$ = " August"
  53. IF m = 9 THEN month$ = "September"
  54. IF m = 10 THEN month$ = " October"
  55. IF m = 11 THEN month$ = "November"
  56. IF m = 12 THEN month$ = "December"
  57.  
  58. 'Calculate to see if it's a Leap Year.
  59. IF m <> 2 THEN GOTO nex:
  60. IF y / 400 = INT(y / 400) THEN leap = 1: GOTO more:
  61. IF y / 4 = INT(y / 4) THEN leap = 1
  62. IF y / 100 = INT(y / 100) THEN leap = 0
  63.  
  64. 'Get the number of days for each month.
  65. more:
  66. IF leap = 1 THEN days = 29
  67. IF leap = 0 THEN days = 28
  68. GOTO weekday:
  69. nex:
  70. IF m = 1 THEN days = 31
  71. IF m = 3 THEN days = 31
  72. IF m = 4 THEN days = 30
  73. IF m = 5 THEN days = 31
  74. IF m = 6 THEN days = 30
  75. IF m = 7 THEN days = 31
  76. IF m = 8 THEN days = 31
  77. IF m = 9 THEN days = 30
  78. IF m = 10 THEN days = 31
  79. IF m = 11 THEN days = 30
  80. IF m = 12 THEN days = 31
  81. weekday:
  82.  
  83. 'Set the month, year, and weekday variables to start with.
  84. mm = m
  85. yy = y
  86. GetDay mm, dd, y, weekday
  87.  
  88. 'This section makes the calendar graph.
  89. make:
  90. SCREEN _NEWIMAGE(800, 600, 32)
  91. LINE (0, 0)-(800, 600), _RGB32(255, 255, 255), BF
  92. _TITLE "Press 'S' to Save and/or Print, Space Bar to make another calendar, or 'Esc' to quit."
  93. COLOR _RGB32(0, 0, 0), _RGB32(255, 255, 255)
  94. LOCATE 3, 42: PRINT month$; "  "; yy
  95.  
  96. FOR x = 20 TO 780 STEP 108
  97.     LINE (x, 100)-(x, 580), _RGB32(0, 0, 0)
  98. FOR z = 100 TO 580 STEP 80
  99.     LINE (16, z)-(780, z), _RGB32(0, 0, 0)
  100.  
  101. LOCATE 5, 8: PRINT "SUNDAY"
  102. LOCATE 5, 21: PRINT "MONDAY"
  103. LOCATE 5, 34: PRINT "TUESDAY"
  104. LOCATE 5, 47: PRINT "WEDNESDAY"
  105. LOCATE 5, 60: PRINT "THURSDAY"
  106. LOCATE 5, 75: PRINT "FRIDAY"
  107. LOCATE 5, 87: PRINT "SATURDAY"
  108.  
  109. 'Finding Date of Easter
  110. PQA = yy
  111. GOSUB PAQUES
  112. 'month = PQM, day = PQJ, year = PQA
  113.  
  114. 'This section puts the right dates and holidays in the right squares for the calendar.
  115. w = (weekday * 108) + 25
  116. FOR weeky = 110 TO 570 STEP 80
  117.     FOR dayx = w TO 692 STEP 108
  118.         _LIMIT 1000
  119.         dd = dd + 1
  120.         GetDay mm, dd, y, weekday
  121.         dd$ = STR$(dd)
  122.         _FONT 16
  123.         _PRINTSTRING (dayx, weeky), dd$
  124.         _FONT 8
  125.         IF m = 1 AND dd = 1 THEN _PRINTSTRING (dayx + 10, weeky + 60), "New Years":
  126.         IF m = 1 AND weekday = 2 AND dd > 14 AND dd < 22 THEN _PRINTSTRING (dayx + 25, weeky + 60), "MLK Jr."
  127.         IF m = 2 AND weekday = 2 AND dd > 14 AND dd < 22 THEN _PRINTSTRING (dayx + 10, weeky + 60), "Presidents"
  128.         IF m = 2 AND dd = 14 THEN _PRINTSTRING (dayx + 10, weeky + 60), "Valentines"
  129.         IF m = PQM AND dd = PQJ THEN _PRINTSTRING (dayx + 25, weeky + 60), "Easter"
  130.         IF m = 5 AND weekday = 2 AND dd > 24 THEN _PRINTSTRING (dayx + 15, weeky + 60), "Memorial"
  131.         IF m = 7 AND dd = 4 THEN _PRINTSTRING (dayx, weeky + 60), "Independence"
  132.         IF m = 9 AND weekday = 2 AND dd < 8 THEN _PRINTSTRING (dayx + 25, weeky + 60), "Labor"
  133.         IF m = 10 AND dd > 9 AND dd < 16 AND weekday = 2 THEN _PRINTSTRING (dayx + 15, weeky + 60), "Columbus"
  134.         IF m = 10 AND dd = 31 THEN _PRINTSTRING (dayx + 15, weeky + 60), "Halloween"
  135.         IF m = 11 AND dd = 11 THEN _PRINTSTRING (dayx + 15, weeky + 60), "Veterans"
  136.         IF m = 11 AND dd > 21 AND dd < 29 AND weekday = 5 THEN _PRINTSTRING (dayx, weeky + 60), "Thanksgiving"
  137.         IF m = 12 AND dd = 25 THEN _PRINTSTRING (dayx + 15, weeky + 60), "Christmas"
  138.  
  139.         IF dd = days THEN _FONT 16: GOTO more2:
  140.     NEXT dayx
  141.     w = 25
  142. NEXT weeky
  143.  
  144. more2:
  145. _LIMIT 1000
  146. a$ = INKEY$
  147. IF a$ = CHR$(27) THEN CLS: PRINT: PRINT: PRINT "Goodbye.": END
  148. IF a$ = "s" OR a$ = "S" THEN GOTO saving:
  149. IF a$ = " " THEN GOTO start:
  150. IF a$ = "p" OR a$ = "P" THEN GOTO saving:
  151. GOTO more2:
  152.  
  153.  
  154. 'Find the right date for Easter.
  155. PAQUES:
  156. PQM = INT(PQA / 100): PQ1 = PQA - PQM * 100: PQJ = INT(((PQA / 19 - INT(PQA / 19)) + .001) * 19)
  157. PQ2 = INT(PQM / 4): PQ3 = INT(((PQM / 4) - PQ2 + .001) * 4): PQ4 = INT((8 + PQM) / 25)
  158. PQ5 = INT((1 + PQM - PQ4 + .001) / 3): PQ4 = (15 + 19 * PQJ + PQM - PQ2 - PQ5 + .001) / 30: PQ4 = PQ4 - INT(PQ4)
  159. PQ4 = INT(PQ4 * 30): PQ5 = INT(PQ1 / 4): PQ6 = ((PQ1 / 4) - PQ5) * 4
  160. PQ7 = (32 + 2 * PQ3 + 2 * PQ5 - PQ4 - PQ6 + .001) / 7: PQ7 = (PQ7 - INT(PQ7)) * 7: PQ6 = (PQJ + 11 * PQ4 + 22 * PQ7) / 451
  161. PQ6 = INT(PQ6): PQ2 = (114 + PQ4 + PQ7 - 7 * PQ6) / 31: PQM = INT(PQ2): PQJ = INT((PQ2 - PQM + .001) * 31 + 1)
  162.  
  163.  
  164. 'This section saves the calendar to a JPG file along with the SUB at the end of this program.
  165. saving:
  166. mo$ = STR$(m)
  167. mo$ = LTRIM$(RTRIM$(mo$))
  168. year$ = STR$(yy)
  169. year$ = LTRIM$(RTRIM$(year$))
  170. nm$ = mo$ + "-"
  171. nm$ = LTRIM$(RTRIM$(nm$))
  172. nm$ = nm$ + year$
  173. nm$ = LTRIM$(RTRIM$(nm$))
  174. SaveImage 0, nm$ 'saves entire program screen,"
  175. nm2$ = nm$ + ".jpg"
  176. nm2$ = LTRIM$(RTRIM$(nm2$))
  177. PRINT "                                        Saving and Printing"
  178. PRINT "                          "; nm2$; " has been saved to your computer."
  179. INPUT "                         Do you wish to print this to your printer (Y/N)"; p$
  180. IF LEFT$(p$, 1) = "y" OR LEFT$(p$, 1) = "Y" THEN GOTO printing:
  181. INPUT "                         Do you wish to make another calendar (Y/N)"; ag$
  182. IF LEFT$(ag$, 1) = "y" OR LEFT$(ag$, 1) = "Y" THEN GOTO start:
  183. PRINT "                        Goodbye."
  184.  
  185. printing:
  186. SCREEN _NEWIMAGE(800, 900), p&
  187. img& = _LOADIMAGE(nm2$) 'load the image file to be drawn
  188.  
  189. wide% = _WIDTH(img&): deep% = _HEIGHT(img&)
  190. TLC$ = "BL" + STR$(wide% \ 2) + "BU" + STR$(deep% \ 2) 'start draw at top left corner
  191. RET$ = "BD BL" + STR$(wide%) 'return to left side of image
  192. _SOURCE img&
  193. FOR angle% = 0 TO 90 STEP 15
  194.     _LIMIT 2000
  195.     CLS
  196.     DRAW "BM400, 450" + "TA=" + VARPTR$(angle%) + TLC$
  197.     FOR y = 0 TO deep% - 1
  198.         FOR x = 0 TO wide% - 1
  199.             DRAW "C" + STR$(POINT(x, y)) + "R1" 'color and DRAW each pixel
  200.         NEXT
  201.         DRAW RET$
  202.     NEXT
  203.     _DISPLAY 'NOTE: CPU usage will be HIGH!
  204. INPUT "               Do you wish to make another calendar (Y/N)"; ag$
  205. IF LEFT$(ag$, 1) = "y" OR LEFT$(ag$, 1) = "Y" THEN GOTO start:
  206. PRINT "               Goodbye."
  207.  
  208. weekdays:
  209.  
  210. 'This section gets the right weekday.
  211. SUB GetDay (mm, dd, y, weekday) 'use 4 digit year
  212.     'From Zeller's congruence: https://en.wikipedia.org/wiki/Zeller%27s_congruence
  213.     IF mm < 3 THEN mm = mm + 12: y = y - 1
  214.     century = y MOD 100
  215.     zerocentury = y \ 100
  216.     weekday = (dd + INT(13 * (mm + 1) / 5) + century + INT(century / 4) + INT(zerocentury / 4) + 5 * zerocentury) MOD 7
  217.  
  218. 'This section saves the .jpg picture file.
  219. SUB SaveImage (image AS LONG, filename AS STRING)
  220.     bytesperpixel& = _PIXELSIZE(image&)
  221.     IF bytesperpixel& = 0 THEN PRINT "Text modes unsupported!": END
  222.     IF bytesperpixel& = 1 THEN bpp& = 8 ELSE bpp& = 24
  223.     x& = _WIDTH(image&)
  224.     y& = _HEIGHT(image&)
  225.     b$ = "BM????QB64????" + MKL$(40) + MKL$(x&) + MKL$(y&) + MKI$(1) + MKI$(bpp&) + MKL$(0) + "????" + STRING$(16, 0) 'partial BMP header info(???? to be filled later)
  226.     IF bytesperpixel& = 1 THEN
  227.         FOR c& = 0 TO 255 ' read BGR color settings from JPG image + 1 byte spacer(CHR$(0))
  228.             cv& = _PALETTECOLOR(c&, image&) ' color attribute to read.
  229.             b$ = b$ + CHR$(_BLUE32(cv&)) + CHR$(_GREEN32(cv&)) + CHR$(_RED32(cv&)) + CHR$(0) 'spacer byte
  230.         NEXT
  231.     END IF
  232.     MID$(b$, 11, 4) = MKL$(LEN(b$)) ' image pixel data offset(BMP header)
  233.     lastsource& = _SOURCE
  234.     _SOURCE image&
  235.     IF ((x& * 3) MOD 4) THEN padder$ = STRING$(4 - ((x& * 3) MOD 4), 0)
  236.     FOR py& = y& - 1 TO 0 STEP -1 ' read JPG image pixel color data
  237.         r$ = ""
  238.         FOR px& = 0 TO x& - 1
  239.             c& = POINT(px&, py&) 'POINT 32 bit values are large LONG values
  240.             IF bytesperpixel& = 1 THEN r$ = r$ + CHR$(c&) ELSE r$ = r$ + LEFT$(MKL$(c&), 3)
  241.         NEXT px&
  242.         d$ = d$ + r$ + padder$
  243.     NEXT py&
  244.     _SOURCE lastsource&
  245.     MID$(b$, 35, 4) = MKL$(LEN(d$)) ' image size(BMP header)
  246.     b$ = b$ + d$ ' total file data bytes to create file
  247.     MID$(b$, 3, 4) = MKL$(LEN(b$)) ' size of data file(BMP header)
  248.     IF LCASE$(RIGHT$(filename$, 4)) <> ".jpg" THEN ext$ = ".jpg"
  249.     f& = FREEFILE
  250.     OPEN filename$ + ext$ FOR OUTPUT AS #f&: CLOSE #f& ' erases an existing file
  251.     OPEN filename$ + ext$ FOR BINARY AS #f&
  252.     PUT #f&, , b$
  253.     CLOSE #f&
  254.  
  255.  
« Last Edit: August 05, 2019, 11:11:25 pm by SierraKen »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Calendar Maker
« Reply #9 on: August 05, 2019, 10:04:17 pm »
Hi Ken,

I modified a small portion of your code to print calendar displayed directly without need to save image:
Code: QB64: [Select]
  1. more2:
  2. _LIMIT 1000
  3. a$ = INKEY$
  4. IF a$ = CHR$(27) THEN CLS: PRINT: PRINT: PRINT "Goodbye.": END
  5. IF a$ = "s" OR a$ = "S" THEN GOTO saving:
  6. IF a$ = " " THEN GOTO start:
  7. IF a$ = "p" OR a$ = "P" THEN
  8.     'see title change  copy here:
  9.     _TITLE "Press 'S' to Save, 'P' to Print (can do again for copy) , Space Bar to make another calendar, or 'Esc' to quit."
  10.     'printer prep (code copied and pasted from bplus Free Calendar Program)
  11.     YMAX = _HEIGHT: XMAX = _WIDTH
  12.     landscape& = _NEWIMAGE(YMAX, XMAX, 32)
  13.     _MAPTRIANGLE (XMAX, 0)-(0, 0)-(0, YMAX), 0 TO(0, 0)-(0, XMAX)-(YMAX, XMAX), landscape&
  14.     _MAPTRIANGLE (XMAX, 0)-(XMAX, YMAX)-(0, YMAX), 0 TO(0, 0)-(YMAX, 0)-(YMAX, XMAX), landscape&
  15.     _PRINTIMAGE landscape& '<<<<<<<<<<<<<<<<<<<<<<<<< debug first before wasting paper and ink
  16. GOTO more2:
  17.  

You can press p for as many copies as you want then press space to go back and do another month.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Calendar Maker
« Reply #10 on: August 05, 2019, 10:36:11 pm »
Code: QB64: [Select]
  1. printing:
  2. SCREEN _NEWIMAGE(800, 900), p&
  3.  

I don't understand this line (with _NEWIMAGE). Nothing in Wiki Syntax line says anything about parameters after the ), but there is an example that shows a setup for page flipping that uses parameters after the ).

So Wiki needs a fix?

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Calendar Maker
« Reply #11 on: August 05, 2019, 10:49:39 pm »
Code: QB64: [Select]
  1. printing:
  2. SCREEN _NEWIMAGE(800, 900), p&
  3.  

I don't understand this line (with _NEWIMAGE). Nothing in Wiki Syntax line says anything about parameters after the ), but there is an example that shows a setup for page flipping that uses parameters after the ).

So Wiki needs a fix?

Nope.  It’s part of the SCREEN syntax.

SCREEN imagehandle& [, , active_page, visual_page]

Though I’m not exactly certain what the ,p& parameter represents.


https://www.qbasic.net/en/reference/qb11/Statement/SCREEN.htm

Color setting?

Doesn’t look like QB64 supports that parameter, which is why it lists the command as: SCREEN {mode%|imagehandle&} , , active_page, visual_page]

(See the comma comma with nothing between it?
« Last Edit: August 05, 2019, 10:55:56 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Calendar Maker
« Reply #12 on: August 05, 2019, 10:58:37 pm »
Back when I made my Paint Pixels program, I took that has a variable that stores the entire screen to it so you can use it later. But I could be wrong.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Calendar Maker
« Reply #13 on: August 05, 2019, 11:07:07 pm »
Well, thanks to B+ I did it!!!!! I deleted the old printing code and used B+'s instead and it works great! Thank you and also to Euklides and SmMcNeill for the help in making this. On the start page, under "By Ken G." I added "With some help from the QB64.org forum guys!". Maybe it will attract programmers here sometime.
Now I got a fully-working Calendar Maker that makes any month from the mid 1700's to 9999. It labels some of the holidays, can save it as a .jpg file to your computer, and can print it to the printer!     I'll put this on my website very soon, which is http://www.KensPrograms.com/
Save this program to its own directory so you can find all of your saved calendars easily. I hope some of you enjoy this and use it sometimes.

(Note: On the next page of this forum topic, I posted an even better version adding some more holidays and also the ability to use arrow keys to change months.)

Code: QB64: [Select]
  1. 'This is my very first calendar making program!
  2. 'Thanks to the guys from the QB64.org forum for the help: bplus, SMcNeill, and euklides!
  3. 'This is a freeware program like all my other programs and games, only free.
  4. 'Feel free to use this code in your own programs.
  5. 'Made on Monday, August 5, 2019 by Ken G.
  6. '
  7.  
  8. start:
  9. _TITLE "Calendar Maker"
  10. _LIMIT 1000
  11. dd = 0
  12. leap = 0
  13. m = 0
  14. mm = 0
  15. y = 0
  16. yy = 0
  17. w = 0
  18. weekday = 0
  19. days = 0
  20. SCREEN _NEWIMAGE(800, 600, 32)
  21. PRINT "                                     Monthly Calendar Maker"
  22. PRINT "                                           By Ken G."
  23. PRINT "                            With some help from the QB64.org Forum guys!"
  24. PRINT "             This program will make a calendar for the year and month you want."
  25. PRINT "             It will also name some holidays on their days."
  26. PRINT "             This uses the Gregorian Calendar which became common practice in"
  27. PRINT "             England in 1753 and we still use it today."
  28. PRINT "             First make a calender, then if you want to save it as a .jpg file,"
  29. PRINT "             press the 'S' key and it will save it as the month and year for its name."
  30. PRINT "             For example, if you made a calendar for January 2020 and wish to save it,"
  31. PRINT "             press the 'S' key and it will save it as 1-2020.jpg"
  32. PRINT "             If you wish to print your calendar on your printer, press 'P' once."
  33. PRINT "             Feel free to print as many times as you wish. They take up 1 page each."
  34. PRINT "             If you save the .jpg calendar, it will be put in the same directory as this program."
  35. PRINT "             To make a new calendar without saving, press the Space Bar."
  36. PRINT "             Keyboard commands will be listed on the title bar of the window."
  37. again1:
  38. INPUT "             Type the year here (1753-9999): ", y
  39. IF y <> INT(y) THEN PRINT "Cannot use decimals, try again.": GOTO again1:
  40. IF y < 1753 OR y > 9999 THEN PRINT "The year can only be between 1753 and 9999, try again.": GOTO again1:
  41. again2:
  42. INPUT "             Type the month here (1-12): ", m
  43. IF m <> INT(m) THEN PRINT "Cannot use decimals, try again.": GOTO again2:
  44. IF m < 1 OR m > 12 THEN PRINT "1-12 only, try again.": GOTO again2:
  45.  
  46. 'Get the month name.
  47. IF m = 1 THEN month$ = " January"
  48. IF m = 2 THEN month$ = "February"
  49. IF m = 3 THEN month$ = "  March"
  50. IF m = 4 THEN month$ = "  April"
  51. IF m = 5 THEN month$ = "  May"
  52. IF m = 6 THEN month$ = "  June"
  53. IF m = 7 THEN month$ = "  July"
  54. IF m = 8 THEN month$ = " August"
  55. IF m = 9 THEN month$ = "September"
  56. IF m = 10 THEN month$ = " October"
  57. IF m = 11 THEN month$ = "November"
  58. IF m = 12 THEN month$ = "December"
  59.  
  60. 'Calculate to see if it's a Leap Year.
  61. IF m <> 2 THEN GOTO nex:
  62. IF y / 400 = INT(y / 400) THEN leap = 1: GOTO more:
  63. IF y / 4 = INT(y / 4) THEN leap = 1
  64. IF y / 100 = INT(y / 100) THEN leap = 0
  65.  
  66. 'Get the number of days for each month.
  67. more:
  68. IF leap = 1 THEN days = 29
  69. IF leap = 0 THEN days = 28
  70. GOTO weekday:
  71. nex:
  72. IF m = 1 THEN days = 31
  73. IF m = 3 THEN days = 31
  74. IF m = 4 THEN days = 30
  75. IF m = 5 THEN days = 31
  76. IF m = 6 THEN days = 30
  77. IF m = 7 THEN days = 31
  78. IF m = 8 THEN days = 31
  79. IF m = 9 THEN days = 30
  80. IF m = 10 THEN days = 31
  81. IF m = 11 THEN days = 30
  82. IF m = 12 THEN days = 31
  83. weekday:
  84.  
  85. 'Set the month, year, and weekday variables to start with.
  86. mm = m
  87. yy = y
  88. GetDay mm, dd, y, weekday
  89.  
  90. 'This section makes the calendar graph.
  91. make:
  92. SCREEN _NEWIMAGE(800, 600, 32)
  93. LINE (0, 0)-(800, 600), _RGB32(255, 255, 255), BF
  94. _TITLE "Press 'S' to Save, 'P' to Print (can do again for copy), Space Bar to make another calendar, or 'Esc' to quit."
  95. COLOR _RGB32(0, 0, 0), _RGB32(255, 255, 255)
  96. LOCATE 3, 42: PRINT month$; "  "; yy
  97.  
  98. FOR x = 20 TO 780 STEP 108
  99.     LINE (x, 100)-(x, 580), _RGB32(0, 0, 0)
  100. FOR z = 100 TO 580 STEP 80
  101.     LINE (16, z)-(780, z), _RGB32(0, 0, 0)
  102.  
  103. LOCATE 5, 8: PRINT "SUNDAY"
  104. LOCATE 5, 21: PRINT "MONDAY"
  105. LOCATE 5, 34: PRINT "TUESDAY"
  106. LOCATE 5, 47: PRINT "WEDNESDAY"
  107. LOCATE 5, 60: PRINT "THURSDAY"
  108. LOCATE 5, 75: PRINT "FRIDAY"
  109. LOCATE 5, 87: PRINT "SATURDAY"
  110.  
  111. 'Finding Date of Easter
  112. PQA = yy
  113. GOSUB PAQUES
  114. 'month = PQM, day = PQJ, year = PQA
  115.  
  116. 'This section puts the right dates and holidays in the right squares for the calendar.
  117. w = (weekday * 108) + 25
  118. FOR weeky = 110 TO 570 STEP 80
  119.     FOR dayx = w TO 692 STEP 108
  120.         _LIMIT 1000
  121.         dd = dd + 1
  122.         GetDay mm, dd, y, weekday
  123.         dd$ = STR$(dd)
  124.         _FONT 16
  125.         _PRINTSTRING (dayx, weeky), dd$
  126.         _FONT 8
  127.         IF m = 1 AND dd = 1 THEN _PRINTSTRING (dayx + 10, weeky + 60), "New Years":
  128.         IF m = 1 AND weekday = 2 AND dd > 14 AND dd < 22 THEN _PRINTSTRING (dayx + 25, weeky + 60), "MLK Jr."
  129.         IF m = 2 AND weekday = 2 AND dd > 14 AND dd < 22 THEN _PRINTSTRING (dayx + 10, weeky + 60), "Presidents"
  130.         IF m = 2 AND dd = 14 THEN _PRINTSTRING (dayx + 10, weeky + 60), "Valentines"
  131.         IF m = PQM AND dd = PQJ THEN _PRINTSTRING (dayx + 25, weeky + 60), "Easter"
  132.         IF m = 5 AND weekday = 2 AND dd > 24 THEN _PRINTSTRING (dayx + 15, weeky + 60), "Memorial"
  133.         IF m = 7 AND dd = 4 THEN _PRINTSTRING (dayx, weeky + 60), "Independence"
  134.         IF m = 9 AND weekday = 2 AND dd < 8 THEN _PRINTSTRING (dayx + 25, weeky + 60), "Labor"
  135.         IF m = 10 AND dd > 9 AND dd < 16 AND weekday = 2 THEN _PRINTSTRING (dayx + 15, weeky + 60), "Columbus"
  136.         IF m = 10 AND dd = 31 THEN _PRINTSTRING (dayx + 15, weeky + 60), "Halloween"
  137.         IF m = 11 AND dd = 11 THEN _PRINTSTRING (dayx + 15, weeky + 60), "Veterans"
  138.         IF m = 11 AND dd > 21 AND dd < 29 AND weekday = 5 THEN _PRINTSTRING (dayx, weeky + 60), "Thanksgiving"
  139.         IF m = 12 AND dd = 25 THEN _PRINTSTRING (dayx + 15, weeky + 60), "Christmas"
  140.  
  141.         IF dd = days THEN _FONT 16: GOTO more2:
  142.     NEXT dayx
  143.     w = 25
  144. NEXT weeky
  145.  
  146. more2:
  147. _LIMIT 1000
  148. a$ = INKEY$
  149. IF a$ = CHR$(27) THEN CLS: PRINT: PRINT: PRINT "Goodbye.": END
  150. IF a$ = "s" OR a$ = "S" THEN GOTO saving:
  151. IF a$ = " " THEN GOTO start:
  152. IF a$ = "p" OR a$ = "P" THEN
  153.     'printer prep (code copied and pasted from bplus Free Calendar Program)
  154.     YMAX = _HEIGHT: XMAX = _WIDTH
  155.     landscape& = _NEWIMAGE(YMAX, XMAX, 32)
  156.     _MAPTRIANGLE (XMAX, 0)-(0, 0)-(0, YMAX), 0 TO(0, 0)-(0, XMAX)-(YMAX, XMAX), landscape&
  157.     _MAPTRIANGLE (XMAX, 0)-(XMAX, YMAX)-(0, YMAX), 0 TO(0, 0)-(YMAX, 0)-(YMAX, XMAX), landscape&
  158.     _PRINTIMAGE landscape&
  159.  
  160. GOTO more2:
  161.  
  162.  
  163. 'Find the right date for Easter.
  164. PAQUES:
  165. PQM = INT(PQA / 100): PQ1 = PQA - PQM * 100: PQJ = INT(((PQA / 19 - INT(PQA / 19)) + .001) * 19)
  166. PQ2 = INT(PQM / 4): PQ3 = INT(((PQM / 4) - PQ2 + .001) * 4): PQ4 = INT((8 + PQM) / 25)
  167. PQ5 = INT((1 + PQM - PQ4 + .001) / 3): PQ4 = (15 + 19 * PQJ + PQM - PQ2 - PQ5 + .001) / 30: PQ4 = PQ4 - INT(PQ4)
  168. PQ4 = INT(PQ4 * 30): PQ5 = INT(PQ1 / 4): PQ6 = ((PQ1 / 4) - PQ5) * 4
  169. PQ7 = (32 + 2 * PQ3 + 2 * PQ5 - PQ4 - PQ6 + .001) / 7: PQ7 = (PQ7 - INT(PQ7)) * 7: PQ6 = (PQJ + 11 * PQ4 + 22 * PQ7) / 451
  170. PQ6 = INT(PQ6): PQ2 = (114 + PQ4 + PQ7 - 7 * PQ6) / 31: PQM = INT(PQ2): PQJ = INT((PQ2 - PQM + .001) * 31 + 1)
  171.  
  172.  
  173. 'This section saves the calendar to a JPG file along with the SUB at the end of this program.
  174. saving:
  175. mo$ = STR$(m)
  176. mo$ = LTRIM$(RTRIM$(mo$))
  177. year$ = STR$(yy)
  178. year$ = LTRIM$(RTRIM$(year$))
  179. nm$ = mo$ + "-"
  180. nm$ = LTRIM$(RTRIM$(nm$))
  181. nm$ = nm$ + year$
  182. nm$ = LTRIM$(RTRIM$(nm$))
  183. SaveImage 0, nm$ 'saves entire program screen,"
  184. nm2$ = nm$ + ".jpg"
  185. nm2$ = LTRIM$(RTRIM$(nm2$))
  186. PRINT "                                           Saving"
  187. PRINT "                          "; nm2$; " has been saved to your computer."
  188. INPUT "                         Do you wish to make another calendar (Y/N)"; ag$
  189. IF LEFT$(ag$, 1) = "y" OR LEFT$(ag$, 1) = "Y" THEN GOTO start:
  190. PRINT "                         Goodbye."
  191.  
  192. weekdays:
  193.  
  194. 'This section gets the right weekday.
  195. SUB GetDay (mm, dd, y, weekday) 'use 4 digit year
  196.     'From Zeller's congruence: https://en.wikipedia.org/wiki/Zeller%27s_congruence
  197.     IF mm < 3 THEN mm = mm + 12: y = y - 1
  198.     century = y MOD 100
  199.     zerocentury = y \ 100
  200.     weekday = (dd + INT(13 * (mm + 1) / 5) + century + INT(century / 4) + INT(zerocentury / 4) + 5 * zerocentury) MOD 7
  201.  
  202. 'This section saves the .jpg picture file.
  203. SUB SaveImage (image AS LONG, filename AS STRING)
  204.     bytesperpixel& = _PIXELSIZE(image&)
  205.     IF bytesperpixel& = 0 THEN PRINT "Text modes unsupported!": END
  206.     IF bytesperpixel& = 1 THEN bpp& = 8 ELSE bpp& = 24
  207.     x& = _WIDTH(image&)
  208.     y& = _HEIGHT(image&)
  209.     b$ = "BM????QB64????" + MKL$(40) + MKL$(x&) + MKL$(y&) + MKI$(1) + MKI$(bpp&) + MKL$(0) + "????" + STRING$(16, 0) 'partial BMP header info(???? to be filled later)
  210.     IF bytesperpixel& = 1 THEN
  211.         FOR c& = 0 TO 255 ' read BGR color settings from JPG image + 1 byte spacer(CHR$(0))
  212.             cv& = _PALETTECOLOR(c&, image&) ' color attribute to read.
  213.             b$ = b$ + CHR$(_BLUE32(cv&)) + CHR$(_GREEN32(cv&)) + CHR$(_RED32(cv&)) + CHR$(0) 'spacer byte
  214.         NEXT
  215.     END IF
  216.     MID$(b$, 11, 4) = MKL$(LEN(b$)) ' image pixel data offset(BMP header)
  217.     lastsource& = _SOURCE
  218.     _SOURCE image&
  219.     IF ((x& * 3) MOD 4) THEN padder$ = STRING$(4 - ((x& * 3) MOD 4), 0)
  220.     FOR py& = y& - 1 TO 0 STEP -1 ' read JPG image pixel color data
  221.         r$ = ""
  222.         FOR px& = 0 TO x& - 1
  223.             c& = POINT(px&, py&) 'POINT 32 bit values are large LONG values
  224.             IF bytesperpixel& = 1 THEN r$ = r$ + CHR$(c&) ELSE r$ = r$ + LEFT$(MKL$(c&), 3)
  225.         NEXT px&
  226.         d$ = d$ + r$ + padder$
  227.     NEXT py&
  228.     _SOURCE lastsource&
  229.     MID$(b$, 35, 4) = MKL$(LEN(d$)) ' image size(BMP header)
  230.     b$ = b$ + d$ ' total file data bytes to create file
  231.     MID$(b$, 3, 4) = MKL$(LEN(b$)) ' size of data file(BMP header)
  232.     IF LCASE$(RIGHT$(filename$, 4)) <> ".jpg" THEN ext$ = ".jpg"
  233.     f& = FREEFILE
  234.     OPEN filename$ + ext$ FOR OUTPUT AS #f&: CLOSE #f& ' erases an existing file
  235.     OPEN filename$ + ext$ FOR BINARY AS #f&
  236.     PUT #f&, , b$
  237.     CLOSE #f&
  238.  
  239.  
« Last Edit: August 06, 2019, 03:38:52 pm by SierraKen »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Calendar Maker
« Reply #14 on: August 05, 2019, 11:34:05 pm »
Nope.  It’s part of the SCREEN syntax.

SCREEN imagehandle& [, , active_page, visual_page]

Though I’m not exactly certain what the ,p& parameter represents.


https://www.qbasic.net/en/reference/qb11/Statement/SCREEN.htm

Color setting?

Doesn’t look like QB64 supports that parameter, which is why it lists the command as: SCREEN {mode%|imagehandle&} , , active_page, visual_page]

(See the comma comma with nothing between it?

Aha! now I get it, it's a part of SCREEN sub call, actually that line I have always been using makes more sense to me now. Thanks Steve.


Hi, Ken,

I thought you might like that change. :)