QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: OldMoses on August 30, 2018, 01:07:37 pm

Title: I seem to be sinning against syntax for UBOUND
Post by: OldMoses on August 30, 2018, 01:07:37 pm
[UPDATE: Problems solved, two unrelated bugs that had nothing at all to do with UBOUND, thanks for all your help, guys.]

Doing a rewrite of an old grain harvest database program that I've using for the last twenty years or so. I want to take advantage of the new screen modes, mouse support and graphics that QB64 brings to the table. I'm having a myriad of issues with the graphics and color, which is completely expected and I'm prepared to slog along, paying my dues until I learn the new systems, but.....

I seem to be missing something that may be related to the UBOUND command and iteration of arrays. In one array example, the routine stops 1 short of UBOUND and in another it generates a subscript out of range error. I'm putting in all the code that I believe is relevant to my issue, along with some comments on what it's doing, but it's just snippets out of a 1800+ line, hot mess of a program, but it worked fine before...

If anyone can see what I'm doing wrong (other than being a complete coding neandertal), I'd appreciate any insights or advise. I've never had these problems from UBOUND before.

Code: QB64: [Select]
  1. 'From Main Module
  2.  
  3. ' Data type for truck list array
  4. TYPE Vehicle
  5.     trucknm AS STRING * 10 'Truck name
  6.     tare AS LONG 'Tare weight
  7.  
  8. DIM SHARED farmindex(x) AS STRING 'Farm index array
  9. DIM SHARED truck(x) AS Vehicle 'Truck index array  
  10.  
  11. 'Initialize truck list from truck.txt
  12. OPEN "truck.txt" FOR RANDOM AS #3 LEN = LEN(truck(0))
  13. IF LOF(3) = 0 THEN 'TRUCK.TXT is empty/not present
  14.     REDIM truck(1) AS Vehicle
  15.     truck(1).trucknm = "default" 'create blank truck record
  16.     truck(1).tare = 0
  17.     PUT #3, 1, truck(1)
  18. ELSE 'TRUCK.TXT is present
  19.     y% = LOF(3) / LEN(truck(0)) 'retrieve truck records
  20.     REDIM truck(y%) AS Vehicle
  21.     FOR x = 1 TO y%
  22.         GET #3, x, truck(x)
  23.     NEXT x
  24.     CLOSE #3
  25.  
  26. 'Initialize farm list into farmindex array
  27. OPEN "farm.txt" FOR RANDOM AS #4 LEN = 20
  28. IF LOF(4) = 0 THEN 'FARM.TXT is empty/not present
  29.     REDIM farmindex(1) AS STRING
  30.     farmindex(1) = "Main" 'create blank farm record
  31.     PUT #4, 1, farmindex(1)
  32. ELSE 'FARM.TXT is present
  33.     y% = LOF(4) / 20 'retrieve farm records
  34.     REDIM farmindex(y%) AS STRING
  35.     FOR x = 1 TO y%
  36.         GET #4, x, farmindex(x)
  37.     NEXT x
  38.     CLOSE #4
  39.  
  40. 'End Main Module code
  41.  
  42.  
  43. 'This code executed in SUB ConfigRun which runs in a
  44. '_NEWIMAGE (50, 20, 0)screen
  45.     DO
  46.         _PRINTSTRING (19, 1), "SELECT FARM"
  47.         LOCATE 1, 31: PRINT UBOUND(farmindex)
  48.         FOR x = 1 TO UBOUND(farmindex)
  49.             LOCATE x + 2, 25 - (LEN(farmindex(x)) / 2) 'center justify
  50.             IF mouse_x > 20 AND mouse_x < 30 THEN
  51.                 IF mouse_y = x + 2 THEN COLOR 12, 0
  52.             END IF
  53.             PRINT farmindex(x)
  54.             COLOR 7, 4
  55.         NEXT x
  56.  
  57.         Mouse_Loop 0, 0
  58.         cho% = Mouse_Point%(2, UBOUND(farmindex), 20, 30)
  59.         _LIMIT 50
  60.     LOOP UNTIL cho% <> 0
  61. 'It refuses to print the last farmindex value. I added a dummy
  62. 'value at the end of the file to make it do so as a work around.
  63.  
  64. 'Then this one from SUB TruckIn same screen parameters
  65.        DO
  66.         LOCATE 5, 1
  67.         PRINT "Choose Truck:"
  68.         FOR x = 1 TO UBOUND(truck)
  69.             IF editmode AND var.truck = truck(x).trucknm THEN COLOR 14 'original truck in yellow
  70.             IF mouse_y > 14 AND mouse_y < 24 THEN
  71.                 IF mouse_x = x + 4 THEN COLOR 12, 0 'mouseover highlight
  72.             END IF
  73.             LOCATE x + 4, 15
  74.             PRINT truck(x).trucknm
  75.             COLOR 0, 3
  76.         NEXT x
  77.  
  78.         Mouse_Loop 0, 0
  79.         cho% = MousePoint%(4, UBOUND(truck), 14, 24)
  80.  
  81.         _LIMIT 50
  82.     LOOP UNTIL x% <> 0
  83. 'It throws a subscript out of range error at MousePoint% call
  84.  
  85.  
  86. 'including the Mouse_Loop and MousePoint% in case of relevance
  87. SUB Mouse_Loop (var AS INTEGER, var2 AS INTEGER)
  88.  
  89.     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  90.     ' SUB: Mouse_Loop
  91.     '
  92.     ' Purpose:
  93.     ' Primary mouse input loop. Controls mousewheel scrolling and conditions
  94.     ' x,y position data.
  95.     '
  96.     ' Passed Variables:
  97.     ' var sends whether data list is extensive enough for using offset printing values
  98.     ' var2 sends maximum allowed offset value
  99.     '
  100.     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  101.  
  102.  
  103.     'scan for changes in mouse position and save to global variables
  104.         IF var = 1 THEN
  105.             offset = offset + _MOUSEWHEEL 'mousewheel offset only works in the loop
  106.             IF offset < 0 THEN offset = 0 'otherwise would SUB to Mouse_Loop
  107.             IF offset > var2 THEN offset = var2
  108.         END IF
  109.         IF _MOUSEY - INT(_MOUSEY) >= .5 THEN
  110.             mouse_y = INT(_MOUSEY + 1)
  111.         ELSE
  112.             mouse_y = INT(_MOUSEY)
  113.         END IF
  114.         mouse_x = INT(_MOUSEX)
  115.     LOOP
  116.  
  117. END SUB 'Mouse_Loop
  118.  
  119. FUNCTION Mouse_Point% (trim_top AS INTEGER, last_item AS INTEGER, left_x AS INTEGER, right_x AS INTEGER)
  120.  
  121.     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  122.     ' FUNCTION: Mouse_Point%
  123.     '
  124.     ' Purpose:
  125.     ' Returns the row position and column range of a mouse pointer on left click.
  126.     ' Used for drop down choice routines.
  127.     '
  128.     ' Passed Variables:
  129.     ' trim_top sends value to be trimmed from row position to mark start of data list
  130.     ' last item sends value of last data item displayed
  131.     ' left_x sends leftmost allowed point of selection of data element
  132.     ' right_x sends rightmost allowed point of selection of data element
  133.     '
  134.     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  135.  
  136.     mouse_in = _MOUSEBUTTON(1)
  137.     IF mouse_in = -1 THEN
  138.         ypos = mouse_y - trim_top
  139.         IF ypos > 0 AND ypos < last_item + 1 THEN
  140.             IF mouse_x > left_x AND mouse_x < right_x THEN
  141.                 Mouse_Point% = ypos
  142.             END IF
  143.         END IF
  144.     END IF
  145.  
  146. END FUNCTION 'Mouse_Point%
  147.  
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: TerryRitchie on August 30, 2018, 01:23:05 pm
I'm looking at your code now.

