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

Username/Email:
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 483
» Latest member: aplus
» Forum threads: 2,804
» Forum posts: 26,431

Full Statistics

Latest Threads
Fast QB64 base64 encoder ...
Forum: a740g
Last Post: a740g
1 hour ago
» Replies: 3
» Views: 420
Mean user base makes Stev...
Forum: General Discussion
Last Post: bobalooie
2 hours ago
» Replies: 7
» Views: 172
What do you guys like to ...
Forum: General Discussion
Last Post: bplus
2 hours ago
» Replies: 1
» Views: 26
_IIF limits two question...
Forum: General Discussion
Last Post: bplus
3 hours ago
» Replies: 6
» Views: 97
DeflatePro
Forum: a740g
Last Post: a740g
4 hours ago
» Replies: 2
» Views: 52
New QBJS Samples Site
Forum: QBJS, BAM, and Other BASICs
Last Post: dbox
11 hours ago
» Replies: 25
» Views: 890
Raspberry OS
Forum: Help Me!
Last Post: Jack
Yesterday, 05:42 PM
» Replies: 7
» Views: 151
InForm-PE
Forum: a740g
Last Post: Kernelpanic
Yesterday, 05:22 PM
» Replies: 80
» Views: 6,147
GNU C++ Compiler error
Forum: Help Me!
Last Post: RhoSigma
Yesterday, 11:57 AM
» Replies: 1
» Views: 62
Merry Christmas Globes!
Forum: Programs
Last Post: SierraKen
Yesterday, 03:46 AM
» Replies: 10
» Views: 135

 
  Tutorial Forum Section
Posted by: TerryRitchie - 05-30-2024, 03:00 PM - Forum: General Discussion - Replies (2)

A new forum area has been added dedicated to questions, comments, and code pertaining to the tutorial.

https://qb64phoenix.com/forum/forumdisplay.php?fid=14

Thank you Steve Smile

Print this item

  Welcome to the Tutorial Forum
Posted by: TerryRitchie - 05-30-2024, 02:42 PM - Forum: Terry Ritchie's Tutorial - Replies (6)

Welcome to the tutorial forum section!

Post your questions, comments, and code and I'll do my best to help answer all your questions.

I welcome all comments about the tutorial, positive and negative. You won't hurt my feelings one bit if you have a criticism to share. How else will I know how the tutorial needs to be improved?

Print this item

  Possible floating point error?
Posted by: TerryRitchie - 05-30-2024, 01:02 AM - Forum: Help Me! - Replies (8)

I have a routine that tracks multiple FPS rates within a master FPS rate. I noticed with certain values that it fails. My son actually created the routine for me a few years back. I showed him what was going on and we tracked it to a floating point error.

For example. The result of x should be 1 but instead the value .9999999 is given:

f = 2 / 454
x = 227 * f

(2 is the target FPS, 454 is the global FPS, 227 is the current global frame number)

I've already created a work around for this. My son's code is too precise for what I need. He's tracking the exact moment the frame changes, whereas I simply need to know the alternate frame number within the master FPS. His code:

Fraction = TargetFPS / GlobalFPS
x = CurrentGlobalFrameNumber * Fraction
IF INT(x) <> INT(x - Fraction) THEN ... (report that a frame change happened)

All I simply need is INT(x) for my purposes but the possibility of a floating point error may still exist in QB64. Am I correct in assuming this?

Print this item

  QB64PE Chat Server
Posted by: SMcNeill - 05-29-2024, 03:39 PM - Forum: Works in Progress - Replies (25)

A work-in-progress, but it's now to the point that it does the very barest of TCP/IP communication back and forth across the internet.

For those that are brave, you might give this a shot and see how badly it glitches out on you.  Big Grin

Code: (Select All)
OPTION _EXPLICIT
$COLOR:32

CONST Port = "7319", IP = "172.93.60.23"
CONST FullPort = "TCP/IP:" + Port
CONST FullIP = FullPort + ":" + IP

DIM SHARED AS LONG client 'up to 1000 connections
DIM AS STRING recieved
DIM SHARED AS STRING nam
DIM SHARED AS LONG MainDisplay, TextArea, InputArea
DIM SHARED AS _FLOAT NextPing, server_active
DIM SHARED AS _BYTE TimeStamp 'toggle type display variables
DIM SHARED AS _UNSIGNED LONG DefaultColor, AudibleAlert

