Welcome, Guest
You have to register before you can post on our site.

Username/Email:
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 485
» Latest member: zenevan
» Forum threads: 2,804
» Forum posts: 26,385

Full Statistics

Latest Threads
Prime Number Generator
Forum: Programs
Last Post: eoredson
5 hours ago
» Replies: 1
» Views: 27
DeflatePro
Forum: a740g
Last Post: aadityap0901
5 hours ago
» Replies: 6
» Views: 186
"9,999 digits of PHI with...
Forum: Programs
Last Post: ahenry3068
6 hours ago
» Replies: 5
» Views: 61
Ascii Christmas Tree
Forum: Christmas Code
Last Post: Pete
10 hours ago
» Replies: 6
» Views: 220
request for printing patt...
Forum: Learning Resources and Archives
Last Post: Pete
10 hours ago
» Replies: 18
» Views: 481
What do you guys like to ...
Forum: General Discussion
Last Post: TempodiBasic
11 hours ago
» Replies: 24
» Views: 570
QB64PE v4.0 is now live!!
Forum: Announcements
Last Post: bplus
Yesterday, 10:55 PM
» Replies: 41
» Views: 1,698
Masakari - the abandoned ...
Forum: Programs
Last Post: Sanmayce
Yesterday, 06:27 PM
» Replies: 0
» Views: 40
Merry X-Mas 2024!!
Forum: General Discussion
Last Post: NakedApe
Yesterday, 05:18 PM
» Replies: 13
» Views: 269
Smallish Games
Forum: bplus
Last Post: bplus
Yesterday, 11:31 AM
» Replies: 20
» Views: 1,402

 
  QPrint v2
Posted by: SMcNeill - 12-11-2023, 05:13 PM - Forum: Works in Progress - Replies (9)

Code: (Select All)
Screen _NewImage(800, 600, 32)
$Color:32

f = _LoadFont("./DejaVuSansMono.ttf", 16, "monospace")
_Font f

'first, let's showcase WHY we need to use QPrint over Print:

a$ = "This_is_a_line_with_underscores"
Print a$
Qlocate 2, 1
Qprint a$, -1
Locate 5, 1
Print "Notice something different with those two statements?"
Print "The first line, which uses PRINT, clips off those underscores to make certain that our height is *EXACTLY* 16 pixels."
Print
Print "QPrint, with uses _UPrintString as its roots, renders above and below the main height as necessary for flourishes and underscores."
Sleep
Cls
_Font 16: _FreeFont f
f = _LoadFont("./DejaVuSansMono.ttf", 24, "monospace")
_Font f




Locate 1, 5 'test positioning of first qprint
For i = 1 To 25
Qprint Str$(i), -1 'print enough to test screen scrolling
Sleep 'so we can watch it in action!
Next


'And here we have a test of multi-line string printing
Cls
a$ = "This is a really long line of rambling text that represents nothing more than an attempt to write so much junk on a single line that we end up having to split this text and move it down onto multiple lines, so that we don't lose what we're printing beyond the bounds of the screen. Nothing here really, and if you read all of this, you're a good man(tm)!"
For i = 1 To 5
Qprint a$, -1
Sleep 'so we can watch it in action!
Next


Sub Qprint (text$, newline)
'Note that this does NOT print unicode or utf-8 formated strings.
'That functionality has to be expanded in a future update.
'This only prints ASCII characters, but it does so by making use of the _UPrint commands,
'so that font clipping and such doesn't occur and make various fonts illegible.

OriginalX = Pos(1)
OriginalY = CsrLin
CurrentX = (OriginalX - 1) * _FontWidth
CurrentY = (OriginalY - 1) * _UFontHeight
temp$ = text$
Do
finished = 0
MaxX = _Width - CurrentX

TextWidth = _UPrintWidth(temp$)
If TextWidth < MaxX Then 'there's enough room to print on the current line
_UPrintString (CurrentX, CurrentY), temp$
CurrentX = CurrentX + _UPrintWidth(temp$)
finished = -1
Else 'we need to print what we can and continue to the next line
lastchar = QFindMaxPos(temp$, MaxX)
_UPrintString (CurrentX, CurrentY), Left$(temp$, lastchar)
temp$ = Mid$(temp$, lastchar + 1)
MaxX = _Width
GoSub scrollup
CurrentX = 0
CurrentY = CurrentY + _UFontHeight
finished = 0
End If
GoSub scrollup
Loop Until finished
If newline Then CurrentY = CurrentY + _UFontHeight: CurrentX = 0


