Author Topic: Spell It Aloud (Help Requested)  (Read 11154 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Spell It Aloud (Help Requested)
« Reply #30 on: August 03, 2019, 05:35:34 am »
This easy and very stupid code show, what i mean, if i say, that ON TIMER get out in middle in the loop:

Code: QB64: [Select]
  1. ON TIMER(1) GOSUB timerdone
  2.     FOR f = 1 TO 500000
  3.     NEXT f
  4.  
  5. timerdone: PRINT "For next loop value is:"; f
  6.  

Sometimes, you want to be able to pop in and out of the middle of a loop.

Code: [Select]
DIM f AS LONG
ON TIMER(.1) GOSUB timerdone
TIMER ON
DO
    c = (c + 1) MOD 16
    COLOR c
    PRINT "COLOR "; c,
    _LIMIT 10 'no need to use a lot of CPU; we're going to handle things VIA the timed routine
LOOP

timerdone:
IF NOT paused THEN
    f = f + 1
    PRINT "For next loop value is:"; f
END IF
k = _KEYHIT
IF k = 32 THEN GOSUB pausetimer

RETURN

pausetimer:
paused = NOT paused
RETURN

The above is a very simple demo of how things might interact so that we do one thing (the main process), while still using ON TIMER as a means to handle control of other processes.

In the Spell It code I posted above, the SUB UserInput reads mouse/keystrokes via an ON TIMER routine, and by utilizing its ability to jump out of the middle of loops/subs, we can use it as a ready means to set control flags so we can stop the sound playing at any point in the process.

Code: [Select]
        _SNDPLAY AlphaSound(a)
        WHILE _SNDPLAYING(AlphaSound(a)) 'wait for sound to finish before playing again
            _LIMIT 10 'play nice with CPU during wait
            IF ControlVariable1 THEN _SNDSTOP (AlphaSound(a))
        WEND

ControlVariable1 can be set in the ON TIMER routine, and when set, we stop the sound and simply wait for the next process to be initiated by the user.  (play, next, quit, ect...)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Spell It Aloud (Help Requested)
« Reply #31 on: August 03, 2019, 05:51:45 am »
 Steve.... i am very curious. How is this possible?

I am on the end in your source code in new compiled IDE with support for your new metacommand $color and give this screen.... Line 579 not exists, maximal row value in source code is 501...



if i comment your new metacommand, i find next bug - you use none LOF(1) control in SUB ChangeSearchTags, so, if is user idiot, so as me, and copy your Spell source code to new installation dir without needed subdirectories, so it generate Input past end of file on row 309 :)


image with your source code so, as it, with missing subdirectories for Spell program:

 
Error.jpg

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Spell It Aloud (Help Requested)
« Reply #32 on: August 03, 2019, 05:55:21 am »
Thank you for your ON Timer example!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Spell It Aloud (Help Requested)
« Reply #33 on: August 03, 2019, 06:08:18 am »
Steve.... i am very curious. How is this possible?

It's actually a glitch which I didn't notice in the last BAS file I posted earlier.

If you open QB64.bas (which you downloaded from earlier), do a quick search for $COLOR32.  At line 2981, you'll see where there's:

Code: [Select]
        IF a3u$ = "$COLOR32" THEN
            ColorHack = -1

This is where QB64 is now parsing the metacommand for $COLOR32.  What it's doing is very simple -- it's actually just injecting those lines into your code (much like a native $INCLUDE statement would), and adding them to your available CONST list...

The glitch is rather simple:  I didn't bother to parse those statements and add the values manually to the CONST list (it's a bunch of different TYPE values which we use to track them), since QB64 already parses and deals with them for us, as it reads our code.  The glitch is that each time it processes them, it adds to the linecount for them -- all 200+ times!

Fix is really simple:

Add a line for:             oldlinenumber = linenumber to the start of that IF block, and then             linenumber = oldlinenumber to the end of that IF block (right before the GOTO which continues processing the rest of our code.

So that error you're getting isn't past the end of the file; your internal line counter is just off, until that one little glitch is corrected.

(There's always something simple like this, which is overlooked when making changes, which is why we have a development build for people to test these things, and a stable build so they don't have to worry about them.)  ;D
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Spell It Aloud (Help Requested)
« Reply #34 on: August 03, 2019, 06:27:48 am »
So rewrited, QB64 recompiled, re-tested and now it is ok. Please add to your Speel program to row 307 something as this:

Code: QB64: [Select]
  1.   IF LOF(1) = 0 THEN PRINT "Missing program directories!": SLEEP 3: SYSTEM
  2.  


We are going to have lunch, I will work with it again later.

FellippeHeitor

  • Guest
Re: Spell It Aloud (Help Requested)
« Reply #35 on: August 03, 2019, 09:41:23 am »
It's actually a glitch which I didn't notice in the last BAS file I posted earlier.

If you open QB64.bas (which you downloaded from earlier), do a quick search for $COLOR32.  At line 2981, you'll see where there's:

Code: [Select]
        IF a3u$ = "$COLOR32" THEN
            ColorHack = -1

This is where QB64 is now parsing the metacommand for $COLOR32.  What it's doing is very simple -- it's actually just injecting those lines into your code (much like a native $INCLUDE statement would), and adding them to your available CONST list...

The glitch is rather simple:  I didn't bother to parse those statements and add the values manually to the CONST list (it's a bunch of different TYPE values which we use to track them), since QB64 already parses and deals with them for us, as it reads our code.  The glitch is that each time it processes them, it adds to the linecount for them -- all 200+ times!

Fix is really simple:

