LB Booster
Programming >> Compatibility with LB4 >> Card graphics not sticking
http://lbb.conforums.com/index.cgi?board=compatibility&action=display&num=1463164201

Card graphics not sticking
Post by Turtleman 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!

Re: Card graphics not sticking
Post by Richard Russell 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 


Re: Card graphics not sticking
Post by Turtleman 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!" smiley
Re: Card graphics not sticking
Post by Richard Russell 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.

Re: Card graphics not sticking
Post by Turtleman 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!

Re: Card graphics not sticking
Post by Richard Russell 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.

Re: Card graphics not sticking
Post by Turtleman 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!

Re: Card graphics not sticking
Post by Richard Russell 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 

Re: Card graphics not sticking
Post by Turtleman 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!
Re: Card graphics not sticking
Post by Richard Russell 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.
Re: Card graphics not sticking
Post by Turtleman 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!


Re: Card graphics not sticking
Post by Richard Russell 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.
Re: Card graphics not sticking
Post by Turtleman 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?
Re: Card graphics not sticking
Post by Richard Russell 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.

Re: Card graphics not sticking
Post by Turtleman 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!

Re: Card graphics not sticking
Post by Richard Russell on May 15th, 2016, 6:58pm

on May 15th, 2016, 5:19pm, Turtleman wrote:
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.

Cumulative resources, no. There's no requirement, as there is in LB, to use CLS or DELSEGMENT to avoid a constantly increasing use of memory.

Quote:
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.

A question for an LB expert, which isn't me (and arguably questions about LB are off-topic here).

Richard.

Re: Card graphics not sticking
Post by Turtleman on May 15th, 2016, 7:04pm

Got it! So for now, I might as well keep the flushes just to maintain compatibility until I get everything working in LBB. It's a lot easier dealing with single versions of code.

I'm now trying to figure out why the program is running much slower in LBB than LB even when the graphic windows aren't opened. Way too much code to post, but will get to the bottom of it eventually. Appreciate all your help.

Re: Card graphics not sticking
Post by Richard Russell on May 15th, 2016, 8:15pm

on May 15th, 2016, 7:04pm, Turtleman wrote:
I'm now trying to figure out why the program is running much slower in LBB than LB even when the graphic windows aren't opened.

I've never suggested that LBB is suitable for all programs; it clearly isn't. Some programs rely on features that LBB doesn't have (e.g. arbitrary precision integer arithmetic or graphics segments), others rely on undocumented features of LB that I either don't know about or can't easily emulate, and some make heavy use of non-standard features that have to be emulated at run-time and are therefore very slow.

It sounds as though your program falls into that last category, so - especially considering what you have said about FLUSH - this is probably one of those rare occasions when it would be more sensible to stick with LB.

Richard.

Re: Card graphics not sticking
Post by Turtleman on May 15th, 2016, 8:24pm

I appreciate your input. Slower is just one of the problems. There are 8 selectable windows in addition to the main one, and when I try to open a particular one, I get an error "Couldn't create bitmap at line 0" Line zero? I don't have a clue what that means, especially since that particular window doesn't even use any bitmaps! Maybe that's a clue, but I don't have the foggiest what's going on. I hate to give up this early in the LB to LBB game, and I'll report back if I ever figure it out. All the other windows and overall program runs normally, albeit very slowly. Very confusing.
Re: Card graphics not sticking
Post by Richard Russell on May 16th, 2016, 08:39am

on May 15th, 2016, 8:24pm, Turtleman wrote:
I get an error "Couldn't create bitmap at line 0" Line zero?

Line zero simply means that the error isn't occurring in your BASIC program but (probably) in the LBLIB emulation library. In an ideal world that code ought not to raise such errors, but I know there are circumstances when it can.

What version of Windows are you running? A "Couldn't create bitmap" error used to be more common in Windows XP because all DCBs (Device Compatible Bitmaps) are allocated from quite a small pool on that version, and it wasn't that difficult to use up all the available memory. But on Windows Vista and later much more memory is available for DCBs.

If you're running a machine that is infrequently rebooted (such as a laptop) that can also increase the likelihood of running out of bitmap memory, because crashed programs that don't correctly clean up after themselves can gobble it up. So try rebooting the PC and running the program again.

I assume the windows you are referring to don't create ridiculously big bitmaps (as they might if you specified large limits in a HORIZSCROLLBAR or VERTSCROLLBAR command). Remember that LBB is double-buffered, so makes much heavier use of bitmaps than LB.

Clearly it would be worth tracing the cause of this error, in the unlikely event that it's a bug in LBB. But if your program runs slowly that's another matter - where does the Profiler say the time is primarily being spent?

Richard.

Re: Card graphics not sticking
Post by Turtleman on May 16th, 2016, 12:58pm

Richard: I've (almost) concluded that the main reason I'm having difficulties running my LB program in LBB is, for lack of a better explanation, sloppy coding! When I started the project several years ago, I didn't have a clue how to program. And while I got the program to run, it was pure unadulterated spaghetti code. I did a major rewrite a couple years ago, broke things into more manageable subroutines, and improved speed and reliability significantly. But now that I'm troubleshooting to get it to play nicely with LBB, I'm seeing that the code is still heavily convoluted in many areas. Hopefully, I know a lot more about programming now than I did a couple years ago (and even a couple days ago), so once again I'm going to try rewriting the entire program using more standalone modules. Being able to test as I go in LB and LBB should reveal any incompatibilities and result in a cleaner program.

Eventually, I'd like it to run on Apple and Android devices, and looked into using a more compatible language. I even began playing with Python and just stumbled across BBC Basic, but I'm afraid the learning curve could exceed my life expectancy. So while LB may not be the ideal language, at least I'm more familiar with it than anything else. Any suggestions besides giving up would be welcome!

Thanks again for your help and I'll be sure to post the results of the "new and improved" LBB-compatible program.
Re: Card graphics not sticking
Post by Richard Russell on May 16th, 2016, 4:59pm

on May 16th, 2016, 12:58pm, Turtleman wrote:
Any suggestions besides giving up would be welcome!

It all depends on how much of your program is 'GUI' stuff (graphics/controls/sprites) and how much is 'computational' stuff (arithmetic, string manipulation, file handling, sound and so on).

As I explained before, LB/LBB rely heavily on the Windows API for GUI functionality. If your program makes extensive use of GUI elements then that's the principal concern as regards porting to other platforms - irrespective of what programming language is used.

Apart from Windows itself, only Wine provides a high degree of compatibility with the Win32 API. That at least gives you a route to porting your program to Linux (86) and to Mac OS-X, because both those platforms are well supported by Wine.

Otherwise it's going to mean replacing all the GUI aspects of your program with something more generic. Only you know how practical that would be.

Richard.

Re: Card graphics not sticking
Post by Turtleman on May 21st, 2016, 10:09am

It's feedback time! I cut the program's 37K lines of code down to 2.4K in an attempt to get one common section of code running in LBB at a time. Interestingly, one of the displays was "flickering" several times in LBB when opening a new window, but wasn't flickering when running in LB. It took some time; but as it turns out, I was doing several redundant reads from the hard drive that went unnoticed in LB, but was very evident in LBB. This particular routine is only active when opening a certain segment of code and won't slow down normal operation, but there are undoubtedly other inefficiencies in the rest of the program that I'll be looking into.