GoSub scrollup

Exit Sub
scrollup:
If CurrentY > _Height - _UFontHeight Then
'scroll up routine:
$Checking:Off
Dim m As _MEM
m = _MemImage(0)
screenw = _UFontHeight * _Width * _PixelSize
t$ = Space$(m.SIZE - screenw)
_MemGet m, m.OFFSET + screenw, t$
Cls , _BackgroundColor(_Dest)
_MemPut m, m.OFFSET, t$
_MemFree m
$Checking:On
'end of scrolling routine
CurrentY = CurrentY - _UFontHeight
End If
Qlocate Int(CurrentY / _UFontHeight) + 1, Int(CurrentX / _FontWidth) + 1
Return
End Sub

Function QFindMaxPos (text$, w)
'Quick Find Max Position
'This routine quickly finds which position fits within a given width of a string
'This works on a binary search method to determine max length and character position,
'So for long strings or large screens, it can find the proper position much quicker than just searching
'and comparing lengths from left to right, or right to left.

min = 0
max = Len(text$)
If _FontWidth Then 'monospaced font
max = Int(w / _FontWidth) + 1 'the most possible characters that can fit on a line
Else
If max > w Then max = w 'most possible would be 1 character per pixel!
End If
If _UPrintWidth(Left$(text$, max)) < w Then QFindMaxPos = max: Exit Function
Do
test = Int((max - min) / 2) + min
p = _UPrintWidth(Left$(text$, test))
If p = oldp Then Exit Do
Select Case p
Case Is < w
min = test
Case Is > w: max = test
Case Is = w: Exit Do
End Select
oldp = p
Loop
QFindMaxPos = test
End Function


Sub Qlocate (x, y)
'a replacement to error check to make certain that we stay within the proper screen coordinates
'while using the new _uprintstring command
CurrentX = (y) * _FontWidth
CurrentY = (x) * _UFontHeight
If CurrentX > _Width Then Error 5: Exit Sub
If CurrentY > _Height Then Error 5: Exit Sub
Locate x, y
End Sub

Required font is below, in case anyone needs it for testing this:


.7z   DejaVuSansMono.7z (Size: 159.16 KB / Downloads: 43)

Currently, this basically mimics the behavior of PRINT in the fact that it breaks words at the border of the screen, with no concern whatsoever over performing any sort of decent word wrap.

Note that since _UPrintString uses more screen area than Print (as illustrated in those first lines where PRINT clips off part of the text on us), our LOCATE positions are *NOT* going to be the same here, when we swap back and forth between the two commands.

LOCATE 10,10: PRINT "Foo"
LOCATE 10,10: QPRINT "Foo"

^The above will print to two completely different areas of the screen! (Print, as I've pointed out already, doesn't display the same height and width characters, so what is considered to be a "line", is going to be smaller than with UPrintString.)

Don't think you can swap back and forth between PRINT and QPRINT seemlessly. That's not gonna happen! Choose one. Use one. And forget the other even exists, except in the most extreme cases.

Print this item

  Jam for All BASIC Dialects
Posted by: dbox - 12-11-2023, 04:46 PM - Forum: General Discussion - Replies (8)