line 72 errors out. var.truck is not referring to anything. A typo perhaps. I remarked the line out for now.

One thing I noticed is at the top of your code you DIM SHARED your arrays.  You should REDIM SHARED those arrays instead.

edit: Do you have some dummy text I can use to run with the program? farm.txt and truck.txt
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: SMcNeill on August 30, 2018, 03:41:06 pm
One point of immediate interest to me:

DIM SHARED farmindex(x) AS STRING 'Farm index array
OPEN "farm.txt" FOR RANDOM AS #4 LEN = 20 

You're setting a limit of 20 characters with the OPEN statement, but you're allowing the farmindex() to be a variable length string.  I think I'd make it AS STRING * 20 to be certain to avoid any issues from length.

Here's a perfect example for you, which I wrote using your own variable types:


Code: QB64: [Select]
  1. ' Data type for truck list array
  2. TYPE Vehicle
  3.     trucknm AS STRING * 10 'Truck name
  4.     tare AS LONG 'Tare weight
  5.  
  6. REDIM SHARED farmindex(10) AS STRING '* 20 'Farm index array
  7. REDIM SHARED truck(10) AS Vehicle 'Truck index array
  8.  
  9. 'Initialize truck list from truck.txt
  10. OPEN "truck.txt" FOR OUTPUT AS #1: CLOSE #1
  11. OPEN "truck.txt" FOR RANDOM AS #1 LEN = LEN(truck(0))
  12.  
  13.  
  14. FOR i = 1 TO 10
  15.     truck(i).trucknm = "Truck " + STR$(i)
  16.     truck(i).tare = i
  17.     PUT #1, , truck(i)
  18.  
  19.     PRINT truck(i).trucknm, truck(i).tare, LOF(1)
  20.     GET #1, i, truck(i)
  21.     PRINT truck(i).trucknm, truck(i).tare, LOF(1)
  22.  
  23. OPEN "farm.txt" FOR OUTPUT AS #1: CLOSE #1
  24. OPEN "farm.txt" FOR RANDOM AS #1 LEN = 20
  25. DIM temp AS STRING '* 20
  26. FOR i = 1 TO 10
  27.     temp = STR$(10 ^ (i - 1))
  28.     PUT #1, i, temp
  29.     PRINT i, temp, LOF(1)
  30.     GET #1, i, farmindex(i)
  31.     PRINT i, farmindex(i), LOF(1)

