Welcome, Guest |
You have to register before you can post on our site.
|
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
|
|
|
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
|
|
|
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]
|
|
|
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. )
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.
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.
|
|
|
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
Thanks y'all
|
|
|
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
|
|
|
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.
|
|
|
|