I really like the fact that making an executable is so much easier in LBB, along with eliminating a zillion flush statements, so I have a high incentive to continue the investigation. More as I go. smiley
Re: Card graphics not sticking
Post by Richard Russell on May 21st, 2016, 10:36am

on May 21st, 2016, 10:09am, Turtleman wrote:
Interestingly, one of the displays was "flickering" several times in LBB when opening a new window, but wasn't flickering when running in LB.

In my experience all sorts of things can influence 'flickering', not just the language. The speed and type of CPU (e.g. whether it is multi-core), the graphics card, the kind of display etc. So even if something is flicker-free on your system you should not assume it will be on somebody else's.

Basically whilst you may get away with repetitively closing-and-opening a window, or using CLS, or anything else which momentarily changes the display, it's far better to avoid doing it. There are usually alternatives which result in minimal display disturbance and they should be flicker-free on all platforms.

LBB's double buffering also gives you more control of exactly when the display is updated, by calling the "InvalidateRect", "UpdateWindow" or "RedrawWindow" APIs, so even in particularly challenging circumstances there is usually a solution.

Running a program in LBB will often reveal weaknesses in your code that you never realised were there, because you 'got away with it' in LB. In such a case the fault is nevertheless with your code, not with LBB.

Richard.

Re: Card graphics not sticking
Post by Turtleman on May 21st, 2016, 10:52am

You said it better than I did, namely that LBB revealed weaknesses in my code that went unnoticed in LB! The flickering was from repeated and unnecessary reads from the HD and writes to the display. That's now been fixed, but probably represents a spoonful of repairs in an ocean of goofs!

There are many CLS and FLUSH statements in the existing program that I hope will be unnecessary in LBB. Sorry for asking again, but does it "slow down" or create other problems to keep those instructions for LB compatibility when running in LBB or should they be deleted? And if the completed program runs better in LBB, is there any reason to maintain LB compatibility?

I'm currently adding additional code and testing in LB and LBB as I go.

Re: Card graphics not sticking
Post by Richard Russell on May 21st, 2016, 11:46am

on May 21st, 2016, 10:52am, Turtleman wrote:
Sorry for asking again, but does it "slow down" or create other problems to keep those instructions for LB compatibility when running in LBB or should they be deleted?

CLS may well be essential if you are using it to clear the graphicbox/window, which is its primary purpose. Only if you are using CLS purely as a quick-and-dirty way of avoiding cumulative memory usage (and there are usually better ways, such as DELSEGMENT) can you safely delete it. Using CLS for that purpose rather than what it is intended for is a recipe for flickering!

Quote:
And if the completed program runs better in LBB, is there any reason to maintain LB compatibility?

Discussed previously; I have nothing to add on the subject.

Richard.

Re: Card graphics not sticking
Post by Turtleman on May 21st, 2016, 12:31pm

Sorry for the repeating the question; besides, I'm finding the answers as I go and LBB is pointing out coding blunders that probably would have remained unnoticed. Adding back in "cleaned up" portions of code is going very well, and I can't wait to see the end result. Will report back later.
Re: Card graphics not sticking
Post by tsh73 on May 22nd, 2016, 9:07pm

Quote:
is there any reason to maintain LB compatibility?

Quote:
Running a program in LBB will often reveal weaknesses in your code that you never realised were there, because you 'got away with it' in LB. In such a case the fault is nevertheless with your code, not with LBB.


I really wonder if there are reversal - things you get away with sloppy coding in LBB but not in LB?
It just should be somewhere - or we assume LBB is perfect (in a god-like sense).
If there are, then LB compatibility supposed to allow checking in two independent realizations, which could pinpoint sloppy coding and so make program better.

Re: Card graphics not sticking
Post by Richard Russell on May 22nd, 2016, 10:18pm

on May 22nd, 2016, 9:07pm, tsh73 wrote:
If there are, then LB compatibility supposed to allow checking in two independent realizations, which could pinpoint sloppy coding and so make program better.

"LB compatibility" implies not using any of LBB's many language extensions, which would be a ridiculous price to pay simply to allow such checking. You would be throwing away one of the principal reasons for using LBB in the first place!

For example you cannot possibly suggest that avoiding TRY...CATCH...END TRY and instead using ON ERROR GOTO, to maintain compatibility, makes a program "better"! Or not being able to use the extensions to USING$(), or DATE$(), or word-wrap in the TEXTEDITOR, or array arithmetic, or......

And what about LB's bugs? Being forced to use a branch label as the TIMER handler, rather than a SUB (which crashes LB), makes it almost impossible to write well-structured programs. If you want more examples of code you would have to avoid, just look at the LB Bug Tracker Wiki.

So, no, allowing "checking in two independent realizations" isn't a valid reason to maintain compatibility with LB. If you want to check programs for "sloppy coding" write a tool to do it; it would be a useful thing to have.

Richard.

Re: Card graphics not sticking
Post by joker on May 23rd, 2016, 09:49am

tsh73,

Quote:
I really wonder if there are reversal - things you get away with sloppy coding in LBB but not in LB?


If you "really wonder" this, then perhaps put up a bunch of examples?


Quote:
... we assume LBB is perfect (in a god-like sense).


What the hell does that mean in a programmer-like sense? What program is "perfect?" Certainly not LB!

Perhaps you are making some kind of oblique personal comment? If so, I don't think that part of your post is appropriate in this context.
Re: Card graphics not sticking
Post by Turtleman on May 23rd, 2016, 10:52am

I'm a little reluctant to jump into this "friendly discussion," but as a newcomer to LBB, I've had nothing but trouble trying to get what appeared to be properly operating LB code to run in LBB. I was hoping to gain faster execution (and maybe reduce or eliminate infrequent crashes), but was disappointed to see that the program ran several times slower in LBB!

I'm currently dissecting and troubleshooting one section of code at a time; and so far, the problems stem entirely from sloppy programming in LB! After some changes, the code runs just as well in both, though any potential speed benefits won't be assessed until more code is "fixed" and the entire program reassembled. The point I'm making is that LBB has definitely identified "errors" in my LB coding that would have remained unnoticed. For that reason alone, I'm very glad to have "discovered" LBB and am still hoping that other benefits will be forthcoming.

On a side note: if I were talented enough to write a program to check for and identify sloppy coding, I probably wouldn't be making so many mistakes to begin with! grin
Re: Card graphics not sticking
Post by Richard Russell on May 23rd, 2016, 12:00pm

on May 23rd, 2016, 10:52am, Turtleman wrote:
I was hoping to gain faster execution (and maybe reduce or eliminate infrequent crashes), but was disappointed to see that the program ran several times slower in LBB!

You keep saying that LBB is much slower than LB, but you never tell us where the Profiler says the time is being spent, despite me having asked at least twice. Please let us know the answer, perhaps by posting an extract from the Profiler report file.

I can artificially create a program which runs "several times slower" in LBB, but it's not typical of real-world code. Here are some extreme comparisons:

Code:
    start = time$("ms")
    for i = 1 to 1000000
    next
    finish = time$("ms")
    print "Execution time ";finish-start;" milliseconds" 

In LB 4.5.0 about 7000 ms and in LBB 3.04 about 90 ms, that's about 75 times faster in LBB. But...