DIM ChatLen AS LONG, ChatLog AS STRING, tempString AS STRING

MainDisplay = _NEWIMAGE(1280, 720, 32)
TextArea = _NEWIMAGE(1280, 600, 32)
InputArea = _NEWIMAGE(1280, 120, 32)
DefaultColor = White
TimeStamp = -1
AudibleAlert = -1

SCREEN MainDisplay

client = _OPENCLIENT(FullIP)
IF client THEN
    PRINT "Connected to Steve's Chat!"
    server_active = ExtendedTimer + 300 'server is now counted as being "active" for the next 5 minutes
    GET #client, , ChatLen
    ChatLog = SPACE$(ChatLen)
    DO
        GET #client, , tempString
        ChatLog = ChatLog + tempString
        _LIMIT 30
    LOOP UNTIL LEN(ChatLog) >= ChatLen

    INPUT "Enter your name =>"; nam
    SendMessage "/NAME:" + nam
    _KEYCLEAR 'clear the input buffer, Steve, you big idiot!
    '_KEYHIT will still hold the name in that buffer as it's independent to INPUT!

    CLS
    PRINT ChatLog

    NextPing = ExtendedTimer
    DO '                                                      main program loop
        recieved$ = GetMessage
        ProcessInput recieved$ '                      deal with any server command type messages
        IF recieved$ <> "" THEN '                          we got something from the clien
            _DEST TextArea
            IF TimeStamp THEN COLOR Yellow: PRINT "[" + TIME$ + "]  ";: COLOR DefaultColor
            PRINT recieved$ '                              it should just be a message of some sort
        END IF
        InputJunk

        IF ExtendedTimer > NextPing THEN 'send a message to the server that we're still active
            SendMessage "/PING:" '        that message is a simple PING
            NextPing = ExtendedTimer + 30 'and send this every 30 seconds so we don't disconnect.
        END IF

        IF ExtendedTimer > server_active THEN
            PRINT: PRINT "Sorry.  It appears the server has went offline."
            PRINT "We are now terminating this chat client."
            PRINT: PRINT "Please try back again later."
            _DELAY 2: _KEYCLEAR: SLEEP: SYSTEM
        END IF

        CLS , 0, MainDisplay
        _PUTIMAGE (0, 600)-(1279, 719), InputArea, MainDisplay
        _PUTIMAGE (0, 0)-(1279, 599), TextArea, MainDisplay

        _DISPLAY
        _LIMIT 30
    LOOP
ELSE
    PRINT "Sorry.  Could not connect at this time."
    PRINT "Check Firewall, port forwarding, or other internet TCP/IP blockades."
    END
END IF

SUB ProcessInput (what AS STRING)
    SELECT CASE what
        CASE "/PING:" 'the server send us back a /PING response
            server_active = ExtendedTimer + 300
            what = ""
    END SELECT
    IF AudibleAlert _ANDALSO RIGHT$(what, 22) = " has entered the chat!" THEN BEEP
END SUB


