Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Junior Librarian

Pages: [1] 2
1
Pi-in-the-Sky Graphics Demonstration

Author: @Qwerkey
Source: qb64.org Forum
URL: https://qb64forum.alephc.xyz//index.php?topic=1969.0
Version: 15/01/22

Description:
This is a program which demonstrates the amazing graphics capabilities of QB64, using simple coding techniques and without resorting to the complexities of Open_GL.  Impressive 3D effects can be obtained using the QB64 _MAPTRIANGLE statement: the 3D _MAPTRIANGLE method gives a convincing 3D display along with perspective.

The program features a number of animations (some 2D and some 3D) enhanced with accompanying audio.  There is no interaction with the user, and the running display is an entertaining series of whimsical tableaux.  The program takes about 10 minutes before repeating.


You will need to go to the URL above to download the program.



screenshot.jpg

2
Interpreters / Symbolic Instruction Code Kit by Erik Jon Oredson
« on: December 27, 2021, 11:39:43 am »
Symbolic Instruction Code Kit (S.I.C.K.) Updated 2022-01-17

Author: @eoredson (eoredson@gmail.com)
URL: https://qb64forum.alephc.xyz/index.php?topic=4500.0
Version: v64.0a r5.5a

Description:
The Symbolic Instruction Code Kit, which contains a QB64 program named SIC64.BAS
and several smaller utility programs. The source code is public domain and can be
found on several sites, including, www.filegate.net and www.keepandshare.com

This program uses a recursive descent parser to interpret a psuedo-basic language
written in a line number oriented fashion and can be used for small programming chores.

The archive also contains some further imbedded .zip files which contain several
QB64 sample programs, and some .SIC programs which are used by the SIC engine.


Source Code:
See download(s) below, or follow this link:
https://bit.ly/EriksSICK

 

Commands:
Code: QB64: [Select]
  1. ENDIF  END IF  STOP  REM  MID$  LEFT$  RIGHT$  PRINT #  DPRINT
  2.  LPRINT USING  SPRINT  UPRINT  INPUT;  FORIF  FOR  NEXTIF  NEXT  CONTINUE FORIF  CONTINUE FOR
  3.  EXIT FORIF  EXIT FOR  DO UNTIL  LOOP WHILE  EXIT DO  CONTINUE DO  GOTO  GOSUB  RETURN  DO WHILE
  4.  DO  OFF  IF  ELSEIF  CASEIF ELSE  CASEIF  SELECT CASE  END SELECTIF  BEEP  SOUND
  5.  COLOR  LOCATE  CLS  SCREEN  WIDTH  WRITE #  LINE INPUT;  LINE INPUT #  INPUT #  WEND
  6.  WHILE  CONTINUE WHILE  EXIT WHILE  ELSE  LOOP UNTIL  LOOPIF  END LOOPIF  EXIT LOOPIF  LOOP  RANDOMIZE
  7.  POKE  INT86  DEFSEG  ABSOLUTE  OUT  WAIT  SLEEP  PAUSE  SELECTIF CASE  END SELECT
  8.  CASE ELSE  CASE  CONTINUE LOOPIF  END  CLEAR  SYSTEM  SWAP  ERROR  ON ERROR GOTO  ON ERROR RESUME PREVIOUS
  9.  ON ERROR RESUME SAME  ON ERROR RESUME NEXT  ON ERROR STOP  RESUME PREVIOUS  RESUME SAME  RESUME NEXT  RESUME  ON  DATE$  TIME$
  10.  CHDRIVE  CD  CHDIR  MD  MKDIR  RD  RMDIR  KILL  DELETE  RENAME
  11.  NAME  SHELL  CHAIN  LET  CLOSE #  OPEN #  FIELD #  WRITE  PRINT USING  INPUT
  12.  LINE INPUT  LSET #  RSET #  PUT #  GET #  READ #  DATA  READ  RESTORE  CIRCLE STEP
  13.  PSET  PRESET  GET  PUT  DIM  COMMON  DECLARE  LOCK #  UNLOCK #  PRINT
  14.  LPRINT  TRIANGLE  POLYGON

SICK.png


3
Embedding files in programs (FileToDATA convertor)

Author: @RhoSigma
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=790.0
Version: October 04 2021


Description:
These two programs I use a lot.  These goodies got an complete overhaul and are now using the LZW packer/unpacker, which I've released. So this is a good opportunity to make it available again for everybody.  MakeDATA.bas Create a DATA block out of the given file, so you can embed it in your program and write it back when needed.  The DATAs are written into a .bm file.   MakeCARR.bas will do the whole thing in an array on C/C++ level, rather then in DATAs on the QB64 level. Although it's handling is a bit more tricky, as you get not only a .bm file, but also a .h file, and both must match (ie. the DECLARE LIBRARY path in the .bm must point to the .h), this approach has several advantages.

Both of the following tools require the 'lzwpacker.bm' file.


The .bm file is to be found in the author's Libraries Collection https://www.qb64.org/forum/index.php?topic=809

Source Code MakeDATA.bas:
Code: QB64: [Select]
  1.     '+---------------+---------------------------------------------------+
  2.     '| ###### ###### |     .--. .         .-.                            |
  3.     '| ##  ## ##   # |     |   )|        (   ) o                         |
  4.     '| ##  ##  ##    |     |--' |--. .-.  `-.  .  .-...--.--. .-.        |
  5.     '| ######   ##   |     |  \ |  |(   )(   ) | (   ||  |  |(   )       |
  6.     '| ##      ##    |     '   `'  `-`-'  `-'-' `-`-`|'  '  `-`-'`-      |
  7.     '| ##     ##   # |                            ._.'                   |
  8.     '| ##     ###### |  Sources & Documents placed in the Public Domain. |
  9.     '+---------------+---------------------------------------------------+
  10.     '|                                                                   |
  11.     '| === MakeDATA.bas ===                                              |
  12.     '|                                                                   |
  13.     '| == Create a DATA block out of the given file, so you can embed it |
  14.     '| == in your program and write it back when needed.                 |
  15.     '|                                                                   |
  16.     '| == The DATAs are written into a .bm file together with a ready to |
  17.     '| == use write back FUNCTION. You just $INCLUDE this .bm file into  |
  18.     '| == your program and call the write back FUNCTION somewhere.       |
  19.     '|                                                                   |
  20.     '| == This program needs the 'lzwpacker.bm' file available from the  |
  21.     '| == Libraries Collection here:                                     |
  22.     '| ==      https://www.qb64.org/forum/index.php?topic=809            |
  23.     '| == as it will try to pack the given file to keep the DATA block   |
  24.     '| == as small as possible. If compression is successful, then your  |
  25.     '| == program also must $INCLUDE 'lzwpacker.bm' to be able to unpack |
  26.     '| == the file data again for write back. MakeDATA.bas is printing   |
  27.     '| == a reminder message in such a case.                             |
  28.     '|                                                                   |
  29.     '+-------------------------------------------------------------------+
  30.     '| Done by RhoSigma, R.Heyder, provided AS IS, use at your own risk. |
  31.     '| Find me in the QB64 Forum or mail to support&rhosigma-cw.net for  |
  32.     '| any questions or suggestions. Thanx for your interest in my work. |
  33.     '+-------------------------------------------------------------------+
  34.      
  35.     '--- if you wish, set any default paths, end with a backslash ---
  36.     srcPath$ = "" 'source path
  37.     tarPath$ = "" 'target path
  38.     '-----
  39.     IF srcPath$ <> "" THEN
  40.         COLOR 15: PRINT "Default source path: ": COLOR 7: PRINT srcPath$: PRINT
  41.     END IF
  42.     IF tarPath$ <> "" THEN
  43.         COLOR 15: PRINT "Default target path: ": COLOR 7: PRINT tarPath$: PRINT
  44.     END IF
  45.      
  46.     '--- collect inputs (relative paths allowed, based on default paths) ---
  47.     source:
  48.     LINE INPUT "Source Filename: "; src$ 'any file you want to put into DATAs
  49.     IF src$ = "" GOTO source
  50.     target:
  51.     LINE INPUT "Target Basename: "; tar$ 'write stuff into this file (.bm is added)
  52.     IF tar$ = "" GOTO target
  53.     '-----
  54.     ON ERROR GOTO abort
  55.     OPEN "I", #1, srcPath$ + src$: CLOSE #1 'file exist check
  56.     OPEN "O", #2, tarPath$ + tar$ + ".bm": CLOSE #2 'path exist check
  57.     ON ERROR GOTO 0
  58.      
  59.     '--- separate source filename part ---
  60.     FOR po% = LEN(src$) TO 1 STEP -1
  61.         IF MID$(src$, po%, 1) = "\" OR MID$(src$, po%, 1) = "/" THEN
  62.             srcName$ = MID$(src$, po% + 1)
  63.             EXIT FOR
  64.         ELSEIF po% = 1 THEN
  65.             srcName$ = src$
  66.         END IF
  67.     NEXT po%
  68.     '--- separate target filename part ---
  69.     FOR po% = LEN(tar$) TO 1 STEP -1
  70.         IF MID$(tar$, po%, 1) = "\" OR MID$(tar$, po%, 1) = "/" THEN
  71.             tarName$ = MID$(tar$, po% + 1)
  72.             EXIT FOR
  73.         ELSEIF po% = 1 THEN
  74.             tarName$ = tar$
  75.         END IF
  76.     NEXT po%
  77.     MID$(tarName$, 1, 1) = UCASE$(MID$(tarName$, 1, 1)) 'capitalize 1st letter
  78.      
  79.     '--- init ---
  80.     OPEN "B", #1, srcPath$ + src$
  81.     filedata$ = SPACE$(LOF(1))
  82.     GET #1, , filedata$
  83.     CLOSE #1
  84.     rawdata$ = LzwPack$(filedata$, 20)
  85.     IF rawdata$ <> "" THEN
  86.         OPEN "O", #1, tarPath$ + tar$ + ".lzw"
  87.         CLOSE #1
  88.         OPEN "B", #1, tarPath$ + tar$ + ".lzw"
  89.         PUT #1, , rawdata$
  90.         CLOSE #1
  91.         packed% = -1
  92.         OPEN "B", #1, tarPath$ + tar$ + ".lzw"
  93.     ELSE
  94.         packed% = 0
  95.         OPEN "B", #1, srcPath$ + src$
  96.     END IF
  97.     fl& = LOF(1)
  98.     cntL& = INT(fl& / 32)
  99.     cntB& = (fl& - (cntL& * 32))
  100.      
  101.     '--- .bm include file ---
  102.     OPEN "O", #2, tarPath$ + tar$ + ".bm"
  103.     PRINT #2, "'============================================================"
  104.     PRINT #2, "'=== This file was created with MakeDATA.bas by RhoSigma, ==="
  105.     PRINT #2, "'=== you must $INCLUDE this at the end of your program.   ==="
  106.     IF packed% THEN
  107.         PRINT #2, "'=== ---------------------------------------------------- ==="
  108.         PRINT #2, "'=== If your program is NOT a GuiTools based application, ==="
  109.         PRINT #2, "'=== then it must also $INCLUDE: 'lzwpacker.bm' available ==="
  110.         PRINT #2, "'=== from the Libraries Collection here:                  ==="
  111.         PRINT #2, "'===    https://www.qb64.org/forum/index.php?topic=809    ==="
  112.     END IF
  113.     PRINT #2, "'============================================================"
  114.     PRINT #2, ""
  115.     '--- writeback function ---
  116.     PRINT #2, "'"; STRING$(LEN(tarName$) + 18, "-")
  117.     PRINT #2, "'--- Write"; tarName$; "Data$ ---"
  118.     PRINT #2, "'"; STRING$(LEN(tarName$) + 18, "-")
  119.     PRINT #2, "' This function will write the DATAs you've created with MakeDATA.bas"
  120.     PRINT #2, "' back to disk and so it rebuilds the original file."
  121.     PRINT #2, "'"
  122.     PRINT #2, "' After the writeback call, only use the returned realFile$ to access the"
  123.     PRINT #2, "' written file. It's your given path, but with an maybe altered filename"
  124.     PRINT #2, "' (number added) in order to avoid the overwriting of an already existing"
  125.     PRINT #2, "' file with the same name in the given location."
  126.     PRINT #2, "'----------"
  127.     PRINT #2, "' SYNTAX:"
  128.     PRINT #2, "'   realFile$ = Write"; tarName$; "Data$ (wantFile$)"
  129.     PRINT #2, "'----------"
  130.     PRINT #2, "' INPUTS:"
  131.     PRINT #2, "'   --- wantFile$ ---"
  132.     PRINT #2, "'    The filename you would like to write the DATAs to, can contain"
  133.     PRINT #2, "'    a full or relative path."
  134.     PRINT #2, "'----------"
  135.     PRINT #2, "' RESULT:"
  136.     PRINT #2, "'   --- realFile$ ---"
  137.     PRINT #2, "'    - On success this is the path and filename finally used after all"
  138.     PRINT #2, "'      applied checks, use only this returned filename to access the"
  139.     PRINT #2, "'      written file."
  140.     PRINT #2, "'    - On failure this function will panic with the appropriate runtime"
  141.     PRINT #2, "'      error code which you may trap and handle as needed with your own"
  142.     PRINT #2, "'      ON ERROR GOTO... handler."
  143.     PRINT #2, "'---------------------------------------------------------------------"
  144.     PRINT #2, "FUNCTION Write"; tarName$; "Data$ (file$)"
  145.     PRINT #2, "'--- option _explicit requirements ---"
  146.     PRINT #2, "DIM po%, body$, ext$, num%, numL&, numB&, rawdata$, stroffs&, i&, dat&, ff%";
  147.     IF packed% THEN PRINT #2, ", filedata$": ELSE PRINT #2, ""
  148.     PRINT #2, "'--- separate filename body & extension ---"
  149.     PRINT #2, "FOR po% = LEN(file$) TO 1 STEP -1"
  150.     PRINT #2, "    IF MID$(file$, po%, 1) = "; CHR$(34); "."; CHR$(34); " THEN"
  151.     PRINT #2, "        body$ = LEFT$(file$, po% - 1)"
  152.     PRINT #2, "        ext$ = MID$(file$, po%)"
  153.     PRINT #2, "        EXIT FOR"
  154.     PRINT #2, "    ELSEIF MID$(file$, po%, 1) = "; CHR$(34); "\"; CHR$(34); " OR MID$(file$, po%, 1) = "; CHR$(34); "/"; CHR$(34); " OR po% = 1 THEN"
  155.     PRINT #2, "        body$ = file$"
  156.     PRINT #2, "        ext$ = "; CHR$(34); CHR$(34)
  157.     PRINT #2, "        EXIT FOR"
  158.     PRINT #2, "    END IF"
  159.     PRINT #2, "NEXT po%"
  160.     PRINT #2, "'--- avoid overwriting of existing files ---"
  161.     PRINT #2, "num% = 1"
  162.     PRINT #2, "WHILE _FILEEXISTS(file$)"
  163.     PRINT #2, "    file$ = body$ + "; CHR$(34); "("; CHR$(34); " + LTRIM$(STR$(num%)) + "; CHR$(34); ")"; CHR$(34); " + ext$"
  164.     PRINT #2, "    num% = num% + 1"
  165.     PRINT #2, "WEND"
  166.     PRINT #2, "'--- write DATAs ---"
  167.     PRINT #2, "RESTORE "; tarName$
  168.     PRINT #2, "READ numL&, numB&"
  169.     PRINT #2, "rawdata$ = SPACE$((numL& * 4) + numB&)"
  170.     PRINT #2, "stroffs& = 1"
  171.     PRINT #2, "FOR i& = 1 TO numL&"
  172.     PRINT #2, "    READ dat&"
  173.     PRINT #2, "    MID$(rawdata$, stroffs&, 4) = MKL$(dat&)"
  174.     PRINT #2, "    stroffs& = stroffs& + 4"
  175.     PRINT #2, "NEXT i&"
  176.     PRINT #2, "IF numB& > 0 THEN"
  177.     PRINT #2, "    FOR i& = 1 TO numB&"
  178.     PRINT #2, "        READ dat&"
  179.     PRINT #2, "        MID$(rawdata$, stroffs&, 1) = CHR$(dat&)"
  180.     PRINT #2, "        stroffs& = stroffs& + 1"
  181.     PRINT #2, "    NEXT i&"
  182.     PRINT #2, "END IF"
  183.     PRINT #2, "ff% = FREEFILE"
  184.     PRINT #2, "OPEN file$ FOR OUTPUT AS ff%"
  185.     IF packed% THEN
  186.         PRINT #2, "CLOSE ff%"
  187.         PRINT #2, "filedata$ = LzwUnpack$(rawdata$)"
  188.         PRINT #2, "OPEN file$ FOR BINARY AS ff%"
  189.         PRINT #2, "PUT #ff%, , filedata$"
  190.     ELSE
  191.         PRINT #2, "PRINT #ff%, rawdata$;"
  192.     END IF
  193.     PRINT #2, "CLOSE ff%"
  194.     PRINT #2, "'--- set result ---"
  195.     PRINT #2, "Write"; tarName$; "Data$ = file$"
  196.     PRINT #2, "EXIT FUNCTION"
  197.     PRINT #2, ""
  198.     PRINT #2, "'--- DATAs representing the contents of file "; srcName$
  199.     PRINT #2, "'---------------------------------------------------------------------"
  200.     PRINT #2, tarName$; ":"
  201.     '--- read LONGs ---
  202.     PRINT #2, "DATA "; LTRIM$(STR$(cntL& * 8)); ","; LTRIM$(STR$(cntB&))
  203.     tmpI$ = SPACE$(32)
  204.     FOR z& = 1 TO cntL&
  205.         GET #1, , tmpI$: offI% = 1
  206.         tmpO$ = "DATA " + STRING$(87, ","): offO% = 6
  207.         DO
  208.             tmpL& = CVL(MID$(tmpI$, offI%, 4)): offI% = offI% + 4
  209.             MID$(tmpO$, offO%, 10) = "&H" + RIGHT$("00000000" + HEX$(tmpL&), 8)
  210.             offO% = offO% + 11
  211.         LOOP UNTIL offO% > 92
  212.         PRINT #2, tmpO$
  213.     NEXT z&
  214.     '--- read remaining BYTEs ---
  215.     IF cntB& > 0 THEN
  216.         PRINT #2, "DATA ";
  217.         FOR x% = 1 TO cntB&
  218.             GET #1, , tmpB%%
  219.             PRINT #2, "&H" + RIGHT$("00" + HEX$(tmpB%%), 2);
  220.             IF x% <> 16 THEN
  221.                 IF x% <> cntB& THEN PRINT #2, ",";
  222.             ELSE
  223.                 IF x% <> cntB& THEN
  224.                     PRINT #2, ""
  225.                     PRINT #2, "DATA ";
  226.                 END IF
  227.             END IF
  228.         NEXT x%
  229.         PRINT #2, ""
  230.     END IF
  231.     PRINT #2, "END FUNCTION"
  232.     PRINT #2, ""
  233.     '--- ending ---
  234.     CLOSE #2
  235.     CLOSE #1
  236.      
  237.     '--- finish message ---
  238.     COLOR 10: PRINT: PRINT "file successfully processed..."
  239.     COLOR 9: PRINT: PRINT "You must $INCLUDE the created file (target name + .bm extension) at"
  240.     PRINT "the end of your program and call the function 'Write"; tarName$; "Data$(...)'"
  241.     PRINT "in an appropriate place to write the file back to disk."
  242.     IF packed% THEN
  243.         COLOR 12: PRINT: PRINT "Your program must also $INCLUDE 'lzwpacker.bm' available from"
  244.         PRINT "the Libraries Collection here:"
  245.         PRINT "     https://www.qb64.org/forum/index.php?topic=809"
  246.         PRINT "to be able to write back the just processed file."
  247.         KILL tarPath$ + tar$ + ".lzw"
  248.     END IF
  249.     done:
  250.     COLOR 7
  251.     END
  252.     '--- error handler ---
  253.     abort:
  254.     COLOR 12: PRINT: PRINT "something is wrong with path/file access, check your inputs and try again..."
  255.     RESUME done
  256.      
  257.     '$INCLUDE: 'QB64Library\LZW-Compress\lzwpacker.bm'
  258.      
  259.      
  260.  