Code:
    start = time$("ms")
    for i = 1 to 100000
      a$ = word$("  The  quick  brown  fox  jumps  over  the  lazy  dog  ", 8)
      scan
    next
    finish = time$("ms")
    print "Execution time ";finish-start;" milliseconds" 

In LB 4.5.0 about 2000 ms and in LBB 3.04 about 8000 ms, that's about 4 times slower in LBB.

Richard.
Re: Card graphics not sticking
Post by tsh73 on May 23rd, 2016, 12:10pm

Quote:
If you "really wonder" this, then perhaps put up a bunch of examples?

If I had examples I had not to wonder. I would then just said that and give examples.

Quote:
>>I really wonder if there are reversal - things you get away with sloppy coding in LBB but not in LB?
It just should be somewhere - or we assume LBB is perfect (in a god-like sense).

> What the hell does that mean in a programmer-like sense? What program is "perfect?" Certainly not LB!

I'll try again.
It was said that trying to run valid working (or seem so) LB program in LBB discovers some defects in coding.
I suppose that should work *both* ways.
That is, having many working LBB programs, occasionally running it in LB will point some defect in coding (not in LB or LBB - but in mine coding, as a BASIC programmer).
Unless one assumes LB is so great that defective in some way code cannot ever work in LBB.

(of cource Richard points out that to have big amount of LBB programs and not to use LBB new features is pointless.
I agree.)

As of the rest please don't think about things I never said.
Re: Card graphics not sticking
Post by Turtleman on May 23rd, 2016, 12:14pm

Russell: Perhaps you misunderstood what I meant. The slower execution I was experiencing in LBB was entirely due to sloppy programming in my LB code to start with! I wasn't saying that LBB is or isn't inherently faster or slower, merely that my inefficient program was causing speed related problems, and that once fixed, ran well in LBB! I was actually praising LBB for identifying errors that were going unnoticed in LB.

I'm currently trying to modify part of my program that's showing a very noticeable difference in speed; but as before, it's likely some goof that I haven't caught yet. I've used the Profiler, but haven't identified anything worthy of passing along … yet. This may take a few days, but I'm trying to get to the bottom of things and will be glad to pass along the results as I find them.

I appreciate your continued help.

Re: Card graphics not sticking
Post by Turtleman on May 23rd, 2016, 3:15pm

Here's an example of a code snippet that runs noticeably slower in LBB than LB. It's not lifted from my program, which would only confuse, but is totally representative of what I'm trying to show.

The program populates a grid of 10 x 20 colored boxes as defined in the [Fieldvalues]. A left click on any box will sequence through 1-5 numbers and associated colors.

Here's the "problem": In LB, the program opens almost immediately, while it takes considerably longer in LBB. (The grid in my actual program is almost twice as large, and the time to load is even longer.) The opening (and closing) is by a button in another part of the program, and it's somewhat disturbing to watch the graph slowly fill in when using LBB as opposed to LB. (The sytlebits comment at the top of the program has been commented out. While the display could be hidden until finished loading, the delay is still not desirable.)

I hope I've committed some horrendous programming error and that there's a way of speeding things up. In any case, there's a noticeable difference in the time it takes to load in LB vs. LBB.

Any suggestions would be must appreciated. Thanks!


SORRY - I GOT A MESSAGE THAT THE CODE WAS TOO LONG. IT'S ONLY 300 LINES - HOW DO I ATTACH IT?
Re: Card graphics not sticking
Post by Richard Russell on May 23rd, 2016, 3:40pm

on May 23rd, 2016, 12:14pm, Turtleman wrote:
The slower execution I was experiencing in LBB was entirely due to sloppy programming in my LB code to start with!

Generally, "sloppy programming" won't cause things to run more slowly in LBB. If the program runs, which means your programming (whether it be 'sloppy' or otherwise) is compatible with LBB, it should benefit from a speed improvement, or at least not run significantly slower.

So very slow-running code in LBB is a concern, irrespective of the quality of your programming, because it's not expected. Because it's so easy to run the Profiler to find out where that slowness is arising, I ask you once again to do that and to post the relevant section(s) of the report file. Many thanks.

Richard.
Re: Card graphics not sticking
Post by Turtleman on May 23rd, 2016, 3:48pm

Got to run right now and may not be able to get back to this until tomorrow. I ran the Profiler and am trying to figure out how to post it along with my code. I'm very anxious to get to the bottom of this. Later!
Re: Card graphics not sticking
Post by Richard Russell on May 23rd, 2016, 4:10pm

on May 23rd, 2016, 3:48pm, Turtleman wrote:
I hope I've committed some horrendous programming error and that there's a way of speeding things up.

No. You have hit a rare 'edge case', which I have encountered only once before, in a program written by an Australian user. LBB is not suitable for your program - use LB instead.

Richard.

Re: Card graphics not sticking
Post by Turtleman on May 23rd, 2016, 7:53pm

Code:
 
Yikes – you're giving up without having even seen the code and running it! Let's not throw in the towel so quickly! If nothing else, it would be good to know what's going on. Code:
    'Graphic boxes demo - May 23, 2016
  
    nomainwin
    'stylebits #main, 0, _WS_VISIBLE, 0, 0     
    
    GridWidth = 40
    GridHeight = 25
    GridRows = 20
    GridColumns = 10
    MaxColors = 5

    dim counters(GridColumns, GridRows), colors$(MaxColors-1)

    restore [FieldValues]

    for row = 1 to GridRows
        for column = 1 to GridColumns
            read n
            counters(column, row) = n
        next
    next

    restore [FieldColors]

    for i = 0 to MaxColors-1
        read color$
        colors$(i) = color$
    next

    BoxWidth = GridColumns * GridWidth
    BoxHeight = GridRows * GridHeight
    WindowWidth = BoxWidth + 100
    WindowHeight = BoxHeight + 100

    UpperLeftX=int((DisplayWidth-WindowWidth)/2)
    UpperLeftY=int((DisplayHeight-WindowHeight)/2)

    graphicbox #main.gb22,                  50, 10,(GridWidth), 25
    graphicbox #main.gb23, (1 * GridWidth +50), 10,(GridWidth), 25
    graphicbox #main.gb24, (2 * GridWidth +50), 10,(GridWidth), 25
    graphicbox #main.gb25, (3 * GridWidth +50), 10,(GridWidth), 25
    graphicbox #main.gb26, (4 * GridWidth +50), 10,(GridWidth), 25
    graphicbox #main.gb27, (5 * GridWidth +50), 10,(GridWidth), 25
    graphicbox #main.gb28, (6 * GridWidth +50), 10,(GridWidth), 25
    graphicbox #main.gb29, (7 * GridWidth +50), 10,(GridWidth), 25
    graphicbox #main.gb30, (8 * GridWidth +50), 10,(GridWidth), 25
    graphicbox #main.gb31, (9 * GridWidth +50), 10,(GridWidth), 25
   
    y = 15
    graphicbox #main.gb11, 5, 1 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb12, 5, 2 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb13, 5, 3 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb14, 5, 4 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb15, 5, 5 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb16, 5, 6 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb17, 5, 7 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb18, 5, 8 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb19, 5, 9 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb110, 5, 10 * GridHeight + y, GridWidth,GridHeight
   
    graphicbox #main.gb111, 5, 11 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb112, 5, 12 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb113, 5, 13 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb114, 5, 14 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb115, 5, 15 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb116, 5, 16 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb117, 5, 17 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb118, 5, 18 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb119, 5, 19 * GridHeight + y, GridWidth, GridHeight
    graphicbox #main.gb120, 5, 20 * GridHeight + y, GridWidth,GridHeight  
   
   
    graphicbox #main.gb, 50, 40, BoxWidth, BoxHeight
    open "Grid" for window as #main
    #main, "trapclose [quit.main]"
    #main.gb "down; font arial 10; size 1; color black"
    #main.gb "when leftButtonUp [IncreaseCounter]"
    #main.gb "when leftButtonDouble [IncreaseCounter]"
    gosub [InitGrid]
    
    gosub [title]  
    #main "show"
    wait