SUB InputJunk
    DIM AS LONG k
    DIM AS STRING temp
    STATIC send$
    _DEST InputArea
    CLS , LightGray
    k = _KEYHIT
    SELECT CASE k
        CASE ASC("v"), ASC("V")
            IF _KEYDOWN(100306) OR _KEYDOWN(100305) THEN
                send$ = send$ + _CLIPBOARD$
            ELSE
                send$ = send$ + CHR$(k)
            END IF
        CASE 32 TO 255
            send$ = send$ + CHR$(k)
        CASE 8
            send$ = LEFT$(send$, LEN(send$) - 1)
        CASE 13
            'do some client side command handling, in case we change some local settings ourselves.
            temp = _TRIM$(send$)
            IF UCASE$(LEFT$(temp, 6)) = "/NAME:" THEN
                nam$ = LEFT$(MID$(temp$, 7), 10)
                send$ = "/NAME:" + nam$
            END IF
            IF UCASE$(LEFT$(temp, 12)) = "/TIMESTAMPS:" THEN
                send$ = ""
                temp$ = UCASE$(_TRIM$(MID$(temp$, 13)))
                IF TimeStamp = 0 THEN
                    IF temp$ = "ON" THEN TimeStamp = -1: SystemMessage "Timestamps are now ON."
                ELSE
                    IF temp$ = "OFF" THEN TimeStamp = 0: SystemMessage "Timestamps are now OFF."
                END IF
                EXIT SUB
            END IF
            IF UCASE$(LEFT$(temp, 7)) = "/ALERT:" THEN
                send$ = ""
                temp$ = UCASE$(_TRIM$(MID$(temp$, 8)))
                IF AudibleAlert = 0 THEN
                    IF temp$ = "ON" THEN AudibleAlert = -1: SystemMessage "Audible Alerts are now ON, for when people join the server."
                ELSE
                    IF temp$ = "OFF" THEN AudibleAlert = 0: SystemMessage "Audible Alerts are now OFF, for when people join the server."
                END IF
                EXIT SUB
            END IF

            SELECT CASE UCASE$(temp)
                CASE "/QUIT", "EXIT", "/QUIT:", "/EXIT:"
                    SendMessage "/EXIT:"
                    SYSTEM
                CASE "/USERS", "/USER", "/LIST", "/USERS:", "/USER:", "/LIST:", "/USERLIST", _
                        "/USERSLIST", "/USERLIST:", "/USERSLISTS:"
                    SendMessage "/USERLIST:"
                    send$ = ""
            END SELECT
            IF send$ <> "" THEN SendMessage send$
            send$ = ""
    END SELECT
    IF TimeStamp THEN COLOR Yellow: PRINT "[" + TIME$ + "]  ";: COLOR DefaultColor
    PRINT nam + ": " + send$ + " (" + STR$(LEN(send$)) + "/65500)"
    _DEST TextArea
    IF _EXIT THEN
        SendMessage "/EXIT:"
        SYSTEM
    END IF
END SUB

SUB SystemMessage (sysmes AS STRING)
    _DEST TextArea
    COLOR Yellow
    PRINT sysmes
    COLOR DefaultColor
    _DEST InputArea
END SUB

SUB SendMessage (msg AS STRING)
    DIM AS STRING temp
    DIM AS _UNSIGNED INTEGER i
    msg = LEFT$(msg, 65535)
    i = LEN(msg)
    IF i = 0 THEN EXIT SUB 'don't bother sending blank messages.
    temp = MKI$(i) + msg
    PUT client, , temp
    _DELAY .1 'wait a moment before we return to get/send more messages
    msg = "" 'reset to blank after we send it
END SUB

FUNCTION GetMessage$
    DIM AS _UNSIGNED _BYTE b
    DIM AS _UNSIGNED INTEGER i
    DIM AS STRING recieved
    GET #client, , i
    recieved = SPACE$(i)
    GET #client, , recieved
    GetMessage = recieved
END FUNCTION


FUNCTION ExtendedTimer##
    'Simplified version of the TimeStamp routine, streamlined to only give positive values based on the current timer.
    'Note:  Only good until the year 2100, as we don't do all the fancy calculations for leap years.
    'A timer should work quickly and efficiently in the background; and the less we do, the less lag we might insert
    'into a program.

    DIM m AS INTEGER, d AS INTEGER, y AS INTEGER
    DIM s AS _FLOAT, day AS STRING
    day = DATE$
    m = VAL(LEFT$(day, 2))
    d = VAL(MID$(day, 4, 2))
    y = VAL(RIGHT$(day, 4)) - 1970
    SELECT CASE m 'Add the number of days for each previous month passed
        CASE 2: d = d + 31
        CASE 3: d = d + 59
        CASE 4: d = d + 90
        CASE 5: d = d + 120
        CASE 6: d = d + 151
        CASE 7: d = d + 181
        CASE 8: d = d + 212
        CASE 9: d = d + 243
        CASE 10: d = d + 273
        CASE 11: d = d + 304
        CASE 12: d = d + 334
    END SELECT
    IF (y MOD 4) = 2 AND m > 2 THEN d = d + 1 'add a day if this is leap year and we're past february
    d = (d - 1) + 365 * y 'current month days passed + 365 days per each standard year
    d = d + (y + 2) \ 4 'add in days for leap years passed
    s = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
    ExtendedTimer## = (s + TIMER)