Source Code MakeCARR.bas:
Code: QB64: [Select]
  1.     '+---------------+---------------------------------------------------+
  2.     '| ###### ###### |     .--. .         .-.                            |
  3.     '| ##  ## ##   # |     |   )|        (   ) o                         |
  4.     '| ##  ##  ##    |     |--' |--. .-.  `-.  .  .-...--.--. .-.        |
  5.     '| ######   ##   |     |  \ |  |(   )(   ) | (   ||  |  |(   )       |
  6.     '| ##      ##    |     '   `'  `-`-'  `-'-' `-`-`|'  '  `-`-'`-      |
  7.     '| ##     ##   # |                            ._.'                   |
  8.     '| ##     ###### |  Sources & Documents placed in the Public Domain. |
  9.     '+---------------+---------------------------------------------------+
  10.     '|                                                                   |
  11.     '| === MakeCARR.bas ===                                              |
  12.     '|                                                                   |
  13.     '| == Create a C/C++ array out of the given file, so you can embed   |
  14.     '| == it in your program and write it back when needed.              |
  15.     '|                                                                   |
  16.     '| == Two files are created, the .h file, which contains the array(s)|
  17.     '| == and some functions, and a respective .bm file which needs to   |
  18.     '| == be $INCLUDEd with your program and does provide the FUNCTION   |
  19.     '| == to write back the array(s) into any file. All used functions   |
  20.     '| == are standard library calls, no API calls are involved, so the  |
  21.     '| == writeback should work on all QB64 supported platforms.         |
  22.     '|                                                                   |
  23.     '| == Make sure to adjust the path for the .h file for your personal |
  24.     '| == needs in the created .bm files (DECLARE LIBRARY), if required. |
  25.     '| == You may specify default paths right below this header.         |
  26.     '|                                                                   |
  27.     '| == This program needs the 'lzwpacker.bm' file available from the  |
  28.     '| == Libraries Collection here:                                     |
  29.     '| ==      https://www.qb64.org/forum/index.php?topic=809            |
  30.     '| == as it will try to pack the given file to keep the array(s) as  |
  31.     '| == small as possible. If compression is successful, then your     |
  32.     '| == program also must $INCLUDE 'lzwpacker.bm' to be able to unpack |
  33.     '| == the file data again for write back. MakeCARR.bas is printing   |
  34.     '| == a reminder message in such a case.                             |
  35.     '|                                                                   |
  36.     '+-------------------------------------------------------------------+
  37.     '| Done by RhoSigma, R.Heyder, provided AS IS, use at your own risk. |
  38.     '| Find me in the QB64 Forum or mail to support&rhosigma-cw.net for  |
  39.     '| any questions or suggestions. Thanx for your interest in my work. |
  40.     '+-------------------------------------------------------------------+
  41.      
  42.     '--- if you wish, set any default paths, end with a backslash ---
  43.     srcPath$ = "" 'source path
  44.     tarPath$ = "" 'target path
  45.     '-----
  46.     IF srcPath$ <> "" THEN
  47.         COLOR 15: PRINT "Default source path: ": COLOR 7: PRINT srcPath$: PRINT
  48.     END IF
  49.     IF tarPath$ <> "" THEN
  50.         COLOR 15: PRINT "Default target path: ": COLOR 7: PRINT tarPath$: PRINT
  51.     END IF
  52.      
  53.     '--- collect inputs (relative paths allowed, based on default paths) ---
  54.     source:
  55.     LINE INPUT "Source Filename: "; src$ 'any file you want to put into a C/C++ array
  56.     IF src$ = "" GOTO source
  57.     target:
  58.     LINE INPUT "Target Basename: "; tar$ 'write stuff into this file(s) (.h/.bm is added)
  59.     IF tar$ = "" GOTO target
  60.     '-----
  61.     ON ERROR GOTO abort
  62.     OPEN "I", #1, srcPath$ + src$: CLOSE #1 'file exist check
  63.     OPEN "O", #2, tarPath$ + tar$ + ".bm": CLOSE #2 'path exist check
  64.     ON ERROR GOTO 0
  65.      
  66.     '--- separate source filename part ---
  67.     FOR po% = LEN(src$) TO 1 STEP -1
  68.         IF MID$(src$, po%, 1) = "\" OR MID$(src$, po%, 1) = "/" THEN
  69.             srcName$ = MID$(src$, po% + 1)
  70.             EXIT FOR
  71.         ELSEIF po% = 1 THEN
  72.             srcName$ = src$
  73.         END IF
  74.     NEXT po%
  75.     '--- separate target filename part ---
  76.     FOR po% = LEN(tar$) TO 1 STEP -1
  77.         IF MID$(tar$, po%, 1) = "\" OR MID$(tar$, po%, 1) = "/" THEN
  78.             tarName$ = MID$(tar$, po% + 1)
  79.             EXIT FOR
  80.         ELSEIF po% = 1 THEN
  81.             tarName$ = tar$
  82.         END IF
  83.     NEXT po%
  84.     MID$(tarName$, 1, 1) = UCASE$(MID$(tarName$, 1, 1)) 'capitalize 1st letter
  85.      
  86.     '---------------------------------------------------------------------
  87.     ' Depending on the source file's size, one or more array(s) are
  88.     ' created. This is because some C/C++ compilers seem to have problems
  89.     ' with arrays with more than 65535 elements. This does not affect the
  90.     ' write back, as the write function will take this behavior into account.
  91.     '---------------------------------------------------------------------
  92.      
  93.     '--- init ---
  94.     OPEN "B", #1, srcPath$ + src$
  95.     filedata$ = SPACE$(LOF(1))
  96.     GET #1, , filedata$
  97.     CLOSE #1
  98.     rawdata$ = LzwPack$(filedata$, 20)
  99.     IF rawdata$ <> "" THEN
  100.         OPEN "O", #1, tarPath$ + tar$ + ".lzw"
  101.         CLOSE #1
  102.         OPEN "B", #1, tarPath$ + tar$ + ".lzw"
  103.         PUT #1, , rawdata$
  104.         CLOSE #1
  105.         packed% = -1
  106.         OPEN "B", #1, tarPath$ + tar$ + ".lzw"
  107.     ELSE
  108.         packed% = 0
  109.         OPEN "B", #1, srcPath$ + src$
  110.     END IF
  111.     fl& = LOF(1)
  112.     cntL& = INT(fl& / 32)
  113.     cntV& = INT(cntL& / 8180)
  114.     cntB& = (fl& - (cntL& * 32))
  115.      
  116.     '--- .h include file ---
  117.     OPEN "O", #2, tarPath$ + tar$ + ".h"
  118.     PRINT #2, "// ============================================================"
  119.     PRINT #2, "// === This file was created with MakeCARR.bas by RhoSigma, ==="
  120.     PRINT #2, "// === use it in conjunction with its respective .bm file.  ==="
  121.     PRINT #2, "// ============================================================"
  122.     PRINT #2, ""
  123.     PRINT #2, "// --- Array(s) representing the contents of file "; srcName$
  124.     PRINT #2, "// ---------------------------------------------------------------------"
  125.     '--- read LONGs ---
  126.     tmpI$ = SPACE$(32)
  127.     FOR vc& = 0 TO cntV&
  128.         IF vc& = cntV& THEN numL& = (cntL& MOD 8180): ELSE numL& = 8180
  129.         PRINT #2, "static const unsigned int32 "; tarName$; "L"; LTRIM$(STR$(vc&)); "[] = {"
  130.         PRINT #2, "    "; LTRIM$(STR$(numL& * 8)); ","
  131.         FOR z& = 1 TO numL&
  132.             GET #1, , tmpI$: offI% = 1
  133.             tmpO$ = "    " + STRING$(88, ","): offO% = 5
  134.             DO
  135.                 tmpL& = CVL(MID$(tmpI$, offI%, 4)): offI% = offI% + 4
  136.                 MID$(tmpO$, offO%, 10) = "0x" + RIGHT$("00000000" + HEX$(tmpL&), 8)
  137.                 offO% = offO% + 11
  138.             LOOP UNTIL offO% > 92
  139.             IF z& < numL& THEN PRINT #2, tmpO$: ELSE PRINT #2, LEFT$(tmpO$, 91)
  140.         NEXT z&
  141.         PRINT #2, "};"
  142.         PRINT #2, ""
  143.     NEXT vc&
  144.     '--- read remaining BYTEs ---
  145.     IF cntB& > 0 THEN
  146.         PRINT #2, "static const unsigned int8 "; tarName$; "B[] = {"
  147.         PRINT #2, "    "; LTRIM$(STR$(cntB&)); ","
  148.         PRINT #2, "    ";
  149.         FOR x% = 1 TO cntB&
  150.             GET #1, , tmpB%%
  151.             PRINT #2, "0x" + RIGHT$("00" + HEX$(tmpB%%), 2);
  152.             IF x% <> 16 THEN
  153.                 IF x% <> cntB& THEN PRINT #2, ",";
  154.             ELSE
  155.                 IF x% <> cntB& THEN
  156.                     PRINT #2, ","
  157.                     PRINT #2, "    ";
  158.                 END IF
  159.             END IF
  160.         NEXT x%
  161.         PRINT #2, ""
  162.         PRINT #2, "};"
  163.         PRINT #2, ""
  164.     END IF
  165.     '--- some functions ---
  166.     PRINT #2, "// --- Saved full qualified output path and filename, so we've no troubles"
  167.     PRINT #2, "// --- when cleaning up, even if the current working folder was changed"
  168.     PRINT #2, "// --- during program runtime."
  169.     PRINT #2, "// ---------------------------------------------------------------------"
  170.     PRINT #2, "char "; tarName$; "Name[8192]; // it's a safe size for any current OS"
  171.     PRINT #2, ""
  172.     PRINT #2, "// --- Cleanup function to delete the written file, called by the atexit()"
  173.     PRINT #2, "// --- handler at program termination time, if requested by user."
  174.     PRINT #2, "// ---------------------------------------------------------------------"
  175.     PRINT #2, "void Kill"; tarName$; "Data(void)"
  176.     PRINT #2, "{"
  177.     PRINT #2, "    remove("; tarName$; "Name);"
  178.     PRINT #2, "}"
  179.     PRINT #2, ""
  180.     PRINT #2, "// --- Function to write the array(s) back into a file, will return the"
  181.     PRINT #2, "// --- full qualified output path and filename on success, otherwise an"
  182.     PRINT #2, "// --- empty string is returned (access/write errors, file truncated)."
  183.     PRINT #2, "// ---------------------------------------------------------------------"
  184.     PRINT #2, "const char *Write"; tarName$; "Data(const char *FileName, int16 AutoClean)"
  185.     PRINT #2, "{"
  186.     PRINT #2, "    FILE *han = NULL; // file handle"
  187.     PRINT #2, "    int32 num = NULL; // written elements"
  188.     PRINT #2, ""
  189.     PRINT #2, "    #ifdef QB64_WINDOWS"
  190.     PRINT #2, "    if (!_fullpath("; tarName$; "Name, FileName, 8192)) return "; CHR$(34); CHR$(34); ";"
  191.     PRINT #2, "    #else"
  192.     PRINT #2, "    if (!realpath(FileName, "; tarName$; "Name)) return "; CHR$(34); CHR$(34); ";"
  193.     PRINT #2, "    #endif"
  194.     PRINT #2, ""
  195.     PRINT #2, "    if (!(han = fopen("; tarName$; "Name, "; CHR$(34); "wb"; CHR$(34); "))) return "; CHR$(34); CHR$(34); ";"
  196.     PRINT #2, "    if (AutoClean) atexit(Kill"; tarName$; "Data);"
  197.     PRINT #2, ""
  198.     FOR vc& = 0 TO cntV&
  199.         PRINT #2, "    num = fwrite(&"; tarName$; "L"; LTRIM$(STR$(vc&)); "[1], 4, "; tarName$; "L"; LTRIM$(STR$(vc&)); "[0], han);"
  200.         PRINT #2, "    if (num != "; tarName$; "L"; LTRIM$(STR$(vc&)); "[0]) {fclose(han); return "; CHR$(34); CHR$(34); ";}"
  201.         PRINT #2, ""
  202.     NEXT vc&
  203.     IF cntB& > 0 THEN
  204.         PRINT #2, "    num = fwrite(&"; tarName$; "B[1], 1, "; tarName$; "B[0], han);"
  205.         PRINT #2, "    if (num != "; tarName$; "B[0]) {fclose(han); return "; CHR$(34); CHR$(34); ";}"
  206.         PRINT #2, ""
  207.     END IF
  208.     PRINT #2, "    fclose(han);"
  209.     PRINT #2, "    return "; tarName$; "Name;"
  210.     PRINT #2, "}"
  211.     PRINT #2, ""
  212.     '--- ending ---
  213.     CLOSE #2
  214.     CLOSE #1
  215.      
  216.     '--- .bm include file ---
  217.     OPEN "O", #2, tarPath$ + tar$ + ".bm"
  218.     PRINT #2, "'============================================================"
  219.     PRINT #2, "'=== This file was created with MakeCARR.bas by RhoSigma, ==="
  220.     PRINT #2, "'=== you must $INCLUDE this at the end of your program.   ==="
  221.     IF packed% THEN
  222.         PRINT #2, "'=== ---------------------------------------------------- ==="
  223.         PRINT #2, "'=== If your program is NOT a GuiTools based application, ==="
  224.         PRINT #2, "'=== then it must also $INCLUDE: 'lzwpacker.bm' available ==="
  225.         PRINT #2, "'=== from the Libraries Collection here:                  ==="
  226.         PRINT #2, "'===    https://www.qb64.org/forum/index.php?topic=809    ==="
  227.     END IF
  228.     PRINT #2, "'============================================================"
  229.     PRINT #2, ""
  230.     PRINT #2, "'-----------------"
  231.     PRINT #2, "'--- Important ---"
  232.     PRINT #2, "'-----------------"
  233.     PRINT #2, "' If you need to move around this .bm file and its respective .h file"
  234.     PRINT #2, "' to fit in your project, then make sure the path in the DECLARE LIBRARY"
  235.     PRINT #2, "' statement below does match the actual .h file location. It's best to"
  236.     PRINT #2, "' specify a relative path assuming your QB64 installation folder as root."
  237.     PRINT #2, "'---------------------------------------------------------------------"
  238.     PRINT #2, ""
  239.     '--- writeback function ---
  240.     PRINT #2, "'"; STRING$(LEN(tarName$) + 19, "-")
  241.     PRINT #2, "'--- Write"; tarName$; "Array$ ---"
  242.     PRINT #2, "'"; STRING$(LEN(tarName$) + 19, "-")
  243.     PRINT #2, "' This function will write the array(s) you've created with MakeCARR.bas"
  244.     PRINT #2, "' back to disk and so it rebuilds the original file."
  245.     PRINT #2, "'"
  246.     PRINT #2, "' After the writeback call, only use the returned realFile$ to access the"
  247.     PRINT #2, "' written file. It's the full qualified absolute path and filename, which"
  248.     PRINT #2, "' is made by expanding your maybe given relative path and an maybe altered"
  249.     PRINT #2, "' filename (number added) in order to avoid the overwriting of an already"
  250.     PRINT #2, "' existing file with the same name in the given location. By this means"
  251.     PRINT #2, "' you'll always have safe access to the file, no matter how your current"
  252.     PRINT #2, "' working folder changes during runtime."
  253.     PRINT #2, "'"
  254.     PRINT #2, "' If you wish, the written file can automatically be deleted for you when"
  255.     PRINT #2, "' your program will end, so you don't need to do the cleanup yourself."
  256.     PRINT #2, "'----------"
  257.     PRINT #2, "' SYNTAX:"
  258.     PRINT #2, "'   realFile$ = Write"; tarName$; "Array$ (wantFile$, autoDel%)"
  259.     PRINT #2, "'----------"
  260.     PRINT #2, "' INPUTS:"
  261.     PRINT #2, "'   --- wantFile$ ---"
  262.     PRINT #2, "'    The filename you would like to write the array(s) to, can contain"
  263.     PRINT #2, "'    a full or relative path."
  264.     PRINT #2, "'   --- autoDel% ---"
  265.     PRINT #2, "'    Shows whether you want the auto cleanup (see description above) at"
  266.     PRINT #2, "'    the program end or not (-1 = delete file, 0 = don't delete file)."
  267.     PRINT #2, "'----------"
  268.     PRINT #2, "' RESULT:"
  269.     PRINT #2, "'   --- realFile$ ---"
  270.     PRINT #2, "'    - On success this is the full qualified path and filename finally"
  271.     PRINT #2, "'      used after all applied checks, use only this returned filename"
  272.     PRINT #2, "'      to access the written file."
  273.     PRINT #2, "'    - On failure (write/access) this will be an empty string, so you"
  274.     PRINT #2, "'      should check for this before trying to access/open the file."
  275.     PRINT #2, "'---------------------------------------------------------------------"
  276.     PRINT #2, "FUNCTION Write"; tarName$; "Array$ (file$, clean%)"
  277.     PRINT #2, "'--- declare C/C++ function ---"
  278.     PRINT #2, "DECLARE LIBRARY "; CHR$(34); tarPath$; tar$; CHR$(34); " 'Do not add .h here !!"
  279.     PRINT #2, "    FUNCTION Write"; tarName$; "Data$ (FileName$, BYVAL AutoClean%)"
  280.     PRINT #2, "END DECLARE"
  281.     PRINT #2, "'--- option _explicit requirements ---"
  282.     PRINT #2, "DIM po%, body$, ext$, num%";
  283.     IF packed% THEN PRINT #2, ", real$, ff%, rawdata$, filedata$": ELSE PRINT #2, ""
  284.     PRINT #2, "'--- separate filename body & extension ---"
  285.     PRINT #2, "FOR po% = LEN(file$) TO 1 STEP -1"
  286.     PRINT #2, "    IF MID$(file$, po%, 1) = "; CHR$(34); "."; CHR$(34); " THEN"
  287.     PRINT #2, "        body$ = LEFT$(file$, po% - 1)"
  288.     PRINT #2, "        ext$ = MID$(file$, po%)"
  289.     PRINT #2, "        EXIT FOR"
  290.     PRINT #2, "    ELSEIF MID$(file$, po%, 1) = "; CHR$(34); "\"; CHR$(34); " OR MID$(file$, po%, 1) = "; CHR$(34); "/"; CHR$(34); " OR po% = 1 THEN"
  291.     PRINT #2, "        body$ = file$"
  292.     PRINT #2, "        ext$ = "; CHR$(34); CHR$(34)
  293.     PRINT #2, "        EXIT FOR"
  294.     PRINT #2, "    END IF"
  295.     PRINT #2, "NEXT po%"
  296.     PRINT #2, "'--- avoid overwriting of existing files ---"
  297.     PRINT #2, "num% = 1"
  298.     PRINT #2, "WHILE _FILEEXISTS(file$)"
  299.     PRINT #2, "    file$ = body$ + "; CHR$(34); "("; CHR$(34); " + LTRIM$(STR$(num%)) + "; CHR$(34); ")"; CHR$(34); " + ext$"
  300.     PRINT #2, "    num% = num% + 1"
  301.     PRINT #2, "WEND"
  302.     PRINT #2, "'--- write array & set result ---"
  303.     IF NOT packed% THEN
  304.         PRINT #2, "Write"; tarName$; "Array$ = Write"; tarName$; "Data$(file$ + CHR$(0), clean%)"
  305.     ELSE
  306.         PRINT #2, "real$ = Write"; tarName$; "Data$(file$ + CHR$(0), clean%)"
  307.         PRINT #2, "IF real$ <> "; CHR$(34); CHR$(34); " THEN"
  308.         PRINT #2, "    ff% = FREEFILE"
  309.         PRINT #2, "    OPEN real$ FOR BINARY AS ff%"
  310.         PRINT #2, "    rawdata$ = SPACE$(LOF(ff%))"
  311.         PRINT #2, "    GET #ff%, , rawdata$"
  312.         PRINT #2, "    filedata$ = LzwUnpack$(rawdata$)"
  313.         PRINT #2, "    PUT #ff%, 1, filedata$"
  314.         PRINT #2, "    CLOSE ff%"
  315.         PRINT #2, "END IF"
  316.         PRINT #2, "Write"; tarName$; "Array$ = real$"
  317.     END IF
  318.     PRINT #2, "END FUNCTION"
  319.     PRINT #2, ""
  320.     '--- ending ---
  321.     CLOSE #2
  322.      
  323.     '--- finish message ---
  324.     COLOR 10: PRINT: PRINT "file successfully processed..."
  325.     COLOR 9: PRINT: PRINT "You must $INCLUDE the created file (target name + .bm extension) at"
  326.     PRINT "the end of your program and call the function 'Write"; tarName$; "Array$(...)'"
  327.     PRINT "in an appropriate place to write the file back to disk."
  328.     IF packed% THEN
  329.         COLOR 12: PRINT: PRINT "Your program must also $INCLUDE 'lzwpacker.bm' available from"
  330.         PRINT "the Libraries Collection here:"
  331.         PRINT "     https://www.qb64.org/forum/index.php?topic=809"
  332.         PRINT "to be able to write back the just processed file."
  333.         KILL tarPath$ + tar$ + ".lzw"
  334.     END IF
  335.     done:
  336.     COLOR 7
  337.     END
  338.     '--- error handler ---
  339.     abort:
  340.     COLOR 12: PRINT: PRINT "something is wrong with path/file access, check your inputs and try again..."
  341.     RESUME done
  342.      
  343.     '$INCLUDE: 'QB64Library\LZW-Compress\lzwpacker.bm'
  344.      
  345.      
  346.  

                                                                                                                                         (162 downloads previously)