Run the above as it is, and see what the length of "farm.txt" is after each PUT statement.  Then, unremark the * 20 which I used to make the variables limited to 20 characters.


If you want to keep the LEN = 20, set the string length to 20 as well, or else you're not going to be able to just divide LOF by 20 to get the correct number of records.
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: OldMoses on August 30, 2018, 06:05:07 pm
Yes indeed, I have tried setting the string length to 20, twice. Each time I got a C++ compilation error, so I'm thinking that avenue isn't available to me... unless there's just a glitch where I can put the statement elsewhere and get away with it, I might give that a try. I will give it your approach first and see if it likes that better, Thanks.

One point of immediate interest to me:

DIM SHARED farmindex(x) AS STRING 'Farm index array
OPEN "farm.txt" FOR RANDOM AS #4 LEN = 20 

You're setting a limit of 20 characters with the OPEN statement, but you're allowing the farmindex() to be a variable length string.  I think I'd make it AS STRING * 20 to be certain to avoid any issues from length.


Title: Re: I seem to be sinning against syntax for UBOUND
Post by: OldMoses on August 30, 2018, 06:37:24 pm
Sorry about that. var.truck references, in the particular SUB, another user defined variable, the main data variable in fact, which receives the results of the routine, I should have either remarked it out or posted the whole kit and kaboodle, but my approach is to shoe horn the new display stuff into the old working version's algorithms and it's a big fat mess right now. I'm tackling it one step at a time and seeing how far it goes before it crashes. I don't want to really fatigue anyone with my problems, but the UBOUND thing has got me stumped... I was kinda hoping that it was a QB64 quirk and someone would say "Oh, you just have to do 'X'"....;)

I'm looking at your code now.

line 72 errors out. var.truck is not referring to anything. A typo perhaps. I remarked the line out for now.

One thing I noticed is at the top of your code you DIM SHARED your arrays.  You should REDIM SHARED those arrays instead.

edit: Do you have some dummy text I can use to run with the program? farm.txt and truck.txt

Anyway, for anyone who is interested in this particular train wreck, I'll attach the whole awful thing. It's been a long term work in progress by a guy with meager skills.

The old working version (written under 4.5) "GRAIN321.bas" along with "farm.txt" and "truck.txt". As our truck loads come in from the field, they are weighed and a sample is taken for moisture testing. The program accepts the gross weight and moisture test and then determines net weight and shrinkage of the bushels from the drying process, and stores the results by truckload in a file for each farm, crop and harvest year. I'm seeking to consolidate all farms and crops in a single year file to clean up the file clutter that this scheme creates. After 20 some years of harvests I have significant clutter.

"Grain4.bas" is to be, one day hopefully, the new and improved version, incorporating mouse support, less cryptic looking graphic display and the ability to print hardcopy without the need to create html files as the workaround of the fact that Windows doesn't want to print my output.

Title: Re: I seem to be sinning against syntax for UBOUND
Post by: bplus on August 30, 2018, 08:28:13 pm
First error I hit is missing "dumper.bmp".

Those 2 lines commented out and the the editor says OK.
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: OldMoses on August 30, 2018, 08:33:48 pm
First error I hit is missing "dumper.bmp".

Oops, forgot that one too. It's just an image for _ICON. I've been playing around with too many things at once.
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: OldMoses on August 30, 2018, 08:38:04 pm
I've had one of those Doh! moments.

Instead of:
REDIM SHARED farmindex(x) AS STRING * 20 'Farm index array 

I was doing:
REDIM SHARED farmindex(x) * 20 AS STRING 'Farm index array 

except that upon changing it, it still gives me a C++ compilation error. The log reads:

