Author |
Topic: Card graphics not sticking (Read 148 times) |
|
Turtleman
New Member
member is offline
Gender:
Posts: 29
|
|
Card graphics not sticking
« Thread started on: May 13th, 2016, 6:30pm » |
|
I've written several programs using Qcard that run fine in LB. The code also runs in LBB and properly displays the cards; that is, until reaching the end of the program. Then the cards disappear! I thought "flush" statements weren't required, but there's no difference with or without them. Of particular note, it's not just MY code, but several "canned" programs that use cards. For example, take a look at the first of several QCard lessions at http://lbpe.wikispaces.com/QCard01
I'd love to see how much faster my program might run in LBB, and any help would be greatly appreciated. Thanks!
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Card graphics not sticking
« Reply #1 on: May 13th, 2016, 10:20pm » |
|
on May 13th, 2016, 6:30pm, Turtleman wrote:any help would be greatly appreciated. |
|
If graphics aren't 'sticking' then the reason is likely to be the same as it is in LB - they are being drawn directly to the screen (rather than to LBB's off-screen bitmap). That's entirely to be expected if they are plotted by a DLL designed specifically to work with LB, because obviously that can't know anything about LBB. Basically the DLL is bypassing LBB's double-buffering and doing things in the 'bad old ways'.
If the DLL's designers had had the foresight to take as a parameter the DC to which the cards should be drawn (just as Windows API graphics functions do), it would have been easy to adapt the program to work with LBB. Unfortunately instead it takes the window handle so you have no way of changing the DC to which the graphics are plotted.
There isn't a trivial fix for this. The only workaround I can think of is to copy the graphics back into LBB's bitmap (in other words in the reverse direction to what usually happens) after they have been plotted; that way they will stick correctly. I've listed below a version of the program modified accordingly. It still works in LB.
Richard.
Code:[varSetup]
i=0
'i will be our counter var in for/next loops
'start with the basics and open a window containing a graphicbox
nomainwin
WindowWidth=700:WindowHeight=480
UpperLeftX=1:UpperLeftY=1
menu #1, "&File", "E&xit", [quit]
graphicbox #1.g, 0, 0, 700, 440
open "Card Game" for window_nf as #1
#1 "trapclose [quit]"
'get graphicbox handle
hBox=hwnd(#1.g)
'open the dll
open "qcard32.dll" for dll as #qc
'initialize the deck
Call InitializeDeck hBox
'draw a nice background
#1.g "down; fill 10 190 225"
playwave "shuffle.wav",sync
'the DLL allows for two decks
'the first deck includes cards 1 - 52
'by default, cards are face up
'deal first deck face up
for i = 1 to 52
scan
'window handle, card index number, x, y
Call DealCard hBox,i,i*12,10
playwave "card.wav",sync
'pause 100 milliseconds between cards
call Pause 100
next
playwave "shuffle.wav",sync
'cards 53 to 104 are in the second deck
'deal second deck face down
'set status of all cards to 0, which is face down
for i = 53 to 104
scan
call SetCardStatus i, 0
Call DealCard hBox,i,(i-52)*6,67+i
playwave "card.wav",sync
'pause 100 milliseconds between cards
call Pause 100
next
call BlitBack hBox, 700, 440
wait
[quit] close #qc:close #1:end
''''''''''''''''''''
'subs and functions:
Sub Pause ms
'pause ms number of milliseconds
calldll #kernel32,"Sleep",_
ms as long, re as void
End Sub
Sub InitializeDeck hndle
calldll #qc, "InitializeDeck",_
hndle as ulong,r as long
End Sub
Sub DealCard hndle,nC,x,y
'places card on window whose handle is hndle at x,y
'nC is number of card - 1-52 in first deck and
'53-104 in second deck, if used
calldll #qc, "DealCard",hndle as ulong,nC as long,_
x as long,y as long,r as void
End Sub
Sub SetCardStatus nC,face
'nC is number of card - 1-52 in first deck and
'53-104 in second deck, if used
'face: 0=facedown,1=faceup
calldll #qc, "SetCardStatus",nC as long,_
face as long,r as void
End Sub
Sub BlitBack hBox, w, h
calldll #user32, "GetDC", hBox as ulong, bmpDC as ulong
calldll #user32, "GetDCEx", hBox as ulong, _
0 as long, 0 as long, winDC as ulong
calldll #gdi32, "BitBlt", bmpDC as ulong, 0 as long, 0 as long, _
w as long, h as long, winDC as ulong, _
0 as long, 0 as long, _
_SRCCOPY as long, ret as long
End Sub
|
|
Logged
|
|
|
|
Turtleman
New Member
member is offline
Gender:
Posts: 29
|
|
Re: Card graphics not sticking
« Reply #2 on: May 14th, 2016, 09:51am » |
|
Richard: Thank you, thank you, thank you! I don't think I ever would have figured out what was going on or how to fix it without your help. In fact, I had to look up what DC even meant, which just shows how little I know about graphic functions. I won't pretend to understand the fix entirely (and didn't understand the complete subroutines before), but the standalone section of code I was working with is now displaying correctly again. (Haven't others run into the same problem or did I just overlook reading about it?)
The display was always visible in LB, so I never gave it a second thought. With 17K lines of code, it's going to take a while before I can run the entire application in LBB, but I'm hopeful it will eventually be a lot faster. Discounting the graphics, the program currently runs several times slower in LBB, but there are undoubtedly other incompatibilities that need to be resolved.
Do I understand correctly that flush statements are no longer required with LBB? I have zillions of them, which undoubtedly consume memory and slow things down. Would the same graphics workaround be sufficient in LB without the flush statements? And assuming my program runs in LBB, why would I care if it no longer works in LB?
Thanks again – and as the Terminator would say, "I'll be back!"
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Card graphics not sticking
« Reply #3 on: May 14th, 2016, 11:30am » |
|
on May 14th, 2016, 09:51am, Turtleman wrote:With 17K lines of code, it's going to take a while before I can run the entire application in LBB, but I'm hopeful it will eventually be a lot faster. |
|
It all depends on what the program is spending most of its time doing. If it's performing mathematical calculations, or simple string manipulation, you can expect it to run up to ten times faster in LBB. But if it's mostly plotting graphics it may run no faster at all, or even a little slower, although in that rare event there are often ways of speeding things up.
You will want to avoid, as far as possible, features of LB which are sufficiently non-standard that they have to be emulated in LBB at run time. A well-known example is the WORD$() function, which can be very slow in LBB. On the other hand there are features unique to LBB that can sometimes speed things up considerably (for example whole-array operations) if you don't mind sacrificing compatibility with LB.
Take full advantage of LBB's Profiler which will tell you exactly where the time is being spent, and allow you to concentrate any 'tuning' you do where it will be of maximum benefit.
Quote:Do I understand correctly that flush statements are no longer required with LBB? |
|
That's right: in general flush achieves nothing in LBB and can be safely removed, unless you want to retain compatibility with LB. I say "in general" because there is a special case, when flush is paired with redraw to save and later recall the current graphics output. In that situation the flush must be retained in LBB.
Quote:Would the same graphics workaround be sufficient in LB without the flush statements? |
|
Whether flush is present or not has no impact on the workaround I devised. For maximum efficiency you don't want to blit the screen back into LBB's bitmap too often. You will have noticed that in the modified program I did it just once, after all the graphics had been drawn. The important thing is to do it before a WAIT or SCAN.
If you're mixing graphics drawn using the Cards DLL with conventional Liberty BASIC graphics, then my workaround may get rather complicated. You could easily end up with the cards graphics on the screen but not in LBB's bitmap, but the LB graphics in the bitmap but not on the screen! Then copying one into another isn't going to leave you with what you want, unless you can set the width and height values that you pass to BlitBack so it only copies the cards (you could BlitBack each card individually, after it's drawn, but that could slow things down).
Quote:And assuming my program runs in LBB, why would I care if it no longer works in LB? |
|
From my rather one-sided perspective you wouldn't, but I think some people prefer not to 'burn their bridges'. There are still some very optimistic people who hope (I can hardly believe 'expect') that Carl will eventually release LB5 so want to keep their options open.
Richard.
Edit: I note that the source code for the Cards DLL is available, so in principle it could be rebuilt to be fully compatible with LBB.
|
|
|
|
Turtleman
New Member
member is offline
Gender:
Posts: 29
|
|
Re: Card graphics not sticking
« Reply #4 on: May 14th, 2016, 11:59am » |
|
Hi Richard and thanks for your speedy reply. I was an electronics hardware engineer and manager in my former life and writing code is a royal struggle. I'm truly in over my head and am sure that a "real" programmer would be able to greatly simplify and speed up what I already have. But as ugly and inefficient as my code is, the program is functioning better than my expectations.
The program has several functions and windows, and I'm now trying to get each one to run in LBB as a standalone item before recombining everything. Aside from the graphics displays, there are numerous data displays that are all currently being flushed. Eliminating that requirement is more than a little appealing.
Yeah, I'd love to see LB5, especially if it will run on more than a Windows OS, but I'm not holding my breath. Then again, maybe LLB would eventually work with LB5. I'm very new and inexperienced with LBB (and not overly swift with LB either), but I'll check out the Profiler you mentioned. The program makes heavy use of arrays, but I'm not sure exactly sure what Word$() functions you say may be very slow in LBB. I guess I'll find out shortly as I modify each section of code as maybe be required. Thanks again for your help, it's greatly appreciated!
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Card graphics not sticking
« Reply #5 on: May 14th, 2016, 2:24pm » |
|
on May 14th, 2016, 11:59am, Turtleman wrote:I'd love to see LB5, especially if it will run on more than a Windows OS, but I'm not holding my breath. |
|
As you know, LBB is based on BBC BASIC, a language which (unlike Liberty BASIC) has been multi-platform since shortly after its inception in 1981. At the last count BBC BASIC has been implemented on about seven different CPUs and ported to about 30 different platforms!
Indeed the 32-bit x86 variant of BBC BASIC on which LBB is based has only recently been ported to Linux (86) and Android (86), and is well on its way to being ported to Mac OS-X. However the difficulty with porting LBB is that, exactly like LB 4, it is highly dependent on Windows for the functionality of its GUI components, i.e. windows, controls, dialogs and sprites. Both dialects consist only of thin wrappers around the Windows API as far as these aspects are concerned.
So whilst the core LBB Run-Time-Engine could easily be ported to other platforms - in fact it already has been because the LBB RTE is the BBC BASIC RTE! - that still leaves large parts of the language which cannot be implemented - at least not in a substantially compatible way - because of their dependence on the Windows API.
Quote:I'm not sure exactly sure what Word$() functions you say may be very slow in LBB. |
|
LBB's documentation of the WORD$ function is here. If you don't use it, which from your comments would seem to be the case, you don't need to worry!
Richard.
|
|
Logged
|
|
|
|
Turtleman
New Member
member is offline
Gender:
Posts: 29
|
|
Re: Card graphics not sticking
« Reply #6 on: May 14th, 2016, 4:08pm » |
|
Here's another question, probably more generic than LBB using the QCard lesson example given earlier: Upon initially opening the program, is there a way of hiding the window until it's positioned and ready to run? The brief flickering while the screen is being built and positioned is less than attractive.
Not so much in the small QCard example, but the several screens in my program first have to fetch the window's prior coordinates from disk, position the screen accordingly, and load several graphics. Is there a way to make it visible only after being loaded and ready to run? Thanks!
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Card graphics not sticking
« Reply #7 on: May 14th, 2016, 5:21pm » |
|
on May 14th, 2016, 4:08pm, Turtleman wrote:Upon initially opening the program, is there a way of hiding the window until it's positioned and ready to run? |
|
Which window are you referring to? In the case of the mainwin that's exactly what is supposed to happen: if your program contains a NOMAINWIN statement the mainwin should never appear at all, however briefly, unless and until you execute a MAINWIN statement (if the program is compiled to an EXE that is; you may see the mainwin flash briefly when run from the IDE).
As far as GUI windows are concerned (i.e. those you create yourself using OPEN) then it's entirely under your own control. If you want to create the window initially hidden, and then only show it when you are ready, it's simply a case of clearing the WS_VISIBLE bit with STYLEBITS and then later using the SHOW command (example code below). This works in both LB and LBB.
But maybe I've misunderstood the question.
Richard.
Code: nomainwin
stylebits #w, 0, _WS_VISIBLE, 0, 0
open "Initially hidden" for window as #w
timer 2000, [show]
wait
[show]
timer 0
#w "show"
wait
|
|
Logged
|
|
|
|
Turtleman
New Member
member is offline
Gender:
Posts: 29
|
|
Re: Card graphics not sticking
« Reply #8 on: May 14th, 2016, 6:47pm » |
|
I can't believe I didn't know about hiding the GUI using stylebits and a show statement. (Didn't need to use a timer.) I've been doing crazy things in LB such as initially positioning off screen. This is a whole lot easier! Anyway, I got one of the windows behaving under LBB and will start on another. Or on second thought, maybe I'll postpone that and see if I can get the main program running faster. Oh, and changing the icon is a heck of a lot simpler. Thanks again and have a great weekend!
|
« Last Edit: May 14th, 2016, 6:48pm by Turtleman » |
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Card graphics not sticking
« Reply #9 on: May 14th, 2016, 8:06pm » |
|
on May 14th, 2016, 6:47pm, Turtleman wrote:Didn't need to use a timer. |
|
The delay was just to show that something out-of-the-ordinary was happening.
Quote:Oh, and changing the icon is a heck of a lot simpler. |
|
Unlike LB, LBB supports multi-format icons (where the .ICO file contains several icons in different sizes and color depths) which can for example result in a high quality 256x256 image being used on a high-DPI screen.
Richard.
|
|
Logged
|
|
|
|
Turtleman
New Member
member is offline
Gender:
Posts: 29
|
|
Re: Card graphics not sticking
« Reply #10 on: May 15th, 2016, 11:21am » |
|
Good morning - and time for my stupid questions of the day!
Going back to the simple QCard example (minus the playwave and pause statements to speed things up), is there a way of using "call BlitBack hBox, 700, 440" instead of flush statements in LB to restore the screen after its been minimized? Without flush statements, the graphics disappear, unlike in LBB.
The 700 and 440 parameters evidently correspond to the graphicbox's dimensions, but larger numbers seem to work as well. It's not a big deal, but is there a downside for using larger numbers so the same call BlitBack statement can be kept consistent throughout the program when used with different size graphicbox's?
I've been using the LB Workstation for development for its ease of use and line statements. Unfortunately, I can't seem to redirect the paths under Preferences to send the program to LBB instead of LB. Is there a trick for doing that? It would be great to at least have line numbers on LBB. I see there are numbers on the LBB pane, but it doesn't display the exact same code.
Whoops - false alarm! I just saw the 09/18/2013 post "Using Liberty BASIC Workshop with LBB" and must have goofed before. It's now working with Workshop.
Sorry if my other questions are confusing. Thanks!
|
« Last Edit: May 15th, 2016, 3:09pm by Turtleman » |
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Card graphics not sticking
« Reply #11 on: May 15th, 2016, 3:25pm » |
|
on May 15th, 2016, 11:21am, Turtleman wrote:Without flush statements, the graphics disappear, unlike in LBB. |
|
Why would you want to do it a "different way"? FLUSH is the method LB uses to cause graphics to 'stick'; a rather unsatisfactory method in my opinion, but there it is. So if you want to retain compatibility with LB keep the FLUSH statements, LBB won't mind.
Quote:It's not a big deal, but is there a downside for using larger numbers so the same call BlitBack statement can be kept consistent throughout the program when used with different size graphicbox's? |
|
Only Microsoft could answer that question. There may be a cost in 'clipping' the rectangle to the size of the window, or there may not. You could try profiling it!
Quote:Whoops - false alarm! I just saw the 09/18/2013 post "Using Liberty BASIC Workshop with LBB" |
|
There's also this Wiki article.
Richard.
|
|
Logged
|
|
|
|
Turtleman
New Member
member is offline
Gender:
Posts: 29
|
|
Re: Card graphics not sticking
« Reply #12 on: May 15th, 2016, 3:37pm » |
|
Thanks Richard. May I safely assume that LBB totally ignores flush statements? I love that LBB doesn't need them, but is there any downside to keeping them in the code to retain compatibility with LB?
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Card graphics not sticking
« Reply #13 on: May 15th, 2016, 5:06pm » |
|
on May 15th, 2016, 3:37pm, Turtleman wrote:May I safely assume that LBB totally ignores flush statements? |
|
No. I explained previously that FLUSH still has a function in LBB when paired with REDRAW; it is not ignored. The LBB Help file describes what each statement does, including FLUSH.
Richard.
|
|
Logged
|
|
|
|
Turtleman
New Member
member is offline
Gender:
Posts: 29
|
|
Re: Card graphics not sticking
« Reply #14 on: May 15th, 2016, 5:19pm » |
|
I probably shouldn't have said "totally ignores." However, it's my understanding that an abundance of flush statements consume memory in LB and was wondering if keeping them in the code when using LBB (only to maintain compatibility) also consumes resources. In other words, will it make any difference if the flush statements are left in or removed?
And I'm still unsure if there's a good way of restoring a graphics screen using LB after the window has been minimized if flush statements are removed. I'm obviously a confused code writer, but am slowly figuring it out. Thanks!
|
|
Logged
|
|
|
|
|