Posts: 2,849
Threads: 340
Joined: Apr 2022
Reputation:
250
And here's an example of how to do this, and only update/change the screen as necessary:
Code: (Select All)
Dim buttons(1) 'just two simple buttons for the demo
button(0) = MakeButton("Hello World")
button(1) = MakeButton("STEVE!")
x = 100 'just for moveable button
Cls , 4 'a red screen for a background
screenChange = _TRUE 'we start by drawing the screen once
Do
k = _KeyHit
Select Case k 'left/right arrow to move that button
Case 19200
x = x - 3
If x < 0 Then x = 0
screenChange = _TRUE
Case 19712
x = x + 3
If x > _Width * _FontWidth - 100 Then x = _Width * _FontWidth - 100
screenChange = _TRUE
Case Is > 0: System 'any other key to end
End Select
If screenChange Then 'only update the screen when it changes
_PutImage (x, 100), button(0)
_PutImage (200, 200), button(1)
_Display
screenChange = _FALSE
End If
_Limit 30
Loop
Function MakeButton (caption$)
d = _Dest
temp = _NewImage(_FontWidth * Len(caption$) + 4, _FontHeight + 4, 32)
_Dest temp
Color &HFFFFFFFF&&, 0 ' bright white text with no background
Cls , &HFF0000FF&& 'dark blue background for this button
Line (0, 0)-(_Width - 1, _Height - 1), &HFFFFFFFF, B 'white trim around the edges
Line (1, 1)-(_Width - 2, _Height - 2), &HFFFFFFFF, B '2 pixel trim
_PrintString (3, 3), caption$ 'print the caption
MakeButton = _CopyImage(temp, 33) 'make the hardware button
_Dest d 'restore the destination
_FreeImage temp 'free the temp image
End Function
Notice here that the vast majority of the time we're not even using _DISPLAY to update the screen. We print what we want on it, draw the buttons over it... and then basically forget about it until we have to update the screen again. We're still doing the input checking and the processing and everything else, but we're doing absolutely *nothing* with images. We're not putting anything on the screen, or making copies of anything, or freeing anything... We're just leaving the screen as it was until we need to do something to change it.
My CPU usage here? 0.1%... and I think that might be because it never seems to be 0.0% on an active program.
Posts: 2,458
Threads: 248
Joined: Apr 2022
Reputation:
125
Yesterday, 12:05 PM
(This post was last modified: Yesterday, 01:36 PM by Pete.)
Well this is going to be fun. I was looking at some button examples by oldmoses. Now his stuff is pure graphics, but he used the create and putimage method. So my next post was going to be if there was a way to create each button once, and put the button into SCREEN 0. I haven't had a chance to run the examples you posted, because I had a headache. Not from the code, from some construction work. I'm allergic to dust, oh, and dropping that sack of cement on my head didn't do me any favors, either. Anyway, I'm going to get some extra sleep and have a look at this in the morning.
For now, I did get the improvements implemented, except the changes did create a bug I need to work through in the tab subroutine. Those changes cut CPU in half.
I edited the mouse subroutine so it reports activity. Funny, I made the changes then looked at your last post. Yep, same page again. My method was to assign and pass a variable named "act" which becomes non-zero anytime an action in the mouse/key subroutine takes place. Now the button routine only cycles if activity is present, meaning it doesn't even call the button sub unless some event has occurred. This cut the CPU usage down to just about null. I'm going to keep the mouse modifications, period. That is good for all programs. It's immediate, so it doesn't even require a system idle subroutine to be added like a screen saver would use.
Oh, and since you seem to be thinking along the same lines I am on this topic... yes, that damn Pete will be giving you plus points for all the help when he gets everything sorted out.
Edit:
Oh @SMcNeill This one still baffles me...
It only happens with the load image button. It always needs two passes to display. The graphics hybrid button (not shown here) only needs one, as does the text hybrid with lines added to it. Anyway, here is the code cut out and simplified.
Code: (Select All)
Type fields_and_buttons
a As String
fld As Integer
nof As Integer
nob As Integer
style As Integer
End Type
Dim fb As fields_and_buttons
ReDim button$(10), x(10), y(10)
x(9) = 5: y(9) = 10
x(10) = 25: y(10) = 10
fb.a = "Activate"
button$(9) = _Trim$(fb.a)
button$(10) = _Trim$(fb.a)
overlay = _NewImage(_Width * _FontWidth, _Height * _FontHeight, 32)
For p = 1 To 2 ' p is not part of the original code. It's just here to demo the problem.
Overlay_Hardware = _CopyImage(overlay, 33)
_Dest overlay
_PutImage (0, 0), Overlay_Hardware
For k = 9 To 10
img& = _LoadImage(button$(k) + "-static.png", 32)
_PutImage ((x(k) - 1) * 8 + 4, (y(k) - 1) * 16), img&
_FreeImage img&
Next
_FreeImage Overlay_Hardware
_Dest 0
_Display
Beep: Sleep
Next p
Note the for/next loop using p has no impact on the code in the loop. It just runs the process twice.
So the first time it displays absolutely nothing p=1. ???
Hit a key and then the next loop finally does display the html buttons. p=2.
Pete
Posts: 2,849
Threads: 340
Joined: Apr 2022
Reputation:
250
Yesterday, 02:16 PM
(This post was last modified: Yesterday, 02:20 PM by SMcNeill.)
Of course what you have is going to take two passes before it goes onto the screen. It's the way you've *BADLY* wrote your workflow once again. Let me break it down for you:
Code: (Select All)
Type fields_and_buttons
a As String
fld As Integer
nof As Integer
nob As Integer
style As Integer
End Type
Dim fb As fields_and_buttons
ReDim button$(10), x(10), y(10)
x(9) = 5: y(9) = 10
x(10) = 25: y(10) = 10
fb.a = "z:\Activate"
button$(9) = _Trim$(fb.a)
button$(10) = _Trim$(fb.a)
overlay = _NewImage(_Width * _FontWidth, _Height * _FontHeight, 32)
'Create a blank overlay with the above
For p = 1 To 2 ' p is not part of the original code. It's just here to demo the problem.
'make a copy of the existing overlay
'when p is 1, we're going to make a copy of a blank image
Overlay_Hardware = _CopyImage(overlay, 33)
'Now, let's draw on that overlay! Here we make it the _DEST
_Dest overlay
'And here, we put the copy of the existing overlay onto the screen...
'Remember, for the first pass, this is still BLANK at this point!!
_PutImage (0, 0), Overlay_Hardware
For k = 9 To 10
'and here we're just dumb. We want to load the same damn tiny file over and over
'and free it so that we run up CPU usage inside a loop and..
'save what? 10k of memory?
'I did the maths -- It's an 87 x 28 image, in 32-bit colors so raw, uncompressed
'mem usuage is 87 * 28 * 4 = 9,744 bytes of memory.
'WOOOOOOO!!! Why the FLUCK is this just not loaded once and then fogotten about?!!
img& = _LoadImage(button$(k) + "-static.png", 32)
'And here, we put the image to... the current _DEST...
'which is, of course, _DEST overlay
_PutImage ((x(k) - 1) * 8 + 4, (y(k) - 1) * 16), img&
'Kindly recall that overlay WAS blank up until this point
'So we're putting it to the overlay for the first time
'But... This does NOTHING to change the fact that we've already
'put the BLANK Hardware image to the screen, before this...
_FreeImage img& 'WHY OH WHY?!!
Next
_FreeImage Overlay_Hardware 'Get rid of that copy we made
_Dest 0 'Restore our _DEST
_Display 'Laugh at Pete quite soundly at this point
Beep: Sleep
Next p 'NOW, when we run this a second time, the Overlay has the image on it
'so when we make a copy of the overlay, we end up with it being visible on the screen
'when we putimage that copy to the display
Read the comments above for what you're doing all wrong here. Then, after you've tossed your shoe at the screen and gotten past cussing poor innocent Steve, take a moment and study the code below for a much simpler and easier workflow:
Code: (Select All)
Type fields_and_buttons
a As String
fld As Integer
nof As Integer
nob As Integer
style As Integer
End Type
Dim fb As fields_and_buttons
img& = _LoadImage("Z:\activate-static.png", 32)
img_hw& = _CopyImage(img&, 33) 'copy the hardware image
_FreeImage img& 'free that image since we made a hardware version of it
ReDim button$(10), x(10), y(10)
x(9) = 5: y(9) = 10
x(10) = 25: y(10) = 10
fb.a = "Activate"
button$(9) = _Trim$(fb.a)
button$(10) = _Trim$(fb.a)
'overlay = _NewImage(_Width * _FontWidth, _Height * _FontHeight, 32)
'No need for an overlay. The hardware screen itself is the overlay!!
'For p = 1 To 2 ' p is not part of the original code. It's just here to demo the problem.
' Overlay_Hardware = _CopyImage(overlay, 33)
' _Dest overlay
' _PutImage (0, 0), Overlay_Hardware
'NOPE. No need for these either!
For k = 9 To 10
_PutImage ((x(k) - 1) * 8 + 4, (y(k) - 1) * 16), img_hw&
'_FreeImage img&
'NOPE!! Not needed. Just leave the image in memory!
Next
'_FreeImage Overlay_Hardware
'_Dest 0
'NOPE. Didn't make it. Don't need to change it. No need to alter _DEST
'Toss all this crapola out
_Display
Beep: Sleep
'Next p
'No need to pee anywhere. We have now sorted out the code so that it works properly
'without having to make that second pass to display
Now, what is your original code doing?
Loading an image FOUR TIMES. (twice in the inner loop, repeated twice in that outer loop)
Using it...
Freeing it...
WHY?? This is... less than 10k bytes of memory. If that's taxing your PC's memory, tell your wife that you have my permission to go out and upgrade from the TRS-80 that you're still trying to somehow run QB64 on. /sigh
Just load it once. Make it hardware. Use it as needed and don't worry about it.
And throw away the Overlay. You don't need that at all. The hardware layer is separate from the software layer. Just put what you need on the hardware layer and _DISPLAY it. It really is *THAT* simple.
(Note that you'll need to change the path to files. I'm storing your images on my ram drive for now, so I won't have to worry about temp junk filling up my folders. That's where the Z:\ comes from.  )
Posts: 2,849
Threads: 340
Joined: Apr 2022
Reputation:
250
(Yesterday, 12:05 PM)Pete Wrote: Oh, and since you seem to be thinking along the same lines I am on this topic... yes, that damn Pete will be giving you plus points for all the help when he gets everything sorted out.
You best go in and edit admin privileges and gives me 1,000 plus points for all this help sorting your thinking around and out of the dark ages where you use to have to load, use, free stuff to keep memory usage as minimal as possible. Otherwise, I want cash! $$$ $$$. I earn $3.00 per word when writing and submitting articles for publishing and such. You might have to end up selling your golf clubs to pay for this one!!
(Note: Your wife told me to say that!)
Posts: 2,458
Threads: 248
Joined: Apr 2022
Reputation:
125
Elon just emailed me back. He cut 75% of your words!
Hmmm, now I'm just glad I already made that remark remover utility.
Well good news, it works and I updated that post #27. CPU is now near nothing. What I now need to do is put those html button images into an array, and I can do that some other time. That way, if multiple html buttons are used, they can all get loaded at one time, during button creation, and then placed on the screen, accordingly. I like that concept better, anyway.
This stuff is totally foreign to me, coming from text programming, but I do like the fact we are no longer tied to the limited text displays of QuickBASIC SCREEN 0 mode, so it's certainly worth learning and rewarding when things work out.
Anyway, Trump just got back to me and said Elon has a point, but give Steve a couple of +2's anyway.
Pete
Posts: 2,849
Threads: 340
Joined: Apr 2022
Reputation:
250
(Yesterday, 06:00 PM)Pete Wrote: This stuff is totally foreign to me, coming from text programming, but I do like the fact we are no longer tied to the limited text displays of QuickBASIC SCREEN 0 mode, so it's certainly worth learning and rewarding when things work out.
I think the main issue was just your way of trying to do things. You just have the basic workflow ... working against itself.
Let's talk turkey for a bit -- or more important, let's talk about the places where you keep your turkey: in the fridge!!
If your wife wants to make certain you get an important message like, "I'M LEAVING!!", she'll write that directly on the fridge in bright red lipstick. Think of that as being your basic SCREEN 0 text screen. You write to it, the writing stays on it -- at least until you pull out the Windex and paper towels and issue a CLS command.
Now, how does hardware images work in relation to this fridge? They're basically magnets. They don't affect what was written on the screen whatsoever and they don't really interact with the screen at all. They just basically stick on top of it, like you'd stick a magnet on top of the fridge.
Hardware images are those children's magnets that make up the alphabet, which you paste over your wife's lipstick to say, "GOOD RIDDANCE!!"
.....
So basically, all you really need is the fridge (Screen 0) and the magnets (the hardware images), and then you can put (_PutImage) those magnets directly over the contents of whatever is written on the fridge and show them instead (_DISPLAY).
That's the basic concept I was trying to show to you in that last code snippet where I commented out everything you'd done. I just put my hardware image in place and let if cover over the SCREEN 0 text, just like that magnet over the lipstick.
What were you doing? And why was it much more complex?
You went out and measured the size of your fridge's door. Then you ordered a sheet of plywood and had it made that size. Then you used that sheet of plywood as a mold and created a sheet of glass that size. Then you drew scribbles on that glass with your own lipstick. You then glued that glass to the front of your fridge and used it to cover the door and your wife's lipstick. Then, after leaving it up for just a millisecond, you tore it down, broke it and tossed it in the trash, and repeated the same process over again, and again, and again, and... OMG!!
Stick a magnet to the fridge -- DON'T make a copy of the door out of glass, copy a magnet image on that door, place the glass door in front of the fridge, throw it away, and start all over...
See the difference in the complexity of the workflow in the two processes?
One is 0.1% difficulty (or 0.1% CPU usage)
The other is... what'd you say? 60% CPU usage?
And, here's something that's funny enough that I just have to mention it:
The code I posted uses LESS memory than yours, and that's even with me never using _FREEIMAGE on my hardware images...
YOU: Create an Overlay of 640 * 400 * 4 pixels of memory with Overlay = _NewImage(_WIDTH * _FONTWIDTH, _HEIGHT * _FONTHEIGHT, 32). Then proceeds to load button images and place them on that overlay and then free the button image, but never freeing that overlay itself...
ME: Loads an image of 87 * 28 * 4 pixels in size, and uses it directly without that overlay.
If you're going to use an image repeatedly in your programs, just load the BLEEPING thing and assign it to a handle you can remember and then leave it at that. Use it when needed, and skip all that reload/copy/free/free_copy crap. The code is soooo much simpler, both your CPU *and* anyone who ever has to maintain that code, will thank you for it.
Posts: 2,458
Threads: 248
Joined: Apr 2022
Reputation:
125
"LIKE YOU MIGHT FIND ON A BACON,
LETTUCE, AND TOMATO SANDWICH."
Posts: 981
Threads: 52
Joined: May 2022
Reputation:
29
Steve, I think there is a small error. With Option _Explicit this would not have happened.
Code: (Select All)
Dim buttons(1) 'just two simple buttons for the demo
button(0) = MakeButton("Hello World")
button(1) = MakeButton("STEVE!")
Otherwise, interesting discussion!
Posts: 2,849
Threads: 340
Joined: Apr 2022
Reputation:
250
(2 hours ago)Kernelpanic Wrote: Steve, I think there is a small error. With Option _Explicit this would not have happened.
Code: (Select All)
Dim buttons(1) 'just two simple buttons for the demo
button(0) = MakeButton("Hello World")
button(1) = MakeButton("STEVE!")
Otherwise, interesting discussion!
And see... that's why you NEVER use Option _Explicit! It'd toss errors when the code works just fine without it.
Would you believe me if I said I left that glitch in there just to see who might actually take time to look at the code, and not just copy/run it?
.... Yeah.... I wouldn't believe that either!!
Posts: 981
Threads: 52
Joined: May 2022
Reputation:
29
Quote:Would you believe me if I said I left that glitch in there just to see who might actually take time to look at the code, and not just copy/run it?
I would only believe that if I could get a bottle of port for it.
|