END FUNCTION

I'll leave the host up and running all day, but I may not be around the whole time to chat or interact with anyone, and I don't guarantee that the server won't explode spontaniously and die a horrible death.  But, at the moment, it seems stable with an client base of ONE person testing it.  LOL!!

Okies... now I have TWO people testing it -- Steve and Steve2!  Yay!!

Anyone want to take bets on how long it takes before this simple chat dies and has to be rebooted and restarted?

Print this item

  ImagePop - puts image on screen with a little popup effect
Posted by: Dav - 05-29-2024, 12:42 PM - Forum: Programs - Replies (2)

Started on this routine today for a friend who wants to make a menu pop on the screen with a little flair.  Here's what I have so far.  It just grows the image in with a little extra grow and shrink loop at the end, and then shrinks the image out.  Posting here for any suggestions and improvements.  Maybe there's a much better way to do the effect.

- Dav

Code: (Select All)

'imagepop.bas
'============
'Shows menu image on screen with a popup effect.
'Coded by Dav MAY/2024 with QB64PE v3.13.0

Screen _NewImage(1024, 680, 32)

'== make a sample image to use offscreen  (REPLACE WITH YOUR OWN)
menu& = _NewImage(500, 500, 32) 'name the image
_Dest menu& 'point drawing commands to it
Cls , _RGB(255, 255, 255) 'main color of image
Line (10, 10)-(490, 490), _RGB(64, 64, 128), BF 'draw border
For y = 10 To 490 Step 5
    Line (10, y)-(490, y), _RGB(0, 0, 0), B 'draw lines down screen
Next
_PrintMode _KeepBackground 'using this so printstring wont destroy background
For t = 1 To 200
    _PrintString (Rnd * 425 + 10, Rnd * 460 + 10), "MENU" 'print something
Next
'===================

_Dest 0 'now point drawing back to main screen


'=== draw stuff on screen
For x = 10 To _Width - 10 Step 10
    For y = 10 To _Height - 10 Step 10
        Line (x, y)-Step(5, 5), _RGB(Rnd * 255, Rnd * 255, Rnd * 255), BF
    Next
Next

'pop image in
PopImage "in", _Width / 2, _Height / 2, menu&

Sleep 2 'wait

'pop it out
PopImage "out", _Width / 2, _Height / 2, menu&



Sub PopImage (way$, x, y, image&)

    Static PopImageBack& 'share this

    xmax = _Width(image&)
    ymax = _Height(image&)

    _Display

    If UCase$(way$) = "IN" Then

        '== copy background first
        PopImageBack& = _CopyImage(_Display)

        '=== pop image on screen

        xcount = 0: ycount = 0
        Do
            _PutImage (x - xcount, y - ycount)-(x + xcount, y + ycount), image&
            xcount = xcount + 4: ycount = ycount + 4
            If xcount > xmax / 2 Then xcount = xmax / 2
            If ycount > ymax / 2 Then ycount = ymax / 2
            If xcount >= (xmax / 2) And ycount >= (ymax / 2) Then Exit Do
            _Limit 250
            _Display
        Loop

        '=== make a little pop effect (grows and shrinks at end)
        For highpop = 100 To 1 Step -20
            For t = 1 To highpop Step 4
                Cls
                _PutImage (0, 0), PopImageBack&
                _PutImage (x - xcount - t, y - ycount - t)-(x + xcount + t, y + ycount + t), image&
                _Display
                _Limit 200 + highpop
            Next
            For t = highpop To 1 Step -3
                Cls
                _PutImage (0, 0), PopImageBack&
                _PutImage (x - xcount - t, y - ycount - t)-(x + xcount + t, y + ycount + t), image&
                _Display
                _Limit 200 + highpop
            Next
        Next

        'Make sure it show normal at the end
        Cls
        _PutImage (0, 0), PopImageBack&
        _PutImage (x - (xmax / 2), y - (ymax / 2)), image&
        _Display

    End If

    If UCase$(way$) = "OUT" Then

        'check if PopImageBack& exists here? <<

        'unpop image here
        xcount = xmax: ycount = ymax
        Do
            Cls
            _PutImage (0, 0), PopImageBack&
            _PutImage (x - xcount, y - ycount)-(x + xcount, y + ycount), image&
            xcount = xcount - 4: ycount = ycount - 4
            If xcount > xmax / 2 Then xcount = xmax / 2
            If ycount > ymax / 2 Then ycount = ymax / 2
            If xcount <= 0 And ycount <= 0 Then Exit Do
            _Limit 200
            _Display
        Loop

        '=== restore background
        Cls
        _PutImage (0, 0), PopImageBack&
        _Display
    End If

    _AutoDisplay

