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.


Topics - SMcNeill

Pages: 1 ... 14 15 [16]
226
Programs / PNG chunk information
« on: September 09, 2018, 02:05:02 pm »
Since TerryRichie was asking how to get the background color from a PNG file, I thought I'd go ahead and take a few moments to write up a program to do that for us:

Code: QB64: [Select]
  1. DIM DataLength AS _UNSIGNED LONG
  2. DIM code AS STRING * 4
  3. f$ = "e1.png"
  4.  
  5.     GET #1, , DataLength
  6.     DataLength = ConvertUL(DataLength)
  7.     PRINT DataLength,
  8.     GET #1, , code
  9.     PRINT code
  10.     IF code = "bKGD" THEN 'we found the background color
  11.         junk$ = " "
  12.         GET #1, , red
  13.         GET #1, , junk$ 'PNG stores the data as 2 bytes, so we need to read an extra character to move file pointer
  14.         GET #1, , blue
  15.         GET #1, , junk$ 'same as before
  16.         GET #1, , green
  17.         GET #1, , junk$ 'same as before
  18.         PRINT "BACKGROUND: "; red, blue, green
  19.         junk$ = "    " 'the CRC check, which we don't really care about, but we need to advance the file pointer to the next chunk
  20.         GET #1, , junk$
  21.     ELSE
  22.         junk$ = SPACE$(DataLength + 4)
  23.         GET #1, , junk$
  24.     END IF
  25.     SLEEP
  26. LOOP UNTIL code$ = "IEND"
  27.  
  28. FUNCTION ConvertUL~& (x AS _UNSIGNED LONG)
  29.     ConvertUL = x \ 2 ^ 24 OR x * 2 ^ 24 OR (x AND &HFF0000) \ 2 ^ 8 OR (x AND &HFF00~&) * 2 ^ 8
  30.  

Test image is below, which has a yellow background set as found here: http://www.schaik.com/pngsuite/pngsuite_bck_png.html

227
Programs / Game Maker 64 (GM64)
« on: August 25, 2018, 02:27:50 am »
After all this talk about map editing, map making, and such, I've finally decided to toss my hat into the ring and start working on a passable Game Map making program.

Attached is the start to my effort, but it should illustrate the interface and how things are going to work and interact for us, as development continues.  Feel free to take a look at it, and tell me if it seems intuitive enough to work with, and feel free to offer suggestions as to what features you'd like to see it support as development progresses.  ;)

