QB64.org Forum

Active Forums => Programs => Topic started by: The Librarian on August 10, 2019, 08:49:24 PM

Title: Samples/Toolbox re-awakening. Call for entries.
Post by: The Librarian on August 10, 2019, 08:49:24 PM
As the topic says, it's time we expand our Samples Gallery and Toolbox. Please reply to this post with links to existing threads in Programs with code that qualifies.

First things first though - is everyone happy with the filled circle/ellipse code up there?
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: bplus on August 10, 2019, 09:20:08 PM
Here is a link to a number of tools:
https://www.qb64.org/forum/index.php?topic=1511.0

First, I have been very happy with filled circle and ellipse code actually has come in handy for me, thanks!
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: SMcNeill on August 10, 2019, 09:29:12 PM
ConvertOffset: http://qb64.freeforums.net/thread/52/convert-offset-integer64

MEMSort: http://qb64.freeforums.net/thread/28/mem-sort

ExtendedTimer: http://qb64.freeforums.net/thread/20/extended-timer-uet

SaveImage: (needs updated on forums to the latest version and then linked)

POSIX File and Dir Listing to Arrays: http://qb64.freeforums.net/thread/63/file-directory-listing-arrays

Spell Checker: https://www.qb64.org/forum/index.php?topic=1587.0

MemToHex: https://www.qb64.org/forum/index.php?topic=1553.0

All of the above are handy little routines which I keep in my toolbox and have reused in a ton of different ways.




Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: STxAxTIC on August 11, 2019, 04:39:32 AM
Thanks boys.

I happen to know the Librarian connects through a mobile hotspot so updates may a bit slow.

The old "saveimage" routine is a gem Steevo! Resurrect that for us, I bet the newbies will be thrilled!
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: STxAxTIC on August 11, 2019, 05:53:25 AM
Not sure where to begin this discussion, but may as well be here.

So MEM is different than all QB64 commands, amirite? It's strange from a QB45 point of view, takes a minute to master from a QB64 point of view, and I've noticed that almost half of Steve's tools involve it.

So the question is, should we cram MEM-related stuff into its own category? Something all-inclusive to MEM, including tutorials. It may be sortof a turnoff to see all the MEM stuff scattered into everything else. --- OR, is this 100% off base? ... because Toolbox entries should be black boxes that shouldnt be looked into... hmmm... opinions?
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: Petr on August 11, 2019, 06:05:13 AM
Hi. I am again last.


Please look to my previous answer  https://www.qb64.org/forum/index.php?topic=1566.msg107875#msg107875
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: pforpond on August 11, 2019, 06:09:15 AM
As the topic says, it's time we expand our Samples Gallery and Toolbox. Please reply to this post with links to existing threads in Programs with code that qualifies.

First things first though - is everyone happy with the filled circle/ellipse code up there?

I'm curious as to what 'code that qualifies' means :) Is there a criteria to me met?
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: STxAxTIC on August 11, 2019, 06:16:02 AM
Quote
I'm curious as to what 'code that qualifies' means :) Is there a criteria to me met?

You got it m8.

https://www.qb64.org/forum/index.php?topic=178.0 (https://www.qb64.org/forum/index.php?topic=178.0)

https://www.qb64.org/forum/index.php?topic=1062.0 (https://www.qb64.org/forum/index.php?topic=1062.0)
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: pforpond on August 11, 2019, 06:33:08 AM
You got it m8.

https://www.qb64.org/forum/index.php?topic=178.0 (https://www.qb64.org/forum/index.php?topic=178.0)

https://www.qb64.org/forum/index.php?topic=1062.0 (https://www.qb64.org/forum/index.php?topic=1062.0)

Thank you. Looks like I probably don't comment my code enough to qualify. I'd submit this (https://www.qb64.org/forum/index.php?topic=34.msg167#msg167) but I didn't post the source code in the thread and it was all spaghetti anyways :)
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: SMcNeill on August 11, 2019, 08:07:49 AM
Not sure where to begin this discussion, but may as well be here.

So MEM is different than all QB64 commands, amirite? It's strange from a QB45 point of view, takes a minute to master from a QB64 point of view, and I've noticed that almost half of Steve's tools involve it.

So the question is, should we cram MEM-related stuff into its own category? Something all-inclusive to MEM, including tutorials. It may be sortof a turnoff to see all the MEM stuff scattered into everything else. --- OR, is this 100% off base? ... because Toolbox entries should be black boxes that shouldnt be looked into... hmmm... opinions?

_MEM really isn’t that strange; it’s QB64’s updated take on PEEK and POKE.  Since “toolboxes” tend to contain those routines which you use over and over again, they tend to be as efficient as possible, so they’ll plug into any program — and you can’t beat the speed and performance of direct memory access I Which MEM gives.  I think a lot of toolbox code will make use of MEM, when it can.  Probably no reason to separate them into their own subfolder. ;)
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: bplus on August 11, 2019, 09:04:19 AM
Not sure where to begin this discussion, but may as well be here.