End Sub

Print this item

  Extended KotD #14: _SAVEIMAGE
Posted by: SMcNeill - 05-29-2024, 09:59 AM - Forum: Keyword of the Day! - Replies (1)

Ah, _SaveImage, my old friend!  How I loves you.  How I hates you.  How your existance makes me want to wax profane like Shakespeare!   "Why then, O brawling love! O loving hate! O any thing, of nothing first create! O heavy lightness, serious vanity, Misshapen chaos of well-seeming forms, Feather of lead, bright smoke, cold fire, sick health, Still-waking sleep, that is not what it is! This love feel I, that feel no love in this."

For ages and ages and ages, poor ole Steve worked hard to write and maintain a SaveImage Library for use with QB64 and QB64PE.  https://qb64phoenix.com/forum/showthread.php?tid=20 <-- This library has been around forever and ever and ever, and poor ole Steve poured a lot of sweat and blood and tears and late nights fixing a nice library which works in QB64, in all screen modes (including text screens), to allow the user to save those screens (full or partial) in various image formats.  I poured over GIF, BMP, PNG, JPG format specifications, sorted them out to the point where I could faithfully create them, and then I wrote simple code so an end-user could just do something like the following to save those screens:

SaveImage "My Screenshot.bmp"

And then...  all in one night...  back in version 3.9....  that all became obsolete!!

WAAAHHHHHHHH!!!