(GM64.BAS is the file you'd want to compile and run, to test everything out.)

228
QB64 Discussion / Occassional Graphical Glitch
« on: August 24, 2018, 09:13:46 pm »
With all this discussion about map making and map editors, I thought I'd sit down and take a little time to write up a little map engine/maker, but from testing it as I get it started, I'm coming across a rather odd graphical glitch.

Graphics are set for 1024x800, 32-bit resolution, and $RESIZE is set to allow the user to STRETCH the screen if they so desire...

Normally, everything compiles and runs exactly as one would expect...

However, about once every 10th compile, the screen starts at a 640x480 resolution, much like we'd expect a SCREEN 0 screen to appear -- though it's still in 32-bit color mode and everything still runs as expected.

It seems as if there's a race condition occurring somewhere, which is affecting the $RESIZE, which "stretches" the screen to an undesirable size at startup...

My question:  Has anyone else experienced this in any other programs?  Can anyone else reproduce this issue?   This is a behavior I've never seen before, and it's an issue that's intermittent -- though annoying -- and I'm wondering if anyone has any ideas where to start to debug it (or just work around the issue temporarily, so it doesn't keep popping up as I run/test this work-in-progress).

229
QB64 Discussion / Re: From strange to weird
« on: July 25, 2018, 10:27:29 pm »
Note: This message is awaiting approval by a moderator.
Sounds like an issue others have reported in the past with their antivirus deleting or quarantining the newly compiled executable seconds after its compiled.

Quick test:  Completely disable anti-virus and try again.  See what happens.

If things work as expected, then you'll need to whitelist QB64 and its folder so your AV doesn't keep interfering with the newly compiled (and unidentified) executables.

230
QB64 Discussion / Why _MEM.OFFSET?
« on: July 22, 2018, 08:33:17 am »
So here's a question:  Why was the Mem commands built to use m.OFFSET as the second parameter?  What's the purpose/reason for it?  Why not have it work inherently behind the scene??

For example, why do we need to _MEMGET m, m.OFFSET + 100, var?  Why wasn't it made to just be _MEMGET m, 100, var?

Think of it in comparison to using GET from a file...   We GET #1, 100, var; we don't need to GET #1, #1.OFFSET + 100, var....

I know _MEM has been around and has been used in too many programs to change its syntax so much now, but is there a reason for m.OFFSET being there that I'm just overlooking?  We're *always* going to reference memory from the start of a memblock, so shouldn't QB64 have just added _MEM.OFFSET to whatever pointer/variable we sent it, behind the scenes, and saved the programmer from ever having to type it out or worry about it??

I'm just curious if anyone knows why it is the way it is, and if there's just an obvious reason for it that I'm overlooking.

231
QB64 Discussion / QB64 x64 (10-17-2018)
« on: July 21, 2018, 02:24:05 pm »
I updated the version of the 64-bit windows copy of QB64 so recent changes, alterations, and additions will work for those who want/need to program in a 64-bit environment with Windows.  Download can be found over here: http://qb64.freeforums.net/thread/100/qb64-x64-07-21-2018



One note to Luke and Felippe, which still requires a manual edit of libqb.cpp before a 64-bit version will build properly:

Code: QB64: [Select]
  1. int32 func__handle(){
  2.     #ifdef QB64_GUI
  3.         #ifdef QB64_WINDOWS
  4.             while (!window_handle){Sleep(100);}
  5.             return (int32)window_handle;
  6.         #endif
  7.     #endif
  8.    
  9.     return 0;
  10. }

The above will error and crap out on compilation for us, and the reason is simple -- you can't return a 64-bit window handle to a 32-bit integer.  At least, not if you want it to work right at all.  ;)

Change is simple and doesn't affect the 32-bit version at all -- simply return an integer based on the pointersize, as below:

Code: QB64: [Select]
  1. int32 func__handle(){
  2.     #ifdef QB64_GUI
  3.         #ifdef QB64_WINDOWS
  4.             while (!window_handle){Sleep(100);}
  5.             return (ptrszint)window_handle;
  6.         #endif
  7.     #endif
  8.    
  9.     return 0;
  10. }

If one of you could make and push the simple change into the repo with your next edit, all that's needed from this point forward is to swap out the 32-bit c-compiler for a 64-bit c-compiler and then run setup_win.bat, to build the 64-bit version whenever someone wants/needs to update it in the future.  ;)

232
QB64 Discussion / ColorAll Library
« on: July 20, 2018, 03:32:59 pm »
I know a lot of folks have enjoyed my color name library for 32-bit colors, so sometime back, I decided to expand the library so that the color names could be used in any screen mode for us, as I'll illustrate below and in the next few posts.

First thing to do, grab the two library files below and put them in your QB64 library.

Next, be aware that the library now makes use of QB64's precompiler, so you'll need to set a precompiler value to tell it which screen mode your program is going to be working with.  The variable for this is simply called KOLOR.

   So, for a text screen (SCREEN 0) program, all you'd need to do is basically set KOLOR to 0 (to indicate it's going to be SCREEN 0 text graphics), and then include the ColorAll.BI at the top of your program, and then you can use the color names instead of the numbers for your program -- as indicated below.

Code: QB64: [Select]
  1. 'First, set the KOLOR value to tell the precompiler what color scheme we need.
  2.  
  3. $LET KOLOR = 0
  4.  
  5.  
  6. 'Then include the library file.
  7. '$include:'ColorAll.BI'
  8.  
  9.  
  10. 'Then use the names
  11. COLOR White, Yellow
  12. PRINT "White on Yellow"
  13. COLOR Red, Blue
  14. PRINT "Red on Blue"
  15. COLOR BrightWhite, Yellow
  16. PRINT "Bright White on Yellow"
  17. COLOR Blink + BrightWhite, Magenta
  18. PRINT "Blink Bright White on Magenta"
  19.  

Color values can be read by looking at the variables inside ColorAll.BI, but for simplicity's sake, I'll include them here since there's only a few to deal with in text mode:

$IF KOLOR = 0 THEN
    CONST Black = 0~%%
    CONST Blue = 1~%%
    CONST Green = 2~%%
    CONST Cyan = 3~%%
    CONST Red = 4~%%
    CONST Magenta = 5~%%
    CONST Brown = 6~%%
    CONST White = 7~%%
    CONST Gray = 8~%%
    CONST LightBlue = 9~%%
    CONST LightGreen = 10~%%
    CONST LightCyan = 11~%%
    CONST LightRed = 12~%%
    CONST LightMagenta = 13~%%
    CONST Yellow = 14~%%
    CONST BrightWhite = 15~%%
    CONST Blink = 16~%%
$END IF

233
Programs / Math Flash Card Trainer for Children
« on: July 28, 2017, 01:29:30 pm »
Code: QB64: [Select]
  1. TYPE ResultsType
  2.     num1 AS LONG
  3.     op AS LONG
  4.     num2 AS LONG
  5.     num3 AS LONG
  6.     answer AS LONG
  7.     correct AS LONG
  8.  
  9.  
  10. _TITLE "Flash Card Math Trainer"
  11. DEFLNG A-Z
  12. _DELAY 0.5
  13. WS = _NEWIMAGE(1280, 720, 32) 'WorkScreen
  14.  
  15. DIM SHARED WF 'Workfont
  16. WF = _LOADFONT("C:\Windows\Fonts\Cour.ttf", 150)
  17.  
  18.  
  19. DIM SHARED RST 'Result Font
  20. RST = _LOADFONT("C:\Windows\Fonts\Cour.ttf", 50)
  21.  
  22. REDIM SHARED Results(0) AS ResultsType
  23. DIM SHARED GameTime, Difficulty
  24.  
  25. CONST Red = _RGB32(255, 0, 0)
  26. CONST White = _RGB32(255, 255, 255)
  27. CONST Black = _RGB32(0, 0, 0)
  28. CONST Blue = _RGB32(0, 0, 255)
  29. CONST Green = _RGB32(0, 255, 0)
  30. CONST Yellow = _RGB32(255, 255, 0)
  31.  
  32. CONST Plus = 1, Minus = 2, Times = 3, Divide = 4
  33.  
  34.  
  35.  
  36.  
  37.  
  38. ON TIMER(t1, 1) CountDown
  39.  
  40.  
  41.  
  42. MainChoiceScreen mode, Difficulty, length
  43.  
  44. SELECT CASE length 'This is the number of seconds we're going to test ourselves
  45.     CASE 1: GameTime = 15
  46.     CASE 2: GameTime = 30
  47.     CASE 3: GameTime = 60
  48.     CASE 4: GameTime = 120
  49.     CASE 5: GameTime = 300
  50.  
  51. SELECT CASE Difficulty 'This determines how hard the game will be
  52.     CASE 1: LowLimit = 0: HighLimit = 10
  53.     CASE 2: LowLimit = 0: HighLimit = 12
  54.     CASE 3: LowLimit = 0: HighLimit = 99
  55.     CASE 4: LowLimit = 10: HighLimit = 89
  56.  
  57.  
  58. TIMER(t1) ON
  59.  
  60.  
  61.  
  62.     _LIMIT 10
  63.     num1 = RND * HighLimit + LowLimit
  64.  
  65.     SELECT CASE mode 'Only give the user the numbers they wanted to play with
  66.         CASE 1: op = 1
  67.         CASE 2: op = 2
  68.         CASE 3: op = RND + 1
  69.         CASE 4: op = 3
  70.         CASE 5: op = 4
  71.         CASE 6: op = RND + 3
  72.         CASE 7: op = RND: IF op = 0 THEN op = 1 ELSE op = 3
  73.         CASE 8: op = INT(RND * 4) + 1
  74.     END SELECT
  75.  
  76.     num2 = RND * HighLimit + LowLimit
  77.  
  78.     IF op = 4 THEN 'it's divide, let's get the numbers in the proper order
  79.         DO
  80.             num1 = RND * HighLimit + LowLimit
  81.             num2 = RND * HighLimit + LowLimit
  82.             num1 = num1 * num2
  83.         LOOP UNTIL num1 < 100
  84.     END IF
  85.     IF op = 2 AND num1 < num2 THEN SWAP num1, num2
  86.     DrawCard num1, op, num2
  87.     DrawUserClickAreas
  88.     GetUserAnswer answer$
  89.     CheckAnswer num1, op, num2, answer$
  90.     DisplayTime
  91.     _DISPLAY
  92.  
  93.  
  94. SUB MainChoiceScreen (mode, difficulty, length)
  95. _FONT RST
  96. PRINT "Welcome to Math Flash!"
  97. LOCATE 5, 1: PRINT "Your personal math trainer!"
  98. PRINT "What would you like to learn to work with today?"
  99. PRINT "1) Addition"
  100. PRINT "2) Subtraction"
  101. PRINT "3) Addition and Subtraction"
  102. PRINT "4) Multiplication"
  103. PRINT "5) Division"
  104. PRINT "6) Multiplication and Division"
  105. PRINT "7) Addition and Multiplication"
  106. PRINT "8) ALL of them"
  107. PRINT "9) QUIT THE TRAINER"
  108.  
  109.     _LIMIT 10
  110.     a = VAL(INKEY$)
  111. LOOP UNTIL a > 0 AND a < 10
  112. IF a = 9 THEN SYSTEM
  113.  
  114. PRINT "How difficult do you wish for this game to be?"
  115. PRINT "1) Easy"
  116. PRINT "2) Normal"
  117. PRINT "3) Hard"
  118. PRINT "4) Grueling"
  119.     _LIMIT 10
  120.     b = VAL(INKEY$)
  121. LOOP UNTIL b > 0 AND b < 5
  122.  
  123. PRINT "How long a game do you want?"
  124. PRINT "1) Very Short"
  125. PRINT "2) Short"
  126. PRINT "3) Average"
  127. PRINT "4) Long"
  128. PRINT "5) Bring It On, Long!"
  129.  
  130.     c = VAL(INKEY$)
  131. LOOP UNTIL c > 0 AND c < 6
  132.  
  133. _FONT RST
  134. DO: LOOP UNTIL INKEY$ = "" 'Clear the keyboard buffer
  135. PRINT "<LEFT CLICK> TO BEGIN MATH FLASH CARDS!"
  136.     _LIMIT 10
  137.     x = mouseclick
  138. LOOP UNTIL x = 1
  139.  
  140. mode = a: difficulty = b: length = c
  141.  
  142.  
  143.  
  144. SUB DisplayTime
  145. _FONT RST
  146. COLOR White, Black
  147. LOCATE 1, 1000: PRINT GameTime; "LEFT  "
  148.  
  149. SUB CountDown
  150. GameTime = GameTime - 1
  151. IF GameTime <= 0 THEN ShowResults 'Clock has ran out
  152.  
  153.  
  154. SUB ShowResults
  155. Score = 0
  156. CLS , Black
  157. COLOR White, Black
  158. PRINT "YOUR ANSWER"; TAB(40); "CORRECT ANSWER"
  159. FOR i = 1 TO UBOUND(results)
  160.     text$ = Num2Str(Results(i).num1)
  161.     SELECT CASE Results(i).op
  162.         CASE 1: text$ = text$ + " + "
  163.         CASE 2: text$ = text$ + " - "
  164.         CASE 3: text$ = text$ + " * "
  165.         CASE 4: text$ = text$ + " / "
  166.     END SELECT
  167.  
  168.     IF Results(i).correct = -1 THEN
  169.         COLOR Green, Black
  170.         Correct = Correct + 1
  171.         YourText$ = text$ + Num2Str(Results(i).num2) + " = " + Num2Str(Results(i).answer)
  172.     ELSE
  173.         COLOR Red, Black
  174.         Wrong = Wrong + 1
  175.         IF Results(i).correct = 1 THEN
  176.             YourText$ = text$ + Num2Str(Results(i).num2) + " = " + "SKIPPED"
  177.         ELSE
  178.             YourText$ = text$ + Num2Str(Results(i).num2) + " = " + Num2Str(Results(i).answer)
  179.         END IF
  180.     END IF
  181.     CorrectText$ = text$ + Num2Str(Results(i).num2) + " = " + Num2Str(Results(i).num3)
  182.     PRINT YourText$; TAB(40);
  183.     COLOR White, Black
  184.     PRINT CorrectText$
  185. PRINT "You got "; Correct; " correct answers, and "; Wrong; " wrong."
  186. PRINT "If this was a test, you would have scored "; INT(100 * (Correct / (i - 1))); "%"
  187. ScoreMultiplier = 25 * Difficulty
  188. Score = ScoreMultiplier * Correct + ScoreMultiplier * -Wrong
  189. PRINT "YOUR GAME SCORE IS: "; Score
  190. SELECT CASE Difficulty
  191.     CASE 1: file$ = "Easy.txt": diff$ = "EASY"
  192.     CASE 2: file$ = "Average.txt": diff$ = "NORMAL"
  193.     CASE 3: file$ = "Hard.txt": diff$ = "HARD"
  194.     CASE 4: file$ = "Grueling.txt": diff$ = "GRUELING"
  195.     'life should be good as we have an existing file.
  196.     'if not, then let's make a blank highscore file for the proper difficulty.
  197.     OPEN file$ FOR OUTPUT AS #1
  198.     FOR i = 1 TO 25
  199.         PRINT #1, "None"
  200.         PRINT #1, 0
  201.         PRINT #1, "None"
  202.     NEXT
  203.     CLOSE #1
  204. OPEN file$ FOR INPUT AS #1
  205. DIM person(25) AS STRING, score(25), diff$(25)
  206. HS = 0 'no high score until we validate it
  207. FOR i = 1 TO 25
  208.     LINE INPUT #1, person(i)
  209.     INPUT #1, score(i)
  210.     LINE INPUT #1, diff$(i)
  211.     IF Score > score(i) AND NOT HS THEN
  212.         PRINT "CONGRATULATIONS!!  YOU GOT A HIGH SCORE!"
  213.         PRINT "What name would you like to be known by? ";
  214.         INPUT person$
  215.         IF i < 25 THEN person(i + 1) = person(i): score(i + 1) = score(i): diff$(i + 1) = diff$(i)
  216.         person(i) = person$: score(i) = Score: diff$(i) = diff$
  217.         i = i + 1: HS = -1
  218.     END IF
  219.  
  220. PRINT "Press <ANY KEY> to see the "; diff$; " HIGH SCORES"
  221. PRINT diff$; " HIGH SCORERS"
  222. FOR i = 1 TO 25
  223.     PRINT person(i); TAB(20); score(i); TAB(40); diff$(i)
  224.  
  225. OPEN file$ FOR OUTPUT AS #1
  226. FOR i = 1 TO 25
  227.     PRINT #1, person(i)
  228.     PRINT #1, score(i)
  229.     PRINT #1, diff$(i)
  230.  
  231.  
  232. PRINT "Do the test again? (Y/N)"
  233.     _LIMIT 10
  234.     a$ = UCASE$(INKEY$)
  235. LOOP UNTIL a$ = "Y" OR a$ = "N"
  236. IF a$ = "Y" THEN
  237.     SHELL _DONTWAIT "Untitled.exe"
  238.  
  239.  
  240. SUB CheckAnswer (num1, op, num2, answer$)
  241. ans = VAL(answer$)
  242.     CASE Plus: num3 = num1 + num2
  243.     CASE Minus: num3 = num1 - num2
  244.     CASE Times: num3 = num1 * num2
  245.     CASE Divide: num3 = num1 / num2
  246. QuestionsAsked = UBOUND(results) + 1
  247. REDIM _PRESERVE Results(QuestionsAsked) AS ResultsType
  248. Results(QuestionsAsked).num1 = num1
  249. Results(QuestionsAsked).op = op
  250. Results(QuestionsAsked).num2 = num2
  251. Results(QuestionsAsked).num3 = num3
  252. Results(QuestionsAsked).answer = ans
  253.  
  254. _FONT RST
  255. COLOR White, Black
  256. LOCATE 1, 1: PRINT "Last Answer:"
  257. IF ans = num3 AND answer$ <> "" THEN
  258.     Correct = Correct + 1
  259.     GameTime = GameTime + 1 'A bonus to time for each correct answer
  260.     COLOR Green, Black
  261.     LOCATE 1, 400: PRINT "CORRECT!"
  262.     Results(QuestionsAsked).correct = -1
  263.     Wrong = Wrong + 1
  264.     GameTime = GameTime - 2 'A penalty to time for each wrong answer
  265.     COLOR Red, Black
  266.     LOCATE 1, 400: PRINT "WRONG!  "
  267.     Results(QuestionsAsked).correct = 0
  268.     IF answer$ = "" THEN Results(QuestionsAsked).correct = 1
  269. COLOR White, Black
  270. DisplayTime
  271.  
  272.  
  273. SUB DisplayUserAnswer (answer$)
  274. COLOR Black, White
  275. LINE (700, 100)-(1100, 300), White, BF
  276. top = 125
  277. left = (400 - GetPrintWidth(answer$, WF)) / 2 + 700
  278. _PRINTSTRING (left, top), answer$
  279.  
  280.  
  281. SUB GetUserAnswer (answer$)
  282. done = 0: answer$ = ""
  283.     _LIMIT 30
  284.     Button = mouseclick
  285.     IF Button = 1 THEN 'We have a mouse click somewhere
  286.         x = _MOUSEX: y = _MOUSEY
  287.         IF y >= 400 AND y <= 600 THEN 'they clicked down where the numbers and OK button are
  288.             num = 0
  289.             IF x \ 100 = (x + 10) \ 100 THEN num = x \ 100 'they didn't click on the 10 pixel blank space between numbers
  290.             IF num > 0 AND num < 12 THEN 'It's a click on either a number or the OK button on the top row
  291.                 IF num = 10 THEN num = 0
  292.                 IF num = 11 THEN
  293.                     done = -1
  294.                 ELSE
  295.                     answer$ = answer$ + LTRIM$(RTRIM$(STR$(num)))
  296.                 END IF
  297.             END IF
  298.         END IF
  299.         IF y >= 610 AND y <= 710 AND x >= 100 AND x <= 1200 THEN done = -1 'Click on the bottom ENTER area
  300.     END IF
  301.     DisplayUserAnswer answer$
  302.     DisplayTime
  303.     _DISPLAY
  304. LOOP UNTIL done
  305.  
  306.  
  307.  
  308. SUB DrawUserClickAreas
  309. FOR i = 1 TO 10
  310.     left = 100 * i
  311.     LINE (left, 400)-(left + 90, 600), Yellow, BF
  312.     COLOR Black, 0
  313.     _PRINTSTRING (left + 10, 425), Num2Str$(i MOD 10)
  314. LINE (100, 610)-(1200, 710), Green, BF
  315. LINE (1100, 400)-(1200, 710), Green, BF
  316. _PRINTSTRING (425, 595), "ENTER"
  317.  
  318.  
  319.  
  320. SUB DrawCard (num1, operator, num2) 'Pass it our 3 numbers like 3, plus, 3 would be 3 + 3 = ?
  321. COLOR Red, 0
  322. LINE (100, 100)-(650, 300), White, BF
  323. text$ = Num2Str(num1)
  324. SELECT CASE operator
  325.     CASE Plus: text$ = text$ + "+"
  326.     CASE Minus: text$ = text$ + "-"
  327.     CASE Times: text$ = text$ + "*"
  328.     CASE Divide: text$ = text$ + "/"
  329. text$ = text$ + Num2Str(num2) + "="
  330. top = 125
  331. left = (550 - GetPrintWidth(text$, WF)) / 2 + 100
  332. _PRINTSTRING (left, top), text$
  333.  
  334. FUNCTION Num2Str$ (num)
  335. Num2Str$ = LTRIM$(RTRIM$(STR$(num)))
  336.  
  337. FUNCTION GetPrintWidth (text AS STRING, fonthandle)
  338. w = _WIDTH: h = _HEIGHT
  339. d = _DEST: s = _SOURCE
  340. t = _NEWIMAGE(w, h, 32)
  341. _FONT fonthandle
  342. COLOR _RGB32(255, 0, 0), _RGB32(255, 255, 255)
  343. PRINT text;
  344. m = _MEMIMAGE(t)
  345. p = 0 'pointer
  346.     _MEMGET m, m.OFFSET + p, c 'Get our color
  347.     p = p + 4 'increase 4 as we're working with 4-byte long values for RGBA color
  348.     GetPrintWidth = GetPrintWidth + 1
  349. LOOP UNTIL NOT c 'until we don't have no color no more
  350.  
  351. FUNCTION mouseclick%
  352. DO WHILE _MOUSEINPUT 'check mouse status
  353.     scroll% = scroll% + _MOUSEWHEEL ' if scrollwheel changes, watch the change here
  354.     IF _MOUSEBUTTON(1) THEN 'left mouse pushed down
  355.         speedup = 1
  356.     ELSEIF _MOUSEBUTTON(2) THEN 'right mouse pushed down
  357.         speedup = 2
  358.     ELSEIF _MOUSEBUTTON(3) THEN 'middle mouse pushed down
  359.         speedup = 3
  360.     END IF
  361.     IF speedup THEN 'buton was pushed down
  362.         mouseclickxxx1% = _MOUSEX: mouseclickyyy1% = _MOUSEY 'see where button was pushed down at
  363.         DO WHILE _MOUSEBUTTON(speedup) 'while button is down
  364.             i% = _MOUSEINPUT
  365.         LOOP 'finishes when button is let up
  366.         IF mouseclickxxx1% >= _MOUSEX - 2 AND mouseclickxxx1% <= _MOUSEX + 2 AND mouseclickyyy1% >= _MOUSEY - 2 AND mouseclickyyy1% <= _MOUSEY + 2 THEN 'if mouse hasn't moved (ie  clicked down, dragged somewhere, then released)
  367.             mouseclick% = speedup
  368.         ELSE
  369.             mouseclick% = 0
  370.         END IF
  371.     END IF
  372. IF scroll% < 0 THEN mouseclick% = 4
  373. IF scroll% > 0 THEN mouseclick% = 5
  374.  

A simple little game which kids can use to help them learn basic math.  Does addition, subtraction, multiplication, and division. 

Just copy and paste into the QB64 IDE, compile and you're good to go!  :)

234
Programs / SHUFFLE (GL Version)
« on: July 28, 2017, 01:25:03 pm »
The very first thing I ever wrote and shared for [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there] was my little Shuffle Game,back all the way in April 2012.  Since then, it's been downloaded over 240 times!  (WOW!!) 

Only thing ism all those downloads were expecting the user to have the SDL version of QB64 to compile and run the program -- and QB64 swapped over to the GL version several years ago.  Ergo, I now present a freshly patched up, compiled, and tested version which runs on works with QB64-GL!

Enjoy!!

https://www.dropbox.com/s/sfzazmv2qtah9ri/Shuffle%20%28GL%20Version%29.7z?dl=0



Note 1: My connection is too low to upload the file here, so the link above will give you a dropbox version which you can download and play around with instead.

Note 2: Linux/Mac users will need to change the location of the font files to point to where they'd be on their system before compiling.

Note 3: Be certain the EXE is in the main SHUFFLE directory with the BAS file before running.  It needs to be there to find the sound and image files necessary to run properly, without tossing a thousand ERROR messages up on screen.

235
Programs / DBF conversion/use programs
« on: July 28, 2017, 12:18:03 pm »
Two programs here which might be useful for someone who needs to access data from a DBF file for use inside a QB64 program.

First, we have a simple program to change DBF files to CSV (Comma Separated Value) Text files:

Code: QB64: [Select]
  1. 'DBF to CSV text converter
  2.  
  3. 'Program written by Steve McNeill @ 9/19/2012
  4.  
  5. 'Code is free to use, abuse, modify, destroy, steal, copy, share, and alter in any way anyone wishes.
  6. 'Just be aware, I'm not responsible if it melts your computer, fries your brain, or makes you sing like a drunken sailor.
  7. 'Use is purely at your own risk, but it seems safe enough to me!
  8.  
  9. 'All this does is convert old dbf files into a simple CSV text file, which can then be read into any program which you wish to use the data with.
  10. 'Your old files stay as they are, and it does nothing to them except read them and then give you a new, converted file to work with.
  11.  
  12. 'change file$ and file1$ to the name of your DBF and new converted filename, respectively.
  13.  
  14. 'No credit, cash, check, or money order needed for this.  Enjoy!!
  15.  
  16.  
  17. TYPE DBF_Header
  18.     FileType AS _UNSIGNED _BYTE
  19.     Year AS _UNSIGNED _BYTE
  20.     Month AS _UNSIGNED _BYTE
  21.     Day AS _UNSIGNED _BYTE
  22.     RecordNumber AS _UNSIGNED LONG
  23.     FirstRecord AS _UNSIGNED INTEGER
  24.     RecordLength AS _UNSIGNED INTEGER
  25.     ReservedJunk AS STRING * 16
  26.     TableFlag AS _UNSIGNED _BYTE
  27.     CodePageMark AS _UNSIGNED _BYTE
  28.     ReservedJunk1 AS STRING * 2
  29.  
  30. TYPE Field_Subrecord
  31.     FieldName AS STRING * 11
  32.     FieldType AS STRING * 1
  33.     Displacement AS _UNSIGNED LONG
  34.     FieldLength AS _UNSIGNED _BYTE
  35.     FieldDecimal AS _UNSIGNED _BYTE
  36.     FieldFlags AS _UNSIGNED _BYTE
  37.     AutoNext AS _UNSIGNED LONG
  38.     AutoStep AS _UNSIGNED _BYTE
  39.     ReservedJunk AS STRING * 8
  40.  
  41. TYPE DBF_HeaderTerminator
  42.     EndCode AS _UNSIGNED _BYTE 'Our End of Field Code is a CHR$(13), or 13 if we read it as a byte
  43.  
  44. TYPE DBF_VFPInfo
  45.     Info AS STRING * 263
  46.  
  47. DIM DataH AS DBF_Header
  48. DIM DataFS(1) AS Field_Subrecord
  49. DIM DataHT AS DBF_HeaderTerminator
  50. DIM DataVFP AS DBF_VFPInfo
  51.  
  52. file$ = ".\tempdata.dbf"
  53. file2$ = ".\converted.txt"
  54.  
  55. Get_Header file$, DataH
  56. 'Display_Header DataH
  57. Get_Fields file$, DataFS()
  58. 'Display_Fields DataFS()
  59. Print_Data file$, DataH, DataFS(), file2$
  60. PRINT "Your file has been converted."
  61. PRINT "The original file was: "; file$
  62. PRINT "The converted file is: "; file2$
  63.  
  64.  
  65.  
  66. SUB Display_Header (DataH AS DBF_Header)
  67. PRINT "Data File Type: ";
  68. SELECT CASE DataH.FileType
  69.     CASE 2: PRINT "FoxBASE"
  70.     CASE 3: PRINT "FoxBASE+/Dbase III plus, no memo"
  71.     CASE 48: PRINT "Visual FoxPro"
  72.     CASE 49: PRINT "Visual FoxPro, autoincrement enabled"
  73.     CASE 50: PRINT "Visual FoxPro with field type Varchar or Varbinary"
  74.     CASE 67: PRINT "dBASE IV SQL table files, no memo"
  75.     CASE 99: PRINT "dBASE IV SQL system files, no memo"
  76.     CASE 131: PRINT "FoxBASE+/dBASE III PLUS, with memo"
  77.     CASE 139: PRINT "dBASE IV with memo"
  78.     CASE 203: PRINT "dBASE IV SQL table files, with memo"
  79.     CASE 229: PRINT "HiPer-Six format with SMT memo file"
  80.     CASE 245: PRINT "FoxPro 2.x (or earlier) with memo"
  81.     CASE 251: PRINT "FoxBASE"
  82.     CASE ELSE: PRINT "Unknown File Type"
  83. PRINT "Date: "; DataH.Month; "/"; DataH.Day; "/"; DataH.Year
  84. PRINT "Number of Records: "; DataH.RecordNumber
  85. PRINT "First Record: "; DataH.FirstRecord
  86. PRINT "Record Length: "; DataH.RecordLength
  87. PRINT "Reserved Junk: "; DataH.ReservedJunk
  88. PRINT "Table Flags: ";
  89. none = 0
  90. IF DataH.TableFlag AND 1 THEN PRINT "file has a structural .cdx ";: none = -1
  91. IF DataH.TableFlag AND 2 THEN PRINT "file has a Memo field ";: none = -1
  92. IF DataH.TableFlag AND 4 THEN PRINT "file is a database (.dbc) ";: none = -1
  93. IF none THEN PRINT ELSE PRINT "None"
  94. PRINT "Code Page Mark: "; DataH.CodePageMark
  95. PRINT "Reserved Junk: "; DataH.ReservedJunk1
  96.  
  97. SUB Display_Fields (DataH() AS Field_Subrecord)
  98. FOR r = 1 TO UBOUND(DataH)
  99.     PRINT "Field Name :"; DataH(r).FieldName
  100.     PRINT "Field Type :"; DataH(r).FieldType
  101.     PRINT "Field Displacement :"; DataH(r).Displacement
  102.     PRINT "Field Length :"; DataH(r).FieldLength
  103.     PRINT "Field Decimal :"; DataH(r).FieldDecimal
  104.     PRINT "Field Flags :"; DataH(r).FieldFlags
  105.     PRINT "Field AutoNext :"; DataH(r).AutoNext
  106.     PRINT "Field SutoStep :"; DataH(r).AutoStep
  107.     PRINT "Field Reserved Junk :"; DataH(r).ReservedJunk
  108.     SLEEP
  109.     PRINT "**************************"
  110.  
  111. SUB Get_Header (file$, DataH AS DBF_Header)
  112. OPEN file$ FOR BINARY AS #1 LEN = LEN(DataH)
  113. GET #1, 1, DataH
  114.  
  115. SUB Get_Fields (file$, DataH() AS Field_Subrecord)
  116. DIM temp AS Field_Subrecord
  117. OPEN file$ FOR BINARY AS #1 LEN = 1
  118. counter = -1: s = 33
  119.     counter = counter + 1
  120.     GET #1, s, databyte
  121.     s = s + 32
  122. LOOP UNTIL databyte = 13
  123. REDIM DataH(counter) AS Field_Subrecord
  124. IF counter < 1 THEN BEEP: BEEP: PRINT "Database has no file records.": END
  125. OPEN file$ FOR BINARY AS #1 LEN = 32
  126. FOR r = 1 TO counter
  127.     GET #1, 32 * r + 1, DataH(r) 'record 1 is our header info, so we need to start our field info at record 2
  128.  
  129.  
  130. SUB Print_Data (file$, DataH AS DBF_Header, DataFS() AS Field_Subrecord, file2$)
  131. OPEN file$ FOR BINARY AS #1
  132. OPEN file2$ FOR OUTPUT AS #2
  133. SEEK #1, DataH.FirstRecord + 1
  134.     GET #1, , databyte 'This is the first byte which tells us if the record is good, or has been deleted.
  135.     IF databyte = 32 THEN WRITE #2, "Good Record", ELSE WRITE #2, "Deleted Record",
  136.     FOR i = 1 TO UBOUND(DataFS)
  137.         SELECT CASE DataFS(i).FieldType
  138.             CASE "C", "0"
  139.                 'C is for Characters, or basically STRING characters.
  140.                 '0 is for Null Flags, which I have no clue what they're for.  I'm basically reading them here as worthless characters until I learn otherwise.
  141.                 temp$ = ""
  142.                 FOR j = 1 TO DataFS(i).FieldLength
  143.                     GET #1, , databyte
  144.                     temp$ = temp$ + CHR$(databyte)
  145.                 NEXT
  146.             CASE "Y"
  147.                 'Y is for currency, which is an _INTEGER 64, with an implied 4 spaces for decimal built in.
  148.                 REDIM temp AS _INTEGER64
  149.                 GET #1, , temp
  150.                 temp$ = STR$(temp)
  151.                 l = LEN(temp$)
  152.                 temp$ = LEFT$(temp$, l - 4) + "." + RIGHT$(temp$, 4)
  153.             CASE "N", "F", "M", "G"
  154.                 'N is for numberic, F is for Floating numbers, and both seem to work in the same manner.
  155.                 'M is for Memo's, which are stored in a different  DBT file.  What we have here is the block number of the memo location in that file, stored as a simple set of characters.
  156.                 'G is for OLE files.  We store the info for it just the same as we do for a Memo.
  157.                 'we read the whole thing as a string, which is an odd way for dBase to write it, but I don't make the rules.  I just convert them!
  158.                 temp$ = ""
  159.                 FOR j = 1 TO DataFS(i).FieldLength
  160.                     GET #1, , databyte
  161.                     temp$ = temp$ + CHR$(databyte)
  162.                 NEXT
  163.             CASE "D"
  164.                 'D is for Date fields.
  165.                 'Dates are stored as a string, in the format YYYYMMDD
  166.                 temp$ = ""
  167.                 FOR j = 1 TO DataFS(i).FieldLength
  168.                     GET #1, , databyte
  169.                     temp$ = temp$ + CHR$(databyte)
  170.                 NEXT
  171.                 year$ = LEFT$(temp$, 4)
  172.                 month$ = MID$(temp$, 5, 2)
  173.                 day$ = RIGHT$(temp$, 2)
  174.                 temp$ = day$ + "/" + month$ + "/" + year$
  175.             CASE "L"
  176.                 'L is our logical operator.  Basically, it's simply True or False Boolean logic
  177.                 GET #1, , databyte
  178.                 IF databyte = 32 THEN temp$ = "True" ELSE temp$ = "false"
  179.             CASE "@", "O"
  180.                 '@ are Timestamps, which I'm too lazy to fully support at the moment.
  181.                 'They are 8 bytes - two longs, first for date, second for time.
  182.                 'The date is the number of days since  01/01/4713 BC.
  183.                 'Time is hours * 3600000L + minutes * 60000L + Seconds * 1000L
  184.                 'All I'm going to do is read both longs as a single _Integer64 and then write that data to the disk.
  185.                 'Be certain to convert it as needed to make use of the Timestamp.
  186.                 'I'm just lazy and don't wanna convert anything right now!  :P
  187.  
  188.                 'O are double long integers -- basically Integer 64s.  Since I'm reading a timestamp as an Int64, this routine works for them as well.
  189.                 REDIM temp1 AS _INTEGER64
  190.                 GET #1, , temp1
  191.                 temp$ = STR$(temp1)
  192.             CASE "I", "+"
  193.                 'Long Integers.  Basically 4 byte numbers
  194.                 '+ are auto-increments.  Stored the same way as a Long.
  195.                 REDIM temp2 AS LONG
  196.                 GET #1, , temp2
  197.                 temp$ = STR$(temp2)
  198.         END SELECT
  199.         IF i = UBOUND(datafs) THEN WRITE #2, temp$ ELSE WRITE #2, temp$,
  200.     NEXT

Useage here is simple:
1) Download the file below and put it in your QB64 folder
2) copy and paste the code above into your QB64 IDE.
3) compile and run
4) Enjoy looking at the "converted.txt" file which we created in that same folder, which now has all the DATA in that DBF file converted over to CSV TXT for ease of use in QB64 (or any other program which you might need it for).

