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

Username/Email:
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 496
» Latest member: braveparrot
» Forum threads: 2,846
» Forum posts: 26,670

Full Statistics

Latest Threads
1990's 3D Doom-Like Walls...
Forum: Programs
Last Post: a740g
1 hour ago
» Replies: 8
» Views: 244
Editor WIP
Forum: bplus
Last Post: aadityap0901
7 hours ago
» Replies: 12
» Views: 671
QBJS v0.9.0 - Release
Forum: QBJS, BAM, and Other BASICs
Last Post: bplus
10 hours ago
» Replies: 14
» Views: 238
Fun with Ray Casting
Forum: a740g
Last Post: a740g
Today, 02:36 AM
» Replies: 2
» Views: 67
Big problem for me.
Forum: General Discussion
Last Post: bplus
Today, 12:20 AM
» Replies: 7
» Views: 99
discover graphics with xa...
Forum: Programs
Last Post: hsiangch_ong
Yesterday, 10:39 PM
» Replies: 0
» Views: 29
another variation of "10 ...
Forum: Programs
Last Post: Jack002
Yesterday, 10:05 PM
» Replies: 37
» Views: 653
Aloha from Maui guys.
Forum: General Discussion
Last Post: doppler
Yesterday, 03:32 PM
» Replies: 14
» Views: 357
Cautionary tale of open, ...
Forum: General Discussion
Last Post: doppler
Yesterday, 03:28 PM
» Replies: 0
» Views: 36
Extended KotD #22: _MOUSE...
Forum: Keyword of the Day!
Last Post: SMcNeill
Yesterday, 12:29 AM
» Replies: 0
» Views: 57

 
  DAY 035: SHELL
Posted by: Pete - 12-16-2022, 02:10 AM - Forum: Keyword of the Day! - Replies (3)

You might think this keyword was leftover from TurtleBASIC, but you'd be wrong. It's actually from DOS.

SHELL is a very versatile way to either call a DOS command or run another app while staying in your current program.

SYNTAX SHELL [_DONTWAIT] [_HIDE] [DOSCommand$]

_DONTWAIT means continue on in our program flow instead of hanging until the call or program started is finished or terminated.

_HIDE means don't show the cmd.exe console window.

Hiding the console is usually preferred. If _HIDE prevents the program from launching, try adding cmd /c to the SHELL.