[quit.main]
    Close #main
    END

[IncreaseCounter]
    row    = int( MouseY / GridHeight) + 1
    column = int( MouseX / GridWidth) + 1
    counters(column, row) = counters(column, row) + 1
    if counters(column, row) > (MaxColors - 1) then counters(column, row) = 0
    #main.gb "delsegment GridUpdate"
    gosub [DrawField]
    #main.gb "flush GridUpdate"
    wait

[InitGrid]
    for row = 1 to GridRows
        for column = 1 to GridColumns
            gosub [DrawField]
        next
    next

    #main.gb "flush InitGrid"
    return

[DrawField]
    #main.gb "backcolor "; colors$(counters(column, row))
    #main.gb "place "; (column-1)*GridWidth; " "; (row-1)*GridHeight
    #main.gb "boxfilled "; column*GridWidth; " "; row*GridHeight
    #main.gb "place "; (column-.6)*GridWidth; " "; (row-.4)*GridHeight

    if instr(lower$(colors$(counters(column, row))), "dark") > 0 then #main.gb "color white"
    #main.gb "\"; counters(column, row)
    if instr(lower$(colors$(counters(column, row))), "dark") > 0 then #main.gb "color black"
    return

[FieldValues]
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4

[FieldColors]
    data "red"      '0
    data "green"    '1
    data "cyan"     '2
    data "yellow"   '3
    data "pink"     '4
  
[title]
'REM  1
    #main.gb22, "down; fill yellow; color black; backcolor yellow"
    #main.gb22, "place 10 17; font arial 12 bold"
    #main.gb22, "\1"
    #main.gb22, "flush"
'REM  2
    #main.gb23, "down; fill yellow; color black; backcolor yellow"
    #main.gb23, "place 10 17; font arial 12 bold"
    #main.gb23, "\2"
    #main.gb23, "flush"
'REM  3
    #main.gb24, "down; fill yellow; color black; backcolor yellow"
    #main.gb24, "place 10 17; font arial 12 bold"
    #main.gb24, "\3"
    #main.gb24, "flush"
'REM  4
    #main.gb25, "down; fill yellow; color black; backcolor yellow"
    #main.gb25, "place 10 17; font arial 12 bold"
    #main.gb25, "\4"
    #main.gb25, "flush"
'REM  5
    #main.gb26, "down; fill yellow; color black; backcolor yellow"
    #main.gb26, "place 10 17; font arial 12 bold"
    #main.gb26, "\5"
    #main.gb26, "flush"
'REM  6
    #main.gb27, "down; fill yellow; color black; backcolor yellow"
    #main.gb27, "place 10 17; font arial 12 bold"
    #main.gb27, "\6"
    #main.gb27, "flush"
'REM  7
    #main.gb28, "down; fill yellow; color black; backcolor yellow"
    #main.gb28, "place 10 17; font arial 12 bold"
    #main.gb28, "\7"
    #main.gb28, "flush"
'REM  8
    #main.gb29, "down; fill yellow;color black; backcolor yellow"
    #main.gb29, "place 10 17; font arial 12 bold"
    #main.gb29, "\8"
    #main.gb29, "flush"
'REM  9
    #main.gb30, "down; fill yellow; color black; backcolor yellow"
    #main.gb30, "place 10 17; font arial 12 bold"
    #main.gb30, "\9"
    #main.gb30, "flush"
'REM  10
    #main.gb31, "down; fill yellow; color black; backcolor yellow"   'REM      255, 153, 0"
    #main.gb31, "place 5 17; font arial 12 bold"
    #main.gb31, "\10"
    #main.gb31, "flush"


'REM  VERTICAL COLUMN LABELS ----------------------------------------------------------------------
'REM  1
    #main.gb11, "down; fill white; color black; backcolor white"
    #main.gb11, "place 14 20; font arial 12 bold"
    #main.gb11, "\1"
    #main.gb11, "flush"

'REM  2  #main.gb91, "down; fill white; color black; backcolor white"
    #main.gb12, "place 14 20; font arial 12 bold"
    #main.gb12, "\2"
    #main.gb12, "flush"
'REM  3
    #main.gb13, "down; fill white; color black; backcolor white"
    #main.gb13, "place 14 20; font arial 12 bold"
    #main.gb13, "\3"
    #main.gb13, "flush"
'REM  4
    #main.gb14, "down; fill white; color black; backcolor white"
    #main.gb14, "place 14 20; font arial 12 bold"
    #main.gb14, "\4"
    #main.gb14, "flush"
'REM  5
    #main.gb15, "down; fill white; color black; backcolor white"
    #main.gb15, "place 14 20; font arial 12 bold"
    #main.gb15, "\5"
    #main.gb15, "flush"
'REM  6
    #main.gb16, "down; fill white; color black; backcolor white"
    #main.gb16, "place 14 20; font arial 12 bold"
    #main.gb16, "\6"
    #main.gb16, "flush"
'REM  7
    #main.gb17, "down; fill white; color black; backcolor white"
    #main.gb17, "place 14 20; font arial 12 bold"
    #main.gb17, "\7"
    #main.gb17, "flush"
'REM  8
    #main.gb18, "down; fill white; color black; backcolor white"
    #main.gb18, "place 14 20; font arial 12 bold"
    #main.gb18, "\8"
    #main.gb18, "flush"
'REM  9
    #main.gb19, "down; fill white; color black; backcolor white"
    #main.gb19, "place 14 20; font arial 12 bold"
    #main.gb19, "\9"
    #main.gb19, "flush"
'REM  10
    #main.gb110, "down; fill white; color black; backcolor white"
    #main.gb110, "place 10 20; font arial 12 bold"
    #main.gb110, "\10"
    #main.gb110, "flush"
'REM  11
    #main.gb111, "down; fill white; color black; backcolor white"
    #main.gb111, "place 10 20; font arial 12 bold"
    #main.gb111, "\11"
    #main.gb111, "flush"
'REM  12  
    #main.gb112, "down; fill white; color black; backcolor white"
    #main.gb112, "place 10 20; font arial 12 bold"
    #main.gb112, "\12"
    #main.gb112, "flush"
'REM  13
    #main.gb113, "down; fill white; color black; backcolor white"
    #main.gb113, "place 10 20; font arial 12 bold"
    #main.gb113, "\13"
    #main.gb113, "flush"
'REM  14
    #main.gb114, "down; fill white; color black; backcolor white"
    #main.gb114, "place 10 20; font arial 12 bold"
    #main.gb114, "\14"
    #main.gb114, "flush"
     return                                                                                                                                       
 

Re: Card graphics not sticking
Post by Turtleman on May 23rd, 2016, 8:28pm

