Author Topic: Inspired by bplus...  (Read 4630 times)

0 Members and 1 Guest are viewing this topic.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Inspired by bplus...
« on: October 25, 2021, 07:06:15 pm »
I don't often do graphics, but when I do... I really , really hate to do the grunt work. I had a lot of that with my Wheel of Fortune spoof, and then I participated in the thread where bplus was discussing a _FONT incompatibility issue in past QB64 versions. I've seen enough of Mark's apps to know he makes use of algorithms, often, to do the grunt work. Anyway, versions aside, I decided if I want to do any more graphics applications, I want to start with some algorithms like the one I wrote for this demo. It automatically determines where to draw boxes around letters, rather than trying to estimate or map them out.

Requires version 1.5 or above.

Code: QB64: [Select]
  1. DIM SHARED overlay
  2.  
  3. Screen0 = _NEWIMAGE(80, 25, 0)
  4. SCREEN Screen0
  5.  
  6. font = _LOADFONT("lucon.ttf", 60, "monospace")
  7. IF font <= 0 THEN font = 16
  8.  
  9. _DEST overlay
  10. _FONT font
  11. COLOR _RGB(255, 102, 0), 0
  12.  
  13. row = 2: col = 2: r1% = 255: r2% = 0: r3% = 0
  14. COLOR _RGB(255, 255, 255)
  15. text$ = "I'd like to solve the puzzle, please!"
  16. y = row: x = col
  17. FOR i = 1 TO LEN(text$)
  18.     IF (x + LEN(MID$(text$, i, INSTR(i, text$, " ") - i))) * _FONTWIDTH > _WIDTH THEN BEEP: x = 2: y = y + 2
  19.     t$ = MID$(text$, i, 1)
  20.     PSL y, x, t$, r1%, r2%, r3%
  21.     x = x + 1
  22.  
  23. _FREEIMAGE overlay
  24.  
  25. _DELAY .66
  26.  
  27.  
  28. SUB PSL (y, x, t$, r1%, r2%, r3%)
  29.     IF t$ <> CHR$(32) THEN CALL box(y, x, r1%, r2%, r3%)
  30.     _PRINTSTRING ((x - 1) * _FONTWIDTH, (y - 1) * _FONTHEIGHT), t$
  31.     overlay_hardware = _COPYIMAGE(overlay, 33)
  32.     _PUTIMAGE (0, 0), overlay_hardware
  33.     _DISPLAY
  34.  
  35. SUB box (y, x, r1%, r2%, r3%)
  36.     LINE ((x - 1) * _FONTWIDTH, ((y - 1) * _FONTHEIGHT))-((x - 1) * _FONTWIDTH + _FONTWIDTH, ((y - 1) * _FONTHEIGHT) + _FONTHEIGHT), _RGB(r1%, r2%, r3%), B , 255
  37.     overlay_hardware = _COPYIMAGE(overlay, 33)
  38.     _PUTIMAGE (0, 0), overlay_hardware
  39.     _DISPLAY

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Inspired by bplus...
« Reply #1 on: October 25, 2021, 08:35:53 pm »
Nice how you handle a string that doesn't fit on one line across the screen.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Inspired by bplus...
« Reply #2 on: October 25, 2021, 09:45:47 pm »
Thanks. There are so many ways to make and apply various algorithms for text manipulation and a lot of it depends if you are using a single variable or arrays. This was made for a single variable. An array model would require more functions to wrap text. It's just something I'm kicking around and if I can get it to work to translate my SCREEN 0 WP into a graphics screen WP, I could add underlining text for hypertext usage. Of course using the overlay method could provide that display, too. It's nice to have so many options.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Inspired by bplus...
« Reply #3 on: October 27, 2021, 05:01:14 pm »
Well, maybe some more math crap needed, as I haven't tested this a whole lot. It is supposed to be a way to set top, bottom, left, and right margins, and work with various font sizes to put letters to the screen using either an overlay or direct graphics display. It wraps words and displays them in a graphics screen with a page border and boxes around each non-space letter. That means if you take this with you on your Blue Origin flight, it won't work once you leave the atmosphere. Sorry about that...

Input nothing at the first prompt to get the default text phrase. Input 1 at the two other prompts for normal text spacing or increase or decrease either, as desired. Esc to quit, or any key to run again.