236
Programs / Epub book creation program
« on: July 28, 2017, 11:59:48 am »
A demo of something a little different from most of the things other people like to post, this one is an illustration of using QB64 to create an EPUB-formatted ebook.

Code: QB64: [Select]
  1. DIM SHARED Id$ 'The unique identifier used for our book, to be created automagically.
  2.  
  3.  
  4. _TITLE "Epub Creation Demo"
  5. 'We'll need some content to use for our book.
  6. 'For this, we're going to store some information in a few diffent arrays.
  7. 'The first array will be for the Chapters (or Pages) for the book.
  8. 'the next array will be for the information in those chapters.
  9. 'I'm making these redimable at this point so that someone could alter them to suit their needs as required.
  10. REDIM SHARED Chapters(0) AS STRING
  11. REDIM SHARED Content(0) AS STRING
  12. 'Now, let's toss some actual information into these Chapters.
  13. REDIM Chapters(2) AS STRING 'a good number for a demo
  14. 'This information just names our chapters and helps set the order by which we'd go to them.
  15. Chapters(0) = "Title Page"
  16. Chapters(1) = "Chapter One"
  17. Chapters(2) = "Chapter Two"
  18.  
  19. 'And since we have a the chapters, let's toss something in them so they're not just blank...
  20. REDIM Content(2) AS STRING
  21. Content(0) = "Steve's Epub Demo Book!"
  22. Content(1) = "This is the Steve Demo for Epub creation!"
  23. Content(2) = "If you study it carefully, you'll see that it's not actually that hard to create or use EPUB files." + CHR$(13) + CHR$(10) + "This page is a quick demo of how we'd write more than a single line onto a page, and this is also quite a long line of text itself so that it will hopefully auto-wrap and auto-format itself to illustrate that we don't usually have to worry about such things manually -- that should be the job of our E-reader!"
  24.  
  25.  
  26. 'Some optional content we can toss into our book if we want.
  27. 'I'm going to include it here, but it can be stripped out if wanted.
  28. DIM SHARED Author$: Author$ = "Steve McNeill"
  29. DIM SHARED Language$: Language$ = "en"
  30. DIM SHARED Rights$: Rights$ = "Public Domain"
  31. DIM SHARED Publisher$: Publisher$ = "Nobody, Nowhere"
  32.  
  33.  
  34. 'So now we can actually make the book
  35.  
  36. MakeEpub "Steve Book" 'notice I didn't actually add the .epub extension here.  We just need the book title
  37.  
  38.  
  39.  
  40. SUB MakeEpub (book$)
  41. 'First we check to make the main folders for our book
  42. 'and the basic files which define our folder structure
  43. result = MakeFolders(book$)
  44. IF result = 0 THEN EXIT SUB
  45. 'then we have to create our  content file
  46. MakeContent book$
  47. MakeToC book$
  48. MakeXPGT book$
  49. MakeCSS book$
  50. MakeChapters book$
  51.  
  52.  
  53. SUB MakeChapters (book$)
  54. 'And here we write our actual content to our files.
  55. FOR i = 0 TO UBOUND(chapters)
  56.     OPEN book$ + "\OEBPS\Text\" + Chapters(i) + ".xhtml" FOR OUTPUT AS #1
  57.     PRINT #1, "<?xml version="; CHR$(34); "1.0"; CHR$(34); " encoding="; CHR$(34); "utf-8"; CHR$(34); "?>"
  58.     PRINT #1, "<!DOCTYPE html PUBLIC "; CHR$(34); "-//W3C//DTD XHTML 1.1//EN"; CHR$(34); ""
  59.     PRINT #1, "  "; CHR$(34); "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"; CHR$(34); ">"
  60.     PRINT #1, ""
  61.     PRINT #1, "<html xmlns="; CHR$(34); "http://www.w3.org/1999/xhtml"; CHR$(34); ">"
  62.     PRINT #1, "<head>"
  63.     PRINT #1, "  <title>Chapter 1</title>"
  64.     PRINT #1, "  <link rel="; CHR$(34); "stylesheet"; CHR$(34); " href="; CHR$(34); "../Styles/stylesheet.css"; CHR$(34); " type="; CHR$(34); "text/css"; CHR$(34); " />"
  65.     PRINT #1, "  <link rel="; CHR$(34); "stylesheet"; CHR$(34); " type="; CHR$(34); "application/vnd.adobe-page-template+xml"; CHR$(34); " href="; CHR$(34); "../Styles/page-template.xpgt"; CHR$(34); " />"
  66.     PRINT #1, "</head>"
  67.     PRINT #1, ""
  68.     PRINT #1, "<body>"
  69.     PRINT #1, ""
  70.     PRINT #1, "  <div>"
  71.     PRINT #1, "    <h3 id="; CHR$(34); "heading_id_2"; CHR$(34); ">"; Chapters(i); "</h3>"
  72.     PRINT #1, ""
  73.     PRINT #1, "    <p>"; Content(i); "</p>"
  74.     PRINT #1, "  </div>"
  75.     PRINT #1, "</body>"
  76.     PRINT #1, "</html>"
  77.     CLOSE #1
  78.  
  79.  
  80.  
  81. SUB MakeCSS (book$)
  82. 'Nothing more than a style sheet to format our pages and such.
  83. 'I'm just going to make this one about as simple as we can and center our stuff on the page.
  84. OPEN book$ + "\OEBPS\Styles\stylesheet.css" FOR OUTPUT AS #1
  85. PRINT #1, "/* Style Sheet */"
  86. PRINT #1, "/* This defines styles and classes used in the book */"
  87. PRINT #1, "body { margin-left: 5%; margin-right: 5%; margin-top: 5%; margin-bottom: 5%; text-align: justify; }"
  88. PRINT #1, "pre { font-size: x-small; }"
  89. PRINT #1, "h1 { text-align: center; }"
  90. PRINT #1, "h2 { text-align: center; }"
  91. PRINT #1, "h3 { text-align: center; }"
  92. PRINT #1, "h4 { text-align: center; }"
  93. PRINT #1, "h5 { text-align: center; }"
  94. PRINT #1, "h6 { text-align: center; }"
  95. PRINT #1, ".CI {"
  96. PRINT #1, "    text-align:center;"
  97. PRINT #1, "    margin-top:0px;"
  98. PRINT #1, "    margin-bottom:0px;"
  99. PRINT #1, "    padding:0px;"
  100. PRINT #1, "    }"
  101. PRINT #1, ".center   {text-align: center;}"
  102. PRINT #1, ".smcap    {font-variant: small-caps;}"
  103. PRINT #1, ".u        {text-decoration: underline;}"
  104. PRINT #1, ".bold     {font-weight: bold;}"
  105.  
  106. SUB MakeXPGT (book$)
  107. 'page-template.xpgt
  108. 'This file isn't part of the IDPF spec, but Adobe Digital Editions uses it for formatting
  109. 'and setting column settings and whatnot.
  110. 'You don't need this file at all, but your book will look nicer in Digital Editions if you include it.
  111. 'Other readers should just ignore it.
  112. OPEN book$ + "\OEBPS\Styles\page-template.xpgt" FOR OUTPUT AS #1
  113. PRINT #1, "<ade:template xmlns="; CHR$(34); "http://www.w3.org/1999/xhtml"; CHR$(34); " xmlns:ade="; CHR$(34); "http://ns.adobe.com/2006/ade"; CHR$(34); ""
  114. PRINT #1, "         xmlns:fo="; CHR$(34); "http://www.w3.org/1999/XSL/Format"; CHR$(34); ">"
  115. PRINT #1, ""
  116. PRINT #1, "  <fo:layout-master-set>"
  117. PRINT #1, "   <fo:simple-page-master master-name="; CHR$(34); "single_column"; CHR$(34); ">"
  118. PRINT #1, "        <fo:region-body margin-bottom="; CHR$(34); "3pt"; CHR$(34); " margin-top="; CHR$(34); "0.5em"; CHR$(34); " margin-left="; CHR$(34); "3pt"; CHR$(34); " margin-right="; CHR$(34); "3pt"; CHR$(34); "/>"
  119. PRINT #1, "    </fo:simple-page-master>"
  120. PRINT #1, ""
  121. PRINT #1, "    <fo:simple-page-master master-name="; CHR$(34); "single_column_head"; CHR$(34); ">"
  122. PRINT #1, "        <fo:region-before extent="; CHR$(34); "8.3em"; CHR$(34); "/>"
  123. PRINT #1, "        <fo:region-body margin-bottom="; CHR$(34); "3pt"; CHR$(34); " margin-top="; CHR$(34); "6em"; CHR$(34); " margin-left="; CHR$(34); "3pt"; CHR$(34); " margin-right="; CHR$(34); "3pt"; CHR$(34); "/>"
  124. PRINT #1, "    </fo:simple-page-master>"
  125. PRINT #1, ""
  126. PRINT #1, "    <fo:simple-page-master master-name="; CHR$(34); "two_column"; CHR$(34); " margin-bottom="; CHR$(34); "0.5em"; CHR$(34); " margin-top="; CHR$(34); "0.5em"; CHR$(34); " margin-left="; CHR$(34); "0.5em"; CHR$(34); " margin-right="; CHR$(34); "0.5em"; CHR$(34); ">"
  127. PRINT #1, "        <fo:region-body column-count="; CHR$(34); "2"; CHR$(34); " column-gap="; CHR$(34); "10pt"; CHR$(34); "/>"
  128. PRINT #1, "    </fo:simple-page-master>"
  129. PRINT #1, ""
  130. PRINT #1, "    <fo:simple-page-master master-name="; CHR$(34); "two_column_head"; CHR$(34); " margin-bottom="; CHR$(34); "0.5em"; CHR$(34); " margin-left="; CHR$(34); "0.5em"; CHR$(34); " margin-right="; CHR$(34); "0.5em"; CHR$(34); ">"
  131. PRINT #1, "        <fo:region-before extent="; CHR$(34); "8.3em"; CHR$(34); "/>"
  132. PRINT #1, "        <fo:region-body column-count="; CHR$(34); "2"; CHR$(34); " margin-top="; CHR$(34); "6em"; CHR$(34); " column-gap="; CHR$(34); "10pt"; CHR$(34); "/>"
  133. PRINT #1, "    </fo:simple-page-master>"
  134. PRINT #1, ""
  135. PRINT #1, "    <fo:simple-page-master master-name="; CHR$(34); "three_column"; CHR$(34); " margin-bottom="; CHR$(34); "0.5em"; CHR$(34); " margin-top="; CHR$(34); "0.5em"; CHR$(34); " margin-left="; CHR$(34); "0.5em"; CHR$(34); " margin-right="; CHR$(34); "0.5em"; CHR$(34); ">"
  136. PRINT #1, "        <fo:region-body column-count="; CHR$(34); "3"; CHR$(34); " column-gap="; CHR$(34); "10pt"; CHR$(34); "/>"
  137. PRINT #1, "    </fo:simple-page-master>"
  138. PRINT #1, ""
  139. PRINT #1, "    <fo:simple-page-master master-name="; CHR$(34); "three_column_head"; CHR$(34); " margin-bottom="; CHR$(34); "0.5em"; CHR$(34); " margin-top="; CHR$(34); "0.5em"; CHR$(34); " margin-left="; CHR$(34); "0.5em"; CHR$(34); " margin-right="; CHR$(34); "0.5em"; CHR$(34); ">"
  140. PRINT #1, "        <fo:region-before extent="; CHR$(34); "8.3em"; CHR$(34); "/>"
  141. PRINT #1, "        <fo:region-body column-count="; CHR$(34); "3"; CHR$(34); " margin-top="; CHR$(34); "6em"; CHR$(34); " column-gap="; CHR$(34); "10pt"; CHR$(34); "/>"
  142. PRINT #1, "    </fo:simple-page-master>"
  143. PRINT #1, ""
  144. PRINT #1, "    <fo:page-sequence-master>"
  145. PRINT #1, "        <fo:repeatable-page-master-alternatives>"
  146. PRINT #1, "            <fo:conditional-page-master-reference master-reference="; CHR$(34); "three_column_head"; CHR$(34); " page-position="; CHR$(34); "first"; CHR$(34); " ade:min-page-width="; CHR$(34); "80em"; CHR$(34); "/>"
  147. PRINT #1, "            <fo:conditional-page-master-reference master-reference="; CHR$(34); "three_column"; CHR$(34); " ade:min-page-width="; CHR$(34); "80em"; CHR$(34); "/>"
  148. PRINT #1, "            <fo:conditional-page-master-reference master-reference="; CHR$(34); "two_column_head"; CHR$(34); " page-position="; CHR$(34); "first"; CHR$(34); " ade:min-page-width="; CHR$(34); "50em"; CHR$(34); "/>"
  149. PRINT #1, "            <fo:conditional-page-master-reference master-reference="; CHR$(34); "two_column"; CHR$(34); " ade:min-page-width="; CHR$(34); "50em"; CHR$(34); "/>"
  150. PRINT #1, "            <fo:conditional-page-master-reference master-reference="; CHR$(34); "single_column_head"; CHR$(34); " page-position="; CHR$(34); "first"; CHR$(34); " />"
  151. PRINT #1, "            <fo:conditional-page-master-reference master-reference="; CHR$(34); "single_column"; CHR$(34); "/>"
  152. PRINT #1, "        </fo:repeatable-page-master-alternatives>"
  153. PRINT #1, "    </fo:page-sequence-master>"
  154. PRINT #1, ""
  155. PRINT #1, "  </fo:layout-master-set>"
  156. PRINT #1, ""
  157. PRINT #1, "  <ade:style>"
  158. PRINT #1, "    <ade:styling-rule selector="; CHR$(34); ".title_box"; CHR$(34); " display="; CHR$(34); "adobe-other-region"; CHR$(34); " adobe-region="; CHR$(34); "xsl-region-before"; CHR$(34); "/>"
  159. PRINT #1, "  </ade:style>"
  160. PRINT #1, ""
  161. PRINT #1, "</ade:template>"
  162.  
  163.  
  164.  
  165. SUB MakeToC (book$)
  166. 'this is the table of Contents for our book.
  167. 'Note that not all e-readers will use (or even look for) this file.
  168. 'For those that do, it makes us a nice little table of contents at the front of our book
  169. 'for ease of navigation and jumping to different chapters.
  170. OPEN book$ + "\OEBPS\toc.ncx" FOR OUTPUT AS #1
  171.  
  172. PRINT #1, "<?xml version="; CHR$(34); "1.0"; CHR$(34); " encoding="; CHR$(34); "UTF-8"; CHR$(34); "?>"
  173. PRINT #1, "<ncx xmlns="; CHR$(34); "http://www.daisy.org/z3986/2005/ncx/"; CHR$(34); " version="; CHR$(34); "2005-1"; CHR$(34); ">"
  174. PRINT #1, ""
  175. PRINT #1, "<head>"
  176. PRINT #1, "    <meta name="; CHR$(34); "dtb:uid"; CHR$(34); " content="; CHR$(34); Id$; CHR$(34); "/>"
  177. PRINT #1, "    <meta name="; CHR$(34); "dtb:depth"; CHR$(34); " content="; CHR$(34); LTRIM$(STR$(UBOUND(chapters) + 1)); CHR$(34); "/>"
  178. PRINT #1, "    <meta name="; CHR$(34); "dtb:totalPageCount"; CHR$(34); " content="; CHR$(34); "0"; CHR$(34); "/>"
  179. PRINT #1, "    <meta name="; CHR$(34); "dtb:maxPageNumber"; CHR$(34); " content="; CHR$(34); "0"; CHR$(34); "/>"
  180. PRINT #1, "</head>"
  181. PRINT #1, ""
  182. PRINT #1, "<docTitle>"
  183. PRINT #1, "    <text>"; book$; "</text>"
  184. PRINT #1, "</docTitle>"
  185. PRINT #1, ""
  186. PRINT #1, "<navMap>"
  187. FOR i = 0 TO UBOUND(chapters)
  188.     PRINT #1, "    <navPoint id="; CHR$(34); "navPoint-"; LTRIM$(STR$(i + 1)); CHR$(34); " playOrder="; CHR$(34); LTRIM$(STR$(i + 1)); CHR$(34); ">"
  189.     PRINT #1, "        <navLabel>"
  190.     PRINT #1, "            <text>"; Chapters(i); "</text>"
  191.     PRINT #1, "        </navLabel>"
  192.     PRINT #1, "        <content src="; CHR$(34); "Text/"; Chapters(i); ".xhtml"; CHR$(34); "/>"
  193.     PRINT #1, "    </navPoint>"
  194. PRINT #1, "</navMap>"
  195. PRINT #1, "</ncx>"
  196.  
  197.  
  198. SUB MakeContent (book$)
  199. 'This file gives a list of all files in the .epub container, defines the order of files,
  200. 'and stores meta data (author, genre, publisher, etc.) information.
  201. OPEN book$ + "\OEBPS\content.opf" FOR OUTPUT AS #1
  202. PRINT #1, "<?xml version="; CHR$(34); "1.0"; CHR$(34); " encoding="; CHR$(34); "UTF-8"; CHR$(34); "?>"
  203. PRINT #1, "<package xmlns="; CHR$(34); "http://www.idpf.org/2007/opf"; CHR$(34); " unique-identifier="; CHR$(34); "BookID"; CHR$(34); " version="; CHR$(34); "2.0"; CHR$(34); " >"
  204. PRINT #1, "    <metadata xmlns:dc="; CHR$(34); "http://purl.org/dc/elements/1.1/"; CHR$(34); " xmlns:opf="; CHR$(34); "http://www.idpf.org/2007/opf"; CHR$(34); ">"
  205. PRINT #1, "        <dc:title>"; book$; "</dc:title>"
  206. PRINT #1, "        <dc:language>"; Language$; "</dc:language>"
  207. 'PRINT #1, "        <dc:rights>"; Rights$; "</dc:rights>"
  208. 'PRINT #1, "        <dc:creator opf:role="; CHR$(34); "aut"; CHR$(34); ">"; Author$; "</dc:creator>"
  209. 'PRINT #1, "        <dc:publisher>"; Publisher$; "</dc:publisher>"
  210. 'Now for the next part here, each book needs to have an unique identifier.
  211. 'To keep this simple, I'm going to name these books after QB64 with a date and time included
  212. Id$ = "QB64Ebook" + DATE$ + LTRIM$(STR$(TIMER))
  213. PRINT #1, "        <dc:identifier id="; CHR$(34); "BookID"; CHR$(34); " opf:scheme="; CHR$(34); "UUID"; CHR$(34); ">"; Id$; "</dc:identifier>"
  214. PRINT #1, "    </metadata>"
  215.  
  216. 'Next comes the manifest. This is just a listing of the files in the .epub container, and their file type.
  217. 'Each item is also assigned an item ID that's used in the spine section of content.opf.
  218. 'This list does not have to be in any particular order.
  219. '(But you'll be happier if it is.)
  220. 'Also, see the section below on the NCX file for more information on the id attribute.
  221. PRINT #1, "    <manifest>"
  222. 'And now we identify the types of files which we're using in the book
  223. PRINT #1, "        <item id="; CHR$(34); "ncx"; CHR$(34); " href="; CHR$(34); "toc.ncx"; CHR$(34); " media-type="; CHR$(34); "application/x-dtbncx+xml"; CHR$(34); " />"
  224. PRINT #1, "        <item id="; CHR$(34); "style"; CHR$(34); " href="; CHR$(34); "Styles/stylesheet.css"; CHR$(34); " media-type="; CHR$(34); "text/css"; CHR$(34); " />"
  225. PRINT #1, "        <item id="; CHR$(34); "pagetemplate"; CHR$(34); " href="; CHR$(34); "Styles/page-template.xpgt"; CHR$(34); " media-type="; CHR$(34); "application/vnd.adobe-page-template+xml"; CHR$(34); " />"
  226. FOR i = 0 TO UBOUND(chapters)
  227.     PRINT #1, "        <item id="; CHR$(34); Chapters(i); CHR$(34); " href="; CHR$(34); "Text/"; Chapters(i); ".xhtml"; CHR$(34); " media-type="; CHR$(34); "application/xhtml+xml"; CHR$(34); " />"
  228. 'If we included any images (which should be PNG format and thus not easily exported in QB64-GL edition yet
  229. 'They would basically be included as the following format
  230. '        <item id="imgl" href="images/sample.png" media-type="image/png" />
  231. PRINT #1, "    </manifest>"
  232.  
  233. 'Since we've now identified the page types, let's tell whatever E-Reader we're using
  234. 'the proper order to read the pages/chapters in.
  235. 'The spine section lists the reading order of the contents.
  236. 'The spine doesn't have to list every file in the manifest, just the reading order.
  237. 'For example, if the manifest lists images, they do not have to be listed in the spine, and in fact, can't be.
  238. 'Only content (i.e. the XHTML files) can be listed here.
  239.  
  240.  
  241. PRINT #1, "    <spine toc="; CHR$(34); "ncx"; CHR$(34); ">"
  242. FOR i = 0 TO UBOUND(chapters)
  243.     PRINT #1, "        <itemref idref="; CHR$(34); Chapters(i); CHR$(34); " />"
  244. PRINT #1, "    </spine>"
  245. PRINT #1, "</package>"
  246. 'And at this point we should now have our table of contents and such written so we now know the proper order
  247. 'to read our book in.  ;)
  248.  
  249.  
  250. FUNCTION MakeFolders (mainfolder$)
  251. 'Returns a 0 if we fail, -1 if we succeed.
  252. 'This should create our main folder structure, and write the basic files needed for EPUB support.
  253. 'This will create the mimetype and container.xml files for us since they shouldn't change
  254. 'and are mainly used to help our OS know where and what type of folders we're using for EPUB format.
  255. IF NOT _DIREXISTS(mainfolder$) THEN
  256.     MKDIR mainfolder$
  257.     CHDIR mainfolder$
  258.     MKDIR "META-INF" + "\"
  259.     MKDIR "OEBPS"
  260.     MKDIR "OEBPS\images"
  261.     MKDIR "OEBPS\Styles"
  262.     MKDIR "OEBPS\Text"
  263.     CHDIR "..\"
  264.     PRINT "Warning: Directory already exists.  Using this name will overwrite or alter existing files inside this folder.  Do you wish to proceed? (Y/N)"
  265.     DO
  266.         i$ = UCASE$(INKEY$)
  267.         IF i$ = "N" THEN MakeFolders = 0: EXIT SUB
  268.     LOOP UNTIL i$ = "Y"
  269. p$ = mainfolder$ + "\"
  270. OPEN p$ + "mimetype" FOR OUTPUT AS #1
  271. PRINT #1, "application/epub+zip"
  272. OPEN p$ + "META-INF\container.xml" FOR OUTPUT AS #1
  273. PRINT #1, "<?xml version="; CHR$(34); "1.0"; CHR$(34); "?>"
  274. PRINT #1, "<container version="; CHR$(34); "1.0"; CHR$(34); " xmlns="; CHR$(34); "urn:oasis:names:tc:opendocument:xmlns:container"; CHR$(34); ">"
  275. PRINT #1, "    <rootfiles>"
  276. PRINT #1, "         <rootfile full-path="; CHR$(34); "OEBPS/content.opf"; CHR$(34); " media-type="; CHR$(34); "application/oebps-package+xml"; CHR$(34); "/>"
  277. PRINT #1, "    </rootfiles>"
  278. PRINT #1, "</container>"
  279. MakeFolders = -1
  280.  