Sorry if the code snippet didn't get posted in the right place, but you should see a significant difference in loading speed between LB and LBB, even though I had to cut it down to size. Comments?
Re: Card graphics not sticking
Post by Richard Russell on May 23rd, 2016, 9:20pm

on May 23rd, 2016, 7:53pm, Turtleman wrote:
Yikes – you're giving up without having even seen the code and running it!

It's not a case of "giving up" but of avoiding further effort being expended when it can't succeed. It would be inappropriate for me to encourage you to carry on, since nothing you can do will make it run any faster than it is now.

What does puzzle me somewhat (although I must emphasise that it has nothing to do with speed) is why you are not populating the boxes in a loop. Whilst LB compatibility prevents you using a loop to create the boxes, there is no such limitation when it comes to populating them.

So whilst you will have no choice but to return to using LB to achieve the speed you seem to require, you could significantly reduce the size of the code by removing much of the repetition.

Thank you for your interest in LBB, I'm sorry it didn't work out in this case.

Richard.

Re: Card graphics not sticking
Post by Turtleman on May 23rd, 2016, 9:32pm

Thanks Russell, though I'm disappointed that LBB won't provide a boost to my program, and even more disappointed that I don't have a clue why it loads differently in LB vs. LBB. (I'm also pretty sure it loaded faster before I went from Win 7 to Win 10, but that's another issue.) I really hate giving up the advantages of LBB, but it's still very useful in identifying coding flaws that LB doesn't care about. And you're right about reducing much of the code, but frankly, I'm not sure how to go about it!
Re: Card graphics not sticking
Post by tsh73 on May 23rd, 2016, 9:46pm

I've put a bit of
Code:
print "Time taken ";time$("ms")-t0: t0=time$("ms") 

lines to see what's going on.

Basically LB shows window (on my old machine) at 200ms, while LBB at 560
Parts that take time:
Code:
creating controls / opening window
60 ms LB , 200 LBB
[InitGrid]
100 ms LB , 140 LBB
[title]
140 ms LB , 300 LBB 

I pretty sure nothing could be done at first part.
[ InitGrid ] and [ title ] is basically bunch of drawing commands
LBB is known might be slower in graphics - there are too much layers to emulate. It is shine in calculating (strings and math). So you still could have speed gain ;)
Time shows things could be done at [ title ]
Let's see
You can move font from each box to main
Code:
[title]
#main "font arial 12 bold" 

you can get rid of color (black by default), down (down by defualt in LBB) and flush.
So I got about 200 ms out of 300 with parts like these
Code:
'REM  1
    #main.gb22, "fill yellow; backcolor yellow;place 10 17"
    #main.gb22, "\1"
 

(man you really should rewrite that part with a loop and handle variables).

BUT
with
Code:
stylebits #main, 0, _WS_VISIBLE, 0, 0
...
#main "show"
 

window seems to came instantly anyway.
So - create window once, then done,
Code:
#main "hide"  

, then need,
Code:
#main "show"  
- instantly.


Re: Card graphics not sticking
Post by tsh73 on May 23rd, 2016, 9:49pm

Quote:
And you're right about reducing much of the code, but frankly, I'm not sure how to go about it!


Code:
[title]
    #main "font arial 12 bold"

    for i = 22 to 31
        handle$ = "#main.gb";i
    #handle$, "fill yellow; backcolor yellow;place 10 17;\";i-21
    next
   
'REM  VERTICAL COLUMN LABELS ----------------------------------------------------------------------

    for i = 1 to 14
        handle$ = "#main.gb1";i
    #handle$, "fill white; backcolor white; place 14 20;\";i
    next
return
 

Re: Card graphics not sticking
Post by Richard Russell on May 23rd, 2016, 10:47pm

on May 23rd, 2016, 9:46pm, tsh73 wrote:
BUT with
Code:
stylebits #main, 0, _WS_VISIBLE, 0, 0
...
#main "show" 

window seems to came instantly anyway.

The OP has already said that he would not be satisfied with that approach: "While the display could be hidden until finished loading, the delay is still not desirable". You (and I) may consider it to be 'instant', but he evidently has a different opinion.

Richard.

Re: Card graphics not sticking
Post by Richard Russell on May 24th, 2016, 08:58am