In file included from qbx.cpp:2120:0:
..\\temp\\main.txt: In function 'void QBMAIN(void*)':
..\\temp\\main.txt:286:5: error: '__ARRAY_STRING_FARMINDEX' was not declared in this scope
compilation terminated due to -Wfatal-errors.
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: bplus on August 30, 2018, 08:43:49 pm
Grain4.bas is the one you are trying to fix up, right?

All farmindex() are AS STRING in code you have attached. My copy compiles.
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: OldMoses on August 30, 2018, 08:55:56 pm
Grain4.bas is the one you are trying to fix up, right?

All farmindex() are AS STRING in code you have attached. My copy compiles.

Correct. "GRAIN321.bas" works as needed, and I'll be using that one for this season. It's cryptic interface keeps my folks from using it, so it's been my baby exclusively. Grain4 will be for next year if I can get it humming. I'm hoping that it will be user friendly enough that everyone will use it, instead of me coming back later and adding the loads when I'm not too busy driving.

Maybe I should try downloading QB64 again, just in case something is corrupted.

Downloaded again....Well that took a lot longer to come to the same end.
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: bplus on August 30, 2018, 10:08:50 pm
I am rusty with Random access files. When you dim or redim an array to hold a random access file with nRecords, do you use
redim myArray(0 to nRecords -1)

or

redim myArray(1 to nRecords) so the array index matches the record numbers

?

this is not doing either, assuming y% is number of records:
Code: QB64: [Select]
  1. ELSE 'TRUCK.TXT is present
  2.     y% = LOF(3) / LEN(truck(0)) 'retrieve truck records
  3.     REDIM truck(y%) AS Vehicle
  4.     FOR x = 1 TO y%
  5.         GET #3, x, truck(x)
  6.     NEXT x
  7.     CLOSE #3

append: eh! that won't cause an error
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: bplus on August 30, 2018, 10:36:14 pm
Hi OldMoses,

So you are putting up a list from an array to select with a mouse click and the mouse click alignment is not matching the array limits? ie you mouse click is one item too many or too short of array index item.
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: OldMoses on August 30, 2018, 11:28:03 pm
The mouse aligns ok and clicks will select the proper array element. The issue I have is that when I iterate the array with FOR...NEXT from 1 to UBOUND(farmindex) the iteration stops 1 short of the final array element. There are three farm names in "farm.txt" but only two are output for mouse selection. That's the first case.

The second case, iterating a list of truck name identifiers, the program hangs with a subscript out of range error before the mouse action can even occur.

I generally match my arrays to the random access files, i.e. 1 to nRecords and have never had a problem doing it. In fact, I was using OPTION BASE 1 (which I had never done in the past) when the bug appeared, and I thought it might have something to do with it. However, commenting that command out didn't change anything. Nothing I've tried so far has.

Progress update:

The code in the first case is good. I grabbed an older version of "farm.txt" and it worked properly. It was a corrupted txt file.

Now to chase the next gremlin...

bplus, thank you. I got to thinking about the mouse alignment issue you mention and looked a little harder. I got my x and y positions switched and fixing that cleared up the problem in the second case. I don't know if I would have caught that one otherwise, I was so sure of myself and my x and y.

Two unrelated bugs that I thought were related.
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: bplus on August 31, 2018, 02:03:20 am
Hi OldMoses,

Glad you found the cause of the problems!
Man that code had me scratching my head! Something about that Mouse_Point% sub was surely causing a problem.

I reworked the code example in original post with a different routine for getting menu item numbers, where the menu is some item in an array you want user to select with mouse or by entered number.