Code: QB64: [Select]
  1. DIM SHARED overlay, olay
  2.  
  3. Screen0 = _NEWIMAGE(80, 42, 0)
  4. SCREEN Screen0
  5.  
  6. LINE INPUT "Input a phrase: "; text$
  7. IF text$ = "" THEN text$ = "I'd like to solve the puzzle, please!"
  8. PRINT: LINE INPUT "Input horizontal letter-spacing 1.0 to 3.0: "; a$
  9. a = VAL(a$): IF a = 0 THEN a = 0 ELSE IF a > 3 THEN a = 3
  10. spacerx = a
  11. PRINT: LINE INPUT "Input vertical letter-spacing 1.0 to 3.0: "; a$
  12. a = VAL(a$): IF a = 0 THEN a = 0 ELSE IF a > 3 THEN a = 3
  13. spacery = a
  14. CLS: PRINT text$
  15.  
  16. font = _LOADFONT("lucon.ttf", 60, "monospace")
  17. IF font <= 0 THEN font = 16
  18.  
  19. olay = -1
  20. _DEST overlay
  21. _FONT font
  22. COLOR _RGB(255, 102, 0), 0
  23.  
  24. row = 1: col = 1: r1% = 255: r2% = 0: r3% = 0
  25. ml = 2: mr = 2: mt = 1: mb = 1
  26. COLOR _RGB(255, 255, 255)
  27. REM spacerx and spacery were assigned upon input.
  28. y = row: x = col: j = 0
  29. maxcpl% = 1 + INT((_WIDTH - ((ml + mr) * _FONTWIDTH)) / (_FONTWIDTH * spacerx)) ' Determines the max number of characters per line.
  30. maxrows% = INT((_HEIGHT / _FONTHEIGHT) / spacery) - (mt + mb) + 1
  31.  
  32. LINE ((ml - .5) * _FONTWIDTH, (mt - .5) * _FONTHEIGHT)-(((ml - .5) * _FONTWIDTH) + (maxcpl% * _FONTWIDTH * spacerx) + (.5 * _FONTWIDTH), maxrows% * spacery * _FONTHEIGHT + _FONTHEIGHT / 2), _RGB(255, 255, 255), B
  33.  
  34. flag = 0: j = 0
  35.     _LIMIT 30
  36.     b$ = INKEY$
  37.     IF show_letters% = 0 THEN
  38.         FOR i = 1 TO LEN(text$)
  39.             t$ = MID$(text$, i, 1)
  40.             k = INSTR(i, text$ + " ", " ") - i
  41.            
  42.             j = j + 1
  43.  
  44.             IF j = 1 THEN
  45.                SELECT CASE j + LEN((MID$(text$ + " ", i, k)))
  46.                     CASE IS = maxcpl% + 1 ' Space in margin.
  47.                         flag = 1 ' Negate leading space on next print line.
  48.                     CASE IS > maxcpl% + 1 ' Word is larger than page width.
  49.                         flag = -1
  50.                 END SELECT
  51.             END IF
  52.  
  53.             l = LEN((MID$(text$ + " ", i, k)))
  54.  
  55.             IF j + l > maxcpl% AND flag = 0 OR flag = 1 AND j > maxcpl% OR flag = -1 AND j > maxcpl% THEN
  56.                 IF row + 1 = maxrows% THEN EXIT FOR
  57.                 x = col: y = y + spacery: j = 0
  58.                 IF flag = 1 THEN skip = 1 ' Negates one leading space.
  59.                 flag = 0: i = i - 1: row = row + 1
  60.             ELSE
  61.                 IF skip = 0 THEN
  62.                     PSL y + mt, x + ml, t$, r1%, r2%, r3%
  63.                     x = x + spacerx
  64.                 ELSE
  65.                     skip = 0: j = 0
  66.                 END IF
  67.             END IF
  68.         NEXT
  69.         _DISPLAY
  70.         show_letters% = -1
  71.     END IF
  72.  
  73.  
  74. _FREEIMAGE overlay
  75.  
  76. IF b$ = CHR$(27) THEN SYSTEM
  77.  
  78.  
  79. SUB PSL (y, x, t$, r1%, r2%, r3%)
  80.     IF t$ <> CHR$(32) THEN CALL box(y, x, r1%, r2%, r3%)
  81.     _PRINTSTRING ((x - 1) * _FONTWIDTH, (y - 1) * _FONTHEIGHT), t$
  82.     IF olay THEN CALL overlay_display
  83.  
  84. SUB box (y, x, r1%, r2%, r3%)
  85.     LINE ((x - 1) * _FONTWIDTH, ((y - 1) * _FONTHEIGHT))-((x - 1) * _FONTWIDTH + _FONTWIDTH, ((y - 1) * _FONTHEIGHT) + _FONTHEIGHT), _RGB(r1%, r2%, r3%), B , 255
  86.  
  87. SUB overlay_display
  88.     overlay_hardware = _COPYIMAGE(overlay, 33)
  89.     _PUTIMAGE (0, 0), overlay_hardware