Just to tidy up loose ends, I timed the code (with Anatoly's modifications, but with flush retained for LB compatibility) as follows on my laptop:

LBB 3.04: ~600 ms
LB 4.5.0: ~300 ms

So, yes, LBB takes twice as long as LB to create and populate the window and all its controls. But both take significantly less than a second and I would not expect that to be greatly annoying to a user (especially if it can be done during initialisation, or when he is reading a prompt for example).

Here we have a case where the OP set an artificial requirement, that the code must not run any slower than in LB, and it's a requirement LBB simply cannot meet. Arguably it would have been better if he had looked at the 'bigger picture' rather than fixated on this one performance measure.

Right at the start of the thread (reply #3) I wrote: "If it's mostly plotting graphics [LBB] may run no faster at all, or even a little slower" so since much of the complained-about delay is indeed when plotting graphics the OP really had no reason to be unduly surprised.

I might perhaps have been more disposed to be helpful if he could have been bothered to get my name right! cheesy

Richard.

Re: Card graphics not sticking
Post by Turtleman on May 24th, 2016, 10:38am

Richard: I'm so sorry to have gotten your name wrong in what must have been a momentary bout of dyslexia. I don't have a clue how I could have done that. Please forgive me!

I never set an "artificial requirement," but was merely curious about the speed differences. I thought (hoped) I was doing something wrong. Yes, perhaps that window and others could be loaded earlier and kept minimized until needed. Unfortunately, another window is used for plotting data repeatedly where speed is much more critical than opening the example code. With hundreds or thousands of data points, even a small difference in speed adds up. I expect that could be a "deal breaker," but will experiment further before giving up.

With thanks to tsh73, the example code used only consecutive numbers in the vertical label column, but in the real application, various numbers and letters are used, which might make it more difficult to simplify the code. I'm sure it can be done, where the labels can be fetched as data, but I haven't gotten around to working on that yet.

My LBB expectations were obviously misplaced, but am glad I gave it a go. And again, if nothing else, LBB is proving helping in identifying LB coding boo-boos!

Re: Card graphics not sticking
Post by Richard Russell on May 24th, 2016, 12:39pm

on May 24th, 2016, 10:38am, Turtleman wrote:
Unfortunately, another window is used for plotting data repeatedly where speed is much more critical than opening the example code. With hundreds or thousands of data points, even a small difference in speed adds up.

I wonder if you have read the Wiki article Speeding up graphics plotting. In the very specific example given there it was possible, by making the suggested changes, to go from LBB plotting graphics noticeably more slowly than LB to it actually plotting more quickly.

Quote:
in the real application, various numbers and letters are used, which might make it more difficult to simplify the code.

If those "various numbers and letters" are constants, they could for example be read from a DATA statement. If they are variables, then I would have expected that they could either be stored in an array or calculated at run-time as the boxes are populated.

Incidentally what is the reason that the main 'grid' is a single large graphicbox, whereas the row and column 'labels' are individual controls? I'm probably missing something, but it's not obvious to me why the row of horizontal labels shouldn't be a single graphicbox, and similarly the column of vertical labels, or indeed why the whole caboodle couldn't be a single graphicbox.

Quote:
My LBB expectations were obviously misplaced, but am glad I gave it a go.

It was to make sure that your expectations were not "misplaced" that I said so early on that you should not expect graphics plotting to be any faster. I don't know whether you somehow missed that, or hoped that it wasn't true, but your realisation that LBB is not a panacea shouldn't have been a recent one!

The background, for those who are interested, is that since both LB and LBB simply pass graphics commands onto the Windows API, fundamentally they should execute at virtually the same speed (if anything LB would be expected to be a little slower because it is both plotting to the screen and recording the commands to a metafile). The reason LBB tends to be slower in practice is the overhead of interpreted BBC BASIC, which decodes the command strings.

It would, in principle, be perfectly possible for the existing BBC BASIC code to be replaced by (say) C or assembler code, which would almost certainly guarantee that graphics plotting is always faster in LBB than LB. But the very reason for LBB's existence is as a demonstrator of the capabilities of BBC BASIC, so from that point of view replacing it with code in another language makes no sense.

Richard.
Re: Card graphics not sticking
Post by Turtleman on May 26th, 2016, 4:37pm

This probably belongs in the Novice category on the LB board, but since it's already been suggested here to hide the window with "stylebits #main, 0, _WS_VISIBLE, 0, 0" and then "#main "show"" after loading, I have a related question.

If the "hidden" window is loaded at the start of the program, it can be made visible by manually issuing a "show" command when desired. That way the window appears to open immediately, which is highly desirable. QUESTION: How do you hide the window again once opened? The program crashes if issued a "#main "hide"" instruction, and simply closing the window takes me back to where I started. Perhaps relocating the window off-screen will work.

There are several windows (not all involving graphics) that can be toggled open or closed by the user, but I don't have enough experience to know how best to go about it. ANOTHER QUESTION: Is opening and closing the "normal" way of handling multiple windows or should they be loaded at the program's start and made visible or invisible as required? I hope that makes sense, and thanks to everyone for your patience.

Tsh73: Thanks to your help, a lot of unnecessary code has been eliminated.

Re: Card graphics not sticking
Post by Turtleman on May 28th, 2016, 4:58pm

Richard: Thanks for your explanations. Not knowing any better, I initially designed the program to open selected windows on demand. I'm now changing that to launch all windows along with the rest of the program – they're just hidden until needed. That eliminates any lag in populating the displays and tremendously simplifies the coding. (I often have a tendency to overcomplicate things! smiley) So far, it looks like LBB might lend itself to running the program after all, but there're many more changes to make first.
Re: Card graphics not sticking
Post by Richard Russell on May 28th, 2016, 10:58pm

on May 28th, 2016, 4:58pm, Turtleman wrote:
Not knowing any better, I initially designed the program to open selected windows on demand.

In the great majority of programs, it will make no noticeable difference which way you do it. Creating a window usually happens virtually 'instantaneously'; even in your own program it's not the window creation that takes a significant time but the window initialisation, i.e. filling all those graphicboxes and grid cells with a background color and text.

As I think I said previously, I've only once before encountered a program in which the window creation/initialisation took sufficiently longer in LBB than in LB to be important, so it's very unusual. On that occasion I could improve things somewhat, but not match the performance of LB.

I've suggested ways in which you could improve the performance of your program. To speed up window creation you could replace the horizontal set of column labels and the vertical set of row labels with single graphicboxes rather than many individual ones. To speed up the window initialisation you could concatenate the commands into one long string, as suggested in the Wiki article to which I linked.

But you never responded to either suggestion, which is why I concluded you weren't really motivated to get it working well in LBB. The code below incorporates both mods:

Code:
    'Graphic boxes demo - May 23, 2016
  
    nomainwin
start = time$("ms")
    
    GridWidth = 40
    GridHeight = 25
    GridRows = 20
    GridColumns = 10
    MaxColors = 5

    dim counters(GridColumns, GridRows), colors$(MaxColors-1)

    restore [FieldValues]

    for row = 1 to GridRows
        for column = 1 to GridColumns
            read n
            counters(column, row) = n
        next
    next

    restore [FieldColors]

    for i = 0 to MaxColors-1
        read color$
        colors$(i) = color$
    next

    BoxWidth = GridColumns * GridWidth
    BoxHeight = GridRows * GridHeight
    WindowWidth = BoxWidth + 100
    WindowHeight = BoxHeight + 100

    UpperLeftX=int((DisplayWidth-WindowWidth)/2)
    UpperLeftY=int((DisplayHeight-WindowHeight)/2)
    
    graphicbox #main.gb2, 50, 10, BoxWidth, GridHeight
    y = 15
    graphicbox #main.gb1, 5, GridHeight + y, GridWidth, BoxHeight
    graphicbox #main.gb, 50, 40, BoxWidth, BoxHeight
    stylebits #main, 0, _WS_VISIBLE, 0, 0
    open "Grid" for window as #main
    #main, "trapclose [quit.main]"
    #main.gb "down; font arial 10; size 1; color black"
    #main.gb "when leftButtonUp [IncreaseCounter]"
    #main.gb "when leftButtonDouble [IncreaseCounter]"
    gosub [InitGrid]
    
    gosub [title]  
    #main "show"
finish = time$("ms")
print finish-start
    wait

[quit.main]
    Close #main
    END

[IncreaseCounter]
    row    = int( MouseY / GridHeight) + 1
    column = int( MouseX / GridWidth) + 1
    counters(column, row) = counters(column, row) + 1
    if counters(column, row) > (MaxColors - 1) then counters(column, row) = 0
    #main.gb "delsegment GridUpdate"
    gosub [DrawField]
    #main.gb "flush GridUpdate"
    wait

[InitGrid]
    for row = 1 to GridRows
        for column = 1 to GridColumns
            gosub [DrawField]
        next
    next

    #main.gb "flush InitGrid"
    return

[DrawField]
    gb$ = "color black; backcolor "; colors$(counters(column, row)); ";"
    gb$ = gb$ + "place "; (column-1)*GridWidth; " "; (row-1)*GridHeight; ";"
    gb$ = gb$ + "boxfilled "; column*GridWidth; " "; row*GridHeight; ";"
    gb$ = gb$ + "place "; (column-.6)*GridWidth; " "; (row-.4)*GridHeight; ";"
    if instr(lower$(colors$(counters(column, row))), "dark") > 0 then gb$ = gb$ + "color white;"
    gb$ = gb$ + "\"; counters(column, row)
    #main.gb gb$
    return

[FieldValues]
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4

[FieldColors]
    data "red"      '0
    data "darkgreen"'1
    data "cyan"     '2
    data "yellow"   '3
    data "pink"     '4
  
[title]
    #main "font arial 12 bold" 
    #main "font arial 12 bold"

    #main.gb2 "down; color black; backcolor yellow"
    for i = 22 to 31
        gb2$ = "place ";(i-22) * GridWidth; " 0;"
        gb2$ = gb2$ + "boxfilled ";(i-21) * GridWidth; " "; GridHeight-2; ";"
        gb2$ = gb2$ + "place ";(i-21.6) * GridWidth; " 17;\";i-21
        #main.gb2 gb2$
    next
    #main.gb2 "flush"
           
'REM  VERTICAL COLUMN LABELS ----------------------------------------------------------------------

    #main.gb1 "down; color black; backcolor white"
    for i = 1 to 20
        gb1$ = "place 0 ";i * GridHeight; ";"
        gb1$ = gb1$ + "boxfilled ";GridWidth-2; " "; (i-1) * GridHeight; ";"
        gb1$ = gb1$ + "place 14 ";(i-0.4) * GridHeight; ";\"; i
        #main.gb1 gb1$
    next
    #main.gb1 "flush"
    return 

Richard.


Re: Card graphics not sticking
Post by Turtleman on May 29th, 2016, 11:01am

Thanks again Richard. You've certainly demonstrated how the amount of code can be greatly reduced and initialization speeded up. The example I posted was just that, an example when I was concerned about the apparent slower speed. My actual application has nearly twice as many graphicboxes and the horizontal and vertical labels have a mix of one to five numbers, letters, and commas.

Thanks to tsh73, the code has been simplified a lot, but your example is much more elegant and efficient. Now, if I can just figure out how to integrate the word$ command to populate the labels with whatever's in the msg$ lines. Meanwhile, I've changed the window to initialize upon loading the program and it now pops up instantly fully populated. Some of the other windows may be modified accordingly. Regardless of LB or LBB, having more efficient code is always desirable; I'm just way too inexperienced to get there in one step.

I'm sorry I didn't respond to your previous post sooner, but even I have to sometimes do other things that take me away from the computer. grin I am, however, highly motivated to get my program working well in LBB! It's identifying many areas in the code that can be improved, and making executables and changing icons (among other things) are way easier than in LB. If it eventually results in a speed increase won't be known for a while. Back later.

UPDATE: Son-of-gun, adding word$ and msg was a very simple change and it's a zillion times faster and simpler than my initial example. It's embarrassing! Now to modify my "real" program. I wonder if a centering command will work here or if I have to give exceptions for the place command on some lines.
Re: Card graphics not sticking
Post by Turtleman on May 29th, 2016, 12:38pm

Another PS: Here's the small modification using Word$ and msg to permit characters to be used for the vertical column labels. That was easy. However, centering the labels within the column is so far eluding me. I've "played" with stylebits #main.gb, _ES_CENTER,0,0,0 with no success and guess there might be something to replace the "place 14 ";(i-0.4) * GridHeight instruction, but what?

Code:
'REM  VERTICAL COLUMN LABELS ----------------------------------------------------------------------
    msg$="10 A,B 3 4 5 6 7 8 C D E,F 14 15 10,10 11 G,G 17 18 19 20"
    #main.gb1 "down; color black; backcolor white"
    for i = 1 to 20
        gb1$ = "place 0 ";i * GridHeight; ";"
        gb1$ = gb1$ + "boxfilled ";GridWidth-2; " "; (i-1) * GridHeight; ";"
        gb1$ = gb1$ +  "font arial bold 10; place 2 ";(i-0.3)  * GridHeight; ";\";  word$(msg$,i)  
        #main.gb1 gb1$
    next
    #main.gb1 "flush"
 return                                                                                             


 

Re: Card graphics not sticking
Post by Richard Russell on May 29th, 2016, 2:22pm

on May 29th, 2016, 12:38pm, Turtleman wrote:
I've "played" with stylebits #main.gb, _ES_CENTER,0,0,0 with no success

As the _ES_ tells you, that's an Edit Style bit that is specific to a Texteditor or Textbox; it will have no effect on a Graphicbox.

Quote:
and guess there might be something to replace the "place 14 ";(i-0.4) * GridHeight instruction, but what?

Find the width of the string in pixels, subtract it from the width of the box and halve the resulting value. That tells you at what horizontal coordinate within the box you need to draw the text so it will be centered. Easy, but it will make the code even slower!

Is the requirement to center the text just for the labels, or for the boxes in the main grid? I'm thinking that if it's only the labels maybe you would be better to use TEXTEDITOR controls rather than GRAPHICBOXes because then you could use the _ES_CENTER style bit. LB 4.5.0 and LBB provide control over the foreground and background color of texteditor controls.

Richard.
Re: Card graphics not sticking
Post by Turtleman on May 29th, 2016, 2:35pm

I probably shouldn't have mentioned the stylebits centering, as I realized after the fact that it wouldn't work in the graphicbox. Yes, the centering is only for the labels, and only for cosmetic reasons. In my original messy code, the individual place parameters could be adjusted to center labels of 1-5 characters. Obviously, a single graphicsbox is far superior from the standpoints of simplification and speed. Right offhand, I don't have a clue how to change over to substituting texeditor controls, but will definitely put it on the to-do list.
Re: Card graphics not sticking
Post by Richard Russell on May 29th, 2016, 4:02pm

on May 29th, 2016, 2:35pm, Turtleman wrote:
I don't have a clue how to change over to substituting texeditor controls

Listed below for comparison purposes. It is slower (because we're back to individual controls for each label) and compatibility with LB must be abandoned, but the labels are centered with no extra effort.

Code:
    'nomainwin
start = time$("ms")
    
    GridWidth = 40
    GridHeight = 25
    GridRows = 20
    GridColumns = 10
    MaxColors = 5

    dim counters(GridColumns, GridRows), colors$(MaxColors-1)

    restore [FieldValues]

    for row = 1 to GridRows
        for column = 1 to GridColumns
            read n
            counters(column, row) = n
        next
    next

    restore [FieldColors]

    for i = 0 to MaxColors-1
        read color$
        colors$(i) = color$
    next

    BoxWidth = GridColumns * GridWidth
    BoxHeight = GridRows * GridHeight
    WindowWidth = BoxWidth + 100
    WindowHeight = BoxHeight + 100

    UpperLeftX=int((DisplayWidth-WindowWidth)/2)
    UpperLeftY=int((DisplayHeight-WindowHeight)/2)
    
    ' Column label boxes:
    for c = 1 to GridColumns
        stylebits #main.te, _ES_CENTER or _ES_READONLY, _
                            _WS_HSCROLL or _WS_VSCROLL or _ES_MULTILINE, 0, 0
        texteditor #main.te, c * GridWidth + 10, 10, GridWidth, GridHeight
        maphandle #main.te, "#main.c";c
    next

    ' Row label boxes:
    for r = 1 to GridRows
        stylebits #main.te, _ES_CENTER or _ES_READONLY, _
                            _WS_HSCROLL or _WS_VSCROLL or _ES_MULTILINE, 0, 0
        texteditor #main.te, 5, r * GridHeight + 15, GridWidth, GridHeight
        maphandle #main.te, "#main.r";r
    next    
        
    graphicbox #main.gb, 50, 40, BoxWidth, BoxHeight
    stylebits #main, 0, _WS_VISIBLE, 0, 0
    open "Grid" for window as #main
    hmain = hwnd(#main)
    calldll #user32, "SetMenu", hmain as ulong, 0 as long, r as long
    #main, "trapclose [quit.main]"
    #main.gb "down; font arial 10; size 1; color black"
    #main.gb "when leftButtonUp [IncreaseCounter]"
    #main.gb "when leftButtonDouble [IncreaseCounter]"
    #main.gb "setfocus"
    gosub [InitGrid]
    
    gosub [title]  
    #main "show"
finish = time$("ms")
print finish-start
    wait

[quit.main]
    Close #main
    END

[IncreaseCounter]
    row    = int( MouseY / GridHeight) + 1
    column = int( MouseX / GridWidth) + 1
    counters(column, row) = counters(column, row) + 1
    if counters(column, row) > (MaxColors - 1) then counters(column, row) = 0
    #main.gb "delsegment GridUpdate"
    gosub [DrawField]
    #main.gb "flush GridUpdate"
    wait

[InitGrid]
    for row = 1 to GridRows
        for column = 1 to GridColumns
            gosub [DrawField]
        next
    next

    #main.gb "flush InitGrid"
    return

[DrawField]
    gb$ = "color black; backcolor "; colors$(counters(column, row)); ";"
    gb$ = gb$ + "place "; (column-1)*GridWidth; " "; (row-1)*GridHeight; ";"
    gb$ = gb$ + "boxfilled "; column*GridWidth; " "; row*GridHeight; ";"
    gb$ = gb$ + "place "; (column-.6)*GridWidth; " "; (row-.4)*GridHeight; ";"
    if instr(lower$(colors$(counters(column, row))), "dark") > 0 then gb$ = gb$ + "color white;"
    gb$ = gb$ + "\"; counters(column, row)
    #main.gb gb$
    return

[FieldValues]
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
    data 0, 1, 2, 3, 4, 0, 1, 2, 3, 4

[FieldColors]
    data "red"      '0
    data "darkgreen"'1
    data "cyan"     '2
    data "yellow"   '3
    data "pink"     '4
  
[title]
    #main "font arial 10 bold" 
    
    ' column labels:
    for c = 1 to GridColumns
      handle$ = "#main.c";c
      #handle$ "!backcolor yellow"
      #handle$ str$(c)
    next
    
    ' row labels:
    lbl$ = "one A,B 3 4 5 6 7 8 C D E,F 14 15 10 11 G,H 17 18 19 20"
    for r = 1 to GridRows
      handle$ = "#main.r";r
      #handle$ "!backcolor lightgray"
      #handle$ word$(lbl$,r)
    next
    
    return 

I'm sorely tempted to replace those obsolete GOSUBs with CALLs, but have resisted the temptation so far!

Richard.
Re: Card graphics not sticking
Post by Turtleman on May 29th, 2016, 4:16pm

WOW - it probably would have taken me weeks or longer to do that if I could at all! I'm involved in something else at the moment and will need to spend some time trying to figure out why the latest code isn't compatible with LB. At this point, I'd still like to maintain compatibility, if for no other reason than to be able to compare performance later on. How big a job is it to modify centering code to be compatible?

Yes, I've heard that gosub's are almost as antiquated and nearly as verboten as goto's, but somehow find them easier to use than calls. I'm not sure I remember why calls are preferred, but gosubs are probably a nasty habit I picked up when I first started. Thanks a bunch!

Re: Card graphics not sticking
Post by Richard Russell on May 29th, 2016, 4:39pm

on May 29th, 2016, 4:16pm, Turtleman wrote:
How big a job is it to modify centering code to be compatible?

It's doable if you are prepared to lose the colored background to the labels. The problem with the !backcolor command is that only texteditor controls provide it, not textboxes, and in LB the _ES_CENTER stylebit only works with textboxes!

But you're on your own for making the changes; I draw the line at modifying programs to make them compatible with LB! Indeed I'm far more likely to make them incompatible with LB (if only accidentally).

Ideally I'd prefer not even to discuss on this forum how one might maintain compatibility with LB, because it's fundamentally contrary to what LBB is all about.

Quote:
Yes, I've heard that gosub's are almost as antiquated and nearly as verboten as goto's

GOSUBs are worse than GOTOs! Getting rid of GOTOs, whilst worthwhile, can sometimes be tricky and require significant code changes. Replacing GOSUBs with CALLs is substantially trivial and GOSUB has no redeeming features at all.

Richard.
Re: Card graphics not sticking
Post by Turtleman on May 29th, 2016, 4:46pm

Thanks - I understand completely. I'll try to stay more LBB-specific here, while most of my questions are generic programming related, anyway. I'll look into the reasons for using calls in place of gosubs and possibly become a convert. smiley

Ron (Probably no need to remain as anonymous!)

Re: Card graphics not sticking
Post by tsh73 on May 29th, 2016, 8:12pm

Quote:
and GOSUB has no redeeming features at all.

It is a quick way to move piece of code away. Moving piece of code in a sub makes one to think of dependant varibles.
(and I missed some more then once, making program work wrong)
While in GOSUB one had access for all variables (kind of global)
Re: Card graphics not sticking
Post by Richard Russell on May 29th, 2016, 10:37pm

on May 29th, 2016, 8:12pm, tsh73 wrote:
It is a quick way to move piece of code away.

I can think of only two reasons why you would ever want to "move a piece of code away". The first is when the same functionality is duplicated in two (or more) places in your program, so it is more efficient to create a 'shared' subroutine that can be called from both places. The second is when a section of code performs some relatively complex self-contained operation, which would make the program harder to read and understand if it is coded 'inline'.

In the first case it is important that the 'shared' subroutine can be called from multiple places without imposing artificial constraints on the calling code. For example it may make no sense for the two or more different places in the program to use the same variable names for the subroutine's inputs and outputs.

In the second case it is important that the calling program can be read and understood in isolation, without the detailed implementation of the subroutine being known. In particular the subroutine must not have unwanted 'side effects' such as modifying the values of variables that the calling code may be using.

Crucially, in both cases only a SUB (or a FUNCTION) meets these requirements. The inputs and outputs need not have the same variable names in the different places from which it is called, and any 'temporary' variables used within the subroutine are independent of those outside.

So my firm opinion is that GOSUB should never ever be used in a program written today. The sole purpose of GOSUB is to make it easier to port a legacy program that was originally written for an ancient version of BASIC that had no other kind of subroutine.

Richard.
Re: Card graphics not sticking
Post by michael on May 30th, 2016, 11:54pm

There is of course these commands too that allow you to do draws behind the scenes and show the draws at will.

These are built into LBB but have BBC Basic origin
Just passing on what Richard sent me for off screen draws.

!*refresh off
!*refresh on
!*refresh

refresh off turns off the automatic refresh
refresh refreshes the screen and shows the updated draws
refresh on returns the automatic refresh to automatic.

We may as well offer this since it is a part of LBB.. (but is not a part of LB. So you wont be able to share such code in LB forums.
Re: Card graphics not sticking
Post by Richard Russell on May 31st, 2016, 08:23am

on May 30th, 2016, 11:54pm, michael wrote:
There is of course these commands too that allow you to do draws behind the scenes and show the draws at will.

Except that they only work when drawing graphics into the mainwin, so are not generally useful.

The easiest way to achieve 'flicker free' animated graphics in LBB (other than using sprites) is to use the normal JB/LB commands but to put them all - including the initial CLS - into a single string. That makes the best use of LBB's double-buffering:

Code:
    timer 40, [animate]
    wait
    
[animate]
    g$ = "cls;"
    g$ += "<graphics commands>;"
    g$ += "<more graphics commands>"
    #g g$
    wait 

By concatenating all the graphics commands for one 'frame' into a single string (sadly you can't do that if text is included) you avoid the possibility of Windows refreshing the screen when the graphics are only partly drawn, which is what results in flickering.

There may still be some 'tearing' (because the drawing isn't synchronized with the display refresh rate) but with care you can get good results this way.

Richard.