Out of curiosity, anyone else participating in the Jam for All BASIC Dialects (#5) that's going on through December?

https://itch.io/jam/jam-for-all-basic-dialects-5

Print this item

  QFindMaxPos
Posted by: SMcNeill - 12-11-2023, 09:33 AM - Forum: SMcNeill - No Replies

Code: (Select All)
Screen _NewImage(640, 480, 32)
Randomize Timer
f = _LoadFont("times.ttf", 20)
_Font f

Do
Cls
text$ = ""
For i = 1 To 75
text$ = text$ + Chr$(Rnd * 60 + 64) 'build a random string for various lengths when testing
Next

temp$ = Left$(text$, QFindMaxPos(text$, _Width))
_UPrintString (0, 0), temp$
'The next line shows how long our text would be, if we printed the next character.
Locate 2, 1: Print _UPrintWidth(temp$), _UPrintWidth(Left$(text$, Len(temp$) + 1))
Do
k = _KeyHit
If k = 27 Then System
_Limit 10
Loop Until k > 0
Loop




Function QFindMaxPos (text$, w)
'Quick Find Max Position
'This routine quickly finds which position fits within a given width of a string
'This works on a binary search method to determine max length and character position,
'So for long strings or large screens, it can find the proper position much quicker than just searching
'and comparing lengths from left to right, or right to left.

min = 0
max = Len(text$)
If _FontWidth Then 'monospaced font
max = Int(w / _FontWidth) + 1 'the most possible characters that can fit on a line
Else
If max > w Then max = w 'most possible would be 1 character per pixel!
End If
If _UPrintWidth(Left$(text$, max)) < w Then QFindMaxPos = max: Exit Function
Do
test = Int((max - min) / 2) + min
p = _UPrintWidth(Left$(text$, test))
If p = oldp Then Exit Do
Select Case p
Case Is < w
min = test
Case Is > w: max = test
Case Is = w: Exit Do
End Select
oldp = p
Loop
QFindMaxPos = test
End Function


A routine to quickly find the max sized string that one can _UPRINTSTRING to a given area.

Print this item

  Basic with a database (Linux only)
Posted by: bigriverguy - 12-10-2023, 05:49 AM - Forum: QBJS, BAM, and Other BASICs - Replies (2)

If your curiosity bug bites, here is a link to an open source version of BASIC with an included multi-value database.  It is the open source version of OpenQM called ScarletDME (SDME for short).  It was released as an open source 32 version in 2007 and has been updated over the years to 64 bit by some dedicated programmers.  It is related to Pick like databases such as Universe, Unidata and D3.

It is multi-user and runs on current linux distros such as Debian 12, Ubuntu 23.10 and Fedora 39.  The BASIC included will be very familar to any Quick Basic lover. And, it manages a database without the use of SQL.

The website is https://www.sdme64.com.

Print this item

  Another easy one:
Posted by: PhilOfPerth - 12-10-2023, 04:46 AM - Forum: Help Me! - Replies (9)

Typing Print val("3*3") returns 3.
I would expect it to return 9. I don't see anything to indicate differently.

Print this item

  Tic-80, an 8-bit game engine
Posted by: vividpixel - 12-09-2023, 05:38 PM - Forum: General Discussion - Replies (2)

Discovered "fantasy computers" recently and this might be of interest to other retro programming fans if you aren't too busy with QB64. Runs on probably all the platforms you'd want.

Tic-80 Site / Reference Manual


  • LowRes NX is a similar setup, though using a dialect of BASIC!

Tic-80 can be used with Lua, Python, Ruby, JavaScript, and some others. Lua seems nice so far, and I feel good about its usefulness in game development. I'm also working through tutorials for Defold which is an engine with much broader scope. Maybe I get comfortable using Lua in Tic-80, see if I can actually make anything substantial, and if I ever get tired of limitations, migrate to Defold and continue using Lua.

As a perpetual beginner who never completed a game and tends to get caught up in fine details, the limited ability & all-in-one nature of Tic-80 seems like it could be helpful to stay focused on the essentials, and the 8-bit sound and feel along with an optional CRT filter comes with the territory. 

I had fun making the beginnings of a game with AppGameKit Studio, but hesitant to spend further time learning that IDE and AGK Script. Kept thinking that if I'm going to use BASIC, might as well be QB64! QB64 can most certainly create anything my brain could imagine, but from my perspective it seems better for those who have the patience to recreate the wheel. Some folks enjoy that but not quite confident that I would, or could.

Print this item

  Interesting drive display utility
Posted by: eoredson - 12-09-2023, 06:31 AM - Forum: Utilities - Replies (5)

In this post is an interesting drive display utility which lists drive volumes and serial numbers using a shell to vol:

Code: (Select All)
Rem Utility to display drives and volume and serial. PD 2023.
Dim Shared drives(26) As Integer
Dim Shared labels(26) As String
Dim Shared serial(26) As String

For i = 1 To 26
  d$ = CheckDrive(i)
  If d$ <> "" Then Print d$
Next
End

Function CheckDrive$ (i)
  t$ = "tempfile.arg"
  i$ = Chr$(i + 64) + ":"
  j$ = "cd " + i$
  Shell _Hide j$ + " > " + t$
  Close
  Open t$ For Input As #1
  If EOF(1) = 0 Then
      Line Input #1, s$
      s$ = LCase$(s$)
      If s$ = "path not found" Then
        ' eat
      Else
        Shell _Hide "vol " + i$ + " > " + t$
        Close
        Open t$ For Input As #1
        z = 0
        Do Until EOF(1)
            Line Input #1, s$
            If Len(s$) Then
              z = -1
              Exit Do
            End If
        Loop
        If z Then
            Close
            Open t$ For Input As #1
            x = 0
            Do Until EOF(1)
              Line Input #1, s$
              'Print s$
              If LCase$(s$) = "invalid drive specification" Then
                  Exit Do
              Else
                  drives(i) = -1
                  If InStr(s$, " is ") Then
                    x = x + 1
                    ' volume in drive C is Label
                    If x = 1 Then
                        labels(i) = Mid$(s$, InStr(s$, " is ") + 4)
                    End If
                    ' volume serial number is xxxx-xxxx
                    If x = 2 Then
                        serial(i) = Mid$(s$, InStr(s$, " is ") + 4)
                    End If
                  End If
              End If
            Loop
        End If
      End If
  End If
  q$ = ""
  If drives(i) Then
      q$ = Chr$(i + 64) + ":\" + labels(i)
      If Len(serial(i)) Then
        q$ = q$ + " [" + serial(i) + "]"
      End If
  End If
  CheckDrive = q$
End Function



Attached Files
.bas   checkdrive.bas (Size: 1.9 KB / Downloads: 35)
Print this item

  For everyone who makes games !
Posted by: MasterGy - 12-08-2023, 11:02 PM - Forum: MasterGy - Replies (5)

I would like to bring it to the attention of those who make games. Even with a 2D game, it's worth considering what you want to show. The image update. Until now I never dealt with it, I always used a value. A value that is good for the speed of my current computer. In my last game, I was shocked at how important this is to the perfection of the display.

It also means a lot if someone makes a 2D game!

Something moves on the screen. This will have a path, a process. How many parts this process is divided into and how many times it is mapped determines the quality of the animation.

It is worth taking this into account before making the game! It can also be built in afterwards.

Delta timing
https://en.wikipedia.org/wiki/Delta_timing

I created an example program to show in which cases it is necessary to multiply with 'deltatime' or to use it as a power exponent.

In the main cycle, the value of _LIMIT can be changed so that the animation speed is constant.

If you are making a game, I recommend that you include it so that the program can be set to any image update later.

Code: (Select All)
monx = 600
mony = 600
mon = _NewImage(monx, mony, 32)
Screen mon

'placing balls horizontally
red_ballx = 200
blue_ballx = 400
green_ballx = 300

blue_bally = 1
ballr = 20 'balls radius


gravity = .2



fps = 30
Color _RGB32(150, 150, 150)
Do: _Limit fps

    fps = fps - (_KeyDown(Asc("+")) - _KeyDown(Asc("-"))) * .5
    If fps < 5 Then fps = 5
    If fps > 500 Then fps = 500

    deltatime = 30 / fps


    Cls: Color _RGB32(100, 100, 100)
    Locate 1, 1: Print "+/- FPS setting              SPACE-green ball jump"
    Locate 3, 1: Print "FPS, (_LIMIT value)"; Int(fps), "deltatime:"; deltatime




    legalso_ypozicio = mony - ballr 'this value is the lowest position given by the size of the window and the ball, when the balls are on the ground


    'RED BALL -------------------------------------------------------------------------------------------------------------------------------------
    red_yvec = red_yvec + gravity * deltatime
    red_bally = red_bally + red_yvec * deltatime
    If legalso_ypozicio < red_bally Then red_bally = legalso_ypozicio: red_yvec = -14 'can also be used for jumping, yvec, momentum vector, which gravity tries to pull down in every cycle
    Color _RGB32(255, 20, 20)
    Circle (red_ballx, red_bally), ballr
    Paint (red_ballx, red_bally)


    'GREEN BALL  ------------------------------- same as the red ball, only you jump with SPACE
    green_yvec = green_yvec + gravity * deltatime
    green_bally = green_bally + green_yvec * deltatime
    If legalso_ypozicio < green_bally Then
        green_bally = legalso_ypozicio
        If _KeyDown(Asc(" ")) Then green_yvec = -5 'you jump to SPACE, which you can only do when you are on the ground (you can't jump while falling). it also has the power of jumping
    End If
    Color _RGB32(20, 255, 20)
    Circle (green_ballx, green_bally), ballr
    Paint (green_ballx, green_bally)



    'BLUE BALL
    blue_bally = blue_bally * 1.12 ^ deltatime '<------------------   in such cases deltatime must be increased!
    If legalso_ypozicio < blue_bally Then blue_bally = 1
    Color _RGB32(20, 20, 255)
    Circle (blue_ballx, blue_bally), ballr
    Paint (blue_ballx, blue_bally)


    _Display