4
Games / Pipes Puzzle by Dav & bplus
« on: September 30, 2021, 06:06:46 am »
Pipes Puzzle

Author: @Dav
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=4232.0
Version: 1

Description:
This is a Maze puzzler.  To play you click on the pipes to rotate them and connect them to the flow, making the pipes all connected and one color.

Source Code (for reference only: use the zip file):
Code: QB64: [Select]
  1.     '================
  2.     'PIPES.BAS v1.0
  3.     '================
  4.     'Connect the pipes puzzle game
  5.     'Coded by Dav for QB64-GL 1.5 in SEP/2021
  6.      
  7.     'NOTE: Formally called MazeConnect Prototype on the forum.
  8.      
  9.     '============
  10.     'HOW TO PLAY:
  11.     '============
  12.      
  13.     'Click on pipes to rotate them and connect them as one.
  14.     'Object is to make all pipes on board connected to leader.
  15.     'Top left pipe is always on, the leader, so start from it.
  16.     'When pipes are all connected, you advance to next level.
  17.     'There are currently 20 levels.  ESC key exits game.
  18.      
  19.     'SPACE  = restarts level
  20.     'RIGHT ARROW = goto next level
  21.     'LEFT ARROW = go back a level
  22.     'ESC = Quits game
  23.      
  24.     '         VVVVVVV     blus fixed next line to work from his downloaded zip
  25.     $ExeIcon:'.\icon.ico'
  26.     _Icon
  27.      
  28.      
  29.      
  30.     Dim Shared GridSize, Level, MaxLevel, LD$, LU$, RD$, RU$, HZ$, VT$, BM$
  31.      
  32.     Level = 1: MaxLevel = 13
  33.      
  34.     GridSize = 3 'default starting GridSize is 3x3 (its level 1)
  35.     MaxGridSize = 15 'The last GridSize level so far (13 levels right now)
  36.      
  37.     'Declare image names: angle characters, right up, left up, etc
  38.     LD$ = "ld": LU$ = "lu"
  39.     RD$ = "rd": RU$ = "ru"
  40.     HZ$ = "hz": VT$ = "vt"
  41.     BM$ = "bm"
  42.      
  43.     'Sound files
  44.     new& = _SndOpen("sfx_magic.ogg")
  45.     move& = _SndOpen("sfx_click1.mp3"):
  46.     click& = _SndOpen("sfx_click2.mp3"):
  47.     clap& = _SndOpen("sfx_clap.ogg")
  48.      
  49.     'image file
  50.     Dim Shared Solved&
  51.     Solved& = _LoadImage("solved.png", 32) '<  thank bplus for this
  52.      
  53.     'For game state saving...to be added later
  54.     loaded = 0: fil$ = "pipe.dat"
  55.     If _FileExists(fil$) Then
  56.         loaded = 1
  57.     End If
  58.      
  59.     '=======
  60.     newlevel:
  61.     '=======
  62.      
  63.     Screen _NewImage(640, 640, 32)
  64.     'Do: Loop Until _ScreenExists ' <<<<<<<<<< sorry Dav this aint working on my system
  65.     _Delay .25 ' <<<<<<<<<<<<<<<<<<<<<<<<<<<<< does this work for you?
  66.     '            No? increase delay time really nice to have centered on screen
  67.     _ScreenMove _Middle ' <  thank bplus for this , ahhhh that's better
  68.     Cls ', _RGB(32, 32, 77)
  69.      
  70.     If Level = 1 Then
  71.         back& = _LoadImage("hz-grn.png")
  72.         _PutImage (0, 0)-(640, 640), back&
  73.         _FreeImage back&
  74.         title& = _LoadImage("title.png")
  75.         _PutImage (84, 140), title&
  76.         _FreeImage title&
  77.         w$ = Input$(1)
  78.         For a = 0 To 64
  79.             Line (0, 0)-(640, 640), _RGBA(0, 0, 0, a), BF
  80.             _Delay .02
  81.         Next
  82.     End If
  83.      
  84.     PPRINT 100, 300, 30, _RGB(200, 200, 200), 0, "Level:" + Str$(Level) + " of" + Str$(MaxLevel)
  85.     _Delay 2
  86.      
  87.     _SndPlay new&
  88.      
  89.     Title$ = "Pipes: Level " + Str$(Level) + " of" + Str$(MaxLevel)
  90.     _Title Title$
  91.      
  92.     'Make space for variables
  93.     ReDim Shared TileVal$(GridSize * GridSize)
  94.     ReDim Shared TileX(GridSize * GridSize), TileY(GridSize * GridSize)
  95.     ReDim Shared TileClr(GridSize * GridSize), TileClr2(GridSize * GridSize)
  96.      
  97.     TileSize = Int(640 / GridSize) 'The width/height of tiles, in pixels
  98.      
  99.     'set tile values, and generate x/y values...
  100.     bb = 1
  101.     For r = 1 To GridSize
  102.         For c = 1 To GridSize
  103.             x = (r * TileSize): y = (c * TileSize)
  104.             If Rnd(GridSize * 2) = GridSize Then br = 0
  105.             TileX(bb) = x - TileSize: TileY(bb) = y - TileSize
  106.             TileVal$(bb) = RD$
  107.             TileClr(bb) = 0
  108.             TileClr2(bb) = 0
  109.             bb = bb + 1
  110.         Next c
  111.     Next r
  112.      
  113.     TileClr(1) = 1 'turn on top left leader tile
  114.     TileClr2(1) = 1 'make a copy
  115.      
  116.     setmaze 'Load level maze data, it's already scrambled up
  117.      
  118.     firstdraw = 1
  119.     GoSub updatebuttons
  120.      
  121.     Do
  122.      
  123.         _Limit 300
  124.      
  125.         'wait until mouse button up to continue
  126.         While _MouseButton(1) <> 0: n = _MouseInput: Wend
  127.      
  128.         trap = _MouseInput
  129.         If _MouseButton(1) Then
  130.             mx = _MouseX: my = _MouseY
  131.      
  132.             For b = 1 To (GridSize * GridSize)
  133.      
  134.                 tx = TileX(b): tx2 = TileX(b) + TileSize
  135.                 ty = TileY(b): ty2 = TileY(b) + TileSize
  136.      
  137.                 If mx >= tx And mx <= tx2 Then
  138.                     If my >= ty And my <= ty2 Then
  139.                         'skip any black blocks clicked on
  140.                         If TileVal$(b) = BM$ Then GoTo skip
  141.      
  142.                         _SndPlay move&
  143.      
  144.                         bv2$ = TileVal$(b) 'see what tile it is
  145.      
  146.                         'rotate right angle tiles
  147.                         If bv2$ = RD$ Then TileVal$(b) = LD$
  148.                         If bv2$ = LD$ Then TileVal$(b) = LU$
  149.                         If bv2$ = LU$ Then TileVal$(b) = RU$
  150.                         If bv2$ = RU$ Then TileVal$(b) = RD$
  151.      
  152.                         'rotate horiz/vert lines
  153.                         If bv2$ = HZ$ Then TileVal$(b) = VT$
  154.                         If bv2$ = VT$ Then TileVal$(b) = HZ$
  155.      
  156.                         'show tile
  157.                         If TileClr(b) = 1 Then
  158.                             tag$ = "-grn.png"
  159.                         Else
  160.                             tag$ = "-wht.png"
  161.                         End If
  162.      
  163.                         SHOW TileVal$(b) + tag$, TileX(b), TileY(b), TileX(b) + TileSize, TileY(b) + TileSize
  164.      
  165.                         GoSub updatebuttons
  166.                         GoSub checkforwin
  167.      
  168.                     End If
  169.                 End If
  170.             Next b
  171.         End If
  172.         skip:
  173.      
  174.         ink$ = UCase$(InKey$)
  175.      
  176.         If ink$ = Chr$(32) Then GoTo newlevel
  177.      
  178.         'Right arrows advance to next level
  179.         If ink$ = Chr$(0) + Chr$(77) Then
  180.             GridSize = GridSize + 1
  181.             Level = Level + 1
  182.             If Level > MaxLevel Then Level = 1
  183.             If GridSize > MaxGridSize Then
  184.                 GridSize = 3 'MaxGridSize  'restart
  185.             End If
  186.             GoTo newlevel
  187.         End If
  188.      
  189.         'Left Arrows go back a level
  190.         If ink$ = Chr$(0) + Chr$(75) Then
  191.             GridSize = GridSize - 1
  192.             If GridSize < 3 Then GridSize = MaxGridSize
  193.             Level = Level - 1
  194.             If Level < 1 Then Level = MaxLevel
  195.             GoTo newlevel
  196.         End If
  197.      
  198.     Loop Until ink$ = Chr$(27)
  199.      
  200.     System
  201.      
  202.     '============
  203.     updatebuttons:
  204.     '============
  205.      
  206.     'first tile always on, draw it green
  207.     SHOW TileVal$(1) + "-grn.png", TileX(1), TileY(1), TileX(1) + TileSize, TileY(1) + TileSize
  208.      
  209.      
  210.     'turn all off tile colors first, except 1st
  211.     For g = 2 To GridSize * GridSize
  212.         TileClr(g) = 0
  213.     Next g
  214.      
  215.      
  216.     'set leader tile flow direction
  217.     If TileVal$(1) = HZ$ Then direction = 1 'going right
  218.     If TileVal$(1) = VT$ Then direction = 2 'going down
  219.      
  220.     cur = 1 'start with 1st tile always
  221.      
  222.     'do until can't flow anymore (direction blocked)
  223.     Do
  224.      
  225.         If direction = 1 Then 'heading right
  226.             'see if already on the right edge of board
  227.             'if so, it can't go right anymore, so end flow...
  228.             For j = (GridSize * GridSize) - GridSize + 1 To GridSize * GridSize
  229.                 If cur = j Then GoTo flowdone
  230.             Next j
  231.             'now see if one to the right can connect with it.
  232.             'if not connectable, end flow here.
  233.             con = 0 'default is not connectable
  234.             nv$ = TileVal$(cur + GridSize)
  235.             If nv$ = HZ$ Then con = 1
  236.             If nv$ = LU$ Then con = 1
  237.             If nv$ = LD$ Then con = 1
  238.             'if not, end flow here
  239.             If con = 0 Then GoTo flowdone
  240.             'looks like it is connectable, so turn it on
  241.             TileClr(cur + GridSize) = 1 'turn piece to the right on.
  242.             'Make new pieve the new current flow position
  243.             tc = (cur + GridSize): cur = tc
  244.             'find/set new direction based on that character
  245.             If nv$ = HZ$ Then direction = 1 'right
  246.             If nv$ = LU$ Then direction = 4 'up
  247.             If nv$ = LD$ Then direction = 2 'down
  248.         End If
  249.      
  250.         If direction = 2 Then 'heading down
  251.             'see if this one is on the bottom edge
  252.             For j = GridSize To (GridSize * GridSize) Step GridSize
  253.                 If cur = j Then GoTo flowdone
  254.             Next j
  255.             'now see if new one can connect with this one.
  256.             'if not, end flow here.
  257.             con = 0 'default is not connectable
  258.             nv$ = TileVal$(cur + 1)
  259.             If nv$ = VT$ Then con = 1
  260.             If nv$ = LU$ Then con = 1
  261.             If nv$ = RU$ Then con = 1
  262.             'if not, end flow here
  263.             If con = 0 Then GoTo flowdone
  264.             'looks like it must be connectable
  265.             TileClr(cur + 1) = 1 'turn the next piece on too
  266.             'Make it the new current char position
  267.             tc = (cur + 1): cur = tc
  268.             'find/set new direction based on character
  269.             If nv$ = LU$ Then direction = 3 'left
  270.             If nv$ = RU$ Then direction = 1 'right
  271.             If nv$ = VT$ Then direction = 2 'down
  272.         End If
  273.      
  274.         If direction = 3 Then 'heading left
  275.             'see if this one is on the bottom edge
  276.             For j = 1 To GridSize
  277.                 If cur = j Then GoTo flowdone
  278.             Next j
  279.      
  280.             'now see if new one can connect with this one.
  281.             'if not, end flow here.
  282.             con = 0 'default is not connectable
  283.             nv$ = TileVal$(cur - GridSize)
  284.             If nv$ = HZ$ Then con = 1
  285.             If nv$ = RU$ Then con = 1
  286.             If nv$ = RD$ Then con = 1
  287.             'if not, end flow here
  288.             If con = 0 Then GoTo flowdone
  289.             'looks like it must be connectable
  290.             TileClr(cur - GridSize) = 1 'turn the next piece on too
  291.             'Make it the new current char position
  292.             tc = (cur - GridSize): cur = tc
  293.             'find/set new direction based on character
  294.             If nv$ = HZ$ Then direction = 3 'left
  295.             If nv$ = RU$ Then direction = 4 'up
  296.             If nv$ = RD$ Then direction = 2 'down
  297.         End If
  298.      
  299.         If direction = 4 Then 'going up
  300.             'see if this one is on the edge of board
  301.             'if so, it can't go up, so end flow...
  302.             For j = 1 To (GridSize * GridSize) Step GridSize
  303.                 If cur = j Then GoTo flowdone
  304.             Next j
  305.             'now see if new one can connect with this one.
  306.             'if not, end flow here.
  307.             con = 0 'default is not connectable
  308.             nv$ = TileVal$(cur - 1)
  309.             If nv$ = VT$ Then con = 1
  310.             If nv$ = LD$ Then con = 1
  311.             If nv$ = RD$ Then con = 1
  312.             'if not, end flow here
  313.             If con = 0 Then GoTo flowdone
  314.             'looks like it must be connectable
  315.             TileClr(cur - 1) = 1 'turn the next piece on too
  316.             'Make it the new current char position
  317.             tc = (cur - 1): cur = tc
  318.             'find/set new direction based on character
  319.             If nv$ = VT$ Then direction = 4 'up
  320.             If nv$ = LD$ Then direction = 3 'left
  321.             If nv$ = RD$ Then direction = 1 'right
  322.         End If
  323.      
  324.     Loop
  325.      
  326.     flowdone:
  327.      
  328.     If firstdraw = 0 Then
  329.      
  330.         'draw/colorize board
  331.         For t = 2 To (GridSize * GridSize)
  332.             If TileClr(t) = 1 And TileClr2(t) = 0 Then
  333.                 'show green...
  334.                 SHOW TileVal$(t) + "-grn.png", TileX(t), TileY(t), TileX(t) + TileSize, TileY(t) + TileSize
  335.             End If
  336.             If TileClr(t) = 0 And TileClr2(t) = 1 Then
  337.                 'show white...
  338.                 SHOW TileVal$(t) + "-wht.png", TileX(t), TileY(t), TileX(t) + TileSize, TileY(t) + TileSize
  339.             End If
  340.         Next t
  341.      
  342.     Else
  343.      
  344.         'draw/colorize board
  345.         For t = 2 To (GridSize * GridSize)
  346.             If TileClr(t) = 1 Then
  347.                 tag$ = "-grn.png"
  348.             Else
  349.                 tag$ = "-wht.png"
  350.             End If
  351.             SHOW TileVal$(t) + tag$, TileX(t), TileY(t), TileX(t) + TileSize, TileY(t) + TileSize
  352.         Next t
  353.      
  354.         firstdraw = 0
  355.      
  356.     End If
  357.      
  358.      
  359.     'copy current color values
  360.     For t = 1 To GridSize * GridSize
  361.         TileClr2(t) = TileClr(t)
  362.     Next t
  363.      
  364.      
  365.     '===========
  366.     checkforwin:
  367.     '===========
  368.      
  369.     all = 0
  370.     For w = 1 To (GridSize * GridSize)
  371.         If TileClr(w) = 1 Then all = all + 1
  372.         If TileVal$(w) = BM$ Then all = all + 1 'add any blocks
  373.     Next w
  374.      
  375.     If all = (GridSize * GridSize) Then
  376.      
  377.         ' bplus rewrote this section to fade in the You did it! sign over the gameboard =======================
  378.         ' Solved& has already been loaded after sounds at start of program
  379.         _SndPlay clap&
  380.         snap& = _NewImage(_Width, _Height, 32)
  381.         _PutImage , 0, snap&
  382.         For alph = 0 To 255
  383.             Cls
  384.             _PutImage , snap&, 0 'background
  385.             _SetAlpha alph, , Solved&
  386.             _PutImage (166, 258), Solved&
  387.             _Limit 40 ' 255 frames in 2 secs
  388.             _Display ' damn blinking!!! without this
  389.         Next
  390.         _AutoDisplay '<<<<<< back to not needing _display
  391.         _FreeImage snap&
  392.         ' end of bplus meddling ================================================================================
  393.      
  394.         Level = Level + 1
  395.      
  396.         GridSize = GridSize + 1
  397.      
  398.         If Level > MaxLevel Then Level = 1
  399.      
  400.         If GridSize > MaxGridSize Then
  401.             GridSize = 3 'MaxGridSize  'restart
  402.         End If
  403.      
  404.         GoTo newlevel
  405.      
  406.     End If
  407.      
  408.     Return
  409.      
  410.      
  411.     Sub setmaze ()
  412.      
  413.         If Level = 1 Then
  414.             GridSize = 3
  415.             a$ = "" '3x3 MazeConnect GridSize
  416.             a$ = a$ + "hzrdru"
  417.             a$ = a$ + "hzhzhz"
  418.             a$ = a$ + "ldluld"
  419.         End If
  420.      
  421.         If Level = 2 Then
  422.             GridSize = 4
  423.             a$ = "" '4x4 MazeConnect GridSize
  424.             a$ = a$ + "vtvtruru"
  425.             a$ = a$ + "rdvtluhz"
  426.             a$ = a$ + "hzrdruhz"
  427.             a$ = a$ + "ldluldlu"
  428.         End If
  429.      
  430.         If Level = 3 Then
  431.             GridSize = 5
  432.             a$ = "" '5x5 MazeConnect GridSize
  433.             a$ = a$ + "hzrdvtvtld"
  434.             a$ = a$ + "hzhzrdrdhz"
  435.             a$ = a$ + "hzhzldhzhz"
  436.             a$ = a$ + "hzldvtluhz"
  437.             a$ = a$ + "ldvtvtvtlu"
  438.         End If
  439.      
  440.         If Level = 4 Then
  441.             GridSize = 6
  442.             a$ = "" '6x6 MazeConnect GridSize
  443.             a$ = a$ + "hzrdrurdvtru"
  444.             a$ = a$ + "hzhzhzhzrdlu"
  445.             a$ = a$ + "ldluhzhzldru"
  446.             a$ = a$ + "rdvtluhzbmhz"
  447.             a$ = a$ + "hzrdruldruhz"
  448.             a$ = a$ + "ldluldvtlulu"
  449.         End If
  450.      
  451.         If Level = 5 Then
  452.             GridSize = 7
  453.             a$ = "" '7x7 MazeConnect GridSize
  454.             a$ = "vtruvtvtrurdru"
  455.             a$ = a$ + "rdlurdruldluhz"
  456.             a$ = a$ + "ldvtluldrurdlu"
  457.             a$ = a$ + "rdvtrurdluldru"
  458.             a$ = a$ + "ldruldlurdvtlu"
  459.             a$ = a$ + "rdlurdruldvtru"
  460.             a$ = a$ + "ldvtluldvtvtlu"
  461.         End If
  462.      
  463.         If Level = 6 Then
  464.             GridSize = 8
  465.             a$ = "" '8x8 MazeConnect GridSize
  466.             a$ = a$ + "hzvtrurdrurdrubm"
  467.             a$ = a$ + "hzbmldluhzhzldru"
  468.             a$ = a$ + "ldvtrurdluhzrdlu"
  469.             a$ = a$ + "rdvtluldvtluldru"
  470.             a$ = a$ + "ldrurdvtrurdvtlu"
  471.             a$ = a$ + "bmhzhzbmldlurdru"
  472.             a$ = a$ + "rdluldvtvtvtluhz"
  473.             a$ = a$ + "ldvtvtvtvtvtvtlu"
  474.         End If
  475.      
  476.         If Level = 7 Then
  477.             GridSize = 9
  478.             a$ = "" '9x9 MazeConnect GridSize
  479.             a$ = a$ + "hzrdvtvtrurdrurdru"
  480.             a$ = a$ + "hzldvtruldluldluhz"
  481.             a$ = a$ + "ldvtruldrubmrdvtlu"
  482.             a$ = a$ + "rdruldruldruldrubm"
  483.             a$ = a$ + "hzldruldruldruldru"
  484.             a$ = a$ + "ldruhzbmldruhzbmhz"
  485.             a$ = a$ + "rdluldvtvtluldruhz"
  486.             a$ = a$ + "hzrdrurdvtrurdluhz"
  487.             a$ = a$ + "ldluldlubmldluvtlu"
  488.         End If
  489.      
  490.         If Level = 8 Then
  491.             GridSize = 10
  492.             a$ = "" '10x10 MazeConnect GridSize
  493.             a$ = a$ + "vtvtvtrurdrurdvtrubm"
  494.             a$ = a$ + "hzrdvtluhzhzldruldru"
  495.             a$ = a$ + "hzldvtvtluldruhzrdlu"
  496.             a$ = a$ + "hzbmrdvtvtruldluldru"
  497.             a$ = a$ + "hzrdlurdruhzrdvtvtlu"
  498.             a$ = a$ + "hzhzrdluhzldlurdrubm"
  499.             a$ = a$ + "hzhzhzbmldrubmhzldru"
  500.             a$ = a$ + "hzldlurdruldvtlurdlu"
  501.             a$ = a$ + "hzrdruhzldrurdruldru"
  502.             a$ = a$ + "ldluldlubmldluldvtlu"
  503.         End If
  504.      
  505.         If Level = 9 Then
  506.             GridSize = 11
  507.             a$ = "" '11x11 MazeConnect GridSize
  508.             a$ = a$ + "hzvtrubmrdvtrubmrdvtru"
  509.             a$ = a$ + "ldruldruldruldruldruhz"
  510.             a$ = a$ + "bmldruldruldruldruhzhz"
  511.             a$ = a$ + "rdruldruldruldruldluhz"
  512.             a$ = a$ + "hzldruldruldruldrurdlu"
  513.             a$ = a$ + "ldruldruldruldruhzldru"
  514.             a$ = a$ + "bmldruldruldruldlurdlu"
  515.             a$ = a$ + "rdruldruldruldrurdlubm"
  516.             a$ = a$ + "hzldruldruldvtluldvtru"
  517.             a$ = a$ + "ldruldvtlurdrurdrurdlu"
  518.             a$ = a$ + "bmldvtvtvtluldluldlubm"
  519.         End If
  520.      
  521.         If Level = 10 Then
  522.             GridSize = 12
  523.             a$ = "" '12x12 MazeConnect GridSize
  524.             a$ = a$ + "vtvtrubmbmrdrurdrurdvtru"
  525.             a$ = a$ + "bmbmhzbmrdluldluhzhzrdlu"
  526.             a$ = a$ + "bmrdlurdlurdrurdluhzldru"
  527.             a$ = a$ + "rdlurdlurdluhzhzrdlurdlu"
  528.             a$ = a$ + "ldruldvtlurdluhzhzbmldru"
  529.             a$ = a$ + "bmldvtvtruhzbmldlurdvtlu"
  530.             a$ = a$ + "rdvtvtvtluhzrdvtvtlurdru"
  531.             a$ = a$ + "ldrurdvtvtluhzrdvtvtluhz"
  532.             a$ = a$ + "rdluhzbmbmbmldlurdrurdlu"
  533.             a$ = a$ + "hzrdlurdrurdrubmhzhzhzbm"
  534.             a$ = a$ + "ldlurdluhzhzhzrdluhzldru"
  535.             a$ = a$ + "vtvtlubmldluldlubmldvtlu"
  536.         End If
  537.      
  538.         If Level = 11 Then
  539.             GridSize = 13
  540.             a$ = "" '13x13 MazeConnect GridSize
  541.             a$ = a$ + "hzvtvtvtvtvtrurdrurdrurdru"
  542.             a$ = a$ + "hzrdrurdvtruldluhzhzldluhz"
  543.             a$ = a$ + "hzhzhzhzspldvtruhzhzrdruhz"
  544.             a$ = a$ + "hzhzhzldrubmrdluldluhzhzhz"
  545.             a$ = a$ + "hzhzldvtlurdlurdvtvtluldlu"
  546.             a$ = a$ + "hzldrubmrdlubmldvtvtrurdru"
  547.             a$ = a$ + "ldruldruhzbmbmbmrdruhzhzhz"
  548.             a$ = a$ + "rdlurdluldrubmrdluhzldluhz"
  549.             a$ = a$ + "hzrdlurdruldvtlurdlubmrdlu"
  550.             a$ = a$ + "hzldruhzldrurdvtlurdruldru"
  551.             a$ = a$ + "hzrdluhzbmldlurdvtluhzrdlu"
  552.             a$ = a$ + "hzhzrdlurdvtruhzrdvtluldru"
  553.             a$ = a$ + "ldluldvtlubmldluldvtvtvtlu"
  554.         End If
  555.      
  556.         If Level = 12 Then
  557.             GridSize = 14
  558.             a$ = "" '14x14 MazeConnect GridSize
  559.             a$ = a$ + "hzrdrurdvtvtrurdrurdvtvtrubm"
  560.             a$ = a$ + "hzhzhzldvtruhzhzhzhzrdruhzbm"
  561.             a$ = a$ + "ldluhzrdruhzldluldluhzhzhzbm"
  562.             a$ = a$ + "rdruhzhzhzldvtvtvtruhzldlubm"
  563.             a$ = a$ + "hzhzhzhzhzrdrurdruhzldvtrubm"
  564.             a$ = a$ + "hzhzhzhzhzhzhzhzhzhzrdruldru"
  565.             a$ = a$ + "hzhzldluhzhzhzhzhzhzhzldvtlu"
  566.             a$ = a$ + "hzldvtruhzhzhzhzhzhzldrurdru"
  567.             a$ = a$ + "hzrdruhzldluhzhzhzhzbmldluhz"
  568.             a$ = a$ + "ldluhzldvtruhzhzhzhzrdrurdlu"
  569.             a$ = a$ + "rdruhzrdvtluhzhzldluhzhzhzbm"
  570.             a$ = a$ + "hzldluldvtvtluhzrdvtluhzhzbm"
  571.             a$ = a$ + "hzvtvtvtvtvtvtluldrurdluhzbm"
  572.             a$ = a$ + "ldvtvtvtvtvtvtvtvtluldvtlubm"
  573.         End If
  574.      
  575.         If Level = 13 Then
  576.             GridSize = 15
  577.             a$ = "" '15x15 MazeConnect GridSize
  578.             a$ = a$ + "vtvtrurdrurdrurdrubmrdvtvtvtru"
  579.             a$ = a$ + "vtruldluhzhzldluldvtlurdvtruhz"
  580.             a$ = a$ + "rdlubmbmhzldvtvtrurdvtlubmldlu"
  581.             a$ = a$ + "ldrurdruhzbmrdruhzldrurdvtvtru"
  582.             a$ = a$ + "bmhzhzldlurdluhzldruldlurdvtlu"
  583.             a$ = a$ + "rdluldrurdlubmhzrdlurdruldrubm"
  584.             a$ = a$ + "ldrubmldlurdruldlubmhzhzbmldru"
  585.             a$ = a$ + "rdlurdvtvtluldrurdruhzhzrdvtlu"
  586.             a$ = a$ + "ldvtlurdvtvtvtluhzldluhzldvtru"
  587.             a$ = a$ + "rdvtvtlurdvtvtruldrurdlurdruhz"
  588.             a$ = a$ + "ldvtrurdlubmrdlurdluhzrdluldlu"
  589.             a$ = a$ + "rdvtluldrurdlurdlurdluhzbmrdru"
  590.             a$ = a$ + "ldvtrurdluhzbmldruldruldvtluhz"
  591.             a$ = a$ + "rdvtluldruhzrdruldruldvtrurdlu"
  592.             a$ = a$ + "ldvtvtvtluldluldvtlubmbmldlubm"
  593.         End If
  594.      
  595.         dd = 1
  596.         For s = 1 To Len(a$) Step 2
  597.             b$ = Mid$(a$, s, 2)
  598.             If b$ = "vt" Then rotate dd, 1
  599.             If b$ = "hz" Then rotate dd, 1
  600.             If b$ = "ld" Then rotate dd, 2
  601.             If b$ = "lu" Then rotate dd, 2
  602.             If b$ = "rd" Then rotate dd, 2
  603.             If b$ = "ru" Then rotate dd, 2
  604.             If b$ = "bm" Then TileVal$(dd) = BM$
  605.      
  606.             dd = dd + 1
  607.         Next s
  608.      
  609.     End Sub
  610.      
  611.     Sub rotate (num, typ)
  612.      
  613.         'there are only two types of rotating characters,
  614.         'straight lines, or right angles...
  615.      
  616.         'randomly rotate straight character
  617.         If typ = 1 Then
  618.             If Int(Rnd * 2) = 0 Then
  619.                 TileVal$(num) = VT$
  620.             Else
  621.                 TileVal$(num) = HZ$
  622.             End If
  623.         End If
  624.      
  625.         'randomly rotate right angles...
  626.         If typ = 2 Then
  627.             rn = Int(Rnd * 4) + 1
  628.             If rn = 1 Then TileVal$(num) = LD$
  629.             If rn = 2 Then TileVal$(num) = LU$
  630.             If rn = 3 Then TileVal$(num) = RD$
  631.             If rn = 4 Then TileVal$(num) = RU$
  632.         End If
  633.      
  634.     End Sub
  635.      
  636.     Sub SHOW (i$, x1, y1, x2, y2)
  637.         'Just a little sub to load & put an image at x1/y1
  638.         ttmp = _LoadImage(i$)
  639.         _PutImage (x1, y1)-(x2, y2), ttmp
  640.         _FreeImage ttmp
  641.     End Sub
  642.      
  643.     Sub PPRINT (x, y, size, clr&, trans&, text$)
  644.         'This sub outputs to the current _DEST set
  645.         'It makes trans& the transparent color
  646.      
  647.         'x/y is where to print text
  648.         'size is the font size to use
  649.         'clr& is the color of your text
  650.         'trans& is the background transparent color
  651.         'text$ is the string to print
  652.      
  653.         '=== get users current write screen
  654.         orig& = _Dest
  655.      
  656.         '=== if you are using an 8 or 32 bit screen
  657.         bit = 32: If _PixelSize(0) = 1 Then bit = 256
  658.      
  659.         '=== step through your text
  660.         For t = 0 To Len(text$) - 1
  661.             '=== make a temp screen to use
  662.             pprintimg& = _NewImage(16, 16, bit)
  663.             _Dest pprintimg&
  664.             '=== set colors and print text
  665.             Cls , trans&: Color clr&
  666.             Print Mid$(text$, t + 1, 1);
  667.             '== make background color the transprent one
  668.             _ClearColor _RGB(0, 0, 0), pprintimg&
  669.             '=== go back to original screen  to output
  670.             _Dest orig&
  671.             '=== set it and forget it
  672.             x1 = x + (t * size): x2 = x1 + size
  673.             y1 = y: y2 = y + size
  674.             _PutImage (x1 - (size / 2), y1)-(x2, y2 + (size / 3)), pprintimg&
  675.             _FreeImage pprintimg&
  676.         Next
  677.     End Sub
  678.  
  679.  