(And it doesn't even matter that I was the one who asked about it and helped get things going for the new command to be added to the core language. Tongue )



Back in v3.9, _SaveImage (wiki entry) was released, and it did everything that my library did (mostly) -- and then some! 

Whereas my old library allows the user to save images in GIF, BMP, PNG, JPG formats, the new _SaveImage command allows users to quickly and easily save the screen in any of the following formats:
  • PNG: Saves the image as Portable Network Graphics format if no file extension is specified.
  • QOI: Saves the image as Quite OK Image format if no file extension is specified.
  • BMP: Saves the image as Windows Bitmap format if no file extension is specified.
  • TGA: Saves the image as Truevision TARGA format if no file extension is specified.
  • JPG: Saves the image as Joint Photographic Experts Group format if no file extension is specified.
  • HDR: Saves the image as Radiance HDR format if no file extension is specified.
Now, if you notice, all of these wiki entries have "if no file extension is specified" attached to the end of them.  From talking to various folks, it appears that these extra few words are the main thing that confuse people in the wiki explaination of how to use this command.  (Any suggestions for how to clarify things better, can always be submitted for Rho to take a look at, if anyone has any brilliant insight to word this better.)

Basically, the way _SaveImage works is very simple, with 3 possible parameters to it:

_SAVEIMAGE fileName$ [, imageHandle&] [, requirements$]

(Note that the last two parameters for imageHandle& and requirements$ are inside brackets and are thus optional parameters.)

The way these break down for us is rather simple.

_SaveImage  <-- the command name.  Always got to have a command name before any parameters!
fileName$    <-- the name that we to save the image to, on our storage device.  
imageHandle&     <-- this is the handle to the image that we want to save, in case it's not our current _DISPLAY
requirements$      <--- *THIS* is what that "if no file extension is specified" is refering to.

fileName$ is NOT optional, as you can't save a file with no name.  Big Grin

fileName$ also takes precidence in how we save our file, IF YOU SPECIFY A VALID EXTENSION.   For examples:

_SaveImage "foo.BMP"    <-- This will create a BMP file, of the current _Display image.
_SaveImage "foo.BMP", WorkScreen     <-- This will create a BMP file, of whatever image is associated with the WorkScreen handle.
_SaveImage "foo.BMP",  , "JPG"          <-- This will create a BMP file, of the current _Display image.  This will ignore that last paramater as the file type is specified in the name (foo.BMP).   (Notice I left that middle parameter blank, as it's optional.)
_SaveImage "foo",  , "JPG"          <-- This will create a JPG file, of the current _Display image.  Notice that the filename doesn't have any extension associated with it?

It's only when the filename has no extension that we use the 3rd parameter.  After all, how silly would it be to have "PNG" files saved under the name "foo.QOI"??



And with that one clarification out of the way, there's really not much else to say about it.   This is one of our simplest commands to learn, use, and master, in my opinion.

_SaveImage "My Screenshot.BMP"    <-- 99.99% of the time, that's all someone needs to save the screen image.   What can be any simpler than that??

Print this item

  A small announcement
Posted by: SMcNeill - 05-29-2024, 06:39 AM - Forum: Announcements - Replies (10)

As he didn't want to make a BIG DEAL ABOUT THINGS, we decided to make a small announcement so everyone can welcome @luke back to the development team for QB64PE.  

For those who aren't aware, Luke is also commonly known in the QB64 circles as flukiluke -- one of the key Team QB64 developers who helped keep the project up and going, before it was closed down for good and then we took over with the QB64 Phoenix Edition.  After the closing of Team QB64, it was luke who recovered the old forums which RC had burnt down, and he's the person who's been hosting and keeping those up and available for everyone to look back on, whenever they might take a notion to do so.

And now, after a small break for college and work and life and eating nasty upside-down cakes (or whatever the heck they eat on the other end of the world), he's came back and rejoined the development team once again.  Big Grin

Welcome back home, Luke!  

Everyone welcome him quietly.  We don't want to scare him back off -- at least, not until he's churned out at least ANOTHER million lines of code for us!

Print this item

  IDE search option
Posted by: eoredson - 05-29-2024, 05:45 AM - Forum: Help Me! - Replies (1)

Hi,

In the IDE you have Alt-S to search and F to find a string or value in your program..

My question is:

Could you have a checkbox for wildcard characters * and ? with the search specifications?

  [  ] Allow wildcard

Thanks, Erik.

Print this item

  Issue differentiating between Ctrl-DEL and Ctrl-Backspace
Posted by: dano - 05-29-2024, 12:50 AM - Forum: General Discussion - Replies (4)

I am unable to different between Ctrl-DEL and Ctrl-Backspace.

   Inkey$ reports both as Chr$(0) + Chr$(147)
   _Keydown reports both as 21248

Is there a way that will work to differentiate whether the user pressed Ctrl-Del    or    Ctrl-Backspace?

Print this item

Question reading multiple mice absolute position, keyboard with raw input api ?
Posted by: madscijr - 05-28-2024, 08:12 PM - Forum: Help Me! - Replies (1)

Well, we can read multiple mice in Windows - see the attached code 

  1. plug in 2+ USB mice
  2. make sure .h files are in program directory
  3. compile subprogram 'readmicesub43.bas" (or run it, it will run and immediately close)
  4. run the main program "readmicemain43.bas"
  5. try moving around the different mice on your PC, you should see letters move around the screen
  6. try clicking left and middle mouse buttons to hear sounds
  7. to quit, right click any mouse

However I'm not sure about reading the absolute position of the cursor - it tracks movement pretty good using dx/dy, but you can't quickly move a mouse and have the position jump immediately to where the mouse cursor should be. There is a value the subprogram reads that I thought might be the absolute position but doesn't seem to be. Any ideas? Also how to read the scroll wheel?

I'm also not sure how to detect keypresses in the current program. Normal methods of reading the keyboard like _BUTTON, _KEYHIT and _KEYDOWN from the main loop in the subprogram (which has the focus) don't seem to work. Maybe the keyboard needs to be read using Raw Input? And as long as we're using the Raw Input API to read the keyboard, can we read seperate input from multiple keyboards, like we do with mice? I found a bunch of information on using the Raw Input API to read keyboard input:

but this stuff is way over my head, and I would need some help translating this into QB64PE. 
With everyone's help I was able to get the mouse mostly working, so the keyboard should be possible too. 

If anyone is interested in giving this a look, that would be great.



Attached Files
.zip   readmice.zip (Size: 52.18 KB / Downloads: 24)
Print this item