Waiting is useful if the app or DOS function you are accessing needs to pass information back to your program. SHELL "Dir" (and piped to a file - we'll discus piping later...) to get the directory info into the next part of your program, for instance.

So let's continue by discussing some other improvements from when this keyword was used in QBasic.

In Windows 98 and prior, we had to use COMMAND\c with our SHELLcall. command.exe was the command prompt then, but sometime after Windows 98, M$ remade the command prompt, and called it cmd.exe. We then used CMD /c in our SHELL calls. Well, along comes QB64 and guess what, cmd /c, forgetaboutit! We don't need it anymore, well, that isn't quite true. QB64 takes care of the command prompt call for us, but it fails once in awhile. (See the example marked INCLUDE PATH, a few lines below).

QB64 can use long path folder names and file names and SHELL command lines can be longer than 124 characters. (Wiki).

So now let's discuss some SHELL components and common ways to use SHELL:

A QBasic SHELL component we can still use in QB64 is START. START is an alternative to _DONTWAIT, and has one added advantages, switches...

Switches in a SHELL START to another app tell the operating how to launch it.

Commonly used switches:

/min Launch minimized to the taskbar.

/max Launch it full screen.

/p Send any text file called with the app to the printer.

Example: Launch Wordpad minimized to print a text file...

Remember, since we are using START we do not have to use _DONTWAIT in this example.

Code: (Select All)
SHELL _HIDE "START /min /p wordpad myfile.txt"

Now you might ask, "Hey, where's the path?" Well, in some, but certainly not all instances, registered programs can be automatically found by a SHELL call. For instance, my Firefox browser will launch without a path included. My advice, give it a try without a path, but if it cannot be found, include the path.

How to include a path in a SHELL call.

The easiest way is to include the drive an path.

Example: INCLUDE PATH

Code: (Select All)
SHELL _HIDE _DONTWAIT "cmd /c C:\Windows\Notepad.exe"

So hold on there Petey! What's up with the cmd /c in there? Well, in my system, I can't get: HELL _HIDE _DONTWAIT "C:\Windows\Notepad.exe" unless I add it. Go figure. My advice, SHELL is a bit fickle and you may have to play with some of these command line statements to get it to work.

Okay, now this is a PITA, but an important PITA. If you have a path with a space in it like PROGRAM FILES, you need to enclose that particular directory in quotes, using ASCII CHR$(34), the quote symbol, to avoid it being concatenated.

PRINT CHR$(34) + "Program Files" + CHR$(34)

So let's try to access Windows Photo View Device Imaging Devices...

Code: (Select All)
SHELL _HIDE _DONTWAIT "C:\" + CHR$(34) + "Program Files" + CHR$(34) + "\" + CHR$(34) + "Windows Photo Viewer" + CHR$(34) + "\ImagingDevices.exe"

Note we had to enclose two file paths with spaces in this example. Oh, and go figure, this one I could get to run with _HIDE and no cmd /c.

Anyway, we can save a little work by just enclosing both paths in quotes, one time...

Code: (Select All)
SHELL _HIDE _DONTWAIT "C:\" + CHR$(34) + "Program Files\Windows Photo Viewer" + CHR$(34) + "\ImagingDevices.exe"

So just remember, paths with spaces require quotes, paths without do not. I believe Linux and Mac have the option of using the apostrophe or CHR$(34).

So besides just running other apps while your program keeps running, SHELL can access command window functions, which you can PIPE into your program or into a file.

WARNING - Some of these examples make a file called mytemp.tmp. If you already have a file named mytemp.tmp, running any example with this file name will overwrite your file.

Code: (Select All)
$CONSOLE:ONLY
SHELL _HIDE "DIR /b *.bas>mytemp.tmp" ' The /b switch "bare" prints just the file names. > sign sends this info to the file.
OPEN "mytemp.tmp" FOR INPUT AS #1
DO
    LINE INPUT #1, a$
    PRINT a$
LOOP UNTIL EOF(1)
CLOSE #1

Okay, so how about instead of a file, we just pipe it to the clipboard?

Code: (Select All)
$CONSOLE:ONLY
SHELL _HIDE "DIR /b | clip"
PRINT _CLIPBOARD$

This example example will be to find that mytemp.tmp file in your qb64 folder. Be sure to change the example path to your path.

Code: (Select All)
SHELL _DONTWAIT "Explorer /select, C:\QB64PE\qb64pe3.3\qb64pe\mytemp.tmp"

Our last example is using SHELL to find our IP Address. This might not work on non-English platforms.

Code: (Select All)
' CAUTION - THE SHELL STATEMENT WILL OVERWRITE ANY PREEXISTING FILE YOU HAVE IN YOUR LOCAL DIRECTORY NAMED "mytemp.tmp".
' Change mytemp.tmp to something else if that's a problem.
SHELL _HIDE "ipconfig>mytemp.tmp"
OPEN "mytemp.tmp" FOR BINARY AS #1
a$ = SPACE$(LOF(1))
GET #1, , a$
CLOSE #1
DO
    j = INSTR(LCASE$(a$), search$)
    IPAddy$ = MID$(a$, j)
    IPAddy$ = MID$(IPAddy$, 1, INSTR(IPAddy$, CHR$(13)) - 1)
    IPAddy$ = _TRIM$(MID$(IPAddy$, INSTR(IPAddy$, ":") + 1))
    IF j AND LEN(search$) > 0 THEN
        PRINT "Your IP Address is: "; IPAddy$
        EXIT DO
    ELSE
        SELECT CASE cnt
            CASE 0
                search$ = "ipv4 address"
            CASE 1
                search$ = "ip address"
            CASE 2
                search$ = "ipv4 "
            CASE 3
                search$ = "ipv4-address"
            CASE 4
                search$ = "ip-address"
            CASE 5
                search$ = "ipv4-"
            CASE ELSE
                PRINT "Sorry, can't find IP addy. Opening Notepad so you can find it..."
                SHELL _HIDE "START Notepad mytemp.tmp"
                ' Other ways to write our SHELL...
                REM SHELL _HIDE _DONTWAIT "Notepad mytemp.tmp"
                REM SHELL _HIDE _DONTWAIT "cmd /c Notepad mytemp.tmp"
                REM SHELL _HIDE "cmd /c START Notepad mytemp.tmp"
                EXIT DO
        END SELECT
    END IF
    cnt = cnt + 1
LOOP

Pete

Print this item

  has anyone had ChatGPT write QB64 code yet?
Posted by: madscijr - 12-15-2022, 09:06 PM - Forum: General Discussion - Replies (9)

Apparently somebody tried to get it to write a game for the Atari VCS, so why not try BASIC? The results could be amusing! LoL

https://www.reddit.com/r/Atari2600/comme...the_atari/

Print this item

  Merry Xelfmas !!!
Posted by: James D Jarvis - 12-14-2022, 07:02 PM - Forum: Christmas Code - Replies (11)

A goofy little seasonal graphics demo.   Uses some of the techniques I've been using in my sprite mixer programs and puts them to use.

Code: (Select All)
'XELFMAS
'By James D. Jarvis December 2022
'This program uses BASIMAGE coded by Dav for QB64GL 1.4, MAY/2020
'
'A jumble of christmas elves and a terribe little festive song
'pres <esc> to quit
'
Randomize Timer
Dim Shared ms&
ms& = _NewImage(800, 600, 32)
Screen ms&
_Title "X E L F M A S"
Dim Shared part&
Dim Shared kk1 As _Unsigned Long
Dim Shared kk2 As _Unsigned Long
Dim Shared kk3 As _Unsigned Long
Dim Shared kk4 As _Unsigned Long
Dim Shared kk5 As _Unsigned Long
Dim Shared kk6 As _Unsigned Long

Dim Shared clr~&
part& = BASIMAGE1&

Type elfbits_type
    legs As Integer
    boots As Integer
    top As Integer
    gloves As Integer
    face As Integer
    hat As Integer
End Type
Type balls
    bx As Integer
    by As Integer
    klr As _Unsigned Long
    d As Integer
End Type
Type anelf
    i As Long
    ex As Single
    ey As Single
    rot As Single
    ss As Single
End Type
Dim Shared elf_limit
elf_limit = 80
Dim Shared ball(30) As balls
Dim Shared elook(elf_limit) As elfbits_type
Dim Shared elf(elf_limit) As anelf
_Source part&
'read the colors from the color reference bar whichever color is in the top left corner will be transparent
clr~& = Point(0, 0) 'find background color of image
_Dest part&
Line (0, 0)-(0, 8), clr~& 'erase the color reference bar from the bit map
_ClearColor clr~&, ms& 'set background color as transparent                  not using it in this program
_ClearColor clr~&, part&
_Source ms&
_Dest ms&
_FullScreen _SquarePixels
Color , _RGB32(250, 250, 250)
Cls
For b = 1 To 30
    ball(b).bx = Int(Rnd * _Width)
    ball(b).by = Int(Rnd * _Height)
    Select Case Int(Rnd * 6)
        Case 0
            ball(b).klr = _RGB32(50 + Rnd * 150, 50 + Rnd * 150, 50 + Rnd * 150)
        Case 1
            ball(b).klr = _RGB32(50 + Rnd * 50, 0, 0)
        Case 2
            ball(b).klr = _RGB32(0, 50 + Rnd * 50, 0)
        Case 3
            ball(b).klr = _RGB32(0, 0, 50 + Rnd * 50)
        Case 4
            ball(b).klr = _RGB32(50 + Rnd * 50, 0, 50 + Rnd * 50)
        Case 5
            ball(b).klr = _RGB32(50 + Rnd * 50, 50 + Rnd * 50, 0)
    End Select
    ball(b).d = Int(20 + Rnd * 40)
Next b

For e = 1 To 80
    elf(e).i = _NewImage(32, 32, 32)
Next e
mmx = 0: mmy = 0
For m = 1 To elf_limit
    'create a new set of weapon sprites
    elook(m).legs = Int(1 + Rnd * 6)
    elook(m).boots = Int(1 + Rnd * 6)
    elook(m).top = Int(1 + Rnd * 6)
    elook(m).gloves = Int(1 + Rnd * 6)
    elook(m).face = Int(1 + Rnd * 6)
    elook(m).hat = Int(1 + Rnd * 6)
    make_elf mmx, mmy, m, elf(m).i
    elf(m).ex = Int(Rnd * _Width)
    elf(m).ey = Int(Rnd * _Height)
    elf(m).rot = 0
    elf(m).ss = 1
    ' RotoZoom2 elf(m).ex, elf(m).ey, elf(m).i, elf(m).ss, elf(m).ss, elf(m).rot
Next m
s1$ = "MB O3 L4  GEDCG GGGEDCA AFED B, GGFDE GEDCG GEDC A A AFED , GGGG A G F D C  E E E    E E E E G C D "
s2$ = " O4 L4  GEDCG GGGEDCA AFED B, GGFDE GEDCG GEDC A A AFED , GGGG A G F D C  E E E    E E E E G C D "
s3$ = " O3 L4 MS GEDCG GGGEDCA AFED B, GGFDE GEDCG GEDC A A AFED , GGGG A G F D C  E E E    E E E E G C D "
s4$ = " O2 L4 MS GEDCG GGGEDCA AFED B, GGFDE GEDCG GEDC A A AFED , GGGG A G F D C  E E E    E E E E G C D "
Play s1$ + s2$ + s3$ + s4$
'Hmmm.... I've gotten pretty bad at reading music, sorry
Do
    _Limit 30
    Cls
    For b = 1 To 30
        cball ball(b).bx, ball(b).by, ball(b).d, ball(b).klr
        Select Case Int(Rnd * 100)
            Case 1
                ball(b).bx = ball(b).bx + 2
            Case 2
                ball(b).bx = ball(b).bx - 2
            Case 3
                ball(b).by = ball(b).by + 2
            Case 4
                ball(b).by = ball(b).by - 2
            Case 5
                ball(b).d = ball(b).d - 2
            Case 6
                ball(b).d = ball(b).d + 2
        End Select
    Next b
    mmx = 0: mmy = 0
    For m = 1 To elf_limit
        RotoZoom2 elf(m).ex, elf(m).ey, elf(m).i, elf(m).ss, elf(m).ss, elf(m).rot
        Select Case Int(1 + Rnd * 200)
            Case 1 To 20
                elf(m).ex = elf(m).ex + Int(Rnd * 16)
            Case 21 To 40
                elf(m).ex = elf(m).ex - Int(Rnd * 16)
            Case 41 To 45
                elf(m).rot = elf(m).rot + 2
            Case 46 To 50
                elf(m).rot = elf(m).rot - 2
            Case 51 To 70
                elf(m).ey = elf(m).ey + Int(Rnd * 16)
            Case 71 To 90
                elf(m).ey = elf(m).ey - Int(Rnd * 16)
            Case 91
                elf(m).ss = elf(m).ss + .05
            Case 92
                elf(m).ss = elf(m).ss - .05
            Case Else
                'nothing happens here
        End Select
        If elf(m).ey < -16 Then elf(m).ey = _Height - 8
        If elf(m).ex < -16 Then elf(m).ex = _Width - 8
        If elf(m).ey > _Height + 16 Then elf(m).ey = 0
        If elf(m).ex > _Width + 16 Then elf(m).ex = 0
    Next m
    _Display
    kk$ = InKey$
Loop Until kk$ = Chr$(27)
_FreeImage part&

For e = 1 To 80
    _FreeImage elf(e).i
Next e
System
Sub make_elf (Mx, my, mid, ii As Long)
    tempi& = _NewImage(32, 32, 32)
    _Source part&
    _ClearColor Point(0, 0), tempi&
    _Dest tempi&
    Color , clr~&
    _PutImage (0, 0)-(31, 31), part&, tempi&, ((elook(mid).legs - 1) * 32, 0)-((elook(mid).legs - 1) * 32 + 31, 31)
    _PutImage (0, 0)-(31, 31), part&, tempi&, ((elook(mid).boots - 1) * 32, 32)-((elook(mid).boots - 1) * 32 + 31, 32 + 31)
    _PutImage (0, 0)-(31, 31), part&, tempi&, ((elook(mid).top - 1) * 32, 64)-((elook(mid).top - 1) * 32 + 31, 64 + 31)
    _PutImage (0, 0)-(31, 31), part&, tempi&, ((elook(mid).gloves - 1) * 32, 96)-((elook(mid).gloves - 1) * 32 + 31, 96 + 31)
    _PutImage (0, 0)-(31, 31), part&, tempi&, ((elook(mid).face - 1) * 32, 128)-((elook(mid).face - 1) * 32 + 31, 128 + 31)
    _PutImage (0, 0)-(31, 31), part&, tempi&, ((elook(mid).hat - 1) * 32, 160)-((elook(mid).hat - 1) * 32 + 31, 160 + 31)
    _Source tempi&
    _PutImage (Mx, my)-(Mx + 31, my + 31), tempi&, ii
    _Source ms&
    _Dest ms&
    _FreeImage tempi&
End Sub

Sub RotoZoom2 (centerX As Long, centerY As Long, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
    Dim px(3) As Single: Dim py(3) As Single
    W& = _Width(Image&): H& = _Height(Image&)
    px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
    px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
    sinr! = Sin(-(0.01745329 * Rotation)): cosr! = Cos(-(0.01745329 * Rotation))
    For i& = 0 To 3
        x2& = (px(i&) * cosr! + sinr! * py(i&)) * xScale + centerX: y2& = (py(i&) * cosr! - px(i&) * sinr!) * yScale + centerY
        px(i&) = x2&: py(i&) = y2&
    Next
    _MapTriangle (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
    _MapTriangle (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
End Sub

Sub cball (CX As Long, CY As Long, R As Long, C As _Unsigned Long)
    Dim kl As _Unsigned Long
    kl = C
    rr = _Red(kl)
    bb = _Blue(kl)
    gg = _Green(kl)
    For d = R To (R - Int(R / 2)) Step -1
        fcirc CX, CY, d, _RGB32(rr, bb, gg)
        rr = rr + Int(1 + Rnd * 2)
        gg = gg + Int(1 + Rnd * 2)
        bb = bb + Int(1 + Rnd * 2)
    Next d
End Sub
Sub fcirc (CX As Long, CY As Long, R As Long, C As _Unsigned Long)
    Dim Radius As Long, RadiusError As Long
    Dim X As Long, Y As Long
    Radius = Abs(R): RadiusError = -Radius: X = Radius: Y = 0
    If Radius = 0 Then PSet (CX, CY), C: Exit Sub
    Line (CX - X, CY)-(CX + X, CY), C, BF
    While X > Y
        RadiusError = RadiusError + Y * 2 + 1
        If RadiusError >= 0 Then
            If X <> Y + 1 Then
                Line (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
                Line (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
            End If
            X = X - 1
            RadiusError = RadiusError - X * 2
        End If
        Y = Y + 1
        Line (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
        Line (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
    Wend
End Sub
'================================
'PNG file saved using BASIMAGE1&
'================================
Function BASIMAGE1& 'xelfs.png
    v& = _NewImage(192, 192, 32)
    Dim m As _MEM: m = _MemImage(v&)
    A$ = ""
    A$ = A$ + "haIkM7VLSZ[460eIAj=YgTlNaE8G\R48<ZUH`7Zj<VPMhCZE3clS9TYkCCC`7Z_nj[Q?6PQIj4<6P1if]73O<0Sbg_<ja0<:g?1S1HD^mhf`73``lmO<ja0<"
    A$ = A$ + "8?LoO00000000000000^XnnWGVe4MnOooGke<b\kaHHdeo=o01Wom=4MniZemZnGZ?[7mOefk7me0S\nod;=S[L\0\E_O?^6XDM^gmokimJI^SnJPCCoO]7_"
    A$ = A$ + "AZ]g?j[16IoobNaJ?N[cemooIWJ?NSU6gF77^BVg]fS3000000000000000000000000000000WBYKKMloUc?gijMb_USYd\FkHA_6Dka_Hnj[_NZfSo?Kn5"
    A$ = A$ + "F?gMn]^_H:ci<gaRBYLjDnUnmKD_nmOg8joGNN[=oF<FbUeNVo=]VTK[Vg[Een]>oINoFf?\e_O_RngoGc[UK]n7ae1YWkJb_ESQLWgJc?TonXTN\=O_6<oC"
    A$ = A$ + "g_dl_dWoXFfG_Em?Z[16Io_lGojk#_^[`iO[lKM_OJFU6SUnn0000000000000P?LYKAL^KEn1<6Olhf;^Deo=TncJb8noJl]oO=OYN=7OGkO]]e5]mo]TfS"
    A$ = A$ + "o^>Bmoi`^5_n^iGIoakNNfZonXmo_ke7EeC?EgWkmjoWfOAK[Ch>of6MooLmmX_NTnoQLo_ko]onXRJn_\6knoG_kooYfoGC=I^fNdiJnnoeNoB3`gllEY8k"
    A$ = A$ + "gcE[W[_7meS\VT^^FCON;k5>3mmkiJPFWGemnKM=#3dcnoBenijmJ_6I=XegWO_jMonIKn_m0<^\7MoocIO=_fQeodOFgkMoOjFGjo[M;dl_W4BjaR;oAgoO"
    A$ = A$ + "6^oolfcWe2If?d\__hil`DQmk`LOc=iO=cOaHh??[CjAfg7Lo?LFT^=ja300000000000000000000`e`d59SoAMO^f4A=J:9S]b_USQ5W_ebog<3<o\WgY:"
    A$ = A$ + "n<=ZnoW\FHniWC4?7MZiLokk5hl?Gn_la2>ooTe98oGf^W\O[b>mLG:oFWM5ITn\\:ZnoBITmIYE0coeVSoYD5#nIkm:UO;73I>MkYo8bN_ROV0Zo[MnkMoo"
    A$ = A$ + "J_ODcoZjmW[EADocUe98oGf^W\O[b>mLG:oFWM5ITfG4monWchmoce[4Aog^kGJMogI<oYT?C;c>]nWVE6AfoglNUAN>100000000000000000n0mm;WQcaW"
    A$ = A$ + "\SDoDk?N]oXeoS^6<jeoc#n;[SKm]Tkki:YViODIm>eoS>VFnUc?g4:macmn]\6<RlcF?o9[UiV;ZFf;DcJODi>jlcEoWFi[KmhHijl_?OBbTOJogE9odePJ"
    A$ = A$ + "ZoAf3<?GGFGTOli_\okUn\YGOfjLEcO?T_l_BiW>F^Mka_7JNo8cKilJ>cUFnN]^6T;oBelN\6lKMonSWjaJn8GoW]lnk?GgoIn?WOD?k6;FoGdk5mjmNc_U"
    A$ = A$ + "SWUOiFiWnI_2eoAWOjc]`Bi7mc`dBm4m\f?ZlCcH]lkehiCZnGjJPIm\g7>3VgMdS3H4VgMdS3H4VgMdS3000000000000000hLkn:nMkM>go\mha]W:miVO"
    A$ = A$ + "oL>Dn[XHNAG_Wn_jjZ_>heoND7b^=hiMTmoYmI[eggSnoUS]imkA=oidISG7ijOdinBmnW]N_6\J?OPckZjikdJ`Wjmo7ejobJ`;gKK:iHGlioIYoO^VoYMo"
    A$ = A$ + "oc`jo_ekOfn4^oobioIXoO4IGcoVCgo?f\[JKTI7iHXVaaE]nO6bOdeoAJ_KSNl200000000000000000000000#Fo?0=48A%%%0"
    btemp$ = ""
    For i& = 1 To Len(A$) Step 4: B$ = Mid$(A$, i&, 4)
        If InStr(1, B$, "%") Then
            For C% = 1 To Len(B$): F$ = Mid$(B$, C%, 1)
                If F$ <> "%" Then C$ = C$ + F$
            Next: B$ = C$: End If: For j = 1 To Len(B$)
            If Mid$(B$, j, 1) = "#" Then
        Mid$(B$, j) = "@": End If: Next
        For t% = Len(B$) To 1 Step -1
            B& = B& * 64 + Asc(Mid$(B$, t%)) - 48
            Next: X$ = "": For t% = 1 To Len(B$) - 1
            X$ = X$ + Chr$(B& And 255): B& = B& \ 256
    Next: btemp$ = btemp$ + X$: Next
    btemp$ = _Inflate$(btemp$)
    _MemPut m, m.OFFSET, btemp$: _MemFree m
    BASIMAGE1& = _CopyImage(v&): _FreeImage v&
End Function

Print this item

  GUI Application Launcher and windowing system
Posted by: Keybone - 12-14-2022, 04:24 PM - Forum: Works in Progress - Replies (8)

Well I havent worked on my GUI for a long while. Monthes...

So the other day I randomly got started working on it again.

I tried to totally rewrite it from scratch but didnt get the result i wanted.

So, I thought, why not just take my version that works and simplify the hell out of it.

I rewrote most sections piece by piece, and now the code is over 200 lines smaller.

The windows dont resize or maximize anymore, only minimize, move, and restore back to window.

some of the icons on the desktop launch external applications, some are minimized windows.

all the shortcuts will need to be changed because they are set up for my computer.

also, a few shortcuts are set up to open a file browser pointed at a specific directory.



I tacked on the background image subroutines as an afterthought so changing the wallpaper is all the way at the end of the program.

and adding new shortcuts and windows is at the top.



Here are some screenshots:





[Image: current.png]



[Image: current2.png]



[Image: folder.png]





and here is the source:


.7z   os3-2.7z (Size: 148 KB / Downloads: 71)

Print this item

  Having screen blinking issue using Hardware Images
Posted by: Dav - 12-14-2022, 03:01 PM - Forum: Help Me! - Replies (4)

I started working on the QB64 video+audio format maker I shared at the old forum, adding playback controls, etc.  I want to load images as Hardware images because they seem to display much faster, will allow better frame rates, but when doing that the screen blanks horrible.  Not sure why and what can fix the blinking.  Hoping to discover a solution or I will have to stick when the slower regular way.

I've attached the code and a test QBV file.  As is the video displays ok, but if you comment out line #53 and use #54 instead (hardware images) the screen will blink very badly.  The video is a low resolution one for testing purposes, me playing a short Christmas song on the piano.

Thanks for any help.

- Dav


[attachment=1221]

Print this item

  DAY 034: WIDTH (SUB)
Posted by: SMcNeill - 12-14-2022, 02:48 PM - Forum: Keyword of the Day! - Replies (4)

I thought I'd be nice and post a word today, to give Pete a break for a bit.  (Also, someone asked me about this, and it's just as easy to write an answer here as it is elsewhere.  Big Grin)

WIDTH -- One of those simple little commands that has been in the language forever and ever.  Going back to the days of GWBASIC, one could always use WIDTH to set the character height and width of a SCREEN 0 screen.  You can see our wiki article on it here: https://qb64phoenix.com/qb64wiki/index.php/WIDTH

Usage has always been rather simple:  WIDTH columns, rows

One keyword, two parameters to set how many columns and how many characters you wanted to print to the screen.  Can't get much simpler than that, now can it??

So, someone asked me, "WHAT THE HECK ARE THE EXTRA TWO PARAMETERS THAT QB64PE ACCEPTS AFTER THAT???"  (And yes, I was asked in all caps, so you know this is a serious question!)

Let me answer this in two parts:

For our Linux and Mac users:  Those two parameters are nothing for you.  They do nothing.  Change nothing.  They're not implemented in either Linux nor Mac.  Set them to whatever you like, nothing is ever going to change.  (At least, not until someone goes in and makes them multi-platform compatible.  At the moment, they only apply for Windows.)

Sorry guys.  Sad

For our Windows users, those two parameters are used FOR THE CONSOLE ONLY.  Unless you use $CONSOLE in your program, they're not going to change anything at all for you either.  You might as well be using a Linux PC, as far as WIDTH and the 3rd and 4th parameter are concerned.

So...  You're a windows user.  Your program uses $CONSOLE.  What the heck does those last 2 parameters do for you?

They set the total width and height of your available console.

For example, let's try the following program:

Code: (Select All)
$Console:Only
Width 50, 50, 500, 500
ten$ = "0123456789"
For i = 1 To 50
    Print ten$;
Next
sleep

 
Now, if you look, you'll see that I'm printing 10 characters to the screen 50 times -- and they're all printed on the same line.  (semicolon at the end of the print keeps continuous printing without a new line, remember?)  

The Width 50, (who cares), (who cares), (who cares) says that my console is only going to be 50 columns in width.  That's the most characters that it can display on the screen at a single time.   Look at the console we created, count the number of ten$ you see on the screen -- it's exactly 5 of them.  First parameter is the number of visible characters.

BUT, if you look down at the bottom of the console, you'll see a scroll bar.  Go ahead and scroll it to the right.  If you took time to scroll and count, you'd see that the total width of our console is actually 500 characters!  We set that with the 3rd parameter:  Width (who cares), (who cares), 500, (who cares)

It's the same with our height and total height as well.  The second parameter says that we're only going to display 50 rows of text on the screen at any given time, but the 4th parameter says that we're going to have 500 rows total, before we start scrolling up the bottom and losing information off the page.

WIDTH, with its 4 parameters, in Windows Console is:

WIDTH columns visible, rows visible, total columns, total rows.

If you set the 3rd and 4th parameters to be the same as your 1st and 2nd, you can create a console with NO scroll bars -- everything that you're displaying is instantly viewable for your user.  

And that's what those two new "secret" little parameters do for us, in a nutshell.  Wink

Print this item

  Storing stuff
Posted by: NasaCow - 12-14-2022, 10:42 AM - Forum: Help Me! - Replies (12)

Every time in the past, when I need to store something to file, I always used a user-defined type and wrote and read the contents to a file using INPUT and OUTPUT. Now starting to design the actual gradebook, I am a little stumped. Naturally, an array sounds useful for something like this. My initial thought is assigning every student a unique ID (UID), unknown to the user but used by me, so if the name changes or something of the sort, we still can line the grades with the proper name.

So, the thinking is UID, Grade or mark, and notes. I am not overly experienced using multi-dimensional arrays. Is there any issues resizing them using REDIM PRESERVE. Is there a better idea for keeping and using this information or storing it with INPUT/OUTPUT won't be overly taxing since I would have to overwrite the file every time I make an update? Using RANDOM sounds like I have to make all these decision on the front-end... I guess I am just looking for a nudge in the right direction since I am kinda inexperinced with this type of programming  Cry

Thanks y'all

Print this item

  Great Cow Basic
Posted by: david_uwi - 12-14-2022, 08:46 AM - Forum: QBJS, BAM, and Other BASICs - Replies (6)

This is a QB compatible language for programming microprocessors. I have been using it for some time and can recommend it for its (relative) simplicity. So if you want to move on from arduinos (who likes C anyway) you can write you own controller programs in BASIC. As far as is possible it has the same instructions as QBasic.
I have attached my latest project. It reads the outside temperature (via a rf link) and displays it on an analog dial gauge. I got the enclosure from a charity shop.
[Image: P1030491a.jpg]

Print this item

  DAY 033: COMMAND$
Posted by: Pete - 12-13-2022, 06:48 PM - Forum: Keyword of the Day! - Replies (9)

Ever wish we could travel the world on a transporter beam? Well, we can't, so for now, let's stay home and play with COMMAND$...

SYNTAX: cmd$ = COMMAND$[(count%)]

USE: Passing arguments to other apps and drag and drop applications.

And as a bonus, if you act now, we'll throw in _COMMANDCOUNT to evaluate that count% variable.

Okay, let's get our demo of the day going...

Works for Windows, untested for Linux or Mac...

Code: (Select All)
WIDTH 120, 25
_SCREENMOVE 0, 0
PRINT
cmd$ = COMMAND$(0) ' Gets the complete path and name of your current running program.
j = _INSTRREV(cmd$, "\")
program$ = MID$(cmd$, j + 1) ' Parse to just the program name.

IF j THEN
    DrivePath$ = MID$(cmd$, 1, LEN(cmd$) - LEN(program$))
    j = 1
ELSE
    DrivePath$ = COMMAND$(1)
    j = 2
END IF

PRINT "Drive and path of program passing arguments... "; DrivePath$: PRINT
PRINT "Program name passing the arguments............ "; program$: PRINT

IF LEN(COMMAND$(1)) THEN
    ' Parse and add back spaces because command$ needs passing spaces enclosed in quotes to preserve them.
    k = _COMMANDCOUNT ' The number of arguments passed.
    FOR i = j TO k
        cmd$ = COMMAND$(i) ' Parse out an argument.
        msg$ = msg$ + cmd$ + " " ' Concatenate string and add space back into string.
    NEXT
    msg$ = MID$(msg$, 1, LEN(msg$) - 1) ' Cut off the trailing space we added.
    COLOR 14: PRINT msg$: PRINT: COLOR 7
END IF

PRINT "[1] Pete is a genius!": PRINT
PRINT "[2] Steve is a genius!": PRINT
PRINT "[3] Pete and Steve are both idiots, and I wore out my [3] key!": PRINT
PRINT
DO
    INPUT "1-3: ", ans%: PRINT
    IF ans% = 0 THEN SYSTEM
    IF ans% > 0 AND ans% < 4 THEN EXIT DO
LOOP

' RUN and pass our sentences as a command$() parameter.
' Note we need a space between each argument we are going to be passing.
format$ = " " + CHR$(34) + _CWD$ + CHR$(34) + "\ "
SELECT CASE ans%
    CASE 1: RUN program$ + format$ + "Pete is a genius!"
    CASE 2: RUN program$ + format$ + "Steve is a genius!"
    CASE 3: RUN program$ + format$ + "Pete and Steve are both idiots, and I wore out my [3] key!"
END SELECT

So the example above is a self-contained program. You don't have to name it or save it, just run it. Well how in the hell is that possible, you ask? Well, let's get into that, pronto...

COMMAND$(0): This is a special parameter of COMMAND$() that retrieves the current drive, path, and name of the running app. Pretty cool, right?

Edit: Steve caught the fact COMMAND$(0) doesn't grab the drive and path of the passing app, it grabs where it is being started from along with the name, of course. (See posts below for more info.) So I adjusted the code above to also include a way to pass the drive and path with _CWD$. Our example only needs the name, but it's nice to know the drive and path, if needed, could be passed as well.

Now that our example program knows its name, it let's you pick a selection then runs itself. It passes the choice you made through COMMAND$() and parses it out in the first conditional block statement... IF LEN(COMMAND$(1)) THEN

The (1) of COMMAND$(1) is string we passed in the RUN statement. So COMMAND$(0) got us or drive, path, and program name, and COMMAND$(1) got us the string argument we passed in the RUN statement.

Note: A difference between QB64 and QuickBASIC is QB made the arguments uppercase. QB64 maintains the case of the passed string.

_COMMANDCOUNT then kicks in and tells us how many parameters. COMMAND$() separates our text message by spaces. In other words a space acts as a string delimiter. So if the message was: "Call me Betty" we would have three arguments: Call, me, Betty. By knowing we have 3, we can save a little coding parsing those arguments out as COMMAND$(1), COMMAND$(2), and COMMAND$(3) by using our FOR/NEXT loop routine.

So even though we posted just one elf-contained program, for ease of use, keep in mind we will primarily use COMMAND$() when RUNning or SHELLing to another application, which needs info passed to it from the previous or calling program.

Note: Other methods of accomplishing for RUN and/or SHELL would be CHAIN, but not used in SHELL statements, Piping, used in SHELL statements, _CLIPBOARD$, usable in both, database sharing, used in both, TCP/IP, usable in both, and SCREEN writing and reading, used in both.

Oh, and here is a fun little shortcut example you can make to view files from Explorer in Notepad...

Instructions: name it anything you want. Make exe only. Find exe and make Desktop shortcut.
Code: (Select All)
cmd$ = COMMAND$(0) ' Gets the complete path and name of your current running program.

IF LEN(COMMAND$(1)) THEN
    ' Parse and add back spaces because command$ needs passing spaces enclosed in quotes to preserve them.
    j = _COMMANDCOUNT ' The number of arguments passed.
    FOR i = 1 TO j
        cmd$ = COMMAND$(i) ' Parse out an argument.
        msg$ = msg$ + cmd$ + " " ' Concatenate string and add space back into string.
    NEXT
    msg$ = MID$(msg$, 1, LEN(msg$) - 1) ' Cut off the trailing space we added.
    COLOR 14: PRINT msg$: PRINT: COLOR 7
    PRINT: PRINT "SHELL notepad " + cmd$
    SHELL _HIDE _DONTWAIT "notepad " + cmd$
END IF

So what now? Open Explorer and find a text file. Drag it into the desktop icon you just created. It will open that dragged file in Notepad.

...And if you want to make it stealth, code it as...
Code: (Select All)
' Make a desktop shortcut to this and drag files into it.
_SCREENHIDE
cmd$ = COMMAND$(0) ' Gets the complete path and name of your current running program.
REM PRINT cmd$: PRINT
IF LEN(COMMAND$(1)) THEN
    ' Parse and add back spaces because command$ needs passing spaces enclosed in quotes to preserve them.
    j = _COMMANDCOUNT ' The number of arguments passed.
    FOR i = 1 TO j
        cmd$ = COMMAND$(i) ' Parse out an argument.
        msg$ = msg$ + cmd$ + " " ' Concatenate string and add space back into string.
    NEXT
    msg$ = MID$(msg$, 1, LEN(msg$) - 1) ' Cut off the trailing space we added.
    REM COLOR 14: PRINT msg$: PRINT: COLOR 7
    REM PRINT: PRINT "SHELL notepad " + cmd$
    SHELL _HIDE _DONTWAIT "start notepad " + cmd$
END IF
SYSTEM

Now imagine what other drag and drop apps you could use this for. Paint.net is one I use this on. I use SENDKEYS WIn32 API routines in my COMMAND$() desktop app to control PAINT.net after it opens and loads the image I dragged into the file. That saves me several steps. I can even resize photos without touching the keyboard once!

If you guys have other uses or programs of a similar nature to share, please feel free to either add them here as examples, or add the link to the forum page.

Thanks, an now back to work on my transporter beam. I think I just sent my CapsLock toe to the South of France.

Pete

Print this item

  NOT OOO
Posted by: SMcNeill - 12-13-2022, 03:10 PM - Forum: General Discussion - Replies (1)

From the thread here, I had a couple of people message me about NOT and why I mentioned it was an oddball in the Order Of Operations (OOO).  Let me see if I can explain this simply, without confounding the issue..

Exponents are one of the first things we solve in our OOO.  Right?

And NOT is down near the end of our OOO.  Right?

So following those rules, write a program to parse and solve: 1 ^ NOT 2 ^ 3 AND 4

???   <-- Now how the heck DOES it calculate that???

The odd secret is NOT is both calculated FIRST, and near the LAST of our OOO.

Here's the trick I learned:  Put a beginning parentheses BEFORE your NOT, and the ending parentheses before any binary operators like AND, OR, EQV...

1 ^ NOT 2 ^ 3 AND 4 gets solved as:  1 ^ (NOT 2 ^ 3) AND 4

1 ^ (NOT 2 ^ 3) AND 4 makes sense to us.  Do the parentheses FIRST, even if NOT might be evaluated down low on the OOO.

You can't just say, "Solve it last," as sometimes, such as in this case, you have to solve it first before you can do the other operations.  1 raised to the WHAT power?   The (NOT 2 ^ 3)rd power!

Put a beginning parentheses BEFORE your NOT, and the ending parentheses before any binary operators like AND, OR, EQV.  <-- That's the rule for parsing and solving NOT properly.

Print this item