So MEM is different than all QB64 commands, amirite? It's strange from a QB45 point of view, takes a minute to master from a QB64 point of view, and I've noticed that almost half of Steve's tools involve it.

So the question is, should we cram MEM-related stuff into its own category? Something all-inclusive to MEM, including tutorials. It may be sortof a turnoff to see all the MEM stuff scattered into everything else. --- OR, is this 100% off base? ... because Toolbox entries should be black boxes that shouldnt be looked into... hmmm... opinions?

Categories would be great!

Who wants to look for a saw in the sandpaper pile or a screwdriver in metric socket sets?

But can this be done on a forum? 0f course it can, if there is a Will to do it!  ;-)

If categories are by function, MEM routines would span many categories for a speedier way to do a numbers crunching task, is my thought.
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: bplus on August 11, 2019, 09:18:36 AM
For my first official submission I would like to present Split1000:

We worked on this a bit here at the forum this is my version from my toolbox.
Code: QB64: [Select]
  1. 'notes: REDIM the array(0) to be loaded before calling Split '<<<<<<<<<<<<<<<<<<<<<<< IMPORTANT!!!!
  2. SUB Split1000 (mystr AS STRING, delim AS STRING, arr() AS STRING)
  3.     ' bplus modifications of Galleon fix of Bulrush Split reply #13
  4.     ' http://xmaxw.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=1612.0
  5.     ' this sub further developed and tested here: \test\Strings\Split test.bas
  6.     DIM copy AS STRING, p AS LONG, curpos AS LONG, arrpos AS LONG, dpos AS LONG, LD AS INTEGER
  7.  
  8.     copy = mystr 'make copy since we are messing with mystr when the delimiter is a space
  9.  
  10.     'special case if delim is space, probably want to remove all excess space
  11.     IF delim = " " THEN
  12.         copy = RTRIM$(LTRIM$(copy))
  13.         p = INSTR(copy, "  ")
  14.         WHILE p > 0
  15.             copy = MID$(copy, 1, p - 1) + MID$(copy, p + 1)
  16.             p = INSTR(copy, "  ")
  17.         WEND
  18.     END IF
  19.     curpos = 1
  20.     arrpos = 0
  21.     LD = LEN(delim) 'mod
  22.     dpos = INSTR(curpos, copy, delim)
  23.     DO UNTIL dpos = 0
  24.         arr(arrpos) = MID$(copy, curpos, dpos - curpos)
  25.         arrpos = arrpos + 1
  26.         IF arrpos > UBOUND(arr) THEN REDIM _PRESERVE arr(UBOUND(arr) + 1000) AS STRING
  27.         curpos = dpos + LD
  28.         dpos = INSTR(curpos, copy, delim)
  29.     LOOP
  30.     arr(arrpos) = MID$(copy, curpos)
  31.     REDIM _PRESERVE arr(arrpos) AS STRING 'need this line? YES to get the ubound correct
  32.  
  33.  

Function: it takes a string, say a whole file gulped in one go with a binary get, and parses the string into a string array using: the specified string to split, delimiter and array name to load.

My version handles splits delimited by spaces specially by removing extra spaces first. 1000 was added to name when Steve recommended only using REDIM _PRESERVE every 1000 times or so instead of at every split.

What else do you need? I have the code used to test the routine.

I am partial to handling the space delimiter specially because this was originally used for space only delimited parser for interpreters I played with but that can be removed and special filter applied in separate function.
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: STxAxTIC on August 11, 2019, 10:09:12 AM
Okay, we've heard from both sides on the "mem categories" thing...

I think for now, until the collection proves unruly, that our existing tag system will work. Nay on categories. I'll "tell" the Librarian... :-)
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: STxAxTIC on August 11, 2019, 12:33:06 PM
bplus-

I The Librarian was looking to add BIN$ found at https://www.qb64.org/forum/index.php?topic=1511.0 (https://www.qb64.org/forum/index.php?topic=1511.0)