Attachments:

 

PipesPuzzle.jpg

Author's previous version for rerefence:https://www.qb64.org/foru/index.php?topic=2094.msg113243#msg113243

5
2D/3D Graphics / MOVED: SaveImage (take screenshots) by SMcNeill
« on: September 26, 2021, 04:55:45 am »

6
General, Math & Geometry / MOVED: Curve Smoother
« on: September 25, 2021, 08:02:15 am »

7
General, Math & Geometry / MOVED: Circle Intersecting Line
« on: September 25, 2021, 08:00:25 am »

8
General, Math & Geometry / MOVED: Circle Intersecting Circle
« on: September 25, 2021, 07:57:43 am »

10
Utilities / Filled Circles and Ellipses (collaborative)
« on: September 25, 2021, 06:48:06 am »
Filled Circles and Ellipses

Contributor(s): @bplus, @Pete, @SMcNeill, @STxAxTIC
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=1044.0

Description:
We develop four variations on the CIRCLE command in the form of four SUBs:
(i) CircleFill = Filled circle
(ii) EllipseFill = Filled ellipse
(iii) EllipseTilt = Tilted ellipse
(iv) EllipseTiltFill = Tilted and filled ellipse

These works have been optimized for speed and respect for alpha transparency.


Source Code:
Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(800, 600, 32)
  2.  
  3. DIM TransRed AS _UNSIGNED LONG
  4. DIM TransGreen AS _UNSIGNED LONG
  5. DIM TransBlue AS _UNSIGNED LONG
  6. TransRed = _RGBA(255, 0, 0, 128)
  7. TransGreen = _RGBA(0, 255, 0, 128)
  8. TransBlue = _RGBA(0, 0, 255, 128)
  9.  
  10. CALL CircleFill(100, 100, 75, TransRed)
  11. CALL CircleFill(120, 120, 75, TransBlue)
  12.  
  13. CALL EllipseFill(550, 100, 150, 75, TransBlue)
  14. CALL EllipseFill(570, 120, 150, 75, TransGreen)
  15.  
  16. CALL EllipseTilt(200, 400, 150, 75, 0, TransGreen)
  17. CALL EllipseTilt(220, 420, 150, 75, 3.14 / 4, TransRed)
  18.  
  19. CALL EllipseTiltFill(0, 550, 400, 150, 75, 3.14 / 6, TransRed)
  20. CALL EllipseTiltFill(0, 570, 420, 150, 75, 3.14 / 4, TransGreen)
  21.  
  22.  
  23. SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  24.     ' CX = center x coordinate
  25.     ' CY = center y coordinate
  26.     '  R = radius
  27.     '  C = fill color
  28.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  29.     DIM X AS INTEGER, Y AS INTEGER
  30.     Radius = ABS(R)
  31.     RadiusError = -Radius
  32.     X = Radius
  33.     Y = 0
  34.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  35.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  36.     WHILE X > Y
  37.         RadiusError = RadiusError + Y * 2 + 1
  38.         IF RadiusError >= 0 THEN
  39.             IF X <> Y + 1 THEN
  40.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  41.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  42.             END IF
  43.             X = X - 1
  44.             RadiusError = RadiusError - X * 2
  45.         END IF
  46.         Y = Y + 1
  47.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  48.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  49.     WEND
  50.  
  51. SUB EllipseFill (CX AS INTEGER, CY AS INTEGER, a AS INTEGER, b AS INTEGER, C AS _UNSIGNED LONG)
  52.     ' CX = center x coordinate
  53.     ' CY = center y coordinate
  54.     '  a = semimajor axis
  55.     '  b = semiminor axis
  56.     '  C = fill color
  57.     IF a = 0 OR b = 0 THEN EXIT SUB
  58.     DIM h2 AS _INTEGER64
  59.     DIM w2 AS _INTEGER64
  60.     DIM h2w2 AS _INTEGER64
  61.     DIM x AS INTEGER
  62.     DIM y AS INTEGER
  63.     w2 = a * a
  64.     h2 = b * b
  65.     h2w2 = h2 * w2
  66.     LINE (CX - a, CY)-(CX + a, CY), C, BF
  67.     DO WHILE y < b
  68.         y = y + 1
  69.         x = SQR((h2w2 - y * y * w2) \ h2)
  70.         LINE (CX - x, CY + y)-(CX + x, CY + y), C, BF
  71.         LINE (CX - x, CY - y)-(CX + x, CY - y), C, BF
  72.     LOOP
  73.  
  74. SUB EllipseTilt (CX, CY, a, b, ang, C AS _UNSIGNED LONG)
  75.     '  CX = center x coordinate
  76.     '  CY = center y coordinate
  77.     '   a = semimajor axis
  78.     '   b = semiminor axis
  79.     ' ang = clockwise orientation of semimajor axis in radians (0 default)
  80.     '   C = fill color
  81.     FOR k = 0 TO 6.283185307179586 + .025 STEP .025
  82.         i = a * COS(k) * COS(ang) + b * SIN(k) * SIN(ang)
  83.         j = -a * COS(k) * SIN(ang) + b * SIN(k) * COS(ang)
  84.         i = i + CX
  85.         j = -j + CY
  86.         IF k <> 0 THEN
  87.             LINE -(i, j), C
  88.         ELSE
  89.             PSET (i, j), C
  90.         END IF
  91.     NEXT
  92.  
  93. SUB EllipseTiltFill (destHandle&, CX, CY, a, b, ang, C AS _UNSIGNED LONG)
  94.     '  destHandle& = destination handle
  95.     '  CX = center x coordinate
  96.     '  CY = center y coordinate
  97.     '   a = semimajor axis
  98.     '   b = semiminor axis
  99.     ' ang = clockwise orientation of semimajor axis in radians (0 default)
  100.     '   C = fill color
  101.     DIM max AS INTEGER, mx2 AS INTEGER, i AS INTEGER, j AS INTEGER
  102.     DIM prc AS _UNSIGNED LONG
  103.     DIM D AS INTEGER, S AS INTEGER
  104.     D = _DEST: S = _SOURCE
  105.     prc = _RGB32(255, 255, 255, 255)
  106.     IF a > b THEN max = a + 1 ELSE max = b + 1
  107.     mx2 = max + max
  108.     tef& = _NEWIMAGE(mx2, mx2)
  109.     _DEST tef&
  110.     _SOURCE tef&
  111.     FOR k = 0 TO 6.283185307179586 + .025 STEP .025
  112.         i = max + a * COS(k) * COS(ang) + b * SIN(k) * SIN(ang)
  113.         j = max + a * COS(k) * SIN(ang) - b * SIN(k) * COS(ang)
  114.         IF k <> 0 THEN
  115.             LINE (lasti, lastj)-(i, j), prc
  116.         ELSE
  117.             PSET (i, j), prc
  118.         END IF
  119.         lasti = i: lastj = j
  120.     NEXT
  121.     DIM xleft(mx2) AS INTEGER, xright(mx2) AS INTEGER, x AS INTEGER, y AS INTEGER
  122.     FOR y = 0 TO mx2
  123.         x = 0
  124.         WHILE POINT(x, y) <> prc AND x < mx2
  125.             x = x + 1
  126.         WEND
  127.         xleft(y) = x
  128.         WHILE POINT(x, y) = prc AND x < mx2
  129.             x = x + 1
  130.         WEND
  131.         WHILE POINT(x, y) <> prc AND x < mx2
  132.             x = x + 1
  133.         WEND
  134.         IF x = mx2 THEN xright(y) = xleft(y) ELSE xright(y) = x
  135.     NEXT
  136.     _DEST destHandle&
  137.     FOR y = 0 TO mx2
  138.         IF xleft(y) <> mx2 THEN LINE (xleft(y) + CX - max, y + CY - max)-(xright(y) + CX - max, y + CY - max), C, BF
  139.     NEXT
  140.     _DEST D: _DEST S
  141.     _FREEIMAGE tef&
  142.  