Pete

@FellippeHeitor BTW - I had some weird results I noticed ONLY when I changed the code and did a recomplie/run with the IDE F5 key. Many times it would only display part of the default text! For example: I input nothing, 1 and 1 and it displayed only part of the default text. Then I pressed a key to rerun, same parameters, and it displayed the entire text, as expected. I'm using v2.0. Any thoughts? Can you reproduce it? I just did by loading the program, typing REM to line 3, and then F5 to compile and run. I then pressed Enter, 1 and Enter, 1 and Enter. It only printed to "I'd like to solve the puzzle," leaving out the please! Very impolite! You'd think I was running FB. :D Anyway, I then pressed a key, re-entered the same parameters, and on that an all other subsequent run loops, it worked fine.
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Inspired by bplus...
« Reply #4 on: October 27, 2021, 07:49:05 pm »
Displays everything for me on the first run.

how ever the more I run it the more it begins to do weird things like this:
(and of course you use _DISPLAY so as soon as anything displays over the window its destroyed! so this screen shot is not the original)
missing text seems to be totally random.(and I do wonder if it has to do with _DISPLAY and a race condition)
Granted after becoming radioactive I only have a half-life!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Inspired by bplus...
« Reply #5 on: October 27, 2021, 08:12:25 pm »
@Cobalt Okay, we've now established this is something that will happen on not just my system. So I made just a couple of changes to allow it to work without the overlay feature. Removing the hardware overlay solves the issue, so the issue appears to be with PUTIMAGE and COPYIMAGE.

This non-overlay version will run correctly each time...

Code: QB64: [Select]
  1. DIM SHARED overlay, olay
  2.  
  3. Screen0 = _NEWIMAGE(80, 42, 0)
  4. SCREEN Screen0
  5.  
  6. LINE INPUT "Input a phrase: "; text$
  7. IF text$ = "" THEN text$ = "I'd like to solve the puzzle, please!"
  8. PRINT: LINE INPUT "Input horizontal letter-spacing 1.0 to 3.0: "; a$
  9. a = VAL(a$): IF a = 0 THEN a = 0 ELSE IF a > 3 THEN a = 3
  10. spacerx = a
  11. PRINT: LINE INPUT "Input vertical letter-spacing 1.0 to 3.0: "; a$
  12. a = VAL(a$): IF a = 0 THEN a = 0 ELSE IF a > 3 THEN a = 3
  13. spacery = a
  14. CLS: PRINT text$
  15.  
  16. font = _LOADFONT("lucon.ttf", 60, "monospace")
  17. IF font <= 0 THEN font = 16
  18.  
  19. olay = 0
  20.  
  21. IF olay THEN
  22.     _DEST overlay
  23.     SCREEN overlay
  24.  
  25. _FONT font
  26. COLOR _RGB(255, 102, 0), 0
  27.  
  28. row = 1: col = 1: r1% = 255: r2% = 0: r3% = 0
  29. ml = 2: mr = 2: mt = 1: mb = 1
  30. COLOR _RGB(255, 255, 255)
  31. REM spacerx and spacery were assigned upon input.
  32. y = row: x = col: j = 0
  33.  
  34. maxcpl% = 1 + INT((_WIDTH - ((ml + mr) * _FONTWIDTH)) / (_FONTWIDTH * spacerx)) ' Determines the max number of characters per line.
  35. maxrows% = INT((_HEIGHT / _FONTHEIGHT) / spacery) - (mt + mb) + 1
  36.  
  37. LINE ((ml - .5) * _FONTWIDTH, (mt - .5) * _FONTHEIGHT)-(((ml - .5) * _FONTWIDTH) + (maxcpl% * _FONTWIDTH * spacerx) + (.5 * _FONTWIDTH), maxrows% * spacery * _FONTHEIGHT + _FONTHEIGHT / 2), _RGB(255, 255, 255), B
  38.  
  39. flag = 0: j = 0
  40.     _LIMIT 30
  41.     b$ = INKEY$
  42.     IF show_letters% = 0 THEN
  43.         FOR i = 1 TO LEN(text$)
  44.             t$ = MID$(text$, i, 1)
  45.             k = INSTR(i, text$ + " ", " ") - i
  46.  
  47.             j = j + 1
  48.  
  49.             IF j = 1 THEN
  50.  
  51.                 SELECT CASE j + LEN((MID$(text$ + " ", i, k)))
  52.                     CASE IS = maxcpl% + 1 ' Space in margin.
  53.                         flag = 1 ' Negate leading space on next print line.
  54.                     CASE IS > maxcpl% + 1 ' Word is larger than page width.
  55.                         flag = -1
  56.                 END SELECT
  57.             END IF
  58.  
  59.             l = LEN((MID$(text$ + " ", i, k)))
  60.  
  61.             IF j + l > maxcpl% AND flag = 0 OR flag = 1 AND j > maxcpl% OR flag = -1 AND j > maxcpl% THEN
  62.                 IF row + 1 = maxrows% THEN EXIT FOR
  63.                 x = col: y = y + spacery: j = 0
  64.                 IF flag = 1 THEN skip = 1 ' Negates one leading space.
  65.                 flag = 0: i = i - 1: row = row + 1
  66.             ELSE
  67.                 IF skip = 0 THEN
  68.                     PSL y + mt, x + ml, t$, r1%, r2%, r3%
  69.                     x = x + spacerx
  70.                 ELSE
  71.                     skip = 0: j = 0
  72.                 END IF
  73.             END IF
  74.         NEXT
  75.         _DISPLAY
  76.         show_letters% = -1
  77.     END IF
  78.  
  79.  
  80. IF olay THEN _FREEIMAGE overlay
  81.  
  82. IF b$ = CHR$(27) THEN SYSTEM
  83.  
  84.  
  85. SUB PSL (y, x, t$, r1%, r2%, r3%)
  86.     IF t$ <> CHR$(32) THEN CALL box(y, x, r1%, r2%, r3%)
  87.     _PRINTSTRING ((x - 1) * _FONTWIDTH, (y - 1) * _FONTHEIGHT), t$
  88.     IF olay THEN CALL overlay_display
  89.  
  90. SUB box (y, x, r1%, r2%, r3%)
  91.     LINE ((x - 1) * _FONTWIDTH, ((y - 1) * _FONTHEIGHT))-((x - 1) * _FONTWIDTH + _FONTWIDTH, ((y - 1) * _FONTHEIGHT) + _FONTHEIGHT), _RGB(r1%, r2%, r3%), B , 255
  92.  
  93. SUB overlay_display
  94.     overlay_hardware = _COPYIMAGE(overlay, 33)
  95.     _PUTIMAGE (0, 0), overlay_hardware