Code: QB64: [Select]
  1. PRINT 2 XOR 3 ' 2 is 10 in binary, 3 is 11 in binary where there is a bit in one but not the other for 2 and 3 in one's position
  2. PRINT 2 XOR 4 '= 6?  yes
  3. PRINT 2 XOR 10 ' = 8,  10 XOR 1010 = 1000 = 8
  4. PRINT &B0
  5. PRINT &B1
  6. PRINT &B10
  7. PRINT &B11
  8. PRINT &B100
  9.  
  10. 'does QB64 reverse &B numbers conver HEX$ for base 16, OCT$ for base 8, no base 2?
  11.     INPUT "Enter integer to convert to binary "; test
  12.     PRINT "Dec2Base$(test, 2) = "; Dec2Base$(test, 2), "BIN$(test) = "; BIN$(test)
  13.     PRINT "and  VAL(BIN$(test)) ="; VAL(BIN$(test))
  14.     PRINT
  15. LOOP UNTIL test = 0
  16.  
  17. 'what is limit _integer64 can take
  18. i = 1000000000
  19.     i = i + 1000000000
  20.     PRINT i
  21. LOOP UNTIL i >= i + 1
  22.  
  23. 'maybe _BIN$
  24. FUNCTION Dec2Base$ (nDec AS INTEGER, bs AS INTEGER)
  25.     DIM n AS INTEGER, p AS INTEGER, pow AS INTEGER, d AS INTEGER, b$
  26.     n = nDec 'copy this because or nDec gets changed effecting main code
  27.     WHILE bs ^ p <= n
  28.         p = p + 1
  29.     WEND
  30.     FOR pow = p TO 0 STEP -1
  31.         IF n >= bs ^ pow THEN
  32.             d = INT(n / bs ^ pow)
  33.             IF d < 10 THEN
  34.                 b$ = b$ + _TRIM$(STR$(d))
  35.             ELSE
  36.                 b$ = b$ + CHR$(65 + d - 10)
  37.             END IF
  38.             n = n - d * bs ^ pow
  39.         ELSE
  40.             IF b$ <> "" THEN b$ = b$ + "0"
  41.         END IF
  42.     NEXT
  43.     IF b$ = "" THEN b$ = "0"
  44.     Dec2Base$ = b$
  45.  
  46. FUNCTION BIN$ (integerBase10 AS _INTEGER64)
  47.     DIM i AS _INTEGER64, pow AS INTEGER, b$
  48.     IF integerBase10 = 0 THEN BIN$ = "&B0": EXIT FUNCTION
  49.     i = integerBase10 'copy
  50.     pow = 0
  51.     WHILE i > 0
  52.         IF i AND 2 ^ pow THEN
  53.             b$ = "1" + b$
  54.             i = i - 2 ^ pow
  55.         ELSE
  56.             b$ = "0" + b$
  57.         END IF
  58.         pow = pow + 1
  59.     WEND
  60.     BIN$ = "&B" + b$
  61.  

Just want to make sure that:
(i) This is the proper link
(ii) Code in top post is the code you want to show
(iii) You know entering "0" for input causes the program to loop infinitely

Thanks!

------------------------------------------------------------------------------------------

EDIT:

Regarding Split1000: Yes, we need some dead-simple test code for that, 'specially given the huge warning at the top.
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: bplus on August 11, 2019, 01:21:04 PM
Hi STxAxTIC,