Usage here is easy enough:
1) compile and run to create a folder called "Steve Book"
2) use whatever ZIP program you have on your machine to zip that folder up and give it a EPUB extension instead of a ZIP extension.

Note that I didn't bother to even try to have the program do step two for us, as QB64 doesn't come packaged with any sort of specific ZIP compression toolset.  In the SDL version, I would've used zlib1.dll, which comes packaged with SDL for use with PNG files, to handle the process, but the GL version doesn't come prepacked with any compression tools.  Since there's a ton of utilities to zip up files and folders out there (winrar, 7z, winzip, countless others), I'm not going to try and even guess what an user has installed on their machine.

EPUB files are just glorified ZIP files with a different extension to them (Don't believe it?  Just rename a few sometime and then look at their contents.), so this program simply makes all the necessary files for an EPUB format ebook and leaves it up to the end-user to finish the process by compressing and renaming the ZIP to EPUB for themselves. 

Try it out, have fun, and let me know if you have any questions about any part of the process.

237
Programs / Steve's Poker Playhouse
« on: July 27, 2017, 09:45:51 am »
It's a solo game of poker.  What more could you want?

Extract, compile, run.  ;)

238
Programs / File Listing
« on: July 27, 2017, 09:00:57 am »
Lots of folks like to ask for a way to easily grab the contents of a directory and import a list of the contents of that directory into their programs, so for them, I introduce my little File Grab Library.

