Welcome, Guest |
You have to register before you can post on our site.
|
|
|
Is vwatch reserved for internal/debugging stuff? |
Posted by: Dav - 10-14-2023, 08:40 PM - Forum: Help Me!
- Replies (2)
|
|
I was making a stop watch thing, couldn't make/use a variable named vwatch. IDE info in the status box says it's a SUB VWATCH. I'm guessing it's an internal name for debugging or something? Has me curious.
- Dav
|
|
|
Toolbox: GetFileList |
Posted by: SMcNeill - 10-14-2023, 12:03 PM - Forum: SMcNeill
- No Replies
|
|
Standard Toolbox message: As I'm working up my new library (details here: https://qb64phoenix.com/forum/showthread.php?tid=2085), I'm going to be working up samples and demos highlighting how simple I'm trying to make it to use all these additional subs and functions. Many of these routines I've uploaded in one version, demo, sample, or another, over the years, but I'm changing the format on a few of them for simplicity's sake.
To run this download:
1) First head your browser over to: https://github.com/SteveMcNeill/QB64-Pho...on-Toolbox
2) Click the GREEN <> Code button. It stands out; it's the only green item on the whole page.
3) Click the "Download Zip" link and you'll download all the files in the Github down to your PC.
4) Extract that file, as you would any ZIP file before trying to use it.
5) Start QB64, navigate to that file folder that you extracted things to, and open the "Samples" folder.
In this case, you can select "GetFileList.bas" and run it. It contains the code below:
Code: (Select All)
$LET INCLUDE_ALL = TRUE
'$INCLUDE:'..\Library Files\Toolbox.BI'
DIM AS LONG i
GetFileList _CWD$
FOR i = 1 TO UBOUND(FileList)
PRINT FileList(i);
IF _FILEEXISTS(FileList(i)) THEN
PRINT "(File)"
ELSEIF _DIREXISTS(FileList(i)) THEN
PRINT "(Dir)"
ELSE
PRINT "(Unidentified)"
END IF
NEXT
'$INCLUDE:'..\Library Files\Toolbox.BM'
That's all there is to it! Simple as can be, right? The output should be something similar to the following:
|
|
|
Rounded Rectangles and Thick Circles |
Posted by: SMcNeill - 10-14-2023, 01:45 AM - Forum: SMcNeill
- Replies (1)
|
|
Code: (Select All)
Option _Explicit
Screen _NewImage(640, 480, 32)
$Color:32
RoundRect 100, 100, 200, 200, 15, Red
RoundRectFill 200, 210, 300, 250, 5, Green
thickCircle 300, 325, 50, 4, Blue
Sub RoundRect (x As Single, y As Single, x1 As Single, y1 As Single, r As Single, c As _Unsigned Long)
Dim a As Single, b As Single, e As Single
'Draw the 4 straight lines first
Line (x, y + r)-(x, y1 - r), c
Line (x1, y + r)-(x1, y1 - r), c
Line (x + r, y)-(x1 - r, y), c
Line (x + r, y1)-(x1 - r, y1), c
a = r: b = 0: e = -a
'And then draw the rounded circle portions of the RoundRect
Do While a >= b
PSet (x + r - b, y + r - a), c: PSet (x1 - r + b, y + r - a), c
PSet (x + r - a, y + r - b), c: PSet (x1 - r + a, y + r - b), c
PSet (x + r - b, y1 - r + a), c: PSet (x1 - r + b, y1 - r + a), c
PSet (x + r - a, y1 - r + b), c: PSet (x1 - r + a, y1 - r + b), c
b = b + 1: e = e + b + b
If e > 0 Then a = a - 1: e = e - a - a
Loop
End Sub
Sub RoundRectFill (x As Single, y As Single, x1 As Single, y1 As Single, r As Single, c As _Unsigned Long)
Dim a As Single, b As Single, e As Single
Line (x, y + r+1)-(x1, y1 - r-1), c, BF
a = r: b = 0: e = -a
Do While a >= b
Line (x + r - b, y + r - a)-(x1 - r + b, y + r - a), c, BF
Line (x + r - a, y + r - b)-(x1 - r + a, y + r - b), c, BF
Line (x + r - b, y1 - r + a)-(x1 - r + b, y1 - r + a), c, BF
Line (x + r - a, y1 - r + b)-(x1 - r + a, y1 - r + b), c, BF
b = b + 1: e = e + b + b
If e > 0 Then a = a - 1: e = e - a - a
Loop
End Sub
Sub thickCircle (x As Single, y As Single, radius As Single, thickness As Single, colour As _Unsigned Long)
Dim rp As Single, rm As Single, rp2 As Single, rm2 As Single
Dim sm As Single, rpi2 As Single, rmi2 As Single, sp As Single
Dim i As Single
rp = radius + thickness / 2
rm = radius - thickness / 2
rp2 = rp ^ 2
rm2 = rm ^ 2
For i = -rp To -rm Step .2
rpi2 = rp2 - i ^ 2
sp = Sqr(rpi2)
Line (x + i, y)-(x + i, y + sp), colour, BF
Line (x + i, y)-(x + i, y - sp), colour, BF
Next
For i = -rm To 0 Step .2
rpi2 = rp2 - i ^ 2
rmi2 = rm2 - i ^ 2
sm = Sqr(rmi2)
sp = Sqr(rpi2)
Line (x + i, y + sm)-(x + i, y + sp), colour, BF
Line (x - i, y + sm)-(x - i, y + sp), colour, BF
Line (x + i, y - sm)-(x + i, y - sp), colour, BF
Line (x - i, y - sm)-(x - i, y - sp), colour, BF
Next
For i = rm To rp Step .2
rpi2 = rp2 - i ^ 2
sp = Sqr(rpi2)
Line (x + i, y)-(x + i, y + sp), colour, BF
Line (x + i, y)-(x + i, y - sp), colour, BF
Next
End Sub
So, while I was searching my hard drives for little routines and utilities to add to my new little Github Toolbox project, I came across these old routines -- RoundRectFill and thickCircle. I don't know who the original author of these were; I don't think I wrote them, but the drive they were on was probably 5 to 10 years old and dated all the way back to the days of Galleon's Forums (.net?), and back when we were all chatting and talking over on the freenode IRC chat channels. (MY original SBot which ran via freenode was in the same folders, which is what helps me date how old these things are! LOL!)
My best guess is STxATxIC or perhaps vince helped create these originally. If anyone knows for certain who the original author of RoundRectFill and thickCircle are, let me know and I'll be certain to add their names to the routines to give them credit for their work.
(If you notice, I didn't list RoundRect as being unknown. That's simple -- I wrote it this evening to go with the filled version. If there was ever an original RoundRect routine somewhere, I didn't save it, so the one here is one I derived myself. It's no mystery code! )
Anyways, I thought I'd share these here to see if anyone knows for certain who the original authors were, before just tossing them all slappy-happy into my toolbox. Kindly speak up if they were yours. Heck, they might've even been mine -- though it's been so long, I certainly don't remember them! LOL! Solve the mystery, if you have information on "Where the heck did those come from?"
|
|
|
Truezoom (fixing rotozoom) |
Posted by: James D Jarvis - 10-13-2023, 02:35 PM - Forum: Programs
- Replies (1)
|
|
So I've noticed rotozoom wasn't reproducing images in 1 to 1 scaling (i.e. no scaling) properly. Here's a demo to show the issue and an attempt to correct it.
Code: (Select All)
'truezoomtest
'OCT 13,2023 10:30 EST
'
'working with rotozoom to draw lines I noted lines of even thickness were not drawing correctly
'I've suspected rotozoom wasn't rescaleing correctly for images of even height and weight for a while now
' but it was close enough for sprites and most uses but in drawing lines the issue was more obvious
'rotozoom is not reporduing images correctly when turning them in 90 degree units
'truezoom is an attempt at a soultion (I'be only tested it at a "scaling of 1" being more interested in rotating for now
'
'this program draws a pair of simple images and places them on the screen to compare the differences
'between the two routines
'it's a very minor change and I've only done ot for 1 to 1 scaling for now
'
'in the demo I've had to manually adjuts the center point for the demonstration having not yet worked out how...
'...to properly adjust the center
'
'and yes... before someone mentions it displayimage has similar issues in reporducing the original image
'
Screen _NewImage(30, 50, 32)
Dim ai&, bi&
ai& = _NewImage(16, 16, 32)
bi& = _NewImage(16, 16, 32)
_FullScreen _SquarePixels
'prepare 2 images
_PrintMode _KeepBackground
Line (1, 1)-(14, 14), _RGB32(200, 0, 0), B
_PrintString (0, 0), "AB"
_PutImage (0, 0)-(15, 15), 0, ai&, (0, 0)-(15, 15)
Cls
Line (1, 1)-(14, 14), _RGB32(0, 200, 0), B
_PrintString (0, 0), "AB"
_PutImage (0, 0)-(15, 15), 0, bi&, (0, 0)-(15, 15)
'Show image put in place
Cls
_PutImage (0, 0), ai&
drawruler
Sleep
'show image rotozoomed into place
RotoZoom23d 8, 8, ai&, 1, 1, 0
_PrintString (0, 25), "R"
drawruler
Sleep
'show image truezoomed into place
Cls
'_PutImage (0, 0), ai&
TrueZoom 8, 8, bi&, 1, 1, 0
_PrintString (0, 25), "T"
drawruler
Sleep
'show image rotozoomed with 90 turn
'have to account for x shift because center is drawn at 8,8 otherwise
Cls
RotoZoom23d 7, 8, ai&, 1, 1, 90
drawruler
_PrintString (0, 25), "R"
Sleep
'show image truezoomed with 90 turn
'have to account for x shift because center is drawn at 8,8 otherwise
Cls
TrueZoom 7, 8, bi&, 1, 1, 90
drawruler
_PrintString (0, 25), "T"
Sleep
'show image Rotozoomed with 180 turn
'have to account for x and y shift because center is drawn at 8,8 otherwise
Cls
RotoZoom23d 7, 7, ai&, 1, 1, 180
drawruler
_PrintString (0, 25), "R"
Sleep
'show image truezoomed with 180 turn
'have to account for x and y shift because center is drawn at 8,8 otherwise
Cls
TrueZoom 7, 7, bi&, 1, 1, 180
drawruler
_PrintString (0, 25), "T"
Sleep
Sub drawruler
'just a few marks for this demo program
Line (0, 0)-(15, 0), _RGB32(200, 0, 0)
For x = 0 To 15 Step 2
PSet (x, 0), _RGB32(200, 200, 200)
PSet (16, x), _RGB32(200, 200, 200)
Next x
End Sub
Sub TrueZoom (centerX As Single, centerY As Single, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
'rotate an image with Rotation defined in units of degrees, 0 is along x axis to the right gogin clockwise
Dim px(3) As Single: Dim py(3) As Single
Wi& = _Width(Image&): Hi& = _Height(Image&)
W& = Wi& / 2 * xScale
H& = (Hi& / 2) * yScale
If Hi& Mod 2 Or Hi& < 2 Then
px(0) = -W&: py(0) = -H&: px(1) = -W&: py(1) = H&
px(2) = W&: py(2) = H&: px(3) = W&: py(3) = -H&
Else
px(0) = -W&: py(0) = -H&: px(1) = -W&: py(1) = H& - 1
px(2) = W& - 1: py(2) = H& - 1: px(3) = W& - 1: py(3) = -H&
End If
sinr! = Sin(-0.01745329 * Rotation): cosr! = Cos(-0.01745329 * Rotation)
For i& = 0 To 3
x2& = (px(i&) * cosr! + sinr! * py(i&)) + centerX: y2& = (py(i&) * cosr! - px(i&) * sinr!) + centerY
px(i&) = x2&: py(i&) = y2&
Next
_MapTriangle (0, 0)-(0, Hi& - 1)-(Wi& - 1, Hi& - 1), Image& To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
_MapTriangle (0, 0)-(Wi& - 1, 0)-(Wi& - 1, Hi& - 1), Image& To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
End Sub
Sub RotoZoom23d (centerX As Single, centerY As Single, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
'rotate an image with Rotation defined in units of degrees, 0 is along x axis to the right gogin clockwise
Dim px(3) As Single: Dim py(3) As Single
Wi& = _Width(Image&): Hi& = _Height(Image&)
W& = Wi& / 2 * xScale
H& = (Hi& / 2) * yScale
px(0) = -W&: py(0) = -H&: px(1) = -W&: py(1) = H&
px(2) = W&: py(2) = H&: px(3) = W&: py(3) = -H&
sinr! = Sin(-0.01745329 * Rotation): cosr! = Cos(-0.01745329 * Rotation)
For i& = 0 To 3
x2& = (px(i&) * cosr! + sinr! * py(i&)) + centerX: y2& = (py(i&) * cosr! - px(i&) * sinr!) + centerY
px(i&) = x2&: py(i&) = y2&
Next
_MapTriangle (0, 0)-(0, Hi& - 1)-(Wi& - 1, Hi& - 1), Image& To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
_MapTriangle (0, 0)-(Wi& - 1, 0)-(Wi& - 1, Hi& - 1), Image& To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
End Sub
|
|
|
MouseyBalls, playing with balls using mouse (repel/attract) |
Posted by: Dav - 10-13-2023, 01:16 PM - Forum: Programs
- Replies (3)
|
|
Yep, I'm still playing with simple balls. This demo shows how to attract/repel objects on the screen from the mouse pointer position. I may use this method in a game. Using the mouse, carve a path through the balls (right click), or draw them to the mouse (left click). SPACE will reset the screen. Uses hardware image for speed handling large number of balls.
- Dav
Code: (Select All)
'===============
'MOUSEYBALLS.BAS
'===============
'By Dav, OCT/2023
'Demo of attracting/repelling objects (balls) from mouse point.
'Uses hardware images for speed handling large number of objects.
'Use mouse clicks to interact with the balls on screen.
'LEFT click mouse to carve a path through the balls (repels from mouse point).
'RIGHT click to draw the balls back (attracts them to mouse point).
'SPACE will reset ball position on screen.
'That's it for now. Have a ball.
Screen _NewImage(1000, 600, 32)
balls = 3000
Dim ballx(balls), bally(balls), balldir(balls)
Dim ballsize(balls), ballclr&(balls), ballimage&(balls)
For i = 1 To balls
ballx(i) = Rnd * _Width
bally(i) = Rnd * _Height
ballsize(i) = Rnd * 10 + 5
balldir(i) = Rnd * 10 * _Pi
ballclr&(i) = _RGB(Rnd * 255, Rnd * 255, Rnd * 255)
Next
'make ball hardware images for speed
For i = 1 To balls
temp& = _NewImage(ballsize(i) * 2, ballsize(i) * 2, 32)
_Dest temp&
r = _Red32(ballclr&(i)): g = _Green32(ballclr&(i)): b = _Blue32(ballclr&(i))
x = _Width(temp&) / 2: y = _Height(temp&) / 2
For y2 = y - ballsize(i) To y + ballsize(i)
For x2 = x - ballsize(i) To x + ballsize(i)
clr = (ballsize(i) - (Sqr((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)))) / ballsize(i)
If clr > 0 Then PSet (x2, y2), _RGB(clr * r, clr * g, clr * b)
Next
Next
ballimage&(i) = _CopyImage(temp&, 33)
_FreeImage temp&
Next: _Dest 0
'stars
For x = 1 To 2000
c = Rnd * 3
Line (Rnd * _Width, Rnd * _Height)-Step(c, c), _RGBA(200, 200, 200, 25 + Rnd * 200), BF
Next: back& = _CopyImage(_Display, 33)
Do
_PutImage (0, 0), back&
While _MouseInput: Wend
For i = 1 To balls
dx = _MouseX - ballx(i)
dy = _MouseY - bally(i)
angle = Atn(dy / dx)
If dx < 0 Then angle = angle + _Pi
balldir(i) = angle
dis = (dx ^ 2 + dy ^ 2) ^ .68
speed = _Width / (dis + 1)
If _MouseButton(1) Then
ballx(i) = ballx(i) + speed * -Cos(balldir(i))
bally(i) = bally(i) + speed * -Sin(balldir(i))
ElseIf _MouseButton(2) Then
ballx(i) = ballx(i) + speed * Cos(balldir(i))
bally(i) = bally(i) + speed * Sin(balldir(i))
Else
balldir(i) = Rnd * 10 * _Pi
ballx(i) = ballx(i) + Cos(balldir(i))
bally(i) = bally(i) + Sin(balldir(i))
End If
If ballx(i) < ballsize(i) Then ballx(i) = ballsize(i)
If ballx(i) > _Width - ballsize(i) Then ballx(i) = _Width - ballsize(i)
If bally(i) < ballsize(i) Then bally(i) = ballsize(i)
If bally(i) > _Height - ballsize(i) Then bally(i) = _Height - ballsize(i)
_PutImage (ballx(i), bally(i)), ballimage&(i)
Next
keys = Inp(&H60)
If keys = 57 Then
For i = 1 To balls
ballx(i) = Rnd * _Width
bally(i) = Rnd * _Height
Next
End If
_Limit 30
_Display
Loop Until keys = 1
End
|
|
|
CompareMem |
Posted by: SMcNeill - 10-13-2023, 11:29 AM - Forum: SMcNeill
- Replies (1)
|
|
A little routine to quickly compare one mem block to another to see if they're identical or not.
Code: (Select All)
Declare CustomType Library
Function memcmp% (ByVal s1%&, Byval s2%&, Byval n As _Offset)
End Declare
Randomize Timer
Screen _NewImage(1280, 720, 32)
'let's make this an unique and pretty image!
For i = 1 To 100
Line (Rnd * _Width, Rnd * _Height)-(Rnd * width, Rnd * _Height), &HFF000000 + Rnd * &HFFFFFF, BF
Next
image1 = _CopyImage(0) 'identical copies for testing
image2 = _CopyImage(0) 'identical copy... BUT
_Dest image2
PSet (Rnd * _Width, Rnd * _Height), &HFF000000 + Rnd * &HFFFFFF 'We've just tweaked it so that there's no way in hell it's the same as the other two now!
_Dest 0 'image3 is EXACTLY one pixel different from the other two. Can we detect that?
image3 = _CopyImage(0) 'an identical copy once again, because 0 will change once we print the resul
Dim m(3) As _MEM
m(0) = _MemImage(0)
m(1) = _MemImage(image1)
m(2) = _MemImage(image2)
m(3) = _MemImage(image3)
result1 = CompareMem(m(0), m(1))
result2 = CompareMem(m(0), m(2))
result3 = CompareMem(m(1), m(2))
Print "Current Screen and Image 1 Compare: "; result1
Print "Current Screen and Image 2 Compare: "; result2
Print "Image1 and Image 2 Compare : "; result3
Print
Print "Press <ANY KEY> for a speed test!"
Sleep
t# = Timer
Limit = 1000
For i = 1 To Limit
result = CompareMem(m(1), m(2))
result = CompareMem(m(1), m(3))
Next
Print
Print Using "####.####### seconds to do"; Timer - t#;
Print Limit * 2; "comparisons of"; m(0).SIZE; "bytes."
Function CompareMem& (m1 As _MEM, m2 As _MEM)
$Checking:Off
If m1.SIZE <> m2.SIZE Then Exit Function 'not identical
If m1.ELEMENTSIZE <> m2.ELEMENTSIZE Then Exit Function 'not identical
If memcmp(m1.OFFSET, m2.OFFSET, m1.SIZE) = 0 Then x = -1 Else x = 0
CompareMem = x
$Checking:On
End Function
Demo here uses images and _MEMIMAGE to compare, as they're nice and quick to generate, duplicate, and alter.
|
|
|
DECLARE LIBRARY at the end of your code? |
Posted by: SMcNeill - 10-13-2023, 02:23 AM - Forum: General Discussion
- Replies (7)
|
|
Now, I know this might seem a little strange, but hear me out: I think folks need to start adopting the strategy of placing DECLARE LIBRARY routines at the end of their code, rather than at the beginning of it.
Now, hold up a moment there! Before you go saying, "Welp, Steve's finally lost his marbles, everybody's always placed those declarations at the top of their source code!", give me a chance to showcase why I'll probably be adopting this new coding style from now on:
Code: (Select All)
Print BorderWidth, TitleBarHeight
Function BorderWidth&
$Let GLUTGET = TRUE
BorderWidth = glutGet(506)
End Function
Function TitleBarHeight&
$Let GLUTGET = TRUE
TitleBarHeight = glutGet(507)
End Function
Sub ScreenMove_Middle
'Moves to the absolute middle of the desktop, ignoring border and title, so the program window is centered without
'taking them into consideration.
$Let GLUTGET = TRUE
_ScreenMove (_DesktopWidth - _Width - BorderWidth) / 2 + 1, (_DesktopHeight - _Height - BorderWidth) / 2 - TitleBarHeight + 1
End Sub
Sub ScreenMove (x, y)
'Moves to the absolute coordinates of the desktop, ignoring border and title, so the program window is
' positioned with the program window at the desired position, without taking them into consideration.
$Let GLUTGET = TRUE
_ScreenMove x - BorderWidth, y - BorderWidth - TitleBarHeight
End Sub
$If GLUTGET = TRUE Then
$If GLUTGET_DECLARED = UNDEFINED Then
$Let GLUTGET_DECLARED = TRUE
Declare Library
Function glutGet& (ByVal what&)
End Declare
$End If
$End If
As you can see from the code above, I can now write my SUB and FUNCTION in such a manner that they make certain that the DECLARE LIBRARY in question is included in my source.
Now, what's the point to such tomfoolery, you ask?
In this case, it allows me to wrap everything up nice and neat in one *.BM file. I don't need to turn the above into two different libraries, with one just for the *.BI Declare Library. It also allows me to write these routines and wrap them up so that I can limit which ones I require in a program. (See the recent Github Toolbox here https://github.com/SteveMcNeill/QB64-Pho...on-Toolbox for an example of this SUB/FUNCTION inclusion/exclusion at work.)
Now, using this style, I can include one of those routines uniquely in my code as needed, and it'll automatically add in the DECLARE with it. And, without me manually including one of those routines which need this particular DECLARE LIBRARY, it's simply excluded and not used at all in my program, keeping EXE filesize and memory usage as small as possible for whatever app I end up building.
DECLARE LIBRARY at the end of your code, instead of at the front. It might not be just as crazy as you'd think it is at first glance.
|
|
|
Github QB64PE Toolbox |
Posted by: SMcNeill - 10-13-2023, 01:45 AM - Forum: Works in Progress
- Replies (29)
|
|
If you're like me, over time you've written and accumulated a zillion different little routines full of subs and functions to help do things for you. If you're also like me, when you need to be able to find those routines to make use of them again, they end up hiding from you.
I've decided it's about time that I did something about that and get my junk a little better organized -- and while I'm at it, I thought I'd share and see if anyone else wanted to jump in on the bandwagon and share their own tools in the same place so we could have a "one stop shop" for all things related to expanding QB64PE functionality.
To that end, I present: https://github.com/SteveMcNeill/QB64-Pho...on-Toolbox
At this point in time, it's very much a work-in-progress, with just ONE whole commit in its entire Github history! WOOT!! But, I hope from this one commit, you can see the general concept of what I'm shooting to accomplish here:
1) Create a simple library which can be included into any QB64 program with only one set of *.BI and *.BM include files.
2) This library has to have the functionality to allow us to ONLY load and use the subs/functions that we want with our programs. (Precompiler $IF commands allow us to do this.)
3) This library has to be Option _Explicit compatible.
4) Over time, this library will need to have documentation added for each of the routines inside it, explaining how to use those routines and what is expected from each parameter.
5) Examples and Samples of each routine will need to be created and added to the library in time, so users can simply load those files and see the routines in action.
At the moment, I've only got a handful of commands pushed into this initial commit, and I can already see that I'm going to have to do some learning in the future to make things more as I envision. (One thing I've got to work on is learning and expanding my knowledge of markup so the *.md files I'll be creating look a little nicer and more useful.)
As it is, it's the very barest of bones for a toolbox, but it's a start. Feel free to follow, or speak up to be added as a contributor. Over time, I'm hoping that this can expand and become a single go to source for all things to expand QB64PE for us.
|
|
|
|