Here is just the BIN$ function with just the tester code for it.
(BTW that wasn't an infinite loop that was a test of _INTEGER64, I was testing a number of things with main code.)

Code: QB64: [Select]
  1.  
  2. ' QB64 can reverse &H numbers with HEX$ and &O numbers with OCT$
  3. ' but what about &B numbers?
  4.  
  5. ' Here is BIN$
  6.  
  7.     INPUT "(0 ends test) Enter a positive integer to convert to binary "; test
  8.     PRINT "BIN$(test) = "; BIN$(test)
  9.     PRINT "and  VAL(BIN$(test)) ="; VAL(BIN$(test))
  10.     PRINT
  11. LOOP UNTIL test = 0
  12.  
  13. 'BIN$ creates a string = the base 2 equivalent of the Base 10 positive integer
  14. 'and is prefixed with &B to work with VAL
  15. FUNCTION BIN$ (integerBase10 AS _INTEGER64)
  16.     DIM i AS _INTEGER64, pow AS INTEGER, b$
  17.     IF integerBase10 = 0 THEN BIN$ = "&B0": EXIT FUNCTION
  18.     i = integerBase10 'copy
  19.     pow = 0
  20.     WHILE i > 0
  21.         IF i AND 2 ^ pow THEN
  22.             b$ = "1" + b$
  23.             i = i - 2 ^ pow
  24.         ELSE
  25.             b$ = "0" + b$
  26.         END IF
  27.         pow = pow + 1
  28.     WEND
  29.     BIN$ = "&B" + b$
  30.  

I will get going on split1000 next.

Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: bplus on August 11, 2019, 02:51:49 PM
Hi STxAxTIC

The "huge warning" is just reminder that the array to be loaded has to be a Dynamic String array base 0.

Here is bare essentials, save the code as Split.bas to test a bas file split into file lines:
Code: QB64: [Select]
  1. _TITLE "Split 2019-08-11 update" 'b+ 2019-08-11 application for toolbox code
  2. ' bplus modifications of Galleon fix of Bulrush Split reply #13 http://xmaxw.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=1612.0
  3. ' further modified with Steve McNeill's suggestion to REDIM _PRESERVE in clumps of 1000
  4.  
  5. ' The Split SUB takes a given string and delimiter and breaks the string into a given Dynamic String array base 0.
  6.  
  7. SCREEN _NEWIMAGE(1200, 720, 32)
  8. DIM s$, i, w$
  9.  
  10. ' simple test modify string s$
  11. s$ = "  ,1, 2,     3,   4      ,5   , 6   ,7,   8,   " 'try start and finish 2 blanks
  12. REDIM sa$(0): Split s$, ",", sa$()
  13. FOR i = LBOUND(sa$) TO UBOUND(sa$): PRINT i, "*" + sa$(i) + "*": NEXT
  14. INPUT "Next a test with this code file, press enter "; w$
  15.  
  16. ' test with this bas file saved as  "Split.bas"
  17. IF _FILEEXISTS("Split.bas") THEN
  18.     OPEN "Split.bas" FOR BINARY AS #1
  19.     s$ = SPACE$(LOF(1)): GET #1, , s$: CLOSE #1
  20.     Split s$, CHR$(13) + CHR$(10), sa$() 'test split on the already used array sa$
  21.     FOR i = LBOUND(sa$) TO UBOUND(sa$): PRINT i, sa$(i): NEXT
  22.  
  23. 'notes: the loadMeArray() needs to be dynamic string array with base 0 ie REDIM loadMeArray(0) AS STRING
  24. SUB Split (SplitMeString AS STRING, delim AS STRING, loadMeArray() AS STRING)
  25.     DIM curpos AS LONG, arrpos AS LONG, LD AS LONG, dpos AS LONG
  26.     curpos = 1: arrpos = 0: LD = LEN(delim)
  27.     dpos = INSTR(curpos, SplitMeString, delim)
  28.     DO UNTIL dpos = 0
  29.         loadMeArray(arrpos) = MID$(SplitMeString, curpos, dpos - curpos)
  30.         arrpos = arrpos + 1
  31.         IF arrpos > UBOUND(loadMeArray) THEN REDIM _PRESERVE loadMeArray(UBOUND(loadMeArray) + 1000) AS STRING
  32.         curpos = dpos + LD
  33.         dpos = INSTR(curpos, SplitMeString, delim)
  34.     LOOP
  35.     loadMeArray(arrpos) = MID$(SplitMeString, curpos)
  36.     REDIM _PRESERVE loadMeArray(arrpos) AS STRING 'get the ubound correct
  37.  

Update: just ran a successful test reversing the order of the two tests loading the file into the array and then loading the smaller string into the array, without REDIM to erase.
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: STxAxTIC on August 12, 2019, 08:27:02 AM
Thanks bplus - I see what you've got goin' on here.
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: SMcNeill on August 12, 2019, 09:41:26 AM
' QB64 can reverse &H numbers with HEX$ and &O numbers with OCT$
' but what about &B numbers?

' Here is BIN$

Negative numbers have a different representation depending on which variable type we're using. 

-1 as a BYTE is &B11111111
-2 as a BYTE is &B11111110
-2 as a integer is &B1111111111111110

Which used to be hard to represent and get proper return values back for, but not anymore!  I present to you an expanded BIN$ which you can use for both positive and negative values:

Code: QB64: [Select]
  1.  
  2. n$ = bin$(12, 1)
  3. PRINT n$, VAL(n$)
  4.  
  5. n$ = bin$(-2, 1) 'byte
  6. PRINT n$, VAL(n$)
  7.  
  8. n$ = bin$(-2, 2) 'integer
  9. PRINT n$, VAL(n$)
  10.  
  11. FUNCTION bin$ (n AS _INTEGER64, Rbytes AS _BYTE)
  12.     STATIC m AS _MEM
  13.     DIM b AS _BYTE, i AS INTEGER, l AS LONG, i64 AS _INTEGER64
  14.     IF n < 1 THEN 'the user needs to tell us how many return bytes they expect
  15.         SELECT CASE Rbytes 'assign the value to the proper mem type
  16.             CASE 1: m = _MEM(b): l = 1: b = n '1 for a byte
  17.             CASE 2: m = _MEM(i): l = 2: i = n '2 for an integer
  18.             CASE 4:: m = _MEM(l): l = 4: l = n '4 for a long
  19.             CASE 8: m = _MEM(i64): l = 8: i64 = n '8 for an integer64
  20.             CASE ELSE: bin$ = "WRONG RETURN TYPE!": EXIT FUNCTION
  21.         END SELECT
  22.     ELSE
  23.         m = _MEM(n): l = 8 'just use the number as we passed it
  24.     END IF
  25.  
  26.     FOR i1 = 0 TO l - 1
  27.         FOR j = 0 TO 7 '8 bytes per length and 8 bits in each byte
  28.             IF _MEMGET(m, m.OFFSET + i1, _BYTE) AND 2 ^ j THEN b$ = "1" + b$ ELSE b$ = "0" + b$
  29.     NEXT j, i1
  30.     bin$ = "&B" + MID$(b$, INSTR(b$, "1"))
  31.  
  32.  



Or, for those who like to keep BIN$ simple, the function could be easily broken down into 2 parts -- bin$ and nbin$ (negative bin$), as so:

Code: QB64: [Select]
  1. n$ = bin$(12)
  2. PRINT n$, VAL(n$)
  3.  
  4. n$ = nbin$(-2, 1) 'byte
  5. PRINT n$, VAL(n$)
  6.  
  7. n$ = nbin$(-2, 2) 'integer
  8. PRINT n$, VAL(n$)
  9.  
  10.     STATIC m AS _MEM
  11.     IF n < 1 THEN bin$ = "WRONG RETURN TYPE!": EXIT FUNCTION
  12.     m = _MEM(n)
  13.     FOR i1 = 0 TO 7: FOR j = 0 TO 7 '8 bytes per byte and 8 bits in each byte
  14.             IF _MEMGET(m, m.OFFSET + i1, _BYTE) AND 2 ^ j THEN b$ = "1" + b$ ELSE b$ = "0" + b$
  15.     NEXT j, i1
  16.     bin$ = "&B" + MID$(b$, INSTR(b$, "1"))
  17.  
  18. FUNCTION nbin$ (n AS _INTEGER64, Rbytes AS _BYTE) 'the user needs to tell us how many return bytes they expect
  19.     STATIC m AS _MEM
  20.     DIM b AS _BYTE, i AS INTEGER, l AS LONG, i64 AS _INTEGER64
  21.     SELECT CASE Rbytes 'assign the value to the proper mem type
  22.         CASE 1: m = _MEM(b): l = 1: b = n '1 for a byte
  23.         CASE 2: m = _MEM(i): l = 2: i = n '2 for an integer
  24.         CASE 4:: m = _MEM(l): l = 4: l = n '4 for a long
  25.         CASE 8: m = _MEM(i64): l = 8: i64 = n '8 for an integer64
  26.         CASE ELSE: nbin$ = "WRONG RETURN TYPE!": EXIT FUNCTION
  27.     END SELECT
  28.     FOR i1 = 0 TO l - 1: FOR j = 0 TO 7 '8 bytes per length and 8 bits in each byte
  29.             IF _MEMGET(m, m.OFFSET + i1, _BYTE) AND 2 ^ j THEN b$ = "1" + b$ ELSE b$ = "0" + b$
  30.     NEXT j, i1
  31.     nbin$ = "&B" + MID$(b$, INSTR(b$, "1"))
  32.  

I don't know if you guys would prefer either of these over the version Bplus posted, but I thought I'd offer them for you to look at.
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: bplus on August 12, 2019, 10:42:31 AM
On converting negative integers in different bases:

Ideally, if BIN$ could handle both positive and negative integers I'd prefer that but if I have to say how many bytes then definitely prefer just doing positive, so nBin$ with 2nd argument of bytes is great additional tool for those who might need that.

BTW I doubt HEX$ and OCT$ handle negatives either, so a tool for all 3 handling negatives?
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: bplus on August 12, 2019, 11:14:16 AM
Hi STxAxTIC,

A couple of comments on the Split1000 entry to tool box, I hope you don't think this picky.

I did rename the sub simply Split, so the title for the tool might be just Split, though Split1000 has a catchy ring. :)