Code: QB64: [Select]
  1. 'Bplus overhauled OldMoses code 2018-08-31
  2. SCREEN _NEWIMAGE(800, 600, 32)
  3. _SCREENMOVE 200, 60
  4.  
  5. '' Data type for truck list array
  6. TYPE Vehicle
  7.     trucknm AS STRING * 10 'Truck name
  8.     tare AS LONG 'Tare weight
  9.  
  10. DIM SHARED farmindex(x) AS STRING 'Farm index array
  11. DIM SHARED truck(x) AS Vehicle 'Truck index array
  12.  
  13. ''Initialize truck list from truck.txt
  14. OPEN "truck.txt" FOR RANDOM AS #3 LEN = LEN(truck(0))
  15. IF LOF(3) = 0 THEN 'TRUCK.TXT is empty/not present
  16.     REDIM truck(1) AS Vehicle
  17.     truck(1).trucknm = "default" 'create blank truck record
  18.     truck(1).tare = 0
  19.     PUT #3, 1, truck(1)
  20. ELSE 'TRUCK.TXT is present
  21.     y% = LOF(3) / LEN(truck(0)) 'retrieve truck records
  22.     REDIM truck(y%) AS Vehicle
  23.     FOR x = 1 TO y%
  24.         GET #3, x, truck(x)
  25.     NEXT x
  26.     CLOSE #3
  27.  
  28. ''Initialize farm list into farmindex array
  29. OPEN "farm.txt" FOR RANDOM AS #4 LEN = 20
  30. IF LOF(4) = 0 THEN 'FARM.TXT is empty/not present
  31.     REDIM farmindex(1) AS STRING
  32.     farmindex(1) = "Main" 'create blank farm record
  33.     PUT #4, 1, farmindex(1)
  34. ELSE 'FARM.TXT is present
  35.     y% = LOF(4) / 20 'retrieve farm records
  36.     REDIM farmindex(y%) AS STRING
  37.     FOR x = 1 TO y%
  38.         GET #4, x, farmindex(x)
  39.     NEXT x
  40.     CLOSE #4
  41.  
  42. 'End Main Module code
  43.  
  44.  
  45. 'This code executed in SUB ConfigRun which runs in a
  46. LOCATE 2, 10: PRINT "SELECT FARM"
  47. ch = getMenuItemNumber(3, 7, farmindex())
  48. PRINT: PRINT "          The farm you selected was "; farmindex(ch)
  49.  
  50. DIM menutruck(UBOUND(truck)) AS STRING
  51. FOR i = 1 TO UBOUND(truck)
  52.     menutruck(i) = truck(i).trucknm
  53.  
  54. LOCATE 15, 10: PRINT "CHOOSE TRUCK"
  55. ch = getMenuItemNumber(16, 7, menutruck())
  56. PRINT: PRINT "         You chose truck: "; truck(ch).trucknm
  57.  
  58. FUNCTION getMenuItemNumber (locateRow, locateColumn, menu() AS STRING)
  59.     FOR m = 1 TO UBOUND(menu)
  60.         LOCATE locateRow + m - 1, locateColumn: PRINT LTRIM$(STR$(m)) + ") " + menu(m)
  61.     NEXT
  62.     LOCATE locateRow + m + 1, locateColumn: PRINT "To select: Enter number or click item."
  63.     DO
  64.         k$ = INKEY$
  65.         IF LEN(k$) THEN
  66.             IF INSTR("0123456789", k$) > 0 THEN b$ = b$ + k$
  67.             IF ASC(k$) = 13 THEN
  68.                 IF VAL(b$) >= 1 AND VAL(b$) <= UBOUND(menu) THEN choice = VAL(b$): EXIT DO ELSE b$ = ""
  69.             END IF
  70.             IF ASC(k$) = 8 THEN
  71.                 IF LEN(b$) THEN b$ = LEFT$(b$, LEN(b$) - 1)
  72.             END IF
  73.         END IF
  74.         WHILE _MOUSEINPUT: WEND
  75.         IF _MOUSEBUTTON(1) THEN
  76.             mx = INT((_MOUSEX - locateColumn * 8) / 8) + 2: my = INT((_MOUSEY - locateRow * 16) / 16) + 2
  77.             IF mx >= 1 AND my >= 1 AND my <= UBOUND(menu) THEN
  78.                 choice = my
  79.             END IF
  80.         END IF
  81.         _LIMIT 200
  82.     LOOP UNTIL choice
  83.     getMenuItemNumber = choice
  84.  
  85.  