Code: QB64: [Select]
  1. '$INCLUDE:'Filegrab.BI'
  2.  
  3. REDIM Results(0) AS STRING
  4. SCREEN _NEWIMAGE(1280, 720, 32)
  5.  
  6. SelectFile _CWD$, "*.*", Results()
  7. FOR i = 1 TO UBOUND(results)
  8.     PRINT Results(i)
  9.  
  10.  
  11. '$INCLUDE:'Filegrab.BM'

As you can see, usage is fairly straight forward.   
Extract to your QB64 folder. 
Include the header. 
Include the footer. 
REDIM an array to hold the results.
Call the routine with SelectFile _CWD$, "*.*", Results(),

SelectFile is the name of the routine. 
First Parameter _CWD$ can be replaced with whatever directory you want the contents of.
Second Parameter "*.*" is the filter of whatever you want for that directory.  Use "*.txt" for a listing of all text files, for example.
Third Parameter Results() is the REDIM array which you use to store the results of the file listing.

Works on Windows, Linux, and Mac.

239
Programs / SaveImage
« on: July 27, 2017, 08:43:57 am »
Since [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there] is down, and nobody knows when it might be back up, I thought I'd take time to post some useful little routines on the forums here so people can find and make use of them. 

First up is my SaveImage library.

Inside is a couple of quick demos which illustrate how to save a QB64 screen image in either BMP or PNG format, how one can easily turn a text screen into a 256 color graphic screen with one simple command, and how to compress and inflate strings or programs quickly and easily. 