Your 2nd line in description:
Quote
Description:
Split receives a string (or entire text file) along with a delimiter argument (such as space, semicolon, tab, etc.) and prepares an array to store the string in fragments. The Nth member of the resulting array is the sub-string between the N-1 and Nth delimiter in the original string.

Did not ring quite right but got me thinking the number of delimiters and the number of strings loaded to the array.
It is true, if there are N delimiters then there are N+1 strings loaded into the zero based array including potentially empty strings to serve as place holders ie if the whole string is just N delimiters, the array will be loaded with N+1 empty strings.

What's not ringing right is that N usually denotes a count and counts usually start at 1. It is very important to stress Split uses a zero based array (and does not exactly prepare one).
It is also true that the last item in the array comes after the last delimiter in the string, counting wise that is N+1.

Thanks for reading carefully and considering this as alternate description:
Quote
'The Split SUB takes a given string and delimiter and loads a given Dynamic String array base 0 with parsed or empty strings s.t. if there are N delimiters there will be N+1 strings and the upper bound of the array will be N.
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: STxAxTIC on August 24, 2019, 04:33:47 PM
Hey fellas,

The Librarian has been slowly chipping away (well, the opposite really) at this archive... Next question is for Steve regarding saving images.

Would you say the save image stuff is ready to crystalize? Namely this post:
https://www.qb64.org/forum/index.php?topic=1605.0 (https://www.qb64.org/forum/index.php?topic=1605.0)

... but save GIF is not:
https://www.qb64.org/forum/index.php?topic=1618.0 (https://www.qb64.org/forum/index.php?topic=1618.0)

- OR -

Should we hold off until the zlib/inflate/deflate stuff is more thoroughly vetted?
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: SMcNeill on August 24, 2019, 04:45:49 PM
Hey fellas,

The Librarian has been slowly chipping away (well, the opposite really) at this archive... Next question is for Steve regarding saving images.

Would you say the save image stuff is ready to crystalize? Namely this post:
https://www.qb64.org/forum/index.php?topic=1605.0 (https://www.qb64.org/forum/index.php?topic=1605.0)

... but save GIF is not:
https://www.qb64.org/forum/index.php?topic=1618.0 (https://www.qb64.org/forum/index.php?topic=1618.0)

- OR -