If you like it, we can figure a way to highlight the mouse over item and color it better.
  [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: OldMoses on August 31, 2018, 07:52:39 am
Hi OldMoses,

Glad you found the cause of the problems!
Man that code had me scratching my head! Something about that Mouse_Point% sub was surely causing a problem.
Yeah, I think because I mixed up x and y, it was always looking for the x value instead. With the drop down list always tabbed in x farther than the upper range of the array, it couldn't begin to function.

Quote
I reworked the code example in original post with a different routine for getting menu item numbers, where the menu is some item in an array you want user to select with mouse or by entered number.
That's great, thanks for your help, it gives me back the option of hotkey choices on the numberpad. I always preferred doing it that way, it being faster than fiddling with a mouse, but I wanted mouse support for my folks to use. That was just an impossible dream before QB64.

Quote
If you like it, we can figure a way to highlight the mouse over item and color it better.
I have been putting the list printing iteration within the DO...LOOP and then testing, within that iteration, if _MOUSEX and _MOUSEY were within certain limits. If they were then I would set colors accordingly. Maybe that would work with your mods? If there's a better way, I would certainly be interested in incorporating it. I always had the suspicion that my method was too processor intensive, because in another program I've been working on, one of my drop down list routines is very long and puts out a lot of screen flicker, which I could reduce (but not eliminate) with _LIMIT.
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: bplus on August 31, 2018, 09:07:11 am
Hi OldMoses,

If you are drawing something and then clearing and redrawing over and over in a loop, use _DISPLAY to stop the flickering.

I put the _LIMIT (which saves CPU from overheating making fan go on) statement just after _DISPLAY.

BUT! Once you use _DISPLAY, you have to use it each time you want to show a screen update, like just writing a message over the current screen displayed. _DISPLAY saves up all screen drawing until the command to _DISPLAY is made.

BUT! _DISPLAY can be disabled with command _AUTODISPLAY

Title: Re: I seem to be sinning against syntax for UBOUND
Post by: OldMoses on August 31, 2018, 12:40:54 pm
Hi OldMoses,

If you are drawing something and then clearing and redrawing over and over in a loop, use _DISPLAY to stop the flickering.

I put the _LIMIT (which saves CPU from overheating making fan go on) statement just after _DISPLAY.

BUT! Once you use _DISPLAY, you have to use it each time you want to show a screen update, like just writing a message over the current screen displayed. _DISPLAY saves up all screen drawing until the command to _DISPLAY is made.

BUT! _DISPLAY can be disabled with command _AUTODISPLAY

Yes! That worked like a charm. I see what you mean by having to use _AUTODISPLAY, the screen would lock when I tried to EXIT SUB unless I invoked it just before the exit.  So much to learn...such a great place to do it.
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: bplus on August 31, 2018, 01:26:55 pm
Hi OldMoses,

If you are drawing something and then clearing and redrawing over and over in a loop, use _DISPLAY to stop the flickering.

I put the _LIMIT (which saves CPU from overheating making fan go on) statement just after _DISPLAY.

BUT! Once you use _DISPLAY, you have to use it each time you want to show a screen update, like just writing a message over the current screen displayed. _DISPLAY saves up all screen drawing until the command to _DISPLAY is made.

BUT! _DISPLAY can be disabled with command _AUTODISPLAY

Yes! That worked like a charm. I see what you mean by having to use _AUTODISPLAY, the screen would lock when I tried to EXIT SUB unless I invoked it just before the exit.  So much to learn...such a great place to do it.

Well _DISPLAY won't prevent an EXIT SUB, you just won't see anything new until the command _DISPLAY occurs again.

If you really did lock up the execution, that may be a bug and need reporting but I am pretty sure you just saw the illusion of being locked because nothing was happening on screen.

Say, I am considering working on getMenuItemNUmber function some more, do you have any plans for using fonts?
I am considering case when all the items won't fit in predefined page or rectangle on screen, plus the mouse over highlight plus more discrimination with mouse clicks on the right side of the listing. Maybe for being able to read the records from a file and select one to edit. Come to think, I have something that scrolls through an array with mouse wheel.... :)
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: OldMoses on August 31, 2018, 05:55:11 pm
Say, I am considering working on getMenuItemNUmber function some more, do you have any plans for using fonts?
I am considering case when all the items won't fit in predefined page or rectangle on screen, plus the mouse over highlight plus more discrimination with mouse clicks on the right side of the listing. Maybe for being able to read the records from a file and select one to edit. Come to think, I have something that scrolls through an array with mouse wheel.... :)

I hadn't really thought about fonts, at this stage I wouldn't have a clue how to work with them. The program that was doing the flickering, my RPG character generator, has a mousewheel scroll routine for long skill and weapon lists. The code I used is:

Code: QB64: [Select]
  1. SUB Mouse_Loop (var AS INTEGER, var2 AS INTEGER)
  2.  
  3.     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  4.     ' SUB: Mouse_Loop
  5.     '
  6.     ' Purpose:
  7.     ' Primary mouse input loop. Controls mousewheel scrolling and conditions
  8.     ' x,y position data.
  9.     '
  10.     ' Passed Variables:
  11.     ' var sends whether data list is extensive enough for using offset printing values
  12.     ' var2 sends maximum allowed offset value
  13.     '
  14.     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  15.  
  16.  
  17.     'scan for changes in mouse position and save to global variables
  18.         IF var = 1 THEN
  19.             offset = offset + _MOUSEWHEEL 'mousewheel offset determines starting element to print
  20.             IF offset < 0 THEN offset = 0 'don't go beyond bottom of array
  21.             IF offset > var2 THEN offset = var2 'don't go beyond upper boundary of array
  22.         END IF
  23.         IF _MOUSEY - INT(_MOUSEY) >= .5 THEN
  24.             mouse_y = INT(_MOUSEY + 1)
  25.         ELSE
  26.             mouse_y = INT(_MOUSEY)
  27.         END IF
  28.         mouse_x = INT(_MOUSEX)
  29.     LOOP
  30.  
  31. END SUB 'Mouse_Loop
  32.  

The preceding loop, nested in and called from a display loop, sends 'offset', 'mouse_x' & 'mouse_y', all global variables, out to the display iteration. It's the same code in my original post, since I recycled it for the Grain4 program, but in that case the arrays are too short to need it so I just send 0 for 'var' and 'var2'.

Then MousePoint% grabs the actual choice determination on mouse click and sends it to IF...THEN or SELECT CASE or whatever...
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: OldMoses on September 01, 2018, 01:25:10 pm
Hi Bplus,

I've been playing around with code you created. By repositioning the print interation within the DO...LOOP and bringing in a modification of my Mouse_Loop SUB I've got it to do the mouseover highlighting and retain the number hotkeys. I'm having a hard time getting my head wrapped around graphics screen x and y handling, but this one {seems} to work.

Code: QB64: [Select]
  1. 'Bplus overhauled OldMoses code 2018-08-31
  2. SCREEN _NEWIMAGE(800, 600, 32)
  3. _SCREENMOVE 200, 60
  4.  
  5. '' Data type for truck list array
  6. TYPE Vehicle
  7.     trucknm AS STRING * 10 'Truck name
  8.     tare AS LONG 'Tare weight
  9.  
  10. DIM SHARED farmindex(x) AS STRING 'Farm index array
  11. DIM SHARED truck(x) AS Vehicle 'Truck index array
  12. DIM SHARED mouse_x AS INTEGER 'column position of mouse
  13. DIM SHARED mouse_y AS INTEGER 'row position of mouse
  14.  
  15. ''Initialize truck list from truck.txt
  16. OPEN "truck.txt" FOR RANDOM AS #3 LEN = LEN(truck(0))
  17. IF LOF(3) = 0 THEN 'TRUCK.TXT is empty/not present
  18.     REDIM truck(1) AS Vehicle
  19.     truck(1).trucknm = "default" 'create blank truck record
  20.     truck(1).tare = 0
  21.     PUT #3, 1, truck(1)
  22. ELSE 'TRUCK.TXT is present
  23.     y% = LOF(3) / LEN(truck(0)) 'retrieve truck records
  24.     REDIM truck(y%) AS Vehicle
  25.     FOR x = 1 TO y%
  26.         GET #3, x, truck(x)
  27.     NEXT x
  28.     CLOSE #3
  29.  
  30. ''Initialize farm list into farmindex array
  31. OPEN "farm.txt" FOR RANDOM AS #4 LEN = 20
  32. IF LOF(4) = 0 THEN 'FARM.TXT is empty/not present
  33.     REDIM farmindex(1) AS STRING
  34.     farmindex(1) = "Main" 'create blank farm record
  35.     PUT #4, 1, farmindex(1)
  36. ELSE 'FARM.TXT is present
  37.     y% = LOF(4) / 20 'retrieve farm records
  38.     REDIM farmindex(y%) AS STRING
  39.     FOR x = 1 TO y%
  40.         GET #4, x, farmindex(x)
  41.     NEXT x
  42.     CLOSE #4
  43.  
  44. 'End Main Module code
  45.  
  46.  
  47. 'This code executed in SUB ConfigRun which runs in a
  48. COLOR _RGB32(255, 255, 255)
  49. LOCATE 2, 10: PRINT "SELECT FARM"
  50. ch = getMenuItemNumber(3, 7, farmindex())
  51. PRINT: PRINT "          The farm you selected was "; farmindex(ch)
  52.  
  53. DIM menutruck(UBOUND(truck)) AS STRING
  54. FOR i = 1 TO UBOUND(truck)
  55.     menutruck(i) = truck(i).trucknm
  56.  
  57. LOCATE 15, 10: PRINT "CHOOSE TRUCK"
  58. ch = getMenuItemNumber(16, 7, menutruck())
  59. PRINT: PRINT "         You chose truck: "; truck(ch).trucknm
  60.  
  61. FUNCTION getMenuItemNumber (locateRow, locateColumn, menu() AS STRING)
  62.     DO
  63.         FOR m = 1 TO UBOUND(menu)
  64.             IF mouse_x >= 1 AND mouse_y = m THEN
  65.                 COLOR _RGB32(255, 51, 51)
  66.             END IF
  67.             LOCATE locateRow + m - 1, locateColumn: PRINT LTRIM$(STR$(m)) + ") " + menu(m)
  68.             COLOR _RGB32(255, 255, 255)
  69.         NEXT
  70.         LOCATE locateRow + m + 1, locateColumn: PRINT "To select: Enter number or click item."
  71.  
  72.         k$ = INKEY$
  73.         IF LEN(k$) THEN
  74.             IF INSTR("0123456789", k$) > 0 THEN b$ = b$ + k$
  75.             IF VAL(b$) >= 1 AND VAL(b$) <= UBOUND(menu) THEN choice = VAL(b$): EXIT DO ELSE b$ = ""
  76.             IF ASC(k$) = 8 THEN
  77.                 IF LEN(b$) THEN b$ = LEFT$(b$, LEN(b$) - 1)
  78.             END IF
  79.         END IF
  80.  
  81.         Mouse_Loop 0, 0, locateRow, locateColumn
  82.         IF _MOUSEBUTTON(1) THEN
  83.             mx = INT((_MOUSEX - locateColumn * 8) / 8) + 2: my = INT((_MOUSEY - locateRow * 16) / 16) + 2
  84.             IF mx >= 1 AND my >= 1 AND my <= UBOUND(menu) THEN
  85.                 choice = my
  86.             END IF
  87.         END IF
  88.         _LIMIT 200
  89.     LOOP UNTIL choice
  90.     getMenuItemNumber = choice
  91.  
  92.  
  93. SUB Mouse_Loop (var AS INTEGER, var2 AS INTEGER, ypos AS INTEGER, xpos AS INTEGER)
  94.  
  95.     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  96.     ' SUB: Mouse_Loop
  97.     '
  98.     ' Purpose:
  99.     ' Primary mouse input loop. Controls mousewheel scrolling and conditions
  100.     ' x,y position data.
  101.     '
  102.     ' Passed Variables:
  103.     ' var sends whether data list is extensive enough for using offset printing values
  104.     ' var2 sends maximum allowed offset value
  105.     '
  106.     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  107.  
  108.     'scan for changes in mouse position and save to global variables
  109.         IF var = 1 THEN
  110.             offset = offset + _MOUSEWHEEL 'mousewheel offset determines starting element to print
  111.             IF offset < 0 THEN offset = 0 'don't go beyond bottom of array
  112.             IF offset > var2 THEN offset = var2 'don't go beyond upper boundary of array
  113.         END IF
  114.         mouse_x = INT((_MOUSEX - (xpos * 8)) / 8) + 2
  115.         mouse_y = INT((_MOUSEY - (ypos * 16)) / 16) + 2
  116.     LOOP
  117.  
  118. END SUB 'Mouse_Loop
  119.  
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: bplus on September 01, 2018, 05:15:12 pm
Yes, the idea is to convert a mouse x, y position in pixels to a character cell position of the screen.

So a standard QB64 font is 8 pixels wide and 16 pixels high.

This is why I asked about fonts, they might have different pixel widths and heights for their character cells.

If you stick to print and locate, I think QB64 can match character cells for a custom font. But finding which cell the mouse is over or clicking is crucial for using mouse selection.

So you need a function that converts mouse pixel x, y to column and row of character cell. For such a routine you could input the Font's width and height, the mouse x, y and out comes the cell row, column for locate.

I have a fuller featured array select index function almost ready for much bigger arrays when you need to page through the array of selections but looks like you've got things handled for your application.
Title: Re: I seem to be sinning against syntax for UBOUND
Post by: OldMoses on September 03, 2018, 11:36:23 pm
I have a fuller featured array select index function almost ready for much bigger arrays when you need to page through the array of selections but looks like you've got things handled for your application.

I look forward to seeing it.

I did something similar to that in a purely SCREEN 0 text environment for my Runequest character generator. There are two displays that utilize mouse wheel scrolling, mouseover highlighting and click and edit various fields.

I'll attach it in case anyone is interested, along with a pre-gen to load. As with most of my creations it's a scatterbrained affair, that could probably benefit from better planning and SUBing out, but mostly seems to work as intended....mostly.... On startup, type "L", or click on Load at the bottom of the screen. It will query for a name, type "Jo" (the included pre-gen). If all files are intact and in the same directory, it should then display a bunch of skill percentages in the central black VIEW PRINT window. A left click on that field will take the user to a scrolling list that allows editing of various fields in the TYPE array, basic instructions displayed in the bottom bar. The main section of code for this is in SUB Mouse_List in the CASE IS = 1 section. Lines 2673 through 2770.

The other display is accessed by typing hotkey "W" or clicking "Weapons/" at the bottom. A split display with the bottom one scrolling by mouse wheel will open. It has several editable fields and displays some popup info on mouse over. The bulk of the code for that one is in SUB Display_Weapons and SUB Print_Arms. That was the one that had the flicker problem that you fixed.