Loop

Print this item

  To and From Base-64
Posted by: SMcNeill - 12-08-2023, 10:18 PM - Forum: SMcNeill - Replies (2)

Umm...  I had a topic here already on this subject, with the code I'd originally posted being (Windows-Only).  I went back to modify that time as I was posting code which would turn my Windows-Only comment into a thing of the past, and... umm...  some mod.... *whistles innocently*... who may, or may not have been me...  *whistles a little more*...  completely ended up destroying that whole topic, rather than just renaming it!!

*Whistles Innocently a whole lot!*

But, since these things happen, and nobody will cop up to deleting and obliterating my old topic...  *hum humm deee hummm* ,,, then I guess I'll just start a new one, so I can share the new code which works on all OSes.

Code: (Select All)
_ControlChr Off

a$ = "Hello World"
Print "Original: "; a$

a1$ = To64$(a$)
Print "Encrypted: "; a1$

b$ = From64$(a1$)
Print "Restored: "; b$


$If BASE64 = UNDEFINED Then
    $Let BASE64 = TRUE
    $If WIN Then
        Declare Dynamic Library "Crypt32"
            Function CryptBinaryToStringA& (Compressed$, Byval numElements&, Byval format&, Byval buffer As _Offset, length&)
            Function CryptStringToBinaryA& (s$, Byval length&, Byval flags&, Byval r As _Offset, ret_length&, skip&, flag2&)
        End Declare

        Function To64$ (original$)
            If CryptBinaryToStringA(original$, Len(original$), &H40000001&, 0, l&) Then temp$ = Space$(l&) Else Exit Function
            If CryptBinaryToStringA(original$, Len(original$), &H40000001&, _Offset(temp$), l&) Then To64$ = temp$
        End Function

        Function From64$ (base64$)
            If CryptStringToBinaryA(base64$, Len(base64$), 6&, 0, l&, 0&, 0&) Then temp$ = Space$(l&) Else Exit Function
            If CryptStringToBinaryA(base64$, Len(base64$), 6&, _Offset(temp$), l&, 0&, 0&) Then From64$ = temp$
        End Function
    $Else
            'Note that these two versions were shamelessly stolen from A740g and taken directly from his work.
            'Orignial code and library can be found on the forums here: https://qb64phoenix.com/forum/showthread.php?tid=2184


            ' Converts a normal string or binary data to a base64 string
            Function To64$ (s As String)
            Const BASE64_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

            Dim srcSize As _Unsigned Long: srcSize = Len(s)
            Dim srcSize3rem As _Unsigned Long: srcSize3rem = srcSize Mod 3
            Dim srcSize3mul As _Unsigned Long: srcSize3mul = srcSize - srcSize3rem
            Dim buffer As String: buffer = Space$(((srcSize + 2) \ 3) * 4) ' preallocate complete buffer
            Dim j As _Unsigned Long: j = 1

            Dim i As _Unsigned Long: For i = 1 To srcSize3mul Step 3
            Dim char1 As _Unsigned _Byte: char1 = Asc(s, i)
            Dim char2 As _Unsigned _Byte: char2 = Asc(s, i + 1)
            Dim char3 As _Unsigned _Byte: char3 = Asc(s, i + 2)

            Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (_ShR(char1, 2)))
            j = j + 1
            Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (_ShL((char1 And 3), 4) Or _ShR(char2, 4)))
            j = j + 1
            Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (_ShL((char2 And 15), 2) Or _ShR(char3, 6)))
            j = j + 1
            Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (char3 And 63))
            j = j + 1
            Next i

            ' Add padding
            If srcSize3rem > 0 Then
            char1 = Asc(s, i)

            Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (_ShR(char1, 2)))
            j = j + 1

            If srcSize3rem = 1 Then
            Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (_ShL(char1 And 3, 4)))
            j = j + 1
            Asc(buffer, j) = 61 ' "="
            j = j + 1
            Asc(buffer, j) = 61 ' "="
            Else ' srcSize3rem = 2
            char2 = Asc(s, i + 1)

            Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (_ShL((char1 And 3), 4) Or _ShR(char2, 4)))
            j = j + 1
            Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (_ShL(char2 And 15, 2)))
            j = j + 1
            Asc(buffer, j) = 61 ' "="
            End If
            End If

            To64$ = buffer
            End Function

            ' Converts a base64 string to a normal string or binary data
            Function From64$ (s As String)
            Dim srcSize As _Unsigned Long: srcSize = Len(s)
            Dim buffer As String: buffer = Space$((srcSize \ 4) * 3) ' preallocate complete buffer
            Dim j As _Unsigned Long: j = 1
            Dim As _Unsigned _Byte index, char1, char2, char3, char4

            Dim i As _Unsigned Long: For i = 1 To srcSize Step 4
            index = Asc(s, i): GoSub find_index: char1 = index
            index = Asc(s, i + 1): GoSub find_index: char2 = index
            index = Asc(s, i + 2): GoSub find_index: char3 = index
            index = Asc(s, i + 3): GoSub find_index: char4 = index

            Asc(buffer, j) = _ShL(char1, 2) Or _ShR(char2, 4)
            j = j + 1
            Asc(buffer, j) = _ShL(char2 And 15, 4) Or _ShR(char3, 2)
            j = j + 1
            Asc(buffer, j) = _ShL(char3 And 3, 6) Or char4
            j = j + 1
            Next i

            ' Remove padding
            If Right$(s, 2) = "==" Then
            buffer = Left$(buffer, Len(buffer) - 2)
            ElseIf Right$(s, 1) = "=" Then
            buffer = Left$(buffer, Len(buffer) - 1)
            End If

            From64$ = buffer
            Exit Function

            find_index:
            If index >= 65 And index <= 90 Then
            index = index - 65
            ElseIf index >= 97 And index <= 122 Then
            index = index - 97 + 26
            ElseIf index >= 48 And index <= 57 Then
            index = index - 48 + 52
            ElseIf index = 43 Then
            index = 62
            ElseIf index = 47 Then
            index = 63
            End If
            Return
            End Function
    $End If
$End If


And, as long as we're whistling innocently, I'd also like to point out to @a740g that I have no idea why large portions of this code may, or may not, resemble his so uncannily!  *Whistle thistle hum and drum...*

Print this item

  Importing and Running Libraries in C
Posted by: krovit - 12-07-2023, 11:29 AM - Forum: Help Me! - Replies (7)

Good morning everyone, 

I would like to try using the C language support to integrate certain functions that do not exist or are difficult to access in QB64.

Apart from the wiki, I have not found a proper guide that can help me understand how to do it, and the examples I have found have not been very helpful.

Can you help me with this?

Even Python, which is currently very popular, would be fantastic if it were implemented in QB64… but I realize I'm asking for too much.
Besides, I don't like Python but I have to acknowledge that it has an incredible amount of libraries.

Thank you!

Print this item