Should we hold off until the zlib/inflate/deflate stuff is more thoroughly vetted?

SaveGIF works just fine and can be added anytime.  Sooner or later, I’ll update it to allow animations, but probably not for quite some time.  There’s also a SaveBMP and SavePNG library available as well, if someone just wants to save in one of those particular formats.

The SaveImage v2.1 Library works just fine and pulls all those libraries together into one place for us, as well as the JPG format.  For Windows, it allows image saving in BMP, JPG, PNG, and GIF format.  Linux doesn’t play nice with DECLARE LIBRARY with the zlib library, so PNG is excluded from it, but it still works with GIF, BMP, and GIF formats.  (Which is part of the reason why I was working so hard to add the zlib library to my repo.)
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: SMcNeill on August 24, 2019, 05:20:06 PM
And here's a suggestion for something else to go into the toolbox -- SafeLoadFont.  I think the demo will explain its functionality for itself.

Code: QB64: [Select]
  1. SUB SafeLoadFont (font#)
  2.     'Safely loads a font without destroying our current print location and making it revert to the top left corner.
  3.  
  4.     down = CSRLIN: right = POS(0)
  5.     down = (down - 1) * _FONTHEIGHT
  6.     IF _FONTWIDTH <> 0 THEN 'weed start with a monospace font
  7.         right = (right - 1) * _PRINTWIDTH(" ") 'convert the monospace LOC to a graphic X coordinate
  8.     END IF
  9.     _FONT font#
  10.     IF _FONTWIDTH <> 0 THEN 'we swapped to a monospace font
  11.         right = (right / _PRINTWIDTH(" ")) + 1 'convert the graphic X coordinate back to a monospace LOC column
  12.     END IF
  13.     down = (down / _FONTHEIGHT) + 1
  14.     IF right < 1 THEN right = 1
  15.     LOCATE down, right
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: STxAxTIC on August 24, 2019, 05:57:33 PM
Right. I see a SUB up there, but a demo?
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: SMcNeill on August 24, 2019, 06:23:25 PM
Right. I see a SUB up there, but a demo?

&!#@%!! 

Sometimes, I think my clipboard is broken.   I copied the routine from my personal set of "toolbox tools", and wrote a demo for it... Somehow, windows didn't bother to copy the whole demo, and I was left with just the copied sub to paste.   Let's try this one more time:

Code: QB64: [Select]
  1. DIM fonts(3) AS LONG
  2. SCREEN _NEWIMAGE(640, 480, 32)
  3.  
  4. font(0) = _LOADFONT("cour.ttf", 16, "monospace")
  5. font(1) = _LOADFONT("courbd.ttf", 16, "monospace")
  6. font(2) = _LOADFONT("courbi.ttf", 16, "monospace")
  7. font(3) = _LOADFONT("couri.ttf", 16, "monospace")
  8.  
  9. PRINT "First, I want to showcase the exisinging issue with the _FONT command."
  10. PRINT "Let's start out typing something, and then pause before loading a"
  11. PRINT "new font..."
  12.  
  13. _FONT font(0)
  14. COLOR &HFFF00000, &HFFFFFF00
  15. slowprint "NOW WHERE IS OUR PRINT CURSOR AT??"
  16. CLS , 0
  17. COLOR -1, 0
  18.  
  19. PRINT "Now, let's try this same type of thing, while using SafeLoadFont"
  20. PRINT "We'll start typing something, and then pause before safe loading"
  21. PRINT "a new font..."
  22.  
  23.  
  24. slowprint "Slowly watch what happens to our print cursor "
  25. SafeLoadFont font(1)
  26. slowprint "as we use SafeLoadFont to change "
  27. SafeLoadFont font(2)
  28. slowprint "fonts while happily printing to "
  29. SafeLoadFont 16
  30. slowprint "the screen, without a concern in the world! "
  31. PRINT "Now, isn't that something?!"
  32.  
  33.  
  34. SUB slowprint (text$)
  35.     FOR i = 1 TO LEN(text$)
  36.         PRINT MID$(text$, i, 1);
  37.         _LIMIT 5
  38.     NEXT
  39.  
  40. SUB SafeLoadFont (font#)
  41.     'Safely loads a font without destroying our current print location and making it revert to the top left corner.
  42.  
  43.     down = CSRLIN: right = POS(0)
  44.     down = (down - 1) * _FONTHEIGHT
  45.     IF _FONTWIDTH <> 0 THEN 'we start with a monospace font
  46.         right = (right - 1) * _PRINTWIDTH(" ") 'convert the monospace LOC to a graphic X coordinate
  47.     END IF
  48.     _FONT font#
  49.     IF _FONTWIDTH <> 0 THEN 'we swapped to a monospace font
  50.         right = (right / _PRINTWIDTH(" ")) + 1 'convert the graphic X coordinate back to a monospace LOC column
  51.     END IF
  52.     down = (down / _FONTHEIGHT) + 1
  53.     IF right < 1 THEN right = 1
  54.     LOCATE down, right
  55.  

(Do I need to load a copy of the fonts as well?  They're fairly standard ones, which seem to ship with most every OS out there.)
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: bplus on August 27, 2019, 09:27:20 PM
Hi STxAxTIC,

I have been working with Ron on streamlining DATA and from the experience have improved our very useful Split SUB into an even more convenient tool to use by lifting the 0 base restriction from it's usage.

Here is an updated Demo that shows we are using base 1 instead of 0 and a new description for the Split SUB. I hope the Librarian will be pleased that we constantly try to improve our tools and sometimes succeed.
Code: QB64: [Select]
  1. _TITLE "Split demo 2" ' started by B+ on 08-27-2019 to compare to Item$ demo
  2. 'new data setup structure to streamline code in setup
  3.  
  4. SCREEN _NEWIMAGE(400, 300, 32)
  5. 'globals seen inside SUBs and FUNCTIONs because SHARED
  6. DIM SHARED topIndex AS INTEGER '<< this is how many keywords we have
  7. 'VVVV REDIM means dynamic arrays, so can change in setup
  8. REDIM SHARED d(1 TO topIndex) AS STRING
  9.  
  10. 'locals just seen in following main code section
  11. REDIM LIST$(1 TO 1)
  12. setup
  13. FOR i = LBOUND(d) TO UBOUND(d) 'all the keywords are first word$ of d() data array
  14.     Split d(i), ",", LIST$()
  15.     PRINT "Data index:"; i; " "; "String Item:"; LBOUND(LIST$); LIST$(LBOUND(LIST$))
  16.     FOR j = LBOUND(LIST$) + 1 TO UBOUND(LIST$)
  17.         PRINT SPACE$(15); "String Item:"; j; LIST$(j) 'j-1 counts off the items after the first
  18.     NEXT
  19.     PRINT: INPUT "Ok... press enter "; w$
  20.     CLS
  21.  
  22. SUB setup '3rd method of data structure, this is meant to be edited over and over as add to a refine words and substitutes
  23.     topIndex = 5 ' <<< make modifications to d() and then update this number, that's it!
  24.     REDIM d(1 TO topIndex) AS STRING
  25.     d(1) = "Months,January,February,March,April,May,June,July,August,September,October,November,December"
  26.     d(2) = "Days,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday"
  27.     d(3) = "Holidays,NewYears Day,MLK Day,Valentine's Day,Easter,Mother's Day,Memorial Day,Father's Day,Independence Day,Bplus Day,Labor Day,Halloween,Thanksgiving,Christmas"
  28.     d(4) = "Test no further words/phrases in this line. (And the next test will do an empty string.)"
  29.     d(5) = ""
  30.  
  31. 'This SUB will take a given N delimited string, and delimiter$ and creates an array of N+1 strings using the LBOUND of the given dynamic array to load.
  32. 'notes: the loadMeArray() needs to be dynamic string array and will not change the LBOUND of the array it is given.
  33. SUB Split (SplitMeString AS STRING, delim AS STRING, loadMeArray() AS STRING)
  34.     DIM curpos AS LONG, arrpos AS LONG, LD AS LONG, dpos AS LONG 'fix use the Lbound the array already has
  35.     curpos = 1: arrpos = LBOUND(loadMeArray): LD = LEN(delim)
  36.     dpos = INSTR(curpos, SplitMeString, delim)
  37.     DO UNTIL dpos = 0
  38.         loadMeArray(arrpos) = MID$(SplitMeString, curpos, dpos - curpos)
  39.         arrpos = arrpos + 1
  40.         IF arrpos > UBOUND(loadMeArray) THEN REDIM _PRESERVE loadMeArray(LBOUND(loadMeArray) TO UBOUND(loadMeArray) + 1000) AS STRING
  41.         curpos = dpos + LD
  42.         dpos = INSTR(curpos, SplitMeString, delim)
  43.     LOOP
  44.     loadMeArray(arrpos) = MID$(SplitMeString, curpos)
  45.     REDIM _PRESERVE loadMeArray(LBOUND(loadMeArray) TO arrpos) AS STRING 'get the ubound correct
  46.  
  47.  
 

Description:
Quote
This SUB will take a given N delimited string, and delimiter$ and creates an array of N+1 strings using the LBOUND of the given dynamic array to load.
'
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: STxAxTIC on August 27, 2019, 09:44:42 PM
On it, thanks for letting us know!
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: bplus on August 27, 2019, 10:12:45 PM
Hi STxAxTIC,

Another great tool I have used in the past (for evaluator for interpreter) is now new and improved and newly named! For instance it use to use a slow FOR structure and step through string 1 character at a time, now uses While loop and Instr to fly through, it is now also not restricted to just space delimited strings.

Here is the description:
Quote
'Description: Use Item$() Function to treat strings like arrays without having to use an array structure.
' This function does not throw a fit if you ask for an item number (index) it does not have, it just returns an empty string.
' In QB64, Functions can't return arrays through the function name, but they can return strings that the Item$() function can translate like an an array index.  nItem numbers are the same as Counting numbers positive integers starting at 1. eg Item7$ = Item$(CommaDelimitedString$, 7, ",") 'get 7th Item in string

And here is the Demo, you might notice it is allot like the one for improved Split. That is because I was comparing the two because I couldn't decide which is better. Both are designed to be vast improvement over the old RESTORE, READ, DATA system.

Code: QB64: [Select]
  1. _TITLE "Item$ Demo" ' B+ start 2019-08-27
  2.  
  3. 'globals seen inside SUBs and FUNCTIONs because SHARED
  4. DIM SHARED topIndex AS INTEGER '<< this is how many data lines we have, set in setup Sub
  5. 'VVVV REDIM means dynamic arrays, so can change in setup
  6. REDIM SHARED d(1 TO topIndex) AS STRING 'here is our data array see setup SUB
  7.  
  8. 'locals just seen in following main code section
  9. DIM i AS INTEGER, j AS INTEGER, keyword$, w$
  10.  
  11. SCREEN _NEWIMAGE(400, 300, 32)
  12. setup
  13. FOR i = 1 TO topIndex 'all the keywords are first Item$ of d() data array
  14.     keyword$ = Item$(d(i), 1, ","): PRINT i; " "; keyword$
  15.     j = 2
  16.     WHILE Item$(d(i), j, ",") <> "" 'all words > 1 are sub or subst items of keyword
  17.         PRINT SPACE$(5); j - 1; Item$(d(i), j, ",") 'j-1 counts off the sub item
  18.         j = j + 1
  19.     WEND
  20.     PRINT: INPUT "Ok... press enter "; w$
  21.     CLS
  22.  
  23. SUB setup '3rd method of data structure, this is meant to be edited over and over as add to a refine words and substitutes
  24.     topIndex = 6 ' <<< make modifications to d() and then update this number, that's it!
  25.     REDIM d(1 TO topIndex) AS STRING
  26.     d(1) = "Months,January,February,March,April,May,June,July,August,September,October,November,December"
  27.     d(2) = "Days,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday"
  28.     d(3) = "Holidays,NewYears Day,MLK Day,Valentine's Day,Easter,Mother's Day,Memorial Day,Father's Day,Independence Day,Bplus Day,Labor Day,Halloween,Thanksgiving,Christmas"
  29.     d(4) = "Leap Years,2000,2004,2008,2012,2016,2020,2024,2028,2032,2036,2040,...,2096,2104,..."
  30.     d(5) = "Test no further words/phrases in this line. (And the next test will do an empty string.)"
  31.     d(6) = ""
  32.  
  33. 'Description: Use Item$() Function to treat strings like arrays without having to use an array structure.
  34. ' This function does not throw a fit if you ask for an item number (index) it does not have, it just returns an empty string.
  35. ' In QB64, Functions can't return arrays through the function name, but they can return strings that the Item$() function can
  36. ' translate like an an array index.  nItem numbers are the same as Counting numbers positive integers starting at 1.
  37. '  eg Item7$ = Item$(CommaDelimitedString$, 7, ",") 'get 7th Item in string
  38. FUNCTION Item$ (s$, nItem AS INTEGER, delimiter$)
  39.     DIM c AS INTEGER, d AS INTEGER, lastd AS INTEGER
  40.     IF LEN(s$) = 0 THEN Item$ = "": EXIT FUNCTION
  41.     lastd = 1: d = INSTR(lastd, s$, delimiter$)
  42.     WHILE d > 0
  43.         c = c + 1
  44.         IF c = nItem THEN
  45.             Item$ = MID$(s$, lastd, d - lastd): EXIT FUNCTION
  46.         ELSE
  47.             lastd = d + 1: d = INSTR(lastd, s$, delimiter$)
  48.         END IF
  49.     WEND
  50.     c = c + 1
  51.     IF c <> nItem THEN Item$ = "" ELSE Item$ = MID$(s$, lastd, LEN(s$))
  52.  

 

Update / Append:
So you may wonder when to use Split and when to use Item$, well it is more efficient to Split to an array if the string is huge, like a file, and it is vital reference for your application. On the other hand, Rons task: https://www.qb64.org/forum/index.php?topic=1655.0 is solved by getting info fast from potentially hundreds of smaller strings a sort of Just In Time processing that gives array like access to a string without actually having to create an array :)
Ha! we have 50 replies in that thread and I have yet to demo the perfect fit Item$ is for his task, stay tuned...
I also have the problem solved with a Split version too but... learning is step by step.
Title: Re: Samples/Toolbox re-awakening. Call for entries.
Post by: Qwerkey on August 28, 2019, 06:13:12 AM
QB64 Mahjong

Librarian, please find attached.  I believe that this would be suitable as a Sample Program.  As well as showing off the good graphics which QB64 produces, this is an InForm-based game and advertises Fellippe's production.

Post:
https://www.qb64.org/forum/index.php?topic=632.msg5033#new (https://www.qb64.org/forum/index.php?topic=632.msg5033#new)