So the putimage and copyimage seem pretty straight forward, unless I'm somehow missing something in my (Steve's) method. Maybe this needs to be investigated as a QB64 bug?

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Inspired by bplus...
« Reply #6 on: October 27, 2021, 09:22:03 pm »
Your also using a HARDWARE image, not just COPYIMAGE and PUTIMAGE.  But I don't think there is anyway to pull off what your doing with just using plan a old image layer. since your trying to use graphics and text only at the same time.
Granted after becoming radioactive I only have a half-life!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Inspired by bplus...
« Reply #7 on: October 27, 2021, 10:59:11 pm »
Guys, you know what we haven't tried is _DELAY. @Cobalt You mentioned a "race" issue, and let's investigate that a bit...

So I put a small delay between the hardware overlay and PUTIMAGE statement. It fixed the unfinished display problem, but I still get strange timing results. The run that would fail without the delay inserted simply prints to the screen slower! When I run it again, it is printed almost all at once. So something is not consistent with the hardware rendering, and I notice it every time I change the code and do the first run after the change.

Hardware overlay activated, but with a small delay...
Code: QB64: [Select]
  1. DIM SHARED overlay, olay
  2.  
  3. Screen0 = _NEWIMAGE(80, 42, 0)
  4. SCREEN Screen0
  5.  
  6. LINE INPUT "Input a phrase: "; text$
  7. IF text$ = "" THEN text$ = "I'd like to solve the puzzle, please!"
  8. PRINT: LINE INPUT "Input horizontal letter-spacing 1.0 to 3.0: "; a$
  9. a = VAL(a$): IF a = 0 THEN a = 0 ELSE IF a > 3 THEN a = 3
  10. spacerx = a
  11. PRINT: LINE INPUT "Input vertical letter-spacing 1.0 to 3.0: "; a$
  12. a = VAL(a$): IF a = 0 THEN a = 0 ELSE IF a > 3 THEN a = 3
  13. spacery = a
  14. CLS: PRINT text$
  15.  
  16. font = _LOADFONT("lucon.ttf", 60, "monospace")
  17. IF font <= 0 THEN font = 16
  18.  
  19. olay = -1
  20.  
  21. IF olay THEN
  22.     _DEST overlay
  23.     SCREEN overlay
  24.  
  25. _FONT font
  26. COLOR _RGB(255, 102, 0), 0
  27.  
  28. row = 1: col = 1: r1% = 255: r2% = 0: r3% = 0
  29. ml = 2: mr = 2: mt = 1: mb = 1
  30. COLOR _RGB(255, 255, 255)
  31. REM spacerx and spacery were assigned upon input.
  32. y = row: x = col: j = 0
  33.  
  34. maxcpl% = 1 + INT((_WIDTH - ((ml + mr) * _FONTWIDTH)) / (_FONTWIDTH * spacerx)) ' Determines the max number of characters per line.
  35. maxrows% = INT((_HEIGHT / _FONTHEIGHT) / spacery) - (mt + mb) + 1
  36.  
  37. LINE ((ml - .5) * _FONTWIDTH, (mt - .5) * _FONTHEIGHT)-(((ml - .5) * _FONTWIDTH) + (maxcpl% * _FONTWIDTH * spacerx) + (.5 * _FONTWIDTH), maxrows% * spacery * _FONTHEIGHT + _FONTHEIGHT / 2), _RGB(255, 255, 255), B
  38.  
  39. flag = 0: j = 0
  40.     _LIMIT 30
  41.     b$ = INKEY$
  42.     IF show_letters% = 0 THEN
  43.         FOR i = 1 TO LEN(text$)
  44.             t$ = MID$(text$, i, 1)
  45.             k = INSTR(i, text$ + " ", " ") - i
  46.  
  47.             j = j + 1
  48.  
  49.             IF j = 1 THEN
  50.  
  51.                 SELECT CASE j + LEN((MID$(text$ + " ", i, k)))
  52.                     CASE IS = maxcpl% + 1 ' Space in margin.
  53.                         flag = 1 ' Negate leading space on next print line.
  54.                     CASE IS > maxcpl% + 1 ' Word is larger than page width.
  55.                         flag = -1
  56.                 END SELECT
  57.             END IF
  58.  
  59.             l = LEN((MID$(text$ + " ", i, k)))
  60.  
  61.             IF j + l > maxcpl% AND flag = 0 OR flag = 1 AND j > maxcpl% OR flag = -1 AND j > maxcpl% THEN
  62.                 IF row + 1 = maxrows% THEN EXIT FOR
  63.                 x = col: y = y + spacery: j = 0
  64.                 IF flag = 1 THEN skip = 1 ' Negates one leading space.
  65.                 flag = 0: i = i - 1: row = row + 1
  66.             ELSE
  67.                 IF skip = 0 THEN
  68.                     PSL y + mt, x + ml, t$, r1%, r2%, r3%
  69.                     x = x + spacerx
  70.                 ELSE
  71.                     skip = 0: j = 0
  72.                 END IF
  73.             END IF
  74.         NEXT
  75.         _DISPLAY
  76.         show_letters% = -1
  77.     END IF
  78.  
  79.  
  80. IF olay THEN _FREEIMAGE overlay
  81.  
  82. IF b$ = CHR$(27) THEN SYSTEM
  83.  
  84.  
  85. SUB PSL (y, x, t$, r1%, r2%, r3%)
  86.     IF t$ <> CHR$(32) THEN CALL box(y, x, r1%, r2%, r3%)
  87.     _PRINTSTRING ((x - 1) * _FONTWIDTH, (y - 1) * _FONTHEIGHT), t$
  88.     IF olay THEN CALL overlay_display
  89.  
  90. SUB box (y, x, r1%, r2%, r3%)
  91.     LINE ((x - 1) * _FONTWIDTH, ((y - 1) * _FONTHEIGHT))-((x - 1) * _FONTWIDTH + _FONTWIDTH, ((y - 1) * _FONTHEIGHT) + _FONTHEIGHT), _RGB(r1%, r2%, r3%), B , 255
  92.  
  93. SUB overlay_display
  94.     overlay_hardware = _COPYIMAGE(overlay, 33)
  95.     _DELAY .01
  96.     _PUTIMAGE (0, 0), overlay_hardware

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Inspired by bplus...
« Reply #8 on: October 28, 2021, 12:13:51 pm »
Don't know anything about Hardware images so that part wasn't inspired by me.

I think you @Pete are using it to cheat the system to get graphics effect in text mode screen, correct?

I know hardware image has some advantage either speed or permanence of image but are you @Pete using it for that advantage? probably the permanence part, probably should ask Steve as it came from him.

I am thinking a hardware image could only be background, so overlaying it is confusing to me.