Add a line for:             oldlinenumber = linenumber to the start of that IF block, and then             linenumber = oldlinenumber to the end of that IF block (right before the GOTO which continues processing the rest of our code.

So that error you're getting isn't past the end of the file; your internal line counter is just off, until that one little glitch is corrected.

(There's always something simple like this, which is overlooked when making changes, which is why we have a development build for people to test these things, and a stable build so they don't have to worry about them.)  ;D

Might also be a good idea to only inject the CONST declarations if ColorHack = 0.

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Spell It Aloud (Help Requested)
« Reply #36 on: August 03, 2019, 10:24:06 am »
Steve, this is another suggestion to change your function so that the input can be end by next click anywhere you want. (so you can not using enter only)

Code: QB64: [Select]
  1. FUNCTION ChangeValue$ (x, y, word$, limit)
  2.     TIMER(Timer1) OFF
  3.     S = SaveState
  4.     _FONT 16
  5.     temp$ = CHR$(179)
  6.     _KEYCLEAR
  7.     DO UNTIL state = 2
  8.         Box x, y, 100, 20, 1, Black, Gold
  9.         CenterText x, y, x + 100, y + 20, temp$
  10.         WHILE _MOUSEINPUT: WEND
  11.         IF _MOUSEBUTTON(1) THEN
  12.             state = state + 1
  13.             DO UNTIL _MOUSEBUTTON(1) = 0
  14.                 WHILE _MOUSEINPUT: WEND
  15.             LOOP
  16.         END IF
  17.  
  18.         k = _KEYHIT
  19.         SELECT CASE k
  20.             CASE 8
  21.                 word$ = LEFT$(word$, LEN(word$) - 1)
  22.             CASE 13
  23.                 EXIT DO
  24.             CASE 48 TO 57 'We'll always accept numeric input
  25.                 word$ = word$ + CHR$(k)
  26.             CASE 65 TO 90, 97 TO 122 'A-Z (a-z) only when we're dealing with a string
  27.                 IF NOT limit THEN word$ = word$ + CHR$(k)
  28.         END SELECT
  29.         temp$ = word$ + CHR$(179)
  30.         _LIMIT 10
  31.     LOOP
  32.     ChangeValue$ = word$
  33.     RestoreState S
  34.     DisplayTags 575, 150, "Search Tags (" + _TRIM$(STR$(PhotoCount)) + ")", LimitTag
  35.     DisplayTags 575, 300, "Photo Tags", PhotoTag
  36.  
  37.     TIMER(Timer1) ON
  38.  

I must upgrading my version in own way, because in your new source is too many news.
« Last Edit: August 03, 2019, 10:27:53 am by Petr »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Spell It Aloud (Help Requested)
« Reply #37 on: August 03, 2019, 11:16:05 am »
Steve, I removed DELAY 1 on SUB PlayLetters and added mouse input control  when is playback, and I have the same speed  without TIMER. Is the intention that the first and third blocks in PlayLetters for playback are the same?

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Spell It Aloud (Help Requested)
« Reply #38 on: August 04, 2019, 01:06:51 am »
Here's a different version for you, Petr, without the ON TIMER routines to handle input:

Code: QB64: [Select]
  1. $COLOR32
  2.  
  3. TYPE TagType
  4.     Year AS INTEGER
  5.     Week AS INTEGER
  6.     Theme AS STRING
  7.  
  8. SCREEN _NEWIMAGE(800, 600, 32)
  9. _TITLE "Spell It Aloud"
  10.  
  11. CONST ImageDir$ = ".\Images\"
  12. CONST SoundDir$ = ".\Alphabet Sounds\"
  13. CONST TagDir$ = ".\Image Tags\"
  14. CONST WordSoundDir$ = ".\Word Sounds\"
  15.  
  16. DIM SHARED PhotoTag AS TagType
  17. DIM SHARED LimitTag AS TagType
  18.  
  19. DIM SHARED AlphaSound(65 TO 90)
  20. REDIM SHARED PhotoList(100000) AS STRING
  21. REDIM SHARED WordList(0) AS LONG
  22. DIM SHARED PhotoCount AS LONG
  23. DIM SHARED PhotoChosen AS LONG
  24. DIM SHARED IsHowYouSpell AS LONG
  25. DIM SHARED ControlVariable1 AS LONG
  26. DIM SHARED ShowNext AS LONG
  27.  
  28.  
  29. 'load our fonts
  30. f = _LOADFONT("courbd.ttf", 84, "MONOSPACE")
  31. f1 = _LOADFONT("courbd.ttf", 48, "MONOSPACE")
  32.  
  33.  
  34. 'Load the alphabet sound library
  35. FOR i = 65 TO 90
  36.     temp$ = SoundDir$ + CHR$(i) + ".ogg"
  37.     AlphaSound(i) = _SNDOPEN(temp$, "VOL,SYNC,LEN,PAUSE")
  38. temp$ = WordSoundDir$ + "is how you spell.ogg"
  39. IsHowYouSpell = _SNDOPEN(temp$, "VOL,SYNC,LEN,PAUSE")
  40.  
  41.  
  42. _DELAY 1 'Give everything a moment to initialize and get started for us.
  43. WordList(0) = 3 'three times repeating the list, as default
  44. ChangeSearchTags
  45. ShowNext = -1
  46.  
  47.     ControlVariable = 0
  48.     MB = mouseclick
  49.     Mx = _MOUSEX: My = _MOUSEY
  50.     IF MB THEN
  51.         IF Mx >= 650 AND Mx <= 750 THEN 'the mouse is in the correct X area for input
  52.             SELECT CASE My
  53.                 CASE 171 TO 190
  54.                     temp$ = ChangeValue(650, 171, STR$(LimitTag.Year), -1)
  55.                     LimitTag.Year = VAL(temp$)
  56.                     ChangeSearchTags
  57.                     ShowNext = -1
  58.                 CASE 191 TO 210
  59.                     temp$ = ChangeValue(650, 191, STR$(LimitTag.Week), -1)
  60.                     LimitTag.Week = VAL(temp$)
  61.                     ChangeSearchTags
  62.                     ShowNext = -1
  63.                 CASE 211 TO 230
  64.                     temp$ = ChangeValue(650, 211, LimitTag.Sound, 0)
  65.                     LimitTag.Sound = temp$
  66.                     ChangeSearchTags
  67.                     ShowNext = -1
  68.                 CASE 231 TO 250
  69.                     temp$ = ChangeValue(650, 231, LimitTag.Theme, 0)
  70.                     LimitTag.Theme = temp$
  71.                     ChangeSearchTags
  72.                     ShowNext = -1
  73.                 CASE 324 TO 340
  74.                     PhotoTag.Year = VAL(ChangeValue(650, 324, STR$(PhotoTag.Year), -1))
  75.                     ChangePhotoTags word$
  76.                     ShowNext = -1: ControlVariable1 = -1
  77.                 CASE 341 TO 360
  78.                     PhotoTag.Week = VAL(ChangeValue(650, 341, STR$(PhotoTag.Week), -1))
  79.                     ChangePhotoTags word$
  80.                     ShowNext = -1: ControlVariable1 = -1
  81.                 CASE 361 TO 380
  82.                     PhotoTag.Sound = ChangeValue(650, 361, PhotoTag.Sound, 0)
  83.                     ChangePhotoTags word$
  84.                     ShowNext = -1: ControlVariable1 = -1
  85.                 CASE 381 TO 400
  86.                     PhotoTag.Theme = ChangeValue(650, 381, PhotoTag.Theme, 0)
  87.                     ChangePhotoTags word$
  88.                     ShowNext = -1: ControlVariable1 = -1
  89.             END SELECT
  90.         END IF
  91.         IF _MOUSEY > 450 AND _MOUSEY < 470 THEN 'it's the right Y pos for the top control buttons
  92.             SELECT CASE _MOUSEX
  93.                 CASE 575 TO 640 'Last
  94.                     PhotoChosen = PhotoChosen - 1
  95.                     IF PhotoChosen < 1 THEN PhotoChosen = UBOUND(WordList)
  96.                     ShowNext = -1
  97.                 CASE 641 TO 705 'Play
  98.                     ShowNext = -1
  99.                 CASE 706 TO 770 'Next
  100.                     PhotoChosen = PhotoChosen + 1
  101.                     IF PhotoChosen > UBOUND(WordList) THEN PhotoChosen = 1
  102.                     ShowNext = -1
  103.             END SELECT
  104.         ELSEIF _MOUSEY > 471 AND _MOUSEY < 491 THEN 'it's the right Y pos for the 2nd row of control buttons
  105.             SELECT CASE _MOUSEX
  106.                 CASE 575 TO 640 'Vol not yet implemented
  107.                 CASE 641 TO 705 'Stop now handled via the sound sub
  108.                 CASE 706 TO 770: SYSTEM 'Quit
  109.             END SELECT
  110.         END IF
  111.     END IF
  112.  
  113.     k = _KEYHIT
  114.     SELECT CASE k
  115.         CASE 32 'space for next picture
  116.             PhotoChosen = PhotoChosen + 1
  117.             IF PhotoChosen > WordList(0) THEN PhotoChosen = 1
  118.             ShowNext = -1
  119.         CASE 27 'escape
  120.             SYSTEM 'quit
  121.     END SELECT
  122.  
  123.     IF ShowNext THEN
  124.         ShowNext = 0
  125.         IF PhotoChosen THEN
  126.             temp$ = PhotoList(WordList(PhotoChosen))
  127.             word$ = MID$(temp$, _INSTRREV(temp$, "\") + 1)
  128.             word$ = LEFT$(word$, INSTR(word$, ".") - 1)
  129.  
  130.             IF tempimage <> 0 THEN _FREEIMAGE tempimage 'free the old image
  131.             tempimage = _LOADIMAGE(temp$, 32) 'get the new image
  132.  
  133.             CLS
  134.             _FONT f1: CenterText 0, 0, 800, 50, "Spell It Aloud": _FONT f
  135.  
  136.             'program photo area is 500 x 450 pixels. So:
  137.             GetNewWH 500, 450, tempimage, nW, nH
  138.             _PUTIMAGE (300 - (nW / 2), 300 - (nH / 2) - 25)-STEP(nW, nH), tempimage
  139.  
  140.             LoadPhotoTags word$
  141.             temp$ = "Search Tags (" + _TRIM$(STR$(PhotoChosen)) + " of " + _TRIM$(STR$(UBOUND(WordList))) + ")"
  142.             DisplayTags 575, 150, temp$, LimitTag
  143.             DisplayTags 575, 300, "Photo Tags", PhotoTag
  144.             DrawCommandBoxes
  145.             IF ControlVariable1 = 0 THEN PlayLetters word$
  146.         ELSE
  147.             DrawNoMatches
  148.         END IF
  149.         ControlVariable1 = 0
  150.     END IF
  151.     _LIMIT 10
  152.     _DISPLAY
  153.  
  154. SUB DrawCommandBoxes
  155.     s = SaveState
  156.     _FONT 16
  157.     COLOR Black, 0
  158.     BoxTitle 575, 450, 640, 470, 2, BlueGray, Gold, "LAST"
  159.     BoxTitle 641, 450, 705, 470, 2, BlueGray, Gold, "PLAY"
  160.     BoxTitle 706, 450, 770, 470, 2, BlueGray, Gold, "NEXT"
  161.     BoxTitle 575, 471, 640, 490, 2, BlueGray, Gold, "VOL"
  162.     COLOR Maroon
  163.     BoxTitle 641, 471, 705, 490, 2, BlueGray, Gold, "STOP"
  164.     COLOR Yellow
  165.     BoxTitle 706, 471, 770, 490, 2, BlueGray, Gold, "QUIT"
  166.  
  167.     RestoreState s
  168.  
  169. SUB BoxTitle (x1, y1, x2, y2, thick, fg AS _UNSIGNED LONG, bg AS _UNSIGNED LONG, title$)
  170.     Box x1, y1, x2 - x1 + 1, y2 - y1 + 1, thick, fg, bg
  171.     CenterText x1, y1 + thick, x2, y2 + thick, title$
  172.  
  173. SUB DrawNoMatches
  174.     S = SaveState
  175.     CLS
  176.     _FONT f1
  177.     Box 50, 50, 500, 500, 5, Silver, Gold
  178.     CenterText 0, 0, 800, 50, "Spell It Aloud"
  179.     FOR i = 1 TO 10 STEP .5
  180.         CIRCLE (300, 300), 200 - i, BrickRed
  181.         LINE (300 + SIN(_D2R(-45)) * 198 + i, 300 + COS(_D2R(-45)) * 198 + i)-(300 + SIN(_D2R(135)) * 198 + i, 300 + COS(_D2R(135)) * 198 + i), BrickRed
  182.     NEXT
  183.     COLOR Yellow, 0
  184.     CenterText 50, 50, 550, 550, "No Matches"
  185.     PhotoTag.Year = 0
  186.     PhotoTag.Week = 0
  187.     PhotoTag.Sound = ""
  188.     PhotoTag.Theme = ""
  189.     DisplayTags 575, 150, "Search Tags (0)", LimitTag
  190.     DisplayTags 575, 300, "Photo Tags", PhotoTag
  191.     RestoreState S
  192.  
  193.  
  194.  
  195. SUB PlayLetters (word$)
  196.     'Put the letters to the screen one by one
  197.     ControlVariable1 = 0
  198.     pw = _PRINTWIDTH(word$): StartX = (600 - pw) \ 2 'center position
  199.  
  200.     FOR i = 1 TO LEN(word$)
  201.         a = ASC(word$, i) AND NOT 32 'play lowercase letters as uppercase sounds
  202.         _PRINTSTRING (StartX + (i - 1) * _FONTWIDTH, 510), CHR$(a)
  203.         _DISPLAY
  204.         IF a < 65 OR a > 90 THEN _CONTINUE 'ignore non-letters in the file name
  205.         _SNDPLAY AlphaSound(a)
  206.         WHILE _SNDPLAYING(AlphaSound(a)) 'wait for sound to finish before playing again
  207.             _LIMIT 10 'play nice with CPU during wait
  208.             GOSUB checkstop
  209.             IF ControlVariable1 THEN _SNDSTOP (AlphaSound(a))
  210.         WEND
  211.     NEXT
  212.     IF ContolVariable1 = 0 THEN
  213.         temp$ = WordSoundDir$ + word$ + ".ogg"
  214.         IF _FILEEXISTS(temp$) THEN
  215.             _SNDVOL IsHowYouSpell, .5
  216.             _SNDPLAY IsHowYouSpell
  217.             WHILE _SNDPLAYING(IsHowYouSpell) 'wait for sound to finish before playing again
  218.                 _LIMIT 10 'play nice with CPU during wait
  219.                 GOSUB checkstop
  220.                 IF ControlVariable1 THEN _SNDSTOP (IsHowYouSpell): EXIT SUB
  221.             WEND
  222.  
  223.             temp = _SNDOPEN(temp$, "VOL,SYNC,LEN,PAUSE")
  224.             _SNDPLAY temp
  225.             WHILE _SNDPLAYING(temp) 'wait for sound to finish before playing again
  226.                 _LIMIT 10 'play nice with CPU during wait
  227.                 GOSUB checkstop
  228.                 IF ControlVariable1 THEN _SNDCLOSE temp: EXIT SUB
  229.             WEND
  230.             _SNDCLOSE temp
  231.  
  232.             FOR i = 1 TO LEN(word$)
  233.                 a = ASC(word$, i) AND NOT 32 'play lowercase letters as uppercase sounds
  234.                 _PRINTSTRING (StartX + (i - 1) * _FONTWIDTH, 510), CHR$(a)
  235.                 IF a < 65 OR a > 90 THEN _CONTINUE 'ignore non-letters in the file name
  236.                 _SNDPLAY AlphaSound(a)
  237.                 WHILE _SNDPLAYING(AlphaSound(a)) 'wait for sound to finish before playing again
  238.                     _LIMIT 10 'play nice with CPU during wait
  239.                     GOSUB checkstop
  240.                     IF ControlVariable1 THEN EXIT SUB
  241.                 WEND
  242.             NEXT
  243.         END IF
  244.     END IF
  245.  
  246.     EXIT SUB
  247.  
  248.     checkstop:
  249.         IF _MOUSEY > 451 AND _MOUSEY < 491 THEN
  250.             IF _MOUSEX > 575 AND _MOUSEX < 770 THEN 'stop
  251.                 ControlVariable1 = -1 'Stop Command for playing the word
  252.             END IF
  253.         END IF
  254.     END IF
  255.     RETURN
  256.  
  257.  
  258. SUB ChangePhotoTags (word$)
  259.     'Get a listing of the files
  260.     file$ = TagDir$ + word$ + ".txt"
  261.     OPEN file$ FOR OUTPUT AS #1
  262.     PRINT #1, PhotoTag.Year
  263.     PRINT #1, PhotoTag.Week
  264.     PRINT #1, PhotoTag.Sound
  265.     PRINT #1, PhotoTag.Theme
  266.     CLOSE
  267.  
  268. SUB LoadPhotoTags (word$)
  269.     file$ = TagDir$ + word$ + ".txt"
  270.     IF _FILEEXISTS(file$) THEN
  271.         OPEN file$ FOR INPUT AS #1
  272.         INPUT #1, PhotoTag.Year
  273.         INPUT #1, PhotoTag.Week
  274.         INPUT #1, PhotoTag.Sound
  275.         INPUT #1, PhotoTag.Theme
  276.         CLOSE
  277.     ELSE
  278.         PhotoTag.Year = 0
  279.         PhotoTag.Week = 0
  280.         PhotoTag.Sound = ""
  281.         PhotoTag.Theme = ""
  282.         IF word$ <> "" THEN ChangePhotoTags word$
  283.     END IF
  284.  
  285.  
  286. SUB ChangeSearchTags
  287.     'Get a listing of the files
  288.     PhotoList$ = ImageDir$ + "*.bmp " + ImageDir$ + "*.jpg " + ImageDir$ + "*.png " + ImageDir$ + "*.gif "
  289.     SHELL _HIDE "DIR " + PhotoList$ + "/b /s /a-d >PhotoList.txt"
  290.  
  291.     REDIM _PRESERVE PhotoList(100000)
  292.     'Load those names into a file.
  293.     OPEN "Photolist.txt" FOR BINARY AS #1
  294.     PhotoCount = 0
  295.     DO UNTIL EOF(1)
  296.         LINE INPUT #1, fullpath$
  297.         word$ = MID$(fullpath$, _INSTRREV(fullpath$, "\") + 1)
  298.         word$ = LEFT$(word$, INSTR(word$, ".") - 1)
  299.  
  300.         file$ = TagDir$ + word$ + ".txt"
  301.         IF _FILEEXISTS(file$) THEN
  302.             OPEN file$ FOR INPUT AS #2
  303.             INPUT #2, PhotoTag.Year
  304.             INPUT #2, PhotoTag.Week
  305.             INPUT #2, PhotoTag.Sound
  306.             INPUT #2, PhotoTag.Theme
  307.         ELSE
  308.             OPEN file$ FOR OUTPUT AS #2
  309.             PRINT #2, 0
  310.             PRINT #2, 0
  311.             PRINT #2, ""
  312.             PRINT #2, ""
  313.         END IF
  314.         CLOSE #2
  315.         good = -1
  316.         IF LimitTag.Year <> 0 AND LimitTag.Year <> PhotoTag.Year THEN good = 0
  317.         IF LimitTag.Week <> 0 AND LimitTag.Week <> PhotoTag.Week THEN good = 0
  318.  
  319.         IF LimitTag.Sound <> "" AND LimitTag.Sound <> PhotoTag.Sound THEN good = 0
  320.         IF LimitTag.Theme <> "" AND LimitTag.Theme <> PhotoTag.Theme THEN good = 0
  321.         IF good THEN
  322.             PhotoCount = PhotoCount + 1
  323.             PhotoList(PhotoCount) = fullpath$
  324.         END IF
  325.     LOOP
  326.     REDIM _PRESERVE PhotoList(PhotoCount)
  327.     CLOSE
  328.     MakeList
  329.  
  330. SUB MakeList
  331.     RepeatCount = WordList(0)
  332.     REDIM WordList(PhotoCount * RepeatCount) AS LONG
  333.     WordList(0) = RepeatCount
  334.     IF UBOUND(wordlist) > 0 THEN
  335.         PhotoChosen = 1
  336.     ELSE
  337.         PhotoChosen = 0
  338.         EXIT SUB
  339.     END IF
  340.     DIM TempList(PhotoCount) AS LONG
  341.     FOR i = 1 TO PhotoCount
  342.         TempList(i) = i
  343.     NEXT
  344.     FOR i = 1 TO RepeatCount
  345.         FOR j = 1 TO PhotoCount
  346.             r = INT(RND * PhotoCount) + 1
  347.             SWAP TempList(j), TempList(r)
  348.         NEXT
  349.         FOR j = 1 TO PhotoCount
  350.             Count = Count + 1
  351.             WordList(Count) = TempList(j)
  352.         NEXT
  353.     NEXT
  354.  
  355. FUNCTION ChangeValue$ (x, y, tword$, limit)
  356.     S = SaveState
  357.     _FONT 16
  358.     temp$ = CHR$(179)
  359.     _KEYCLEAR
  360.     DO
  361.         Box x, y, 100, 20, 1, Black, Gold
  362.         CenterText x, y, x + 100, y + 20, temp$
  363.         k = _KEYHIT
  364.         SELECT CASE k
  365.             CASE 8
  366.                 tword$ = LEFT$(tword$, LEN(tword$) - 1)
  367.             CASE 13
  368.                 EXIT DO
  369.             CASE 48 TO 57 'We'll always accept numeric input
  370.                 tword$ = tword$ + CHR$(k)
  371.             CASE 65 TO 90, 97 TO 122 'A-Z (a-z) only when we're dealing with a string
  372.                 IF NOT limit THEN tword$ = tword$ + CHR$(k)
  373.         END SELECT
  374.         temp$ = tword$ + CHR$(179)
  375.         _LIMIT 10
  376.         DisplayTags 575, 150, "Search Tags (" + _TRIM$(STR$(PhotoCount)) + ")", LimitTag
  377.         DisplayTags 575, 300, "Photo Tags", PhotoTag
  378.     LOOP
  379.     ChangeValue$ = tword$
  380.     RestoreState S
  381.  
  382. SUB DisplayTags (x, y, Title AS STRING, DisplayTag AS TagType)
  383.     S = SaveState
  384.     _FONT 16
  385.     W = 200: h = 106
  386.     Box x, y, W, h, 2, BlueGray, Gold
  387.     COLOR Gold, 0
  388.     CenterText x, y + 2, x + 200, y + 20, Title
  389.     LINE (x + 1, y + 19)-STEP(W - 2, 0), Gold
  390.     COLOR White, 0
  391.     xs = x + 24: ys = y + 24 'x/y start after the box offset
  392.     _PRINTSTRING (xs, ys), "Year :"
  393.     _PRINTSTRING (xs, ys + 20), "Week :"
  394.     _PRINTSTRING (xs, ys + 40), "Sound:"
  395.     _PRINTSTRING (xs, ys + 60), "Theme:"
  396.     bxs = xs + 50: bys = ys - 2 'x/y start for the display boxes
  397.     FOR i = 0 TO 3
  398.         Box bxs, bys + i * 20, 100, 20, 1, Black, Gold
  399.     NEXT
  400.     CenterValue bxs, bys, bxs + 100, bys + 20, DisplayTag.Year
  401.     CenterValue bxs, bys + 20, bxs + 100, bys + 40, DisplayTag.Week
  402.     CenterText bxs, bys + 40, bxs + 100, bys + 60, DisplayTag.Sound
  403.     CenterText bxs, bys + 60, bxs + 100, bys + 80, DisplayTag.Theme
  404.     RestoreState S
  405.  
  406. SUB Box (x, y, wide, high, thick, Kolor AS _UNSIGNED LONG, Trim AS _UNSIGNED LONG)
  407.     LINE (x, y)-STEP(wide, high), Kolor, BF
  408.     FOR i = 0 TO thick - 1
  409.         LINE (x + i, y + i)-STEP(wide - 2 * i, high - 2 * i), Trim, B
  410.     NEXT
  411.  
  412.  
  413. SUB CenterText (x1, y1, x2, y2, text$)
  414.     text$ = _TRIM$(text$)
  415.     xmax = x2 - x1: ymax = y2 - y1
  416.     textlength = _PRINTWIDTH(text$)
  417.     xpos = (xmax - textlength) / 2
  418.     ypos = (ymax - _FONTHEIGHT) / 2
  419.     _PRINTSTRING (x1 + xpos, y1 + ypos), text$
  420.  
  421. SUB CenterValue (x1, y1, x2, y2, value AS LONG)
  422.     text$ = _TRIM$(STR$(value))
  423.     CenterText x1, y1, x2, y2, text$
  424.  
  425. FUNCTION SaveState
  426.     TYPE SaveStateType
  427.         InUse AS INTEGER
  428.         DC AS INTEGER
  429.         BG AS INTEGER
  430.         F AS INTEGER
  431.         D AS INTEGER
  432.         S AS INTEGER
  433.         Disp AS INTEGER
  434.         CurX AS INTEGER
  435.         CurY AS INTEGER
  436.     END TYPE
  437.     DIM SS AS SaveStateType, Temp AS SaveStateType
  438.     SHARED NSS AS LONG 'Number of Saved States
  439.     SHARED SaveMem AS _MEM
  440.     IF NOT _MEMEXISTS(SaveMem) THEN
  441.         SaveMem = _MEMNEW(LEN(SS) * 255) 'Save up to 255 save states; More than 255 and we toss an error
  442.         $CHECKING:OFF
  443.         _MEMFILL SaveMem, SaveMem.OFFSET, SaveMem.SIZE, 0 AS _UNSIGNED _BYTE
  444.         $CHECKING:ON
  445.     END IF
  446.  
  447.     'Data to Save
  448.     SS.InUse = -1
  449.     SS.F = _FONT
  450.     SS.DC = _DEFAULTCOLOR
  451.     SS.BG = _BACKGROUNDCOLOR
  452.     SS.D = _DEST
  453.     SS.S = _SOURCE
  454.     SS.Disp = _AUTODISPLAY
  455.     SS.CurX = POS(0)
  456.     SS.CurY = CSRLIN
  457.     FOR i = 1 TO NSS
  458.         o = (i - 1) * LEN(SS)
  459.         _MEMGET SaveMem, SaveMem.OFFSET + o, Temp
  460.         IF Temp.InUse = 0 THEN
  461.             _MEMPUT SaveMem, SaveMem.OFFSET + o, SS
  462.             SaveState = i
  463.             EXIT FUNCTION
  464.         END IF
  465.     NEXT
  466.     _MEMPUT SaveMem, SaveMem.OFFSET + NSS * LEN(SS), SS
  467.     NSS = NSS + 1
  468.     SaveState = NSS
  469.  
  470. SUB RestoreState (WhichOne AS LONG)
  471.     DIM SS AS SaveStateType
  472.     SHARED NSS AS LONG 'Number of Saved States
  473.     SHARED SaveMem AS _MEM
  474.     _MEMGET SaveMem, SaveMem.OFFSET + (WhichOne - 1) * LEN(SS), SS
  475.     IF SS.InUse THEN
  476.         SS.InUse = 0 'Let the routine know that we're no longer in use for this handle
  477.         $CHECKING:OFF
  478.         _MEMPUT SaveMem, SaveMem.OFFSET + (WhichOne - 1) * LEN(SS), SS
  479.         $CHECKING:ON
  480.         _FONT SS.F
  481.         COLOR SS.DC, SS.BG
  482.         _DEST SS.D
  483.         _SOURCE SS.S
  484.         IF SS.Disp THEN _AUTODISPLAY ELSE _DISPLAY
  485.         LOCATE SS.CurY, SS.CurX
  486.     END IF
  487.  
  488. SUB GetNewWH (destWidth, destHeight, handle AS LONG, NewWidth, NewHeight) 'Sub return in variables NewWidth and NewHeight new image Width and image Height with the same ratio for optimal picture to set area width and height with [destWidth, destHeight]
  489.     W = _WIDTH(handle)
  490.     H = _HEIGHT(handle)
  491.     Pw = W / destWidth
  492.     Ph = H / destHeight
  493.     IF W > H THEN P = Pw ELSE P = Ph
  494.     NewWidth = W / P
  495.     NewHeight = H / P
  496.  
  497. FUNCTION mouseclick%
  498.     DO WHILE _MOUSEINPUT 'check mouse status
  499.         lb% = _MOUSEBUTTON(1)
  500.     LOOP
  501.  
  502.     DO WHILE lb% 'check for leftbutton release
  503.         i% = _MOUSEINPUT
  504.         lb% = _MOUSEBUTTON(1)
  505.         mouseclick% = -1
  506.     LOOP
  507.  

It's now making the review lists (I still need to quick code in the buttons to change how many times we review our words, as of now, they're stuck at 3 times each), and I think I've sorted out the glitches so that we no longer require the ON TIMER method of handling things.  All GOTO statements are now removed as well, since many folks find them completely distasteful, and all that's left at this point is to:

1) Add the 5 quick select buttons for the numbers of times to review the material chosen.
2) To add in the quiz routine at the end of the review process.

And then it's just add pictures and words, and tag them so they can be reviewed as wanted.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Spell It Aloud (Help Requested)
« Reply #39 on: August 04, 2019, 07:27:14 am »
Hi Steve. I tried with my "English" to say those few words .... the result is - useless. Check your email (@QB64.ORG), have fun and delete it. I never learned English (I learned German, because I live near the German border) and my English pronunciation is disastrous. But - again - I tried it, unlike English-speaking colleagues here on the forum. English speaking gentlemen programmers could think about each other :-D

Yeah, I have a provocative day today. Steve, because I don't have enough imagination, I ask you to elaborate on the idea. Five buttons. Good. Specifically, what to this 5 buttons have to do. Thanks for your patience.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Spell It Aloud (Help Requested)
« Reply #40 on: August 04, 2019, 12:16:09 pm »
Steve, because I don't have enough imagination, I ask you to elaborate on the idea. Five buttons. Good. Specifically, what to this 5 buttons have to do. Thanks for your patience.

They're now in there.  All that's left now is for the QUIZ portion of the program!  ;D

Code: [Select]
$COLOR:32

TYPE TagType
    Year AS INTEGER
    Week AS INTEGER
    Sound AS STRING
    Theme AS STRING
END TYPE

SCREEN _NEWIMAGE(800, 600, 32)
_TITLE "Spell It Aloud"
RANDOMIZE TIMER

$IF WIN THEN
    temp$ = MID$(_CWD$, _INSTRREV(_CWD$, "\") + 1)
$ELSE
    temp$ = MID$(_CWD$, _INSTRREV(_CWD$, "/") + 1)
$END IF

IF temp$ <> "Spell It Aloud" THEN
    PRINT "ERROR -- Program not in proper directory."
    PRINT "Stopping execution..."
    PRINT
    PRINT "Please don't be a dufus, and fix it!"
END IF

CONST ImageDir$ = ".\Images\"
CONST SoundDir$ = ".\Alphabet Sounds\"
CONST TagDir$ = ".\Image Tags\"
CONST WordSoundDir$ = ".\Word Sounds\"


DIM SHARED PhotoTag AS TagType
DIM SHARED LimitTag AS TagType

DIM SHARED AlphaSound(65 TO 90)
REDIM SHARED PhotoList(100000) AS STRING
REDIM SHARED WordList(0) AS LONG
DIM SHARED PhotoCount AS LONG
DIM SHARED PhotoChosen AS LONG
DIM SHARED f AS LONG, f1 AS LONG
DIM SHARED IsHowYouSpell AS LONG
DIM SHARED ControlVariable1 AS LONG
DIM SHARED ShowNext AS LONG


'load our fonts
f = _LOADFONT("courbd.ttf", 84, "MONOSPACE")
f1 = _LOADFONT("courbd.ttf", 48, "MONOSPACE")
_FONT f
fw = _FONTWIDTH: fh = _FONTHEIGHT


'Load the alphabet sound library
FOR i = 65 TO 90
    temp$ = SoundDir$ + CHR$(i) + ".ogg"
    AlphaSound(i) = _SNDOPEN(temp$, "VOL,SYNC,LEN,PAUSE")
NEXT
temp$ = WordSoundDir$ + "is how you spell.ogg"
IsHowYouSpell = _SNDOPEN(temp$, "VOL,SYNC,LEN,PAUSE")

_FONT f

_DELAY 1 'Give everything a moment to initialize and get started for us.
WordList(0) = 3 'three times repeating the list, as default
ChangeSearchTags
ShowNext = -1

DO
    ControlVariable = 0
    WHILE _MOUSEINPUT: WEND

    MB = _MOUSEBUTTON(1)
    Mx = _MOUSEX: My = _MOUSEY
    IF MB AND NOT oldmouse THEN
        IF Mx >= 650 AND Mx <= 750 THEN 'the mouse is in the correct X area for input
            SELECT CASE My
                CASE 171 TO 190
                    temp$ = ChangeValue(650, 171, STR$(LimitTag.Year), -1)
                    LimitTag.Year = VAL(temp$)
                    ChangeSearchTags
                    ShowNext = -1
                CASE 191 TO 210
                    temp$ = ChangeValue(650, 191, STR$(LimitTag.Week), -1)
                    LimitTag.Week = VAL(temp$)
                    ChangeSearchTags
                    ShowNext = -1
                CASE 211 TO 230
                    temp$ = ChangeValue(650, 211, LimitTag.Sound, 0)
                    LimitTag.Sound = temp$
                    ChangeSearchTags
                    ShowNext = -1
                CASE 231 TO 250
                    temp$ = ChangeValue(650, 231, LimitTag.Theme, 0)
                    LimitTag.Theme = temp$
                    ChangeSearchTags
                    ShowNext = -1
                CASE 324 TO 340
                    PhotoTag.Year = VAL(ChangeValue(650, 324, STR$(PhotoTag.Year), -1))
                    ChangePhotoTags word$
                    ShowNext = -1: ControlVariable1 = -1
                CASE 341 TO 360
                    PhotoTag.Week = VAL(ChangeValue(650, 341, STR$(PhotoTag.Week), -1))
                    ChangePhotoTags word$
                    ShowNext = -1: ControlVariable1 = -1
                CASE 361 TO 380
                    PhotoTag.Sound = ChangeValue(650, 361, PhotoTag.Sound, 0)
                    ChangePhotoTags word$
                    ShowNext = -1: ControlVariable1 = -1
                CASE 381 TO 400
                    PhotoTag.Theme = ChangeValue(650, 381, PhotoTag.Theme, 0)
                    ChangePhotoTags word$
                    ShowNext = -1: ControlVariable1 = -1
            END SELECT
        END IF
        IF _MOUSEY > 450 AND _MOUSEY < 470 THEN 'it's the right Y pos for the top control buttons
            SELECT CASE _MOUSEX
                CASE 575 TO 640 'Last
                    PhotoChosen = PhotoChosen - 1
                    IF PhotoChosen < 1 THEN PhotoChosen = 1
                    ShowNext = -1
                CASE 641 TO 705 'Play
                    ShowNext = -1
                CASE 706 TO 770 'Next
                    PhotoChosen = PhotoChosen + 1
                    IF PhotoChosen > UBOUND(WordList) THEN PhotoChosen = 1
                    ShowNext = -1
            END SELECT
        ELSEIF _MOUSEY > 471 AND _MOUSEY < 491 THEN 'it's the right Y pos for the 2nd row of control buttons
            SELECT CASE _MOUSEX
                CASE 575 TO 640 'Vol not yet implemented
                CASE 641 TO 705 'Stop now handled via the sound sub
                CASE 706 TO 770: SYSTEM 'Quit
            END SELECT
        ELSEIF _MOUSEY > 495 AND _MOUSEY < 515 THEN 'it's in the review column
            oldR = WordList(0)
            R = (_MOUSEX - 641) / 26
            IF R <> oldR THEN
                IF R > 0 AND R < 5 THEN WordList(0) = INT(R + 1)
                MakeList
                ShowNext = -1
            END IF
        END IF
    END IF

    k = _KEYHIT
    SELECT CASE k
        CASE 32 'space for next picture
            PhotoChosen = PhotoChosen + 1
            IF PhotoChosen > WordList(0) THEN PhotoChosen = 1
            ShowNext = -1
        CASE 27 'escape
            SYSTEM 'quit
    END SELECT

    IF ShowNext THEN
        ShowNext = 0
        IF PhotoChosen THEN
            temp$ = PhotoList(WordList(PhotoChosen))
            word$ = MID$(temp$, _INSTRREV(temp$, "\") + 1)
            word$ = LEFT$(word$, INSTR(word$, ".") - 1)

            IF tempimage <> 0 THEN _FREEIMAGE tempimage 'free the old image
            tempimage = _LOADIMAGE(temp$, 32) 'get the new image

            CLS
            _FONT f1: CenterText 0, 0, 800, 50, "Spell It Aloud": _FONT f

            'program photo area is 500 x 450 pixels. So:
            GetNewWH 500, 450, tempimage, nW, nH
            _PUTIMAGE (300 - (nW / 2), 300 - (nH / 2) - 25)-STEP(nW, nH), tempimage

            LoadPhotoTags word$
            temp$ = "Search Tags (" + _TRIM$(STR$(PhotoChosen)) + " of " + _TRIM$(STR$(UBOUND(wordlist))) + ")"
            DisplayTags 575, 150, temp$, LimitTag
            DisplayTags 575, 300, "Photo Tags", PhotoTag
            DrawCommandBoxes
            IF ControlVariable1 = 0 THEN PlayLetters word$
        ELSE
            DrawNoMatches
        END IF
        ControlVariable1 = 0
    END IF
    _LIMIT 10
    _DISPLAY
    oldmouse = MB
LOOP

SUB DrawCommandBoxes
    s = SaveState
    _FONT 16
    COLOR Black, 0
    BoxTitle 575, 450, 640, 470, 2, BlueGray, Gold, "LAST"
    BoxTitle 641, 450, 705, 470, 2, BlueGray, Gold, "PLAY"
    BoxTitle 706, 450, 770, 470, 2, BlueGray, Gold, "NEXT"
    BoxTitle 575, 471, 640, 490, 2, BlueGray, Gold, "VOL"
    COLOR Maroon
    BoxTitle 641, 471, 705, 490, 2, BlueGray, Gold, "STOP"
    COLOR Yellow
    BoxTitle 706, 471, 770, 490, 2, BlueGray, Gold, "QUIT"
    COLOR Black
    BoxTitle 575, 495, 640, 515, 2, BlueGray, Gold, "REVIEW:"
    R = WordList(0) '3
    FOR i = 1 TO 5
        IF i <> R THEN
            COLOR LightGray
            BoxTitle 641 + (i - 1) * 26, 495, 641 + i * 26, 515, 1, Black, Gold, STR$(i)
        ELSE
            COLOR White
            BoxTitle 641 + (i - 1) * 26, 495, 641 + i * 26, 515, 1, BlueGray, Gold, STR$(i)
        END IF
    NEXT
    RestoreState s
END SUB

SUB BoxTitle (x1, y1, x2, y2, thick, fg AS _UNSIGNED LONG, bg AS _UNSIGNED LONG, title$)
    Box x1, y1, x2 - x1 + 1, y2 - y1 + 1, thick, fg, bg
    CenterText x1, y1 + thick, x2, y2 + thick, title$
END SUB

SUB DrawNoMatches
    S = SaveState
    CLS
    _FONT f1
    Box 50, 50, 500, 500, 5, Silver, Gold
    CenterText 0, 0, 800, 50, "Spell It Aloud"
    FOR i = 1 TO 10 STEP .5
        CIRCLE (300, 300), 200 - i, BrickRed
        LINE (300 + SIN(_D2R(-45)) * 198 + i, 300 + COS(_D2R(-45)) * 198 + i)-(300 + SIN(_D2R(135)) * 198 + i, 300 + COS(_D2R(135)) * 198 + i), BrickRed
    NEXT
    COLOR Yellow, 0
    CenterText 50, 50, 550, 550, "No Matches"
    PhotoTag.Year = 0
    PhotoTag.Week = 0
    PhotoTag.Sound = ""
    PhotoTag.Theme = ""
    DisplayTags 575, 150, "Search Tags (0)", LimitTag
    DisplayTags 575, 300, "Photo Tags", PhotoTag
    RestoreState S
END SUB



SUB PlayLetters (word$)
    'Put the letters to the screen one by one
    ControlVariable1 = 0
    pw = _PRINTWIDTH(word$): StartX = (600 - pw) \ 2 'center position

    FOR i = 1 TO LEN(word$)
        a = ASC(word$, i) AND NOT 32 'play lowercase letters as uppercase sounds
        _PRINTSTRING (StartX + (i - 1) * _FONTWIDTH, 510), CHR$(a)
        _DISPLAY
        IF a < 65 OR a > 90 THEN _CONTINUE 'ignore non-letters in the file name
        _SNDPLAY AlphaSound(a)
        WHILE _SNDPLAYING(AlphaSound(a)) 'wait for sound to finish before playing again
            _LIMIT 10 'play nice with CPU during wait
            GOSUB checkstop
            IF ControlVariable1 THEN _SNDSTOP (AlphaSound(a))
        WEND
    NEXT
    IF ContolVariable1 = 0 THEN
        temp$ = WordSoundDir$ + word$ + ".ogg"
        IF _FILEEXISTS(temp$) THEN
            _SNDVOL IsHowYouSpell, .5
            _SNDPLAY IsHowYouSpell
            WHILE _SNDPLAYING(IsHowYouSpell) 'wait for sound to finish before playing again
                _LIMIT 10 'play nice with CPU during wait
                GOSUB checkstop
                IF ControlVariable1 THEN _SNDSTOP (IsHowYouSpell): EXIT SUB
            WEND

            temp = _SNDOPEN(temp$, "VOL,SYNC,LEN,PAUSE")
            _SNDPLAY temp
            WHILE _SNDPLAYING(temp) 'wait for sound to finish before playing again
                _LIMIT 10 'play nice with CPU during wait
                GOSUB checkstop
                IF ControlVariable1 THEN _SNDCLOSE temp: EXIT SUB
            WEND
            _SNDCLOSE temp

            FOR i = 1 TO LEN(word$)
                a = ASC(word$, i) AND NOT 32 'play lowercase letters as uppercase sounds
                _PRINTSTRING (StartX + (i - 1) * _FONTWIDTH, 510), CHR$(a)
                IF a < 65 OR a > 90 THEN _CONTINUE 'ignore non-letters in the file name
                _SNDPLAY AlphaSound(a)
                WHILE _SNDPLAYING(AlphaSound(a)) 'wait for sound to finish before playing again
                    _LIMIT 10 'play nice with CPU during wait
                    GOSUB checkstop
                    IF ControlVariable1 THEN EXIT SUB
                WEND
            NEXT
        END IF
    END IF

    EXIT SUB

    checkstop:
    WHILE _MOUSEINPUT: WEND
    IF _MOUSEBUTTON(1) THEN
        IF _MOUSEY > 451 AND _MOUSEY < 491 THEN
            IF _MOUSEX > 575 AND _MOUSEX < 770 THEN 'stop
                ControlVariable1 = -1 'Stop Command for playing the word
            END IF
        END IF
    END IF
    RETURN
END SUB


SUB ChangePhotoTags (word$)
    'Get a listing of the files
    file$ = TagDir$ + word$ + ".txt"
    OPEN file$ FOR OUTPUT AS #1
    PRINT #1, PhotoTag.Year
    PRINT #1, PhotoTag.Week
    PRINT #1, PhotoTag.Sound
    PRINT #1, PhotoTag.Theme
    CLOSE
END SUB

SUB LoadPhotoTags (word$)
    file$ = TagDir$ + word$ + ".txt"
    IF _FILEEXISTS(file$) THEN
        OPEN file$ FOR INPUT AS #1
        INPUT #1, PhotoTag.Year
        INPUT #1, PhotoTag.Week
        INPUT #1, PhotoTag.Sound
        INPUT #1, PhotoTag.Theme
        CLOSE
    ELSE
        PhotoTag.Year = 0
        PhotoTag.Week = 0
        PhotoTag.Sound = ""
        PhotoTag.Theme = ""
        IF word$ <> "" THEN ChangePhotoTags word$
    END IF
END SUB


SUB ChangeSearchTags
    'Get a listing of the files
    PhotoList$ = ImageDir$ + "*.bmp " + ImageDir$ + "*.jpg " + ImageDir$ + "*.png " + ImageDir$ + "*.gif "
    SHELL _HIDE "DIR " + PhotoList$ + "/b /s /a-d >PhotoList.txt"

    REDIM _PRESERVE PhotoList(100000)
    'Load those names into a file.
    OPEN "Photolist.txt" FOR BINARY AS #1
    PhotoCount = 0
    DO UNTIL EOF(1)
        LINE INPUT #1, fullpath$
        word$ = MID$(fullpath$, _INSTRREV(fullpath$, "\") + 1)
        word$ = LEFT$(word$, INSTR(word$, ".") - 1)

        file$ = TagDir$ + word$ + ".txt"
        IF _FILEEXISTS(file$) THEN
            OPEN file$ FOR INPUT AS #2
            INPUT #2, PhotoTag.Year
            INPUT #2, PhotoTag.Week
            INPUT #2, PhotoTag.Sound
            INPUT #2, PhotoTag.Theme
        ELSE
            OPEN file$ FOR OUTPUT AS #2
            PRINT #2, 0
            PRINT #2, 0
            PRINT #2, ""
            PRINT #2, ""
        END IF
        CLOSE #2
        good = -1
        IF LimitTag.Year <> 0 AND LimitTag.Year <> PhotoTag.Year THEN good = 0
        IF LimitTag.Week <> 0 AND LimitTag.Week <> PhotoTag.Week THEN good = 0

        IF LimitTag.Sound <> "" AND LimitTag.Sound <> PhotoTag.Sound THEN good = 0
        IF LimitTag.Theme <> "" AND LimitTag.Theme <> PhotoTag.Theme THEN good = 0
        IF good THEN
            PhotoCount = PhotoCount + 1
            PhotoList(PhotoCount) = fullpath$
        END IF
    LOOP
    REDIM _PRESERVE PhotoList(PhotoCount)
    CLOSE
    MakeList
END SUB

SUB MakeList
    RepeatCount = WordList(0)
    REDIM WordList(PhotoCount * RepeatCount) AS LONG
    WordList(0) = RepeatCount
    IF UBOUND(wordlist) > 0 THEN
        PhotoChosen = 1
    ELSE
        PhotoChosen = 0
        EXIT SUB
    END IF
    DIM TempList(PhotoCount) AS LONG
    FOR i = 1 TO PhotoCount
        TempList(i) = i
    NEXT
    FOR i = 1 TO RepeatCount
        FOR j = 1 TO PhotoCount
            r = INT(RND * PhotoCount) + 1
            SWAP TempList(j), TempList(r)
        NEXT
        FOR j = 1 TO PhotoCount
            Count = Count + 1
            WordList(Count) = TempList(j)
        NEXT
    NEXT
END SUB

FUNCTION ChangeValue$ (x, y, tword$, limit)
    S = SaveState
    _FONT 16
    temp$ = CHR$(179)
    _KEYCLEAR
    _AUTODISPLAY
    DO
        Box x, y, 100, 20, 1, Black, Gold
        CenterText x, y, x + 100, y + 20, temp$
        k = _KEYHIT
        SELECT CASE k
            CASE 8
                tword$ = LEFT$(tword$, LEN(tword$) - 1)
            CASE 13
                EXIT DO
            CASE 48 TO 57 'We'll always accept numeric input
                tword$ = tword$ + CHR$(k)
            CASE 65 TO 90, 97 TO 122 'A-Z (a-z) only when we're dealing with a string
                IF NOT limit THEN tword$ = tword$ + CHR$(k)
        END SELECT
        temp$ = tword$ + CHR$(179)
        _LIMIT 10
        DisplayTags 575, 150, "Search Tags (" + _TRIM$(STR$(PhotoCount)) + ")", LimitTag
        DisplayTags 575, 300, "Photo Tags", PhotoTag
    LOOP
    ChangeValue$ = tword$
    RestoreState S
END SUB

SUB DisplayTags (x, y, Title AS STRING, DisplayTag AS TagType)
    S = SaveState
    _FONT 16
    W = 200: h = 106
    Box x, y, W, h, 2, BlueGray, Gold
    COLOR Gold, 0
    CenterText x, y + 2, x + 200, y + 20, Title
    LINE (x + 1, y + 19)-STEP(W - 2, 0), Gold
    COLOR White, 0
    xs = x + 24: ys = y + 24 'x/y start after the box offset
    _PRINTSTRING (xs, ys), "Year :"
    _PRINTSTRING (xs, ys + 20), "Week :"
    _PRINTSTRING (xs, ys + 40), "Sound:"
    _PRINTSTRING (xs, ys + 60), "Theme:"
    bxs = xs + 50: bys = ys - 2 'x/y start for the display boxes
    FOR i = 0 TO 3
        Box bxs, bys + i * 20, 100, 20, 1, Black, Gold
    NEXT
    CenterValue bxs, bys, bxs + 100, bys + 20, DisplayTag.Year
    CenterValue bxs, bys + 20, bxs + 100, bys + 40, DisplayTag.Week
    CenterText bxs, bys + 40, bxs + 100, bys + 60, DisplayTag.Sound
    CenterText bxs, bys + 60, bxs + 100, bys + 80, DisplayTag.Theme
    RestoreState S
END SUB

SUB Box (x, y, wide, high, thick, Kolor AS _UNSIGNED LONG, Trim AS _UNSIGNED LONG)
    LINE (x, y)-STEP(wide, high), Kolor, BF
    FOR i = 0 TO thick - 1
        LINE (x + i, y + i)-STEP(wide - 2 * i, high - 2 * i), Trim, B
    NEXT
END SUB


SUB CenterText (x1, y1, x2, y2, text$)
    text$ = _TRIM$(text$)
    xmax = x2 - x1: ymax = y2 - y1
    textlength = _PRINTWIDTH(text$)
    xpos = (xmax - textlength) / 2
    ypos = (ymax - _FONTHEIGHT) / 2
    _PRINTSTRING (x1 + xpos, y1 + ypos), text$
END SUB

SUB CenterValue (x1, y1, x2, y2, value AS LONG)
    text$ = _TRIM$(STR$(value))
    CenterText x1, y1, x2, y2, text$
END SUB

FUNCTION SaveState
    TYPE SaveStateType
        InUse AS INTEGER
        DC AS INTEGER
        BG AS INTEGER
        F AS INTEGER
        D AS INTEGER
        S AS INTEGER
        Disp AS INTEGER
        CurX AS INTEGER
        CurY AS INTEGER
    END TYPE
    DIM SS AS SaveStateType, Temp AS SaveStateType
    SHARED NSS AS LONG 'Number of Saved States
    SHARED SaveMem AS _MEM
    IF NOT _MEMEXISTS(SaveMem) THEN
        SaveMem = _MEMNEW(LEN(SS) * 255) 'Save up to 255 save states; More than 255 and we toss an error
        $CHECKING:OFF
        _MEMFILL SaveMem, SaveMem.OFFSET, SaveMem.SIZE, 0 AS _UNSIGNED _BYTE
        $CHECKING:ON
    END IF

    'Data to Save
    SS.InUse = -1
    SS.F = _FONT
    SS.DC = _DEFAULTCOLOR
    SS.BG = _BACKGROUNDCOLOR
    SS.D = _DEST
    SS.S = _SOURCE
    SS.Disp = _AUTODISPLAY
    SS.CurX = POS(0)
    SS.CurY = CSRLIN
    $CHECKING:OFF
    FOR i = 1 TO NSS
        o = (i - 1) * LEN(SS)
        _MEMGET SaveMem, SaveMem.OFFSET + o, Temp
        IF Temp.InUse = 0 THEN
            _MEMPUT SaveMem, SaveMem.OFFSET + o, SS
            SaveState = i
            EXIT FUNCTION
        END IF
    NEXT
    _MEMPUT SaveMem, SaveMem.OFFSET + NSS * LEN(SS), SS
    $CHECKING:ON
    NSS = NSS + 1
    SaveState = NSS
END SUB

SUB RestoreState (WhichOne AS LONG)
    DIM SS AS SaveStateType
    SHARED NSS AS LONG 'Number of Saved States
    SHARED SaveMem AS _MEM
    _MEMGET SaveMem, SaveMem.OFFSET + (WhichOne - 1) * LEN(SS), SS
    $CHECKING:ON
    IF SS.InUse THEN
        SS.InUse = 0 'Let the routine know that we're no longer in use for this handle
        $CHECKING:OFF
        _MEMPUT SaveMem, SaveMem.OFFSET + (WhichOne - 1) * LEN(SS), SS
        $CHECKING:ON
        _FONT SS.F
        COLOR SS.DC, SS.BG
        _DEST SS.D
        _SOURCE SS.S
        IF SS.Disp THEN _AUTODISPLAY ELSE _DISPLAY
        LOCATE SS.CurY, SS.CurX
    END IF
END SUB

SUB GetNewWH (destWidth, destHeight, handle AS LONG, NewWidth, NewHeight) 'Sub return in variables NewWidth and NewHeight new image Width and image Height with the same ratio for optimal picture to set area width and height with [destWidth, destHeight]
    W = _WIDTH(handle)
    H = _HEIGHT(handle)
    Pw = W / destWidth
    Ph = H / destHeight
    IF W > H THEN P = Pw ELSE P = Ph
    NewWidth = W / P
    NewHeight = H / P
END SUB

What the review buttons does is choose how many times we review the material at hand, before we finish and take our (not yet implemented) quiz.

For example, we narrow down our list of words to "Petr, Pete, Peter".

If the Review number is one, our review list might be:  "Pete, Petr, Peter"
If the Review number is two, our review list might be:  "Pete, Petr, Peter, Petr, Peter, Pete".

It's just the number of times (from 1 to 5) which we want to set to review the material, before taking a test on it. 



Not related to this, but related to QB64 development:

If you notice, the syntax on $COLOR32 has changed a little in my version; it's now $COLOR:32.  (See that : in there?)

This is because $COLOR now has 2 modes which we can get names from -- $COLOR:32 for 32-bit color names, and $COLOR:0 for screen 0 color names. 

It's a slight change, but it makes my current version of QB64 slightly incompatible with yours, at the moment.

When this little project is finished, I'll probably just put the CONST values in an $INCLUDE file for now, so that it'll be usable for everyone -- those that keep up with the latest development builds, and those who prefer the stable 1.3 version instead.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Spell It Aloud (Help Requested)
« Reply #41 on: August 04, 2019, 01:57:56 pm »
Yeah, so there is a nice buzz at the beginning, with the wrong directory, but SOMEONE who entered it also for Linux no longer added support for Linux when loading the contents of the directory (ls for Linux, DIR for Windows) :-D
So i am tryed it and have query. If selecting 3 images, in Photo tags saving for this 3 photos the same flags to theme and then select review - let say to 3x. Then if i press space or next button, are this 3 photos playing (if i set this theme to search tag). So after then, when are this selected images all played, in current version starting again, but final version then start quiz. Its so correct?

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Spell It Aloud (Help Requested)
« Reply #42 on: August 04, 2019, 06:44:54 pm »
Here's a prototype of the finished product.  ;)

Things still needed:

It needs some layout work to center things better to make the screen prettier.
A prettier QUIZ results page, with pauses in case the user has a quiz with more words than can appear on a single display page.
Hard/Easy mode to be implemented for the spelling quiz --
      At the moment, all we're having is the HARD mode implemented.  (Enter the word, with no help whatsoever.)
      For easy mode, I picture it to limit word input to the proper number of letters, and to display a placeholder on the screen for the letters.  Such as for "cat", the screen will offer a prompt of three stars ("***") as placeholders to help indicate how many letters belong in the word. 

But, more or less, our little spelling training program is workable the way it already exists!  ;D
* Spell It Aloud.7z (Filesize: 1.42 MB, Downloads: 216)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Spell It Aloud (Help Requested)
« Reply #43 on: August 05, 2019, 11:28:14 am »
Nice Work, Steve. There is one very small bug - try to search tags writing "animals", not "Animals", then is none match. LCASE$ can reapir it.  Next - :) - in begin - if is program not in correct directory, yet continue.

This is big and nice work, Steve.

Offline SW

  • Newbie
  • Posts: 6
    • View Profile
Re: Spell It Aloud (Help Requested)
« Reply #44 on: August 05, 2019, 01:18:42 pm »
congratz, Steve!

I mind its good to add multi lingual support by adding ".\en\Alphabet Sounds\" and "".\en\Word Sounds\". So you can add other pronounces(languages) for same images.