Attachments:
 
                                                                                                                                         (191 downloads previously)

Ellipses.png

11
Utilities / RotoZoom3 (Modification) by bplus
« on: September 25, 2021, 06:20:27 am »
Author and contributor: @bplus @Galleon
Source: QB64.org Wiki and Forum
URL: https://www.qb64.org/wiki/MAPTRIANGLE
https://www.qb64.org/forum/index.php?topic=1511.msg115148#msg115148
Version: 2020 version #3
Tags: [graphics] [image]
Description:
A modification of Galleon's RotoZoom in Wiki that both scales and rotates an image, this version scales the x-axis and y-axis independently allowing some rotations of image just by changing X or Y Scales making this already powerful routine even more a versatile image tool.

Source Code (and demos with Spike Image (attached)):
Code: QB64: [Select]
  1. _TITLE "Another RotoZoom Demo" 'b+ started 2020-03-02
  2.  
  3. CONST xmax = 1200, ymax = 700, xc = 600, yc = 350
  4. SCREEN _NEWIMAGE(xmax, ymax, 32)
  5. _SCREENMOVE 100, 40
  6. DIM SHARED s&, ao
  7. DIM a, x, y, x1, y1, xs, dxs, ddxs, ys, dys, ddys, maxScale
  8.  
  9. ' Starting from an image I pulled from Internet, I used Paint 3D to give it a transparent background.
  10. s& = _LOADIMAGE("tspike.png") 't for transparent background
  11.  
  12.  
  13. ' Standard Rotation about the image center on a given X, Y location. Rotating image in middle of screen,
  14. ' I used something like this to find ideal angle for level point on left head on right.
  15. WHILE _KEYDOWN(27) = 0
  16.     a = a + _PI(1 / 36)
  17.     IF a > _PI(1.999) THEN a = 0
  18.     CLS
  19.     RotoZoom3 xc, yc, s&, 1, 1, a
  20.     PRINT "Raw image rotation:": PRINT
  21.     PRINT "radian angle:"; a; "   degrees:"; _R2D(a) \ 1; " press key for next angle... esc to rotate on y axis"
  22.     WHILE LEN(INKEY$) = 0: _LIMIT 60: WEND
  23.  
  24. ao = _PI(.27) ' I have to offset the image angle by this amount so that the spike point is on the left
  25. '               and the head is on the right at 0 degrees or radians.
  26.  
  27.  
  28. 'Demo of the independent x and y scale for axis rotations
  29. maxScale = 4: dxs = .01: ddxs = 1: xs = maxScale:
  30.     CLS
  31.     PRINT "Press any for rotation on x axis..."
  32.     RotoZoom3 xc, yc, s&, xs, maxScale, ao
  33.     IF xs + dxs > maxScale OR xs + dxs < -maxScale THEN ddxs = ddxs * -1
  34.     xs = xs + dxs * ddxs
  35.     _DISPLAY
  36.     _LIMIT 60
  37.  
  38. ys = maxScale: dys = .01: ddys = 1
  39.     CLS
  40.     PRINT "Press any to see layout of image over whole screen and end demo..."
  41.     RotoZoom3 xc, yc, s&, maxScale, ys, ao
  42.     IF ys + dys > maxScale OR ys + dys < -maxScale THEN ddys = ddys * -1
  43.     ys = ys + dys * ddys
  44.     _DISPLAY
  45.     _LIMIT 60
  46.  
  47. ' Demo of an applied layout on screen
  48. COLOR , &HFFBBBBBB: CLS ' the image has slight gray halo so hide with gray background
  49. FOR x = 40 TO _WIDTH - 40 STEP 20
  50.     RotoZoom3 x, 15, s&, .2, .2, _PI(1.5 + .27)
  51.     RotoZoom3 x, _HEIGHT - 15, s&, .2, .2, _PI(.5 + .27)
  52. FOR y = 40 TO _HEIGHT - 40 STEP 20
  53.     RotoZoom3 15, y, s&, .2, .2, _PI(1 + .27)
  54.     RotoZoom3 _WIDTH - 15, y, s&, .2, .2, _PI(.27)
  55. FOR a = 0 TO _PI(2) STEP _PI(1 / 6)
  56.     x1 = xc + 200 * COS(a)
  57.     y1 = yc + 200 * SIN(a)
  58.     RotoZoom3 x1, y1, s&, 2, 2, a + ao
  59.  
  60. 'And finally a little show. What is better than a knife thrower throwing bananas?
  61. WHILE _KEYDOWN(27) = 0
  62.     CLS
  63.     drawKite xc, .9 * ymax, 600, a + ao
  64.     _DISPLAY
  65.     _LIMIT 30
  66.     a = a + _PI(2 / 360)
  67.  
  68. SUB drawKite (x, y, s, a)
  69.     RotoZoom3 x, y, s&, s / _WIDTH(s&), s / _HEIGHT(s&), a + ao
  70.     IF s > 10 THEN
  71.         drawKite x + .5 * s * COS(_PI(2) - a), (y - .25 * s) + .25 * s * SIN(_PI(2) - a), s / 1.5, a
  72.         drawKite x + .5 * s * COS(_PI + a), (y - .25 * s) + .25 * s * SIN(_PI + a), s / 1.5, a
  73.     END IF
  74.  
  75. ' Description:
  76. ' Started from a mod of Galleon's in Wiki that both scales and rotates an image.
  77. ' This version scales the x-axis and y-axis independently allowing rotations of image just by changing X or Y Scales
  78. ' making this tightly coded routine a very powerful and versatile image tool.
  79. SUB RotoZoom3 (X AS LONG, Y AS LONG, Image AS LONG, xScale AS SINGLE, yScale AS SINGLE, radianRotation AS SINGLE)
  80.     ' This assumes you have set your drawing location with _DEST or default to screen.
  81.     ' X, Y - is where you want to put the middle of the image
  82.     ' Image - is the handle assigned with _LOADIMAGE
  83.     ' xScale, yScale - are shrinkage < 1 or magnification > 1 on the given axis, 1 just uses image size.
  84.     ' These are multipliers so .5 will create image .5 size on given axis and 2 for twice image size.
  85.     ' radianRotation is the Angle in Radian units to rotate the image
  86.     ' note: Radian units for rotation because it matches angle units of other Basic Trig functions
  87.     '       and saves a little time converting from degree.
  88.     '       Use the _D2R() function if you prefer to work in degree units for angles.
  89.  
  90.     DIM px(3) AS SINGLE: DIM py(3) AS SINGLE ' simple arrays for x, y to hold the 4 corners of image
  91.     DIM W&, H&, sinr!, cosr!, i&, x2&, y2& '   variables for image manipulation
  92.     W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
  93.     px(0) = -W& / 2: py(0) = -H& / 2 'left top corner
  94.     px(1) = -W& / 2: py(1) = H& / 2 ' left bottom corner
  95.     px(2) = W& / 2: py(2) = H& / 2 '  right bottom
  96.     px(3) = W& / 2: py(3) = -H& / 2 ' right top
  97.     sinr! = SIN(-radianRotation): cosr! = COS(-radianRotation) ' rotation helpers
  98.     FOR i& = 0 TO 3 ' calc new point locations with rotation and zoom
  99.         x2& = xScale * (px(i&) * cosr! + sinr! * py(i&)) + X: y2& = yScale * (py(i&) * cosr! - px(i&) * sinr!) + Y
  100.         px(i&) = x2&: py(i&) = y2&
  101.     NEXT
  102.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  103.     _MAPTRIANGLE _SEAMLESS(0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  104.  
  105.  

Attachments:
 
                                                                                                                                         (124 downloads previously)

Spiked.PNG

12
General, Math & Geometry / Convert BMP to Dominoes by Richard Frost
« on: September 25, 2021, 05:46:49 am »
Convert BMP to Dominoes

Author: @Richard Frost
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=1023.0
Version: 2019

Description:
[This] is an image converter that takes a picture a small block at a time and finds the "best fit" domino for that space. (The woman is Heather Thomas.)

Source Code:
Code: QB64: [Select]
  1. ' The woman is Heather Thomas
  2.  
  3. DEFINT A-Z
  4. DIM dots(7), x(7, 7), y(7, 7), c1(7), c2(28), pixel(7, 7), w(3), y$(30)
  5. cps! = 12.83 ' cost per set
  6. FOR i = 1 TO 28: READ y$(i): NEXT i
  7. FOR n = 1 TO 7
  8.     READ dots(n)
  9.     FOR dot = 1 TO dots(n)
  10.         READ x(n, dot), y(n, dot)
  11.     NEXT dot
  12. xb = 10: xe = 350 ' x begin and end
  13. yb = 0: ye = 470 ' y begin and end
  14. OPEN "heath.bmp" FOR RANDOM AS #1 LEN = 1: FIELD #1, 1 AS t$
  15. FOR y1 = yb TO ye STEP 8
  16.     FOR x1 = xb TO xe STEP 8
  17.         n = 0
  18.         FOR y2 = 0 TO 7
  19.             FOR x2 = 0 TO 7
  20.                 x3 = x1 + x2
  21.                 y3 = y1 + y2
  22.                 r& = CDBL(479 - y3) * 640 + x3 + 441
  23.                 GET #1, r&
  24.                 d = ASC(t$) \ 13
  25.                 IF d > 15 THEN d = 15
  26.                 pixel(x2, y2) = -(d > 7) ' for 3 problem
  27.                 n = n + d
  28.             NEXT x2
  29.         NEXT y2
  30.         n = n / 155 ' 175
  31.         IF n > 6 THEN n = 6
  32.         x$ = x$ + CHR$(48 + n) ' for counting tiles used
  33.         IF LEN(x$) = 2 THEN ' got left & right
  34.             FOR i = 1 TO 28
  35.                 IF x$ = y$(i) THEN c2(i) = c2(i) + 1: EXIT FOR
  36.             NEXT i
  37.             x$ = ""
  38.         END IF
  39.         IF n = 3 THEN ' default bottom left - top right
  40.             IF (l = 3) OR (l = 7) THEN ' can't change direction if the
  41.                 n = l ' last piece was also a 3
  42.             ELSE
  43.                 FOR zi = 0 TO 3
  44.                     w(zi) = 0
  45.                 NEXT zi
  46.                 FOR y2 = 0 TO 7
  47.                     FOR x2 = 0 TO 7
  48.                         xi = x2 \ 4 ' 0 or 1
  49.                         yi = y2 \ 4 ' 0 or 1
  50.                         zi = xi * 2 + yi ' 0-3
  51.                         ' LOCATE zi + 1, 1: PRINT zi;
  52.                         w(zi) = w(zi) + pixel(x2, y2)
  53.                     NEXT x2
  54.                 NEXT y2
  55.                 IF (w(1) + w(2)) > (w(0) + w(3)) THEN n = 7
  56.             END IF
  57.         END IF
  58.         l = n ' save last used (for 3)
  59.         d = dots(n)
  60.         c1(n) = c1(n) + 1
  61.         FOR dot = 1 TO d
  62.             tx = (x1 + 4) + x(n, dot) * 2 - xb
  63.             ty = (y1 + 4) + y(n, dot) * 2 - yb
  64.             PSET (tx, ty), 15
  65.         NEXT dot
  66.         IF INKEY$ = CHR$(27) THEN CLOSE: SCREEN 0, 0, 0, 0: END
  67.         nd = nd + 1
  68.     NEXT x1
  69.     GOSUB Status
  70. NEXT y1
  71.  
  72. Status:
  73. FOR i = 0 TO 7
  74.     'COLOR i
  75.     LOCATE i + 2, 49: PRINT USING "####"; i; c1(i);
  76. RESTORE count
  77. FOR i = 1 TO 28
  78.     LOCATE i + 1, 60: PRINT " ";
  79.     LOCATE i + 1, 60
  80.     IF c2(i) >= max THEN
  81.         max = c2(i)
  82.         PRINT "*";
  83.     ELSE
  84.         PRINT " ";
  85.     END IF
  86.     PRINT y$(i);
  87.     PRINT USING " #### "; c2(i);
  88.     c! = c2(i) * cps!
  89.     c! = c! + c! * .07
  90.     PRINT USING "####.##"; c!;
  91. xn = (xe - xb) / 16
  92. yn = (ye - yb) / 8
  93. LOCATE 27, 52: PRINT xn;
  94. LOCATE 28, 52: PRINT yn;
  95. LOCATE 29, 52: PRINT xn * yn;
  96.  
  97. count:
  98. DATA 00,01,02,03,04,05,06
  99. DATA 11,12,13,14,15,16
  100. DATA 22,23,24,25,26
  101. DATA 33,34,35,36
  102. DATA 44,45,46
  103. DATA 55,56
  104. DATA 66
  105.  
  106. dots:
  107. DATA 1,0,0
  108. DATA 2,0,-1,0,1
  109. DATA 3,-1,-1,0,0,1,1
  110. DATA 4,-1,1,-1,-1,1,-1,1,1
  111. DATA 5,-1,1,-1,-1,1,-1,1,1,0,0
  112. DATA 6,-1,1,-1,0,-1,-1,1,1,1,0,1,-1
  113. DATA 3,1,-1,0,0,-1,1
  114.  

Attachments:
Requires HEATH.BMP

 
                                                                                                                                         (219 downloads previously)
 
HEATH.BMP


BMP2Dominoes.png

13
General, Math & Geometry / InForm Calculator by Terry Ritchie
« on: September 24, 2021, 05:12:55 am »
InForm Calculator

Author: @TerryRitchie
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=507.0
Version: 1

Description:
This is a calculator program I have been working on.  This little program gave me the general feel for InForm and got me back into programming QB64, a win-win.

Source Code:
Code: QB64: [Select]
  1.  
  2.     ':  ____ ____ ____ ____ ____ ____ ____ ____ ____ ____
  3.     ': ||C |||A |||L |||C |||U |||L |||A |||T |||O |||R ||
  4.     ': ||__|||__|||__|||__|||__|||__|||__|||__|||__|||__||
  5.     ': |/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|
  6.     ':
  7.     ': QB64 Calculator V1.0
  8.     ': Terry Ritchie - 08/29/18
  9.     ':
  10.     ': Built as a clone of the Windows 7 standard calculator
  11.     ': An exersize in getting to know the InForm library
  12.     ':
  13.     ': This program uses
  14.     ': InForm - GUI library for QB64 - Beta version 7
  15.     ': Fellippe Heitor, 2016-2018 - fellippe@qb64.org - [member=2]FellippeHeitor[/member]
  16.     ': https://github.com/FellippeHeitor/InForm
  17.     '----------------------------------------------------------------------------------------------------------------------
  18.      
  19.     ': Program constants: -------------------------------------------------------------------------------------------------
  20.      
  21.     CONST EQUATE = 0
  22.     CONST ADDITION = 1
  23.     CONST SUBTRACTION = 2
  24.     CONST MULTIPLICATION = 3
  25.     CONST DIVISION = 4
  26.      
  27.     ': Controls' IDs: -----------------------------------------------------------------------------------------------------
  28.      
  29.     DIM SHARED Calculator AS LONG
  30.     DIM SHARED frmResults AS LONG
  31.     DIM SHARED mnuEdit AS LONG
  32.     DIM SHARED mnuHelp AS LONG
  33.     DIM SHARED butMC AS LONG
  34.     DIM SHARED butMR AS LONG
  35.     DIM SHARED butMS AS LONG
  36.     DIM SHARED butMplus AS LONG
  37.     DIM SHARED butMminus AS LONG
  38.     DIM SHARED butBS AS LONG
  39.     DIM SHARED butCE AS LONG
  40.     DIM SHARED butC AS LONG
  41.     DIM SHARED butSign AS LONG
  42.     DIM SHARED butSQR AS LONG
  43.     DIM SHARED but7 AS LONG
  44.     DIM SHARED but8 AS LONG
  45.     DIM SHARED but9 AS LONG
  46.     DIM SHARED butDivide AS LONG
  47.     DIM SHARED butPercent AS LONG
  48.     DIM SHARED but4 AS LONG
  49.     DIM SHARED but5 AS LONG
  50.     DIM SHARED but6 AS LONG
  51.     DIM SHARED butMultiply AS LONG
  52.     DIM SHARED butReciprocate AS LONG
  53.     DIM SHARED but1 AS LONG
  54.     DIM SHARED but2 AS LONG
  55.     DIM SHARED but3 AS LONG
  56.     DIM SHARED butSubtract AS LONG
  57.     DIM SHARED but0 AS LONG
  58.     DIM SHARED butPoint AS LONG
  59.     DIM SHARED butAdd AS LONG
  60.     DIM SHARED butEqual AS LONG
  61.     DIM SHARED mnuCopy AS LONG
  62.     DIM SHARED mnuPaste AS LONG
  63.     DIM SHARED mnuAbout AS LONG
  64.     DIM SHARED lblAnswer AS LONG
  65.     DIM SHARED lblMemory AS LONG
  66.     DIM SHARED lblHistory AS LONG
  67.      
  68.     ': Program variables: -------------------------------------------------------------------------------------------------
  69.      
  70.     DIM SHARED operand$ '                       current operand
  71.     DIM SHARED history$ '                       calculation history
  72.     DIM SHARED operand1 AS DOUBLE '             first operand enetered
  73.     DIM SHARED operand2 AS DOUBLE '             second operand entered
  74.     DIM SHARED operator AS INTEGER '            current operator selected
  75.     DIM SHARED operator$(4)
  76.     DIM SHARED previousoperator AS INTEGER '    previous operator saved
  77.     DIM SHARED resetoperand AS INTEGER '        True when operand entry needs reset
  78.     DIM SHARED memory AS DOUBLE '               value stored in memory
  79.     DIM SHARED nohistory AS INTEGER
  80.      
  81.     ': External modules: --------------------------------------------------------------------------------------------------
  82.      
  83.     '$INCLUDE:'InForm\InForm.ui'
  84.     '$INCLUDE:'InForm\xp.uitheme'
  85.     '$INCLUDE:'Calculator.frm'
  86.      
  87.     ': Windows libraries : ------------------------------------------------------------------------------------------------
  88.      
  89.     ' Windows system sounds
  90.     ' Code contributed by QB64.org Wiki - Author unknown
  91.     ' http://qb64.org/wiki/Windows_Libraries#Windows_Sounds
  92.     ' Note: this Windows library will fail in SDL versions of QB64
  93.     '       change DECLARE LIBRARY to DECLARE DYNAMIC LIBRARY "Wimmm"
  94.     '       to allow this library to work with SDL versions of QB64
  95.      
  96.         FUNCTION PlaySound (pszSound AS STRING, BYVAL hmod AS INTEGER, BYVAL fdwSound AS INTEGER)
  97.     END DECLARE
  98.      
  99.     ': Program procedures: ------------------------------------------------------------------------------------------------
  100.      
  101.     '----------------------------------------------------------------------------------------------------------------------
  102.     SUB ALERT () '                                                                                                  ALERT()
  103.         '------------------------------------------------------------------------------------------------------------------
  104.      
  105.         ' Plays Windows default sounds
  106.         ' Sounds can be invoked using the following strings:
  107.         ' "SystemDefault","SystemExclamation","SystemExit","SystemHand","SystemQuestion","SystemStart","SystemWelcome"
  108.      
  109.         s = PlaySound("SystemDefault" + CHR$(0), 0, 65537) '                play Windows default system sound
  110.      
  111.     END SUB
  112.      
  113.     '----------------------------------------------------------------------------------------------------------------------
  114.     FUNCTION CLEAN$ (n AS DOUBLE) '                                                                                CLEAN$()
  115.         '------------------------------------------------------------------------------------------------------------------
  116.      
  117.         ' Return number (n) as a string with no leading/trailing spaces
  118.         ' Add leading zero if necessary
  119.      
  120.         DIM c$ ' n converted to a clean string
  121.      
  122.         c$ = LTRIM$(RTRIM$(STR$(n))) '                                      create clean string
  123.         IF ASC(c$, 1) = 46 THEN '                                           first character a decimal point?
  124.             c$ = "0" + c$ '                                                 yes, add leading zero
  125.         ELSEIF ASC(c$, 1) = 45 AND ASC(c$, 2) = 46 THEN '                   no, minus sign then decimal point?
  126.             c$ = "-0" + RIGHT$(c$, LEN(c$) - 1) '                           yes, add leading zero
  127.         END IF
  128.         CLEAN$ = c$ '                                                       return cleaned string
  129.      
  130.      
  131.     '----------------------------------------------------------------------------------------------------------------------
  132.     SUB UPDATEOPERAND (n$) '                                                                                UPDATEOPERAND()
  133.         '------------------------------------------------------------------------------------------------------------------
  134.      
  135.         ' Add user entries to operand
  136.         ' Keep operand to a max length of 16 numbers (not including decimal point)
  137.         ' Reset user operand input as needed
  138.         ' Keep leading zero for decimal values between one and negative one
  139.      
  140.         DIM olen AS INTEGER ' operand length
  141.      
  142.         IF resetoperand THEN '                                              new operand input?
  143.             operand$ = "" '                                                 yes, reset operand
  144.             resetoperand = False '                                          reset trigger
  145.         END IF
  146.         IF n$ = "." THEN '                                                  adding decimal point?
  147.             IF INSTR(operand$, ".") = 0 THEN '                              yes, already a decimal point?
  148.                 IF operand$ = "" THEN '                                     no, has operand been reset?
  149.                     n$ = "0." '                                             yes, add leading zero
  150.                 END IF
  151.             ELSE '                                                          yes, decimal point exists
  152.                 n$ = "" '                                                   ignore user request for decimal point
  153.             END IF
  154.         END IF
  155.         operand$ = operand$ + n$ '                                          update operand with user entry
  156.         olen = LEN(operand$) '                                              get length of operand
  157.         IF INSTR(operand$, ".") > 0 THEN olen = olen - 1 '                  don't count decimal point if preset
  158.         IF olen > 16 THEN operand$ = LEFT$(operand$, LEN(operand$) - 1) '   keep operand within 16 number limit
  159.      
  160.     END SUB
  161.      
  162.     '----------------------------------------------------------------------------------------------------------------------
  163.     SUB CALCULATE () '                                                                                          CALCULATE()
  164.         '------------------------------------------------------------------------------------------------------------------
  165.      
  166.         ' Calculate operand values based on operator previously used
  167.         ' Store result back into current operand
  168.      
  169.         SELECT CASE previousoperator '                                      which operator to use?
  170.             CASE ADDITION '                                                 add the operands
  171.             &