Commands should be simple enough that everyone can figure them out without any real effort involved.

To Deflate/Inflate a string/file:
Code: QB64: [Select]
  1. '$include:'saveimage.bi'
  2. text$ = "Whatever the heck it is that we might want to compress, be that a long string of input, a binary file (just load the whole file into a single string and then deflate it), or whatever else is wanted)."
  3. de$ = Deflate(text$) ' <-- This is how simple it is to deflate the string
  4. t$ = Inflate(de$) '  <-- This is how simple it is to inflate that deflated string
  5. '$include:'saveimage.bm'

To turn a text screen into a graphic screen:
Code: QB64: [Select]
  1. '$include:'saveimage.bi'
  2. PRINT "Hello World.  This is a SCREEN 0 screen which I'm printing on."
  3. x = TextScreenToImage256(0) 'And a quick example of how to turn a text screen into a 256 color image screen
  4. SCREEN x 'swap screens
  5. CIRCLE (320, 240), 100, 40 'And draw a circle on it
  6. LOCATE 2,1: PRINT "And now it's been converted to a 256 color graphical screen.  See the circle on it??"
  7. '$include:'saveimage.bm'
  8.  

To save an image (from any QB64 screen mode -- even SCREEN 0 text screens work!):
Code: QB64: [Select]
  1. '$Include:'SaveImage.BI'
  2. SCREEN _NEWIMAGE(1280, 720, 32)
  3. InitialImage$ = "Volcano Logo.jpg"
  4. exportimage1$ = "testimage.png"
  5. exportimage2$ = "testimage.bmp"
  6.  
  7.  
  8. l& = _LOADIMAGE(InitialImage$)
  9. _PUTIMAGE , l& 'And this line
  10.  
  11. Result = SaveImage(exportimage1$, 0, 0, 0, _WIDTH, _HEIGHT)
  12. IF Result = 1 THEN 'file already found on drive
  13.     KILL exportimage1$ 'delete the old file
  14.     Result = SaveImage(exportimage1$, 0, 0, 0, _WIDTH, _HEIGHT) 'save the new one again
  15. PRINT Result
  16. PRINT "Our initial Image"
  17. IF Result < 0 THEN PRINT "Successful PNG export" ELSE PRINT "PNG Export failed.": ' END
  18.  
  19.  
  20.  
  21. Result = SaveImage(exportimage2$, 0, 0, 0, _WIDTH, _HEIGHT)
  22. IF Result = 1 THEN 'file already found on drive
  23.     KILL exportimage2$ 'delete the old file
  24.     Result = SaveImage(exportimage2$, 0, 0, 0, _WIDTH, _HEIGHT) 'save the new one again
  25. PRINT Result
  26. PRINT "Our initial Image"
  27. IF Result < 0 THEN PRINT "Successful BMP export" ELSE PRINT "BMP Export failed.": END
  28.  
  29.  
  30.  
  31.  
  32.  
  33. zz& = _LOADIMAGE(exportimage1$, 32) 'Even though we saved them in 256 color mode, we currently have to force load them as 32 bit images as _LOADIMAGE doesn't support 256 color pictures yet
  34. IF zz& <> -1 THEN
  35.     SCREEN zz&
  36.     PRINT "Image Handle: "; zz&, exportimage1$
  37.     PRINT "Successful Import using _LOADIMAGE"
  38.     PRINT "ERROR - Not Loading the new image with _LOADIMAGE."
  39.  
  40.  
  41.  
  42. zz& = _LOADIMAGE(exportimage1$, 32) 'Even though we saved them in 256 color mode, we currently have to force load them as 32 bit images as _LOADIMAGE doesn't support 256 color pictures yet
  43. IF zz& <> -1 THEN
  44.     SCREEN zz&
  45.     PRINT "Image Handle: "; zz&, exportimage2$
  46.     PRINT "Successful Import using _LOADIMAGE"
  47.     PRINT "ERROR - Not Loading the new image with _LOADIMAGE."
  48.  
  49.  
  50.  
  51.  
  52. '$INCLUDE:'SaveImage.BM'

Pages: 1 ... 14 15 [16]